diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 63252a76abb69f..b5b2765e43844f 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -1,7 +1,4 @@ -variables: - coverage: false - -trigger: ['main', '3.11', '3.10', '3.9', '3.8', '3.7'] +trigger: ['main', '3.12', '3.11', '3.10', '3.9', '3.8', '3.7'] jobs: - job: Prebuild @@ -14,70 +11,6 @@ jobs: - template: ./prebuild-checks.yml -- job: macOS_CI_Tests - displayName: macOS CI Tests - dependsOn: Prebuild - #condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) - # bpo-39837: macOS tests on Azure Pipelines are disabled - condition: false - - variables: - testRunTitle: '$(build.sourceBranchName)-macos' - testRunPlatform: macos - - pool: - vmImage: macos-10.15 - - steps: - - template: ./macos-steps.yml - - -- job: Ubuntu_CI_Tests - displayName: Ubuntu CI Tests - dependsOn: Prebuild - condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) - - pool: - vmImage: ubuntu-22.04 - - variables: - testRunTitle: '$(build.sourceBranchName)-linux' - testRunPlatform: linux - openssl_version: 1.1.1u - - steps: - - template: ./posix-steps.yml - parameters: - dependencies: apt - - -- job: Ubuntu_Coverage_CI_Tests - displayName: Ubuntu CI Tests (coverage) - dependsOn: Prebuild - condition: | - and( - and( - succeeded(), - eq(variables['coverage'], 'true') - ), - eq(dependencies.Prebuild.outputs['tests.run'], 'true') - ) - - pool: - vmImage: ubuntu-22.04 - - variables: - testRunTitle: '$(Build.SourceBranchName)-linux-coverage' - testRunPlatform: linux-coverage - openssl_version: 1.1.1u - - steps: - - template: ./posix-steps.yml - parameters: - dependencies: apt - coverage: true - - - job: Windows_CI_Tests displayName: Windows CI Tests dependsOn: Prebuild diff --git a/.azure-pipelines/macos-steps.yml b/.azure-pipelines/macos-steps.yml deleted file mode 100644 index fa38a0df8c87b8..00000000000000 --- a/.azure-pipelines/macos-steps.yml +++ /dev/null @@ -1,27 +0,0 @@ -steps: -- checkout: self - clean: true - fetchDepth: 5 - -- script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-azdev - displayName: 'Configure CPython (debug)' - -- script: make -j4 - displayName: 'Build CPython' - -- script: make pythoninfo - displayName: 'Display build info' - -- script: make buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml" - displayName: 'Tests' - continueOnError: true - timeoutInMinutes: 30 - -- task: PublishTestResults@2 - displayName: 'Publish Test Results' - inputs: - testResultsFiles: '$(build.binariesDirectory)/test-results.xml' - mergeTestResults: true - testRunTitle: $(testRunTitle) - platform: $(testRunPlatform) - condition: succeededOrFailed() diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index 9d7c5e1279f46d..e23c7b1dcb55c1 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -1,10 +1,3 @@ -parameters: - coverage: false - sudo_dependencies: sudo - dependencies: apt - patchcheck: true - xvfb: true - steps: - checkout: self clean: true @@ -14,7 +7,7 @@ steps: - script: sudo setfacl -Rb /home/vsts displayName: 'Workaround ACL issue' -- script: ${{ parameters.sudo_dependencies }} ./.azure-pipelines/posix-deps-${{ parameters.dependencies }}.sh $(openssl_version) +- script: sudo ./.azure-pipelines/posix-deps-apt.sh $(openssl_version) displayName: 'Install dependencies' - script: ./configure --with-pydebug @@ -23,61 +16,11 @@ steps: - script: make -j4 displayName: 'Build CPython' -- ${{ if eq(parameters.coverage, 'true') }}: - - script: ./python -m venv venv && ./venv/bin/python -m pip install -U coverage - displayName: 'Set up virtual environment' - - - script: ./venv/bin/python -m test.pythoninfo - displayName: 'Display build info' - - - script: | - $COMMAND -m coverage run --pylib -m test \ - --fail-env-changed \ - -uall,-cpu \ - --junit-xml=$(build.binariesDirectory)/test-results.xml \ - -x test_multiprocessing_fork \ - -x test_multiprocessing_forkserver \ - -x test_multiprocessing_spawn \ - -x test_concurrent_futures - displayName: 'Tests with coverage' - env: - ${{ if eq(parameters.xvfb, 'true') }}: - COMMAND: xvfb-run ./venv/bin/python - ${{ if ne(parameters.xvfb, 'true') }}: - COMMAND: ./venv/bin/python - - - script: ./venv/bin/python -m coverage xml - displayName: 'Generate coverage.xml' - - - script: source ./venv/bin/activate && bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml - displayName: 'Publish code coverage results' - - -- ${{ if ne(parameters.coverage, 'true') }}: - - script: make pythoninfo - displayName: 'Display build info' - - - script: $COMMAND buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml" - displayName: 'Tests' - env: - ${{ if eq(parameters.xvfb, 'true') }}: - COMMAND: xvfb-run make - ${{ if ne(parameters.xvfb, 'true') }}: - COMMAND: make - -- ${{ if eq(parameters.patchcheck, 'true') }}: - - script: | - git fetch origin - ./python Tools/patchcheck/patchcheck.py --ci true - displayName: 'Run patchcheck.py' - condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) - +- script: make pythoninfo + displayName: 'Display build info' -- task: PublishTestResults@2 - displayName: 'Publish Test Results' - inputs: - testResultsFiles: '$(build.binariesDirectory)/test-results.xml' - mergeTestResults: true - testRunTitle: $(testRunTitle) - platform: $(testRunPlatform) - condition: succeededOrFailed() +- script: | + git fetch origin + ./python Tools/patchcheck/patchcheck.py --ci true + displayName: 'Run patchcheck.py' + condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 939c9b4249a3c2..335a4b407cb83c 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -1,7 +1,4 @@ -variables: - coverage: false - -pr: ['main', '3.11', '3.10', '3.9', '3.8', '3.7'] +pr: ['main', '3.12', '3.11', '3.10', '3.9', '3.8', '3.7'] jobs: - job: Prebuild @@ -14,28 +11,8 @@ jobs: - template: ./prebuild-checks.yml -- job: macOS_PR_Tests - displayName: macOS PR Tests - dependsOn: Prebuild - #condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) - # bpo-39837: macOS tests on Azure Pipelines are disabled - condition: false - - variables: - testRunTitle: '$(system.pullRequest.TargetBranch)-macos' - testRunPlatform: macos - - pool: - vmImage: macos-10.15 - - steps: - - template: ./macos-steps.yml - parameters: - targetBranch: $(System.PullRequest.TargetBranch) - - -- job: Ubuntu_PR_Tests - displayName: Ubuntu PR Tests +- job: Ubuntu_Patchcheck + displayName: Ubuntu patchcheck dependsOn: Prebuild condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) @@ -49,63 +26,3 @@ jobs: steps: - template: ./posix-steps.yml - parameters: - dependencies: apt - - -- job: Ubuntu_Coverage_PR_Tests - displayName: Ubuntu PR Tests (coverage) - dependsOn: Prebuild - condition: | - and( - and( - succeeded(), - eq(variables['coverage'], 'true') - ), - eq(dependencies.Prebuild.outputs['tests.run'], 'true') - ) - - pool: - vmImage: ubuntu-22.04 - - variables: - testRunTitle: '$(Build.SourceBranchName)-linux-coverage' - testRunPlatform: linux-coverage - openssl_version: 1.1.1u - - steps: - - template: ./posix-steps.yml - parameters: - dependencies: apt - coverage: true - - -- job: Windows_PR_Tests - displayName: Windows PR Tests - dependsOn: Prebuild - condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) - - pool: - vmImage: windows-2022 - - strategy: - matrix: - win32: - arch: win32 - buildOpt: '-p Win32' - testRunTitle: '$(System.PullRequest.TargetBranch)-win32' - testRunPlatform: win32 - win64: - arch: amd64 - buildOpt: '-p x64' - testRunTitle: '$(System.PullRequest.TargetBranch)-win64' - testRunPlatform: win64 - winarm64: - arch: arm64 - buildOpt: '-p arm64' - maxParallel: 4 - - steps: - - template: ./windows-steps.yml - parameters: - targetBranch: $(System.PullRequest.TargetBranch) diff --git a/.cirrus-DISABLED.yml b/.cirrus-DISABLED.yml new file mode 100644 index 00000000000000..f20835cb6cac2a --- /dev/null +++ b/.cirrus-DISABLED.yml @@ -0,0 +1,29 @@ +# gh-91960: Job disabled since Python is out of free credit (September 2023): +# https://discuss.python.org/t/freebsd-gets-a-new-cirrus-ci-github-action-job-and-a-new-buildbot/33122/26 + +freebsd_task: + freebsd_instance: + matrix: + - image: freebsd-13-2-release-amd64 + # Turn off TCP and UDP blackhole. It is not enabled by default in FreeBSD, + # but it is in the FreeBSD GCE images as used by Cirrus-CI. It causes even + # local local connections to fail with ETIMEDOUT instead of ECONNREFUSED. + # For more information see https://reviews.freebsd.org/D41751 and + # https://github.com/cirruslabs/cirrus-ci-docs/issues/483. + sysctl_script: + - sysctl net.inet.tcp.blackhole=0 + - sysctl net.inet.udp.blackhole=0 + configure_script: + - mkdir build + - cd build + - ../configure --with-pydebug + build_script: + - cd build + - make -j$(sysctl -n hw.ncpu) + pythoninfo_script: + - cd build + - make pythoninfo + test_script: + - cd build + # dtrace fails to build on FreeBSD - see gh-73263 + - make buildbottest TESTOPTS="-j0 -x test_dtrace --timeout=600" diff --git a/.coveragerc b/.coveragerc index 18bf2f40fe523f..b5d94317e8aa8b 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,6 +7,11 @@ exclude_lines = # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.: + raise AssertionError\( + + # Empty bodies in protocols or abstract methods + ^\s*def [a-zA-Z0-9_]+\(.*\)(\s*->.*)?:\s*\.\.\.(\s*#.*)?$ + ^\s*\.\.\.(\s*#.*)?$ .*# pragma: no cover .*# pragma: no branch diff --git a/.editorconfig b/.editorconfig index 81445d2d79c739..0169eed951cd3f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,5 +8,8 @@ indent_style = space [*.{py,c,cpp,h}] indent_size = 4 +[*.rst] +indent_size = 3 + [*.yml] indent_size = 2 diff --git a/.gitattributes b/.gitattributes index 5d5558da711b17..8c37dbbb631022 100644 --- a/.gitattributes +++ b/.gitattributes @@ -24,7 +24,7 @@ PC/classicAppCompat.* binary [attr]noeol -text Lib/test/cjkencodings/* noeol -Lib/test/coding20731.py noeol +Lib/test/tokenizedata/coding20731.py noeol Lib/test/decimaltestdata/*.decTest noeol Lib/test/test_email/data/*.txt noeol Lib/test/test_importlib/resources/data01/* noeol @@ -66,15 +66,20 @@ PCbuild/readme.txt dos [attr]generated linguist-generated=true diff=generated **/clinic/*.c.h generated +**/clinic/*.cpp.h generated +**/clinic/*.h.h generated *_db.h generated Doc/data/stable_abi.dat generated Doc/library/token-list.inc generated Include/internal/pycore_ast.h generated Include/internal/pycore_ast_state.h generated Include/internal/pycore_opcode.h generated +Include/internal/pycore_opcode_metadata.h generated Include/internal/pycore_*_generated.h generated Include/opcode.h generated +Include/opcode_ids.h generated Include/token.h generated +Lib/_opcode_metadata.py generated Lib/keyword.py generated Lib/test/levenshtein_examples.json generated Lib/test/test_stable_abi_ctypes.py generated @@ -87,6 +92,7 @@ Programs/test_frozenmain.h generated Python/Python-ast.c generated Python/executor_cases.c.h generated Python/generated_cases.c.h generated +Python/abstract_interp_cases.c.h generated Python/opcode_targets.h generated Python/stdlib_module_names.h generated Tools/peg_generator/pegen/grammar_parser.py generated diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 882ba9e9c9ebea..cd35cba5b5c56d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,6 +9,7 @@ # pre-commit .pre-commit-config.yaml @hugovk @AlexWaygood +.ruff.toml @hugovk @AlexWaygood # Build system configure* @erlend-aasland @corona10 @@ -69,6 +70,7 @@ Python/traceback.c @iritkatriel # Import (including importlib). **/*import* @brettcannon @ericsnowcurrently @ncoghlan @warsaw +/Python/import.c @kumaraditya303 **/*importlib/resources/* @jaraco @warsaw @FFY00 **/importlib/metadata/* @jaraco @warsaw @@ -178,3 +180,6 @@ Doc/c-api/stable.rst @encukou /Tools/clinic/** @erlend-aasland @AlexWaygood /Lib/test/test_clinic.py @erlend-aasland @AlexWaygood Doc/howto/clinic.rst @erlend-aasland + +# WebAssembly +/Tools/wasm/ @brettcannon diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md deleted file mode 100644 index 1d93e0735e50f3..00000000000000 --- a/.github/ISSUE_TEMPLATE/bug.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Bug report -about: Submit a bug report -labels: "type-bug" ---- - - - -# Bug report - -A clear and concise description of what the bug is. -Include a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example), if possible. - -# Your environment - - - -- CPython versions tested on: -- Operating system and architecture: - - diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 00000000000000..21a375361bf58e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,55 @@ +name: Bug report +description: Submit a bug report +labels: ["type-bug"] +body: + - type: markdown + attributes: + value: | + **New to Python?** + + For help or advice on using Python, try one of the following options instead of opening a GitHub issue: + + - Asking on [Discourse](https://discuss.python.org/c/users/7) or [Stack Overflow](https://stackoverflow.com) + - Reading the [Python tutorial](https://docs.python.org/3/tutorial/) + - Emailing [python-list](https://mail.python.org/mailman/listinfo/python-list) + + Make sure to also search the [CPython issue tracker](https://github.com/python/cpython/issues?q=is%3Aissue+sort%3Acreated-desc) to check that the bug has not already been reported. + - type: textarea + attributes: + label: "Bug description:" + description: > + Give a clear and concise description of what happened. + Include a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) if possible. + [Copy and paste code where possible rather than using screenshots](https://meta.stackoverflow.com/a/285557/13990016), + and put any code blocks inside triple backticks. + + value: | + ```python + # Add a code block here, if required + ``` + validations: + required: true + - type: dropdown + attributes: + label: "CPython versions tested on:" + multiple: true + options: + - "3.8" + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "CPython main branch" + validations: + required: true + - type: dropdown + attributes: + label: "Operating systems tested on:" + multiple: true + options: + - Linux + - macOS + - Windows + - Other + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/crash.md b/.github/ISSUE_TEMPLATE/crash.md deleted file mode 100644 index dad3423db03410..00000000000000 --- a/.github/ISSUE_TEMPLATE/crash.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Crash report -about: A hard crash of the interpreter, possibly with a core dump -labels: "type-crash" ---- - - - -# Crash report - -Tell us what happened, ideally including a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example). - -# Error messages - -Enter any relevant error message caused by the crash, including a core dump if there is one. - -# Your environment - - - -- CPython versions tested on: -- Operating system and architecture: - - diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml new file mode 100644 index 00000000000000..c14d7cf2599d4c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -0,0 +1,54 @@ +name: Crash report +description: A hard crash of the interpreter, possibly with a core dump +labels: ["type-crash"] +body: + - type: markdown + attributes: + value: | + This form is for hard crashes of the Python interpreter, segmentation faults, failed C-level assertions, and similar. Unexpected exceptions raised from Python functions in the standard library count as bugs rather than crashes. + + The CPython interpreter is written in a different programming language, C. A "CPython crash" is when Python itself fails, leading to a traceback in the C stack. + - type: textarea + attributes: + label: What happened? + description: > + Include a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) if possible. + [Copy and paste code where possible rather than using screenshots](https://meta.stackoverflow.com/a/285557/13990016), + and put any code blocks inside triple backticks. + + value: | + ```python + # Add a code block here, if required + ``` + validations: + required: true + - type: dropdown + attributes: + label: "CPython versions tested on:" + multiple: true + options: + - "3.8" + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "CPython main branch" + validations: + required: true + - type: dropdown + attributes: + label: "Operating systems tested on:" + multiple: true + options: + - Linux + - macOS + - Windows + - Other + validations: + required: false + - type: input + attributes: + label: "Output from running 'python -VV' on the command line:" + description: If you tested with multiple operating systems or architectures, feel free to provide details in the main bug description. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md deleted file mode 100644 index ed051e945f8120..00000000000000 --- a/.github/ISSUE_TEMPLATE/feature.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -name: Feature or enhancement -about: Submit a proposal for a new CPython feature or enhancement -labels: "type-feature" ---- - -# Feature or enhancement - -(A clear and concise description of your proposal.) - -# Pitch - -(Explain why this feature or enhancement should be implemented and how it would be used. - Add examples, if applicable.) - -# Previous discussion - - - - - diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml new file mode 100644 index 00000000000000..4361ab2bf827fb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -0,0 +1,40 @@ +name: Feature or enhancement +description: Submit a proposal for a new CPython feature or enhancement +labels: ["type-feature"] +body: + - type: markdown + attributes: + value: | + # Proposing a feature to CPython? + + You'll need to demonstrate widespread support for your idea among the community. + + Major feature proposals should generally be discussed on [Discourse](https://discuss.python.org/c/ideas/6) before opening a GitHub issue. Wait until it's clear that most people support your idea before filling in this form. + - type: textarea + attributes: + label: "Proposal:" + description: > + Explain your proposal, why it should be implemented, and how it would be used. + Add examples, if applicable. + Put any code blocks inside triple backticks. + value: | + ```python + # Add a code block here, if required + ``` + validations: + required: true + - type: dropdown + attributes: + label: Has this already been discussed elsewhere? + options: + - No response given + - I have already discussed this feature proposal on Discourse + - This is a minor feature, which does not need previous discussion elsewhere + multiple: false + validations: + required: true + - type: textarea + attributes: + label: "Links to previous discussion of this feature:" + validations: + required: false diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f026b0f5f9454a..c8a3165d690364 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,7 +13,7 @@ updates: - "version-update:semver-minor" - "version-update:semver-patch" - package-ecosystem: "pip" - directory: "/Tools/clinic/" + directory: "/Tools/" schedule: interval: "monthly" labels: diff --git a/.github/problem-matchers/sphinx.json b/.github/problem-matchers/sphinx.json deleted file mode 100644 index 09848608a7b034..00000000000000 --- a/.github/problem-matchers/sphinx.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "problemMatcher": [ - { - "owner": "sphinx-problem-matcher", - "pattern": [ - { - "regexp": "^(.*):(\\d+):\\s+(\\w*):\\s+(.*)$", - "file": 1, - "line": 2, - "severity": 3, - "message": 4 - } - ] - }, - { - "owner": "sphinx-problem-matcher-loose", - "pattern": [ - { - "_comment": "A bit of a looser pattern, doesn't look for line numbers, just looks for file names relying on them to start with / and end with .rst", - "regexp": "(\/.*\\.rst):\\s+(\\w*):\\s+(.*)$", - "file": 1, - "severity": 2, - "message": 3 - } - ] - }, - { - "owner": "sphinx-problem-matcher-loose-no-severity", - "pattern": [ - { - "_comment": "Looks for file names ending with .rst and line numbers but without severity", - "regexp": "^(.*\\.rst):(\\d+):(.*)$", - "file": 1, - "line": 2, - "message": 3 - } - ] - } - ] -} \ No newline at end of file diff --git a/.github/workflows/add-issue-header.yml b/.github/workflows/add-issue-header.yml new file mode 100644 index 00000000000000..1ef9178b95e5f6 --- /dev/null +++ b/.github/workflows/add-issue-header.yml @@ -0,0 +1,53 @@ +name: Add issue header +# Automatically edits an issue's descriptions with a header, +# one of: +# +# - Bug report +# - Crash report +# - Feature or enhancement + +on: + issues: + types: + # Only ever run once + - opened + + +jobs: + add-header: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - uses: actions/github-script@v6 + with: + # language=JavaScript + script: | + // https://devguide.python.org/triage/labels/#type-labels + const HEADERS = new Map([ + ['type-bug', 'Bug report'], + ['type-crash', 'Crash report'], + ['type-feature', 'Feature or enhancement'], + ]); + let issue_data = await github.rest.issues.get({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }).then(issue => issue.data); + let header = ''; + for (const label_data of issue_data.labels) { + const label_name = (typeof label_data === 'string') ? label_data : label_data.name; + if (HEADERS.has(label_name)) { + header = HEADERS.get(label_name); + break; + } + } + if (header !== '') { + console.log(`Setting new header: ${header}`); + await github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `# ${header}\n\n${issue_data.body.replaceAll('\r', '')}` + }); + } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 06551b13219c2a..81e85e630bb001 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,9 +40,10 @@ jobs: run-docs: ${{ steps.docs-changes.outputs.run-docs || false }} run_tests: ${{ steps.check.outputs.run_tests }} run_hypothesis: ${{ steps.check.outputs.run_hypothesis }} + run_cifuzz: ${{ steps.check.outputs.run_cifuzz }} config_hash: ${{ steps.config_hash.outputs.hash }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Check for source changes id: check run: | @@ -63,7 +64,7 @@ jobs: # into the PR branch anyway. # # https://github.com/python/core-workflow/issues/373 - git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true + git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc|^\.pre-commit-config\.yaml$|\.ruff\.toml$)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true fi # Check if we should run hypothesis tests @@ -76,6 +77,21 @@ jobs: echo "Run hypothesis tests" echo "run_hypothesis=true" >> $GITHUB_OUTPUT fi + + # oss-fuzz maintains a configuration for fuzzing the main branch of + # CPython, so CIFuzz should be run only for code that is likely to be + # merged into the main branch; compatibility with older branches may + # be broken. + FUZZ_RELEVANT_FILES='(\.c$|\.h$|\.cpp$|^configure$|^\.github/workflows/build\.yml$|^Modules/_xxtestfuzz)' + if [ "$GITHUB_BASE_REF" = "main" ] && [ "$(git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE $FUZZ_RELEVANT_FILES; echo $?)" -eq 0 ]; then + # The tests are pretty slow so they are executed only for PRs + # changing relevant files. + echo "Run CIFuzz tests" + echo "run_cifuzz=true" >> $GITHUB_OUTPUT + else + echo "Branch too old for CIFuzz tests; or no C files were changed" + echo "run_cifuzz=false" >> $GITHUB_OUTPUT + fi - name: Compute hash for config cache key id: config_hash run: | @@ -111,13 +127,15 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Restore config.cache uses: actions/cache@v3 with: path: config.cache key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' - name: Install Dependencies run: sudo ./.github/workflows/posix-deps-apt.sh - name: Add ccache to PATH @@ -138,9 +156,6 @@ jobs: run: make regen-configure - name: Build CPython run: | - # Deepfreeze will usually cause global objects to be added or removed, - # so we run it before regen-global-objects gets rum (in regen-all). - make regen-deepfreeze make -j4 regen-all make regen-stdlib-module-names - name: Check for changes @@ -174,13 +189,13 @@ jobs: env: IncludeUwp: 'true' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build CPython run: .\PCbuild\build.bat -e -d -p Win32 - name: Display build info run: .\python.bat -m test.pythoninfo - name: Tests - run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + run: .\PCbuild\rt.bat -p Win32 -d -q --fast-ci build_win_amd64: name: 'Windows (x64)' @@ -191,7 +206,7 @@ jobs: env: IncludeUwp: 'true' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Register MSVC problem matcher run: echo "::add-matcher::.github/problem-matchers/msvc.json" - name: Build CPython @@ -199,7 +214,22 @@ jobs: - name: Display build info run: .\python.bat -m test.pythoninfo - name: Tests - run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + run: .\PCbuild\rt.bat -p x64 -d -q --fast-ci + + build_win_arm64: + name: 'Windows (arm64)' + runs-on: windows-latest + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + IncludeUwp: 'true' + steps: + - uses: actions/checkout@v4 + - name: Register MSVC problem matcher + run: echo "::add-matcher::.github/problem-matchers/msvc.json" + - name: Build CPython + run: .\PCbuild\build.bat -e -d -p arm64 build_macos: name: 'macOS' @@ -213,7 +243,7 @@ jobs: HOMEBREW_NO_INSTALL_CLEANUP: 1 PYTHONSTRICTEXTENSIONBUILD: 1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Restore config.cache uses: actions/cache@v3 with: @@ -235,7 +265,7 @@ jobs: - name: Display build info run: make pythoninfo - name: Tests - run: make buildbottest TESTOPTS="-j4 -uall,-cpu" + run: make test build_ubuntu: name: 'Ubuntu' @@ -244,10 +274,10 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1u + OPENSSL_VER: 3.0.11 PYTHONSTRICTEXTENSIONBUILD: 1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Register gcc problem matcher run: echo "::add-matcher::.github/problem-matchers/gcc.json" - name: Install Dependencies @@ -302,7 +332,7 @@ jobs: run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw - name: Tests working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" + run: xvfb-run make test build_ubuntu_ssltests: name: 'Ubuntu SSL tests with OpenSSL' @@ -313,14 +343,14 @@ jobs: strategy: fail-fast: false matrix: - openssl_ver: [1.1.1u, 3.0.9, 3.1.1] + openssl_ver: [1.1.1w, 3.0.11, 3.1.3] env: OPENSSL_VER: ${{ matrix.openssl_ver }} MULTISSL_DIR: ${{ github.workspace }}/multissl OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Restore config.cache uses: actions/cache@v3 with: @@ -365,10 +395,10 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_hypothesis == 'true' env: - OPENSSL_VER: 1.1.1u + OPENSSL_VER: 3.0.11 PYTHONSTRICTEXTENSIONBUILD: 1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Register gcc problem matcher run: echo "::add-matcher::.github/problem-matchers/gcc.json" - name: Install Dependencies @@ -431,7 +461,7 @@ jobs: VENV_PYTHON=$VENV_LOC/bin/python echo "HYPOVENV=${VENV_LOC}" >> $GITHUB_ENV echo "VENV_PYTHON=${VENV_PYTHON}" >> $GITHUB_ENV - ./python -m venv $VENV_LOC && $VENV_PYTHON -m pip install -U hypothesis + ./python -m venv $VENV_LOC && $VENV_PYTHON -m pip install -r ${GITHUB_WORKSPACE}/Tools/requirements-hypothesis.txt - name: 'Restore Hypothesis database' id: cache-hypothesis-database uses: actions/cache@v3 @@ -474,11 +504,11 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1u + OPENSSL_VER: 3.0.11 PYTHONSTRICTEXTENSIONBUILD: 1 ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Restore config.cache uses: actions/cache@v3 with: @@ -518,7 +548,47 @@ jobs: - name: Display build info run: make pythoninfo - name: Tests - run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" + run: xvfb-run make test + + # CIFuzz job based on https://google.github.io/oss-fuzz/getting-started/continuous-integration/ + cifuzz: + name: CIFuzz + runs-on: ubuntu-latest + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_cifuzz == 'true' + permissions: + security-events: write + strategy: + fail-fast: false + matrix: + sanitizer: [address, undefined, memory] + steps: + - name: Build fuzzers (${{ matrix.sanitizer }}) + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: cpython3 + sanitizer: ${{ matrix.sanitizer }} + - name: Run fuzzers (${{ matrix.sanitizer }}) + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + fuzz-seconds: 600 + oss-fuzz-project-name: cpython3 + output-sarif: true + sanitizer: ${{ matrix.sanitizer }} + - name: Upload crash + uses: actions/upload-artifact@v3 + if: failure() && steps.build.outcome == 'success' + with: + name: ${{ matrix.sanitizer }}-artifacts + path: ./out/artifacts + - name: Upload SARIF + if: always() && steps.build.outcome == 'success' + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: cifuzz-sarif/results.sarif + checkout_path: cifuzz-sarif all-required-green: # This job does nothing and is only used for the branch protection name: All required checks pass @@ -530,11 +600,13 @@ jobs: - check_generated_files - build_win32 - build_win_amd64 + - build_win_arm64 - build_macos - build_ubuntu - build_ubuntu_ssltests - test_hypothesis - build_asan + - cifuzz runs-on: ubuntu-latest @@ -546,6 +618,8 @@ jobs: build_macos, build_ubuntu_ssltests, build_win32, + build_win_arm64, + cifuzz, test_hypothesis, allowed-skips: >- ${{ @@ -561,6 +635,7 @@ jobs: check_generated_files, build_win32, build_win_amd64, + build_win_arm64, build_macos, build_ubuntu, build_ubuntu_ssltests, @@ -568,6 +643,13 @@ jobs: ' || '' }} + ${{ + !fromJSON(needs.check_source.outputs.run_cifuzz) + && ' + cifuzz, + ' + || '' + }} ${{ !fromJSON(needs.check_source.outputs.run_hypothesis) && ' diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml index 22f613a88aa11e..29282dffa37ec0 100644 --- a/.github/workflows/build_msi.yml +++ b/.github/workflows/build_msi.yml @@ -33,6 +33,6 @@ jobs: matrix: type: [x86, x64, arm64] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build CPython installer run: .\Tools\msi\build.bat --doc -${{ matrix.type }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4481ea80bfd936..6c1c29a58cf4fc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,6 +5,10 @@ on: [push, pull_request, workflow_dispatch] permissions: contents: read +env: + FORCE_COLOR: 1 + RUFF_OUTPUT_FORMAT: github + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true @@ -15,7 +19,7 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.x" diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 1315bb5a966f01..405511ca6820b3 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -7,8 +7,12 @@ on: - main pull_request: paths: - - "Tools/clinic/**" - ".github/workflows/mypy.yml" + - "Tools/cases_generator/**" + - "Tools/clinic/**" + - "Tools/peg_generator/**" + - "Tools/requirements-dev.txt" + - "Tools/wasm/**" workflow_dispatch: permissions: @@ -25,15 +29,23 @@ concurrency: jobs: mypy: - name: Run mypy on Tools/clinic/ + strategy: + matrix: + target: [ + "Tools/cases_generator", + "Tools/clinic", + "Tools/peg_generator", + "Tools/wasm", + ] + name: Run mypy on ${{ matrix.target }} runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.x" + python-version: "3.11" cache: pip - cache-dependency-path: Tools/clinic/requirements-dev.txt - - run: pip install -r Tools/clinic/requirements-dev.txt - - run: mypy --config-file Tools/clinic/mypy.ini + cache-dependency-path: Tools/requirements-dev.txt + - run: pip install -r Tools/requirements-dev.txt + - run: mypy --config-file ${{ matrix.target }}/mypy.ini diff --git a/.github/workflows/require-pr-label.yml b/.github/workflows/require-pr-label.yml index 9327b43ae02710..080204bcfd3b94 100644 --- a/.github/workflows/require-pr-label.yml +++ b/.github/workflows/require-pr-label.yml @@ -5,8 +5,8 @@ on: types: [opened, reopened, labeled, unlabeled, synchronize] permissions: - issues: read - pull-requests: read + issues: write + pull-requests: write jobs: label: diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index b39d8cea6421ea..1c4fa4239c1e34 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -16,10 +16,30 @@ jobs: name: 'Docs' runs-on: ubuntu-latest timeout-minutes: 60 + env: + branch_base: 'origin/${{ github.event.pull_request.base.ref }}' + branch_pr: 'origin/${{ github.event.pull_request.head.ref }}' + refspec_base: '+${{ github.event.pull_request.base.sha }}:remotes/origin/${{ github.event.pull_request.base.ref }}' + refspec_pr: '+${{ github.event.pull_request.head.sha }}:remotes/origin/${{ github.event.pull_request.head.ref }}' steps: - - uses: actions/checkout@v3 - - name: Register Sphinx problem matcher - run: echo "::add-matcher::.github/problem-matchers/sphinx.json" + - name: 'Check out latest PR branch commit' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + # Adapted from https://github.com/actions/checkout/issues/520#issuecomment-1167205721 + - name: 'Fetch commits to get branch diff' + run: | + # Fetch enough history to find a common ancestor commit (aka merge-base): + git fetch origin ${{ env.refspec_pr }} --depth=$(( ${{ github.event.pull_request.commits }} + 1 )) \ + --no-tags --prune --no-recurse-submodules + + # This should get the oldest commit in the local fetched history (which may not be the commit the PR branched from): + COMMON_ANCESTOR=$( git rev-list --first-parent --max-parents=0 --max-count=1 ${{ env.branch_pr }} ) + DATE=$( git log --date=iso8601 --format=%cd "${COMMON_ANCESTOR}" ) + + # Get all commits since that commit date from the base branch (eg: master or main): + git fetch origin ${{ env.refspec_base }} --shallow-since="${DATE}" \ + --no-tags --prune --no-recurse-submodules - name: 'Set up Python' uses: actions/setup-python@v4 with: @@ -28,35 +48,21 @@ jobs: cache-dependency-path: 'Doc/requirements.txt' - name: 'Install build dependencies' run: make -C Doc/ venv - - name: 'Build HTML documentation' - run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html - # Add pull request annotations for Sphinx nitpicks (missing references) - - name: 'Get list of changed files' - if: github.event_name == 'pull_request' - id: changed_files - uses: Ana06/get-changed-files@v2.2.0 - with: - filter: "Doc/**" - format: csv # works for paths with spaces - - name: 'Build changed files in nit-picky mode' - if: github.event_name == 'pull_request' + # To annotate PRs with Sphinx nitpicks (missing references) + - name: 'Build HTML documentation' continue-on-error: true run: | set -Eeuo pipefail - # Mark files the pull request modified - python Doc/tools/touch-clean-files.py --clean '${{ steps.changed_files.outputs.added_modified }}' - # Build docs with the '-n' (nit-picky) option; convert warnings to annotations - make -C Doc/ PYTHON=../python SPHINXOPTS="-q -n --keep-going" html 2>&1 | - python Doc/tools/warnings-to-gh-actions.py - - # Ensure some files always pass Sphinx nit-picky mode (no missing references) - - name: 'Build known-good files in nit-picky mode' + # Build docs with the '-n' (nit-picky) option; write warnings to file + make -C Doc/ PYTHON=../python SPHINXOPTS="-q -n -W --keep-going -w sphinx-warnings.txt" html + - name: 'Check warnings' + if: github.event_name == 'pull_request' run: | - # Mark files that must pass nit-picky - python Doc/tools/touch-clean-files.py - # Build docs with the '-n' (nit-picky) option, convert warnings to errors (-W) - make -C Doc/ PYTHON=../python SPHINXOPTS="-q -n -W --keep-going" html 2>&1 + python Doc/tools/check-warnings.py \ + --annotate-diff '${{ env.branch_base }}' '${{ env.branch_pr }}' \ + --fail-if-regression \ + --fail-if-improved # This build doesn't use problem matchers or check annotations build_doc_oldest_supported_sphinx: @@ -64,11 +70,11 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 60 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: 'Set up Python' uses: actions/setup-python@v4 with: - python-version: '3.11' # known to work with Sphinx 3.2 + python-version: '3.11' # known to work with Sphinx 4.2 cache: 'pip' cache-dependency-path: 'Doc/requirements-oldest-sphinx.txt' - name: 'Install build dependencies' @@ -82,9 +88,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 60 steps: - - uses: actions/checkout@v3 - - name: Register Sphinx problem matcher - run: echo "::add-matcher::.github/problem-matchers/sphinx.json" + - uses: actions/checkout@v4 - uses: actions/cache@v3 with: path: ~/.cache/pip diff --git a/.github/workflows/verify-ensurepip-wheels.yml b/.github/workflows/verify-ensurepip-wheels.yml index 17d841f1f1c54a..4a545037bf6e2b 100644 --- a/.github/workflows/verify-ensurepip-wheels.yml +++ b/.github/workflows/verify-ensurepip-wheels.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: '3' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d62c57c044728f..4835b641b3106a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,18 +1,37 @@ repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.292 + hooks: + - id: ruff + name: Run Ruff on Lib/test/ + args: [--exit-non-zero-on-fix] + files: ^Lib/test/ + - id: ruff + name: Run Ruff on Argument Clinic + args: [--exit-non-zero-on-fix, --config=Tools/clinic/.ruff.toml] + files: ^Tools/clinic/|Lib/test/test_clinic.py + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: + - id: check-toml + exclude: ^Lib/test/test_tomllib/ - id: check-yaml - id: end-of-file-fixer types: [python] - exclude: Lib/test/coding20731.py + exclude: Lib/test/tokenizedata/coding20731.py - id: trailing-whitespace - types_or: [c, python, rst] + types_or: [c, inc, python, rst] - repo: https://github.com/sphinx-contrib/sphinx-lint - rev: v0.6.7 + rev: v0.7.0 hooks: - id: sphinx-lint - args: [--enable=default-role] - files: ^Doc/ + args: [--enable=default-role, -j1] + files: ^Doc/|^Misc/NEWS.d/next/ types: [rst] + + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes diff --git a/Doc/Makefile b/Doc/Makefile index 22691895068fea..78ee4271e25f79 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -7,7 +7,6 @@ PYTHON = python3 VENVDIR = ./venv SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-build -SPHINXLINT = PATH=$(VENVDIR)/bin:$$PATH sphinx-lint BLURB = PATH=$(VENVDIR)/bin:$$PATH blurb JOBS = auto PAPER = diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst index 0a8fcc5ae5fcdf..b3609c233156b6 100644 --- a/Doc/c-api/allocation.rst +++ b/Doc/c-api/allocation.rst @@ -27,22 +27,26 @@ Allocating Objects on the Heap length information for a variable-size object. -.. c:function:: TYPE* PyObject_New(TYPE, PyTypeObject *type) +.. c:macro:: PyObject_New(TYPE, typeobj) - Allocate a new Python object using the C structure type *TYPE* and the - Python type object *type*. Fields not defined by the Python object header - are not initialized; the object's reference count will be one. The size of - the memory allocation is determined from the :c:member:`~PyTypeObject.tp_basicsize` field of - the type object. + Allocate a new Python object using the C structure type *TYPE* + and the Python type object *typeobj* (``PyTypeObject*``). + Fields not defined by the Python object header are not initialized. + The caller will own the only reference to the object + (i.e. its reference count will be one). + The size of the memory allocation is determined from the + :c:member:`~PyTypeObject.tp_basicsize` field of the type object. -.. c:function:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) +.. c:macro:: PyObject_NewVar(TYPE, typeobj, size) Allocate a new Python object using the C structure type *TYPE* and the - Python type object *type*. Fields not defined by the Python object header + Python type object *typeobj* (``PyTypeObject*``). + Fields not defined by the Python object header are not initialized. The allocated memory allows for the *TYPE* structure - plus *size* fields of the size given by the :c:member:`~PyTypeObject.tp_itemsize` field of - *type*. This is useful for implementing objects like tuples, which are + plus *size* (``Py_ssize_t``) fields of the size + given by the :c:member:`~PyTypeObject.tp_itemsize` field of + *typeobj*. This is useful for implementing objects like tuples, which are able to determine their size at construction time. Embedding the array of fields into the same allocation decreases the number of allocations, improving the memory management efficiency. @@ -50,8 +54,8 @@ Allocating Objects on the Heap .. 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 + Releases memory allocated to an object using :c:macro:`PyObject_New` or + :c:macro:`PyObject_NewVar`. This is normally called from the :c:member:`~PyTypeObject.tp_dealloc` handler specified in the object's type. The fields of the object should not be accessed after this call as the memory is no longer a valid Python object. diff --git a/Doc/c-api/apiabiversion.rst b/Doc/c-api/apiabiversion.rst index 62d542966622ce..f6c8284daeacb0 100644 --- a/Doc/c-api/apiabiversion.rst +++ b/Doc/c-api/apiabiversion.rst @@ -60,7 +60,7 @@ See :ref:`stable` for a discussion of API and ABI stability across versions. Use this for numeric comparisons, e.g. ``#if PY_VERSION_HEX >= ...``. - This version is also available via the symbol :data:`Py_Version`. + This version is also available via the symbol :c:var:`Py_Version`. .. c:var:: const unsigned long Py_Version diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index d2ea490732fe59..c43dd0f4303cd4 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -293,8 +293,10 @@ Other objects ``O`` (object) [PyObject \*] Store a Python object (without any conversion) in a C object pointer. The C - program thus receives the actual object that was passed. The object's reference - count is not increased. The pointer stored is not ``NULL``. + program thus receives the actual object that was passed. A new + :term:`strong reference` to the object is not created + (i.e. its reference count is not increased). + The pointer stored is not ``NULL``. ``O!`` (object) [*typeobject*, PyObject \*] Store a Python object in a C object pointer. This is similar to ``O``, but @@ -343,7 +345,7 @@ Other objects *items*. Format units for sequences may be nested. It is possible to pass "long" integers (integers whose value exceeds the -platform's :const:`LONG_MAX`) however no proper range checking is done --- the +platform's :c:macro:`LONG_MAX`) however no proper range checking is done --- the most significant bits are silently truncated when the receiving field is too small to receive the value (actually, the semantics are inherited from downcasts in C --- your mileage may vary). @@ -378,7 +380,8 @@ inside nested parentheses. They are: mutually exclude each other. Note that any Python object references which are provided to the caller are -*borrowed* references; do not decrement their reference count! +*borrowed* references; do not release them +(i.e. do not decrement their reference count)! Additional arguments passed to these functions must be addresses of variables whose type is determined by the format string; these are used to store values @@ -463,7 +466,7 @@ API Functions A simpler form of parameter retrieval which does not use a format string to specify the types of the arguments. Functions which use this method to retrieve - their parameters should be declared as :const:`METH_VARARGS` in function or + their parameters should be declared as :c:macro:`METH_VARARGS` in function or method tables. The tuple containing the actual parameters should be passed as *args*; it must actually be a tuple. The length of the tuple must be at least *min* and no more than *max*; *min* and *max* may be equal. Additional @@ -477,7 +480,7 @@ API Functions will be set if there was a failure. This is an example of the use of this function, taken from the sources for the - :mod:`_weakref` helper module for weak references:: + :mod:`!_weakref` helper module for weak references:: static PyObject * weakref_ref(PyObject *self, PyObject *args) @@ -555,7 +558,7 @@ Building values Same as ``s#``. ``u`` (:class:`str`) [const wchar_t \*] - Convert a null-terminated :c:expr:`wchar_t` buffer of Unicode (UTF-16 or UCS-4) + Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4) data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, ``None`` is returned. @@ -621,8 +624,10 @@ Building values Convert a C :c:type:`Py_complex` structure to a Python complex number. ``O`` (object) [PyObject \*] - Pass a Python object untouched (except for its reference count, which is - incremented by one). If the object passed in is a ``NULL`` pointer, it is assumed + Pass a Python object untouched but create a new + :term:`strong reference` to it + (i.e. its reference count is incremented by one). + If the object passed in is a ``NULL`` pointer, it is assumed that this was caused because the call producing the argument found an error and set an exception. Therefore, :c:func:`Py_BuildValue` will return ``NULL`` but won't raise an exception. If no exception has been raised yet, :exc:`SystemError` is @@ -632,7 +637,7 @@ Building values Same as ``O``. ``N`` (object) [PyObject \*] - Same as ``O``, except it doesn't increment the reference count on the object. + Same as ``O``, except it doesn't create a new :term:`strong reference`. Useful when the object is created by a call to an object constructor in the argument list. diff --git a/Doc/c-api/bool.rst b/Doc/c-api/bool.rst index b2d8f2124fc203..b14fa6a0a982e2 100644 --- a/Doc/c-api/bool.rst +++ b/Doc/c-api/bool.rst @@ -11,6 +11,12 @@ creation and deletion functions don't apply to booleans. The following macros are available, however. +.. c:var:: PyTypeObject PyBool_Type + + This instance of :c:type:`PyTypeObject` represents the Python boolean type; it + is the same object as :class:`bool` in the Python layer. + + .. c:function:: int PyBool_Check(PyObject *o) Return true if *o* is of type :c:data:`PyBool_Type`. This function always diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index 91d1edd9b2ec46..e572815ffd6259 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -44,7 +44,7 @@ the elements exposed by an :class:`array.array` can be multi-byte values. An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write` method of file objects: any object that can export a series of bytes through -the buffer interface can be written to a file. While :meth:`write` only +the buffer interface can be written to a file. While :meth:`!write` only needs read-only access to the internal contents of the object passed to it, other methods such as :meth:`~io.BufferedIOBase.readinto` need write access to the contents of their argument. The buffer interface allows objects to @@ -102,7 +102,9 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. c:member:: PyObject *obj A new reference to the exporting object. The reference is owned by - the consumer and automatically decremented and set to ``NULL`` by + the consumer and automatically released + (i.e. reference count decremented) + and set to ``NULL`` by :c:func:`PyBuffer_Release`. The field is the equivalent of the return value of any standard C-API function. @@ -159,10 +161,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. If it is ``0``, :c:member:`~Py_buffer.buf` points to a single item representing a scalar. In this case, :c:member:`~Py_buffer.shape`, :c:member:`~Py_buffer.strides` and :c:member:`~Py_buffer.suboffsets` MUST be ``NULL``. - - The macro :c:macro:`PyBUF_MAX_NDIM` limits the maximum number of dimensions - to 64. Exporters MUST respect this limit, consumers of multi-dimensional - buffers SHOULD be able to handle up to :c:macro:`PyBUF_MAX_NDIM` dimensions. + The maximum number of dimensions is given by :c:macro:`PyBUF_MAX_NDIM`. .. c:member:: Py_ssize_t *shape @@ -215,6 +214,17 @@ a buffer, see :c:func:`PyObject_GetBuffer`. freed when the buffer is released. The consumer MUST NOT alter this value. + +Constants: + +.. c:macro:: PyBUF_MAX_NDIM + + The maximum number of dimensions the memory represents. + Exporters MUST respect this limit, consumers of multi-dimensional + buffers SHOULD be able to handle up to :c:macro:`!PyBUF_MAX_NDIM` dimensions. + Currently set to 64. + + .. _buffer-request-types: Buffer request types @@ -225,7 +235,7 @@ object via :c:func:`PyObject_GetBuffer`. Since the complexity of the logical structure of the memory can vary drastically, the consumer uses the *flags* argument to specify the exact buffer type it can handle. -All :c:data:`Py_buffer` fields are unambiguously defined by the request +All :c:type:`Py_buffer` fields are unambiguously defined by the request type. request-independent fields @@ -438,7 +448,7 @@ Buffer-related functions Send a request to *exporter* to fill in *view* as specified by *flags*. If the exporter cannot provide a buffer of the exact type, it MUST raise - :c:data:`PyExc_BufferError`, set ``view->obj`` to ``NULL`` and + :exc:`BufferError`, set ``view->obj`` to ``NULL`` and return ``-1``. On success, fill in *view*, set ``view->obj`` to a new reference @@ -454,7 +464,8 @@ Buffer-related functions .. c:function:: void PyBuffer_Release(Py_buffer *view) - Release the buffer *view* and decrement the reference count for + Release the buffer *view* and release the :term:`strong reference` + (i.e. decrement the reference count) to the view's supporting object, ``view->obj``. This function MUST be called when the buffer is no longer being used, otherwise reference leaks may occur. @@ -464,7 +475,7 @@ Buffer-related functions .. c:function:: Py_ssize_t PyBuffer_SizeFromFormat(const char *format) - Return the implied :c:data:`~Py_buffer.itemsize` from :c:data:`~Py_buffer.format`. + Return the implied :c:member:`~Py_buffer.itemsize` from :c:member:`~Py_buffer.format`. On error, raise an exception and return -1. .. versionadded:: 3.9 @@ -524,7 +535,7 @@ Buffer-related functions and :c:macro:`PyBUF_WRITABLE` is set in *flags*. On success, set ``view->obj`` to a new reference to *exporter* and - return 0. Otherwise, raise :c:data:`PyExc_BufferError`, set + return 0. Otherwise, raise :exc:`BufferError`, set ``view->obj`` to ``NULL`` and return ``-1``; If this function is used as part of a :ref:`getbufferproc `, diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index 9f48f2ffafe170..61a68f52773882 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -64,39 +64,39 @@ called with a non-bytes parameter. +-------------------+---------------+--------------------------------+ | Format Characters | Type | Comment | +===================+===============+================================+ - | :attr:`%%` | *n/a* | The literal % character. | + | ``%%`` | *n/a* | The literal % character. | +-------------------+---------------+--------------------------------+ - | :attr:`%c` | int | A single byte, | + | ``%c`` | int | A single byte, | | | | represented as a C int. | +-------------------+---------------+--------------------------------+ - | :attr:`%d` | int | Equivalent to | + | ``%d`` | int | Equivalent to | | | | ``printf("%d")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%u` | unsigned int | Equivalent to | + | ``%u`` | unsigned int | Equivalent to | | | | ``printf("%u")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%ld` | long | Equivalent to | + | ``%ld`` | long | Equivalent to | | | | ``printf("%ld")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%lu` | unsigned long | Equivalent to | + | ``%lu`` | unsigned long | Equivalent to | | | | ``printf("%lu")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%zd` | :c:type:`\ | Equivalent to | + | ``%zd`` | :c:type:`\ | Equivalent to | | | Py_ssize_t` | ``printf("%zd")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%zu` | size_t | Equivalent to | + | ``%zu`` | size_t | Equivalent to | | | | ``printf("%zu")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%i` | int | Equivalent to | + | ``%i`` | int | Equivalent to | | | | ``printf("%i")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%x` | int | Equivalent to | + | ``%x`` | int | Equivalent to | | | | ``printf("%x")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%s` | const char\* | A null-terminated C character | + | ``%s`` | const char\* | A null-terminated C character | | | | array. | +-------------------+---------------+--------------------------------+ - | :attr:`%p` | const void\* | The hex representation of a C | + | ``%p`` | const void\* | The hex representation of a C | | | | pointer. Mostly equivalent to | | | | ``printf("%p")`` except that | | | | it is guaranteed to start with | @@ -184,8 +184,8 @@ called with a non-bytes parameter. .. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart) Create a new bytes object in *\*bytes* containing the contents of *newpart* - appended to *bytes*. This version decrements the reference count of - *newpart*. + appended to *bytes*. This version releases the :term:`strong reference` + to *newpart* (i.e. decrements its reference count). .. c:function:: int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize) diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index ac6242701c5047..aed4ae44c76eea 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -59,12 +59,12 @@ This bears repeating: .. versionchanged:: 3.12 - The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class + The :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class when the class's :py:meth:`~object.__call__` method is reassigned. (This internally sets :c:member:`~PyTypeObject.tp_call` only, and thus may make it behave differently than the vectorcall function.) In earlier Python versions, vectorcall should only be used with - :const:`immutable ` or static types. + :c:macro:`immutable ` or static types. A class should not implement vectorcall if that would be slower than *tp_call*. For example, if the callee needs to convert @@ -72,7 +72,7 @@ the arguments to an args tuple and kwargs dict anyway, then there is no point in implementing vectorcall. Classes can implement the vectorcall protocol by enabling the -:const:`Py_TPFLAGS_HAVE_VECTORCALL` flag and setting +:c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag and setting :c:member:`~PyTypeObject.tp_vectorcall_offset` to the offset inside the object structure where a *vectorcallfunc* appears. This is a pointer to a function with the following signature: @@ -84,7 +84,7 @@ This is a pointer to a function with the following signature: values of the keyword arguments. This can be *NULL* if there are no arguments. - *nargsf* is the number of positional arguments plus possibly the - :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` flag. + :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET` flag. To get the actual number of positional arguments from *nargsf*, use :c:func:`PyVectorcall_NARGS`. - *kwnames* is a tuple containing the names of the keyword arguments; @@ -93,7 +93,7 @@ This is a pointer to a function with the following signature: and they must be unique. If there are no keyword arguments, then *kwnames* can instead be *NULL*. -.. data:: PY_VECTORCALL_ARGUMENTS_OFFSET +.. c:macro:: PY_VECTORCALL_ARGUMENTS_OFFSET If this flag is set in a vectorcall *nargsf* argument, the callee is allowed to temporarily change ``args[-1]``. In other words, *args* points to @@ -104,7 +104,7 @@ This is a pointer to a function with the following signature: ``args[0]`` may be changed. Whenever they can do so cheaply (without additional allocation), callers - are encouraged to use :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`. + are encouraged to use :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET`. Doing so will allow callables such as bound methods to make their onward calls (which include a prepended *self* argument) very efficiently. @@ -152,7 +152,7 @@ Vectorcall Support API This is mostly useful to check whether or not *op* supports vectorcall, which can be done by checking ``PyVectorcall_Function(op) != NULL``. - .. versionadded:: 3.8 + .. versionadded:: 3.9 .. c:function:: PyObject* PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict) @@ -161,7 +161,7 @@ Vectorcall Support API This is a specialized function, intended to be put in the :c:member:`~PyTypeObject.tp_call` slot or be used in an implementation of ``tp_call``. - It does not check the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag + It does not check the :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag and it does not fall back to ``tp_call``. .. versionadded:: 3.8 @@ -379,11 +379,11 @@ please see individual documentation for details. *args[0]*, and the *args* array starting at *args[1]* represents the arguments of the call. There must be at least one positional argument. *nargsf* is the number of positional arguments including *args[0]*, - plus :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` if the value of ``args[0]`` may + plus :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET` if the value of ``args[0]`` may temporarily be changed. Keyword arguments can be passed just like in :c:func:`PyObject_Vectorcall`. - If the object has the :const:`Py_TPFLAGS_METHOD_DESCRIPTOR` feature, + If the object has the :c:macro:`Py_TPFLAGS_METHOD_DESCRIPTOR` feature, this will call the unbound method object with the full *args* vector as arguments. diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst index 427ed959c58568..cdb8aa33e9fd32 100644 --- a/Doc/c-api/capsule.rst +++ b/Doc/c-api/capsule.rst @@ -64,7 +64,7 @@ Refer to :ref:`using-capsules` for more information on using these objects. The *name* parameter must compare exactly to the name stored in the capsule. If the name stored in the capsule is ``NULL``, the *name* passed in must also - be ``NULL``. Python uses the C function :c:func:`strcmp` to compare capsule + be ``NULL``. Python uses the C function :c:func:`!strcmp` to compare capsule names. @@ -121,7 +121,7 @@ Refer to :ref:`using-capsules` for more information on using these objects. compared.) In other words, if :c:func:`PyCapsule_IsValid` returns a true value, calls to - any of the accessors (any function starting with :c:func:`PyCapsule_Get`) are + any of the accessors (any function starting with ``PyCapsule_Get``) are guaranteed to succeed. Return a nonzero value if the object is valid and matches the name passed in. diff --git a/Doc/c-api/cell.rst b/Doc/c-api/cell.rst index ac4ef5adc5cc20..f8cd0344fdd1c0 100644 --- a/Doc/c-api/cell.rst +++ b/Doc/c-api/cell.rst @@ -25,7 +25,7 @@ Cell objects are not likely to be useful elsewhere. The type object corresponding to cell objects. -.. c:function:: int PyCell_Check(ob) +.. c:function:: int PyCell_Check(PyObject *ob) Return true if *ob* is a cell object; *ob* must not be ``NULL``. This function always succeeds. diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index a99de9904c0740..5082b0cb6ad3f3 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -33,20 +33,20 @@ bound into a function. Return the number of free variables in *co*. -.. c:function:: PyCodeObject* PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable) +.. c:function:: PyCodeObject* PyUnstable_Code_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, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable) Return a new code object. If you need a dummy code object to create a frame, use :c:func:`PyCode_NewEmpty` instead. Since the definition of the bytecode changes often, calling - :c:func:`PyCode_New` directly can bind you to a precise Python version. + :c:func:`PyUnstable_Code_New` directly can bind you to a precise Python version. The many arguments of this function are inter-dependent in complex ways, meaning that subtle changes to values are likely to result in incorrect execution or VM crashes. Use this function only with extreme care. .. versionchanged:: 3.11 - Added ``exceptiontable`` parameter. + Added ``qualname`` and ``exceptiontable`` parameters. .. index:: single: PyCode_New @@ -56,17 +56,17 @@ bound into a function. The old name is deprecated, but will remain available until the signature changes again. -.. c:function:: PyCodeObject* PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable) +.. c:function:: PyCodeObject* PyUnstable_Code_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, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable) - Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positional-only arguments. - The same caveats that apply to ``PyCode_New`` also apply to this function. + Similar to :c:func:`PyUnstable_Code_New`, but with an extra "posonlyargcount" for positional-only arguments. + The same caveats that apply to ``PyUnstable_Code_New`` also apply to this function. .. index:: single: PyCode_NewWithPosOnlyArgs .. versionadded:: 3.8 as ``PyCode_NewWithPosOnlyArgs`` .. versionchanged:: 3.11 - Added ``exceptiontable`` parameter. + Added ``qualname`` and ``exceptiontable`` parameters. .. versionchanged:: 3.12 diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst index 235c77c945cc5b..8ae5c4fecd6248 100644 --- a/Doc/c-api/codec.rst +++ b/Doc/c-api/codec.rst @@ -7,7 +7,7 @@ Codec registry and support functions Register a new codec search function. - As side effect, this tries to load the :mod:`encodings` package, if not yet + As side effect, this tries to load the :mod:`!encodings` package, if not yet done, to make sure that it is always first in the list of search functions. .. c:function:: int PyCodec_Unregister(PyObject *search_function) diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst index cb8b270fcbab6e..e3fd001c599c80 100644 --- a/Doc/c-api/complex.rst +++ b/Doc/c-api/complex.rst @@ -64,7 +64,7 @@ pointers. This is consistent throughout the API. representation. If *divisor* is null, this method returns zero and sets - :c:data:`errno` to :c:data:`EDOM`. + :c:data:`errno` to :c:macro:`!EDOM`. .. c:function:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp) @@ -73,7 +73,7 @@ pointers. This is consistent throughout the API. representation. If *num* is null and *exp* is not a positive real number, - this method returns zero and sets :c:data:`errno` to :c:data:`EDOM`. + this method returns zero and sets :c:data:`errno` to :c:macro:`!EDOM`. Complex Numbers as Python Objects diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index fdb321fe7ab3f2..c5350123dfdfdc 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -119,10 +119,10 @@ The following functions provide locale-independent string to number conversions. .. c:function:: int PyOS_stricmp(const char *s1, const char *s2) Case insensitive comparison of strings. The function works almost - identically to :c:func:`strcmp` except that it ignores the case. + identically to :c:func:`!strcmp` except that it ignores the case. .. c:function:: int PyOS_strnicmp(const char *s1, const char *s2, Py_ssize_t size) Case insensitive comparison of strings. The function works almost - identically to :c:func:`strncmp` except that it ignores the case. + identically to :c:func:`!strncmp` except that it ignores the case. diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst index 72fc07afbf1f4d..97522da773477e 100644 --- a/Doc/c-api/datetime.rst +++ b/Doc/c-api/datetime.rst @@ -8,11 +8,54 @@ DateTime Objects Various date and time objects are supplied by the :mod:`datetime` module. Before using any of these functions, the header file :file:`datetime.h` must be included in your source (note that this is not included by :file:`Python.h`), -and the macro :c:macro:`PyDateTime_IMPORT` must be invoked, usually as part of +and the macro :c:macro:`!PyDateTime_IMPORT` must be invoked, usually as part of the module initialisation function. The macro puts a pointer to a C structure -into a static variable, :c:data:`PyDateTimeAPI`, that is used by the following +into a static variable, :c:data:`!PyDateTimeAPI`, that is used by the following macros. +.. c:type:: PyDateTime_Date + + This subtype of :c:type:`PyObject` represents a Python date object. + +.. c:type:: PyDateTime_DateTime + + This subtype of :c:type:`PyObject` represents a Python datetime object. + +.. c:type:: PyDateTime_Time + + This subtype of :c:type:`PyObject` represents a Python time object. + +.. c:type:: PyDateTime_Delta + + This subtype of :c:type:`PyObject` represents the difference between two datetime values. + +.. c:var:: PyTypeObject PyDateTime_DateType + + This instance of :c:type:`PyTypeObject` represents the Python date type; + it is the same object as :class:`datetime.date` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_DateTimeType + + This instance of :c:type:`PyTypeObject` represents the Python datetime type; + it is the same object as :class:`datetime.datetime` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_TimeType + + This instance of :c:type:`PyTypeObject` represents the Python time type; + it is the same object as :class:`datetime.time` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_DeltaType + + This instance of :c:type:`PyTypeObject` represents Python type for + the difference between two datetime values; + it is the same object as :class:`datetime.timedelta` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_TZInfoType + + This instance of :c:type:`PyTypeObject` represents the Python time zone info type; + it is the same object as :class:`datetime.tzinfo` in the Python layer. + + Macro for access to the UTC singleton: .. c:var:: PyObject* PyDateTime_TimeZone_UTC @@ -28,7 +71,7 @@ Type-check macros: .. c:function:: int PyDate_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateType` or a subtype of - :c:data:`PyDateTime_DateType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_DateType`. *ob* must not be ``NULL``. This function always succeeds. @@ -41,7 +84,7 @@ Type-check macros: .. c:function:: int PyDateTime_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType` or a subtype of - :c:data:`PyDateTime_DateTimeType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_DateTimeType`. *ob* must not be ``NULL``. This function always succeeds. @@ -54,7 +97,7 @@ Type-check macros: .. c:function:: int PyTime_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TimeType` or a subtype of - :c:data:`PyDateTime_TimeType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_TimeType`. *ob* must not be ``NULL``. This function always succeeds. @@ -67,7 +110,7 @@ Type-check macros: .. c:function:: int PyDelta_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DeltaType` or a subtype of - :c:data:`PyDateTime_DeltaType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_DeltaType`. *ob* must not be ``NULL``. This function always succeeds. @@ -80,7 +123,7 @@ Type-check macros: .. c:function:: int PyTZInfo_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType` or a subtype of - :c:data:`PyDateTime_TZInfoType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_TZInfoType`. *ob* must not be ``NULL``. This function always succeeds. @@ -133,7 +176,7 @@ Macros to create objects: :class:`datetime.timedelta` objects. -.. c:function:: PyObject* PyTimeZone_FromOffset(PyDateTime_DeltaType* offset) +.. c:function:: PyObject* PyTimeZone_FromOffset(PyObject *offset) Return a :class:`datetime.timezone` object with an unnamed fixed offset represented by the *offset* argument. @@ -141,7 +184,7 @@ Macros to create objects: .. versionadded:: 3.7 -.. c:function:: PyObject* PyTimeZone_FromOffsetAndName(PyDateTime_DeltaType* offset, PyUnicode* name) +.. c:function:: PyObject* PyTimeZone_FromOffsetAndName(PyObject *offset, PyObject *name) Return a :class:`datetime.timezone` object with a fixed offset represented by the *offset* argument and with tzname *name*. @@ -150,8 +193,8 @@ Macros to create objects: Macros to extract fields from date objects. The argument must be an instance of -:c:data:`PyDateTime_Date`, including subclasses (such as -:c:data:`PyDateTime_DateTime`). The argument must not be ``NULL``, and the type is +:c:type:`PyDateTime_Date`, including subclasses (such as +:c:type:`PyDateTime_DateTime`). The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_GET_YEAR(PyDateTime_Date *o) @@ -170,7 +213,7 @@ not checked: Macros to extract fields from datetime objects. The argument must be an -instance of :c:data:`PyDateTime_DateTime`, including subclasses. The argument +instance of :c:type:`PyDateTime_DateTime`, including subclasses. The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o) @@ -208,7 +251,7 @@ must not be ``NULL``, and the type is not checked: Macros to extract fields from time objects. The argument must be an instance of -:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``, +:c:type:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o) @@ -246,7 +289,7 @@ and the type is not checked: Macros to extract fields from time delta objects. The argument must be an -instance of :c:data:`PyDateTime_Delta`, including subclasses. The argument must +instance of :c:type:`PyDateTime_Delta`, including subclasses. The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_DELTA_GET_DAYS(PyDateTime_Delta *o) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index bd0c36a217e2ce..8ee351918006e4 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -55,6 +55,15 @@ Dictionary Objects This is equivalent to the Python expression ``key in p``. +.. c:function:: int PyDict_ContainsString(PyObject *p, const char *key) + + This is the same as :c:func:`PyDict_Contains`, but *key* is specified as a + :c:expr:`const char*` UTF-8 encoded bytes string, rather than a + :c:expr:`PyObject*`. + + .. versionadded:: 3.13 + + .. c:function:: PyObject* PyDict_Copy(PyObject *p) Return a new dictionary that contains the same key-value pairs as *p*. @@ -70,12 +79,9 @@ Dictionary Objects .. c:function:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) - .. index:: single: PyUnicode_FromString() - - Insert *val* into the dictionary *p* using *key* as a key. *key* should - be a :c:expr:`const char*`. The key object is created using - ``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on - failure. This function *does not* steal a reference to *val*. + This is the same as :c:func:`PyDict_SetItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: int PyDict_DelItem(PyObject *p, PyObject *key) @@ -88,15 +94,31 @@ Dictionary Objects .. c:function:: int PyDict_DelItemString(PyObject *p, const char *key) - Remove the entry in dictionary *p* which has a key specified by the string *key*. - If *key* is not in the dictionary, :exc:`KeyError` is raised. - Return ``0`` on success or ``-1`` on failure. + This is the same as :c:func:`PyDict_DelItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. + + +.. c:function:: int PyDict_GetItemRef(PyObject *p, PyObject *key, PyObject **result) + + Return a new :term:`strong reference` to the object from dictionary *p* + which has a key *key*: + + * If the key is present, set *\*result* to a new :term:`strong reference` + to the value and return ``1``. + * If the key is missing, set *\*result* to ``NULL`` and return ``0``. + * On error, raise an exception and return ``-1``. + + .. versionadded:: 3.13 + + See also the :c:func:`PyObject_GetItem` function. .. c:function:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) - Return the object from dictionary *p* which has a key *key*. Return ``NULL`` - if the key *key* is not present, but *without* setting an exception. + Return a :term:`borrowed reference` to the object from dictionary *p* which + has a key *key*. Return ``NULL`` if the key *key* is missing *without* + setting an exception. .. note:: @@ -120,7 +142,8 @@ Dictionary Objects .. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a - :c:expr:`const char*`, rather than a :c:expr:`PyObject*`. + :c:expr:`const char*` UTF-8 encoded bytes string, rather than a + :c:expr:`PyObject*`. .. note:: @@ -131,6 +154,15 @@ Dictionary Objects :c:func:`PyUnicode_FromString` *key* instead. +.. c:function:: int PyDict_GetItemStringRef(PyObject *p, const char *key, PyObject **result) + + Similar than :c:func:`PyDict_GetItemRef`, but *key* is specified as a + :c:expr:`const char*` UTF-8 encoded bytes string, rather than a + :c:expr:`PyObject*`. + + .. versionadded:: 3.13 + + .. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj) This is the same as the Python-level :meth:`dict.setdefault`. If present, it diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index a24ecac861e76b..2139da051e0193 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -83,7 +83,7 @@ Printing and clearing This utility function prints a warning message to ``sys.stderr`` when an exception has been set but it is impossible for the interpreter to actually raise the exception. It is used, for example, when an exception occurs in an - :meth:`__del__` method. + :meth:`~object.__del__` method. The function is called with a single argument *obj* that identifies the context in which the unraisable exception occurred. If possible, @@ -110,7 +110,8 @@ For convenience, some of these functions will always return a This is the most common way to set the error indicator. The first argument specifies the exception type; it is normally one of the standard exceptions, - e.g. :c:data:`PyExc_RuntimeError`. You need not increment its reference count. + e.g. :c:data:`PyExc_RuntimeError`. You need not create a new + :term:`strong reference` to it (e.g. with :c:func:`Py_INCREF`). The second argument is an error message; it is decoded from ``'utf-8'``. @@ -163,9 +164,9 @@ For convenience, some of these functions will always return a This is a convenience function to raise an exception when a C library function has returned an error and set the C variable :c:data:`errno`. It constructs a tuple object whose first item is the integer :c:data:`errno` value and whose - second item is the corresponding error message (gotten from :c:func:`strerror`), + second item is the corresponding error message (gotten from :c:func:`!strerror`), and then calls ``PyErr_SetObject(type, object)``. On Unix, when the - :c:data:`errno` value is :const:`EINTR`, indicating an interrupted system call, + :c:data:`errno` value is :c:macro:`!EINTR`, indicating an interrupted system call, this calls :c:func:`PyErr_CheckSignals`, and if that set the error indicator, leaves it set to that. The function always returns ``NULL``, so a wrapper function around a system call can write ``return PyErr_SetFromErrno(type);`` @@ -177,7 +178,7 @@ For convenience, some of these functions will always return a Similar to :c:func:`PyErr_SetFromErrno`, with the additional behavior that if *filenameObject* is not ``NULL``, it is passed to the constructor of *type* as a third parameter. In the case of :exc:`OSError` exception, - this is used to define the :attr:`filename` attribute of the + this is used to define the :attr:`!filename` attribute of the exception instance. @@ -200,12 +201,12 @@ For convenience, some of these functions will always return a .. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr) This is a convenience function to raise :exc:`WindowsError`. If called with - *ierr* of ``0``, the error code returned by a call to :c:func:`GetLastError` - is used instead. It calls the Win32 function :c:func:`FormatMessage` to retrieve - the Windows description of error code given by *ierr* or :c:func:`GetLastError`, + *ierr* of ``0``, the error code returned by a call to :c:func:`!GetLastError` + is used instead. It calls the Win32 function :c:func:`!FormatMessage` to retrieve + the Windows description of error code given by *ierr* or :c:func:`!GetLastError`, then it constructs a tuple object whose first item is the *ierr* value and whose second item is the corresponding error message (gotten from - :c:func:`FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError, + :c:func:`!FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError, object)``. This function always returns ``NULL``. .. availability:: Windows. @@ -221,17 +222,21 @@ For convenience, some of these functions will always return a .. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename) - Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the - filename is given as a C string. *filename* is decoded from the filesystem - encoding (:func:`os.fsdecode`). + Similar to :c:func:`PyErr_SetFromWindowsErr`, with the additional behavior + that if *filename* is not ``NULL``, it is decoded from the filesystem + encoding (:func:`os.fsdecode`) and passed to the constructor of + :exc:`OSError` as a third parameter to be used to define the + :attr:`!filename` attribute of the exception instance. .. availability:: Windows. .. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename) - Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, with an - additional parameter specifying the exception type to be raised. + Similar to :c:func:`PyErr_SetExcFromWindowsErr`, with the additional behavior + that if *filename* is not ``NULL``, it is passed to the constructor of + :exc:`OSError` as a third parameter to be used to define the + :attr:`!filename` attribute of the exception instance. .. availability:: Windows. @@ -631,7 +636,7 @@ Signal Handling be interruptible by user requests (such as by pressing Ctrl-C). .. note:: - The default Python signal handler for :const:`SIGINT` raises the + The default Python signal handler for :c:macro:`!SIGINT` raises the :exc:`KeyboardInterrupt` exception. @@ -642,7 +647,7 @@ Signal Handling single: SIGINT single: KeyboardInterrupt (built-in exception) - Simulate the effect of a :const:`SIGINT` signal arriving. + Simulate the effect of a :c:macro:`!SIGINT` signal arriving. This is equivalent to ``PyErr_SetInterruptEx(SIGINT)``. .. note:: @@ -666,7 +671,7 @@ Signal Handling to interrupt an operation). If the given signal isn't handled by Python (it was set to - :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), it will be ignored. + :py:const:`signal.SIG_DFL` or :py:const:`signal.SIG_IGN`), it will be ignored. If *signum* is outside of the allowed range of signal numbers, ``-1`` is returned. Otherwise, ``0`` is returned. The error indicator is @@ -754,7 +759,7 @@ Exception Objects .. c:function:: PyObject* PyException_GetCause(PyObject *ex) - Return the cause (either an exception instance, or :const:`None`, + Return the cause (either an exception instance, or ``None``, set by ``raise ... from ...``) associated with the exception as a new reference, as accessible from Python through :attr:`__cause__`. @@ -763,7 +768,7 @@ Exception Objects Set the cause associated with the exception to *cause*. Use ``NULL`` to clear it. There is no type check to make sure that *cause* is either an exception - instance or :const:`None`. This steals a reference to *cause*. + instance or ``None``. This steals a reference to *cause*. :attr:`__suppress_context__` is implicitly set to ``True`` by this function. @@ -781,7 +786,7 @@ Exception Objects Implement part of the interpreter's implementation of :keyword:`!except*`. *orig* is the original exception that was caught, and *excs* is the list of - the exceptions that need to be raised. This list contains the the unhandled + the exceptions that need to be raised. This list contains the unhandled part of *orig*, if any, as well as the exceptions that were raised from the :keyword:`!except*` clauses (so they have a different traceback from *orig*) and those that were reraised (and have the same traceback as *orig*). @@ -874,7 +879,7 @@ because the :ref:`call protocol ` takes care of recursion handling. Marks a point where a recursive C-level call is about to be performed. - If :const:`USE_STACKCHECK` is defined, this function checks if the OS + If :c:macro:`USE_STACKCHECK` is defined, this function checks if the OS stack overflowed using :c:func:`PyOS_CheckStack`. In this is the case, it sets a :exc:`MemoryError` and returns a nonzero value. diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index f32ecba9f27029..b36c800e00444a 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -93,7 +93,7 @@ the :mod:`io` APIs instead. .. index:: single: Py_PRINT_RAW Write object *obj* to file object *p*. The only supported flag for *flags* is - :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written + :c:macro:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written instead of the :func:`repr`. Return ``0`` on success or ``-1`` on failure; the appropriate exception will be set. diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index fd0be1108c6300..4f6ac0d8175c6b 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -109,7 +109,7 @@ Pack functions The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an :c:expr:`int` argument, non-zero if you want the bytes string in little-endian format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you -want big-endian format (exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` +want big-endian format (exponent first, at *p*). The :c:macro:`PY_BIG_ENDIAN` constant can be used to use the native endian: it is equal to ``1`` on big endian processor, or ``0`` on little endian processor. @@ -140,7 +140,7 @@ Unpack functions The unpack routines read 2, 4 or 8 bytes, starting at *p*. *le* is an :c:expr:`int` argument, non-zero if the bytes string is in little-endian format (exponent last, at ``p+1``, ``p+3`` or ``p+6`` and ``p+7``), zero if big-endian -(exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` constant can be used to +(exponent first, at *p*). The :c:macro:`PY_BIG_ENDIAN` constant can be used to use the native endian: it is equal to ``1`` on big endian processor, or ``0`` on little endian processor. diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst index c3260a21bc7f8b..6b2494ee4f0ed4 100644 --- a/Doc/c-api/gcsupport.rst +++ b/Doc/c-api/gcsupport.rst @@ -13,22 +13,20 @@ or strings), do not need to provide any explicit support for garbage collection. To create a container type, the :c:member:`~PyTypeObject.tp_flags` field of the type object must -include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the +include the :c:macro:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the :c:member:`~PyTypeObject.tp_traverse` handler. If instances of the type are mutable, a :c:member:`~PyTypeObject.tp_clear` implementation must also be provided. -.. data:: Py_TPFLAGS_HAVE_GC - :noindex: - +:c:macro:`Py_TPFLAGS_HAVE_GC` Objects with a type with this flag set must conform with the rules documented here. For convenience these objects will be referred to as container objects. Constructors for container types must conform to two rules: -#. The memory for the object must be allocated using :c:func:`PyObject_GC_New` - or :c:func:`PyObject_GC_NewVar`. +#. The memory for the object must be allocated using :c:macro:`PyObject_GC_New` + or :c:macro:`PyObject_GC_NewVar`. #. Once all the fields which may contain references to other containers are initialized, it must call :c:func:`PyObject_GC_Track`. @@ -52,21 +50,21 @@ rules: :c:member:`~PyTypeObject.tp_flags`, :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields if the type inherits from a class that implements the garbage collector protocol and the child class - does *not* include the :const:`Py_TPFLAGS_HAVE_GC` flag. + does *not* include the :c:macro:`Py_TPFLAGS_HAVE_GC` flag. -.. c:function:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type) +.. c:macro:: PyObject_GC_New(TYPE, typeobj) - Analogous to :c:func:`PyObject_New` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. + Analogous to :c:macro:`PyObject_New` but for container objects with the + :c:macro:`Py_TPFLAGS_HAVE_GC` flag set. -.. c:function:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) +.. c:macro:: PyObject_GC_NewVar(TYPE, typeobj, size) - Analogous to :c:func:`PyObject_NewVar` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. + Analogous to :c:macro:`PyObject_NewVar` but for container objects with the + :c:macro:`Py_TPFLAGS_HAVE_GC` flag set. .. c:function:: PyObject* PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *type, size_t extra_size) - Analogous to :c:func:`PyObject_GC_New` but allocates *extra_size* + Analogous to :c:macro:`PyObject_GC_New` but allocates *extra_size* bytes at the end of the object (at offset :c:member:`~PyTypeObject.tp_basicsize`). The allocated memory is initialized to zeros, @@ -87,7 +85,7 @@ rules: .. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) - Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the + Resize an object allocated by :c:macro:`PyObject_NewVar`. Returns the resized object or ``NULL`` on failure. *op* must not be tracked by the collector yet. @@ -130,8 +128,8 @@ rules: .. c:function:: void PyObject_GC_Del(void *op) - Releases memory allocated to an object using :c:func:`PyObject_GC_New` or - :c:func:`PyObject_GC_NewVar`. + Releases memory allocated to an object using :c:macro:`PyObject_GC_New` or + :c:macro:`PyObject_GC_NewVar`. .. c:function:: void PyObject_GC_UnTrack(void *op) @@ -145,7 +143,7 @@ rules: .. versionchanged:: 3.8 - The :c:func:`_PyObject_GC_TRACK` and :c:func:`_PyObject_GC_UNTRACK` macros + The :c:func:`!_PyObject_GC_TRACK` and :c:func:`!_PyObject_GC_UNTRACK` macros have been removed from the public C API. The :c:member:`~PyTypeObject.tp_traverse` handler accepts a function parameter of this type: diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 7aacc219a2bd61..137780cc359cf9 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -142,19 +142,19 @@ Importing Modules read from a Python bytecode file or obtained from the built-in function :func:`compile`, load the module. Return a new reference to the module object, or ``NULL`` with an exception set if an error occurred. *name* - is removed from :attr:`sys.modules` in error cases, even if *name* was already - in :attr:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`. Leaving - incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of + is removed from :data:`sys.modules` in error cases, even if *name* was already + in :data:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`. Leaving + incompletely initialized modules in :data:`sys.modules` is dangerous, as imports of such modules have no way to know that the module object is an unknown (and probably damaged with respect to the module author's intents) state. The module's :attr:`__spec__` and :attr:`__loader__` will be set, if not set already, with the appropriate values. The spec's loader will be set to the module's ``__loader__`` (if set) and to an instance of - :class:`SourceFileLoader` otherwise. + :class:`~importlib.machinery.SourceFileLoader` otherwise. The module's :attr:`__file__` attribute will be set to the code object's - :c:member:`co_filename`. If applicable, :attr:`__cached__` will also + :attr:`!co_filename`. If applicable, :attr:`__cached__` will also be set. This function will reload the module if it was already imported. See @@ -241,7 +241,7 @@ Importing Modules .. c:function:: PyObject* PyImport_GetImporter(PyObject *path) - Return a finder object for a :data:`sys.path`/:attr:`pkg.__path__` item + Return a finder object for a :data:`sys.path`/:attr:`!pkg.__path__` item *path*, possibly by fetching it from the :data:`sys.path_importer_cache` dict. If it wasn't yet cached, traverse :data:`sys.path_hooks` until a hook is found that can handle the path item. Return ``None`` if no hook could; @@ -310,23 +310,25 @@ Importing Modules .. c:struct:: _inittab - Structure describing a single entry in the list of built-in modules. Each of - these structures gives the name and initialization function for a module built - into the interpreter. The name is an ASCII encoded string. Programs which + Structure describing a single entry in the list of built-in modules. + Programs which embed Python may use an array of these structures in conjunction with :c:func:`PyImport_ExtendInittab` to provide additional built-in modules. - The structure is defined in :file:`Include/import.h` as:: + The structure consists of two members: - struct _inittab { - const char *name; /* ASCII encoded string */ - PyObject* (*initfunc)(void); - }; + .. c:member:: const char *name + + The module name, as an ASCII encoded string. + + .. c: member:: PyObject* (*initfunc)(void) + + Initialization function for a module built into the interpreter. .. c:function:: int PyImport_ExtendInittab(struct _inittab *newtab) Add a collection of modules to the table of built-in modules. The *newtab* - array must end with a sentinel entry which contains ``NULL`` for the :attr:`name` + array must end with a sentinel entry which contains ``NULL`` for the :c:member:`~_inittab.name` field; failure to provide the sentinel value can result in a memory fault. Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to extend the internal table. In the event of failure, no modules are added to the diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index e7b2937d38dcf9..d164d1a752e295 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -25,7 +25,7 @@ The following functions can be safely called before Python is initialized: * :c:func:`PyImport_AppendInittab` * :c:func:`PyImport_ExtendInittab` - * :c:func:`PyInitFrozenExtensions` + * :c:func:`!PyInitFrozenExtensions` * :c:func:`PyMem_SetAllocator` * :c:func:`PyMem_SetupDebugHooks` * :c:func:`PyObject_SetArenaAllocator` @@ -151,7 +151,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. :c:member:`PyConfig.use_environment` should be used instead, see :ref:`Python Initialization Configuration `. - Ignore all :envvar:`PYTHON*` environment variables, e.g. + Ignore all :envvar:`!PYTHON*` environment variables, e.g. :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. Set by the :option:`-E` and :option:`-I` options. @@ -224,7 +224,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. :ref:`Python Initialization Configuration `. If the flag is non-zero, use :class:`io.FileIO` instead of - :class:`WindowsConsoleIO` for :mod:`sys` standard streams. + :class:`!io._WindowsConsoleIO` for :mod:`sys` standard streams. Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSSTDIO` environment variable is set to a non-empty string. @@ -373,6 +373,14 @@ Initializing and finalizing the interpreter :c:func:`Py_Initialize` is called again. +.. c:function:: int Py_IsFinalizing() + + Return true (non-zero) if the main Python interpreter is + :term:`shutting down `. Return false (zero) otherwise. + + .. versionadded:: 3.13 + + .. c:function:: int Py_FinalizeEx() Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of @@ -393,7 +401,7 @@ Initializing and finalizing the interpreter the application. **Bugs and caveats:** The destruction of modules and objects in modules is done - in random order; this may cause destructors (:meth:`__del__` methods) to fail + in random order; this may cause destructors (:meth:`~object.__del__` methods) to fail when they depend on other objects (even functions) or modules. Dynamically loaded extension modules loaded by Python are not unloaded. Small amounts of memory allocated by the Python interpreter may not be freed (if you find a leak, @@ -417,7 +425,7 @@ Process-wide parameters ======================= -.. c:function:: wchar* Py_GetProgramName() +.. c:function:: wchar_t* Py_GetProgramName() Return the program name set with :c:member:`PyConfig.program_name`, or the default. The returned string points into static storage; the caller should not modify its @@ -785,7 +793,7 @@ the fork, and releasing them afterwards. In addition, it resets any :ref:`lock-objects` in the child. When extending or embedding Python, there is no way to inform Python of additional (non-Python) locks that need to be acquired before or reset after a fork. OS facilities such as -:c:func:`pthread_atfork` would need to be used to accomplish the same thing. +:c:func:`!pthread_atfork` would need to be used to accomplish the same thing. Additionally, when extending or embedding Python, calling :c:func:`fork` directly rather than through :func:`os.fork` (and returning to or calling into Python) may result in a deadlock by one of Python's internal locks @@ -827,8 +835,11 @@ code, or when embedding the Python interpreter: .. c:type:: PyThreadState This data structure represents the state of a single thread. The only public - data member is :attr:`interp` (:c:expr:`PyInterpreterState *`), which points to - this thread's interpreter state. + data member is: + + .. c:member:: PyInterpreterState *interp + + This thread's interpreter state. .. c:function:: PyThreadState* PyEval_SaveThread() @@ -849,7 +860,7 @@ code, or when embedding the Python interpreter: .. note:: Calling this function from a thread when the runtime is finalizing will terminate the thread, even if the thread was not created by Python. - You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + You can use :c:func:`Py_IsFinalizing` or :func:`sys.is_finalizing` to check if the interpreter is in process of being finalized before calling this function to avoid unwanted termination. @@ -859,6 +870,19 @@ code, or when embedding the Python interpreter: When the current thread state is ``NULL``, this issues a fatal error (so that the caller needn't check for ``NULL``). + See also :c:func:`PyThreadState_GetUnchecked`. + + +.. c:function:: PyThreadState* PyThreadState_GetUnchecked() + + Similar to :c:func:`PyThreadState_Get`, but don't kill the process with a + fatal error if it is NULL. The caller is responsible to check if the result + is NULL. + + .. versionadded:: 3.13 + In Python 3.5 to 3.12, the function was private and known as + ``_PyThreadState_UncheckedGet()``. + .. c:function:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) @@ -895,7 +919,7 @@ with sub-interpreters: .. note:: Calling this function from a thread when the runtime is finalizing will terminate the thread, even if the thread was not created by Python. - You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + You can use :c:func:`Py_IsFinalizing` or :func:`sys.is_finalizing` to check if the interpreter is in process of being finalized before calling this function to avoid unwanted termination. @@ -1161,7 +1185,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. function does not steal any references to *exc*. To prevent naive misuse, you must write your own C extension to call this. Must be called with the GIL held. Returns the number of thread states modified; this is normally one, but will be - zero if the thread id isn't found. If *exc* is :const:`NULL`, the pending + zero if the thread id isn't found. If *exc* is ``NULL``, the pending exception (if any) for the thread is cleared. This raises no exceptions. .. versionchanged:: 3.7 @@ -1177,7 +1201,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. .. note:: Calling this function from a thread when the runtime is finalizing will terminate the thread, even if the thread was not created by Python. - You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + You can use :c:func:`Py_IsFinalizing` or :func:`sys.is_finalizing` to check if the interpreter is in process of being finalized before calling this function to avoid unwanted termination. @@ -1223,7 +1247,96 @@ 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() +.. c:type:: PyInterpreterConfig + + Structure containing most parameters to configure a sub-interpreter. + Its values are used only in :c:func:`Py_NewInterpreterFromConfig` and + never modified by the runtime. + + .. versionadded:: 3.12 + + Structure fields: + + .. c:member:: int use_main_obmalloc + + If this is ``0`` then the sub-interpreter will use its own + "object" allocator state. + Otherwise it will use (share) the main interpreter's. + + If this is ``0`` then + :c:member:`~PyInterpreterConfig.check_multi_interp_extensions` + must be ``1`` (non-zero). + If this is ``1`` then :c:member:`~PyInterpreterConfig.gil` + must not be :c:macro:`PyInterpreterConfig_OWN_GIL`. + + .. c:member:: int allow_fork + + If this is ``0`` then the runtime will not support forking the + process in any thread where the sub-interpreter is currently active. + Otherwise fork is unrestricted. + + Note that the :mod:`subprocess` module still works + when fork is disallowed. + + .. c:member:: int allow_exec + + If this is ``0`` then the runtime will not support replacing the + current process via exec (e.g. :func:`os.execv`) in any thread + where the sub-interpreter is currently active. + Otherwise exec is unrestricted. + + Note that the :mod:`subprocess` module still works + when exec is disallowed. + + .. c:member:: int allow_threads + + If this is ``0`` then the sub-interpreter's :mod:`threading` module + won't create threads. + Otherwise threads are allowed. + + .. c:member:: int allow_daemon_threads + + If this is ``0`` then the sub-interpreter's :mod:`threading` module + won't create daemon threads. + Otherwise daemon threads are allowed (as long as + :c:member:`~PyInterpreterConfig.allow_threads` is non-zero). + + .. c:member:: int check_multi_interp_extensions + + If this is ``0`` then all extension modules may be imported, + including legacy (single-phase init) modules, + in any thread where the sub-interpreter is currently active. + Otherwise only multi-phase init extension modules + (see :pep:`489`) may be imported. + (Also see :c:macro:`Py_mod_multiple_interpreters`.) + + This must be ``1`` (non-zero) if + :c:member:`~PyInterpreterConfig.use_main_obmalloc` is ``0``. + + .. c:member:: int gil + + This determines the operation of the GIL for the sub-interpreter. + It may be one of the following: + + .. c:namespace:: NULL + + .. c:macro:: PyInterpreterConfig_DEFAULT_GIL + + Use the default selection (:c:macro:`PyInterpreterConfig_SHARED_GIL`). + + .. c:macro:: PyInterpreterConfig_SHARED_GIL + + Use (share) the main interpreter's GIL. + + .. c:macro:: PyInterpreterConfig_OWN_GIL + + Use the sub-interpreter's own GIL. + + If this is :c:macro:`PyInterpreterConfig_OWN_GIL` then + :c:member:`PyInterpreterConfig.use_main_obmalloc` must be ``0``. + + +.. c:function:: PyStatus Py_NewInterpreterFromConfig(PyThreadState **tstate_p, const PyInterpreterConfig *config) .. index:: pair: module; builtins @@ -1243,16 +1356,47 @@ function. You can create and destroy them using the following functions: ``sys.stdout`` and ``sys.stderr`` (however these refer to the same underlying file descriptors). - The return value points to the first thread state created in the new + The given *config* controls the options with which the interpreter + is initialized. + + Upon success, *tstate_p* will be set to the first thread state + created in the new sub-interpreter. This thread state is made in the current thread state. Note that no actual thread is created; see the discussion of thread states - below. If creation of the new interpreter is unsuccessful, ``NULL`` is - returned; no exception is set since the exception state is stored in the - current thread state and there may not be a current thread state. (Like all - other Python/C API functions, the global interpreter lock must be held before - calling this function and is still held when it returns; however, unlike most - other Python/C API functions, there needn't be a current thread state on - entry.) + below. If creation of the new interpreter is unsuccessful, + *tstate_p* is set to ``NULL``; + no exception is set since the exception state is stored in the + current thread state and there may not be a current thread state. + + Like all other Python/C API functions, the global interpreter lock + must be held before calling this function and is still held when it + returns. Likewise a current thread state must be set on entry. On + success, the returned thread state will be set as current. If the + sub-interpreter is created with its own GIL then the GIL of the + calling interpreter will be released. When the function returns, + the new interpreter's GIL will be held by the current thread and + the previously interpreter's GIL will remain released here. + + .. versionadded:: 3.12 + + Sub-interpreters are most effective when isolated from each other, + with certain functionality restricted:: + + PyInterpreterConfig config = { + .use_main_obmalloc = 0, + .allow_fork = 0, + .allow_exec = 0, + .allow_threads = 1, + .allow_daemon_threads = 0, + .check_multi_interp_extensions = 1, + .gil = PyInterpreterConfig_OWN_GIL, + }; + PyThreadState *tstate = Py_NewInterpreterFromConfig(&config); + + Note that the config is used only briefly and does not get modified. + During initialization the config's values are converted into various + :c:type:`PyInterpreterState` values. A read-only copy of the config + may be stored internally on the :c:type:`PyInterpreterState`. .. index:: single: Py_FinalizeEx() @@ -1287,19 +1431,79 @@ function. You can create and destroy them using the following functions: .. index:: single: close() (in module os) +.. c:function:: PyThreadState* Py_NewInterpreter(void) + + .. index:: + pair: module; builtins + pair: module; __main__ + pair: module; sys + single: stdout (in module sys) + single: stderr (in module sys) + single: stdin (in module sys) + + Create a new sub-interpreter. This is essentially just a wrapper + around :c:func:`Py_NewInterpreterFromConfig` with a config that + preserves the existing behavior. The result is an unisolated + sub-interpreter that shares the main interpreter's GIL, allows + fork/exec, allows daemon threads, and allows single-phase init + modules. + + .. c:function:: void Py_EndInterpreter(PyThreadState *tstate) .. index:: single: Py_FinalizeEx() - Destroy the (sub-)interpreter represented by the given thread state. The given - thread state must be the current thread state. See the discussion of thread - states below. When the call returns, the current thread state is ``NULL``. All - thread states associated with this interpreter are destroyed. (The global - interpreter lock must be held before calling this function and is still held - when it returns.) :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that + Destroy the (sub-)interpreter represented by the given thread state. + The given thread state must be the current thread state. See the + discussion of thread states below. When the call returns, + the current thread state is ``NULL``. All thread states associated + with this interpreter are destroyed. The global interpreter lock + used by the target interpreter must be held before calling this + function. No GIL is held when it returns. + + :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that haven't been explicitly destroyed at that point. +A Per-Interpreter GIL +--------------------- + +Using :c:func:`Py_NewInterpreterFromConfig` you can create +a sub-interpreter that is completely isolated from other interpreters, +including having its own GIL. The most important benefit of this +isolation is that such an interpreter can execute Python code without +being blocked by other interpreters or blocking any others. Thus a +single Python process can truly take advantage of multiple CPU cores +when running Python code. The isolation also encourages a different +approach to concurrency than that of just using threads. +(See :pep:`554`.) + +Using an isolated interpreter requires vigilance in preserving that +isolation. That especially means not sharing any objects or mutable +state without guarantees about thread-safety. Even objects that are +otherwise immutable (e.g. ``None``, ``(1, 5)``) can't normally be shared +because of the refcount. One simple but less-efficient approach around +this is to use a global lock around all use of some state (or object). +Alternately, effectively immutable objects (like integers or strings) +can be made safe in spite of their refcounts by making them "immortal". +In fact, this has been done for the builtin singletons, small integers, +and a number of other builtin objects. + +If you preserve isolation then you will have access to proper multi-core +computing without the complications that come with free-threading. +Failure to preserve isolation will expose you to the full consequences +of free-threading, including races and hard-to-debug crashes. + +Aside from that, one of the main challenges of using multiple isolated +interpreters is how to communicate between them safely (not break +isolation) and efficiently. The runtime and stdlib do not provide +any standard approach to this yet. A future stdlib module would help +mitigate the effort of preserving isolation and expose effective tools +for communicating (and sharing) data between interpreters. + +.. versionadded:: 3.12 + + Bugs and caveats ---------------- @@ -1407,32 +1611,32 @@ Python-level trace functions in previous versions. The type of the trace function registered using :c:func:`PyEval_SetProfile` and :c:func:`PyEval_SetTrace`. The first parameter is the object passed to the registration function as *obj*, *frame* is the frame object to which the event - pertains, *what* is one of the constants :const:`PyTrace_CALL`, - :const:`PyTrace_EXCEPTION`, :const:`PyTrace_LINE`, :const:`PyTrace_RETURN`, - :const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION`, :const:`PyTrace_C_RETURN`, - or :const:`PyTrace_OPCODE`, and *arg* depends on the value of *what*: - - +------------------------------+----------------------------------------+ - | Value of *what* | Meaning of *arg* | - +==============================+========================================+ - | :const:`PyTrace_CALL` | Always :c:data:`Py_None`. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_EXCEPTION` | Exception information as returned by | - | | :func:`sys.exc_info`. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_LINE` | Always :c:data:`Py_None`. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_RETURN` | Value being returned to the caller, | - | | or ``NULL`` if caused by an exception. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_C_CALL` | Function object being called. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_C_EXCEPTION` | Function object being called. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_C_RETURN` | Function object being called. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | - +------------------------------+----------------------------------------+ + pertains, *what* is one of the constants :c:data:`PyTrace_CALL`, + :c:data:`PyTrace_EXCEPTION`, :c:data:`PyTrace_LINE`, :c:data:`PyTrace_RETURN`, + :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION`, :c:data:`PyTrace_C_RETURN`, + or :c:data:`PyTrace_OPCODE`, and *arg* depends on the value of *what*: + + +-------------------------------+----------------------------------------+ + | Value of *what* | Meaning of *arg* | + +===============================+========================================+ + | :c:data:`PyTrace_CALL` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_EXCEPTION` | Exception information as returned by | + | | :func:`sys.exc_info`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_LINE` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_RETURN` | Value being returned to the caller, | + | | or ``NULL`` if caused by an exception. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_CALL` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_EXCEPTION` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_RETURN` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ .. c:var:: int PyTrace_CALL @@ -1499,8 +1703,8 @@ Python-level trace functions in previous versions. function as its first parameter, and may be any Python object, or ``NULL``. If the profile function needs to maintain state, using a different value for *obj* for each thread provides a convenient and thread-safe place to store it. The - profile function is called for all monitored events except :const:`PyTrace_LINE` - :const:`PyTrace_OPCODE` and :const:`PyTrace_EXCEPTION`. + profile function is called for all monitored events except :c:data:`PyTrace_LINE` + :c:data:`PyTrace_OPCODE` and :c:data:`PyTrace_EXCEPTION`. See also the :func:`sys.setprofile` function. @@ -1525,8 +1729,8 @@ Python-level trace functions in previous versions. :c:func:`PyEval_SetProfile`, except the tracing function does receive line-number events and per-opcode events, but does not receive any event related to C function objects being called. Any trace function registered using :c:func:`PyEval_SetTrace` - will not receive :const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION` or - :const:`PyTrace_C_RETURN` as a value for the *what* parameter. + will not receive :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION` or + :c:data:`PyTrace_C_RETURN` as a value for the *what* parameter. See also the :func:`sys.settrace` function. diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 5f70c45c54f757..0240e25b6f1607 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -82,6 +82,8 @@ PyWideStringList If *length* is non-zero, *items* must be non-``NULL`` and all strings must be non-``NULL``. + .. c:namespace:: NULL + Methods: .. c:function:: PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) @@ -101,6 +103,8 @@ PyWideStringList Python must be preinitialized to call this function. + .. c:namespace:: PyWideStringList + Structure fields: .. c:member:: Py_ssize_t length @@ -135,6 +139,8 @@ PyStatus Name of the function which created an error, can be ``NULL``. + .. c:namespace:: NULL + Functions to create a status: .. c:function:: PyStatus PyStatus_Ok(void) @@ -210,6 +216,8 @@ PyPreConfig Structure used to preinitialize Python. + .. c:namespace:: NULL + Function to initialize a preconfiguration: .. c:function:: void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig) @@ -222,6 +230,8 @@ PyPreConfig Initialize the preconfiguration with :ref:`Isolated Configuration `. + .. c:namespace:: PyPreConfig + Structure fields: .. c:member:: int allocator @@ -429,6 +439,8 @@ PyConfig When done, the :c:func:`PyConfig_Clear` function must be used to release the configuration memory. + .. c:namespace:: NULL + Structure methods: .. c:function:: void PyConfig_InitPythonConfig(PyConfig *config) @@ -522,11 +534,13 @@ PyConfig Moreover, if :c:func:`PyConfig_SetArgv` or :c:func:`PyConfig_SetBytesArgv` is used, this method must be called before other methods, since the preinitialization configuration depends on command line arguments (if - :c:member:`parse_argv` is non-zero). + :c:member:`~PyConfig.parse_argv` is non-zero). The caller of these methods is responsible to handle exceptions (error or exit) using ``PyStatus_Exception()`` and ``Py_ExitStatusException()``. + .. c:namespace:: PyConfig + Structure fields: .. c:member:: PyWideStringList argv @@ -864,6 +878,19 @@ PyConfig .. versionadded:: 3.12 + .. c:member:: int cpu_count + + If the value of :c:member:`~PyConfig.cpu_count` is not ``-1`` then it will + override the return values of :func:`os.cpu_count`, + :func:`os.process_cpu_count`, and :func:`multiprocessing.cpu_count`. + + Configured by the :samp:`-X cpu_count={n|default}` command line + flag or the :envvar:`PYTHON_CPU_COUNT` environment variable. + + Default: ``-1``. + + .. versionadded:: 3.13 + .. c:member:: int isolated If greater than ``0``, enable isolated mode: @@ -889,7 +916,7 @@ PyConfig .. c:member:: int legacy_windows_stdio If non-zero, use :class:`io.FileIO` instead of - :class:`io.WindowsConsoleIO` for :data:`sys.stdin`, :data:`sys.stdout` + :class:`!io._WindowsConsoleIO` for :data:`sys.stdin`, :data:`sys.stdout` and :data:`sys.stderr`. Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSSTDIO` environment @@ -938,7 +965,7 @@ PyConfig .. c:member:: wchar_t* pythonpath_env Module search paths (:data:`sys.path`) as a string separated by ``DELIM`` - (:data:`os.path.pathsep`). + (:data:`os.pathsep`). Set by the :envvar:`PYTHONPATH` environment variable. @@ -1118,7 +1145,7 @@ PyConfig .. c:member:: int show_ref_count - Show total reference count at exit? + Show total reference count at exit (excluding immortal objects)? Set to ``1`` by :option:`-X showrefcount <-X>` command line option. @@ -1139,7 +1166,7 @@ PyConfig Set to ``0`` by the :option:`-S` command line option. - :data:`sys.flags.no_site` is set to the inverted value of + :data:`sys.flags.no_site ` is set to the inverted value of :c:member:`~PyConfig.site_import`. Default: ``1``. diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 9014f7e03b3600..4dbca92b18b5cd 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -105,6 +105,30 @@ defined closer to where they are useful (e.g. :c:macro:`Py_RETURN_NONE`). Others of a more general utility are defined here. This is not necessarily a complete listing. +.. c:macro:: PyMODINIT_FUNC + + Declare an extension module ``PyInit`` initialization function. The function + return type is :c:expr:`PyObject*`. The macro declares any special linkage + declarations required by the platform, and for C++ declares the function as + ``extern "C"``. + + The initialization function must be named :samp:`PyInit_{name}`, where + *name* is the name of the module, and should be the only non-\ ``static`` + item defined in the module file. Example:: + + static struct PyModuleDef spam_module = { + PyModuleDef_HEAD_INIT, + .m_name = "spam", + ... + }; + + PyMODINIT_FUNC + PyInit_spam(void) + { + return PyModule_Create(&spam_module); + } + + .. c:macro:: Py_ABS(x) Return the absolute value of ``x``. @@ -287,52 +311,58 @@ true if (and only if) the object pointed to by *a* is a Python list. Reference Counts ---------------- -The reference count is important because today's computers have a finite (and -often severely limited) memory size; it counts how many different places there -are that have a reference to an object. Such a place could be another object, -or a global (or static) C variable, or a local variable in some C function. -When an object's reference count becomes zero, the object is deallocated. If -it contains references to other objects, their reference count is decremented. -Those other objects may be deallocated in turn, if this decrement makes their -reference count become zero, and so on. (There's an obvious problem with -objects that reference each other here; for now, the solution is "don't do -that.") +The reference count is important because today's computers have a finite +(and often severely limited) memory size; it counts how many different +places there are that have a :term:`strong reference` to an object. +Such a place could be another object, or a global (or static) C variable, +or a local variable in some C function. +When the last :term:`strong reference` to an object is released +(i.e. its reference count becomes zero), the object is deallocated. +If it contains references to other objects, those references are released. +Those other objects may be deallocated in turn, if there are no more +references to them, and so on. (There's an obvious problem with +objects that reference each other here; for now, the solution +is "don't do that.") .. index:: single: Py_INCREF() single: Py_DECREF() -Reference counts are always manipulated explicitly. The normal way is to use -the macro :c:func:`Py_INCREF` to increment an object's reference count by one, -and :c:func:`Py_DECREF` to decrement it by one. The :c:func:`Py_DECREF` macro +Reference counts are always manipulated explicitly. The normal way is +to use the macro :c:func:`Py_INCREF` to take a new reference to an +object (i.e. increment its reference count by one), +and :c:func:`Py_DECREF` to release that reference (i.e. decrement the +reference count by one). The :c:func:`Py_DECREF` macro is considerably more complex than the incref one, since it must check whether the reference count becomes zero and then cause the object's deallocator to be -called. The deallocator is a function pointer contained in the object's type -structure. The type-specific deallocator takes care of decrementing the -reference counts for other objects contained in the object if this is a compound +called. The deallocator is a function pointer contained in the object's type +structure. The type-specific deallocator takes care of releasing references +for other objects contained in the object if this is a compound object type, such as a list, as well as performing any additional finalization that's needed. There's no chance that the reference count can overflow; at least as many bits are used to hold the reference count as there are distinct memory locations in virtual memory (assuming ``sizeof(Py_ssize_t) >= sizeof(void*)``). Thus, the reference count increment is a simple operation. -It is not necessary to increment an object's reference count for every local -variable that contains a pointer to an object. In theory, the object's +It is not necessary to hold a :term:`strong reference` (i.e. increment +the reference count) for every local variable that contains a pointer +to an object. In theory, the object's reference count goes up by one when the variable is made to point to it and it goes down by one when the variable goes out of scope. However, these two cancel each other out, so at the end the reference count hasn't changed. The only real reason to use the reference count is to prevent the object from being deallocated as long as our variable is pointing to it. If we know that there is at least one other reference to the object that lives at least as long as -our variable, there is no need to increment the reference count temporarily. +our variable, there is no need to take a new :term:`strong reference` +(i.e. increment the reference count) temporarily. An important situation where this arises is in objects that are passed as arguments to C functions in an extension module that are called from Python; the call mechanism guarantees to hold a reference to every argument for the duration of the call. However, a common pitfall is to extract an object from a list and hold on to it -for a while without incrementing its reference count. Some other operation might -conceivably remove the object from the list, decrementing its reference count +for a while without taking a new reference. Some other operation might +conceivably remove the object from the list, releasing that reference, and possibly deallocating it. The real danger is that innocent-looking operations may invoke arbitrary Python code which could do this; there is a code path which allows control to flow back to the user from a :c:func:`Py_DECREF`, so @@ -340,7 +370,8 @@ almost any operation is potentially dangerous. A safe approach is to always use the generic operations (functions whose name begins with ``PyObject_``, ``PyNumber_``, ``PySequence_`` or ``PyMapping_``). -These operations always increment the reference count of the object they return. +These operations always create a new :term:`strong reference` +(i.e. increment the reference count) of the object they return. This leaves the caller with the responsibility to call :c:func:`Py_DECREF` when they are done with the result; this soon becomes second nature. @@ -356,7 +387,7 @@ to objects (objects are not owned: they are always shared). "Owning a reference" means being responsible for calling Py_DECREF on it when the reference is no longer needed. Ownership can also be transferred, meaning that the code that receives ownership of the reference then becomes responsible for -eventually decref'ing it by calling :c:func:`Py_DECREF` or :c:func:`Py_XDECREF` +eventually releasing it by calling :c:func:`Py_DECREF` or :c:func:`Py_XDECREF` when it's no longer needed---or passing on this responsibility (usually to its caller). When a function passes ownership of a reference on to its caller, the caller is said to receive a *new* reference. When no ownership is transferred, @@ -414,9 +445,9 @@ For example, the above two blocks of code could be replaced by the following It is much more common to use :c:func:`PyObject_SetItem` and friends with items whose references you are only borrowing, like arguments that were passed in to -the function you are writing. In that case, their behaviour regarding reference -counts is much saner, since you don't have to increment a reference count so you -can give a reference away ("have it be stolen"). For example, this function +the function you are writing. In that case, their behaviour regarding references +is much saner, since you don't have to take a new reference just so you +can give that reference away ("have it be stolen"). For example, this function sets all items of a list (actually, any mutable sequence) to a given item:: int @@ -616,7 +647,7 @@ and lose important information about the exact cause of the error. .. index:: single: sum_sequence() A simple example of detecting exceptions and passing them on is shown in the -:c:func:`sum_sequence` example above. It so happens that this example doesn't +:c:func:`!sum_sequence` example above. It so happens that this example doesn't need to clean up any owned references when it detects an error. The following example function shows some error cleanup. First, to remind you why you like Python, we show the equivalent Python code:: diff --git a/Doc/c-api/iterator.rst b/Doc/c-api/iterator.rst index 3fcf099134d4dd..6b7ba8c9979163 100644 --- a/Doc/c-api/iterator.rst +++ b/Doc/c-api/iterator.rst @@ -6,7 +6,7 @@ Iterator Objects ---------------- Python provides two general-purpose iterator objects. The first, a sequence -iterator, works with an arbitrary sequence supporting the :meth:`__getitem__` +iterator, works with an arbitrary sequence supporting the :meth:`~object.__getitem__` method. The second works with a callable object and a sentinel value, calling the callable for each item in the sequence, and ending the iteration when the sentinel value is returned. @@ -19,7 +19,7 @@ sentinel value is returned. types. -.. c:function:: int PySeqIter_Check(op) +.. c:function:: int PySeqIter_Check(PyObject *op) Return true if the type of *op* is :c:data:`PySeqIter_Type`. This function always succeeds. @@ -38,7 +38,7 @@ sentinel value is returned. two-argument form of the :func:`iter` built-in function. -.. c:function:: int PyCallIter_Check(op) +.. c:function:: int PyCallIter_Check(PyObject *op) Return true if the type of *op* is :c:data:`PyCallIter_Type`. This function always succeeds. diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index fe379ffe912391..045604870d3c84 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -136,14 +136,22 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. This function will no longer use :meth:`~object.__int__`. +.. c:function:: int PyLong_AsInt(PyObject *obj) + + Similar to :c:func:`PyLong_AsLong`, but store the result in a C + :c:expr:`int` instead of a C :c:expr:`long`. + + .. versionadded:: 3.13 + + .. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow) Return a C :c:expr:`long` representation of *obj*. If *obj* is not an instance of :c:type:`PyLongObject`, first call its :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. - If the value of *obj* is greater than :const:`LONG_MAX` or less than - :const:`LONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and + If the value of *obj* is greater than :c:macro:`LONG_MAX` or less than + :c:macro:`LONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and return ``-1``; otherwise, set *\*overflow* to ``0``. If any other exception occurs set *\*overflow* to ``0`` and return ``-1`` as usual. @@ -183,8 +191,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. instance of :c:type:`PyLongObject`, first call its :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. - If the value of *obj* is greater than :const:`LLONG_MAX` or less than - :const:`LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, + If the value of *obj* is greater than :c:macro:`LLONG_MAX` or less than + :c:macro:`LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and return ``-1``; otherwise, set *\*overflow* to ``0``. If any other exception occurs set *\*overflow* to ``0`` and return ``-1`` as usual. diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 9176a4652cbf29..1f55c0aa955c75 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -13,7 +13,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and Return ``1`` if the object provides the mapping protocol or supports slicing, and ``0`` otherwise. Note that it returns ``1`` for Python classes with - a :meth:`__getitem__` method, since in general it is impossible to + a :meth:`~object.__getitem__` method, since in general it is impossible to determine what type of keys the class supports. This function always succeeds. @@ -28,9 +28,9 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key) - Return element of *o* corresponding to the string *key* or ``NULL`` on failure. - This is the equivalent of the Python expression ``o[key]``. - See also :c:func:`PyObject_GetItem`. + This is the same as :c:func:`PyObject_GetItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: int PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result) @@ -50,60 +50,78 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: int PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject **result) - Variant of :c:func:`PyMapping_GetItemString` which doesn't raise - :exc:`KeyError` if the key is not found. - - If the key is found, return ``1`` and set *\*result* to a new - :term:`strong reference` to the corresponding value. - If the key is not found, return ``0`` and set *\*result* to ``NULL``; - the :exc:`KeyError` is silenced. - If an error other than :exc:`KeyError` is raised, return ``-1`` and - set *\*result* to ``NULL``. + This is the same as :c:func:`PyMapping_GetOptionalItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. versionadded:: 3.13 .. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v) - Map the string *key* to the value *v* in object *o*. Returns ``-1`` on - failure. This is the equivalent of the Python statement ``o[key] = v``. - See also :c:func:`PyObject_SetItem`. This function *does not* steal a - reference to *v*. + This is the same as :c:func:`PyObject_SetItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: int PyMapping_DelItem(PyObject *o, PyObject *key) - Remove the mapping for the object *key* from the object *o*. Return ``-1`` - on failure. This is equivalent to the Python statement ``del o[key]``. This is an alias of :c:func:`PyObject_DelItem`. .. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key) - Remove the mapping for the string *key* from the object *o*. Return ``-1`` - on failure. This is equivalent to the Python statement ``del o[key]``. + This is the same as :c:func:`PyObject_DelItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. -.. c:function:: int PyMapping_HasKey(PyObject *o, PyObject *key) +.. c:function:: int PyMapping_HasKeyWithError(PyObject *o, PyObject *key) Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This is equivalent to the Python expression ``key in o``. - This function always succeeds. + On failure, return ``-1``. - Note that exceptions which occur while calling the :meth:`__getitem__` - method will get suppressed. - To get error reporting use :c:func:`PyObject_GetItem()` instead. + .. versionadded:: 3.13 -.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key) +.. c:function:: int PyMapping_HasKeyStringWithError(PyObject *o, const char *key) + + This is the same as :c:func:`PyMapping_HasKeyWithError`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. + + .. versionadded:: 3.13 + + +.. c:function:: int PyMapping_HasKey(PyObject *o, PyObject *key) Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This is equivalent to the Python expression ``key in o``. This function always succeeds. - Note that exceptions which occur while calling the :meth:`__getitem__` - method and creating a temporary string object will get suppressed. - To get error reporting use :c:func:`PyMapping_GetItemString()` instead. + .. note:: + + Exceptions which occur when this calls :meth:`~object.__getitem__` + method are silently ignored. + For proper error handling, use :c:func:`PyMapping_HasKeyWithError`, + :c:func:`PyMapping_GetOptionalItem` or :c:func:`PyObject_GetItem()` instead. + + +.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key) + + This is the same as :c:func:`PyMapping_HasKey`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. + + .. note:: + + Exceptions that occur when this calls :meth:`~object.__getitem__` + method or while creating the temporary :class:`str` + object are silently ignored. + For proper error handling, use :c:func:`PyMapping_HasKeyStringWithError`, + :c:func:`PyMapping_GetOptionalItemString` or + :c:func:`PyMapping_GetItemString` instead. .. c:function:: PyObject* PyMapping_Keys(PyObject *o) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 7041c15d23fb83..e98c178ac27a37 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -136,7 +136,7 @@ need to be held. The :ref:`default raw memory allocator ` uses the following functions: :c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` -and :c:func:`free`; call ``malloc(1)`` (or ``calloc(1, 1)``) when requesting +and :c:func:`!free`; call ``malloc(1)`` (or ``calloc(1, 1)``) when requesting zero bytes. .. versionadded:: 3.4 @@ -264,14 +264,14 @@ The following type-oriented macros are provided for convenience. Note that *TYPE* refers to any C type. -.. c:function:: TYPE* PyMem_New(TYPE, size_t n) +.. c:macro:: PyMem_New(TYPE, n) Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of memory. Returns a pointer cast to :c:expr:`TYPE*`. The memory will not have been initialized in any way. -.. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n) +.. c:macro:: PyMem_Resize(p, TYPE, n) Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n * sizeof(TYPE))`` bytes. Returns a pointer cast to :c:expr:`TYPE*`. On return, @@ -423,7 +423,7 @@ Customize Memory Allocators +----------------------------------------------------------+---------------------------------------+ .. versionchanged:: 3.5 - The :c:type:`PyMemAllocator` structure was renamed to + The :c:type:`!PyMemAllocator` structure was renamed to :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. @@ -431,6 +431,8 @@ Customize Memory Allocators Enum used to identify an allocator domain. Domains: + .. c:namespace:: NULL + .. c:macro:: PYMEM_DOMAIN_RAW Functions: @@ -470,10 +472,14 @@ Customize Memory Allocators The new allocator must return a distinct non-``NULL`` pointer when requesting zero bytes. - For the :c:data:`PYMEM_DOMAIN_RAW` domain, the allocator must be + For the :c:macro:`PYMEM_DOMAIN_RAW` domain, the allocator must be thread-safe: the :term:`GIL ` is not held when the allocator is called. + For the remaining domains, the allocator must also be thread-safe: + the allocator may be called in different interpreters that do not + share a ``GIL``. + If the new allocator is not a hook (does not call the previous allocator), the :c:func:`PyMem_SetupDebugHooks` function must be called to reinstall the debug hooks on top on the new allocator. @@ -485,19 +491,21 @@ Customize Memory Allocators :c:func:`PyMem_SetAllocator` does have the following contract: - * It can be called after :c:func:`Py_PreInitialize` and before - :c:func:`Py_InitializeFromConfig` to install a custom memory - allocator. There are no restrictions over the installed allocator - other than the ones imposed by the domain (for instance, the Raw - Domain allows the allocator to be called without the GIL held). See - :ref:`the section on allocator domains ` for more - information. + * It can be called after :c:func:`Py_PreInitialize` and before + :c:func:`Py_InitializeFromConfig` to install a custom memory + allocator. There are no restrictions over the installed allocator + other than the ones imposed by the domain (for instance, the Raw + Domain allows the allocator to be called without the GIL held). See + :ref:`the section on allocator domains ` for more + information. - * If called after Python has finish initializing (after - :c:func:`Py_InitializeFromConfig` has been called) the allocator - **must** wrap the existing allocator. Substituting the current - allocator for some other arbitrary one is **not supported**. + * If called after Python has finish initializing (after + :c:func:`Py_InitializeFromConfig` has been called) the allocator + **must** wrap the existing allocator. Substituting the current + allocator for some other arbitrary one is **not supported**. + .. versionchanged:: 3.12 + All allocators must be thread-safe. .. c:function:: void PyMem_SetupDebugHooks(void) @@ -536,8 +544,8 @@ Runtime checks: - Detect write before the start of the buffer (buffer underflow). - Detect write after the end of the buffer (buffer overflow). - Check that the :term:`GIL ` is held when - allocator functions of :c:data:`PYMEM_DOMAIN_OBJ` (ex: - :c:func:`PyObject_Malloc`) and :c:data:`PYMEM_DOMAIN_MEM` (ex: + allocator functions of :c:macro:`PYMEM_DOMAIN_OBJ` (ex: + :c:func:`PyObject_Malloc`) and :c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. On error, the debug hooks use the :mod:`tracemalloc` module to get the @@ -557,9 +565,9 @@ that the treatment of negative indices differs from a Python slice): ``p[-S]`` API identifier (ASCII character): - * ``'r'`` for :c:data:`PYMEM_DOMAIN_RAW`. - * ``'m'`` for :c:data:`PYMEM_DOMAIN_MEM`. - * ``'o'`` for :c:data:`PYMEM_DOMAIN_OBJ`. + * ``'r'`` for :c:macro:`PYMEM_DOMAIN_RAW`. + * ``'m'`` for :c:macro:`PYMEM_DOMAIN_MEM`. + * ``'o'`` for :c:macro:`PYMEM_DOMAIN_OBJ`. ``p[-S+1:0]`` Copies of PYMEM_FORBIDDENBYTE. Used to catch under- writes and reads. @@ -581,7 +589,7 @@ that the treatment of negative indices differs from a Python slice): default). A serial number, incremented by 1 on each call to a malloc-like or - realloc-like function. Big-endian ``size_t``. If "bad memory" is detected + realloc-like function. Big-endian :c:type:`size_t`. If "bad memory" is detected later, the serial number gives an excellent way to set a breakpoint on the next run, to capture the instant at which this block was passed out. The static function bumpserialno() in obmalloc.c is the only place the serial @@ -601,7 +609,7 @@ PYMEM_CLEANBYTE (meaning uninitialized memory is getting used). compiled in release mode. On error, the debug hooks now use :mod:`tracemalloc` to get the traceback where a memory block was allocated. The debug hooks now also check if the GIL is held when functions of - :c:data:`PYMEM_DOMAIN_OBJ` and :c:data:`PYMEM_DOMAIN_MEM` domains are + :c:macro:`PYMEM_DOMAIN_OBJ` and :c:macro:`PYMEM_DOMAIN_MEM` domains are called. .. versionchanged:: 3.8 @@ -622,13 +630,13 @@ with a fixed size of 256 KiB. It falls back to :c:func:`PyMem_RawMalloc` and :c:func:`PyMem_RawRealloc` for allocations larger than 512 bytes. *pymalloc* is the :ref:`default allocator ` of the -:c:data:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) and -:c:data:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) domains. +:c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) and +:c:macro:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) domains. The arena allocator uses the following functions: -* :c:func:`VirtualAlloc` and :c:func:`VirtualFree` on Windows, -* :c:func:`mmap` and :c:func:`munmap` if available, +* :c:func:`!VirtualAlloc` and :c:func:`!VirtualFree` on Windows, +* :c:func:`!mmap` and :c:func:`!munmap` if available, * :c:func:`malloc` and :c:func:`free` otherwise. This allocator is disabled if Python is configured with the @@ -732,8 +740,8 @@ allocators operating on different heaps. :: free(buf1); /* Fatal -- should be PyMem_Del() */ In addition to the functions aimed at handling raw memory blocks from the Python -heap, objects in Python are allocated and released with :c:func:`PyObject_New`, -:c:func:`PyObject_NewVar` and :c:func:`PyObject_Del`. +heap, objects in Python are allocated and released with :c:macro:`PyObject_New`, +:c:macro:`PyObject_NewVar` and :c:func:`PyObject_Del`. These will be explained in the next chapter on defining and implementing new object types in C. diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst index 93ad30cd4f7a8d..0d75ab8e1af111 100644 --- a/Doc/c-api/method.rst +++ b/Doc/c-api/method.rst @@ -7,8 +7,8 @@ Instance Method Objects .. index:: pair: object; instancemethod -An instance method is a wrapper for a :c:data:`PyCFunction` and the new way -to bind a :c:data:`PyCFunction` to a class object. It replaces the former call +An instance method is a wrapper for a :c:type:`PyCFunction` and the new way +to bind a :c:type:`PyCFunction` to a class object. It replaces the former call ``PyMethod_New(func, NULL, class)``. diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index d35b302fce6aa6..979b22261efa3b 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -119,7 +119,7 @@ Module Objects encoded to 'utf-8'. .. deprecated:: 3.2 - :c:func:`PyModule_GetFilename` raises :c:type:`UnicodeEncodeError` on + :c:func:`PyModule_GetFilename` raises :exc:`UnicodeEncodeError` on unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead. @@ -145,7 +145,7 @@ or request "multi-phase initialization" by returning the definition struct itsel .. c:member:: PyModuleDef_Base m_base - Always initialize this member to :const:`PyModuleDef_HEAD_INIT`. + Always initialize this member to :c:macro:`PyModuleDef_HEAD_INIT`. .. c:member:: const char *m_name @@ -164,7 +164,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This memory area is allocated based on *m_size* on module creation, and freed when the module object is deallocated, after the - :c:member:`m_free` function has been called, if present. + :c:member:`~PyModuleDef.m_free` function has been called, if present. Setting ``m_size`` to ``-1`` means that the module does not support sub-interpreters, because it has global state. @@ -202,7 +202,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (:c:data:`Py_mod_exec` function). More - precisely, this function is not called if :c:member:`m_size` is greater + precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. @@ -217,7 +217,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (:c:data:`Py_mod_exec` function). More - precisely, this function is not called if :c:member:`m_size` is greater + precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. @@ -238,7 +238,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (:c:data:`Py_mod_exec` function). More - precisely, this function is not called if :c:member:`m_size` is greater + precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. @@ -256,7 +256,7 @@ of the following two module creation functions: Create a new module object, given the definition in *def*. This behaves like :c:func:`PyModule_Create2` with *module_api_version* set to - :const:`PYTHON_API_VERSION`. + :c:macro:`PYTHON_API_VERSION`. .. c:function:: PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version) @@ -282,7 +282,7 @@ An alternate way to specify extensions is to request "multi-phase initialization Extension modules created this way behave more like Python modules: the initialization is split between the *creation phase*, when the module object is created, and the *execution phase*, when it is populated. -The distinction is similar to the :py:meth:`__new__` and :py:meth:`__init__` methods +The distinction is similar to the :py:meth:`!__new__` and :py:meth:`!__init__` methods of classes. Unlike modules created using single-phase initialization, these modules are not @@ -293,7 +293,7 @@ By default, multiple modules created from the same definition should be independent: changes to one should not affect the others. This means that all state should be specific to the module object (using e.g. using :c:func:`PyModule_GetState`), or its contents (such as the module's -:attr:`__dict__` or individual classes created with :c:func:`PyType_FromSpec`). +:attr:`~object.__dict__` or individual classes created with :c:func:`PyType_FromSpec`). All modules created using multi-phase initialization are expected to support :ref:`sub-interpreters `. Making sure multiple modules @@ -338,6 +338,7 @@ The available slot types are: The *value* pointer of this slot must point to a function of the signature: .. c:function:: PyObject* create_module(PyObject *spec, PyModuleDef *def) + :noindex: The function receives a :py:class:`~importlib.machinery.ModuleSpec` instance, as defined in :PEP:`451`, and the module definition. @@ -372,10 +373,44 @@ The available slot types are: The signature of the function is: .. c:function:: int exec_module(PyObject* module) + :noindex: If multiple ``Py_mod_exec`` slots are specified, they are processed in the order they appear in the *m_slots* array. +.. c:macro:: Py_mod_multiple_interpreters + + Specifies one of the following values: + + .. c:namespace:: NULL + + .. c:macro:: Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED + + The module does not support being imported in subinterpreters. + + .. c:macro:: Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED + + The module supports being imported in subinterpreters, + but only when they share the main interpreter's GIL. + (See :ref:`isolating-extensions-howto`.) + + .. c:macro:: Py_MOD_PER_INTERPRETER_GIL_SUPPORTED + + The module supports being imported in subinterpreters, + even when they have their own GIL. + (See :ref:`isolating-extensions-howto`.) + + This slot determines whether or not importing this module + in a subinterpreter will fail. + + Multiple ``Py_mod_multiple_interpreters`` slots may not be specified + in one module definition. + + If ``Py_mod_multiple_interpreters`` is not specified, the import + machinery defaults to ``Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED``. + + .. versionadded:: 3.12 + See :PEP:`489` for more details on multi-phase initialization. Low-level module creation functions @@ -390,7 +425,7 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and Create a new module object, given the definition in *def* and the ModuleSpec *spec*. This behaves like :c:func:`PyModule_FromDefAndSpec2` - with *module_api_version* set to :const:`PYTHON_API_VERSION`. + with *module_api_version* set to :c:macro:`PYTHON_API_VERSION`. .. versionadded:: 3.5 @@ -515,7 +550,7 @@ state: .. note:: Unlike other functions that steal references, ``PyModule_AddObject()`` - only decrements the reference count of *value* **on success**. + only releases the reference to *value* **on success**. This means that its return value must be checked, and calling code must :c:func:`Py_XDECREF` *value* manually on error. @@ -552,7 +587,7 @@ state: ``NULL``-terminated. Return ``-1`` on error, ``0`` on success. -.. c:function:: int PyModule_AddIntMacro(PyObject *module, macro) +.. c:macro:: PyModule_AddIntMacro(module, macro) Add an int constant to *module*. The name and the value are taken from *macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int @@ -560,7 +595,7 @@ state: Return ``-1`` on error, ``0`` on success. -.. c:function:: int PyModule_AddStringMacro(PyObject *module, macro) +.. c:macro:: PyModule_AddStringMacro(module, macro) Add a string constant to *module*. diff --git a/Doc/c-api/none.rst b/Doc/c-api/none.rst index 1a497652ac5655..dd8bfb56104251 100644 --- a/Doc/c-api/none.rst +++ b/Doc/c-api/none.rst @@ -9,7 +9,7 @@ The ``None`` Object Note that the :c:type:`PyTypeObject` for ``None`` is not directly exposed in the Python/C API. Since ``None`` is a singleton, testing for object identity (using -``==`` in C) is sufficient. There is no :c:func:`PyNone_Check` function for the +``==`` in C) is sufficient. There is no :c:func:`!PyNone_Check` function for the same reason. diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 6fc5b2d14dd327..a4e3e74861a315 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -15,18 +15,36 @@ Object Protocol .. c:macro:: Py_RETURN_NOTIMPLEMENTED Properly handle returning :c:data:`Py_NotImplemented` from within a C - function (that is, increment the reference count of NotImplemented and - return it). + function (that is, create a new :term:`strong reference` + to NotImplemented and return it). .. c:function:: int PyObject_Print(PyObject *o, FILE *fp, int flags) Print an object *o*, on file *fp*. Returns ``-1`` on error. The flags argument is used to enable certain printing options. The only option currently supported - is :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written + is :c:macro:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written instead of the :func:`repr`. +.. c:function:: int PyObject_HasAttrWithError(PyObject *o, const char *attr_name) + + Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. + This is equivalent to the Python expression ``hasattr(o, attr_name)``. + On failure, return ``-1``. + + .. versionadded:: 3.13 + + +.. c:function:: int PyObject_HasAttrStringWithError(PyObject *o, const char *attr_name) + + This is the same as :c:func:`PyObject_HasAttrWithError`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. + + .. versionadded:: 3.13 + + .. c:function:: int PyObject_HasAttr(PyObject *o, PyObject *attr_name) Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This @@ -37,22 +55,23 @@ Object Protocol Exceptions that occur when this calls :meth:`~object.__getattr__` and :meth:`~object.__getattribute__` methods are silently ignored. - For proper error handling, use :c:func:`PyObject_GetOptionalAttr` or - :c:func:`PyObject_GetAttr` instead. + For proper error handling, use :c:func:`PyObject_HasAttrWithError`, + :c:func:`PyObject_GetOptionalAttr` or :c:func:`PyObject_GetAttr` instead. .. c:function:: int PyObject_HasAttrString(PyObject *o, const char *attr_name) - Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This - is equivalent to the Python expression ``hasattr(o, attr_name)``. This function - always succeeds. + This is the same as :c:func:`PyObject_HasAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. note:: Exceptions that occur when this calls :meth:`~object.__getattr__` and - :meth:`~object.__getattribute__` methods or while creating the temporary :class:`str` - object are silently ignored. - For proper error handling, use :c:func:`PyObject_GetOptionalAttrString` + :meth:`~object.__getattribute__` methods or while creating the temporary + :class:`str` object are silently ignored. + For proper error handling, use :c:func:`PyObject_HasAttrStringWithError`, + :c:func:`PyObject_GetOptionalAttrString` or :c:func:`PyObject_GetAttrString` instead. @@ -68,9 +87,9 @@ Object Protocol .. c:function:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name) - Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or ``NULL`` on failure. This is the equivalent of the Python - expression ``o.attr_name``. + This is the same as :c:func:`PyObject_GetAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. If the missing attribute should not be treated as a failure, you can use :c:func:`PyObject_GetOptionalAttrString` instead. @@ -93,15 +112,9 @@ Object Protocol .. c:function:: int PyObject_GetOptionalAttrString(PyObject *obj, const char *attr_name, PyObject **result); - Variant of :c:func:`PyObject_GetAttrString` which doesn't raise - :exc:`AttributeError` if the attribute is not found. - - If the attribute is found, return ``1`` and set *\*result* to a new - :term:`strong reference` to the attribute. - If the attribute is not found, return ``0`` and set *\*result* to ``NULL``; - the :exc:`AttributeError` is silenced. - If an error other than :exc:`AttributeError` is raised, return ``-1`` and - set *\*result* to ``NULL``. + This is the same as :c:func:`PyObject_GetOptionalAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. versionadded:: 3.13 @@ -129,10 +142,9 @@ Object Protocol .. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v) - Set the value of the attribute named *attr_name*, for object *o*, to the value - *v*. Raise an exception and return ``-1`` on failure; - return ``0`` on success. This is the equivalent of the Python statement - ``o.attr_name = v``. + This is the same as :c:func:`PyObject_SetAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. If *v* is ``NULL``, the attribute is deleted, but this feature is deprecated in favour of using :c:func:`PyObject_DelAttrString`. @@ -158,8 +170,9 @@ Object Protocol .. c:function:: int PyObject_DelAttrString(PyObject *o, const char *attr_name) - Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``del o.attr_name``. + This is the same as :c:func:`PyObject_DelAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: PyObject* PyObject_GenericGetDict(PyObject *o, void *context) @@ -199,8 +212,8 @@ Object Protocol .. c:function:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid) Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, + which must be one of :c:macro:`Py_LT`, :c:macro:`Py_LE`, :c:macro:`Py_EQ`, + :c:macro:`Py_NE`, :c:macro:`Py_GT`, or :c:macro:`Py_GE`, corresponding to ``<``, ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. This is the equivalent of the Python expression ``o1 op o2``, where ``op`` is the operator corresponding to *opid*. Returns the value of the comparison on success, or ``NULL`` on failure. @@ -209,8 +222,8 @@ Object Protocol .. c:function:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid) Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, + which must be one of :c:macro:`Py_LT`, :c:macro:`Py_LE`, :c:macro:`Py_EQ`, + :c:macro:`Py_NE`, :c:macro:`Py_GT`, or :c:macro:`Py_GE`, corresponding to ``<``, ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. Returns ``-1`` on error, ``0`` if the result is false, ``1`` otherwise. This is the equivalent of the Python expression ``o1 op o2``, where ``op`` is the operator corresponding to @@ -218,7 +231,7 @@ Object Protocol .. note:: If *o1* and *o2* are the same object, :c:func:`PyObject_RichCompareBool` - will always return ``1`` for :const:`Py_EQ` and ``0`` for :const:`Py_NE`. + will always return ``1`` for :c:macro:`Py_EQ` and ``0`` for :c:macro:`Py_NE`. .. c:function:: PyObject* PyObject_Format(PyObject *obj, PyObject *format_spec) @@ -293,7 +306,7 @@ Object Protocol Normally only class objects, i.e. instances of :class:`type` or a derived class, are considered classes. However, objects can override this by having - a :attr:`__bases__` attribute (which must be a tuple of base classes). + a :attr:`~class.__bases__` attribute (which must be a tuple of base classes). .. c:function:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) @@ -310,10 +323,10 @@ Object Protocol is an instance of *cls* if its class is a subclass of *cls*. An instance *inst* can override what is considered its class by having a - :attr:`__class__` attribute. + :attr:`~instance.__class__` attribute. An object *cls* can override if it is considered a class, and what its base - classes are, by having a :attr:`__bases__` attribute (which must be a tuple + classes are, by having a :attr:`~class.__bases__` attribute (which must be a tuple of base classes). @@ -357,11 +370,12 @@ Object Protocol When *o* is non-``NULL``, returns a type object corresponding to the object type of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``. This - is equivalent to the Python expression ``type(o)``. This function increments the - reference count of the return value. There's really no reason to use this + is equivalent to the Python expression ``type(o)``. + This function creates a new :term:`strong reference` to the return value. + There's really no reason to use this function instead of the :c:func:`Py_TYPE()` function, which returns a - pointer of type :c:expr:`PyTypeObject*`, except when the incremented reference - count is needed. + pointer of type :c:expr:`PyTypeObject*`, except when a new + :term:`strong reference` is needed. .. c:function:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type) @@ -468,10 +482,28 @@ Object Protocol .. c:function:: void *PyObject_GetItemData(PyObject *o) Get a pointer to per-item data for a class with - :const:`Py_TPFLAGS_ITEMS_AT_END`. + :c:macro:`Py_TPFLAGS_ITEMS_AT_END`. On error, set an exception and return ``NULL``. :py:exc:`TypeError` is raised if *o* does not have - :const:`Py_TPFLAGS_ITEMS_AT_END` set. + :c:macro:`Py_TPFLAGS_ITEMS_AT_END` set. .. versionadded:: 3.12 + +.. c:function:: int PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) + + Visit the managed dictionary of *obj*. + + This function must only be called in a traverse function of the type which + has the :c:macro:`Py_TPFLAGS_MANAGED_DICT` flag set. + + .. versionadded:: 3.13 + +.. c:function:: void PyObject_ClearManagedDict(PyObject *obj) + + Clear the managed dictionary of *obj*. + + This function must only be called in a traverse function of the type which + has the :c:macro:`Py_TPFLAGS_MANAGED_DICT` flag set. + + .. versionadded:: 3.13 diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst index d8e9c2da6f3ff3..118af7a1a8cf90 100644 --- a/Doc/c-api/refcounting.rst +++ b/Doc/c-api/refcounting.rst @@ -15,6 +15,12 @@ of Python objects. Get the reference count of the Python object *o*. + Note that the returned value may not actually reflect how many + references to the object are actually held. For example, some + objects are "immortal" and have a very high refcount that does not + reflect the actual number of references. Consequently, do not rely + on the returned value to be accurate, other than a value of 0 or 1. + Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count. .. versionchanged:: 3.11 @@ -28,36 +34,53 @@ of Python objects. Set the object *o* reference counter to *refcnt*. + Note that this function has no effect on + `immortal `_ + objects. + .. versionadded:: 3.9 + .. versionchanged:: 3.12 + Immortal objects are not modified. + .. c:function:: void Py_INCREF(PyObject *o) - Increment the reference count for object *o*. + Indicate taking a new :term:`strong reference` to object *o*, + indicating it is in use and should not be destroyed. This function is usually used to convert a :term:`borrowed reference` to a :term:`strong reference` in-place. The :c:func:`Py_NewRef` function can be used to create a new :term:`strong reference`. + When done using the object, release is by calling :c:func:`Py_DECREF`. + The object must not be ``NULL``; if you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`. + Do not expect this function to actually modify *o* in any way. + For at least `some objects `_, + this function has no effect. + + .. versionchanged:: 3.12 + Immortal objects are not modified. + .. c:function:: void Py_XINCREF(PyObject *o) - Increment the reference count for object *o*. The object may be ``NULL``, in - which case the macro has no effect. + Similar to :c:func:`Py_INCREF`, but the object *o* can be ``NULL``, + in which case this has no effect. See also :c:func:`Py_XNewRef`. .. c:function:: PyObject* Py_NewRef(PyObject *o) - Create a new :term:`strong reference` to an object: increment the reference - count of the object *o* and return the object *o*. + Create a new :term:`strong reference` to an object: + call :c:func:`Py_INCREF` on *o* and return the object *o*. When the :term:`strong reference` is no longer needed, :c:func:`Py_DECREF` - should be called on it to decrement the object reference count. + should be called on it to release the reference. The object *o* must not be ``NULL``; use :c:func:`Py_XNewRef` if *o* can be ``NULL``. @@ -87,9 +110,12 @@ of Python objects. .. c:function:: void Py_DECREF(PyObject *o) - Decrement the reference count for object *o*. + Release a :term:`strong reference` to object *o*, indicating the + reference is no longer used. - If the reference count reaches zero, the object's type's deallocation + Once the last :term:`strong reference` is released + (i.e. the object's reference count reaches 0), + the object's type's deallocation function (which must not be ``NULL``) is invoked. This function is usually used to delete a :term:`strong reference` before @@ -98,10 +124,14 @@ of Python objects. The object must not be ``NULL``; if you aren't sure that it isn't ``NULL``, use :c:func:`Py_XDECREF`. + Do not expect this function to actually modify *o* in any way. + For at least `some objects `_, + this function has no effect. + .. warning:: The deallocation function can cause arbitrary Python code to be invoked (e.g. - when a class instance with a :meth:`__del__` method is deallocated). While + when a class instance with a :meth:`~object.__del__` method is deallocated). While exceptions in such code are not propagated, the executed code has free access to all Python global variables. This means that any object that is reachable from a global variable should be in a consistent state before :c:func:`Py_DECREF` is @@ -109,25 +139,29 @@ of Python objects. reference to the deleted object in a temporary variable, update the list data structure, and then call :c:func:`Py_DECREF` for the temporary variable. + .. versionchanged:: 3.12 + Immortal objects are not modified. + .. c:function:: void Py_XDECREF(PyObject *o) - Decrement the reference count for object *o*. The object may be ``NULL``, in - which case the macro has no effect; otherwise the effect is the same as for - :c:func:`Py_DECREF`, and the same warning applies. + Similar to :c:func:`Py_DECREF`, but the object *o* can be ``NULL``, + in which case this has no effect. + The same warning from :c:func:`Py_DECREF` applies here as well. .. c:function:: void Py_CLEAR(PyObject *o) - Decrement the reference count for object *o*. The object may be ``NULL``, in + Release a :term:`strong reference` for object *o*. + The object may be ``NULL``, in which case the macro has no effect; otherwise the effect is the same as for :c:func:`Py_DECREF`, except that the argument is also set to ``NULL``. The warning for :c:func:`Py_DECREF` does not apply with respect to the object passed because the macro carefully uses a temporary variable and sets the argument to ``NULL`` - before decrementing its reference count. + before releasing the reference. - It is a good idea to use this macro whenever decrementing the reference - count of an object that might be traversed during garbage collection. + It is a good idea to use this macro whenever releasing a reference + to an object that might be traversed during garbage collection. .. versionchanged:: 3.12 The macro argument is now only evaluated once. If the argument has side @@ -136,20 +170,22 @@ of Python objects. .. c:function:: void Py_IncRef(PyObject *o) - Increment the reference count for object *o*. A function version of :c:func:`Py_XINCREF`. + Indicate taking a new :term:`strong reference` to object *o*. + A function version of :c:func:`Py_XINCREF`. It can be used for runtime dynamic embedding of Python. .. c:function:: void Py_DecRef(PyObject *o) - Decrement the reference count for object *o*. A function version of :c:func:`Py_XDECREF`. + Release a :term:`strong reference` to object *o*. + A function version of :c:func:`Py_XDECREF`. It can be used for runtime dynamic embedding of Python. .. c:macro:: Py_SETREF(dst, src) - Macro safely decrementing the `dst` reference count and setting `dst` to - `src`. + Macro safely releasing a :term:`strong reference` to object *dst* + and setting *dst* to *src*. As in case of :c:func:`Py_CLEAR`, "the obvious" code can be deadly:: @@ -160,9 +196,10 @@ of Python objects. Py_SETREF(dst, src); - That arranges to set `dst` to `src` _before_ decrementing reference count of - *dst* old value, so that any code triggered as a side-effect of `dst` - getting torn down no longer believes `dst` points to a valid object. + That arranges to set *dst* to *src* _before_ releasing the reference + to the old value of *dst*, so that any code triggered as a side-effect + of *dst* getting torn down no longer believes *dst* points + to a valid object. .. versionadded:: 3.6 diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index 402a3e5e09ff56..ce28839f5ba739 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -9,7 +9,7 @@ Sequence Protocol .. c:function:: int PySequence_Check(PyObject *o) Return ``1`` if the object provides the sequence protocol, and ``0`` otherwise. - Note that it returns ``1`` for Python classes with a :meth:`__getitem__` + Note that it returns ``1`` for Python classes with a :meth:`~object.__getitem__` method, unless they are :class:`dict` subclasses, since in general it is impossible to determine what type of keys the class supports. This function always succeeds. diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst index d642a5f1902e2e..1e8a09509032f5 100644 --- a/Doc/c-api/set.rst +++ b/Doc/c-api/set.rst @@ -110,7 +110,7 @@ or :class:`frozenset` or instances of their subtypes. .. index:: pair: built-in function; len Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to - ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a + ``len(anyset)``. Raises a :exc:`SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. @@ -122,9 +122,9 @@ or :class:`frozenset` or instances of their subtypes. .. c:function:: int PySet_Contains(PyObject *anyset, PyObject *key) Return ``1`` if found, ``0`` if not found, and ``-1`` if an error is encountered. Unlike - the Python :meth:`__contains__` method, this function does not automatically + the Python :meth:`~object.__contains__` method, this function does not automatically convert unhashable sets into temporary frozensets. Raise a :exc:`TypeError` if - the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a + the *key* is unhashable. Raise :exc:`SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. @@ -149,7 +149,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes. error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a :exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`~set.discard` method, this function does not automatically convert unhashable sets into - temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is not an + temporary frozensets. Raise :exc:`SystemError` if *set* is not an instance of :class:`set` or its subtype. diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index c54a659cf2ffd8..9e880c6b7f25ad 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -34,7 +34,7 @@ Slice Objects *length* as errors. Returns ``0`` on success and ``-1`` on error with no exception set (unless one of - the indices was not :const:`None` and failed to be converted to an integer, + the indices was not ``None`` and failed to be converted to an integer, in which case ``-1`` is returned with an exception set). You probably do not want to use this function. diff --git a/Doc/c-api/stable.rst b/Doc/c-api/stable.rst index 149d4d6bac3ee4..63a100a6f26f24 100644 --- a/Doc/c-api/stable.rst +++ b/Doc/c-api/stable.rst @@ -18,7 +18,7 @@ way; see :ref:`stable-abi-platform` below). So, code compiled for Python 3.10.0 will work on 3.10.8 and vice versa, but will need to be compiled separately for 3.9.x and 3.10.x. -There are two tiers of C API with different stability exepectations: +There are two tiers of C API with different stability expectations: - :ref:`Unstable API `, may change in minor versions without a deprecation period. It is marked by the ``PyUnstable`` prefix in names. @@ -74,7 +74,7 @@ Contents of the Limited API are :ref:`listed below `. Define this macro before including ``Python.h`` to opt in to only use the Limited API, and to select the Limited API version. - Define ``Py_LIMITED_API`` to the value of :c:data:`PY_VERSION_HEX` + Define ``Py_LIMITED_API`` to the value of :c:macro:`PY_VERSION_HEX` corresponding to the lowest Python version your extension supports. The extension will work without recompilation with all Python 3 releases from the specified one onward, and can use Limited API introduced up to that diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 766f881463c00f..25cb4ed40f63e7 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -35,7 +35,7 @@ under :ref:`reference counting `. .. c:type:: PyVarObject - This is an extension of :c:type:`PyObject` that adds the :attr:`ob_size` + This is an extension of :c:type:`PyObject` that adds the :c:member:`~PyVarObject.ob_size` field. This is only used for objects that have some notion of *length*. This type does not often appear in the Python/C API. Access to the members must be done by using the macros @@ -152,7 +152,7 @@ under :ref:`reference counting `. .. c:macro:: PyVarObject_HEAD_INIT(type, size) This is a macro which expands to initialization values for a new - :c:type:`PyVarObject` type, including the :attr:`ob_size` field. + :c:type:`PyVarObject` type, including the :c:member:`~PyVarObject.ob_size` field. This macro expands to:: _PyObject_EXTRA_INIT @@ -179,7 +179,7 @@ Implementing functions and methods .. c:type:: PyCFunctionWithKeywords Type of the functions used to implement Python callables in C - with signature :const:`METH_VARARGS | METH_KEYWORDS`. + with signature :ref:`METH_VARARGS | METH_KEYWORDS `. The function signature is:: PyObject *PyCFunctionWithKeywords(PyObject *self, @@ -190,7 +190,7 @@ Implementing functions and methods .. c:type:: _PyCFunctionFast Type of the functions used to implement Python callables in C - with signature :const:`METH_FASTCALL`. + with signature :c:macro:`METH_FASTCALL`. The function signature is:: PyObject *_PyCFunctionFast(PyObject *self, @@ -200,7 +200,7 @@ Implementing functions and methods .. c:type:: _PyCFunctionFastWithKeywords Type of the functions used to implement Python callables in C - with signature :const:`METH_FASTCALL | METH_KEYWORDS`. + with signature :ref:`METH_FASTCALL | METH_KEYWORDS `. The function signature is:: PyObject *_PyCFunctionFastWithKeywords(PyObject *self, @@ -211,7 +211,7 @@ Implementing functions and methods .. c:type:: PyCMethod Type of the functions used to implement Python callables in C - with signature :const:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS`. + with signature :ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS `. The function signature is:: PyObject *PyCMethod(PyObject *self, @@ -228,36 +228,38 @@ Implementing functions and methods Structure used to describe a method of an extension type. This structure has four fields: - .. c:member:: const char* ml_name + .. c:member:: const char *ml_name - name of the method + Name of the method. .. c:member:: PyCFunction ml_meth - pointer to the C implementation + Pointer to the C implementation. .. c:member:: int ml_flags - flags bits indicating how the call should be constructed + Flags bits indicating how the call should be constructed. - .. c:member:: const char* ml_doc + .. c:member:: const char *ml_doc - points to the contents of the docstring + Points to the contents of the docstring. -The :c:member:`ml_meth` is a C function pointer. The functions may be of different +The :c:member:`~PyMethodDef.ml_meth` is a C function pointer. +The functions may be of different types, but they always return :c:expr:`PyObject*`. If the function is not of the :c:type:`PyCFunction`, the compiler will require a cast in the method table. Even though :c:type:`PyCFunction` defines the first parameter as :c:expr:`PyObject*`, it is common that the method implementation uses the specific C type of the *self* object. -The :c:member:`ml_flags` field is a bitfield which can include the following flags. +The :c:member:`~PyMethodDef.ml_flags` field is a bitfield which can include +the following flags. The individual flags indicate either a calling convention or a binding convention. There are these calling conventions: -.. data:: METH_VARARGS +.. c:macro:: METH_VARARGS This is the typical calling convention, where the methods have the type :c:type:`PyCFunction`. The function expects two :c:expr:`PyObject*` values. @@ -267,8 +269,17 @@ There are these calling conventions: using :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_UnpackTuple`. -.. data:: METH_VARARGS | METH_KEYWORDS +.. c:macro:: METH_KEYWORDS + Can only be used in certain combinations with other flags: + :ref:`METH_VARARGS | METH_KEYWORDS `, + :ref:`METH_FASTCALL | METH_KEYWORDS ` and + :ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS `. + + +.. _METH_VARARGS-METH_KEYWORDS: + +:c:expr:`METH_VARARGS | METH_KEYWORDS` Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`. The function expects three parameters: *self*, *args*, *kwargs* where *kwargs* is a dictionary of all the keyword arguments or possibly ``NULL`` @@ -276,7 +287,7 @@ There are these calling conventions: using :c:func:`PyArg_ParseTupleAndKeywords`. -.. data:: METH_FASTCALL +.. c:macro:: METH_FASTCALL Fast calling convention supporting only positional arguments. The methods have the type :c:type:`_PyCFunctionFast`. @@ -291,9 +302,10 @@ There are these calling conventions: ``METH_FASTCALL`` is now part of the :ref:`stable ABI `. -.. data:: METH_FASTCALL | METH_KEYWORDS +.. _METH_FASTCALL-METH_KEYWORDS: - Extension of :const:`METH_FASTCALL` supporting also keyword arguments, +:c:expr:`METH_FASTCALL | METH_KEYWORDS` + Extension of :c:macro:`METH_FASTCALL` supporting also keyword arguments, with methods of type :c:type:`_PyCFunctionFastWithKeywords`. Keyword arguments are passed the same way as in the :ref:`vectorcall protocol `: @@ -306,10 +318,18 @@ There are these calling conventions: .. versionadded:: 3.7 -.. data:: METH_METHOD | METH_FASTCALL | METH_KEYWORDS +.. c:macro:: METH_METHOD + + Can only be used in the combination with other flags: + :ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS `. - Extension of :const:`METH_FASTCALL | METH_KEYWORDS` supporting the *defining - class*, that is, the class that contains the method in question. + +.. _METH_METHOD-METH_FASTCALL-METH_KEYWORDS: + +:c:expr:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` + Extension of :ref:`METH_FASTCALL | METH_KEYWORDS ` + supporting the *defining class*, that is, + the class that contains the method in question. The defining class might be a superclass of ``Py_TYPE(self)``. The method needs to be of type :c:type:`PyCMethod`, the same as for @@ -319,10 +339,10 @@ There are these calling conventions: .. versionadded:: 3.9 -.. data:: METH_NOARGS +.. c:macro:: METH_NOARGS Methods without parameters don't need to check whether arguments are given if - they are listed with the :const:`METH_NOARGS` flag. They need to be of type + they are listed with the :c:macro:`METH_NOARGS` flag. They need to be of type :c:type:`PyCFunction`. The first parameter is typically named *self* and will hold a reference to the module or object instance. In all cases the second parameter will be ``NULL``. @@ -331,9 +351,9 @@ There are these calling conventions: :c:macro:`Py_UNUSED` can be used to prevent a compiler warning. -.. data:: METH_O +.. c:macro:: METH_O - Methods with a single object argument can be listed with the :const:`METH_O` + Methods with a single object argument can be listed with the :c:macro:`METH_O` flag, instead of invoking :c:func:`PyArg_ParseTuple` with a ``"O"`` argument. They have the type :c:type:`PyCFunction`, with the *self* parameter, and a :c:expr:`PyObject*` parameter representing the single argument. @@ -345,7 +365,7 @@ defined for modules. At most one of these flags may be set for any given method. -.. data:: METH_CLASS +.. c:macro:: METH_CLASS .. index:: pair: built-in function; classmethod @@ -355,7 +375,7 @@ method. function. -.. data:: METH_STATIC +.. c:macro:: METH_STATIC .. index:: pair: built-in function; staticmethod @@ -367,13 +387,13 @@ One other constant controls whether a method is loaded in place of another definition with the same method name. -.. data:: METH_COEXIST +.. c:macro:: METH_COEXIST The method will be loaded in place of existing definitions. Without *METH_COEXIST*, the default is to skip repeated definitions. Since slot wrappers are loaded before the method table, the existence of a *sq_contains* slot, for example, would generate a wrapped method named - :meth:`__contains__` and preclude the loading of a corresponding + :meth:`~object.__contains__` and preclude the loading of a corresponding PyCFunction with the same name. With the flag defined, the PyCFunction will be loaded in place of the wrapper object and will co-exist with the slot. This is helpful because calls to PyCFunctions are optimized more @@ -386,7 +406,11 @@ Accessing attributes of extension types .. c:type:: PyMemberDef Structure which describes an attribute of a type which corresponds to a C - struct member. Its fields are, in order: + struct member. + When defining a class, put a NULL-terminated array of these + structures in the :c:member:`~PyTypeObject.tp_members` slot. + + Its fields are, in order: .. c:member:: const char* name @@ -414,7 +438,7 @@ Accessing attributes of extension types The string should be static, no copy is made of it. Typically, it is defined using :c:macro:`PyDoc_STR`. - By default (when :c:member:`flags` is ``0``), members allow + By default (when :c:member:`~PyMemberDef.flags` is ``0``), members allow both read and write access. Use the :c:macro:`Py_READONLY` flag for read-only access. Certain types, like :c:macro:`Py_T_STRING`, imply :c:macro:`Py_READONLY`. @@ -440,8 +464,8 @@ Accessing attributes of extension types The legacy offsets :c:member:`~PyTypeObject.tp_dictoffset` and :c:member:`~PyTypeObject.tp_weaklistoffset` can be defined similarly using ``"__dictoffset__"`` and ``"__weaklistoffset__"`` members, but extensions - are strongly encouraged to use :const:`Py_TPFLAGS_MANAGED_DICT` and - :const:`Py_TPFLAGS_MANAGED_WEAKREF` instead. + are strongly encouraged to use :c:macro:`Py_TPFLAGS_MANAGED_DICT` and + :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead. .. versionchanged:: 3.12 @@ -494,7 +518,7 @@ The following flags can be used with :c:member:`PyMemberDef.flags`: Can only be used as part of :c:member:`Py_tp_members ` :c:type:`slot ` when creating a class using negative - :c:member:`~PyTypeDef.basicsize`. + :c:member:`~PyType_Spec.basicsize`. It is mandatory in that case. This flag is only used in :c:type:`PyTypeSlot`. @@ -509,19 +533,19 @@ The following flags can be used with :c:member:`PyMemberDef.flags`: .. versionchanged:: 3.10 - The :const:`!RESTRICTED`, :const:`!READ_RESTRICTED` and - :const:`!WRITE_RESTRICTED` macros available with + The :c:macro:`!RESTRICTED`, :c:macro:`!READ_RESTRICTED` and + :c:macro:`!WRITE_RESTRICTED` macros available with ``#include "structmember.h"`` are deprecated. - :const:`!READ_RESTRICTED` and :const:`!RESTRICTED` are equivalent to - :const:`Py_AUDIT_READ`; :const:`!WRITE_RESTRICTED` does nothing. + :c:macro:`!READ_RESTRICTED` and :c:macro:`!RESTRICTED` are equivalent to + :c:macro:`Py_AUDIT_READ`; :c:macro:`!WRITE_RESTRICTED` does nothing. .. index:: single: READONLY .. versionchanged:: 3.12 - The :const:`!READONLY` macro was renamed to :const:`Py_READONLY`. - The :const:`!PY_AUDIT_READ` macro was renamed with the ``Py_`` prefix. + The :c:macro:`!READONLY` macro was renamed to :c:macro:`Py_READONLY`. + The :c:macro:`!PY_AUDIT_READ` macro was renamed with the ``Py_`` prefix. The new names are now always available. Previously, these required ``#include "structmember.h"``. The header is still available and it provides the old names. diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index c4077b2a5620d6..e3c54b075114ff 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -8,8 +8,9 @@ Operating System Utilities .. c:function:: PyObject* PyOS_FSPath(PyObject *path) Return the file system representation for *path*. If the object is a - :class:`str` or :class:`bytes` object, then its reference count is - incremented. If the object implements the :class:`os.PathLike` interface, + :class:`str` or :class:`bytes` object, then a new + :term:`strong reference` is returned. + If the object implements the :class:`os.PathLike` interface, then :meth:`~os.PathLike.__fspath__` is returned as long as it is a :class:`str` or :class:`bytes` object. Otherwise :exc:`TypeError` is raised and ``NULL`` is returned. @@ -97,16 +98,16 @@ Operating System Utilities .. c:function:: int PyOS_CheckStack() Return true when the interpreter runs out of stack space. This is a reliable - check, but is only available when :const:`USE_STACKCHECK` is defined (currently + check, but is only available when :c:macro:`USE_STACKCHECK` is defined (currently on certain versions of Windows using the Microsoft Visual C++ compiler). - :const:`USE_STACKCHECK` will be defined automatically; you should never + :c:macro:`USE_STACKCHECK` will be defined automatically; you should never change the definition in your own code. .. c:function:: PyOS_sighandler_t PyOS_getsig(int i) Return the current signal handler for signal *i*. This is a thin wrapper around - either :c:func:`sigaction` or :c:func:`signal`. Do not call those functions + either :c:func:`!sigaction` or :c:func:`!signal`. Do not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:expr:`void (\*)(int)`. @@ -114,7 +115,7 @@ Operating System Utilities .. c:function:: PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) Set the signal handler for signal *i* to be *h*; return the old signal handler. - This is a thin wrapper around either :c:func:`sigaction` or :c:func:`signal`. Do + This is a thin wrapper around either :c:func:`!sigaction` or :c:func:`!signal`. Do not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:expr:`void (\*)(int)`. @@ -167,7 +168,7 @@ Operating System Utilities .. versionchanged:: 3.8 The function now uses the UTF-8 encoding on Windows if - :c:member:`PyConfig.legacy_windows_fs_encoding` is zero; + :c:member:`PyPreConfig.legacy_windows_fs_encoding` is zero; .. c:function:: char* Py_EncodeLocale(const wchar_t *text, size_t *error_pos) @@ -209,7 +210,7 @@ Operating System Utilities .. versionchanged:: 3.8 The function now uses the UTF-8 encoding on Windows if - :c:member:`PyConfig.legacy_windows_fs_encoding` is zero. + :c:member:`PyPreConfig.legacy_windows_fs_encoding` is zero. .. _systemfunctions: @@ -290,19 +291,24 @@ accessible to C code. They all work with the current interpreter thread's Raise an auditing event with any active hooks. Return zero for success and non-zero with an exception set on failure. + The *event* string argument must not be *NULL*. + If any hooks have been added, *format* and other arguments will be used to construct a tuple to pass. Apart from ``N``, the same format characters as used in :c:func:`Py_BuildValue` are available. If the built value is not - a tuple, it will be added into a single-element tuple. (The ``N`` format - option consumes a reference, but since there is no way to know whether - arguments to this function will be consumed, using it may cause reference - leaks.) + a tuple, it will be added into a single-element tuple. + + The ``N`` format option must not be used. It consumes a reference, but since + there is no way to know whether arguments to this function will be consumed, + using it may cause reference leaks. Note that ``#`` format characters should always be treated as :c:type:`Py_ssize_t`, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined. :func:`sys.audit` performs the same function from Python code. + See also :c:func:`PySys_AuditTuple`. + .. versionadded:: 3.8 .. versionchanged:: 3.8.2 @@ -311,6 +317,14 @@ accessible to C code. They all work with the current interpreter thread's unavoidable deprecation warning was raised. +.. c:function:: int PySys_AuditTuple(const char *event, PyObject *args) + + Similar to :c:func:`PySys_Audit`, but pass arguments as a Python object. + *args* must be a :class:`tuple`. To pass no arguments, *args* can be *NULL*. + + .. versionadded:: 3.13 + + .. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) Append the callable *hook* to the list of active auditing hooks. @@ -363,7 +377,7 @@ Process Control This function should only be invoked when a condition is detected that would make it dangerous to continue using the Python interpreter; e.g., when the object administration appears to be corrupted. On Unix, the standard C library - function :c:func:`abort` is called which will attempt to produce a :file:`core` + function :c:func:`!abort` is called which will attempt to produce a :file:`core` file. The ``Py_FatalError()`` function is replaced with a macro which logs diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 3fe1062aa8539a..b3710560ebe7ac 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -114,6 +114,8 @@ Tuple Objects raises :exc:`MemoryError` or :exc:`SystemError`. +.. _struct-sequence-objects: + Struct Sequence Objects ----------------------- @@ -145,39 +147,39 @@ type. Contains the meta information of a struct sequence type to create. - +-------------------+------------------------------+--------------------------------------+ - | Field | C Type | Meaning | - +===================+==============================+======================================+ - | ``name`` | ``const char *`` | name of the struct sequence type | - +-------------------+------------------------------+--------------------------------------+ - | ``doc`` | ``const char *`` | pointer to docstring for the type | - | | | or ``NULL`` to omit | - +-------------------+------------------------------+--------------------------------------+ - | ``fields`` | ``PyStructSequence_Field *`` | pointer to ``NULL``-terminated array | - | | | with field names of the new type | - +-------------------+------------------------------+--------------------------------------+ - | ``n_in_sequence`` | ``int`` | number of fields visible to the | - | | | Python side (if used as tuple) | - +-------------------+------------------------------+--------------------------------------+ + .. c:member:: const char *name + + Name of the struct sequence type. + + .. c:member:: const char *doc + + Pointer to docstring for the type or ``NULL`` to omit. + + .. c:member:: PyStructSequence_Field *fields + + Pointer to ``NULL``-terminated array with field names of the new type. + + .. c:member:: int n_in_sequence + + Number of fields visible to the Python side (if used as tuple). .. c:type:: PyStructSequence_Field Describes a field of a struct sequence. As a struct sequence is modeled as a tuple, all fields are typed as :c:expr:`PyObject*`. The index in the - :attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which + :c:member:`~PyStructSequence_Desc.fields` array of + the :c:type:`PyStructSequence_Desc` determines which field of the struct sequence is described. - +-----------+------------------+-----------------------------------------+ - | Field | C Type | Meaning | - +===========+==================+=========================================+ - | ``name`` | ``const char *`` | name for the field or ``NULL`` to end | - | | | the list of named fields, set to | - | | | :c:data:`PyStructSequence_UnnamedField` | - | | | to leave unnamed | - +-----------+------------------+-----------------------------------------+ - | ``doc`` | ``const char *`` | field docstring or ``NULL`` to omit | - +-----------+------------------+-----------------------------------------+ + .. c:member:: const char *name + + Name for the field or ``NULL`` to end the list of named fields, + set to :c:data:`PyStructSequence_UnnamedField` to leave unnamed. + + .. c:member:: const char *doc + + Field docstring or ``NULL`` to omit. .. c:var:: const char * const PyStructSequence_UnnamedField diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index a5f333e2a31e03..5aaa8147dd3176 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -103,7 +103,7 @@ Type Objects :c:func:`PyType_AddWatcher` will be called whenever :c:func:`PyType_Modified` reports a change to *type*. (The callback may be called only once for a series of consecutive modifications to *type*, if - :c:func:`PyType_Lookup` is not called on *type* between the modifications; + :c:func:`!_PyType_Lookup` is not called on *type* between the modifications; this is an implementation detail and subject to change.) An extension should never call ``PyType_Watch`` with a *watcher_id* that was @@ -132,7 +132,7 @@ Type Objects .. c:function:: int PyType_IS_GC(PyTypeObject *o) Return true if the type object includes support for the cycle detector; this - tests the type flag :const:`Py_TPFLAGS_HAVE_GC`. + tests the type flag :c:macro:`Py_TPFLAGS_HAVE_GC`. .. c:function:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) @@ -165,10 +165,10 @@ Type Objects .. note:: If some of the base classes implements the GC protocol and the provided - type does not include the :const:`Py_TPFLAGS_HAVE_GC` in its flags, then + type does not include the :c:macro:`Py_TPFLAGS_HAVE_GC` in its flags, then the GC protocol will be automatically implemented from its parents. On the contrary, if the type being created does include - :const:`Py_TPFLAGS_HAVE_GC` in its flags then it **must** implement the + :c:macro:`Py_TPFLAGS_HAVE_GC` in its flags then it **must** implement the GC protocol itself by at least implementing the :c:member:`~PyTypeObject.tp_traverse` handle. @@ -215,7 +215,7 @@ Type Objects ``Py_TYPE(self)`` may be a *subclass* of the intended class, and subclasses are not necessarily defined in the same module as their superclass. See :c:type:`PyCMethod` to get the class that defines the method. - See :c:func:`PyType_GetModuleByDef` for cases when ``PyCMethod`` cannot + See :c:func:`PyType_GetModuleByDef` for cases when :c:type:`!PyCMethod` cannot be used. .. versionadded:: 3.9 @@ -268,7 +268,7 @@ The following functions and structs are used to create .. c:function:: PyObject* PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) Create and return a :ref:`heap type ` from the *spec* - (see :const:`Py_TPFLAGS_HEAPTYPE`). + (see :c:macro:`Py_TPFLAGS_HEAPTYPE`). The metaclass *metaclass* is used to construct the resulting type object. When *metaclass* is ``NULL``, the metaclass is derived from *bases* @@ -420,7 +420,7 @@ The following functions and structs are used to create - The requested :c:member:`PyType_Spec.basicsize` is zero, suggesting that the subclass does not access the instance's memory directly. - - With the :const:`Py_TPFLAGS_ITEMS_AT_END` flag. + - With the :c:macro:`Py_TPFLAGS_ITEMS_AT_END` flag. .. c:member:: unsigned int flags @@ -461,26 +461,39 @@ The following functions and structs are used to create * ``Py_nb_add`` to set :c:member:`PyNumberMethods.nb_add` * ``Py_sq_length`` to set :c:member:`PySequenceMethods.sq_length` - The following fields cannot be set at all using :c:type:`PyType_Spec` and - :c:type:`PyType_Slot`: + The following “offset†fields cannot be set using :c:type:`PyType_Slot`: + + * :c:member:`~PyTypeObject.tp_weaklistoffset` + (use :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead if possible) + * :c:member:`~PyTypeObject.tp_dictoffset` + (use :c:macro:`Py_TPFLAGS_MANAGED_DICT` instead if possible) + * :c:member:`~PyTypeObject.tp_vectorcall_offset` + (use ``"__vectorcalloffset__"`` in + :ref:`PyMemberDef `) + + If it is not possible to switch to a ``MANAGED`` flag (for example, + for vectorcall or to support Python older than 3.12), specify the + offset in :c:member:`Py_tp_members `. + See :ref:`PyMemberDef documentation ` + for details. + + The following fields cannot be set at all when creating a heap type: - * :c:member:`~PyTypeObject.tp_dict` - * :c:member:`~PyTypeObject.tp_mro` - * :c:member:`~PyTypeObject.tp_cache` - * :c:member:`~PyTypeObject.tp_subclasses` - * :c:member:`~PyTypeObject.tp_weaklist` * :c:member:`~PyTypeObject.tp_vectorcall` - * :c:member:`~PyTypeObject.tp_weaklistoffset` - (use :const:`Py_TPFLAGS_MANAGED_WEAKREF` instead) - * :c:member:`~PyTypeObject.tp_dictoffset` - (use :const:`Py_TPFLAGS_MANAGED_DICT` instead) - * :c:member:`~PyTypeObject.tp_vectorcall_offset` - (see :ref:`PyMemberDef `) + (use :c:member:`~PyTypeObject.tp_new` and/or + :c:member:`~PyTypeObject.tp_init`) + + * Internal fields: + :c:member:`~PyTypeObject.tp_dict`, + :c:member:`~PyTypeObject.tp_mro`, + :c:member:`~PyTypeObject.tp_cache`, + :c:member:`~PyTypeObject.tp_subclasses`, and + :c:member:`~PyTypeObject.tp_weaklist`. Setting :c:data:`Py_tp_bases` or :c:data:`Py_tp_base` may be problematic on some platforms. To avoid issues, use the *bases* argument of - :py:func:`PyType_FromSpecWithBases` instead. + :c:func:`PyType_FromSpecWithBases` instead. .. versionchanged:: 3.9 diff --git a/Doc/c-api/typehints.rst b/Doc/c-api/typehints.rst index 4c1957a2a1dbca..98fe68737deb81 100644 --- a/Doc/c-api/typehints.rst +++ b/Doc/c-api/typehints.rst @@ -35,7 +35,7 @@ two types exist -- :ref:`GenericAlias ` and ... } - .. seealso:: The data model method :meth:`__class_getitem__`. + .. seealso:: The data model method :meth:`~object.__class_getitem__`. .. versionadded:: 3.9 diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 7249cfe79c32e9..10c05beda7c66f 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -147,7 +147,7 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_watched`] | char | | | | | | + | [:c:member:`~PyTypeObject.tp_watched`] | unsigned char | | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ .. [#slots] @@ -163,9 +163,9 @@ Quick Reference .. [#cols] Columns: - **"O"**: set on :c:type:`PyBaseObject_Type` + **"O"**: set on :c:data:`PyBaseObject_Type` - **"T"**: set on :c:type:`PyType_Type` + **"T"**: set on :c:data:`PyType_Type` **"D"**: default (if slot is set to ``NULL``) @@ -485,17 +485,17 @@ PyObject Slots -------------- The type object structure extends the :c:type:`PyVarObject` structure. The -:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, +:c:member:`~PyVarObject.ob_size` field is used for dynamic types (created by :c:func:`!type_new`, usually called from a class statement). Note that :c:data:`PyType_Type` (the metatype) initializes :c:member:`~PyTypeObject.tp_itemsize`, which means that its instances (i.e. -type objects) *must* have the :attr:`ob_size` field. +type objects) *must* have the :c:member:`~PyVarObject.ob_size` field. .. c:member:: Py_ssize_t PyObject.ob_refcnt This is the type object's reference count, initialized to ``1`` by the ``PyObject_HEAD_INIT`` macro. Note that for :ref:`statically allocated type - objects `, the type's instances (objects whose :attr:`ob_type` + objects `, the type's instances (objects whose :c:member:`~PyObject.ob_type` points back to the type) do *not* count as references. But for :ref:`dynamically allocated type objects `, the instances *do* count as references. @@ -519,8 +519,8 @@ type objects) *must* have the :attr:`ob_size` field. Foo_Type.ob_type = &PyType_Type; This should be done before any instances of the type are created. - :c:func:`PyType_Ready` checks if :attr:`ob_type` is ``NULL``, and if so, - initializes it to the :attr:`ob_type` field of the base class. + :c:func:`PyType_Ready` checks if :c:member:`~PyObject.ob_type` is ``NULL``, and if so, + initializes it to the :c:member:`~PyObject.ob_type` field of the base class. :c:func:`PyType_Ready` will not change this field if it is non-zero. **Inheritance:** @@ -528,28 +528,6 @@ type objects) *must* have the :attr:`ob_size` field. This field is inherited by subtypes. -.. c:member:: PyObject* PyObject._ob_next - PyObject* PyObject._ob_prev - - These fields are only present when the macro ``Py_TRACE_REFS`` is defined - (see the :option:`configure --with-trace-refs option <--with-trace-refs>`). - - Their initialization to ``NULL`` is taken care of by the - ``PyObject_HEAD_INIT`` macro. For :ref:`statically allocated objects - `, these fields always remain ``NULL``. For :ref:`dynamically - allocated objects `, these two fields are used to link the - object into a doubly linked list of *all* live objects on the heap. - - This could be used for various debugging purposes; currently the only uses - are the :func:`sys.getobjects` function and to print the objects that are - still alive at the end of a run when the environment variable - :envvar:`PYTHONDUMPREFS` is set. - - **Inheritance:** - - These fields are not inherited by subtypes. - - PyVarObject Slots ----------------- @@ -569,8 +547,8 @@ PyTypeObject Slots Each slot has a section describing inheritance. If :c:func:`PyType_Ready` may set a value when the field is set to ``NULL`` then there will also be -a "Default" section. (Note that many fields set on :c:type:`PyBaseObject_Type` -and :c:type:`PyType_Type` effectively act as defaults.) +a "Default" section. (Note that many fields set on :c:data:`PyBaseObject_Type` +and :c:data:`PyType_Type` effectively act as defaults.) .. c:member:: const char* PyTypeObject.tp_name @@ -579,7 +557,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) name, followed by a dot, followed by the type name; for built-in types, it should be just the type name. If the module is a submodule of a package, the full package name is part of the full module name. For example, a type named - :class:`T` defined in module :mod:`M` in subpackage :mod:`Q` in package :mod:`P` + :class:`!T` defined in module :mod:`!M` in subpackage :mod:`!Q` in package :mod:`!P` should have the :c:member:`~PyTypeObject.tp_name` initializer ``"P.Q.M.T"``. For :ref:`dynamically allocated type objects `, @@ -619,20 +597,20 @@ and :c:type:`PyType_Type` effectively act as defaults.) instances have the same size, given in :c:member:`~PyTypeObject.tp_basicsize`. For a type with variable-length instances, the instances must have an - :attr:`ob_size` field, and the instance size is :c:member:`~PyTypeObject.tp_basicsize` plus N + :c:member:`~PyVarObject.ob_size` field, and the instance size is :c:member:`~PyTypeObject.tp_basicsize` plus N times :c:member:`~PyTypeObject.tp_itemsize`, where N is the "length" of the object. The value of - N is typically stored in the instance's :attr:`ob_size` field. There are - exceptions: for example, ints use a negative :attr:`ob_size` to indicate a + N is typically stored in the instance's :c:member:`~PyVarObject.ob_size` field. There are + exceptions: for example, ints use a negative :c:member:`~PyVarObject.ob_size` to indicate a negative number, and N is ``abs(ob_size)`` there. Also, the presence of an - :attr:`ob_size` field in the instance layout doesn't mean that the instance + :c:member:`~PyVarObject.ob_size` field in the instance layout doesn't mean that the instance structure is variable-length (for example, the structure for the list type has - fixed-length instances, yet those instances have a meaningful :attr:`ob_size` + fixed-length instances, yet those instances have a meaningful :c:member:`~PyVarObject.ob_size` field). The basic size includes the fields in the instance declared by the macro :c:macro:`PyObject_HEAD` or :c:macro:`PyObject_VAR_HEAD` (whichever is used to - declare the instance struct) and this in turn includes the :attr:`_ob_prev` and - :attr:`_ob_next` fields if they are present. This means that the only correct + declare the instance struct) and this in turn includes the :c:member:`~PyObject._ob_prev` and + :c:member:`~PyObject._ob_next` fields if they are present. This means that the only correct way to get an initializer for the :c:member:`~PyTypeObject.tp_basicsize` is to use the ``sizeof`` operator on the struct used to declare the instance layout. The basic size does not include the GC header size. @@ -669,15 +647,15 @@ and :c:type:`PyType_Type` effectively act as defaults.) memory buffers owned by the instance (using the freeing function corresponding 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 + (doesn't have the :c:macro:`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 - using :c:func:`PyObject_New` or :c:func:`PyObject_VarNew`, or + using :c:macro:`PyObject_New` or :c:macro:`PyObject_NewVar`, or :c:func:`PyObject_GC_Del` if the instance was allocated using - :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`. + :c:macro:`PyObject_GC_New` or :c:macro:`PyObject_GC_NewVar`. - If the type supports garbage collection (has the :const:`Py_TPFLAGS_HAVE_GC` + If the type supports garbage collection (has the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit set), the destructor should call :c:func:`PyObject_GC_UnTrack` before clearing any member fields. @@ -689,8 +667,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) Py_TYPE(self)->tp_free((PyObject *)self); } - Finally, if the type is heap allocated (:const:`Py_TPFLAGS_HEAPTYPE`), the - deallocator should decrement the reference count for its type object after + Finally, if the type is heap allocated (:c:macro:`Py_TPFLAGS_HEAPTYPE`), the + deallocator should release the owned reference to its type object + (via :c:func:`Py_DECREF`) after calling the type deallocator. In order to avoid dangling pointers, the recommended way to achieve this is: @@ -716,12 +695,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) a more efficient alternative of the simpler :c:member:`~PyTypeObject.tp_call`. - This field is only used if the flag :const:`Py_TPFLAGS_HAVE_VECTORCALL` + This field is only used if the flag :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` is set. If so, this must be a positive integer containing the offset in the instance of a :c:type:`vectorcallfunc` pointer. The *vectorcallfunc* pointer may be ``NULL``, in which case the instance behaves - as if :const:`Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance + as if :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance falls back to :c:member:`~PyTypeObject.tp_call`. Any class that sets ``Py_TPFLAGS_HAVE_VECTORCALL`` must also set @@ -740,15 +719,15 @@ and :c:type:`PyType_Type` effectively act as defaults.) Before version 3.12, it was not recommended for :ref:`mutable heap types ` to implement the vectorcall protocol. - When a user sets :attr:`~type.__call__` in Python code, only *tp_call* is + When a user sets :attr:`~object.__call__` in Python code, only *tp_call* is updated, likely making it inconsistent with the vectorcall function. Since 3.12, setting ``__call__`` will disable vectorcall optimization - by clearing the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + by clearing the :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag. **Inheritance:** This field is always inherited. - However, the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not + However, the :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not always inherited. If it's not set, then the subclass won't use :ref:`vectorcall `, except when :c:func:`PyVectorcall_Call` is explicitly called. @@ -764,7 +743,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_getattr`, :attr:`tp_getattro` + Group: :c:member:`~PyTypeObject.tp_getattr`, :c:member:`~PyTypeObject.tp_getattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when @@ -781,7 +760,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_setattr`, :attr:`tp_setattro` + Group: :c:member:`~PyTypeObject.tp_setattr`, :c:member:`~PyTypeObject.tp_setattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when @@ -883,7 +862,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) normal return value; when an error occurs during the computation of the hash value, the function should set an exception and return ``-1``. - When this field is not set (*and* :attr:`tp_richcompare` is not set), + When this field is not set (*and* :c:member:`~PyTypeObject.tp_richcompare` is not set), an attempt to take the hash of the object raises :exc:`TypeError`. This is the same as setting it to :c:func:`PyObject_HashNotImplemented`. @@ -897,7 +876,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_hash`, :attr:`tp_richcompare` + Group: :c:member:`~PyTypeObject.tp_hash`, :c:member:`~PyTypeObject.tp_richcompare` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_richcompare`: a subtype inherits both of @@ -956,7 +935,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_getattr`, :attr:`tp_getattro` + Group: :c:member:`~PyTypeObject.tp_getattr`, :c:member:`~PyTypeObject.tp_getattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when @@ -964,7 +943,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** - :c:type:`PyBaseObject_Type` uses :c:func:`PyObject_GenericGetAttr`. + :c:data:`PyBaseObject_Type` uses :c:func:`PyObject_GenericGetAttr`. .. c:member:: setattrofunc PyTypeObject.tp_setattro @@ -982,7 +961,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_setattr`, :attr:`tp_setattro` + Group: :c:member:`~PyTypeObject.tp_setattr`, :c:member:`~PyTypeObject.tp_setattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when @@ -990,7 +969,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** - :c:type:`PyBaseObject_Type` uses :c:func:`PyObject_GenericSetAttr`. + :c:data:`PyBaseObject_Type` uses :c:func:`PyObject_GenericSetAttr`. .. c:member:: PyBufferProcs* PyTypeObject.tp_as_buffer @@ -1022,30 +1001,32 @@ and :c:type:`PyType_Type` effectively act as defaults.) this flag bit. The flag bits that pertain to extension structures are strictly inherited if the extension structure is inherited, i.e. the base type's value of the flag bit is copied into the subtype together with a pointer to the extension - structure. The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with + structure. The :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields, i.e. if the - :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have ``NULL`` values. .. XXX are most flag bits *really* inherited individually? **Default:** - :c:type:`PyBaseObject_Type` uses + :c:data:`PyBaseObject_Type` uses ``Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE``. **Bit Masks:** + .. c:namespace:: NULL + The following bit masks are currently defined; these can be ORed together using the ``|`` operator to form the value of the :c:member:`~PyTypeObject.tp_flags` field. The macro :c:func:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and checks whether ``tp->tp_flags & f`` is non-zero. - .. data:: Py_TPFLAGS_HEAPTYPE + .. c:macro:: Py_TPFLAGS_HEAPTYPE 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 + case, the :c:member:`~PyObject.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 subtypes; only the type referenced by the instance's ob_type gets INCREF'ed or @@ -1056,7 +1037,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_BASETYPE + .. c:macro:: Py_TPFLAGS_BASETYPE This bit is set when the type can be used as the base type of another type. If this bit is clear, the type cannot be subtyped (similar to a "final" class in @@ -1067,7 +1048,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_READY + .. c:macro:: Py_TPFLAGS_READY This bit is set when the type object has been fully initialized by :c:func:`PyType_Ready`. @@ -1077,7 +1058,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_READYING + .. c:macro:: Py_TPFLAGS_READYING This bit is set while :c:func:`PyType_Ready` is in the process of initializing the type object. @@ -1087,10 +1068,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_HAVE_GC + .. c:macro:: Py_TPFLAGS_HAVE_GC This bit is set when the object supports garbage collection. If this bit - is set, instances must be created using :c:func:`PyObject_GC_New` and + is set, instances must be created using :c:macro:`PyObject_GC_New` and destroyed using :c:func:`PyObject_GC_Del`. More information in section :ref:`supporting-cycle-detection`. This bit also implies that the GC-related fields :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` are present in @@ -1098,28 +1079,28 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + Group: :c:macro:`Py_TPFLAGS_HAVE_GC`, :c:member:`~PyTypeObject.tp_traverse`, :c:member:`~PyTypeObject.tp_clear` - The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited - together with the :attr:`tp_traverse` and :attr:`tp_clear` - fields, i.e. if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is - clear in the subtype and the :attr:`tp_traverse` and - :attr:`tp_clear` fields in the subtype exist and have ``NULL`` + The :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is inherited + together with the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` + fields, i.e. if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is + clear in the subtype and the :c:member:`~PyTypeObject.tp_traverse` and + :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have ``NULL`` values. - .. data:: Py_TPFLAGS_DEFAULT + .. c:macro:: Py_TPFLAGS_DEFAULT This is a bitmask of all the bits that pertain to the existence of certain fields in the type object and its extension structures. Currently, it includes - the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`. + the following bits: :c:macro:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`. **Inheritance:** ??? - .. data:: Py_TPFLAGS_METHOD_DESCRIPTOR + .. c:macro:: Py_TPFLAGS_METHOD_DESCRIPTOR This bit indicates that objects behave like unbound methods. @@ -1140,15 +1121,18 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** This flag is never inherited by types without the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is + :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is inherited whenever :c:member:`~PyTypeObject.tp_descr_get` is inherited. - .. data:: Py_TPFLAGS_MANAGED_DICT + .. c:macro:: Py_TPFLAGS_MANAGED_DICT This bit indicates that instances of the class have a ``__dict__`` attribute, and that the space for the dictionary is managed by the VM. - If this flag is set, :const:`Py_TPFLAGS_HAVE_GC` should also be set. + If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` should also be set. + + The type traverse function must call :c:func:`PyObject_VisitManagedDict` + and its clear function must call :c:func:`PyObject_ClearManagedDict`. .. versionadded:: 3.12 @@ -1158,7 +1142,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:member:`~PyTypeObject.tp_dictoffset` field is set in a superclass. - .. data:: Py_TPFLAGS_MANAGED_WEAKREF + .. c:macro:: Py_TPFLAGS_MANAGED_WEAKREF This bit indicates that instances of the class should be weakly referenceable. @@ -1171,14 +1155,14 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:member:`~PyTypeObject.tp_weaklistoffset` field is set in a superclass. - .. data:: Py_TPFLAGS_ITEMS_AT_END + .. c:macro:: Py_TPFLAGS_ITEMS_AT_END Only usable with variable-size types, i.e. ones with non-zero - :c:member:`~PyObject.tp_itemsize`. + :c:member:`~PyTypeObject.tp_itemsize`. Indicates that the variable-sized portion of an instance of this type is at the end of the instance's memory area, at an offset of - :c:expr:`Py_TYPE(obj)->tp_basicsize` (which may be different in each + ``Py_TYPE(obj)->tp_basicsize`` (which may be different in each subclass). When setting this flag, be sure that all superclasses either @@ -1194,14 +1178,14 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. XXX Document more flags here? - .. data:: Py_TPFLAGS_LONG_SUBCLASS - .. data:: Py_TPFLAGS_LIST_SUBCLASS - .. data:: Py_TPFLAGS_TUPLE_SUBCLASS - .. data:: Py_TPFLAGS_BYTES_SUBCLASS - .. data:: Py_TPFLAGS_UNICODE_SUBCLASS - .. data:: Py_TPFLAGS_DICT_SUBCLASS - .. data:: Py_TPFLAGS_BASE_EXC_SUBCLASS - .. data:: Py_TPFLAGS_TYPE_SUBCLASS + .. c:macro:: Py_TPFLAGS_LONG_SUBCLASS + .. c:macro:: Py_TPFLAGS_LIST_SUBCLASS + .. c:macro:: Py_TPFLAGS_TUPLE_SUBCLASS + .. c:macro:: Py_TPFLAGS_BYTES_SUBCLASS + .. c:macro:: Py_TPFLAGS_UNICODE_SUBCLASS + .. c:macro:: Py_TPFLAGS_DICT_SUBCLASS + .. c:macro:: Py_TPFLAGS_BASE_EXC_SUBCLASS + .. c:macro:: Py_TPFLAGS_TYPE_SUBCLASS These flags are used by functions such as :c:func:`PyLong_Check` to quickly determine if a type is a subclass @@ -1212,7 +1196,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) will behave differently depending on what kind of check is used. - .. data:: Py_TPFLAGS_HAVE_FINALIZE + .. c:macro:: Py_TPFLAGS_HAVE_FINALIZE This bit is set when the :c:member:`~PyTypeObject.tp_finalize` slot is present in the type structure. @@ -1225,7 +1209,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) type structure. - .. data:: Py_TPFLAGS_HAVE_VECTORCALL + .. c:macro:: Py_TPFLAGS_HAVE_VECTORCALL This bit is set when the class implements the :ref:`vectorcall protocol `. @@ -1245,7 +1229,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) This flag can now be inherited by mutable classes. - .. data:: Py_TPFLAGS_IMMUTABLETYPE + .. c:macro:: Py_TPFLAGS_IMMUTABLETYPE This bit is set for type objects that are immutable: type attributes cannot be set nor deleted. @@ -1258,7 +1242,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.10 - .. data:: Py_TPFLAGS_DISALLOW_INSTANTIATION + .. c:macro:: Py_TPFLAGS_DISALLOW_INSTANTIATION Disallow creating instances of the type: set :c:member:`~PyTypeObject.tp_new` to NULL and don't create the ``__new__`` @@ -1289,7 +1273,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.10 - .. data:: Py_TPFLAGS_MAPPING + .. c:macro:: Py_TPFLAGS_MAPPING This bit indicates that instances of the class may match mapping patterns when used as the subject of a :keyword:`match` block. It is automatically @@ -1298,20 +1282,20 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. note:: - :const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are + :c:macro:`Py_TPFLAGS_MAPPING` and :c:macro:`Py_TPFLAGS_SEQUENCE` are mutually exclusive; it is an error to enable both flags simultaneously. **Inheritance:** This flag is inherited by types that do not already set - :const:`Py_TPFLAGS_SEQUENCE`. + :c:macro:`Py_TPFLAGS_SEQUENCE`. .. seealso:: :pep:`634` -- Structural Pattern Matching: Specification .. versionadded:: 3.10 - .. data:: Py_TPFLAGS_SEQUENCE + .. c:macro:: Py_TPFLAGS_SEQUENCE This bit indicates that instances of the class may match sequence patterns when used as the subject of a :keyword:`match` block. It is automatically @@ -1320,20 +1304,20 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. note:: - :const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are + :c:macro:`Py_TPFLAGS_MAPPING` and :c:macro:`Py_TPFLAGS_SEQUENCE` are mutually exclusive; it is an error to enable both flags simultaneously. **Inheritance:** This flag is inherited by types that do not already set - :const:`Py_TPFLAGS_MAPPING`. + :c:macro:`Py_TPFLAGS_MAPPING`. .. seealso:: :pep:`634` -- Structural Pattern Matching: Specification .. versionadded:: 3.10 - .. data:: Py_TPFLAGS_VALID_VERSION_TAG + .. c:macro:: Py_TPFLAGS_VALID_VERSION_TAG Internal. Do not set or unset this flag. To indicate that a class has changed call :c:func:`PyType_Modified` @@ -1357,7 +1341,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: traverseproc PyTypeObject.tp_traverse An optional pointer to a traversal function for the garbage collector. This is - only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: + only used if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: int tp_traverse(PyObject *self, visitproc visit, void *arg); @@ -1367,8 +1351,8 @@ and :c:type:`PyType_Type` effectively act as defaults.) The :c:member:`~PyTypeObject.tp_traverse` pointer is used by the garbage collector to detect reference cycles. A typical implementation of a :c:member:`~PyTypeObject.tp_traverse` function simply calls :c:func:`Py_VISIT` on each of the instance's members that are Python - objects that the instance owns. For example, this is function :c:func:`local_traverse` from the - :mod:`_thread` extension module:: + objects that the instance owns. For example, this is function :c:func:`!local_traverse` from the + :mod:`!_thread` extension module:: static int local_traverse(localobject *self, visitproc visit, void *arg) @@ -1387,6 +1371,23 @@ and :c:type:`PyType_Type` effectively act as defaults.) debugging aid you may want to visit it anyway just so the :mod:`gc` module's :func:`~gc.get_referents` function will include it. + Heap types (:c:macro:`Py_TPFLAGS_HEAPTYPE`) must visit their type with:: + + Py_VISIT(Py_TYPE(self)); + + It is only needed since Python 3.9. To support Python 3.8 and older, this + line must be conditionnal:: + + #if PY_VERSION_HEX >= 0x03090000 + Py_VISIT(Py_TYPE(self)); + #endif + + If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` bit is set in the + :c:member:`~PyTypeObject.tp_flags` field, the traverse function must call + :c:func:`PyObject_VisitManagedDict` like this:: + + PyObject_VisitManagedDict((PyObject*)self, visit, arg); + .. warning:: When implementing :c:member:`~PyTypeObject.tp_traverse`, only the members that the instance *owns* (by having :term:`strong references @@ -1400,7 +1401,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) are allowed to be removed even if the instance is still alive). Note that :c:func:`Py_VISIT` requires the *visit* and *arg* parameters to - :c:func:`local_traverse` to have these specific names; don't name them just + :c:func:`!local_traverse` to have these specific names; don't name them just anything. Instances of :ref:`heap-allocated types ` hold a reference to @@ -1419,10 +1420,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + Group: :c:macro:`Py_TPFLAGS_HAVE_GC`, :c:member:`~PyTypeObject.tp_traverse`, :c:member:`~PyTypeObject.tp_clear` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_clear` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and :c:member:`~PyTypeObject.tp_clear` are all inherited from the base type if they are all zero in the subtype. @@ -1430,7 +1431,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: inquiry PyTypeObject.tp_clear An optional pointer to a clear function for the garbage collector. This is only - used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: + used if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: int tp_clear(PyObject *); @@ -1459,9 +1460,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) } The :c:func:`Py_CLEAR` macro should be used, because clearing references is - delicate: the reference to the contained object must not be decremented until + delicate: the reference to the contained object must not be released + (via :c:func:`Py_DECREF`) until after the pointer to the contained object is set to ``NULL``. This is because - decrementing the reference count may cause the contained object to become trash, + releasing the reference may cause the contained object to become trash, triggering a chain of reclamation activity that may include invoking arbitrary Python code (due to finalizers, or weakref callbacks, associated with the contained object). If it's possible for such code to reference *self* again, @@ -1469,6 +1471,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) so that *self* knows the contained object can no longer be used. The :c:func:`Py_CLEAR` macro performs the operations in a safe order. + If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` bit is set in the + :c:member:`~PyTypeObject.tp_flags` field, the traverse function must call + :c:func:`PyObject_ClearManagedDict` like this:: + + PyObject_ClearManagedDict((PyObject*)self); + Note that :c:member:`~PyTypeObject.tp_clear` is not *always* called before an instance is deallocated. For example, when reference counting is enough to determine that an object is no longer used, the cyclic garbage @@ -1486,10 +1494,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + Group: :c:macro:`Py_TPFLAGS_HAVE_GC`, :c:member:`~PyTypeObject.tp_traverse`, :c:member:`~PyTypeObject.tp_clear` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_traverse` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and :c:member:`~PyTypeObject.tp_clear` are all inherited from the base type if they are all zero in the subtype. @@ -1511,21 +1519,23 @@ and :c:type:`PyType_Type` effectively act as defaults.) The following constants are defined to be used as the third argument for :c:member:`~PyTypeObject.tp_richcompare` and for :c:func:`PyObject_RichCompare`: - +----------------+------------+ - | Constant | Comparison | - +================+============+ - | :const:`Py_LT` | ``<`` | - +----------------+------------+ - | :const:`Py_LE` | ``<=`` | - +----------------+------------+ - | :const:`Py_EQ` | ``==`` | - +----------------+------------+ - | :const:`Py_NE` | ``!=`` | - +----------------+------------+ - | :const:`Py_GT` | ``>`` | - +----------------+------------+ - | :const:`Py_GE` | ``>=`` | - +----------------+------------+ + .. c:namespace:: NULL + + +--------------------+------------+ + | Constant | Comparison | + +====================+============+ + | .. c:macro:: Py_LT | ``<`` | + +--------------------+------------+ + | .. c:macro:: Py_LE | ``<=`` | + +--------------------+------------+ + | .. c:macro:: Py_EQ | ``==`` | + +--------------------+------------+ + | .. c:macro:: Py_NE | ``!=`` | + +--------------------+------------+ + | .. c:macro:: Py_GT | ``>`` | + +--------------------+------------+ + | .. c:macro:: Py_GE | ``>=`` | + +--------------------+------------+ The following macro is defined to ease writing rich comparison functions: @@ -1537,7 +1547,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) they may be C ints or floats). The third argument specifies the requested operation, as for :c:func:`PyObject_RichCompare`. - The return value's reference count is properly incremented. + The returned value is a new :term:`strong reference`. On error, sets an exception and returns ``NULL`` from the function. @@ -1545,7 +1555,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_hash`, :attr:`tp_richcompare` + Group: :c:member:`~PyTypeObject.tp_hash`, :c:member:`~PyTypeObject.tp_richcompare` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_hash`: a subtype inherits :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` when @@ -1554,16 +1564,16 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** - :c:type:`PyBaseObject_Type` provides a :attr:`tp_richcompare` + :c:data:`PyBaseObject_Type` provides a :c:member:`~PyTypeObject.tp_richcompare` implementation, which may be inherited. However, if only - :attr:`tp_hash` is defined, not even the inherited function is used + :c:member:`~PyTypeObject.tp_hash` is defined, not even the inherited function is used and instances of the type will not be able to participate in any comparisons. .. c:member:: Py_ssize_t PyTypeObject.tp_weaklistoffset - While this field is still supported, :const:`Py_TPFLAGS_MANAGED_WEAKREF` + While this field is still supported, :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` should be used instead, if at all possible. If the instances of this type are weakly referenceable, this field is greater @@ -1576,7 +1586,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for weak references to the type object itself. - It is an error to set both the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + It is an error to set both the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit and :c:member:`~PyTypeObject.tp_weaklist`. **Inheritance:** @@ -1588,7 +1598,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** - If the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit is set in the + If the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit is set in the :c:member:`~PyTypeObject.tp_dict` field, then :c:member:`~PyTypeObject.tp_weaklistoffset` will be set to a negative value, to indicate that it is unsafe to use this field. @@ -1691,7 +1701,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) to a pointer, are valid C99 address constants. However, the unary '&' operator applied to a non-static variable - like :c:func:`PyBaseObject_Type` is not required to produce an address + like :c:data:`PyBaseObject_Type` is not required to produce an address constant. Compilers may support this (gcc does), MSVC does not. Both compilers are strictly standard conforming in this particular behavior. @@ -1717,12 +1727,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) called; it may also be initialized to a dictionary containing initial attributes for the type. Once :c:func:`PyType_Ready` has initialized the type, extra attributes for the type may be added to this dictionary only if they don't - correspond to overloaded operations (like :meth:`__add__`). Once + correspond to overloaded operations (like :meth:`~object.__add__`). Once initialization for the type has finished, this field should be treated as read-only. Some types may not store their dictionary in this slot. - Use :c:func:`PyType_GetDict` to retreive the dictionary for an arbitrary + Use :c:func:`PyType_GetDict` to retrieve the dictionary for an arbitrary type. .. versionchanged:: 3.12 @@ -1782,7 +1792,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: Py_ssize_t PyTypeObject.tp_dictoffset - While this field is still supported, :const:`Py_TPFLAGS_MANAGED_DICT` should be + While this field is still supported, :c:macro:`Py_TPFLAGS_MANAGED_DICT` should be used instead, if at all possible. If the instances of this type have a dictionary containing instance variables, @@ -1801,7 +1811,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr` when accessing an attribute on the object. - It is an error to set both the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + It is an error to set both the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit and :c:member:`~PyTypeObject.tp_dictoffset`. **Inheritance:** @@ -1809,15 +1819,15 @@ and :c:type:`PyType_Type` effectively act as defaults.) This field is inherited by subtypes. A subtype should not override this offset; doing so could be unsafe, if C code tries to access the dictionary at the previous offset. - To properly support inheritance, use :const:`Py_TPFLAGS_MANAGED_DICT`. + To properly support inheritance, use :c:macro:`Py_TPFLAGS_MANAGED_DICT`. **Default:** This slot has no default. For :ref:`static types `, if the - field is ``NULL`` then no :attr:`__dict__` gets created for instances. + field is ``NULL`` then no :attr:`~object.__dict__` gets created for instances. - If the :const:`Py_TPFLAGS_MANAGED_DICT` bit is set in the - :c:member:`~PyTypeObject.tp_dict` field, then + If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` bit is set in the + :c:member:`~PyTypeObject.tp_flags` field, then :c:member:`~PyTypeObject.tp_dictoffset` will be set to ``-1``, to indicate that it is unsafe to use this field. @@ -1826,10 +1836,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) An optional pointer to an instance initialization function. - This function corresponds to the :meth:`__init__` method of classes. Like - :meth:`__init__`, it is possible to create an instance without calling - :meth:`__init__`, and it is possible to reinitialize an instance by calling its - :meth:`__init__` method again. + This function corresponds to the :meth:`~object.__init__` method of classes. Like + :meth:`!__init__`, it is possible to create an instance without calling + :meth:`!__init__`, and it is possible to reinitialize an instance by calling its + :meth:`!__init__` method again. The function signature is:: @@ -1837,7 +1847,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) The self argument is the instance to be initialized; the *args* and *kwds* arguments represent positional and keyword arguments of the call to - :meth:`__init__`. + :meth:`~object.__init__`. The :c:member:`~PyTypeObject.tp_init` function, if not ``NULL``, is called when an instance is created normally by calling its type, after the type's :c:member:`~PyTypeObject.tp_new` function @@ -1876,7 +1886,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:func:`PyType_GenericAlloc`, to force a standard heap allocation strategy. - For static subtypes, :c:type:`PyBaseObject_Type` uses + For static subtypes, :c:data:`PyBaseObject_Type` uses :c:func:`PyType_GenericAlloc`. That is the recommended value for all statically defined types. @@ -1903,7 +1913,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) in :c:member:`~PyTypeObject.tp_new`, while for mutable types, most initialization should be deferred to :c:member:`~PyTypeObject.tp_init`. - Set the :const:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag to disallow creating + Set the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag to disallow creating instances of the type in Python. **Inheritance:** @@ -1937,9 +1947,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) In dynamic subtypes, this field is set to a deallocator suitable to match :c:func:`PyType_GenericAlloc` and the value of the - :const:`Py_TPFLAGS_HAVE_GC` flag bit. + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit. - For static subtypes, :c:type:`PyBaseObject_Type` uses PyObject_Del. + For static subtypes, :c:data:`PyBaseObject_Type` uses :c:func:`PyObject_Del`. .. c:member:: inquiry PyTypeObject.tp_is_gc @@ -1948,7 +1958,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) The garbage collector needs to know whether a particular object is collectible or not. Normally, it is sufficient to look at the object's type's - :c:member:`~PyTypeObject.tp_flags` field, and check the :const:`Py_TPFLAGS_HAVE_GC` flag bit. But + :c:member:`~PyTypeObject.tp_flags` field, and check the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit. But some types have a mixture of statically and dynamically allocated instances, and the statically allocated instances are not collectible. Such types should define this function; it should return ``1`` for a collectible instance, and @@ -1967,7 +1977,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** This slot has no default. If this field is ``NULL``, - :const:`Py_TPFLAGS_HAVE_GC` is used as the functional equivalent. + :c:macro:`Py_TPFLAGS_HAVE_GC` is used as the functional equivalent. .. c:member:: PyObject* PyTypeObject.tp_bases @@ -2114,7 +2124,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionchanged:: 3.8 Before version 3.8 it was necessary to set the - :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be + :c:macro:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be used. This is no longer required. .. seealso:: "Safe object finalization" (:pep:`442`) @@ -2126,7 +2136,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) In other words, it is used to implement :ref:`vectorcall ` for ``type.__call__``. If ``tp_vectorcall`` is ``NULL``, the default call implementation - using :attr:`__new__` and :attr:`__init__` is used. + using :meth:`~object.__new__` and :meth:`~object.__init__` is used. **Inheritance:** @@ -2135,7 +2145,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9) -.. c:member:: char PyTypeObject.tp_watched +.. c:member:: unsigned char PyTypeObject.tp_watched Internal. Do not use. @@ -2173,7 +2183,7 @@ Heap Types An alternative to :ref:`static types ` is *heap-allocated types*, or *heap types* for short, which correspond closely to classes created by -Python's ``class`` statement. Heap types have the :const:`Py_TPFLAGS_HEAPTYPE` +Python's ``class`` statement. Heap types have the :c:macro:`Py_TPFLAGS_HEAPTYPE` flag set. This is done by filling a :c:type:`PyType_Spec` structure and calling @@ -2253,8 +2263,8 @@ Number Object Structures .. note:: - The :c:data:`nb_reserved` field should always be ``NULL``. It - was previously called :c:data:`nb_long`, and was renamed in + The :c:member:`~PyNumberMethods.nb_reserved` field should always be ``NULL``. It + was previously called :c:member:`!nb_long`, and was renamed in Python 3.0.1. .. c:member:: binaryfunc PyNumberMethods.nb_add @@ -2325,8 +2335,8 @@ Mapping Object Structures .. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript This function is used by :c:func:`PyObject_SetItem`, - :c:func:`PyObject_DelItem`, :c:func:`PyObject_SetSlice` and - :c:func:`PyObject_DelSlice`. It has the same signature as + :c:func:`PyObject_DelItem`, :c:func:`PySequence_SetSlice` and + :c:func:`PySequence_DelSlice`. It has the same signature as :c:func:`!PyObject_SetItem`, but *v* can also be set to ``NULL`` to delete an item. If this slot is ``NULL``, the object does not support item assignment and deletion. @@ -2372,9 +2382,9 @@ Sequence Object Structures This slot must be filled for the :c:func:`PySequence_Check` function to return ``1``, it can be ``NULL`` otherwise. - Negative indexes are handled as follows: if the :attr:`sq_length` slot is + Negative indexes are handled as follows: if the :c:member:`~PySequenceMethods.sq_length` slot is filled, it is called and the sequence length is used to compute a positive - index which is passed to :attr:`sq_item`. If :attr:`sq_length` is ``NULL``, + index which is passed to :c:member:`~PySequenceMethods.sq_item`. If :c:member:`!sq_length` is ``NULL``, the index is passed as is to the function. .. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item @@ -2437,7 +2447,7 @@ Buffer Object Structures Except for point (3), an implementation of this function MUST take these steps: - (1) Check if the request can be met. If not, raise :c:data:`PyExc_BufferError`, + (1) Check if the request can be met. If not, raise :exc:`BufferError`, set :c:expr:`view->obj` to ``NULL`` and return ``-1``. (2) Fill in the requested fields. @@ -2548,7 +2558,7 @@ Async Object Structures PyObject *am_aiter(PyObject *self); Must return an :term:`asynchronous iterator` object. - See :meth:`__anext__` for details. + See :meth:`~object.__anext__` for details. This slot may be set to ``NULL`` if an object does not implement asynchronous iteration protocol. @@ -2559,7 +2569,8 @@ Async Object Structures PyObject *am_anext(PyObject *self); - Must return an :term:`awaitable` object. See :meth:`__anext__` for details. + Must return an :term:`awaitable` object. + See :meth:`~object.__anext__` for details. This slot may be set to ``NULL``. .. c:member:: sendfunc PyAsyncMethods.am_send @@ -2584,8 +2595,8 @@ Slot Type typedefs The purpose of this function is to separate memory allocation from memory initialization. It should return a pointer to a block of memory of adequate length for the instance, suitably aligned, and initialized to zeros, but with - :attr:`ob_refcnt` set to ``1`` and :attr:`ob_type` set to the type argument. If - the type's :c:member:`~PyTypeObject.tp_itemsize` is non-zero, the object's :attr:`ob_size` field + :c:member:`~PyObject.ob_refcnt` set to ``1`` and :c:member:`~PyObject.ob_type` set to the type argument. If + the type's :c:member:`~PyTypeObject.tp_itemsize` is non-zero, the object's :c:member:`~PyVarObject.ob_size` field should be initialized to *nitems* and the length of the allocated memory block should be ``tp_basicsize + nitems*tp_itemsize``, rounded up to a multiple of ``sizeof(void*)``; otherwise, *nitems* is not used and the length of the block @@ -2781,7 +2792,7 @@ A type that supports weakrefs, instance dicts, and hashing:: A str subclass that cannot be subclassed and cannot be called to create instances (e.g. uses a separate factory func) using -:c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag:: +:c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag:: typedef struct { PyUnicodeObject raw; diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 64dcea785d0c68..5ab9f1cab23ef8 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -44,7 +44,7 @@ Python: .. c:type:: Py_UNICODE - This is a typedef of :c:expr:`wchar_t`, which is a 16-bit type or 32-bit type + This is a typedef of :c:type:`wchar_t`, which is a 16-bit type or 32-bit type depending on the platform. .. versionchanged:: 3.3 @@ -437,11 +437,11 @@ APIs: +----------+-----------------------------------------------------+ | ``ll`` | :c:expr:`long long` or :c:expr:`unsigned long long` | +----------+-----------------------------------------------------+ - | ``j`` | :c:expr:`intmax_t` or :c:expr:`uintmax_t` | + | ``j`` | :c:type:`intmax_t` or :c:type:`uintmax_t` | +----------+-----------------------------------------------------+ - | ``z`` | :c:expr:`size_t` or :c:expr:`ssize_t` | + | ``z`` | :c:type:`size_t` or :c:type:`ssize_t` | +----------+-----------------------------------------------------+ - | ``t`` | :c:expr:`ptrdiff_t` | + | ``t`` | :c:type:`ptrdiff_t` | +----------+-----------------------------------------------------+ The length modifier ``l`` for following conversions ``s`` or ``V`` specify @@ -520,7 +520,7 @@ APIs: .. note:: The width formatter unit is number of characters rather than bytes. - The precision formatter unit is number of bytes or :c:expr:`wchar_t` + The precision formatter unit is number of bytes or :c:type:`wchar_t` items (if the length modifier ``l`` is used) for ``"%s"`` and ``"%V"`` (if the ``PyObject*`` argument is ``NULL``), and a number of characters for ``"%A"``, ``"%U"``, ``"%S"``, ``"%R"`` and ``"%V"`` @@ -564,7 +564,7 @@ APIs: Copy an instance of a Unicode subtype to a new true Unicode object if necessary. If *obj* is already a true Unicode object (not a subtype), - return the reference with incremented refcount. + return a new :term:`strong reference` to the object. Objects other than Unicode or its subtypes will cause a :exc:`TypeError`. @@ -601,7 +601,7 @@ APIs: Py_ssize_t how_many) Copy characters from one Unicode object into another. This function performs - character conversion when necessary and falls back to :c:func:`memcpy` if + character conversion when necessary and falls back to :c:func:`!memcpy` if possible. Returns ``-1`` and sets an exception on error, otherwise returns the number of copied characters. @@ -714,7 +714,7 @@ system. .. c:function:: PyObject* PyUnicode_DecodeLocale(const char *str, const char *errors) Similar to :c:func:`PyUnicode_DecodeLocaleAndSize`, but compute the string - length using :c:func:`strlen`. + length using :c:func:`!strlen`. .. versionadded:: 3.3 @@ -839,11 +839,11 @@ conversion function: wchar_t Support """"""""""""""" -:c:expr:`wchar_t` support for platforms which support it: +:c:type:`wchar_t` support for platforms which support it: .. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) - Create a Unicode object from the :c:expr:`wchar_t` buffer *w* of the given *size*. + Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*. Passing ``-1`` as the *size* indicates that the function must itself compute the length, using wcslen. Return ``NULL`` on failure. @@ -851,9 +851,9 @@ wchar_t Support .. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size) - Copy the Unicode object contents into the :c:expr:`wchar_t` buffer *w*. At most - *size* :c:expr:`wchar_t` characters are copied (excluding a possibly trailing - null termination character). Return the number of :c:expr:`wchar_t` characters + Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most + *size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing + null termination character). Return the number of :c:type:`wchar_t` characters copied or ``-1`` in case of an error. Note that the resulting :c:expr:`wchar_t*` string may or may not be null-terminated. It is the responsibility of the caller to make sure that the :c:expr:`wchar_t*` string is null-terminated in case this is @@ -867,12 +867,12 @@ wchar_t Support Convert the Unicode object to a wide character string. The output string always ends with a null character. If *size* is not ``NULL``, write the number of wide characters (excluding the trailing null termination character) into - *\*size*. Note that the resulting :c:expr:`wchar_t` string might contain + *\*size*. Note that the resulting :c:type:`wchar_t` string might contain null characters, which would cause the string to be truncated when used with most C functions. If *size* is ``NULL`` and the :c:expr:`wchar_t*` string contains null characters a :exc:`ValueError` is raised. - Returns a buffer allocated by :c:func:`PyMem_New` (use + Returns a buffer allocated by :c:macro:`PyMem_New` (use :c:func:`PyMem_Free` to free it) on success. On error, returns ``NULL`` and *\*size* is undefined. Raises a :exc:`MemoryError` if memory allocation is failed. @@ -1205,9 +1205,9 @@ Character Map Codecs This codec is special in that it can be used to implement many different codecs (and this is in fact what was done to obtain most of the standard codecs -included in the :mod:`encodings` package). The codec uses mappings to encode and +included in the :mod:`!encodings` package). The codec uses mappings to encode and decode characters. The mapping objects provided must support the -:meth:`__getitem__` mapping interface; dictionaries and sequences work well. +:meth:`~object.__getitem__` mapping interface; dictionaries and sequences work well. These are the mapping codec APIs: @@ -1250,7 +1250,7 @@ The following codec API is special in that maps Unicode to Unicode. The mapping table must map Unicode ordinal integers to Unicode ordinal integers or ``None`` (causing deletion of the character). - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries + Mapping tables need only provide the :meth:`~object.__getitem__` interface; dictionaries and sequences work well. Unmapped character ordinals (ones which cause a :exc:`LookupError`) are left untouched and are copied as-is. @@ -1292,7 +1292,7 @@ the user settings on the machine running the codec. Encode the Unicode object using the specified code page and return a Python bytes object. Return ``NULL`` if an exception was raised by the codec. Use - :c:data:`CP_ACP` code page to get the MBCS encoder. + :c:macro:`!CP_ACP` code page to get the MBCS encoder. .. versionadded:: 3.3 @@ -1396,6 +1396,28 @@ They all return ``NULL`` or ``-1`` if an exception occurs. :c:func:`PyErr_Occurred` to check for errors. +.. c:function:: int PyUnicode_EqualToUTF8AndSize(PyObject *unicode, const char *string, Py_ssize_t size) + + Compare a Unicode object with a char buffer which is interpreted as + being UTF-8 or ASCII encoded and return true (``1``) if they are equal, + or false (``0``) otherwise. + If the Unicode object contains surrogate characters or + the C string is not valid UTF-8, false (``0``) is returned. + + This function does not raise exceptions. + + .. versionadded:: 3.13 + + +.. c:function:: int PyUnicode_EqualToUTF8(PyObject *unicode, const char *string) + + Similar to :c:func:`PyUnicode_EqualToUTF8AndSize`, but compute *string* + length using :c:func:`!strlen`. + If the Unicode object contains null characters, false (``0``) is returned. + + .. versionadded:: 3.13 + + .. c:function:: int PyUnicode_CompareWithASCIIString(PyObject *uni, const char *string) Compare a Unicode object, *uni*, with *string* and return ``-1``, ``0``, ``1`` for less @@ -1411,11 +1433,11 @@ They all return ``NULL`` or ``-1`` if an exception occurs. Rich compare two Unicode strings and return one of the following: * ``NULL`` in case an exception was raised - * :const:`Py_True` or :const:`Py_False` for successful comparisons - * :const:`Py_NotImplemented` in case the type combination is unknown + * :c:data:`Py_True` or :c:data:`Py_False` for successful comparisons + * :c:data:`Py_NotImplemented` in case the type combination is unknown - Possible values for *op* are :const:`Py_GT`, :const:`Py_GE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_LT`, and :const:`Py_LE`. + Possible values for *op* are :c:macro:`Py_GT`, :c:macro:`Py_GE`, :c:macro:`Py_EQ`, + :c:macro:`Py_NE`, :c:macro:`Py_LT`, and :c:macro:`Py_LE`. .. c:function:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args) @@ -1438,11 +1460,11 @@ They all return ``NULL`` or ``-1`` if an exception occurs. Intern the argument *\*string* in place. The argument must be the address of a pointer variable pointing to a Python Unicode string object. If there is an existing interned string that is the same as *\*string*, it sets *\*string* to - it (decrementing the reference count of the old string object and incrementing - the reference count of the interned string object), otherwise it leaves - *\*string* alone and interns it (incrementing its reference count). - (Clarification: even though there is a lot of talk about reference counts, think - of this function as reference-count-neutral; you own the object after the call + it (releasing the reference to the old string object and creating a new + :term:`strong reference` to the interned string object), otherwise it leaves + *\*string* alone and interns it (creating a new :term:`strong reference`). + (Clarification: even though there is a lot of talk about references, think + of this function as reference-neutral; you own the object after the call if and only if you owned it before the call.) diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 000a2d3d8790bb..324518c035096b 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -12,12 +12,12 @@ file or a buffer, but they will not let you interact in a more detailed way with the interpreter. Several of these functions accept a start symbol from the grammar as a -parameter. The available start symbols are :const:`Py_eval_input`, -:const:`Py_file_input`, and :const:`Py_single_input`. These are described +parameter. The available start symbols are :c:data:`Py_eval_input`, +:c:data:`Py_file_input`, and :c:data:`Py_single_input`. These are described following the functions which accept them as parameters. Note also that several of these functions take :c:expr:`FILE*` parameters. One -particular issue which needs to be handled carefully is that the :c:expr:`FILE` +particular issue which needs to be handled carefully is that the :c:type:`FILE` structure for different C libraries can be different and incompatible. Under Windows (at least), it is possible for dynamically linked extensions to actually use different libraries, so care should be taken that :c:expr:`FILE*` parameters @@ -256,8 +256,8 @@ the same library that the Python runtime is using. Parse and compile the Python source code in *str*, returning the resulting code object. The start token is given by *start*; this can be used to constrain the - code which can be compiled and should be :const:`Py_eval_input`, - :const:`Py_file_input`, or :const:`Py_single_input`. The filename specified by + code which can be compiled and should be :c:data:`Py_eval_input`, + :c:data:`Py_file_input`, or :c:data:`Py_single_input`. The filename specified by *filename* is used to construct the code object and may appear in tracebacks or :exc:`SyntaxError` exception messages. This returns ``NULL`` if the code cannot be parsed or compiled. @@ -353,7 +353,7 @@ the same library that the Python runtime is using. executed, it is passed as ``PyCompilerFlags *flags``. In this case, ``from __future__ import`` can modify *flags*. - Whenever ``PyCompilerFlags *flags`` is ``NULL``, :attr:`cf_flags` is treated as + Whenever ``PyCompilerFlags *flags`` is ``NULL``, :c:member:`~PyCompilerFlags.cf_flags` is treated as equal to ``0``, and any modification due to ``from __future__ import`` is discarded. @@ -367,7 +367,7 @@ the same library that the Python runtime is using. 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*. + ``PyCF_ONLY_AST`` flag is set in :c:member:`~PyCompilerFlags.cf_flags`. .. versionchanged:: 3.8 Added *cf_feature_version* field. diff --git a/Doc/conf.py b/Doc/conf.py index 09e12e245891d2..c92ea60ee07094 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -66,7 +66,7 @@ highlight_language = 'python3' # Minimum version of sphinx required -needs_sphinx = '3.2' +needs_sphinx = '4.2' # Ignore any .rst files in the includes/ directory; # they're embedded in pages but not rendered individually. @@ -77,12 +77,172 @@ exclude_patterns.append(venvdir + '/*') nitpick_ignore = [ + # Standard C functions + ('c:func', 'calloc'), + ('c:func', 'dlopen'), + ('c:func', 'exec'), + ('c:func', 'fcntl'), + ('c:func', 'fork'), + ('c:func', 'free'), + ('c:func', 'gmtime'), + ('c:func', 'localtime'), + ('c:func', 'main'), + ('c:func', 'malloc'), + ('c:func', 'printf'), + ('c:func', 'realloc'), + ('c:func', 'snprintf'), + ('c:func', 'sprintf'), + ('c:func', 'stat'), + ('c:func', 'system'), + ('c:func', 'time'), + ('c:func', 'vsnprintf'), + # Standard C types + ('c:type', 'FILE'), + ('c:type', 'int64_t'), + ('c:type', 'intmax_t'), + ('c:type', 'off_t'), + ('c:type', 'ptrdiff_t'), + ('c:type', 'siginfo_t'), + ('c:type', 'size_t'), + ('c:type', 'ssize_t'), + ('c:type', 'time_t'), + ('c:type', 'uint64_t'), + ('c:type', 'uintmax_t'), + ('c:type', 'uintptr_t'), + ('c:type', 'va_list'), + ('c:type', 'wchar_t'), + ('c:type', '__int64'), + ('c:type', 'unsigned __int64'), + # Standard C structures + ('c:struct', 'in6_addr'), + ('c:struct', 'in_addr'), + ('c:struct', 'stat'), + ('c:struct', 'statvfs'), + # Standard C macros + ('c:macro', 'LLONG_MAX'), + ('c:macro', 'LLONG_MIN'), + ('c:macro', 'LONG_MAX'), + ('c:macro', 'LONG_MIN'), + # Standard C variables + ('c:data', 'errno'), + # Standard environment variables + ('envvar', 'BROWSER'), + ('envvar', 'COLUMNS'), + ('envvar', 'COMSPEC'), + ('envvar', 'DISPLAY'), + ('envvar', 'HOME'), + ('envvar', 'HOMEDRIVE'), + ('envvar', 'HOMEPATH'), + ('envvar', 'IDLESTARTUP'), + ('envvar', 'LANG'), + ('envvar', 'LANGUAGE'), + ('envvar', 'LC_ALL'), + ('envvar', 'LC_CTYPE'), + ('envvar', 'LC_COLLATE'), + ('envvar', 'LC_MESSAGES'), + ('envvar', 'LC_MONETARY'), + ('envvar', 'LC_NUMERIC'), + ('envvar', 'LC_TIME'), + ('envvar', 'LINES'), + ('envvar', 'LOGNAME'), + ('envvar', 'PAGER'), + ('envvar', 'PATH'), + ('envvar', 'PATHEXT'), + ('envvar', 'SOURCE_DATE_EPOCH'), + ('envvar', 'TEMP'), + ('envvar', 'TERM'), + ('envvar', 'TMP'), + ('envvar', 'TMPDIR'), + ('envvar', 'TZ'), + ('envvar', 'USER'), + ('envvar', 'USERNAME'), + ('envvar', 'USERPROFILE'), +] + +# Temporary undocumented names. +# In future this list must be empty. +nitpick_ignore += [ + # C API: Standard Python exception classes + ('c:data', 'PyExc_ArithmeticError'), + ('c:data', 'PyExc_AssertionError'), + ('c:data', 'PyExc_AttributeError'), + ('c:data', 'PyExc_BaseException'), + ('c:data', 'PyExc_BlockingIOError'), + ('c:data', 'PyExc_BrokenPipeError'), + ('c:data', 'PyExc_BufferError'), + ('c:data', 'PyExc_ChildProcessError'), + ('c:data', 'PyExc_ConnectionAbortedError'), + ('c:data', 'PyExc_ConnectionError'), + ('c:data', 'PyExc_ConnectionRefusedError'), + ('c:data', 'PyExc_ConnectionResetError'), + ('c:data', 'PyExc_EOFError'), + ('c:data', 'PyExc_Exception'), + ('c:data', 'PyExc_FileExistsError'), + ('c:data', 'PyExc_FileNotFoundError'), + ('c:data', 'PyExc_FloatingPointError'), + ('c:data', 'PyExc_GeneratorExit'), + ('c:data', 'PyExc_ImportError'), + ('c:data', 'PyExc_IndentationError'), + ('c:data', 'PyExc_IndexError'), + ('c:data', 'PyExc_InterruptedError'), + ('c:data', 'PyExc_IsADirectoryError'), + ('c:data', 'PyExc_KeyboardInterrupt'), + ('c:data', 'PyExc_KeyError'), + ('c:data', 'PyExc_LookupError'), + ('c:data', 'PyExc_MemoryError'), + ('c:data', 'PyExc_ModuleNotFoundError'), + ('c:data', 'PyExc_NameError'), + ('c:data', 'PyExc_NotADirectoryError'), + ('c:data', 'PyExc_NotImplementedError'), + ('c:data', 'PyExc_OSError'), + ('c:data', 'PyExc_OverflowError'), + ('c:data', 'PyExc_PermissionError'), + ('c:data', 'PyExc_ProcessLookupError'), + ('c:data', 'PyExc_RecursionError'), + ('c:data', 'PyExc_ReferenceError'), + ('c:data', 'PyExc_RuntimeError'), + ('c:data', 'PyExc_StopAsyncIteration'), + ('c:data', 'PyExc_StopIteration'), + ('c:data', 'PyExc_SyntaxError'), + ('c:data', 'PyExc_SystemError'), + ('c:data', 'PyExc_SystemExit'), + ('c:data', 'PyExc_TabError'), + ('c:data', 'PyExc_TimeoutError'), + ('c:data', 'PyExc_TypeError'), + ('c:data', 'PyExc_UnboundLocalError'), + ('c:data', 'PyExc_UnicodeDecodeError'), + ('c:data', 'PyExc_UnicodeEncodeError'), + ('c:data', 'PyExc_UnicodeError'), + ('c:data', 'PyExc_UnicodeTranslateError'), + ('c:data', 'PyExc_ValueError'), + ('c:data', 'PyExc_ZeroDivisionError'), + # C API: Standard Python warning classes + ('c:data', 'PyExc_BytesWarning'), + ('c:data', 'PyExc_DeprecationWarning'), + ('c:data', 'PyExc_FutureWarning'), + ('c:data', 'PyExc_ImportWarning'), + ('c:data', 'PyExc_PendingDeprecationWarning'), + ('c:data', 'PyExc_ResourceWarning'), + ('c:data', 'PyExc_RuntimeWarning'), + ('c:data', 'PyExc_SyntaxWarning'), + ('c:data', 'PyExc_UnicodeWarning'), + ('c:data', 'PyExc_UserWarning'), + ('c:data', 'PyExc_Warning'), # Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot # be resolved, as the method is currently undocumented. For context, see # https://github.com/python/cpython/pull/103289. ('py:meth', '_SubParsersAction.add_parser'), ] +# gh-106948: Copy standard C types declared in the "c:type" domain to the +# "c:identifier" domain, since "c:function" markup looks for types in the +# "c:identifier" domain. Use list() to not iterate on items which are being +# added +for role, name in list(nitpick_ignore): + if role == 'c:type': + nitpick_ignore.append(('c:identifier', name)) +del role, name + # Disable Docutils smartquotes for several translations smartquotes_excludes = { 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], 'builders': ['man', 'text'], @@ -194,8 +354,6 @@ latex_documents = [ ('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'), - ('distributing/index', 'distributing.tex', - 'Distributing Python Modules', _stdauthor, 'manual'), ('extending/index', 'extending.tex', 'Extending and Embedding Python', _stdauthor, 'manual'), ('installing/index', 'installing.tex', diff --git a/Doc/constraints.txt b/Doc/constraints.txt index 54888eaab242ee..147de1271eb2b7 100644 --- a/Doc/constraints.txt +++ b/Doc/constraints.txt @@ -10,8 +10,7 @@ colorama<0.5 imagesize<1.5 Jinja2<3.2 packaging<24 -# Pygments==2.15.0 breaks CI -Pygments<2.16,!=2.15.0 +Pygments>=2.16.1,<3 requests<3 snowballstemmer<3 sphinxcontrib-applehelp<1.1 diff --git a/Doc/contents.rst b/Doc/contents.rst index 464f93bdf85f95..24ceacb0076b5e 100644 --- a/Doc/contents.rst +++ b/Doc/contents.rst @@ -11,7 +11,6 @@ library/index.rst extending/index.rst c-api/index.rst - distributing/index.rst installing/index.rst howto/index.rst faq/index.rst @@ -21,10 +20,3 @@ bugs.rst copyright.rst license.rst - -.. to include legacy packaging docs in build - -.. toctree:: - :hidden: - - install/index.rst diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index aa1edf54637058..6ec9c907254b04 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -111,7 +111,9 @@ function,PyDict_Copy,3.2,, function,PyDict_DelItem,3.2,, function,PyDict_DelItemString,3.2,, function,PyDict_GetItem,3.2,, +function,PyDict_GetItemRef,3.13,, function,PyDict_GetItemString,3.2,, +function,PyDict_GetItemStringRef,3.13,, function,PyDict_GetItemWithError,3.2,, function,PyDict_Items,3.2,, function,PyDict_Keys,3.2,, @@ -345,6 +347,7 @@ var,PyList_Type,3.2,, type,PyLongObject,3.2,,opaque var,PyLongRangeIter_Type,3.2,, function,PyLong_AsDouble,3.2,, +function,PyLong_AsInt,3.13,, function,PyLong_AsLong,3.2,, function,PyLong_AsLongAndOverflow,3.2,, function,PyLong_AsLongLong,3.2,, @@ -374,6 +377,8 @@ function,PyMapping_GetOptionalItem,3.13,, function,PyMapping_GetOptionalItemString,3.13,, function,PyMapping_HasKey,3.2,, function,PyMapping_HasKeyString,3.2,, +function,PyMapping_HasKeyStringWithError,3.13,, +function,PyMapping_HasKeyWithError,3.13,, function,PyMapping_Items,3.2,, function,PyMapping_Keys,3.2,, function,PyMapping_Length,3.2,, @@ -520,6 +525,8 @@ function,PyObject_GetOptionalAttrString,3.13,, function,PyObject_GetTypeData,3.12,, function,PyObject_HasAttr,3.2,, function,PyObject_HasAttrString,3.2,, +function,PyObject_HasAttrStringWithError,3.13,, +function,PyObject_HasAttrWithError,3.13,, function,PyObject_Hash,3.2,, function,PyObject_HashNotImplemented,3.2,, function,PyObject_Init,3.2,, @@ -748,6 +755,8 @@ function,PyUnicode_DecodeUnicodeEscape,3.2,, function,PyUnicode_EncodeCodePage,3.7,on Windows, function,PyUnicode_EncodeFSDefault,3.2,, function,PyUnicode_EncodeLocale,3.7,, +function,PyUnicode_EqualToUTF8,3.13,, +function,PyUnicode_EqualToUTF8AndSize,3.13,, function,PyUnicode_FSConverter,3.2,, function,PyUnicode_FSDecoder,3.2,, function,PyUnicode_Find,3.2,, @@ -833,6 +842,7 @@ function,Py_Initialize,3.2,, function,Py_InitializeEx,3.2,, function,Py_Is,3.10,, function,Py_IsFalse,3.10,, +function,Py_IsFinalizing,3.13,, function,Py_IsInitialized,3.2,, function,Py_IsNone,3.10,, function,Py_IsTrue,3.10,, diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst index d237f8f082d87b..2430564b45d6d2 100644 --- a/Doc/distributing/index.rst +++ b/Doc/distributing/index.rst @@ -1,174 +1,19 @@ +:orphan: + +.. This page is retained solely for existing links to /distributing/index.html. + Direct readers to the PPUG instead. + .. _distributing-index: ############################### Distributing Python Modules ############################### -:Email: distutils-sig@python.org - - -As a popular open source development project, Python has an active -supporting community of contributors and users that also make their software -available for other Python developers to use under open source license terms. - -This allows Python users to share and collaborate effectively, benefiting -from the solutions others have already created to common (and sometimes -even rare!) problems, as well as potentially contributing their own -solutions to the common pool. - -This guide covers the distribution part of the process. For a guide to -installing other Python projects, refer to the -:ref:`installation guide `. - .. note:: - For corporate and other institutional users, be aware that many - organisations have their own policies around using and contributing to - open source software. Please take such policies into account when making - use of the distribution and installation tools provided with Python. - - -Key terms -========= - -* the `Python Package Index `__ is a public - repository of open source licensed packages made available for use by - other Python users -* the `Python Packaging Authority - `__ are the group of - developers and documentation authors responsible for the maintenance and - evolution of the standard packaging tools and the associated metadata and - file format standards. They maintain a variety of tools, documentation - and issue trackers on `GitHub `__. -* ``distutils`` is the original build and distribution system first added - to the Python standard library in 1998. While direct use of ``distutils`` - is being phased out, it still laid the foundation for the current packaging - and distribution infrastructure, and it not only remains part of the - standard library, but its name lives on in other ways (such as the name - of the mailing list used to coordinate Python packaging standards - development). -* `setuptools`_ is a (largely) drop-in replacement for ``distutils`` first - published in 2004. Its most notable addition over the unmodified - ``distutils`` tools was the ability to declare dependencies on other - packages. It is currently recommended as a more regularly updated - alternative to ``distutils`` that offers consistent support for more - recent packaging standards across a wide range of Python versions. -* `wheel`_ (in this context) is a project that adds the ``bdist_wheel`` - command to ``distutils``/`setuptools`_. This produces a cross platform - binary packaging format (called "wheels" or "wheel files" and defined in - :pep:`427`) that allows Python libraries, even those including binary - extensions, to be installed on a system without needing to be built - locally. - -.. _setuptools: https://setuptools.readthedocs.io/en/latest/ -.. _wheel: https://wheel.readthedocs.io/ - -Open source licensing and collaboration -======================================= - -In most parts of the world, software is automatically covered by copyright. -This means that other developers require explicit permission to copy, use, -modify and redistribute the software. - -Open source licensing is a way of explicitly granting such permission in a -relatively consistent way, allowing developers to share and collaborate -efficiently by making common solutions to various problems freely available. -This leaves many developers free to spend more time focusing on the problems -that are relatively unique to their specific situation. - -The distribution tools provided with Python are designed to make it -reasonably straightforward for developers to make their own contributions -back to that common pool of software if they choose to do so. - -The same distribution tools can also be used to distribute software within -an organisation, regardless of whether that software is published as open -source software or not. - - -Installing the tools -==================== - -The standard library does not include build tools that support modern -Python packaging standards, as the core development team has found that it -is important to have standard tools that work consistently, even on older -versions of Python. - -The currently recommended build and distribution tools can be installed -by invoking the ``pip`` module at the command line:: - - python -m pip install setuptools wheel twine - -.. note:: - - For POSIX users (including macOS and Linux users), these instructions - assume the use of a :term:`virtual environment`. - - For Windows users, these instructions assume that the option to - adjust the system PATH environment variable was selected when installing - Python. - -The Python Packaging User Guide includes more details on the `currently -recommended tools`_. - -.. _currently recommended tools: https://packaging.python.org/guides/tool-recommendations/#packaging-tool-recommendations - -.. index:: - single: Python Package Index (PyPI) - single: PyPI; (see Python Package Index (PyPI)) - -.. _publishing-python-packages: - -Reading the Python Packaging User Guide -======================================= - -The Python Packaging User Guide covers the various key steps and elements -involved in creating and publishing a project: - -* `Project structure`_ -* `Building and packaging the project`_ -* `Uploading the project to the Python Package Index`_ -* `The .pypirc file`_ - -.. _Project structure: https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects -.. _Building and packaging the project: https://packaging.python.org/tutorials/packaging-projects/#creating-the-package-files -.. _Uploading the project to the Python Package Index: https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives -.. _The .pypirc file: https://packaging.python.org/specifications/pypirc/ - - -How do I...? -============ - -These are quick answers or links for some common tasks. - -... choose a name for my project? ---------------------------------- - -This isn't an easy topic, but here are a few tips: - -* check the Python Package Index to see if the name is already in use -* 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, - as they can make it difficult for users to find your software when - searching for it - - -... create and distribute binary extensions? --------------------------------------------- - -This is actually quite a complex topic, with a variety of alternatives -available depending on exactly what you're aiming to achieve. See the -Python Packaging User Guide for more information and recommendations. - -.. seealso:: - - `Python Packaging User Guide: Binary Extensions - `__ - -.. other topics: + Information and guidance on distributing Python modules and packages + has been moved to the `Python Packaging User Guide`_, + and the tutorial on `packaging Python projects`_. - Once the Development & Deployment part of PPUG is fleshed out, some of - those sections should be linked from new questions here (most notably, - we should have a question about avoiding depending on PyPI that links to - https://packaging.python.org/en/latest/mirrors/) + .. _Python Packaging User Guide: https://packaging.python.org/ + .. _packaging Python projects: https://packaging.python.org/en/latest/tutorials/packaging-projects/ diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst index 880bb33ee56718..ddde567f6f3efa 100644 --- a/Doc/extending/building.rst +++ b/Doc/extending/building.rst @@ -45,6 +45,7 @@ See the *"Multiple modules in one library"* section in :pep:`489` for details. .. highlight:: c +.. _install-index: .. _setuptools-index: Building C and C++ Extensions with setuptools diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst index bd1abe36cbb80e..20397dc5add5db 100644 --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -269,7 +269,7 @@ following two statements before the call to :c:func:`Py_Initialize`:: PyImport_AppendInittab("emb", &PyInit_emb); These two lines initialize the ``numargs`` variable, and make the -:func:`emb.numargs` function accessible to the embedded Python interpreter. +:func:`!emb.numargs` function accessible to the embedded Python interpreter. With these extensions, the Python script can do things like .. code-block:: python diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index 7d08bb9f6b8dd8..1ee7f28b2ba220 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -197,7 +197,7 @@ The choice of which exception to raise is entirely yours. There are predeclared C objects corresponding to all built-in Python exceptions, such as :c:data:`PyExc_ZeroDivisionError`, which you can use directly. Of course, you should choose exceptions wisely --- don't use :c:data:`PyExc_TypeError` to mean -that a file couldn't be opened (that should probably be :c:data:`PyExc_IOError`). +that a file couldn't be opened (that should probably be :c:data:`PyExc_OSError`). If something's wrong with the argument list, the :c:func:`PyArg_ParseTuple` function usually raises :c:data:`PyExc_TypeError`. If you have an argument whose value must be in a particular range or must satisfy other conditions, @@ -208,7 +208,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`) +and initialize it in your module's initialization function (:c:func:`!PyInit_spam`) with an exception object:: PyMODINIT_FUNC @@ -221,9 +221,7 @@ with an exception object:: return NULL; SpamError = PyErr_NewException("spam.error", NULL, NULL); - Py_XINCREF(SpamError); - if (PyModule_AddObject(m, "error", SpamError) < 0) { - Py_XDECREF(SpamError); + if (PyModule_AddObjectRef(m, "error", SpamError) < 0) { Py_CLEAR(SpamError); Py_DECREF(m); return NULL; @@ -232,22 +230,22 @@ with an exception object:: return m; } -Note that the Python name for the exception object is :exc:`spam.error`. The +Note that the Python name for the exception object is :exc:`!spam.error`. The :c:func:`PyErr_NewException` function may create a class with the base class being :exc:`Exception` (unless another class is passed in instead of ``NULL``), described in :ref:`bltin-exceptions`. -Note also that the :c:data:`SpamError` variable retains a reference to the newly +Note also that the :c:data:`!SpamError` variable retains a reference to the newly created exception class; this is intentional! Since the exception could be removed from the module by external code, an owned reference to the class is -needed to ensure that it will not be discarded, causing :c:data:`SpamError` to +needed to ensure that it will not be discarded, causing :c:data:`!SpamError` to become a dangling pointer. Should it become a dangling pointer, C code which raises the exception could cause a core dump or other unintended side effects. -We discuss the use of ``PyMODINIT_FUNC`` as a function return type later in this +We discuss the use of :c:macro:`PyMODINIT_FUNC` as a function return type later in this sample. -The :exc:`spam.error` exception can be raised in your extension module using a +The :exc:`!spam.error` exception can be raised in your extension module using a call to :c:func:`PyErr_SetString` as shown below:: static PyObject * @@ -281,9 +279,9 @@ statement:: It returns ``NULL`` (the error indicator for functions returning object pointers) if an error is detected in the argument list, relying on the exception set by :c:func:`PyArg_ParseTuple`. Otherwise the string value of the argument has been -copied to the local variable :c:data:`command`. This is a pointer assignment and +copied to the local variable :c:data:`!command`. This is a pointer assignment and you are not supposed to modify the string to which it points (so in Standard C, -the variable :c:data:`command` should properly be declared as ``const char +the variable :c:data:`!command` should properly be declared as ``const char *command``). The next statement is a call to the Unix function :c:func:`system`, passing it @@ -291,7 +289,7 @@ the string we just got from :c:func:`PyArg_ParseTuple`:: sts = system(command); -Our :func:`spam.system` function must return the value of :c:data:`sts` as a +Our :func:`!spam.system` function must return the value of :c:data:`!sts` as a Python object. This is done using the function :c:func:`PyLong_FromLong`. :: return PyLong_FromLong(sts); @@ -317,7 +315,7 @@ contexts, as we have seen. The Module's Method Table and Initialization Function ===================================================== -I promised to show how :c:func:`spam_system` is called from Python programs. +I promised to show how :c:func:`!spam_system` is called from Python programs. First, we need to list its name and address in a "method table":: static PyMethodDef SpamMethods[] = { @@ -337,7 +335,7 @@ When using only ``METH_VARARGS``, the function should expect the Python-level parameters to be passed in as a tuple acceptable for parsing via :c:func:`PyArg_ParseTuple`; more information on this function is provided below. -The :const:`METH_KEYWORDS` bit may be set in the third field if keyword +The :c:macro:`METH_KEYWORDS` bit may be set in the third field if keyword arguments should be passed to the function. In this case, the C function should accept a third ``PyObject *`` parameter which will be a dictionary of keywords. Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a @@ -356,7 +354,7 @@ The method table must be referenced in the module definition structure:: This structure, in turn, must be passed to the interpreter in the module's initialization function. The initialization function must be named -:c:func:`PyInit_name`, where *name* is the name of the module, and should be the +:c:func:`!PyInit_name`, where *name* is the name of the module, and should be the only non-\ ``static`` item defined in the module file:: PyMODINIT_FUNC @@ -365,12 +363,12 @@ only non-\ ``static`` item defined in the module file:: return PyModule_Create(&spammodule); } -Note that PyMODINIT_FUNC declares the function as ``PyObject *`` return type, +Note that :c:macro:`PyMODINIT_FUNC` declares the function as ``PyObject *`` return type, declares any special linkage declarations required by the platform, and for C++ declares the function as ``extern "C"``. -When the Python program imports module :mod:`spam` for the first time, -:c:func:`PyInit_spam` is called. (See below for comments about embedding Python.) +When the Python program imports module :mod:`!spam` for the first time, +:c:func:`!PyInit_spam` is called. (See below for comments about embedding Python.) It calls :c:func:`PyModule_Create`, which returns a module object, and inserts built-in function objects into the newly created module based upon the table (an array of :c:type:`PyMethodDef` structures) found in the module definition. @@ -380,7 +378,7 @@ certain errors, or return ``NULL`` if the module could not be initialized satisfactorily. The init function must return the module object to its caller, so that it then gets inserted into ``sys.modules``. -When embedding Python, the :c:func:`PyInit_spam` function is not called +When embedding Python, the :c:func:`!PyInit_spam` function is not called automatically unless there's an entry in the :c:data:`PyImport_Inittab` table. To add the module to the initialization table, use :c:func:`PyImport_AppendInittab`, optionally followed by an import of the module:: @@ -540,7 +538,7 @@ be part of a module definition:: } This function must be registered with the interpreter using the -:const:`METH_VARARGS` flag; this is described in section :ref:`methodtable`. The +:c:macro:`METH_VARARGS` flag; this is described in section :ref:`methodtable`. The :c:func:`PyArg_ParseTuple` function and its arguments are documented in section :ref:`parsetuple`. @@ -1043,13 +1041,13 @@ Let's follow the control flow into :c:func:`PyList_SetItem`. The list owns references to all its items, so when item 1 is replaced, it has to dispose of the original item 1. Now let's suppose the original item 1 was an instance of a user-defined class, and let's further suppose that the class defined a -:meth:`__del__` method. If this class instance has a reference count of 1, -disposing of it will call its :meth:`__del__` method. +:meth:`!__del__` method. If this class instance has a reference count of 1, +disposing of it will call its :meth:`!__del__` method. -Since it is written in Python, the :meth:`__del__` method can execute arbitrary +Since it is written in Python, the :meth:`!__del__` method can execute arbitrary Python code. Could it perhaps do something to invalidate the reference to -``item`` in :c:func:`bug`? You bet! Assuming that the list passed into -:c:func:`bug` is accessible to the :meth:`__del__` method, it could execute a +``item`` in :c:func:`!bug`? You bet! Assuming that the list passed into +:c:func:`!bug` is accessible to the :meth:`!__del__` method, it could execute a statement to the effect of ``del list[0]``, and assuming this was the last reference to that object, it would free the memory associated with it, thereby invalidating ``item``. @@ -1070,7 +1068,7 @@ increment the reference count. The correct version of the function reads:: This is a true story. An older version of Python contained variants of this bug and someone spent a considerable amount of time in a C debugger to figure out -why his :meth:`__del__` methods would fail... +why his :meth:`!__del__` methods would fail... The second case of problems with a borrowed reference is a variant involving threads. Normally, multiple threads in the Python interpreter can't get in each @@ -1221,14 +1219,14 @@ file corresponding to the module provides a macro that takes care of importing the module and retrieving its C API pointers; client modules only have to call this macro before accessing the C API. -The exporting module is a modification of the :mod:`spam` module from section -:ref:`extending-simpleexample`. The function :func:`spam.system` does not call +The exporting module is a modification of the :mod:`!spam` module from section +:ref:`extending-simpleexample`. The function :func:`!spam.system` does not call the C library function :c:func:`system` directly, but a function -:c:func:`PySpam_System`, which would of course do something more complicated in +:c:func:`!PySpam_System`, which would of course do something more complicated in reality (such as adding "spam" to every command). This function -:c:func:`PySpam_System` is also exported to other extension modules. +:c:func:`!PySpam_System` is also exported to other extension modules. -The function :c:func:`PySpam_System` is a plain C function, declared +The function :c:func:`!PySpam_System` is a plain C function, declared ``static`` like everything else:: static int @@ -1237,7 +1235,7 @@ The function :c:func:`PySpam_System` is a plain C function, declared return system(command); } -The function :c:func:`spam_system` is modified in a trivial way:: +The function :c:func:`!spam_system` is modified in a trivial way:: static PyObject * spam_system(PyObject *self, PyObject *args) @@ -1281,8 +1279,7 @@ 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 (PyModule_AddObject(m, "_C_API", c_api_object) < 0) { - Py_XDECREF(c_api_object); + if (PyModule_Add(m, "_C_API", c_api_object) < 0) { Py_DECREF(m); return NULL; } @@ -1291,7 +1288,7 @@ function must take care of initializing the C API pointer array:: } Note that ``PySpam_API`` is declared ``static``; otherwise the pointer -array would disappear when :func:`PyInit_spam` terminates! +array would disappear when :c:func:`!PyInit_spam` terminates! The bulk of the work is in the header file :file:`spammodule.h`, which looks like this:: @@ -1345,8 +1342,8 @@ like this:: #endif /* !defined(Py_SPAMMODULE_H) */ All that a client module must do in order to have access to the function -:c:func:`PySpam_System` is to call the function (or rather macro) -:c:func:`import_spam` in its initialization function:: +:c:func:`!PySpam_System` is to call the function (or rather macro) +:c:func:`!import_spam` in its initialization function:: PyMODINIT_FUNC PyInit_client(void) diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index 7f8f8ddaaaccd6..9f166eb8a4c3ff 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -270,7 +270,7 @@ structure:: One entry should be defined for each method provided by the type; no entries are needed for methods inherited from a base type. One additional entry is needed at the end; it is a sentinel that marks the end of the array. The -:attr:`ml_name` field of the sentinel must be ``NULL``. +:c:member:`~PyMethodDef.ml_name` field of the sentinel must be ``NULL``. The second table is used to define attributes which map directly to data stored in the instance. A variety of primitive C types are supported, and access may @@ -286,9 +286,9 @@ be read-only or read-write. The structures in the table are defined as:: For each entry in the table, a :term:`descriptor` will be constructed and added to the type which will be able to extract a value from the instance structure. The -:attr:`type` field should contain a type code like :c:macro:`Py_T_INT` or +:c:member:`~PyMemberDef.type` field should contain a type code like :c:macro:`Py_T_INT` or :c:macro:`Py_T_DOUBLE`; the value will be used to determine how to -convert Python values to and from C values. The :attr:`flags` field is used to +convert Python values to and from C values. The :c:member:`~PyMemberDef.flags` field is used to store flags which control how the attribute can be accessed: you can set it to :c:macro:`Py_READONLY` to prevent Python code from setting it. @@ -298,7 +298,7 @@ have an associated doc string simply by providing the text in the table. An application can use the introspection API to retrieve the descriptor from the class object, and get the doc string using its :attr:`__doc__` attribute. -As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry with a :attr:`name` value +As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry with a :c:member:`~PyMethodDef.ml_name` value of ``NULL`` is required. .. XXX Descriptors need to be explained in more detail somewhere, but not here. @@ -323,7 +323,7 @@ called, so that if you do need to extend their functionality, you'll understand what needs to be done. The :c:member:`~PyTypeObject.tp_getattr` handler is called when the object requires an attribute -look-up. It is called in the same situations where the :meth:`__getattr__` +look-up. It is called in the same situations where the :meth:`~object.__getattr__` method of a class would be called. Here is an example:: @@ -342,8 +342,8 @@ Here is an example:: return NULL; } -The :c:member:`~PyTypeObject.tp_setattr` handler is called when the :meth:`__setattr__` or -:meth:`__delattr__` method of a class instance would be called. When an +The :c:member:`~PyTypeObject.tp_setattr` handler is called when the :meth:`~object.__setattr__` or +:meth:`~object.__delattr__` method of a class instance would be called. When an attribute should be deleted, the third parameter will be ``NULL``. Here is an example that simply raises an exception; if this were really all you wanted, the :c:member:`~PyTypeObject.tp_setattr` handler should be set to ``NULL``. :: @@ -364,7 +364,7 @@ Object Comparison The :c:member:`~PyTypeObject.tp_richcompare` handler is called when comparisons are needed. It is analogous to the :ref:`rich comparison methods `, like -:meth:`__lt__`, and also called by :c:func:`PyObject_RichCompare` and +:meth:`!__lt__`, and also called by :c:func:`PyObject_RichCompare` and :c:func:`PyObject_RichCompareBool`. This function is called with two Python objects and the operator as arguments, @@ -505,7 +505,7 @@ These functions provide support for the iterator protocol. Both handlers take exactly one parameter, the instance for which they are being called, and return a new reference. In the case of an error, they should set an exception and return ``NULL``. :c:member:`~PyTypeObject.tp_iter` corresponds -to the Python :meth:`__iter__` method, while :c:member:`~PyTypeObject.tp_iternext` +to the Python :meth:`~object.__iter__` method, while :c:member:`~PyTypeObject.tp_iternext` corresponds to the Python :meth:`~iterator.__next__` method. Any :term:`iterable` object must implement the :c:member:`~PyTypeObject.tp_iter` diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index f89934a11f12a8..7eba9759119b3b 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -36,8 +36,8 @@ So, if you want to define a new extension type, you need to create a new type object. This sort of thing can only be explained by example, so here's a minimal, but -complete, module that defines a new type named :class:`Custom` inside a C -extension module :mod:`custom`: +complete, module that defines a new type named :class:`!Custom` inside a C +extension module :mod:`!custom`: .. note:: What we're showing here is the traditional way of defining *static* @@ -45,17 +45,17 @@ extension module :mod:`custom`: allows defining heap-allocated extension types using the :c:func:`PyType_FromSpec` function, which isn't covered in this tutorial. -.. literalinclude:: ../includes/custom.c +.. literalinclude:: ../includes/newtypes/custom.c Now that's quite a bit to take in at once, but hopefully bits will seem familiar from the previous chapter. This file defines three things: -#. What a :class:`Custom` **object** contains: this is the ``CustomObject`` - struct, which is allocated once for each :class:`Custom` instance. -#. How the :class:`Custom` **type** behaves: this is the ``CustomType`` struct, +#. What a :class:`!Custom` **object** contains: this is the ``CustomObject`` + struct, which is allocated once for each :class:`!Custom` instance. +#. How the :class:`!Custom` **type** behaves: this is the ``CustomType`` struct, which defines a set of flags and function pointers that the interpreter inspects when specific operations are requested. -#. How to initialize the :mod:`custom` module: this is the ``PyInit_custom`` +#. How to initialize the :mod:`!custom` module: this is the ``PyInit_custom`` function and the associated ``custommodule`` struct. The first bit is:: @@ -127,8 +127,8 @@ our objects and in some error messages, for example: TypeError: can only concatenate str (not "custom.Custom") to str Note that the name is a dotted name that includes both the module name and the -name of the type within the module. The module in this case is :mod:`custom` and -the type is :class:`Custom`, so we set the type name to :class:`custom.Custom`. +name of the type within the module. The module in this case is :mod:`!custom` and +the type is :class:`!Custom`, so we set the type name to :class:`!custom.Custom`. Using the real dotted import path is important to make your type compatible with the :mod:`pydoc` and :mod:`pickle` modules. :: @@ -136,7 +136,7 @@ with the :mod:`pydoc` and :mod:`pickle` modules. :: .tp_itemsize = 0, This is so that Python knows how much memory to allocate when creating -new :class:`Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is +new :class:`!Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is only used for variable-sized objects and should otherwise be zero. .. note:: @@ -145,13 +145,13 @@ only used for variable-sized objects and should otherwise be zero. :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have problems with multiple inheritance. A Python subclass of your type will have to list your type first in its :attr:`~class.__bases__`, or else it will not be able to call your type's - :meth:`__new__` method without getting an error. You can avoid this problem by + :meth:`~object.__new__` method without getting an error. You can avoid this problem by ensuring that your type has a larger value for :c:member:`~PyTypeObject.tp_basicsize` than its base type does. Most of the time, this will be true anyway, because either your base type will be :class:`object`, or else you will be adding data members to your base type, and therefore increasing its size. -We set the class flags to :const:`Py_TPFLAGS_DEFAULT`. :: +We set the class flags to :c:macro:`Py_TPFLAGS_DEFAULT`. :: .tp_flags = Py_TPFLAGS_DEFAULT, @@ -164,31 +164,29 @@ We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. :: .tp_doc = PyDoc_STR("Custom objects"), To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new` -handler. This is the equivalent of the Python method :meth:`__new__`, but +handler. This is the equivalent of the Python method :meth:`~object.__new__`, but has to be specified explicitly. In this case, we can just use the default implementation provided by the API function :c:func:`PyType_GenericNew`. :: .tp_new = PyType_GenericNew, Everything else in the file should be familiar, except for some code in -:c:func:`PyInit_custom`:: +:c:func:`!PyInit_custom`:: if (PyType_Ready(&CustomType) < 0) return; -This initializes the :class:`Custom` type, filling in a number of members -to the appropriate default values, including :attr:`ob_type` that we initially +This initializes the :class:`!Custom` type, filling in a number of members +to the appropriate default values, including :c:member:`~PyObject.ob_type` that we initially set to ``NULL``. :: - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } This adds the type to the module dictionary. This allows us to create -:class:`Custom` instances by calling the :class:`Custom` class: +:class:`!Custom` instances by calling the :class:`!Custom` class: .. code-block:: pycon @@ -196,50 +194,46 @@ This adds the type to the module dictionary. This allows us to create >>> mycustom = custom.Custom() That's it! All that remains is to build it; put the above code in a file called -:file:`custom.c` and: +:file:`custom.c`, + +.. literalinclude:: ../includes/newtypes/pyproject.toml + +in a file called :file:`pyproject.toml`, and .. code-block:: python - from distutils.core import setup, Extension - setup(name="custom", version="1.0", - ext_modules=[Extension("custom", ["custom.c"])]) + from setuptools import Extension, setup + setup(ext_modules=[Extension("custom", ["custom.c"])]) in a file called :file:`setup.py`; then typing .. code-block:: shell-session - $ python setup.py build + $ python -m pip install . -at a shell should produce a file :file:`custom.so` in a subdirectory; move to -that directory and fire up Python --- you should be able to ``import custom`` and -play around with Custom objects. +in a shell should produce a file :file:`custom.so` in a subdirectory +and install it; now fire up Python --- you should be able to ``import custom`` +and play around with ``Custom`` objects. That wasn't so hard, was it? Of course, the current Custom type is pretty uninteresting. It has no data and doesn't do anything. It can't even be subclassed. -.. note:: - While this documentation showcases the standard :mod:`distutils` module - for building C extensions, it is recommended in real-world use cases to - use the newer and better-maintained ``setuptools`` library. Documentation - on how to do this is out of scope for this document and can be found in - the `Python Packaging User's Guide `_. - Adding data and methods to the Basic example ============================================ Let's extend the basic example to add some data and methods. Let's also make -the type usable as a base class. We'll create a new module, :mod:`custom2` that +the type usable as a base class. We'll create a new module, :mod:`!custom2` that adds these capabilities: -.. literalinclude:: ../includes/custom2.c +.. literalinclude:: ../includes/newtypes/custom2.c This version of the module has a number of changes. -The :class:`Custom` type now has three data attributes in its C struct, +The :class:`!Custom` type now has three data attributes in its C struct, *first*, *last*, and *number*. The *first* and *last* variables are Python strings containing first and last names. The *number* attribute is a C integer. @@ -272,7 +266,7 @@ This method first clears the reference counts of the two Python attributes. ``NULL`` (which might happen here if ``tp_new`` failed midway). It then calls the :c:member:`~PyTypeObject.tp_free` member of the object's type (computed by ``Py_TYPE(self)``) to free the object's memory. Note that -the object's type might not be :class:`CustomType`, because the object may +the object's type might not be :class:`!CustomType`, because the object may be an instance of a subclass. .. note:: @@ -311,10 +305,10 @@ and install it in the :c:member:`~PyTypeObject.tp_new` member:: .tp_new = Custom_new, The ``tp_new`` handler is responsible for creating (as opposed to initializing) -objects of the type. It is exposed in Python as the :meth:`__new__` method. +objects of the type. It is exposed in Python as the :meth:`~object.__new__` method. It is not required to define a ``tp_new`` member, and indeed many extension types will simply reuse :c:func:`PyType_GenericNew` as done in the first -version of the ``Custom`` type above. In this case, we use the ``tp_new`` +version of the :class:`!Custom` type above. In this case, we use the ``tp_new`` handler to initialize the ``first`` and ``last`` attributes to non-``NULL`` default values. @@ -345,7 +339,7 @@ result against ``NULL`` before proceeding. .. note:: If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one - that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:`__new__`), + that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:`~object.__new__`), you must *not* try to determine what method to call using method resolution order at runtime. Always statically determine what type you are going to call, and call its :c:member:`~PyTypeObject.tp_new` directly, or via @@ -388,14 +382,14 @@ by filling the :c:member:`~PyTypeObject.tp_init` slot. :: .tp_init = (initproc) Custom_init, The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the -:meth:`__init__` method. It is used to initialize an object after it's +:meth:`~object.__init__` method. It is used to initialize an object after it's created. Initializers always accept positional and keyword arguments, and they should return either ``0`` on success or ``-1`` on error. Unlike the ``tp_new`` handler, there is no guarantee that ``tp_init`` is called at all (for example, the :mod:`pickle` module by default -doesn't call :meth:`__init__` on unpickled instances). It can also be -called multiple times. Anyone can call the :meth:`__init__` method on +doesn't call :meth:`~object.__init__` on unpickled instances). It can also be +called multiple times. Anyone can call the :meth:`!__init__` method on our objects. For this reason, we have to be extra careful when assigning the new attribute values. We might be tempted, for example to assign the ``first`` member like this:: @@ -453,7 +447,7 @@ Further, the attributes can be deleted, setting the C pointers to ``NULL``. Eve though we can make sure the members are initialized to non-``NULL`` values, the members can be set to ``NULL`` if the attributes are deleted. -We define a single method, :meth:`Custom.name()`, that outputs the objects name as the +We define a single method, :meth:`!Custom.name()`, that outputs the objects name as the concatenation of the first and last names. :: static PyObject * @@ -470,8 +464,8 @@ concatenation of the first and last names. :: return PyUnicode_FromFormat("%S %S", self->first, self->last); } -The method is implemented as a C function that takes a :class:`Custom` (or -:class:`Custom` subclass) instance as the first argument. Methods always take an +The method is implemented as a C function that takes a :class:`!Custom` (or +:class:`!Custom` subclass) instance as the first argument. Methods always take an instance as the first argument. Methods often take positional and keyword arguments as well, but in this case we don't take any and don't need to accept a positional argument tuple or keyword argument dictionary. This method is @@ -482,8 +476,8 @@ equivalent to the Python method: def name(self): return "%s %s" % (self.first, self.last) -Note that we have to check for the possibility that our :attr:`first` and -:attr:`last` members are ``NULL``. This is because they can be deleted, in which +Note that we have to check for the possibility that our :attr:`!first` and +:attr:`!last` members are ``NULL``. This is because they can be deleted, in which case they are set to ``NULL``. It would be better to prevent deletion of these attributes and to restrict the attribute values to be strings. We'll see how to do that in the next section. @@ -498,7 +492,7 @@ definitions:: {NULL} /* Sentinel */ }; -(note that we used the :const:`METH_NOARGS` flag to indicate that the method +(note that we used the :c:macro:`METH_NOARGS` flag to indicate that the method is expecting no arguments other than *self*) and assign it to the :c:member:`~PyTypeObject.tp_methods` slot:: @@ -508,41 +502,45 @@ and assign it to the :c:member:`~PyTypeObject.tp_methods` slot:: Finally, we'll make our type usable as a base class for subclassing. We've written our methods carefully so far so that they don't make any assumptions about the type of the object being created or used, so all we need to do is -to add the :const:`Py_TPFLAGS_BASETYPE` to our class flag definition:: +to add the :c:macro:`Py_TPFLAGS_BASETYPE` to our class flag definition:: .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, -We rename :c:func:`PyInit_custom` to :c:func:`PyInit_custom2`, update the +We rename :c:func:`!PyInit_custom` to :c:func:`!PyInit_custom2`, update the module name in the :c:type:`PyModuleDef` struct, and update the full class name in the :c:type:`PyTypeObject` struct. -Finally, we update our :file:`setup.py` file to build the new module: +Finally, we update our :file:`setup.py` file to include the new module, .. code-block:: python - from distutils.core import setup, Extension - setup(name="custom", version="1.0", - ext_modules=[ - Extension("custom", ["custom.c"]), - Extension("custom2", ["custom2.c"]), - ]) + from setuptools import Extension, setup + setup(ext_modules=[ + Extension("custom", ["custom.c"]), + Extension("custom2", ["custom2.c"]), + ]) + +and then we re-install so that we can ``import custom2``: + +.. code-block:: shell-session + $ python -m pip install . Providing finer control over data attributes ============================================ -In this section, we'll provide finer control over how the :attr:`first` and -:attr:`last` attributes are set in the :class:`Custom` example. In the previous -version of our module, the instance variables :attr:`first` and :attr:`last` +In this section, we'll provide finer control over how the :attr:`!first` and +:attr:`!last` attributes are set in the :class:`!Custom` example. In the previous +version of our module, the instance variables :attr:`!first` and :attr:`!last` could be set to non-string values or even deleted. We want to make sure that these attributes always contain strings. -.. literalinclude:: ../includes/custom3.c +.. literalinclude:: ../includes/newtypes/custom3.c -To provide greater control, over the :attr:`first` and :attr:`last` attributes, +To provide greater control, over the :attr:`!first` and :attr:`!last` attributes, we'll use custom getter and setter functions. Here are the functions for -getting and setting the :attr:`first` attribute:: +getting and setting the :attr:`!first` attribute:: static PyObject * Custom_getfirst(CustomObject *self, void *closure) @@ -571,13 +569,13 @@ getting and setting the :attr:`first` attribute:: return 0; } -The getter function is passed a :class:`Custom` object and a "closure", which is +The getter function is passed a :class:`!Custom` object and a "closure", which is a void pointer. In this case, the closure is ignored. (The closure supports an advanced usage in which definition data is passed to the getter and setter. This could, for example, be used to allow a single set of getter and setter functions that decide the attribute to get or set based on data in the closure.) -The setter function is passed the :class:`Custom` object, the new value, and the +The setter function is passed the :class:`!Custom` object, the new value, and the closure. The new value may be ``NULL``, in which case the attribute is being deleted. In our setter, we raise an error if the attribute is deleted or if its new value is not a string. @@ -666,11 +664,11 @@ still has a reference from itself. Its reference count doesn't drop to zero. Fortunately, Python's cyclic garbage collector will eventually figure out that the list is garbage and free it. -In the second version of the :class:`Custom` example, we allowed any kind of -object to be stored in the :attr:`first` or :attr:`last` attributes [#]_. +In the second version of the :class:`!Custom` example, we allowed any kind of +object to be stored in the :attr:`!first` or :attr:`!last` attributes [#]_. Besides, in the second and third versions, we allowed subclassing -:class:`Custom`, and subclasses may add arbitrary attributes. For any of -those two reasons, :class:`Custom` objects can participate in cycles: +:class:`!Custom`, and subclasses may add arbitrary attributes. For any of +those two reasons, :class:`!Custom` objects can participate in cycles: .. code-block:: pycon @@ -680,11 +678,11 @@ those two reasons, :class:`Custom` objects can participate in cycles: >>> n = Derived() >>> n.some_attribute = n -To allow a :class:`Custom` instance participating in a reference cycle to -be properly detected and collected by the cyclic GC, our :class:`Custom` type +To allow a :class:`!Custom` instance participating in a reference cycle to +be properly detected and collected by the cyclic GC, our :class:`!Custom` type needs to fill two additional slots and to enable a flag that enables these slots: -.. literalinclude:: ../includes/custom4.c +.. literalinclude:: ../includes/newtypes/custom4.c First, the traversal method lets the cyclic GC know about subobjects that could @@ -708,8 +706,8 @@ participate in cycles:: } For each subobject that can participate in cycles, we need to call the -:c:func:`visit` function, which is passed to the traversal method. The -:c:func:`visit` function takes as arguments the subobject and the extra argument +:c:func:`!visit` function, which is passed to the traversal method. The +:c:func:`!visit` function takes as arguments the subobject and the extra argument *arg* passed to the traversal method. It returns an integer value that must be returned if it is non-zero. @@ -774,7 +772,7 @@ and ``Custom_clear``:: Py_TYPE(self)->tp_free((PyObject *) self); } -Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags:: +Finally, we add the :c:macro:`Py_TPFLAGS_HAVE_GC` flag to the class flags:: .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, @@ -791,9 +789,9 @@ types. It is easiest to inherit from the built in types, since an extension can easily use the :c:type:`PyTypeObject` it needs. It can be difficult to share these :c:type:`PyTypeObject` structures between extension modules. -In this example we will create a :class:`SubList` type that inherits from the +In this example we will create a :class:`!SubList` type that inherits from the built-in :class:`list` type. The new type will be completely compatible with -regular lists, but will have an additional :meth:`increment` method that +regular lists, but will have an additional :meth:`!increment` method that increases an internal counter: .. code-block:: pycon @@ -808,10 +806,10 @@ increases an internal counter: >>> print(s.increment()) 2 -.. literalinclude:: ../includes/sublist.c +.. literalinclude:: ../includes/newtypes/sublist.c -As you can see, the source code closely resembles the :class:`Custom` examples in +As you can see, the source code closely resembles the :class:`!Custom` examples in previous sections. We will break down the main differences between them. :: typedef struct { @@ -823,7 +821,7 @@ The primary difference for derived type objects is that the base type's object structure must be the first value. The base type will already include the :c:func:`PyObject_HEAD` at the beginning of its structure. -When a Python object is a :class:`SubList` instance, its ``PyObject *`` pointer +When a Python object is a :class:`!SubList` instance, its ``PyObject *`` pointer can be safely cast to both ``PyListObject *`` and ``SubListObject *``:: static int @@ -835,7 +833,7 @@ can be safely cast to both ``PyListObject *`` and ``SubListObject *``:: return 0; } -We see above how to call through to the :attr:`__init__` method of the base +We see above how to call through to the :meth:`~object.__init__` method of the base type. This pattern is important when writing a type with custom @@ -862,9 +860,7 @@ function:: if (m == NULL) return NULL; - Py_INCREF(&SubListType); - if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) { - Py_DECREF(&SubListType); + if (PyModule_AddObjectRef(m, "SubList", (PyObject *) &SubListType) < 0) { Py_DECREF(m); return NULL; } @@ -879,7 +875,7 @@ slot with :c:func:`PyType_GenericNew` -- the allocation function from the base type will be inherited. After that, calling :c:func:`PyType_Ready` and adding the type object to the -module is the same as with the basic :class:`Custom` examples. +module is the same as with the basic :class:`!Custom` examples. .. rubric:: Footnotes diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst index 1129b0968bc4e6..e366d6cb9f79e3 100644 --- a/Doc/extending/windows.rst +++ b/Doc/extending/windows.rst @@ -132,4 +132,4 @@ modules (including Python) to be able to see your identifiers, you have to say Developer Studio will throw in a lot of import libraries that you do not really need, adding about 100K to your executable. To get rid of them, use the Project Settings dialog, Link tab, to specify *ignore default libraries*. Add the -correct :file:`msvcrtxx.lib` to the list of libraries. +correct :file:`msvcrt{xx}.lib` to the list of libraries. diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 11d01374dc1e79..ae02c443e5938b 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -584,9 +584,9 @@ exhaustive test suites that exercise every line of code in a module. An appropriate testing discipline can help build large complex applications in Python as well as having interface specifications would. In fact, it can be better because an interface specification cannot test certain properties of a -program. For example, the :meth:`list.append` method is expected to add new elements +program. For example, the :meth:`!list.append` method is expected to add new elements to the end of some internal list; an interface specification cannot test that -your :meth:`list.append` implementation will actually do this correctly, but it's +your :meth:`!list.append` implementation will actually do this correctly, but it's trivial to check this property in a test suite. Writing test suites is very helpful, and you might want to design your code to diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index bc3080f60ee237..2a8b976925d042 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -81,13 +81,13 @@ How do I extract C values from a Python object? That depends on the object's type. If it's a tuple, :c:func:`PyTuple_Size` returns its length and :c:func:`PyTuple_GetItem` returns the item at a specified -index. Lists have similar functions, :c:func:`PyListSize` and +index. Lists have similar functions, :c:func:`PyList_Size` and :c:func:`PyList_GetItem`. For bytes, :c:func:`PyBytes_Size` returns its length and :c:func:`PyBytes_AsStringAndSize` provides a pointer to its value and its length. Note that Python bytes objects may contain null bytes so C's -:c:func:`strlen` should not be used. +:c:func:`!strlen` should not be used. To test the type of an object, first make sure it isn't ``NULL``, and then use :c:func:`PyBytes_Check`, :c:func:`PyTuple_Check`, :c:func:`PyList_Check`, etc. diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 0a372342862d2f..cfa60feceb31b7 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -43,7 +43,7 @@ applications, the applications will not be truly stand-alone, as the application will still need the Tcl and Tk libraries. One solution is to ship the application with the Tcl and Tk libraries, and point -to them at run-time using the :envvar:`TCL_LIBRARY` and :envvar:`TK_LIBRARY` +to them at run-time using the :envvar:`!TCL_LIBRARY` and :envvar:`!TK_LIBRARY` environment variables. Various third-party freeze libraries such as py2exe and cx_Freeze have @@ -55,7 +55,7 @@ Can I have Tk events handled while waiting for I/O? On platforms other than Windows, yes, and you don't even need threads! But you'll have to restructure your I/O -code a bit. Tk has the equivalent of Xt's :c:func:`XtAddInput()` call, which allows you +code a bit. Tk has the equivalent of Xt's :c:func:`!XtAddInput` call, which allows you to register a callback function which will be called from the Tk mainloop when I/O is possible on a file descriptor. See :ref:`tkinter-file-handlers`. @@ -63,8 +63,9 @@ I/O is possible on a file descriptor. See :ref:`tkinter-file-handlers`. I can't get key bindings to work in Tkinter: why? ------------------------------------------------- -An often-heard complaint is that event handlers bound to events with the -:meth:`bind` method don't get handled even when the appropriate key is pressed. +An often-heard complaint is that event handlers :ref:`bound ` +to events with the :meth:`!bind` method +don't get handled even when the appropriate key is pressed. The most common cause is that the widget to which the binding applies doesn't have "keyboard focus". Check out the Tk documentation for the focus command. diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst index 22f7f846d261d8..476a43d9c288f1 100644 --- a/Doc/faq/library.rst +++ b/Doc/faq/library.rst @@ -111,7 +111,7 @@ Is there an equivalent to C's onexit() in Python? ------------------------------------------------- The :mod:`atexit` module provides a register function that is similar to C's -:c:func:`onexit`. +:c:func:`!onexit`. Why don't my signal handlers work? @@ -397,7 +397,7 @@ These aren't:: D[x] = D[x] + 1 Operations that replace other objects may invoke those other objects' -:meth:`__del__` method when their reference count reaches zero, and that can +:meth:`~object.__del__` method when their reference count reaches zero, and that can affect things. This is especially true for the mass updates to dictionaries and lists. When in doubt, use a mutex! @@ -566,7 +566,7 @@ use ``p.read(n)``. Note on a bug in popen2: unless your program calls ``wait()`` or ``waitpid()``, finished child processes are never removed, and eventually calls to popen2 will fail because of a limit on the number of child - processes. Calling :func:`os.waitpid` with the :data:`os.WNOHANG` option can + processes. Calling :func:`os.waitpid` with the :const:`os.WNOHANG` option can prevent this; a good place to insert such a call would be before calling ``popen2`` again. @@ -730,14 +730,17 @@ The :mod:`select` module is commonly used to help with asynchronous I/O on sockets. To prevent the TCP connect from blocking, you can set the socket to non-blocking -mode. Then when you do the :meth:`socket.connect`, you will either connect immediately +mode. Then when you do the :meth:`~socket.socket.connect`, +you will either connect immediately (unlikely) or get an exception that contains the error number as ``.errno``. ``errno.EINPROGRESS`` indicates that the connection is in progress, but hasn't finished yet. Different OSes will return different values, so you're going to have to check what's returned on your system. -You can use the :meth:`socket.connect_ex` method to avoid creating an exception. It will -just return the errno value. To poll, you can call :meth:`socket.connect_ex` again later +You can use the :meth:`~socket.socket.connect_ex` method +to avoid creating an exception. +It will just return the errno value. +To poll, you can call :meth:`~socket.socket.connect_ex` again later -- ``0`` or ``errno.EISCONN`` indicate that you're connected -- or you can pass this socket to :meth:`select.select` to check if it's writable. diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 6e1812504a184f..0a88c5f6384f2b 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -454,7 +454,7 @@ There are two factors that produce this result: (the list), and both ``x`` and ``y`` refer to it. 2) Lists are :term:`mutable`, which means that you can change their content. -After the call to :meth:`~list.append`, the content of the mutable object has +After the call to :meth:`!append`, the content of the mutable object has changed from ``[]`` to ``[10]``. Since both the variables refer to the same object, using either name accesses the modified value ``[10]``. @@ -1397,7 +1397,7 @@ To see why this happens, you need to know that (a) if an object implements an :meth:`~object.__iadd__` magic method, it gets called when the ``+=`` augmented assignment is executed, and its return value is what gets used in the assignment statement; -and (b) for lists, :meth:`!__iadd__` is equivalent to calling :meth:`~list.extend` on the list +and (b) for lists, :meth:`!__iadd__` is equivalent to calling :meth:`!extend` on the list and returning the list. That's why we say that for lists, ``+=`` is a "shorthand" for :meth:`!list.extend`:: @@ -1903,7 +1903,7 @@ identity tests. This prevents the code from being confused by objects such as ``float('NaN')`` that are not equal to themselves. For example, here is the implementation of -:meth:`collections.abc.Sequence.__contains__`:: +:meth:`!collections.abc.Sequence.__contains__`:: def __contains__(self, value): for v in self: diff --git a/Doc/glossary.rst b/Doc/glossary.rst index a4650a6c3efa22..a4cd05b0cf019d 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -159,8 +159,9 @@ Glossary :class:`str` objects. borrowed reference - In Python's C API, a borrowed reference is a reference to an object. - It does not modify the object reference count. It becomes a dangling + In Python's C API, a borrowed reference is a reference to an object, + where the code using the object does not own the reference. + It becomes a dangling pointer if the object is destroyed. For example, a garbage collection can remove the last :term:`strong reference` to the object and so destroy it. @@ -1054,7 +1055,9 @@ Glossary reference count The number of references to an object. When the reference count of an - object drops to zero, it is deallocated. Reference counting is + object drops to zero, it is deallocated. Some objects are + "immortal" and have reference counts that are never modified, and + therefore the objects are never deallocated. Reference counting is generally not visible to Python code, but it is a key element of the :term:`CPython` implementation. Programmers can call the :func:`sys.getrefcount` function to return the @@ -1137,8 +1140,10 @@ Glossary strong reference In Python's C API, a strong reference is a reference to an object - which increments the object's reference count when it is created and - decrements the object's reference count when it is deleted. + which is owned by the code holding the reference. The strong + reference is taken by calling :c:func:`Py_INCREF` when the + reference is created and released with :c:func:`Py_DECREF` + when the reference is deleted. The :c:func:`Py_NewRef` function can be used to create a strong reference to an object. Usually, the :c:func:`Py_DECREF` function must be called on diff --git a/Doc/howto/annotations.rst b/Doc/howto/annotations.rst index 472069032d6509..1134686c947d66 100644 --- a/Doc/howto/annotations.rst +++ b/Doc/howto/annotations.rst @@ -32,201 +32,201 @@ Annotations Best Practices Accessing The Annotations Dict Of An Object In Python 3.10 And Newer ==================================================================== - Python 3.10 adds a new function to the standard library: - :func:`inspect.get_annotations`. In Python versions 3.10 - and newer, calling this function is the best practice for - accessing the annotations dict of any object that supports - annotations. This function can also "un-stringize" - stringized annotations for you. - - If for some reason :func:`inspect.get_annotations` isn't - viable for your use case, you may access the - ``__annotations__`` data member manually. Best practice - for this changed in Python 3.10 as well: as of Python 3.10, - ``o.__annotations__`` is guaranteed to *always* work - on Python functions, classes, and modules. If you're - certain the object you're examining is one of these three - *specific* objects, you may simply use ``o.__annotations__`` - to get at the object's annotations dict. - - However, other types of callables--for example, - callables created by :func:`functools.partial`--may - not have an ``__annotations__`` attribute defined. When - accessing the ``__annotations__`` of a possibly unknown - object, best practice in Python versions 3.10 and - newer is to call :func:`getattr` with three arguments, - for example ``getattr(o, '__annotations__', None)``. - - Before Python 3.10, accessing ``__annotations__`` on a class that - defines no annotations but that has a parent class with - annotations would return the parent's ``__annotations__``. - In Python 3.10 and newer, the child class's annotations - will be an empty dict instead. +Python 3.10 adds a new function to the standard library: +:func:`inspect.get_annotations`. In Python versions 3.10 +and newer, calling this function is the best practice for +accessing the annotations dict of any object that supports +annotations. This function can also "un-stringize" +stringized annotations for you. + +If for some reason :func:`inspect.get_annotations` isn't +viable for your use case, you may access the +``__annotations__`` data member manually. Best practice +for this changed in Python 3.10 as well: as of Python 3.10, +``o.__annotations__`` is guaranteed to *always* work +on Python functions, classes, and modules. If you're +certain the object you're examining is one of these three +*specific* objects, you may simply use ``o.__annotations__`` +to get at the object's annotations dict. + +However, other types of callables--for example, +callables created by :func:`functools.partial`--may +not have an ``__annotations__`` attribute defined. When +accessing the ``__annotations__`` of a possibly unknown +object, best practice in Python versions 3.10 and +newer is to call :func:`getattr` with three arguments, +for example ``getattr(o, '__annotations__', None)``. + +Before Python 3.10, accessing ``__annotations__`` on a class that +defines no annotations but that has a parent class with +annotations would return the parent's ``__annotations__``. +In Python 3.10 and newer, the child class's annotations +will be an empty dict instead. Accessing The Annotations Dict Of An Object In Python 3.9 And Older =================================================================== - In Python 3.9 and older, accessing the annotations dict - of an object is much more complicated than in newer versions. - The problem is a design flaw in these older versions of Python, - specifically to do with class annotations. +In Python 3.9 and older, accessing the annotations dict +of an object is much more complicated than in newer versions. +The problem is a design flaw in these older versions of Python, +specifically to do with class annotations. - Best practice for accessing the annotations dict of other - objects--functions, other callables, and modules--is the same - as best practice for 3.10, assuming you aren't calling - :func:`inspect.get_annotations`: you should use three-argument - :func:`getattr` to access the object's ``__annotations__`` - attribute. +Best practice for accessing the annotations dict of other +objects--functions, other callables, and modules--is the same +as best practice for 3.10, assuming you aren't calling +:func:`inspect.get_annotations`: you should use three-argument +:func:`getattr` to access the object's ``__annotations__`` +attribute. - Unfortunately, this isn't best practice for classes. The problem - is that, since ``__annotations__`` is optional on classes, and - because classes can inherit attributes from their base classes, - accessing the ``__annotations__`` attribute of a class may - inadvertently return the annotations dict of a *base class.* - As an example:: +Unfortunately, this isn't best practice for classes. The problem +is that, since ``__annotations__`` is optional on classes, and +because classes can inherit attributes from their base classes, +accessing the ``__annotations__`` attribute of a class may +inadvertently return the annotations dict of a *base class.* +As an example:: - class Base: - a: int = 3 - b: str = 'abc' + class Base: + a: int = 3 + b: str = 'abc' - class Derived(Base): - pass + class Derived(Base): + pass - print(Derived.__annotations__) + print(Derived.__annotations__) - This will print the annotations dict from ``Base``, not - ``Derived``. +This will print the annotations dict from ``Base``, not +``Derived``. - Your code will have to have a separate code path if the object - you're examining is a class (``isinstance(o, type)``). - In that case, best practice relies on an implementation detail - of Python 3.9 and before: if a class has annotations defined, - they are stored in the class's ``__dict__`` dictionary. Since - the class may or may not have annotations defined, best practice - is to call the ``get`` method on the class dict. +Your code will have to have a separate code path if the object +you're examining is a class (``isinstance(o, type)``). +In that case, best practice relies on an implementation detail +of Python 3.9 and before: if a class has annotations defined, +they are stored in the class's ``__dict__`` dictionary. Since +the class may or may not have annotations defined, best practice +is to call the ``get`` method on the class dict. - To put it all together, here is some sample code that safely - accesses the ``__annotations__`` attribute on an arbitrary - object in Python 3.9 and before:: +To put it all together, here is some sample code that safely +accesses the ``__annotations__`` attribute on an arbitrary +object in Python 3.9 and before:: - if isinstance(o, type): - ann = o.__dict__.get('__annotations__', None) - else: - ann = getattr(o, '__annotations__', None) + if isinstance(o, type): + ann = o.__dict__.get('__annotations__', None) + else: + ann = getattr(o, '__annotations__', None) - After running this code, ``ann`` should be either a - dictionary or ``None``. You're encouraged to double-check - the type of ``ann`` using :func:`isinstance` before further - examination. +After running this code, ``ann`` should be either a +dictionary or ``None``. You're encouraged to double-check +the type of ``ann`` using :func:`isinstance` before further +examination. - Note that some exotic or malformed type objects may not have - a ``__dict__`` attribute, so for extra safety you may also wish - to use :func:`getattr` to access ``__dict__``. +Note that some exotic or malformed type objects may not have +a ``__dict__`` attribute, so for extra safety you may also wish +to use :func:`getattr` to access ``__dict__``. Manually Un-Stringizing Stringized Annotations ============================================== - In situations where some annotations may be "stringized", - and you wish to evaluate those strings to produce the - Python values they represent, it really is best to - call :func:`inspect.get_annotations` to do this work - for you. - - If you're using Python 3.9 or older, or if for some reason - you can't use :func:`inspect.get_annotations`, you'll need - to duplicate its logic. You're encouraged to examine the - implementation of :func:`inspect.get_annotations` in the - current Python version and follow a similar approach. - - In a nutshell, if you wish to evaluate a stringized annotation - on an arbitrary object ``o``: - - * If ``o`` is a module, use ``o.__dict__`` as the - ``globals`` when calling :func:`eval`. - * If ``o`` is a class, use ``sys.modules[o.__module__].__dict__`` - as the ``globals``, and ``dict(vars(o))`` as the ``locals``, - when calling :func:`eval`. - * If ``o`` is a wrapped callable using :func:`functools.update_wrapper`, - :func:`functools.wraps`, or :func:`functools.partial`, iteratively - unwrap it by accessing either ``o.__wrapped__`` or ``o.func`` as - appropriate, until you have found the root unwrapped function. - * If ``o`` is a callable (but not a class), use - ``o.__globals__`` as the globals when calling :func:`eval`. - - However, not all string values used as annotations can - be successfully turned into Python values by :func:`eval`. - String values could theoretically contain any valid string, - and in practice there are valid use cases for type hints that - require annotating with string values that specifically - *can't* be evaluated. For example: - - * :pep:`604` union types using ``|``, before support for this - was added to Python 3.10. - * Definitions that aren't needed at runtime, only imported - when :const:`typing.TYPE_CHECKING` is true. - - If :func:`eval` attempts to evaluate such values, it will - fail and raise an exception. So, when designing a library - API that works with annotations, it's recommended to only - attempt to evaluate string values when explicitly requested - to by the caller. +In situations where some annotations may be "stringized", +and you wish to evaluate those strings to produce the +Python values they represent, it really is best to +call :func:`inspect.get_annotations` to do this work +for you. + +If you're using Python 3.9 or older, or if for some reason +you can't use :func:`inspect.get_annotations`, you'll need +to duplicate its logic. You're encouraged to examine the +implementation of :func:`inspect.get_annotations` in the +current Python version and follow a similar approach. + +In a nutshell, if you wish to evaluate a stringized annotation +on an arbitrary object ``o``: + +* If ``o`` is a module, use ``o.__dict__`` as the + ``globals`` when calling :func:`eval`. +* If ``o`` is a class, use ``sys.modules[o.__module__].__dict__`` + as the ``globals``, and ``dict(vars(o))`` as the ``locals``, + when calling :func:`eval`. +* If ``o`` is a wrapped callable using :func:`functools.update_wrapper`, + :func:`functools.wraps`, or :func:`functools.partial`, iteratively + unwrap it by accessing either ``o.__wrapped__`` or ``o.func`` as + appropriate, until you have found the root unwrapped function. +* If ``o`` is a callable (but not a class), use + ``o.__globals__`` as the globals when calling :func:`eval`. + +However, not all string values used as annotations can +be successfully turned into Python values by :func:`eval`. +String values could theoretically contain any valid string, +and in practice there are valid use cases for type hints that +require annotating with string values that specifically +*can't* be evaluated. For example: + +* :pep:`604` union types using ``|``, before support for this + was added to Python 3.10. +* Definitions that aren't needed at runtime, only imported + when :const:`typing.TYPE_CHECKING` is true. + +If :func:`eval` attempts to evaluate such values, it will +fail and raise an exception. So, when designing a library +API that works with annotations, it's recommended to only +attempt to evaluate string values when explicitly requested +to by the caller. Best Practices For ``__annotations__`` In Any Python Version ============================================================ - * You should avoid assigning to the ``__annotations__`` member - of objects directly. Let Python manage setting ``__annotations__``. +* You should avoid assigning to the ``__annotations__`` member + of objects directly. Let Python manage setting ``__annotations__``. - * If you do assign directly to the ``__annotations__`` member - of an object, you should always set it to a ``dict`` object. +* If you do assign directly to the ``__annotations__`` member + of an object, you should always set it to a ``dict`` object. - * If you directly access the ``__annotations__`` member - of an object, you should ensure that it's a - dictionary before attempting to examine its contents. +* If you directly access the ``__annotations__`` member + of an object, you should ensure that it's a + dictionary before attempting to examine its contents. - * You should avoid modifying ``__annotations__`` dicts. +* You should avoid modifying ``__annotations__`` dicts. - * You should avoid deleting the ``__annotations__`` attribute - of an object. +* You should avoid deleting the ``__annotations__`` attribute + of an object. ``__annotations__`` Quirks ========================== - In all versions of Python 3, function - objects lazy-create an annotations dict if no annotations - are defined on that object. You can delete the ``__annotations__`` - attribute using ``del fn.__annotations__``, but if you then - access ``fn.__annotations__`` the object will create a new empty dict - that it will store and return as its annotations. Deleting the - annotations on a function before it has lazily created its annotations - dict will throw an ``AttributeError``; using ``del fn.__annotations__`` - twice in a row is guaranteed to always throw an ``AttributeError``. - - Everything in the above paragraph also applies to class and module - objects in Python 3.10 and newer. - - In all versions of Python 3, you can set ``__annotations__`` - on a function object to ``None``. However, subsequently - accessing the annotations on that object using ``fn.__annotations__`` - will lazy-create an empty dictionary as per the first paragraph of - this section. This is *not* true of modules and classes, in any Python - version; those objects permit setting ``__annotations__`` to any - Python value, and will retain whatever value is set. - - If Python stringizes your annotations for you - (using ``from __future__ import annotations``), and you - specify a string as an annotation, the string will - itself be quoted. In effect the annotation is quoted - *twice.* For example:: - - from __future__ import annotations - def foo(a: "str"): pass - - print(foo.__annotations__) - - This prints ``{'a': "'str'"}``. This shouldn't really be considered - a "quirk"; it's mentioned here simply because it might be surprising. +In all versions of Python 3, function +objects lazy-create an annotations dict if no annotations +are defined on that object. You can delete the ``__annotations__`` +attribute using ``del fn.__annotations__``, but if you then +access ``fn.__annotations__`` the object will create a new empty dict +that it will store and return as its annotations. Deleting the +annotations on a function before it has lazily created its annotations +dict will throw an ``AttributeError``; using ``del fn.__annotations__`` +twice in a row is guaranteed to always throw an ``AttributeError``. + +Everything in the above paragraph also applies to class and module +objects in Python 3.10 and newer. + +In all versions of Python 3, you can set ``__annotations__`` +on a function object to ``None``. However, subsequently +accessing the annotations on that object using ``fn.__annotations__`` +will lazy-create an empty dictionary as per the first paragraph of +this section. This is *not* true of modules and classes, in any Python +version; those objects permit setting ``__annotations__`` to any +Python value, and will retain whatever value is set. + +If Python stringizes your annotations for you +(using ``from __future__ import annotations``), and you +specify a string as an annotation, the string will +itself be quoted. In effect the annotation is quoted +*twice.* For example:: + + from __future__ import annotations + def foo(a: "str"): pass + + print(foo.__annotations__) + +This prints ``{'a': "'str'"}``. This shouldn't really be considered +a "quirk"; it's mentioned here simply because it might be surprising. diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index 52e98fa9620194..ae5bab90bf8131 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -788,6 +788,59 @@ but not both at the same time: -q, --quiet +How to translate the argparse output +==================================== + +The output of the :mod:`argparse` module such as its help text and error +messages are all made translatable using the :mod:`gettext` module. This +allows applications to easily localize messages produced by +:mod:`argparse`. See also :ref:`i18n-howto`. + +For instance, in this :mod:`argparse` output: + +.. code-block:: shell-session + + $ python prog.py --help + usage: prog.py [-h] [-v | -q] x y + + calculate X to the power of Y + + positional arguments: + x the base + y the exponent + + options: + -h, --help show this help message and exit + -v, --verbose + -q, --quiet + +The strings ``usage:``, ``positional arguments:``, ``options:`` and +``show this help message and exit`` are all translatable. + +In order to translate these strings, they must first be extracted +into a ``.po`` file. For example, using `Babel `__, +run this command: + +.. code-block:: shell-session + + $ pybabel extract -o messages.po /usr/lib/python3.12/argparse.py + +This command will extract all translatable strings from the :mod:`argparse` +module and output them into a file named ``messages.po``. This command assumes +that your Python installation is in ``/usr/lib``. + +You can find out the location of the :mod:`argparse` module on your system +using this script:: + + import argparse + print(argparse.__file__) + +Once the messages in the ``.po`` file are translated and the translations are +installed using :mod:`gettext`, :mod:`argparse` will be able to display the +translated messages. + +To translate your own strings in the :mod:`argparse` output, use :mod:`gettext`. + Conclusion ========== diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index efeb22c618b512..060977246149cf 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,1826 +1,14 @@ -.. highlight:: c +:orphan: -.. _howto-clinic: +.. This page is retained solely for existing links to /howto/clinic.html. + Direct readers to the devguide. ********************** Argument Clinic How-To ********************** -:author: Larry Hastings +.. note:: -.. topic:: Abstract - - Argument Clinic is a preprocessor for CPython C files. - Its purpose is to automate all the boilerplate involved - with writing argument parsing code for "builtins". - This document shows you how to convert your first C - function to work with Argument Clinic, and then introduces - some advanced topics on Argument Clinic usage. - - Currently Argument Clinic is considered internal-only - for CPython. Its use is not supported for files outside - CPython, and no guarantees are made regarding backwards - compatibility for future versions. In other words: if you - maintain an external C extension for CPython, you're welcome - to experiment with Argument Clinic in your own code. But the - version of Argument Clinic that ships with the next version - of CPython *could* be totally incompatible and break all your code. - - -The goals of Argument Clinic -============================ - -Argument Clinic's primary goal -is to take over responsibility for all argument parsing code -inside CPython. This means that, when you convert a function -to work with Argument Clinic, that function should no longer -do any of its own argument parsing—the code generated by -Argument Clinic should be a "black box" to you, where CPython -calls in at the top, and your code gets called at the bottom, -with ``PyObject *args`` (and maybe ``PyObject *kwargs``) -magically converted into the C variables and types you need. - -In order for Argument Clinic to accomplish its primary goal, -it must be easy to use. Currently, working with CPython's -argument parsing library is a chore, requiring maintaining -redundant information in a surprising number of places. -When you use Argument Clinic, you don't have to repeat yourself. - -Obviously, no one would want to use Argument Clinic unless -it's solving their problem—and without creating new problems of -its own. -So it's paramount that Argument Clinic generate correct code. -It'd be nice if the code was faster, too, but at the very least -it should not introduce a major speed regression. (Eventually Argument -Clinic *should* make a major speedup possible—we could -rewrite its code generator to produce tailor-made argument -parsing code, rather than calling the general-purpose CPython -argument parsing library. That would make for the fastest -argument parsing possible!) - -Additionally, Argument Clinic must be flexible enough to -work with any approach to argument parsing. Python has -some functions with some very strange parsing behaviors; -Argument Clinic's goal is to support all of them. - -Finally, the original motivation for Argument Clinic was -to provide introspection "signatures" for CPython builtins. -It used to be, the introspection query functions would throw -an exception if you passed in a builtin. With Argument -Clinic, that's a thing of the past! - -One idea you should keep in mind, as you work with -Argument Clinic: the more information you give it, the -better job it'll be able to do. -Argument Clinic is admittedly relatively simple right -now. But as it evolves it will get more sophisticated, -and it should be able to do many interesting and smart -things with all the information you give it. - - -Basic concepts and usage -======================== - -Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. -If you run that script, specifying a C file as an argument: - -.. code-block:: shell-session - - $ python Tools/clinic/clinic.py foo.c - -Argument Clinic will scan over the file looking for lines that -look exactly like this: - -.. code-block:: none - - /*[clinic input] - -When it finds one, it reads everything up to a line that looks -exactly like this: - -.. code-block:: none - - [clinic start generated code]*/ - -Everything in between these two lines is input for Argument Clinic. -All of these lines, including the beginning and ending comment -lines, are collectively called an Argument Clinic "block". - -When Argument Clinic parses one of these blocks, it -generates output. This output is rewritten into the C file -immediately after the block, followed by a comment containing a checksum. -The Argument Clinic block now looks like this: - -.. code-block:: none - - /*[clinic input] - ... clinic input goes here ... - [clinic start generated code]*/ - ... clinic output goes here ... - /*[clinic end generated code: checksum=...]*/ - -If you run Argument Clinic on the same file a second time, Argument Clinic -will discard the old output and write out the new output with a fresh checksum -line. However, if the input hasn't changed, the output won't change either. - -You should never modify the output portion of an Argument Clinic block. Instead, -change the input until it produces the output you want. (That's the purpose of the -checksum—to detect if someone changed the output, as these edits would be lost -the next time Argument Clinic writes out fresh output.) - -For the sake of clarity, here's the terminology we'll use with Argument Clinic: - -* The first line of the comment (``/*[clinic input]``) is the *start line*. -* The last line of the initial comment (``[clinic start generated code]*/``) is the *end line*. -* The last line (``/*[clinic end generated code: checksum=...]*/``) is the *checksum line*. -* In between the start line and the end line is the *input*. -* In between the end line and the checksum line is the *output*. -* All the text collectively, from the start line to the checksum line inclusively, - is the *block*. (A block that hasn't been successfully processed by Argument - Clinic yet doesn't have output or a checksum line, but it's still considered - a block.) - - -Converting your first function -============================== - -The best way to get a sense of how Argument Clinic works is to -convert a function to work with it. Here, then, are the bare -minimum steps you'd need to follow to convert a function to -work with Argument Clinic. Note that for code you plan to -check in to CPython, you really should take the conversion farther, -using some of the advanced concepts you'll see later on in -the document (like "return converters" and "self converters"). -But we'll keep it simple for this walkthrough so you can learn. - -Let's dive in! - -0. Make sure you're working with a freshly updated checkout - of the CPython trunk. - -1. Find a Python builtin that calls either :c:func:`PyArg_ParseTuple` - or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted - to work with Argument Clinic yet. - For my example I'm using ``_pickle.Pickler.dump()``. - -2. If the call to the ``PyArg_Parse`` function uses any of the - following format units: - - .. code-block:: none - - O& - O! - es - es# - et - et# - - or if it has multiple calls to :c:func:`PyArg_ParseTuple`, - you should choose a different function. Argument Clinic *does* - support all of these scenarios. But these are advanced - topics—let's do something simpler for your first function. - - Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple` - or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different - types for the same argument, or if the function uses something besides - PyArg_Parse functions to parse its arguments, it probably - isn't suitable for conversion to Argument Clinic. Argument Clinic - doesn't support generic functions or polymorphic parameters. - -3. Add the following boilerplate above the function, creating our block:: - - /*[clinic input] - [clinic start generated code]*/ - -4. Cut the docstring and paste it in between the ``[clinic]`` lines, - removing all the junk that makes it a properly quoted C string. - When you're done you should have just the text, based at the left - margin, with no line wider than 80 characters. - (Argument Clinic will preserve indents inside the docstring.) - - If the old docstring had a first line that looked like a function - signature, throw that line away. (The docstring doesn't need it - anymore—when you use ``help()`` on your builtin in the future, - the first line will be built automatically based on the function's - signature.) - - Sample:: - - /*[clinic input] - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -5. If your docstring doesn't have a "summary" line, Argument Clinic will - complain. So let's make sure it has one. The "summary" line should - be a paragraph consisting of a single 80-column line - at the beginning of the docstring. - - (Our example docstring consists solely of a summary line, so the sample - code doesn't have to change for this step.) - -6. Above the docstring, enter the name of the function, followed - by a blank line. This should be the Python name of the function, - and should be the full dotted path - to the function—it should start with the name of the module, - include any sub-modules, and if the function is a method on - a class it should include the class name too. - - Sample:: - - /*[clinic input] - _pickle.Pickler.dump - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -7. If this is the first time that module or class has been used with Argument - Clinic in this C file, - you must declare the module and/or class. Proper Argument Clinic hygiene - prefers declaring these in a separate block somewhere near the - top of the C file, in the same way that include files and statics go at - the top. (In our sample code we'll just show the two blocks next to - each other.) - - The name of the class and module should be the same as the one - seen by Python. Check the name defined in the :c:type:`PyModuleDef` - or :c:type:`PyTypeObject` as appropriate. - - When you declare a class, you must also specify two aspects of its type - in C: the type declaration you'd use for a pointer to an instance of - this class, and a pointer to the :c:type:`PyTypeObject` for this class. - - Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - - - - -8. Declare each of the parameters to the function. Each parameter - should get its own line. All the parameter lines should be - indented from the function name and the docstring. - - The general form of these parameter lines is as follows: - - .. code-block:: none - - name_of_parameter: converter - - If the parameter has a default value, add that after the - converter: - - .. code-block:: none - - name_of_parameter: converter = default_value - - Argument Clinic's support for "default values" is quite sophisticated; - please see :ref:`the section below on default values ` - for more information. - - Add a blank line below the parameters. - - What's a "converter"? It establishes both the type - of the variable used in C, and the method to convert the Python - value into a C value at runtime. - For now you're going to use what's called a "legacy converter"—a - convenience syntax intended to make porting old code into Argument - Clinic easier. - - For each parameter, copy the "format unit" for that - parameter from the ``PyArg_Parse()`` format argument and - specify *that* as its converter, as a quoted - string. ("format unit" is the formal name for the one-to-three - character substring of the ``format`` parameter that tells - the argument parsing function what the type of the variable - is and how to convert it. For more on format units please - see :ref:`arg-parsing`.) - - For multicharacter format units like ``z#``, use the - entire two-or-three character string. - - Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -9. If your function has ``|`` in the format string, meaning some - parameters have default values, you can ignore it. Argument - Clinic infers which parameters are optional based on whether - or not they have default values. - - If your function has ``$`` in the format string, meaning it - takes keyword-only arguments, specify ``*`` on a line by - itself before the first keyword-only argument, indented the - same as the parameter lines. - - (``_pickle.Pickler.dump`` has neither, so our sample is unchanged.) - - -10. If the existing C function calls :c:func:`PyArg_ParseTuple` - (as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its - arguments are positional-only. - - To mark all parameters as positional-only in Argument Clinic, - add a ``/`` on a line by itself after the last parameter, - indented the same as the parameter lines. - - Currently this is all-or-nothing; either all parameters are - positional-only, or none of them are. (In the future Argument - Clinic may relax this restriction.) - - Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -11. It's helpful to write a per-parameter docstring for each parameter. - But per-parameter docstrings are optional; you can skip this step - if you prefer. - - Here's how to add a per-parameter docstring. The first line - of the per-parameter docstring must be indented further than the - parameter definition. The left margin of this first line establishes - the left margin for the whole per-parameter docstring; all the text - you write will be outdented by this amount. You can write as much - text as you like, across multiple lines if you wish. - - Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -12. Save and close the file, then run ``Tools/clinic/clinic.py`` on - it. With luck everything worked---your block now has output, and - a ``.c.h`` file has been generated! Reopen the file in your - text editor to see:: - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - - static PyObject * - _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ - - Obviously, if Argument Clinic didn't produce any output, it's because - it found an error in your input. Keep fixing your errors and retrying - until Argument Clinic processes your file without complaint. - - For readability, most of the glue code has been generated to a ``.c.h`` - file. You'll need to include that in your original ``.c`` file, - typically right after the clinic module block:: - - #include "clinic/_pickle.c.h" - -13. Double-check that the argument-parsing code Argument Clinic generated - looks basically the same as the existing code. - - First, ensure both places use the same argument-parsing function. - The existing code must call either - :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; - ensure that the code generated by Argument Clinic calls the - *exact* same function. - - Second, the format string passed in to :c:func:`PyArg_ParseTuple` or - :c:func:`PyArg_ParseTupleAndKeywords` should be *exactly* the same - as the hand-written one in the existing function, up to the colon - or semi-colon. - - (Argument Clinic always generates its format strings - with a ``:`` followed by the name of the function. If the - existing code's format string ends with ``;``, to provide - usage help, this change is harmless—don't worry about it.) - - Third, for parameters whose format units require two arguments - (like a length variable, or an encoding string, or a pointer - to a conversion function), ensure that the second argument is - *exactly* the same between the two invocations. - - Fourth, inside the output portion of the block you'll find a preprocessor - macro defining the appropriate static :c:type:`PyMethodDef` structure for - this builtin:: - - #define __PICKLE_PICKLER_DUMP_METHODDEF \ - {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, - - This static structure should be *exactly* the same as the existing static - :c:type:`PyMethodDef` structure for this builtin. - - If any of these items differ in *any way*, - adjust your Argument Clinic function specification and rerun - ``Tools/clinic/clinic.py`` until they *are* the same. - - -14. Notice that the last line of its output is the declaration - of your "impl" function. This is where the builtin's implementation goes. - Delete the existing prototype of the function you're modifying, but leave - the opening curly brace. Now delete its argument parsing code and the - declarations of all the variables it dumps the arguments into. - Notice how the Python arguments are now arguments to this impl function; - if the implementation used different names for these variables, fix it. - - Let's reiterate, just because it's kind of weird. Your code should now - look like this:: - - static return_type - your_function_impl(...) - /*[clinic end generated code: checksum=...]*/ - { - ... - - Argument Clinic generated the checksum line and the function prototype just - above it. You should write the opening (and closing) curly braces for the - function, and the implementation inside. - - Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - - PyDoc_STRVAR(__pickle_Pickler_dump__doc__, - "Write a pickled representation of obj to the open file.\n" - "\n" - ... - static PyObject * - _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ - { - /* Check whether the Pickler was initialized correctly (issue3664). - Developers often forget to call __init__() in their subclasses, which - would trigger a segfault without this check. */ - if (self->write == NULL) { - PyErr_Format(PicklingError, - "Pickler.__init__() was not called by %s.__init__()", - Py_TYPE(self)->tp_name); - return NULL; - } - - if (_Pickler_ClearBuffer(self) < 0) - return NULL; - - ... - -15. Remember the macro with the :c:type:`PyMethodDef` structure for this - function? Find the existing :c:type:`PyMethodDef` structure for this - function and replace it with a reference to the macro. (If the builtin - is at module scope, this will probably be very near the end of the file; - if the builtin is a class method, this will probably be below but relatively - near to the implementation.) - - Note that the body of the macro contains a trailing comma. So when you - replace the existing static :c:type:`PyMethodDef` structure with the macro, - *don't* add a comma to the end. - - Sample:: - - static struct PyMethodDef Pickler_methods[] = { - __PICKLE_PICKLER_DUMP_METHODDEF - __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF - {NULL, NULL} /* sentinel */ - }; - - -16. Argument Clinic may generate new instances of ``_Py_ID``. For example:: - - &_Py_ID(new_unique_py_id) - - If it does, you'll have to run ``Tools/scripts/generate_global_objects.py`` - to regenerate the list of precompiled identifiers at this point. - - -17. Compile, then run the relevant portions of the regression-test suite. - This change should not introduce any new compile-time warnings or errors, - and there should be no externally visible change to Python's behavior. - - Well, except for one difference: ``inspect.signature()`` run on your function - should now provide a valid signature! - - Congratulations, you've ported your first function to work with Argument Clinic! - - -How-to guides -============= - - -How to to rename C functions and variables generated by Argument Clinic ------------------------------------------------------------------------ - -Argument Clinic automatically names the functions it generates for you. -Occasionally this may cause a problem, if the generated name collides with -the name of an existing C function. There's an easy solution: override the names -used for the C functions. Just add the keyword ``"as"`` -to your function declaration line, followed by the function name you wish to use. -Argument Clinic will use that function name for the base (generated) function, -then add ``"_impl"`` to the end and use that for the name of the impl function. - -For example, if we wanted to rename the C function names generated for -``pickle.Pickler.dump``, it'd look like this:: - - /*[clinic input] - pickle.Pickler.dump as pickler_dumper - - ... - -The base function would now be named ``pickler_dumper()``, -and the impl function would now be named ``pickler_dumper_impl()``. - - -Similarly, you may have a problem where you want to give a parameter -a specific Python name, but that name may be inconvenient in C. Argument -Clinic allows you to give a parameter different names in Python and in C, -using the same ``"as"`` syntax:: - - /*[clinic input] - pickle.Pickler.dump - - obj: object - file as file_obj: object - protocol: object = NULL - * - fix_imports: bool = True - -Here, the name used in Python (in the signature and the ``keywords`` -array) would be ``file``, but the C variable would be named ``file_obj``. - -You can use this to rename the ``self`` parameter too! - - -How to convert functions using ``PyArg_UnpackTuple`` ----------------------------------------------------- - -To convert a function parsing its arguments with :c:func:`PyArg_UnpackTuple`, -simply write out all the arguments, specifying each as an ``object``. You -may specify the ``type`` argument to cast the type as appropriate. All -arguments should be marked positional-only (add a ``/`` on a line by itself -after the last argument). - -Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this -will change soon. - - -How to use optional groups --------------------------- - -Some legacy functions have a tricky approach to parsing their arguments: -they count the number of positional arguments, then use a ``switch`` statement -to call one of several different :c:func:`PyArg_ParseTuple` calls depending on -how many positional arguments there are. (These functions cannot accept -keyword-only arguments.) This approach was used to simulate optional -arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. - -While functions using this approach can often be converted to -use :c:func:`PyArg_ParseTupleAndKeywords`, optional arguments, and default values, -it's not always possible. Some of these legacy functions have -behaviors :c:func:`PyArg_ParseTupleAndKeywords` doesn't directly support. -The most obvious example is the builtin function ``range()``, which has -an optional argument on the *left* side of its required argument! -Another example is ``curses.window.addch()``, which has a group of two -arguments that must always be specified together. (The arguments are -called ``x`` and ``y``; if you call the function passing in ``x``, -you must also pass in ``y``—and if you don't pass in ``x`` you may not -pass in ``y`` either.) - -In any case, the goal of Argument Clinic is to support argument parsing -for all existing CPython builtins without changing their semantics. -Therefore Argument Clinic supports -this alternate approach to parsing, using what are called *optional groups*. -Optional groups are groups of arguments that must all be passed in together. -They can be to the left or the right of the required arguments. They -can *only* be used with positional-only parameters. - -.. note:: Optional groups are *only* intended for use when converting - functions that make multiple calls to :c:func:`PyArg_ParseTuple`! - Functions that use *any* other approach for parsing arguments - should *almost never* be converted to Argument Clinic using - optional groups. Functions using optional groups currently - cannot have accurate signatures in Python, because Python just - doesn't understand the concept. Please avoid using optional - groups wherever possible. - -To specify an optional group, add a ``[`` on a line by itself before -the parameters you wish to group together, and a ``]`` on a line by itself -after these parameters. As an example, here's how ``curses.window.addch`` -uses optional groups to make the first two parameters and the last -parameter optional:: - - /*[clinic input] - - curses.window.addch - - [ - x: int - X-coordinate. - y: int - Y-coordinate. - ] - - ch: object - Character to add. - - [ - attr: long - Attributes for the character. - ] - / - - ... - - -Notes: - -* For every optional group, one additional parameter will be passed into the - impl function representing the group. The parameter will be an int named - ``group_{direction}_{number}``, - where ``{direction}`` is either ``right`` or ``left`` depending on whether the group - is before or after the required parameters, and ``{number}`` is a monotonically - increasing number (starting at 1) indicating how far away the group is from - the required parameters. When the impl is called, this parameter will be set - to zero if this group was unused, and set to non-zero if this group was used. - (By used or unused, I mean whether or not the parameters received arguments - in this invocation.) - -* If there are no required arguments, the optional groups will behave - as if they're to the right of the required arguments. - -* In the case of ambiguity, the argument parsing code - favors parameters on the left (before the required parameters). - -* Optional groups can only contain positional-only parameters. - -* Optional groups are *only* intended for legacy code. Please do not - use optional groups for new code. - - -How to use real Argument Clinic converters, instead of "legacy converters" --------------------------------------------------------------------------- - -To save time, and to minimize how much you need to learn -to achieve your first port to Argument Clinic, the walkthrough above tells -you to use "legacy converters". "Legacy converters" are a convenience, -designed explicitly to make porting existing code to Argument Clinic -easier. And to be clear, their use is acceptable when porting code for -Python 3.4. - -However, in the long term we probably want all our blocks to -use Argument Clinic's real syntax for converters. Why? A couple -reasons: - -* The proper converters are far easier to read and clearer in their intent. -* There are some format units that are unsupported as "legacy converters", - because they require arguments, and the legacy converter syntax doesn't - support specifying arguments. -* In the future we may have a new argument parsing library that isn't - restricted to what :c:func:`PyArg_ParseTuple` supports; this flexibility - won't be available to parameters using legacy converters. - -Therefore, if you don't mind a little extra effort, please use the normal -converters instead of legacy converters. - -In a nutshell, the syntax for Argument Clinic (non-legacy) converters -looks like a Python function call. However, if there are no explicit -arguments to the function (all functions take their default values), -you may omit the parentheses. Thus ``bool`` and ``bool()`` are exactly -the same converters. - -All arguments to Argument Clinic converters are keyword-only. -All Argument Clinic converters accept the following arguments: - - ``c_default`` - The default value for this parameter when defined in C. - Specifically, this will be the initializer for the variable declared - in the "parse function". See :ref:`the section on default values ` - for how to use this. - Specified as a string. - - ``annotation`` - The annotation value for this parameter. Not currently supported, - because :pep:`8` mandates that the Python library may not use - annotations. - - ``unused`` - Wrap the argument with :c:macro:`Py_UNUSED` in the impl function signature. - -In addition, some converters accept additional arguments. Here is a list -of these arguments, along with their meanings: - - ``accept`` - A set of Python types (and possibly pseudo-types); - this restricts the allowable Python argument to values of these types. - (This is not a general-purpose facility; as a rule it only supports - specific lists of types as shown in the legacy converter table.) - - To accept ``None``, add ``NoneType`` to this set. - - ``bitwise`` - Only supported for unsigned integers. The native integer value of this - Python argument will be written to the parameter without any range checking, - even for negative values. - - ``converter`` - Only supported by the ``object`` converter. Specifies the name of a - :ref:`C "converter function" ` - to use to convert this object to a native type. - - ``encoding`` - Only supported for strings. Specifies the encoding to use when converting - this string from a Python str (Unicode) value into a C ``char *`` value. - - - ``subclass_of`` - Only supported for the ``object`` converter. Requires that the Python - value be a subclass of a Python type, as expressed in C. - - ``type`` - Only supported for the ``object`` and ``self`` converters. Specifies - the C type that will be used to declare the variable. Default value is - ``"PyObject *"``. - - ``zeroes`` - Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are - permitted inside the value. The length of the string will be passed in - to the impl function, just after the string parameter, as a parameter named - ``_length``. - -Please note, not every possible combination of arguments will work. -Usually these arguments are implemented by specific ``PyArg_ParseTuple`` -*format units*, with specific behavior. For example, currently you cannot -call ``unsigned_short`` without also specifying ``bitwise=True``. -Although it's perfectly reasonable to think this would work, these semantics don't -map to any existing format unit. So Argument Clinic doesn't support it. (Or, at -least, not yet.) - -Below is a table showing the mapping of legacy converters into real -Argument Clinic converters. On the left is the legacy converter, -on the right is the text you'd replace it with. - -========= ================================================================================= -``'B'`` ``unsigned_char(bitwise=True)`` -``'b'`` ``unsigned_char`` -``'c'`` ``char`` -``'C'`` ``int(accept={str})`` -``'d'`` ``double`` -``'D'`` ``Py_complex`` -``'es'`` ``str(encoding='name_of_encoding')`` -``'es#'`` ``str(encoding='name_of_encoding', zeroes=True)`` -``'et'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str})`` -``'et#'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str}, zeroes=True)`` -``'f'`` ``float`` -``'h'`` ``short`` -``'H'`` ``unsigned_short(bitwise=True)`` -``'i'`` ``int`` -``'I'`` ``unsigned_int(bitwise=True)`` -``'k'`` ``unsigned_long(bitwise=True)`` -``'K'`` ``unsigned_long_long(bitwise=True)`` -``'l'`` ``long`` -``'L'`` ``long long`` -``'n'`` ``Py_ssize_t`` -``'O'`` ``object`` -``'O!'`` ``object(subclass_of='&PySomething_Type')`` -``'O&'`` ``object(converter='name_of_c_function')`` -``'p'`` ``bool`` -``'S'`` ``PyBytesObject`` -``'s'`` ``str`` -``'s#'`` ``str(zeroes=True)`` -``'s*'`` ``Py_buffer(accept={buffer, str})`` -``'U'`` ``unicode`` -``'u'`` ``wchar_t`` -``'u#'`` ``wchar_t(zeroes=True)`` -``'w*'`` ``Py_buffer(accept={rwbuffer})`` -``'Y'`` ``PyByteArrayObject`` -``'y'`` ``str(accept={bytes})`` -``'y#'`` ``str(accept={robuffer}, zeroes=True)`` -``'y*'`` ``Py_buffer`` -``'Z'`` ``wchar_t(accept={str, NoneType})`` -``'Z#'`` ``wchar_t(accept={str, NoneType}, zeroes=True)`` -``'z'`` ``str(accept={str, NoneType})`` -``'z#'`` ``str(accept={str, NoneType}, zeroes=True)`` -``'z*'`` ``Py_buffer(accept={buffer, str, NoneType})`` -========= ================================================================================= - -As an example, here's our sample ``pickle.Pickler.dump`` using the proper -converter:: - - /*[clinic input] - pickle.Pickler.dump - - obj: object - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -One advantage of real converters is that they're more flexible than legacy -converters. For example, the ``unsigned_int`` converter (and all the -``unsigned_`` converters) can be specified without ``bitwise=True``. Their -default behavior performs range checking on the value, and they won't accept -negative numbers. You just can't do that with a legacy converter! - -Argument Clinic will show you all the converters it has -available. For each converter it'll show you all the parameters -it accepts, along with the default value for each parameter. -Just run ``Tools/clinic/clinic.py --converters`` to see the full list. - - -How to use the ``Py_buffer`` converter --------------------------------------- - -When using the ``Py_buffer`` converter -(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), -you *must* not call :c:func:`PyBuffer_Release` on the provided buffer. -Argument Clinic generates code that does it for you (in the parsing function). - - -How to use advanced converters ------------------------------- - -Remember those format units you skipped for your first -time because they were advanced? Here's how to handle those too. - -The trick is, all those format units take arguments—either -conversion functions, or types, or strings specifying an encoding. -(But "legacy converters" don't support arguments. That's why we -skipped them for your first function.) The argument you specified -to the format unit is now an argument to the converter; this -argument is either ``converter`` (for ``O&``), ``subclass_of`` (for ``O!``), -or ``encoding`` (for all the format units that start with ``e``). - -When using ``subclass_of``, you may also want to use the other -custom argument for ``object()``: ``type``, which lets you set the type -actually used for the parameter. For example, if you want to ensure -that the object is a subclass of ``PyUnicode_Type``, you probably want -to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. - -One possible problem with using Argument Clinic: it takes away some possible -flexibility for the format units starting with ``e``. When writing a -``PyArg_Parse`` call by hand, you could theoretically decide at runtime what -encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must -be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; -it made supporting this format unit much easier, and may allow for future optimizations. -This restriction doesn't seem unreasonable; CPython itself always passes in static -hard-coded encoding strings for parameters whose format units start with ``e``. - - -.. _default_values: - -How to assign default values to parameter ------------------------------------------ - -Default values for parameters can be any of a number of values. -At their simplest, they can be string, int, or float literals: - -.. code-block:: none - - foo: str = "abc" - bar: int = 123 - bat: float = 45.6 - -They can also use any of Python's built-in constants: - -.. code-block:: none - - yep: bool = True - nope: bool = False - nada: object = None - -There's also special support for a default value of ``NULL``, and -for simple expressions, documented in the following sections. - - -The ``NULL`` default value -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -For string and object parameters, you can set them to ``None`` to indicate -that there's no default. However, that means the C variable will be -initialized to ``Py_None``. For convenience's sakes, there's a special -value called ``NULL`` for just this reason: from Python's perspective it -behaves like a default value of ``None``, but the C variable is initialized -with ``NULL``. - - -Symbolic default values -^^^^^^^^^^^^^^^^^^^^^^^ - -The default value you provide for a parameter can't be any arbitrary -expression. Currently the following are explicitly supported: - -* Numeric constants (integer and float) -* String constants -* ``True``, ``False``, and ``None`` -* Simple symbolic constants like ``sys.maxsize``, which must - start with the name of the module - -(In the future, this may need to get even more elaborate, -to allow full expressions like ``CONSTANT - 1``.) - - -Expressions as default values -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The default value for a parameter can be more than just a literal value. -It can be an entire expression, using math operators and looking up attributes -on objects. However, this support isn't exactly simple, because of some -non-obvious semantics. - -Consider the following example: - -.. code-block:: none - - foo: Py_ssize_t = sys.maxsize - 1 - -``sys.maxsize`` can have different values on different platforms. Therefore -Argument Clinic can't simply evaluate that expression locally and hard-code it -in C. So it stores the default in such a way that it will get evaluated at -runtime, when the user asks for the function's signature. - -What namespace is available when the expression is evaluated? It's evaluated -in the context of the module the builtin came from. So, if your module has an -attribute called "``max_widgets``", you may simply use it: - -.. code-block:: none - - foo: Py_ssize_t = max_widgets - -If the symbol isn't found in the current module, it fails over to looking in -``sys.modules``. That's how it can find ``sys.maxsize`` for example. (Since you -don't know in advance what modules the user will load into their interpreter, -it's best to restrict yourself to modules that are preloaded by Python itself.) - -Evaluating default values only at runtime means Argument Clinic can't compute -the correct equivalent C default value. So you need to tell it explicitly. -When you use an expression, you must also specify the equivalent expression -in C, using the ``c_default`` parameter to the converter: - -.. code-block:: none - - foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1 - -Another complication: Argument Clinic can't know in advance whether or not the -expression you supply is valid. It parses it to make sure it looks legal, but -it can't *actually* know. You must be very careful when using expressions to -specify values that are guaranteed to be valid at runtime! - -Finally, because expressions must be representable as static C values, there -are many restrictions on legal expressions. Here's a list of Python features -you're not permitted to use: - -* Function calls. -* Inline if statements (``3 if foo else 5``). -* Automatic sequence unpacking (``*[1, 2, 3]``). -* List/set/dict comprehensions and generator expressions. -* Tuple/list/set/dict literals. - - -How to use return converters ----------------------------- - -By default, the impl function Argument Clinic generates for you returns -:c:type:`PyObject * `. -But your C function often computes some C type, -then converts it into the :c:type:`!PyObject *` -at the last moment. Argument Clinic handles converting your inputs from Python types -into native C types—why not have it convert your return value from a native C type -into a Python type too? - -That's what a "return converter" does. It changes your impl function to return -some C type, then adds code to the generated (non-impl) function to handle converting -that value into the appropriate :c:type:`!PyObject *`. - -The syntax for return converters is similar to that of parameter converters. -You specify the return converter like it was a return annotation on the -function itself, using ``->`` notation. - -For example: - -.. code-block:: c - - /*[clinic input] - add -> int - - a: int - b: int - / - - [clinic start generated code]*/ - -Return converters behave much the same as parameter converters; -they take arguments, the arguments are all keyword-only, and if you're not changing -any of the default arguments you can omit the parentheses. - -(If you use both ``"as"`` *and* a return converter for your function, -the ``"as"`` should come before the return converter.) - -There's one additional complication when using return converters: how do you -indicate an error has occurred? Normally, a function returns a valid (non-``NULL``) -pointer for success, and ``NULL`` for failure. But if you use an integer return converter, -all integers are valid. How can Argument Clinic detect an error? Its solution: each return -converter implicitly looks for a special value that indicates an error. If you return -that value, and an error has been set (``PyErr_Occurred()`` returns a true -value), then the generated code will propagate the error. Otherwise it will -encode the value you return like normal. - -Currently Argument Clinic supports only a few return converters: - -.. code-block:: none - - bool - double - float - int - long - Py_ssize_t - size_t - unsigned int - unsigned long - -None of these take parameters. -For all of these, return ``-1`` to indicate error. - -To see all the return converters Argument Clinic supports, along with -their parameters (if any), -just run ``Tools/clinic/clinic.py --converters`` for the full list. - - -How to clone existing functions -------------------------------- - -If you have a number of functions that look similar, you may be able to -use Clinic's "clone" feature. When you clone an existing function, -you reuse: - -* its parameters, including - - * their names, - - * their converters, with all parameters, - - * their default values, - - * their per-parameter docstrings, - - * their *kind* (whether they're positional only, - positional or keyword, or keyword only), and - -* its return converter. - -The only thing not copied from the original function is its docstring; -the syntax allows you to specify a new docstring. - -Here's the syntax for cloning a function:: - - /*[clinic input] - module.class.new_function [as c_basename] = module.class.existing_function - - Docstring for new_function goes here. - [clinic start generated code]*/ - -(The functions can be in different modules or classes. I wrote -``module.class`` in the sample just to illustrate that you must -use the full path to *both* functions.) - -Sorry, there's no syntax for partially cloning a function, or cloning a function -then modifying it. Cloning is an all-or nothing proposition. - -Also, the function you are cloning from must have been previously defined -in the current file. - - -How to call Python code ------------------------ - -The rest of the advanced topics require you to write Python code -which lives inside your C file and modifies Argument Clinic's -runtime state. This is simple: you simply define a Python block. - -A Python block uses different delimiter lines than an Argument -Clinic function block. It looks like this:: - - /*[python input] - # python code goes here - [python start generated code]*/ - -All the code inside the Python block is executed at the -time it's parsed. All text written to stdout inside the block -is redirected into the "output" after the block. - -As an example, here's a Python block that adds a static integer -variable to the C code:: - - /*[python input] - print('static int __ignored_unused_variable__ = 0;') - [python start generated code]*/ - static int __ignored_unused_variable__ = 0; - /*[python checksum:...]*/ - - -How to use the "self converter" -------------------------------- - -Argument Clinic automatically adds a "self" parameter for you -using a default converter. It automatically sets the ``type`` -of this parameter to the "pointer to an instance" you specified -when you declared the type. However, you can override -Argument Clinic's converter and specify one yourself. -Just add your own ``self`` parameter as the first parameter in a -block, and ensure that its converter is an instance of -``self_converter`` or a subclass thereof. - -What's the point? This lets you override the type of ``self``, -or give it a different default name. - -How do you specify the custom type you want to cast ``self`` to? -If you only have one or two functions with the same type for ``self``, -you can directly use Argument Clinic's existing ``self`` converter, -passing in the type you want to use as the ``type`` parameter:: - - /*[clinic input] - - _pickle.Pickler.dump - - self: self(type="PicklerObject *") - obj: object - / - - Write a pickled representation of the given object to the open file. - [clinic start generated code]*/ - -On the other hand, if you have a lot of functions that will use the same -type for ``self``, it's best to create your own converter, subclassing -``self_converter`` but overwriting the ``type`` member:: - - /*[python input] - class PicklerObject_converter(self_converter): - type = "PicklerObject *" - [python start generated code]*/ - - /*[clinic input] - - _pickle.Pickler.dump - - self: PicklerObject - obj: object - / - - Write a pickled representation of the given object to the open file. - [clinic start generated code]*/ - - -How to use the "defining class" converter ------------------------------------------ - -Argument Clinic facilitates gaining access to the defining class of a method. -This is useful for :ref:`heap type ` methods that need to fetch -module level state. Use :c:func:`PyType_FromModuleAndSpec` to associate a new -heap type with a module. You can now use :c:func:`PyType_GetModuleState` on -the defining class to fetch the module state, for example from a module method. - -Example from ``Modules/zlibmodule.c``. First, ``defining_class`` is added to -the clinic input:: - - /*[clinic input] - zlib.Compress.compress - - cls: defining_class - data: Py_buffer - Binary data to be compressed. - / - - -After running the Argument Clinic tool, the following function signature is -generated:: - - /*[clinic start generated code]*/ - static PyObject * - zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, - Py_buffer *data) - /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ - - -The following code can now use ``PyType_GetModuleState(cls)`` to fetch the -module state:: - - zlibstate *state = PyType_GetModuleState(cls); - - -Each method may only have one argument using this converter, and it must appear -after ``self``, or, if ``self`` is not used, as the first argument. The argument -will be of type ``PyTypeObject *``. The argument will not appear in the -``__text_signature__``. - -The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` -methods, which cannot use the ``METH_METHOD`` convention. - -It is not possible to use ``defining_class`` with slot methods. In order to -fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` -to look up the module and then :c:func:`PyModule_GetState` to fetch the module -state. Example from the ``setattro`` slot method in -``Modules/_threadmodule.c``:: - - static int - local_setattro(localobject *self, PyObject *name, PyObject *v) - { - PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module); - thread_module_state *state = get_thread_state(module); - ... - } - - -See also :pep:`573`. - - -How to write a custom converter -------------------------------- - -As we hinted at in the previous section... you can write your own converters! -A converter is simply a Python class that inherits from ``CConverter``. -The main purpose of a custom converter is if you have a parameter using -the ``O&`` format unit—parsing this parameter means calling -a :c:func:`PyArg_ParseTuple` "converter function". - -Your converter class should be named ``*something*_converter``. -If the name follows this convention, then your converter class -will be automatically registered with Argument Clinic; its name -will be the name of your class with the ``_converter`` suffix -stripped off. (This is accomplished with a metaclass.) - -You shouldn't subclass ``CConverter.__init__``. Instead, you should -write a ``converter_init()`` function. ``converter_init()`` -always accepts a ``self`` parameter; after that, all additional -parameters *must* be keyword-only. Any arguments passed in to -the converter in Argument Clinic will be passed along to your -``converter_init()``. - -There are some additional members of ``CConverter`` you may wish -to specify in your subclass. Here's the current list: - -``type`` - The C type to use for this variable. - ``type`` should be a Python string specifying the type, e.g. ``int``. - If this is a pointer type, the type string should end with ``' *'``. - -``default`` - The Python default value for this parameter, as a Python value. - Or the magic value ``unspecified`` if there is no default. - -``py_default`` - ``default`` as it should appear in Python code, - as a string. - Or ``None`` if there is no default. - -``c_default`` - ``default`` as it should appear in C code, - as a string. - Or ``None`` if there is no default. - -``c_ignored_default`` - The default value used to initialize the C variable when - there is no default, but not specifying a default may - result in an "uninitialized variable" warning. This can - easily happen when using option groups—although - properly written code will never actually use this value, - the variable does get passed in to the impl, and the - C compiler will complain about the "use" of the - uninitialized value. This value should always be a - non-empty string. - -``converter`` - The name of the C converter function, as a string. - -``impl_by_reference`` - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into the impl function. - -``parse_by_reference`` - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into :c:func:`PyArg_ParseTuple`. - - -Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: - - /*[python input] - - class ssize_t_converter(CConverter): - type = 'Py_ssize_t' - converter = 'ssize_t_converter' - - [python start generated code]*/ - /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ - -This block adds a converter to Argument Clinic named ``ssize_t``. Parameters -declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will -be parsed by the ``'O&'`` format unit, which will call the -``ssize_t_converter`` converter function. ``ssize_t`` variables -automatically support default values. - -More sophisticated custom converters can insert custom C code to -handle initialization and cleanup. -You can see more examples of custom converters in the CPython -source tree; grep the C files for the string ``CConverter``. - - -How to write a custom return converter --------------------------------------- - -Writing a custom return converter is much like writing -a custom converter. Except it's somewhat simpler, because return -converters are themselves much simpler. - -Return converters must subclass ``CReturnConverter``. -There are no examples yet of custom return converters, -because they are not widely used yet. If you wish to -write your own return converter, please read ``Tools/clinic/clinic.py``, -specifically the implementation of ``CReturnConverter`` and -all its subclasses. - - -How to convert ``METH_O`` and ``METH_NOARGS`` functions -------------------------------------------------------- - -To convert a function using ``METH_O``, make sure the function's -single argument is using the ``object`` converter, and mark the -arguments as positional-only:: - - /*[clinic input] - meth_o_sample - - argument: object - / - [clinic start generated code]*/ - - -To convert a function using ``METH_NOARGS``, just don't specify -any arguments. - -You can still use a self converter, a return converter, and specify -a ``type`` argument to the object converter for ``METH_O``. - - -How to convert ``tp_new`` and ``tp_init`` functions ---------------------------------------------------- - -You can convert ``tp_new`` and ``tp_init`` functions. Just name -them ``__new__`` or ``__init__`` as appropriate. Notes: - -* The function name generated for ``__new__`` doesn't end in ``__new__`` - like it would by default. It's just the name of the class, converted - into a valid C identifier. - -* No ``PyMethodDef`` ``#define`` is generated for these functions. - -* ``__init__`` functions return ``int``, not ``PyObject *``. - -* Use the docstring as the class docstring. - -* Although ``__new__`` and ``__init__`` functions must always - accept both the ``args`` and ``kwargs`` objects, when converting - you may specify any signature for these functions that you like. - (If your function doesn't support keywords, the parsing function - generated will throw an exception if it receives any.) - - -How to change and redirect Clinic's output ------------------------------------------- - -It can be inconvenient to have Clinic's output interspersed with -your conventional hand-edited C code. Luckily, Clinic is configurable: -you can buffer up its output for printing later (or earlier!), or write -its output to a separate file. You can also add a prefix or suffix to -every line of Clinic's generated output. - -While changing Clinic's output in this manner can be a boon to readability, -it may result in Clinic code using types before they are defined, or -your code attempting to use Clinic-generated code before it is defined. -These problems can be easily solved by rearranging the declarations in your file, -or moving where Clinic's generated code goes. (This is why the default behavior -of Clinic is to output everything into the current block; while many people -consider this hampers readability, it will never require rearranging your -code to fix definition-before-use problems.) - -Let's start with defining some terminology: - -*field* - A field, in this context, is a subsection of Clinic's output. - For example, the ``#define`` for the ``PyMethodDef`` structure - is a field, called ``methoddef_define``. Clinic has seven - different fields it can output per function definition: - - .. code-block:: none - - docstring_prototype - docstring_definition - methoddef_define - impl_prototype - parser_prototype - parser_definition - impl_definition - - All the names are of the form ``"_"``, - where ``""`` is the semantic object represented (the parsing function, - the impl function, the docstring, or the methoddef structure) and ``""`` - represents what kind of statement the field is. Field names that end in - ``"_prototype"`` - represent forward declarations of that thing, without the actual body/data - of the thing; field names that end in ``"_definition"`` represent the actual - definition of the thing, with the body/data of the thing. (``"methoddef"`` - is special, it's the only one that ends with ``"_define"``, representing that - it's a preprocessor #define.) - -*destination* - A destination is a place Clinic can write output to. There are - five built-in destinations: - - ``block`` - The default destination: printed in the output section of - the current Clinic block. - - ``buffer`` - A text buffer where you can save text for later. Text sent - here is appended to the end of any existing text. It's an - error to have any text left in the buffer when Clinic finishes - processing a file. - - ``file`` - A separate "clinic file" that will be created automatically by Clinic. - The filename chosen for the file is ``{basename}.clinic{extension}``, - where ``basename`` and ``extension`` were assigned the output - from ``os.path.splitext()`` run on the current file. (Example: - the ``file`` destination for ``_pickle.c`` would be written to - ``_pickle.clinic.c``.) - - **Important: When using a** ``file`` **destination, you** - *must check in* **the generated file!** - - ``two-pass`` - A buffer like ``buffer``. However, a two-pass buffer can only - be dumped once, and it prints out all text sent to it during - all processing, even from Clinic blocks *after* the dumping point. - - ``suppress`` - The text is suppressed—thrown away. - - -Clinic defines five new directives that let you reconfigure its output. - -The first new directive is ``dump``: - -.. code-block:: none - - dump - -This dumps the current contents of the named destination into the output of -the current block, and empties it. This only works with ``buffer`` and -``two-pass`` destinations. - -The second new directive is ``output``. The most basic form of ``output`` -is like this: - -.. code-block:: none - - output - -This tells Clinic to output *field* to *destination*. ``output`` also -supports a special meta-destination, called ``everything``, which tells -Clinic to output *all* fields to that *destination*. - -``output`` has a number of other functions: - -.. code-block:: none - - output push - output pop - output preset - - -``output push`` and ``output pop`` allow you to push and pop -configurations on an internal configuration stack, so that you -can temporarily modify the output configuration, then easily restore -the previous configuration. Simply push before your change to save -the current configuration, then pop when you wish to restore the -previous configuration. - -``output preset`` sets Clinic's output to one of several built-in -preset configurations, as follows: - - ``block`` - Clinic's original starting configuration. Writes everything - immediately after the input block. - - Suppress the ``parser_prototype`` - and ``docstring_prototype``, write everything else to ``block``. - - ``file`` - Designed to write everything to the "clinic file" that it can. - You then ``#include`` this file near the top of your file. - You may need to rearrange your file to make this work, though - usually this just means creating forward declarations for various - ``typedef`` and ``PyTypeObject`` definitions. - - Suppress the ``parser_prototype`` - and ``docstring_prototype``, write the ``impl_definition`` to - ``block``, and write everything else to ``file``. - - The default filename is ``"{dirname}/clinic/{basename}.h"``. - - ``buffer`` - Save up most of the output from Clinic, to be written into - your file near the end. For Python files implementing modules - or builtin types, it's recommended that you dump the buffer - just above the static structures for your module or - builtin type; these are normally very near the end. Using - ``buffer`` may require even more editing than ``file``, if - your file has static ``PyMethodDef`` arrays defined in the - middle of the file. - - Suppress the ``parser_prototype``, ``impl_prototype``, - and ``docstring_prototype``, write the ``impl_definition`` to - ``block``, and write everything else to ``file``. - - ``two-pass`` - Similar to the ``buffer`` preset, but writes forward declarations to - the ``two-pass`` buffer, and definitions to the ``buffer``. - This is similar to the ``buffer`` preset, but may require - less editing than ``buffer``. Dump the ``two-pass`` buffer - near the top of your file, and dump the ``buffer`` near - the end just like you would when using the ``buffer`` preset. - - Suppresses the ``impl_prototype``, write the ``impl_definition`` - to ``block``, write ``docstring_prototype``, ``methoddef_define``, - and ``parser_prototype`` to ``two-pass``, write everything else - to ``buffer``. - - ``partial-buffer`` - Similar to the ``buffer`` preset, but writes more things to ``block``, - only writing the really big chunks of generated code to ``buffer``. - This avoids the definition-before-use problem of ``buffer`` completely, - at the small cost of having slightly more stuff in the block's output. - Dump the ``buffer`` near the end, just like you would when using - the ``buffer`` preset. - - Suppresses the ``impl_prototype``, write the ``docstring_definition`` - and ``parser_definition`` to ``buffer``, write everything else to ``block``. - -The third new directive is ``destination``: - -.. code-block:: none - - destination [...] - -This performs an operation on the destination named ``name``. - -There are two defined subcommands: ``new`` and ``clear``. - -The ``new`` subcommand works like this: - -.. code-block:: none - - destination new - -This creates a new destination with name ```` and type ````. - -There are five destination types: - - ``suppress`` - Throws the text away. - - ``block`` - Writes the text to the current block. This is what Clinic - originally did. - - ``buffer`` - A simple text buffer, like the "buffer" builtin destination above. - - ``file`` - A text file. The file destination takes an extra argument, - a template to use for building the filename, like so: - - destination new - - The template can use three strings internally that will be replaced - by bits of the filename: - - {path} - The full path to the file, including directory and full filename. - {dirname} - The name of the directory the file is in. - {basename} - Just the name of the file, not including the directory. - {basename_root} - Basename with the extension clipped off - (everything up to but not including the last '.'). - {basename_extension} - The last '.' and everything after it. If the basename - does not contain a period, this will be the empty string. - - If there are no periods in the filename, {basename} and {filename} - are the same, and {extension} is empty. "{basename}{extension}" - is always exactly the same as "{filename}"." - - ``two-pass`` - A two-pass buffer, like the "two-pass" builtin destination above. - - -The ``clear`` subcommand works like this: - -.. code-block:: none - - destination clear - -It removes all the accumulated text up to this point in the destination. -(I don't know what you'd need this for, but I thought maybe it'd be -useful while someone's experimenting.) - -The fourth new directive is ``set``: - -.. code-block:: none - - set line_prefix "string" - set line_suffix "string" - -``set`` lets you set two internal variables in Clinic. -``line_prefix`` is a string that will be prepended to every line of Clinic's output; -``line_suffix`` is a string that will be appended to every line of Clinic's output. - -Both of these support two format strings: - - ``{block comment start}`` - Turns into the string ``/*``, the start-comment text sequence for C files. - - ``{block comment end}`` - Turns into the string ``*/``, the end-comment text sequence for C files. - -The final new directive is one you shouldn't need to use directly, -called ``preserve``: - -.. code-block:: none - - preserve - -This tells Clinic that the current contents of the output should be kept, unmodified. -This is used internally by Clinic when dumping output into ``file`` files; wrapping -it in a Clinic block lets Clinic use its existing checksum functionality to ensure -the file was not modified by hand before it gets overwritten. - - -How to use the ``#ifdef`` trick -------------------------------- - -If you're converting a function that isn't available on all platforms, -there's a trick you can use to make life a little easier. The existing -code probably looks like this:: - - #ifdef HAVE_FUNCTIONNAME - static module_functionname(...) - { - ... - } - #endif /* HAVE_FUNCTIONNAME */ - -And then in the ``PyMethodDef`` structure at the bottom the existing code -will have: - -.. code-block:: none - - #ifdef HAVE_FUNCTIONNAME - {'functionname', ... }, - #endif /* HAVE_FUNCTIONNAME */ - -In this scenario, you should enclose the body of your impl function inside the ``#ifdef``, -like so:: - - #ifdef HAVE_FUNCTIONNAME - /*[clinic input] - module.functionname - ... - [clinic start generated code]*/ - static module_functionname(...) - { - ... - } - #endif /* HAVE_FUNCTIONNAME */ - -Then, remove those three lines from the ``PyMethodDef`` structure, -replacing them with the macro Argument Clinic generated: - -.. code-block:: none - - MODULE_FUNCTIONNAME_METHODDEF - -(You can find the real name for this macro inside the generated code. -Or you can calculate it yourself: it's the name of your function as defined -on the first line of your block, but with periods changed to underscores, -uppercased, and ``"_METHODDEF"`` added to the end.) - -Perhaps you're wondering: what if ``HAVE_FUNCTIONNAME`` isn't defined? -The ``MODULE_FUNCTIONNAME_METHODDEF`` macro won't be defined either! - -Here's where Argument Clinic gets very clever. It actually detects that the -Argument Clinic block might be deactivated by the ``#ifdef``. When that -happens, it generates a little extra code that looks like this:: - - #ifndef MODULE_FUNCTIONNAME_METHODDEF - #define MODULE_FUNCTIONNAME_METHODDEF - #endif /* !defined(MODULE_FUNCTIONNAME_METHODDEF) */ - -That means the macro always works. If the function is defined, this turns -into the correct structure, including the trailing comma. If the function is -undefined, this turns into nothing. - -However, this causes one ticklish problem: where should Argument Clinic put this -extra code when using the "block" output preset? It can't go in the output block, -because that could be deactivated by the ``#ifdef``. (That's the whole point!) - -In this situation, Argument Clinic writes the extra code to the "buffer" destination. -This may mean that you get a complaint from Argument Clinic: - -.. code-block:: none - - Warning in file "Modules/posixmodule.c" on line 12357: - Destination buffer 'buffer' not empty at end of file, emptying. - -When this happens, just open your file, find the ``dump buffer`` block that -Argument Clinic added to your file (it'll be at the very bottom), then -move it above the ``PyMethodDef`` structure where that macro is used. - - -How to use Argument Clinic in Python files ------------------------------------------- - -It's actually possible to use Argument Clinic to preprocess Python files. -There's no point to using Argument Clinic blocks, of course, as the output -wouldn't make any sense to the Python interpreter. But using Argument Clinic -to run Python blocks lets you use Python as a Python preprocessor! - -Since Python comments are different from C comments, Argument Clinic -blocks embedded in Python files look slightly different. They look like this: - -.. code-block:: python3 - - #/*[python input] - #print("def foo(): pass") - #[python start generated code]*/ - def foo(): pass - #/*[python checksum:...]*/ + The Argument Clinic How-TO has been moved to the `Python Developer's Guide + `__. diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index a3068d86d85bc4..4828e2fa29bd24 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -527,7 +527,7 @@ If you're in doubt about the detailed behavior of the curses functions, consult the manual pages for your curses implementation, whether it's ncurses or a proprietary Unix vendor's. The manual pages will document any quirks, and provide complete lists of all the -functions, attributes, and :const:`ACS_\*` characters available to +functions, attributes, and :ref:`ACS_\* ` characters available to you. Because the curses API is so large, some functions aren't supported in diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 3688c47f0d6ec9..1d9424cb735a46 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -779,8 +779,8 @@ by a search through the class's :term:`method resolution order`. If a descriptor is found, it is invoked with ``desc.__get__(None, A)``. -The full C implementation can be found in :c:func:`type_getattro()` and -:c:func:`_PyType_Lookup()` in :source:`Objects/typeobject.c`. +The full C implementation can be found in :c:func:`!type_getattro` and +:c:func:`!_PyType_Lookup` in :source:`Objects/typeobject.c`. Invocation from super @@ -794,7 +794,7 @@ for the base class ``B`` immediately following ``A`` and then returns ``B.__dict__['m'].__get__(obj, A)``. If not a descriptor, ``m`` is returned unchanged. -The full C implementation can be found in :c:func:`super_getattro()` in +The full C implementation can be found in :c:func:`!super_getattro` in :source:`Objects/typeobject.c`. A pure Python equivalent can be found in `Guido's Tutorial `_. @@ -836,8 +836,8 @@ and if they define :meth:`__set_name__`, that method is called with two arguments. The *owner* is the class where the descriptor is used, and the *name* is the class variable the descriptor was assigned to. -The implementation details are in :c:func:`type_new()` and -:c:func:`set_names()` in :source:`Objects/typeobject.c`. +The implementation details are in :c:func:`!type_new` and +:c:func:`!set_names` in :source:`Objects/typeobject.c`. Since the update logic is in :meth:`type.__new__`, notifications only take place at the time of class creation. If descriptors are added to the class diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst index 4312b4c8140f5c..ebaa1cfe4c8b58 100644 --- a/Doc/howto/enum.rst +++ b/Doc/howto/enum.rst @@ -426,10 +426,17 @@ enumeration, with the exception of special methods (:meth:`__str__`, :meth:`__add__`, etc.), descriptors (methods are also descriptors), and variable names listed in :attr:`_ignore_`. -Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__` then +Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__`, any value(s) given to the enum member will be passed into those methods. See `Planet`_ for an example. +.. note:: + + The :meth:`__new__` method, if defined, is used during creation of the Enum + members; it is then replaced by Enum's :meth:`__new__` which is used after + class creation for lookup of existing members. See :ref:`new-vs-init` for + more details. + Restricted Enum subclassing --------------------------- @@ -895,6 +902,8 @@ Some rules: :meth:`__str__` method has been reset to their data types' :meth:`__str__` method. +.. _new-vs-init: + When to use :meth:`__new__` vs. :meth:`__init__` ------------------------------------------------ @@ -927,6 +936,11 @@ want one of them to be the value:: >>> print(Coordinate(3)) Coordinate.VY +.. warning:: + + *Do not* call ``super().__new__()``, as the lookup-only ``__new__`` is the one + that is found; instead, use the data type directly. + Finer Points ^^^^^^^^^^^^ @@ -1142,13 +1156,14 @@ the following are true: There is a new boundary mechanism that controls how out-of-range / invalid bits are handled: ``STRICT``, ``CONFORM``, ``EJECT``, and ``KEEP``: - * STRICT --> raises an exception when presented with invalid values - * CONFORM --> discards any invalid bits - * EJECT --> lose Flag status and become a normal int with the given value - * KEEP --> keep the extra bits - - keeps Flag status and extra bits - - extra bits do not show up in iteration - - extra bits do show up in repr() and str() +* STRICT --> raises an exception when presented with invalid values +* CONFORM --> discards any invalid bits +* EJECT --> lose Flag status and become a normal int with the given value +* KEEP --> keep the extra bits + + - keeps Flag status and extra bits + - extra bits do not show up in iteration + - extra bits do show up in repr() and str() The default for Flag is ``STRICT``, the default for ``IntFlag`` is ``EJECT``, and the default for ``_convert_`` is ``KEEP`` (see ``ssl.Options`` for an @@ -1353,6 +1368,13 @@ to handle any extra arguments:: members; it is then replaced by Enum's :meth:`__new__` which is used after class creation for lookup of existing members. +.. warning:: + + *Do not* call ``super().__new__()``, as the lookup-only ``__new__`` is the one + that is found; instead, use the data type directly -- e.g.:: + + obj = int.__new__(cls, value) + OrderedEnum ^^^^^^^^^^^ diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index 5cf12cc52bde4e..b0f9d22d74f0e3 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -1072,8 +1072,8 @@ write the obvious :keyword:`for` loop:: A related function is :func:`itertools.accumulate(iterable, func=operator.add) `. It performs the same calculation, but instead of -returning only the final result, :func:`accumulate` returns an iterator that -also yields each partial result:: +returning only the final result, :func:`~itertools.accumulate` returns an iterator +that also yields each partial result:: itertools.accumulate([1, 2, 3, 4, 5]) => 1, 3, 6, 10, 15 diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst index f521276a5a83c5..a835bb5f13bd1c 100644 --- a/Doc/howto/index.rst +++ b/Doc/howto/index.rst @@ -28,9 +28,9 @@ Currently, the HOWTOs are: urllib2.rst argparse.rst ipaddress.rst - clinic.rst instrumentation.rst perf_profiling.rst annotations.rst isolating-extensions.rst + timerfd.rst diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index 4ce15c69dac90b..9c99fcecce1fcb 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -13,9 +13,9 @@ DTrace and SystemTap are monitoring tools, each providing a way to inspect what the processes on a computer system are doing. They both use domain-specific languages allowing a user to write scripts which: - - filter which processes are to be observed - - gather data from the processes of interest - - generate reports on the data +- filter which processes are to be observed +- gather data from the processes of interest +- generate reports on the data As of Python 3.6, CPython can be built with embedded "markers", also known as "probes", that can be observed by a DTrace or SystemTap script, @@ -246,11 +246,9 @@ The output looks like this: where the columns are: - - time in microseconds since start of script - - - name of executable - - - PID of process +- time in microseconds since start of script +- name of executable +- PID of process and the remainder indicates the call/return hierarchy as the script executes. @@ -292,11 +290,11 @@ Available static markers .. object:: function__return(str filename, str funcname, int lineno) - This marker is the converse of :c:func:`function__entry`, and indicates that + This marker is the converse of :c:func:`!function__entry`, and indicates that execution of a Python function has ended (either via ``return``, or via an exception). It is only triggered for pure-Python (bytecode) functions. - The arguments are the same as for :c:func:`function__entry` + The arguments are the same as for :c:func:`!function__entry` .. object:: line(str filename, str funcname, int lineno) @@ -304,7 +302,7 @@ Available static markers the equivalent of line-by-line tracing with a Python profiler. It is not triggered within C functions. - The arguments are the same as for :c:func:`function__entry`. + The arguments are the same as for :c:func:`!function__entry`. .. object:: gc__start(int generation) diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst index 8adb85f3a87401..8f3787f2d2f145 100644 --- a/Doc/howto/isolating-extensions.rst +++ b/Doc/howto/isolating-extensions.rst @@ -1,5 +1,7 @@ .. highlight:: c +.. _isolating-extensions-howto: + *************************** Isolating Extension Modules *************************** @@ -62,7 +64,7 @@ Enter Per-Module State Instead of focusing on per-interpreter state, Python's C API is evolving to better support the more granular *per-module* state. -This means that C-level data is be attached to a *module object*. +This means that C-level data should be attached to a *module object*. Each interpreter creates its own module object, keeping the data separate. For testing the isolation, multiple module objects corresponding to a single extension can even be loaded in a single interpreter. @@ -298,10 +300,10 @@ Watch out for the following two points in particular (but note that this is not a comprehensive list): * Unlike static types, heap type objects are mutable by default. - Use the :c:data:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability. + Use the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability. * Heap types inherit :c:member:`~PyTypeObject.tp_new` by default, so it may become possible to instantiate them from Python code. - You can prevent this with the :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. + You can prevent this with the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. Defining Heap Types @@ -333,12 +335,12 @@ To avoid memory leaks, instances of heap types must implement the garbage collection protocol. That is, heap types should: -- Have the :c:data:`Py_TPFLAGS_HAVE_GC` flag. +- Have the :c:macro:`Py_TPFLAGS_HAVE_GC` flag. - Define a traverse function using ``Py_tp_traverse``, which visits the type (e.g. using :c:expr:`Py_VISIT(Py_TYPE(self))`). Please refer to the :ref:`the documentation ` of -:c:data:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse` +:c:macro:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse` for additional considerations. If your traverse function delegates to the ``tp_traverse`` of its base class @@ -411,7 +413,7 @@ that subclass, which may be defined in different module than yours. pass For a method to get its "defining class", it must use the -:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` +:ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS ` :c:type:`calling convention ` and the corresponding :c:type:`PyCMethod` signature:: @@ -467,7 +469,7 @@ Module State Access from Slot Methods, Getters and Setters Slot methods—the fast C equivalents for special methods, such as :c:member:`~PyNumberMethods.nb_add` for :py:attr:`~object.__add__` or -:c:member:`~PyType.tp_new` for initialization—have a very simple API that +:c:member:`~PyTypeObject.tp_new` for initialization—have a very simple API that doesn't allow passing in the defining class, unlike with :c:type:`PyCMethod`. The same goes for getters and setters defined with :c:type:`PyGetSetDef`. @@ -483,14 +485,14 @@ to get the state:: return NULL; } -``PyType_GetModuleByDef`` works by searching the +:c:func:`!PyType_GetModuleByDef` works by searching the :term:`method resolution order` (i.e. all superclasses) for the first superclass that has a corresponding module. .. note:: In very exotic cases (inheritance chains spanning multiple modules - created from the same definition), ``PyType_GetModuleByDef`` might not + created from the same definition), :c:func:`!PyType_GetModuleByDef` might not return the module of the true defining class. However, it will always return a module with the same definition, ensuring a compatible C memory layout. diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 6ef252d709e735..588f5a0a53ded0 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -761,7 +761,7 @@ printed on the console; on the server side, you should see something like: Note that there are some security issues with pickle in some scenarios. If these affect you, you can use an alternative serialization scheme by overriding -the :meth:`~handlers.SocketHandler.makePickle` method and implementing your +the :meth:`~SocketHandler.makePickle` method and implementing your alternative there, as well as adapting the above script to use your alternative serialization. @@ -835,6 +835,8 @@ To test these files, do the following in a POSIX environment: You may need to tweak the configuration files in the unlikely event that the configured ports clash with something else in your test environment. +.. currentmodule:: logging + .. _context-info: Adding contextual information to your logging output @@ -1546,7 +1548,7 @@ Sometimes you want to let a log file grow to a certain size, then open a new file and log to that. You may want to keep a certain number of these files, and when that many files have been created, rotate the files so that the number of files and the size of the files both remain bounded. For this usage pattern, the -logging package provides a :class:`~handlers.RotatingFileHandler`:: +logging package provides a :class:`RotatingFileHandler`:: import glob import logging @@ -1594,6 +1596,8 @@ and each time it reaches the size limit it is renamed with the suffix Obviously this example sets the log length much too small as an extreme example. You would want to set *maxBytes* to an appropriate value. +.. currentmodule:: logging + .. _format-styles: Use of alternative formatting styles @@ -1724,7 +1728,7 @@ when (and if) the logged message is actually about to be output to a log by a handler. So the only slightly unusual thing which might trip you up is that the parentheses go around the format string and the arguments, not just the format string. That's because the __ notation is just syntax sugar for a constructor -call to one of the XXXMessage classes. +call to one of the :samp:`{XXX}Message` classes. If you prefer, you can use a :class:`LoggerAdapter` to achieve a similar effect to the above, as in the following example:: @@ -1840,6 +1844,7 @@ However, it should be borne in mind that each link in the chain adds run-time overhead to all logging operations, and the technique should only be used when the use of a :class:`Filter` does not provide the desired result. +.. currentmodule:: logging.handlers .. _zeromq-handlers: @@ -1917,6 +1922,8 @@ of queues, for example a ZeroMQ 'subscribe' socket. Here's an example:: :ref:`A more advanced logging tutorial ` +.. currentmodule:: logging + An example dictionary-based configuration ----------------------------------------- @@ -2637,7 +2644,7 @@ when (and if) the logged message is actually about to be output to a log by a handler. So the only slightly unusual thing which might trip you up is that the parentheses go around the format string and the arguments, not just the format string. That’s because the __ notation is just syntax sugar for a constructor -call to one of the ``XXXMessage`` classes shown above. +call to one of the :samp:`{XXX}Message` classes shown above. .. _filters-dictconfig: @@ -3918,8 +3925,8 @@ that in other languages such as Java and C#, loggers are often static class attributes. However, this pattern doesn't make sense in Python, where the module (and not the class) is the unit of software decomposition. -Adding handlers other than :class:`NullHandler` to a logger in a library -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Adding handlers other than :class:`~logging.NullHandler` to a logger in a library +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Configuring logging by adding handlers, formatters and filters is the responsibility of the application developer, not the library developer. If you diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index a72e9a820ef347..7330cf675baa36 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -979,7 +979,7 @@ provided: #. :class:`NullHandler` instances do nothing with error messages. They are used by library developers who want to use logging, but want to avoid the 'No - handlers could be found for logger XXX' message which can be displayed if + handlers could be found for logger *XXX*' message which can be displayed if the library user has not configured logging. See :ref:`library-config` for more information. diff --git a/Doc/howto/perf_profiling.rst b/Doc/howto/perf_profiling.rst index 61812c19ae6ca9..af7b67d2042950 100644 --- a/Doc/howto/perf_profiling.rst +++ b/Doc/howto/perf_profiling.rst @@ -162,8 +162,7 @@ the :option:`!-X` option takes precedence over the environment variable. Example, using the environment variable:: - $ PYTHONPERFSUPPORT=1 - $ python script.py + $ PYTHONPERFSUPPORT=1 python script.py $ perf report -g -i perf.data Example, using the :option:`!-X` option:: diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index baea3e85c3b84b..6c30a0dd7d6bcc 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -1,49 +1,47 @@ .. _pyporting-howto: -********************************* -Porting Python 2 Code to Python 3 -********************************* +************************************* +How to port Python 2 Code to Python 3 +************************************* :author: Brett Cannon .. topic:: Abstract - With Python 3 being the future of Python while Python 2 is still in active - use, it is good to have your project available for both major releases of - Python. This guide is meant to help you figure out how best to support both - Python 2 & 3 simultaneously. + Python 2 reached its official end-of-life at the start of 2020. This means + that no new bug reports, fixes, or changes will be made to Python 2 - it's + no longer supported. + + This guide is intended to provide you with a path to Python 3 for your + code, that includes compatibility with Python 2 as a first step. If you are looking to port an extension module instead of pure Python code, please see :ref:`cporting-howto`. - If you would like to read one core Python developer's take on why Python 3 - came into existence, you can read Nick Coghlan's `Python 3 Q & A`_ or - Brett Cannon's `Why Python 3 exists`_. - + The archived python-porting_ mailing list may contain some useful guidance. - For help with porting, you can view the archived python-porting_ mailing list. The Short Explanation ===================== -To make your project be single-source Python 2/3 compatible, the basic steps +To achieve Python 2/3 compatibility in a single code base, the basic steps are: #. Only worry about supporting Python 2.7 #. Make sure you have good test coverage (coverage.py_ can help; ``python -m pip install coverage``) -#. Learn the differences between Python 2 & 3 +#. Learn the differences between Python 2 and 3 #. Use Futurize_ (or Modernize_) to update your code (e.g. ``python -m pip install future``) #. Use Pylint_ to help make sure you don't regress on your Python 3 support (``python -m pip install pylint``) #. Use caniusepython3_ to find out which of your dependencies are blocking your use of Python 3 (``python -m pip install caniusepython3``) #. Once your dependencies are no longer blocking you, use continuous integration - to make sure you stay compatible with Python 2 & 3 (tox_ can help test + to make sure you stay compatible with Python 2 and 3 (tox_ can help test against multiple versions of Python; ``python -m pip install tox``) #. Consider using optional static type checking to make sure your type usage - works in both Python 2 & 3 (e.g. use mypy_ to check your typing under both - Python 2 & Python 3; ``python -m pip install mypy``). + works in both Python 2 and 3 (e.g. use mypy_ to check your typing under both + Python 2 and Python 3; ``python -m pip install mypy``). .. note:: @@ -55,43 +53,30 @@ are: Details ======= -A key point about supporting Python 2 & 3 simultaneously is that you can start -**today**! Even if your dependencies are not supporting Python 3 yet that does -not mean you can't modernize your code **now** to support Python 3. Most changes -required to support Python 3 lead to cleaner code using newer practices even in -Python 2 code. +Even if other factors - say, dependencies over which you have no control - +still require you to support Python 2, that does not prevent you taking the +step of including Python 3 support. -Another key point is that modernizing your Python 2 code to also support -Python 3 is largely automated for you. While you might have to make some API -decisions thanks to Python 3 clarifying text data versus binary data, the -lower-level work is now mostly done for you and thus can at least benefit from -the automated changes immediately. +Most changes required to support Python 3 lead to cleaner code using newer +practices even in Python 2 code. -Keep those key points in mind while you read on about the details of porting -your code to support Python 2 & 3 simultaneously. +Different versions of Python 2 +------------------------------ -Drop support for Python 2.6 and older -------------------------------------- +Ideally, your code should be compatible with Python 2.7, which was the +last supported version of Python 2. -While you can make Python 2.5 work with Python 3, it is **much** easier if you -only have to work with Python 2.7. If dropping Python 2.5 is not an -option then the six_ project can help you support Python 2.5 & 3 simultaneously -(``python -m pip install six``). Do realize, though, that nearly all the projects listed -in this HOWTO will not be available to you. +Some of the tools mentioned in this guide will not work with Python 2.6. -If you are able to skip Python 2.5 and older, then the required changes -to your code should continue to look and feel like idiomatic Python code. At -worst you will have to use a function instead of a method in some instances or -have to import a function instead of using a built-in one, but otherwise the -overall transformation should not feel foreign to you. +If absolutely necessary, the six_ project can help you support Python 2.5 and +3 simultaneously. Do realize, though, that nearly all the projects listed in +this guide will not be available to you. -But you should aim for only supporting Python 2.7. Python 2.6 is no longer -freely supported and thus is not receiving bugfixes. This means **you** will have -to work around any issues you come across with Python 2.6. There are also some -tools mentioned in this HOWTO which do not support Python 2.6 (e.g., Pylint_), -and this will become more commonplace as time goes on. It will simply be easier -for you if you only support the versions of Python that you have to support. +If you are able to skip Python 2.5 and older, the required changes to your +code will be minimal. At worst you will have to use a function instead of a +method in some instances or have to import a function instead of using a +built-in one. Make sure you specify the proper version support in your ``setup.py`` file @@ -118,62 +103,57 @@ coverage). If you don't already have a tool to measure test coverage then coverage.py_ is recommended. -Learn the differences between Python 2 & 3 -------------------------------------------- +Be aware of the differences between Python 2 and 3 +-------------------------------------------------- Once you have your code well-tested you are ready to begin porting your code to Python 3! But to fully understand how your code is going to change and what you want to look out for while you code, you will want to learn what changes -Python 3 makes in terms of Python 2. Typically the two best ways of doing that -is reading the :ref:`"What's New" ` doc for each release of Python 3 and the -`Porting to Python 3`_ book (which is free online). There is also a handy -`cheat sheet`_ from the Python-Future project. +Python 3 makes in terms of Python 2. + +Some resources for understanding the differences and their implications for you +code: + +* the :ref:`"What's New" ` doc for each release of Python 3 +* the `Porting to Python 3`_ book (which is free online) +* the handy `cheat sheet`_ from the Python-Future project. Update your code ---------------- -Once you feel like you know what is different in Python 3 compared to Python 2, -it's time to update your code! You have a choice between two tools in porting -your code automatically: Futurize_ and Modernize_. Which tool you choose will -depend on how much like Python 3 you want your code to be. Futurize_ does its -best to make Python 3 idioms and practices exist in Python 2, e.g. backporting -the ``bytes`` type from Python 3 so that you have semantic parity between the -major versions of Python. Modernize_, -on the other hand, is more conservative and targets a Python 2/3 subset of -Python, directly relying on six_ to help provide compatibility. As Python 3 is -the future, it might be best to consider Futurize to begin adjusting to any new -practices that Python 3 introduces which you are not accustomed to yet. - -Regardless of which tool you choose, they will update your code to run under -Python 3 while staying compatible with the version of Python 2 you started with. -Depending on how conservative you want to be, you may want to run the tool over -your test suite first and visually inspect the diff to make sure the -transformation is accurate. After you have transformed your test suite and -verified that all the tests still pass as expected, then you can transform your -application code knowing that any tests which fail is a translation failure. +There are tools available that can port your code automatically. + +Futurize_ does its best to make Python 3 idioms and practices exist in Python +2, e.g. backporting the ``bytes`` type from Python 3 so that you have +semantic parity between the major versions of Python. This is the better +approach for most cases. + +Modernize_, on the other hand, is more conservative and targets a Python 2/3 +subset of Python, directly relying on six_ to help provide compatibility. + +A good approach is to run the tool over your test suite first and visually +inspect the diff to make sure the transformation is accurate. After you have +transformed your test suite and verified that all the tests still pass as +expected, then you can transform your application code knowing that any tests +which fail is a translation failure. Unfortunately the tools can't automate everything to make your code work under -Python 3 and so there are a handful of things you will need to update manually -to get full Python 3 support (which of these steps are necessary vary between -the tools). Read the documentation for the tool you choose to use to see what it -fixes by default and what it can do optionally to know what will (not) be fixed -for you and what you may have to fix on your own (e.g. using ``io.open()`` over -the built-in ``open()`` function is off by default in Modernize). Luckily, -though, there are only a couple of things to watch out for which can be -considered large issues that may be hard to debug if not watched for. +Python 3, and you will also need to read the tools' documentation in case some +options you need are turned off by default. +Key issues to be aware of and check for: Division ++++++++ -In Python 3, ``5 / 2 == 2.5`` and not ``2``; all division between ``int`` values -result in a ``float``. This change has actually been planned since Python 2.2 -which was released in 2002. Since then users have been encouraged to add -``from __future__ import division`` to any and all files which use the ``/`` and -``//`` operators or to be running the interpreter with the ``-Q`` flag. If you -have not been doing this then you will need to go through your code and do two -things: +In Python 3, ``5 / 2 == 2.5`` and not ``2`` as it was in Python 2; all +division between ``int`` values result in a ``float``. This change has +actually been planned since Python 2.2 which was released in 2002. Since then +users have been encouraged to add ``from __future__ import division`` to any +and all files which use the ``/`` and ``//`` operators or to be running the +interpreter with the ``-Q`` flag. If you have not been doing this then you +will need to go through your code and do two things: #. Add ``from __future__ import division`` to your files #. Update any division operator as necessary to either use ``//`` to use floor @@ -197,30 +177,29 @@ specific type. This complicated the situation especially for anyone supporting multiple languages as APIs wouldn't bother explicitly supporting ``unicode`` when they claimed text data support. -To make the distinction between text and binary data clearer and more -pronounced, Python 3 did what most languages created in the age of the internet -have done and made text and binary data distinct types that cannot blindly be -mixed together (Python predates widespread access to the internet). For any code -that deals only with text or only binary data, this separation doesn't pose an -issue. But for code that has to deal with both, it does mean you might have to -now care about when you are using text compared to binary data, which is why -this cannot be entirely automated. - -To start, you will need to decide which APIs take text and which take binary -(it is **highly** recommended you don't design APIs that can take both due to -the difficulty of keeping the code working; as stated earlier it is difficult to -do well). In Python 2 this means making sure the APIs that take text can work -with ``unicode`` and those that work with binary data work with the -``bytes`` type from Python 3 (which is a subset of ``str`` in Python 2 and acts -as an alias for ``bytes`` type in Python 2). Usually the biggest issue is -realizing which methods exist on which types in Python 2 & 3 simultaneously -(for text that's ``unicode`` in Python 2 and ``str`` in Python 3, for binary -that's ``str``/``bytes`` in Python 2 and ``bytes`` in Python 3). The following -table lists the **unique** methods of each data type across Python 2 & 3 -(e.g., the ``decode()`` method is usable on the equivalent binary data type in -either Python 2 or 3, but it can't be used by the textual data type consistently -between Python 2 and 3 because ``str`` in Python 3 doesn't have the method). Do -note that as of Python 3.5 the ``__mod__`` method was added to the bytes type. +Python 3 made text and binary data distinct types that cannot simply be mixed +together. For any code that deals only with text or only binary data, this +separation doesn't pose an issue. But for code that has to deal with both, it +does mean you might have to now care about when you are using text compared +to binary data, which is why this cannot be entirely automated. + +Decide which APIs take text and which take binary (it is **highly** recommended +you don't design APIs that can take both due to the difficulty of keeping the +code working; as stated earlier it is difficult to do well). In Python 2 this +means making sure the APIs that take text can work with ``unicode`` and those +that work with binary data work with the ``bytes`` type from Python 3 +(which is a subset of ``str`` in Python 2 and acts as an alias for ``bytes`` +type in Python 2). Usually the biggest issue is realizing which methods exist +on which types in Python 2 and 3 simultaneously (for text that's ``unicode`` +in Python 2 and ``str`` in Python 3, for binary that's ``str``/``bytes`` in +Python 2 and ``bytes`` in Python 3). + +The following table lists the **unique** methods of each data type across +Python 2 and 3 (e.g., the ``decode()`` method is usable on the equivalent binary +data type in either Python 2 or 3, but it can't be used by the textual data +type consistently between Python 2 and 3 because ``str`` in Python 3 doesn't +have the method). Do note that as of Python 3.5 the ``__mod__`` method was +added to the bytes type. ======================== ===================== **Text data** **Binary data** @@ -246,12 +225,11 @@ having to keep track of what type of data you are working with. The next issue is making sure you know whether the string literals in your code represent text or binary data. You should add a ``b`` prefix to any literal that presents binary data. For text you should add a ``u`` prefix to -the text literal. (there is a :mod:`__future__` import to force all unspecified +the text literal. (There is a :mod:`__future__` import to force all unspecified literals to be Unicode, but usage has shown it isn't as effective as adding a ``b`` or ``u`` prefix to all literals explicitly) -As part of this dichotomy you also need to be careful about opening files. -Unless you have been working on Windows, there is a chance you have not always +You also need to be careful about opening files. Possibly you have not always bothered to add the ``b`` mode when opening a binary file (e.g., ``rb`` for binary reading). Under Python 3, binary files and text files are clearly distinct and mutually incompatible; see the :mod:`io` module for details. @@ -265,7 +243,7 @@ outdated practice of using :func:`codecs.open` as that's only necessary for keeping compatibility with Python 2.5. The constructors of both ``str`` and ``bytes`` have different semantics for the -same arguments between Python 2 & 3. Passing an integer to ``bytes`` in Python 2 +same arguments between Python 2 and 3. Passing an integer to ``bytes`` in Python 2 will give you the string representation of the integer: ``bytes(3) == '3'``. But in Python 3, an integer argument to ``bytes`` will give you a bytes object as long as the integer specified, filled with null bytes: @@ -400,7 +378,7 @@ Use continuous integration to stay compatible --------------------------------------------- Once you are able to fully run under Python 3 you will want to make sure your -code always works under both Python 2 & 3. Probably the best tool for running +code always works under both Python 2 and 3. Probably the best tool for running your tests under multiple Python interpreters is tox_. You can then integrate tox with your continuous integration system so that you never accidentally break Python 2 or 3 support. @@ -413,11 +391,6 @@ separation of text/binary data handling or indexing on bytes you wouldn't easily find the mistake. This flag will raise an exception when these kinds of comparisons occur, making the mistake much easier to track down. -And that's mostly it! At this point your code base is compatible with both -Python 2 and 3 simultaneously. Your testing will also be set up so that you -don't accidentally break Python 2 or 3 compatibility regardless of which version -you typically run your tests under while developing. - Consider using optional static type checking -------------------------------------------- diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index 655df59e27b641..c19c48301f5848 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -518,6 +518,8 @@ cache. Compilation Flags ----------------- +.. currentmodule:: re + Compilation flags let you modify some aspects of how regular expressions work. Flags are available in the :mod:`re` module under two names, a long name such as :const:`IGNORECASE` and a short, one-letter form such as :const:`I`. (If you're diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst index decce12bf3faf6..38dd09f0a721d2 100644 --- a/Doc/howto/sorting.rst +++ b/Doc/howto/sorting.rst @@ -273,7 +273,7 @@ Odds and Ends * The sort routines use ``<`` when making comparisons between two objects. So, it is easy to add a standard sort order to a class by - defining an :meth:`__lt__` method: + defining an :meth:`~object.__lt__` method: .. doctest:: @@ -281,8 +281,8 @@ Odds and Ends >>> sorted(student_objects) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] - However, note that ``<`` can fall back to using :meth:`__gt__` if - :meth:`__lt__` is not implemented (see :func:`object.__lt__`). + However, note that ``<`` can fall back to using :meth:`~object.__gt__` if + :meth:`~object.__lt__` is not implemented (see :func:`object.__lt__`). * Key functions need not depend directly on the objects being sorted. A key function can also access external resources. For instance, if the student grades diff --git a/Doc/howto/timerfd.rst b/Doc/howto/timerfd.rst new file mode 100644 index 00000000000000..98f0294f9d082d --- /dev/null +++ b/Doc/howto/timerfd.rst @@ -0,0 +1,230 @@ +.. _timerfd-howto: + +***************************** + timer file descriptor HOWTO +***************************** + +:Release: 1.13 + +This HOWTO discusses Python's support for the linux timer file descriptor. + + +Examples +======== + +The following example shows how to use a timer file descriptor +to execute a function twice a second: + +.. code-block:: python + + # Practical scripts should use really use a non-blocking timer, + # we use a blocking timer here for simplicity. + import os, time + + # Create the timer file descriptor + fd = os.timerfd_create(time.CLOCK_REALTIME) + + # Start the timer in 1 second, with an interval of half a second + os.timerfd_settime(fd, initial=1, interval=0.5) + + try: + # Process timer events four times. + for _ in range(4): + # read() will block until the timer expires + _ = os.read(fd, 8) + print("Timer expired") + finally: + # Remember to close the timer file descriptor! + os.close(fd) + +To avoid the precision loss caused by the :class:`float` type, +timer file descriptors allow specifying initial expiration and interval +in integer nanoseconds with ``_ns`` variants of the functions. + +This example shows how :func:`~select.epoll` can be used with timer file +descriptors to wait until the file descriptor is ready for reading: + +.. code-block:: python + + import os, time, select, socket, sys + + # Create an epoll object + ep = select.epoll() + + # In this example, use loopback address to send "stop" command to the server. + # + # $ telnet 127.0.0.1 1234 + # Trying 127.0.0.1... + # Connected to 127.0.0.1. + # Escape character is '^]'. + # stop + # Connection closed by foreign host. + # + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.bind(("127.0.0.1", 1234)) + sock.setblocking(False) + sock.listen(1) + ep.register(sock, select.EPOLLIN) + + # Create timer file descriptors in non-blocking mode. + num = 3 + fds = [] + for _ in range(num): + fd = os.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK) + fds.append(fd) + # Register the timer file descriptor for read events + ep.register(fd, select.EPOLLIN) + + # Start the timer with os.timerfd_settime_ns() in nanoseconds. + # Timer 1 fires every 0.25 seconds; timer 2 every 0.5 seconds; etc + for i, fd in enumerate(fds, start=1): + one_sec_in_nsec = 10**9 + i = i * one_sec_in_nsec + os.timerfd_settime_ns(fd, initial=i//4, interval=i//4) + + timeout = 3 + try: + conn = None + is_active = True + while is_active: + # Wait for the timer to expire for 3 seconds. + # epoll.poll() returns a list of (fd, event) pairs. + # fd is a file descriptor. + # sock and conn[=returned value of socket.accept()] are socket objects, not file descriptors. + # So use sock.fileno() and conn.fileno() to get the file descriptors. + events = ep.poll(timeout) + + # If more than one timer file descriptors are ready for reading at once, + # epoll.poll() returns a list of (fd, event) pairs. + # + # In this example settings, + # 1st timer fires every 0.25 seconds in 0.25 seconds. (0.25, 0.5, 0.75, 1.0, ...) + # 2nd timer every 0.5 seconds in 0.5 seconds. (0.5, 1.0, 1.5, 2.0, ...) + # 3rd timer every 0.75 seconds in 0.75 seconds. (0.75, 1.5, 2.25, 3.0, ...) + # + # In 0.25 seconds, only 1st timer fires. + # In 0.5 seconds, 1st timer and 2nd timer fires at once. + # In 0.75 seconds, 1st timer and 3rd timer fires at once. + # In 1.5 seconds, 1st timer, 2nd timer and 3rd timer fires at once. + # + # If a timer file descriptor is signaled more than once since + # the last os.read() call, os.read() returns the nubmer of signaled + # as host order of class bytes. + print(f"Signaled events={events}") + for fd, event in events: + if event & select.EPOLLIN: + if fd == sock.fileno(): + # Check if there is a connection request. + print(f"Accepting connection {fd}") + conn, addr = sock.accept() + conn.setblocking(False) + print(f"Accepted connection {conn} from {addr}") + ep.register(conn, select.EPOLLIN) + elif conn and fd == conn.fileno(): + # Check if there is data to read. + print(f"Reading data {fd}") + data = conn.recv(1024) + if data: + # You should catch UnicodeDecodeError exception for safety. + cmd = data.decode() + if cmd.startswith("stop"): + print(f"Stopping server") + is_active = False + else: + print(f"Unknown command: {cmd}") + else: + # No more data, close connection + print(f"Closing connection {fd}") + ep.unregister(conn) + conn.close() + conn = None + elif fd in fds: + print(f"Reading timer {fd}") + count = int.from_bytes(os.read(fd, 8), byteorder=sys.byteorder) + print(f"Timer {fds.index(fd) + 1} expired {count} times") + else: + print(f"Unknown file descriptor {fd}") + finally: + for fd in fds: + ep.unregister(fd) + os.close(fd) + ep.close() + +This example shows how :func:`~select.select` can be used with timer file +descriptors to wait until the file descriptor is ready for reading: + +.. code-block:: python + + import os, time, select, socket, sys + + # In this example, use loopback address to send "stop" command to the server. + # + # $ telnet 127.0.0.1 1234 + # Trying 127.0.0.1... + # Connected to 127.0.0.1. + # Escape character is '^]'. + # stop + # Connection closed by foreign host. + # + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.bind(("127.0.0.1", 1234)) + sock.setblocking(False) + sock.listen(1) + + # Create timer file descriptors in non-blocking mode. + num = 3 + fds = [os.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK) + for _ in range(num)] + select_fds = fds + [sock] + + # Start the timers with os.timerfd_settime() in seconds. + # Timer 1 fires every 0.25 seconds; timer 2 every 0.5 seconds; etc + for i, fd in enumerate(fds, start=1): + os.timerfd_settime(fd, initial=i/4, interval=i/4) + + timeout = 3 + try: + conn = None + is_active = True + while is_active: + # Wait for the timer to expire for 3 seconds. + # select.select() returns a list of file descriptors or objects. + rfd, wfd, xfd = select.select(select_fds, select_fds, select_fds, timeout) + for fd in rfd: + if fd == sock: + # Check if there is a connection request. + print(f"Accepting connection {fd}") + conn, addr = sock.accept() + conn.setblocking(False) + print(f"Accepted connection {conn} from {addr}") + select_fds.append(conn) + elif conn and fd == conn: + # Check if there is data to read. + print(f"Reading data {fd}") + data = conn.recv(1024) + if data: + # You should catch UnicodeDecodeError exception for safety. + cmd = data.decode() + if cmd.startswith("stop"): + print(f"Stopping server") + is_active = False + else: + print(f"Unknown command: {cmd}") + else: + # No more data, close connection + print(f"Closing connection {fd}") + select_fds.remove(conn) + conn.close() + conn = None + elif fd in fds: + print(f"Reading timer {fd}") + count = int.from_bytes(os.read(fd, 8), byteorder=sys.byteorder) + print(f"Timer {fds.index(fd) + 1} expired {count} times") + else: + print(f"Unknown file descriptor {fd}") + finally: + for fd in fds: + os.close(fd) + sock.close() + sock = None + diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index b0faa68d240896..254fe729355353 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -424,8 +424,8 @@ lowercase letters 'ss'. A second tool is the :mod:`unicodedata` module's :func:`~unicodedata.normalize` function that converts strings to one -of several normal forms, where letters followed by a combining -character are replaced with single characters. :func:`normalize` can +of several normal forms, where letters followed by a combining character are +replaced with single characters. :func:`~unicodedata.normalize` can be used to perform string comparisons that won't falsely report inequality if two strings use combining characters differently: @@ -474,8 +474,8 @@ The Unicode Standard also specifies how to do caseless comparisons:: print(compare_caseless(single_char, multiple_chars)) -This will print ``True``. (Why is :func:`NFD` invoked twice? Because -there are a few characters that make :meth:`casefold` return a +This will print ``True``. (Why is :func:`!NFD` invoked twice? Because +there are a few characters that make :meth:`~str.casefold` return a non-normalized string, so the result needs to be normalized again. See section 3.13 of the Unicode Standard for a discussion and an example.) diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 86137fb38c9b93..570435d48866d3 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -194,11 +194,11 @@ which comes after we have a look at what happens when things go wrong. Handling Exceptions =================== -*urlopen* raises :exc:`URLError` when it cannot handle a response (though as +*urlopen* raises :exc:`~urllib.error.URLError` when it cannot handle a response (though as usual with Python APIs, built-in exceptions such as :exc:`ValueError`, :exc:`TypeError` etc. may also be raised). -:exc:`HTTPError` is the subclass of :exc:`URLError` raised in the specific case of +:exc:`~urllib.error.HTTPError` is the subclass of :exc:`~urllib.error.URLError` raised in the specific case of HTTP URLs. The exception classes are exported from the :mod:`urllib.error` module. @@ -229,12 +229,12 @@ the status code indicates that the server is unable to fulfil the request. The default handlers will handle some of these responses for you (for example, if the response is a "redirection" that requests the client fetch the document from a different URL, urllib will handle that for you). For those it can't handle, -urlopen will raise an :exc:`HTTPError`. Typical errors include '404' (page not +urlopen will raise an :exc:`~urllib.error.HTTPError`. Typical errors include '404' (page not found), '403' (request forbidden), and '401' (authentication required). See section 10 of :rfc:`2616` for a reference on all the HTTP error codes. -The :exc:`HTTPError` instance raised will have an integer 'code' attribute, which +The :exc:`~urllib.error.HTTPError` instance raised will have an integer 'code' attribute, which corresponds to the error sent by the server. Error Codes @@ -317,7 +317,7 @@ dictionary is reproduced here for convenience :: } When an error is raised the server responds by returning an HTTP error code -*and* an error page. You can use the :exc:`HTTPError` instance as a response on the +*and* an error page. You can use the :exc:`~urllib.error.HTTPError` instance as a response on the page returned. This means that as well as the code attribute, it also has read, geturl, and info, methods as returned by the ``urllib.response`` module:: @@ -338,7 +338,7 @@ geturl, and info, methods as returned by the ``urllib.response`` module:: Wrapping it Up -------------- -So if you want to be prepared for :exc:`HTTPError` *or* :exc:`URLError` there are two +So if you want to be prepared for :exc:`~urllib.error.HTTPError` *or* :exc:`~urllib.error.URLError` there are two basic approaches. I prefer the second approach. Number 1 @@ -365,7 +365,7 @@ Number 1 .. note:: The ``except HTTPError`` *must* come first, otherwise ``except URLError`` - will *also* catch an :exc:`HTTPError`. + will *also* catch an :exc:`~urllib.error.HTTPError`. Number 2 ~~~~~~~~ @@ -391,7 +391,7 @@ Number 2 info and geturl =============== -The response returned by urlopen (or the :exc:`HTTPError` instance) has two +The response returned by urlopen (or the :exc:`~urllib.error.HTTPError` instance) has two useful methods :meth:`info` and :meth:`geturl` and is defined in the module :mod:`urllib.response`.. diff --git a/Doc/includes/custom.c b/Doc/includes/newtypes/custom.c similarity index 86% rename from Doc/includes/custom.c rename to Doc/includes/newtypes/custom.c index 9cfba50ace25db..5253f879360210 100644 --- a/Doc/includes/custom.c +++ b/Doc/includes/newtypes/custom.c @@ -34,9 +34,7 @@ PyInit_custom(void) if (m == NULL) return NULL; - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Doc/includes/custom2.c b/Doc/includes/newtypes/custom2.c similarity index 100% rename from Doc/includes/custom2.c rename to Doc/includes/newtypes/custom2.c diff --git a/Doc/includes/custom3.c b/Doc/includes/newtypes/custom3.c similarity index 100% rename from Doc/includes/custom3.c rename to Doc/includes/newtypes/custom3.c diff --git a/Doc/includes/custom4.c b/Doc/includes/newtypes/custom4.c similarity index 100% rename from Doc/includes/custom4.c rename to Doc/includes/newtypes/custom4.c diff --git a/Doc/includes/newtypes/pyproject.toml b/Doc/includes/newtypes/pyproject.toml new file mode 100644 index 00000000000000..ea7937a3171473 --- /dev/null +++ b/Doc/includes/newtypes/pyproject.toml @@ -0,0 +1,7 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "custom" +version = "1" diff --git a/Doc/includes/newtypes/setup.py b/Doc/includes/newtypes/setup.py new file mode 100644 index 00000000000000..67f83673bcc657 --- /dev/null +++ b/Doc/includes/newtypes/setup.py @@ -0,0 +1,8 @@ +from setuptools import Extension, setup +setup(ext_modules=[ + Extension("custom", ["custom.c"]), + Extension("custom2", ["custom2.c"]), + Extension("custom3", ["custom3.c"]), + Extension("custom4", ["custom4.c"]), + Extension("sublist", ["sublist.c"]), +]) diff --git a/Doc/includes/sublist.c b/Doc/includes/newtypes/sublist.c similarity index 91% rename from Doc/includes/sublist.c rename to Doc/includes/newtypes/sublist.c index b36dadf07eae87..d8aba463f30ba2 100644 --- a/Doc/includes/sublist.c +++ b/Doc/includes/newtypes/sublist.c @@ -58,9 +58,7 @@ PyInit_sublist(void) if (m == NULL) return NULL; - Py_INCREF(&SubListType); - if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) { - Py_DECREF(&SubListType); + if (PyModule_AddObjectRef(m, "SubList", (PyObject *) &SubListType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Doc/includes/test.py b/Doc/includes/newtypes/test.py similarity index 94% rename from Doc/includes/test.py rename to Doc/includes/newtypes/test.py index 09ebe3fec0bdbe..55a5cf9f68b94a 100644 --- a/Doc/includes/test.py +++ b/Doc/includes/newtypes/test.py @@ -187,13 +187,6 @@ >>> gc.enable() """ -import os -import sys -from distutils.util import get_platform -PLAT_SPEC = "%s-%d.%d" % (get_platform(), *sys.version_info[:2]) -src = os.path.join("build", "lib.%s" % PLAT_SPEC) -sys.path.append(src) - if __name__ == "__main__": import doctest, __main__ doctest.testmod(__main__) diff --git a/Doc/includes/setup.py b/Doc/includes/setup.py deleted file mode 100644 index a38a39de3e7c86..00000000000000 --- a/Doc/includes/setup.py +++ /dev/null @@ -1,9 +0,0 @@ -from distutils.core import setup, Extension -setup(name="noddy", version="1.0", - ext_modules=[ - Extension("noddy", ["noddy.c"]), - Extension("noddy2", ["noddy2.c"]), - Extension("noddy3", ["noddy3.c"]), - Extension("noddy4", ["noddy4.c"]), - Extension("shoddy", ["shoddy.c"]), - ]) diff --git a/Doc/includes/turtle-star.py b/Doc/includes/turtle-star.py deleted file mode 100644 index 1a5db761b32385..00000000000000 --- a/Doc/includes/turtle-star.py +++ /dev/null @@ -1,10 +0,0 @@ -from turtle import * -color('red', 'yellow') -begin_fill() -while True: - forward(200) - left(170) - if abs(pos()) < 1: - break -end_fill() -done() diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h index f0ad1e47cb0d86..ec939c28831c33 100644 --- a/Doc/includes/typestruct.h +++ b/Doc/includes/typestruct.h @@ -82,5 +82,5 @@ typedef struct _typeobject { vectorcallfunc tp_vectorcall; /* bitset of which type-watchers care about this type */ - char tp_watched; + unsigned char tp_watched; } PyTypeObject; diff --git a/Doc/install/index.rst b/Doc/install/index.rst deleted file mode 100644 index beb34f0cf21b22..00000000000000 --- a/Doc/install/index.rst +++ /dev/null @@ -1,1081 +0,0 @@ -.. highlight:: none - -.. _install-index: - -******************************************** - Installing Python Modules (Legacy version) -******************************************** - -:Author: Greg Ward - -.. TODO: Fill in XXX comments - -.. note:: - - The entire ``distutils`` package has been deprecated and will be - removed in Python 3.12. This documentation is retained as a - reference only, and will be removed with the package. See the - :ref:`What's New ` entry for more information. - -.. seealso:: - - :ref:`installing-index` - The up to date module installation documentation. For regular Python - usage, you almost certainly want that document rather than this one. - -.. note:: - - This document is being retained solely until the ``setuptools`` documentation - at https://setuptools.readthedocs.io/en/latest/setuptools.html - independently covers all of the relevant information currently included here. - -.. note:: - - This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third party - tools offer easier to use and more secure alternatives. Refer to the `quick - recommendations section `__ - in the Python Packaging User Guide for more information. - - -.. _inst-intro: - - -Introduction -============ - -In Python 2.0, the ``distutils`` API was first added to the standard library. -This provided Linux distro maintainers with a standard way of converting -Python projects into Linux distro packages, and system administrators with a -standard way of installing them directly onto target systems. - -In the many years since Python 2.0 was released, tightly coupling the build -system and package installer to the language runtime release cycle has turned -out to be problematic, and it is now recommended that projects use the -``pip`` package installer and the ``setuptools`` build system, rather than -using ``distutils`` directly. - -See :ref:`installing-index` and :ref:`distributing-index` for more details. - -This legacy documentation is being retained only until we're confident that the -``setuptools`` documentation covers everything needed. - -.. _inst-new-standard: - -Distutils based source distributions ------------------------------------- - -If you download a module source distribution, you can tell pretty quickly if it -was packaged and distributed in the standard way, i.e. using the Distutils. -First, the distribution's name and version number will be featured prominently -in the name of the downloaded archive, e.g. :file:`foo-1.0.tar.gz` or -:file:`widget-0.9.7.zip`. Next, the archive will unpack into a similarly named -directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the -distribution will contain a setup script :file:`setup.py`, and a file named -:file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running -one command from a terminal:: - - python setup.py install - -For Windows, this command should be run from a command prompt window -(:menuselection:`Start --> Accessories`):: - - setup.py install - -If all these things are true, then you already know how to build and install the -modules you've just downloaded: Run the command above. Unless you need to -install things in a non-standard way or customize the build process, you don't -really need this manual. Or rather, the above command is everything you need to -get out of this manual. - - -.. _inst-standard-install: - -Standard Build and Install -========================== - -As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command to run from a -terminal:: - - python setup.py install - - -.. _inst-platform-variations: - -Platform variations -------------------- - -You should always run the setup command from the distribution root directory, -i.e. the top-level subdirectory that the module source distribution unpacks -into. For example, if you've just downloaded a module source distribution -:file:`foo-1.0.tar.gz` onto a Unix system, the normal thing to do is:: - - gunzip -c foo-1.0.tar.gz | tar xf - # unpacks into directory foo-1.0 - cd foo-1.0 - python setup.py install - -On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the -archive file to :file:`C:\\Temp`, then it would unpack into -:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a -graphical user interface (such as WinZip) or a command-line tool (such as -:program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a -command prompt window and run:: - - cd c:\Temp\foo-1.0 - python setup.py install - - -.. _inst-splitting-up: - -Splitting the job up --------------------- - -Running ``setup.py install`` builds and installs all modules in one run. If you -prefer to work incrementally---especially useful if you want to customize the -build process, or if things are going wrong---you can use the setup script to do -one thing at a time. This is particularly helpful when the build and install -will be done by different users---for example, you might want to build a module -distribution and hand it off to a system administrator for installation (or do -it yourself, with super-user privileges). - -For example, you can build everything in one step, and then install everything -in a second step, by invoking the setup script twice:: - - python setup.py build - python setup.py install - -If you do this, you will notice that running the :command:`install` command -first runs the :command:`build` command, which---in this case---quickly notices -that it has nothing to do, since everything in the :file:`build` directory is -up-to-date. - -You may not need this ability to break things down often if all you do is -install modules downloaded off the 'net, but it's very handy for more advanced -tasks. If you get into distributing your own Python modules and extensions, -you'll run lots of individual Distutils commands on their own. - - -.. _inst-how-build-works: - -How building works ------------------- - -As implied above, the :command:`build` command is responsible for putting the -files to install into a *build directory*. By default, this is :file:`build` -under the distribution root; if you're excessively concerned with speed, or want -to keep the source tree pristine, you can change the build directory with the -:option:`!--build-base` option. For example:: - - python setup.py build --build-base=/path/to/pybuild/foo-1.0 - -(Or you could do this permanently with a directive in your system or personal -Distutils configuration file; see section :ref:`inst-config-files`.) Normally, this -isn't necessary. - -The default layout for the build tree is as follows:: - - --- build/ --- lib/ - or - --- build/ --- lib./ - temp./ - -where ```` expands to a brief description of the current OS/hardware -platform and Python version. The first form, with just a :file:`lib` directory, -is used for "pure module distributions"---that is, module distributions that -include only pure Python modules. If a module distribution contains any -extensions (modules written in C/C++), then the second form, with two ```` -directories, is used. In that case, the :file:`temp.{plat}` directory holds -temporary files generated by the compile/link process that don't actually get -installed. In either case, the :file:`lib` (or :file:`lib.{plat}`) directory -contains all Python modules (pure Python and extensions) that will be installed. - -In the future, more directories will be added to handle Python scripts, -documentation, binary executables, and whatever else is needed to handle the job -of installing Python modules and applications. - - -.. _inst-how-install-works: - -How installation works ----------------------- - -After the :command:`build` command runs (whether you run it explicitly, or the -:command:`install` command does it for you), the work of the :command:`install` -command is relatively simple: all it has to do is copy everything under -:file:`build/lib` (or :file:`build/lib.{plat}`) to your chosen installation -directory. - -If you don't choose an installation directory---i.e., if you just run ``setup.py -install``\ ---then the :command:`install` command installs to the standard -location for third-party Python modules. This location varies by platform and -by how you built/installed Python itself. On Unix (and macOS, which is also -Unix-based), it also depends on whether the module distribution being installed -is pure Python or contains extensions ("non-pure"): - -.. tabularcolumns:: |l|l|l|l| - -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ -| Platform | Standard installation location | Default value | Notes | -+=================+=====================================================+==================================================+=======+ -| Unix (pure) | :file:`{prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ -| Unix (non-pure) | :file:`{exec-prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ -| Windows | :file:`{prefix}\\Lib\\site-packages` | :file:`C:\\Python{XY}\\Lib\\site-packages` | \(2) | -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ - -Notes: - -(1) - Most Linux distributions include Python as a standard part of the system, so - :file:`{prefix}` and :file:`{exec-prefix}` are usually both :file:`/usr` on - Linux. If you build Python yourself on Linux (or any Unix-like system), the - default :file:`{prefix}` and :file:`{exec-prefix}` are :file:`/usr/local`. - -(2) - The default installation directory on Windows was :file:`C:\\Program - Files\\Python` under Python 1.6a1, 1.5.2, and earlier. - -:file:`{prefix}` and :file:`{exec-prefix}` stand for the directories that Python -is installed to, and where it finds its libraries at run-time. They are always -the same under Windows, and very often the same under Unix and macOS. You -can find out what your Python installation uses for :file:`{prefix}` and -:file:`{exec-prefix}` by running Python in interactive mode and typing a few -simple commands. Under Unix, just type ``python`` at the shell prompt. Under -Windows, choose :menuselection:`Start --> Programs --> Python X.Y --> -Python (command line)`. Once the interpreter is started, you type Python code -at the prompt. For example, on my Linux system, I type the three Python -statements shown below, and get the output as shown, to find out my -:file:`{prefix}` and :file:`{exec-prefix}`: - -.. code-block:: pycon - - Python 2.4 (#26, Aug 7 2004, 17:19:02) - Type "help", "copyright", "credits" or "license" for more information. - >>> import sys - >>> sys.prefix - '/usr' - >>> sys.exec_prefix - '/usr' - -A few other placeholders are used in this document: :file:`{X.Y}` stands for the -version of Python, for example ``3.2``; :file:`{abiflags}` will be replaced by -the value of :data:`sys.abiflags` or the empty string for platforms which don't -define ABI flags; :file:`{distname}` will be replaced by the name of the module -distribution being installed. Dots and capitalization are important in the -paths; for example, a value that uses ``python3.2`` on UNIX will typically use -``Python32`` on Windows. - -If you don't want to install modules to the standard location, or if you don't -have permission to write there, then you need to read about alternate -installations in section :ref:`inst-alt-install`. If you want to customize your -installation directories more heavily, see section :ref:`inst-custom-install` on -custom installations. - - -.. _inst-alt-install: - -Alternate Installation -====================== - -Often, it is necessary or desirable to install modules to a location other than -the standard location for third-party Python modules. For example, on a Unix -system you might not have permission to write to the standard third-party module -directory. Or you might wish to try out a module before making it a standard -part of your local Python installation. This is especially true when upgrading -a distribution already present: you want to make sure your existing base of -scripts still works with the new version before actually upgrading. - -The Distutils :command:`install` command is designed to make installing module -distributions to an alternate location simple and painless. The basic idea is -that you supply a base directory for the installation, and the -:command:`install` command picks a set of directories (called an *installation -scheme*) under this base directory in which to install files. The details -differ across platforms, so read whichever of the following sections applies to -you. - -Note that the various alternate installation schemes are mutually exclusive: you -can pass ``--user``, or ``--home``, or ``--prefix`` and ``--exec-prefix``, or -``--install-base`` and ``--install-platbase``, but you can't mix from these -groups. - - -.. _inst-alt-install-user: - -Alternate installation: the user scheme ---------------------------------------- - -This scheme is designed to be the most convenient solution for users that don't -have write permission to the global site-packages directory or don't want to -install into it. It is enabled with a simple option:: - - python setup.py install --user - -Files will be installed into subdirectories of :data:`site.USER_BASE` (written -as :file:`{userbase}` hereafter). This scheme installs pure Python modules and -extension modules in the same location (also known as :data:`site.USER_SITE`). -Here are the values for UNIX, including macOS: - -=============== =========================================================== -Type of file Installation directory -=============== =========================================================== -modules :file:`{userbase}/lib/python{X.Y}/site-packages` -scripts :file:`{userbase}/bin` -data :file:`{userbase}` -C headers :file:`{userbase}/include/python{X.Y}{abiflags}/{distname}` -=============== =========================================================== - -And here are the values used on Windows: - -=============== =========================================================== -Type of file Installation directory -=============== =========================================================== -modules :file:`{userbase}\\Python{XY}\\site-packages` -scripts :file:`{userbase}\\Python{XY}\\Scripts` -data :file:`{userbase}` -C headers :file:`{userbase}\\Python{XY}\\Include\\{distname}` -=============== =========================================================== - -The advantage of using this scheme compared to the other ones described below is -that the user site-packages directory is under normal conditions always included -in :data:`sys.path` (see :mod:`site` for more information), which means that -there is no additional step to perform after running the :file:`setup.py` script -to finalize the installation. - -The :command:`build_ext` command also has a ``--user`` option to add -:file:`{userbase}/include` to the compiler search path for header files and -:file:`{userbase}/lib` to the compiler search path for libraries as well as to -the runtime search path for shared C libraries (rpath). - - -.. _inst-alt-install-home: - -Alternate installation: the home scheme ---------------------------------------- - -The idea behind the "home scheme" is that you build and maintain a personal -stash of Python modules. This scheme's name is derived from the idea of a -"home" directory on Unix, since it's not unusual for a Unix user to make their -home directory have a layout similar to :file:`/usr/` or :file:`/usr/local/`. -This scheme can be used by anyone, regardless of the operating system they -are installing for. - -Installing a new module distribution is as simple as :: - - python setup.py install --home= - -where you can supply any directory you like for the :option:`!--home` option. On -Unix, lazy typists can just type a tilde (``~``); the :command:`install` command -will expand this to your home directory:: - - python setup.py install --home=~ - -To make Python find the distributions installed with this scheme, you may have -to :ref:`modify Python's search path ` or edit -:mod:`sitecustomize` (see :mod:`site`) to call :func:`site.addsitedir` or edit -:data:`sys.path`. - -The :option:`!--home` option defines the installation base directory. Files are -installed to the following directories under the installation base as follows: - -=============== =========================================================== -Type of file Installation directory -=============== =========================================================== -modules :file:`{home}/lib/python` -scripts :file:`{home}/bin` -data :file:`{home}` -C headers :file:`{home}/include/python/{distname}` -=============== =========================================================== - -(Mentally replace slashes with backslashes if you're on Windows.) - - -.. _inst-alt-install-prefix-unix: - -Alternate installation: Unix (the prefix scheme) ------------------------------------------------- - -The "prefix scheme" is useful when you wish to use one Python installation to -perform the build/install (i.e., to run the setup script), but install modules -into the third-party module directory of a different Python installation (or -something that looks like a different Python installation). If this sounds a -trifle unusual, it is---that's why the user and home schemes come before. However, -there are at least two known cases where the prefix scheme will be useful. - -First, consider that many Linux distributions put Python in :file:`/usr`, rather -than the more traditional :file:`/usr/local`. This is entirely appropriate, -since in those cases Python is part of "the system" rather than a local add-on. -However, if you are installing Python modules from source, you probably want -them to go in :file:`/usr/local/lib/python2.{X}` rather than -:file:`/usr/lib/python2.{X}`. This can be done with :: - - /usr/bin/python setup.py install --prefix=/usr/local - -Another possibility is a network filesystem where the name used to write to a -remote directory is different from the name used to read it: for example, the -Python interpreter accessed as :file:`/usr/local/bin/python` might search for -modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to -be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. This could -be done with :: - - /usr/local/bin/python setup.py install --prefix=/mnt/@server/export - -In either case, the :option:`!--prefix` option defines the installation base, and -the :option:`!--exec-prefix` option defines the platform-specific installation -base, which is used for platform-specific files. (Currently, this just means -non-pure module distributions, but could be expanded to C libraries, binary -executables, etc.) If :option:`!--exec-prefix` is not supplied, it defaults to -:option:`!--prefix`. Files are installed as follows: - -================= ========================================================== -Type of file Installation directory -================= ========================================================== -Python modules :file:`{prefix}/lib/python{X.Y}/site-packages` -extension modules :file:`{exec-prefix}/lib/python{X.Y}/site-packages` -scripts :file:`{prefix}/bin` -data :file:`{prefix}` -C headers :file:`{prefix}/include/python{X.Y}{abiflags}/{distname}` -================= ========================================================== - -There is no requirement that :option:`!--prefix` or :option:`!--exec-prefix` -actually point to an alternate Python installation; if the directories listed -above do not already exist, they are created at installation time. - -Incidentally, the real reason the prefix scheme is important is simply that a -standard Unix installation uses the prefix scheme, but with :option:`!--prefix` -and :option:`!--exec-prefix` supplied by Python itself as ``sys.prefix`` and -``sys.exec_prefix``. Thus, you might think you'll never use the prefix scheme, -but every time you run ``python setup.py install`` without any other options, -you're using it. - -Note that installing extensions to an alternate Python installation has no -effect on how those extensions are built: in particular, the Python header files -(:file:`Python.h` and friends) installed with the Python interpreter used to run -the setup script will be used in compiling extensions. It is your -responsibility to ensure that the interpreter used to run extensions installed -in this way is compatible with the interpreter used to build them. The best way -to do this is to ensure that the two interpreters are the same version of Python -(possibly different builds, or possibly copies of the same build). (Of course, -if your :option:`!--prefix` and :option:`!--exec-prefix` don't even point to an -alternate Python installation, this is immaterial.) - - -.. _inst-alt-install-prefix-windows: - -Alternate installation: Windows (the prefix scheme) ---------------------------------------------------- - -Windows has no concept of a user's home directory, and since the standard Python -installation under Windows is simpler than under Unix, the :option:`!--prefix` -option has traditionally been used to install additional packages in separate -locations on Windows. :: - - python setup.py install --prefix="\Temp\Python" - -to install modules to the :file:`\\Temp\\Python` directory on the current drive. - -The installation base is defined by the :option:`!--prefix` option; the -:option:`!--exec-prefix` option is not supported under Windows, which means that -pure Python modules and extension modules are installed into the same location. -Files are installed as follows: - -=============== ========================================================== -Type of file Installation directory -=============== ========================================================== -modules :file:`{prefix}\\Lib\\site-packages` -scripts :file:`{prefix}\\Scripts` -data :file:`{prefix}` -C headers :file:`{prefix}\\Include\\{distname}` -=============== ========================================================== - - -.. _inst-custom-install: - -Custom Installation -=================== - -Sometimes, the alternate installation schemes described in section -:ref:`inst-alt-install` just don't do what you want. You might want to tweak just -one or two directories while keeping everything under the same base directory, -or you might want to completely redefine the installation scheme. In either -case, you're creating a *custom installation scheme*. - -To create a custom installation scheme, you start with one of the alternate -schemes and override some of the installation directories used for the various -types of files, using these options: - -====================== ======================= -Type of file Override option -====================== ======================= -Python modules ``--install-purelib`` -extension modules ``--install-platlib`` -all modules ``--install-lib`` -scripts ``--install-scripts`` -data ``--install-data`` -C headers ``--install-headers`` -====================== ======================= - -These override options can be relative, absolute, -or explicitly defined in terms of one of the installation base directories. -(There are two installation base directories, and they are normally the -same---they only differ when you use the Unix "prefix scheme" and supply -different ``--prefix`` and ``--exec-prefix`` options; using ``--install-lib`` -will override values computed or given for ``--install-purelib`` and -``--install-platlib``, and is recommended for schemes that don't make a -difference between Python and extension modules.) - -For example, say you're installing a module distribution to your home directory -under Unix---but you want scripts to go in :file:`~/scripts` rather than -:file:`~/bin`. As you might expect, you can override this directory with the -:option:`!--install-scripts` option; in this case, it makes most sense to supply -a relative path, which will be interpreted relative to the installation base -directory (your home directory, in this case):: - - python setup.py install --home=~ --install-scripts=scripts - -Another Unix example: suppose your Python installation was built and installed -with a prefix of :file:`/usr/local/python`, so under a standard installation -scripts will wind up in :file:`/usr/local/python/bin`. If you want them in -:file:`/usr/local/bin` instead, you would supply this absolute directory for the -:option:`!--install-scripts` option:: - - python setup.py install --install-scripts=/usr/local/bin - -(This performs an installation using the "prefix scheme", where the prefix is -whatever your Python interpreter was installed with--- :file:`/usr/local/python` -in this case.) - -If you maintain Python on Windows, you might want third-party modules to live in -a subdirectory of :file:`{prefix}`, rather than right in :file:`{prefix}` -itself. This is almost as easy as customizing the script installation -directory---you just have to remember that there are two types of modules -to worry about, Python and extension modules, which can conveniently be both -controlled by one option:: - - python setup.py install --install-lib=Site - -The specified installation directory is relative to :file:`{prefix}`. Of -course, you also have to ensure that this directory is in Python's module -search path, such as by putting a :file:`.pth` file in a site directory (see -:mod:`site`). See section :ref:`inst-search-path` to find out how to modify -Python's search path. - -If you want to define an entire installation scheme, you just have to supply all -of the installation directory options. The recommended way to do this is to -supply relative paths; for example, if you want to maintain all Python -module-related files under :file:`python` in your home directory, and you want a -separate directory for each platform that you use your home directory from, you -might define the following installation scheme:: - - python setup.py install --home=~ \ - --install-purelib=python/lib \ - --install-platlib=python/lib.$PLAT \ - --install-scripts=python/scripts - --install-data=python/data - -or, equivalently, :: - - python setup.py install --home=~/python \ - --install-purelib=lib \ - --install-platlib='lib.$PLAT' \ - --install-scripts=scripts - --install-data=data - -``$PLAT`` is not (necessarily) an environment variable---it will be expanded by -the Distutils as it parses your command line options, just as it does when -parsing your configuration file(s). - -Obviously, specifying the entire installation scheme every time you install a -new module distribution would be very tedious. Thus, you can put these options -into your Distutils config file (see section :ref:`inst-config-files`): - -.. code-block:: ini - - [install] - install-base=$HOME - install-purelib=python/lib - install-platlib=python/lib.$PLAT - install-scripts=python/scripts - install-data=python/data - -or, equivalently, - -.. code-block:: ini - - [install] - install-base=$HOME/python - install-purelib=lib - install-platlib=lib.$PLAT - install-scripts=scripts - install-data=data - -Note that these two are *not* equivalent if you supply a different installation -base directory when you run the setup script. For example, :: - - python setup.py install --install-base=/tmp - -would install pure modules to :file:`/tmp/python/lib` in the first case, and -to :file:`/tmp/lib` in the second case. (For the second case, you probably -want to supply an installation base of :file:`/tmp/python`.) - -You probably noticed the use of ``$HOME`` and ``$PLAT`` in the sample -configuration file input. These are Distutils configuration variables, which -bear a strong resemblance to environment variables. In fact, you can use -environment variables in config files on platforms that have such a notion but -the Distutils additionally define a few extra variables that may not be in your -environment, such as ``$PLAT``. (And of course, on systems that don't have -environment variables, such as Mac OS 9, the configuration variables supplied by -the Distutils are the only ones you can use.) See section :ref:`inst-config-files` -for details. - -.. note:: When a :ref:`virtual environment ` is activated, any options - that change the installation path will be ignored from all distutils configuration - files to prevent inadvertently installing projects outside of the virtual - environment. - -.. XXX need some Windows examples---when would custom installation schemes be - needed on those platforms? - - -.. XXX Move this to Doc/using - -.. _inst-search-path: - -Modifying Python's Search Path ------------------------------- - -When the Python interpreter executes an :keyword:`import` statement, it searches -for both Python code and extension modules along a search path. A default value -for the path is configured into the Python binary when the interpreter is built. -You can determine the path by importing the :mod:`sys` module and printing the -value of ``sys.path``. :: - - $ python - Python 2.2 (#11, Oct 3 2002, 13:31:27) - [GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - >>> import sys - >>> sys.path - ['', '/usr/local/lib/python2.3', '/usr/local/lib/python2.3/plat-linux2', - '/usr/local/lib/python2.3/lib-tk', '/usr/local/lib/python2.3/lib-dynload', - '/usr/local/lib/python2.3/site-packages'] - >>> - -The null string in ``sys.path`` represents the current working directory. - -The expected convention for locally installed packages is to put them in the -:file:`{...}/site-packages/` directory, but you may want to install Python -modules into some arbitrary directory. For example, your site may have a -convention of keeping all software related to the web server under :file:`/www`. -Add-on Python modules might then belong in :file:`/www/python`, and in order to -import them, this directory must be added to ``sys.path``. There are several -different ways to add the directory. - -The most convenient way is to add a path configuration file to a directory -that's already on Python's path, usually to the :file:`.../site-packages/` -directory. Path configuration files have an extension of :file:`.pth`, and each -line must contain a single path that will be appended to ``sys.path``. (Because -the new paths are appended to ``sys.path``, modules in the added directories -will not override standard modules. This means you can't use this mechanism for -installing fixed versions of standard modules.) - -Paths can be absolute or relative, in which case they're relative to the -directory containing the :file:`.pth` file. See the documentation of -the :mod:`site` module for more information. - -A slightly less convenient way is to edit the :file:`site.py` file in Python's -standard library, and modify ``sys.path``. :file:`site.py` is automatically -imported when the Python interpreter is executed, unless the :option:`-S` switch -is supplied to suppress this behaviour. So you could simply edit -:file:`site.py` and add two lines to it: - -.. code-block:: python - - import sys - sys.path.append('/www/python/') - -However, if you reinstall the same minor version of Python (perhaps when -upgrading from 2.2 to 2.2.2, for example) :file:`site.py` will be overwritten by -the stock version. You'd have to remember that it was modified and save a copy -before doing the installation. - -There are two environment variables that can modify ``sys.path``. -:envvar:`PYTHONHOME` sets an alternate value for the prefix of the Python -installation. For example, if :envvar:`PYTHONHOME` is set to ``/www/python``, -the search path will be set to ``['', '/www/python/lib/pythonX.Y/', -'/www/python/lib/pythonX.Y/plat-linux2', ...]``. - -The :envvar:`PYTHONPATH` variable can be set to a list of paths that will be -added to the beginning of ``sys.path``. For example, if :envvar:`PYTHONPATH` is -set to ``/www/python:/opt/py``, the search path will begin with -``['/www/python', '/opt/py']``. (Note that directories must exist in order to -be added to ``sys.path``; the :mod:`site` module removes paths that don't -exist.) - -Finally, ``sys.path`` is just a regular Python list, so any Python application -can modify it by adding or removing entries. - - -.. _inst-config-files: - -Distutils Configuration Files -============================= - -As mentioned above, you can use Distutils configuration files to record personal -or site preferences for any Distutils options. That is, any option to any -command can be stored in one of two or three (depending on your platform) -configuration files, which will be consulted before the command-line is parsed. -This means that configuration files will override default values, and the -command-line will in turn override configuration files. Furthermore, if -multiple configuration files apply, values from "earlier" files are overridden -by "later" files. - - -.. _inst-config-filenames: - -Location and names of config files ----------------------------------- - -The names and locations of the configuration files vary slightly across -platforms. On Unix and macOS, the three configuration files (in the order -they are processed) are: - -+--------------+----------------------------------------------------------+-------+ -| Type of file | Location and filename | Notes | -+==============+==========================================================+=======+ -| system | :file:`{prefix}/lib/python{ver}/distutils/distutils.cfg` | \(1) | -+--------------+----------------------------------------------------------+-------+ -| personal | :file:`$HOME/.pydistutils.cfg` | \(2) | -+--------------+----------------------------------------------------------+-------+ -| local | :file:`setup.cfg` | \(3) | -+--------------+----------------------------------------------------------+-------+ - -And on Windows, the configuration files are: - -+--------------+-------------------------------------------------+-------+ -| Type of file | Location and filename | Notes | -+==============+=================================================+=======+ -| system | :file:`{prefix}\\Lib\\distutils\\distutils.cfg` | \(4) | -+--------------+-------------------------------------------------+-------+ -| personal | :file:`%HOME%\\pydistutils.cfg` | \(5) | -+--------------+-------------------------------------------------+-------+ -| local | :file:`setup.cfg` | \(3) | -+--------------+-------------------------------------------------+-------+ - -On all platforms, the "personal" file can be temporarily disabled by -passing the ``--no-user-cfg`` option. - -Notes: - -(1) - Strictly speaking, the system-wide configuration file lives in the directory - where the Distutils are installed; under Python 1.6 and later on Unix, this is - as shown. For Python 1.5.2, the Distutils will normally be installed to - :file:`{prefix}/lib/python1.5/site-packages/distutils`, so the system - configuration file should be put there under Python 1.5.2. - -(2) - On Unix, if the :envvar:`HOME` environment variable is not defined, the user's - home directory will be determined with the :func:`getpwuid` function from the - standard :mod:`pwd` module. This is done by the :func:`os.path.expanduser` - function used by Distutils. - -(3) - I.e., in the current directory (usually the location of the setup script). - -(4) - (See also note (1).) Under Python 1.6 and later, Python's default "installation - prefix" is :file:`C:\\Python`, so the system configuration file is normally - :file:`C:\\Python\\Lib\\distutils\\distutils.cfg`. Under Python 1.5.2, the - default prefix was :file:`C:\\Program Files\\Python`, and the Distutils were not - part of the standard library---so the system configuration file would be - :file:`C:\\Program Files\\Python\\distutils\\distutils.cfg` in a standard Python - 1.5.2 installation under Windows. - -(5) - On Windows, if the :envvar:`HOME` environment variable is not defined, - :envvar:`USERPROFILE` then :envvar:`HOMEDRIVE` and :envvar:`HOMEPATH` will - be tried. This is done by the :func:`os.path.expanduser` function used - by Distutils. - - -.. _inst-config-syntax: - -Syntax of config files ----------------------- - -The Distutils configuration files all have the same syntax. The config files -are grouped into sections. There is one section for each Distutils command, -plus a ``global`` section for global options that affect every command. Each -section consists of one option per line, specified as ``option=value``. - -For example, the following is a complete config file that just forces all -commands to run quietly by default: - -.. code-block:: ini - - [global] - verbose=0 - -If this is installed as the system config file, it will affect all processing of -any Python module distribution by any user on the current system. If it is -installed as your personal config file (on systems that support them), it will -affect only module distributions processed by you. And if it is used as the -:file:`setup.cfg` for a particular module distribution, it affects only that -distribution. - -You could override the default "build base" directory and make the -:command:`build\*` commands always forcibly rebuild all files with the -following: - -.. code-block:: ini - - [build] - build-base=blib - force=1 - -which corresponds to the command-line arguments :: - - python setup.py build --build-base=blib --force - -except that including the :command:`build` command on the command-line means -that command will be run. Including a particular command in config files has no -such implication; it only means that if the command is run, the options in the -config file will apply. (Or if other commands that derive values from it are -run, they will use the values in the config file.) - -You can find out the complete list of options for any command using the -:option:`!--help` option, e.g.:: - - python setup.py build --help - -and you can find out the complete list of global options by using -:option:`!--help` without a command:: - - python setup.py --help - -See also the "Reference" section of the "Distributing Python Modules" manual. - - -.. _inst-building-ext: - -Building Extensions: Tips and Tricks -==================================== - -Whenever possible, the Distutils try to use the configuration information made -available by the Python interpreter used to run the :file:`setup.py` script. -For example, the same compiler and linker flags used to compile Python will also -be used for compiling extensions. Usually this will work well, but in -complicated situations this might be inappropriate. This section discusses how -to override the usual Distutils behaviour. - - -.. _inst-tweak-flags: - -Tweaking compiler/linker flags ------------------------------- - -Compiling a Python extension written in C or C++ will sometimes require -specifying custom flags for the compiler and linker in order to use a particular -library or produce a special kind of object code. This is especially true if the -extension hasn't been tested on your platform, or if you're trying to -cross-compile Python. - -In the most general case, the extension author might have foreseen that -compiling the extensions would be complicated, and provided a :file:`Setup` file -for you to edit. This will likely only be done if the module distribution -contains many separate extension modules, or if they often require elaborate -sets of compiler flags in order to work. - -A :file:`Setup` file, if present, is parsed in order to get a list of extensions -to build. Each line in a :file:`Setup` describes a single module. Lines have -the following structure:: - - module ... [sourcefile ...] [cpparg ...] [library ...] - - -Let's examine each of the fields in turn. - -* *module* is the name of the extension module to be built, and should be a - valid Python identifier. You can't just change this in order to rename a module - (edits to the source code would also be needed), so this should be left alone. - -* *sourcefile* is anything that's likely to be a source code file, at least - judging by the filename. Filenames ending in :file:`.c` are assumed to be - written in C, filenames ending in :file:`.C`, :file:`.cc`, and :file:`.c++` are - assumed to be C++, and filenames ending in :file:`.m` or :file:`.mm` are assumed - to be in Objective C. - -* *cpparg* is an argument for the C preprocessor, and is anything starting with - :option:`!-I`, :option:`!-D`, :option:`!-U` or :option:`!-C`. - -* *library* is anything ending in :file:`.a` or beginning with :option:`!-l` or - :option:`!-L`. - -If a particular platform requires a special library on your platform, you can -add it by editing the :file:`Setup` file and running ``python setup.py build``. -For example, if the module defined by the line :: - - foo foomodule.c - -must be linked with the math library :file:`libm.a` on your platform, simply add -:option:`!-lm` to the line:: - - foo foomodule.c -lm - -Arbitrary switches intended for the compiler or the linker can be supplied with -the :option:`!-Xcompiler` *arg* and :option:`!-Xlinker` *arg* options:: - - foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm - -The next option after :option:`!-Xcompiler` and :option:`!-Xlinker` will be -appended to the proper command line, so in the above example the compiler will -be passed the :option:`!-o32` option, and the linker will be passed -:option:`!-shared`. If a compiler option requires an argument, you'll have to -supply multiple :option:`!-Xcompiler` options; for example, to pass ``-x c++`` -the :file:`Setup` file would have to contain ``-Xcompiler -x -Xcompiler c++``. - -Compiler flags can also be supplied through setting the :envvar:`CFLAGS` -environment variable. If set, the contents of :envvar:`CFLAGS` will be added to -the compiler flags specified in the :file:`Setup` file. - - -.. _inst-non-ms-compilers: - -Using non-Microsoft compilers on Windows ----------------------------------------- - -.. sectionauthor:: Rene Liebscher - - - -Borland/CodeGear C++ -^^^^^^^^^^^^^^^^^^^^ - -This subsection describes the necessary steps to use Distutils with the Borland -C++ compiler version 5.5. First you have to know that Borland's object file -format (OMF) is different from the format used by the Python version you can -download from the Python or ActiveState web site. (Python is built with -Microsoft Visual C++, which uses COFF as the object file format.) For this -reason you have to convert Python's library :file:`python25.lib` into the -Borland format. You can do this as follows: - -.. Should we mention that users have to create cfg-files for the compiler? -.. see also http://community.borland.com/article/0,1410,21205,00.html - -:: - - coff2omf python25.lib python25_bcpp.lib - -The :file:`coff2omf` program comes with the Borland compiler. The file -:file:`python25.lib` is in the :file:`Libs` directory of your Python -installation. If your extension uses other libraries (zlib, ...) you have to -convert them too. - -The converted files have to reside in the same directories as the normal -libraries. - -How does Distutils manage to use these libraries with their changed names? If -the extension needs a library (eg. :file:`foo`) Distutils checks first if it -finds a library with suffix :file:`_bcpp` (eg. :file:`foo_bcpp.lib`) and then -uses this library. In the case it doesn't find such a special library it uses -the default name (:file:`foo.lib`.) [#]_ - -To let Distutils compile your extension with Borland C++ you now have to type:: - - python setup.py build --compiler=bcpp - -If you want to use the Borland C++ compiler as the default, you could specify -this in your personal or system-wide configuration file for Distutils (see -section :ref:`inst-config-files`.) - - -.. seealso:: - - `C++Builder Compiler `_ - Information about the free C++ compiler from Borland, including links to the - download pages. - - `Creating Python Extensions Using Borland's Free Compiler `_ - Document describing how to use Borland's free command-line C++ compiler to build - Python. - - -GNU C / Cygwin / MinGW -^^^^^^^^^^^^^^^^^^^^^^ - -This section describes the necessary steps to use Distutils with the GNU C/C++ -compilers in their Cygwin and MinGW distributions. [#]_ For a Python interpreter -that was built with Cygwin, everything should work without any of these -following steps. - -Not all extensions can be built with MinGW or Cygwin, but many can. Extensions -most likely to not work are those that use C++ or depend on Microsoft Visual C -extensions. - -To let Distutils compile your extension with Cygwin you have to type:: - - python setup.py build --compiler=cygwin - -and for Cygwin in no-cygwin mode [#]_ or for MinGW type:: - - python setup.py build --compiler=mingw32 - -If you want to use any of these options/compilers as default, you should -consider writing it in your personal or system-wide configuration file for -Distutils (see section :ref:`inst-config-files`.) - -Older Versions of Python and MinGW -"""""""""""""""""""""""""""""""""" -The following instructions only apply if you're using a version of Python -inferior to 2.4.1 with a MinGW inferior to 3.0.0 (with -binutils-2.13.90-20030111-1). - -These compilers require some special libraries. This task is more complex than -for Borland's C++, because there is no program to convert the library. First -you have to create a list of symbols which the Python DLL exports. (You can find -a good program for this task at -https://sourceforge.net/projects/mingw/files/MinGW/Extension/pexports/). - -.. I don't understand what the next line means. --amk -.. (inclusive the references on data structures.) - -:: - - pexports python25.dll >python25.def - -The location of an installed :file:`python25.dll` will depend on the -installation options and the version and language of Windows. In a "just for -me" installation, it will appear in the root of the installation directory. In -a shared installation, it will be located in the system directory. - -Then you can create from these information an import library for gcc. :: - - /cygwin/bin/dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a - -The resulting library has to be placed in the same directory as -:file:`python25.lib`. (Should be the :file:`libs` directory under your Python -installation directory.) - -If your extension uses other libraries (zlib,...) you might have to convert -them too. The converted files have to reside in the same directories as the -normal libraries do. - - -.. seealso:: - - `Building Python modules on MS Windows platform with MinGW `_ - Information about building the required libraries for the MinGW environment. - - -.. rubric:: Footnotes - -.. [#] This also means you could replace all existing COFF-libraries with OMF-libraries - of the same name. - -.. [#] Check https://www.sourceware.org/cygwin/ for more information - -.. [#] Then you have no POSIX emulation available, but you also don't need - :file:`cygwin1.dll`. diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst index 5aec5178d48f3d..a46c1caefe4d8a 100644 --- a/Doc/installing/index.rst +++ b/Doc/installing/index.rst @@ -19,7 +19,9 @@ solutions to the common pool. This guide covers the installation part of the process. For a guide to creating and sharing your own Python projects, refer to the -:ref:`distribution guide `. +`Python packaging user guide`_. + +.. _Python Packaging User Guide: https://packaging.python.org/en/latest/tutorials/packaging-projects/ .. note:: diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst index 8bd23daee73977..d261e4a4f338a5 100644 --- a/Doc/library/__future__.rst +++ b/Doc/library/__future__.rst @@ -22,42 +22,48 @@ can be inspected programmatically via importing :mod:`__future__` and examining its contents. -Each statement in :file:`__future__.py` is of the form:: +.. _future-classes: - FeatureName = _Feature(OptionalRelease, MandatoryRelease, - CompilerFlag) +.. class:: _Feature + Each statement in :file:`__future__.py` is of the form:: -where, normally, *OptionalRelease* is less than *MandatoryRelease*, and both are -5-tuples of the same form as :data:`sys.version_info`:: + FeatureName = _Feature(OptionalRelease, MandatoryRelease, + CompilerFlag) - (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int - PY_MINOR_VERSION, # the 1; an int - PY_MICRO_VERSION, # the 0; an int - PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string - PY_RELEASE_SERIAL # the 3; an int - ) + where, normally, *OptionalRelease* is less than *MandatoryRelease*, and both are + 5-tuples of the same form as :data:`sys.version_info`:: -*OptionalRelease* records the first release in which the feature was accepted. + (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int + PY_MINOR_VERSION, # the 1; an int + PY_MICRO_VERSION, # the 0; an int + PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string + PY_RELEASE_SERIAL # the 3; an int + ) -In the case of a *MandatoryRelease* that has not yet occurred, -*MandatoryRelease* predicts the release in which the feature will become part of -the language. +.. method:: _Feature.getOptionalRelease() -Else *MandatoryRelease* records when the feature became part of the language; in -releases at or after that, modules no longer need a future statement to use the -feature in question, but may continue to use such imports. + *OptionalRelease* records the first release in which the feature was accepted. -*MandatoryRelease* may also be ``None``, meaning that a planned feature got -dropped. +.. method:: _Feature.getMandatoryRelease() -Instances of class :class:`_Feature` have two corresponding methods, -:meth:`getOptionalRelease` and :meth:`getMandatoryRelease`. + In the case of a *MandatoryRelease* that has not yet occurred, + *MandatoryRelease* predicts the release in which the feature will become part of + the language. -*CompilerFlag* is the (bitfield) flag that should be passed in the fourth -argument to the built-in function :func:`compile` to enable the feature in -dynamically compiled code. This flag is stored in the :attr:`compiler_flag` -attribute on :class:`_Feature` instances. + Else *MandatoryRelease* records when the feature became part of the language; in + releases at or after that, modules no longer need a future statement to use the + feature in question, but may continue to use such imports. + + *MandatoryRelease* may also be ``None``, meaning that a planned feature got + dropped or that it is not yet decided. + +.. attribute:: _Feature.compiler_flag + + *CompilerFlag* is the (bitfield) flag that should be passed in the fourth + argument to the built-in function :func:`compile` to enable the feature in + dynamically compiled code. This flag is stored in the :attr:`_Feature.compiler_flag` + attribute on :class:`_Feature` instances. No feature description will ever be deleted from :mod:`__future__`. Since its introduction in Python 2.1 the following features have found their way into the diff --git a/Doc/library/__main__.rst b/Doc/library/__main__.rst index d29cbdff7830c8..24a32b30bba673 100644 --- a/Doc/library/__main__.rst +++ b/Doc/library/__main__.rst @@ -54,45 +54,45 @@ The top-level code environment can be: * the scope of an interactive prompt:: - >>> __name__ - '__main__' + >>> __name__ + '__main__' * the Python module passed to the Python interpreter as a file argument: - .. code-block:: shell-session + .. code-block:: shell-session - $ python helloworld.py - Hello, world! + $ python helloworld.py + Hello, world! * the Python module or package passed to the Python interpreter with the :option:`-m` argument: - .. code-block:: shell-session + .. code-block:: shell-session - $ python -m tarfile - usage: tarfile.py [-h] [-v] (...) + $ python -m tarfile + usage: tarfile.py [-h] [-v] (...) * Python code read by the Python interpreter from standard input: - .. code-block:: shell-session + .. code-block:: shell-session - $ echo "import this" | python - The Zen of Python, by Tim Peters + $ echo "import this" | python + The Zen of Python, by Tim Peters - Beautiful is better than ugly. - Explicit is better than implicit. - ... + Beautiful is better than ugly. + Explicit is better than implicit. + ... * Python code passed to the Python interpreter with the :option:`-c` argument: - .. code-block:: shell-session + .. code-block:: shell-session - $ python -c "import this" - The Zen of Python, by Tim Peters + $ python -c "import this" + The Zen of Python, by Tim Peters - Beautiful is better than ugly. - Explicit is better than implicit. - ... + Beautiful is better than ugly. + Explicit is better than implicit. + ... In each of these situations, the top-level module's ``__name__`` is set to ``'__main__'``. @@ -102,9 +102,9 @@ top-level environment by checking its own ``__name__``, which allows a common idiom for conditionally executing code when the module is not initialized from an import statement:: - if __name__ == '__main__': - # Execute when the module is not initialized from an import statement. - ... + if __name__ == '__main__': + # Execute when the module is not initialized from an import statement. + ... .. seealso:: @@ -238,9 +238,9 @@ package. For more details, see :ref:`intra-package-references` in the Idiomatic Usage ^^^^^^^^^^^^^^^ -The contents of ``__main__.py`` typically isn't fenced with -``if __name__ == '__main__'`` blocks. Instead, those files are kept short, -functions to execute from other modules. Those other modules can then be +The content of ``__main__.py`` typically isn't fenced with an +``if __name__ == '__main__'`` block. Instead, those files are kept +short and import functions to execute from other modules. Those other modules can then be easily unit-tested and are properly reusable. If used, an ``if __name__ == '__main__'`` block will still work as expected @@ -336,12 +336,12 @@ Note that importing ``__main__`` doesn't cause any issues with unintentionally running top-level code meant for script use which is put in the ``if __name__ == "__main__"`` block of the ``start`` module. Why does this work? -Python inserts an empty ``__main__`` module in :attr:`sys.modules` at +Python inserts an empty ``__main__`` module in :data:`sys.modules` at interpreter startup, and populates it by running top-level code. In our example this is the ``start`` module which runs line by line and imports ``namely``. In turn, ``namely`` imports ``__main__`` (which is really ``start``). That's an import cycle! Fortunately, since the partially populated ``__main__`` -module is present in :attr:`sys.modules`, Python passes that to ``namely``. +module is present in :data:`sys.modules`, Python passes that to ``namely``. See :ref:`Special considerations for __main__ ` in the import system's reference for details on how this works. diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index ba9314e46ab6ea..d7c61c3d7ef126 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -70,10 +70,10 @@ This module defines the following constants and functions: there is no guarantee that the interruption will happen immediately. If given, *signum* is the number of the signal to simulate. - If *signum* is not given, :data:`signal.SIGINT` is simulated. + If *signum* is not given, :const:`signal.SIGINT` is simulated. If the given signal isn't handled by Python (it was set to - :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does + :const:`signal.SIG_DFL` or :const:`signal.SIG_IGN`), this function does nothing. .. versionchanged:: 3.10 @@ -150,8 +150,8 @@ This module defines the following constants and functions: .. data:: TIMEOUT_MAX The maximum value allowed for the *timeout* parameter of - :meth:`Lock.acquire`. Specifying a timeout greater than this value will - raise an :exc:`OverflowError`. + :meth:`Lock.acquire `. Specifying a timeout greater + than this value will raise an :exc:`OverflowError`. .. versionadded:: 3.2 @@ -208,7 +208,7 @@ In addition to these methods, lock objects can also be used via the **Caveats:** - .. index:: pair: module; signal +.. index:: pair: module; signal * Threads interact strangely with interrupts: the :exc:`KeyboardInterrupt` exception will be received by an arbitrary thread. (When the :mod:`signal` @@ -217,8 +217,9 @@ In addition to these methods, lock objects can also be used via the * Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is equivalent to calling :func:`_thread.exit`. -* It is not possible to interrupt the :meth:`acquire` method on a lock --- the - :exc:`KeyboardInterrupt` exception will happen after the lock has been acquired. +* It is not possible to interrupt the :meth:`~threading.Lock.acquire` method on + a lock --- the :exc:`KeyboardInterrupt` exception will happen after the lock + has been acquired. * When the main thread exits, it is system defined whether the other threads survive. On most systems, they are killed without executing diff --git a/Doc/library/array.rst b/Doc/library/array.rst index 0afc217642a756..ad622627724217 100644 --- a/Doc/library/array.rst +++ b/Doc/library/array.rst @@ -53,9 +53,9 @@ Notes: It can be 16 bits or 32 bits depending on the platform. .. versionchanged:: 3.9 - ``array('u')`` now uses ``wchar_t`` as C type instead of deprecated + ``array('u')`` now uses :c:type:`wchar_t` as C type instead of deprecated ``Py_UNICODE``. This change doesn't affect its behavior because - ``Py_UNICODE`` is alias of ``wchar_t`` since Python 3.3. + ``Py_UNICODE`` is alias of :c:type:`wchar_t` since Python 3.3. .. deprecated-removed:: 3.3 3.16 Please migrate to ``'w'`` typecode. diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 530cf30643687f..4ebbe0e5471c88 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -585,7 +585,7 @@ Expressions :class:`Name` or :class:`Attribute` object. Of the arguments: * ``args`` holds a list of the arguments passed by position. - * ``keywords`` holds a list of :class:`keyword` objects representing + * ``keywords`` holds a list of :class:`.keyword` objects representing arguments passed by keyword. When creating a ``Call`` node, ``args`` and ``keywords`` are required, but @@ -650,10 +650,10 @@ Expressions .. class:: NamedExpr(target, value) - A named expression. This AST node is produced by the assignment expressions - operator (also known as the walrus operator). As opposed to the :class:`Assign` - node in which the first argument can be multiple nodes, in this case both - ``target`` and ``value`` must be single nodes. + A named expression. This AST node is produced by the assignment expressions + operator (also known as the walrus operator). As opposed to the :class:`Assign` + node in which the first argument can be multiple nodes, in this case both + ``target`` and ``value`` must be single nodes. .. doctest:: @@ -663,6 +663,7 @@ Expressions target=Name(id='x', ctx=Store()), value=Constant(value=4))) + .. versionadded:: 3.8 Subscripting ~~~~~~~~~~~~ @@ -1036,6 +1037,7 @@ Statements value=Name(id='int', ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 Other statements which are only applicable inside functions or loops are described in other sections. @@ -1318,6 +1320,7 @@ Control flow finalbody=[])], type_ignores=[]) + .. versionadded:: 3.11 .. class:: ExceptHandler(type, name, body) @@ -1407,6 +1410,8 @@ Pattern matching that is being matched against the cases) and ``cases`` contains an iterable of :class:`match_case` nodes with the different cases. + .. versionadded:: 3.10 + .. class:: match_case(pattern, guard, body) A single case pattern in a ``match`` statement. ``pattern`` contains the @@ -1458,6 +1463,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchValue(value) A match literal or value pattern that compares by equality. ``value`` is @@ -1485,6 +1492,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchSingleton(value) A match literal pattern that compares by identity. ``value`` is the @@ -1510,6 +1519,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchSequence(patterns) A match sequence pattern. ``patterns`` contains the patterns to be matched @@ -1541,6 +1552,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchStar(name) Matches the rest of the sequence in a variable length match sequence pattern. @@ -1581,6 +1594,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchMapping(keys, patterns, rest) A match mapping pattern. ``keys`` is a sequence of expression nodes. @@ -1627,6 +1642,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchClass(cls, patterns, kwd_attrs, kwd_patterns) A match class pattern. ``cls`` is an expression giving the nominal class to @@ -1691,6 +1708,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchAs(pattern, name) A match "as-pattern", capture pattern or wildcard pattern. ``pattern`` @@ -1732,6 +1751,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchOr(patterns) A match "or-pattern". An or-pattern matches each of its subpatterns in turn @@ -1764,6 +1785,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. _ast-type-params: Type parameters @@ -1795,6 +1818,8 @@ aliases. ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 + .. class:: ParamSpec(name) A :class:`typing.ParamSpec`. ``name`` is the name of the parameter specification. @@ -1818,6 +1843,8 @@ aliases. ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 + .. class:: TypeVarTuple(name) A :class:`typing.TypeVarTuple`. ``name`` is the name of the type variable tuple. @@ -1842,6 +1869,8 @@ aliases. ctx=Load()))], type_ignores=[]) + .. versionadded:: 3.12 + Function and class definitions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1861,6 +1890,9 @@ Function and class definitions ``type_comment`` is an optional string with the type annotation as a comment. + .. versionchanged:: 3.12 + Added ``type_params``. + .. class:: Lambda(args, body) @@ -2024,7 +2056,7 @@ Function and class definitions * ``name`` is a raw string for the class name * ``bases`` is a list of nodes for explicitly specified base classes. - * ``keywords`` is a list of :class:`keyword` nodes, principally for 'metaclass'. + * ``keywords`` is a list of :class:`.keyword` nodes, principally for 'metaclass'. Other keywords will be passed to the metaclass, as per `PEP-3115 `_. * ``body`` is a list of nodes representing the code within the class @@ -2059,6 +2091,9 @@ Function and class definitions type_params=[])], type_ignores=[]) + .. versionchanged:: 3.12 + Added ``type_params``. + Async and await ^^^^^^^^^^^^^^^ @@ -2067,6 +2102,9 @@ Async and await An ``async def`` function definition. Has the same fields as :class:`FunctionDef`. + .. versionchanged:: 3.12 + Added ``type_params``. + .. class:: Await(value) @@ -2122,10 +2160,12 @@ Async and await 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=None) +.. function:: parse(source, filename='', mode='exec', *, type_comments=False, feature_version=None, optimize=-1) Parse the source into an AST node. Equivalent to ``compile(source, - filename, mode, ast.PyCF_ONLY_AST)``. + filename, mode, flags=FLAGS_VALUE, optimize=optimize)``, + where ``FLAGS_VALUE`` is ``ast.PyCF_ONLY_AST`` if ``optimize <= 0`` + and ``ast.PyCF_OPTIMIZED_AST`` otherwise. If ``type_comments=True`` is given, the parser is modified to check and return type comments as specified by :pep:`484` and :pep:`526`. @@ -2146,7 +2186,7 @@ and classes for traversing abstract syntax trees: 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]``. + ``(3, 7)``; the highest is ``sys.version_info[0:2]``. If source contains a null character ('\0'), :exc:`ValueError` is raised. @@ -2169,6 +2209,10 @@ and classes for traversing abstract syntax trees: .. versionchanged:: 3.8 Added ``type_comments``, ``mode='func_type'`` and ``feature_version``. + .. versionchanged:: 3.13 + The minimum supported version for feature_version is now (3,7) + The ``optimize`` argument was added. + .. function:: unparse(ast_obj) @@ -2439,26 +2483,26 @@ The following options are accepted: .. program:: ast -.. cmdoption:: -h, --help +.. option:: -h, --help Show the help message and exit. -.. cmdoption:: -m - --mode +.. option:: -m + --mode Specify what kind of code must be compiled, like the *mode* argument in :func:`parse`. -.. cmdoption:: --no-type-comments +.. option:: --no-type-comments Don't parse type comments. -.. cmdoption:: -a, --include-attributes +.. option:: -a, --include-attributes Include attributes such as line numbers and column offsets. -.. cmdoption:: -i - --indent +.. option:: -i + --indent Indentation of nodes in AST (number of spaces). diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index 921a394a59fec7..a9c3a0183bb72d 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -34,7 +34,7 @@ There are several ways to enable asyncio debug mode: In addition to enabling the debug mode, consider also: * setting the log level of the :ref:`asyncio logger ` to - :py:data:`logging.DEBUG`, for example the following snippet of code + :py:const:`logging.DEBUG`, for example the following snippet of code can be run at startup of the application:: logging.basicConfig(level=logging.DEBUG) @@ -99,7 +99,7 @@ To schedule a coroutine object from a different OS thread, the # Wait for the result: result = future.result() -To handle signals and to execute subprocesses, the event loop must be +To handle signals the event loop must be run in the main thread. The :meth:`loop.run_in_executor` method can be used with a @@ -142,7 +142,7 @@ Logging asyncio uses the :mod:`logging` module and all logging is performed via the ``"asyncio"`` logger. -The default log level is :py:data:`logging.INFO`, which can be easily +The default log level is :py:const:`logging.INFO`, which can be easily adjusted:: logging.getLogger("asyncio").setLevel(logging.WARNING) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 38f2e2f510c176..361e7bb9c8f2fa 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -403,11 +403,11 @@ Opening network connections Open a streaming transport connection to a given address specified by *host* and *port*. - The socket family can be either :py:data:`~socket.AF_INET` or - :py:data:`~socket.AF_INET6` depending on *host* (or the *family* + The socket family can be either :py:const:`~socket.AF_INET` or + :py:const:`~socket.AF_INET6` depending on *host* (or the *family* argument, if provided). - The socket type will be :py:data:`~socket.SOCK_STREAM`. + The socket type will be :py:const:`~socket.SOCK_STREAM`. *protocol_factory* must be a callable returning an :ref:`asyncio protocol ` implementation. @@ -509,7 +509,7 @@ Opening network connections .. versionchanged:: 3.6 - The socket option :py:data:`~socket.TCP_NODELAY` is set by default + The socket option :py:const:`~socket.TCP_NODELAY` is set by default for all TCP connections. .. versionchanged:: 3.7 @@ -552,11 +552,11 @@ Opening network connections Create a datagram connection. - The socket family can be either :py:data:`~socket.AF_INET`, - :py:data:`~socket.AF_INET6`, or :py:data:`~socket.AF_UNIX`, + The socket family can be either :py:const:`~socket.AF_INET`, + :py:const:`~socket.AF_INET6`, or :py:const:`~socket.AF_UNIX`, depending on *host* (or the *family* argument, if provided). - The socket type will be :py:data:`~socket.SOCK_DGRAM`. + The socket type will be :py:const:`~socket.SOCK_DGRAM`. *protocol_factory* must be a callable returning a :ref:`protocol ` implementation. @@ -581,7 +581,7 @@ Opening network connections * *reuse_port* tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows - and some Unixes. If the :py:data:`~socket.SO_REUSEPORT` constant is not + and some Unixes. If the :py:const:`~socket.SO_REUSEPORT` constant is not defined then this capability is unsupported. * *allow_broadcast* tells the kernel to allow this endpoint to send @@ -607,7 +607,7 @@ Opening network connections .. versionchanged:: 3.8.1 The *reuse_address* parameter is no longer supported, as using - :py:data:`~sockets.SO_REUSEADDR` poses a significant security concern for + :py:const:`~sockets.SO_REUSEADDR` poses a significant security concern for UDP. Explicitly passing ``reuse_address=True`` will raise an exception. When multiple processes with differing UIDs assign sockets to an @@ -616,7 +616,7 @@ Opening network connections For supported platforms, *reuse_port* can be used as a replacement for similar functionality. With *reuse_port*, - :py:data:`~sockets.SO_REUSEPORT` is used instead, which specifically + :py:const:`~sockets.SO_REUSEPORT` is used instead, which specifically prevents processes with differing UIDs from assigning sockets to the same socket address. @@ -634,8 +634,8 @@ Opening network connections Create a Unix connection. - The socket family will be :py:data:`~socket.AF_UNIX`; socket - type will be :py:data:`~socket.SOCK_STREAM`. + The socket family will be :py:const:`~socket.AF_UNIX`; socket + type will be :py:const:`~socket.SOCK_STREAM`. A tuple of ``(transport, protocol)`` is returned on success. @@ -671,7 +671,7 @@ Creating network servers ssl_shutdown_timeout=None, \ start_serving=True) - Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) listening + Create a TCP server (socket type :const:`~socket.SOCK_STREAM`) listening on *port* of the *host* address. Returns a :class:`Server` object. @@ -699,10 +699,10 @@ Creating network servers be selected (note that if *host* resolves to multiple network interfaces, a different random port will be selected for each interface). - * *family* can be set to either :data:`socket.AF_INET` or - :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. + * *family* can be set to either :const:`socket.AF_INET` or + :const:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. If not set, the *family* will be determined from host name - (defaults to :data:`~socket.AF_UNSPEC`). + (defaults to :const:`~socket.AF_UNSPEC`). * *flags* is a bitmask for :meth:`getaddrinfo`. @@ -756,7 +756,7 @@ Creating network servers .. versionchanged:: 3.6 Added *ssl_handshake_timeout* and *start_serving* parameters. - The socket option :py:data:`~socket.TCP_NODELAY` is set by default + The socket option :py:const:`~socket.TCP_NODELAY` is set by default for all TCP connections. .. versionchanged:: 3.11 @@ -777,7 +777,7 @@ Creating network servers start_serving=True) Similar to :meth:`loop.create_server` but works with the - :py:data:`~socket.AF_UNIX` socket family. + :py:const:`~socket.AF_UNIX` socket family. *path* is the name of a Unix domain socket, and is required, unless a *sock* argument is provided. Abstract Unix sockets, @@ -1442,6 +1442,7 @@ async/await code consider using the high-level * *stdin* can be any of these: * a file-like object + * an existing file descriptor (a positive integer), for example those created with :meth:`os.pipe()` * the :const:`subprocess.PIPE` constant (default) which will create a new pipe and connect it, * the value ``None`` which will make the subprocess inherit the file @@ -1593,6 +1594,9 @@ Do not instantiate the :class:`Server` class directly. .. versionchanged:: 3.7 Server object is an asynchronous context manager since Python 3.7. + .. versionchanged:: 3.11 + This class was exposed publicly as ``asyncio.Server`` in Python 3.9.11, 3.10.3 and 3.11. + .. method:: close() Stop serving: close listening sockets and set the :attr:`sockets` @@ -1682,13 +1686,13 @@ Event Loop Implementations asyncio ships with two different event loop implementations: :class:`SelectorEventLoop` and :class:`ProactorEventLoop`. -By default asyncio is configured to use :class:`SelectorEventLoop` -on Unix and :class:`ProactorEventLoop` on Windows. +By default asyncio is configured to use :class:`EventLoop`. .. class:: SelectorEventLoop - An event loop based on the :mod:`selectors` module. + A subclass of :class:`AbstractEventLoop` based on the + :mod:`selectors` module. Uses the most efficient *selector* available for the given platform. It is also possible to manually configure the @@ -1710,7 +1714,7 @@ on Unix and :class:`ProactorEventLoop` on Windows. .. class:: ProactorEventLoop - An event loop for Windows that uses "I/O Completion Ports" (IOCP). + A subclass of :class:`AbstractEventLoop` for Windows that uses "I/O Completion Ports" (IOCP). .. availability:: Windows. @@ -1719,6 +1723,14 @@ on Unix and :class:`ProactorEventLoop` on Windows. `MSDN documentation on I/O Completion Ports `_. +.. class:: EventLoop + + An alias to the most efficient available subclass of :class:`AbstractEventLoop` for the given + platform. + + It is an alias to :class:`SelectorEventLoop` on Unix and :class:`ProactorEventLoop` on Windows. + + .. versionadded:: 3.13 .. class:: AbstractEventLoop diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst index 8ffd356f2d1cc3..e7b293f484f8de 100644 --- a/Doc/library/asyncio-extending.rst +++ b/Doc/library/asyncio-extending.rst @@ -69,7 +69,7 @@ Task lifetime support ===================== A third party task implementation should call the following functions to keep a task -visible by :func:`asyncio.get_tasks` and :func:`asyncio.current_task`: +visible by :func:`asyncio.all_tasks` and :func:`asyncio.current_task`: .. function:: _register_task(task) diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst index 70cec9b2f90248..893ae5518f757d 100644 --- a/Doc/library/asyncio-future.rst +++ b/Doc/library/asyncio-future.rst @@ -276,4 +276,4 @@ the Future has a result:: :func:`concurrent.futures.as_completed` functions. - :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument, - but :func:`concurrent.futures.cancel` does not. + but :meth:`concurrent.futures.Future.cancel` does not. diff --git a/Doc/library/asyncio-llapi-index.rst b/Doc/library/asyncio-llapi-index.rst index 9ce48a24444e66..67136ba69ec875 100644 --- a/Doc/library/asyncio-llapi-index.rst +++ b/Doc/library/asyncio-llapi-index.rst @@ -484,19 +484,19 @@ Protocol classes can implement the following **callback methods**: :widths: 50 50 :class: full-width-table - * - ``callback`` :meth:`pipe_data_received() - ` + * - ``callback`` :meth:`~SubprocessProtocol.pipe_data_received` - Called when the child process writes data into its *stdout* or *stderr* pipe. - * - ``callback`` :meth:`pipe_connection_lost() - ` + * - ``callback`` :meth:`~SubprocessProtocol.pipe_connection_lost` - Called when one of the pipes communicating with the child process is closed. * - ``callback`` :meth:`process_exited() ` - - Called when the child process has exited. + - Called when the child process has exited. It can be called before + :meth:`~SubprocessProtocol.pipe_data_received` and + :meth:`~SubprocessProtocol.pipe_connection_lost` methods. Event Loop Policies diff --git a/Doc/library/asyncio-platforms.rst b/Doc/library/asyncio-platforms.rst index 50ad8a2ab70324..19ec726c1be060 100644 --- a/Doc/library/asyncio-platforms.rst +++ b/Doc/library/asyncio-platforms.rst @@ -37,7 +37,7 @@ All event loops on Windows do not support the following methods: * :meth:`loop.create_unix_connection` and :meth:`loop.create_unix_server` are not supported. - The :data:`socket.AF_UNIX` socket family is specific to Unix. + The :const:`socket.AF_UNIX` socket family is specific to Unix. * :meth:`loop.add_signal_handler` and :meth:`loop.remove_signal_handler` are not supported. diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index 7bc906eaafc1f2..3f734f544afe21 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -708,6 +708,9 @@ factories passed to the :meth:`loop.subprocess_exec` and Called when the child process has exited. + It can be called before :meth:`~SubprocessProtocol.pipe_data_received` and + :meth:`~SubprocessProtocol.pipe_connection_lost` methods. + Examples ======== @@ -746,7 +749,7 @@ received data, and close the connection:: loop = asyncio.get_running_loop() server = await loop.create_server( - lambda: EchoServerProtocol(), + EchoServerProtocol, '127.0.0.1', 8888) async with server: @@ -850,7 +853,7 @@ method, sends back received data:: # One protocol instance will be created to serve all # client requests. transport, protocol = await loop.create_datagram_endpoint( - lambda: EchoServerProtocol(), + EchoServerProtocol, local_addr=('127.0.0.1', 9999)) try: @@ -1003,12 +1006,26 @@ The subprocess is created by the :meth:`loop.subprocess_exec` method:: def __init__(self, exit_future): self.exit_future = exit_future self.output = bytearray() + self.pipe_closed = False + self.exited = False + + def pipe_connection_lost(self, fd, exc): + self.pipe_closed = True + self.check_for_exit() def pipe_data_received(self, fd, data): self.output.extend(data) def process_exited(self): - self.exit_future.set_result(True) + self.exited = True + # process_exited() method can be called before + # pipe_connection_lost() method: wait until both methods are + # called. + self.check_for_exit() + + def check_for_exit(self): + if self.pipe_closed and self.exited: + self.exit_future.set_result(True) async def get_date(): # Get a reference to the event loop as we plan to use diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index b68b2570ef071e..ec170dfde9e9aa 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -42,6 +42,8 @@ Running an asyncio Program This function should be used as a main entry point for asyncio programs, and should ideally only be called once. It is recommended to use *loop_factory* to configure the event loop instead of policies. + Passing :class:`asyncio.EventLoop` allows running asyncio without the + policy system. The executor is given a timeout duration of 5 minutes to shutdown. If the executor hasn't finished within that duration, a warning is diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index bbac1c32b5695f..d8186b6ce75c79 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -157,8 +157,8 @@ and work with streams: .. versionchanged:: 3.10 Removed the *loop* parameter. - .. versionchanged:: 3.11 - Added the *ssl_shutdown_timeout* parameter. + .. versionchanged:: 3.11 + Added the *ssl_shutdown_timeout* parameter. .. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \ diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index b7c83aa04c09f1..bf35b1cb798aee 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -68,7 +68,7 @@ Creating Subprocesses The *limit* argument sets the buffer limit for :class:`StreamReader` wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` - (if :attr:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). + (if :const:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). Return a :class:`~asyncio.subprocess.Process` instance. @@ -86,7 +86,7 @@ Creating Subprocesses The *limit* argument sets the buffer limit for :class:`StreamReader` wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` - (if :attr:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). + (if :const:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). Return a :class:`~asyncio.subprocess.Process` instance. @@ -249,7 +249,7 @@ their completion. Stop the child process. - On POSIX systems this method sends :py:data:`signal.SIGTERM` to the + On POSIX systems this method sends :py:const:`signal.SIGTERM` to the child process. On Windows the Win32 API function :c:func:`TerminateProcess` is diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 0651ff7213e527..88fdf41c7b2a3e 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -592,7 +592,7 @@ Shielding From Cancellation is equivalent to:: - res = await something() + res = await shield(something()) *except* that if the coroutine containing it is cancelled, the Task running in ``something()`` is not cancelled. From the point @@ -631,9 +631,9 @@ Shielding From Cancellation Timeouts ======== -.. coroutinefunction:: timeout(delay) +.. function:: timeout(delay) - An :ref:`asynchronous context manager ` + Return an :ref:`asynchronous context manager ` that can be used to limit the amount of time spent waiting on something. @@ -724,7 +724,7 @@ Timeouts .. versionadded:: 3.11 -.. coroutinefunction:: timeout_at(when) +.. function:: timeout_at(when) Similar to :func:`asyncio.timeout`, except *when* is the absolute time to stop waiting, or ``None``. @@ -767,9 +767,6 @@ Timeouts If the wait is cancelled, the future *aw* is also cancelled. - .. versionchanged:: 3.10 - Removed the *loop* parameter. - .. _asyncio_example_waitfor: Example:: @@ -800,6 +797,9 @@ Timeouts .. versionchanged:: 3.10 Removed the *loop* parameter. + .. versionchanged:: 3.11 + Raises :exc:`TimeoutError` instead of :exc:`asyncio.TimeoutError`. + Waiting Primitives ================== diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index c6a046f534e9a1..c75ab47404c1e4 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -56,6 +56,8 @@ Additionally, there are **low-level** APIs for * :ref:`bridge ` callback-based libraries and code with async/await syntax. +.. _asyncio-cli: + You can experiment with an ``asyncio`` concurrent context in the REPL: .. code-block:: pycon diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index e9f6f0e09de27b..39fabb59bb1984 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -57,10 +57,11 @@ The :mod:`binascii` module defines the following functions: data will raise :exc:`binascii.Error`. Valid base64: - * Conforms to :rfc:`3548`. - * Contains only characters from the base64 alphabet. - * Contains no excess data after padding (including excess padding, newlines, etc.). - * Does not start with a padding. + + * Conforms to :rfc:`3548`. + * Contains only characters from the base64 alphabet. + * Contains no excess data after padding (including excess padding, newlines, etc.). + * Does not start with a padding. .. versionchanged:: 3.11 Added the *strict_mode* parameter. diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 32df99869eb530..ec4aeaa04395ac 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -87,7 +87,8 @@ The :mod:`bz2` module contains: compressed streams. :class:`BZ2File` provides all of the members specified by the - :class:`io.BufferedIOBase`, except for :meth:`detach` and :meth:`truncate`. + :class:`io.BufferedIOBase`, except for :meth:`~io.BufferedIOBase.detach` + and :meth:`~io.IOBase.truncate`. Iteration and the :keyword:`with` statement are supported. :class:`BZ2File` also provides the following method: diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst index 07d04a1c7b582a..157a7537f97dc6 100644 --- a/Doc/library/calendar.rst +++ b/Doc/library/calendar.rst @@ -28,58 +28,6 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is 2 BC, and so on. -.. class:: Day - - Enumeration defining the days of the week as integer constants, from 0 to 6. - - .. attribute:: MONDAY - - .. attribute:: TUESDAY - - .. attribute:: WEDNESDAY - - .. attribute:: THURSDAY - - .. attribute:: FRIDAY - - .. attribute:: SATURDAY - - .. attribute:: SUNDAY - - .. versionadded:: 3.12 - - -.. class:: Month - - Enumeration defining months of the year as integer constants, from 1 to 12. - - .. attribute:: JANUARY - - .. attribute:: FEBRUARY - - .. attribute:: MARCH - - .. attribute:: APRIL - - .. attribute:: MAY - - .. attribute:: JUNE - - .. attribute:: JULY - - .. attribute:: AUGUST - - .. attribute:: SEPTEMBER - - .. attribute:: OCTOBER - - .. attribute:: NOVEMBER - - .. attribute:: DECEMBER - - .. versionadded:: 3.12 - - .. class:: Calendar(firstweekday=0) Creates a :class:`Calendar` object. *firstweekday* is an integer specifying the @@ -446,6 +394,29 @@ The :mod:`calendar` module exports the following data attributes: An array that represents the abbreviated days of the week in the current locale. +.. data:: MONDAY + TUESDAY + WEDNESDAY + THURSDAY + FRIDAY + SATURDAY + SUNDAY + + Aliases for the days of the week, + where ``MONDAY`` is ``0`` and ``SUNDAY`` is ``6``. + + .. versionadded:: 3.12 + + +.. class:: Day + + Enumeration defining days of the week as integer constants. + The members of this enumeration are exported to the module scope as + :data:`MONDAY` through :data:`SUNDAY`. + + .. versionadded:: 3.12 + + .. data:: month_name An array that represents the months of the year in the current locale. This @@ -459,15 +430,56 @@ The :mod:`calendar` module exports the following data attributes: locale. This follows normal convention of January being month number 1, so it has a length of 13 and ``month_abbr[0]`` is the empty string. -.. data:: MONDAY - TUESDAY - WEDNESDAY - THURSDAY - FRIDAY - SATURDAY - SUNDAY - Aliases for day numbers, where ``MONDAY`` is ``0`` and ``SUNDAY`` is ``6``. +.. data:: JANUARY + FEBRUARY + MARCH + APRIL + MAY + JUNE + JULY + AUGUST + SEPTEMBER + OCTOBER + NOVEMBER + DECEMBER + + Aliases for the months of the year, + where ``JANUARY`` is ``1`` and ``DECEMBER`` is ``12``. + + .. versionadded:: 3.12 + + +.. class:: Month + + Enumeration defining months of the year as integer constants. + The members of this enumeration are exported to the module scope as + :data:`JANUARY` through :data:`DECEMBER`. + + .. versionadded:: 3.12 + + +The :mod:`calendar` module defines the following exceptions: + +.. exception:: IllegalMonthError(month) + + A subclass of :exc:`ValueError`, + raised when the given month number is outside of the range 1-12 (inclusive). + + .. attribute:: month + + The invalid month number. + + +.. exception:: IllegalWeekdayError(weekday) + + A subclass of :exc:`ValueError`, + raised when the given weekday number is outside of the range 0-6 (inclusive). + + .. attribute:: weekday + + The invalid weekday number. + .. seealso:: @@ -477,3 +489,146 @@ The :mod:`calendar` module exports the following data attributes: Module :mod:`time` Low-level time related functions. + + +.. _calendar-cli: + +Command-Line Usage +------------------ + +.. versionadded:: 2.5 + +The :mod:`calendar` module can be executed as a script from the command line +to interactively print a calendar. + +.. code-block:: shell + + python -m calendar [-h] [-L LOCALE] [-e ENCODING] [-t {text,html}] + [-w WIDTH] [-l LINES] [-s SPACING] [-m MONTHS] [-c CSS] + [year] [month] + + +For example, to print a calendar for the year 2000: + +.. code-block:: console + + $ python -m calendar 2000 + 2000 + + January February March + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 1 2 3 4 5 + 3 4 5 6 7 8 9 7 8 9 10 11 12 13 6 7 8 9 10 11 12 + 10 11 12 13 14 15 16 14 15 16 17 18 19 20 13 14 15 16 17 18 19 + 17 18 19 20 21 22 23 21 22 23 24 25 26 27 20 21 22 23 24 25 26 + 24 25 26 27 28 29 30 28 29 27 28 29 30 31 + 31 + + April May June + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 7 1 2 3 4 + 3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11 + 10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18 + 17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25 + 24 25 26 27 28 29 30 29 30 31 26 27 28 29 30 + + July August September + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 1 2 3 + 3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10 + 10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17 + 17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24 + 24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30 + 31 + + October November December + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 1 2 3 4 5 1 2 3 + 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10 + 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17 + 16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24 + 23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31 + 30 31 + + +The following options are accepted: + +.. program:: calendar + + +.. option:: --help, -h + + Show the help message and exit. + + +.. option:: --locale LOCALE, -L LOCALE + + The locale to use for month and weekday names. + Defaults to English. + + +.. option:: --encoding ENCODING, -e ENCODING + + The encoding to use for output. + :option:`--encoding` is required if :option:`--locale` is set. + + +.. option:: --type {text,html}, -t {text,html} + + Print the calendar to the terminal as text, + or as an HTML document. + + +.. option:: year + + The year to print the calendar for. + Must be a number between 1 and 9999. + Defaults to the current year. + + +.. option:: month + + The month of the specified :option:`year` to print the calendar for. + Must be a number between 1 and 12, + and may only be used in text mode. + Defaults to printing a calendar for the full year. + + +*Text-mode options:* + +.. option:: --width WIDTH, -w WIDTH + + The width of the date column in terminal columns. + The date is printed centred in the column. + Any value lower than 2 is ignored. + Defaults to 2. + + +.. option:: --lines LINES, -l LINES + + The number of lines for each week in terminal rows. + The date is printed top-aligned. + Any value lower than 1 is ignored. + Defaults to 1. + + +.. option:: --spacing SPACING, -s SPACING + + The space between months in columns. + Any value lower than 2 is ignored. + Defaults to 6. + + +.. option:: --months MONTHS, -m MONTHS + + The number of months printed per row. + Defaults to 3. + + +*HTML-mode options:* + +.. option:: --css CSS, -c CSS + + The path of a CSS stylesheet to use for the calendar. + This must either be relative to the generated HTML, + or an absolute HTTP or ``file:///`` URL. diff --git a/Doc/library/cmdline.rst b/Doc/library/cmdline.rst new file mode 100644 index 00000000000000..b2379befeffcba --- /dev/null +++ b/Doc/library/cmdline.rst @@ -0,0 +1,57 @@ +++++++++++++++++++++++++++++++++++++ +Modules command-line interface (CLI) +++++++++++++++++++++++++++++++++++++ + +The following modules have a command-line interface. + +* :ref:`ast ` +* :ref:`asyncio ` +* :mod:`base64` +* :ref:`calendar ` +* :mod:`code` +* :ref:`compileall ` +* :mod:`cProfile`: see :ref:`profile ` +* :ref:`difflib ` +* :ref:`dis ` +* :mod:`doctest` +* :mod:`!encodings.rot_13` +* :mod:`ensurepip` +* :mod:`filecmp` +* :mod:`fileinput` +* :mod:`ftplib` +* :ref:`gzip ` +* :ref:`http.server ` +* :mod:`!idlelib` +* :ref:`inspect ` +* :ref:`json.tool ` +* :mod:`mimetypes` +* :mod:`pdb` +* :mod:`pickle` +* :ref:`pickletools ` +* :mod:`platform` +* :mod:`poplib` +* :ref:`profile ` +* :mod:`pstats` +* :ref:`py_compile ` +* :mod:`pyclbr` +* :mod:`pydoc` +* :mod:`quopri` +* :mod:`runpy` +* :ref:`site ` +* :ref:`sqlite3 ` +* :ref:`sysconfig ` +* :mod:`tabnanny` +* :ref:`tarfile ` +* :mod:`!this` +* :ref:`timeit ` +* :ref:`tokenize ` +* :ref:`trace ` +* :mod:`turtledemo` +* :ref:`unittest ` +* :ref:`uuid ` +* :mod:`venv` +* :mod:`webbrowser` +* :ref:`zipapp ` +* :ref:`zipfile ` + +See also the :ref:`Python command-line interface `. diff --git a/Doc/library/code.rst b/Doc/library/code.rst index 538e5afc7822aa..3d7f43c86a0557 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -163,12 +163,12 @@ interpreter objects as well as the following additions. Push a line of source text to the interpreter. The line should not have a trailing newline; it may have internal newlines. The line is appended to a - buffer and the interpreter's :meth:`runsource` method is called with the + buffer and the interpreter's :meth:`~InteractiveInterpreter.runsource` method is called with the concatenated contents of the buffer as source. If this indicates that the command was executed or invalid, the buffer is reset; otherwise, the command is incomplete, and the buffer is left as it was after the line was appended. The return value is ``True`` if more input is required, ``False`` if the line was - dealt with in some way (this is the same as :meth:`runsource`). + dealt with in some way (this is the same as :meth:`!runsource`). .. method:: InteractiveConsole.resetbuffer() diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 8225236350d22e..2db4a67d1973d5 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -345,9 +345,10 @@ The following error handlers can be used with all Python +-------------------------+-----------------------------------------------+ | ``'backslashreplace'`` | Replace with backslashed escape sequences. | | | On encoding, use hexadecimal form of Unicode | -| | code point with formats ``\xhh`` ``\uxxxx`` | -| | ``\Uxxxxxxxx``. On decoding, use hexadecimal | -| | form of byte value with format ``\xhh``. | +| | code point with formats :samp:`\\x{hh}` | +| | :samp:`\\u{xxxx}` :samp:`\\U{xxxxxxxx}`. | +| | On decoding, use hexadecimal form of byte | +| | value with format :samp:`\\x{hh}`. | | | Implemented in | | | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ @@ -373,8 +374,9 @@ The following error handlers are only applicable to encoding (within +=========================+===============================================+ | ``'xmlcharrefreplace'`` | Replace with XML/HTML numeric character | | | reference, which is a decimal form of Unicode | -| | code point with format ``&#num;`` Implemented | -| | in :func:`xmlcharrefreplace_errors`. | +| | code point with format :samp:`&#{num};`. | +| | Implemented in | +| | :func:`xmlcharrefreplace_errors`. | +-------------------------+-----------------------------------------------+ | ``'namereplace'`` | Replace with ``\N{...}`` escape sequences, | | | what appears in the braces is the Name | @@ -478,8 +480,9 @@ functions: Malformed data is replaced by a backslashed escape sequence. On encoding, use the hexadecimal form of Unicode code point with formats - ``\xhh`` ``\uxxxx`` ``\Uxxxxxxxx``. On decoding, use the hexadecimal form of - byte value with format ``\xhh``. + :samp:`\\x{hh}` :samp:`\\u{xxxx}` :samp:`\\U{xxxxxxxx}`. + On decoding, use the hexadecimal form of + byte value with format :samp:`\\x{hh}`. .. versionchanged:: 3.5 Works with decoding and translating. @@ -492,7 +495,7 @@ functions: The unencodable character is replaced by an appropriate XML/HTML numeric character reference, which is a decimal form of Unicode code point with - format ``&#num;`` . + format :samp:`&#{num};` . .. function:: namereplace_errors(exception) @@ -1346,9 +1349,10 @@ encodings. | | | supported. | +--------------------+---------+---------------------------+ | raw_unicode_escape | | Latin-1 encoding with | -| | | ``\uXXXX`` and | -| | | ``\UXXXXXXXX`` for other | -| | | code points. Existing | +| | | :samp:`\\u{XXXX}` and | +| | | :samp:`\\U{XXXXXXXX}` | +| | | for other code points. | +| | | Existing | | | | backslashes are not | | | | escaped in any way. | | | | It is used in the Python | diff --git a/Doc/library/codeop.rst b/Doc/library/codeop.rst index 90df499f8207b7..55606e1c5f09ac 100644 --- a/Doc/library/codeop.rst +++ b/Doc/library/codeop.rst @@ -58,7 +58,7 @@ To do just the former: .. class:: Compile() - Instances of this class have :meth:`__call__` methods identical in signature to + Instances of this class have :meth:`~object.__call__` methods identical in signature to the built-in function :func:`compile`, but with the difference that if the instance compiles program text containing a :mod:`__future__` statement, the instance 'remembers' and compiles all subsequent program texts with the @@ -67,7 +67,7 @@ To do just the former: .. class:: CommandCompiler() - Instances of this class have :meth:`__call__` methods identical in signature to + Instances of this class have :meth:`~object.__call__` methods identical in signature to :func:`compile_command`; the difference is that if the instance compiles program text containing a :mod:`__future__` statement, the instance 'remembers' and compiles all subsequent program texts with the statement in force. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index bb46782c06e1c8..02df6e9f137926 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -120,26 +120,26 @@ The class can be used to simulate nested scopes and is useful in templating. .. seealso:: - * The `MultiContext class - `_ - in the Enthought `CodeTools package - `_ has options to support - writing to any mapping in the chain. + * The `MultiContext class + `_ + in the Enthought `CodeTools package + `_ has options to support + writing to any mapping in the chain. - * Django's `Context class - `_ - for templating is a read-only chain of mappings. It also features - pushing and popping of contexts similar to the - :meth:`~collections.ChainMap.new_child` method and the - :attr:`~collections.ChainMap.parents` property. + * Django's `Context class + `_ + for templating is a read-only chain of mappings. It also features + pushing and popping of contexts similar to the + :meth:`~collections.ChainMap.new_child` method and the + :attr:`~collections.ChainMap.parents` property. - * The `Nested Contexts recipe - `_ has options to control - whether writes and other mutations apply only to the first mapping or to - any mapping in the chain. + * The `Nested Contexts recipe + `_ has options to control + whether writes and other mutations apply only to the first mapping or to + any mapping in the chain. - * A `greatly simplified read-only version of Chainmap - `_. + * A `greatly simplified read-only version of Chainmap + `_. :class:`ChainMap` Examples and Recipes @@ -358,7 +358,7 @@ Common patterns for working with :class:`Counter` objects:: list(c) # list unique elements set(c) # convert to a set dict(c) # convert to a regular dictionary - c.items() # convert to a list of (elem, cnt) pairs + c.items() # access the (elem, cnt) pairs Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs c.most_common()[:-n-1:-1] # n least common elements +c # remove zero and negative counts @@ -429,22 +429,22 @@ or subtracting from an empty counter. .. seealso:: - * `Bag class `_ - in Smalltalk. + * `Bag class `_ + in Smalltalk. - * Wikipedia entry for `Multisets `_. + * Wikipedia entry for `Multisets `_. - * `C++ multisets `_ - tutorial with examples. + * `C++ multisets `_ + tutorial with examples. - * For mathematical operations on multisets and their use cases, see - *Knuth, Donald. The Art of Computer Programming Volume II, - Section 4.6.3, Exercise 19*. + * For mathematical operations on multisets and their use cases, see + *Knuth, Donald. The Art of Computer Programming Volume II, + Section 4.6.3, Exercise 19*. - * To enumerate all distinct multisets of a given size over a given set of - elements, see :func:`itertools.combinations_with_replacement`:: + * To enumerate all distinct multisets of a given size over a given set of + elements, see :func:`itertools.combinations_with_replacement`:: - map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC + map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC :class:`deque` objects @@ -979,6 +979,8 @@ field names, the method and attribute names start with an underscore. >>> for partnum, record in inventory.items(): ... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now()) + Named tuples are also supported by generic function :func:`copy.replace`. + .. attribute:: somenamedtuple._fields Tuple of strings listing the field names. Useful for introspection @@ -1060,20 +1062,20 @@ fields: .. seealso:: - * See :class:`typing.NamedTuple` for a way to add type hints for named - tuples. It also provides an elegant notation using the :keyword:`class` - keyword:: + * See :class:`typing.NamedTuple` for a way to add type hints for named + tuples. It also provides an elegant notation using the :keyword:`class` + keyword:: - class Component(NamedTuple): - part_number: int - weight: float - description: Optional[str] = None + class Component(NamedTuple): + part_number: int + weight: float + description: Optional[str] = None - * See :meth:`types.SimpleNamespace` for a mutable namespace based on an - underlying dictionary instead of a tuple. + * See :meth:`types.SimpleNamespace` for a mutable namespace based on an + underlying dictionary instead of a tuple. - * The :mod:`dataclasses` module provides a decorator and functions for - automatically adding generated special methods to user-defined classes. + * The :mod:`dataclasses` module provides a decorator and functions for + automatically adding generated special methods to user-defined classes. :class:`OrderedDict` objects @@ -1224,7 +1226,7 @@ variants of :func:`functools.lru_cache`: result = self.func(*args) self.cache[args] = time(), result if len(self.cache) > self.maxsize: - self.cache.popitem(0) + self.cache.popitem(last=False) return result @@ -1256,12 +1258,12 @@ variants of :func:`functools.lru_cache`: if self.requests[args] <= self.cache_after: self.requests.move_to_end(args) if len(self.requests) > self.maxrequests: - self.requests.popitem(0) + self.requests.popitem(last=False) else: self.requests.pop(args, None) self.cache[args] = result if len(self.cache) > self.maxsize: - self.cache.popitem(0) + self.cache.popitem(last=False) return result .. doctest:: diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index 180f5b81c2b615..df1eefab839cc1 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -16,6 +16,8 @@ have write permission to the library directories. .. include:: ../includes/wasm-notavail.rst +.. _compileall-cli: + Command-line use ---------------- @@ -24,28 +26,28 @@ compile Python sources. .. program:: compileall -.. cmdoption:: directory ... - file ... +.. option:: directory ... + file ... Positional arguments are files to compile or directories that contain source files, traversed recursively. If no argument is given, behave as if - the command line was ``-l ``. + the command line was :samp:`-l {}`. -.. cmdoption:: -l +.. option:: -l Do not recurse into subdirectories, only compile source code files directly contained in the named or implied directories. -.. cmdoption:: -f +.. option:: -f Force rebuild even if timestamps are up-to-date. -.. cmdoption:: -q +.. option:: -q Do not print the list of files compiled. If passed once, error messages will still be printed. If passed twice (``-qq``), all output is suppressed. -.. cmdoption:: -d destdir +.. option:: -d destdir Directory prepended to the path to each file being compiled. This will appear in compilation time tracebacks, and is also compiled in to the @@ -53,45 +55,45 @@ compile Python sources. cases where the source file does not exist at the time the byte-code file is executed. -.. cmdoption:: -s strip_prefix -.. cmdoption:: -p prepend_prefix +.. option:: -s strip_prefix +.. option:: -p prepend_prefix Remove (``-s``) or append (``-p``) the given prefix of paths recorded in the ``.pyc`` files. Cannot be combined with ``-d``. -.. cmdoption:: -x regex +.. option:: -x regex regex is used to search the full path to each file considered for compilation, and if the regex produces a match, the file is skipped. -.. cmdoption:: -i list +.. option:: -i list Read the file ``list`` and add each line that it contains to the list of files and directories to compile. If ``list`` is ``-``, read lines from ``stdin``. -.. cmdoption:: -b +.. option:: -b Write the byte-code files to their legacy locations and names, which may overwrite byte-code files created by another version of Python. The default is to write files to their :pep:`3147` locations and names, which allows byte-code files from multiple versions of Python to coexist. -.. cmdoption:: -r +.. option:: -r Control the maximum recursion level for subdirectories. If this is given, then ``-l`` option will not be taken into account. :program:`python -m compileall -r 0` is equivalent to :program:`python -m compileall -l`. -.. cmdoption:: -j N +.. option:: -j N Use *N* workers to compile the files within the given directory. - If ``0`` is used, then the result of :func:`os.cpu_count()` + If ``0`` is used, then the result of :func:`os.process_cpu_count()` will be used. -.. cmdoption:: --invalidation-mode [timestamp|checked-hash|unchecked-hash] +.. option:: --invalidation-mode [timestamp|checked-hash|unchecked-hash] Control how the generated byte-code files are invalidated at runtime. The ``timestamp`` value, means that ``.pyc`` files with the source timestamp @@ -104,17 +106,17 @@ compile Python sources. variable is not set, and ``checked-hash`` if the ``SOURCE_DATE_EPOCH`` environment variable is set. -.. cmdoption:: -o level +.. option:: -o level Compile with the given optimization level. May be used multiple times to compile for multiple levels at a time (for example, ``compileall -o 1 -o 2``). -.. cmdoption:: -e dir +.. option:: -e dir Ignore symlinks pointing outside the given directory. -.. cmdoption:: --hardlink-dupes +.. option:: --hardlink-dupes If two ``.pyc`` files with different optimization level have the same content, use hard links to consolidate duplicate files. @@ -141,9 +143,9 @@ There is no command-line option to control the optimization level used by the :func:`compile` function, because the Python interpreter itself already provides the option: :program:`python -O -m compileall`. -Similarly, the :func:`compile` function respects the :attr:`sys.pycache_prefix` +Similarly, the :func:`compile` function respects the :data:`sys.pycache_prefix` setting. The generated bytecode cache will only be useful if :func:`compile` is -run with the same :attr:`sys.pycache_prefix` (if any) that will be used at +run with the same :data:`sys.pycache_prefix` (if any) that will be used at runtime. Public functions diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 09c9fc4e6e227a..deefb8606ead84 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -29,83 +29,83 @@ Executor Objects An abstract class that provides methods to execute calls asynchronously. It should not be used directly, but through its concrete subclasses. - .. method:: submit(fn, /, *args, **kwargs) + .. method:: submit(fn, /, *args, **kwargs) - Schedules the callable, *fn*, to be executed as ``fn(*args, **kwargs)`` - and returns a :class:`Future` object representing the execution of the - callable. :: + Schedules the callable, *fn*, to be executed as ``fn(*args, **kwargs)`` + and returns a :class:`Future` object representing the execution of the + callable. :: - with ThreadPoolExecutor(max_workers=1) as executor: - future = executor.submit(pow, 323, 1235) - print(future.result()) + with ThreadPoolExecutor(max_workers=1) as executor: + future = executor.submit(pow, 323, 1235) + print(future.result()) - .. method:: map(func, *iterables, timeout=None, chunksize=1) + .. method:: map(func, *iterables, timeout=None, chunksize=1) - Similar to :func:`map(func, *iterables) ` except: + Similar to :func:`map(func, *iterables) ` except: - * the *iterables* are collected immediately rather than lazily; + * the *iterables* are collected immediately rather than lazily; - * *func* is executed asynchronously and several calls to - *func* may be made concurrently. + * *func* is executed asynchronously and several calls to + *func* may be made concurrently. - The returned iterator raises a :exc:`TimeoutError` - if :meth:`~iterator.__next__` is called and the result isn't available - after *timeout* seconds from the original call to :meth:`Executor.map`. - *timeout* can be an int or a float. If *timeout* is not specified or - ``None``, there is no limit to the wait time. + The returned iterator raises a :exc:`TimeoutError` + if :meth:`~iterator.__next__` is called and the result isn't available + after *timeout* seconds from the original call to :meth:`Executor.map`. + *timeout* can be an int or a float. If *timeout* is not specified or + ``None``, there is no limit to the wait time. - If a *func* call raises an exception, then that exception will be - raised when its value is retrieved from the iterator. + If a *func* call raises an exception, then that exception will be + raised when its value is retrieved from the iterator. - When using :class:`ProcessPoolExecutor`, this method chops *iterables* - into a number of chunks which it submits to the pool as separate - tasks. The (approximate) size of these chunks can be specified by - setting *chunksize* to a positive integer. For very long iterables, - using a large value for *chunksize* can significantly improve - performance compared to the default size of 1. With - :class:`ThreadPoolExecutor`, *chunksize* has no effect. + When using :class:`ProcessPoolExecutor`, this method chops *iterables* + into a number of chunks which it submits to the pool as separate + tasks. The (approximate) size of these chunks can be specified by + setting *chunksize* to a positive integer. For very long iterables, + using a large value for *chunksize* can significantly improve + performance compared to the default size of 1. With + :class:`ThreadPoolExecutor`, *chunksize* has no effect. - .. versionchanged:: 3.5 - Added the *chunksize* argument. + .. versionchanged:: 3.5 + Added the *chunksize* argument. - .. method:: shutdown(wait=True, *, cancel_futures=False) + .. method:: shutdown(wait=True, *, cancel_futures=False) - Signal the executor that it should free any resources that it is using - when the currently pending futures are done executing. Calls to - :meth:`Executor.submit` and :meth:`Executor.map` made after shutdown will - raise :exc:`RuntimeError`. + Signal the executor that it should free any resources that it is using + when the currently pending futures are done executing. Calls to + :meth:`Executor.submit` and :meth:`Executor.map` made after shutdown will + raise :exc:`RuntimeError`. - If *wait* is ``True`` then this method will not return until all the - pending futures are done executing and the resources associated with the - executor have been freed. If *wait* is ``False`` then this method will - return immediately and the resources associated with the executor will be - freed when all pending futures are done executing. Regardless of the - value of *wait*, the entire Python program will not exit until all - pending futures are done executing. + If *wait* is ``True`` then this method will not return until all the + pending futures are done executing and the resources associated with the + executor have been freed. If *wait* is ``False`` then this method will + return immediately and the resources associated with the executor will be + freed when all pending futures are done executing. Regardless of the + value of *wait*, the entire Python program will not exit until all + pending futures are done executing. - If *cancel_futures* is ``True``, this method will cancel all pending - futures that the executor has not started running. Any futures that - are completed or running won't be cancelled, regardless of the value - of *cancel_futures*. + If *cancel_futures* is ``True``, this method will cancel all pending + futures that the executor has not started running. Any futures that + are completed or running won't be cancelled, regardless of the value + of *cancel_futures*. - If both *cancel_futures* and *wait* are ``True``, all futures that the - executor has started running will be completed prior to this method - returning. The remaining futures are cancelled. + If both *cancel_futures* and *wait* are ``True``, all futures that the + executor has started running will be completed prior to this method + returning. The remaining futures are cancelled. - You can avoid having to call this method explicitly if you use the - :keyword:`with` statement, which will shutdown the :class:`Executor` - (waiting as if :meth:`Executor.shutdown` were called with *wait* set to - ``True``):: + You can avoid having to call this method explicitly if you use the + :keyword:`with` statement, which will shutdown the :class:`Executor` + (waiting as if :meth:`Executor.shutdown` were called with *wait* set to + ``True``):: - import shutil - with ThreadPoolExecutor(max_workers=4) as e: - e.submit(shutil.copy, 'src1.txt', 'dest1.txt') - e.submit(shutil.copy, 'src2.txt', 'dest2.txt') - e.submit(shutil.copy, 'src3.txt', 'dest3.txt') - e.submit(shutil.copy, 'src4.txt', 'dest4.txt') + import shutil + with ThreadPoolExecutor(max_workers=4) as e: + e.submit(shutil.copy, 'src1.txt', 'dest1.txt') + e.submit(shutil.copy, 'src2.txt', 'dest2.txt') + e.submit(shutil.copy, 'src3.txt', 'dest3.txt') + e.submit(shutil.copy, 'src4.txt', 'dest4.txt') - .. versionchanged:: 3.9 - Added *cancel_futures*. + .. versionchanged:: 3.9 + Added *cancel_futures*. ThreadPoolExecutor @@ -188,6 +188,10 @@ And:: ThreadPoolExecutor now reuses idle worker threads before starting *max_workers* worker threads too. + .. versionchanged:: 3.13 + Default value of *max_workers* is changed to + ``min(32, (os.process_cpu_count() or 1) + 4)``. + .. _threadpoolexecutor-example: @@ -243,7 +247,7 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. An :class:`Executor` subclass that executes calls asynchronously using a pool of at most *max_workers* processes. If *max_workers* is ``None`` or not - given, it will default to the number of processors on the machine. + given, it will default to :func:`os.process_cpu_count`. If *max_workers* is less than or equal to ``0``, then a :exc:`ValueError` will be raised. On Windows, *max_workers* must be less than or equal to ``61``. If it is not @@ -293,6 +297,18 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. The *max_tasks_per_child* argument was added to allow users to control the lifetime of workers in the pool. + .. versionchanged:: 3.12 + On POSIX systems, if your application has multiple threads and the + :mod:`multiprocessing` context uses the ``"fork"`` start method: + The :func:`os.fork` function called internally to spawn workers may raise a + :exc:`DeprecationWarning`. Pass a *mp_context* configured to use a + different start method. See the :func:`os.fork` documentation for + further explanation. + + .. versionchanged:: 3.13 + *max_workers* uses :func:`os.process_cpu_count` by default, instead of + :func:`os.cpu_count`. + .. _processpoolexecutor-example: ProcessPoolExecutor Example @@ -345,117 +361,117 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. instances are created by :meth:`Executor.submit` and should not be created directly except for testing. - .. method:: cancel() + .. method:: cancel() - 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``. + 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() + .. method:: cancelled() - Return ``True`` if the call was successfully cancelled. + Return ``True`` if the call was successfully cancelled. - .. method:: running() + .. method:: running() - Return ``True`` if the call is currently being executed and cannot be - cancelled. + Return ``True`` if the call is currently being executed and cannot be + cancelled. - .. method:: done() + .. method:: done() - Return ``True`` if the call was successfully cancelled or finished - running. + Return ``True`` if the call was successfully cancelled or finished + running. - .. method:: result(timeout=None) + .. method:: result(timeout=None) - Return the value returned by the call. If the call hasn't yet completed - then this method will wait up to *timeout* seconds. If the call hasn't - completed in *timeout* seconds, then a - :exc:`TimeoutError` will be raised. *timeout* can be - an int or float. If *timeout* is not specified or ``None``, there is no - limit to the wait time. + Return the value returned by the call. If the call hasn't yet completed + then this method will wait up to *timeout* seconds. If the call hasn't + completed in *timeout* seconds, then a + :exc:`TimeoutError` will be raised. *timeout* can be + an int or float. If *timeout* is not specified or ``None``, there is no + limit to the wait time. - If the future is cancelled before completing then :exc:`.CancelledError` - will be raised. + If the future is cancelled before completing then :exc:`.CancelledError` + will be raised. - If the call raised an exception, this method will raise the same exception. + If the call raised an exception, this method will raise the same exception. - .. method:: exception(timeout=None) + .. method:: exception(timeout=None) - Return the exception raised by the call. If the call hasn't yet - completed then this method will wait up to *timeout* seconds. If the - call hasn't completed in *timeout* seconds, then a - :exc:`TimeoutError` will be raised. *timeout* can be - an int or float. If *timeout* is not specified or ``None``, there is no - limit to the wait time. + Return the exception raised by the call. If the call hasn't yet + completed then this method will wait up to *timeout* seconds. If the + call hasn't completed in *timeout* seconds, then a + :exc:`TimeoutError` will be raised. *timeout* can be + an int or float. If *timeout* is not specified or ``None``, there is no + limit to the wait time. - If the future is cancelled before completing then :exc:`.CancelledError` - will be raised. + If the future is cancelled before completing then :exc:`.CancelledError` + will be raised. - If the call completed without raising, ``None`` is returned. + If the call completed without raising, ``None`` is returned. - .. method:: add_done_callback(fn) + .. method:: add_done_callback(fn) - Attaches the callable *fn* to the future. *fn* will be called, with the - future as its only argument, when the future is cancelled or finishes - running. + Attaches the callable *fn* to the future. *fn* will be called, with the + future as its only argument, when the future is cancelled or finishes + running. - Added callables are called in the order that they were added and are - always called in a thread belonging to the process that added them. If - the callable raises an :exc:`Exception` subclass, it will be logged and - ignored. If the callable raises a :exc:`BaseException` subclass, the - behavior is undefined. + Added callables are called in the order that they were added and are + always called in a thread belonging to the process that added them. If + the callable raises an :exc:`Exception` subclass, it will be logged and + ignored. If the callable raises a :exc:`BaseException` subclass, the + behavior is undefined. - If the future has already completed or been cancelled, *fn* will be - called immediately. + If the future has already completed or been cancelled, *fn* will be + called immediately. The following :class:`Future` methods are meant for use in unit tests and :class:`Executor` implementations. - .. method:: set_running_or_notify_cancel() + .. method:: set_running_or_notify_cancel() - This method should only be called by :class:`Executor` implementations - before executing the work associated with the :class:`Future` and by unit - tests. + This method should only be called by :class:`Executor` implementations + before executing the work associated with the :class:`Future` and by unit + tests. - If the method returns ``False`` then the :class:`Future` was cancelled, - i.e. :meth:`Future.cancel` was called and returned ``True``. Any threads - waiting on the :class:`Future` completing (i.e. through - :func:`as_completed` or :func:`wait`) will be woken up. + If the method returns ``False`` then the :class:`Future` was cancelled, + i.e. :meth:`Future.cancel` was called and returned ``True``. Any threads + waiting on the :class:`Future` completing (i.e. through + :func:`as_completed` or :func:`wait`) will be woken up. - If the method returns ``True`` then the :class:`Future` was not cancelled - and has been put in the running state, i.e. calls to - :meth:`Future.running` will return ``True``. + If the method returns ``True`` then the :class:`Future` was not cancelled + and has been put in the running state, i.e. calls to + :meth:`Future.running` will return ``True``. - This method can only be called once and cannot be called after - :meth:`Future.set_result` or :meth:`Future.set_exception` have been - called. + This method can only be called once and cannot be called after + :meth:`Future.set_result` or :meth:`Future.set_exception` have been + called. - .. method:: set_result(result) + .. method:: set_result(result) - Sets the result of the work associated with the :class:`Future` to - *result*. + Sets the result of the work associated with the :class:`Future` to + *result*. - This method should only be used by :class:`Executor` implementations and - unit tests. + This method should only be used by :class:`Executor` implementations and + unit tests. - .. versionchanged:: 3.8 - This method raises - :exc:`concurrent.futures.InvalidStateError` if the :class:`Future` is - already done. + .. versionchanged:: 3.8 + This method raises + :exc:`concurrent.futures.InvalidStateError` if the :class:`Future` is + already done. - .. method:: set_exception(exception) + .. method:: set_exception(exception) - Sets the result of the work associated with the :class:`Future` to the - :class:`Exception` *exception*. + Sets the result of the work associated with the :class:`Future` to the + :class:`Exception` *exception*. - This method should only be used by :class:`Executor` implementations and - unit tests. + This method should only be used by :class:`Executor` implementations and + unit tests. - .. versionchanged:: 3.8 - This method raises - :exc:`concurrent.futures.InvalidStateError` if the :class:`Future` is - already done. + .. versionchanged:: 3.8 + This method raises + :exc:`concurrent.futures.InvalidStateError` if the :class:`Future` is + already done. Module Functions ---------------- diff --git a/Doc/library/concurrent.rst b/Doc/library/concurrent.rst index 2eba5365125805..8caea78bbb57e8 100644 --- a/Doc/library/concurrent.rst +++ b/Doc/library/concurrent.rst @@ -1,5 +1,5 @@ -The :mod:`concurrent` package -============================= +The :mod:`!concurrent` package +============================== Currently, there is only one module in this package: diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index a7f75fd6e84f4c..bb282428c5fffc 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -935,8 +935,10 @@ ConfigParser Objects When *default_section* is given, it specifies the name for the special section holding default values for other sections and interpolation purposes - (normally named ``"DEFAULT"``). This value can be retrieved and changed on - runtime using the ``default_section`` instance attribute. + (normally named ``"DEFAULT"``). This value can be retrieved and changed at + runtime using the ``default_section`` instance attribute. This won't + re-evaluate an already parsed config file, but will be used when writing + parsed settings to a new config file. Interpolation behaviour may be customized by providing a custom handler through the *interpolation* argument. ``None`` can be used to turn off diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index 38dd552a0363ac..401dc9a320c5e0 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -22,16 +22,16 @@ A small number of constants live in the built-in namespace. They are: An object frequently used to represent the absence of a value, as when default arguments are not passed to a function. Assignments to ``None`` are illegal and raise a :exc:`SyntaxError`. - ``None`` is the sole instance of the :data:`NoneType` type. + ``None`` is the sole instance of the :data:`~types.NoneType` type. .. data:: NotImplemented A special value which should be returned by the binary special methods - (e.g. :meth:`__eq__`, :meth:`__lt__`, :meth:`__add__`, :meth:`__rsub__`, + (e.g. :meth:`~object.__eq__`, :meth:`~object.__lt__`, :meth:`~object.__add__`, :meth:`~object.__rsub__`, etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods - (e.g. :meth:`__imul__`, :meth:`__iand__`, etc.) for the same purpose. + (e.g. :meth:`~object.__imul__`, :meth:`~object.__iand__`, etc.) for the same purpose. It should not be evaluated in a boolean context. ``NotImplemented`` is the sole instance of the :data:`types.NotImplementedType` type. diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst index 8f32477ed508c3..74333b2e934814 100644 --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -17,14 +17,22 @@ operations (explained below). Interface summary: -.. function:: copy(x) +.. function:: copy(obj) - Return a shallow copy of *x*. + Return a shallow copy of *obj*. -.. function:: deepcopy(x[, memo]) +.. function:: deepcopy(obj[, memo]) - Return a deep copy of *x*. + Return a deep copy of *obj*. + + +.. function:: replace(obj, /, **changes) + + Creates a new object of the same type as *obj*, replacing fields with values + from *changes*. + + .. versionadded:: 3.13 .. exception:: Error @@ -79,14 +87,40 @@ pickle functions from the :mod:`copyreg` module. single: __copy__() (copy protocol) single: __deepcopy__() (copy protocol) +.. currentmodule:: None + In order for a class to define its own copy implementation, it can define -special methods :meth:`__copy__` and :meth:`__deepcopy__`. The former is called -to implement the shallow copy operation; no additional arguments are passed. -The latter is called to implement the deep copy operation; it is passed one -argument, the ``memo`` dictionary. If the :meth:`__deepcopy__` implementation needs -to make a deep copy of a component, it should call the :func:`deepcopy` function -with the component as first argument and the memo dictionary as second argument. -The memo dictionary should be treated as an opaque object. +special methods :meth:`~object.__copy__` and :meth:`~object.__deepcopy__`. + +.. method:: object.__copy__(self) + :noindexentry: + + Called to implement the shallow copy operation; + no additional arguments are passed. + +.. method:: object.__deepcopy__(self, memo) + :noindexentry: + + Called to implement the deep copy operation; it is passed one + argument, the *memo* dictionary. If the ``__deepcopy__`` implementation needs + to make a deep copy of a component, it should call the :func:`~copy.deepcopy` function + with the component as first argument and the *memo* dictionary as second argument. + The *memo* dictionary should be treated as an opaque object. + + +.. index:: + single: __replace__() (replace protocol) + +Function :func:`!copy.replace` is more limited +than :func:`~copy.copy` and :func:`~copy.deepcopy`, +and only supports named tuples created by :func:`~collections.namedtuple`, +:mod:`dataclasses`, and other classes which define method :meth:`~object.__replace__`. + +.. method:: object.__replace__(self, /, **changes) + :noindexentry: + + This method should create a new object of the same type, + replacing fields with values from *changes*. .. seealso:: diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 64baa69be4af31..aba398b8ee1e54 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -288,9 +288,9 @@ The :mod:`csv` module defines the following classes: Inspecting each column, one of two key criteria will be considered to estimate if the sample contains a header: - - the second through n-th rows contain numeric values - - the second through n-th rows contain strings where at least one value's - length differs from that of the putative header of that column. + - the second through n-th rows contain numeric values + - the second through n-th rows contain strings where at least one value's + length differs from that of the putative header of that column. Twenty rows after the first row are sampled; if more than half of columns + rows meet the criteria, :const:`True` is returned. diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 81509c0920bb6e..ef3a9a0f5898af 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -41,7 +41,7 @@ You load libraries by accessing them as attributes of these objects. *cdll* loads libraries which export functions using the standard ``cdecl`` calling convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and -assumes the functions return a Windows :c:type:`HRESULT` error code. The error +assumes the functions return a Windows :c:type:`!HRESULT` error code. The error code is used to automatically raise an :class:`OSError` exception when the function call fails. @@ -72,8 +72,9 @@ Windows appends the usual ``.dll`` file suffix automatically. On Linux, it is required to specify the filename *including* the extension to load a library, so attribute access can not be used to load libraries. Either the -:meth:`LoadLibrary` method of the dll loaders should be used, or you should load -the library by creating an instance of CDLL by calling the constructor:: +:meth:`~LibraryLoader.LoadLibrary` method of the dll loaders should be used, +or you should load the library by creating an instance of CDLL by calling +the constructor:: >>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX @@ -220,7 +221,7 @@ Fundamental data types +----------------------+------------------------------------------+----------------------------+ | :class:`c_char` | :c:expr:`char` | 1-character bytes object | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_wchar` | :c:expr:`wchar_t` | 1-character string | +| :class:`c_wchar` | :c:type:`wchar_t` | 1-character string | +----------------------+------------------------------------------+----------------------------+ | :class:`c_byte` | :c:expr:`char` | int | +----------------------+------------------------------------------+----------------------------+ @@ -243,9 +244,9 @@ Fundamental data types | :class:`c_ulonglong` | :c:expr:`unsigned __int64` or | int | | | :c:expr:`unsigned long long` | | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_size_t` | :c:expr:`size_t` | int | +| :class:`c_size_t` | :c:type:`size_t` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_ssize_t` | :c:expr:`ssize_t` or | int | +| :class:`c_ssize_t` | :c:type:`ssize_t` or | int | | | :c:expr:`Py_ssize_t` | | +----------------------+------------------------------------------+----------------------------+ | :class:`c_time_t` | :c:type:`time_t` | int | @@ -333,9 +334,9 @@ property:: 10 b'Hi\x00lo\x00\x00\x00\x00\x00' >>> -The :func:`create_string_buffer` function replaces the old :func:`c_buffer` +The :func:`create_string_buffer` function replaces the old :func:`!c_buffer` function (which is still available as an alias). To create a mutable memory -block containing unicode characters of the C type :c:expr:`wchar_t`, use the +block containing unicode characters of the C type :c:type:`wchar_t`, use the :func:`create_unicode_buffer` function. @@ -361,7 +362,7 @@ from within *IDLE* or *PythonWin*:: >>> printf(b"%f bottles of beer\n", 42.5) Traceback (most recent call last): File "", line 1, in - ArgumentError: argument 2: TypeError: Don't know how to convert parameter 2 + ctypes.ArgumentError: argument 2: TypeError: Don't know how to convert parameter 2 >>> As has been mentioned before, all Python types except integers, strings, and @@ -383,15 +384,15 @@ as calling functions with a fixed number of parameters. On some platforms, and i particular ARM64 for Apple Platforms, the calling convention for variadic functions is different than that for regular functions. -On those platforms it is required to specify the *argtypes* attribute for the -regular, non-variadic, function arguments: +On those platforms it is required to specify the :attr:`~_FuncPtr.argtypes` +attribute for the regular, non-variadic, function arguments: .. code-block:: python3 libc.printf.argtypes = [ctypes.c_char_p] Because specifying the attribute does not inhibit portability it is advised to always -specify ``argtypes`` for all variadic functions. +specify :attr:`~_FuncPtr.argtypes` for all variadic functions. .. _ctypes-calling-functions-with-own-custom-data-types: @@ -400,9 +401,10 @@ Calling functions with your own custom data types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can also customize :mod:`ctypes` argument conversion to allow instances of -your own classes be used as function arguments. :mod:`ctypes` looks for an -:attr:`_as_parameter_` attribute and uses this as the function argument. Of -course, it must be one of integer, string, or bytes:: +your own classes be used as function arguments. :mod:`ctypes` looks for an +:attr:`!_as_parameter_` attribute and uses this as the function argument. The +attribute must be an integer, string, bytes, a :mod:`ctypes` instance, or an +object with an :attr:`!_as_parameter_` attribute:: >>> class Bottles: ... def __init__(self, number): @@ -414,7 +416,7 @@ course, it must be one of integer, string, or bytes:: 19 >>> -If you don't want to store the instance's data in the :attr:`_as_parameter_` +If you don't want to store the instance's data in the :attr:`!_as_parameter_` instance variable, you could define a :class:`property` which makes the attribute available on request. @@ -425,9 +427,9 @@ Specifying the required argument types (function prototypes) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It is possible to specify the required argument types of functions exported from -DLLs by setting the :attr:`argtypes` attribute. +DLLs by setting the :attr:`~_FuncPtr.argtypes` attribute. -:attr:`argtypes` must be a sequence of C data types (the ``printf`` function is +:attr:`~_FuncPtr.argtypes` must be a sequence of C data types (the :func:`!printf` function is probably not a good example here, because it takes a variable number and different types of parameters depending on the format string, on the other hand this is quite handy to experiment with this feature):: @@ -444,21 +446,21 @@ prototype for a C function), and tries to convert the arguments to valid types:: >>> printf(b"%d %d %d", 1, 2, 3) Traceback (most recent call last): File "", line 1, in - ArgumentError: argument 2: TypeError: wrong type + ctypes.ArgumentError: argument 2: TypeError: 'int' object cannot be interpreted as ctypes.c_char_p >>> printf(b"%s %d %f\n", b"X", 2, 3) X 2 3.000000 13 >>> If you have defined your own classes which you pass to function calls, you have -to implement a :meth:`from_param` class method for them to be able to use them -in the :attr:`argtypes` sequence. The :meth:`from_param` class method receives +to implement a :meth:`~_CData.from_param` class method for them to be able to use them +in the :attr:`~_FuncPtr.argtypes` sequence. The :meth:`~_CData.from_param` class method receives the Python object passed to the function call, it should do a typecheck or whatever is needed to make sure this object is acceptable, and then return the -object itself, its :attr:`_as_parameter_` attribute, or whatever you want to +object itself, its :attr:`!_as_parameter_` attribute, or whatever you want to pass as the C function argument in this case. Again, the result should be an integer, string, bytes, a :mod:`ctypes` instance, or an object with an -:attr:`_as_parameter_` attribute. +:attr:`!_as_parameter_` attribute. .. _ctypes-return-types: @@ -475,16 +477,16 @@ Return types By default functions are assumed to return the C :c:expr:`int` type. Other -return types can be specified by setting the :attr:`restype` attribute of the +return types can be specified by setting the :attr:`~_FuncPtr.restype` attribute of the function object. -The C prototype of ``time()`` is ``time_t time(time_t *)``. Because ``time_t`` -might be of a different type than the default return type ``int``, you should -specify the ``restype``:: +The C prototype of :c:func:`time` is ``time_t time(time_t *)``. Because :c:type:`time_t` +might be of a different type than the default return type :c:expr:`int`, you should +specify the :attr:`!restype` attribute:: >>> libc.time.restype = c_time_t -The argument types can be specified using ``argtypes``:: +The argument types can be specified using :attr:`~_FuncPtr.argtypes`:: >>> libc.time.argtypes = (POINTER(c_time_t),) @@ -493,7 +495,7 @@ To call the function with a ``NULL`` pointer as first argument, use ``None``:: >>> print(libc.time(None)) # doctest: +SKIP 1150640792 -Here is a more advanced example, it uses the ``strchr`` function, which expects +Here is a more advanced example, it uses the :func:`!strchr` function, which expects a string pointer and a char, and returns a pointer to a string:: >>> strchr = libc.strchr @@ -506,8 +508,8 @@ a string pointer and a char, and returns a pointer to a string:: None >>> -If you want to avoid the ``ord("x")`` calls above, you can set the -:attr:`argtypes` attribute, and the second argument will be converted from a +If you want to avoid the :func:`ord("x") ` calls above, you can set the +:attr:`~_FuncPtr.argtypes` attribute, and the second argument will be converted from a single character Python bytes object into a C char: .. doctest:: @@ -526,7 +528,7 @@ single character Python bytes object into a C char: >>> You can also use a callable Python object (a function or a class for example) as -the :attr:`restype` attribute, if the foreign function returns an integer. The +the :attr:`~_FuncPtr.restype` attribute, if the foreign function returns an integer. The callable will be called with the *integer* the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception:: @@ -554,7 +556,8 @@ get the string representation of an error code, and *returns* an exception. :func:`GetLastError` to retrieve it. Please note that a much more powerful error checking mechanism is available -through the :attr:`errcheck` attribute; see the reference manual for details. +through the :attr:`~_FuncPtr.errcheck` attribute; +see the reference manual for details. .. _ctypes-passing-pointers: @@ -592,7 +595,7 @@ Structures and unions Structures and unions must derive from the :class:`Structure` and :class:`Union` base classes which are defined in the :mod:`ctypes` module. Each subclass must -define a :attr:`_fields_` attribute. :attr:`_fields_` must be a list of +define a :attr:`~Structure._fields_` attribute. :attr:`!_fields_` must be a list of *2-tuples*, containing a *field name* and a *field type*. The field type must be a :mod:`ctypes` type like :class:`c_int`, or any other @@ -664,9 +667,9 @@ Structure/union alignment and byte order By default, Structure and Union fields are aligned in the same way the C compiler does it. It is possible to override this behavior by specifying a -:attr:`_pack_` class attribute in the subclass definition. This must be set to a -positive integer and specifies the maximum alignment for the fields. This is -what ``#pragma pack(n)`` also does in MSVC. +:attr:`~Structure._pack_` class attribute in the subclass definition. +This must be set to a positive integer and specifies the maximum alignment for the fields. +This is what ``#pragma pack(n)`` also does in MSVC. :mod:`ctypes` uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the @@ -682,7 +685,7 @@ Bit fields in structures and unions It is possible to create structures and unions containing bit fields. Bit fields are only possible for integer fields, the bit width is specified as the third -item in the :attr:`_fields_` tuples:: +item in the :attr:`~Structure._fields_` tuples:: >>> class Int(Structure): ... _fields_ = [("first_16", c_int, 16), @@ -853,7 +856,7 @@ Type conversions ^^^^^^^^^^^^^^^^ Usually, ctypes does strict type checking. This means, if you have -``POINTER(c_int)`` in the :attr:`argtypes` list of a function or as the type of +``POINTER(c_int)`` in the :attr:`~_FuncPtr.argtypes` list of a function or as the type of a member field in a structure definition, only instances of exactly the same type are accepted. There are some exceptions to this rule, where ctypes accepts other objects. For example, you can pass compatible array instances instead of @@ -874,7 +877,7 @@ pointer types. So, for ``POINTER(c_int)``, ctypes accepts an array of c_int:: >>> In addition, if a function argument is explicitly declared to be a pointer type -(such as ``POINTER(c_int)``) in :attr:`argtypes`, an object of the pointed +(such as ``POINTER(c_int)``) in :attr:`~_FuncPtr.argtypes`, an object of the pointed type (``c_int`` in this case) can be passed to the function. ctypes will apply the required :func:`byref` conversion in this case automatically. @@ -950,8 +953,8 @@ work:: >>> because the new ``class cell`` is not available in the class statement itself. -In :mod:`ctypes`, we can define the ``cell`` class and set the :attr:`_fields_` -attribute later, after the class statement:: +In :mod:`ctypes`, we can define the ``cell`` class and set the +:attr:`~Structure._fields_` attribute later, after the class statement:: >>> from ctypes import * >>> class cell(Structure): @@ -1001,8 +1004,8 @@ argument, and the callback functions expected argument types as the remaining arguments. I will present an example here which uses the standard C library's -:c:func:`qsort` function, that is used to sort items with the help of a callback -function. :c:func:`qsort` will be used to sort an array of integers:: +:c:func:`!qsort` function, that is used to sort items with the help of a callback +function. :c:func:`!qsort` will be used to sort an array of integers:: >>> IntArray5 = c_int * 5 >>> ia = IntArray5(5, 1, 7, 33, 99) @@ -1010,7 +1013,7 @@ function. :c:func:`qsort` will be used to sort an array of integers:: >>> qsort.restype = None >>> -:func:`qsort` must be called with a pointer to the data to sort, the number of +:func:`!qsort` must be called with a pointer to the data to sort, the number of items in the data array, the size of one item, and a pointer to the comparison function, the callback. The callback will then be called with two pointers to items, and it must return a negative integer if the first item is smaller than @@ -1102,7 +1105,7 @@ Some shared libraries not only export functions, they also export variables. An example in the Python library itself is the :c:data:`Py_Version`, Python runtime version number encoded in a single constant integer. -:mod:`ctypes` can access values like this with the :meth:`in_dll` class methods of +:mod:`ctypes` can access values like this with the :meth:`~_CData.in_dll` class methods of the type. *pythonapi* is a predefined symbol giving access to the Python C api:: @@ -1292,13 +1295,13 @@ Finding shared libraries When programming in a compiled language, shared libraries are accessed when compiling/linking a program, and when the program is run. -The purpose of the :func:`find_library` function is to locate a library in a way +The purpose of the :func:`~ctypes.util.find_library` function is to locate a library in a way similar to what the compiler or runtime loader does (on platforms with several versions of a shared library the most recent should be loaded), while the ctypes library loaders act like when a program is run, and call the runtime loader directly. -The :mod:`ctypes.util` module provides a function which can help to determine +The :mod:`!ctypes.util` module provides a function which can help to determine the library to load. @@ -1313,7 +1316,7 @@ the library to load. The exact functionality is system dependent. -On Linux, :func:`find_library` tries to run external programs +On Linux, :func:`~ctypes.util.find_library` tries to run external programs (``/sbin/ldconfig``, ``gcc``, ``objdump`` and ``ld``) to find the library file. It returns the filename of the library file. @@ -1332,7 +1335,7 @@ Here are some examples:: 'libbz2.so.1.0' >>> -On macOS, :func:`find_library` tries several predefined naming schemes and paths +On macOS, :func:`~ctypes.util.find_library` tries several predefined naming schemes and paths to locate the library, and returns a full pathname if successful:: >>> from ctypes.util import find_library @@ -1346,13 +1349,13 @@ to locate the library, and returns a full pathname if successful:: '/System/Library/Frameworks/AGL.framework/AGL' >>> -On Windows, :func:`find_library` searches along the system search path, and +On Windows, :func:`~ctypes.util.find_library` searches along the system search path, and returns the full pathname, but since there is no predefined naming scheme a call like ``find_library("c")`` will fail and return ``None``. If wrapping a shared library with :mod:`ctypes`, it *may* be better to determine the shared library name at development time, and hardcode that into the wrapper -module instead of using :func:`find_library` to locate the library at runtime. +module instead of using :func:`~ctypes.util.find_library` to locate the library at runtime. .. _ctypes-loading-shared-libraries: @@ -1400,7 +1403,8 @@ way is to instantiate one of the following classes: failure, an :class:`OSError` is automatically raised. .. versionchanged:: 3.3 - :exc:`WindowsError` used to be raised. + :exc:`WindowsError` used to be raised, + which is now an alias of :exc:`OSError`. .. versionchanged:: 3.12 @@ -1437,9 +1441,9 @@ function exported by these libraries, and reacquired afterwards. All these classes can be instantiated by calling them with at least one argument, the pathname of the shared library. If you have an existing handle to an already loaded shared library, it can be passed as the ``handle`` named -parameter, otherwise the underlying platforms ``dlopen`` or ``LoadLibrary`` -function is used to load the library into the process, and to get a handle to -it. +parameter, otherwise the underlying platforms :c:func:`!dlopen` or +:c:func:`!LoadLibrary` function is used to load the library into +the process, and to get a handle to it. The *mode* parameter can be used to specify how the library is loaded. For details, consult the :manpage:`dlopen(3)` manpage. On Windows, *mode* is @@ -1459,7 +1463,7 @@ to a new value and returns the former value. The *use_last_error* parameter, when set to true, enables the same mechanism for the Windows error code which is managed by the :func:`GetLastError` and -:func:`SetLastError` Windows API functions; :func:`ctypes.get_last_error` and +:func:`!SetLastError` Windows API functions; :func:`ctypes.get_last_error` and :func:`ctypes.set_last_error` are used to request and change the ctypes private copy of the windows error code. @@ -1522,8 +1526,8 @@ underscore to not clash with exported function names: Shared libraries can also be loaded by using one of the prefabricated objects, which are instances of the :class:`LibraryLoader` class, either by calling the -:meth:`LoadLibrary` method, or by retrieving the library as attribute of the -loader instance. +:meth:`~LibraryLoader.LoadLibrary` method, or by retrieving the library as +attribute of the loader instance. .. class:: LibraryLoader(dlltype) @@ -1531,7 +1535,7 @@ loader instance. Class which loads shared libraries. *dlltype* should be one of the :class:`CDLL`, :class:`PyDLL`, :class:`WinDLL`, or :class:`OleDLL` types. - :meth:`__getattr__` has special behavior: It allows loading a shared library by + :meth:`!__getattr__` has special behavior: It allows loading a shared library by accessing it as attribute of a library loader instance. The result is cached, so repeated attribute accesses return the same library each time. @@ -1576,7 +1580,7 @@ object is available: An instance of :class:`PyDLL` that exposes Python C API functions as attributes. Note that all these functions are assumed to return C :c:expr:`int`, which is of course not always the truth, so you have to assign - the correct :attr:`restype` attribute to use these functions. + the correct :attr:`!restype` attribute to use these functions. .. audit-event:: ctypes.dlopen name ctypes.LibraryLoader @@ -1628,7 +1632,7 @@ They are instances of a private class: the callable will be called with this integer, allowing further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as - :attr:`restype` and assign a callable to the :attr:`errcheck` attribute. + :attr:`!restype` and assign a callable to the :attr:`errcheck` attribute. .. attribute:: argtypes @@ -1639,14 +1643,14 @@ They are instances of a private class: unspecified arguments as well. When a foreign function is called, each actual argument is passed to the - :meth:`from_param` class method of the items in the :attr:`argtypes` + :meth:`~_CData.from_param` class method of the items in the :attr:`argtypes` tuple, this method allows adapting the actual argument to an object that the foreign function accepts. For example, a :class:`c_char_p` item in the :attr:`argtypes` tuple will convert a string passed as argument into a bytes object using ctypes conversion rules. New: It is now possible to put items in argtypes which are not ctypes - types, but each item must have a :meth:`from_param` method which returns a + types, but each item must have a :meth:`~_CData.from_param` method which returns a value usable as argument (integer, string, ctypes instance). This allows defining adapters that can adapt custom objects as function parameters. @@ -1660,7 +1664,7 @@ They are instances of a private class: :module: *result* is what the foreign function returns, as specified by the - :attr:`restype` attribute. + :attr:`!restype` attribute. *func* is the foreign function object itself, this allows reusing the same callable object to check or post process the results of several @@ -1734,70 +1738,70 @@ See :ref:`ctypes-callback-functions` for examples. Function prototypes created by these factory functions can be instantiated in different ways, depending on the type and number of the parameters in the call: +.. function:: prototype(address) + :noindex: + :module: - .. function:: prototype(address) - :noindex: - :module: + Returns a foreign function at the specified address which must be an integer. - Returns a foreign function at the specified address which must be an integer. +.. function:: prototype(callable) + :noindex: + :module: - .. function:: prototype(callable) - :noindex: - :module: + Create a C callable function (a callback function) from a Python *callable*. - Create a C callable function (a callback function) from a Python *callable*. +.. function:: prototype(func_spec[, paramflags]) + :noindex: + :module: - .. function:: prototype(func_spec[, paramflags]) - :noindex: - :module: + Returns a foreign function exported by a shared library. *func_spec* must + be a 2-tuple ``(name_or_ordinal, library)``. The first item is the name of + the exported function as string, or the ordinal of the exported function + as small integer. The second item is the shared library instance. - Returns a foreign function exported by a shared library. *func_spec* must - be a 2-tuple ``(name_or_ordinal, library)``. The first item is the name of - the exported function as string, or the ordinal of the exported function - as small integer. The second item is the shared library instance. +.. function:: prototype(vtbl_index, name[, paramflags[, iid]]) + :noindex: + :module: - .. function:: prototype(vtbl_index, name[, paramflags[, iid]]) - :noindex: - :module: + Returns a foreign function that will call a COM method. *vtbl_index* is + the index into the virtual function table, a small non-negative + integer. *name* is name of the COM method. *iid* is an optional pointer to + the interface identifier which is used in extended error reporting. - Returns a foreign function that will call a COM method. *vtbl_index* is - the index into the virtual function table, a small non-negative - integer. *name* is name of the COM method. *iid* is an optional pointer to - the interface identifier which is used in extended error reporting. + COM methods use a special calling convention: They require a pointer to + the COM interface as first argument, in addition to those parameters that + are specified in the :attr:`!argtypes` tuple. - COM methods use a special calling convention: They require a pointer to - the COM interface as first argument, in addition to those parameters that - are specified in the :attr:`argtypes` tuple. +The optional *paramflags* parameter creates foreign function wrappers with much +more functionality than the features described above. - The optional *paramflags* parameter creates foreign function wrappers with much - more functionality than the features described above. +*paramflags* must be a tuple of the same length as :attr:`~_FuncPtr.argtypes`. - *paramflags* must be a tuple of the same length as :attr:`argtypes`. +Each item in this tuple contains further information about a parameter, it must +be a tuple containing one, two, or three items. - Each item in this tuple contains further information about a parameter, it must - be a tuple containing one, two, or three items. +The first item is an integer containing a combination of direction +flags for the parameter: - The first item is an integer containing a combination of direction - flags for the parameter: + 1 + Specifies an input parameter to the function. - 1 - Specifies an input parameter to the function. + 2 + Output parameter. The foreign function fills in a value. - 2 - Output parameter. The foreign function fills in a value. + 4 + Input parameter which defaults to the integer zero. - 4 - Input parameter which defaults to the integer zero. +The optional second item is the parameter name as string. If this is specified, +the foreign function can be called with named parameters. - The optional second item is the parameter name as string. If this is specified, - the foreign function can be called with named parameters. +The optional third item is the default value for this parameter. - The optional third item is the default value for this parameter. -This example demonstrates how to wrap the Windows ``MessageBoxW`` function so +The following example demonstrates how to wrap the Windows ``MessageBoxW`` function so that it supports default parameters and named arguments. The C declaration from the windows header file is this:: @@ -1845,7 +1849,7 @@ value if there is a single one, or a tuple containing the output parameter values when there are more than one, so the GetWindowRect function now returns a RECT instance, when called. -Output parameters can be combined with the :attr:`errcheck` protocol to do +Output parameters can be combined with the :attr:`~_FuncPtr.errcheck` protocol to do further output processing and error checking. The win32 ``GetWindowRect`` api function returns a ``BOOL`` to signal success or failure, so this function could do the error checking, and raises an exception when the api call failed:: @@ -1858,7 +1862,7 @@ do the error checking, and raises an exception when the api call failed:: >>> GetWindowRect.errcheck = errcheck >>> -If the :attr:`errcheck` function returns the argument tuple it receives +If the :attr:`~_FuncPtr.errcheck` function returns the argument tuple it receives unchanged, :mod:`ctypes` continues the normal processing it does on the output parameters. If you want to return a tuple of window coordinates instead of a ``RECT`` instance, you can retrieve the fields in the function and return them @@ -2008,7 +2012,7 @@ Utility functions .. function:: get_last_error() Windows only: returns the current value of the ctypes-private copy of the system - :data:`LastError` variable in the calling thread. + :data:`!LastError` variable in the calling thread. .. audit-event:: ctypes.get_last_error "" ctypes.get_last_error @@ -2026,17 +2030,17 @@ Utility functions specifying an address, or a ctypes instance. -.. function:: POINTER(type) +.. function:: POINTER(type, /) - This factory function creates and returns a new ctypes pointer type. Pointer - types are cached and reused internally, so calling this function repeatedly is - cheap. *type* must be a ctypes type. + Create and return a new ctypes pointer type. Pointer types are cached and + reused internally, so calling this function repeatedly is cheap. + *type* must be a ctypes type. -.. function:: pointer(obj) +.. function:: pointer(obj, /) - This function creates a new pointer instance, pointing to *obj*. The returned - object is of the type ``POINTER(type(obj))``. + Create a new pointer instance, pointing to *obj*. + The returned object is of the type ``POINTER(type(obj))``. Note: If you just want to pass a pointer to an object to a foreign function call, you should use ``byref(obj)`` which is much faster. @@ -2061,7 +2065,7 @@ Utility functions .. function:: set_last_error(value) Windows only: set the current value of the ctypes-private copy of the system - :data:`LastError` variable in the calling thread to *value* and return the + :data:`!LastError` variable in the calling thread to *value* and return the previous value. .. audit-event:: ctypes.set_last_error error ctypes.set_last_error @@ -2085,13 +2089,14 @@ Utility functions .. function:: WinError(code=None, descr=None) Windows only: this function is probably the worst-named thing in ctypes. It - creates an instance of OSError. If *code* is not specified, + creates an instance of :exc:`OSError`. If *code* is not specified, ``GetLastError`` is called to determine the error code. If *descr* is not specified, :func:`FormatError` is called to get a textual description of the error. .. versionchanged:: 3.3 - An instance of :exc:`WindowsError` used to be created. + An instance of :exc:`WindowsError` used to be created, which is now an + alias of :exc:`OSError`. .. function:: wstring_at(address, size=-1) @@ -2157,8 +2162,8 @@ Data types This method adapts *obj* to a ctypes type. It is called with the actual object used in a foreign function call when the type is present in the - foreign function's :attr:`argtypes` tuple; it must return an object that - can be used as a function call parameter. + foreign function's :attr:`~_FuncPtr.argtypes` tuple; + it must return an object that can be used as a function call parameter. All ctypes data types have a default implementation of this classmethod that normally returns *obj* if that is an instance of the type. Some @@ -2223,13 +2228,13 @@ Fundamental data types Fundamental data types, when returned as foreign function call results, or, for example, by retrieving structure field members or array items, are transparently converted to native Python types. In other words, if a foreign function has a -:attr:`restype` of :class:`c_char_p`, you will always receive a Python bytes +:attr:`~_FuncPtr.restype` of :class:`c_char_p`, you will always receive a Python bytes object, *not* a :class:`c_char_p` instance. .. XXX above is false, it actually returns a Unicode string Subclasses of fundamental data types do *not* inherit this behavior. So, if a -foreign functions :attr:`restype` is a subclass of :class:`c_void_p`, you will +foreign functions :attr:`!restype` is a subclass of :class:`c_void_p`, you will receive an instance of this subclass from the function call. Of course, you can get the value of the pointer by accessing the ``value`` attribute. @@ -2407,7 +2412,7 @@ These are the fundamental ctypes data types: .. class:: c_wchar - Represents the C :c:expr:`wchar_t` datatype, and interprets the value as a + Represents the C :c:type:`wchar_t` datatype, and interprets the value as a single character unicode string. The constructor accepts an optional string initializer, the length of the string must be exactly one character. @@ -2428,7 +2433,7 @@ These are the fundamental ctypes data types: .. class:: HRESULT - Windows only: Represents a :c:type:`HRESULT` value, which contains success or + Windows only: Represents a :c:type:`!HRESULT` value, which contains success or error information for a function or method call. @@ -2437,9 +2442,9 @@ These are the fundamental ctypes data types: Represents the C :c:expr:`PyObject *` datatype. Calling this without an argument creates a ``NULL`` :c:expr:`PyObject *` pointer. -The :mod:`ctypes.wintypes` module provides quite some other Windows specific -data types, for example :c:type:`HWND`, :c:type:`WPARAM`, or :c:type:`DWORD`. Some -useful structures like :c:type:`MSG` or :c:type:`RECT` are also defined. +The :mod:`!ctypes.wintypes` module provides quite some other Windows specific +data types, for example :c:type:`!HWND`, :c:type:`!WPARAM`, or :c:type:`!DWORD`. +Some useful structures like :c:type:`!MSG` or :c:type:`!RECT` are also defined. .. _ctypes-structured-data-types: diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index cf208f3ba0db36..9b8a98f05f7cbb 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -641,7 +641,8 @@ The module :mod:`curses` defines the following functions: .. function:: update_lines_cols() - Update :envvar:`LINES` and :envvar:`COLS`. Useful for detecting manual screen resize. + Update the :const:`LINES` and :const:`COLS` module variables. + Useful for detecting manual screen resize. .. versionadded:: 3.5 @@ -1342,10 +1343,27 @@ The :mod:`curses` module defines the following data members: .. data:: COLORS The maximum number of colors the terminal can support. + It is defined only after the call to :func:`start_color`. .. data:: COLOR_PAIRS The maximum number of color pairs the terminal can support. + It is defined only after the call to :func:`start_color`. + +.. data:: COLS + + The width of the screen, i.e., the number of columns. + It is defined only after the call to :func:`initscr`. + Updated by :func:`update_lines_cols`, :func:`resizeterm` and + :func:`resize_term`. + +.. data:: LINES + + The height of the screen, i.e., the number of lines. + It is defined only after the call to :func:`initscr`. + Updated by :func:`update_lines_cols`, :func:`resizeterm` and + :func:`resize_term`. + Some constants are available to specify character cell attributes. The exact constants available are system dependent. @@ -1630,6 +1648,8 @@ keys); also, the following keypad mappings are standard: | :kbd:`Page Down` | KEY_NPAGE | +------------------+-----------+ +.. _curses-acs-codes: + The following table lists characters from the alternate character set. These are inherited from the VT100 terminal, and will generally be available on software emulations such as X terminals. When there is no graphic available, curses @@ -1751,9 +1771,9 @@ The following table lists mouse button constants used by :meth:`getmouse`: | .. data:: BUTTON_ALT | Control was down during button state change | +----------------------------------+---------------------------------------------+ - .. versionchanged:: 3.10 - The ``BUTTON5_*`` constants are now exposed if they are provided by the - underlying curses library. +.. versionchanged:: 3.10 + The ``BUTTON5_*`` constants are now exposed if they are provided by the + underlying curses library. The following table lists the predefined colors: diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 535a60ccca8d07..bbbbcb00d8fef8 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -319,13 +319,11 @@ Module contents module-level method (see below). Users should never instantiate a :class:`Field` object directly. Its documented attributes are: - - ``name``: The name of the field. - - - ``type``: The type of the field. - - - ``default``, ``default_factory``, ``init``, ``repr``, ``hash``, - ``compare``, ``metadata``, and ``kw_only`` have the identical - meaning and values as they do in the :func:`field` function. + - ``name``: The name of the field. + - ``type``: The type of the field. + - ``default``, ``default_factory``, ``init``, ``repr``, ``hash``, + ``compare``, ``metadata``, and ``kw_only`` have the identical + meaning and values as they do in the :func:`field` function. Other attributes may exist, but they are private and must not be inspected or relied on. @@ -456,6 +454,8 @@ Module contents ``replace()`` (or similarly named) method which handles instance copying. + Dataclass instances are also supported by generic function :func:`copy.replace`. + .. function:: is_dataclass(obj) Return ``True`` if its parameter is a dataclass or an instance of one, @@ -609,7 +609,7 @@ methods will raise a :exc:`FrozenInstanceError` when invoked. There is a tiny performance penalty when using ``frozen=True``: :meth:`~object.__init__` cannot use simple assignment to initialize fields, and -must use :meth:`~object.__setattr__`. +must use :meth:`!object.__setattr__`. Inheritance ----------- diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index bed19ad145a20c..0b9d42f32e3bd6 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -19,6 +19,10 @@ 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. +.. tip:: + + Skip to :ref:`the format codes `. + .. seealso:: Module :mod:`calendar` @@ -33,6 +37,10 @@ on efficient attribute extraction for output formatting and manipulation. Package `dateutil `_ Third-party library with expanded time zone and parsing support. + Package `DateType `_ + Third-party library that introduces distinct static types to e.g. allow static type checkers + to differentiate between naive and aware datetimes. + .. _datetime-naive-aware: Aware and Naive Objects @@ -644,6 +652,9 @@ Instance methods: >>> d.replace(day=26) datetime.date(2002, 12, 26) + :class:`date` objects are also supported by generic function + :func:`copy.replace`. + .. method:: date.timetuple() @@ -1243,6 +1254,9 @@ Instance methods: ``tzinfo=None`` can be specified to create a naive datetime from an aware datetime with no conversion of date and time data. + :class:`datetime` objects are also supported by generic function + :func:`copy.replace`. + .. versionadded:: 3.6 Added the ``fold`` argument. @@ -1819,6 +1833,9 @@ Instance methods: ``tzinfo=None`` can be specified to create a naive :class:`.time` from an aware :class:`.time`, without conversion of the time data. + :class:`time` objects are also supported by generic function + :func:`copy.replace`. + .. versionadded:: 3.6 Added the ``fold`` argument. @@ -2322,6 +2339,8 @@ versus :meth:`strptime`: +----------------+--------------------------------------------------------+------------------------------------------------------------------------------+ + .. _format-codes: + :meth:`strftime` and :meth:`strptime` Format Codes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 2be499337a2a15..766847b971b645 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -245,6 +245,13 @@ supported. Close the ``gdbm`` database. + .. method:: gdbm.clear() + + Remove all items from the ``gdbm`` database. + + .. versionadded:: 3.13 + + :mod:`dbm.ndbm` --- Interface based on ndbm ------------------------------------------- @@ -313,6 +320,12 @@ to locate the appropriate header file to simplify building this module. Close the ``ndbm`` database. + .. method:: ndbm.clear() + + Remove all items from the ``ndbm`` database. + + .. versionadded:: 3.13 + :mod:`dbm.dumb` --- Portable DBM implementation ----------------------------------------------- diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index c2b96954c5f8ef..fb8bbf72adf268 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -1396,10 +1396,10 @@ In addition to the three supplied contexts, new contexts can be created with the With three arguments, compute ``(x**y) % modulo``. For the three argument form, the following restrictions on the arguments hold: - - all three arguments must be integral - - ``y`` must be nonnegative - - at least one of ``x`` or ``y`` must be nonzero - - ``modulo`` must be nonzero and have at most 'precision' digits + - all three arguments must be integral + - ``y`` must be nonnegative + - at least one of ``x`` or ``y`` must be nonzero + - ``modulo`` must be nonzero and have at most 'precision' digits The value resulting from ``Context.power(x, y, modulo)`` is equal to the value that would be obtained by computing ``(x**y) diff --git a/Doc/library/devmode.rst b/Doc/library/devmode.rst index 80ac13b116c1d2..5b8a9bd1908456 100644 --- a/Doc/library/devmode.rst +++ b/Doc/library/devmode.rst @@ -59,8 +59,9 @@ Effects of the Python Development Mode: ``default``. * Call :func:`faulthandler.enable` at Python startup to install handlers for - the :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS` and - :const:`SIGILL` signals to dump the Python traceback on a crash. + the :const:`~signal.SIGSEGV`, :const:`~signal.SIGFPE`, + :const:`~signal.SIGABRT`, :const:`~signal.SIGBUS` and + :const:`~signal.SIGILL` signals to dump the Python traceback on a crash. It behaves as if the :option:`-X faulthandler <-X>` command line option is used or if the :envvar:`PYTHONFAULTHANDLER` environment variable is set to @@ -81,7 +82,7 @@ Effects of the Python Development Mode: ignored for empty strings. * The :class:`io.IOBase` destructor logs ``close()`` exceptions. -* Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to +* Set the :attr:`~sys.flags.dev_mode` attribute of :data:`sys.flags` to ``True``. The Python Development Mode does not enable the :mod:`tracemalloc` module by diff --git a/Doc/library/dialog.rst b/Doc/library/dialog.rst index 53f98c1018988f..191e0da12103fa 100644 --- a/Doc/library/dialog.rst +++ b/Doc/library/dialog.rst @@ -27,15 +27,15 @@ functions for creating simple modal dialogs to get a value from the user. The base class for custom dialogs. - .. method:: body(master) + .. method:: body(master) - Override to construct the dialog's interface and return the widget that - should have initial focus. + Override to construct the dialog's interface and return the widget that + should have initial focus. - .. method:: buttonbox() + .. method:: buttonbox() - Default behaviour adds OK and Cancel buttons. Override for custom button - layouts. + Default behaviour adds OK and Cancel buttons. Override for custom button + layouts. diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 5ee1f4a02c6816..c553611401d018 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -570,8 +570,8 @@ The :class:`SequenceMatcher` class has this constructor: The three methods that return the ratio of matching to total characters can give different results due to differing levels of approximation, although -:meth:`quick_ratio` and :meth:`real_quick_ratio` are always at least as large as -:meth:`ratio`: +:meth:`~SequenceMatcher.quick_ratio` and :meth:`~SequenceMatcher.real_quick_ratio` +are always at least as large as :meth:`~SequenceMatcher.ratio`: >>> s = SequenceMatcher(None, "abcd", "bcde") >>> s.ratio() @@ -593,15 +593,15 @@ This example compares two strings, considering blanks to be "junk": ... "private Thread currentThread;", ... "private volatile Thread currentThread;") -:meth:`ratio` returns a float in [0, 1], measuring the similarity of the -sequences. As a rule of thumb, a :meth:`ratio` value over 0.6 means the +:meth:`~SequenceMatcher.ratio` returns a float in [0, 1], measuring the similarity of the +sequences. As a rule of thumb, a :meth:`~SequenceMatcher.ratio` value over 0.6 means the sequences are close matches: >>> print(round(s.ratio(), 3)) 0.866 If you're only interested in where the sequences match, -:meth:`get_matching_blocks` is handy: +:meth:`~SequenceMatcher.get_matching_blocks` is handy: >>> for block in s.get_matching_blocks(): ... print("a[%d] and b[%d] match for %d elements" % block) @@ -609,12 +609,12 @@ If you're only interested in where the sequences match, a[8] and b[17] match for 21 elements a[29] and b[38] match for 0 elements -Note that the last tuple returned by :meth:`get_matching_blocks` is always a -dummy, ``(len(a), len(b), 0)``, and this is the only case in which the last +Note that the last tuple returned by :meth:`~SequenceMatcher.get_matching_blocks` +is always a dummy, ``(len(a), len(b), 0)``, and this is the only case in which the last tuple element (number of elements matched) is ``0``. If you want to know how to change the first sequence into the second, use -:meth:`get_opcodes`: +:meth:`~SequenceMatcher.get_opcodes`: >>> for opcode in s.get_opcodes(): ... print("%6s a[%d:%d] b[%d:%d]" % opcode) @@ -689,7 +689,7 @@ Differ Example This example compares two texts. First we set up the texts, sequences of individual single-line strings ending with newlines (such sequences can also be -obtained from the :meth:`~io.BaseIO.readlines` method of file-like objects): +obtained from the :meth:`~io.IOBase.readlines` method of file-like objects): >>> text1 = ''' 1. Beautiful is better than ugly. ... 2. Explicit is better than implicit. diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 6beaad3825aba8..1f773b7b337fa3 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -43,26 +43,52 @@ interpreter. adaptive bytecode can be shown by passing ``adaptive=True``. -Example: Given the function :func:`myfunc`:: +Example: Given the function :func:`!myfunc`:: def myfunc(alist): return len(alist) the following command can be used to display the disassembly of -:func:`myfunc`: +:func:`!myfunc`: .. doctest:: >>> dis.dis(myfunc) 2 0 RESUME 0 - 3 2 LOAD_GLOBAL 1 (NULL + len) + 3 2 LOAD_GLOBAL 1 (len + NULL) 12 LOAD_FAST 0 (alist) 14 CALL 1 22 RETURN_VALUE (The "2" is a line number). +.. _dis-cli: + +Command-line interface +---------------------- + +The :mod:`dis` module can be invoked as a script from the command line: + +.. code-block:: sh + + python -m dis [-h] [-C] [infile] + +The following options are accepted: + +.. program:: dis + +.. cmdoption:: -h, --help + + Display usage and exit. + +.. cmdoption:: -C, --show-caches + + Show inline caches. + +If :file:`infile` is specified, its disassembled code will be written to stdout. +Otherwise, disassembly is performed on compiled source code recieved from stdin. + Bytecode analysis ----------------- @@ -297,6 +323,9 @@ operation is being performed, so the intermediate analysis object isn't useful: The :pep:`626` ``co_lines`` method is used instead of the ``co_firstlineno`` and ``co_lnotab`` attributes of the code object. + .. versionchanged:: 3.13 + Line numbers can be ``None`` for bytecode that does not map to source lines. + .. function:: findlabels(code) @@ -402,7 +431,12 @@ details of bytecode instructions as :class:`Instruction` instances: .. data:: starts_line - line started by this opcode (if any), otherwise ``None`` + ``True`` if this opcode starts a source line, otherwise ``False`` + + + .. data:: line_number + + source line number associated with this opcode (if any), otherwise ``None`` .. data:: is_jump_target @@ -429,8 +463,11 @@ details of bytecode instructions as :class:`Instruction` instances: .. versionchanged:: 3.13 + Changed field ``starts_line``. + Added fields ``start_offset``, ``cache_offset``, ``end_offset``, - ``baseopname``, ``baseopcode``, ``jump_target`` and ``oparg``. + ``baseopname``, ``baseopcode``, ``jump_target``, ``oparg``, and + ``line_number``. .. class:: Positions @@ -586,7 +623,7 @@ not have to be) the original ``STACK[-2]``. key = STACK.pop() container = STACK.pop() - STACK.append(container[index]) + STACK.append(container[key]) .. opcode:: STORE_SUBSCR @@ -851,7 +888,7 @@ iterations of the loop. .. opcode:: LOAD_BUILD_CLASS - Pushes :func:`builtins.__build_class__` onto the stack. It is later called + Pushes :func:`!builtins.__build_class__` onto the stack. It is later called to construct a class. @@ -876,7 +913,7 @@ iterations of the loop. .. opcode:: MATCH_MAPPING If ``STACK[-1]`` is an instance of :class:`collections.abc.Mapping` (or, more - technically: if it has the :const:`Py_TPFLAGS_MAPPING` flag set in its + technically: if it has the :c:macro:`Py_TPFLAGS_MAPPING` flag set in its :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push ``False``. @@ -887,7 +924,7 @@ iterations of the loop. If ``STACK[-1]`` is an instance of :class:`collections.abc.Sequence` and is *not* an instance of :class:`str`/:class:`bytes`/:class:`bytearray` (or, more technically: if it has - the :const:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`), + the :c:macro:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push ``False``. .. versionadded:: 3.10 @@ -909,22 +946,23 @@ iterations of the loop. .. opcode:: STORE_NAME (namei) Implements ``name = STACK.pop()``. *namei* is the index of *name* in the attribute - :attr:`co_names` of the code object. The compiler tries to use - :opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible. + :attr:`!co_names` of the :ref:`code object `. + The compiler tries to use :opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible. .. opcode:: DELETE_NAME (namei) - Implements ``del name``, where *namei* is the index into :attr:`co_names` - attribute of the code object. + Implements ``del name``, where *namei* is the index into :attr:`!co_names` + attribute of the :ref:`code object `. .. opcode:: UNPACK_SEQUENCE (count) Unpacks ``STACK[-1]`` into *count* individual values, which are put onto the stack - right-to-left:: + right-to-left. Require there to be exactly *count* values.:: - STACK.extend(STACK.pop()[:count:-1]) + assert(len(STACK[-1]) == count) + STACK.extend(STACK.pop()[:-count-1:-1]) .. opcode:: UNPACK_EX (counts) @@ -954,7 +992,8 @@ iterations of the loop. value = STACK.pop() obj.name = value - where *namei* is the index of name in :attr:`co_names`. + where *namei* is the index of name in :attr:`!co_names` of the + :ref:`code object `. .. opcode:: DELETE_ATTR (namei) @@ -963,7 +1002,8 @@ iterations of the loop. obj = STACK.pop() del obj.name - where *namei* is the index of name into :attr:`co_names`. + where *namei* is the index of name into :attr:`!co_names` of the + :ref:`code object `. .. opcode:: STORE_GLOBAL (namei) @@ -1108,7 +1148,8 @@ iterations of the loop. This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the correct name, the bytecode pushes the unbound method and ``STACK[-1]``. ``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL` - when calling the unbound method. Otherwise, ``NULL`` and the object returned by + or :opcode:`CALL_KW` when calling the unbound method. + Otherwise, ``NULL`` and the object returned by the attribute lookup are pushed. .. versionchanged:: 3.12 @@ -1376,25 +1417,14 @@ iterations of the loop. .. opcode:: CALL (argc) - Calls a callable object with the number of arguments specified by ``argc``, - including the named arguments specified by the preceding - :opcode:`KW_NAMES`, if any. - On the stack are (in ascending order), either: - - * NULL - * The callable - * The positional arguments - * The named arguments - - or: + Calls a callable object with the number of arguments specified by ``argc``. + On the stack are (in ascending order): * The callable - * ``self`` + * ``self`` or ``NULL`` * The remaining positional arguments - * The named arguments - ``argc`` is the total of the positional and named arguments, excluding - ``self`` when a ``NULL`` is not present. + ``argc`` is the total of the positional arguments, excluding ``self``. ``CALL`` pops all arguments and the callable object off the stack, calls the callable object with those arguments, and pushes the return value @@ -1402,6 +1432,33 @@ iterations of the loop. .. versionadded:: 3.11 + .. versionchanged:: 3.13 + The callable now always appears at the same position on the stack. + + .. versionchanged:: 3.13 + Calls with keyword arguments are now handled by :opcode:`CALL_KW`. + + +.. opcode:: CALL_KW (argc) + + Calls a callable object with the number of arguments specified by ``argc``, + including one or more named arguments. On the stack are (in ascending order): + + * The callable + * ``self`` or ``NULL`` + * The remaining positional arguments + * The named arguments + * A :class:`tuple` of keyword argument names + + ``argc`` is the total of the positional and named arguments, excluding ``self``. + The length of the tuple of keyword argument names is the number of named arguments. + + ``CALL_KW`` pops all arguments, the keyword names, and the callable object + off the stack, calls the callable object with those arguments, and pushes the + return value returned by the callable object. + + .. versionadded:: 3.13 + .. opcode:: CALL_FUNCTION_EX (flags) @@ -1427,15 +1484,6 @@ iterations of the loop. .. versionadded:: 3.11 -.. opcode:: KW_NAMES (consti) - - Prefixes :opcode:`CALL`. - Stores a reference to ``co_consts[consti]`` into an internal variable - for use by :opcode:`CALL`. ``co_consts[consti]`` must be a tuple of strings. - - .. versionadded:: 3.11 - - .. opcode:: MAKE_FUNCTION Pushes a new function object on the stack built from the code object at ``STACK[1]``. @@ -1597,8 +1645,8 @@ iterations of the loop. opcodes in the range [0,255] which don't use their argument and those that do (``< HAVE_ARGUMENT`` and ``>= HAVE_ARGUMENT``, respectively). - If your application uses pseudo instructions, use the :data:`hasarg` - collection instead. + If your application uses pseudo instructions or specialized instructions, + use the :data:`hasarg` collection instead. .. versionchanged:: 3.6 Now every instruction has an argument, but opcodes ``< HAVE_ARGUMENT`` @@ -1609,6 +1657,8 @@ iterations of the loop. it is not true that comparison with ``HAVE_ARGUMENT`` indicates whether they use their arg. + .. deprecated:: 3.13 + Use :data:`hasarg` instead. .. opcode:: CALL_INTRINSIC_1 diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 92da6133f9bf09..54a8e79a0ef941 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -1409,6 +1409,27 @@ DocTestParser objects identifying this string, and is only used for error messages. +TestResults objects +^^^^^^^^^^^^^^^^^^^ + + +.. class:: TestResults(failed, attempted) + + .. attribute:: failed + + Number of failed tests. + + .. attribute:: attempted + + Number of attempted tests. + + .. attribute:: skipped + + Number of skipped tests. + + .. versionadded:: 3.13 + + .. _doctest-doctestrunner: DocTestRunner objects @@ -1427,7 +1448,7 @@ DocTestRunner objects passing a subclass of :class:`OutputChecker` to the constructor. The test runner's display output can be controlled in two ways. First, an output - function can be passed to :meth:`TestRunner.run`; this function will be called + function can be passed to :meth:`run`; this function will be called with strings that should be displayed. It defaults to ``sys.stdout.write``. If capturing the output is not sufficient, then the display output can be also customized by subclassing DocTestRunner, and overriding the methods @@ -1448,6 +1469,10 @@ DocTestRunner objects runner compares expected output to actual output, and how it displays failures. For more information, see section :ref:`doctest-options`. + The test runner accumulates statistics. The aggregated number of attempted, + failed and skipped examples is also available via the :attr:`tries`, + :attr:`failures` and :attr:`skips` attributes. The :meth:`run` and + :meth:`summarize` methods return a :class:`TestResults` instance. :class:`DocTestParser` defines the following methods: @@ -1500,7 +1525,8 @@ DocTestRunner objects .. method:: run(test, compileflags=None, out=None, clear_globs=True) Run the examples in *test* (a :class:`DocTest` object), and display the - results using the writer function *out*. + results using the writer function *out*. Return a :class:`TestResults` + instance. The examples are run in the namespace ``test.globs``. If *clear_globs* is true (the default), then this namespace will be cleared after the test runs, @@ -1519,12 +1545,29 @@ DocTestRunner objects .. method:: summarize(verbose=None) Print a summary of all the test cases that have been run by this DocTestRunner, - and return a :term:`named tuple` ``TestResults(failed, attempted)``. + and return a :class:`TestResults` instance. The optional *verbose* argument controls how detailed the summary is. If the verbosity is not specified, then the :class:`DocTestRunner`'s verbosity is used. + :class:`DocTestParser` has the following attributes: + + .. attribute:: tries + + Number of attempted examples. + + .. attribute:: failures + + Number of failed examples. + + .. attribute:: skips + + Number of skipped examples. + + .. versionadded:: 3.13 + + .. _doctest-outputchecker: OutputChecker objects diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst index adbe6c1c7d29b8..aa0134412f3a60 100644 --- a/Doc/library/email.charset.rst +++ b/Doc/library/email.charset.rst @@ -150,7 +150,7 @@ Import this class from the :mod:`email.charset` module. .. method:: __str__() Returns *input_charset* as a string coerced to lower - case. :meth:`__repr__` is an alias for :meth:`__str__`. + case. :meth:`!__repr__` is an alias for :meth:`!__str__`. .. method:: __eq__(other) diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst index 918fc55677e723..5b49339650f0e9 100644 --- a/Doc/library/email.contentmanager.rst +++ b/Doc/library/email.contentmanager.rst @@ -32,9 +32,9 @@ To find the handler, look for the following keys in the registry, stopping with the first one found: - * the string representing the full MIME type (``maintype/subtype``) - * the string representing the ``maintype`` - * the empty string + * the string representing the full MIME type (``maintype/subtype``) + * the string representing the ``maintype`` + * the empty string If none of these keys produce a handler, raise a :exc:`KeyError` for the full MIME type. @@ -55,11 +55,11 @@ look for the following keys in the registry, stopping with the first one found: - * the type itself (``typ``) - * the type's fully qualified name (``typ.__module__ + '.' + - typ.__qualname__``). - * the type's qualname (``typ.__qualname__``) - * the type's name (``typ.__name__``). + * the type itself (``typ``) + * the type's fully qualified name (``typ.__module__ + '.' + + typ.__qualname__``). + * the type's qualname (``typ.__qualname__``) + * the type's name (``typ.__name__``). If none of the above match, repeat all of the checks above for each of the types in the :term:`MRO` (``typ.__mro__``). Finally, if no other key @@ -132,15 +132,15 @@ Currently the email package provides only one concrete content manager, Add a :mailheader:`Content-Type` header with a ``maintype/subtype`` value. - * For ``str``, set the MIME ``maintype`` to ``text``, and set the - subtype to *subtype* if it is specified, or ``plain`` if it is not. - * For ``bytes``, use the specified *maintype* and *subtype*, or - raise a :exc:`TypeError` if they are not specified. - * For :class:`~email.message.EmailMessage` objects, set the maintype - to ``message``, and set the subtype to *subtype* if it is - specified or ``rfc822`` if it is not. If *subtype* is - ``partial``, raise an error (``bytes`` objects must be used to - construct ``message/partial`` parts). + * For ``str``, set the MIME ``maintype`` to ``text``, and set the + subtype to *subtype* if it is specified, or ``plain`` if it is not. + * For ``bytes``, use the specified *maintype* and *subtype*, or + raise a :exc:`TypeError` if they are not specified. + * For :class:`~email.message.EmailMessage` objects, set the maintype + to ``message``, and set the subtype to *subtype* if it is + specified or ``rfc822`` if it is not. If *subtype* is + ``partial``, raise an error (``bytes`` objects must be used to + construct ``message/partial`` parts). If *charset* is provided (which is valid only for ``str``), encode the string to bytes using the specified character set. The default is @@ -155,14 +155,14 @@ Currently the email package provides only one concrete content manager, ``7bit`` for an input that contains non-ASCII values), raise a :exc:`ValueError`. - * For ``str`` objects, if *cte* is not set use heuristics to - determine the most compact encoding. - * For :class:`~email.message.EmailMessage`, per :rfc:`2046`, raise - an error if a *cte* of ``quoted-printable`` or ``base64`` is - requested for *subtype* ``rfc822``, and for any *cte* other than - ``7bit`` for *subtype* ``external-body``. For - ``message/rfc822``, use ``8bit`` if *cte* is not specified. For - all other values of *subtype*, use ``7bit``. + * For ``str`` objects, if *cte* is not set use heuristics to + determine the most compact encoding. + * For :class:`~email.message.EmailMessage`, per :rfc:`2046`, raise + an error if a *cte* of ``quoted-printable`` or ``base64`` is + requested for *subtype* ``rfc822``, and for any *cte* other than + ``7bit`` for *subtype* ``external-body``. For + ``message/rfc822``, use ``8bit`` if *cte* is not specified. For + all other values of *subtype*, use ``7bit``. .. note:: A *cte* of ``binary`` does not actually work correctly yet. The ``EmailMessage`` object as modified by ``set_content`` is diff --git a/Doc/library/email.encoders.rst b/Doc/library/email.encoders.rst index 5d68b104f3a45c..3bd377e33f6c15 100644 --- a/Doc/library/email.encoders.rst +++ b/Doc/library/email.encoders.rst @@ -25,7 +25,7 @@ is especially true for :mimetype:`image/\*` and :mimetype:`text/\*` type message containing binary data. The :mod:`email` package provides some convenient encoders in its -:mod:`encoders` module. These encoders are actually used by the +:mod:`~email.encoders` module. These encoders are actually used by the :class:`~email.mime.audio.MIMEAudio` and :class:`~email.mime.image.MIMEImage` class constructors to provide default encodings. All encoder functions take exactly one argument, the message object to encode. They usually extract the diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index eb775b68362c76..afa0038ea2d6c4 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -274,9 +274,9 @@ in with information about the part. .. rubric:: Footnotes .. [#] This statement assumes that you use the appropriate setting for - ``unixfrom``, and that there are no :mod:`policy` settings calling for + ``unixfrom``, and that there are no :mod:`email.policy` settings calling for automatic adjustments (for example, - :attr:`~email.policy.Policy.refold_source` must be ``none``, which is + :attr:`~email.policy.EmailPolicy.refold_source` must be ``none``, which is *not* the default). It is also not 100% true, since if the message does not conform to the RFC standards occasionally information about the exact original text is lost during parsing error recovery. It is a goal diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 5e0509f4181199..225f498781fa86 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -67,7 +67,7 @@ message objects. with the base :class:`~email.message.Message` class *maxheaderlen* is accepted, but defaults to ``None``, which means that by default the line length is controlled by the - :attr:`~email.policy.EmailPolicy.max_line_length` of the policy. The + :attr:`~email.policy.Policy.max_line_length` of the policy. The *policy* argument may be used to override the default policy obtained from the message instance. This can be used to control some of the formatting produced by the method, since the specified *policy* will be @@ -213,7 +213,7 @@ message objects. del msg['subject'] msg['subject'] = 'Python roolz!' - If the :mod:`policy` defines certain headers to be unique (as the standard + If the :mod:`policy ` defines certain headers to be unique (as the standard policies do), this method may raise a :exc:`ValueError` when an attempt is made to assign a value to such a header when one already exists. This behavior is intentional for consistency's sake, but do not depend on it @@ -378,7 +378,7 @@ message objects. deprecated. Note that existing parameter values of headers may be accessed through - the :attr:`~email.headerregistry.BaseHeader.params` attribute of the + the :attr:`~email.headerregistry.ParameterizedMIMEHeader.params` attribute of the header value (for example, ``msg['Content-Type'].params['charset']``). .. versionchanged:: 3.4 ``replace`` keyword was added. @@ -691,7 +691,7 @@ message objects. .. method:: clear_content() - Remove the payload and all of the :exc:`Content-` headers, leaving + Remove the payload and all of the :mailheader:`!Content-` headers, leaving all other headers intact and in their original order. diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst index d9a61616bbbdfb..dda0466a6afa7d 100644 --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -39,9 +39,9 @@ returns the root object when you close the parser. Note that the parser can be extended in limited ways, and of course you can implement your own parser completely from scratch. All of the logic that connects the :mod:`email` package's bundled parser and the -:class:`~email.message.EmailMessage` class is embodied in the :mod:`policy` +:class:`~email.message.EmailMessage` class is embodied in the :class:`~email.policy.Policy` class, so a custom parser can create message object trees any way it finds -necessary by implementing custom versions of the appropriate :mod:`policy` +necessary by implementing custom versions of the appropriate :class:`!Policy` methods. diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index 2439dee676c9b0..fd47dd0dc5df36 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -557,17 +557,17 @@ more closely to the RFCs relevant to their domains. With all of these :class:`EmailPolicies <.EmailPolicy>`, the effective API of the email package is changed from the Python 3.2 API in the following ways: - * Setting a header on a :class:`~email.message.Message` results in that - header being parsed and a header object created. +* Setting a header on a :class:`~email.message.Message` results in that + header being parsed and a header object created. - * Fetching a header value from a :class:`~email.message.Message` results - in that header being parsed and a header object created and - returned. +* Fetching a header value from a :class:`~email.message.Message` results + in that header being parsed and a header object created and + returned. - * Any header object, or any header that is refolded due to the - policy settings, is folded using an algorithm that fully implements the - RFC folding algorithms, including knowing where encoded words are required - and allowed. +* Any header object, or any header that is refolded due to the + policy settings, is folded using an algorithm that fully implements the + RFC folding algorithms, including knowing where encoded words are required + and allowed. From the application view, this means that any header obtained through the :class:`~email.message.EmailMessage` is a header object with extra diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index a87a0bd2e7de6b..345b64001c1ace 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -65,11 +65,6 @@ of the new API. *email address* parts. Returns a tuple of that information, unless the parse fails, in which case a 2-tuple of ``('', '')`` is returned. - .. versionchanged:: 3.12 - For security reasons, addresses that were ambiguous and could parse into - multiple different addresses now cause ``('', '')`` to be returned - instead of only one of the *potential* addresses. - .. function:: formataddr(pair, charset='utf-8') @@ -92,7 +87,7 @@ of the new API. This method returns a list of 2-tuples of the form returned by ``parseaddr()``. *fieldvalues* is a sequence of header field values as might be returned by :meth:`Message.get_all `. Here's a simple - example that gets all the recipients of a message: + example that gets all the recipients of a message:: from email.utils import getaddresses @@ -102,25 +97,6 @@ of the new API. resent_ccs = msg.get_all('resent-cc', []) all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) - When parsing fails for a single fieldvalue, a 2-tuple of ``('', '')`` - is returned in its place. Other errors in parsing the list of - addresses such as a fieldvalue seemingly parsing into multiple - addresses may result in a list containing a single empty 2-tuple - ``[('', '')]`` being returned rather than returning potentially - invalid output. - - Example malformed input parsing: - - .. doctest:: - - >>> from email.utils import getaddresses - >>> getaddresses(['alice@example.com ', 'me@example.com']) - [('', '')] - - .. versionchanged:: 3.12 - The 2-tuple of ``('', '')`` in the returned values when parsing - fails were added as to address a security issue. - .. function:: parsedate(date) diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index d7f89cf96368b5..de3b93f5e61073 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -61,7 +61,7 @@ By default, ``pip`` is installed into the current virtual environment active virtual environment). The installation location can be controlled through two additional command line options: -* ``--root ``: Installs ``pip`` relative to the given root directory +* :samp:`--root {dir}`: Installs ``pip`` relative to the given root directory rather than the root of the currently active virtual environment (if any) or the default root for the current Python installation. * ``--user``: Installs ``pip`` into the user site packages directory rather diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index e9c4f0e2c5f59b..d5f46ed58e8d24 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -241,6 +241,10 @@ Data Types >>> list(reversed(Color)) [, , ] + .. versionadded:: 3.11 + + Before 3.11 ``enum`` used ``EnumMeta`` type, which is kept as an alias. + .. class:: Enum @@ -318,7 +322,7 @@ Data Types >>> PowersOfThree.SECOND.value 9 - .. method:: Enum.__init_subclass__(cls, \**kwds) + .. method:: Enum.__init_subclass__(cls, **kwds) A *classmethod* that is used to further configure subsequent subclasses. By default, does nothing. @@ -593,8 +597,8 @@ Data Types If a *Flag* operation is performed with an *IntFlag* member and: - * the result is a valid *IntFlag*: an *IntFlag* is returned - * the result is not a valid *IntFlag*: the result depends on the *FlagBoundary* setting + * the result is a valid *IntFlag*: an *IntFlag* is returned + * the result is not a valid *IntFlag*: the result depends on the *FlagBoundary* setting The *repr()* of unnamed zero-valued flags has changed. It is now: @@ -621,8 +625,8 @@ Data Types :class:`!ReprEnum` uses the :meth:`repr() ` of :class:`Enum`, but the :class:`str() ` of the mixed-in data type: - * :meth:`!int.__str__` for :class:`IntEnum` and :class:`IntFlag` - * :meth:`!str.__str__` for :class:`StrEnum` + * :meth:`!int.__str__` for :class:`IntEnum` and :class:`IntFlag` + * :meth:`!str.__str__` for :class:`StrEnum` Inherit from :class:`!ReprEnum` to keep the :class:`str() ` / :func:`format` of the mixed-in data type instead of using the @@ -785,13 +789,13 @@ Supported ``_sunder_`` names - ``_generate_next_value_`` -- used to get an appropriate value for an enum member; may be overridden - .. note:: + .. note:: - For standard :class:`Enum` classes the next value chosen is the last value seen - incremented by one. + For standard :class:`Enum` classes the next value chosen is the last value seen + incremented by one. - For :class:`Flag` classes the next value chosen will be the next highest - power-of-two, regardless of the last value seen. + For :class:`Flag` classes the next value chosen will be the next highest + power-of-two, regardless of the last value seen. .. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_`` .. versionadded:: 3.7 ``_ignore_`` @@ -813,11 +817,11 @@ Utilities and Decorators *auto* instances are only resolved when at the top level of an assignment: - * ``FIRST = auto()`` will work (auto() is replaced with ``1``); - * ``SECOND = auto(), -2`` will work (auto is replaced with ``2``, so ``2, -2`` is - used to create the ``SECOND`` enum member; - * ``THREE = [auto(), -3]`` will *not* work (``, -3`` is used to - create the ``THREE`` enum member) + * ``FIRST = auto()`` will work (auto() is replaced with ``1``); + * ``SECOND = auto(), -2`` will work (auto is replaced with ``2``, so ``2, -2`` is + used to create the ``SECOND`` enum member; + * ``THREE = [auto(), -3]`` will *not* work (``, -3`` is used to + create the ``THREE`` enum member) .. versionchanged:: 3.11.1 diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst index 5122c69697ef91..283e8b013265d9 100644 --- a/Doc/library/errno.rst +++ b/Doc/library/errno.rst @@ -511,6 +511,13 @@ defined by the module. The specific list of defined symbols is available as Operation not supported on transport endpoint +.. data:: ENOTSUP + + Operation not supported + + .. versionadded:: 3.2 + + .. data:: EPFNOSUPPORT Protocol family not supported @@ -666,3 +673,24 @@ defined by the module. The specific list of defined symbols is available as .. availability:: WASI, FreeBSD .. versionadded:: 3.11.1 + + +.. data:: ECANCELED + + Operation canceled + + .. versionadded:: 3.2 + + +.. data:: EOWNERDEAD + + Owner died + + .. versionadded:: 3.2 + + +.. data:: ENOTRECOVERABLE + + State not recoverable + + .. versionadded:: 3.2 diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 4651eddf843700..cd85df8723a76b 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -220,10 +220,16 @@ The following exceptions are the exceptions that are usually raised. load a module. Also raised when the "from list" in ``from ... import`` has a name that cannot be found. - The :attr:`name` and :attr:`path` attributes can be set using keyword-only - arguments to the constructor. When set they represent the name of the module - that was attempted to be imported and the path to any file which triggered - the exception, respectively. + The optional *name* and *path* keyword-only arguments + set the corresponding attributes: + + .. attribute:: name + + The name of the module that was attempted to be imported. + + .. attribute:: path + + The path to any file which triggered the exception. .. versionchanged:: 3.3 Added the :attr:`name` and :attr:`path` attributes. @@ -659,8 +665,8 @@ depending on the system error code. Raised when an operation would block on an object (e.g. socket) set for non-blocking operation. - Corresponds to :c:data:`errno` :py:data:`~errno.EAGAIN`, :py:data:`~errno.EALREADY`, - :py:data:`~errno.EWOULDBLOCK` and :py:data:`~errno.EINPROGRESS`. + Corresponds to :c:data:`errno` :py:const:`~errno.EAGAIN`, :py:const:`~errno.EALREADY`, + :py:const:`~errno.EWOULDBLOCK` and :py:const:`~errno.EINPROGRESS`. In addition to those of :exc:`OSError`, :exc:`BlockingIOError` can have one more attribute: @@ -674,7 +680,7 @@ depending on the system error code. .. exception:: ChildProcessError Raised when an operation on a child process failed. - Corresponds to :c:data:`errno` :py:data:`~errno.ECHILD`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECHILD`. .. exception:: ConnectionError @@ -688,40 +694,40 @@ depending on the system error code. A subclass of :exc:`ConnectionError`, raised when trying to write on a pipe while the other end has been closed, or trying to write on a socket which has been shutdown for writing. - Corresponds to :c:data:`errno` :py:data:`~errno.EPIPE` and :py:data:`~errno.ESHUTDOWN`. + Corresponds to :c:data:`errno` :py:const:`~errno.EPIPE` and :py:const:`~errno.ESHUTDOWN`. .. exception:: ConnectionAbortedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is aborted by the peer. - Corresponds to :c:data:`errno` :py:data:`~errno.ECONNABORTED`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECONNABORTED`. .. exception:: ConnectionRefusedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is refused by the peer. - Corresponds to :c:data:`errno` :py:data:`~errno.ECONNREFUSED`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECONNREFUSED`. .. exception:: ConnectionResetError A subclass of :exc:`ConnectionError`, raised when a connection is reset by the peer. - Corresponds to :c:data:`errno` :py:data:`~errno.ECONNRESET`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECONNRESET`. .. exception:: FileExistsError Raised when trying to create a file or directory which already exists. - Corresponds to :c:data:`errno` :py:data:`~errno.EEXIST`. + Corresponds to :c:data:`errno` :py:const:`~errno.EEXIST`. .. exception:: FileNotFoundError Raised when a file or directory is requested but doesn't exist. - Corresponds to :c:data:`errno` :py:data:`~errno.ENOENT`. + Corresponds to :c:data:`errno` :py:const:`~errno.ENOENT`. .. exception:: InterruptedError Raised when a system call is interrupted by an incoming signal. - Corresponds to :c:data:`errno` :py:data:`~errno.EINTR`. + Corresponds to :c:data:`errno` :py:const:`~errno.EINTR`. .. versionchanged:: 3.5 Python now retries system calls when a syscall is interrupted by a @@ -732,7 +738,7 @@ depending on the system error code. Raised when a file operation (such as :func:`os.remove`) is requested on a directory. - Corresponds to :c:data:`errno` :py:data:`~errno.EISDIR`. + Corresponds to :c:data:`errno` :py:const:`~errno.EISDIR`. .. exception:: NotADirectoryError @@ -740,28 +746,28 @@ depending on the system error code. something which is not a directory. On most POSIX platforms, it may also be raised if an operation attempts to open or traverse a non-directory file as if it were a directory. - Corresponds to :c:data:`errno` :py:data:`~errno.ENOTDIR`. + Corresponds to :c:data:`errno` :py:const:`~errno.ENOTDIR`. .. exception:: PermissionError Raised when trying to run an operation without the adequate access rights - for example filesystem permissions. - Corresponds to :c:data:`errno` :py:data:`~errno.EACCES`, - :py:data:`~errno.EPERM`, and :py:data:`~errno.ENOTCAPABLE`. + Corresponds to :c:data:`errno` :py:const:`~errno.EACCES`, + :py:const:`~errno.EPERM`, and :py:const:`~errno.ENOTCAPABLE`. .. versionchanged:: 3.11.1 - WASI's :py:data:`~errno.ENOTCAPABLE` is now mapped to + WASI's :py:const:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`. .. exception:: ProcessLookupError Raised when a given process doesn't exist. - Corresponds to :c:data:`errno` :py:data:`~errno.ESRCH`. + Corresponds to :c:data:`errno` :py:const:`~errno.ESRCH`. .. exception:: TimeoutError Raised when a system function timed out at the system level. - Corresponds to :c:data:`errno` :py:data:`~errno.ETIMEDOUT`. + Corresponds to :c:data:`errno` :py:const:`~errno.ETIMEDOUT`. .. versionadded:: 3.3 All the above :exc:`OSError` subclasses were added. diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 997c7ea571fc03..969a79fa873395 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -172,9 +172,9 @@ The module defines the following functions: which the lock starts, relative to *whence*, and *whence* is as with :func:`io.IOBase.seek`, specifically: - * :const:`0` -- relative to the start of the file (:data:`os.SEEK_SET`) - * :const:`1` -- relative to the current buffer position (:data:`os.SEEK_CUR`) - * :const:`2` -- relative to the end of the file (:data:`os.SEEK_END`) + * ``0`` -- relative to the start of the file (:const:`os.SEEK_SET`) + * ``1`` -- relative to the current buffer position (:const:`os.SEEK_CUR`) + * ``2`` -- relative to the end of the file (:const:`os.SEEK_END`) The default for *start* is 0, which means to start at the beginning of the file. The default for *len* is 0 which means to lock to the end of the file. The @@ -201,7 +201,7 @@ using the :func:`flock` call may be better. .. seealso:: Module :mod:`os` - If the locking flags :data:`~os.O_SHLOCK` and :data:`~os.O_EXLOCK` are + If the locking flags :const:`~os.O_SHLOCK` and :const:`~os.O_EXLOCK` are 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/filecmp.rst b/Doc/library/filecmp.rst index 83e9e14ddcacd8..dfe4b7c59fd578 100644 --- a/Doc/library/filecmp.rst +++ b/Doc/library/filecmp.rst @@ -74,7 +74,7 @@ The :class:`dircmp` class Construct a new directory comparison object, to compare the directories *a* and *b*. *ignore* is a list of names to ignore, and defaults to - :attr:`filecmp.DEFAULT_IGNORES`. *hide* is a list of names to hide, and + :const:`filecmp.DEFAULT_IGNORES`. *hide* is a list of names to hide, and defaults to ``[os.curdir, os.pardir]``. The :class:`dircmp` class compares files by doing *shallow* comparisons @@ -100,7 +100,7 @@ The :class:`dircmp` class used to get various bits of information about the directory trees being compared. - Note that via :meth:`__getattr__` hooks, all attributes are computed lazily, + Note that via :meth:`~object.__getattr__` hooks, all attributes are computed lazily, so there is no speed penalty if only those attributes which are lightweight to compute are used. diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 4bc868759f2025..f93e9a58791eeb 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -177,7 +177,7 @@ available for subclassing as well: The keyword-only parameter *encoding* and *errors* are added. .. versionchanged:: 3.11 - The ``'rU'`` and ``'U'`` modes and the :meth:`__getitem__` method have + The ``'rU'`` and ``'U'`` modes and the :meth:`!__getitem__` method have been removed. diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index fe2e8ab655edf8..509c63686f5a7f 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -25,7 +25,7 @@ another rational number, or from a string. The first version requires that *numerator* and *denominator* are instances of :class:`numbers.Rational` and returns a new :class:`Fraction` instance - with value ``numerator/denominator``. If *denominator* is :const:`0`, it + with value ``numerator/denominator``. If *denominator* is ``0``, it raises a :exc:`ZeroDivisionError`. The second version requires that *other_fraction* is an instance of :class:`numbers.Rational` and returns a :class:`Fraction` instance with the same value. The next two versions accept diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index e7fb5b1ae26960..d1fe6414ea020c 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -105,7 +105,7 @@ The module defines the following items: .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a @@ -431,7 +431,7 @@ FTP_TLS Objects .. attribute:: FTP_TLS.ssl_version - The SSL version to use (defaults to :attr:`ssl.PROTOCOL_SSLv23`). + The SSL version to use (defaults to :data:`ssl.PROTOCOL_SSLv23`). .. method:: FTP_TLS.auth() @@ -441,7 +441,7 @@ FTP_TLS Objects .. versionchanged:: 3.4 The method now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. method:: FTP_TLS.ccc() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index d8091f0b093aab..6031ca85434362 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -14,8 +14,8 @@ are always available. They are listed here in alphabetical order. | | :func:`abs` | | :func:`enumerate` | | :func:`len` | | |func-range|_ | | | :func:`aiter` | | :func:`eval` | | |func-list|_ | | :func:`repr` | | | :func:`all` | | :func:`exec` | | :func:`locals` | | :func:`reversed` | -| | :func:`any` | | | | | | :func:`round` | -| | :func:`anext` | | **F** | | **M** | | | +| | :func:`anext` | | | | | | :func:`round` | +| | :func:`any` | | **F** | | **M** | | | | | :func:`ascii` | | :func:`filter` | | :func:`map` | | **S** | | | | | :func:`float` | | :func:`max` | | |func-set|_ | | | **B** | | :func:`format` | | |func-memoryview|_ | | :func:`setattr` | @@ -1158,8 +1158,8 @@ are always available. They are listed here in alphabetical order. See also :func:`format` for more information. - .. index:: - single: file object; open() built-in function +.. index:: + single: file object; open() built-in function .. function:: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) @@ -1231,7 +1231,7 @@ are always available. They are listed here in alphabetical order. * Binary files are buffered in fixed-size chunks; the size of the buffer is chosen using a heuristic trying to determine the underlying device's "block - size" and falling back on :attr:`io.DEFAULT_BUFFER_SIZE`. On many systems, + size" and falling back on :const:`io.DEFAULT_BUFFER_SIZE`. On many systems, the buffer will typically be 4096 or 8192 bytes long. * "Interactive" text files (files for which :meth:`~io.IOBase.isatty` @@ -1271,7 +1271,7 @@ are always available. They are listed here in alphabetical order. * ``'xmlcharrefreplace'`` is only supported when writing to a file. Characters not supported by the encoding are replaced with the - appropriate XML character reference ``&#nnn;``. + appropriate XML character reference :samp:`&#{nnn};`. * ``'backslashreplace'`` replaces malformed data by Python's backslashed escape sequences. @@ -1360,28 +1360,28 @@ are always available. They are listed here in alphabetical order. .. versionchanged:: 3.3 - * The *opener* parameter was added. - * The ``'x'`` mode was added. - * :exc:`IOError` used to be raised, it is now an alias of :exc:`OSError`. - * :exc:`FileExistsError` is now raised if the file opened in exclusive - creation mode (``'x'``) already exists. + * The *opener* parameter was added. + * The ``'x'`` mode was added. + * :exc:`IOError` used to be raised, it is now an alias of :exc:`OSError`. + * :exc:`FileExistsError` is now raised if the file opened in exclusive + creation mode (``'x'``) already exists. .. versionchanged:: 3.4 - * The file is now non-inheritable. + * The file is now non-inheritable. .. versionchanged:: 3.5 - * If the system call is interrupted and the signal handler does not raise an - exception, the function now retries the system call instead of raising an - :exc:`InterruptedError` exception (see :pep:`475` for the rationale). - * The ``'namereplace'`` error handler was added. + * If the system call is interrupted and the signal handler does not raise an + exception, the function now retries the system call instead of raising an + :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + * The ``'namereplace'`` error handler was added. .. versionchanged:: 3.6 - * Support added to accept objects implementing :class:`os.PathLike`. - * On Windows, opening a console buffer may return a subclass of - :class:`io.RawIOBase` other than :class:`io.FileIO`. + * Support added to accept objects implementing :class:`os.PathLike`. + * On Windows, opening a console buffer may return a subclass of + :class:`io.RawIOBase` other than :class:`io.FileIO`. .. versionchanged:: 3.11 The ``'U'`` mode has been removed. @@ -1631,7 +1631,7 @@ are always available. They are listed here in alphabetical order. .. class:: slice(stop) - slice(start, stop, step=1) + slice(start, stop, step=None) Return a :term:`slice` object representing the set of indices specified by ``range(start, stop, step)``. The *start* and *step* arguments default to @@ -1752,7 +1752,7 @@ are always available. They are listed here in alphabetical order. The *start* parameter can be specified as a keyword argument. .. versionchanged:: 3.12 Summation of floats switched to an algorithm - that gives higher accuracy on most builds. + that gives higher accuracy and better commutativity on most builds. .. class:: super() diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 40f43f8b3519cd..69ec1eb3ecd89d 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -226,8 +226,9 @@ The :mod:`functools` module defines the following functions: In general, the LRU cache should only be used when you want to reuse previously computed values. Accordingly, it doesn't make sense to cache - functions with side-effects, functions that need to create distinct mutable - objects on each call, or impure functions such as time() or random(). + functions with side-effects, functions that need to create + distinct mutable objects on each call (such as generators and async functions), + or impure functions such as time() or random(). Example of an LRU cache for static web content:: @@ -402,25 +403,27 @@ The :mod:`functools` module defines the following functions: .. versionadded:: 3.4 -.. function:: reduce(function, iterable[, initializer]) +.. function:: reduce(function, iterable[, initial], /) Apply *function* of two arguments cumulatively to the items of *iterable*, from left to right, so as to reduce the iterable to a single value. For example, ``reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])`` calculates ``((((1+2)+3)+4)+5)``. The left argument, *x*, is the accumulated value and the right argument, *y*, is - the update value from the *iterable*. If the optional *initializer* is present, + the update value from the *iterable*. If the optional *initial* is present, it is placed before the items of the iterable in the calculation, and serves as - a default when the iterable is empty. If *initializer* is not given and + a default when the iterable is empty. If *initial* is not given and *iterable* contains only one item, the first item is returned. Roughly equivalent to:: - def reduce(function, iterable, initializer=None): + initial_missing = object() + + def reduce(function, iterable, initial=initial_missing, /): it = iter(iterable) - if initializer is None: + if initial is initial_missing: value = next(it) else: - value = initializer + value = initial for element in it: value = function(value, element) return value diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 0961ca4aaa9422..331c071cda7692 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -260,7 +260,7 @@ values but should not rebind them): .. versionchanged:: 3.4 Following :pep:`442`, objects with a :meth:`~object.__del__` method don't end - up in :attr:`gc.garbage` anymore. + up in :data:`gc.garbage` anymore. .. data:: callbacks diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 747f8703b750ec..dc6cf5533fccbe 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -58,7 +58,7 @@ class-based API instead. Return the localized translation of *message*, based on the current global domain, language, and locale directory. This function is usually aliased as - :func:`_` in the local namespace (see examples below). + :func:`!_` in the local namespace (see examples below). .. function:: dgettext(domain, message) @@ -98,7 +98,7 @@ class-based API instead. .. versionadded:: 3.8 -Note that GNU :program:`gettext` also defines a :func:`dcgettext` method, but +Note that GNU :program:`gettext` also defines a :func:`!dcgettext` method, but this was deemed not useful and so it is currently unimplemented. Here's an example of typical usage for this API:: @@ -119,7 +119,7 @@ greater convenience than the GNU :program:`gettext` API. It is the recommended way of localizing your Python applications and modules. :mod:`!gettext` defines a :class:`GNUTranslations` class which implements the parsing of GNU :file:`.mo` format files, and has methods for returning strings. Instances of this class can also -install themselves in the built-in namespace as the function :func:`_`. +install themselves in the built-in namespace as the function :func:`!_`. .. function:: find(domain, localedir=None, languages=None, all=False) @@ -150,15 +150,12 @@ install themselves in the built-in namespace as the function :func:`_`. .. function:: translation(domain, localedir=None, languages=None, class_=None, fallback=False) - Return a :class:`*Translations` instance based on the *domain*, *localedir*, + Return a ``*Translations`` instance based on the *domain*, *localedir*, and *languages*, which are first passed to :func:`find` to get a list of the associated :file:`.mo` file paths. Instances with identical :file:`.mo` file names are cached. The actual class instantiated is *class_* if provided, otherwise :class:`GNUTranslations`. The class's constructor must - take a single :term:`file object` argument. If provided, *codeset* will change - the charset used to encode translated strings in the - :meth:`~NullTranslations.lgettext` and :meth:`~NullTranslations.lngettext` - methods. + take a single :term:`file object` argument. If multiple files are found, later files are used as fallbacks for earlier ones. To allow setting the fallback, :func:`copy.copy` is used to clone each @@ -170,26 +167,26 @@ install themselves in the built-in namespace as the function :func:`_`. :class:`NullTranslations` instance if *fallback* is true. .. versionchanged:: 3.3 - :exc:`IOError` used to be raised instead of :exc:`OSError`. + :exc:`IOError` used to be raised, it is now an alias of :exc:`OSError`. .. versionchanged:: 3.11 *codeset* parameter is removed. .. function:: install(domain, localedir=None, *, names=None) - This installs the function :func:`_` in Python's builtins namespace, based on + This installs the function :func:`!_` in Python's builtins namespace, based on *domain* and *localedir* which are passed to the function :func:`translation`. For the *names* parameter, please see the description of the translation object's :meth:`~NullTranslations.install` method. As seen below, you usually mark the strings in your application that are - candidates for translation, by wrapping them in a call to the :func:`_` + candidates for translation, by wrapping them in a call to the :func:`!_` function, like this:: print(_('This string will be translated.')) - For convenience, you want the :func:`_` function to be installed in Python's + For convenience, you want the :func:`!_` function to be installed in Python's builtins namespace, so it is easily accessible in all modules of your application. @@ -276,20 +273,20 @@ are the methods of :class:`!NullTranslations`: If the *names* parameter is given, it must be a sequence containing the names of functions you want to install in the builtins namespace in - addition to :func:`_`. Supported names are ``'gettext'``, ``'ngettext'``, - ``'pgettext'``, ``'npgettext'``, ``'lgettext'``, and ``'lngettext'``. + addition to :func:`!_`. Supported names are ``'gettext'``, ``'ngettext'``, + ``'pgettext'``, and ``'npgettext'``. Note that this is only one way, albeit the most convenient way, to make - the :func:`_` function available to your application. Because it affects + the :func:`!_` function available to your application. Because it affects the entire application globally, and specifically the built-in namespace, - localized modules should never install :func:`_`. Instead, they should use - this code to make :func:`_` available to their module:: + localized modules should never install :func:`!_`. Instead, they should use + this code to make :func:`!_` available to their module:: import gettext t = gettext.translation('mymodule', ...) _ = t.gettext - This puts :func:`_` only in the module's global namespace and so only + This puts :func:`!_` only in the module's global namespace and so only affects calls within this module. .. versionchanged:: 3.8 @@ -314,7 +311,7 @@ initialize the "protected" :attr:`_charset` instance variable, defaulting to ids and message strings read from the catalog are converted to Unicode using this encoding, else ASCII is assumed. -Since message ids are read as Unicode strings too, all :meth:`*gettext` methods +Since message ids are read as Unicode strings too, all ``*gettext()`` methods will assume message ids as Unicode strings, not byte strings. The entire set of key/value pairs are placed into a dictionary and set as the @@ -404,13 +401,14 @@ version has a slightly different API. Its documented usage was:: _ = cat.gettext print(_('hello world')) -For compatibility with this older module, the function :func:`Catalog` is an +For compatibility with this older module, the function :func:`!Catalog` is an alias for the :func:`translation` function described above. One difference between this module and Henstridge's: his catalog objects supported access through a mapping API, but this appears to be unused and so is not currently supported. +.. _i18n-howto: Internationalizing your programs and modules -------------------------------------------- @@ -431,7 +429,7 @@ take the following steps: In order to prepare your code for I18N, you need to look at all the strings in your files. Any string that needs to be translated should be marked by wrapping -it in ``_('...')`` --- that is, a call to the function :func:`_`. For example:: +it in ``_('...')`` --- that is, a call to the function :func:`_ `. For example:: filename = 'mylog.txt' message = _('writing a log message') @@ -503,7 +501,7 @@ module:: Localizing your application ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you are localizing your application, you can install the :func:`_` function +If you are localizing your application, you can install the :func:`!_` function globally into the built-in namespace, usually in the main driver file of your application. This will let all your application-specific files just use ``_('...')`` without having to explicitly install it in each file. @@ -580,13 +578,13 @@ Here is one way you can handle this situation:: for a in animals: print(_(a)) -This works because the dummy definition of :func:`_` simply returns the string +This works because the dummy definition of :func:`!_` simply returns the string unchanged. And this dummy definition will temporarily override any definition -of :func:`_` in the built-in namespace (until the :keyword:`del` command). Take -care, though if you have a previous definition of :func:`_` in the local +of :func:`!_` in the built-in namespace (until the :keyword:`del` command). Take +care, though if you have a previous definition of :func:`!_` in the local namespace. -Note that the second use of :func:`_` will not identify "a" as being +Note that the second use of :func:`!_` will not identify "a" as being translatable to the :program:`gettext` program, because the parameter is not a string literal. @@ -605,13 +603,13 @@ Another way to handle this is with the following example:: print(_(a)) In this case, you are marking translatable strings with the function -:func:`N_`, which won't conflict with any definition of :func:`_`. +:func:`!N_`, which won't conflict with any definition of :func:`!_`. However, you will need to teach your message extraction program to -look for translatable strings marked with :func:`N_`. :program:`xgettext`, +look for translatable strings marked with :func:`!N_`. :program:`xgettext`, :program:`pygettext`, ``pybabel extract``, and :program:`xpot` all support this through the use of the :option:`!-k` command-line switch. -The choice of :func:`N_` here is totally arbitrary; it could have just -as easily been :func:`MarkThisStringForTranslation`. +The choice of :func:`!N_` here is totally arbitrary; it could have just +as easily been :func:`!MarkThisStringForTranslation`. Acknowledgements diff --git a/Doc/library/graphlib.rst b/Doc/library/graphlib.rst index fe7932e7a61cb5..5414d6370b78ce 100644 --- a/Doc/library/graphlib.rst +++ b/Doc/library/graphlib.rst @@ -37,14 +37,14 @@ In the general case, the steps required to perform the sorting of a given graph are as follows: - * Create an instance of the :class:`TopologicalSorter` with an optional - initial graph. - * Add additional nodes to the graph. - * Call :meth:`~TopologicalSorter.prepare` on the graph. - * While :meth:`~TopologicalSorter.is_active` is ``True``, iterate over - the nodes returned by :meth:`~TopologicalSorter.get_ready` and - process them. Call :meth:`~TopologicalSorter.done` on each node as it - finishes processing. + * Create an instance of the :class:`TopologicalSorter` with an optional + initial graph. + * Add additional nodes to the graph. + * Call :meth:`~TopologicalSorter.prepare` on the graph. + * While :meth:`~TopologicalSorter.is_active` is ``True``, iterate over + the nodes returned by :meth:`~TopologicalSorter.get_ready` and + process them. Call :meth:`~TopologicalSorter.done` on each node as it + finishes processing. In case just an immediate sorting of the nodes in the graph is required and no parallelism is involved, the convenience method @@ -115,7 +115,7 @@ :meth:`TopologicalSorter.done` is less than the number that have been returned by :meth:`TopologicalSorter.get_ready`. - The :meth:`~TopologicalSorter.__bool__` method of this class defers to + The :meth:`~object.__bool__` method of this class defers to this function, so instead of:: if ts.is_active(): @@ -204,7 +204,7 @@ The :mod:`graphlib` module defines the following exception classes: in the working graph. If multiple cycles exist, only one undefined choice among them will be reported and included in the exception. - The detected cycle can be accessed via the second element in the :attr:`~CycleError.args` + The detected cycle can be accessed via the second element in the :attr:`~BaseException.args` attribute of the exception instance and consists in a list of nodes, such that each node is, in the graph, an immediate predecessor of the next node in the list. In the reported list, the first and the last node will be the same, to make it clear that it is cyclic. diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 06cbd2567a0bc6..f931d0e399c9f2 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -70,7 +70,7 @@ The module defines the following items: .. class:: GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None) Constructor for the :class:`GzipFile` class, which simulates most of the - methods of a :term:`file object`, with the exception of the :meth:`truncate` + methods of a :term:`file object`, with the exception of the :meth:`~io.IOBase.truncate` method. At least one of *fileobj* and *filename* must be given a non-trivial value. @@ -113,7 +113,7 @@ The module defines the following items: :class:`GzipFile` supports the :class:`io.BufferedIOBase` interface, including iteration and the :keyword:`with` statement. Only the - :meth:`truncate` method isn't implemented. + :meth:`~io.IOBase.truncate` method isn't implemented. :class:`GzipFile` also provides the following method and attribute: @@ -250,6 +250,8 @@ Example of how to GZIP compress a binary string:: .. program:: gzip +.. _gzip-cli: + Command Line Interface ---------------------- @@ -266,23 +268,23 @@ Once executed the :mod:`gzip` module keeps the input file(s). Command line options ^^^^^^^^^^^^^^^^^^^^ -.. cmdoption:: file +.. option:: file - If *file* is not specified, read from :attr:`sys.stdin`. + If *file* is not specified, read from :data:`sys.stdin`. -.. cmdoption:: --fast +.. option:: --fast Indicates the fastest compression method (less compression). -.. cmdoption:: --best +.. option:: --best Indicates the slowest compression method (best compression). -.. cmdoption:: -d, --decompress +.. option:: -d, --decompress Decompress the given file. -.. cmdoption:: -h, --help +.. option:: -h, --help Show the help message. diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 8102767a43d6dd..761dd84edee299 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -136,16 +136,16 @@ Using :func:`new` with an algorithm name: '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' -.. function:: md5([, data], \*, usedforsecurity=True) -.. function:: sha1([, data], \*, usedforsecurity=True) -.. function:: sha224([, data], \*, usedforsecurity=True) -.. function:: sha256([, data], \*, usedforsecurity=True) -.. function:: sha384([, data], \*, usedforsecurity=True) -.. function:: sha512([, data], \*, usedforsecurity=True) -.. function:: sha3_224([, data], \*, usedforsecurity=True) -.. function:: sha3_256([, data], \*, usedforsecurity=True) -.. function:: sha3_384([, data], \*, usedforsecurity=True) -.. function:: sha3_512([, data], \*, usedforsecurity=True) +.. function:: md5([, data], *, usedforsecurity=True) +.. function:: sha1([, data], *, usedforsecurity=True) +.. function:: sha224([, data], *, usedforsecurity=True) +.. function:: sha256([, data], *, usedforsecurity=True) +.. function:: sha384([, data], *, usedforsecurity=True) +.. function:: sha512([, data], *, usedforsecurity=True) +.. function:: sha3_224([, data], *, usedforsecurity=True) +.. function:: sha3_256([, data], *, usedforsecurity=True) +.. function:: sha3_384([, data], *, usedforsecurity=True) +.. function:: sha3_512([, data], *, usedforsecurity=True) Named constructors such as these are faster than passing an algorithm name to :func:`new`. @@ -234,8 +234,8 @@ A hash object has the following methods: SHAKE variable length digests ----------------------------- -.. function:: shake_128([, data], \*, usedforsecurity=True) -.. function:: shake_256([, data], \*, usedforsecurity=True) +.. function:: shake_128([, data], *, usedforsecurity=True) +.. function:: shake_256([, data], *, usedforsecurity=True) The :func:`shake_128` and :func:`shake_256` algorithms provide variable length digests with length_in_bits//2 up to 128 or 256 bits of security. @@ -244,7 +244,7 @@ by the SHAKE algorithm. .. method:: shake.digest(length) - Return the digest of the data passed to the :meth:`update` method so far. + Return the digest of the data passed to the :meth:`~hash.update` method so far. This is a bytes object of size *length* which may contain bytes in the whole range from 0 to 255. @@ -364,6 +364,8 @@ include a `salt `_. .. versionadded:: 3.6 +.. _hashlib-blake2: + BLAKE2 ------ @@ -507,9 +509,9 @@ Simple hashing To calculate hash of some data, you should first construct a hash object by calling the appropriate constructor function (:func:`blake2b` or -:func:`blake2s`), then update it with the data by calling :meth:`update` on the +:func:`blake2s`), then update it with the data by calling :meth:`~hash.update` on the object, and, finally, get the digest out of the object by calling -:meth:`digest` (or :meth:`hexdigest` for hex-encoded string). +:meth:`~hash.digest` (or :meth:`~hash.hexdigest` for hex-encoded string). >>> from hashlib import blake2b >>> h = blake2b() diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst index 03aff25ce6117a..d35090111e0822 100644 --- a/Doc/library/html.parser.rst +++ b/Doc/library/html.parser.rst @@ -173,7 +173,7 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`): .. method:: HTMLParser.handle_charref(name) This method is called to process decimal and hexadecimal numeric character - references of the form ``&#NNN;`` and ``&#xNNN;``. For example, the decimal + references of the form :samp:`&#{NNN};` and :samp:`&#x{NNN};`. For example, the decimal equivalent for ``>`` is ``>``, whereas the hexadecimal is ``>``; in this case the method will receive ``'62'`` or ``'x3E'``. This method is never called if *convert_charrefs* is ``True``. diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index b9ceab699cef63..c46314fc5e253b 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -83,7 +83,7 @@ The module provides the following classes: .. versionchanged:: 3.2 This class now supports HTTPS virtual hosts if possible (that is, - if :data:`ssl.HAS_SNI` is true). + if :const:`ssl.HAS_SNI` is true). .. versionchanged:: 3.4 The *strict* parameter was removed. HTTP 0.9-style "Simple Responses" are diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 87ef156a0bed57..12a6d768437ea5 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -44,8 +44,8 @@ The module defines the following exception: cookies from a file. :exc:`LoadError` is a subclass of :exc:`OSError`. .. versionchanged:: 3.3 - LoadError was made a subclass of :exc:`OSError` instead of - :exc:`IOError`. + :exc:`LoadError` used to be a subtype of :exc:`IOError`, which is now an + alias of :exc:`OSError`. The following classes are provided: diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index ae75e6dc5fdcf3..6f79b222790094 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -217,7 +217,7 @@ provides three different variants: attribute holds the default values for *message* and *explain* that will be used if no value is provided; for unknown codes the default value for both is the string ``???``. The body will be empty if the method is - HEAD or the response code is one of the following: ``1xx``, + HEAD or the response code is one of the following: :samp:`1{xx}`, ``204 No Content``, ``205 Reset Content``, ``304 Not Modified``. .. versionchanged:: 3.4 @@ -502,11 +502,24 @@ following command runs an HTTP/1.1 conformant server:: Note that CGI scripts will be run with UID of user nobody, for security reasons. Problems with the CGI script will be translated to error 403. + .. deprecated-removed:: 3.13 3.15 + + :class:`CGIHTTPRequestHandler` is being removed in 3.15. CGI has not + been considered a good way to do things for well over a decade. This code + has been unmaintained for a while now and sees very little practical use. + Retaining it could lead to further :ref:`security considerations + `. + :class:`CGIHTTPRequestHandler` can be enabled in the command line by passing the ``--cgi`` option:: python -m http.server --cgi +.. deprecated-removed:: 3.13 3.15 + + :mod:`http.server` command line ``--cgi`` support is being removed + because :class:`CGIHTTPRequestHandler` is being removed. + .. _http.server-security: Security Considerations diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 3058bcead661f3..e710d0bacf3fee 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -439,24 +439,24 @@ the :kbd:`Command` key on macOS. * Some useful Emacs bindings are inherited from Tcl/Tk: - * :kbd:`C-a` beginning of line + * :kbd:`C-a` beginning of line - * :kbd:`C-e` end of line + * :kbd:`C-e` end of line - * :kbd:`C-k` kill line (but doesn't put it in clipboard) + * :kbd:`C-k` kill line (but doesn't put it in clipboard) - * :kbd:`C-l` center window around the insertion point + * :kbd:`C-l` center window around the insertion point - * :kbd:`C-b` go backward one character without deleting (usually you can - also use the cursor key for this) + * :kbd:`C-b` go backward one character without deleting (usually you can + also use the cursor key for this) - * :kbd:`C-f` go forward one character without deleting (usually you can - also use the cursor key for this) + * :kbd:`C-f` go forward one character without deleting (usually you can + also use the cursor key for this) - * :kbd:`C-p` go up one line (usually you can also use the cursor key for - this) + * :kbd:`C-p` go up one line (usually you can also use the cursor key for + this) - * :kbd:`C-d` delete next character + * :kbd:`C-d` delete next character Standard keybindings (like :kbd:`C-c` to copy and :kbd:`C-v` to paste) may work. Keybindings are selected in the Configure IDLE dialog. @@ -479,7 +479,7 @@ Search and Replace Any selection becomes a search target. However, only selections within a line work because searches are only performed within lines with the -terminal newline removed. If ``[x] Regular expresion`` is checked, the +terminal newline removed. If ``[x] Regular expression`` is checked, the target is interpreted according to the Python re module. .. _completions: diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 59d7711f9cbd3c..1f774e64b0eae3 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -106,7 +106,7 @@ There's also a subclass for secure connections: .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 The optional *timeout* parameter was added. @@ -503,7 +503,7 @@ An :class:`IMAP4` instance has the following methods: .. versionchanged:: 3.4 The method now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. method:: IMAP4.status(mailbox, names) diff --git a/Doc/library/importlib.resources.abc.rst b/Doc/library/importlib.resources.abc.rst index 2d0f137ffc7996..c508b6ba965cc0 100644 --- a/Doc/library/importlib.resources.abc.rst +++ b/Doc/library/importlib.resources.abc.rst @@ -43,8 +43,6 @@ :const:`None`. An object compatible with this ABC should only be returned when the specified module is a package. - .. versionadded:: 3.7 - .. deprecated-removed:: 3.12 3.14 Use :class:`importlib.resources.abc.TraversableResources` instead. @@ -95,11 +93,6 @@ For a representation of the object on the file-system, use :meth:`importlib.resources.as_file`. - .. versionadded:: 3.9 - - .. deprecated-removed:: 3.12 3.14 - Use :class:`importlib.resources.abc.Traversable` instead. - .. attribute:: name Abstract. The base name of this object without any parent references. @@ -130,7 +123,7 @@ suitable for reading (same as :attr:`pathlib.Path.open`). When opening as text, accepts encoding parameters such as those - accepted by :attr:`io.TextIOWrapper`. + accepted by :class:`io.TextIOWrapper`. .. method:: read_bytes() @@ -145,19 +138,14 @@ An abstract base class for resource readers capable of serving the :meth:`importlib.resources.files` interface. Subclasses - :class:`importlib.resources.abc.ResourceReader` and provides - concrete implementations of the :class:`importlib.resources.abc.ResourceReader`'s + :class:`ResourceReader` and provides + concrete implementations of the :class:`!ResourceReader`'s abstract methods. Therefore, any loader supplying - :class:`importlib.abc.TraversableResources` also supplies ResourceReader. + :class:`!TraversableResources` also supplies :class:`!ResourceReader`. Loaders that wish to support resource reading are expected to implement this interface. - .. versionadded:: 3.9 - - .. deprecated-removed:: 3.12 3.14 - Use :class:`importlib.resources.abc.TraversableResources` instead. - .. abstractmethod:: files() Returns a :class:`importlib.resources.abc.Traversable` object for the loaded diff --git a/Doc/library/importlib.resources.rst b/Doc/library/importlib.resources.rst index 76faf731144779..3de97e80311a17 100644 --- a/Doc/library/importlib.resources.rst +++ b/Doc/library/importlib.resources.rst @@ -82,15 +82,18 @@ for example, a package and its resources can be imported from a zip file using .. function:: as_file(traversable) Given a :class:`~importlib.resources.abc.Traversable` object representing - a file, typically from :func:`importlib.resources.files`, return - a context manager for use in a :keyword:`with` statement. + a file or directory, typically from :func:`importlib.resources.files`, + return a context manager for use in a :keyword:`with` statement. The context manager provides a :class:`pathlib.Path` object. - Exiting the context manager cleans up any temporary file created when the - resource was extracted from e.g. a zip file. + Exiting the context manager cleans up any temporary file or directory + created when the resource was extracted from e.g. a zip file. Use ``as_file`` when the Traversable methods - (``read_text``, etc) are insufficient and an actual file on + (``read_text``, etc) are insufficient and an actual file or directory on the file system is required. .. versionadded:: 3.9 + + .. versionchanged:: 3.12 + Added support for ``traversable`` representing a directory. diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 65aaad0df9ee66..fc954724bb72fe 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -372,7 +372,7 @@ ABC hierarchy:: The list of locations where the package's submodules will be found. Most of the time this is a single directory. The import system passes this attribute to ``__import__()`` and to finders - in the same way as :attr:`sys.path` but just for the package. + in the same way as :data:`sys.path` but just for the package. It is not set on non-package modules so it can be used as an indicator that the module is a package. @@ -609,7 +609,7 @@ ABC hierarchy:: automatically. When writing to the path fails because the path is read-only - (:attr:`errno.EACCES`/:exc:`PermissionError`), do not propagate the + (:const:`errno.EACCES`/:exc:`PermissionError`), do not propagate the exception. .. versionchanged:: 3.4 @@ -645,6 +645,160 @@ ABC hierarchy:: itself does not end in ``__init__``. +.. class:: ResourceReader + + *Superseded by TraversableResources* + + An :term:`abstract base class` to provide the ability to read + *resources*. + + From the perspective of this ABC, a *resource* is a binary + artifact that is shipped within a package. Typically this is + something like a data file that lives next to the ``__init__.py`` + file of the package. The purpose of this class is to help abstract + out the accessing of such data files so that it does not matter if + the package and its data file(s) are stored in a e.g. zip file + versus on the file system. + + For any of methods of this class, a *resource* argument is + expected to be a :term:`path-like object` which represents + conceptually just a file name. This means that no subdirectory + paths should be included in the *resource* argument. This is + because the location of the package the reader is for, acts as the + "directory". Hence the metaphor for directories and file + names is packages and resources, respectively. This is also why + instances of this class are expected to directly correlate to + a specific package (instead of potentially representing multiple + packages or a module). + + Loaders that wish to support resource reading are expected to + provide a method called ``get_resource_reader(fullname)`` which + returns an object implementing this ABC's interface. If the module + specified by fullname is not a package, this method should return + :const:`None`. An object compatible with this ABC should only be + returned when the specified module is a package. + + .. versionadded:: 3.7 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: open_resource(resource) + + Returns an opened, :term:`file-like object` for binary reading + of the *resource*. + + If the resource cannot be found, :exc:`FileNotFoundError` is + raised. + + .. abstractmethod:: resource_path(resource) + + Returns the file system path to the *resource*. + + If the resource does not concretely exist on the file system, + raise :exc:`FileNotFoundError`. + + .. abstractmethod:: is_resource(name) + + Returns ``True`` if the named *name* is considered a resource. + :exc:`FileNotFoundError` is raised if *name* does not exist. + + .. abstractmethod:: contents() + + Returns an :term:`iterable` of strings over the contents of + the package. Do note that it is not required that all names + returned by the iterator be actual resources, e.g. it is + acceptable to return names for which :meth:`is_resource` would + be false. + + Allowing non-resource names to be returned is to allow for + situations where how a package and its resources are stored + are known a priori and the non-resource names would be useful. + For instance, returning subdirectory names is allowed so that + when it is known that the package and resources are stored on + the file system then those subdirectory names can be used + directly. + + The abstract method returns an iterable of no items. + + +.. class:: Traversable + + An object with a subset of :class:`pathlib.Path` methods suitable for + traversing directories and opening files. + + For a representation of the object on the file-system, use + :meth:`importlib.resources.as_file`. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.Traversable` instead. + + .. attribute:: name + + Abstract. The base name of this object without any parent references. + + .. abstractmethod:: iterdir() + + Yield ``Traversable`` objects in ``self``. + + .. abstractmethod:: is_dir() + + Return ``True`` if ``self`` is a directory. + + .. abstractmethod:: is_file() + + Return ``True`` if ``self`` is a file. + + .. abstractmethod:: joinpath(child) + + Return Traversable child in ``self``. + + .. abstractmethod:: __truediv__(child) + + Return ``Traversable`` child in ``self``. + + .. abstractmethod:: open(mode='r', *args, **kwargs) + + *mode* may be 'r' or 'rb' to open as text or binary. Return a handle + suitable for reading (same as :attr:`pathlib.Path.open`). + + When opening as text, accepts encoding parameters such as those + accepted by :attr:`io.TextIOWrapper`. + + .. method:: read_bytes() + + Read contents of ``self`` as bytes. + + .. method:: read_text(encoding=None) + + Read contents of ``self`` as text. + + +.. class:: TraversableResources + + An abstract base class for resource readers capable of serving + the :meth:`importlib.resources.files` interface. Subclasses + :class:`importlib.resources.abc.ResourceReader` and provides + concrete implementations of the :class:`importlib.resources.abc.ResourceReader`'s + abstract methods. Therefore, any loader supplying + :class:`importlib.abc.TraversableResources` also supplies ResourceReader. + + Loaders that wish to support resource reading are expected to + implement this interface. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: files() + + Returns a :class:`importlib.resources.abc.Traversable` object for the loaded + package. + + :mod:`importlib.machinery` -- Importers and path hooks ------------------------------------------------------ @@ -843,7 +997,7 @@ find and load modules. .. classmethod:: path_hook(*loader_details) - A class method which returns a closure for use on :attr:`sys.path_hooks`. + A class method which returns a closure for use on :data:`sys.path_hooks`. An instance of :class:`FileFinder` is returned by the closure using the path argument given to the closure directly and *loader_details* indirectly. @@ -941,8 +1095,15 @@ find and load modules. The *fullname* argument specifies the name of the module the loader is to support. The *path* argument is the path to the extension module's file. + Note that, by default, importing an extension module will fail + in subinterpreters if it doesn't implement multi-phase init + (see :pep:`489`), even if it would otherwise import successfully. + .. versionadded:: 3.3 + .. versionchanged:: 3.12 + Multi-phase init is now required for use in subinterpreters. + .. attribute:: name Name of the module the loader supports. @@ -1184,10 +1345,10 @@ an :term:`importer`. .. function:: find_spec(name, package=None) Find the :term:`spec ` for a module, optionally relative to - the specified **package** name. If the module is in :attr:`sys.modules`, + the specified **package** name. If the module is in :data:`sys.modules`, then ``sys.modules[name].__spec__`` is returned (unless the spec would be ``None`` or is not set, in which case :exc:`ValueError` is raised). - Otherwise a search using :attr:`sys.meta_path` is done. ``None`` is + Otherwise a search using :data:`sys.meta_path` is done. ``None`` is returned if no spec is found. If **name** is for a submodule (contains a dot), the parent module is @@ -1248,6 +1409,30 @@ an :term:`importer`. .. versionadded:: 3.7 +.. function:: _incompatible_extension_module_restrictions(*, disable_check) + + A context manager that can temporarily skip the compatibility check + for extension modules. By default the check is enabled and will fail + when a single-phase init module is imported in a subinterpreter. + It will also fail for a multi-phase init module that doesn't + explicitly support a per-interpreter GIL, when imported + in an interpreter with its own GIL. + + Note that this function is meant to accommodate an unusual case; + one which is likely to eventually go away. There's is a pretty good + chance this is not what you were looking for. + + You can get the same effect as this function by implementing the + basic interface of multi-phase init (:pep:`489`) and lying about + support for multiple interpreters (or per-interpreter GIL). + + .. warning:: + Using this function to disable the check can lead to + unexpected behavior and even crashes. It should only be used during + extension module development. + + .. versionadded:: 3.12 + .. class:: LazyLoader(loader) A class which postpones the execution of the loader of a module until the @@ -1259,7 +1444,7 @@ an :term:`importer`. :meth:`~importlib.abc.Loader.create_module` method must return ``None`` or a type for which its ``__class__`` attribute can be mutated along with not using :term:`slots <__slots__>`. Finally, modules which substitute the object - placed into :attr:`sys.modules` will not work as there is no way to properly + placed into :data:`sys.modules` will not work as there is no way to properly replace the module references throughout the interpreter safely; :exc:`ValueError` is raised if such a substitution is detected. @@ -1383,9 +1568,9 @@ For deep customizations of import, you typically want to implement an :term:`importer`. This means managing both the :term:`finder` and :term:`loader` side of things. For finders there are two flavours to choose from depending on your needs: a :term:`meta path finder` or a :term:`path entry finder`. The -former is what you would put on :attr:`sys.meta_path` while the latter is what -you create using a :term:`path entry hook` on :attr:`sys.path_hooks` which works -with :attr:`sys.path` entries to potentially create a finder. This example will +former is what you would put on :data:`sys.meta_path` while the latter is what +you create using a :term:`path entry hook` on :data:`sys.path_hooks` which works +with :data:`sys.path` entries to potentially create a finder. This example will show you how to register your own importers so that import will use them (for creating an importer for yourself, read the documentation for the appropriate classes defined within this package):: diff --git a/Doc/library/index.rst b/Doc/library/index.rst index d064b680f9aaa4..0b348ae6f5c8c0 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -73,5 +73,6 @@ the `Python Package Index `_. language.rst windows.rst unix.rst + cmdline.rst superseded.rst security_warnings.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 7884308a333020..3efd3be5909254 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -689,8 +689,8 @@ function. The optional *return_annotation* argument, can be an arbitrary Python object, is the "return" annotation of the callable. - Signature objects are *immutable*. Use :meth:`Signature.replace` to make a - modified copy. + Signature objects are *immutable*. Use :meth:`Signature.replace` or + :func:`copy.replace` to make a modified copy. .. versionchanged:: 3.5 Signature objects are picklable and :term:`hashable`. @@ -730,7 +730,7 @@ function. .. method:: Signature.replace(*[, parameters][, return_annotation]) - Create a new Signature instance based on the instance replace was invoked + Create a new Signature instance based on the instance :meth:`replace` was invoked on. It is possible to pass different ``parameters`` and/or ``return_annotation`` to override the corresponding properties of the base signature. To remove return_annotation from the copied Signature, pass in @@ -746,6 +746,9 @@ function. >>> str(new_sig) "(a, b) -> 'new return anno'" + Signature objects are also supported by generic function + :func:`copy.replace`. + .. classmethod:: Signature.from_callable(obj, *, follow_wrapped=True, globalns=None, localns=None) Return a :class:`Signature` (or its subclass) object for a given callable @@ -769,7 +772,7 @@ function. .. class:: Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty) Parameter objects are *immutable*. Instead of modifying a Parameter object, - you can use :meth:`Parameter.replace` to create a modified copy. + you can use :meth:`Parameter.replace` or :func:`copy.replace` to create a modified copy. .. versionchanged:: 3.5 Parameter objects are picklable and :term:`hashable`. @@ -892,6 +895,8 @@ function. >>> str(param.replace(default=Parameter.empty, annotation='spam')) "foo:'spam'" + Parameter objects are also supported by generic function :func:`copy.replace`. + .. versionchanged:: 3.4 In Python 3.3 Parameter objects were allowed to have ``name`` set to ``None`` if their ``kind`` was set to ``POSITIONAL_ONLY``. @@ -1458,10 +1463,11 @@ generator to be determined easily. Get current state of a generator-iterator. Possible states are: - * GEN_CREATED: Waiting to start execution. - * GEN_RUNNING: Currently being executed by the interpreter. - * GEN_SUSPENDED: Currently suspended at a yield expression. - * GEN_CLOSED: Execution has completed. + + * GEN_CREATED: Waiting to start execution. + * GEN_RUNNING: Currently being executed by the interpreter. + * GEN_SUSPENDED: Currently suspended at a yield expression. + * GEN_CLOSED: Execution has completed. .. versionadded:: 3.2 @@ -1473,10 +1479,11 @@ generator to be determined easily. ``cr_frame`` attributes. Possible states are: - * CORO_CREATED: Waiting to start execution. - * CORO_RUNNING: Currently being executed by the interpreter. - * CORO_SUSPENDED: Currently suspended at an await expression. - * CORO_CLOSED: Execution has completed. + + * CORO_CREATED: Waiting to start execution. + * CORO_RUNNING: Currently being executed by the interpreter. + * CORO_SUSPENDED: Currently suspended at an await expression. + * CORO_CLOSED: Execution has completed. .. versionadded:: 3.5 @@ -1489,10 +1496,11 @@ generator to be determined easily. ``ag_running`` and ``ag_frame`` attributes. Possible states are: - * AGEN_CREATED: Waiting to start execution. - * AGEN_RUNNING: Currently being executed by the interpreter. - * AGEN_SUSPENDED: Currently suspended at a yield expression. - * AGEN_CLOSED: Execution has completed. + + * AGEN_CREATED: Waiting to start execution. + * AGEN_RUNNING: Currently being executed by the interpreter. + * AGEN_SUSPENDED: Currently suspended at a yield expression. + * AGEN_CLOSED: Execution has completed. .. versionadded:: 3.12 @@ -1650,6 +1658,6 @@ By default, accepts the name of a module and prints the source of that module. A class or function within the module can be printed instead by appended a colon and the qualified name of the target object. -.. cmdoption:: --details +.. option:: --details Print information about the specified object rather than the source code diff --git a/Doc/library/io.rst b/Doc/library/io.rst index c9249da1c3c3d2..6736aa9ee2b0ef 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -38,9 +38,9 @@ location), or only sequential access (for example in the case of a socket or pipe). All streams are careful about the type of data you give to them. For example -giving a :class:`str` object to the ``write()`` method of a binary stream +giving a :class:`str` object to the :meth:`!write` method of a binary stream will raise a :exc:`TypeError`. So will giving a :class:`bytes` object to the -``write()`` method of a text stream. +:meth:`!write` method of a text stream. .. versionchanged:: 3.3 Operations that used to raise :exc:`IOError` now raise :exc:`OSError`, since @@ -146,7 +146,7 @@ Opt-in EncodingWarning See :pep:`597` for more details. To find where the default locale encoding is used, you can enable -the ``-X warn_default_encoding`` command line option or set the +the :option:`-X warn_default_encoding <-X>` command line option or set the :envvar:`PYTHONWARNDEFAULTENCODING` environment variable, which will emit an :exc:`EncodingWarning` when the default encoding is used. @@ -175,7 +175,7 @@ High-level Module Interface .. audit-event:: open path,mode,flags io.open This function raises an :ref:`auditing event ` ``open`` with - arguments ``path``, ``mode`` and ``flags``. The ``mode`` and ``flags`` + arguments *path*, *mode* and *flags*. The *mode* and *flags* arguments may have been modified or inferred from the original call. @@ -184,10 +184,10 @@ High-level Module Interface Opens the provided file with mode ``'rb'``. This function should be used when the intent is to treat the contents as executable code. - ``path`` should be a :class:`str` and an absolute path. + *path* should be a :class:`str` and an absolute path. The behavior of this function may be overridden by an earlier call to the - :c:func:`PyFile_SetOpenCodeHook`. However, assuming that ``path`` is a + :c:func:`PyFile_SetOpenCodeHook`. However, assuming that *path* is a :class:`str` and an absolute path, ``open_code(path)`` should always behave the same as ``open(path, 'rb')``. Overriding the behavior is intended for additional validation or preprocessing of the file. @@ -253,12 +253,12 @@ The implementation of I/O streams is organized as a hierarchy of classes. First specify the various categories of streams, then concrete classes providing the standard stream implementations. - .. note:: +.. note:: - The abstract base classes also provide default implementations of some - methods in order to help implementation of concrete stream classes. For - example, :class:`BufferedIOBase` provides unoptimized implementations of - :meth:`~IOBase.readinto` and :meth:`~IOBase.readline`. + The abstract base classes also provide default implementations of some + methods in order to help implementation of concrete stream classes. For + example, :class:`BufferedIOBase` provides unoptimized implementations of + :meth:`!readinto` and :meth:`!readline`. At the top of the I/O hierarchy is the abstract base class :class:`IOBase`. It defines the basic interface to a stream. Note, however, that there is no @@ -320,8 +320,8 @@ I/O Base Classes implementations represent a file that cannot be read, written or seeked. - Even though :class:`IOBase` does not declare :meth:`read` - or :meth:`write` because their signatures will vary, implementations and + Even though :class:`IOBase` does not declare :meth:`!read` + or :meth:`!write` because their signatures will vary, implementations and clients should consider those methods part of the interface. Also, implementations may raise a :exc:`ValueError` (or :exc:`UnsupportedOperation`) when operations they do not support are called. @@ -379,8 +379,8 @@ I/O Base Classes .. method:: readable() - Return ``True`` if the stream can be read from. If ``False``, :meth:`read` - will raise :exc:`OSError`. + Return ``True`` if the stream can be read from. + If ``False``, :meth:`!read` will raise :exc:`OSError`. .. method:: readline(size=-1, /) @@ -401,29 +401,28 @@ I/O Base Classes hint. Note that it's already possible to iterate on file objects using ``for - line in file: ...`` without calling ``file.readlines()``. + line in file: ...`` without calling :meth:`!file.readlines`. - .. method:: seek(offset, whence=SEEK_SET, /) + .. method:: seek(offset, whence=os.SEEK_SET, /) - Change the stream position to the given byte *offset*. *offset* is - interpreted relative to the position indicated by *whence*. The default - value for *whence* is :data:`SEEK_SET`. Values for *whence* are: + Change the stream position to the given byte *offset*, + interpreted relative to the position indicated by *whence*, + and return the new absolute position. + Values for *whence* are: - * :data:`SEEK_SET` or ``0`` -- start of the stream (the default); + * :data:`os.SEEK_SET` or ``0`` -- start of the stream (the default); *offset* should be zero or positive - * :data:`SEEK_CUR` or ``1`` -- current stream position; *offset* may - be negative - * :data:`SEEK_END` or ``2`` -- end of the stream; *offset* is usually - negative - - Return the new absolute position. + * :data:`os.SEEK_CUR` or ``1`` -- current stream position; + *offset* may be negative + * :data:`os.SEEK_END` or ``2`` -- end of the stream; + *offset* is usually negative .. versionadded:: 3.1 - The ``SEEK_*`` constants. + The :data:`!SEEK_*` constants. .. versionadded:: 3.3 Some operating systems could support additional values, like - :data:`os.SEEK_HOLE` or :data:`os.SEEK_DATA`. The valid values + :const:`os.SEEK_HOLE` or :const:`os.SEEK_DATA`. The valid values for a file could depend on it being open in text or binary mode. .. method:: seekable() @@ -450,7 +449,7 @@ I/O Base Classes .. method:: writable() Return ``True`` if the stream supports writing. If ``False``, - :meth:`write` and :meth:`truncate` will raise :exc:`OSError`. + :meth:`!write` and :meth:`truncate` will raise :exc:`OSError`. .. method:: writelines(lines, /) @@ -654,8 +653,9 @@ Raw File I/O implies writing, so this mode behaves in a similar way to ``'w'``. Add a ``'+'`` to the mode to allow simultaneous reading and writing. - The :meth:`read` (when called with a positive argument), :meth:`readinto` - and :meth:`write` methods on this class will only make one system call. + The :meth:`~RawIOBase.read` (when called with a positive argument), + :meth:`~RawIOBase.readinto` and :meth:`~RawIOBase.write` methods on this + class will only make one system call. A custom opener can be used by passing a callable as *opener*. The underlying file descriptor for the file object is then obtained by calling *opener* with @@ -791,8 +791,8 @@ than raw I/O does. object under various conditions, including: * when the buffer gets too small for all pending data; - * when :meth:`flush()` is called; - * when a :meth:`seek()` is requested (for :class:`BufferedRandom` objects); + * when :meth:`flush` is called; + * when a :meth:`~IOBase.seek` is requested (for :class:`BufferedRandom` objects); * when the :class:`BufferedWriter` object is closed or destroyed. The constructor creates a :class:`BufferedWriter` for the given writeable @@ -826,8 +826,8 @@ than raw I/O does. :data:`DEFAULT_BUFFER_SIZE`. :class:`BufferedRandom` is capable of anything :class:`BufferedReader` or - :class:`BufferedWriter` can do. In addition, :meth:`seek` and :meth:`tell` - are guaranteed to be implemented. + :class:`BufferedWriter` can do. In addition, :meth:`~IOBase.seek` and + :meth:`~IOBase.tell` are guaranteed to be implemented. .. class:: BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /) @@ -904,7 +904,7 @@ Text I/O .. method:: readline(size=-1, /) - Read until newline or EOF and return a single ``str``. If the stream is + Read until newline or EOF and return a single :class:`str`. If the stream is already at EOF, an empty string is returned. If *size* is specified, at most *size* characters will be read. @@ -913,22 +913,22 @@ Text I/O Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is - :data:`SEEK_SET`. + :data:`!SEEK_SET`. - * :data:`SEEK_SET` or ``0``: seek from the start of the stream + * :data:`!SEEK_SET` or ``0``: seek from the start of the stream (the default); *offset* must either be a number returned by :meth:`TextIOBase.tell`, or zero. Any other *offset* value produces undefined behaviour. - * :data:`SEEK_CUR` or ``1``: "seek" to the current position; + * :data:`!SEEK_CUR` or ``1``: "seek" to the current position; *offset* must be zero, which is a no-operation (all other values are unsupported). - * :data:`SEEK_END` or ``2``: seek to the end of the stream; + * :data:`!SEEK_END` or ``2``: seek to the end of the stream; *offset* must be zero (all other values are unsupported). Return the new absolute position as an opaque number. .. versionadded:: 3.1 - The ``SEEK_*`` constants. + The :data:`!SEEK_*` constants. .. method:: tell() @@ -988,10 +988,10 @@ Text I/O takes place. If *newline* is any of the other legal values, any ``'\n'`` characters written are translated to the given string. - If *line_buffering* is ``True``, :meth:`flush` is implied when a call to + If *line_buffering* is ``True``, :meth:`~IOBase.flush` is implied when a call to write contains a newline character or a carriage return. - If *write_through* is ``True``, calls to :meth:`write` are guaranteed + If *write_through* is ``True``, calls to :meth:`~BufferedIOBase.write` are guaranteed not to be buffered: any data written on the :class:`TextIOWrapper` object is immediately handled to its underlying binary *buffer*. @@ -1043,6 +1043,33 @@ Text I/O .. versionchanged:: 3.11 The method supports ``encoding="locale"`` option. + .. method:: seek(cookie, whence=os.SEEK_SET, /) + + Set the stream position. + Return the new stream position as an :class:`int`. + + Four operations are supported, + given by the following argument combinations: + + * ``seek(0, SEEK_SET)``: Rewind to the start of the stream. + * ``seek(cookie, SEEK_SET)``: Restore a previous position; + *cookie* **must be** a number returned by :meth:`tell`. + * ``seek(0, SEEK_END)``: Fast-forward to the end of the stream. + * ``seek(0, SEEK_CUR)``: Leave the current stream position unchanged. + + Any other argument combinations are invalid, + and may raise exceptions. + + .. seealso:: + + :data:`os.SEEK_SET`, :data:`os.SEEK_CUR`, and :data:`os.SEEK_END`. + + .. method:: tell() + + Return the stream position as an opaque number. + The return value of :meth:`!tell` can be given as input to :meth:`seek`, + to restore a previous stream position. + .. class:: StringIO(initial_value='', newline='\n') @@ -1070,7 +1097,7 @@ Text I/O .. method:: getvalue() - Return a ``str`` containing the entire contents of the buffer. + Return a :class:`str` containing the entire contents of the buffer. Newlines are decoded as if by :meth:`~TextIOBase.read`, although the stream position is not changed. @@ -1125,7 +1152,7 @@ Text I/O over a binary storage (such as a file) is significantly slower than binary I/O over the same storage, because it requires conversions between unicode and binary data using a character codec. This can become noticeable handling huge amounts of text data like large log files. Also, -:meth:`TextIOWrapper.tell` and :meth:`TextIOWrapper.seek` are both quite slow +:meth:`~TextIOBase.tell` and :meth:`~TextIOBase.seek` are both quite slow due to the reconstruction algorithm used. :class:`StringIO`, however, is a native in-memory unicode container and will @@ -1135,7 +1162,7 @@ Multi-threading ^^^^^^^^^^^^^^^ :class:`FileIO` objects are thread-safe to the extent that the operating system -calls (such as ``read(2)`` under Unix) they wrap are thread-safe too. +calls (such as :manpage:`read(2)` under Unix) they wrap are thread-safe too. Binary buffered objects (instances of :class:`BufferedReader`, :class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 730736bbb59ed9..5846d784c88ccc 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -844,7 +844,7 @@ which incur interpreter overhead. return next(islice(iterable, n, None), default) def quantify(iterable, pred=bool): - "Count how many times the predicate is True" + "Given a predicate that returns True or False, count the True results." return sum(map(pred, iterable)) def all_equal(iterable): @@ -865,26 +865,23 @@ which incur interpreter overhead. # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x return next(filter(pred, iterable), default) - def iter_index(iterable, value, start=0): + def iter_index(iterable, value, start=0, stop=None): "Return indices where a value occurs in a sequence or iterable." # iter_index('AABCADEAF', 'A') --> 0 1 4 7 - try: - seq_index = iterable.index - except AttributeError: + seq_index = getattr(iterable, 'index', None) + if seq_index is None: # Slow path for general iterables - it = islice(iterable, start, None) - i = start - 1 - try: - while True: - yield (i := i + operator.indexOf(it, value) + 1) - except ValueError: - pass + it = islice(iterable, start, stop) + for i, element in enumerate(it, start): + if element is value or element == value: + yield i else: # Fast path for sequences + stop = len(iterable) if stop is None else stop i = start - 1 try: while True: - yield (i := seq_index(value, i+1)) + yield (i := seq_index(value, i+1, stop)) except ValueError: pass @@ -1031,33 +1028,6 @@ The following recipes have a more mathematical flavor: s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - def sieve(n): - "Primes less than n." - # sieve(30) --> 2 3 5 7 11 13 17 19 23 29 - data = bytearray((0, 1)) * (n // 2) - data[:3] = 0, 0, 0 - limit = math.isqrt(n) + 1 - for p in compress(range(limit), data): - data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p))) - data[2] = 1 - return iter_index(data, 1) if n > 2 else iter([]) - - def factor(n): - "Prime factors of n." - # factor(99) --> 3 3 11 - # factor(1_000_000_000_000_007) --> 47 59 360620266859 - # factor(1_000_000_000_000_403) --> 1000000000000403 - for prime in sieve(math.isqrt(n) + 1): - while True: - if n % prime: - break - yield prime - n //= prime - if n == 1: - return - if n > 1: - yield n - def sum_of_squares(it): "Add up the squares of the input values." # sum_of_squares([10, 20, 30]) -> 1400 @@ -1075,14 +1045,21 @@ The following recipes have a more mathematical flavor: return batched(starmap(math.sumprod, product(m1, transpose(m2))), n) def convolve(signal, kernel): - """Linear convolution of two iterables. + """Discrete linear convolution of two iterables. + + The kernel is fully consumed before the calculations begin. + The signal is consumed lazily and can be infinite. + + Convolutions are mathematically commutative. + If the signal and kernel are swapped, + the output will be the same. Article: https://betterexplained.com/articles/intuitive-convolution/ Video: https://www.youtube.com/watch?v=KuXjwB4LzSA """ # convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur) - # convolve(data, [1, -1]) --> 1st finite difference (1st derivative) - # convolve(data, [1, -2, 1]) --> 2nd finite difference (2nd derivative) + # convolve(data, [1/2, 0, -1/2]) --> 1st derivative estimate + # convolve(data, [1, -2, 1]) --> 2nd derivative estimate kernel = tuple(kernel)[::-1] n = len(kernel) padded_signal = chain(repeat(0, n-1), signal, repeat(0, n-1)) @@ -1106,8 +1083,8 @@ The following recipes have a more mathematical flavor: # Evaluate x³ -4x² -17x + 60 at x = 2.5 # polynomial_eval([1, -4, -17, 60], x=2.5) --> 8.125 n = len(coefficients) - if n == 0: - return x * 0 # coerce zero to the type of x + if not n: + return type(x)(0) powers = map(pow, repeat(x), reversed(range(n))) return math.sumprod(coefficients, powers) @@ -1122,6 +1099,34 @@ The following recipes have a more mathematical flavor: powers = reversed(range(1, n)) return list(map(operator.mul, coefficients, powers)) + def sieve(n): + "Primes less than n." + # sieve(30) --> 2 3 5 7 11 13 17 19 23 29 + if n > 2: + yield 2 + start = 3 + data = bytearray((0, 1)) * (n // 2) + limit = math.isqrt(n) + 1 + for p in iter_index(data, 1, start, limit): + yield from iter_index(data, 1, start, p*p) + data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p))) + start = p*p + yield from iter_index(data, 1, start) + + def factor(n): + "Prime factors of n." + # factor(99) --> 3 3 11 + # factor(1_000_000_000_000_007) --> 47 59 360620266859 + # factor(1_000_000_000_000_403) --> 1000000000000403 + for prime in sieve(math.isqrt(n) + 1): + while not n % prime: + yield prime + n //= prime + if n == 1: + return + if n > 1: + yield n + def nth_combination(iterable, r, index): "Equivalent to list(combinations(iterable, r))[index]" pool = tuple(iterable) @@ -1297,7 +1302,7 @@ The following recipes have a more mathematical flavor: >>> polynomial_eval([], Fraction(2, 3)) Fraction(0, 1) >>> polynomial_eval([], Decimal('1.75')) - Decimal('0.00') + Decimal('0') >>> polynomial_eval([11], 7) == 11 True >>> polynomial_eval([11, 2], 7) == 11 * 7 + 2 @@ -1333,6 +1338,31 @@ The following recipes have a more mathematical flavor: [] >>> list(iter_index(iter('AABCADEAF'), 'A', 10)) [] + >>> list(iter_index('AABCADEAF', 'A', 1, 7)) + [1, 4] + >>> list(iter_index(iter('AABCADEAF'), 'A', 1, 7)) + [1, 4] + >>> # Verify that ValueErrors not swallowed (gh-107208) + >>> def assert_no_value(iterable, forbidden_value): + ... for item in iterable: + ... if item == forbidden_value: + ... raise ValueError + ... yield item + ... + >>> list(iter_index(assert_no_value('AABCADEAF', 'B'), 'A')) + Traceback (most recent call last): + ... + ValueError + >>> # Verify that both paths can find identical NaN values + >>> x = float('NaN') + >>> y = float('NaN') + >>> list(iter_index([0, x, x, y, 0], x)) + [1, 2] + >>> list(iter_index(iter([0, x, x, y, 0]), x)) + [1, 2] + >>> # Test list input. Lists do not support None for the stop argument + >>> list(iter_index(list('AABCADEAF'), 'A')) + [0, 1, 4, 7] >>> list(sieve(30)) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 5383614575c213..0ce4b697145cb3 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -54,12 +54,23 @@ Compact encoding:: Pretty printing:: >>> import json - >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) + >>> print(json.dumps({'6': 7, '4': 5}, sort_keys=True, indent=4)) { "4": 5, "6": 7 } +Specializing JSON object encoding:: + + >>> import json + >>> def custom_json(obj): + ... if isinstance(obj, complex): + ... return {'__complex__': True, 'real': obj.real, 'imag': obj.imag} + ... raise TypeError(f'Cannot serialize object of {type(obj)}') + ... + >>> json.dumps(1 + 2j, default=custom_json) + '{"__complex__": true, "real": 1.0, "imag": 2.0}' + Decoding JSON:: >>> import json @@ -192,7 +203,7 @@ Basic Usage dictionaries will be sorted by key. To use a custom :class:`JSONEncoder` subclass (e.g. one that overrides the - :meth:`default` method to serialize additional types), specify it with the + :meth:`~JSONEncoder.default` method to serialize additional types), specify it with the *cls* kwarg; otherwise :class:`JSONEncoder` is used. .. versionchanged:: 3.6 @@ -422,7 +433,7 @@ Encoders and Decoders Added support for int- and float-derived Enum classes. To extend this to recognize other objects, subclass and implement a - :meth:`default` method with another method that returns a serializable object + :meth:`~JSONEncoder.default` method with another method that returns a serializable object for ``o`` if possible, otherwise it should call the superclass implementation (to raise :exc:`TypeError`). @@ -483,7 +494,7 @@ Encoders and Decoders :exc:`TypeError`). For example, to support arbitrary iterators, you could implement - :meth:`default` like this:: + :meth:`~JSONEncoder.default` like this:: def default(self, o): try: @@ -683,7 +694,7 @@ The :mod:`json.tool` module provides a simple command line interface to validate and pretty-print JSON objects. If the optional ``infile`` and ``outfile`` arguments are not -specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively: +specified, :data:`sys.stdin` and :data:`sys.stdout` will be used respectively: .. code-block:: shell-session @@ -703,7 +714,7 @@ specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively: Command line options ^^^^^^^^^^^^^^^^^^^^ -.. cmdoption:: infile +.. option:: infile The JSON file to be validated or pretty-printed: @@ -721,38 +732,38 @@ Command line options } ] - If *infile* is not specified, read from :attr:`sys.stdin`. + If *infile* is not specified, read from :data:`sys.stdin`. -.. cmdoption:: outfile +.. option:: outfile Write the output of the *infile* to the given *outfile*. Otherwise, write it - to :attr:`sys.stdout`. + to :data:`sys.stdout`. -.. cmdoption:: --sort-keys +.. option:: --sort-keys Sort the output of dictionaries alphabetically by key. .. versionadded:: 3.5 -.. cmdoption:: --no-ensure-ascii +.. option:: --no-ensure-ascii Disable escaping of non-ascii characters, see :func:`json.dumps` for more information. .. versionadded:: 3.9 -.. cmdoption:: --json-lines +.. option:: --json-lines Parse every input line as separate JSON object. .. versionadded:: 3.8 -.. cmdoption:: --indent, --tab, --no-indent, --compact +.. option:: --indent, --tab, --no-indent, --compact Mutually exclusive options for whitespace control. .. versionadded:: 3.9 -.. cmdoption:: -h, --help +.. option:: -h, --help Show the help message. diff --git a/Doc/library/kde_example.png b/Doc/library/kde_example.png new file mode 100644 index 00000000000000..f4504895699974 Binary files /dev/null and b/Doc/library/kde_example.png differ diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 448978f43b6d13..85a53e6aa7a78b 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -257,11 +257,11 @@ otherwise, the context is used to determine what to instantiate. which correspond to the arguments passed to create a :class:`~logging.Formatter` object: - * ``format`` - * ``datefmt`` - * ``style`` - * ``validate`` (since version >=3.8) - * ``defaults`` (since version >=3.12) + * ``format`` + * ``datefmt`` + * ``style`` + * ``validate`` (since version >=3.8) + * ``defaults`` (since version >=3.12) An optional ``class`` key indicates the name of the formatter's class (as a dotted module and class name). The instantiation @@ -544,9 +544,9 @@ valid keyword parameter name, and so will not clash with the names of the keyword arguments used in the call. The ``'()'`` also serves as a mnemonic that the corresponding value is a callable. - .. versionchanged:: 3.11 - The ``filters`` member of ``handlers`` and ``loggers`` can take - filter instances in addition to ids. +.. versionchanged:: 3.11 + The ``filters`` member of ``handlers`` and ``loggers`` can take + filter instances in addition to ids. You can also specify a special key ``'.'`` whose value is a dictionary is a mapping of attribute names to values. If found, the specified attributes will @@ -685,7 +685,8 @@ resolve to ``'dev_team@domain.tld'`` and the string ``'support_team@domain.tld'``. The ``subject`` value could be accessed using either ``'cfg://handlers.email.subject'`` or, equivalently, ``'cfg://handlers.email[subject]'``. The latter form only needs to be -used if the key contains spaces or non-alphanumeric characters. If an +used if the key contains spaces or non-alphanumeric characters. Please note +that the characters ``[`` and ``]`` are not allowed in the keys. If an index value consists only of decimal digits, access will be attempted using the corresponding integer value, falling back to the string value if needed. diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index d4429d3d0a4f73..2a825db54aed5c 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -97,7 +97,7 @@ sends logging output to a disk file. It inherits the output functionality from Returns a new instance of the :class:`FileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, - :const:`'a'` is used. If *encoding* is not ``None``, it is used to open the file + ``'a'`` is used. If *encoding* is not ``None``, it is used to open the file with that encoding. If *delay* is true, then file opening is deferred until the first call to :meth:`emit`. By default, the file grows indefinitely. If *errors* is specified, it's used to determine how encoding errors are handled. @@ -182,7 +182,7 @@ for this value. Returns a new instance of the :class:`WatchedFileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, - :const:`'a'` is used. If *encoding* is not ``None``, it is used to open the file + ``'a'`` is used. If *encoding* is not ``None``, it is used to open the file with that encoding. If *delay* is true, then file opening is deferred until the first call to :meth:`emit`. By default, the file grows indefinitely. If *errors* is provided, it determines how encoding errors are handled. @@ -917,8 +917,9 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: flush() - You can override this to implement custom flushing behavior. This version - just zaps the buffer to empty. + For a :class:`BufferingHandler` instance, flushing means that it sets the + buffer to an empty list. This method can be overwritten to implement more useful + flushing behavior. .. method:: shouldFlush(record) @@ -950,9 +951,9 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: flush() - For a :class:`MemoryHandler`, flushing means just sending the buffered + For a :class:`MemoryHandler` instance, flushing means just sending the buffered records to the target, if there is one. The buffer is also cleared when - this happens. Override if you want different behavior. + buffered records are sent to the target. Override if you want different behavior. .. method:: setTarget(target) @@ -1051,8 +1052,8 @@ possible, while any potentially slow operations (such as sending an email via occur (e.g. because a bounded queue has filled up), the :meth:`~logging.Handler.handleError` method is called to handle the error. This can result in the record silently being dropped (if - :attr:`logging.raiseExceptions` is ``False``) or a message printed to - ``sys.stderr`` (if :attr:`logging.raiseExceptions` is ``True``). + :data:`logging.raiseExceptions` is ``False``) or a message printed to + ``sys.stderr`` (if :data:`logging.raiseExceptions` is ``True``). .. method:: prepare(record) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 4e07eabd57f5e9..acdeb88a546261 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -397,21 +397,39 @@ have specific values relative to the predefined levels. If you define a level with the same numeric value, it overwrites the predefined value; the predefined name is lost. -+--------------+---------------+ -| Level | Numeric value | -+==============+===============+ -| ``CRITICAL`` | 50 | -+--------------+---------------+ -| ``ERROR`` | 40 | -+--------------+---------------+ -| ``WARNING`` | 30 | -+--------------+---------------+ -| ``INFO`` | 20 | -+--------------+---------------+ -| ``DEBUG`` | 10 | -+--------------+---------------+ -| ``NOTSET`` | 0 | -+--------------+---------------+ ++-----------------------+---------------+-------------------------------------+ +| Level | Numeric value | What it means / When to use it | ++=======================+===============+=====================================+ +| .. py:data:: NOTSET | 0 | When set on a logger, indicates that| +| | | ancestor loggers are to be consulted| +| | | to determine the effective level. | +| | | If that still resolves to | +| | | :const:`!NOTSET`, then all events | +| | | are logged. When set on a handler, | +| | | all events are handled. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: DEBUG | 10 | Detailed information, typically only| +| | | of interest to a developer trying to| +| | | diagnose a problem. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: INFO | 20 | Confirmation that things are working| +| | | as expected. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: WARNING | 30 | An indication that something | +| | | unexpected happened, or that a | +| | | problem might occur in the near | +| | | future (e.g. 'disk space low'). The | +| | | software is still working as | +| | | expected. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: ERROR | 40 | Due to a more serious problem, the | +| | | software has not been able to | +| | | perform some function. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: CRITICAL | 50 | A serious error, indicating that the| +| | | program itself may be unable to | +| | | continue running. | ++-----------------------+---------------+-------------------------------------+ .. _handler: @@ -421,7 +439,7 @@ Handler Objects Handlers have the following attributes and methods. Note that :class:`Handler` is never instantiated directly; this class acts as a base for more useful -subclasses. However, the :meth:`__init__` method in subclasses needs to call +subclasses. However, the :meth:`!__init__` method in subclasses needs to call :meth:`Handler.__init__`. .. class:: Handler @@ -889,7 +907,7 @@ you want to use. In the case of {}-formatting, you can specify formatting flags by placing them after the attribute name, separated from it with a colon. For example: a -placeholder of ``{msecs:03d}`` would format a millisecond value of ``4`` as +placeholder of ``{msecs:03.0f}`` would format a millisecond value of ``4`` as ``004``. Refer to the :meth:`str.format` documentation for full details on the options available to you. @@ -984,10 +1002,14 @@ LoggerAdapter Objects information into logging calls. For a usage example, see the section on :ref:`adding contextual information to your logging output `. -.. class:: LoggerAdapter(logger, extra) +.. class:: LoggerAdapter(logger, extra, merge_extra=False) Returns an instance of :class:`LoggerAdapter` initialized with an - underlying :class:`Logger` instance and a dict-like object. + underlying :class:`Logger` instance, a dict-like object (*extra*), and a + boolean (*merge_extra*) indicating whether or not the *extra* argument of + individual log calls should be merged with the :class:`LoggerAdapter` extra. + The default behavior is to ignore the *extra* argument of individual log + calls and only use the one of the :class:`LoggerAdapter` instance .. method:: process(msg, kwargs) @@ -997,27 +1019,42 @@ information into logging calls. For a usage example, see the section on 'extra'. The return value is a (*msg*, *kwargs*) tuple which has the (possibly modified) versions of the arguments passed in. -In addition to the above, :class:`LoggerAdapter` supports the following -methods of :class:`Logger`: :meth:`~Logger.debug`, :meth:`~Logger.info`, -:meth:`~Logger.warning`, :meth:`~Logger.error`, :meth:`~Logger.exception`, -:meth:`~Logger.critical`, :meth:`~Logger.log`, :meth:`~Logger.isEnabledFor`, -:meth:`~Logger.getEffectiveLevel`, :meth:`~Logger.setLevel` and -:meth:`~Logger.hasHandlers`. These methods have the same signatures as their -counterparts in :class:`Logger`, so you can use the two types of instances -interchangeably. + .. attribute:: manager -.. versionchanged:: 3.2 - The :meth:`~Logger.isEnabledFor`, :meth:`~Logger.getEffectiveLevel`, - :meth:`~Logger.setLevel` and :meth:`~Logger.hasHandlers` methods were added - to :class:`LoggerAdapter`. These methods delegate to the underlying logger. + Delegates to the underlying :attr:`!manager`` on *logger*. + + .. attribute:: _log + + Delegates to the underlying :meth:`!_log`` method on *logger*. + + In addition to the above, :class:`LoggerAdapter` supports the following + methods of :class:`Logger`: :meth:`~Logger.debug`, :meth:`~Logger.info`, + :meth:`~Logger.warning`, :meth:`~Logger.error`, :meth:`~Logger.exception`, + :meth:`~Logger.critical`, :meth:`~Logger.log`, :meth:`~Logger.isEnabledFor`, + :meth:`~Logger.getEffectiveLevel`, :meth:`~Logger.setLevel` and + :meth:`~Logger.hasHandlers`. These methods have the same signatures as their + counterparts in :class:`Logger`, so you can use the two types of instances + interchangeably. + + .. versionchanged:: 3.2 + + The :meth:`~Logger.isEnabledFor`, :meth:`~Logger.getEffectiveLevel`, + :meth:`~Logger.setLevel` and :meth:`~Logger.hasHandlers` methods were added + to :class:`LoggerAdapter`. These methods delegate to the underlying logger. -.. versionchanged:: 3.6 - Attribute :attr:`manager` and method :meth:`_log` were added, which - delegate to the underlying logger and allow adapters to be nested. + .. versionchanged:: 3.6 + + Attribute :attr:`!manager` and method :meth:`!_log` were added, which + delegate to the underlying logger and allow adapters to be nested. + + .. versionchanged:: 3.13 + + Remove the undocumented :meth:`!warn`` method which was an alias to the + :meth:`!warning` method. + + .. versionchanged:: 3.13 -.. versionchanged:: 3.13 - Remove the undocumented ``warn()`` method which was an alias to the - ``warning()`` method. + The *merge_extra* argument was added. Thread Safety @@ -1405,8 +1442,8 @@ functions. .. function:: setLoggerClass(klass) Tells the logging system to use the class *klass* when instantiating a logger. - The class should define :meth:`__init__` such that only a name argument is - required, and the :meth:`__init__` should call :meth:`Logger.__init__`. This + The class should define :meth:`!__init__` such that only a name argument is + required, and the :meth:`!__init__` should call :meth:`!Logger.__init__`. This function is typically called before any loggers are instantiated by applications which need to use custom logger behavior. After this call, as at any other time, do not instantiate loggers directly using the subclass: continue to use diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 868d4dcfb6c996..0d69c3bc01d1e2 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -100,7 +100,8 @@ Reading and writing compressed files *filters* arguments have the same meanings as for :class:`LZMACompressor`. :class:`LZMAFile` supports all the members specified by - :class:`io.BufferedIOBase`, except for :meth:`detach` and :meth:`truncate`. + :class:`io.BufferedIOBase`, except for :meth:`~io.BufferedIOBase.detach` + and :meth:`~io.IOBase.truncate`. Iteration and the :keyword:`with` statement are supported. The following method is also provided: @@ -332,19 +333,22 @@ the key ``"id"``, and may contain additional keys to specify filter-dependent options. Valid filter IDs are as follows: * Compression filters: - * :const:`FILTER_LZMA1` (for use with :const:`FORMAT_ALONE`) - * :const:`FILTER_LZMA2` (for use with :const:`FORMAT_XZ` and :const:`FORMAT_RAW`) + + * :const:`FILTER_LZMA1` (for use with :const:`FORMAT_ALONE`) + * :const:`FILTER_LZMA2` (for use with :const:`FORMAT_XZ` and :const:`FORMAT_RAW`) * Delta filter: - * :const:`FILTER_DELTA` + + * :const:`FILTER_DELTA` * Branch-Call-Jump (BCJ) filters: - * :const:`FILTER_X86` - * :const:`FILTER_IA64` - * :const:`FILTER_ARM` - * :const:`FILTER_ARMTHUMB` - * :const:`FILTER_POWERPC` - * :const:`FILTER_SPARC` + + * :const:`FILTER_X86` + * :const:`FILTER_IA64` + * :const:`FILTER_ARM` + * :const:`FILTER_ARMTHUMB` + * :const:`FILTER_POWERPC` + * :const:`FILTER_SPARC` A filter chain can consist of up to 4 filters, and cannot be empty. The last filter in the chain must be a compression filter, and any other filters must be @@ -353,21 +357,21 @@ delta or BCJ filters. Compression filters support the following options (specified as additional entries in the dictionary representing the filter): - * ``preset``: A compression preset to use as a source of default values for - options that are not specified explicitly. - * ``dict_size``: Dictionary size in bytes. This should be between 4 KiB and - 1.5 GiB (inclusive). - * ``lc``: Number of literal context bits. - * ``lp``: Number of literal position bits. The sum ``lc + lp`` must be at - most 4. - * ``pb``: Number of position bits; must be at most 4. - * ``mode``: :const:`MODE_FAST` or :const:`MODE_NORMAL`. - * ``nice_len``: What should be considered a "nice length" for a match. - This should be 273 or less. - * ``mf``: What match finder to use -- :const:`MF_HC3`, :const:`MF_HC4`, - :const:`MF_BT2`, :const:`MF_BT3`, or :const:`MF_BT4`. - * ``depth``: Maximum search depth used by match finder. 0 (default) means to - select automatically based on other filter options. +* ``preset``: A compression preset to use as a source of default values for + options that are not specified explicitly. +* ``dict_size``: Dictionary size in bytes. This should be between 4 KiB and + 1.5 GiB (inclusive). +* ``lc``: Number of literal context bits. +* ``lp``: Number of literal position bits. The sum ``lc + lp`` must be at + most 4. +* ``pb``: Number of position bits; must be at most 4. +* ``mode``: :const:`MODE_FAST` or :const:`MODE_NORMAL`. +* ``nice_len``: What should be considered a "nice length" for a match. + This should be 273 or less. +* ``mf``: What match finder to use -- :const:`MF_HC3`, :const:`MF_HC4`, + :const:`MF_BT2`, :const:`MF_BT3`, or :const:`MF_BT4`. +* ``depth``: Maximum search depth used by match finder. 0 (default) means to + select automatically based on other filter options. The delta filter stores the differences between bytes, producing more repetitive input for the compressor in certain circumstances. It supports one option, diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index 56908dedea1b40..91df07d914cae2 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -477,7 +477,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. + :c:func:`!flock` and :c:func:`!lockf` system calls. .. seealso:: @@ -588,7 +588,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. For MH mailboxes, locking + :c:func:`!flock` and :c:func:`!lockf` system calls. For MH mailboxes, locking the mailbox means locking the :file:`.mh_sequences` file and, only for the duration of any operations that affect them, locking individual message files. @@ -686,7 +686,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. + :c:func:`!flock` and :c:func:`!lockf` system calls. .. seealso:: @@ -737,7 +737,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. + :c:func:`!flock` and :c:func:`!lockf` system calls. .. seealso:: diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index 42fffee6a0f449..0b059e746c61af 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -10,8 +10,8 @@ -------------- These functions provide access to some useful capabilities on Windows platforms. -Some higher-level modules use these functions to build the Windows -implementations of their services. For example, the :mod:`getpass` module uses +Some higher-level modules use these functions to build the Windows +implementations of their services. For example, the :mod:`getpass` module uses this in the implementation of the :func:`getpass` function. Further documentation on these functions can be found in the Platform API @@ -35,11 +35,11 @@ File Operations .. function:: locking(fd, mode, nbytes) - Lock part of a file based on file descriptor *fd* from the C runtime. Raises - :exc:`OSError` on failure. The locked region of the file extends from the + Lock part of a file based on file descriptor *fd* from the C runtime. Raises + :exc:`OSError` on failure. The locked region of the file extends from the current file position for *nbytes* bytes, and may continue beyond the end of the - file. *mode* must be one of the :const:`LK_\*` constants listed below. Multiple - regions in a file may be locked at the same time, but may not overlap. Adjacent + file. *mode* must be one of the :const:`!LK_\*` constants listed below. Multiple + regions in a file may be locked at the same time, but may not overlap. Adjacent regions are not merged; they must be unlocked individually. .. audit-event:: msvcrt.locking fd,mode,nbytes msvcrt.locking @@ -49,7 +49,7 @@ File Operations LK_RLCK Locks the specified bytes. If the bytes cannot be locked, the program - immediately tries again after 1 second. If, after 10 attempts, the bytes cannot + immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, :exc:`OSError` is raised. @@ -74,9 +74,9 @@ File Operations .. function:: open_osfhandle(handle, flags) - Create a C runtime file descriptor from the file handle *handle*. The *flags* + Create a C runtime file descriptor from the file handle *handle*. The *flags* parameter should be a bitwise OR of :const:`os.O_APPEND`, :const:`os.O_RDONLY`, - and :const:`os.O_TEXT`. The returned file descriptor may be used as a parameter + and :const:`os.O_TEXT`. The returned file descriptor may be used as a parameter to :func:`os.fdopen` to create a file object. .. audit-event:: msvcrt.open_osfhandle handle,flags msvcrt.open_osfhandle @@ -84,7 +84,7 @@ File Operations .. function:: get_osfhandle(fd) - Return the file handle for the file descriptor *fd*. Raises :exc:`OSError` if + Return the file handle for the file descriptor *fd*. Raises :exc:`OSError` if *fd* is not recognized. .. audit-event:: msvcrt.get_osfhandle fd msvcrt.get_osfhandle @@ -98,13 +98,14 @@ Console I/O .. function:: kbhit() - Return ``True`` if a keypress is waiting to be read. + Returns a nonzero value if a keypress is waiting to be read. Otherwise, + return 0. .. function:: getch() Read a keypress and return the resulting character as a byte string. - Nothing is echoed to the console. This call will block if a keypress + Nothing is echoed to the console. This call will block if a keypress is not already available, but will not wait for :kbd:`Enter` to be pressed. If the pressed key was a special function key, this will return ``'\000'`` or ``'\xe0'``; the next call will return the keycode. @@ -118,7 +119,7 @@ Console I/O .. function:: getche() - Similar to :func:`getch`, but the keypress will be echoed if it represents a + Similar to :func:`getch`, but the keypress will be echoed if it represents a printable character. @@ -157,4 +158,93 @@ Other Functions .. function:: heapmin() Force the :c:func:`malloc` heap to clean itself up and return unused blocks to - the operating system. On failure, this raises :exc:`OSError`. + the operating system. On failure, this raises :exc:`OSError`. + + +.. function:: set_error_mode(mode) + + Changes the location where the C runtime writes an error message for an error + that might end the program. *mode* must be one of the :const:`!OUT_\*` + constants listed below or :const:`REPORT_ERRMODE`. Returns the old setting + or -1 if an error occurs. Only available in + :ref:`debug build of Python `. + + +.. data:: OUT_TO_DEFAULT + + Error sink is determined by the app's type. Only available in + :ref:`debug build of Python `. + + +.. data:: OUT_TO_STDERR + + Error sink is a standard error. Only available in + :ref:`debug build of Python `. + + +.. data:: OUT_TO_MSGBOX + + Error sink is a message box. Only available in + :ref:`debug build of Python `. + + +.. data:: REPORT_ERRMODE + + Report the current error mode value. Only available in + :ref:`debug build of Python `. + + +.. function:: CrtSetReportMode(type, mode) + + Specifies the destination or destinations for a specific report type + generated by :c:func:`!_CrtDbgReport` in the MS VC++ runtime. *type* must be + one of the :const:`!CRT_\*` constants listed below. *mode* must be one of the + :const:`!CRTDBG_\*` constants listed below. Only available in + :ref:`debug build of Python `. + + +.. function:: CrtSetReportFile(type, file) + + After you use :func:`CrtSetReportMode` to specify :const:`CRTDBG_MODE_FILE`, + you can specify the file handle to receive the message text. *type* must be + one of the :const:`!CRT_\*` constants listed below. *file* shuld be the file + handle your want specified. Only available in + :ref:`debug build of Python `. + + +.. data:: CRT_WARN + + Warnings, messages, and information that doesn't need immediate attention. + + +.. data:: CRT_ERROR + + Errors, unrecoverable problems, and issues that require immediate attention. + + +.. data:: CRT_ASSERT + + Assertion failures. + + +.. data:: CRTDBG_MODE_DEBUG + + Writes the message to the debugger's output window. + + +.. data:: CRTDBG_MODE_FILE + + Writes the message to a user-supplied file handle. :func:`CrtSetReportFile` + should be called to define the specific file or stream to use as + the destination. + + +.. data:: CRTDBG_MODE_WNDW + + Creates a message box to display the message along with the ``Abort``, + ``Retry``, and ``Ignore`` buttons. + + +.. data:: CRTDBG_REPORT_MODE + + Returns current *mode* for the specified *type*. diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 8454296b815b41..231038e6678dbc 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -131,6 +131,12 @@ to start a process. These *start methods* are Code that requires *fork* should explicitly specify that via :func:`get_context` or :func:`set_start_method`. + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple threads, the + :func:`os.fork` function that this start method calls internally will + raise a :exc:`DeprecationWarning`. Use a different start method. + See the :func:`os.fork` documentation for further explanation. + *forkserver* When the program starts and selects the *forkserver* start method, a server process is spawned. From then on, whenever a new process @@ -990,13 +996,20 @@ Miscellaneous This number is not equivalent to the number of CPUs the current process can use. The number of usable CPUs can be obtained with - ``len(os.sched_getaffinity(0))`` + :func:`os.process_cpu_count` (or ``len(os.sched_getaffinity(0))``). When the number of CPUs cannot be determined a :exc:`NotImplementedError` is raised. .. seealso:: :func:`os.cpu_count` + :func:`os.process_cpu_count` + + .. versionchanged:: 3.13 + + The return value can also be overridden using the + :option:`-X cpu_count <-X>` flag or :envvar:`PYTHON_CPU_COUNT` as this is + merely a wrapper around the :mod:`os` cpu count APIs. .. function:: current_process() @@ -2208,7 +2221,7 @@ with the :class:`Pool` class. callbacks and has a parallel map implementation. *processes* is the number of worker processes to use. If *processes* is - ``None`` then the number returned by :func:`os.cpu_count` is used. + ``None`` then the number returned by :func:`os.process_cpu_count` is used. If *initializer* is not ``None`` then each worker process will call ``initializer(*initargs)`` when it starts. @@ -2243,6 +2256,10 @@ with the :class:`Pool` class. .. versionadded:: 3.4 *context* + .. versionchanged:: 3.13 + *processes* uses :func:`os.process_cpu_count` by default, instead of + :func:`os.cpu_count`. + .. note:: Worker processes within a :class:`Pool` typically live for the complete @@ -2613,7 +2630,6 @@ server:: The following code uses :func:`~multiprocessing.connection.wait` to wait for messages from multiple processes at once:: - import time, random from multiprocessing import Process, Pipe, current_process from multiprocessing.connection import wait @@ -2707,7 +2723,7 @@ handler type) for messages from different processes to get mixed up. Returns the logger used by :mod:`multiprocessing`. If necessary, a new one will be created. - When first created the logger has level :data:`logging.NOTSET` and no + When first created the logger has level :const:`logging.NOTSET` and no default handler. Messages sent to this logger will not by default propagate to the root logger. @@ -2769,27 +2785,27 @@ worker threads rather than worker processes. :meth:`~multiprocessing.pool.Pool.terminate` manually. *processes* is the number of worker threads to use. If *processes* is - ``None`` then the number returned by :func:`os.cpu_count` is used. + ``None`` then the number returned by :func:`os.process_cpu_count` is used. If *initializer* is not ``None`` then each worker process will call ``initializer(*initargs)`` when it starts. Unlike :class:`Pool`, *maxtasksperchild* and *context* cannot be provided. - .. note:: + .. note:: - A :class:`ThreadPool` shares the same interface as :class:`Pool`, which - is designed around a pool of processes and predates the introduction of - the :class:`concurrent.futures` module. As such, it inherits some - operations that don't make sense for a pool backed by threads, and it - has its own type for representing the status of asynchronous jobs, - :class:`AsyncResult`, that is not understood by any other libraries. + A :class:`ThreadPool` shares the same interface as :class:`Pool`, which + is designed around a pool of processes and predates the introduction of + the :class:`concurrent.futures` module. As such, it inherits some + operations that don't make sense for a pool backed by threads, and it + has its own type for representing the status of asynchronous jobs, + :class:`AsyncResult`, that is not understood by any other libraries. - Users should generally prefer to use - :class:`concurrent.futures.ThreadPoolExecutor`, which has a simpler - interface that was designed around threads from the start, and which - returns :class:`concurrent.futures.Future` instances that are - compatible with many other libraries, including :mod:`asyncio`. + Users should generally prefer to use + :class:`concurrent.futures.ThreadPoolExecutor`, which has a simpler + interface that was designed around threads from the start, and which + returns :class:`concurrent.futures.Future` instances that are + compatible with many other libraries, including :mod:`asyncio`. .. _multiprocessing-programming: @@ -2988,7 +3004,7 @@ Global variables Safe importing of main module Make sure that the main module can be safely imported by a new Python - interpreter without causing unintended side effects (such a starting a new + interpreter without causing unintended side effects (such as starting a new process). For example, using the *spawn* or *forkserver* start method diff --git a/Doc/library/multiprocessing.shared_memory.rst b/Doc/library/multiprocessing.shared_memory.rst index 76046b34610abe..f453e6403d932d 100644 --- a/Doc/library/multiprocessing.shared_memory.rst +++ b/Doc/library/multiprocessing.shared_memory.rst @@ -255,16 +255,17 @@ shared memory blocks created using that manager are all released when the :keyword:`with` statement's code block finishes execution. -.. class:: ShareableList(sequence=None, *, name=None) +.. class:: ShareableList(sequence=None, \*, name=None) Provides a mutable list-like object where all values stored within are stored in a shared memory block. This constrains storable values to - only the ``int``, ``float``, ``bool``, ``str`` (less than 10M bytes each), - ``bytes`` (less than 10M bytes each), and ``None`` built-in data types. - It also notably differs from the built-in ``list`` type in that these - lists can not change their overall length (i.e. no append, insert, etc.) - and do not support the dynamic creation of new :class:`ShareableList` - instances via slicing. + only the ``int`` (signed 64-bit), ``float``, ``bool``, ``str`` (less + than 10M bytes each when encoded as utf-8), ``bytes`` (less than 10M + bytes each), and ``None`` built-in data types. It also notably + differs from the built-in ``list`` type in that these lists can not + change their overall length (i.e. no append, insert, etc.) and do not + support the dynamic creation of new :class:`ShareableList` instances + via slicing. *sequence* is used in populating a new ``ShareableList`` full of values. Set to ``None`` to instead attach to an already existing @@ -275,6 +276,35 @@ shared memory blocks created using that manager are all released when the existing ``ShareableList``, specify its shared memory block's unique name while leaving ``sequence`` set to ``None``. + .. note:: + + A known issue exists for :class:`bytes` and :class:`str` values. + If they end with ``\x00`` nul bytes or characters, those may be + *silently stripped* when fetching them by index from the + :class:`ShareableList`. This ``.rstrip(b'\x00')`` behavior is + considered a bug and may go away in the future. See :gh:`106939`. + + For applications where rstripping of trailing nulls is a problem, + work around it by always unconditionally appending an extra non-0 + byte to the end of such values when storing and unconditionally + removing it when fetching: + + .. doctest:: + + >>> from multiprocessing import shared_memory + >>> nul_bug_demo = shared_memory.ShareableList(['?\x00', b'\x03\x02\x01\x00\x00\x00']) + >>> nul_bug_demo[0] + '?' + >>> nul_bug_demo[1] + b'\x03\x02\x01' + >>> nul_bug_demo.shm.unlink() + >>> padded = shared_memory.ShareableList(['?\x00\x07', b'\x03\x02\x01\x00\x00\x00\x07']) + >>> padded[0][:-1] + '?\x00' + >>> padded[1][:-1] + b'\x03\x02\x01\x00\x00\x00' + >>> padded.shm.unlink() + .. method:: count(value) Returns the number of occurrences of ``value``. diff --git a/Doc/library/netrc.rst b/Doc/library/netrc.rst index 88265d9b9e9e93..c36e5cfecfc6a8 100644 --- a/Doc/library/netrc.rst +++ b/Doc/library/netrc.rst @@ -51,9 +51,19 @@ the Unix :program:`ftp` program and other FTP clients. Exception raised by the :class:`~netrc.netrc` class when syntactical errors are encountered in source text. Instances of this exception provide three - interesting attributes: :attr:`msg` is a textual explanation of the error, - :attr:`filename` is the name of the source file, and :attr:`lineno` gives the - line number on which the error was found. + interesting attributes: + + .. attribute:: msg + + Textual explanation of the error. + + .. attribute:: filename + + The name of the source file. + + .. attribute:: lineno + + The line number on which the error was found. .. _netrc-objects: diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst index b3dce151aee289..2a05b56db051f9 100644 --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -160,23 +160,23 @@ refer to ``MyIntegral`` and ``OtherTypeIKnowAbout`` as of :class:`Complex` (``a : A <: Complex``), and ``b : B <: Complex``. I'll consider ``a + b``: - 1. If ``A`` defines an :meth:`__add__` which accepts ``b``, all is - well. - 2. If ``A`` falls back to the boilerplate code, and it were to - return a value from :meth:`__add__`, we'd miss the possibility - that ``B`` defines a more intelligent :meth:`__radd__`, so the - boilerplate should return :const:`NotImplemented` from - :meth:`__add__`. (Or ``A`` may not implement :meth:`__add__` at - all.) - 3. Then ``B``'s :meth:`__radd__` gets a chance. If it accepts - ``a``, all is well. - 4. If it falls back to the boilerplate, there are no more possible - methods to try, so this is where the default implementation - should live. - 5. If ``B <: A``, Python tries ``B.__radd__`` before - ``A.__add__``. This is ok, because it was implemented with - knowledge of ``A``, so it can handle those instances before - delegating to :class:`Complex`. +1. If ``A`` defines an :meth:`__add__` which accepts ``b``, all is + well. +2. If ``A`` falls back to the boilerplate code, and it were to + return a value from :meth:`__add__`, we'd miss the possibility + that ``B`` defines a more intelligent :meth:`__radd__`, so the + boilerplate should return :const:`NotImplemented` from + :meth:`__add__`. (Or ``A`` may not implement :meth:`__add__` at + all.) +3. Then ``B``'s :meth:`__radd__` gets a chance. If it accepts + ``a``, all is well. +4. If it falls back to the boilerplate, there are no more possible + methods to try, so this is where the default implementation + should live. +5. If ``B <: A``, Python tries ``B.__radd__`` before + ``A.__add__``. This is ok, because it was implemented with + knowledge of ``A``, so it can handle those instances before + delegating to :class:`Complex`. If ``A <: Complex`` and ``B <: Real`` without sharing any other knowledge, then the appropriate shared operation is the one involving the built diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index dab4de9eb6abb7..57c67bcf3aa12e 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -59,9 +59,9 @@ truth tests, identity tests, and boolean operations: __not__(obj) Return the outcome of :keyword:`not` *obj*. (Note that there is no - :meth:`__not__` method for object instances; only the interpreter core defines - this operation. The result is affected by the :meth:`__bool__` and - :meth:`__len__` methods.) + :meth:`!__not__` method for object instances; only the interpreter core defines + this operation. The result is affected by the :meth:`~object.__bool__` and + :meth:`~object.__len__` methods.) .. function:: truth(obj) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 01177a04ab434d..015e83ed2ce5f7 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -813,7 +813,7 @@ The first step in using :mod:`optparse` is to create an OptionParser instance. help option. When :mod:`optparse` prints the usage string, it expands ``%prog`` to ``os.path.basename(sys.argv[0])`` (or to ``prog`` if you passed that keyword argument). To suppress a usage message, pass the - special value :data:`optparse.SUPPRESS_USAGE`. + special value :const:`optparse.SUPPRESS_USAGE`. ``option_list`` (default: ``[]``) A list of Option objects to populate the parser with. The options in @@ -1079,7 +1079,7 @@ relevant to a particular option, or fail to pass a required option attribute, Help text to print for this option when listing all available options after the user supplies a :attr:`~Option.help` option (such as ``--help``). If no help text is supplied, the option will be listed without help text. To - hide this option, use the special value :data:`optparse.SUPPRESS_HELP`. + hide this option, use the special value :const:`optparse.SUPPRESS_HELP`. .. attribute:: Option.metavar @@ -1251,7 +1251,7 @@ must specify for any option using that action. If no :attr:`~Option.help` string is supplied for an option, it will still be listed in the help message. To omit an option entirely, use the special value - :data:`optparse.SUPPRESS_HELP`. + :const:`optparse.SUPPRESS_HELP`. :mod:`optparse` automatically adds a :attr:`~Option.help` option to all OptionParsers, so you do not normally need to create one. @@ -1522,7 +1522,7 @@ OptionParser supports several other public methods: Set the usage string according to the rules described above for the ``usage`` constructor keyword argument. Passing ``None`` sets the default usage - string; use :data:`optparse.SUPPRESS_USAGE` to suppress a usage message. + string; use :const:`optparse.SUPPRESS_USAGE` to suppress a usage message. .. method:: OptionParser.print_usage(file=None) diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 3a668e28f2e268..95933f56d50542 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -377,7 +377,8 @@ the :mod:`glob` module.) Return the canonical path of the specified filename, eliminating any symbolic links encountered in the path (if they are supported by the operating - system). + system). On Windows, this function will also resolve MS-DOS (also called 8.3) + style names such as ``C:\\PROGRA~1`` to ``C:\\Program Files``. If a path doesn't exist or a symlink loop is encountered, and *strict* is ``True``, :exc:`OSError` is raised. If *strict* is ``False``, the path is @@ -410,7 +411,7 @@ the :mod:`glob` module.) *start*. On Windows, :exc:`ValueError` is raised when *path* and *start* are on different drives. - *start* defaults to :attr:`os.curdir`. + *start* defaults to :data:`os.curdir`. .. availability:: Unix, Windows. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 83abb5d5ca1e42..fe573f188ab066 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -60,7 +60,7 @@ Notes on the availability of these functions: ``'java'``. .. seealso:: - :attr:`sys.platform` has a finer granularity. :func:`os.uname` gives + :data:`sys.platform` has a finer granularity. :func:`os.uname` gives system-dependent version information. The :mod:`platform` module provides detailed checks for the @@ -88,8 +88,8 @@ startup by the :c:func:`PyConfig_Read` function: see On some systems, conversion using the file system encoding may fail. In this case, Python uses the :ref:`surrogateescape encoding error handler `, which means that undecodable bytes are replaced by a - Unicode character U+DCxx on decoding, and these are again translated to the - original byte on encoding. + Unicode character U+DC\ *xx* on decoding, and these are again + translated to the original byte on encoding. The :term:`file system encoding ` must @@ -215,7 +215,7 @@ process and user. On some platforms, including FreeBSD and macOS, setting ``environ`` may cause memory leaks. Refer to the system documentation for - :c:func:`putenv`. + :c:func:`!putenv`. You can delete items in this mapping to unset environment variables. :func:`unsetenv` will be called automatically when an item is deleted from @@ -233,7 +233,7 @@ process and user. :data:`environ` and :data:`environb` are synchronized (modifying :data:`environb` updates :data:`environ`, and vice versa). - :data:`environb` is only available if :data:`supports_bytes_environ` is + :data:`environb` is only available if :const:`supports_bytes_environ` is ``True``. .. versionadded:: 3.2 @@ -331,7 +331,7 @@ process and user. future environment changes. - :func:`getenvb` is only available if :data:`supports_bytes_environ` + :func:`getenvb` is only available if :const:`supports_bytes_environ` is ``True``. .. availability:: Unix. @@ -401,11 +401,11 @@ process and user. On macOS, :func:`getgroups` behavior differs somewhat from other Unix platforms. If the Python interpreter was built with a - deployment target of :const:`10.5` or earlier, :func:`getgroups` returns + deployment target of ``10.5`` or earlier, :func:`getgroups` returns the list of effective group ids associated with the current user process; this list is limited to a system-defined number of entries, typically 16, and may be modified by calls to :func:`setgroups` if suitably privileged. - If built with a deployment target greater than :const:`10.5`, + If built with a deployment target greater than ``10.5``, :func:`getgroups` returns the current group access list for the user associated with the effective user id of the process; the group access list may change over the lifetime of the process, it is not affected by @@ -564,7 +564,7 @@ process and user. .. note:: On some platforms, including FreeBSD and macOS, setting ``environ`` may - cause memory leaks. Refer to the system documentation for :c:func:`putenv`. + cause memory leaks. Refer to the system documentation for :c:func:`!putenv`. .. audit-event:: os.putenv key,value os.putenv @@ -646,7 +646,7 @@ process and user. .. function:: setpgrp() - Call the system call :c:func:`setpgrp` or ``setpgrp(0, 0)`` depending on + Call the system call :c:func:`!setpgrp` or ``setpgrp(0, 0)`` depending on which version is implemented (if any). See the Unix manual for the semantics. .. availability:: Unix, not Emscripten, not WASI. @@ -654,7 +654,7 @@ process and user. .. function:: setpgid(pid, pgrp, /) - Call the system call :c:func:`setpgid` to set the process group id of the + Call the system call :c:func:`!setpgid` to set the process group id of the process with id *pid* to the process group with id *pgrp*. See the Unix manual for the semantics. @@ -714,14 +714,14 @@ process and user. .. function:: getsid(pid, /) - Call the system call :c:func:`getsid`. See the Unix manual for the semantics. + Call the system call :c:func:`!getsid`. See the Unix manual for the semantics. .. availability:: Unix, not Emscripten, not WASI. .. function:: setsid() - Call the system call :c:func:`setsid`. See the Unix manual for the semantics. + Call the system call :c:func:`!setsid`. See the Unix manual for the semantics. .. availability:: Unix, not Emscripten, not WASI. @@ -739,7 +739,7 @@ process and user. .. function:: strerror(code, /) Return the error message corresponding to the error code in *code*. - On platforms where :c:func:`strerror` returns ``NULL`` when given an unknown + On platforms where :c:func:`!strerror` returns ``NULL`` when given an unknown error number, :exc:`ValueError` is raised. @@ -923,7 +923,7 @@ as internal buffering of data. In Linux kernel older than 5.3, the files pointed by *src* and *dst* must reside in the same filesystem, otherwise an :exc:`OSError` is - raised with :attr:`~OSError.errno` set to :data:`errno.EXDEV`. + raised with :attr:`~OSError.errno` set to :const:`errno.EXDEV`. This copy is done without the additional cost of transferring data from the kernel to user space and then back into the kernel. Additionally, @@ -1077,7 +1077,7 @@ as internal buffering of data. .. function:: fsync(fd) Force write of file with filedescriptor *fd* to disk. On Unix, this calls the - native :c:func:`fsync` function; on Windows, the MS :c:func:`_commit` function. + native :c:func:`!fsync` function; on Windows, the MS :c:func:`!_commit` function. If you're starting with a buffered Python :term:`file object` *f*, first do ``f.flush()``, and then do ``os.fsync(f.fileno())``, to ensure that all internal @@ -1163,25 +1163,65 @@ as internal buffering of data. .. versionadded:: 3.11 -.. function:: lseek(fd, pos, how, /) +.. function:: lseek(fd, pos, whence, /) Set the current position of file descriptor *fd* to position *pos*, modified - by *how*: :const:`SEEK_SET` or ``0`` to set the position relative to the - beginning of the file; :const:`SEEK_CUR` or ``1`` to set it relative to the - current position; :const:`SEEK_END` or ``2`` to set it relative to the end of - the file. Return the new cursor position in bytes, starting from the beginning. + by *whence*, and return the new position in bytes relative to + the start of the file. + Valid values for *whence* are: + + * :const:`SEEK_SET` or ``0`` -- set *pos* relative to the beginning of the file + * :const:`SEEK_CUR` or ``1`` -- set *pos* relative to the current file position + * :const:`SEEK_END` or ``2`` -- set *pos* relative to the end of the file + * :const:`SEEK_HOLE` -- set *pos* to the next data location, relative to *pos* + * :const:`SEEK_DATA` -- set *pos* to the next data hole, relative to *pos* + + .. versionchanged:: 3.3 + + Add support for :const:`!SEEK_HOLE` and :const:`!SEEK_DATA`. .. data:: SEEK_SET SEEK_CUR SEEK_END - Parameters to the :func:`lseek` function. Their values are 0, 1, and 2, - respectively. + Parameters to the :func:`lseek` function and the :meth:`~io.IOBase.seek` + method on :term:`file-like objects `, + for whence to adjust the file position indicator. + + :const:`SEEK_SET` + Adjust the file position relative to the beginning of the file. + :const:`SEEK_CUR` + Adjust the file position relative to the current file position. + :const:`SEEK_END` + Adjust the file position relative to the end of the file. + + Their values are 0, 1, and 2, respectively. + + +.. data:: SEEK_HOLE + SEEK_DATA + + Parameters to the :func:`lseek` function and the :meth:`~io.IOBase.seek` + method on :term:`file-like objects `, + for seeking file data and holes on sparsely allocated files. + + :data:`!SEEK_DATA` + Adjust the file offset to the next location containing data, + relative to the seek position. + + :data:`!SEEK_HOLE` + Adjust the file offset to the next location containing a hole, + relative to the seek position. + A hole is defined as a sequence of zeros. + + .. note:: + + These operations only make sense for filesystems that support them. + + .. availability:: Linux >= 3.1, macOS, Unix .. versionadded:: 3.3 - Some operating systems could support additional values, like - :data:`os.SEEK_HOLE` or :data:`os.SEEK_DATA`. .. function:: open(path, flags, mode=0o777, *, dir_fd=None) @@ -1422,7 +1462,7 @@ or `the MSDN `_ on Windo If some data was successfully read, it will return the number of bytes read. If no bytes were read, it will return ``-1`` and set errno to - :data:`errno.EAGAIN`. + :const:`errno.EAGAIN`. .. availability:: Linux >= 4.14. @@ -1578,25 +1618,6 @@ or `the MSDN `_ on Windo Parameters *out* and *in* was renamed to *out_fd* and *in_fd*. -.. function:: set_blocking(fd, blocking, /) - - Set the blocking mode of the specified file descriptor. Set the - :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. - - See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. - - .. availability:: Unix, Windows. - - The function is limited on Emscripten and WASI, see - :ref:`wasm-availability` for more information. - - On Windows, this function is limited to pipes. - - .. versionadded:: 3.5 - - .. versionchanged:: 3.12 - Added support for pipes on Windows. - .. data:: SF_NODISKIO SF_MNOWAIT SF_SYNC @@ -1618,6 +1639,26 @@ or `the MSDN `_ on Windo .. versionadded:: 3.11 +.. function:: set_blocking(fd, blocking, /) + + Set the blocking mode of the specified file descriptor. Set the + :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. + + See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. + + .. availability:: Unix, Windows. + + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + + On Windows, this function is limited to pipes. + + .. versionadded:: 3.5 + + .. versionchanged:: 3.12 + Added support for pipes on Windows. + + .. function:: splice(src, dst, count, offset_src=None, offset_dst=None) Transfer *count* bytes from file descriptor *src*, starting from offset @@ -1627,7 +1668,7 @@ or `the MSDN `_ on Windo *offset_dst*. The offset associated to the file descriptor that refers to a pipe must be ``None``. The files pointed by *src* and *dst* must reside in the same filesystem, otherwise an :exc:`OSError` is raised with - :attr:`~OSError.errno` set to :data:`errno.EXDEV`. + :attr:`~OSError.errno` set to :const:`errno.EXDEV`. This copy is done without the additional cost of transferring data from the kernel to user space and then back into the kernel. Additionally, @@ -1960,18 +2001,18 @@ features: Set the flags of *path* to the numeric *flags*. *flags* may take a combination (bitwise OR) of the following values (as defined in the :mod:`stat` module): - * :data:`stat.UF_NODUMP` - * :data:`stat.UF_IMMUTABLE` - * :data:`stat.UF_APPEND` - * :data:`stat.UF_OPAQUE` - * :data:`stat.UF_NOUNLINK` - * :data:`stat.UF_COMPRESSED` - * :data:`stat.UF_HIDDEN` - * :data:`stat.SF_ARCHIVED` - * :data:`stat.SF_IMMUTABLE` - * :data:`stat.SF_APPEND` - * :data:`stat.SF_NOUNLINK` - * :data:`stat.SF_SNAPSHOT` + * :const:`stat.UF_NODUMP` + * :const:`stat.UF_IMMUTABLE` + * :const:`stat.UF_APPEND` + * :const:`stat.UF_OPAQUE` + * :const:`stat.UF_NOUNLINK` + * :const:`stat.UF_COMPRESSED` + * :const:`stat.UF_HIDDEN` + * :const:`stat.SF_ARCHIVED` + * :const:`stat.SF_IMMUTABLE` + * :const:`stat.SF_APPEND` + * :const:`stat.SF_NOUNLINK` + * :const:`stat.SF_SNAPSHOT` This function can support :ref:`not following symlinks `. @@ -1992,25 +2033,25 @@ features: following values (as defined in the :mod:`stat` module) or bitwise ORed combinations of them: - * :data:`stat.S_ISUID` - * :data:`stat.S_ISGID` - * :data:`stat.S_ENFMT` - * :data:`stat.S_ISVTX` - * :data:`stat.S_IREAD` - * :data:`stat.S_IWRITE` - * :data:`stat.S_IEXEC` - * :data:`stat.S_IRWXU` - * :data:`stat.S_IRUSR` - * :data:`stat.S_IWUSR` - * :data:`stat.S_IXUSR` - * :data:`stat.S_IRWXG` - * :data:`stat.S_IRGRP` - * :data:`stat.S_IWGRP` - * :data:`stat.S_IXGRP` - * :data:`stat.S_IRWXO` - * :data:`stat.S_IROTH` - * :data:`stat.S_IWOTH` - * :data:`stat.S_IXOTH` + * :const:`stat.S_ISUID` + * :const:`stat.S_ISGID` + * :const:`stat.S_ENFMT` + * :const:`stat.S_ISVTX` + * :const:`stat.S_IREAD` + * :const:`stat.S_IWRITE` + * :const:`stat.S_IEXEC` + * :const:`stat.S_IRWXU` + * :const:`stat.S_IRUSR` + * :const:`stat.S_IWUSR` + * :const:`stat.S_IXUSR` + * :const:`stat.S_IRWXG` + * :const:`stat.S_IRGRP` + * :const:`stat.S_IWGRP` + * :const:`stat.S_IXGRP` + * :const:`stat.S_IRWXO` + * :const:`stat.S_IROTH` + * :const:`stat.S_IWOTH` + * :const:`stat.S_IXOTH` This function can support :ref:`specifying a file descriptor `, :ref:`paths relative to directory descriptors ` and :ref:`not @@ -2150,7 +2191,7 @@ features: .. audit-event:: os.link src,dst,src_dir_fd,dst_dir_fd os.link - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten. .. versionchanged:: 3.2 Added Windows support. @@ -2264,7 +2305,7 @@ features: .. function:: lstat(path, *, dir_fd=None) - Perform the equivalent of an :c:func:`lstat` system call on the given path. + Perform the equivalent of an :c:func:`!lstat` system call on the given path. Similar to :func:`~os.stat`, but does not follow symbolic links. Return a :class:`stat_result` object. @@ -2420,13 +2461,13 @@ features: .. function:: major(device, /) Extract the device major number from a raw device number (usually the - :attr:`st_dev` or :attr:`st_rdev` field from :c:type:`stat`). + :attr:`st_dev` or :attr:`st_rdev` field from :c:struct:`stat`). .. function:: minor(device, /) Extract the device minor number from a raw device number (usually the - :attr:`st_dev` or :attr:`st_rdev` field from :c:type:`stat`). + :attr:`st_dev` or :attr:`st_rdev` field from :c:struct:`stat`). .. function:: makedev(major, minor, /) @@ -2937,7 +2978,7 @@ features: .. class:: stat_result Object whose attributes correspond roughly to the members of the - :c:type:`stat` structure. It is used for the result of :func:`os.stat`, + :c:struct:`stat` structure. It is used for the result of :func:`os.stat`, :func:`os.fstat` and :func:`os.lstat`. Attributes: @@ -3107,22 +3148,24 @@ features: Windows file attributes: ``dwFileAttributes`` member of the ``BY_HANDLE_FILE_INFORMATION`` structure returned by - :c:func:`GetFileInformationByHandle`. See the ``FILE_ATTRIBUTE_*`` + :c:func:`!GetFileInformationByHandle`. + See the :const:`!FILE_ATTRIBUTE_* ` constants in the :mod:`stat` module. .. attribute:: st_reparse_tag - When :attr:`st_file_attributes` has the ``FILE_ATTRIBUTE_REPARSE_POINT`` + When :attr:`st_file_attributes` has the :const:`~stat.FILE_ATTRIBUTE_REPARSE_POINT` set, this field contains the tag identifying the type of reparse point. - See the ``IO_REPARSE_TAG_*`` constants in the :mod:`stat` module. + See the :const:`IO_REPARSE_TAG_* ` + constants in the :mod:`stat` module. The standard module :mod:`stat` defines functions and constants that are - useful for extracting information from a :c:type:`stat` structure. (On + useful for extracting information from a :c:struct:`stat` structure. (On Windows, some items are filled with dummy values.) For backward compatibility, a :class:`stat_result` instance is also accessible as a tuple of at least 10 integers giving the most important (and - portable) members of the :c:type:`stat` structure, in the order + portable) members of the :c:struct:`stat` structure, in the order :attr:`st_mode`, :attr:`st_ino`, :attr:`st_dev`, :attr:`st_nlink`, :attr:`st_uid`, :attr:`st_gid`, :attr:`st_size`, :attr:`st_atime`, :attr:`st_mtime`, :attr:`st_ctime`. More items may be added at the end by @@ -3172,9 +3215,9 @@ features: .. function:: statvfs(path) - Perform a :c:func:`statvfs` system call on the given path. The return value is + Perform a :c:func:`!statvfs` system call on the given path. The return value is an object whose attributes describe the filesystem on the given path, and - correspond to the members of the :c:type:`statvfs` structure, namely: + correspond to the members of the :c:struct:`statvfs` structure, namely: :attr:`f_bsize`, :attr:`f_frsize`, :attr:`f_blocks`, :attr:`f_bfree`, :attr:`f_bavail`, :attr:`f_files`, :attr:`f_ffree`, :attr:`f_favail`, :attr:`f_flag`, :attr:`f_namemax`, :attr:`f_fsid`. @@ -3738,6 +3781,217 @@ features: .. versionadded:: 3.10 +Timer File Descriptors +~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 3.13 + +These functions provide support for Linux's *timer file descriptor* API. +Naturally, they are all only available on Linux. + +.. function:: timerfd_create(clockid, /, *, flags=0) + + Create and return a timer file descriptor (*timerfd*). + + The file descriptor returned by :func:`timerfd_create` supports: + + - :func:`read` + - :func:`~select.select` + - :func:`~select.poll` + + The file descriptor's :func:`read` method can be called with a buffer size + of 8. If the timer has already expired one or more times, :func:`read` + returns the number of expirations with the host's endianness, which may be + converted to an :class:`int` by ``int.from_bytes(x, byteorder=sys.byteorder)``. + + :func:`~select.select` and :func:`~select.poll` can be used to wait until + timer expires and the file descriptor is readable. + + *clockid* must be a valid :ref:`clock ID `, + as defined in the :py:mod:`time` module: + + - :const:`time.CLOCK_REALTIME` + - :const:`time.CLOCK_MONOTONIC` + - :const:`time.CLOCK_BOOTTIME` (Since Linux 3.15 for timerfd_create) + + If *clockid* is :const:`time.CLOCK_REALTIME`, a settable system-wide + real-time clock is used. If system clock is changed, timer setting need + to be updated. To cancel timer when system clock is changed, see + :const:`TFD_TIMER_CANCEL_ON_SET`. + + If *clockid* is :const:`time.CLOCK_MONOTONIC`, a non-settable monotonically + increasing clock is used. Even if the system clock is changed, the timer + setting will not be affected. + + If *clockid* is :const:`time.CLOCK_BOOTTIME`, same as :const:`time.CLOCK_MONOTONIC` + except it includes any time that the system is suspended. + + The file descriptor's behaviour can be modified by specifying a *flags* value. + Any of the following variables may used, combined using bitwise OR + (the ``|`` operator): + + - :const:`TFD_NONBLOCK` + - :const:`TFD_CLOEXEC` + + If :const:`TFD_NONBLOCK` is not set as a flag, :func:`read` blocks until + the timer expires. If it is set as a flag, :func:`read` doesn't block, but + If there hasn't been an expiration since the last call to read, + :func:`read` raises :class:`OSError` with ``errno`` is set to + :const:`errno.EAGAIN`. + + :const:`TFD_CLOEXEC` is always set by Python automatically. + + The file descriptor must be closed with :func:`os.close` when it is no + longer needed, or else the file descriptor will be leaked. + + .. seealso:: The :manpage:`timerfd_create(2)` man page. + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + + +.. function:: timerfd_settime(fd, /, *, flags=flags, initial=0.0, interval=0.0) + + Alter a timer file descriptor's internal timer. + This function operates the same interval timer as :func:`timerfd_settime_ns`. + + *fd* must be a valid timer file descriptor. + + The timer's behaviour can be modified by specifying a *flags* value. + Any of the following variables may used, combined using bitwise OR + (the ``|`` operator): + + - :const:`TFD_TIMER_ABSTIME` + - :const:`TFD_TIMER_CANCEL_ON_SET` + + The timer is disabled by setting *initial* to zero (``0``). + If *initial* is equal to or greater than zero, the timer is enabled. + If *initial* is less than zero, it raises an :class:`OSError` exception + with ``errno`` set to :const:`errno.EINVAL` + + By default the timer will fire when *initial* seconds have elapsed. + (If *initial* is zero, timer will fire immediately.) + + However, if the :const:`TFD_TIMER_ABSTIME` flag is set, + the timer will fire when the timer's clock + (set by *clockid* in :func:`timerfd_create`) reaches *initial* seconds. + + The timer's interval is set by the *interval* :py:class:`float`. + If *interval* is zero, the timer only fires once, on the initial expiration. + If *interval* is greater than zero, the timer fires every time *interval* + seconds have elapsed since the previous expiration. + If *interval* is less than zero, it raises :class:`OSError` with ``errno`` + set to :const:`errno.EINVAL` + + If the :const:`TFD_TIMER_CANCEL_ON_SET` flag is set along with + :const:`TFD_TIMER_ABSTIME` and the clock for this timer is + :const:`time.CLOCK_REALTIME`, the timer is marked as cancelable if the + real-time clock is changed discontinuously. Reading the descriptor is + aborted with the error ECANCELED. + + Linux manages system clock as UTC. A daylight-savings time transition is + done by changing time offset only and doesn't cause discontinuous system + clock change. + + Discontinuous system clock change will be caused by the following events: + + - ``settimeofday`` + - ``clock_settime`` + - set the system date and time by ``date`` command + + Return a two-item tuple of (``next_expiration``, ``interval``) from + the previous timer state, before this function executed. + + .. seealso:: + + :manpage:`timerfd_create(2)`, :manpage:`timerfd_settime(2)`, + :manpage:`settimeofday(2)`, :manpage:`clock_settime(2)`, + and :manpage:`date(1)`. + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + + +.. function:: timerfd_settime_ns(fd, /, *, flags=0, initial=0, interval=0) + + Similar to :func:`timerfd_settime`, but use time as nanoseconds. + This function operates the same interval timer as :func:`timerfd_settime`. + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + + +.. function:: timerfd_gettime(fd, /) + + Return a two-item tuple of floats (``next_expiration``, ``interval``). + + ``next_expiration`` denotes the relative time until next the timer next fires, + regardless of if the :const:`TFD_TIMER_ABSTIME` flag is set. + + ``interval`` denotes the timer's interval. + If zero, the timer will only fire once, after ``next_expiration`` seconds + have elapsed. + + .. seealso:: :manpage:`timerfd_gettime(2)` + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + + +.. function:: timerfd_gettime_ns(fd, /) + + Similar to :func:`timerfd_gettime`, but return time as nanoseconds. + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + +.. data:: TFD_NONBLOCK + + A flag for the :func:`timerfd_create` function, + which sets the :const:`O_NONBLOCK` status flag for the new timer file + descriptor. If :const:`TFD_NONBLOCK` is not set as a flag, :func:`read` blocks. + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + +.. data:: TFD_CLOEXEC + + A flag for the :func:`timerfd_create` function, + If :const:`TFD_CLOEXEC` is set as a flag, set close-on-exec flag for new file + descriptor. + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + +.. data:: TFD_TIMER_ABSTIME + + A flag for the :func:`timerfd_settime` and :func:`timerfd_settime_ns` functions. + If this flag is set, *initial* is interpreted as an absolute value on the + timer's clock (in UTC seconds or nanoseconds since the Unix Epoch). + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + +.. data:: TFD_TIMER_CANCEL_ON_SET + + A flag for the :func:`timerfd_settime` and :func:`timerfd_settime_ns` + functions along with :const:`TFD_TIMER_ABSTIME`. + The timer is cancelled when the time of the underlying clock changes + discontinuously. + + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 + + .. versionadded:: 3.13 + + Linux extended attributes ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -4114,15 +4368,38 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.fork "" os.fork + .. warning:: + + If you use TLS sockets in an application calling ``fork()``, see + the warning in the :mod:`ssl` documentation. + .. versionchanged:: 3.8 Calling ``fork()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - .. warning:: - - See :mod:`ssl` for applications that use the SSL module with fork(). + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple + threads, :func:`os.fork` now raises a :exc:`DeprecationWarning`. + + We chose to surface this as a warning, when detectable, to better + inform developers of a design problem that the POSIX platform + specifically notes as not supported. Even in code that + *appears* to work, it has never been safe to mix threading with + :func:`os.fork` on POSIX platforms. The CPython runtime itself has + always made API calls that are not safe for use in the child + process when threads existed in the parent (such as ``malloc`` and + ``free``). + + Users of macOS or users of libc or malloc implementations other + than those typically found in glibc to date are among those + already more likely to experience deadlocks running such code. + + See `this discussion on fork being incompatible with threads + `_ + for technical details of why we're surfacing this longstanding + platform compatibility problem to developers. - .. availability:: Unix, not Emscripten, not WASI. + .. availability:: POSIX, not Emscripten, not WASI. .. function:: forkpty() @@ -4135,6 +4412,11 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.forkpty "" os.forkpty + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple + threads, this now raises a :exc:`DeprecationWarning`. See the + longer explanation on :func:`os.fork`. + .. versionchanged:: 3.8 Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -4151,8 +4433,8 @@ written in Python, such as a mail server's external command delivery program. Send signal *sig* to the process *pid*. Constants for the specific signals available on the host platform are defined in the :mod:`signal` module. - Windows: The :data:`signal.CTRL_C_EVENT` and - :data:`signal.CTRL_BREAK_EVENT` signals are special signals which can + Windows: The :const:`signal.CTRL_C_EVENT` and + :const:`signal.CTRL_BREAK_EVENT` signals are special signals which can only be sent to console processes which share a common console window, e.g., some subprocesses. Any other value for *sig* will cause the process to be unconditionally killed by the TerminateProcess API, and the exit code @@ -4205,7 +4487,7 @@ written in Python, such as a mail server's external command delivery program. This flag indicates that the file descriptor will be non-blocking. If the process referred to by the file descriptor has not yet terminated, then an attempt to wait on the file descriptor using :manpage:`waitid(2)` - will immediately return the error :data:`~errno.EAGAIN` rather than blocking. + will immediately return the error :const:`~errno.EAGAIN` rather than blocking. .. availability:: Linux >= 5.10 .. versionadded:: 3.12 @@ -4263,7 +4545,7 @@ written in Python, such as a mail server's external command delivery program. setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ setsigdef=(), scheduler=None) - Wraps the :c:func:`posix_spawn` C library API for use from Python. + Wraps the :c:func:`!posix_spawn` C library API for use from Python. Most users should use :func:`subprocess.run` instead of :func:`posix_spawn`. @@ -4299,16 +4581,16 @@ written in Python, such as a mail server's external command delivery program. Performs ``os.dup2(fd, new_fd)``. These tuples correspond to the C library - :c:func:`posix_spawn_file_actions_addopen`, - :c:func:`posix_spawn_file_actions_addclose`, and - :c:func:`posix_spawn_file_actions_adddup2` API calls used to prepare - for the :c:func:`posix_spawn` call itself. + :c:func:`!posix_spawn_file_actions_addopen`, + :c:func:`!posix_spawn_file_actions_addclose`, and + :c:func:`!posix_spawn_file_actions_adddup2` API calls used to prepare + for the :c:func:`!posix_spawn` call itself. The *setpgroup* argument will set the process group of the child to the value specified. If the value specified is 0, the child's process group ID will be made the same as its process ID. If the value of *setpgroup* is not set, the child will inherit the parent's process group ID. This argument corresponds - to the C library :c:data:`POSIX_SPAWN_SETPGROUP` flag. + to the C library :c:macro:`!POSIX_SPAWN_SETPGROUP` flag. If the *resetids* argument is ``True`` it will reset the effective UID and GID of the child to the real UID and GID of the parent process. If the @@ -4316,27 +4598,27 @@ written in Python, such as a mail server's external command delivery program. the parent. In either case, if the set-user-ID and set-group-ID permission bits are enabled on the executable file, their effect will override the setting of the effective UID and GID. This argument corresponds to the C - library :c:data:`POSIX_SPAWN_RESETIDS` flag. + library :c:macro:`!POSIX_SPAWN_RESETIDS` flag. If the *setsid* argument is ``True``, it will create a new session ID - for ``posix_spawn``. *setsid* requires :c:data:`POSIX_SPAWN_SETSID` - or :c:data:`POSIX_SPAWN_SETSID_NP` flag. Otherwise, :exc:`NotImplementedError` + for ``posix_spawn``. *setsid* requires :c:macro:`!POSIX_SPAWN_SETSID` + or :c:macro:`!POSIX_SPAWN_SETSID_NP` flag. Otherwise, :exc:`NotImplementedError` is raised. The *setsigmask* argument will set the signal mask to the signal set specified. If the parameter is not used, then the child inherits the parent's signal mask. This argument corresponds to the C library - :c:data:`POSIX_SPAWN_SETSIGMASK` flag. + :c:macro:`!POSIX_SPAWN_SETSIGMASK` flag. The *sigdef* argument will reset the disposition of all signals in the set specified. This argument corresponds to the C library - :c:data:`POSIX_SPAWN_SETSIGDEF` flag. + :c:macro:`!POSIX_SPAWN_SETSIGDEF` flag. The *scheduler* argument must be a tuple containing the (optional) scheduler policy and an instance of :class:`sched_param` with the scheduler parameters. A value of ``None`` in the place of the scheduler policy indicates that is not being provided. This argument is a combination of the C library - :c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER` + :c:macro:`!POSIX_SPAWN_SETSCHEDPARAM` and :c:macro:`!POSIX_SPAWN_SETSCHEDULER` flags. .. audit-event:: os.posix_spawn path,argv,env os.posix_spawn @@ -4349,7 +4631,7 @@ written in Python, such as a mail server's external command delivery program. setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ setsigdef=(), scheduler=None) - Wraps the :c:func:`posix_spawnp` C library API for use from Python. + Wraps the :c:func:`!posix_spawnp` C library API for use from Python. Similar to :func:`posix_spawn` except that the system searches for the *executable* file in the list of directories specified by the @@ -4530,7 +4812,7 @@ written in Python, such as a mail server's external command delivery program. Use *show_cmd* to override the default window style. Whether this has any effect will depend on the application being launched. Values are integers as - supported by the Win32 :c:func:`ShellExecute` function. + supported by the Win32 :c:func:`!ShellExecute` function. :func:`startfile` returns as soon as the associated application is launched. There is no option to wait for the application to close, and no way to retrieve @@ -4540,7 +4822,7 @@ written in Python, such as a mail server's external command delivery program. :func:`os.path.normpath` function to ensure that paths are properly encoded for Win32. - To reduce interpreter startup overhead, the Win32 :c:func:`ShellExecute` + To reduce interpreter startup overhead, the Win32 :c:func:`!ShellExecute` function is not resolved until this function is first called. If the function cannot be resolved, :exc:`NotImplementedError` will be raised. @@ -4650,11 +4932,11 @@ written in Python, such as a mail server's external command delivery program. :data:`WNOHANG` and :data:`WNOWAIT` are additional optional flags. The return value is an object representing the data contained in the - :c:type:`!siginfo_t` structure with the following attributes: + :c:type:`siginfo_t` structure with the following attributes: * :attr:`!si_pid` (process ID) * :attr:`!si_uid` (real user ID of the child) - * :attr:`!si_signo` (always :data:`~signal.SIGCHLD`) + * :attr:`!si_signo` (always :const:`~signal.SIGCHLD`) * :attr:`!si_status` (the exit status or signal number, depending on :attr:`!si_code`) * :attr:`!si_code` (see :data:`CLD_EXITED` for possible values) @@ -4892,7 +5174,7 @@ used to determine the disposition of a process. .. function:: WIFCONTINUED(status) Return ``True`` if a stopped child has been resumed by delivery of - :data:`~signal.SIGCONT` (if the process has been continued from a job + :const:`~signal.SIGCONT` (if the process has been continued from a job control stop), otherwise return ``False``. See :data:`WCONTINUED` option. @@ -5070,8 +5352,12 @@ operating system. .. function:: sched_getaffinity(pid, /) - Return the set of CPUs the process with PID *pid* (or the current process - if zero) is restricted to. + Return the set of CPUs the process with PID *pid* is restricted to. + + If *pid* is zero, return the set of CPUs the calling thread of the current + process is restricted to. + + See also the :func:`process_cpu_count` function. .. _os-path: @@ -5112,15 +5398,18 @@ Miscellaneous System Information .. function:: cpu_count() - Return the number of CPUs in the system. Returns ``None`` if undetermined. - - This number is not equivalent to the number of CPUs the current process can - use. The number of usable CPUs can be obtained with - ``len(os.sched_getaffinity(0))`` + Return the number of logical CPUs in the **system**. Returns ``None`` if + undetermined. + The :func:`process_cpu_count` function can be used to get the number of + logical CPUs usable by the calling thread of the **current process**. .. versionadded:: 3.4 + .. versionchanged:: 3.13 + If :option:`-X cpu_count <-X>` is given or :envvar:`PYTHON_CPU_COUNT` is set, + :func:`cpu_count` returns the overridden value *n*. + .. function:: getloadavg() @@ -5131,6 +5420,23 @@ Miscellaneous System Information .. availability:: Unix. +.. function:: process_cpu_count() + + Get the number of logical CPUs usable by the calling thread of the **current + process**. Returns ``None`` if undetermined. It can be less than + :func:`cpu_count` depending on the CPU affinity. + + The :func:`cpu_count` function can be used to get the number of logical CPUs + in the **system**. + + If :option:`-X cpu_count <-X>` is given or :envvar:`PYTHON_CPU_COUNT` is set, + :func:`process_cpu_count` returns the overridden value *n*. + + See also the :func:`sched_getaffinity` functions. + + .. versionadded:: 3.13 + + .. function:: sysconf(name, /) Return integer-valued system configuration values. If the configuration value @@ -5264,7 +5570,7 @@ Random numbers ``/dev/urandom`` devices. The flags argument is a bit mask that can contain zero or more of the - following values ORed together: :py:data:`os.GRND_RANDOM` and + following values ORed together: :py:const:`os.GRND_RANDOM` and :py:data:`GRND_NONBLOCK`. See also the `Linux getrandom() manual page diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 01dabe286969bb..8ee89a003a339a 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -850,6 +850,42 @@ call fails (for example because the path doesn't exist). .. versionadded:: 3.5 +.. classmethod:: Path.from_uri(uri) + + Return a new path object from parsing a 'file' URI conforming to + :rfc:`8089`. For example:: + + >>> p = Path.from_uri('file:///etc/hosts') + PosixPath('/etc/hosts') + + On Windows, DOS device and UNC paths may be parsed from URIs:: + + >>> p = Path.from_uri('file:///c:/windows') + WindowsPath('c:/windows') + >>> p = Path.from_uri('file://server/share') + WindowsPath('//server/share') + + Several variant forms are supported:: + + >>> p = Path.from_uri('file:////server/share') + WindowsPath('//server/share') + >>> p = Path.from_uri('file://///server/share') + WindowsPath('//server/share') + >>> p = Path.from_uri('file:c:/windows') + WindowsPath('c:/windows') + >>> p = Path.from_uri('file:/c|/windows') + WindowsPath('c:/windows') + + :exc:`ValueError` is raised if the URI does not start with ``file:``, or + the parsed path isn't absolute. + + :func:`os.fsdecode` is used to decode percent-escaped byte sequences, and + so file URIs are not portable across machines with different + :ref:`filesystem encodings `. + + .. versionadded:: 3.13 + + .. method:: Path.stat(*, follow_symlinks=True) Return a :class:`os.stat_result` object containing information about this path, like :func:`os.stat`. @@ -976,6 +1012,11 @@ call fails (for example because the path doesn't exist). .. versionchanged:: 3.13 The *follow_symlinks* parameter was added. + .. versionchanged:: 3.13 + Emits :exc:`FutureWarning` if the pattern ends with "``**``". In a + future Python release, patterns with this ending will match both files + and directories. Add a trailing slash to match only directories. + .. method:: Path.group() Return the name of the group owning the file. :exc:`KeyError` is raised @@ -1376,15 +1417,19 @@ call fails (for example because the path doesn't exist). >>> p.resolve() PosixPath('/home/antoine/pathlib/setup.py') - If the path doesn't exist and *strict* is ``True``, :exc:`FileNotFoundError` - is raised. If *strict* is ``False``, the path is resolved as far as possible - and any remainder is appended without checking whether it exists. If an - infinite loop is encountered along the resolution path, :exc:`RuntimeError` - is raised. + If a path doesn't exist or a symlink loop is encountered, and *strict* is + ``True``, :exc:`OSError` is raised. If *strict* is ``False``, the path is + resolved as far as possible and any remainder is appended without checking + whether it exists. .. versionchanged:: 3.6 The *strict* parameter was added (pre-3.6 behavior is strict). + .. versionchanged:: 3.13 + Symlink loops are treated like other errors: :exc:`OSError` is raised in + strict mode, and no exception is raised in non-strict mode. In previous + versions, :exc:`RuntimeError` is raised no matter the value of *strict*. + .. method:: Path.rglob(pattern, *, case_sensitive=None, follow_symlinks=None) Glob the given relative *pattern* recursively. This is like calling diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index ef52370bff8058..002eeef4c09b5d 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -175,8 +175,8 @@ slightly different way: .. function:: pm() - Enter post-mortem debugging of the traceback found in - :data:`sys.last_traceback`. + Enter post-mortem debugging of the exception found in + :data:`sys.last_exc`. The ``run*`` functions and :func:`set_trace` are aliases for instantiating the @@ -252,6 +252,10 @@ change a variable or call a function. When an exception occurs in such a statement, the exception name is printed but the debugger's state is not changed. +.. versionchanged:: 3.13 + Expressions/Statements whose prefix is a pdb command are now correctly + identified and executed. + The debugger supports :ref:`aliases `. Aliases can have parameters which allows one a certain level of adaptability to the context under examination. @@ -639,6 +643,55 @@ can be overridden by the local file. Print the return value for the last return of the current function. +.. pdbcommand:: exceptions [excnumber] + + List or jump between chained exceptions. + + When using ``pdb.pm()`` or ``Pdb.post_mortem(...)`` with a chained exception + instead of a traceback, it allows the user to move between the + chained exceptions using ``exceptions`` command to list exceptions, and + ``exception `` to switch to that exception. + + + Example:: + + def out(): + try: + middle() + except Exception as e: + raise ValueError("reraise middle() error") from e + + def middle(): + try: + return inner(0) + except Exception as e: + raise ValueError("Middle fail") + + def inner(x): + 1 / x + + out() + + calling ``pdb.pm()`` will allow to move between exceptions:: + + > example.py(5)out() + -> raise ValueError("reraise middle() error") from e + + (Pdb) exceptions + 0 ZeroDivisionError('division by zero') + 1 ValueError('Middle fail') + > 2 ValueError('reraise middle() error') + + (Pdb) exceptions 0 + > example.py(16)inner() + -> 1 / x + + (Pdb) up + > example.py(10)middle() + -> return inner(0) + + .. versionadded:: 3.13 + .. rubric:: Footnotes .. [1] Whether a frame is considered to originate in a certain module diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index ba00ba29f5ba48..93387fb0b45038 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -494,7 +494,8 @@ What can be pickled and unpickled? The following types can be pickled: -* ``None``, ``True``, and ``False``; +* built-in constants (``None``, ``True``, ``False``, ``Ellipsis``, and + ``NotImplemented``); * integers, floating-point numbers, complex numbers; diff --git a/Doc/library/pickletools.rst b/Doc/library/pickletools.rst index 480f4a6d320815..41930f8cbe8412 100644 --- a/Doc/library/pickletools.rst +++ b/Doc/library/pickletools.rst @@ -17,6 +17,8 @@ are useful for Python core developers who are working on the :mod:`pickle`; ordinary users of the :mod:`pickle` module probably won't find the :mod:`pickletools` module relevant. +.. _pickletools-cli: + Command line usage ------------------ @@ -51,24 +53,24 @@ Command line options .. program:: pickletools -.. cmdoption:: -a, --annotate +.. option:: -a, --annotate Annotate each line with a short opcode description. -.. cmdoption:: -o, --output= +.. option:: -o, --output= Name of a file where the output should be written. -.. cmdoption:: -l, --indentlevel= +.. option:: -l, --indentlevel= The number of blanks by which to indent a new MARK level. -.. cmdoption:: -m, --memo +.. option:: -m, --memo When multiple objects are disassembled, preserve memo between disassemblies. -.. cmdoption:: -p, --preamble= +.. option:: -p, --preamble= When more than one pickle file are specified, print given preamble before each disassembly. diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index 69c4dfc422c98e..ec2a7ebd5d6e0b 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -46,7 +46,7 @@ Cross Platform universal files containing multiple architectures. To get at the "64-bitness" of the current interpreter, it is more - reliable to query the :attr:`sys.maxsize` attribute:: + reliable to query the :data:`sys.maxsize` attribute:: is_64bits = sys.maxsize > 2**32 diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 260c4a63d12031..943eb21f6eec02 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -77,7 +77,7 @@ The :mod:`poplib` module provides two classes: .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a @@ -148,7 +148,7 @@ A :class:`POP3` instance has the following methods: .. method:: POP3.pass_(password) Send password, response includes message count and mailbox size. Note: the - mailbox on the server is locked until :meth:`~poplib.quit` is called. + mailbox on the server is locked until :meth:`~POP3.quit` is called. .. method:: POP3.apop(user, secret) @@ -240,7 +240,7 @@ A :class:`POP3` instance has the following methods: This method supports hostname checking via :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. versionadded:: 3.4 diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index d8269ef48cb36a..e883acd67d6c72 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -45,7 +45,7 @@ The :mod:`pprint` module defines one class: several keyword parameters. *stream* (default ``sys.stdout``) is a :term:`file-like object` to - which the output will be written by calling its :meth:`write` method. + which the output will be written by calling its :meth:`!write` method. If both *stream* and ``sys.stdout`` are ``None``, then :meth:`~PrettyPrinter.pprint` silently returns. diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 723f927135a0f4..4c60a1e0d781b0 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -121,6 +121,8 @@ results to a file by specifying a filename to the :func:`run` function:: The :class:`pstats.Stats` class reads profile results from a file and formats them in various ways. +.. _profile-cli: + The files :mod:`cProfile` and :mod:`profile` can also be invoked as a script to profile another script. For example:: @@ -133,11 +135,11 @@ the output by. This only applies when ``-o`` is not supplied. ``-m`` specifies that a module is being profiled instead of a script. - .. versionadded:: 3.7 - Added the ``-m`` option to :mod:`cProfile`. +.. versionadded:: 3.7 + Added the ``-m`` option to :mod:`cProfile`. - .. versionadded:: 3.8 - Added the ``-m`` option to :mod:`profile`. +.. versionadded:: 3.8 + Added the ``-m`` option to :mod:`profile`. The :mod:`pstats` module's :class:`~pstats.Stats` class has a variety of methods for manipulating and printing the data saved into a profile results file:: diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 7f4da41e93802d..ad4981c97119fa 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -71,7 +71,7 @@ The :mod:`pty` module defines the following functions: Return the exit status value from :func:`os.waitpid` on the child process. - :func:`waitstatus_to_exitcode` can be used to convert the exit status into + :func:`os.waitstatus_to_exitcode` can be used to convert the exit status into an exit code. .. audit-event:: pty.spawn argv pty.spawn diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 69b93a3bdfcb26..38c416f9ad0305 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -125,6 +125,7 @@ byte-code cache files in the directory containing the source code. This option is useful when the ``.pycs`` are kept up to date by some system external to Python like a build system. +.. _py_compile-cli: Command-Line Interface ---------------------- @@ -138,13 +139,13 @@ not be compiled. .. program:: python -m py_compile -.. cmdoption:: ... - - +.. option:: ... + - Positional arguments are files to compile. If ``-`` is the only parameter, the list of files is taken from standard input. -.. cmdoption:: -q, --quiet +.. option:: -q, --quiet Suppress errors output. diff --git a/Doc/library/python.rst b/Doc/library/python.rst index f39613f572884f..610435999d9f48 100644 --- a/Doc/library/python.rst +++ b/Doc/library/python.rst @@ -12,6 +12,7 @@ overview: .. toctree:: sys.rst + sys.monitoring.rst sysconfig.rst builtins.rst __main__.rst diff --git a/Doc/library/re.rst b/Doc/library/re.rst index b7510b93d75427..251ec8ca0021a6 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -176,7 +176,7 @@ The special characters are: ``x*+``, ``x++`` and ``x?+`` are equivalent to ``(?>x*)``, ``(?>x+)`` and ``(?>x?)`` correspondingly. - .. versionadded:: 3.11 + .. versionadded:: 3.11 .. index:: single: {} (curly brackets); in regular expressions @@ -501,6 +501,8 @@ The special characters are: in the ASCII range (``b'\x00'``-``b'\x7f'``). +.. _re-special-sequences: + The special sequences consist of ``'\'`` and a character from the list below. If the ordinary character is not an ASCII digit or an ASCII letter, then the resulting RE will match the second character. For example, ``\$`` matches the @@ -632,8 +634,8 @@ character ``'$'``. single: \x; in regular expressions single: \\; in regular expressions -Most of the standard escapes supported by Python string literals are also -accepted by the regular expression parser:: +Most of the :ref:`escape sequences ` supported by Python +string literals are also accepted by the regular expression parser:: \a \b \f \n \N \r \t \u @@ -658,7 +660,7 @@ three digits in length. Unknown escapes consisting of ``'\'`` and an ASCII letter now are errors. .. versionchanged:: 3.8 - The ``'\N{name}'`` escape sequence has been added. As in string literals, + The :samp:`'\\N\\{{name}\\}'` escape sequence has been added. As in string literals, it expands to the named Unicode character (e.g. ``'\N{EM DASH}'``). @@ -779,6 +781,17 @@ Flags Corresponds to the inline flag ``(?s)``. +.. data:: U + UNICODE + + In Python 2, this flag made :ref:`special sequences ` + include Unicode characters in matches. Since Python 3, Unicode characters + are matched by default. + + See :const:`A` for restricting matching on ASCII characters instead. + + This flag is only kept for backward compatibility. + .. data:: X VERBOSE @@ -843,18 +856,17 @@ Functions .. function:: search(pattern, string, flags=0) Scan through *string* looking for the first location where the regular expression - *pattern* produces a match, and return a corresponding :ref:`match object - `. Return ``None`` if no position in the string matches the - pattern; note that this is different from finding a zero-length match at some - point in the string. + *pattern* produces a match, and return a corresponding :class:`~re.Match`. Return + ``None`` if no position in the string matches the pattern; note that this is + different from finding a zero-length match at some point in the string. .. function:: match(pattern, string, flags=0) If zero or more characters at the beginning of *string* match the regular - expression *pattern*, return a corresponding :ref:`match object - `. Return ``None`` if the string does not match the pattern; - note that this is different from a zero-length match. + expression *pattern*, return a corresponding :class:`~re.Match`. Return + ``None`` if the string does not match the pattern; note that this is + different from a zero-length match. Note that even in :const:`MULTILINE` mode, :func:`re.match` will only match at the beginning of the string and not at the beginning of each line. @@ -866,9 +878,8 @@ Functions .. function:: fullmatch(pattern, string, flags=0) If the whole *string* matches the regular expression *pattern*, return a - corresponding :ref:`match object `. Return ``None`` if the - string does not match the pattern; note that this is different from a - zero-length match. + corresponding :class:`~re.Match`. Return ``None`` if the string does not match + the pattern; note that this is different from a zero-length match. .. versionadded:: 3.4 @@ -885,7 +896,7 @@ Functions ['Words', 'words', 'words', ''] >>> re.split(r'(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] - >>> re.split(r'\W+', 'Words, words, words.', 1) + >>> re.split(r'\W+', 'Words, words, words.', maxsplit=1) ['Words', 'words, words.'] >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) ['0', '3', '9'] @@ -916,6 +927,11 @@ Functions .. versionchanged:: 3.7 Added support of splitting on a pattern that could match an empty string. + .. deprecated:: 3.13 + Passing *maxsplit* and *flags* as positional arguments is deprecated. + In future Python versions they will be + :ref:`keyword-only parameters `. + .. function:: findall(pattern, string, flags=0) @@ -941,7 +957,7 @@ Functions .. function:: finditer(pattern, string, flags=0) - Return an :term:`iterator` yielding :ref:`match objects ` over + Return an :term:`iterator` yielding :class:`~re.Match` objects over all non-overlapping matches for the RE *pattern* in *string*. The *string* is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result. @@ -969,8 +985,8 @@ Functions 'static PyObject*\npy_myfunc(void)\n{' If *repl* is a function, it is called for every non-overlapping occurrence of - *pattern*. The function takes a single :ref:`match object ` - argument, and returns the replacement string. For example:: + *pattern*. The function takes a single :class:`~re.Match` argument, and returns + the replacement string. For example:: >>> def dashrepl(matchobj): ... if matchobj.group(0) == '-': return ' ' @@ -981,7 +997,7 @@ Functions >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) 'Baked Beans & Spam' - The pattern may be a string or a :ref:`pattern object `. + The pattern may be a string or a :class:`~re.Pattern`. The optional argument *count* is the maximum number of pattern occurrences to be replaced; *count* must be a non-negative integer. If omitted or zero, all @@ -1014,8 +1030,6 @@ Functions .. versionchanged:: 3.7 Unknown escapes in *repl* consisting of ``'\'`` and an ASCII letter now are errors. - - .. versionchanged:: 3.7 Empty matches for the pattern are replaced when adjacent to a previous non-empty match. @@ -1024,18 +1038,17 @@ Functions In :class:`bytes` replacement strings, group *name* can only contain bytes in the ASCII range (``b'\x00'``-``b'\x7f'``). + .. deprecated:: 3.13 + Passing *count* and *flags* as positional arguments is deprecated. + In future Python versions they will be + :ref:`keyword-only parameters `. + .. function:: subn(pattern, repl, string, count=0, flags=0) Perform the same operation as :func:`sub`, but return a tuple ``(new_string, number_of_subs_made)``. - .. versionchanged:: 3.1 - Added the optional flags argument. - - .. versionchanged:: 3.5 - Unmatched groups are replaced with an empty string. - .. function:: escape(pattern) @@ -1116,16 +1129,20 @@ Exceptions Regular Expression Objects -------------------------- -Compiled regular expression objects support the following methods and -attributes: +.. class:: Pattern + + Compiled regular expression object returned by :func:`re.compile`. + + .. versionchanged:: 3.9 + :py:class:`re.Pattern` supports ``[]`` to indicate a Unicode (str) or bytes pattern. + See :ref:`types-genericalias`. .. method:: Pattern.search(string[, pos[, endpos]]) Scan through *string* looking for the first location where this regular - expression produces a match, and return a corresponding :ref:`match object - `. Return ``None`` if no position in the string matches the - pattern; note that this is different from finding a zero-length match at some - point in the string. + expression produces a match, and return a corresponding :class:`~re.Match`. + Return ``None`` if no position in the string matches the pattern; note that + this is different from finding a zero-length match at some point in the string. The optional second parameter *pos* gives an index in the string where the search is to start; it defaults to ``0``. This is not completely equivalent to @@ -1149,9 +1166,9 @@ attributes: .. method:: Pattern.match(string[, pos[, endpos]]) If zero or more characters at the *beginning* of *string* match this regular - expression, return a corresponding :ref:`match object `. - Return ``None`` if the string does not match the pattern; note that this is - different from a zero-length match. + expression, return a corresponding :class:`~re.Match`. Return ``None`` if the + string does not match the pattern; note that this is different from a + zero-length match. The optional *pos* and *endpos* parameters have the same meaning as for the :meth:`~Pattern.search` method. :: @@ -1168,8 +1185,8 @@ attributes: .. method:: Pattern.fullmatch(string[, pos[, endpos]]) If the whole *string* matches this regular expression, return a corresponding - :ref:`match object `. Return ``None`` if the string does not - match the pattern; note that this is different from a zero-length match. + :class:`~re.Match`. Return ``None`` if the string does not match the pattern; + note that this is different from a zero-length match. The optional *pos* and *endpos* parameters have the same meaning as for the :meth:`~Pattern.search` method. :: @@ -1255,8 +1272,13 @@ when there is no match, you can test whether there was a match with a simple if match: process(match) -Match objects support the following methods and attributes: +.. class:: Match + + Match object returned by successful ``match``\ es and ``search``\ es. + .. versionchanged:: 3.9 + :py:class:`re.Match` supports ``[]`` to indicate a Unicode (str) or bytes match. + See :ref:`types-genericalias`. .. method:: Match.expand(template) @@ -1520,14 +1542,14 @@ Simulating scanf() .. index:: single: scanf() -Python does not currently have an equivalent to :c:func:`scanf`. Regular +Python does not currently have an equivalent to :c:func:`!scanf`. Regular expressions are generally more powerful, though also more verbose, than -:c:func:`scanf` format strings. The table below offers some more-or-less -equivalent mappings between :c:func:`scanf` format tokens and regular +:c:func:`!scanf` format strings. The table below offers some more-or-less +equivalent mappings between :c:func:`!scanf` format tokens and regular expressions. +--------------------------------+---------------------------------------------+ -| :c:func:`scanf` Token | Regular Expression | +| :c:func:`!scanf` Token | Regular Expression | +================================+=============================================+ | ``%c`` | ``.`` | +--------------------------------+---------------------------------------------+ @@ -1552,7 +1574,7 @@ To extract the filename and numbers from a string like :: /usr/sbin/sendmail - 0 errors, 4 warnings -you would use a :c:func:`scanf` format like :: +you would use a :c:func:`!scanf` format like :: %s - %d errors, %d warnings @@ -1643,7 +1665,7 @@ because the address has spaces, our splitting pattern, in it: .. doctest:: :options: +NORMALIZE_WHITESPACE - >>> [re.split(":? ", entry, 3) for entry in entries] + >>> [re.split(":? ", entry, maxsplit=3) for entry in entries] [['Ross', 'McFluff', '834.345.1254', '155 Elm Street'], ['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'], ['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'], @@ -1656,7 +1678,7 @@ house number from the street name: .. doctest:: :options: +NORMALIZE_WHITESPACE - >>> [re.split(":? ", entry, 4) for entry in entries] + >>> [re.split(":? ", entry, maxsplit=4) for entry in entries] [['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'], ['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'], ['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'], @@ -1700,10 +1722,10 @@ Finding all Adverbs and their Positions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If one wants more information about all matches of a pattern than the matched -text, :func:`finditer` is useful as it provides :ref:`match objects -` instead of strings. Continuing with the previous example, if -a writer wanted to find all of the adverbs *and their positions* in -some text, they would use :func:`finditer` in the following manner:: +text, :func:`finditer` is useful as it provides :class:`~re.Match` objects +instead of strings. Continuing with the previous example, if a writer wanted +to find all of the adverbs *and their positions* in some text, they would use +:func:`finditer` in the following manner:: >>> text = "He was carefully disguised but captured quickly by police." >>> for m in re.finditer(r"\w+ly\b", text): diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index 42ed8c253b8027..406b080b7be30f 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -39,7 +39,7 @@ The :mod:`runpy` module provides two functions: The *mod_name* argument should be an absolute module name. If the module name refers to a package rather than a normal - module, then that package is imported and the ``__main__`` submodule within + module, then that package is imported and the :mod:`__main__` submodule within that package is then executed and the resulting module globals dictionary returned. @@ -74,7 +74,7 @@ The :mod:`runpy` module provides two functions: Note that this manipulation of :mod:`sys` is not thread-safe. Other threads may see the partially initialised module, as well as the altered list of - arguments. It is recommended that the :mod:`sys` module be left alone when + arguments. It is recommended that the ``sys`` module be left alone when invoking this function from threaded code. .. seealso:: @@ -82,7 +82,7 @@ The :mod:`runpy` module provides two functions: command line. .. versionchanged:: 3.1 - Added ability to execute packages by looking for a ``__main__`` submodule. + Added ability to execute packages by looking for a :mod:`__main__` submodule. .. versionchanged:: 3.2 Added ``__cached__`` global variable (see :pep:`3147`). @@ -106,15 +106,16 @@ The :mod:`runpy` module provides two functions: Execute the code at the named filesystem location and return the resulting module globals dictionary. As with a script name supplied to the CPython command line, the supplied path may refer to a Python source file, a - compiled bytecode file or a valid sys.path entry containing a ``__main__`` - module (e.g. a zipfile containing a top-level ``__main__.py`` file). + compiled bytecode file or a valid :data:`sys.path` entry containing a + :mod:`__main__` module + (e.g. a zipfile containing a top-level ``__main__.py`` file). For a simple script, the specified code is simply executed in a fresh - module namespace. For a valid sys.path entry (typically a zipfile or + module namespace. For a valid :data:`sys.path` entry (typically a zipfile or directory), the entry is first added to the beginning of ``sys.path``. The function then looks for and executes a :mod:`__main__` module using the updated path. Note that there is no special protection against invoking - an existing :mod:`__main__` entry located elsewhere on ``sys.path`` if + an existing ``__main__`` entry located elsewhere on ``sys.path`` if there is no such module at the specified location. The optional dictionary argument *init_globals* may be used to pre-populate @@ -137,14 +138,14 @@ The :mod:`runpy` module provides two functions: supplied path, and ``__spec__``, ``__cached__``, ``__loader__`` and ``__package__`` will all be set to :const:`None`. - If the supplied path is a reference to a valid sys.path entry, then - ``__spec__`` will be set appropriately for the imported ``__main__`` + If the supplied path is a reference to a valid :data:`sys.path` entry, then + ``__spec__`` will be set appropriately for the imported :mod:`__main__` module (that is, ``__spec__.name`` will always be ``__main__``). ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` will be :ref:`set as normal ` based on the module spec. A number of alterations are also made to the :mod:`sys` module. Firstly, - ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated + :data:`sys.path` may be altered as described above. ``sys.argv[0]`` is updated with the value of ``path_name`` and ``sys.modules[__name__]`` is updated with a temporary module object for the module being executed. All modifications to items in :mod:`sys` are reverted before the function @@ -152,7 +153,7 @@ The :mod:`runpy` module provides two functions: Note that, unlike :func:`run_module`, the alterations made to :mod:`sys` are not optional in this function as these adjustments are essential to - allowing the execution of sys.path entries. As the thread-safety + allowing the execution of :data:`sys.path` entries. As the thread-safety limitations still apply, use of this function in threaded code should be either serialised with the import lock or delegated to a separate process. @@ -165,7 +166,7 @@ The :mod:`runpy` module provides two functions: .. versionchanged:: 3.4 Updated to take advantage of the module spec feature added by :pep:`451`. This allows ``__cached__`` to be set correctly in the - case where ``__main__`` is imported from a valid sys.path entry rather + case where ``__main__`` is imported from a valid :data:`sys.path` entry rather than being executed directly. .. versionchanged:: 3.12 diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 04215d31ba10ca..01bac5afd0b9b3 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -115,7 +115,7 @@ Scheduler Objects .. method:: scheduler.run(blocking=True) - Run all scheduled events. This method will wait (using the :func:`delayfunc` + Run all scheduled events. This method will wait (using the *delayfunc* function passed to the constructor) for the next event, then execute it and so on until there are no more scheduled events. diff --git a/Doc/library/select.rst b/Doc/library/select.rst index b0891b0c8f584a..c2941e628d9d78 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -6,10 +6,10 @@ -------------- -This module provides access to the :c:func:`select` and :c:func:`poll` functions -available in most operating systems, :c:func:`devpoll` available on -Solaris and derivatives, :c:func:`epoll` available on Linux 2.5+ and -:c:func:`kqueue` available on most BSD. +This module provides access to the :c:func:`!select` and :c:func:`!poll` functions +available in most operating systems, :c:func:`!devpoll` available on +Solaris and derivatives, :c:func:`!epoll` available on Linux 2.5+ and +:c:func:`!kqueue` available on most BSD. Note that on Windows, it only works for sockets; on other operating systems, it also works for other file types (in particular, on Unix, it works on pipes). It cannot be used on regular files to determine whether a file has grown since @@ -41,10 +41,10 @@ The module defines the following: polling object; see section :ref:`devpoll-objects` below for the methods supported by devpoll objects. - :c:func:`devpoll` objects are linked to the number of file + :c:func:`!devpoll` objects are linked to the number of file descriptors allowed at the time of instantiation. If your program - reduces this value, :c:func:`devpoll` will fail. If your program - increases this value, :c:func:`devpoll` may return an + reduces this value, :c:func:`!devpoll` will fail. If your program + increases this value, :c:func:`!devpoll` may return an incomplete list of active file descriptors. The new file descriptor is :ref:`non-inheritable `. @@ -62,7 +62,7 @@ The module defines the following: *sizehint* informs epoll about the expected number of events to be registered. It must be positive, or ``-1`` to use the default. It is only - used on older systems where :c:func:`epoll_create1` is not available; + used on older systems where :c:func:`!epoll_create1` is not available; otherwise it has no effect (though its value is still checked). *flags* is deprecated and completely ignored. However, when supplied, its @@ -117,7 +117,7 @@ The module defines the following: .. function:: select(rlist, wlist, xlist[, timeout]) - This is a straightforward interface to the Unix :c:func:`select` system call. + This is a straightforward interface to the Unix :c:func:`!select` system call. The first three arguments are iterables of 'waitable objects': either integers representing file descriptors or objects with a parameterless method named :meth:`~io.IOBase.fileno` returning such an integer: @@ -154,7 +154,7 @@ The module defines the following: .. index:: single: WinSock File objects on Windows are not acceptable, but sockets are. On Windows, - the underlying :c:func:`select` function is provided by the WinSock + the underlying :c:func:`!select` function is provided by the WinSock library, and does not handle file descriptors that don't originate from WinSock. @@ -169,7 +169,7 @@ The module defines the following: The minimum number of bytes which can be written without blocking to a pipe when the pipe has been reported as ready for writing by :func:`~select.select`, - :func:`poll` or another interface in this module. This doesn't apply + :func:`!poll` or another interface in this module. This doesn't apply to other kind of file-like objects such as sockets. This value is guaranteed by POSIX to be at least 512. @@ -184,11 +184,11 @@ The module defines the following: ``/dev/poll`` Polling Objects ----------------------------- -Solaris and derivatives have ``/dev/poll``. While :c:func:`select` is -O(highest file descriptor) and :c:func:`poll` is O(number of file +Solaris and derivatives have ``/dev/poll``. While :c:func:`!select` is +O(highest file descriptor) and :c:func:`!poll` is O(number of file descriptors), ``/dev/poll`` is O(active file descriptors). -``/dev/poll`` behaviour is very close to the standard :c:func:`poll` +``/dev/poll`` behaviour is very close to the standard :c:func:`!poll` object. @@ -222,7 +222,7 @@ object. implement :meth:`!fileno`, so they can also be used as the argument. *eventmask* is an optional bitmask describing the type of events you want to - check for. The constants are the same that with :c:func:`poll` + check for. The constants are the same that with :c:func:`!poll` object. The default value is a combination of the constants :const:`POLLIN`, :const:`POLLPRI`, and :const:`POLLOUT`. @@ -231,7 +231,7 @@ object. Registering a file descriptor that's already registered is not an error, but the result is undefined. The appropriate action is to unregister or modify it first. This is an important difference - compared with :c:func:`poll`. + compared with :c:func:`!poll`. .. method:: devpoll.modify(fd[, eventmask]) @@ -376,13 +376,13 @@ Edge and Level Trigger Polling (epoll) Objects Polling Objects --------------- -The :c:func:`poll` system call, supported on most Unix systems, provides better +The :c:func:`!poll` system call, supported on most Unix systems, provides better scalability for network servers that service many, many clients at the same -time. :c:func:`poll` scales better because the system call only requires listing -the file descriptors of interest, while :c:func:`select` builds a bitmap, turns +time. :c:func:`!poll` scales better because the system call only requires listing +the file descriptors of interest, while :c:func:`!select` builds a bitmap, turns on bits for the fds of interest, and then afterward the whole bitmap has to be -linearly scanned again. :c:func:`select` is O(highest file descriptor), while -:c:func:`poll` is O(number of file descriptors). +linearly scanned again. :c:func:`!select` is O(highest file descriptor), while +:c:func:`!poll` is O(number of file descriptors). .. method:: poll.register(fd[, eventmask]) diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index 0deb15cf4c5037..dd50bac37e49b8 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -60,9 +60,9 @@ constants below: +-----------------------+-----------------------------------------------+ | Constant | Meaning | +=======================+===============================================+ - | :const:`EVENT_READ` | Available for read | + | .. data:: EVENT_READ | Available for read | +-----------------------+-----------------------------------------------+ - | :const:`EVENT_WRITE` | Available for write | + | .. data:: EVENT_WRITE | Available for write | +-----------------------+-----------------------------------------------+ @@ -132,8 +132,8 @@ constants below: Change a registered file object's monitored events or attached data. - This is equivalent to :meth:`BaseSelector.unregister(fileobj)` followed - by :meth:`BaseSelector.register(fileobj, events, data)`, except that it + This is equivalent to ``BaseSelector.unregister(fileobj)`` followed + by ``BaseSelector.register(fileobj, events, data)``, except that it can be implemented more efficiently. This returns a new :class:`SelectorKey` instance, or raises a diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index dc87af398ed757..219219af6fd87f 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -25,7 +25,7 @@ lots of shared sub-objects. The keys are ordinary strings. database file is opened for reading and writing. The optional *flag* parameter has the same interpretation as the *flag* parameter of :func:`dbm.open`. - By default, pickles created with :data:`pickle.DEFAULT_PROTOCOL` are used + By default, pickles created with :const:`pickle.DEFAULT_PROTOCOL` are used to serialize values. The version of the pickle protocol can be specified with the *protocol* parameter. @@ -42,7 +42,7 @@ lots of shared sub-objects. The keys are ordinary strings. mutated). .. versionchanged:: 3.10 - :data:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle + :const:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle protocol. .. versionchanged:: 3.11 @@ -94,9 +94,9 @@ Two additional methods are supported: Restrictions ------------ - .. index:: - pair: module; dbm.ndbm - pair: module; dbm.gnu +.. index:: + pair: module; dbm.ndbm + pair: module; dbm.gnu * The choice of which database package will be used (such as :mod:`dbm.ndbm` or :mod:`dbm.gnu`) depends on which interface is available. Therefore it is not @@ -119,7 +119,7 @@ Restrictions A subclass of :class:`collections.abc.MutableMapping` which stores pickled values in the *dict* object. - By default, pickles created with :data:`pickle.DEFAULT_PROTOCOL` are used + By default, pickles created with :const:`pickle.DEFAULT_PROTOCOL` are used to serialize values. The version of the pickle protocol can be specified with the *protocol* parameter. See the :mod:`pickle` documentation for a discussion of the pickle protocols. @@ -143,7 +143,7 @@ Restrictions Added context manager support. .. versionchanged:: 3.10 - :data:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle + :const:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle protocol. diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 7f408be2336824..d1949d698f5614 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -369,7 +369,7 @@ Directory and files operations If *copy_function* is given, it must be a callable that takes two arguments *src* and *dst*, and will be used to copy *src* to *dst* if :func:`os.rename` cannot be used. If the source is a directory, - :func:`copytree` is called, passing it the :func:`copy_function`. The + :func:`copytree` is called, passing it the *copy_function*. The default *copy_function* is :func:`copy2`. Using :func:`~shutil.copy` as the *copy_function* allows the move to succeed when it is not possible to also copy the metadata, at the expense of not copying any of the metadata. @@ -399,6 +399,12 @@ Directory and files operations total, used and free space, in bytes. *path* may be a file or a directory. + .. note:: + + On Unix filesystems, *path* must point to a path within a **mounted** + filesystem partition. On those platforms, CPython doesn't attempt to + retrieve disk usage information from non-mounted filesystems. + .. versionadded:: 3.3 .. versionchanged:: 3.8 @@ -431,7 +437,7 @@ Directory and files operations determining if the file exists and executable. When no *path* is specified, the results of :func:`os.environ` are used, - returning either the "PATH" value or a fallback of :attr:`os.defpath`. + returning either the "PATH" value or a fallback of :data:`os.defpath`. On Windows, the current directory is prepended to the *path* if *mode* does not include ``os.X_OK``. When the *mode* does include ``os.X_OK``, the @@ -470,6 +476,12 @@ Directory and files operations or ends with an extension that is in ``PATHEXT``; and filenames that have no extension can now be found. + .. versionchanged:: 3.12.1 + On Windows, if *mode* includes ``os.X_OK``, executables with an + extension in ``PATHEXT`` will be preferred over executables without a + matching extension. + This brings behavior closer to that of Python 3.11. + .. exception:: Error This exception collects exceptions that are raised during a multi-file diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 523d1ac5001360..7ee5ece8859825 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -562,7 +562,7 @@ The :mod:`signal` module defines the following functions: Note that installing a signal handler with :func:`signal` will reset the restart behaviour to interruptible by implicitly calling - :c:func:`siginterrupt` with a true *flag* value for the given signal. + :c:func:`!siginterrupt` with a true *flag* value for the given signal. .. function:: signal(signalnum, handler) @@ -656,7 +656,7 @@ The :mod:`signal` module defines the following functions: .. function:: sigtimedwait(sigset, timeout) Like :func:`sigwaitinfo`, but takes an additional *timeout* argument - specifying a timeout. If *timeout* is specified as :const:`0`, a poll is + specifying a timeout. If *timeout* is specified as ``0``, a poll is performed. Returns :const:`None` if a timeout occurs. .. availability:: Unix. diff --git a/Doc/library/site.rst b/Doc/library/site.rst index 44f90a3b9e496f..2dc9fb09d727e2 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -19,7 +19,7 @@ Importing this module will append site-specific paths to the module search path and add a few builtins, unless :option:`-S` was used. In that case, this module can be safely imported with no automatic modifications to the module search path or additions to the builtins. To explicitly trigger the usual site-specific -additions, call the :func:`site.main` function. +additions, call the :func:`main` function. .. versionchanged:: 3.3 Importing the module used to trigger paths manipulation even when using @@ -109,32 +109,40 @@ directory precedes the :file:`foo` directory because :file:`bar.pth` comes alphabetically before :file:`foo.pth`; and :file:`spam` is omitted because it is not mentioned in either path configuration file. -.. index:: pair: module; sitecustomize +:mod:`sitecustomize` +-------------------- + +.. module:: sitecustomize After these path manipulations, an attempt is made to import a module named :mod:`sitecustomize`, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an :exc:`ImportError` or its subclass -exception, and the exception's :attr:`name` attribute equals to ``'sitecustomize'``, +exception, and the exception's :attr:`~ImportError.name` +attribute equals to ``'sitecustomize'``, it is silently ignored. If Python is started without output streams available, as with :file:`pythonw.exe` on Windows (which is used by default to start IDLE), attempted output from :mod:`sitecustomize` is ignored. Any other exception causes a silent and perhaps mysterious failure of the process. -.. index:: pair: module; usercustomize +:mod:`usercustomize` +-------------------- + +.. module:: usercustomize After this, an attempt is made to import a module named :mod:`usercustomize`, which can perform arbitrary user-specific customizations, if -:data:`ENABLE_USER_SITE` is true. This file is intended to be created in the +:data:`~site.ENABLE_USER_SITE` is true. This file is intended to be created in the user site-packages directory (see below), which is part of ``sys.path`` unless disabled by :option:`-s`. If this import fails with an :exc:`ImportError` or -its subclass exception, and the exception's :attr:`name` attribute equals to -``'usercustomize'``, it is silently ignored. +its subclass exception, and the exception's :attr:`~ImportError.name` +attribute equals to ``'usercustomize'``, it is silently ignored. Note that for some non-Unix systems, ``sys.prefix`` and ``sys.exec_prefix`` are empty, and the path manipulations are skipped; however the import of :mod:`sitecustomize` and :mod:`usercustomize` is still attempted. +.. currentmodule:: site .. _rlcompleter-config: @@ -189,9 +197,9 @@ Module contents :func:`getuserbase` hasn't been called yet. Default value is :file:`~/.local` for UNIX and macOS non-framework builds, :file:`~/Library/Python/{X.Y}` for macOS framework builds, and - :file:`{%APPDATA%}\\Python` for Windows. This value is used by Distutils to + :file:`{%APPDATA%}\\Python` for Windows. This value is used to compute the installation directories for scripts, data files, Python modules, - etc. for the :ref:`user installation scheme `. + etc. for the :ref:`user installation scheme `. See also :envvar:`PYTHONUSERBASE`. @@ -258,11 +266,11 @@ If it is called without arguments, it will print the contents of :data:`USER_BASE` and whether the directory exists, then the same thing for :data:`USER_SITE`, and finally the value of :data:`ENABLE_USER_SITE`. -.. cmdoption:: --user-base +.. option:: --user-base Print the path to the user base directory. -.. cmdoption:: --user-site +.. option:: --user-site Print the path to the user site-packages directory. diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index f90274feb6bf9a..aaec2aa1ef1dbe 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -98,7 +98,7 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a @@ -418,7 +418,7 @@ An :class:`SMTP` instance has the following methods: .. versionchanged:: 3.4 The method now supports hostname check with :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see - :data:`~ssl.HAS_SNI`). + :const:`~ssl.HAS_SNI`). .. versionchanged:: 3.5 The error raised for lack of STARTTLS support is now the diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index f2408cb95ff314..c3cf48316b3248 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -207,14 +207,14 @@ created. Socket addresses are represented as follows: - *addr* - Optional bytes-like object specifying the hardware physical address, whose interpretation depends on the device. - .. availability:: Linux >= 2.2. + .. availability:: Linux >= 2.2. - :const:`AF_QIPCRTR` is a Linux-only socket based interface for communicating with services running on co-processors in Qualcomm platforms. The address family is represented as a ``(node, port)`` tuple where the *node* and *port* are non-negative integers. - .. availability:: Linux >= 4.7. + .. availability:: Linux >= 4.7. .. versionadded:: 3.8 @@ -979,7 +979,7 @@ The :mod:`socket` module also offers various network-related services: .. function:: gethostbyname_ex(hostname) Translate a host name to IPv4 address format, extended interface. Return a - triple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the host's + 3-tuple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the host's primary host name, *aliaslist* is a (possibly empty) list of alternative host names for the same address, and *ipaddrlist* is a list of IPv4 addresses for the same interface on the same host (often but not @@ -1007,7 +1007,7 @@ The :mod:`socket` module also offers various network-related services: .. function:: gethostbyaddr(ip_address) - Return a triple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the + Return a 3-tuple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the primary host name responding to the given *ip_address*, *aliaslist* is a (possibly empty) list of alternative host names for the same address, and *ipaddrlist* is a list of IPv4/v6 addresses for the same interface on the same @@ -2100,7 +2100,7 @@ The next two examples are identical to the above two, but support both IPv4 and IPv6. The server side will listen to the first address family available (it should listen to both instead). On most of IPv6-ready systems, IPv6 will take precedence and the server may not accept IPv4 traffic. The client side will try -to connect to the all addresses returned as a result of the name resolution, and +to connect to all the addresses returned as a result of the name resolution, and sends traffic to the first one connected successfully. :: # Echo server program @@ -2252,7 +2252,7 @@ This is because the previous execution has left the socket in a ``TIME_WAIT`` state, and can't be immediately reused. There is a :mod:`socket` flag to set, in order to prevent this, -:data:`socket.SO_REUSEADDR`:: +:const:`socket.SO_REUSEADDR`:: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index d65e9fe81acf8b..5fd213fa613c8d 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -116,23 +116,28 @@ server is the address family. :class:`ForkingMixIn` and the Forking classes mentioned below are only available on POSIX platforms that support :func:`~os.fork`. - :meth:`socketserver.ForkingMixIn.server_close` waits until all child - processes complete, except if - :attr:`socketserver.ForkingMixIn.block_on_close` attribute is false. + .. attribute:: block_on_close - :meth:`socketserver.ThreadingMixIn.server_close` waits until all non-daemon - threads complete, except if - :attr:`socketserver.ThreadingMixIn.block_on_close` attribute is false. Use - daemonic threads by setting - :data:`ThreadingMixIn.daemon_threads` to ``True`` to not wait until threads - complete. + :meth:`ForkingMixIn.server_close ` + waits until all child processes complete, except if + :attr:`block_on_close` attribute is ``False``. + + :meth:`ThreadingMixIn.server_close ` + waits until all non-daemon threads complete, except if + :attr:`block_on_close` attribute is ``False``. + + .. attribute:: daemon_threads + + For :class:`ThreadingMixIn` use daemonic threads by setting + :data:`ThreadingMixIn.daemon_threads ` + to ``True`` to not wait until threads complete. .. versionchanged:: 3.7 - :meth:`socketserver.ForkingMixIn.server_close` and - :meth:`socketserver.ThreadingMixIn.server_close` now waits until all + :meth:`ForkingMixIn.server_close ` and + :meth:`ThreadingMixIn.server_close ` now waits until all child processes and non-daemonic threads complete. - Add a new :attr:`socketserver.ForkingMixIn.block_on_close` class + Add a new :attr:`ForkingMixIn.block_on_close ` class attribute to opt-in for the pre-3.7 behaviour. @@ -412,13 +417,13 @@ Request Handler Objects This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are - available to it; the request is available as :attr:`self.request`; the client - address as :attr:`self.client_address`; and the server instance as - :attr:`self.server`, in case it needs access to per-server information. + available to it; the request is available as :attr:`request`; the client + address as :attr:`client_address`; and the server instance as + :attr:`server`, in case it needs access to per-server information. - The type of :attr:`self.request` is different for datagram or stream - services. For stream services, :attr:`self.request` is a socket object; for - datagram services, :attr:`self.request` is a pair of string and socket. + The type of :attr:`request` is different for datagram or stream + services. For stream services, :attr:`request` is a socket object; for + datagram services, :attr:`request` is a pair of string and socket. .. method:: finish() @@ -428,20 +433,42 @@ Request Handler Objects raises an exception, this function will not be called. + .. attribute:: request + + The *new* :class:`socket.socket` object + to be used to communicate with the client. + + + .. attribute:: client_address + + Client address returned by :meth:`BaseServer.get_request`. + + + .. attribute:: server + + :class:`BaseServer` object used for handling the request. + + .. class:: StreamRequestHandler DatagramRequestHandler These :class:`BaseRequestHandler` subclasses override the :meth:`~BaseRequestHandler.setup` and :meth:`~BaseRequestHandler.finish` - methods, and provide :attr:`self.rfile` and :attr:`self.wfile` attributes. - The :attr:`self.rfile` and :attr:`self.wfile` attributes can be - read or written, respectively, to get the request data or return data - to the client. - The :attr:`!rfile` attributes support the :class:`io.BufferedIOBase` readable interface, - and :attr:`!wfile` attributes support the :class:`!io.BufferedIOBase` writable interface. + methods, and provide :attr:`rfile` and :attr:`wfile` attributes. + + .. attribute:: rfile + + A file object from which receives the request is read. + Support the :class:`io.BufferedIOBase` readable interface. + + .. attribute:: wfile + + A file object to which the reply is written. + Support the :class:`io.BufferedIOBase` writable interface + .. versionchanged:: 3.6 - :attr:`StreamRequestHandler.wfile` also supports the + :attr:`wfile` also supports the :class:`io.BufferedIOBase` writable interface. diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 356888d64b8876..fc87aa94d3363b 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -235,11 +235,11 @@ inserted data and retrieved values from it in multiple ways. * :ref:`sqlite3-howtos` for further reading: - * :ref:`sqlite3-placeholders` - * :ref:`sqlite3-adapters` - * :ref:`sqlite3-converters` - * :ref:`sqlite3-connection-context-manager` - * :ref:`sqlite3-howto-row-factory` + * :ref:`sqlite3-placeholders` + * :ref:`sqlite3-adapters` + * :ref:`sqlite3-converters` + * :ref:`sqlite3-connection-context-manager` + * :ref:`sqlite3-howto-row-factory` * :ref:`sqlite3-explanation` for in-depth background on transaction control. @@ -299,7 +299,7 @@ Module functions Can be ``"DEFERRED"`` (default), ``"EXCLUSIVE"`` or ``"IMMEDIATE"``; or ``None`` to disable opening transactions implicitly. Has no effect unless :attr:`Connection.autocommit` is set to - :data:`~sqlite3.LEGACY_TRANSACTION_CONTROL` (the default). + :const:`~sqlite3.LEGACY_TRANSACTION_CONTROL` (the default). :type isolation_level: str | None :param bool check_same_thread: @@ -334,7 +334,7 @@ Module functions See :attr:`Connection.autocommit` and :ref:`sqlite3-transaction-control-autocommit` for more information. *autocommit* currently defaults to - :data:`~sqlite3.LEGACY_TRANSACTION_CONTROL`. + :const:`~sqlite3.LEGACY_TRANSACTION_CONTROL`. The default will change to ``False`` in a future Python release. :type autocommit: bool @@ -355,6 +355,12 @@ Module functions .. versionadded:: 3.12 The *autocommit* parameter. + .. versionchanged:: 3.13 + Positional use of the parameters *timeout*, *detect_types*, + *isolation_level*, *check_same_thread*, *factory*, *cached_statements*, + and *uri* is deprecated. + They will become keyword-only parameters in Python 3.15. + .. function:: complete_statement(statement) Return ``True`` if the string *statement* appears to contain @@ -523,13 +529,13 @@ Module constants the default `threading mode `_ the underlying SQLite library is compiled with. The SQLite threading modes are: - 1. **Single-thread**: In this mode, all mutexes are disabled and SQLite is - unsafe to use in more than a single thread at once. - 2. **Multi-thread**: In this mode, SQLite can be safely used by multiple - threads provided that no single database connection is used - simultaneously in two or more threads. - 3. **Serialized**: In serialized mode, SQLite can be safely used by - multiple threads with no restriction. + 1. **Single-thread**: In this mode, all mutexes are disabled and SQLite is + unsafe to use in more than a single thread at once. + 2. **Multi-thread**: In this mode, SQLite can be safely used by multiple + threads provided that no single database connection is used + simultaneously in two or more threads. + 3. **Serialized**: In serialized mode, SQLite can be safely used by + multiple threads with no restriction. The mappings from SQLite threading modes to DB-API 2.0 threadsafety levels are as follows: @@ -624,6 +630,12 @@ Connection objects * :ref:`sqlite3-connection-shortcuts` * :ref:`sqlite3-connection-context-manager` + + .. versionchanged:: 3.13 + + A :exc:`ResourceWarning` is emitted if :meth:`close` is not called before + a :class:`!Connection` object is deleted. + An SQLite database connection has the following attributes and methods: .. method:: cursor(factory=Cursor) @@ -751,8 +763,13 @@ Connection objects ... print(row) ('acbd18db4cc2f85cedef654fccc4a4d8',) + .. versionchanged:: 3.13 + + Passing *name*, *narg*, and *func* as keyword arguments is deprecated. + These parameters will become positional-only in Python 3.15. + - .. method:: create_aggregate(name, /, n_arg, aggregate_class) + .. method:: create_aggregate(name, n_arg, aggregate_class) Create or remove a user-defined SQL aggregate function. @@ -805,6 +822,11 @@ Connection objects 3 + .. versionchanged:: 3.13 + + Passing *name*, *n_arg*, and *aggregate_class* as keyword arguments is deprecated. + These parameters will become positional-only in Python 3.15. + .. method:: create_window_function(name, num_params, aggregate_class, /) @@ -892,7 +914,7 @@ Connection objects [('a', 9), ('b', 12), ('c', 16), ('d', 12), ('e', 9)] - .. method:: create_collation(name, callable) + .. method:: create_collation(name, callable, /) Create a collation named *name* using the collating function *callable*. *callable* is passed two :class:`string ` arguments, @@ -969,6 +991,10 @@ Connection objects .. versionchanged:: 3.11 Added support for disabling the authorizer using ``None``. + .. versionchanged:: 3.13 + Passing *authorizer_callback* as a keyword argument is deprecated. + The parameter will become positional-only in Python 3.15. + .. method:: set_progress_handler(progress_handler, n) @@ -984,6 +1010,10 @@ Connection objects currently executing query and cause it to raise a :exc:`DatabaseError` exception. + .. versionchanged:: 3.13 + Passing *progress_handler* as a keyword argument is deprecated. + The parameter will become positional-only in Python 3.15. + .. method:: set_trace_callback(trace_callback) @@ -1008,6 +1038,10 @@ Connection objects .. versionadded:: 3.3 + .. versionchanged:: 3.13 + Passing *trace_callback* as a keyword argument is deprecated. + The parameter will become positional-only in Python 3.15. + .. method:: enable_load_extension(enabled, /) @@ -1544,7 +1578,7 @@ Cursor objects :raises ProgrammingError: If *sql* contains more than one SQL statement, - or is not a DML statment. + or is not a DML statement. Example: @@ -1818,9 +1852,9 @@ Blob objects .. method:: seek(offset, origin=os.SEEK_SET, /) Set the current access position of the blob to *offset*. The *origin* - argument defaults to :data:`os.SEEK_SET` (absolute blob positioning). - Other values for *origin* are :data:`os.SEEK_CUR` (seek relative to the - current position) and :data:`os.SEEK_END` (seek relative to the blob’s + argument defaults to :const:`os.SEEK_SET` (absolute blob positioning). + Other values for *origin* are :const:`os.SEEK_CUR` (seek relative to the + current position) and :const:`os.SEEK_END` (seek relative to the blob’s end). @@ -2403,9 +2437,9 @@ or if :attr:`~Connection.autocommit` is ``True``, the context manager does nothing. .. note:: - The context manager neither implicitly opens a new transaction - nor closes the connection. + nor closes the connection. If you need a closing context manager, consider + using :meth:`contextlib.closing`. .. testcode:: diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 18a6c5ab4858a4..21b38ae62fe02f 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -43,8 +43,10 @@ This module provides a class, :class:`ssl.SSLSocket`, which is derived from the :class:`socket.socket` type, and provides a socket-like wrapper that also encrypts and decrypts the data going over the socket with SSL. It supports additional methods such as :meth:`getpeercert`, which retrieves the -certificate of the other side of the connection, and :meth:`cipher`, which -retrieves the cipher being used for the secure connection. +certificate of the other side of the connection, :meth:`cipher`, which +retrieves the cipher being used for the secure connection or +:meth:`get_verified_chain`, :meth:`get_unverified_chain` which retrieves +certificate chain. For more sophisticated applications, the :class:`ssl.SSLContext` class helps manage settings and certificates, which can then be inherited @@ -139,7 +141,7 @@ purposes. The settings are: :data:`PROTOCOL_TLS_CLIENT` or :data:`PROTOCOL_TLS_SERVER`, :data:`OP_NO_SSLv2`, and :data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and - without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH` + without unauthenticated cipher suites. Passing :const:`~Purpose.SERVER_AUTH` as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` and either loads CA certificates (when at least one of *cafile*, *capath* or *cadata* is given) or uses :meth:`SSLContext.load_default_certs` to load @@ -320,7 +322,7 @@ Random generation Mix the given *bytes* into the SSL pseudo-random number generator. The parameter *entropy* (a float) is a lower bound on the entropy contained in - string (so you can always use :const:`0.0`). See :rfc:`1750` for more + string (so you can always use ``0.0``). See :rfc:`1750` for more information on sources of entropy. .. versionchanged:: 3.5 @@ -1210,6 +1212,22 @@ SSL sockets also have the following additional methods and attributes: .. versionchanged:: 3.9 IPv6 address strings no longer have a trailing new line. +.. method:: SSLSocket.get_verified_chain() + + Returns verified certificate chain provided by the other + end of the SSL channel as a list of DER-encoded bytes. + If certificate verification was disabled method acts the same as + :meth:`~SSLSocket.get_unverified_chain`. + + .. versionadded:: 3.13 + +.. method:: SSLSocket.get_unverified_chain() + + Returns raw certificate chain provided by the other + end of the SSL channel as a list of DER-encoded bytes. + + .. versionadded:: 3.13 + .. method:: SSLSocket.cipher() Returns a three-value tuple containing the name of the cipher being used, the @@ -1380,18 +1398,18 @@ to speed up repeated connections from the same clients. Here's a table showing which versions in a client (down the side) can connect to which versions in a server (along the top): - .. table:: + .. table:: - ======================== ============ ============ ============= ========= =========== =========== - *client* / **server** **SSLv2** **SSLv3** **TLS** [3]_ **TLSv1** **TLSv1.1** **TLSv1.2** - ------------------------ ------------ ------------ ------------- --------- ----------- ----------- - *SSLv2* yes no no [1]_ no no no - *SSLv3* no yes no [2]_ no no no - *TLS* (*SSLv23*) [3]_ no [1]_ no [2]_ yes yes yes yes - *TLSv1* no no yes yes no no - *TLSv1.1* no no yes no yes no - *TLSv1.2* no no yes no no yes - ======================== ============ ============ ============= ========= =========== =========== + ======================== ============ ============ ============= ========= =========== =========== + *client* / **server** **SSLv2** **SSLv3** **TLS** [3]_ **TLSv1** **TLSv1.1** **TLSv1.2** + ------------------------ ------------ ------------ ------------- --------- ----------- ----------- + *SSLv2* yes no no [1]_ no no no + *SSLv3* no yes no [2]_ no no no + *TLS* (*SSLv23*) [3]_ no [1]_ no [2]_ yes yes yes yes + *TLSv1* no no yes yes no no + *TLSv1.1* no no yes no yes no + *TLSv1.2* no no yes no no yes + ======================== ============ ============ ============= ========= =========== =========== .. rubric:: Footnotes .. [1] :class:`SSLContext` disables SSLv2 with :data:`OP_NO_SSLv2` by default. @@ -1484,9 +1502,9 @@ to speed up repeated connections from the same clients. load CA certificates from other locations, too. The *purpose* flag specifies what kind of CA certificates are loaded. The - default settings :data:`Purpose.SERVER_AUTH` loads certificates, that are + default settings :const:`Purpose.SERVER_AUTH` loads certificates, that are flagged and trusted for TLS web server authentication (client side - sockets). :data:`Purpose.CLIENT_AUTH` loads CA certificates for client + sockets). :const:`Purpose.CLIENT_AUTH` loads CA certificates for client certificate verification on the server side. .. versionadded:: 3.4 @@ -1656,8 +1674,9 @@ to speed up repeated connections from the same clients. Due to the early negotiation phase of the TLS connection, only limited methods and attributes are usable like :meth:`SSLSocket.selected_alpn_protocol` and :attr:`SSLSocket.context`. - The :meth:`SSLSocket.getpeercert`, - :meth:`SSLSocket.cipher` and :meth:`SSLSocket.compression` methods require that + The :meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.get_verified_chain`, + :meth:`SSLSocket.get_unverified_chain` :meth:`SSLSocket.cipher` + and :meth:`SSLSocket.compression` methods require that the TLS connection has progressed beyond the TLS Client Hello and therefore will not return meaningful values nor can they be called safely. @@ -1729,7 +1748,7 @@ to speed up repeated connections from the same clients. Wrap an existing Python socket *sock* and return an instance of :attr:`SSLContext.sslsocket_class` (default :class:`SSLSocket`). The returned SSL socket is tied to the context, its settings and certificates. - *sock* must be a :data:`~socket.SOCK_STREAM` socket; other + *sock* must be a :const:`~socket.SOCK_STREAM` socket; other socket types are unsupported. The parameter ``server_side`` is a boolean which identifies whether @@ -2414,6 +2433,8 @@ provided. - :meth:`~SSLSocket.read` - :meth:`~SSLSocket.write` - :meth:`~SSLSocket.getpeercert` + - :meth:`~SSLSocket.get_verified_chain` + - :meth:`~SSLSocket.get_unverified_chain` - :meth:`~SSLSocket.selected_alpn_protocol` - :meth:`~SSLSocket.selected_npn_protocol` - :meth:`~SSLSocket.cipher` @@ -2592,7 +2613,7 @@ disabled by default. >>> client_context.maximum_version = ssl.TLSVersion.TLSv1_3 -The SSL context created above will only allow TLSv1.2 and later (if +The SSL context created above will only allow TLSv1.3 and later (if supported by your system) connections to a server. :const:`PROTOCOL_TLS_CLIENT` implies certificate validation and hostname checks by default. You have to load certificates into the context. diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index 083dc5e3bcfd68..77538514598a50 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -13,8 +13,8 @@ The :mod:`stat` module defines constants and functions for interpreting the results of :func:`os.stat`, :func:`os.fstat` and :func:`os.lstat` (if they -exist). For complete details about the :c:func:`stat`, :c:func:`fstat` and -:c:func:`lstat` calls, consult the documentation for your system. +exist). For complete details about the :c:func:`stat`, :c:func:`!fstat` and +:c:func:`!lstat` calls, consult the documentation for your system. .. versionchanged:: 3.4 The stat module is backed by a C implementation. @@ -89,9 +89,9 @@ mode: .. function:: S_IFMT(mode) Return the portion of the file's mode that describes the file type (used by the - :func:`S_IS\*` functions above). + :func:`!S_IS\*` functions above). -Normally, you would use the :func:`os.path.is\*` functions for testing the type +Normally, you would use the :func:`!os.path.is\*` functions for testing the type of a file; the functions here are useful when you are doing multiple tests of the same file and wish to avoid the overhead of the :c:func:`stat` system call for each test. These are also useful when checking for information about a file diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 395b324c860389..5c8ad3a7dd7380 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -14,6 +14,7 @@ .. testsetup:: * from statistics import * + import math __name__ = '' -------------- @@ -584,7 +585,7 @@ However, for reading convenience, most of the examples show sorted sequences. The *data* can be any iterable containing sample data. For meaningful results, the number of data points in *data* should be larger than *n*. - Raises :exc:`StatisticsError` if there are not at least two data points. + Raises :exc:`StatisticsError` if there is not at least one data point. The cut points are linearly interpolated from the two nearest data points. For example, if a cut point falls one-third @@ -624,6 +625,11 @@ However, for reading convenience, most of the examples show sorted sequences. .. versionadded:: 3.8 + .. versionchanged:: 3.13 + No longer raises an exception for an input with only a single data point. + This allows quantile estimates to be built up one sample point + at a time becoming gradually more refined with each new data point. + .. function:: covariance(x, y, /) Return the sample covariance of two inputs *x* and *y*. Covariance @@ -741,6 +747,24 @@ However, for reading convenience, most of the examples show sorted sequences. *y = slope \* x + noise* + Continuing the example from :func:`correlation`, we look to see + how well a model based on major planets can predict the orbital + distances for dwarf planets: + + .. doctest:: + + >>> model = linear_regression(period_squared, dist_cubed, proportional=True) + >>> slope = model.slope + + >>> # Dwarf planets: Pluto, Eris, Makemake, Haumea, Ceres + >>> orbital_periods = [90_560, 204_199, 111_845, 103_410, 1_680] # days + >>> predicted_dist = [math.cbrt(slope * (p * p)) for p in orbital_periods] + >>> list(map(round, predicted_dist)) + [5912, 10166, 6806, 6459, 414] + + >>> [5_906, 10_152, 6_796, 6_450, 414] # actual distance in million km + [5906, 10152, 6796, 6450, 414] + .. versionadded:: 3.10 .. versionchanged:: 3.11 @@ -828,6 +852,11 @@ of applications in statistics. number generator. This is useful for creating reproducible results, even in a multi-threading context. + .. versionchanged:: 3.13 + + Switched to a faster algorithm. To reproduce samples from previous + versions, use :func:`random.seed` and :func:`random.gauss`. + .. method:: NormalDist.pdf(x) Using a `probability density function (pdf) @@ -922,6 +951,10 @@ of applications in statistics. :class:`NormalDist` Examples and Recipes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Classic probability problems +**************************** + :class:`NormalDist` readily solves classic probability problems. For example, given `historical data for SAT exams @@ -947,6 +980,10 @@ Find the `quartiles `_ and `deciles >>> list(map(round, sat.quantiles(n=10))) [810, 896, 958, 1011, 1060, 1109, 1162, 1224, 1310] + +Monte Carlo inputs for simulations +********************************** + To estimate the distribution for a model than isn't easy to solve analytically, :class:`NormalDist` can generate input samples for a `Monte Carlo simulation `_: @@ -963,6 +1000,9 @@ Carlo simulation `_: >>> quantiles(map(model, X, Y, Z)) # doctest: +SKIP [1.4591308524824727, 1.8035946855390597, 2.175091447274739] +Approximating binomial distributions +************************************ + Normal distributions can be used to approximate `Binomial distributions `_ when the sample size is large and when the probability of a successful @@ -1000,6 +1040,10 @@ probability that the Python room will stay within its capacity limits? >>> mean(trial() <= k for i in range(10_000)) 0.8398 + +Naive bayesian classifier +************************* + Normal distributions commonly arise in machine learning problems. Wikipedia has a `nice example of a Naive Bayesian Classifier @@ -1054,6 +1098,48 @@ The final prediction goes to the largest posterior. This is known as the 'female' +Kernel density estimation +************************* + +It is possible to estimate a continuous probability density function +from a fixed number of discrete samples. + +The basic idea is to smooth the data using `a kernel function such as a +normal distribution, triangular distribution, or uniform distribution +`_. +The degree of smoothing is controlled by a single +parameter, ``h``, representing the variance of the kernel function. + +.. testcode:: + + import math + + def kde_normal(sample, h): + "Create a continuous probability density function from a sample." + # Smooth the sample with a normal distribution of variance h. + kernel_h = NormalDist(0.0, math.sqrt(h)).pdf + n = len(sample) + def pdf(x): + return sum(kernel_h(x - x_i) for x_i in sample) / n + return pdf + +`Wikipedia has an example +`_ +where we can use the ``kde_normal()`` recipe to generate and plot +a probability density function estimated from a small sample: + +.. doctest:: + + >>> sample = [-2.1, -1.3, -0.4, 1.9, 5.1, 6.2] + >>> f_hat = kde_normal(sample, h=2.25) + >>> xarr = [i/100 for i in range(-750, 1100)] + >>> yarr = [f_hat(x) for x in xarr] + +The points in ``xarr`` and ``yarr`` can be used to make a PDF plot: + +.. image:: kde_example.png + :alt: Scatter plot of the estimated probability density function. + .. # This modelines must appear within the last ten lines of the file. kate: indent-width 3; remove-trailing-space on; replace-tabs on; encoding utf-8; diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index fd51b1187576b1..4c63d1557c048a 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -44,13 +44,13 @@ Any object can be tested for truth value, for use in an :keyword:`if` or .. index:: single: true By default, an object is considered true unless its class defines either a -:meth:`__bool__` method that returns ``False`` or a :meth:`__len__` method that +:meth:`~object.__bool__` method that returns ``False`` or a :meth:`__len__` method that returns zero, when called with the object. [1]_ Here are most of the built-in objects considered false: - .. index:: - single: None (Built-in object) - single: False (Built-in object) +.. index:: + single: None (Built-in object) + single: False (Built-in object) * constants defined to be false: ``None`` and ``False`` @@ -282,7 +282,7 @@ the operations, see :ref:`operator-summary`): +---------------------+---------------------------------+---------+--------------------+ | ``x / y`` | quotient of *x* and *y* | | | +---------------------+---------------------------------+---------+--------------------+ -| ``x // y`` | floored quotient of *x* and | \(1) | | +| ``x // y`` | floored quotient of *x* and | \(1)\(2)| | | | *y* | | | +---------------------+---------------------------------+---------+--------------------+ | ``x % y`` | remainder of ``x / y`` | \(2) | | @@ -319,8 +319,10 @@ the operations, see :ref:`operator-summary`): Notes: (1) - Also referred to as integer division. The resultant value is a whole - integer, though the result's type is not necessarily int. The result is + Also referred to as integer division. For operands of type :class:`int`, + the result has type :class:`int`. For operands of type :class:`float`, + the result has type :class:`float`. In general, the result is a whole + integer, though the result's type is not necessarily :class:`int`. The result is always rounded towards minus infinity: ``1//2`` is ``0``, ``(-1)//2`` is ``-1``, ``1//(-2)`` is ``-1``, and ``(-1)//(-2)`` is ``0``. @@ -802,6 +804,7 @@ number, :class:`float`, or :class:`complex`:: hash_value = -2 return hash_value +.. _bltin-boolean-values: .. _typebool: Boolean Type - :class:`bool` @@ -1639,7 +1642,7 @@ expression support in the :mod:`re` module). The casefolding algorithm is `described in section 3.13 'Default Case Folding' of the Unicode Standard - `__. + `__. .. versionadded:: 3.3 @@ -1803,7 +1806,7 @@ expression support in the :mod:`re` module). property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different from the `Alphabetic property defined in the section 4.10 'Letters, Alphabetic, and Ideographic' of the Unicode Standard - `_. + `_. .. method:: str.isascii() @@ -1939,7 +1942,7 @@ expression support in the :mod:`re` module). The lowercasing algorithm used is `described in section 3.13 'Default Case Folding' of the Unicode Standard - `__. + `__. .. method:: str.lstrip([chars]) @@ -2288,7 +2291,7 @@ expression support in the :mod:`re` module). The uppercasing algorithm used is `described in section 3.13 'Default Case Folding' of the Unicode Standard - `__. + `__. .. method:: str.zfill(width) @@ -5632,7 +5635,7 @@ From code, you can inspect the current limit and set a new one using these a getter and setter for the interpreter-wide limit. Subinterpreters have their own limit. -Information about the default and minimum can be found in :attr:`sys.int_info`: +Information about the default and minimum can be found in :data:`sys.int_info`: * :data:`sys.int_info.default_max_str_digits ` is the compiled-in default limit. diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 9b28f99536a3ae..262b785bbcbfc1 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -206,15 +206,15 @@ literal text, it can be escaped by doubling: ``{{`` and ``}}``. The grammar for a replacement field is as follows: - .. productionlist:: format-string - replacement_field: "{" [`field_name`] ["!" `conversion`] [":" `format_spec`] "}" - field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")* - arg_name: [`identifier` | `digit`+] - attribute_name: `identifier` - element_index: `digit`+ | `index_string` - index_string: + - conversion: "r" | "s" | "a" - format_spec: +.. productionlist:: format-string + replacement_field: "{" [`field_name`] ["!" `conversion`] [":" `format_spec`] "}" + field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")* + arg_name: [`identifier` | `digit`+] + attribute_name: `identifier` + element_index: `digit`+ | `index_string` + index_string: + + conversion: "r" | "s" | "a" + format_spec: In less formal terms, the replacement field can start with a *field_name* that specifies the object whose value is to be formatted and inserted @@ -332,30 +332,30 @@ affect the :func:`format` function. The meaning of the various alignment options is as follows: - .. index:: - single: < (less); in string formatting - single: > (greater); in string formatting - single: = (equals); in string formatting - single: ^ (caret); in string formatting - - +---------+----------------------------------------------------------+ - | Option | Meaning | - +=========+==========================================================+ - | ``'<'`` | Forces the field to be left-aligned within the available | - | | space (this is the default for most objects). | - +---------+----------------------------------------------------------+ - | ``'>'`` | Forces the field to be right-aligned within the | - | | available space (this is the default for numbers). | - +---------+----------------------------------------------------------+ - | ``'='`` | Forces the padding to be placed after the sign (if any) | - | | but before the digits. This is used for printing fields | - | | in the form '+000000120'. This alignment option is only | - | | valid for numeric types. It becomes the default for | - | | numbers when '0' immediately precedes the field width. | - +---------+----------------------------------------------------------+ - | ``'^'`` | Forces the field to be centered within the available | - | | space. | - +---------+----------------------------------------------------------+ +.. index:: + single: < (less); in string formatting + single: > (greater); in string formatting + single: = (equals); in string formatting + single: ^ (caret); in string formatting + ++---------+----------------------------------------------------------+ +| Option | Meaning | ++=========+==========================================================+ +| ``'<'`` | Forces the field to be left-aligned within the available | +| | space (this is the default for most objects). | ++---------+----------------------------------------------------------+ +| ``'>'`` | Forces the field to be right-aligned within the | +| | available space (this is the default for numbers). | ++---------+----------------------------------------------------------+ +| ``'='`` | Forces the padding to be placed after the sign (if any) | +| | but before the digits. This is used for printing fields | +| | in the form '+000000120'. This alignment option is only | +| | valid for numeric types. It becomes the default for | +| | numbers when '0' immediately precedes the field width. | ++---------+----------------------------------------------------------+ +| ``'^'`` | Forces the field to be centered within the available | +| | space. | ++---------+----------------------------------------------------------+ Note that unless a minimum field width is defined, the field width will always be the same size as the data to fill it, so that the alignment option has no @@ -364,23 +364,23 @@ meaning in this case. The *sign* option is only valid for number types, and can be one of the following: - .. index:: - single: + (plus); in string formatting - single: - (minus); in string formatting - single: space; in string formatting - - +---------+----------------------------------------------------------+ - | Option | Meaning | - +=========+==========================================================+ - | ``'+'`` | indicates that a sign should be used for both | - | | positive as well as negative numbers. | - +---------+----------------------------------------------------------+ - | ``'-'`` | indicates that a sign should be used only for negative | - | | numbers (this is the default behavior). | - +---------+----------------------------------------------------------+ - | space | indicates that a leading space should be used on | - | | positive numbers, and a minus sign on negative numbers. | - +---------+----------------------------------------------------------+ +.. index:: + single: + (plus); in string formatting + single: - (minus); in string formatting + single: space; in string formatting + ++---------+----------------------------------------------------------+ +| Option | Meaning | ++=========+==========================================================+ +| ``'+'`` | indicates that a sign should be used for both | +| | positive as well as negative numbers. | ++---------+----------------------------------------------------------+ +| ``'-'`` | indicates that a sign should be used only for negative | +| | numbers (this is the default behavior). | ++---------+----------------------------------------------------------+ +| space | indicates that a leading space should be used on | +| | positive numbers, and a minus sign on negative numbers. | ++---------+----------------------------------------------------------+ .. index:: single: z; in string formatting diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 5cfb533d802db4..c6d78a356d97bc 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -27,7 +27,7 @@ procedure are part of the profile. One example of a ``stringprep`` profile is ``nameprep``, which is used for internationalized domain names. The module :mod:`stringprep` only exposes the tables from :rfc:`3454`. As these -tables would be very large to represent them as dictionaries or lists, the +tables would be very large to represent as dictionaries or lists, the module uses the Unicode character database internally. The module source code itself was generated using the ``mkstringprep.py`` utility. diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 6d2739b4557fbf..e2e6fc542e3e67 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -1,6 +1,10 @@ :mod:`struct` --- Interpret bytes as packed binary data ======================================================= +.. testsetup:: * + + from struct import * + .. module:: struct :synopsis: Interpret bytes as packed binary data. @@ -231,9 +235,9 @@ platform-dependent. | ``Q`` | :c:expr:`unsigned long | integer | 8 | \(2) | | | long` | | | | +--------+--------------------------+--------------------+----------------+------------+ -| ``n`` | :c:expr:`ssize_t` | integer | | \(3) | +| ``n`` | :c:type:`ssize_t` | integer | | \(3) | +--------+--------------------------+--------------------+----------------+------------+ -| ``N`` | :c:expr:`size_t` | integer | | \(3) | +| ``N`` | :c:type:`size_t` | integer | | \(3) | +--------+--------------------------+--------------------+----------------+------------+ | ``e`` | \(6) | float | 2 | \(4) | +--------+--------------------------+--------------------+----------------+------------+ @@ -597,6 +601,11 @@ The :mod:`struct` module also defines the following type: The calculated size of the struct (and hence of the bytes object produced by the :meth:`pack` method) corresponding to :attr:`format`. + .. versionchanged:: 3.13 The *repr()* of structs has changed. It + is now: + + >>> Struct('i') + Struct('i') .. _half precision format: https://en.wikipedia.org/wiki/Half-precision_floating-point_format diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 738e611c05adbf..7f22a5d1852a89 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -465,9 +465,9 @@ functions. :func:`open` function when creating the stdin/stdout/stderr pipe file objects: - - :const:`0` means unbuffered (read and write are one + - ``0`` means unbuffered (read and write are one system call and can return short) - - :const:`1` means line buffered + - ``1`` means line buffered (only usable if ``text=True`` or ``universal_newlines=True``) - any other positive value means use a buffer of approximately that size @@ -477,7 +477,7 @@ functions. .. versionchanged:: 3.3.1 *bufsize* now defaults to -1 to enable buffering by default to match the behavior that most code expects. In versions prior to Python 3.2.4 and - 3.3.1 it incorrectly defaulted to :const:`0` which was unbuffered + 3.3.1 it incorrectly defaulted to ``0`` which was unbuffered and allowed short reads. This was unintentional and did not match the behavior of Python 2 as most code expected. @@ -541,8 +541,8 @@ functions. :exc:`RuntimeError`. The new restriction may affect applications that are deployed in mod_wsgi, uWSGI, and other embedded environments. - If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and - :const:`2` will be closed before the child process is executed. Otherwise + If *close_fds* is true, all file descriptors except ``0``, ``1`` and + ``2`` will be closed before the child process is executed. Otherwise when *close_fds* is false, file descriptors obey their inheritable flag as described in :ref:`fd_inheritance`. @@ -666,18 +666,18 @@ functions. passed to the underlying ``CreateProcess`` function. *creationflags*, if given, can be one or more of the following flags: - * :data:`CREATE_NEW_CONSOLE` - * :data:`CREATE_NEW_PROCESS_GROUP` - * :data:`ABOVE_NORMAL_PRIORITY_CLASS` - * :data:`BELOW_NORMAL_PRIORITY_CLASS` - * :data:`HIGH_PRIORITY_CLASS` - * :data:`IDLE_PRIORITY_CLASS` - * :data:`NORMAL_PRIORITY_CLASS` - * :data:`REALTIME_PRIORITY_CLASS` - * :data:`CREATE_NO_WINDOW` - * :data:`DETACHED_PROCESS` - * :data:`CREATE_DEFAULT_ERROR_MODE` - * :data:`CREATE_BREAKAWAY_FROM_JOB` + * :data:`CREATE_NEW_CONSOLE` + * :data:`CREATE_NEW_PROCESS_GROUP` + * :data:`ABOVE_NORMAL_PRIORITY_CLASS` + * :data:`BELOW_NORMAL_PRIORITY_CLASS` + * :data:`HIGH_PRIORITY_CLASS` + * :data:`IDLE_PRIORITY_CLASS` + * :data:`NORMAL_PRIORITY_CLASS` + * :data:`REALTIME_PRIORITY_CLASS` + * :data:`CREATE_NO_WINDOW` + * :data:`DETACHED_PROCESS` + * :data:`CREATE_DEFAULT_ERROR_MODE` + * :data:`CREATE_BREAKAWAY_FROM_JOB` *pipesize* can be used to change the size of the pipe when :data:`PIPE` is used for *stdin*, *stdout* or *stderr*. The size of the pipe @@ -742,8 +742,8 @@ the timeout expires before the process exits. Exceptions defined in this module all inherit from :exc:`SubprocessError`. - .. versionadded:: 3.3 - The :exc:`SubprocessError` base class was added. +.. versionadded:: 3.3 + The :exc:`SubprocessError` base class was added. .. _subprocess-security: @@ -1610,7 +1610,7 @@ improves performance. If you ever encounter a presumed highly unusual situation where you need to prevent ``vfork()`` from being used by Python, you can set the -:attr:`subprocess._USE_VFORK` attribute to a false value. +:const:`subprocess._USE_VFORK` attribute to a false value. :: @@ -1618,7 +1618,7 @@ prevent ``vfork()`` from being used by Python, you can set the Setting this has no impact on use of ``posix_spawn()`` which could use ``vfork()`` internally within its libc implementation. There is a similar -:attr:`subprocess._USE_POSIX_SPAWN` attribute if you need to prevent use of +:const:`subprocess._USE_POSIX_SPAWN` attribute if you need to prevent use of that. :: diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index bd17039bc6f6b6..17bfa66f043302 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -4,10 +4,12 @@ Superseded Modules ****************** -The modules described in this chapter are deprecated and only kept for +The modules described in this chapter are deprecated or :term:`soft deprecated` and only kept for backwards compatibility. They have been superseded by other modules. .. toctree:: + :maxdepth: 1 + getopt.rst optparse.rst diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 65ff5bfe7abd61..85eae5f3822575 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -38,7 +38,13 @@ Examining Symbol Tables .. method:: get_type() Return the type of the symbol table. Possible values are ``'class'``, - ``'module'``, and ``'function'``. + ``'module'``, ``'function'``, ``'annotation'``, ``'TypeVar bound'``, + ``'type alias'``, and ``'type parameter'``. The latter four refer to + different flavors of :ref:`annotation scopes `. + + .. versionchanged:: 3.12 + Added ``'annotation'``, ``'TypeVar bound'``, ``'type alias'``, + and ``'type parameter'`` as possible return values. .. method:: get_id() @@ -49,6 +55,10 @@ Examining Symbol Tables Return the table's name. This is the name of the class if the table is for a class, the name of the function if the table is for a function, or ``'top'`` if the table is global (:meth:`get_type` returns ``'module'``). + For type parameter scopes (which are used for generic classes, functions, + and type aliases), it is the name of the underlying class, function, or + type alias. For type alias scopes, it is the name of the type alias. + For :class:`~typing.TypeVar` bound scopes, it is the name of the ``TypeVar``. .. method:: get_lineno() diff --git a/Doc/library/sys.monitoring.rst b/Doc/library/sys.monitoring.rst new file mode 100644 index 00000000000000..5dcbdaf8e5d0e4 --- /dev/null +++ b/Doc/library/sys.monitoring.rst @@ -0,0 +1,300 @@ +:mod:`sys.monitoring` --- Execution event monitoring +==================================================== + +.. module:: sys.monitoring + :synopsis: Access and control event monitoring + +----------------- + +.. note:: + + ``sys.monitoring`` is a namespace within the ``sys`` module, + not an independent module, so there is no need to + ``import sys.monitoring``, simply ``import sys`` and then use + ``sys.monitoring``. + + +This namespace provides access to the functions and constants necessary to +activate and control event monitoring. + +As programs execute, events occur that might be of interest to tools that +monitor execution. The :mod:`!sys.monitoring` namespace provides means to +receive callbacks when events of interest occur. + +The monitoring API consists of three components: + +* Tool identifiers +* Events +* Callbacks + +Tool identifiers +---------------- + +A tool identifier is an integer and associated name. +Tool identifiers are used to discourage tools from interfering with each +other and to allow multiple tools to operate at the same time. +Currently tools are completely independent and cannot be used to +monitor each other. This restriction may be lifted in the future. + +Before registering or activating events, a tool should choose an identifier. +Identifiers are integers in the range 0 to 5. + +Registering and using tools +''''''''''''''''''''''''''' + +.. function:: use_tool_id(id: int, name: str) -> None + + Must be called before ``id`` can be used. + ``id`` must be in the range 0 to 5 inclusive. + Raises a ``ValueError`` if ``id`` is in use. + +.. function:: free_tool_id(id: int) -> None + + Should be called once a tool no longer requires ``id``. + +.. function:: get_tool(id: int) -> str | None + + Returns the name of the tool if ``id`` is in use, + otherwise it returns ``None``. + ``id`` must be in the range 0 to 5 inclusive. + +All IDs are treated the same by the VM with regard to events, but the +following IDs are pre-defined to make co-operation of tools easier:: + + sys.monitoring.DEBUGGER_ID = 0 + sys.monitoring.COVERAGE_ID = 1 + sys.monitoring.PROFILER_ID = 2 + sys.monitoring.OPTIMIZER_ID = 5 + +There is no obligation to set an ID, nor is there anything preventing a tool +from using an ID even it is already in use. +However, tools are encouraged to use a unique ID and respect other tools. + +Events +------ + +The following events are supported: + +BRANCH + A conditional branch is taken (or not). +CALL + A call in Python code (event occurs before the call). +C_RAISE + Exception raised from any callable, except Python functions (event occurs after the exit). +C_RETURN + Return from any callable, except Python functions (event occurs after the return). +EXCEPTION_HANDLED + An exception is handled. +INSTRUCTION + A VM instruction is about to be executed. +JUMP + An unconditional jump in the control flow graph is made. +LINE + An instruction is about to be executed that has a different line number from the preceding instruction. +PY_RESUME + Resumption of a Python function (for generator and coroutine functions), except for throw() calls. +PY_RETURN + Return from a Python function (occurs immediately before the return, the callee's frame will be on the stack). +PY_START + Start of a Python function (occurs immediately after the call, the callee's frame will be on the stack) +PY_THROW + A Python function is resumed by a throw() call. +PY_UNWIND + Exit from a Python function during exception unwinding. +PY_YIELD + Yield from a Python function (occurs immediately before the yield, the callee's frame will be on the stack). +RAISE + An exception is raised, except those that cause a ``STOP_ITERATION`` event. +RERAISE + An exception is re-raised, for example at the end of a ``finally`` block. +STOP_ITERATION + An artificial ``StopIteration`` is raised; see `the STOP_ITERATION event`_. + +More events may be added in the future. + +These events are attributes of the :mod:`!sys.monitoring.events` namespace. +Each event is represented as a power-of-2 integer constant. +To define a set of events, simply bitwise or the individual events together. +For example, to specify both ``PY_RETURN`` and ``PY_START`` events, use the +expression ``PY_RETURN | PY_START``. + +Events are divided into three groups: + +Local events +'''''''''''' + +Local events are associated with normal execution of the program and happen +at clearly defined locations. All local events can be disabled. +The local events are: + +* PY_START +* PY_RESUME +* PY_RETURN +* PY_YIELD +* CALL +* LINE +* INSTRUCTION +* JUMP +* BRANCH +* STOP_ITERATION + +Ancillary events +'''''''''''''''' + +Ancillary events can be monitored like other events, but are controlled +by another event: + +* C_RAISE +* C_RETURN + +The ``C_RETURN`` and ``C_RAISE`` events are controlled by the ``CALL`` +event. ``C_RETURN`` and ``C_RAISE`` events will only be seen if the +corresponding ``CALL`` event is being monitored. + +Other events +'''''''''''' + +Other events are not necessarily tied to a specific location in the +program and cannot be individually disabled. + +The other events that can be monitored are: + +* PY_THROW +* PY_UNWIND +* RAISE +* EXCEPTION_HANDLED + + +The STOP_ITERATION event +'''''''''''''''''''''''' + +:pep:`PEP 380 <380#use-of-stopiteration-to-return-values>` +specifies that a ``StopIteration`` exception is raised when returning a value +from a generator or coroutine. However, this is a very inefficient way to +return a value, so some Python implementations, notably CPython 3.12+, do not +raise an exception unless it would be visible to other code. + +To allow tools to monitor for real exceptions without slowing down generators +and coroutines, the ``STOP_ITERATION`` event is provided. +``STOP_ITERATION`` can be locally disabled, unlike ``RAISE``. + + +Turning events on and off +------------------------- + +In order to monitor an event, it must be turned on and a callback registered. +Events can be turned on or off by setting the events either globally or +for a particular code object. + + +Setting events globally +''''''''''''''''''''''' + +Events can be controlled globally by modifying the set of events being monitored. + +.. function:: get_events(tool_id: int) -> int + + Returns the ``int`` representing all the active events. + +.. function:: set_events(tool_id: int, event_set: int) + + Activates all events which are set in ``event_set``. + Raises a ``ValueError`` if ``tool_id`` is not in use. + +No events are active by default. + +Per code object events +'''''''''''''''''''''' + +Events can also be controlled on a per code object basis. + +.. function:: get_local_events(tool_id: int, code: CodeType) -> int + + Returns all the local events for ``code`` + +.. function:: set_local_events(tool_id: int, code: CodeType, event_set: int) + + Activates all the local events for ``code`` which are set in ``event_set``. + Raises a ``ValueError`` if ``tool_id`` is not in use. + +Local events add to global events, but do not mask them. +In other words, all global events will trigger for a code object, +regardless of the local events. + + +Disabling events +'''''''''''''''' + +Local events can be disabled for a specific code location by returning +``sys.monitoring.DISABLE`` from a callback function. This does not change +which events are set, or any other code locations for the same event. + +Disabling events for specific locations is very important for high +performance monitoring. For example, a program can be run under a +debugger with no overhead if the debugger disables all monitoring +except for a few breakpoints. + + +Registering callback functions +------------------------------ + +To register a callable for events call + +.. function:: register_callback(tool_id: int, event: int, func: Callable | None) -> Callable | None + + Registers the callable ``func`` for the ``event`` with the given ``tool_id`` + + If another callback was registered for the given ``tool_id`` and ``event``, + it is unregistered and returned. + Otherwise ``register_callback`` returns ``None``. + + +Functions can be unregistered by calling +``sys.monitoring.register_callback(tool_id, event, None)``. + +Callback functions can be registered and unregistered at any time. + +Registering or unregistering a callback function will generate a ``sys.audit`` event. + + +Callback function arguments +''''''''''''''''''''''''''' + +When an active event occurs, the registered callback function is called. +Different events will provide the callback function with different arguments, as follows: + +* ``PY_START`` and ``PY_RESUME``:: + + func(code: CodeType, instruction_offset: int) -> DISABLE | Any + +* ``PY_RETURN`` and ``PY_YIELD``: + + ``func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any`` + +* ``CALL``, ``C_RAISE`` and ``C_RETURN``: + + ``func(code: CodeType, instruction_offset: int, callable: object, arg0: object | MISSING) -> DISABLE | Any`` + + If there are no arguments, ``arg0`` is set to ``MISSING``. + +* ``RAISE``, ``RERAISE``, ``EXCEPTION_HANDLED``, ``PY_UNWIND``, ``PY_THROW`` and ``STOP_ITERATION``: + + ``func(code: CodeType, instruction_offset: int, exception: BaseException) -> DISABLE | Any`` + +* ``LINE``: + + ``func(code: CodeType, line_number: int) -> DISABLE | Any`` + +* ``BRANCH`` and ``JUMP``: + + ``func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any`` + + Note that the ``destination_offset`` is where the code will next execute. + For an untaken branch this will be the offset of the instruction following + the branch. + +* ``INSTRUCTION``: + + ``func(code: CodeType, instruction_offset: int) -> DISABLE | Any`` + + diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index bacf8ceac5041e..f9f556306f5827 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -22,6 +22,8 @@ always available. .. versionadded:: 3.2 + .. availability:: Unix. + .. function:: addaudithook(hook) @@ -166,7 +168,7 @@ always available. Python interpreter. (This information is not available in any other way --- ``modules.keys()`` only lists the imported modules.) - See also the :attr:`sys.stdlib_module_names` list. + See also the :data:`sys.stdlib_module_names` list. .. function:: call_tracing(func, args) @@ -333,23 +335,21 @@ always available. *wasm32-emscripten* platform. The named tuple is provisional and may change in the future. - .. tabularcolumns:: |l|L| - - +-----------------------------+----------------------------------------------+ - | Attribute | Explanation | - +=============================+==============================================+ - | :const:`emscripten_version` | Emscripten version as tuple of ints | - | | (major, minor, micro), e.g. ``(3, 1, 8)``. | - +-----------------------------+----------------------------------------------+ - | :const:`runtime` | Runtime string, e.g. browser user agent, | - | | ``'Node.js v14.18.2'``, or ``'UNKNOWN'``. | - +-----------------------------+----------------------------------------------+ - | :const:`pthreads` | ``True`` if Python is compiled with | - | | Emscripten pthreads support. | - +-----------------------------+----------------------------------------------+ - | :const:`shared_memory` | ``True`` if Python is compiled with shared | - | | memory support. | - +-----------------------------+----------------------------------------------+ + .. attribute:: _emscripten_info.emscripten_version + + Emscripten version as tuple of ints (major, minor, micro), e.g. ``(3, 1, 8)``. + + .. attribute:: _emscripten_info.runtime + + Runtime string, e.g. browser user agent, ``'Node.js v14.18.2'``, or ``'UNKNOWN'``. + + .. attribute:: _emscripten_info.pthreads + + ``True`` if Python is compiled with Emscripten pthreads support. + + .. attribute:: _emscripten_info.shared_memory + + ``True`` if Python is compiled with shared memory support. .. availability:: Emscripten. @@ -380,7 +380,7 @@ always available. This function prints out a given traceback and exception to ``sys.stderr``. - When an exception is raised and uncaught, the interpreter calls + When an exception other than :exc:`SystemExit` is raised and uncaught, the interpreter calls ``sys.excepthook`` with three arguments, the exception class, exception instance, and a traceback object. In an interactive session this happens just before control is returned to the prompt; in a Python program this happens just @@ -515,27 +515,62 @@ always available. The :term:`named tuple` *flags* exposes the status of command line flags. The attributes are read only. - ============================= ============================================================================================================== - attribute flag - ============================= ============================================================================================================== - :const:`debug` :option:`-d` - :const:`inspect` :option:`-i` - :const:`interactive` :option:`-i` - :const:`isolated` :option:`-I` - :const:`optimize` :option:`-O` or :option:`-OO` - :const:`dont_write_bytecode` :option:`-B` - :const:`no_user_site` :option:`-s` - :const:`no_site` :option:`-S` - :const:`ignore_environment` :option:`-E` - :const:`verbose` :option:`-v` - :const:`bytes_warning` :option:`-b` - :const:`quiet` :option:`-q` - :const:`hash_randomization` :option:`-R` - :const:`dev_mode` :option:`-X dev <-X>` (:ref:`Python Development Mode `) - :const:`utf8_mode` :option:`-X utf8 <-X>` - :const:`safe_path` :option:`-P` - :const:`int_max_str_digits` :option:`-X int_max_str_digits <-X>` (:ref:`integer string conversion length limitation `) - ============================= ============================================================================================================== + .. list-table:: + + * - .. attribute:: flags.debug + - :option:`-d` + + * - .. attribute:: flags.inspect + - :option:`-i` + + * - .. attribute:: flags.interactive + - :option:`-i` + + * - .. attribute:: flags.isolated + - :option:`-I` + + * - .. attribute:: flags.optimize + - :option:`-O` or :option:`-OO` + + * - .. attribute:: flags.dont_write_bytecode + - :option:`-B` + + * - .. attribute:: flags.no_user_site + - :option:`-s` + + * - .. attribute:: flags.no_site + - :option:`-S` + + * - .. attribute:: flags.ignore_environment + - :option:`-E` + + * - .. attribute:: flags.verbose + - :option:`-v` + + * - .. attribute:: flags.bytes_warning + - :option:`-b` + + * - .. attribute:: flags.quiet + - :option:`-q` + + * - .. attribute:: flags.hash_randomization + - :option:`-R` + + * - .. attribute:: flags.dev_mode + - :option:`-X dev <-X>` (:ref:`Python Development Mode `) + + * - .. attribute:: flags.utf8_mode + - :option:`-X utf8 <-X>` + + * - .. attribute:: flags.safe_path + - :option:`-P` + + * - .. attribute:: flags.int_max_str_digits + - :option:`-X int_max_str_digits <-X>` + (:ref:`integer string conversion length limitation `) + + * - .. attribute:: flags.warn_default_encoding + - :option:`-X warn_default_encoding <-X>` .. versionchanged:: 3.2 Added ``quiet`` attribute for the new :option:`-q` flag. @@ -554,6 +589,9 @@ always available. Mode ` and the ``utf8_mode`` attribute for the new :option:`-X` ``utf8`` flag. + .. versionchanged:: 3.10 + Added ``warn_default_encoding`` attribute for :option:`-X` ``warn_default_encoding`` flag. + .. versionchanged:: 3.11 Added the ``safe_path`` attribute for :option:`-P` option. @@ -570,61 +608,82 @@ always available. programming language; see section 5.2.4.2.2 of the 1999 ISO/IEC C standard [C99]_, 'Characteristics of floating types', for details. - .. tabularcolumns:: |l|l|L| - - +---------------------+---------------------+--------------------------------------------------+ - | attribute | float.h macro | explanation | - +=====================+=====================+==================================================+ - | ``epsilon`` | ``DBL_EPSILON`` | difference between 1.0 and the least value | - | | | greater than 1.0 that is representable as a float| - | | | | - | | | See also :func:`math.ulp`. | - +---------------------+---------------------+--------------------------------------------------+ - | ``dig`` | ``DBL_DIG`` | maximum number of decimal digits that can be | - | | | faithfully represented in a float; see below | - +---------------------+---------------------+--------------------------------------------------+ - | ``mant_dig`` | ``DBL_MANT_DIG`` | float precision: the number of base-``radix`` | - | | | digits in the significand of a float | - +---------------------+---------------------+--------------------------------------------------+ - | ``max`` | ``DBL_MAX`` | maximum representable positive finite float | - +---------------------+---------------------+--------------------------------------------------+ - | ``max_exp`` | ``DBL_MAX_EXP`` | maximum integer *e* such that ``radix**(e-1)`` is| - | | | a representable finite float | - +---------------------+---------------------+--------------------------------------------------+ - | ``max_10_exp`` | ``DBL_MAX_10_EXP`` | maximum integer *e* such that ``10**e`` is in the| - | | | range of representable finite floats | - +---------------------+---------------------+--------------------------------------------------+ - | ``min`` | ``DBL_MIN`` | minimum representable positive *normalized* float| - | | | | - | | | Use :func:`math.ulp(0.0) ` to get the | - | | | smallest positive *denormalized* representable | - | | | float. | - +---------------------+---------------------+--------------------------------------------------+ - | ``min_exp`` | ``DBL_MIN_EXP`` | minimum integer *e* such that ``radix**(e-1)`` is| - | | | a normalized float | - +---------------------+---------------------+--------------------------------------------------+ - | ``min_10_exp`` | ``DBL_MIN_10_EXP`` | minimum integer *e* such that ``10**e`` is a | - | | | normalized float | - +---------------------+---------------------+--------------------------------------------------+ - | ``radix`` | ``FLT_RADIX`` | radix of exponent representation | - +---------------------+---------------------+--------------------------------------------------+ - | ``rounds`` | ``FLT_ROUNDS`` | integer representing the rounding mode for | - | | | floating-point arithmetic. This reflects the | - | | | value of the system ``FLT_ROUNDS`` macro at | - | | | interpreter startup time: | - | | | ``-1`` indeterminable, | - | | | ``0`` toward zero, | - | | | ``1`` to nearest, | - | | | ``2`` toward positive infinity, | - | | | ``3`` toward negative infinity | - | | | | - | | | All other values for ``FLT_ROUNDS`` characterize | - | | | implementation-defined rounding behavior. | - +---------------------+---------------------+--------------------------------------------------+ + .. list-table:: Attributes of the :data:`!float_info` :term:`named tuple` + :header-rows: 1 + + * - attribute + - float.h macro + - explanation + + * - .. attribute:: float_info.epsilon + - :c:macro:`!DBL_EPSILON` + - difference between 1.0 and the least value greater than 1.0 that is + representable as a float. + + See also :func:`math.ulp`. + + * - .. attribute:: float_info.dig + - :c:macro:`!DBL_DIG` + - The maximum number of decimal digits that can be faithfully + represented in a float; see below. + + * - .. attribute:: float_info.mant_dig + - :c:macro:`!DBL_MANT_DIG` + - Float precision: the number of base-``radix`` digits in the + significand of a float. + + * - .. attribute:: float_info.max + - :c:macro:`!DBL_MAX` + - The maximum representable positive finite float. + + * - .. attribute:: float_info.max_exp + - :c:macro:`!DBL_MAX_EXP` + - The maximum integer *e* such that ``radix**(e-1)`` is a representable + finite float. + + * - .. attribute:: float_info.max_10_exp + - :c:macro:`!DBL_MAX_10_EXP` + - The maximum integer *e* such that ``10**e`` is in the range of + representable finite floats. + + * - .. attribute:: float_info.min + - :c:macro:`!DBL_MIN` + - The minimum representable positive *normalized* float. + + Use :func:`math.ulp(0.0) ` to get the smallest positive + *denormalized* representable float. + + * - .. attribute:: float_info.min_exp + - :c:macro:`!DBL_MIN_EXP` + - The minimum integer *e* such that ``radix**(e-1)`` is a normalized + float. + + * - .. attribute:: float_info.min_10_exp + - :c:macro:`!DBL_MIN_10_EXP` + - The minimum integer *e* such that ``10**e`` is a normalized float. + + * - .. attribute:: float_info.radix + - :c:macro:`!FLT_RADIX` + - The radix of exponent representation. + + * - .. attribute:: float_info.rounds + - :c:macro:`!FLT_ROUNDS` + - An integer representing the rounding mode for floating-point arithmetic. + This reflects the value of the system :c:macro:`!FLT_ROUNDS` macro + at interpreter startup time: + + * ``-1``: indeterminable + * ``0``: toward zero + * ``1``: to nearest + * ``2``: toward positive infinity + * ``3``: toward negative infinity + + All other values for :c:macro:`!FLT_ROUNDS` characterize + implementation-defined rounding behavior. The attribute :attr:`sys.float_info.dig` needs further explanation. If ``s`` is any string representing a decimal number with at most - :attr:`sys.float_info.dig` significant digits, then converting ``s`` to a + :attr:`!sys.float_info.dig` significant digits, then converting ``s`` to a float and back again will recover a string representing the same decimal value:: @@ -696,8 +755,8 @@ always available. Return the current value of the flags that are used for :c:func:`dlopen` calls. Symbolic names for the flag values can be - found in the :mod:`os` module (``RTLD_xxx`` constants, e.g. - :data:`os.RTLD_LAZY`). + found in the :mod:`os` module (:samp:`RTLD_{xxx}` constants, e.g. + :const:`os.RTLD_LAZY`). .. availability:: Unix. @@ -766,6 +825,15 @@ always available. higher than you might expect, because it includes the (temporary) reference as an argument to :func:`getrefcount`. + Note that the returned value may not actually reflect how many + references to the object are actually held. For example, some + objects are "immortal" and have a very high refcount that does not + reflect the actual number of references. Consequently, do not rely + on the returned value to be accurate, other than a value of 0 or 1. + + .. versionchanged:: 3.12 + Immortal objects have very large refcounts that do not match + the actual number of references to the object. .. function:: getrecursionlimit() @@ -873,24 +941,24 @@ always available. ``sys.getwindowsversion().major``. For compatibility with prior versions, only the first 5 elements are retrievable by indexing. - *platform* will be :const:`2 (VER_PLATFORM_WIN32_NT)`. + *platform* will be ``2`` (VER_PLATFORM_WIN32_NT). *product_type* may be one of the following values: +---------------------------------------+---------------------------------+ | Constant | Meaning | +=======================================+=================================+ - | :const:`1 (VER_NT_WORKSTATION)` | The system is a workstation. | + | ``1`` (VER_NT_WORKSTATION) | The system is a workstation. | +---------------------------------------+---------------------------------+ - | :const:`2 (VER_NT_DOMAIN_CONTROLLER)` | The system is a domain | + | ``2`` (VER_NT_DOMAIN_CONTROLLER) | The system is a domain | | | controller. | +---------------------------------------+---------------------------------+ - | :const:`3 (VER_NT_SERVER)` | The system is a server, but not | + | ``3`` (VER_NT_SERVER) | The system is a server, but not | | | a domain controller. | +---------------------------------------+---------------------------------+ - This function wraps the Win32 :c:func:`GetVersionEx` function; see the - Microsoft documentation on :c:func:`OSVERSIONINFOEX` for more information + This function wraps the Win32 :c:func:`!GetVersionEx` function; see the + Microsoft documentation on :c:func:`!OSVERSIONINFOEX` for more information about these fields. *platform_version* returns the major version, minor version and @@ -948,28 +1016,37 @@ always available. implementation. For more details about hashing of numeric types, see :ref:`numeric-hash`. - +---------------------+--------------------------------------------------+ - | attribute | explanation | - +=====================+==================================================+ - | :const:`width` | width in bits used for hash values | - +---------------------+--------------------------------------------------+ - | :const:`modulus` | prime modulus P used for numeric hash scheme | - +---------------------+--------------------------------------------------+ - | :const:`inf` | hash value returned for a positive infinity | - +---------------------+--------------------------------------------------+ - | :const:`nan` | (this attribute is no longer used) | - +---------------------+--------------------------------------------------+ - | :const:`imag` | multiplier used for the imaginary part of a | - | | complex number | - +---------------------+--------------------------------------------------+ - | :const:`algorithm` | name of the algorithm for hashing of str, bytes, | - | | and memoryview | - +---------------------+--------------------------------------------------+ - | :const:`hash_bits` | internal output size of the hash algorithm | - +---------------------+--------------------------------------------------+ - | :const:`seed_bits` | size of the seed key of the hash algorithm | - +---------------------+--------------------------------------------------+ + .. attribute:: hash_info.width + + The width in bits used for hash values + + .. attribute:: hash_info.modulus + + The prime modulus P used for numeric hash scheme + + .. attribute:: hash_info.inf + + The hash value returned for a positive infinity + + .. attribute:: hash_info.nan + + (This attribute is no longer used) + + .. attribute:: hash_info.imag + + The multiplier used for the imaginary part of a complex number + + .. attribute:: hash_info.algorithm + + The name of the algorithm for hashing of str, bytes, and memoryview + + .. attribute:: hash_info.hash_bits + + The internal output size of the hash algorithm + + .. attribute:: hash_info.seed_bits + The size of the seed key of the hash algorithm .. versionadded:: 3.2 @@ -1047,32 +1124,31 @@ always available. A :term:`named tuple` that holds information about Python's internal representation of integers. The attributes are read only. - .. tabularcolumns:: |l|L| - - +----------------------------------------+-----------------------------------------------+ - | Attribute | Explanation | - +========================================+===============================================+ - | :const:`bits_per_digit` | number of bits held in each digit. Python | - | | integers are stored internally in base | - | | ``2**int_info.bits_per_digit`` | - +----------------------------------------+-----------------------------------------------+ - | :const:`sizeof_digit` | size in bytes of the C type used to | - | | represent a digit | - +----------------------------------------+-----------------------------------------------+ - | :const:`default_max_str_digits` | default value for | - | | :func:`sys.get_int_max_str_digits` when it | - | | is not otherwise explicitly configured. | - +----------------------------------------+-----------------------------------------------+ - | :const:`str_digits_check_threshold` | minimum non-zero value for | - | | :func:`sys.set_int_max_str_digits`, | - | | :envvar:`PYTHONINTMAXSTRDIGITS`, or | - | | :option:`-X int_max_str_digits <-X>`. | - +----------------------------------------+-----------------------------------------------+ + .. attribute:: int_info.bits_per_digit + + The number of bits held in each digit. + Python integers are stored internally in base ``2**int_info.bits_per_digit``. + + .. attribute:: int_info.sizeof_digit + + The size in bytes of the C type used to represent a digit. + + .. attribute:: int_info.default_max_str_digits + + The default value for :func:`sys.get_int_max_str_digits` + when it is not otherwise explicitly configured. + + .. attribute:: int_info.str_digits_check_threshold + + The minimum non-zero value for :func:`sys.set_int_max_str_digits`, + :envvar:`PYTHONINTMAXSTRDIGITS`, or :option:`-X int_max_str_digits <-X>`. .. versionadded:: 3.1 .. versionchanged:: 3.11 - Added ``default_max_str_digits`` and ``str_digits_check_threshold``. + + Added :attr:`~int_info.default_max_str_digits` and + :attr:`~int_info.str_digits_check_threshold`. .. data:: __interactivehook__ @@ -1108,8 +1184,8 @@ always available. .. function:: is_finalizing() - Return :const:`True` if the Python interpreter is - :term:`shutting down `, :const:`False` otherwise. + Return :const:`True` if the main Python interpreter is + :term:`shutting down `. Return :const:`False` otherwise. .. versionadded:: 3.5 @@ -1287,20 +1363,20 @@ always available. ================ =========================== .. versionchanged:: 3.3 - On Linux, :attr:`sys.platform` doesn't contain the major version anymore. + On Linux, :data:`sys.platform` doesn't contain the major version anymore. It is always ``'linux'``, instead of ``'linux2'`` or ``'linux3'``. Since older Python versions include the version number, it is recommended to always use the ``startswith`` idiom presented above. .. versionchanged:: 3.8 - On AIX, :attr:`sys.platform` doesn't contain the major version anymore. + On AIX, :data:`sys.platform` doesn't contain the major version anymore. It is always ``'aix'``, instead of ``'aix5'`` or ``'aix7'``. Since older Python versions include the version number, it is recommended to always use the ``startswith`` idiom presented above. .. seealso:: - :attr:`os.name` has a coarser granularity. :func:`os.uname` gives + :data:`os.name` has a coarser granularity. :func:`os.uname` gives system-dependent version information. The :mod:`platform` module provides detailed checks for the @@ -1367,8 +1443,8 @@ always available. lazy resolving of symbols when importing a module, if called as ``sys.setdlopenflags(0)``. To share symbols across extension modules, call as ``sys.setdlopenflags(os.RTLD_GLOBAL)``. Symbolic names for the flag values - can be found in the :mod:`os` module (``RTLD_xxx`` constants, e.g. - :data:`os.RTLD_LAZY`). + can be found in the :mod:`os` module (:samp:`RTLD_{xxx}` constants, e.g. + :const:`os.RTLD_LAZY`). .. availability:: Unix. @@ -1499,7 +1575,7 @@ always available. :file:`Objects/lnotab_notes.txt` for a detailed explanation of how this works. Per-line events may be disabled for a frame by setting - :attr:`f_trace_lines` to :const:`False` on that frame. + :attr:`!f_trace_lines` to :const:`False` on that :ref:`frame `. ``'return'`` A function (or other code block) is about to return. The local trace @@ -1517,8 +1593,8 @@ always available. opcode details). The local trace function is called; *arg* is ``None``; the return value specifies the new local trace function. Per-opcode events are not emitted by default: they must be explicitly - requested by setting :attr:`f_trace_opcodes` to :const:`True` on the - frame. + requested by setting :attr:`!f_trace_opcodes` to :const:`True` on the + :ref:`frame `. Note that as an exception is propagated down the chain of callers, an ``'exception'`` event is generated at each level. @@ -1547,8 +1623,8 @@ always available. .. versionchanged:: 3.7 - ``'opcode'`` event type added; :attr:`f_trace_lines` and - :attr:`f_trace_opcodes` attributes added to frames + ``'opcode'`` event type added; :attr:`!f_trace_lines` and + :attr:`!f_trace_opcodes` attributes added to frames .. function:: set_asyncgen_hooks(firstiter, finalizer) @@ -1705,7 +1781,7 @@ always available. However, if you are writing a library (and do not control in which context its code will be executed), be aware that the standard streams may be replaced with file-like objects like :class:`io.StringIO` which - do not support the :attr:`~io.BufferedIOBase.buffer` attribute. + do not support the :attr:!buffer` attribute. .. data:: __stdin__ @@ -1743,7 +1819,7 @@ always available. ``email.mime`` sub-package and the ``email.message`` sub-module are not listed. - See also the :attr:`sys.builtin_module_names` list. + See also the :data:`sys.builtin_module_names` list. .. versionadded:: 3.10 @@ -1753,29 +1829,28 @@ always available. A :term:`named tuple` holding information about the thread implementation. - .. tabularcolumns:: |l|p{0.7\linewidth}| - - +------------------+---------------------------------------------------------+ - | Attribute | Explanation | - +==================+=========================================================+ - | :const:`name` | Name of the thread implementation: | - | | | - | | * ``'nt'``: Windows threads | - | | * ``'pthread'``: POSIX threads | - | | * ``'pthread-stubs'``: stub POSIX threads | - | | (on WebAssembly platforms without threading support) | - | | * ``'solaris'``: Solaris threads | - +------------------+---------------------------------------------------------+ - | :const:`lock` | Name of the lock implementation: | - | | | - | | * ``'semaphore'``: a lock uses a semaphore | - | | * ``'mutex+cond'``: a lock uses a mutex | - | | and a condition variable | - | | * ``None`` if this information is unknown | - +------------------+---------------------------------------------------------+ - | :const:`version` | Name and version of the thread library. It is a string, | - | | or ``None`` if this information is unknown. | - +------------------+---------------------------------------------------------+ + .. attribute:: thread_info.name + + The name of the thread implementation: + + * ``"nt"``: Windows threads + * ``"pthread"``: POSIX threads + * ``"pthread-stubs"``: stub POSIX threads + (on WebAssembly platforms without threading support) + * ``"solaris"``: Solaris threads + + .. attribute:: thread_info.lock + + The name of the lock implementation: + + * ``"semaphore"``: a lock uses a semaphore + * ``"mutex+cond"``: a lock uses a mutex and a condition variable + * ``None`` if this information is unknown + + .. attribute:: thread_info.version + + The name and version of the thread library. + It is a string, or ``None`` if this information is unknown. .. versionadded:: 3.3 @@ -1798,35 +1873,39 @@ always available. The *unraisable* argument has the following attributes: - * *exc_type*: Exception type. - * *exc_value*: Exception value, can be ``None``. - * *exc_traceback*: Exception traceback, can be ``None``. - * *err_msg*: Error message, can be ``None``. - * *object*: Object causing the exception, can be ``None``. + * :attr:`!exc_type`: Exception type. + * :attr:`!exc_value`: Exception value, can be ``None``. + * :attr:`!exc_traceback`: Exception traceback, can be ``None``. + * :attr:`!err_msg`: Error message, can be ``None``. + * :attr:`!object`: Object causing the exception, can be ``None``. - The default hook formats *err_msg* and *object* as: + The default hook formats :attr:`!err_msg` and :attr:`!object` as: ``f'{err_msg}: {object!r}'``; use "Exception ignored in" error message - if *err_msg* is ``None``. + if :attr:`!err_msg` is ``None``. :func:`sys.unraisablehook` can be overridden to control how unraisable exceptions are handled. - Storing *exc_value* using a custom hook can create a reference cycle. It - should be cleared explicitly to break the reference cycle when the - exception is no longer needed. + .. seealso:: + + :func:`excepthook` which handles uncaught exceptions. + + .. warning:: - Storing *object* using a custom hook can resurrect it if it is set to an - object which is being finalized. Avoid storing *object* after the custom - hook completes to avoid resurrecting objects. + Storing :attr:`!exc_value` using a custom hook can create a reference cycle. + It should be cleared explicitly to break the reference cycle when the + exception is no longer needed. - See also :func:`excepthook` which handles uncaught exceptions. + Storing :attr:`!object` using a custom hook can resurrect it if it is set to an + object which is being finalized. Avoid storing :attr:`!object` after the custom + hook completes to avoid resurrecting objects. .. audit-event:: sys.unraisablehook hook,unraisable sys.unraisablehook Raise an auditing event ``sys.unraisablehook`` with arguments - ``hook``, ``unraisable`` when an exception that cannot be handled occurs. - The ``unraisable`` object is the same as what will be passed to the hook. - If no hook has been set, ``hook`` may be ``None``. + *hook*, *unraisable* when an exception that cannot be handled occurs. + The *unraisable* object is the same as what will be passed to the hook. + If no hook has been set, *hook* may be ``None``. .. versionadded:: 3.8 @@ -1876,6 +1955,13 @@ always available. .. availability:: Windows. +.. data:: monitoring + :noindex: + + Namespace containing functions and constants for register callbacks + and controlling monitoring events. + See :mod:`sys.monitoring` for details. + .. data:: _xoptions A dictionary of the various implementation-specific flags passed through diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index 839c2c015b49ae..905abc3a7c9f9b 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -20,6 +20,7 @@ The :mod:`sysconfig` module provides access to Python's configuration information like the list of installation paths and the configuration variables relevant for the current platform. + Configuration variables ----------------------- @@ -60,6 +61,7 @@ Example of usage:: >>> sysconfig.get_config_vars('AR', 'CXX') ['ar', 'g++'] + .. _installation_paths: Installation paths @@ -68,29 +70,26 @@ Installation paths Python uses an installation scheme that differs depending on the platform and on the installation options. These schemes are stored in :mod:`sysconfig` under unique identifiers based on the value returned by :const:`os.name`. - -Every new component that is installed using :mod:`distutils` or a -Distutils-based system will follow the same scheme to copy its file in the right -places. +The schemes are used by package installers to determine where to copy files to. Python currently supports nine schemes: - *posix_prefix*: scheme for POSIX platforms like Linux or macOS. This is the default scheme used when Python or a component is installed. -- *posix_home*: scheme for POSIX platforms used when a *home* option is used - upon installation. This scheme is used when a component is installed through - Distutils with a specific home prefix. -- *posix_user*: scheme for POSIX platforms used when a component is installed - through Distutils and the *user* option is used. This scheme defines paths - located under the user home directory. +- *posix_home*: scheme for POSIX platforms, when the *home* option is used. + This scheme defines paths located under a specific home prefix. +- *posix_user*: scheme for POSIX platforms, when the *user* option is used. + This scheme defines paths located under the user's home directory + (:const:`site.USER_BASE`). - *posix_venv*: scheme for :mod:`Python virtual environments ` on POSIX - platforms; by default it is the same as *posix_prefix* . -- *nt*: scheme for NT platforms like Windows. -- *nt_user*: scheme for NT platforms, when the *user* option is used. -- *nt_venv*: scheme for :mod:`Python virtual environments ` on NT - platforms; by default it is the same as *nt* . -- *venv*: a scheme with values from ether *posix_venv* or *nt_venv* depending - on the platform Python runs on + platforms; by default it is the same as *posix_prefix*. +- *nt*: scheme for Windows. + This is the default scheme used when Python or a component is installed. +- *nt_user*: scheme for Windows, when the *user* option is used. +- *nt_venv*: scheme for :mod:`Python virtual environments ` on Windows; + by default it is the same as *nt*. +- *venv*: a scheme with values from either *posix_venv* or *nt_venv* depending + on the platform Python runs on. - *osx_framework_user*: scheme for macOS, when the *user* option is used. Each scheme is itself composed of a series of paths and each path has a unique @@ -101,7 +100,7 @@ identifier. Python currently uses eight paths: - *platstdlib*: directory containing the standard Python library files that are platform-specific. - *platlib*: directory for site-specific, platform-specific files. -- *purelib*: directory for site-specific, non-platform-specific files. +- *purelib*: directory for site-specific, non-platform-specific files ('pure' Python). - *include*: directory for non-platform-specific header files for the Python C-API. - *platinclude*: directory for platform-specific header files for @@ -109,7 +108,157 @@ identifier. Python currently uses eight paths: - *scripts*: directory for script files. - *data*: directory for data files. -:mod:`sysconfig` provides some functions to determine these paths. + +.. _sysconfig-user-scheme: + +User scheme +--------------- + +This scheme is designed to be the most convenient solution for users that don't +have write permission to the global site-packages directory or don't want to +install into it. + +Files will be installed into subdirectories of :const:`site.USER_BASE` (written +as :file:`{userbase}` hereafter). This scheme installs pure Python modules and +extension modules in the same location (also known as :const:`site.USER_SITE`). + +``posix_user`` +^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}/lib/python{X.Y}` +*platstdlib* :file:`{userbase}/lib/python{X.Y}` +*platlib* :file:`{userbase}/lib/python{X.Y}/site-packages` +*purelib* :file:`{userbase}/lib/python{X.Y}/site-packages` +*include* :file:`{userbase}/include/python{X.Y}` +*scripts* :file:`{userbase}/bin` +*data* :file:`{userbase}` +============== =========================================================== + +``nt_user`` +^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}\\Python{XY}` +*platstdlib* :file:`{userbase}\\Python{XY}` +*platlib* :file:`{userbase}\\Python{XY}\\site-packages` +*purelib* :file:`{userbase}\\Python{XY}\\site-packages` +*include* :file:`{userbase}\\Python{XY}\\Include` +*scripts* :file:`{userbase}\\Python{XY}\\Scripts` +*data* :file:`{userbase}` +============== =========================================================== + +``osx_framework_user`` +^^^^^^^^^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}/lib/python` +*platstdlib* :file:`{userbase}/lib/python` +*platlib* :file:`{userbase}/lib/python/site-packages` +*purelib* :file:`{userbase}/lib/python/site-packages` +*include* :file:`{userbase}/include/python{X.Y}` +*scripts* :file:`{userbase}/bin` +*data* :file:`{userbase}` +============== =========================================================== + + +.. _sysconfig-home-scheme: + +Home scheme +----------- + +The idea behind the "home scheme" is that you build and maintain a personal +stash of Python modules. This scheme's name is derived from the idea of a +"home" directory on Unix, since it's not unusual for a Unix user to make their +home directory have a layout similar to :file:`/usr/` or :file:`/usr/local/`. +This scheme can be used by anyone, regardless of the operating system they +are installing for. + +``posix_home`` +^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{home}/lib/python` +*platstdlib* :file:`{home}/lib/python` +*platlib* :file:`{home}/lib/python` +*purelib* :file:`{home}/lib/python` +*include* :file:`{home}/include/python` +*platinclude* :file:`{home}/include/python` +*scripts* :file:`{home}/bin` +*data* :file:`{home}` +============== =========================================================== + + +.. _sysconfig-prefix-scheme: + +Prefix scheme +------------- + +The "prefix scheme" is useful when you wish to use one Python installation to +perform the build/install (i.e., to run the setup script), but install modules +into the third-party module directory of a different Python installation (or +something that looks like a different Python installation). If this sounds a +trifle unusual, it is---that's why the user and home schemes come before. However, +there are at least two known cases where the prefix scheme will be useful. + +First, consider that many Linux distributions put Python in :file:`/usr`, rather +than the more traditional :file:`/usr/local`. This is entirely appropriate, +since in those cases Python is part of "the system" rather than a local add-on. +However, if you are installing Python modules from source, you probably want +them to go in :file:`/usr/local/lib/python2.{X}` rather than +:file:`/usr/lib/python2.{X}`. + +Another possibility is a network filesystem where the name used to write to a +remote directory is different from the name used to read it: for example, the +Python interpreter accessed as :file:`/usr/local/bin/python` might search for +modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to +be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. + +``posix_prefix`` +^^^^^^^^^^^^^^^^ + +============== ========================================================== +Path Installation directory +============== ========================================================== +*stdlib* :file:`{prefix}/lib/python{X.Y}` +*platstdlib* :file:`{prefix}/lib/python{X.Y}` +*platlib* :file:`{prefix}/lib/python{X.Y}/site-packages` +*purelib* :file:`{prefix}/lib/python{X.Y}/site-packages` +*include* :file:`{prefix}/include/python{X.Y}` +*platinclude* :file:`{prefix}/include/python{X.Y}` +*scripts* :file:`{prefix}/bin` +*data* :file:`{prefix}` +============== ========================================================== + +``nt`` +^^^^^^ + +============== ========================================================== +Path Installation directory +============== ========================================================== +*stdlib* :file:`{prefix}\\Lib` +*platstdlib* :file:`{prefix}\\Lib` +*platlib* :file:`{prefix}\\Lib\\site-packages` +*purelib* :file:`{prefix}\\Lib\\site-packages` +*include* :file:`{prefix}\\Include` +*platinclude* :file:`{prefix}\\Include` +*scripts* :file:`{prefix}\\Scripts` +*data* :file:`{prefix}` +============== ========================================================== + + +Installation path functions +--------------------------- + +:mod:`sysconfig` provides some functions to determine these installation paths. .. function:: get_scheme_names() @@ -187,7 +336,7 @@ identifier. Python currently uses eight paths: platform is used. If *vars* is provided, it must be a dictionary of variables that will update - the dictionary return by :func:`get_config_vars`. + the dictionary returned by :func:`get_config_vars`. If *expand* is set to ``False``, the path will not be expanded using the variables. @@ -278,6 +427,7 @@ Other functions Return the path of :file:`Makefile`. +.. _sysconfig-cli: Using :mod:`sysconfig` as a script ---------------------------------- diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index fd4820e78d68d1..3e5723a66780ca 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -740,6 +740,11 @@ A ``TarInfo`` object has the following public data attributes: Name of the target file name, which is only present in :class:`TarInfo` objects of type :const:`LNKTYPE` and :const:`SYMTYPE`. + For symbolic links (``SYMTYPE``), the *linkname* is relative to the directory + that contains the link. + For hard links (``LNKTYPE``), the *linkname* is relative to the root of + the archive. + .. attribute:: TarInfo.uid :type: int @@ -938,7 +943,7 @@ reused in custom filters: Implements the ``'tar'`` filter. - - Strip leading slashes (``/`` and :attr:`os.sep`) from filenames. + - Strip leading slashes (``/`` and :data:`os.sep`) from filenames. - :ref:`Refuse ` to extract files with absolute paths (in case the name is absolute even after stripping slashes, e.g. ``C:/foo`` on Windows). @@ -947,7 +952,7 @@ reused in custom filters: path (after following symlinks) would end up outside the destination. This raises :class:`~tarfile.OutsideDestinationError`. - Clear high mode bits (setuid, setgid, sticky) and group/other write bits - (:attr:`~stat.S_IWGRP`|:attr:`~stat.S_IWOTH`). + (:const:`~stat.S_IWGRP`|:const:`~stat.S_IWOTH`). Return the modified ``TarInfo`` member. @@ -972,10 +977,10 @@ reused in custom filters: - For regular files, including hard links: - Set the owner read and write permissions - (:attr:`~stat.S_IRUSR`|:attr:`~stat.S_IWUSR`). + (:const:`~stat.S_IRUSR`|:const:`~stat.S_IWUSR`). - Remove the group & other executable permission - (:attr:`~stat.S_IXGRP`|:attr:`~stat.S_IXOTH`) - if the owner doesn’t have it (:attr:`~stat.S_IXUSR`). + (:const:`~stat.S_IXGRP`|:const:`~stat.S_IXOTH`) + if the owner doesn’t have it (:const:`~stat.S_IXUSR`). - For other files (directories), set ``mode`` to ``None``, so that extraction methods skip applying permission bits. @@ -1151,31 +1156,31 @@ For a list of the files in a tar archive, use the :option:`-l` option: Command-line options ~~~~~~~~~~~~~~~~~~~~ -.. cmdoption:: -l - --list +.. option:: -l + --list List files in a tarfile. -.. cmdoption:: -c ... - --create ... +.. option:: -c ... + --create ... Create tarfile from source files. -.. cmdoption:: -e [] - --extract [] +.. option:: -e [] + --extract [] Extract tarfile into the current directory if *output_dir* is not specified. -.. cmdoption:: -t - --test +.. option:: -t + --test Test whether the tarfile is valid or not. -.. cmdoption:: -v, --verbose +.. option:: -v, --verbose Verbose output. -.. cmdoption:: --filter +.. option:: --filter Specifies the *filter* for ``--extract``. See :ref:`tarfile-extraction-filter` for details. diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index fd4c294613fd31..42314648fec2bd 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -59,7 +59,7 @@ The module defines the following user-callable items: platforms, it is a file-like object whose :attr:`!file` attribute is the underlying true file object. - The :py:data:`os.O_TMPFILE` flag is used if it is available and works + The :py:const:`os.O_TMPFILE` flag is used if it is available and works (Linux-specific, requires Linux kernel 3.11 or later). On platforms that are neither Posix nor Cygwin, TemporaryFile is an alias @@ -69,7 +69,7 @@ The module defines the following user-callable items: .. versionchanged:: 3.5 - The :py:data:`os.O_TMPFILE` flag is now used if available. + The :py:const:`os.O_TMPFILE` flag is now used if available. .. versionchanged:: 3.8 Added *errors* parameter. @@ -115,14 +115,14 @@ The module defines the following user-callable items: * On Windows, make sure that at least one of the following conditions are fulfilled: - * *delete* is false - * additional open shares delete access (e.g. by calling :func:`os.open` - with the flag ``O_TEMPORARY``) - * *delete* is true but *delete_on_close* is false. Note, that in this - case the additional opens that do not share delete access (e.g. - created via builtin :func:`open`) must be closed before exiting the - context manager, else the :func:`os.unlink` call on context manager - exit will fail with a :exc:`PermissionError`. + * *delete* is false + * additional open shares delete access (e.g. by calling :func:`os.open` + with the flag ``O_TEMPORARY``) + * *delete* is true but *delete_on_close* is false. Note, that in this + case the additional opens that do not share delete access (e.g. + created via builtin :func:`open`) must be closed before exiting the + context manager, else the :func:`os.unlink` call on context manager + exit will fail with a :exc:`PermissionError`. On Windows, if *delete_on_close* is false, and the file is created in a directory for which the user lacks delete access, then the :func:`os.unlink` diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 1b045c7de83a80..de60151bb32ce1 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -472,7 +472,7 @@ The :mod:`test.support` module defines the following functions: .. function:: with_pymalloc() - Return :data:`_testcapi.WITH_PYMALLOC`. + Return :const:`_testcapi.WITH_PYMALLOC`. .. function:: requires(resource, msg=None) @@ -1040,7 +1040,7 @@ The :mod:`test.support` module defines the following classes: `SetErrorMode `_. On UNIX, :func:`resource.setrlimit` is used to set - :attr:`resource.RLIMIT_CORE`'s soft limit to 0 to prevent coredump file + :const:`resource.RLIMIT_CORE`'s soft limit to 0 to prevent coredump file creation. On both platforms, the old value is restored by :meth:`__exit__`. diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 1a9d5f98f78a7e..7445410f91808c 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -60,7 +60,7 @@ functions should be good enough; otherwise, you should use an instance of First the whitespace in *text* is collapsed (all whitespace is replaced by single spaces). If the result fits in the *width*, it is returned. Otherwise, enough words are dropped from the end so that the remaining words - plus the :attr:`placeholder` fit within :attr:`width`:: + plus the *placeholder* fit within *width*:: >>> textwrap.shorten("Hello world!", width=12) 'Hello world!' @@ -173,7 +173,7 @@ hyphenated words; only then will long words be broken if necessary, unless .. attribute:: expand_tabs (default: ``True``) If true, then all tab characters in *text* will be - expanded to spaces using the :meth:`expandtabs` method of *text*. + expanded to spaces using the :meth:`~str.expandtabs` method of *text*. .. attribute:: tabsize @@ -238,7 +238,7 @@ hyphenated words; only then will long words be broken if necessary, unless However, the sentence detection algorithm is imperfect: it assumes that a sentence ending consists of a lowercase letter followed by one of ``'.'``, ``'!'``, or ``'?'``, possibly followed by one of ``'"'`` or ``"'"``, - followed by a space. One problem with this is algorithm is that it is + followed by a space. One problem with this algorithm is that it is unable to detect the difference between "Dr." in :: [...] Dr. Frankenstein's monster [...] diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 83ed48052704fb..23d8cd158abd5d 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -272,7 +272,7 @@ The instance's values will be different for separate threads. A class that represents thread-local data. For more details and extensive examples, see the documentation string of the - :mod:`_threading_local` module: :source:`Lib/_threading_local.py`. + :mod:`!_threading_local` module: :source:`Lib/_threading_local.py`. .. _thread-objects: @@ -285,7 +285,7 @@ thread of control. There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the :meth:`~Thread.run` method in a subclass. No other methods (except for the constructor) should be overridden in a subclass. In other words, *only* override the -:meth:`~Thread.__init__` and :meth:`~Thread.run` methods of this class. +``__init__()`` and :meth:`~Thread.run` methods of this class. Once a thread object is created, its activity must be started by calling the thread's :meth:`~Thread.start` method. This invokes the :meth:`~Thread.run` @@ -337,7 +337,7 @@ since it is impossible to detect the termination of alien threads. are: *group* should be ``None``; reserved for future extension when a - :class:`ThreadGroup` class is implemented. + :class:`!ThreadGroup` class is implemented. *target* is the callable object to be invoked by the :meth:`run` method. Defaults to ``None``, meaning nothing is called. @@ -1009,7 +1009,7 @@ This class represents an action that should be run only after a certain amount of time has passed --- a timer. :class:`Timer` is a subclass of :class:`Thread` and as such also functions as an example of creating custom threads. -Timers are started, as with threads, by calling their :meth:`~Timer.start` +Timers are started, as with threads, by calling their :meth:`Timer.start ` method. The timer can be stopped (before its action has begun) by calling the :meth:`~Timer.cancel` method. The interval the timer will wait before executing its action may not be exactly the same as the interval specified by @@ -1147,10 +1147,10 @@ As an example, here is a simple way to synchronize a client and server thread:: Using locks, conditions, and semaphores in the :keyword:`!with` statement ------------------------------------------------------------------------- -All of the objects provided by this module that have :meth:`acquire` and -:meth:`release` methods can be used as context managers for a :keyword:`with` -statement. The :meth:`acquire` method will be called when the block is -entered, and :meth:`release` will be called when the block is exited. Hence, +All of the objects provided by this module that have ``acquire`` and +``release`` methods can be used as context managers for a :keyword:`with` +statement. The ``acquire`` method will be called when the block is +entered, and ``release`` will be called when the block is exited. Hence, the following snippet:: with some_lock: diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 9f23a6fc7d5341..6ffe4ac4284140 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -379,6 +379,8 @@ Functions * Or use ``nanosleep()`` if available (resolution: 1 nanosecond); * Or use ``select()`` (resolution: 1 microsecond). + .. audit-event:: time.sleep secs + .. versionchanged:: 3.11 On Unix, the ``clock_nanosleep()`` and ``nanosleep()`` functions are now used if available. On Windows, a waitable timer is now used. @@ -389,6 +391,9 @@ Functions :pep:`475` for the rationale). + .. versionchanged:: 3.13 + Raises an auditing event. + .. index:: single: % (percent); datetime format diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index a559e0a2eb3dad..616f8365b80f6c 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -86,9 +86,11 @@ The module defines three convenience functions and a public class: .. versionchanged:: 3.7 Default value of *repeat* changed from 3 to 5. + .. function:: default_timer() - The default timer, which is always :func:`time.perf_counter`. + The default timer, which is always time.perf_counter(), returns float seconds. + An alternative, time.perf_counter_ns, returns integer nanoseconds. .. versionchanged:: 3.3 :func:`time.perf_counter` is now the default timer. @@ -124,7 +126,7 @@ The module defines three convenience functions and a public class: Time *number* executions of the main statement. This executes the setup statement once, and then returns the time it takes to execute the main - statement a number of times, measured in seconds as a float. + statement a number of times. The default timer returns seconds as a float. The argument is the number of times through the loop, defaulting to one million. The main statement, the setup statement and the timer function to be used are passed to the constructor. @@ -149,7 +151,7 @@ The module defines three convenience functions and a public class: so that the total time >= 0.2 second, returning the eventual (number of loops, time taken for that number of loops). It calls :meth:`.timeit` with increasing numbers from the sequence 1, 2, 5, - 10, 20, 50, ... until the time taken is at least 0.2 second. + 10, 20, 50, ... until the time taken is at least 0.2 seconds. If *callback* is given and is not ``None``, it will be called after each trial with two arguments: ``callback(number, time_taken)``. @@ -212,36 +214,36 @@ Where the following options are understood: .. program:: timeit -.. cmdoption:: -n N, --number=N +.. option:: -n N, --number=N how many times to execute 'statement' -.. cmdoption:: -r N, --repeat=N +.. option:: -r N, --repeat=N how many times to repeat the timer (default 5) -.. cmdoption:: -s S, --setup=S +.. option:: -s S, --setup=S statement to be executed once initially (default ``pass``) -.. cmdoption:: -p, --process +.. option:: -p, --process measure process time, not wallclock time, using :func:`time.process_time` instead of :func:`time.perf_counter`, which is the default .. versionadded:: 3.3 -.. cmdoption:: -u, --unit=U +.. option:: -u, --unit=U specify a time unit for timer output; can select ``nsec``, ``usec``, ``msec``, or ``sec`` .. versionadded:: 3.5 -.. cmdoption:: -v, --verbose +.. option:: -v, --verbose print raw timing results; repeat for more digits precision -.. cmdoption:: -h, --help +.. option:: -h, --help print a short usage message and exit diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 988b0cf3d70663..5fab26db67633c 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -163,7 +163,7 @@ the modern themed widget set and API:: interpreter and calls :func:`exec` on the contents of :file:`.{className}.py` and :file:`.{baseName}.py`. The path for the profile files is the :envvar:`HOME` environment variable or, if that - isn't defined, then :attr:`os.curdir`. + isn't defined, then :data:`os.curdir`. .. attribute:: tk @@ -348,7 +348,7 @@ Understanding How Tkinter Wraps Tcl/Tk When your application uses Tkinter's classes and methods, internally Tkinter is assembling strings representing Tcl/Tk commands, and executing those -commands in the Tcl interpreter attached to your applicaton's :class:`Tk` +commands in the Tcl interpreter attached to your application's :class:`Tk` instance. Whether it's trying to navigate reference documentation, trying to find @@ -529,24 +529,24 @@ interpreter will fail. A number of special cases exist: - * Tcl/Tk libraries can be built so they are not thread-aware. In this case, - :mod:`tkinter` calls the library from the originating Python thread, even - if this is different than the thread that created the Tcl interpreter. A global - lock ensures only one call occurs at a time. +* Tcl/Tk libraries can be built so they are not thread-aware. In this case, + :mod:`tkinter` calls the library from the originating Python thread, even + if this is different than the thread that created the Tcl interpreter. A global + lock ensures only one call occurs at a time. - * While :mod:`tkinter` allows you to create more than one instance of a :class:`Tk` - object (with its own interpreter), all interpreters that are part of the same - thread share a common event queue, which gets ugly fast. In practice, don't create - more than one instance of :class:`Tk` at a time. Otherwise, it's best to create - them in separate threads and ensure you're running a thread-aware Tcl/Tk build. +* While :mod:`tkinter` allows you to create more than one instance of a :class:`Tk` + object (with its own interpreter), all interpreters that are part of the same + thread share a common event queue, which gets ugly fast. In practice, don't create + more than one instance of :class:`Tk` at a time. Otherwise, it's best to create + them in separate threads and ensure you're running a thread-aware Tcl/Tk build. - * Blocking event handlers are not the only way to prevent the Tcl interpreter from - reentering the event loop. It is even possible to run multiple nested event loops - or abandon the event loop entirely. If you're doing anything tricky when it comes - to events or threads, be aware of these possibilities. +* Blocking event handlers are not the only way to prevent the Tcl interpreter from + reentering the event loop. It is even possible to run multiple nested event loops + or abandon the event loop entirely. If you're doing anything tricky when it comes + to events or threads, be aware of these possibilities. - * There are a few select :mod:`tkinter` functions that presently work only when - called from the thread that created the Tcl interpreter. +* There are a few select :mod:`tkinter` functions that presently work only when + called from the thread that created the Tcl interpreter. Handy Reference diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 4ff2b2159c3622..dc31a1a4c1850a 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -102,35 +102,35 @@ themed widgets and is not supposed to be directly instantiated. Standard Options ^^^^^^^^^^^^^^^^ -All the :mod:`ttk` Widgets accepts the following options: - - .. tabularcolumns:: |l|L| - - +-----------+--------------------------------------------------------------+ - | Option | Description | - +===========+==============================================================+ - | class | Specifies the window class. The class is used when querying | - | | the option database for the window's other options, to | - | | determine the default bindtags for the window, and to select | - | | the widget's default layout and style. This option is | - | | read-only, and may only be specified when the window is | - | | created. | - +-----------+--------------------------------------------------------------+ - | cursor | Specifies the mouse cursor to be used for the widget. If set | - | | to the empty string (the default), the cursor is inherited | - | | for the parent widget. | - +-----------+--------------------------------------------------------------+ - | takefocus | Determines whether the window accepts the focus during | - | | keyboard traversal. 0, 1 or an empty string is returned. | - | | If 0 is returned, it means that the window should be skipped | - | | entirely during keyboard traversal. If 1, it means that the | - | | window should receive the input focus as long as it is | - | | viewable. And an empty string means that the traversal | - | | scripts make the decision about whether or not to focus | - | | on the window. | - +-----------+--------------------------------------------------------------+ - | style | May be used to specify a custom widget style. | - +-----------+--------------------------------------------------------------+ +All the :mod:`ttk` Widgets accept the following options: + +.. tabularcolumns:: |l|L| + ++-----------+--------------------------------------------------------------+ +| Option | Description | ++===========+==============================================================+ +| class | Specifies the window class. The class is used when querying | +| | the option database for the window's other options, to | +| | determine the default bindtags for the window, and to select | +| | the widget's default layout and style. This option is | +| | read-only, and may only be specified when the window is | +| | created. | ++-----------+--------------------------------------------------------------+ +| cursor | Specifies the mouse cursor to be used for the widget. If set | +| | to the empty string (the default), the cursor is inherited | +| | for the parent widget. | ++-----------+--------------------------------------------------------------+ +| takefocus | Determines whether the window accepts the focus during | +| | keyboard traversal. 0, 1 or an empty string is returned. | +| | If 0 is returned, it means that the window should be skipped | +| | entirely during keyboard traversal. If 1, it means that the | +| | window should receive the input focus as long as it is | +| | viewable. And an empty string means that the traversal | +| | scripts make the decision about whether or not to focus | +| | on the window. | ++-----------+--------------------------------------------------------------+ +| style | May be used to specify a custom widget style. | ++-----------+--------------------------------------------------------------+ Scrollable Widget Options @@ -139,24 +139,24 @@ Scrollable Widget Options The following options are supported by widgets that are controlled by a scrollbar. - .. tabularcolumns:: |l|L| - - +----------------+---------------------------------------------------------+ - | Option | Description | - +================+=========================================================+ - | xscrollcommand | Used to communicate with horizontal scrollbars. | - | | | - | | When the view in the widget's window change, the widget | - | | will generate a Tcl command based on the scrollcommand. | - | | | - | | Usually this option consists of the method | - | | :meth:`Scrollbar.set` of some scrollbar. This will cause| - | | the scrollbar to be updated whenever the view in the | - | | window changes. | - +----------------+---------------------------------------------------------+ - | yscrollcommand | Used to communicate with vertical scrollbars. | - | | For some more information, see above. | - +----------------+---------------------------------------------------------+ +.. tabularcolumns:: |l|L| + ++----------------+---------------------------------------------------------+ +| Option | Description | ++================+=========================================================+ +| xscrollcommand | Used to communicate with horizontal scrollbars. | +| | | +| | When the view in the widget's window change, the widget | +| | will generate a Tcl command based on the scrollcommand. | +| | | +| | Usually this option consists of the method | +| | :meth:`Scrollbar.set` of some scrollbar. This will cause| +| | the scrollbar to be updated whenever the view in the | +| | window changes. | ++----------------+---------------------------------------------------------+ +| yscrollcommand | Used to communicate with vertical scrollbars. | +| | For some more information, see above. | ++----------------+---------------------------------------------------------+ Label Options @@ -165,93 +165,93 @@ Label Options The following options are supported by labels, buttons and other button-like widgets. - .. tabularcolumns:: |l|p{0.7\linewidth}| - - +--------------+-----------------------------------------------------------+ - | Option | Description | - +==============+===========================================================+ - | text | Specifies a text string to be displayed inside the widget.| - +--------------+-----------------------------------------------------------+ - | textvariable | Specifies a name whose value will be used in place of the | - | | text option resource. | - +--------------+-----------------------------------------------------------+ - | underline | If set, specifies the index (0-based) of a character to | - | | underline in the text string. The underline character is | - | | used for mnemonic activation. | - +--------------+-----------------------------------------------------------+ - | image | Specifies an image to display. This is a list of 1 or more| - | | elements. The first element is the default image name. The| - | | rest of the list if a sequence of statespec/value pairs as| - | | defined by :meth:`Style.map`, specifying different images | - | | to use when the widget is in a particular state or a | - | | combination of states. All images in the list should have | - | | the same size. | - +--------------+-----------------------------------------------------------+ - | compound | Specifies how to display the image relative to the text, | - | | in the case both text and images options are present. | - | | Valid values are: | - | | | - | | * text: display text only | - | | * image: display image only | - | | * top, bottom, left, right: display image above, below, | - | | left of, or right of the text, respectively. | - | | * none: the default. display the image if present, | - | | otherwise the text. | - +--------------+-----------------------------------------------------------+ - | width | If greater than zero, specifies how much space, in | - | | character widths, to allocate for the text label, if less | - | | than zero, specifies a minimum width. If zero or | - | | unspecified, the natural width of the text label is used. | - +--------------+-----------------------------------------------------------+ +.. tabularcolumns:: |l|p{0.7\linewidth}| + ++--------------+-----------------------------------------------------------+ +| Option | Description | ++==============+===========================================================+ +| text | Specifies a text string to be displayed inside the widget.| ++--------------+-----------------------------------------------------------+ +| textvariable | Specifies a name whose value will be used in place of the | +| | text option resource. | ++--------------+-----------------------------------------------------------+ +| underline | If set, specifies the index (0-based) of a character to | +| | underline in the text string. The underline character is | +| | used for mnemonic activation. | ++--------------+-----------------------------------------------------------+ +| image | Specifies an image to display. This is a list of 1 or more| +| | elements. The first element is the default image name. The| +| | rest of the list if a sequence of statespec/value pairs as| +| | defined by :meth:`Style.map`, specifying different images | +| | to use when the widget is in a particular state or a | +| | combination of states. All images in the list should have | +| | the same size. | ++--------------+-----------------------------------------------------------+ +| compound | Specifies how to display the image relative to the text, | +| | in the case both text and images options are present. | +| | Valid values are: | +| | | +| | * text: display text only | +| | * image: display image only | +| | * top, bottom, left, right: display image above, below, | +| | left of, or right of the text, respectively. | +| | * none: the default. display the image if present, | +| | otherwise the text. | ++--------------+-----------------------------------------------------------+ +| width | If greater than zero, specifies how much space, in | +| | character widths, to allocate for the text label, if less | +| | than zero, specifies a minimum width. If zero or | +| | unspecified, the natural width of the text label is used. | ++--------------+-----------------------------------------------------------+ Compatibility Options ^^^^^^^^^^^^^^^^^^^^^ - .. tabularcolumns:: |l|L| +.. tabularcolumns:: |l|L| - +--------+----------------------------------------------------------------+ - | Option | Description | - +========+================================================================+ - | state | May be set to "normal" or "disabled" to control the "disabled" | - | | state bit. This is a write-only option: setting it changes the | - | | widget state, but the :meth:`Widget.state` method does not | - | | affect this option. | - +--------+----------------------------------------------------------------+ ++--------+----------------------------------------------------------------+ +| Option | Description | ++========+================================================================+ +| state | May be set to "normal" or "disabled" to control the "disabled" | +| | state bit. This is a write-only option: setting it changes the | +| | widget state, but the :meth:`Widget.state` method does not | +| | affect this option. | ++--------+----------------------------------------------------------------+ Widget States ^^^^^^^^^^^^^ The widget state is a bitmap of independent state flags. - .. tabularcolumns:: |l|L| - - +------------+-------------------------------------------------------------+ - | Flag | Description | - +============+=============================================================+ - | active | The mouse cursor is over the widget and pressing a mouse | - | | button will cause some action to occur | - +------------+-------------------------------------------------------------+ - | disabled | Widget is disabled under program control | - +------------+-------------------------------------------------------------+ - | focus | Widget has keyboard focus | - +------------+-------------------------------------------------------------+ - | pressed | Widget is being pressed | - +------------+-------------------------------------------------------------+ - | selected | "On", "true", or "current" for things like Checkbuttons and | - | | radiobuttons | - +------------+-------------------------------------------------------------+ - | background | Windows and Mac have a notion of an "active" or foreground | - | | window. The *background* state is set for widgets in a | - | | background window, and cleared for those in the foreground | - | | window | - +------------+-------------------------------------------------------------+ - | readonly | Widget should not allow user modification | - +------------+-------------------------------------------------------------+ - | alternate | A widget-specific alternate display format | - +------------+-------------------------------------------------------------+ - | invalid | The widget's value is invalid | - +------------+-------------------------------------------------------------+ +.. tabularcolumns:: |l|L| + ++------------+-------------------------------------------------------------+ +| Flag | Description | ++============+=============================================================+ +| active | The mouse cursor is over the widget and pressing a mouse | +| | button will cause some action to occur | ++------------+-------------------------------------------------------------+ +| disabled | Widget is disabled under program control | ++------------+-------------------------------------------------------------+ +| focus | Widget has keyboard focus | ++------------+-------------------------------------------------------------+ +| pressed | Widget is being pressed | ++------------+-------------------------------------------------------------+ +| selected | "On", "true", or "current" for things like Checkbuttons and | +| | radiobuttons | ++------------+-------------------------------------------------------------+ +| background | Windows and Mac have a notion of an "active" or foreground | +| | window. The *background* state is set for widgets in a | +| | background window, and cleared for those in the foreground | +| | window | ++------------+-------------------------------------------------------------+ +| readonly | Widget should not allow user modification | ++------------+-------------------------------------------------------------+ +| alternate | A widget-specific alternate display format | ++------------+-------------------------------------------------------------+ +| invalid | The widget's value is invalid | ++------------+-------------------------------------------------------------+ A state specification is a sequence of state names, optionally prefixed with an exclamation point indicating that the bit is off. @@ -311,43 +311,43 @@ Options This widget accepts the following specific options: - .. tabularcolumns:: |l|L| - - +-----------------+--------------------------------------------------------+ - | Option | Description | - +=================+========================================================+ - | exportselection | Boolean value. If set, the widget selection is linked | - | | to the Window Manager selection (which can be returned | - | | by invoking Misc.selection_get, for example). | - +-----------------+--------------------------------------------------------+ - | justify | Specifies how the text is aligned within the widget. | - | | One of "left", "center", or "right". | - +-----------------+--------------------------------------------------------+ - | height | Specifies the height of the pop-down listbox, in rows. | - +-----------------+--------------------------------------------------------+ - | postcommand | A script (possibly registered with Misc.register) that | - | | is called immediately before displaying the values. It | - | | may specify which values to display. | - +-----------------+--------------------------------------------------------+ - | state | One of "normal", "readonly", or "disabled". In the | - | | "readonly" state, the value may not be edited directly,| - | | and the user can only selection of the values from the | - | | dropdown list. In the "normal" state, the text field is| - | | directly editable. In the "disabled" state, no | - | | interaction is possible. | - +-----------------+--------------------------------------------------------+ - | textvariable | Specifies a name whose value is linked to the widget | - | | value. Whenever the value associated with that name | - | | changes, the widget value is updated, and vice versa. | - | | See :class:`tkinter.StringVar`. | - +-----------------+--------------------------------------------------------+ - | values | Specifies the list of values to display in the | - | | drop-down listbox. | - +-----------------+--------------------------------------------------------+ - | width | Specifies an integer value indicating the desired width| - | | of the entry window, in average-size characters of the | - | | widget's font. | - +-----------------+--------------------------------------------------------+ +.. tabularcolumns:: |l|L| + ++-----------------+--------------------------------------------------------+ +| Option | Description | ++=================+========================================================+ +| exportselection | Boolean value. If set, the widget selection is linked | +| | to the Window Manager selection (which can be returned | +| | by invoking Misc.selection_get, for example). | ++-----------------+--------------------------------------------------------+ +| justify | Specifies how the text is aligned within the widget. | +| | One of "left", "center", or "right". | ++-----------------+--------------------------------------------------------+ +| height | Specifies the height of the pop-down listbox, in rows. | ++-----------------+--------------------------------------------------------+ +| postcommand | A script (possibly registered with Misc.register) that | +| | is called immediately before displaying the values. It | +| | may specify which values to display. | ++-----------------+--------------------------------------------------------+ +| state | One of "normal", "readonly", or "disabled". In the | +| | "readonly" state, the value may not be edited directly,| +| | and the user can only selection of the values from the | +| | dropdown list. In the "normal" state, the text field is| +| | directly editable. In the "disabled" state, no | +| | interaction is possible. | ++-----------------+--------------------------------------------------------+ +| textvariable | Specifies a name whose value is linked to the widget | +| | value. Whenever the value associated with that name | +| | changes, the widget value is updated, and vice versa. | +| | See :class:`tkinter.StringVar`. | ++-----------------+--------------------------------------------------------+ +| values | Specifies the list of values to display in the | +| | drop-down listbox. | ++-----------------+--------------------------------------------------------+ +| width | Specifies an integer value indicating the desired width| +| | of the entry window, in average-size characters of the | +| | widget's font. | ++-----------------+--------------------------------------------------------+ Virtual events @@ -397,7 +397,7 @@ Options This widget accepts the following specific options: - .. tabularcolumns:: |l|L| +.. tabularcolumns:: |l|L| +----------------------+------------------------------------------------------+ | Option | Description | @@ -473,25 +473,25 @@ Options This widget accepts the following specific options: - .. tabularcolumns:: |l|L| - - +---------+----------------------------------------------------------------+ - | Option | Description | - +=========+================================================================+ - | height | If present and greater than zero, specifies the desired height | - | | of the pane area (not including internal padding or tabs). | - | | Otherwise, the maximum height of all panes is used. | - +---------+----------------------------------------------------------------+ - | padding | Specifies the amount of extra space to add around the outside | - | | of the notebook. The padding is a list up to four length | - | | specifications left top right bottom. If fewer than four | - | | elements are specified, bottom defaults to top, right defaults | - | | to left, and top defaults to left. | - +---------+----------------------------------------------------------------+ - | width | If present and greater than zero, specified the desired width | - | | of the pane area (not including internal padding). Otherwise, | - | | the maximum width of all panes is used. | - +---------+----------------------------------------------------------------+ +.. tabularcolumns:: |l|L| + ++---------+----------------------------------------------------------------+ +| Option | Description | ++=========+================================================================+ +| height | If present and greater than zero, specifies the desired height | +| | of the pane area (not including internal padding or tabs). | +| | Otherwise, the maximum height of all panes is used. | ++---------+----------------------------------------------------------------+ +| padding | Specifies the amount of extra space to add around the outside | +| | of the notebook. The padding is a list up to four length | +| | specifications left top right bottom. If fewer than four | +| | elements are specified, bottom defaults to top, right defaults | +| | to left, and top defaults to left. | ++---------+----------------------------------------------------------------+ +| width | If present and greater than zero, specified the desired width | +| | of the pane area (not including internal padding). Otherwise, | +| | the maximum width of all panes is used. | ++---------+----------------------------------------------------------------+ Tab Options @@ -499,39 +499,39 @@ Tab Options There are also specific options for tabs: - .. tabularcolumns:: |l|L| - - +-----------+--------------------------------------------------------------+ - | Option | Description | - +===========+==============================================================+ - | state | Either "normal", "disabled" or "hidden". If "disabled", then | - | | the tab is not selectable. If "hidden", then the tab is not | - | | shown. | - +-----------+--------------------------------------------------------------+ - | sticky | Specifies how the child window is positioned within the pane | - | | area. Value is a string containing zero or more of the | - | | characters "n", "s", "e" or "w". Each letter refers to a | - | | side (north, south, east or west) that the child window will | - | | stick to, as per the :meth:`grid` geometry manager. | - +-----------+--------------------------------------------------------------+ - | padding | Specifies the amount of extra space to add between the | - | | notebook and this pane. Syntax is the same as for the option | - | | padding used by this widget. | - +-----------+--------------------------------------------------------------+ - | text | Specifies a text to be displayed in the tab. | - +-----------+--------------------------------------------------------------+ - | image | Specifies an image to display in the tab. See the option | - | | image described in :class:`Widget`. | - +-----------+--------------------------------------------------------------+ - | compound | Specifies how to display the image relative to the text, in | - | | the case both options text and image are present. See | - | | `Label Options`_ for legal values. | - +-----------+--------------------------------------------------------------+ - | underline | Specifies the index (0-based) of a character to underline in | - | | the text string. The underlined character is used for | - | | mnemonic activation if :meth:`Notebook.enable_traversal` is | - | | called. | - +-----------+--------------------------------------------------------------+ +.. tabularcolumns:: |l|L| + ++-----------+--------------------------------------------------------------+ +| Option | Description | ++===========+==============================================================+ +| state | Either "normal", "disabled" or "hidden". If "disabled", then | +| | the tab is not selectable. If "hidden", then the tab is not | +| | shown. | ++-----------+--------------------------------------------------------------+ +| sticky | Specifies how the child window is positioned within the pane | +| | area. Value is a string containing zero or more of the | +| | characters "n", "s", "e" or "w". Each letter refers to a | +| | side (north, south, east or west) that the child window will | +| | stick to, as per the :meth:`grid` geometry manager. | ++-----------+--------------------------------------------------------------+ +| padding | Specifies the amount of extra space to add between the | +| | notebook and this pane. Syntax is the same as for the option | +| | padding used by this widget. | ++-----------+--------------------------------------------------------------+ +| text | Specifies a text to be displayed in the tab. | ++-----------+--------------------------------------------------------------+ +| image | Specifies an image to display in the tab. See the option | +| | image described in :class:`Widget`. | ++-----------+--------------------------------------------------------------+ +| compound | Specifies how to display the image relative to the text, in | +| | the case both options text and image are present. See | +| | `Label Options`_ for legal values. | ++-----------+--------------------------------------------------------------+ +| underline | Specifies the index (0-based) of a character to underline in | +| | the text string. The underlined character is used for | +| | mnemonic activation if :meth:`Notebook.enable_traversal` is | +| | called. | ++-----------+--------------------------------------------------------------+ Tab Identifiers @@ -663,36 +663,36 @@ Options This widget accepts the following specific options: - .. tabularcolumns:: |l|L| - - +----------+---------------------------------------------------------------+ - | Option | Description | - +==========+===============================================================+ - | orient | One of "horizontal" or "vertical". Specifies the orientation | - | | of the progress bar. | - +----------+---------------------------------------------------------------+ - | length | Specifies the length of the long axis of the progress bar | - | | (width if horizontal, height if vertical). | - +----------+---------------------------------------------------------------+ - | mode | One of "determinate" or "indeterminate". | - +----------+---------------------------------------------------------------+ - | maximum | A number specifying the maximum value. Defaults to 100. | - +----------+---------------------------------------------------------------+ - | value | The current value of the progress bar. In "determinate" mode, | - | | this represents the amount of work completed. In | - | | "indeterminate" mode, it is interpreted as modulo *maximum*; | - | | that is, the progress bar completes one "cycle" when its value| - | | increases by *maximum*. | - +----------+---------------------------------------------------------------+ - | variable | A name which is linked to the option value. If specified, the | - | | value of the progress bar is automatically set to the value of| - | | this name whenever the latter is modified. | - +----------+---------------------------------------------------------------+ - | phase | Read-only option. The widget periodically increments the value| - | | of this option whenever its value is greater than 0 and, in | - | | determinate mode, less than maximum. This option may be used | - | | by the current theme to provide additional animation effects. | - +----------+---------------------------------------------------------------+ +.. tabularcolumns:: |l|L| + ++----------+---------------------------------------------------------------+ +| Option | Description | ++==========+===============================================================+ +| orient | One of "horizontal" or "vertical". Specifies the orientation | +| | of the progress bar. | ++----------+---------------------------------------------------------------+ +| length | Specifies the length of the long axis of the progress bar | +| | (width if horizontal, height if vertical). | ++----------+---------------------------------------------------------------+ +| mode | One of "determinate" or "indeterminate". | ++----------+---------------------------------------------------------------+ +| maximum | A number specifying the maximum value. Defaults to 100. | ++----------+---------------------------------------------------------------+ +| value | The current value of the progress bar. In "determinate" mode, | +| | this represents the amount of work completed. In | +| | "indeterminate" mode, it is interpreted as modulo *maximum*; | +| | that is, the progress bar completes one "cycle" when its value| +| | increases by *maximum*. | ++----------+---------------------------------------------------------------+ +| variable | A name which is linked to the option value. If specified, the | +| | value of the progress bar is automatically set to the value of| +| | this name whenever the latter is modified. | ++----------+---------------------------------------------------------------+ +| phase | Read-only option. The widget periodically increments the value| +| | of this option whenever its value is greater than 0 and, in | +| | determinate mode, less than maximum. This option may be used | +| | by the current theme to provide additional animation effects. | ++----------+---------------------------------------------------------------+ ttk.Progressbar @@ -734,14 +734,14 @@ Options This widget accepts the following specific option: - .. tabularcolumns:: |l|L| +.. tabularcolumns:: |l|L| - +--------+----------------------------------------------------------------+ - | Option | Description | - +========+================================================================+ - | orient | One of "horizontal" or "vertical". Specifies the orientation of| - | | the separator. | - +--------+----------------------------------------------------------------+ ++--------+----------------------------------------------------------------+ +| Option | Description | ++========+================================================================+ +| orient | One of "horizontal" or "vertical". Specifies the orientation of| +| | the separator. | ++--------+----------------------------------------------------------------+ Sizegrip @@ -802,49 +802,49 @@ Options This widget accepts the following specific options: - .. tabularcolumns:: |l|p{0.7\linewidth}| - - +----------------+--------------------------------------------------------+ - | Option | Description | - +================+========================================================+ - | columns | A list of column identifiers, specifying the number of | - | | columns and their names. | - +----------------+--------------------------------------------------------+ - | displaycolumns | A list of column identifiers (either symbolic or | - | | integer indices) specifying which data columns are | - | | displayed and the order in which they appear, or the | - | | string "#all". | - +----------------+--------------------------------------------------------+ - | height | Specifies the number of rows which should be visible. | - | | Note: the requested width is determined from the sum | - | | of the column widths. | - +----------------+--------------------------------------------------------+ - | padding | Specifies the internal padding for the widget. The | - | | padding is a list of up to four length specifications. | - +----------------+--------------------------------------------------------+ - | selectmode | Controls how the built-in class bindings manage the | - | | selection. One of "extended", "browse" or "none". | - | | If set to "extended" (the default), multiple items may | - | | be selected. If "browse", only a single item will be | - | | selected at a time. If "none", the selection will not | - | | be changed. | - | | | - | | Note that the application code and tag bindings can set| - | | the selection however they wish, regardless of the | - | | value of this option. | - +----------------+--------------------------------------------------------+ - | show | A list containing zero or more of the following values,| - | | specifying which elements of the tree to display. | - | | | - | | * tree: display tree labels in column #0. | - | | * headings: display the heading row. | - | | | - | | The default is "tree headings", i.e., show all | - | | elements. | - | | | - | | **Note**: Column #0 always refers to the tree column, | - | | even if show="tree" is not specified. | - +----------------+--------------------------------------------------------+ +.. tabularcolumns:: |l|p{0.7\linewidth}| + ++----------------+--------------------------------------------------------+ +| Option | Description | ++================+========================================================+ +| columns | A list of column identifiers, specifying the number of | +| | columns and their names. | ++----------------+--------------------------------------------------------+ +| displaycolumns | A list of column identifiers (either symbolic or | +| | integer indices) specifying which data columns are | +| | displayed and the order in which they appear, or the | +| | string "#all". | ++----------------+--------------------------------------------------------+ +| height | Specifies the number of rows which should be visible. | +| | Note: the requested width is determined from the sum | +| | of the column widths. | ++----------------+--------------------------------------------------------+ +| padding | Specifies the internal padding for the widget. The | +| | padding is a list of up to four length specifications. | ++----------------+--------------------------------------------------------+ +| selectmode | Controls how the built-in class bindings manage the | +| | selection. One of "extended", "browse" or "none". | +| | If set to "extended" (the default), multiple items may | +| | be selected. If "browse", only a single item will be | +| | selected at a time. If "none", the selection will not | +| | be changed. | +| | | +| | Note that the application code and tag bindings can set| +| | the selection however they wish, regardless of the | +| | value of this option. | ++----------------+--------------------------------------------------------+ +| show | A list containing zero or more of the following values,| +| | specifying which elements of the tree to display. | +| | | +| | * tree: display tree labels in column #0. | +| | * headings: display the heading row. | +| | | +| | The default is "tree headings", i.e., show all | +| | elements. | +| | | +| | **Note**: Column #0 always refers to the tree column, | +| | even if show="tree" is not specified. | ++----------------+--------------------------------------------------------+ Item Options @@ -853,27 +853,27 @@ Item Options The following item options may be specified for items in the insert and item widget commands. - .. tabularcolumns:: |l|L| - - +--------+---------------------------------------------------------------+ - | Option | Description | - +========+===============================================================+ - | text | The textual label to display for the item. | - +--------+---------------------------------------------------------------+ - | image | A Tk Image, displayed to the left of the label. | - +--------+---------------------------------------------------------------+ - | values | The list of values associated with the item. | - | | | - | | Each item should have the same number of values as the widget | - | | option columns. If there are fewer values than columns, the | - | | remaining values are assumed empty. If there are more values | - | | than columns, the extra values are ignored. | - +--------+---------------------------------------------------------------+ - | open | ``True``/``False`` value indicating whether the item's | - | | children should be displayed or hidden. | - +--------+---------------------------------------------------------------+ - | tags | A list of tags associated with this item. | - +--------+---------------------------------------------------------------+ +.. tabularcolumns:: |l|L| + ++--------+---------------------------------------------------------------+ +| Option | Description | ++========+===============================================================+ +| text | The textual label to display for the item. | ++--------+---------------------------------------------------------------+ +| image | A Tk Image, displayed to the left of the label. | ++--------+---------------------------------------------------------------+ +| values | The list of values associated with the item. | +| | | +| | Each item should have the same number of values as the widget | +| | option columns. If there are fewer values than columns, the | +| | remaining values are assumed empty. If there are more values | +| | than columns, the extra values are ignored. | ++--------+---------------------------------------------------------------+ +| open | ``True``/``False`` value indicating whether the item's | +| | children should be displayed or hidden. | ++--------+---------------------------------------------------------------+ +| tags | A list of tags associated with this item. | ++--------+---------------------------------------------------------------+ Tag Options @@ -881,20 +881,20 @@ Tag Options The following options may be specified on tags: - .. tabularcolumns:: |l|L| +.. tabularcolumns:: |l|L| - +------------+-----------------------------------------------------------+ - | Option | Description | - +============+===========================================================+ - | foreground | Specifies the text foreground color. | - +------------+-----------------------------------------------------------+ - | background | Specifies the cell or item background color. | - +------------+-----------------------------------------------------------+ - | font | Specifies the font to use when drawing text. | - +------------+-----------------------------------------------------------+ - | image | Specifies the item image, in case the item's image option | - | | is empty. | - +------------+-----------------------------------------------------------+ ++------------+-----------------------------------------------------------+ +| Option | Description | ++============+===========================================================+ +| foreground | Specifies the text foreground color. | ++------------+-----------------------------------------------------------+ +| background | Specifies the cell or item background color. | ++------------+-----------------------------------------------------------+ +| font | Specifies the font to use when drawing text. | ++------------+-----------------------------------------------------------+ +| image | Specifies the item image, in case the item's image option | +| | is empty. | ++------------+-----------------------------------------------------------+ Column Identifiers @@ -926,19 +926,19 @@ Virtual Events The Treeview widget generates the following virtual events. - .. tabularcolumns:: |l|L| +.. tabularcolumns:: |l|L| - +--------------------+--------------------------------------------------+ - | Event | Description | - +====================+==================================================+ - | <> | Generated whenever the selection changes. | - +--------------------+--------------------------------------------------+ - | <> | Generated just before settings the focus item to | - | | open=True. | - +--------------------+--------------------------------------------------+ - | <> | Generated just after setting the focus item to | - | | open=False. | - +--------------------+--------------------------------------------------+ ++--------------------+--------------------------------------------------+ +| Event | Description | ++====================+==================================================+ +| <> | Generated whenever the selection changes. | ++--------------------+--------------------------------------------------+ +| <> | Generated just before settings the focus item to | +| | open=True. | ++--------------------+--------------------------------------------------+ +| <> | Generated just after setting the focus item to | +| | open=False. | ++--------------------+--------------------------------------------------+ The :meth:`Treeview.focus` and :meth:`Treeview.selection` methods can be used to determine the affected item or items. @@ -986,19 +986,19 @@ ttk.Treeview The valid options/values are: - * id + id Returns the column name. This is a read-only option. - * anchor: One of the standard Tk anchor values. + anchor: One of the standard Tk anchor values. Specifies how the text in this column should be aligned with respect to the cell. - * minwidth: width + minwidth: width The minimum width of the column in pixels. The treeview widget will not make the column any smaller than specified by this option when the widget is resized or the user drags a column. - * stretch: ``True``/``False`` + stretch: ``True``/``False`` Specifies whether the column's width should be adjusted when the widget is resized. - * width: width + width: width The width of the column in pixels. To configure the tree column, call this with column = "#0" @@ -1041,14 +1041,14 @@ ttk.Treeview The valid options/values are: - * text: text + text: text The text to display in the column heading. - * image: imageName + image: imageName Specifies an image to display to the right of the column heading. - * anchor: anchor + anchor: anchor Specifies how the heading text should be aligned. One of the standard Tk anchor values. - * command: callback + command: callback A callback to be invoked when the heading label is pressed. To configure the tree column heading, call this with column = "#0". @@ -1398,25 +1398,25 @@ option. If you don't know the class name of a widget, use the method by statespec/value pairs (this is the imagespec), and *kw* may have the following options: - * border=padding - padding is a list of up to four integers, specifying the left, top, - right, and bottom borders, respectively. + border=padding + padding is a list of up to four integers, specifying the left, top, + right, and bottom borders, respectively. - * height=height - Specifies a minimum height for the element. If less than zero, the - base image's height is used as a default. + height=height + Specifies a minimum height for the element. If less than zero, the + base image's height is used as a default. - * padding=padding - Specifies the element's interior padding. Defaults to border's value - if not specified. + padding=padding + Specifies the element's interior padding. Defaults to border's value + if not specified. - * sticky=spec - Specifies how the image is placed within the final parcel. spec - contains zero or more characters "n", "s", "w", or "e". + sticky=spec + Specifies how the image is placed within the final parcel. spec + contains zero or more characters "n", "s", "w", or "e". - * width=width - Specifies a minimum width for the element. If less than zero, the - base image's width is used as a default. + width=width + Specifies a minimum width for the element. If less than zero, the + base image's width is used as a default. If "from" is used as the value of *etype*, :meth:`element_create` will clone an existing @@ -1504,22 +1504,22 @@ uses a simplified version of the pack geometry manager: given an initial cavity, each element is allocated a parcel. Valid options/values are: - * side: whichside - Specifies which side of the cavity to place the element; one of - top, right, bottom or left. If omitted, the element occupies the - entire cavity. +side: whichside + Specifies which side of the cavity to place the element; one of + top, right, bottom or left. If omitted, the element occupies the + entire cavity. - * sticky: nswe - Specifies where the element is placed inside its allocated parcel. +sticky: nswe + Specifies where the element is placed inside its allocated parcel. - * unit: 0 or 1 - If set to 1, causes the element and all of its descendants to be treated as - a single element for the purposes of :meth:`Widget.identify` et al. It's - used for things like scrollbar thumbs with grips. +unit: 0 or 1 + If set to 1, causes the element and all of its descendants to be treated as + a single element for the purposes of :meth:`Widget.identify` et al. It's + used for things like scrollbar thumbs with grips. - * children: [sublayout... ] - Specifies a list of elements to place inside the element. Each - element is a tuple (or other sequence type) where the first item is - the layout name, and the other is a `Layout`_. +children: [sublayout... ] + Specifies a list of elements to place inside the element. Each + element is a tuple (or other sequence type) where the first item is + the layout name, and the other is a `Layout`_. .. _Layout: `Layouts`_ diff --git a/Doc/library/token-list.inc b/Doc/library/token-list.inc index e885de88cad9ae..39df2927a0b7f2 100644 --- a/Doc/library/token-list.inc +++ b/Doc/library/token-list.inc @@ -207,10 +207,6 @@ .. data:: OP -.. data:: AWAIT - -.. data:: ASYNC - .. data:: TYPE_IGNORE .. data:: TYPE_COMMENT diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 903847bb206d62..e6dc37d7ad852c 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -80,17 +80,21 @@ the :mod:`tokenize` module. .. versionchanged:: 3.5 - Added :data:`AWAIT` and :data:`ASYNC` tokens. + Added :data:`!AWAIT` and :data:`!ASYNC` tokens. .. versionchanged:: 3.7 Added :data:`COMMENT`, :data:`NL` and :data:`ENCODING` tokens. .. versionchanged:: 3.7 - Removed :data:`AWAIT` and :data:`ASYNC` tokens. "async" and "await" are + Removed :data:`!AWAIT` and :data:`!ASYNC` tokens. "async" and "await" are now tokenized as :data:`NAME` tokens. .. versionchanged:: 3.8 Added :data:`TYPE_COMMENT`, :data:`TYPE_IGNORE`, :data:`COLONEQUAL`. - Added :data:`AWAIT` and :data:`ASYNC` tokens back (they're needed + Added :data:`!AWAIT` and :data:`!ASYNC` tokens back (they're needed to support parsing older Python versions for :func:`ast.parse` with ``feature_version`` set to 6 or lower). + +.. versionchanged:: 3.13 + Removed :data:`!AWAIT` and :data:`!ASYNC` tokens again. + diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index bffe93006edc7b..92bdb052267a68 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -166,11 +166,11 @@ The following options are accepted: .. program:: tokenize -.. cmdoption:: -h, --help +.. option:: -h, --help show this help message and exit -.. cmdoption:: -e, --exact +.. option:: -e, --exact display token names using the exact type diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index 40cf198f1287d7..e9b59a6d186ba2 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -34,11 +34,11 @@ all Python modules imported during the execution into the current directory. .. program:: trace -.. cmdoption:: --help +.. option:: --help Display usage and exit. -.. cmdoption:: --version +.. option:: --version Display the version of the module and exit. @@ -56,28 +56,28 @@ the :option:`--trace <-t>` and :option:`--count <-c>` options. When .. program:: trace -.. cmdoption:: -c, --count +.. option:: -c, --count Produce a set of annotated listing files upon program completion that shows how many times each statement was executed. See also :option:`--coverdir <-C>`, :option:`--file <-f>` and :option:`--no-report <-R>` below. -.. cmdoption:: -t, --trace +.. option:: -t, --trace Display lines as they are executed. -.. cmdoption:: -l, --listfuncs +.. option:: -l, --listfuncs Display the functions executed by running the program. -.. cmdoption:: -r, --report +.. option:: -r, --report Produce an annotated list from an earlier program run that used the :option:`--count <-c>` and :option:`--file <-f>` option. This does not execute any code. -.. cmdoption:: -T, --trackcalls +.. option:: -T, --trackcalls Display the calling relationships exposed by running the program. @@ -86,33 +86,33 @@ Modifiers .. program:: trace -.. cmdoption:: -f, --file= +.. option:: -f, --file= Name of a file to accumulate counts over several tracing runs. Should be used with the :option:`--count <-c>` option. -.. cmdoption:: -C, --coverdir= +.. option:: -C, --coverdir= Directory where the report files go. The coverage report for ``package.module`` is written to file :file:`{dir}/{package}/{module}.cover`. -.. cmdoption:: -m, --missing +.. option:: -m, --missing When generating annotated listings, mark lines which were not executed with ``>>>>>>``. -.. cmdoption:: -s, --summary +.. option:: -s, --summary When using :option:`--count <-c>` or :option:`--report <-r>`, write a brief summary to stdout for each file processed. -.. cmdoption:: -R, --no-report +.. option:: -R, --no-report Do not generate annotated listings. This is useful if you intend to make several runs with :option:`--count <-c>`, and then produce a single set of annotated listings at the end. -.. cmdoption:: -g, --timing +.. option:: -g, --timing Prefix each line with the time since the program started. Only used while tracing. @@ -124,12 +124,12 @@ These options may be repeated multiple times. .. program:: trace -.. cmdoption:: --ignore-module= +.. option:: --ignore-module= Ignore each of the given module names and its submodules (if it is a package). The argument can be a list of names separated by a comma. -.. cmdoption:: --ignore-dir= +.. option:: --ignore-dir= Ignore all modules and packages in the named directory and subdirectories. The argument can be a list of directories separated by :data:`os.pathsep`. diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index 3eb77fc3df5709..67ee73d4b2e1e5 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -139,11 +139,11 @@ The module defines the following functions: Format the exception part of a traceback using an exception value such as given by ``sys.last_value``. The return value is a list of strings, each - ending in a newline. Normally, the list contains a single string; however, - for :exc:`SyntaxError` exceptions, it contains several lines that (when - printed) display detailed information about where the syntax error occurred. - The message indicating which exception occurred is the always last string in - the list. + ending in a newline. The list contains the exception's message, which is + normally a single string; however, for :exc:`SyntaxError` exceptions, it + contains several lines that (when printed) display detailed information + about where the syntax error occurred. Following the message, the list + contains the exception's :attr:`notes `. Since Python 3.10, instead of passing *value*, an exception object can be passed as the first argument. If *value* is provided, the first @@ -153,6 +153,9 @@ The module defines the following functions: The *etype* parameter has been renamed to *exc* and is now positional-only. + .. versionchanged:: 3.11 + The returned list now includes any notes attached to the exception. + .. function:: format_exception(exc, /[, value, tb], limit=None, chain=True) @@ -235,6 +238,12 @@ capture data for later printing in a lightweight fashion. group's exceptions array. The formatted output is truncated when either limit is exceeded. + .. versionchanged:: 3.10 + Added the *compact* parameter. + + .. versionchanged:: 3.11 + Added the *max_group_width* and *max_group_depth* parameters. + .. attribute:: __cause__ A :class:`TracebackException` of the original ``__cause__``. @@ -330,35 +339,28 @@ capture data for later printing in a lightweight fashion. some containing internal newlines. :func:`~traceback.print_exception` is a wrapper around this method which just prints the lines to a file. - The message indicating which exception occurred is always the last - string in the output. - .. method:: format_exception_only(*, show_group=False) Format the exception part of the traceback. The return value is a generator of strings, each ending in a newline. - When *show_group* is ``False``, the generator normally emits a single - string; however, for :exc:`SyntaxError` exceptions, it emits several - lines that (when printed) display detailed information about where - the syntax error occurred. The message indicating which exception - occurred is always the last string in the output. + When *show_group* is ``False``, the generator emits the exception's + message followed by its notes (if it has any). The exception message + is normally a single string; however, for :exc:`SyntaxError` exceptions, + it consists of several lines that (when printed) display detailed + information about where the syntax error occurred. When *show_group* is ``True``, and the exception is an instance of :exc:`BaseExceptionGroup`, the nested exceptions are included as well, recursively, with indentation relative to their nesting depth. + .. versionchanged:: 3.11 + The exception's notes are now included in the output. + .. versionchanged:: 3.13 Added the *show_group* parameter. - .. versionchanged:: 3.10 - Added the *compact* parameter. - - .. versionchanged:: 3.11 - Added the *max_group_width* and *max_group_depth* parameters. - - :class:`StackSummary` Objects ----------------------------- diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index fc7f98c7931fa5..a4777772e1fc6c 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -43,6 +43,9 @@ The :mod:`tty` module defines the following functions: :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr` is saved before setting *fd* to raw mode; this value is returned. + .. versionchanged:: 3.12 + The return value is now the original tty attributes, instead of None. + .. function:: setcbreak(fd, when=termios.TCSAFLUSH) @@ -51,6 +54,9 @@ The :mod:`tty` module defines the following functions: :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr` is saved before setting *fd* to cbreak mode; this value is returned. + .. versionchanged:: 3.12 + The return value is now the original tty attributes, instead of None. + .. seealso:: diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index c9ce955a6d2ba4..88b1f09eb3c8b7 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -19,9 +19,14 @@ Introduction ============ -Turtle graphics is a popular way for introducing programming to kids. It was -part of the original Logo programming language developed by Wally Feurzeig, -Seymour Papert and Cynthia Solomon in 1967. +Turtle graphics is an implementation of `the popular geometric drawing tools +introduced in Logo `_, developed by Wally Feurzeig, Seymour Papert and Cynthia Solomon +in 1967. + + +Get started +=========== Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it the command ``turtle.forward(15)``, and it moves (on-screen!) 15 pixels in the @@ -36,67 +41,261 @@ direction it is facing, drawing a line as it moves. Give it the command .. image:: turtle-star.* :align: center - .. literalinclude:: ../includes/turtle-star.py +In Python, turtle graphics provides a representation of a physical "turtle" +(a little robot with a pen) that draws on a sheet of paper on the floor. + +It's an effective and well-proven way for learners to encounter +programming concepts and interaction with software, as it provides instant, +visible feedback. It also provides convenient access to graphical output +in general. + +Turtle drawing was originally created as an educational tool, to be used by +teachers in the classroom. For the programmer who needs to produce some +graphical output it can be a way to do that without the overhead of +introducing more complex or external libraries into their work. + + +.. _turtle-tutorial: + +Tutorial +======== + +New users should start here. In this tutorial we'll explore some of the +basics of turtle drawing. + + +Starting a turtle environment +----------------------------- + +In a Python shell, import all the objects of the ``turtle`` module:: + + from turtle import * + +If you run into a ``No module named '_tkinter'`` error, you'll have to +install the :mod:`Tk interface package ` on your system. + + +Basic drawing +------------- + +Send the turtle forward 100 steps:: + + forward(100) + +You should see (most likely, in a new window on your display) a line +drawn by the turtle, heading East. Change the direction of the turtle, +so that it turns 120 degrees left (anti-clockwise):: + + left(120) + +Let's continue by drawing a triangle:: + + forward(100) + left(120) + forward(100) + +Notice how the turtle, represented by an arrow, points in different +directions as you steer it. + +Experiment with those commands, and also with ``backward()`` and +``right()``. + + +Pen control +~~~~~~~~~~~ + +Try changing the color - for example, ``color('blue')`` - and +width of the line - for example, ``width(3)`` - and then drawing again. + +You can also move the turtle around without drawing, by lifting up the pen: +``up()`` before moving. To start drawing again, use ``down()``. + + +The turtle's position +~~~~~~~~~~~~~~~~~~~~~ + +Send your turtle back to its starting-point (useful if it has disappeared +off-screen):: + + home() + +The home position is at the center of the turtle's screen. If you ever need to +know them, get the turtle's x-y co-ordinates with:: + + pos() + +Home is at ``(0, 0)``. + +And after a while, it will probably help to clear the window so we can start +anew:: + + clearscreen() + + +Making algorithmic patterns +--------------------------- + +Using loops, it's possible to build up geometric patterns:: + + for steps in range(100): + for c in ('blue', 'red', 'green'): + color(c) + forward(steps) + right(30) + + +\ - which of course, are limited only by the imagination! + +Let's draw the star shape at the top of this page. We want red lines, +filled in with yellow:: + + color('red') + fillcolor('yellow') -By combining together these and similar commands, intricate shapes and pictures -can easily be drawn. +Just as ``up()`` and ``down()`` determine whether lines will be drawn, +filling can be turned on and off:: -The :mod:`turtle` module is an extended reimplementation of the same-named -module from the Python standard distribution up to version Python 2.5. + begin_fill() -It tries to keep the merits of the old turtle module and to be (nearly) 100% -compatible with it. This means in the first place to enable the learning -programmer to use all the commands, classes and methods interactively when using -the module from within IDLE run with the ``-n`` switch. +Next we'll create a loop:: -The turtle module provides turtle graphics primitives, in both object-oriented -and procedure-oriented ways. Because it uses :mod:`tkinter` for the underlying -graphics, it needs a version of Python installed with Tk support. + while True: + forward(200) + left(170) + if abs(pos()) < 1: + break -The object-oriented interface uses essentially two+two classes: +``abs(pos()) < 1`` is a good way to know when the turtle is back at its +home position. -1. The :class:`TurtleScreen` class defines graphics windows as a playground for - the drawing turtles. Its constructor needs a :class:`tkinter.Canvas` or a - :class:`ScrolledCanvas` as argument. It should be used when :mod:`turtle` is - used as part of some application. +Finally, complete the filling:: - The function :func:`Screen` returns a singleton object of a - :class:`TurtleScreen` subclass. This function should be used when - :mod:`turtle` is used as a standalone tool for doing graphics. - As a singleton object, inheriting from its class is not possible. + end_fill() - All methods of TurtleScreen/Screen also exist as functions, i.e. as part of - the procedure-oriented interface. +(Note that filling only actually takes place when you give the +``end_fill()`` command.) -2. :class:`RawTurtle` (alias: :class:`RawPen`) defines Turtle objects which draw - on a :class:`TurtleScreen`. Its constructor needs a Canvas, ScrolledCanvas - or TurtleScreen as argument, so the RawTurtle objects know where to draw. - Derived from RawTurtle is the subclass :class:`Turtle` (alias: :class:`Pen`), - which draws on "the" :class:`Screen` instance which is automatically - created, if not already present. +.. _turtle-how-to: - All methods of RawTurtle/Turtle also exist as functions, i.e. part of the - procedure-oriented interface. +How to... +========= -The procedural interface provides functions which are derived from the methods -of the classes :class:`Screen` and :class:`Turtle`. They have the same names as -the corresponding methods. A screen object is automatically created whenever a -function derived from a Screen method is called. An (unnamed) turtle object is -automatically created whenever any of the functions derived from a Turtle method -is called. +This section covers some typical turtle use-cases and approaches. -To use multiple turtles on a screen one has to use the object-oriented interface. + +Get started as quickly as possible +---------------------------------- + +One of the joys of turtle graphics is the immediate, visual feedback that's +available from simple commands - it's an excellent way to introduce children +to programming ideas, with a minimum of overhead (not just children, of +course). + +The turtle module makes this possible by exposing all its basic functionality +as functions, available with ``from turtle import *``. The :ref:`turtle +graphics tutorial ` covers this approach. + +It's worth noting that many of the turtle commands also have even more terse +equivalents, such as ``fd()`` for :func:`forward`. These are especially +useful when working with learners for whom typing is not a skill. + +.. _note: + + You'll need to have the :mod:`Tk interface package ` installed on + your system for turtle graphics to work. Be warned that this is not + always straightforward, so check this in advance if you're planning to + use turtle graphics with a learner. + + +Use the ``turtle`` module namespace +----------------------------------- + +Using ``from turtle import *`` is convenient - but be warned that it imports a +rather large collection of objects, and if you're doing anything but turtle +graphics you run the risk of a name conflict (this becomes even more an issue +if you're using turtle graphics in a script where other modules might be +imported). + +The solution is to use ``import turtle`` - ``fd()`` becomes +``turtle.fd()``, ``width()`` becomes ``turtle.width()`` and so on. (If typing +"turtle" over and over again becomes tedious, use for example ``import turtle +as t`` instead.) + + +Use turtle graphics in a script +------------------------------- + +It's recommended to use the ``turtle`` module namespace as described +immediately above, for example:: + + import turtle as t + from random import random + + for i in range(100): + steps = int(random() * 100) + angle = int(random() * 360) + t.right(angle) + t.fd(steps) + +Another step is also required though - as soon as the script ends, Python +will also close the turtle's window. Add:: + + t.mainloop() + +to the end of the script. The script will now wait to be dismissed and +will not exit until it is terminated, for example by closing the turtle +graphics window. + + +Use object-oriented turtle graphics +----------------------------------- + +.. seealso:: :ref:`Explanation of the object-oriented interface ` + +Other than for very basic introductory purposes, or for trying things out +as quickly as possible, it's more usual and much more powerful to use the +object-oriented approach to turtle graphics. For example, this allows +multiple turtles on screen at once. + +In this approach, the various turtle commands are methods of objects (mostly of +``Turtle`` objects). You *can* use the object-oriented approach in the shell, +but it would be more typical in a Python script. + +The example above then becomes:: + + from turtle import Turtle + from random import random + + t = Turtle() + for i in range(100): + steps = int(random() * 100) + angle = int(random() * 360) + t.right(angle) + t.fd(steps) + + t.screen.mainloop() + +Note the last line. ``t.screen`` is an instance of the :class:`Screen` +that a Turtle instance exists on; it's created automatically along with +the turtle. + +The turtle's screen can be customised, for example:: + + t.screen.title('Object-oriented turtle demo') + t.screen.bgcolor("orange") + + +Turtle graphics reference +========================= .. note:: + In the following documentation the argument list for functions is given. Methods, of course, have the additional first argument *self* which is omitted here. -Overview of available Turtle and Screen methods -================================================= - Turtle methods -------------- @@ -2116,7 +2315,7 @@ Public classes .. class:: RawTurtle(canvas) RawPen(canvas) - :param canvas: a :class:`tkinter.Canvas`, a :class:`ScrolledCanvas` or a + :param canvas: a :class:`!tkinter.Canvas`, a :class:`ScrolledCanvas` or a :class:`TurtleScreen` Create a turtle. The turtle has all methods described above as "methods of @@ -2131,7 +2330,7 @@ Public classes .. class:: TurtleScreen(cv) - :param cv: a :class:`tkinter.Canvas` + :param cv: a :class:`!tkinter.Canvas` Provides screen oriented methods like :func:`bgcolor` etc. that are described above. @@ -2201,6 +2400,41 @@ Public classes * ``a.rotate(angle)`` rotation +.. _turtle-explanation: + +Explanation +=========== + +A turtle object draws on a screen object, and there a number of key classes in +the turtle object-oriented interface that can be used to create them and relate +them to each other. + +A :class:`Turtle` instance will automatically create a :class:`Screen` +instance if one is not already present. + +``Turtle`` is a subclass of :class:`RawTurtle`, which *doesn't* automatically +create a drawing surface - a *canvas* will need to be provided or created for +it. The *canvas* can be a :class:`!tkinter.Canvas`, :class:`ScrolledCanvas` +or :class:`TurtleScreen`. + + +:class:`TurtleScreen` is the basic drawing surface for a +turtle. :class:`Screen` is a subclass of ``TurtleScreen``, and +includes :ref:`some additional methods ` for managing its +appearance (including size and title) and behaviour. ``TurtleScreen``'s +constructor needs a :class:`!tkinter.Canvas` or a +:class:`ScrolledCanvas` as an argument. + +The functional interface for turtle graphics uses the various methods of +``Turtle`` and ``TurtleScreen``/``Screen``. Behind the scenes, a screen +object is automatically created whenever a function derived from a ``Screen`` +method is called. Similarly, a turtle object is automatically created +whenever any of the functions derived from a Turtle method is called. + +To use multiple turtles on a screen, the object-oriented interface must be +used. + + Help and configuration ====================== diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 8cbe17df16f107..54c3907dec98cc 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -200,6 +200,8 @@ Standard names are defined for the following types: Return a copy of the code object with new values for the specified fields. + Code objects are also supported by generic function :func:`copy.replace`. + .. versionadded:: 3.8 .. data:: CellType @@ -470,6 +472,12 @@ Standard names are defined for the following types: .. versionadded:: 3.12 +.. class:: CapsuleType + + The type of :ref:`capsule objects `. + + .. versionadded:: 3.13 + Additional Utility Classes and Functions ---------------------------------------- @@ -502,6 +510,8 @@ Additional Utility Classes and Functions However, for a structured record type use :func:`~collections.namedtuple` instead. + :class:`!SimpleNamespace` objects are supported by :func:`copy.replace`. + .. versionadded:: 3.3 .. versionchanged:: 3.9 diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 0265a39ce646f4..8f691932201225 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -462,7 +462,7 @@ contrast, a variable annotated with ``type[C]`` (or themselves -- specifically, it will accept the *class object* of ``C``. For example:: - a = 3 # Has type ``int``` + a = 3 # Has type ``int`` b = int # Has type ``type[int]`` c = type(a) # Also has type ``type[int]`` @@ -849,6 +849,31 @@ using ``[]``. concat(b"foo", b"bar") # OK, output has type 'bytes' concat("foo", b"bar") # Error, cannot mix str and bytes + Note that, despite its name, ``AnyStr`` has nothing to do with the + :class:`Any` type, nor does it mean "any string". In particular, ``AnyStr`` + and ``str | bytes`` are different from each other and have different use + cases:: + + # Invalid use of AnyStr: + # The type variable is used only once in the function signature, + # so cannot be "solved" by the type checker + def greet_bad(cond: bool) -> AnyStr: + return "hi there!" if cond else b"greetings!" + + # The better way of annotating this function: + def greet_proper(cond: bool) -> str | bytes: + return "hi there!" if cond else b"greetings!" + + .. deprecated-removed:: 3.13 3.18 + Deprecated in favor of the new :ref:`type parameter syntax `. + Use ``class A[T: (str, bytes)]: ...`` instead of importing ``AnyStr``. See + :pep:`695` for more details. + + In Python 3.16, ``AnyStr`` will be removed from ``typing.__all__``, and + deprecation warnings will be emitted at runtime when it is accessed or + imported from ``typing``. ``AnyStr`` will be removed from ``typing`` + in Python 3.18. + .. data:: LiteralString Special type that includes only literal strings. @@ -938,13 +963,17 @@ using ``[]``. For example:: - from typing import Self + from typing import Self, reveal_type class Foo: def return_self(self) -> Self: ... return self + class SubclassOfFoo(Foo): pass + + reveal_type(Foo().return_self()) # Revealed type is "Foo" + reveal_type(SubclassOfFoo().return_self()) # Revealed type is "SubclassOfFoo" This annotation is semantically equivalent to the following, albeit in a more succinct fashion:: @@ -958,15 +987,11 @@ using ``[]``. ... return self - In general if something currently follows the pattern of:: - - class Foo: - def return_self(self) -> "Foo": - ... - return self - - You should use :data:`Self` as calls to ``SubclassOfFoo.return_self`` would have - ``Foo`` as the return type and not ``SubclassOfFoo``. + In general, if something returns ``self``, as in the above examples, you + should use ``Self`` as the return annotation. If ``Foo.return_self`` was + annotated as returning ``"Foo"``, then the type checker would infer the + object returned from ``SubclassOfFoo.return_self`` as being of type ``Foo`` + rather than ``SubclassOfFoo``. Other common use cases include: @@ -974,6 +999,17 @@ using ``[]``. of the ``cls`` parameter. - Annotating an :meth:`~object.__enter__` method which returns self. + You should not use ``Self`` as the return annotation if the method is not + guaranteed to return an instance of a subclass when the class is + subclassed:: + + class Eggs: + # Self would be an incorrect return annotation here, + # as the object returned is always an instance of Eggs, + # even in subclasses + def returns_eggs(self) -> "Eggs": + return Eggs() + See :pep:`673` for more details. .. versionadded:: 3.11 @@ -1265,7 +1301,7 @@ These can be used as types in annotations. They all support subscription using completely disables typechecking for a function or class. The responsibility of how to interpret the metadata - lies with the the tool or library encountering an + lies with the tool or library encountering an ``Annotated`` annotation. A tool or library encountering an ``Annotated`` type can scan through the metadata elements to determine if they are of interest (e.g., using :func:`isinstance`). @@ -2329,9 +2365,6 @@ types. class XZ(X, Z): pass # raises TypeError - T = TypeVar('T') - class XT(X, Generic[T]): pass # raises TypeError - A ``TypedDict`` can be generic:: class Group[T](TypedDict): @@ -2371,6 +2404,13 @@ types. >>> Point3D.__total__ True + This attribute reflects *only* the value of the ``total`` argument + to the current ``TypedDict`` class, not whether the class is semantically + total. For example, a ``TypedDict`` with ``__total__`` set to True may + have keys marked with :data:`NotRequired`, or it may inherit from another + ``TypedDict`` with ``total=False``. Therefore, it is generally better to use + :attr:`__required_keys__` and :attr:`__optional_keys__` for introspection. + .. attribute:: __required_keys__ .. versionadded:: 3.9 @@ -2406,6 +2446,14 @@ types. .. versionadded:: 3.9 + .. note:: + + If ``from __future__ import annotations`` is used or if annotations + are given as strings, annotations are not evaluated when the + ``TypedDict`` is defined. Therefore, the runtime introspection that + ``__required_keys__`` and ``__optional_keys__`` rely on may not work + properly, and the values of the attributes may be incorrect. + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 @@ -3688,3 +3736,7 @@ convenience. This is subject to change, and not all deprecations are listed. - 3.13 - 3.15 - :gh:`106309` + * - :data:`typing.AnyStr` + - 3.13 + - 3.18 + - :gh:`105578` diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 3a094f9c64d4a0..7db47d48022a0e 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -17,8 +17,8 @@ This module provides access to the Unicode Character Database (UCD) which defines character properties for all Unicode characters. The data contained in -this database is compiled from the `UCD version 15.0.0 -`_. +this database is compiled from the `UCD version 15.1.0 +`_. The module uses the same names and symbols as defined by Unicode Standard Annex #44, `"Unicode Character Database" @@ -175,6 +175,6 @@ Examples: .. rubric:: Footnotes -.. [#] https://www.unicode.org/Public/15.0.0/ucd/NameAliases.txt +.. [#] https://www.unicode.org/Public/15.1.0/ucd/NameAliases.txt -.. [#] https://www.unicode.org/Public/15.0.0/ucd/NamedSequences.txt +.. [#] https://www.unicode.org/Public/15.1.0/ucd/NamedSequences.txt diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index 895b9f9f07671b..f2bdde80bdbd64 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -339,7 +339,7 @@ instantiate the class in those tests. >>> mock.old_method() Traceback (most recent call last): ... - AttributeError: object has no attribute 'old_method' + AttributeError: Mock object has no attribute 'old_method'. Did you mean: 'class_method'? Using a specification also enables a smarter matching of calls made to the mock, regardless of whether some parameters were passed as positional or @@ -360,6 +360,30 @@ of arbitrary attributes as well as the getting of them then you can use *spec_set* instead of *spec*. +Using side_effect to return per file content +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:func:`mock_open` is used to patch :func:`open` method. :attr:`~Mock.side_effect` +can be used to return a new Mock object per call. This can be used to return different +contents per file stored in a dictionary:: + + DEFAULT = "default" + data_dict = {"file1": "data1", + "file2": "data2"} + + def open_side_effect(name): + return mock_open(read_data=data_dict.get(name, DEFAULT))() + + with patch("builtins.open", side_effect=open_side_effect): + with open("file1") as file1: + assert file1.read() == "data1" + + with open("file2") as file2: + assert file2.read() == "data2" + + with open("file3") as file2: + assert file2.read() == "default" + Patch Decorators ---------------- @@ -579,14 +603,14 @@ Partial mocking In some tests I wanted to mock out a call to :meth:`datetime.date.today` to return a known date, but I didn't want to prevent the code under test from creating new date objects. Unfortunately :class:`datetime.date` is written in C, and -so I couldn't just monkey-patch out the static :meth:`date.today` method. +so I couldn't just monkey-patch out the static :meth:`datetime.date.today` method. I found a simple way of doing this that involved effectively wrapping the date class with a mock, but passing through calls to the constructor to the real class (and returning real instances). The :func:`patch decorator ` is used here to -mock out the ``date`` class in the module under test. The :attr:`side_effect` +mock out the ``date`` class in the module under test. The :attr:`~Mock.side_effect` attribute on the mock date class is then set to a lambda function that returns a real date. When the mock date class is called a real date will be constructed and returned by ``side_effect``. :: @@ -766,15 +790,16 @@ mock has a nice API for making assertions about how your mock objects are used. >>> mock.foo_bar.assert_called_with('baz', spam='eggs') If your mock is only being called once you can use the -:meth:`assert_called_once_with` method that also asserts that the -:attr:`call_count` is one. +:meth:`~Mock.assert_called_once_with` method that also asserts that the +:attr:`~Mock.call_count` is one. >>> mock.foo_bar.assert_called_once_with('baz', spam='eggs') >>> mock.foo_bar() >>> mock.foo_bar.assert_called_once_with('baz', spam='eggs') Traceback (most recent call last): ... - AssertionError: Expected to be called once. Called 2 times. + AssertionError: Expected 'foo_bar' to be called once. Called 2 times. + Calls: [call('baz', spam='eggs'), call()]. Both ``assert_called_with`` and ``assert_called_once_with`` make assertions about the *most recent* call. If your mock is going to be called several times, and @@ -835,7 +860,7 @@ One possibility would be for mock to copy the arguments you pass in. This could then cause problems if you do assertions that rely on object identity for equality. -Here's one solution that uses the :attr:`side_effect` +Here's one solution that uses the :attr:`~Mock.side_effect` functionality. If you provide a ``side_effect`` function for a mock then ``side_effect`` will be called with the same args as the mock. This gives us an opportunity to copy the arguments and store them for later assertions. In this @@ -903,8 +928,9 @@ Here's an example implementation: >>> c.assert_called_with(arg) Traceback (most recent call last): ... - AssertionError: Expected call: mock({1}) - Actual call: mock(set()) + AssertionError: expected call not found. + Expected: mock({1}) + Actual: mock(set()) >>> c.foo @@ -971,7 +997,8 @@ We can do this with :class:`MagicMock`, which will behave like a dictionary, and using :data:`~Mock.side_effect` to delegate dictionary access to a real underlying dictionary that is under our control. -When the :meth:`__getitem__` and :meth:`__setitem__` methods of our ``MagicMock`` are called +When the :meth:`~object.__getitem__` and :meth:`~object.__setitem__` methods +of our ``MagicMock`` are called (normal dictionary access) then ``side_effect`` is called with the key (and in the case of ``__setitem__`` the value too). We can also control what is returned. @@ -1267,8 +1294,9 @@ sufficient: >>> mock.assert_called_with(Foo(1, 2)) Traceback (most recent call last): ... - AssertionError: Expected: call(<__main__.Foo object at 0x...>) - Actual call: call(<__main__.Foo object at 0x...>) + AssertionError: expected call not found. + Expected: mock(<__main__.Foo object at 0x...>) + Actual: mock(<__main__.Foo object at 0x...>) A comparison function for our ``Foo`` class might look something like this: diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 6d5f17d1c2c5cd..ea6412abf72d1a 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -189,7 +189,7 @@ code if they are used incorrectly: >>> mock_function('wrong arguments') Traceback (most recent call last): ... - TypeError: () takes exactly 3 arguments (1 given) + TypeError: missing a required argument: 'b' :func:`create_autospec` can also be used on classes, where it copies the signature of the ``__init__`` method, and on callable objects where it copies the signature of @@ -315,6 +315,7 @@ the *new_callable* argument to :func:`patch`. Traceback (most recent call last): ... AssertionError: Expected 'method' to have been called once. Called 2 times. + Calls: [call(), call()]. .. versionadded:: 3.6 @@ -342,7 +343,7 @@ the *new_callable* argument to :func:`patch`. Traceback (most recent call last): ... AssertionError: Expected 'mock' to be called once. Called 2 times. - + Calls: [call('foo', bar='baz'), call('other', bar='values')]. .. method:: assert_any_call(*args, **kwargs) @@ -392,6 +393,7 @@ the *new_callable* argument to :func:`patch`. Traceback (most recent call last): ... AssertionError: Expected 'hello' to not have been called. Called 1 times. + Calls: [call()]. .. versionadded:: 3.5 @@ -816,8 +818,8 @@ This applies to :meth:`~Mock.assert_called_with`, :meth:`~Mock.assert_any_call`. When :ref:`auto-speccing`, it will also apply to method calls on the mock object. - .. versionchanged:: 3.4 - Added signature introspection on specced and autospecced mock objects. +.. versionchanged:: 3.4 + Added signature introspection on specced and autospecced mock objects. .. class:: PropertyMock(*args, **kwargs) @@ -954,7 +956,7 @@ object:: >>> asyncio.run(main()) >>> mock.assert_awaited_once() >>> asyncio.run(main()) - >>> mock.method.assert_awaited_once() + >>> mock.assert_awaited_once() Traceback (most recent call last): ... AssertionError: Expected mock to have been awaited once. Awaited 2 times. @@ -972,7 +974,7 @@ object:: >>> mock.assert_awaited_with('other') Traceback (most recent call last): ... - AssertionError: expected call not found. + AssertionError: expected await not found. Expected: mock('other') Actual: mock('foo', bar='bar') @@ -1128,7 +1130,7 @@ object:: .. method:: wait_until_any_call_with(*args, **kwargs) - Waits until the the mock is called with the specified arguments. + Waits until the mock is called with the specified arguments. If a timeout was passed at the creation of the mock the function raises an :exc:`AssertionError` if the call is not performed in time. @@ -1435,9 +1437,9 @@ patch .. note:: - .. versionchanged:: 3.5 - If you are patching builtins in a module then you don't - need to pass ``create=True``, it will be added by default. + .. versionchanged:: 3.5 + If you are patching builtins in a module then you don't + need to pass ``create=True``, it will be added by default. Patch can be used as a :class:`TestCase` class decorator. It works by decorating each test method in the class. This reduces the boilerplate @@ -2485,7 +2487,7 @@ behaviour you can switch it off by setting the module level switch Alternatively you can just use ``vars(my_mock)`` (instance members) and ``dir(type(my_mock))`` (type members) to bypass the filtering irrespective of -:data:`mock.FILTER_DIR`. +:const:`mock.FILTER_DIR`. mock_open diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index b26e6c0e6bc024..21abc583f853a7 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -206,13 +206,13 @@ Command-line options .. program:: unittest -.. cmdoption:: -b, --buffer +.. option:: -b, --buffer The standard output and standard error streams are buffered during the test run. Output during a passing test is discarded. Output is echoed normally on test fail or error and is added to the failure messages. -.. cmdoption:: -c, --catch +.. option:: -c, --catch :kbd:`Control-C` during the test run waits for the current test to end and then reports all the results so far. A second :kbd:`Control-C` raises the normal @@ -220,11 +220,11 @@ Command-line options See `Signal Handling`_ for the functions that provide this functionality. -.. cmdoption:: -f, --failfast +.. option:: -f, --failfast Stop the test run on the first error or failure. -.. cmdoption:: -k +.. option:: -k Only run test methods and classes that match the pattern or substring. This option may be used multiple times, in which case all test cases that @@ -240,11 +240,11 @@ Command-line options For example, ``-k foo`` matches ``foo_tests.SomeTest.test_something``, ``bar_tests.SomeTest.test_foo``, but not ``bar_tests.FooTest.test_something``. -.. cmdoption:: --locals +.. option:: --locals Show local variables in tracebacks. -.. cmdoption:: --durations N +.. option:: --durations N Show the N slowest test cases (N=0 for all). @@ -292,19 +292,19 @@ The ``discover`` sub-command has the following options: .. program:: unittest discover -.. cmdoption:: -v, --verbose +.. option:: -v, --verbose Verbose output -.. cmdoption:: -s, --start-directory directory +.. option:: -s, --start-directory directory Directory to start discovery (``.`` default) -.. cmdoption:: -p, --pattern pattern +.. option:: -p, --pattern pattern Pattern to match test files (``test*.py`` default) -.. cmdoption:: -t, --top-level-directory directory +.. option:: -t, --top-level-directory directory Top level directory of project (defaults to start directory) @@ -1134,7 +1134,7 @@ Test cases If given, *level* should be either a numeric logging level or its string equivalent (for example either ``"ERROR"`` or - :attr:`logging.ERROR`). The default is :attr:`logging.INFO`. + :const:`logging.ERROR`). The default is :const:`logging.INFO`. The test passes if at least one message emitted inside the ``with`` block matches the *logger* and *level* conditions, otherwise it fails. @@ -1175,7 +1175,7 @@ Test cases If given, *level* should be either a numeric logging level or its string equivalent (for example either ``"ERROR"`` or - :attr:`logging.ERROR`). The default is :attr:`logging.INFO`. + :const:`logging.ERROR`). The default is :const:`logging.INFO`. Unlike :meth:`assertLogs`, nothing will be returned by the context manager. @@ -2017,7 +2017,7 @@ Loading and running tests .. attribute:: collectedDurations - A list containing 2-tuples of :class:`TestCase` instances and floats + A list containing 2-tuples of test case names and floats representing the elapsed time of each test which was run. .. versionadded:: 3.12 diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst index 3adbdd26132273..facb11f42a40c5 100644 --- a/Doc/library/urllib.error.rst +++ b/Doc/library/urllib.error.rst @@ -27,8 +27,8 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate: exception instance. .. versionchanged:: 3.3 - :exc:`URLError` has been made a subclass of :exc:`OSError` instead - of :exc:`IOError`. + :exc:`URLError` used to be a subtype of :exc:`IOError`, which is now an + alias of :exc:`OSError`. .. exception:: HTTPError(url, code, msg, hdrs, fp) @@ -72,6 +72,8 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate: This exception is raised when the :func:`~urllib.request.urlretrieve` function detects that the amount of the downloaded data is less than the expected amount (given by - the *Content-Length* header). The :attr:`content` attribute stores the - downloaded (and supposedly truncated) data. + the *Content-Length* header). + .. attribute:: content + + The downloaded (and supposedly truncated) data. diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index e1aa4ebb0964dd..53e5f0395715d7 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -598,7 +598,7 @@ task isn't already covered by the URL parsing functions above. .. function:: quote(string, safe='/', encoding=None, errors=None) - Replace special characters in *string* using the ``%xx`` escape. Letters, + Replace special characters in *string* using the :samp:`%{xx}` escape. Letters, digits, and the characters ``'_.-~'`` are never quoted. By default, this function is intended for quoting the path section of a URL. The optional *safe* parameter specifies additional ASCII characters that should not be @@ -645,7 +645,7 @@ task isn't already covered by the URL parsing functions above. .. function:: unquote(string, encoding='utf-8', errors='replace') - Replace ``%xx`` escapes with their single-character equivalent. + Replace :samp:`%{xx}` escapes with their single-character equivalent. The optional *encoding* and *errors* parameters specify how to decode percent-encoded sequences into Unicode characters, as accepted by the :meth:`bytes.decode` method. @@ -676,7 +676,7 @@ task isn't already covered by the URL parsing functions above. .. function:: unquote_to_bytes(string) - Replace ``%xx`` escapes with their single-octet equivalent, and return a + Replace :samp:`%{xx}` escapes with their single-octet equivalent, and return a :class:`bytes` object. *string* may be either a :class:`str` or a :class:`bytes` object. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 7e79871bbd6077..bf3af1bef0714c 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -91,7 +91,7 @@ The :mod:`urllib.request` module defines the following functions: .. versionchanged:: 3.2 HTTPS virtual hosts are now supported if possible (that is, if - :data:`ssl.HAS_SNI` is true). + :const:`ssl.HAS_SNI` is true). .. versionadded:: 3.2 *data* can be an iterable object. @@ -304,10 +304,10 @@ The following classes are provided: list of hostname suffixes, optionally with ``:port`` appended, for example ``cern.ch,ncsa.uiuc.edu,some.host:8080``. - .. note:: + .. note:: - ``HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set; - see the documentation on :func:`~urllib.request.getproxies`. + ``HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set; + see the documentation on :func:`~urllib.request.getproxies`. .. class:: HTTPPasswordMgr() @@ -1525,9 +1525,9 @@ some point in the future. :mod:`urllib.request` Restrictions ---------------------------------- - .. index:: - pair: HTTP; protocol - pair: FTP; protocol +.. index:: + pair: HTTP; protocol + pair: FTP; protocol * Currently, only the following protocols are supported: HTTP (versions 0.9 and 1.0), FTP, local files, and data URLs. diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index 94b9a432372195..e2d231da38fd9a 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -22,7 +22,7 @@ random UUID. Depending on support from the underlying platform, :func:`uuid1` may or may not return a "safe" UUID. A safe UUID is one which is generated using synchronization methods that ensure no two processes can obtain the same -UUID. All instances of :class:`UUID` have an :attr:`is_safe` attribute +UUID. All instances of :class:`UUID` have an :attr:`~UUID.is_safe` attribute which relays any information about the UUID's safety, using this enumeration: .. class:: SafeUUID @@ -95,25 +95,34 @@ which relays any information about the UUID's safety, using this enumeration: A tuple of the six integer fields of the UUID, which are also available as six individual attributes and two derived attributes: - +------------------------------+-------------------------------+ - | Field | Meaning | - +==============================+===============================+ - | :attr:`time_low` | the first 32 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`time_mid` | the next 16 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`time_hi_version` | the next 16 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`clock_seq_hi_variant` | the next 8 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`clock_seq_low` | the next 8 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`node` | the last 48 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`time` | the 60-bit timestamp | - +------------------------------+-------------------------------+ - | :attr:`clock_seq` | the 14-bit sequence number | - +------------------------------+-------------------------------+ +.. list-table:: + + * - Field + - Meaning + + * - .. attribute:: UUID.time_low + - The first 32 bits of the UUID. + + * - .. attribute:: UUID.time_mid + - The next 16 bits of the UUID. + + * - .. attribute:: UUID.time_hi_version + - The next 16 bits of the UUID. + + * - .. attribute:: UUID.clock_seq_hi_variant + - The next 8 bits of the UUID. + + * - .. attribute:: UUID.clock_seq_low + - The next 8 bits of the UUID. + + * - .. attribute:: UUID.node + - The last 48 bits of the UUID. + + * - .. attribute:: UUID.time + - The 60-bit timestamp. + + * - .. attribute:: UUID.clock_seq + - The 14-bit sequence number. .. attribute:: UUID.hex @@ -233,7 +242,7 @@ The :mod:`uuid` module defines the following namespace identifiers for use with text output format. The :mod:`uuid` module defines the following constants for the possible values -of the :attr:`variant` attribute: +of the :attr:`~UUID.variant` attribute: .. data:: RESERVED_NCS @@ -280,25 +289,25 @@ The following options are accepted: .. program:: uuid -.. cmdoption:: -h, --help +.. option:: -h, --help Show the help message and exit. -.. cmdoption:: -u - --uuid +.. option:: -u + --uuid Specify the function name to use to generate the uuid. By default :func:`uuid4` is used. -.. cmdoption:: -n - --namespace +.. option:: -n + --namespace The namespace is a ``UUID``, or ``@ns`` where ``ns`` is a well-known predefined UUID addressed by namespace name. Such as ``@dns``, ``@url``, ``@oid``, and ``@x500``. Only required for :func:`uuid3` / :func:`uuid5` functions. -.. cmdoption:: -N - --name +.. option:: -N + --name The name used as part of generating the uuid. Only required for :func:`uuid3` / :func:`uuid5` functions. diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 9e5672545dea35..da8942c554dea1 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -30,6 +30,25 @@ When used from within a virtual environment, common installation tools such as `pip`_ will install Python packages into a virtual environment without needing to be told to do so explicitly. +A virtual environment is (amongst other things): + +* Used to contain a specific Python interpreter and software libraries and + binaries which are needed to support a project (library or application). These + are by default isolated from software in other virtual environments and Python + interpreters and libraries installed in the operating system. + +* Contained in a directory, conventionally either named ``venv`` or ``.venv`` in + the project directory, or under a container directory for lots of virtual + environments, such as ``~/.virtualenvs``. + +* Not checked into source control systems such as Git. + +* Considered as disposable -- it should be simple to delete and recreate it from + scratch. You don't place any project code in the environment + +* Not considered as movable or copyable -- you just recreate the same + environment in the target location. + See :pep:`405` for more background on Python virtual environments. .. seealso:: @@ -60,7 +79,7 @@ running from a virtual environment. A virtual environment may be "activated" using a script in its binary directory (``bin`` on POSIX; ``Scripts`` on Windows). -This will prepend that directory to your :envvar:`!PATH`, so that running +This will prepend that directory to your :envvar:`PATH`, so that running :program:`python` will invoke the environment's Python interpreter and you can run installed scripts without having to use their full path. The invocation of the activation script is platform-specific @@ -100,10 +119,10 @@ In order to achieve this, scripts installed into virtual environments have a "shebang" line which points to the environment's Python interpreter, i.e. :samp:`#!/{}/bin/python`. This means that the script will run with that interpreter regardless of the -value of :envvar:`!PATH`. On Windows, "shebang" line processing is supported if +value of :envvar:`PATH`. On Windows, "shebang" line processing is supported if you have the :ref:`launcher` installed. Thus, double-clicking an installed script in a Windows Explorer window should run it with the correct interpreter -without the environment needing to be activated or on the :envvar:`!PATH`. +without the environment needing to be activated or on the :envvar:`PATH`. When a virtual environment has been activated, the :envvar:`!VIRTUAL_ENV` environment variable is set to the path of the environment. @@ -143,7 +162,8 @@ creation according to their needs, the :class:`EnvBuilder` class. .. class:: EnvBuilder(system_site_packages=False, clear=False, \ symlinks=False, upgrade=False, with_pip=False, \ - prompt=None, upgrade_deps=False) + prompt=None, upgrade_deps=False, \ + *, scm_ignore_files=frozenset()) The :class:`EnvBuilder` class accepts the following keyword arguments on instantiation: @@ -172,6 +192,12 @@ creation according to their needs, the :class:`EnvBuilder` class. * ``upgrade_deps`` -- Update the base venv modules to the latest on PyPI + * ``scm_ignore_files`` -- Create ignore files based for the specified source + control managers (SCM) in the iterable. Support is defined by having a + method named ``create_{scm}_ignore_file``. The only value supported by + default is ``"git"`` via :meth:`create_git_ignore_file`. + + .. versionchanged:: 3.4 Added the ``with_pip`` parameter @@ -181,6 +207,9 @@ creation according to their needs, the :class:`EnvBuilder` class. .. versionadded:: 3.9 Added the ``upgrade_deps`` parameter + .. versionadded:: 3.13 + Added the ``scm_ignore_files`` parameter + Creators of third-party virtual environment tools will be free to use the provided :class:`EnvBuilder` class as a base class. @@ -339,11 +368,18 @@ creation according to their needs, the :class:`EnvBuilder` class. The directories are allowed to exist (for when an existing environment is being upgraded). + .. method:: create_git_ignore_file(context) + + Creates a ``.gitignore`` file within the virtual environment that causes + the entire directory to be ignored by the ``git`` source control manager. + + .. versionadded:: 3.13 + There is also a module-level convenience function: .. function:: create(env_dir, system_site_packages=False, clear=False, \ symlinks=False, with_pip=False, prompt=None, \ - upgrade_deps=False) + upgrade_deps=False, *, scm_ignore_files=frozenset()) Create an :class:`EnvBuilder` with the given keyword arguments, and call its :meth:`~EnvBuilder.create` method with the *env_dir* argument. @@ -359,6 +395,9 @@ There is also a module-level convenience function: .. versionchanged:: 3.9 Added the ``upgrade_deps`` parameter + .. versionchanged:: 3.13 + Added the ``scm_ignore_files`` parameter + An example of extending ``EnvBuilder`` -------------------------------------- diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 1406b663c6a8e2..d6e062df945c64 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -111,7 +111,7 @@ See :ref:`__slots__ documentation ` for details. Exceptions raised by the callback will be noted on the standard error output, but cannot be propagated; they are handled in exactly the same way as exceptions - raised from an object's :meth:`__del__` method. + raised from an object's :meth:`~object.__del__` method. Weak references are :term:`hashable` if the *object* is hashable. They will maintain their hash value even after the *object* was deleted. If @@ -221,8 +221,7 @@ than needed. Added support for ``|`` and ``|=`` operators, as specified in :pep:`584`. :class:`WeakValueDictionary` objects have an additional method that has the -same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary` -objects. +same issues as the :meth:`WeakKeyDictionary.keyrefs` method. .. method:: WeakValueDictionary.valuerefs() @@ -281,7 +280,7 @@ objects. Exceptions raised by finalizer callbacks during garbage collection will be shown on the standard error output, but cannot be propagated. They are handled in the same way as exceptions raised - from an object's :meth:`__del__` method or a weak reference's + from an object's :meth:`~object.__del__` method or a weak reference's callback. When the program exits, each remaining live finalizer is called @@ -523,18 +522,18 @@ is still alive. For instance obj dead or exiting -Comparing finalizers with :meth:`__del__` methods -------------------------------------------------- +Comparing finalizers with :meth:`~object.__del__` methods +--------------------------------------------------------- Suppose we want to create a class whose instances represent temporary directories. The directories should be deleted with their contents when the first of the following events occurs: * the object is garbage collected, -* the object's :meth:`remove` method is called, or +* the object's :meth:`!remove` method is called, or * the program exits. -We might try to implement the class using a :meth:`__del__` method as +We might try to implement the class using a :meth:`~object.__del__` method as follows:: class TempDir: @@ -553,12 +552,12 @@ follows:: def __del__(self): self.remove() -Starting with Python 3.4, :meth:`__del__` methods no longer prevent +Starting with Python 3.4, :meth:`~object.__del__` methods no longer prevent reference cycles from being garbage collected, and module globals are no longer forced to :const:`None` during :term:`interpreter shutdown`. So this code should work without any issues on CPython. -However, handling of :meth:`__del__` methods is notoriously implementation +However, handling of :meth:`~object.__del__` methods is notoriously implementation specific, since it depends on internal details of the interpreter's garbage collector implementation. diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index b6762f78830a5f..4667b81e38ada2 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -20,7 +20,7 @@ will be used if graphical browsers are not available or an X11 display isn't available. If text-mode browsers are used, the calling process will block until the user exits the browser. -If the environment variable :envvar:`!BROWSER` exists, it is interpreted as the +If the environment variable :envvar:`BROWSER` exists, it is interpreted as the :data:`os.pathsep`-separated list of browsers to try ahead of the platform defaults. When the value of a list part contains the string ``%s``, then it is interpreted as a literal browser command line to be used with the argument URL @@ -97,7 +97,7 @@ The following functions are defined: Setting *preferred* to ``True`` makes this browser a preferred result for a :func:`get` call with no argument. Otherwise, this entry point is only - useful if you plan to either set the :envvar:`!BROWSER` variable or call + useful if you plan to either set the :envvar:`BROWSER` variable or call :func:`get` with a nonempty argument matching the name of a handler you declare. @@ -224,4 +224,4 @@ module-level convenience functions: .. rubric:: Footnotes .. [1] Executables named here without a full path will be searched in the - directories given in the :envvar:`!PATH` environment variable. + directories given in the :envvar:`PATH` environment variable. diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 4ab671817710dd..06bd4d87eb03c6 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -288,7 +288,7 @@ This module offers the following functions: table (FAT) file system, the filename may not have an extension. A call to :func:`LoadKey` fails if the calling process does not have the - :const:`SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different + :c:data:`!SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different from permissions -- see the `RegLoadKey documentation `__ for more details. @@ -414,7 +414,7 @@ This module offers the following functions: If *key* represents a key on a remote computer, the path described by *file_name* is relative to the remote computer. The caller of this method must - possess the :const:`SeBackupPrivilege` security privilege. Note that + possess the **SeBackupPrivilege** security privilege. Note that privileges are different than permissions -- see the `Conflicts Between User Rights and Permissions documentation `__ @@ -536,7 +536,7 @@ This module offers the following functions: Constants ------------------ -The following constants are defined for use in many :mod:`_winreg` functions. +The following constants are defined for use in many :mod:`winreg` functions. .. _hkey-constants: @@ -745,7 +745,7 @@ All registry functions in this module return one of these objects. All registry functions in this module which accept a handle object also accept an integer, however, use of the handle object is encouraged. -Handle objects provide semantics for :meth:`__bool__` -- thus :: +Handle objects provide semantics for :meth:`~object.__bool__` -- thus :: if handle: print("Yes") diff --git a/Doc/library/winsound.rst b/Doc/library/winsound.rst index 372f792a0f938e..370c5216652ba7 100644 --- a/Doc/library/winsound.rst +++ b/Doc/library/winsound.rst @@ -24,7 +24,7 @@ provided by Windows platforms. It includes functions and several constants. .. function:: PlaySound(sound, flags) - Call the underlying :c:func:`PlaySound` function from the Platform API. The + Call the underlying :c:func:`!PlaySound` function from the Platform API. The *sound* parameter may be a filename, a system sound alias, audio data as a :term:`bytes-like object`, or ``None``. Its interpretation depends on the value of *flags*, which can be a bitwise ORed @@ -35,7 +35,7 @@ provided by Windows platforms. It includes functions and several constants. .. function:: MessageBeep(type=MB_OK) - Call the underlying :c:func:`MessageBeep` function from the Platform API. This + Call the underlying :c:func:`!MessageBeep` function from the Platform API. This plays a sound as specified in the registry. The *type* argument specifies which sound to play; possible values are ``-1``, ``MB_ICONASTERISK``, ``MB_ICONEXCLAMATION``, ``MB_ICONHAND``, ``MB_ICONQUESTION``, and ``MB_OK``, all diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index f9290f528e5555..54c93008503c02 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -17,7 +17,7 @@ for parsing and creating XML data. This module will use a fast implementation whenever available. .. deprecated:: 3.3 - The :mod:`xml.etree.cElementTree` module is deprecated. + The :mod:`!xml.etree.cElementTree` module is deprecated. .. warning:: @@ -825,6 +825,8 @@ Reference Functions ^^^^^^^^^ +.. module:: xml.etree.ElementInclude + .. function:: xml.etree.ElementInclude.default_loader( href, parse, encoding=None) :module: @@ -862,6 +864,9 @@ Functions Element Objects ^^^^^^^^^^^^^^^ +.. module:: xml.etree.ElementTree + :noindex: + .. class:: Element(tag, attrib={}, **extra) Element class. This class defines the Element interface, and provides a diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index 20b0905bb1093a..1e49b6568dfc28 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -73,12 +73,12 @@ decompression bomb Safe Safe Safe 1. Expat 2.4.1 and newer is not vulnerable to the "billion laughs" and "quadratic blowup" vulnerabilities. Items still listed as vulnerable due to potential reliance on system-provided libraries. Check - :data:`pyexpat.EXPAT_VERSION`. + :const:`pyexpat.EXPAT_VERSION`. 2. :mod:`xml.etree.ElementTree` doesn't expand external entities and raises a - :exc:`ParserError` when an entity occurs. + :exc:`~xml.etree.ElementTree.ParseError` when an entity occurs. 3. :mod:`xml.dom.minidom` doesn't expand external entities and simply returns the unexpanded entity verbatim. -4. :mod:`xmlrpclib` doesn't expand external entities and omits them. +4. :mod:`xmlrpc.client` doesn't expand external entities and omits them. 5. Since Python 3.7.1, external general entities are no longer processed by default. @@ -119,8 +119,8 @@ all known attack vectors with examples and references. .. _defusedxml-package: -The :mod:`defusedxml` Package ------------------------------------------------------- +The :mod:`!defusedxml` Package +------------------------------ `defusedxml`_ is a pure Python package with modified subclasses of all stdlib XML parsers that prevent any potentially malicious operation. Use of this diff --git a/Doc/library/xml.sax.handler.rst b/Doc/library/xml.sax.handler.rst index 719ce5ab1bcf65..e2f28e3244cb09 100644 --- a/Doc/library/xml.sax.handler.rst +++ b/Doc/library/xml.sax.handler.rst @@ -393,7 +393,7 @@ implements this interface, then register the object with your :class:`~xml.sax.xmlreader.XMLReader`, the parser will call the methods in your object to report all warnings and errors. There are three levels of errors available: warnings, (possibly) recoverable errors, -and unrecoverable errors. All methods take a :exc:`SAXParseException` as the +and unrecoverable errors. All methods take a :exc:`~xml.sax.SAXParseException` as the only parameter. Errors and warnings may be converted to an exception by raising the passed-in exception object. diff --git a/Doc/library/xml.sax.utils.rst b/Doc/library/xml.sax.utils.rst index ab4606bcf9fe6c..e57e76dcac7820 100644 --- a/Doc/library/xml.sax.utils.rst +++ b/Doc/library/xml.sax.utils.rst @@ -92,5 +92,5 @@ or as base classes. reading. The input source can be given as a string, a file-like object, or an :class:`~xml.sax.xmlreader.InputSource` object; parsers will use this function to implement the polymorphic *source* argument to their - :meth:`parse` method. + :meth:`~xml.sax.xmlreader.XMLReader.parse` method. diff --git a/Doc/library/xmlrpc.rst b/Doc/library/xmlrpc.rst index ae68157b0f63c1..5f0a2cf68d01f9 100644 --- a/Doc/library/xmlrpc.rst +++ b/Doc/library/xmlrpc.rst @@ -1,5 +1,5 @@ -:mod:`xmlrpc` --- XMLRPC server and client modules -================================================== +:mod:`!xmlrpc` --- XMLRPC server and client modules +=================================================== XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport. With it, a client can call methods with parameters on a remote diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst index 8cee85b32d2a83..104afca23a20b4 100644 --- a/Doc/library/zipapp.rst +++ b/Doc/library/zipapp.rst @@ -54,7 +54,7 @@ The following options are understood: .. program:: zipapp -.. cmdoption:: -o , --output= +.. option:: -o , --output= Write the output to a file named *output*. If this option is not specified, the output filename will be the same as the input *source*, with the @@ -64,13 +64,13 @@ The following options are understood: An output filename must be specified if the *source* is an archive (and in that case, *output* must not be the same as *source*). -.. cmdoption:: -p , --python= +.. option:: -p , --python= Add a ``#!`` line to the archive specifying *interpreter* as the command to run. Also, on POSIX, make the archive executable. The default is to write no ``#!`` line, and not make the file executable. -.. cmdoption:: -m , --main= +.. option:: -m , --main= Write a ``__main__.py`` file to the archive that executes *mainfn*. The *mainfn* argument should have the form "pkg.mod:fn", where "pkg.mod" is a @@ -79,7 +79,7 @@ The following options are understood: :option:`--main` cannot be specified when copying an archive. -.. cmdoption:: -c, --compress +.. option:: -c, --compress Compress files with the deflate method, reducing the size of the output file. By default, files are stored uncompressed in the archive. @@ -88,13 +88,13 @@ The following options are understood: .. versionadded:: 3.7 -.. cmdoption:: --info +.. option:: --info Display the interpreter embedded in the archive, for diagnostic purposes. In this case, any other options are ignored and SOURCE must be an archive, not a directory. -.. cmdoption:: -h, --help +.. option:: -h, --help Print a short usage message and exit. @@ -281,12 +281,7 @@ The steps to create a standalone archive are as follows: file - if not, you can just list the dependencies manually on the pip command line). -3. Optionally, delete the ``.dist-info`` directories created by pip in the - ``myapp`` directory. These hold metadata for pip to manage the packages, and - as you won't be making any further use of pip they aren't required - - although it won't do any harm if you leave them. - -4. Package the application using: +3. Package the application using: .. code-block:: shell-session diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index bd951e4872f113..a77e49a7643826 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -906,27 +906,27 @@ For a list of the files in a ZIP archive, use the :option:`-l` option: Command-line options ~~~~~~~~~~~~~~~~~~~~ -.. cmdoption:: -l - --list +.. option:: -l + --list List files in a zipfile. -.. cmdoption:: -c ... - --create ... +.. option:: -c ... + --create ... Create zipfile from source files. -.. cmdoption:: -e - --extract +.. option:: -e + --extract Extract zipfile into target directory. -.. cmdoption:: -t - --test +.. option:: -t + --test Test whether the zipfile is valid or not. -.. cmdoption:: --metadata-encoding +.. option:: --metadata-encoding Specify encoding of member names for :option:`-l`, :option:`-e` and :option:`-t`. diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 11d19e8c863e9f..47c81f0e63603d 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -113,7 +113,7 @@ zipimporter Objects file wasn't found. .. versionchanged:: 3.3 - :exc:`IOError` used to be raised instead of :exc:`OSError`. + :exc:`IOError` used to be raised, it is now an alias of :exc:`OSError`. .. method:: get_filename(fullname) diff --git a/Doc/license.rst b/Doc/license.rst index 1dadb6264a0059..82039fd9aaf9d0 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -352,8 +352,8 @@ the verbatim comments from the original code:: Sockets ------- -The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and -:func:`getnameinfo`, which are coded in separate source files from the WIDE +The :mod:`socket` module uses the functions, :c:func:`!getaddrinfo`, and +:c:func:`!getnameinfo`, which are coded in separate source files from the WIDE Project, https://www.wide.ad.jp/. :: Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -387,7 +387,7 @@ Project, https://www.wide.ad.jp/. :: Asynchronous socket services ---------------------------- -The :mod:`test.support.asynchat` and :mod:`test.support.asyncore` +The :mod:`!test.support.asynchat` and :mod:`!test.support.asyncore` modules contain the following notice:: Copyright 1996 by Sam Rushing @@ -539,7 +539,7 @@ The :mod:`xmlrpc.client` module contains the following notice:: test_epoll ---------- -The :mod:`test_epoll` module contains the following notice:: +The :mod:`!test.test_epoll` module contains the following notice:: Copyright (c) 2001-2006 Twisted Matrix Laboratories. @@ -659,140 +659,192 @@ The modules :mod:`hashlib`, :mod:`posix` and :mod:`ssl` use the OpenSSL library for added performance if made available by the operating system. Additionally, the Windows and macOS installers for Python may include a copy of the OpenSSL libraries, so we include a copy -of the OpenSSL license here:: - - - LICENSE ISSUES - ============== - - The OpenSSL toolkit stays under a dual license, i.e. both the conditions of - the OpenSSL License and the original SSLeay license apply to the toolkit. - See below for the actual license texts. Actually both licenses are BSD-style - Open Source licenses. In case of any license issues related to OpenSSL - please contact openssl-core@openssl.org. - - OpenSSL License - --------------- - - /* ==================================================================== - * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - - /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ +of the OpenSSL license here. For the OpenSSL 3.0 release, +and later releases derived from that, the Apache License v2 applies:: + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS expat ----- -The :mod:`pyexpat` extension is built using an included copy of the expat +The :mod:`pyexpat ` extension is built using an included copy of the expat sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 6d30eccab1990f..f79db828604b24 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -642,14 +642,14 @@ Here's an overview of the logical flow of a match statement: specified below. **Name bindings made during a successful pattern match outlive the executed block and can be used after the match statement**. - .. note:: + .. note:: - During failed pattern matches, some subpatterns may succeed. Do not - rely on bindings being made for a failed match. Conversely, do not - rely on variables remaining unchanged after a failed match. The exact - behavior is dependent on implementation and may vary. This is an - intentional decision made to allow different implementations to add - optimizations. + During failed pattern matches, some subpatterns may succeed. Do not + rely on bindings being made for a failed match. Conversely, do not + rely on variables remaining unchanged after a failed match. The exact + behavior is dependent on implementation and may vary. This is an + intentional decision made to allow different implementations to add + optimizations. #. If the pattern succeeds, the corresponding guard (if present) is evaluated. In this case all name bindings are guaranteed to have happened. @@ -1170,8 +1170,10 @@ In simple terms ``CLS(P1, attr=P2)`` matches only if the following happens: * ``isinstance(, CLS)`` * convert ``P1`` to a keyword pattern using ``CLS.__match_args__`` * For each keyword argument ``attr=P2``: - * ``hasattr(, "attr")`` - * ``P2`` matches ``.attr`` + + * ``hasattr(, "attr")`` + * ``P2`` matches ``.attr`` + * ... and so on for the corresponding keyword argument/pattern pair. .. seealso:: @@ -1838,29 +1840,29 @@ like ``TYPE_PARAMS_OF_ListOrSet`` are not actually bound at runtime. .. [#] In pattern matching, a sequence is defined as one of the following: - * a class that inherits from :class:`collections.abc.Sequence` - * a Python class that has been registered as :class:`collections.abc.Sequence` - * a builtin class that has its (CPython) :data:`Py_TPFLAGS_SEQUENCE` bit set - * a class that inherits from any of the above + * a class that inherits from :class:`collections.abc.Sequence` + * a Python class that has been registered as :class:`collections.abc.Sequence` + * a builtin class that has its (CPython) :c:macro:`Py_TPFLAGS_SEQUENCE` bit set + * a class that inherits from any of the above The following standard library classes are sequences: - * :class:`array.array` - * :class:`collections.deque` - * :class:`list` - * :class:`memoryview` - * :class:`range` - * :class:`tuple` + * :class:`array.array` + * :class:`collections.deque` + * :class:`list` + * :class:`memoryview` + * :class:`range` + * :class:`tuple` .. note:: Subject values of type ``str``, ``bytes``, and ``bytearray`` do not match sequence patterns. .. [#] In pattern matching, a mapping is defined as one of the following: - * a class that inherits from :class:`collections.abc.Mapping` - * a Python class that has been registered as :class:`collections.abc.Mapping` - * a builtin class that has its (CPython) :data:`Py_TPFLAGS_MAPPING` bit set - * a class that inherits from any of the above + * a class that inherits from :class:`collections.abc.Mapping` + * a Python class that has been registered as :class:`collections.abc.Mapping` + * a builtin class that has its (CPython) :c:macro:`Py_TPFLAGS_MAPPING` bit set + * a class that inherits from any of the above The standard library classes :class:`dict` and :class:`types.MappingProxyType` are mappings. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 8a10a34347c2de..cc81f73f824352 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -141,1095 +141,1201 @@ Some of the type descriptions below contain a paragraph listing 'special attributes.' These are attributes that provide access to the implementation and are not intended for general use. Their definition may change in the future. + None - .. index:: pair: object; None +---- + +.. index:: pair: object; None + +This type has a single value. There is a single object with this value. This +object is accessed through the built-in name ``None``. It is used to signify the +absence of a value in many situations, e.g., it is returned from functions that +don't explicitly return anything. Its truth value is false. - This type has a single value. There is a single object with this value. This - object is accessed through the built-in name ``None``. It is used to signify the - absence of a value in many situations, e.g., it is returned from functions that - don't explicitly return anything. Its truth value is false. NotImplemented - .. index:: pair: object; NotImplemented +-------------- + +.. index:: pair: object; NotImplemented - This type has a single value. There is a single object with this value. This - object is accessed through the built-in name ``NotImplemented``. Numeric methods - and rich comparison methods should return this value if they do not implement the - operation for the operands provided. (The interpreter will then try the - reflected operation, or some other fallback, depending on the operator.) It - should not be evaluated in a boolean context. +This type has a single value. There is a single object with this value. This +object is accessed through the built-in name ``NotImplemented``. Numeric methods +and rich comparison methods should return this value if they do not implement the +operation for the operands provided. (The interpreter will then try the +reflected operation, or some other fallback, depending on the operator.) It +should not be evaluated in a boolean context. - See - :ref:`implementing-the-arithmetic-operations` - for more details. +See +:ref:`implementing-the-arithmetic-operations` +for more details. - .. versionchanged:: 3.9 - Evaluating ``NotImplemented`` in a boolean context is deprecated. While - it currently evaluates as true, it will emit a :exc:`DeprecationWarning`. - It will raise a :exc:`TypeError` in a future version of Python. +.. versionchanged:: 3.9 + Evaluating ``NotImplemented`` in a boolean context is deprecated. While + it currently evaluates as true, it will emit a :exc:`DeprecationWarning`. + It will raise a :exc:`TypeError` in a future version of Python. Ellipsis - .. index:: - pair: object; Ellipsis - single: ...; ellipsis literal +-------- +.. index:: + pair: object; Ellipsis + single: ...; ellipsis literal + +This type has a single value. There is a single object with this value. This +object is accessed through the literal ``...`` or the built-in name +``Ellipsis``. Its truth value is true. - This type has a single value. There is a single object with this value. This - object is accessed through the literal ``...`` or the built-in name - ``Ellipsis``. Its truth value is true. :class:`numbers.Number` - .. index:: pair: object; numeric +----------------------- + +.. index:: pair: object; numeric + +These are created by numeric literals and returned as results by arithmetic +operators and arithmetic built-in functions. Numeric objects are immutable; +once created their value never changes. Python numbers are of course strongly +related to mathematical numbers, but subject to the limitations of numerical +representation in computers. + +The string representations of the numeric classes, computed by +:meth:`~object.__repr__` and :meth:`~object.__str__`, have the following +properties: + +* They are valid numeric literals which, when passed to their + class constructor, produce an object having the value of the + original numeric. + +* The representation is in base 10, when possible. + +* Leading zeros, possibly excepting a single zero before a + decimal point, are not shown. - These are created by numeric literals and returned as results by arithmetic - operators and arithmetic built-in functions. Numeric objects are immutable; - once created their value never changes. Python numbers are of course strongly - related to mathematical numbers, but subject to the limitations of numerical - representation in computers. +* Trailing zeros, possibly excepting a single zero after a + decimal point, are not shown. - The string representations of the numeric classes, computed by - :meth:`~object.__repr__` and :meth:`~object.__str__`, have the following - properties: +* A sign is shown only when the number is negative. - * They are valid numeric literals which, when passed to their - class constructor, produce an object having the value of the - original numeric. +Python distinguishes between integers, floating point numbers, and complex +numbers: - * The representation is in base 10, when possible. - * Leading zeros, possibly excepting a single zero before a - decimal point, are not shown. +:class:`numbers.Integral` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: pair: object; integer - * Trailing zeros, possibly excepting a single zero after a - decimal point, are not shown. +These represent elements from the mathematical set of integers (positive and +negative). - * A sign is shown only when the number is negative. +.. note:: + .. index:: pair: integer; representation - Python distinguishes between integers, floating point numbers, and complex - numbers: + The rules for integer representation are intended to give the most meaningful + interpretation of shift and mask operations involving negative integers. - :class:`numbers.Integral` - .. index:: pair: object; integer +There are two types of integers: - These represent elements from the mathematical set of integers (positive and - negative). +Integers (:class:`int`) + These represent numbers in an unlimited range, subject to available (virtual) + memory only. For the purpose of shift and mask operations, a binary + representation is assumed, and negative numbers are represented in a variant of + 2's complement which gives the illusion of an infinite string of sign bits + extending to the left. - There are two types of integers: +Booleans (:class:`bool`) + .. index:: + pair: object; Boolean + single: False + single: True - Integers (:class:`int`) - These represent numbers in an unlimited range, subject to available (virtual) - memory only. For the purpose of shift and mask operations, a binary - representation is assumed, and negative numbers are represented in a variant of - 2's complement which gives the illusion of an infinite string of sign bits - extending to the left. + These represent the truth values False and True. The two objects representing + the values ``False`` and ``True`` are the only Boolean objects. The Boolean type is a + subtype of the integer type, and Boolean values behave like the values 0 and 1, + respectively, in almost all contexts, the exception being that when converted to + a string, the strings ``"False"`` or ``"True"`` are returned, respectively. - Booleans (:class:`bool`) - .. index:: - pair: object; Boolean - single: False - single: True - These represent the truth values False and True. The two objects representing - the values ``False`` and ``True`` are the only Boolean objects. The Boolean type is a - subtype of the integer type, and Boolean values behave like the values 0 and 1, - respectively, in almost all contexts, the exception being that when converted to - a string, the strings ``"False"`` or ``"True"`` are returned, respectively. +:class:`numbers.Real` (:class:`float`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; floating point + pair: floating point; number + pair: C; language + pair: Java; language - .. index:: pair: integer; representation +These represent machine-level double precision floating point numbers. You are +at the mercy of the underlying machine architecture (and C or Java +implementation) for the accepted range and handling of overflow. Python does not +support single-precision floating point numbers; the savings in processor and +memory usage that are usually the reason for using these are dwarfed by the +overhead of using objects in Python, so there is no reason to complicate the +language with two kinds of floating point numbers. - The rules for integer representation are intended to give the most meaningful - interpretation of shift and mask operations involving negative integers. - :class:`numbers.Real` (:class:`float`) - .. index:: - pair: object; floating point - pair: floating point; number - pair: C; language - pair: Java; language +:class:`numbers.Complex` (:class:`complex`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - These represent machine-level double precision floating point numbers. You are - at the mercy of the underlying machine architecture (and C or Java - implementation) for the accepted range and handling of overflow. Python does not - support single-precision floating point numbers; the savings in processor and - memory usage that are usually the reason for using these are dwarfed by the - overhead of using objects in Python, so there is no reason to complicate the - language with two kinds of floating point numbers. +.. index:: + pair: object; complex + pair: complex; number - :class:`numbers.Complex` (:class:`complex`) - .. index:: - pair: object; complex - pair: complex; number +These represent complex numbers as a pair of machine-level double precision +floating point numbers. The same caveats apply as for floating point numbers. +The real and imaginary parts of a complex number ``z`` can be retrieved through +the read-only attributes ``z.real`` and ``z.imag``. - These represent complex numbers as a pair of machine-level double precision - floating point numbers. The same caveats apply as for floating point numbers. - The real and imaginary parts of a complex number ``z`` can be retrieved through - the read-only attributes ``z.real`` and ``z.imag``. Sequences +--------- + +.. index:: + pair: built-in function; len + pair: object; sequence + single: index operation + single: item selection + single: subscription + +These represent finite ordered sets indexed by non-negative numbers. The +built-in function :func:`len` returns the number of items of a sequence. When +the length of a sequence is *n*, the index set contains the numbers 0, 1, +..., *n*-1. Item *i* of sequence *a* is selected by ``a[i]``. + +.. index:: single: slicing + +Sequences also support slicing: ``a[i:j]`` selects all items with index *k* such +that *i* ``<=`` *k* ``<`` *j*. When used as an expression, a slice is a +sequence of the same type. This implies that the index set is renumbered so +that it starts at 0. + +Some sequences also support "extended slicing" with a third "step" parameter: +``a[i:j:k]`` selects all items of *a* with index *x* where ``x = i + n*k``, *n* +``>=`` ``0`` and *i* ``<=`` *x* ``<`` *j*. + +Sequences are distinguished according to their mutability: + + +Immutable sequences +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; immutable sequence + pair: object; immutable + +An object of an immutable sequence type cannot change once it is created. (If +the object contains references to other objects, these other objects may be +mutable and may be changed; however, the collection of objects directly +referenced by an immutable object cannot change.) + +The following types are immutable sequences: + +.. index:: + single: string; immutable sequences + +Strings .. index:: - pair: built-in function; len - pair: object; sequence - single: index operation - single: item selection - single: subscription - - These represent finite ordered sets indexed by non-negative numbers. The - built-in function :func:`len` returns the number of items of a sequence. When - the length of a sequence is *n*, the index set contains the numbers 0, 1, - ..., *n*-1. Item *i* of sequence *a* is selected by ``a[i]``. - - .. index:: single: slicing - - Sequences also support slicing: ``a[i:j]`` selects all items with index *k* such - that *i* ``<=`` *k* ``<`` *j*. When used as an expression, a slice is a - sequence of the same type. This implies that the index set is renumbered so - that it starts at 0. - - Some sequences also support "extended slicing" with a third "step" parameter: - ``a[i:j:k]`` selects all items of *a* with index *x* where ``x = i + n*k``, *n* - ``>=`` ``0`` and *i* ``<=`` *x* ``<`` *j*. - - Sequences are distinguished according to their mutability: - - Immutable sequences - .. index:: - pair: object; immutable sequence - pair: object; immutable - - An object of an immutable sequence type cannot change once it is created. (If - the object contains references to other objects, these other objects may be - mutable and may be changed; however, the collection of objects directly - referenced by an immutable object cannot change.) - - The following types are immutable sequences: - - .. index:: - single: string; immutable sequences - - Strings - .. index:: - pair: built-in function; chr - pair: built-in function; ord - single: character - single: integer - single: Unicode - - A string is a sequence of values that represent Unicode code points. - All the code points in the range ``U+0000 - U+10FFFF`` can be - represented in a string. Python doesn't have a :c:expr:`char` type; - instead, every code point in the string is represented as a string - object with length ``1``. The built-in function :func:`ord` - converts a code point from its string form to an integer in the - range ``0 - 10FFFF``; :func:`chr` converts an integer in the range - ``0 - 10FFFF`` to the corresponding length ``1`` string object. - :meth:`str.encode` can be used to convert a :class:`str` to - :class:`bytes` using the given text encoding, and - :meth:`bytes.decode` can be used to achieve the opposite. - - Tuples - .. index:: - pair: object; tuple - pair: singleton; tuple - pair: empty; tuple - - The items of a tuple are arbitrary Python objects. Tuples of two or - more items are formed by comma-separated lists of expressions. A tuple - of one item (a 'singleton') can be formed by affixing a comma to an - expression (an expression by itself does not create a tuple, since - parentheses must be usable for grouping of expressions). An empty - tuple can be formed by an empty pair of parentheses. - - Bytes - .. index:: bytes, byte - - A bytes object is an immutable array. The items are 8-bit bytes, - represented by integers in the range 0 <= x < 256. Bytes literals - (like ``b'abc'``) and the built-in :func:`bytes()` constructor - can be used to create bytes objects. Also, bytes objects can be - decoded to strings via the :meth:`~bytes.decode` method. - - Mutable sequences - .. index:: - pair: object; mutable sequence - pair: object; mutable - pair: assignment; statement - single: subscription - single: slicing - - Mutable sequences can be changed after they are created. The subscription and - slicing notations can be used as the target of assignment and :keyword:`del` - (delete) statements. - - There are currently two intrinsic mutable sequence types: - - Lists - .. index:: pair: object; list - - The items of a list are arbitrary Python objects. Lists are formed by - placing a comma-separated list of expressions in square brackets. (Note - that there are no special cases needed to form lists of length 0 or 1.) - - Byte Arrays - .. index:: bytearray - - A bytearray object is a mutable array. They are created by the built-in - :func:`bytearray` constructor. Aside from being mutable - (and hence unhashable), byte arrays otherwise provide the same interface - and functionality as immutable :class:`bytes` objects. - - .. index:: pair: module; array - - The extension module :mod:`array` provides an additional example of a - mutable sequence type, as does the :mod:`collections` module. + pair: built-in function; chr + pair: built-in function; ord + single: character + single: integer + single: Unicode + + A string is a sequence of values that represent Unicode code points. + All the code points in the range ``U+0000 - U+10FFFF`` can be + represented in a string. Python doesn't have a :c:expr:`char` type; + instead, every code point in the string is represented as a string + object with length ``1``. The built-in function :func:`ord` + converts a code point from its string form to an integer in the + range ``0 - 10FFFF``; :func:`chr` converts an integer in the range + ``0 - 10FFFF`` to the corresponding length ``1`` string object. + :meth:`str.encode` can be used to convert a :class:`str` to + :class:`bytes` using the given text encoding, and + :meth:`bytes.decode` can be used to achieve the opposite. + +Tuples + .. index:: + pair: object; tuple + pair: singleton; tuple + pair: empty; tuple + + The items of a tuple are arbitrary Python objects. Tuples of two or + more items are formed by comma-separated lists of expressions. A tuple + of one item (a 'singleton') can be formed by affixing a comma to an + expression (an expression by itself does not create a tuple, since + parentheses must be usable for grouping of expressions). An empty + tuple can be formed by an empty pair of parentheses. + +Bytes + .. index:: bytes, byte + + A bytes object is an immutable array. The items are 8-bit bytes, + represented by integers in the range 0 <= x < 256. Bytes literals + (like ``b'abc'``) and the built-in :func:`bytes()` constructor + can be used to create bytes objects. Also, bytes objects can be + decoded to strings via the :meth:`~bytes.decode` method. + + +Mutable sequences +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; mutable sequence + pair: object; mutable + pair: assignment; statement + single: subscription + single: slicing + +Mutable sequences can be changed after they are created. The subscription and +slicing notations can be used as the target of assignment and :keyword:`del` +(delete) statements. + +.. note:: + .. index:: pair: module; array + .. index:: pair: module; collections + + The :mod:`collections` and :mod:`array` module provide + additional examples of mutable sequence types. + +There are currently two intrinsic mutable sequence types: + +Lists + .. index:: pair: object; list + + The items of a list are arbitrary Python objects. Lists are formed by + placing a comma-separated list of expressions in square brackets. (Note + that there are no special cases needed to form lists of length 0 or 1.) + +Byte Arrays + .. index:: bytearray + + A bytearray object is a mutable array. They are created by the built-in + :func:`bytearray` constructor. Aside from being mutable + (and hence unhashable), byte arrays otherwise provide the same interface + and functionality as immutable :class:`bytes` objects. + Set types - .. index:: - pair: built-in function; len - pair: object; set type +--------- + +.. index:: + pair: built-in function; len + pair: object; set type + +These represent unordered, finite sets of unique, immutable objects. As such, +they cannot be indexed by any subscript. However, they can be iterated over, and +the built-in function :func:`len` returns the number of items in a set. Common +uses for sets are fast membership testing, removing duplicates from a sequence, +and computing mathematical operations such as intersection, union, difference, +and symmetric difference. - These represent unordered, finite sets of unique, immutable objects. As such, - they cannot be indexed by any subscript. However, they can be iterated over, and - the built-in function :func:`len` returns the number of items in a set. Common - uses for sets are fast membership testing, removing duplicates from a sequence, - and computing mathematical operations such as intersection, union, difference, - and symmetric difference. +For set elements, the same immutability rules apply as for dictionary keys. Note +that numeric types obey the normal rules for numeric comparison: if two numbers +compare equal (e.g., ``1`` and ``1.0``), only one of them can be contained in a +set. - For set elements, the same immutability rules apply as for dictionary keys. Note - that numeric types obey the normal rules for numeric comparison: if two numbers - compare equal (e.g., ``1`` and ``1.0``), only one of them can be contained in a - set. +There are currently two intrinsic set types: - There are currently two intrinsic set types: - Sets - .. index:: pair: object; set +Sets + .. index:: pair: object; set - These represent a mutable set. They are created by the built-in :func:`set` - constructor and can be modified afterwards by several methods, such as - :meth:`~set.add`. + These represent a mutable set. They are created by the built-in :func:`set` + constructor and can be modified afterwards by several methods, such as + :meth:`~set.add`. - Frozen sets - .. index:: pair: object; frozenset - These represent an immutable set. They are created by the built-in - :func:`frozenset` constructor. As a frozenset is immutable and - :term:`hashable`, it can be used again as an element of another set, or as - a dictionary key. +Frozen sets + .. index:: pair: object; frozenset + + These represent an immutable set. They are created by the built-in + :func:`frozenset` constructor. As a frozenset is immutable and + :term:`hashable`, it can be used again as an element of another set, or as + a dictionary key. + Mappings - .. index:: - pair: built-in function; len - single: subscription - pair: object; mapping - - These represent finite sets of objects indexed by arbitrary index sets. The - subscript notation ``a[k]`` selects the item indexed by ``k`` from the mapping - ``a``; this can be used in expressions and as the target of assignments or - :keyword:`del` statements. The built-in function :func:`len` returns the number - of items in a mapping. - - There is currently a single intrinsic mapping type: - - Dictionaries - .. index:: pair: object; dictionary - - These represent finite sets of objects indexed by nearly arbitrary values. The - only types of values not acceptable as keys are values containing lists or - dictionaries or other mutable types that are compared by value rather than by - object identity, the reason being that the efficient implementation of - dictionaries requires a key's hash value to remain constant. Numeric types used - for keys obey the normal rules for numeric comparison: if two numbers compare - equal (e.g., ``1`` and ``1.0``) then they can be used interchangeably to index - the same dictionary entry. - - Dictionaries preserve insertion order, meaning that keys will be produced - in the same order they were added sequentially over the dictionary. - Replacing an existing key does not change the order, however removing a key - and re-inserting it will add it to the end instead of keeping its old place. - - Dictionaries are mutable; they can be created by the ``{...}`` notation (see - section :ref:`dict`). - - .. index:: - pair: module; dbm.ndbm - pair: module; dbm.gnu - - The extension modules :mod:`dbm.ndbm` and :mod:`dbm.gnu` provide - additional examples of mapping types, as does the :mod:`collections` - module. - - .. versionchanged:: 3.7 - Dictionaries did not preserve insertion order in versions of Python before 3.6. - In CPython 3.6, insertion order was preserved, but it was considered - an implementation detail at that time rather than a language guarantee. +-------- + +.. index:: + pair: built-in function; len + single: subscription + pair: object; mapping + +These represent finite sets of objects indexed by arbitrary index sets. The +subscript notation ``a[k]`` selects the item indexed by ``k`` from the mapping +``a``; this can be used in expressions and as the target of assignments or +:keyword:`del` statements. The built-in function :func:`len` returns the number +of items in a mapping. + +There is currently a single intrinsic mapping type: + + +Dictionaries +^^^^^^^^^^^^ + +.. index:: pair: object; dictionary + +These represent finite sets of objects indexed by nearly arbitrary values. The +only types of values not acceptable as keys are values containing lists or +dictionaries or other mutable types that are compared by value rather than by +object identity, the reason being that the efficient implementation of +dictionaries requires a key's hash value to remain constant. Numeric types used +for keys obey the normal rules for numeric comparison: if two numbers compare +equal (e.g., ``1`` and ``1.0``) then they can be used interchangeably to index +the same dictionary entry. + +Dictionaries preserve insertion order, meaning that keys will be produced +in the same order they were added sequentially over the dictionary. +Replacing an existing key does not change the order, however removing a key +and re-inserting it will add it to the end instead of keeping its old place. + +Dictionaries are mutable; they can be created by the ``{...}`` notation (see +section :ref:`dict`). + +.. index:: + pair: module; dbm.ndbm + pair: module; dbm.gnu + +The extension modules :mod:`dbm.ndbm` and :mod:`dbm.gnu` provide +additional examples of mapping types, as does the :mod:`collections` +module. + +.. versionchanged:: 3.7 + Dictionaries did not preserve insertion order in versions of Python before 3.6. + In CPython 3.6, insertion order was preserved, but it was considered + an implementation detail at that time rather than a language guarantee. + Callable types - .. index:: - pair: object; callable - pair: function; call - single: invocation - pair: function; argument - - These are the types to which the function call operation (see section - :ref:`calls`) can be applied: - - User-defined functions - .. index:: - pair: user-defined; function - pair: object; function - pair: object; user-defined function - - A user-defined function object is created by a function definition (see - section :ref:`function`). It should be called with an argument list - containing the same number of items as the function's formal parameter - list. - - Special attributes: - - .. tabularcolumns:: |l|L|l| - - .. index:: - single: __doc__ (function attribute) - single: __name__ (function attribute) - single: __module__ (function attribute) - single: __dict__ (function attribute) - single: __defaults__ (function attribute) - single: __closure__ (function attribute) - single: __code__ (function attribute) - single: __globals__ (function attribute) - single: __annotations__ (function attribute) - single: __kwdefaults__ (function attribute) - single: __type_params__ (function attribute) - pair: global; namespace - - +-------------------------+-------------------------------+-----------+ - | Attribute | Meaning | | - +=========================+===============================+===========+ - | :attr:`__doc__` | The function's documentation | Writable | - | | string, or ``None`` if | | - | | unavailable; not inherited by | | - | | subclasses. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`~definition.\ | The function's name. | Writable | - | __name__` | | | - +-------------------------+-------------------------------+-----------+ - | :attr:`~definition.\ | The function's | Writable | - | __qualname__` | :term:`qualified name`. | | - | | | | - | | .. versionadded:: 3.3 | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__module__` | The name of the module the | Writable | - | | function was defined in, or | | - | | ``None`` if unavailable. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__defaults__` | A tuple containing default | Writable | - | | argument values for those | | - | | arguments that have defaults, | | - | | or ``None`` if no arguments | | - | | have a default value. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__code__` | The code object representing | Writable | - | | the compiled function body. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__globals__` | A reference to the dictionary | Read-only | - | | that holds the function's | | - | | global variables --- the | | - | | global namespace of the | | - | | module in which the function | | - | | was defined. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`~object.__dict__`| The namespace supporting | Writable | - | | arbitrary function | | - | | attributes. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__closure__` | ``None`` or a tuple of cells | Read-only | - | | that contain bindings for the | | - | | function's free variables. | | - | | See below for information on | | - | | the ``cell_contents`` | | - | | attribute. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__annotations__` | A dict containing annotations | Writable | - | | of parameters. The keys of | | - | | the dict are the parameter | | - | | names, and ``'return'`` for | | - | | the return annotation, if | | - | | provided. For more | | - | | information on working with | | - | | this attribute, see | | - | | :ref:`annotations-howto`. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__kwdefaults__` | A dict containing defaults | Writable | - | | for keyword-only parameters. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__type_params__` | A tuple containing the | Writable | - | | :ref:`type parameters | | - | | ` of a | | - | | :ref:`generic function | | - | | `. | | - +-------------------------+-------------------------------+-----------+ - - Most of the attributes labelled "Writable" check the type of the assigned value. - - Function objects also support getting and setting arbitrary attributes, which - can be used, for example, to attach metadata to functions. Regular attribute - dot-notation is used to get and set such attributes. *Note that the current - implementation only supports function attributes on user-defined functions. - Function attributes on built-in functions may be supported in the future.* - - A cell object has the attribute ``cell_contents``. This can be used to get - the value of the cell, as well as set the value. - - Additional information about a function's definition can be retrieved from its - code object; see the description of internal types below. The - :data:`cell ` type can be accessed in the :mod:`types` - module. - - Instance methods - .. index:: - pair: object; method - pair: object; user-defined method - pair: user-defined; method - - An instance method object combines a class, a class instance and any - callable object (normally a user-defined function). - - .. index:: - single: __func__ (method attribute) - single: __self__ (method attribute) - single: __doc__ (method attribute) - single: __name__ (method attribute) - single: __module__ (method attribute) - - Special read-only attributes: :attr:`__self__` is the class instance object, - :attr:`__func__` is the function object; :attr:`__doc__` is the method's - documentation (same as ``__func__.__doc__``); :attr:`~definition.__name__` is the - method name (same as ``__func__.__name__``); :attr:`__module__` is the - name of the module the method was defined in, or ``None`` if unavailable. - - Methods also support accessing (but not setting) the arbitrary function - attributes on the underlying function object. - - User-defined method objects may be created when getting an attribute of a - class (perhaps via an instance of that class), if that attribute is a - user-defined function object or a class method object. - - When an instance method object is created by retrieving a user-defined - function object from a class via one of its instances, its - :attr:`__self__` attribute is the instance, and the method object is said - to be bound. The new method's :attr:`__func__` attribute is the original - function object. - - When an instance method object is created by retrieving a class method - object from a class or instance, its :attr:`__self__` attribute is the - class itself, and its :attr:`__func__` attribute is the function object - underlying the class method. - - When an instance method object is called, the underlying function - (:attr:`__func__`) is called, inserting the class instance - (:attr:`__self__`) in front of the argument list. For instance, when - :class:`C` is a class which contains a definition for a function - :meth:`f`, and ``x`` is an instance of :class:`C`, calling ``x.f(1)`` is - equivalent to calling ``C.f(x, 1)``. - - When an instance method object is derived from a class method object, the - "class instance" stored in :attr:`__self__` will actually be the class - itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to - calling ``f(C,1)`` where ``f`` is the underlying function. - - Note that the transformation from function object to instance method - object happens each time the attribute is retrieved from the instance. In - some cases, a fruitful optimization is to assign the attribute to a local - variable and call that local variable. Also notice that this - transformation only happens for user-defined functions; other callable - objects (and all non-callable objects) are retrieved without - transformation. It is also important to note that user-defined functions - which are attributes of a class instance are not converted to bound - methods; this *only* happens when the function is an attribute of the - class. - - Generator functions - .. index:: - single: generator; function - single: generator; iterator - - A function or method which uses the :keyword:`yield` statement (see section - :ref:`yield`) is called a :dfn:`generator function`. Such a function, when - called, always returns an :term:`iterator` object which can be used to - execute the body of the function: calling the iterator's - :meth:`iterator.__next__` method will cause the function to execute until - it provides a value using the :keyword:`!yield` statement. When the - function executes a :keyword:`return` statement or falls off the end, a - :exc:`StopIteration` exception is raised and the iterator will have - reached the end of the set of values to be returned. - - Coroutine functions - .. index:: - single: coroutine; function - - A function or method which is defined using :keyword:`async def` is called - a :dfn:`coroutine function`. Such a function, when called, returns a - :term:`coroutine` object. It may contain :keyword:`await` expressions, - as well as :keyword:`async with` and :keyword:`async for` statements. See - also the :ref:`coroutine-objects` section. - - Asynchronous generator functions - .. index:: - single: asynchronous generator; function - single: asynchronous generator; asynchronous iterator - - A function or method which is defined using :keyword:`async def` and - which uses the :keyword:`yield` statement is called a - :dfn:`asynchronous generator function`. Such a function, when called, - returns an :term:`asynchronous iterator` object which can be used in an - :keyword:`async for` statement to execute the body of the function. - - Calling the asynchronous iterator's - :meth:`aiterator.__anext__ ` method - will return an :term:`awaitable` which when awaited - will execute until it provides a value using the :keyword:`yield` - expression. When the function executes an empty :keyword:`return` - statement or falls off the end, a :exc:`StopAsyncIteration` exception - is raised and the asynchronous iterator will have reached the end of - the set of values to be yielded. - - Built-in functions - .. index:: - pair: object; built-in function - pair: object; function - pair: C; language - - A built-in function object is a wrapper around a C function. Examples of - built-in functions are :func:`len` and :func:`math.sin` (:mod:`math` is a - standard built-in module). The number and type of the arguments are - determined by the C function. Special read-only attributes: - :attr:`__doc__` is the function's documentation string, or ``None`` if - unavailable; :attr:`~definition.__name__` is the function's name; :attr:`__self__` is - set to ``None`` (but see the next item); :attr:`__module__` is the name of - the module the function was defined in or ``None`` if unavailable. - - Built-in methods - .. index:: - pair: object; built-in method - pair: object; method - pair: built-in; method - - This is really a different disguise of a built-in function, this time containing - an object passed to the C function as an implicit extra argument. An example of - a built-in method is ``alist.append()``, assuming *alist* is a list object. In - this case, the special read-only attribute :attr:`__self__` is set to the object - denoted by *alist*. - - Classes - Classes are callable. These objects normally act as factories for new - instances of themselves, but variations are possible for class types that - override :meth:`~object.__new__`. The arguments of the call are passed to - :meth:`__new__` and, in the typical case, to :meth:`~object.__init__` to - initialize the new instance. - - Class Instances - Instances of arbitrary classes can be made callable by defining a - :meth:`~object.__call__` method in their class. +-------------- + +.. index:: + pair: object; callable + pair: function; call + single: invocation + pair: function; argument + +These are the types to which the function call operation (see section +:ref:`calls`) can be applied: + + +User-defined functions +^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: user-defined; function + pair: object; function + pair: object; user-defined function + +A user-defined function object is created by a function definition (see +section :ref:`function`). It should be called with an argument list +containing the same number of items as the function's formal parameter +list. + +Special attributes: + +.. tabularcolumns:: |l|L|l| + +.. index:: + single: __doc__ (function attribute) + single: __name__ (function attribute) + single: __module__ (function attribute) + single: __dict__ (function attribute) + single: __defaults__ (function attribute) + single: __closure__ (function attribute) + single: __code__ (function attribute) + single: __globals__ (function attribute) + single: __annotations__ (function attribute) + single: __kwdefaults__ (function attribute) + single: __type_params__ (function attribute) + pair: global; namespace + ++-------------------------+-------------------------------+-----------+ +| Attribute | Meaning | | ++=========================+===============================+===========+ +| :attr:`__doc__` | The function's documentation | Writable | +| | string, or ``None`` if | | +| | unavailable; not inherited by | | +| | subclasses. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`~definition.\ | The function's name. | Writable | +| __name__` | | | ++-------------------------+-------------------------------+-----------+ +| :attr:`~definition.\ | The function's | Writable | +| __qualname__` | :term:`qualified name`. | | +| | | | +| | .. versionadded:: 3.3 | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__module__` | The name of the module the | Writable | +| | function was defined in, or | | +| | ``None`` if unavailable. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__defaults__` | A tuple containing default | Writable | +| | argument values for those | | +| | arguments that have defaults, | | +| | or ``None`` if no arguments | | +| | have a default value. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__code__` | The code object representing | Writable | +| | the compiled function body. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__globals__` | A reference to the dictionary | Read-only | +| | that holds the function's | | +| | global variables --- the | | +| | global namespace of the | | +| | module in which the function | | +| | was defined. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`~object.__dict__`| The namespace supporting | Writable | +| | arbitrary function | | +| | attributes. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__closure__` | ``None`` or a tuple of cells | Read-only | +| | that contain bindings for the | | +| | function's free variables. | | +| | See below for information on | | +| | the ``cell_contents`` | | +| | attribute. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__annotations__` | A dict containing annotations | Writable | +| | of parameters. The keys of | | +| | the dict are the parameter | | +| | names, and ``'return'`` for | | +| | the return annotation, if | | +| | provided. For more | | +| | information on working with | | +| | this attribute, see | | +| | :ref:`annotations-howto`. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__kwdefaults__` | A dict containing defaults | Writable | +| | for keyword-only parameters. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__type_params__` | A tuple containing the | Writable | +| | :ref:`type parameters | | +| | ` of a | | +| | :ref:`generic function | | +| | `. | | ++-------------------------+-------------------------------+-----------+ + +Most of the attributes labelled "Writable" check the type of the assigned value. + +Function objects also support getting and setting arbitrary attributes, which +can be used, for example, to attach metadata to functions. Regular attribute +dot-notation is used to get and set such attributes. *Note that the current +implementation only supports function attributes on user-defined functions. +Function attributes on built-in functions may be supported in the future.* + +A cell object has the attribute ``cell_contents``. This can be used to get +the value of the cell, as well as set the value. + +Additional information about a function's definition can be retrieved from its +code object; see the description of internal types below. The +:data:`cell ` type can be accessed in the :mod:`types` +module. + + +Instance methods +^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; method + pair: object; user-defined method + pair: user-defined; method + +An instance method object combines a class, a class instance and any +callable object (normally a user-defined function). + +.. index:: + single: __func__ (method attribute) + single: __self__ (method attribute) + single: __doc__ (method attribute) + single: __name__ (method attribute) + single: __module__ (method attribute) + +Special read-only attributes: :attr:`__self__` is the class instance object, +:attr:`__func__` is the function object; :attr:`__doc__` is the method's +documentation (same as ``__func__.__doc__``); :attr:`~definition.__name__` is the +method name (same as ``__func__.__name__``); :attr:`__module__` is the +name of the module the method was defined in, or ``None`` if unavailable. + +Methods also support accessing (but not setting) the arbitrary function +attributes on the underlying function object. + +User-defined method objects may be created when getting an attribute of a +class (perhaps via an instance of that class), if that attribute is a +user-defined function object or a class method object. + +When an instance method object is created by retrieving a user-defined +function object from a class via one of its instances, its +:attr:`__self__` attribute is the instance, and the method object is said +to be bound. The new method's :attr:`__func__` attribute is the original +function object. + +When an instance method object is created by retrieving a class method +object from a class or instance, its :attr:`__self__` attribute is the +class itself, and its :attr:`__func__` attribute is the function object +underlying the class method. + +When an instance method object is called, the underlying function +(:attr:`__func__`) is called, inserting the class instance +(:attr:`__self__`) in front of the argument list. For instance, when +:class:`C` is a class which contains a definition for a function +:meth:`f`, and ``x`` is an instance of :class:`C`, calling ``x.f(1)`` is +equivalent to calling ``C.f(x, 1)``. + +When an instance method object is derived from a class method object, the +"class instance" stored in :attr:`__self__` will actually be the class +itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to +calling ``f(C,1)`` where ``f`` is the underlying function. + +Note that the transformation from function object to instance method +object happens each time the attribute is retrieved from the instance. In +some cases, a fruitful optimization is to assign the attribute to a local +variable and call that local variable. Also notice that this +transformation only happens for user-defined functions; other callable +objects (and all non-callable objects) are retrieved without +transformation. It is also important to note that user-defined functions +which are attributes of a class instance are not converted to bound +methods; this *only* happens when the function is an attribute of the +class. + + +Generator functions +^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: generator; function + single: generator; iterator + +A function or method which uses the :keyword:`yield` statement (see section +:ref:`yield`) is called a :dfn:`generator function`. Such a function, when +called, always returns an :term:`iterator` object which can be used to +execute the body of the function: calling the iterator's +:meth:`iterator.__next__` method will cause the function to execute until +it provides a value using the :keyword:`!yield` statement. When the +function executes a :keyword:`return` statement or falls off the end, a +:exc:`StopIteration` exception is raised and the iterator will have +reached the end of the set of values to be returned. + + +Coroutine functions +^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: coroutine; function + +A function or method which is defined using :keyword:`async def` is called +a :dfn:`coroutine function`. Such a function, when called, returns a +:term:`coroutine` object. It may contain :keyword:`await` expressions, +as well as :keyword:`async with` and :keyword:`async for` statements. See +also the :ref:`coroutine-objects` section. + + +Asynchronous generator functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: asynchronous generator; function + single: asynchronous generator; asynchronous iterator + +A function or method which is defined using :keyword:`async def` and +which uses the :keyword:`yield` statement is called a +:dfn:`asynchronous generator function`. Such a function, when called, +returns an :term:`asynchronous iterator` object which can be used in an +:keyword:`async for` statement to execute the body of the function. + +Calling the asynchronous iterator's +:meth:`aiterator.__anext__ ` method +will return an :term:`awaitable` which when awaited +will execute until it provides a value using the :keyword:`yield` +expression. When the function executes an empty :keyword:`return` +statement or falls off the end, a :exc:`StopAsyncIteration` exception +is raised and the asynchronous iterator will have reached the end of +the set of values to be yielded. + + +Built-in functions +^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; built-in function + pair: object; function + pair: C; language + +A built-in function object is a wrapper around a C function. Examples of +built-in functions are :func:`len` and :func:`math.sin` (:mod:`math` is a +standard built-in module). The number and type of the arguments are +determined by the C function. Special read-only attributes: +:attr:`__doc__` is the function's documentation string, or ``None`` if +unavailable; :attr:`~definition.__name__` is the function's name; :attr:`__self__` is +set to ``None`` (but see the next item); :attr:`__module__` is the name of +the module the function was defined in or ``None`` if unavailable. + + +Built-in methods +^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; built-in method + pair: object; method + pair: built-in; method + +This is really a different disguise of a built-in function, this time containing +an object passed to the C function as an implicit extra argument. An example of +a built-in method is ``alist.append()``, assuming *alist* is a list object. In +this case, the special read-only attribute :attr:`__self__` is set to the object +denoted by *alist*. + + +Classes +^^^^^^^ + +Classes are callable. These objects normally act as factories for new +instances of themselves, but variations are possible for class types that +override :meth:`~object.__new__`. The arguments of the call are passed to +:meth:`__new__` and, in the typical case, to :meth:`~object.__init__` to +initialize the new instance. + + +Class Instances +^^^^^^^^^^^^^^^ + +Instances of arbitrary classes can be made callable by defining a +:meth:`~object.__call__` method in their class. Modules - .. index:: - pair: statement; import - pair: object; module - - Modules are a basic organizational unit of Python code, and are created by - the :ref:`import system ` as invoked either by the - :keyword:`import` statement, or by calling - functions such as :func:`importlib.import_module` and built-in - :func:`__import__`. A module object has a namespace implemented by a - dictionary object (this is the dictionary referenced by the ``__globals__`` - attribute of functions defined in the module). Attribute references are - translated to lookups in this dictionary, e.g., ``m.x`` is equivalent to - ``m.__dict__["x"]``. A module object does not contain the code object used - to initialize the module (since it isn't needed once the initialization is - done). - - Attribute assignment updates the module's namespace dictionary, e.g., - ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``. +------- - .. index:: - single: __name__ (module attribute) - single: __doc__ (module attribute) - single: __file__ (module attribute) - single: __annotations__ (module attribute) - pair: module; namespace +.. index:: + pair: statement; import + pair: object; module + +Modules are a basic organizational unit of Python code, and are created by +the :ref:`import system ` as invoked either by the +:keyword:`import` statement, or by calling +functions such as :func:`importlib.import_module` and built-in +:func:`__import__`. A module object has a namespace implemented by a +dictionary object (this is the dictionary referenced by the ``__globals__`` +attribute of functions defined in the module). Attribute references are +translated to lookups in this dictionary, e.g., ``m.x`` is equivalent to +``m.__dict__["x"]``. A module object does not contain the code object used +to initialize the module (since it isn't needed once the initialization is +done). + +Attribute assignment updates the module's namespace dictionary, e.g., +``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``. - Predefined (writable) attributes: +.. index:: + single: __name__ (module attribute) + single: __doc__ (module attribute) + single: __file__ (module attribute) + single: __annotations__ (module attribute) + pair: module; namespace - :attr:`__name__` - The module's name. +Predefined (writable) attributes: - :attr:`__doc__` - The module's documentation string, or ``None`` if - unavailable. + :attr:`__name__` + The module's name. - :attr:`__file__` - The pathname of the file from which the - module was loaded, if it was loaded from a file. - The :attr:`__file__` - attribute may be missing for certain types of modules, such as C modules - that are statically linked into the interpreter. For extension modules - loaded dynamically from a shared library, it's the pathname of the shared - library file. + :attr:`__doc__` + The module's documentation string, or ``None`` if + unavailable. - :attr:`__annotations__` - A dictionary containing - :term:`variable annotations ` collected during - module body execution. For best practices on working - with :attr:`__annotations__`, please see :ref:`annotations-howto`. + :attr:`__file__` + The pathname of the file from which the + module was loaded, if it was loaded from a file. + The :attr:`__file__` + attribute may be missing for certain types of modules, such as C modules + that are statically linked into the interpreter. For extension modules + loaded dynamically from a shared library, it's the pathname of the shared + library file. - .. index:: single: __dict__ (module attribute) + :attr:`__annotations__` + A dictionary containing + :term:`variable annotations ` collected during + module body execution. For best practices on working + with :attr:`__annotations__`, please see :ref:`annotations-howto`. - Special read-only attribute: :attr:`~object.__dict__` is the module's - namespace as a dictionary object. +.. index:: single: __dict__ (module attribute) - .. impl-detail:: +Special read-only attribute: :attr:`~object.__dict__` is the module's +namespace as a dictionary object. + +.. impl-detail:: + + Because of the way CPython clears module dictionaries, the module + dictionary will be cleared when the module falls out of scope even if the + dictionary still has live references. To avoid this, copy the dictionary + or keep the module around while using its dictionary directly. - Because of the way CPython clears module dictionaries, the module - dictionary will be cleared when the module falls out of scope even if the - dictionary still has live references. To avoid this, copy the dictionary - or keep the module around while using its dictionary directly. Custom classes - Custom class types are typically created by class definitions (see section - :ref:`class`). A class has a namespace implemented by a dictionary object. - Class attribute references are translated to lookups in this dictionary, e.g., - ``C.x`` is translated to ``C.__dict__["x"]`` (although there are a number of - hooks which allow for other means of locating attributes). When the attribute - name is not found there, the attribute search continues in the base classes. - This search of the base classes uses the C3 method resolution order which - behaves correctly even in the presence of 'diamond' inheritance structures - where there are multiple inheritance paths leading back to a common ancestor. - Additional details on the C3 MRO used by Python can be found in the - documentation accompanying the 2.3 release at - https://www.python.org/download/releases/2.3/mro/. - - .. XXX: Could we add that MRO doc as an appendix to the language ref? +-------------- + +Custom class types are typically created by class definitions (see section +:ref:`class`). A class has a namespace implemented by a dictionary object. +Class attribute references are translated to lookups in this dictionary, e.g., +``C.x`` is translated to ``C.__dict__["x"]`` (although there are a number of +hooks which allow for other means of locating attributes). When the attribute +name is not found there, the attribute search continues in the base classes. +This search of the base classes uses the C3 method resolution order which +behaves correctly even in the presence of 'diamond' inheritance structures +where there are multiple inheritance paths leading back to a common ancestor. +Additional details on the C3 MRO used by Python can be found in the +documentation accompanying the 2.3 release at +https://www.python.org/download/releases/2.3/mro/. + +.. XXX: Could we add that MRO doc as an appendix to the language ref? - .. index:: - pair: object; class - pair: object; class instance - pair: object; instance - pair: class object; call - single: container - pair: object; dictionary - pair: class; attribute +.. index:: + pair: object; class + pair: object; class instance + pair: object; instance + pair: class object; call + single: container + pair: object; dictionary + pair: class; attribute - When a class attribute reference (for class :class:`C`, say) would yield a - class method object, it is transformed into an instance method object whose - :attr:`__self__` attribute is :class:`C`. When it would yield a static - method object, it is transformed into the object wrapped by the static method - object. See section :ref:`descriptors` for another way in which attributes - retrieved from a class may differ from those actually contained in its - :attr:`~object.__dict__`. +When a class attribute reference (for class :class:`C`, say) would yield a +class method object, it is transformed into an instance method object whose +:attr:`__self__` attribute is :class:`C`. When it would yield a static +method object, it is transformed into the object wrapped by the static method +object. See section :ref:`descriptors` for another way in which attributes +retrieved from a class may differ from those actually contained in its +:attr:`~object.__dict__`. - .. index:: triple: class; attribute; assignment +.. index:: triple: class; attribute; assignment - Class attribute assignments update the class's dictionary, never the dictionary - of a base class. +Class attribute assignments update the class's dictionary, never the dictionary +of a base class. - .. index:: pair: class object; call +.. index:: pair: class object; call - A class object can be called (see above) to yield a class instance (see below). +A class object can be called (see above) to yield a class instance (see below). - .. index:: - single: __name__ (class attribute) - single: __module__ (class attribute) - single: __dict__ (class attribute) - single: __bases__ (class attribute) - single: __doc__ (class attribute) - single: __annotations__ (class attribute) - single: __type_params__ (class attribute) +.. index:: + single: __name__ (class attribute) + single: __module__ (class attribute) + single: __dict__ (class attribute) + single: __bases__ (class attribute) + single: __doc__ (class attribute) + single: __annotations__ (class attribute) + single: __type_params__ (class attribute) + +Special attributes: - Special attributes: + :attr:`~definition.__name__` + The class name. - :attr:`~definition.__name__` - The class name. + :attr:`__module__` + The name of the module in which the class was defined. - :attr:`__module__` - The name of the module in which the class was defined. + :attr:`~object.__dict__` + The dictionary containing the class's namespace. - :attr:`~object.__dict__` - The dictionary containing the class's namespace. + :attr:`~class.__bases__` + A tuple containing the base classes, in the order of + their occurrence in the base class list. - :attr:`~class.__bases__` - A tuple containing the base classes, in the order of - their occurrence in the base class list. + :attr:`__doc__` + The class's documentation string, or ``None`` if undefined. - :attr:`__doc__` - The class's documentation string, or ``None`` if undefined. + :attr:`__annotations__` + A dictionary containing + :term:`variable annotations ` + collected during class body execution. For best practices on + working with :attr:`__annotations__`, please see + :ref:`annotations-howto`. - :attr:`__annotations__` - A dictionary containing - :term:`variable annotations ` - collected during class body execution. For best practices on - working with :attr:`__annotations__`, please see - :ref:`annotations-howto`. + :attr:`__type_params__` + A tuple containing the :ref:`type parameters ` of + a :ref:`generic class `. - :attr:`__type_params__` - A tuple containing the :ref:`type parameters ` of - a :ref:`generic class `. Class instances - .. index:: - pair: object; class instance - pair: object; instance - pair: class; instance - pair: class instance; attribute - - A class instance is created by calling a class object (see above). A class - instance has a namespace implemented as a dictionary which is the first place - in which attribute references are searched. When an attribute is not found - there, and the instance's class has an attribute by that name, the search - continues with the class attributes. If a class attribute is found that is a - user-defined function object, it is transformed into an instance method - object whose :attr:`__self__` attribute is the instance. Static method and - class method objects are also transformed; see above under "Classes". See - section :ref:`descriptors` for another way in which attributes of a class - retrieved via its instances may differ from the objects actually stored in - the class's :attr:`~object.__dict__`. If no class attribute is found, and the - object's class has a :meth:`~object.__getattr__` method, that is called to satisfy - the lookup. - - .. index:: triple: class instance; attribute; assignment - - Attribute assignments and deletions update the instance's dictionary, never a - class's dictionary. If the class has a :meth:`~object.__setattr__` or - :meth:`~object.__delattr__` method, this is called instead of updating the instance - dictionary directly. +--------------- - .. index:: - pair: object; numeric - pair: object; sequence - pair: object; mapping +.. index:: + pair: object; class instance + pair: object; instance + pair: class; instance + pair: class instance; attribute + +A class instance is created by calling a class object (see above). A class +instance has a namespace implemented as a dictionary which is the first place +in which attribute references are searched. When an attribute is not found +there, and the instance's class has an attribute by that name, the search +continues with the class attributes. If a class attribute is found that is a +user-defined function object, it is transformed into an instance method +object whose :attr:`__self__` attribute is the instance. Static method and +class method objects are also transformed; see above under "Classes". See +section :ref:`descriptors` for another way in which attributes of a class +retrieved via its instances may differ from the objects actually stored in +the class's :attr:`~object.__dict__`. If no class attribute is found, and the +object's class has a :meth:`~object.__getattr__` method, that is called to satisfy +the lookup. + +.. index:: triple: class instance; attribute; assignment + +Attribute assignments and deletions update the instance's dictionary, never a +class's dictionary. If the class has a :meth:`~object.__setattr__` or +:meth:`~object.__delattr__` method, this is called instead of updating the instance +dictionary directly. - Class instances can pretend to be numbers, sequences, or mappings if they have - methods with certain special names. See section :ref:`specialnames`. +.. index:: + pair: object; numeric + pair: object; sequence + pair: object; mapping - .. index:: - single: __dict__ (instance attribute) - single: __class__ (instance attribute) +Class instances can pretend to be numbers, sequences, or mappings if they have +methods with certain special names. See section :ref:`specialnames`. + +.. index:: + single: __dict__ (instance attribute) + single: __class__ (instance attribute) + +Special attributes: :attr:`~object.__dict__` is the attribute dictionary; +:attr:`~instance.__class__` is the instance's class. - Special attributes: :attr:`~object.__dict__` is the attribute dictionary; - :attr:`~instance.__class__` is the instance's class. I/O objects (also known as file objects) - .. index:: - pair: built-in function; open - pair: module; io - single: popen() (in module os) - single: makefile() (socket method) - single: sys.stdin - single: sys.stdout - single: sys.stderr - single: stdio - single: stdin (in module sys) - single: stdout (in module sys) - single: stderr (in module sys) - - A :term:`file object` represents an open file. Various shortcuts are - available to create file objects: the :func:`open` built-in function, and - also :func:`os.popen`, :func:`os.fdopen`, and the - :meth:`~socket.socket.makefile` method of socket objects (and perhaps by - other functions or methods provided by extension modules). - - The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are - initialized to file objects corresponding to the interpreter's standard - input, output and error streams; they are all open in text mode and - therefore follow the interface defined by the :class:`io.TextIOBase` - abstract class. +---------------------------------------- + +.. index:: + pair: built-in function; open + pair: module; io + single: popen() (in module os) + single: makefile() (socket method) + single: sys.stdin + single: sys.stdout + single: sys.stderr + single: stdio + single: stdin (in module sys) + single: stdout (in module sys) + single: stderr (in module sys) + +A :term:`file object` represents an open file. Various shortcuts are +available to create file objects: the :func:`open` built-in function, and +also :func:`os.popen`, :func:`os.fdopen`, and the +:meth:`~socket.socket.makefile` method of socket objects (and perhaps by +other functions or methods provided by extension modules). + +The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are +initialized to file objects corresponding to the interpreter's standard +input, output and error streams; they are all open in text mode and +therefore follow the interface defined by the :class:`io.TextIOBase` +abstract class. + Internal types - .. index:: - single: internal type - single: types, internal - - A few types used internally by the interpreter are exposed to the user. Their - definitions may change with future versions of the interpreter, but they are - mentioned here for completeness. - - .. index:: bytecode, object; code, code object - - Code objects - Code objects represent *byte-compiled* executable Python code, or :term:`bytecode`. - The difference between a code object and a function object is that the function - object contains an explicit reference to the function's globals (the module in - which it was defined), while a code object contains no context; also the default - argument values are stored in the function object, not in the code object - (because they represent values calculated at run-time). Unlike function - objects, code objects are immutable and contain no references (directly or - indirectly) to mutable objects. - - .. index:: - single: co_argcount (code object attribute) - single: co_posonlyargcount (code object attribute) - single: co_kwonlyargcount (code object attribute) - single: co_code (code object attribute) - single: co_consts (code object attribute) - single: co_filename (code object attribute) - single: co_firstlineno (code object attribute) - single: co_flags (code object attribute) - single: co_lnotab (code object attribute) - single: co_name (code object attribute) - single: co_names (code object attribute) - single: co_nlocals (code object attribute) - single: co_stacksize (code object attribute) - single: co_varnames (code object attribute) - single: co_cellvars (code object attribute) - single: co_freevars (code object attribute) - single: co_qualname (code object attribute) - - Special read-only attributes: :attr:`co_name` gives the function name; - :attr:`co_qualname` gives the fully qualified function name; - :attr:`co_argcount` is the total number of positional arguments - (including positional-only arguments and arguments with default values); - :attr:`co_posonlyargcount` is the number of positional-only arguments - (including arguments with default values); :attr:`co_kwonlyargcount` is - the number of keyword-only arguments (including arguments with default - values); :attr:`co_nlocals` is the number of local variables used by the - function (including arguments); :attr:`co_varnames` is a tuple containing - the names of the local variables (starting with the argument names); - :attr:`co_cellvars` is a tuple containing the names of local variables - that are referenced by nested functions; :attr:`co_freevars` is a tuple - containing the names of free variables; :attr:`co_code` is a string - representing the sequence of bytecode instructions; :attr:`co_consts` is - a tuple containing the literals used by the bytecode; :attr:`co_names` is - a tuple containing the names used by the bytecode; :attr:`co_filename` is - the filename from which the code was compiled; :attr:`co_firstlineno` is - the first line number of the function; :attr:`co_lnotab` is a string - encoding the mapping from bytecode offsets to line numbers (for details - see the source code of the interpreter, is deprecated since 3.12 - and may be removed in 3.14); :attr:`co_stacksize` is the - required stack size; :attr:`co_flags` is an integer encoding a number - of flags for the interpreter. - - .. index:: pair: object; generator - - The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if - the function uses the ``*arguments`` syntax to accept an arbitrary number of - positional arguments; bit ``0x08`` is set if the function uses the - ``**keywords`` syntax to accept arbitrary keyword arguments; bit ``0x20`` is set - if the function is a generator. - - Future feature declarations (``from __future__ import division``) also use bits - in :attr:`co_flags` to indicate whether a code object was compiled with a - particular feature enabled: bit ``0x2000`` is set if the function was compiled - with future division enabled; bits ``0x10`` and ``0x1000`` were used in earlier - versions of Python. - - Other bits in :attr:`co_flags` are reserved for internal use. - - .. index:: single: documentation string - - If a code object represents a function, the first item in :attr:`co_consts` is - the documentation string of the function, or ``None`` if undefined. - - .. method:: codeobject.co_positions() - - Returns an iterable over the source code positions of each bytecode - instruction in the code object. - - The iterator returns tuples containing the ``(start_line, end_line, - start_column, end_column)``. The *i-th* tuple corresponds to the - position of the source code that compiled to the *i-th* instruction. - Column information is 0-indexed utf-8 byte offsets on the given source - line. - - This positional information can be missing. A non-exhaustive lists of - cases where this may happen: - - - Running the interpreter with :option:`-X` ``no_debug_ranges``. - - Loading a pyc file compiled while using :option:`-X` ``no_debug_ranges``. - - Position tuples corresponding to artificial instructions. - - Line and column numbers that can't be represented due to - implementation specific limitations. - - When this occurs, some or all of the tuple elements can be - :const:`None`. - - .. versionadded:: 3.11 - - .. note:: - This feature requires storing column positions in code objects which may - result in a small increase of disk usage of compiled Python files or - interpreter memory usage. To avoid storing the extra information and/or - deactivate printing the extra traceback information, the - :option:`-X` ``no_debug_ranges`` command line flag or the :envvar:`PYTHONNODEBUGRANGES` - environment variable can be used. - - .. _frame-objects: - - Frame objects - .. index:: pair: object; frame - - Frame objects represent execution frames. They may occur in traceback objects - (see below), and are also passed to registered trace functions. - - .. index:: - single: f_back (frame attribute) - single: f_code (frame attribute) - single: f_globals (frame attribute) - single: f_locals (frame attribute) - single: f_lasti (frame attribute) - single: f_builtins (frame attribute) - - Special read-only attributes: :attr:`f_back` is to the previous stack frame - (towards the caller), or ``None`` if this is the bottom stack frame; - :attr:`f_code` is the code object being executed in this frame; :attr:`f_locals` - is the dictionary used to look up local variables; :attr:`f_globals` is used for - global variables; :attr:`f_builtins` is used for built-in (intrinsic) names; - :attr:`f_lasti` gives the precise instruction (this is an index into the - bytecode string of the code object). - - Accessing ``f_code`` raises an :ref:`auditing event ` - ``object.__getattr__`` with arguments ``obj`` and ``"f_code"``. - - .. index:: - single: f_trace (frame attribute) - single: f_trace_lines (frame attribute) - single: f_trace_opcodes (frame attribute) - single: f_lineno (frame attribute) - - Special writable attributes: :attr:`f_trace`, if not ``None``, is a function - called for various events during code execution (this is used by the debugger). - Normally an event is triggered for each new source line - this can be - disabled by setting :attr:`f_trace_lines` to :const:`False`. - - Implementations *may* allow per-opcode events to be requested by setting - :attr:`f_trace_opcodes` to :const:`True`. Note that this may lead to - undefined interpreter behaviour if exceptions raised by the trace - function escape to the function being traced. - - :attr:`f_lineno` is the current line number of the frame --- writing to this - from within a trace function jumps to the given line (only for the bottom-most - frame). A debugger can implement a Jump command (aka Set Next Statement) - by writing to f_lineno. - - Frame objects support one method: - - .. method:: frame.clear() - - This method clears all references to local variables held by the - frame. Also, if the frame belonged to a generator, the generator - is finalized. This helps break reference cycles involving frame - objects (for example when catching an exception and storing its - traceback for later use). - - :exc:`RuntimeError` is raised if the frame is currently executing. - - .. versionadded:: 3.4 - - .. _traceback-objects: - - Traceback objects - .. index:: - pair: object; traceback - pair: stack; trace - pair: exception; handler - pair: execution; stack - single: exc_info (in module sys) - single: last_traceback (in module sys) - single: sys.exc_info - single: sys.exception - single: sys.last_traceback - - Traceback objects represent a stack trace of an exception. A traceback object - is implicitly created when an exception occurs, and may also be explicitly - created by calling :class:`types.TracebackType`. - - For implicitly created tracebacks, when the search for an exception handler - unwinds the execution stack, at each unwound level a traceback object is - inserted in front of the current traceback. When an exception handler is - entered, the stack trace is made available to the program. (See section - :ref:`try`.) It is accessible as the third item of the - tuple returned by ``sys.exc_info()``, and as the ``__traceback__`` attribute - of the caught exception. - - When the program contains no suitable - handler, the stack trace is written (nicely formatted) to the standard error - stream; if the interpreter is interactive, it is also made available to the user - as ``sys.last_traceback``. - - For explicitly created tracebacks, it is up to the creator of the traceback - to determine how the ``tb_next`` attributes should be linked to form a - full stack trace. - - .. index:: - single: tb_frame (traceback attribute) - single: tb_lineno (traceback attribute) - single: tb_lasti (traceback attribute) - pair: statement; try - - Special read-only attributes: - :attr:`tb_frame` points to the execution frame of the current level; - :attr:`tb_lineno` gives the line number where the exception occurred; - :attr:`tb_lasti` indicates the precise instruction. - The line number and last instruction in the traceback may differ from the - line number of its frame object if the exception occurred in a - :keyword:`try` statement with no matching except clause or with a - finally clause. - - Accessing ``tb_frame`` raises an :ref:`auditing event ` - ``object.__getattr__`` with arguments ``obj`` and ``"tb_frame"``. - - .. index:: - single: tb_next (traceback attribute) - - Special writable attribute: :attr:`tb_next` is the next level in the stack - trace (towards the frame where the exception occurred), or ``None`` if - there is no next level. - - .. versionchanged:: 3.7 - Traceback objects can now be explicitly instantiated from Python code, - and the ``tb_next`` attribute of existing instances can be updated. - - Slice objects - .. index:: pair: built-in function; slice - - Slice objects are used to represent slices for - :meth:`~object.__getitem__` - methods. They are also created by the built-in :func:`slice` function. - - .. index:: - single: start (slice object attribute) - single: stop (slice object attribute) - single: step (slice object attribute) - - Special read-only attributes: :attr:`~slice.start` is the lower bound; - :attr:`~slice.stop` is the upper bound; :attr:`~slice.step` is the step - value; each is ``None`` if omitted. These attributes can have any type. - - Slice objects support one method: - - .. method:: slice.indices(self, length) - - This method takes a single integer argument *length* and computes - information about the slice that the slice object would describe if - applied to a sequence of *length* items. It returns a tuple of three - integers; respectively these are the *start* and *stop* indices and the - *step* or stride length of the slice. Missing or out-of-bounds indices - are handled in a manner consistent with regular slices. - - Static method objects - Static method objects provide a way of defeating the transformation of function - objects to method objects described above. A static method object is a wrapper - around any other object, usually a user-defined method object. When a static - method object is retrieved from a class or a class instance, the object actually - returned is the wrapped object, which is not subject to any further - transformation. Static method objects are also callable. Static method - objects are created by the built-in :func:`staticmethod` constructor. - - Class method objects - A class method object, like a static method object, is a wrapper around another - object that alters the way in which that object is retrieved from classes and - class instances. The behaviour of class method objects upon such retrieval is - described above, under "User-defined methods". Class method objects are created - by the built-in :func:`classmethod` constructor. +-------------- + +.. index:: + single: internal type + single: types, internal + +A few types used internally by the interpreter are exposed to the user. Their +definitions may change with future versions of the interpreter, but they are +mentioned here for completeness. + + +.. _code-objects: + +Code objects +^^^^^^^^^^^^ + +.. index:: bytecode, object; code, code object + +Code objects represent *byte-compiled* executable Python code, or :term:`bytecode`. +The difference between a code object and a function object is that the function +object contains an explicit reference to the function's globals (the module in +which it was defined), while a code object contains no context; also the default +argument values are stored in the function object, not in the code object +(because they represent values calculated at run-time). Unlike function +objects, code objects are immutable and contain no references (directly or +indirectly) to mutable objects. + +.. index:: + single: co_argcount (code object attribute) + single: co_posonlyargcount (code object attribute) + single: co_kwonlyargcount (code object attribute) + single: co_code (code object attribute) + single: co_consts (code object attribute) + single: co_filename (code object attribute) + single: co_firstlineno (code object attribute) + single: co_flags (code object attribute) + single: co_lnotab (code object attribute) + single: co_name (code object attribute) + single: co_names (code object attribute) + single: co_nlocals (code object attribute) + single: co_stacksize (code object attribute) + single: co_varnames (code object attribute) + single: co_cellvars (code object attribute) + single: co_freevars (code object attribute) + single: co_qualname (code object attribute) + +Special read-only attributes: :attr:`co_name` gives the function name; +:attr:`co_qualname` gives the fully qualified function name; +:attr:`co_argcount` is the total number of positional arguments +(including positional-only arguments and arguments with default values); +:attr:`co_posonlyargcount` is the number of positional-only arguments +(including arguments with default values); :attr:`co_kwonlyargcount` is +the number of keyword-only arguments (including arguments with default +values); :attr:`co_nlocals` is the number of local variables used by the +function (including arguments); :attr:`co_varnames` is a tuple containing +the names of the local variables (starting with the argument names); +:attr:`co_cellvars` is a tuple containing the names of local variables +that are referenced by nested functions; :attr:`co_freevars` is a tuple +containing the names of free variables; :attr:`co_code` is a string +representing the sequence of bytecode instructions; :attr:`co_consts` is +a tuple containing the literals used by the bytecode; :attr:`co_names` is +a tuple containing the names used by the bytecode; :attr:`co_filename` is +the filename from which the code was compiled; :attr:`co_firstlineno` is +the first line number of the function; :attr:`co_lnotab` is a string +encoding the mapping from bytecode offsets to line numbers (for details +see the source code of the interpreter, is deprecated since 3.12 +and may be removed in 3.14); :attr:`co_stacksize` is the +required stack size; :attr:`co_flags` is an integer encoding a number +of flags for the interpreter. + +.. index:: pair: object; generator + +The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if +the function uses the ``*arguments`` syntax to accept an arbitrary number of +positional arguments; bit ``0x08`` is set if the function uses the +``**keywords`` syntax to accept arbitrary keyword arguments; bit ``0x20`` is set +if the function is a generator. + +Future feature declarations (``from __future__ import division``) also use bits +in :attr:`co_flags` to indicate whether a code object was compiled with a +particular feature enabled: bit ``0x2000`` is set if the function was compiled +with future division enabled; bits ``0x10`` and ``0x1000`` were used in earlier +versions of Python. + +Other bits in :attr:`co_flags` are reserved for internal use. + +.. index:: single: documentation string + +If a code object represents a function, the first item in :attr:`co_consts` is +the documentation string of the function, or ``None`` if undefined. + +.. method:: codeobject.co_positions() + + Returns an iterable over the source code positions of each bytecode + instruction in the code object. + + The iterator returns tuples containing the ``(start_line, end_line, + start_column, end_column)``. The *i-th* tuple corresponds to the + position of the source code that compiled to the *i-th* instruction. + Column information is 0-indexed utf-8 byte offsets on the given source + line. + + This positional information can be missing. A non-exhaustive lists of + cases where this may happen: + + - Running the interpreter with :option:`-X` ``no_debug_ranges``. + - Loading a pyc file compiled while using :option:`-X` ``no_debug_ranges``. + - Position tuples corresponding to artificial instructions. + - Line and column numbers that can't be represented due to + implementation specific limitations. + + When this occurs, some or all of the tuple elements can be + :const:`None`. + + .. versionadded:: 3.11 + + .. note:: + This feature requires storing column positions in code objects which may + result in a small increase of disk usage of compiled Python files or + interpreter memory usage. To avoid storing the extra information and/or + deactivate printing the extra traceback information, the + :option:`-X` ``no_debug_ranges`` command line flag or the :envvar:`PYTHONNODEBUGRANGES` + environment variable can be used. + + +.. _frame-objects: + +Frame objects +^^^^^^^^^^^^^ + +.. index:: pair: object; frame + +Frame objects represent execution frames. They may occur in traceback objects +(see below), and are also passed to registered trace functions. + +.. index:: + single: f_back (frame attribute) + single: f_code (frame attribute) + single: f_globals (frame attribute) + single: f_locals (frame attribute) + single: f_lasti (frame attribute) + single: f_builtins (frame attribute) + +Special read-only attributes: :attr:`f_back` is to the previous stack frame +(towards the caller), or ``None`` if this is the bottom stack frame; +:attr:`f_code` is the code object being executed in this frame; :attr:`f_locals` +is the dictionary used to look up local variables; :attr:`f_globals` is used for +global variables; :attr:`f_builtins` is used for built-in (intrinsic) names; +:attr:`f_lasti` gives the precise instruction (this is an index into the +bytecode string of the code object). + +Accessing ``f_code`` raises an :ref:`auditing event ` +``object.__getattr__`` with arguments ``obj`` and ``"f_code"``. + +.. index:: + single: f_trace (frame attribute) + single: f_trace_lines (frame attribute) + single: f_trace_opcodes (frame attribute) + single: f_lineno (frame attribute) + +Special writable attributes: :attr:`f_trace`, if not ``None``, is a function +called for various events during code execution (this is used by the debugger). +Normally an event is triggered for each new source line - this can be +disabled by setting :attr:`f_trace_lines` to :const:`False`. + +Implementations *may* allow per-opcode events to be requested by setting +:attr:`f_trace_opcodes` to :const:`True`. Note that this may lead to +undefined interpreter behaviour if exceptions raised by the trace +function escape to the function being traced. + +:attr:`f_lineno` is the current line number of the frame --- writing to this +from within a trace function jumps to the given line (only for the bottom-most +frame). A debugger can implement a Jump command (aka Set Next Statement) +by writing to f_lineno. + +Frame objects support one method: + +.. method:: frame.clear() + + This method clears all references to local variables held by the + frame. Also, if the frame belonged to a generator, the generator + is finalized. This helps break reference cycles involving frame + objects (for example when catching an exception and storing its + traceback for later use). + + :exc:`RuntimeError` is raised if the frame is currently executing. + + .. versionadded:: 3.4 + + +.. _traceback-objects: + +Traceback objects +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; traceback + pair: stack; trace + pair: exception; handler + pair: execution; stack + single: exc_info (in module sys) + single: last_traceback (in module sys) + single: sys.exc_info + single: sys.exception + single: sys.last_traceback + +Traceback objects represent a stack trace of an exception. A traceback object +is implicitly created when an exception occurs, and may also be explicitly +created by calling :class:`types.TracebackType`. + +For implicitly created tracebacks, when the search for an exception handler +unwinds the execution stack, at each unwound level a traceback object is +inserted in front of the current traceback. When an exception handler is +entered, the stack trace is made available to the program. (See section +:ref:`try`.) It is accessible as the third item of the +tuple returned by ``sys.exc_info()``, and as the ``__traceback__`` attribute +of the caught exception. + +When the program contains no suitable +handler, the stack trace is written (nicely formatted) to the standard error +stream; if the interpreter is interactive, it is also made available to the user +as ``sys.last_traceback``. + +For explicitly created tracebacks, it is up to the creator of the traceback +to determine how the ``tb_next`` attributes should be linked to form a +full stack trace. + +.. index:: + single: tb_frame (traceback attribute) + single: tb_lineno (traceback attribute) + single: tb_lasti (traceback attribute) + pair: statement; try + +Special read-only attributes: +:attr:`tb_frame` points to the execution frame of the current level; +:attr:`tb_lineno` gives the line number where the exception occurred; +:attr:`tb_lasti` indicates the precise instruction. +The line number and last instruction in the traceback may differ from the +line number of its frame object if the exception occurred in a +:keyword:`try` statement with no matching except clause or with a +finally clause. + +Accessing ``tb_frame`` raises an :ref:`auditing event ` +``object.__getattr__`` with arguments ``obj`` and ``"tb_frame"``. + +.. index:: + single: tb_next (traceback attribute) + +Special writable attribute: :attr:`tb_next` is the next level in the stack +trace (towards the frame where the exception occurred), or ``None`` if +there is no next level. + +.. versionchanged:: 3.7 + Traceback objects can now be explicitly instantiated from Python code, + and the ``tb_next`` attribute of existing instances can be updated. + + +Slice objects +^^^^^^^^^^^^^ + +.. index:: pair: built-in function; slice + +Slice objects are used to represent slices for +:meth:`~object.__getitem__` +methods. They are also created by the built-in :func:`slice` function. + +.. index:: + single: start (slice object attribute) + single: stop (slice object attribute) + single: step (slice object attribute) + +Special read-only attributes: :attr:`~slice.start` is the lower bound; +:attr:`~slice.stop` is the upper bound; :attr:`~slice.step` is the step +value; each is ``None`` if omitted. These attributes can have any type. + +Slice objects support one method: + +.. method:: slice.indices(self, length) + + This method takes a single integer argument *length* and computes + information about the slice that the slice object would describe if + applied to a sequence of *length* items. It returns a tuple of three + integers; respectively these are the *start* and *stop* indices and the + *step* or stride length of the slice. Missing or out-of-bounds indices + are handled in a manner consistent with regular slices. + + +Static method objects +^^^^^^^^^^^^^^^^^^^^^ + +Static method objects provide a way of defeating the transformation of function +objects to method objects described above. A static method object is a wrapper +around any other object, usually a user-defined method object. When a static +method object is retrieved from a class or a class instance, the object actually +returned is the wrapped object, which is not subject to any further +transformation. Static method objects are also callable. Static method +objects are created by the built-in :func:`staticmethod` constructor. + + +Class method objects +^^^^^^^^^^^^^^^^^^^^ + +A class method object, like a static method object, is a wrapper around another +object that alters the way in which that object is retrieved from classes and +class instances. The behaviour of class method objects upon such retrieval is +described above, under "User-defined methods". Class method objects are created +by the built-in :func:`classmethod` constructor. .. _specialnames: @@ -1594,9 +1700,9 @@ Basic customization Called to implement truth value testing and the built-in operation ``bool()``; should return ``False`` or ``True``. When this method is not - defined, :meth:`__len__` is called, if it is defined, and the object is + defined, :meth:`~object.__len__` is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither - :meth:`__len__` nor :meth:`__bool__`, all its instances are considered + :meth:`!__len__` nor :meth:`!__bool__`, all its instances are considered true. @@ -1920,8 +2026,7 @@ Attribute lookup speed can be significantly improved as well. .. _datamodel-note-slots: -Notes on using *__slots__* -"""""""""""""""""""""""""" +Notes on using *__slots__*: * When inheriting from a class without *__slots__*, the :attr:`~object.__dict__` and @@ -2494,16 +2599,16 @@ through the object's keys; for sequences, it should iterate through the values. Called to implement the built-in function :func:`len`. Should return the length of the object, an integer ``>=`` 0. Also, an object that doesn't define a - :meth:`__bool__` method and whose :meth:`__len__` method returns zero is + :meth:`~object.__bool__` method and whose :meth:`!__len__` method returns zero is considered to be false in a Boolean context. .. impl-detail:: - In CPython, the length is required to be at most :attr:`sys.maxsize`. - If the length is larger than :attr:`!sys.maxsize` some features (such as + In CPython, the length is required to be at most :data:`sys.maxsize`. + If the length is larger than :data:`!sys.maxsize` some features (such as :func:`len`) may raise :exc:`OverflowError`. To prevent raising :exc:`!OverflowError` by truth value testing, an object must define a - :meth:`__bool__` method. + :meth:`~object.__bool__` method. .. method:: object.__length_hint__(self) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index ce1c9a59d58353..5e9d12c0087a94 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -499,8 +499,8 @@ the yield expression. It can be either set explicitly when raising :exc:`StopIteration`, or automatically when the subiterator is a generator (by returning a value from the subgenerator). - .. versionchanged:: 3.3 - Added ``yield from `` to delegate control flow to a subiterator. +.. versionchanged:: 3.3 + Added ``yield from `` to delegate control flow to a subiterator. The parentheses may be omitted when the yield expression is the sole expression on the right hand side of an assignment statement. @@ -1724,7 +1724,7 @@ control flow statements, the following values are interpreted as false: ``False``, ``None``, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. User-defined objects can customize their -truth value by providing a :meth:`__bool__` method. +truth value by providing a :meth:`~object.__bool__` method. .. index:: pair: operator; not diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 0f416a5c583f85..1a2677e7562b9c 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -375,32 +375,32 @@ of what happens during the loading portion of import:: Note the following details: - * If there is an existing module object with the given name in - :data:`sys.modules`, import will have already returned it. +* If there is an existing module object with the given name in + :data:`sys.modules`, import will have already returned it. - * The module will exist in :data:`sys.modules` before the loader - executes the module code. This is crucial because the module code may - (directly or indirectly) import itself; adding it to :data:`sys.modules` - beforehand prevents unbounded recursion in the worst case and multiple - loading in the best. +* The module will exist in :data:`sys.modules` before the loader + executes the module code. This is crucial because the module code may + (directly or indirectly) import itself; adding it to :data:`sys.modules` + beforehand prevents unbounded recursion in the worst case and multiple + loading in the best. - * If loading fails, the failing module -- and only the failing module -- - gets removed from :data:`sys.modules`. Any module already in the - :data:`sys.modules` cache, and any module that was successfully loaded - as a side-effect, must remain in the cache. This contrasts with - reloading where even the failing module is left in :data:`sys.modules`. +* If loading fails, the failing module -- and only the failing module -- + gets removed from :data:`sys.modules`. Any module already in the + :data:`sys.modules` cache, and any module that was successfully loaded + as a side-effect, must remain in the cache. This contrasts with + reloading where even the failing module is left in :data:`sys.modules`. - * After the module is created but before execution, the import machinery - sets the import-related module attributes ("_init_module_attrs" in - the pseudo-code example above), as summarized in a - :ref:`later section `. +* After the module is created but before execution, the import machinery + sets the import-related module attributes ("_init_module_attrs" in + the pseudo-code example above), as summarized in a + :ref:`later section `. - * Module execution is the key moment of loading in which the module's - namespace gets populated. Execution is entirely delegated to the - loader, which gets to decide what gets populated and how. +* Module execution is the key moment of loading in which the module's + namespace gets populated. Execution is entirely delegated to the + loader, which gets to decide what gets populated and how. - * The module created during loading and passed to exec_module() may - not be the one returned at the end of import [#fnlo]_. +* The module created during loading and passed to exec_module() may + not be the one returned at the end of import [#fnlo]_. .. versionchanged:: 3.4 The import system has taken over the boilerplate responsibilities of @@ -417,13 +417,13 @@ returned from :meth:`~importlib.abc.Loader.exec_module` is ignored. Loaders must satisfy the following requirements: - * If the module is a Python module (as opposed to a built-in module or a - dynamically loaded extension), the loader should execute the module's code - in the module's global name space (``module.__dict__``). +* If the module is a Python module (as opposed to a built-in module or a + dynamically loaded extension), the loader should execute the module's code + in the module's global name space (``module.__dict__``). - * If the loader cannot execute the module, it should raise an - :exc:`ImportError`, although any other exception raised during - :meth:`~importlib.abc.Loader.exec_module` will be propagated. +* If the loader cannot execute the module, it should raise an + :exc:`ImportError`, although any other exception raised during + :meth:`~importlib.abc.Loader.exec_module` will be propagated. In many cases, the finder and loader can be the same object; in such cases the :meth:`~importlib.abc.MetaPathFinder.find_spec` method would just return a @@ -453,20 +453,20 @@ import machinery will create the new module itself. functionality described above in addition to executing the module. All the same constraints apply, with some additional clarification: - * If there is an existing module object with the given name in - :data:`sys.modules`, the loader must use that existing module. - (Otherwise, :func:`importlib.reload` will not work correctly.) If the - named module does not exist in :data:`sys.modules`, the loader - must create a new module object and add it to :data:`sys.modules`. + * If there is an existing module object with the given name in + :data:`sys.modules`, the loader must use that existing module. + (Otherwise, :func:`importlib.reload` will not work correctly.) If the + named module does not exist in :data:`sys.modules`, the loader + must create a new module object and add it to :data:`sys.modules`. - * The module *must* exist in :data:`sys.modules` before the loader - executes the module code, to prevent unbounded recursion or multiple - loading. + * The module *must* exist in :data:`sys.modules` before the loader + executes the module code, to prevent unbounded recursion or multiple + loading. - * If loading fails, the loader must remove any modules it has inserted - into :data:`sys.modules`, but it must remove **only** the failing - module(s), and only if the loader itself has loaded the module(s) - explicitly. + * If loading fails, the loader must remove any modules it has inserted + into :data:`sys.modules`, but it must remove **only** the failing + module(s), and only if the loader itself has loaded the module(s) + explicitly. .. versionchanged:: 3.5 A :exc:`DeprecationWarning` is raised when ``exec_module()`` is defined but @@ -693,17 +693,17 @@ with defaults for whatever information is missing. Here are the exact rules used: - * If the module has a ``__spec__`` attribute, the information in the spec - is used to generate the repr. The "name", "loader", "origin", and - "has_location" attributes are consulted. +* If the module has a ``__spec__`` attribute, the information in the spec + is used to generate the repr. The "name", "loader", "origin", and + "has_location" attributes are consulted. - * If the module has a ``__file__`` attribute, this is used as part of the - module's repr. +* If the module has a ``__file__`` attribute, this is used as part of the + module's repr. - * If the module has no ``__file__`` but does have a ``__loader__`` that is not - ``None``, then the loader's repr is used as part of the module's repr. +* If the module has no ``__file__`` but does have a ``__loader__`` that is not + ``None``, then the loader's repr is used as part of the module's repr. - * Otherwise, just use the module's ``__name__`` in the repr. +* Otherwise, just use the module's ``__name__`` in the repr. .. versionchanged:: 3.12 Use of :meth:`!module_repr`, having been deprecated since Python 3.4, was diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 47062f86810e91..3e07d16068a627 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -315,7 +315,7 @@ The Unicode category codes mentioned above stand for: * *Nd* - decimal numbers * *Pc* - connector punctuations * *Other_ID_Start* - explicit list of characters in `PropList.txt - `_ to support backwards + `_ to support backwards compatibility * *Other_ID_Continue* - likewise @@ -323,8 +323,8 @@ All identifiers are converted into the normal form NFKC while parsing; compariso of identifiers is based on NFKC. A non-normative HTML file listing all valid identifier characters for Unicode -15.0.0 can be found at -https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt +15.1.0 can be found at +https://www.unicode.org/Public/15.1.0/ucd/DerivedCoreProperties.txt .. _keywords: @@ -549,55 +549,59 @@ retained), except that three unescaped quotes in a row terminate the literal. ( .. _escape-sequences: + +Escape sequences +^^^^^^^^^^^^^^^^ + Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in string and bytes literals are interpreted according to rules similar to those used by Standard C. The recognized escape sequences are: -+-----------------+---------------------------------+-------+ -| Escape Sequence | Meaning | Notes | -+=================+=================================+=======+ -| ``\``\ | Backslash and newline ignored | \(1) | -+-----------------+---------------------------------+-------+ -| ``\\`` | Backslash (``\``) | | -+-----------------+---------------------------------+-------+ -| ``\'`` | Single quote (``'``) | | -+-----------------+---------------------------------+-------+ -| ``\"`` | Double quote (``"``) | | -+-----------------+---------------------------------+-------+ -| ``\a`` | ASCII Bell (BEL) | | -+-----------------+---------------------------------+-------+ -| ``\b`` | ASCII Backspace (BS) | | -+-----------------+---------------------------------+-------+ -| ``\f`` | ASCII Formfeed (FF) | | -+-----------------+---------------------------------+-------+ -| ``\n`` | ASCII Linefeed (LF) | | -+-----------------+---------------------------------+-------+ -| ``\r`` | ASCII Carriage Return (CR) | | -+-----------------+---------------------------------+-------+ -| ``\t`` | ASCII Horizontal Tab (TAB) | | -+-----------------+---------------------------------+-------+ -| ``\v`` | ASCII Vertical Tab (VT) | | -+-----------------+---------------------------------+-------+ -| ``\ooo`` | Character with octal value | (2,4) | -| | *ooo* | | -+-----------------+---------------------------------+-------+ -| ``\xhh`` | Character with hex value *hh* | (3,4) | -+-----------------+---------------------------------+-------+ ++-------------------------+---------------------------------+-------+ +| Escape Sequence | Meaning | Notes | ++=========================+=================================+=======+ +| ``\``\ | Backslash and newline ignored | \(1) | ++-------------------------+---------------------------------+-------+ +| ``\\`` | Backslash (``\``) | | ++-------------------------+---------------------------------+-------+ +| ``\'`` | Single quote (``'``) | | ++-------------------------+---------------------------------+-------+ +| ``\"`` | Double quote (``"``) | | ++-------------------------+---------------------------------+-------+ +| ``\a`` | ASCII Bell (BEL) | | ++-------------------------+---------------------------------+-------+ +| ``\b`` | ASCII Backspace (BS) | | ++-------------------------+---------------------------------+-------+ +| ``\f`` | ASCII Formfeed (FF) | | ++-------------------------+---------------------------------+-------+ +| ``\n`` | ASCII Linefeed (LF) | | ++-------------------------+---------------------------------+-------+ +| ``\r`` | ASCII Carriage Return (CR) | | ++-------------------------+---------------------------------+-------+ +| ``\t`` | ASCII Horizontal Tab (TAB) | | ++-------------------------+---------------------------------+-------+ +| ``\v`` | ASCII Vertical Tab (VT) | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\\\{ooo}` | Character with octal value | (2,4) | +| | *ooo* | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\x{hh}` | Character with hex value *hh* | (3,4) | ++-------------------------+---------------------------------+-------+ Escape sequences only recognized in string literals are: -+-----------------+---------------------------------+-------+ -| Escape Sequence | Meaning | Notes | -+=================+=================================+=======+ -| ``\N{name}`` | Character named *name* in the | \(5) | -| | Unicode database | | -+-----------------+---------------------------------+-------+ -| ``\uxxxx`` | Character with 16-bit hex value | \(6) | -| | *xxxx* | | -+-----------------+---------------------------------+-------+ -| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) | -| | *xxxxxxxx* | | -+-----------------+---------------------------------+-------+ ++-------------------------+---------------------------------+-------+ +| Escape Sequence | Meaning | Notes | ++=========================+=================================+=======+ +| :samp:`\\N\\{{name}\\}` | Character named *name* in the | \(5) | +| | Unicode database | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\u{xxxx}` | Character with 16-bit hex value | \(6) | +| | *xxxx* | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\U{xxxxxxxx}` | Character with 32-bit hex value | \(7) | +| | *xxxxxxxx* | | ++-------------------------+---------------------------------+-------+ Notes: @@ -653,12 +657,12 @@ is more easily recognized as broken.) It is also important to note that the escape sequences only recognized in string literals fall into the category of unrecognized escapes for bytes literals. - .. versionchanged:: 3.6 - Unrecognized escape sequences produce a :exc:`DeprecationWarning`. +.. versionchanged:: 3.6 + Unrecognized escape sequences produce a :exc:`DeprecationWarning`. - .. versionchanged:: 3.12 - Unrecognized escape sequences produce a :exc:`SyntaxWarning`. In a future - Python version they will be eventually a :exc:`SyntaxError`. +.. versionchanged:: 3.12 + Unrecognized escape sequences produce a :exc:`SyntaxWarning`. In a future + Python version they will be eventually a :exc:`SyntaxError`. Even in a raw literal, quotes can be escaped with a backslash, but the backslash remains in the result; for example, ``r"\""`` is a valid string @@ -783,7 +787,7 @@ is converted before formatting. Conversion ``'!s'`` calls :func:`str` on the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`. The result is then formatted using the :func:`format` protocol. The -format specifier is passed to the :meth:`__format__` method of the +format specifier is passed to the :meth:`~object.__format__` method of the expression or conversion result. An empty string is passed when the format specifier is omitted. The formatted result is then included in the final value of the whole string. @@ -1041,4 +1045,4 @@ occurrence outside string literals and comments is an unconditional error: .. rubric:: Footnotes -.. [#] https://www.unicode.org/Public/15.0.0/ucd/NameAliases.txt +.. [#] https://www.unicode.org/Public/15.1.0/ucd/NameAliases.txt diff --git a/Doc/requirements-oldest-sphinx.txt b/Doc/requirements-oldest-sphinx.txt index f7e0665bde445d..5de739fc10b085 100644 --- a/Doc/requirements-oldest-sphinx.txt +++ b/Doc/requirements-oldest-sphinx.txt @@ -7,32 +7,30 @@ blurb python-docs-theme>=2022.1 # Generated from: -# pip install "Sphinx~=3.2.0" "docutils<0.17" "Jinja2<3" "MarkupSafe<2" +# pip install "Sphinx~=4.2.0" # pip freeze # -# Sphinx 3.2 comes from ``needs_sphinx = '3.2'`` in ``Doc/conf.py``. -# Docutils<0.17, Jinja2<3, and MarkupSafe<2 are additionally specified as -# Sphinx 3.2 is incompatible with newer releases of these packages. +# Sphinx 4.2 comes from ``needs_sphinx = '4.2'`` in ``Doc/conf.py``. -Sphinx==3.2.1 alabaster==0.7.13 -Babel==2.12.1 -certifi==2022.12.7 -charset-normalizer==3.1.0 +Babel==2.13.0 +certifi==2023.7.22 +charset-normalizer==3.3.0 colorama==0.4.6 -docutils==0.16 +docutils==0.17.1 idna==3.4 imagesize==1.4.1 -Jinja2==2.11.3 -MarkupSafe==1.1.1 -packaging==23.1 -Pygments==2.15.1 +Jinja2==3.1.2 +MarkupSafe==2.1.3 +packaging==23.2 +Pygments==2.16.1 requests==2.31.0 snowballstemmer==2.2.0 +Sphinx==4.2.0 sphinxcontrib-applehelp==1.0.4 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.1 sphinxcontrib-jsmath==1.0.1 sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 -urllib3==1.26.15 +urllib3==2.0.6 diff --git a/Doc/requirements.txt b/Doc/requirements.txt index bde509febf5bde..d4f23ea8c400fe 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -7,7 +7,7 @@ # won't suddenly cause build failures. Updating the version is fine as long # as no warnings are raised by doing so. # PR #104777: Sphinx 6.2 no longer uses imghdr, removed in Python 3.13. -sphinx==6.2.0 +sphinx==6.2.1 blurb @@ -15,6 +15,6 @@ sphinxext-opengraph==0.7.5 # The theme used by the documentation is stored separately, so we need # to install that as well. -python-docs-theme>=2022.1 +python-docs-theme>=2023.3.1,!=2023.7 -c constraints.txt diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore index 23aa30c956b3bd..8ae6500277fd5d 100644 --- a/Doc/tools/.nitignore +++ b/Doc/tools/.nitignore @@ -1,85 +1,38 @@ # All RST files under Doc/ -- except these -- must pass Sphinx nit-picky mode, -# as tested on the CI via touch-clean-files.py in doc.yml. -# Add blank lines between files and keep them sorted lexicographically -# to help avoid merge conflicts. +# as tested on the CI via check-warnings.py in reusable-docs.yml. +# Keep lines sorted lexicographically to help avoid merge conflicts. -Doc/c-api/allocation.rst -Doc/c-api/apiabiversion.rst -Doc/c-api/arg.rst -Doc/c-api/bool.rst -Doc/c-api/buffer.rst -Doc/c-api/bytes.rst -Doc/c-api/call.rst -Doc/c-api/capsule.rst -Doc/c-api/cell.rst -Doc/c-api/code.rst -Doc/c-api/codec.rst -Doc/c-api/complex.rst -Doc/c-api/conversion.rst -Doc/c-api/datetime.rst Doc/c-api/descriptor.rst -Doc/c-api/dict.rst Doc/c-api/exceptions.rst Doc/c-api/file.rst Doc/c-api/float.rst Doc/c-api/gcsupport.rst -Doc/c-api/import.rst Doc/c-api/init.rst Doc/c-api/init_config.rst Doc/c-api/intro.rst -Doc/c-api/iterator.rst -Doc/c-api/long.rst -Doc/c-api/mapping.rst -Doc/c-api/marshal.rst Doc/c-api/memory.rst Doc/c-api/memoryview.rst Doc/c-api/module.rst -Doc/c-api/none.rst Doc/c-api/object.rst -Doc/c-api/refcounting.rst -Doc/c-api/sequence.rst Doc/c-api/set.rst Doc/c-api/stable.rst Doc/c-api/structures.rst Doc/c-api/sys.rst -Doc/c-api/tuple.rst Doc/c-api/type.rst -Doc/c-api/typehints.rst Doc/c-api/typeobj.rst -Doc/c-api/unicode.rst -Doc/c-api/veryhigh.rst -Doc/c-api/weakref.rst -Doc/extending/embedding.rst Doc/extending/extending.rst Doc/extending/newtypes.rst -Doc/extending/newtypes_tutorial.rst -Doc/faq/design.rst -Doc/faq/extending.rst -Doc/faq/gui.rst -Doc/faq/library.rst -Doc/faq/programming.rst Doc/glossary.rst -Doc/howto/curses.rst Doc/howto/descriptor.rst Doc/howto/enum.rst -Doc/howto/functional.rst -Doc/howto/instrumentation.rst Doc/howto/isolating-extensions.rst -Doc/howto/logging-cookbook.rst Doc/howto/logging.rst -Doc/howto/regex.rst -Doc/howto/sorting.rst -Doc/howto/unicode.rst Doc/howto/urllib2.rst -Doc/install/index.rst -Doc/library/__future__.rst -Doc/library/_thread.rst Doc/library/abc.rst Doc/library/ast.rst Doc/library/asyncio-dev.rst Doc/library/asyncio-eventloop.rst Doc/library/asyncio-extending.rst -Doc/library/asyncio-future.rst Doc/library/asyncio-policy.rst Doc/library/asyncio-stream.rst Doc/library/asyncio-subprocess.rst @@ -88,39 +41,22 @@ Doc/library/bdb.rst Doc/library/bisect.rst Doc/library/bz2.rst Doc/library/calendar.rst -Doc/library/cgi.rst -Doc/library/cmath.rst Doc/library/cmd.rst -Doc/library/code.rst Doc/library/codecs.rst -Doc/library/codeop.rst Doc/library/collections.abc.rst Doc/library/collections.rst -Doc/library/compileall.rst Doc/library/concurrent.futures.rst -Doc/library/concurrent.rst Doc/library/configparser.rst -Doc/library/constants.rst Doc/library/contextlib.rst -Doc/library/copy.rst Doc/library/csv.rst -Doc/library/ctypes.rst -Doc/library/curses.ascii.rst -Doc/library/curses.rst Doc/library/datetime.rst Doc/library/dbm.rst Doc/library/decimal.rst -Doc/library/devmode.rst -Doc/library/difflib.rst -Doc/library/dis.rst Doc/library/doctest.rst Doc/library/email.charset.rst Doc/library/email.compat32-message.rst -Doc/library/email.encoders.rst Doc/library/email.errors.rst -Doc/library/email.generator.rst Doc/library/email.headerregistry.rst -Doc/library/email.message.rst Doc/library/email.mime.rst Doc/library/email.parser.rst Doc/library/email.policy.rst @@ -128,42 +64,28 @@ Doc/library/enum.rst Doc/library/exceptions.rst Doc/library/faulthandler.rst Doc/library/fcntl.rst -Doc/library/filecmp.rst -Doc/library/fileinput.rst -Doc/library/fractions.rst Doc/library/ftplib.rst Doc/library/functions.rst Doc/library/functools.rst -Doc/library/getopt.rst Doc/library/getpass.rst Doc/library/gettext.rst -Doc/library/graphlib.rst Doc/library/gzip.rst -Doc/library/hashlib.rst Doc/library/http.client.rst Doc/library/http.cookiejar.rst Doc/library/http.cookies.rst Doc/library/http.server.rst -Doc/library/idle.rst -Doc/library/importlib.resources.abc.rst Doc/library/importlib.resources.rst Doc/library/importlib.rst Doc/library/inspect.rst -Doc/library/io.rst -Doc/library/json.rst Doc/library/locale.rst Doc/library/logging.config.rst Doc/library/logging.handlers.rst -Doc/library/logging.rst Doc/library/lzma.rst Doc/library/mailbox.rst Doc/library/mmap.rst -Doc/library/msvcrt.rst Doc/library/multiprocessing.rst Doc/library/multiprocessing.shared_memory.rst -Doc/library/netrc.rst Doc/library/numbers.rst -Doc/library/operator.rst Doc/library/optparse.rst Doc/library/os.path.rst Doc/library/os.rst @@ -171,98 +93,59 @@ Doc/library/pickle.rst Doc/library/pickletools.rst Doc/library/platform.rst Doc/library/plistlib.rst -Doc/library/poplib.rst -Doc/library/posix.rst -Doc/library/pprint.rst Doc/library/profile.rst -Doc/library/pty.rst -Doc/library/py_compile.rst Doc/library/pyclbr.rst Doc/library/pydoc.rst Doc/library/pyexpat.rst Doc/library/random.rst -Doc/library/re.rst Doc/library/readline.rst Doc/library/reprlib.rst Doc/library/resource.rst Doc/library/rlcompleter.rst -Doc/library/sched.rst Doc/library/select.rst Doc/library/selectors.rst Doc/library/shelve.rst -Doc/library/shutil.rst Doc/library/signal.rst -Doc/library/site.rst Doc/library/smtplib.rst Doc/library/socket.rst -Doc/library/socketserver.rst Doc/library/ssl.rst -Doc/library/stat.rst Doc/library/stdtypes.rst Doc/library/string.rst -Doc/library/struct.rst Doc/library/subprocess.rst -Doc/library/sys.rst -Doc/library/sys_path_init.rst -Doc/library/sysconfig.rst Doc/library/syslog.rst Doc/library/tarfile.rst Doc/library/tempfile.rst Doc/library/termios.rst Doc/library/test.rst -Doc/library/textwrap.rst -Doc/library/threading.rst Doc/library/time.rst Doc/library/tkinter.rst Doc/library/tkinter.scrolledtext.rst Doc/library/tkinter.ttk.rst Doc/library/traceback.rst Doc/library/tty.rst -Doc/library/turtle.rst -Doc/library/unittest.mock-examples.rst Doc/library/unittest.mock.rst Doc/library/unittest.rst -Doc/library/urllib.error.rst Doc/library/urllib.parse.rst Doc/library/urllib.request.rst -Doc/library/uuid.rst -Doc/library/weakref.rst -Doc/library/winreg.rst -Doc/library/winsound.rst Doc/library/wsgiref.rst Doc/library/xml.dom.minidom.rst Doc/library/xml.dom.pulldom.rst Doc/library/xml.dom.rst -Doc/library/xml.etree.elementtree.rst Doc/library/xml.rst Doc/library/xml.sax.handler.rst Doc/library/xml.sax.reader.rst Doc/library/xml.sax.rst -Doc/library/xml.sax.utils.rst Doc/library/xmlrpc.client.rst -Doc/library/xmlrpc.rst Doc/library/xmlrpc.server.rst Doc/library/zlib.rst -Doc/license.rst Doc/reference/compound_stmts.rst Doc/reference/datamodel.rst Doc/reference/expressions.rst Doc/reference/import.rst -Doc/reference/lexical_analysis.rst Doc/reference/simple_stmts.rst -Doc/tutorial/appendix.rst -Doc/tutorial/classes.rst -Doc/tutorial/controlflow.rst Doc/tutorial/datastructures.rst -Doc/tutorial/errors.rst -Doc/tutorial/inputoutput.rst -Doc/tutorial/interactive.rst Doc/tutorial/introduction.rst -Doc/tutorial/modules.rst -Doc/tutorial/stdlib2.rst Doc/using/cmdline.rst -Doc/using/configure.rst -Doc/using/unix.rst Doc/using/windows.rst Doc/whatsnew/2.0.rst Doc/whatsnew/2.1.rst diff --git a/Doc/tools/check-warnings.py b/Doc/tools/check-warnings.py new file mode 100644 index 00000000000000..809a8d63087e12 --- /dev/null +++ b/Doc/tools/check-warnings.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python3 +""" +Check the output of running Sphinx in nit-picky mode (missing references). +""" +from __future__ import annotations + +import argparse +import itertools +import os +import re +import subprocess +import sys +from pathlib import Path +from typing import TextIO + +# Exclude these whether they're dirty or clean, +# because they trigger a rebuild of dirty files. +EXCLUDE_FILES = { + "Doc/whatsnew/changelog.rst", +} + +# Subdirectories of Doc/ to exclude. +EXCLUDE_SUBDIRS = { + ".env", + ".venv", + "env", + "includes", + "venv", +} + +# Regex pattern to match the parts of a Sphinx warning +WARNING_PATTERN = re.compile( + r"(?P([A-Za-z]:[\\/])?[^:]+):(?P\d+): WARNING: (?P.+)" +) + +# Regex pattern to match the line numbers in a Git unified diff +DIFF_PATTERN = re.compile( + r"^@@ -(?P\d+)(?:,(?P\d+))? \+(?P\d+)(?:,(?P\d+))? @@", + flags=re.MULTILINE, +) + + +def get_diff_files(ref_a: str, ref_b: str, filter_mode: str = "") -> set[Path]: + """List the files changed between two Git refs, filtered by change type.""" + added_files_result = subprocess.run( + [ + "git", + "diff", + f"--diff-filter={filter_mode}", + "--name-only", + f"{ref_a}...{ref_b}", + "--", + ], + stdout=subprocess.PIPE, + check=True, + text=True, + encoding="UTF-8", + ) + + added_files = added_files_result.stdout.strip().split("\n") + return {Path(file.strip()) for file in added_files if file.strip()} + + +def get_diff_lines(ref_a: str, ref_b: str, file: Path) -> list[int]: + """List the lines changed between two Git refs for a specific file.""" + diff_output = subprocess.run( + [ + "git", + "diff", + "--unified=0", + f"{ref_a}...{ref_b}", + "--", + str(file), + ], + stdout=subprocess.PIPE, + check=True, + text=True, + encoding="UTF-8", + ) + + # Scrape line offsets + lengths from diff and convert to line numbers + line_matches = DIFF_PATTERN.finditer(diff_output.stdout) + # Removed and added line counts are 1 if not printed + line_match_values = [ + line_match.groupdict(default=1) for line_match in line_matches + ] + line_ints = [ + (int(match_value["lineb"]), int(match_value["added"])) + for match_value in line_match_values + ] + line_ranges = [ + range(line_b, line_b + added) for line_b, added in line_ints + ] + line_numbers = list(itertools.chain(*line_ranges)) + + return line_numbers + + +def get_para_line_numbers(file_obj: TextIO) -> list[list[int]]: + """Get the line numbers of text in a file object, grouped by paragraph.""" + paragraphs = [] + prev_line = None + for lineno, line in enumerate(file_obj): + lineno = lineno + 1 + if prev_line is None or (line.strip() and not prev_line.strip()): + paragraph = [lineno - 1] + paragraphs.append(paragraph) + paragraph.append(lineno) + prev_line = line + return paragraphs + + +def filter_and_parse_warnings( + warnings: list[str], files: set[Path] +) -> list[re.Match[str]]: + """Get the warnings matching passed files and parse them with regex.""" + filtered_warnings = [ + warning + for warning in warnings + if any(str(file) in warning for file in files) + ] + warning_matches = [ + WARNING_PATTERN.fullmatch(warning.strip()) + for warning in filtered_warnings + ] + non_null_matches = [warning for warning in warning_matches if warning] + return non_null_matches + + +def filter_warnings_by_diff( + warnings: list[re.Match[str]], ref_a: str, ref_b: str, file: Path +) -> list[re.Match[str]]: + """Filter the passed per-file warnings to just those on changed lines.""" + diff_lines = get_diff_lines(ref_a, ref_b, file) + with file.open(encoding="UTF-8") as file_obj: + paragraphs = get_para_line_numbers(file_obj) + touched_paras = [ + para_lines + for para_lines in paragraphs + if set(diff_lines) & set(para_lines) + ] + touched_para_lines = set(itertools.chain(*touched_paras)) + warnings_infile = [ + warning for warning in warnings if str(file) in warning["file"] + ] + warnings_touched = [ + warning + for warning in warnings_infile + if int(warning["line"]) in touched_para_lines + ] + return warnings_touched + + +def process_touched_warnings( + warnings: list[str], ref_a: str, ref_b: str +) -> list[re.Match[str]]: + """Filter a list of Sphinx warnings to those affecting touched lines.""" + added_files, modified_files = tuple( + get_diff_files(ref_a, ref_b, filter_mode=mode) for mode in ("A", "M") + ) + + warnings_added = filter_and_parse_warnings(warnings, added_files) + warnings_modified = filter_and_parse_warnings(warnings, modified_files) + + modified_files_warned = { + file + for file in modified_files + if any(str(file) in warning["file"] for warning in warnings_modified) + } + + warnings_modified_touched = [ + filter_warnings_by_diff(warnings_modified, ref_a, ref_b, file) + for file in modified_files_warned + ] + warnings_touched = warnings_added + list( + itertools.chain(*warnings_modified_touched) + ) + + return warnings_touched + + +def annotate_diff( + warnings: list[str], ref_a: str = "main", ref_b: str = "HEAD" +) -> None: + """ + Convert Sphinx warning messages to GitHub Actions for changed paragraphs. + + Converts lines like: + .../Doc/library/cgi.rst:98: WARNING: reference target not found + to: + ::warning file=.../Doc/library/cgi.rst,line=98::reference target not found + + See: + https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-warning-message + """ + warnings_touched = process_touched_warnings(warnings, ref_a, ref_b) + print("Emitting doc warnings matching modified lines:") + for warning in warnings_touched: + print("::warning file={file},line={line}::{msg}".format_map(warning)) + print(warning[0]) + if not warnings_touched: + print("None") + + +def fail_if_regression( + warnings: list[str], files_with_expected_nits: set[str], files_with_nits: set[str] +) -> int: + """ + Ensure some files always pass Sphinx nit-picky mode (no missing references). + These are files which are *not* in .nitignore. + """ + all_rst = { + str(rst) + for rst in Path("Doc/").rglob("*.rst") + if rst.parts[1] not in EXCLUDE_SUBDIRS + } + should_be_clean = all_rst - files_with_expected_nits - EXCLUDE_FILES + problem_files = sorted(should_be_clean & files_with_nits) + if problem_files: + print("\nError: must not contain warnings:\n") + for filename in problem_files: + print(filename) + for warning in warnings: + if filename in warning: + if match := WARNING_PATTERN.fullmatch(warning): + print(" {line}: {msg}".format_map(match)) + return -1 + return 0 + + +def fail_if_improved( + files_with_expected_nits: set[str], files_with_nits: set[str] +) -> int: + """ + We may have fixed warnings in some files so that the files are now completely clean. + Good news! Let's add them to .nitignore to prevent regression. + """ + files_with_no_nits = files_with_expected_nits - files_with_nits + if files_with_no_nits: + print("\nCongratulations! You improved:\n") + for filename in sorted(files_with_no_nits): + print(filename) + print("\nPlease remove from Doc/tools/.nitignore\n") + return -1 + return 0 + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument( + "--annotate-diff", + nargs="*", + metavar=("BASE_REF", "HEAD_REF"), + help="Add GitHub Actions annotations on the diff for warnings on " + "lines changed between the given refs (main and HEAD, by default)", + ) + parser.add_argument( + "--fail-if-regression", + action="store_true", + help="Fail if known-good files have warnings", + ) + parser.add_argument( + "--fail-if-improved", + action="store_true", + help="Fail if new files with no nits are found", + ) + + args = parser.parse_args(argv) + if args.annotate_diff is not None and len(args.annotate_diff) > 2: + parser.error( + "--annotate-diff takes between 0 and 2 ref args, not " + f"{len(args.annotate_diff)} {tuple(args.annotate_diff)}" + ) + exit_code = 0 + + wrong_directory_msg = "Must run this script from the repo root" + assert Path("Doc").exists() and Path("Doc").is_dir(), wrong_directory_msg + + with Path("Doc/sphinx-warnings.txt").open(encoding="UTF-8") as f: + warnings = f.read().splitlines() + + cwd = str(Path.cwd()) + os.path.sep + files_with_nits = { + warning.removeprefix(cwd).split(":")[0] + for warning in warnings + if "Doc/" in warning + } + + with Path("Doc/tools/.nitignore").open(encoding="UTF-8") as clean_files: + files_with_expected_nits = { + filename.strip() + for filename in clean_files + if filename.strip() and not filename.startswith("#") + } + + if args.annotate_diff is not None: + annotate_diff(warnings, *args.annotate_diff) + + if args.fail_if_regression: + exit_code += fail_if_regression( + warnings, files_with_expected_nits, files_with_nits + ) + + if args.fail_if_improved: + exit_code += fail_if_improved(files_with_expected_nits, files_with_nits) + + return exit_code + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 8d99b0bfa4f381..4ba5f5a1fbdc1b 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -39,7 +39,7 @@ ISSUE_URI = 'https://bugs.python.org/issue?@action=redirect&bpo=%s' GH_ISSUE_URI = 'https://github.com/python/cpython/issues/%s' -SOURCE_URI = 'https://github.com/python/cpython/tree/3.12/%s' +SOURCE_URI = 'https://github.com/python/cpython/tree/main/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body @@ -98,14 +98,13 @@ class ImplementationDetail(Directive): final_argument_whitespace = True # This text is copied to templates/dummy.html - label_text = 'CPython implementation detail:' + label_text = sphinx_gettext('CPython implementation detail:') def run(self): self.assert_has_content() pnode = nodes.compound(classes=['impl-detail']) - label = sphinx_gettext(self.label_text) content = self.content - add_text = nodes.strong(label, label) + add_text = nodes.strong(self.label_text, self.label_text) self.state.nested_parse(content, self.content_offset, pnode) content = nodes.inline(pnode[0].rawsource, translatable=True) content.source = pnode[0].source @@ -180,7 +179,7 @@ def parse_platforms(self): if unknown: cls = type(self) logger = logging.getLogger(cls.__qualname__) - logger.warn( + logger.warning( f"Unknown platform(s) or syntax '{' '.join(sorted(unknown))}' " f"in '.. availability:: {self.arguments[0]}', see " f"{__file__}:{cls.__qualname__}.known_platforms for a set " @@ -234,9 +233,9 @@ class AuditEvent(Directive): final_argument_whitespace = True _label = [ - "Raises an :ref:`auditing event ` {name} with no arguments.", - "Raises an :ref:`auditing event ` {name} with argument {args}.", - "Raises an :ref:`auditing event ` {name} with arguments {args}.", + sphinx_gettext("Raises an :ref:`auditing event ` {name} with no arguments."), + sphinx_gettext("Raises an :ref:`auditing event ` {name} with argument {args}."), + sphinx_gettext("Raises an :ref:`auditing event ` {name} with arguments {args}."), ] @property @@ -252,7 +251,7 @@ def run(self): else: args = [] - label = sphinx_gettext(self._label[min(2, len(args))]) + label = self._label[min(2, len(args))] text = label.format(name="``{}``".format(name), args=", ".join("``{}``".format(a) for a in args if a)) @@ -267,7 +266,7 @@ def run(self): info = env.all_audit_events.setdefault(name, new_info) if info is not new_info: if not self._do_args_match(info['args'], new_info['args']): - self.logger.warn( + self.logger.warning( "Mismatched arguments for audit-event {}: {!r} != {!r}" .format(name, info['args'], new_info['args']) ) @@ -414,8 +413,8 @@ class DeprecatedRemoved(Directive): final_argument_whitespace = True option_spec = {} - _deprecated_label = 'Deprecated since version {deprecated}, will be removed in version {removed}' - _removed_label = 'Deprecated since version {deprecated}, removed in version {removed}' + _deprecated_label = sphinx_gettext('Deprecated since version {deprecated}, will be removed in version {removed}') + _removed_label = sphinx_gettext('Deprecated since version {deprecated}, removed in version {removed}') def run(self): node = addnodes.versionmodified() @@ -431,7 +430,6 @@ def run(self): else: label = self._removed_label - label = sphinx_gettext(label) text = label.format(deprecated=self.arguments[0], removed=self.arguments[1]) if len(self.arguments) == 3: inodes, messages = self.state.inline_text(self.arguments[2], @@ -544,7 +542,7 @@ def write(self, *ignored): 'building topics... ', length=len(pydoc_topic_labels)): if label not in self.env.domaindata['std']['labels']: - self.env.logger.warn('label %r not in documentation' % label) + self.env.logger.warning(f'label {label!r} not in documentation') continue docname, labelid, sectname = self.env.domaindata['std']['labels'][label] doctree = self.env.get_and_resolve_doctree(docname, self) diff --git a/Doc/tools/templates/indexcontent.html b/Doc/tools/templates/indexcontent.html index a96746b69fd41b..1e3ab7cfe02fee 100644 --- a/Doc/tools/templates/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -62,6 +62,7 @@

{{ docstitle|e }}

+ {% endblock %} diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index 18a49271df5f20..9498b2ccc5af92 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -4,16 +4,16 @@ {%- if outdated %}
{% trans %}This document is for an old version of Python that is no longer supported. - You should upgrade, and read the {% endtrans %} - {% trans %} Python documentation for the current stable release{% endtrans %}. + You should upgrade, and read the{% endtrans %} + {% trans %}Python documentation for the current stable release{% endtrans %}.
{%- endif %} {%- if is_deployment_preview %}
{% trans %}This is a deploy preview created from a pull request. - For authoritative documentation, see {% endtrans %} - {% trans %} the current stable release{% endtrans %}. + For authoritative documentation, see{% endtrans %} + {% trans %}the current stable release{% endtrans %}.
{%- endif %} {% endblock %} @@ -26,7 +26,6 @@ {% endblock %} {% block extrahead %} - {% if builder != "htmlhelp" %} {% if pagename == 'whatsnew/changelog' and not embedded %} diff --git a/Doc/tools/touch-clean-files.py b/Doc/tools/touch-clean-files.py deleted file mode 100644 index 2b045bd68a0cf0..00000000000000 --- a/Doc/tools/touch-clean-files.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 -""" -Touch files that must pass Sphinx nit-picky mode -so they are rebuilt and we can catch regressions. -""" -import argparse -import csv -import sys -from pathlib import Path - -wrong_directory_msg = "Must run this script from the repo root" -assert Path("Doc").exists() and Path("Doc").is_dir(), wrong_directory_msg - -# Exclude these whether they're dirty or clean, -# because they trigger a rebuild of dirty files. -EXCLUDE_FILES = { - Path("Doc/whatsnew/changelog.rst"), -} - -# Subdirectories of Doc/ to exclude. -EXCLUDE_SUBDIRS = { - ".env", - ".venv", - "env", - "includes", - "venv", -} - -ALL_RST = { - rst for rst in Path("Doc/").rglob("*.rst") if rst.parts[1] not in EXCLUDE_SUBDIRS -} - - -parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter -) -parser.add_argument("-c", "--clean", help="Comma-separated list of clean files") -args = parser.parse_args() - -if args.clean: - clean_files = next(csv.reader([args.clean])) - CLEAN = { - Path(filename.strip()) - for filename in clean_files - if Path(filename.strip()).is_file() - } -elif args.clean is not None: - print( - "Not touching any files: an empty string `--clean` arg value passed.", - ) - sys.exit(0) -else: - with Path("Doc/tools/.nitignore").open() as ignored_files: - IGNORED = { - Path(filename.strip()) - for filename in ignored_files - if filename.strip() and not filename.startswith("#") - } - CLEAN = ALL_RST - IGNORED - EXCLUDE_FILES - -print("Touching:") -for filename in sorted(CLEAN): - print(filename) - filename.touch() -print(f"Touched {len(CLEAN)} files") diff --git a/Doc/tools/warnings-to-gh-actions.py b/Doc/tools/warnings-to-gh-actions.py deleted file mode 100644 index da33a4ede07abc..00000000000000 --- a/Doc/tools/warnings-to-gh-actions.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 - -""" -Convert Sphinx warning messages to GitHub Actions. - -Converts lines like: - .../Doc/library/cgi.rst:98: WARNING: reference target not found -to: - ::warning file=.../Doc/library/cgi.rst,line=98::reference target not found - -Non-matching lines are echoed unchanged. - -see: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-warning-message -""" - -import re -import sys - -pattern = re.compile(r'(?P[^:]+):(?P\d+): WARNING: (?P.+)') - -for line in sys.stdin: - if match := pattern.fullmatch(line.strip()): - print('::warning file={file},line={line}::{msg}'.format_map(match)) - else: - print(line) diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst index 241a812037469e..588591fcdb726f 100644 --- a/Doc/tutorial/appendix.rst +++ b/Doc/tutorial/appendix.rst @@ -101,8 +101,8 @@ in the script:: The Customization Modules ------------------------- -Python provides two hooks to let you customize it: :mod:`sitecustomize` and -:mod:`usercustomize`. To see how it works, you need first to find the location +Python provides two hooks to let you customize it: :index:`sitecustomize` and +:index:`usercustomize`. To see how it works, you need first to find the location of your user site-packages directory. Start Python and run this code:: >>> import site @@ -113,9 +113,9 @@ Now you can create a file named :file:`usercustomize.py` in that directory and put anything you want in it. It will affect every invocation of Python, unless it is started with the :option:`-s` option to disable the automatic import. -:mod:`sitecustomize` works in the same way, but is typically created by an +:index:`sitecustomize` works in the same way, but is typically created by an administrator of the computer in the global site-packages directory, and is -imported before :mod:`usercustomize`. See the documentation of the :mod:`site` +imported before :index:`usercustomize`. See the documentation of the :mod:`site` module for more details. diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 06445e000c1ef6..7b92e1a51b6e67 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -91,7 +91,7 @@ Attributes may be read-only or writable. In the latter case, assignment to attributes is possible. Module attributes are writable: you can write ``modname.the_answer = 42``. Writable attributes may also be deleted with the :keyword:`del` statement. For example, ``del modname.the_answer`` will remove -the attribute :attr:`the_answer` from the object named by ``modname``. +the attribute :attr:`!the_answer` from the object named by ``modname``. Namespaces are created at different moments and have different lifetimes. The namespace containing the built-in names is created when the Python interpreter @@ -249,7 +249,7 @@ created. This is basically a wrapper around the contents of the namespace created by the class definition; we'll learn more about class objects in the next section. The original local scope (the one in effect just before the class definition was entered) is reinstated, and the class object is bound here to the -class name given in the class definition header (:class:`ClassName` in the +class name given in the class definition header (:class:`!ClassName` in the example). @@ -276,7 +276,7 @@ definition looked like this:: then ``MyClass.i`` and ``MyClass.f`` are valid attribute references, returning an integer and a function object, respectively. Class attributes can also be assigned to, so you can change the value of ``MyClass.i`` by assignment. -:attr:`__doc__` is also a valid attribute, returning the docstring belonging to +:attr:`!__doc__` is also a valid attribute, returning the docstring belonging to the class: ``"A simple example class"``. Class *instantiation* uses function notation. Just pretend that the class @@ -291,20 +291,20 @@ variable ``x``. The instantiation operation ("calling" a class object) creates an empty object. Many classes like to create objects with instances customized to a specific initial state. Therefore a class may define a special method named -:meth:`__init__`, like this:: +:meth:`~object.__init__`, like this:: def __init__(self): self.data = [] -When a class defines an :meth:`__init__` method, class instantiation -automatically invokes :meth:`__init__` for the newly created class instance. So +When a class defines an :meth:`~object.__init__` method, class instantiation +automatically invokes :meth:`!__init__` for the newly created class instance. So in this example, a new, initialized instance can be obtained by:: x = MyClass() -Of course, the :meth:`__init__` method may have arguments for greater +Of course, the :meth:`~object.__init__` method may have arguments for greater flexibility. In that case, arguments given to the class instantiation operator -are passed on to :meth:`__init__`. For example, :: +are passed on to :meth:`!__init__`. For example, :: >>> class Complex: ... def __init__(self, realpart, imagpart): @@ -328,7 +328,7 @@ attribute names: data attributes and methods. *data attributes* correspond to "instance variables" in Smalltalk, and to "data members" in C++. Data attributes need not be declared; like local variables, they spring into existence when they are first assigned to. For example, if -``x`` is the instance of :class:`MyClass` created above, the following piece of +``x`` is the instance of :class:`!MyClass` created above, the following piece of code will print the value ``16``, without leaving a trace:: x.counter = 1 @@ -363,7 +363,7 @@ Usually, a method is called right after it is bound:: x.f() -In the :class:`MyClass` example, this will return the string ``'hello world'``. +In the :class:`!MyClass` example, this will return the string ``'hello world'``. However, it is not necessary to call a method right away: ``x.f`` is a method object, and can be stored away and called at a later time. For example:: @@ -375,7 +375,7 @@ will continue to print ``hello world`` until the end of time. What exactly happens when a method is called? You may have noticed that ``x.f()`` was called without an argument above, even though the function -definition for :meth:`f` specified an argument. What happened to the argument? +definition for :meth:`!f` specified an argument. What happened to the argument? Surely Python raises an exception when a function that requires an argument is called without any --- even if the argument isn't actually used... @@ -532,9 +532,9 @@ variable in the class is also ok. For example:: h = g -Now ``f``, ``g`` and ``h`` are all attributes of class :class:`C` that refer to +Now ``f``, ``g`` and ``h`` are all attributes of class :class:`!C` that refer to function objects, and consequently they are all methods of instances of -:class:`C` --- ``h`` being exactly equivalent to ``g``. Note that this practice +:class:`!C` --- ``h`` being exactly equivalent to ``g``. Note that this practice usually only serves to confuse the reader of a program. Methods may call other methods by using method attributes of the ``self`` @@ -581,7 +581,7 @@ this:: . -The name :class:`BaseClassName` must be defined in a +The name :class:`!BaseClassName` must be defined in a namespace accessible from the scope containing the derived class definition. In place of a base class name, other arbitrary expressions are also allowed. This can be useful, for example, when the base @@ -645,9 +645,9 @@ multiple base classes looks like this:: For most purposes, in the simplest cases, you can think of the search for attributes inherited from a parent class as depth-first, left-to-right, not searching twice in the same class where there is an overlap in the hierarchy. -Thus, if an attribute is not found in :class:`DerivedClassName`, it is searched -for in :class:`Base1`, then (recursively) in the base classes of :class:`Base1`, -and if it was not found there, it was searched for in :class:`Base2`, and so on. +Thus, if an attribute is not found in :class:`!DerivedClassName`, it is searched +for in :class:`!Base1`, then (recursively) in the base classes of :class:`!Base1`, +and if it was not found there, it was searched for in :class:`!Base2`, and so on. In fact, it is slightly more complex than that; the method resolution order changes dynamically to support cooperative calls to :func:`super`. This @@ -760,7 +760,8 @@ is to use :mod:`dataclasses` for this purpose:: A piece of Python code that expects a particular abstract data type can often be passed a class that emulates the methods of that data type instead. For instance, if you have a function that formats some data from a file object, you -can define a class with methods :meth:`read` and :meth:`!readline` that get the +can define a class with methods :meth:`~io.TextIOBase.read` and +:meth:`~io.TextIOBase.readline` that get the data from a string buffer instead, and pass it as an argument. .. (Unfortunately, this technique has its limitations: a class can't define @@ -769,7 +770,7 @@ data from a string buffer instead, and pass it as an argument. not cause the interpreter to read further input from it.) Instance method objects have attributes, too: ``m.__self__`` is the instance -object with the method :meth:`m`, and ``m.__func__`` is the function object +object with the method :meth:`!m`, and ``m.__func__`` is the function object corresponding to the method. @@ -818,9 +819,9 @@ using the :func:`next` built-in function; this example shows how it all works:: StopIteration Having seen the mechanics behind the iterator protocol, it is easy to add -iterator behavior to your classes. Define an :meth:`__iter__` method which +iterator behavior to your classes. Define an :meth:`~container.__iter__` method which returns an object with a :meth:`~iterator.__next__` method. If the class -defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``:: +defines :meth:`!__next__`, then :meth:`!__iter__` can just return ``self``:: class Reverse: """Iterator for looping over a sequence backwards.""" @@ -879,7 +880,7 @@ easy to create:: Anything that can be done with generators can also be done with class-based iterators as described in the previous section. What makes generators so -compact is that the :meth:`__iter__` and :meth:`~generator.__next__` methods +compact is that the :meth:`~iterator.__iter__` and :meth:`~generator.__next__` methods are created automatically. Another key feature is that the local variables and execution state are diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index e140f51f1dda78..aa9caa101da40a 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -4,8 +4,8 @@ More Control Flow Tools *********************** -Besides the :keyword:`while` statement just introduced, Python uses the usual -flow control statements known from other languages, with some twists. +As well as the :keyword:`while` statement just introduced, Python uses a few more +that we will encounter in this chapter. .. _tut-if: @@ -163,14 +163,21 @@ arguments. In chapter :ref:`tut-structures`, we will discuss in more detail abo :keyword:`!break` and :keyword:`!continue` Statements, and :keyword:`!else` Clauses on Loops ============================================================================================ -The :keyword:`break` statement, like in C, breaks out of the innermost enclosing +The :keyword:`break` statement breaks out of the innermost enclosing :keyword:`for` or :keyword:`while` loop. -Loop statements may have an :keyword:`!else` clause; it is executed when the loop -terminates through exhaustion of the iterable (with :keyword:`for`) or when the -condition becomes false (with :keyword:`while`), but not when the loop is -terminated by a :keyword:`break` statement. This is exemplified by the -following loop, which searches for prime numbers:: +A :keyword:`!for` or :keyword:`!while` loop can include an :keyword:`!else` clause. + +In a :keyword:`for` loop, the :keyword:`!else` clause is executed +after the loop reaches its final iteration. + +In a :keyword:`while` loop, it's executed after the loop's condition becomes false. + +In either kind of loop, the :keyword:`!else` clause is **not** executed +if the loop was terminated by a :keyword:`break`. + +This is exemplified in the following :keyword:`!for` loop, +which searches for prime numbers:: >>> for n in range(2, 10): ... for x in range(2, n): @@ -527,7 +534,7 @@ This example, as usual, demonstrates some new Python features: Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using *classes*, see :ref:`tut-classes`) - The method :meth:`append` shown in the example is defined for list objects; it + The method :meth:`!append` shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to ``result = result + [a]``, but more efficient. @@ -1039,7 +1046,7 @@ Function Annotations information about the types used by user-defined functions (see :pep:`3107` and :pep:`484` for more information). -:term:`Annotations ` are stored in the :attr:`__annotations__` +:term:`Annotations ` are stored in the :attr:`!__annotations__` attribute of the function as a dictionary and have no effect on any other part of the function. Parameter annotations are defined by a colon after the parameter name, followed by an expression evaluating to the value of the annotation. Return annotations are diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index c8e89d9b79bddd..87614d082a1d4e 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -143,8 +143,8 @@ Using Lists as Stacks The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved ("last-in, first-out"). To add an -item to the top of the stack, use :meth:`append`. To retrieve an item from the -top of the stack, use :meth:`pop` without an explicit index. For example:: +item to the top of the stack, use :meth:`~list.append`. To retrieve an item from the +top of the stack, use :meth:`~list.pop` without an explicit index. For example:: >>> stack = [3, 4, 5] >>> stack.append(6) @@ -341,7 +341,7 @@ The :keyword:`!del` statement ============================= There is a way to remove an item from a list given its index instead of its -value: the :keyword:`del` statement. This differs from the :meth:`pop` method +value: the :keyword:`del` statement. This differs from the :meth:`~list.pop` method which returns a value. The :keyword:`!del` statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:: @@ -501,8 +501,8 @@ any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can't use lists as keys, since lists can be modified in place using index -assignments, slice assignments, or methods like :meth:`append` and -:meth:`extend`. +assignments, slice assignments, or methods like :meth:`~list.append` and +:meth:`~list.extend`. It is best to think of a dictionary as a set of *key: value* pairs, with the requirement that the keys are unique (within one dictionary). A pair of @@ -567,7 +567,7 @@ Looping Techniques ================== When looping through dictionaries, the key and corresponding value can be -retrieved at the same time using the :meth:`items` method. :: +retrieved at the same time using the :meth:`~dict.items` method. :: >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.items(): diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 6419ff621f1b31..1ec59767e9ce12 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -154,7 +154,7 @@ exception type. The *except clause* may specify a variable after the exception name. The variable is bound to the exception instance which typically has an ``args`` attribute that stores the arguments. For convenience, builtin exception -types define :meth:`__str__` to print all the arguments without explicitly +types define :meth:`~object.__str__` to print all the arguments without explicitly accessing ``.args``. :: >>> try: @@ -174,7 +174,7 @@ accessing ``.args``. :: x = spam y = eggs -The exception's :meth:`__str__` output is printed as the last part ('detail') +The exception's :meth:`~object.__str__` output is printed as the last part ('detail') of the message for unhandled exceptions. :exc:`BaseException` is the common base class of all exceptions. One of its @@ -535,11 +535,20 @@ of a certain type while letting all other exceptions propagate to other clauses and eventually to be reraised. :: >>> def f(): - ... raise ExceptionGroup("group1", - ... [OSError(1), - ... SystemError(2), - ... ExceptionGroup("group2", - ... [OSError(3), RecursionError(4)])]) + ... raise ExceptionGroup( + ... "group1", + ... [ + ... OSError(1), + ... SystemError(2), + ... ExceptionGroup( + ... "group2", + ... [ + ... OSError(3), + ... RecursionError(4) + ... ] + ... ) + ... ] + ... ) ... >>> try: ... f() diff --git a/Doc/tutorial/floatingpoint.rst b/Doc/tutorial/floatingpoint.rst index b88055a41fd1ff..30f3dfb6b238b4 100644 --- a/Doc/tutorial/floatingpoint.rst +++ b/Doc/tutorial/floatingpoint.rst @@ -137,7 +137,7 @@ the :func:`math.isclose` function can be useful for comparing inexact values: True Alternatively, the :func:`round` function can be used to compare rough -approximations:: +approximations: .. doctest:: diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index f5cdd84cbadefe..fe9ca9ccb9c7e0 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -15,7 +15,7 @@ Fancier Output Formatting ========================= So far we've encountered two ways of writing values: *expression statements* and -the :func:`print` function. (A third way is using the :meth:`write` method +the :func:`print` function. (A third way is using the :meth:`~io.TextIOBase.write` method of file objects; the standard output file can be referenced as ``sys.stdout``. See the Library Reference for more information on this.) @@ -456,8 +456,8 @@ to the very file end with ``seek(0, 2)``) and the only valid *offset* values are those returned from the ``f.tell()``, or zero. Any other *offset* value produces undefined behaviour. -File objects have some additional methods, such as :meth:`~file.isatty` and -:meth:`~file.truncate` which are less frequently used; consult the Library +File objects have some additional methods, such as :meth:`~io.IOBase.isatty` and +:meth:`~io.IOBase.truncate` which are less frequently used; consult the Library Reference for a complete guide to file objects. @@ -469,7 +469,7 @@ Saving structured data with :mod:`json` .. index:: pair: module; json Strings can easily be written to and read from a file. Numbers take a bit more -effort, since the :meth:`read` method only returns strings, which will have to +effort, since the :meth:`~io.TextIOBase.read` method only returns strings, which will have to be passed to a function like :func:`int`, which takes a string like ``'123'`` and returns its numeric value 123. When you want to save more complex data types like nested lists and dictionaries, parsing and serializing by hand diff --git a/Doc/tutorial/interactive.rst b/Doc/tutorial/interactive.rst index c0eb1feec4eb4d..0d3896a4832b59 100644 --- a/Doc/tutorial/interactive.rst +++ b/Doc/tutorial/interactive.rst @@ -23,7 +23,7 @@ Python statement names, the current local variables, and the available module names. For dotted expressions such as ``string.a``, it will evaluate the expression up to the final ``'.'`` and then suggest completions from the attributes of the resulting object. Note that this may execute -application-defined code if an object with a :meth:`__getattr__` method +application-defined code if an object with a :meth:`~object.__getattr__` method is part of the expression. The default configuration also saves your history into a file named :file:`.python_history` in your user directory. The history will be available again during the next interactive interpreter diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index ebc2e9187534b4..172611dd0cfb41 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -52,8 +52,8 @@ Numbers The interpreter acts as a simple calculator: you can type an expression at it and it will write the value. Expression syntax is straightforward: the -operators ``+``, ``-``, ``*`` and ``/`` work just like in most other languages -(for example, Pascal or C); parentheses (``()``) can be used for grouping. +operators ``+``, ``-``, ``*`` and ``/`` can be used to perform +arithmetic; parentheses (``()``) can be used for grouping. For example:: >>> 2 + 2 @@ -138,16 +138,25 @@ and uses the ``j`` or ``J`` suffix to indicate the imaginary part .. _tut-strings: -Strings -------- +Text +---- -Besides numbers, Python can also manipulate strings, which can be expressed -in several ways. They can be enclosed in single quotes (``'...'``) or -double quotes (``"..."``) with the same result [#]_. ``\`` can be used -to escape quotes:: +Python can manipulate text (represented by type :class:`str`, so-called +"strings") as well as numbers. This includes characters "``!``", words +"``rabbit``", names "``Paris``", sentences "``Got your back.``", etc. +"``Yay! :)``". They can be enclosed in single quotes (``'...'``) or double +quotes (``"..."``) with the same result [#]_. >>> 'spam eggs' # single quotes 'spam eggs' + >>> "Paris rabbit got your back :)! Yay!" # double quotes + 'Paris rabbit got your back :)! Yay!' + >>> '1975' # digits and numerals enclosed in quotes are also strings + '1975' + +To quote a quote, we need to "escape" it, by preceding it with ``\``. +Alternatively, we can use the other type of quotation marks:: + >>> 'doesn\'t' # use \' to escape the single quote... "doesn't" >>> "doesn't" # ...or use double quotes instead @@ -159,23 +168,14 @@ to escape quotes:: >>> '"Isn\'t," they said.' '"Isn\'t," they said.' -In the interactive interpreter, the output string is enclosed in quotes and -special characters are escaped with backslashes. While this might sometimes -look different from the input (the enclosing quotes could change), the two -strings are equivalent. The string is enclosed in double quotes if -the string contains a single quote and no double quotes, otherwise it is -enclosed in single quotes. The :func:`print` function produces a more -readable output, by omitting the enclosing quotes and by printing escaped -and special characters:: +In the Python shell, the string definition and output string can look +different. The :func:`print` function produces a more readable output, by +omitting the enclosing quotes and by printing escaped and special characters:: - >>> '"Isn\'t," they said.' - '"Isn\'t," they said.' - >>> print('"Isn\'t," they said.') - "Isn't," they said. >>> s = 'First line.\nSecond line.' # \n means newline - >>> s # without print(), \n is included in the output + >>> s # without print(), special characters are included in the string 'First line.\nSecond line.' - >>> print(s) # with print(), \n produces a new line + >>> print(s) # with print(), special characters are interpreted, so \n produces new line First line. Second line. @@ -480,7 +480,7 @@ First Steps Towards Programming Of course, we can use Python for more complicated tasks than adding two and two together. For instance, we can write an initial sub-sequence of the -`Fibonacci series `_ +`Fibonacci series `_ as follows:: >>> # Fibonacci series: diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index 3bd034bcc9703f..bf9e8e0b7b8066 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -183,7 +183,7 @@ The Module Search Path .. index:: triple: module; search; path -When a module named :mod:`spam` is imported, the interpreter first searches for +When a module named :mod:`!spam` is imported, the interpreter first searches for a built-in module with that name. These module names are listed in :data:`sys.builtin_module_names`. If not found, it then searches for a file named :file:`spam.py` in a list of directories given by the variable @@ -389,7 +389,7 @@ Packages ======== Packages are a way of structuring Python's module namespace by using "dotted -module names". For example, the module name :mod:`A.B` designates a submodule +module names". For example, the module name :mod:`!A.B` designates a submodule named ``B`` in a package named ``A``. Just like the use of modules saves the authors of different modules from having to worry about each other's global variable names, the use of dotted module names saves the authors of multi-module @@ -448,7 +448,7 @@ example:: import sound.effects.echo -This loads the submodule :mod:`sound.effects.echo`. It must be referenced with +This loads the submodule :mod:`!sound.effects.echo`. It must be referenced with its full name. :: sound.effects.echo.echofilter(input, output, delay=0.7, atten=4) @@ -457,7 +457,7 @@ An alternative way of importing the submodule is:: from sound.effects import echo -This also loads the submodule :mod:`echo`, and makes it available without its +This also loads the submodule :mod:`!echo`, and makes it available without its package prefix, so it can be used as follows:: echo.echofilter(input, output, delay=0.7, atten=4) @@ -466,8 +466,8 @@ Yet another variation is to import the desired function or variable directly:: from sound.effects.echo import echofilter -Again, this loads the submodule :mod:`echo`, but this makes its function -:func:`echofilter` directly available:: +Again, this loads the submodule :mod:`!echo`, but this makes its function +:func:`!echofilter` directly available:: echofilter(input, output, delay=0.7, atten=4) @@ -510,11 +510,27 @@ code:: __all__ = ["echo", "surround", "reverse"] This would mean that ``from sound.effects import *`` would import the three -named submodules of the :mod:`sound.effects` package. +named submodules of the :mod:`!sound.effects` package. + +Be aware that submodules might become shadowed by locally defined names. For +example, if you added a ``reverse`` function to the +:file:`sound/effects/__init__.py` file, the ``from sound.effects import *`` +would only import the two submodules ``echo`` and ``surround``, but *not* the +``reverse`` submodule, because it is shadowed by the locally defined +``reverse`` function:: + + __all__ = [ + "echo", # refers to the 'echo.py' file + "surround", # refers to the 'surround.py' file + "reverse", # !!! refers to the 'reverse' function now !!! + ] + + def reverse(msg: str): # <-- this name shadows the 'reverse.py' submodule + return msg[::-1] # in the case of a 'from sound.effects import *' If ``__all__`` is not defined, the statement ``from sound.effects import *`` -does *not* import all submodules from the package :mod:`sound.effects` into the -current namespace; it only ensures that the package :mod:`sound.effects` has +does *not* import all submodules from the package :mod:`!sound.effects` into the +current namespace; it only ensures that the package :mod:`!sound.effects` has been imported (possibly running any initialization code in :file:`__init__.py`) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by :file:`__init__.py`. It @@ -525,8 +541,8 @@ previous :keyword:`import` statements. Consider this code:: import sound.effects.surround from sound.effects import * -In this example, the :mod:`echo` and :mod:`surround` modules are imported in the -current namespace because they are defined in the :mod:`sound.effects` package +In this example, the :mod:`!echo` and :mod:`!surround` modules are imported in the +current namespace because they are defined in the :mod:`!sound.effects` package when the ``from...import`` statement is executed. (This also works when ``__all__`` is defined.) @@ -545,15 +561,15 @@ packages. Intra-package References ------------------------ -When packages are structured into subpackages (as with the :mod:`sound` package +When packages are structured into subpackages (as with the :mod:`!sound` package in the example), you can use absolute imports to refer to submodules of siblings -packages. For example, if the module :mod:`sound.filters.vocoder` needs to use -the :mod:`echo` module in the :mod:`sound.effects` package, it can use ``from +packages. For example, if the module :mod:`!sound.filters.vocoder` needs to use +the :mod:`!echo` module in the :mod:`!sound.effects` package, it can use ``from sound.effects import echo``. You can also write relative imports, with the ``from module import name`` form of import statement. These imports use leading dots to indicate the current and -parent packages involved in the relative import. From the :mod:`surround` +parent packages involved in the relative import. From the :mod:`!surround` module for example, you might use:: from . import echo diff --git a/Doc/tutorial/venv.rst b/Doc/tutorial/venv.rst index d1bba098d7d23b..a6dead2eac11f6 100644 --- a/Doc/tutorial/venv.rst +++ b/Doc/tutorial/venv.rst @@ -207,4 +207,6 @@ necessary packages with ``install -r``: ``pip`` has many more options. Consult the :ref:`installing-index` guide for complete documentation for ``pip``. When you've written a package and want to make it available on the Python Package Index, -consult the :ref:`distributing-index` guide. +consult the `Python packaging user guide`_. + +.. _Python Packaging User Guide: https://packaging.python.org/en/latest/tutorials/packaging-projects/ diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 1b470d395d6d58..2767b0cb15451c 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -59,7 +59,7 @@ all consecutive arguments will end up in :data:`sys.argv` -- note that the first element, subscript zero (``sys.argv[0]``), is a string reflecting the program's source. -.. cmdoption:: -c +.. option:: -c Execute the Python code in *command*. *command* can be one or more statements separated by newlines, with significant leading whitespace as in @@ -72,7 +72,7 @@ source. .. audit-event:: cpython.run_command command cmdoption-c -.. cmdoption:: -m +.. option:: -m Search :data:`sys.path` for the named module and execute its contents as the :mod:`__main__` module. @@ -188,35 +188,35 @@ automatically enabled, if available on your platform (see Generic options ~~~~~~~~~~~~~~~ -.. cmdoption:: -? - -h - --help +.. option:: -? + -h + --help Print a short description of all command line options and corresponding environment variables and exit. -.. cmdoption:: --help-env +.. option:: --help-env Print a short description of Python-specific environment variables and exit. .. versionadded:: 3.11 -.. cmdoption:: --help-xoptions +.. option:: --help-xoptions Print a description of implementation-specific :option:`-X` options and exit. .. versionadded:: 3.11 -.. cmdoption:: --help-all +.. option:: --help-all Print complete usage information and exit. .. versionadded:: 3.11 -.. cmdoption:: -V - --version +.. option:: -V + --version Print the Python version number and exit. Example output could be: @@ -240,7 +240,7 @@ Generic options Miscellaneous options ~~~~~~~~~~~~~~~~~~~~~ -.. cmdoption:: -b +.. option:: -b Issue a warning when comparing :class:`bytes` or :class:`bytearray` with :class:`str` or :class:`bytes` with :class:`int`. Issue an error when the @@ -249,13 +249,13 @@ Miscellaneous options .. versionchanged:: 3.5 Affects comparisons of :class:`bytes` with :class:`int`. -.. cmdoption:: -B +.. option:: -B If given, Python won't try to write ``.pyc`` files on the import of source modules. See also :envvar:`PYTHONDONTWRITEBYTECODE`. -.. cmdoption:: --check-hash-based-pycs default|always|never +.. option:: --check-hash-based-pycs default|always|never Control the validation behavior of hash-based ``.pyc`` files. See :ref:`pyc-invalidation`. When set to ``default``, checked and unchecked @@ -269,7 +269,7 @@ Miscellaneous options option. -.. cmdoption:: -d +.. option:: -d Turn on parser debugging output (for expert only). See also the :envvar:`PYTHONDEBUG` environment variable. @@ -278,7 +278,7 @@ Miscellaneous options it's ignored. -.. cmdoption:: -E +.. option:: -E Ignore all :envvar:`PYTHON*` environment variables, e.g. :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. @@ -286,7 +286,7 @@ Miscellaneous options See also the :option:`-P` and :option:`-I` (isolated) options. -.. cmdoption:: -i +.. option:: -i When a script is passed as first argument or the :option:`-c` option is used, enter interactive mode after executing the script or the command, even when @@ -297,7 +297,7 @@ Miscellaneous options raises an exception. See also :envvar:`PYTHONINSPECT`. -.. cmdoption:: -I +.. option:: -I Run Python in isolated mode. This also implies :option:`-E`, :option:`-P` and :option:`-s` options. @@ -310,7 +310,7 @@ Miscellaneous options .. versionadded:: 3.4 -.. cmdoption:: -O +.. option:: -O Remove assert statements and any code conditional on the value of :const:`__debug__`. Augment the filename for compiled @@ -321,7 +321,7 @@ Miscellaneous options Modify ``.pyc`` filenames according to :pep:`488`. -.. cmdoption:: -OO +.. option:: -OO Do :option:`-O` and also discard docstrings. Augment the filename for compiled (:term:`bytecode`) files by adding ``.opt-2`` before the @@ -331,7 +331,7 @@ Miscellaneous options Modify ``.pyc`` filenames according to :pep:`488`. -.. cmdoption:: -P +.. option:: -P Don't prepend a potentially unsafe path to :data:`sys.path`: @@ -348,14 +348,14 @@ Miscellaneous options .. versionadded:: 3.11 -.. cmdoption:: -q +.. option:: -q Don't display the copyright and version messages even in interactive mode. .. versionadded:: 3.2 -.. cmdoption:: -R +.. option:: -R Turn on hash randomization. This option only has an effect if the :envvar:`PYTHONHASHSEED` environment variable is set to ``0``, since hash @@ -381,7 +381,7 @@ Miscellaneous options .. versionadded:: 3.2.3 -.. cmdoption:: -s +.. option:: -s Don't add the :data:`user site-packages directory ` to :data:`sys.path`. @@ -391,7 +391,7 @@ Miscellaneous options :pep:`370` -- Per user site-packages directory -.. cmdoption:: -S +.. option:: -S Disable the import of the module :mod:`site` and the site-dependent manipulations of :data:`sys.path` that it entails. Also disable these @@ -399,7 +399,7 @@ Miscellaneous options :func:`site.main` if you want them to be triggered). -.. cmdoption:: -u +.. option:: -u Force the stdout and stderr streams to be unbuffered. This option has no effect on the stdin stream. @@ -410,7 +410,7 @@ Miscellaneous options The text layer of the stdout and stderr streams now is unbuffered. -.. cmdoption:: -v +.. option:: -v Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded. When given twice @@ -425,7 +425,7 @@ Miscellaneous options .. _using-on-warnings: -.. cmdoption:: -W arg +.. option:: -W arg Warning control. Python's warning machinery by default prints warning messages to :data:`sys.stderr`. @@ -484,13 +484,13 @@ Miscellaneous options details. -.. cmdoption:: -x +.. option:: -x Skip the first line of the source, allowing use of non-Unix forms of ``#!cmd``. This is intended for a DOS specific hack only. -.. cmdoption:: -X +.. option:: -X Reserved for various implementation-specific options. CPython currently defines the following possible values: @@ -546,6 +546,12 @@ Miscellaneous options report Python calls. This option is only available on some platforms and will do nothing if is not supported on the current system. The default value is "off". See also :envvar:`PYTHONPERFSUPPORT` and :ref:`perf_profiling`. + * :samp:`-X cpu_count={n}` overrides :func:`os.cpu_count`, + :func:`os.process_cpu_count`, and :func:`multiprocessing.cpu_count`. + *n* must be greater than or equal to 1. + This option may be useful for users who need to limit CPU resources of a + container system. See also :envvar:`PYTHON_CPU_COUNT`. + If *n* is ``default``, nothing is overridden. It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -593,11 +599,14 @@ Miscellaneous options .. versionadded:: 3.12 The ``-X perf`` option. + .. versionadded:: 3.13 + The ``-X cpu_count`` option. + Options you shouldn't use ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. cmdoption:: -J +.. option:: -J Reserved for use by Jython_. @@ -811,8 +820,8 @@ conflict. Defines the :data:`user base directory `, which is used to compute the path of the :data:`user site-packages directory ` - and :ref:`Distutils installation paths ` for - ``python setup.py install --user``. + and :ref:`installation paths ` for + ``python -m pip install --user``. .. seealso:: @@ -897,11 +906,11 @@ conflict. * ``default``: use the :ref:`default memory allocators `. * ``malloc``: use the :c:func:`malloc` function of the C library - for all domains (:c:data:`PYMEM_DOMAIN_RAW`, :c:data:`PYMEM_DOMAIN_MEM`, - :c:data:`PYMEM_DOMAIN_OBJ`). + for all domains (:c:macro:`PYMEM_DOMAIN_RAW`, :c:macro:`PYMEM_DOMAIN_MEM`, + :c:macro:`PYMEM_DOMAIN_OBJ`). * ``pymalloc``: use the :ref:`pymalloc allocator ` for - :c:data:`PYMEM_DOMAIN_MEM` and :c:data:`PYMEM_DOMAIN_OBJ` domains and use - the :c:func:`malloc` function for the :c:data:`PYMEM_DOMAIN_RAW` domain. + :c:macro:`PYMEM_DOMAIN_MEM` and :c:macro:`PYMEM_DOMAIN_OBJ` domains and use + the :c:func:`malloc` function for the :c:macro:`PYMEM_DOMAIN_RAW` domain. Install :ref:`debug hooks `: @@ -1063,6 +1072,15 @@ conflict. .. versionadded:: 3.12 +.. envvar:: PYTHON_CPU_COUNT + + If this variable is set to a positive integer, it overrides the return + values of :func:`os.cpu_count` and :func:`os.process_cpu_count`. + + See also the :option:`-X cpu_count <-X>` command-line option. + + .. versionadded:: 3.13 + Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index fbe280d6413170..5f9e695d10ad44 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -5,29 +5,42 @@ Configure Python Build Requirements ================== -Features required to build CPython: +Features and minimum versions required to build CPython: * A `C11 `_ compiler. `Optional C11 features `_ are not required. +* On Windows, Microsoft Visual Studio 2017 or later is required. + * Support for `IEEE 754 `_ floating point numbers and `floating point Not-a-Number (NaN) `_. * Support for threads. -* OpenSSL 1.1.1 or newer for the :mod:`ssl` and :mod:`hashlib` modules. +* OpenSSL 1.1.1 is the minimum version and OpenSSL 3.0.9 is the recommended + minimum version for the :mod:`ssl` and :mod:`hashlib` extension modules. -* On Windows, Microsoft Visual Studio 2017 or later is required. +* SQLite 3.15.2 for the :mod:`sqlite3` extension module. + +* Tcl/Tk 8.5.12 for the :mod:`tkinter` module. + +* Autoconf 2.71 and aclocal 1.16.4 are required to regenerate the + :file:`configure` script. + +.. versionchanged:: 3.13: + Autoconf 2.71, aclocal 1.16.4 and SQLite 3.15.2 are now required. .. versionchanged:: 3.11 C11 compiler, IEEE 754 and NaN support are now required. On Windows, Visual Studio 2017 or later is required. + Tcl/Tk version 8.5.12 is now required for the :mod:`tkinter` module. .. versionchanged:: 3.10 OpenSSL 1.1.1 is now required. + Require SQLite 3.7.15. .. versionchanged:: 3.7 Thread support and OpenSSL 1.0.2 are now required. @@ -37,18 +50,45 @@ Features required to build CPython: inline`` functions. .. versionchanged:: 3.5 - On Windows, Visual Studio 2015 or later is required. + On Windows, Visual Studio 2015 or later is now required. + Tcl/Tk version 8.4 is now required. + +.. versionchanged:: 3.1 + Tcl/Tk version 8.3.1 is now required. See also :pep:`7` "Style Guide for C Code" and :pep:`11` "CPython platform support". +Generated files +=============== + +To reduce build dependencies, Python source code contains multiple generated +files. Commands to regenerate all generated files:: + + make regen-all + make regen-stdlib-module-names + make regen-limited-abi + make regen-configure + +The ``Makefile.pre.in`` file documents generated files, their inputs, and tools used +to regenerate them. Search for ``regen-*`` make targets. + +The ``make regen-configure`` command runs `tiran/cpython_autoconf +`_ container for reproducible build; +see container ``entry.sh`` script. The container is optional, the following +command can be run locally, the generated files depend on autoconf and aclocal +versions:: + + autoreconf -ivf -Werror + + .. _configure-options: Configure Options ================= -List all ``./configure`` script options using:: +List all :file:`configure` script options using:: ./configure --help @@ -57,22 +97,22 @@ See also the :file:`Misc/SpecialBuilds.txt` in the Python source distribution. General Options --------------- -.. cmdoption:: --enable-loadable-sqlite-extensions +.. option:: --enable-loadable-sqlite-extensions - Support loadable extensions in the :mod:`_sqlite` extension module (default - is no). + Support loadable extensions in the :mod:`!_sqlite` extension module (default + is no) of the :mod:`sqlite3` module. See the :meth:`sqlite3.Connection.enable_load_extension` method of the :mod:`sqlite3` module. .. versionadded:: 3.6 -.. cmdoption:: --disable-ipv6 +.. option:: --disable-ipv6 Disable IPv6 support (enabled by default if supported), see the :mod:`socket` module. -.. cmdoption:: --enable-big-digits=[15|30] +.. option:: --enable-big-digits=[15|30] Define the size in bits of Python :class:`int` digits: 15 or 30 bits. @@ -82,7 +122,7 @@ General Options See :data:`sys.int_info.bits_per_digit `. -.. cmdoption:: --with-suffix=SUFFIX +.. option:: --with-suffix=SUFFIX Set the Python executable suffix to *SUFFIX*. @@ -95,9 +135,9 @@ General Options The default suffix on WASM platform is one of ``.js``, ``.html`` or ``.wasm``. -.. cmdoption:: --with-tzpath= +.. option:: --with-tzpath= - Select the default time zone search path for :data:`zoneinfo.TZPATH`. + Select the default time zone search path for :const:`zoneinfo.TZPATH`. See the :ref:`Compile-time configuration ` of the :mod:`zoneinfo` module. @@ -107,16 +147,16 @@ General Options .. versionadded:: 3.9 -.. cmdoption:: --without-decimal-contextvar +.. option:: --without-decimal-contextvar Build the ``_decimal`` extension module using a thread-local context rather than a coroutine-local context (default), see the :mod:`decimal` module. - See :data:`decimal.HAVE_CONTEXTVAR` and the :mod:`contextvars` module. + See :const:`decimal.HAVE_CONTEXTVAR` and the :mod:`contextvars` module. .. versionadded:: 3.9 -.. cmdoption:: --with-dbmliborder= +.. option:: --with-dbmliborder= Override order to check db backends for the :mod:`dbm` module @@ -126,7 +166,7 @@ General Options * ``gdbm``; * ``bdb``. -.. cmdoption:: --without-c-locale-coercion +.. option:: --without-c-locale-coercion Disable C locale coercion to a UTF-8 based locale (enabled by default). @@ -134,13 +174,13 @@ General Options See :envvar:`PYTHONCOERCECLOCALE` and the :pep:`538`. -.. cmdoption:: --without-freelists +.. option:: --without-freelists Disable all freelists except the empty tuple singleton. .. versionadded:: 3.11 -.. cmdoption:: --with-platlibdir=DIRNAME +.. option:: --with-platlibdir=DIRNAME Python library directory name (default is ``lib``). @@ -150,7 +190,7 @@ General Options .. versionadded:: 3.9 -.. cmdoption:: --with-wheel-pkg-dir=PATH +.. option:: --with-wheel-pkg-dir=PATH Directory of wheel packages used by the :mod:`ensurepip` module (none by default). @@ -158,11 +198,11 @@ General Options Some Linux distribution packaging policies recommend against bundling dependencies. For example, Fedora installs wheel packages in the ``/usr/share/python-wheels/`` directory and don't install the - :mod:`ensurepip._bundled` package. + :mod:`!ensurepip._bundled` package. .. versionadded:: 3.10 -.. cmdoption:: --with-pkg-config=[check|yes|no] +.. option:: --with-pkg-config=[check|yes|no] Whether configure should use :program:`pkg-config` to detect build dependencies. @@ -173,22 +213,216 @@ General Options .. versionadded:: 3.11 -.. cmdoption:: --enable-pystats +.. option:: --enable-pystats - Turn on internal statistics gathering. + Turn on internal Python performance statistics gathering. + + By default, statistics gathering is off. Use ``python3 -X pystats`` command + or set ``PYTHONSTATS=1`` environment variable to turn on statistics + gathering at Python startup. + + At Python exit, dump statistics if statistics gathering was on and not + cleared. + + Effects: + + * Add :option:`-X pystats <-X>` command line option. + * Add :envvar:`!PYTHONSTATS` environment variable. + * Define the ``Py_STATS`` macro. + * Add functions to the :mod:`sys` module: + + * :func:`!sys._stats_on`: Turns on statistics gathering. + * :func:`!sys._stats_off`: Turns off statistics gathering. + * :func:`!sys._stats_clear`: Clears the statistics. + * :func:`!sys._stats_dump`: Dump statistics to file, and clears the statistics. The statistics will be dumped to a arbitrary (probably unique) file in - ``/tmp/py_stats/``, or ``C:\temp\py_stats\`` on Windows. If that directory - does not exist, results will be printed on stdout. + ``/tmp/py_stats/`` (Unix) or ``C:\temp\py_stats\`` (Windows). If that + directory does not exist, results will be printed on stderr. Use ``Tools/scripts/summarize_stats.py`` to read the stats. + Statistics: + + * Opcode: + + * Specialization: success, failure, hit, deferred, miss, deopt, failures; + * Execution count; + * Pair count. + + * Call: + + * Inlined Python calls; + * PyEval calls; + * Frames pushed; + * Frame object created; + * Eval calls: vector, generator, legacy, function VECTORCALL, build class, + slot, function "ex", API, method. + + * Object: + + * incref and decref; + * interpreter incref and decref; + * allocations: all, 512 bytes, 4 kiB, big; + * free; + * to/from free lists; + * dictionary materialized/dematerialized; + * type cache; + * optimization attemps; + * optimization traces created/executed; + * uops executed. + + * Garbage collector: + + * Garbage collections; + * Objects visited; + * Objects collected. + .. versionadded:: 3.11 +.. option:: --disable-gil + + Enables **experimental** support for running Python without the + :term:`global interpreter lock` (GIL). + + See :pep:`703` "Making the Global Interpreter Lock Optional in CPython". + + .. versionadded:: 3.13 + +.. option:: PKG_CONFIG + + Path to ``pkg-config`` utility. + +.. option:: PKG_CONFIG_LIBDIR +.. option:: PKG_CONFIG_PATH + + ``pkg-config`` options. + + +C compiler options +------------------ + +.. option:: CC + + C compiler command. + +.. option:: CFLAGS + + C compiler flags. + +.. option:: CPP + + C preprocessor command. + +.. option:: CPPFLAGS + + C preprocessor flags, e.g. :samp:`-I{include_dir}`. + + +Linker options +-------------- + +.. option:: LDFLAGS + + Linker flags, e.g. :samp:`-L{library_directory}`. + +.. option:: LIBS + + Libraries to pass to the linker, e.g. :samp:`-l{library}`. + +.. option:: MACHDEP + + Name for machine-dependent library files. + + +Options for third-party dependencies +------------------------------------ + +.. versionadded:: 3.11 + +.. option:: BZIP2_CFLAGS +.. option:: BZIP2_LIBS + + C compiler and linker flags to link Python to ``libbz2``, used by :mod:`bz2` + module, overriding ``pkg-config``. + +.. option:: CURSES_CFLAGS +.. option:: CURSES_LIBS + + C compiler and linker flags for ``libncurses`` or ``libncursesw``, used by + :mod:`curses` module, overriding ``pkg-config``. + +.. option:: GDBM_CFLAGS +.. option:: GDBM_LIBS + + C compiler and linker flags for ``gdbm``. + +.. option:: LIBB2_CFLAGS +.. option:: LIBB2_LIBS + + C compiler and linker flags for ``libb2`` (:ref:`BLAKE2 `), + used by :mod:`hashlib` module, overriding ``pkg-config``. + +.. option:: LIBEDIT_CFLAGS +.. option:: LIBEDIT_LIBS + + C compiler and linker flags for ``libedit``, used by :mod:`readline` module, + overriding ``pkg-config``. + +.. option:: LIBFFI_CFLAGS +.. option:: LIBFFI_LIBS + + C compiler and linker flags for ``libffi``, used by :mod:`ctypes` module, + overriding ``pkg-config``. + +.. option:: LIBLZMA_CFLAGS +.. option:: LIBLZMA_LIBS + + C compiler and linker flags for ``liblzma``, used by :mod:`lzma` module, + overriding ``pkg-config``. + +.. option:: LIBREADLINE_CFLAGS +.. option:: LIBREADLINE_LIBS + + C compiler and linker flags for ``libreadline``, used by :mod:`readline` + module, overriding ``pkg-config``. + +.. option:: LIBSQLITE3_CFLAGS +.. option:: LIBSQLITE3_LIBS + + C compiler and linker flags for ``libsqlite3``, used by :mod:`sqlite3` + module, overriding ``pkg-config``. + +.. option:: LIBUUID_CFLAGS +.. option:: LIBUUID_LIBS + + C compiler and linker flags for ``libuuid``, used by :mod:`uuid` module, + overriding ``pkg-config``. + +.. option:: PANEL_CFLAGS +.. option:: PANEL_LIBS + + C compiler and Linker flags for PANEL, overriding ``pkg-config``. + + C compiler and linker flags for ``libpanel`` or ``libpanelw``, used by + :mod:`curses.panel` module, overriding ``pkg-config``. + +.. option:: TCLTK_CFLAGS +.. option:: TCLTK_LIBS + + C compiler and linker flags for TCLTK, overriding ``pkg-config``. + +.. option:: ZLIB_CFLAGS +.. option:: ZLIB_LIBS + + C compiler and linker flags for ``libzlib``, used by :mod:`gzip` module, + overriding ``pkg-config``. + + WebAssembly Options ------------------- -.. cmdoption:: --with-emscripten-target=[browser|node] +.. option:: --with-emscripten-target=[browser|node] Set build flavor for ``wasm32-emscripten``. @@ -197,7 +431,7 @@ WebAssembly Options .. versionadded:: 3.11 -.. cmdoption:: --enable-wasm-dynamic-linking +.. option:: --enable-wasm-dynamic-linking Turn on dynamic linking support for WASM. @@ -206,7 +440,7 @@ WebAssembly Options .. versionadded:: 3.11 -.. cmdoption:: --enable-wasm-pthreads +.. option:: --enable-wasm-pthreads Turn on pthreads support for WASM. @@ -216,30 +450,30 @@ WebAssembly Options Install Options --------------- -.. cmdoption:: --prefix=PREFIX +.. option:: --prefix=PREFIX Install architecture-independent files in PREFIX. On Unix, it defaults to :file:`/usr/local`. - This value can be retrived at runtime using :data:`sys.prefix`. + This value can be retrieved at runtime using :data:`sys.prefix`. As an example, one can use ``--prefix="$HOME/.local/"`` to install a Python in its home directory. -.. cmdoption:: --exec-prefix=EPREFIX +.. option:: --exec-prefix=EPREFIX Install architecture-dependent files in EPREFIX, defaults to :option:`--prefix`. - This value can be retrived at runtime using :data:`sys.exec_prefix`. + This value can be retrieved at runtime using :data:`sys.exec_prefix`. -.. cmdoption:: --disable-test-modules +.. option:: --disable-test-modules Don't build nor install test modules, like the :mod:`test` package or the - :mod:`_testcapi` extension module (built and installed by default). + :mod:`!_testcapi` extension module (built and installed by default). .. versionadded:: 3.10 -.. cmdoption:: --with-ensurepip=[upgrade|install|no] +.. option:: --with-ensurepip=[upgrade|install|no] Select the :mod:`ensurepip` command run on Python installation: @@ -258,7 +492,7 @@ Configuring Python using ``--enable-optimizations --with-lto`` (PGO + LTO) is recommended for best performance. The experimental ``--enable-bolt`` flag can also be used to improve performance. -.. cmdoption:: --enable-optimizations +.. option:: --enable-optimizations Enable Profile Guided Optimization (PGO) using :envvar:`PROFILE_TASK` (disabled by default). @@ -284,7 +518,10 @@ also be used to improve performance. .. versionadded:: 3.8 -.. cmdoption:: --with-lto=[full|thin|no|yes] + .. versionchanged:: 3.13 + Task failure is no longer ignored silently. + +.. option:: --with-lto=[full|thin|no|yes] Enable Link Time Optimization (LTO) in any build (disabled by default). @@ -299,7 +536,7 @@ also be used to improve performance. .. versionchanged:: 3.12 Use ThinLTO as the default optimization policy on Clang if the compiler accepts the flag. -.. cmdoption:: --enable-bolt +.. option:: --enable-bolt Enable usage of the `BOLT post-link binary optimizer `_ (disabled by @@ -324,19 +561,32 @@ also be used to improve performance. .. versionadded:: 3.12 -.. cmdoption:: --with-computed-gotos +.. option:: BOLT_APPLY_FLAGS + + Arguments to ``llvm-bolt`` when creating a `BOLT optimized binary + `_. + + .. versionadded:: 3.12 + +.. option:: BOLT_INSTRUMENT_FLAGS + + Arguments to ``llvm-bolt`` when instrumenting binaries. + + .. versionadded:: 3.12 + +.. option:: --with-computed-gotos Enable computed gotos in evaluation loop (enabled by default on supported compilers). -.. cmdoption:: --without-pymalloc +.. option:: --without-pymalloc Disable the specialized Python memory allocator :ref:`pymalloc ` (enabled by default). See also :envvar:`PYTHONMALLOC` environment variable. -.. cmdoption:: --without-doc-strings +.. option:: --without-doc-strings Disable static documentation strings to reduce the memory footprint (enabled by default). Documentation strings defined in Python are not affected. @@ -345,11 +595,11 @@ also be used to improve performance. See the ``PyDoc_STRVAR()`` macro. -.. cmdoption:: --enable-profiling +.. option:: --enable-profiling Enable C-level code profiling with ``gprof`` (disabled by default). -.. cmdoption:: --with-strict-overflow +.. option:: --with-strict-overflow Add ``-fstrict-overflow`` to the C compiler flags (by default we add ``-fno-strict-overflow`` instead). @@ -368,7 +618,7 @@ Effects of a debug build: * Display all warnings by default: the list of default warning filters is empty in the :mod:`warnings` module. * Add ``d`` to :data:`sys.abiflags`. -* Add :func:`sys.gettotalrefcount` function. +* Add :func:`!sys.gettotalrefcount` function. * Add :option:`-X showrefcount <-X>` command line option. * Add :option:`-d` command line option and :envvar:`PYTHONDEBUG` environment variable to debug the parser. @@ -390,7 +640,7 @@ Effects of a debug build: * Check that deallocator functions don't change the current exception. * The garbage collector (:func:`gc.collect` function) runs some basic checks on objects consistency. - * The :c:macro:`Py_SAFE_DOWNCAST()` macro checks for integer underflow and + * The :c:macro:`!Py_SAFE_DOWNCAST()` macro checks for integer underflow and overflow when downcasting from wide types to narrow types. See also the :ref:`Python Development Mode ` and the @@ -399,34 +649,39 @@ See also the :ref:`Python Development Mode ` and the .. versionchanged:: 3.8 Release builds and debug builds are now ABI compatible: defining the ``Py_DEBUG`` macro no longer implies the ``Py_TRACE_REFS`` macro (see the - :option:`--with-trace-refs` option), which introduces the only ABI - incompatibility. + :option:`--with-trace-refs` option). Debug options ------------- -.. cmdoption:: --with-pydebug +.. option:: --with-pydebug :ref:`Build Python in debug mode `: define the ``Py_DEBUG`` macro (disabled by default). -.. cmdoption:: --with-trace-refs +.. option:: --with-trace-refs Enable tracing references for debugging purpose (disabled by default). Effects: * Define the ``Py_TRACE_REFS`` macro. - * Add :func:`sys.getobjects` function. + * Add :func:`!sys.getobjects` function. * Add :envvar:`PYTHONDUMPREFS` environment variable. - This build is not ABI compatible with release build (default build) or debug - build (``Py_DEBUG`` and ``Py_REF_DEBUG`` macros). + The :envvar:`PYTHONDUMPREFS` environment variable can be used to dump + objects and reference counts still alive at Python exit. + + :ref:`Statically allocated objects ` are not traced. + + .. versionchanged:: 3.13 + This build is now ABI compatible with release build and :ref:`debug build + `. .. versionadded:: 3.8 -.. cmdoption:: --with-assertions +.. option:: --with-assertions Build with C assertions enabled (default is no): ``assert(...);`` and ``_PyObject_ASSERT(...);``. @@ -439,11 +694,11 @@ Debug options .. versionadded:: 3.6 -.. cmdoption:: --with-valgrind +.. option:: --with-valgrind Enable Valgrind support (default is no). -.. cmdoption:: --with-dtrace +.. option:: --with-dtrace Enable DTrace support (default is no). @@ -452,19 +707,19 @@ Debug options .. versionadded:: 3.6 -.. cmdoption:: --with-address-sanitizer +.. option:: --with-address-sanitizer Enable AddressSanitizer memory error detector, ``asan`` (default is no). .. versionadded:: 3.6 -.. cmdoption:: --with-memory-sanitizer +.. option:: --with-memory-sanitizer Enable MemorySanitizer allocation error detector, ``msan`` (default is no). .. versionadded:: 3.6 -.. cmdoption:: --with-undefined-behavior-sanitizer +.. option:: --with-undefined-behavior-sanitizer Enable UndefinedBehaviorSanitizer undefined behaviour detector, ``ubsan`` (default is no). @@ -475,11 +730,11 @@ Debug options Linker options -------------- -.. cmdoption:: --enable-shared +.. option:: --enable-shared Enable building a shared Python library: ``libpython`` (default is no). -.. cmdoption:: --without-static-libpython +.. option:: --without-static-libpython Do not build ``libpythonMAJOR.MINOR.a`` and do not install ``python.o`` (built and enabled by default). @@ -490,31 +745,32 @@ Linker options Libraries options ----------------- -.. cmdoption:: --with-libs='lib1 ...' +.. option:: --with-libs='lib1 ...' Link against additional libraries (default is no). -.. cmdoption:: --with-system-expat +.. option:: --with-system-expat - Build the :mod:`pyexpat` module using an installed ``expat`` library + Build the :mod:`!pyexpat` module using an installed ``expat`` library (default is no). -.. cmdoption:: --with-system-libmpdec +.. option:: --with-system-libmpdec Build the ``_decimal`` extension module using an installed ``mpdec`` library, see the :mod:`decimal` module (default is no). .. versionadded:: 3.3 -.. cmdoption:: --with-readline=editline +.. option:: --with-readline=readline|editline - Use ``editline`` library for backend of the :mod:`readline` module. + Designate a backend library for the :mod:`readline` module. - Define the ``WITH_EDITLINE`` macro. + * readline: Use readline as the backend. + * editline: Use editline as the backend. .. versionadded:: 3.10 -.. cmdoption:: --without-readline +.. option:: --without-readline Don't build the :mod:`readline` module (built by default). @@ -522,21 +778,21 @@ Libraries options .. versionadded:: 3.10 -.. cmdoption:: --with-libm=STRING +.. option:: --with-libm=STRING Override ``libm`` math library to *STRING* (default is system-dependent). -.. cmdoption:: --with-libc=STRING +.. option:: --with-libc=STRING Override ``libc`` C library to *STRING* (default is system-dependent). -.. cmdoption:: --with-openssl=DIR +.. option:: --with-openssl=DIR Root of the OpenSSL directory. .. versionadded:: 3.7 -.. cmdoption:: --with-openssl-rpath=[no|auto|DIR] +.. option:: --with-openssl-rpath=[no|auto|DIR] Set runtime library directory (rpath) for OpenSSL libraries: @@ -551,7 +807,7 @@ Libraries options Security Options ---------------- -.. cmdoption:: --with-hash-algorithm=[fnv|siphash13|siphash24] +.. option:: --with-hash-algorithm=[fnv|siphash13|siphash24] Select hash algorithm for use in ``Python/pyhash.c``: @@ -564,7 +820,7 @@ Security Options .. versionadded:: 3.11 ``siphash13`` is added and it is the new default. -.. cmdoption:: --with-builtin-hashlib-hashes=md5,sha1,sha256,sha512,sha3,blake2 +.. option:: --with-builtin-hashlib-hashes=md5,sha1,sha256,sha512,sha3,blake2 Built-in hash modules: @@ -577,7 +833,7 @@ Security Options .. versionadded:: 3.9 -.. cmdoption:: --with-ssl-default-suites=[python|openssl|STRING] +.. option:: --with-ssl-default-suites=[python|openssl|STRING] Override the OpenSSL default cipher suites string: @@ -599,19 +855,19 @@ macOS Options See ``Mac/README.rst``. -.. cmdoption:: --enable-universalsdk -.. cmdoption:: --enable-universalsdk=SDKDIR +.. option:: --enable-universalsdk +.. option:: --enable-universalsdk=SDKDIR Create a universal binary build. *SDKDIR* specifies which macOS SDK should be used to perform the build (default is no). -.. cmdoption:: --enable-framework -.. cmdoption:: --enable-framework=INSTALLDIR +.. option:: --enable-framework +.. option:: --enable-framework=INSTALLDIR Create a Python.framework rather than a traditional Unix install. Optional *INSTALLDIR* specifies the installation path (default is no). -.. cmdoption:: --with-universal-archs=ARCH +.. option:: --with-universal-archs=ARCH Specify the kind of universal binary that should be created. This option is only valid when :option:`--enable-universalsdk` is set. @@ -627,7 +883,7 @@ See ``Mac/README.rst``. * ``intel-64``; * ``all``. -.. cmdoption:: --with-framework-name=FRAMEWORK +.. option:: --with-framework-name=FRAMEWORK Specify the name for the python framework on macOS only valid when :option:`--enable-framework` is set (default: ``Python``). @@ -641,21 +897,21 @@ for another CPU architecture or platform. Cross compiling requires a Python interpreter for the build platform. The version of the build Python must match the version of the cross compiled host Python. -.. cmdoption:: --build=BUILD +.. option:: --build=BUILD configure for building on BUILD, usually guessed by :program:`config.guess`. -.. cmdoption:: --host=HOST +.. option:: --host=HOST cross-compile to build programs to run on HOST (target platform) -.. cmdoption:: --with-build-python=path/to/python +.. option:: --with-build-python=path/to/python path to build ``python`` binary for cross compiling .. versionadded:: 3.11 -.. cmdoption:: CONFIG_SITE=file +.. option:: CONFIG_SITE=file An environment variable that points to a file with configure overrides. @@ -666,6 +922,12 @@ the version of the cross compiled host Python. ac_cv_file__dev_ptmx=yes ac_cv_file__dev_ptc=no +.. option:: HOSTRUNNER + + Program to run CPython for the host platform for cross-compilation. + + .. versionadded:: 3.11 + Cross compiling example:: @@ -686,7 +948,6 @@ Main files of the build system * :file:`pyconfig.h` (created by :file:`configure`); * :file:`Modules/Setup`: C extensions built by the Makefile using :file:`Module/makesetup` shell script; -* :file:`setup.py`: C extensions built using the ``setuptools`` package. Main build steps ---------------- @@ -695,8 +956,7 @@ Main build steps * A static ``libpython`` library (``.a``) is created from objects files. * ``python.o`` and the static ``libpython`` library are linked into the final ``python`` program. -* C extensions are built by the Makefile (see :file:`Modules/Setup`) - and ``python setup.py build``. +* C extensions are built by the Makefile (see :file:`Modules/Setup`). Main Makefile targets --------------------- @@ -708,9 +968,18 @@ Main Makefile targets You can use the configure :option:`--enable-optimizations` option to make this the default target of the ``make`` command (``make all`` or just ``make``). -* ``make buildbottest``: Build Python and run the Python test suite, the same - way than buildbots test Python. Set ``TESTTIMEOUT`` variable (in seconds) - to change the test timeout (1200 by default: 20 minutes). + +* ``make test``: Build Python and run the Python test suite with ``--fast-ci`` + option. Variables: + + * ``TESTOPTS``: additional regrtest command line options. + * ``TESTPYTHONOPTS``: additional Python command line options. + * ``TESTTIMEOUT``: timeout in seconds (default: 20 minutes). + +* ``make buildbottest``: Similar to ``make test``, but use ``--slow-ci`` + option and default timeout of 20 minutes, instead of ``--fast-ci`` option + and a default timeout of 10 minutes. + * ``make install``: Build and install Python. * ``make regen-all``: Regenerate (almost) all generated files; ``make regen-stdlib-module-names`` and ``autoconf`` must be run separately @@ -748,18 +1017,15 @@ Example on Linux x86-64:: At the beginning of the files, C extensions are built as built-in modules. Extensions defined after the ``*shared*`` marker are built as dynamic libraries. -The :file:`setup.py` script only builds C extensions as shared libraries using -the :mod:`distutils` module. - -The :c:macro:`PyAPI_FUNC()`, :c:macro:`PyAPI_API()` and -:c:macro:`PyMODINIT_FUNC()` macros of :file:`Include/pyport.h` are defined +The :c:macro:`!PyAPI_FUNC()`, :c:macro:`!PyAPI_DATA()` and +:c:macro:`PyMODINIT_FUNC` macros of :file:`Include/exports.h` are defined differently depending if the ``Py_BUILD_CORE_MODULE`` macro is defined: * Use ``Py_EXPORTED_SYMBOL`` if the ``Py_BUILD_CORE_MODULE`` is defined * Use ``Py_IMPORTED_SYMBOL`` otherwise. If the ``Py_BUILD_CORE_BUILTIN`` macro is used by mistake on a C extension -built as a shared library, its ``PyInit_xxx()`` function is not exported, +built as a shared library, its :samp:`PyInit_{xxx}()` function is not exported, causing an :exc:`ImportError` on import. @@ -780,11 +1046,11 @@ Preprocessor flags .. envvar:: CPPFLAGS - (Objective) C/C++ preprocessor flags, e.g. ``-I`` if you have - headers in a nonstandard directory ````. + (Objective) C/C++ preprocessor flags, e.g. :samp:`-I{include_dir}` if you have + headers in a nonstandard directory *include_dir*. Both :envvar:`CPPFLAGS` and :envvar:`LDFLAGS` need to contain the shell's - value for setup.py to be able to build extension modules using the + value to be able to build extension modules using the directories specified in the environment variables. .. envvar:: BASECPPFLAGS @@ -821,8 +1087,8 @@ Compiler flags .. envvar:: CFLAGS_NODIST :envvar:`CFLAGS_NODIST` is used for building the interpreter and stdlib C - extensions. Use it when a compiler flag should *not* be part of the - distutils :envvar:`CFLAGS` once Python is installed (:issue:`21121`). + extensions. Use it when a compiler flag should *not* be part of + :envvar:`CFLAGS` once Python is installed (:gh:`65320`). In particular, :envvar:`CFLAGS` should not contain: @@ -952,7 +1218,7 @@ Linker flags :envvar:`LDFLAGS_NODIST` is used in the same manner as :envvar:`CFLAGS_NODIST`. Use it when a linker flag should *not* be part of - the distutils :envvar:`LDFLAGS` once Python is installed (:issue:`35257`). + :envvar:`LDFLAGS` once Python is installed (:gh:`65320`). In particular, :envvar:`LDFLAGS` should not contain: @@ -970,11 +1236,11 @@ Linker flags .. envvar:: LDFLAGS - Linker flags, e.g. ``-L`` if you have libraries in a nonstandard - directory ````. + Linker flags, e.g. :samp:`-L{lib_dir}` if you have libraries in a nonstandard + directory *lib_dir*. Both :envvar:`CPPFLAGS` and :envvar:`LDFLAGS` need to contain the shell's - value for setup.py to be able to build extension modules using the + value to be able to build extension modules using the directories specified in the environment variables. .. envvar:: LIBS diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index 65178272862168..eb1413af2cbc3d 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -125,13 +125,9 @@ http://www.hashcollision.org/hkn/python/idle_intro/index.html. Installing Additional Python Packages ===================================== -There are several methods to install additional Python packages: +This section has moved to the `Python Packaging User Guide`_. -* Packages can be installed via the standard Python distutils mode (``python - setup.py install``). - -* Many packages can also be installed via the :program:`setuptools` extension - or :program:`pip` wrapper, see https://pip.pypa.io/. +.. _Python Packaging User Guide: https://packaging.python.org/en/latest/tutorials/installing-packages/ GUI Programming on the Mac diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index 0044eb07f56eec..58838c28e6eb86 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -30,9 +30,9 @@ following links: for Debian users https://en.opensuse.org/Portal:Packaging for OpenSuse users - https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html + https://docs.fedoraproject.org/en-US/package-maintainers/Packaging_Tutorial_GNU_Hello/ for Fedora users - http://www.slackbook.org/html/package-management-making-packages.html + https://slackbook.org/html/package-management-making-packages.html for Slackware users diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index 2fc90126482268..1cf438b198a9af 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -35,37 +35,48 @@ your :ref:`Python installation `:: The command, if run with ``-h``, will show the available options:: - usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear] - [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps] - ENV_DIR [ENV_DIR ...] - - Creates virtual Python environments in one or more target directories. - - positional arguments: - ENV_DIR A directory to create the environment in. - - optional arguments: - -h, --help show this help message and exit - --system-site-packages - Give the virtual environment access to the system - site-packages dir. - --symlinks Try to use symlinks rather than copies, when symlinks - are not the default for the platform. - --copies Try to use copies rather than symlinks, even when - symlinks are the default for the platform. - --clear Delete the contents of the environment directory if it - already exists, before environment creation. - --upgrade Upgrade the environment directory to use this version - of Python, assuming Python has been upgraded in-place. - --without-pip Skips installing or upgrading pip in the virtual - environment (pip is bootstrapped by default) - --prompt PROMPT Provides an alternative prompt prefix for this - environment. - --upgrade-deps Upgrade core dependencies (pip) to the - latest version in PyPI - - Once an environment has been created, you may wish to activate it, e.g. by - sourcing an activate script in its bin directory. + usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear] + [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps] + [--without-scm-ignore-file] + ENV_DIR [ENV_DIR ...] + + Creates virtual Python environments in one or more target directories. + + positional arguments: + ENV_DIR A directory to create the environment in. + + options: + -h, --help show this help message and exit + --system-site-packages + Give the virtual environment access to the system + site-packages dir. + --symlinks Try to use symlinks rather than copies, when + symlinks are not the default for the platform. + --copies Try to use copies rather than symlinks, even when + symlinks are the default for the platform. + --clear Delete the contents of the environment directory if + it already exists, before environment creation. + --upgrade Upgrade the environment directory to use this + version of Python, assuming Python has been upgraded + in-place. + --without-pip Skips installing or upgrading pip in the virtual + environment (pip is bootstrapped by default) + --prompt PROMPT Provides an alternative prompt prefix for this + environment. + --upgrade-deps Upgrade core dependencies (pip) to the latest + version in PyPI + --without-scm-ignore-file + Skips adding the default SCM ignore file to the + environment directory (the default is a .gitignore + file). + + Once an environment has been created, you may wish to activate it, e.g. by + sourcing an activate script in its bin directory. + +.. versionchanged:: 3.13 + + ``--without-scm-ignore-file`` was added along with creating an ignore file + for ``git`` by default. .. versionchanged:: 3.12 diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index ac1ba111e6d9b3..598bf3ca9bcc04 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -867,17 +867,18 @@ For example, if the first line of your script starts with #! /usr/bin/python -The default Python will be located and used. As many Python scripts written -to work on Unix will already have this line, you should find these scripts can -be used by the launcher without modification. If you are writing a new script -on Windows which you hope will be useful on Unix, you should use one of the -shebang lines starting with ``/usr``. +The default Python or an active virtual environment will be located and used. +As many Python scripts written to work on Unix will already have this line, +you should find these scripts can be used by the launcher without modification. +If you are writing a new script on Windows which you hope will be useful on +Unix, you should use one of the shebang lines starting with ``/usr``. Any of the above virtual commands can be suffixed with an explicit version (either just the major version, or the major and minor version). Furthermore the 32-bit version can be requested by adding "-32" after the minor version. I.e. ``/usr/bin/python3.7-32`` will request usage of the -32-bit python 3.7. +32-bit Python 3.7. If a virtual environment is active, the version will be +ignored and the environment will be used. .. versionadded:: 3.7 @@ -889,7 +890,14 @@ minor version. I.e. ``/usr/bin/python3.7-32`` will request usage of the The "-64" suffix is deprecated, and now implies "any architecture that is not provably i386/32-bit". To request a specific environment, use the new - ``-V:`` argument with the complete tag. + :samp:`-V:{TAG}` argument with the complete tag. + +.. versionchanged:: 3.13 + + Virtual commands referencing ``python`` now prefer an active virtual + environment rather than searching :envvar:`PATH`. This handles cases where + the shebang specifies ``/usr/bin/env python3`` but :file:`python3.exe` is + not present in the active environment. The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the @@ -1187,21 +1195,22 @@ Otherwise, your users may experience problems using your application. Note that the first suggestion is the best, as the others may still be susceptible to non-standard paths in the registry and user site-packages. -.. versionchanged:: - 3.6 +.. versionchanged:: 3.6 + + Add ``._pth`` file support and removes ``applocal`` option from + ``pyvenv.cfg``. + +.. versionchanged:: 3.6 - * Adds ``._pth`` file support and removes ``applocal`` option from - ``pyvenv.cfg``. - * Adds ``pythonXX.zip`` as a potential landmark when directly adjacent - to the executable. + Add :file:`python{XX}.zip` as a potential landmark when directly adjacent + to the executable. -.. deprecated:: - 3.6 +.. deprecated:: 3.6 - Modules specified in the registry under ``Modules`` (not ``PythonPath``) - may be imported by :class:`importlib.machinery.WindowsRegistryFinder`. - This finder is enabled on Windows in 3.6.0 and earlier, but may need to - be explicitly added to :attr:`sys.meta_path` in the future. + Modules specified in the registry under ``Modules`` (not ``PythonPath``) + may be imported by :class:`importlib.machinery.WindowsRegistryFinder`. + This finder is enabled on Windows in 3.6.0 and earlier, but may need to + be explicitly added to :data:`sys.meta_path` in the future. Additional modules ================== @@ -1246,8 +1255,8 @@ shipped with PyWin32. It is an embeddable IDE with a built-in debugger. cx_Freeze --------- -`cx_Freeze `_ is a ``distutils`` -extension which wraps Python scripts into executable Windows programs +`cx_Freeze `_ +wraps Python scripts into executable Windows programs (:file:`{*}.exe` files). When you have done this, you can distribute your application without requiring your users to install Python. diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index 489268ced4c864..c2b0ae8c76302a 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -153,9 +153,9 @@ Lundh. A detailed explanation of the interface was written up as :pep:`100`, significant points about the Unicode interfaces. In Python source code, Unicode strings are written as ``u"string"``. Arbitrary -Unicode characters can be written using a new escape sequence, ``\uHHHH``, where +Unicode characters can be written using a new escape sequence, :samp:`\\u{HHHH}`, where *HHHH* is a 4-digit hexadecimal number from 0000 to FFFF. The existing -``\xHHHH`` escape sequence can also be used, and octal escapes can be used for +:samp:`\\x{HH}` escape sequence can also be used, and octal escapes can be used for characters up to U+01FF, which is represented by ``\777``. Unicode strings, just like regular strings, are an immutable sequence type. @@ -664,7 +664,7 @@ extra set of parentheses to pass both values as a tuple: ``L.append( (1,2) )``. The earlier versions of these methods were more forgiving because they used an old function in Python's C interface to parse their arguments; 2.0 modernizes -them to use :func:`PyArg_ParseTuple`, the current argument parsing function, +them to use :c:func:`PyArg_ParseTuple`, the current argument parsing function, which provides more helpful error messages and treats multi-argument calls as errors. If you absolutely must use 2.0 but can't fix your code, you can edit :file:`Objects/listobject.c` and define the preprocessor symbol @@ -766,7 +766,7 @@ file, :file:`Include/pyport.h`. Vladimir Marangozov's long-awaited malloc restructuring was completed, to make it easy to have the Python interpreter use a custom allocator instead of C's -standard :func:`malloc`. For documentation, read the comments in +standard :c:func:`malloc`. For documentation, read the comments in :file:`Include/pymem.h` and :file:`Include/objimpl.h`. For the lengthy discussions during which the interface was hammered out, see the web archives of the 'patches' and 'python-dev' lists at python.org. @@ -794,15 +794,15 @@ are generating Python code would run into this limit. A patch by Charles G. Waldman raises the limit from ``2**16`` to ``2**32``. Three new convenience functions intended for adding constants to a module's -dictionary at module initialization time were added: :func:`PyModule_AddObject`, -:func:`PyModule_AddIntConstant`, and :func:`PyModule_AddStringConstant`. Each +dictionary at module initialization time were added: :c:func:`PyModule_AddObject`, +:c:func:`PyModule_AddIntConstant`, and :c:func:`PyModule_AddStringConstant`. Each of these functions takes a module object, a null-terminated C string containing the name to be added, and a third argument for the value to be assigned to the name. This third argument is, respectively, a Python object, a C long, or a C string. -A wrapper API was added for Unix-style signal handlers. :func:`PyOS_getsig` gets -a signal handler and :func:`PyOS_setsig` will set a new handler. +A wrapper API was added for Unix-style signal handlers. :c:func:`PyOS_getsig` gets +a signal handler and :c:func:`PyOS_setsig` will set a new handler. .. ====================================================================== diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst index 676da702b39693..f0e1ded75a9d27 100644 --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -692,8 +692,8 @@ applied, and 136 bugs fixed; both figures are likely to be underestimates. Some of the more notable changes are: * A specialized object allocator is now optionally available, that should be - faster than the system :func:`malloc` and have less memory overhead. The - allocator uses C's :func:`malloc` function to get large pools of memory, and + faster than the system :c:func:`malloc` and have less memory overhead. The + allocator uses C's :c:func:`!malloc` function to get large pools of memory, and then fulfills smaller memory requests from these pools. It can be enabled by providing the :option:`!--with-pymalloc` option to the :program:`configure` script; see :file:`Objects/obmalloc.c` for the implementation details. @@ -701,13 +701,13 @@ of the more notable changes are: Authors of C extension modules should test their code with the object allocator enabled, because some incorrect code may break, causing core dumps at runtime. There are a bunch of memory allocation functions in Python's C API that have - previously been just aliases for the C library's :func:`malloc` and - :func:`free`, meaning that if you accidentally called mismatched functions, the + previously been just aliases for the C library's :c:func:`malloc` and + :c:func:`free`, meaning that if you accidentally called mismatched functions, the error wouldn't be noticeable. When the object allocator is enabled, these - functions aren't aliases of :func:`malloc` and :func:`free` any more, and + functions aren't aliases of :c:func:`!malloc` and :c:func:`!free` any more, and calling the wrong function to free memory will get you a core dump. For - example, if memory was allocated using :func:`PyMem_New`, it has to be freed - using :func:`PyMem_Del`, not :func:`free`. A few modules included with Python + example, if memory was allocated using :c:macro:`PyMem_New`, it has to be freed + using :c:func:`PyMem_Del`, not :c:func:`!free`. A few modules included with Python fell afoul of this and had to be fixed; doubtless there are more third-party modules that will have the same problem. @@ -717,7 +717,7 @@ of the more notable changes are: complain about its lack of speed, and because it's often been used as a naïve benchmark. The :meth:`readline` method of file objects has therefore been rewritten to be much faster. The exact amount of the speedup will vary from - platform to platform depending on how slow the C library's :func:`getc` was, but + platform to platform depending on how slow the C library's :c:func:`!getc` was, but is around 66%, and potentially much faster on some particular operating systems. Tim Peters did much of the benchmarking and coding for this change, motivated by a discussion in comp.lang.python. @@ -770,7 +770,7 @@ of the more notable changes are: reorganization done by Jeremy Hylton. * C extensions which import other modules have been changed to use - :func:`PyImport_ImportModule`, which means that they will use any import hooks + :c:func:`PyImport_ImportModule`, which means that they will use any import hooks that have been installed. This is also encouraged for third-party extensions that need to import some other module from C code. diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index 82aff0be1ed3b3..d9ead57413cbbf 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -1078,17 +1078,17 @@ code, none of the changes described here will affect you very much. To upgrade an extension module to the new API, perform the following steps: -* Rename :c:func:`Py_TPFLAGS_GC` to :c:func:`PyTPFLAGS_HAVE_GC`. +* Rename :c:macro:`!Py_TPFLAGS_GC` to :c:macro:`Py_TPFLAGS_HAVE_GC`. * Use :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar` to allocate objects, and :c:func:`PyObject_GC_Del` to deallocate them. -* Rename :c:func:`PyObject_GC_Init` to :c:func:`PyObject_GC_Track` and - :c:func:`PyObject_GC_Fini` to :c:func:`PyObject_GC_UnTrack`. +* Rename :c:func:`!PyObject_GC_Init` to :c:func:`PyObject_GC_Track` and + :c:func:`!PyObject_GC_Fini` to :c:func:`PyObject_GC_UnTrack`. -* Remove :c:func:`PyGC_HEAD_SIZE` from object size calculations. +* Remove :c:macro:`!PyGC_HEAD_SIZE` from object size calculations. -* Remove calls to :c:func:`PyObject_AS_GC` and :c:func:`PyObject_FROM_GC`. +* Remove calls to :c:func:`!PyObject_AS_GC` and :c:func:`!PyObject_FROM_GC`. * A new ``et`` format sequence was added to :c:func:`PyArg_ParseTuple`; ``et`` takes both a parameter and an encoding name, and converts the parameter to the @@ -1105,11 +1105,11 @@ code, none of the changes described here will affect you very much. expected, and a set of pointers to :c:expr:`PyObject*` variables that will be filled in with argument values. -* Two new flags :const:`METH_NOARGS` and :const:`METH_O` are available in method +* Two new flags :c:macro:`METH_NOARGS` and :c:macro:`METH_O` are available in method definition tables to simplify implementation of methods with no arguments or a single untyped argument. Calling such methods is more efficient than calling a - corresponding method that uses :const:`METH_VARARGS`. Also, the old - :const:`METH_OLDARGS` style of writing C methods is now officially deprecated. + corresponding method that uses :c:macro:`METH_VARARGS`. Also, the old + :c:macro:`!METH_OLDARGS` style of writing C methods is now officially deprecated. * Two new wrapper functions, :c:func:`PyOS_snprintf` and :c:func:`PyOS_vsnprintf` were added to provide cross-platform implementations for the relatively new @@ -1219,7 +1219,7 @@ Some of the more notable changes are: operator, but these features were rarely used and therefore buggy. The :meth:`tolist` method and the :attr:`start`, :attr:`stop`, and :attr:`step` attributes are also being deprecated. At the C level, the fourth argument to - the :c:func:`PyRange_New` function, ``repeat``, has also been deprecated. + the :c:func:`!PyRange_New` function, ``repeat``, has also been deprecated. * There were a bunch of patches to the dictionary implementation, mostly to fix potential core dumps if a dictionary contains objects that sneakily changed diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index 43bf3fa46a29f1..ec1ca417ee139d 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -1474,7 +1474,7 @@ complete list of changes, or look through the CVS logs for all the details. * On Windows, the :mod:`socket` module now ships with Secure Sockets Layer (SSL) support. -* The value of the C :const:`PYTHON_API_VERSION` macro is now exposed at the +* The value of the C :c:macro:`PYTHON_API_VERSION` macro is now exposed at the Python level as ``sys.api_version``. The current exception can be cleared by calling the new :func:`sys.exc_clear` function. @@ -1847,7 +1847,7 @@ specifically for allocating Python objects. :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc`, and :c:func:`PyObject_Free`. * To allocate and free Python objects, use the "object" family - :c:func:`PyObject_New`, :c:func:`PyObject_NewVar`, and :c:func:`PyObject_Del`. + :c:macro:`PyObject_New`, :c:macro:`PyObject_NewVar`, and :c:func:`PyObject_Del`. Thanks to lots of work by Tim Peters, pymalloc in 2.3 also provides debugging features to catch memory overwrites and doubled frees in both extension modules @@ -1886,10 +1886,10 @@ Changes to Python's build process and to the C API include: (:file:`libpython2.3.so`) by supplying :option:`!--enable-shared` when running Python's :program:`configure` script. (Contributed by Ondrej Palkovsky.) -* The :c:macro:`DL_EXPORT` and :c:macro:`DL_IMPORT` macros are now deprecated. +* The :c:macro:`!DL_EXPORT` and :c:macro:`!DL_IMPORT` macros are now deprecated. Initialization functions for Python extension modules should now be declared using the new macro :c:macro:`PyMODINIT_FUNC`, while the Python core will - generally use the :c:macro:`PyAPI_FUNC` and :c:macro:`PyAPI_DATA` macros. + generally use the :c:macro:`!PyAPI_FUNC` and :c:macro:`!PyAPI_DATA` macros. * The interpreter can be compiled without any docstrings for the built-in functions and modules by supplying :option:`!--without-doc-strings` to the @@ -1897,12 +1897,12 @@ Changes to Python's build process and to the C API include: but will also mean that you can't get help for Python's built-ins. (Contributed by Gustavo Niemeyer.) -* The :c:func:`PyArg_NoArgs` macro is now deprecated, and code that uses it +* The :c:func:`!PyArg_NoArgs` macro is now deprecated, and code that uses it should be changed. For Python 2.2 and later, the method definition table can - specify the :const:`METH_NOARGS` flag, signalling that there are no arguments, + specify the :c:macro:`METH_NOARGS` flag, signalling that there are no arguments, and the argument checking can then be removed. If compatibility with pre-2.2 versions of Python is important, the code could use ``PyArg_ParseTuple(args, - "")`` instead, but this will be slower than using :const:`METH_NOARGS`. + "")`` instead, but this will be slower than using :c:macro:`METH_NOARGS`. * :c:func:`PyArg_ParseTuple` accepts new format characters for various sizes of unsigned integers: ``B`` for :c:expr:`unsigned char`, ``H`` for :c:expr:`unsigned @@ -1918,7 +1918,7 @@ Changes to Python's build process and to the C API include: seconds, according to one measurement). * It's now possible to define class and static methods for a C extension type by - setting either the :const:`METH_CLASS` or :const:`METH_STATIC` flags in a + setting either the :c:macro:`METH_CLASS` or :c:macro:`METH_STATIC` flags in a method's :c:type:`PyMethodDef` structure. * Python now includes a copy of the Expat XML parser's source code, removing any diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index 43c3f01e5af89c..cab321c3e54d18 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -1468,7 +1468,7 @@ Some of the changes to Python's build process and to the C API are: *X* is a NaN. (Contributed by Tim Peters.) * C code can avoid unnecessary locking by using the new - :c:func:`PyEval_ThreadsInitialized` function to tell if any thread operations + :c:func:`!PyEval_ThreadsInitialized` function to tell if any thread operations have been performed. If this function returns false, no lock operations are needed. (Contributed by Nick Coghlan.) @@ -1476,7 +1476,7 @@ Some of the changes to Python's build process and to the C API are: :c:func:`PyArg_ParseTupleAndKeywords` but takes a :c:type:`va_list` instead of a number of arguments. (Contributed by Greg Chapman.) -* A new method flag, :const:`METH_COEXISTS`, allows a function defined in slots +* A new method flag, :c:macro:`METH_COEXIST`, allows a function defined in slots to co-exist with a :c:type:`PyCFunction` having the same name. This can halve the access time for a method such as :meth:`set.__contains__`. (Contributed by Raymond Hettinger.) @@ -1491,7 +1491,7 @@ Some of the changes to Python's build process and to the C API are: though that processor architecture doesn't call that register "the TSC register". (Contributed by Jeremy Hylton.) -* The :c:type:`tracebackobject` type has been renamed to +* The :c:type:`!tracebackobject` type has been renamed to :c:type:`PyTracebackObject`. .. ====================================================================== diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 85ffd170e7d113..2df6d603207a10 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -954,7 +954,7 @@ The return value must be either a Python integer or long integer. The interpreter will check that the type returned is correct, and raises a :exc:`TypeError` if this requirement isn't met. -A corresponding :attr:`nb_index` slot was added to the C-level +A corresponding :c:member:`~PyNumberMethods.nb_index` slot was added to the C-level :c:type:`PyNumberMethods` structure to let C extensions implement this protocol. ``PyNumber_Index(obj)`` can be used in extension code to call the :meth:`__index__` function and retrieve its result. @@ -1448,10 +1448,10 @@ complete list of changes, or look through the SVN logs for all the details. return times that are precise to fractions of a second; not all systems support such precision.) - Constants named :attr:`os.SEEK_SET`, :attr:`os.SEEK_CUR`, and - :attr:`os.SEEK_END` have been added; these are the parameters to the + Constants named :const:`os.SEEK_SET`, :const:`os.SEEK_CUR`, and + :const:`os.SEEK_END` have been added; these are the parameters to the :func:`os.lseek` function. Two new constants for locking are - :attr:`os.O_SHLOCK` and :attr:`os.O_EXLOCK`. + :const:`os.O_SHLOCK` and :const:`os.O_EXLOCK`. Two new functions, :func:`wait3` and :func:`wait4`, were added. They're similar the :func:`waitpid` function which waits for a child process to exit and returns @@ -1602,7 +1602,7 @@ complete list of changes, or look through the SVN logs for all the details. * The :mod:`unicodedata` module has been updated to use version 4.1.0 of the Unicode character database. Version 3.2.0 is required by some specifications, - so it's still available as :attr:`unicodedata.ucd_3_2_0`. + so it's still available as :data:`unicodedata.ucd_3_2_0`. * New module: the :mod:`uuid` module generates universally unique identifiers (UUIDs) according to :rfc:`4122`. The RFC defines several different UUID @@ -2119,9 +2119,9 @@ Changes to Python's build process and to the C API include: the various AST nodes in :file:`Parser/Python.asdl`. A Python script reads this file and generates a set of C structure definitions in :file:`Include/Python-ast.h`. The :c:func:`PyParser_ASTFromString` and - :c:func:`PyParser_ASTFromFile`, defined in :file:`Include/pythonrun.h`, take + :c:func:`!PyParser_ASTFromFile`, defined in :file:`Include/pythonrun.h`, take Python source as input and return the root of an AST representing the contents. - This AST can then be turned into a code object by :c:func:`PyAST_Compile`. For + This AST can then be turned into a code object by :c:func:`!PyAST_Compile`. For more information, read the source code, and then ask questions on python-dev. The AST code was developed under Jeremy Hylton's management, and implemented by @@ -2151,8 +2151,8 @@ Changes to Python's build process and to the C API include: Previously these different families all reduced to the platform's :c:func:`malloc` and :c:func:`free` functions. This meant it didn't matter if - you got things wrong and allocated memory with the :c:func:`PyMem` function but - freed it with the :c:func:`PyObject` function. With 2.5's changes to obmalloc, + you got things wrong and allocated memory with the ``PyMem`` function but + freed it with the ``PyObject`` function. With 2.5's changes to obmalloc, these families now do different things and mismatches will probably result in a segfault. You should carefully test your C extension modules with Python 2.5. @@ -2172,7 +2172,7 @@ Changes to Python's build process and to the C API include: ``Py_LOCAL(type)`` declares the function as returning a value of the specified *type* and uses a fast-calling qualifier. ``Py_LOCAL_INLINE(type)`` does the same thing and also requests the - function be inlined. If :c:func:`PY_LOCAL_AGGRESSIVE` is defined before + function be inlined. If macro :c:macro:`!PY_LOCAL_AGGRESSIVE` is defined before :file:`python.h` is included, a set of more aggressive optimizations are enabled for the module; you should benchmark the results to find out if these optimizations actually make the code faster. (Contributed by Fredrik Lundh at @@ -2181,7 +2181,7 @@ Changes to Python's build process and to the C API include: * ``PyErr_NewException(name, base, dict)`` can now accept a tuple of base classes as its *base* argument. (Contributed by Georg Brandl.) -* The :c:func:`PyErr_Warn` function for issuing warnings is now deprecated in +* The :c:func:`!PyErr_Warn` function for issuing warnings is now deprecated in favour of ``PyErr_WarnEx(category, message, stacklevel)`` which lets you specify the number of stack frames separating this function and the caller. A *stacklevel* of 1 is the function calling :c:func:`PyErr_WarnEx`, 2 is the @@ -2191,7 +2191,7 @@ Changes to Python's build process and to the C API include: compiled with a C++ compiler without errors. (Implemented by Anthony Baxter, Martin von Löwis, Skip Montanaro.) -* The :c:func:`PyRange_New` function was removed. It was never documented, never +* The :c:func:`!PyRange_New` function was removed. It was never documented, never used in the core code, and had dangerously lax error checking. In the unlikely case that your extensions were using it, you can replace it by something like the following:: diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index 69170897ccc50a..198d5152194e93 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -121,11 +121,11 @@ about features that will be removed in Python 3.0. You can run code with this switch to see how much work will be necessary to port code to 3.0. The value of this switch is available to Python code as the boolean variable :data:`sys.py3kwarning`, -and to C extension code as :c:data:`Py_Py3kWarningFlag`. +and to C extension code as :c:data:`!Py_Py3kWarningFlag`. .. seealso:: - The 3xxx series of PEPs, which contains proposals for Python 3.0. + The 3\ *xxx* series of PEPs, which contains proposals for Python 3.0. :pep:`3000` describes the development process for Python 3.0. Start with :pep:`3100` that describes the general goals for Python 3.0, and then explore the higher-numbered PEPS that propose @@ -875,11 +875,11 @@ The signature of the new function is:: The parameters are: - * *args*: positional arguments whose values will be printed out. - * *sep*: the separator, which will be printed between arguments. - * *end*: the ending text, which will be printed after all of the - arguments have been output. - * *file*: the file object to which the output will be sent. +* *args*: positional arguments whose values will be printed out. +* *sep*: the separator, which will be printed between arguments. +* *end*: the ending text, which will be printed after all of the + arguments have been output. +* *file*: the file object to which the output will be sent. .. seealso:: @@ -977,7 +977,7 @@ can be used to include Unicode characters:: print len(s) # 12 Unicode characters At the C level, Python 3.0 will rename the existing 8-bit -string type, called :c:type:`PyStringObject` in Python 2.x, +string type, called :c:type:`!PyStringObject` in Python 2.x, to :c:type:`PyBytesObject`. Python 2.6 uses ``#define`` to support using the names :c:func:`PyBytesObject`, :c:func:`PyBytes_Check`, :c:func:`PyBytes_FromStringAndSize`, @@ -1138,13 +1138,13 @@ indicate that the external caller is done. The *flags* argument to :c:func:`PyObject_GetBuffer` specifies constraints upon the memory returned. Some examples are: - * :const:`PyBUF_WRITABLE` indicates that the memory must be writable. +* :c:macro:`PyBUF_WRITABLE` indicates that the memory must be writable. - * :const:`PyBUF_LOCK` requests a read-only or exclusive lock on the memory. +* :c:macro:`PyBUF_LOCK` requests a read-only or exclusive lock on the memory. - * :const:`PyBUF_C_CONTIGUOUS` and :const:`PyBUF_F_CONTIGUOUS` - requests a C-contiguous (last dimension varies the fastest) or - Fortran-contiguous (first dimension varies the fastest) array layout. +* :c:macro:`PyBUF_C_CONTIGUOUS` and :c:macro:`PyBUF_F_CONTIGUOUS` + requests a C-contiguous (last dimension varies the fastest) or + Fortran-contiguous (first dimension varies the fastest) array layout. Two new argument codes for :c:func:`PyArg_ParseTuple`, ``s*`` and ``z*``, return locked buffer objects for a parameter. @@ -1850,8 +1850,8 @@ changes, or look through the Subversion logs for all the details. special values and floating-point exceptions in a manner consistent with Annex 'G' of the C99 standard. -* A new data type in the :mod:`collections` module: :class:`namedtuple(typename, - fieldnames)` is a factory function that creates subclasses of the standard tuple +* A new data type in the :mod:`collections` module: ``namedtuple(typename, fieldnames)`` + is a factory function that creates subclasses of the standard tuple whose fields are accessible by name as well as index. For example:: >>> var_type = collections.namedtuple('variable', @@ -1873,7 +1873,7 @@ changes, or look through the Subversion logs for all the details. variable(id=1, name='amplitude', type='int', size=4) Several places in the standard library that returned tuples have - been modified to return :class:`namedtuple` instances. For example, + been modified to return :func:`namedtuple` instances. For example, the :meth:`Decimal.as_tuple` method now returns a named tuple with :attr:`sign`, :attr:`digits`, and :attr:`exponent` fields. @@ -2289,7 +2289,7 @@ changes, or look through the Subversion logs for all the details. (Contributed by Raymond Hettinger; :issue:`1861`.) * The :mod:`select` module now has wrapper functions - for the Linux :c:func:`epoll` and BSD :c:func:`kqueue` system calls. + for the Linux :c:func:`!epoll` and BSD :c:func:`!kqueue` system calls. :meth:`modify` method was added to the existing :class:`poll` objects; ``pollobj.modify(fd, eventmask)`` takes a file descriptor or file object and an event mask, modifying the recorded event mask @@ -2328,7 +2328,7 @@ changes, or look through the Subversion logs for all the details. one for reading and one for writing. The writable descriptor will be passed to :func:`set_wakeup_fd`, and the readable descriptor will be added to the list of descriptors monitored by the event loop via - :c:func:`select` or :c:func:`poll`. + :c:func:`!select` or :c:func:`!poll`. On receiving a signal, a byte will be written and the main event loop will be woken up, avoiding the need to poll. @@ -2982,7 +2982,7 @@ Changes to Python's build process and to the C API include: * Python now must be compiled with C89 compilers (after 19 years!). This means that the Python source tree has dropped its - own implementations of :c:func:`memmove` and :c:func:`strerror`, which + own implementations of :c:func:`!memmove` and :c:func:`!strerror`, which are in the C89 standard library. * Python 2.6 can be built with Microsoft Visual Studio 2008 (version @@ -3012,11 +3012,11 @@ Changes to Python's build process and to the C API include: bug occurred if one thread closed a file object while another thread was reading from or writing to the object. In 2.6 file objects have a reference count, manipulated by the - :c:func:`PyFile_IncUseCount` and :c:func:`PyFile_DecUseCount` + :c:func:`!PyFile_IncUseCount` and :c:func:`!PyFile_DecUseCount` functions. File objects can't be closed unless the reference count - is zero. :c:func:`PyFile_IncUseCount` should be called while the GIL + is zero. :c:func:`!PyFile_IncUseCount` should be called while the GIL is still held, before carrying out an I/O operation using the - ``FILE *`` pointer, and :c:func:`PyFile_DecUseCount` should be called + ``FILE *`` pointer, and :c:func:`!PyFile_DecUseCount` should be called immediately after the GIL is re-acquired. (Contributed by Antoine Pitrou and Gregory P. Smith.) @@ -3060,9 +3060,9 @@ Changes to Python's build process and to the C API include: * Some macros were renamed in both 3.0 and 2.6 to make it clearer that they are macros, - not functions. :c:macro:`Py_Size()` became :c:macro:`Py_SIZE()`, - :c:macro:`Py_Type()` became :c:macro:`Py_TYPE()`, and - :c:macro:`Py_Refcnt()` became :c:macro:`Py_REFCNT()`. + not functions. :c:macro:`!Py_Size()` became :c:macro:`Py_SIZE()`, + :c:macro:`!Py_Type()` became :c:macro:`Py_TYPE()`, and + :c:macro:`!Py_Refcnt()` became :c:macro:`Py_REFCNT()`. The mixed-case macros are still available in Python 2.6 for backward compatibility. (:issue:`1629`) diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index f8c7872d7d3f89..f45d45f5b5bf72 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -355,7 +355,7 @@ added as a more powerful replacement for the This means Python now supports three different modules for parsing command-line arguments: :mod:`getopt`, :mod:`optparse`, and :mod:`argparse`. The :mod:`getopt` module closely resembles the C -library's :c:func:`getopt` function, so it remains useful if you're writing a +library's :c:func:`!getopt` function, so it remains useful if you're writing a Python prototype that will eventually be rewritten in C. :mod:`optparse` becomes redundant, but there are no plans to remove it because there are many scripts still using it, and there's no @@ -1556,9 +1556,9 @@ changes, or look through the Subversion logs for all the details. :issue:`8484`.) The version of OpenSSL being used is now available as the module - attributes :data:`ssl.OPENSSL_VERSION` (a string), - :data:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and - :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by Antoine + attributes :const:`ssl.OPENSSL_VERSION` (a string), + :const:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and + :const:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by Antoine Pitrou; :issue:`8321`.) * The :mod:`struct` module will no longer silently ignore overflow @@ -2152,16 +2152,16 @@ Changes to Python's build process and to the C API include: * New function: stemming from the rewrite of string-to-float conversion, a new :c:func:`PyOS_string_to_double` function was added. The old - :c:func:`PyOS_ascii_strtod` and :c:func:`PyOS_ascii_atof` functions + :c:func:`!PyOS_ascii_strtod` and :c:func:`!PyOS_ascii_atof` functions are now deprecated. -* New function: :c:func:`PySys_SetArgvEx` sets the value of +* New function: :c:func:`!PySys_SetArgvEx` sets the value of ``sys.argv`` and can optionally update ``sys.path`` to include the directory containing the script named by ``sys.argv[0]`` depending on the value of an *updatepath* parameter. This function was added to close a security hole for applications - that embed Python. The old function, :c:func:`PySys_SetArgv`, would + that embed Python. The old function, :c:func:`!PySys_SetArgv`, would always update ``sys.path``, and sometimes it would add the current directory. This meant that, if you ran an application embedding Python in a directory controlled by someone else, attackers could @@ -2169,8 +2169,8 @@ Changes to Python's build process and to the C API include: :file:`os.py`) that your application would then import and run. If you maintain a C/C++ application that embeds Python, check - whether you're calling :c:func:`PySys_SetArgv` and carefully consider - whether the application should be using :c:func:`PySys_SetArgvEx` + whether you're calling :c:func:`!PySys_SetArgv` and carefully consider + whether the application should be using :c:func:`!PySys_SetArgvEx` with *updatepath* set to false. Security issue reported as `CVE-2008-5983 @@ -2195,13 +2195,13 @@ Changes to Python's build process and to the C API include: .. XXX these macros don't seem to be described in the c-api docs. -* Removed function: :c:macro:`PyEval_CallObject` is now only available +* Removed function: :c:func:`!PyEval_CallObject` is now only available as a macro. A function version was being kept around to preserve ABI linking compatibility, but that was in 1997; it can certainly be deleted by now. (Removed by Antoine Pitrou; :issue:`8276`.) -* New format codes: the :c:func:`PyFormat_FromString`, - :c:func:`PyFormat_FromStringV`, and :c:func:`PyErr_Format` functions now +* New format codes: the :c:func:`!PyString_FromFormat`, + :c:func:`!PyString_FromFormatV`, and :c:func:`PyErr_Format` functions now accept ``%lld`` and ``%llu`` format codes for displaying C's :c:expr:`long long` types. (Contributed by Mark Dickinson; :issue:`7228`.) @@ -2231,7 +2231,7 @@ Changes to Python's build process and to the C API include: * When using the :c:type:`PyMemberDef` structure to define attributes of a type, Python will no longer let you try to delete or set a - :const:`T_STRING_INPLACE` attribute. + :c:macro:`T_STRING_INPLACE` attribute. .. rev 79644 @@ -2287,10 +2287,10 @@ object, and then get the ``void *`` pointer, which will usually point to an array of pointers to the module's various API functions. There is an existing data type already used for this, -:c:type:`PyCObject`, but it doesn't provide type safety. Evil code +:c:type:`!PyCObject`, but it doesn't provide type safety. Evil code written in pure Python could cause a segmentation fault by taking a -:c:type:`PyCObject` from module A and somehow substituting it for the -:c:type:`PyCObject` in module B. Capsules know their own name, +:c:type:`!PyCObject` from module A and somehow substituting it for the +:c:type:`!PyCObject` in module B. Capsules know their own name, and getting the pointer requires providing the name: .. code-block:: c @@ -2310,10 +2310,10 @@ detect the mismatched name and return false. Refer to :ref:`using-capsules` for more information on using these objects. Python 2.7 now uses capsules internally to provide various -extension-module APIs, but the :c:func:`PyCObject_AsVoidPtr` was +extension-module APIs, but the :c:func:`!PyCObject_AsVoidPtr` was modified to handle capsules, preserving compile-time compatibility -with the :c:type:`CObject` interface. Use of -:c:func:`PyCObject_AsVoidPtr` will signal a +with the :c:type:`!PyCObject` interface. Use of +:c:func:`!PyCObject_AsVoidPtr` will signal a :exc:`PendingDeprecationWarning`, which is silent by default. Implemented in Python 3.1 and backported to 2.7 by Larry Hastings; @@ -2368,7 +2368,7 @@ Port-Specific Changes: Mac OS X installation and a user-installed copy of the same version. (Changed by Ronald Oussoren; :issue:`4865`.) - .. versionchanged:: 2.7.13 + .. versionchanged:: 2.7.13 As of 2.7.13, this change was removed. ``/Library/Python/2.7/site-packages``, the site-packages directory @@ -2540,16 +2540,16 @@ For C extensions: instead of triggering a :exc:`DeprecationWarning` (:issue:`5080`). * Use the new :c:func:`PyOS_string_to_double` function instead of the old - :c:func:`PyOS_ascii_strtod` and :c:func:`PyOS_ascii_atof` functions, + :c:func:`!PyOS_ascii_strtod` and :c:func:`!PyOS_ascii_atof` functions, which are now deprecated. For applications that embed Python: -* The :c:func:`PySys_SetArgvEx` function was added, letting +* The :c:func:`!PySys_SetArgvEx` function was added, letting applications close a security hole when the existing - :c:func:`PySys_SetArgv` function was used. Check whether you're - calling :c:func:`PySys_SetArgv` and carefully consider whether the - application should be using :c:func:`PySys_SetArgvEx` with + :c:func:`!PySys_SetArgv` function was used. Check whether you're + calling :c:func:`!PySys_SetArgv` and carefully consider whether the + application should be using :c:func:`!PySys_SetArgvEx` with *updatepath* set to false. .. ====================================================================== diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index b8cd7c48b359b2..b0c2529e780213 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -789,7 +789,7 @@ Operators And Special Methods :attr:`__doc__`, :attr:`__globals__`, :attr:`~definition.__name__`, respectively. -* :meth:`__nonzero__` is now :meth:`__bool__`. +* :meth:`!__nonzero__` is now :meth:`~object.__bool__`. Builtins -------- @@ -865,8 +865,8 @@ to the C API. * No more C API support for restricted execution. -* :c:func:`PyNumber_Coerce`, :c:func:`PyNumber_CoerceEx`, - :c:func:`PyMember_Get`, and :c:func:`PyMember_Set` C APIs are removed. +* :c:func:`!PyNumber_Coerce`, :c:func:`!PyNumber_CoerceEx`, + :c:func:`!PyMember_Get`, and :c:func:`!PyMember_Set` C APIs are removed. * New C API :c:func:`PyImport_ImportModuleNoBlock`, works like :c:func:`PyImport_ImportModule` but won't block on the import lock @@ -875,7 +875,7 @@ to the C API. * Renamed the boolean conversion C-level slot and method: ``nb_nonzero`` is now ``nb_bool``. -* Removed :c:macro:`METH_OLDARGS` and :c:macro:`WITH_CYCLE_GC` from the C API. +* Removed :c:macro:`!METH_OLDARGS` and :c:macro:`!WITH_CYCLE_GC` from the C API. .. ====================================================================== diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index 054762de7e743a..e237179f4b1829 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -370,7 +370,7 @@ New, Improved, and Deprecated Modules * The :mod:`io` module has three new constants for the :meth:`seek` method :data:`SEEK_SET`, :data:`SEEK_CUR`, and :data:`SEEK_END`. -* The :attr:`sys.version_info` tuple is now a named tuple:: +* The :data:`sys.version_info` tuple is now a named tuple:: >>> sys.version_info sys.version_info(major=3, minor=1, micro=0, releaselevel='alpha', serial=2) @@ -486,7 +486,7 @@ Changes to Python's build process and to the C API include: Apart from the performance improvements this change should be invisible to end users, with one exception: for testing and debugging purposes there's a - new :attr:`sys.int_info` that provides information about the + new :data:`sys.int_info` that provides information about the internal format, giving the number of bits per digit and the size in bytes of the C type used to store each digit:: @@ -501,16 +501,16 @@ Changes to Python's build process and to the C API include: (Contributed by Mark Dickinson and Lisandro Dalcrin; :issue:`5175`.) -* Deprecated :c:func:`PyNumber_Int`. Use :c:func:`PyNumber_Long` instead. +* Deprecated :c:func:`!PyNumber_Int`. Use :c:func:`PyNumber_Long` instead. (Contributed by Mark Dickinson; :issue:`4910`.) * Added a new :c:func:`PyOS_string_to_double` function to replace the - deprecated functions :c:func:`PyOS_ascii_strtod` and :c:func:`PyOS_ascii_atof`. + deprecated functions :c:func:`!PyOS_ascii_strtod` and :c:func:`!PyOS_ascii_atof`. (Contributed by Mark Dickinson; :issue:`5914`.) -* Added :c:type:`PyCapsule` as a replacement for the :c:type:`PyCObject` API. +* Added :c:type:`PyCapsule` as a replacement for the :c:type:`!PyCObject` API. The principal difference is that the new type has a well defined interface for passing typing safety information and a less complicated signature for calling a destructor. The old type had a problematic API and is now diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index ab030db5b3ffaa..df821d68eb8d9f 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -221,116 +221,116 @@ have been incorporated. Some of the most notable ones are as follows: * Missing ``:`` before blocks: - .. code-block:: python + .. code-block:: python - >>> if rocket.position > event_horizon - File "", line 1 - if rocket.position > event_horizon - ^ - SyntaxError: expected ':' + >>> if rocket.position > event_horizon + File "", line 1 + if rocket.position > event_horizon + ^ + SyntaxError: expected ':' - (Contributed by Pablo Galindo in :issue:`42997`.) + (Contributed by Pablo Galindo in :issue:`42997`.) * Unparenthesised tuples in comprehensions targets: - .. code-block:: python + .. code-block:: python - >>> {x,y for x,y in zip('abcd', '1234')} - File "", line 1 - {x,y for x,y in zip('abcd', '1234')} - ^ - SyntaxError: did you forget parentheses around the comprehension target? + >>> {x,y for x,y in zip('abcd', '1234')} + File "", line 1 + {x,y for x,y in zip('abcd', '1234')} + ^ + SyntaxError: did you forget parentheses around the comprehension target? - (Contributed by Pablo Galindo in :issue:`43017`.) + (Contributed by Pablo Galindo in :issue:`43017`.) * Missing commas in collection literals and between expressions: - .. code-block:: python + .. code-block:: python - >>> items = { - ... x: 1, - ... y: 2 - ... z: 3, - File "", line 3 - y: 2 - ^ - SyntaxError: invalid syntax. Perhaps you forgot a comma? + >>> items = { + ... x: 1, + ... y: 2 + ... z: 3, + File "", line 3 + y: 2 + ^ + SyntaxError: invalid syntax. Perhaps you forgot a comma? - (Contributed by Pablo Galindo in :issue:`43822`.) + (Contributed by Pablo Galindo in :issue:`43822`.) * Multiple Exception types without parentheses: - .. code-block:: python + .. code-block:: python - >>> try: - ... build_dyson_sphere() - ... except NotEnoughScienceError, NotEnoughResourcesError: - File "", line 3 - except NotEnoughScienceError, NotEnoughResourcesError: - ^ - SyntaxError: multiple exception types must be parenthesized + >>> try: + ... build_dyson_sphere() + ... except NotEnoughScienceError, NotEnoughResourcesError: + File "", line 3 + except NotEnoughScienceError, NotEnoughResourcesError: + ^ + SyntaxError: multiple exception types must be parenthesized - (Contributed by Pablo Galindo in :issue:`43149`.) + (Contributed by Pablo Galindo in :issue:`43149`.) * Missing ``:`` and values in dictionary literals: - .. code-block:: python + .. code-block:: python - >>> values = { - ... x: 1, - ... y: 2, - ... z: - ... } - File "", line 4 - z: - ^ - SyntaxError: expression expected after dictionary key and ':' + >>> values = { + ... x: 1, + ... y: 2, + ... z: + ... } + File "", line 4 + z: + ^ + SyntaxError: expression expected after dictionary key and ':' - >>> values = {x:1, y:2, z w:3} - File "", line 1 - values = {x:1, y:2, z w:3} - ^ - SyntaxError: ':' expected after dictionary key + >>> values = {x:1, y:2, z w:3} + File "", line 1 + values = {x:1, y:2, z w:3} + ^ + SyntaxError: ':' expected after dictionary key - (Contributed by Pablo Galindo in :issue:`43823`.) + (Contributed by Pablo Galindo in :issue:`43823`.) * ``try`` blocks without ``except`` or ``finally`` blocks: - .. code-block:: python + .. code-block:: python - >>> try: - ... x = 2 - ... something = 3 - File "", line 3 - something = 3 - ^^^^^^^^^ - SyntaxError: expected 'except' or 'finally' block + >>> try: + ... x = 2 + ... something = 3 + File "", line 3 + something = 3 + ^^^^^^^^^ + SyntaxError: expected 'except' or 'finally' block - (Contributed by Pablo Galindo in :issue:`44305`.) + (Contributed by Pablo Galindo in :issue:`44305`.) * Usage of ``=`` instead of ``==`` in comparisons: - .. code-block:: python + .. code-block:: python - >>> if rocket.position = event_horizon: - File "", line 1 - if rocket.position = event_horizon: - ^ - SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='? + >>> if rocket.position = event_horizon: + File "", line 1 + if rocket.position = event_horizon: + ^ + SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='? - (Contributed by Pablo Galindo in :issue:`43797`.) + (Contributed by Pablo Galindo in :issue:`43797`.) * Usage of ``*`` in f-strings: - .. code-block:: python + .. code-block:: python - >>> f"Black holes {*all_black_holes} and revelations" - File "", line 1 - (*all_black_holes) - ^ - SyntaxError: f-string: cannot use starred expression here + >>> f"Black holes {*all_black_holes} and revelations" + File "", line 1 + (*all_black_holes) + ^ + SyntaxError: f-string: cannot use starred expression here - (Contributed by Pablo Galindo in :issue:`41064`.) + (Contributed by Pablo Galindo in :issue:`41064`.) IndentationErrors ~~~~~~~~~~~~~~~~~ @@ -365,10 +365,10 @@ raised from: (Contributed by Pablo Galindo in :issue:`38530`.) - .. warning:: - Notice this won't work if :c:func:`PyErr_Display` is not called to display the error - which can happen if some other custom error display function is used. This is a common - scenario in some REPLs like IPython. +.. warning:: + Notice this won't work if :c:func:`PyErr_Display` is not called to display the error + which can happen if some other custom error display function is used. This is a common + scenario in some REPLs like IPython. NameErrors ~~~~~~~~~~ @@ -387,10 +387,10 @@ was raised from: (Contributed by Pablo Galindo in :issue:`38530`.) - .. warning:: - Notice this won't work if :c:func:`PyErr_Display` is not called to display the error, - which can happen if some other custom error display function is used. This is a common - scenario in some REPLs like IPython. +.. warning:: + Notice this won't work if :c:func:`PyErr_Display` is not called to display the error, + which can happen if some other custom error display function is used. This is a common + scenario in some REPLs like IPython. PEP 626: Precise line numbers for debugging and other tools @@ -433,16 +433,16 @@ A match statement takes an expression and compares its value to successive patterns given as one or more case blocks. Specifically, pattern matching operates by: - 1. using data with type and shape (the ``subject``) - 2. evaluating the ``subject`` in the ``match`` statement - 3. comparing the subject with each pattern in a ``case`` statement - from top to bottom until a match is confirmed. - 4. executing the action associated with the pattern of the confirmed - match - 5. If an exact match is not confirmed, the last case, a wildcard ``_``, - if provided, will be used as the matching case. If an exact match is - not confirmed and a wildcard case does not exist, the entire match - block is a no-op. +1. using data with type and shape (the ``subject``) +2. evaluating the ``subject`` in the ``match`` statement +3. comparing the subject with each pattern in a ``case`` statement + from top to bottom until a match is confirmed. +4. executing the action associated with the pattern of the confirmed + match +5. If an exact match is not confirmed, the last case, a wildcard ``_``, + if provided, will be used as the matching case. If an exact match is + not confirmed and a wildcard case does not exist, the entire match + block is a no-op. Declarative approach ~~~~~~~~~~~~~~~~~~~~ @@ -878,7 +878,7 @@ Other Language Changes (Contributed by Raymond Hettinger in :issue:`43475`.) * A :exc:`SyntaxError` (instead of a :exc:`NameError`) will be raised when deleting - the :const:`__debug__` constant. (Contributed by Dong-hee Na in :issue:`45000`.) + the :const:`__debug__` constant. (Contributed by Donghee Na in :issue:`45000`.) * :exc:`SyntaxError` exceptions now have ``end_lineno`` and ``end_offset`` attributes. They will be ``None`` if not determined. @@ -887,7 +887,7 @@ Other Language Changes New Modules =========== -* None yet. +* None. Improved Modules @@ -1253,9 +1253,9 @@ descriptors without copying between kernel address space and user address space, where one of the file descriptors must refer to a pipe. (Contributed by Pablo Galindo in :issue:`41625`.) -Add :data:`~os.O_EVTONLY`, :data:`~os.O_FSYNC`, :data:`~os.O_SYMLINK` -and :data:`~os.O_NOFOLLOW_ANY` for macOS. -(Contributed by Dong-hee Na in :issue:`43106`.) +Add :const:`~os.O_EVTONLY`, :const:`~os.O_FSYNC`, :const:`~os.O_SYMLINK` +and :const:`~os.O_NOFOLLOW_ANY` for macOS. +(Contributed by Donghee Na in :issue:`43106`.) os.path ------- @@ -1319,7 +1319,7 @@ objects in the tree returned by :func:`pyclbr.readline` and shelve ------ -The :mod:`shelve` module now uses :data:`pickle.DEFAULT_PROTOCOL` by default +The :mod:`shelve` module now uses :const:`pickle.DEFAULT_PROTOCOL` by default instead of :mod:`pickle` protocol ``3`` when creating shelves. (Contributed by Zackery Spytz in :issue:`34204`.) @@ -1356,7 +1356,7 @@ The ssl module requires OpenSSL 1.1.1 or newer. (Contributed by Christian Heimes in :pep:`644` and :issue:`43669`.) The ssl module has preliminary support for OpenSSL 3.0.0 and new option -:data:`~ssl.OP_IGNORE_UNEXPECTED_EOF`. +:const:`~ssl.OP_IGNORE_UNEXPECTED_EOF`. (Contributed by Christian Heimes in :issue:`38820`, :issue:`43794`, :issue:`43788`, :issue:`43791`, :issue:`43799`, :issue:`43920`, :issue:`43789`, and :issue:`43811`.) @@ -1387,7 +1387,7 @@ Add a *timeout* parameter to the :func:`ssl.get_server_certificate` function. The ssl module uses heap-types and multi-phase initialization. (Contributed by Christian Heimes in :issue:`42333`.) -A new verify flag :data:`~ssl.VERIFY_X509_PARTIAL_CHAIN` has been added. +A new verify flag :const:`~ssl.VERIFY_X509_PARTIAL_CHAIN` has been added. (Contributed by l0x in :issue:`40849`.) sqlite3 @@ -1413,7 +1413,7 @@ _thread ------- :func:`_thread.interrupt_main` now takes an optional signal number to -simulate (the default is still :data:`signal.SIGINT`). +simulate (the default is still :const:`signal.SIGINT`). (Contributed by Antoine Pitrou in :issue:`43356`.) threading @@ -1582,7 +1582,7 @@ Optimizations * The following built-in functions now support the faster :pep:`590` vectorcall calling convention: :func:`map`, :func:`filter`, :func:`reversed`, :func:`bool` and :func:`float`. - (Contributed by Dong-hee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`.) + (Contributed by Donghee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`.) * :class:`BZ2File` performance is improved by removing internal ``RLock``. This makes :class:`BZ2File` thread unsafe in the face of multiple simultaneous @@ -1757,8 +1757,8 @@ Deprecated * :data:`~ssl.PROTOCOL_SSLv2`, :data:`~ssl.PROTOCOL_SSLv3`, :data:`~ssl.PROTOCOL_SSLv23`, :data:`~ssl.PROTOCOL_TLSv1`, :data:`~ssl.PROTOCOL_TLSv1_1`, :data:`~ssl.PROTOCOL_TLSv1_2`, and - :data:`~ssl.PROTOCOL_TLS` are deprecated in favor of - :data:`~ssl.PROTOCOL_TLS_CLIENT` and :data:`~ssl.PROTOCOL_TLS_SERVER` + :const:`~ssl.PROTOCOL_TLS` are deprecated in favor of + :const:`~ssl.PROTOCOL_TLS_CLIENT` and :const:`~ssl.PROTOCOL_TLS_SERVER` * :func:`~ssl.wrap_socket` is replaced by :meth:`ssl.SSLContext.wrap_socket` @@ -1817,10 +1817,10 @@ Removed scheduled to be removed in Python 3.6, but such removals were delayed until after Python 2.7 EOL. Existing users should copy whatever classes they use into their code. - (Contributed by Dong-hee Na and Terry J. Reedy in :issue:`42299`.) + (Contributed by Donghee Na and Terry J. Reedy in :issue:`42299`.) -* Removed the :c:func:`PyModule_GetWarningsModule` function that was useless - now due to the _warnings module was converted to a builtin module in 2.6. +* Removed the :c:func:`!PyModule_GetWarningsModule` function that was useless + now due to the :mod:`!_warnings` module was converted to a builtin module in 2.6. (Contributed by Hai Shi in :issue:`42599`.) * Remove deprecated aliases to :ref:`collections-abstract-base-classes` from @@ -2124,11 +2124,11 @@ New Features These functions allow to activate, deactivate and query the state of the garbage collector from C code without having to import the :mod:`gc` module. -* Add a new :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow +* Add a new :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow creating type instances. (Contributed by Victor Stinner in :issue:`43916`.) -* Add a new :c:data:`Py_TPFLAGS_IMMUTABLETYPE` type flag for creating immutable +* Add a new :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` type flag for creating immutable type objects: type attributes cannot be set nor deleted. (Contributed by Victor Stinner and Erlend E. Aasland in :issue:`43908`.) @@ -2187,9 +2187,9 @@ Porting to Python 3.10 been included directly, consider including ``Python.h`` instead. (Contributed by Nicholas Sim in :issue:`35134`.) -* Use the :c:data:`Py_TPFLAGS_IMMUTABLETYPE` type flag to create immutable type - objects. Do not rely on :c:data:`Py_TPFLAGS_HEAPTYPE` to decide if a type - object is mutable or not; check if :c:data:`Py_TPFLAGS_IMMUTABLETYPE` is set +* Use the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` type flag to create immutable type + objects. Do not rely on :c:macro:`Py_TPFLAGS_HEAPTYPE` to decide if a type + object is mutable or not; check if :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` is set instead. (Contributed by Victor Stinner and Erlend E. Aasland in :issue:`43908`.) @@ -2211,16 +2211,16 @@ Removed * Removed ``Py_UNICODE_str*`` functions manipulating ``Py_UNICODE*`` strings. (Contributed by Inada Naoki in :issue:`41123`.) - * ``Py_UNICODE_strlen``: use :c:func:`PyUnicode_GetLength` or - :c:macro:`PyUnicode_GET_LENGTH` - * ``Py_UNICODE_strcat``: use :c:func:`PyUnicode_CopyCharacters` or - :c:func:`PyUnicode_FromFormat` - * ``Py_UNICODE_strcpy``, ``Py_UNICODE_strncpy``: use - :c:func:`PyUnicode_CopyCharacters` or :c:func:`PyUnicode_Substring` - * ``Py_UNICODE_strcmp``: use :c:func:`PyUnicode_Compare` - * ``Py_UNICODE_strncmp``: use :c:func:`PyUnicode_Tailmatch` - * ``Py_UNICODE_strchr``, ``Py_UNICODE_strrchr``: use - :c:func:`PyUnicode_FindChar` + * ``Py_UNICODE_strlen``: use :c:func:`PyUnicode_GetLength` or + :c:macro:`PyUnicode_GET_LENGTH` + * ``Py_UNICODE_strcat``: use :c:func:`PyUnicode_CopyCharacters` or + :c:func:`PyUnicode_FromFormat` + * ``Py_UNICODE_strcpy``, ``Py_UNICODE_strncpy``: use + :c:func:`PyUnicode_CopyCharacters` or :c:func:`PyUnicode_Substring` + * ``Py_UNICODE_strcmp``: use :c:func:`PyUnicode_Compare` + * ``Py_UNICODE_strncmp``: use :c:func:`PyUnicode_Tailmatch` + * ``Py_UNICODE_strchr``, ``Py_UNICODE_strrchr``: use + :c:func:`PyUnicode_FindChar` * Removed ``PyUnicode_GetMax()``. Please migrate to new (:pep:`393`) APIs. (Contributed by Inada Naoki in :issue:`41103`.) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 45194130c993a0..257025da91a7ed 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -45,7 +45,7 @@ when researching a change. This article explains the new features in Python 3.11, compared to 3.10. - +Python 3.11 was released on October 24, 2022. For full details, see the :ref:`changelog `. @@ -218,7 +218,7 @@ Windows ``py.exe`` launcher improvements The copy of the :ref:`launcher` included with Python 3.11 has been significantly updated. It now supports company/tag syntax as defined in :pep:`514` using the -``-V:/`` argument instead of the limited ``-.``. +:samp:`-V:{}/{}` argument instead of the limited :samp:`-{}.{}`. This allows launching distributions other than ``PythonCore``, the one hosted on `python.org `_. @@ -227,8 +227,8 @@ installs will be searched. For example, ``-V:OtherPython/`` will select the "best" tag registered for ``OtherPython``, while ``-V:3.11`` or ``-V:/3.11`` will select the "best" distribution with tag ``3.11``. -When using the legacy ``-``, ``-.``, -``--`` or ``-.-`` arguments, +When using the legacy :samp:`-{}`, :samp:`-{}.{}`, +:samp:`-{}-{}` or :samp:`-{}.{}-{}` arguments, all existing behaviour should be preserved from past versions, and only releases from ``PythonCore`` will be selected. However, the ``-64`` suffix now implies "not 32-bit" (not necessarily x86-64), @@ -459,6 +459,10 @@ Other Language Changes :class:`collections.OrderedDict`, :class:`collections.deque`, :class:`weakref.WeakSet`, and :class:`datetime.tzinfo` now copies and pickles instance attributes implemented as :term:`slots <__slots__>`. + This change has an unintended side effect: It trips up a small minority + of existing Python projects not expecting :meth:`object.__getstate__` to + exist. See the later comments on :gh:`70766` for discussions of what + workarounds such code may need. (Contributed by Serhiy Storchaka in :issue:`26579`.) .. _whatsnew311-pythonsafepath: @@ -495,7 +499,7 @@ Other CPython Implementation Changes * The special methods :meth:`~object.__complex__` for :class:`complex` and :meth:`~object.__bytes__` for :class:`bytes` are implemented to support the :class:`typing.SupportsComplex` and :class:`typing.SupportsBytes` protocols. - (Contributed by Mark Dickinson and Dong-hee Na in :issue:`24234`.) + (Contributed by Mark Dickinson and Donghee Na in :issue:`24234`.) * ``siphash13`` is added as a new internal hashing algorithm. It has similar security properties as ``siphash24``, @@ -640,7 +644,7 @@ dataclasses datetime -------- -* Add :attr:`datetime.UTC`, a convenience alias for +* Add :const:`datetime.UTC`, a convenience alias for :attr:`datetime.timezone.utc`. (Contributed by Kabir Kwatra in :gh:`91973`.) * :meth:`datetime.date.fromisoformat`, :meth:`datetime.time.fromisoformat` and @@ -690,7 +694,7 @@ enum * Added the :func:`~enum.global_enum` enum decorator, which adjusts :meth:`~object.__repr__` and :meth:`~object.__str__` to show values as members of their module rather than the enum class. - For example, ``'re.ASCII'`` for the :data:`~re.ASCII` member + For example, ``'re.ASCII'`` for the :const:`~re.ASCII` member of :class:`re.RegexFlag` rather than ``'RegexFlag.ASCII'``. * Enhanced :class:`~enum.Flag` to support @@ -893,7 +897,7 @@ os * On Windows, :func:`os.urandom` now uses ``BCryptGenRandom()``, instead of ``CryptGenRandom()`` which is deprecated. - (Contributed by Dong-hee Na in :issue:`44611`.) + (Contributed by Donghee Na in :issue:`44611`.) .. _whatsnew311-pathlib: @@ -1063,8 +1067,8 @@ threading * On Unix, if the ``sem_clockwait()`` function is available in the C library (glibc 2.30 and newer), the :meth:`threading.Lock.acquire` method now uses - the monotonic clock (:data:`time.CLOCK_MONOTONIC`) for the timeout, rather - than using the system clock (:data:`time.CLOCK_REALTIME`), to not be affected + the monotonic clock (:const:`time.CLOCK_MONOTONIC`) for the timeout, rather + than using the system clock (:const:`time.CLOCK_REALTIME`), to not be affected by system clock changes. (Contributed by Victor Stinner in :issue:`41710`.) @@ -1085,7 +1089,7 @@ time `_ which has a resolution of 100 nanoseconds (10\ :sup:`-7` seconds). Previously, it had a resolution of 1 millisecond (10\ :sup:`-3` seconds). - (Contributed by Benjamin SzÅ‘ke, Dong-hee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) + (Contributed by Benjamin SzÅ‘ke, Donghee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) .. _whatsnew311-tkinter: @@ -1301,7 +1305,7 @@ This section covers specific optimizations independent of the * :func:`unicodedata.normalize` now normalizes pure-ASCII strings in constant time. - (Contributed by Dong-hee Na in :issue:`44987`.) + (Contributed by Donghee Na in :issue:`44987`.) .. _whatsnew311-faster-cpython: @@ -1448,7 +1452,7 @@ Bucher, with additional help from Irit Katriel and Dennis Sweeney.) | | | | (up to) | | +===============+====================+=======================================================+===================+===================+ | Binary | ``x + x`` | Binary add, multiply and subtract for common types | 10% | Mark Shannon, | -| operations | | such as :class:`int`, :class:`float` and :class:`str` | | Dong-hee Na, | +| operations | | such as :class:`int`, :class:`float` and :class:`str` | | Donghee Na, | | | ``x - x`` | take custom fast paths for their underlying types. | | Brandt Bucher, | | | | | | Dennis Sweeney | | | ``x * x`` | | | | @@ -1812,7 +1816,7 @@ Standard Library (Contributed by Serhiy Storchaka in :gh:`91760`.) * In the :mod:`re` module, the :func:`!re.template` function - and the corresponding :data:`!re.TEMPLATE` and :data:`!re.T` flags + and the corresponding :const:`!re.TEMPLATE` and :const:`!re.T` flags are deprecated, as they were undocumented and lacked an obvious purpose. They will be removed in Python 3.13. (Contributed by Serhiy Storchaka and Miro HronÄok in :gh:`92728`.) @@ -1835,7 +1839,7 @@ Standard Library * :class:`!webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. It is untested, undocumented, and not used by :mod:`webbrowser` itself. - (Contributed by Dong-hee Na in :issue:`42255`.) + (Contributed by Donghee Na in :issue:`42255`.) * The behavior of returning a value from a :class:`~unittest.TestCase` and :class:`~unittest.IsolatedAsyncioTestCase` test methods (other than the @@ -1980,7 +1984,7 @@ Removed C APIs are :ref:`listed separately `. :meth:`!NullTranslations.set_output_charset` methods, and the *codeset* parameter of :func:`!translation` and :func:`!install`, since they are only used for the :func:`!l*gettext` functions. - (Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.) + (Contributed by Donghee Na and Serhiy Storchaka in :issue:`44235`.) * Removed from the :mod:`inspect` module: @@ -2005,7 +2009,7 @@ Removed C APIs are :ref:`listed separately `. * Removed the :class:`!MailmanProxy` class in the :mod:`smtpd` module, as it is unusable without the external :mod:`!mailman` package. - (Contributed by Dong-hee Na in :issue:`35800`.) + (Contributed by Donghee Na in :issue:`35800`.) * Removed the deprecated :meth:`!split` method of :class:`!_tkinter.TkappType`. (Contributed by Erlend E. Aasland in :issue:`38371`.) @@ -2147,7 +2151,7 @@ Build Changes * CPython can now be built with the `ThinLTO `_ option via passing ``thin`` to :option:`--with-lto`, i.e. ``--with-lto=thin``. - (Contributed by Dong-hee Na and Brett Holman in :issue:`44340`.) + (Contributed by Donghee Na and Brett Holman in :issue:`44340`.) * Freelists for object structs can now be disabled. A new :program:`configure` option :option:`--without-freelists` can be used to disable all freelists @@ -2216,7 +2220,7 @@ New Features * :c:func:`PyBuffer_SizeFromFormat` * :c:func:`PyBuffer_ToContiguous` * :c:func:`PyBuffer_FromContiguous` - * :c:func:`PyBuffer_CopyData` + * :c:func:`PyObject_CopyData` * :c:func:`PyBuffer_IsContiguous` * :c:func:`PyBuffer_FillContiguousStrides` * :c:func:`PyBuffer_FillInfo` @@ -2227,7 +2231,7 @@ New Features (Contributed by Christian Heimes in :issue:`45459`.) -* Added the :c:data:`PyType_GetModuleByDef` function, used to get the module +* Added the :c:func:`PyType_GetModuleByDef` function, used to get the module in which a method was defined, in cases where this information is not available directly (via :c:type:`PyCMethod`). (Contributed by Petr Viktorin in :issue:`46613`.) @@ -2347,11 +2351,11 @@ Porting to Python 3.11 #endif * The :c:func:`PyType_Ready` function now raises an error if a type is defined - with the :const:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function + with the :c:macro:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function (:c:member:`PyTypeObject.tp_traverse`). (Contributed by Victor Stinner in :issue:`44263`.) -* Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit +* Heap types with the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit the :pep:`590` vectorcall protocol. Previously, this was only possible for :ref:`static types `. (Contributed by Erlend E. Aasland in :issue:`43908`) @@ -2562,18 +2566,18 @@ Deprecated * Deprecate the following functions to configure the Python initialization: - * :c:func:`PySys_AddWarnOptionUnicode` - * :c:func:`PySys_AddWarnOption` - * :c:func:`PySys_AddXOption` - * :c:func:`PySys_HasWarnOptions` - * :c:func:`PySys_SetArgvEx` - * :c:func:`PySys_SetArgv` - * :c:func:`PySys_SetPath` - * :c:func:`Py_SetPath` - * :c:func:`Py_SetProgramName` - * :c:func:`Py_SetPythonHome` - * :c:func:`Py_SetStandardStreamEncoding` - * :c:func:`_Py_SetProgramFullPath` + * :c:func:`!PySys_AddWarnOptionUnicode` + * :c:func:`!PySys_AddWarnOption` + * :c:func:`!PySys_AddXOption` + * :c:func:`!PySys_HasWarnOptions` + * :c:func:`!PySys_SetArgvEx` + * :c:func:`!PySys_SetArgv` + * :c:func:`!PySys_SetPath` + * :c:func:`!Py_SetPath` + * :c:func:`!Py_SetProgramName` + * :c:func:`!Py_SetPythonHome` + * :c:func:`!Py_SetStandardStreamEncoding` + * :c:func:`!_Py_SetProgramFullPath` Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization Configuration ` instead (:pep:`587`). @@ -2591,22 +2595,22 @@ Pending Removal in Python 3.12 The following C APIs have been deprecated in earlier Python releases, and will be removed in Python 3.12. -* :c:func:`PyUnicode_AS_DATA` -* :c:func:`PyUnicode_AS_UNICODE` -* :c:func:`PyUnicode_AsUnicodeAndSize` -* :c:func:`PyUnicode_AsUnicode` -* :c:func:`PyUnicode_FromUnicode` -* :c:func:`PyUnicode_GET_DATA_SIZE` -* :c:func:`PyUnicode_GET_SIZE` -* :c:func:`PyUnicode_GetSize` +* :c:func:`!PyUnicode_AS_DATA` +* :c:func:`!PyUnicode_AS_UNICODE` +* :c:func:`!PyUnicode_AsUnicodeAndSize` +* :c:func:`!PyUnicode_AsUnicode` +* :c:func:`!PyUnicode_FromUnicode` +* :c:func:`!PyUnicode_GET_DATA_SIZE` +* :c:func:`!PyUnicode_GET_SIZE` +* :c:func:`!PyUnicode_GetSize` * :c:func:`PyUnicode_IS_COMPACT` * :c:func:`PyUnicode_IS_READY` * :c:func:`PyUnicode_READY` -* :c:func:`Py_UNICODE_WSTR_LENGTH` -* :c:func:`_PyUnicode_AsUnicode` -* :c:macro:`PyUnicode_WCHAR_KIND` +* :c:func:`!PyUnicode_WSTR_LENGTH` +* :c:func:`!_PyUnicode_AsUnicode` +* :c:macro:`!PyUnicode_WCHAR_KIND` * :c:type:`PyUnicodeObject` -* :c:func:`PyUnicode_InternImmortal()` +* :c:func:`!PyUnicode_InternImmortal` .. _whatsnew311-c-api-removed: @@ -2614,7 +2618,7 @@ and will be removed in Python 3.12. Removed ------- -* :c:func:`PyFrame_BlockSetup` and :c:func:`PyFrame_BlockPop` have been +* :c:func:`!PyFrame_BlockSetup` and :c:func:`!PyFrame_BlockPop` have been removed. (Contributed by Mark Shannon in :issue:`40222`.) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index a6d101bdb9f7a8..dc0cc82475a2e4 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -3,8 +3,7 @@ What's New In Python 3.12 **************************** -:Release: |release| -:Date: |today| +:Editor: Adam Turner .. Rules for maintenance: @@ -47,15 +46,12 @@ researching a change. This article explains the new features in Python 3.12, compared to 3.11. - +Python 3.12 was released on October 2, 2023. For full details, see the :ref:`changelog `. -.. note:: - - Prerelease users should be aware that this document is currently in draft - form. It will be updated substantially as Python 3.12 moves towards release, - so it's worth checking back even after reading earlier versions. +.. seealso:: + :pep:`693` -- Python 3.12 Release Schedule Summary -- Release highlights ============================= @@ -63,96 +59,198 @@ Summary -- Release highlights .. This section singles out the most important changes in Python 3.12. Brevity is key. +Python 3.12 is the latest stable release of the Python programming language, +with a mix of changes to the language and the standard library. +The library changes focus on cleaning up deprecated APIs, usability, and correctness. +Of note, the :mod:`!distutils` package has been removed from the standard library. +Filesystem support in :mod:`os` and :mod:`pathlib` has seen a number of improvements, +and several modules have better performance. + +The language changes focus on usability, +as :term:`f-strings ` have had many limitations removed +and 'Did you mean ...' suggestions continue to improve. +The new :ref:`type parameter syntax ` +and :keyword:`type` statement improve ergonomics for using :term:`generic types +` and :term:`type aliases ` with static type checkers. + +This article doesn't attempt to provide a complete specification of all new features, +but instead gives a convenient overview. +For full details, you should refer to the documentation, +such as the :ref:`Library Reference ` +and :ref:`Language Reference `. +If you want to understand the complete implementation and design rationale for a change, +refer to the PEP for a particular new feature; +but note that PEPs usually are not kept up-to-date +once a feature has been fully implemented. + +-------------- .. PEP-sized items next. +New syntax features: + +* :ref:`PEP 695 `, type parameter syntax and the :keyword:`type` statement + New grammar features: -* :pep:`701`: Syntactic formalization of f-strings +* :ref:`PEP 701 `, :term:`f-strings ` in the grammar -New typing features: +Interpreter improvements: -* :pep:`688`: Making the buffer protocol accessible in Python +* :ref:`PEP 684 `, a unique per-interpreter :term:`GIL + ` +* :ref:`PEP 669 `, low impact monitoring +* `Improved 'Did you mean ...' suggestions `_ + for :exc:`NameError`, :exc:`ImportError`, and :exc:`SyntaxError` exceptions -* :ref:`whatsnew312-pep692` +Python data model improvements: -* :ref:`whatsnew312-pep695` +* :ref:`PEP 688 `, using the :ref:`buffer protocol + ` from Python -* :pep:`698`: Override Decorator for Static Typing +Significant improvements in the standard library: -Important deprecations, removals or restrictions: +* The :class:`pathlib.Path` class now supports subclassing +* The :mod:`os` module received several improvements for Windows support +* A :ref:`command-line interface ` has been added to the + :mod:`sqlite3` module +* :func:`isinstance` checks against :func:`runtime-checkable protocols + ` enjoy a speed up of between two and 20 times +* The :mod:`asyncio` package has had a number of performance improvements, + with some benchmarks showing a 75% speed up. +* A :ref:`command-line interface ` has been added to the + :mod:`uuid` module +* Due to the changes in :ref:`PEP 701 `, + producing tokens via the :mod:`tokenize` module is up to 64% faster. -* :pep:`623`: Remove wstr from Unicode +Security improvements: -* :pep:`632`: Remove the ``distutils`` package +* Replace the builtin :mod:`hashlib` implementations of + SHA1, SHA3, SHA2-384, SHA2-512, and MD5 with formally verified code from the + `HACL* `__ project. + These builtin implementations remain as fallbacks that are only used when + OpenSSL does not provide them. -Improved Error Messages -======================= +C API improvements: -* Modules from the standard library are now potentially suggested as part of - the error messages displayed by the interpreter when a :exc:`NameError` is - raised to the top level. Contributed by Pablo Galindo in :gh:`98254`. +* :ref:`PEP 697 `, unstable C API tier +* :ref:`PEP 683 `, immortal objects - >>> sys.version_info - Traceback (most recent call last): - File "", line 1, in - NameError: name 'sys' is not defined. Did you forget to import 'sys'? +CPython implementation improvements: -* Improve the error suggestion for :exc:`NameError` exceptions for instances. - Now if a :exc:`NameError` is raised in a method and the instance has an - attribute that's exactly equal to the name in the exception, the suggestion - will include ``self.`` instead of the closest match in the method - scope. Contributed by Pablo Galindo in :gh:`99139`. +* :ref:`PEP 709 `, comprehension inlining +* :ref:`CPython support ` for the Linux ``perf`` profiler +* Implement stack overflow protection on supported platforms - >>> class A: - ... def __init__(self): - ... self.blech = 1 - ... - ... def foo(self): - ... somethin = blech +New typing features: - >>> A().foo() - Traceback (most recent call last): - File "", line 1 - somethin = blech - ^^^^^ - NameError: name 'blech' is not defined. Did you mean: 'self.blech'? +* :ref:`PEP 692 `, using :class:`~typing.TypedDict` to + annotate :term:`**kwargs ` +* :ref:`PEP 698 `, :func:`typing.override` decorator +Important deprecations, removals or restrictions: -* Improve the :exc:`SyntaxError` error message when the user types ``import x - from y`` instead of ``from y import x``. Contributed by Pablo Galindo in :gh:`98931`. +* :pep:`623`: Remove ``wstr`` from Unicode objects in Python's C API, + reducing the size of every :class:`str` object by at least 8 bytes. - >>> import a.y.z from b.y.z - Traceback (most recent call last): - File "", line 1 - import a.y.z from b.y.z - ^^^^^^^^^^^^^^^^^^^^^^^ - SyntaxError: Did you mean to use 'from ... import ...' instead? +* :pep:`632`: Remove the :mod:`!distutils` package. + See `the migration guide `_ + for advice replacing the APIs it provided. + The third-party `Setuptools `__ + package continues to provide :mod:`!distutils`, + if you still require it in Python 3.12 and beyond. -* :exc:`ImportError` exceptions raised from failed ``from import - `` statements now include suggestions for the value of ```` based on the - available names in ````. Contributed by Pablo Galindo in :gh:`91058`. +* :gh:`95299`: Do not pre-install ``setuptools`` in virtual environments + created with :mod:`venv`. + This means that ``distutils``, ``setuptools``, ``pkg_resources``, + and ``easy_install`` will no longer available by default; to access these + run ``pip install setuptools`` in the :ref:`activated ` + virtual environment. - >>> from collections import chainmap - Traceback (most recent call last): - File "", line 1, in - ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'? +* The :mod:`!asynchat`, :mod:`!asyncore`, and :mod:`!imp` modules have been + removed, along with several :class:`unittest.TestCase` + `method aliases `_. New Features ============ +.. _whatsnew312-pep695: + +PEP 695: Type Parameter Syntax +------------------------------ + +Generic classes and functions under :pep:`484` were declared using a verbose syntax +that left the scope of type parameters unclear and required explicit declarations of +variance. + +:pep:`695` introduces a new, more compact and explicit way to create +:ref:`generic classes ` and :ref:`functions `:: + + def max[T](args: Iterable[T]) -> T: + ... + + class list[T]: + def __getitem__(self, index: int, /) -> T: + ... + + def append(self, element: T) -> None: + ... + +In addition, the PEP introduces a new way to declare :ref:`type aliases ` +using the :keyword:`type` statement, which creates an instance of +:class:`~typing.TypeAliasType`:: + + type Point = tuple[float, float] + +Type aliases can also be :ref:`generic `:: + + type Point[T] = tuple[T, T] + +The new syntax allows declaring :class:`~typing.TypeVarTuple` +and :class:`~typing.ParamSpec` parameters, as well as :class:`~typing.TypeVar` +parameters with bounds or constraints:: + + type IntFunc[**P] = Callable[P, int] # ParamSpec + type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple + type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound + type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints + +The value of type aliases and the bound and constraints of type variables +created through this syntax are evaluated only on demand (see +:ref:`lazy evaluation `). This means type aliases are able to +refer to other types defined later in the file. + +Type parameters declared through a type parameter list are visible within the +scope of the declaration and any nested scopes, but not in the outer scope. For +example, they can be used in the type annotations for the methods of a generic +class or in the class body. However, they cannot be used in the module scope after +the class is defined. See :ref:`type-params` for a detailed description of the +runtime semantics of type parameters. + +In order to support these scoping semantics, a new kind of scope is introduced, +the :ref:`annotation scope `. Annotation scopes behave for the +most part like function scopes, but interact differently with enclosing class scopes. +In Python 3.13, :term:`annotations ` will also be evaluated in +annotation scopes. + +See :pep:`695` for more details. + +(PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut, +and others in :gh:`103764`.) + .. _whatsnew312-pep701: PEP 701: Syntactic formalization of f-strings --------------------------------------------- -:pep:`701` lifts some restrictions on the usage of f-strings. Expression components -inside f-strings can now be any valid Python expression including backslashes, -unicode escaped sequences, multi-line expressions, comments and strings reusing the -same quote as the containing f-string. Let's cover these in detail: +:pep:`701` lifts some restrictions on the usage of :term:`f-strings `. +Expression components inside f-strings can now be any valid Python expression, +including strings reusing the same quote as the containing f-string, +multi-line expressions, comments, backslashes, and unicode escape sequences. +Let's cover these in detail: -* Quote reuse: in Python 3.11, reusing the same quotes as the containing f-string +* Quote reuse: in Python 3.11, reusing the same quotes as the enclosing f-string raises a :exc:`SyntaxError`, forcing the user to either use other available quotes (like using double quotes or triple quotes if the f-string uses single quotes). In Python 3.12, you can now do things like this: @@ -175,11 +273,12 @@ same quote as the containing f-string. Let's cover these in detail: >>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" '2' -* Multi-line expressions and comments: In Python 3.11, f-strings expressions - must be defined in a single line even if outside f-strings expressions could - span multiple lines (like literal lists being defined over multiple lines), - making them harder to read. In Python 3.12 you can now define expressions - spanning multiple lines and include comments on them: +* Multi-line expressions and comments: In Python 3.11, f-string expressions + must be defined in a single line, even if the expression within the f-string + could normally span multiple lines + (like literal lists being defined over multiple lines), + making them harder to read. In Python 3.12 you can now define f-strings + spanning multiple lines, and add inline comments: >>> f"This is the playlist: {", ".join([ ... 'Take me back to Eden', # My, my, those eyes like fire @@ -189,10 +288,10 @@ same quote as the containing f-string. Let's cover these in detail: 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism' * Backslashes and unicode characters: before Python 3.12 f-string expressions - couldn't contain any ``\`` character. This also affected unicode escaped - sequences (such as ``\N{snowman}``) as these contain the ``\N`` part that - previously could not be part of expression components of f-strings. Now, you - can define expressions like this: + couldn't contain any ``\`` character. This also affected unicode :ref:`escape + sequences ` (such as ``\N{snowman}``) as these contain + the ``\N`` part that previously could not be part of expression components of + f-strings. Now, you can define expressions like this: >>> print(f"This is the playlist: {"\n".join(songs)}") This is the playlist: Take me back to Eden @@ -204,7 +303,7 @@ same quote as the containing f-string. Let's cover these in detail: See :pep:`701` for more details. As a positive side-effect of how this feature has been implemented (by parsing f-strings -with the PEG parser (see :pep:`617`), now error messages for f-strings are more precise +with :pep:`the PEG parser <617>`), now error messages for f-strings are more precise and include the exact location of the error. For example, in Python 3.11, the following f-string raises a :exc:`SyntaxError`: @@ -232,6 +331,66 @@ are parsed with the PEG parser, error messages can be more precise and show the Maureira-Fredes and Marta Gómez in :gh:`102856`. PEP written by Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou and Marta Gómez). +.. _whatsnew312-pep684: + +PEP 684: A Per-Interpreter GIL +------------------------------ + +:pep:`684` introduces a per-interpreter :term:`GIL `, +so that sub-interpreters may now be created with a unique GIL per interpreter. +This allows Python programs to take full advantage of multiple CPU +cores. This is currently only available through the C-API, +though a Python API is :pep:`anticipated for 3.13 <554>`. + +Use the new :c:func:`Py_NewInterpreterFromConfig` function to +create an interpreter with its own GIL:: + + PyInterpreterConfig config = { + .check_multi_interp_extensions = 1, + .gil = PyInterpreterConfig_OWN_GIL, + }; + PyThreadState *tstate = NULL; + PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); + if (PyStatus_Exception(status)) { + return -1; + } + /* The new interpreter is now active in the current thread. */ + +For further examples how to use the C-API for sub-interpreters with a +per-interpreter GIL, see :source:`Modules/_xxsubinterpretersmodule.c`. + +(Contributed by Eric Snow in :gh:`104210`, etc.) + +.. _whatsnew312-pep669: + +PEP 669: Low impact monitoring for CPython +------------------------------------------ + +:pep:`669` defines a new :mod:`API ` for profilers, +debuggers, and other tools to monitor events in CPython. +It covers a wide range of events, including calls, +returns, lines, exceptions, jumps, and more. +This means that you only pay for what you use, providing support +for near-zero overhead debuggers and coverage tools. +See :mod:`sys.monitoring` for details. + +(Contributed by Mark Shannon in :gh:`103082`.) + +.. _whatsnew312-pep688: + +PEP 688: Making the buffer protocol accessible in Python +-------------------------------------------------------- + +:pep:`688` introduces a way to use the :ref:`buffer protocol ` +from Python code. Classes that implement the :meth:`~object.__buffer__` method +are now usable as buffer types. + +The new :class:`collections.abc.Buffer` ABC provides a standard +way to represent buffer objects, for example in type annotations. +The new :class:`inspect.BufferFlags` enum represents the flags that +can be used to customize buffer creation. +(Contributed by Jelle Zijlstra in :gh:`102500`.) + .. _whatsnew312-pep709: PEP 709: Comprehension inlining @@ -239,17 +398,18 @@ PEP 709: Comprehension inlining Dictionary, list, and set comprehensions are now inlined, rather than creating a new single-use function object for each execution of the comprehension. This -speeds up execution of a comprehension by up to 2x. +speeds up execution of a comprehension by up to two times. +See :pep:`709` for further details. -Comprehension iteration variables remain isolated; they don't overwrite a +Comprehension iteration variables remain isolated and don't overwrite a variable of the same name in the outer scope, nor are they visible after the -comprehension. This isolation is now maintained via stack/locals manipulation, -not via separate function scope. - -Inlining does result in a few visible behavior changes: +comprehension. Inlining does result in a few visible behavior changes: * There is no longer a separate frame for the comprehension in tracebacks, and tracing/profiling no longer shows the comprehension as a function call. +* The :mod:`symtable` module will no longer produce child symbol tables for each + comprehension; instead, the comprehension's locals will be included in the + parent function's symbol table. * Calling :func:`locals` inside a comprehension now includes variables from outside the comprehension, and no longer includes the synthetic ``.0`` variable for the comprehension "argument". @@ -260,25 +420,64 @@ Inlining does result in a few visible behavior changes: create a list of keys to iterate over: ``keys = list(locals()); [k for k in keys]``. -Contributed by Carl Meyer and Vladimir Matveev in :pep:`709`. +(Contributed by Carl Meyer and Vladimir Matveev in :pep:`709`.) -PEP 688: Making the buffer protocol accessible in Python --------------------------------------------------------- +Improved Error Messages +----------------------- -:pep:`688` introduces a way to use the :ref:`buffer protocol ` -from Python code. Classes that implement the :meth:`~object.__buffer__` method -are now usable as buffer types. +* Modules from the standard library are now potentially suggested as part of + the error messages displayed by the interpreter when a :exc:`NameError` is + raised to the top level. (Contributed by Pablo Galindo in :gh:`98254`.) + + >>> sys.version_info + Traceback (most recent call last): + File "", line 1, in + NameError: name 'sys' is not defined. Did you forget to import 'sys'? + +* Improve the error suggestion for :exc:`NameError` exceptions for instances. + Now if a :exc:`NameError` is raised in a method and the instance has an + attribute that's exactly equal to the name in the exception, the suggestion + will include ``self.`` instead of the closest match in the method + scope. (Contributed by Pablo Galindo in :gh:`99139`.) + + >>> class A: + ... def __init__(self): + ... self.blech = 1 + ... + ... def foo(self): + ... somethin = blech + ... + >>> A().foo() + Traceback (most recent call last): + File "", line 1 + somethin = blech + ^^^^^ + NameError: name 'blech' is not defined. Did you mean: 'self.blech'? + +* Improve the :exc:`SyntaxError` error message when the user types ``import x + from y`` instead of ``from y import x``. (Contributed by Pablo Galindo in :gh:`98931`.) + + >>> import a.y.z from b.y.z + Traceback (most recent call last): + File "", line 1 + import a.y.z from b.y.z + ^^^^^^^^^^^^^^^^^^^^^^^ + SyntaxError: Did you mean to use 'from ... import ...' instead? + +* :exc:`ImportError` exceptions raised from failed ``from import + `` statements now include suggestions for the value of ```` based on the + available names in ````. (Contributed by Pablo Galindo in :gh:`91058`.) + + >>> from collections import chainmap + Traceback (most recent call last): + File "", line 1, in + ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'? -The new :class:`collections.abc.Buffer` ABC provides a standard -way to represent buffer objects, for example in type annotations. -The new :class:`inspect.BufferFlags` enum represents the flags that -can be used to customize buffer creation. -(Contributed by Jelle Zijlstra in :gh:`102500`.) New Features Related to Type Hints ================================== -This section covers major changes affecting :pep:`484` type hints and +This section covers major changes affecting :pep:`type hints <484>` and the :mod:`typing` module. .. _whatsnew312-pep692: @@ -290,7 +489,7 @@ Typing ``**kwargs`` in a function signature as introduced by :pep:`484` allowed for valid annotations only in cases where all of the ``**kwargs`` were of the same type. -This PEP specifies a more precise way of typing ``**kwargs`` by relying on +:pep:`692` specifies a more precise way of typing ``**kwargs`` by relying on typed dictionaries:: from typing import TypedDict, Unpack @@ -305,6 +504,8 @@ See :pep:`692` for more details. (Contributed by Franek Magiera in :gh:`103629`.) +.. _whatsnew312-pep698: + PEP 698: Override Decorator for Static Typing --------------------------------------------- @@ -332,119 +533,21 @@ Example:: def get_colour(self) -> str: return "red" -(Contributed by Steven Troxler in :gh:`101561`.) - -.. _whatsnew312-pep695: - -PEP 695: Type Parameter Syntax ------------------------------- - -Generic classes and functions under :pep:`484` were declared using a verbose syntax -that left the scope of type parameters unclear and required explicit declarations of -variance. - -:pep:`695` introduces a new, more compact and explicit way to create -:ref:`generic classes ` and :ref:`functions `:: - - def max[T](args: Iterable[T]) -> T: - ... - - class list[T]: - def __getitem__(self, index: int, /) -> T: - ... - - def append(self, element: T) -> None: - ... - -In addition, the PEP introduces a new way to declare :ref:`type aliases ` -using the :keyword:`type` statement, which creates an instance of -:class:`~typing.TypeAliasType`:: +See :pep:`698` for more details. - type Point = tuple[float, float] - -Type aliases can also be :ref:`generic `:: - - type Point[T] = tuple[T, T] - -The new syntax allows declaring :class:`~typing.TypeVarTuple` -and :class:`~typing.ParamSpec` parameters, as well as :class:`~typing.TypeVar` -parameters with bounds or constraints:: - - type IntFunc[**P] = Callable[P, int] # ParamSpec - type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple - type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound - type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints - -The value of type aliases and the bound and constraints of type variables -created through this syntax are evaluated only on demand (see -:ref:`lazy-evaluation`). This means type aliases are able to refer to other -types defined later in the file. - -Type parameters declared through a type parameter list are visible within the -scope of the declaration and any nested scopes, but not in the outer scope. For -example, they can be used in the type annotations for the methods of a generic -class or in the class body. However, they cannot be used in the module scope after -the class is defined. See :ref:`type-params` for a detailed description of the -runtime semantics of type parameters. - -In order to support these scoping semantics, a new kind of scope is introduced, -the :ref:`annotation scope `. Annotation scopes behave for the -most part like function scopes, but interact differently with enclosing class scopes. -In Python 3.13, :term:`annotations ` will also be evaluated in -annotation scopes. - -See :pep:`695` for more details. - -(PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut, -and others in :gh:`103764`.) +(Contributed by Steven Troxler in :gh:`101561`.) Other Language Changes ====================== -* Add :ref:`perf_profiling` through the new - environment variable :envvar:`PYTHONPERFSUPPORT`, - the new command-line option :option:`-X perf <-X>`, - as well as the new :func:`sys.activate_stack_trampoline`, - :func:`sys.deactivate_stack_trampoline`, - and :func:`sys.is_stack_trampoline_active` APIs. - (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes - with contributions from Gregory P. Smith [Google] and Mark Shannon - in :gh:`96123`.) - -* The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, - have a new a *filter* argument that allows limiting tar features than may be - surprising or dangerous, such as creating files outside the destination - directory. - See :ref:`tarfile-extraction-filter` for details. - In Python 3.14, the default will switch to ``'data'``. - (Contributed by Petr Viktorin in :pep:`706`.) - -* :class:`types.MappingProxyType` instances are now hashable if the underlying - mapping is hashable. - (Contributed by Serhiy Storchaka in :gh:`87995`.) - -* :class:`memoryview` now supports the half-float type (the "e" format code). - (Contributed by Dong-hee Na and Antoine Pitrou in :gh:`90751`.) - * The parser now raises :exc:`SyntaxError` when parsing source code containing null bytes. (Contributed by Pablo Galindo in :gh:`96670`.) -* :func:`ast.parse` now raises :exc:`SyntaxError` instead of :exc:`ValueError` - when parsing source code containing null bytes. (Contributed by Pablo Galindo - in :gh:`96670`.) - -* The Garbage Collector now runs only on the eval breaker mechanism of the - Python bytecode evaluation loop instead of object allocations. The GC can - also run when :c:func:`PyErr_CheckSignals` is called so C extensions that - need to run for a long time without executing any Python code also have a - chance to execute the GC periodically. (Contributed by Pablo Galindo in - :gh:`97922`.) - * A backslash-character pair that is not a valid escape sequence now generates a :exc:`SyntaxWarning`, instead of :exc:`DeprecationWarning`. For example, ``re.compile("\d+\.\d+")`` now emits a :exc:`SyntaxWarning` - (``"\d"`` is an invalid escape sequence), use raw strings for regular - expression: ``re.compile(r"\d+\.\d+")``. + (``"\d"`` is an invalid escape sequence, use raw strings for regular + expression: ``re.compile(r"\d+\.\d+")``). In a future Python version, :exc:`SyntaxError` will eventually be raised, instead of :exc:`SyntaxWarning`. (Contributed by Victor Stinner in :gh:`98401`.) @@ -455,10 +558,6 @@ Other Language Changes In a future Python version they will be eventually a :exc:`SyntaxError`. (Contributed by Victor Stinner in :gh:`98401`.) -* All builtin and extension callables expecting boolean parameters now accept - arguments of any type instead of just :class:`bool` and :class:`int`. - (Contributed by Serhiy Storchaka in :gh:`60203`.) - * Variables used in the target part of comprehensions that are not stored to can now be used in assignment expressions (``:=``). For example, in ``[(b := 1) for a, b.prop in some_iter]``, the assignment to @@ -466,14 +565,7 @@ Other Language Changes part of comprehensions (like ``a``) is still disallowed, as per :pep:`572`. (Contributed by Nikita Sobolev in :gh:`100581`.) -* :class:`slice` objects are now hashable, allowing them to be used as dict keys and - set items. (Contributed by Will Bradshaw, Furkan Onder, and Raymond Hettinger in :gh:`101264`.) - -* :func:`sum` now uses Neumaier summation to improve accuracy when summing - floats or mixed ints and floats. - (Contributed by Raymond Hettinger in :gh:`100425`.) - -* Exceptions raised in a typeobject's ``__set_name__`` method are no longer +* Exceptions raised in a class or type's ``__set_name__`` method are no longer wrapped by a :exc:`RuntimeError`. Context information is added to the exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.) @@ -482,11 +574,58 @@ Other Language Changes :exc:`ExceptionGroup`. Also changed in version 3.11.4. (Contributed by Irit Katriel in :gh:`103590`.) +* The Garbage Collector now runs only on the eval breaker mechanism of the + Python bytecode evaluation loop instead of object allocations. The GC can + also run when :c:func:`PyErr_CheckSignals` is called so C extensions that + need to run for a long time without executing any Python code also have a + chance to execute the GC periodically. (Contributed by Pablo Galindo in + :gh:`97922`.) + +* All builtin and extension callables expecting boolean parameters now accept + arguments of any type instead of just :class:`bool` and :class:`int`. + (Contributed by Serhiy Storchaka in :gh:`60203`.) + +* :class:`memoryview` now supports the half-float type (the "e" format code). + (Contributed by Donghee Na and Antoine Pitrou in :gh:`90751`.) + +* :class:`slice` objects are now hashable, allowing them to be used as dict keys and + set items. (Contributed by Will Bradshaw, Furkan Onder, and Raymond Hettinger in :gh:`101264`.) + +* :func:`sum` now uses Neumaier summation to improve accuracy and commutativity + when summing floats or mixed ints and floats. + (Contributed by Raymond Hettinger in :gh:`100425`.) + +* :func:`ast.parse` now raises :exc:`SyntaxError` instead of :exc:`ValueError` + when parsing source code containing null bytes. (Contributed by Pablo Galindo + in :gh:`96670`.) + +* The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, + have a new a *filter* argument that allows limiting tar features than may be + surprising or dangerous, such as creating files outside the destination + directory. + See :ref:`tarfile extraction filters ` for details. + In Python 3.14, the default will switch to ``'data'``. + (Contributed by Petr Viktorin in :pep:`706`.) + +* :class:`types.MappingProxyType` instances are now hashable if the underlying + mapping is hashable. + (Contributed by Serhiy Storchaka in :gh:`87995`.) + +* Add :ref:`support for the perf profiler ` through the new + environment variable :envvar:`PYTHONPERFSUPPORT` + and command-line option :option:`-X perf <-X>`, + as well as the new :func:`sys.activate_stack_trampoline`, + :func:`sys.deactivate_stack_trampoline`, + and :func:`sys.is_stack_trampoline_active` functions. + (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes + with contributions from Gregory P. Smith [Google] and Mark Shannon + in :gh:`96123`.) + New Modules =========== -* None yet. +* None. Improved Modules @@ -506,29 +645,20 @@ asyncio writing to sockets and uses :meth:`~socket.socket.sendmsg` if the platform supports it. (Contributed by Kumar Aditya in :gh:`91166`.) -* Added :func:`asyncio.eager_task_factory` and :func:`asyncio.create_eager_task_factory` +* Add :func:`asyncio.eager_task_factory` and :func:`asyncio.create_eager_task_factory` functions to allow opting an event loop in to eager task execution, making some use-cases 2x to 5x faster. - (Contributed by Jacob Bower & Itamar O in :gh:`102853`, :gh:`104140`, and :gh:`104138`) + (Contributed by Jacob Bower & Itamar Oren in :gh:`102853`, :gh:`104140`, and :gh:`104138`) -* On Linux, :mod:`asyncio` uses :class:`~asyncio.PidfdChildWatcher` by default +* On Linux, :mod:`asyncio` uses :class:`asyncio.PidfdChildWatcher` by default if :func:`os.pidfd_open` is available and functional instead of - :class:`~asyncio.ThreadedChildWatcher`. + :class:`asyncio.ThreadedChildWatcher`. (Contributed by Kumar Aditya in :gh:`98024`.) -* The child watcher classes :class:`~asyncio.MultiLoopChildWatcher`, - :class:`~asyncio.FastChildWatcher`, :class:`~asyncio.AbstractChildWatcher` - and :class:`~asyncio.SafeChildWatcher` are deprecated and - will be removed in Python 3.14. It is recommended to not manually - configure a child watcher as the event loop now uses the best available - child watcher for each platform (:class:`~asyncio.PidfdChildWatcher` - if supported and :class:`~asyncio.ThreadedChildWatcher` otherwise). - (Contributed by Kumar Aditya in :gh:`94597`.) - -* :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`, - :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and - :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated - and will be removed in Python 3.14. +* The event loop now uses the best available child watcher for each platform + (:class:`asyncio.PidfdChildWatcher` if supported and + :class:`asyncio.ThreadedChildWatcher` otherwise), so manually + configuring a child watcher is not recommended. (Contributed by Kumar Aditya in :gh:`94597`.) * Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying @@ -536,7 +666,7 @@ asyncio (Contributed by Kumar Aditya in :gh:`99388`.) * Add C implementation of :func:`asyncio.current_task` for 4x-6x speedup. - (Contributed by Itamar Ostricher and Pranav Thulasiram Bhat in :gh:`100344`.) + (Contributed by Itamar Oren and Pranav Thulasiram Bhat in :gh:`100344`.) * :func:`asyncio.iscoroutine` now returns ``False`` for generators as :mod:`asyncio` does not support legacy generator-based coroutines. @@ -549,15 +679,16 @@ asyncio calendar -------- -* Add enums :data:`~calendar.Month` and :data:`~calendar.Day`. +* Add enums :data:`calendar.Month` and :data:`calendar.Day` + defining months of the year and days of the week. (Contributed by Prince Roshan in :gh:`103636`.) csv --- -* Add :data:`~csv.QUOTE_NOTNULL` and :data:`~csv.QUOTE_STRINGS` flags to +* Add :const:`csv.QUOTE_NOTNULL` and :const:`csv.QUOTE_STRINGS` flags to provide finer grained control of ``None`` and empty strings by - :class:`~csv.writer` objects. + :class:`csv.writer` objects. dis --- @@ -567,16 +698,11 @@ dis :mod:`dis` module. :opcode:`HAVE_ARGUMENT` is still relevant to real opcodes, but it is not useful for pseudo instructions. Use the new - :data:`~dis.hasarg` collection instead. + :data:`dis.hasarg` collection instead. (Contributed by Irit Katriel in :gh:`94216`.) -email ------ - -* :func:`email.utils.getaddresses` and :func:`email.utils.parseaddr` now return - ``('', '')`` 2-tuples in more situations where invalid email addresses are - encountered instead of potentially inaccurate values. - (Contributed by Thomas Dwyer for :gh:`102988` to ameliorate CVE-2023-27043.) +* Add the :data:`dis.hasexc` collection to signify instructions that set + an exception handler. (Contributed by Irit Katriel in :gh:`94216`.) fractions --------- @@ -584,6 +710,12 @@ fractions * Objects of type :class:`fractions.Fraction` now support float-style formatting. (Contributed by Mark Dickinson in :gh:`100161`.) +importlib.resources +------------------- + +* :func:`importlib.resources.as_file` now supports resource directories. + (Contributed by Jason R. Coombs in :gh:`97930`.) + inspect ------- @@ -593,7 +725,7 @@ inspect * Add :func:`inspect.getasyncgenstate` and :func:`inspect.getasyncgenlocals` for determining the current state of asynchronous generators. - (Contributed by Thomas Krennwallner in :issue:`35759`.) + (Contributed by Thomas Krennwallner in :gh:`79940`.) * The performance of :func:`inspect.getattr_static` has been considerably improved. Most calls to the function should be at least 2x faster than they @@ -603,24 +735,24 @@ inspect itertools --------- -* Added :class:`itertools.batched()` for collecting into even-sized +* Add :class:`itertools.batched()` for collecting into even-sized tuples where the last batch may be shorter than the rest. (Contributed by Raymond Hettinger in :gh:`98363`.) math ---- -* Added :func:`math.sumprod` for computing a sum of products. +* Add :func:`math.sumprod` for computing a sum of products. (Contributed by Raymond Hettinger in :gh:`100485`.) -* Extended :func:`math.nextafter` to include a *steps* argument +* Extend :func:`math.nextafter` to include a *steps* argument for moving up or down multiple steps at a time. (By Matthias Goergens, Mark Dickinson, and Raymond Hettinger in :gh:`94906`.) os -- -* Add :data:`os.PIDFD_NONBLOCK` to open a file descriptor +* Add :const:`os.PIDFD_NONBLOCK` to open a file descriptor for a process with :func:`os.pidfd_open` in non-blocking mode. (Contributed by Kumar Aditya in :gh:`93312`.) @@ -655,18 +787,18 @@ pathlib ------- * Add support for subclassing :class:`pathlib.PurePath` and - :class:`~pathlib.Path`, plus their Posix- and Windows-specific variants. - Subclasses may override the :meth:`~pathlib.PurePath.with_segments` method + :class:`pathlib.Path`, plus their Posix- and Windows-specific variants. + Subclasses may override the :meth:`pathlib.PurePath.with_segments` method to pass information between path instances. -* Add :meth:`~pathlib.Path.walk` for walking the directory trees and generating +* Add :meth:`pathlib.Path.walk` for walking the directory trees and generating all file or directory names within them, similar to :func:`os.walk`. (Contributed by Stanislav Zmiev in :gh:`90385`.) * Add *walk_up* optional parameter to :meth:`pathlib.PurePath.relative_to` to allow the insertion of ``..`` entries in the result; this behavior is more consistent with :func:`os.path.relpath`. - (Contributed by Domenico Ragusa in :issue:`40358`.) + (Contributed by Domenico Ragusa in :gh:`84538`.) * Add :meth:`pathlib.Path.is_junction` as a proxy to :func:`os.path.isjunction`. (Contributed by Charles Machalow in :gh:`99547`.) @@ -686,10 +818,10 @@ pdb random ------ -* Added :func:`random.binomialvariate`. +* Add :func:`random.binomialvariate`. (Contributed by Raymond Hettinger in :gh:`81620`.) -* Added a default of ``lamb=1.0`` to :func:`random.expovariate`. +* Add a default of ``lambd=1.0`` to :func:`random.expovariate`. (Contributed by Raymond Hettinger in :gh:`100234`.) shutil @@ -728,33 +860,37 @@ sqlite3 * Add a :ref:`command-line interface `. (Contributed by Erlend E. Aasland in :gh:`77617`.) -* Add the :attr:`~sqlite3.Connection.autocommit` attribute - to :class:`~sqlite3.Connection` - and the *autocommit* parameter to :func:`~sqlite3.connect` +* Add the :attr:`sqlite3.Connection.autocommit` attribute + to :class:`sqlite3.Connection` + and the *autocommit* parameter to :func:`sqlite3.connect` to control :pep:`249`-compliant :ref:`transaction handling `. (Contributed by Erlend E. Aasland in :gh:`83638`.) * Add *entrypoint* keyword-only parameter to - :meth:`~sqlite3.Connection.load_extension`, + :meth:`sqlite3.Connection.load_extension`, for overriding the SQLite extension entry point. (Contributed by Erlend E. Aasland in :gh:`103015`.) -* Add :meth:`~sqlite3.Connection.getconfig` and - :meth:`~sqlite3.Connection.setconfig` to :class:`~sqlite3.Connection` +* Add :meth:`sqlite3.Connection.getconfig` and + :meth:`sqlite3.Connection.setconfig` to :class:`sqlite3.Connection` to make configuration changes to a database connection. (Contributed by Erlend E. Aasland in :gh:`103489`.) statistics ---------- -* Extended :func:`statistics.correlation` to include as a ``ranked`` method +* Extend :func:`statistics.correlation` to include as a ``ranked`` method for computing the Spearman correlation of ranked data. (Contributed by Raymond Hettinger in :gh:`95861`.) sys --- +* Add the :mod:`sys.monitoring` namespace to expose the new :ref:`PEP 669 + ` monitoring API. + (Contributed by Mark Shannon in :gh:`103082`.) + * Add :func:`sys.activate_stack_trampoline` and :func:`sys.deactivate_stack_trampoline` for activating and deactivating stack profiler trampolines, @@ -774,6 +910,11 @@ sys exception instance, rather than to a ``(typ, exc, tb)`` tuple. (Contributed by Irit Katriel in :gh:`103176`.) +* :func:`sys.setrecursionlimit` and :func:`sys.getrecursionlimit`. + The recursion limit now applies only to Python code. Builtin functions do + not use the recursion limit, but are protected by a different mechanism + that prevents recursion from causing a virtual machine crash. + tempfile -------- @@ -806,8 +947,8 @@ tkinter tokenize -------- -* The :mod:`tokenize` module includes the changes introduced in :pep:`701`. ( - Contributed by Marta Gómez Macías and Pablo Galindo in :gh:`102856`.) +* The :mod:`tokenize` module includes the changes introduced in :pep:`701`. + (Contributed by Marta Gómez Macías and Pablo Galindo in :gh:`102856`.) See :ref:`whatsnew312-porting-to-python312` for more information on the changes to the :mod:`tokenize` module. @@ -881,7 +1022,7 @@ unicodedata unittest -------- -Added ``--durations`` command line option, showing the N slowest test cases:: +Add a ``--durations`` command line option, showing the N slowest test cases:: python3 -m unittest --durations=3 lib.tests.test_threading ..... @@ -897,7 +1038,7 @@ Added ``--durations`` command line option, showing the N slowest test cases:: OK (skipped=3) -(Contributed by Giampaolo Rodola in :issue:`4080`) +(Contributed by Giampaolo Rodola in :gh:`48330`) uuid ---- @@ -909,13 +1050,13 @@ uuid Optimizations ============= -* Removed ``wstr`` and ``wstr_length`` members from Unicode objects. +* Remove ``wstr`` and ``wstr_length`` members from Unicode objects. It reduces object size by 8 or 16 bytes on 64bit platform. (:pep:`623`) (Contributed by Inada Naoki in :gh:`92536`.) -* Added experimental support for using the BOLT binary optimizer in the build +* Add experimental support for using the BOLT binary optimizer in the build process, which improves performance by 1-5%. - (Contributed by Kevin Modzelewski in :gh:`90536` and tuned by Dong-hee Na in :gh:`101525`) + (Contributed by Kevin Modzelewski in :gh:`90536` and tuned by Donghee Na in :gh:`101525`) * Speed up the regular expression substitution (functions :func:`re.sub` and :func:`re.subn` and corresponding :class:`!re.Pattern` methods) for @@ -923,7 +1064,7 @@ Optimizations (Contributed by Serhiy Storchaka in :gh:`91524`.) * Speed up :class:`asyncio.Task` creation by deferring expensive string formatting. - (Contributed by Itamar O in :gh:`103793`.) + (Contributed by Itamar Oren in :gh:`103793`.) * The :func:`tokenize.tokenize` and :func:`tokenize.generate_tokens` functions are up to 64% faster as a side effect of the changes required to cover :pep:`701` in @@ -938,17 +1079,38 @@ Optimizations CPython bytecode changes ======================== -* Remove the :opcode:`LOAD_METHOD` instruction. It has been merged into +* Remove the :opcode:`!LOAD_METHOD` instruction. It has been merged into :opcode:`LOAD_ATTR`. :opcode:`LOAD_ATTR` will now behave like the old - :opcode:`LOAD_METHOD` instruction if the low bit of its oparg is set. + :opcode:`!LOAD_METHOD` instruction if the low bit of its oparg is set. (Contributed by Ken Jin in :gh:`93429`.) * Remove the :opcode:`!JUMP_IF_FALSE_OR_POP` and :opcode:`!JUMP_IF_TRUE_OR_POP` instructions. (Contributed by Irit Katriel in :gh:`102859`.) +* Remove the :opcode:`!PRECALL` instruction. (Contributed by Mark Shannon in + :gh:`92925`.) + +* Add the :opcode:`BINARY_SLICE` and :opcode:`STORE_SLICE` instructions. + (Contributed by Mark Shannon in :gh:`94163`.) + +* Add the :opcode:`CALL_INTRINSIC_1` instructions. + (Contributed by Mark Shannon in :gh:`99005`.) + +* Add the :opcode:`CALL_INTRINSIC_2` instruction. + (Contributed by Irit Katriel in :gh:`101799`.) + +* Add the :opcode:`CLEANUP_THROW` instruction. + (Contributed by Brandt Bucher in :gh:`90997`.) + +* Add the :opcode:`!END_SEND` instruction. + (Contributed by Mark Shannon in :gh:`103082`.) + * Add the :opcode:`LOAD_FAST_AND_CLEAR` instruction as part of the implementation of :pep:`709`. (Contributed by Carl Meyer in :gh:`101441`.) +* Add the :opcode:`LOAD_FAST_CHECK` instruction. + (Contributed by Dennis Sweeney in :gh:`93143`.) + * Add the :opcode:`LOAD_FROM_DICT_OR_DEREF`, :opcode:`LOAD_FROM_DICT_OR_GLOBALS`, and :opcode:`LOAD_LOCALS` opcodes as part of the implementation of :pep:`695`. Remove the :opcode:`!LOAD_CLASSDEREF` opcode, which can be replaced with @@ -958,6 +1120,8 @@ CPython bytecode changes * Add the :opcode:`LOAD_SUPER_ATTR` instruction. (Contributed by Carl Meyer and Vladimir Matveev in :gh:`103497`.) +* Add the :opcode:`RETURN_CONST` instruction. (Contributed by Wenyang Wang in :gh:`101632`.) + Demos and Tools =============== @@ -975,83 +1139,191 @@ Demos and Tools Deprecated ========== -* :class:`typing.Hashable` and :class:`typing.Sized` aliases for :class:`collections.abc.Hashable` - and :class:`collections.abc.Sized`. (:gh:`94309`.) +* :mod:`argparse`: The *type*, *choices*, and *metavar* parameters + of :class:`!argparse.BooleanOptionalAction` are deprecated + and will be removed in 3.14. + (Contributed by Nikita Sobolev in :gh:`92248`.) + +* :mod:`ast`: The following :mod:`ast` features have been deprecated in documentation since + Python 3.8, now cause a :exc:`DeprecationWarning` to be emitted at runtime + when they are accessed or used, and will be removed in Python 3.14: -* The :mod:`sqlite3` :ref:`default adapters and converters - ` are now deprecated. - Instead, use the :ref:`sqlite3-adapter-converter-recipes` - and tailor them to your needs. - (Contributed by Erlend E. Aasland in :gh:`90016`.) + * :class:`!ast.Num` + * :class:`!ast.Str` + * :class:`!ast.Bytes` + * :class:`!ast.NameConstant` + * :class:`!ast.Ellipsis` -* In :meth:`~sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted - when :ref:`named placeholders ` are used together with - parameters supplied as a :term:`sequence` instead of as a :class:`dict`. - Starting from Python 3.14, using named placeholders with parameters supplied - as a sequence will raise a :exc:`~sqlite3.ProgrammingError`. - (Contributed by Erlend E. Aasland in :gh:`101698`.) + Use :class:`ast.Constant` instead. + (Contributed by Serhiy Storchaka in :gh:`90953`.) -* The 3-arg signatures (type, value, traceback) of :meth:`~coroutine.throw`, - :meth:`~generator.throw` and :meth:`~agen.athrow` are deprecated and - may be removed in a future version of Python. Use the single-arg versions - of these functions instead. (Contributed by Ofey Chan in :gh:`89874`.) +* :mod:`asyncio`: -* :exc:`DeprecationWarning` is now raised when ``__package__`` on a - module differs from ``__spec__.parent`` (previously it was - :exc:`ImportWarning`). - (Contributed by Brett Cannon in :gh:`65961`.) + * The child watcher classes :class:`asyncio.MultiLoopChildWatcher`, + :class:`asyncio.FastChildWatcher`, :class:`asyncio.AbstractChildWatcher` + and :class:`asyncio.SafeChildWatcher` are deprecated and + will be removed in Python 3.14. + (Contributed by Kumar Aditya in :gh:`94597`.) -* The :meth:`~asyncio.get_event_loop` method of the - default event loop policy now emits a :exc:`DeprecationWarning` if there - is no current event loop set and it decides to create one. - (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.) + * :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`, + :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and + :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated + and will be removed in Python 3.14. + (Contributed by Kumar Aditya in :gh:`94597`.) -* The :mod:`xml.etree.ElementTree` module now emits :exc:`DeprecationWarning` - when testing the truth value of an :class:`xml.etree.ElementTree.Element`. - Before, the Python implementation emitted :exc:`FutureWarning`, and the C - implementation emitted nothing. + * The :meth:`~asyncio.get_event_loop` method of the + default event loop policy now emits a :exc:`DeprecationWarning` if there + is no current event loop set and it decides to create one. + (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.) -* In accordance with :pep:`699`, the ``ma_version_tag`` field in :c:type:`PyDictObject` - is deprecated for extension modules. Accessing this field will generate a compiler - warning at compile time. This field will be removed in Python 3.14. - (Contributed by Ramvikrams and Kumar Aditya in :gh:`101193`. PEP by Ken Jin.) +* :mod:`calendar`: ``calendar.January`` and ``calendar.February`` constants are deprecated and + replaced by :data:`calendar.JANUARY` and :data:`calendar.FEBRUARY`. + (Contributed by Prince Roshan in :gh:`103636`.) -* The ``st_ctime`` fields return by :func:`os.stat` and :func:`os.lstat` on - Windows are deprecated. In a future release, they will contain the last - metadata change time, consistent with other platforms. For now, they still - contain the creation time, which is also available in the new ``st_birthtime`` - field. (Contributed by Steve Dower in :gh:`99726`.) +* :mod:`collections.abc`: Deprecated :class:`collections.abc.ByteString`. + Prefer :class:`Sequence` or :class:`collections.abc.Buffer`. + For use in typing, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. + (Contributed by Shantanu Jain in :gh:`91896`.) -* The :data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback` - fields are deprecated. Use :data:`sys.last_exc` instead. - (Contributed by Irit Katriel in :gh:`102778`.) +* :mod:`datetime`: :class:`datetime.datetime`'s :meth:`~datetime.datetime.utcnow` and + :meth:`~datetime.datetime.utcfromtimestamp` are deprecated and will be + removed in a future version. Instead, use timezone-aware objects to represent + datetimes in UTC: respectively, call :meth:`~datetime.datetime.now` and + :meth:`~datetime.datetime.fromtimestamp` with the *tz* parameter set to + :const:`datetime.UTC`. + (Contributed by Paul Ganssle in :gh:`103857`.) -* The *onerror* argument of :func:`shutil.rmtree` is deprecated as will be removed +* :mod:`email`: Deprecate the *isdst* parameter in :func:`email.utils.localtime`. + (Contributed by Alan Williams in :gh:`72346`.) + +* :mod:`importlib.abc`: Deprecated the following classes, scheduled for removal in + Python 3.14: + + * :class:`!importlib.abc.ResourceReader` + * :class:`!importlib.abc.Traversable` + * :class:`!importlib.abc.TraversableResources` + + Use :mod:`importlib.resources.abc` classes instead: + + * :class:`importlib.resources.abc.Traversable` + * :class:`importlib.resources.abc.TraversableResources` + + (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.) + +* :mod:`itertools`: Deprecate the support for copy, deepcopy, and pickle operations, + which is undocumented, inefficient, historically buggy, and inconsistent. + This will be removed in 3.14 for a significant reduction in code + volume and maintenance burden. + (Contributed by Raymond Hettinger in :gh:`101588`.) + +* :mod:`multiprocessing`: In Python 3.14, the default :mod:`multiprocessing` + start method will change to a safer one on Linux, BSDs, + and other non-macOS POSIX platforms where ``'fork'`` is currently + the default (:gh:`84559`). Adding a runtime warning about this was deemed too + disruptive as the majority of code is not expected to care. Use the + :func:`~multiprocessing.get_context` or + :func:`~multiprocessing.set_start_method` APIs to explicitly specify when + your code *requires* ``'fork'``. See :ref:`contexts and start methods + `. + +* :mod:`pkgutil`: :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` + are deprecated and will be removed in Python 3.14; + use :func:`importlib.util.find_spec` instead. + (Contributed by Nikita Sobolev in :gh:`97850`.) + +* :mod:`pty`: The module has two undocumented ``master_open()`` and ``slave_open()`` + functions that have been deprecated since Python 2 but only gained a + proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14. + (Contributed by Soumendra Ganguly and Gregory P. Smith in :gh:`85984`.) + +* :mod:`os`: + + * The ``st_ctime`` fields return by :func:`os.stat` and :func:`os.lstat` on + Windows are deprecated. In a future release, they will contain the last + metadata change time, consistent with other platforms. For now, they still + contain the creation time, which is also available in the new ``st_birthtime`` + field. (Contributed by Steve Dower in :gh:`99726`.) + + * On POSIX platforms, :func:`os.fork` can now raise a + :exc:`DeprecationWarning` when it can detect being called from a + multithreaded process. There has always been a fundamental incompatibility + with the POSIX platform when doing so. Even if such code *appeared* to work. + We added the warning to to raise awareness as issues encounted by code doing + this are becoming more frequent. See the :func:`os.fork` documentation for + more details along with `this discussion on fork being incompatible with threads + `_ for *why* we're now surfacing this + longstanding platform compatibility problem to developers. + + When this warning appears due to usage of :mod:`multiprocessing` or + :mod:`concurrent.futures` the fix is to use a different + :mod:`multiprocessing` start method such as ``"spawn"`` or ``"forkserver"``. + +* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` is deprecated and will be removed in Python 3.14. Use *onexc* instead. (Contributed by Irit Katriel in :gh:`102828`.) -* Extracting tar archives without specifying *filter* is deprecated until +* :mod:`sqlite3`: + + * :ref:`default adapters and converters + ` are now deprecated. + Instead, use the :ref:`sqlite3-adapter-converter-recipes` + and tailor them to your needs. + (Contributed by Erlend E. Aasland in :gh:`90016`.) + + * In :meth:`~sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted + when :ref:`named placeholders ` are used together with + parameters supplied as a :term:`sequence` instead of as a :class:`dict`. + Starting from Python 3.14, using named placeholders with parameters supplied + as a sequence will raise a :exc:`~sqlite3.ProgrammingError`. + (Contributed by Erlend E. Aasland in :gh:`101698`.) + +* :mod:`sys`: The :data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback` + fields are deprecated. Use :data:`sys.last_exc` instead. + (Contributed by Irit Katriel in :gh:`102778`.) + +* :mod:`tarfile`: Extracting tar archives without specifying *filter* is deprecated until Python 3.14, when ``'data'`` filter will become the default. See :ref:`tarfile-extraction-filter` for details. -* ``calendar.January`` and ``calendar.February`` constants are deprecated and - replaced by :data:`calendar.Month.JANUARY` and :data:`calendar.Month.FEBRUARY`. - (Contributed by Prince Roshan in :gh:`103636`.) +* :mod:`typing`: + + * :class:`typing.Hashable` and :class:`typing.Sized` aliases for :class:`collections.abc.Hashable` + and :class:`collections.abc.Sized`. (:gh:`94309`.) + + * :class:`typing.ByteString`, deprecated since Python 3.9, now causes a + :exc:`DeprecationWarning` to be emitted when it is used. + (Contributed by Alex Waygood in :gh:`91896`.) + +* :mod:`xml.etree.ElementTree`: The module now emits :exc:`DeprecationWarning` + when testing the truth value of an :class:`xml.etree.ElementTree.Element`. + Before, the Python implementation emitted :exc:`FutureWarning`, and the C + implementation emitted nothing. + (Contributed by Jacob Walls in :gh:`83122`.) + +* The 3-arg signatures (type, value, traceback) of :meth:`coroutine throw() + `, :meth:`generator throw() ` and + :meth:`async generator throw() ` are deprecated and + may be removed in a future version of Python. Use the single-arg versions + of these functions instead. (Contributed by Ofey Chan in :gh:`89874`.) + +* :exc:`DeprecationWarning` is now raised when ``__package__`` on a + module differs from ``__spec__.parent`` (previously it was + :exc:`ImportWarning`). + (Contributed by Brett Cannon in :gh:`65961`.) + +* Setting ``__package__`` or ``__cached__`` on a module is deprecated, + and will cease to be set or taken into consideration by the import system in Python 3.14. + (Contributed by Brett Cannon in :gh:`65961`.) * The bitwise inversion operator (``~``) on bool is deprecated. It will throw an error in Python 3.14. Use ``not`` for logical negation of bools instead. In the rare case that you really need the bitwise inversion of the underlying - ``int``, convert to int explicitly with ``~int(x)``. (Contributed by Tim Hoffmann + ``int``, convert to int explicitly: ``~int(x)``. (Contributed by Tim Hoffmann in :gh:`103487`.) -* :class:`datetime.datetime`'s - :meth:`~datetime.datetime.utcnow` and - :meth:`~datetime.datetime.utcfromtimestamp` are deprecated and will be - removed in a future version. Instead, use timezone-aware objects to represent - datetimes in UTC: respectively, call - :meth:`~datetime.datetime.now` and - :meth:`~datetime.datetime.fromtimestamp` with the *tz* parameter set to - :attr:`datetime.UTC`. - (Contributed by Paul Ganssle in :gh:`103857`.) +* Accessing ``co_lnotab`` on code objects was deprecated in Python 3.10 via :pep:`626`, + but it only got a proper :exc:`DeprecationWarning` in 3.12, + therefore it will be removed in 3.14. + (Contributed by Nikita Sobolev in :gh:`101866`.) Pending Removal in Python 3.13 ------------------------------ @@ -1081,6 +1353,10 @@ Modules (see :pep:`594`): * :mod:`!uu` * :mod:`!xdrlib` +Other modules: + +* :mod:`!lib2to3`, and the :program:`2to3` program (:gh:`84540`) + APIs: * :class:`!configparser.LegacyInterpolation` (:gh:`90765`) @@ -1097,89 +1373,62 @@ APIs: Pending Removal in Python 3.14 ------------------------------ -* Deprecated the following :mod:`importlib.abc` classes, scheduled for removal in - Python 3.14: - - * :class:`!importlib.abc.ResourceReader` - * :class:`!importlib.abc.Traversable` - * :class:`!importlib.abc.TraversableResources` +The following APIs have been deprecated +and will be removed in Python 3.14. - Use :mod:`importlib.resources.abc` classes instead: +* :mod:`argparse`: The *type*, *choices*, and *metavar* parameters + of :class:`!argparse.BooleanOptionalAction` - * :class:`importlib.resources.abc.Traversable` - * :class:`importlib.resources.abc.TraversableResources` +* :mod:`ast`: - (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.) + * :class:`!ast.Num` + * :class:`!ast.Str` + * :class:`!ast.Bytes` + * :class:`!ast.NameConstant` + * :class:`!ast.Ellipsis` -* Deprecated :class:`collections.abc.ByteString`. - Prefer :class:`Sequence` or :class:`collections.abc.Buffer`. - For use in typing, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. - (Contributed by Shantanu Jain in :gh:`91896`.) +* :mod:`asyncio`: -* :class:`typing.ByteString`, deprecated since Python 3.9, now causes a - :exc:`DeprecationWarning` to be emitted when it is used. + * :class:`!asyncio.MultiLoopChildWatcher` + * :class:`!asyncio.FastChildWatcher` + * :class:`!asyncio.AbstractChildWatcher` + * :class:`!asyncio.SafeChildWatcher` + * :func:`!asyncio.set_child_watcher` + * :func:`!asyncio.get_child_watcher`, + * :meth:`!asyncio.AbstractEventLoopPolicy.set_child_watcher` + * :meth:`!asyncio.AbstractEventLoopPolicy.get_child_watcher` -* Creating immutable types (:data:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable - bases using the C API. +* :mod:`collections.abc`: :class:`!collections.abc.ByteString`. -* Deprecated the *isdst* parameter in :func:`email.utils.localtime`. - (Contributed by Alan Williams in :gh:`72346`.) +* :mod:`email`: the *isdst* parameter in :func:`email.utils.localtime`. -* ``__package__`` and ``__cached__`` will cease to be set or taken - into consideration by the import system (:gh:`97879`). +* :mod:`importlib.abc`: -* Testing the truth value of an :class:`xml.etree.ElementTree.Element` - is deprecated and will raise an exception in Python 3.14. + * :class:`!importlib.abc.ResourceReader` + * :class:`!importlib.abc.Traversable` + * :class:`!importlib.abc.TraversableResources` -* The default :mod:`multiprocessing` start method will change to a safer one on - Linux, BSDs, and other non-macOS POSIX platforms where ``'fork'`` is currently - the default (:gh:`84559`). Adding a runtime warning about this was deemed too - disruptive as the majority of code is not expected to care. Use the - :func:`~multiprocessing.get_context` or - :func:`~multiprocessing.set_start_method` APIs to explicitly specify when - your code *requires* ``'fork'``. See :ref:`multiprocessing-start-methods`. +* :mod:`itertools`: Support for copy, deepcopy, and pickle operations. -* :mod:`pty` has two undocumented ``master_open()`` and ``slave_open()`` - functions that have been deprecated since Python 2 but only gained a - proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14. +* :mod:`pkgutil`: -* :mod:`itertools` had undocumented, inefficient, historically buggy, - and inconsistent support for copy, deepcopy, and pickle operations. - This will be removed in 3.14 for a significant reduction in code - volume and maintenance burden. - (Contributed by Raymond Hettinger in :gh:`101588`.) + * :func:`!pkgutil.find_loader` + * :func:`!pkgutil.get_loader`. -* Accessing ``co_lnotab`` was deprecated in :pep:`626` since 3.10 - and was planned to be removed in 3.12 - but it only got a proper :exc:`DeprecationWarning` in 3.12. - May be removed in 3.14. - (Contributed by Nikita Sobolev in :gh:`101866`.) +* :mod:`pty`: -* The *onerror* argument of :func:`shutil.rmtree` is deprecated in 3.12, - and will be removed in 3.14. + * :func:`!pty.master_open` + * :func:`!pty.slave_open` -* The *type*, *choices*, and *metavar* parameters - of :class:`!argparse.BooleanOptionalAction` are deprecated - and will be removed in 3.14. - (Contributed by Nikita Sobolev in :gh:`92248`.) +* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` -* :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` - now raise :exc:`DeprecationWarning`; - use :func:`importlib.util.find_spec` instead. - (Contributed by Nikita Sobolev in :gh:`97850`.) +* :mod:`typing`: :class:`!typing.ByteString` -* The following :mod:`ast` features have been deprecated in documentation since - Python 3.8, now cause a :exc:`DeprecationWarning` to be emitted at runtime - when they are accessed or used, and will be removed in Python 3.14: +* :mod:`xml.etree.ElementTree`: Testing the truth value of an :class:`xml.etree.ElementTree.Element`. - * :class:`!ast.Num` - * :class:`!ast.Str` - * :class:`!ast.Bytes` - * :class:`!ast.NameConstant` - * :class:`!ast.Ellipsis` +* The ``__package__`` and ``__cached__`` attributes on module objects. - Use :class:`ast.Constant` instead. - (Contributed by Serhiy Storchaka in :gh:`90953`.) +* The ``co_lnotab`` attribute of code objects. Pending Removal in Future Versions ---------------------------------- @@ -1187,6 +1436,8 @@ Pending Removal in Future Versions The following APIs were deprecated in earlier Python versions and will be removed, although there is currently no date scheduled for their removal. +* :mod:`array`'s ``'u'`` format code (:gh:`57281`) + * :class:`typing.Text` (:gh:`92332`) * Currently Python accepts numeric literals immediately followed by keywords, @@ -1202,68 +1453,17 @@ although there is currently no date scheduled for their removal. Removed ======= -* Remove the ``distutils`` package. It was deprecated in Python 3.10 by - :pep:`632` "Deprecate distutils module". For projects still using - ``distutils`` and cannot be updated to something else, the ``setuptools`` - project can be installed: it still provides ``distutils``. - (Contributed by Victor Stinner in :gh:`92584`.) - -* Remove the bundled setuptools wheel from :mod:`ensurepip`, - and stop installing setuptools in environments created by :mod:`venv`. - - ``pip (>= 22.1)`` does not require setuptools to be installed in the - environment. ``setuptools``-based (and ``distutils``-based) packages - can still be used with ``pip install``, since pip will provide - ``setuptools`` in the build environment it uses for building a - package. - - ``easy_install``, ``pkg_resources``, ``setuptools`` and ``distutils`` - are no longer provided by default in environments created with - ``venv`` or bootstrapped with ``ensurepip``, since they are part of - the ``setuptools`` package. For projects relying on these at runtime, - the ``setuptools`` project should be declared as a dependency and - installed separately (typically, using pip). - - (Contributed by Pradyun Gedam in :gh:`95299`.) - -* Removed many old deprecated :mod:`unittest` features: - - - A number of :class:`~unittest.TestCase` method aliases: - - ============================ =============================== =============== - Deprecated alias Method Name Deprecated in - ============================ =============================== =============== - ``failUnless`` :meth:`.assertTrue` 3.1 - ``failIf`` :meth:`.assertFalse` 3.1 - ``failUnlessEqual`` :meth:`.assertEqual` 3.1 - ``failIfEqual`` :meth:`.assertNotEqual` 3.1 - ``failUnlessAlmostEqual`` :meth:`.assertAlmostEqual` 3.1 - ``failIfAlmostEqual`` :meth:`.assertNotAlmostEqual` 3.1 - ``failUnlessRaises`` :meth:`.assertRaises` 3.1 - ``assert_`` :meth:`.assertTrue` 3.2 - ``assertEquals`` :meth:`.assertEqual` 3.2 - ``assertNotEquals`` :meth:`.assertNotEqual` 3.2 - ``assertAlmostEquals`` :meth:`.assertAlmostEqual` 3.2 - ``assertNotAlmostEquals`` :meth:`.assertNotAlmostEqual` 3.2 - ``assertRegexpMatches`` :meth:`.assertRegex` 3.2 - ``assertRaisesRegexp`` :meth:`.assertRaisesRegex` 3.2 - ``assertNotRegexpMatches`` :meth:`.assertNotRegex` 3.5 - ============================ =============================== =============== - - You can use https://github.com/isidentical/teyit to automatically modernise - your unit tests. - - - Undocumented and broken :class:`~unittest.TestCase` method - ``assertDictContainsSubset`` (deprecated in Python 3.2). - - - Undocumented :meth:`TestLoader.loadTestsFromModule - ` parameter *use_load_tests* - (deprecated and ignored since Python 3.2). +asynchat and asyncore +--------------------- - - An alias of the :class:`~unittest.TextTestResult` class: - ``_TextTestResult`` (deprecated in Python 3.2). +* These two modules have been removed + according to the schedule in :pep:`594`, + having been deprecated in Python 3.6. + Use :mod:`asyncio` instead. + (Contributed by Nikita Sobolev in :gh:`96580`.) - (Contributed by Serhiy Storchaka in :issue:`45162`.) +configparser +------------ * Several names deprecated in the :mod:`configparser` way back in 3.2 have been removed per :gh:`89336`: @@ -1275,87 +1475,70 @@ Removed * :class:`configparser.ConfigParser` no longer has a ``readfp`` method. Use :meth:`~configparser.ConfigParser.read_file` instead. -* The following undocumented :mod:`sqlite3` features, deprecated in Python - 3.10, are now removed: +distutils +--------- - * ``sqlite3.enable_shared_cache()`` - * ``sqlite3.OptimizedUnicode`` +* Remove the :py:mod:`!distutils` package. It was deprecated in Python 3.10 by + :pep:`632` "Deprecate distutils module". For projects still using + ``distutils`` and cannot be updated to something else, the ``setuptools`` + project can be installed: it still provides ``distutils``. + (Contributed by Victor Stinner in :gh:`92584`.) - If a shared cache must be used, open the database in URI mode using the - ``cache=shared`` query parameter. +ensurepip +--------- - The ``sqlite3.OptimizedUnicode`` text factory has been an alias for - :class:`str` since Python 3.3. Code that previously set the text factory to - ``OptimizedUnicode`` can either use ``str`` explicitly, or rely on the - default value which is also ``str``. +* Remove the bundled setuptools wheel from :mod:`ensurepip`, + and stop installing setuptools in environments created by :mod:`venv`. - (Contributed by Erlend E. Aasland in :gh:`92548`.) + ``pip (>= 22.1)`` does not require setuptools to be installed in the + environment. ``setuptools``-based (and ``distutils``-based) packages + can still be used with ``pip install``, since pip will provide + ``setuptools`` in the build environment it uses for building a + package. -* ``smtpd`` has been removed according to the schedule in :pep:`594`, - having been deprecated in Python 3.4.7 and 3.5.4. - Use aiosmtpd_ PyPI module or any other - :mod:`asyncio`-based server instead. - (Contributed by Oleg Iarygin in :gh:`93243`.) + ``easy_install``, ``pkg_resources``, ``setuptools`` and ``distutils`` + are no longer provided by default in environments created with + ``venv`` or bootstrapped with ``ensurepip``, since they are part of + the ``setuptools`` package. For projects relying on these at runtime, + the ``setuptools`` project should be declared as a dependency and + installed separately (typically, using pip). -.. _aiosmtpd: https://pypi.org/project/aiosmtpd/ + (Contributed by Pradyun Gedam in :gh:`95299`.) -* ``asynchat`` and ``asyncore`` have been removed - according to the schedule in :pep:`594`, - having been deprecated in Python 3.6. - Use :mod:`asyncio` instead. - (Contributed by Nikita Sobolev in :gh:`96580`.) +enum +---- -* Remove ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python - 3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) - function is a built-in function. Since Python 3.10, :func:`!_pyio.open` is - also a static method. - (Contributed by Victor Stinner in :gh:`94169`.) +* Remove :mod:`enum`'s ``EnumMeta.__getattr__``, which is no longer needed for + enum attribute access. + (Contributed by Ethan Furman in :gh:`95083`.) -* Remove the :func:`!ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: - use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. - (Contributed by Victor Stinner in :gh:`94199`.) +ftplib +------ + +* Remove :mod:`ftplib`'s ``FTP_TLS.ssl_version`` class attribute: use the + *context* parameter instead. + (Contributed by Victor Stinner in :gh:`94172`.) + +gzip +---- -* :mod:`gzip`: Remove the ``filename`` attribute of :class:`gzip.GzipFile`, +* Remove the ``filename`` attribute of :mod:`gzip`'s :class:`gzip.GzipFile`, deprecated since Python 2.6, use the :attr:`~gzip.GzipFile.name` attribute instead. In write mode, the ``filename`` attribute added ``'.gz'`` file extension if it was not present. (Contributed by Victor Stinner in :gh:`94196`.) -* Remove the :func:`!ssl.match_hostname` function. - It was deprecated in Python 3.7. OpenSSL performs - hostname matching since Python 3.7, Python no longer uses the - :func:`!ssl.match_hostname` function. - (Contributed by Victor Stinner in :gh:`94199`.) - -* Remove the :func:`!locale.format` function, deprecated in Python 3.7: - use :func:`locale.format_string` instead. - (Contributed by Victor Stinner in :gh:`94226`.) +hashlib +------- -* :mod:`hashlib`: Remove the pure Python implementation of +* Remove the pure Python implementation of :mod:`hashlib`'s :func:`hashlib.pbkdf2_hmac()`, deprecated in Python 3.10. Python 3.10 and newer requires OpenSSL 1.1.1 (:pep:`644`): this OpenSSL version provides a C implementation of :func:`~hashlib.pbkdf2_hmac()` which is faster. (Contributed by Victor Stinner in :gh:`94199`.) -* :mod:`xml.etree.ElementTree`: Remove the ``ElementTree.Element.copy()`` method of the - pure Python implementation, deprecated in Python 3.10, use the - :func:`copy.copy` function instead. The C implementation of :mod:`xml.etree.ElementTree` - has no ``copy()`` method, only a ``__copy__()`` method. - (Contributed by Victor Stinner in :gh:`94383`.) - -* :mod:`zipimport`: Remove ``find_loader()`` and ``find_module()`` methods, - deprecated in Python 3.10: use the ``find_spec()`` method instead. See - :pep:`451` for the rationale. - (Contributed by Victor Stinner in :gh:`94379`.) - -* Remove the :func:`!ssl.wrap_socket` function, deprecated in Python 3.7: - instead, create a :class:`ssl.SSLContext` object and call its - :class:`ssl.SSLContext.wrap_socket` method. Any package that still uses - :func:`!ssl.wrap_socket` is broken and insecure. The function neither sends a - SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 - `_: Improper Certificate - Validation. - (Contributed by Victor Stinner in :gh:`94199`.) +importlib +--------- * Many previously deprecated cleanups in :mod:`importlib` have now been completed: @@ -1363,8 +1546,9 @@ Removed * References to, and support for :meth:`!module_repr()` has been removed. (Contributed by Barry Warsaw in :gh:`97850`.) - * ``importlib.util.set_package`` has been removed. (Contributed by Brett - Cannon in :gh:`65961`.) + * ``importlib.util.set_package``, ``importlib.util.set_loader`` and + ``importlib.util.module_for_loader`` have all been removed. (Contributed by + Brett Cannon and Nikita Sobolev in :gh:`65961` and :gh:`97850`.) * Support for ``find_loader()`` and ``find_module()`` APIs have been removed. (Contributed by Barry Warsaw in :gh:`98040`.) @@ -1372,10 +1556,13 @@ Removed * ``importlib.abc.Finder``, ``pkgutil.ImpImporter``, and ``pkgutil.ImpLoader`` have been removed. (Contributed by Barry Warsaw in :gh:`98040`.) - * The :mod:`!imp` module has been removed. (Contributed by Barry Warsaw in - :gh:`98040`.) +imp +--- + +* The :mod:`!imp` module has been removed. (Contributed by Barry Warsaw in + :gh:`98040`.) - * Replace removed :mod:`!imp` functions with :mod:`importlib` functions: + To migrate, consult the following correspondence table: ================================= ======================================= imp importlib @@ -1390,9 +1577,10 @@ Removed ``imp.new_module(name)`` ``types.ModuleType(name)`` ``imp.reload()`` :func:`importlib.reload` ``imp.source_from_cache()`` :func:`importlib.util.source_from_cache` + ``imp.load_source()`` *See below* ================================= ======================================= - * Replace ``imp.load_source()`` with:: + Replace ``imp.load_source()`` with:: import importlib.util import importlib.machinery @@ -1407,23 +1595,159 @@ Removed loader.exec_module(module) return module - * Removed :mod:`!imp` functions and attributes with no replacements: +* Remove :mod:`!imp` functions and attributes with no replacements: + + * Undocumented functions: + + * ``imp.init_builtin()`` + * ``imp.load_compiled()`` + * ``imp.load_dynamic()`` + * ``imp.load_package()`` + + * ``imp.lock_held()``, ``imp.acquire_lock()``, ``imp.release_lock()``: + the locking scheme has changed in Python 3.3 to per-module locks. + * ``imp.find_module()`` constants: ``SEARCH_ERROR``, ``PY_SOURCE``, + ``PY_COMPILED``, ``C_EXTENSION``, ``PY_RESOURCE``, ``PKG_DIRECTORY``, + ``C_BUILTIN``, ``PY_FROZEN``, ``PY_CODERESOURCE``, ``IMP_HOOK``. + +io +-- + +* Remove :mod:`io`'s ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python + 3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) + function is a built-in function. Since Python 3.10, :func:`!_pyio.open` is + also a static method. + (Contributed by Victor Stinner in :gh:`94169`.) + +locale +------ + +* Remove :mod:`locale`'s :func:`!locale.format` function, deprecated in Python 3.7: + use :func:`locale.format_string` instead. + (Contributed by Victor Stinner in :gh:`94226`.) + +* ``smtpd``: The module has been removed according to the schedule in :pep:`594`, + having been deprecated in Python 3.4.7 and 3.5.4. + Use aiosmtpd_ PyPI module or any other + :mod:`asyncio`-based server instead. + (Contributed by Oleg Iarygin in :gh:`93243`.) + +.. _aiosmtpd: https://pypi.org/project/aiosmtpd/ + +sqlite3 +------- + +* The following undocumented :mod:`sqlite3` features, deprecated in Python + 3.10, are now removed: + + * ``sqlite3.enable_shared_cache()`` + * ``sqlite3.OptimizedUnicode`` + + If a shared cache must be used, open the database in URI mode using the + ``cache=shared`` query parameter. + + The ``sqlite3.OptimizedUnicode`` text factory has been an alias for + :class:`str` since Python 3.3. Code that previously set the text factory to + ``OptimizedUnicode`` can either use ``str`` explicitly, or rely on the + default value which is also ``str``. + + (Contributed by Erlend E. Aasland in :gh:`92548`.) + +ssl +--- + +* Remove :mod:`ssl`'s :func:`!ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: + use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Remove the :func:`!ssl.match_hostname` function. + It was deprecated in Python 3.7. OpenSSL performs + hostname matching since Python 3.7, Python no longer uses the + :func:`!ssl.match_hostname` function. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Remove the :func:`!ssl.wrap_socket` function, deprecated in Python 3.7: + instead, create a :class:`ssl.SSLContext` object and call its + :class:`ssl.SSLContext.wrap_socket` method. Any package that still uses + :func:`!ssl.wrap_socket` is broken and insecure. The function neither sends a + SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 + `_: Improper Certificate + Validation. + (Contributed by Victor Stinner in :gh:`94199`.) + +unittest +-------- + +* Remove many long-deprecated :mod:`unittest` features: + + .. _unittest-TestCase-removed-aliases: + + * A number of :class:`~unittest.TestCase` method aliases: + + ============================ =============================== =============== + Deprecated alias Method Name Deprecated in + ============================ =============================== =============== + ``failUnless`` :meth:`.assertTrue` 3.1 + ``failIf`` :meth:`.assertFalse` 3.1 + ``failUnlessEqual`` :meth:`.assertEqual` 3.1 + ``failIfEqual`` :meth:`.assertNotEqual` 3.1 + ``failUnlessAlmostEqual`` :meth:`.assertAlmostEqual` 3.1 + ``failIfAlmostEqual`` :meth:`.assertNotAlmostEqual` 3.1 + ``failUnlessRaises`` :meth:`.assertRaises` 3.1 + ``assert_`` :meth:`.assertTrue` 3.2 + ``assertEquals`` :meth:`.assertEqual` 3.2 + ``assertNotEquals`` :meth:`.assertNotEqual` 3.2 + ``assertAlmostEquals`` :meth:`.assertAlmostEqual` 3.2 + ``assertNotAlmostEquals`` :meth:`.assertNotAlmostEqual` 3.2 + ``assertRegexpMatches`` :meth:`.assertRegex` 3.2 + ``assertRaisesRegexp`` :meth:`.assertRaisesRegex` 3.2 + ``assertNotRegexpMatches`` :meth:`.assertNotRegex` 3.5 + ============================ =============================== =============== + + You can use https://github.com/isidentical/teyit to automatically modernise + your unit tests. + + * Undocumented and broken :class:`~unittest.TestCase` method + ``assertDictContainsSubset`` (deprecated in Python 3.2). + + * Undocumented :meth:`TestLoader.loadTestsFromModule + ` parameter *use_load_tests* + (deprecated and ignored since Python 3.2). + + * An alias of the :class:`~unittest.TextTestResult` class: + ``_TextTestResult`` (deprecated in Python 3.2). + + (Contributed by Serhiy Storchaka in :gh:`89325`.) + +webbrowser +---------- + +* Remove support for obsolete browsers from :mod:`webbrowser`. + The removed browsers include: Grail, Mosaic, Netscape, Galeon, Skipstone, + Iceape, Firebird, and Firefox versions 35 and below (:gh:`102871`). + +xml.etree.ElementTree +--------------------- + +* Remove the ``ElementTree.Element.copy()`` method of the + pure Python implementation, deprecated in Python 3.10, use the + :func:`copy.copy` function instead. The C implementation of :mod:`xml.etree.ElementTree` + has no ``copy()`` method, only a ``__copy__()`` method. + (Contributed by Victor Stinner in :gh:`94383`.) - * undocumented functions: +zipimport +--------- - * ``imp.init_builtin()`` - * ``imp.load_compiled()`` - * ``imp.load_dynamic()`` - * ``imp.load_package()`` +* Remove :mod:`zipimport`'s ``find_loader()`` and ``find_module()`` methods, + deprecated in Python 3.10: use the ``find_spec()`` method instead. See + :pep:`451` for the rationale. + (Contributed by Victor Stinner in :gh:`94379`.) - * ``imp.lock_held()``, ``imp.acquire_lock()``, ``imp.release_lock()``: - the locking scheme has changed in Python 3.3 to per-module locks. - * ``imp.find_module()`` constants: ``SEARCH_ERROR``, ``PY_SOURCE``, - ``PY_COMPILED``, ``C_EXTENSION``, ``PY_RESOURCE``, ``PKG_DIRECTORY``, - ``C_BUILTIN``, ``PY_FROZEN``, ``PY_CODERESOURCE``, ``IMP_HOOK``. +Others +------ -* Removed the ``suspicious`` rule from the documentation Makefile, and - removed ``Doc/tools/rstlint.py``, both in favor of `sphinx-lint +* Remove the ``suspicious`` rule from the documentation :file:`Makefile` and + :file:`Doc/tools/rstlint.py`, both in favor of `sphinx-lint `_. (Contributed by Julien Palard in :gh:`98179`.) @@ -1435,15 +1759,6 @@ Removed (*ssl_context* in :mod:`imaplib`) instead. (Contributed by Victor Stinner in :gh:`94172`.) -* :mod:`ftplib`: Remove the ``FTP_TLS.ssl_version`` class attribute: use the - *context* parameter instead. - (Contributed by Victor Stinner in :gh:`94172`.) - -* Remove support for obsolete browsers from :mod:`webbrowser`. - Removed browsers include: Grail, Mosaic, Netscape, Galeon, Skipstone, - Iceape, Firebird, and Firefox versions 35 and below (:gh:`102871`). - - .. _whatsnew312-porting-to-python312: Porting to Python 3.12 @@ -1462,9 +1777,9 @@ Changes in the Python API contain ASCII letters and digits and underscore. (Contributed by Serhiy Storchaka in :gh:`91760`.) -* Removed ``randrange()`` functionality deprecated since Python 3.10. Formerly, +* Remove ``randrange()`` functionality deprecated since Python 3.10. Formerly, ``randrange(10.0)`` losslessly converted to ``randrange(10)``. Now, it raises a - :exc:`TypeError`. Also, the exception raised for non-integral values such as + :exc:`TypeError`. Also, the exception raised for non-integer values such as ``randrange(10.5)`` or ``randrange('10')`` has been changed from :exc:`ValueError` to :exc:`TypeError`. This also prevents bugs where ``randrange(1e25)`` would silently select from a larger range than ``randrange(10**25)``. @@ -1476,7 +1791,7 @@ Changes in the Python API to :term:`filesystem encoding and error handler`. Argument files should be encoded in UTF-8 instead of ANSI Codepage on Windows. -* Removed the ``asyncore``-based ``smtpd`` module deprecated in Python 3.4.7 +* Remove the ``asyncore``-based ``smtpd`` module deprecated in Python 3.4.7 and 3.5.4. A recommended replacement is the :mod:`asyncio`-based aiosmtpd_ PyPI module. @@ -1497,7 +1812,7 @@ Changes in the Python API so only a very small set of users might be affected. This change helps with interpreter isolation. Furthermore, :mod:`syslog` is a wrapper around process-global resources, which are best managed from the main interpreter. - (Contributed by Dong-hee Na in :gh:`99127`.) + (Contributed by Donghee Na in :gh:`99127`.) * The undocumented locking behavior of :func:`~functools.cached_property` is removed, because it locked across all instances of the class, leading to high @@ -1521,7 +1836,7 @@ Changes in the Python API functions is now changed due to the changes introduced in :pep:`701`. This means that ``STRING`` tokens are not emitted any more for f-strings and the tokens described in :pep:`701` are now produced instead: ``FSTRING_START``, - ``FSRING_MIDDLE`` and ``FSTRING_END`` are now emitted for f-string "string" + ``FSTRING_MIDDLE`` and ``FSTRING_END`` are now emitted for f-string "string" parts in addition to the appropriate tokens for the tokenization in the expression components. For example for the f-string ``f"start {1+1} end"`` the old version of the tokenizer emitted:: @@ -1540,7 +1855,7 @@ Changes in the Python API 1,13-1,17: FSTRING_MIDDLE ' end' 1,17-1,18: FSTRING_END '"' - Additionally, there may be some minor behavioral changes as a consecuence of the + Additionally, there may be some minor behavioral changes as a consequence of the changes required to support :pep:`701`. Some of these changes include: * The ``type`` attribute of the tokens emitted when tokenizing some invalid Python @@ -1558,9 +1873,9 @@ Changes in the Python API Build Changes ============= -* Python no longer uses ``setup.py`` to build shared C extension modules. +* Python no longer uses :file:`setup.py` to build shared C extension modules. Build parameters like headers and libraries are detected in ``configure`` - script. Extensions are built by ``Makefile``. Most extensions use + script. Extensions are built by :file:`Makefile`. Most extensions use ``pkg-config`` and fall back to manual detection. (Contributed by Christian Heimes in :gh:`93939`.) @@ -1571,9 +1886,9 @@ Build Changes * CPython now uses the ThinLTO option as the default link time optimization policy if the Clang compiler accepts the flag. - (Contributed by Dong-hee Na in :gh:`89536`.) + (Contributed by Donghee Na in :gh:`89536`.) -* Add ``COMPILEALL_OPTS`` variable in Makefile to override :mod:`compileall` +* Add ``COMPILEALL_OPTS`` variable in :file:`Makefile` to override :mod:`compileall` options (default: ``-j0``) in ``make install``. Also merged the 3 ``compileall`` commands into a single command to build .pyc files for all optimization levels (0, 1, 2) at once. @@ -1600,8 +1915,9 @@ C API Changes New Features ------------ +.. _whatsnew312-pep697: -* :pep:`697`: Introduced the :ref:`Unstable C API tier `, +* :pep:`697`: Introduce the :ref:`Unstable C API tier `, intended for low-level tools like debuggers and JIT compilers. This API may change in each minor release of CPython without deprecation warnings. @@ -1623,14 +1939,14 @@ New Features (Contributed by Petr Viktorin in :gh:`101101`.) -* :pep:`697`: Added API for extending types whose instance memory layout is +* :pep:`697`: Add an API for extending types whose instance memory layout is opaque: - :c:member:`PyType_Spec.basicsize` can be zero or negative to specify inheriting or extending the base class size. - :c:func:`PyObject_GetTypeData` and :c:func:`PyType_GetTypeDataSize` added to allow access to subclass-specific instance data. - - :const:`Py_TPFLAGS_ITEMS_AT_END` and :c:func:`PyObject_GetItemData` + - :c:macro:`Py_TPFLAGS_ITEMS_AT_END` and :c:func:`PyObject_GetItemData` added to allow safely extending certain variable-sized types, including :c:var:`PyType_Type`. - :c:macro:`Py_RELATIVE_OFFSET` added to allow defining @@ -1638,7 +1954,7 @@ New Features (Contributed by Petr Viktorin in :gh:`103509`.) -* Added the new :ref:`limited C API ` function :c:func:`PyType_FromMetaclass`, +* Add the new :ref:`limited C API ` function :c:func:`PyType_FromMetaclass`, which generalizes the existing :c:func:`PyType_FromModuleAndSpec` using an additional metaclass argument. (Contributed by Wenzel Jakob in :gh:`93012`.) @@ -1647,20 +1963,20 @@ New Features :ref:`the vectorcall protocol ` was added to the :ref:`Limited API `: - * :const:`Py_TPFLAGS_HAVE_VECTORCALL` + * :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` * :c:func:`PyVectorcall_NARGS` * :c:func:`PyVectorcall_Call` * :c:type:`vectorcallfunc` - The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class + The :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class when the class's :py:meth:`~object.__call__` method is reassigned. This makes vectorcall safe to use with mutable types (i.e. heap types - without the immutable flag, :const:`Py_TPFLAGS_IMMUTABLETYPE`). + without the immutable flag, :c:macro:`Py_TPFLAGS_IMMUTABLETYPE`). Mutable types that do not override :c:member:`~PyTypeObject.tp_call` now inherit the ``Py_TPFLAGS_HAVE_VECTORCALL`` flag. (Contributed by Petr Viktorin in :gh:`93274`.) - The :const:`Py_TPFLAGS_MANAGED_DICT` and :const:`Py_TPFLAGS_MANAGED_WEAKREF` + The :c:macro:`Py_TPFLAGS_MANAGED_DICT` and :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` flags have been added. This allows extensions classes to support object ``__dict__`` and weakrefs with less bookkeeping, using less memory and with faster access. @@ -1671,19 +1987,19 @@ New Features * :c:func:`PyObject_Vectorcall` * :c:func:`PyObject_VectorcallMethod` - * :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` + * :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET` This means that both the incoming and outgoing ends of the vector call protocol are now available in the :ref:`Limited API `. (Contributed by Wenzel Jakob in :gh:`98586`.) -* Added two new public functions, +* Add two new public functions, :c:func:`PyEval_SetProfileAllThreads` and :c:func:`PyEval_SetTraceAllThreads`, that allow to set tracing and profiling functions in all running threads in addition to the calling one. (Contributed by Pablo Galindo in :gh:`93503`.) -* Added new function :c:func:`PyFunction_SetVectorcall` to the C API +* Add new function :c:func:`PyFunction_SetVectorcall` to the C API which sets the vectorcall field of a given :c:type:`PyFunctionObject`. (Contributed by Andrew Frost in :gh:`92257`.) @@ -1693,14 +2009,14 @@ New Features compilers, or debuggers. (Contributed by Carl Meyer in :gh:`91052`.) -* Added :c:func:`PyType_AddWatcher` and :c:func:`PyType_Watch` API to register +* Add :c:func:`PyType_AddWatcher` and :c:func:`PyType_Watch` API to register callbacks to receive notification on changes to a type. (Contributed by Carl Meyer in :gh:`91051`.) -* Added :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` +* Add :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` APIs to register callbacks to receive notification on creation and destruction of code objects. - (Contributed by Itamar Ostricher in :gh:`91054`.) + (Contributed by Itamar Oren in :gh:`91054`.) * Add :c:func:`PyFrame_GetVar` and :c:func:`PyFrame_GetVarString` functions to get a frame variable by its name. @@ -1727,8 +2043,10 @@ New Features to replace the legacy-api :c:func:`!PyErr_Display`. (Contributed by Irit Katriel in :gh:`102755`). -* :pep:`683`: Introduced Immortal Objects to Python which allows objects - to bypass reference counts and introduced changes to the C-API: +.. _whatsnew312-pep683: + +* :pep:`683`: Introduce *Immortal Objects*, which allows objects + to bypass reference counts, and related changes to the C-API: - ``_Py_IMMORTAL_REFCNT``: The reference count that defines an object as immortal. @@ -1740,11 +2058,17 @@ New Features - ``SSTATE_INTERNED_IMMORTAL_STATIC`` An identifier for interned unicode objects that are immortal and static - ``sys.getunicodeinternedsize`` This returns the total number of unicode - objects that have been interned. This is now needed for refleak.py to + objects that have been interned. This is now needed for :file:`refleak.py` to correctly track reference counts and allocated blocks (Contributed by Eddie Elizondo in :gh:`84436`.) +* :pep:`684`: Add the new :c:func:`Py_NewInterpreterFromConfig` + function and :c:type:`PyInterpreterConfig`, which may be used + to create sub-interpreters with their own GILs. + (See :ref:`whatsnew312-pep684` for more info.) + (Contributed by Eric Snow in :gh:`104110`.) + * In the limited C API version 3.12, :c:func:`Py_INCREF` and :c:func:`Py_DECREF` functions are now implemented as opaque function calls to hide implementation details. @@ -1777,7 +2101,7 @@ Porting to Python 3.12 for example). * Add support of more formatting options (left aligning, octals, uppercase - hexadecimals, ``intmax_t``, ``ptrdiff_t``, ``wchar_t`` C + hexadecimals, :c:type:`intmax_t`, :c:type:`ptrdiff_t`, :c:type:`wchar_t` C strings, variable width and precision) in :c:func:`PyUnicode_FromFormat` and :c:func:`PyUnicode_FromFormatV`. (Contributed by Serhiy Storchaka in :gh:`98836`.) @@ -1788,18 +2112,18 @@ Porting to Python 3.12 copied as-is to the result string, and any extra arguments discarded. (Contributed by Serhiy Storchaka in :gh:`95781`.) -* Fixed wrong sign placement in :c:func:`PyUnicode_FromFormat` and +* Fix wrong sign placement in :c:func:`PyUnicode_FromFormat` and :c:func:`PyUnicode_FromFormatV`. (Contributed by Philip Georgi in :gh:`95504`.) * Extension classes wanting to add a ``__dict__`` or weak reference slot - should use :const:`Py_TPFLAGS_MANAGED_DICT` and - :const:`Py_TPFLAGS_MANAGED_WEAKREF` instead of ``tp_dictoffset`` and + should use :c:macro:`Py_TPFLAGS_MANAGED_DICT` and + :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead of ``tp_dictoffset`` and ``tp_weaklistoffset``, respectively. The use of ``tp_dictoffset`` and ``tp_weaklistoffset`` is still supported, but does not fully support multiple inheritance (:gh:`95589`), and performance may be worse. - Classes declaring :const:`Py_TPFLAGS_MANAGED_DICT` should call + Classes declaring :c:macro:`Py_TPFLAGS_MANAGED_DICT` must call :c:func:`!_PyObject_VisitManagedDict` and :c:func:`!_PyObject_ClearManagedDict` to traverse and clear their instance's dictionaries. To clear weakrefs, call :c:func:`PyObject_ClearWeakRefs`, as before. @@ -1853,7 +2177,7 @@ Porting to Python 3.12 :c:member:`~PyTypeObject.tp_init` instead. - If the metaclass doesn't need to be instantiated from Python, set its ``tp_new`` to ``NULL`` using - the :const:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. + the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. This makes it acceptable for ``PyType_From*`` functions. - Avoid ``PyType_From*`` functions: if you don't need C-specific features @@ -1872,9 +2196,32 @@ Porting to Python 3.12 subinterpreter that they don't support (or haven't yet been loaded in). See :gh:`104668` for more info. +* :c:struct:`PyLongObject` has had its internals changed for better performance. + Although the internals of :c:struct:`PyLongObject` are private, they are used + by some extension modules. + The internal fields should no longer be accessed directly, instead the API + functions beginning ``PyLong_...`` should be used instead. + Two new *unstable* API functions are provided for efficient access to the + value of :c:struct:`PyLongObject`\s which fit into a single machine word: + + * :c:func:`PyUnstable_Long_IsCompact` + * :c:func:`PyUnstable_Long_CompactValue` + +* Custom allocators, set via :c:func:`PyMem_SetAllocator`, are now + required to be thread-safe, regardless of memory domain. Allocators + that don't have their own state, including "hooks", are not affected. + If your custom allocator is not already thread-safe and you need + guidance then please create a new GitHub issue + and CC ``@ericsnowcurrently``. + Deprecated ---------- +* In accordance with :pep:`699`, the ``ma_version_tag`` field in :c:type:`PyDictObject` + is deprecated for extension modules. Accessing this field will generate a compiler + warning at compile time. This field will be removed in Python 3.14. + (Contributed by Ramvikrams and Kumar Aditya in :gh:`101193`. PEP by Ken Jin.) + * Deprecate global configuration variable: * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` @@ -1904,13 +2251,13 @@ Deprecated :c:type:`PyConfig` instead. (Contributed by Victor Stinner in :gh:`77782`.) -* Creating immutable types (:const:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable - bases is deprecated and will be disabled in Python 3.14. +* Creating :c:data:`immutable types ` with mutable + bases is deprecated and will be disabled in Python 3.14. (:gh:`95388`) -* The ``structmember.h`` header is deprecated, though it continues to be +* The :file:`structmember.h` header is deprecated, though it continues to be available and there are no plans to remove it. - Its contents are now available just by including ``Python.h``, + Its contents are now available just by including :file:`Python.h`, with a ``Py`` prefix added if it was missing: - :c:struct:`PyMemberDef`, :c:func:`PyMember_GetOne` and @@ -1920,14 +2267,14 @@ Deprecated - The flags :c:macro:`Py_READONLY` (previously ``READONLY``) and :c:macro:`Py_AUDIT_READ` (previously all uppercase) - Several items are not exposed from ``Python.h``: + Several items are not exposed from :file:`Python.h`: - :c:macro:`T_OBJECT` (use :c:macro:`Py_T_OBJECT_EX`) - :c:macro:`T_NONE` (previously undocumented, and pretty quirky) - The macro ``WRITE_RESTRICTED`` which does nothing. - The macros ``RESTRICTED`` and ``READ_RESTRICTED``, equivalents of :c:macro:`Py_AUDIT_READ`. - - In some configurations, ```` is not included from ``Python.h``. + - In some configurations, ```` is not included from :file:`Python.h`. It should be included manually when using ``offsetof()``. The deprecated header continues to provide its original @@ -1954,25 +2301,112 @@ Deprecated overrides :c:member:`~PyTypeObject.tp_new` is deprecated. Call the metaclass instead. +Pending Removal in Python 3.14 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* The ``ma_version_tag`` field in :c:type:`PyDictObject` for extension modules + (:pep:`699`; :gh:`101193`). + +* Global configuration variables: + + * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` + * :c:var:`Py_VerboseFlag`: use :c:member:`PyConfig.verbose` + * :c:var:`Py_QuietFlag`: use :c:member:`PyConfig.quiet` + * :c:var:`Py_InteractiveFlag`: use :c:member:`PyConfig.interactive` + * :c:var:`Py_InspectFlag`: use :c:member:`PyConfig.inspect` + * :c:var:`Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level` + * :c:var:`Py_NoSiteFlag`: use :c:member:`PyConfig.site_import` + * :c:var:`Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning` + * :c:var:`Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings` + * :c:var:`Py_IgnoreEnvironmentFlag`: use :c:member:`PyConfig.use_environment` + * :c:var:`Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode` + * :c:var:`Py_NoUserSiteDirectory`: use :c:member:`PyConfig.user_site_directory` + * :c:var:`Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio` + * :c:var:`Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed` + and :c:member:`PyConfig.hash_seed` + * :c:var:`Py_IsolatedFlag`: use :c:member:`PyConfig.isolated` + * :c:var:`Py_LegacyWindowsFSEncodingFlag`: use :c:member:`PyPreConfig.legacy_windows_fs_encoding` + * :c:var:`Py_LegacyWindowsStdioFlag`: use :c:member:`PyConfig.legacy_windows_stdio` + * :c:var:`!Py_FileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_HasFileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_FileSystemDefaultEncodeErrors`: use :c:member:`PyConfig.filesystem_errors` + * :c:var:`!Py_UTF8Mode`: use :c:member:`PyPreConfig.utf8_mode` (see :c:func:`Py_PreInitialize`) + + The :c:func:`Py_InitializeFromConfig` API should be used with + :c:type:`PyConfig` instead. + +* Creating :c:data:`immutable types ` with mutable + bases (:gh:`95388`). + +Pending Removal in Python 3.15 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* :c:func:`PyImport_ImportModuleNoBlock`: use :c:func:`PyImport_ImportModule` +* :c:type:`!Py_UNICODE_WIDE` type: use :c:type:`wchar_t` +* :c:type:`Py_UNICODE` type: use :c:type:`wchar_t` +* Python initialization functions: + + * :c:func:`PySys_ResetWarnOptions`: clear :data:`sys.warnoptions` and + :data:`!warnings.filters` + * :c:func:`Py_GetExecPrefix`: get :data:`sys.exec_prefix` + * :c:func:`Py_GetPath`: get :data:`sys.path` + * :c:func:`Py_GetPrefix`: get :data:`sys.prefix` + * :c:func:`Py_GetProgramFullPath`: get :data:`sys.executable` + * :c:func:`Py_GetProgramName`: get :data:`sys.executable` + * :c:func:`Py_GetPythonHome`: get :c:member:`PyConfig.home` or + the :envvar:`PYTHONHOME` environment variable + +Pending Removal in Future Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following APIs are deprecated and will be removed, +although there is currently no date scheduled for their removal. + +* :c:macro:`Py_TPFLAGS_HAVE_FINALIZE`: unneeded since Python 3.8 +* :c:func:`PyErr_Fetch`: use :c:func:`PyErr_GetRaisedException` +* :c:func:`PyErr_NormalizeException`: use :c:func:`PyErr_GetRaisedException` +* :c:func:`PyErr_Restore`: use :c:func:`PyErr_SetRaisedException` +* :c:func:`PyModule_GetFilename`: use :c:func:`PyModule_GetFilenameObject` +* :c:func:`PyOS_AfterFork`: use :c:func:`PyOS_AfterFork_Child` +* :c:func:`PySlice_GetIndicesEx`: use :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` +* :c:func:`!PyUnicode_AsDecodedObject`: use :c:func:`PyCodec_Decode` +* :c:func:`!PyUnicode_AsDecodedUnicode`: use :c:func:`PyCodec_Decode` +* :c:func:`!PyUnicode_AsEncodedObject`: use :c:func:`PyCodec_Encode` +* :c:func:`!PyUnicode_AsEncodedUnicode`: use :c:func:`PyCodec_Encode` +* :c:func:`PyUnicode_READY`: unneeded since Python 3.12 +* :c:func:`!PyErr_Display`: use :c:func:`PyErr_DisplayException` +* :c:func:`!_PyErr_ChainExceptions`: use ``_PyErr_ChainExceptions1`` +* :c:member:`!PyBytesObject.ob_shash` member: + call :c:func:`PyObject_Hash` instead +* :c:member:`!PyDictObject.ma_version_tag` member +* Thread Local Storage (TLS) API: + + * :c:func:`PyThread_create_key`: use :c:func:`PyThread_tss_alloc` + * :c:func:`PyThread_delete_key`: use :c:func:`PyThread_tss_free` + * :c:func:`PyThread_set_key_value`: use :c:func:`PyThread_tss_set` + * :c:func:`PyThread_get_key_value`: use :c:func:`PyThread_tss_get` + * :c:func:`PyThread_delete_key_value`: use :c:func:`PyThread_tss_delete` + * :c:func:`PyThread_ReInitTLS`: unneeded since Python 3.7 + Removed ------- -* Remove the ``token.h`` header file. There was never any public tokenizer C - API. The ``token.h`` header file was only designed to be used by Python +* Remove the :file:`token.h` header file. There was never any public tokenizer C + API. The :file:`token.h` header file was only designed to be used by Python internals. (Contributed by Victor Stinner in :gh:`92651`.) * Legacy Unicode APIs have been removed. See :pep:`623` for detail. - * :c:macro:`!PyUnicode_WCHAR_KIND` - * :c:func:`!PyUnicode_AS_UNICODE` - * :c:func:`!PyUnicode_AsUnicode` - * :c:func:`!PyUnicode_AsUnicodeAndSize` - * :c:func:`!PyUnicode_AS_DATA` - * :c:func:`!PyUnicode_FromUnicode` - * :c:func:`!PyUnicode_GET_SIZE` - * :c:func:`!PyUnicode_GetSize` - * :c:func:`!PyUnicode_GET_DATA_SIZE` + * :c:macro:`!PyUnicode_WCHAR_KIND` + * :c:func:`!PyUnicode_AS_UNICODE` + * :c:func:`!PyUnicode_AsUnicode` + * :c:func:`!PyUnicode_AsUnicodeAndSize` + * :c:func:`!PyUnicode_AS_DATA` + * :c:func:`!PyUnicode_FromUnicode` + * :c:func:`!PyUnicode_GET_SIZE` + * :c:func:`!PyUnicode_GetSize` + * :c:func:`!PyUnicode_GET_DATA_SIZE` * Remove the ``PyUnicode_InternImmortal()`` function macro. (Contributed by Victor Stinner in :gh:`85858`.) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 479d08b24b112a..dfce976fbb50ee 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -3,8 +3,7 @@ What's New In Python 3.13 **************************** -:Release: |release| -:Date: |today| +:Editor: TBD .. Rules for maintenance: @@ -86,6 +85,22 @@ Other Language Changes This change will affect tools using docstrings, like :mod:`doctest`. (Contributed by Inada Naoki in :gh:`81283`.) +* The :func:`compile` built-in can now accept a new flag, + ``ast.PyCF_OPTIMIZED_AST``, which is similar to ``ast.PyCF_ONLY_AST`` + except that the returned ``AST`` is optimized according to the value + of the ``optimize`` argument. + (Contributed by Irit Katriel in :gh:`108113`). + +* :mod:`multiprocessing`, :mod:`concurrent.futures`, :mod:`compileall`: + Replace :func:`os.cpu_count` with :func:`os.process_cpu_count` to select the + default number of worker threads and processes. Get the CPU affinity + if supported. + (Contributed by Victor Stinner in :gh:`109649`.) + +* :func:`os.path.realpath` now resolves MS-DOS style file names even if + the file is not accessible. + (Contributed by Moonsik Park in :gh:`82367`.) + New Modules =========== @@ -95,6 +110,14 @@ New Modules Improved Modules ================ +ast +--- + +* :func:`ast.parse` now accepts an optional argument ``optimize`` + which is passed on to the :func:`compile` built-in. This makes it + possible to obtain an optimized ``AST``. + (Contributed by Irit Katriel in :gh:`108113`). + array ----- @@ -102,6 +125,33 @@ array It can be used instead of ``'u'`` type code, which is deprecated. (Contributed by Inada Naoki in :gh:`80480`.) +copy +---- + +* Add :func:`copy.replace` function which allows to create a modified copy of + an object, which is especially useful for immutable objects. + It supports named tuples created with the factory function + :func:`collections.namedtuple`, :class:`~dataclasses.dataclass` instances, + various :mod:`datetime` objects, :class:`~inspect.Signature` objects, + :class:`~inspect.Parameter` objects, :ref:`code object `, and + any user classes which define the :meth:`!__replace__` method. + (Contributed by Serhiy Storchaka in :gh:`108751`.) + +dbm +--- + +* Add :meth:`dbm.gnu.gdbm.clear` and :meth:`dbm.ndbm.ndbm.clear` methods that remove all items + from the database. + (Contributed by Donghee Na in :gh:`107122`.) + +doctest +------- + +* The :meth:`doctest.DocTestRunner.run` method now counts the number of skipped + tests. Add :attr:`doctest.DocTestRunner.skips` and + :attr:`doctest.TestResults.skipped` attributes. + (Contributed by Victor Stinner in :gh:`108794`.) + io -- @@ -111,6 +161,39 @@ and only logged in :ref:`Python Development Mode ` or on :ref:`Python built on debug mode `. (Contributed by Victor Stinner in :gh:`62948`.) +opcode +------ + +* Move ``opcode.ENABLE_SPECIALIZATION`` to ``_opcode.ENABLE_SPECIALIZATION``. + This field was added in 3.12, it was never documented and is not intended for + external usage. (Contributed by Irit Katriel in :gh:`105481`.) + +* Removed ``opcode.is_pseudo``, ``opcode.MIN_PSEUDO_OPCODE`` and + ``opcode.MAX_PSEUDO_OPCODE``, which were added in 3.12, were never + documented or exposed through ``dis``, and were not intended to be + used externally. + +os +-- + +* Add :func:`os.process_cpu_count` function to get the number of logical CPUs + usable by the calling thread of the current process. + (Contributed by Victor Stinner in :gh:`109649`.) + +* Add a low level interface for Linux's timer notification file descriptors + via :func:`os.timerfd_create`, + :func:`os.timerfd_settime`, :func:`os.timerfd_settime_ns`, + :func:`os.timerfd_gettime`, and :func:`os.timerfd_gettime_ns`, + :const:`os.TFD_NONBLOCK`, :const:`os.TFD_CLOEXEC`, + :const:`os.TFD_TIMER_ABSTIME`, and :const:`os.TFD_TIMER_CANCEL_ON_SET` + (Contributed by Masaru Tsuchiyama in :gh:`108277`.) + +* :func:`os.cpu_count` and :func:`os.process_cpu_count` can be overridden through + the new environment variable :envvar:`PYTHON_CPU_COUNT` or the new command-line option + :option:`-X cpu_count <-X>`. This option is useful for users who need to limit + CPU resources of a container system without having to modify the container (application code). + (Contributed by Donghee Na in :gh:`109595`) + pathlib ------- @@ -118,6 +201,10 @@ pathlib :exc:`NotImplementedError` when a path operation isn't supported. (Contributed by Barney Gale in :gh:`89812`.) +* Add :meth:`pathlib.Path.from_uri`, a new constructor to create a :class:`pathlib.Path` + object from a 'file' URI (``file:/``). + (Contributed by Barney Gale in :gh:`107465`.) + * Add support for recursive wildcards in :meth:`pathlib.PurePath.match`. (Contributed by Barney Gale in :gh:`73435`.) @@ -126,10 +213,37 @@ pathlib :meth:`~pathlib.Path.is_dir`. (Contributed by Barney Gale in :gh:`77609` and :gh:`105793`.) +pdb +--- + +* Add ability to move between chained exceptions during post mortem debugging in :func:`~pdb.pm` using + the new ``exceptions [exc_number]`` command for Pdb. (Contributed by Matthias + Bussonnier in :gh:`106676`.) + +* Expressions/Statements whose prefix is a pdb command are now correctly + identified and executed. + (Contributed by Tian Gao in :gh:`108464`.) + +sqlite3 +------- + +* A :exc:`ResourceWarning` is now emitted if a :class:`sqlite3.Connection` + object is not :meth:`closed ` explicitly. + (Contributed by Erlend E. Aasland in :gh:`105539`.) + +tkinter +------- + +* Add :mod:`tkinter` widget methods: + :meth:`!tk_busy_hold`, :meth:`!tk_busy_configure`, + :meth:`!tk_busy_cget`, :meth:`!tk_busy_forget`, + :meth:`!tk_busy_current`, and :meth:`!tk_busy_status`. + (Contributed by Miguel, klappnase and Serhiy Storchaka in :gh:`72684`.) + traceback --------- -* Add *show_group* paramter to :func:`traceback.TracebackException.format_exception_only` +* Add *show_group* parameter to :func:`traceback.TracebackException.format_exception_only` to format the nested exceptions of a :exc:`BaseExceptionGroup` instance, recursively. (Contributed by Irit Katriel in :gh:`105292`.) @@ -141,39 +255,27 @@ typing check whether a class is a :class:`typing.Protocol`. (Contributed by Jelle Zijlstra in :gh:`104873`.) +venv +---- + +* Add support for adding source control management (SCM) ignore files to a + virtual environment's directory. By default, Git is supported. This is + implemented as opt-in via the API which can be extended to support other SCMs + (:class:`venv.EnvBuilder` and :func:`venv.create`), and opt-out via the CLI + (using ``--without-scm-ignore-files``). (Contributed by Brett Cannon in + :gh:`108125`.) + Optimizations ============= - +* :func:`textwrap.indent` is now ~30% faster than before for large input. + (Contributed by Inada Naoki in :gh:`107369`.) Deprecated ========== -* :mod:`wave`: Deprecate the ``getmark()``, ``setmark()`` and ``getmarkers()`` - methods of the :class:`wave.Wave_read` and :class:`wave.Wave_write` classes. - They will be removed in Python 3.15. - (Contributed by Victor Stinner in :gh:`105096`.) -* :mod:`typing`: Creating a :class:`typing.NamedTuple` class using keyword arguments to denote - the fields (``NT = NamedTuple("NT", x=int, y=int)``) is deprecated, and will - be disallowed in Python 3.15. Use the class-based syntax or the functional - syntax instead. (Contributed by Alex Waygood in :gh:`105566`.) -* :mod:`typing`: When using the functional syntax to create a :class:`typing.NamedTuple` - class or a :class:`typing.TypedDict` class, failing to pass a value to the - 'fields' parameter (``NT = NamedTuple("NT")`` or ``TD = TypedDict("TD")``) is - deprecated. Passing ``None`` to the 'fields' parameter - (``NT = NamedTuple("NT", None)`` or ``TD = TypedDict("TD", None)``) is also - deprecated. Both will be disallowed in Python 3.15. To create a NamedTuple - class with 0 fields, use ``class NT(NamedTuple): pass`` or - ``NT = NamedTuple("NT", [])``. To create a TypedDict class with 0 fields, use - ``class TD(TypedDict): pass`` or ``TD = TypedDict("TD", {})``. - (Contributed by Alex Waygood in :gh:`105566` and :gh:`105570`.) -* :func:`typing.no_type_check_decorator` is deprecated, and scheduled for - removal in Python 3.15. After eight years in the :mod:`typing` module, it - has yet to be supported by any major type checkers. - (Contributed by Alex Waygood in :gh:`106309`.) - -* :mod:`array`'s ``'u'`` format code, deprecated in docs since Python 3.3, +* :mod:`array`: :mod:`array`'s ``'u'`` format code, deprecated in docs since Python 3.3, emits :exc:`DeprecationWarning` since 3.13 and will be removed in Python 3.16. Use the ``'w'`` format code instead. @@ -184,13 +286,84 @@ Deprecated Replace ``ctypes.ARRAY(item_type, size)`` with ``item_type * size``. (Contributed by Victor Stinner in :gh:`105733`.) -* The :mod:`getopt` and :mod:`optparse` modules are now +* :mod:`getopt` and :mod:`optparse` modules: They are now :term:`soft deprecated`: the :mod:`argparse` should be used for new projects. Previously, the :mod:`optparse` module was already deprecated, its removal was not scheduled, and no warnings was emitted: so there is no change in practice. (Contributed by Victor Stinner in :gh:`106535`.) +* :mod:`http.server`: :class:`http.server.CGIHTTPRequestHandler` now emits a + :exc:`DeprecationWarning` as it will be removed in 3.15. Process based CGI + http servers have been out of favor for a very long time. This code was + outdated, unmaintained, and rarely used. It has a high potential for both + security and functionality bugs. This includes removal of the ``--cgi`` + flag to the ``python -m http.server`` command line in 3.15. + +* :mod:`typing`: + + * Creating a :class:`typing.NamedTuple` class using keyword arguments to denote + the fields (``NT = NamedTuple("NT", x=int, y=int)``) is deprecated, and will + be disallowed in Python 3.15. Use the class-based syntax or the functional + syntax instead. (Contributed by Alex Waygood in :gh:`105566`.) + + * When using the functional syntax to create a :class:`typing.NamedTuple` + class or a :class:`typing.TypedDict` class, failing to pass a value to the + 'fields' parameter (``NT = NamedTuple("NT")`` or ``TD = TypedDict("TD")``) is + deprecated. Passing ``None`` to the 'fields' parameter + (``NT = NamedTuple("NT", None)`` or ``TD = TypedDict("TD", None)``) is also + deprecated. Both will be disallowed in Python 3.15. To create a NamedTuple + class with 0 fields, use ``class NT(NamedTuple): pass`` or + ``NT = NamedTuple("NT", [])``. To create a TypedDict class with 0 fields, use + ``class TD(TypedDict): pass`` or ``TD = TypedDict("TD", {})``. + (Contributed by Alex Waygood in :gh:`105566` and :gh:`105570`.) + + * :func:`typing.no_type_check_decorator` is deprecated, and scheduled for + removal in Python 3.15. After eight years in the :mod:`typing` module, it + has yet to be supported by any major type checkers. + (Contributed by Alex Waygood in :gh:`106309`.) + + * :data:`typing.AnyStr` is deprecated. In Python 3.16, it will be removed from + ``typing.__all__``, and a :exc:`DeprecationWarning` will be emitted when it + is imported or accessed. It will be removed entirely in Python 3.18. Use + the new :ref:`type parameter syntax ` instead. + (Contributed by Michael The in :gh:`107116`.) + +* :mod:`wave`: Deprecate the ``getmark()``, ``setmark()`` and ``getmarkers()`` + methods of the :class:`wave.Wave_read` and :class:`wave.Wave_write` classes. + They will be removed in Python 3.15. + (Contributed by Victor Stinner in :gh:`105096`.) + +* Passing more than one positional argument to :func:`sqlite3.connect` and the + :class:`sqlite3.Connection` constructor is deprecated. The remaining + parameters will become keyword-only in Python 3.15. + + Deprecate passing name, number of arguments, and the callable as keyword + arguments, for the following :class:`sqlite3.Connection` APIs: + + * :meth:`~sqlite3.Connection.create_function` + * :meth:`~sqlite3.Connection.create_aggregate` + + Deprecate passing the callback callable by keyword for the following + :class:`sqlite3.Connection` APIs: + + * :meth:`~sqlite3.Connection.set_authorizer` + * :meth:`~sqlite3.Connection.set_progress_handler` + * :meth:`~sqlite3.Connection.set_trace_callback` + + The affected parameters will become positional-only in Python 3.15. + + (Contributed by Erlend E. Aasland in :gh:`107948` and :gh:`108278`.) + +* The ``dis.HAVE_ARGUMENT`` separator is deprecated. Check membership + in :data:`~dis.hasarg` instead. + (Contributed by Irit Katriel in :gh:`109319`.) + +* Deprecate non-standard format specifier "N" for :class:`decimal.Decimal`. + It was not documented and only supported in the C implementation. + (Contributed by Serhiy Storchaka in :gh:`89902`.) + + Pending Removal in Python 3.14 ------------------------------ @@ -299,6 +472,11 @@ Pending Removal in Python 3.14 Pending Removal in Python 3.15 ------------------------------ +* :class:`http.server.CGIHTTPRequestHandler` will be removed along with its + related ``--cgi`` flag to ``python -m http.server``. It was obsolete and + rarely used. No direct replacement exists. *Anything* is better than CGI + to interface a web server with a request handler. + * :class:`typing.NamedTuple`: * The undocumented keyword argument syntax for creating NamedTuple classes @@ -324,10 +502,16 @@ Pending Removal in Python 3.15 They will be removed in Python 3.15. (Contributed by Victor Stinner in :gh:`105096`.) +* Passing any arguments to :func:`threading.RLock` is now deprecated. + C version allows any numbers of args and kwargs, + but they are just ignored. Python version does not allow any arguments. + All arguments will be removed from :func:`threading.RLock` in Python 3.15. + (Contributed by Nikita Sobolev in :gh:`102029`.) + Pending Removal in Python 3.16 ------------------------------ -* :class:`array.array` ``'u'`` type (``wchar_t``): +* :class:`array.array` ``'u'`` type (:c:type:`wchar_t`): use the ``'w'`` type instead (``Py_UCS4``). Pending Removal in Future Versions @@ -366,8 +550,8 @@ although there is currently no date scheduled for their removal. * Delegation of ``int()`` to ``__trunc__()`` method. * :mod:`calendar`: ``calendar.January`` and ``calendar.February`` constants are - deprecated and replaced by :data:`calendar.Month.JANUARY` and - :data:`calendar.Month.FEBRUARY`. + deprecated and replaced by :data:`calendar.JANUARY` and + :data:`calendar.FEBRUARY`. (Contributed by Prince Roshan in :gh:`103636`.) * :mod:`datetime`: @@ -730,12 +914,24 @@ Build Changes ============= * Autoconf 2.71 and aclocal 1.16.4 is now required to regenerate - :file:`!configure`. + the :file:`configure` script. (Contributed by Christian Heimes in :gh:`89886`.) * SQLite 3.15.2 or newer is required to build the :mod:`sqlite3` extension module. (Contributed by Erlend Aasland in :gh:`105875`.) +* Python built with :file:`configure` :option:`--with-trace-refs` (tracing + references) is now ABI compatible with Python release build and + :ref:`debug build `. + (Contributed by Victor Stinner in :gh:`108634`.) + +* Building CPython now requires a compiler with support for the C11 atomic + library, GCC built-in atomic functions, or MSVC interlocked intrinsics. + +* The ``_stat`` C extension is now built with the :ref:`limited C API + `. + (Contributed by Victor Stinner in :gh:`85283`.) + C API Changes ============= @@ -775,6 +971,18 @@ New Features be treated as a failure. (Contributed by Serhiy Storchaka in :gh:`106307`.) +* Add fixed variants of functions which silently ignore errors: + + - :c:func:`PyObject_HasAttrWithError` replaces :c:func:`PyObject_HasAttr`. + - :c:func:`PyObject_HasAttrStringWithError` replaces :c:func:`PyObject_HasAttrString`. + - :c:func:`PyMapping_HasKeyWithError` replaces :c:func:`PyMapping_HasKey`. + - :c:func:`PyMapping_HasKeyStringWithError` replaces :c:func:`PyMapping_HasKeyString`. + + New functions return not only ``1`` for true and ``0`` for false, but also + ``-1`` for error. + + (Contributed by Serhiy Storchaka in :gh:`108511`.) + * If Python is built in :ref:`debug mode ` or :option:`with assertions <--with-assertions>`, :c:func:`PyTuple_SET_ITEM` and :c:func:`PyList_SET_ITEM` now check the index argument with an assertion. @@ -786,15 +994,109 @@ New Features always steals a reference to the value. (Contributed by Serhiy Storchaka in :gh:`86493`.) +* Added :c:func:`PyDict_GetItemRef` and :c:func:`PyDict_GetItemStringRef` + functions: similar to :c:func:`PyDict_GetItemWithError` but returning a + :term:`strong reference` instead of a :term:`borrowed reference`. Moreover, + these functions return -1 on error and so checking ``PyErr_Occurred()`` is + not needed. + (Contributed by Victor Stinner in :gh:`106004`.) + +* Added :c:func:`PyDict_ContainsString` function: same as + :c:func:`PyDict_Contains`, but *key* is specified as a :c:expr:`const char*` + UTF-8 encoded bytes string, rather than a :c:expr:`PyObject*`. + (Contributed by Victor Stinner in :gh:`108314`.) + +* Add :c:func:`Py_IsFinalizing` function: check if the main Python interpreter is + :term:`shutting down `. + (Contributed by Victor Stinner in :gh:`108014`.) + +* Add :c:func:`PyLong_AsInt` function: similar to :c:func:`PyLong_AsLong`, but + store the result in a C :c:expr:`int` instead of a C :c:expr:`long`. + Previously, it was known as the private function :c:func:`!_PyLong_AsInt` + (with an underscore prefix). + (Contributed by Victor Stinner in :gh:`108014`.) + +* Python built with :file:`configure` :option:`--with-trace-refs` (tracing + references) now supports the :ref:`Limited API `. + (Contributed by Victor Stinner in :gh:`108634`.) + +* Add :c:func:`PyObject_VisitManagedDict` and + :c:func:`PyObject_ClearManagedDict` functions which must be called by the + traverse and clear functions of a type using + :c:macro:`Py_TPFLAGS_MANAGED_DICT` flag. The `pythoncapi-compat project + `__ can be used to get these + functions on Python 3.11 and 3.12. + (Contributed by Victor Stinner in :gh:`107073`.) + +* Add :c:func:`PyUnicode_EqualToUTF8AndSize` and :c:func:`PyUnicode_EqualToUTF8` + functions: compare Unicode object with a :c:expr:`const char*` UTF-8 encoded + string and return true (``1``) if they are equal, or false (``0``) otherwise. + These functions do not raise exceptions. + (Contributed by Serhiy Storchaka in :gh:`110289`.) + +* Add :c:func:`PyThreadState_GetUnchecked()` function: similar to + :c:func:`PyThreadState_Get()`, but don't kill the process with a fatal error + if it is NULL. The caller is responsible to check if the result is NULL. + Previously, the function was private and known as + ``_PyThreadState_UncheckedGet()``. + (Contributed by Victor Stinner in :gh:`108867`.) + +* Add :c:func:`PySys_AuditTuple` function: similar to :c:func:`PySys_Audit`, + but pass event arguments as a Python :class:`tuple` object. + (Contributed by Victor Stinner in :gh:`85283`.) + Porting to Python 3.13 ---------------------- +* ``Python.h`` no longer includes the ```` standard header. It was + included for the ``finite()`` function which is now provided by the + ```` header. It should now be included explicitly if needed. Remove + also the ``HAVE_IEEEFP_H`` macro. + (Contributed by Victor Stinner in :gh:`108765`.) + +* ``Python.h`` no longer includes the ```` standard header file. If + needed, it should now be included explicitly. For example, it provides the + functions: ``read()``, ``write()``, ``close()``, ``isatty()``, ``lseek()``, + ``getpid()``, ``getcwd()``, ``sysconf()`` and ``getpagesize()``. + As a consequence, ``_POSIX_SEMAPHORES`` and ``_POSIX_THREADS`` macros are no + longer defined by ``Python.h``. The ``HAVE_UNISTD_H`` and ``HAVE_PTHREAD_H`` + macros defined by ``Python.h`` can be used to decide if ```` and + ```` header files can be included. + (Contributed by Victor Stinner in :gh:`108765`.) + +* ``Python.h`` no longer includes these standard header files: ````, + ```` and ````. If needed, they should now be + included explicitly. For example, ```` provides the ``clock()`` and + ``gmtime()`` functions, ```` provides the ``select()`` + function, and ```` provides the ``futimes()``, ``gettimeofday()`` + and ``setitimer()`` functions. + (Contributed by Victor Stinner in :gh:`108765`.) + +* ``Python.h`` no longer includes the ```` standard header file. If + needed, it should now be included explicitly. For example, it provides + ``isalpha()`` and ``tolower()`` functions which are locale dependent. Python + provides locale independent functions, like :c:func:`!Py_ISALPHA` and + :c:func:`!Py_TOLOWER`. + (Contributed by Victor Stinner in :gh:`108765`.) + +* If the :c:macro:`Py_LIMITED_API` macro is defined, :c:macro:`!Py_BUILD_CORE`, + :c:macro:`!Py_BUILD_CORE_BUILTIN` and :c:macro:`!Py_BUILD_CORE_MODULE` macros + are now undefined by ````. + (Contributed by Victor Stinner in :gh:`85283`.) + Deprecated ---------- +* Passing optional arguments *maxsplit*, *count* and *flags* in module-level + functions :func:`re.split`, :func:`re.sub` and :func:`re.subn` as positional + arguments is now deprecated. + In future Python versions these parameters will be + :ref:`keyword-only `. + (Contributed by Serhiy Storchaka in :gh:`56166`.) + * Deprecate the old ``Py_UNICODE`` and ``PY_UNICODE_TYPE`` types: use directly - the ``wchar_t`` type instead. Since Python 3.3, ``Py_UNICODE`` and - ``PY_UNICODE_TYPE`` are just aliases to ``wchar_t``. + the :c:type:`wchar_t` type instead. Since Python 3.3, ``Py_UNICODE`` and + ``PY_UNICODE_TYPE`` are just aliases to :c:type:`wchar_t`. (Contributed by Victor Stinner in :gh:`105156`.) * Deprecate old Python initialization functions: @@ -828,6 +1130,13 @@ Deprecated Removed ------- +* Remove many APIs (functions, macros, variables) with names prefixed by + ``_Py`` or ``_PY`` (considered as private API). If your project is affected + by one of these removals and you consider that the removed API should remain + available, please open a new issue to request a public C API and + add ``cc @vstinner`` to the issue to notify Victor Stinner. + (Contributed by Victor Stinner in :gh:`106320`.) + * Remove functions deprecated in Python 3.9. * ``PyEval_CallObject()``, ``PyEval_CallObjectWithKeywords()``: use @@ -847,37 +1156,37 @@ Removed * Remove old buffer protocols deprecated in Python 3.0. Use :ref:`bufferobjects` instead. - * :c:func:`!PyObject_CheckReadBuffer`: Use :c:func:`PyObject_CheckBuffer` to - test if the object supports the buffer protocol. - Note that :c:func:`PyObject_CheckBuffer` doesn't guarantee that - :c:func:`PyObject_GetBuffer` will succeed. - To test if the object is actually readable, see the next example - of :c:func:`PyObject_GetBuffer`. + * :c:func:`!PyObject_CheckReadBuffer`: Use :c:func:`PyObject_CheckBuffer` to + test if the object supports the buffer protocol. + Note that :c:func:`PyObject_CheckBuffer` doesn't guarantee that + :c:func:`PyObject_GetBuffer` will succeed. + To test if the object is actually readable, see the next example + of :c:func:`PyObject_GetBuffer`. - * :c:func:`!PyObject_AsCharBuffer`, :c:func:`!PyObject_AsReadBuffer`: - :c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release` instead: + * :c:func:`!PyObject_AsCharBuffer`, :c:func:`!PyObject_AsReadBuffer`: + :c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release` instead: - .. code-block:: c + .. code-block:: c - Py_buffer view; - if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) < 0) { - return NULL; - } - // Use `view.buf` and `view.len` to read from the buffer. - // You may need to cast buf as `(const char*)view.buf`. - PyBuffer_Release(&view); + Py_buffer view; + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) < 0) { + return NULL; + } + // Use `view.buf` and `view.len` to read from the buffer. + // You may need to cast buf as `(const char*)view.buf`. + PyBuffer_Release(&view); - * :c:func:`!PyObject_AsWriteBuffer`: Use - :c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release` instead: + * :c:func:`!PyObject_AsWriteBuffer`: Use + :c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release` instead: - .. code-block:: c + .. code-block:: c - Py_buffer view; - if (PyObject_GetBuffer(obj, &view, PyBUF_WRITABLE) < 0) { - return NULL; - } - // Use `view.buf` and `view.len` to write to the buffer. - PyBuffer_Release(&view); + Py_buffer view; + if (PyObject_GetBuffer(obj, &view, PyBUF_WRITABLE) < 0) { + return NULL; + } + // Use `view.buf` and `view.len` to write to the buffer. + PyBuffer_Release(&view); (Contributed by Inada Naoki in :gh:`85275`.) @@ -894,7 +1203,9 @@ Removed * ``Py_SetPath()``: set :c:member:`PyConfig.module_search_paths` instead. * ``Py_SetProgramName()``: set :c:member:`PyConfig.program_name` instead. * ``Py_SetPythonHome()``: set :c:member:`PyConfig.home` instead. - * ``Py_SetStandardStreamEncoding()``: set :c:member:`PyConfig.stdio_encoding` instead. + * ``Py_SetStandardStreamEncoding()``: set :c:member:`PyConfig.stdio_encoding` + instead, and set also maybe :c:member:`PyConfig.legacy_windows_stdio` (on + Windows). * ``_Py_SetProgramFullPath()``: set :c:member:`PyConfig.executable` instead. Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization @@ -917,13 +1228,6 @@ Removed (Contributed by Victor Stinner in :gh:`105182`.) -* Remove the old private, undocumented and untested ``_PyGC_FINALIZED()`` macro - which was kept for backward compatibility with Python 3.8 and older: use - :c:func:`PyObject_GC_IsFinalized()` instead. The `pythoncapi-compat project - `__ can be used to get this - function on Python 3.8 and older. - (Contributed by Victor Stinner in :gh:`105268`.) - * Remove the old aliases to functions calling functions which were kept for backward compatibility with Python 3.8 provisional API: @@ -961,7 +1265,7 @@ Removed Pending Removal in Python 3.14 ------------------------------ -* Creating immutable types (:data:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable +* Creating immutable types (:c:macro:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable bases using the C API. * Global configuration variables: @@ -997,8 +1301,8 @@ Pending Removal in Python 3.15 * :c:func:`PyImport_ImportModuleNoBlock`: use :c:func:`PyImport_ImportModule`. * :c:func:`PyWeakref_GET_OBJECT`: use :c:func:`PyWeakref_GetRef` instead. * :c:func:`PyWeakref_GetObject`: use :c:func:`PyWeakref_GetRef` instead. -* :c:type:`!Py_UNICODE_WIDE` type: use ``wchar_t`` instead. -* :c:type:`Py_UNICODE` type: use ``wchar_t`` instead. +* :c:type:`!Py_UNICODE_WIDE` type: use :c:type:`wchar_t` instead. +* :c:type:`Py_UNICODE` type: use :c:type:`wchar_t` instead. * Python initialization functions: * :c:func:`PySys_ResetWarnOptions`: clear :data:`sys.warnoptions` and @@ -1017,7 +1321,7 @@ Pending Removal in Future Versions The following APIs were deprecated in earlier Python versions and will be removed, although there is currently no date scheduled for their removal. -* :const:`Py_TPFLAGS_HAVE_FINALIZE`: no needed since Python 3.8. +* :c:macro:`Py_TPFLAGS_HAVE_FINALIZE`: no needed since Python 3.8. * :c:func:`PyErr_Fetch`: use :c:func:`PyErr_GetRaisedException`. * :c:func:`PyErr_NormalizeException`: use :c:func:`PyErr_GetRaisedException`. * :c:func:`PyErr_Restore`: use :c:func:`PyErr_SetRaisedException`. @@ -1041,3 +1345,6 @@ removed, although there is currently no date scheduled for their removal. * :c:func:`PyThread_get_key_value`: use :c:func:`PyThread_tss_get`. * :c:func:`PyThread_delete_key_value`: use :c:func:`PyThread_tss_delete`. * :c:func:`PyThread_ReInitTLS`: no longer needed. + +* Remove undocumented ``PY_TIMEOUT_MAX`` constant from the limited C API. + (Contributed by Victor Stinner in :gh:`110014`.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index c3f7ef6e565995..df32b76b6d7b03 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -424,7 +424,7 @@ protocols, the users must to be able access the environment using native strings even though the underlying platform may have a different convention. To bridge this gap, the :mod:`wsgiref` module has a new function, :func:`wsgiref.handlers.read_environ` for transcoding CGI variables from -:attr:`os.environ` into native strings and returning a new dictionary. +:data:`os.environ` into native strings and returning a new dictionary. .. seealso:: @@ -485,7 +485,7 @@ Some smaller changes made to the core Python language are: * The interpreter can now be started with a quiet option, ``-q``, to prevent the copyright and version information from being displayed in the interactive - mode. The option can be introspected using the :attr:`sys.flags` attribute: + mode. The option can be introspected using the :data:`sys.flags` attribute: .. code-block:: shell-session @@ -566,9 +566,9 @@ Some smaller changes made to the core Python language are: (See :issue:`4617`.) -* The internal :c:type:`structsequence` tool now creates subclasses of tuple. +* :ref:`Struct sequence types ` are now subclasses of tuple. This means that C structures like those returned by :func:`os.stat`, - :func:`time.gmtime`, and :attr:`sys.version_info` now work like a + :func:`time.gmtime`, and :data:`sys.version_info` now work like a :term:`named tuple` and now work with functions and methods that expect a tuple as an argument. This is a big step forward in making the C structures as flexible as their pure Python counterparts: @@ -598,7 +598,7 @@ Some smaller changes made to the core Python language are: module, or on the command line. A :exc:`ResourceWarning` is issued at interpreter shutdown if the - :data:`gc.garbage` list isn't empty, and if :attr:`gc.DEBUG_UNCOLLECTABLE` is + :data:`gc.garbage` list isn't empty, and if :const:`gc.DEBUG_UNCOLLECTABLE` is set, all uncollectable objects are printed. This is meant to make the programmer aware that their code contains object finalization issues. @@ -623,7 +623,7 @@ Some smaller changes made to the core Python language are: :class:`collections.Sequence` :term:`abstract base class`. As a result, the language will have a more uniform API. In addition, :class:`range` objects now support slicing and negative indices, even with values larger than - :attr:`sys.maxsize`. This makes *range* more interoperable with lists:: + :data:`sys.maxsize`. This makes *range* more interoperable with lists:: >>> range(0, 100, 2).count(10) 1 @@ -1007,13 +1007,13 @@ datetime and time after 1900. The new supported year range is from 1000 to 9999 inclusive. * Whenever a two-digit year is used in a time tuple, the interpretation has been - governed by :attr:`time.accept2dyear`. The default is ``True`` which means that + governed by :data:`time.accept2dyear`. The default is ``True`` which means that for a two-digit year, the century is guessed according to the POSIX rules governing the ``%y`` strptime format. Starting with Py3.2, use of the century guessing heuristic will emit a :exc:`DeprecationWarning`. Instead, it is recommended that - :attr:`time.accept2dyear` be set to ``False`` so that large date ranges + :data:`time.accept2dyear` be set to ``False`` so that large date ranges can be used without guesswork:: >>> import time, warnings @@ -1031,7 +1031,7 @@ datetime and time 'Fri Jan 1 12:34:56 11' Several functions now have significantly expanded date ranges. When - :attr:`time.accept2dyear` is false, the :func:`time.asctime` function will + :data:`time.accept2dyear` is false, the :func:`time.asctime` function will accept any year that fits in a C int, while the :func:`time.mktime` and :func:`time.strftime` functions will accept the full range supported by the corresponding operating system functions. @@ -1194,11 +1194,11 @@ can be set to "$" for the shell-style formatting provided by If no configuration is set-up before a logging event occurs, there is now a default configuration using a :class:`~logging.StreamHandler` directed to -:attr:`sys.stderr` for events of ``WARNING`` level or higher. Formerly, an +:data:`sys.stderr` for events of ``WARNING`` level or higher. Formerly, an event occurring before a configuration was set-up would either raise an exception or silently drop the event depending on the value of -:attr:`logging.raiseExceptions`. The new default handler is stored in -:attr:`logging.lastResort`. +:data:`logging.raiseExceptions`. The new default handler is stored in +:data:`logging.lastResort`. The use of filters has been simplified. Instead of creating a :class:`~logging.Filter` object, the predicate can be any Python callable that @@ -1300,7 +1300,7 @@ values are equal (:issue:`8188`):: hash(Decimal("1.5")) == hash(complex(1.5, 0)) Some of the hashing details are exposed through a new attribute, -:attr:`sys.hash_info`, which describes the bit width of the hash value, the +:data:`sys.hash_info`, which describes the bit width of the hash value, the prime modulus, the hash values for *infinity* and *nan*, and the multiplier used for the imaginary part of a number: @@ -1388,7 +1388,7 @@ select ------ The :mod:`select` module now exposes a new, constant attribute, -:attr:`~select.PIPE_BUF`, which gives the minimum number of bytes which are +:const:`~select.PIPE_BUF`, which gives the minimum number of bytes which are guaranteed not to block when :func:`select.select` says a pipe is ready for writing. @@ -1529,7 +1529,7 @@ filenames: b'Sehensw\xc3\xbcrdigkeiten' Some operating systems allow direct access to encoded bytes in the -environment. If so, the :attr:`os.supports_bytes_environ` constant will be +environment. If so, the :const:`os.supports_bytes_environ` constant will be true. For direct access to encoded environment variables (if available), @@ -1666,9 +1666,9 @@ for secure (encrypted, authenticated) internet connections: algorithm" error. * The version of OpenSSL being used is now accessible using the module - attributes :data:`ssl.OPENSSL_VERSION` (a string), - :data:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and - :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). + attributes :const:`ssl.OPENSSL_VERSION` (a string), + :const:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and + :const:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Contributed by Antoine Pitrou in :issue:`8850`, :issue:`1589`, :issue:`8322`, :issue:`5639`, :issue:`4870`, :issue:`8484`, and :issue:`8321`.) @@ -2302,7 +2302,7 @@ turtledemo The demonstration code for the :mod:`turtle` module was moved from the *Demo* directory to main library. It includes over a dozen sample scripts with -lively displays. Being on :attr:`sys.path`, it can now be run directly +lively displays. Being on :data:`sys.path`, it can now be run directly from the command-line: .. code-block:: shell-session @@ -2566,10 +2566,10 @@ Changes to Python's build process and to the C API include: (:issue:`2443`). * A new C API function :c:func:`PySys_SetArgvEx` allows an embedded interpreter - to set :attr:`sys.argv` without also modifying :attr:`sys.path` + to set :data:`sys.argv` without also modifying :data:`sys.path` (:issue:`5753`). -* :c:macro:`PyEval_CallObject` is now only available in macro form. The +* :c:func:`!PyEval_CallObject` is now only available in macro form. The function declaration, which was kept for backwards compatibility reasons, is now removed -- the macro was introduced in 1997 (:issue:`8276`). @@ -2658,7 +2658,7 @@ require changes to your code: * "t#" format has been removed: use "s#" or "s*" instead * "w" and "w#" formats has been removed: use "w*" instead -* The :c:type:`PyCObject` type, deprecated in 3.1, has been removed. To wrap +* The :c:type:`!PyCObject` type, deprecated in 3.1, has been removed. To wrap opaque C pointers in Python objects, the :c:type:`PyCapsule` API should be used instead; the new type has a well-defined interface for passing typing safety information and a less complicated signature for calling a destructor. @@ -2731,15 +2731,15 @@ require changes to your code: (Contributed by Antoine Pitrou, :issue:`10272`.) -* The misleading functions :c:func:`PyEval_AcquireLock()` and - :c:func:`PyEval_ReleaseLock()` have been officially deprecated. The - thread-state aware APIs (such as :c:func:`PyEval_SaveThread()` - and :c:func:`PyEval_RestoreThread()`) should be used instead. +* The misleading functions :c:func:`!PyEval_AcquireLock` and + :c:func:`!PyEval_ReleaseLock` have been officially deprecated. The + thread-state aware APIs (such as :c:func:`PyEval_SaveThread` + and :c:func:`PyEval_RestoreThread`) should be used instead. * Due to security risks, :func:`asyncore.handle_accept` has been deprecated, and a new function, :func:`asyncore.handle_accepted`, was added to replace it. (Contributed by Giampaolo Rodola in :issue:`6706`.) -* Due to the new :term:`GIL` implementation, :c:func:`PyEval_InitThreads()` - cannot be called before :c:func:`Py_Initialize()` anymore. +* Due to the new :term:`GIL` implementation, :c:func:`!PyEval_InitThreads` + cannot be called before :c:func:`Py_Initialize` anymore. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 3dca7227a91c38..5674bc7f359b72 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -249,7 +249,7 @@ Changes introduced by :pep:`393` are the following: non-BMP code points. * The value of :data:`sys.maxunicode` is now always ``1114111`` (``0x10FFFF`` - in hexadecimal). The :c:func:`PyUnicode_GetMax` function still returns + in hexadecimal). The :c:func:`!PyUnicode_GetMax` function still returns either ``0xFFFF`` or ``0x10FFFF`` for backward compatibility, and it should not be used with the new Unicode API (see :issue:`13054`). @@ -648,7 +648,7 @@ PEP 421: Adding sys.implementation A new attribute on the :mod:`sys` module exposes details specific to the implementation of the currently running interpreter. The initial set of -attributes on :attr:`sys.implementation` are ``name``, ``version``, +attributes on :data:`sys.implementation` are ``name``, ``version``, ``hexversion``, and ``cache_tag``. The intention of ``sys.implementation`` is to consolidate into one namespace @@ -719,7 +719,7 @@ and does not enforce any method requirements. In terms of finders, :class:`importlib.machinery.FileFinder` exposes the mechanism used to search for source and bytecode files of a module. Previously -this class was an implicit member of :attr:`sys.path_hooks`. +this class was an implicit member of :data:`sys.path_hooks`. For loaders, the new abstract base class :class:`importlib.abc.FileLoader` helps write a loader that uses the file system as the storage mechanism for a module's @@ -735,7 +735,7 @@ provide the full name of the module now instead of just the tail end of the module's name. The :func:`importlib.invalidate_caches` function will now call the method with -the same name on all finders cached in :attr:`sys.path_importer_cache` to help +the same name on all finders cached in :data:`sys.path_importer_cache` to help clean up any stored state as necessary. Visible Changes @@ -745,8 +745,8 @@ For potential required changes to code, see the `Porting Python code`_ section. Beyond the expanse of what :mod:`importlib` now exposes, there are other -visible changes to import. The biggest is that :attr:`sys.meta_path` and -:attr:`sys.path_hooks` now store all of the meta path finders and path entry +visible changes to import. The biggest is that :data:`sys.meta_path` and +:data:`sys.path_hooks` now store all of the meta path finders and path entry hooks used by import. Previously the finders were implicit and hidden within the C code of import instead of being directly exposed. This means that one can now easily remove or change the order of the various finders to fit one's needs. @@ -761,9 +761,9 @@ Loaders are also now expected to set the ``__package__`` attribute from :pep:`366`. Once again, import itself is already setting this on all loaders from :mod:`importlib` and import itself is setting the attribute post-load. -``None`` is now inserted into :attr:`sys.path_importer_cache` when no finder -can be found on :attr:`sys.path_hooks`. Since :class:`!imp.NullImporter` is not -directly exposed on :attr:`sys.path_hooks` it could no longer be relied upon to +``None`` is now inserted into :data:`sys.path_importer_cache` when no finder +can be found on :data:`sys.path_hooks`. Since :class:`!imp.NullImporter` is not +directly exposed on :data:`sys.path_hooks` it could no longer be relied upon to always be available to use as a value representing no finder found. All other changes relate to semantic changes which should be taken into @@ -842,7 +842,7 @@ Builtin functions and types * :func:`open` gets a new *opener* parameter: the underlying file descriptor for the file object is then obtained by calling *opener* with (*file*, - *flags*). It can be used to use custom flags like :data:`os.O_CLOEXEC` for + *flags*). It can be used to use custom flags like :const:`os.O_CLOEXEC` for example. The ``'x'`` mode was added: open for exclusive creation, failing if the file already exists. * :func:`print`: added the *flush* keyword argument. If the *flush* keyword @@ -917,12 +917,12 @@ abstract methods. The recommended approach to declaring abstract descriptors is now to provide :attr:`__isabstractmethod__` as a dynamically updated property. The built-in descriptors have been updated accordingly. - * :class:`abc.abstractproperty` has been deprecated, use :class:`property` - with :func:`abc.abstractmethod` instead. - * :class:`abc.abstractclassmethod` has been deprecated, use - :class:`classmethod` with :func:`abc.abstractmethod` instead. - * :class:`abc.abstractstaticmethod` has been deprecated, use - :class:`staticmethod` with :func:`abc.abstractmethod` instead. +* :class:`abc.abstractproperty` has been deprecated, use :class:`property` + with :func:`abc.abstractmethod` instead. +* :class:`abc.abstractclassmethod` has been deprecated, use + :class:`classmethod` with :func:`abc.abstractmethod` instead. +* :class:`abc.abstractstaticmethod` has been deprecated, use + :class:`staticmethod` with :func:`abc.abstractmethod` instead. (Contributed by Darren Dale in :issue:`11610`.) @@ -1060,32 +1060,32 @@ function to the :mod:`!crypt` module. curses ------ - * If the :mod:`curses` module is linked to the ncursesw library, use Unicode - functions when Unicode strings or characters are passed (e.g. - :c:func:`waddwstr`), and bytes functions otherwise (e.g. :c:func:`waddstr`). - * Use the locale encoding instead of ``utf-8`` to encode Unicode strings. - * :class:`curses.window` has a new :attr:`curses.window.encoding` attribute. - * The :class:`curses.window` class has a new :meth:`~curses.window.get_wch` - method to get a wide character - * The :mod:`curses` module has a new :meth:`~curses.unget_wch` function to - push a wide character so the next :meth:`~curses.window.get_wch` will return - it +* If the :mod:`curses` module is linked to the ncursesw library, use Unicode + functions when Unicode strings or characters are passed (e.g. + :c:func:`waddwstr`), and bytes functions otherwise (e.g. :c:func:`waddstr`). +* Use the locale encoding instead of ``utf-8`` to encode Unicode strings. +* :class:`curses.window` has a new :attr:`curses.window.encoding` attribute. +* The :class:`curses.window` class has a new :meth:`~curses.window.get_wch` + method to get a wide character +* The :mod:`curses` module has a new :meth:`~curses.unget_wch` function to + push a wide character so the next :meth:`~curses.window.get_wch` will return + it (Contributed by Iñigo Serna in :issue:`6755`.) datetime -------- - * Equality comparisons between naive and aware :class:`~datetime.datetime` - instances now return :const:`False` instead of raising :exc:`TypeError` - (:issue:`15006`). - * New :meth:`datetime.datetime.timestamp` method: Return POSIX timestamp - corresponding to the :class:`~datetime.datetime` instance. - * The :meth:`datetime.datetime.strftime` method supports formatting years - older than 1000. - * The :meth:`datetime.datetime.astimezone` method can now be - called without arguments to convert datetime instance to the system - timezone. +* Equality comparisons between naive and aware :class:`~datetime.datetime` + instances now return :const:`False` instead of raising :exc:`TypeError` + (:issue:`15006`). +* New :meth:`datetime.datetime.timestamp` method: Return POSIX timestamp + corresponding to the :class:`~datetime.datetime` instance. +* The :meth:`datetime.datetime.strftime` method supports formatting years + older than 1000. +* The :meth:`datetime.datetime.astimezone` method can now be + called without arguments to convert datetime instance to the system + timezone. .. _new-decimal: @@ -1127,7 +1127,7 @@ Features * If Python is compiled without threads, the C version automatically disables the expensive thread local context machinery. In this case, - the variable :data:`~decimal.HAVE_THREADS` is set to ``False``. + the variable :const:`~decimal.HAVE_THREADS` is set to ``False``. API changes ~~~~~~~~~~~ @@ -1135,20 +1135,20 @@ API changes * The C module has the following context limits, depending on the machine architecture: - +-------------------+---------------------+------------------------------+ - | | 32-bit | 64-bit | - +===================+=====================+==============================+ - | :const:`MAX_PREC` | :const:`425000000` | :const:`999999999999999999` | - +-------------------+---------------------+------------------------------+ - | :const:`MAX_EMAX` | :const:`425000000` | :const:`999999999999999999` | - +-------------------+---------------------+------------------------------+ - | :const:`MIN_EMIN` | :const:`-425000000` | :const:`-999999999999999999` | - +-------------------+---------------------+------------------------------+ + +-------------------+----------------+-------------------------+ + | | 32-bit | 64-bit | + +===================+================+=========================+ + | :const:`MAX_PREC` | ``425000000`` | ``999999999999999999`` | + +-------------------+----------------+-------------------------+ + | :const:`MAX_EMAX` | ``425000000`` | ``999999999999999999`` | + +-------------------+----------------+-------------------------+ + | :const:`MIN_EMIN` | ``-425000000`` | ``-999999999999999999`` | + +-------------------+----------------+-------------------------+ * In the context templates (:class:`~decimal.DefaultContext`, :class:`~decimal.BasicContext` and :class:`~decimal.ExtendedContext`) the magnitude of :attr:`~decimal.Context.Emax` and - :attr:`~decimal.Context.Emin` has changed to :const:`999999`. + :attr:`~decimal.Context.Emin` has changed to ``999999``. * The :class:`~decimal.Decimal` constructor in decimal.py does not observe the context limits and converts values with arbitrary exponents or precision @@ -1210,25 +1210,25 @@ the ``Message`` object it is serializing. The default policy is The minimum set of controls implemented by all ``policy`` objects are: - .. tabularcolumns:: |l|L| +.. tabularcolumns:: |l|L| - =============== ======================================================= - max_line_length The maximum length, excluding the linesep character(s), - individual lines may have when a ``Message`` is - serialized. Defaults to 78. +=============== ======================================================= +max_line_length The maximum length, excluding the linesep character(s), + individual lines may have when a ``Message`` is + serialized. Defaults to 78. - linesep The character used to separate individual lines when a - ``Message`` is serialized. Defaults to ``\n``. +linesep The character used to separate individual lines when a + ``Message`` is serialized. Defaults to ``\n``. - cte_type ``7bit`` or ``8bit``. ``8bit`` applies only to a - ``Bytes`` ``generator``, and means that non-ASCII may - be used where allowed by the protocol (or where it - exists in the original input). +cte_type ``7bit`` or ``8bit``. ``8bit`` applies only to a + ``Bytes`` ``generator``, and means that non-ASCII may + be used where allowed by the protocol (or where it + exists in the original input). - raise_on_defect Causes a ``parser`` to raise error when defects are - encountered instead of adding them to the ``Message`` - object's ``defects`` list. - =============== ======================================================= +raise_on_defect Causes a ``parser`` to raise error when defects are + encountered instead of adding them to the ``Message`` + object's ``defects`` list. +=============== ======================================================= A new policy instance, with new settings, is created using the :meth:`~email.policy.Policy.clone` method of policy objects. ``clone`` takes @@ -1263,21 +1263,21 @@ removal of the code) may occur if deemed necessary by the core developers. The new policies are instances of :class:`~email.policy.EmailPolicy`, and add the following additional controls: - .. tabularcolumns:: |l|L| +.. tabularcolumns:: |l|L| - =============== ======================================================= - refold_source Controls whether or not headers parsed by a - :mod:`~email.parser` are refolded by the - :mod:`~email.generator`. It can be ``none``, ``long``, - or ``all``. The default is ``long``, which means that - source headers with a line longer than - ``max_line_length`` get refolded. ``none`` means no - line get refolded, and ``all`` means that all lines - get refolded. +=============== ======================================================= +refold_source Controls whether or not headers parsed by a + :mod:`~email.parser` are refolded by the + :mod:`~email.generator`. It can be ``none``, ``long``, + or ``all``. The default is ``long``, which means that + source headers with a line longer than + ``max_line_length`` get refolded. ``none`` means no + line get refolded, and ``all`` means that all lines + get refolded. - header_factory A callable that take a ``name`` and ``value`` and - produces a custom header object. - =============== ======================================================= +header_factory A callable that take a ``name`` and ``value`` and + produces a custom header object. +=============== ======================================================= The ``header_factory`` is the key to the new features provided by the new policies. When one of the new policies is used, any header retrieved from @@ -1352,18 +1352,18 @@ API. New utility functions: - * :func:`~email.utils.format_datetime`: given a :class:`~datetime.datetime`, - produce a string formatted for use in an email header. +* :func:`~email.utils.format_datetime`: given a :class:`~datetime.datetime`, + produce a string formatted for use in an email header. - * :func:`~email.utils.parsedate_to_datetime`: given a date string from - an email header, convert it into an aware :class:`~datetime.datetime`, - or a naive :class:`~datetime.datetime` if the offset is ``-0000``. +* :func:`~email.utils.parsedate_to_datetime`: given a date string from + an email header, convert it into an aware :class:`~datetime.datetime`, + or a naive :class:`~datetime.datetime` if the offset is ``-0000``. - * :func:`~email.utils.localtime`: With no argument, returns the - current local time as an aware :class:`~datetime.datetime` using the local - :class:`~datetime.timezone`. Given an aware :class:`~datetime.datetime`, - converts it into an aware :class:`~datetime.datetime` using the - local :class:`~datetime.timezone`. +* :func:`~email.utils.localtime`: With no argument, returns the + current local time as an aware :class:`~datetime.datetime` using the local + :class:`~datetime.timezone`. Given an aware :class:`~datetime.datetime`, + converts it into an aware :class:`~datetime.datetime` using the + local :class:`~datetime.timezone`. ftplib @@ -1576,8 +1576,8 @@ os -- * The :mod:`os` module has a new :func:`~os.pipe2` function that makes it - possible to create a pipe with :data:`~os.O_CLOEXEC` or - :data:`~os.O_NONBLOCK` flags set atomically. This is especially useful to + possible to create a pipe with :const:`~os.O_CLOEXEC` or + :const:`~os.O_NONBLOCK` flags set atomically. This is especially useful to avoid race conditions in multi-threaded programs. * The :mod:`os` module has a new :func:`~os.sendfile` function which provides @@ -1691,9 +1691,9 @@ os * Some platforms now support additional constants for the :func:`~os.lseek` function, such as ``os.SEEK_HOLE`` and ``os.SEEK_DATA``. -* New constants :data:`~os.RTLD_LAZY`, :data:`~os.RTLD_NOW`, - :data:`~os.RTLD_GLOBAL`, :data:`~os.RTLD_LOCAL`, :data:`~os.RTLD_NODELETE`, - :data:`~os.RTLD_NOLOAD`, and :data:`~os.RTLD_DEEPBIND` are available on +* New constants :const:`~os.RTLD_LAZY`, :const:`~os.RTLD_NOW`, + :const:`~os.RTLD_GLOBAL`, :const:`~os.RTLD_LOCAL`, :const:`~os.RTLD_NODELETE`, + :const:`~os.RTLD_NOLOAD`, and :const:`~os.RTLD_DEEPBIND` are available on platforms that support them. These are for use with the :func:`sys.setdlopenflags` function, and supersede the similar constants defined in :mod:`ctypes` and :mod:`DLFCN`. (Contributed by Victor Stinner @@ -1952,7 +1952,7 @@ ssl * You can query the SSL compression algorithm used by an SSL socket, thanks to its new :meth:`~ssl.SSLSocket.compression` method. The new attribute - :attr:`~ssl.OP_NO_COMPRESSION` can be used to disable compression. + :const:`~ssl.OP_NO_COMPRESSION` can be used to disable compression. (Contributed by Antoine Pitrou in :issue:`13634`.) * Support has been added for the Next Protocol Negotiation extension using @@ -1966,7 +1966,7 @@ ssl * The :func:`~ssl.get_server_certificate` function now supports IPv6. (Contributed by Charles-François Natali in :issue:`11811`.) -* New attribute :attr:`~ssl.OP_CIPHER_SERVER_PREFERENCE` allows setting +* New attribute :const:`~ssl.OP_CIPHER_SERVER_PREFERENCE` allows setting SSLv3 server sockets to use the server's cipher ordering preference rather than the client's (:issue:`13635`). @@ -1984,7 +1984,7 @@ the form '-rwxrwxrwx'. struct ------ -The :mod:`struct` module now supports ``ssize_t`` and ``size_t`` via the +The :mod:`struct` module now supports :c:type:`ssize_t` and :c:type:`size_t` via the new codes ``n`` and ``N``, respectively. (Contributed by Antoine Pitrou in :issue:`3163`.) @@ -1995,7 +1995,7 @@ subprocess Command strings can now be bytes objects on posix platforms. (Contributed by Victor Stinner in :issue:`8513`.) -A new constant :data:`~subprocess.DEVNULL` allows suppressing output in a +A new constant :const:`~subprocess.DEVNULL` allows suppressing output in a platform-independent fashion. (Contributed by Ross Lagerwall in :issue:`5870`.) @@ -2067,7 +2067,7 @@ The :pep:`418` added new functions to the :mod:`time` module: Other new functions: * :func:`~time.clock_getres`, :func:`~time.clock_gettime` and - :func:`~time.clock_settime` functions with ``CLOCK_xxx`` constants. + :func:`~time.clock_settime` functions with :samp:`CLOCK_{xxx}` constants. (Contributed by Victor Stinner in :issue:`10278`.) To improve cross platform consistency, :func:`~time.sleep` now raises a @@ -2141,7 +2141,7 @@ New attribute :attr:`zlib.Decompress.eof` makes it possible to distinguish between a properly formed compressed stream and an incomplete or truncated one. (Contributed by Nadeem Vawda in :issue:`12646`.) -New attribute :attr:`zlib.ZLIB_RUNTIME_VERSION` reports the version string of +New attribute :const:`zlib.ZLIB_RUNTIME_VERSION` reports the version string of the underlying ``zlib`` library that is loaded at runtime. (Contributed by Torsten Landschoff in :issue:`12306`.) @@ -2195,8 +2195,8 @@ Changes to Python's build process and to the C API include: * :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsUCS4Copy` * :c:macro:`PyUnicode_DATA`, :c:macro:`PyUnicode_1BYTE_DATA`, :c:macro:`PyUnicode_2BYTE_DATA`, :c:macro:`PyUnicode_4BYTE_DATA` - * :c:macro:`PyUnicode_KIND` with :c:type:`PyUnicode_Kind` enum: - :c:data:`PyUnicode_WCHAR_KIND`, :c:data:`PyUnicode_1BYTE_KIND`, + * :c:macro:`PyUnicode_KIND` with :c:enum:`PyUnicode_Kind` enum: + :c:data:`!PyUnicode_WCHAR_KIND`, :c:data:`PyUnicode_1BYTE_KIND`, :c:data:`PyUnicode_2BYTE_KIND`, :c:data:`PyUnicode_4BYTE_KIND` * :c:macro:`PyUnicode_READ`, :c:macro:`PyUnicode_READ_CHAR`, :c:macro:`PyUnicode_WRITE` * :c:macro:`PyUnicode_MAX_CHAR_VALUE` @@ -2270,58 +2270,58 @@ removed in Python 4. All functions using this type are deprecated: Unicode functions and methods using :c:type:`Py_UNICODE` and :c:expr:`Py_UNICODE*` types: -* :c:macro:`PyUnicode_FromUnicode`: use :c:func:`PyUnicode_FromWideChar` or +* :c:macro:`!PyUnicode_FromUnicode`: use :c:func:`PyUnicode_FromWideChar` or :c:func:`PyUnicode_FromKindAndData` -* :c:macro:`PyUnicode_AS_UNICODE`, :c:func:`PyUnicode_AsUnicode`, - :c:func:`PyUnicode_AsUnicodeAndSize`: use :c:func:`PyUnicode_AsWideCharString` -* :c:macro:`PyUnicode_AS_DATA`: use :c:macro:`PyUnicode_DATA` with +* :c:macro:`!PyUnicode_AS_UNICODE`, :c:func:`!PyUnicode_AsUnicode`, + :c:func:`!PyUnicode_AsUnicodeAndSize`: use :c:func:`PyUnicode_AsWideCharString` +* :c:macro:`!PyUnicode_AS_DATA`: use :c:macro:`PyUnicode_DATA` with :c:macro:`PyUnicode_READ` and :c:macro:`PyUnicode_WRITE` -* :c:macro:`PyUnicode_GET_SIZE`, :c:func:`PyUnicode_GetSize`: use +* :c:macro:`!PyUnicode_GET_SIZE`, :c:func:`!PyUnicode_GetSize`: use :c:macro:`PyUnicode_GET_LENGTH` or :c:func:`PyUnicode_GetLength` -* :c:macro:`PyUnicode_GET_DATA_SIZE`: use +* :c:macro:`!PyUnicode_GET_DATA_SIZE`: use ``PyUnicode_GET_LENGTH(str) * PyUnicode_KIND(str)`` (only work on ready strings) -* :c:func:`PyUnicode_AsUnicodeCopy`: use :c:func:`PyUnicode_AsUCS4Copy` or +* :c:func:`!PyUnicode_AsUnicodeCopy`: use :c:func:`PyUnicode_AsUCS4Copy` or :c:func:`PyUnicode_AsWideCharString` -* :c:func:`PyUnicode_GetMax` +* :c:func:`!PyUnicode_GetMax` Functions and macros manipulating Py_UNICODE* strings: -* :c:macro:`Py_UNICODE_strlen`: use :c:func:`PyUnicode_GetLength` or +* :c:macro:`!Py_UNICODE_strlen()`: use :c:func:`PyUnicode_GetLength` or :c:macro:`PyUnicode_GET_LENGTH` -* :c:macro:`Py_UNICODE_strcat`: use :c:func:`PyUnicode_CopyCharacters` or +* :c:macro:`!Py_UNICODE_strcat()`: use :c:func:`PyUnicode_CopyCharacters` or :c:func:`PyUnicode_FromFormat` -* :c:macro:`Py_UNICODE_strcpy`, :c:macro:`Py_UNICODE_strncpy`, - :c:macro:`Py_UNICODE_COPY`: use :c:func:`PyUnicode_CopyCharacters` or +* :c:macro:`!Py_UNICODE_strcpy()`, :c:macro:`!Py_UNICODE_strncpy()`, + :c:macro:`!Py_UNICODE_COPY()`: use :c:func:`PyUnicode_CopyCharacters` or :c:func:`PyUnicode_Substring` -* :c:macro:`Py_UNICODE_strcmp`: use :c:func:`PyUnicode_Compare` -* :c:macro:`Py_UNICODE_strncmp`: use :c:func:`PyUnicode_Tailmatch` -* :c:macro:`Py_UNICODE_strchr`, :c:macro:`Py_UNICODE_strrchr`: use +* :c:macro:`!Py_UNICODE_strcmp()`: use :c:func:`PyUnicode_Compare` +* :c:macro:`!Py_UNICODE_strncmp()`: use :c:func:`PyUnicode_Tailmatch` +* :c:macro:`!Py_UNICODE_strchr()`, :c:macro:`!Py_UNICODE_strrchr()`: use :c:func:`PyUnicode_FindChar` -* :c:macro:`Py_UNICODE_FILL`: use :c:func:`PyUnicode_Fill` -* :c:macro:`Py_UNICODE_MATCH` +* :c:macro:`!Py_UNICODE_FILL()`: use :c:func:`PyUnicode_Fill` +* :c:macro:`!Py_UNICODE_MATCH` Encoders: -* :c:func:`PyUnicode_Encode`: use :c:func:`PyUnicode_AsEncodedObject` -* :c:func:`PyUnicode_EncodeUTF7` -* :c:func:`PyUnicode_EncodeUTF8`: use :c:func:`PyUnicode_AsUTF8` or +* :c:func:`!PyUnicode_Encode`: use :c:func:`!PyUnicode_AsEncodedObject` +* :c:func:`!PyUnicode_EncodeUTF7` +* :c:func:`!PyUnicode_EncodeUTF8`: use :c:func:`PyUnicode_AsUTF8` or :c:func:`PyUnicode_AsUTF8String` -* :c:func:`PyUnicode_EncodeUTF32` -* :c:func:`PyUnicode_EncodeUTF16` -* :c:func:`PyUnicode_EncodeUnicodeEscape` use +* :c:func:`!PyUnicode_EncodeUTF32` +* :c:func:`!PyUnicode_EncodeUTF16` +* :c:func:`!PyUnicode_EncodeUnicodeEscape` use :c:func:`PyUnicode_AsUnicodeEscapeString` -* :c:func:`PyUnicode_EncodeRawUnicodeEscape` use +* :c:func:`!PyUnicode_EncodeRawUnicodeEscape` use :c:func:`PyUnicode_AsRawUnicodeEscapeString` -* :c:func:`PyUnicode_EncodeLatin1`: use :c:func:`PyUnicode_AsLatin1String` -* :c:func:`PyUnicode_EncodeASCII`: use :c:func:`PyUnicode_AsASCIIString` -* :c:func:`PyUnicode_EncodeCharmap` -* :c:func:`PyUnicode_TranslateCharmap` -* :c:func:`PyUnicode_EncodeMBCS`: use :c:func:`PyUnicode_AsMBCSString` or +* :c:func:`!PyUnicode_EncodeLatin1`: use :c:func:`PyUnicode_AsLatin1String` +* :c:func:`!PyUnicode_EncodeASCII`: use :c:func:`PyUnicode_AsASCIIString` +* :c:func:`!PyUnicode_EncodeCharmap` +* :c:func:`!PyUnicode_TranslateCharmap` +* :c:func:`!PyUnicode_EncodeMBCS`: use :c:func:`PyUnicode_AsMBCSString` or :c:func:`PyUnicode_EncodeCodePage` (with ``CP_ACP`` code_page) -* :c:func:`PyUnicode_EncodeDecimal`, - :c:func:`PyUnicode_TransformDecimalToASCII` +* :c:func:`!PyUnicode_EncodeDecimal`, + :c:func:`!PyUnicode_TransformDecimalToASCII` Deprecated features @@ -2378,16 +2378,16 @@ Porting Python code * :func:`__import__` no longer allows one to use an index value other than 0 for top-level modules. E.g. ``__import__('sys', level=1)`` is now an error. -* Because :attr:`sys.meta_path` and :attr:`sys.path_hooks` now have finders on +* Because :data:`sys.meta_path` and :data:`sys.path_hooks` now have finders on them by default, you will most likely want to use :meth:`list.insert` instead of :meth:`list.append` to add to those lists. -* Because ``None`` is now inserted into :attr:`sys.path_importer_cache`, if you +* Because ``None`` is now inserted into :data:`sys.path_importer_cache`, if you are clearing out entries in the dictionary of paths that do not have a finder, you will need to remove keys paired with values of ``None`` **and** :class:`!imp.NullImporter` to be backwards-compatible. This will lead to extra overhead on older versions of Python that re-insert ``None`` into - :attr:`sys.path_importer_cache` where it represents the use of implicit + :data:`sys.path_importer_cache` where it represents the use of implicit finders, but semantically it should not change anything. * :class:`!importlib.abc.Finder` no longer specifies a ``find_module()`` abstract @@ -2445,7 +2445,7 @@ Porting Python code error instead of sleeping forever. It has always raised an error on posix. * The ``ast.__version__`` constant has been removed. If you need to - make decisions affected by the AST version, use :attr:`sys.version_info` + make decisions affected by the AST version, use :data:`sys.version_info` to make the decision. * Code that used to work around the fact that the :mod:`threading` module used @@ -2462,7 +2462,7 @@ Porting C code -------------- * In the course of changes to the buffer API the undocumented - :c:member:`~Py_buffer.smalltable` member of the + :c:member:`!smalltable` member of the :c:type:`Py_buffer` structure has been removed and the layout of the :c:type:`PyMemoryViewObject` has changed. diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index f3a8873747a3ed..2ddab76814369e 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -775,7 +775,7 @@ of a given opcode and argument, information that is not otherwise available. doctest ------- -A new :ref:`option flag `, :data:`~doctest.FAIL_FAST`, halts +A new :ref:`option flag `, :const:`~doctest.FAIL_FAST`, halts test running as soon as the first failure is detected. (Contributed by R. David Murray and Daniel Urban in :issue:`16522`.) @@ -841,7 +841,7 @@ for example, if the file might have been changed and re-checked in less time than the resolution of a particular filesystem's file modification time field. (Contributed by Mark Levitt in :issue:`18149`.) -New module attribute :data:`~filecmp.DEFAULT_IGNORES` provides the list of +New module attribute :const:`~filecmp.DEFAULT_IGNORES` provides the list of directories that are used as the default value for the *ignore* parameter of the :func:`~filecmp.dircmp` function. (Contributed by Eli Bendersky in :issue:`15442`.) @@ -1189,7 +1189,7 @@ Windows). (Contributed by Brian Curtin in :issue:`11939`.) root on Windows. (Contributed by Tim Golden in :issue:`9035`.) :func:`os.open` supports two new flags on platforms that provide them, -:data:`~os.O_PATH` (un-opened file descriptor), and :data:`~os.O_TMPFILE` +:const:`~os.O_PATH` (un-opened file descriptor), and :const:`~os.O_TMPFILE` (unnamed temporary file; as of 3.4.0 release available only on Linux systems with a kernel version of 3.11 or newer that have uapi headers). (Contributed by Christian Heimes in :issue:`18673` and Benjamin Peterson, respectively.) @@ -1238,8 +1238,8 @@ plistlib stdlib serialization protocols, with new :func:`~plistlib.load`, :func:`~plistlib.dump`, :func:`~plistlib.loads`, and :func:`~plistlib.dumps` functions. (The older API is now deprecated.) In addition to the already -supported XML plist format (:data:`~plistlib.FMT_XML`), it also now supports -the binary plist format (:data:`~plistlib.FMT_BINARY`). (Contributed by Ronald +supported XML plist format (:const:`~plistlib.FMT_XML`), it also now supports +the binary plist format (:const:`~plistlib.FMT_BINARY`). (Contributed by Ronald Oussoren and others in :issue:`14455`.) @@ -1323,14 +1323,14 @@ ability to query or set the resource limits for processes other than the one making the call. (Contributed by Christian Heimes in :issue:`16595`.) On Linux kernel version 2.6.36 or later, there are also some new -Linux specific constants: :attr:`~resource.RLIMIT_MSGQUEUE`, -:attr:`~resource.RLIMIT_NICE`, :attr:`~resource.RLIMIT_RTPRIO`, -:attr:`~resource.RLIMIT_RTTIME`, and :attr:`~resource.RLIMIT_SIGPENDING`. +Linux specific constants: :const:`~resource.RLIMIT_MSGQUEUE`, +:const:`~resource.RLIMIT_NICE`, :const:`~resource.RLIMIT_RTPRIO`, +:const:`~resource.RLIMIT_RTTIME`, and :const:`~resource.RLIMIT_SIGPENDING`. (Contributed by Christian Heimes in :issue:`19324`.) On FreeBSD version 9 and later, there some new FreeBSD specific constants: -:attr:`~resource.RLIMIT_SBSIZE`, :attr:`~resource.RLIMIT_SWAP`, and -:attr:`~resource.RLIMIT_NPTS`. (Contributed by Claudiu Popa in +:const:`~resource.RLIMIT_SBSIZE`, :const:`~resource.RLIMIT_SWAP`, and +:const:`~resource.RLIMIT_NPTS`. (Contributed by Claudiu Popa in :issue:`19343`.) @@ -1388,7 +1388,7 @@ try/except statement by code that only cares whether or not an error occurred. socket ------ -The socket module now supports the :data:`~socket.CAN_BCM` protocol on +The socket module now supports the :const:`~socket.CAN_BCM` protocol on platforms that support it. (Contributed by Brian Thorne in :issue:`15359`.) Socket objects have new methods to get or set their :ref:`inheritable flag @@ -1399,7 +1399,7 @@ The ``socket.AF_*`` and ``socket.SOCK_*`` constants are now enumeration values using the new :mod:`enum` module. This allows meaningful names to be printed during debugging, instead of integer "magic numbers". -The :data:`~socket.AF_LINK` constant is now available on BSD and OSX. +The :const:`~socket.AF_LINK` constant is now available on BSD and OSX. :func:`~socket.inet_pton` and :func:`~socket.inet_ntop` are now supported on Windows. (Contributed by Atsuo Ishimoto in :issue:`7171`.) @@ -1460,8 +1460,8 @@ Heimes in :issue:`18147`.) If OpenSSL 0.9.8 or later is available, :class:`~ssl.SSLContext` has a new attribute :attr:`~ssl.SSLContext.verify_flags` that can be used to control the certificate verification process by setting it to some combination of the new -constants :data:`~ssl.VERIFY_DEFAULT`, :data:`~ssl.VERIFY_CRL_CHECK_LEAF`, -:data:`~ssl.VERIFY_CRL_CHECK_CHAIN`, or :data:`~ssl.VERIFY_X509_STRICT`. +constants :const:`~ssl.VERIFY_DEFAULT`, :const:`~ssl.VERIFY_CRL_CHECK_LEAF`, +:const:`~ssl.VERIFY_CRL_CHECK_CHAIN`, or :const:`~ssl.VERIFY_X509_STRICT`. OpenSSL does not do any CRL verification by default. (Contributed by Christien Heimes in :issue:`8813`.) @@ -1500,7 +1500,7 @@ implementation is required as most of the values aren't standardized and are platform-dependent. (Contributed by Christian Heimes in :issue:`11016`.) The module supports new :mod:`~stat.ST_MODE` flags, :mod:`~stat.S_IFDOOR`, -:attr:`~stat.S_IFPORT`, and :attr:`~stat.S_IFWHT`. (Contributed by +:const:`~stat.S_IFPORT`, and :const:`~stat.S_IFWHT`. (Contributed by Christian Hiemes in :issue:`11016`.) @@ -1849,7 +1849,7 @@ Python's default implementation to a SipHash implementation on platforms that have a 64 bit data type. Any performance differences in comparison with the older FNV algorithm are trivial. -The PEP adds additional fields to the :attr:`sys.hash_info` named tuple to +The PEP adds additional fields to the :data:`sys.hash_info` named tuple to describe the hash algorithm in use by the currently executing binary. Otherwise, the PEP does not alter any existing CPython APIs. @@ -1891,7 +1891,7 @@ Other Build and C API Changes allowing retrieval of function pointers from named type slots when using the limited API. (Contributed by Martin von Löwis in :issue:`17162`.) -* The new :c:func:`Py_SetStandardStreamEncoding` pre-initialization API +* The new :c:func:`!Py_SetStandardStreamEncoding` pre-initialization API allows applications embedding the CPython interpreter to reliably force a particular encoding and error handler for the standard streams. (Contributed by Bastien Montagne and Nick Coghlan in :issue:`16129`.) @@ -2085,7 +2085,7 @@ Deprecations in the Python API :meth:`importlib.abc.MetaPathFinder.find_spec`; :meth:`!importlib.abc.PathEntryFinder.find_loader` and :meth:`!find_module` are replaced by - :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the ``xxxLoader`` ABC + :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the :samp:`{xxx}Loader` ABC ``load_module`` methods (:meth:`!importlib.abc.Loader.load_module`, :meth:`!importlib.abc.InspectLoader.load_module`, :meth:`!importlib.abc.FileLoader.load_module`, diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index ccf71bf08e8608..ae6affcab664c6 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -478,7 +478,7 @@ not make an additional system call:: PEP 475: Retry system calls failing with EINTR ---------------------------------------------- -An :py:data:`errno.EINTR` error code is returned whenever a system call, that +An :py:const:`errno.EINTR` error code is returned whenever a system call, that is waiting for I/O, is interrupted by a signal. Previously, Python would raise :exc:`InterruptedError` in such cases. This meant that, when writing a Python application, the developer had two choices: @@ -527,7 +527,7 @@ by a signal: :func:`~os.writev`; * special cases: :func:`os.close` and :func:`os.dup2` now ignore - :py:data:`~errno.EINTR` errors; the syscall is not retried (see the PEP + :py:const:`~errno.EINTR` errors; the syscall is not retried (see the PEP for the rationale); * :mod:`select` functions: :func:`devpoll.poll() `, @@ -921,7 +921,7 @@ and improves their substitutability for lists. Docstrings produced by :func:`~collections.namedtuple` can now be updated:: Point = namedtuple('Point', ['x', 'y']) - Point.__doc__ += ': Cartesian coodinate' + Point.__doc__ += ': Cartesian coordinate' Point.x.__doc__ = 'abscissa' Point.y.__doc__ = 'ordinate' @@ -1045,8 +1045,8 @@ not just sequences. (Contributed by Serhiy Storchaka in :issue:`23171`.) curses ------ -The new :func:`~curses.update_lines_cols` function updates the :envvar:`LINES` -and :envvar:`COLS` environment variables. This is useful for detecting +The new :func:`~curses.update_lines_cols` function updates the :data:`LINES` +and :data:`COLS` module variables. This is useful for detecting manual screen resizing. (Contributed by Arnon Yaari in :issue:`4254`.) @@ -1498,7 +1498,7 @@ use ``/dev/urandom`` and avoiding failures due to potential file descriptor exhaustion. (Contributed by Victor Stinner in :issue:`22181`.) New :func:`~os.get_blocking` and :func:`~os.set_blocking` functions allow -getting and setting a file descriptor's blocking mode (:data:`~os.O_NONBLOCK`.) +getting and setting a file descriptor's blocking mode (:const:`~os.O_NONBLOCK`.) (Contributed by Victor Stinner in :issue:`22054`.) The :func:`~os.truncate` and :func:`~os.ftruncate` functions are now supported @@ -1783,7 +1783,7 @@ the TLS handshake. The new :meth:`SSLSocket.selected_alpn_protocol() ` returns the protocol that was selected during the TLS handshake. -The :data:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. +The :const:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. Other Changes @@ -2192,7 +2192,7 @@ encode error with ``\N{...}`` escapes. (Contributed by Serhiy Storchaka in :issue:`19676`.) A new :c:func:`PyErr_FormatV` function similar to :c:func:`PyErr_Format`, -but accepts a ``va_list`` argument. +but accepts a :c:type:`va_list` argument. (Contributed by Antoine Pitrou in :issue:`18711`.) A new :c:data:`PyExc_RecursionError` exception. @@ -2476,7 +2476,7 @@ Changes in the Python API in Python 3.5, all old ``.pyo`` files from previous versions of Python are invalid regardless of this PEP. -* The :mod:`socket` module now exports the :data:`~socket.CAN_RAW_FD_FRAMES` +* The :mod:`socket` module now exports the :const:`~socket.CAN_RAW_FD_FRAMES` constant on linux 3.6 and greater. * The :func:`ssl.cert_time_to_seconds` function now interprets the input time @@ -2512,7 +2512,7 @@ Changes in the Python API Changes in the C API -------------------- -* The undocumented :c:member:`~PyMemoryViewObject.format` member of the +* The undocumented :c:member:`!format` member of the (non-public) :c:type:`PyMemoryViewObject` structure has been removed. All extensions relying on the relevant parts in ``memoryobject.h`` must be rebuilt. @@ -2520,7 +2520,7 @@ Changes in the C API * The :c:type:`PyMemAllocator` structure was renamed to :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. -* Removed non-documented macro :c:macro:`PyObject_REPR` which leaked references. +* Removed non-documented macro :c:macro:`!PyObject_REPR()` which leaked references. Use format character ``%R`` in :c:func:`PyUnicode_FromFormat`-like functions to format the :func:`repr` of the object. (Contributed by Serhiy Storchaka in :issue:`22453`.) @@ -2533,7 +2533,7 @@ Changes in the C API * As part of the :pep:`492` implementation, the ``tp_reserved`` slot of :c:type:`PyTypeObject` was replaced with a - :c:member:`tp_as_async` slot. Refer to :ref:`coro-objects` for + :c:member:`~PyTypeObject.tp_as_async` slot. Refer to :ref:`coro-objects` for new types, structures and functions. diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index 7d293c634f237b..c15d8be651fd17 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -650,8 +650,8 @@ compiled in release mode using ``PYTHONMALLOC=debug``. Effects of debug hooks: * Detect writes before the start of a buffer (buffer underflows) * Detect writes after the end of a buffer (buffer overflows) * Check that the :term:`GIL ` is held when allocator - functions of :c:data:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and - :c:data:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. + functions of :c:macro:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and + :c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. Checking if the GIL is held is also a new feature of Python 3.6. @@ -1388,7 +1388,7 @@ are treated as punctuation. site ---- -When specifying paths to add to :attr:`sys.path` in a ``.pth`` file, +When specifying paths to add to :data:`sys.path` in a ``.pth`` file, you may now specify file paths on top of directories (e.g. zip files). (Contributed by Wolfgang Langner in :issue:`26587`). @@ -1404,7 +1404,7 @@ socket ------ The :func:`~socket.socket.ioctl` function now supports the -:data:`~socket.SIO_LOOPBACK_FAST_PATH` control code. +:const:`~socket.SIO_LOOPBACK_FAST_PATH` control code. (Contributed by Daniel Stokes in :issue:`26536`.) The :meth:`~socket.socket.getsockopt` constants ``SO_DOMAIN``, @@ -1416,7 +1416,7 @@ The :meth:`~socket.socket.setsockopt` now supports the (Contributed by Christian Heimes in :issue:`27744`.) The socket module now supports the address family -:data:`~socket.AF_ALG` to interface with Linux Kernel crypto API. ``ALG_*``, +:const:`~socket.AF_ALG` to interface with Linux Kernel crypto API. ``ALG_*``, ``SOL_ALG`` and :meth:`~socket.socket.sendmsg_afalg` were added. (Contributed by Christian Heimes in :issue:`27744` with support from Victor Stinner.) @@ -1822,7 +1822,7 @@ Optimizations up to 80% faster. (Contributed by Josh Snider in :issue:`26574`). * Allocator functions of the :c:func:`PyMem_Malloc` domain - (:c:data:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc memory allocator + (:c:macro:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc memory allocator ` instead of :c:func:`malloc` function of the C library. The pymalloc allocator is optimized for objects smaller or equal to 512 bytes with a short lifetime, and use :c:func:`malloc` for larger memory blocks. @@ -1874,8 +1874,8 @@ Build and C API Changes (Original patch by Alecsandru Patrascu of Intel in :issue:`26359`.) * The :term:`GIL ` must now be held when allocator - functions of :c:data:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and - :c:data:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. + functions of :c:macro:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and + :c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. * New :c:func:`Py_FinalizeEx` API which indicates if flushing buffered data failed. @@ -2010,7 +2010,7 @@ been deprecated in previous versions of Python in favour of :meth:`importlib.abc.Loader.exec_module`. The :class:`importlib.machinery.WindowsRegistryFinder` class is now -deprecated. As of 3.6.0, it is still added to :attr:`sys.meta_path` by +deprecated. As of 3.6.0, it is still added to :data:`sys.meta_path` by default (on Windows), but this may change in future releases. os @@ -2066,9 +2066,9 @@ environment. (Contributed by Brett Cannon in :issue:`25154`.) Deprecated functions and types of the C API ------------------------------------------- -Undocumented functions :c:func:`PyUnicode_AsEncodedObject`, -:c:func:`PyUnicode_AsDecodedObject`, :c:func:`PyUnicode_AsEncodedUnicode` -and :c:func:`PyUnicode_AsDecodedUnicode` are deprecated now. +Undocumented functions :c:func:`!PyUnicode_AsEncodedObject`, +:c:func:`!PyUnicode_AsDecodedObject`, :c:func:`!PyUnicode_AsEncodedUnicode` +and :c:func:`!PyUnicode_AsDecodedUnicode` are deprecated now. Use the :ref:`generic codec based API ` instead. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 24244ff17b1ea0..a7d5c3db6ddcb2 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -1280,13 +1280,13 @@ This function should be used instead of :func:`os.close` for better compatibility across platforms. (Contributed by Christian Heimes in :issue:`32454`.) -The :mod:`socket` module now exposes the :data:`socket.TCP_CONGESTION` -(Linux 2.6.13), :data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37), and -:data:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constants. +The :mod:`socket` module now exposes the :const:`socket.TCP_CONGESTION` +(Linux 2.6.13), :const:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37), and +:const:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constants. (Contributed by Omar Sandoval in :issue:`26273` and Nathaniel J. Smith in :issue:`29728`.) -Support for :data:`socket.AF_VSOCK` sockets has been added to allow +Support for :const:`socket.AF_VSOCK` sockets has been added to allow communication between virtual machines and their hosts. (Contributed by Cathy Avery in :issue:`27584`.) @@ -1394,7 +1394,7 @@ subprocess The :func:`subprocess.run` function accepts the new *capture_output* keyword argument. When true, stdout and stderr will be captured. -This is equivalent to passing :data:`subprocess.PIPE` as *stdout* and +This is equivalent to passing :const:`subprocess.PIPE` as *stdout* and *stderr* arguments. (Contributed by Bo Bayles in :issue:`32102`.) @@ -1453,12 +1453,12 @@ time New clock identifiers have been added: -* :data:`time.CLOCK_BOOTTIME` (Linux): Identical to - :data:`time.CLOCK_MONOTONIC`, except it also includes any time that the +* :const:`time.CLOCK_BOOTTIME` (Linux): Identical to + :const:`time.CLOCK_MONOTONIC`, except it also includes any time that the system is suspended. -* :data:`time.CLOCK_PROF` (FreeBSD, NetBSD and OpenBSD): High-resolution +* :const:`time.CLOCK_PROF` (FreeBSD, NetBSD and OpenBSD): High-resolution per-process CPU timer. -* :data:`time.CLOCK_UPTIME` (FreeBSD, OpenBSD): Time whose absolute value is +* :const:`time.CLOCK_UPTIME` (FreeBSD, OpenBSD): Time whose absolute value is the time the system has been running and not suspended, providing accurate uptime measurement. @@ -1580,13 +1580,13 @@ The initialization of the default warnings filters has changed as follows: * warnings filters enabled via the command line or the environment now have the following order of precedence: - * the ``BytesWarning`` filter for :option:`-b` (or ``-bb``) - * any filters specified with the :option:`-W` option - * any filters specified with the :envvar:`PYTHONWARNINGS` environment - variable - * any other CPython specific filters (e.g. the ``default`` filter added - for the new ``-X dev`` mode) - * any implicit filters defined directly by the warnings machinery + * the ``BytesWarning`` filter for :option:`-b` (or ``-bb``) + * any filters specified with the :option:`-W` option + * any filters specified with the :envvar:`PYTHONWARNINGS` environment + variable + * any other CPython specific filters (e.g. the ``default`` filter added + for the new ``-X dev`` mode) + * any implicit filters defined directly by the warnings machinery * in :ref:`CPython debug builds `, all warnings are now displayed by default (the implicit filter list is empty) @@ -1674,10 +1674,10 @@ The new :c:func:`import__find__load__start` and module imports. (Contributed by Christian Heimes in :issue:`31574`.) -The fields :c:member:`name` and :c:member:`doc` of structures +The fields :c:member:`!name` and :c:member:`!doc` of structures :c:type:`PyMemberDef`, :c:type:`PyGetSetDef`, :c:type:`PyStructSequence_Field`, :c:type:`PyStructSequence_Desc`, -and :c:type:`wrapperbase` are now of type ``const char *`` rather of +and :c:struct:`wrapperbase` are now of type ``const char *`` rather of ``char *``. (Contributed by Serhiy Storchaka in :issue:`28761`.) The result of :c:func:`PyUnicode_AsUTF8AndSize` and :c:func:`PyUnicode_AsUTF8` @@ -2495,12 +2495,12 @@ either in embedding applications, or in CPython itself. :issue:`22257`, and further updated by Nick, Eric, and Victor Stinner in a number of other issues). Some known details affected: -* :c:func:`PySys_AddWarnOptionUnicode` is not currently usable by embedding +* :c:func:`!PySys_AddWarnOptionUnicode` is not currently usable by embedding applications due to the requirement to create a Unicode object prior to - calling ``Py_Initialize``. Use :c:func:`PySys_AddWarnOption` instead. + calling ``Py_Initialize``. Use :c:func:`!PySys_AddWarnOption` instead. * warnings filters added by an embedding application with - :c:func:`PySys_AddWarnOption` should now more consistently take precedence + :c:func:`!PySys_AddWarnOption` should now more consistently take precedence over the default filters set by the interpreter Due to changes in the way the default warnings filters are configured, diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 16762817ab8250..a2a67264deff66 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -123,7 +123,7 @@ There is a new function parameter syntax ``/`` to indicate that some function parameters must be specified positionally and cannot be used as keyword arguments. This is the same notation shown by ``help()`` for C functions annotated with Larry Hastings' -:ref:`Argument Clinic ` tool. +`Argument Clinic `__ tool. In the following example, parameters *a* and *b* are positional-only, while *c* or *d* can be positional or keyword, and *e* or *f* are @@ -404,7 +404,7 @@ Other Language Changes or :meth:`~object.__complex__` is not available. (Contributed by Serhiy Storchaka in :issue:`20092`.) -* Added support of ``\N{name}`` escapes in :mod:`regular expressions `:: +* Added support of :samp:`\\N\\{{name}\\}` escapes in :mod:`regular expressions `:: >>> notice = 'Copyright © 2019' >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})') @@ -947,7 +947,7 @@ This made it difficult to update, experiment with, or teach the various logging configuration options using the interactive prompt or a Jupyter notebook. -(Suggested by Raymond Hettinger, implemented by Dong-hee Na, and +(Suggested by Raymond Hettinger, implemented by Donghee Na, and reviewed by Vinay Sajip in :issue:`33897`.) @@ -1305,7 +1305,7 @@ Zackery Spytz in :issue:`25451`.) time ---- -Added new clock :data:`~time.CLOCK_UPTIME_RAW` for macOS 10.12. +Added new clock :const:`~time.CLOCK_UPTIME_RAW` for macOS 10.12. (Contributed by Joannah Nanjekye in :issue:`35702`.) @@ -1574,12 +1574,12 @@ Build and C API Changes * :c:func:`Py_INCREF`, :c:func:`Py_DECREF` * :c:func:`Py_XINCREF`, :c:func:`Py_XDECREF` * :c:func:`PyObject_INIT`, :c:func:`PyObject_INIT_VAR` - * Private functions: :c:func:`_PyObject_GC_TRACK`, - :c:func:`_PyObject_GC_UNTRACK`, :c:func:`_Py_Dealloc` + * Private functions: :c:func:`!_PyObject_GC_TRACK`, + :c:func:`!_PyObject_GC_UNTRACK`, :c:func:`!_Py_Dealloc` (Contributed by Victor Stinner in :issue:`35059`.) -* The :c:func:`PyByteArray_Init` and :c:func:`PyByteArray_Fini` functions have +* The :c:func:`!PyByteArray_Init` and :c:func:`!PyByteArray_Fini` functions have been removed. They did nothing since Python 2.7.4 and Python 3.2.0, were excluded from the limited API (stable ABI), and were not documented. (Contributed by Victor Stinner in :issue:`35713`.) @@ -1628,7 +1628,7 @@ Build and C API Changes parameter for indicating the number of positional-only arguments. (Contributed by Pablo Galindo in :issue:`37221`.) -* :c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full +* :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`). (Contributed by Victor Stinner in :issue:`38234`.) @@ -1714,7 +1714,7 @@ Deprecated * The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread` has been deprecated. - (Contributed by Dong-hee Na in :issue:`35283`.) + (Contributed by Donghee Na in :issue:`35283`.) * Many builtin and extension functions that take integer arguments will now emit a deprecation warning for :class:`~decimal.Decimal`\ s, @@ -1839,18 +1839,18 @@ Changes in Python behavior classes will affect their string representation. (Contributed by Serhiy Storchaka in :issue:`36793`.) -* On AIX, :attr:`sys.platform` doesn't contain the major version anymore. +* On AIX, :data:`sys.platform` doesn't contain the major version anymore. It is always ``'aix'``, instead of ``'aix3'`` .. ``'aix7'``. Since older Python versions include the version number, so it is recommended to always use ``sys.platform.startswith('aix')``. (Contributed by M. Felt in :issue:`36588`.) -* :c:func:`PyEval_AcquireLock` and :c:func:`PyEval_AcquireThread` now +* :c:func:`!PyEval_AcquireLock` and :c:func:`!PyEval_AcquireThread` now terminate the current thread if called while the interpreter is finalizing, making them consistent with :c:func:`PyEval_RestoreThread`, :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`. If this - behavior is not desired, guard the call by checking :c:func:`_Py_IsFinalizing` - or :c:func:`sys.is_finalizing`. + behavior is not desired, guard the call by checking :c:func:`!_Py_IsFinalizing` + or :func:`sys.is_finalizing`. (Contributed by Joannah Nanjekye in :issue:`36475`.) @@ -2021,7 +2021,7 @@ Changes in the C API *cf_flags*. (Contributed by Guido van Rossum in :issue:`35766`.) -* The :c:func:`PyEval_ReInitThreads` function has been removed from the C API. +* The :c:func:`!PyEval_ReInitThreads` function has been removed from the C API. It should not be called explicitly: use :c:func:`PyOS_AfterFork_Child` instead. (Contributed by Victor Stinner in :issue:`36728`.) @@ -2061,8 +2061,8 @@ Changes in the C API * Remove :c:macro:`Py_INCREF` on the type object after allocating an instance - if any. - This may happen after calling :c:func:`PyObject_New`, - :c:func:`PyObject_NewVar`, :c:func:`PyObject_GC_New`, + This may happen after calling :c:macro:`PyObject_New`, + :c:macro:`PyObject_NewVar`, :c:func:`PyObject_GC_New`, :c:func:`PyObject_GC_NewVar`, or any other custom allocator that uses :c:func:`PyObject_Init` or :c:func:`PyObject_INIT`. @@ -2116,12 +2116,12 @@ Changes in the C API extension types across feature releases, anymore. A :c:type:`PyTypeObject` exported by a third-party extension module is supposed to have all the slots expected in the current Python version, including - :c:member:`~PyTypeObject.tp_finalize` (:const:`Py_TPFLAGS_HAVE_FINALIZE` + :c:member:`~PyTypeObject.tp_finalize` (:c:macro:`Py_TPFLAGS_HAVE_FINALIZE` is not checked anymore before reading :c:member:`~PyTypeObject.tp_finalize`). (Contributed by Antoine Pitrou in :issue:`32388`.) -* The functions :c:func:`PyNode_AddChild` and :c:func:`PyParser_AddToken` now accept +* The functions :c:func:`!PyNode_AddChild` and :c:func:`!PyParser_AddToken` now accept two additional ``int`` arguments *end_lineno* and *end_col_offset*. * The :file:`libpython38.a` file to allow MinGW tools to link directly against diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 976d72a0342510..cb2482ee48d7fa 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -44,7 +44,6 @@ This article explains the new features in Python 3.9, compared to 3.8. Python 3.9 was released on October 5, 2020. - For full details, see the :ref:`changelog `. .. seealso:: @@ -415,7 +414,7 @@ datetime The :meth:`~datetime.date.isocalendar()` of :class:`datetime.date` and :meth:`~datetime.datetime.isocalendar()` of :class:`datetime.datetime` methods now returns a :func:`~collections.namedtuple` instead of a :class:`tuple`. -(Contributed by Dong-hee Na in :issue:`24416`.) +(Contributed by Donghee Na in :issue:`24416`.) distutils --------- @@ -427,16 +426,16 @@ digests. It skips MD5 on platforms that block MD5 digest. fcntl ----- -Added constants :data:`~fcntl.F_OFD_GETLK`, :data:`~fcntl.F_OFD_SETLK` -and :data:`~fcntl.F_OFD_SETLKW`. -(Contributed by Dong-hee Na in :issue:`38602`.) +Added constants :const:`~fcntl.F_OFD_GETLK`, :const:`~fcntl.F_OFD_SETLK` +and :const:`~fcntl.F_OFD_SETLKW`. +(Contributed by Donghee Na in :issue:`38602`.) ftplib ------- :class:`~ftplib.FTP` and :class:`~ftplib.FTP_TLS` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) gc -- @@ -468,7 +467,7 @@ http ---- HTTP status codes ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` are added to -:class:`http.HTTPStatus`. (Contributed by Dong-hee Na in :issue:`39509` and Ross Rhodes in :issue:`39507`.) +:class:`http.HTTPStatus`. (Contributed by Donghee Na in :issue:`39509` and Ross Rhodes in :issue:`39507`.) IDLE and idlelib ---------------- @@ -509,14 +508,14 @@ an optional *timeout* parameter for their constructors. Also, the :meth:`~imaplib.IMAP4.open` method now has an optional *timeout* parameter with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and :class:`~imaplib.IMAP4_stream` were applied to this change. -(Contributed by Dong-hee Na in :issue:`38615`.) +(Contributed by Donghee Na in :issue:`38615`.) :meth:`imaplib.IMAP4.unselect` is added. :meth:`imaplib.IMAP4.unselect` frees server's resources associated with the selected mailbox and returns the server to the authenticated state. This command performs the same actions as :meth:`imaplib.IMAP4.close`, except that no messages are permanently removed from the currently -selected mailbox. (Contributed by Dong-hee Na in :issue:`40375`.) +selected mailbox. (Contributed by Donghee Na in :issue:`40375`.) importlib --------- @@ -588,16 +587,16 @@ nntplib :class:`~!nntplib.NNTP` and :class:`~!nntplib.NNTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) os -- -Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for :attr:`si_code`. -(Contributed by Dong-hee Na in :issue:`38493`.) +Added :const:`~os.CLD_KILLED` and :const:`~os.CLD_STOPPED` for :attr:`si_code`. +(Contributed by Donghee Na in :issue:`38493`.) Exposed the Linux-specific :func:`os.pidfd_open` (:issue:`38692`) and -:data:`os.P_PIDFD` (:issue:`38713`) for process management with file +:const:`os.P_PIDFD` (:issue:`38713`) for process management with file descriptors. The :func:`os.unsetenv` function is now also available on Windows. @@ -629,7 +628,7 @@ poplib :class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) pprint ------ @@ -661,19 +660,19 @@ smtplib :class:`~smtplib.SMTP` and :class:`~smtplib.SMTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) :class:`~smtplib.LMTP` constructor now has an optional *timeout* parameter. -(Contributed by Dong-hee Na in :issue:`39329`.) +(Contributed by Donghee Na in :issue:`39329`.) socket ------ -The :mod:`socket` module now exports the :data:`~socket.CAN_RAW_JOIN_FILTERS` +The :mod:`socket` module now exports the :const:`~socket.CAN_RAW_JOIN_FILTERS` constant on Linux 4.1 and greater. (Contributed by Stefan Tatschner and Zackery Spytz in :issue:`25780`.) -The socket module now supports the :data:`~socket.CAN_J1939` protocol on +The socket module now supports the :const:`~socket.CAN_J1939` protocol on platforms that support it. (Contributed by Karl Ding in :issue:`40291`.) The socket module now has the :func:`socket.send_fds` and @@ -692,13 +691,13 @@ which has nanosecond resolution, rather than sys --- -Added a new :attr:`sys.platlibdir` attribute: name of the platform-specific +Added a new :data:`sys.platlibdir` attribute: name of the platform-specific library directory. It is used to build the path of standard library and the paths of installed extension modules. It is equal to ``"lib"`` on most platforms. On Fedora and SuSE, it is equal to ``"lib64"`` on 64-bit platforms. (Contributed by Jan MatÄ›jek, MatÄ›j Cepl, Charalampos Stratakis and Victor Stinner in :issue:`1294959`.) -Previously, :attr:`sys.stderr` was block-buffered when non-interactive. Now +Previously, :data:`sys.stderr` was block-buffered when non-interactive. Now ``stderr`` defaults to always being line-buffered. (Contributed by Jendrik Seipp in :issue:`13601`.) @@ -777,7 +776,7 @@ Optimizations * A number of Python builtins (:class:`range`, :class:`tuple`, :class:`set`, :class:`frozenset`, :class:`list`, :class:`dict`) are now sped up by using :pep:`590` vectorcall protocol. - (Contributed by Dong-hee Na, Mark Shannon, Jeroen Demeyer and Petr Viktorin in :issue:`37207`.) + (Contributed by Donghee Na, Mark Shannon, Jeroen Demeyer and Petr Viktorin in :issue:`37207`.) * Optimized :func:`~set.difference_update` for the case when the other set is much larger than the base set. @@ -791,7 +790,7 @@ Optimizations * :term:`floor division` of float operation now has a better performance. Also the message of :exc:`ZeroDivisionError` for this operation is updated. - (Contributed by Dong-hee Na in :issue:`39434`.) + (Contributed by Donghee Na in :issue:`39434`.) * Decoding short ASCII strings with UTF-8 and ascii codecs is now about 15% faster. (Contributed by Inada Naoki in :issue:`37348`.) @@ -870,9 +869,9 @@ Deprecated users can leverage the Abstract Syntax Tree (AST) generation and compilation stage, using the :mod:`ast` module. -* The Public C API functions :c:func:`PyParser_SimpleParseStringFlags`, - :c:func:`PyParser_SimpleParseStringFlagsFilename`, - :c:func:`PyParser_SimpleParseFileFlags` and :c:func:`PyNode_Compile` +* The Public C API functions :c:func:`!PyParser_SimpleParseStringFlags`, + :c:func:`!PyParser_SimpleParseStringFlagsFilename`, + :c:func:`!PyParser_SimpleParseFileFlags` and :c:func:`!PyNode_Compile` are deprecated and will be removed in Python 3.10 together with the old parser. * Using :data:`NotImplemented` in a boolean context has been deprecated, @@ -923,10 +922,10 @@ Deprecated (Contributed by Batuhan Taskaya in :issue:`39639` and :issue:`39969` and Serhiy Storchaka in :issue:`39988`.) -* The :c:func:`PyEval_InitThreads` and :c:func:`PyEval_ThreadsInitialized` +* The :c:func:`!PyEval_InitThreads` and :c:func:`!PyEval_ThreadsInitialized` functions are now deprecated and will be removed in Python 3.11. Calling - :c:func:`PyEval_InitThreads` now does nothing. The :term:`GIL` is initialized - by :c:func:`Py_Initialize()` since Python 3.7. + :c:func:`!PyEval_InitThreads` now does nothing. The :term:`GIL` is initialized + by :c:func:`Py_Initialize` since Python 3.7. (Contributed by Victor Stinner in :issue:`39877`.) * Passing ``None`` as the first argument to the :func:`shlex.split` function @@ -961,7 +960,7 @@ Removed are not supported or not enabled by NNTP server administrators. For ``xgtitle()``, please use :meth:`!nntplib.NNTP.descriptions` or :meth:`!nntplib.NNTP.description` instead. - (Contributed by Dong-hee Na in :issue:`39366`.) + (Contributed by Donghee Na in :issue:`39366`.) * :class:`array.array`: ``tostring()`` and ``fromstring()`` methods have been removed. They were aliases to ``tobytes()`` and ``frombytes()``, deprecated @@ -994,7 +993,7 @@ Removed * The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread` has been removed. It was deprecated since Python 3.8. Use :meth:`~threading.Thread.is_alive()` instead. - (Contributed by Dong-hee Na in :issue:`37804`.) + (Contributed by Donghee Na in :issue:`37804`.) * Methods ``getchildren()`` and ``getiterator()`` of classes :class:`~xml.etree.ElementTree.ElementTree` and @@ -1084,7 +1083,7 @@ Changes in the Python API ``__VENV_PROMPT__`` is set to ``""``. * The :meth:`select.epoll.unregister` method no longer ignores the - :data:`~errno.EBADF` error. + :const:`~errno.EBADF` error. (Contributed by Victor Stinner in :issue:`39239`.) * The *compresslevel* parameter of :class:`bz2.BZ2File` became keyword-only, @@ -1115,9 +1114,9 @@ Changes in the Python API ``PyCF_ALLOW_TOP_LEVEL_AWAIT`` was clashing with ``CO_FUTURE_DIVISION``. (Contributed by Batuhan Taskaya in :issue:`39562`) -* ``array('u')`` now uses ``wchar_t`` as C type instead of ``Py_UNICODE``. +* ``array('u')`` now uses :c:type:`wchar_t` as C type instead of ``Py_UNICODE``. This change doesn't affect to its behavior because ``Py_UNICODE`` is alias - of ``wchar_t`` since Python 3.3. + of :c:type:`wchar_t` since Python 3.3. (Contributed by Inada Naoki in :issue:`34538`.) * The :func:`logging.getLogger` API now returns the root logger when passed @@ -1226,8 +1225,8 @@ Build Changes ============= * Added ``--with-platlibdir`` option to the ``configure`` script: name of the - platform-specific library directory, stored in the new :attr:`sys.platlibdir` - attribute. See :attr:`sys.platlibdir` attribute for more information. + platform-specific library directory, stored in the new :data:`sys.platlibdir` + attribute. See :data:`sys.platlibdir` attribute for more information. (Contributed by Jan MatÄ›jek, MatÄ›j Cepl, Charalampos Stratakis and Victor Stinner in :issue:`1294959`.) @@ -1276,7 +1275,7 @@ New Features * :pep:`573`: Added :c:func:`PyType_FromModuleAndSpec` to associate a module with a class; :c:func:`PyType_GetModule` and :c:func:`PyType_GetModuleState` to retrieve the module and its state; and - :c:data:`PyCMethod` and :c:data:`METH_METHOD` to allow a method to + :c:type:`PyCMethod` and :c:macro:`METH_METHOD` to allow a method to access the class it was defined in. (Contributed by Marcel Plch and Petr Viktorin in :issue:`38787`.) @@ -1315,7 +1314,7 @@ New Features * The :c:func:`PyModule_AddType` function is added to help adding a type to a module. - (Contributed by Dong-hee Na in :issue:`40024`.) + (Contributed by Donghee Na in :issue:`40024`.) * Added the functions :c:func:`PyObject_GC_IsTracked` and :c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if @@ -1370,8 +1369,8 @@ Porting to Python 3.9 (Contributed by Victor Stinner in :issue:`40241`.) * The ``Py_UNICODE_COPY``, ``Py_UNICODE_FILL``, ``PyUnicode_WSTR_LENGTH``, - :c:func:`PyUnicode_FromUnicode`, :c:func:`PyUnicode_AsUnicode`, - ``_PyUnicode_AsUnicode``, and :c:func:`PyUnicode_AsUnicodeAndSize` are + :c:func:`!PyUnicode_FromUnicode`, :c:func:`!PyUnicode_AsUnicode`, + ``_PyUnicode_AsUnicode``, and :c:func:`!PyUnicode_AsUnicodeAndSize` are marked as deprecated in C. They have been deprecated by :pep:`393` since Python 3.3. (Contributed by Inada Naoki in :issue:`36346`.) @@ -1389,8 +1388,8 @@ Porting to Python 3.9 * :c:func:`PyObject_IS_GC` macro was converted to a function. * The :c:func:`PyObject_NEW` macro becomes an alias to the - :c:func:`PyObject_New` macro, and the :c:func:`PyObject_NEW_VAR` macro - becomes an alias to the :c:func:`PyObject_NewVar` macro. They no longer + :c:macro:`PyObject_New` macro, and the :c:func:`PyObject_NEW_VAR` macro + becomes an alias to the :c:macro:`PyObject_NewVar` macro. They no longer access directly the :c:member:`PyTypeObject.tp_basicsize` member. * :c:func:`PyObject_GET_WEAKREFS_LISTPTR` macro was converted to a function: diff --git a/Grammar/Tokens b/Grammar/Tokens index 618ae811d824b0..20bb803b7d58a6 100644 --- a/Grammar/Tokens +++ b/Grammar/Tokens @@ -56,8 +56,6 @@ COLONEQUAL ':=' EXCLAMATION '!' OP -AWAIT -ASYNC TYPE_IGNORE TYPE_COMMENT SOFT_KEYWORD diff --git a/Grammar/python.gram b/Grammar/python.gram index c1863aec67cc2b..8b479a716ac44d 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -19,8 +19,6 @@ _PyPegen_parse(Parser *p) result = eval_rule(p); } else if (p->start_rule == Py_func_type_input) { result = func_type_rule(p); - } else if (p->start_rule == Py_fstring_input) { - result = fstring_rule(p); } return result; @@ -89,7 +87,6 @@ file[mod_ty]: a=[statements] ENDMARKER { _PyPegen_make_module(p, a) } interactive[mod_ty]: a=statement_newline { _PyAST_Interactive(a, p->arena) } eval[mod_ty]: a=expressions NEWLINE* ENDMARKER { _PyAST_Expression(a, p->arena) } func_type[mod_ty]: '(' a=[type_expressions] ')' '->' b=expression NEWLINE* ENDMARKER { _PyAST_FunctionType(a, b, p->arena) } -fstring[expr_ty]: star_expressions # GENERAL STATEMENTS # ================== @@ -127,11 +124,11 @@ simple_stmt[stmt_ty] (memo): | &'nonlocal' nonlocal_stmt compound_stmt[stmt_ty]: - | &('def' | '@' | ASYNC) function_def + | &('def' | '@' | 'async') function_def | &'if' if_stmt | &('class' | '@') class_def - | &('with' | ASYNC) with_stmt - | &('for' | ASYNC) for_stmt + | &('with' | 'async') with_stmt + | &('for' | 'async') for_stmt | &'try' try_stmt | &'while' while_stmt | match_stmt @@ -272,7 +269,7 @@ function_def_raw[stmt_ty]: _PyAST_FunctionDef(n->v.Name.id, (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)), b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA) } - | ASYNC 'def' n=NAME t=[type_params] &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block { + | 'async' 'def' n=NAME t=[type_params] &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block { CHECK_VERSION( stmt_ty, 5, @@ -385,7 +382,7 @@ for_stmt[stmt_ty]: | invalid_for_stmt | 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] { _PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) } - | ASYNC 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] { + | 'async' 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] { CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) } | invalid_for_target @@ -398,9 +395,9 @@ with_stmt[stmt_ty]: CHECK_VERSION(stmt_ty, 9, "Parenthesized context managers are", _PyAST_With(a, b, NULL, EXTRA)) } | 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) } - | ASYNC 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block { + | 'async' 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block { CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NULL, EXTRA)) } - | ASYNC 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { + | 'async' 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) } | invalid_with_stmt @@ -647,20 +644,20 @@ type_param_seq[asdl_type_param_seq*]: a[asdl_type_param_seq*]=','.type_param+ [' type_param[type_param_ty] (memo): | a=NAME b=[type_param_bound] { _PyAST_TypeVar(a->v.Name.id, b, EXTRA) } - | '*' a=NAME colon=":" e=expression { + | '*' a=NAME colon=':' e=expression { RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind ? "cannot use constraints with TypeVarTuple" : "cannot use bound with TypeVarTuple") } | '*' a=NAME { _PyAST_TypeVarTuple(a->v.Name.id, EXTRA) } - | '**' a=NAME colon=":" e=expression { + | '**' a=NAME colon=':' e=expression { RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind ? "cannot use constraints with ParamSpec" : "cannot use bound with ParamSpec") } | '**' a=NAME { _PyAST_ParamSpec(a->v.Name.id, EXTRA) } -type_param_bound[expr_ty]: ":" e=expression { e } +type_param_bound[expr_ty]: ':' e=expression { e } # EXPRESSIONS # ----------- @@ -814,7 +811,7 @@ power[expr_ty]: # Primary elements are things like "obj.something.something", "obj[something]", "obj(something)", "obj" ... await_primary[expr_ty] (memo): - | AWAIT a=primary { CHECK_VERSION(expr_ty, 5, "Await expressions are", _PyAST_Await(a, EXTRA)) } + | 'await' a=primary { CHECK_VERSION(expr_ty, 5, "Await expressions are", _PyAST_Await(a, EXTRA)) } | primary primary[expr_ty]: @@ -915,7 +912,7 @@ fstring_middle[expr_ty]: | fstring_replacement_field | t=FSTRING_MIDDLE { _PyPegen_constant_from_token(p, t) } fstring_replacement_field[expr_ty]: - | '{' a=(yield_expr | star_expressions) debug_expr="="? conversion=[fstring_conversion] format=[fstring_full_format_spec] rbrace='}' { + | '{' a=(yield_expr | star_expressions) debug_expr='='? conversion=[fstring_conversion] format=[fstring_full_format_spec] rbrace='}' { _PyPegen_formatted_value(p, a, debug_expr, conversion, format, rbrace, EXTRA) } | invalid_replacement_field fstring_conversion[ResultTokenWithMetadata*]: @@ -966,7 +963,7 @@ for_if_clauses[asdl_comprehension_seq*]: | a[asdl_comprehension_seq*]=for_if_clause+ { a } for_if_clause[comprehension_ty]: - | ASYNC 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* { + | 'async' 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* { CHECK_VERSION(comprehension_ty, 6, "Async comprehensions are", _PyAST_comprehension(a, b, c, 1, p->arena)) } | 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* { _PyAST_comprehension(a, b, c, 0, p->arena) } @@ -1131,7 +1128,8 @@ func_type_comment[Token*]: # From here on, there are rules for invalid syntax with specialised error messages invalid_arguments: - | a=args ',' '*' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable argument unpacking follows keyword argument unpacking") } + | ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' b='*' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(b, "iterable argument unpacking follows keyword argument unpacking") } | a=expression b=for_if_clauses ',' [args | expression for_if_clauses] { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } | a=NAME b='=' expression for_if_clauses { @@ -1170,7 +1168,7 @@ invalid_expression: _PyPegen_check_legacy_stmt(p, a) ? NULL : p->tokens[p->mark-1]->level == 0 ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") } | a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") } - | a='lambda' [lambda_params] b=':' &(FSTRING_MIDDLE | fstring_replacement_field) { + | a='lambda' [lambda_params] b=':' &FSTRING_MIDDLE { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") } invalid_named_expression(memo): @@ -1284,7 +1282,7 @@ invalid_with_item: RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) } invalid_for_target: - | ASYNC? 'for' a=star_expressions { + | 'async'? 'for' a=star_expressions { RAISE_SYNTAX_ERROR_INVALID_TARGET(FOR_TARGETS, a) } invalid_group: @@ -1301,12 +1299,12 @@ invalid_import_from_targets: RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") } invalid_with_stmt: - | [ASYNC] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } - | [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | ['async'] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | ['async'] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } invalid_with_stmt_indent: - | [ASYNC] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT { + | ['async'] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) } - | [ASYNC] a='with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT { + | ['async'] a='with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) } invalid_try_stmt: @@ -1367,11 +1365,11 @@ invalid_while_stmt: | a='while' named_expression ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'while' statement on line %d", a->lineno) } invalid_for_stmt: - | [ASYNC] 'for' star_targets 'in' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } - | [ASYNC] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT { + | ['async'] 'for' star_targets 'in' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | ['async'] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'for' statement on line %d", a->lineno) } invalid_def_raw: - | [ASYNC] a='def' NAME '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT { + | ['async'] a='def' NAME '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) } invalid_class_def_raw: | 'class' NAME ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } diff --git a/Include/Python.h b/Include/Python.h index 07f6c202a7f126..7312cc87d5cc33 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -5,42 +5,50 @@ #ifndef Py_PYTHON_H #define Py_PYTHON_H -// Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { +// Since this is a "meta-include" file, "#ifdef __cplusplus / extern "C" {" +// is not needed. + // Include Python header files #include "patchlevel.h" #include "pyconfig.h" #include "pymacconfig.h" -#if defined(__sgi) && !defined(_SGI_MP_SOURCE) -# define _SGI_MP_SOURCE + +// Include standard header files +#include // assert() +#include // uintptr_t +#include // INT_MAX +#include // HUGE_VAL +#include // va_list +#include // wchar_t +#ifdef HAVE_STDDEF_H +# include // size_t +#endif +#ifdef HAVE_SYS_TYPES_H +# include // ssize_t #endif -// stdlib.h, stdio.h, errno.h and string.h headers are not used by Python -// headers, but kept for backward compatibility. They are excluded from the -// limited C API of Python 3.11. +// errno.h, stdio.h, stdlib.h and string.h headers are no longer used by +// Python, but kept for backward compatibility (avoid compiler warnings). +// They are no longer included by limited C API version 3.11 and newer. #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# include -# include // FILE* # include // errno +# include // FILE* +# include // getenv() # include // memcpy() #endif -#ifndef MS_WINDOWS -# include -#endif -#ifdef HAVE_STDDEF_H -# include // size_t -#endif -#include // assert() -#include // wchar_t +// Include Python header files #include "pyport.h" #include "pymacro.h" #include "pymath.h" #include "pymem.h" #include "pytypedefs.h" #include "pybuffer.h" +#include "pystats.h" +#include "pyatomic.h" #include "object.h" #include "objimpl.h" #include "typeslots.h" diff --git a/Include/abstract.h b/Include/abstract.h index dd915004e7834e..bd12a54963c13f 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -50,6 +50,25 @@ extern "C" { This function always succeeds. */ + +/* Implemented elsewhere: + + int PyObject_HasAttrStringWithError(PyObject *o, const char *attr_name); + + Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise. + This is equivalent to the Python expression: hasattr(o,attr_name). + Returns -1 on failure. */ + + +/* Implemented elsewhere: + + int PyObject_HasAttrWithError(PyObject *o, PyObject *attr_name); + + Returns 1 if o has the attribute attr_name, and 0 otherwise. + This is equivalent to the Python expression: hasattr(o,attr_name). + Returns -1 on failure. */ + + /* Implemented elsewhere: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name); @@ -821,6 +840,18 @@ PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, const char *key); This function always succeeds. */ PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key); +/* Return 1 if the mapping object has the key 'key', and 0 otherwise. + This is equivalent to the Python expression: key in o. + On failure, return -1. */ + +PyAPI_FUNC(int) PyMapping_HasKeyWithError(PyObject *o, PyObject *key); + +/* Return 1 if the mapping object has the key 'key', and 0 otherwise. + This is equivalent to the Python expression: key in o. + On failure, return -1. */ + +PyAPI_FUNC(int) PyMapping_HasKeyStringWithError(PyObject *o, const char *key); + /* On success, return a list or tuple of the keys in mapping object 'o'. On failure, return NULL. */ PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o); diff --git a/Include/bytesobject.h b/Include/bytesobject.h index ee448cd02bdab3..c5a24195be6bc3 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -1,5 +1,4 @@ - -/* Bytes object interface */ +// Bytes object interface #ifndef Py_BYTESOBJECT_H #define Py_BYTESOBJECT_H @@ -7,8 +6,6 @@ extern "C" { #endif -#include // va_list - /* Type PyBytesObject represents a byte string. An extra zero byte is reserved at the end to ensure it is zero-terminated, but a size is diff --git a/Include/compile.h b/Include/compile.h index 3c5acd7209f763..52d0bc76c9fca4 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -10,9 +10,6 @@ extern "C" { #define Py_eval_input 258 #define Py_func_type_input 345 -/* This doesn't need to match anything */ -#define Py_fstring_input 800 - #ifndef Py_LIMITED_API # define Py_CPYTHON_COMPILE_H # include "cpython/compile.h" diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index dd924dfd3d8fcc..1f495f19df280b 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -53,13 +53,3 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); need to be corrected for a negative index. */ #define PySequence_ITEM(o, i)\ ( Py_TYPE(o)->tp_as_sequence->sq_item((o), (i)) ) - -/* === Mapping protocol ================================================= */ - -// Convert Python int to Py_ssize_t. Do nothing if the argument is None. -// Cannot be moved to the internal C API: used by Argument Clinic. -PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); - -// Same as PyNumber_Index but can return an instance of a subclass of int. -// Cannot be moved to the internal C API: used by Argument Clinic. -PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o); diff --git a/Include/cpython/bytesobject.h b/Include/cpython/bytesobject.h index 0af4c83b1e5bc7..816823716e9a6f 100644 --- a/Include/cpython/bytesobject.h +++ b/Include/cpython/bytesobject.h @@ -15,18 +15,6 @@ typedef struct { } PyBytesObject; PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); -PyAPI_FUNC(PyObject*) _PyBytes_FormatEx( - const char *format, - Py_ssize_t format_len, - PyObject *args, - int use_bytearray); -PyAPI_FUNC(PyObject*) _PyBytes_FromHex( - PyObject *string, - int use_bytearray); - -/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ -PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, - const char *, const char **); /* Macros and static inline functions, trading safety for speed */ #define _PyBytes_CAST(op) \ @@ -43,7 +31,3 @@ static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) { return Py_SIZE(self); } #define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self)) - -/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, - x must be an iterable object. */ -PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 5255d715142b97..78f7405661662f 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -4,14 +4,9 @@ PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_FUNC(void) PyEval_SetProfileAllThreads(Py_tracefunc, PyObject *); -PyAPI_FUNC(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); PyAPI_FUNC(void) PyEval_SetTraceAllThreads(Py_tracefunc, PyObject *); -PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); -/* Helper to look up a builtin object */ -PyAPI_FUNC(PyObject *) _PyEval_GetBuiltin(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *); /* Look at the current frame's (if any) code's co_flags, and turn on the corresponding compiler flags in cf->cf_flags. Return 1 if any flag was set, else return 0. */ @@ -19,11 +14,6 @@ PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc); -PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); -PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); - -PyAPI_FUNC(int) _PyEval_MakePendingCalls(PyThreadState *); - PyAPI_FUNC(Py_ssize_t) PyUnstable_Eval_RequestCodeExtraIndex(freefunc); // Old name -- remove when this API changes: _Py_DEPRECATED_EXTERNALLY(3.12) static inline Py_ssize_t diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 1b65b0d01d89f8..cf715c55a2b3b8 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -8,16 +8,21 @@ extern "C" { #endif - +/* Count of all local monitoring events */ +#define _PY_MONITORING_LOCAL_EVENTS 10 /* Count of all "real" monitoring events (not derived from other events) */ -#define PY_MONITORING_UNGROUPED_EVENTS 14 +#define _PY_MONITORING_UNGROUPED_EVENTS 15 /* Count of all monitoring events */ -#define PY_MONITORING_EVENTS 16 +#define _PY_MONITORING_EVENTS 17 + +/* Tables of which tools are active for each monitored event. */ +typedef struct _Py_LocalMonitors { + uint8_t tools[_PY_MONITORING_LOCAL_EVENTS]; +} _Py_LocalMonitors; -/* Table of which tools are active for each monitored event. */ -typedef struct _Py_Monitors { - uint8_t tools[PY_MONITORING_UNGROUPED_EVENTS]; -} _Py_Monitors; +typedef struct _Py_GlobalMonitors { + uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS]; +} _Py_GlobalMonitors; /* Each instruction in a code object is a fixed-width value, * currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG @@ -88,9 +93,9 @@ typedef struct { */ typedef struct { /* Monitoring specific to this code object */ - _Py_Monitors local_monitors; + _Py_LocalMonitors local_monitors; /* Monitoring that is active on this code object */ - _Py_Monitors active_monitors; + _Py_LocalMonitors active_monitors; /* The tools that are to be notified for events for the matching code unit */ uint8_t *tools; /* Information to support line events */ @@ -162,7 +167,7 @@ typedef struct { PyObject *co_weakreflist; /* to support weakrefs to code objects */ \ _PyExecutorArray *co_executors; /* executors from optimizer */ \ _PyCoCached *_co_cached; /* cached co_* attributes */ \ - uint64_t _co_instrumentation_version; /* current instrumentation version */ \ + uintptr_t _co_instrumentation_version; /* current instrumentation version */ \ _PyCoMonitoringData *_co_monitoring; /* Monitoring data */ \ int _co_firsttraceable; /* index of first traceable instruction */ \ /* Scratch space for extra data relating to the code object. \ diff --git a/Include/cpython/compile.h b/Include/cpython/compile.h index fd52697840203a..265f5397b45116 100644 --- a/Include/cpython/compile.h +++ b/Include/cpython/compile.h @@ -19,9 +19,10 @@ #define PyCF_TYPE_COMMENTS 0x1000 #define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 #define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000 +#define PyCF_OPTIMIZED_AST (0x8000 | PyCF_ONLY_AST) #define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \ - PyCF_ALLOW_INCOMPLETE_INPUT) + PyCF_ALLOW_INCOMPLETE_INPUT | PyCF_OPTIMIZED_AST) typedef struct { int cf_flags; /* bitmask of CO_xxx flags relevant to future */ @@ -77,3 +78,5 @@ PyAPI_FUNC(int) PyUnstable_OpcodeHasFree(int opcode); PyAPI_FUNC(int) PyUnstable_OpcodeHasLocal(int opcode); PyAPI_FUNC(int) PyUnstable_OpcodeHasExc(int opcode); +PyAPI_FUNC(PyObject*) PyUnstable_GetUnaryIntrinsicName(int index); +PyAPI_FUNC(PyObject*) PyUnstable_GetBinaryIntrinsicName(int index); diff --git a/Include/cpython/context.h b/Include/cpython/context.h index 9879fc7192ebb8..a3249fc29b082e 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -67,10 +67,6 @@ PyAPI_FUNC(PyObject *) PyContextVar_Set(PyObject *var, PyObject *value); PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token); -/* This method is exposed only for CPython tests. Don not use it. */ -PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void); - - #ifdef __cplusplus } #endif diff --git a/Include/cpython/descrobject.h b/Include/cpython/descrobject.h index e2ea1b9a2d3058..bbad8b59c225ab 100644 --- a/Include/cpython/descrobject.h +++ b/Include/cpython/descrobject.h @@ -57,8 +57,6 @@ typedef struct { void *d_wrapped; /* This can be any function pointer */ } PyWrapperDescrObject; -PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type; - PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); PyAPI_FUNC(int) PyDescr_IsData(PyObject *); diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index ddada922020aa4..b05ca3ef453816 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -32,22 +32,8 @@ typedef struct { PyDictValues *ma_values; } PyDictObject; -PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, - Py_hash_t hash); -PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *dp, PyObject *key); -PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, - _Py_Identifier *key); -PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *); PyAPI_FUNC(PyObject *) PyDict_SetDefault( PyObject *mp, PyObject *key, PyObject *defaultobj); -PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, - PyObject *item, Py_hash_t hash); -PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, - Py_hash_t hash); -PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, - int (*predicate)(PyObject *value)); -PyAPI_FUNC(int) _PyDict_Next( - PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); /* Get the number of items of a dictionary. */ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { @@ -58,35 +44,8 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { } #define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op)) -PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); -PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *); -PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); -PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); -PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); -PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); -PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *); -#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) +PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key); -/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0, - the first occurrence of a key wins, if override is 1, the last occurrence - of a key wins, if override is 2, a KeyError with conflicting key as - argument is raised. -*/ -PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); -PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, _Py_Identifier *key, PyObject *item); - -PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, _Py_Identifier *key); -PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); - -/* _PyDictView */ - -typedef struct { - PyObject_HEAD - PyDictObject *dv_dict; -} _PyDictViewObject; - -PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); -PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); /* Dictionary watchers */ diff --git a/Include/cpython/fileobject.h b/Include/cpython/fileobject.h index b70ec318986d82..e2d89c522bdd13 100644 --- a/Include/cpython/fileobject.h +++ b/Include/cpython/fileobject.h @@ -3,7 +3,6 @@ #endif PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); -PyAPI_FUNC(char *) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject *, size_t*); /* The std printer acts as a preliminary sys.stderr until the new io infrastructure is in place. */ @@ -15,5 +14,3 @@ typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *); PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); - -PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *); diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index a3dc6661786451..4e19535c656f2c 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -4,8 +4,6 @@ # error "this header file must not be included directly" #endif -struct _PyInterpreterFrame; - /* Standard object interface */ PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, @@ -29,18 +27,3 @@ PyAPI_FUNC(int) _PyFrame_IsEntryFrame(PyFrameObject *frame); PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); - -/* The following functions are for use by debuggers and other tools - * implementing custom frame evaluators with PEP 523. */ - -/* Returns the code object of the frame (strong reference). - * Does not raise an exception. */ -PyAPI_FUNC(PyObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame); - -/* Returns a byte ofsset into the last executed instruction. - * Does not raise an exception. */ -PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame); - -/* Returns the currently executing line number, or -1 if there is no line number. - * Does not raise an exception. */ -PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame); diff --git a/Include/cpython/funcobject.h b/Include/cpython/funcobject.h index 6f78f5868d0166..de2013323d2c72 100644 --- a/Include/cpython/funcobject.h +++ b/Include/cpython/funcobject.h @@ -79,12 +79,6 @@ PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *); PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( - PyObject *func, - PyObject *const *stack, - size_t nargsf, - PyObject *kwnames); - #define _PyFunction_CAST(func) \ (assert(PyFunction_Check(func)), _Py_CAST(PyFunctionObject*, func)) diff --git a/Include/cpython/genobject.h b/Include/cpython/genobject.h index 7856481b5db300..49e46c277d75ae 100644 --- a/Include/cpython/genobject.h +++ b/Include/cpython/genobject.h @@ -41,9 +41,6 @@ PyAPI_DATA(PyTypeObject) PyGen_Type; PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *); PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, PyObject *name, PyObject *qualname); -PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); -PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); -PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); PyAPI_FUNC(PyCodeObject *) PyGen_GetCode(PyGenObject *gen); @@ -54,7 +51,6 @@ typedef struct { } PyCoroObject; PyAPI_DATA(PyTypeObject) PyCoro_Type; -PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; #define PyCoro_CheckExact(op) Py_IS_TYPE((op), &PyCoro_Type) PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *, @@ -69,8 +65,6 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyAsyncGen_Type; PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type; -PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type; -PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *, PyObject *name, PyObject *qualname); diff --git a/Include/cpython/import.h b/Include/cpython/import.h index cdfdd15bfa48d2..7daf0b84fcf71b 100644 --- a/Include/cpython/import.h +++ b/Include/cpython/import.h @@ -17,7 +17,6 @@ struct _frozen { const unsigned char *code; int size; int is_package; - PyObject *(*get_code)(void); }; /* Embedding apps may change this pointer to point to their favorite diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index c103c2026e40e9..808c1056498b49 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -25,7 +25,6 @@ PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode); PyAPI_FUNC(int) PyStatus_IsError(PyStatus err); PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err); PyAPI_FUNC(int) PyStatus_Exception(PyStatus err); -PyAPI_FUNC(PyObject *) _PyErr_SetFromPyStatus(PyStatus status); /* --- PyWideStringList ------------------------------------------------ */ @@ -181,6 +180,8 @@ typedef struct PyConfig { int safe_path; int int_max_str_digits; + int cpu_count; + /* --- Path configuration inputs ------------ */ int pathconfig_warnings; wchar_t *program_name; @@ -205,6 +206,9 @@ typedef struct PyConfig { wchar_t *run_module; wchar_t *run_filename; + /* --- Set by Py_Main() -------------------------- */ + wchar_t *sys_path_0; + /* --- Private fields ---------------------------- */ // Install importlib? If equals to 0, importlib is not initialized at all. @@ -216,6 +220,11 @@ typedef struct PyConfig { // If non-zero, we believe we're running from a source tree. int _is_python_build; + +#ifdef Py_STATS + // If non-zero, turns on statistics gathering. + int _pystats; +#endif } PyConfig; PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); @@ -242,45 +251,6 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, Py_ssize_t length, wchar_t **items); -/* --- PyInterpreterConfig ------------------------------------ */ - -#define PyInterpreterConfig_DEFAULT_GIL (0) -#define PyInterpreterConfig_SHARED_GIL (1) -#define PyInterpreterConfig_OWN_GIL (2) - -typedef struct { - // XXX "allow_object_sharing"? "own_objects"? - int use_main_obmalloc; - int allow_fork; - int allow_exec; - int allow_threads; - int allow_daemon_threads; - int check_multi_interp_extensions; - int gil; -} PyInterpreterConfig; - -#define _PyInterpreterConfig_INIT \ - { \ - .use_main_obmalloc = 0, \ - .allow_fork = 0, \ - .allow_exec = 0, \ - .allow_threads = 1, \ - .allow_daemon_threads = 0, \ - .check_multi_interp_extensions = 1, \ - .gil = PyInterpreterConfig_OWN_GIL, \ - } - -#define _PyInterpreterConfig_LEGACY_INIT \ - { \ - .use_main_obmalloc = 1, \ - .allow_fork = 1, \ - .allow_exec = 1, \ - .allow_threads = 1, \ - .allow_daemon_threads = 1, \ - .check_multi_interp_extensions = 0, \ - .gil = PyInterpreterConfig_SHARED_GIL, \ - } - /* --- Helper functions --------------------------------------- */ /* Get the original command line arguments, before Python modified them. diff --git a/Include/cpython/interpreteridobject.h b/Include/cpython/interpreteridobject.h index 5076584209b90b..4ab9ad5d315f80 100644 --- a/Include/cpython/interpreteridobject.h +++ b/Include/cpython/interpreteridobject.h @@ -4,8 +4,8 @@ /* Interpreter ID Object */ -PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; +PyAPI_DATA(PyTypeObject) PyInterpreterID_Type; -PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t); -PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *); -PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *); +PyAPI_FUNC(PyObject *) PyInterpreterID_New(int64_t); +PyAPI_FUNC(PyObject *) PyInterpreterState_GetIDObject(PyInterpreterState *); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterID_LookUp(PyObject *); diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h index b3b23985de7a66..661610548733fd 100644 --- a/Include/cpython/listobject.h +++ b/Include/cpython/listobject.h @@ -21,9 +21,6 @@ typedef struct { Py_ssize_t allocated; } PyListObject; -PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); -PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); - /* Cast argument to PyListObject* type. */ #define _PyList_CAST(op) \ (assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op))) diff --git a/Include/cpython/longintrepr.h b/Include/cpython/longintrepr.h index 692c69ba76db2f..fb82f83dc50e42 100644 --- a/Include/cpython/longintrepr.h +++ b/Include/cpython/longintrepr.h @@ -89,14 +89,6 @@ struct _longobject { _PyLongValue long_value; }; -PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); - -/* Return a copy of src. */ -PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); - -PyAPI_FUNC(PyLongObject *) -_PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits); - /* Inline some internals for speed. These should be in pycore_long.h * if user code didn't need them inlined. */ diff --git a/Include/cpython/longobject.h b/Include/cpython/longobject.h index 90cc0f267ae833..57834173490c99 100644 --- a/Include/cpython/longobject.h +++ b/Include/cpython/longobject.h @@ -2,98 +2,7 @@ # error "this header file must not be included directly" #endif -PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); - -PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *); - -/* _PyLong_Frexp returns a double x and an exponent e such that the - true value is approximately equal to x * 2**e. e is >= 0. x is - 0.0 if and only if the input is 0 (in which case, e and x are both - zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is - possible if the number of bits doesn't fit into a Py_ssize_t, sets - OverflowError and returns -1.0 for x, 0 for e. */ -PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); - -PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base); -PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int); - -/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. - v must not be NULL, and must be a normalized long. - There are no error cases. -*/ -PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); - -/* _PyLong_NumBits. Return the number of bits needed to represent the - absolute value of a long. For example, this returns 1 for 1 and -1, 2 - for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. - v must not be NULL, and must be a normalized long. - (size_t)-1 is returned and OverflowError set if the true result doesn't - fit in a size_t. -*/ -PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); - -/* _PyLong_DivmodNear. Given integers a and b, compute the nearest - integer q to the exact quotient a / b, rounding to the nearest even integer - in the case of a tie. Return (q, r), where r = a - q*b. The remainder r - will satisfy abs(r) <= abs(b)/2, with equality possible only if q is - even. -*/ -PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); - -/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in - base 256, and return a Python int with the same numeric value. - If n is 0, the integer is 0. Else: - If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; - else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the - LSB. - If is_signed is 0/false, view the bytes as a non-negative integer. - If is_signed is 1/true, view the bytes as a 2's-complement integer, - non-negative if bit 0x80 of the MSB is clear, negative if set. - Error returns: - + Return NULL with the appropriate exception set if there's not - enough memory to create the Python int. -*/ -PyAPI_FUNC(PyObject *) _PyLong_FromByteArray( - const unsigned char* bytes, size_t n, - int little_endian, int is_signed); - -/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long - v to a base-256 integer, stored in array bytes. Normally return 0, - return -1 on error. - If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at - bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and - the LSB at bytes[n-1]. - If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes - are filled and there's nothing special about bit 0x80 of the MSB. - If is_signed is 1/true, bytes is filled with the 2's-complement - representation of v's value. Bit 0x80 of the MSB is the sign bit. - Error returns (-1): - + is_signed is 0 and v < 0. TypeError is set in this case, and bytes - isn't altered. - + n isn't big enough to hold the full mathematical value of v. For - example, if is_signed is 0 and there are more digits in the v than - fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of - being large enough to hold a sign bit. OverflowError is set in this - case, but bytes holds the least-significant n bytes of the true value. -*/ -PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, - unsigned char* bytes, size_t n, - int little_endian, int is_signed); - -/* _PyLong_Format: Convert the long to a string object with given base, - appending a base prefix of 0[box] if base is 2, 8 or 16. */ -PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base); - -/* For use by the gcd function in mathmodule.c */ -PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); - -PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t); -PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t); - +PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base); PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op); PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op); diff --git a/Include/cpython/memoryobject.h b/Include/cpython/memoryobject.h index 3837fa8c6ab5aa..961161b70f2058 100644 --- a/Include/cpython/memoryobject.h +++ b/Include/cpython/memoryobject.h @@ -2,8 +2,6 @@ # error "this header file must not be included directly" #endif -PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; - /* The structs are declared here so that macros can work, but they shouldn't be considered public. Don't access their fields directly, use the macros and functions instead! */ diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h index 376336b13dcf8a..cfc2c2cdb5a7f4 100644 --- a/Include/cpython/modsupport.h +++ b/Include/cpython/modsupport.h @@ -52,8 +52,6 @@ PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( PyObject *kwnames, struct _PyArg_Parser *, ...); -PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list); PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, PyObject *kwnames, diff --git a/Include/cpython/object.h b/Include/cpython/object.h index cd421b4f7e0d49..ede394d9673d7e 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -5,11 +5,6 @@ PyAPI_FUNC(void) _Py_NewReference(PyObject *op); PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op); -#ifdef Py_TRACE_REFS -/* Py_TRACE_REFS is such major surgery that we call external routines. */ -PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); -#endif - #ifdef Py_REF_DEBUG /* These are useful as debugging aids when chasing down refleaks. */ PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void); @@ -19,43 +14,6 @@ PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *); #endif -/********************* String Literals ****************************************/ -/* This structure helps managing static strings. The basic usage goes like this: - Instead of doing - - r = PyObject_CallMethod(o, "foo", "args", ...); - - do - - _Py_IDENTIFIER(foo); - ... - r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); - - PyId_foo is a static variable, either on block level or file level. On first - usage, the string "foo" is interned, and the structures are linked. On interpreter - shutdown, all strings are released. - - Alternatively, _Py_static_string allows choosing the variable name. - _PyUnicode_FromId returns a borrowed reference to the interned string. - _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. -*/ -typedef struct _Py_Identifier { - const char* string; - // Index in PyInterpreterState.unicode.ids.array. It is process-wide - // unique and must be initialized to -1. - Py_ssize_t index; -} _Py_Identifier; - -#ifndef Py_BUILD_CORE -// For now we are keeping _Py_IDENTIFIER for continued use -// in non-builtin extensions (and naughty PyPI modules). - -#define _Py_static_string_init(value) { .string = (value), .index = -1 } -#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) -#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) - -#endif /* !Py_BUILD_CORE */ - typedef struct { /* Number implementations must check *both* arguments for proper type and implement the necessary conversions @@ -227,7 +185,7 @@ struct _typeobject { vectorcallfunc tp_vectorcall; /* bitset of which type-watchers care about this type */ - char tp_watched; + unsigned char tp_watched; }; /* This struct is used by the specializer @@ -273,32 +231,14 @@ typedef struct _heaptypeobject { PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); -PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *); -#ifndef Py_BUILD_CORE -// Backward compatibility for 3rd-party extensions -// that may be using the old name. -#define _PyObject_LookupSpecial _PyObject_LookupSpecialId -#endif -PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); -PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *); PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *); PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _PyObject_Dump(PyObject *); -PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); - -PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); -PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, _Py_Identifier *); -PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *); - -PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); -PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); @@ -377,20 +317,6 @@ PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); #endif -PyAPI_DATA(PyTypeObject) _PyNone_Type; -PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type; - -/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. - * Defined in object.c. - */ -PyAPI_DATA(int) _Py_SwappedOp[]; - -PyAPI_FUNC(void) -_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, - size_t sizeof_block); -PyAPI_FUNC(void) -_PyObject_DebugTypeStats(FILE *out); - /* Define a pair of assertion macros: _PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT(). @@ -439,21 +365,6 @@ PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed( int line, const char *function); -/* Check if an object is consistent. For example, ensure that the reference - counter is greater than or equal to 1, and ensure that ob_type is not NULL. - - Call _PyObject_AssertFailed() if the object is inconsistent. - - If check_content is zero, only check header fields: reduce the overhead. - - The function always return 1. The return value is just here to be able to - write: - - assert(_PyObject_CheckConsistency(obj, 1)); */ -PyAPI_FUNC(int) _PyObject_CheckConsistency( - PyObject *op, - int check_content); - /* Trashcan mechanism, thanks to Christian Tismer. @@ -514,7 +425,7 @@ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); /* If "cond" is false, then _tstate remains NULL and the deallocator \ * is run normally without involving the trashcan */ \ if (cond) { \ - _tstate = _PyThreadState_UncheckedGet(); \ + _tstate = PyThreadState_GetUnchecked(); \ if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \ break; \ } \ @@ -533,8 +444,8 @@ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj); -PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg); -PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *obj); +PyAPI_FUNC(int) PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg); +PyAPI_FUNC(void) PyObject_ClearManagedDict(PyObject *obj); #define TYPE_MAX_WATCHERS 8 diff --git a/Include/cpython/optimizer.h b/Include/cpython/optimizer.h index 2260501bfd608e..47536108a9665e 100644 --- a/Include/cpython/optimizer.h +++ b/Include/cpython/optimizer.h @@ -12,7 +12,7 @@ typedef struct { } _PyVMData; typedef struct _PyExecutorObject { - PyObject_HEAD + PyObject_VAR_HEAD /* WARNING: execute consumes a reference to self. This is necessary to allow executors to tail call into each other. */ struct _PyInterpreterFrame *(*execute)(struct _PyExecutorObject *self, struct _PyInterpreterFrame *frame, PyObject **stack_pointer); _PyVMData vm_data; /* Used by the VM, but opaque to the optimizer */ @@ -22,7 +22,7 @@ typedef struct _PyExecutorObject { typedef struct _PyOptimizerObject _PyOptimizerObject; /* Should return > 0 if a new executor is created. O if no executor is produced and < 0 if an error occurred. */ -typedef int (*optimize_func)(_PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutorObject **); +typedef int (*optimize_func)(_PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutorObject **, int curr_stackentries); typedef struct _PyOptimizerObject { PyObject_HEAD @@ -38,9 +38,9 @@ PyAPI_FUNC(void) PyUnstable_SetOptimizer(_PyOptimizerObject* optimizer); PyAPI_FUNC(_PyOptimizerObject *) PyUnstable_GetOptimizer(void); -PyAPI_FUNC(_PyExecutorObject *)PyUnstable_GetExecutor(PyCodeObject *code, int offset); +PyAPI_FUNC(_PyExecutorObject *) PyUnstable_GetExecutor(PyCodeObject *code, int offset); -struct _PyInterpreterFrame * +int _PyOptimizer_BackEdge(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest, PyObject **stack_pointer); extern _PyOptimizerObject _PyOptimizer_Default; diff --git a/Include/cpython/pthread_stubs.h b/Include/cpython/pthread_stubs.h index d95ee03d8308ce..5246968ea05476 100644 --- a/Include/cpython/pthread_stubs.h +++ b/Include/cpython/pthread_stubs.h @@ -21,13 +21,29 @@ #ifdef __wasi__ // WASI's bits/alltypes.h provides type definitions when __NEED_ is set. // The header file can be included multiple times. -# define __NEED_pthread_cond_t 1 -# define __NEED_pthread_condattr_t 1 -# define __NEED_pthread_mutex_t 1 -# define __NEED_pthread_mutexattr_t 1 -# define __NEED_pthread_key_t 1 -# define __NEED_pthread_t 1 -# define __NEED_pthread_attr_t 1 +// +// may also define these macros. +# ifndef __NEED_pthread_cond_t +# define __NEED_pthread_cond_t 1 +# endif +# ifndef __NEED_pthread_condattr_t +# define __NEED_pthread_condattr_t 1 +# endif +# ifndef __NEED_pthread_mutex_t +# define __NEED_pthread_mutex_t 1 +# endif +# ifndef __NEED_pthread_mutexattr_t +# define __NEED_pthread_mutexattr_t 1 +# endif +# ifndef __NEED_pthread_key_t +# define __NEED_pthread_key_t 1 +# endif +# ifndef __NEED_pthread_t +# define __NEED_pthread_t 1 +# endif +# ifndef __NEED_pthread_attr_t +# define __NEED_pthread_attr_t 1 +# endif # include #else typedef struct { void *__x; } pthread_cond_t; diff --git a/Include/cpython/pyatomic.h b/Include/cpython/pyatomic.h new file mode 100644 index 00000000000000..7a783058c173aa --- /dev/null +++ b/Include/cpython/pyatomic.h @@ -0,0 +1,528 @@ +// This header provides cross-platform low-level atomic operations +// similar to C11 atomics. +// +// Operations are sequentially consistent unless they have a suffix indicating +// otherwise. If in doubt, prefer the sequentially consistent operations. +// +// The "_relaxed" suffix for load and store operations indicates the "relaxed" +// memory order. They don't provide synchronization, but (roughly speaking) +// guarantee somewhat sane behavior for races instead of undefined behavior. +// In practice, they correspond to "normal" hardware load and store +// instructions, so they are almost as inexpensive as plain loads and stores +// in C. +// +// Note that atomic read-modify-write operations like _Py_atomic_add_* return +// the previous value of the atomic variable, not the new value. +// +// See https://en.cppreference.com/w/c/atomic for more information on C11 +// atomics. +// See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2055r0.pdf +// "A Relaxed Guide to memory_order_relaxed" for discussion of and common usage +// or relaxed atomics. +// +// Functions with pseudo Python code: +// +// def _Py_atomic_load(obj): +// return obj # sequential consistency +// +// def _Py_atomic_load_relaxed(obj): +// return obj # relaxed consistency +// +// def _Py_atomic_store(obj, value): +// obj = value # sequential consistency +// +// def _Py_atomic_store_relaxed(obj, value): +// obj = value # relaxed consistency +// +// def _Py_atomic_exchange(obj, value): +// # sequential consistency +// old_obj = obj +// obj = value +// return old_obj +// +// def _Py_atomic_compare_exchange(obj, expected, desired): +// # sequential consistency +// if obj == expected: +// obj = desired +// return True +// else: +// expected = obj +// return False +// +// def _Py_atomic_add(obj, value): +// # sequential consistency +// old_obj = obj +// obj += value +// return old_obj +// +// def _Py_atomic_and(obj, value): +// # sequential consistency +// old_obj = obj +// obj &= value +// return old_obj +// +// def _Py_atomic_or(obj, value): +// # sequential consistency +// old_obj = obj +// obj |= value +// return old_obj +// +// Other functions: +// +// def _Py_atomic_load_ptr_acquire(obj): +// return obj # acquire +// +// def _Py_atomic_store_ptr_release(obj): +// return obj # release +// +// def _Py_atomic_fence_seq_cst(): +// # sequential consistency +// ... +// +// def _Py_atomic_fence_release(): +// # release +// ... + +#ifndef Py_CPYTHON_ATOMIC_H +# error "this header file must not be included directly" +#endif + +// --- _Py_atomic_add -------------------------------------------------------- +// Atomically adds `value` to `obj` and returns the previous value + +static inline int +_Py_atomic_add_int(int *obj, int value); + +static inline int8_t +_Py_atomic_add_int8(int8_t *obj, int8_t value); + +static inline int16_t +_Py_atomic_add_int16(int16_t *obj, int16_t value); + +static inline int32_t +_Py_atomic_add_int32(int32_t *obj, int32_t value); + +static inline int64_t +_Py_atomic_add_int64(int64_t *obj, int64_t value); + +static inline intptr_t +_Py_atomic_add_intptr(intptr_t *obj, intptr_t value); + +static inline unsigned int +_Py_atomic_add_uint(unsigned int *obj, unsigned int value); + +static inline uint8_t +_Py_atomic_add_uint8(uint8_t *obj, uint8_t value); + +static inline uint16_t +_Py_atomic_add_uint16(uint16_t *obj, uint16_t value); + +static inline uint32_t +_Py_atomic_add_uint32(uint32_t *obj, uint32_t value); + +static inline uint64_t +_Py_atomic_add_uint64(uint64_t *obj, uint64_t value); + +static inline uintptr_t +_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value); + +static inline Py_ssize_t +_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value); + + +// --- _Py_atomic_compare_exchange ------------------------------------------- +// Performs an atomic compare-and-exchange. +// +// - If `*obj` and `*expected` are equal, store `desired` into `*obj` +// and return 1 (success). +// - Otherwise, store the `*obj` current value into `*expected` +// and return 0 (failure). +// +// These correspond to the C11 atomic_compare_exchange_strong() function. + +static inline int +_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired); + +static inline int +_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired); + +static inline int +_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired); + +static inline int +_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired); + +static inline int +_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired); + +static inline int +_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired); + +static inline int +_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired); + +static inline int +_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired); + +static inline int +_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired); + +static inline int +_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired); + +static inline int +_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired); + +static inline int +_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired); + +static inline int +_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired); + +// NOTE: `obj` and `expected` are logically `void**` types, but we use `void*` +// so that we can pass types like `PyObject**` without a cast. +static inline int +_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *value); + + +// --- _Py_atomic_exchange --------------------------------------------------- +// Atomically replaces `*obj` with `value` and returns the previous value of `*obj`. + +static inline int +_Py_atomic_exchange_int(int *obj, int value); + +static inline int8_t +_Py_atomic_exchange_int8(int8_t *obj, int8_t value); + +static inline int16_t +_Py_atomic_exchange_int16(int16_t *obj, int16_t value); + +static inline int32_t +_Py_atomic_exchange_int32(int32_t *obj, int32_t value); + +static inline int64_t +_Py_atomic_exchange_int64(int64_t *obj, int64_t value); + +static inline intptr_t +_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value); + +static inline unsigned int +_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value); + +static inline uint8_t +_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value); + +static inline uint16_t +_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value); + +static inline uint32_t +_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value); + +static inline uint64_t +_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value); + +static inline uintptr_t +_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value); + +static inline Py_ssize_t +_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value); + +static inline void * +_Py_atomic_exchange_ptr(void *obj, void *value); + + +// --- _Py_atomic_and -------------------------------------------------------- +// Performs `*obj &= value` atomically and returns the previous value of `*obj`. + +static inline uint8_t +_Py_atomic_and_uint8(uint8_t *obj, uint8_t value); + +static inline uint16_t +_Py_atomic_and_uint16(uint16_t *obj, uint16_t value); + +static inline uint32_t +_Py_atomic_and_uint32(uint32_t *obj, uint32_t value); + +static inline uint64_t +_Py_atomic_and_uint64(uint64_t *obj, uint64_t value); + +static inline uintptr_t +_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value); + + +// --- _Py_atomic_or --------------------------------------------------------- +// Performs `*obj |= value` atomically and returns the previous value of `*obj`. + +static inline uint8_t +_Py_atomic_or_uint8(uint8_t *obj, uint8_t value); + +static inline uint16_t +_Py_atomic_or_uint16(uint16_t *obj, uint16_t value); + +static inline uint32_t +_Py_atomic_or_uint32(uint32_t *obj, uint32_t value); + +static inline uint64_t +_Py_atomic_or_uint64(uint64_t *obj, uint64_t value); + +static inline uintptr_t +_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value); + + +// --- _Py_atomic_load ------------------------------------------------------- +// Atomically loads `*obj` (sequential consistency) + +static inline int +_Py_atomic_load_int(const int *obj); + +static inline int8_t +_Py_atomic_load_int8(const int8_t *obj); + +static inline int16_t +_Py_atomic_load_int16(const int16_t *obj); + +static inline int32_t +_Py_atomic_load_int32(const int32_t *obj); + +static inline int64_t +_Py_atomic_load_int64(const int64_t *obj); + +static inline intptr_t +_Py_atomic_load_intptr(const intptr_t *obj); + +static inline uint8_t +_Py_atomic_load_uint8(const uint8_t *obj); + +static inline uint16_t +_Py_atomic_load_uint16(const uint16_t *obj); + +static inline uint32_t +_Py_atomic_load_uint32(const uint32_t *obj); + +static inline uint64_t +_Py_atomic_load_uint64(const uint64_t *obj); + +static inline uintptr_t +_Py_atomic_load_uintptr(const uintptr_t *obj); + +static inline unsigned int +_Py_atomic_load_uint(const unsigned int *obj); + +static inline Py_ssize_t +_Py_atomic_load_ssize(const Py_ssize_t *obj); + +static inline void * +_Py_atomic_load_ptr(const void *obj); + + +// --- _Py_atomic_load_relaxed ----------------------------------------------- +// Loads `*obj` (relaxed consistency, i.e., no ordering) + +static inline int +_Py_atomic_load_int_relaxed(const int *obj); + +static inline int8_t +_Py_atomic_load_int8_relaxed(const int8_t *obj); + +static inline int16_t +_Py_atomic_load_int16_relaxed(const int16_t *obj); + +static inline int32_t +_Py_atomic_load_int32_relaxed(const int32_t *obj); + +static inline int64_t +_Py_atomic_load_int64_relaxed(const int64_t *obj); + +static inline intptr_t +_Py_atomic_load_intptr_relaxed(const intptr_t *obj); + +static inline uint8_t +_Py_atomic_load_uint8_relaxed(const uint8_t *obj); + +static inline uint16_t +_Py_atomic_load_uint16_relaxed(const uint16_t *obj); + +static inline uint32_t +_Py_atomic_load_uint32_relaxed(const uint32_t *obj); + +static inline uint64_t +_Py_atomic_load_uint64_relaxed(const uint64_t *obj); + +static inline uintptr_t +_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj); + +static inline unsigned int +_Py_atomic_load_uint_relaxed(const unsigned int *obj); + +static inline Py_ssize_t +_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj); + +static inline void * +_Py_atomic_load_ptr_relaxed(const void *obj); + + +// --- _Py_atomic_store ------------------------------------------------------ +// Atomically performs `*obj = value` (sequential consistency) + +static inline void +_Py_atomic_store_int(int *obj, int value); + +static inline void +_Py_atomic_store_int8(int8_t *obj, int8_t value); + +static inline void +_Py_atomic_store_int16(int16_t *obj, int16_t value); + +static inline void +_Py_atomic_store_int32(int32_t *obj, int32_t value); + +static inline void +_Py_atomic_store_int64(int64_t *obj, int64_t value); + +static inline void +_Py_atomic_store_intptr(intptr_t *obj, intptr_t value); + +static inline void +_Py_atomic_store_uint8(uint8_t *obj, uint8_t value); + +static inline void +_Py_atomic_store_uint16(uint16_t *obj, uint16_t value); + +static inline void +_Py_atomic_store_uint32(uint32_t *obj, uint32_t value); + +static inline void +_Py_atomic_store_uint64(uint64_t *obj, uint64_t value); + +static inline void +_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value); + +static inline void +_Py_atomic_store_uint(unsigned int *obj, unsigned int value); + +static inline void +_Py_atomic_store_ptr(void *obj, void *value); + +static inline void +_Py_atomic_store_ssize(Py_ssize_t* obj, Py_ssize_t value); + + +// --- _Py_atomic_store_relaxed ---------------------------------------------- +// Stores `*obj = value` (relaxed consistency, i.e., no ordering) + +static inline void +_Py_atomic_store_int_relaxed(int *obj, int value); + +static inline void +_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value); + +static inline void +_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value); + +static inline void +_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value); + +static inline void +_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value); + +static inline void +_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value); + +static inline void +_Py_atomic_store_uint8_relaxed(uint8_t* obj, uint8_t value); + +static inline void +_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value); + +static inline void +_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value); + +static inline void +_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value); + +static inline void +_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value); + +static inline void +_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value); + +static inline void +_Py_atomic_store_ptr_relaxed(void *obj, void *value); + +static inline void +_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value); + + +// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------ + +// Loads `*obj` (acquire operation) +static inline void * +_Py_atomic_load_ptr_acquire(const void *obj); + +// Stores `*obj = value` (release operation) +static inline void +_Py_atomic_store_ptr_release(void *obj, void *value); + + +// --- _Py_atomic_fence ------------------------------------------------------ + +// Sequential consistency fence. C11 fences have complex semantics. When +// possible, use the atomic operations on variables defined above, which +// generally do not require explicit use of a fence. +// See https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence +static inline void _Py_atomic_fence_seq_cst(void); + +// Release fence +static inline void _Py_atomic_fence_release(void); + + +#ifndef _Py_USE_GCC_BUILTIN_ATOMICS +# if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +# define _Py_USE_GCC_BUILTIN_ATOMICS 1 +# elif defined(__clang__) +# if __has_builtin(__atomic_load) +# define _Py_USE_GCC_BUILTIN_ATOMICS 1 +# endif +# endif +#endif + +#if _Py_USE_GCC_BUILTIN_ATOMICS +# define Py_ATOMIC_GCC_H +# include "cpython/pyatomic_gcc.h" +# undef Py_ATOMIC_GCC_H +#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__) +# define Py_ATOMIC_STD_H +# include "cpython/pyatomic_std.h" +# undef Py_ATOMIC_STD_H +#elif defined(_MSC_VER) +# define Py_ATOMIC_MSC_H +# include "cpython/pyatomic_msc.h" +# undef Py_ATOMIC_MSC_H +#else +# error "no available pyatomic implementation for this platform/compiler" +#endif + + +// --- aliases --------------------------------------------------------------- + +#if SIZEOF_LONG == 8 +# define _Py_atomic_load_ulong(p) \ + _Py_atomic_load_uint64((uint64_t *)p) +# define _Py_atomic_load_ulong_relaxed(p) \ + _Py_atomic_load_uint64_relaxed((uint64_t *)p) +# define _Py_atomic_store_ulong(p, v) \ + _Py_atomic_store_uint64((uint64_t *)p, v) +# define _Py_atomic_store_ulong_relaxed(p, v) \ + _Py_atomic_store_uint64_relaxed((uint64_t *)p, v) +#elif SIZEOF_LONG == 4 +# define _Py_atomic_load_ulong(p) \ + _Py_atomic_load_uint32((uint32_t *)p) +# define _Py_atomic_load_ulong_relaxed(p) \ + _Py_atomic_load_uint32_relaxed((uint32_t *)p) +# define _Py_atomic_store_ulong(p, v) \ + _Py_atomic_store_uint32((uint32_t *)p, v) +# define _Py_atomic_store_ulong_relaxed(p, v) \ + _Py_atomic_store_uint32_relaxed((uint32_t *)p, v) +#else +# error "long must be 4 or 8 bytes in size" +#endif // SIZEOF_LONG diff --git a/Include/cpython/pyatomic_gcc.h b/Include/cpython/pyatomic_gcc.h new file mode 100644 index 00000000000000..f1a38c7b52871a --- /dev/null +++ b/Include/cpython/pyatomic_gcc.h @@ -0,0 +1,499 @@ +// This is the implementation of Python atomic operations using GCC's built-in +// functions that match the C+11 memory model. This implementation is preferred +// for GCC compatible compilers, such as Clang. These functions are available +// in GCC 4.8+ without needing to compile with --std=c11 or --std=gnu11. + +#ifndef Py_ATOMIC_GCC_H +# error "this header file must not be included directly" +#endif + + +// --- _Py_atomic_add -------------------------------------------------------- + +static inline int +_Py_atomic_add_int(int *obj, int value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline int8_t +_Py_atomic_add_int8(int8_t *obj, int8_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline int16_t +_Py_atomic_add_int16(int16_t *obj, int16_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline int32_t +_Py_atomic_add_int32(int32_t *obj, int32_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline int64_t +_Py_atomic_add_int64(int64_t *obj, int64_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline intptr_t +_Py_atomic_add_intptr(intptr_t *obj, intptr_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline unsigned int +_Py_atomic_add_uint(unsigned int *obj, unsigned int value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint8_t +_Py_atomic_add_uint8(uint8_t *obj, uint8_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint16_t +_Py_atomic_add_uint16(uint16_t *obj, uint16_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint32_t +_Py_atomic_add_uint32(uint32_t *obj, uint32_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint64_t +_Py_atomic_add_uint64(uint64_t *obj, uint64_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline uintptr_t +_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + +static inline Py_ssize_t +_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); } + + +// --- _Py_atomic_compare_exchange ------------------------------------------- + +static inline int +_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired) +{ return __atomic_compare_exchange_n(obj, expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + +static inline int +_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *desired) +{ return __atomic_compare_exchange_n((void **)obj, (void **)expected, desired, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } + + +// --- _Py_atomic_exchange --------------------------------------------------- + +static inline int +_Py_atomic_exchange_int(int *obj, int value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline int8_t +_Py_atomic_exchange_int8(int8_t *obj, int8_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline int16_t +_Py_atomic_exchange_int16(int16_t *obj, int16_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline int32_t +_Py_atomic_exchange_int32(int32_t *obj, int32_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline int64_t +_Py_atomic_exchange_int64(int64_t *obj, int64_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline intptr_t +_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline unsigned int +_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint8_t +_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint16_t +_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint32_t +_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint64_t +_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline uintptr_t +_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline Py_ssize_t +_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void * +_Py_atomic_exchange_ptr(void *obj, void *value) +{ return __atomic_exchange_n((void **)obj, value, __ATOMIC_SEQ_CST); } + + +// --- _Py_atomic_and -------------------------------------------------------- + +static inline uint8_t +_Py_atomic_and_uint8(uint8_t *obj, uint8_t value) +{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint16_t +_Py_atomic_and_uint16(uint16_t *obj, uint16_t value) +{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint32_t +_Py_atomic_and_uint32(uint32_t *obj, uint32_t value) +{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint64_t +_Py_atomic_and_uint64(uint64_t *obj, uint64_t value) +{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); } + +static inline uintptr_t +_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value) +{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); } + + +// --- _Py_atomic_or --------------------------------------------------------- + +static inline uint8_t +_Py_atomic_or_uint8(uint8_t *obj, uint8_t value) +{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint16_t +_Py_atomic_or_uint16(uint16_t *obj, uint16_t value) +{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint32_t +_Py_atomic_or_uint32(uint32_t *obj, uint32_t value) +{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); } + +static inline uint64_t +_Py_atomic_or_uint64(uint64_t *obj, uint64_t value) +{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); } + +static inline uintptr_t +_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value) +{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); } + + +// --- _Py_atomic_load ------------------------------------------------------- + +static inline int +_Py_atomic_load_int(const int *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline int8_t +_Py_atomic_load_int8(const int8_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline int16_t +_Py_atomic_load_int16(const int16_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline int32_t +_Py_atomic_load_int32(const int32_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline int64_t +_Py_atomic_load_int64(const int64_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline intptr_t +_Py_atomic_load_intptr(const intptr_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline uint8_t +_Py_atomic_load_uint8(const uint8_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline uint16_t +_Py_atomic_load_uint16(const uint16_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline uint32_t +_Py_atomic_load_uint32(const uint32_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline uint64_t +_Py_atomic_load_uint64(const uint64_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline uintptr_t +_Py_atomic_load_uintptr(const uintptr_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline unsigned int +_Py_atomic_load_uint(const unsigned int *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline Py_ssize_t +_Py_atomic_load_ssize(const Py_ssize_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); } + +static inline void * +_Py_atomic_load_ptr(const void *obj) +{ return (void *)__atomic_load_n((void **)obj, __ATOMIC_SEQ_CST); } + + +// --- _Py_atomic_load_relaxed ----------------------------------------------- + +static inline int +_Py_atomic_load_int_relaxed(const int *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline int8_t +_Py_atomic_load_int8_relaxed(const int8_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline int16_t +_Py_atomic_load_int16_relaxed(const int16_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline int32_t +_Py_atomic_load_int32_relaxed(const int32_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline int64_t +_Py_atomic_load_int64_relaxed(const int64_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline intptr_t +_Py_atomic_load_intptr_relaxed(const intptr_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline uint8_t +_Py_atomic_load_uint8_relaxed(const uint8_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline uint16_t +_Py_atomic_load_uint16_relaxed(const uint16_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline uint32_t +_Py_atomic_load_uint32_relaxed(const uint32_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline uint64_t +_Py_atomic_load_uint64_relaxed(const uint64_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline uintptr_t +_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline unsigned int +_Py_atomic_load_uint_relaxed(const unsigned int *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline Py_ssize_t +_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_RELAXED); } + +static inline void * +_Py_atomic_load_ptr_relaxed(const void *obj) +{ return (void *)__atomic_load_n((const void **)obj, __ATOMIC_RELAXED); } + + +// --- _Py_atomic_store ------------------------------------------------------ + +static inline void +_Py_atomic_store_int(int *obj, int value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_int8(int8_t *obj, int8_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_int16(int16_t *obj, int16_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_int32(int32_t *obj, int32_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_int64(int64_t *obj, int64_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_intptr(intptr_t *obj, intptr_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_uint8(uint8_t *obj, uint8_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_uint16(uint16_t *obj, uint16_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_uint32(uint32_t *obj, uint32_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_uint64(uint64_t *obj, uint64_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_uint(unsigned int *obj, unsigned int value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_ptr(void *obj, void *value) +{ __atomic_store_n((void **)obj, value, __ATOMIC_SEQ_CST); } + +static inline void +_Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); } + + +// --- _Py_atomic_store_relaxed ---------------------------------------------- + +static inline void +_Py_atomic_store_int_relaxed(int *obj, int value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_ptr_relaxed(void *obj, void *value) +{ __atomic_store_n((void **)obj, value, __ATOMIC_RELAXED); } + +static inline void +_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); } + + +// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------ + +static inline void * +_Py_atomic_load_ptr_acquire(const void *obj) +{ return (void *)__atomic_load_n((void **)obj, __ATOMIC_ACQUIRE); } + +static inline void +_Py_atomic_store_ptr_release(void *obj, void *value) +{ __atomic_store_n((void **)obj, value, __ATOMIC_RELEASE); } + + +// --- _Py_atomic_fence ------------------------------------------------------ + +static inline void +_Py_atomic_fence_seq_cst(void) +{ __atomic_thread_fence(__ATOMIC_SEQ_CST); } + + static inline void +_Py_atomic_fence_release(void) +{ __atomic_thread_fence(__ATOMIC_RELEASE); } diff --git a/Include/cpython/pyatomic_msc.h b/Include/cpython/pyatomic_msc.h new file mode 100644 index 00000000000000..287ed43b5714cd --- /dev/null +++ b/Include/cpython/pyatomic_msc.h @@ -0,0 +1,944 @@ +// This is the implementation of Python atomic operations for MSVC if the +// compiler does not support C11 or C++11 atomics. +// +// MSVC intrinsics are defined on char, short, long, __int64, and pointer +// types. Note that long and int are both 32-bits even on 64-bit Windows, +// so operations on int are cast to long. +// +// The volatile keyword has additional memory ordering semantics on MSVC. On +// x86 and x86-64, volatile accesses have acquire-release semantics. On ARM64, +// volatile accesses behave like C11's memory_order_relaxed. + +#ifndef Py_ATOMIC_MSC_H +# error "this header file must not be included directly" +#endif + +#include + +#define _Py_atomic_ASSERT_ARG_TYPE(TYPE) \ + Py_BUILD_ASSERT(sizeof(*obj) == sizeof(TYPE)) + + +// --- _Py_atomic_add -------------------------------------------------------- + +static inline int8_t +_Py_atomic_add_int8(int8_t *obj, int8_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(char); + return (int8_t)_InterlockedExchangeAdd8((volatile char *)obj, (char)value); +} + +static inline int16_t +_Py_atomic_add_int16(int16_t *obj, int16_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(short); + return (int16_t)_InterlockedExchangeAdd16((volatile short *)obj, (short)value); +} + +static inline int32_t +_Py_atomic_add_int32(int32_t *obj, int32_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(long); + return (int32_t)_InterlockedExchangeAdd((volatile long *)obj, (long)value); +} + +static inline int64_t +_Py_atomic_add_int64(int64_t *obj, int64_t value) +{ +#if defined(_M_X64) || defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(__int64); + return (int64_t)_InterlockedExchangeAdd64((volatile __int64 *)obj, (__int64)value); +#else + int64_t old_value = _Py_atomic_load_int64_relaxed(obj); + for (;;) { + int64_t new_value = old_value + value; + if (_Py_atomic_compare_exchange_int64(obj, &old_value, new_value)) { + return old_value; + } + } +#endif +} + + +static inline uint8_t +_Py_atomic_add_uint8(uint8_t *obj, uint8_t value) +{ + return (uint8_t)_Py_atomic_add_int8((int8_t *)obj, (int8_t)value); +} + +static inline uint16_t +_Py_atomic_add_uint16(uint16_t *obj, uint16_t value) +{ + return (uint16_t)_Py_atomic_add_int16((int16_t *)obj, (int16_t)value); +} + +static inline uint32_t +_Py_atomic_add_uint32(uint32_t *obj, uint32_t value) +{ + return (uint32_t)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value); +} + +static inline int +_Py_atomic_add_int(int *obj, int value) +{ + _Py_atomic_ASSERT_ARG_TYPE(int32_t); + return (int)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value); +} + +static inline unsigned int +_Py_atomic_add_uint(unsigned int *obj, unsigned int value) +{ + _Py_atomic_ASSERT_ARG_TYPE(int32_t); + return (unsigned int)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value); +} + +static inline uint64_t +_Py_atomic_add_uint64(uint64_t *obj, uint64_t value) +{ + return (uint64_t)_Py_atomic_add_int64((int64_t *)obj, (int64_t)value); +} + +static inline intptr_t +_Py_atomic_add_intptr(intptr_t *obj, intptr_t value) +{ +#if SIZEOF_VOID_P == 8 + _Py_atomic_ASSERT_ARG_TYPE(int64_t); + return (intptr_t)_Py_atomic_add_int64((int64_t *)obj, (int64_t)value); +#else + _Py_atomic_ASSERT_ARG_TYPE(int32_t); + return (intptr_t)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value); +#endif +} + +static inline uintptr_t +_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(intptr_t); + return (uintptr_t)_Py_atomic_add_intptr((intptr_t *)obj, (intptr_t)value); +} + +static inline Py_ssize_t +_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(intptr_t); + return (Py_ssize_t)_Py_atomic_add_intptr((intptr_t *)obj, (intptr_t)value); +} + + +// --- _Py_atomic_compare_exchange ------------------------------------------- + +static inline int +_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(char); + int8_t initial = (int8_t)_InterlockedCompareExchange8( + (volatile char *)obj, + (char)value, + (char)*expected); + if (initial == *expected) { + return 1; + } + *expected = initial; + return 0; +} + +static inline int +_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(short); + int16_t initial = (int16_t)_InterlockedCompareExchange16( + (volatile short *)obj, + (short)value, + (short)*expected); + if (initial == *expected) { + return 1; + } + *expected = initial; + return 0; +} + +static inline int +_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(long); + int32_t initial = (int32_t)_InterlockedCompareExchange( + (volatile long *)obj, + (long)value, + (long)*expected); + if (initial == *expected) { + return 1; + } + *expected = initial; + return 0; +} + +static inline int +_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(__int64); + int64_t initial = (int64_t)_InterlockedCompareExchange64( + (volatile __int64 *)obj, + (__int64)value, + (__int64)*expected); + if (initial == *expected) { + return 1; + } + *expected = initial; + return 0; +} + +static inline int +_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *value) +{ + void *initial = _InterlockedCompareExchangePointer( + (void**)obj, + value, + *(void**)expected); + if (initial == *(void**)expected) { + return 1; + } + *(void**)expected = initial; + return 0; +} + + +static inline int +_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t value) +{ + return _Py_atomic_compare_exchange_int8((int8_t *)obj, + (int8_t *)expected, + (int8_t)value); +} + +static inline int +_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t value) +{ + return _Py_atomic_compare_exchange_int16((int16_t *)obj, + (int16_t *)expected, + (int16_t)value); +} + +static inline int +_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t value) +{ + return _Py_atomic_compare_exchange_int32((int32_t *)obj, + (int32_t *)expected, + (int32_t)value); +} + +static inline int +_Py_atomic_compare_exchange_int(int *obj, int *expected, int value) +{ + _Py_atomic_ASSERT_ARG_TYPE(int32_t); + return _Py_atomic_compare_exchange_int32((int32_t *)obj, + (int32_t *)expected, + (int32_t)value); +} + +static inline int +_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int value) +{ + _Py_atomic_ASSERT_ARG_TYPE(int32_t); + return _Py_atomic_compare_exchange_int32((int32_t *)obj, + (int32_t *)expected, + (int32_t)value); +} + +static inline int +_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t value) +{ + return _Py_atomic_compare_exchange_int64((int64_t *)obj, + (int64_t *)expected, + (int64_t)value); +} + +static inline int +_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return _Py_atomic_compare_exchange_ptr((void**)obj, + (void**)expected, + (void*)value); +} + +static inline int +_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return _Py_atomic_compare_exchange_ptr((void**)obj, + (void**)expected, + (void*)value); +} + +static inline int +_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return _Py_atomic_compare_exchange_ptr((void**)obj, + (void**)expected, + (void*)value); +} + + +// --- _Py_atomic_exchange --------------------------------------------------- + +static inline int8_t +_Py_atomic_exchange_int8(int8_t *obj, int8_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(char); + return (int8_t)_InterlockedExchange8((volatile char *)obj, (char)value); +} + +static inline int16_t +_Py_atomic_exchange_int16(int16_t *obj, int16_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(short); + return (int16_t)_InterlockedExchange16((volatile short *)obj, (short)value); +} + +static inline int32_t +_Py_atomic_exchange_int32(int32_t *obj, int32_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(long); + return (int32_t)_InterlockedExchange((volatile long *)obj, (long)value); +} + +static inline int64_t +_Py_atomic_exchange_int64(int64_t *obj, int64_t value) +{ +#if defined(_M_X64) || defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(__int64); + return (int64_t)_InterlockedExchange64((volatile __int64 *)obj, (__int64)value); +#else + int64_t old_value = _Py_atomic_load_int64_relaxed(obj); + for (;;) { + if (_Py_atomic_compare_exchange_int64(obj, &old_value, value)) { + return old_value; + } + } +#endif +} + +static inline void* +_Py_atomic_exchange_ptr(void *obj, void *value) +{ + return (void*)_InterlockedExchangePointer((void * volatile *)obj, (void *)value); +} + + +static inline uint8_t +_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value) +{ + return (uint8_t)_Py_atomic_exchange_int8((int8_t *)obj, + (int8_t)value); +} + +static inline uint16_t +_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value) +{ + return (uint16_t)_Py_atomic_exchange_int16((int16_t *)obj, + (int16_t)value); +} + +static inline uint32_t +_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value) +{ + return (uint32_t)_Py_atomic_exchange_int32((int32_t *)obj, + (int32_t)value); +} + +static inline int +_Py_atomic_exchange_int(int *obj, int value) +{ + _Py_atomic_ASSERT_ARG_TYPE(int32_t); + return (int)_Py_atomic_exchange_int32((int32_t *)obj, + (int32_t)value); +} + +static inline unsigned int +_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value) +{ + _Py_atomic_ASSERT_ARG_TYPE(int32_t); + return (unsigned int)_Py_atomic_exchange_int32((int32_t *)obj, + (int32_t)value); +} + +static inline uint64_t +_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value) +{ + return (uint64_t)_Py_atomic_exchange_int64((int64_t *)obj, + (int64_t)value); +} + +static inline intptr_t +_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return (intptr_t)_Py_atomic_exchange_ptr((void**)obj, + (void*)value); +} + +static inline uintptr_t +_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return (uintptr_t)_Py_atomic_exchange_ptr((void**)obj, + (void*)value); +} + +static inline Py_ssize_t +_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return (Py_ssize_t)_Py_atomic_exchange_ptr((void**)obj, + (void*)value); +} + + +// --- _Py_atomic_and -------------------------------------------------------- + +static inline uint8_t +_Py_atomic_and_uint8(uint8_t *obj, uint8_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(char); + return (uint8_t)_InterlockedAnd8((volatile char *)obj, (char)value); +} + +static inline uint16_t +_Py_atomic_and_uint16(uint16_t *obj, uint16_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(short); + return (uint16_t)_InterlockedAnd16((volatile short *)obj, (short)value); +} + +static inline uint32_t +_Py_atomic_and_uint32(uint32_t *obj, uint32_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(long); + return (uint32_t)_InterlockedAnd((volatile long *)obj, (long)value); +} + +static inline uint64_t +_Py_atomic_and_uint64(uint64_t *obj, uint64_t value) +{ +#if defined(_M_X64) || defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(__int64); + return (uint64_t)_InterlockedAnd64((volatile __int64 *)obj, (__int64)value); +#else + uint64_t old_value = _Py_atomic_load_uint64_relaxed(obj); + for (;;) { + uint64_t new_value = old_value & value; + if (_Py_atomic_compare_exchange_uint64(obj, &old_value, new_value)) { + return old_value; + } + } +#endif +} + +static inline uintptr_t +_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value) +{ +#if SIZEOF_VOID_P == 8 + _Py_atomic_ASSERT_ARG_TYPE(uint64_t); + return (uintptr_t)_Py_atomic_and_uint64((uint64_t *)obj, + (uint64_t)value); +#else + _Py_atomic_ASSERT_ARG_TYPE(uint32_t); + return (uintptr_t)_Py_atomic_and_uint32((uint32_t *)obj, + (uint32_t)value); +#endif +} + + +// --- _Py_atomic_or --------------------------------------------------------- + +static inline uint8_t +_Py_atomic_or_uint8(uint8_t *obj, uint8_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(char); + return (uint8_t)_InterlockedOr8((volatile char *)obj, (char)value); +} + +static inline uint16_t +_Py_atomic_or_uint16(uint16_t *obj, uint16_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(short); + return (uint16_t)_InterlockedOr16((volatile short *)obj, (short)value); +} + +static inline uint32_t +_Py_atomic_or_uint32(uint32_t *obj, uint32_t value) +{ + _Py_atomic_ASSERT_ARG_TYPE(long); + return (uint32_t)_InterlockedOr((volatile long *)obj, (long)value); +} + +static inline uint64_t +_Py_atomic_or_uint64(uint64_t *obj, uint64_t value) +{ +#if defined(_M_X64) || defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(__int64); + return (uint64_t)_InterlockedOr64((volatile __int64 *)obj, (__int64)value); +#else + uint64_t old_value = _Py_atomic_load_uint64_relaxed(obj); + for (;;) { + uint64_t new_value = old_value | value; + if (_Py_atomic_compare_exchange_uint64(obj, &old_value, new_value)) { + return old_value; + } + } +#endif +} + + +static inline uintptr_t +_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value) +{ +#if SIZEOF_VOID_P == 8 + _Py_atomic_ASSERT_ARG_TYPE(uint64_t); + return (uintptr_t)_Py_atomic_or_uint64((uint64_t *)obj, + (uint64_t)value); +#else + _Py_atomic_ASSERT_ARG_TYPE(uint32_t); + return (uintptr_t)_Py_atomic_or_uint32((uint32_t *)obj, + (uint32_t)value); +#endif +} + + +// --- _Py_atomic_load ------------------------------------------------------- + +static inline uint8_t +_Py_atomic_load_uint8(const uint8_t *obj) +{ +#if defined(_M_X64) || defined(_M_IX86) + return *(volatile uint8_t *)obj; +#elif defined(_M_ARM64) + return (uint8_t)__ldar8((unsigned __int8 volatile *)obj); +#else +# error "no implementation of _Py_atomic_load_uint8" +#endif +} + +static inline uint16_t +_Py_atomic_load_uint16(const uint16_t *obj) +{ +#if defined(_M_X64) || defined(_M_IX86) + return *(volatile uint16_t *)obj; +#elif defined(_M_ARM64) + return (uint16_t)__ldar16((unsigned __int16 volatile *)obj); +#else +# error "no implementation of _Py_atomic_load_uint16" +#endif +} + +static inline uint32_t +_Py_atomic_load_uint32(const uint32_t *obj) +{ +#if defined(_M_X64) || defined(_M_IX86) + return *(volatile uint32_t *)obj; +#elif defined(_M_ARM64) + return (uint32_t)__ldar32((unsigned __int32 volatile *)obj); +#else +# error "no implementation of _Py_atomic_load_uint32" +#endif +} + +static inline uint64_t +_Py_atomic_load_uint64(const uint64_t *obj) +{ +#if defined(_M_X64) || defined(_M_IX86) + return *(volatile uint64_t *)obj; +#elif defined(_M_ARM64) + return (uint64_t)__ldar64((unsigned __int64 volatile *)obj); +#else +# error "no implementation of _Py_atomic_load_uint64" +#endif +} + +static inline int8_t +_Py_atomic_load_int8(const int8_t *obj) +{ + return (int8_t)_Py_atomic_load_uint8((const uint8_t *)obj); +} + +static inline int16_t +_Py_atomic_load_int16(const int16_t *obj) +{ + return (int16_t)_Py_atomic_load_uint16((const uint16_t *)obj); +} + +static inline int32_t +_Py_atomic_load_int32(const int32_t *obj) +{ + return (int32_t)_Py_atomic_load_uint32((const uint32_t *)obj); +} + +static inline int +_Py_atomic_load_int(const int *obj) +{ + _Py_atomic_ASSERT_ARG_TYPE(uint32_t); + return (int)_Py_atomic_load_uint32((uint32_t *)obj); +} + +static inline unsigned int +_Py_atomic_load_uint(const unsigned int *obj) +{ + _Py_atomic_ASSERT_ARG_TYPE(uint32_t); + return (unsigned int)_Py_atomic_load_uint32((uint32_t *)obj); +} + +static inline int64_t +_Py_atomic_load_int64(const int64_t *obj) +{ + return (int64_t)_Py_atomic_load_uint64((const uint64_t *)obj); +} + +static inline void* +_Py_atomic_load_ptr(const void *obj) +{ +#if SIZEOF_VOID_P == 8 + return (void*)_Py_atomic_load_uint64((const uint64_t *)obj); +#else + return (void*)_Py_atomic_load_uint32((const uint32_t *)obj); +#endif +} + +static inline intptr_t +_Py_atomic_load_intptr(const intptr_t *obj) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return (intptr_t)_Py_atomic_load_ptr((void*)obj); +} + +static inline uintptr_t +_Py_atomic_load_uintptr(const uintptr_t *obj) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return (uintptr_t)_Py_atomic_load_ptr((void*)obj); +} + +static inline Py_ssize_t +_Py_atomic_load_ssize(const Py_ssize_t *obj) +{ + _Py_atomic_ASSERT_ARG_TYPE(void*); + return (Py_ssize_t)_Py_atomic_load_ptr((void*)obj); +} + + +// --- _Py_atomic_load_relaxed ----------------------------------------------- + +static inline int +_Py_atomic_load_int_relaxed(const int *obj) +{ + return *(volatile int *)obj; +} + +static inline int8_t +_Py_atomic_load_int8_relaxed(const int8_t *obj) +{ + return *(volatile int8_t *)obj; +} + +static inline int16_t +_Py_atomic_load_int16_relaxed(const int16_t *obj) +{ + return *(volatile int16_t *)obj; +} + +static inline int32_t +_Py_atomic_load_int32_relaxed(const int32_t *obj) +{ + return *(volatile int32_t *)obj; +} + +static inline int64_t +_Py_atomic_load_int64_relaxed(const int64_t *obj) +{ + return *(volatile int64_t *)obj; +} + +static inline intptr_t +_Py_atomic_load_intptr_relaxed(const intptr_t *obj) +{ + return *(volatile intptr_t *)obj; +} + +static inline uint8_t +_Py_atomic_load_uint8_relaxed(const uint8_t *obj) +{ + return *(volatile uint8_t *)obj; +} + +static inline uint16_t +_Py_atomic_load_uint16_relaxed(const uint16_t *obj) +{ + return *(volatile uint16_t *)obj; +} + +static inline uint32_t +_Py_atomic_load_uint32_relaxed(const uint32_t *obj) +{ + return *(volatile uint32_t *)obj; +} + +static inline uint64_t +_Py_atomic_load_uint64_relaxed(const uint64_t *obj) +{ + return *(volatile uint64_t *)obj; +} + +static inline uintptr_t +_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj) +{ + return *(volatile uintptr_t *)obj; +} + +static inline unsigned int +_Py_atomic_load_uint_relaxed(const unsigned int *obj) +{ + return *(volatile unsigned int *)obj; +} + +static inline Py_ssize_t +_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj) +{ + return *(volatile Py_ssize_t *)obj; +} + +static inline void* +_Py_atomic_load_ptr_relaxed(const void *obj) +{ + return *(void * volatile *)obj; +} + + +// --- _Py_atomic_store ------------------------------------------------------ + +static inline void +_Py_atomic_store_int(int *obj, int value) +{ + (void)_Py_atomic_exchange_int(obj, value); +} + +static inline void +_Py_atomic_store_int8(int8_t *obj, int8_t value) +{ + (void)_Py_atomic_exchange_int8(obj, value); +} + +static inline void +_Py_atomic_store_int16(int16_t *obj, int16_t value) +{ + (void)_Py_atomic_exchange_int16(obj, value); +} + +static inline void +_Py_atomic_store_int32(int32_t *obj, int32_t value) +{ + (void)_Py_atomic_exchange_int32(obj, value); +} + +static inline void +_Py_atomic_store_int64(int64_t *obj, int64_t value) +{ + (void)_Py_atomic_exchange_int64(obj, value); +} + +static inline void +_Py_atomic_store_intptr(intptr_t *obj, intptr_t value) +{ + (void)_Py_atomic_exchange_intptr(obj, value); +} + +static inline void +_Py_atomic_store_uint8(uint8_t *obj, uint8_t value) +{ + (void)_Py_atomic_exchange_uint8(obj, value); +} + +static inline void +_Py_atomic_store_uint16(uint16_t *obj, uint16_t value) +{ + (void)_Py_atomic_exchange_uint16(obj, value); +} + +static inline void +_Py_atomic_store_uint32(uint32_t *obj, uint32_t value) +{ + (void)_Py_atomic_exchange_uint32(obj, value); +} + +static inline void +_Py_atomic_store_uint64(uint64_t *obj, uint64_t value) +{ + (void)_Py_atomic_exchange_uint64(obj, value); +} + +static inline void +_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value) +{ + (void)_Py_atomic_exchange_uintptr(obj, value); +} + +static inline void +_Py_atomic_store_uint(unsigned int *obj, unsigned int value) +{ + (void)_Py_atomic_exchange_uint(obj, value); +} + +static inline void +_Py_atomic_store_ptr(void *obj, void *value) +{ + (void)_Py_atomic_exchange_ptr(obj, value); +} + +static inline void +_Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ + (void)_Py_atomic_exchange_ssize(obj, value); +} + + +// --- _Py_atomic_store_relaxed ---------------------------------------------- + +static inline void +_Py_atomic_store_int_relaxed(int *obj, int value) +{ + *(volatile int *)obj = value; +} + +static inline void +_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value) +{ + *(volatile int8_t *)obj = value; +} + +static inline void +_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value) +{ + *(volatile int16_t *)obj = value; +} + +static inline void +_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value) +{ + *(volatile int32_t *)obj = value; +} + +static inline void +_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value) +{ + *(volatile int64_t *)obj = value; +} + +static inline void +_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value) +{ + *(volatile intptr_t *)obj = value; +} + +static inline void +_Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value) +{ + *(volatile uint8_t *)obj = value; +} + +static inline void +_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value) +{ + *(volatile uint16_t *)obj = value; +} + +static inline void +_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value) +{ + *(volatile uint32_t *)obj = value; +} + +static inline void +_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value) +{ + *(volatile uint64_t *)obj = value; +} + +static inline void +_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value) +{ + *(volatile uintptr_t *)obj = value; +} + +static inline void +_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value) +{ + *(volatile unsigned int *)obj = value; +} + +static inline void +_Py_atomic_store_ptr_relaxed(void *obj, void* value) +{ + *(void * volatile *)obj = value; +} + +static inline void +_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value) +{ + *(volatile Py_ssize_t *)obj = value; +} + +// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------ + +static inline void * +_Py_atomic_load_ptr_acquire(const void *obj) +{ +#if defined(_M_X64) || defined(_M_IX86) + return *(void * volatile *)obj; +#elif defined(_M_ARM64) + return (void *)__ldar64((unsigned __int64 volatile *)obj); +#else +# error "no implementation of _Py_atomic_load_ptr_acquire" +#endif +} + +static inline void +_Py_atomic_store_ptr_release(void *obj, void *value) +{ +#if defined(_M_X64) || defined(_M_IX86) + *(void * volatile *)obj = value; +#elif defined(_M_ARM64) + __stlr64((unsigned __int64 volatile *)obj, (uintptr_t)value); +#else +# error "no implementation of _Py_atomic_store_ptr_release" +#endif +} + + +// --- _Py_atomic_fence ------------------------------------------------------ + + static inline void +_Py_atomic_fence_seq_cst(void) +{ +#if defined(_M_ARM64) + __dmb(_ARM64_BARRIER_ISH); +#elif defined(_M_X64) + __faststorefence(); +#elif defined(_M_IX86) + _mm_mfence(); +#else +# error "no implementation of _Py_atomic_fence_seq_cst" +#endif +} + + static inline void +_Py_atomic_fence_release(void) +{ +#if defined(_M_ARM64) + __dmb(_ARM64_BARRIER_ISH); +#elif defined(_M_X64) || defined(_M_IX86) + _ReadWriteBarrier(); +#else +# error "no implementation of _Py_atomic_fence_release" +#endif +} + +#undef _Py_atomic_ASSERT_ARG_TYPE diff --git a/Include/cpython/pyatomic_std.h b/Include/cpython/pyatomic_std.h new file mode 100644 index 00000000000000..bf74a90887c634 --- /dev/null +++ b/Include/cpython/pyatomic_std.h @@ -0,0 +1,872 @@ +// This is the implementation of Python atomic operations using C++11 or C11 +// atomics. Note that the pyatomic_gcc.h implementation is preferred for GCC +// compatible compilers, even if they support C++11 atomics. + +#ifndef Py_ATOMIC_STD_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C++" { +# include +} +# define _Py_USING_STD using namespace std +# define _Atomic(tp) atomic +#else +# define _Py_USING_STD +# include +#endif + + +// --- _Py_atomic_add -------------------------------------------------------- + +static inline int +_Py_atomic_add_int(int *obj, int value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(int)*)obj, value); +} + +static inline int8_t +_Py_atomic_add_int8(int8_t *obj, int8_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(int8_t)*)obj, value); +} + +static inline int16_t +_Py_atomic_add_int16(int16_t *obj, int16_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(int16_t)*)obj, value); +} + +static inline int32_t +_Py_atomic_add_int32(int32_t *obj, int32_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(int32_t)*)obj, value); +} + +static inline int64_t +_Py_atomic_add_int64(int64_t *obj, int64_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(int64_t)*)obj, value); +} + +static inline intptr_t +_Py_atomic_add_intptr(intptr_t *obj, intptr_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(intptr_t)*)obj, value); +} + +static inline unsigned int +_Py_atomic_add_uint(unsigned int *obj, unsigned int value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(unsigned int)*)obj, value); +} + +static inline uint8_t +_Py_atomic_add_uint8(uint8_t *obj, uint8_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(uint8_t)*)obj, value); +} + +static inline uint16_t +_Py_atomic_add_uint16(uint16_t *obj, uint16_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(uint16_t)*)obj, value); +} + +static inline uint32_t +_Py_atomic_add_uint32(uint32_t *obj, uint32_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(uint32_t)*)obj, value); +} + +static inline uint64_t +_Py_atomic_add_uint64(uint64_t *obj, uint64_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(uint64_t)*)obj, value); +} + +static inline uintptr_t +_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(uintptr_t)*)obj, value); +} + +static inline Py_ssize_t +_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ + _Py_USING_STD; + return atomic_fetch_add((_Atomic(Py_ssize_t)*)obj, value); +} + + +// --- _Py_atomic_compare_exchange ------------------------------------------- + +static inline int +_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(int)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(int8_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(int16_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(int32_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(int64_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(intptr_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(unsigned int)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(uint8_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(uint16_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(uint32_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(uint64_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(uintptr_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(Py_ssize_t)*)obj, + expected, desired); +} + +static inline int +_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *desired) +{ + _Py_USING_STD; + return atomic_compare_exchange_strong((_Atomic(void *)*)obj, + (void **)expected, desired); +} + + +// --- _Py_atomic_exchange --------------------------------------------------- + +static inline int +_Py_atomic_exchange_int(int *obj, int value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(int)*)obj, value); +} + +static inline int8_t +_Py_atomic_exchange_int8(int8_t *obj, int8_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(int8_t)*)obj, value); +} + +static inline int16_t +_Py_atomic_exchange_int16(int16_t *obj, int16_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(int16_t)*)obj, value); +} + +static inline int32_t +_Py_atomic_exchange_int32(int32_t *obj, int32_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(int32_t)*)obj, value); +} + +static inline int64_t +_Py_atomic_exchange_int64(int64_t *obj, int64_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(int64_t)*)obj, value); +} + +static inline intptr_t +_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(intptr_t)*)obj, value); +} + +static inline unsigned int +_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(unsigned int)*)obj, value); +} + +static inline uint8_t +_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(uint8_t)*)obj, value); +} + +static inline uint16_t +_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(uint16_t)*)obj, value); +} + +static inline uint32_t +_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(uint32_t)*)obj, value); +} + +static inline uint64_t +_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(uint64_t)*)obj, value); +} + +static inline uintptr_t +_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(uintptr_t)*)obj, value); +} + +static inline Py_ssize_t +_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(Py_ssize_t)*)obj, value); +} + +static inline void* +_Py_atomic_exchange_ptr(void *obj, void *value) +{ + _Py_USING_STD; + return atomic_exchange((_Atomic(void *)*)obj, value); +} + + +// --- _Py_atomic_and -------------------------------------------------------- + +static inline uint8_t +_Py_atomic_and_uint8(uint8_t *obj, uint8_t value) +{ + _Py_USING_STD; + return atomic_fetch_and((_Atomic(uint8_t)*)obj, value); +} + +static inline uint16_t +_Py_atomic_and_uint16(uint16_t *obj, uint16_t value) +{ + _Py_USING_STD; + return atomic_fetch_and((_Atomic(uint16_t)*)obj, value); +} + +static inline uint32_t +_Py_atomic_and_uint32(uint32_t *obj, uint32_t value) +{ + _Py_USING_STD; + return atomic_fetch_and((_Atomic(uint32_t)*)obj, value); +} + +static inline uint64_t +_Py_atomic_and_uint64(uint64_t *obj, uint64_t value) +{ + _Py_USING_STD; + return atomic_fetch_and((_Atomic(uint64_t)*)obj, value); +} + +static inline uintptr_t +_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value) +{ + _Py_USING_STD; + return atomic_fetch_and((_Atomic(uintptr_t)*)obj, value); +} + + +// --- _Py_atomic_or --------------------------------------------------------- + +static inline uint8_t +_Py_atomic_or_uint8(uint8_t *obj, uint8_t value) +{ + _Py_USING_STD; + return atomic_fetch_or((_Atomic(uint8_t)*)obj, value); +} + +static inline uint16_t +_Py_atomic_or_uint16(uint16_t *obj, uint16_t value) +{ + _Py_USING_STD; + return atomic_fetch_or((_Atomic(uint16_t)*)obj, value); +} + +static inline uint32_t +_Py_atomic_or_uint32(uint32_t *obj, uint32_t value) +{ + _Py_USING_STD; + return atomic_fetch_or((_Atomic(uint32_t)*)obj, value); +} + +static inline uint64_t +_Py_atomic_or_uint64(uint64_t *obj, uint64_t value) +{ + _Py_USING_STD; + return atomic_fetch_or((_Atomic(uint64_t)*)obj, value); +} + +static inline uintptr_t +_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value) +{ + _Py_USING_STD; + return atomic_fetch_or((_Atomic(uintptr_t)*)obj, value); +} + + +// --- _Py_atomic_load ------------------------------------------------------- + +static inline int +_Py_atomic_load_int(const int *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(int)*)obj); +} + +static inline int8_t +_Py_atomic_load_int8(const int8_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(int8_t)*)obj); +} + +static inline int16_t +_Py_atomic_load_int16(const int16_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(int16_t)*)obj); +} + +static inline int32_t +_Py_atomic_load_int32(const int32_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(int32_t)*)obj); +} + +static inline int64_t +_Py_atomic_load_int64(const int64_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(int64_t)*)obj); +} + +static inline intptr_t +_Py_atomic_load_intptr(const intptr_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(intptr_t)*)obj); +} + +static inline uint8_t +_Py_atomic_load_uint8(const uint8_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(uint8_t)*)obj); +} + +static inline uint16_t +_Py_atomic_load_uint16(const uint16_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(uint32_t)*)obj); +} + +static inline uint32_t +_Py_atomic_load_uint32(const uint32_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(uint32_t)*)obj); +} + +static inline uint64_t +_Py_atomic_load_uint64(const uint64_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(uint64_t)*)obj); +} + +static inline uintptr_t +_Py_atomic_load_uintptr(const uintptr_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(uintptr_t)*)obj); +} + +static inline unsigned int +_Py_atomic_load_uint(const unsigned int *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(unsigned int)*)obj); +} + +static inline Py_ssize_t +_Py_atomic_load_ssize(const Py_ssize_t *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(Py_ssize_t)*)obj); +} + +static inline void* +_Py_atomic_load_ptr(const void *obj) +{ + _Py_USING_STD; + return atomic_load((const _Atomic(void*)*)obj); +} + + +// --- _Py_atomic_load_relaxed ----------------------------------------------- + +static inline int +_Py_atomic_load_int_relaxed(const int *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(int)*)obj, + memory_order_relaxed); +} + +static inline int8_t +_Py_atomic_load_int8_relaxed(const int8_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(int8_t)*)obj, + memory_order_relaxed); +} + +static inline int16_t +_Py_atomic_load_int16_relaxed(const int16_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(int16_t)*)obj, + memory_order_relaxed); +} + +static inline int32_t +_Py_atomic_load_int32_relaxed(const int32_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(int32_t)*)obj, + memory_order_relaxed); +} + +static inline int64_t +_Py_atomic_load_int64_relaxed(const int64_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(int64_t)*)obj, + memory_order_relaxed); +} + +static inline intptr_t +_Py_atomic_load_intptr_relaxed(const intptr_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(intptr_t)*)obj, + memory_order_relaxed); +} + +static inline uint8_t +_Py_atomic_load_uint8_relaxed(const uint8_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(uint8_t)*)obj, + memory_order_relaxed); +} + +static inline uint16_t +_Py_atomic_load_uint16_relaxed(const uint16_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(uint16_t)*)obj, + memory_order_relaxed); +} + +static inline uint32_t +_Py_atomic_load_uint32_relaxed(const uint32_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(uint32_t)*)obj, + memory_order_relaxed); +} + +static inline uint64_t +_Py_atomic_load_uint64_relaxed(const uint64_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(uint64_t)*)obj, + memory_order_relaxed); +} + +static inline uintptr_t +_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(uintptr_t)*)obj, + memory_order_relaxed); +} + +static inline unsigned int +_Py_atomic_load_uint_relaxed(const unsigned int *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(unsigned int)*)obj, + memory_order_relaxed); +} + +static inline Py_ssize_t +_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(Py_ssize_t)*)obj, + memory_order_relaxed); +} + +static inline void* +_Py_atomic_load_ptr_relaxed(const void *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(void*)*)obj, + memory_order_relaxed); +} + + +// --- _Py_atomic_store ------------------------------------------------------ + +static inline void +_Py_atomic_store_int(int *obj, int value) +{ + _Py_USING_STD; + atomic_store((_Atomic(int)*)obj, value); +} + +static inline void +_Py_atomic_store_int8(int8_t *obj, int8_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(int8_t)*)obj, value); +} + +static inline void +_Py_atomic_store_int16(int16_t *obj, int16_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(int16_t)*)obj, value); +} + +static inline void +_Py_atomic_store_int32(int32_t *obj, int32_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(int32_t)*)obj, value); +} + +static inline void +_Py_atomic_store_int64(int64_t *obj, int64_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(int64_t)*)obj, value); +} + +static inline void +_Py_atomic_store_intptr(intptr_t *obj, intptr_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(intptr_t)*)obj, value); +} + +static inline void +_Py_atomic_store_uint8(uint8_t *obj, uint8_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(uint8_t)*)obj, value); +} + +static inline void +_Py_atomic_store_uint16(uint16_t *obj, uint16_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(uint16_t)*)obj, value); +} + +static inline void +_Py_atomic_store_uint32(uint32_t *obj, uint32_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(uint32_t)*)obj, value); +} + +static inline void +_Py_atomic_store_uint64(uint64_t *obj, uint64_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(uint64_t)*)obj, value); +} + +static inline void +_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(uintptr_t)*)obj, value); +} + +static inline void +_Py_atomic_store_uint(unsigned int *obj, unsigned int value) +{ + _Py_USING_STD; + atomic_store((_Atomic(unsigned int)*)obj, value); +} + +static inline void +_Py_atomic_store_ptr(void *obj, void *value) +{ + _Py_USING_STD; + atomic_store((_Atomic(void*)*)obj, value); +} + +static inline void +_Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value) +{ + _Py_USING_STD; + atomic_store((_Atomic(Py_ssize_t)*)obj, value); +} + + +// --- _Py_atomic_store_relaxed ---------------------------------------------- + +static inline void +_Py_atomic_store_int_relaxed(int *obj, int value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(int)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(int8_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(int16_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(int32_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(int64_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(intptr_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(uint8_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(uint16_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(uint32_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(uint64_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(uintptr_t)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(unsigned int)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_ptr_relaxed(void *obj, void *value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(void*)*)obj, value, + memory_order_relaxed); +} + +static inline void +_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(Py_ssize_t)*)obj, value, + memory_order_relaxed); +} + + +// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------ + +static inline void * +_Py_atomic_load_ptr_acquire(const void *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(void*)*)obj, + memory_order_acquire); +} + +static inline void +_Py_atomic_store_ptr_release(void *obj, void *value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(void*)*)obj, value, + memory_order_release); +} + + +// --- _Py_atomic_fence ------------------------------------------------------ + + static inline void +_Py_atomic_fence_seq_cst(void) +{ + _Py_USING_STD; + atomic_thread_fence(memory_order_seq_cst); +} + + static inline void +_Py_atomic_fence_release(void) +{ + _Py_USING_STD; + atomic_thread_fence(memory_order_release); +} diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index 5c128211bd525a..da96eec4b35aab 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -88,15 +88,6 @@ typedef PyOSErrorObject PyEnvironmentErrorObject; typedef PyOSErrorObject PyWindowsErrorObject; #endif -/* Error handling definitions */ - -PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); - -/* Context manipulation (PEP 3134) */ - -Py_DEPRECATED(3.12) PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); -PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *); - /* In exceptions.c */ PyAPI_FUNC(PyObject*) PyUnstable_Exc_PrepReraiseStar( @@ -125,10 +116,6 @@ PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( PyObject *filename, int lineno); -PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg( - const char *err_msg, - PyObject *obj); - PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFunc( const char *func, const char *message); diff --git a/Include/cpython/pyframe.h b/Include/cpython/pyframe.h index 6ec292718aff1a..c5adbbe4868f69 100644 --- a/Include/cpython/pyframe.h +++ b/Include/cpython/pyframe.h @@ -16,3 +16,28 @@ PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame); PyAPI_FUNC(int) PyFrame_GetLasti(PyFrameObject *frame); PyAPI_FUNC(PyObject*) PyFrame_GetVar(PyFrameObject *frame, PyObject *name); PyAPI_FUNC(PyObject*) PyFrame_GetVarString(PyFrameObject *frame, const char *name); + +/* The following functions are for use by debuggers and other tools + * implementing custom frame evaluators with PEP 523. */ + +struct _PyInterpreterFrame; + +/* Returns the code object of the frame (strong reference). + * Does not raise an exception. */ +PyAPI_FUNC(PyObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame); + +/* Returns a byte ofsset into the last executed instruction. + * Does not raise an exception. */ +PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame); + +/* Returns the currently executing line number, or -1 if there is no line number. + * Does not raise an exception. */ +PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame); + +#define PyUnstable_EXECUTABLE_KIND_SKIP 0 +#define PyUnstable_EXECUTABLE_KIND_PY_FUNCTION 1 +#define PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION 3 +#define PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR 4 +#define PyUnstable_EXECUTABLE_KINDS 5 + +PyAPI_DATA(const PyTypeObject *) const PyUnstable_ExecutableKinds[PyUnstable_EXECUTABLE_KINDS+1]; diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 8af34b05642512..d425a233f71000 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -35,6 +35,49 @@ PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err); PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); +/* --- PyInterpreterConfig ------------------------------------ */ + +#define PyInterpreterConfig_DEFAULT_GIL (0) +#define PyInterpreterConfig_SHARED_GIL (1) +#define PyInterpreterConfig_OWN_GIL (2) + +typedef struct { + // XXX "allow_object_sharing"? "own_objects"? + int use_main_obmalloc; + int allow_fork; + int allow_exec; + int allow_threads; + int allow_daemon_threads; + int check_multi_interp_extensions; + int gil; +} PyInterpreterConfig; + +#define _PyInterpreterConfig_INIT \ + { \ + .use_main_obmalloc = 0, \ + .allow_fork = 0, \ + .allow_exec = 0, \ + .allow_threads = 1, \ + .allow_daemon_threads = 0, \ + .check_multi_interp_extensions = 1, \ + .gil = PyInterpreterConfig_OWN_GIL, \ + } + +#define _PyInterpreterConfig_LEGACY_INIT \ + { \ + .use_main_obmalloc = 1, \ + .allow_fork = 1, \ + .allow_exec = 1, \ + .allow_threads = 1, \ + .allow_daemon_threads = 1, \ + .check_multi_interp_extensions = 0, \ + .gil = PyInterpreterConfig_SHARED_GIL, \ + } + PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig( PyThreadState **tstate_p, const PyInterpreterConfig *config); + +typedef void (*atexit_datacallbackfunc)(void *); +PyAPI_FUNC(int) PyUnstable_AtExit( + PyInterpreterState *, atexit_datacallbackfunc, void *); diff --git a/Include/cpython/pymem.h b/Include/cpython/pymem.h index d1054d76520b9a..b75f1c4d2425dd 100644 --- a/Include/cpython/pymem.h +++ b/Include/cpython/pymem.h @@ -7,18 +7,6 @@ PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_RawFree(void *ptr); -/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ -PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void); - -/* strdup() using PyMem_RawMalloc() */ -PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); - -/* strdup() using PyMem_Malloc() */ -PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); - -/* wcsdup() using PyMem_RawMalloc() */ -PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); - typedef enum { /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 4254110889fc6c..40102f8855090e 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -8,6 +8,7 @@ PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); +PyAPI_FUNC(PyObject *) PyUnstable_InterpreterState_GetMainModule(PyInterpreterState *); /* State unique per thread */ @@ -28,24 +29,6 @@ typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *); #define PyTrace_C_RETURN 6 #define PyTrace_OPCODE 7 -// Internal structure: you should not use it directly, but use public functions -// like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing(). -typedef struct _PyCFrame { - /* This struct will be threaded through the C stack - * allowing fast access to per-thread state that needs - * to be accessed quickly by the interpreter, but can - * be modified outside of the interpreter. - * - * WARNING: This makes data on the C stack accessible from - * heap objects. Care must be taken to maintain stack - * discipline and make sure that instances of this struct cannot - * accessed outside of their lifetime. - */ - /* Pointer to the currently executing frame (it can be NULL) */ - struct _PyInterpreterFrame *current_frame; - struct _PyCFrame *previous; -} _PyCFrame; - typedef struct _err_stackitem { /* This struct represents a single execution context where we might * be currently handling an exception. It is a per-coroutine state @@ -109,6 +92,19 @@ struct _ts { /* padding to align to 4 bytes */ unsigned int :24; } _status; +#ifdef Py_BUILD_CORE +# define _PyThreadState_WHENCE_NOTSET -1 +# define _PyThreadState_WHENCE_UNKNOWN 0 +# define _PyThreadState_WHENCE_INTERP 1 +# define _PyThreadState_WHENCE_THREADING 2 +# define _PyThreadState_WHENCE_GILSTATE 3 +# define _PyThreadState_WHENCE_EXEC 4 +#endif + int _whence; + + /* Thread state (_Py_THREAD_ATTACHED, _Py_THREAD_DETACHED, _Py_THREAD_GC). + See Include/internal/pycore_pystate.h for more details. */ + int state; int py_recursion_remaining; int py_recursion_limit; @@ -122,9 +118,8 @@ struct _ts { int tracing; int what_event; /* The event currently being monitored, if any. */ - /* Pointer to current _PyCFrame in the C stack frame of the currently, - * or most recently, executing _PyEval_EvalFrameDefault. */ - _PyCFrame *cframe; + /* Pointer to currently executing frame. */ + struct _PyInterpreterFrame *current_frame; Py_tracefunc c_profilefunc; Py_tracefunc c_tracefunc; @@ -210,26 +205,25 @@ struct _ts { /* The thread's exception stack entry. (Always the last entry.) */ _PyErr_StackItem exc_state; - /* The bottom-most frame on the stack. */ - _PyCFrame root_cframe; }; -/* WASI has limited call stack. Python's recursion limit depends on code - layout, optimization, and WASI runtime. Wasmtime can handle about 700 - recursions, sometimes less. 500 is a more conservative limit. */ -#ifndef C_RECURSION_LIMIT -# ifdef __wasi__ -# define C_RECURSION_LIMIT 500 -# else -# define C_RECURSION_LIMIT 800 -# endif +#ifdef __wasi__ + // WASI has limited call stack. Python's recursion limit depends on code + // layout, optimization, and WASI runtime. Wasmtime can handle about 700 + // recursions, sometimes less. 500 is a more conservative limit. +# define Py_C_RECURSION_LIMIT 500 +#else + // This value is duplicated in Lib/test/support/__init__.py +# define Py_C_RECURSION_LIMIT 1500 #endif + /* other API */ /* Similar to PyThreadState_Get(), but don't issue a fatal error * if it is NULL. */ -PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); +PyAPI_FUNC(PyThreadState *) PyThreadState_GetUnchecked(void); + // Disable tracing and profiling. PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); @@ -246,15 +240,6 @@ PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate); The function returns 1 if _PyGILState_check_enabled is non-zero. */ PyAPI_FUNC(int) PyGILState_Check(void); -/* Get the single PyInterpreterState used by this process' GILState - implementation. - - This function doesn't check for error. Return NULL before _PyGILState_Init() - is called and after _PyGILState_Fini() is called. - - See also PyInterpreterState_Get() and _PyInterpreterState_GET(). */ -PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); - /* Routines for advanced debuggers, requested by David Beazley. Don't use unless you know what you are doing! */ PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); @@ -338,6 +323,7 @@ PyAPI_FUNC(void) _PyCrossInterpreterData_Clear( PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); +PyAPI_FUNC(int) _PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *); PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); diff --git a/Include/cpython/pystats.h b/Include/cpython/pystats.h new file mode 100644 index 00000000000000..4988caa803723d --- /dev/null +++ b/Include/cpython/pystats.h @@ -0,0 +1,141 @@ +// Statistics on Python performance. +// +// API: +// +// - _Py_INCREF_STAT_INC() and _Py_DECREF_STAT_INC() used by Py_INCREF() +// and Py_DECREF(). +// - _Py_stats variable +// +// Functions of the sys module: +// +// - sys._stats_on() +// - sys._stats_off() +// - sys._stats_clear() +// - sys._stats_dump() +// +// Python must be built with ./configure --enable-pystats to define the +// Py_STATS macro. +// +// Define _PY_INTERPRETER macro to increment interpreter_increfs and +// interpreter_decrefs. Otherwise, increment increfs and decrefs. + +#ifndef Py_CPYTHON_PYSTATS_H +# error "this header file must not be included directly" +#endif + +#define SPECIALIZATION_FAILURE_KINDS 36 + +/* Stats for determining who is calling PyEval_EvalFrame */ +#define EVAL_CALL_TOTAL 0 +#define EVAL_CALL_VECTOR 1 +#define EVAL_CALL_GENERATOR 2 +#define EVAL_CALL_LEGACY 3 +#define EVAL_CALL_FUNCTION_VECTORCALL 4 +#define EVAL_CALL_BUILD_CLASS 5 +#define EVAL_CALL_SLOT 6 +#define EVAL_CALL_FUNCTION_EX 7 +#define EVAL_CALL_API 8 +#define EVAL_CALL_METHOD 9 + +#define EVAL_CALL_KINDS 10 + +typedef struct _specialization_stats { + uint64_t success; + uint64_t failure; + uint64_t hit; + uint64_t deferred; + uint64_t miss; + uint64_t deopt; + uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS]; +} SpecializationStats; + +typedef struct _opcode_stats { + SpecializationStats specialization; + uint64_t execution_count; + uint64_t pair_count[256]; +} OpcodeStats; + +typedef struct _call_stats { + uint64_t inlined_py_calls; + uint64_t pyeval_calls; + uint64_t frames_pushed; + uint64_t frame_objects_created; + uint64_t eval_calls[EVAL_CALL_KINDS]; +} CallStats; + +typedef struct _object_stats { + uint64_t increfs; + uint64_t decrefs; + uint64_t interpreter_increfs; + uint64_t interpreter_decrefs; + uint64_t allocations; + uint64_t allocations512; + uint64_t allocations4k; + uint64_t allocations_big; + uint64_t frees; + uint64_t to_freelist; + uint64_t from_freelist; + uint64_t new_values; + uint64_t dict_materialized_on_request; + uint64_t dict_materialized_new_key; + uint64_t dict_materialized_too_big; + uint64_t dict_materialized_str_subclass; + uint64_t dict_dematerialized; + uint64_t type_cache_hits; + uint64_t type_cache_misses; + uint64_t type_cache_dunder_hits; + uint64_t type_cache_dunder_misses; + uint64_t type_cache_collisions; + /* Temporary value used during GC */ + uint64_t object_visits; +} ObjectStats; + +typedef struct _gc_stats { + uint64_t collections; + uint64_t object_visits; + uint64_t objects_collected; +} GCStats; + +typedef struct _uop_stats { + uint64_t execution_count; +} UOpStats; + +#define _Py_UOP_HIST_SIZE 32 + +typedef struct _optimization_stats { + uint64_t attempts; + uint64_t traces_created; + uint64_t traces_executed; + uint64_t uops_executed; + uint64_t trace_stack_overflow; + uint64_t trace_stack_underflow; + uint64_t trace_too_long; + uint64_t trace_too_short; + uint64_t inner_loop; + uint64_t recursive_call; + UOpStats opcode[512]; + uint64_t unsupported_opcode[256]; + uint64_t trace_length_hist[_Py_UOP_HIST_SIZE]; + uint64_t trace_run_length_hist[_Py_UOP_HIST_SIZE]; + uint64_t optimized_trace_length_hist[_Py_UOP_HIST_SIZE]; +} OptimizationStats; + +typedef struct _stats { + OpcodeStats opcode_stats[256]; + CallStats call_stats; + ObjectStats object_stats; + OptimizationStats optimization_stats; + GCStats *gc_stats; +} PyStats; + + +// Export for shared extensions like 'math' +PyAPI_DATA(PyStats*) _Py_stats; + +#ifdef _PY_INTERPRETER +# define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_increfs++; } while (0) +# define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_decrefs++; } while (0) +#else +# define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.increfs++; } while (0) +# define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.decrefs++; } while (0) +#endif diff --git a/Include/cpython/pythonrun.h b/Include/cpython/pythonrun.h index fb617655374026..edc40952254029 100644 --- a/Include/cpython/pythonrun.h +++ b/Include/cpython/pythonrun.h @@ -3,21 +3,11 @@ #endif PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); -PyAPI_FUNC(int) _PyRun_SimpleFileObject( - FILE *fp, - PyObject *filename, - int closeit, - PyCompilerFlags *flags); PyAPI_FUNC(int) PyRun_AnyFileExFlags( FILE *fp, const char *filename, /* decoded from the filesystem encoding */ int closeit, PyCompilerFlags *flags); -PyAPI_FUNC(int) _PyRun_AnyFileObject( - FILE *fp, - PyObject *filename, - int closeit, - PyCompilerFlags *flags); PyAPI_FUNC(int) PyRun_SimpleFileExFlags( FILE *fp, const char *filename, /* decoded from the filesystem encoding */ @@ -35,10 +25,6 @@ PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( FILE *fp, const char *filename, /* decoded from the filesystem encoding */ PyCompilerFlags *flags); -PyAPI_FUNC(int) _PyRun_InteractiveLoopObject( - FILE *fp, - PyObject *filename, - PyCompilerFlags *flags); PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, @@ -69,15 +55,6 @@ PyAPI_FUNC(PyObject *) Py_CompileStringObject( #define Py_CompileString(str, p, s) Py_CompileStringExFlags((str), (p), (s), NULL, -1) #define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags((str), (p), (s), (f), -1) - -PyAPI_FUNC(const char *) _Py_SourceAsString( - PyObject *cmd, - const char *funcname, - const char *what, - PyCompilerFlags *cf, - PyObject **cmd_copy); - - /* A function flavor is also exported by libpython. It is required when libpython is accessed directly rather than using header files which defines macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to @@ -114,8 +91,6 @@ PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject #define PyRun_FileFlags(fp, p, s, g, l, flags) \ PyRun_FileExFlags((fp), (p), (s), (g), (l), 0, (flags)) - /* Stuff with no proper home (yet) */ PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); -PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *); diff --git a/Include/cpython/pythread.h b/Include/cpython/pythread.h index ce4ec8f65b15ea..03f710a9f7ef2e 100644 --- a/Include/cpython/pythread.h +++ b/Include/cpython/pythread.h @@ -2,14 +2,15 @@ # error "this header file must not be included directly" #endif -#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) +// PY_TIMEOUT_MAX is the highest usable value (in microseconds) of PY_TIMEOUT_T +// type, and depends on the system threading API. +// +// NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread module +// exposes a higher-level API, with timeouts expressed in seconds and +// floating-point numbers allowed. +PyAPI_DATA(const long long) PY_TIMEOUT_MAX; -#ifdef HAVE_FORK -/* Private function to reinitialize a lock at fork in the child process. - Reset the lock to the unlocked state. - Return 0 on success, return -1 on error. */ -PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock); -#endif /* HAVE_FORK */ +#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) #ifdef HAVE_PTHREAD_H /* Darwin needs pthread.h to know type name the pthread_key_t. */ diff --git a/Include/cpython/setobject.h b/Include/cpython/setobject.h index 20fd63eaae56e2..1778c778a05324 100644 --- a/Include/cpython/setobject.h +++ b/Include/cpython/setobject.h @@ -65,8 +65,3 @@ static inline Py_ssize_t PySet_GET_SIZE(PyObject *so) { return _PySet_CAST(so)->used; } #define PySet_GET_SIZE(so) PySet_GET_SIZE(_PyObject_CAST(so)) - -PyAPI_DATA(PyObject *) _PySet_Dummy; - -PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); -PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); diff --git a/Include/cpython/sysmodule.h b/Include/cpython/sysmodule.h index 19d9dddc344a4f..36c4f89432067b 100644 --- a/Include/cpython/sysmodule.h +++ b/Include/cpython/sysmodule.h @@ -2,15 +2,14 @@ # error "this header file must not be included directly" #endif -PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *tstate, - PyObject *name); - -PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); - typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); PyAPI_FUNC(int) PySys_Audit( const char *event, - const char *argFormat, + const char *format, ...); PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); + +PyAPI_FUNC(int) PySys_AuditTuple( + const char *event, + PyObject *args); diff --git a/Include/cpython/traceback.h b/Include/cpython/traceback.h index a4e087b2b4eced..81c51944f136f2 100644 --- a/Include/cpython/traceback.h +++ b/Include/cpython/traceback.h @@ -11,6 +11,3 @@ struct _traceback { int tb_lasti; int tb_lineno; }; - -PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **); -PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); diff --git a/Include/cpython/tupleobject.h b/Include/cpython/tupleobject.h index 370da1612a61ed..e530c8beda44ab 100644 --- a/Include/cpython/tupleobject.h +++ b/Include/cpython/tupleobject.h @@ -11,7 +11,6 @@ typedef struct { } PyTupleObject; PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); -PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); /* Cast argument to PyTupleObject* type. */ #define _PyTuple_CAST(op) \ @@ -37,5 +36,3 @@ PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { } #define PyTuple_SET_ITEM(op, index, value) \ PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) - -PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index e75b5e154943dc..859ab7178e920a 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -140,9 +140,11 @@ typedef struct { and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is set, use the PyASCIIObject structure. */ unsigned int ascii:1; + /* The object is statically allocated. */ + unsigned int statically_allocated:1; /* Padding to ensure that PyUnicode_DATA() is always aligned to 4 bytes (see issue #19537 on m68k). */ - unsigned int :25; + unsigned int :24; } state; } PyASCIIObject; @@ -446,17 +448,12 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData( Like PyUnicode_AsUTF8AndSize(), this also caches the UTF-8 representation in the unicodeobject. - _PyUnicode_AsString is a #define for PyUnicode_AsUTF8 to - support the previous internal function with the same behaviour. - Use of this API is DEPRECATED since no size information can be extracted from the returned data. */ PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode); -#define _PyUnicode_AsString PyUnicode_AsUTF8 - /* === Characters Type APIs =============================================== */ /* These should not be used directly. Use the Py_UNICODE_IS* and @@ -478,14 +475,6 @@ PyAPI_FUNC(int) _PyUnicode_IsTitlecase( Py_UCS4 ch /* Unicode character */ ); -PyAPI_FUNC(int) _PyUnicode_IsXidStart( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsXidContinue( - Py_UCS4 ch /* Unicode character */ - ); - PyAPI_FUNC(int) _PyUnicode_IsWhitespace( const Py_UCS4 ch /* Unicode character */ ); @@ -506,34 +495,6 @@ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase( Py_UCS4 ch /* Unicode character */ ); -PyAPI_FUNC(int) _PyUnicode_ToLowerFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_ToTitleFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_ToUpperFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_ToFoldedFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_IsCaseIgnorable( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsCased( - Py_UCS4 ch /* Unicode character */ - ); - PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit( Py_UCS4 ch /* Unicode character */ ); diff --git a/Include/dictobject.h b/Include/dictobject.h index e7fcb44d0cf9a9..1bbeec1ab699e7 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -57,6 +57,17 @@ PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030D0000 +// Return the object from dictionary *op* which has a key *key*. +// - If the key is present, set *result to a new strong reference to the value +// and return 1. +// - If the key is missing, set *result to NULL and return 0 . +// - On error, raise an exception and return -1. +PyAPI_FUNC(int) PyDict_GetItemRef(PyObject *mp, PyObject *key, PyObject **result); +PyAPI_FUNC(int) PyDict_GetItemStringRef(PyObject *mp, const char *key, PyObject **result); +#endif + #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *); #endif diff --git a/Include/errcode.h b/Include/errcode.h index 54ae929bf25870..8d44e9ae559193 100644 --- a/Include/errcode.h +++ b/Include/errcode.h @@ -1,18 +1,24 @@ +// Error codes passed around between file input, tokenizer, parser and +// interpreter. This is necessary so we can turn them into Python +// exceptions at a higher level. Note that some errors have a +// slightly different meaning when passed from the tokenizer to the +// parser than when passed from the parser to the interpreter; e.g. +// the parser only returns E_EOF when it hits EOF immediately, and it +// never returns E_OK. +// +// The public PyRun_InteractiveOneObjectEx() function can return E_EOF, +// same as its variants: +// +// * PyRun_InteractiveOneObject() +// * PyRun_InteractiveOneFlags() +// * PyRun_InteractiveOne() + #ifndef Py_ERRCODE_H #define Py_ERRCODE_H #ifdef __cplusplus extern "C" { #endif - -/* Error codes passed around between file input, tokenizer, parser and - interpreter. This is necessary so we can turn them into Python - exceptions at a higher level. Note that some errors have a - slightly different meaning when passed from the tokenizer to the - parser than when passed from the parser to the interpreter; e.g. - the parser only returns E_EOF when it hits EOF immediately, and it - never returns E_OK. */ - #define E_OK 10 /* No error */ #define E_EOF 11 /* End Of File */ #define E_INTR 12 /* Interrupted */ diff --git a/Include/exports.h b/Include/exports.h index 59373c39ff757c..ce601216f17156 100644 --- a/Include/exports.h +++ b/Include/exports.h @@ -1,6 +1,29 @@ #ifndef Py_EXPORTS_H #define Py_EXPORTS_H +/* Declarations for symbol visibility. + + PyAPI_FUNC(type): Declares a public Python API function and return type + PyAPI_DATA(type): Declares public Python data and its type + PyMODINIT_FUNC: A Python module init function. If these functions are + inside the Python core, they are private to the core. + If in an extension module, it may be declared with + external linkage depending on the platform. + + As a number of platforms support/require "__declspec(dllimport/dllexport)", + we support a HAVE_DECLSPEC_DLL macro to save duplication. +*/ + +/* + All windows ports, except cygwin, are handled in PC/pyconfig.h. + + Cygwin is the only other autoconf platform requiring special + linkage handling and it uses __declspec(). +*/ +#if defined(__CYGWIN__) +# define HAVE_DECLSPEC_DLL +#endif + #if defined(_WIN32) || defined(__CYGWIN__) #if defined(Py_ENABLE_SHARED) #define Py_IMPORTED_SYMBOL __declspec(dllimport) @@ -33,4 +56,53 @@ #endif #endif +/* only get special linkage if built as shared or platform is Cygwin */ +#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) +# if defined(HAVE_DECLSPEC_DLL) +# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE +# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE + /* module init functions inside the core need no external linkage */ + /* except for Cygwin to handle embedding */ +# if defined(__CYGWIN__) +# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* +# else /* __CYGWIN__ */ +# define PyMODINIT_FUNC PyObject* +# endif /* __CYGWIN__ */ +# else /* Py_BUILD_CORE */ + /* Building an extension module, or an embedded situation */ + /* public Python functions and data are imported */ + /* Under Cygwin, auto-import functions to prevent compilation */ + /* failures similar to those described at the bottom of 4.1: */ + /* http://docs.python.org/extending/windows.html#a-cookbook-approach */ +# if !defined(__CYGWIN__) +# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE +# endif /* !__CYGWIN__ */ +# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE + /* module init functions outside the core must be exported */ +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject* +# else /* __cplusplus */ +# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* +# endif /* __cplusplus */ +# endif /* Py_BUILD_CORE */ +# endif /* HAVE_DECLSPEC_DLL */ +#endif /* Py_ENABLE_SHARED */ + +/* If no external linkage macros defined by now, create defaults */ +#ifndef PyAPI_FUNC +# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE +#endif +#ifndef PyAPI_DATA +# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE +#endif +#ifndef PyMODINIT_FUNC +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject* +# else /* __cplusplus */ +# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* +# endif /* __cplusplus */ +#endif + + #endif /* Py_EXPORTS_H */ diff --git a/Include/fileobject.h b/Include/fileobject.h index 2deef544d667a5..6a6d11409497fa 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -29,14 +29,6 @@ Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UTF8Mode; #endif -/* A routine to check if a file descriptor can be select()-ed. */ -#ifdef _MSC_VER - /* On Windows, any socket fd can be select()-ed, no matter how high */ - #define _PyIsSelectable_fd(FD) (1) -#else - #define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE) -#endif - #ifndef Py_LIMITED_API # define Py_CPYTHON_FILEOBJECT_H # include "cpython/fileobject.h" diff --git a/Include/fileutils.h b/Include/fileutils.h index ba5acc84fcb185..1509198e45f0ca 100644 --- a/Include/fileutils.h +++ b/Include/fileutils.h @@ -1,5 +1,41 @@ #ifndef Py_FILEUTILS_H #define Py_FILEUTILS_H + +/******************************* + * stat() and fstat() fiddling * + *******************************/ + +#ifdef HAVE_SYS_STAT_H +# include // S_ISREG() +#elif defined(HAVE_STAT_H) +# include // S_ISREG() +#endif + +#ifndef S_IFMT + // VisualAge C/C++ Failed to Define MountType Field in sys/stat.h. +# define S_IFMT 0170000 +#endif +#ifndef S_IFLNK + // Windows doesn't define S_IFLNK, but posixmodule.c maps + // IO_REPARSE_TAG_SYMLINK to S_IFLNK. +# define S_IFLNK 0120000 +#endif +#ifndef S_ISREG +# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif +#ifndef S_ISDIR +# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif +#ifndef S_ISCHR +# define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) +#endif +#ifndef S_ISLNK +# define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) +#endif + + +// Move this down here since some C++ #include's don't like to be included +// inside an extern "C". #ifdef __cplusplus extern "C" { #endif diff --git a/Include/internal/pycore_abstract.h b/Include/internal/pycore_abstract.h index 2733d8102e5ef4..3cc0afac4bd5b4 100644 --- a/Include/internal/pycore_abstract.h +++ b/Include/internal/pycore_abstract.h @@ -47,6 +47,13 @@ extern int _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); extern int _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); +// Convert Python int to Py_ssize_t. Do nothing if the argument is None. +// Export for '_bisect' shared extension. +PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); + +// Same as PyNumber_Index() but can return an instance of a subclass of int. +// Export for 'math' shared extension. +PyAPI_FUNC(PyObject*) _PyNumber_Index(PyObject *o); #ifdef __cplusplus } diff --git a/Include/internal/pycore_ast.h b/Include/internal/pycore_ast.h index b568902bb1e381..f222d485e0b54b 100644 --- a/Include/internal/pycore_ast.h +++ b/Include/internal/pycore_ast.h @@ -10,7 +10,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_asdl.h" +#include "pycore_asdl.h" // _ASDL_SEQ_HEAD typedef struct _mod *mod_ty; diff --git a/Include/internal/pycore_atexit.h b/Include/internal/pycore_atexit.h index fc5cb6d8826435..3966df70e2616f 100644 --- a/Include/internal/pycore_atexit.h +++ b/Include/internal/pycore_atexit.h @@ -51,6 +51,7 @@ struct atexit_state { int callback_len; }; +// Export for '_xxinterpchannels' shared extension PyAPI_FUNC(int) _Py_AtExit( PyInterpreterState *interp, atexit_datacallbackfunc func, diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h index 425d69f868b52b..22ce971a64f3df 100644 --- a/Include/internal/pycore_atomic.h +++ b/Include/internal/pycore_atomic.h @@ -1,5 +1,5 @@ -#ifndef Py_ATOMIC_H -#define Py_ATOMIC_H +#ifndef Py_INTERNAL_ATOMIC_H +#define Py_INTERNAL_ATOMIC_H #ifdef __cplusplus extern "C" { #endif @@ -8,19 +8,19 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "dynamic_annotations.h" /* _Py_ANNOTATE_MEMORY_ORDER */ -#include "pyconfig.h" +#include "pyconfig.h" // HAVE_STD_ATOMIC +#include "dynamic_annotations.h" // _Py_ANNOTATE_MEMORY_ORDER #ifdef HAVE_STD_ATOMIC -# include +# include // atomic_store_explicit() #endif #if defined(_MSC_VER) -#include -#if defined(_M_IX86) || defined(_M_X64) -# include -#endif +# include // _InterlockedExchange64() +# if defined(_M_IX86) || defined(_M_X64) +# include // _InterlockedExchange_HLEAcquire() +# endif #endif /* This is modeled after the atomics interface from C1x, according to @@ -554,4 +554,4 @@ typedef struct _Py_atomic_int { #ifdef __cplusplus } #endif -#endif /* Py_ATOMIC_H */ +#endif /* Py_INTERNAL_ATOMIC_H */ diff --git a/Include/internal/pycore_atomic_funcs.h b/Include/internal/pycore_atomic_funcs.h deleted file mode 100644 index a708789cea733b..00000000000000 --- a/Include/internal/pycore_atomic_funcs.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Atomic functions: similar to pycore_atomic.h, but don't need - to declare variables as atomic. - - Py_ssize_t type: - - * value = _Py_atomic_size_get(&var) - * _Py_atomic_size_set(&var, value) - - Use sequentially-consistent ordering (__ATOMIC_SEQ_CST memory order): - enforce total ordering with all other atomic functions. -*/ -#ifndef Py_ATOMIC_FUNC_H -#define Py_ATOMIC_FUNC_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#if defined(_MSC_VER) -# include // _InterlockedExchange() -#endif - - -// Use builtin atomic operations in GCC >= 4.7 and clang -#ifdef HAVE_BUILTIN_ATOMIC - -static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) -{ - return __atomic_load_n(var, __ATOMIC_SEQ_CST); -} - -static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) -{ - __atomic_store_n(var, value, __ATOMIC_SEQ_CST); -} - -#elif defined(_MSC_VER) - -static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) -{ -#if SIZEOF_VOID_P == 8 - Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var)); - volatile __int64 *volatile_var = (volatile __int64 *)var; - __int64 old; - do { - old = *volatile_var; - } while(_InterlockedCompareExchange64(volatile_var, old, old) != old); -#else - Py_BUILD_ASSERT(sizeof(long) == sizeof(*var)); - volatile long *volatile_var = (volatile long *)var; - long old; - do { - old = *volatile_var; - } while(_InterlockedCompareExchange(volatile_var, old, old) != old); -#endif - return old; -} - -static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) -{ -#if SIZEOF_VOID_P == 8 - Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var)); - volatile __int64 *volatile_var = (volatile __int64 *)var; - _InterlockedExchange64(volatile_var, value); -#else - Py_BUILD_ASSERT(sizeof(long) == sizeof(*var)); - volatile long *volatile_var = (volatile long *)var; - _InterlockedExchange(volatile_var, value); -#endif -} - -#else -// Fallback implementation using volatile - -static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) -{ - volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var; - return *volatile_var; -} - -static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) -{ - volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var; - *volatile_var = value; -} -#endif - -#ifdef __cplusplus -} -#endif -#endif /* Py_ATOMIC_FUNC_H */ diff --git a/Include/internal/pycore_bitutils.h b/Include/internal/pycore_bitutils.h index e6bf61ef425bd8..50f69377523818 100644 --- a/Include/internal/pycore_bitutils.h +++ b/Include/internal/pycore_bitutils.h @@ -26,10 +26,10 @@ extern "C" { #endif #ifdef _MSC_VER - /* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */ -# include +# include // _byteswap_uint64() #endif + static inline uint16_t _Py_bswap16(uint16_t word) { diff --git a/Include/internal/pycore_blocks_output_buffer.h b/Include/internal/pycore_blocks_output_buffer.h index 28cf6fba4eeba2..573e10359b7bd2 100644 --- a/Include/internal/pycore_blocks_output_buffer.h +++ b/Include/internal/pycore_blocks_output_buffer.h @@ -40,6 +40,10 @@ extern "C" { #include "Python.h" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + typedef struct { // List of bytes objects PyObject *list; @@ -314,4 +318,4 @@ _BlocksOutputBuffer_OnError(_BlocksOutputBuffer *buffer) #ifdef __cplusplus } #endif -#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */ \ No newline at end of file +#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */ diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index 115c0c52c8f9a9..94d421a9eb742a 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -8,35 +8,57 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif - -/* Substring Search. - - Returns the index of the first occurrence of - a substring ("needle") in a larger text ("haystack"). - If the needle is not found, return -1. - If the needle is found, add offset to the index. -*/ - +extern PyObject* _PyBytes_FormatEx( + const char *format, + Py_ssize_t format_len, + PyObject *args, + int use_bytearray); + +extern PyObject* _PyBytes_FromHex( + PyObject *string, + int use_bytearray); + +// Helper for PyBytes_DecodeEscape that detects invalid escape chars. +// Export for test_peg_generator. +PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, const char **); + +/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, + x must be an iterable object. */ +extern PyObject* _PyBytes_Join(PyObject *sep, PyObject *x); + + +// Substring Search. +// +// Returns the index of the first occurrence of +// a substring ("needle") in a larger text ("haystack"). +// If the needle is not found, return -1. +// If the needle is found, add offset to the index. +// +// Export for 'mmap' shared extension. PyAPI_FUNC(Py_ssize_t) _PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, const char *needle, Py_ssize_t len_needle, Py_ssize_t offset); -/* Same as above, but search right-to-left */ +// Same as above, but search right-to-left. +// Export for 'mmap' shared extension. PyAPI_FUNC(Py_ssize_t) _PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, const char *needle, Py_ssize_t len_needle, Py_ssize_t offset); -/** Helper function to implement the repeat and inplace repeat methods on a buffer - * - * len_dest is assumed to be an integer multiple of len_src. - * If src equals dest, then assume the operation is inplace. - * - * This method repeately doubles the number of bytes copied to reduce - * the number of invocations of memcpy. - */ +// Helper function to implement the repeat and inplace repeat methods on a +// buffer. +// +// len_dest is assumed to be an integer multiple of len_src. +// If src equals dest, then assume the operation is inplace. +// +// This method repeately doubles the number of bytes copied to reduce +// the number of invocations of memcpy. +// +// Export for 'array' shared extension. PyAPI_FUNC(void) _PyBytes_Repeat(char* dest, Py_ssize_t len_dest, const char* src, Py_ssize_t len_src); @@ -72,7 +94,9 @@ typedef struct { /* Initialize a bytes writer By default, the overallocation is disabled. Set the overallocate attribute - to control the allocation of the buffer. */ + to control the allocation of the buffer. + + Export _PyBytesWriter API for '_pickle' shared extension. */ PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer); /* Get the buffer content and reset the writer. diff --git a/Include/internal/pycore_call.h b/Include/internal/pycore_call.h index 9c32035d474b3c..8846155b38defb 100644 --- a/Include/internal/pycore_call.h +++ b/Include/internal/pycore_call.h @@ -8,6 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_identifier.h" // _Py_Identifier #include "pycore_pystate.h" // _PyThreadState_GET() /* Suggested size (number of positional arguments) for arrays of PyObject* @@ -22,8 +23,8 @@ extern "C" { #define _PY_FASTCALL_SMALL_STACK 5 -// Export for shared stdlib extensions like the math extension, -// function used via inlined _PyObject_VectorcallTstate() function. +// Export for 'math' shared extension, used via _PyObject_VectorcallTstate() +// static inline function. PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult( PyThreadState *tstate, PyObject *callable, @@ -68,7 +69,7 @@ extern PyObject * _PyObject_CallMethodFormat( const char *format, ...); -// Export for shared stdlib extensions like the array extension +// Export for 'array' shared extension PyAPI_FUNC(PyObject*) _PyObject_CallMethod( PyObject *obj, PyObject *name, @@ -120,8 +121,8 @@ _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg // Call callable using tp_call. Arguments are like PyObject_Vectorcall(), // except that nargs is plainly the number of arguments without flags. // -// Export for shared stdlib extensions like the math extension, -// function used via inlined _PyObject_VectorcallTstate() function. +// Export for 'math' shared extension, used via _PyObject_VectorcallTstate() +// static inline function. PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall( PyThreadState *tstate, PyObject *callable, diff --git a/Include/internal/pycore_capsule.h b/Include/internal/pycore_capsule.h new file mode 100644 index 00000000000000..aa2c67f3a8f002 --- /dev/null +++ b/Include/internal/pycore_capsule.h @@ -0,0 +1,17 @@ +#ifndef Py_INTERNAL_PYCAPSULE_H +#define Py_INTERNAL_PYCAPSULE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +// Export for '_socket' shared extension +PyAPI_FUNC(int) _PyCapsule_SetTraverse(PyObject *op, traverseproc traverse_func, inquiry clear_func); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYCAPSULE_H */ diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index e729904ff2c4cc..312d67ee0b37aa 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -8,28 +8,61 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_interp.h" // PyInterpreterState.eval_frame +#include "pycore_pystate.h" // _PyThreadState_GET() + /* Forward declarations */ struct pyruntimestate; struct _ceval_runtime_state; +// Export for '_lsprof' shared extension +PyAPI_FUNC(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); + +extern int _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); + +// Helper to look up a builtin object +// Export for 'array' shared extension +PyAPI_FUNC(PyObject*) _PyEval_GetBuiltin(PyObject *); + +extern PyObject* _PyEval_GetBuiltinId(_Py_Identifier *); + +extern void _PyEval_SetSwitchInterval(unsigned long microseconds); +extern unsigned long _PyEval_GetSwitchInterval(void); + +// Export for '_queue' shared extension +PyAPI_FUNC(int) _PyEval_MakePendingCalls(PyThreadState *); + #ifndef Py_DEFAULT_RECURSION_LIMIT # define Py_DEFAULT_RECURSION_LIMIT 1000 #endif -#include "pycore_interp.h" // PyInterpreterState.eval_frame -#include "pycore_pystate.h" // _PyThreadState_GET() - - extern void _Py_FinishPendingCalls(PyThreadState *tstate); extern void _PyEval_InitState(PyInterpreterState *, PyThread_type_lock); extern void _PyEval_FiniState(struct _ceval_state *ceval); -PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp); +extern void _PyEval_SignalReceived(PyInterpreterState *interp); + +// bitwise flags: +#define _Py_PENDING_MAINTHREADONLY 1 +#define _Py_PENDING_RAWFREE 2 + +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(int) _PyEval_AddPendingCall( PyInterpreterState *interp, - int (*func)(void *), + _Py_pending_call_func func, void *arg, - int mainthreadonly); -PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp); + int flags); + +typedef int (*_Py_simple_func)(void *); +extern int _Py_CallInInterpreter( + PyInterpreterState *interp, + _Py_simple_func func, + void *arg); +extern int _Py_CallInInterpreterAndRawFree( + PyInterpreterState *interp, + _Py_simple_func func, + void *arg); + +extern void _PyEval_SignalAsyncExc(PyInterpreterState *interp); #ifdef HAVE_FORK extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); #endif @@ -102,7 +135,6 @@ extern void _PyEval_FiniGIL(PyInterpreterState *interp); extern void _PyEval_AcquireLock(PyThreadState *tstate); extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *); -extern PyThreadState * _PyThreadState_SwapNoGIL(PyThreadState *); extern void _PyEval_DeactivateOpCache(void); @@ -122,6 +154,8 @@ static inline int _Py_MakeRecCheck(PyThreadState *tstate) { } #endif +// Export for '_json' shared extension, used via _Py_EnterRecursiveCall() +// static inline function. PyAPI_FUNC(int) _Py_CheckRecursiveCall( PyThreadState *tstate, const char *where); @@ -158,6 +192,52 @@ extern int _Py_HandlePending(PyThreadState *tstate); extern PyObject * _PyEval_GetFrameLocals(void); +extern const binaryfunc _PyEval_BinaryOps[]; +int _PyEval_CheckExceptStarTypeValid(PyThreadState *tstate, PyObject* right); +int _PyEval_CheckExceptTypeValid(PyThreadState *tstate, PyObject* right); +int _PyEval_ExceptionGroupMatch(PyObject* exc_value, PyObject *match_type, PyObject **match, PyObject **rest); +void _PyEval_FormatAwaitableError(PyThreadState *tstate, PyTypeObject *type, int oparg); +void _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, const char *format_str, PyObject *obj); +void _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg); +void _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs); +PyObject *_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs); +PyObject *_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys); +int _PyEval_UnpackIterable(PyThreadState *tstate, PyObject *v, int argcnt, int argcntafter, PyObject **sp); +void _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame); + + +#define _PY_GIL_DROP_REQUEST_BIT 0 +#define _PY_SIGNALS_PENDING_BIT 1 +#define _PY_CALLS_TO_DO_BIT 2 +#define _PY_ASYNC_EXCEPTION_BIT 3 +#define _PY_GC_SCHEDULED_BIT 4 + +/* Reserve a few bits for future use */ +#define _PY_EVAL_EVENTS_BITS 8 +#define _PY_EVAL_EVENTS_MASK ((1 << _PY_EVAL_EVENTS_BITS)-1) + +static inline void +_Py_set_eval_breaker_bit(PyInterpreterState *interp, uint32_t bit, uint32_t set) +{ + assert(set == 0 || set == 1); + uintptr_t to_set = set << bit; + uintptr_t mask = ((uintptr_t)1) << bit; + uintptr_t old = _Py_atomic_load_uintptr(&interp->ceval.eval_breaker); + if ((old & mask) == to_set) { + return; + } + uintptr_t new; + do { + new = (old & ~mask) | to_set; + } while (!_Py_atomic_compare_exchange_uintptr(&interp->ceval.eval_breaker, &old, new)); +} + +static inline bool +_Py_eval_breaker_bit_is_set(PyInterpreterState *interp, int32_t bit) +{ + return _Py_atomic_load_uintptr_relaxed(&interp->ceval.eval_breaker) & (((uintptr_t)1) << bit); +} + #ifdef __cplusplus } diff --git a/Include/internal/pycore_ceval_state.h b/Include/internal/pycore_ceval_state.h index e56e43c6e0c6a7..1717ec4f41c36b 100644 --- a/Include/internal/pycore_ceval_state.h +++ b/Include/internal/pycore_ceval_state.h @@ -8,24 +8,21 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif - -#include "pycore_atomic.h" /* _Py_atomic_address */ #include "pycore_gil.h" // struct _gil_runtime_state +typedef int (*_Py_pending_call_func)(void *); + struct _pending_calls { int busy; PyThread_type_lock lock; /* Request for running pending calls. */ - _Py_atomic_int calls_to_do; - /* Request for looking at the `async_exc` field of the current - thread state. - Guarded by the GIL. */ - int async_exc; + int32_t calls_to_do; #define NPENDINGCALLS 32 struct _pending_call { - int (*func)(void *); + _Py_pending_call_func func; void *arg; + int flags; } calls[NPENDINGCALLS]; int first; int last; @@ -62,11 +59,6 @@ struct _ceval_runtime_state { int _not_used; #endif } perf; - /* Request for checking signals. It is shared by all interpreters (see - bpo-40513). Any thread of any interpreter can receive a signal, but only - the main thread of the main interpreter can handle signals: see - _Py_ThreadCanHandleSignals(). */ - _Py_atomic_int signals_pending; /* Pending calls to be made only on the main thread. */ struct _pending_calls pending_mainthread; }; @@ -84,15 +76,15 @@ struct _ceval_runtime_state { struct _ceval_state { /* This single variable consolidates all requests to break out of - the fast path in the eval loop. */ - _Py_atomic_int eval_breaker; - /* Request for dropping the GIL */ - _Py_atomic_int gil_drop_request; + * the fast path in the eval loop. + * It is by far the hottest field in this struct and + * should be placed at the beginning. */ + uintptr_t eval_breaker; + /* Avoid false sharing */ + int64_t padding[7]; int recursion_limit; struct _gil_runtime_state *gil; int own_gil; - /* The GC is ready to be executed */ - _Py_atomic_int gc_scheduled; struct _pending_calls pending; }; diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index b6b1aeca6e5c5f..d31d8363d771ca 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -4,6 +4,10 @@ extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + #define CODE_MAX_WATCHERS 8 /* PEP 659 @@ -203,8 +207,8 @@ struct _PyCodeConstructor { // back to a regular function signature. Regardless, this approach // wouldn't be appropriate if this weren't a strictly internal API. // (See the comments in https://github.com/python/cpython/pull/26258.) -PyAPI_FUNC(int) _PyCode_Validate(struct _PyCodeConstructor *); -PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *); +extern int _PyCode_Validate(struct _PyCodeConstructor *); +extern PyCodeObject* _PyCode_New(struct _PyCodeConstructor *); /* Private API */ @@ -229,6 +233,11 @@ extern void _PyLineTable_InitAddressRange( extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range); extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); +/** API for executors */ +extern void _PyCode_Clear_Executors(PyCodeObject *code); + +#define ENABLE_SPECIALIZATION 1 + /* Specialization functions */ extern void _Py_Specialize_LoadSuperAttr(PyObject *global_super, PyObject *cls, @@ -244,7 +253,7 @@ extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames); + int nargs); extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg, PyObject **locals); extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, @@ -262,19 +271,30 @@ extern int _PyStaticCode_Init(PyCodeObject *co); #ifdef Py_STATS - -#define STAT_INC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name++; } while (0) -#define STAT_DEC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name--; } while (0) -#define OPCODE_EXE_INC(opname) do { if (_py_stats) _py_stats->opcode_stats[opname].execution_count++; } while (0) -#define CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.name++; } while (0) -#define OBJECT_STAT_INC(name) do { if (_py_stats) _py_stats->object_stats.name++; } while (0) +#define STAT_INC(opname, name) do { if (_Py_stats) _Py_stats->opcode_stats[opname].specialization.name++; } while (0) +#define STAT_DEC(opname, name) do { if (_Py_stats) _Py_stats->opcode_stats[opname].specialization.name--; } while (0) +#define OPCODE_EXE_INC(opname) do { if (_Py_stats) _Py_stats->opcode_stats[opname].execution_count++; } while (0) +#define CALL_STAT_INC(name) do { if (_Py_stats) _Py_stats->call_stats.name++; } while (0) +#define OBJECT_STAT_INC(name) do { if (_Py_stats) _Py_stats->object_stats.name++; } while (0) #define OBJECT_STAT_INC_COND(name, cond) \ - do { if (_py_stats && cond) _py_stats->object_stats.name++; } while (0) -#define EVAL_CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.eval_calls[name]++; } while (0) + do { if (_Py_stats && cond) _Py_stats->object_stats.name++; } while (0) +#define EVAL_CALL_STAT_INC(name) do { if (_Py_stats) _Py_stats->call_stats.eval_calls[name]++; } while (0) #define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) \ - do { if (_py_stats && PyFunction_Check(callable)) _py_stats->call_stats.eval_calls[name]++; } while (0) - -// Used by the _opcode extension which is built as a shared library + do { if (_Py_stats && PyFunction_Check(callable)) _Py_stats->call_stats.eval_calls[name]++; } while (0) +#define GC_STAT_ADD(gen, name, n) do { if (_Py_stats) _Py_stats->gc_stats[(gen)].name += (n); } while (0) +#define OPT_STAT_INC(name) do { if (_Py_stats) _Py_stats->optimization_stats.name++; } while (0) +#define UOP_EXE_INC(opname) do { if (_Py_stats) _Py_stats->optimization_stats.opcode[opname].execution_count++; } while (0) +#define OPT_UNSUPPORTED_OPCODE(opname) do { if (_Py_stats) _Py_stats->optimization_stats.unsupported_opcode[opname]++; } while (0) +#define OPT_HIST(length, name) \ + do { \ + if (_Py_stats) { \ + int bucket = _Py_bit_length(length >= 1 ? length - 1 : 0); \ + bucket = (bucket >= _Py_UOP_HIST_SIZE) ? _Py_UOP_HIST_SIZE - 1 : bucket; \ + _Py_stats->optimization_stats.name[bucket]++; \ + } \ + } while (0) + +// Export for '_opcode' shared extension PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #else @@ -286,6 +306,11 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #define OBJECT_STAT_INC_COND(name, cond) ((void)0) #define EVAL_CALL_STAT_INC(name) ((void)0) #define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) ((void)0) +#define GC_STAT_ADD(gen, name, n) ((void)0) +#define OPT_STAT_INC(name) ((void)0) +#define UOP_EXE_INC(opname) ((void)0) +#define OPT_UNSUPPORTED_OPCODE(opname) ((void)0) +#define OPT_HIST(length, name) ((void)0) #endif // !Py_STATS // Utility functions for reading/writing 32/64-bit values in the inline caches. @@ -455,8 +480,6 @@ adaptive_counter_backoff(uint16_t counter) { return adaptive_counter_bits(value, backoff); } -extern uint32_t _Py_next_func_version; - /* Comparison bit masks. */ diff --git a/Include/internal/pycore_codecs.h b/Include/internal/pycore_codecs.h index a2465192eacd5e..a2a7151d50ade7 100644 --- a/Include/internal/pycore_codecs.h +++ b/Include/internal/pycore_codecs.h @@ -4,6 +4,10 @@ extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + extern PyObject* _PyCodec_Lookup(const char *encoding); /* Text codec specific encoding and decoding API. diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h index beb37cced06dba..a5a7146f5ee917 100644 --- a/Include/internal/pycore_compile.h +++ b/Include/internal/pycore_compile.h @@ -11,7 +11,7 @@ extern "C" { struct _arena; // Type defined in pycore_pyarena.h struct _mod; // Type defined in pycore_ast.h -// Export the symbol for test_peg_generator (built as a library) +// Export for 'test_peg_generator' shared extension PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( struct _mod *mod, PyObject *filename, @@ -19,6 +19,14 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( int optimize, struct _arena *arena); +/* AST optimizations */ +extern int _PyCompile_AstOptimize( + struct _mod *mod, + PyObject *filename, + PyCompilerFlags *flags, + int optimize, + struct _arena *arena); + static const _PyCompilerSrcLocation NO_LOCATION = {-1, -1, -1, -1}; extern int _PyAST_Optimize( @@ -54,6 +62,11 @@ typedef struct { int s_next_free_label; /* next free label id */ } _PyCompile_InstructionSequence; +int _PyCompile_InstructionSequence_UseLabel(_PyCompile_InstructionSequence *seq, int lbl); +int _PyCompile_InstructionSequence_Addop(_PyCompile_InstructionSequence *seq, + int opcode, int oparg, + _PyCompilerSrcLocation loc); + typedef struct { PyObject *u_name; PyObject *u_qualname; /* dot-separated qualified name (lazy) */ @@ -91,8 +104,10 @@ int _PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj); /* Access compiler internals for unit testing */ +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(PyObject*) _PyCompile_CleanDoc(PyObject *doc); +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(PyObject*) _PyCompile_CodeGen( PyObject *ast, PyObject *filename, @@ -100,11 +115,13 @@ PyAPI_FUNC(PyObject*) _PyCompile_CodeGen( int optimize, int compile_mode); +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(PyObject*) _PyCompile_OptimizeCfg( PyObject *instructions, PyObject *consts, int nlocals); +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(PyCodeObject*) _PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename, PyObject *instructions); diff --git a/Include/internal/pycore_complexobject.h b/Include/internal/pycore_complexobject.h index 7843c0a008ebb6..a6fee9d23f3a9f 100644 --- a/Include/internal/pycore_complexobject.h +++ b/Include/internal/pycore_complexobject.h @@ -10,8 +10,8 @@ extern "C" { #include "pycore_unicodeobject.h" // _PyUnicodeWriter -/* Operations on complex numbers from complexmodule.c */ - +// Operations on complex numbers. +// Export functions for 'cmath' shared extension. PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); diff --git a/Include/internal/pycore_condvar.h b/Include/internal/pycore_condvar.h index 981c962bf7dfdf..34c21aaad43197 100644 --- a/Include/internal/pycore_condvar.h +++ b/Include/internal/pycore_condvar.h @@ -5,14 +5,8 @@ # error "this header requires Py_BUILD_CORE define" #endif -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include /* _POSIX_THREADS */ -# endif -#endif +#include "pycore_pythread.h" // _POSIX_THREADS + #ifdef _POSIX_THREADS /* @@ -21,7 +15,7 @@ #define Py_HAVE_CONDVAR #ifdef HAVE_PTHREAD_H -# include +# include // pthread_mutex_t #endif #define PyMUTEX_T pthread_mutex_t @@ -38,7 +32,7 @@ /* include windows if it hasn't been done before */ #define WIN32_LEAN_AND_MEAN -#include +#include // CRITICAL_SECTION /* options */ /* non-emulated condition variables are provided for those that want diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h index 52dfe3ef233874..ec884e9e0f55a9 100644 --- a/Include/internal/pycore_context.h +++ b/Include/internal/pycore_context.h @@ -5,7 +5,7 @@ # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_hamt.h" /* PyHamtObject */ +#include "pycore_hamt.h" // PyHamtObject extern PyTypeObject _PyContextTokenMissing_Type; @@ -68,4 +68,9 @@ struct _pycontexttokenobject { }; +// _testinternalcapi.hamt() used by tests. +// Export for '_testcapi' shared extension +PyAPI_FUNC(PyObject*) _PyContext_NewHamtForTests(void); + + #endif /* !Py_INTERNAL_CONTEXT_H */ diff --git a/Include/internal/pycore_descrobject.h b/Include/internal/pycore_descrobject.h index 76378569df90e3..3cec59a68a3d2b 100644 --- a/Include/internal/pycore_descrobject.h +++ b/Include/internal/pycore_descrobject.h @@ -20,6 +20,8 @@ typedef struct { typedef propertyobject _PyPropertyObject; +extern PyTypeObject _PyMethodWrapper_Type; + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 6253e0841ad349..47b5948f66343a 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -9,8 +9,70 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_dict_state.h" -#include "pycore_runtime.h" // _PyRuntime +#include "pycore_identifier.h" // _Py_Identifier +#include "pycore_object.h" // PyDictOrValues + +// Unsafe flavor of PyDict_GetItemWithError(): no error checking +extern PyObject* _PyDict_GetItemWithError(PyObject *dp, PyObject *key); + +extern int _PyDict_DelItemIf(PyObject *mp, PyObject *key, + int (*predicate)(PyObject *value)); + +// "KnownHash" variants +// Export for '_testinternalcapi' shared extension +PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +// Export for '_asyncio' shared extension +PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, + PyObject *item, Py_hash_t hash); +// Export for '_asyncio' shared extension +PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +extern int _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); + +// "Id" variants +extern PyObject* _PyDict_GetItemIdWithError(PyObject *dp, + _Py_Identifier *key); +extern int _PyDict_ContainsId(PyObject *, _Py_Identifier *); +extern int _PyDict_SetItemId(PyObject *dp, _Py_Identifier *key, PyObject *item); +extern int _PyDict_DelItemId(PyObject *mp, _Py_Identifier *key); + +extern int _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); + +extern int _PyDict_HasOnlyStringKeys(PyObject *mp); + +extern void _PyDict_MaybeUntrack(PyObject *mp); + +extern PyObject* _PyDict_NewPresized(Py_ssize_t minused); + +// Export for '_ctypes' shared extension +PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); + +// Export for '_socket' shared extension (Windows remove_unusable_flags()) +PyAPI_FUNC(PyObject*) _PyDict_Pop(PyObject *, PyObject *, PyObject *); + +#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) + +/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0, + the first occurrence of a key wins, if override is 1, the last occurrence + of a key wins, if override is 2, a KeyError with conflicting key as + argument is raised. +*/ +extern int _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); + +extern void _PyDict_DebugMallocStats(FILE *out); + + +/* _PyDictView */ + +typedef struct { + PyObject_HEAD + PyDictObject *dv_dict; +} _PyDictViewObject; + +extern PyObject* _PyDictView_New(PyObject *, PyTypeObject *); +extern PyObject* _PyDictView_Intersect(PyObject* self, PyObject *other); /* runtime lifecycle */ @@ -42,6 +104,8 @@ extern uint32_t _PyDictKeys_GetVersionForCurrentState( extern size_t _PyDict_KeysSize(PyDictKeysObject *keys); +extern void _PyDictKeys_DecRef(PyDictKeysObject *keys); + /* _Py_dict_lookup() returns index of entry which can be used like DK_ENTRIES(dk)[index]. * -1 when no entry found, -3 when compare raises error. */ @@ -176,6 +240,7 @@ _PyDict_NotifyEvent(PyInterpreterState *interp, } extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values); +extern bool _PyObject_MakeInstanceAttributesFromDict(PyObject *obj, PyDictOrValues *dorv); extern PyObject *_PyDict_FromItems( PyObject *const *keys, Py_ssize_t keys_offset, PyObject *const *values, Py_ssize_t values_offset, diff --git a/Include/internal/pycore_dtoa.h b/Include/internal/pycore_dtoa.h index 4d9681d59a64f7..ac62a4d300720a 100644 --- a/Include/internal/pycore_dtoa.h +++ b/Include/internal/pycore_dtoa.h @@ -60,10 +60,10 @@ struct _dtoa_state { /* These functions are used by modules compiled as C extension like math: they must be exported. */ -PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); -PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); -PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); +extern double _Py_dg_strtod(const char *str, char **ptr); +extern char* _Py_dg_dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +extern void _Py_dg_freedtoa(char *s); #endif // _PY_SHORT_FLOAT_REPR == 1 diff --git a/Include/internal/pycore_emscripten_signal.h b/Include/internal/pycore_emscripten_signal.h index 8b3287d85da4b2..754193e21dec5a 100644 --- a/Include/internal/pycore_emscripten_signal.h +++ b/Include/internal/pycore_emscripten_signal.h @@ -3,6 +3,10 @@ #if defined(__EMSCRIPTEN__) +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + void _Py_CheckEmscriptenSignals(void); @@ -14,6 +18,7 @@ _Py_CheckEmscriptenSignalsPeriodically(void); #define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY() _Py_CheckEmscriptenSignalsPeriodically() extern int Py_EMSCRIPTEN_SIGNAL_HANDLING; +extern int _Py_emscripten_signal_clock; #else diff --git a/Include/internal/pycore_emscripten_trampoline.h b/Include/internal/pycore_emscripten_trampoline.h new file mode 100644 index 00000000000000..e519c99ad86cce --- /dev/null +++ b/Include/internal/pycore_emscripten_trampoline.h @@ -0,0 +1,81 @@ +#ifndef Py_EMSCRIPTEN_TRAMPOLINE_H +#define Py_EMSCRIPTEN_TRAMPOLINE_H + +#include "pycore_runtime.h" // _PyRuntimeState + +/** + * C function call trampolines to mitigate bad function pointer casts. + * + * Section 6.3.2.3, paragraph 8 reads: + * + * A pointer to a function of one type may be converted to a pointer to a + * function of another type and back again; the result shall compare equal to + * the original pointer. If a converted pointer is used to call a function + * whose type is not compatible with the pointed-to type, the behavior is + * undefined. + * + * Typical native ABIs ignore additional arguments or fill in missing values + * with 0/NULL in function pointer cast. Compilers do not show warnings when a + * function pointer is explicitly casted to an incompatible type. + * + * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict + * function signature checks. Argument count, types, and return type must match. + * + * Third party code unintentionally rely on problematic fpcasts. The call + * trampoline mitigates common occurrences of bad fpcasts on Emscripten. + */ + +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) + +void _Py_EmscriptenTrampoline_Init(_PyRuntimeState *runtime); + +PyObject* +_PyEM_TrampolineCall_JavaScript(PyCFunctionWithKeywords func, + PyObject* self, + PyObject* args, + PyObject* kw); + +PyObject* +_PyEM_TrampolineCall_Reflection(PyCFunctionWithKeywords func, + PyObject* self, + PyObject* args, + PyObject* kw); + +#define _PyEM_TrampolineCall(meth, self, args, kw) \ + ((_PyRuntime.wasm_type_reflection_available) ? \ + (_PyEM_TrampolineCall_Reflection((PyCFunctionWithKeywords)(meth), (self), (args), (kw))) : \ + (_PyEM_TrampolineCall_JavaScript((PyCFunctionWithKeywords)(meth), (self), (args), (kw)))) + +#define _PyCFunction_TrampolineCall(meth, self, args) \ + _PyEM_TrampolineCall( \ + (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL) + +#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \ + _PyEM_TrampolineCall((meth), (self), (args), (kw)) + +#define descr_set_trampoline_call(set, obj, value, closure) \ + ((int)_PyEM_TrampolineCall((PyCFunctionWithKeywords)(set), (obj), (value), (PyObject*)(closure))) + +#define descr_get_trampoline_call(get, obj, closure) \ + _PyEM_TrampolineCall((PyCFunctionWithKeywords)(get), (obj), (PyObject*)(closure), NULL) + + +#else // defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) + +#define _Py_EmscriptenTrampoline_Init(runtime) + +#define _PyCFunction_TrampolineCall(meth, self, args) \ + (meth)((self), (args)) + +#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \ + (meth)((self), (args), (kw)) + +#define descr_set_trampoline_call(set, obj, value, closure) \ + (set)((obj), (value), (closure)) + +#define descr_get_trampoline_call(get, obj, closure) \ + (get)((obj), (closure)) + +#endif // defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) + +#endif // ndef Py_EMSCRIPTEN_SIGNAL_H diff --git a/Include/internal/pycore_faulthandler.h b/Include/internal/pycore_faulthandler.h index e6aec7745a6479..6dd7d8d7ca9792 100644 --- a/Include/internal/pycore_faulthandler.h +++ b/Include/internal/pycore_faulthandler.h @@ -9,7 +9,7 @@ extern "C" { #endif #ifdef HAVE_SIGACTION -# include +# include // sigaction #endif diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h index ef6642d00f1b54..2f89da2c6ecd91 100644 --- a/Include/internal/pycore_fileutils.h +++ b/Include/internal/pycore_fileutils.h @@ -5,12 +5,20 @@ extern "C" { #endif #ifndef Py_BUILD_CORE -# error "Py_BUILD_CORE must be defined to include this header" +# error "this header requires Py_BUILD_CORE define" #endif -#include /* struct lconv */ +#include // struct lconv +/* A routine to check if a file descriptor can be select()-ed. */ +#ifdef _MSC_VER + /* On Windows, any socket fd can be select()-ed, no matter how high */ + #define _PyIsSelectable_fd(FD) (1) +#else + #define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE) +#endif + struct _fileutils_state { int force_ascii; }; @@ -27,8 +35,10 @@ typedef enum { _Py_ERROR_OTHER } _Py_error_handler; +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors); +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(int) _Py_DecodeLocaleEx( const char *arg, wchar_t **wstr, @@ -37,6 +47,7 @@ PyAPI_FUNC(int) _Py_DecodeLocaleEx( int current_locale, _Py_error_handler errors); +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(int) _Py_EncodeLocaleEx( const wchar_t *text, char **str, @@ -45,11 +56,11 @@ PyAPI_FUNC(int) _Py_EncodeLocaleEx( int current_locale, _Py_error_handler errors); -PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( +extern char* _Py_EncodeLocaleRaw( const wchar_t *text, size_t *error_pos); -PyAPI_FUNC(PyObject *) _Py_device_encoding(int); +extern PyObject* _Py_device_encoding(int); #if defined(MS_WINDOWS) || defined(__APPLE__) /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611). @@ -90,47 +101,54 @@ struct _Py_stat_struct { # define _Py_stat_struct stat #endif +// Export for 'mmap' shared extension PyAPI_FUNC(int) _Py_fstat( int fd, struct _Py_stat_struct *status); +// Export for 'mmap' shared extension PyAPI_FUNC(int) _Py_fstat_noraise( int fd, struct _Py_stat_struct *status); +// Export for '_tkinter' shared extension PyAPI_FUNC(int) _Py_stat( PyObject *path, struct stat *status); +// Export for 'select' shared extension (Solaris newDevPollObject()) PyAPI_FUNC(int) _Py_open( const char *pathname, int flags); +// Export for '_posixsubprocess' shared extension PyAPI_FUNC(int) _Py_open_noraise( const char *pathname, int flags); -PyAPI_FUNC(FILE *) _Py_wfopen( +extern FILE* _Py_wfopen( const wchar_t *path, const wchar_t *mode); -PyAPI_FUNC(Py_ssize_t) _Py_read( +extern Py_ssize_t _Py_read( int fd, void *buf, size_t count); +// Export for 'select' shared extension (Solaris devpoll_flush()) PyAPI_FUNC(Py_ssize_t) _Py_write( int fd, const void *buf, size_t count); +// Export for '_posixsubprocess' shared extension PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( int fd, const void *buf, size_t count); #ifdef HAVE_READLINK -PyAPI_FUNC(int) _Py_wreadlink( +extern int _Py_wreadlink( const wchar_t *path, wchar_t *buf, /* Number of characters of 'buf' buffer @@ -139,7 +157,7 @@ PyAPI_FUNC(int) _Py_wreadlink( #endif #ifdef HAVE_REALPATH -PyAPI_FUNC(wchar_t*) _Py_wrealpath( +extern wchar_t* _Py_wrealpath( const wchar_t *path, wchar_t *resolved_path, /* Number of characters of 'resolved_path' buffer @@ -147,34 +165,38 @@ PyAPI_FUNC(wchar_t*) _Py_wrealpath( size_t resolved_path_len); #endif -PyAPI_FUNC(wchar_t*) _Py_wgetcwd( +extern wchar_t* _Py_wgetcwd( wchar_t *buf, /* Number of characters of 'buf' buffer including the trailing NUL character */ size_t buflen); -PyAPI_FUNC(int) _Py_get_inheritable(int fd); +extern int _Py_get_inheritable(int fd); +// Export for '_socket' shared extension PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works); +// Export for '_posixsubprocess' shared extension PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, int *atomic_flag_works); +// Export for '_socket' shared extension PyAPI_FUNC(int) _Py_dup(int fd); -PyAPI_FUNC(int) _Py_get_blocking(int fd); +extern int _Py_get_blocking(int fd); -PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); +extern int _Py_set_blocking(int fd, int blocking); #ifdef MS_WINDOWS -PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd); +extern void* _Py_get_osfhandle_noraise(int fd); +// Export for '_testconsole' shared extension PyAPI_FUNC(void*) _Py_get_osfhandle(int fd); -PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags); +extern int _Py_open_osfhandle_noraise(void *handle, int flags); -PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags); +extern int _Py_open_osfhandle(void *handle, int flags); #endif /* MS_WINDOWS */ // This is used after getting NULL back from Py_DecodeLocale(). @@ -183,9 +205,9 @@ PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags); ? _PyStatus_ERR("cannot decode " NAME) \ : _PyStatus_NO_MEMORY() -PyAPI_DATA(int) _Py_HasFileSystemDefaultEncodeErrors; +extern int _Py_HasFileSystemDefaultEncodeErrors; -PyAPI_FUNC(int) _Py_DecodeUTF8Ex( +extern int _Py_DecodeUTF8Ex( const char *arg, Py_ssize_t arglen, wchar_t **wstr, @@ -193,7 +215,7 @@ PyAPI_FUNC(int) _Py_DecodeUTF8Ex( const char **reason, _Py_error_handler errors); -PyAPI_FUNC(int) _Py_EncodeUTF8Ex( +extern int _Py_EncodeUTF8Ex( const wchar_t *text, char **str, size_t *error_pos, @@ -201,7 +223,7 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex( int raw_malloc, _Py_error_handler errors); -PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape( +extern wchar_t* _Py_DecodeUTF8_surrogateescape( const char *arg, Py_ssize_t arglen, size_t *wlen); @@ -209,25 +231,26 @@ PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape( extern int _Py_wstat(const wchar_t *, struct stat *); -PyAPI_FUNC(int) _Py_GetForceASCII(void); +extern int _Py_GetForceASCII(void); /* Reset "force ASCII" mode (if it was initialized). This function should be called when Python changes the LC_CTYPE locale, so the "force ASCII" mode can be detected again on the new locale encoding. */ -PyAPI_FUNC(void) _Py_ResetForceASCII(void); +extern void _Py_ResetForceASCII(void); -PyAPI_FUNC(int) _Py_GetLocaleconvNumeric( +extern int _Py_GetLocaleconvNumeric( struct lconv *lc, PyObject **decimal_point, PyObject **thousands_sep); +// Export for '_posixsubprocess' (on macOS) PyAPI_FUNC(void) _Py_closerange(int first, int last); -PyAPI_FUNC(wchar_t*) _Py_GetLocaleEncoding(void); -PyAPI_FUNC(PyObject*) _Py_GetLocaleEncodingObject(void); +extern wchar_t* _Py_GetLocaleEncoding(void); +extern PyObject* _Py_GetLocaleEncodingObject(void); #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION extern int _Py_LocaleUsesNonUnicodeWchar(void); @@ -246,19 +269,23 @@ extern int _Py_abspath(const wchar_t *path, wchar_t **abspath_p); #ifdef MS_WINDOWS extern int _PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p); #endif -extern wchar_t * _Py_join_relfile(const wchar_t *dirname, - const wchar_t *relfile); +extern wchar_t* _Py_join_relfile(const wchar_t *dirname, + const wchar_t *relfile); extern int _Py_add_relfile(wchar_t *dirname, const wchar_t *relfile, size_t bufsize); extern size_t _Py_find_basename(const wchar_t *filename); -PyAPI_FUNC(wchar_t *) _Py_normpath(wchar_t *path, Py_ssize_t size); + +// Export for '_testinternalcapi' shared extension +PyAPI_FUNC(wchar_t*) _Py_normpath(wchar_t *path, Py_ssize_t size); + +extern wchar_t *_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *length); // The Windows Games API family does not provide these functions // so provide our own implementations. Remove them in case they get added // to the Games API family #if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) -#include +#include // HRESULT extern HRESULT PathCchSkipRoot(const wchar_t *pszPath, const wchar_t **ppszRootEnd); #endif /* defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) */ @@ -285,6 +312,14 @@ extern HRESULT PathCchSkipRoot(const wchar_t *pszPath, const wchar_t **ppszRootE # define _Py_END_SUPPRESS_IPH #endif /* _MSC_VER >= 1900 */ +// Export for 'select' shared extension (Argument Clinic code) +PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *); + +// Export for test_peg_generator +PyAPI_FUNC(char*) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject *, size_t*); + +extern int _PyFile_Flush(PyObject *); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_fileutils_windows.h b/Include/internal/pycore_fileutils_windows.h index e804d385e76708..b79aa9fb465376 100644 --- a/Include/internal/pycore_fileutils_windows.h +++ b/Include/internal/pycore_fileutils_windows.h @@ -5,7 +5,7 @@ extern "C" { #endif #ifndef Py_BUILD_CORE -# error "Py_BUILD_CORE must be defined to include this header" +# error "this header requires Py_BUILD_CORE define" #endif #ifdef MS_WINDOWS diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h index 6abba04033d281..4e5474841bc25d 100644 --- a/Include/internal/pycore_floatobject.h +++ b/Include/internal/pycore_floatobject.h @@ -55,18 +55,25 @@ struct _Py_float_state { void _PyFloat_ExactDealloc(PyObject *op); -PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); +extern void _PyFloat_DebugMallocStats(FILE* out); /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ -PyAPI_FUNC(int) _PyFloat_FormatAdvancedWriter( +extern int _PyFloat_FormatAdvancedWriter( _PyUnicodeWriter *writer, PyObject *obj, PyObject *format_spec, Py_ssize_t start, Py_ssize_t end); +extern PyObject* _Py_string_to_number_with_underscores( + const char *str, Py_ssize_t len, const char *what, PyObject *obj, void *arg, + PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)); + +extern double _Py_parse_inf_or_nan(const char *p, char **endptr); + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_flowgraph.h b/Include/internal/pycore_flowgraph.h index 4a01574809fff5..58fed46886ea45 100644 --- a/Include/internal/pycore_flowgraph.h +++ b/Include/internal/pycore_flowgraph.h @@ -11,101 +11,26 @@ extern "C" { #include "pycore_opcode_utils.h" #include "pycore_compile.h" - -typedef struct { - int i_opcode; - int i_oparg; - _PyCompilerSrcLocation i_loc; - struct _PyCfgBasicblock_ *i_target; /* target block (if jump instruction) */ - struct _PyCfgBasicblock_ *i_except; /* target block when exception is raised */ -} _PyCfgInstruction; - typedef struct { int id; } _PyCfgJumpTargetLabel; +struct _PyCfgBuilder; -typedef struct { - struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+1]; - int depth; -} _PyCfgExceptStack; - -typedef struct _PyCfgBasicblock_ { - /* Each basicblock in a compilation unit is linked via b_list in the - reverse order that the block are allocated. b_list points to the next - block in this list, not to be confused with b_next, which is next by - control flow. */ - struct _PyCfgBasicblock_ *b_list; - /* The label of this block if it is a jump target, -1 otherwise */ - _PyCfgJumpTargetLabel b_label; - /* Exception stack at start of block, used by assembler to create the exception handling table */ - _PyCfgExceptStack *b_exceptstack; - /* pointer to an array of instructions, initially NULL */ - _PyCfgInstruction *b_instr; - /* If b_next is non-NULL, it is a pointer to the next - block reached by normal control flow. */ - struct _PyCfgBasicblock_ *b_next; - /* number of instructions used */ - int b_iused; - /* length of instruction array (b_instr) */ - int b_ialloc; - /* Used by add_checks_for_loads_of_unknown_variables */ - uint64_t b_unsafe_locals_mask; - /* Number of predecessors that a block has. */ - int b_predecessors; - /* depth of stack upon entry of block, computed by stackdepth() */ - int b_startdepth; - /* Basic block is an exception handler that preserves lasti */ - unsigned b_preserve_lasti : 1; - /* Used by compiler passes to mark whether they have visited a basic block. */ - unsigned b_visited : 1; - /* b_except_handler is used by the cold-detection algorithm to mark exception targets */ - unsigned b_except_handler : 1; - /* b_cold is true if this block is not perf critical (like an exception handler) */ - unsigned b_cold : 1; - /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */ - unsigned b_warm : 1; -} _PyCfgBasicblock; - -int _PyBasicblock_InsertInstruction(_PyCfgBasicblock *block, int pos, _PyCfgInstruction *instr); +int _PyCfgBuilder_UseLabel(struct _PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl); +int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc); -typedef struct cfg_builder_ { - /* The entryblock, at which control flow begins. All blocks of the - CFG are reachable through the b_next links */ - _PyCfgBasicblock *g_entryblock; - /* Pointer to the most recently allocated block. By following - b_list links, you can reach all allocated blocks. */ - _PyCfgBasicblock *g_block_list; - /* pointer to the block currently being constructed */ - _PyCfgBasicblock *g_curblock; - /* label for the next instruction to be placed */ - _PyCfgJumpTargetLabel g_current_label; -} _PyCfgBuilder; +struct _PyCfgBuilder* _PyCfgBuilder_New(void); +void _PyCfgBuilder_Free(struct _PyCfgBuilder *g); +int _PyCfgBuilder_CheckSize(struct _PyCfgBuilder* g); -int _PyCfgBuilder_UseLabel(_PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl); -int _PyCfgBuilder_Addop(_PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc); - -int _PyCfgBuilder_Init(_PyCfgBuilder *g); -void _PyCfgBuilder_Fini(_PyCfgBuilder *g); - -_PyCfgInstruction* _PyCfg_BasicblockLastInstr(const _PyCfgBasicblock *b); -int _PyCfg_OptimizeCodeUnit(_PyCfgBuilder *g, PyObject *consts, PyObject *const_cache, - int code_flags, int nlocals, int nparams, int firstlineno); -int _PyCfg_Stackdepth(_PyCfgBasicblock *entryblock, int code_flags); -void _PyCfg_ConvertPseudoOps(_PyCfgBasicblock *entryblock); -int _PyCfg_ResolveJumps(_PyCfgBuilder *g); - - -static inline int -basicblock_nofallthrough(const _PyCfgBasicblock *b) { - _PyCfgInstruction *last = _PyCfg_BasicblockLastInstr(b); - return (last && - (IS_SCOPE_EXIT_OPCODE(last->i_opcode) || - IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode))); -} +int _PyCfg_OptimizeCodeUnit(struct _PyCfgBuilder *g, PyObject *consts, PyObject *const_cache, + int nlocals, int nparams, int firstlineno); -#define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B)) -#define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B)) +int _PyCfg_ToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_InstructionSequence *seq); +int _PyCfg_OptimizedCfgToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_CodeUnitMetadata *umd, + int code_flags, int *stackdepth, int *nlocalsplus, + _PyCompile_InstructionSequence *seq); PyCodeObject * _PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *u, PyObject *const_cache, diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index efc19e33ec5dc5..bd448272e058ab 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -4,9 +4,13 @@ extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + #include -#include -#include "pycore_code.h" // STATS +#include // offsetof() +#include "pycore_code.h" // STATS /* See Objects/frame_layout.md for an explanation of the frame stack * including explanation of the PyFrameObject and _PyInterpreterFrame @@ -196,7 +200,7 @@ _PyFrame_GetFirstComplete(_PyInterpreterFrame *frame) static inline _PyInterpreterFrame * _PyThreadState_GetFrame(PyThreadState *tstate) { - return _PyFrame_GetFirstComplete(tstate->cframe->current_frame); + return _PyFrame_GetFirstComplete(tstate->current_frame); } /* For use by _PyFrame_GetFrameObject @@ -278,7 +282,7 @@ _PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_l /* Pushes a trampoline frame without checking for space. * Must be guarded by _PyThreadState_HasStackSpace() */ static inline _PyInterpreterFrame * -_PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int stackdepth, int prev_instr) +_PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int stackdepth) { CALL_STAT_INC(frames_pushed); _PyInterpreterFrame *frame = (_PyInterpreterFrame *)tstate->datastack_top; @@ -293,7 +297,7 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int frame->f_locals = NULL; frame->stacktop = code->co_nlocalsplus + stackdepth; frame->frame_obj = NULL; - frame->prev_instr = _PyCode_CODE(code) + prev_instr; + frame->prev_instr = _PyCode_CODE(code); frame->owner = FRAME_OWNED_BY_THREAD; frame->return_offset = 0; return frame; @@ -307,14 +311,6 @@ PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) return (PyGenObject *)(((char *)frame) - offset_in_gen); } -#define PY_EXECUTABLE_KIND_SKIP 0 -#define PY_EXECUTABLE_KIND_PY_FUNCTION 1 -#define PY_EXECUTABLE_KIND_BUILTIN_FUNCTION 3 -#define PY_EXECUTABLE_KIND_METHOD_DESCRIPTOR 4 -#define PY_EXECUTABLE_KINDS 5 - -PyAPI_DATA(const PyTypeObject *) const PyUnstable_ExecutableKinds[PY_EXECUTABLE_KINDS+1]; - #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_function.h b/Include/internal/pycore_function.h index ecbb7001e7d840..3f3da8a44b77e4 100644 --- a/Include/internal/pycore_function.h +++ b/Include/internal/pycore_function.h @@ -8,15 +8,30 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +extern PyObject* _PyFunction_Vectorcall( + PyObject *func, + PyObject *const *stack, + size_t nargsf, + PyObject *kwnames); + #define FUNC_MAX_WATCHERS 8 +#define FUNC_VERSION_CACHE_SIZE (1<<12) /* Must be a power of 2 */ struct _py_func_state { uint32_t next_version; + // Borrowed references to function objects whose + // func_version % FUNC_VERSION_CACHE_SIZE + // once was equal to the index in the table. + // They are cleared when the function is deallocated. + PyFunctionObject *func_version_cache[FUNC_VERSION_CACHE_SIZE]; }; extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr); extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); +extern void _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version); +PyFunctionObject *_PyFunction_LookupByVersion(uint32_t version); + extern PyObject *_Py_set_function_type_params( PyThreadState* unused, PyObject *func, PyObject *type_params); diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h index dc60b4ca705112..cf58a2750a31f9 100644 --- a/Include/internal/pycore_genobject.h +++ b/Include/internal/pycore_genobject.h @@ -9,9 +9,21 @@ extern "C" { #endif extern PyObject *_PyGen_yf(PyGenObject *); +extern void _PyGen_Finalize(PyObject *self); + +// Export for '_asyncio' shared extension +PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); + +// Export for '_asyncio' shared extension +PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); + extern PyObject *_PyCoro_GetAwaitableIter(PyObject *o); extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *); +extern PyTypeObject _PyCoroWrapper_Type; +extern PyTypeObject _PyAsyncGenWrappedValue_Type; +extern PyTypeObject _PyAsyncGenAThrow_Type; + /* runtime lifecycle */ extern void _PyAsyncGen_Fini(PyInterpreterState *); diff --git a/Include/internal/pycore_gil.h b/Include/internal/pycore_gil.h index 8ebad37b686cd4..daf1e73e7827e8 100644 --- a/Include/internal/pycore_gil.h +++ b/Include/internal/pycore_gil.h @@ -8,8 +8,8 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_atomic.h" /* _Py_atomic_address */ -#include "pycore_condvar.h" /* PyCOND_T */ +#include "pycore_atomic.h" // _Py_atomic_int +#include "pycore_condvar.h" // PyCOND_T #ifndef Py_HAVE_CONDVAR # error You need either a POSIX-compatible or a Windows system! @@ -25,7 +25,7 @@ struct _gil_runtime_state { unsigned long interval; /* Last PyThreadState holding / having held the GIL. This helps us know whether anyone else was scheduled after we dropped the GIL. */ - _Py_atomic_address last_holder; + PyThreadState* last_holder; /* Whether the GIL is already taken (-1 if uninitialized). This is atomic because it can be read without any lock taken in ceval.c. */ _Py_atomic_int locked; diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h index 5a3fb132c745ab..327fcc24cb29f1 100644 --- a/Include/internal/pycore_global_objects.h +++ b/Include/internal/pycore_global_objects.h @@ -8,10 +8,11 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_gc.h" // PyGC_Head +#include "pycore_context.h" // _PyContextTokenMissing +#include "pycore_gc.h" // _PyGC_Head_UNUSED #include "pycore_global_strings.h" // struct _Py_global_strings #include "pycore_hamt.h" // PyHamtNode_Bitmap -#include "pycore_context.h" // _PyContextTokenMissing +#include "pycore_hashtable.h" // _Py_hashtable_t #include "pycore_typeobject.h" // pytype_slotdef @@ -28,6 +29,11 @@ extern "C" { #define _Py_SINGLETON(NAME) \ _Py_GLOBAL_OBJECT(singletons.NAME) +struct _Py_cached_objects { + // XXX We could statically allocate the hashtable. + _Py_hashtable_t *interned_strings; +}; + struct _Py_static_objects { struct { /* Small integers are preallocated in this array so that they diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 6d50ffd0a02f1f..8fb22f70505808 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -547,6 +547,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_lambda)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_listcomp)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_null)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_setcomp)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_string)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_unknown)); @@ -786,11 +787,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_child)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_parent)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(aggregate_class)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(alias)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(append)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arg)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argdefs)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(args)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arguments)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argv)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(as_integer_ratio)); @@ -914,14 +912,13 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(errors)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(event)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eventmask)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_type)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_value)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(excepthook)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exception)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(existing_file_name)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exp)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(extend)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(extra_tokens)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(f)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(facility)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(factory)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(false)); @@ -953,6 +950,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fset)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(func)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(future)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(g)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(generation)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(genexpr)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get)); @@ -966,6 +964,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(globals)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groupindex)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groups)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(h)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(handle)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hash_name)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(header)); @@ -994,6 +993,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(instructions)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intern)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intersection)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(interval)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(is_running)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isatty)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isinstance)); @@ -1228,7 +1228,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timetuple)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(top)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trace_callback)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traceback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trailers)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(translate)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(true)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index bb1fb13f342fc6..39ffda8419a77d 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -33,6 +33,7 @@ struct _Py_global_strings { STRUCT_FOR_STR(anon_lambda, "") STRUCT_FOR_STR(anon_listcomp, "") STRUCT_FOR_STR(anon_module, "") + STRUCT_FOR_STR(anon_null, "") STRUCT_FOR_STR(anon_setcomp, "") STRUCT_FOR_STR(anon_string, "") STRUCT_FOR_STR(anon_unknown, "") @@ -275,11 +276,8 @@ struct _Py_global_strings { STRUCT_FOR_ID(after_in_child) STRUCT_FOR_ID(after_in_parent) STRUCT_FOR_ID(aggregate_class) - STRUCT_FOR_ID(alias) STRUCT_FOR_ID(append) - STRUCT_FOR_ID(arg) STRUCT_FOR_ID(argdefs) - STRUCT_FOR_ID(args) STRUCT_FOR_ID(arguments) STRUCT_FOR_ID(argv) STRUCT_FOR_ID(as_integer_ratio) @@ -403,14 +401,13 @@ struct _Py_global_strings { STRUCT_FOR_ID(errors) STRUCT_FOR_ID(event) STRUCT_FOR_ID(eventmask) - STRUCT_FOR_ID(exc_type) - STRUCT_FOR_ID(exc_value) STRUCT_FOR_ID(excepthook) STRUCT_FOR_ID(exception) STRUCT_FOR_ID(existing_file_name) STRUCT_FOR_ID(exp) STRUCT_FOR_ID(extend) STRUCT_FOR_ID(extra_tokens) + STRUCT_FOR_ID(f) STRUCT_FOR_ID(facility) STRUCT_FOR_ID(factory) STRUCT_FOR_ID(false) @@ -442,6 +439,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(fset) STRUCT_FOR_ID(func) STRUCT_FOR_ID(future) + STRUCT_FOR_ID(g) STRUCT_FOR_ID(generation) STRUCT_FOR_ID(genexpr) STRUCT_FOR_ID(get) @@ -455,6 +453,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(globals) STRUCT_FOR_ID(groupindex) STRUCT_FOR_ID(groups) + STRUCT_FOR_ID(h) STRUCT_FOR_ID(handle) STRUCT_FOR_ID(hash_name) STRUCT_FOR_ID(header) @@ -483,6 +482,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(instructions) STRUCT_FOR_ID(intern) STRUCT_FOR_ID(intersection) + STRUCT_FOR_ID(interval) STRUCT_FOR_ID(is_running) STRUCT_FOR_ID(isatty) STRUCT_FOR_ID(isinstance) @@ -717,7 +717,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(timetuple) STRUCT_FOR_ID(top) STRUCT_FOR_ID(trace_callback) - STRUCT_FOR_ID(traceback) STRUCT_FOR_ID(trailers) STRUCT_FOR_ID(translate) STRUCT_FOR_ID(true) diff --git a/Include/internal/pycore_hashtable.h b/Include/internal/pycore_hashtable.h index 6501ab14d27684..369d49c42bbfcc 100644 --- a/Include/internal/pycore_hashtable.h +++ b/Include/internal/pycore_hashtable.h @@ -70,6 +70,11 @@ struct _Py_hashtable_t { _Py_hashtable_allocator_t alloc; }; +// Export _Py_hashtable functions for '_testinternalcapi' shared extension +PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new( + _Py_hashtable_hash_func hash_func, + _Py_hashtable_compare_func compare_func); + /* Hash a pointer (void*) */ PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key); @@ -78,10 +83,6 @@ PyAPI_FUNC(int) _Py_hashtable_compare_direct( const void *key1, const void *key2); -PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new( - _Py_hashtable_hash_func hash_func, - _Py_hashtable_compare_func compare_func); - PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full( _Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func, @@ -106,6 +107,7 @@ PyAPI_FUNC(int) _Py_hashtable_foreach( void *user_data); PyAPI_FUNC(size_t) _Py_hashtable_size(const _Py_hashtable_t *ht); +PyAPI_FUNC(size_t) _Py_hashtable_len(const _Py_hashtable_t *ht); /* Add a new entry to the hash. The key must not be present in the hash table. Return 0 on success, -1 on memory error. */ diff --git a/Include/internal/pycore_identifier.h b/Include/internal/pycore_identifier.h new file mode 100644 index 00000000000000..0e015a40c831f4 --- /dev/null +++ b/Include/internal/pycore_identifier.h @@ -0,0 +1,54 @@ +/* String Literals: _Py_Identifier API */ + +#ifndef Py_INTERNAL_IDENTIFIER_H +#define Py_INTERNAL_IDENTIFIER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* This structure helps managing static strings. The basic usage goes like this: + Instead of doing + + r = PyObject_CallMethod(o, "foo", "args", ...); + + do + + _Py_IDENTIFIER(foo); + ... + r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); + + PyId_foo is a static variable, either on block level or file level. On first + usage, the string "foo" is interned, and the structures are linked. On interpreter + shutdown, all strings are released. + + Alternatively, _Py_static_string allows choosing the variable name. + _PyUnicode_FromId returns a borrowed reference to the interned string. + _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. +*/ +typedef struct _Py_Identifier { + const char* string; + // Index in PyInterpreterState.unicode.ids.array. It is process-wide + // unique and must be initialized to -1. + Py_ssize_t index; +} _Py_Identifier; + +// For now we are keeping _Py_IDENTIFIER for continued use +// in non-builtin extensions (and naughty PyPI modules). + +#define _Py_static_string_init(value) { .string = (value), .index = -1 } +#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) +#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) + +extern PyObject* _PyType_LookupId(PyTypeObject *, _Py_Identifier *); +extern PyObject* _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *); +extern PyObject* _PyObject_GetAttrId(PyObject *, _Py_Identifier *); +extern int _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *); + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_IDENTIFIER_H diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index c048ae88d9000c..117e46bb86285d 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -5,13 +5,19 @@ extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_hashtable.h" // _Py_hashtable_t #include "pycore_time.h" // _PyTime_t extern int _PyImport_IsInitialized(PyInterpreterState *); -PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(_Py_Identifier *name); +// Export for 'pyexpat' shared extension PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); -PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); + +extern int _PyImport_SetModuleString(const char *name, PyObject* module); extern void _PyImport_AcquireLock(PyInterpreterState *interp); extern int _PyImport_ReleaseLock(PyInterpreterState *interp); @@ -24,8 +30,11 @@ extern int _PyImport_FixupBuiltin( extern int _PyImport_FixupExtensionObject(PyObject*, PyObject *, PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyImport_GetModuleAttr(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyImport_GetModuleAttrString(const char *, const char *); +// Export for many shared extensions, like '_json' +PyAPI_FUNC(PyObject*) _PyImport_GetModuleAttr(PyObject *, PyObject *); + +// Export for many shared extensions, like '_datetime' +PyAPI_FUNC(PyObject*) _PyImport_GetModuleAttrString(const char *, const char *); struct _import_runtime_state { @@ -37,19 +46,15 @@ struct _import_runtime_state { See PyInterpreterState.modules_by_index for more info. */ Py_ssize_t last_module_index; struct { - /* A thread state tied to the main interpreter, - used exclusively for when the extensions dict is access/modified - from an arbitrary thread. */ - PyThreadState main_tstate; - /* A lock to guard the dict. */ + /* A lock to guard the cache. */ PyThread_type_lock mutex; - /* A dict mapping (filename, name) to PyModuleDef for modules. + /* The actual cache of (filename, name, PyModuleDef) for modules. Only legacy (single-phase init) extension modules are added and only if they support multiple initialization (m_size >- 0) or are imported in the main interpreter. This is initialized lazily in _PyImport_FixupExtensionObject(). Modules are added there and looked up in _imp.find_extension(). */ - PyObject *dict; + _Py_hashtable_t *hashtable; } extensions; /* Package context -- the full module name for package imports */ const char * pkgcontext; @@ -103,7 +108,7 @@ struct _import_state { }; #ifdef HAVE_DLOPEN -# include +# include // RTLD_NOW, RTLD_LAZY # if HAVE_DECL_RTLD_NOW # define _Py_DLOPEN_FLAGS RTLD_NOW # else @@ -187,16 +192,18 @@ struct _module_alias { const char *orig; /* ASCII encoded string */ }; -PyAPI_DATA(const struct _frozen *) _PyImport_FrozenBootstrap; -PyAPI_DATA(const struct _frozen *) _PyImport_FrozenStdlib; -PyAPI_DATA(const struct _frozen *) _PyImport_FrozenTest; +// Export these 3 symbols for test_ctypes +PyAPI_DATA(const struct _frozen*) _PyImport_FrozenBootstrap; +PyAPI_DATA(const struct _frozen*) _PyImport_FrozenStdlib; +PyAPI_DATA(const struct _frozen*) _PyImport_FrozenTest; + extern const struct _module_alias * _PyImport_FrozenAliases; -PyAPI_FUNC(int) _PyImport_CheckSubinterpIncompatibleExtensionAllowed( +extern int _PyImport_CheckSubinterpIncompatibleExtensionAllowed( const char *name); -// for testing +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(int) _PyImport_ClearExtension(PyObject *name, PyObject *filename); #ifdef __cplusplus diff --git a/Include/internal/pycore_importdl.h b/Include/internal/pycore_importdl.h new file mode 100644 index 00000000000000..dee64241c763f3 --- /dev/null +++ b/Include/internal/pycore_importdl.h @@ -0,0 +1,57 @@ +#ifndef Py_INTERNAL_IMPORTDL_H +#define Py_INTERNAL_IMPORTDL_H + +#include "patchlevel.h" // PY_MAJOR_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +extern const char *_PyImport_DynLoadFiletab[]; + +extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *); + +typedef PyObject *(*PyModInitFunction)(void); + +/* Max length of module suffix searched for -- accommodates "module.slb" */ +#define MAXSUFFIXSIZE 12 + +#ifdef MS_WINDOWS +#include +typedef FARPROC dl_funcptr; + +#ifdef _DEBUG +# define PYD_DEBUG_SUFFIX "_d" +#else +# define PYD_DEBUG_SUFFIX "" +#endif + +#ifdef Py_NOGIL +# define PYD_THREADING_TAG "t" +#else +# define PYD_THREADING_TAG "" +#endif + +#ifdef PYD_PLATFORM_TAG +# define PYD_SOABI "cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG "-" PYD_PLATFORM_TAG +#else +# define PYD_SOABI "cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG +#endif + +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX "." PYD_SOABI ".pyd" +#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" + +#else +typedef void (*dl_funcptr)(void); +#endif + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_IMPORTDL_H */ diff --git a/Include/internal/pycore_initconfig.h b/Include/internal/pycore_initconfig.h index 4cbd14a61d4545..c86988234f6a05 100644 --- a/Include/internal/pycore_initconfig.h +++ b/Include/internal/pycore_initconfig.h @@ -22,7 +22,7 @@ struct pyruntimestate; #endif #define _PyStatus_OK() \ - (PyStatus){._type = _PyStatus_TYPE_OK,} + (PyStatus){._type = _PyStatus_TYPE_OK} /* other fields are set to 0 */ #define _PyStatus_ERR(ERR_MSG) \ (PyStatus){ \ @@ -30,7 +30,8 @@ struct pyruntimestate; .func = _PyStatus_GET_FUNC(), \ .err_msg = (ERR_MSG)} /* other fields are set to 0 */ -#define _PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed") +#define _PyStatus_NO_MEMORY_ERRMSG "memory allocation failed" +#define _PyStatus_NO_MEMORY() _PyStatus_ERR(_PyStatus_NO_MEMORY_ERRMSG) #define _PyStatus_EXIT(EXITCODE) \ (PyStatus){ \ ._type = _PyStatus_TYPE_EXIT, \ @@ -44,19 +45,23 @@ struct pyruntimestate; #define _PyStatus_UPDATE_FUNC(err) \ do { (err).func = _PyStatus_GET_FUNC(); } while (0) +// Export for '_testinternalcapi' shared extension +PyAPI_FUNC(void) _PyErr_SetFromPyStatus(PyStatus status); + + /* --- PyWideStringList ------------------------------------------------ */ #define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL} #ifndef NDEBUG -PyAPI_FUNC(int) _PyWideStringList_CheckConsistency(const PyWideStringList *list); +extern int _PyWideStringList_CheckConsistency(const PyWideStringList *list); #endif -PyAPI_FUNC(void) _PyWideStringList_Clear(PyWideStringList *list); -PyAPI_FUNC(int) _PyWideStringList_Copy(PyWideStringList *list, +extern void _PyWideStringList_Clear(PyWideStringList *list); +extern int _PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2); -PyAPI_FUNC(PyStatus) _PyWideStringList_Extend(PyWideStringList *list, +extern PyStatus _PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2); -PyAPI_FUNC(PyObject*) _PyWideStringList_AsList(const PyWideStringList *list); +extern PyObject* _PyWideStringList_AsList(const PyWideStringList *list); /* --- _PyArgv ---------------------------------------------------- */ @@ -68,28 +73,28 @@ typedef struct _PyArgv { wchar_t * const *wchar_argv; } _PyArgv; -PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args, +extern PyStatus _PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list); /* --- Helper functions ------------------------------------------- */ -PyAPI_FUNC(int) _Py_str_to_int( +extern int _Py_str_to_int( const char *str, int *result); -PyAPI_FUNC(const wchar_t*) _Py_get_xoption( +extern const wchar_t* _Py_get_xoption( const PyWideStringList *xoptions, const wchar_t *name); -PyAPI_FUNC(const char*) _Py_GetEnv( +extern const char* _Py_GetEnv( int use_environment, const char *name); -PyAPI_FUNC(void) _Py_get_env_flag( +extern void _Py_get_env_flag( int use_environment, int *flag, const char *name); /* Py_GetArgcArgv() helper */ -PyAPI_FUNC(void) _Py_ClearArgcArgv(void); +extern void _Py_ClearArgcArgv(void); /* --- _PyPreCmdline ------------------------------------------------- */ @@ -122,7 +127,9 @@ extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline, /* --- PyPreConfig ----------------------------------------------- */ +// Export for '_testembed' program PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig); + extern void _PyPreConfig_InitFromConfig( PyPreConfig *preconfig, const PyConfig *config); @@ -146,7 +153,9 @@ typedef enum { _PyConfig_INIT_ISOLATED = 3 } _PyConfigInitEnum; +// Export for '_testembed' program PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config); + extern PyStatus _PyConfig_Copy( PyConfig *config, const PyConfig *config2); @@ -161,16 +170,16 @@ extern PyStatus _PyConfig_SetPyArgv( PyConfig *config, const _PyArgv *args); -PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config); -PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict); extern void _Py_DumpPathConfig(PyThreadState *tstate); -PyAPI_FUNC(PyObject*) _Py_Get_Getpath_CodeObject(void); - /* --- Function used for testing ---------------------------------- */ +// Export these functions for '_testinternalcapi' shared extension +PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config); +PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict); +PyAPI_FUNC(PyObject*) _Py_Get_Getpath_CodeObject(void); PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); #ifdef __cplusplus diff --git a/Include/internal/pycore_instruments.h b/Include/internal/pycore_instruments.h index 9fb3952227af18..97dcfb9f8672f7 100644 --- a/Include/internal/pycore_instruments.h +++ b/Include/internal/pycore_instruments.h @@ -1,12 +1,11 @@ - #ifndef Py_INTERNAL_INSTRUMENT_H #define Py_INTERNAL_INSTRUMENT_H +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif -#include "pycore_bitutils.h" // _Py_popcount32 -#include "pycore_frame.h" - -#include "cpython/code.h" +#include "pycore_frame.h" // _PyInterpreterFrame #ifdef __cplusplus extern "C" { @@ -28,7 +27,8 @@ extern "C" { #define PY_MONITORING_EVENT_BRANCH 8 #define PY_MONITORING_EVENT_STOP_ITERATION 9 -#define PY_MONITORING_INSTRUMENTED_EVENTS 10 +#define PY_MONITORING_IS_INSTRUMENTED_EVENT(ev) \ + ((ev) < _PY_MONITORING_LOCAL_EVENTS) /* Other events, mainly exceptions */ @@ -36,12 +36,13 @@ extern "C" { #define PY_MONITORING_EVENT_EXCEPTION_HANDLED 11 #define PY_MONITORING_EVENT_PY_UNWIND 12 #define PY_MONITORING_EVENT_PY_THROW 13 +#define PY_MONITORING_EVENT_RERAISE 14 /* Ancilliary events */ -#define PY_MONITORING_EVENT_C_RETURN 14 -#define PY_MONITORING_EVENT_C_RAISE 15 +#define PY_MONITORING_EVENT_C_RETURN 15 +#define PY_MONITORING_EVENT_C_RAISE 16 typedef uint32_t _PyMonitoringEventSet; @@ -88,10 +89,6 @@ extern int _Py_call_instrumentation_2args(PyThreadState *tstate, int event, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); -extern void -_Py_call_instrumentation_exc0(PyThreadState *tstate, int event, - _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); - extern void _Py_call_instrumentation_exc2(PyThreadState *tstate, int event, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index bb37cafe6286a9..60d333ad7baa2e 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -8,11 +8,10 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include +#include // bool #include "pycore_ast_state.h" // struct ast_state #include "pycore_atexit.h" // struct atexit_state -#include "pycore_atomic.h" // _Py_atomic_address #include "pycore_ceval_state.h" // struct _ceval_state #include "pycore_code.h" // struct callable_cache #include "pycore_context.h" // struct _Py_context_state @@ -21,16 +20,16 @@ extern "C" { #include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_floatobject.h" // struct _Py_float_state #include "pycore_function.h" // FUNC_MAX_WATCHERS -#include "pycore_genobject.h" // struct _Py_async_gen_state #include "pycore_gc.h" // struct _gc_runtime_state -#include "pycore_global_objects.h" // struct _Py_interp_static_objects +#include "pycore_genobject.h" // struct _Py_async_gen_state +#include "pycore_global_objects.h"// struct _Py_interp_cached_objects #include "pycore_import.h" // struct _import_state -#include "pycore_instruments.h" // PY_MONITORING_EVENTS +#include "pycore_instruments.h" // _PY_MONITORING_EVENTS #include "pycore_list.h" // struct _Py_list_state -#include "pycore_object_state.h" // struct _py_object_state -#include "pycore_obmalloc.h" // struct obmalloc_state +#include "pycore_object_state.h" // struct _py_object_state +#include "pycore_obmalloc.h" // struct _obmalloc_state #include "pycore_tuple.h" // struct _Py_tuple_state -#include "pycore_typeobject.h" // struct type_cache +#include "pycore_typeobject.h" // struct types_state #include "pycore_unicodeobject.h" // struct _Py_unicode_state #include "pycore_warnings.h" // struct _warnings_runtime_state @@ -39,6 +38,32 @@ struct _Py_long_state { int max_str_digits; }; + +/* cross-interpreter data registry */ + +/* For now we use a global registry of shareable classes. An + alternative would be to add a tp_* slot for a class's + crossinterpdatafunc. It would be simpler and more efficient. */ + +struct _xidregitem; + +struct _xidregitem { + struct _xidregitem *prev; + struct _xidregitem *next; + /* This can be a dangling pointer, but only if weakref is set. */ + PyTypeObject *cls; + /* This is NULL for builtin types. */ + PyObject *weakref; + size_t refcount; + crossinterpdatafunc getdata; +}; + +struct _xidregistry { + PyThread_type_lock mutex; + struct _xidregitem *head; +}; + + /* interpreter state */ /* PyInterpreterState holds the global state for one of the runtime's @@ -48,6 +73,11 @@ struct _Py_long_state { */ struct _is { + /* This struct countains the eval_breaker, + * which is by far the hottest field in this struct + * and should be placed at the beginning. */ + struct _ceval_state ceval; + PyInterpreterState *next; int64_t id; @@ -62,12 +92,13 @@ struct _is { int _initialized; int finalizing; - uint64_t monitoring_version; - uint64_t last_restart_version; + uintptr_t last_restart_version; struct pythreads { uint64_t next_unique_id; /* The linked list of threads, newest first. */ PyThreadState *head; + /* The thread currently executing in the __main__ module, if any. */ + PyThreadState *main; /* Used in Modules/_threadmodule.c. */ long count; /* Support for runtime thread stack size tuning. @@ -87,7 +118,9 @@ struct _is { Use _PyInterpreterState_GetFinalizing() and _PyInterpreterState_SetFinalizing() to access it, don't access it directly. */ - _Py_atomic_address _finalizing; + PyThreadState* _finalizing; + /* The ID of the OS thread in which we are finalizing. */ + unsigned long _finalizing_id; struct _gc_runtime_state gc; @@ -109,8 +142,6 @@ struct _is { // Dictionary of the builtins module PyObject *builtins; - struct _ceval_state ceval; - struct _import_state imports; /* The per-interpreter GIL, which might not be used. */ @@ -143,6 +174,9 @@ struct _is { Py_ssize_t co_extra_user_count; freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; + // XXX Remove this field once we have a tp_* slot. + struct _xidregistry xidregistry; + #ifdef HAVE_FORK PyObject *before_forkers; PyObject *after_forkers_parent; @@ -183,14 +217,15 @@ struct _is { _PyOptimizerObject *optimizer; uint16_t optimizer_resume_threshold; uint16_t optimizer_backedge_threshold; + uint32_t next_func_version; - _Py_Monitors monitors; + _Py_GlobalMonitors monitors; bool f_opcode_trace_set; bool sys_profile_initialized; bool sys_trace_initialized; Py_ssize_t sys_profiling_threads; /* Count of threads with c_profilefunc set */ Py_ssize_t sys_tracing_threads; /* Count of threads with c_tracefunc set */ - PyObject *monitoring_callables[PY_MONITORING_TOOL_IDS][PY_MONITORING_EVENTS]; + PyObject *monitoring_callables[PY_MONITORING_TOOL_IDS][_PY_MONITORING_EVENTS]; PyObject *monitoring_tool_names[PY_MONITORING_TOOL_IDS]; struct _Py_interp_cached_objects cached_objects; @@ -198,6 +233,7 @@ struct _is { /* the initial PyInterpreterState.threads.head */ PyThreadState _initial_thread; + Py_ssize_t _interactive_src_count; }; @@ -208,70 +244,72 @@ extern void _PyInterpreterState_Clear(PyThreadState *tstate); static inline PyThreadState* _PyInterpreterState_GetFinalizing(PyInterpreterState *interp) { - return (PyThreadState*)_Py_atomic_load_relaxed(&interp->_finalizing); + return (PyThreadState*)_Py_atomic_load_ptr_relaxed(&interp->_finalizing); +} + +static inline unsigned long +_PyInterpreterState_GetFinalizingID(PyInterpreterState *interp) { + return _Py_atomic_load_ulong_relaxed(&interp->_finalizing_id); } static inline void _PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tstate) { - _Py_atomic_store_relaxed(&interp->_finalizing, (uintptr_t)tstate); + _Py_atomic_store_ptr_relaxed(&interp->_finalizing, tstate); + if (tstate == NULL) { + _Py_atomic_store_ulong_relaxed(&interp->_finalizing_id, 0); + } + else { + // XXX Re-enable this assert once gh-109860 is fixed. + //assert(tstate->thread_id == PyThread_get_thread_ident()); + _Py_atomic_store_ulong_relaxed(&interp->_finalizing_id, + tstate->thread_id); + } } -/* cross-interpreter data registry */ - -/* For now we use a global registry of shareable classes. An - alternative would be to add a tp_* slot for a class's - crossinterpdatafunc. It would be simpler and more efficient. */ - -struct _xidregitem; - -struct _xidregitem { - struct _xidregitem *prev; - struct _xidregitem *next; - PyObject *cls; // weakref to a PyTypeObject - crossinterpdatafunc getdata; -}; - -PyAPI_FUNC(PyInterpreterState*) _PyInterpreterState_LookUpID(int64_t); - -PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); -PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); -PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); +// Export for the _xxinterpchannels module. +PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t); -PyAPI_FUNC(PyObject*) _PyInterpreterState_GetMainModule(PyInterpreterState *); +extern int _PyInterpreterState_IDInitref(PyInterpreterState *); +extern int _PyInterpreterState_IDIncref(PyInterpreterState *); +extern void _PyInterpreterState_IDDecref(PyInterpreterState *); extern const PyConfig* _PyInterpreterState_GetConfig(PyInterpreterState *interp); -/* Get a copy of the current interpreter configuration. - - Return 0 on success. Raise an exception and return -1 on error. - - The caller must initialize 'config', using PyConfig_InitPythonConfig() - for example. - - Python must be preinitialized to call this method. - The caller must hold the GIL. - - Once done with the configuration, PyConfig_Clear() must be called to clear - it. */ +// Get a copy of the current interpreter configuration. +// +// Return 0 on success. Raise an exception and return -1 on error. +// +// The caller must initialize 'config', using PyConfig_InitPythonConfig() +// for example. +// +// Python must be preinitialized to call this method. +// The caller must hold the GIL. +// +// Once done with the configuration, PyConfig_Clear() must be called to clear +// it. +// +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( struct PyConfig *config); -/* Set the configuration of the current interpreter. - - This function should be called during or just after the Python - initialization. - - Update the sys module with the new configuration. If the sys module was - modified directly after the Python initialization, these changes are lost. - - Some configuration like faulthandler or warnoptions can be updated in the - configuration, but don't reconfigure Python (don't enable/disable - faulthandler and don't reconfigure warnings filters). - - Return 0 on success. Raise an exception and return -1 on error. - - The configuration should come from _PyInterpreterState_GetConfigCopy(). */ +// Set the configuration of the current interpreter. +// +// This function should be called during or just after the Python +// initialization. +// +// Update the sys module with the new configuration. If the sys module was +// modified directly after the Python initialization, these changes are lost. +// +// Some configuration like faulthandler or warnoptions can be updated in the +// configuration, but don't reconfigure Python (don't enable/disable +// faulthandler and don't reconfigure warnings filters). +// +// Return 0 on success. Raise an exception and return -1 on error. +// +// The configuration should come from _PyInterpreterState_GetConfigCopy(). +// +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(int) _PyInterpreterState_SetConfig( const struct PyConfig *config); @@ -306,6 +344,10 @@ might not be allowed in the current interpreter (i.e. os.fork() would fail). extern int _PyInterpreterState_HasFeature(PyInterpreterState *interp, unsigned long feature); +PyAPI_FUNC(PyStatus) _PyInterpreterState_New( + PyThreadState *tstate, + PyInterpreterState **pinterp); + #ifdef __cplusplus } diff --git a/Include/internal/pycore_intrinsics.h b/Include/internal/pycore_intrinsics.h index 39f15681b7b24b..3a8dd95cff8e5d 100644 --- a/Include/internal/pycore_intrinsics.h +++ b/Include/internal/pycore_intrinsics.h @@ -1,4 +1,9 @@ -// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py +#ifndef Py_INTERNAL_INTRINSIC_H +#define Py_INTERNAL_INTRINSIC_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif /* Unary Functions: */ #define INTRINSIC_1_INVALID 0 @@ -26,7 +31,20 @@ #define MAX_INTRINSIC_2 4 -typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value); -typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2); -extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[]; -extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[]; +typedef PyObject *(*intrinsic_func1)(PyThreadState* tstate, PyObject *value); +typedef PyObject *(*intrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2); + +typedef struct { + intrinsic_func1 func; + const char *name; +} intrinsic_func1_info; + +typedef struct { + intrinsic_func2 func; + const char *name; +} intrinsic_func2_info; + +extern const intrinsic_func1_info _PyIntrinsics_UnaryFunctions[]; +extern const intrinsic_func2_info _PyIntrinsics_BinaryFunctions[]; + +#endif // !Py_INTERNAL_INTRINSIC_H diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h index b2e503c87542bf..056be2c80c8ce6 100644 --- a/Include/internal/pycore_list.h +++ b/Include/internal/pycore_list.h @@ -8,7 +8,9 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "listobject.h" // _PyList_CAST() + +extern PyObject* _PyList_Extend(PyListObject *, PyObject *); +extern void _PyList_DebugMallocStats(FILE *out); /* runtime lifecycle */ diff --git a/Include/internal/pycore_llist.h b/Include/internal/pycore_llist.h new file mode 100644 index 00000000000000..5fd261da05fa5d --- /dev/null +++ b/Include/internal/pycore_llist.h @@ -0,0 +1,107 @@ +// A doubly-linked list that can be embedded in a struct. +// +// Usage: +// struct llist_node head = LLIST_INIT(head); +// typedef struct { +// ... +// struct llist_node node; +// ... +// } MyObj; +// +// llist_insert_tail(&head, &obj->node); +// llist_remove(&obj->node); +// +// struct llist_node *node; +// llist_for_each(node, &head) { +// MyObj *obj = llist_data(node, MyObj, node); +// ... +// } +// + +#ifndef Py_INTERNAL_LLIST_H +#define Py_INTERNAL_LLIST_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "Py_BUILD_CORE must be defined to include this header" +#endif + +struct llist_node { + struct llist_node *next; + struct llist_node *prev; +}; + +// Get the struct containing a node. +#define llist_data(node, type, member) \ + (type*)((char*)node - offsetof(type, member)) + +// Iterate over a list. +#define llist_for_each(node, head) \ + for (node = (head)->next; node != (head); node = node->next) + +// Iterate over a list, but allow removal of the current node. +#define llist_for_each_safe(node, head) \ + for (struct llist_node *_next = (node = (head)->next, node->next); \ + node != (head); node = _next, _next = node->next) + +#define LLIST_INIT(head) { &head, &head } + +static inline void +llist_init(struct llist_node *head) +{ + head->next = head; + head->prev = head; +} + +// Returns 1 if the list is empty, 0 otherwise. +static inline int +llist_empty(struct llist_node *head) +{ + return head->next == head; +} + +// Appends to the tail of the list. +static inline void +llist_insert_tail(struct llist_node *head, struct llist_node *node) +{ + node->prev = head->prev; + node->next = head; + head->prev->next = node; + head->prev = node; +} + +// Remove a node from the list. +static inline void +llist_remove(struct llist_node *node) +{ + struct llist_node *prev = node->prev; + struct llist_node *next = node->next; + prev->next = next; + next->prev = prev; + node->prev = NULL; + node->next = NULL; +} + +// Append all nodes from head2 onto head1. head2 is left empty. +static inline void +llist_concat(struct llist_node *head1, struct llist_node *head2) +{ + if (!llist_empty(head2)) { + head1->prev->next = head2->next; + head2->next->prev = head1->prev; + + head1->prev = head2->prev; + head2->prev->next = head1; + llist_init(head2); + } +} + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_LLIST_H */ diff --git a/Include/internal/pycore_lock.h b/Include/internal/pycore_lock.h new file mode 100644 index 00000000000000..c4bb76a40e7b12 --- /dev/null +++ b/Include/internal/pycore_lock.h @@ -0,0 +1,158 @@ +// Lightweight locks and other synchronization mechanisms. +// +// These implementations are based on WebKit's WTF::Lock. See +// https://webkit.org/blog/6161/locking-in-webkit/ for a description of the +// design. +#ifndef Py_INTERNAL_LOCK_H +#define Py_INTERNAL_LOCK_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_time.h" // _PyTime_t + + +// A mutex that occupies one byte. The lock can be zero initialized. +// +// Only the two least significant bits are used. The remaining bits should be +// zero: +// 0b00: unlocked +// 0b01: locked +// 0b10: unlocked and has parked threads +// 0b11: locked and has parked threads +// +// Typical initialization: +// PyMutex m = (PyMutex){0}; +// +// Typical usage: +// PyMutex_Lock(&m); +// ... +// PyMutex_Unlock(&m); +typedef struct _PyMutex { + uint8_t v; +} PyMutex; + +#define _Py_UNLOCKED 0 +#define _Py_LOCKED 1 +#define _Py_HAS_PARKED 2 + +// (private) slow path for locking the mutex +PyAPI_FUNC(void) _PyMutex_LockSlow(PyMutex *m); + +// (private) slow path for unlocking the mutex +PyAPI_FUNC(void) _PyMutex_UnlockSlow(PyMutex *m); + +// Locks the mutex. +// +// If the mutex is currently locked, the calling thread will be parked until +// the mutex is unlocked. If the current thread holds the GIL, then the GIL +// will be released while the thread is parked. +static inline void +PyMutex_Lock(PyMutex *m) +{ + uint8_t expected = _Py_UNLOCKED; + if (!_Py_atomic_compare_exchange_uint8(&m->v, &expected, _Py_LOCKED)) { + _PyMutex_LockSlow(m); + } +} + +// Unlocks the mutex. +static inline void +PyMutex_Unlock(PyMutex *m) +{ + uint8_t expected = _Py_LOCKED; + if (!_Py_atomic_compare_exchange_uint8(&m->v, &expected, _Py_UNLOCKED)) { + _PyMutex_UnlockSlow(m); + } +} + +// Checks if the mutex is currently locked. +static inline int +PyMutex_IsLocked(PyMutex *m) +{ + return (_Py_atomic_load_uint8(&m->v) & _Py_LOCKED) != 0; +} + +typedef enum _PyLockFlags { + // Do not detach/release the GIL when waiting on the lock. + _Py_LOCK_DONT_DETACH = 0, + + // Detach/release the GIL while waiting on the lock. + _PY_LOCK_DETACH = 1, + + // Handle signals if interrupted while waiting on the lock. + _PY_LOCK_HANDLE_SIGNALS = 2, +} _PyLockFlags; + +// Lock a mutex with an optional timeout and additional options. See +// _PyLockFlags for details. +extern PyLockStatus +_PyMutex_LockTimed(PyMutex *m, _PyTime_t timeout_ns, _PyLockFlags flags); + +// Unlock a mutex, returns 0 if the mutex is not locked (used for improved +// error messages). +extern int _PyMutex_TryUnlock(PyMutex *m); + + +// PyEvent is a one-time event notification +typedef struct { + uint8_t v; +} PyEvent; + +// Set the event and notify any waiting threads. +// Export for '_testinternalcapi' shared extension +PyAPI_FUNC(void) _PyEvent_Notify(PyEvent *evt); + +// Wait for the event to be set. If the event is already set, then this returns +// immediately. +PyAPI_FUNC(void) PyEvent_Wait(PyEvent *evt); + +// Wait for the event to be set, or until the timeout expires. If the event is +// already set, then this returns immediately. Returns 1 if the event was set, +// and 0 if the timeout expired or thread was interrupted. +PyAPI_FUNC(int) PyEvent_WaitTimed(PyEvent *evt, _PyTime_t timeout_ns); + + +// _PyRawMutex implements a word-sized mutex that that does not depend on the +// parking lot API, and therefore can be used in the parking lot +// implementation. +// +// The mutex uses a packed representation: the least significant bit is used to +// indicate whether the mutex is locked or not. The remaining bits are either +// zero or a pointer to a `struct raw_mutex_entry` (see lock.c). +typedef struct { + uintptr_t v; +} _PyRawMutex; + +// Slow paths for lock/unlock +extern void _PyRawMutex_LockSlow(_PyRawMutex *m); +extern void _PyRawMutex_UnlockSlow(_PyRawMutex *m); + +static inline void +_PyRawMutex_Lock(_PyRawMutex *m) +{ + uintptr_t unlocked = _Py_UNLOCKED; + if (_Py_atomic_compare_exchange_uintptr(&m->v, &unlocked, _Py_LOCKED)) { + return; + } + _PyRawMutex_LockSlow(m); +} + +static inline void +_PyRawMutex_Unlock(_PyRawMutex *m) +{ + uintptr_t locked = _Py_LOCKED; + if (_Py_atomic_compare_exchange_uintptr(&m->v, &locked, _Py_UNLOCKED)) { + return; + } + _PyRawMutex_UnlockSlow(m); +} + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_LOCK_H */ diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index 3f01694e5f5ac4..3c253ed7ff556b 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -47,6 +47,34 @@ extern "C" { # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold." #endif +extern PyLongObject* _PyLong_New(Py_ssize_t); + +// Return a copy of src. +extern PyObject* _PyLong_Copy(PyLongObject *src); + +// Export for '_decimal' shared extension +PyAPI_FUNC(PyLongObject*) _PyLong_FromDigits( + int negative, + Py_ssize_t digit_count, + digit *digits); + +// _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. +// v must not be NULL, and must be a normalized long. +// There are no error cases. +// +// Export for '_pickle' shared extension. +PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); + +// _PyLong_NumBits. Return the number of bits needed to represent the +// absolute value of a long. For example, this returns 1 for 1 and -1, 2 +// for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. +// v must not be NULL, and must be a normalized long. +// (size_t)-1 is returned and OverflowError set if the true result doesn't +// fit in a size_t. +// +// Export for 'math' shared extension. +PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); + /* runtime lifecycle */ @@ -64,51 +92,145 @@ extern void _PyLong_FiniTypes(PyInterpreterState *interp); # error "_PY_NSMALLPOSINTS must be greater than or equal to 257" #endif -// Return a borrowed reference to the zero singleton. +// Return a reference to the immortal zero singleton. // The function cannot return NULL. static inline PyObject* _PyLong_GetZero(void) { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; } -// Return a borrowed reference to the one singleton. +// Return a reference to the immortal one singleton. // The function cannot return NULL. static inline PyObject* _PyLong_GetOne(void) { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) { - return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]); + return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]; } -PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right); -PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right); -PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right); - -/* Used by Python/mystrtoul.c, _PyBytes_FromHex(), - _PyBytes_DecodeEscape(), etc. */ +// _PyLong_Frexp returns a double x and an exponent e such that the +// true value is approximately equal to x * 2**e. e is >= 0. x is +// 0.0 if and only if the input is 0 (in which case, e and x are both +// zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is +// possible if the number of bits doesn't fit into a Py_ssize_t, sets +// OverflowError and returns -1.0 for x, 0 for e. +// +// Export for 'math' shared extension +PyAPI_DATA(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); + +extern PyObject* _PyLong_FromBytes(const char *, Py_ssize_t, int); + +// _PyLong_DivmodNear. Given integers a and b, compute the nearest +// integer q to the exact quotient a / b, rounding to the nearest even integer +// in the case of a tie. Return (q, r), where r = a - q*b. The remainder r +// will satisfy abs(r) <= abs(b)/2, with equality possible only if q is +// even. +// +// Export for '_datetime' shared extension. +PyAPI_DATA(PyObject*) _PyLong_DivmodNear(PyObject *, PyObject *); + +// _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in +// base 256, and return a Python int with the same numeric value. +// If n is 0, the integer is 0. Else: +// If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; +// else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the +// LSB. +// If is_signed is 0/false, view the bytes as a non-negative integer. +// If is_signed is 1/true, view the bytes as a 2's-complement integer, +// non-negative if bit 0x80 of the MSB is clear, negative if set. +// Error returns: +// + Return NULL with the appropriate exception set if there's not +// enough memory to create the Python int. +// +// Export for '_multibytecodec' shared extension. +PyAPI_DATA(PyObject*) _PyLong_FromByteArray( + const unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +// _PyLong_AsByteArray: Convert the least-significant 8*n bits of long +// v to a base-256 integer, stored in array bytes. Normally return 0, +// return -1 on error. +// If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at +// bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and +// the LSB at bytes[n-1]. +// If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes +// are filled and there's nothing special about bit 0x80 of the MSB. +// If is_signed is 1/true, bytes is filled with the 2's-complement +// representation of v's value. Bit 0x80 of the MSB is the sign bit. +// Error returns (-1): +// + is_signed is 0 and v < 0. TypeError is set in this case, and bytes +// isn't altered. +// + n isn't big enough to hold the full mathematical value of v. For +// example, if is_signed is 0 and there are more digits in the v than +// fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of +// being large enough to hold a sign bit. OverflowError is set in this +// case, but bytes holds the least-significant n bytes of the true value. +// +// Export for '_struct' shared extension. +PyAPI_DATA(int) _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +// _PyLong_Format: Convert the long to a string object with given base, +// appending a base prefix of 0[box] if base is 2, 8 or 16. +// Export for '_tkinter' shared extension. +PyAPI_DATA(PyObject*) _PyLong_Format(PyObject *obj, int base); + +// For use by the math.gcd() function. +// Export for 'math' shared extension. +PyAPI_DATA(PyObject*) _PyLong_GCD(PyObject *, PyObject *); + +// Export for 'math' shared extension +PyAPI_DATA(PyObject*) _PyLong_Rshift(PyObject *, size_t); + +// Export for 'math' shared extension +PyAPI_DATA(PyObject*) _PyLong_Lshift(PyObject *, size_t); + +extern PyObject* _PyLong_Add(PyLongObject *left, PyLongObject *right); +extern PyObject* _PyLong_Multiply(PyLongObject *left, PyLongObject *right); +extern PyObject* _PyLong_Subtract(PyLongObject *left, PyLongObject *right); + +// Export for 'binascii' shared extension. PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ -PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter( +extern int _PyLong_FormatAdvancedWriter( _PyUnicodeWriter *writer, PyObject *obj, PyObject *format_spec, Py_ssize_t start, Py_ssize_t end); -PyAPI_FUNC(int) _PyLong_FormatWriter( +extern int _PyLong_FormatWriter( _PyUnicodeWriter *writer, PyObject *obj, int base, int alternate); -PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( +extern char* _PyLong_FormatBytesWriter( _PyBytesWriter *writer, char *str, PyObject *obj, int base, int alternate); +// Argument converters used by Argument Clinic + +// Export for 'select' shared extension (Argument Clinic code) +PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *); + +// Export for '_testclinic' shared extension (Argument Clinic code) +PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *); + +// Export for '_blake2' shared extension (Argument Clinic code) +PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *); + +// Export for '_blake2' shared extension (Argument Clinic code) +PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *); + +// Export for '_testclinic' shared extension (Argument Clinic code) +PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *); + /* Long value tag bits: * 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1. * 2: Reserved for immortality bit diff --git a/Include/internal/pycore_memoryobject.h b/Include/internal/pycore_memoryobject.h index fe19e3f9611a16..62e204fcbf6533 100644 --- a/Include/internal/pycore_memoryobject.h +++ b/Include/internal/pycore_memoryobject.h @@ -8,6 +8,8 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +extern PyTypeObject _PyManagedBuffer_Type; + PyObject * _PyMemoryView_FromBufferProc(PyObject *v, int flags, getbufferproc bufferproc); diff --git a/Include/internal/pycore_moduleobject.h b/Include/internal/pycore_moduleobject.h index 31a31e724d0b21..5644bbe5e0552b 100644 --- a/Include/internal/pycore_moduleobject.h +++ b/Include/internal/pycore_moduleobject.h @@ -8,6 +8,12 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +extern void _PyModule_Clear(PyObject *); +extern void _PyModule_ClearDict(PyObject *); +extern int _PyModuleSpec_IsInitializing(PyObject *); + +extern int _PyModule_IsExtension(PyObject *obj); + typedef struct { PyObject_HEAD PyObject *md_dict; diff --git a/Include/internal/pycore_namespace.h b/Include/internal/pycore_namespace.h index cb76f040693d10..f165cf15319a59 100644 --- a/Include/internal/pycore_namespace.h +++ b/Include/internal/pycore_namespace.h @@ -10,9 +10,10 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -PyAPI_DATA(PyTypeObject) _PyNamespace_Type; +extern PyTypeObject _PyNamespace_Type; -PyAPI_FUNC(PyObject *) _PyNamespace_New(PyObject *kwds); +// Export for '_testmultiphase' shared extension +PyAPI_FUNC(PyObject*) _PyNamespace_New(PyObject *kwds); #ifdef __cplusplus } diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 2358f48738a905..2d50f42c9c614d 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -10,9 +10,41 @@ extern "C" { #include #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() +#include "pycore_emscripten_trampoline.h" // _PyCFunction_TrampolineCall() #include "pycore_interp.h" // PyInterpreterState.gc #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_runtime.h" // _PyRuntime + +/* Check if an object is consistent. For example, ensure that the reference + counter is greater than or equal to 1, and ensure that ob_type is not NULL. + + Call _PyObject_AssertFailed() if the object is inconsistent. + + If check_content is zero, only check header fields: reduce the overhead. + + The function always return 1. The return value is just here to be able to + write: + + assert(_PyObject_CheckConsistency(obj, 1)); */ +extern int _PyObject_CheckConsistency(PyObject *op, int check_content); + +extern void _PyDebugAllocatorStats(FILE *out, const char *block_name, + int num_blocks, size_t sizeof_block); + +extern void _PyObject_DebugTypeStats(FILE *out); + +#ifdef Py_TRACE_REFS +// Forget a reference registered by _Py_NewReference(). Function called by +// _Py_Dealloc(). +// +// On a free list, the function can be used before modifying an object to +// remove the object from traced objects. Then _Py_NewReference() or +// _Py_NewReferenceNoTotal() should be called again on the object to trace +// it again. +extern void _Py_ForgetReference(PyObject *); +#endif + +// Export for shared _testinternalcapi extension +PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); /* We need to maintain an internal copy of Py{Var}Object_HEAD_INIT to avoid designated initializer conflicts in C++20. If we use the deinition in @@ -24,7 +56,6 @@ extern "C" { backwards compatible solution */ #define _PyObject_HEAD_INIT(type) \ { \ - _PyObject_EXTRA_INIT \ .ob_refcnt = _Py_IMMORTAL_REFCNT, \ .ob_type = (type) \ }, @@ -34,7 +65,7 @@ extern "C" { .ob_size = size \ }, -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc( +extern void _Py_NO_RETURN _Py_FatalRefcountErrorFunc( const char *func, const char *message); @@ -135,8 +166,8 @@ _Py_DECREF_NO_DEALLOC(PyObject *op) #endif -PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); -PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); +extern int _PyType_CheckConsistency(PyTypeObject *type); +extern int _PyDict_CheckConsistency(PyObject *mp, int check_content); /* Update the Python traceback of an object. This function must be called when a memory block is reused from a free list. @@ -152,6 +183,9 @@ _PyType_HasFeature(PyTypeObject *type, unsigned long feature) { extern void _PyType_InitCache(PyInterpreterState *interp); +extern PyStatus _PyObject_InitState(PyInterpreterState *interp); +extern void _PyObject_FiniState(PyInterpreterState *interp); +extern bool _PyRefchain_IsTraced(PyInterpreterState *interp, PyObject *obj); /* Inline functions trading binary compatibility for speed: _PyObject_Init() is the fast version of PyObject_Init(), and @@ -270,9 +304,9 @@ extern void _PyDebug_PrintTotalRefs(void); #endif #ifdef Py_TRACE_REFS -extern void _Py_AddToAllObjects(PyObject *op, int force); -extern void _Py_PrintReferences(FILE *); -extern void _Py_PrintReferenceAddresses(FILE *); +extern void _Py_AddToAllObjects(PyObject *op); +extern void _Py_PrintReferences(PyInterpreterState *, FILE *); +extern void _Py_PrintReferenceAddresses(PyInterpreterState *, FILE *); #endif @@ -355,7 +389,11 @@ static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) { } extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems); -PyObject *_PyType_NewManagedObject(PyTypeObject *type); +extern PyObject *_PyType_NewManagedObject(PyTypeObject *type); + +extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); +extern PyObject* _PyType_GetDocFromInternalDoc(const char *, const char *); +extern PyObject* _PyType_GetTextSignatureFromInternalDoc(const char *, const char *, int); extern int _PyObject_InitializeDict(PyObject *obj); int _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp); @@ -409,7 +447,17 @@ extern PyObject ** _PyObject_ComputedDictPointer(PyObject *); extern void _PyObject_FreeInstanceAttributes(PyObject *obj); extern int _PyObject_IsInstanceDictEmpty(PyObject *); -PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *); +// Export for 'math' shared extension +PyAPI_FUNC(PyObject*) _PyObject_LookupSpecial(PyObject *, PyObject *); + +extern int _PyObject_IsAbstract(PyObject *); + +extern int _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); +extern PyObject* _PyObject_NextNotImplemented(PyObject *); + +// Pickle support. +// Export for '_datetime' shared extension +PyAPI_FUNC(PyObject*) _PyObject_GetState(PyObject *); /* C function call trampolines to mitigate bad function pointer casts. * @@ -438,6 +486,14 @@ extern PyObject* _PyCFunctionWithKeywords_TrampolineCall( (meth)((self), (args), (kw)) #endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE +// Export these 2 symbols for '_pickle' shared extension +PyAPI_DATA(PyTypeObject) _PyNone_Type; +PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type; + +// Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. +// Export for the stable ABI. +PyAPI_DATA(int) _Py_SwappedOp[]; + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_object_state.h b/Include/internal/pycore_object_state.h index 94005d77881432..9eac27b1a9a4e3 100644 --- a/Include/internal/pycore_object_state.h +++ b/Include/internal/pycore_object_state.h @@ -8,20 +8,26 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_hashtable.h" // _Py_hashtable_t + struct _py_object_runtime_state { #ifdef Py_REF_DEBUG Py_ssize_t interpreter_leaks; -#else - int _not_used; #endif + int _not_used; }; struct _py_object_state { #ifdef Py_REF_DEBUG Py_ssize_t reftotal; -#else - int _not_used; #endif +#ifdef Py_TRACE_REFS + // Hash table storing all objects. The key is the object pointer + // (PyObject*) and the value is always the number 1 (as uintptr_t). + // See _PyRefchain_IsTraced() and _PyRefchain_Trace() functions. + _Py_hashtable_t *refchain; +#endif + int _not_used; }; diff --git a/Include/internal/pycore_obmalloc.h b/Include/internal/pycore_obmalloc.h index ca2a0419b4f038..b0dbf53d4e3d15 100644 --- a/Include/internal/pycore_obmalloc.h +++ b/Include/internal/pycore_obmalloc.h @@ -687,7 +687,7 @@ extern void _PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *); #ifdef WITH_PYMALLOC -// Export the symbol for the 3rd party guppy3 project +// Export the symbol for the 3rd party 'guppy3' project PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); #endif diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h deleted file mode 100644 index d7f6b84e95c4f8..00000000000000 --- a/Include/internal/pycore_opcode.h +++ /dev/null @@ -1,580 +0,0 @@ -// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py - -#ifndef Py_INTERNAL_OPCODE_H -#define Py_INTERNAL_OPCODE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "opcode.h" - -extern const uint8_t _PyOpcode_Caches[256]; - -extern const uint8_t _PyOpcode_Deopt[256]; - -#ifdef NEED_OPCODE_TABLES - -const uint8_t _PyOpcode_Caches[256] = { - [TO_BOOL] = 3, - [BINARY_SUBSCR] = 1, - [STORE_SUBSCR] = 1, - [UNPACK_SEQUENCE] = 1, - [FOR_ITER] = 1, - [STORE_ATTR] = 4, - [LOAD_ATTR] = 9, - [COMPARE_OP] = 1, - [LOAD_GLOBAL] = 4, - [BINARY_OP] = 1, - [SEND] = 1, - [JUMP_BACKWARD] = 1, - [LOAD_SUPER_ATTR] = 1, - [CALL] = 3, -}; - -const uint8_t _PyOpcode_Deopt[256] = { - [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, - [BEFORE_WITH] = BEFORE_WITH, - [BINARY_OP] = BINARY_OP, - [BINARY_OP_ADD_FLOAT] = BINARY_OP, - [BINARY_OP_ADD_INT] = BINARY_OP, - [BINARY_OP_ADD_UNICODE] = BINARY_OP, - [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP, - [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP, - [BINARY_OP_MULTIPLY_INT] = BINARY_OP, - [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, - [BINARY_OP_SUBTRACT_INT] = BINARY_OP, - [BINARY_SLICE] = BINARY_SLICE, - [BINARY_SUBSCR] = BINARY_SUBSCR, - [BINARY_SUBSCR_DICT] = BINARY_SUBSCR, - [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR, - [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR, - [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR, - [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, - [BUILD_LIST] = BUILD_LIST, - [BUILD_MAP] = BUILD_MAP, - [BUILD_SET] = BUILD_SET, - [BUILD_SLICE] = BUILD_SLICE, - [BUILD_STRING] = BUILD_STRING, - [BUILD_TUPLE] = BUILD_TUPLE, - [CACHE] = CACHE, - [CALL] = CALL, - [CALL_BOUND_METHOD_EXACT_ARGS] = CALL, - [CALL_BUILTIN_CLASS] = CALL, - [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL, - [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, - [CALL_INTRINSIC_1] = CALL_INTRINSIC_1, - [CALL_INTRINSIC_2] = CALL_INTRINSIC_2, - [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL, - [CALL_NO_KW_ALLOC_AND_ENTER_INIT] = CALL, - [CALL_NO_KW_BUILTIN_FAST] = CALL, - [CALL_NO_KW_BUILTIN_O] = CALL, - [CALL_NO_KW_ISINSTANCE] = CALL, - [CALL_NO_KW_LEN] = CALL, - [CALL_NO_KW_LIST_APPEND] = CALL, - [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL, - [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL, - [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL, - [CALL_NO_KW_STR_1] = CALL, - [CALL_NO_KW_TUPLE_1] = CALL, - [CALL_NO_KW_TYPE_1] = CALL, - [CALL_PY_EXACT_ARGS] = CALL, - [CALL_PY_WITH_DEFAULTS] = CALL, - [CHECK_EG_MATCH] = CHECK_EG_MATCH, - [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, - [CLEANUP_THROW] = CLEANUP_THROW, - [COMPARE_OP] = COMPARE_OP, - [COMPARE_OP_FLOAT] = COMPARE_OP, - [COMPARE_OP_INT] = COMPARE_OP, - [COMPARE_OP_STR] = COMPARE_OP, - [CONTAINS_OP] = CONTAINS_OP, - [CONVERT_VALUE] = CONVERT_VALUE, - [COPY] = COPY, - [COPY_FREE_VARS] = COPY_FREE_VARS, - [DELETE_ATTR] = DELETE_ATTR, - [DELETE_DEREF] = DELETE_DEREF, - [DELETE_FAST] = DELETE_FAST, - [DELETE_GLOBAL] = DELETE_GLOBAL, - [DELETE_NAME] = DELETE_NAME, - [DELETE_SUBSCR] = DELETE_SUBSCR, - [DICT_MERGE] = DICT_MERGE, - [DICT_UPDATE] = DICT_UPDATE, - [END_ASYNC_FOR] = END_ASYNC_FOR, - [END_FOR] = END_FOR, - [END_SEND] = END_SEND, - [ENTER_EXECUTOR] = ENTER_EXECUTOR, - [EXIT_INIT_CHECK] = EXIT_INIT_CHECK, - [EXTENDED_ARG] = EXTENDED_ARG, - [FORMAT_SIMPLE] = FORMAT_SIMPLE, - [FORMAT_WITH_SPEC] = FORMAT_WITH_SPEC, - [FOR_ITER] = FOR_ITER, - [FOR_ITER_GEN] = FOR_ITER, - [FOR_ITER_LIST] = FOR_ITER, - [FOR_ITER_RANGE] = FOR_ITER, - [FOR_ITER_TUPLE] = FOR_ITER, - [GET_AITER] = GET_AITER, - [GET_ANEXT] = GET_ANEXT, - [GET_AWAITABLE] = GET_AWAITABLE, - [GET_ITER] = GET_ITER, - [GET_LEN] = GET_LEN, - [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, - [IMPORT_FROM] = IMPORT_FROM, - [IMPORT_NAME] = IMPORT_NAME, - [INSTRUMENTED_CALL] = INSTRUMENTED_CALL, - [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, - [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR, - [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND, - [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER, - [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION, - [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD, - [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD, - [INSTRUMENTED_LINE] = INSTRUMENTED_LINE, - [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, - [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE, - [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE, - [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE, - [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE, - [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME, - [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST, - [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, - [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, - [INTERPRETER_EXIT] = INTERPRETER_EXIT, - [IS_OP] = IS_OP, - [JUMP_BACKWARD] = JUMP_BACKWARD, - [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, - [JUMP_FORWARD] = JUMP_FORWARD, - [KW_NAMES] = KW_NAMES, - [LIST_APPEND] = LIST_APPEND, - [LIST_EXTEND] = LIST_EXTEND, - [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, - [LOAD_ATTR] = LOAD_ATTR, - [LOAD_ATTR_CLASS] = LOAD_ATTR, - [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR, - [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, - [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, - [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, - [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, - [LOAD_ATTR_MODULE] = LOAD_ATTR, - [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR, - [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR, - [LOAD_ATTR_PROPERTY] = LOAD_ATTR, - [LOAD_ATTR_SLOT] = LOAD_ATTR, - [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, - [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, - [LOAD_CONST] = LOAD_CONST, - [LOAD_DEREF] = LOAD_DEREF, - [LOAD_FAST] = LOAD_FAST, - [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR, - [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, - [LOAD_FAST_LOAD_FAST] = LOAD_FAST_LOAD_FAST, - [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF, - [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS, - [LOAD_GLOBAL] = LOAD_GLOBAL, - [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, - [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, - [LOAD_LOCALS] = LOAD_LOCALS, - [LOAD_NAME] = LOAD_NAME, - [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR, - [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR, - [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR, - [MAKE_CELL] = MAKE_CELL, - [MAKE_FUNCTION] = MAKE_FUNCTION, - [MAP_ADD] = MAP_ADD, - [MATCH_CLASS] = MATCH_CLASS, - [MATCH_KEYS] = MATCH_KEYS, - [MATCH_MAPPING] = MATCH_MAPPING, - [MATCH_SEQUENCE] = MATCH_SEQUENCE, - [NOP] = NOP, - [POP_EXCEPT] = POP_EXCEPT, - [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE, - [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE, - [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE, - [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE, - [POP_TOP] = POP_TOP, - [PUSH_EXC_INFO] = PUSH_EXC_INFO, - [PUSH_NULL] = PUSH_NULL, - [RAISE_VARARGS] = RAISE_VARARGS, - [RERAISE] = RERAISE, - [RESERVED] = RESERVED, - [RESUME] = RESUME, - [RETURN_CONST] = RETURN_CONST, - [RETURN_GENERATOR] = RETURN_GENERATOR, - [RETURN_VALUE] = RETURN_VALUE, - [SEND] = SEND, - [SEND_GEN] = SEND, - [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, - [SET_ADD] = SET_ADD, - [SET_FUNCTION_ATTRIBUTE] = SET_FUNCTION_ATTRIBUTE, - [SET_UPDATE] = SET_UPDATE, - [STORE_ATTR] = STORE_ATTR, - [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, - [STORE_ATTR_SLOT] = STORE_ATTR, - [STORE_ATTR_WITH_HINT] = STORE_ATTR, - [STORE_DEREF] = STORE_DEREF, - [STORE_FAST] = STORE_FAST, - [STORE_FAST_LOAD_FAST] = STORE_FAST_LOAD_FAST, - [STORE_FAST_STORE_FAST] = STORE_FAST_STORE_FAST, - [STORE_GLOBAL] = STORE_GLOBAL, - [STORE_NAME] = STORE_NAME, - [STORE_SLICE] = STORE_SLICE, - [STORE_SUBSCR] = STORE_SUBSCR, - [STORE_SUBSCR_DICT] = STORE_SUBSCR, - [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, - [SWAP] = SWAP, - [TO_BOOL] = TO_BOOL, - [TO_BOOL_ALWAYS_TRUE] = TO_BOOL, - [TO_BOOL_BOOL] = TO_BOOL, - [TO_BOOL_INT] = TO_BOOL, - [TO_BOOL_LIST] = TO_BOOL, - [TO_BOOL_NONE] = TO_BOOL, - [TO_BOOL_STR] = TO_BOOL, - [UNARY_INVERT] = UNARY_INVERT, - [UNARY_NEGATIVE] = UNARY_NEGATIVE, - [UNARY_NOT] = UNARY_NOT, - [UNPACK_EX] = UNPACK_EX, - [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, - [WITH_EXCEPT_START] = WITH_EXCEPT_START, - [YIELD_VALUE] = YIELD_VALUE, -}; -#endif // NEED_OPCODE_TABLES - - -extern const char *const _PyOpcode_OpName[268]; - -#ifdef NEED_OPCODE_TABLES -const char *const _PyOpcode_OpName[268] = { - [CACHE] = "CACHE", - [POP_TOP] = "POP_TOP", - [PUSH_NULL] = "PUSH_NULL", - [INTERPRETER_EXIT] = "INTERPRETER_EXIT", - [END_FOR] = "END_FOR", - [END_SEND] = "END_SEND", - [TO_BOOL] = "TO_BOOL", - [TO_BOOL_ALWAYS_TRUE] = "TO_BOOL_ALWAYS_TRUE", - [TO_BOOL_BOOL] = "TO_BOOL_BOOL", - [NOP] = "NOP", - [TO_BOOL_INT] = "TO_BOOL_INT", - [UNARY_NEGATIVE] = "UNARY_NEGATIVE", - [UNARY_NOT] = "UNARY_NOT", - [TO_BOOL_LIST] = "TO_BOOL_LIST", - [TO_BOOL_NONE] = "TO_BOOL_NONE", - [UNARY_INVERT] = "UNARY_INVERT", - [EXIT_INIT_CHECK] = "EXIT_INIT_CHECK", - [RESERVED] = "RESERVED", - [TO_BOOL_STR] = "TO_BOOL_STR", - [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT", - [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", - [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT", - [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT", - [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", - [MAKE_FUNCTION] = "MAKE_FUNCTION", - [BINARY_SUBSCR] = "BINARY_SUBSCR", - [BINARY_SLICE] = "BINARY_SLICE", - [STORE_SLICE] = "STORE_SLICE", - [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT", - [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE", - [GET_LEN] = "GET_LEN", - [MATCH_MAPPING] = "MATCH_MAPPING", - [MATCH_SEQUENCE] = "MATCH_SEQUENCE", - [MATCH_KEYS] = "MATCH_KEYS", - [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE", - [PUSH_EXC_INFO] = "PUSH_EXC_INFO", - [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH", - [CHECK_EG_MATCH] = "CHECK_EG_MATCH", - [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT", - [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM", - [FORMAT_SIMPLE] = "FORMAT_SIMPLE", - [FORMAT_WITH_SPEC] = "FORMAT_WITH_SPEC", - [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT", - [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT", - [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", - [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", - [SEND_GEN] = "SEND_GEN", - [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", - [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", - [WITH_EXCEPT_START] = "WITH_EXCEPT_START", - [GET_AITER] = "GET_AITER", - [GET_ANEXT] = "GET_ANEXT", - [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", - [BEFORE_WITH] = "BEFORE_WITH", - [END_ASYNC_FOR] = "END_ASYNC_FOR", - [CLEANUP_THROW] = "CLEANUP_THROW", - [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", - [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", - [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", - [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", - [STORE_SUBSCR] = "STORE_SUBSCR", - [DELETE_SUBSCR] = "DELETE_SUBSCR", - [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", - [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", - [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR", - [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD", - [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", - [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", - [GET_ITER] = "GET_ITER", - [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", - [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", - [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", - [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", - [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", - [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", - [RETURN_GENERATOR] = "RETURN_GENERATOR", - [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", - [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", - [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", - [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", - [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", - [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", - [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT", - [RETURN_VALUE] = "RETURN_VALUE", - [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT", - [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [COMPARE_OP_INT] = "COMPARE_OP_INT", - [LOAD_LOCALS] = "LOAD_LOCALS", - [COMPARE_OP_STR] = "COMPARE_OP_STR", - [POP_EXCEPT] = "POP_EXCEPT", - [STORE_NAME] = "STORE_NAME", - [DELETE_NAME] = "DELETE_NAME", - [UNPACK_SEQUENCE] = "UNPACK_SEQUENCE", - [FOR_ITER] = "FOR_ITER", - [UNPACK_EX] = "UNPACK_EX", - [STORE_ATTR] = "STORE_ATTR", - [DELETE_ATTR] = "DELETE_ATTR", - [STORE_GLOBAL] = "STORE_GLOBAL", - [DELETE_GLOBAL] = "DELETE_GLOBAL", - [SWAP] = "SWAP", - [LOAD_CONST] = "LOAD_CONST", - [LOAD_NAME] = "LOAD_NAME", - [BUILD_TUPLE] = "BUILD_TUPLE", - [BUILD_LIST] = "BUILD_LIST", - [BUILD_SET] = "BUILD_SET", - [BUILD_MAP] = "BUILD_MAP", - [LOAD_ATTR] = "LOAD_ATTR", - [COMPARE_OP] = "COMPARE_OP", - [IMPORT_NAME] = "IMPORT_NAME", - [IMPORT_FROM] = "IMPORT_FROM", - [JUMP_FORWARD] = "JUMP_FORWARD", - [FOR_ITER_LIST] = "FOR_ITER_LIST", - [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE", - [FOR_ITER_RANGE] = "FOR_ITER_RANGE", - [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE", - [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE", - [LOAD_GLOBAL] = "LOAD_GLOBAL", - [IS_OP] = "IS_OP", - [CONTAINS_OP] = "CONTAINS_OP", - [RERAISE] = "RERAISE", - [COPY] = "COPY", - [RETURN_CONST] = "RETURN_CONST", - [BINARY_OP] = "BINARY_OP", - [SEND] = "SEND", - [LOAD_FAST] = "LOAD_FAST", - [STORE_FAST] = "STORE_FAST", - [DELETE_FAST] = "DELETE_FAST", - [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK", - [POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE", - [POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE", - [RAISE_VARARGS] = "RAISE_VARARGS", - [GET_AWAITABLE] = "GET_AWAITABLE", - [FOR_ITER_GEN] = "FOR_ITER_GEN", - [BUILD_SLICE] = "BUILD_SLICE", - [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT", - [MAKE_CELL] = "MAKE_CELL", - [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS", - [LOAD_DEREF] = "LOAD_DEREF", - [STORE_DEREF] = "STORE_DEREF", - [DELETE_DEREF] = "DELETE_DEREF", - [JUMP_BACKWARD] = "JUMP_BACKWARD", - [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR", - [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", - [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR", - [EXTENDED_ARG] = "EXTENDED_ARG", - [LIST_APPEND] = "LIST_APPEND", - [SET_ADD] = "SET_ADD", - [MAP_ADD] = "MAP_ADD", - [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", - [COPY_FREE_VARS] = "COPY_FREE_VARS", - [YIELD_VALUE] = "YIELD_VALUE", - [RESUME] = "RESUME", - [MATCH_CLASS] = "MATCH_CLASS", - [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", - [CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1", - [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1", - [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", - [BUILD_STRING] = "BUILD_STRING", - [CONVERT_VALUE] = "CONVERT_VALUE", - [CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1", - [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS", - [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O", - [LIST_EXTEND] = "LIST_EXTEND", - [SET_UPDATE] = "SET_UPDATE", - [DICT_MERGE] = "DICT_MERGE", - [DICT_UPDATE] = "DICT_UPDATE", - [CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST", - [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS", - [LOAD_FAST_LOAD_FAST] = "LOAD_FAST_LOAD_FAST", - [STORE_FAST_LOAD_FAST] = "STORE_FAST_LOAD_FAST", - [STORE_FAST_STORE_FAST] = "STORE_FAST_STORE_FAST", - [CALL] = "CALL", - [KW_NAMES] = "KW_NAMES", - [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1", - [CALL_INTRINSIC_2] = "CALL_INTRINSIC_2", - [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS", - [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF", - [SET_FUNCTION_ATTRIBUTE] = "SET_FUNCTION_ATTRIBUTE", - [CALL_NO_KW_LEN] = "CALL_NO_KW_LEN", - [CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE", - [CALL_NO_KW_LIST_APPEND] = "CALL_NO_KW_LIST_APPEND", - [CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O", - [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", - [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", - [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "CALL_NO_KW_METHOD_DESCRIPTOR_FAST", - [CALL_NO_KW_ALLOC_AND_ENTER_INIT] = "CALL_NO_KW_ALLOC_AND_ENTER_INIT", - [186] = "<186>", - [187] = "<187>", - [188] = "<188>", - [189] = "<189>", - [190] = "<190>", - [191] = "<191>", - [192] = "<192>", - [193] = "<193>", - [194] = "<194>", - [195] = "<195>", - [196] = "<196>", - [197] = "<197>", - [198] = "<198>", - [199] = "<199>", - [200] = "<200>", - [201] = "<201>", - [202] = "<202>", - [203] = "<203>", - [204] = "<204>", - [205] = "<205>", - [206] = "<206>", - [207] = "<207>", - [208] = "<208>", - [209] = "<209>", - [210] = "<210>", - [211] = "<211>", - [212] = "<212>", - [213] = "<213>", - [214] = "<214>", - [215] = "<215>", - [216] = "<216>", - [217] = "<217>", - [218] = "<218>", - [219] = "<219>", - [220] = "<220>", - [221] = "<221>", - [222] = "<222>", - [223] = "<223>", - [224] = "<224>", - [225] = "<225>", - [226] = "<226>", - [227] = "<227>", - [228] = "<228>", - [229] = "<229>", - [ENTER_EXECUTOR] = "ENTER_EXECUTOR", - [231] = "<231>", - [232] = "<232>", - [233] = "<233>", - [234] = "<234>", - [235] = "<235>", - [236] = "<236>", - [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR", - [INSTRUMENTED_POP_JUMP_IF_NONE] = "INSTRUMENTED_POP_JUMP_IF_NONE", - [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE", - [INSTRUMENTED_RESUME] = "INSTRUMENTED_RESUME", - [INSTRUMENTED_CALL] = "INSTRUMENTED_CALL", - [INSTRUMENTED_RETURN_VALUE] = "INSTRUMENTED_RETURN_VALUE", - [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE", - [INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX", - [INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD", - [INSTRUMENTED_JUMP_BACKWARD] = "INSTRUMENTED_JUMP_BACKWARD", - [INSTRUMENTED_RETURN_CONST] = "INSTRUMENTED_RETURN_CONST", - [INSTRUMENTED_FOR_ITER] = "INSTRUMENTED_FOR_ITER", - [INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE", - [INSTRUMENTED_POP_JUMP_IF_TRUE] = "INSTRUMENTED_POP_JUMP_IF_TRUE", - [INSTRUMENTED_END_FOR] = "INSTRUMENTED_END_FOR", - [INSTRUMENTED_END_SEND] = "INSTRUMENTED_END_SEND", - [INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION", - [INSTRUMENTED_LINE] = "INSTRUMENTED_LINE", - [255] = "<255>", - [SETUP_FINALLY] = "SETUP_FINALLY", - [SETUP_CLEANUP] = "SETUP_CLEANUP", - [SETUP_WITH] = "SETUP_WITH", - [POP_BLOCK] = "POP_BLOCK", - [JUMP] = "JUMP", - [JUMP_NO_INTERRUPT] = "JUMP_NO_INTERRUPT", - [LOAD_METHOD] = "LOAD_METHOD", - [LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD", - [LOAD_ZERO_SUPER_METHOD] = "LOAD_ZERO_SUPER_METHOD", - [LOAD_ZERO_SUPER_ATTR] = "LOAD_ZERO_SUPER_ATTR", - [STORE_FAST_MAYBE_NULL] = "STORE_FAST_MAYBE_NULL", - [LOAD_CLOSURE] = "LOAD_CLOSURE", -}; -#endif // NEED_OPCODE_TABLES - -#define EXTRA_CASES \ - case 186: \ - case 187: \ - case 188: \ - case 189: \ - case 190: \ - case 191: \ - case 192: \ - case 193: \ - case 194: \ - case 195: \ - case 196: \ - case 197: \ - case 198: \ - case 199: \ - case 200: \ - case 201: \ - case 202: \ - case 203: \ - case 204: \ - case 205: \ - case 206: \ - case 207: \ - case 208: \ - case 209: \ - case 210: \ - case 211: \ - case 212: \ - case 213: \ - case 214: \ - case 215: \ - case 216: \ - case 217: \ - case 218: \ - case 219: \ - case 220: \ - case 221: \ - case 222: \ - case 223: \ - case 224: \ - case 225: \ - case 226: \ - case 227: \ - case 228: \ - case 229: \ - case 231: \ - case 232: \ - case 233: \ - case 234: \ - case 235: \ - case 236: \ - case 255: \ - ; - -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_OPCODE_H diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index d525913f8a7aba..926c0041c34c28 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -3,7 +3,11 @@ // Python/bytecodes.c // Do not edit! -#include +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include // bool #define IS_PSEUDO_INSTR(OP) ( \ @@ -21,8 +25,8 @@ ((OP) == POP_BLOCK) || \ 0) -#define EXIT_TRACE 300 -#define SAVE_IP 301 +#define _EXIT_TRACE 300 +#define _SET_IP 301 #define _GUARD_BOTH_INT 302 #define _BINARY_OP_MULTIPLY_INT 303 #define _BINARY_OP_ADD_INT 304 @@ -33,40 +37,69 @@ #define _BINARY_OP_SUBTRACT_FLOAT 309 #define _GUARD_BOTH_UNICODE 310 #define _BINARY_OP_ADD_UNICODE 311 -#define _LOAD_LOCALS 312 -#define _LOAD_FROM_DICT_OR_GLOBALS 313 -#define _SKIP_CACHE 314 -#define _GUARD_GLOBALS_VERSION 315 -#define _GUARD_BUILTINS_VERSION 316 -#define _LOAD_GLOBAL_MODULE 317 -#define _LOAD_GLOBAL_BUILTINS 318 -#define _GUARD_TYPE_VERSION 319 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES 320 -#define _LOAD_ATTR_INSTANCE_VALUE 321 -#define IS_NONE 322 -#define _ITER_CHECK_LIST 323 -#define _IS_ITER_EXHAUSTED_LIST 324 -#define _ITER_NEXT_LIST 325 -#define _ITER_CHECK_TUPLE 326 -#define _IS_ITER_EXHAUSTED_TUPLE 327 -#define _ITER_NEXT_TUPLE 328 -#define _ITER_CHECK_RANGE 329 -#define _IS_ITER_EXHAUSTED_RANGE 330 -#define _ITER_NEXT_RANGE 331 -#define _POP_JUMP_IF_FALSE 332 -#define _POP_JUMP_IF_TRUE 333 -#define JUMP_TO_TOP 334 +#define _BINARY_OP_INPLACE_ADD_UNICODE 312 +#define _POP_FRAME 313 +#define _GUARD_GLOBALS_VERSION 314 +#define _GUARD_BUILTINS_VERSION 315 +#define _LOAD_GLOBAL_MODULE 316 +#define _LOAD_GLOBAL_BUILTINS 317 +#define _GUARD_TYPE_VERSION 318 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES 319 +#define _LOAD_ATTR_INSTANCE_VALUE 320 +#define _CHECK_ATTR_MODULE 321 +#define _LOAD_ATTR_MODULE 322 +#define _CHECK_ATTR_WITH_HINT 323 +#define _LOAD_ATTR_WITH_HINT 324 +#define _LOAD_ATTR_SLOT 325 +#define _CHECK_ATTR_CLASS 326 +#define _LOAD_ATTR_CLASS 327 +#define _GUARD_DORV_VALUES 328 +#define _STORE_ATTR_INSTANCE_VALUE 329 +#define _STORE_ATTR_SLOT 330 +#define _IS_NONE 331 +#define _ITER_CHECK_LIST 332 +#define _ITER_JUMP_LIST 333 +#define _IS_ITER_EXHAUSTED_LIST 334 +#define _ITER_NEXT_LIST 335 +#define _ITER_CHECK_TUPLE 336 +#define _ITER_JUMP_TUPLE 337 +#define _IS_ITER_EXHAUSTED_TUPLE 338 +#define _ITER_NEXT_TUPLE 339 +#define _ITER_CHECK_RANGE 340 +#define _ITER_JUMP_RANGE 341 +#define _IS_ITER_EXHAUSTED_RANGE 342 +#define _ITER_NEXT_RANGE 343 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 344 +#define _GUARD_KEYS_VERSION 345 +#define _LOAD_ATTR_METHOD_WITH_VALUES 346 +#define _LOAD_ATTR_METHOD_NO_DICT 347 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 348 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 349 +#define _CHECK_ATTR_METHOD_LAZY_DICT 350 +#define _LOAD_ATTR_METHOD_LAZY_DICT 351 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 352 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 353 +#define _CHECK_PEP_523 354 +#define _CHECK_FUNCTION_EXACT_ARGS 355 +#define _CHECK_STACK_SPACE 356 +#define _INIT_CALL_PY_EXACT_ARGS 357 +#define _PUSH_FRAME 358 +#define _POP_JUMP_IF_FALSE 359 +#define _POP_JUMP_IF_TRUE 360 +#define _JUMP_TO_TOP 361 +#define _SAVE_CURRENT_IP 362 +#define _INSERT 363 -#ifndef NEED_OPCODE_METADATA extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump); -#else -int -_PyOpcode_num_popped(int opcode, int oparg, bool jump) { +#ifdef NEED_OPCODE_METADATA +int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { switch(opcode) { case NOP: return 0; case RESUME: return 0; + case RESUME_CHECK: + return 0; case INSTRUMENTED_RESUME: return 0; case LOAD_CLOSURE: @@ -121,20 +154,42 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case UNARY_INVERT: return 1; + case _GUARD_BOTH_INT: + return 2; + case _BINARY_OP_MULTIPLY_INT: + return 2; + case _BINARY_OP_ADD_INT: + return 2; + case _BINARY_OP_SUBTRACT_INT: + return 2; case BINARY_OP_MULTIPLY_INT: return 2; case BINARY_OP_ADD_INT: return 2; case BINARY_OP_SUBTRACT_INT: return 2; + case _GUARD_BOTH_FLOAT: + return 2; + case _BINARY_OP_MULTIPLY_FLOAT: + return 2; + case _BINARY_OP_ADD_FLOAT: + return 2; + case _BINARY_OP_SUBTRACT_FLOAT: + return 2; case BINARY_OP_MULTIPLY_FLOAT: return 2; case BINARY_OP_ADD_FLOAT: return 2; case BINARY_OP_SUBTRACT_FLOAT: return 2; + case _GUARD_BOTH_UNICODE: + return 2; + case _BINARY_OP_ADD_UNICODE: + return 2; case BINARY_OP_ADD_UNICODE: return 2; + case _BINARY_OP_INPLACE_ADD_UNICODE: + return 2; case BINARY_OP_INPLACE_ADD_UNICODE: return 2; case BINARY_SUBSCR: @@ -145,6 +200,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 4; case BINARY_SUBSCR_LIST_INT: return 2; + case BINARY_SUBSCR_STR_INT: + return 2; case BINARY_SUBSCR_TUPLE_INT: return 2; case BINARY_SUBSCR_DICT: @@ -171,6 +228,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return oparg; case INTERPRETER_EXIT: return 1; + case _POP_FRAME: + return 1; case RETURN_VALUE: return 1; case INSTRUMENTED_RETURN_VALUE: @@ -229,12 +288,20 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 0; case LOAD_LOCALS: return 0; - case LOAD_NAME: - return 0; case LOAD_FROM_DICT_OR_GLOBALS: return 1; + case LOAD_NAME: + return 0; case LOAD_GLOBAL: return 0; + case _GUARD_GLOBALS_VERSION: + return 0; + case _GUARD_BUILTINS_VERSION: + return 0; + case _LOAD_GLOBAL_MODULE: + return 0; + case _LOAD_GLOBAL_BUILTINS: + return 0; case LOAD_GLOBAL_MODULE: return 0; case LOAD_GLOBAL_BUILTIN: @@ -272,11 +339,11 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { case BUILD_CONST_KEY_MAP: return oparg + 1; case DICT_UPDATE: - return 1; + return (oparg - 1) + 2; case DICT_MERGE: - return 1; + return (oparg - 1) + 5; case MAP_ADD: - return 2; + return (oparg - 1) + 3; case INSTRUMENTED_LOAD_SUPER_ATTR: return 3; case LOAD_SUPER_ATTR: @@ -295,24 +362,50 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case LOAD_METHOD: return 1; + case _GUARD_TYPE_VERSION: + return 1; + case _CHECK_MANAGED_OBJECT_HAS_VALUES: + return 1; + case _LOAD_ATTR_INSTANCE_VALUE: + return 1; case LOAD_ATTR_INSTANCE_VALUE: return 1; + case _CHECK_ATTR_MODULE: + return 1; + case _LOAD_ATTR_MODULE: + return 1; case LOAD_ATTR_MODULE: return 1; + case _CHECK_ATTR_WITH_HINT: + return 1; + case _LOAD_ATTR_WITH_HINT: + return 1; case LOAD_ATTR_WITH_HINT: return 1; + case _LOAD_ATTR_SLOT: + return 1; case LOAD_ATTR_SLOT: return 1; + case _CHECK_ATTR_CLASS: + return 1; + case _LOAD_ATTR_CLASS: + return 1; case LOAD_ATTR_CLASS: return 1; case LOAD_ATTR_PROPERTY: return 1; case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: return 1; + case _GUARD_DORV_VALUES: + return 1; + case _STORE_ATTR_INSTANCE_VALUE: + return 2; case STORE_ATTR_INSTANCE_VALUE: return 2; case STORE_ATTR_WITH_HINT: return 2; + case _STORE_ATTR_SLOT: + return 2; case STORE_ATTR_SLOT: return 2; case COMPARE_OP: @@ -349,6 +442,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case POP_JUMP_IF_TRUE: return 1; + case _IS_NONE: + return 1; case POP_JUMP_IF_NONE: return 1; case POP_JUMP_IF_NOT_NONE: @@ -373,10 +468,34 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case INSTRUMENTED_FOR_ITER: return 0; + case _ITER_CHECK_LIST: + return 1; + case _ITER_JUMP_LIST: + return 1; + case _IS_ITER_EXHAUSTED_LIST: + return 1; + case _ITER_NEXT_LIST: + return 1; case FOR_ITER_LIST: return 1; + case _ITER_CHECK_TUPLE: + return 1; + case _ITER_JUMP_TUPLE: + return 1; + case _IS_ITER_EXHAUSTED_TUPLE: + return 1; + case _ITER_NEXT_TUPLE: + return 1; case FOR_ITER_TUPLE: return 1; + case _ITER_CHECK_RANGE: + return 1; + case _ITER_JUMP_RANGE: + return 1; + case _IS_ITER_EXHAUSTED_RANGE: + return 1; + case _ITER_NEXT_RANGE: + return 1; case FOR_ITER_RANGE: return 1; case FOR_ITER_GEN: @@ -397,60 +516,92 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 0; case PUSH_EXC_INFO: return 1; + case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT: + return 1; + case _GUARD_KEYS_VERSION: + return 1; + case _LOAD_ATTR_METHOD_WITH_VALUES: + return 1; case LOAD_ATTR_METHOD_WITH_VALUES: return 1; + case _LOAD_ATTR_METHOD_NO_DICT: + return 1; case LOAD_ATTR_METHOD_NO_DICT: return 1; + case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: + return 1; case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: return 1; + case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: + return 1; case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: return 1; + case _CHECK_ATTR_METHOD_LAZY_DICT: + return 1; + case _LOAD_ATTR_METHOD_LAZY_DICT: + return 1; case LOAD_ATTR_METHOD_LAZY_DICT: return 1; - case KW_NAMES: - return 0; case INSTRUMENTED_CALL: return 0; case CALL: return oparg + 2; + case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: + return oparg + 2; + case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: + return oparg + 2; + case _CHECK_PEP_523: + return 0; + case _CHECK_FUNCTION_EXACT_ARGS: + return oparg + 2; + case _CHECK_STACK_SPACE: + return oparg + 2; + case _INIT_CALL_PY_EXACT_ARGS: + return oparg + 2; + case _PUSH_FRAME: + return 1; case CALL_BOUND_METHOD_EXACT_ARGS: return oparg + 2; case CALL_PY_EXACT_ARGS: return oparg + 2; case CALL_PY_WITH_DEFAULTS: return oparg + 2; - case CALL_NO_KW_TYPE_1: + case CALL_TYPE_1: return oparg + 2; - case CALL_NO_KW_STR_1: + case CALL_STR_1: return oparg + 2; - case CALL_NO_KW_TUPLE_1: + case CALL_TUPLE_1: return oparg + 2; - case CALL_NO_KW_ALLOC_AND_ENTER_INIT: + case CALL_ALLOC_AND_ENTER_INIT: return oparg + 2; case EXIT_INIT_CHECK: return 1; case CALL_BUILTIN_CLASS: return oparg + 2; - case CALL_NO_KW_BUILTIN_O: + case CALL_BUILTIN_O: return oparg + 2; - case CALL_NO_KW_BUILTIN_FAST: + case CALL_BUILTIN_FAST: return oparg + 2; case CALL_BUILTIN_FAST_WITH_KEYWORDS: return oparg + 2; - case CALL_NO_KW_LEN: + case CALL_LEN: return oparg + 2; - case CALL_NO_KW_ISINSTANCE: + case CALL_ISINSTANCE: return oparg + 2; - case CALL_NO_KW_LIST_APPEND: + case CALL_LIST_APPEND: return oparg + 2; - case CALL_NO_KW_METHOD_DESCRIPTOR_O: + case CALL_METHOD_DESCRIPTOR_O: return oparg + 2; case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: return oparg + 2; - case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: + case CALL_METHOD_DESCRIPTOR_NOARGS: return oparg + 2; - case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: + case CALL_METHOD_DESCRIPTOR_FAST: return oparg + 2; + case INSTRUMENTED_CALL_KW: + return 0; + case CALL_KW: + return oparg + 3; case INSTRUMENTED_CALL_FUNCTION_EX: return 0; case CALL_FUNCTION_EX: @@ -495,22 +646,36 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 0; case RESERVED: return 0; + case _POP_JUMP_IF_FALSE: + return 1; + case _POP_JUMP_IF_TRUE: + return 1; + case _JUMP_TO_TOP: + return 0; + case _SET_IP: + return 0; + case _SAVE_CURRENT_IP: + return 0; + case _EXIT_TRACE: + return 0; + case _INSERT: + return oparg + 1; default: return -1; } } -#endif +#endif // NEED_OPCODE_METADATA -#ifndef NEED_OPCODE_METADATA extern int _PyOpcode_num_pushed(int opcode, int oparg, bool jump); -#else -int -_PyOpcode_num_pushed(int opcode, int oparg, bool jump) { +#ifdef NEED_OPCODE_METADATA +int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { switch(opcode) { case NOP: return 0; case RESUME: return 0; + case RESUME_CHECK: + return 0; case INSTRUMENTED_RESUME: return 0; case LOAD_CLOSURE: @@ -565,20 +730,42 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case UNARY_INVERT: return 1; + case _GUARD_BOTH_INT: + return 2; + case _BINARY_OP_MULTIPLY_INT: + return 1; + case _BINARY_OP_ADD_INT: + return 1; + case _BINARY_OP_SUBTRACT_INT: + return 1; case BINARY_OP_MULTIPLY_INT: return 1; case BINARY_OP_ADD_INT: return 1; case BINARY_OP_SUBTRACT_INT: return 1; + case _GUARD_BOTH_FLOAT: + return 2; + case _BINARY_OP_MULTIPLY_FLOAT: + return 1; + case _BINARY_OP_ADD_FLOAT: + return 1; + case _BINARY_OP_SUBTRACT_FLOAT: + return 1; case BINARY_OP_MULTIPLY_FLOAT: return 1; case BINARY_OP_ADD_FLOAT: return 1; case BINARY_OP_SUBTRACT_FLOAT: return 1; + case _GUARD_BOTH_UNICODE: + return 2; + case _BINARY_OP_ADD_UNICODE: + return 1; case BINARY_OP_ADD_UNICODE: return 1; + case _BINARY_OP_INPLACE_ADD_UNICODE: + return 0; case BINARY_OP_INPLACE_ADD_UNICODE: return 0; case BINARY_SUBSCR: @@ -589,6 +776,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case BINARY_SUBSCR_LIST_INT: return 1; + case BINARY_SUBSCR_STR_INT: + return 1; case BINARY_SUBSCR_TUPLE_INT: return 1; case BINARY_SUBSCR_DICT: @@ -615,6 +804,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case INTERPRETER_EXIT: return 0; + case _POP_FRAME: + return 0; case RETURN_VALUE: return 0; case INSTRUMENTED_RETURN_VALUE: @@ -673,16 +864,24 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case LOAD_LOCALS: return 1; - case LOAD_NAME: - return 1; case LOAD_FROM_DICT_OR_GLOBALS: return 1; + case LOAD_NAME: + return 1; case LOAD_GLOBAL: return ((oparg & 1) ? 1 : 0) + 1; - case LOAD_GLOBAL_MODULE: + case _GUARD_GLOBALS_VERSION: + return 0; + case _GUARD_BUILTINS_VERSION: + return 0; + case _LOAD_GLOBAL_MODULE: return ((oparg & 1) ? 1 : 0) + 1; - case LOAD_GLOBAL_BUILTIN: + case _LOAD_GLOBAL_BUILTINS: return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_GLOBAL_MODULE: + return (oparg & 1 ? 1 : 0) + 1; + case LOAD_GLOBAL_BUILTIN: + return (oparg & 1 ? 1 : 0) + 1; case DELETE_FAST: return 0; case MAKE_CELL: @@ -716,11 +915,11 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case BUILD_CONST_KEY_MAP: return 1; case DICT_UPDATE: - return 0; + return (oparg - 1) + 1; case DICT_MERGE: - return 0; + return (oparg - 1) + 4; case MAP_ADD: - return 0; + return (oparg - 1) + 1; case INSTRUMENTED_LOAD_SUPER_ATTR: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_SUPER_ATTR: @@ -732,31 +931,57 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case LOAD_ZERO_SUPER_ATTR: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_SUPER_ATTR_ATTR: - return ((oparg & 1) ? 1 : 0) + 1; + return 1; case LOAD_SUPER_ATTR_METHOD: return 2; case LOAD_ATTR: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_METHOD: return ((oparg & 1) ? 1 : 0) + 1; + case _GUARD_TYPE_VERSION: + return 1; + case _CHECK_MANAGED_OBJECT_HAS_VALUES: + return 1; + case _LOAD_ATTR_INSTANCE_VALUE: + return ((oparg & 1) ? 1 : 0) + 1; case LOAD_ATTR_INSTANCE_VALUE: + return (oparg & 1 ? 1 : 0) + 1; + case _CHECK_ATTR_MODULE: + return 1; + case _LOAD_ATTR_MODULE: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_ATTR_MODULE: + return (oparg & 1 ? 1 : 0) + 1; + case _CHECK_ATTR_WITH_HINT: + return 1; + case _LOAD_ATTR_WITH_HINT: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_ATTR_WITH_HINT: + return (oparg & 1 ? 1 : 0) + 1; + case _LOAD_ATTR_SLOT: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_ATTR_SLOT: + return (oparg & 1 ? 1 : 0) + 1; + case _CHECK_ATTR_CLASS: + return 1; + case _LOAD_ATTR_CLASS: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_ATTR_CLASS: - return ((oparg & 1) ? 1 : 0) + 1; + return (oparg & 1 ? 1 : 0) + 1; case LOAD_ATTR_PROPERTY: - return ((oparg & 1) ? 1 : 0) + 1; + return 1; case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: - return ((oparg & 1) ? 1 : 0) + 1; + return 1; + case _GUARD_DORV_VALUES: + return 1; + case _STORE_ATTR_INSTANCE_VALUE: + return 0; case STORE_ATTR_INSTANCE_VALUE: return 0; case STORE_ATTR_WITH_HINT: return 0; + case _STORE_ATTR_SLOT: + return 0; case STORE_ATTR_SLOT: return 0; case COMPARE_OP: @@ -793,6 +1018,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case POP_JUMP_IF_TRUE: return 0; + case _IS_NONE: + return 1; case POP_JUMP_IF_NONE: return 0; case POP_JUMP_IF_NOT_NONE: @@ -817,10 +1044,34 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 2; case INSTRUMENTED_FOR_ITER: return 0; + case _ITER_CHECK_LIST: + return 1; + case _ITER_JUMP_LIST: + return 1; + case _IS_ITER_EXHAUSTED_LIST: + return 2; + case _ITER_NEXT_LIST: + return 2; case FOR_ITER_LIST: return 2; + case _ITER_CHECK_TUPLE: + return 1; + case _ITER_JUMP_TUPLE: + return 1; + case _IS_ITER_EXHAUSTED_TUPLE: + return 2; + case _ITER_NEXT_TUPLE: + return 2; case FOR_ITER_TUPLE: return 2; + case _ITER_CHECK_RANGE: + return 1; + case _ITER_JUMP_RANGE: + return 1; + case _IS_ITER_EXHAUSTED_RANGE: + return 2; + case _ITER_NEXT_RANGE: + return 2; case FOR_ITER_RANGE: return 2; case FOR_ITER_GEN: @@ -841,59 +1092,91 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case PUSH_EXC_INFO: return 2; + case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT: + return 1; + case _GUARD_KEYS_VERSION: + return 1; + case _LOAD_ATTR_METHOD_WITH_VALUES: + return 2; case LOAD_ATTR_METHOD_WITH_VALUES: return 2; + case _LOAD_ATTR_METHOD_NO_DICT: + return 2; case LOAD_ATTR_METHOD_NO_DICT: return 2; + case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: + return 1; case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: return 1; + case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: + return 1; case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: return 1; + case _CHECK_ATTR_METHOD_LAZY_DICT: + return 1; + case _LOAD_ATTR_METHOD_LAZY_DICT: + return 2; case LOAD_ATTR_METHOD_LAZY_DICT: return 2; - case KW_NAMES: - return 0; case INSTRUMENTED_CALL: return 0; case CALL: return 1; + case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: + return oparg + 2; + case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: + return oparg + 2; + case _CHECK_PEP_523: + return 0; + case _CHECK_FUNCTION_EXACT_ARGS: + return oparg + 2; + case _CHECK_STACK_SPACE: + return oparg + 2; + case _INIT_CALL_PY_EXACT_ARGS: + return 1; + case _PUSH_FRAME: + return 1; case CALL_BOUND_METHOD_EXACT_ARGS: return 1; case CALL_PY_EXACT_ARGS: return 1; case CALL_PY_WITH_DEFAULTS: return 1; - case CALL_NO_KW_TYPE_1: + case CALL_TYPE_1: return 1; - case CALL_NO_KW_STR_1: + case CALL_STR_1: return 1; - case CALL_NO_KW_TUPLE_1: + case CALL_TUPLE_1: return 1; - case CALL_NO_KW_ALLOC_AND_ENTER_INIT: + case CALL_ALLOC_AND_ENTER_INIT: return 1; case EXIT_INIT_CHECK: return 0; case CALL_BUILTIN_CLASS: return 1; - case CALL_NO_KW_BUILTIN_O: + case CALL_BUILTIN_O: return 1; - case CALL_NO_KW_BUILTIN_FAST: + case CALL_BUILTIN_FAST: return 1; case CALL_BUILTIN_FAST_WITH_KEYWORDS: return 1; - case CALL_NO_KW_LEN: + case CALL_LEN: return 1; - case CALL_NO_KW_ISINSTANCE: + case CALL_ISINSTANCE: return 1; - case CALL_NO_KW_LIST_APPEND: + case CALL_LIST_APPEND: return 1; - case CALL_NO_KW_METHOD_DESCRIPTOR_O: + case CALL_METHOD_DESCRIPTOR_O: return 1; case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: return 1; - case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: + case CALL_METHOD_DESCRIPTOR_NOARGS: + return 1; + case CALL_METHOD_DESCRIPTOR_FAST: return 1; - case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: + case INSTRUMENTED_CALL_KW: + return 0; + case CALL_KW: return 1; case INSTRUMENTED_CALL_FUNCTION_EX: return 0; @@ -939,13 +1222,39 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case RESERVED: return 0; + case _POP_JUMP_IF_FALSE: + return 0; + case _POP_JUMP_IF_TRUE: + return 0; + case _JUMP_TO_TOP: + return 0; + case _SET_IP: + return 0; + case _SAVE_CURRENT_IP: + return 0; + case _EXIT_TRACE: + return 0; + case _INSERT: + return oparg + 1; default: return -1; } } -#endif +#endif // NEED_OPCODE_METADATA -enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC00, INSTR_FMT_IBC000, INSTR_FMT_IBC00000, INSTR_FMT_IBC00000000, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC0, INSTR_FMT_IXC00, INSTR_FMT_IXC000 }; +enum InstructionFormat { + INSTR_FMT_IB, + INSTR_FMT_IBC, + INSTR_FMT_IBC0, + INSTR_FMT_IBC00, + INSTR_FMT_IBC000, + INSTR_FMT_IBC00000000, + INSTR_FMT_IX, + INSTR_FMT_IXC, + INSTR_FMT_IXC0, + INSTR_FMT_IXC00, + INSTR_FMT_IXC000, +}; #define IS_VALID_OPCODE(OP) \ (((OP) >= 0) && ((OP) < OPCODE_METADATA_SIZE) && \ @@ -957,12 +1266,18 @@ enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC00, INSTR_FMT #define HAS_JUMP_FLAG (8) #define HAS_FREE_FLAG (16) #define HAS_LOCAL_FLAG (32) +#define HAS_EVAL_BREAK_FLAG (64) +#define HAS_DEOPT_FLAG (128) +#define HAS_ERROR_FLAG (256) #define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG)) #define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG)) #define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG)) #define OPCODE_HAS_JUMP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_JUMP_FLAG)) #define OPCODE_HAS_FREE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_FREE_FLAG)) #define OPCODE_HAS_LOCAL(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_LOCAL_FLAG)) +#define OPCODE_HAS_EVAL_BREAK(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_EVAL_BREAK_FLAG)) +#define OPCODE_HAS_DEOPT(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_DEOPT_FLAG)) +#define OPCODE_HAS_ERROR(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_FLAG)) struct opcode_metadata { bool valid_entry; @@ -972,7 +1287,7 @@ struct opcode_metadata { struct opcode_macro_expansion { int nuops; - struct { int16_t uop; int8_t size; int8_t offset; } uops[8]; + struct { int16_t uop; int8_t size; int8_t offset; } uops[12]; }; #define OPARG_FULL 0 @@ -981,6 +1296,7 @@ struct opcode_macro_expansion { #define OPARG_CACHE_4 4 #define OPARG_TOP 5 #define OPARG_BOTTOM 6 +#define OPARG_SET_IP 7 #define OPCODE_METADATA_FMT(OP) (_PyOpcode_opcode_metadata[(OP)].instr_format) #define SAME_OPCODE_METADATA(OP1, OP2) \ @@ -990,17 +1306,15 @@ struct opcode_macro_expansion { #define OPCODE_UOP_NAME_SIZE 512 #define OPCODE_MACRO_EXPANSION_SIZE 256 -#ifndef NEED_OPCODE_METADATA extern const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE]; -extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE]; -extern const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE]; -#else // if NEED_OPCODE_METADATA +#ifdef NEED_OPCODE_METADATA const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = { [NOP] = { true, INSTR_FMT_IX, 0 }, - [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, + [RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, [LOAD_CLOSURE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, - [LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, + [LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG }, [LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FAST_AND_CLEAR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, @@ -1011,210 +1325,281 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = { [STORE_FAST_STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [POP_TOP] = { true, INSTR_FMT_IX, 0 }, [PUSH_NULL] = { true, INSTR_FMT_IX, 0 }, - [END_FOR] = { true, INSTR_FMT_IB, 0 }, - [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, 0 }, + [END_FOR] = { true, INSTR_FMT_IX, 0 }, + [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [END_SEND] = { true, INSTR_FMT_IX, 0 }, - [INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, 0 }, - [UNARY_NEGATIVE] = { true, INSTR_FMT_IX, 0 }, + [INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [UNARY_NOT] = { true, INSTR_FMT_IX, 0 }, - [TO_BOOL] = { true, INSTR_FMT_IXC00, 0 }, - [TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, 0 }, - [TO_BOOL_INT] = { true, INSTR_FMT_IXC00, 0 }, - [TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, 0 }, - [TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, 0 }, - [TO_BOOL_STR] = { true, INSTR_FMT_IXC00, 0 }, - [TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, 0 }, - [UNARY_INVERT] = { true, INSTR_FMT_IX, 0 }, - [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IBC, 0 }, - [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IBC, 0 }, - [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IBC, 0 }, - [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IBC, 0 }, - [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IBC, 0 }, - [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IBC, 0 }, - [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IBC, 0 }, - [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IB, HAS_LOCAL_FLAG }, - [BINARY_SUBSCR] = { true, INSTR_FMT_IXC, 0 }, - [BINARY_SLICE] = { true, INSTR_FMT_IX, 0 }, - [STORE_SLICE] = { true, INSTR_FMT_IX, 0 }, - [BINARY_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, 0 }, - [BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC, 0 }, - [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC, 0 }, - [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC, 0 }, - [LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [STORE_SUBSCR] = { true, INSTR_FMT_IXC, 0 }, - [STORE_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, 0 }, - [STORE_SUBSCR_DICT] = { true, INSTR_FMT_IXC, 0 }, - [DELETE_SUBSCR] = { true, INSTR_FMT_IX, 0 }, - [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [RAISE_VARARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG }, + [TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG }, + [TO_BOOL_INT] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG }, + [TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG }, + [TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG }, + [TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG }, + [TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG }, + [UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [_GUARD_BOTH_INT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG }, + [_BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG }, + [_BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG }, + [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [_GUARD_BOTH_FLOAT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, 0 }, + [_BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, 0 }, + [_BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, 0 }, + [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [_GUARD_BOTH_UNICODE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG }, + [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [_BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IX, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IX, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG }, + [BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [STORE_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [BINARY_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [BINARY_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG }, + [STORE_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [STORE_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [DELETE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [RAISE_VARARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, [INTERPRETER_EXIT] = { true, INSTR_FMT_IX, 0 }, + [_POP_FRAME] = { true, INSTR_FMT_IX, 0 }, [RETURN_VALUE] = { true, INSTR_FMT_IX, 0 }, - [INSTRUMENTED_RETURN_VALUE] = { true, INSTR_FMT_IX, 0 }, + [INSTRUMENTED_RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG }, - [INSTRUMENTED_RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG }, - [GET_AITER] = { true, INSTR_FMT_IX, 0 }, - [GET_ANEXT] = { true, INSTR_FMT_IX, 0 }, - [GET_AWAITABLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [INSTRUMENTED_RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_ERROR_FLAG }, + [GET_AITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [GET_ANEXT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [GET_AWAITABLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG }, + [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [POP_EXCEPT] = { true, INSTR_FMT_IX, 0 }, - [RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [END_ASYNC_FOR] = { true, INSTR_FMT_IX, 0 }, - [CLEANUP_THROW] = { true, INSTR_FMT_IX, 0 }, + [RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX, 0 }, - [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, 0 }, - [STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [DELETE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [STORE_ATTR] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [DELETE_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [STORE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [DELETE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_LOCALS] = { true, INSTR_FMT_IB, 0 }, - [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, - [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, - [DELETE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, - [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG }, - [DELETE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG }, - [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG }, - [LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG }, + [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [DELETE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [STORE_ATTR] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [DELETE_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [STORE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [DELETE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [_GUARD_GLOBALS_VERSION] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [_GUARD_BUILTINS_VERSION] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [_LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_LOAD_GLOBAL_BUILTINS] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [DELETE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG }, + [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG }, + [DELETE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG }, + [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG }, + [LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG }, [STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG }, [COPY_FREE_VARS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [BUILD_STRING] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [BUILD_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [BUILD_SET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [BUILD_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, 0 }, - [BUILD_CONST_KEY_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [DICT_MERGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [BUILD_STRING] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [BUILD_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [BUILD_SET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [BUILD_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [BUILD_CONST_KEY_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [DICT_MERGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, [INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_ZERO_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_ZERO_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_METHOD] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000, 0 }, - [STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000, 0 }, - [COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_ZERO_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_ZERO_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [LOAD_METHOD] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [_GUARD_TYPE_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG }, + [_CHECK_MANAGED_OBJECT_HAS_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_CHECK_ATTR_MODULE] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG }, + [_LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_CHECK_ATTR_WITH_HINT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG }, + [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG }, + [_LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_CHECK_ATTR_CLASS] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG }, + [_LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, + [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG }, + [_GUARD_DORV_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC, 0 }, + [STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG }, + [STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG }, + [_STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC, 0 }, + [STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG }, + [COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [CONTAINS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [CHECK_EG_MATCH] = { true, INSTR_FMT_IX, 0 }, - [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, 0 }, - [IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, + [CONTAINS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, + [IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG }, [JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, [JUMP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [JUMP_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, + [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [_IS_NONE] = { true, INSTR_FMT_IX, 0 }, + [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [GET_LEN] = { true, INSTR_FMT_IX, 0 }, - [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, [MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 }, [MATCH_SEQUENCE] = { true, INSTR_FMT_IX, 0 }, - [MATCH_KEYS] = { true, INSTR_FMT_IX, 0 }, - [GET_ITER] = { true, INSTR_FMT_IX, 0 }, - [GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX, 0 }, - [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, 0 }, - [BEFORE_WITH] = { true, INSTR_FMT_IX, 0 }, - [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, 0 }, + [MATCH_KEYS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [GET_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG }, + [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [_ITER_CHECK_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_ITER_JUMP_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [_IS_ITER_EXHAUSTED_LIST] = { true, INSTR_FMT_IX, 0 }, + [_ITER_NEXT_LIST] = { true, INSTR_FMT_IX, 0 }, + [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG }, + [_ITER_CHECK_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_ITER_JUMP_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [_IS_ITER_EXHAUSTED_TUPLE] = { true, INSTR_FMT_IX, 0 }, + [_ITER_NEXT_TUPLE] = { true, INSTR_FMT_IX, 0 }, + [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG }, + [_ITER_CHECK_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_ITER_JUMP_RANGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [_IS_ITER_EXHAUSTED_RANGE] = { true, INSTR_FMT_IX, 0 }, + [_ITER_NEXT_RANGE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [BEFORE_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [SETUP_FINALLY] = { true, INSTR_FMT_IX, 0 }, [SETUP_CLEANUP] = { true, INSTR_FMT_IX, 0 }, [SETUP_WITH] = { true, INSTR_FMT_IX, 0 }, [POP_BLOCK] = { true, INSTR_FMT_IX, 0 }, [PUSH_EXC_INFO] = { true, INSTR_FMT_IX, 0 }, - [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG }, - [KW_NAMES] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG }, - [INSTRUMENTED_CALL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, 0 }, - [CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, - [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG }, + [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_GUARD_KEYS_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG }, + [_LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, + [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, + [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, + [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, + [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_CHECK_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG }, + [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [INSTRUMENTED_CALL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, + [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [_CHECK_PEP_523] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_CHECK_FUNCTION_EXACT_ARGS] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_CHECK_STACK_SPACE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [_INIT_CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [_PUSH_FRAME] = { true, INSTR_FMT_IX, 0 }, + [CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [CALL_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, + [INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, [INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, 0 }, - [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [MAKE_FUNCTION] = { true, INSTR_FMT_IX, 0 }, + [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, + [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [RETURN_GENERATOR] = { true, INSTR_FMT_IX, 0 }, - [BUILD_SLICE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [CONVERT_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [FORMAT_SIMPLE] = { true, INSTR_FMT_IX, 0 }, - [FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, 0 }, + [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [BUILD_SLICE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [CONVERT_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [COPY] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG }, [SWAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, 0 }, + [INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG }, + [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, [EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [CACHE] = { true, INSTR_FMT_IX, 0 }, [RESERVED] = { true, INSTR_FMT_IX, 0 }, + [_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [_JUMP_TO_TOP] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG }, + [_SET_IP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [_SAVE_CURRENT_IP] = { true, INSTR_FMT_IX, 0 }, + [_EXIT_TRACE] = { true, INSTR_FMT_IX, 0 }, + [_INSERT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, }; +#endif // NEED_OPCODE_METADATA + +extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE]; +#ifdef NEED_OPCODE_METADATA const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE] = { [NOP] = { .nuops = 1, .uops = { { NOP, 0, 0 } } }, + [RESUME_CHECK] = { .nuops = 1, .uops = { { RESUME_CHECK, 0, 0 } } }, [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { LOAD_FAST_CHECK, 0, 0 } } }, [LOAD_FAST] = { .nuops = 1, .uops = { { LOAD_FAST, 0, 0 } } }, [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { LOAD_FAST_AND_CLEAR, 0, 0 } } }, @@ -1248,6 +1633,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [BINARY_SLICE] = { .nuops = 1, .uops = { { BINARY_SLICE, 0, 0 } } }, [STORE_SLICE] = { .nuops = 1, .uops = { { STORE_SLICE, 0, 0 } } }, [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_LIST_INT, 0, 0 } } }, + [BINARY_SUBSCR_STR_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_STR_INT, 0, 0 } } }, [BINARY_SUBSCR_TUPLE_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_TUPLE_INT, 0, 0 } } }, [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_DICT, 0, 0 } } }, [LIST_APPEND] = { .nuops = 1, .uops = { { LIST_APPEND, 0, 0 } } }, @@ -1258,6 +1644,8 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [DELETE_SUBSCR] = { .nuops = 1, .uops = { { DELETE_SUBSCR, 0, 0 } } }, [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { CALL_INTRINSIC_1, 0, 0 } } }, [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { CALL_INTRINSIC_2, 0, 0 } } }, + [RETURN_VALUE] = { .nuops = 2, .uops = { { _SAVE_CURRENT_IP, 7, -1 }, { _POP_FRAME, 0, 0 } } }, + [RETURN_CONST] = { .nuops = 3, .uops = { { LOAD_CONST, 0, 0 }, { _SAVE_CURRENT_IP, 7, -1 }, { _POP_FRAME, 0, 0 } } }, [GET_AITER] = { .nuops = 1, .uops = { { GET_AITER, 0, 0 } } }, [GET_ANEXT] = { .nuops = 1, .uops = { { GET_ANEXT, 0, 0 } } }, [GET_AWAITABLE] = { .nuops = 1, .uops = { { GET_AWAITABLE, 0, 0 } } }, @@ -1275,12 +1663,12 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [DELETE_ATTR] = { .nuops = 1, .uops = { { DELETE_ATTR, 0, 0 } } }, [STORE_GLOBAL] = { .nuops = 1, .uops = { { STORE_GLOBAL, 0, 0 } } }, [DELETE_GLOBAL] = { .nuops = 1, .uops = { { DELETE_GLOBAL, 0, 0 } } }, - [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } }, - [LOAD_NAME] = { .nuops = 2, .uops = { { _LOAD_LOCALS, 0, 0 }, { _LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } }, - [LOAD_FROM_DICT_OR_GLOBALS] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } }, + [LOAD_LOCALS] = { .nuops = 1, .uops = { { LOAD_LOCALS, 0, 0 } } }, + [LOAD_FROM_DICT_OR_GLOBALS] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } }, + [LOAD_NAME] = { .nuops = 1, .uops = { { LOAD_NAME, 0, 0 } } }, [LOAD_GLOBAL] = { .nuops = 1, .uops = { { LOAD_GLOBAL, 0, 0 } } }, - [LOAD_GLOBAL_MODULE] = { .nuops = 4, .uops = { { _SKIP_CACHE, 0, 0 }, { _GUARD_GLOBALS_VERSION, 1, 1 }, { _SKIP_CACHE, 0, 0 }, { _LOAD_GLOBAL_MODULE, 1, 3 } } }, - [LOAD_GLOBAL_BUILTIN] = { .nuops = 4, .uops = { { _SKIP_CACHE, 0, 0 }, { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION, 1, 2 }, { _LOAD_GLOBAL_BUILTINS, 1, 3 } } }, + [LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _LOAD_GLOBAL_MODULE, 1, 3 } } }, + [LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION, 1, 2 }, { _LOAD_GLOBAL_BUILTINS, 1, 3 } } }, [DELETE_FAST] = { .nuops = 1, .uops = { { DELETE_FAST, 0, 0 } } }, [DELETE_DEREF] = { .nuops = 1, .uops = { { DELETE_DEREF, 0, 0 } } }, [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_DEREF, 0, 0 } } }, @@ -1302,7 +1690,13 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { LOAD_SUPER_ATTR_ATTR, 0, 0 } } }, [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { LOAD_SUPER_ATTR_METHOD, 0, 0 } } }, [LOAD_ATTR] = { .nuops = 1, .uops = { { LOAD_ATTR, 0, 0 } } }, - [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 4, .uops = { { _SKIP_CACHE, 0, 0 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } }, + [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } }, + [LOAD_ATTR_MODULE] = { .nuops = 2, .uops = { { _CHECK_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, 1, 3 } } }, + [LOAD_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_WITH_HINT, 0, 0 }, { _LOAD_ATTR_WITH_HINT, 1, 3 } } }, + [LOAD_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 } } }, + [LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } }, + [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } }, + [STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } }, [COMPARE_OP] = { .nuops = 1, .uops = { { COMPARE_OP, 0, 0 } } }, [COMPARE_OP_FLOAT] = { .nuops = 1, .uops = { { COMPARE_OP_FLOAT, 0, 0 } } }, [COMPARE_OP_INT] = { .nuops = 1, .uops = { { COMPARE_OP_INT, 0, 0 } } }, @@ -1320,17 +1714,27 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { GET_YIELD_FROM_ITER, 0, 0 } } }, [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { WITH_EXCEPT_START, 0, 0 } } }, [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } }, - [CALL_NO_KW_TYPE_1] = { .nuops = 1, .uops = { { CALL_NO_KW_TYPE_1, 0, 0 } } }, - [CALL_NO_KW_STR_1] = { .nuops = 1, .uops = { { CALL_NO_KW_STR_1, 0, 0 } } }, - [CALL_NO_KW_TUPLE_1] = { .nuops = 1, .uops = { { CALL_NO_KW_TUPLE_1, 0, 0 } } }, + [LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } }, + [LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } }, + [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } }, + [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } }, + [LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 0, 0 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } }, + [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_CURRENT_IP, 7, 2 }, { _PUSH_FRAME, 0, 0 } } }, + [CALL_PY_EXACT_ARGS] = { .nuops = 6, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_CURRENT_IP, 7, 2 }, { _PUSH_FRAME, 0, 0 } } }, + [CALL_TYPE_1] = { .nuops = 1, .uops = { { CALL_TYPE_1, 0, 0 } } }, + [CALL_STR_1] = { .nuops = 1, .uops = { { CALL_STR_1, 0, 0 } } }, + [CALL_TUPLE_1] = { .nuops = 1, .uops = { { CALL_TUPLE_1, 0, 0 } } }, [EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { EXIT_INIT_CHECK, 0, 0 } } }, - [CALL_NO_KW_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_NO_KW_BUILTIN_O, 0, 0 } } }, - [CALL_NO_KW_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_NO_KW_BUILTIN_FAST, 0, 0 } } }, - [CALL_NO_KW_LEN] = { .nuops = 1, .uops = { { CALL_NO_KW_LEN, 0, 0 } } }, - [CALL_NO_KW_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_NO_KW_ISINSTANCE, 0, 0 } } }, - [CALL_NO_KW_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_O, 0, 0 } } }, - [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } }, - [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_FAST, 0, 0 } } }, + [CALL_BUILTIN_CLASS] = { .nuops = 1, .uops = { { CALL_BUILTIN_CLASS, 0, 0 } } }, + [CALL_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_BUILTIN_O, 0, 0 } } }, + [CALL_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST, 0, 0 } } }, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 } } }, + [CALL_LEN] = { .nuops = 1, .uops = { { CALL_LEN, 0, 0 } } }, + [CALL_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_ISINSTANCE, 0, 0 } } }, + [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_O, 0, 0 } } }, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 } } }, + [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } }, + [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST, 0, 0 } } }, [MAKE_FUNCTION] = { .nuops = 1, .uops = { { MAKE_FUNCTION, 0, 0 } } }, [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { SET_FUNCTION_ATTRIBUTE, 0, 0 } } }, [BUILD_SLICE] = { .nuops = 1, .uops = { { BUILD_SLICE, 0, 0 } } }, @@ -1341,9 +1745,13 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [BINARY_OP] = { .nuops = 1, .uops = { { BINARY_OP, 0, 0 } } }, [SWAP] = { .nuops = 1, .uops = { { SWAP, 0, 0 } } }, }; +#endif // NEED_OPCODE_METADATA + +extern const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE]; +#ifdef NEED_OPCODE_METADATA const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = { - [EXIT_TRACE] = "EXIT_TRACE", - [SAVE_IP] = "SAVE_IP", + [_EXIT_TRACE] = "_EXIT_TRACE", + [_SET_IP] = "_SET_IP", [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT", [_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT", [_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT", @@ -1354,9 +1762,8 @@ const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = { [_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT", [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE", [_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE", - [_LOAD_LOCALS] = "_LOAD_LOCALS", - [_LOAD_FROM_DICT_OR_GLOBALS] = "_LOAD_FROM_DICT_OR_GLOBALS", - [_SKIP_CACHE] = "_SKIP_CACHE", + [_BINARY_OP_INPLACE_ADD_UNICODE] = "_BINARY_OP_INPLACE_ADD_UNICODE", + [_POP_FRAME] = "_POP_FRAME", [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION", [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION", [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE", @@ -1364,18 +1771,564 @@ const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = { [_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION", [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES", [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE", - [IS_NONE] = "IS_NONE", + [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE", + [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE", + [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT", + [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT", + [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT", + [_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS", + [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS", + [_GUARD_DORV_VALUES] = "_GUARD_DORV_VALUES", + [_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE", + [_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT", + [_IS_NONE] = "_IS_NONE", [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST", + [_ITER_JUMP_LIST] = "_ITER_JUMP_LIST", [_IS_ITER_EXHAUSTED_LIST] = "_IS_ITER_EXHAUSTED_LIST", [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST", [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE", + [_ITER_JUMP_TUPLE] = "_ITER_JUMP_TUPLE", [_IS_ITER_EXHAUSTED_TUPLE] = "_IS_ITER_EXHAUSTED_TUPLE", [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE", [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE", + [_ITER_JUMP_RANGE] = "_ITER_JUMP_RANGE", [_IS_ITER_EXHAUSTED_RANGE] = "_IS_ITER_EXHAUSTED_RANGE", [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE", + [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT", + [_GUARD_KEYS_VERSION] = "_GUARD_KEYS_VERSION", + [_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES", + [_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT", + [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", + [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT", + [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT", + [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT", + [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS", + [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = "_INIT_CALL_BOUND_METHOD_EXACT_ARGS", + [_CHECK_PEP_523] = "_CHECK_PEP_523", + [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS", + [_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE", + [_INIT_CALL_PY_EXACT_ARGS] = "_INIT_CALL_PY_EXACT_ARGS", + [_PUSH_FRAME] = "_PUSH_FRAME", [_POP_JUMP_IF_FALSE] = "_POP_JUMP_IF_FALSE", [_POP_JUMP_IF_TRUE] = "_POP_JUMP_IF_TRUE", - [JUMP_TO_TOP] = "JUMP_TO_TOP", + [_JUMP_TO_TOP] = "_JUMP_TO_TOP", + [_SAVE_CURRENT_IP] = "_SAVE_CURRENT_IP", + [_INSERT] = "_INSERT", }; #endif // NEED_OPCODE_METADATA + +extern const char *const _PyOpcode_OpName[268]; +#ifdef NEED_OPCODE_METADATA +const char *const _PyOpcode_OpName[268] = { + [CACHE] = "CACHE", + [RESERVED] = "RESERVED", + [RESUME] = "RESUME", + [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", + [BEFORE_WITH] = "BEFORE_WITH", + [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE", + [BINARY_SLICE] = "BINARY_SLICE", + [BINARY_SUBSCR] = "BINARY_SUBSCR", + [CHECK_EG_MATCH] = "CHECK_EG_MATCH", + [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH", + [CLEANUP_THROW] = "CLEANUP_THROW", + [DELETE_SUBSCR] = "DELETE_SUBSCR", + [END_ASYNC_FOR] = "END_ASYNC_FOR", + [END_FOR] = "END_FOR", + [END_SEND] = "END_SEND", + [EXIT_INIT_CHECK] = "EXIT_INIT_CHECK", + [FORMAT_SIMPLE] = "FORMAT_SIMPLE", + [FORMAT_WITH_SPEC] = "FORMAT_WITH_SPEC", + [GET_AITER] = "GET_AITER", + [GET_ANEXT] = "GET_ANEXT", + [GET_ITER] = "GET_ITER", + [GET_LEN] = "GET_LEN", + [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", + [INTERPRETER_EXIT] = "INTERPRETER_EXIT", + [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", + [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", + [LOAD_LOCALS] = "LOAD_LOCALS", + [MAKE_FUNCTION] = "MAKE_FUNCTION", + [MATCH_KEYS] = "MATCH_KEYS", + [MATCH_MAPPING] = "MATCH_MAPPING", + [MATCH_SEQUENCE] = "MATCH_SEQUENCE", + [NOP] = "NOP", + [POP_EXCEPT] = "POP_EXCEPT", + [POP_TOP] = "POP_TOP", + [PUSH_EXC_INFO] = "PUSH_EXC_INFO", + [PUSH_NULL] = "PUSH_NULL", + [RETURN_GENERATOR] = "RETURN_GENERATOR", + [RETURN_VALUE] = "RETURN_VALUE", + [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", + [STORE_SLICE] = "STORE_SLICE", + [STORE_SUBSCR] = "STORE_SUBSCR", + [TO_BOOL] = "TO_BOOL", + [UNARY_INVERT] = "UNARY_INVERT", + [UNARY_NEGATIVE] = "UNARY_NEGATIVE", + [UNARY_NOT] = "UNARY_NOT", + [WITH_EXCEPT_START] = "WITH_EXCEPT_START", + [BINARY_OP] = "BINARY_OP", + [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", + [BUILD_LIST] = "BUILD_LIST", + [BUILD_MAP] = "BUILD_MAP", + [BUILD_SET] = "BUILD_SET", + [BUILD_SLICE] = "BUILD_SLICE", + [BUILD_STRING] = "BUILD_STRING", + [BUILD_TUPLE] = "BUILD_TUPLE", + [CALL] = "CALL", + [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", + [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1", + [CALL_INTRINSIC_2] = "CALL_INTRINSIC_2", + [CALL_KW] = "CALL_KW", + [COMPARE_OP] = "COMPARE_OP", + [CONTAINS_OP] = "CONTAINS_OP", + [CONVERT_VALUE] = "CONVERT_VALUE", + [COPY] = "COPY", + [COPY_FREE_VARS] = "COPY_FREE_VARS", + [DELETE_ATTR] = "DELETE_ATTR", + [DELETE_DEREF] = "DELETE_DEREF", + [DELETE_FAST] = "DELETE_FAST", + [DELETE_GLOBAL] = "DELETE_GLOBAL", + [DELETE_NAME] = "DELETE_NAME", + [DICT_MERGE] = "DICT_MERGE", + [DICT_UPDATE] = "DICT_UPDATE", + [ENTER_EXECUTOR] = "ENTER_EXECUTOR", + [EXTENDED_ARG] = "EXTENDED_ARG", + [FOR_ITER] = "FOR_ITER", + [GET_AWAITABLE] = "GET_AWAITABLE", + [IMPORT_FROM] = "IMPORT_FROM", + [IMPORT_NAME] = "IMPORT_NAME", + [IS_OP] = "IS_OP", + [JUMP_BACKWARD] = "JUMP_BACKWARD", + [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT", + [JUMP_FORWARD] = "JUMP_FORWARD", + [LIST_APPEND] = "LIST_APPEND", + [LIST_EXTEND] = "LIST_EXTEND", + [LOAD_ATTR] = "LOAD_ATTR", + [LOAD_CONST] = "LOAD_CONST", + [LOAD_DEREF] = "LOAD_DEREF", + [LOAD_FAST] = "LOAD_FAST", + [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR", + [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK", + [LOAD_FAST_LOAD_FAST] = "LOAD_FAST_LOAD_FAST", + [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF", + [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS", + [LOAD_GLOBAL] = "LOAD_GLOBAL", + [LOAD_NAME] = "LOAD_NAME", + [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR", + [MAKE_CELL] = "MAKE_CELL", + [MAP_ADD] = "MAP_ADD", + [MATCH_CLASS] = "MATCH_CLASS", + [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE", + [POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE", + [POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE", + [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE", + [RAISE_VARARGS] = "RAISE_VARARGS", + [RERAISE] = "RERAISE", + [RETURN_CONST] = "RETURN_CONST", + [SEND] = "SEND", + [SET_ADD] = "SET_ADD", + [SET_FUNCTION_ATTRIBUTE] = "SET_FUNCTION_ATTRIBUTE", + [SET_UPDATE] = "SET_UPDATE", + [STORE_ATTR] = "STORE_ATTR", + [STORE_DEREF] = "STORE_DEREF", + [STORE_FAST] = "STORE_FAST", + [STORE_FAST_LOAD_FAST] = "STORE_FAST_LOAD_FAST", + [STORE_FAST_STORE_FAST] = "STORE_FAST_STORE_FAST", + [STORE_GLOBAL] = "STORE_GLOBAL", + [STORE_NAME] = "STORE_NAME", + [SWAP] = "SWAP", + [UNPACK_EX] = "UNPACK_EX", + [UNPACK_SEQUENCE] = "UNPACK_SEQUENCE", + [YIELD_VALUE] = "YIELD_VALUE", + [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", + [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", + [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE", + [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT", + [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT", + [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT", + [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT", + [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT", + [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM", + [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT", + [BINARY_SUBSCR_STR_INT] = "BINARY_SUBSCR_STR_INT", + [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT", + [CALL_ALLOC_AND_ENTER_INIT] = "CALL_ALLOC_AND_ENTER_INIT", + [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS", + [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS", + [CALL_BUILTIN_FAST] = "CALL_BUILTIN_FAST", + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS", + [CALL_BUILTIN_O] = "CALL_BUILTIN_O", + [CALL_ISINSTANCE] = "CALL_ISINSTANCE", + [CALL_LEN] = "CALL_LEN", + [CALL_LIST_APPEND] = "CALL_LIST_APPEND", + [CALL_METHOD_DESCRIPTOR_FAST] = "CALL_METHOD_DESCRIPTOR_FAST", + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", + [CALL_METHOD_DESCRIPTOR_NOARGS] = "CALL_METHOD_DESCRIPTOR_NOARGS", + [CALL_METHOD_DESCRIPTOR_O] = "CALL_METHOD_DESCRIPTOR_O", + [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", + [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", + [CALL_STR_1] = "CALL_STR_1", + [CALL_TUPLE_1] = "CALL_TUPLE_1", + [CALL_TYPE_1] = "CALL_TYPE_1", + [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT", + [COMPARE_OP_INT] = "COMPARE_OP_INT", + [COMPARE_OP_STR] = "COMPARE_OP_STR", + [FOR_ITER_GEN] = "FOR_ITER_GEN", + [FOR_ITER_LIST] = "FOR_ITER_LIST", + [FOR_ITER_RANGE] = "FOR_ITER_RANGE", + [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE", + [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", + [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", + [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", + [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", + [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", + [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT", + [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", + [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", + [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", + [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", + [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", + [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR", + [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD", + [RESUME_CHECK] = "RESUME_CHECK", + [SEND_GEN] = "SEND_GEN", + [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", + [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", + [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", + [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", + [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", + [TO_BOOL_ALWAYS_TRUE] = "TO_BOOL_ALWAYS_TRUE", + [TO_BOOL_BOOL] = "TO_BOOL_BOOL", + [TO_BOOL_INT] = "TO_BOOL_INT", + [TO_BOOL_LIST] = "TO_BOOL_LIST", + [TO_BOOL_NONE] = "TO_BOOL_NONE", + [TO_BOOL_STR] = "TO_BOOL_STR", + [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", + [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", + [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [INSTRUMENTED_RESUME] = "INSTRUMENTED_RESUME", + [INSTRUMENTED_END_FOR] = "INSTRUMENTED_END_FOR", + [INSTRUMENTED_END_SEND] = "INSTRUMENTED_END_SEND", + [INSTRUMENTED_RETURN_VALUE] = "INSTRUMENTED_RETURN_VALUE", + [INSTRUMENTED_RETURN_CONST] = "INSTRUMENTED_RETURN_CONST", + [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE", + [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR", + [INSTRUMENTED_FOR_ITER] = "INSTRUMENTED_FOR_ITER", + [INSTRUMENTED_CALL] = "INSTRUMENTED_CALL", + [INSTRUMENTED_CALL_KW] = "INSTRUMENTED_CALL_KW", + [INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX", + [INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION", + [INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD", + [INSTRUMENTED_JUMP_BACKWARD] = "INSTRUMENTED_JUMP_BACKWARD", + [INSTRUMENTED_POP_JUMP_IF_TRUE] = "INSTRUMENTED_POP_JUMP_IF_TRUE", + [INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE", + [INSTRUMENTED_POP_JUMP_IF_NONE] = "INSTRUMENTED_POP_JUMP_IF_NONE", + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE", + [INSTRUMENTED_LINE] = "INSTRUMENTED_LINE", + [JUMP] = "JUMP", + [JUMP_NO_INTERRUPT] = "JUMP_NO_INTERRUPT", + [LOAD_CLOSURE] = "LOAD_CLOSURE", + [LOAD_METHOD] = "LOAD_METHOD", + [LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD", + [LOAD_ZERO_SUPER_ATTR] = "LOAD_ZERO_SUPER_ATTR", + [LOAD_ZERO_SUPER_METHOD] = "LOAD_ZERO_SUPER_METHOD", + [POP_BLOCK] = "POP_BLOCK", + [SETUP_CLEANUP] = "SETUP_CLEANUP", + [SETUP_FINALLY] = "SETUP_FINALLY", + [SETUP_WITH] = "SETUP_WITH", + [STORE_FAST_MAYBE_NULL] = "STORE_FAST_MAYBE_NULL", +}; +#endif // NEED_OPCODE_METADATA + +extern const uint8_t _PyOpcode_Caches[256]; +#ifdef NEED_OPCODE_METADATA +const uint8_t _PyOpcode_Caches[256] = { + [TO_BOOL] = 3, + [BINARY_SUBSCR] = 1, + [STORE_SUBSCR] = 1, + [SEND] = 1, + [UNPACK_SEQUENCE] = 1, + [STORE_ATTR] = 4, + [LOAD_GLOBAL] = 4, + [LOAD_SUPER_ATTR] = 1, + [LOAD_ATTR] = 9, + [COMPARE_OP] = 1, + [POP_JUMP_IF_FALSE] = 1, + [POP_JUMP_IF_TRUE] = 1, + [POP_JUMP_IF_NONE] = 1, + [POP_JUMP_IF_NOT_NONE] = 1, + [FOR_ITER] = 1, + [CALL] = 3, + [BINARY_OP] = 1, + [JUMP_BACKWARD] = 1, +}; +#endif // NEED_OPCODE_METADATA + +extern const uint8_t _PyOpcode_Deopt[256]; +#ifdef NEED_OPCODE_METADATA +const uint8_t _PyOpcode_Deopt[256] = { + [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, + [BEFORE_WITH] = BEFORE_WITH, + [BINARY_OP] = BINARY_OP, + [BINARY_OP_ADD_FLOAT] = BINARY_OP, + [BINARY_OP_ADD_INT] = BINARY_OP, + [BINARY_OP_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP, + [BINARY_OP_MULTIPLY_INT] = BINARY_OP, + [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, + [BINARY_OP_SUBTRACT_INT] = BINARY_OP, + [BINARY_SLICE] = BINARY_SLICE, + [BINARY_SUBSCR] = BINARY_SUBSCR, + [BINARY_SUBSCR_DICT] = BINARY_SUBSCR, + [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR, + [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR, + [BINARY_SUBSCR_STR_INT] = BINARY_SUBSCR, + [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR, + [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, + [BUILD_LIST] = BUILD_LIST, + [BUILD_MAP] = BUILD_MAP, + [BUILD_SET] = BUILD_SET, + [BUILD_SLICE] = BUILD_SLICE, + [BUILD_STRING] = BUILD_STRING, + [BUILD_TUPLE] = BUILD_TUPLE, + [CACHE] = CACHE, + [CALL] = CALL, + [CALL_ALLOC_AND_ENTER_INIT] = CALL, + [CALL_BOUND_METHOD_EXACT_ARGS] = CALL, + [CALL_BUILTIN_CLASS] = CALL, + [CALL_BUILTIN_FAST] = CALL, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL, + [CALL_BUILTIN_O] = CALL, + [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, + [CALL_INTRINSIC_1] = CALL_INTRINSIC_1, + [CALL_INTRINSIC_2] = CALL_INTRINSIC_2, + [CALL_ISINSTANCE] = CALL, + [CALL_KW] = CALL_KW, + [CALL_LEN] = CALL, + [CALL_LIST_APPEND] = CALL, + [CALL_METHOD_DESCRIPTOR_FAST] = CALL, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL, + [CALL_METHOD_DESCRIPTOR_NOARGS] = CALL, + [CALL_METHOD_DESCRIPTOR_O] = CALL, + [CALL_PY_EXACT_ARGS] = CALL, + [CALL_PY_WITH_DEFAULTS] = CALL, + [CALL_STR_1] = CALL, + [CALL_TUPLE_1] = CALL, + [CALL_TYPE_1] = CALL, + [CHECK_EG_MATCH] = CHECK_EG_MATCH, + [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, + [CLEANUP_THROW] = CLEANUP_THROW, + [COMPARE_OP] = COMPARE_OP, + [COMPARE_OP_FLOAT] = COMPARE_OP, + [COMPARE_OP_INT] = COMPARE_OP, + [COMPARE_OP_STR] = COMPARE_OP, + [CONTAINS_OP] = CONTAINS_OP, + [CONVERT_VALUE] = CONVERT_VALUE, + [COPY] = COPY, + [COPY_FREE_VARS] = COPY_FREE_VARS, + [DELETE_ATTR] = DELETE_ATTR, + [DELETE_DEREF] = DELETE_DEREF, + [DELETE_FAST] = DELETE_FAST, + [DELETE_GLOBAL] = DELETE_GLOBAL, + [DELETE_NAME] = DELETE_NAME, + [DELETE_SUBSCR] = DELETE_SUBSCR, + [DICT_MERGE] = DICT_MERGE, + [DICT_UPDATE] = DICT_UPDATE, + [END_ASYNC_FOR] = END_ASYNC_FOR, + [END_FOR] = END_FOR, + [END_SEND] = END_SEND, + [ENTER_EXECUTOR] = ENTER_EXECUTOR, + [EXIT_INIT_CHECK] = EXIT_INIT_CHECK, + [EXTENDED_ARG] = EXTENDED_ARG, + [FORMAT_SIMPLE] = FORMAT_SIMPLE, + [FORMAT_WITH_SPEC] = FORMAT_WITH_SPEC, + [FOR_ITER] = FOR_ITER, + [FOR_ITER_GEN] = FOR_ITER, + [FOR_ITER_LIST] = FOR_ITER, + [FOR_ITER_RANGE] = FOR_ITER, + [FOR_ITER_TUPLE] = FOR_ITER, + [GET_AITER] = GET_AITER, + [GET_ANEXT] = GET_ANEXT, + [GET_AWAITABLE] = GET_AWAITABLE, + [GET_ITER] = GET_ITER, + [GET_LEN] = GET_LEN, + [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, + [IMPORT_FROM] = IMPORT_FROM, + [IMPORT_NAME] = IMPORT_NAME, + [INSTRUMENTED_CALL] = INSTRUMENTED_CALL, + [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, + [INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW, + [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR, + [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND, + [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER, + [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION, + [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD, + [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD, + [INSTRUMENTED_LINE] = INSTRUMENTED_LINE, + [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, + [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE, + [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE, + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE, + [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE, + [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME, + [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST, + [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, + [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, + [INTERPRETER_EXIT] = INTERPRETER_EXIT, + [IS_OP] = IS_OP, + [JUMP_BACKWARD] = JUMP_BACKWARD, + [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, + [JUMP_FORWARD] = JUMP_FORWARD, + [LIST_APPEND] = LIST_APPEND, + [LIST_EXTEND] = LIST_EXTEND, + [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, + [LOAD_ATTR] = LOAD_ATTR, + [LOAD_ATTR_CLASS] = LOAD_ATTR, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR, + [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, + [LOAD_ATTR_MODULE] = LOAD_ATTR, + [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR, + [LOAD_ATTR_PROPERTY] = LOAD_ATTR, + [LOAD_ATTR_SLOT] = LOAD_ATTR, + [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, + [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, + [LOAD_CONST] = LOAD_CONST, + [LOAD_DEREF] = LOAD_DEREF, + [LOAD_FAST] = LOAD_FAST, + [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR, + [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, + [LOAD_FAST_LOAD_FAST] = LOAD_FAST_LOAD_FAST, + [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF, + [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS, + [LOAD_GLOBAL] = LOAD_GLOBAL, + [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, + [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, + [LOAD_LOCALS] = LOAD_LOCALS, + [LOAD_NAME] = LOAD_NAME, + [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR, + [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR, + [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR, + [MAKE_CELL] = MAKE_CELL, + [MAKE_FUNCTION] = MAKE_FUNCTION, + [MAP_ADD] = MAP_ADD, + [MATCH_CLASS] = MATCH_CLASS, + [MATCH_KEYS] = MATCH_KEYS, + [MATCH_MAPPING] = MATCH_MAPPING, + [MATCH_SEQUENCE] = MATCH_SEQUENCE, + [NOP] = NOP, + [POP_EXCEPT] = POP_EXCEPT, + [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE, + [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE, + [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE, + [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE, + [POP_TOP] = POP_TOP, + [PUSH_EXC_INFO] = PUSH_EXC_INFO, + [PUSH_NULL] = PUSH_NULL, + [RAISE_VARARGS] = RAISE_VARARGS, + [RERAISE] = RERAISE, + [RESERVED] = RESERVED, + [RESUME] = RESUME, + [RESUME_CHECK] = RESUME, + [RETURN_CONST] = RETURN_CONST, + [RETURN_GENERATOR] = RETURN_GENERATOR, + [RETURN_VALUE] = RETURN_VALUE, + [SEND] = SEND, + [SEND_GEN] = SEND, + [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, + [SET_ADD] = SET_ADD, + [SET_FUNCTION_ATTRIBUTE] = SET_FUNCTION_ATTRIBUTE, + [SET_UPDATE] = SET_UPDATE, + [STORE_ATTR] = STORE_ATTR, + [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, + [STORE_ATTR_SLOT] = STORE_ATTR, + [STORE_ATTR_WITH_HINT] = STORE_ATTR, + [STORE_DEREF] = STORE_DEREF, + [STORE_FAST] = STORE_FAST, + [STORE_FAST_LOAD_FAST] = STORE_FAST_LOAD_FAST, + [STORE_FAST_STORE_FAST] = STORE_FAST_STORE_FAST, + [STORE_GLOBAL] = STORE_GLOBAL, + [STORE_NAME] = STORE_NAME, + [STORE_SLICE] = STORE_SLICE, + [STORE_SUBSCR] = STORE_SUBSCR, + [STORE_SUBSCR_DICT] = STORE_SUBSCR, + [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, + [SWAP] = SWAP, + [TO_BOOL] = TO_BOOL, + [TO_BOOL_ALWAYS_TRUE] = TO_BOOL, + [TO_BOOL_BOOL] = TO_BOOL, + [TO_BOOL_INT] = TO_BOOL, + [TO_BOOL_LIST] = TO_BOOL, + [TO_BOOL_NONE] = TO_BOOL, + [TO_BOOL_STR] = TO_BOOL, + [UNARY_INVERT] = UNARY_INVERT, + [UNARY_NEGATIVE] = UNARY_NEGATIVE, + [UNARY_NOT] = UNARY_NOT, + [UNPACK_EX] = UNPACK_EX, + [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, + [WITH_EXCEPT_START] = WITH_EXCEPT_START, + [YIELD_VALUE] = YIELD_VALUE, +}; +#endif // NEED_OPCODE_METADATA + +#define EXTRA_CASES \ + case 119: \ + case 120: \ + case 121: \ + case 122: \ + case 123: \ + case 124: \ + case 125: \ + case 126: \ + case 127: \ + case 128: \ + case 129: \ + case 130: \ + case 131: \ + case 132: \ + case 133: \ + case 134: \ + case 135: \ + case 136: \ + case 137: \ + case 138: \ + case 139: \ + case 140: \ + case 141: \ + case 142: \ + case 143: \ + case 144: \ + case 145: \ + case 146: \ + case 147: \ + case 148: \ + case 219: \ + case 220: \ + case 221: \ + case 222: \ + case 223: \ + case 224: \ + case 225: \ + case 226: \ + case 227: \ + case 228: \ + case 229: \ + case 230: \ + case 231: \ + case 232: \ + case 233: \ + case 234: \ + case 235: \ + case 255: \ + ; + diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h index 50ff2af38d2cbe..c4acb00a4b291e 100644 --- a/Include/internal/pycore_opcode_utils.h +++ b/Include/internal/pycore_opcode_utils.h @@ -8,8 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_opcode.h" // _PyOpcode_Jump - +#include "opcode_ids.h" #define MAX_REAL_OPCODE 254 diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h new file mode 100644 index 00000000000000..f9f16c48cbc21c --- /dev/null +++ b/Include/internal/pycore_optimizer.h @@ -0,0 +1,20 @@ +#ifndef Py_INTERNAL_OPTIMIZER_H +#define Py_INTERNAL_OPTIMIZER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_uops.h" // _PyUOpInstruction + +int _Py_uop_analyze_and_optimize(PyCodeObject *code, + _PyUOpInstruction *trace, int trace_len, int curr_stackentries); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_OPTIMIZER_H */ diff --git a/Include/internal/pycore_parking_lot.h b/Include/internal/pycore_parking_lot.h new file mode 100644 index 00000000000000..f444da730055e8 --- /dev/null +++ b/Include/internal/pycore_parking_lot.h @@ -0,0 +1,99 @@ +// ParkingLot is an internal API for building efficient synchronization +// primitives like mutexes and events. +// +// The API and name is inspired by WebKit's WTF::ParkingLot, which in turn +// is inspired Linux's futex API. +// See https://webkit.org/blog/6161/locking-in-webkit/. +// +// The core functionality is an atomic "compare-and-sleep" operation along with +// an atomic "wake-up" operation. + +#ifndef Py_INTERNAL_PARKING_LOT_H +#define Py_INTERNAL_PARKING_LOT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_time.h" // _PyTime_t + + +enum { + // The thread was unparked by another thread. + Py_PARK_OK = 0, + + // The value of `address` did not match `expected`. + Py_PARK_AGAIN = -1, + + // The thread was unparked due to a timeout. + Py_PARK_TIMEOUT = -2, + + // The thread was interrupted by a signal. + Py_PARK_INTR = -3, +}; + +// Checks that `*address == *expected` and puts the thread to sleep until an +// unpark operation is called on the same `address`. Otherwise, the function +// returns `Py_PARK_AGAIN`. The comparison behaves like memcmp, but is +// performed atomically with respect to unpark operations. +// +// The `address_size` argument is the size of the data pointed to by the +// `address` and `expected` pointers (i.e., sizeof(*address)). It must be +// 1, 2, 4, or 8. +// +// The `timeout_ns` argument specifies the maximum amount of time to wait, with +// -1 indicating an infinite wait. +// +// `park_arg`, which can be NULL, is passed to the unpark operation. +// +// If `detach` is true, then the thread will detach/release the GIL while +// waiting. +// +// Example usage: +// +// if (_Py_atomic_compare_exchange_uint8(address, &expected, new_value)) { +// int res = _PyParkingLot_Park(address, &new_value, sizeof(*address), +// timeout_ns, NULL, 1); +// ... +// } +PyAPI_FUNC(int) +_PyParkingLot_Park(const void *address, const void *expected, + size_t address_size, _PyTime_t timeout_ns, + void *park_arg, int detach); + +// Callback for _PyParkingLot_Unpark: +// +// `arg` is the data of the same name provided to the _PyParkingLot_Unpark() +// call. +// `park_arg` is the data provided to _PyParkingLot_Park() call or NULL if +// no waiting thread was found. +// `has_more_waiters` is true if there are more threads waiting on the same +// address. May be true in cases where threads are waiting on a different +// address that map to the same internal bucket. +typedef void _Py_unpark_fn_t(void *arg, void *park_arg, int has_more_waiters); + +// Unparks a single thread waiting on `address`. +// +// Note that fn() is called regardless of whether a thread was unparked. If +// no threads are waiting on `address` then the `park_arg` argument to fn() +// will be NULL. +// +// Example usage: +// void callback(void *arg, void *park_arg, int has_more_waiters); +// _PyParkingLot_Unpark(address, &callback, arg); +PyAPI_FUNC(void) +_PyParkingLot_Unpark(const void *address, _Py_unpark_fn_t *fn, void *arg); + +// Unparks all threads waiting on `address`. +PyAPI_FUNC(void) _PyParkingLot_UnparkAll(const void *address); + +// Resets the parking lot state after a fork. Forgets all parked threads. +PyAPI_FUNC(void) _PyParkingLot_AfterFork(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PARKING_LOT_H */ diff --git a/Include/internal/pycore_parser.h b/Include/internal/pycore_parser.h index dd51b92801aebf..067b34c12c4e7f 100644 --- a/Include/internal/pycore_parser.h +++ b/Include/internal/pycore_parser.h @@ -58,7 +58,17 @@ extern struct _mod* _PyParser_ASTFromFile( PyCompilerFlags *flags, int *errcode, PyArena *arena); - +extern struct _mod* _PyParser_InteractiveASTFromFile( + FILE *fp, + PyObject *filename_ob, + const char *enc, + int mode, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyObject **interactive_src, + PyArena *arena); #ifdef __cplusplus } diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index b8deaa0c3eb067..a1ce1b19a00283 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.h @@ -8,7 +8,9 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(void) _PyPathConfig_ClearGlobal(void); + extern PyStatus _PyPathConfig_ReadGlobal(PyConfig *config); extern PyStatus _PyPathConfig_UpdateGlobal(const PyConfig *config); extern const wchar_t * _PyPathConfig_GetGlobalModuleSearchPath(void); diff --git a/Include/internal/pycore_pyarena.h b/Include/internal/pycore_pyarena.h index d78972a88ca238..1f07479fb2ca27 100644 --- a/Include/internal/pycore_pyarena.h +++ b/Include/internal/pycore_pyarena.h @@ -1,5 +1,4 @@ -/* An arena-like memory interface for the compiler. - */ +// An arena-like memory interface for the compiler. #ifndef Py_INTERNAL_PYARENA_H #define Py_INTERNAL_PYARENA_H @@ -13,49 +12,54 @@ extern "C" { typedef struct _arena PyArena; -/* _PyArena_New() and _PyArena_Free() create a new arena and free it, - respectively. Once an arena has been created, it can be used - to allocate memory via _PyArena_Malloc(). Pointers to PyObject can - also be registered with the arena via _PyArena_AddPyObject(), and the - arena will ensure that the PyObjects stay alive at least until - _PyArena_Free() is called. When an arena is freed, all the memory it - allocated is freed, the arena releases internal references to registered - PyObject*, and none of its pointers are valid. - XXX (tim) What does "none of its pointers are valid" mean? Does it - XXX mean that pointers previously obtained via _PyArena_Malloc() are - XXX no longer valid? (That's clearly true, but not sure that's what - XXX the text is trying to say.) - - _PyArena_New() returns an arena pointer. On error, it - returns a negative number and sets an exception. - XXX (tim): Not true. On error, _PyArena_New() actually returns NULL, - XXX and looks like it may or may not set an exception (e.g., if the - XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on - XXX and an exception is set; OTOH, if the internal - XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but - XXX an exception is not set in that case). -*/ +// _PyArena_New() and _PyArena_Free() create a new arena and free it, +// respectively. Once an arena has been created, it can be used +// to allocate memory via _PyArena_Malloc(). Pointers to PyObject can +// also be registered with the arena via _PyArena_AddPyObject(), and the +// arena will ensure that the PyObjects stay alive at least until +// _PyArena_Free() is called. When an arena is freed, all the memory it +// allocated is freed, the arena releases internal references to registered +// PyObject*, and none of its pointers are valid. +// XXX (tim) What does "none of its pointers are valid" mean? Does it +// XXX mean that pointers previously obtained via _PyArena_Malloc() are +// XXX no longer valid? (That's clearly true, but not sure that's what +// XXX the text is trying to say.) +// +// _PyArena_New() returns an arena pointer. On error, it +// returns a negative number and sets an exception. +// XXX (tim): Not true. On error, _PyArena_New() actually returns NULL, +// XXX and looks like it may or may not set an exception (e.g., if the +// XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on +// XXX and an exception is set; OTOH, if the internal +// XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but +// XXX an exception is not set in that case). +// +// Export for test_peg_generator PyAPI_FUNC(PyArena*) _PyArena_New(void); + +// Export for test_peg_generator PyAPI_FUNC(void) _PyArena_Free(PyArena *); -/* Mostly like malloc(), return the address of a block of memory spanning - * `size` bytes, or return NULL (without setting an exception) if enough - * new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with - * size=0 does not guarantee to return a unique pointer (the pointer - * returned may equal one or more other pointers obtained from - * _PyArena_Malloc()). - * Note that pointers obtained via _PyArena_Malloc() must never be passed to - * the system free() or realloc(), or to any of Python's similar memory- - * management functions. _PyArena_Malloc()-obtained pointers remain valid - * until _PyArena_Free(ar) is called, at which point all pointers obtained - * from the arena `ar` become invalid simultaneously. - */ +// Mostly like malloc(), return the address of a block of memory spanning +// `size` bytes, or return NULL (without setting an exception) if enough +// new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with +// size=0 does not guarantee to return a unique pointer (the pointer +// returned may equal one or more other pointers obtained from +// _PyArena_Malloc()). +// Note that pointers obtained via _PyArena_Malloc() must never be passed to +// the system free() or realloc(), or to any of Python's similar memory- +// management functions. _PyArena_Malloc()-obtained pointers remain valid +// until _PyArena_Free(ar) is called, at which point all pointers obtained +// from the arena `ar` become invalid simultaneously. +// +// Export for test_peg_generator PyAPI_FUNC(void*) _PyArena_Malloc(PyArena *, size_t size); -/* This routine isn't a proper arena allocation routine. It takes - * a PyObject* and records it so that it can be DECREFed when the - * arena is freed. - */ +// This routine isn't a proper arena allocation routine. It takes +// a PyObject* and records it so that it can be DECREFed when the +// arena is freed. +// +// Export for test_peg_generator PyAPI_FUNC(int) _PyArena_AddPyObject(PyArena *, PyObject *); #ifdef __cplusplus diff --git a/Include/internal/pycore_pybuffer.h b/Include/internal/pycore_pybuffer.h new file mode 100644 index 00000000000000..3cbc290b2ea3ee --- /dev/null +++ b/Include/internal/pycore_pybuffer.h @@ -0,0 +1,21 @@ +#ifndef Py_INTERNAL_PYBUFFER_H +#define Py_INTERNAL_PYBUFFER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +// Exported for the _xxinterpchannels module. +PyAPI_FUNC(int) _PyBuffer_ReleaseInInterpreter( + PyInterpreterState *interp, Py_buffer *view); +PyAPI_FUNC(int) _PyBuffer_ReleaseInInterpreterAndRawFree( + PyInterpreterState *interp, Py_buffer *view); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYBUFFER_H */ diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index e3ba4b75e3cfc3..184eb35e52b47b 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -11,46 +11,51 @@ extern "C" { /* Error handling definitions */ -PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate); -PyAPI_FUNC(PyObject*) _PyErr_GetHandledException(PyThreadState *); -PyAPI_FUNC(void) _PyErr_SetHandledException(PyThreadState *, PyObject *); -PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **); - -/* Like PyErr_Format(), but saves current exception as __context__ and - __cause__. - */ -PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause( +extern _PyErr_StackItem* _PyErr_GetTopmostException(PyThreadState *tstate); +extern PyObject* _PyErr_GetHandledException(PyThreadState *); +extern void _PyErr_SetHandledException(PyThreadState *, PyObject *); +extern void _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **); + +// Export for '_testinternalcapi' shared extension +PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); + + +// Like PyErr_Format(), but saves current exception as __context__ and +// __cause__. +// Export for '_sqlite3' shared extension. +PyAPI_FUNC(PyObject*) _PyErr_FormatFromCause( PyObject *exception, const char *format, /* ASCII-encoded string */ ... ); -PyAPI_FUNC(int) _PyException_AddNote( +extern int _PyException_AddNote( PyObject *exc, PyObject *note); -PyAPI_FUNC(int) _PyErr_CheckSignals(void); +extern int _PyErr_CheckSignals(void); /* Support for adding program text to SyntaxErrors */ -PyAPI_FUNC(PyObject *) _PyErr_ProgramDecodedTextObject( +// Export for test_peg_generator +PyAPI_FUNC(PyObject*) _PyErr_ProgramDecodedTextObject( PyObject *filename, int lineno, const char* encoding); -PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( +extern PyObject* _PyUnicodeTranslateError_Create( PyObject *object, Py_ssize_t start, Py_ssize_t end, const char *reason /* UTF-8 encoded string */ ); -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat( +extern void _Py_NO_RETURN _Py_FatalErrorFormat( const char *func, const char *format, ...); -extern PyObject *_PyErr_SetImportErrorWithNameFrom( +extern PyObject* _PyErr_SetImportErrorWithNameFrom( PyObject *, PyObject *, PyObject *, @@ -79,85 +84,97 @@ static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state) Py_CLEAR(exc_state->exc_value); } -PyAPI_FUNC(PyObject*) _PyErr_StackItemToExcInfoTuple( +extern PyObject* _PyErr_StackItemToExcInfoTuple( _PyErr_StackItem *err_info); -PyAPI_FUNC(void) _PyErr_Fetch( +extern void _PyErr_Fetch( PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **traceback); -extern PyObject * -_PyErr_GetRaisedException(PyThreadState *tstate); +extern PyObject* _PyErr_GetRaisedException(PyThreadState *tstate); -PyAPI_FUNC(int) _PyErr_ExceptionMatches( +extern int _PyErr_ExceptionMatches( PyThreadState *tstate, PyObject *exc); -void -_PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc); +extern void _PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc); -PyAPI_FUNC(void) _PyErr_Restore( +extern void _PyErr_Restore( PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *traceback); -PyAPI_FUNC(void) _PyErr_SetObject( +extern void _PyErr_SetObject( PyThreadState *tstate, PyObject *type, PyObject *value); -PyAPI_FUNC(void) _PyErr_ChainStackItem(void); +extern void _PyErr_ChainStackItem(void); -PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate); +extern void _PyErr_Clear(PyThreadState *tstate); -PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); +extern void _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); -PyAPI_FUNC(PyObject *) _PyErr_NoMemory(PyThreadState *tstate); +extern PyObject* _PyErr_NoMemory(PyThreadState *tstate); -PyAPI_FUNC(void) _PyErr_SetString( +extern void _PyErr_SetString( PyThreadState *tstate, PyObject *exception, const char *string); -PyAPI_FUNC(PyObject *) _PyErr_Format( +extern PyObject* _PyErr_Format( PyThreadState *tstate, PyObject *exception, const char *format, ...); -PyAPI_FUNC(void) _PyErr_NormalizeException( +extern void _PyErr_NormalizeException( PyThreadState *tstate, PyObject **exc, PyObject **val, PyObject **tb); -PyAPI_FUNC(PyObject *) _PyErr_FormatFromCauseTstate( +extern PyObject* _PyErr_FormatFromCauseTstate( PyThreadState *tstate, PyObject *exception, const char *format, ...); -PyAPI_FUNC(PyObject *) _PyExc_CreateExceptionGroup( +extern PyObject* _PyExc_CreateExceptionGroup( const char *msg, PyObject *excs); -PyAPI_FUNC(PyObject *) _PyExc_PrepReraiseStar( +extern PyObject* _PyExc_PrepReraiseStar( PyObject *orig, PyObject *excs); -PyAPI_FUNC(int) _PyErr_CheckSignalsTstate(PyThreadState *tstate); - -PyAPI_FUNC(void) _Py_DumpExtensionModules(int fd, PyInterpreterState *interp); +extern int _PyErr_CheckSignalsTstate(PyThreadState *tstate); +extern void _Py_DumpExtensionModules(int fd, PyInterpreterState *interp); +extern PyObject* _Py_CalculateSuggestions(PyObject *dir, PyObject *name); extern PyObject* _Py_Offer_Suggestions(PyObject* exception); + +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b, Py_ssize_t max_cost); void _PyErr_FormatNote(const char *format, ...); +/* Context manipulation (PEP 3134) */ + +Py_DEPRECATED(3.12) extern void _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); + +// Export for '_zoneinfo' shared extension +PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *); + +// Export for '_lsprof' shared extension +PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg( + const char *err_msg, + PyObject *obj); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pyhash.h b/Include/internal/pycore_pyhash.h index 34dfa53771288e..78bf0c7d07eb10 100644 --- a/Include/internal/pycore_pyhash.h +++ b/Include/internal/pycore_pyhash.h @@ -1,10 +1,89 @@ -#ifndef Py_INTERNAL_HASH_H -#define Py_INTERNAL_HASH_H +#ifndef Py_INTERNAL_PYHASH_H +#define Py_INTERNAL_PYHASH_H #ifndef Py_BUILD_CORE # error "this header requires Py_BUILD_CORE define" #endif +/* Helpers for hash functions */ +extern Py_hash_t _Py_HashDouble(PyObject *, double); + +// Export for '_decimal' shared extension +PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); + +// Similar to _Py_HashPointer(), but don't replace -1 with -2 +extern Py_hash_t _Py_HashPointerRaw(const void*); + +// Export for '_datetime' shared extension +PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); + +/* Prime multiplier used in string and various other hashes. */ +#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */ + +/* Parameters used for the numeric hash implementation. See notes for + _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on + reduction modulo the prime 2**_PyHASH_BITS - 1. */ + +#if SIZEOF_VOID_P >= 8 +# define _PyHASH_BITS 61 +#else +# define _PyHASH_BITS 31 +#endif + +#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1) +#define _PyHASH_INF 314159 +#define _PyHASH_IMAG _PyHASH_MULTIPLIER + +/* Hash secret + * + * memory layout on 64 bit systems + * cccccccc cccccccc cccccccc uc -- unsigned char[24] + * pppppppp ssssssss ........ fnv -- two Py_hash_t + * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t + * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t + * ........ ........ eeeeeeee pyexpat XML hash salt + * + * memory layout on 32 bit systems + * cccccccc cccccccc cccccccc uc + * ppppssss ........ ........ fnv -- two Py_hash_t + * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*) + * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t + * ........ ........ eeee.... pyexpat XML hash salt + * + * (*) The siphash member may not be available on 32 bit platforms without + * an unsigned int64 data type. + */ +typedef union { + /* ensure 24 bytes */ + unsigned char uc[24]; + /* two Py_hash_t for FNV */ + struct { + Py_hash_t prefix; + Py_hash_t suffix; + } fnv; + /* two uint64 for SipHash24 */ + struct { + uint64_t k0; + uint64_t k1; + } siphash; + /* a different (!) Py_hash_t for small string optimization */ + struct { + unsigned char padding[16]; + Py_hash_t suffix; + } djbx33a; + struct { + unsigned char padding[16]; + Py_hash_t hashsalt; + } expat; +} _Py_HashSecret_t; + +// Export for '_elementtree' shared extension +PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; + +#ifdef Py_DEBUG +extern int _Py_HashSecret_Initialized; +#endif + struct pyhash_runtime_state { struct { @@ -34,7 +113,6 @@ struct pyhash_runtime_state { } -uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); - +extern uint64_t _Py_KeyedHash(uint64_t key, const void *src, Py_ssize_t src_sz); -#endif // Py_INTERNAL_HASH_H +#endif // !Py_INTERNAL_PYHASH_H diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index fb28652515909d..ec003a1dad2595 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -98,16 +98,20 @@ extern int _Py_FdIsInteractive(FILE *fp, PyObject *filename); extern const char* _Py_gitidentifier(void); extern const char* _Py_gitversion(void); -extern int _Py_IsFinalizing(void); +// Export for '_asyncio' shared extension PyAPI_FUNC(int) _Py_IsInterpreterFinalizing(PyInterpreterState *interp); /* Random */ extern int _PyOS_URandom(void *buffer, Py_ssize_t size); + +// Export for '_random' shared extension PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size); /* Legacy locale support */ extern int _Py_CoerceLegacyLocale(int warn); extern int _Py_LegacyLocaleDetected(int warn); + +// Export for 'readline' shared extension PyAPI_FUNC(char*) _Py_SetLocaleFromEnv(int category); #ifdef __cplusplus diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index 81a707a0a5ddf3..6b5113714dbeb2 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -8,8 +8,20 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pymem.h" // PyMemAllocatorName +// Try to get the allocators name set by _PyMem_SetupAllocators(). +// Return NULL if unknown. +// Export for '_testinternalcapi' shared extension. +PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void); +// strdup() using PyMem_RawMalloc() +extern char* _PyMem_RawStrdup(const char *str); + +// strdup() using PyMem_Malloc(). +// Export for '_pickle ' shared extension. +PyAPI_FUNC(char*) _PyMem_Strdup(const char *str); + +// wcsdup() using PyMem_RawMalloc() +extern wchar_t* _PyMem_RawWcsdup(const wchar_t *str); typedef struct { /* We tag each block with an API ID in order to tag API violations */ @@ -36,7 +48,7 @@ struct _pymem_allocators { /* Set the memory allocator of the specified domain to the default. Save the old allocator into *old_alloc if it's non-NULL. Return on success, or return -1 if the domain is unknown. */ -PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( +extern int _PyMem_SetDefaultAllocator( PyMemAllocatorDomain domain, PyMemAllocatorEx *old_alloc); @@ -82,17 +94,17 @@ static inline int _PyMem_IsPtrFreed(const void *ptr) #endif } -PyAPI_FUNC(int) _PyMem_GetAllocatorName( +extern int _PyMem_GetAllocatorName( const char *name, PyMemAllocatorName *allocator); /* Configure the Python memory allocators. Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators. PYMEM_ALLOCATOR_NOT_SET does nothing. */ -PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); +extern int _PyMem_SetupAllocators(PyMemAllocatorName allocator); #ifdef __cplusplus } #endif -#endif /* !Py_INTERNAL_PYMEM_H */ +#endif // !Py_INTERNAL_PYMEM_H diff --git a/Include/internal/pycore_pymem_init.h b/Include/internal/pycore_pymem_init.h index 78232738cb09d5..119fa16fb911ae 100644 --- a/Include/internal/pycore_pymem_init.h +++ b/Include/internal/pycore_pymem_init.h @@ -8,8 +8,6 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_pymem.h" - /********************************/ /* the allocators' initializers */ diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 0659084194d293..7135b1e966feb5 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -8,7 +8,34 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_runtime.h" /* PyRuntimeState */ +#include "pycore_runtime.h" // _PyRuntime + + +// Values for PyThreadState.state. A thread must be in the "attached" state +// before calling most Python APIs. If the GIL is enabled, then "attached" +// implies that the thread holds the GIL and "detached" implies that the +// thread does not hold the GIL (or is in the process of releasing it). In +// `--disable-gil` builds, multiple threads may be "attached" to the same +// interpreter at the same time. Only the "bound" thread may perform the +// transitions between "attached" and "detached" on its own PyThreadState. +// +// The "gc" state is used to implement stop-the-world pauses, such as for +// cyclic garbage collection. It is only used in `--disable-gil` builds. It is +// similar to the "detached" state, but only the thread performing a +// stop-the-world pause may transition threads between the "detached" and "gc" +// states. A thread trying to "attach" from the "gc" state will block until +// it is transitioned back to "detached" when the stop-the-world pause is +// complete. +// +// State transition diagram: +// +// (bound thread) (stop-the-world thread) +// [attached] <-> [detached] <-> [gc] +// +// See `_PyThreadState_Attach()` and `_PyThreadState_Detach()`. +#define _Py_THREAD_DETACHED 0 +#define _Py_THREAD_ATTACHED 1 +#define _Py_THREAD_GC 2 /* Check if the current thread is the main thread. @@ -36,10 +63,20 @@ _Py_IsMainInterpreter(PyInterpreterState *interp) static inline int _Py_IsMainInterpreterFinalizing(PyInterpreterState *interp) { - return (_PyRuntimeState_GetFinalizing(interp->runtime) != NULL && - interp == &interp->runtime->_main_interpreter); + /* bpo-39877: Access _PyRuntime directly rather than using + tstate->interp->runtime to support calls from Python daemon threads. + After Py_Finalize() has been called, tstate can be a dangling pointer: + point to PyThreadState freed memory. */ + return (_PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL && + interp == &_PyRuntime._main_interpreter); } +// Export for _xxsubinterpreters module. +PyAPI_FUNC(int) _PyInterpreterState_SetRunningMain(PyInterpreterState *); +PyAPI_FUNC(void) _PyInterpreterState_SetNotRunningMain(PyInterpreterState *); +PyAPI_FUNC(int) _PyInterpreterState_IsRunningMain(PyInterpreterState *); +PyAPI_FUNC(int) _PyInterpreterState_FailIfRunningMain(PyInterpreterState *); + static inline const PyConfig * _Py_GetMainConfig(void) @@ -66,7 +103,16 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp) #if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE) extern _Py_thread_local PyThreadState *_Py_tss_tstate; #endif -PyAPI_DATA(PyThreadState *) _PyThreadState_GetCurrent(void); + +#ifndef NDEBUG +extern int _PyThreadState_CheckConsistency(PyThreadState *tstate); +#endif + +int _PyThreadState_MustExit(PyThreadState *tstate); + +// Export for most shared extensions, used via _PyThreadState_GET() static +// inline function. +PyAPI_FUNC(PyThreadState *) _PyThreadState_GetCurrent(void); /* Get the current Python thread state. @@ -74,7 +120,7 @@ PyAPI_DATA(PyThreadState *) _PyThreadState_GetCurrent(void); The caller must hold the GIL. - See also PyThreadState_Get() and _PyThreadState_UncheckedGet(). */ + See also PyThreadState_Get() and PyThreadState_GetUnchecked(). */ static inline PyThreadState* _PyThreadState_GET(void) { @@ -85,6 +131,21 @@ _PyThreadState_GET(void) #endif } +// Attaches the current thread to the interpreter. +// +// This may block while acquiring the GIL (if the GIL is enabled) or while +// waiting for a stop-the-world pause (if the GIL is disabled). +// +// High-level code should generally call PyEval_RestoreThread() instead, which +// calls this function. +void _PyThreadState_Attach(PyThreadState *tstate); + +// Detaches the current thread from the interpreter. +// +// High-level code should generally call PyEval_SaveThread() instead, which +// calls this function. +void _PyThreadState_Detach(PyThreadState *tstate); + static inline void _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate) @@ -121,15 +182,13 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) { // PyThreadState functions -PyAPI_FUNC(PyThreadState *) _PyThreadState_New(PyInterpreterState *interp); -PyAPI_FUNC(void) _PyThreadState_Bind(PyThreadState *tstate); -PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); - -extern void _PyThreadState_InitDetached(PyThreadState *, PyInterpreterState *); -extern void _PyThreadState_ClearDetached(PyThreadState *); -extern void _PyThreadState_BindDetached(PyThreadState *); -extern void _PyThreadState_UnbindDetached(PyThreadState *); +extern PyThreadState * _PyThreadState_New( + PyInterpreterState *interp, + int whence); +extern void _PyThreadState_Bind(PyThreadState *tstate); +extern void _PyThreadState_DeleteExcept(PyThreadState *tstate); +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(PyObject*) _PyThreadState_GetDict(PyThreadState *tstate); /* The implementation of sys._current_frames() Returns a dict mapping @@ -145,25 +204,25 @@ extern PyObject* _PyThread_CurrentExceptions(void); /* Other */ -PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( +extern PyThreadState * _PyThreadState_Swap( _PyRuntimeState *runtime, PyThreadState *newts); -PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); +extern PyStatus _PyInterpreterState_Enable(_PyRuntimeState *runtime); #ifdef HAVE_FORK extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); extern void _PySignal_AfterFork(void); #endif - +// Export for the stable ABI PyAPI_FUNC(int) _PyState_AddModule( PyThreadState *tstate, PyObject* module, PyModuleDef* def); -PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); +extern int _PyOS_InterruptOccurred(PyThreadState *tstate); #define HEAD_LOCK(runtime) \ PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) @@ -172,8 +231,17 @@ PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); // Get the configuration of the current interpreter. // The caller must hold the GIL. +// Export for test_peg_generator. PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); +// Get the single PyInterpreterState used by this process' GILState +// implementation. +// +// This function doesn't check for error. Return NULL before _PyGILState_Init() +// is called and after _PyGILState_Fini() is called. +// +// See also PyInterpreterState_Get() and _PyInterpreterState_GET(). +extern PyInterpreterState* _PyGILState_GetInterpreterStateUnsafe(void); #ifdef __cplusplus } diff --git a/Include/internal/pycore_pystats.h b/Include/internal/pycore_pystats.h new file mode 100644 index 00000000000000..f8af398a560586 --- /dev/null +++ b/Include/internal/pycore_pystats.h @@ -0,0 +1,21 @@ +#ifndef Py_INTERNAL_PYSTATS_H +#define Py_INTERNAL_PYSTATS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#ifdef Py_STATS +extern void _Py_StatsOn(void); +extern void _Py_StatsOff(void); +extern void _Py_StatsClear(void); +extern int _Py_PrintSpecializationStats(int to_file); +#endif + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_PYSTATS_H diff --git a/Include/internal/pycore_pythonrun.h b/Include/internal/pycore_pythonrun.h new file mode 100644 index 00000000000000..0bfc5704dc4c59 --- /dev/null +++ b/Include/internal/pycore_pythonrun.h @@ -0,0 +1,39 @@ +#ifndef Py_INTERNAL_PYTHONRUN_H +#define Py_INTERNAL_PYTHONRUN_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +extern int _PyRun_SimpleFileObject( + FILE *fp, + PyObject *filename, + int closeit, + PyCompilerFlags *flags); + +extern int _PyRun_AnyFileObject( + FILE *fp, + PyObject *filename, + int closeit, + PyCompilerFlags *flags); + +extern int _PyRun_InteractiveLoopObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); + +extern const char* _Py_SourceAsString( + PyObject *cmd, + const char *funcname, + const char *what, + PyCompilerFlags *cf, + PyObject **cmd_copy); + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_PYTHONRUN_H + diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h index f53921494c158f..f679c1bdb75499 100644 --- a/Include/internal/pycore_pythread.h +++ b/Include/internal/pycore_pythread.h @@ -8,42 +8,43 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +// Get _POSIX_THREADS and _POSIX_SEMAPHORES macros if available +#if (defined(HAVE_UNISTD_H) && !defined(_POSIX_THREADS) \ + && !defined(_POSIX_SEMAPHORES)) +# include // _POSIX_THREADS, _POSIX_SEMAPHORES +#endif +#if (defined(HAVE_PTHREAD_H) && !defined(_POSIX_THREADS) \ + && !defined(_POSIX_SEMAPHORES)) + // This means pthreads are not implemented in libc headers, hence the macro + // not present in . But they still can be implemented as an + // external library (e.g. gnu pth in pthread emulation) +# include // _POSIX_THREADS, _POSIX_SEMAPHORES +#endif +#if !defined(_POSIX_THREADS) && defined(__hpux) && defined(_SC_THREADS) + // Check if we're running on HP-UX and _SC_THREADS is defined. If so, then + // enough of the POSIX threads package is implemented to support Python + // threads. + // + // This is valid for HP-UX 11.23 running on an ia64 system. If needed, add + // a check of __ia64 to verify that we're running on an ia64 system instead + // of a pa-risc system. +# define _POSIX_THREADS +#endif -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include /* _POSIX_THREADS */ -# endif -# ifndef _POSIX_THREADS -/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then - enough of the Posix threads package is implemented to support python - threads. - - This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on an ia64 system instead - of a pa-risc system. -*/ -# ifdef __hpux -# ifdef _SC_THREADS -# define _POSIX_THREADS -# endif -# endif -# endif /* _POSIX_THREADS */ -#endif /* _POSIX_THREADS */ #if defined(_POSIX_THREADS) || defined(HAVE_PTHREAD_STUBS) -# define _USE_PTHREADS +# define _USE_PTHREADS #endif #if defined(_USE_PTHREADS) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) // monotonic is supported statically. It doesn't mean it works on runtime. -# define CONDATTR_MONOTONIC +# define CONDATTR_MONOTONIC #endif #if defined(HAVE_PTHREAD_STUBS) +#include // bool + // pthread_key struct py_stub_tls_entry { bool in_use; @@ -75,6 +76,14 @@ struct _pythread_runtime_state { }; +#ifdef HAVE_FORK +/* Private function to reinitialize a lock at fork in the child process. + Reset the lock to the unlocked state. + Return 0 on success, return -1 on error. */ +extern int _PyThread_at_fork_reinit(PyThread_type_lock *lock); +#endif /* HAVE_FORK */ + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index a16d4202b616db..f2383b43fabaf1 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -8,24 +8,22 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_atexit.h" // struct atexit_runtime_state -#include "pycore_atomic.h" /* _Py_atomic_address */ +#include "pycore_atexit.h" // struct _atexit_runtime_state #include "pycore_ceval_state.h" // struct _ceval_runtime_state -#include "pycore_floatobject.h" // struct _Py_float_runtime_state #include "pycore_faulthandler.h" // struct _faulthandler_runtime_state -#include "pycore_global_objects.h" // struct _Py_global_objects +#include "pycore_floatobject.h" // struct _Py_float_runtime_state #include "pycore_import.h" // struct _import_runtime_state #include "pycore_interp.h" // PyInterpreterState #include "pycore_object_state.h" // struct _py_object_runtime_state #include "pycore_parser.h" // struct _parser_runtime_state -#include "pycore_pymem.h" // struct _pymem_allocators #include "pycore_pyhash.h" // struct pyhash_runtime_state +#include "pycore_pymem.h" // struct _pymem_allocators #include "pycore_pythread.h" // struct _pythread_runtime_state #include "pycore_signal.h" // struct _signals_runtime_state #include "pycore_time.h" // struct _time_runtime_state #include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state -#include "pycore_typeobject.h" // struct types_runtime_state -#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids +#include "pycore_typeobject.h" // struct _types_runtime_state +#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_state struct _getargs_runtime_state { PyThread_type_lock mutex; @@ -80,7 +78,7 @@ typedef struct _Py_DebugOffsets { off_t prev; off_t next; off_t interp; - off_t cframe; + off_t current_frame; off_t thread_id; off_t native_thread_id; } thread_state; @@ -171,7 +169,9 @@ typedef struct pyruntimestate { Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing() to access it, don't access it directly. */ - _Py_atomic_address _finalizing; + PyThreadState *_finalizing; + /* The ID of the OS thread in which we are finalizing. */ + unsigned long _finalizing_id; struct pyinterpreters { PyThread_type_lock mutex; @@ -200,10 +200,7 @@ typedef struct pyruntimestate { tools. */ // XXX Remove this field once we have a tp_* slot. - struct _xidregistry { - PyThread_type_lock mutex; - struct _xidregitem *head; - } xidregistry; + struct _xidregistry xidregistry; struct _pymem_allocators allocators; struct _obmalloc_global_state obmalloc; @@ -249,6 +246,7 @@ typedef struct pyruntimestate { struct _types_runtime_state types; /* All the objects that are shared by the runtime's interpreters. */ + struct _Py_cached_objects cached_objects; struct _Py_static_objects static_objects; /* The following fields are here to avoid allocation during init. @@ -267,15 +265,25 @@ typedef struct pyruntimestate { /* PyInterpreterState.interpreters.main */ PyInterpreterState _main_interpreter; + +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) + // Used in "Python/emscripten_trampoline.c" to choose between type + // reflection trampoline and EM_JS trampoline. + bool wasm_type_reflection_available; +#endif + } _PyRuntimeState; /* other API */ +// Export _PyRuntime for shared extensions which use it in static inline +// functions for best performance, like _Py_IsMainThread() or _Py_ID(). +// It's also made accessible for debuggers and profilers. PyAPI_DATA(_PyRuntimeState) _PyRuntime; -PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); -PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); +extern PyStatus _PyRuntimeState_Init(_PyRuntimeState *runtime); +extern void _PyRuntimeState_Fini(_PyRuntimeState *runtime); #ifdef HAVE_FORK extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); @@ -283,19 +291,33 @@ extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); /* Initialize _PyRuntimeState. Return NULL on success, or return an error message on failure. */ -PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void); +extern PyStatus _PyRuntime_Initialize(void); -PyAPI_FUNC(void) _PyRuntime_Finalize(void); +extern void _PyRuntime_Finalize(void); static inline PyThreadState* _PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) { - return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing); + return (PyThreadState*)_Py_atomic_load_ptr_relaxed(&runtime->_finalizing); +} + +static inline unsigned long +_PyRuntimeState_GetFinalizingID(_PyRuntimeState *runtime) { + return _Py_atomic_load_ulong_relaxed(&runtime->_finalizing_id); } static inline void _PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) { - _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate); + _Py_atomic_store_ptr_relaxed(&runtime->_finalizing, tstate); + if (tstate == NULL) { + _Py_atomic_store_ulong_relaxed(&runtime->_finalizing_id, 0); + } + else { + // XXX Re-enable this assert once gh-109860 is fixed. + //assert(tstate->thread_id == PyThread_get_thread_ident()); + _Py_atomic_store_ulong_relaxed(&runtime->_finalizing_id, + tstate->thread_id); + } } #ifdef __cplusplus diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index e72e7422c7207e..574a3c1a9db66c 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -8,11 +8,17 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_long.h" -#include "pycore_object.h" -#include "pycore_parser.h" -#include "pycore_pymem_init.h" -#include "pycore_obmalloc_init.h" +#include "pycore_ceval_state.h" // _PyEval_RUNTIME_PERF_INIT +#include "pycore_faulthandler.h" // _faulthandler_runtime_state_INIT +#include "pycore_floatobject.h" // _py_float_format_unknown +#include "pycore_object.h" // _PyObject_HEAD_INIT +#include "pycore_obmalloc_init.h" // _obmalloc_global_state_INIT +#include "pycore_parser.h" // _parser_runtime_state_INIT +#include "pycore_pyhash.h" // pyhash_state_INIT +#include "pycore_pymem_init.h" // _pymem_allocators_standard_INIT +#include "pycore_runtime_init_generated.h" // _Py_bytes_characters_INIT +#include "pycore_signal.h" // _signals_RUNTIME_INIT +#include "pycore_tracemalloc.h" // _tracemalloc_runtime_state_INIT extern PyTypeObject _PyExc_MemoryError; @@ -45,7 +51,7 @@ extern PyTypeObject _PyExc_MemoryError; .prev = offsetof(PyThreadState, prev), \ .next = offsetof(PyThreadState, next), \ .interp = offsetof(PyThreadState, interp), \ - .cframe = offsetof(PyThreadState, cframe), \ + .current_frame = offsetof(PyThreadState, current_frame), \ .thread_id = offsetof(PyThreadState, thread_id), \ .native_thread_id = offsetof(PyThreadState, native_thread_id), \ }, \ @@ -56,10 +62,6 @@ extern PyTypeObject _PyExc_MemoryError; .localsplus = offsetof(_PyInterpreterFrame, localsplus), \ .owner = offsetof(_PyInterpreterFrame, owner), \ }, \ - .cframe = { \ - .current_frame = offsetof(_PyCFrame, current_frame), \ - .previous = offsetof(_PyCFrame, previous), \ - }, \ .code_object = { \ .filename = offsetof(PyCodeObject, co_filename), \ .name = offsetof(PyCodeObject, co_name), \ @@ -97,11 +99,6 @@ extern PyTypeObject _PyExc_MemoryError; in accordance with the specification. */ \ .autoTSSkey = Py_tss_NEEDS_INIT, \ .parser = _parser_runtime_state_INIT, \ - .imports = { \ - .extensions = { \ - .main_tstate = _PyThreadState_INIT, \ - }, \ - }, \ .ceval = { \ .perf = _PyEval_RUNTIME_PERF_INIT, \ }, \ @@ -162,6 +159,7 @@ extern PyTypeObject _PyExc_MemoryError; { .threshold = 10, }, \ }, \ }, \ + .object_state = _py_object_state_INIT(INTERP), \ .dtoa = _dtoa_state_INIT(&(INTERP)), \ .dict_state = _dict_state_INIT, \ .func_state = { \ @@ -187,10 +185,21 @@ extern PyTypeObject _PyExc_MemoryError; #define _PyThreadState_INIT \ { \ + ._whence = _PyThreadState_WHENCE_NOTSET, \ .py_recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ .context_ver = 1, \ } +#ifdef Py_TRACE_REFS +# define _py_object_state_INIT(INTERP) \ + { \ + .refchain = NULL, \ + } +#else +# define _py_object_state_INIT(INTERP) \ + { 0 } +#endif + // global objects @@ -214,6 +223,7 @@ extern PyTypeObject _PyExc_MemoryError; .kind = 1, \ .compact = 1, \ .ascii = (ASCII), \ + .statically_allocated = 1, \ }, \ } #define _PyASCIIObject_INIT(LITERAL) \ diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 2d66647438b193..43a8243bf41b7e 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -8,6 +8,9 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_long.h" // _PyLong_DIGIT_INIT() + + /* The following is auto-generated by Tools/build/generate_global_objects.py. */ #define _Py_small_ints_INIT { \ _PyLong_DIGIT_INIT(-5), \ @@ -539,6 +542,7 @@ extern "C" { INIT_STR(anon_lambda, ""), \ INIT_STR(anon_listcomp, ""), \ INIT_STR(anon_module, ""), \ + INIT_STR(anon_null, ""), \ INIT_STR(anon_setcomp, ""), \ INIT_STR(anon_string, ""), \ INIT_STR(anon_unknown, ""), \ @@ -781,11 +785,8 @@ extern "C" { INIT_ID(after_in_child), \ INIT_ID(after_in_parent), \ INIT_ID(aggregate_class), \ - INIT_ID(alias), \ INIT_ID(append), \ - INIT_ID(arg), \ INIT_ID(argdefs), \ - INIT_ID(args), \ INIT_ID(arguments), \ INIT_ID(argv), \ INIT_ID(as_integer_ratio), \ @@ -909,14 +910,13 @@ extern "C" { INIT_ID(errors), \ INIT_ID(event), \ INIT_ID(eventmask), \ - INIT_ID(exc_type), \ - INIT_ID(exc_value), \ INIT_ID(excepthook), \ INIT_ID(exception), \ INIT_ID(existing_file_name), \ INIT_ID(exp), \ INIT_ID(extend), \ INIT_ID(extra_tokens), \ + INIT_ID(f), \ INIT_ID(facility), \ INIT_ID(factory), \ INIT_ID(false), \ @@ -948,6 +948,7 @@ extern "C" { INIT_ID(fset), \ INIT_ID(func), \ INIT_ID(future), \ + INIT_ID(g), \ INIT_ID(generation), \ INIT_ID(genexpr), \ INIT_ID(get), \ @@ -961,6 +962,7 @@ extern "C" { INIT_ID(globals), \ INIT_ID(groupindex), \ INIT_ID(groups), \ + INIT_ID(h), \ INIT_ID(handle), \ INIT_ID(hash_name), \ INIT_ID(header), \ @@ -989,6 +991,7 @@ extern "C" { INIT_ID(instructions), \ INIT_ID(intern), \ INIT_ID(intersection), \ + INIT_ID(interval), \ INIT_ID(is_running), \ INIT_ID(isatty), \ INIT_ID(isinstance), \ @@ -1223,7 +1226,6 @@ extern "C" { INIT_ID(timetuple), \ INIT_ID(top), \ INIT_ID(trace_callback), \ - INIT_ID(traceback), \ INIT_ID(trailers), \ INIT_ID(translate), \ INIT_ID(true), \ diff --git a/Include/internal/pycore_semaphore.h b/Include/internal/pycore_semaphore.h new file mode 100644 index 00000000000000..4c37df7b39a48a --- /dev/null +++ b/Include/internal/pycore_semaphore.h @@ -0,0 +1,66 @@ +// The _PySemaphore API a simplified cross-platform semaphore used to implement +// wakeup/sleep. +#ifndef Py_INTERNAL_SEMAPHORE_H +#define Py_INTERNAL_SEMAPHORE_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pythread.h" // _POSIX_SEMAPHORES +#include "pycore_time.h" // _PyTime_t + +#ifdef MS_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include +#elif defined(HAVE_PTHREAD_H) +# include +#elif defined(HAVE_PTHREAD_STUBS) +# include "cpython/pthread_stubs.h" +#else +# error "Require native threads. See https://bugs.python.org/issue31370" +#endif + +#if (defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES+0) != -1 && \ + defined(HAVE_SEM_TIMEDWAIT)) +# define _Py_USE_SEMAPHORES +# include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _PySemaphore { +#if defined(MS_WINDOWS) + HANDLE platform_sem; +#elif defined(_Py_USE_SEMAPHORES) + sem_t platform_sem; +#else + pthread_mutex_t mutex; + pthread_cond_t cond; + int counter; +#endif +} _PySemaphore; + +// Puts the current thread to sleep until _PySemaphore_Wakeup() is called. +// If `detach` is true, then the thread will detach/release the GIL while +// sleeping. +PyAPI_FUNC(int) +_PySemaphore_Wait(_PySemaphore *sema, _PyTime_t timeout_ns, int detach); + +// Wakes up a single thread waiting on sema. Note that _PySemaphore_Wakeup() +// can be called before _PySemaphore_Wait(). +PyAPI_FUNC(void) +_PySemaphore_Wakeup(_PySemaphore *sema); + +// Initializes/destroys a semaphore +PyAPI_FUNC(void) _PySemaphore_Init(_PySemaphore *sema); +PyAPI_FUNC(void) _PySemaphore_Destroy(_PySemaphore *sema); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_SEMAPHORE_H */ diff --git a/Include/internal/pycore_setobject.h b/Include/internal/pycore_setobject.h new file mode 100644 index 00000000000000..34a00e6d45fe69 --- /dev/null +++ b/Include/internal/pycore_setobject.h @@ -0,0 +1,27 @@ +#ifndef Py_INTERNAL_SETOBJECT_H +#define Py_INTERNAL_SETOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +// Export for '_pickle' shared extension +PyAPI_FUNC(int) _PySet_NextEntry( + PyObject *set, + Py_ssize_t *pos, + PyObject **key, + Py_hash_t *hash); + +// Export for '_pickle' shared extension +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); + +// Export for the gdb plugin's (python-gdb.py) benefit +PyAPI_DATA(PyObject *) _PySet_Dummy; + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_SETOBJECT_H diff --git a/Include/internal/pycore_signal.h b/Include/internal/pycore_signal.h index 1a454ba6f4e8fb..47213a34ab77b5 100644 --- a/Include/internal/pycore_signal.h +++ b/Include/internal/pycore_signal.h @@ -10,11 +10,11 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_atomic.h" // _Py_atomic_address -#include // NSIG +#include // NSIG -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ +// Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. +// Export for '_posixsubprocess' shared extension. PyAPI_FUNC(void) _Py_RestoreSignals(void); #ifdef _SIG_MAXSIG @@ -37,12 +37,10 @@ PyAPI_FUNC(void) _Py_RestoreSignals(void); #define INVALID_FD (-1) struct _signals_runtime_state { - volatile struct { - _Py_atomic_int tripped; - /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe - * (even though it would probably be otherwise, anyway). - */ - _Py_atomic_address func; + struct { + // tripped and func should be accessed using atomic ops. + int tripped; + PyObject* func; } handlers[Py_NSIG]; volatile struct { @@ -62,8 +60,9 @@ struct _signals_runtime_state { #endif } wakeup; - /* Speed up sigcheck() when none tripped */ - _Py_atomic_int is_tripped; + /* Speed up sigcheck() when none tripped. + is_tripped should be accessed using atomic ops. */ + int is_tripped; /* These objects necessarily belong to the main interpreter. */ PyObject *default_handler; @@ -94,6 +93,15 @@ struct _signals_runtime_state { } +// Export for '_multiprocessing' shared extension +PyAPI_FUNC(int) _PyOS_IsMainThread(void); + +#ifdef MS_WINDOWS +// is not included by Python.h so use void* instead of HANDLE. +// Export for '_multiprocessing' shared extension +PyAPI_FUNC(void*) _PyOS_SigintEvent(void); +#endif + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_strhex.h b/Include/internal/pycore_strhex.h index f427b4d695bd29..225f423912f2c2 100644 --- a/Include/internal/pycore_strhex.h +++ b/Include/internal/pycore_strhex.h @@ -9,21 +9,24 @@ extern "C" { #endif // Returns a str() containing the hex representation of argbuf. +// Export for '_hashlib' shared extension. PyAPI_FUNC(PyObject*) _Py_strhex(const char* argbuf, const Py_ssize_t arglen); // Returns a bytes() containing the ASCII hex representation of argbuf. -PyAPI_FUNC(PyObject*) _Py_strhex_bytes( +extern PyObject* _Py_strhex_bytes( const char* argbuf, const Py_ssize_t arglen); // These variants include support for a separator between every N bytes: -PyAPI_FUNC(PyObject*) _Py_strhex_with_sep( +extern PyObject* _Py_strhex_with_sep( const char* argbuf, const Py_ssize_t arglen, PyObject* sep, const int bytes_per_group); + +// Export for 'binascii' shared extension PyAPI_FUNC(PyObject*) _Py_strhex_bytes_with_sep( const char* argbuf, const Py_ssize_t arglen, diff --git a/Include/internal/pycore_structseq.h b/Include/internal/pycore_structseq.h index 6f5dfc12707cf8..5cff165627502b 100644 --- a/Include/internal/pycore_structseq.h +++ b/Include/internal/pycore_structseq.h @@ -11,7 +11,8 @@ extern "C" { /* other API */ -PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType( +// Export for '_curses' shared extension +PyAPI_FUNC(PyTypeObject*) _PyStructSequence_NewType( PyStructSequence_Desc *desc, unsigned long tp_flags); diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index c8e0578a231756..1d782ca2c96e05 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -101,7 +101,7 @@ extern struct symtable* _PySymtable_Build( struct _mod *mod, PyObject *filename, PyFutureFeatures *future); -PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); +extern PySTEntryObject* _PySymtable_Lookup(struct symtable *, void *); extern void _PySymtable_Free(struct symtable *); diff --git a/Include/internal/pycore_sysmodule.h b/Include/internal/pycore_sysmodule.h index b4b1febafa4479..9b8eafd3d6cfd3 100644 --- a/Include/internal/pycore_sysmodule.h +++ b/Include/internal/pycore_sysmodule.h @@ -8,17 +8,23 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -PyAPI_FUNC(int) _PySys_Audit( +// Export for '_pickle' shared extension +PyAPI_FUNC(PyObject*) _PySys_GetAttr(PyThreadState *tstate, PyObject *name); + +// Export for '_pickle' shared extension +PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); + +extern int _PySys_Audit( PyThreadState *tstate, const char *event, const char *argFormat, ...); -/* We want minimal exposure of this function, so use extern rather than - PyAPI_FUNC() to not export the symbol. */ +// _PySys_ClearAuditHooks() must not be exported: use extern rather than +// PyAPI_FUNC(). We want minimal exposure of this function. extern void _PySys_ClearAuditHooks(PyThreadState *tstate); -PyAPI_FUNC(int) _PySys_SetAttr(PyObject *, PyObject *); +extern int _PySys_SetAttr(PyObject *, PyObject *); extern int _PySys_ClearAttrString(PyInterpreterState *interp, const char *name, int verbose); diff --git a/Include/internal/pycore_time.h b/Include/internal/pycore_time.h index 3d394e8d36a132..46713f91d190ff 100644 --- a/Include/internal/pycore_time.h +++ b/Include/internal/pycore_time.h @@ -66,9 +66,9 @@ struct _time_runtime_state { struct timeval; #endif -/* _PyTime_t: Python timestamp with subsecond precision. It can be used to - store a duration, and so indirectly a date (related to another date, like - UNIX epoch). */ +// _PyTime_t: Python timestamp with subsecond precision. It can be used to +// store a duration, and so indirectly a date (related to another date, like +// UNIX epoch). typedef int64_t _PyTime_t; // _PyTime_MIN nanoseconds is around -292.3 years #define _PyTime_MIN INT64_MIN @@ -77,52 +77,61 @@ typedef int64_t _PyTime_t; #define _SIZEOF_PYTIME_T 8 typedef enum { - /* Round towards minus infinity (-inf). - For example, used to read a clock. */ + // Round towards minus infinity (-inf). + // For example, used to read a clock. _PyTime_ROUND_FLOOR=0, - /* Round towards infinity (+inf). - For example, used for timeout to wait "at least" N seconds. */ + + // Round towards infinity (+inf). + // For example, used for timeout to wait "at least" N seconds. _PyTime_ROUND_CEILING=1, - /* Round to nearest with ties going to nearest even integer. - For example, used to round from a Python float. */ + + // Round to nearest with ties going to nearest even integer. + // For example, used to round from a Python float. _PyTime_ROUND_HALF_EVEN=2, - /* Round away from zero - For example, used for timeout. _PyTime_ROUND_CEILING rounds - -1e-9 to 0 milliseconds which causes bpo-31786 issue. - _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps - the timeout sign as expected. select.poll(timeout) must block - for negative values." */ + + // Round away from zero + // For example, used for timeout. _PyTime_ROUND_CEILING rounds + // -1e-9 to 0 milliseconds which causes bpo-31786 issue. + // _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps + // the timeout sign as expected. select.poll(timeout) must block + // for negative values. _PyTime_ROUND_UP=3, - /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be - used for timeouts. */ + + // _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be + // used for timeouts. _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP } _PyTime_round_t; -/* Convert a time_t to a PyLong. */ +// Convert a time_t to a PyLong. +// Export for '_testinternalcapi' shared extension PyAPI_FUNC(PyObject*) _PyLong_FromTime_t(time_t sec); -/* Convert a PyLong to a time_t. */ +// Convert a PyLong to a time_t. +// Export for '_datetime' shared extension PyAPI_FUNC(time_t) _PyLong_AsTime_t(PyObject *obj); -/* Convert a number of seconds, int or float, to time_t. */ +// Convert a number of seconds, int or float, to time_t. +// Export for '_datetime' shared extension. PyAPI_FUNC(int) _PyTime_ObjectToTime_t( PyObject *obj, time_t *sec, _PyTime_round_t); -/* Convert a number of seconds, int or float, to a timeval structure. - usec is in the range [0; 999999] and rounded towards zero. - For example, -1.2 is converted to (-2, 800000). */ +// Convert a number of seconds, int or float, to a timeval structure. +// usec is in the range [0; 999999] and rounded towards zero. +// For example, -1.2 is converted to (-2, 800000). +// Export for '_datetime' shared extension. PyAPI_FUNC(int) _PyTime_ObjectToTimeval( PyObject *obj, time_t *sec, long *usec, _PyTime_round_t); -/* Convert a number of seconds, int or float, to a timespec structure. - nsec is in the range [0; 999999999] and rounded towards zero. - For example, -1.2 is converted to (-2, 800000000). */ +// Convert a number of seconds, int or float, to a timespec structure. +// nsec is in the range [0; 999999999] and rounded towards zero. +// For example, -1.2 is converted to (-2, 800000000). +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(int) _PyTime_ObjectToTimespec( PyObject *obj, time_t *sec, @@ -130,50 +139,62 @@ PyAPI_FUNC(int) _PyTime_ObjectToTimespec( _PyTime_round_t); -/* Create a timestamp from a number of seconds. */ +// Create a timestamp from a number of seconds. +// Export for '_socket' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); -/* Macro to create a timestamp from a number of seconds, no integer overflow. - Only use the macro for small values, prefer _PyTime_FromSeconds(). */ +// Create a timestamp from a number of seconds in double. +// Export for '_socket' shared extension. +PyAPI_FUNC(_PyTime_t) _PyTime_FromSecondsDouble(double seconds, _PyTime_round_t round); + +// Macro to create a timestamp from a number of seconds, no integer overflow. +// Only use the macro for small values, prefer _PyTime_FromSeconds(). #define _PYTIME_FROMSECONDS(seconds) \ ((_PyTime_t)(seconds) * (1000 * 1000 * 1000)) -/* Create a timestamp from a number of nanoseconds. */ +// Create a timestamp from a number of nanoseconds. +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); -/* Create a timestamp from a number of microseconds. - * Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. */ +// Create a timestamp from a number of microseconds. +// Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. extern _PyTime_t _PyTime_FromMicrosecondsClamp(_PyTime_t us); -/* Create a timestamp from nanoseconds (Python int). */ +// Create a timestamp from nanoseconds (Python int). +// Export for '_lsprof' shared extension. PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, PyObject *obj); -/* Convert a number of seconds (Python float or int) to a timestamp. - Raise an exception and return -1 on error, return 0 on success. */ +// Convert a number of seconds (Python float or int) to a timestamp. +// Raise an exception and return -1 on error, return 0 on success. +// Export for '_socket' shared extension. PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round); -/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp. - Raise an exception and return -1 on error, return 0 on success. */ +// Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp. +// Raise an exception and return -1 on error, return 0 on success. +// Export for 'select' shared extension. PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round); -/* Convert a timestamp to a number of seconds as a C double. */ +// Convert a timestamp to a number of seconds as a C double. +// Export for '_socket' shared extension. PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); -/* Convert timestamp to a number of milliseconds (10^-3 seconds). */ +// Convert timestamp to a number of milliseconds (10^-3 seconds). +// Export for '_ssl' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round); -/* Convert timestamp to a number of microseconds (10^-6 seconds). */ +// Convert timestamp to a number of microseconds (10^-6 seconds). +// Export for '_queue' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round); -/* Convert timestamp to a number of nanoseconds (10^-9 seconds). */ -PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t); +// Convert timestamp to a number of nanoseconds (10^-9 seconds). +extern _PyTime_t _PyTime_AsNanoseconds(_PyTime_t t); #ifdef MS_WINDOWS // Convert timestamp to a number of 100 nanoseconds (10^-7 seconds). @@ -181,36 +202,40 @@ extern _PyTime_t _PyTime_As100Nanoseconds(_PyTime_t t, _PyTime_round_t round); #endif -/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int - object. */ +// Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int +// object. +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(PyObject*) _PyTime_AsNanosecondsObject(_PyTime_t t); #ifndef MS_WINDOWS -/* Create a timestamp from a timeval structure. - Raise an exception and return -1 on overflow, return 0 on success. */ +// Create a timestamp from a timeval structure. +// Raise an exception and return -1 on overflow, return 0 on success. extern int _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); #endif -/* Convert a timestamp to a timeval structure (microsecond resolution). - tv_usec is always positive. - Raise an exception and return -1 if the conversion overflowed, - return 0 on success. */ +// Convert a timestamp to a timeval structure (microsecond resolution). +// tv_usec is always positive. +// Raise an exception and return -1 if the conversion overflowed, +// return 0 on success. +// Export for 'select' shared extension. PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round); -/* Similar to _PyTime_AsTimeval() but don't raise an exception on overflow. - On overflow, clamp tv_sec to _PyTime_t min/max. */ +// Similar to _PyTime_AsTimeval() but don't raise an exception on overflow. +// On overflow, clamp tv_sec to _PyTime_t min/max. +// Export for 'select' shared extension. PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(_PyTime_t t, struct timeval *tv, _PyTime_round_t round); -/* Convert a timestamp to a number of seconds (secs) and microseconds (us). - us is always positive. This function is similar to _PyTime_AsTimeval() - except that secs is always a time_t type, whereas the timeval structure - uses a C long for tv_sec on Windows. - Raise an exception and return -1 if the conversion overflowed, - return 0 on success. */ +// Convert a timestamp to a number of seconds (secs) and microseconds (us). +// us is always positive. This function is similar to _PyTime_AsTimeval() +// except that secs is always a time_t type, whereas the timeval structure +// uses a C long for tv_sec on Windows. +// Raise an exception and return -1 if the conversion overflowed, +// return 0 on success. +// Export for '_datetime' shared extension. PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( _PyTime_t t, time_t *secs, @@ -218,17 +243,19 @@ PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( _PyTime_round_t round); #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) -/* Create a timestamp from a timespec structure. - Raise an exception and return -1 on overflow, return 0 on success. */ -extern int _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts); - -/* Convert a timestamp to a timespec structure (nanosecond resolution). - tv_nsec is always positive. - Raise an exception and return -1 on error, return 0 on success. */ +// Create a timestamp from a timespec structure. +// Raise an exception and return -1 on overflow, return 0 on success. +extern int _PyTime_FromTimespec(_PyTime_t *tp, const struct timespec *ts); + +// Convert a timestamp to a timespec structure (nanosecond resolution). +// tv_nsec is always positive. +// Raise an exception and return -1 on error, return 0 on success. +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts); -/* Similar to _PyTime_AsTimespec() but don't raise an exception on overflow. - On overflow, clamp tv_sec to _PyTime_t min/max. */ +// Similar to _PyTime_AsTimespec() but don't raise an exception on overflow. +// On overflow, clamp tv_sec to _PyTime_t min/max. +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts); #endif @@ -236,14 +263,14 @@ PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts); // Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. extern _PyTime_t _PyTime_Add(_PyTime_t t1, _PyTime_t t2); -/* Compute ticks * mul / div. - Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. - The caller must ensure that ((div - 1) * mul) cannot overflow. */ +// Compute ticks * mul / div. +// Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +// The caller must ensure that ((div - 1) * mul) cannot overflow. extern _PyTime_t _PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div); -/* Structure used by time.get_clock_info() */ +// Structure used by time.get_clock_info() typedef struct { const char *implementation; int monotonic; @@ -251,72 +278,77 @@ typedef struct { double resolution; } _Py_clock_info_t; -/* Get the current time from the system clock. - - If the internal clock fails, silently ignore the error and return 0. - On integer overflow, silently ignore the overflow and clamp the clock to - [_PyTime_MIN; _PyTime_MAX]. - - Use _PyTime_GetSystemClockWithInfo() to check for failure. */ +// Get the current time from the system clock. +// +// If the internal clock fails, silently ignore the error and return 0. +// On integer overflow, silently ignore the overflow and clamp the clock to +// [_PyTime_MIN; _PyTime_MAX]. +// +// Use _PyTime_GetSystemClockWithInfo() to check for failure. +// Export for '_random' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); -/* Get the current time from the system clock. - * On success, set *t and *info (if not NULL), and return 0. - * On error, raise an exception and return -1. - */ -PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( +// Get the current time from the system clock. +// On success, set *t and *info (if not NULL), and return 0. +// On error, raise an exception and return -1. +extern int _PyTime_GetSystemClockWithInfo( _PyTime_t *t, _Py_clock_info_t *info); -/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. - The clock is not affected by system clock updates. The reference point of - the returned value is undefined, so that only the difference between the - results of consecutive calls is valid. - - If the internal clock fails, silently ignore the error and return 0. - On integer overflow, silently ignore the overflow and clamp the clock to - [_PyTime_MIN; _PyTime_MAX]. - - Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */ +// Get the time of a monotonic clock, i.e. a clock that cannot go backwards. +// The clock is not affected by system clock updates. The reference point of +// the returned value is undefined, so that only the difference between the +// results of consecutive calls is valid. +// +// If the internal clock fails, silently ignore the error and return 0. +// On integer overflow, silently ignore the overflow and clamp the clock to +// [_PyTime_MIN; _PyTime_MAX]. +// +// Use _PyTime_GetMonotonicClockWithInfo() to check for failure. +// Export for '_random' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); -/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. - The clock is not affected by system clock updates. The reference point of - the returned value is undefined, so that only the difference between the - results of consecutive calls is valid. - - Fill info (if set) with information of the function used to get the time. - - Return 0 on success, raise an exception and return -1 on error. */ +// Get the time of a monotonic clock, i.e. a clock that cannot go backwards. +// The clock is not affected by system clock updates. The reference point of +// the returned value is undefined, so that only the difference between the +// results of consecutive calls is valid. +// +// Fill info (if set) with information of the function used to get the time. +// +// Return 0 on success, raise an exception and return -1 on error. +// Export for '_testsinglephase' shared extension. PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo( _PyTime_t *t, _Py_clock_info_t *info); -/* Converts a timestamp to the Gregorian time, using the local time zone. - Return 0 on success, raise an exception and return -1 on error. */ +// Converts a timestamp to the Gregorian time, using the local time zone. +// Return 0 on success, raise an exception and return -1 on error. +// Export for '_datetime' shared extension. PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); -/* Converts a timestamp to the Gregorian time, assuming UTC. - Return 0 on success, raise an exception and return -1 on error. */ +// Converts a timestamp to the Gregorian time, assuming UTC. +// Return 0 on success, raise an exception and return -1 on error. +// Export for '_datetime' shared extension. PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); -/* Get the performance counter: clock with the highest available resolution to - measure a short duration. - - If the internal clock fails, silently ignore the error and return 0. - On integer overflow, silently ignore the overflow and clamp the clock to - [_PyTime_MIN; _PyTime_MAX]. - - Use _PyTime_GetPerfCounterWithInfo() to check for failure. */ +// Get the performance counter: clock with the highest available resolution to +// measure a short duration. +// +// If the internal clock fails, silently ignore the error and return 0. +// On integer overflow, silently ignore the overflow and clamp the clock to +// [_PyTime_MIN; _PyTime_MAX]. +// +// Use _PyTime_GetPerfCounterWithInfo() to check for failure. +// Export for '_lsprof' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); -/* Get the performance counter: clock with the highest available resolution to - measure a short duration. - - Fill info (if set) with information of the function used to get the time. - - Return 0 on success, raise an exception and return -1 on error. */ +// Get the performance counter: clock with the highest available resolution to +// measure a short duration. +// +// Fill info (if set) with information of the function used to get the time. +// +// Return 0 on success, raise an exception and return -1 on error. extern int _PyTime_GetPerfCounterWithInfo( _PyTime_t *t, _Py_clock_info_t *info); @@ -324,14 +356,16 @@ extern int _PyTime_GetPerfCounterWithInfo( // Create a deadline. // Pseudo code: _PyTime_GetMonotonicClock() + timeout. +// Export for '_ssl' shared extension. PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout); // Get remaining time from a deadline. // Pseudo code: deadline - _PyTime_GetMonotonicClock(). +// Export for '_ssl' shared extension. PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline); #ifdef __cplusplus } #endif -#endif /* !Py_INTERNAL_TIME_H */ +#endif // !Py_INTERNAL_TIME_H diff --git a/Include/internal/pycore_token.h b/Include/internal/pycore_token.h index c02e637fee1ee2..571cd6249f2812 100644 --- a/Include/internal/pycore_token.h +++ b/Include/internal/pycore_token.h @@ -1,4 +1,4 @@ -/* Auto-generated by Tools/build/generate_token.py */ +// Auto-generated by Tools/build/generate_token.py /* Token types */ #ifndef Py_INTERNAL_TOKEN_H @@ -69,18 +69,16 @@ extern "C" { #define COLONEQUAL 53 #define EXCLAMATION 54 #define OP 55 -#define AWAIT 56 -#define ASYNC 57 -#define TYPE_IGNORE 58 -#define TYPE_COMMENT 59 -#define SOFT_KEYWORD 60 -#define FSTRING_START 61 -#define FSTRING_MIDDLE 62 -#define FSTRING_END 63 -#define COMMENT 64 -#define NL 65 -#define ERRORTOKEN 66 -#define N_TOKENS 68 +#define TYPE_IGNORE 56 +#define TYPE_COMMENT 57 +#define SOFT_KEYWORD 58 +#define FSTRING_START 59 +#define FSTRING_MIDDLE 60 +#define FSTRING_END 61 +#define COMMENT 62 +#define NL 63 +#define ERRORTOKEN 64 +#define N_TOKENS 66 #define NT_OFFSET 256 /* Special definitions for cooperation with parser */ @@ -96,7 +94,7 @@ extern "C" { (x) == FSTRING_MIDDLE) -// Symbols exported for test_peg_generator +// Export these 4 symbols for 'test_peg_generator' PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ PyAPI_FUNC(int) _PyToken_OneChar(int); PyAPI_FUNC(int) _PyToken_TwoChars(int, int); diff --git a/Include/internal/pycore_traceback.h b/Include/internal/pycore_traceback.h index c393b2c136f2de..10922bff98bd4b 100644 --- a/Include/internal/pycore_traceback.h +++ b/Include/internal/pycore_traceback.h @@ -8,6 +8,12 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +// Export for '_ctypes' shared extension +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **); + +// Export for 'pyexact' shared extension +PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); + /* Write the Python traceback into the file 'fd'. For example: Traceback (most recent call first): @@ -25,7 +31,7 @@ extern "C" { This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpTraceback( +extern void _Py_DumpTraceback( int fd, PyThreadState *tstate); @@ -52,7 +58,7 @@ PyAPI_FUNC(void) _Py_DumpTraceback( This function is signal safe. */ -PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( +extern const char* _Py_DumpTracebackThreads( int fd, PyInterpreterState *interp, PyThreadState *current_tstate); @@ -64,23 +70,23 @@ PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( string which is not ready (PyUnicode_WCHAR_KIND). This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text); +extern void _Py_DumpASCII(int fd, PyObject *text); /* Format an integer as decimal into the file descriptor fd. This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpDecimal( +extern void _Py_DumpDecimal( int fd, size_t value); /* Format an integer as hexadecimal with width digits into fd file descriptor. The function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpHexadecimal( +extern void _Py_DumpHexadecimal( int fd, uintptr_t value, Py_ssize_t width); -PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame( +extern PyObject* _PyTraceBack_FromFrame( PyObject *tb_next, PyFrameObject *frame); @@ -89,11 +95,10 @@ PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame( /* Write the traceback tb to file f. Prefix each line with indent spaces followed by the margin (if it is not NULL). */ -PyAPI_FUNC(int) _PyTraceBack_Print_Indented( - PyObject *tb, int indent, const char* margin, - const char *header_margin, const char *header, PyObject *f); -PyAPI_FUNC(int) _Py_WriteIndentedMargin(int, const char*, PyObject *); -PyAPI_FUNC(int) _Py_WriteIndent(int, PyObject *); +extern int _PyTraceBack_Print( + PyObject *tb, const char *header, PyObject *f); +extern int _Py_WriteIndentedMargin(int, const char*, PyObject *); +extern int _Py_WriteIndent(int, PyObject *); #ifdef __cplusplus } diff --git a/Include/internal/pycore_tracemalloc.h b/Include/internal/pycore_tracemalloc.h index cfc4d1fe43999e..7ddc5bac5d10af 100644 --- a/Include/internal/pycore_tracemalloc.h +++ b/Include/internal/pycore_tracemalloc.h @@ -117,14 +117,16 @@ struct _tracemalloc_runtime_state { } -/* Get the traceback where a memory block was allocated. - - Return a tuple of (filename: str, lineno: int) tuples. - - Return None if the tracemalloc module is disabled or if the memory block - is not tracked by tracemalloc. - - Raise an exception and return NULL on error. */ +// Get the traceback where a memory block was allocated. +// +// Return a tuple of (filename: str, lineno: int) tuples. +// +// Return None if the tracemalloc module is disabled or if the memory block +// is not tracked by tracemalloc. +// +// Raise an exception and return NULL on error. +// +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback( unsigned int domain, uintptr_t ptr); diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index 335edad89792c3..4fa7a12206bcb2 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -8,8 +8,8 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "tupleobject.h" /* _PyTuple_CAST() */ - +extern void _PyTuple_MaybeUntrack(PyObject *); +extern void _PyTuple_DebugMallocStats(FILE *out); /* runtime lifecycle */ diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 8f3fbbcdb5ffcd..27c6c8731cb3f9 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -4,12 +4,12 @@ extern "C" { #endif -#include "pycore_moduleobject.h" - #ifndef Py_BUILD_CORE # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_moduleobject.h" // PyModuleObject + /* state */ @@ -114,7 +114,10 @@ extern static_builtin_state * _PyStaticType_GetState(PyInterpreterState *, PyTyp extern void _PyStaticType_ClearWeakRefs(PyInterpreterState *, PyTypeObject *type); extern void _PyStaticType_Dealloc(PyInterpreterState *, PyTypeObject *); +// Export for 'math' shared extension, used via _PyType_IsReady() static inline +// function PyAPI_FUNC(PyObject *) _PyType_GetDict(PyTypeObject *); + extern PyObject * _PyType_GetBases(PyTypeObject *type); extern PyObject * _PyType_GetMRO(PyTypeObject *type); extern PyObject* _PyType_GetSubclasses(PyTypeObject *); @@ -128,18 +131,17 @@ _PyType_IsReady(PyTypeObject *type) return _PyType_GetDict(type) != NULL; } -PyObject * -_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute); -PyObject * -_Py_type_getattro(PyTypeObject *type, PyObject *name); +extern PyObject* _Py_type_getattro_impl(PyTypeObject *type, PyObject *name, + int *suppress_missing_attribute); +extern PyObject* _Py_type_getattro(PyTypeObject *type, PyObject *name); -PyObject *_Py_slot_tp_getattro(PyObject *self, PyObject *name); -PyObject *_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name); +extern PyObject* _Py_slot_tp_getattro(PyObject *self, PyObject *name); +extern PyObject* _Py_slot_tp_getattr_hook(PyObject *self, PyObject *name); -PyAPI_DATA(PyTypeObject) _PyBufferWrapper_Type; +extern PyTypeObject _PyBufferWrapper_Type; -PyObject * -_PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *meth_found); +extern PyObject* _PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, + PyObject *name, int *meth_found); #ifdef __cplusplus } diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index ad59c3e385f2d3..360a9e1819f8e8 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -9,8 +9,23 @@ extern "C" { #endif #include "pycore_fileutils.h" // _Py_error_handler +#include "pycore_identifier.h" // _Py_Identifier #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI +/* --- Characters Type APIs ----------------------------------------------- */ + +extern int _PyUnicode_IsXidStart(Py_UCS4 ch); +extern int _PyUnicode_IsXidContinue(Py_UCS4 ch); +extern int _PyUnicode_ToLowerFull(Py_UCS4 ch, Py_UCS4 *res); +extern int _PyUnicode_ToTitleFull(Py_UCS4 ch, Py_UCS4 *res); +extern int _PyUnicode_ToUpperFull(Py_UCS4 ch, Py_UCS4 *res); +extern int _PyUnicode_ToFoldedFull(Py_UCS4 ch, Py_UCS4 *res); +extern int _PyUnicode_IsCaseIgnorable(Py_UCS4 ch); +extern int _PyUnicode_IsCased(Py_UCS4 ch); + +/* --- Unicode API -------------------------------------------------------- */ + +// Export for '_json' shared extension PyAPI_FUNC(int) _PyUnicode_CheckConsistency( PyObject *op, int check_content); @@ -18,10 +33,10 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( extern void _PyUnicode_ExactDealloc(PyObject *op); extern Py_ssize_t _PyUnicode_InternedSize(void); -/* Get a copy of a Unicode string. */ +// Get a copy of a Unicode string. +// Export for '_datetime' shared extension. PyAPI_FUNC(PyObject*) _PyUnicode_Copy( - PyObject *unicode - ); + PyObject *unicode); /* Unsafe version of PyUnicode_Fill(): don't check arguments and so may crash if parameters are invalid (e.g. if length is longer than the string). */ @@ -80,11 +95,13 @@ typedef struct { unsigned char readonly; } _PyUnicodeWriter ; -/* Initialize a Unicode writer. - * - * By default, the minimum buffer size is 0 character and overallocation is - * disabled. Set min_length, min_char and overallocate attributes to control - * the allocation of the buffer. */ +// Initialize a Unicode writer. +// +// By default, the minimum buffer size is 0 character and overallocation is +// disabled. Set min_length, min_char and overallocate attributes to control +// the allocation of the buffer. +// +// Export the _PyUnicodeWriter API for '_multibytecodec' shared extension. PyAPI_FUNC(void) _PyUnicodeWriter_Init(_PyUnicodeWriter *writer); @@ -174,7 +191,7 @@ _PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer); /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ -PyAPI_FUNC(int) _PyUnicode_FormatAdvancedWriter( +extern int _PyUnicode_FormatAdvancedWriter( _PyUnicodeWriter *writer, PyObject *obj, PyObject *format_spec, @@ -191,12 +208,14 @@ extern PyObject* _PyUnicode_EncodeUTF7( /* --- UTF-8 Codecs ------------------------------------------------------- */ +// Export for '_tkinter' shared extension. PyAPI_FUNC(PyObject*) _PyUnicode_AsUTF8String( PyObject *unicode, const char *errors); /* --- UTF-32 Codecs ------------------------------------------------------ */ +// Export for '_tkinter' shared extension PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( PyObject *object, /* Unicode object */ const char *errors, /* error handling */ @@ -204,20 +223,21 @@ PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( /* --- UTF-16 Codecs ------------------------------------------------------ */ -/* Returns a Python string object holding the UTF-16 encoded value of - the Unicode data. - - If byteorder is not 0, output is written according to the following - byte order: - - byteorder == -1: little endian - byteorder == 0: native byte order (writes a BOM mark) - byteorder == 1: big endian - - If byteorder is 0, the output string will always start with the - Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is - prepended. -*/ +// Returns a Python string object holding the UTF-16 encoded value of +// the Unicode data. +// +// If byteorder is not 0, output is written according to the following +// byte order: +// +// byteorder == -1: little endian +// byteorder == 0: native byte order (writes a BOM mark) +// byteorder == 1: big endian +// +// If byteorder is 0, the output string will always start with the +// Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is +// prepended. +// +// Export for '_tkinter' shared extension PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF16( PyObject* unicode, /* Unicode object */ const char *errors, /* error handling */ @@ -232,8 +252,9 @@ extern PyObject* _PyUnicode_DecodeUnicodeEscapeStateful( const char *errors, /* error handling */ Py_ssize_t *consumed); /* bytes consumed */ -/* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape - chars. */ +// Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape +// chars. +// Export for test_peg_generator. PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal( const char *string, /* Unicode-Escape encoded string */ Py_ssize_t length, /* size of string */ @@ -283,13 +304,14 @@ extern PyObject* _PyUnicode_EncodeCharmap( /* --- Decimal Encoder ---------------------------------------------------- */ -/* Coverts a Unicode object holding a decimal value to an ASCII string - for using in int, float and complex parsers. - Transforms code points that have decimal digit property to the - corresponding ASCII digit code points. Transforms spaces to ASCII. - Transforms code points starting from the first non-ASCII code point that - is neither a decimal digit nor a space to the end into '?'. */ - +// Coverts a Unicode object holding a decimal value to an ASCII string +// for using in int, float and complex parsers. +// Transforms code points that have decimal digit property to the +// corresponding ASCII digit code points. Transforms spaces to ASCII. +// Transforms code points starting from the first non-ASCII code point that +// is neither a decimal digit nor a space to the end into '?'. +// +// Export for '_testinternalcapi' shared extension. PyAPI_FUNC(PyObject*) _PyUnicode_TransformDecimalAndSpaceToASCII( PyObject *unicode); /* Unicode object */ @@ -309,9 +331,10 @@ extern int _PyUnicode_EqualToASCIIId( _Py_Identifier *right /* Right identifier */ ); -/* Test whether a unicode is equal to ASCII string. Return 1 if true, - 0 otherwise. The right argument must be ASCII-encoded string. - Any error occurs inside will be cleared before return. */ +// Test whether a unicode is equal to ASCII string. Return 1 if true, +// 0 otherwise. The right argument must be ASCII-encoded string. +// Any error occurs inside will be cleared before return. +// Export for '_ctypes' shared extension PyAPI_FUNC(int) _PyUnicode_EqualToASCIIString( PyObject *left, const char *right /* ASCII-encoded string */ @@ -343,19 +366,23 @@ extern Py_ssize_t _PyUnicode_InsertThousandsGrouping( extern PyObject* _PyUnicode_FormatLong(PyObject *, int, int, int); -/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ +// Return an interned Unicode object for an Identifier; may fail if there is no +// memory. +// Export for '_testembed' program. PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); /* Fast equality check when the inputs are known to be exact unicode types and where the hash values are equal (i.e. a very probable match) */ extern int _PyUnicode_EQ(PyObject *, PyObject *); -/* Equality check. */ +// Equality check. +// Export for '_pickle' shared extension. PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *, PyObject *); extern int _PyUnicode_WideCharString_Converter(PyObject *, void *); extern int _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *); +// Export for test_peg_generator PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *); /* --- Runtime lifecycle -------------------------------------------------- */ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 59f40075f93983..729d54bbb951e7 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -669,21 +669,12 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(aggregate_class); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(alias); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(append); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(arg); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(argdefs); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(args); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(arguments); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1053,12 +1044,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(eventmask); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(exc_type); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(exc_value); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(excepthook); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1077,6 +1062,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(extra_tokens); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(f); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(facility); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1170,6 +1158,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(future); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(g); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(generation); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1209,6 +1200,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(groups); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(h); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(handle); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1293,6 +1287,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(intersection); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(interval); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(is_running); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1995,9 +1992,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(trace_callback); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(traceback); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(trailers); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); diff --git a/Include/internal/pycore_uops.h b/Include/internal/pycore_uops.h index edb141cc79f752..d8a7d978f1304e 100644 --- a/Include/internal/pycore_uops.h +++ b/Include/internal/pycore_uops.h @@ -8,7 +8,9 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#define _Py_UOP_MAX_TRACE_LENGTH 32 +#include "pycore_frame.h" // _PyInterpreterFrame + +#define _Py_UOP_MAX_TRACE_LENGTH 128 typedef struct { uint32_t opcode; @@ -18,7 +20,7 @@ typedef struct { typedef struct { _PyExecutorObject base; - _PyUOpInstruction trace[_Py_UOP_MAX_TRACE_LENGTH]; // TODO: variable length + _PyUOpInstruction trace[1]; } _PyUOpExecutorObject; _PyInterpreterFrame *_PyUopExecute( diff --git a/Include/internal/pycore_warnings.h b/Include/internal/pycore_warnings.h index 452d6b96ce4f1c..9785d7cc467de2 100644 --- a/Include/internal/pycore_warnings.h +++ b/Include/internal/pycore_warnings.h @@ -19,7 +19,7 @@ struct _warnings_runtime_state { extern int _PyWarnings_InitState(PyInterpreterState *interp); -PyAPI_FUNC(PyObject*) _PyWarnings_Init(void); +extern PyObject* _PyWarnings_Init(void); extern void _PyErr_WarnUnawaitedCoroutine(PyObject *coro); extern void _PyErr_WarnUnawaitedAgenMethod(PyAsyncGenObject *agen, PyObject *method); diff --git a/Include/intrcheck.h b/Include/intrcheck.h index b8cc65601683cb..1d1feee83de483 100644 --- a/Include/intrcheck.h +++ b/Include/intrcheck.h @@ -5,6 +5,7 @@ extern "C" { #endif PyAPI_FUNC(int) PyOS_InterruptOccurred(void); + #ifdef HAVE_FORK #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 PyAPI_FUNC(void) PyOS_BeforeFork(void); @@ -12,18 +13,10 @@ PyAPI_FUNC(void) PyOS_AfterFork_Parent(void); PyAPI_FUNC(void) PyOS_AfterFork_Child(void); #endif #endif + /* Deprecated, please use PyOS_AfterFork_Child() instead */ Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyOS_AfterFork(void); -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyOS_IsMainThread(void); - -#ifdef MS_WINDOWS -/* windows.h is not included by Python.h so use void* instead of HANDLE */ -PyAPI_FUNC(void*) _PyOS_SigintEvent(void); -#endif -#endif /* !Py_LIMITED_API */ - #ifdef __cplusplus } #endif diff --git a/Include/iterobject.h b/Include/iterobject.h index fff30f7176fdeb..e69d09719bb4d1 100644 --- a/Include/iterobject.h +++ b/Include/iterobject.h @@ -7,9 +7,6 @@ extern "C" { PyAPI_DATA(PyTypeObject) PySeqIter_Type; PyAPI_DATA(PyTypeObject) PyCallIter_Type; -#ifdef Py_BUILD_CORE -extern PyTypeObject _PyAnextAwaitable_Type; -#endif #define PySeqIter_Check(op) Py_IS_TYPE((op), &PySeqIter_Type) diff --git a/Include/longobject.h b/Include/longobject.h index e559e238ae5a35..7393254cd24a9b 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -18,12 +18,18 @@ PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); + PyAPI_FUNC(long) PyLong_AsLong(PyObject *); PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000 +PyAPI_FUNC(int) PyLong_AsInt(PyObject *); +#endif + PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); /* It may be useful in the future. I've added it in the PyInt -> PyLong diff --git a/Include/modsupport.h b/Include/modsupport.h index 51061c5bc8090a..6efe9dfaa9089e 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -1,3 +1,4 @@ +// Module support interface #ifndef Py_MODSUPPORT_H #define Py_MODSUPPORT_H @@ -5,10 +6,6 @@ extern "C" { #endif -/* Module support interface */ - -#include // va_list - PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, @@ -22,10 +19,12 @@ PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030a0000 // Add an attribute with name 'name' and value 'obj' to the module 'mod. // On success, return 0. // On error, raise an exception and return -1. PyAPI_FUNC(int) PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value); +#endif /* Py_LIMITED_API */ #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000 // Similar to PyModule_AddObjectRef() but steal a reference to 'value'. @@ -109,14 +108,6 @@ PyAPI_FUNC(int) PyModule_ExecDef(PyObject *module, PyModuleDef *def); #define PYTHON_ABI_VERSION 3 #define PYTHON_ABI_STRING "3" -#ifdef Py_TRACE_REFS - /* When we are tracing reference counts, rename module creation functions so - modules compiled with incompatible settings will generate a - link-time error. */ - #define PyModule_Create2 PyModule_Create2TraceRefs - #define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs -#endif - PyAPI_FUNC(PyObject *) PyModule_Create2(PyModuleDef*, int apiver); #ifdef Py_LIMITED_API diff --git a/Include/moduleobject.h b/Include/moduleobject.h index b8bdfe29d80406..ea08145381cee6 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -27,11 +27,6 @@ PyAPI_FUNC(PyObject *) PyModule_GetNameObject(PyObject *); PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); Py_DEPRECATED(3.2) PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _PyModule_Clear(PyObject *); -PyAPI_FUNC(void) _PyModule_ClearDict(PyObject *); -PyAPI_FUNC(int) _PyModuleSpec_IsInitializing(PyObject *); -#endif PyAPI_FUNC(PyModuleDef*) PyModule_GetDef(PyObject*); PyAPI_FUNC(void*) PyModule_GetState(PyObject*); @@ -103,12 +98,6 @@ struct PyModuleDef { freefunc m_free; }; - -// Internal C API -#ifdef Py_BUILD_CORE -extern int _PyModule_IsExtension(PyObject *obj); -#endif - #ifdef __cplusplus } #endif diff --git a/Include/object.h b/Include/object.h index 7f2e4e90615e7b..9058558e3cd4d9 100644 --- a/Include/object.h +++ b/Include/object.h @@ -51,30 +51,11 @@ A standard interface exists for objects that contain an array of items whose size is determined when the object is allocated. */ -#include "pystats.h" - /* Py_DEBUG implies Py_REF_DEBUG. */ #if defined(Py_DEBUG) && !defined(Py_REF_DEBUG) # define Py_REF_DEBUG #endif -#if defined(Py_LIMITED_API) && defined(Py_TRACE_REFS) -# error Py_LIMITED_API is incompatible with Py_TRACE_REFS -#endif - -#ifdef Py_TRACE_REFS -/* Define pointers to support a doubly-linked list of all live heap objects. */ -#define _PyObject_HEAD_EXTRA \ - PyObject *_ob_next; \ - PyObject *_ob_prev; - -#define _PyObject_EXTRA_INIT _Py_NULL, _Py_NULL, - -#else -# define _PyObject_HEAD_EXTRA -# define _PyObject_EXTRA_INIT -#endif - /* PyObject_HEAD defines the initial segment of every PyObject. */ #define PyObject_HEAD PyObject ob_base; @@ -130,14 +111,12 @@ check by comparing the reference count field to the immortality reference count. #ifdef Py_BUILD_CORE #define PyObject_HEAD_INIT(type) \ { \ - _PyObject_EXTRA_INIT \ { _Py_IMMORTAL_REFCNT }, \ (type) \ }, #else #define PyObject_HEAD_INIT(type) \ { \ - _PyObject_EXTRA_INIT \ { 1 }, \ (type) \ }, @@ -164,13 +143,27 @@ check by comparing the reference count field to the immortality reference count. * in addition, be cast to PyVarObject*. */ struct _object { - _PyObject_HEAD_EXTRA +#if (defined(__GNUC__) || defined(__clang__)) \ + && !(defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L) + // On C99 and older, anonymous union is a GCC and clang extension + __extension__ +#endif +#ifdef _MSC_VER + // Ignore MSC warning C4201: "nonstandard extension used: + // nameless struct/union" + __pragma(warning(push)) + __pragma(warning(disable: 4201)) +#endif union { Py_ssize_t ob_refcnt; #if SIZEOF_VOID_P > 4 PY_UINT32_T ob_refcnt_split[2]; #endif }; +#ifdef _MSC_VER + __pragma(warning(pop)) +#endif + PyTypeObject *ob_type; }; @@ -401,6 +394,10 @@ PyAPI_FUNC(int) PyObject_GetOptionalAttrString(PyObject *, const char *, PyObjec PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_DelAttr(PyObject *v, PyObject *name); PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000 +PyAPI_FUNC(int) PyObject_HasAttrWithError(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttrStringWithError(PyObject *, const char *); +#endif PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, PyObject *, PyObject *); @@ -421,12 +418,6 @@ PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); */ PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); -/* Pickle support. */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyObject_GetState(PyObject *); -#endif - - /* Helpers for printing recursive container types */ PyAPI_FUNC(int) Py_ReprEnter(PyObject *); PyAPI_FUNC(void) Py_ReprLeave(PyObject *); @@ -594,10 +585,8 @@ you can count such references to the type object.) #if defined(Py_REF_DEBUG) && !defined(Py_LIMITED_API) PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op); -PyAPI_FUNC(void) _Py_IncRefTotal_DO_NOT_USE_THIS(void); -PyAPI_FUNC(void) _Py_DecRefTotal_DO_NOT_USE_THIS(void); -# define _Py_INC_REFTOTAL() _Py_IncRefTotal_DO_NOT_USE_THIS() -# define _Py_DEC_REFTOTAL() _Py_DecRefTotal_DO_NOT_USE_THIS() +PyAPI_FUNC(void) _Py_INCREF_IncRefTotal(void); +PyAPI_FUNC(void) _Py_DECREF_DecRefTotal(void); #endif // Py_REF_DEBUG && !Py_LIMITED_API PyAPI_FUNC(void) _Py_Dealloc(PyObject *); @@ -646,7 +635,7 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op) #endif _Py_INCREF_STAT_INC(); #ifdef Py_REF_DEBUG - _Py_INC_REFTOTAL(); + _Py_INCREF_IncRefTotal(); #endif #endif } @@ -671,17 +660,15 @@ static inline void Py_DECREF(PyObject *op) { #elif defined(Py_REF_DEBUG) static inline void Py_DECREF(const char *filename, int lineno, PyObject *op) { + if (op->ob_refcnt <= 0) { + _Py_NegativeRefcount(filename, lineno, op); + } if (_Py_IsImmortal(op)) { return; } _Py_DECREF_STAT_INC(); - _Py_DEC_REFTOTAL(); - if (--op->ob_refcnt != 0) { - if (op->ob_refcnt < 0) { - _Py_NegativeRefcount(filename, lineno, op); - } - } - else { + _Py_DECREF_DecRefTotal(); + if (--op->ob_refcnt == 0) { _Py_Dealloc(op); } } @@ -703,9 +690,6 @@ static inline Py_ALWAYS_INLINE void Py_DECREF(PyObject *op) #define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) #endif -#undef _Py_INC_REFTOTAL -#undef _Py_DEC_REFTOTAL - /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementations. @@ -834,8 +818,6 @@ static inline PyObject* _Py_XNewRef(PyObject *obj) /* _Py_NoneStruct is an object of undefined type which can be used in contexts where NULL (nil) is not suitable (since NULL often means 'error'). - -Don't forget to apply Py_INCREF() when returning this value!!! */ PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ #define Py_None (&_Py_NoneStruct) diff --git a/Include/objimpl.h b/Include/objimpl.h index ef871c5ea93ebe..967e2776767756 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -1,12 +1,8 @@ -/* The PyObject_ memory family: high-level object memory interfaces. - See pymem.h for the low-level PyMem_ family. -*/ +// The PyObject_ memory family: high-level object memory interfaces. +// See pymem.h for the low-level PyMem_ family. #ifndef Py_OBJIMPL_H #define Py_OBJIMPL_H - -#include "pymem.h" - #ifdef __cplusplus extern "C" { #endif @@ -231,4 +227,4 @@ PyAPI_FUNC(int) PyObject_GC_IsFinalized(PyObject *); #ifdef __cplusplus } #endif -#endif /* !Py_OBJIMPL_H */ +#endif // !Py_OBJIMPL_H diff --git a/Include/opcode.h b/Include/opcode.h index 697520937d9055..2619b690019acc 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -1,233 +1,11 @@ -// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py - #ifndef Py_OPCODE_H #define Py_OPCODE_H #ifdef __cplusplus extern "C" { #endif +#include "opcode_ids.h" -/* Instruction opcodes for compiled code */ -#define CACHE 0 -#define POP_TOP 1 -#define PUSH_NULL 2 -#define INTERPRETER_EXIT 3 -#define END_FOR 4 -#define END_SEND 5 -#define TO_BOOL 6 -#define NOP 9 -#define UNARY_NEGATIVE 11 -#define UNARY_NOT 12 -#define UNARY_INVERT 15 -#define EXIT_INIT_CHECK 16 -#define RESERVED 17 -#define MAKE_FUNCTION 24 -#define BINARY_SUBSCR 25 -#define BINARY_SLICE 26 -#define STORE_SLICE 27 -#define GET_LEN 30 -#define MATCH_MAPPING 31 -#define MATCH_SEQUENCE 32 -#define MATCH_KEYS 33 -#define PUSH_EXC_INFO 35 -#define CHECK_EXC_MATCH 36 -#define CHECK_EG_MATCH 37 -#define FORMAT_SIMPLE 40 -#define FORMAT_WITH_SPEC 41 -#define WITH_EXCEPT_START 49 -#define GET_AITER 50 -#define GET_ANEXT 51 -#define BEFORE_ASYNC_WITH 52 -#define BEFORE_WITH 53 -#define END_ASYNC_FOR 54 -#define CLEANUP_THROW 55 -#define STORE_SUBSCR 60 -#define DELETE_SUBSCR 61 -#define GET_ITER 68 -#define GET_YIELD_FROM_ITER 69 -#define LOAD_BUILD_CLASS 71 -#define LOAD_ASSERTION_ERROR 74 -#define RETURN_GENERATOR 75 -#define RETURN_VALUE 83 -#define SETUP_ANNOTATIONS 85 -#define LOAD_LOCALS 87 -#define POP_EXCEPT 89 -#define STORE_NAME 90 -#define DELETE_NAME 91 -#define UNPACK_SEQUENCE 92 -#define FOR_ITER 93 -#define UNPACK_EX 94 -#define STORE_ATTR 95 -#define DELETE_ATTR 96 -#define STORE_GLOBAL 97 -#define DELETE_GLOBAL 98 -#define SWAP 99 -#define LOAD_CONST 100 -#define LOAD_NAME 101 -#define BUILD_TUPLE 102 -#define BUILD_LIST 103 -#define BUILD_SET 104 -#define BUILD_MAP 105 -#define LOAD_ATTR 106 -#define COMPARE_OP 107 -#define IMPORT_NAME 108 -#define IMPORT_FROM 109 -#define JUMP_FORWARD 110 -#define POP_JUMP_IF_FALSE 114 -#define POP_JUMP_IF_TRUE 115 -#define LOAD_GLOBAL 116 -#define IS_OP 117 -#define CONTAINS_OP 118 -#define RERAISE 119 -#define COPY 120 -#define RETURN_CONST 121 -#define BINARY_OP 122 -#define SEND 123 -#define LOAD_FAST 124 -#define STORE_FAST 125 -#define DELETE_FAST 126 -#define LOAD_FAST_CHECK 127 -#define POP_JUMP_IF_NOT_NONE 128 -#define POP_JUMP_IF_NONE 129 -#define RAISE_VARARGS 130 -#define GET_AWAITABLE 131 -#define BUILD_SLICE 133 -#define JUMP_BACKWARD_NO_INTERRUPT 134 -#define MAKE_CELL 135 -#define LOAD_DEREF 137 -#define STORE_DEREF 138 -#define DELETE_DEREF 139 -#define JUMP_BACKWARD 140 -#define LOAD_SUPER_ATTR 141 -#define CALL_FUNCTION_EX 142 -#define LOAD_FAST_AND_CLEAR 143 -#define EXTENDED_ARG 144 -#define LIST_APPEND 145 -#define SET_ADD 146 -#define MAP_ADD 147 -#define COPY_FREE_VARS 149 -#define YIELD_VALUE 150 -#define RESUME 151 -#define MATCH_CLASS 152 -#define BUILD_CONST_KEY_MAP 156 -#define BUILD_STRING 157 -#define CONVERT_VALUE 158 -#define LIST_EXTEND 162 -#define SET_UPDATE 163 -#define DICT_MERGE 164 -#define DICT_UPDATE 165 -#define LOAD_FAST_LOAD_FAST 168 -#define STORE_FAST_LOAD_FAST 169 -#define STORE_FAST_STORE_FAST 170 -#define CALL 171 -#define KW_NAMES 172 -#define CALL_INTRINSIC_1 173 -#define CALL_INTRINSIC_2 174 -#define LOAD_FROM_DICT_OR_GLOBALS 175 -#define LOAD_FROM_DICT_OR_DEREF 176 -#define SET_FUNCTION_ATTRIBUTE 177 -#define ENTER_EXECUTOR 230 -#define MIN_INSTRUMENTED_OPCODE 237 -#define INSTRUMENTED_LOAD_SUPER_ATTR 237 -#define INSTRUMENTED_POP_JUMP_IF_NONE 238 -#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 239 -#define INSTRUMENTED_RESUME 240 -#define INSTRUMENTED_CALL 241 -#define INSTRUMENTED_RETURN_VALUE 242 -#define INSTRUMENTED_YIELD_VALUE 243 -#define INSTRUMENTED_CALL_FUNCTION_EX 244 -#define INSTRUMENTED_JUMP_FORWARD 245 -#define INSTRUMENTED_JUMP_BACKWARD 246 -#define INSTRUMENTED_RETURN_CONST 247 -#define INSTRUMENTED_FOR_ITER 248 -#define INSTRUMENTED_POP_JUMP_IF_FALSE 249 -#define INSTRUMENTED_POP_JUMP_IF_TRUE 250 -#define INSTRUMENTED_END_FOR 251 -#define INSTRUMENTED_END_SEND 252 -#define INSTRUMENTED_INSTRUCTION 253 -#define INSTRUMENTED_LINE 254 -#define MIN_PSEUDO_OPCODE 256 -#define SETUP_FINALLY 256 -#define SETUP_CLEANUP 257 -#define SETUP_WITH 258 -#define POP_BLOCK 259 -#define JUMP 260 -#define JUMP_NO_INTERRUPT 261 -#define LOAD_METHOD 262 -#define LOAD_SUPER_METHOD 263 -#define LOAD_ZERO_SUPER_METHOD 264 -#define LOAD_ZERO_SUPER_ATTR 265 -#define STORE_FAST_MAYBE_NULL 266 -#define LOAD_CLOSURE 267 -#define MAX_PSEUDO_OPCODE 267 -#define TO_BOOL_ALWAYS_TRUE 7 -#define TO_BOOL_BOOL 8 -#define TO_BOOL_INT 10 -#define TO_BOOL_LIST 13 -#define TO_BOOL_NONE 14 -#define TO_BOOL_STR 18 -#define BINARY_OP_MULTIPLY_INT 19 -#define BINARY_OP_ADD_INT 20 -#define BINARY_OP_SUBTRACT_INT 21 -#define BINARY_OP_MULTIPLY_FLOAT 22 -#define BINARY_OP_ADD_FLOAT 23 -#define BINARY_OP_SUBTRACT_FLOAT 28 -#define BINARY_OP_ADD_UNICODE 29 -#define BINARY_OP_INPLACE_ADD_UNICODE 34 -#define BINARY_SUBSCR_DICT 38 -#define BINARY_SUBSCR_GETITEM 39 -#define BINARY_SUBSCR_LIST_INT 42 -#define BINARY_SUBSCR_TUPLE_INT 43 -#define STORE_SUBSCR_DICT 44 -#define STORE_SUBSCR_LIST_INT 45 -#define SEND_GEN 46 -#define UNPACK_SEQUENCE_TWO_TUPLE 47 -#define UNPACK_SEQUENCE_TUPLE 48 -#define UNPACK_SEQUENCE_LIST 56 -#define STORE_ATTR_INSTANCE_VALUE 57 -#define STORE_ATTR_SLOT 58 -#define STORE_ATTR_WITH_HINT 59 -#define LOAD_GLOBAL_MODULE 62 -#define LOAD_GLOBAL_BUILTIN 63 -#define LOAD_SUPER_ATTR_ATTR 64 -#define LOAD_SUPER_ATTR_METHOD 65 -#define LOAD_ATTR_INSTANCE_VALUE 66 -#define LOAD_ATTR_MODULE 67 -#define LOAD_ATTR_WITH_HINT 70 -#define LOAD_ATTR_SLOT 72 -#define LOAD_ATTR_CLASS 73 -#define LOAD_ATTR_PROPERTY 76 -#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 77 -#define LOAD_ATTR_METHOD_WITH_VALUES 78 -#define LOAD_ATTR_METHOD_NO_DICT 79 -#define LOAD_ATTR_METHOD_LAZY_DICT 80 -#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 81 -#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 82 -#define COMPARE_OP_FLOAT 84 -#define COMPARE_OP_INT 86 -#define COMPARE_OP_STR 88 -#define FOR_ITER_LIST 111 -#define FOR_ITER_TUPLE 112 -#define FOR_ITER_RANGE 113 -#define FOR_ITER_GEN 132 -#define CALL_BOUND_METHOD_EXACT_ARGS 136 -#define CALL_PY_EXACT_ARGS 148 -#define CALL_PY_WITH_DEFAULTS 153 -#define CALL_NO_KW_TYPE_1 154 -#define CALL_NO_KW_STR_1 155 -#define CALL_NO_KW_TUPLE_1 159 -#define CALL_BUILTIN_CLASS 160 -#define CALL_NO_KW_BUILTIN_O 161 -#define CALL_NO_KW_BUILTIN_FAST 166 -#define CALL_BUILTIN_FAST_WITH_KEYWORDS 167 -#define CALL_NO_KW_LEN 178 -#define CALL_NO_KW_ISINSTANCE 179 -#define CALL_NO_KW_LIST_APPEND 180 -#define CALL_NO_KW_METHOD_DESCRIPTOR_O 181 -#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 182 -#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 183 -#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 184 -#define CALL_NO_KW_ALLOC_AND_ENTER_INIT 185 #define NB_ADD 0 #define NB_AND 1 @@ -256,8 +34,7 @@ extern "C" { #define NB_INPLACE_TRUE_DIVIDE 24 #define NB_INPLACE_XOR 25 -/* Defined in Lib/opcode.py */ -#define ENABLE_SPECIALIZATION 1 +#define NB_OPARG_LAST 25 #ifdef __cplusplus } diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h new file mode 100644 index 00000000000000..ba25bd459c1bcd --- /dev/null +++ b/Include/opcode_ids.h @@ -0,0 +1,239 @@ +// This file is generated by Tools/cases_generator/generate_cases.py +// from: +// Python/bytecodes.c +// Do not edit! + +#ifndef Py_OPCODE_IDS_H +#define Py_OPCODE_IDS_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Instruction opcodes for compiled code */ +#define CACHE 0 +#define BEFORE_ASYNC_WITH 1 +#define BEFORE_WITH 2 +#define BINARY_OP_INPLACE_ADD_UNICODE 3 +#define BINARY_SLICE 4 +#define BINARY_SUBSCR 5 +#define CHECK_EG_MATCH 6 +#define CHECK_EXC_MATCH 7 +#define CLEANUP_THROW 8 +#define DELETE_SUBSCR 9 +#define END_ASYNC_FOR 10 +#define END_FOR 11 +#define END_SEND 12 +#define EXIT_INIT_CHECK 13 +#define FORMAT_SIMPLE 14 +#define FORMAT_WITH_SPEC 15 +#define GET_AITER 16 +#define RESERVED 17 +#define GET_ANEXT 18 +#define GET_ITER 19 +#define GET_LEN 20 +#define GET_YIELD_FROM_ITER 21 +#define INTERPRETER_EXIT 22 +#define LOAD_ASSERTION_ERROR 23 +#define LOAD_BUILD_CLASS 24 +#define LOAD_LOCALS 25 +#define MAKE_FUNCTION 26 +#define MATCH_KEYS 27 +#define MATCH_MAPPING 28 +#define MATCH_SEQUENCE 29 +#define NOP 30 +#define POP_EXCEPT 31 +#define POP_TOP 32 +#define PUSH_EXC_INFO 33 +#define PUSH_NULL 34 +#define RETURN_GENERATOR 35 +#define RETURN_VALUE 36 +#define SETUP_ANNOTATIONS 37 +#define STORE_SLICE 38 +#define STORE_SUBSCR 39 +#define TO_BOOL 40 +#define UNARY_INVERT 41 +#define UNARY_NEGATIVE 42 +#define UNARY_NOT 43 +#define WITH_EXCEPT_START 44 +#define HAVE_ARGUMENT 45 +#define BINARY_OP 45 +#define BUILD_CONST_KEY_MAP 46 +#define BUILD_LIST 47 +#define BUILD_MAP 48 +#define BUILD_SET 49 +#define BUILD_SLICE 50 +#define BUILD_STRING 51 +#define BUILD_TUPLE 52 +#define CALL 53 +#define CALL_FUNCTION_EX 54 +#define CALL_INTRINSIC_1 55 +#define CALL_INTRINSIC_2 56 +#define CALL_KW 57 +#define COMPARE_OP 58 +#define CONTAINS_OP 59 +#define CONVERT_VALUE 60 +#define COPY 61 +#define COPY_FREE_VARS 62 +#define DELETE_ATTR 63 +#define DELETE_DEREF 64 +#define DELETE_FAST 65 +#define DELETE_GLOBAL 66 +#define DELETE_NAME 67 +#define DICT_MERGE 68 +#define DICT_UPDATE 69 +#define ENTER_EXECUTOR 70 +#define EXTENDED_ARG 71 +#define FOR_ITER 72 +#define GET_AWAITABLE 73 +#define IMPORT_FROM 74 +#define IMPORT_NAME 75 +#define IS_OP 76 +#define JUMP_BACKWARD 77 +#define JUMP_BACKWARD_NO_INTERRUPT 78 +#define JUMP_FORWARD 79 +#define LIST_APPEND 80 +#define LIST_EXTEND 81 +#define LOAD_ATTR 82 +#define LOAD_CONST 83 +#define LOAD_DEREF 84 +#define LOAD_FAST 85 +#define LOAD_FAST_AND_CLEAR 86 +#define LOAD_FAST_CHECK 87 +#define LOAD_FAST_LOAD_FAST 88 +#define LOAD_FROM_DICT_OR_DEREF 89 +#define LOAD_FROM_DICT_OR_GLOBALS 90 +#define LOAD_GLOBAL 91 +#define LOAD_NAME 92 +#define LOAD_SUPER_ATTR 93 +#define MAKE_CELL 94 +#define MAP_ADD 95 +#define MATCH_CLASS 96 +#define POP_JUMP_IF_FALSE 97 +#define POP_JUMP_IF_NONE 98 +#define POP_JUMP_IF_NOT_NONE 99 +#define POP_JUMP_IF_TRUE 100 +#define RAISE_VARARGS 101 +#define RERAISE 102 +#define RETURN_CONST 103 +#define SEND 104 +#define SET_ADD 105 +#define SET_FUNCTION_ATTRIBUTE 106 +#define SET_UPDATE 107 +#define STORE_ATTR 108 +#define STORE_DEREF 109 +#define STORE_FAST 110 +#define STORE_FAST_LOAD_FAST 111 +#define STORE_FAST_STORE_FAST 112 +#define STORE_GLOBAL 113 +#define STORE_NAME 114 +#define SWAP 115 +#define UNPACK_EX 116 +#define UNPACK_SEQUENCE 117 +#define YIELD_VALUE 118 +#define RESUME 149 +#define BINARY_OP_ADD_FLOAT 150 +#define BINARY_OP_ADD_INT 151 +#define BINARY_OP_ADD_UNICODE 152 +#define BINARY_OP_MULTIPLY_FLOAT 153 +#define BINARY_OP_MULTIPLY_INT 154 +#define BINARY_OP_SUBTRACT_FLOAT 155 +#define BINARY_OP_SUBTRACT_INT 156 +#define BINARY_SUBSCR_DICT 157 +#define BINARY_SUBSCR_GETITEM 158 +#define BINARY_SUBSCR_LIST_INT 159 +#define BINARY_SUBSCR_STR_INT 160 +#define BINARY_SUBSCR_TUPLE_INT 161 +#define CALL_ALLOC_AND_ENTER_INIT 162 +#define CALL_BOUND_METHOD_EXACT_ARGS 163 +#define CALL_BUILTIN_CLASS 164 +#define CALL_BUILTIN_FAST 165 +#define CALL_BUILTIN_FAST_WITH_KEYWORDS 166 +#define CALL_BUILTIN_O 167 +#define CALL_ISINSTANCE 168 +#define CALL_LEN 169 +#define CALL_LIST_APPEND 170 +#define CALL_METHOD_DESCRIPTOR_FAST 171 +#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 172 +#define CALL_METHOD_DESCRIPTOR_NOARGS 173 +#define CALL_METHOD_DESCRIPTOR_O 174 +#define CALL_PY_EXACT_ARGS 175 +#define CALL_PY_WITH_DEFAULTS 176 +#define CALL_STR_1 177 +#define CALL_TUPLE_1 178 +#define CALL_TYPE_1 179 +#define COMPARE_OP_FLOAT 180 +#define COMPARE_OP_INT 181 +#define COMPARE_OP_STR 182 +#define FOR_ITER_GEN 183 +#define FOR_ITER_LIST 184 +#define FOR_ITER_RANGE 185 +#define FOR_ITER_TUPLE 186 +#define LOAD_ATTR_CLASS 187 +#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 188 +#define LOAD_ATTR_INSTANCE_VALUE 189 +#define LOAD_ATTR_METHOD_LAZY_DICT 190 +#define LOAD_ATTR_METHOD_NO_DICT 191 +#define LOAD_ATTR_METHOD_WITH_VALUES 192 +#define LOAD_ATTR_MODULE 193 +#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 194 +#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 195 +#define LOAD_ATTR_PROPERTY 196 +#define LOAD_ATTR_SLOT 197 +#define LOAD_ATTR_WITH_HINT 198 +#define LOAD_GLOBAL_BUILTIN 199 +#define LOAD_GLOBAL_MODULE 200 +#define LOAD_SUPER_ATTR_ATTR 201 +#define LOAD_SUPER_ATTR_METHOD 202 +#define RESUME_CHECK 203 +#define SEND_GEN 204 +#define STORE_ATTR_INSTANCE_VALUE 205 +#define STORE_ATTR_SLOT 206 +#define STORE_ATTR_WITH_HINT 207 +#define STORE_SUBSCR_DICT 208 +#define STORE_SUBSCR_LIST_INT 209 +#define TO_BOOL_ALWAYS_TRUE 210 +#define TO_BOOL_BOOL 211 +#define TO_BOOL_INT 212 +#define TO_BOOL_LIST 213 +#define TO_BOOL_NONE 214 +#define TO_BOOL_STR 215 +#define UNPACK_SEQUENCE_LIST 216 +#define UNPACK_SEQUENCE_TUPLE 217 +#define UNPACK_SEQUENCE_TWO_TUPLE 218 +#define MIN_INSTRUMENTED_OPCODE 236 +#define INSTRUMENTED_RESUME 236 +#define INSTRUMENTED_END_FOR 237 +#define INSTRUMENTED_END_SEND 238 +#define INSTRUMENTED_RETURN_VALUE 239 +#define INSTRUMENTED_RETURN_CONST 240 +#define INSTRUMENTED_YIELD_VALUE 241 +#define INSTRUMENTED_LOAD_SUPER_ATTR 242 +#define INSTRUMENTED_FOR_ITER 243 +#define INSTRUMENTED_CALL 244 +#define INSTRUMENTED_CALL_KW 245 +#define INSTRUMENTED_CALL_FUNCTION_EX 246 +#define INSTRUMENTED_INSTRUCTION 247 +#define INSTRUMENTED_JUMP_FORWARD 248 +#define INSTRUMENTED_JUMP_BACKWARD 249 +#define INSTRUMENTED_POP_JUMP_IF_TRUE 250 +#define INSTRUMENTED_POP_JUMP_IF_FALSE 251 +#define INSTRUMENTED_POP_JUMP_IF_NONE 252 +#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 253 +#define INSTRUMENTED_LINE 254 +#define JUMP 256 +#define JUMP_NO_INTERRUPT 257 +#define LOAD_CLOSURE 258 +#define LOAD_METHOD 259 +#define LOAD_SUPER_METHOD 260 +#define LOAD_ZERO_SUPER_ATTR 261 +#define LOAD_ZERO_SUPER_METHOD 262 +#define POP_BLOCK 263 +#define SETUP_CLEANUP 264 +#define SETUP_FINALLY 265 +#define SETUP_WITH 266 +#define STORE_FAST_MAYBE_NULL 267 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_IDS_H */ diff --git a/Include/osdefs.h b/Include/osdefs.h index 3243944a1483e9..2599e87a9d7c4b 100644 --- a/Include/osdefs.h +++ b/Include/osdefs.h @@ -1,51 +1,57 @@ +// Operating system dependencies. +// +// Define constants: +// +// - ALTSEP +// - DELIM +// - MAXPATHLEN +// - SEP + #ifndef Py_OSDEFS_H #define Py_OSDEFS_H #ifdef __cplusplus extern "C" { #endif - -/* Operating system dependencies */ - #ifdef MS_WINDOWS -#define SEP L'\\' -#define ALTSEP L'/' -#define MAXPATHLEN 256 -#define DELIM L';' +# define SEP L'\\' +# define ALTSEP L'/' +# define MAXPATHLEN 256 +# define DELIM L';' #endif #ifdef __VXWORKS__ -#define DELIM L';' +# define DELIM L';' #endif /* Filename separator */ #ifndef SEP -#define SEP L'/' +# define SEP L'/' #endif /* Max pathname length */ #ifdef __hpux -#include -#include -#ifndef PATH_MAX -#define PATH_MAX MAXPATHLEN -#endif +# include +# include +# ifndef PATH_MAX +# define PATH_MAX MAXPATHLEN +# endif #endif #ifndef MAXPATHLEN -#if defined(PATH_MAX) && PATH_MAX > 1024 -#define MAXPATHLEN PATH_MAX -#else -#define MAXPATHLEN 1024 -#endif +# if defined(PATH_MAX) && PATH_MAX > 1024 +# define MAXPATHLEN PATH_MAX +# else +# define MAXPATHLEN 1024 +# endif #endif /* Search path entry delimiter */ #ifndef DELIM -#define DELIM L':' +# define DELIM L':' #endif #ifdef __cplusplus } #endif -#endif /* !Py_OSDEFS_H */ +#endif // !Py_OSDEFS_H diff --git a/Include/patchlevel.h b/Include/patchlevel.h index ae9d36c12d6eaf..c2ffa3d5a75c06 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 13 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 0 +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.13.0a0" +#define PY_VERSION "3.13.0a1+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/pyatomic.h b/Include/pyatomic.h new file mode 100644 index 00000000000000..2ce2c81cf5251a --- /dev/null +++ b/Include/pyatomic.h @@ -0,0 +1,16 @@ +#ifndef Py_ATOMIC_H +#define Py_ATOMIC_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_ATOMIC_H +# include "cpython/pyatomic.h" +# undef Py_CPYTHON_ATOMIC_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ATOMIC_H */ diff --git a/Include/pycapsule.h b/Include/pycapsule.h index 929a9a685259fb..666b9f86739670 100644 --- a/Include/pycapsule.h +++ b/Include/pycapsule.h @@ -52,7 +52,6 @@ PyAPI_FUNC(void *) PyCapsule_Import( const char *name, /* UTF-8 encoded string */ int no_block); - #ifdef __cplusplus } #endif diff --git a/Include/pyerrors.h b/Include/pyerrors.h index d089fa71779330..5d0028c116e2d8 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -1,13 +1,11 @@ +// Error handling definitions + #ifndef Py_ERRORS_H #define Py_ERRORS_H #ifdef __cplusplus extern "C" { #endif -#include // va_list - -/* Error handling definitions */ - PyAPI_FUNC(void) PyErr_SetNone(PyObject *); PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); PyAPI_FUNC(void) PyErr_SetString( diff --git a/Include/pyhash.h b/Include/pyhash.h index 182d223fab1cac..6e969f86fa2625 100644 --- a/Include/pyhash.h +++ b/Include/pyhash.h @@ -1,87 +1,10 @@ #ifndef Py_HASH_H - #define Py_HASH_H #ifdef __cplusplus extern "C" { #endif -/* Helpers for hash functions */ #ifndef Py_LIMITED_API -PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double); -PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); -// Similar to _Py_HashPointer(), but don't replace -1 with -2 -PyAPI_FUNC(Py_hash_t) _Py_HashPointerRaw(const void*); -PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); -#endif - -/* Prime multiplier used in string and various other hashes. */ -#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */ - -/* Parameters used for the numeric hash implementation. See notes for - _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on - reduction modulo the prime 2**_PyHASH_BITS - 1. */ - -#if SIZEOF_VOID_P >= 8 -# define _PyHASH_BITS 61 -#else -# define _PyHASH_BITS 31 -#endif - -#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1) -#define _PyHASH_INF 314159 -#define _PyHASH_IMAG _PyHASH_MULTIPLIER - - -/* hash secret - * - * memory layout on 64 bit systems - * cccccccc cccccccc cccccccc uc -- unsigned char[24] - * pppppppp ssssssss ........ fnv -- two Py_hash_t - * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t - * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t - * ........ ........ eeeeeeee pyexpat XML hash salt - * - * memory layout on 32 bit systems - * cccccccc cccccccc cccccccc uc - * ppppssss ........ ........ fnv -- two Py_hash_t - * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*) - * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t - * ........ ........ eeee.... pyexpat XML hash salt - * - * (*) The siphash member may not be available on 32 bit platforms without - * an unsigned int64 data type. - */ -#ifndef Py_LIMITED_API -typedef union { - /* ensure 24 bytes */ - unsigned char uc[24]; - /* two Py_hash_t for FNV */ - struct { - Py_hash_t prefix; - Py_hash_t suffix; - } fnv; - /* two uint64 for SipHash24 */ - struct { - uint64_t k0; - uint64_t k1; - } siphash; - /* a different (!) Py_hash_t for small string optimization */ - struct { - unsigned char padding[16]; - Py_hash_t suffix; - } djbx33a; - struct { - unsigned char padding[16]; - Py_hash_t hashsalt; - } expat; -} _Py_HashSecret_t; -PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; - -#ifdef Py_DEBUG -PyAPI_DATA(int) _Py_HashSecret_Initialized; -#endif - - /* hash function definition */ typedef struct { Py_hash_t (*const hash)(const void *, Py_ssize_t); @@ -94,7 +17,7 @@ PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); #endif -/* cutoff for small string DJBX33A optimization in range [1, cutoff). +/* Cutoff for small string DJBX33A optimization in range [1, cutoff). * * About 50% of the strings in a typical Python application are smaller than * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks. @@ -112,7 +35,7 @@ PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); #endif /* Py_HASH_CUTOFF */ -/* hash algorithm selection +/* Hash algorithm selection * * The values for Py_HASH_* are hard-coded in the * configure script. @@ -140,5 +63,4 @@ PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); #ifdef __cplusplus } #endif - -#endif /* !Py_HASH_H */ +#endif // !Py_HASH_H diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index 34f32a5000e9d5..c1e2bc5e323358 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -60,6 +60,10 @@ PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); PyAPI_DATA(const unsigned long) Py_Version; #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030D0000 +PyAPI_FUNC(int) Py_IsFinalizing(void); +#endif + #ifndef Py_LIMITED_API # define Py_CPYTHON_PYLIFECYCLE_H # include "cpython/pylifecycle.h" diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h index 00459a03b980be..806e41955efd7f 100644 --- a/Include/pymacconfig.h +++ b/Include/pymacconfig.h @@ -1,90 +1,82 @@ -#ifndef PYMACCONFIG_H -#define PYMACCONFIG_H - /* - * This file moves some of the autoconf magic to compile-time - * when building on MacOSX. This is needed for building 4-way - * universal binaries and for 64-bit universal binaries because - * the values redefined below aren't configure-time constant but - * only compile-time constant in these scenarios. - */ +// This file moves some of the autoconf magic to compile-time when building on +// macOS. This is needed for building 4-way universal binaries and for 64-bit +// universal binaries because the values redefined below aren't configure-time +// constant but only compile-time constant in these scenarios. -#if defined(__APPLE__) +#ifndef PY_MACCONFIG_H +#define PY_MACCONFIG_H +#ifdef __APPLE__ -# undef SIZEOF_LONG -# undef SIZEOF_PTHREAD_T -# undef SIZEOF_SIZE_T -# undef SIZEOF_TIME_T -# undef SIZEOF_VOID_P -# undef SIZEOF__BOOL -# undef SIZEOF_UINTPTR_T -# undef SIZEOF_PTHREAD_T -# undef WORDS_BIGENDIAN -# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 -# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 -# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 -# undef HAVE_GCC_ASM_FOR_X87 +#undef SIZEOF_LONG +#undef SIZEOF_PTHREAD_T +#undef SIZEOF_SIZE_T +#undef SIZEOF_TIME_T +#undef SIZEOF_VOID_P +#undef SIZEOF__BOOL +#undef SIZEOF_UINTPTR_T +#undef SIZEOF_PTHREAD_T +#undef WORDS_BIGENDIAN +#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 +#undef DOUBLE_IS_BIG_ENDIAN_IEEE754 +#undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +#undef HAVE_GCC_ASM_FOR_X87 -# undef VA_LIST_IS_ARRAY -# if defined(__LP64__) && defined(__x86_64__) -# define VA_LIST_IS_ARRAY 1 -# endif - -# undef HAVE_LARGEFILE_SUPPORT -# ifndef __LP64__ -# define HAVE_LARGEFILE_SUPPORT 1 -# endif - -# undef SIZEOF_LONG -# ifdef __LP64__ -# define SIZEOF__BOOL 1 -# define SIZEOF__BOOL 1 -# define SIZEOF_LONG 8 -# define SIZEOF_PTHREAD_T 8 -# define SIZEOF_SIZE_T 8 -# define SIZEOF_TIME_T 8 -# define SIZEOF_VOID_P 8 -# define SIZEOF_UINTPTR_T 8 -# define SIZEOF_PTHREAD_T 8 -# else -# ifdef __ppc__ -# define SIZEOF__BOOL 4 -# else -# define SIZEOF__BOOL 1 -# endif -# define SIZEOF_LONG 4 -# define SIZEOF_PTHREAD_T 4 -# define SIZEOF_SIZE_T 4 -# define SIZEOF_TIME_T 4 -# define SIZEOF_VOID_P 4 -# define SIZEOF_UINTPTR_T 4 -# define SIZEOF_PTHREAD_T 4 -# endif +#undef VA_LIST_IS_ARRAY +#if defined(__LP64__) && defined(__x86_64__) +# define VA_LIST_IS_ARRAY 1 +#endif -# if defined(__LP64__) - /* MacOSX 10.4 (the first release to support 64-bit code - * at all) only supports 64-bit in the UNIX layer. - * Therefore suppress the toolbox-glue in 64-bit mode. - */ +#undef HAVE_LARGEFILE_SUPPORT +#ifndef __LP64__ +# define HAVE_LARGEFILE_SUPPORT 1 +#endif - /* In 64-bit mode setpgrp always has no arguments, in 32-bit - * mode that depends on the compilation environment - */ -# undef SETPGRP_HAVE_ARG +#undef SIZEOF_LONG +#ifdef __LP64__ +# define SIZEOF__BOOL 1 +# define SIZEOF__BOOL 1 +# define SIZEOF_LONG 8 +# define SIZEOF_PTHREAD_T 8 +# define SIZEOF_SIZE_T 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_VOID_P 8 +# define SIZEOF_UINTPTR_T 8 +# define SIZEOF_PTHREAD_T 8 +#else +# ifdef __ppc__ +# define SIZEOF__BOOL 4 +# else +# define SIZEOF__BOOL 1 +# endif +# define SIZEOF_LONG 4 +# define SIZEOF_PTHREAD_T 4 +# define SIZEOF_SIZE_T 4 +# define SIZEOF_TIME_T 4 +# define SIZEOF_VOID_P 4 +# define SIZEOF_UINTPTR_T 4 +# define SIZEOF_PTHREAD_T 4 +#endif -# endif +// macOS 10.4 (the first release to support 64-bit code +// at all) only supports 64-bit in the UNIX layer. +// Therefore suppress the toolbox-glue in 64-bit mode. +// +// In 64-bit mode setpgrp always has no arguments, in 32-bit +// mode that depends on the compilation environment +#if defined(__LP64__) +# undef SETPGRP_HAVE_ARG +#endif #ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#define DOUBLE_IS_BIG_ENDIAN_IEEE754 +# define WORDS_BIGENDIAN 1 +# define DOUBLE_IS_BIG_ENDIAN_IEEE754 #else -#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 -#endif /* __BIG_ENDIAN */ +# define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +#endif #ifdef __i386__ -# define HAVE_GCC_ASM_FOR_X87 +# define HAVE_GCC_ASM_FOR_X87 #endif - -#endif /* defined(_APPLE__) */ - -#endif /* PYMACCONFIG_H */ +#endif // __APPLE__ +#endif // !PY_MACCONFIG_H diff --git a/Include/pymacro.h b/Include/pymacro.h index 342d2a7b844adf..9d264fe6eea1d4 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -118,6 +118,15 @@ */ #if defined(__GNUC__) || defined(__clang__) # define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) +#elif defined(_MSC_VER) + // Disable warning C4100: unreferenced formal parameter, + // declare the parameter, + // restore old compiler warnings. +# define Py_UNUSED(name) \ + __pragma(warning(push)) \ + __pragma(warning(suppress: 4100)) \ + _unused_ ## name \ + __pragma(warning(pop)) #else # define Py_UNUSED(name) _unused_ ## name #endif diff --git a/Include/pymem.h b/Include/pymem.h index e882645757bfd3..68e33f90b7b913 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -1,12 +1,8 @@ -/* The PyMem_ family: low-level memory allocation interfaces. - See objimpl.h for the PyObject_ memory family. -*/ +// The PyMem_ family: low-level memory allocation interfaces. +// See objimpl.h for the PyObject_ memory family. #ifndef Py_PYMEM_H #define Py_PYMEM_H - -#include "pyport.h" - #ifdef __cplusplus extern "C" { #endif @@ -100,5 +96,4 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr); #ifdef __cplusplus } #endif - -#endif /* !Py_PYMEM_H */ +#endif // !Py_PYMEM_H diff --git a/Include/pyport.h b/Include/pyport.h index d7c6ae64f2bf2f..d30fcd7f6cb7da 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -1,13 +1,8 @@ #ifndef Py_PYPORT_H #define Py_PYPORT_H -#include "pyconfig.h" /* include for defines */ - -#include - -#include #ifndef UCHAR_MAX -# error "limits.h must define UCHAR_MAX" +# error " header must define UCHAR_MAX" #endif #if UCHAR_MAX != 255 # error "Python's source code assumes C's unsigned char is an 8-bit type" @@ -24,9 +19,10 @@ #define _Py_CAST(type, expr) ((type)(expr)) // Static inline functions should use _Py_NULL rather than using directly NULL -// to prevent C++ compiler warnings. On C++11 and newer, _Py_NULL is defined as -// nullptr. -#if defined(__cplusplus) && __cplusplus >= 201103 +// to prevent C++ compiler warnings. On C23 and newer and on C++11 and newer, +// _Py_NULL is defined as nullptr. +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ > 201710L) \ + || (defined(__cplusplus) && __cplusplus >= 201103) # define _Py_NULL nullptr #else # define _Py_NULL NULL @@ -188,68 +184,6 @@ typedef Py_ssize_t Py_ssize_clean_t; # define Py_MEMCPY memcpy #endif -#ifdef HAVE_IEEEFP_H -#include /* needed for 'finite' declaration on some platforms */ -#endif - -#include /* Moved here from the math section, before extern "C" */ - -/******************************************** - * WRAPPER FOR and/or * - ********************************************/ - -#ifdef HAVE_SYS_TIME_H -#include -#endif -#include - -/****************************** - * WRAPPER FOR * - ******************************/ - -/* NB caller must include */ - -#ifdef HAVE_SYS_SELECT_H -#include -#endif /* !HAVE_SYS_SELECT_H */ - -/******************************* - * stat() and fstat() fiddling * - *******************************/ - -#ifdef HAVE_SYS_STAT_H -#include -#elif defined(HAVE_STAT_H) -#include -#endif - -#ifndef S_IFMT -/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */ -#define S_IFMT 0170000 -#endif - -#ifndef S_IFLNK -/* Windows doesn't define S_IFLNK but posixmodule.c maps - * IO_REPARSE_TAG_SYMLINK to S_IFLNK */ -# define S_IFLNK 0120000 -#endif - -#ifndef S_ISREG -#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) -#endif - -#ifndef S_ISDIR -#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) -#endif - -#ifndef S_ISCHR -#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) -#endif - -#ifndef S_ISLNK -#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) -#endif - #ifdef __cplusplus /* Move this down here since some C++ #include's don't like to be included inside an extern "C" */ @@ -421,141 +355,15 @@ extern "C" { # define Py_NO_INLINE #endif -/************************************************************************** -Prototypes that are missing from the standard include files on some systems -(and possibly only some versions of such systems.) - -Please be conservative with adding new ones, document them and enclose them -in platform-specific #ifdefs. -**************************************************************************/ - -#ifdef SOLARIS -/* Unchecked */ -extern int gethostname(char *, int); -#endif - -#ifdef HAVE__GETPTY -#include /* we need to import mode_t */ -extern char * _getpty(int *, int, mode_t, int); -#endif - -/* On QNX 6, struct termio must be declared by including sys/termio.h - if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must - be included before termios.h or it will generate an error. */ -#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux) -#include -#endif - - -/* On 4.4BSD-descendants, ctype functions serves the whole range of - * wchar_t character set rather than single byte code points only. - * This characteristic can break some operations of string object - * including str.upper() and str.split() on UTF-8 locales. This - * workaround was provided by Tim Robbins of FreeBSD project. - */ - -#if defined(__APPLE__) -# define _PY_PORT_CTYPE_UTF8_ISSUE -#endif - -#ifdef _PY_PORT_CTYPE_UTF8_ISSUE -#ifndef __cplusplus - /* The workaround below is unsafe in C++ because - * the defines these symbols as real functions, - * with a slightly different signature. - * See issue #10910 - */ -#include -#include -#undef isalnum -#define isalnum(c) iswalnum(btowc(c)) -#undef isalpha -#define isalpha(c) iswalpha(btowc(c)) -#undef islower -#define islower(c) iswlower(btowc(c)) -#undef isspace -#define isspace(c) iswspace(btowc(c)) -#undef isupper -#define isupper(c) iswupper(btowc(c)) -#undef tolower -#define tolower(c) towlower(btowc(c)) -#undef toupper -#define toupper(c) towupper(btowc(c)) -#endif -#endif - - -/* Declarations for symbol visibility. - - PyAPI_FUNC(type): Declares a public Python API function and return type - PyAPI_DATA(type): Declares public Python data and its type - PyMODINIT_FUNC: A Python module init function. If these functions are - inside the Python core, they are private to the core. - If in an extension module, it may be declared with - external linkage depending on the platform. - - As a number of platforms support/require "__declspec(dllimport/dllexport)", - we support a HAVE_DECLSPEC_DLL macro to save duplication. -*/ - -/* - All windows ports, except cygwin, are handled in PC/pyconfig.h. - - Cygwin is the only other autoconf platform requiring special - linkage handling and it uses __declspec(). -*/ -#if defined(__CYGWIN__) -# define HAVE_DECLSPEC_DLL -#endif - #include "exports.h" -/* only get special linkage if built as shared or platform is Cygwin */ -#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) -# if defined(HAVE_DECLSPEC_DLL) -# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE -# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE - /* module init functions inside the core need no external linkage */ - /* except for Cygwin to handle embedding */ -# if defined(__CYGWIN__) -# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* -# else /* __CYGWIN__ */ -# define PyMODINIT_FUNC PyObject* -# endif /* __CYGWIN__ */ -# else /* Py_BUILD_CORE */ - /* Building an extension module, or an embedded situation */ - /* public Python functions and data are imported */ - /* Under Cygwin, auto-import functions to prevent compilation */ - /* failures similar to those described at the bottom of 4.1: */ - /* http://docs.python.org/extending/windows.html#a-cookbook-approach */ -# if !defined(__CYGWIN__) -# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE -# endif /* !__CYGWIN__ */ -# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE - /* module init functions outside the core must be exported */ -# if defined(__cplusplus) -# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject* -# else /* __cplusplus */ -# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* -# endif /* __cplusplus */ -# endif /* Py_BUILD_CORE */ -# endif /* HAVE_DECLSPEC_DLL */ -#endif /* Py_ENABLE_SHARED */ - -/* If no external linkage macros defined by now, create defaults */ -#ifndef PyAPI_FUNC -# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE -#endif -#ifndef PyAPI_DATA -# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE -#endif -#ifndef PyMODINIT_FUNC -# if defined(__cplusplus) -# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject* -# else /* __cplusplus */ -# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* -# endif /* __cplusplus */ +#ifdef Py_LIMITED_API + // The internal C API must not be used with the limited C API: make sure + // that Py_BUILD_CORE macro is not defined in this case. These 3 macros are + // used by exports.h, so only undefine them afterwards. +# undef Py_BUILD_CORE +# undef Py_BUILD_CORE_BUILTIN +# undef Py_BUILD_CORE_MODULE #endif /* limits.h constants that may be missing */ @@ -683,12 +491,6 @@ extern char * _getpty(int *, int, mode_t, int); # endif #endif -/* Check that ALT_SOABI is consistent with Py_TRACE_REFS: - ./configure --with-trace-refs should must be used to define Py_TRACE_REFS */ -#if defined(ALT_SOABI) && defined(Py_TRACE_REFS) -# error "Py_TRACE_REFS ABI is not compatible with release and debug ABI" -#endif - #if defined(__ANDROID__) || defined(__VXWORKS__) // Use UTF-8 as the locale encoding, ignore the LC_CTYPE locale. // See _Py_GetLocaleEncoding(), PyUnicode_DecodeLocale() @@ -776,4 +578,8 @@ extern char * _getpty(int *, int, mode_t, int); # define ALIGNOF_MAX_ALIGN_T _Alignof(long double) #endif +#if defined(__sgi) && !defined(_SGI_MP_SOURCE) +# define _SGI_MP_SOURCE +#endif + #endif /* Py_PYPORT_H */ diff --git a/Include/pystate.h b/Include/pystate.h index e6b4de979c87b8..727b8fbfffe0e6 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -56,7 +56,7 @@ PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); The caller must hold the GIL. - See also _PyThreadState_UncheckedGet() and _PyThreadState_GET(). */ + See also PyThreadState_GetUnchecked() and _PyThreadState_GET(). */ PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); // Alias to PyThreadState_Get() diff --git a/Include/pystats.h b/Include/pystats.h index 54c9b8d8b3538f..acfa32201711e0 100644 --- a/Include/pystats.h +++ b/Include/pystats.h @@ -1,4 +1,9 @@ - +// Statistics on Python performance (public API). +// +// Define _Py_INCREF_STAT_INC() and _Py_DECREF_STAT_INC() used by Py_INCREF() +// and Py_DECREF(). +// +// See Include/cpython/pystats.h for the full API. #ifndef Py_PYSTATS_H #define Py_PYSTATS_H @@ -6,109 +11,16 @@ extern "C" { #endif -#ifdef Py_STATS - -#define SPECIALIZATION_FAILURE_KINDS 36 - -/* Stats for determining who is calling PyEval_EvalFrame */ -#define EVAL_CALL_TOTAL 0 -#define EVAL_CALL_VECTOR 1 -#define EVAL_CALL_GENERATOR 2 -#define EVAL_CALL_LEGACY 3 -#define EVAL_CALL_FUNCTION_VECTORCALL 4 -#define EVAL_CALL_BUILD_CLASS 5 -#define EVAL_CALL_SLOT 6 -#define EVAL_CALL_FUNCTION_EX 7 -#define EVAL_CALL_API 8 -#define EVAL_CALL_METHOD 9 - -#define EVAL_CALL_KINDS 10 - -typedef struct _specialization_stats { - uint64_t success; - uint64_t failure; - uint64_t hit; - uint64_t deferred; - uint64_t miss; - uint64_t deopt; - uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS]; -} SpecializationStats; - -typedef struct _opcode_stats { - SpecializationStats specialization; - uint64_t execution_count; - uint64_t pair_count[256]; -} OpcodeStats; - -typedef struct _call_stats { - uint64_t inlined_py_calls; - uint64_t pyeval_calls; - uint64_t frames_pushed; - uint64_t frame_objects_created; - uint64_t eval_calls[EVAL_CALL_KINDS]; -} CallStats; - -typedef struct _object_stats { - uint64_t increfs; - uint64_t decrefs; - uint64_t interpreter_increfs; - uint64_t interpreter_decrefs; - uint64_t allocations; - uint64_t allocations512; - uint64_t allocations4k; - uint64_t allocations_big; - uint64_t frees; - uint64_t to_freelist; - uint64_t from_freelist; - uint64_t new_values; - uint64_t dict_materialized_on_request; - uint64_t dict_materialized_new_key; - uint64_t dict_materialized_too_big; - uint64_t dict_materialized_str_subclass; - uint64_t type_cache_hits; - uint64_t type_cache_misses; - uint64_t type_cache_dunder_hits; - uint64_t type_cache_dunder_misses; - uint64_t type_cache_collisions; - uint64_t optimization_attempts; - uint64_t optimization_traces_created; - uint64_t optimization_traces_executed; - uint64_t optimization_uops_executed; -} ObjectStats; - -typedef struct _stats { - OpcodeStats opcode_stats[256]; - CallStats call_stats; - ObjectStats object_stats; -} PyStats; - - -PyAPI_DATA(PyStats) _py_stats_struct; -PyAPI_DATA(PyStats *) _py_stats; - -extern void _Py_StatsClear(void); -extern void _Py_PrintSpecializationStats(int to_file); - -#ifdef _PY_INTERPRETER - -#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_increfs++; } while (0) -#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_decrefs++; } while (0) - -#else - -#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.increfs++; } while (0) -#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.decrefs++; } while (0) - -#endif - +#if defined(Py_STATS) && !defined(Py_LIMITED_API) +# define Py_CPYTHON_PYSTATS_H +# include "cpython/pystats.h" +# undef Py_CPYTHON_PYSTATS_H #else - -#define _Py_INCREF_STAT_INC() ((void)0) -#define _Py_DECREF_STAT_INC() ((void)0) - +# define _Py_INCREF_STAT_INC() ((void)0) +# define _Py_DECREF_STAT_INC() ((void)0) #endif // !Py_STATS #ifdef __cplusplus } #endif -#endif /* !Py_PYSTATs_H */ +#endif // !Py_PYSTATS_H diff --git a/Include/pystrtod.h b/Include/pystrtod.h index fa056d17b6395f..e83d245eb623af 100644 --- a/Include/pystrtod.h +++ b/Include/pystrtod.h @@ -18,15 +18,6 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val, int flags, int *type); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _Py_string_to_number_with_underscores( - const char *str, Py_ssize_t len, const char *what, PyObject *obj, void *arg, - PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)); - -PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr); -#endif - - /* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ #define Py_DTSF_SIGN 0x01 /* always add the sign */ #define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ diff --git a/Include/pythread.h b/Include/pythread.h index 63714437c496b7..0784f6b2e5391f 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -33,42 +33,18 @@ PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); #define WAIT_LOCK 1 #define NOWAIT_LOCK 0 -/* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting - on a lock (see PyThread_acquire_lock_timed() below). - PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that - type, and depends on the system threading API. - - NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread - module exposes a higher-level API, with timeouts expressed in seconds - and floating-point numbers allowed. -*/ +// PY_TIMEOUT_T is the integral type used to specify timeouts when waiting +// on a lock (see PyThread_acquire_lock_timed() below). #define PY_TIMEOUT_T long long -#if defined(_POSIX_THREADS) - /* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000), - convert microseconds to nanoseconds. */ -# define PY_TIMEOUT_MAX (LLONG_MAX / 1000) -#elif defined (NT_THREADS) - // WaitForSingleObject() accepts timeout in milliseconds in the range - // [0; 0xFFFFFFFE] (DWORD type). INFINITE value (0xFFFFFFFF) means no - // timeout. 0xFFFFFFFE milliseconds is around 49.7 days. -# if 0xFFFFFFFELL * 1000 < LLONG_MAX -# define PY_TIMEOUT_MAX (0xFFFFFFFELL * 1000) -# else -# define PY_TIMEOUT_MAX LLONG_MAX -# endif -#else -# define PY_TIMEOUT_MAX LLONG_MAX -#endif - /* If microseconds == 0, the call is non-blocking: it returns immediately even when the lock can't be acquired. If microseconds > 0, the call waits up to the specified duration. If microseconds < 0, the call waits until success (or abnormal failure) - microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is - undefined. + If *microseconds* is greater than PY_TIMEOUT_MAX, clamp the timeout to + PY_TIMEOUT_MAX microseconds. If intr_flag is true and the acquire is interrupted by a signal, then the call will return PY_LOCK_INTR. The caller may reattempt to acquire the diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 5839c747a29275..dee00715b3c51d 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1,8 +1,6 @@ #ifndef Py_UNICODEOBJECT_H #define Py_UNICODEOBJECT_H -#include // va_list - /* Unicode implementation based on original code by Fredrik Lundh, @@ -55,8 +53,6 @@ Copyright (c) Corporation for National Research Initiatives. * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * -------------------------------------------------------------------- */ -#include - /* === Internal API ======================================================= */ /* --- Internal Unicode Format -------------------------------------------- */ @@ -93,10 +89,6 @@ Copyright (c) Corporation for National Research Initiatives. # endif #endif -#ifdef HAVE_WCHAR_H -# include -#endif - /* Py_UCS4 and Py_UCS2 are typedefs for the respective unicode representations. */ typedef uint32_t Py_UCS4; @@ -965,6 +957,15 @@ PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( const char *right /* ASCII-encoded string */ ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030D0000 +/* Compare a Unicode object with UTF-8 encoded C string. + Return 1 if they are equal, or 0 otherwise. + This function does not raise exceptions. */ + +PyAPI_FUNC(int) PyUnicode_EqualToUTF8(PyObject *, const char *); +PyAPI_FUNC(int) PyUnicode_EqualToUTF8AndSize(PyObject *, const char *, Py_ssize_t); +#endif + /* Rich compare two strings and return one of the following: - NULL in case an exception was raised diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index fd8ecdb5c980f3..5dd06ae487dfcf 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -4,6 +4,9 @@ # Do not edit! _specializations = { + "RESUME": [ + "RESUME_CHECK", + ], "TO_BOOL": [ "TO_BOOL_ALWAYS_TRUE", "TO_BOOL_BOOL", @@ -25,6 +28,7 @@ "BINARY_SUBSCR_DICT", "BINARY_SUBSCR_GETITEM", "BINARY_SUBSCR_LIST_INT", + "BINARY_SUBSCR_STR_INT", "BINARY_SUBSCR_TUPLE_INT", ], "STORE_SUBSCR": [ @@ -81,25 +85,251 @@ "CALL_BOUND_METHOD_EXACT_ARGS", "CALL_PY_EXACT_ARGS", "CALL_PY_WITH_DEFAULTS", - "CALL_NO_KW_TYPE_1", - "CALL_NO_KW_STR_1", - "CALL_NO_KW_TUPLE_1", + "CALL_TYPE_1", + "CALL_STR_1", + "CALL_TUPLE_1", "CALL_BUILTIN_CLASS", - "CALL_NO_KW_BUILTIN_O", - "CALL_NO_KW_BUILTIN_FAST", + "CALL_BUILTIN_O", + "CALL_BUILTIN_FAST", "CALL_BUILTIN_FAST_WITH_KEYWORDS", - "CALL_NO_KW_LEN", - "CALL_NO_KW_ISINSTANCE", - "CALL_NO_KW_LIST_APPEND", - "CALL_NO_KW_METHOD_DESCRIPTOR_O", + "CALL_LEN", + "CALL_ISINSTANCE", + "CALL_LIST_APPEND", + "CALL_METHOD_DESCRIPTOR_O", "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", - "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", - "CALL_NO_KW_METHOD_DESCRIPTOR_FAST", - "CALL_NO_KW_ALLOC_AND_ENTER_INIT", + "CALL_METHOD_DESCRIPTOR_NOARGS", + "CALL_METHOD_DESCRIPTOR_FAST", + "CALL_ALLOC_AND_ENTER_INIT", ], } # An irregular case: _specializations["BINARY_OP"].append("BINARY_OP_INPLACE_ADD_UNICODE") -_specialized_instructions = [opcode for family in _specializations.values() for opcode in family] +_specialized_opmap = { + 'BINARY_OP_INPLACE_ADD_UNICODE': 3, + 'BINARY_OP_ADD_FLOAT': 150, + 'BINARY_OP_ADD_INT': 151, + 'BINARY_OP_ADD_UNICODE': 152, + 'BINARY_OP_MULTIPLY_FLOAT': 153, + 'BINARY_OP_MULTIPLY_INT': 154, + 'BINARY_OP_SUBTRACT_FLOAT': 155, + 'BINARY_OP_SUBTRACT_INT': 156, + 'BINARY_SUBSCR_DICT': 157, + 'BINARY_SUBSCR_GETITEM': 158, + 'BINARY_SUBSCR_LIST_INT': 159, + 'BINARY_SUBSCR_STR_INT': 160, + 'BINARY_SUBSCR_TUPLE_INT': 161, + 'CALL_ALLOC_AND_ENTER_INIT': 162, + 'CALL_BOUND_METHOD_EXACT_ARGS': 163, + 'CALL_BUILTIN_CLASS': 164, + 'CALL_BUILTIN_FAST': 165, + 'CALL_BUILTIN_FAST_WITH_KEYWORDS': 166, + 'CALL_BUILTIN_O': 167, + 'CALL_ISINSTANCE': 168, + 'CALL_LEN': 169, + 'CALL_LIST_APPEND': 170, + 'CALL_METHOD_DESCRIPTOR_FAST': 171, + 'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 172, + 'CALL_METHOD_DESCRIPTOR_NOARGS': 173, + 'CALL_METHOD_DESCRIPTOR_O': 174, + 'CALL_PY_EXACT_ARGS': 175, + 'CALL_PY_WITH_DEFAULTS': 176, + 'CALL_STR_1': 177, + 'CALL_TUPLE_1': 178, + 'CALL_TYPE_1': 179, + 'COMPARE_OP_FLOAT': 180, + 'COMPARE_OP_INT': 181, + 'COMPARE_OP_STR': 182, + 'FOR_ITER_GEN': 183, + 'FOR_ITER_LIST': 184, + 'FOR_ITER_RANGE': 185, + 'FOR_ITER_TUPLE': 186, + 'LOAD_ATTR_CLASS': 187, + 'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 188, + 'LOAD_ATTR_INSTANCE_VALUE': 189, + 'LOAD_ATTR_METHOD_LAZY_DICT': 190, + 'LOAD_ATTR_METHOD_NO_DICT': 191, + 'LOAD_ATTR_METHOD_WITH_VALUES': 192, + 'LOAD_ATTR_MODULE': 193, + 'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 194, + 'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 195, + 'LOAD_ATTR_PROPERTY': 196, + 'LOAD_ATTR_SLOT': 197, + 'LOAD_ATTR_WITH_HINT': 198, + 'LOAD_GLOBAL_BUILTIN': 199, + 'LOAD_GLOBAL_MODULE': 200, + 'LOAD_SUPER_ATTR_ATTR': 201, + 'LOAD_SUPER_ATTR_METHOD': 202, + 'RESUME_CHECK': 203, + 'SEND_GEN': 204, + 'STORE_ATTR_INSTANCE_VALUE': 205, + 'STORE_ATTR_SLOT': 206, + 'STORE_ATTR_WITH_HINT': 207, + 'STORE_SUBSCR_DICT': 208, + 'STORE_SUBSCR_LIST_INT': 209, + 'TO_BOOL_ALWAYS_TRUE': 210, + 'TO_BOOL_BOOL': 211, + 'TO_BOOL_INT': 212, + 'TO_BOOL_LIST': 213, + 'TO_BOOL_NONE': 214, + 'TO_BOOL_STR': 215, + 'UNPACK_SEQUENCE_LIST': 216, + 'UNPACK_SEQUENCE_TUPLE': 217, + 'UNPACK_SEQUENCE_TWO_TUPLE': 218, +} + +opmap = { + 'CACHE': 0, + 'BEFORE_ASYNC_WITH': 1, + 'BEFORE_WITH': 2, + 'BINARY_SLICE': 4, + 'BINARY_SUBSCR': 5, + 'CHECK_EG_MATCH': 6, + 'CHECK_EXC_MATCH': 7, + 'CLEANUP_THROW': 8, + 'DELETE_SUBSCR': 9, + 'END_ASYNC_FOR': 10, + 'END_FOR': 11, + 'END_SEND': 12, + 'EXIT_INIT_CHECK': 13, + 'FORMAT_SIMPLE': 14, + 'FORMAT_WITH_SPEC': 15, + 'GET_AITER': 16, + 'RESERVED': 17, + 'GET_ANEXT': 18, + 'GET_ITER': 19, + 'GET_LEN': 20, + 'GET_YIELD_FROM_ITER': 21, + 'INTERPRETER_EXIT': 22, + 'LOAD_ASSERTION_ERROR': 23, + 'LOAD_BUILD_CLASS': 24, + 'LOAD_LOCALS': 25, + 'MAKE_FUNCTION': 26, + 'MATCH_KEYS': 27, + 'MATCH_MAPPING': 28, + 'MATCH_SEQUENCE': 29, + 'NOP': 30, + 'POP_EXCEPT': 31, + 'POP_TOP': 32, + 'PUSH_EXC_INFO': 33, + 'PUSH_NULL': 34, + 'RETURN_GENERATOR': 35, + 'RETURN_VALUE': 36, + 'SETUP_ANNOTATIONS': 37, + 'STORE_SLICE': 38, + 'STORE_SUBSCR': 39, + 'TO_BOOL': 40, + 'UNARY_INVERT': 41, + 'UNARY_NEGATIVE': 42, + 'UNARY_NOT': 43, + 'WITH_EXCEPT_START': 44, + 'BINARY_OP': 45, + 'BUILD_CONST_KEY_MAP': 46, + 'BUILD_LIST': 47, + 'BUILD_MAP': 48, + 'BUILD_SET': 49, + 'BUILD_SLICE': 50, + 'BUILD_STRING': 51, + 'BUILD_TUPLE': 52, + 'CALL': 53, + 'CALL_FUNCTION_EX': 54, + 'CALL_INTRINSIC_1': 55, + 'CALL_INTRINSIC_2': 56, + 'CALL_KW': 57, + 'COMPARE_OP': 58, + 'CONTAINS_OP': 59, + 'CONVERT_VALUE': 60, + 'COPY': 61, + 'COPY_FREE_VARS': 62, + 'DELETE_ATTR': 63, + 'DELETE_DEREF': 64, + 'DELETE_FAST': 65, + 'DELETE_GLOBAL': 66, + 'DELETE_NAME': 67, + 'DICT_MERGE': 68, + 'DICT_UPDATE': 69, + 'ENTER_EXECUTOR': 70, + 'EXTENDED_ARG': 71, + 'FOR_ITER': 72, + 'GET_AWAITABLE': 73, + 'IMPORT_FROM': 74, + 'IMPORT_NAME': 75, + 'IS_OP': 76, + 'JUMP_BACKWARD': 77, + 'JUMP_BACKWARD_NO_INTERRUPT': 78, + 'JUMP_FORWARD': 79, + 'LIST_APPEND': 80, + 'LIST_EXTEND': 81, + 'LOAD_ATTR': 82, + 'LOAD_CONST': 83, + 'LOAD_DEREF': 84, + 'LOAD_FAST': 85, + 'LOAD_FAST_AND_CLEAR': 86, + 'LOAD_FAST_CHECK': 87, + 'LOAD_FAST_LOAD_FAST': 88, + 'LOAD_FROM_DICT_OR_DEREF': 89, + 'LOAD_FROM_DICT_OR_GLOBALS': 90, + 'LOAD_GLOBAL': 91, + 'LOAD_NAME': 92, + 'LOAD_SUPER_ATTR': 93, + 'MAKE_CELL': 94, + 'MAP_ADD': 95, + 'MATCH_CLASS': 96, + 'POP_JUMP_IF_FALSE': 97, + 'POP_JUMP_IF_NONE': 98, + 'POP_JUMP_IF_NOT_NONE': 99, + 'POP_JUMP_IF_TRUE': 100, + 'RAISE_VARARGS': 101, + 'RERAISE': 102, + 'RETURN_CONST': 103, + 'SEND': 104, + 'SET_ADD': 105, + 'SET_FUNCTION_ATTRIBUTE': 106, + 'SET_UPDATE': 107, + 'STORE_ATTR': 108, + 'STORE_DEREF': 109, + 'STORE_FAST': 110, + 'STORE_FAST_LOAD_FAST': 111, + 'STORE_FAST_STORE_FAST': 112, + 'STORE_GLOBAL': 113, + 'STORE_NAME': 114, + 'SWAP': 115, + 'UNPACK_EX': 116, + 'UNPACK_SEQUENCE': 117, + 'YIELD_VALUE': 118, + 'RESUME': 149, + 'INSTRUMENTED_RESUME': 236, + 'INSTRUMENTED_END_FOR': 237, + 'INSTRUMENTED_END_SEND': 238, + 'INSTRUMENTED_RETURN_VALUE': 239, + 'INSTRUMENTED_RETURN_CONST': 240, + 'INSTRUMENTED_YIELD_VALUE': 241, + 'INSTRUMENTED_LOAD_SUPER_ATTR': 242, + 'INSTRUMENTED_FOR_ITER': 243, + 'INSTRUMENTED_CALL': 244, + 'INSTRUMENTED_CALL_KW': 245, + 'INSTRUMENTED_CALL_FUNCTION_EX': 246, + 'INSTRUMENTED_INSTRUCTION': 247, + 'INSTRUMENTED_JUMP_FORWARD': 248, + 'INSTRUMENTED_JUMP_BACKWARD': 249, + 'INSTRUMENTED_POP_JUMP_IF_TRUE': 250, + 'INSTRUMENTED_POP_JUMP_IF_FALSE': 251, + 'INSTRUMENTED_POP_JUMP_IF_NONE': 252, + 'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 253, + 'INSTRUMENTED_LINE': 254, + 'JUMP': 256, + 'JUMP_NO_INTERRUPT': 257, + 'LOAD_CLOSURE': 258, + 'LOAD_METHOD': 259, + 'LOAD_SUPER_METHOD': 260, + 'LOAD_ZERO_SUPER_ATTR': 261, + 'LOAD_ZERO_SUPER_METHOD': 262, + 'POP_BLOCK': 263, + 'SETUP_CLEANUP': 264, + 'SETUP_FINALLY': 265, + 'SETUP_WITH': 266, + 'STORE_FAST_MAYBE_NULL': 267, +} +MIN_INSTRUMENTED_OPCODE = 236 +HAVE_ARGUMENT = 45 diff --git a/Lib/_pydatetime.py b/Lib/_pydatetime.py index f4fc2c58e5e293..bca2acf1fc88cf 100644 --- a/Lib/_pydatetime.py +++ b/Lib/_pydatetime.py @@ -1015,13 +1015,9 @@ def fromisocalendar(cls, year, week, day): def __repr__(self): """Convert to formal string, for repr(). - >>> dt = datetime(2010, 1, 1) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0)' - - >>> dt = datetime(2010, 1, 1, tzinfo=timezone.utc) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' + >>> d = date(2010, 1, 1) + >>> repr(d) + 'datetime.date(2010, 1, 1)' """ return "%s.%s(%d, %d, %d)" % (_get_class_module(self), self.__class__.__qualname__, @@ -1112,6 +1108,8 @@ def replace(self, year=None, month=None, day=None): day = self._day return type(self)(year, month, day) + __replace__ = replace + # Comparisons of date objects with other. def __eq__(self, other): @@ -1236,7 +1234,7 @@ def __reduce__(self): class tzinfo: """Abstract base class for time zone info classes. - Subclasses must override the name(), utcoffset() and dst() methods. + Subclasses must override the tzname(), utcoffset() and dst() methods. """ __slots__ = () @@ -1637,6 +1635,8 @@ def replace(self, hour=None, minute=None, second=None, microsecond=None, fold = self._fold return type(self)(hour, minute, second, microsecond, tzinfo, fold=fold) + __replace__ = replace + # Pickle support. def _getstate(self, protocol=3): @@ -1684,7 +1684,7 @@ class datetime(date): The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints. """ - __slots__ = date.__slots__ + time.__slots__ + __slots__ = time.__slots__ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0): @@ -1812,7 +1812,7 @@ def utcfromtimestamp(cls, t): warnings.warn("datetime.utcfromtimestamp() is deprecated and scheduled " "for removal in a future version. Use timezone-aware " "objects to represent datetimes in UTC: " - "datetime.fromtimestamp(t, datetime.UTC).", + "datetime.datetime.fromtimestamp(t, datetime.UTC).", DeprecationWarning, stacklevel=2) return cls._fromtimestamp(t, True, None) @@ -1830,7 +1830,7 @@ def utcnow(cls): warnings.warn("datetime.utcnow() is deprecated and scheduled for " "removal in a future version. Instead, Use timezone-aware " "objects to represent datetimes in UTC: " - "datetime.now(datetime.UTC).", + "datetime.datetime.now(datetime.UTC).", DeprecationWarning, stacklevel=2) t = _time.time() @@ -1983,6 +1983,8 @@ def replace(self, year=None, month=None, day=None, hour=None, return type(self)(year, month, day, hour, minute, second, microsecond, tzinfo, fold=fold) + __replace__ = replace + def _local_timezone(self): if self.tzinfo is None: ts = self._mktime() diff --git a/Lib/argparse.py b/Lib/argparse.py index dfc98695f64e0a..a32884db80d1ea 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -89,8 +89,6 @@ import re as _re import sys as _sys -import warnings - from gettext import gettext as _, ngettext SUPPRESS = '==SUPPRESS==' @@ -910,6 +908,7 @@ def __init__(self, # parser.add_argument('-f', action=BooleanOptionalAction, type=int) for field_name in ('type', 'choices', 'metavar'): if locals()[field_name] is not _deprecated_default: + import warnings warnings._deprecated( field_name, "{name!r} is deprecated as of Python 3.12 and will be " @@ -1700,6 +1699,7 @@ def _remove_action(self, action): self._group_actions.remove(action) def add_argument_group(self, *args, **kwargs): + import warnings warnings.warn( "Nesting argument groups is deprecated.", category=DeprecationWarning, @@ -1728,6 +1728,7 @@ def _remove_action(self, action): self._group_actions.remove(action) def add_mutually_exclusive_group(self, *args, **kwargs): + import warnings warnings.warn( "Nesting mutually exclusive groups is deprecated.", category=DeprecationWarning, diff --git a/Lib/ast.py b/Lib/ast.py index a307f3ecd06175..f7888d18859ae4 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -32,13 +32,15 @@ def parse(source, filename='', mode='exec', *, - type_comments=False, feature_version=None): + type_comments=False, feature_version=None, optimize=-1): """ Parse the source into an AST node. Equivalent to compile(source, filename, mode, PyCF_ONLY_AST). Pass type_comments=True to get back type comments where the syntax allows. """ flags = PyCF_ONLY_AST + if optimize > 0: + flags |= PyCF_OPTIMIZED_AST if type_comments: flags |= PyCF_TYPE_COMMENTS if feature_version is None: @@ -50,7 +52,7 @@ def parse(source, filename='', mode='exec', *, feature_version = minor # Else it should be an int giving the minor version for 3.x. return compile(source, filename, mode, flags, - _feature_version=feature_version) + _feature_version=feature_version, optimize=optimize) def literal_eval(node_or_string): @@ -1223,17 +1225,7 @@ def _write_str_avoiding_backslashes(self, string, *, quote_types=_ALL_QUOTES): def visit_JoinedStr(self, node): self.write("f") - if self._avoid_backslashes: - with self.buffered() as buffer: - self._write_fstring_inner(node) - return self._write_str_avoiding_backslashes("".join(buffer)) - - # If we don't need to avoid backslashes globally (i.e., we only need - # to avoid them inside FormattedValues), it's cosmetically preferred - # to use escaped whitespace. That is, it's preferred to use backslashes - # for cases like: f"{x}\n". To accomplish this, we keep track of what - # in our buffer corresponds to FormattedValues and what corresponds to - # Constant parts of the f-string, and allow escapes accordingly. + fstring_parts = [] for value in node.values: with self.buffered() as buffer: @@ -1244,25 +1236,49 @@ def visit_JoinedStr(self, node): new_fstring_parts = [] quote_types = list(_ALL_QUOTES) + fallback_to_repr = False for value, is_constant in fstring_parts: - value, quote_types = self._str_literal_helper( - value, - quote_types=quote_types, - escape_special_whitespace=is_constant, - ) + if is_constant: + value, new_quote_types = self._str_literal_helper( + value, + quote_types=quote_types, + escape_special_whitespace=True, + ) + if set(new_quote_types).isdisjoint(quote_types): + fallback_to_repr = True + break + quote_types = new_quote_types + elif "\n" in value: + quote_types = [q for q in quote_types if q in _MULTI_QUOTES] + assert quote_types new_fstring_parts.append(value) + if fallback_to_repr: + # If we weren't able to find a quote type that works for all parts + # of the JoinedStr, fallback to using repr and triple single quotes. + quote_types = ["'''"] + new_fstring_parts.clear() + for value, is_constant in fstring_parts: + if is_constant: + value = repr('"' + value) # force repr to use single quotes + expected_prefix = "'\"" + assert value.startswith(expected_prefix), repr(value) + value = value[len(expected_prefix):-1] + new_fstring_parts.append(value) + value = "".join(new_fstring_parts) quote_type = quote_types[0] self.write(f"{quote_type}{value}{quote_type}") - def _write_fstring_inner(self, node): + def _write_fstring_inner(self, node, scape_newlines=False): if isinstance(node, JoinedStr): # for both the f-string itself, and format_spec for value in node.values: - self._write_fstring_inner(value) + self._write_fstring_inner(value, scape_newlines=scape_newlines) elif isinstance(node, Constant) and isinstance(node.value, str): value = node.value.replace("{", "{{").replace("}", "}}") + if scape_newlines: + value = value.replace("\n", "\\n") self.write(value) elif isinstance(node, FormattedValue): self.visit_FormattedValue(node) @@ -1271,16 +1287,12 @@ def _write_fstring_inner(self, node): def visit_FormattedValue(self, node): def unparse_inner(inner): - unparser = type(self)(_avoid_backslashes=True) + unparser = type(self)() unparser.set_precedence(_Precedence.TEST.next(), inner) return unparser.visit(inner) with self.delimit("{", "}"): expr = unparse_inner(node.value) - if "\\" in expr: - raise ValueError( - "Unable to avoid backslash in f-string expression part" - ) if expr.startswith("{"): # Separate pair of opening brackets as "{ {" self.write(" ") @@ -1289,7 +1301,10 @@ def unparse_inner(inner): self.write(f"!{chr(node.conversion)}") if node.format_spec: self.write(":") - self._write_fstring_inner(node.format_spec) + self._write_fstring_inner( + node.format_spec, + scape_newlines=True + ) def visit_Name(self, node): self.write(node.id) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index b092c9343634e2..0476de631a6a52 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -400,6 +400,8 @@ def __init__(self): self._clock_resolution = time.get_clock_info('monotonic').resolution self._exception_handler = None self.set_debug(coroutines._is_debug_mode()) + # The preserved state of async generator hooks. + self._old_agen_hooks = None # In debug mode, if the execution of a callback or a step of a task # exceed this duration in seconds, the slow callback/task is logged. self.slow_callback_duration = 0.1 @@ -601,29 +603,52 @@ def _check_running(self): raise RuntimeError( 'Cannot run the event loop while another loop is running') - def run_forever(self): - """Run until stop() is called.""" + def _run_forever_setup(self): + """Prepare the run loop to process events. + + This method exists so that custom custom event loop subclasses (e.g., event loops + that integrate a GUI event loop with Python's event loop) have access to all the + loop setup logic. + """ self._check_closed() self._check_running() self._set_coroutine_origin_tracking(self._debug) - old_agen_hooks = sys.get_asyncgen_hooks() - try: - self._thread_id = threading.get_ident() - sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook, - finalizer=self._asyncgen_finalizer_hook) + self._old_agen_hooks = sys.get_asyncgen_hooks() + self._thread_id = threading.get_ident() + sys.set_asyncgen_hooks( + firstiter=self._asyncgen_firstiter_hook, + finalizer=self._asyncgen_finalizer_hook + ) + + events._set_running_loop(self) + + def _run_forever_cleanup(self): + """Clean up after an event loop finishes the looping over events. - events._set_running_loop(self) + This method exists so that custom custom event loop subclasses (e.g., event loops + that integrate a GUI event loop with Python's event loop) have access to all the + loop cleanup logic. + """ + self._stopping = False + self._thread_id = None + events._set_running_loop(None) + self._set_coroutine_origin_tracking(False) + # Restore any pre-existing async generator hooks. + if self._old_agen_hooks is not None: + sys.set_asyncgen_hooks(*self._old_agen_hooks) + self._old_agen_hooks = None + + def run_forever(self): + """Run until stop() is called.""" + try: + self._run_forever_setup() while True: self._run_once() if self._stopping: break finally: - self._stopping = False - self._thread_id = None - events._set_running_loop(None) - self._set_coroutine_origin_tracking(False) - sys.set_asyncgen_hooks(*old_agen_hooks) + self._run_forever_cleanup() def run_until_complete(self, future): """Run until the Future is done. @@ -1907,8 +1932,11 @@ def _run_once(self): timeout = 0 elif self._scheduled: # Compute the desired timeout. - when = self._scheduled[0]._when - timeout = min(max(0, when - self.time()), MAXIMUM_SELECT_TIMEOUT) + timeout = self._scheduled[0]._when - self.time() + if timeout > MAXIMUM_SELECT_TIMEOUT: + timeout = MAXIMUM_SELECT_TIMEOUT + elif timeout < 0: + timeout = 0 event_list = self._selector.select(timeout) self._process_events(event_list) diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index f895750e3cf959..d521b4e2e255a9 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -274,9 +274,8 @@ def _ensure_fd_no_transport(self, fd): def _add_reader(self, fd, callback, *args): self._check_closed() handle = events.Handle(callback, args, self, None) - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: self._selector.register(fd, selectors.EVENT_READ, (handle, None)) else: @@ -290,30 +289,27 @@ def _add_reader(self, fd, callback, *args): def _remove_reader(self, fd): if self.is_closed(): return False - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: return False + mask, (reader, writer) = key.events, key.data + mask &= ~selectors.EVENT_READ + if not mask: + self._selector.unregister(fd) else: - mask, (reader, writer) = key.events, key.data - mask &= ~selectors.EVENT_READ - if not mask: - self._selector.unregister(fd) - else: - self._selector.modify(fd, mask, (None, writer)) + self._selector.modify(fd, mask, (None, writer)) - if reader is not None: - reader.cancel() - return True - else: - return False + if reader is not None: + reader.cancel() + return True + else: + return False def _add_writer(self, fd, callback, *args): self._check_closed() handle = events.Handle(callback, args, self, None) - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: self._selector.register(fd, selectors.EVENT_WRITE, (None, handle)) else: @@ -328,24 +324,22 @@ def _remove_writer(self, fd): """Remove a writer callback.""" if self.is_closed(): return False - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: return False + mask, (reader, writer) = key.events, key.data + # Remove both writer and connector. + mask &= ~selectors.EVENT_WRITE + if not mask: + self._selector.unregister(fd) else: - mask, (reader, writer) = key.events, key.data - # Remove both writer and connector. - mask &= ~selectors.EVENT_WRITE - if not mask: - self._selector.unregister(fd) - else: - self._selector.modify(fd, mask, (reader, None)) + self._selector.modify(fd, mask, (reader, None)) - if writer is not None: - writer.cancel() - return True - else: - return False + if writer is not None: + writer.cancel() + return True + else: + return False def add_reader(self, fd, callback, *args): """Add a reader callback.""" diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 488e17d8bccd5b..3eb65a8a08b5a0 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -539,7 +539,7 @@ def _start_handshake(self): # start handshake timeout count down self._handshake_timeout_handle = \ self._loop.call_later(self._ssl_handshake_timeout, - lambda: self._check_handshake_timeout()) + self._check_handshake_timeout) self._do_handshake() @@ -619,7 +619,7 @@ def _start_shutdown(self): self._set_state(SSLProtocolState.FLUSHING) self._shutdown_timeout_handle = self._loop.call_later( self._ssl_shutdown_timeout, - lambda: self._check_shutdown_timeout() + self._check_shutdown_timeout ) self._do_flush() @@ -758,7 +758,7 @@ def _do_read__buffered(self): else: break else: - self._loop.call_soon(lambda: self._do_read()) + self._loop.call_soon(self._do_read) except SSLAgainErrors: pass if offset > 0: diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index bf15f517e50dce..bc84e53b8443cf 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -5,6 +5,7 @@ import collections import socket import sys +import warnings import weakref if hasattr(socket, 'AF_UNIX'): @@ -66,9 +67,8 @@ async def start_server(client_connected_cb, host=None, port=None, *, positional host and port, with various optional keyword arguments following. The return value is the same as loop.create_server(). - Additional optional keyword arguments are loop (to set the event loop - instance to use) and limit (to set the buffer limit passed to the - StreamReader). + Additional optional keyword argument is limit (to set the buffer + limit passed to the StreamReader). The return value is the same as loop.create_server(), i.e. a Server object which can be used to stop the service. @@ -392,6 +392,11 @@ async def start_tls(self, sslcontext, *, self._transport = new_transport protocol._replace_writer(self) + def __del__(self, warnings=warnings): + if not self._transport.is_closing(): + self.close() + warnings.warn(f"unclosed {self!r}", ResourceWarning) + class StreamReader: diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py index c4e5ba2061cffc..043359bbd03f8a 100644 --- a/Lib/asyncio/subprocess.py +++ b/Lib/asyncio/subprocess.py @@ -147,15 +147,17 @@ def kill(self): async def _feed_stdin(self, input): debug = self._loop.get_debug() - if input is not None: - self.stdin.write(input) - if debug: - logger.debug( - '%r communicate: feed stdin (%s bytes)', self, len(input)) try: + if input is not None: + self.stdin.write(input) + if debug: + logger.debug( + '%r communicate: feed stdin (%s bytes)', self, len(input)) + await self.stdin.drain() except (BrokenPipeError, ConnectionResetError) as exc: - # communicate() ignores BrokenPipeError and ConnectionResetError + # communicate() ignores BrokenPipeError and ConnectionResetError. + # write() and drain() can raise these exceptions. if debug: logger.debug('%r communicate: stdin got %r', self, exc) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 75dd3cb6c2e987..72f4cc07173f0a 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -17,7 +17,6 @@ import itertools import math import types -import warnings import weakref from types import GenericAlias @@ -74,15 +73,25 @@ class Task(futures._PyFuture): # Inherit Python Task implementation """A coroutine wrapped in a Future.""" # An important invariant maintained while a Task not done: + # _fut_waiter is either None or a Future. The Future + # can be either done() or not done(). + # The task can be in any of 3 states: # - # - Either _fut_waiter is None, and _step() is scheduled; - # - or _fut_waiter is some Future, and _step() is *not* scheduled. + # - 1: _fut_waiter is not None and not _fut_waiter.done(): + # __step() is *not* scheduled and the Task is waiting for _fut_waiter. + # - 2: (_fut_waiter is None or _fut_waiter.done()) and __step() is scheduled: + # the Task is waiting for __step() to be executed. + # - 3: _fut_waiter is None and __step() is *not* scheduled: + # the Task is currently executing (in __step()). # - # The only transition from the latter to the former is through - # _wakeup(). When _fut_waiter is not None, one of its callbacks - # must be _wakeup(). - - # If False, don't log a message if the task is destroyed whereas its + # * In state 1, one of the callbacks of __fut_waiter must be __wakeup(). + # * The transition from 1 to 2 happens when _fut_waiter becomes done(), + # as it schedules __wakeup() to be called (which calls __step() so + # we way that __step() is scheduled). + # * It transitions from 2 to 3 when __step() is executed, and it clears + # _fut_waiter to None. + + # If False, don't log a message if the task is destroyed while its # status is still pending _log_destroy_pending = True @@ -935,21 +944,21 @@ def callback(): def create_eager_task_factory(custom_task_constructor): """Create a function suitable for use as a task factory on an event-loop. - Example usage: + Example usage: - loop.set_task_factory( - asyncio.create_eager_task_factory(my_task_constructor)) + loop.set_task_factory( + asyncio.create_eager_task_factory(my_task_constructor)) - Now, tasks created will be started immediately (rather than being first - scheduled to an event loop). The constructor argument can be any callable - that returns a Task-compatible object and has a signature compatible - with `Task.__init__`; it must have the `eager_start` keyword argument. + Now, tasks created will be started immediately (rather than being first + scheduled to an event loop). The constructor argument can be any callable + that returns a Task-compatible object and has a signature compatible + with `Task.__init__`; it must have the `eager_start` keyword argument. - Most applications will use `Task` for `custom_task_constructor` and in + Most applications will use `Task` for `custom_task_constructor` and in this case there's no need to call `create_eager_task_factory()` directly. Instead the global `eager_task_factory` instance can be used. E.g. `loop.set_task_factory(asyncio.eager_task_factory)`. - """ + """ def factory(loop, coro, *, name=None, context=None): return custom_task_constructor( diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 17fb4d5f7646ce..65f0923264d14e 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -32,6 +32,7 @@ 'FastChildWatcher', 'PidfdChildWatcher', 'MultiLoopChildWatcher', 'ThreadedChildWatcher', 'DefaultEventLoopPolicy', + 'EventLoop', ) @@ -226,8 +227,7 @@ async def _make_subprocess_transport(self, protocol, args, shell, return transp def _child_watcher_callback(self, pid, returncode, transp): - # Skip one iteration for callbacks to be executed - self.call_soon_threadsafe(self.call_soon, transp._process_exited, returncode) + self.call_soon_threadsafe(transp._process_exited, returncode) async def create_unix_connection( self, protocol_factory, path=None, *, @@ -394,6 +394,9 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno, fut.set_result(total_sent) return + # On 32-bit architectures truncate to 1GiB to avoid OverflowError + blocksize = min(blocksize, sys.maxsize//2 + 1) + try: sent = os.sendfile(fd, fileno, offset, blocksize) except (BlockingIOError, InterruptedError): @@ -1508,3 +1511,4 @@ def set_child_watcher(self, watcher): SelectorEventLoop = _UnixSelectorEventLoop DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy +EventLoop = SelectorEventLoop diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index c9a5fb841cb134..b62ea75fee3858 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -29,7 +29,7 @@ __all__ = ( 'SelectorEventLoop', 'ProactorEventLoop', 'IocpProactor', 'DefaultEventLoopPolicy', 'WindowsSelectorEventLoopPolicy', - 'WindowsProactorEventLoopPolicy', + 'WindowsProactorEventLoopPolicy', 'EventLoop', ) @@ -314,24 +314,25 @@ def __init__(self, proactor=None): proactor = IocpProactor() super().__init__(proactor) - def run_forever(self): - try: - assert self._self_reading_future is None - self.call_soon(self._loop_self_reading) - super().run_forever() - finally: - if self._self_reading_future is not None: - ov = self._self_reading_future._ov - self._self_reading_future.cancel() - # self_reading_future was just cancelled so if it hasn't been - # finished yet, it never will be (it's possible that it has - # already finished and its callback is waiting in the queue, - # where it could still happen if the event loop is restarted). - # Unregister it otherwise IocpProactor.close will wait for it - # forever - if ov is not None: - self._proactor._unregister(ov) - self._self_reading_future = None + def _run_forever_setup(self): + assert self._self_reading_future is None + self.call_soon(self._loop_self_reading) + super()._run_forever_setup() + + def _run_forever_cleanup(self): + super()._run_forever_cleanup() + if self._self_reading_future is not None: + ov = self._self_reading_future._ov + self._self_reading_future.cancel() + # self_reading_future was just cancelled so if it hasn't been + # finished yet, it never will be (it's possible that it has + # already finished and its callback is waiting in the queue, + # where it could still happen if the event loop is restarted). + # Unregister it otherwise IocpProactor.close will wait for it + # forever + if ov is not None: + self._proactor._unregister(ov) + self._self_reading_future = None async def create_pipe_connection(self, protocol_factory, address): f = self._proactor.connect_pipe(address) @@ -894,3 +895,4 @@ class WindowsProactorEventLoopPolicy(events.BaseDefaultEventLoopPolicy): DefaultEventLoopPolicy = WindowsProactorEventLoopPolicy +EventLoop = ProactorEventLoop diff --git a/Lib/calendar.py b/Lib/calendar.py index ea56f12ccc41d0..03469d8ac96bcd 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -10,7 +10,6 @@ from enum import IntEnum, global_enum import locale as _locale from itertools import repeat -import warnings __all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", "firstweekday", "isleap", "leapdays", "weekday", "monthrange", @@ -44,6 +43,7 @@ def __str__(self): def __getattr__(name): if name in ('January', 'February'): + import warnings warnings.warn(f"The '{name}' attribute is deprecated, use '{name.upper()}' instead", DeprecationWarning, stacklevel=2) if name == 'January': @@ -585,8 +585,6 @@ def __enter__(self): _locale.setlocale(_locale.LC_TIME, self.locale) def __exit__(self, *args): - if self.oldlocale is None: - return _locale.setlocale(_locale.LC_TIME, self.oldlocale) @@ -690,7 +688,7 @@ def timegm(tuple): return seconds -def main(args): +def main(args=None): import argparse parser = argparse.ArgumentParser() textgroup = parser.add_argument_group('text only arguments') @@ -723,7 +721,7 @@ def main(args): parser.add_argument( "-L", "--locale", default=None, - help="locale to be used from month and weekday names" + help="locale to use for month and weekday names" ) parser.add_argument( "-e", "--encoding", @@ -747,7 +745,7 @@ def main(args): help="month number (1-12, text only)" ) - options = parser.parse_args(args[1:]) + options = parser.parse_args(args) if options.locale and not options.encoding: parser.error("if --locale is specified --encoding is required") @@ -756,6 +754,9 @@ def main(args): locale = options.locale, options.encoding if options.type == "html": + if options.month: + parser.error("incorrect number of arguments") + sys.exit(1) if options.locale: cal = LocaleHTMLCalendar(locale=locale) else: @@ -767,11 +768,8 @@ def main(args): write = sys.stdout.buffer.write if options.year is None: write(cal.formatyearpage(datetime.date.today().year, **optdict)) - elif options.month is None: - write(cal.formatyearpage(options.year, **optdict)) else: - parser.error("incorrect number of arguments") - sys.exit(1) + write(cal.formatyearpage(options.year, **optdict)) else: if options.locale: cal = LocaleTextCalendar(locale=locale) @@ -795,4 +793,4 @@ def main(args): if __name__ == "__main__": - main(sys.argv) + main() diff --git a/Lib/codecs.py b/Lib/codecs.py index c1c55d8afef389..9b35b6127dd01c 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -111,6 +111,9 @@ def __repr__(self): (self.__class__.__module__, self.__class__.__qualname__, self.name, id(self)) + def __getnewargs__(self): + return tuple(self) + class Codec: """ Defines the interface for stateless encoders/decoders. @@ -414,6 +417,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamReader(Codec): @@ -663,6 +669,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamReaderWriter: @@ -750,6 +759,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamRecoder: @@ -866,6 +878,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### Shortcuts def open(filename, mode='r', encoding=None, errors='strict', buffering=-1): diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 03ca2d7e18f6f0..a461550ea40da7 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -95,17 +95,19 @@ class OrderedDict(dict): # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. + def __new__(cls, /, *args, **kwds): + "Create the ordered dict object and set up the underlying structures." + self = dict.__new__(cls) + self.__hardroot = _Link() + self.__root = root = _proxy(self.__hardroot) + root.prev = root.next = root + self.__map = {} + return self + def __init__(self, other=(), /, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries. Keyword argument order is preserved. ''' - try: - self.__root - except AttributeError: - self.__hardroot = _Link() - self.__root = root = _proxy(self.__hardroot) - root.prev = root.next = root - self.__map = {} self.__update(other, **kwds) def __setitem__(self, key, value, @@ -493,6 +495,7 @@ def __getnewargs__(self): '_field_defaults': field_defaults, '__new__': __new__, '_make': _make, + '__replace__': _replace, '_replace': _replace, '__repr__': __repr__, '_asdict': _asdict, diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 301207f59de37a..ffaffdb8b3d0aa 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -71,6 +71,11 @@ def __init__(self): self._reader, self._writer = mp.Pipe(duplex=False) def close(self): + # Please note that we do not take the shutdown lock when + # calling clear() (to avoid deadlocking) so this method can + # only be called safely from the same thread as all calls to + # clear() even if you hold the shutdown lock. Otherwise we + # might try to read from the closed pipe. if not self._closed: self._closed = True self._writer.close() @@ -336,7 +341,14 @@ def run(self): # Main loop for the executor manager thread. while True: - self.add_call_item_to_queue() + # gh-109047: During Python finalization, self.call_queue.put() + # creation of a thread can fail with RuntimeError. + try: + self.add_call_item_to_queue() + except BaseException as exc: + cause = format_exception(exc) + self.terminate_broken(cause) + return result_item, is_broken, cause = self.wait_result_broken_or_wakeup() @@ -420,14 +432,18 @@ def wait_result_broken_or_wakeup(self): try: result_item = result_reader.recv() is_broken = False - except BaseException as e: - cause = format_exception(type(e), e, e.__traceback__) + except BaseException as exc: + cause = format_exception(exc) elif wakeup_reader in ready: is_broken = False - with self.shutdown_lock: - self.thread_wakeup.clear() + # No need to hold the _shutdown_lock here because: + # 1. we're the only thread to use the wakeup reader + # 2. we're also the only thread to call thread_wakeup.close() + # 3. we want to avoid a possible deadlock when both reader and writer + # would block (gh-105829) + self.thread_wakeup.clear() return result_item, is_broken, cause @@ -435,24 +451,14 @@ def process_result_item(self, result_item): # Process the received a result_item. This can be either the PID of a # worker that exited gracefully or a _ResultItem - if isinstance(result_item, int): - # Clean shutdown of a worker using its PID - # (avoids marking the executor broken) - assert self.is_shutting_down() - p = self.processes.pop(result_item) - p.join() - if not self.processes: - self.join_executor_internals() - return - else: - # Received a _ResultItem so mark the future as completed. - work_item = self.pending_work_items.pop(result_item.work_id, None) - # work_item can be None if another process terminated (see above) - if work_item is not None: - if result_item.exception: - work_item.future.set_exception(result_item.exception) - else: - work_item.future.set_result(result_item.result) + # Received a _ResultItem so mark the future as completed. + work_item = self.pending_work_items.pop(result_item.work_id, None) + # work_item can be None if another process terminated (see above) + if work_item is not None: + if result_item.exception: + work_item.future.set_exception(result_item.exception) + else: + work_item.future.set_result(result_item.result) def is_shutting_down(self): # Check whether we should start shutting down the executor. @@ -464,7 +470,7 @@ def is_shutting_down(self): return (_global_shutdown or executor is None or executor._shutdown_thread) - def terminate_broken(self, cause): + def _terminate_broken(self, cause): # Terminate the executor because it is in a broken state. The cause # argument can be used to display more information on the error that # lead the executor into becoming broken. @@ -489,7 +495,14 @@ def terminate_broken(self, cause): # Mark pending tasks as failed. for work_id, work_item in self.pending_work_items.items(): - work_item.future.set_exception(bpe) + try: + work_item.future.set_exception(bpe) + except _base.InvalidStateError: + # set_exception() fails if the future is cancelled: ignore it. + # Trying to check if the future is cancelled before calling + # set_exception() would leave a race condition if the future is + # cancelled between the check and set_exception(). + pass # Delete references to object. See issue16284 del work_item self.pending_work_items.clear() @@ -499,12 +512,14 @@ def terminate_broken(self, cause): for p in self.processes.values(): p.terminate() - # Prevent queue writing to a pipe which is no longer read. - # https://github.com/python/cpython/issues/94777 - self.call_queue._reader.close() + self.call_queue._terminate_broken() # clean up resources - self.join_executor_internals() + self._join_executor_internals(broken=True) + + def terminate_broken(self, cause): + with self.shutdown_lock: + self._terminate_broken(cause) def flag_executor_shutting_down(self): # Flag the executor as shutting down and cancel remaining tasks if @@ -547,15 +562,24 @@ def shutdown_workers(self): break def join_executor_internals(self): - self.shutdown_workers() + with self.shutdown_lock: + self._join_executor_internals() + + def _join_executor_internals(self, broken=False): + # If broken, call_queue was closed and so can no longer be used. + if not broken: + self.shutdown_workers() + # Release the queue's resources as soon as possible. self.call_queue.close() self.call_queue.join_thread() - with self.shutdown_lock: - self.thread_wakeup.close() + self.thread_wakeup.close() + # If .join() is not called on the created processes then # some ctx.Queue methods may deadlock on Mac OS X. for p in self.processes.values(): + if broken: + p.terminate() p.join() def get_n_children_alive(self): @@ -642,7 +666,7 @@ def __init__(self, max_workers=None, mp_context=None, _check_system_limits() if max_workers is None: - self._max_workers = os.cpu_count() or 1 + self._max_workers = os.process_cpu_count() or 1 if sys.platform == 'win32': self._max_workers = min(_MAX_WINDOWS_WORKERS, self._max_workers) @@ -706,7 +730,10 @@ def __init__(self, max_workers=None, mp_context=None, # as it could result in a deadlock if a worker process dies with the # _result_queue write lock still acquired. # - # _shutdown_lock must be locked to access _ThreadWakeup. + # _shutdown_lock must be locked to access _ThreadWakeup.close() and + # .wakeup(). Care must also be taken to not call clear or close from + # more than one thread since _ThreadWakeup.clear() is not protected by + # the _shutdown_lock self._executor_manager_thread_wakeup = _ThreadWakeup() # Create communication channels for the executor diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 3b3a36a5093336..a024033f35fb54 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -139,10 +139,10 @@ def __init__(self, max_workers=None, thread_name_prefix='', # * CPU bound task which releases GIL # * I/O bound task (which releases GIL, of course) # - # We use cpu_count + 4 for both types of tasks. + # We use process_cpu_count + 4 for both types of tasks. # But we limit it to 32 to avoid consuming surprisingly large resource # on many core machine. - max_workers = min(32, (os.cpu_count() or 1) + 4) + max_workers = min(32, (os.process_cpu_count() or 1) + 4) if max_workers <= 0: raise ValueError("max_workers must be greater than 0") diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 95947aceccc304..6994690ebf7eb2 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -149,7 +149,10 @@ def __exit__(self, typ, value, traceback): except StopIteration: return False else: - raise RuntimeError("generator didn't stop") + try: + raise RuntimeError("generator didn't stop") + finally: + self.gen.close() else: if value is None: # Need to force instantiation so we can reliably @@ -191,7 +194,10 @@ def __exit__(self, typ, value, traceback): raise exc.__traceback__ = traceback return False - raise RuntimeError("generator didn't stop after throw()") + try: + raise RuntimeError("generator didn't stop after throw()") + finally: + self.gen.close() class _AsyncGeneratorContextManager( _GeneratorContextManagerBase, @@ -216,7 +222,10 @@ async def __aexit__(self, typ, value, traceback): except StopAsyncIteration: return False else: - raise RuntimeError("generator didn't stop") + try: + raise RuntimeError("generator didn't stop") + finally: + await self.gen.aclose() else: if value is None: # Need to force instantiation so we can reliably @@ -258,7 +267,10 @@ async def __aexit__(self, typ, value, traceback): raise exc.__traceback__ = traceback return False - raise RuntimeError("generator didn't stop after athrow()") + try: + raise RuntimeError("generator didn't stop after athrow()") + finally: + await self.gen.aclose() def contextmanager(func): @@ -557,11 +569,12 @@ def __enter__(self): return self def __exit__(self, *exc_details): - received_exc = exc_details[0] is not None + exc = exc_details[1] + received_exc = exc is not None # We manipulate the exception state so it behaves as though # we were actually nesting multiple with statements - frame_exc = sys.exc_info()[1] + frame_exc = sys.exception() def _fix_exception_context(new_exc, old_exc): # Context may not be correct, so find the end of the chain while 1: @@ -584,24 +597,28 @@ def _fix_exception_context(new_exc, old_exc): is_sync, cb = self._exit_callbacks.pop() assert is_sync try: + if exc is None: + exc_details = None, None, None + else: + exc_details = type(exc), exc, exc.__traceback__ if cb(*exc_details): suppressed_exc = True pending_raise = False - exc_details = (None, None, None) - except: - new_exc_details = sys.exc_info() + exc = None + except BaseException as new_exc: # simulate the stack of exceptions by setting the context - _fix_exception_context(new_exc_details[1], exc_details[1]) + _fix_exception_context(new_exc, exc) pending_raise = True - exc_details = new_exc_details + exc = new_exc + if pending_raise: try: - # bare "raise exc_details[1]" replaces our carefully + # bare "raise exc" replaces our carefully # set-up context - fixed_ctx = exc_details[1].__context__ - raise exc_details[1] + fixed_ctx = exc.__context__ + raise exc except BaseException: - exc_details[1].__context__ = fixed_ctx + exc.__context__ = fixed_ctx raise return received_exc and suppressed_exc @@ -697,11 +714,12 @@ async def __aenter__(self): return self async def __aexit__(self, *exc_details): - received_exc = exc_details[0] is not None + exc = exc_details[1] + received_exc = exc is not None # We manipulate the exception state so it behaves as though # we were actually nesting multiple with statements - frame_exc = sys.exc_info()[1] + frame_exc = sys.exception() def _fix_exception_context(new_exc, old_exc): # Context may not be correct, so find the end of the chain while 1: @@ -723,6 +741,10 @@ def _fix_exception_context(new_exc, old_exc): while self._exit_callbacks: is_sync, cb = self._exit_callbacks.pop() try: + if exc is None: + exc_details = None, None, None + else: + exc_details = type(exc), exc, exc.__traceback__ if is_sync: cb_suppress = cb(*exc_details) else: @@ -731,21 +753,21 @@ def _fix_exception_context(new_exc, old_exc): if cb_suppress: suppressed_exc = True pending_raise = False - exc_details = (None, None, None) - except: - new_exc_details = sys.exc_info() + exc = None + except BaseException as new_exc: # simulate the stack of exceptions by setting the context - _fix_exception_context(new_exc_details[1], exc_details[1]) + _fix_exception_context(new_exc, exc) pending_raise = True - exc_details = new_exc_details + exc = new_exc + if pending_raise: try: - # bare "raise exc_details[1]" replaces our carefully + # bare "raise exc" replaces our carefully # set-up context - fixed_ctx = exc_details[1].__context__ - raise exc_details[1] + fixed_ctx = exc.__context__ + raise exc except BaseException: - exc_details[1].__context__ = fixed_ctx + exc.__context__ = fixed_ctx raise return received_exc and suppressed_exc diff --git a/Lib/copy.py b/Lib/copy.py index da2908ef623d8c..a69bc4e78c20b3 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -121,13 +121,13 @@ def deepcopy(x, memo=None, _nil=[]): See the module's __doc__ string for more info. """ + d = id(x) if memo is None: memo = {} - - d = id(x) - y = memo.get(d, _nil) - if y is not _nil: - return y + else: + y = memo.get(d, _nil) + if y is not _nil: + return y cls = type(x) @@ -290,3 +290,16 @@ def _reconstruct(x, memo, func, args, return y del types, weakref + + +def replace(obj, /, **changes): + """Return a new object replacing specified fields with new values. + + This is especially useful for immutable objects, like named tuples or + frozen dataclasses. + """ + cls = obj.__class__ + func = getattr(cls, '__replace__', None) + if func is None: + raise TypeError(f"replace() does not support {cls.__name__} objects") + return func(obj, **changes) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index e766a7b554afe1..2fba32b5ffbc1e 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -575,15 +575,15 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init, # message, and future-proofs us in case we build up the function # using ast. - seen_default = False + seen_default = None for f in std_fields: # Only consider the non-kw-only fields in the __init__ call. if f.init: if not (f.default is MISSING and f.default_factory is MISSING): - seen_default = True + seen_default = f elif seen_default: raise TypeError(f'non-default argument {f.name!r} ' - 'follows default argument') + f'follows default argument {seen_default.name!r}') locals = {f'__dataclass_type_{f.name}__': f.type for f in fields} locals.update({ @@ -944,8 +944,11 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, # Find our base classes in reverse MRO order, and exclude # ourselves. In reversed order so that more derived classes # override earlier field definitions in base classes. As long as - # we're iterating over them, see if any are frozen. + # we're iterating over them, see if all or any of them are frozen. any_frozen_base = False + # By default `all_frozen_bases` is `None` to represent a case, + # where some dataclasses does not have any bases with `_FIELDS` + all_frozen_bases = None has_dataclass_bases = False for b in cls.__mro__[-1:0:-1]: # Only process classes that have been processed by our @@ -955,8 +958,11 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, has_dataclass_bases = True for f in base_fields.values(): fields[f.name] = f - if getattr(b, _PARAMS).frozen: - any_frozen_base = True + if all_frozen_bases is None: + all_frozen_bases = True + current_frozen = getattr(b, _PARAMS).frozen + all_frozen_bases = all_frozen_bases and current_frozen + any_frozen_base = any_frozen_base or current_frozen # Annotations defined specifically in this class (not in base classes). # @@ -1025,7 +1031,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, 'frozen one') # Raise an exception if we're frozen, but none of our bases are. - if not any_frozen_base and frozen: + if all_frozen_bases is False and frozen: raise TypeError('cannot inherit frozen dataclass from a ' 'non-frozen one') @@ -1036,7 +1042,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, # Was this class defined with an explicit __hash__? Note that if # __eq__ is defined in this class, then python will automatically # set __hash__ to None. This is a heuristic, as it's possible - # that such a __hash__ == None was not auto-generated, but it + # that such a __hash__ == None was not auto-generated, but it's # close enough. class_hash = cls.__dict__.get('__hash__', MISSING) has_explicit_hash = not (class_hash is MISSING or @@ -1073,6 +1079,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, globals, slots, )) + _set_new_attribute(cls, '__replace__', _replace) # Get the fields as a list, and include only real fields. This is # used in all of the following methods. @@ -1546,13 +1553,15 @@ class C: c1 = replace(c, x=3) assert c1.x == 3 and c1.y == 2 """ + if not _is_dataclass_instance(obj): + raise TypeError("replace() should be called on dataclass instances") + return _replace(obj, **changes) + +def _replace(obj, /, **changes): # We're going to mutate 'changes', but that's okay because it's a # new dict, even if called with 'replace(obj, **my_changes)'. - if not _is_dataclass_instance(obj): - raise TypeError("replace() should be called on dataclass instances") - # It's an error to have init=False fields in 'changes'. # If a field is not in 'changes', read its value from the provided obj. @@ -1564,15 +1573,15 @@ class C: if not f.init: # Error if this field is specified in changes. if f.name in changes: - raise ValueError(f'field {f.name} is declared with ' - 'init=False, it cannot be specified with ' - 'replace()') + raise TypeError(f'field {f.name} is declared with ' + f'init=False, it cannot be specified with ' + f'replace()') continue if f.name not in changes: if f._field_type is _FIELD_INITVAR and f.default is MISSING: - raise ValueError(f"InitVar {f.name!r} " - 'must be specified with replace()') + raise TypeError(f"InitVar {f.name!r} " + f'must be specified with replace()') changes[f.name] = getattr(obj, f.name) # Create the new object, which calls __init__() and diff --git a/Lib/dis.py b/Lib/dis.py index f7a31f2f96b99b..cad62b95990c30 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -14,7 +14,7 @@ _intrinsic_1_descs, _intrinsic_2_descs, _specializations, - _specialized_instructions, + _specialized_opmap, ) __all__ = ["code_info", "dis", "disassemble", "distb", "disco", @@ -49,11 +49,11 @@ _all_opname = list(opname) _all_opmap = dict(opmap) -_empty_slot = [slot for slot, name in enumerate(_all_opname) if name.startswith("<")] -for spec_op, specialized in zip(_empty_slot, _specialized_instructions): +for name, op in _specialized_opmap.items(): # fill opname and opmap - _all_opname[spec_op] = specialized - _all_opmap[specialized] = spec_op + assert op < len(_all_opname) + _all_opname[op] = name + _all_opmap[name] = op deoptmap = { specialized: base for base, family in _specializations.items() for specialized in family @@ -262,6 +262,7 @@ def show_code(co, *, file=None): 'offset', 'start_offset', 'starts_line', + 'line_number', 'is_jump_target', 'positions' ], @@ -278,7 +279,8 @@ def show_code(co, *, file=None): "Start index of operation within bytecode sequence, including extended args if present; " "otherwise equal to Instruction.offset" ) -_Instruction.starts_line.__doc__ = "Line started by this opcode (if any), otherwise None" +_Instruction.starts_line.__doc__ = "True if this opcode starts a source line, otherwise False" +_Instruction.line_number.__doc__ = "source line number associated with this opcode (if any), otherwise None" _Instruction.is_jump_target.__doc__ = "True if other code jumps to here, otherwise False" _Instruction.positions.__doc__ = "dis.Positions object holding the span of source code covered by this instruction" @@ -288,13 +290,16 @@ def show_code(co, *, file=None): _OPNAME_WIDTH = 20 _OPARG_WIDTH = 5 +def _get_cache_size(opname): + return _inline_cache_entries.get(opname, 0) + def _get_jump_target(op, arg, offset): """Gets the bytecode offset of the jump target if this is a jump instruction. Otherwise return None. """ deop = _deoptop(op) - caches = _inline_cache_entries[deop] + caches = _get_cache_size(_all_opname[deop]) if deop in hasjrel: if _is_backward_jump(deop): arg = -arg @@ -318,7 +323,8 @@ class Instruction(_Instruction): offset - start index of operation within bytecode sequence start_offset - start index of operation within bytecode sequence including extended args if present; otherwise equal to Instruction.offset - starts_line - line started by this opcode (if any), otherwise None + starts_line - True if this opcode starts a source line, otherwise False + line_number - source line number associated with this opcode (if any), otherwise None is_jump_target - True if other code jumps to here, otherwise False positions - Optional dis.Positions object holding the span of source code covered by this instruction @@ -353,7 +359,7 @@ def cache_offset(self): @property def end_offset(self): """End index of the cache entries following the operation.""" - return self.cache_offset + _inline_cache_entries[self.opcode]*2 + return self.cache_offset + _get_cache_size(_all_opname[self.opcode])*2 @property def jump_target(self): @@ -373,9 +379,10 @@ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): fields = [] # Column: Source code line number if lineno_width: - if self.starts_line is not None: - lineno_fmt = "%%%dd" % lineno_width - fields.append(lineno_fmt % self.starts_line) + if self.starts_line: + lineno_fmt = "%%%dd" if self.line_number is not None else "%%%ds" + lineno_fmt = lineno_fmt % lineno_width + fields.append(lineno_fmt % self.line_number) else: fields.append(' ' * lineno_width) # Column: Current instruction indicator @@ -430,7 +437,8 @@ def get_instructions(x, *, first_line=None, show_caches=False, adaptive=False): co.co_names, co.co_consts, linestarts, line_offset, co_positions=co.co_positions(), - show_caches=show_caches) + show_caches=show_caches, + original_code=co.co_code) def _get_const_value(op, arg, co_consts): """Helper to get the value of the const in a hasconst op. @@ -504,7 +512,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None, names=None, co_consts=None, linestarts=None, line_offset=0, exception_entries=(), co_positions=None, - show_caches=False): + show_caches=False, original_code=None): """Iterate over the instructions in a bytecode string. Generates a sequence of Instruction namedtuples giving the details of each @@ -513,24 +521,35 @@ def _get_instructions_bytes(code, varname_from_oparg=None, arguments. """ + # Use the basic, unadaptive code for finding labels and actually walking the + # bytecode, since replacements like ENTER_EXECUTOR and INSTRUMENTED_* can + # mess that logic up pretty badly: + original_code = original_code or code co_positions = co_positions or iter(()) get_name = None if names is None else names.__getitem__ - labels = set(findlabels(code)) + labels = set(findlabels(original_code)) for start, end, target, _, _ in exception_entries: for i in range(start, end): labels.add(target) - starts_line = None - for offset, start_offset, op, arg in _unpack_opargs(code): + starts_line = False + local_line_number = None + line_number = None + for offset, start_offset, op, arg in _unpack_opargs(original_code): if linestarts is not None: - starts_line = linestarts.get(offset, None) - if starts_line is not None: - starts_line += line_offset + starts_line = offset in linestarts + if starts_line: + local_line_number = linestarts[offset] + if local_line_number is not None: + line_number = local_line_number + line_offset + else: + line_number = None is_jump_target = offset in labels argval = None argrepr = '' positions = Positions(*next(co_positions, ())) deop = _deoptop(op) - caches = _inline_cache_entries[deop] + caches = _get_cache_size(_all_opname[deop]) + op = code[offset] if arg is not None: # Set argval to the dereferenced value of the argument when # available, and argrepr to the string representation of argval. @@ -543,15 +562,15 @@ def _get_instructions_bytes(code, varname_from_oparg=None, if deop == LOAD_GLOBAL: argval, argrepr = _get_name_info(arg//2, get_name) if (arg & 1) and argrepr: - argrepr = "NULL + " + argrepr + argrepr = f"{argrepr} + NULL" elif deop == LOAD_ATTR: argval, argrepr = _get_name_info(arg//2, get_name) if (arg & 1) and argrepr: - argrepr = "NULL|self + " + argrepr + argrepr = f"{argrepr} + NULL|self" elif deop == LOAD_SUPER_ATTR: argval, argrepr = _get_name_info(arg//4, get_name) if (arg & 1) and argrepr: - argrepr = "NULL|self + " + argrepr + argrepr = f"{argrepr} + NULL|self" else: argval, argrepr = _get_name_info(arg, get_name) elif deop in hasjabs: @@ -590,8 +609,8 @@ def _get_instructions_bytes(code, varname_from_oparg=None, argrepr = _intrinsic_2_descs[arg] yield Instruction(_all_opname[op], op, arg, argval, argrepr, - offset, start_offset, starts_line, is_jump_target, positions) - caches = _inline_cache_entries[deop] + offset, start_offset, starts_line, line_number, + is_jump_target, positions) if not caches: continue if not show_caches: @@ -610,7 +629,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None, else: argrepr = "" yield Instruction( - "CACHE", CACHE, 0, None, argrepr, offset, offset, None, False, + "CACHE", CACHE, 0, None, argrepr, offset, offset, False, None, False, Positions(*next(co_positions, ())) ) @@ -622,7 +641,8 @@ def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False): lasti, co._varname_from_oparg, co.co_names, co.co_consts, linestarts, file=file, exception_entries=exception_entries, - co_positions=co.co_positions(), show_caches=show_caches) + co_positions=co.co_positions(), show_caches=show_caches, + original_code=co.co_code) def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adaptive=False): disassemble(co, file=file, show_caches=show_caches, adaptive=adaptive) @@ -640,15 +660,23 @@ def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adap def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, names=None, co_consts=None, linestarts=None, *, file=None, line_offset=0, exception_entries=(), - co_positions=None, show_caches=False): + co_positions=None, show_caches=False, original_code=None): # Omit the line number column entirely if we have no line number info - show_lineno = bool(linestarts) + if bool(linestarts): + linestarts_ints = [line for line in linestarts.values() if line is not None] + show_lineno = len(linestarts_ints) > 0 + else: + show_lineno = False + if show_lineno: - maxlineno = max(linestarts.values()) + line_offset + maxlineno = max(linestarts_ints) + line_offset if maxlineno >= 1000: lineno_width = len(str(maxlineno)) else: lineno_width = 3 + + if lineno_width < len(str(None)) and None in linestarts.values(): + lineno_width = len(str(None)) else: lineno_width = 0 maxoffset = len(code) - 2 @@ -661,9 +689,10 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, line_offset=line_offset, exception_entries=exception_entries, co_positions=co_positions, - show_caches=show_caches): + show_caches=show_caches, + original_code=original_code): new_source_line = (show_lineno and - instr.starts_line is not None and + instr.starts_line and instr.offset > 0) if new_source_line: print(file=file) @@ -672,7 +701,7 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, else: # Each CACHE takes 2 bytes is_current_instr = instr.offset <= lasti \ - <= instr.offset + 2 * _inline_cache_entries[_deoptop(instr.opcode)] + <= instr.offset + 2 * _get_cache_size(_all_opname[_deoptop(instr.opcode)]) print(instr._disassemble(lineno_width, is_current_instr, offset_width), file=file) if exception_entries: @@ -705,7 +734,7 @@ def _unpack_opargs(code): continue op = code[i] deop = _deoptop(op) - caches = _inline_cache_entries[deop] + caches = _get_cache_size(_all_opname[deop]) if deop in hasarg: arg = code[i+1] | extended_arg extended_arg = (arg << 8) if deop == EXTENDED_ARG else 0 @@ -745,10 +774,12 @@ def findlinestarts(code): """Find the offsets in a byte code which are start of lines in the source. Generate pairs (offset, lineno) + lineno will be an integer or None the offset does not have a source line. """ - lastline = None + + lastline = False # None is a valid line number for start, end, line in code.co_lines(): - if line is not None and line != lastline: + if line is not lastline: lastline = line yield start, line return @@ -823,7 +854,8 @@ def __iter__(self): line_offset=self._line_offset, exception_entries=self.exception_entries, co_positions=co.co_positions(), - show_caches=self.show_caches) + show_caches=self.show_caches, + original_code=co.co_code) def __repr__(self): return "{}({!r})".format(self.__class__.__name__, @@ -859,21 +891,23 @@ def dis(self): lasti=offset, exception_entries=self.exception_entries, co_positions=co.co_positions(), - show_caches=self.show_caches) + show_caches=self.show_caches, + original_code=co.co_code) return output.getvalue() -def _test(): - """Simple test program to disassemble a file.""" +def main(): import argparse parser = argparse.ArgumentParser() + parser.add_argument('-C', '--show-caches', action='store_true', + help='show inline caches') parser.add_argument('infile', type=argparse.FileType('rb'), nargs='?', default='-') args = parser.parse_args() with args.infile as infile: source = infile.read() code = compile(source, args.infile.name, "exec") - dis(code) + dis(code, show_caches=args.show_caches) if __name__ == "__main__": - _test() + main() diff --git a/Lib/doctest.py b/Lib/doctest.py index 2776d74bf9b586..46b4dd6769b063 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -105,7 +105,23 @@ def _test(): from io import StringIO, IncrementalNewlineDecoder from collections import namedtuple -TestResults = namedtuple('TestResults', 'failed attempted') + +class TestResults(namedtuple('TestResults', 'failed attempted')): + def __new__(cls, failed, attempted, *, skipped=0): + results = super().__new__(cls, failed, attempted) + results.skipped = skipped + return results + + def __repr__(self): + if self.skipped: + return (f'TestResults(failed={self.failed}, ' + f'attempted={self.attempted}, ' + f'skipped={self.skipped})') + else: + # Leave the repr() unchanged for backward compatibility + # if skipped is zero + return super().__repr__() + # There are 4 basic classes: # - Example: a pair, plus an intra-docstring line number. @@ -1110,7 +1126,7 @@ def _find_lineno(self, obj, source_lines): if source_lines is None: return None pat = re.compile(r'^\s*class\s*%s\b' % - getattr(obj, '__name__', '-')) + re.escape(getattr(obj, '__name__', '-'))) for i, line in enumerate(source_lines): if pat.match(line): lineno = i @@ -1150,8 +1166,7 @@ class DocTestRunner: """ A class used to run DocTest test cases, and accumulate statistics. The `run` method is used to process a single DocTest case. It - returns a tuple `(f, t)`, where `t` is the number of test cases - tried, and `f` is the number of test cases that failed. + returns a TestResults instance. >>> tests = DocTestFinder().find(_TestClass) >>> runner = DocTestRunner(verbose=False) @@ -1164,8 +1179,8 @@ class DocTestRunner: _TestClass.square -> TestResults(failed=0, attempted=1) The `summarize` method prints a summary of all the test cases that - have been run by the runner, and returns an aggregated `(f, t)` - tuple: + have been run by the runner, and returns an aggregated TestResults + instance: >>> runner.summarize(verbose=1) 4 items passed all tests: @@ -1178,13 +1193,15 @@ class DocTestRunner: Test passed. TestResults(failed=0, attempted=7) - The aggregated number of tried examples and failed examples is - also available via the `tries` and `failures` attributes: + The aggregated number of tried examples and failed examples is also + available via the `tries`, `failures` and `skips` attributes: >>> runner.tries 7 >>> runner.failures 0 + >>> runner.skips + 0 The comparison between expected outputs and actual outputs is done by an `OutputChecker`. This comparison may be customized with a @@ -1233,7 +1250,8 @@ def __init__(self, checker=None, verbose=None, optionflags=0): # Keep track of the examples we've run. self.tries = 0 self.failures = 0 - self._name2ft = {} + self.skips = 0 + self._stats = {} # Create a fake output target for capturing doctest output. self._fakeout = _SpoofOut() @@ -1302,13 +1320,11 @@ def __run(self, test, compileflags, out): Run the examples in `test`. Write the outcome of each example with one of the `DocTestRunner.report_*` methods, using the writer function `out`. `compileflags` is the set of compiler - flags that should be used to execute examples. Return a tuple - `(f, t)`, where `t` is the number of examples tried, and `f` - is the number of examples that failed. The examples are run - in the namespace `test.globs`. + flags that should be used to execute examples. Return a TestResults + instance. The examples are run in the namespace `test.globs`. """ - # Keep track of the number of failures and tries. - failures = tries = 0 + # Keep track of the number of failed, attempted, skipped examples. + failures = attempted = skips = 0 # Save the option flags (since option directives can be used # to modify them). @@ -1320,6 +1336,7 @@ def __run(self, test, compileflags, out): # Process each example. for examplenum, example in enumerate(test.examples): + attempted += 1 # If REPORT_ONLY_FIRST_FAILURE is set, then suppress # reporting after the first failure. @@ -1337,10 +1354,10 @@ def __run(self, test, compileflags, out): # If 'SKIP' is set, then skip this example. if self.optionflags & SKIP: + skips += 1 continue # Record that we started this example. - tries += 1 if not quiet: self.report_start(out, test, example) @@ -1418,19 +1435,22 @@ def __run(self, test, compileflags, out): # Restore the option flags (in case they were modified) self.optionflags = original_optionflags - # Record and return the number of failures and tries. - self.__record_outcome(test, failures, tries) - return TestResults(failures, tries) + # Record and return the number of failures and attempted. + self.__record_outcome(test, failures, attempted, skips) + return TestResults(failures, attempted, skipped=skips) - def __record_outcome(self, test, f, t): + def __record_outcome(self, test, failures, tries, skips): """ - Record the fact that the given DocTest (`test`) generated `f` - failures out of `t` tried examples. + Record the fact that the given DocTest (`test`) generated `failures` + failures out of `tries` tried examples. """ - f2, t2 = self._name2ft.get(test.name, (0,0)) - self._name2ft[test.name] = (f+f2, t+t2) - self.failures += f - self.tries += t + failures2, tries2, skips2 = self._stats.get(test.name, (0, 0, 0)) + self._stats[test.name] = (failures + failures2, + tries + tries2, + skips + skips2) + self.failures += failures + self.tries += tries + self.skips += skips __LINECACHE_FILENAME_RE = re.compile(r'.+)' @@ -1519,9 +1539,7 @@ def out(s): def summarize(self, verbose=None): """ Print a summary of all the test cases that have been run by - this DocTestRunner, and return a tuple `(f, t)`, where `f` is - the total number of failed examples, and `t` is the total - number of tried examples. + this DocTestRunner, and return a TestResults instance. The optional `verbose` argument controls how detailed the summary is. If the verbosity is not specified, then the @@ -1532,59 +1550,61 @@ def summarize(self, verbose=None): notests = [] passed = [] failed = [] - totalt = totalf = 0 - for x in self._name2ft.items(): - name, (f, t) = x - assert f <= t - totalt += t - totalf += f - if t == 0: + total_tries = total_failures = total_skips = 0 + for item in self._stats.items(): + name, (failures, tries, skips) = item + assert failures <= tries + total_tries += tries + total_failures += failures + total_skips += skips + if tries == 0: notests.append(name) - elif f == 0: - passed.append( (name, t) ) + elif failures == 0: + passed.append((name, tries)) else: - failed.append(x) + failed.append(item) if verbose: if notests: - print(len(notests), "items had no tests:") + print(f"{len(notests)} items had no tests:") notests.sort() - for thing in notests: - print(" ", thing) + for name in notests: + print(f" {name}") if passed: - print(len(passed), "items passed all tests:") + print(f"{len(passed)} items passed all tests:") passed.sort() - for thing, count in passed: - print(" %3d tests in %s" % (count, thing)) + for name, count in passed: + print(f" {count:3d} tests in {name}") if failed: print(self.DIVIDER) - print(len(failed), "items had failures:") + print(f"{len(failed)} items had failures:") failed.sort() - for thing, (f, t) in failed: - print(" %3d of %3d in %s" % (f, t, thing)) + for name, (failures, tries, skips) in failed: + print(f" {failures:3d} of {tries:3d} in {name}") if verbose: - print(totalt, "tests in", len(self._name2ft), "items.") - print(totalt - totalf, "passed and", totalf, "failed.") - if totalf: - print("***Test Failed***", totalf, "failures.") + print(f"{total_tries} tests in {len(self._stats)} items.") + print(f"{total_tries - total_failures} passed and {total_failures} failed.") + if total_failures: + msg = f"***Test Failed*** {total_failures} failures" + if total_skips: + msg = f"{msg} and {total_skips} skipped tests" + print(f"{msg}.") elif verbose: print("Test passed.") - return TestResults(totalf, totalt) + return TestResults(total_failures, total_tries, skipped=total_skips) #///////////////////////////////////////////////////////////////// # Backward compatibility cruft to maintain doctest.master. #///////////////////////////////////////////////////////////////// def merge(self, other): - d = self._name2ft - for name, (f, t) in other._name2ft.items(): + d = self._stats + for name, (failures, tries, skips) in other._stats.items(): if name in d: - # Don't print here by default, since doing - # so breaks some of the buildbots - #print("*** DocTestRunner.merge: '" + name + "' in both" \ - # " testers; summing outcomes.") - f2, t2 = d[name] - f = f + f2 - t = t + t2 - d[name] = f, t + failures2, tries2, skips2 = d[name] + failures = failures + failures2 + tries = tries + tries2 + skips = skips + skips2 + d[name] = (failures, tries, skips) + class OutputChecker: """ @@ -1984,7 +2004,8 @@ class doctest.Tester, then merges the results into (or creates) else: master.merge(runner) - return TestResults(runner.failures, runner.tries) + return TestResults(runner.failures, runner.tries, skipped=runner.skips) + def testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, @@ -2107,7 +2128,8 @@ class doctest.Tester, then merges the results into (or creates) else: master.merge(runner) - return TestResults(runner.failures, runner.tries) + return TestResults(runner.failures, runner.tries, skipped=runner.skips) + def run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0): diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index 53d71f50225152..06d6b4a3afcd07 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -189,7 +189,7 @@ def close(self): assert not self._msgstack # Look for final set of defects if root.get_content_maintype() == 'multipart' \ - and not root.is_multipart(): + and not root.is_multipart() and not self._headersonly: defect = errors.MultipartInvariantViolationDefect() self.policy.handle_defect(root, defect) return root diff --git a/Lib/email/utils.py b/Lib/email/utils.py index 11ad75e94e9345..a49a8fa986ce0c 100644 --- a/Lib/email/utils.py +++ b/Lib/email/utils.py @@ -25,8 +25,6 @@ import os import re import time -import random -import socket import datetime import urllib.parse @@ -36,9 +34,6 @@ from email._parseaddr import parsedate, parsedate_tz, _parsedate_tz -# Intrapackage imports -from email.charset import Charset - COMMASPACE = ', ' EMPTYSTRING = '' UEMPTYSTRING = '' @@ -94,6 +89,8 @@ def formataddr(pair, charset='utf-8'): name.encode('ascii') except UnicodeEncodeError: if isinstance(charset, str): + # lazy import to improve module import time + from email.charset import Charset charset = Charset(charset) encoded_name = charset.header_encode(name) return "%s <%s>" % (encoded_name, address) @@ -106,54 +103,12 @@ def formataddr(pair, charset='utf-8'): return address -def _pre_parse_validation(email_header_fields): - accepted_values = [] - for v in email_header_fields: - s = v.replace('\\(', '').replace('\\)', '') - if s.count('(') != s.count(')'): - v = "('', '')" - accepted_values.append(v) - - return accepted_values - - -def _post_parse_validation(parsed_email_header_tuples): - accepted_values = [] - # The parser would have parsed a correctly formatted domain-literal - # The existence of an [ after parsing indicates a parsing failure - for v in parsed_email_header_tuples: - if '[' in v[1]: - v = ('', '') - accepted_values.append(v) - - return accepted_values - def getaddresses(fieldvalues): - """Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue. - - When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in - its place. - - If the resulting list of parsed address is not the same as the number of - fieldvalues in the input list a parsing error has occurred. A list - containing a single empty 2-tuple [('', '')] is returned in its place. - This is done to avoid invalid output. - """ - fieldvalues = [str(v) for v in fieldvalues] - fieldvalues = _pre_parse_validation(fieldvalues) - all = COMMASPACE.join(v for v in fieldvalues) + """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" + all = COMMASPACE.join(str(v) for v in fieldvalues) a = _AddressList(all) - result = _post_parse_validation(a.addresslist) - - n = 0 - for v in fieldvalues: - n += v.count(',') + 1 - - if len(result) != n: - return [('', '')] - - return result + return a.addresslist def _format_timetuple_and_zone(timetuple, zone): @@ -223,6 +178,11 @@ def make_msgid(idstring=None, domain=None): portion of the message id after the '@'. It defaults to the locally defined hostname. """ + # Lazy imports to speedup module import time + # (no other functions in email.utils need these modules) + import random + import socket + timeval = int(time.time()*100) pid = os.getpid() randint = random.getrandbits(64) @@ -254,18 +214,9 @@ def parseaddr(addr): Return a tuple of realname and email address, unless the parse fails, in which case return a 2-tuple of ('', ''). """ - if isinstance(addr, list): - addr = addr[0] - - if not isinstance(addr, str): - return ('', '') - - addr = _pre_parse_validation([addr])[0] - addrs = _post_parse_validation(_AddressList(addr).addresslist) - - if not addrs or len(addrs) > 1: - return ('', '') - + addrs = _AddressList(addr).addresslist + if not addrs: + return '', '' return addrs[0] diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 5f4f1d75b43e64..1fb1d505cfd0c5 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('pip',) -_PIP_VERSION = "23.1.2" +_PIP_VERSION = "23.2.1" _PROJECTS = [ ("pip", _PIP_VERSION, "py3"), ] diff --git a/Lib/ensurepip/_bundled/pip-23.1.2-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl similarity index 74% rename from Lib/ensurepip/_bundled/pip-23.1.2-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl index 6a2515615ccda3..ba28ef02e265f0 100644 Binary files a/Lib/ensurepip/_bundled/pip-23.1.2-py3-none-any.whl and b/Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl differ diff --git a/Lib/enum.py b/Lib/enum.py index 0c985b2c778569..f5448a1788e4d2 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1,8 +1,6 @@ import sys import builtins as bltns from types import MappingProxyType, DynamicClassAttribute -from operator import or_ as _or_ -from functools import reduce __all__ = [ @@ -730,6 +728,11 @@ def __call__(cls, value, names=None, *values, module=None, qualname=None, type=N value = (value, names) + values return cls.__new__(cls, value) # otherwise, functional API: we're creating a new Enum type + if names is None and type is None: + # no body? no data-type? possibly wrong usage + raise TypeError( + f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum" + ) return cls._create_( class_name=value, names=names, @@ -856,6 +859,8 @@ def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, s value = first_enum._generate_next_value_(name, start, count, last_values[:]) last_values.append(value) names.append((name, value)) + if names is None: + names = () # Here, names is either an iterable of (name, value) or a mapping. for item in names: @@ -1112,6 +1117,11 @@ def __new__(cls, value): for member in cls._member_map_.values(): if member._value_ == value: return member + # still not found -- verify that members exist, in-case somebody got here mistakenly + # (such as via super when trying to override __new__) + if not cls._member_map_: + raise TypeError("%r has no members defined" % cls) + # # still not found -- try _missing_ hook try: exc = None @@ -1872,7 +1882,8 @@ def __call__(self, enumeration): missed = [v for v in values if v not in member_values] if missed: missing_names.append(name) - missing_value |= reduce(_or_, missed) + for val in missed: + missing_value |= val if missing_names: if len(missing_names) == 1: alias = 'alias %s is missing' % missing_names[0] diff --git a/Lib/functools.py b/Lib/functools.py index 8518450a8d499d..55990e742bf23f 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -19,8 +19,9 @@ # import types, weakref # Deferred to single_dispatch() from reprlib import recursive_repr from _thread import RLock -from types import GenericAlias +# Avoid importing types, so we can speedup import time +GenericAlias = type(list[int]) ################################################################################ ### update_wrapper() and wraps() decorator @@ -236,7 +237,7 @@ def __ge__(self, other): def reduce(function, sequence, initial=_initial_missing): """ - reduce(function, iterable[, initial]) -> value + reduce(function, iterable[, initial], /) -> value Apply a function of two arguments cumulatively to the items of a sequence or iterable, from left to right, so as to reduce the iterable to a single @@ -934,6 +935,9 @@ def __init__(self, func): self.dispatcher = singledispatch(func) self.func = func + import weakref # see comment in singledispatch function + self._method_cache = weakref.WeakKeyDictionary() + def register(self, cls, method=None): """generic_method.register(cls, func) -> func @@ -942,13 +946,27 @@ def register(self, cls, method=None): return self.dispatcher.register(cls, func=method) def __get__(self, obj, cls=None): + if self._method_cache is not None: + try: + _method = self._method_cache[obj] + except TypeError: + self._method_cache = None + except KeyError: + pass + else: + return _method + + dispatch = self.dispatcher.dispatch def _method(*args, **kwargs): - method = self.dispatcher.dispatch(args[0].__class__) - return method.__get__(obj, cls)(*args, **kwargs) + return dispatch(args[0].__class__).__get__(obj, cls)(*args, **kwargs) _method.__isabstractmethod__ = self.__isabstractmethod__ _method.register = self.register update_wrapper(_method, self.func) + + if self._method_cache is not None: + self._method_cache[obj] = _method + return _method @property @@ -967,6 +985,7 @@ def __init__(self, func): self.func = func self.attrname = None self.__doc__ = func.__doc__ + self.__module__ = func.__module__ def __set_name__(self, owner, name): if self.attrname is None: diff --git a/Lib/getpass.py b/Lib/getpass.py index 6970d8adfbab36..8b42c0a536b4c4 100644 --- a/Lib/getpass.py +++ b/Lib/getpass.py @@ -18,7 +18,6 @@ import io import os import sys -import warnings __all__ = ["getpass","getuser","GetPassWarning"] @@ -118,6 +117,7 @@ def win_getpass(prompt='Password: ', stream=None): def fallback_getpass(prompt='Password: ', stream=None): + import warnings warnings.warn("Can not control echo on the terminal.", GetPassWarning, stacklevel=2) if not stream: diff --git a/Lib/gettext.py b/Lib/gettext.py index 6c5ec4e517f637..e84765bfdf0649 100644 --- a/Lib/gettext.py +++ b/Lib/gettext.py @@ -46,6 +46,7 @@ # find this format documented anywhere. +import operator import os import re import sys @@ -166,14 +167,21 @@ def _parse(tokens, priority=-1): def _as_int(n): try: - i = round(n) + round(n) except TypeError: raise TypeError('Plural value must be an integer, got %s' % (n.__class__.__name__,)) from None + import warnings + frame = sys._getframe(1) + stacklevel = 2 + while frame.f_back is not None and frame.f_globals.get('__name__') == __name__: + stacklevel += 1 + frame = frame.f_back warnings.warn('Plural value must be an integer, got %s' % (n.__class__.__name__,), - DeprecationWarning, 4) + DeprecationWarning, + stacklevel) return n @@ -200,7 +208,7 @@ def c2py(plural): elif c == ')': depth -= 1 - ns = {'_as_int': _as_int} + ns = {'_as_int': _as_int, '__name__': __name__} exec('''if True: def func(n): if not isinstance(n, int): @@ -422,10 +430,12 @@ def gettext(self, message): missing = object() tmsg = self._catalog.get(message, missing) if tmsg is missing: - if self._fallback: - return self._fallback.gettext(message) - return message - return tmsg + tmsg = self._catalog.get((message, self.plural(1)), missing) + if tmsg is not missing: + return tmsg + if self._fallback: + return self._fallback.gettext(message) + return message def ngettext(self, msgid1, msgid2, n): try: @@ -444,10 +454,12 @@ def pgettext(self, context, message): missing = object() tmsg = self._catalog.get(ctxt_msg_id, missing) if tmsg is missing: - if self._fallback: - return self._fallback.pgettext(context, message) - return message - return tmsg + tmsg = self._catalog.get((ctxt_msg_id, self.plural(1)), missing) + if tmsg is not missing: + return tmsg + if self._fallback: + return self._fallback.pgettext(context, message) + return message def npgettext(self, context, msgid1, msgid2, n): ctxt_msg_id = self.CONTEXT % (context, msgid1) diff --git a/Lib/gzip.py b/Lib/gzip.py index cf8b675064ce89..177f9080dc5af8 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -401,6 +401,9 @@ def seekable(self): def seek(self, offset, whence=io.SEEK_SET): if self.mode == WRITE: + self._check_not_closed() + # Flush buffer to ensure validity of self.offset + self._buffer.flush() if whence != io.SEEK_SET: if whence == io.SEEK_CUR: offset = self.offset + offset diff --git a/Lib/http/server.py b/Lib/http/server.py index ca6240d9a921e6..ee7a9b6aa55b88 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -2,18 +2,18 @@ Note: BaseHTTPRequestHandler doesn't implement any HTTP request; see SimpleHTTPRequestHandler for simple implementations of GET, HEAD and POST, -and CGIHTTPRequestHandler for CGI scripts. +and (deprecated) CGIHTTPRequestHandler for CGI scripts. -It does, however, optionally implement HTTP/1.1 persistent connections, -as of version 0.3. +It does, however, optionally implement HTTP/1.1 persistent connections. Notes on CGIHTTPRequestHandler ------------------------------ -This class implements GET and POST requests to cgi-bin scripts. +This class is deprecated. It implements GET and POST requests to cgi-bin scripts. -If the os.fork() function is not present (e.g. on Windows), -subprocess.Popen() is used as a fallback, with slightly altered semantics. +If the os.fork() function is not present (Windows), subprocess.Popen() is used, +with slightly altered but never documented semantics. Use from a threaded +process is likely to trigger a warning at os.fork() time. In all cases, the implementation is intentionally naive -- all requests are executed synchronously. @@ -986,6 +986,12 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler): """ + def __init__(self, *args, **kwargs): + import warnings + warnings._deprecated("http.server.CGIHTTPRequestHandler", + remove=(3, 15)) + super().__init__(*args, **kwargs) + # Determine platform specifics have_fork = hasattr(os, 'fork') diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index c48fd506a0e4eb..ec2e56f6ea9ca1 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -51,18 +51,106 @@ def _new_module(name): # Module-level locking ######################################################## -# A dict mapping module names to weakrefs of _ModuleLock instances -# Dictionary protected by the global import lock +# For a list that can have a weakref to it. +class _List(list): + pass + + +# Copied from weakref.py with some simplifications and modifications unique to +# bootstrapping importlib. Many methods were simply deleting for simplicity, so if they +# are needed in the future they may work if simply copied back in. +class _WeakValueDictionary: + + def __init__(self): + self_weakref = _weakref.ref(self) + + # Inlined to avoid issues with inheriting from _weakref.ref before _weakref is + # set by _setup(). Since there's only one instance of this class, this is + # not expensive. + class KeyedRef(_weakref.ref): + + __slots__ = "key", + + def __new__(type, ob, key): + self = super().__new__(type, ob, type.remove) + self.key = key + return self + + def __init__(self, ob, key): + super().__init__(ob, self.remove) + + @staticmethod + def remove(wr): + nonlocal self_weakref + + self = self_weakref() + if self is not None: + if self._iterating: + self._pending_removals.append(wr.key) + else: + _weakref._remove_dead_weakref(self.data, wr.key) + + self._KeyedRef = KeyedRef + self.clear() + + def clear(self): + self._pending_removals = [] + self._iterating = set() + self.data = {} + + def _commit_removals(self): + pop = self._pending_removals.pop + d = self.data + while True: + try: + key = pop() + except IndexError: + return + _weakref._remove_dead_weakref(d, key) + + def get(self, key, default=None): + if self._pending_removals: + self._commit_removals() + try: + wr = self.data[key] + except KeyError: + return default + else: + if (o := wr()) is None: + return default + else: + return o + + def setdefault(self, key, default=None): + try: + o = self.data[key]() + except KeyError: + o = None + if o is None: + if self._pending_removals: + self._commit_removals() + self.data[key] = self._KeyedRef(default, key) + return default + else: + return o + + +# A dict mapping module names to weakrefs of _ModuleLock instances. +# Dictionary protected by the global import lock. _module_locks = {} -# A dict mapping thread IDs to lists of _ModuleLock instances. This maps a -# thread to the module locks it is blocking on acquiring. The values are -# lists because a single thread could perform a re-entrant import and be "in -# the process" of blocking on locks for more than one module. A thread can -# be "in the process" because a thread cannot actually block on acquiring -# more than one lock but it can have set up bookkeeping that reflects that -# it intends to block on acquiring more than one lock. -_blocking_on = {} +# A dict mapping thread IDs to weakref'ed lists of _ModuleLock instances. +# This maps a thread to the module locks it is blocking on acquiring. The +# values are lists because a single thread could perform a re-entrant import +# and be "in the process" of blocking on locks for more than one module. A +# thread can be "in the process" because a thread cannot actually block on +# acquiring more than one lock but it can have set up bookkeeping that reflects +# that it intends to block on acquiring more than one lock. +# +# The dictionary uses a WeakValueDictionary to avoid keeping unnecessary +# lists around, regardless of GC runs. This way there's no memory leak if +# the list is no longer needed (GH-106176). +_blocking_on = None class _BlockingOnManager: @@ -79,7 +167,7 @@ def __enter__(self): # re-entrant (i.e., a single thread may take it more than once) so it # wouldn't help us be correct in the face of re-entrancy either. - self.blocked_on = _blocking_on.setdefault(self.thread_id, []) + self.blocked_on = _blocking_on.setdefault(self.thread_id, _List()) self.blocked_on.append(self.lock) def __exit__(self, *args, **kwargs): @@ -1409,7 +1497,7 @@ def _setup(sys_module, _imp_module): modules, those two modules must be explicitly passed in. """ - global _imp, sys + global _imp, sys, _blocking_on _imp = _imp_module sys = sys_module @@ -1437,6 +1525,9 @@ def _setup(sys_module, _imp_module): builtin_module = sys.modules[builtin_name] setattr(self_module, builtin_name, builtin_module) + # Instantiation requires _weakref to have been set. + _blocking_on = _WeakValueDictionary() + def _install(sys_module, _imp_module): """Install importers for builtin and frozen modules""" diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 16a82bef2ba71f..0019897c943e14 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -453,6 +453,12 @@ def _write_atomic(path, data, mode=0o666): # Python 3.13a1 3555 (generate specialized opcodes metadata from bytecodes.c) # Python 3.13a1 3556 (Convert LOAD_CLOSURE to a pseudo-op) # Python 3.13a1 3557 (Make the conversion to boolean in jumps explicit) +# Python 3.13a1 3558 (Reorder the stack items for CALL) +# Python 3.13a1 3559 (Generate opcode IDs from bytecodes.c) +# Python 3.13a1 3560 (Add RESUME_CHECK instruction) +# Python 3.13a1 3561 (Add cache entry to branch instructions) +# Python 3.13a1 3562 (Assign opcode IDs for internal ops in separate range) +# Python 3.13a1 3563 (Add CALL_KW and remove KW_NAMES) # Python 3.14 will start with 3600 @@ -469,7 +475,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3557).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3563).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c diff --git a/Lib/inspect.py b/Lib/inspect.py index 675714dc8b3f70..aaa22bef896602 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1078,7 +1078,8 @@ def get_lineno(self): # First, let's see if there are any method definitions for member in self.cls.__dict__.values(): - if isinstance(member, types.FunctionType): + if (isinstance(member, types.FunctionType) and + member.__module__ == self.cls.__module__): for lineno, end_lineno in self.lineno_found: if lineno <= member.__code__.co_firstlineno <= end_lineno: return lineno @@ -2869,6 +2870,8 @@ def __str__(self): return formatted + __replace__ = replace + def __repr__(self): return '<{} "{}">'.format(self.__class__.__name__, self) @@ -3129,6 +3132,8 @@ def replace(self, *, parameters=_void, return_annotation=_void): return type(self)(parameters, return_annotation=return_annotation) + __replace__ = replace + def _hash_basis(self): params = tuple(param for param in self.parameters.values() if param.kind != _KEYWORD_ONLY) diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index af1d5c4800cce8..f5aba434fd4253 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1923,8 +1923,40 @@ def __init__(self, address): self._ip = self._ip_int_from_string(addr_str) + def _explode_shorthand_ip_string(self): + ipv4_mapped = self.ipv4_mapped + if ipv4_mapped is None: + long_form = super()._explode_shorthand_ip_string() + else: + prefix_len = 30 + raw_exploded_str = super()._explode_shorthand_ip_string() + long_form = "%s%s" % (raw_exploded_str[:prefix_len], str(ipv4_mapped)) + return long_form + + def _ipv4_mapped_ipv6_to_str(self): + """Return convenient text representation of IPv4-mapped IPv6 address + + See RFC 4291 2.5.5.2, 2.2 p.3 for details. + + Returns: + A string, 'x:x:x:x:x:x:d.d.d.d', where the 'x's are the hexadecimal values of + the six high-order 16-bit pieces of the address, and the 'd's are + the decimal values of the four low-order 8-bit pieces of the + address (standard IPv4 representation) as defined in RFC 4291 2.2 p.3. + + """ + ipv4_mapped = self.ipv4_mapped + if ipv4_mapped is None: + raise AddressValueError("Can not apply to non-IPv4-mapped IPv6 address %s" % str(self)) + high_order_bits = self._ip >> 32 + return "%s:%s" % (self._string_from_ip_int(high_order_bits), str(ipv4_mapped)) + def __str__(self): - ip_str = super().__str__() + ipv4_mapped = self.ipv4_mapped + if ipv4_mapped is None: + ip_str = super().__str__() + else: + ip_str = self._ipv4_mapped_ipv6_to_str() return ip_str + '%' + self._scope_id if self._scope_id else ip_str def __hash__(self): diff --git a/Lib/linecache.py b/Lib/linecache.py index 97644a8e3794e1..c1c988d9df436c 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -180,3 +180,10 @@ def lazycache(filename, module_globals): cache[filename] = (get_lines,) return True return False + +def _register_code(code, string, name): + cache[code] = ( + len(string), + None, + [line + '\n' for line in string.splitlines()], + name) diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 46e86cb87ecfcb..eb7e020d1edfc0 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -159,12 +159,9 @@ def addLevelName(level, levelName): This is used when converting levels to text during message formatting. """ - _acquireLock() - try: #unlikely to cause an exception, but you never know... + with _lock: _levelToName[level] = levelName _nameToLevel[levelName] = level - finally: - _releaseLock() if hasattr(sys, "_getframe"): currentframe = lambda: sys._getframe(1) @@ -231,25 +228,27 @@ def _checkLevel(level): # _lock = threading.RLock() -def _acquireLock(): +def _prepareFork(): """ - Acquire the module-level lock for serializing access to shared data. + Prepare to fork a new child process by acquiring the module-level lock. - This should be released with _releaseLock(). + This should be used in conjunction with _afterFork(). """ - if _lock: - try: - _lock.acquire() - except BaseException: - _lock.release() - raise + # Wrap the lock acquisition in a try-except to prevent the lock from being + # abandoned in the event of an asynchronous exception. See gh-106238. + try: + _lock.acquire() + except BaseException: + _lock.release() + raise -def _releaseLock(): +def _afterFork(): """ - Release the module-level lock acquired by calling _acquireLock(). + After a new child process has been forked, release the module-level lock. + + This should be used in conjunction with _prepareFork(). """ - if _lock: - _lock.release() + _lock.release() # Prevent a held logging lock from blocking a child from logging. @@ -264,23 +263,20 @@ def _register_at_fork_reinit_lock(instance): _at_fork_reinit_lock_weakset = weakref.WeakSet() def _register_at_fork_reinit_lock(instance): - _acquireLock() - try: + with _lock: _at_fork_reinit_lock_weakset.add(instance) - finally: - _releaseLock() def _after_at_fork_child_reinit_locks(): for handler in _at_fork_reinit_lock_weakset: handler._at_fork_reinit() - # _acquireLock() was called in the parent before forking. + # _prepareFork() was called in the parent before forking. # The lock is reinitialized to unlocked state. _lock._at_fork_reinit() - os.register_at_fork(before=_acquireLock, + os.register_at_fork(before=_prepareFork, after_in_child=_after_at_fork_child_reinit_locks, - after_in_parent=_releaseLock) + after_in_parent=_afterFork) #--------------------------------------------------------------------------- @@ -883,25 +879,20 @@ def _removeHandlerRef(wr): # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. - acquire, release, handlers = _acquireLock, _releaseLock, _handlerList - if acquire and release and handlers: - acquire() - try: - handlers.remove(wr) - except ValueError: - pass - finally: - release() + handlers, lock = _handlerList, _lock + if lock and handlers: + with lock: + try: + handlers.remove(wr) + except ValueError: + pass def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ - _acquireLock() - try: + with _lock: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) - finally: - _releaseLock() def getHandlerByName(name): @@ -916,8 +907,7 @@ def getHandlerNames(): """ Return all known handler names as an immutable set. """ - result = set(_handlers.keys()) - return frozenset(result) + return frozenset(_handlers) class Handler(Filterer): @@ -947,15 +937,12 @@ def get_name(self): return self._name def set_name(self, name): - _acquireLock() - try: + with _lock: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self - finally: - _releaseLock() name = property(get_name, set_name) @@ -1027,11 +1014,8 @@ def handle(self, record): if isinstance(rv, LogRecord): record = rv if rv: - self.acquire() - try: + with self.lock: self.emit(record) - finally: - self.release() return rv def setFormatter(self, fmt): @@ -1059,13 +1043,10 @@ def close(self): methods. """ #get the module data lock, as we're updating a shared structure. - _acquireLock() - try: #unlikely to raise an exception, but you never know... + with _lock: self._closed = True if self._name and self._name in _handlers: del _handlers[self._name] - finally: - _releaseLock() def handleError(self, record): """ @@ -1142,12 +1123,9 @@ def flush(self): """ Flushes the stream. """ - self.acquire() - try: + with self.lock: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() - finally: - self.release() def emit(self, record): """ @@ -1183,12 +1161,9 @@ def setStream(self, stream): result = None else: result = self.stream - self.acquire() - try: + with self.lock: self.flush() self.stream = stream - finally: - self.release() return result def __repr__(self): @@ -1238,8 +1213,7 @@ def close(self): """ Closes the stream. """ - self.acquire() - try: + with self.lock: try: if self.stream: try: @@ -1255,8 +1229,6 @@ def close(self): # Also see Issue #42378: we also rely on # self._closed being set to True there StreamHandler.close(self) - finally: - self.release() def _open(self): """ @@ -1392,8 +1364,7 @@ def getLogger(self, name): rv = None if not isinstance(name, str): raise TypeError('A logger name must be a string') - _acquireLock() - try: + with _lock: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): @@ -1408,8 +1379,6 @@ def getLogger(self, name): rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) - finally: - _releaseLock() return rv def setLoggerClass(self, klass): @@ -1472,12 +1441,11 @@ def _clear_cache(self): Called when level changes are made """ - _acquireLock() - for logger in self.loggerDict.values(): - if isinstance(logger, Logger): - logger._cache.clear() - self.root._cache.clear() - _releaseLock() + with _lock: + for logger in self.loggerDict.values(): + if isinstance(logger, Logger): + logger._cache.clear() + self.root._cache.clear() #--------------------------------------------------------------------------- # Logger classes and functions @@ -1702,23 +1670,17 @@ def addHandler(self, hdlr): """ Add the specified handler to this logger. """ - _acquireLock() - try: + with _lock: if not (hdlr in self.handlers): self.handlers.append(hdlr) - finally: - _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ - _acquireLock() - try: + with _lock: if hdlr in self.handlers: self.handlers.remove(hdlr) - finally: - _releaseLock() def hasHandlers(self): """ @@ -1796,16 +1758,13 @@ def isEnabledFor(self, level): try: return self._cache[level] except KeyError: - _acquireLock() - try: + with _lock: if self.manager.disable >= level: is_enabled = self._cache[level] = False else: is_enabled = self._cache[level] = ( level >= self.getEffectiveLevel() ) - finally: - _releaseLock() return is_enabled def getChild(self, suffix): @@ -1835,16 +1794,13 @@ def _hierlevel(logger): return 1 + logger.name.count('.') d = self.manager.loggerDict - _acquireLock() - try: + with _lock: # exclude PlaceHolders - the last check is to ensure that lower-level # descendants aren't returned - if there are placeholders, a logger's # parent field might point to a grandparent or ancestor thereof. return set(item for item in d.values() if isinstance(item, Logger) and item.parent is self and _hierlevel(item) == 1 + _hierlevel(item.parent)) - finally: - _releaseLock() def __repr__(self): level = getLevelName(self.getEffectiveLevel()) @@ -1880,7 +1836,7 @@ class LoggerAdapter(object): information in logging output. """ - def __init__(self, logger, extra=None): + def __init__(self, logger, extra=None, merge_extra=False): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows @@ -1890,9 +1846,20 @@ def __init__(self, logger, extra=None): following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) + + By default, LoggerAdapter objects will drop the "extra" argument + passed on the individual log calls to use its own instead. + + Initializing it with merge_extra=True will instead merge both + maps when logging, the individual call extra taking precedence + over the LoggerAdapter instance extra + + .. versionchanged:: 3.13 + The *merge_extra* argument was added. """ self.logger = logger self.extra = extra + self.merge_extra = merge_extra def process(self, msg, kwargs): """ @@ -1904,7 +1871,10 @@ def process(self, msg, kwargs): Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ - kwargs["extra"] = self.extra + if self.merge_extra and "extra" in kwargs: + kwargs["extra"] = {**self.extra, **kwargs["extra"]} + else: + kwargs["extra"] = self.extra return msg, kwargs # @@ -2089,8 +2059,7 @@ def basicConfig(**kwargs): """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads - _acquireLock() - try: + with _lock: force = kwargs.pop('force', False) encoding = kwargs.pop('encoding', None) errors = kwargs.pop('errors', 'backslashreplace') @@ -2139,8 +2108,6 @@ def basicConfig(**kwargs): if kwargs: keys = ', '.join(kwargs.keys()) raise ValueError('Unrecognised argument(s): %s' % keys) - finally: - _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. diff --git a/Lib/logging/config.py b/Lib/logging/config.py index a68281d3e359fd..951bba73913cb3 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -83,15 +83,12 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=Non formatters = _create_formatters(cp) # critical section - logging._acquireLock() - try: + with logging._lock: _clearExistingHandlers() # Handlers add themselves to logging._handlers handlers = _install_handlers(cp, formatters) _install_loggers(cp, handlers, disable_existing_loggers) - finally: - logging._releaseLock() def _resolve(name): @@ -378,7 +375,7 @@ class BaseConfigurator(object): WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') - INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + INDEX_PATTERN = re.compile(r'^\[([^\[\]]*)\]\s*') DIGIT_PATTERN = re.compile(r'^\d+$') value_converters = { @@ -516,8 +513,7 @@ def configure(self): raise ValueError("Unsupported version: %s" % config['version']) incremental = config.pop('incremental', False) EMPTY_DICT = {} - logging._acquireLock() - try: + with logging._lock: if incremental: handlers = config.get('handlers', EMPTY_DICT) for name in handlers: @@ -661,8 +657,6 @@ def configure(self): except Exception as e: raise ValueError('Unable to configure root ' 'logger') from e - finally: - logging._releaseLock() def configure_formatter(self, config): """Configure a formatter from a dictionary.""" @@ -988,9 +982,8 @@ class ConfigSocketReceiver(ThreadingTCPServer): def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT, handler=None, ready=None, verify=None): ThreadingTCPServer.__init__(self, (host, port), handler) - logging._acquireLock() - self.abort = 0 - logging._releaseLock() + with logging._lock: + self.abort = 0 self.timeout = 1 self.ready = ready self.verify = verify @@ -1004,9 +997,8 @@ def serve_until_stopped(self): self.timeout) if rd: self.handle_request() - logging._acquireLock() - abort = self.abort - logging._releaseLock() + with logging._lock: + abort = self.abort self.server_close() class Server(threading.Thread): @@ -1027,9 +1019,8 @@ def run(self): self.port = server.server_address[1] self.ready.set() global _listener - logging._acquireLock() - _listener = server - logging._releaseLock() + with logging._lock: + _listener = server server.serve_until_stopped() return Server(ConfigSocketReceiver, ConfigStreamHandler, port, verify) @@ -1039,10 +1030,7 @@ def stopListening(): Stop the listening server which was created with a call to listen(). """ global _listener - logging._acquireLock() - try: + with logging._lock: if _listener: _listener.abort = 1 _listener = None - finally: - logging._releaseLock() diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 9847104446eaf6..e75da9b7b1de64 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -683,15 +683,12 @@ def close(self): """ Closes the socket. """ - self.acquire() - try: + with self.lock: sock = self.sock if sock: self.sock = None sock.close() logging.Handler.close(self) - finally: - self.release() class DatagramHandler(SocketHandler): """ @@ -953,15 +950,12 @@ def close(self): """ Closes the socket. """ - self.acquire() - try: + with self.lock: sock = self.socket if sock: self.socket = None sock.close() logging.Handler.close(self) - finally: - self.release() def mapPriority(self, levelName): """ @@ -1333,11 +1327,8 @@ def flush(self): This version just zaps the buffer to empty. """ - self.acquire() - try: + with self.lock: self.buffer.clear() - finally: - self.release() def close(self): """ @@ -1387,11 +1378,8 @@ def setTarget(self, target): """ Set the target handler for this handler. """ - self.acquire() - try: + with self.lock: self.target = target - finally: - self.release() def flush(self): """ @@ -1399,16 +1387,13 @@ def flush(self): records to the target, if there is one. Override if you want different behaviour. - The record buffer is also cleared by this operation. + The record buffer is only cleared if a target has been set. """ - self.acquire() - try: + with self.lock: if self.target: for record in self.buffer: self.target.handle(record) self.buffer.clear() - finally: - self.release() def close(self): """ @@ -1419,12 +1404,9 @@ def close(self): if self.flushOnClose: self.flush() finally: - self.acquire() - try: + with self.lock: self.target = None BufferingHandler.close(self) - finally: - self.release() class QueueHandler(logging.Handler): diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 04eaea811cfbbe..dbbf106f680964 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -9,6 +9,7 @@ __all__ = [ 'Client', 'Listener', 'Pipe', 'wait' ] +import errno import io import os import sys @@ -271,12 +272,22 @@ class PipeConnection(_ConnectionBase): with FILE_FLAG_OVERLAPPED. """ _got_empty_message = False + _send_ov = None def _close(self, _CloseHandle=_winapi.CloseHandle): + ov = self._send_ov + if ov is not None: + # Interrupt WaitForMultipleObjects() in _send_bytes() + ov.cancel() _CloseHandle(self._handle) def _send_bytes(self, buf): + if self._send_ov is not None: + # A connection should only be used by a single thread + raise ValueError("concurrent send_bytes() calls " + "are not supported") ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True) + self._send_ov = ov try: if err == _winapi.ERROR_IO_PENDING: waitres = _winapi.WaitForMultipleObjects( @@ -286,7 +297,13 @@ def _send_bytes(self, buf): ov.cancel() raise finally: + self._send_ov = None nwritten, err = ov.GetOverlappedResult(True) + if err == _winapi.ERROR_OPERATION_ABORTED: + # close() was called by another thread while + # WaitForMultipleObjects() was waiting for the overlapped + # operation. + raise OSError(errno.EPIPE, "handle is closed") assert err == 0 assert nwritten == len(buf) diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py index 22a911a7a29cdc..4642707dae2f4e 100644 --- a/Lib/multiprocessing/forkserver.py +++ b/Lib/multiprocessing/forkserver.py @@ -61,7 +61,7 @@ def _stop_unlocked(self): def set_forkserver_preload(self, modules_names): '''Set list of module names to try to load in forkserver process.''' - if not all(type(mod) is str for mod in self._preload_modules): + if not all(type(mod) is str for mod in modules_names): raise TypeError('module_names must be a list of strings') self._preload_modules = modules_names diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index b6534939b4d98b..273c22a7654f05 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -90,7 +90,10 @@ def dispatch(c, id, methodname, args=(), kwds={}): kind, result = c.recv() if kind == '#RETURN': return result - raise convert_to_error(kind, result) + try: + raise convert_to_error(kind, result) + finally: + del result # break reference cycle def convert_to_error(kind, result): if kind == '#ERROR': @@ -833,7 +836,10 @@ def _callmethod(self, methodname, args=(), kwds={}): conn = self._Client(token.address, authkey=self._authkey) dispatch(conn, None, 'decref', (token.id,)) return proxy - raise convert_to_error(kind, result) + try: + raise convert_to_error(kind, result) + finally: + del result # break reference cycle def _getvalue(self): ''' diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 4f5d88cb975cb7..f979890170b1a1 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -200,7 +200,7 @@ def __init__(self, processes=None, initializer=None, initargs=(), self._initargs = initargs if processes is None: - processes = os.cpu_count() or 1 + processes = os.process_cpu_count() or 1 if processes < 1: raise ValueError("Number of processes must be at least 1") if maxtasksperchild is not None: diff --git a/Lib/multiprocessing/popen_spawn_win32.py b/Lib/multiprocessing/popen_spawn_win32.py index 4d60ffc030bea6..af044305709e56 100644 --- a/Lib/multiprocessing/popen_spawn_win32.py +++ b/Lib/multiprocessing/popen_spawn_win32.py @@ -14,6 +14,7 @@ # # +# Exit code used by Popen.terminate() TERMINATE = 0x10000 WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False)) WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") @@ -122,9 +123,15 @@ def terminate(self): if self.returncode is None: try: _winapi.TerminateProcess(int(self._handle), TERMINATE) - except OSError: - if self.wait(timeout=1.0) is None: + except PermissionError: + # ERROR_ACCESS_DENIED (winerror 5) is received when the + # process already died. + code = _winapi.GetExitCodeProcess(int(self._handle)) + if code == _winapi.STILL_ACTIVE: raise + self.returncode = code + else: + self.returncode = -signal.SIGTERM kill = terminate diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index daf9ee94a19431..852ae87b276861 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -158,6 +158,20 @@ def cancel_join_thread(self): except AttributeError: pass + def _terminate_broken(self): + # Close a Queue on error. + + # gh-94777: Prevent queue writing to a pipe which is no longer read. + self._reader.close() + + # gh-107219: Close the connection writer which can unblock + # Queue._feed() if it was stuck in send_bytes(). + if sys.platform == 'win32': + self._writer.close() + + self.close() + self.join_thread() + def _start_thread(self): debug('Queue._start_thread()') @@ -169,13 +183,19 @@ def _start_thread(self): self._wlock, self._reader.close, self._writer.close, self._ignore_epipe, self._on_queue_feeder_error, self._sem), - name='QueueFeederThread' + name='QueueFeederThread', + daemon=True, ) - self._thread.daemon = True - debug('doing self._thread.start()') - self._thread.start() - debug('... done self._thread.start()') + try: + debug('doing self._thread.start()') + self._thread.start() + debug('... done self._thread.start()') + except: + # gh-109047: During Python finalization, creating a thread + # can fail with RuntimeError. + self._thread = None + raise if not self._joincancelled: self._jointhread = Finalize( diff --git a/Lib/multiprocessing/resource_tracker.py b/Lib/multiprocessing/resource_tracker.py index ea369507297f86..8e41f461cc934e 100644 --- a/Lib/multiprocessing/resource_tracker.py +++ b/Lib/multiprocessing/resource_tracker.py @@ -51,15 +51,31 @@ }) +class ReentrantCallError(RuntimeError): + pass + + class ResourceTracker(object): def __init__(self): - self._lock = threading.Lock() + self._lock = threading.RLock() self._fd = None self._pid = None + def _reentrant_call_error(self): + # gh-109629: this happens if an explicit call to the ResourceTracker + # gets interrupted by a garbage collection, invoking a finalizer (*) + # that itself calls back into ResourceTracker. + # (*) for example the SemLock finalizer + raise ReentrantCallError( + "Reentrant call into the multiprocessing resource tracker") + def _stop(self): with self._lock: + # This should not happen (_stop() isn't called by a finalizer) + # but we check for it anyway. + if self._lock._recursion_count() > 1: + return self._reentrant_call_error() if self._fd is None: # not running return @@ -81,6 +97,9 @@ def ensure_running(self): This can be run from any process. Usually a child process will use the resource created by its parent.''' with self._lock: + if self._lock._recursion_count() > 1: + # The code below is certainly not reentrant-safe, so bail out + return self._reentrant_call_error() if self._fd is not None: # resource tracker was launched before, is it still running? if self._check_alive(): @@ -159,7 +178,17 @@ def unregister(self, name, rtype): self._send('UNREGISTER', name, rtype) def _send(self, cmd, name, rtype): - self.ensure_running() + try: + self.ensure_running() + except ReentrantCallError: + # The code below might or might not work, depending on whether + # the resource tracker was already running and still alive. + # Better warn the user. + # (XXX is warnings.warn itself reentrant-safe? :-) + warnings.warn( + f"ResourceTracker called reentrantly for resource cleanup, " + f"which is unsupported. " + f"The {rtype} object {name!r} might leak.") msg = '{0}:{1}:{2}\n'.format(cmd, name, rtype).encode('ascii') if len(msg) > 512: # posix guarantees that writes to a pipe of less than PIPE_BUF @@ -176,6 +205,7 @@ def _send(self, cmd, name, rtype): unregister = _resource_tracker.unregister getfd = _resource_tracker.getfd + def main(fd): '''Run resource tracker.''' # protect the process from ^C and "killall python" etc @@ -221,9 +251,10 @@ def main(fd): for rtype, rtype_cache in cache.items(): if rtype_cache: try: - warnings.warn('resource_tracker: There appear to be %d ' - 'leaked %s objects to clean up at shutdown' % - (len(rtype_cache), rtype)) + warnings.warn( + f'resource_tracker: There appear to be {len(rtype_cache)} ' + f'leaked {rtype} objects to clean up at shutdown: {rtype_cache}' + ) except Exception: pass for name in rtype_cache: diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index f1af7709104714..daac1ecc34b55e 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -150,7 +150,11 @@ def _check_not_importing_main(): ... The "freeze_support()" line can be omitted if the program - is not going to be frozen to produce an executable.''') + is not going to be frozen to produce an executable. + + To fix this issue, refer to the "Safe importing of main module" + section in https://docs.python.org/3/library/multiprocessing.html + ''') def get_preparation_data(name): diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index 42624b543601a1..3ccbfe311c71f3 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -50,8 +50,8 @@ class SemLock(object): def __init__(self, kind, value, maxvalue, *, ctx): if ctx is None: ctx = context._default_context.get_context() - name = ctx.get_start_method() - unlink_now = sys.platform == 'win32' or name == 'fork' + self._is_fork_ctx = ctx.get_start_method() == 'fork' + unlink_now = sys.platform == 'win32' or self._is_fork_ctx for i in range(100): try: sl = self._semlock = _multiprocessing.SemLock( @@ -103,6 +103,11 @@ def __getstate__(self): if sys.platform == 'win32': h = context.get_spawning_popen().duplicate_for_child(sl.handle) else: + if self._is_fork_ctx: + raise RuntimeError('A SemLock created in a fork context is being ' + 'shared with a process in a spawn context. This is ' + 'not supported. Please use the same context to create ' + 'multiprocessing objects and Process.') h = sl.handle return (h, sl.kind, sl.maxvalue, sl.name) @@ -110,6 +115,8 @@ def __setstate__(self, state): self._semlock = _multiprocessing.SemLock._rebuild(*state) util.debug('recreated blocker with handle %r' % state[0]) self._make_methods() + # Ensure that deserialized SemLock can be serialized again (gh-108520). + self._is_fork_ctx = False @staticmethod def _make_name(): diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index 6ee0d33e88a060..28c77df1c32ea8 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -64,8 +64,7 @@ def get_logger(): global _logger import logging - logging._acquireLock() - try: + with logging._lock: if not _logger: _logger = logging.getLogger(LOGGER_NAME) @@ -79,9 +78,6 @@ def get_logger(): atexit._exithandlers.remove((_exit_function, (), {})) atexit._exithandlers.append((_exit_function, (), {})) - finally: - logging._releaseLock() - return _logger def log_to_stderr(level=None): diff --git a/Lib/ntpath.py b/Lib/ntpath.py index dadcdc0c495da1..3061a4a5ef4c56 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -23,7 +23,6 @@ import genericpath from genericpath import * - __all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext", "basename","dirname","commonprefix","getsize","getmtime", "getatime","getctime", "islink","exists","lexists","isdir","isfile", @@ -601,7 +600,7 @@ def abspath(path): return _abspath_fallback(path) try: - from nt import _getfinalpathname, readlink as _nt_readlink + from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink except ImportError: # realpath is a no-op on systems without _getfinalpathname support. realpath = abspath @@ -688,10 +687,15 @@ def _getfinalpathname_nonstrict(path): except OSError: # If we fail to readlink(), let's keep traversing pass - path, name = split(path) - # TODO (bpo-38186): Request the real file name from the directory - # entry using FindFirstFileW. For now, we will return the path - # as best we have it + # If we get these errors, try to get the real name of the file without accessing it. + if ex.winerror in (1, 5, 32, 50, 87, 1920, 1921): + try: + name = _findfirstfile(path) + path, _ = split(path) + except OSError: + path, name = split(path) + else: + path, name = split(path) if path and not name: return path + tail tail = join(name, tail) if tail else name @@ -721,6 +725,14 @@ def realpath(path, *, strict=False): try: path = _getfinalpathname(path) initial_winerror = 0 + except ValueError as ex: + # gh-106242: Raised for embedded null characters + # In strict mode, we convert into an OSError. + # Non-strict mode returns the path as-is, since we've already + # made it absolute. + if strict: + raise OSError(str(ex)) from None + path = normpath(path) except OSError as ex: if strict: raise @@ -740,6 +752,10 @@ def realpath(path, *, strict=False): try: if _getfinalpathname(spath) == path: path = spath + except ValueError as ex: + # Unexpected, as an invalid path should not have gained a prefix + # at any point, but we ignore this error just in case. + pass except OSError as ex: # If the path does not exist and originally did not exist, then # strip the prefix anyway. diff --git a/Lib/opcode.py b/Lib/opcode.py index 08dfd2674dca78..88f4df7c0e8c38 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -5,312 +5,40 @@ """ -# Note that __all__ is further extended below -__all__ = ["cmp_op", "opname", "opmap", "stack_effect", "hascompare", - "HAVE_ARGUMENT", "EXTENDED_ARG"] +__all__ = ["cmp_op", "stack_effect", "hascompare", "opname", "opmap", + "HAVE_ARGUMENT", "EXTENDED_ARG", "hasarg", "hasconst", "hasname", + "hasjump", "hasjrel", "hasjabs", "hasfree", "haslocal", "hasexc"] import _opcode from _opcode import stack_effect -import sys -# The build uses older versions of Python which do not have _opcode_metadata -if sys.version_info[:2] >= (3, 13): - from _opcode_metadata import _specializations, _specialized_instructions - -cmp_op = ('<', '<=', '==', '!=', '>', '>=') - - -ENABLE_SPECIALIZATION = True - -def is_pseudo(op): - return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE - -opmap = {} - -# pseudo opcodes (used in the compiler) mapped to the values -# they can become in the actual code. -_pseudo_ops = {} - -def def_op(name, op): - opmap[name] = op - -def pseudo_op(name, op, real_ops): - def_op(name, op) - _pseudo_ops[name] = real_ops - - -# Instruction opcodes for compiled code -# Blank lines correspond to available opcodes - -def_op('CACHE', 0) -def_op('POP_TOP', 1) -def_op('PUSH_NULL', 2) -def_op('INTERPRETER_EXIT', 3) -def_op('END_FOR', 4) -def_op('END_SEND', 5) -def_op('TO_BOOL', 6) - -def_op('NOP', 9) - -def_op('UNARY_NEGATIVE', 11) -def_op('UNARY_NOT', 12) - -def_op('UNARY_INVERT', 15) -def_op('EXIT_INIT_CHECK', 16) - -# We reserve 17 as it is the initial value for the specializing counter -# This helps us catch cases where we attempt to execute a cache. -def_op('RESERVED', 17) - -def_op('MAKE_FUNCTION', 24) -def_op('BINARY_SUBSCR', 25) -def_op('BINARY_SLICE', 26) -def_op('STORE_SLICE', 27) - -def_op('GET_LEN', 30) -def_op('MATCH_MAPPING', 31) -def_op('MATCH_SEQUENCE', 32) -def_op('MATCH_KEYS', 33) - -def_op('PUSH_EXC_INFO', 35) -def_op('CHECK_EXC_MATCH', 36) -def_op('CHECK_EG_MATCH', 37) - -def_op('FORMAT_SIMPLE', 40) -def_op('FORMAT_WITH_SPEC', 41) - -def_op('WITH_EXCEPT_START', 49) -def_op('GET_AITER', 50) -def_op('GET_ANEXT', 51) -def_op('BEFORE_ASYNC_WITH', 52) -def_op('BEFORE_WITH', 53) -def_op('END_ASYNC_FOR', 54) -def_op('CLEANUP_THROW', 55) - -def_op('STORE_SUBSCR', 60) -def_op('DELETE_SUBSCR', 61) - -def_op('GET_ITER', 68) -def_op('GET_YIELD_FROM_ITER', 69) - -def_op('LOAD_BUILD_CLASS', 71) - -def_op('LOAD_ASSERTION_ERROR', 74) -def_op('RETURN_GENERATOR', 75) - -def_op('RETURN_VALUE', 83) - -def_op('SETUP_ANNOTATIONS', 85) - -def_op('LOAD_LOCALS', 87) - -def_op('POP_EXCEPT', 89) - -HAVE_ARGUMENT = 90 # real opcodes from here have an argument: - -def_op('STORE_NAME', 90) # Index in name list -def_op('DELETE_NAME', 91) # "" -def_op('UNPACK_SEQUENCE', 92) # Number of tuple items -def_op('FOR_ITER', 93) -def_op('UNPACK_EX', 94) -def_op('STORE_ATTR', 95) # Index in name list -def_op('DELETE_ATTR', 96) # "" -def_op('STORE_GLOBAL', 97) # "" -def_op('DELETE_GLOBAL', 98) # "" -def_op('SWAP', 99) -def_op('LOAD_CONST', 100) # Index in const list -def_op('LOAD_NAME', 101) # Index in name list -def_op('BUILD_TUPLE', 102) # Number of tuple items -def_op('BUILD_LIST', 103) # Number of list items -def_op('BUILD_SET', 104) # Number of set items -def_op('BUILD_MAP', 105) # Number of dict entries -def_op('LOAD_ATTR', 106) # Index in name list -def_op('COMPARE_OP', 107) # Comparison operator -def_op('IMPORT_NAME', 108) # Index in name list -def_op('IMPORT_FROM', 109) # Index in name list -def_op('JUMP_FORWARD', 110) # Number of words to skip - -def_op('POP_JUMP_IF_FALSE', 114) -def_op('POP_JUMP_IF_TRUE', 115) -def_op('LOAD_GLOBAL', 116) # Index in name list -def_op('IS_OP', 117) -def_op('CONTAINS_OP', 118) -def_op('RERAISE', 119) -def_op('COPY', 120) -def_op('RETURN_CONST', 121) -def_op('BINARY_OP', 122) -def_op('SEND', 123) # Number of words to skip -def_op('LOAD_FAST', 124) # Local variable number, no null check -def_op('STORE_FAST', 125) # Local variable number -def_op('DELETE_FAST', 126) # Local variable number -def_op('LOAD_FAST_CHECK', 127) # Local variable number -def_op('POP_JUMP_IF_NOT_NONE', 128) -def_op('POP_JUMP_IF_NONE', 129) -def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) -def_op('GET_AWAITABLE', 131) -def_op('BUILD_SLICE', 133) # Number of items -def_op('JUMP_BACKWARD_NO_INTERRUPT', 134) # Number of words to skip (backwards) -def_op('MAKE_CELL', 135) -def_op('LOAD_DEREF', 137) -def_op('STORE_DEREF', 138) -def_op('DELETE_DEREF', 139) -def_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards) -def_op('LOAD_SUPER_ATTR', 141) -def_op('CALL_FUNCTION_EX', 142) # Flags -def_op('LOAD_FAST_AND_CLEAR', 143) # Local variable number -def_op('EXTENDED_ARG', 144) +from _opcode_metadata import (_specializations, _specialized_opmap, opmap, + HAVE_ARGUMENT, MIN_INSTRUMENTED_OPCODE) EXTENDED_ARG = opmap['EXTENDED_ARG'] -def_op('LIST_APPEND', 145) -def_op('SET_ADD', 146) -def_op('MAP_ADD', 147) -def_op('COPY_FREE_VARS', 149) -def_op('YIELD_VALUE', 150) -def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py -def_op('MATCH_CLASS', 152) - -def_op('BUILD_CONST_KEY_MAP', 156) -def_op('BUILD_STRING', 157) -def_op('CONVERT_VALUE', 158) - -def_op('LIST_EXTEND', 162) -def_op('SET_UPDATE', 163) -def_op('DICT_MERGE', 164) -def_op('DICT_UPDATE', 165) - -def_op('LOAD_FAST_LOAD_FAST', 168) -def_op('STORE_FAST_LOAD_FAST', 169) -def_op('STORE_FAST_STORE_FAST', 170) -def_op('CALL', 171) -def_op('KW_NAMES', 172) -def_op('CALL_INTRINSIC_1', 173) -def_op('CALL_INTRINSIC_2', 174) -def_op('LOAD_FROM_DICT_OR_GLOBALS', 175) -def_op('LOAD_FROM_DICT_OR_DEREF', 176) -def_op('SET_FUNCTION_ATTRIBUTE', 177) # Attribute - -# Optimizer hook -def_op('ENTER_EXECUTOR', 230) - -# Instrumented instructions -MIN_INSTRUMENTED_OPCODE = 237 - -def_op('INSTRUMENTED_LOAD_SUPER_ATTR', 237) -def_op('INSTRUMENTED_POP_JUMP_IF_NONE', 238) -def_op('INSTRUMENTED_POP_JUMP_IF_NOT_NONE', 239) -def_op('INSTRUMENTED_RESUME', 240) -def_op('INSTRUMENTED_CALL', 241) -def_op('INSTRUMENTED_RETURN_VALUE', 242) -def_op('INSTRUMENTED_YIELD_VALUE', 243) -def_op('INSTRUMENTED_CALL_FUNCTION_EX', 244) -def_op('INSTRUMENTED_JUMP_FORWARD', 245) -def_op('INSTRUMENTED_JUMP_BACKWARD', 246) -def_op('INSTRUMENTED_RETURN_CONST', 247) -def_op('INSTRUMENTED_FOR_ITER', 248) -def_op('INSTRUMENTED_POP_JUMP_IF_FALSE', 249) -def_op('INSTRUMENTED_POP_JUMP_IF_TRUE', 250) -def_op('INSTRUMENTED_END_FOR', 251) -def_op('INSTRUMENTED_END_SEND', 252) -def_op('INSTRUMENTED_INSTRUCTION', 253) -def_op('INSTRUMENTED_LINE', 254) -# 255 is reserved - - -MIN_PSEUDO_OPCODE = 256 - -pseudo_op('SETUP_FINALLY', 256, ['NOP']) -pseudo_op('SETUP_CLEANUP', 257, ['NOP']) -pseudo_op('SETUP_WITH', 258, ['NOP']) -pseudo_op('POP_BLOCK', 259, ['NOP']) - -pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD']) -pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT']) - -pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR']) -pseudo_op('LOAD_SUPER_METHOD', 263, ['LOAD_SUPER_ATTR']) -pseudo_op('LOAD_ZERO_SUPER_METHOD', 264, ['LOAD_SUPER_ATTR']) -pseudo_op('LOAD_ZERO_SUPER_ATTR', 265, ['LOAD_SUPER_ATTR']) - -pseudo_op('STORE_FAST_MAYBE_NULL', 266, ['STORE_FAST']) -pseudo_op('LOAD_CLOSURE', 267, ['LOAD_FAST']) - -MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1 -del def_op, pseudo_op - -opname = ['<%r>' % (op,) for op in range(MAX_PSEUDO_OPCODE + 1)] +opname = ['<%r>' % (op,) for op in range(max(opmap.values()) + 1)] for op, i in opmap.items(): opname[i] = op -# The build uses older versions of Python which do not have _opcode.has_* functions -if sys.version_info[:2] >= (3, 13): - # These lists are documented as part of the dis module's API - hasarg = [op for op in opmap.values() if _opcode.has_arg(op)] - hasconst = [op for op in opmap.values() if _opcode.has_const(op)] - hasname = [op for op in opmap.values() if _opcode.has_name(op)] - hasjump = [op for op in opmap.values() if _opcode.has_jump(op)] - hasjrel = hasjump # for backward compatibility - hasjabs = [] - hasfree = [op for op in opmap.values() if _opcode.has_free(op)] - haslocal = [op for op in opmap.values() if _opcode.has_local(op)] - hasexc = [op for op in opmap.values() if _opcode.has_exc(op)] - - __all__.extend(["hasarg", "hasconst", "hasname", "hasjump", "hasjrel", - "hasjabs", "hasfree", "haslocal", "hasexc"]) - -hascompare = [opmap["COMPARE_OP"]] +cmp_op = ('<', '<=', '==', '!=', '>', '>=') -_nb_ops = [ - ("NB_ADD", "+"), - ("NB_AND", "&"), - ("NB_FLOOR_DIVIDE", "//"), - ("NB_LSHIFT", "<<"), - ("NB_MATRIX_MULTIPLY", "@"), - ("NB_MULTIPLY", "*"), - ("NB_REMAINDER", "%"), - ("NB_OR", "|"), - ("NB_POWER", "**"), - ("NB_RSHIFT", ">>"), - ("NB_SUBTRACT", "-"), - ("NB_TRUE_DIVIDE", "/"), - ("NB_XOR", "^"), - ("NB_INPLACE_ADD", "+="), - ("NB_INPLACE_AND", "&="), - ("NB_INPLACE_FLOOR_DIVIDE", "//="), - ("NB_INPLACE_LSHIFT", "<<="), - ("NB_INPLACE_MATRIX_MULTIPLY", "@="), - ("NB_INPLACE_MULTIPLY", "*="), - ("NB_INPLACE_REMAINDER", "%="), - ("NB_INPLACE_OR", "|="), - ("NB_INPLACE_POWER", "**="), - ("NB_INPLACE_RSHIFT", ">>="), - ("NB_INPLACE_SUBTRACT", "-="), - ("NB_INPLACE_TRUE_DIVIDE", "/="), - ("NB_INPLACE_XOR", "^="), -] +# These lists are documented as part of the dis module's API +hasarg = [op for op in opmap.values() if _opcode.has_arg(op)] +hasconst = [op for op in opmap.values() if _opcode.has_const(op)] +hasname = [op for op in opmap.values() if _opcode.has_name(op)] +hasjump = [op for op in opmap.values() if _opcode.has_jump(op)] +hasjrel = hasjump # for backward compatibility +hasjabs = [] +hasfree = [op for op in opmap.values() if _opcode.has_free(op)] +haslocal = [op for op in opmap.values() if _opcode.has_local(op)] +hasexc = [op for op in opmap.values() if _opcode.has_exc(op)] -_intrinsic_1_descs = [ - "INTRINSIC_1_INVALID", - "INTRINSIC_PRINT", - "INTRINSIC_IMPORT_STAR", - "INTRINSIC_STOPITERATION_ERROR", - "INTRINSIC_ASYNC_GEN_WRAP", - "INTRINSIC_UNARY_POSITIVE", - "INTRINSIC_LIST_TO_TUPLE", - "INTRINSIC_TYPEVAR", - "INTRINSIC_PARAMSPEC", - "INTRINSIC_TYPEVARTUPLE", - "INTRINSIC_SUBSCRIPT_GENERIC", - "INTRINSIC_TYPEALIAS", -] -_intrinsic_2_descs = [ - "INTRINSIC_2_INVALID", - "INTRINSIC_PREP_RERAISE_STAR", - "INTRINSIC_TYPEVAR_WITH_BOUND", - "INTRINSIC_TYPEVAR_WITH_CONSTRAINTS", - "INTRINSIC_SET_FUNCTION_TYPE_PARAMS", -] +_intrinsic_1_descs = _opcode.get_intrinsic1_descs() +_intrinsic_2_descs = _opcode.get_intrinsic2_descs() +_nb_ops = _opcode.get_nb_ops() +hascompare = [opmap["COMPARE_OP"]] _cache_format = { "LOAD_GLOBAL": { @@ -365,8 +93,20 @@ def pseudo_op(name, op, real_ops): "counter": 1, "version": 2, }, + "POP_JUMP_IF_TRUE": { + "counter": 1, + }, + "POP_JUMP_IF_FALSE": { + "counter": 1, + }, + "POP_JUMP_IF_NONE": { + "counter": 1, + }, + "POP_JUMP_IF_NOT_NONE": { + "counter": 1, + }, } -_inline_cache_entries = [ - sum(_cache_format.get(opname[opcode], {}).values()) for opcode in range(256) -] +_inline_cache_entries = { + name : sum(value.values()) for (name, value) in _cache_format.items() +} diff --git a/Lib/os.py b/Lib/os.py index d8c9ba4b15400a..a17946750ea7e7 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -1136,3 +1136,17 @@ def add_dll_directory(path): cookie, nt._remove_dll_directory ) + + +if _exists('sched_getaffinity') and sys._get_cpu_count_config() < 0: + def process_cpu_count(): + """ + Get the number of CPUs of the current process. + + Return the number of logical CPUs usable by the calling thread of the + current process. Return None if indeterminable. + """ + return len(sched_getaffinity(0)) +else: + # Just an alias to cpu_count() (same docstring) + process_cpu_count = cpu_count diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 558283bef7e512..c99b854f5e2087 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -5,6 +5,7 @@ operating systems. """ +import contextlib import fnmatch import functools import io @@ -15,9 +16,17 @@ import sys import warnings from _collections_abc import Sequence -from errno import ENOENT, ENOTDIR, EBADF, ELOOP +from errno import ENOENT, ENOTDIR, EBADF, ELOOP, EINVAL from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO -from urllib.parse import quote_from_bytes as urlquote_from_bytes + +try: + import pwd +except ImportError: + pwd = None +try: + import grp +except ImportError: + grp = None __all__ = [ @@ -30,6 +39,9 @@ # Internals # +# Maximum number of symlinks to follow in _PathBase.resolve() +_MAX_SYMLINKS = 40 + # Reference for Windows paths can be found at # https://learn.microsoft.com/en-gb/windows/win32/fileio/naming-a-file . _WIN_RESERVED_NAMES = frozenset( @@ -292,6 +304,11 @@ class PurePath: # The `_hash` slot stores the hash of the case-normalized string # path. It's set when `__hash__()` is called for the first time. '_hash', + + # The '_resolving' slot stores a boolean indicating whether the path + # is being processed by `_PathBase.resolve()`. This prevents duplicate + # work from occurring when `resolve()` calls `stat()` or `readlink()`. + '_resolving', ) pathmod = os.path @@ -331,6 +348,7 @@ def __init__(self, *args): f"not {type(path).__name__!r}") paths.append(path) self._raw_paths = paths + self._resolving = False def with_segments(self, *pathsegments): """Construct a new path object from any number of path-like objects. @@ -437,7 +455,7 @@ def __repr__(self): return "{}({!r})".format(self.__class__.__name__, self.as_posix()) def as_uri(self): - """Return the path as a 'file' URI.""" + """Return the path as a URI.""" if not self.is_absolute(): raise ValueError("relative path can't be expressed as a file URI") @@ -454,7 +472,8 @@ def as_uri(self): # It's a posix path => 'file:///etc/hosts' prefix = 'file://' path = str(self) - return prefix + urlquote_from_bytes(os.fsencode(path)) + from urllib.parse import quote_from_bytes + return prefix + quote_from_bytes(os.fsencode(path)) @property def _str_normcase(self): @@ -605,8 +624,7 @@ def with_name(self, name): if not self.name: raise ValueError("%r has an empty name" % (self,)) m = self.pathmod - drv, root, tail = m.splitroot(name) - if drv or root or not tail or m.sep in tail or (m.altsep and m.altsep in tail): + if not name or m.sep in name or (m.altsep and m.altsep in name) or name == '.': raise ValueError("Invalid name %r" % (name)) return self._from_parsed_parts(self.drive, self.root, self._tail[:-1] + [name]) @@ -654,10 +672,12 @@ def relative_to(self, other, /, *_deprecated, walk_up=False): for step, path in enumerate([other] + list(other.parents)): if self.is_relative_to(path): break + elif not walk_up: + raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}") + elif path.name == '..': + raise ValueError(f"'..' segment in {str(other)!r} cannot be walked") else: raise ValueError(f"{str(self)!r} and {str(other)!r} have different anchors") - if step and not walk_up: - raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}") parts = ['..'] * step + self._tail[len(path._tail):] return self.with_segments(*parts) @@ -710,7 +730,9 @@ def parent(self): tail = self._tail if not tail: return self - return self._from_parsed_parts(drv, root, tail[:-1]) + path = self._from_parsed_parts(drv, root, tail[:-1]) + path._resolving = self._resolving + return path @property def parents(self): @@ -795,23 +817,36 @@ class PureWindowsPath(PurePath): # Filesystem-accessing classes -class Path(PurePath): - """PurePath subclass that can make system calls. +class _PathBase(PurePath): + """Base class for concrete path objects. - Path represents a filesystem path but unlike PurePath, also offers - methods to do system calls on path objects. Depending on your system, - instantiating a Path will return either a PosixPath or a WindowsPath - object. You can also instantiate a PosixPath or WindowsPath directly, - but cannot instantiate a WindowsPath on a POSIX system or vice versa. + This class provides dummy implementations for many methods that derived + classes can override selectively; the default implementations raise + UnsupportedOperation. The most basic methods, such as stat() and open(), + directly raise UnsupportedOperation; these basic methods are called by + other methods such as is_dir() and read_text(). + + The Path class derives this class to implement local filesystem paths. + Users may derive their own classes to implement virtual filesystem paths, + such as paths in archive files or on remote storage systems. """ __slots__ = () + __bytes__ = None + __fspath__ = None # virtual paths have no local file system representation + + @classmethod + def _unsupported(cls, method_name): + msg = f"{cls.__name__}.{method_name}() is unsupported" + if issubclass(cls, Path): + msg += " on this system" + raise UnsupportedOperation(msg) def stat(self, *, follow_symlinks=True): """ Return the result of the stat() system call on this path, like os.stat() does. """ - return os.stat(self, follow_symlinks=follow_symlinks) + self._unsupported("stat") def lstat(self): """ @@ -878,7 +913,21 @@ def is_mount(self): """ Check if this path is a mount point """ - return os.path.ismount(self) + # Need to exist and be a dir + if not self.exists() or not self.is_dir(): + return False + + try: + parent_dev = self.parent.stat().st_dev + except OSError: + return False + + dev = self.stat().st_dev + if dev != parent_dev: + return True + ino = self.stat().st_ino + parent_ino = self.parent.stat().st_ino + return ino == parent_ino def is_symlink(self): """ @@ -899,7 +948,10 @@ def is_junction(self): """ Whether this path is a junction. """ - return os.path.isjunction(self) + # Junctions are a Windows-only feature, not present in POSIX nor the + # majority of virtual filesystems. There is no cross-platform idiom + # to check for junctions (using stat().st_mode). + return False def is_block_device(self): """ @@ -983,9 +1035,7 @@ def open(self, mode='r', buffering=-1, encoding=None, Open the file pointed by this path and return a file object, as the built-in open() function does. """ - if "b" not in mode: - encoding = io.text_encoding(encoding) - return io.open(self, mode, buffering, encoding, errors, newline) + self._unsupported("open") def read_bytes(self): """ @@ -1028,14 +1078,12 @@ def iterdir(self): The children are yielded in arbitrary order, and the special entries '.' and '..' are not included. """ - for name in os.listdir(self): - yield self._make_child_relpath(name) + self._unsupported("iterdir") def _scandir(self): - # bpo-24132: a future version of pathlib will support subclassing of - # pathlib.Path to customize how the filesystem is accessed. This - # includes scandir(), which is used to implement glob(). - return os.scandir(self) + # Emulate os.scandir(), which returns an object that can be used as a + # context manager. This method is called by walk() and glob(). + return contextlib.nullcontext(self.iterdir()) def _make_child_relpath(self, name): sep = self.pathmod.sep @@ -1088,6 +1136,11 @@ def _glob(self, pattern, case_sensitive, follow_symlinks): pattern_parts.append('') if pattern_parts[-1] == '**': # GH-70303: '**' only matches directories. Add trailing slash. + warnings.warn( + "Pattern ending '**' will match files and directories in a " + "future Python release. Add a trailing slash to match only " + "directories and remove this warning.", + FutureWarning, 3) pattern_parts.append('') if case_sensitive is None: @@ -1159,13 +1212,13 @@ def walk(self, top_down=True, on_error=None, follow_symlinks=False): # blow up for a minor reason when (say) a thousand readable # directories are still left to visit. That logic is copied here. try: - scandir_it = path._scandir() + scandir_obj = path._scandir() except OSError as error: if on_error is not None: on_error(error) continue - with scandir_it: + with scandir_obj as scandir_it: dirnames = [] filenames = [] for entry in scandir_it: @@ -1187,17 +1240,13 @@ def walk(self, top_down=True, on_error=None, follow_symlinks=False): paths += [path._make_child_relpath(d) for d in reversed(dirnames)] - def __init__(self, *args, **kwargs): - if kwargs: - msg = ("support for supplying keyword arguments to pathlib.PurePath " - "is deprecated and scheduled for removal in Python {remove}") - warnings._deprecated("pathlib.PurePath(**kwargs)", msg, remove=(3, 14)) - super().__init__(*args) + def absolute(self): + """Return an absolute version of this path + No normalization or symlink resolution is performed. - def __new__(cls, *args, **kwargs): - if cls is Path: - cls = WindowsPath if os.name == 'nt' else PosixPath - return object.__new__(cls) + Use resolve() to resolve symlinks and remove '..' segments. + """ + self._unsupported("absolute") @classmethod def cwd(cls): @@ -1208,18 +1257,269 @@ def cwd(cls): # os.path.abspath('.') == os.getcwd(). return cls().absolute() + def expanduser(self): + """ Return a new path with expanded ~ and ~user constructs + (as returned by os.path.expanduser) + """ + self._unsupported("expanduser") + @classmethod def home(cls): - """Return a new path pointing to the user's home directory (as - returned by os.path.expanduser('~')). + """Return a new path pointing to expanduser('~'). """ return cls("~").expanduser() + def readlink(self): + """ + Return the path to which the symbolic link points. + """ + self._unsupported("readlink") + readlink._supported = False + + def _split_stack(self): + """ + Split the path into a 2-tuple (anchor, parts), where *anchor* is the + uppermost parent of the path (equivalent to path.parents[-1]), and + *parts* is a reversed list of parts following the anchor. + """ + return self._from_parsed_parts(self.drive, self.root, []), self._tail[::-1] + + def resolve(self, strict=False): + """ + Make the path absolute, resolving all symlinks on the way and also + normalizing it. + """ + if self._resolving: + return self + try: + path = self.absolute() + except UnsupportedOperation: + path = self + + # If the user has *not* overridden the `readlink()` method, then symlinks are unsupported + # and (in non-strict mode) we can improve performance by not calling `stat()`. + querying = strict or getattr(self.readlink, '_supported', True) + link_count = 0 + stat_cache = {} + target_cache = {} + path, parts = path._split_stack() + while parts: + part = parts.pop() + if part == '..': + if not path._tail: + if path.root: + # Delete '..' segment immediately following root + continue + elif path._tail[-1] != '..': + # Delete '..' segment and its predecessor + path = path.parent + continue + # Join the current part onto the path. + path_parent = path + path = path._make_child_relpath(part) + if querying and part != '..': + path._resolving = True + try: + st = stat_cache.get(path) + if st is None: + st = stat_cache[path] = path.stat(follow_symlinks=False) + if S_ISLNK(st.st_mode): + # Like Linux and macOS, raise OSError(errno.ELOOP) if too many symlinks are + # encountered during resolution. + link_count += 1 + if link_count >= _MAX_SYMLINKS: + raise OSError(ELOOP, "Too many symbolic links in path", str(path)) + target = target_cache.get(path) + if target is None: + target = target_cache[path] = path.readlink() + target, target_parts = target._split_stack() + # If the symlink target is absolute (like '/etc/hosts'), set the current + # path to its uppermost parent (like '/'). If not, the symlink target is + # relative to the symlink parent, which we recorded earlier. + path = target if target.root else path_parent + # Add the symlink target's reversed tail parts (like ['hosts', 'etc']) to + # the stack of unresolved path parts. + parts.extend(target_parts) + elif parts and not S_ISDIR(st.st_mode): + raise NotADirectoryError(ENOTDIR, "Not a directory", str(path)) + except OSError: + if strict: + raise + else: + querying = False + path._resolving = False + return path + + def symlink_to(self, target, target_is_directory=False): + """ + Make this path a symlink pointing to the target path. + Note the order of arguments (link, target) is the reverse of os.symlink. + """ + self._unsupported("symlink_to") + + def hardlink_to(self, target): + """ + Make this path a hard link pointing to the same file as *target*. + + Note the order of arguments (self, target) is the reverse of os.link's. + """ + self._unsupported("hardlink_to") + + def touch(self, mode=0o666, exist_ok=True): + """ + Create this file with the given access mode, if it doesn't exist. + """ + self._unsupported("touch") + + def mkdir(self, mode=0o777, parents=False, exist_ok=False): + """ + Create a new directory at this given path. + """ + self._unsupported("mkdir") + + def rename(self, target): + """ + Rename this path to the target path. + + The target path may be absolute or relative. Relative paths are + interpreted relative to the current working directory, *not* the + directory of the Path object. + + Returns the new Path instance pointing to the target path. + """ + self._unsupported("rename") + + def replace(self, target): + """ + Rename this path to the target path, overwriting if that path exists. + + The target path may be absolute or relative. Relative paths are + interpreted relative to the current working directory, *not* the + directory of the Path object. + + Returns the new Path instance pointing to the target path. + """ + self._unsupported("replace") + + def chmod(self, mode, *, follow_symlinks=True): + """ + Change the permissions of the path, like os.chmod(). + """ + self._unsupported("chmod") + + def lchmod(self, mode): + """ + Like chmod(), except if the path points to a symlink, the symlink's + permissions are changed, rather than its target's. + """ + self.chmod(mode, follow_symlinks=False) + + def unlink(self, missing_ok=False): + """ + Remove this file or link. + If the path is a directory, use rmdir() instead. + """ + self._unsupported("unlink") + + def rmdir(self): + """ + Remove this directory. The directory must be empty. + """ + self._unsupported("rmdir") + + def owner(self): + """ + Return the login name of the file owner. + """ + self._unsupported("owner") + + def group(self): + """ + Return the group name of the file gid. + """ + self._unsupported("group") + + @classmethod + def from_uri(cls, uri): + """Return a new path from the given 'file' URI.""" + cls._unsupported("from_uri") + + def as_uri(self): + """Return the path as a URI.""" + self._unsupported("as_uri") + + +class Path(_PathBase): + """PurePath subclass that can make system calls. + + Path represents a filesystem path but unlike PurePath, also offers + methods to do system calls on path objects. Depending on your system, + instantiating a Path will return either a PosixPath or a WindowsPath + object. You can also instantiate a PosixPath or WindowsPath directly, + but cannot instantiate a WindowsPath on a POSIX system or vice versa. + """ + __slots__ = () + __bytes__ = PurePath.__bytes__ + __fspath__ = PurePath.__fspath__ + as_uri = PurePath.as_uri + + def __init__(self, *args, **kwargs): + if kwargs: + msg = ("support for supplying keyword arguments to pathlib.PurePath " + "is deprecated and scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath(**kwargs)", msg, remove=(3, 14)) + super().__init__(*args) + + def __new__(cls, *args, **kwargs): + if cls is Path: + cls = WindowsPath if os.name == 'nt' else PosixPath + return object.__new__(cls) + + def stat(self, *, follow_symlinks=True): + """ + Return the result of the stat() system call on this path, like + os.stat() does. + """ + return os.stat(self, follow_symlinks=follow_symlinks) + + def is_mount(self): + """ + Check if this path is a mount point + """ + return os.path.ismount(self) + + def is_junction(self): + """ + Whether this path is a junction. + """ + return os.path.isjunction(self) + + def open(self, mode='r', buffering=-1, encoding=None, + errors=None, newline=None): + """ + Open the file pointed by this path and return a file object, as + the built-in open() function does. + """ + if "b" not in mode: + encoding = io.text_encoding(encoding) + return io.open(self, mode, buffering, encoding, errors, newline) + + def iterdir(self): + """Yield path objects of the directory contents. + + The children are yielded in arbitrary order, and the + special entries '.' and '..' are not included. + """ + return (self._make_child_relpath(name) for name in os.listdir(self)) + + def _scandir(self): + return os.scandir(self) + def absolute(self): - """Return an absolute version of this path by prepending the current - working directory. No normalization or symlink resolution is performed. + """Return an absolute version of this path + No normalization or symlink resolution is performed. - Use resolve() to get the canonical path to a file. + Use resolve() to resolve symlinks and remove '..' segments. """ if self.is_absolute(): return self @@ -1245,55 +1545,28 @@ def resolve(self, strict=False): normalizing it. """ - def check_eloop(e): - winerror = getattr(e, 'winerror', 0) - if e.errno == ELOOP or winerror == _WINERROR_CANT_RESOLVE_FILENAME: - raise RuntimeError("Symlink loop from %r" % e.filename) - - try: - s = os.path.realpath(self, strict=strict) - except OSError as e: - check_eloop(e) - raise - p = self.with_segments(s) + return self.with_segments(os.path.realpath(self, strict=strict)) - # In non-strict mode, realpath() doesn't raise on symlink loops. - # Ensure we get an exception by calling stat() - if not strict: - try: - p.stat() - except OSError as e: - check_eloop(e) - return p - - def owner(self): - """ - Return the login name of the file owner. - """ - try: - import pwd + if pwd: + def owner(self): + """ + Return the login name of the file owner. + """ return pwd.getpwuid(self.stat().st_uid).pw_name - except ImportError: - raise UnsupportedOperation("Path.owner() is unsupported on this system") - def group(self): - """ - Return the group name of the file gid. - """ - - try: - import grp + if grp: + def group(self): + """ + Return the group name of the file gid. + """ return grp.getgrgid(self.stat().st_gid).gr_name - except ImportError: - raise UnsupportedOperation("Path.group() is unsupported on this system") - def readlink(self): - """ - Return the path to which the symbolic link points. - """ - if not hasattr(os, "readlink"): - raise UnsupportedOperation("os.readlink() not available on this system") - return self.with_segments(os.readlink(self)) + if hasattr(os, "readlink"): + def readlink(self): + """ + Return the path to which the symbolic link points. + """ + return self.with_segments(os.readlink(self)) def touch(self, mode=0o666, exist_ok=True): """ @@ -1340,13 +1613,6 @@ def chmod(self, mode, *, follow_symlinks=True): """ os.chmod(self, mode, follow_symlinks=follow_symlinks) - def lchmod(self, mode): - """ - Like chmod(), except if the path points to a symlink, the symlink's - permissions are changed, rather than its target's. - """ - self.chmod(mode, follow_symlinks=False) - def unlink(self, missing_ok=False): """ Remove this file or link. @@ -1390,24 +1656,22 @@ def replace(self, target): os.replace(self, target) return self.with_segments(target) - def symlink_to(self, target, target_is_directory=False): - """ - Make this path a symlink pointing to the target path. - Note the order of arguments (link, target) is the reverse of os.symlink. - """ - if not hasattr(os, "symlink"): - raise UnsupportedOperation("os.symlink() not available on this system") - os.symlink(target, self, target_is_directory) + if hasattr(os, "symlink"): + def symlink_to(self, target, target_is_directory=False): + """ + Make this path a symlink pointing to the target path. + Note the order of arguments (link, target) is the reverse of os.symlink. + """ + os.symlink(target, self, target_is_directory) - def hardlink_to(self, target): - """ - Make this path a hard link pointing to the same file as *target*. + if hasattr(os, "link"): + def hardlink_to(self, target): + """ + Make this path a hard link pointing to the same file as *target*. - Note the order of arguments (self, target) is the reverse of os.link's. - """ - if not hasattr(os, "link"): - raise UnsupportedOperation("os.link() not available on this system") - os.link(target, self) + Note the order of arguments (self, target) is the reverse of os.link's. + """ + os.link(target, self) def expanduser(self): """ Return a new path with expanded ~ and ~user constructs @@ -1423,6 +1687,30 @@ def expanduser(self): return self + @classmethod + def from_uri(cls, uri): + """Return a new path from the given 'file' URI.""" + if not uri.startswith('file:'): + raise ValueError(f"URI does not start with 'file:': {uri!r}") + path = uri[5:] + if path[:3] == '///': + # Remove empty authority + path = path[2:] + elif path[:12] == '//localhost/': + # Remove 'localhost' authority + path = path[11:] + if path[:3] == '///' or (path[:1] == '/' and path[2:3] in ':|'): + # Remove slash before DOS device/UNC path + path = path[1:] + if path[1:2] == '|': + # Replace bar with colon in DOS drive + path = path[:1] + ':' + path[2:] + from urllib.parse import unquote_to_bytes + path = cls(os.fsdecode(unquote_to_bytes(path))) + if not path.is_absolute(): + raise ValueError(f"URI is not absolute: {uri!r}") + return path + class PosixPath(Path, PurePosixPath): """Path subclass for non-Windows systems. diff --git a/Lib/pdb.py b/Lib/pdb.py index 3db3e6a5be1a7b..930cb91b8696a3 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -85,6 +85,7 @@ import traceback import linecache +from contextlib import contextmanager from typing import Union @@ -205,10 +206,15 @@ def namespace(self): # line_prefix = ': ' # Use this to get the old situation back line_prefix = '\n-> ' # Probably a better default -class Pdb(bdb.Bdb, cmd.Cmd): + +class Pdb(bdb.Bdb, cmd.Cmd): _previous_sigint_handler = None + # Limit the maximum depth of chained exceptions, we should be handling cycles, + # but in case there are recursions, we stop at 999. + MAX_CHAINED_EXCEPTION_DEPTH = 999 + def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True): bdb.Bdb.__init__(self, skip=skip) @@ -231,6 +237,9 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, pass self.allow_kbdint = False self.nosigint = nosigint + # Consider these characters as part of the command so when the users type + # c.a or c['a'], it won't be recognized as a c(ontinue) command + self.identchars = cmd.Cmd.identchars + '=.[](),"\'+-*/%@&|<>~^' # Read ~/.pdbrc and ./.pdbrc self.rcLines = [] @@ -256,6 +265,9 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, self.commands_bnum = None # The breakpoint number for which we are # defining a list + self._chained_exceptions = tuple() + self._chained_exception_index = 0 + def sigint_handler(self, signum, frame): if self.allow_kbdint: raise KeyboardInterrupt @@ -292,6 +304,14 @@ def setup(self, f, tb): # cache it here to ensure that modifications are not overwritten. self.curframe_locals = self.curframe.f_locals self.set_convenience_variable(self.curframe, '_frame', self.curframe) + + if self._chained_exceptions: + self.set_convenience_variable( + self.curframe, + '_exception', + self._chained_exceptions[self._chained_exception_index], + ) + return self.execRcLines() # Can be executed earlier than 'setup' if desired @@ -411,10 +431,68 @@ def preloop(self): # fields are changed to be displayed if newvalue is not oldvalue and newvalue != oldvalue: displaying[expr] = newvalue - self.message('display %s: %r [old: %r]' % - (expr, newvalue, oldvalue)) + self.message('display %s: %s [old: %s]' % + (expr, self._safe_repr(newvalue, expr), + self._safe_repr(oldvalue, expr))) + + def _get_tb_and_exceptions(self, tb_or_exc): + """ + Given a tracecack or an exception, return a tuple of chained exceptions + and current traceback to inspect. + + This will deal with selecting the right ``__cause__`` or ``__context__`` + as well as handling cycles, and return a flattened list of exceptions we + can jump to with do_exceptions. + + """ + _exceptions = [] + if isinstance(tb_or_exc, BaseException): + traceback, current = tb_or_exc.__traceback__, tb_or_exc + + while current is not None: + if current in _exceptions: + break + _exceptions.append(current) + if current.__cause__ is not None: + current = current.__cause__ + elif ( + current.__context__ is not None and not current.__suppress_context__ + ): + current = current.__context__ + + if len(_exceptions) >= self.MAX_CHAINED_EXCEPTION_DEPTH: + self.message( + f"More than {self.MAX_CHAINED_EXCEPTION_DEPTH}" + " chained exceptions found, not all exceptions" + "will be browsable with `exceptions`." + ) + break + else: + traceback = tb_or_exc + return tuple(reversed(_exceptions)), traceback + + @contextmanager + def _hold_exceptions(self, exceptions): + """ + Context manager to ensure proper cleaning of exceptions references + + When given a chained exception instead of a traceback, + pdb may hold references to many objects which may leak memory. + + We use this context manager to make sure everything is properly cleaned - def interaction(self, frame, traceback): + """ + try: + self._chained_exceptions = exceptions + self._chained_exception_index = len(exceptions) - 1 + yield + finally: + # we can't put those in forget as otherwise they would + # be cleared on exception change + self._chained_exceptions = tuple() + self._chained_exception_index = 0 + + def interaction(self, frame, tb_or_exc): # Restore the previous signal handler at the Pdb prompt. if Pdb._previous_sigint_handler: try: @@ -423,14 +501,19 @@ def interaction(self, frame, traceback): pass else: Pdb._previous_sigint_handler = None - if self.setup(frame, traceback): - # no interaction desired at this time (happens if .pdbrc contains - # a command like "continue") + + _chained_exceptions, tb = self._get_tb_and_exceptions(tb_or_exc) + if isinstance(tb_or_exc, BaseException): + assert tb is not None, "main exception must have a traceback" + with self._hold_exceptions(_chained_exceptions): + if self.setup(frame, tb): + # no interaction desired at this time (happens if .pdbrc contains + # a command like "continue") + self.forget() + return + self.print_stack_entry(self.stack[self.curindex]) + self._cmdloop() self.forget() - return - self.print_stack_entry(self.stack[self.curindex]) - self._cmdloop() - self.forget() def displayhook(self, obj): """Custom displayhook for the exec in default(), which prevents @@ -440,6 +523,22 @@ def displayhook(self, obj): if obj is not None: self.message(repr(obj)) + @contextmanager + def _disable_tab_completion(self): + if self.use_rawinput and self.completekey == 'tab': + try: + import readline + except ImportError: + yield + return + try: + readline.parse_and_bind('tab: self-insert') + yield + finally: + readline.parse_and_bind('tab: complete') + else: + yield + def default(self, line): if line[:1] == '!': line = line[1:].strip() locals = self.curframe_locals @@ -447,28 +546,29 @@ def default(self, line): try: if (code := codeop.compile_command(line + '\n', '', 'single')) is None: # Multi-line mode - buffer = line - continue_prompt = "... " - while (code := codeop.compile_command(buffer, '', 'single')) is None: - if self.use_rawinput: - try: - line = input(continue_prompt) - except (EOFError, KeyboardInterrupt): - self.lastcmd = "" - print('\n') - return - else: - self.stdout.write(continue_prompt) - self.stdout.flush() - line = self.stdin.readline() - if not len(line): - self.lastcmd = "" - self.stdout.write('\n') - self.stdout.flush() - return + with self._disable_tab_completion(): + buffer = line + continue_prompt = "... " + while (code := codeop.compile_command(buffer, '', 'single')) is None: + if self.use_rawinput: + try: + line = input(continue_prompt) + except (EOFError, KeyboardInterrupt): + self.lastcmd = "" + print('\n') + return else: - line = line.rstrip('\r\n') - buffer += '\n' + line + self.stdout.write(continue_prompt) + self.stdout.flush() + line = self.stdin.readline() + if not len(line): + self.lastcmd = "" + self.stdout.write('\n') + self.stdout.flush() + return + else: + line = line.rstrip('\r\n') + buffer += '\n' + line save_stdout = sys.stdout save_stdin = sys.stdin save_displayhook = sys.displayhook @@ -1073,6 +1173,53 @@ def _select_frame(self, number): self.print_stack_entry(self.stack[self.curindex]) self.lineno = None + def do_exceptions(self, arg): + """exceptions [number] + + List or change current exception in an exception chain. + + Without arguments, list all the current exception in the exception + chain. Exceptions will be numbered, with the current exception indicated + with an arrow. + + If given an integer as argument, switch to the exception at that index. + """ + if not self._chained_exceptions: + self.message( + "Did not find chained exceptions. To move between" + " exceptions, pdb/post_mortem must be given an exception" + " object rather than a traceback." + ) + return + if not arg: + for ix, exc in enumerate(self._chained_exceptions): + prompt = ">" if ix == self._chained_exception_index else " " + rep = repr(exc) + if len(rep) > 80: + rep = rep[:77] + "..." + indicator = ( + " -" + if self._chained_exceptions[ix].__traceback__ is None + else f"{ix:>3}" + ) + self.message(f"{prompt} {indicator} {rep}") + else: + try: + number = int(arg) + except ValueError: + self.error("Argument must be an integer") + return + if 0 <= number < len(self._chained_exceptions): + if self._chained_exceptions[number].__traceback__ is None: + self.error("This exception does not have a traceback, cannot jump to it") + return + + self._chained_exception_index = number + self.setup(None, self._chained_exceptions[number].__traceback__) + self.print_stack_entry(self.stack[self.curindex]) + else: + self.error("No exception with that number") + def do_up(self, arg): """u(p) [count] @@ -1314,7 +1461,7 @@ def do_args(self, arg): for i in range(n): name = co.co_varnames[i] if name in dict: - self.message('%s = %r' % (name, dict[name])) + self.message('%s = %s' % (name, self._safe_repr(dict[name], name))) else: self.message('%s = *** undefined ***' % (name,)) do_a = do_args @@ -1328,7 +1475,7 @@ def do_retval(self, arg): self._print_invalid_arg(arg) return if '__return__' in self.curframe_locals: - self.message(repr(self.curframe_locals['__return__'])) + self.message(self._safe_repr(self.curframe_locals['__return__'], "retval")) else: self.error('Not yet returned!') do_rv = do_retval @@ -1363,6 +1510,12 @@ def _msg_val_func(self, arg, func): except: self._error_exc() + def _safe_repr(self, obj, expr): + try: + return repr(obj) + except Exception as e: + return _rstr(f"*** repr({expr}) failed: {self._format_exc(e)} ***") + def do_p(self, arg): """p expression @@ -1542,8 +1695,8 @@ def do_display(self, arg): if not arg: if self.displaying: self.message('Currently displaying:') - for item in self.displaying.get(self.curframe, {}).items(): - self.message('%s: %r' % item) + for key, val in self.displaying.get(self.curframe, {}).items(): + self.message('%s: %s' % (key, self._safe_repr(val, key))) else: self.message('No expression is being displayed') else: @@ -1552,7 +1705,7 @@ def do_display(self, arg): else: val = self._getval_except(arg) self.displaying.setdefault(self.curframe, {})[arg] = val - self.message('display %s: %r' % (arg, val)) + self.message('display %s: %s' % (arg, self._safe_repr(val, arg))) complete_display = _complete_expression @@ -1615,8 +1768,11 @@ def do_alias(self, arg): for alias in keys: self.message("%s = %s" % (alias, self.aliases[alias])) return - if args[0] in self.aliases and len(args) == 1: - self.message("%s = %s" % (args[0], self.aliases[args[0]])) + if len(args) == 1: + if args[0] in self.aliases: + self.message("%s = %s" % (args[0], self.aliases[args[0]])) + else: + self.error(f"Unknown alias '{args[0]}'") else: self.aliases[args[0]] = ' '.join(args[1:]) @@ -1890,11 +2046,23 @@ def set_trace(*, header=None): # Post-Mortem interface def post_mortem(t=None): - """Enter post-mortem debugging of the given *traceback* object. + """Enter post-mortem debugging of the given *traceback*, or *exception* + object. If no traceback is given, it uses the one of the exception that is currently being handled (an exception must be being handled if the default is to be used). + + If `t` is an exception object, the `exceptions` command makes it possible to + list and inspect its chained exceptions (if any). + """ + return _post_mortem(t, Pdb()) + + +def _post_mortem(t, pdb_instance): + """ + Private version of post_mortem, which allow to pass a pdb instance + for testing purposes. """ # handling the default if t is None: @@ -1902,21 +2070,17 @@ def post_mortem(t=None): if exc is not None: t = exc.__traceback__ - if t is None: + if t is None or (isinstance(t, BaseException) and t.__traceback__ is None): raise ValueError("A valid traceback must be passed if no " "exception is being handled") - p = Pdb() - p.reset() - p.interaction(None, t) + pdb_instance.reset() + pdb_instance.interaction(None, t) + def pm(): - """Enter post-mortem debugging of the traceback found in sys.last_traceback.""" - if hasattr(sys, 'last_exc'): - tb = sys.last_exc.__traceback__ - else: - tb = sys.last_traceback - post_mortem(tb) + """Enter post-mortem debugging of the traceback found in sys.last_exc.""" + post_mortem(sys.last_exc) # Main program for testing @@ -1932,8 +2096,6 @@ def help(): pydoc.pager(__doc__) _usage = """\ -usage: pdb.py [-c command] ... [-m module | pyfile] [arg] ... - Debug the Python program given by pyfile. Alternatively, an executable module or package to debug can be specified using the -m switch. @@ -1948,34 +2110,44 @@ def help(): def main(): - import getopt - - opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['help', 'command=']) - - if not args: - print(_usage) + import argparse + + parser = argparse.ArgumentParser(prog="pdb", + description=_usage, + formatter_class=argparse.RawDescriptionHelpFormatter, + allow_abbrev=False) + + parser.add_argument('-c', '--command', action='append', default=[], metavar='command') + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-m', metavar='module') + group.add_argument('pyfile', nargs='?') + parser.add_argument('args', nargs="*") + + if len(sys.argv) == 1: + # If no arguments were given (python -m pdb), print the whole help message. + # Without this check, argparse would only complain about missing required arguments. + parser.print_help() sys.exit(2) - if any(opt in ['-h', '--help'] for opt, optarg in opts): - print(_usage) - sys.exit() + opts = parser.parse_args() - commands = [optarg for opt, optarg in opts if opt in ['-c', '--command']] - - module_indicated = any(opt in ['-m'] for opt, optarg in opts) - cls = _ModuleTarget if module_indicated else _ScriptTarget - target = cls(args[0]) + if opts.m: + file = opts.m + target = _ModuleTarget(file) + else: + file = opts.pyfile + target = _ScriptTarget(file) target.check() - sys.argv[:] = args # Hide "pdb.py" and pdb options from argument list + sys.argv[:] = [file] + opts.args # Hide "pdb.py" and pdb options from argument list # Note on saving/restoring sys.argv: it's a good idea when sys.argv was # modified by the script being debugged. It's a bad idea when it was # changed by the user from the command line. There is a "restart" command # which allows explicit specification of command line arguments. pdb = Pdb() - pdb.rcLines.extend(commands) + pdb.rcLines.extend(opts.command) while True: try: pdb._run(target) @@ -1996,8 +2168,7 @@ def main(): traceback.print_exc() print("Uncaught exception. Entering post mortem debugging") print("Running 'cont' or 'step' will restart the program") - t = e.__traceback__ - pdb.interaction(None, t) + pdb.interaction(None, e) print("Post mortem debugger finished. The " + target + " will be restarted") diff --git a/Lib/pickle.py b/Lib/pickle.py index fe86f80f51d3b9..4f5ad5b71e8899 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -396,6 +396,8 @@ def decode_long(data): return int.from_bytes(data, byteorder='little', signed=True) +_NoValue = object() + # Pickling machinery class _Pickler: @@ -542,8 +544,8 @@ def save(self, obj, save_persistent_id=True): return rv = NotImplemented - reduce = getattr(self, "reducer_override", None) - if reduce is not None: + reduce = getattr(self, "reducer_override", _NoValue) + if reduce is not _NoValue: rv = reduce(obj) if rv is NotImplemented: @@ -556,8 +558,8 @@ def save(self, obj, save_persistent_id=True): # Check private dispatch table if any, or else # copyreg.dispatch_table - reduce = getattr(self, 'dispatch_table', dispatch_table).get(t) - if reduce is not None: + reduce = getattr(self, 'dispatch_table', dispatch_table).get(t, _NoValue) + if reduce is not _NoValue: rv = reduce(obj) else: # Check for a class with a custom metaclass; treat as regular @@ -567,12 +569,12 @@ def save(self, obj, save_persistent_id=True): return # Check for a __reduce_ex__ method, fall back to __reduce__ - reduce = getattr(obj, "__reduce_ex__", None) - if reduce is not None: + reduce = getattr(obj, "__reduce_ex__", _NoValue) + if reduce is not _NoValue: rv = reduce(self.proto) else: - reduce = getattr(obj, "__reduce__", None) - if reduce is not None: + reduce = getattr(obj, "__reduce__", _NoValue) + if reduce is not _NoValue: rv = reduce() else: raise PicklingError("Can't pickle %r object: %r" % @@ -1705,8 +1707,8 @@ def load_build(self): stack = self.stack state = stack.pop() inst = stack[-1] - setstate = getattr(inst, "__setstate__", None) - if setstate is not None: + setstate = getattr(inst, "__setstate__", _NoValue) + if setstate is not _NoValue: setstate(state) return slotstate = None diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 185f09e603df2e..c9a55799b39f0c 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -197,6 +197,24 @@ def splitdoc(doc): return lines[0], '\n'.join(lines[2:]) return '', '\n'.join(lines) +def _getargspec(object): + try: + signature = inspect.signature(object) + if signature: + return str(signature) + except (ValueError, TypeError): + argspec = getattr(object, '__text_signature__', None) + if argspec: + if argspec[:2] == '($': + argspec = '(' + argspec[2:] + if getattr(object, '__self__', None) is not None: + # Strip the bound argument. + m = re.match(r'\(\w+(?:(?=\))|,\s*(?:/(?:(?=\))|,\s*))?)', argspec) + if m: + argspec = '(' + argspec[m.end():] + return argspec + return None + def classname(object, modname): """Get a class name and qualify it with a module name if necessary.""" name = object.__name__ @@ -1003,14 +1021,9 @@ def spilldata(msg, attrs, predicate): title = title + '(%s)' % ', '.join(parents) decl = '' - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if argspec and argspec != '()': - decl = name + self.escape(argspec) + '\n\n' + argspec = _getargspec(object) + if argspec and argspec != '()': + decl = name + self.escape(argspec) + '\n\n' doc = getdoc(object) if decl: @@ -1063,18 +1076,13 @@ def docroutine(self, object, name=None, mod=None, anchor, name, reallink) argspec = None if inspect.isroutine(object): - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if realname == '': - title = '%s lambda ' % name - # XXX lambda's won't usually have func_annotations['return'] - # since the syntax doesn't support but it is possible. - # So removing parentheses isn't truly safe. - argspec = argspec[1:-1] # remove parentheses + argspec = _getargspec(object) + if argspec and realname == '': + title = '%s lambda ' % name + # XXX lambda's won't usually have func_annotations['return'] + # since the syntax doesn't support but it is possible. + # So removing parentheses isn't truly safe. + argspec = argspec[1:-1] # remove parentheses if not argspec: argspec = '(...)' @@ -1321,14 +1329,9 @@ def makename(c, m=object.__module__): contents = [] push = contents.append - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if argspec and argspec != '()': - push(name + argspec + '\n') + argspec = _getargspec(object) + if argspec and argspec != '()': + push(name + argspec + '\n') doc = getdoc(object) if doc: @@ -1492,18 +1495,13 @@ def docroutine(self, object, name=None, mod=None, cl=None): argspec = None if inspect.isroutine(object): - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if realname == '': - title = self.bold(name) + ' lambda ' - # XXX lambda's won't usually have func_annotations['return'] - # since the syntax doesn't support but it is possible. - # So removing parentheses isn't truly safe. - argspec = argspec[1:-1] # remove parentheses + argspec = _getargspec(object) + if argspec and realname == '': + title = self.bold(name) + ' lambda ' + # XXX lambda's won't usually have func_annotations['return'] + # since the syntax doesn't support but it is possible. + # So removing parentheses isn't truly safe. + argspec = argspec[1:-1] # remove parentheses if not argspec: argspec = '(...)' decl = asyncqualifier + title + argspec + note diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index cb742992a48e8f..87b0a2d669e5a3 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Mon May 22 14:02:15 2023 +# Autogenerated by Sphinx on Fri Oct 13 10:51:21 2023 +# as part of the release process. topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -208,7 +209,7 @@ 'the\n' ' subscript must have a type compatible with the mapping’s key ' 'type,\n' - ' and the mapping is then asked to create a key/datum pair ' + ' and the mapping is then asked to create a key/value pair ' 'which maps\n' ' the subscript to the assigned object. This can either ' 'replace an\n' @@ -538,77 +539,7 @@ ' **PEP 492** - Coroutines with async and await syntax\n' ' The proposal that made coroutines a proper standalone concept ' 'in\n' - ' Python, and added supporting syntax.\n' - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] The exception is propagated to the invocation stack unless ' - 'there\n' - ' is a "finally" clause which happens to raise another ' - 'exception.\n' - ' That new exception causes the old one to be lost.\n' - '\n' - '[2] In pattern matching, a sequence is defined as one of the\n' - ' following:\n' - '\n' - ' * a class that inherits from "collections.abc.Sequence"\n' - '\n' - ' * a Python class that has been registered as\n' - ' "collections.abc.Sequence"\n' - '\n' - ' * a builtin class that has its (CPython) ' - '"Py_TPFLAGS_SEQUENCE"\n' - ' bit set\n' - '\n' - ' * a class that inherits from any of the above\n' - '\n' - ' The following standard library classes are sequences:\n' - '\n' - ' * "array.array"\n' - '\n' - ' * "collections.deque"\n' - '\n' - ' * "list"\n' - '\n' - ' * "memoryview"\n' - '\n' - ' * "range"\n' - '\n' - ' * "tuple"\n' - '\n' - ' Note:\n' - '\n' - ' Subject values of type "str", "bytes", and "bytearray" do ' - 'not\n' - ' match sequence patterns.\n' - '\n' - '[3] In pattern matching, a mapping is defined as one of the ' - 'following:\n' - '\n' - ' * a class that inherits from "collections.abc.Mapping"\n' - '\n' - ' * a Python class that has been registered as\n' - ' "collections.abc.Mapping"\n' - '\n' - ' * a builtin class that has its (CPython) ' - '"Py_TPFLAGS_MAPPING"\n' - ' bit set\n' - '\n' - ' * a class that inherits from any of the above\n' - '\n' - ' The standard library classes "dict" and ' - '"types.MappingProxyType"\n' - ' are mappings.\n' - '\n' - '[4] A string literal appearing as the first statement in the ' - 'function\n' - ' body is transformed into the function’s "__doc__" attribute ' - 'and\n' - ' therefore the function’s *docstring*.\n' - '\n' - '[5] A string literal appearing as the first statement in the class\n' - ' body is transformed into the namespace’s "__doc__" item and\n' - ' therefore the class’s *docstring*.\n', + ' Python, and added supporting syntax.\n', 'atom-identifiers': 'Identifiers (Names)\n' '*******************\n' '\n' @@ -713,7 +644,7 @@ '"__getattr__()" would have\n' ' no way to access other attributes of the instance. ' 'Note that at\n' - ' least for instance variables, you can fake total ' + ' least for instance variables, you can take total ' 'control by not\n' ' inserting any values in the instance attribute ' 'dictionary (but\n' @@ -1075,9 +1006,7 @@ 'for each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '--------------------------\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -1748,8 +1677,8 @@ 'standard\n' 'type hierarchy):\n' '\n' - ' classdef ::= [decorators] "class" classname [inheritance] ":" ' - 'suite\n' + ' classdef ::= [decorators] "class" classname [type_params] ' + '[inheritance] ":" suite\n' ' inheritance ::= "(" [argument_list] ")"\n' ' classname ::= identifier\n' '\n' @@ -1813,6 +1742,19 @@ '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'immediately\n' + 'after the class’s name. This indicates to static type checkers ' + 'that\n' + 'the class is generic. At runtime, the type parameters can be ' + 'retrieved\n' + 'from the class’s "__type_params__" attribute. See Generic classes ' + 'for\n' + 'more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' '**Programmer’s note:** Variables defined in the class definition ' 'are\n' 'class attributes; they are shared by instances. Instance ' @@ -2870,18 +2812,19 @@ ' bindings made during a successful pattern match outlive the\n' ' executed block and can be used after the match statement**.\n' '\n' - ' Note:\n' + ' Note:\n' '\n' - ' During failed pattern matches, some subpatterns may ' - 'succeed.\n' - ' Do not rely on bindings being made for a failed match.\n' - ' Conversely, do not rely on variables remaining unchanged ' - 'after\n' - ' a failed match. The exact behavior is dependent on\n' - ' implementation and may vary. This is an intentional ' - 'decision\n' - ' made to allow different implementations to add ' - 'optimizations.\n' + ' During failed pattern matches, some subpatterns may ' + 'succeed. Do\n' + ' not rely on bindings being made for a failed match. ' + 'Conversely,\n' + ' do not rely on variables remaining unchanged after a ' + 'failed\n' + ' match. The exact behavior is dependent on implementation ' + 'and may\n' + ' vary. This is an intentional decision made to allow ' + 'different\n' + ' implementations to add optimizations.\n' '\n' '3. If the pattern succeeds, the corresponding guard (if present) ' 'is\n' @@ -3533,9 +3476,10 @@ '* convert "P1" to a keyword pattern using "CLS.__match_args__"\n' '\n' '* For each keyword argument "attr=P2":\n' - ' * "hasattr(, "attr")"\n' '\n' - ' * "P2" matches ".attr"\n' + ' * "hasattr(, "attr")"\n' + '\n' + ' * "P2" matches ".attr"\n' '\n' '* … and so on for the corresponding keyword argument/pattern ' 'pair.\n' @@ -3554,8 +3498,8 @@ '(see\n' 'section The standard type hierarchy):\n' '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' - '[parameter_list] ")"\n' + ' funcdef ::= [decorators] "def" funcname ' + '[type_params] "(" [parameter_list] ")"\n' ' ["->" expression] ":" suite\n' ' decorators ::= decorator+\n' ' decorator ::= "@" assignment_expression ' @@ -3617,6 +3561,19 @@ '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'between the\n' + 'function’s name and the opening parenthesis for its parameter ' + 'list.\n' + 'This indicates to static type checkers that the function is ' + 'generic.\n' + 'At runtime, the type parameters can be retrieved from the ' + 'function’s\n' + '"__type_params__" attribute. See Generic functions for more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' 'When one or more *parameters* have the form *parameter* "="\n' '*expression*, the function is said to have “default parameter ' 'values.â€\n' @@ -3759,8 +3716,8 @@ 'standard\n' 'type hierarchy):\n' '\n' - ' classdef ::= [decorators] "class" classname [inheritance] ' - '":" suite\n' + ' classdef ::= [decorators] "class" classname [type_params] ' + '[inheritance] ":" suite\n' ' inheritance ::= "(" [argument_list] ")"\n' ' classname ::= identifier\n' '\n' @@ -3828,6 +3785,19 @@ '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'immediately\n' + 'after the class’s name. This indicates to static type checkers ' + 'that\n' + 'the class is generic. At runtime, the type parameters can be ' + 'retrieved\n' + 'from the class’s "__type_params__" attribute. See Generic ' + 'classes for\n' + 'more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' '**Programmer’s note:** Variables defined in the class definition ' 'are\n' 'class attributes; they are shared by instances. Instance ' @@ -3985,6 +3955,272 @@ 'concept in\n' ' Python, and added supporting syntax.\n' '\n' + '\n' + 'Type parameter lists\n' + '====================\n' + '\n' + 'New in version 3.12.\n' + '\n' + ' type_params ::= "[" type_param ("," type_param)* "]"\n' + ' type_param ::= typevar | typevartuple | paramspec\n' + ' typevar ::= identifier (":" expression)?\n' + ' typevartuple ::= "*" identifier\n' + ' paramspec ::= "**" identifier\n' + '\n' + 'Functions (including coroutines), classes and type aliases may ' + 'contain\n' + 'a type parameter list:\n' + '\n' + ' def max[T](args: list[T]) -> T:\n' + ' ...\n' + '\n' + ' async def amax[T](args: list[T]) -> T:\n' + ' ...\n' + '\n' + ' class Bag[T]:\n' + ' def __iter__(self) -> Iterator[T]:\n' + ' ...\n' + '\n' + ' def add(self, arg: T) -> None:\n' + ' ...\n' + '\n' + ' type ListOrSet[T] = list[T] | set[T]\n' + '\n' + 'Semantically, this indicates that the function, class, or type ' + 'alias\n' + 'is generic over a type variable. This information is primarily ' + 'used by\n' + 'static type checkers, and at runtime, generic objects behave ' + 'much like\n' + 'their non-generic counterparts.\n' + '\n' + 'Type parameters are declared in square brackets ("[]") ' + 'immediately\n' + 'after the name of the function, class, or type alias. The type\n' + 'parameters are accessible within the scope of the generic ' + 'object, but\n' + 'not elsewhere. Thus, after a declaration "def func[T](): pass", ' + 'the\n' + 'name "T" is not available in the module scope. Below, the ' + 'semantics of\n' + 'generic objects are described with more precision. The scope of ' + 'type\n' + 'parameters is modeled with a special function (technically, an\n' + 'annotation scope) that wraps the creation of the generic ' + 'object.\n' + '\n' + 'Generic functions, classes, and type aliases have a ' + '"__type_params__"\n' + 'attribute listing their type parameters.\n' + '\n' + 'Type parameters come in three kinds:\n' + '\n' + '* "typing.TypeVar", introduced by a plain name (e.g., "T").\n' + ' Semantically, this represents a single type to a type ' + 'checker.\n' + '\n' + '* "typing.TypeVarTuple", introduced by a name prefixed with a ' + 'single\n' + ' asterisk (e.g., "*Ts"). Semantically, this stands for a tuple ' + 'of any\n' + ' number of types.\n' + '\n' + '* "typing.ParamSpec", introduced by a name prefixed with two ' + 'asterisks\n' + ' (e.g., "**P"). Semantically, this stands for the parameters of ' + 'a\n' + ' callable.\n' + '\n' + '"typing.TypeVar" declarations can define *bounds* and ' + '*constraints*\n' + 'with a colon (":") followed by an expression. A single ' + 'expression\n' + 'after the colon indicates a bound (e.g. "T: int"). Semantically, ' + 'this\n' + 'means that the "typing.TypeVar" can only represent types that ' + 'are a\n' + 'subtype of this bound. A parenthesized tuple of expressions ' + 'after the\n' + 'colon indicates a set of constraints (e.g. "T: (str, bytes)"). ' + 'Each\n' + 'member of the tuple should be a type (again, this is not ' + 'enforced at\n' + 'runtime). Constrained type variables can only take on one of the ' + 'types\n' + 'in the list of constraints.\n' + '\n' + 'For "typing.TypeVar"s declared using the type parameter list ' + 'syntax,\n' + 'the bound and constraints are not evaluated when the generic ' + 'object is\n' + 'created, but only when the value is explicitly accessed through ' + 'the\n' + 'attributes "__bound__" and "__constraints__". To accomplish ' + 'this, the\n' + 'bounds or constraints are evaluated in a separate annotation ' + 'scope.\n' + '\n' + '"typing.TypeVarTuple"s and "typing.ParamSpec"s cannot have ' + 'bounds or\n' + 'constraints.\n' + '\n' + 'The following example indicates the full set of allowed type ' + 'parameter\n' + 'declarations:\n' + '\n' + ' def overly_generic[\n' + ' SimpleTypeVar,\n' + ' TypeVarWithBound: int,\n' + ' TypeVarWithConstraints: (str, bytes),\n' + ' *SimpleTypeVarTuple,\n' + ' **SimpleParamSpec,\n' + ' ](\n' + ' a: SimpleTypeVar,\n' + ' b: TypeVarWithBound,\n' + ' c: Callable[SimpleParamSpec, TypeVarWithConstraints],\n' + ' *d: SimpleTypeVarTuple,\n' + ' ): ...\n' + '\n' + '\n' + 'Generic functions\n' + '-----------------\n' + '\n' + 'Generic functions are declared as follows:\n' + '\n' + ' def func[T](arg: T): ...\n' + '\n' + 'This syntax is equivalent to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_func():\n' + ' T = typing.TypeVar("T")\n' + ' def func(arg: T): ...\n' + ' func.__type_params__ = (T,)\n' + ' return func\n' + ' func = TYPE_PARAMS_OF_func()\n' + '\n' + 'Here "annotation-def" indicates an annotation scope, which is ' + 'not\n' + 'actually bound to any name at runtime. (One other liberty is ' + 'taken in\n' + 'the translation: the syntax does not go through attribute access ' + 'on\n' + 'the "typing" module, but creates an instance of ' + '"typing.TypeVar"\n' + 'directly.)\n' + '\n' + 'The annotations of generic functions are evaluated within the\n' + 'annotation scope used for declaring the type parameters, but ' + 'the\n' + 'function’s defaults and decorators are not.\n' + '\n' + 'The following example illustrates the scoping rules for these ' + 'cases,\n' + 'as well as for additional flavors of type parameters:\n' + '\n' + ' @decorator\n' + ' def func[T: int, *Ts, **P](*args: *Ts, arg: Callable[P, T] = ' + 'some_default):\n' + ' ...\n' + '\n' + 'Except for the lazy evaluation of the "TypeVar" bound, this is\n' + 'equivalent to:\n' + '\n' + ' DEFAULT_OF_arg = some_default\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_func():\n' + '\n' + ' annotation-def BOUND_OF_T():\n' + ' return int\n' + ' # In reality, BOUND_OF_T() is evaluated only on demand.\n' + ' T = typing.TypeVar("T", bound=BOUND_OF_T())\n' + '\n' + ' Ts = typing.TypeVarTuple("Ts")\n' + ' P = typing.ParamSpec("P")\n' + '\n' + ' def func(*args: *Ts, arg: Callable[P, T] = ' + 'DEFAULT_OF_arg):\n' + ' ...\n' + '\n' + ' func.__type_params__ = (T, Ts, P)\n' + ' return func\n' + ' func = decorator(TYPE_PARAMS_OF_func())\n' + '\n' + 'The capitalized names like "DEFAULT_OF_arg" are not actually ' + 'bound at\n' + 'runtime.\n' + '\n' + '\n' + 'Generic classes\n' + '---------------\n' + '\n' + 'Generic classes are declared as follows:\n' + '\n' + ' class Bag[T]: ...\n' + '\n' + 'This syntax is equivalent to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_Bag():\n' + ' T = typing.TypeVar("T")\n' + ' class Bag(typing.Generic[T]):\n' + ' __type_params__ = (T,)\n' + ' ...\n' + ' return Bag\n' + ' Bag = TYPE_PARAMS_OF_Bag()\n' + '\n' + 'Here again "annotation-def" (not a real keyword) indicates an\n' + 'annotation scope, and the name "TYPE_PARAMS_OF_Bag" is not ' + 'actually\n' + 'bound at runtime.\n' + '\n' + 'Generic classes implicitly inherit from "typing.Generic". The ' + 'base\n' + 'classes and keyword arguments of generic classes are evaluated ' + 'within\n' + 'the type scope for the type parameters, and decorators are ' + 'evaluated\n' + 'outside that scope. This is illustrated by this example:\n' + '\n' + ' @decorator\n' + ' class Bag(Base[T], arg=T): ...\n' + '\n' + 'This is equivalent to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_Bag():\n' + ' T = typing.TypeVar("T")\n' + ' class Bag(Base[T], typing.Generic[T], arg=T):\n' + ' __type_params__ = (T,)\n' + ' ...\n' + ' return Bag\n' + ' Bag = decorator(TYPE_PARAMS_OF_Bag())\n' + '\n' + '\n' + 'Generic type aliases\n' + '--------------------\n' + '\n' + 'The "type" statement can also be used to create a generic type ' + 'alias:\n' + '\n' + ' type ListOrSet[T] = list[T] | set[T]\n' + '\n' + 'Except for the lazy evaluation of the value, this is equivalent ' + 'to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_ListOrSet():\n' + ' T = typing.TypeVar("T")\n' + '\n' + ' annotation-def VALUE_OF_ListOrSet():\n' + ' return list[T] | set[T]\n' + ' # In reality, the value is lazily evaluated\n' + ' return typing.TypeAliasType("ListOrSet", ' + 'VALUE_OF_ListOrSet(), type_params=(T,))\n' + ' ListOrSet = TYPE_PARAMS_OF_ListOrSet()\n' + '\n' + 'Here, "annotation-def" (not a real keyword) indicates an ' + 'annotation\n' + 'scope. The capitalized names like "TYPE_PARAMS_OF_ListOrSet" are ' + 'not\n' + 'actually bound at runtime.\n' + '\n' '-[ Footnotes ]-\n' '\n' '[1] The exception is propagated to the invocation stack unless ' @@ -3996,30 +4232,30 @@ '[2] In pattern matching, a sequence is defined as one of the\n' ' following:\n' '\n' - ' * a class that inherits from "collections.abc.Sequence"\n' + ' * a class that inherits from "collections.abc.Sequence"\n' '\n' - ' * a Python class that has been registered as\n' - ' "collections.abc.Sequence"\n' + ' * a Python class that has been registered as\n' + ' "collections.abc.Sequence"\n' '\n' - ' * a builtin class that has its (CPython) ' - '"Py_TPFLAGS_SEQUENCE"\n' - ' bit set\n' + ' * a builtin class that has its (CPython) ' + '"Py_TPFLAGS_SEQUENCE" bit\n' + ' set\n' '\n' - ' * a class that inherits from any of the above\n' + ' * a class that inherits from any of the above\n' '\n' ' The following standard library classes are sequences:\n' '\n' - ' * "array.array"\n' + ' * "array.array"\n' '\n' - ' * "collections.deque"\n' + ' * "collections.deque"\n' '\n' - ' * "list"\n' + ' * "list"\n' '\n' - ' * "memoryview"\n' + ' * "memoryview"\n' '\n' - ' * "range"\n' + ' * "range"\n' '\n' - ' * "tuple"\n' + ' * "tuple"\n' '\n' ' Note:\n' '\n' @@ -4030,16 +4266,16 @@ '[3] In pattern matching, a mapping is defined as one of the ' 'following:\n' '\n' - ' * a class that inherits from "collections.abc.Mapping"\n' + ' * a class that inherits from "collections.abc.Mapping"\n' '\n' - ' * a Python class that has been registered as\n' - ' "collections.abc.Mapping"\n' + ' * a Python class that has been registered as\n' + ' "collections.abc.Mapping"\n' '\n' - ' * a builtin class that has its (CPython) ' - '"Py_TPFLAGS_MAPPING"\n' - ' bit set\n' + ' * a builtin class that has its (CPython) ' + '"Py_TPFLAGS_MAPPING" bit\n' + ' set\n' '\n' - ' * a class that inherits from any of the above\n' + ' * a class that inherits from any of the above\n' '\n' ' The standard library classes "dict" and ' '"types.MappingProxyType"\n' @@ -4817,8 +5053,8 @@ '\n' 'pdb.pm()\n' '\n' - ' Enter post-mortem debugging of the traceback found in\n' - ' "sys.last_traceback".\n' + ' Enter post-mortem debugging of the exception found in\n' + ' "sys.last_exc".\n' '\n' 'The "run*" functions and "set_trace()" are aliases for ' 'instantiating\n' @@ -4914,6 +5150,10 @@ 'is\n' 'printed but the debugger’s state is not changed.\n' '\n' + 'Changed in version 3.13: Expressions/Statements whose prefix is ' + 'a pdb\n' + 'command are now correctly identified and executed.\n' + '\n' 'The debugger supports aliases. Aliases can have parameters ' 'which\n' 'allows one a certain level of adaptability to the context under\n' @@ -5415,6 +5655,57 @@ ' Print the return value for the last return of the current ' 'function.\n' '\n' + 'exceptions [excnumber]\n' + '\n' + ' List or jump between chained exceptions.\n' + '\n' + ' When using "pdb.pm()" or "Pdb.post_mortem(...)" with a ' + 'chained\n' + ' exception instead of a traceback, it allows the user to move\n' + ' between the chained exceptions using "exceptions" command to ' + 'list\n' + ' exceptions, and "exception " to switch to that ' + 'exception.\n' + '\n' + ' Example:\n' + '\n' + ' def out():\n' + ' try:\n' + ' middle()\n' + ' except Exception as e:\n' + ' raise ValueError("reraise middle() error") from e\n' + '\n' + ' def middle():\n' + ' try:\n' + ' return inner(0)\n' + ' except Exception as e:\n' + ' raise ValueError("Middle fail")\n' + '\n' + ' def inner(x):\n' + ' 1 / x\n' + '\n' + ' out()\n' + '\n' + ' calling "pdb.pm()" will allow to move between exceptions:\n' + '\n' + ' > example.py(5)out()\n' + ' -> raise ValueError("reraise middle() error") from e\n' + '\n' + ' (Pdb) exceptions\n' + " 0 ZeroDivisionError('division by zero')\n" + " 1 ValueError('Middle fail')\n" + " > 2 ValueError('reraise middle() error')\n" + '\n' + ' (Pdb) exceptions 0\n' + ' > example.py(16)inner()\n' + ' -> 1 / x\n' + '\n' + ' (Pdb) up\n' + ' > example.py(10)middle()\n' + ' -> return inner(0)\n' + '\n' + ' New in version 3.13.\n' + '\n' '-[ Footnotes ]-\n' '\n' '[1] Whether a frame is considered to originate in a certain ' @@ -5452,30 +5743,31 @@ 'dict': 'Dictionary displays\n' '*******************\n' '\n' - 'A dictionary display is a possibly empty series of key/datum pairs\n' - 'enclosed in curly braces:\n' + 'A dictionary display is a possibly empty series of dict items\n' + '(key/value pairs) enclosed in curly braces:\n' '\n' - ' dict_display ::= "{" [key_datum_list | dict_comprehension] ' + ' dict_display ::= "{" [dict_item_list | dict_comprehension] ' '"}"\n' - ' key_datum_list ::= key_datum ("," key_datum)* [","]\n' - ' key_datum ::= expression ":" expression | "**" or_expr\n' + ' dict_item_list ::= dict_item ("," dict_item)* [","]\n' + ' dict_item ::= expression ":" expression | "**" or_expr\n' ' dict_comprehension ::= expression ":" expression comp_for\n' '\n' 'A dictionary display yields a new dictionary object.\n' '\n' - 'If a comma-separated sequence of key/datum pairs is given, they are\n' + 'If a comma-separated sequence of dict items is given, they are\n' 'evaluated from left to right to define the entries of the ' 'dictionary:\n' 'each key object is used as a key into the dictionary to store the\n' - 'corresponding datum. This means that you can specify the same key\n' - 'multiple times in the key/datum list, and the final dictionary’s ' + 'corresponding value. This means that you can specify the same key\n' + 'multiple times in the dict item list, and the final dictionary’s ' 'value\n' 'for that key will be the last one given.\n' '\n' 'A double asterisk "**" denotes *dictionary unpacking*. Its operand\n' 'must be a *mapping*. Each mapping item is added to the new\n' - 'dictionary. Later values replace values already set by earlier\n' - 'key/datum pairs and earlier dictionary unpackings.\n' + 'dictionary. Later values replace values already set by earlier ' + 'dict\n' + 'items and earlier dictionary unpackings.\n' '\n' 'New in version 3.5: Unpacking into dictionary displays, originally\n' 'proposed by **PEP 448**.\n' @@ -5491,7 +5783,7 @@ 'Restrictions on the types of the key values are listed earlier in\n' 'section The standard type hierarchy. (To summarize, the key type\n' 'should be *hashable*, which excludes all mutable objects.) Clashes\n' - 'between duplicate keys are not detected; the last datum (textually\n' + 'between duplicate keys are not detected; the last value (textually\n' 'rightmost in the display) stored for a given key value prevails.\n' '\n' 'Changed in version 3.8: Prior to Python 3.8, in dict ' @@ -5692,6 +5984,10 @@ '\n' '* "import" statements.\n' '\n' + '* "type" statements.\n' + '\n' + '* type parameter lists.\n' + '\n' 'The "import" statement of the form "from ... import *" binds ' 'all names\n' 'defined in the imported module, except those beginning with an\n' @@ -5798,7 +6094,9 @@ 'scope.\n' '"SyntaxError" is raised at compile time if the given name does ' 'not\n' - 'exist in any enclosing function scope.\n' + 'exist in any enclosing function scope. Type parameters cannot ' + 'be\n' + 'rebound with the "nonlocal" statement.\n' '\n' 'The namespace for a module is automatically created the first ' 'time a\n' @@ -5821,17 +6119,162 @@ 'the class. The scope of names defined in a class block is ' 'limited to\n' 'the class block; it does not extend to the code blocks of ' - 'methods –\n' - 'this includes comprehensions and generator expressions since ' - 'they are\n' - 'implemented using a function scope. This means that the ' - 'following\n' - 'will fail:\n' + 'methods.\n' + 'This includes comprehensions and generator expressions, but it ' + 'does\n' + 'not include annotation scopes, which have access to their ' + 'enclosing\n' + 'class scopes. This means that the following will fail:\n' '\n' ' class A:\n' ' a = 42\n' ' b = list(a + i for i in range(10))\n' '\n' + 'However, the following will succeed:\n' + '\n' + ' class A:\n' + ' type Alias = Nested\n' + ' class Nested: pass\n' + '\n' + " print(A.Alias.__value__) # \n" + '\n' + '\n' + 'Annotation scopes\n' + '-----------------\n' + '\n' + 'Type parameter lists and "type" statements introduce ' + '*annotation\n' + 'scopes*, which behave mostly like function scopes, but with ' + 'some\n' + 'exceptions discussed below. *Annotations* currently do not use\n' + 'annotation scopes, but they are expected to use annotation ' + 'scopes in\n' + 'Python 3.13 when **PEP 649** is implemented.\n' + '\n' + 'Annotation scopes are used in the following contexts:\n' + '\n' + '* Type parameter lists for generic type aliases.\n' + '\n' + '* Type parameter lists for generic functions. A generic ' + 'function’s\n' + ' annotations are executed within the annotation scope, but ' + 'its\n' + ' defaults and decorators are not.\n' + '\n' + '* Type parameter lists for generic classes. A generic class’s ' + 'base\n' + ' classes and keyword arguments are executed within the ' + 'annotation\n' + ' scope, but its decorators are not.\n' + '\n' + '* The bounds and constraints for type variables (lazily ' + 'evaluated).\n' + '\n' + '* The value of type aliases (lazily evaluated).\n' + '\n' + 'Annotation scopes differ from function scopes in the following ' + 'ways:\n' + '\n' + '* Annotation scopes have access to their enclosing class ' + 'namespace. If\n' + ' an annotation scope is immediately within a class scope, or ' + 'within\n' + ' another annotation scope that is immediately within a class ' + 'scope,\n' + ' the code in the annotation scope can use names defined in the ' + 'class\n' + ' scope as if it were executed directly within the class body. ' + 'This\n' + ' contrasts with regular functions defined within classes, ' + 'which\n' + ' cannot access names defined in the class scope.\n' + '\n' + '* Expressions in annotation scopes cannot contain "yield", ' + '"yield\n' + ' from", "await", or ":=" expressions. (These expressions are ' + 'allowed\n' + ' in other scopes contained within the annotation scope.)\n' + '\n' + '* Names defined in annotation scopes cannot be rebound with ' + '"nonlocal"\n' + ' statements in inner scopes. This includes only type ' + 'parameters, as\n' + ' no other syntactic elements that can appear within annotation ' + 'scopes\n' + ' can introduce new names.\n' + '\n' + '* While annotation scopes have an internal name, that name is ' + 'not\n' + ' reflected in the *__qualname__* of objects defined within the ' + 'scope.\n' + ' Instead, the "__qualname__" of such objects is as if the ' + 'object were\n' + ' defined in the enclosing scope.\n' + '\n' + 'New in version 3.12: Annotation scopes were introduced in ' + 'Python 3.12\n' + 'as part of **PEP 695**.\n' + '\n' + '\n' + 'Lazy evaluation\n' + '---------------\n' + '\n' + 'The values of type aliases created through the "type" statement ' + 'are\n' + '*lazily evaluated*. The same applies to the bounds and ' + 'constraints of\n' + 'type variables created through the type parameter syntax. This ' + 'means\n' + 'that they are not evaluated when the type alias or type ' + 'variable is\n' + 'created. Instead, they are only evaluated when doing so is ' + 'necessary\n' + 'to resolve an attribute access.\n' + '\n' + 'Example:\n' + '\n' + ' >>> type Alias = 1/0\n' + ' >>> Alias.__value__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + ' >>> def func[T: 1/0](): pass\n' + ' >>> T = func.__type_params__[0]\n' + ' >>> T.__bound__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + '\n' + 'Here the exception is raised only when the "__value__" ' + 'attribute of\n' + 'the type alias or the "__bound__" attribute of the type ' + 'variable is\n' + 'accessed.\n' + '\n' + 'This behavior is primarily useful for references to types that ' + 'have\n' + 'not yet been defined when the type alias or type variable is ' + 'created.\n' + 'For example, lazy evaluation enables creation of mutually ' + 'recursive\n' + 'type aliases:\n' + '\n' + ' from typing import Literal\n' + '\n' + ' type SimpleExpr = int | Parenthesized\n' + ' type Parenthesized = tuple[Literal["("], Expr, ' + 'Literal[")"]]\n' + ' type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", ' + '"-"], Expr]\n' + '\n' + 'Lazily evaluated values are evaluated in annotation scope, ' + 'which means\n' + 'that names that appear inside the lazily evaluated value are ' + 'looked up\n' + 'as if they were used in the immediately enclosing scope.\n' + '\n' + 'New in version 3.12.\n' + '\n' '\n' 'Builtins and restricted execution\n' '---------------------------------\n' @@ -6101,18 +6544,17 @@ '\n' 'The grammar for a replacement field is as follows:\n' '\n' - ' replacement_field ::= "{" [field_name] ["!" ' - 'conversion] [":" format_spec] "}"\n' - ' field_name ::= arg_name ("." attribute_name | ' - '"[" element_index "]")*\n' - ' arg_name ::= [identifier | digit+]\n' - ' attribute_name ::= identifier\n' - ' element_index ::= digit+ | index_string\n' - ' index_string ::= +\n' - ' conversion ::= "r" | "s" | "a"\n' - ' format_spec ::= \n' + ' replacement_field ::= "{" [field_name] ["!" conversion] ' + '[":" format_spec] "}"\n' + ' field_name ::= arg_name ("." attribute_name | "[" ' + 'element_index "]")*\n' + ' arg_name ::= [identifier | digit+]\n' + ' attribute_name ::= identifier\n' + ' element_index ::= digit+ | index_string\n' + ' index_string ::= ' + '+\n' + ' conversion ::= "r" | "s" | "a"\n' + ' format_spec ::= \n' '\n' 'In less formal terms, the replacement field can start with ' 'a\n' @@ -6136,22 +6578,26 @@ 'positional\n' 'argument, and if it’s a keyword, it refers to a named ' 'keyword\n' - 'argument. If the numerical arg_names in a format string ' - 'are 0, 1, 2,\n' - '… in sequence, they can all be omitted (not just some) and ' - 'the numbers\n' - '0, 1, 2, … will be automatically inserted in that order. ' - 'Because\n' - '*arg_name* is not quote-delimited, it is not possible to ' - 'specify\n' - 'arbitrary dictionary keys (e.g., the strings "\'10\'" or ' - '"\':-]\'") within\n' - 'a format string. The *arg_name* can be followed by any ' - 'number of index\n' - 'or attribute expressions. An expression of the form ' - '"\'.name\'" selects\n' - 'the named attribute using "getattr()", while an expression ' - 'of the form\n' + 'argument. An *arg_name* is treated as a number if a call ' + 'to\n' + '"str.isdecimal()" on the string would return true. If the ' + 'numerical\n' + 'arg_names in a format string are 0, 1, 2, … in sequence, ' + 'they can all\n' + 'be omitted (not just some) and the numbers 0, 1, 2, … will ' + 'be\n' + 'automatically inserted in that order. Because *arg_name* is ' + 'not quote-\n' + 'delimited, it is not possible to specify arbitrary ' + 'dictionary keys\n' + '(e.g., the strings "\'10\'" or "\':-]\'") within a format ' + 'string. The\n' + '*arg_name* can be followed by any number of index or ' + 'attribute\n' + 'expressions. An expression of the form "\'.name\'" selects ' + 'the named\n' + 'attribute using "getattr()", while an expression of the ' + 'form\n' '"\'[index]\'" does an index lookup using "__getitem__()".\n' '\n' 'Changed in version 3.1: The positional argument specifiers ' @@ -6294,43 +6740,37 @@ 'The meaning of the various alignment options is as ' 'follows:\n' '\n' - ' ' '+-----------+------------------------------------------------------------+\n' - ' | Option | ' + '| Option | ' 'Meaning ' '|\n' - ' ' '|===========|============================================================|\n' - ' | "\'<\'" | Forces the field to be left-aligned ' - 'within the available |\n' - ' | | space (this is the default for most ' + '| "\'<\'" | Forces the field to be left-aligned within ' + 'the available |\n' + '| | space (this is the default for most ' 'objects). |\n' - ' ' '+-----------+------------------------------------------------------------+\n' - ' | "\'>\'" | Forces the field to be right-aligned ' - 'within the available |\n' - ' | | space (this is the default for ' + '| "\'>\'" | Forces the field to be right-aligned within ' + 'the available |\n' + '| | space (this is the default for ' 'numbers). |\n' - ' ' '+-----------+------------------------------------------------------------+\n' - ' | "\'=\'" | Forces the padding to be placed after ' - 'the sign (if any) |\n' - ' | | but before the digits. This is used for ' + '| "\'=\'" | Forces the padding to be placed after the ' + 'sign (if any) |\n' + '| | but before the digits. This is used for ' 'printing fields |\n' - ' | | in the form ‘+000000120’. This alignment ' + '| | in the form ‘+000000120’. This alignment ' 'option is only |\n' - ' | | valid for numeric types. It becomes the ' + '| | valid for numeric types. It becomes the ' 'default for |\n' - ' | | numbers when ‘0’ immediately precedes the ' + '| | numbers when ‘0’ immediately precedes the ' 'field width. |\n' - ' ' '+-----------+------------------------------------------------------------+\n' - ' | "\'^\'" | Forces the field to be centered within ' - 'the available |\n' - ' | | ' + '| "\'^\'" | Forces the field to be centered within the ' + 'available |\n' + '| | ' 'space. ' '|\n' - ' ' '+-----------+------------------------------------------------------------+\n' '\n' 'Note that unless a minimum field width is defined, the ' @@ -6343,30 +6783,25 @@ 'be one of\n' 'the following:\n' '\n' - ' ' '+-----------+------------------------------------------------------------+\n' - ' | Option | ' + '| Option | ' 'Meaning ' '|\n' - ' ' '|===========|============================================================|\n' - ' | "\'+\'" | indicates that a sign should be used for ' + '| "\'+\'" | indicates that a sign should be used for ' 'both positive as |\n' - ' | | well as negative ' + '| | well as negative ' 'numbers. |\n' - ' ' '+-----------+------------------------------------------------------------+\n' - ' | "\'-\'" | indicates that a sign should be used ' - 'only for negative |\n' - ' | | numbers (this is the default ' + '| "\'-\'" | indicates that a sign should be used only ' + 'for negative |\n' + '| | numbers (this is the default ' 'behavior). |\n' - ' ' '+-----------+------------------------------------------------------------+\n' - ' | space | indicates that a leading space should be ' - 'used on positive |\n' - ' | | numbers, and a minus sign on negative ' + '| space | indicates that a leading space should be used ' + 'on positive |\n' + '| | numbers, and a minus sign on negative ' 'numbers. |\n' - ' ' '+-----------+------------------------------------------------------------+\n' '\n' 'The "\'z\'" option coerces negative zero floating-point ' @@ -6872,8 +7307,8 @@ '(see\n' 'section The standard type hierarchy):\n' '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' - '[parameter_list] ")"\n' + ' funcdef ::= [decorators] "def" funcname ' + '[type_params] "(" [parameter_list] ")"\n' ' ["->" expression] ":" suite\n' ' decorators ::= decorator+\n' ' decorator ::= "@" assignment_expression ' @@ -6935,6 +7370,19 @@ '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'between the\n' + 'function’s name and the opening parenthesis for its parameter ' + 'list.\n' + 'This indicates to static type checkers that the function is ' + 'generic.\n' + 'At runtime, the type parameters can be retrieved from the ' + 'function’s\n' + '"__type_params__" attribute. See Generic functions for more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' 'When one or more *parameters* have the form *parameter* "="\n' '*expression*, the function is said to have “default parameter ' 'values.â€\n' @@ -7248,8 +7696,8 @@ '\n' 'A non-normative HTML file listing all valid identifier ' 'characters for\n' - 'Unicode 15.0.0 can be found at\n' - 'https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt\n' + 'Unicode 15.1.0 can be found at\n' + 'https://www.unicode.org/Public/15.1.0/ucd/DerivedCoreProperties.txt\n' '\n' '\n' 'Keywords\n' @@ -7277,19 +7725,24 @@ '\n' 'Some identifiers are only reserved under specific contexts. ' 'These are\n' - 'known as *soft keywords*. The identifiers "match", "case" ' - 'and "_" can\n' - 'syntactically act as keywords in contexts related to the ' - 'pattern\n' - 'matching statement, but this distinction is done at the ' - 'parser level,\n' - 'not when tokenizing.\n' + 'known as *soft keywords*. The identifiers "match", "case", ' + '"type" and\n' + '"_" can syntactically act as keywords in certain contexts, ' + 'but this\n' + 'distinction is done at the parser level, not when ' + 'tokenizing.\n' + '\n' + 'As soft keywords, their use in the grammar is possible while ' + 'still\n' + 'preserving compatibility with existing code that uses these ' + 'names as\n' + 'identifier names.\n' + '\n' + '"match", "case", and "_" are used in the "match" statement. ' + '"type" is\n' + 'used in the "type" statement.\n' '\n' - 'As soft keywords, their use with pattern matching is possible ' - 'while\n' - 'still preserving compatibility with existing code that uses ' - '"match",\n' - '"case" and "_" as identifier names.\n' + 'Changed in version 3.12: "type" is now a soft keyword.\n' '\n' '\n' 'Reserved classes of identifiers\n' @@ -7809,6 +8262,10 @@ '\n' '* "import" statements.\n' '\n' + '* "type" statements.\n' + '\n' + '* type parameter lists.\n' + '\n' 'The "import" statement of the form "from ... import *" binds all ' 'names\n' 'defined in the imported module, except those beginning with an\n' @@ -7908,7 +8365,8 @@ 'scope.\n' '"SyntaxError" is raised at compile time if the given name does ' 'not\n' - 'exist in any enclosing function scope.\n' + 'exist in any enclosing function scope. Type parameters cannot be\n' + 'rebound with the "nonlocal" statement.\n' '\n' 'The namespace for a module is automatically created the first time ' 'a\n' @@ -7930,18 +8388,156 @@ 'of\n' 'the class. The scope of names defined in a class block is limited ' 'to\n' - 'the class block; it does not extend to the code blocks of methods ' - '–\n' - 'this includes comprehensions and generator expressions since they ' - 'are\n' - 'implemented using a function scope. This means that the ' - 'following\n' - 'will fail:\n' + 'the class block; it does not extend to the code blocks of ' + 'methods.\n' + 'This includes comprehensions and generator expressions, but it ' + 'does\n' + 'not include annotation scopes, which have access to their ' + 'enclosing\n' + 'class scopes. This means that the following will fail:\n' '\n' ' class A:\n' ' a = 42\n' ' b = list(a + i for i in range(10))\n' '\n' + 'However, the following will succeed:\n' + '\n' + ' class A:\n' + ' type Alias = Nested\n' + ' class Nested: pass\n' + '\n' + " print(A.Alias.__value__) # \n" + '\n' + '\n' + 'Annotation scopes\n' + '=================\n' + '\n' + 'Type parameter lists and "type" statements introduce *annotation\n' + 'scopes*, which behave mostly like function scopes, but with some\n' + 'exceptions discussed below. *Annotations* currently do not use\n' + 'annotation scopes, but they are expected to use annotation scopes ' + 'in\n' + 'Python 3.13 when **PEP 649** is implemented.\n' + '\n' + 'Annotation scopes are used in the following contexts:\n' + '\n' + '* Type parameter lists for generic type aliases.\n' + '\n' + '* Type parameter lists for generic functions. A generic ' + 'function’s\n' + ' annotations are executed within the annotation scope, but its\n' + ' defaults and decorators are not.\n' + '\n' + '* Type parameter lists for generic classes. A generic class’s ' + 'base\n' + ' classes and keyword arguments are executed within the ' + 'annotation\n' + ' scope, but its decorators are not.\n' + '\n' + '* The bounds and constraints for type variables (lazily ' + 'evaluated).\n' + '\n' + '* The value of type aliases (lazily evaluated).\n' + '\n' + 'Annotation scopes differ from function scopes in the following ' + 'ways:\n' + '\n' + '* Annotation scopes have access to their enclosing class ' + 'namespace. If\n' + ' an annotation scope is immediately within a class scope, or ' + 'within\n' + ' another annotation scope that is immediately within a class ' + 'scope,\n' + ' the code in the annotation scope can use names defined in the ' + 'class\n' + ' scope as if it were executed directly within the class body. ' + 'This\n' + ' contrasts with regular functions defined within classes, which\n' + ' cannot access names defined in the class scope.\n' + '\n' + '* Expressions in annotation scopes cannot contain "yield", "yield\n' + ' from", "await", or ":=" expressions. (These expressions are ' + 'allowed\n' + ' in other scopes contained within the annotation scope.)\n' + '\n' + '* Names defined in annotation scopes cannot be rebound with ' + '"nonlocal"\n' + ' statements in inner scopes. This includes only type parameters, ' + 'as\n' + ' no other syntactic elements that can appear within annotation ' + 'scopes\n' + ' can introduce new names.\n' + '\n' + '* While annotation scopes have an internal name, that name is not\n' + ' reflected in the *__qualname__* of objects defined within the ' + 'scope.\n' + ' Instead, the "__qualname__" of such objects is as if the object ' + 'were\n' + ' defined in the enclosing scope.\n' + '\n' + 'New in version 3.12: Annotation scopes were introduced in Python ' + '3.12\n' + 'as part of **PEP 695**.\n' + '\n' + '\n' + 'Lazy evaluation\n' + '===============\n' + '\n' + 'The values of type aliases created through the "type" statement ' + 'are\n' + '*lazily evaluated*. The same applies to the bounds and constraints ' + 'of\n' + 'type variables created through the type parameter syntax. This ' + 'means\n' + 'that they are not evaluated when the type alias or type variable ' + 'is\n' + 'created. Instead, they are only evaluated when doing so is ' + 'necessary\n' + 'to resolve an attribute access.\n' + '\n' + 'Example:\n' + '\n' + ' >>> type Alias = 1/0\n' + ' >>> Alias.__value__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + ' >>> def func[T: 1/0](): pass\n' + ' >>> T = func.__type_params__[0]\n' + ' >>> T.__bound__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + '\n' + 'Here the exception is raised only when the "__value__" attribute ' + 'of\n' + 'the type alias or the "__bound__" attribute of the type variable ' + 'is\n' + 'accessed.\n' + '\n' + 'This behavior is primarily useful for references to types that ' + 'have\n' + 'not yet been defined when the type alias or type variable is ' + 'created.\n' + 'For example, lazy evaluation enables creation of mutually ' + 'recursive\n' + 'type aliases:\n' + '\n' + ' from typing import Literal\n' + '\n' + ' type SimpleExpr = int | Parenthesized\n' + ' type Parenthesized = tuple[Literal["("], Expr, Literal[")"]]\n' + ' type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", "-"], ' + 'Expr]\n' + '\n' + 'Lazily evaluated values are evaluated in annotation scope, which ' + 'means\n' + 'that names that appear inside the lazily evaluated value are ' + 'looked up\n' + 'as if they were used in the immediately enclosing scope.\n' + '\n' + 'New in version 3.12.\n' + '\n' '\n' 'Builtins and restricted execution\n' '=================================\n' @@ -9105,6 +9701,14 @@ '\n' ' New in version 3.3.\n' '\n' + 'definition.__type_params__\n' + '\n' + ' The type parameters of generic classes, functions, and ' + 'type\n' + ' aliases.\n' + '\n' + ' New in version 3.12.\n' + '\n' 'class.__mro__\n' '\n' ' This attribute is a tuple of classes that are considered ' @@ -9128,7 +9732,8 @@ ' still alive. The list is in definition order. Example:\n' '\n' ' >>> int.__subclasses__()\n' - " []\n", + " [, , , " + "]\n", 'specialnames': 'Special method names\n' '********************\n' '\n' @@ -9661,7 +10266,7 @@ 'would have\n' ' no way to access other attributes of the instance. Note ' 'that at\n' - ' least for instance variables, you can fake total control ' + ' least for instance variables, you can take total control ' 'by not\n' ' inserting any values in the instance attribute dictionary ' '(but\n' @@ -10019,9 +10624,7 @@ 'each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '~~~~~~~~~~~~~~~~~~~~~~~~~~\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -11951,13 +12554,19 @@ '\n' ' New in version 3.9.\n' '\n' - 'str.replace(old, new[, count])\n' + 'str.replace(old, new, count=-1)\n' '\n' ' Return a copy of the string with all occurrences of ' 'substring *old*\n' - ' replaced by *new*. If the optional argument *count* is ' - 'given, only\n' - ' the first *count* occurrences are replaced.\n' + ' replaced by *new*. If *count* is given, only the first ' + '*count*\n' + ' occurrences are replaced. If *count* is not specified ' + 'or "-1", then\n' + ' all occurrences are replaced.\n' + '\n' + ' Changed in version 3.13: *count* is now supported as a ' + 'keyword\n' + ' argument.\n' '\n' 'str.rfind(sub[, start[, end]])\n' '\n' @@ -11997,7 +12606,7 @@ 'followed by\n' ' the string itself.\n' '\n' - 'str.rsplit(sep=None, maxsplit=- 1)\n' + 'str.rsplit(sep=None, maxsplit=-1)\n' '\n' ' Return a list of the words in the string, using *sep* ' 'as the\n' @@ -12038,7 +12647,7 @@ " >>> 'Monty Python'.removesuffix(' Python')\n" " 'Monty'\n" '\n' - 'str.split(sep=None, maxsplit=- 1)\n' + 'str.split(sep=None, maxsplit=-1)\n' '\n' ' Return a list of the words in the string, using *sep* ' 'as the\n' @@ -12448,77 +13057,81 @@ 'the\n' 'literal, i.e. either "\'" or """.)\n' '\n' + '\n' + 'Escape sequences\n' + '================\n' + '\n' 'Unless an "\'r\'" or "\'R\'" prefix is present, escape sequences ' 'in string\n' 'and bytes literals are interpreted according to rules similar to ' 'those\n' 'used by Standard C. The recognized escape sequences are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\" | Backslash and newline ignored | ' - '(1) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\\" | Backslash ("\\") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\'" | Single quote ("\'") ' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\" | Backslash and newline ignored ' + '| (1) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\\" | Backslash ' + '("\\") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\'" | Single quote ' + '("\'") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\"" | Double quote (""") ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\"" | Double quote (""") ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\a" | ASCII Bell (BEL) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\a" | ASCII Bell (BEL) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\b" | ASCII Backspace (BS) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\b" | ASCII Backspace (BS) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\f" | ASCII Formfeed (FF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\f" | ASCII Formfeed (FF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\n" | ASCII Linefeed (LF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\n" | ASCII Linefeed (LF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\r" | ASCII Carriage Return (CR) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\r" | ASCII Carriage Return (CR) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\t" | ASCII Horizontal Tab (TAB) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\t" | ASCII Horizontal Tab (TAB) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\v" | ASCII Vertical Tab (VT) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\v" | ASCII Vertical Tab (VT) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\ooo" | Character with octal value *ooo* | ' - '(2,4) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\xhh" | Character with hex value *hh* | ' - '(3,4) |\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\*ooo*" | Character with octal value *ooo* ' + '| (2,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\x*hh*" | Character with hex value *hh* ' + '| (3,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Escape sequences only recognized in string literals are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\N{name}" | Character named *name* in the | ' - '(5) |\n' - '| | Unicode database | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\uxxxx" | Character with 16-bit hex value | ' - '(6) |\n' - '| | *xxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' - '(7) |\n' - '| | *xxxxxxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\N{*name*}" | Character named *name* in the ' + '| (5) |\n' + '| | Unicode database ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\u*xxxx*" | Character with 16-bit hex value ' + '| (6) |\n' + '| | *xxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\U*xxxxxxxx*" | Character with 32-bit hex value ' + '| (7) |\n' + '| | *xxxxxxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Notes:\n' '\n' @@ -12575,15 +13188,13 @@ 'bytes\n' 'literals.\n' '\n' - ' Changed in version 3.6: Unrecognized escape sequences produce ' - 'a\n' - ' "DeprecationWarning".\n' + 'Changed in version 3.6: Unrecognized escape sequences produce a\n' + '"DeprecationWarning".\n' '\n' - ' Changed in version 3.12: Unrecognized escape sequences produce ' - 'a\n' - ' "SyntaxWarning". In a future Python version they will be ' - 'eventually\n' - ' a "SyntaxError".\n' + 'Changed in version 3.12: Unrecognized escape sequences produce a\n' + '"SyntaxWarning". In a future Python version they will be ' + 'eventually a\n' + '"SyntaxError".\n' '\n' 'Even in a raw literal, quotes can be escaped with a backslash, ' 'but the\n' @@ -12697,7 +13308,7 @@ 'are\n' 'most of the built-in objects considered false:\n' '\n' - '* constants defined to be false: "None" and "False".\n' + '* constants defined to be false: "None" and "False"\n' '\n' '* zero of any numeric type: "0", "0.0", "0j", "Decimal(0)",\n' ' "Fraction(0, 1)"\n' @@ -12978,1144 +13589,1185 @@ 'definition\n' 'may change in the future.\n' '\n' + '\n' 'None\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name "None". ' - 'It\n' - ' is used to signify the absence of a value in many situations, ' - 'e.g.,\n' - ' it is returned from functions that don’t explicitly return\n' - ' anything. Its truth value is false.\n' + '====\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name "None". It ' + 'is\n' + 'used to signify the absence of a value in many situations, e.g., it ' + 'is\n' + 'returned from functions that don’t explicitly return anything. Its\n' + 'truth value is false.\n' + '\n' '\n' 'NotImplemented\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name\n' - ' "NotImplemented". Numeric methods and rich comparison methods\n' - ' should return this value if they do not implement the operation ' - 'for\n' - ' the operands provided. (The interpreter will then try the\n' - ' reflected operation, or some other fallback, depending on the\n' - ' operator.) It should not be evaluated in a boolean context.\n' + '==============\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name\n' + '"NotImplemented". Numeric methods and rich comparison methods ' + 'should\n' + 'return this value if they do not implement the operation for the\n' + 'operands provided. (The interpreter will then try the reflected\n' + 'operation, or some other fallback, depending on the operator.) It\n' + 'should not be evaluated in a boolean context.\n' '\n' - ' See Implementing the arithmetic operations for more details.\n' + 'See Implementing the arithmetic operations for more details.\n' + '\n' + 'Changed in version 3.9: Evaluating "NotImplemented" in a boolean\n' + 'context is deprecated. While it currently evaluates as true, it ' + 'will\n' + 'emit a "DeprecationWarning". It will raise a "TypeError" in a ' + 'future\n' + 'version of Python.\n' '\n' - ' Changed in version 3.9: Evaluating "NotImplemented" in a ' - 'boolean\n' - ' context is deprecated. While it currently evaluates as true, it\n' - ' will emit a "DeprecationWarning". It will raise a "TypeError" in ' - 'a\n' - ' future version of Python.\n' '\n' 'Ellipsis\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the literal "..." or the\n' - ' built-in name "Ellipsis". Its truth value is true.\n' + '========\n' '\n' - '"numbers.Number"\n' - ' These are created by numeric literals and returned as results ' - 'by\n' - ' arithmetic operators and arithmetic built-in functions. ' - 'Numeric\n' - ' objects are immutable; once created their value never changes.\n' - ' Python numbers are of course strongly related to mathematical\n' - ' numbers, but subject to the limitations of numerical ' - 'representation\n' - ' in computers.\n' - '\n' - ' The string representations of the numeric classes, computed by\n' - ' "__repr__()" and "__str__()", have the following properties:\n' - '\n' - ' * They are valid numeric literals which, when passed to their ' - 'class\n' - ' constructor, produce an object having the value of the ' - 'original\n' - ' numeric.\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the literal "..." or the ' + 'built-\n' + 'in name "Ellipsis". Its truth value is true.\n' '\n' - ' * The representation is in base 10, when possible.\n' '\n' - ' * Leading zeros, possibly excepting a single zero before a ' - 'decimal\n' - ' point, are not shown.\n' + '"numbers.Number"\n' + '================\n' '\n' - ' * Trailing zeros, possibly excepting a single zero after a ' - 'decimal\n' - ' point, are not shown.\n' + 'These are created by numeric literals and returned as results by\n' + 'arithmetic operators and arithmetic built-in functions. Numeric\n' + 'objects are immutable; once created their value never changes. ' + 'Python\n' + 'numbers are of course strongly related to mathematical numbers, ' + 'but\n' + 'subject to the limitations of numerical representation in ' + 'computers.\n' '\n' - ' * A sign is shown only when the number is negative.\n' + 'The string representations of the numeric classes, computed by\n' + '"__repr__()" and "__str__()", have the following properties:\n' '\n' - ' Python distinguishes between integers, floating point numbers, ' - 'and\n' - ' complex numbers:\n' + '* They are valid numeric literals which, when passed to their ' + 'class\n' + ' constructor, produce an object having the value of the original\n' + ' numeric.\n' '\n' - ' "numbers.Integral"\n' - ' These represent elements from the mathematical set of ' - 'integers\n' - ' (positive and negative).\n' + '* The representation is in base 10, when possible.\n' '\n' - ' There are two types of integers:\n' + '* Leading zeros, possibly excepting a single zero before a decimal\n' + ' point, are not shown.\n' '\n' - ' Integers ("int")\n' - ' These represent numbers in an unlimited range, subject to\n' - ' available (virtual) memory only. For the purpose of ' - 'shift\n' - ' and mask operations, a binary representation is assumed, ' - 'and\n' - ' negative numbers are represented in a variant of 2’s\n' - ' complement which gives the illusion of an infinite string ' - 'of\n' - ' sign bits extending to the left.\n' + '* Trailing zeros, possibly excepting a single zero after a decimal\n' + ' point, are not shown.\n' '\n' - ' Booleans ("bool")\n' - ' These represent the truth values False and True. The two\n' - ' objects representing the values "False" and "True" are ' - 'the\n' - ' only Boolean objects. The Boolean type is a subtype of ' + '* A sign is shown only when the number is negative.\n' + '\n' + 'Python distinguishes between integers, floating point numbers, and\n' + 'complex numbers:\n' + '\n' + '\n' + '"numbers.Integral"\n' + '------------------\n' + '\n' + 'These represent elements from the mathematical set of integers\n' + '(positive and negative).\n' + '\n' + 'Note:\n' + '\n' + ' The rules for integer representation are intended to give the ' + 'most\n' + ' meaningful interpretation of shift and mask operations involving\n' + ' negative integers.\n' + '\n' + 'There are two types of integers:\n' + '\n' + 'Integers ("int")\n' + ' These represent numbers in an unlimited range, subject to ' + 'available\n' + ' (virtual) memory only. For the purpose of shift and mask\n' + ' operations, a binary representation is assumed, and negative\n' + ' numbers are represented in a variant of 2’s complement which ' + 'gives\n' + ' the illusion of an infinite string of sign bits extending to ' 'the\n' - ' integer type, and Boolean values behave like the values 0 ' - 'and\n' - ' 1, respectively, in almost all contexts, the exception ' - 'being\n' - ' that when converted to a string, the strings ""False"" or\n' - ' ""True"" are returned, respectively.\n' + ' left.\n' + '\n' + 'Booleans ("bool")\n' + ' These represent the truth values False and True. The two ' + 'objects\n' + ' representing the values "False" and "True" are the only Boolean\n' + ' objects. The Boolean type is a subtype of the integer type, and\n' + ' Boolean values behave like the values 0 and 1, respectively, in\n' + ' almost all contexts, the exception being that when converted to ' + 'a\n' + ' string, the strings ""False"" or ""True"" are returned,\n' + ' respectively.\n' + '\n' '\n' - ' The rules for integer representation are intended to give ' + '"numbers.Real" ("float")\n' + '------------------------\n' + '\n' + 'These represent machine-level double precision floating point ' + 'numbers.\n' + 'You are at the mercy of the underlying machine architecture (and C ' + 'or\n' + 'Java implementation) for the accepted range and handling of ' + 'overflow.\n' + 'Python does not support single-precision floating point numbers; ' 'the\n' - ' most meaningful interpretation of shift and mask operations\n' - ' involving negative integers.\n' - '\n' - ' "numbers.Real" ("float")\n' - ' These represent machine-level double precision floating ' - 'point\n' - ' numbers. You are at the mercy of the underlying machine\n' - ' architecture (and C or Java implementation) for the accepted\n' - ' range and handling of overflow. Python does not support ' - 'single-\n' - ' precision floating point numbers; the savings in processor ' - 'and\n' - ' memory usage that are usually the reason for using these are\n' - ' dwarfed by the overhead of using objects in Python, so there ' - 'is\n' - ' no reason to complicate the language with two kinds of ' - 'floating\n' - ' point numbers.\n' - '\n' - ' "numbers.Complex" ("complex")\n' - ' These represent complex numbers as a pair of machine-level\n' - ' double precision floating point numbers. The same caveats ' - 'apply\n' - ' as for floating point numbers. The real and imaginary parts ' - 'of a\n' - ' complex number "z" can be retrieved through the read-only\n' - ' attributes "z.real" and "z.imag".\n' + 'savings in processor and memory usage that are usually the reason ' + 'for\n' + 'using these are dwarfed by the overhead of using objects in Python, ' + 'so\n' + 'there is no reason to complicate the language with two kinds of\n' + 'floating point numbers.\n' + '\n' + '\n' + '"numbers.Complex" ("complex")\n' + '-----------------------------\n' + '\n' + 'These represent complex numbers as a pair of machine-level double\n' + 'precision floating point numbers. The same caveats apply as for\n' + 'floating point numbers. The real and imaginary parts of a complex\n' + 'number "z" can be retrieved through the read-only attributes ' + '"z.real"\n' + 'and "z.imag".\n' + '\n' '\n' 'Sequences\n' - ' These represent finite ordered sets indexed by non-negative\n' - ' numbers. The built-in function "len()" returns the number of ' - 'items\n' - ' of a sequence. When the length of a sequence is *n*, the index ' + '=========\n' + '\n' + 'These represent finite ordered sets indexed by non-negative ' + 'numbers.\n' + 'The built-in function "len()" returns the number of items of a\n' + 'sequence. When the length of a sequence is *n*, the index set ' + 'contains\n' + 'the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* is selected ' + 'by\n' + '"a[i]".\n' + '\n' + 'Sequences also support slicing: "a[i:j]" selects all items with ' + 'index\n' + '*k* such that *i* "<=" *k* "<" *j*. When used as an expression, a\n' + 'slice is a sequence of the same type. This implies that the index ' 'set\n' - ' contains the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* ' - 'is\n' - ' selected by "a[i]".\n' + 'is renumbered so that it starts at 0.\n' '\n' - ' Sequences also support slicing: "a[i:j]" selects all items with\n' - ' index *k* such that *i* "<=" *k* "<" *j*. When used as an\n' - ' expression, a slice is a sequence of the same type. This ' - 'implies\n' - ' that the index set is renumbered so that it starts at 0.\n' + 'Some sequences also support “extended slicing†with a third “stepâ€\n' + 'parameter: "a[i:j:k]" selects all items of *a* with index *x* where ' + '"x\n' + '= i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' '\n' - ' Some sequences also support “extended slicing†with a third ' - '“stepâ€\n' - ' parameter: "a[i:j:k]" selects all items of *a* with index *x* ' - 'where\n' - ' "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' + 'Sequences are distinguished according to their mutability:\n' '\n' - ' Sequences are distinguished according to their mutability:\n' '\n' - ' Immutable sequences\n' - ' An object of an immutable sequence type cannot change once it ' - 'is\n' - ' created. (If the object contains references to other ' - 'objects,\n' - ' these other objects may be mutable and may be changed; ' - 'however,\n' - ' the collection of objects directly referenced by an ' - 'immutable\n' - ' object cannot change.)\n' + 'Immutable sequences\n' + '-------------------\n' '\n' - ' The following types are immutable sequences:\n' + 'An object of an immutable sequence type cannot change once it is\n' + 'created. (If the object contains references to other objects, ' + 'these\n' + 'other objects may be mutable and may be changed; however, the\n' + 'collection of objects directly referenced by an immutable object\n' + 'cannot change.)\n' '\n' - ' Strings\n' - ' A string is a sequence of values that represent Unicode ' - 'code\n' - ' points. All the code points in the range "U+0000 - ' - 'U+10FFFF"\n' - ' can be represented in a string. Python doesn’t have a ' - 'char\n' - ' type; instead, every code point in the string is ' - 'represented\n' - ' as a string object with length "1". The built-in ' - 'function\n' - ' "ord()" converts a code point from its string form to an\n' - ' integer in the range "0 - 10FFFF"; "chr()" converts an\n' - ' integer in the range "0 - 10FFFF" to the corresponding ' - 'length\n' - ' "1" string object. "str.encode()" can be used to convert ' - 'a\n' - ' "str" to "bytes" using the given text encoding, and\n' - ' "bytes.decode()" can be used to achieve the opposite.\n' + 'The following types are immutable sequences:\n' '\n' - ' Tuples\n' - ' The items of a tuple are arbitrary Python objects. Tuples ' - 'of\n' - ' two or more items are formed by comma-separated lists of\n' - ' expressions. A tuple of one item (a ‘singleton’) can be\n' - ' formed by affixing a comma to an expression (an expression ' - 'by\n' - ' itself does not create a tuple, since parentheses must be\n' - ' usable for grouping of expressions). An empty tuple can ' + 'Strings\n' + ' A string is a sequence of values that represent Unicode code\n' + ' points. All the code points in the range "U+0000 - U+10FFFF" can ' 'be\n' - ' formed by an empty pair of parentheses.\n' - '\n' - ' Bytes\n' - ' A bytes object is an immutable array. The items are ' - '8-bit\n' - ' bytes, represented by integers in the range 0 <= x < 256.\n' - ' Bytes literals (like "b\'abc\'") and the built-in ' - '"bytes()"\n' - ' constructor can be used to create bytes objects. Also, ' - 'bytes\n' - ' objects can be decoded to strings via the "decode()" ' - 'method.\n' + ' represented in a string. Python doesn’t have a char type; ' + 'instead,\n' + ' every code point in the string is represented as a string ' + 'object\n' + ' with length "1". The built-in function "ord()" converts a code\n' + ' point from its string form to an integer in the range "0 - ' + '10FFFF";\n' + ' "chr()" converts an integer in the range "0 - 10FFFF" to the\n' + ' corresponding length "1" string object. "str.encode()" can be ' + 'used\n' + ' to convert a "str" to "bytes" using the given text encoding, ' + 'and\n' + ' "bytes.decode()" can be used to achieve the opposite.\n' '\n' - ' Mutable sequences\n' - ' Mutable sequences can be changed after they are created. ' - 'The\n' - ' subscription and slicing notations can be used as the target ' + 'Tuples\n' + ' The items of a tuple are arbitrary Python objects. Tuples of two ' + 'or\n' + ' more items are formed by comma-separated lists of expressions. ' + 'A\n' + ' tuple of one item (a ‘singleton’) can be formed by affixing a ' + 'comma\n' + ' to an expression (an expression by itself does not create a ' + 'tuple,\n' + ' since parentheses must be usable for grouping of expressions). ' + 'An\n' + ' empty tuple can be formed by an empty pair of parentheses.\n' + '\n' + 'Bytes\n' + ' A bytes object is an immutable array. The items are 8-bit ' + 'bytes,\n' + ' represented by integers in the range 0 <= x < 256. Bytes ' + 'literals\n' + ' (like "b\'abc\'") and the built-in "bytes()" constructor can be ' + 'used\n' + ' to create bytes objects. Also, bytes objects can be decoded to\n' + ' strings via the "decode()" method.\n' + '\n' + '\n' + 'Mutable sequences\n' + '-----------------\n' + '\n' + 'Mutable sequences can be changed after they are created. The\n' + 'subscription and slicing notations can be used as the target of\n' + 'assignment and "del" (delete) statements.\n' + '\n' + 'Note:\n' + '\n' + ' The "collections" and "array" module provide additional examples ' 'of\n' - ' assignment and "del" (delete) statements.\n' + ' mutable sequence types.\n' '\n' - ' There are currently two intrinsic mutable sequence types:\n' + 'There are currently two intrinsic mutable sequence types:\n' '\n' - ' Lists\n' - ' The items of a list are arbitrary Python objects. Lists ' - 'are\n' - ' formed by placing a comma-separated list of expressions ' - 'in\n' - ' square brackets. (Note that there are no special cases ' - 'needed\n' - ' to form lists of length 0 or 1.)\n' + 'Lists\n' + ' The items of a list are arbitrary Python objects. Lists are ' + 'formed\n' + ' by placing a comma-separated list of expressions in square\n' + ' brackets. (Note that there are no special cases needed to form\n' + ' lists of length 0 or 1.)\n' '\n' - ' Byte Arrays\n' - ' A bytearray object is a mutable array. They are created ' - 'by\n' - ' the built-in "bytearray()" constructor. Aside from being\n' - ' mutable (and hence unhashable), byte arrays otherwise ' - 'provide\n' - ' the same interface and functionality as immutable "bytes"\n' - ' objects.\n' + 'Byte Arrays\n' + ' A bytearray object is a mutable array. They are created by the\n' + ' built-in "bytearray()" constructor. Aside from being mutable ' + '(and\n' + ' hence unhashable), byte arrays otherwise provide the same ' + 'interface\n' + ' and functionality as immutable "bytes" objects.\n' '\n' - ' The extension module "array" provides an additional example ' - 'of a\n' - ' mutable sequence type, as does the "collections" module.\n' '\n' 'Set types\n' - ' These represent unordered, finite sets of unique, immutable\n' - ' objects. As such, they cannot be indexed by any subscript. ' - 'However,\n' - ' they can be iterated over, and the built-in function "len()"\n' - ' returns the number of items in a set. Common uses for sets are ' - 'fast\n' - ' membership testing, removing duplicates from a sequence, and\n' - ' computing mathematical operations such as intersection, union,\n' - ' difference, and symmetric difference.\n' - '\n' - ' For set elements, the same immutability rules apply as for\n' - ' dictionary keys. Note that numeric types obey the normal rules ' - 'for\n' - ' numeric comparison: if two numbers compare equal (e.g., "1" and\n' - ' "1.0"), only one of them can be contained in a set.\n' + '=========\n' '\n' - ' There are currently two intrinsic set types:\n' + 'These represent unordered, finite sets of unique, immutable ' + 'objects.\n' + 'As such, they cannot be indexed by any subscript. However, they can ' + 'be\n' + 'iterated over, and the built-in function "len()" returns the number ' + 'of\n' + 'items in a set. Common uses for sets are fast membership testing,\n' + 'removing duplicates from a sequence, and computing mathematical\n' + 'operations such as intersection, union, difference, and symmetric\n' + 'difference.\n' + '\n' + 'For set elements, the same immutability rules apply as for ' + 'dictionary\n' + 'keys. Note that numeric types obey the normal rules for numeric\n' + 'comparison: if two numbers compare equal (e.g., "1" and "1.0"), ' + 'only\n' + 'one of them can be contained in a set.\n' + '\n' + 'There are currently two intrinsic set types:\n' '\n' - ' Sets\n' - ' These represent a mutable set. They are created by the ' + 'Sets\n' + ' These represent a mutable set. They are created by the built-in\n' + ' "set()" constructor and can be modified afterwards by several\n' + ' methods, such as "add()".\n' + '\n' + 'Frozen sets\n' + ' These represent an immutable set. They are created by the ' 'built-in\n' - ' "set()" constructor and can be modified afterwards by ' - 'several\n' - ' methods, such as "add()".\n' - '\n' - ' Frozen sets\n' - ' These represent an immutable set. They are created by the\n' - ' built-in "frozenset()" constructor. As a frozenset is ' - 'immutable\n' - ' and *hashable*, it can be used again as an element of ' - 'another\n' - ' set, or as a dictionary key.\n' + ' "frozenset()" constructor. As a frozenset is immutable and\n' + ' *hashable*, it can be used again as an element of another set, ' + 'or\n' + ' as a dictionary key.\n' + '\n' '\n' 'Mappings\n' - ' These represent finite sets of objects indexed by arbitrary ' - 'index\n' - ' sets. The subscript notation "a[k]" selects the item indexed by ' + '========\n' + '\n' + 'These represent finite sets of objects indexed by arbitrary index\n' + 'sets. The subscript notation "a[k]" selects the item indexed by ' '"k"\n' - ' from the mapping "a"; this can be used in expressions and as ' - 'the\n' - ' target of assignments or "del" statements. The built-in ' - 'function\n' - ' "len()" returns the number of items in a mapping.\n' + 'from the mapping "a"; this can be used in expressions and as the\n' + 'target of assignments or "del" statements. The built-in function\n' + '"len()" returns the number of items in a mapping.\n' '\n' - ' There is currently a single intrinsic mapping type:\n' + 'There is currently a single intrinsic mapping type:\n' '\n' - ' Dictionaries\n' - ' These represent finite sets of objects indexed by nearly\n' - ' arbitrary values. The only types of values not acceptable ' - 'as\n' - ' keys are values containing lists or dictionaries or other\n' - ' mutable types that are compared by value rather than by ' - 'object\n' - ' identity, the reason being that the efficient implementation ' - 'of\n' - ' dictionaries requires a key’s hash value to remain constant.\n' - ' Numeric types used for keys obey the normal rules for ' - 'numeric\n' - ' comparison: if two numbers compare equal (e.g., "1" and ' - '"1.0")\n' - ' then they can be used interchangeably to index the same\n' - ' dictionary entry.\n' - '\n' - ' Dictionaries preserve insertion order, meaning that keys will ' - 'be\n' - ' produced in the same order they were added sequentially over ' - 'the\n' - ' dictionary. Replacing an existing key does not change the ' - 'order,\n' - ' however removing a key and re-inserting it will add it to ' + '\n' + 'Dictionaries\n' + '------------\n' + '\n' + 'These represent finite sets of objects indexed by nearly arbitrary\n' + 'values. The only types of values not acceptable as keys are ' + 'values\n' + 'containing lists or dictionaries or other mutable types that are\n' + 'compared by value rather than by object identity, the reason being\n' + 'that the efficient implementation of dictionaries requires a key’s\n' + 'hash value to remain constant. Numeric types used for keys obey ' 'the\n' - ' end instead of keeping its old place.\n' + 'normal rules for numeric comparison: if two numbers compare equal\n' + '(e.g., "1" and "1.0") then they can be used interchangeably to ' + 'index\n' + 'the same dictionary entry.\n' '\n' - ' Dictionaries are mutable; they can be created by the "{...}"\n' - ' notation (see section Dictionary displays).\n' + 'Dictionaries preserve insertion order, meaning that keys will be\n' + 'produced in the same order they were added sequentially over the\n' + 'dictionary. Replacing an existing key does not change the order,\n' + 'however removing a key and re-inserting it will add it to the end\n' + 'instead of keeping its old place.\n' '\n' - ' The extension modules "dbm.ndbm" and "dbm.gnu" provide\n' - ' additional examples of mapping types, as does the ' - '"collections"\n' - ' module.\n' + 'Dictionaries are mutable; they can be created by the "{...}" ' + 'notation\n' + '(see section Dictionary displays).\n' + '\n' + 'The extension modules "dbm.ndbm" and "dbm.gnu" provide additional\n' + 'examples of mapping types, as does the "collections" module.\n' + '\n' + 'Changed in version 3.7: Dictionaries did not preserve insertion ' + 'order\n' + 'in versions of Python before 3.6. In CPython 3.6, insertion order ' + 'was\n' + 'preserved, but it was considered an implementation detail at that ' + 'time\n' + 'rather than a language guarantee.\n' '\n' - ' Changed in version 3.7: Dictionaries did not preserve ' - 'insertion\n' - ' order in versions of Python before 3.6. In CPython 3.6,\n' - ' insertion order was preserved, but it was considered an\n' - ' implementation detail at that time rather than a language\n' - ' guarantee.\n' '\n' 'Callable types\n' - ' These are the types to which the function call operation (see\n' - ' section Calls) can be applied:\n' + '==============\n' '\n' - ' User-defined functions\n' - ' A user-defined function object is created by a function\n' - ' definition (see section Function definitions). It should be\n' - ' called with an argument list containing the same number of ' - 'items\n' - ' as the function’s formal parameter list.\n' + 'These are the types to which the function call operation (see ' + 'section\n' + 'Calls) can be applied:\n' + '\n' + '\n' + 'User-defined functions\n' + '----------------------\n' + '\n' + 'A user-defined function object is created by a function definition\n' + '(see section Function definitions). It should be called with an\n' + 'argument list containing the same number of items as the ' + 'function’s\n' + 'formal parameter list.\n' '\n' - ' Special attributes:\n' + 'Special attributes:\n' '\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | Attribute | Meaning ' + '| Attribute | Meaning ' '| |\n' - ' ' '|===========================|=================================|=============|\n' - ' | "__doc__" | The function’s documentation ' - '| Writable |\n' - ' | | string, or "None" if ' + '| "__doc__" | The function’s documentation | ' + 'Writable |\n' + '| | string, or "None" if ' '| |\n' - ' | | unavailable; not inherited by ' + '| | unavailable; not inherited by ' '| |\n' - ' | | subclasses. ' + '| | subclasses. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__name__" | The function’s name. ' - '| Writable |\n' - ' ' + '| "__name__" | The function’s name. | ' + 'Writable |\n' '+---------------------------+---------------------------------+-------------+\n' - ' | "__qualname__" | The function’s *qualified ' - '| Writable |\n' - ' | | name*. New in version 3.3. ' + '| "__qualname__" | The function’s *qualified | ' + 'Writable |\n' + '| | name*. New in version 3.3. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__module__" | The name of the module the ' - '| Writable |\n' - ' | | function was defined in, or ' + '| "__module__" | The name of the module the | ' + 'Writable |\n' + '| | function was defined in, or ' '| |\n' - ' | | "None" if unavailable. ' + '| | "None" if unavailable. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__defaults__" | A tuple containing default ' - '| Writable |\n' - ' | | argument values for those ' + '| "__defaults__" | A tuple containing default | ' + 'Writable |\n' + '| | argument values for those ' '| |\n' - ' | | arguments that have defaults, ' + '| | arguments that have defaults, ' '| |\n' - ' | | or "None" if no arguments have ' + '| | or "None" if no arguments have ' '| |\n' - ' | | a default value. ' + '| | a default value. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__code__" | The code object representing ' - '| Writable |\n' - ' | | the compiled function body. ' + '| "__code__" | The code object representing | ' + 'Writable |\n' + '| | the compiled function body. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__globals__" | A reference to the dictionary ' - '| Read-only |\n' - ' | | that holds the function’s ' + '| "__globals__" | A reference to the dictionary | ' + 'Read-only |\n' + '| | that holds the function’s ' '| |\n' - ' | | global variables — the global ' + '| | global variables — the global ' '| |\n' - ' | | namespace of the module in ' + '| | namespace of the module in ' '| |\n' - ' | | which the function was defined. ' + '| | which the function was defined. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__dict__" | The namespace supporting ' - '| Writable |\n' - ' | | arbitrary function attributes. ' + '| "__dict__" | The namespace supporting | ' + 'Writable |\n' + '| | arbitrary function attributes. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__closure__" | "None" or a tuple of cells that ' - '| Read-only |\n' - ' | | contain bindings for the ' + '| "__closure__" | "None" or a tuple of cells that | ' + 'Read-only |\n' + '| | contain bindings for the ' '| |\n' - ' | | function’s free variables. See ' + '| | function’s free variables. See ' '| |\n' - ' | | below for information on the ' + '| | below for information on the ' '| |\n' - ' | | "cell_contents" attribute. ' + '| | "cell_contents" attribute. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__annotations__" | A dict containing annotations ' - '| Writable |\n' - ' | | of parameters. The keys of the ' + '| "__annotations__" | A dict containing annotations | ' + 'Writable |\n' + '| | of parameters. The keys of the ' '| |\n' - ' | | dict are the parameter names, ' + '| | dict are the parameter names, ' '| |\n' - ' | | and "\'return\'" for the ' - 'return | |\n' - ' | | annotation, if provided. For ' + '| | and "\'return\'" for the return ' '| |\n' - ' | | more information on working ' + '| | annotation, if provided. For ' '| |\n' - ' | | with this attribute, see ' + '| | more information on working ' '| |\n' - ' | | Annotations Best Practices. ' + '| | with this attribute, see ' + '| |\n' + '| | Annotations Best Practices. ' + '| |\n' + '+---------------------------+---------------------------------+-------------+\n' + '| "__kwdefaults__" | A dict containing defaults for | ' + 'Writable |\n' + '| | keyword-only parameters. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__kwdefaults__" | A dict containing defaults for ' - '| Writable |\n' - ' | | keyword-only parameters. ' + '| "__type_params__" | A tuple containing the type | ' + 'Writable |\n' + '| | parameters of a generic ' + '| |\n' + '| | function. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' '\n' - ' Most of the attributes labelled “Writable†check the type of ' - 'the\n' - ' assigned value.\n' + 'Most of the attributes labelled “Writable†check the type of the\n' + 'assigned value.\n' '\n' - ' Function objects also support getting and setting arbitrary\n' - ' attributes, which can be used, for example, to attach ' - 'metadata\n' - ' to functions. Regular attribute dot-notation is used to get ' - 'and\n' - ' set such attributes. *Note that the current implementation ' - 'only\n' - ' supports function attributes on user-defined functions. ' - 'Function\n' - ' attributes on built-in functions may be supported in the\n' - ' future.*\n' - '\n' - ' A cell object has the attribute "cell_contents". This can be\n' - ' used to get the value of the cell, as well as set the value.\n' - '\n' - ' Additional information about a function’s definition can be\n' - ' retrieved from its code object; see the description of ' - 'internal\n' - ' types below. The "cell" type can be accessed in the "types"\n' - ' module.\n' - '\n' - ' Instance methods\n' - ' An instance method object combines a class, a class instance ' - 'and\n' - ' any callable object (normally a user-defined function).\n' - '\n' - ' Special read-only attributes: "__self__" is the class ' - 'instance\n' - ' object, "__func__" is the function object; "__doc__" is the\n' - ' method’s documentation (same as "__func__.__doc__"); ' - '"__name__"\n' - ' is the method name (same as "__func__.__name__"); ' - '"__module__"\n' - ' is the name of the module the method was defined in, or ' - '"None"\n' - ' if unavailable.\n' + 'Function objects also support getting and setting arbitrary\n' + 'attributes, which can be used, for example, to attach metadata to\n' + 'functions. Regular attribute dot-notation is used to get and set ' + 'such\n' + 'attributes. *Note that the current implementation only supports\n' + 'function attributes on user-defined functions. Function attributes ' + 'on\n' + 'built-in functions may be supported in the future.*\n' '\n' - ' Methods also support accessing (but not setting) the ' - 'arbitrary\n' - ' function attributes on the underlying function object.\n' + 'A cell object has the attribute "cell_contents". This can be used ' + 'to\n' + 'get the value of the cell, as well as set the value.\n' '\n' - ' User-defined method objects may be created when getting an\n' - ' attribute of a class (perhaps via an instance of that class), ' - 'if\n' - ' that attribute is a user-defined function object or a class\n' - ' method object.\n' - '\n' - ' When an instance method object is created by retrieving a ' - 'user-\n' - ' defined function object from a class via one of its ' - 'instances,\n' - ' its "__self__" attribute is the instance, and the method ' - 'object\n' - ' is said to be bound. The new method’s "__func__" attribute ' - 'is\n' - ' the original function object.\n' + 'Additional information about a function’s definition can be ' + 'retrieved\n' + 'from its code object; see the description of internal types below. ' + 'The\n' + '"cell" type can be accessed in the "types" module.\n' '\n' - ' When an instance method object is created by retrieving a ' - 'class\n' - ' method object from a class or instance, its "__self__" ' - 'attribute\n' - ' is the class itself, and its "__func__" attribute is the\n' - ' function object underlying the class method.\n' '\n' - ' When an instance method object is called, the underlying\n' - ' function ("__func__") is called, inserting the class ' - 'instance\n' - ' ("__self__") in front of the argument list. For instance, ' - 'when\n' - ' "C" is a class which contains a definition for a function ' - '"f()",\n' - ' and "x" is an instance of "C", calling "x.f(1)" is equivalent ' - 'to\n' - ' calling "C.f(x, 1)".\n' + 'Instance methods\n' + '----------------\n' + '\n' + 'An instance method object combines a class, a class instance and ' + 'any\n' + 'callable object (normally a user-defined function).\n' '\n' - ' When an instance method object is derived from a class ' + 'Special read-only attributes: "__self__" is the class instance ' + 'object,\n' + '"__func__" is the function object; "__doc__" is the method’s\n' + 'documentation (same as "__func__.__doc__"); "__name__" is the ' 'method\n' - ' object, the “class instance†stored in "__self__" will ' - 'actually\n' - ' be the class itself, so that calling either "x.f(1)" or ' - '"C.f(1)"\n' - ' is equivalent to calling "f(C,1)" where "f" is the ' - 'underlying\n' - ' function.\n' - '\n' - ' Note that the transformation from function object to ' - 'instance\n' - ' method object happens each time the attribute is retrieved ' - 'from\n' - ' the instance. In some cases, a fruitful optimization is to\n' - ' assign the attribute to a local variable and call that local\n' - ' variable. Also notice that this transformation only happens ' - 'for\n' - ' user-defined functions; other callable objects (and all non-\n' - ' callable objects) are retrieved without transformation. It ' - 'is\n' - ' also important to note that user-defined functions which are\n' - ' attributes of a class instance are not converted to bound\n' - ' methods; this *only* happens when the function is an ' + 'name (same as "__func__.__name__"); "__module__" is the name of ' + 'the\n' + 'module the method was defined in, or "None" if unavailable.\n' + '\n' + 'Methods also support accessing (but not setting) the arbitrary\n' + 'function attributes on the underlying function object.\n' + '\n' + 'User-defined method objects may be created when getting an ' + 'attribute\n' + 'of a class (perhaps via an instance of that class), if that ' 'attribute\n' - ' of the class.\n' + 'is a user-defined function object or a class method object.\n' '\n' - ' Generator functions\n' - ' A function or method which uses the "yield" statement (see\n' - ' section The yield statement) is called a *generator ' - 'function*.\n' - ' Such a function, when called, always returns an *iterator*\n' - ' object which can be used to execute the body of the ' - 'function:\n' - ' calling the iterator’s "iterator.__next__()" method will ' - 'cause\n' - ' the function to execute until it provides a value using the\n' - ' "yield" statement. When the function executes a "return"\n' - ' statement or falls off the end, a "StopIteration" exception ' - 'is\n' - ' raised and the iterator will have reached the end of the set ' + 'When an instance method object is created by retrieving a ' + 'user-defined\n' + 'function object from a class via one of its instances, its ' + '"__self__"\n' + 'attribute is the instance, and the method object is said to be ' + 'bound.\n' + 'The new method’s "__func__" attribute is the original function ' + 'object.\n' + '\n' + 'When an instance method object is created by retrieving a class ' + 'method\n' + 'object from a class or instance, its "__self__" attribute is the ' + 'class\n' + 'itself, and its "__func__" attribute is the function object ' + 'underlying\n' + 'the class method.\n' + '\n' + 'When an instance method object is called, the underlying function\n' + '("__func__") is called, inserting the class instance ("__self__") ' + 'in\n' + 'front of the argument list. For instance, when "C" is a class ' + 'which\n' + 'contains a definition for a function "f()", and "x" is an instance ' 'of\n' - ' values to be returned.\n' - '\n' - ' Coroutine functions\n' - ' A function or method which is defined using "async def" is\n' - ' called a *coroutine function*. Such a function, when ' - 'called,\n' - ' returns a *coroutine* object. It may contain "await"\n' - ' expressions, as well as "async with" and "async for" ' - 'statements.\n' - ' See also the Coroutine Objects section.\n' - '\n' - ' Asynchronous generator functions\n' - ' A function or method which is defined using "async def" and\n' - ' which uses the "yield" statement is called a *asynchronous\n' - ' generator function*. Such a function, when called, returns ' - 'an\n' - ' *asynchronous iterator* object which can be used in an ' - '"async\n' - ' for" statement to execute the body of the function.\n' + '"C", calling "x.f(1)" is equivalent to calling "C.f(x, 1)".\n' '\n' - ' Calling the asynchronous iterator’s "aiterator.__anext__" ' + 'When an instance method object is derived from a class method ' + 'object,\n' + 'the “class instance†stored in "__self__" will actually be the ' + 'class\n' + 'itself, so that calling either "x.f(1)" or "C.f(1)" is equivalent ' + 'to\n' + 'calling "f(C,1)" where "f" is the underlying function.\n' + '\n' + 'Note that the transformation from function object to instance ' 'method\n' - ' will return an *awaitable* which when awaited will execute ' + 'object happens each time the attribute is retrieved from the ' + 'instance.\n' + 'In some cases, a fruitful optimization is to assign the attribute ' + 'to a\n' + 'local variable and call that local variable. Also notice that this\n' + 'transformation only happens for user-defined functions; other ' + 'callable\n' + 'objects (and all non-callable objects) are retrieved without\n' + 'transformation. It is also important to note that user-defined\n' + 'functions which are attributes of a class instance are not ' + 'converted\n' + 'to bound methods; this *only* happens when the function is an\n' + 'attribute of the class.\n' + '\n' + '\n' + 'Generator functions\n' + '-------------------\n' + '\n' + 'A function or method which uses the "yield" statement (see section ' + 'The\n' + 'yield statement) is called a *generator function*. Such a ' + 'function,\n' + 'when called, always returns an *iterator* object which can be used ' + 'to\n' + 'execute the body of the function: calling the iterator’s\n' + '"iterator.__next__()" method will cause the function to execute ' 'until\n' - ' it provides a value using the "yield" expression. When the\n' - ' function executes an empty "return" statement or falls off ' + 'it provides a value using the "yield" statement. When the ' + 'function\n' + 'executes a "return" statement or falls off the end, a ' + '"StopIteration"\n' + 'exception is raised and the iterator will have reached the end of ' 'the\n' - ' end, a "StopAsyncIteration" exception is raised and the\n' - ' asynchronous iterator will have reached the end of the set ' - 'of\n' - ' values to be yielded.\n' + 'set of values to be returned.\n' '\n' - ' Built-in functions\n' - ' A built-in function object is a wrapper around a C function.\n' - ' Examples of built-in functions are "len()" and "math.sin()"\n' - ' ("math" is a standard built-in module). The number and type ' - 'of\n' - ' the arguments are determined by the C function. Special ' - 'read-\n' - ' only attributes: "__doc__" is the function’s documentation\n' - ' string, or "None" if unavailable; "__name__" is the ' - 'function’s\n' - ' name; "__self__" is set to "None" (but see the next item);\n' - ' "__module__" is the name of the module the function was ' - 'defined\n' - ' in or "None" if unavailable.\n' '\n' - ' Built-in methods\n' - ' This is really a different disguise of a built-in function, ' - 'this\n' - ' time containing an object passed to the C function as an\n' - ' implicit extra argument. An example of a built-in method is\n' - ' "alist.append()", assuming *alist* is a list object. In this\n' - ' case, the special read-only attribute "__self__" is set to ' + 'Coroutine functions\n' + '-------------------\n' + '\n' + 'A function or method which is defined using "async def" is called ' + 'a\n' + '*coroutine function*. Such a function, when called, returns a\n' + '*coroutine* object. It may contain "await" expressions, as well ' + 'as\n' + '"async with" and "async for" statements. See also the Coroutine\n' + 'Objects section.\n' + '\n' + '\n' + 'Asynchronous generator functions\n' + '--------------------------------\n' + '\n' + 'A function or method which is defined using "async def" and which ' + 'uses\n' + 'the "yield" statement is called a *asynchronous generator ' + 'function*.\n' + 'Such a function, when called, returns an *asynchronous iterator*\n' + 'object which can be used in an "async for" statement to execute ' 'the\n' - ' object denoted by *alist*.\n' + 'body of the function.\n' '\n' - ' Classes\n' - ' Classes are callable. These objects normally act as ' - 'factories\n' - ' for new instances of themselves, but variations are possible ' - 'for\n' - ' class types that override "__new__()". The arguments of the\n' - ' call are passed to "__new__()" and, in the typical case, to\n' - ' "__init__()" to initialize the new instance.\n' + 'Calling the asynchronous iterator’s "aiterator.__anext__" method ' + 'will\n' + 'return an *awaitable* which when awaited will execute until it\n' + 'provides a value using the "yield" expression. When the function\n' + 'executes an empty "return" statement or falls off the end, a\n' + '"StopAsyncIteration" exception is raised and the asynchronous ' + 'iterator\n' + 'will have reached the end of the set of values to be yielded.\n' + '\n' + '\n' + 'Built-in functions\n' + '------------------\n' + '\n' + 'A built-in function object is a wrapper around a C function. ' + 'Examples\n' + 'of built-in functions are "len()" and "math.sin()" ("math" is a\n' + 'standard built-in module). The number and type of the arguments ' + 'are\n' + 'determined by the C function. Special read-only attributes: ' + '"__doc__"\n' + 'is the function’s documentation string, or "None" if unavailable;\n' + '"__name__" is the function’s name; "__self__" is set to "None" ' + '(but\n' + 'see the next item); "__module__" is the name of the module the\n' + 'function was defined in or "None" if unavailable.\n' + '\n' + '\n' + 'Built-in methods\n' + '----------------\n' + '\n' + 'This is really a different disguise of a built-in function, this ' + 'time\n' + 'containing an object passed to the C function as an implicit extra\n' + 'argument. An example of a built-in method is "alist.append()",\n' + 'assuming *alist* is a list object. In this case, the special ' + 'read-only\n' + 'attribute "__self__" is set to the object denoted by *alist*.\n' + '\n' + '\n' + 'Classes\n' + '-------\n' + '\n' + 'Classes are callable. These objects normally act as factories for ' + 'new\n' + 'instances of themselves, but variations are possible for class ' + 'types\n' + 'that override "__new__()". The arguments of the call are passed ' + 'to\n' + '"__new__()" and, in the typical case, to "__init__()" to ' + 'initialize\n' + 'the new instance.\n' + '\n' + '\n' + 'Class Instances\n' + '---------------\n' + '\n' + 'Instances of arbitrary classes can be made callable by defining a\n' + '"__call__()" method in their class.\n' '\n' - ' Class Instances\n' - ' Instances of arbitrary classes can be made callable by ' - 'defining\n' - ' a "__call__()" method in their class.\n' '\n' 'Modules\n' - ' Modules are a basic organizational unit of Python code, and are\n' - ' created by the import system as invoked either by the "import"\n' - ' statement, or by calling functions such as\n' - ' "importlib.import_module()" and built-in "__import__()". A ' - 'module\n' - ' object has a namespace implemented by a dictionary object (this ' - 'is\n' - ' the dictionary referenced by the "__globals__" attribute of\n' - ' functions defined in the module). Attribute references are\n' - ' translated to lookups in this dictionary, e.g., "m.x" is ' - 'equivalent\n' - ' to "m.__dict__["x"]". A module object does not contain the code\n' - ' object used to initialize the module (since it isn’t needed ' - 'once\n' - ' the initialization is done).\n' + '=======\n' + '\n' + 'Modules are a basic organizational unit of Python code, and are\n' + 'created by the import system as invoked either by the "import"\n' + 'statement, or by calling functions such as ' + '"importlib.import_module()"\n' + 'and built-in "__import__()". A module object has a namespace\n' + 'implemented by a dictionary object (this is the dictionary ' + 'referenced\n' + 'by the "__globals__" attribute of functions defined in the ' + 'module).\n' + 'Attribute references are translated to lookups in this dictionary,\n' + 'e.g., "m.x" is equivalent to "m.__dict__["x"]". A module object ' + 'does\n' + 'not contain the code object used to initialize the module (since ' + 'it\n' + 'isn’t needed once the initialization is done).\n' + '\n' + 'Attribute assignment updates the module’s namespace dictionary, ' + 'e.g.,\n' + '"m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' '\n' - ' Attribute assignment updates the module’s namespace dictionary,\n' - ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' + 'Predefined (writable) attributes:\n' '\n' - ' Predefined (writable) attributes:\n' + ' "__name__"\n' + ' The module’s name.\n' '\n' - ' "__name__"\n' - ' The module’s name.\n' + ' "__doc__"\n' + ' The module’s documentation string, or "None" if unavailable.\n' '\n' - ' "__doc__"\n' - ' The module’s documentation string, or "None" if ' - 'unavailable.\n' + ' "__file__"\n' + ' The pathname of the file from which the module was loaded, if ' + 'it\n' + ' was loaded from a file. The "__file__" attribute may be ' + 'missing\n' + ' for certain types of modules, such as C modules that are\n' + ' statically linked into the interpreter. For extension ' + 'modules\n' + ' loaded dynamically from a shared library, it’s the pathname ' + 'of\n' + ' the shared library file.\n' '\n' - ' "__file__"\n' - ' The pathname of the file from which the module was loaded, ' - 'if\n' - ' it was loaded from a file. The "__file__" attribute may ' - 'be\n' - ' missing for certain types of modules, such as C modules ' - 'that\n' - ' are statically linked into the interpreter. For ' - 'extension\n' - ' modules loaded dynamically from a shared library, it’s ' - 'the\n' - ' pathname of the shared library file.\n' - '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during module body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' - '\n' - ' Special read-only attribute: "__dict__" is the module’s ' - 'namespace\n' - ' as a dictionary object.\n' - '\n' - ' **CPython implementation detail:** Because of the way CPython\n' - ' clears module dictionaries, the module dictionary will be ' - 'cleared\n' - ' when the module falls out of scope even if the dictionary still ' - 'has\n' - ' live references. To avoid this, copy the dictionary or keep ' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' module body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' + '\n' + 'Special read-only attribute: "__dict__" is the module’s namespace ' + 'as a\n' + 'dictionary object.\n' + '\n' + '**CPython implementation detail:** Because of the way CPython ' + 'clears\n' + 'module dictionaries, the module dictionary will be cleared when ' 'the\n' - ' module around while using its dictionary directly.\n' + 'module falls out of scope even if the dictionary still has live\n' + 'references. To avoid this, copy the dictionary or keep the module\n' + 'around while using its dictionary directly.\n' + '\n' '\n' 'Custom classes\n' - ' Custom class types are typically created by class definitions ' - '(see\n' - ' section Class definitions). A class has a namespace implemented ' - 'by\n' - ' a dictionary object. Class attribute references are translated ' - 'to\n' - ' lookups in this dictionary, e.g., "C.x" is translated to\n' - ' "C.__dict__["x"]" (although there are a number of hooks which ' + '==============\n' + '\n' + 'Custom class types are typically created by class definitions (see\n' + 'section Class definitions). A class has a namespace implemented by ' + 'a\n' + 'dictionary object. Class attribute references are translated to\n' + 'lookups in this dictionary, e.g., "C.x" is translated to\n' + '"C.__dict__["x"]" (although there are a number of hooks which ' 'allow\n' - ' for other means of locating attributes). When the attribute name ' + 'for other means of locating attributes). When the attribute name ' 'is\n' - ' not found there, the attribute search continues in the base\n' - ' classes. This search of the base classes uses the C3 method\n' - ' resolution order which behaves correctly even in the presence ' - 'of\n' - ' ‘diamond’ inheritance structures where there are multiple\n' - ' inheritance paths leading back to a common ancestor. Additional\n' - ' details on the C3 MRO used by Python can be found in the\n' - ' documentation accompanying the 2.3 release at\n' - ' https://www.python.org/download/releases/2.3/mro/.\n' - '\n' - ' When a class attribute reference (for class "C", say) would ' - 'yield a\n' - ' class method object, it is transformed into an instance method\n' - ' object whose "__self__" attribute is "C". When it would yield ' + 'not found there, the attribute search continues in the base ' + 'classes.\n' + 'This search of the base classes uses the C3 method resolution ' + 'order\n' + 'which behaves correctly even in the presence of ‘diamond’ ' + 'inheritance\n' + 'structures where there are multiple inheritance paths leading back ' + 'to\n' + 'a common ancestor. Additional details on the C3 MRO used by Python ' + 'can\n' + 'be found in the documentation accompanying the 2.3 release at\n' + 'https://www.python.org/download/releases/2.3/mro/.\n' + '\n' + 'When a class attribute reference (for class "C", say) would yield ' 'a\n' - ' static method object, it is transformed into the object wrapped ' - 'by\n' - ' the static method object. See section Implementing Descriptors ' - 'for\n' - ' another way in which attributes retrieved from a class may ' - 'differ\n' - ' from those actually contained in its "__dict__".\n' + 'class method object, it is transformed into an instance method ' + 'object\n' + 'whose "__self__" attribute is "C". When it would yield a static\n' + 'method object, it is transformed into the object wrapped by the ' + 'static\n' + 'method object. See section Implementing Descriptors for another way ' + 'in\n' + 'which attributes retrieved from a class may differ from those ' + 'actually\n' + 'contained in its "__dict__".\n' '\n' - ' Class attribute assignments update the class’s dictionary, ' - 'never\n' - ' the dictionary of a base class.\n' + 'Class attribute assignments update the class’s dictionary, never ' + 'the\n' + 'dictionary of a base class.\n' '\n' - ' A class object can be called (see above) to yield a class ' - 'instance\n' - ' (see below).\n' + 'A class object can be called (see above) to yield a class instance\n' + '(see below).\n' '\n' - ' Special attributes:\n' + 'Special attributes:\n' '\n' - ' "__name__"\n' - ' The class name.\n' + ' "__name__"\n' + ' The class name.\n' '\n' - ' "__module__"\n' - ' The name of the module in which the class was defined.\n' + ' "__module__"\n' + ' The name of the module in which the class was defined.\n' '\n' - ' "__dict__"\n' - ' The dictionary containing the class’s namespace.\n' + ' "__dict__"\n' + ' The dictionary containing the class’s namespace.\n' '\n' - ' "__bases__"\n' - ' A tuple containing the base classes, in the order of ' - 'their\n' - ' occurrence in the base class list.\n' + ' "__bases__"\n' + ' A tuple containing the base classes, in the order of their\n' + ' occurrence in the base class list.\n' '\n' - ' "__doc__"\n' - ' The class’s documentation string, or "None" if undefined.\n' + ' "__doc__"\n' + ' The class’s documentation string, or "None" if undefined.\n' + '\n' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' class body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' + '\n' + ' "__type_params__"\n' + ' A tuple containing the type parameters of a generic class.\n' '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during class body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' '\n' 'Class instances\n' - ' A class instance is created by calling a class object (see ' - 'above).\n' - ' A class instance has a namespace implemented as a dictionary ' - 'which\n' - ' is the first place in which attribute references are searched.\n' - ' When an attribute is not found there, and the instance’s class ' - 'has\n' - ' an attribute by that name, the search continues with the class\n' - ' attributes. If a class attribute is found that is a ' - 'user-defined\n' - ' function object, it is transformed into an instance method ' - 'object\n' - ' whose "__self__" attribute is the instance. Static method and\n' - ' class method objects are also transformed; see above under\n' - ' “Classesâ€. See section Implementing Descriptors for another way ' - 'in\n' - ' which attributes of a class retrieved via its instances may ' - 'differ\n' - ' from the objects actually stored in the class’s "__dict__". If ' - 'no\n' - ' class attribute is found, and the object’s class has a\n' - ' "__getattr__()" method, that is called to satisfy the lookup.\n' + '===============\n' + '\n' + 'A class instance is created by calling a class object (see above). ' + 'A\n' + 'class instance has a namespace implemented as a dictionary which ' + 'is\n' + 'the first place in which attribute references are searched. When ' + 'an\n' + 'attribute is not found there, and the instance’s class has an\n' + 'attribute by that name, the search continues with the class\n' + 'attributes. If a class attribute is found that is a user-defined\n' + 'function object, it is transformed into an instance method object\n' + 'whose "__self__" attribute is the instance. Static method and ' + 'class\n' + 'method objects are also transformed; see above under “Classesâ€. ' + 'See\n' + 'section Implementing Descriptors for another way in which ' + 'attributes\n' + 'of a class retrieved via its instances may differ from the objects\n' + 'actually stored in the class’s "__dict__". If no class attribute ' + 'is\n' + 'found, and the object’s class has a "__getattr__()" method, that ' + 'is\n' + 'called to satisfy the lookup.\n' '\n' - ' Attribute assignments and deletions update the instance’s\n' - ' dictionary, never a class’s dictionary. If the class has a\n' - ' "__setattr__()" or "__delattr__()" method, this is called ' - 'instead\n' - ' of updating the instance dictionary directly.\n' + 'Attribute assignments and deletions update the instance’s ' + 'dictionary,\n' + 'never a class’s dictionary. If the class has a "__setattr__()" or\n' + '"__delattr__()" method, this is called instead of updating the\n' + 'instance dictionary directly.\n' '\n' - ' Class instances can pretend to be numbers, sequences, or ' - 'mappings\n' - ' if they have methods with certain special names. See section\n' - ' Special method names.\n' + 'Class instances can pretend to be numbers, sequences, or mappings ' + 'if\n' + 'they have methods with certain special names. See section Special\n' + 'method names.\n' + '\n' + 'Special attributes: "__dict__" is the attribute dictionary;\n' + '"__class__" is the instance’s class.\n' '\n' - ' Special attributes: "__dict__" is the attribute dictionary;\n' - ' "__class__" is the instance’s class.\n' '\n' 'I/O objects (also known as file objects)\n' - ' A *file object* represents an open file. Various shortcuts are\n' - ' available to create file objects: the "open()" built-in ' - 'function,\n' - ' and also "os.popen()", "os.fdopen()", and the "makefile()" ' - 'method\n' - ' of socket objects (and perhaps by other functions or methods\n' - ' provided by extension modules).\n' + '========================================\n' + '\n' + 'A *file object* represents an open file. Various shortcuts are\n' + 'available to create file objects: the "open()" built-in function, ' + 'and\n' + 'also "os.popen()", "os.fdopen()", and the "makefile()" method of\n' + 'socket objects (and perhaps by other functions or methods provided ' + 'by\n' + 'extension modules).\n' + '\n' + 'The objects "sys.stdin", "sys.stdout" and "sys.stderr" are ' + 'initialized\n' + 'to file objects corresponding to the interpreter’s standard input,\n' + 'output and error streams; they are all open in text mode and ' + 'therefore\n' + 'follow the interface defined by the "io.TextIOBase" abstract ' + 'class.\n' '\n' - ' The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n' - ' initialized to file objects corresponding to the interpreter’s\n' - ' standard input, output and error streams; they are all open in ' - 'text\n' - ' mode and therefore follow the interface defined by the\n' - ' "io.TextIOBase" abstract class.\n' '\n' 'Internal types\n' - ' A few types used internally by the interpreter are exposed to ' - 'the\n' - ' user. Their definitions may change with future versions of the\n' - ' interpreter, but they are mentioned here for completeness.\n' - '\n' - ' Code objects\n' - ' Code objects represent *byte-compiled* executable Python ' - 'code,\n' - ' or *bytecode*. The difference between a code object and a\n' - ' function object is that the function object contains an ' - 'explicit\n' - ' reference to the function’s globals (the module in which it ' - 'was\n' - ' defined), while a code object contains no context; also the\n' - ' default argument values are stored in the function object, ' - 'not\n' - ' in the code object (because they represent values calculated ' - 'at\n' - ' run-time). Unlike function objects, code objects are ' - 'immutable\n' - ' and contain no references (directly or indirectly) to ' - 'mutable\n' - ' objects.\n' - '\n' - ' Special read-only attributes: "co_name" gives the function ' - 'name;\n' - ' "co_qualname" gives the fully qualified function name;\n' - ' "co_argcount" is the total number of positional arguments\n' - ' (including positional-only arguments and arguments with ' - 'default\n' - ' values); "co_posonlyargcount" is the number of ' - 'positional-only\n' - ' arguments (including arguments with default values);\n' - ' "co_kwonlyargcount" is the number of keyword-only arguments\n' - ' (including arguments with default values); "co_nlocals" is ' - 'the\n' - ' number of local variables used by the function (including\n' - ' arguments); "co_varnames" is a tuple containing the names of ' - 'the\n' - ' local variables (starting with the argument names);\n' - ' "co_cellvars" is a tuple containing the names of local ' - 'variables\n' - ' that are referenced by nested functions; "co_freevars" is a\n' - ' tuple containing the names of free variables; "co_code" is a\n' - ' string representing the sequence of bytecode instructions;\n' - ' "co_consts" is a tuple containing the literals used by the\n' - ' bytecode; "co_names" is a tuple containing the names used by ' - 'the\n' - ' bytecode; "co_filename" is the filename from which the code ' - 'was\n' - ' compiled; "co_firstlineno" is the first line number of the\n' - ' function; "co_lnotab" is a string encoding the mapping from\n' - ' bytecode offsets to line numbers (for details see the source\n' - ' code of the interpreter, is deprecated since 3.12 and may be\n' - ' removed in 3.14); "co_stacksize" is the required stack size;\n' - ' "co_flags" is an integer encoding a number of flags for the\n' - ' interpreter.\n' - '\n' - ' The following flag bits are defined for "co_flags": bit ' - '"0x04"\n' - ' is set if the function uses the "*arguments" syntax to accept ' - 'an\n' - ' arbitrary number of positional arguments; bit "0x08" is set ' - 'if\n' - ' the function uses the "**keywords" syntax to accept ' - 'arbitrary\n' - ' keyword arguments; bit "0x20" is set if the function is a\n' - ' generator.\n' + '==============\n' + '\n' + 'A few types used internally by the interpreter are exposed to the\n' + 'user. Their definitions may change with future versions of the\n' + 'interpreter, but they are mentioned here for completeness.\n' '\n' - ' Future feature declarations ("from __future__ import ' - 'division")\n' - ' also use bits in "co_flags" to indicate whether a code ' + '\n' + 'Code objects\n' + '------------\n' + '\n' + 'Code objects represent *byte-compiled* executable Python code, or\n' + '*bytecode*. The difference between a code object and a function ' 'object\n' - ' was compiled with a particular feature enabled: bit "0x2000" ' + 'is that the function object contains an explicit reference to the\n' + 'function’s globals (the module in which it was defined), while a ' + 'code\n' + 'object contains no context; also the default argument values are\n' + 'stored in the function object, not in the code object (because ' + 'they\n' + 'represent values calculated at run-time). Unlike function ' + 'objects,\n' + 'code objects are immutable and contain no references (directly or\n' + 'indirectly) to mutable objects.\n' + '\n' + 'Special read-only attributes: "co_name" gives the function name;\n' + '"co_qualname" gives the fully qualified function name; ' + '"co_argcount"\n' + 'is the total number of positional arguments (including ' + 'positional-only\n' + 'arguments and arguments with default values); "co_posonlyargcount" ' + 'is\n' + 'the number of positional-only arguments (including arguments with\n' + 'default values); "co_kwonlyargcount" is the number of keyword-only\n' + 'arguments (including arguments with default values); "co_nlocals" ' 'is\n' - ' set if the function was compiled with future division ' - 'enabled;\n' - ' bits "0x10" and "0x1000" were used in earlier versions of\n' - ' Python.\n' + 'the number of local variables used by the function (including\n' + 'arguments); "co_varnames" is a tuple containing the names of the ' + 'local\n' + 'variables (starting with the argument names); "co_cellvars" is a ' + 'tuple\n' + 'containing the names of local variables that are referenced by ' + 'nested\n' + 'functions; "co_freevars" is a tuple containing the names of free\n' + 'variables; "co_code" is a string representing the sequence of ' + 'bytecode\n' + 'instructions; "co_consts" is a tuple containing the literals used ' + 'by\n' + 'the bytecode; "co_names" is a tuple containing the names used by ' + 'the\n' + 'bytecode; "co_filename" is the filename from which the code was\n' + 'compiled; "co_firstlineno" is the first line number of the ' + 'function;\n' + '"co_lnotab" is a string encoding the mapping from bytecode offsets ' + 'to\n' + 'line numbers (for details see the source code of the interpreter, ' + 'is\n' + 'deprecated since 3.12 and may be removed in 3.14); "co_stacksize" ' + 'is\n' + 'the required stack size; "co_flags" is an integer encoding a number ' + 'of\n' + 'flags for the interpreter.\n' '\n' - ' Other bits in "co_flags" are reserved for internal use.\n' + 'The following flag bits are defined for "co_flags": bit "0x04" is ' + 'set\n' + 'if the function uses the "*arguments" syntax to accept an ' + 'arbitrary\n' + 'number of positional arguments; bit "0x08" is set if the function ' + 'uses\n' + 'the "**keywords" syntax to accept arbitrary keyword arguments; bit\n' + '"0x20" is set if the function is a generator.\n' + '\n' + 'Future feature declarations ("from __future__ import division") ' + 'also\n' + 'use bits in "co_flags" to indicate whether a code object was ' + 'compiled\n' + 'with a particular feature enabled: bit "0x2000" is set if the ' + 'function\n' + 'was compiled with future division enabled; bits "0x10" and ' + '"0x1000"\n' + 'were used in earlier versions of Python.\n' '\n' - ' If a code object represents a function, the first item in\n' - ' "co_consts" is the documentation string of the function, or\n' - ' "None" if undefined.\n' + 'Other bits in "co_flags" are reserved for internal use.\n' '\n' - ' codeobject.co_positions()\n' + 'If a code object represents a function, the first item in ' + '"co_consts"\n' + 'is the documentation string of the function, or "None" if ' + 'undefined.\n' '\n' - ' Returns an iterable over the source code positions of ' - 'each\n' - ' bytecode instruction in the code object.\n' + 'codeobject.co_positions()\n' '\n' - ' The iterator returns tuples containing the "(start_line,\n' - ' end_line, start_column, end_column)". The *i-th* tuple\n' - ' corresponds to the position of the source code that ' - 'compiled\n' - ' to the *i-th* instruction. Column information is ' - '0-indexed\n' - ' utf-8 byte offsets on the given source line.\n' + ' Returns an iterable over the source code positions of each ' + 'bytecode\n' + ' instruction in the code object.\n' '\n' - ' This positional information can be missing. A ' - 'non-exhaustive\n' - ' lists of cases where this may happen:\n' + ' The iterator returns tuples containing the "(start_line, ' + 'end_line,\n' + ' start_column, end_column)". The *i-th* tuple corresponds to the\n' + ' position of the source code that compiled to the *i-th*\n' + ' instruction. Column information is 0-indexed utf-8 byte offsets ' + 'on\n' + ' the given source line.\n' '\n' - ' * Running the interpreter with "-X" "no_debug_ranges".\n' + ' This positional information can be missing. A non-exhaustive ' + 'lists\n' + ' of cases where this may happen:\n' '\n' - ' * Loading a pyc file compiled while using "-X"\n' - ' "no_debug_ranges".\n' + ' * Running the interpreter with "-X" "no_debug_ranges".\n' '\n' - ' * Position tuples corresponding to artificial ' - 'instructions.\n' + ' * Loading a pyc file compiled while using "-X" ' + '"no_debug_ranges".\n' '\n' - ' * Line and column numbers that can’t be represented due ' - 'to\n' - ' implementation specific limitations.\n' + ' * Position tuples corresponding to artificial instructions.\n' '\n' - ' When this occurs, some or all of the tuple elements can ' - 'be\n' - ' "None".\n' + ' * Line and column numbers that can’t be represented due to\n' + ' implementation specific limitations.\n' '\n' - ' New in version 3.11.\n' + ' When this occurs, some or all of the tuple elements can be ' + '"None".\n' '\n' - ' Note:\n' + ' New in version 3.11.\n' '\n' - ' This feature requires storing column positions in code\n' - ' objects which may result in a small increase of disk ' - 'usage\n' - ' of compiled Python files or interpreter memory usage. ' - 'To\n' - ' avoid storing the extra information and/or deactivate\n' - ' printing the extra traceback information, the "-X"\n' - ' "no_debug_ranges" command line flag or the\n' - ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + ' Note:\n' '\n' - ' Frame objects\n' - ' Frame objects represent execution frames. They may occur in\n' - ' traceback objects (see below), and are also passed to ' - 'registered\n' - ' trace functions.\n' + ' This feature requires storing column positions in code ' + 'objects\n' + ' which may result in a small increase of disk usage of ' + 'compiled\n' + ' Python files or interpreter memory usage. To avoid storing ' + 'the\n' + ' extra information and/or deactivate printing the extra ' + 'traceback\n' + ' information, the "-X" "no_debug_ranges" command line flag or ' + 'the\n' + ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + '\n' + '\n' + 'Frame objects\n' + '-------------\n' + '\n' + 'Frame objects represent execution frames. They may occur in ' + 'traceback\n' + 'objects (see below), and are also passed to registered trace\n' + 'functions.\n' + '\n' + 'Special read-only attributes: "f_back" is to the previous stack ' + 'frame\n' + '(towards the caller), or "None" if this is the bottom stack frame;\n' + '"f_code" is the code object being executed in this frame; ' + '"f_locals"\n' + 'is the dictionary used to look up local variables; "f_globals" is ' + 'used\n' + 'for global variables; "f_builtins" is used for built-in ' + '(intrinsic)\n' + 'names; "f_lasti" gives the precise instruction (this is an index ' + 'into\n' + 'the bytecode string of the code object).\n' + '\n' + 'Accessing "f_code" raises an auditing event "object.__getattr__" ' + 'with\n' + 'arguments "obj" and ""f_code"".\n' + '\n' + 'Special writable attributes: "f_trace", if not "None", is a ' + 'function\n' + 'called for various events during code execution (this is used by ' + 'the\n' + 'debugger). Normally an event is triggered for each new source line ' + '-\n' + 'this can be disabled by setting "f_trace_lines" to "False".\n' '\n' - ' Special read-only attributes: "f_back" is to the previous ' - 'stack\n' - ' frame (towards the caller), or "None" if this is the bottom\n' - ' stack frame; "f_code" is the code object being executed in ' + 'Implementations *may* allow per-opcode events to be requested by\n' + 'setting "f_trace_opcodes" to "True". Note that this may lead to\n' + 'undefined interpreter behaviour if exceptions raised by the trace\n' + 'function escape to the function being traced.\n' + '\n' + '"f_lineno" is the current line number of the frame — writing to ' 'this\n' - ' frame; "f_locals" is the dictionary used to look up local\n' - ' variables; "f_globals" is used for global variables;\n' - ' "f_builtins" is used for built-in (intrinsic) names; ' - '"f_lasti"\n' - ' gives the precise instruction (this is an index into the\n' - ' bytecode string of the code object).\n' - '\n' - ' Accessing "f_code" raises an auditing event ' - '"object.__getattr__"\n' - ' with arguments "obj" and ""f_code"".\n' - '\n' - ' Special writable attributes: "f_trace", if not "None", is a\n' - ' function called for various events during code execution ' - '(this\n' - ' is used by the debugger). Normally an event is triggered for\n' - ' each new source line - this can be disabled by setting\n' - ' "f_trace_lines" to "False".\n' - '\n' - ' Implementations *may* allow per-opcode events to be requested ' - 'by\n' - ' setting "f_trace_opcodes" to "True". Note that this may lead ' - 'to\n' - ' undefined interpreter behaviour if exceptions raised by the\n' - ' trace function escape to the function being traced.\n' + 'from within a trace function jumps to the given line (only for the\n' + 'bottom-most frame). A debugger can implement a Jump command (aka ' + 'Set\n' + 'Next Statement) by writing to f_lineno.\n' '\n' - ' "f_lineno" is the current line number of the frame — writing ' - 'to\n' - ' this from within a trace function jumps to the given line ' - '(only\n' - ' for the bottom-most frame). A debugger can implement a Jump\n' - ' command (aka Set Next Statement) by writing to f_lineno.\n' + 'Frame objects support one method:\n' '\n' - ' Frame objects support one method:\n' + 'frame.clear()\n' '\n' - ' frame.clear()\n' + ' This method clears all references to local variables held by ' + 'the\n' + ' frame. Also, if the frame belonged to a generator, the ' + 'generator\n' + ' is finalized. This helps break reference cycles involving ' + 'frame\n' + ' objects (for example when catching an exception and storing its\n' + ' traceback for later use).\n' '\n' - ' This method clears all references to local variables held ' - 'by\n' - ' the frame. Also, if the frame belonged to a generator, ' + ' "RuntimeError" is raised if the frame is currently executing.\n' + '\n' + ' New in version 3.4.\n' + '\n' + '\n' + 'Traceback objects\n' + '-----------------\n' + '\n' + 'Traceback objects represent a stack trace of an exception. A\n' + 'traceback object is implicitly created when an exception occurs, ' + 'and\n' + 'may also be explicitly created by calling "types.TracebackType".\n' + '\n' + 'For implicitly created tracebacks, when the search for an ' + 'exception\n' + 'handler unwinds the execution stack, at each unwound level a ' + 'traceback\n' + 'object is inserted in front of the current traceback. When an\n' + 'exception handler is entered, the stack trace is made available to ' 'the\n' - ' generator is finalized. This helps break reference ' - 'cycles\n' - ' involving frame objects (for example when catching an\n' - ' exception and storing its traceback for later use).\n' + 'program. (See section The try statement.) It is accessible as the\n' + 'third item of the tuple returned by "sys.exc_info()", and as the\n' + '"__traceback__" attribute of the caught exception.\n' '\n' - ' "RuntimeError" is raised if the frame is currently ' - 'executing.\n' + 'When the program contains no suitable handler, the stack trace is\n' + 'written (nicely formatted) to the standard error stream; if the\n' + 'interpreter is interactive, it is also made available to the user ' + 'as\n' + '"sys.last_traceback".\n' '\n' - ' New in version 3.4.\n' + 'For explicitly created tracebacks, it is up to the creator of the\n' + 'traceback to determine how the "tb_next" attributes should be ' + 'linked\n' + 'to form a full stack trace.\n' '\n' - ' Traceback objects\n' - ' Traceback objects represent a stack trace of an exception. ' - 'A\n' - ' traceback object is implicitly created when an exception ' - 'occurs,\n' - ' and may also be explicitly created by calling\n' - ' "types.TracebackType".\n' - '\n' - ' For implicitly created tracebacks, when the search for an\n' - ' exception handler unwinds the execution stack, at each ' - 'unwound\n' - ' level a traceback object is inserted in front of the current\n' - ' traceback. When an exception handler is entered, the stack\n' - ' trace is made available to the program. (See section The try\n' - ' statement.) It is accessible as the third item of the tuple\n' - ' returned by "sys.exc_info()", and as the "__traceback__"\n' - ' attribute of the caught exception.\n' - '\n' - ' When the program contains no suitable handler, the stack ' - 'trace\n' - ' is written (nicely formatted) to the standard error stream; ' - 'if\n' - ' the interpreter is interactive, it is also made available to ' + 'Special read-only attributes: "tb_frame" points to the execution ' + 'frame\n' + 'of the current level; "tb_lineno" gives the line number where the\n' + 'exception occurred; "tb_lasti" indicates the precise instruction. ' + 'The\n' + 'line number and last instruction in the traceback may differ from ' 'the\n' - ' user as "sys.last_traceback".\n' + 'line number of its frame object if the exception occurred in a ' + '"try"\n' + 'statement with no matching except clause or with a finally clause.\n' '\n' - ' For explicitly created tracebacks, it is up to the creator ' - 'of\n' - ' the traceback to determine how the "tb_next" attributes ' - 'should\n' - ' be linked to form a full stack trace.\n' - '\n' - ' Special read-only attributes: "tb_frame" points to the ' - 'execution\n' - ' frame of the current level; "tb_lineno" gives the line ' - 'number\n' - ' where the exception occurred; "tb_lasti" indicates the ' - 'precise\n' - ' instruction. The line number and last instruction in the\n' - ' traceback may differ from the line number of its frame object ' + 'Accessing "tb_frame" raises an auditing event "object.__getattr__"\n' + 'with arguments "obj" and ""tb_frame"".\n' + '\n' + 'Special writable attribute: "tb_next" is the next level in the ' + 'stack\n' + 'trace (towards the frame where the exception occurred), or "None" ' 'if\n' - ' the exception occurred in a "try" statement with no matching\n' - ' except clause or with a finally clause.\n' + 'there is no next level.\n' '\n' - ' Accessing "tb_frame" raises an auditing event\n' - ' "object.__getattr__" with arguments "obj" and ""tb_frame"".\n' + 'Changed in version 3.7: Traceback objects can now be explicitly\n' + 'instantiated from Python code, and the "tb_next" attribute of ' + 'existing\n' + 'instances can be updated.\n' '\n' - ' Special writable attribute: "tb_next" is the next level in ' - 'the\n' - ' stack trace (towards the frame where the exception occurred), ' - 'or\n' - ' "None" if there is no next level.\n' '\n' - ' Changed in version 3.7: Traceback objects can now be ' - 'explicitly\n' - ' instantiated from Python code, and the "tb_next" attribute ' - 'of\n' - ' existing instances can be updated.\n' + 'Slice objects\n' + '-------------\n' '\n' - ' Slice objects\n' - ' Slice objects are used to represent slices for ' - '"__getitem__()"\n' - ' methods. They are also created by the built-in "slice()"\n' - ' function.\n' + 'Slice objects are used to represent slices for "__getitem__()"\n' + 'methods. They are also created by the built-in "slice()" ' + 'function.\n' '\n' - ' Special read-only attributes: "start" is the lower bound; ' - '"stop"\n' - ' is the upper bound; "step" is the step value; each is "None" ' - 'if\n' - ' omitted. These attributes can have any type.\n' + 'Special read-only attributes: "start" is the lower bound; "stop" ' + 'is\n' + 'the upper bound; "step" is the step value; each is "None" if ' + 'omitted.\n' + 'These attributes can have any type.\n' '\n' - ' Slice objects support one method:\n' + 'Slice objects support one method:\n' '\n' - ' slice.indices(self, length)\n' + 'slice.indices(self, length)\n' '\n' - ' This method takes a single integer argument *length* and\n' - ' computes information about the slice that the slice ' - 'object\n' - ' would describe if applied to a sequence of *length* ' - 'items.\n' - ' It returns a tuple of three integers; respectively these ' - 'are\n' - ' the *start* and *stop* indices and the *step* or stride\n' - ' length of the slice. Missing or out-of-bounds indices are\n' - ' handled in a manner consistent with regular slices.\n' - '\n' - ' Static method objects\n' - ' Static method objects provide a way of defeating the\n' - ' transformation of function objects to method objects ' - 'described\n' - ' above. A static method object is a wrapper around any other\n' - ' object, usually a user-defined method object. When a static\n' - ' method object is retrieved from a class or a class instance, ' - 'the\n' - ' object actually returned is the wrapped object, which is not\n' - ' subject to any further transformation. Static method objects ' - 'are\n' - ' also callable. Static method objects are created by the ' - 'built-in\n' - ' "staticmethod()" constructor.\n' + ' This method takes a single integer argument *length* and ' + 'computes\n' + ' information about the slice that the slice object would describe ' + 'if\n' + ' applied to a sequence of *length* items. It returns a tuple of\n' + ' three integers; respectively these are the *start* and *stop*\n' + ' indices and the *step* or stride length of the slice. Missing ' + 'or\n' + ' out-of-bounds indices are handled in a manner consistent with\n' + ' regular slices.\n' '\n' - ' Class method objects\n' - ' A class method object, like a static method object, is a ' - 'wrapper\n' - ' around another object that alters the way in which that ' - 'object\n' - ' is retrieved from classes and class instances. The behaviour ' + '\n' + 'Static method objects\n' + '---------------------\n' + '\n' + 'Static method objects provide a way of defeating the transformation ' 'of\n' - ' class method objects upon such retrieval is described above,\n' - ' under “User-defined methodsâ€. Class method objects are ' - 'created\n' - ' by the built-in "classmethod()" constructor.\n', + 'function objects to method objects described above. A static ' + 'method\n' + 'object is a wrapper around any other object, usually a ' + 'user-defined\n' + 'method object. When a static method object is retrieved from a ' + 'class\n' + 'or a class instance, the object actually returned is the wrapped\n' + 'object, which is not subject to any further transformation. Static\n' + 'method objects are also callable. Static method objects are created ' + 'by\n' + 'the built-in "staticmethod()" constructor.\n' + '\n' + '\n' + 'Class method objects\n' + '--------------------\n' + '\n' + 'A class method object, like a static method object, is a wrapper\n' + 'around another object that alters the way in which that object is\n' + 'retrieved from classes and class instances. The behaviour of class\n' + 'method objects upon such retrieval is described above, under ' + '“User-\n' + 'defined methodsâ€. Class method objects are created by the built-in\n' + '"classmethod()" constructor.\n', 'typesfunctions': 'Functions\n' '*********\n' '\n' @@ -14611,10 +15263,12 @@ ' >>> # set operations\n' " >>> keys & {'eggs', 'bacon', 'salad'}\n" " {'bacon'}\n" - " >>> keys ^ {'sausage', 'juice'}\n" - " {'juice', 'sausage', 'bacon', 'spam'}\n" - " >>> keys | ['juice', 'juice', 'juice']\n" - " {'juice', 'sausage', 'bacon', 'spam', 'eggs'}\n" + " >>> keys ^ {'sausage', 'juice'} == {'juice', 'sausage', " + "'bacon', 'spam'}\n" + ' True\n' + " >>> keys | ['juice', 'juice', 'juice'] == {'bacon', " + "'spam', 'juice'}\n" + ' True\n' '\n' ' >>> # get back a read-only proxy for the original ' 'dictionary\n' diff --git a/Lib/random.py b/Lib/random.py index 586c3f7f9da938..3f7bfd272d65a5 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -65,7 +65,7 @@ try: # hashlib is pretty heavy to load, try lean internal module first - from _sha512 import sha512 as _sha512 + from _sha2 import sha512 as _sha512 except ImportError: # fallback to official implementation from hashlib import sha512 as _sha512 @@ -164,8 +164,8 @@ def seed(self, a=None, version=2): a = int.from_bytes(a + _sha512(a).digest()) elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)): - raise TypeError('The only supported seed types are: None,\n' - 'int, float, str, bytes, and bytearray.') + raise TypeError('The only supported seed types are:\n' + 'None, int, float, str, bytes, and bytearray.') super().seed(a) self.gauss_next = None @@ -492,7 +492,14 @@ def choices(self, population, weights=None, *, cum_weights=None, k=1): ## -------------------- real-valued distributions ------------------- def uniform(self, a, b): - "Get a random number in the range [a, b) or [a, b] depending on rounding." + """Get a random number in the range [a, b) or [a, b] depending on rounding. + + The mean (expected value) and variance of the random variable are: + + E[X] = (a + b) / 2 + Var[X] = (b - a) ** 2 / 12 + + """ return a + (b - a) * self.random() def triangular(self, low=0.0, high=1.0, mode=None): @@ -503,6 +510,11 @@ def triangular(self, low=0.0, high=1.0, mode=None): http://en.wikipedia.org/wiki/Triangular_distribution + The mean (expected value) and variance of the random variable are: + + E[X] = (low + high + mode) / 3 + Var[X] = (low**2 + high**2 + mode**2 - low*high - low*mode - high*mode) / 18 + """ u = self.random() try: @@ -593,12 +605,15 @@ def expovariate(self, lambd=1.0): positive infinity if lambd is positive, and from negative infinity to 0 if lambd is negative. - """ - # lambd: rate lambd = 1/mean - # ('lambda' is a Python reserved word) + The mean (expected value) and variance of the random variable are: + + E[X] = 1 / lambd + Var[X] = 1 / lambd ** 2 + """ # we use 1-random() instead of random() to preclude the # possibility of taking the log of zero. + return -_log(1.0 - self.random()) / lambd def vonmisesvariate(self, mu, kappa): @@ -654,8 +669,12 @@ def gammavariate(self, alpha, beta): pdf(x) = -------------------------------------- math.gamma(alpha) * beta ** alpha + The mean (expected value) and variance of the random variable are: + + E[X] = alpha * beta + Var[X] = alpha * beta ** 2 + """ - # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 # Warning: a few older sources define the gamma distribution in terms # of alpha > -1.0 @@ -714,6 +733,11 @@ def betavariate(self, alpha, beta): Conditions on the parameters are alpha > 0 and beta > 0. Returned values range between 0 and 1. + The mean (expected value) and variance of the random variable are: + + E[X] = alpha / (alpha + beta) + Var[X] = alpha * beta / ((alpha + beta)**2 * (alpha + beta + 1)) + """ ## See ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html @@ -766,6 +790,11 @@ def binomialvariate(self, n=1, p=0.5): Returns an integer in the range: 0 <= X <= n + The mean (expected value) and variance of the random variable are: + + E[X] = n * p + Var[x] = n * p * (1 - p) + """ # Error check inputs and handle edge cases if n < 0: @@ -827,7 +856,7 @@ def binomialvariate(self, n=1, p=0.5): return k # Acceptance-rejection test. - # Note, the original paper errorneously omits the call to log(v) + # Note, the original paper erroneously omits the call to log(v) # when comparing to the log of the rescaled binomial distribution. if not setup_complete: alpha = (2.83 + 5.1 / b) * spq diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index d6fccd5bc97cc0..428d1b0d5fbd87 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -175,16 +175,39 @@ def search(pattern, string, flags=0): a Match object, or None if no match was found.""" return _compile(pattern, flags).search(string) -def sub(pattern, repl, string, count=0, flags=0): +class _ZeroSentinel(int): + pass +_zero_sentinel = _ZeroSentinel() + +def sub(pattern, repl, string, *args, count=_zero_sentinel, flags=_zero_sentinel): """Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the Match object and must return a replacement string to be used.""" + if args: + if count is not _zero_sentinel: + raise TypeError("sub() got multiple values for argument 'count'") + count, *args = args + if args: + if flags is not _zero_sentinel: + raise TypeError("sub() got multiple values for argument 'flags'") + flags, *args = args + if args: + raise TypeError("sub() takes from 3 to 5 positional arguments " + "but %d were given" % (5 + len(args))) + + import warnings + warnings.warn( + "'count' is passed as positional argument", + DeprecationWarning, stacklevel=2 + ) + return _compile(pattern, flags).sub(repl, string, count) +sub.__text_signature__ = '(pattern, repl, string, count=0, flags=0)' -def subn(pattern, repl, string, count=0, flags=0): +def subn(pattern, repl, string, *args, count=_zero_sentinel, flags=_zero_sentinel): """Return a 2-tuple containing (new_string, number). new_string is the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in the source @@ -193,9 +216,28 @@ def subn(pattern, repl, string, count=0, flags=0): callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the Match object and must return a replacement string to be used.""" + if args: + if count is not _zero_sentinel: + raise TypeError("subn() got multiple values for argument 'count'") + count, *args = args + if args: + if flags is not _zero_sentinel: + raise TypeError("subn() got multiple values for argument 'flags'") + flags, *args = args + if args: + raise TypeError("subn() takes from 3 to 5 positional arguments " + "but %d were given" % (5 + len(args))) + + import warnings + warnings.warn( + "'count' is passed as positional argument", + DeprecationWarning, stacklevel=2 + ) + return _compile(pattern, flags).subn(repl, string, count) +subn.__text_signature__ = '(pattern, repl, string, count=0, flags=0)' -def split(pattern, string, maxsplit=0, flags=0): +def split(pattern, string, *args, maxsplit=_zero_sentinel, flags=_zero_sentinel): """Split the source string by the occurrences of the pattern, returning a list containing the resulting substrings. If capturing parentheses are used in pattern, then the text of all @@ -203,7 +245,26 @@ def split(pattern, string, maxsplit=0, flags=0): list. If maxsplit is nonzero, at most maxsplit splits occur, and the remainder of the string is returned as the final element of the list.""" + if args: + if maxsplit is not _zero_sentinel: + raise TypeError("split() got multiple values for argument 'maxsplit'") + maxsplit, *args = args + if args: + if flags is not _zero_sentinel: + raise TypeError("split() got multiple values for argument 'flags'") + flags, *args = args + if args: + raise TypeError("split() takes from 2 to 4 positional arguments " + "but %d were given" % (4 + len(args))) + + import warnings + warnings.warn( + "'maxsplit' is passed as positional argument", + DeprecationWarning, stacklevel=2 + ) + return _compile(pattern, flags).split(string, maxsplit) +split.__text_signature__ = '(pattern, string, maxsplit=0, flags=0)' def findall(pattern, string, flags=0): """Return a list of all non-overlapping matches in the string. diff --git a/Lib/re/_parser.py b/Lib/re/_parser.py index 22d10ab6e31d37..d00b7e67d55958 100644 --- a/Lib/re/_parser.py +++ b/Lib/re/_parser.py @@ -773,8 +773,10 @@ def _parse(source, state, verbose, nested, first=False): source.tell() - start) if char == "=": subpatternappend((ASSERT, (dir, p))) - else: + elif p: subpatternappend((ASSERT_NOT, (dir, p))) + else: + subpatternappend((FAILURE, ())) continue elif char == "(": diff --git a/Lib/reprlib.py b/Lib/reprlib.py index a92b3e3dbb613a..05bb1a0eb01795 100644 --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -29,6 +29,8 @@ def wrapper(self): wrapper.__name__ = getattr(user_function, '__name__') wrapper.__qualname__ = getattr(user_function, '__qualname__') wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + wrapper.__type_params__ = getattr(user_function, '__type_params__', ()) + wrapper.__wrapped__ = user_function return wrapper return decorating_function diff --git a/Lib/selectors.py b/Lib/selectors.py index 13497a24097232..b8e5f6a4f77d89 100644 --- a/Lib/selectors.py +++ b/Lib/selectors.py @@ -339,11 +339,8 @@ def __init__(self): def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) - poller_events = 0 - if events & EVENT_READ: - poller_events |= self._EVENT_READ - if events & EVENT_WRITE: - poller_events |= self._EVENT_WRITE + poller_events = ((events & EVENT_READ and self._EVENT_READ) + | (events & EVENT_WRITE and self._EVENT_WRITE) ) try: self._selector.register(key.fd, poller_events) except: @@ -369,11 +366,8 @@ def modify(self, fileobj, events, data=None): changed = False if events != key.events: - selector_events = 0 - if events & EVENT_READ: - selector_events |= self._EVENT_READ - if events & EVENT_WRITE: - selector_events |= self._EVENT_WRITE + selector_events = ((events & EVENT_READ and self._EVENT_READ) + | (events & EVENT_WRITE and self._EVENT_WRITE)) try: self._selector.modify(key.fd, selector_events) except: @@ -404,15 +398,13 @@ def select(self, timeout=None): fd_event_list = self._selector.poll(timeout) except InterruptedError: return ready - for fd, event in fd_event_list: - events = 0 - if event & ~self._EVENT_READ: - events |= EVENT_WRITE - if event & ~self._EVENT_WRITE: - events |= EVENT_READ - key = self._fd_to_key.get(fd) + fd_to_key_get = self._fd_to_key.get + for fd, event in fd_event_list: + key = fd_to_key_get(fd) if key: + events = ((event & ~self._EVENT_READ and EVENT_WRITE) + | (event & ~self._EVENT_WRITE and EVENT_READ)) ready.append((key, events & key.events)) return ready @@ -499,6 +491,7 @@ class KqueueSelector(_BaseSelectorImpl): def __init__(self): super().__init__() self._selector = select.kqueue() + self._max_events = 0 def fileno(self): return self._selector.fileno() @@ -510,10 +503,12 @@ def register(self, fileobj, events, data=None): kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_ADD) self._selector.control([kev], 0, 0) + self._max_events += 1 if events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_ADD) self._selector.control([kev], 0, 0) + self._max_events += 1 except: super().unregister(fileobj) raise @@ -524,6 +519,7 @@ def unregister(self, fileobj): if key.events & EVENT_READ: kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) + self._max_events -= 1 try: self._selector.control([kev], 0, 0) except OSError: @@ -533,6 +529,7 @@ def unregister(self, fileobj): if key.events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) + self._max_events -= 1 try: self._selector.control([kev], 0, 0) except OSError: @@ -545,7 +542,7 @@ def select(self, timeout=None): # If max_ev is 0, kqueue will ignore the timeout. For consistent # behavior with the other selector classes, we prevent that here # (using max). See https://bugs.python.org/issue29255 - max_ev = len(self._fd_to_key) or 1 + max_ev = self._max_events or 1 ready = [] try: kev_list = self._selector.control(None, max_ev, timeout) diff --git a/Lib/shelve.py b/Lib/shelve.py index e053c397345a07..50584716e9ea64 100644 --- a/Lib/shelve.py +++ b/Lib/shelve.py @@ -226,6 +226,13 @@ def __init__(self, filename, flag='c', protocol=None, writeback=False): import dbm Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback) + def clear(self): + """Remove all items from the shelf.""" + # Call through to the clear method on dbm-backed shelves. + # see https://github.com/python/cpython/issues/107089 + self.cache.clear() + self.dict.clear() + def open(filename, flag='c', protocol=None, writeback=False): """Open a persistent dictionary for reading and writing. diff --git a/Lib/shutil.py b/Lib/shutil.py index 3f2864af517e7d..0fed0117a63234 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -10,7 +10,6 @@ import fnmatch import collections import errno -import warnings try: import zlib @@ -481,7 +480,7 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function, if ignore is not None: ignored_names = ignore(os.fspath(src), [x.name for x in entries]) else: - ignored_names = set() + ignored_names = () os.makedirs(dst, exist_ok=dirs_exist_ok) errors = [] @@ -723,6 +722,7 @@ def rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None): """ if onerror is not None: + import warnings warnings.warn("onerror argument is deprecated, use onexc instead", DeprecationWarning, stacklevel=2) @@ -1156,6 +1156,10 @@ def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, supports_root_dir = getattr(func, 'supports_root_dir', False) save_cwd = None if root_dir is not None: + stmd = os.stat(root_dir).st_mode + if not stat.S_ISDIR(stmd): + raise NotADirectoryError(errno.ENOTDIR, 'Not a directory', root_dir) + if supports_root_dir: # Support path-like base_name here for backwards-compatibility. base_name = os.fspath(base_name) @@ -1550,8 +1554,16 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): if use_bytes: pathext = [os.fsencode(ext) for ext in pathext] - # Always try checking the originally given cmd, if it doesn't match, try pathext - files = [cmd] + [cmd + ext for ext in pathext] + files = ([cmd] + [cmd + ext for ext in pathext]) + + # gh-109590. If we are looking for an executable, we need to look + # for a PATHEXT match. The first cmd is the direct match + # (e.g. python.exe instead of python) + # Check that direct match first if and only if the extension is in PATHEXT + # Otherwise check it last + suffix = os.path.splitext(files[0])[1].upper() + if mode & os.X_OK and not any(suffix == ext.upper() for ext in pathext): + files.append(files.pop(0)) else: # On other platforms you don't have things like PATHEXT to tell you # what file suffixes are executable, so just pass on cmd as-is. diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 18c91746fd7bf2..b3cc68a789a7d8 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -542,7 +542,7 @@ def mail(self, sender, options=()): raise SMTPNotSupportedError( 'SMTPUTF8 not supported by server') optionlist = ' ' + ' '.join(options) - self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist)) + self.putcmd("mail", "from:%s%s" % (quoteaddr(sender), optionlist)) return self.getreply() def rcpt(self, recip, options=()): @@ -550,7 +550,7 @@ def rcpt(self, recip, options=()): optionlist = '' if options and self.does_esmtp: optionlist = ' ' + ' '.join(options) - self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist)) + self.putcmd("rcpt", "to:%s%s" % (quoteaddr(recip), optionlist)) return self.getreply() def data(self, msg): diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py index 3228dbc09d502a..b93b84384a0925 100644 --- a/Lib/sqlite3/__main__.py +++ b/Lib/sqlite3/__main__.py @@ -62,7 +62,7 @@ def runsource(self, source, filename="", symbol="single"): return False -def main(): +def main(*args): parser = ArgumentParser( description="Python sqlite3 CLI", prog="python -m sqlite3", @@ -86,7 +86,7 @@ def main(): version=f"SQLite version {sqlite3.sqlite_version}", help="Print underlying SQLite library version", ) - args = parser.parse_args() + args = parser.parse_args(*args) if args.filename == ":memory:": db_name = "a transient in-memory database" @@ -116,9 +116,16 @@ def main(): else: # No SQL provided; start the REPL. console = SqliteInteractiveConsole(con) + try: + import readline + except ImportError: + pass console.interact(banner, exitmsg="") finally: con.close() + sys.exit(0) -main() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Lib/sqlite3/dump.py b/Lib/sqlite3/dump.py index 07b9da10b920f9..ead3360ce67608 100644 --- a/Lib/sqlite3/dump.py +++ b/Lib/sqlite3/dump.py @@ -7,6 +7,14 @@ # future enhancements, you should normally quote any identifier that # is an English language word, even if you do not have to." +def _quote_name(name): + return '"{0}"'.format(name.replace('"', '""')) + + +def _quote_value(value): + return "'{0}'".format(value.replace("'", "''")) + + def _iterdump(connection): """ Returns an iterator to the dump of the database in an SQL text format. @@ -16,6 +24,7 @@ def _iterdump(connection): directly but instead called from the Connection method, iterdump(). """ + writeable_schema = False cu = connection.cursor() yield('BEGIN TRANSACTION;') @@ -31,34 +40,39 @@ def _iterdump(connection): sqlite_sequence = [] for table_name, type, sql in schema_res.fetchall(): if table_name == 'sqlite_sequence': - rows = cu.execute('SELECT * FROM "sqlite_sequence";').fetchall() + rows = cu.execute('SELECT * FROM "sqlite_sequence";') sqlite_sequence = ['DELETE FROM "sqlite_sequence"'] sqlite_sequence += [ - f'INSERT INTO "sqlite_sequence" VALUES(\'{row[0]}\',{row[1]})' - for row in rows + f'INSERT INTO "sqlite_sequence" VALUES({_quote_value(table_name)},{seq_value})' + for table_name, seq_value in rows.fetchall() ] continue elif table_name == 'sqlite_stat1': yield('ANALYZE "sqlite_master";') elif table_name.startswith('sqlite_'): continue - # NOTE: Virtual table support not implemented - #elif sql.startswith('CREATE VIRTUAL TABLE'): - # qtable = table_name.replace("'", "''") - # yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\ - # "VALUES('table','{0}','{0}',0,'{1}');".format( - # qtable, - # sql.replace("''"))) + elif sql.startswith('CREATE VIRTUAL TABLE'): + if not writeable_schema: + writeable_schema = True + yield('PRAGMA writable_schema=ON;') + yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table',{0},{0},0,{1});".format( + _quote_value(table_name), + _quote_value(sql), + )) else: yield('{0};'.format(sql)) # Build the insert statement for each row of the current table - table_name_ident = table_name.replace('"', '""') - res = cu.execute('PRAGMA table_info("{0}")'.format(table_name_ident)) + table_name_ident = _quote_name(table_name) + res = cu.execute(f'PRAGMA table_info({table_name_ident})') column_names = [str(table_info[1]) for table_info in res.fetchall()] - q = """SELECT 'INSERT INTO "{0}" VALUES({1})' FROM "{0}";""".format( + q = "SELECT 'INSERT INTO {0} VALUES('{1}')' FROM {0};".format( table_name_ident, - ",".join("""'||quote("{0}")||'""".format(col.replace('"', '""')) for col in column_names)) + "','".join( + "||quote({0})||".format(_quote_name(col)) for col in column_names + ) + ) query_res = cu.execute(q) for row in query_res: yield("{0};".format(row[0])) @@ -74,6 +88,9 @@ def _iterdump(connection): for name, type, sql in schema_res.fetchall(): yield('{0};'.format(sql)) + if writeable_schema: + yield('PRAGMA writable_schema=OFF;') + # gh-79009: Yield statements concerning the sqlite_sequence table at the # end of the transaction. for row in sqlite_sequence: diff --git a/Lib/ssl.py b/Lib/ssl.py index 1d5873726441e4..62e55857141dfc 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -876,6 +876,31 @@ def getpeercert(self, binary_form=False): """ return self._sslobj.getpeercert(binary_form) + def get_verified_chain(self): + """Returns verified certificate chain provided by the other + end of the SSL channel as a list of DER-encoded bytes. + + If certificate verification was disabled method acts the same as + ``SSLSocket.get_unverified_chain``. + """ + chain = self._sslobj.get_verified_chain() + + if chain is None: + return [] + + return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain] + + def get_unverified_chain(self): + """Returns raw certificate chain provided by the other + end of the SSL channel as a list of DER-encoded bytes. + """ + chain = self._sslobj.get_unverified_chain() + + if chain is None: + return [] + + return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain] + def selected_npn_protocol(self): """Return the currently selected NPN protocol as a string, or ``None`` if a next protocol was not negotiated or if NPN is not supported by one @@ -975,7 +1000,7 @@ def _create(cls, sock, server_side=False, do_handshake_on_connect=True, ) self = cls.__new__(cls, **kwargs) super(SSLSocket, self).__init__(**kwargs) - self.settimeout(sock.gettimeout()) + sock_timeout = sock.gettimeout() sock.detach() self._context = context @@ -994,9 +1019,42 @@ def _create(cls, sock, server_side=False, do_handshake_on_connect=True, if e.errno != errno.ENOTCONN: raise connected = False + blocking = self.getblocking() + self.setblocking(False) + try: + # We are not connected so this is not supposed to block, but + # testing revealed otherwise on macOS and Windows so we do + # the non-blocking dance regardless. Our raise when any data + # is found means consuming the data is harmless. + notconn_pre_handshake_data = self.recv(1) + except OSError as e: + # EINVAL occurs for recv(1) on non-connected on unix sockets. + if e.errno not in (errno.ENOTCONN, errno.EINVAL): + raise + notconn_pre_handshake_data = b'' + self.setblocking(blocking) + if notconn_pre_handshake_data: + # This prevents pending data sent to the socket before it was + # closed from escaping to the caller who could otherwise + # presume it came through a successful TLS connection. + reason = "Closed before TLS handshake with data in recv buffer." + notconn_pre_handshake_data_error = SSLError(e.errno, reason) + # Add the SSLError attributes that _ssl.c always adds. + notconn_pre_handshake_data_error.reason = reason + notconn_pre_handshake_data_error.library = None + try: + self.close() + except OSError: + pass + try: + raise notconn_pre_handshake_data_error + finally: + # Explicitly break the reference cycle. + notconn_pre_handshake_data_error = None else: connected = True + self.settimeout(sock_timeout) # Must come after setblocking() calls. self._connected = connected if connected: # create the SSL object @@ -1096,6 +1154,14 @@ def getpeercert(self, binary_form=False): self._check_connected() return self._sslobj.getpeercert(binary_form) + @_sslcopydoc + def get_verified_chain(self): + return self._sslobj.get_verified_chain() + + @_sslcopydoc + def get_unverified_chain(self): + return self._sslobj.get_unverified_chain() + @_sslcopydoc def selected_npn_protocol(self): self._checkClosed() diff --git a/Lib/stat.py b/Lib/stat.py index fc024db3f4fbee..52cadbf04f6c88 100644 --- a/Lib/stat.py +++ b/Lib/stat.py @@ -126,6 +126,8 @@ def S_ISWHT(mode): _filemode_table = ( + # File type chars according to: + # http://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h ((S_IFLNK, "l"), (S_IFSOCK, "s"), # Must appear before IFREG and IFDIR as IFSOCK == IFREG | IFDIR (S_IFREG, "-"), @@ -156,13 +158,17 @@ def S_ISWHT(mode): def filemode(mode): """Convert a file's mode to a string of the form '-rwxrwxrwx'.""" perm = [] - for table in _filemode_table: + for index, table in enumerate(_filemode_table): for bit, char in table: if mode & bit == bit: perm.append(char) break else: - perm.append("-") + if index == 0: + # Unknown filetype + perm.append("?") + else: + perm.append("-") return "".join(perm) diff --git a/Lib/statistics.py b/Lib/statistics.py index 6bd214bbfe2ff5..4da06889c6db46 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -137,6 +137,7 @@ from itertools import count, groupby, repeat from bisect import bisect_left, bisect_right from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum, sumprod +from math import isfinite, isinf from functools import reduce from operator import itemgetter from collections import Counter, namedtuple, defaultdict @@ -843,7 +844,9 @@ def quantiles(data, *, n=4, method='exclusive'): data = sorted(data) ld = len(data) if ld < 2: - raise StatisticsError('must have at least two data points') + if ld == 1: + return data * (n - 1) + raise StatisticsError('must have at least one data point') if method == 'inclusive': m = ld - 1 result = [] @@ -1004,6 +1007,27 @@ def _mean_stdev(data): # Handle Nans and Infs gracefully return float(xbar), float(xbar) / float(ss) +def _sqrtprod(x: float, y: float) -> float: + "Return sqrt(x * y) computed with improved accuracy and without overflow/underflow." + h = sqrt(x * y) + if not isfinite(h): + if isinf(h) and not isinf(x) and not isinf(y): + # Finite inputs overflowed, so scale down, and recompute. + scale = 2.0 ** -512 # sqrt(1 / sys.float_info.max) + return _sqrtprod(scale * x, scale * y) / scale + return h + if not h: + if x and y: + # Non-zero inputs underflowed, so scale up, and recompute. + # Scale: 1 / sqrt(sys.float_info.min * sys.float_info.epsilon) + scale = 2.0 ** 537 + return _sqrtprod(scale * x, scale * y) / scale + return h + # Improve accuracy with a differential correction. + # https://www.wolframalpha.com/input/?i=Maclaurin+series+sqrt%28h**2+%2B+x%29+at+x%3D0 + d = sumprod((x, h), (y, -h)) + return h + d / (2.0 * h) + # === Statistics for relations between two inputs === @@ -1083,7 +1107,7 @@ def correlation(x, y, /, *, method='linear'): sxx = sumprod(x, x) syy = sumprod(y, y) try: - return sxy / sqrt(sxx * syy) + return sxy / _sqrtprod(sxx, syy) except ZeroDivisionError: raise StatisticsError('at least one of the inputs is constant') @@ -1113,7 +1137,7 @@ def linear_regression(x, y, /, *, proportional=False): >>> noise = NormalDist().samples(5, seed=42) >>> y = [3 * x[i] + 2 + noise[i] for i in range(5)] >>> linear_regression(x, y) #doctest: +ELLIPSIS - LinearRegression(slope=3.09078914170..., intercept=1.75684970486...) + LinearRegression(slope=3.17495..., intercept=1.00925...) If *proportional* is true, the independent variable *x* and the dependent variable *y* are assumed to be directly proportional. @@ -1126,7 +1150,7 @@ def linear_regression(x, y, /, *, proportional=False): >>> y = [3 * x[i] + noise[i] for i in range(5)] >>> linear_regression(x, y, proportional=True) #doctest: +ELLIPSIS - LinearRegression(slope=3.02447542484..., intercept=0.0) + LinearRegression(slope=2.90475..., intercept=0.0) """ n = len(x) @@ -1257,9 +1281,11 @@ def from_samples(cls, data): def samples(self, n, *, seed=None): "Generate *n* samples for a given mean and standard deviation." - gauss = random.gauss if seed is None else random.Random(seed).gauss - mu, sigma = self._mu, self._sigma - return [gauss(mu, sigma) for _ in repeat(None, n)] + rnd = random.random if seed is None else random.Random(seed).random + inv_cdf = _normal_dist_inv_cdf + mu = self._mu + sigma = self._sigma + return [inv_cdf(rnd(), mu, sigma) for _ in repeat(None, n)] def pdf(self, x): "Probability density function. P(x <= X < x+dx) / dx" diff --git a/Lib/subprocess.py b/Lib/subprocess.py index fbc76b8d0f14b2..6df5dd551ea67e 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -346,7 +346,7 @@ def _args_from_interpreter_flags(): if dev_mode: args.extend(('-X', 'dev')) for opt in ('faulthandler', 'tracemalloc', 'importtime', - 'showrefcount', 'utf8'): + 'frozen_modules', 'showrefcount', 'utf8'): if opt in xoptions: value = xoptions[opt] if value is True: diff --git a/Lib/symtable.py b/Lib/symtable.py index 5dd71ffc6b4f19..4b0bc6f497a553 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -62,8 +62,8 @@ def __repr__(self): def get_type(self): """Return the type of the symbol table. - The values returned are 'class', 'module' and - 'function'. + The values returned are 'class', 'module', 'function', + 'annotation', 'TypeVar bound', 'type alias', and 'type parameter'. """ if self._table.type == _symtable.TYPE_MODULE: return "module" @@ -71,8 +71,15 @@ def get_type(self): return "function" if self._table.type == _symtable.TYPE_CLASS: return "class" - assert self._table.type in (1, 2, 3), \ - "unexpected type: {0}".format(self._table.type) + if self._table.type == _symtable.TYPE_ANNOTATION: + return "annotation" + if self._table.type == _symtable.TYPE_TYPE_VAR_BOUND: + return "TypeVar bound" + if self._table.type == _symtable.TYPE_TYPE_ALIAS: + return "type alias" + if self._table.type == _symtable.TYPE_TYPE_PARAM: + return "type parameter" + assert False, f"unexpected type: {self._table.type}" def get_id(self): """Return an identifier for the table. diff --git a/Lib/sysconfig.py b/Lib/sysconfig/__init__.py similarity index 73% rename from Lib/sysconfig.py rename to Lib/sysconfig/__init__.py index a8b5c5f7dfba5b..68d30c0f9e618f 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig/__init__.py @@ -180,12 +180,6 @@ def joinuser(*args): _CONFIG_VARS_INITIALIZED = False _USER_BASE = None -# Regexes needed for parsing Makefile (and similar syntaxes, -# like old-style Setup files). -_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)" -_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)" -_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}" - def _safe_realpath(path): try: @@ -317,134 +311,6 @@ def get_default_scheme(): return get_preferred_scheme('prefix') -def _parse_makefile(filename, vars=None, keep_unresolved=True): - """Parse a Makefile-style file. - - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - import re - - if vars is None: - vars = {} - done = {} - notdone = {} - - with open(filename, encoding=sys.getfilesystemencoding(), - errors="surrogateescape") as f: - lines = f.readlines() - - for line in lines: - if line.startswith('#') or line.strip() == '': - continue - m = re.match(_variable_rx, line) - if m: - n, v = m.group(1, 2) - v = v.strip() - # `$$' is a literal `$' in make - tmpv = v.replace('$$', '') - - if "$" in tmpv: - notdone[n] = v - else: - try: - if n in _ALWAYS_STR: - raise ValueError - - v = int(v) - except ValueError: - # insert literal `$' - done[n] = v.replace('$$', '$') - else: - done[n] = v - - # do variable interpolation here - variables = list(notdone.keys()) - - # Variables with a 'PY_' prefix in the makefile. These need to - # be made available without that prefix through sysconfig. - # Special care is needed to ensure that variable expansion works, even - # if the expansion uses the name without a prefix. - renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') - - while len(variables) > 0: - for name in tuple(variables): - value = notdone[name] - m1 = re.search(_findvar1_rx, value) - m2 = re.search(_findvar2_rx, value) - if m1 and m2: - m = m1 if m1.start() < m2.start() else m2 - else: - m = m1 if m1 else m2 - if m is not None: - n = m.group(1) - found = True - if n in done: - item = str(done[n]) - elif n in notdone: - # get it on a subsequent round - found = False - elif n in os.environ: - # do it like make: fall back to environment - item = os.environ[n] - - elif n in renamed_variables: - if (name.startswith('PY_') and - name[3:] in renamed_variables): - item = "" - - elif 'PY_' + n in notdone: - found = False - - else: - item = str(done['PY_' + n]) - - else: - done[n] = item = "" - - if found: - after = value[m.end():] - value = value[:m.start()] + item + after - if "$" in after: - notdone[name] = value - else: - try: - if name in _ALWAYS_STR: - raise ValueError - value = int(value) - except ValueError: - done[name] = value.strip() - else: - done[name] = value - variables.remove(name) - - if name.startswith('PY_') \ - and name[3:] in renamed_variables: - - name = name[3:] - if name not in done: - done[name] = value - - else: - # Adds unresolved variables to the done dict. - # This is disabled when called from distutils.sysconfig - if keep_unresolved: - done[name] = value - # bogus variable reference (e.g. "prefix=$/opt/python"); - # just drop it since we can't deal - variables.remove(name) - - # strip spurious spaces - for k, v in done.items(): - if isinstance(v, str): - done[k] = v.strip() - - # save the results in the global dictionary - vars.update(done) - return vars - - def get_makefile_filename(): """Return the path of the Makefile.""" if _PYTHON_BUILD: @@ -465,74 +331,6 @@ def _get_sysconfigdata_name(): f'_sysconfigdata_{sys.abiflags}_{sys.platform}_{multiarch}', ) -def _print_config_dict(d, stream): - print ("{", file=stream) - for k, v in sorted(d.items()): - print(f" {k!r}: {v!r},", file=stream) - print ("}", file=stream) - -def _generate_posix_vars(): - """Generate the Python module containing build-time variables.""" - vars = {} - # load the installed Makefile: - makefile = get_makefile_filename() - try: - _parse_makefile(makefile, vars) - except OSError as e: - msg = f"invalid Python installation: unable to open {makefile}" - if hasattr(e, "strerror"): - msg = f"{msg} ({e.strerror})" - raise OSError(msg) - # load the installed pyconfig.h: - config_h = get_config_h_filename() - try: - with open(config_h, encoding="utf-8") as f: - parse_config_h(f, vars) - except OSError as e: - msg = f"invalid Python installation: unable to open {config_h}" - if hasattr(e, "strerror"): - msg = f"{msg} ({e.strerror})" - raise OSError(msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile - # -- these paths are relative to the Python source, but when installed - # the scripts are in another directory. - if _PYTHON_BUILD: - vars['BLDSHARED'] = vars['LDSHARED'] - - # There's a chicken-and-egg situation on OS X with regards to the - # _sysconfigdata module after the changes introduced by #15298: - # get_config_vars() is called by get_platform() as part of the - # `make pybuilddir.txt` target -- which is a precursor to the - # _sysconfigdata.py module being constructed. Unfortunately, - # get_config_vars() eventually calls _init_posix(), which attempts - # to import _sysconfigdata, which we won't have built yet. In order - # for _init_posix() to work, if we're on Darwin, just mock up the - # _sysconfigdata module manually and populate it with the build vars. - # This is more than sufficient for ensuring the subsequent call to - # get_platform() succeeds. - name = _get_sysconfigdata_name() - if 'darwin' in sys.platform: - import types - module = types.ModuleType(name) - module.build_time_vars = vars - sys.modules[name] = module - - pybuilddir = f'build/lib.{get_platform()}-{_PY_VERSION_SHORT}' - if hasattr(sys, "gettotalrefcount"): - pybuilddir += '-pydebug' - os.makedirs(pybuilddir, exist_ok=True) - destfile = os.path.join(pybuilddir, name + '.py') - - with open(destfile, 'w', encoding='utf8') as f: - f.write('# system configuration generated and used by' - ' the sysconfig module\n') - f.write('build_time_vars = ') - _print_config_dict(vars, stream=f) - - # Create file used for sys.path fixup -- see Modules/getpath.c - with open('pybuilddir.txt', 'w', encoding='utf8') as f: - f.write(pybuilddir) - def _init_posix(vars): """Initialize the module as appropriate for POSIX systems.""" # _sysconfigdata is generated at build time, see _generate_posix_vars() @@ -544,16 +342,20 @@ def _init_posix(vars): def _init_non_posix(vars): """Initialize the module as appropriate for NT""" # set basic install directories - import _imp + import _winapi + import _sysconfig vars['LIBDEST'] = get_path('stdlib') vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') - try: - # GH-99201: _imp.extension_suffixes may be empty when - # HAVE_DYNAMIC_LOADING is not set. In this case, don't set EXT_SUFFIX. - vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] - except IndexError: - pass + + # Add EXT_SUFFIX, SOABI, and Py_NOGIL + vars.update(_sysconfig.config_vars()) + + vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) + if hasattr(sys, 'dllhandle'): + dllhandle = _winapi.GetModuleFileName(sys.dllhandle) + vars['LIBRARY'] = os.path.basename(_safe_realpath(dllhandle)) + vars['LDLIBRARY'] = vars['LIBRARY'] vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) @@ -853,28 +655,3 @@ def expand_makefile_vars(s, vars): else: break return s - - -def _print_dict(title, data): - for index, (key, value) in enumerate(sorted(data.items())): - if index == 0: - print(f'{title}: ') - print(f'\t{key} = "{value}"') - - -def _main(): - """Display all information sysconfig detains.""" - if '--generate-posix-vars' in sys.argv: - _generate_posix_vars() - return - print(f'Platform: "{get_platform()}"') - print(f'Python version: "{get_python_version()}"') - print(f'Current installation scheme: "{get_default_scheme()}"') - print() - _print_dict('Paths', get_paths()) - print() - _print_dict('Variables', get_config_vars()) - - -if __name__ == '__main__': - _main() diff --git a/Lib/sysconfig/__main__.py b/Lib/sysconfig/__main__.py new file mode 100644 index 00000000000000..d7257b9d2d00db --- /dev/null +++ b/Lib/sysconfig/__main__.py @@ -0,0 +1,248 @@ +import os +import sys +from sysconfig import ( + _ALWAYS_STR, + _PYTHON_BUILD, + _get_sysconfigdata_name, + get_config_h_filename, + get_config_vars, + get_default_scheme, + get_makefile_filename, + get_paths, + get_platform, + get_python_version, + parse_config_h, +) + + +# Regexes needed for parsing Makefile (and similar syntaxes, +# like old-style Setup files). +_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)" +_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)" +_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}" + + +def _parse_makefile(filename, vars=None, keep_unresolved=True): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + import re + + if vars is None: + vars = {} + done = {} + notdone = {} + + with open(filename, encoding=sys.getfilesystemencoding(), + errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = re.match(_variable_rx, line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + if n in _ALWAYS_STR: + raise ValueError + + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m1 = re.search(_findvar1_rx, value) + m2 = re.search(_findvar2_rx, value) + if m1 and m2: + m = m1 if m1.start() < m2.start() else m2 + else: + m = m1 if m1 else m2 + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if (name.startswith('PY_') and + name[3:] in renamed_variables): + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + if name in _ALWAYS_STR: + raise ValueError + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if name.startswith('PY_') \ + and name[3:] in renamed_variables: + + name = name[3:] + if name not in done: + done[name] = value + + else: + # Adds unresolved variables to the done dict. + # This is disabled when called from distutils.sysconfig + if keep_unresolved: + done[name] = value + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def _print_config_dict(d, stream): + print ("{", file=stream) + for k, v in sorted(d.items()): + print(f" {k!r}: {v!r},", file=stream) + print ("}", file=stream) + + +def _generate_posix_vars(): + """Generate the Python module containing build-time variables.""" + vars = {} + # load the installed Makefile: + makefile = get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except OSError as e: + msg = f"invalid Python installation: unable to open {makefile}" + if hasattr(e, "strerror"): + msg = f"{msg} ({e.strerror})" + raise OSError(msg) + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h, encoding="utf-8") as f: + parse_config_h(f, vars) + except OSError as e: + msg = f"invalid Python installation: unable to open {config_h}" + if hasattr(e, "strerror"): + msg = f"{msg} ({e.strerror})" + raise OSError(msg) + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['BLDSHARED'] = vars['LDSHARED'] + + # There's a chicken-and-egg situation on OS X with regards to the + # _sysconfigdata module after the changes introduced by #15298: + # get_config_vars() is called by get_platform() as part of the + # `make pybuilddir.txt` target -- which is a precursor to the + # _sysconfigdata.py module being constructed. Unfortunately, + # get_config_vars() eventually calls _init_posix(), which attempts + # to import _sysconfigdata, which we won't have built yet. In order + # for _init_posix() to work, if we're on Darwin, just mock up the + # _sysconfigdata module manually and populate it with the build vars. + # This is more than sufficient for ensuring the subsequent call to + # get_platform() succeeds. + name = _get_sysconfigdata_name() + if 'darwin' in sys.platform: + import types + module = types.ModuleType(name) + module.build_time_vars = vars + sys.modules[name] = module + + pybuilddir = f'build/lib.{get_platform()}-{get_python_version()}' + if hasattr(sys, "gettotalrefcount"): + pybuilddir += '-pydebug' + os.makedirs(pybuilddir, exist_ok=True) + destfile = os.path.join(pybuilddir, name + '.py') + + with open(destfile, 'w', encoding='utf8') as f: + f.write('# system configuration generated and used by' + ' the sysconfig module\n') + f.write('build_time_vars = ') + _print_config_dict(vars, stream=f) + + # Create file used for sys.path fixup -- see Modules/getpath.c + with open('pybuilddir.txt', 'w', encoding='utf8') as f: + f.write(pybuilddir) + + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print(f'{title}: ') + print(f'\t{key} = "{value}"') + + +def _main(): + """Display all information sysconfig detains.""" + if '--generate-posix-vars' in sys.argv: + _generate_posix_vars() + return + print(f'Platform: "{get_platform()}"') + print(f'Python version: "{get_python_version()}"') + print(f'Current installation scheme: "{get_default_scheme()}"') + print() + _print_dict('Paths', get_paths()) + print() + _print_dict('Variables', get_config_vars()) + + +if __name__ == '__main__': + try: + _main() + except BrokenPipeError: + pass diff --git a/Lib/tarfile.py b/Lib/tarfile.py index df4e41f7a0d23a..ec32f9ba49b03f 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -46,7 +46,6 @@ import struct import copy import re -import warnings try: import pwd @@ -372,8 +371,8 @@ def __init__(self, name, mode, comptype, fileobj, bufsize, self.zlib = zlib self.crc = zlib.crc32(b"") if mode == "r": - self._init_read_gz() self.exception = zlib.error + self._init_read_gz() else: self._init_write_gz(compresslevel) @@ -742,7 +741,7 @@ def __init__(self, tarinfo): class AbsoluteLinkError(FilterError): def __init__(self, tarinfo): self.tarinfo = tarinfo - super().__init__(f'{tarinfo.name!r} is a symlink to an absolute path') + super().__init__(f'{tarinfo.name!r} is a link to an absolute path') class LinkOutsideDestinationError(FilterError): def __init__(self, tarinfo, path): @@ -802,7 +801,14 @@ def _get_filtered_attrs(member, dest_path, for_data=True): if member.islnk() or member.issym(): if os.path.isabs(member.linkname): raise AbsoluteLinkError(member) - target_path = os.path.realpath(os.path.join(dest_path, member.linkname)) + if member.issym(): + target_path = os.path.join(dest_path, + os.path.dirname(name), + member.linkname) + else: + target_path = os.path.join(dest_path, + member.linkname) + target_path = os.path.realpath(target_path) if os.path.commonpath([target_path, dest_path]) != dest_path: raise LinkOutsideDestinationError(member, target_path) return new_attrs @@ -2212,6 +2218,7 @@ def _get_filter_function(self, filter): if filter is None: filter = self.extraction_filter if filter is None: + import warnings warnings.warn( 'Python 3.14 will, by default, filter extracted tar ' + 'archives and reject files or modify their metadata. ' @@ -2550,7 +2557,8 @@ def chown(self, tarinfo, targetpath, numeric_owner): os.lchown(targetpath, u, g) else: os.chown(targetpath, u, g) - except OSError as e: + except (OSError, OverflowError) as e: + # OverflowError can be raised if an ID doesn't fit in `id_t` raise ExtractError("could not change owner") from e def chmod(self, tarinfo, targetpath): diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml new file mode 100644 index 00000000000000..424c81f6ecd759 --- /dev/null +++ b/Lib/test/.ruff.toml @@ -0,0 +1,32 @@ +fix = true +select = [ + "F811", # Redefinition of unused variable (useful for finding test methods with the same name) +] +extend-exclude = [ + # Excluded (run with the other AC files in its own separate ruff job in pre-commit) + "test_clinic.py", + # Excluded (these aren't actually executed, they're just "data files") + "tokenizedata/*.py", + # Failed to lint + "encoded_modules/module_iso_8859_1.py", + "encoded_modules/module_koi8_r.py", + # TODO Fix: F811 Redefinition of unused name + "test__opcode.py", + "test_buffer.py", + "test_ctypes/test_arrays.py", + "test_ctypes/test_functions.py", + "test_dataclasses/__init__.py", + "test_descr.py", + "test_enum.py", + "test_functools.py", + "test_genericclass.py", + "test_grammar.py", + "test_import/__init__.py", + "test_keywordonlyarg.py", + "test_pkg.py", + "test_subclassinit.py", + "test_yield_from.py", + "time_hashlib.py", + # Pending https://github.com/python/cpython/pull/109139 + "test_monitoring.py", +] diff --git a/Lib/test/__main__.py b/Lib/test/__main__.py index 19a6b2b8904526..82b50ad2c6e777 100644 --- a/Lib/test/__main__.py +++ b/Lib/test/__main__.py @@ -1,2 +1,2 @@ -from test.libregrtest import main -main() +from test.libregrtest.main import main +main(_add_python_opts=True) diff --git a/Lib/test/_test_eintr.py b/Lib/test/_test_eintr.py index 006581f7cc6a9a..15586f15dfab30 100644 --- a/Lib/test/_test_eintr.py +++ b/Lib/test/_test_eintr.py @@ -25,6 +25,12 @@ from test.support import os_helper from test.support import socket_helper + +# gh-109592: Tolerate a difference of 20 ms when comparing timings +# (clock resolution) +CLOCK_RES = 0.020 + + @contextlib.contextmanager def kill_on_error(proc): """Context manager killing the subprocess if a Python exception is raised.""" @@ -75,6 +81,9 @@ def subprocess(self, *args, **kw): cmd_args = (sys.executable, '-c') + args return subprocess.Popen(cmd_args, **kw) + def check_elapsed_time(self, elapsed): + self.assertGreaterEqual(elapsed, self.sleep_time - CLOCK_RES) + @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") class OSEINTRTest(EINTRBaseTest): @@ -373,7 +382,7 @@ def test_sleep(self): time.sleep(self.sleep_time) self.stop_alarm() dt = time.monotonic() - t0 - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") @@ -435,7 +444,7 @@ def test_select(self): select.select([], [], [], self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipIf(sys.platform == "darwin", "poll may fail on macOS; see issue #28087") @@ -447,7 +456,7 @@ def test_poll(self): poller.poll(self.sleep_time * 1e3) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'epoll'), 'need select.epoll') def test_epoll(self): @@ -458,7 +467,7 @@ def test_epoll(self): poller.poll(self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'kqueue'), 'need select.kqueue') def test_kqueue(self): @@ -469,7 +478,7 @@ def test_kqueue(self): kqueue.control(None, 1, self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'devpoll'), 'need select.devpoll') def test_devpoll(self): @@ -480,7 +489,7 @@ def test_devpoll(self): poller.poll(self.sleep_time * 1e3) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) class FNTLEINTRTest(EINTRBaseTest): @@ -512,8 +521,8 @@ def _lock(self, lock_func, lock_name): # potential context switch delay lock_func(f, fcntl.LOCK_EX) dt = time.monotonic() - start_time - self.assertGreaterEqual(dt, self.sleep_time) self.stop_alarm() + self.check_elapsed_time(dt) proc.wait() # Issue 35633: See https://bugs.python.org/issue35633#msg333662 diff --git a/Lib/test/_test_embed_set_config.py b/Lib/test/_test_embed_set_config.py index 0c016b5d75d734..a2ddd133cf47c8 100644 --- a/Lib/test/_test_embed_set_config.py +++ b/Lib/test/_test_embed_set_config.py @@ -9,9 +9,9 @@ import os import sys import unittest +from test.support import MS_WINDOWS -MS_WINDOWS = (os.name == 'nt') MAX_HASH_SEED = 4294967295 class SetConfigTests(unittest.TestCase): diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index c1f9487ae80511..0b333ca3b7e9dc 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -78,10 +78,15 @@ msvcrt = None -if support.check_sanitizer(address=True): - # bpo-45200: Skip multiprocessing tests if Python is built with ASAN to +if support.HAVE_ASAN_FORK_BUG: + # gh-89363: Skip multiprocessing tests if Python is built with ASAN to # work around a libasan race condition: dead lock in pthread_create(). - raise unittest.SkipTest("libasan has a pthread_create() dead lock") + raise unittest.SkipTest("libasan has a pthread_create() dead lock related to thread+fork") + + +# gh-110666: Tolerate a difference of 100 ms when comparing timings +# (clock resolution) +CLOCK_RES = 0.100 def latin(s): @@ -329,6 +334,7 @@ def test_set_executable(self): p.join() self.assertEqual(p.exitcode, 0) + @support.requires_resource('cpu') def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. @@ -556,13 +562,14 @@ def handler(*args): def test_terminate(self): exitcode = self._kill_process(multiprocessing.Process.terminate) - if os.name != 'nt': - self.assertEqual(exitcode, -signal.SIGTERM) + self.assertEqual(exitcode, -signal.SIGTERM) def test_kill(self): exitcode = self._kill_process(multiprocessing.Process.kill) if os.name != 'nt': self.assertEqual(exitcode, -signal.SIGKILL) + else: + self.assertEqual(exitcode, -signal.SIGTERM) def test_cpu_count(self): try: @@ -674,6 +681,7 @@ def test_close(self): close_queue(q) + @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1648,12 +1656,11 @@ def test_waitfor(self): def _test_waitfor_timeout_f(cls, cond, state, success, sem): sem.release() with cond: - expected = 0.1 + expected = 0.100 dt = time.monotonic() result = cond.wait_for(lambda : state.value==4, timeout=expected) dt = time.monotonic() - dt - # borrow logic in assertTimeout() from test/lock_tests.py - if not result and expected * 0.6 < dt < expected * 10.0: + if not result and (expected - CLOCK_RES) <= dt: success.value = True @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') @@ -1672,7 +1679,7 @@ def test_waitfor_timeout(self): # Only increment 3 times, so state == 4 is never reached. for i in range(3): - time.sleep(0.01) + time.sleep(0.010) with cond: state.value += 1 cond.notify() @@ -2571,7 +2578,7 @@ def test_async(self): self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1) def test_async_timeout(self): - res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 1.0)) + res = self.pool.apply_async(sqr, (6, TIMEOUT2 + support.SHORT_TIMEOUT)) get = TimingWrapper(res.get) self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2) self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2) @@ -2675,14 +2682,11 @@ def test_make_pool(self): p.join() def test_terminate(self): - result = self.pool.map_async( - time.sleep, [0.1 for i in range(10000)], chunksize=1 - ) + # Simulate slow tasks which take "forever" to complete + args = [support.LONG_TIMEOUT for i in range(10_000)] + result = self.pool.map_async(time.sleep, args, chunksize=1) self.pool.terminate() - join = TimingWrapper(self.pool.join) - join() - # Sanity check the pool didn't wait for all tasks to finish - self.assertLess(join.elapsed, 2.0) + self.pool.join() def test_empty_iterable(self): # See Issue 12157 @@ -3149,6 +3153,44 @@ def test_rapid_restart(self): if hasattr(manager, "shutdown"): self.addCleanup(manager.shutdown) + +class FakeConnection: + def send(self, payload): + pass + + def recv(self): + return '#ERROR', pyqueue.Empty() + +class TestManagerExceptions(unittest.TestCase): + # Issue 106558: Manager exceptions avoids creating cyclic references. + def setUp(self): + self.mgr = multiprocessing.Manager() + + def tearDown(self): + self.mgr.shutdown() + self.mgr.join() + + def test_queue_get(self): + queue = self.mgr.Queue() + if gc.isenabled(): + gc.disable() + self.addCleanup(gc.enable) + try: + queue.get_nowait() + except pyqueue.Empty as e: + wr = weakref.ref(e) + self.assertEqual(wr(), None) + + def test_dispatch(self): + if gc.isenabled(): + gc.disable() + self.addCleanup(gc.enable) + try: + multiprocessing.managers.dispatch(FakeConnection(), None, None) + except pyqueue.Empty as e: + wr = weakref.ref(e) + self.assertEqual(wr(), None) + # # # @@ -4466,6 +4508,7 @@ def test_finalize(self): result = [obj for obj in iter(conn.recv, 'STOP')] self.assertEqual(result, ['a', 'b', 'd10', 'd03', 'd02', 'd01', 'e']) + @support.requires_resource('cpu') def test_thread_safety(self): # bpo-24484: _run_finalizers() should be thread-safe def cb(): @@ -4866,7 +4909,7 @@ class TestWait(unittest.TestCase): def _child_test_wait(cls, w, slow): for i in range(10): if slow: - time.sleep(random.random()*0.1) + time.sleep(random.random() * 0.100) w.send((i, os.getpid())) w.close() @@ -4906,7 +4949,7 @@ def _child_test_wait_socket(cls, address, slow): s.connect(address) for i in range(10): if slow: - time.sleep(random.random()*0.1) + time.sleep(random.random() * 0.100) s.sendall(('%s\n' % i).encode('ascii')) s.close() @@ -4951,34 +4994,30 @@ def test_wait_slow(self): def test_wait_socket_slow(self): self.test_wait_socket(True) + @support.requires_resource('walltime') def test_wait_timeout(self): from multiprocessing.connection import wait - expected = 5 + timeout = 5.0 # seconds a, b = multiprocessing.Pipe() start = time.monotonic() - res = wait([a, b], expected) + res = wait([a, b], timeout) delta = time.monotonic() - start self.assertEqual(res, []) - self.assertLess(delta, expected * 2) - self.assertGreater(delta, expected * 0.5) + self.assertGreater(delta, timeout - CLOCK_RES) b.send(None) - - start = time.monotonic() res = wait([a, b], 20) - delta = time.monotonic() - start - self.assertEqual(res, [a]) - self.assertLess(delta, 0.4) @classmethod def signal_and_sleep(cls, sem, period): sem.release() time.sleep(period) + @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait @@ -5331,6 +5370,14 @@ def test_context(self): self.assertRaises(ValueError, ctx.set_start_method, None) self.check_context(ctx) + def test_context_check_module_types(self): + try: + ctx = multiprocessing.get_context('forkserver') + except ValueError: + raise unittest.SkipTest('forkserver should be available') + with self.assertRaisesRegex(TypeError, 'module_names must be a list of strings'): + ctx.set_forkserver_preload([1, 2, 3]) + def test_set_get(self): multiprocessing.set_forkserver_preload(PRELOAD) count = 0 @@ -5375,6 +5422,56 @@ def test_preload_resources(self): print(err) self.fail("failed spawning forkserver or grandchild") + @unittest.skipIf(sys.platform == "win32", + "Only Spawn on windows so no risk of mixing") + @only_run_in_spawn_testsuite("avoids redundant testing.") + def test_mixed_startmethod(self): + # Fork-based locks cannot be used with spawned process + for process_method in ["spawn", "forkserver"]: + queue = multiprocessing.get_context("fork").Queue() + process_ctx = multiprocessing.get_context(process_method) + p = process_ctx.Process(target=close_queue, args=(queue,)) + err_msg = "A SemLock created in a fork" + with self.assertRaisesRegex(RuntimeError, err_msg): + p.start() + + # non-fork-based locks can be used with all other start methods + for queue_method in ["spawn", "forkserver"]: + for process_method in multiprocessing.get_all_start_methods(): + queue = multiprocessing.get_context(queue_method).Queue() + process_ctx = multiprocessing.get_context(process_method) + p = process_ctx.Process(target=close_queue, args=(queue,)) + p.start() + p.join() + + @classmethod + def _put_one_in_queue(cls, queue): + queue.put(1) + + @classmethod + def _put_two_and_nest_once(cls, queue): + queue.put(2) + process = multiprocessing.Process(target=cls._put_one_in_queue, args=(queue,)) + process.start() + process.join() + + def test_nested_startmethod(self): + # gh-108520: Regression test to ensure that child process can send its + # arguments to another process + queue = multiprocessing.Queue() + + process = multiprocessing.Process(target=self._put_two_and_nest_once, args=(queue,)) + process.start() + process.join() + + results = [] + while not queue.empty(): + results.append(queue.get()) + + # gh-109706: queue.put(1) can write into the queue before queue.put(2), + # there is no synchronization in the test. + self.assertSetEqual(set(results), set([2, 1])) + @unittest.skipIf(sys.platform == "win32", "test semantics don't make sense on Windows") @@ -6058,7 +6155,8 @@ class ThreadsMixin(BaseMixin): # Functions used to create test cases from the base ones in this module # -def install_tests_in_module_dict(remote_globs, start_method): +def install_tests_in_module_dict(remote_globs, start_method, + only_type=None, exclude_types=False): __module__ = remote_globs['__name__'] local_globs = globals() ALL_TYPES = {'processes', 'threads', 'manager'} @@ -6071,6 +6169,10 @@ def install_tests_in_module_dict(remote_globs, start_method): continue assert set(base.ALLOWED_TYPES) <= ALL_TYPES, base.ALLOWED_TYPES for type_ in base.ALLOWED_TYPES: + if only_type and type_ != only_type: + continue + if exclude_types: + continue newname = 'With' + type_.capitalize() + name[1:] Mixin = local_globs[type_.capitalize() + 'Mixin'] class Temp(base, Mixin, unittest.TestCase): @@ -6081,6 +6183,9 @@ class Temp(base, Mixin, unittest.TestCase): Temp.__module__ = __module__ remote_globs[newname] = Temp elif issubclass(base, unittest.TestCase): + if only_type: + continue + class Temp(base, object): pass Temp.__name__ = Temp.__qualname__ = name diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index 0edc9d9c472766..f0cedde308d53b 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -186,7 +186,7 @@ class C(A): ) -def test_open(): +def test_open(testfn): # SSLContext.load_dh_params uses _Py_fopen_obj rather than normal open() try: import ssl @@ -199,11 +199,11 @@ def test_open(): # All of them should fail with TestHook(raise_on_events={"open"}) as hook: for fn, *args in [ - (open, sys.argv[2], "r"), + (open, testfn, "r"), (open, sys.executable, "rb"), (open, 3, "wb"), - (open, sys.argv[2], "w", -1, None, None, None, False, lambda *a: 1), - (load_dh_params, sys.argv[2]), + (open, testfn, "w", -1, None, None, None, False, lambda *a: 1), + (load_dh_params, testfn), ]: if not fn: continue @@ -216,11 +216,11 @@ def test_open(): [ i for i in [ - (sys.argv[2], "r"), + (testfn, "r"), (sys.executable, "r"), (3, "w"), - (sys.argv[2], "w"), - (sys.argv[2], "rb") if load_dh_params else None, + (testfn, "w"), + (testfn, "rb") if load_dh_params else None, ] if i is not None ], @@ -289,7 +289,7 @@ def hook(event, args): def test_unraisablehook(): - from _testcapi import write_unraisable_exc + from _testinternalcapi import write_unraisable_exc def unraisablehook(hookargs): pass @@ -398,15 +398,18 @@ def hook(event, *args): cx2 = sqlite3.Connection(":memory:") # Configured without --enable-loadable-sqlite-extensions - if hasattr(sqlite3.Connection, "enable_load_extension"): - cx1.enable_load_extension(False) - try: - cx1.load_extension("test") - except sqlite3.OperationalError: - pass - else: - raise RuntimeError("Expected sqlite3.load_extension to fail") - + try: + if hasattr(sqlite3.Connection, "enable_load_extension"): + cx1.enable_load_extension(False) + try: + cx1.load_extension("test") + except sqlite3.OperationalError: + pass + else: + raise RuntimeError("Expected sqlite3.load_extension to fail") + finally: + cx1.close() + cx2.close() def test_sys_getframe(): import sys @@ -514,10 +517,39 @@ def test_not_in_gc(): assert hook not in o +def test_time(mode): + import time + + def hook(event, args): + if event.startswith("time."): + if mode == 'print': + print(event, *args) + elif mode == 'fail': + raise AssertionError('hook failed') + sys.addaudithook(hook) + + time.sleep(0) + time.sleep(0.0625) # 1/16, a small exact float + try: + time.sleep(-1) + except ValueError: + pass + +def test_sys_monitoring_register_callback(): + import sys + + def hook(event, args): + if event.startswith("sys.monitoring"): + print(event, args) + + sys.addaudithook(hook) + sys.monitoring.register_callback(1, 1, None) + + if __name__ == "__main__": from test.support import suppress_msvcrt_asserts suppress_msvcrt_asserts() test = sys.argv[1] - globals()[test]() + globals()[test](*sys.argv[2:]) diff --git a/Lib/test/autotest.py b/Lib/test/autotest.py index fa85cc153a133a..b5a1fab404c72d 100644 --- a/Lib/test/autotest.py +++ b/Lib/test/autotest.py @@ -1,5 +1,5 @@ # This should be equivalent to running regrtest.py from the cmdline. # It can be especially handy if you're in an interactive shell, e.g., # from test import autotest. -from test.libregrtest import main +from test.libregrtest.main import main main() diff --git a/Lib/test/badsyntax_future3.py b/Lib/test/badsyntax_future3.py deleted file mode 100644 index f1c8417edaa297..00000000000000 --- a/Lib/test/badsyntax_future3.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" -from __future__ import nested_scopes -from __future__ import rested_snopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/badsyntax_future4.py b/Lib/test/badsyntax_future4.py deleted file mode 100644 index b5f4c98e922ac2..00000000000000 --- a/Lib/test/badsyntax_future4.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" -import __future__ -from __future__ import nested_scopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/badsyntax_future5.py b/Lib/test/badsyntax_future5.py deleted file mode 100644 index 8a7e5fcb70ff2e..00000000000000 --- a/Lib/test/badsyntax_future5.py +++ /dev/null @@ -1,12 +0,0 @@ -"""This is a test""" -from __future__ import nested_scopes -import foo -from __future__ import nested_scopes - - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/badsyntax_future6.py b/Lib/test/badsyntax_future6.py deleted file mode 100644 index 5a8b55a02c41bf..00000000000000 --- a/Lib/test/badsyntax_future6.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" -"this isn't a doc string" -from __future__ import nested_scopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/badsyntax_future7.py b/Lib/test/badsyntax_future7.py deleted file mode 100644 index 131db2c2164cf2..00000000000000 --- a/Lib/test/badsyntax_future7.py +++ /dev/null @@ -1,11 +0,0 @@ -"""This is a test""" - -from __future__ import nested_scopes; import string; from __future__ import \ - nested_scopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/badsyntax_future8.py b/Lib/test/badsyntax_future8.py deleted file mode 100644 index ca45289e2e5a4f..00000000000000 --- a/Lib/test/badsyntax_future8.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" - -from __future__ import * - -def f(x): - def g(y): - return x + y - return g - -print(f(2)(4)) diff --git a/Lib/test/badsyntax_future9.py b/Lib/test/badsyntax_future9.py deleted file mode 100644 index 916de06ab71e97..00000000000000 --- a/Lib/test/badsyntax_future9.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" - -from __future__ import nested_scopes, braces - -def f(x): - def g(y): - return x + y - return g - -print(f(2)(4)) diff --git a/Lib/test/bisect_cmd.py b/Lib/test/bisect_cmd.py index 0bdd7a43c03f7b..5cb804bd469dc3 100755 --- a/Lib/test/bisect_cmd.py +++ b/Lib/test/bisect_cmd.py @@ -109,9 +109,10 @@ def parse_args(): def main(): args = parse_args() - if '-w' in args.test_args or '--verbose2' in args.test_args: - print("WARNING: -w/--verbose2 option should not be used to bisect!") - print() + for opt in ('-w', '--rerun', '--verbose2'): + if opt in args.test_args: + print(f"WARNING: {opt} option should not be used to bisect!") + print() if args.input: with open(args.input) as fp: diff --git a/Lib/test/allsans.pem b/Lib/test/certdata/allsans.pem similarity index 100% rename from Lib/test/allsans.pem rename to Lib/test/certdata/allsans.pem diff --git a/Lib/test/badcert.pem b/Lib/test/certdata/badcert.pem similarity index 100% rename from Lib/test/badcert.pem rename to Lib/test/certdata/badcert.pem diff --git a/Lib/test/badkey.pem b/Lib/test/certdata/badkey.pem similarity index 100% rename from Lib/test/badkey.pem rename to Lib/test/certdata/badkey.pem diff --git a/Lib/test/capath/4e1295a3.0 b/Lib/test/certdata/capath/4e1295a3.0 similarity index 100% rename from Lib/test/capath/4e1295a3.0 rename to Lib/test/certdata/capath/4e1295a3.0 diff --git a/Lib/test/capath/5ed36f99.0 b/Lib/test/certdata/capath/5ed36f99.0 similarity index 100% rename from Lib/test/capath/5ed36f99.0 rename to Lib/test/certdata/capath/5ed36f99.0 diff --git a/Lib/test/capath/6e88d7b8.0 b/Lib/test/certdata/capath/6e88d7b8.0 similarity index 100% rename from Lib/test/capath/6e88d7b8.0 rename to Lib/test/certdata/capath/6e88d7b8.0 diff --git a/Lib/test/capath/99d0fa06.0 b/Lib/test/certdata/capath/99d0fa06.0 similarity index 100% rename from Lib/test/capath/99d0fa06.0 rename to Lib/test/certdata/capath/99d0fa06.0 diff --git a/Lib/test/capath/b1930218.0 b/Lib/test/certdata/capath/b1930218.0 similarity index 100% rename from Lib/test/capath/b1930218.0 rename to Lib/test/certdata/capath/b1930218.0 diff --git a/Lib/test/capath/ceff1710.0 b/Lib/test/certdata/capath/ceff1710.0 similarity index 100% rename from Lib/test/capath/ceff1710.0 rename to Lib/test/certdata/capath/ceff1710.0 diff --git a/Lib/test/ffdh3072.pem b/Lib/test/certdata/ffdh3072.pem similarity index 100% rename from Lib/test/ffdh3072.pem rename to Lib/test/certdata/ffdh3072.pem diff --git a/Lib/test/idnsans.pem b/Lib/test/certdata/idnsans.pem similarity index 100% rename from Lib/test/idnsans.pem rename to Lib/test/certdata/idnsans.pem diff --git a/Lib/test/keycert.passwd.pem b/Lib/test/certdata/keycert.passwd.pem similarity index 100% rename from Lib/test/keycert.passwd.pem rename to Lib/test/certdata/keycert.passwd.pem diff --git a/Lib/test/keycert.pem b/Lib/test/certdata/keycert.pem similarity index 100% rename from Lib/test/keycert.pem rename to Lib/test/certdata/keycert.pem diff --git a/Lib/test/keycert2.pem b/Lib/test/certdata/keycert2.pem similarity index 100% rename from Lib/test/keycert2.pem rename to Lib/test/certdata/keycert2.pem diff --git a/Lib/test/keycert3.pem b/Lib/test/certdata/keycert3.pem similarity index 100% rename from Lib/test/keycert3.pem rename to Lib/test/certdata/keycert3.pem diff --git a/Lib/test/keycert4.pem b/Lib/test/certdata/keycert4.pem similarity index 100% rename from Lib/test/keycert4.pem rename to Lib/test/certdata/keycert4.pem diff --git a/Lib/test/keycertecc.pem b/Lib/test/certdata/keycertecc.pem similarity index 100% rename from Lib/test/keycertecc.pem rename to Lib/test/certdata/keycertecc.pem diff --git a/Lib/test/make_ssl_certs.py b/Lib/test/certdata/make_ssl_certs.py similarity index 100% rename from Lib/test/make_ssl_certs.py rename to Lib/test/certdata/make_ssl_certs.py diff --git a/Lib/test/nokia.pem b/Lib/test/certdata/nokia.pem similarity index 100% rename from Lib/test/nokia.pem rename to Lib/test/certdata/nokia.pem diff --git a/Lib/test/nosan.pem b/Lib/test/certdata/nosan.pem similarity index 100% rename from Lib/test/nosan.pem rename to Lib/test/certdata/nosan.pem diff --git a/Lib/test/nullbytecert.pem b/Lib/test/certdata/nullbytecert.pem similarity index 100% rename from Lib/test/nullbytecert.pem rename to Lib/test/certdata/nullbytecert.pem diff --git a/Lib/test/nullcert.pem b/Lib/test/certdata/nullcert.pem similarity index 100% rename from Lib/test/nullcert.pem rename to Lib/test/certdata/nullcert.pem diff --git a/Lib/test/pycacert.pem b/Lib/test/certdata/pycacert.pem similarity index 100% rename from Lib/test/pycacert.pem rename to Lib/test/certdata/pycacert.pem diff --git a/Lib/test/pycakey.pem b/Lib/test/certdata/pycakey.pem similarity index 100% rename from Lib/test/pycakey.pem rename to Lib/test/certdata/pycakey.pem diff --git a/Lib/test/revocation.crl b/Lib/test/certdata/revocation.crl similarity index 100% rename from Lib/test/revocation.crl rename to Lib/test/certdata/revocation.crl diff --git a/Lib/test/secp384r1.pem b/Lib/test/certdata/secp384r1.pem similarity index 100% rename from Lib/test/secp384r1.pem rename to Lib/test/certdata/secp384r1.pem diff --git a/Lib/test/selfsigned_pythontestdotnet.pem b/Lib/test/certdata/selfsigned_pythontestdotnet.pem similarity index 100% rename from Lib/test/selfsigned_pythontestdotnet.pem rename to Lib/test/certdata/selfsigned_pythontestdotnet.pem diff --git a/Lib/test/ssl_cert.pem b/Lib/test/certdata/ssl_cert.pem similarity index 100% rename from Lib/test/ssl_cert.pem rename to Lib/test/certdata/ssl_cert.pem diff --git a/Lib/test/ssl_key.passwd.pem b/Lib/test/certdata/ssl_key.passwd.pem similarity index 100% rename from Lib/test/ssl_key.passwd.pem rename to Lib/test/certdata/ssl_key.passwd.pem diff --git a/Lib/test/ssl_key.pem b/Lib/test/certdata/ssl_key.pem similarity index 100% rename from Lib/test/ssl_key.pem rename to Lib/test/certdata/ssl_key.pem diff --git a/Lib/test/talos-2019-0758.pem b/Lib/test/certdata/talos-2019-0758.pem similarity index 100% rename from Lib/test/talos-2019-0758.pem rename to Lib/test/certdata/talos-2019-0758.pem diff --git a/Lib/test/clinic.test.c b/Lib/test/clinic.test.c index da99e58c77f021..2ef7a6e8eb2795 100644 --- a/Lib/test/clinic.test.c +++ b/Lib/test/clinic.test.c @@ -4,9 +4,11 @@ output preset block /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c81ac2402d06a8b]*/ /*[clinic input] +module m +class m.T "TestObj *" "TestType" class Test "TestObj *" "TestType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fc7e50384d12b83f]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f761b4d55cb179cf]*/ /*[clinic input] test_object_converter @@ -471,7 +473,7 @@ test_bool_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - c = _PyLong_AsInt(args[2]); + c = PyLong_AsInt(args[2]); if (c == -1 && PyErr_Occurred()) { goto exit; } @@ -484,7 +486,7 @@ test_bool_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) static PyObject * test_bool_converter_impl(PyObject *module, int a, int b, int c) -/*[clinic end generated code: output=27f0e653a70b9be3 input=939854fa9f248c60]*/ +/*[clinic end generated code: output=3190e46490de0644 input=939854fa9f248c60]*/ /*[clinic input] @@ -1007,14 +1009,14 @@ test_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - a = _PyLong_AsInt(args[0]); + a = PyLong_AsInt(args[0]); if (a == -1 && PyErr_Occurred()) { goto exit; } if (nargs < 2) { goto skip_optional; } - b = _PyLong_AsInt(args[1]); + b = PyLong_AsInt(args[1]); if (b == -1 && PyErr_Occurred()) { goto exit; } @@ -1033,7 +1035,7 @@ test_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - d = _PyLong_AsInt(args[3]); + d = PyLong_AsInt(args[3]); if (d == -1 && PyErr_Occurred()) { goto exit; } @@ -1046,7 +1048,7 @@ test_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) static PyObject * test_int_converter_impl(PyObject *module, int a, int b, int c, myenum d) -/*[clinic end generated code: output=375eedba5ca9a5b3 input=d20541fc1ca0553e]*/ +/*[clinic end generated code: output=5aed87a7589eefb2 input=d20541fc1ca0553e]*/ /*[clinic input] @@ -4507,7 +4509,7 @@ Test_cls_with_param(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_ if (!args) { goto exit; } - a = _PyLong_AsInt(args[0]); + a = PyLong_AsInt(args[0]); if (a == -1 && PyErr_Occurred()) { goto exit; } @@ -4519,7 +4521,7 @@ Test_cls_with_param(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_ static PyObject * Test_cls_with_param_impl(TestObj *self, PyTypeObject *cls, int a) -/*[clinic end generated code: output=00218e7f583e6c81 input=af158077bd237ef9]*/ +/*[clinic end generated code: output=d89b99e83d442be0 input=af158077bd237ef9]*/ /*[clinic input] @@ -4701,7 +4703,7 @@ Test_an_metho_arg_named_arg(TestObj *self, PyObject *arg_) PyObject *return_value = NULL; int arg; - arg = _PyLong_AsInt(arg_); + arg = PyLong_AsInt(arg_); if (arg == -1 && PyErr_Occurred()) { goto exit; } @@ -4713,7 +4715,7 @@ Test_an_metho_arg_named_arg(TestObj *self, PyObject *arg_) static PyObject * Test_an_metho_arg_named_arg_impl(TestObj *self, int arg) -/*[clinic end generated code: output=7d590626642194ae input=2a53a57cf5624f95]*/ +/*[clinic end generated code: output=9f04de4a62287e28 input=2a53a57cf5624f95]*/ /*[clinic input] @@ -4948,3 +4950,520 @@ Test_meth_coexist(TestObj *self, PyObject *Py_UNUSED(ignored)) static PyObject * Test_meth_coexist_impl(TestObj *self) /*[clinic end generated code: output=808a293d0cd27439 input=2a1d75b5e6fec6dd]*/ + + +/*[clinic input] +output push +output preset buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5bff3376ee0df0b5]*/ + +/*[clinic input] +buffer_clear + a: int +We'll call 'destination buffer clear' after this. + +Argument Clinic's buffer preset puts most generated code into the +'buffer' destination, except from 'impl_definition', which is put into +the 'block' destination, so we should expect everything but +'impl_definition' to be cleared. +[clinic start generated code]*/ + +static PyObject * +buffer_clear_impl(PyObject *module, int a) +/*[clinic end generated code: output=f14bba74677e1846 input=a4c308a6fdab043c]*/ + +/*[clinic input] +destination buffer clear +output pop +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f20d06adb8252084]*/ + + +/*[clinic input] +output push +destination test1 new buffer +output everything suppress +output docstring_definition test1 +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5a77c454970992fc]*/ + +/*[clinic input] +new_dest + a: int +Only this docstring should be outputted to test1. +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=da5af421ed8996ed]*/ + +/*[clinic input] +dump test1 +output pop +[clinic start generated code]*/ + +PyDoc_STRVAR(new_dest__doc__, +"new_dest($module, /, a)\n" +"--\n" +"\n" +"Only this docstring should be outputted to test1."); +/*[clinic end generated code: output=9cac703f51d90e84 input=090db8df4945576d]*/ + + +/*[clinic input] +mangled_c_keyword_identifier + i as int: int +The 'int' param should be mangled as 'int_value' +[clinic start generated code]*/ + +PyDoc_STRVAR(mangled_c_keyword_identifier__doc__, +"mangled_c_keyword_identifier($module, /, i)\n" +"--\n" +"\n" +"The \'int\' param should be mangled as \'int_value\'"); + +#define MANGLED_C_KEYWORD_IDENTIFIER_METHODDEF \ + {"mangled_c_keyword_identifier", _PyCFunction_CAST(mangled_c_keyword_identifier), METH_FASTCALL|METH_KEYWORDS, mangled_c_keyword_identifier__doc__}, + +static PyObject * +mangled_c_keyword_identifier_impl(PyObject *module, int int_value); + +static PyObject * +mangled_c_keyword_identifier(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(i), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"i", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mangled_c_keyword_identifier", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int int_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + int_value = PyLong_AsInt(args[0]); + if (int_value == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = mangled_c_keyword_identifier_impl(module, int_value); + +exit: + return return_value; +} + +static PyObject * +mangled_c_keyword_identifier_impl(PyObject *module, int int_value) +/*[clinic end generated code: output=f24b37e0368e0eb8 input=060876448ab567a2]*/ + + +/*[clinic input] +bool_return -> bool +[clinic start generated code]*/ + +PyDoc_STRVAR(bool_return__doc__, +"bool_return($module, /)\n" +"--\n" +"\n"); + +#define BOOL_RETURN_METHODDEF \ + {"bool_return", (PyCFunction)bool_return, METH_NOARGS, bool_return__doc__}, + +static int +bool_return_impl(PyObject *module); + +static PyObject * +bool_return(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = bool_return_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +bool_return_impl(PyObject *module) +/*[clinic end generated code: output=3a65f07830e48e98 input=93ba95d39ee98f39]*/ + + +/*[clinic input] +double_return -> double +[clinic start generated code]*/ + +PyDoc_STRVAR(double_return__doc__, +"double_return($module, /)\n" +"--\n" +"\n"); + +#define DOUBLE_RETURN_METHODDEF \ + {"double_return", (PyCFunction)double_return, METH_NOARGS, double_return__doc__}, + +static double +double_return_impl(PyObject *module); + +static PyObject * +double_return(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + double _return_value; + + _return_value = double_return_impl(module); + if ((_return_value == -1.0) && PyErr_Occurred()) { + goto exit; + } + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; +} + +static double +double_return_impl(PyObject *module) +/*[clinic end generated code: output=076dc72595d3f66d input=da11b6255e4cbfd7]*/ + + +/*[clinic input] +Test.__init__ + a: object + [ + b: object + ] + / +Should generate two PyArg_ParseTuple calls. +[clinic start generated code]*/ + +PyDoc_STRVAR(Test___init____doc__, +"Test(a, [b])\n" +"Should generate two PyArg_ParseTuple calls."); + +static int +Test___init___impl(TestObj *self, PyObject *a, int group_right_1, + PyObject *b); + +static int +Test___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + PyTypeObject *base_tp = TestType; + PyObject *a; + int group_right_1 = 0; + PyObject *b = NULL; + + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && + !_PyArg_NoKeywords("Test", kwargs)) { + goto exit; + } + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:__init__", &a)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:__init__", &a, &b)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "Test.__init__ requires 1 to 2 arguments"); + goto exit; + } + return_value = Test___init___impl((TestObj *)self, a, group_right_1, b); + +exit: + return return_value; +} + +static int +Test___init___impl(TestObj *self, PyObject *a, int group_right_1, + PyObject *b) +/*[clinic end generated code: output=2bbb8ea60e8f57a6 input=10f5d0f1e8e466ef]*/ + + +/*[clinic input] +Test._pyarg_parsestackandkeywords + cls: defining_class + key: str(accept={str, robuffer}, zeroes=True) + / +Check that _PyArg_ParseStackAndKeywords() is generated. +[clinic start generated code]*/ + +PyDoc_STRVAR(Test__pyarg_parsestackandkeywords__doc__, +"_pyarg_parsestackandkeywords($self, key, /)\n" +"--\n" +"\n" +"Check that _PyArg_ParseStackAndKeywords() is generated."); + +#define TEST__PYARG_PARSESTACKANDKEYWORDS_METHODDEF \ + {"_pyarg_parsestackandkeywords", _PyCFunction_CAST(Test__pyarg_parsestackandkeywords), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, Test__pyarg_parsestackandkeywords__doc__}, + +static PyObject * +Test__pyarg_parsestackandkeywords_impl(TestObj *self, PyTypeObject *cls, + const char *key, + Py_ssize_t key_length); + +static PyObject * +Test__pyarg_parsestackandkeywords(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#:_pyarg_parsestackandkeywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + const char *key; + Py_ssize_t key_length; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &key, &key_length)) { + goto exit; + } + return_value = Test__pyarg_parsestackandkeywords_impl(self, cls, key, key_length); + +exit: + return return_value; +} + +static PyObject * +Test__pyarg_parsestackandkeywords_impl(TestObj *self, PyTypeObject *cls, + const char *key, + Py_ssize_t key_length) +/*[clinic end generated code: output=4fda8a7f2547137c input=fc72ef4b4cfafabc]*/ + + +/*[clinic input] +Test.__init__ -> long +Test overriding the __init__ return converter +[clinic start generated code]*/ + +PyDoc_STRVAR(Test___init____doc__, +"Test()\n" +"--\n" +"\n" +"Test overriding the __init__ return converter"); + +static long +Test___init___impl(TestObj *self); + +static int +Test___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + PyTypeObject *base_tp = TestType; + long _return_value; + + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && + !_PyArg_NoPositional("Test", args)) { + goto exit; + } + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && + !_PyArg_NoKeywords("Test", kwargs)) { + goto exit; + } + _return_value = Test___init___impl((TestObj *)self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +static long +Test___init___impl(TestObj *self) +/*[clinic end generated code: output=daf6ee12c4e443fb input=311af0dc7f17e8e9]*/ + + +/*[clinic input] +fn_with_default_binop_expr + arg: object(c_default='CONST_A + CONST_B') = a+b +[clinic start generated code]*/ + +PyDoc_STRVAR(fn_with_default_binop_expr__doc__, +"fn_with_default_binop_expr($module, /, arg=a+b)\n" +"--\n" +"\n"); + +#define FN_WITH_DEFAULT_BINOP_EXPR_METHODDEF \ + {"fn_with_default_binop_expr", _PyCFunction_CAST(fn_with_default_binop_expr), METH_FASTCALL|METH_KEYWORDS, fn_with_default_binop_expr__doc__}, + +static PyObject * +fn_with_default_binop_expr_impl(PyObject *module, PyObject *arg); + +static PyObject * +fn_with_default_binop_expr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(arg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"arg", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fn_with_default_binop_expr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *arg = CONST_A + CONST_B; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + arg = args[0]; +skip_optional_pos: + return_value = fn_with_default_binop_expr_impl(module, arg); + +exit: + return return_value; +} + +static PyObject * +fn_with_default_binop_expr_impl(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=018672772e4092ff input=1b55c8ae68d89453]*/ + + +/*[python input] +class Custom_converter(CConverter): + type = "str" + default = "Hello!" + converter = "c_converter_func" +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=d612708f0efb8e3c]*/ + +/*[clinic input] +docstr_fallback_to_converter_default + a: Custom +Check docstring default value fallback. + +Verify that the docstring formatter fetches the default +value from the converter if no 'py_default' is found. +The signature should have the default a='Hello!', +as given by the Custom converter. +[clinic start generated code]*/ + +PyDoc_STRVAR(docstr_fallback_to_converter_default__doc__, +"docstr_fallback_to_converter_default($module, /, a=\'Hello!\')\n" +"--\n" +"\n" +"Check docstring default value fallback.\n" +"\n" +"Verify that the docstring formatter fetches the default\n" +"value from the converter if no \'py_default\' is found.\n" +"The signature should have the default a=\'Hello!\',\n" +"as given by the Custom converter."); + +#define DOCSTR_FALLBACK_TO_CONVERTER_DEFAULT_METHODDEF \ + {"docstr_fallback_to_converter_default", _PyCFunction_CAST(docstr_fallback_to_converter_default), METH_FASTCALL|METH_KEYWORDS, docstr_fallback_to_converter_default__doc__}, + +static PyObject * +docstr_fallback_to_converter_default_impl(PyObject *module, str a); + +static PyObject * +docstr_fallback_to_converter_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "docstr_fallback_to_converter_default", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + str a; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!c_converter_func(args[0], &a)) { + goto exit; + } + return_value = docstr_fallback_to_converter_default_impl(module, a); + +exit: + return return_value; +} + +static PyObject * +docstr_fallback_to_converter_default_impl(PyObject *module, str a) +/*[clinic end generated code: output=ae24a9c6f60ee8a6 input=0cbe6a4d24bc2274]*/ diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 55e061950ff280..8bda17358db87f 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1699,22 +1699,23 @@ def test_replace(self): cls = self.theclass args = [1, 2, 3] base = cls(*args) - self.assertEqual(base, base.replace()) + self.assertEqual(base.replace(), base) + self.assertEqual(copy.replace(base), base) - i = 0 - for name, newval in (("year", 2), - ("month", 3), - ("day", 4)): + changes = (("year", 2), + ("month", 3), + ("day", 4)) + for i, (name, newval) in enumerate(changes): newargs = args[:] newargs[i] = newval expected = cls(*newargs) - got = base.replace(**{name: newval}) - self.assertEqual(expected, got) - i += 1 + self.assertEqual(base.replace(**{name: newval}), expected) + self.assertEqual(copy.replace(base, **{name: newval}), expected) # Out of bounds. base = cls(2000, 2, 29) self.assertRaises(ValueError, base.replace, year=2001) + self.assertRaises(ValueError, copy.replace, base, year=2001) def test_subclass_replace(self): class DateSubclass(self.theclass): @@ -1722,6 +1723,7 @@ class DateSubclass(self.theclass): dt = DateSubclass(2012, 1, 1) self.assertIs(type(dt.replace(year=2013)), DateSubclass) + self.assertIs(type(copy.replace(dt, year=2013)), DateSubclass) def test_subclass_date(self): @@ -2856,26 +2858,27 @@ def test_replace(self): cls = self.theclass args = [1, 2, 3, 4, 5, 6, 7] base = cls(*args) - self.assertEqual(base, base.replace()) - - i = 0 - for name, newval in (("year", 2), - ("month", 3), - ("day", 4), - ("hour", 5), - ("minute", 6), - ("second", 7), - ("microsecond", 8)): + self.assertEqual(base.replace(), base) + self.assertEqual(copy.replace(base), base) + + changes = (("year", 2), + ("month", 3), + ("day", 4), + ("hour", 5), + ("minute", 6), + ("second", 7), + ("microsecond", 8)) + for i, (name, newval) in enumerate(changes): newargs = args[:] newargs[i] = newval expected = cls(*newargs) - got = base.replace(**{name: newval}) - self.assertEqual(expected, got) - i += 1 + self.assertEqual(base.replace(**{name: newval}), expected) + self.assertEqual(copy.replace(base, **{name: newval}), expected) # Out of bounds. base = cls(2000, 2, 29) self.assertRaises(ValueError, base.replace, year=2001) + self.assertRaises(ValueError, copy.replace, base, year=2001) @support.run_with_tz('EDT4') def test_astimezone(self): @@ -3671,19 +3674,19 @@ def test_replace(self): cls = self.theclass args = [1, 2, 3, 4] base = cls(*args) - self.assertEqual(base, base.replace()) - - i = 0 - for name, newval in (("hour", 5), - ("minute", 6), - ("second", 7), - ("microsecond", 8)): + self.assertEqual(base.replace(), base) + self.assertEqual(copy.replace(base), base) + + changes = (("hour", 5), + ("minute", 6), + ("second", 7), + ("microsecond", 8)) + for i, (name, newval) in enumerate(changes): newargs = args[:] newargs[i] = newval expected = cls(*newargs) - got = base.replace(**{name: newval}) - self.assertEqual(expected, got) - i += 1 + self.assertEqual(base.replace(**{name: newval}), expected) + self.assertEqual(copy.replace(base, **{name: newval}), expected) # Out of bounds. base = cls(1) @@ -3691,6 +3694,10 @@ def test_replace(self): self.assertRaises(ValueError, base.replace, minute=-1) self.assertRaises(ValueError, base.replace, second=100) self.assertRaises(ValueError, base.replace, microsecond=1000000) + self.assertRaises(ValueError, copy.replace, base, hour=24) + self.assertRaises(ValueError, copy.replace, base, minute=-1) + self.assertRaises(ValueError, copy.replace, base, second=100) + self.assertRaises(ValueError, copy.replace, base, microsecond=1000000) def test_subclass_replace(self): class TimeSubclass(self.theclass): @@ -3698,6 +3705,7 @@ class TimeSubclass(self.theclass): ctime = TimeSubclass(12, 30) self.assertIs(type(ctime.replace(hour=10)), TimeSubclass) + self.assertIs(type(copy.replace(ctime, hour=10)), TimeSubclass) def test_subclass_time(self): @@ -4085,31 +4093,37 @@ def test_replace(self): zm200 = FixedOffset(timedelta(minutes=-200), "-200") args = [1, 2, 3, 4, z100] base = cls(*args) - self.assertEqual(base, base.replace()) - - i = 0 - for name, newval in (("hour", 5), - ("minute", 6), - ("second", 7), - ("microsecond", 8), - ("tzinfo", zm200)): + self.assertEqual(base.replace(), base) + self.assertEqual(copy.replace(base), base) + + changes = (("hour", 5), + ("minute", 6), + ("second", 7), + ("microsecond", 8), + ("tzinfo", zm200)) + for i, (name, newval) in enumerate(changes): newargs = args[:] newargs[i] = newval expected = cls(*newargs) - got = base.replace(**{name: newval}) - self.assertEqual(expected, got) - i += 1 + self.assertEqual(base.replace(**{name: newval}), expected) + self.assertEqual(copy.replace(base, **{name: newval}), expected) # Ensure we can get rid of a tzinfo. self.assertEqual(base.tzname(), "+100") base2 = base.replace(tzinfo=None) self.assertIsNone(base2.tzinfo) self.assertIsNone(base2.tzname()) + base22 = copy.replace(base, tzinfo=None) + self.assertIsNone(base22.tzinfo) + self.assertIsNone(base22.tzname()) # Ensure we can add one. base3 = base2.replace(tzinfo=z100) self.assertEqual(base, base3) self.assertIs(base.tzinfo, base3.tzinfo) + base32 = copy.replace(base22, tzinfo=z100) + self.assertEqual(base, base32) + self.assertIs(base.tzinfo, base32.tzinfo) # Out of bounds. base = cls(1) @@ -4117,6 +4131,10 @@ def test_replace(self): self.assertRaises(ValueError, base.replace, minute=-1) self.assertRaises(ValueError, base.replace, second=100) self.assertRaises(ValueError, base.replace, microsecond=1000000) + self.assertRaises(ValueError, copy.replace, base, hour=24) + self.assertRaises(ValueError, copy.replace, base, minute=-1) + self.assertRaises(ValueError, copy.replace, base, second=100) + self.assertRaises(ValueError, copy.replace, base, microsecond=1000000) def test_mixed_compare(self): t1 = self.theclass(1, 2, 3) @@ -4885,38 +4903,45 @@ def test_replace(self): zm200 = FixedOffset(timedelta(minutes=-200), "-200") args = [1, 2, 3, 4, 5, 6, 7, z100] base = cls(*args) - self.assertEqual(base, base.replace()) - - i = 0 - for name, newval in (("year", 2), - ("month", 3), - ("day", 4), - ("hour", 5), - ("minute", 6), - ("second", 7), - ("microsecond", 8), - ("tzinfo", zm200)): + self.assertEqual(base.replace(), base) + self.assertEqual(copy.replace(base), base) + + changes = (("year", 2), + ("month", 3), + ("day", 4), + ("hour", 5), + ("minute", 6), + ("second", 7), + ("microsecond", 8), + ("tzinfo", zm200)) + for i, (name, newval) in enumerate(changes): newargs = args[:] newargs[i] = newval expected = cls(*newargs) - got = base.replace(**{name: newval}) - self.assertEqual(expected, got) - i += 1 + self.assertEqual(base.replace(**{name: newval}), expected) + self.assertEqual(copy.replace(base, **{name: newval}), expected) # Ensure we can get rid of a tzinfo. self.assertEqual(base.tzname(), "+100") base2 = base.replace(tzinfo=None) self.assertIsNone(base2.tzinfo) self.assertIsNone(base2.tzname()) + base22 = copy.replace(base, tzinfo=None) + self.assertIsNone(base22.tzinfo) + self.assertIsNone(base22.tzname()) # Ensure we can add one. base3 = base2.replace(tzinfo=z100) self.assertEqual(base, base3) self.assertIs(base.tzinfo, base3.tzinfo) + base32 = copy.replace(base22, tzinfo=z100) + self.assertEqual(base, base32) + self.assertIs(base.tzinfo, base32.tzinfo) # Out of bounds. base = cls(2000, 2, 29) self.assertRaises(ValueError, base.replace, year=2001) + self.assertRaises(ValueError, copy.replace, base, year=2001) def test_more_astimezone(self): # The inherited test_astimezone covered some trivial and error cases. diff --git a/Lib/test/libregrtest/__init__.py b/Lib/test/libregrtest/__init__.py index 5e8dba5dbde71a..e69de29bb2d1d6 100644 --- a/Lib/test/libregrtest/__init__.py +++ b/Lib/test/libregrtest/__init__.py @@ -1,2 +0,0 @@ -from test.libregrtest.cmdline import _parse_args, RESOURCE_NAMES, ALL_RESOURCES -from test.libregrtest.main import main diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index ebe57920d9185c..dd4cd335bef7e3 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -1,8 +1,9 @@ import argparse -import os +import os.path import shlex import sys from test.support import os_helper +from .utils import ALL_RESOURCES, RESOURCE_NAMES USAGE = """\ @@ -27,8 +28,10 @@ Additional option details: -r randomizes test execution order. You can use --randseed=int to provide an -int seed value for the randomizer; this is useful for reproducing troublesome -test orders. +int seed value for the randomizer. The randseed value will be used +to set seeds for all random usages in tests +(including randomizing the tests order if -r is set). +By default we always set random seed, but do not randomize test order. -s On the first invocation of regrtest using -s, the first test file found or the first test file given on the command line is run, and the name of @@ -107,6 +110,8 @@ cpu - Used for certain CPU-heavy tests. + walltime - Long running but not CPU-bound tests. + subprocess Run all tests for the subprocess module. urlfetch - It is okay to download files required on testing. @@ -128,25 +133,17 @@ """ -ALL_RESOURCES = ('audio', 'curses', 'largefile', 'network', - 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui') - -# Other resources excluded from --use=all: -# -# - extralagefile (ex: test_zipfile64): really too slow to be enabled -# "by default" -# - tzdata: while needed to validate fully test_datetime, it makes -# test_datetime too slow (15-20 min on some buildbots) and so is disabled by -# default (see bpo-30822). -RESOURCE_NAMES = ALL_RESOURCES + ('extralargefile', 'tzdata') - - class Namespace(argparse.Namespace): def __init__(self, **kwargs) -> None: + self.ci = False self.testdir = None self.verbose = 0 self.quiet = False self.exclude = False + self.cleanup = False + self.wait = False + self.list_cases = False + self.list_tests = False self.single = False self.randomize = False self.fromfile = None @@ -155,8 +152,8 @@ def __init__(self, **kwargs) -> None: self.trace = False self.coverdir = 'coverage' self.runleaks = False - self.huntrleaks = False - self.verbose2 = False + self.huntrleaks: tuple[int, int, str] | None = None + self.rerun = False self.verbose3 = False self.print_slow = False self.random_seed = None @@ -168,6 +165,14 @@ def __init__(self, **kwargs) -> None: self.ignore_tests = None self.pgo = False self.pgo_extended = False + self.worker_json = None + self.start = None + self.timeout = None + self.memlimit = None + self.threshold = None + self.fail_rerun = False + self.tempdir = None + self._add_python_opts = True super().__init__(**kwargs) @@ -196,25 +201,35 @@ def _create_parser(): # We add help explicitly to control what argument group it renders under. group.add_argument('-h', '--help', action='help', help='show this help message and exit') - group.add_argument('--timeout', metavar='TIMEOUT', type=float, + group.add_argument('--fast-ci', action='store_true', + help='Fast Continuous Integration (CI) mode used by ' + 'GitHub Actions') + group.add_argument('--slow-ci', action='store_true', + help='Slow Continuous Integration (CI) mode used by ' + 'buildbot workers') + group.add_argument('--timeout', metavar='TIMEOUT', help='dump the traceback and exit if a test takes ' 'more than TIMEOUT seconds; disabled if TIMEOUT ' 'is negative or equals to zero') group.add_argument('--wait', action='store_true', help='wait for user input, e.g., allow a debugger ' 'to be attached') - group.add_argument('--worker-args', metavar='ARGS') group.add_argument('-S', '--start', metavar='START', help='the name of the test at which to start.' + more_details) group.add_argument('-p', '--python', metavar='PYTHON', help='Command to run Python test subprocesses with.') + group.add_argument('--randseed', metavar='SEED', + dest='random_seed', type=int, + help='pass a global random seed') group = parser.add_argument_group('Verbosity') group.add_argument('-v', '--verbose', action='count', help='run tests in verbose mode with output to stdout') - group.add_argument('-w', '--verbose2', action='store_true', + group.add_argument('-w', '--rerun', action='store_true', help='re-run failed tests in verbose mode') + group.add_argument('--verbose2', action='store_true', dest='rerun', + help='deprecated alias to --rerun') group.add_argument('-W', '--verbose3', action='store_true', help='display test output on failure') group.add_argument('-q', '--quiet', action='store_true', @@ -227,10 +242,6 @@ def _create_parser(): group = parser.add_argument_group('Selecting tests') group.add_argument('-r', '--randomize', action='store_true', help='randomize test execution order.' + more_details) - group.add_argument('--randseed', metavar='SEED', - dest='random_seed', type=int, - help='pass a random seed to reproduce a previous ' - 'random run') group.add_argument('-f', '--fromfile', metavar='FILE', help='read names of tests to run from a file.' + more_details) @@ -309,6 +320,9 @@ def _create_parser(): group.add_argument('--fail-env-changed', action='store_true', help='if a test file alters the environment, mark ' 'the test as failed') + group.add_argument('--fail-rerun', action='store_true', + help='if a test failed and then passed when re-run, ' + 'mark the tests as failed') group.add_argument('--junit-xml', dest='xmlpath', metavar='FILENAME', help='writes JUnit-style XML results to the specified ' @@ -317,6 +331,9 @@ def _create_parser(): help='override the working directory for the test run') group.add_argument('--cleanup', action='store_true', help='remove old test_python_* directories') + group.add_argument('--dont-add-python-opts', dest='_add_python_opts', + action='store_false', + help="internal option, don't use it") return parser @@ -367,7 +384,50 @@ def _parse_args(args, **kwargs): for arg in ns.args: if arg.startswith('-'): parser.error("unrecognized arguments: %s" % arg) - sys.exit(1) + + if ns.timeout is not None: + # Support "--timeout=" (no value) so Makefile.pre.pre TESTTIMEOUT + # can be used by "make buildbottest" and "make test". + if ns.timeout != "": + try: + ns.timeout = float(ns.timeout) + except ValueError: + parser.error(f"invalid timeout value: {ns.timeout!r}") + else: + ns.timeout = None + + # Continuous Integration (CI): common options for fast/slow CI modes + if ns.slow_ci or ns.fast_ci: + # Similar to options: + # + # -j0 --randomize --fail-env-changed --fail-rerun --rerun + # --slowest --verbose3 + if ns.use_mp is None: + ns.use_mp = 0 + ns.randomize = True + ns.fail_env_changed = True + ns.fail_rerun = True + if ns.python is None: + ns.rerun = True + ns.print_slow = True + ns.verbose3 = True + else: + ns._add_python_opts = False + + # When both --slow-ci and --fast-ci options are present, + # --slow-ci has the priority + if ns.slow_ci: + # Similar to: -u "all" --timeout=1200 + if not ns.use: + ns.use = [['all']] + if ns.timeout is None: + ns.timeout = 1200 # 20 minutes + elif ns.fast_ci: + # Similar to: -u "all,-cpu" --timeout=600 + if not ns.use: + ns.use = [['all', '-cpu']] + if ns.timeout is None: + ns.timeout = 600 # 10 minutes if ns.single and ns.fromfile: parser.error("-s and -f don't go together!") @@ -380,7 +440,7 @@ def _parse_args(args, **kwargs): ns.python = shlex.split(ns.python) if ns.failfast and not (ns.verbose or ns.verbose3): parser.error("-G/--failfast needs either -v or -W") - if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3): + if ns.pgo and (ns.verbose or ns.rerun or ns.verbose3): parser.error("--pgo/-v don't go together!") if ns.pgo_extended: ns.pgo = True # pgo_extended implies pgo @@ -394,10 +454,6 @@ def _parse_args(args, **kwargs): if ns.timeout is not None: if ns.timeout <= 0: ns.timeout = None - if ns.use_mp is not None: - if ns.use_mp <= 0: - # Use all cores + extras for tests that like to sleep - ns.use_mp = 2 + (os.cpu_count() or 1) if ns.use: for a in ns.use: for r in a: @@ -441,4 +497,13 @@ def _parse_args(args, **kwargs): # --forever implies --failfast ns.failfast = True + if ns.huntrleaks: + warmup, repetitions, _ = ns.huntrleaks + if warmup < 1 or repetitions < 1: + msg = ("Invalid values for the --huntrleaks/-R parameters. The " + "number of warmups and repetitions must be at least 1 " + "each (1:1).") + print(msg, file=sys.stderr, flush=True) + sys.exit(2) + return ns diff --git a/Lib/test/libregrtest/findtests.py b/Lib/test/libregrtest/findtests.py new file mode 100644 index 00000000000000..caf2872cfc9a18 --- /dev/null +++ b/Lib/test/libregrtest/findtests.py @@ -0,0 +1,106 @@ +import os +import sys +import unittest + +from test import support + +from .utils import ( + StrPath, TestName, TestTuple, TestList, FilterTuple, + abs_module_name, count, printlist) + + +# If these test directories are encountered recurse into them and treat each +# "test_*.py" file or each sub-directory as a separate test module. This can +# increase parallelism. +# +# Beware this can't generally be done for any directory with sub-tests as the +# __init__.py may do things which alter what tests are to be run. +SPLITTESTDIRS: set[TestName] = { + "test_asyncio", + "test_concurrent_futures", + "test_future_stmt", + "test_gdb", + "test_inspect", + "test_multiprocessing_fork", + "test_multiprocessing_forkserver", + "test_multiprocessing_spawn", +} + + +def findtestdir(path: StrPath | None = None) -> StrPath: + return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir + + +def findtests(*, testdir: StrPath | None = None, exclude=(), + split_test_dirs: set[TestName] = SPLITTESTDIRS, + base_mod: str = "") -> TestList: + """Return a list of all applicable test modules.""" + testdir = findtestdir(testdir) + tests = [] + for name in os.listdir(testdir): + mod, ext = os.path.splitext(name) + if (not mod.startswith("test_")) or (mod in exclude): + continue + if base_mod: + fullname = f"{base_mod}.{mod}" + else: + fullname = mod + if fullname in split_test_dirs: + subdir = os.path.join(testdir, mod) + if not base_mod: + fullname = f"test.{mod}" + tests.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, + base_mod=fullname)) + elif ext in (".py", ""): + tests.append(fullname) + return sorted(tests) + + +def split_test_packages(tests, *, testdir: StrPath | None = None, exclude=(), + split_test_dirs=SPLITTESTDIRS): + testdir = findtestdir(testdir) + splitted = [] + for name in tests: + if name in split_test_dirs: + subdir = os.path.join(testdir, name) + splitted.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, + base_mod=name)) + else: + splitted.append(name) + return splitted + + +def _list_cases(suite): + for test in suite: + if isinstance(test, unittest.loader._FailedTest): + continue + if isinstance(test, unittest.TestSuite): + _list_cases(test) + elif isinstance(test, unittest.TestCase): + if support.match_test(test): + print(test.id()) + +def list_cases(tests: TestTuple, *, + match_tests: FilterTuple | None = None, + ignore_tests: FilterTuple | None = None, + test_dir: StrPath | None = None): + support.verbose = False + support.set_match_tests(match_tests, ignore_tests) + + skipped = [] + for test_name in tests: + module_name = abs_module_name(test_name, test_dir) + try: + suite = unittest.defaultTestLoader.loadTestsFromName(module_name) + _list_cases(suite) + except unittest.SkipTest: + skipped.append(test_name) + + if skipped: + sys.stdout.flush() + stderr = sys.stderr + print(file=stderr) + print(count(len(skipped), "test"), "skipped:", file=stderr) + printlist(skipped, file=stderr) diff --git a/Lib/test/libregrtest/logger.py b/Lib/test/libregrtest/logger.py new file mode 100644 index 00000000000000..a125706927393c --- /dev/null +++ b/Lib/test/libregrtest/logger.py @@ -0,0 +1,86 @@ +import os +import time + +from test.support import MS_WINDOWS +from .results import TestResults +from .runtests import RunTests +from .utils import print_warning + +if MS_WINDOWS: + from .win_utils import WindowsLoadTracker + + +class Logger: + def __init__(self, results: TestResults, quiet: bool, pgo: bool): + self.start_time = time.perf_counter() + self.test_count_text = '' + self.test_count_width = 3 + self.win_load_tracker: WindowsLoadTracker | None = None + self._results: TestResults = results + self._quiet: bool = quiet + self._pgo: bool = pgo + + def log(self, line: str = '') -> None: + empty = not line + + # add the system load prefix: "load avg: 1.80 " + load_avg = self.get_load_avg() + if load_avg is not None: + line = f"load avg: {load_avg:.2f} {line}" + + # add the timestamp prefix: "0:01:05 " + log_time = time.perf_counter() - self.start_time + + mins, secs = divmod(int(log_time), 60) + hours, mins = divmod(mins, 60) + formatted_log_time = "%d:%02d:%02d" % (hours, mins, secs) + + line = f"{formatted_log_time} {line}" + if empty: + line = line[:-1] + + print(line, flush=True) + + def get_load_avg(self) -> float | None: + if hasattr(os, 'getloadavg'): + return os.getloadavg()[0] + if self.win_load_tracker is not None: + return self.win_load_tracker.getloadavg() + return None + + def display_progress(self, test_index: int, text: str) -> None: + if self._quiet: + return + results = self._results + + # "[ 51/405/1] test_tcl passed" + line = f"{test_index:{self.test_count_width}}{self.test_count_text}" + fails = len(results.bad) + len(results.env_changed) + if fails and not self._pgo: + line = f"{line}/{fails}" + self.log(f"[{line}] {text}") + + def set_tests(self, runtests: RunTests) -> None: + if runtests.forever: + self.test_count_text = '' + self.test_count_width = 3 + else: + self.test_count_text = '/{}'.format(len(runtests.tests)) + self.test_count_width = len(self.test_count_text) - 1 + + def start_load_tracker(self) -> None: + if not MS_WINDOWS: + return + + try: + self.win_load_tracker = WindowsLoadTracker() + except PermissionError as error: + # Standard accounts may not have access to the performance + # counters. + print_warning(f'Failed to create WindowsLoadTracker: {error}') + + def stop_load_tracker(self) -> None: + if self.win_load_tracker is None: + return + self.win_load_tracker.close() + self.win_load_tracker = None diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 9001ca33b6166a..cb60d5af732b43 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -1,46 +1,30 @@ -import faulthandler -import locale import os -import platform import random import re +import shlex import sys import sysconfig -import tempfile import time -import unittest -from test.libregrtest.cmdline import _parse_args -from test.libregrtest.runtest import ( - findtests, runtest, get_abs_module, is_failed, - STDTESTS, NOTTESTS, PROGRESS_MIN_TIME, - Passed, Failed, EnvChanged, Skipped, ResourceDenied, Interrupted, - ChildError, DidNotRun) -from test.libregrtest.setup import setup_tests -from test.libregrtest.pgo import setup_pgo_tests -from test.libregrtest.utils import (removepy, count, format_duration, - printlist, get_build_info) -from test import support -from test.support import os_helper -from test.support import threading_helper - - -# bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()). -# Used to protect against threading._shutdown() hang. -# Must be smaller than buildbot "1200 seconds without output" limit. -EXIT_TIMEOUT = 120.0 - -# gh-90681: When rerunning tests, we might need to rerun the whole -# class or module suite if some its life-cycle hooks fail. -# Test level hooks are not affected. -_TEST_LIFECYCLE_HOOKS = frozenset(( - 'setUpClass', 'tearDownClass', - 'setUpModule', 'tearDownModule', -)) -EXITCODE_BAD_TEST = 2 -EXITCODE_INTERRUPTED = 130 -EXITCODE_ENV_CHANGED = 3 -EXITCODE_NO_TESTS_RAN = 4 +from test import support +from test.support import os_helper, MS_WINDOWS + +from .cmdline import _parse_args, Namespace +from .findtests import findtests, split_test_packages, list_cases +from .logger import Logger +from .pgo import setup_pgo_tests +from .result import State +from .results import TestResults, EXITCODE_INTERRUPTED +from .runtests import RunTests, HuntRefleak +from .setup import setup_process, setup_test_dir +from .single import run_single_test, PROGRESS_MIN_TIME +from .utils import ( + StrPath, StrJSON, TestName, TestList, TestTuple, FilterTuple, + strip_py_suffix, count, format_duration, + printlist, get_temp_dir, get_work_dir, exit_timeout, + display_header, cleanup_temp_dir, print_warning, + is_cross_compiled, get_host_runner, + EXIT_TIMEOUT) class Regrtest: @@ -66,263 +50,212 @@ class Regrtest: directly to set the values that would normally be set by flags on the command line. """ - def __init__(self): - # Namespace of command line options - self.ns = None + def __init__(self, ns: Namespace, _add_python_opts: bool = False): + # Log verbosity + self.verbose: int = int(ns.verbose) + self.quiet: bool = ns.quiet + self.pgo: bool = ns.pgo + self.pgo_extended: bool = ns.pgo_extended + + # Test results + self.results: TestResults = TestResults() + self.first_state: str | None = None + + # Logger + self.logger = Logger(self.results, self.quiet, self.pgo) + + # Actions + self.want_header: bool = ns.header + self.want_list_tests: bool = ns.list_tests + self.want_list_cases: bool = ns.list_cases + self.want_wait: bool = ns.wait + self.want_cleanup: bool = ns.cleanup + self.want_rerun: bool = ns.rerun + self.want_run_leaks: bool = ns.runleaks + + self.ci_mode: bool = (ns.fast_ci or ns.slow_ci) + self.want_add_python_opts: bool = (_add_python_opts + and ns._add_python_opts) + + # Select tests + if ns.match_tests: + self.match_tests: FilterTuple | None = tuple(ns.match_tests) + else: + self.match_tests = None + if ns.ignore_tests: + self.ignore_tests: FilterTuple | None = tuple(ns.ignore_tests) + else: + self.ignore_tests = None + self.exclude: bool = ns.exclude + self.fromfile: StrPath | None = ns.fromfile + self.starting_test: TestName | None = ns.start + self.cmdline_args: TestList = ns.args + + # Workers + if ns.use_mp is None: + num_workers = 0 # run sequentially + elif ns.use_mp <= 0: + num_workers = -1 # use the number of CPUs + else: + num_workers = ns.use_mp + self.num_workers: int = num_workers + self.worker_json: StrJSON | None = ns.worker_json + + # Options to run tests + self.fail_fast: bool = ns.failfast + self.fail_env_changed: bool = ns.fail_env_changed + self.fail_rerun: bool = ns.fail_rerun + self.forever: bool = ns.forever + self.output_on_failure: bool = ns.verbose3 + self.timeout: float | None = ns.timeout + if ns.huntrleaks: + warmups, runs, filename = ns.huntrleaks + filename = os.path.abspath(filename) + self.hunt_refleak: HuntRefleak | None = HuntRefleak(warmups, runs, filename) + else: + self.hunt_refleak = None + self.test_dir: StrPath | None = ns.testdir + self.junit_filename: StrPath | None = ns.xmlpath + self.memory_limit: str | None = ns.memlimit + self.gc_threshold: int | None = ns.threshold + self.use_resources: tuple[str, ...] = tuple(ns.use_resources) + if ns.python: + self.python_cmd: tuple[str, ...] | None = tuple(ns.python) + else: + self.python_cmd = None + self.coverage: bool = ns.trace + self.coverage_dir: StrPath | None = ns.coverdir + self.tmp_dir: StrPath | None = ns.tempdir + + # Randomize + self.randomize: bool = ns.randomize + self.random_seed: int | None = ( + ns.random_seed + if ns.random_seed is not None + else random.getrandbits(32) + ) + if 'SOURCE_DATE_EPOCH' in os.environ: + self.randomize = False + self.random_seed = None # tests - self.tests = [] - self.selected = [] - - # test results - self.good = [] - self.bad = [] - self.skipped = [] - self.resource_denieds = [] - self.environment_changed = [] - self.run_no_tests = [] - self.need_rerun = [] - self.rerun = [] - self.first_result = None - self.interrupted = False - - # used by --slow - self.test_times = [] - - # used by --coverage, trace.Trace instance - self.tracer = None + self.first_runtests: RunTests | None = None + + # used by --slowest + self.print_slowest: bool = ns.print_slow # used to display the progress bar "[ 3/100]" - self.start_time = time.monotonic() - self.test_count = '' - self.test_count_width = 1 + self.start_time = time.perf_counter() # used by --single - self.next_single_test = None - self.next_single_filename = None - - # used by --junit-xml - self.testsuite_xml = None - - # misc - self.win_load_tracker = None - self.tmp_dir = None - self.worker_test_name = None - - def get_executed(self): - return (set(self.good) | set(self.bad) | set(self.skipped) - | set(self.resource_denieds) | set(self.environment_changed) - | set(self.run_no_tests)) - - def accumulate_result(self, result, rerun=False): - test_name = result.name - - if not isinstance(result, (ChildError, Interrupted)) and not rerun: - self.test_times.append((result.duration_sec, test_name)) - - if isinstance(result, Passed): - self.good.append(test_name) - elif isinstance(result, ResourceDenied): - self.skipped.append(test_name) - self.resource_denieds.append(test_name) - elif isinstance(result, Skipped): - self.skipped.append(test_name) - elif isinstance(result, EnvChanged): - self.environment_changed.append(test_name) - elif isinstance(result, Failed): - if not rerun: - self.bad.append(test_name) - self.need_rerun.append(result) - elif isinstance(result, DidNotRun): - self.run_no_tests.append(test_name) - elif isinstance(result, Interrupted): - self.interrupted = True - else: - raise ValueError("invalid test result: %r" % result) - - if rerun and not isinstance(result, (Failed, Interrupted)): - self.bad.remove(test_name) - - xml_data = result.xml_data - if xml_data: - import xml.etree.ElementTree as ET - for e in xml_data: - try: - self.testsuite_xml.append(ET.fromstring(e)) - except ET.ParseError: - print(xml_data, file=sys.__stderr__) - raise + self.single_test_run: bool = ns.single + self.next_single_test: TestName | None = None + self.next_single_filename: StrPath | None = None def log(self, line=''): - empty = not line - - # add the system load prefix: "load avg: 1.80 " - load_avg = self.getloadavg() - if load_avg is not None: - line = f"load avg: {load_avg:.2f} {line}" - - # add the timestamp prefix: "0:01:05 " - test_time = time.monotonic() - self.start_time - - mins, secs = divmod(int(test_time), 60) - hours, mins = divmod(mins, 60) - test_time = "%d:%02d:%02d" % (hours, mins, secs) - - line = f"{test_time} {line}" - if empty: - line = line[:-1] - - print(line, flush=True) - - def display_progress(self, test_index, text): - if self.ns.quiet: - return - - # "[ 51/405/1] test_tcl passed" - line = f"{test_index:{self.test_count_width}}{self.test_count}" - fails = len(self.bad) + len(self.environment_changed) - if fails and not self.ns.pgo: - line = f"{line}/{fails}" - self.log(f"[{line}] {text}") - - def parse_args(self, kwargs): - ns = _parse_args(sys.argv[1:], **kwargs) - - if ns.xmlpath: - support.junit_xml_list = self.testsuite_xml = [] + self.logger.log(line) - worker_args = ns.worker_args - if worker_args is not None: - from test.libregrtest.runtest_mp import parse_worker_args - ns, test_name = parse_worker_args(ns.worker_args) - ns.worker_args = worker_args - self.worker_test_name = test_name - - # Strip .py extensions. - removepy(ns.args) - - if ns.huntrleaks: - warmup, repetitions, _ = ns.huntrleaks - if warmup < 1 or repetitions < 1: - msg = ("Invalid values for the --huntrleaks/-R parameters. The " - "number of warmups and repetitions must be at least 1 " - "each (1:1).") - print(msg, file=sys.stderr, flush=True) - sys.exit(2) - - if ns.tempdir: - ns.tempdir = os.path.expanduser(ns.tempdir) - - self.ns = ns - - def find_tests(self, tests): - self.tests = tests - - if self.ns.single: + def find_tests(self, tests: TestList | None = None) -> tuple[TestTuple, TestList | None]: + if self.single_test_run: self.next_single_filename = os.path.join(self.tmp_dir, 'pynexttest') try: with open(self.next_single_filename, 'r') as fp: next_test = fp.read().strip() - self.tests = [next_test] + tests = [next_test] except OSError: pass - if self.ns.fromfile: - self.tests = [] + if self.fromfile: + tests = [] # regex to match 'test_builtin' in line: # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec' regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b') - with open(os.path.join(os_helper.SAVEDCWD, self.ns.fromfile)) as fp: + with open(os.path.join(os_helper.SAVEDCWD, self.fromfile)) as fp: for line in fp: line = line.split('#', 1)[0] line = line.strip() match = regex.search(line) if match is not None: - self.tests.append(match.group()) + tests.append(match.group()) - removepy(self.tests) + strip_py_suffix(tests) - if self.ns.pgo: + if self.pgo: # add default PGO tests if no tests are specified - setup_pgo_tests(self.ns) - - stdtests = STDTESTS[:] - nottests = NOTTESTS.copy() - if self.ns.exclude: - for arg in self.ns.args: - if arg in stdtests: - stdtests.remove(arg) - nottests.add(arg) - self.ns.args = [] - - # if testdir is set, then we are not running the python tests suite, so - # don't add default tests to be executed or skipped (pass empty values) - if self.ns.testdir: - alltests = findtests(self.ns.testdir, list(), set()) - else: - alltests = findtests(self.ns.testdir, stdtests, nottests) + setup_pgo_tests(self.cmdline_args, self.pgo_extended) + + exclude_tests = set() + if self.exclude: + for arg in self.cmdline_args: + exclude_tests.add(arg) + self.cmdline_args = [] + + alltests = findtests(testdir=self.test_dir, + exclude=exclude_tests) - if not self.ns.fromfile: - self.selected = self.tests or self.ns.args or alltests + if not self.fromfile: + selected = tests or self.cmdline_args + if selected: + selected = split_test_packages(selected) + else: + selected = alltests else: - self.selected = self.tests - if self.ns.single: - self.selected = self.selected[:1] + selected = tests + + if self.single_test_run: + selected = selected[:1] try: - pos = alltests.index(self.selected[0]) + pos = alltests.index(selected[0]) self.next_single_test = alltests[pos + 1] except IndexError: pass # Remove all the selected tests that precede start if it's set. - if self.ns.start: + if self.starting_test: try: - del self.selected[:self.selected.index(self.ns.start)] + del selected[:selected.index(self.starting_test)] except ValueError: - print("Couldn't find starting test (%s), using all tests" - % self.ns.start, file=sys.stderr) + print(f"Cannot find starting test: {self.starting_test}") + sys.exit(1) - if self.ns.randomize: - if self.ns.random_seed is None: - self.ns.random_seed = random.randrange(10000000) - random.seed(self.ns.random_seed) - random.shuffle(self.selected) + random.seed(self.random_seed) + if self.randomize: + random.shuffle(selected) - def list_tests(self): - for name in self.selected: - print(name) + return (tuple(selected), tests) - def _list_cases(self, suite): - for test in suite: - if isinstance(test, unittest.loader._FailedTest): - continue - if isinstance(test, unittest.TestSuite): - self._list_cases(test) - elif isinstance(test, unittest.TestCase): - if support.match_test(test): - print(test.id()) - - def list_cases(self): - support.verbose = False - support.set_match_tests(self.ns.match_tests, self.ns.ignore_tests) - - for test_name in self.selected: - abstest = get_abs_module(self.ns, test_name) - try: - suite = unittest.defaultTestLoader.loadTestsFromName(abstest) - self._list_cases(suite) - except unittest.SkipTest: - self.skipped.append(test_name) - - if self.skipped: - print(file=sys.stderr) - print(count(len(self.skipped), "test"), "skipped:", file=sys.stderr) - printlist(self.skipped, file=sys.stderr) - - def rerun_failed_tests(self): - self.log() + @staticmethod + def list_tests(tests: TestTuple): + for name in tests: + print(name) - if self.ns.python: + def _rerun_failed_tests(self, runtests: RunTests): + # Configure the runner to re-run tests + if self.num_workers == 0: + # Always run tests in fresh processes to have more deterministic + # initial state. Don't re-run tests in parallel but limit to a + # single worker process to have side effects (on the system load + # and timings) between tests. + self.num_workers = 1 + + tests, match_tests_dict = self.results.prepare_rerun() + + # Re-run failed tests + self.log(f"Re-running {len(tests)} failed tests in verbose mode in subprocesses") + runtests = runtests.copy( + tests=tests, + rerun=True, + verbose=True, + forever=False, + fail_fast=False, + match_tests_dict=match_tests_dict, + output_on_failure=False) + self.logger.set_tests(runtests) + self._run_tests_mp(runtests, self.num_workers) + return runtests + + def rerun_failed_tests(self, runtests: RunTests): + if self.python_cmd: # Temp patch for https://github.com/python/cpython/issues/94052 self.log( "Re-running failed tests is not supported with --python " @@ -330,297 +263,107 @@ def rerun_failed_tests(self): ) return - self.ns.verbose = True - self.ns.failfast = False - self.ns.verbose3 = False - - self.first_result = self.get_tests_result() - - self.log("Re-running failed tests in verbose mode") - rerun_list = list(self.need_rerun) - self.need_rerun.clear() - for result in rerun_list: - test_name = result.name - self.rerun.append(test_name) - - errors = result.errors or [] - failures = result.failures or [] - error_names = [ - self.normalize_test_name(test_full_name, is_error=True) - for (test_full_name, *_) in errors] - failure_names = [ - self.normalize_test_name(test_full_name) - for (test_full_name, *_) in failures] - self.ns.verbose = True - orig_match_tests = self.ns.match_tests - if errors or failures: - if self.ns.match_tests is None: - self.ns.match_tests = [] - self.ns.match_tests.extend(error_names) - self.ns.match_tests.extend(failure_names) - matching = "matching: " + ", ".join(self.ns.match_tests) - self.log(f"Re-running {test_name} in verbose mode ({matching})") - else: - self.log(f"Re-running {test_name} in verbose mode") - result = runtest(self.ns, test_name) - self.ns.match_tests = orig_match_tests + self.first_state = self.get_state() + + print() + rerun_runtests = self._rerun_failed_tests(runtests) - self.accumulate_result(result, rerun=True) + if self.results.bad: + print(count(len(self.results.bad), 'test'), "failed again:") + printlist(self.results.bad) - if isinstance(result, Interrupted): - break + self.display_result(rerun_runtests) - if self.bad: - print(count(len(self.bad), 'test'), "failed again:") - printlist(self.bad) - - self.display_result() - - def normalize_test_name(self, test_full_name, *, is_error=False): - short_name = test_full_name.split(" ")[0] - if is_error and short_name in _TEST_LIFECYCLE_HOOKS: - # This means that we have a failure in a life-cycle hook, - # we need to rerun the whole module or class suite. - # Basically the error looks like this: - # ERROR: setUpClass (test.test_reg_ex.RegTest) - # or - # ERROR: setUpModule (test.test_reg_ex) - # So, we need to parse the class / module name. - lpar = test_full_name.index('(') - rpar = test_full_name.index(')') - return test_full_name[lpar + 1: rpar].split('.')[-1] - return short_name - - def display_result(self): + def display_result(self, runtests): # If running the test suite for PGO then no one cares about results. - if self.ns.pgo: + if runtests.pgo: return + state = self.get_state() print() - print("== Tests result: %s ==" % self.get_tests_result()) - - if self.interrupted: - print("Test suite interrupted by signal SIGINT.") - - omitted = set(self.selected) - self.get_executed() - if omitted: - print() - print(count(len(omitted), "test"), "omitted:") - printlist(omitted) - - if self.good and not self.ns.quiet: - print() - if (not self.bad - and not self.skipped - and not self.interrupted - and len(self.good) > 1): - print("All", end=' ') - print(count(len(self.good), "test"), "OK.") - - if self.ns.print_slow: - self.test_times.sort(reverse=True) - print() - print("10 slowest tests:") - for test_time, test in self.test_times[:10]: - print("- %s: %s" % (test, format_duration(test_time))) - - if self.bad: - print() - print(count(len(self.bad), "test"), "failed:") - printlist(self.bad) - - if self.environment_changed: - print() - print("{} altered the execution environment:".format( - count(len(self.environment_changed), "test"))) - printlist(self.environment_changed) - - if self.skipped and not self.ns.quiet: - print() - print(count(len(self.skipped), "test"), "skipped:") - printlist(self.skipped) - - if self.rerun: - print() - print("%s:" % count(len(self.rerun), "re-run test")) - printlist(self.rerun) - - if self.run_no_tests: - print() - print(count(len(self.run_no_tests), "test"), "run no tests:") - printlist(self.run_no_tests) - - def run_tests_sequential(self): - if self.ns.trace: + print(f"== Tests result: {state} ==") + + self.results.display_result(runtests.tests, + self.quiet, self.print_slowest) + + def run_test(self, test_name: TestName, runtests: RunTests, tracer): + if tracer is not None: + # If we're tracing code coverage, then we don't exit with status + # if on a false return value from main. + cmd = ('result = run_single_test(test_name, runtests)') + namespace = dict(locals()) + tracer.runctx(cmd, globals=globals(), locals=namespace) + result = namespace['result'] + else: + result = run_single_test(test_name, runtests) + + self.results.accumulate_result(result, runtests) + + return result + + def run_tests_sequentially(self, runtests): + if self.coverage: import trace - self.tracer = trace.Trace(trace=False, count=True) + tracer = trace.Trace(trace=False, count=True) + else: + tracer = None save_modules = sys.modules.keys() - msg = "Run tests sequentially" - if self.ns.timeout: - msg += " (timeout: %s)" % format_duration(self.ns.timeout) + jobs = runtests.get_jobs() + if jobs is not None: + tests = count(jobs, 'test') + else: + tests = 'tests' + msg = f"Run {tests} sequentially" + if runtests.timeout: + msg += " (timeout: %s)" % format_duration(runtests.timeout) self.log(msg) previous_test = None - for test_index, test_name in enumerate(self.tests, 1): - start_time = time.monotonic() + tests_iter = runtests.iter_tests() + for test_index, test_name in enumerate(tests_iter, 1): + start_time = time.perf_counter() text = test_name if previous_test: text = '%s -- %s' % (text, previous_test) - self.display_progress(test_index, text) - - if self.tracer: - # If we're tracing code coverage, then we don't exit with status - # if on a false return value from main. - cmd = ('result = runtest(self.ns, test_name); ' - 'self.accumulate_result(result)') - ns = dict(locals()) - self.tracer.runctx(cmd, globals=globals(), locals=ns) - result = ns['result'] - else: - result = runtest(self.ns, test_name) - self.accumulate_result(result) + self.logger.display_progress(test_index, text) - if isinstance(result, Interrupted): - break - - previous_test = str(result) - test_time = time.monotonic() - start_time - if test_time >= PROGRESS_MIN_TIME: - previous_test = "%s in %s" % (previous_test, format_duration(test_time)) - elif isinstance(result, Passed): - # be quiet: say nothing if the test passed shortly - previous_test = None + result = self.run_test(test_name, runtests, tracer) # Unload the newly imported modules (best effort finalization) for module in sys.modules.keys(): if module not in save_modules and module.startswith("test."): support.unload(module) - if self.ns.failfast and is_failed(result, self.ns): + if result.must_stop(self.fail_fast, self.fail_env_changed): break + previous_test = str(result) + test_time = time.perf_counter() - start_time + if test_time >= PROGRESS_MIN_TIME: + previous_test = "%s in %s" % (previous_test, format_duration(test_time)) + elif result.state == State.PASSED: + # be quiet: say nothing if the test passed shortly + previous_test = None + if previous_test: print(previous_test) - def _test_forever(self, tests): - while True: - for test_name in tests: - yield test_name - if self.bad: - return - if self.ns.fail_env_changed and self.environment_changed: - return - - def display_header(self): - # Print basic platform information - print("==", platform.python_implementation(), *sys.version.split()) - print("==", platform.platform(aliased=True), - "%s-endian" % sys.byteorder) - print("== Python build:", ' '.join(get_build_info())) - print("== cwd:", os.getcwd()) - cpu_count = os.cpu_count() - if cpu_count: - print("== CPU count:", cpu_count) - print("== encodings: locale=%s, FS=%s" - % (locale.getencoding(), sys.getfilesystemencoding())) - asan = support.check_sanitizer(address=True) - msan = support.check_sanitizer(memory=True) - ubsan = support.check_sanitizer(ub=True) - # This makes it easier to remember what to set in your local - # environment when trying to reproduce a sanitizer failure. - if asan or msan or ubsan: - names = [n for n in (asan and "address", - msan and "memory", - ubsan and "undefined behavior") - if n] - print(f"== sanitizers: {', '.join(names)}") - a_opts = os.environ.get("ASAN_OPTIONS") - if asan and a_opts is not None: - print(f"== ASAN_OPTIONS={a_opts}") - m_opts = os.environ.get("ASAN_OPTIONS") - if msan and m_opts is not None: - print(f"== MSAN_OPTIONS={m_opts}") - ub_opts = os.environ.get("UBSAN_OPTIONS") - if ubsan and ub_opts is not None: - print(f"== UBSAN_OPTIONS={ub_opts}") - - def no_tests_run(self): - return not any((self.good, self.bad, self.skipped, self.interrupted, - self.environment_changed)) - - def get_tests_result(self): - result = [] - if self.bad: - result.append("FAILURE") - elif self.ns.fail_env_changed and self.environment_changed: - result.append("ENV CHANGED") - elif self.no_tests_run(): - result.append("NO TESTS RAN") - - if self.interrupted: - result.append("INTERRUPTED") - - if not result: - result.append("SUCCESS") - - result = ', '.join(result) - if self.first_result: - result = '%s then %s' % (self.first_result, result) - return result + return tracer - def run_tests(self): - # For a partial run, we do not need to clutter the output. - if (self.ns.header - or not(self.ns.pgo or self.ns.quiet or self.ns.single - or self.tests or self.ns.args)): - self.display_header() - - if self.ns.huntrleaks: - warmup, repetitions, _ = self.ns.huntrleaks - if warmup < 3: - msg = ("WARNING: Running tests with --huntrleaks/-R and less than " - "3 warmup repetitions can give false positives!") - print(msg, file=sys.stdout, flush=True) - - if self.ns.randomize: - print("Using random seed", self.ns.random_seed) - - if self.ns.forever: - self.tests = self._test_forever(list(self.selected)) - self.test_count = '' - self.test_count_width = 3 - else: - self.tests = iter(self.selected) - self.test_count = '/{}'.format(len(self.selected)) - self.test_count_width = len(self.test_count) - 1 - - if self.ns.use_mp: - from test.libregrtest.runtest_mp import run_tests_multiprocess - # If we're on windows and this is the parent runner (not a worker), - # track the load average. - if sys.platform == 'win32' and self.worker_test_name is None: - from test.libregrtest.win_utils import WindowsLoadTracker - - try: - self.win_load_tracker = WindowsLoadTracker() - except PermissionError as error: - # Standard accounts may not have access to the performance - # counters. - print(f'Failed to create WindowsLoadTracker: {error}') + def get_state(self): + state = self.results.get_state(self.fail_env_changed) + if self.first_state: + state = f'{self.first_state} then {state}' + return state - try: - run_tests_multiprocess(self) - finally: - if self.win_load_tracker is not None: - self.win_load_tracker.close() - self.win_load_tracker = None - else: - self.run_tests_sequential() + def _run_tests_mp(self, runtests: RunTests, num_workers: int) -> None: + from .run_workers import RunWorkers + RunWorkers(num_workers, runtests, self.logger, self.results).run() - def finalize(self): + def finalize_tests(self, tracer): if self.next_single_filename: if self.next_single_test: with open(self.next_single_filename, 'w') as fp: @@ -628,195 +371,299 @@ def finalize(self): else: os.unlink(self.next_single_filename) - if self.tracer: - r = self.tracer.results() - r.write_results(show_missing=True, summary=True, - coverdir=self.ns.coverdir) + if tracer is not None: + results = tracer.results() + results.write_results(show_missing=True, summary=True, + coverdir=self.coverage_dir) + + if self.want_run_leaks: + os.system("leaks %d" % os.getpid()) + + if self.junit_filename: + self.results.write_junit(self.junit_filename) + def display_summary(self): + duration = time.perf_counter() - self.logger.start_time + filtered = bool(self.match_tests) or bool(self.ignore_tests) + + # Total duration print() - duration = time.monotonic() - self.start_time print("Total duration: %s" % format_duration(duration)) - print("Tests result: %s" % self.get_tests_result()) - if self.ns.runleaks: - os.system("leaks %d" % os.getpid()) + self.results.display_summary(self.first_runtests, filtered) + + # Result + state = self.get_state() + print(f"Result: {state}") + + def create_run_tests(self, tests: TestTuple): + return RunTests( + tests, + fail_fast=self.fail_fast, + fail_env_changed=self.fail_env_changed, + match_tests=self.match_tests, + ignore_tests=self.ignore_tests, + match_tests_dict=None, + rerun=False, + forever=self.forever, + pgo=self.pgo, + pgo_extended=self.pgo_extended, + output_on_failure=self.output_on_failure, + timeout=self.timeout, + verbose=self.verbose, + quiet=self.quiet, + hunt_refleak=self.hunt_refleak, + test_dir=self.test_dir, + use_junit=(self.junit_filename is not None), + memory_limit=self.memory_limit, + gc_threshold=self.gc_threshold, + use_resources=self.use_resources, + python_cmd=self.python_cmd, + randomize=self.randomize, + random_seed=self.random_seed, + json_file=None, + ) + + def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int: + if self.hunt_refleak and self.hunt_refleak.warmups < 3: + msg = ("WARNING: Running tests with --huntrleaks/-R and " + "less than 3 warmup repetitions can give false positives!") + print(msg, file=sys.stdout, flush=True) + + if self.num_workers < 0: + # Use all CPUs + 2 extra worker processes for tests + # that like to sleep + self.num_workers = (os.process_cpu_count() or 1) + 2 - def save_xml_result(self): - if not self.ns.xmlpath and not self.testsuite_xml: - return + # For a partial run, we do not need to clutter the output. + if (self.want_header + or not(self.pgo or self.quiet or self.single_test_run + or tests or self.cmdline_args)): + display_header(self.use_resources, self.python_cmd) - import xml.etree.ElementTree as ET - root = ET.Element("testsuites") - - # Manually count the totals for the overall summary - totals = {'tests': 0, 'errors': 0, 'failures': 0} - for suite in self.testsuite_xml: - root.append(suite) - for k in totals: - try: - totals[k] += int(suite.get(k, 0)) - except ValueError: - pass - - for k, v in totals.items(): - root.set(k, str(v)) - - xmlpath = os.path.join(os_helper.SAVEDCWD, self.ns.xmlpath) - with open(xmlpath, 'wb') as f: - for s in ET.tostringlist(root): - f.write(s) - - def fix_umask(self): - if support.is_emscripten: - # Emscripten has default umask 0o777, which breaks some tests. - # see https://github.com/emscripten-core/emscripten/issues/17269 - old_mask = os.umask(0) - if old_mask == 0o777: - os.umask(0o027) - else: - os.umask(old_mask) - - def set_temp_dir(self): - if self.ns.tempdir: - self.tmp_dir = self.ns.tempdir - - if not self.tmp_dir: - # When tests are run from the Python build directory, it is best practice - # to keep the test files in a subfolder. This eases the cleanup of leftover - # files using the "make distclean" command. - if sysconfig.is_python_build(): - self.tmp_dir = sysconfig.get_config_var('abs_builddir') - if self.tmp_dir is None: - # bpo-30284: On Windows, only srcdir is available. Using - # abs_builddir mostly matters on UNIX when building Python - # out of the source tree, especially when the source tree - # is read only. - self.tmp_dir = sysconfig.get_config_var('srcdir') - self.tmp_dir = os.path.join(self.tmp_dir, 'build') - else: - self.tmp_dir = tempfile.gettempdir() + print("Using random seed", self.random_seed) - self.tmp_dir = os.path.abspath(self.tmp_dir) + runtests = self.create_run_tests(selected) + self.first_runtests = runtests + self.logger.set_tests(runtests) - def create_temp_dir(self): - os.makedirs(self.tmp_dir, exist_ok=True) + setup_process() - # Define a writable temp dir that will be used as cwd while running - # the tests. The name of the dir includes the pid to allow parallel - # testing (see the -j option). - # Emscripten and WASI have stubbed getpid(), Emscripten has only - # milisecond clock resolution. Use randint() instead. - if sys.platform in {"emscripten", "wasi"}: - nounce = random.randint(0, 1_000_000) - else: - nounce = os.getpid() - if self.worker_test_name is not None: - test_cwd = 'test_python_worker_{}'.format(nounce) + if self.hunt_refleak and not self.num_workers: + # gh-109739: WindowsLoadTracker thread interfers with refleak check + use_load_tracker = False else: - test_cwd = 'test_python_{}'.format(nounce) - test_cwd += os_helper.FS_NONASCII - test_cwd = os.path.join(self.tmp_dir, test_cwd) - return test_cwd - - def cleanup(self): - import glob - - path = os.path.join(glob.escape(self.tmp_dir), 'test_python_*') - print("Cleanup %s directory" % self.tmp_dir) - for name in glob.glob(path): - if os.path.isdir(name): - print("Remove directory: %s" % name) - os_helper.rmtree(name) + # WindowsLoadTracker is only needed on Windows + use_load_tracker = MS_WINDOWS + + if use_load_tracker: + self.logger.start_load_tracker() + try: + if self.num_workers: + self._run_tests_mp(runtests, self.num_workers) + tracer = None else: - print("Remove file: %s" % name) - os_helper.unlink(name) + tracer = self.run_tests_sequentially(runtests) - def main(self, tests=None, **kwargs): - self.parse_args(kwargs) + self.display_result(runtests) - self.set_temp_dir() + if self.want_rerun and self.results.need_rerun(): + self.rerun_failed_tests(runtests) + finally: + if use_load_tracker: + self.logger.stop_load_tracker() - self.fix_umask() + self.display_summary() + self.finalize_tests(tracer) - if self.ns.cleanup: - self.cleanup() - sys.exit(0) + return self.results.get_exitcode(self.fail_env_changed, + self.fail_rerun) - test_cwd = self.create_temp_dir() + def run_tests(self, selected: TestTuple, tests: TestList | None) -> int: + os.makedirs(self.tmp_dir, exist_ok=True) + work_dir = get_work_dir(self.tmp_dir) - try: - # Run the tests in a context manager that temporarily changes the CWD - # to a temporary and writable directory. If it's not possible to - # create or change the CWD, the original CWD will be used. + # Put a timeout on Python exit + with exit_timeout(): + # Run the tests in a context manager that temporarily changes the + # CWD to a temporary and writable directory. If it's not possible + # to create or change the CWD, the original CWD will be used. # The original CWD is available from os_helper.SAVEDCWD. - with os_helper.temp_cwd(test_cwd, quiet=True): - # When using multiprocessing, worker processes will use test_cwd - # as their parent temporary directory. So when the main process - # exit, it removes also subdirectories of worker processes. - self.ns.tempdir = test_cwd - - self._main(tests, kwargs) - except SystemExit as exc: - # bpo-38203: Python can hang at exit in Py_Finalize(), especially - # on threading._shutdown() call: put a timeout - if threading_helper.can_start_thread: - faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True) - - sys.exit(exc.code) + with os_helper.temp_cwd(work_dir, quiet=True): + # When using multiprocessing, worker processes will use + # work_dir as their parent temporary directory. So when the + # main process exit, it removes also subdirectories of worker + # processes. + return self._run_tests(selected, tests) + + def _add_cross_compile_opts(self, regrtest_opts): + # WASM/WASI buildbot builders pass multiple PYTHON environment + # variables such as PYTHONPATH and _PYTHON_HOSTRUNNER. + keep_environ = bool(self.python_cmd) + environ = None + + # Are we using cross-compilation? + cross_compile = is_cross_compiled() + + # Get HOSTRUNNER + hostrunner = get_host_runner() + + if cross_compile: + # emulate -E, but keep PYTHONPATH + cross compile env vars, + # so test executable can load correct sysconfigdata file. + keep = { + '_PYTHON_PROJECT_BASE', + '_PYTHON_HOST_PLATFORM', + '_PYTHON_SYSCONFIGDATA_NAME', + 'PYTHONPATH' + } + old_environ = os.environ + new_environ = { + name: value for name, value in os.environ.items() + if not name.startswith(('PYTHON', '_PYTHON')) or name in keep + } + # Only set environ if at least one variable was removed + if new_environ != old_environ: + environ = new_environ + keep_environ = True + + if cross_compile and hostrunner: + if self.num_workers == 0: + # For now use only two cores for cross-compiled builds; + # hostrunner can be expensive. + regrtest_opts.extend(['-j', '2']) + + # If HOSTRUNNER is set and -p/--python option is not given, then + # use hostrunner to execute python binary for tests. + if not self.python_cmd: + buildpython = sysconfig.get_config_var("BUILDPYTHON") + python_cmd = f"{hostrunner} {buildpython}" + regrtest_opts.extend(["--python", python_cmd]) + keep_environ = True + + return (environ, keep_environ) + + def _add_ci_python_opts(self, python_opts, keep_environ): + # --fast-ci and --slow-ci add options to Python: + # "-u -W default -bb -E" + + # Unbuffered stdout and stderr + if not sys.stdout.write_through: + python_opts.append('-u') + + # Add warnings filter 'default' + if 'default' not in sys.warnoptions: + python_opts.extend(('-W', 'default')) + + # Error on bytes/str comparison + if sys.flags.bytes_warning < 2: + python_opts.append('-bb') + + if not keep_environ: + # Ignore PYTHON* environment variables + if not sys.flags.ignore_environment: + python_opts.append('-E') + + def _execute_python(self, cmd, environ): + # Make sure that messages before execv() are logged + sys.stdout.flush() + sys.stderr.flush() + + cmd_text = shlex.join(cmd) + try: + print(f"+ {cmd_text}", flush=True) - def getloadavg(self): - if self.win_load_tracker is not None: - return self.win_load_tracker.getloadavg() + if hasattr(os, 'execv') and not MS_WINDOWS: + os.execv(cmd[0], cmd) + # On success, execv() do no return. + # On error, it raises an OSError. + else: + import subprocess + with subprocess.Popen(cmd, env=environ) as proc: + try: + proc.wait() + except KeyboardInterrupt: + # There is no need to call proc.terminate(): on CTRL+C, + # SIGTERM is also sent to the child process. + try: + proc.wait(timeout=EXIT_TIMEOUT) + except subprocess.TimeoutExpired: + proc.kill() + proc.wait() + sys.exit(EXITCODE_INTERRUPTED) + + sys.exit(proc.returncode) + except Exception as exc: + print_warning(f"Failed to change Python options: {exc!r}\n" + f"Command: {cmd_text}") + # continue executing main() + + def _add_python_opts(self): + python_opts = [] + regrtest_opts = [] + + environ, keep_environ = self._add_cross_compile_opts(regrtest_opts) + if self.ci_mode: + self._add_ci_python_opts(python_opts, keep_environ) + + if (not python_opts) and (not regrtest_opts) and (environ is None): + # Nothing changed: nothing to do + return - if hasattr(os, 'getloadavg'): - return os.getloadavg()[0] + # Create new command line + cmd = list(sys.orig_argv) + if python_opts: + cmd[1:1] = python_opts + if regrtest_opts: + cmd.extend(regrtest_opts) + cmd.append("--dont-add-python-opts") - return None + self._execute_python(cmd, environ) - def _main(self, tests, kwargs): - if self.worker_test_name is not None: - from test.libregrtest.runtest_mp import run_tests_worker - run_tests_worker(self.ns, self.worker_test_name) + def _init(self): + # Set sys.stdout encoder error handler to backslashreplace, + # similar to sys.stderr error handler, to avoid UnicodeEncodeError + # when printing a traceback or any other non-encodable character. + sys.stdout.reconfigure(errors="backslashreplace") - if self.ns.wait: - input("Press any key to continue...") + if self.junit_filename and not os.path.isabs(self.junit_filename): + self.junit_filename = os.path.abspath(self.junit_filename) - support.PGO = self.ns.pgo - support.PGO_EXTENDED = self.ns.pgo_extended + strip_py_suffix(self.cmdline_args) - setup_tests(self.ns) + self.tmp_dir = get_temp_dir(self.tmp_dir) - self.find_tests(tests) + def main(self, tests: TestList | None = None): + if self.want_add_python_opts: + self._add_python_opts() - if self.ns.list_tests: - self.list_tests() - sys.exit(0) + self._init() - if self.ns.list_cases: - self.list_cases() + if self.want_cleanup: + cleanup_temp_dir(self.tmp_dir) sys.exit(0) - self.run_tests() - self.display_result() - - if self.ns.verbose2 and self.bad: - self.rerun_failed_tests() - - self.finalize() + if self.want_wait: + input("Press any key to continue...") - self.save_xml_result() + setup_test_dir(self.test_dir) + selected, tests = self.find_tests(tests) + + exitcode = 0 + if self.want_list_tests: + self.list_tests(selected) + elif self.want_list_cases: + list_cases(selected, + match_tests=self.match_tests, + ignore_tests=self.ignore_tests, + test_dir=self.test_dir) + else: + exitcode = self.run_tests(selected, tests) - if self.bad: - sys.exit(EXITCODE_BAD_TEST) - if self.interrupted: - sys.exit(EXITCODE_INTERRUPTED) - if self.ns.fail_env_changed and self.environment_changed: - sys.exit(EXITCODE_ENV_CHANGED) - if self.no_tests_run(): - sys.exit(EXITCODE_NO_TESTS_RAN) - sys.exit(0) + sys.exit(exitcode) -def main(tests=None, **kwargs): +def main(tests=None, _add_python_opts=False, **kwargs): """Run the Python suite.""" - Regrtest().main(tests=tests, **kwargs) + ns = _parse_args(sys.argv[1:], **kwargs) + Regrtest(ns, _add_python_opts=_add_python_opts).main(tests=tests) diff --git a/Lib/test/libregrtest/mypy.ini b/Lib/test/libregrtest/mypy.ini new file mode 100644 index 00000000000000..fefc347728a701 --- /dev/null +++ b/Lib/test/libregrtest/mypy.ini @@ -0,0 +1,33 @@ +# Config file for running mypy on libregrtest. +# Run mypy by invoking `mypy --config-file Lib/test/libregrtest/mypy.ini` +# on the command-line from the repo root + +[mypy] +files = Lib/test/libregrtest +explicit_package_bases = True +python_version = 3.11 +platform = linux +pretty = True + +# Enable most stricter settings +enable_error_code = ignore-without-code +strict = True + +# Various stricter settings that we can't yet enable +# Try to enable these in the following order: +disallow_any_generics = False +disallow_incomplete_defs = False +disallow_untyped_calls = False +disallow_untyped_defs = False +check_untyped_defs = False +warn_return_any = False + +disable_error_code = return + +# Enable --strict-optional for these ASAP: +[mypy-Lib.test.libregrtest.main.*,Lib.test.libregrtest.run_workers.*,Lib.test.libregrtest.worker.*,Lib.test.libregrtest.single.*,Lib.test.libregrtest.results.*,Lib.test.libregrtest.utils.*] +strict_optional = False + +# Various internal modules that typeshed deliberately doesn't have stubs for: +[mypy-_abc.*,_opcode.*,_overlapped.*,_testcapi.*,_testinternalcapi.*,test.*] +ignore_missing_imports = True diff --git a/Lib/test/libregrtest/pgo.py b/Lib/test/libregrtest/pgo.py index 42ce5fba7a97c3..e3a6927be5db1d 100644 --- a/Lib/test/libregrtest/pgo.py +++ b/Lib/test/libregrtest/pgo.py @@ -42,15 +42,15 @@ 'test_set', 'test_sqlite3', 'test_statistics', + 'test_str', 'test_struct', 'test_tabnanny', 'test_time', - 'test_unicode', 'test_xml_etree', 'test_xml_etree_c', ] -def setup_pgo_tests(ns): - if not ns.args and not ns.pgo_extended: +def setup_pgo_tests(cmdline_args, pgo_extended: bool): + if not cmdline_args and not pgo_extended: # run default set of tests for PGO training - ns.args = PGO_TESTS[:] + cmdline_args[:] = PGO_TESTS[:] diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index cd11d385591f80..ada1a65b867ee6 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -1,10 +1,13 @@ -import os import sys import warnings from inspect import isabstract +from typing import Any + from test import support from test.support import os_helper -from test.libregrtest.utils import clear_caches + +from .runtests import HuntRefleak +from .utils import clear_caches try: from _abc import _get_dump @@ -19,7 +22,9 @@ def _get_dump(cls): cls._abc_negative_cache, cls._abc_negative_cache_version) -def dash_R(ns, test_name, test_func): +def runtest_refleak(test_name, test_func, + hunt_refleak: HuntRefleak, + quiet: bool): """Run a test multiple times, looking for reference leaks. Returns: @@ -41,6 +46,7 @@ def dash_R(ns, test_name, test_func): fs = warnings.filters[:] ps = copyreg.dispatch_table.copy() pic = sys.path_importer_cache.copy() + zdc: dict[str, Any] | None try: import zipimport except ImportError: @@ -62,9 +68,10 @@ def dash_R(ns, test_name, test_func): def get_pooled_int(value): return int_pool.setdefault(value, value) - nwarmup, ntracked, fname = ns.huntrleaks - fname = os.path.join(os_helper.SAVEDCWD, fname) - repcount = nwarmup + ntracked + warmups = hunt_refleak.warmups + runs = hunt_refleak.runs + filename = hunt_refleak.filename + repcount = warmups + runs # Pre-allocate to ensure that the loop doesn't allocate anything new rep_range = list(range(repcount)) @@ -78,16 +85,17 @@ def get_pooled_int(value): # initialize variables to make pyflakes quiet rc_before = alloc_before = fd_before = interned_before = 0 - if not ns.quiet: + if not quiet: print("beginning", repcount, "repetitions", file=sys.stderr) print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr, flush=True) + results = None dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() for i in rep_range: - test_func() + results = test_func() dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() @@ -101,7 +109,7 @@ def get_pooled_int(value): rc_after = gettotalrefcount() - interned_after * 2 fd_after = fd_count() - if not ns.quiet: + if not quiet: print('.', end='', file=sys.stderr, flush=True) rc_deltas[i] = get_pooled_int(rc_after - rc_before) @@ -113,7 +121,7 @@ def get_pooled_int(value): fd_before = fd_after interned_before = interned_after - if not ns.quiet: + if not quiet: print(file=sys.stderr) # These checkers return False on success, True on failure @@ -142,16 +150,16 @@ def check_fd_deltas(deltas): (fd_deltas, 'file descriptors', check_fd_deltas) ]: # ignore warmup runs - deltas = deltas[nwarmup:] + deltas = deltas[warmups:] if checker(deltas): msg = '%s leaked %s %s, sum=%s' % ( test_name, deltas, item_name, sum(deltas)) print(msg, file=sys.stderr, flush=True) - with open(fname, "a", encoding="utf-8") as refrep: + with open(filename, "a", encoding="utf-8") as refrep: print(msg, file=refrep) refrep.flush() failed = True - return failed + return (failed, results) def dash_R_cleanup(fs, ps, pic, zdc, abcs): diff --git a/Lib/test/libregrtest/result.py b/Lib/test/libregrtest/result.py new file mode 100644 index 00000000000000..d6b0d5ad383a5b --- /dev/null +++ b/Lib/test/libregrtest/result.py @@ -0,0 +1,190 @@ +import dataclasses +import json +from typing import Any + +from test.support import TestStats + +from .utils import ( + StrJSON, TestName, FilterTuple, + format_duration, normalize_test_name, print_warning) + + +# Avoid enum.Enum to reduce the number of imports when tests are run +class State: + PASSED = "PASSED" + FAILED = "FAILED" + SKIPPED = "SKIPPED" + UNCAUGHT_EXC = "UNCAUGHT_EXC" + REFLEAK = "REFLEAK" + ENV_CHANGED = "ENV_CHANGED" + RESOURCE_DENIED = "RESOURCE_DENIED" + INTERRUPTED = "INTERRUPTED" + WORKER_FAILED = "WORKER_FAILED" # non-zero worker process exit code + WORKER_BUG = "WORKER_BUG" # exception when running a worker + DID_NOT_RUN = "DID_NOT_RUN" + TIMEOUT = "TIMEOUT" + + @staticmethod + def is_failed(state): + return state in { + State.FAILED, + State.UNCAUGHT_EXC, + State.REFLEAK, + State.WORKER_FAILED, + State.WORKER_BUG, + State.TIMEOUT} + + @staticmethod + def has_meaningful_duration(state): + # Consider that the duration is meaningless for these cases. + # For example, if a whole test file is skipped, its duration + # is unlikely to be the duration of executing its tests, + # but just the duration to execute code which skips the test. + return state not in { + State.SKIPPED, + State.RESOURCE_DENIED, + State.INTERRUPTED, + State.WORKER_FAILED, + State.WORKER_BUG, + State.DID_NOT_RUN} + + @staticmethod + def must_stop(state): + return state in { + State.INTERRUPTED, + State.WORKER_BUG, + } + + +@dataclasses.dataclass(slots=True) +class TestResult: + test_name: TestName + state: str | None = None + # Test duration in seconds + duration: float | None = None + xml_data: list[str] | None = None + stats: TestStats | None = None + + # errors and failures copied from support.TestFailedWithDetails + errors: list[tuple[str, str]] | None = None + failures: list[tuple[str, str]] | None = None + + def is_failed(self, fail_env_changed: bool) -> bool: + if self.state == State.ENV_CHANGED: + return fail_env_changed + return State.is_failed(self.state) + + def _format_failed(self): + if self.errors and self.failures: + le = len(self.errors) + lf = len(self.failures) + error_s = "error" + ("s" if le > 1 else "") + failure_s = "failure" + ("s" if lf > 1 else "") + return f"{self.test_name} failed ({le} {error_s}, {lf} {failure_s})" + + if self.errors: + le = len(self.errors) + error_s = "error" + ("s" if le > 1 else "") + return f"{self.test_name} failed ({le} {error_s})" + + if self.failures: + lf = len(self.failures) + failure_s = "failure" + ("s" if lf > 1 else "") + return f"{self.test_name} failed ({lf} {failure_s})" + + return f"{self.test_name} failed" + + def __str__(self) -> str: + match self.state: + case State.PASSED: + return f"{self.test_name} passed" + case State.FAILED: + return self._format_failed() + case State.SKIPPED: + return f"{self.test_name} skipped" + case State.UNCAUGHT_EXC: + return f"{self.test_name} failed (uncaught exception)" + case State.REFLEAK: + return f"{self.test_name} failed (reference leak)" + case State.ENV_CHANGED: + return f"{self.test_name} failed (env changed)" + case State.RESOURCE_DENIED: + return f"{self.test_name} skipped (resource denied)" + case State.INTERRUPTED: + return f"{self.test_name} interrupted" + case State.WORKER_FAILED: + return f"{self.test_name} worker non-zero exit code" + case State.WORKER_BUG: + return f"{self.test_name} worker bug" + case State.DID_NOT_RUN: + return f"{self.test_name} ran no tests" + case State.TIMEOUT: + return f"{self.test_name} timed out ({format_duration(self.duration)})" + case _: + raise ValueError("unknown result state: {state!r}") + + def has_meaningful_duration(self): + return State.has_meaningful_duration(self.state) + + def set_env_changed(self): + if self.state is None or self.state == State.PASSED: + self.state = State.ENV_CHANGED + + def must_stop(self, fail_fast: bool, fail_env_changed: bool) -> bool: + if State.must_stop(self.state): + return True + if fail_fast and self.is_failed(fail_env_changed): + return True + return False + + def get_rerun_match_tests(self) -> FilterTuple | None: + match_tests = [] + + errors = self.errors or [] + failures = self.failures or [] + for error_list, is_error in ( + (errors, True), + (failures, False), + ): + for full_name, *_ in error_list: + match_name = normalize_test_name(full_name, is_error=is_error) + if match_name is None: + # 'setUpModule (test.test_sys)': don't filter tests + return None + if not match_name: + error_type = "ERROR" if is_error else "FAIL" + print_warning(f"rerun failed to parse {error_type} test name: " + f"{full_name!r}: don't filter tests") + return None + match_tests.append(match_name) + + if not match_tests: + return None + return tuple(match_tests) + + def write_json_into(self, file) -> None: + json.dump(self, file, cls=_EncodeTestResult) + + @staticmethod + def from_json(worker_json: StrJSON) -> 'TestResult': + return json.loads(worker_json, object_hook=_decode_test_result) + + +class _EncodeTestResult(json.JSONEncoder): + def default(self, o: Any) -> dict[str, Any]: + if isinstance(o, TestResult): + result = dataclasses.asdict(o) + result["__test_result__"] = o.__class__.__name__ + return result + else: + return super().default(o) + + +def _decode_test_result(data: dict[str, Any]) -> TestResult | dict[str, Any]: + if "__test_result__" in data: + data.pop('__test_result__') + if data['stats'] is not None: + data['stats'] = TestStats(**data['stats']) + return TestResult(**data) + else: + return data diff --git a/Lib/test/libregrtest/results.py b/Lib/test/libregrtest/results.py new file mode 100644 index 00000000000000..3708078ff0bf3a --- /dev/null +++ b/Lib/test/libregrtest/results.py @@ -0,0 +1,261 @@ +import sys +from test.support import TestStats + +from .runtests import RunTests +from .result import State, TestResult +from .utils import ( + StrPath, TestName, TestTuple, TestList, FilterDict, + printlist, count, format_duration) + + +# Python uses exit code 1 when an exception is not catched +# argparse.ArgumentParser.error() uses exit code 2 +EXITCODE_BAD_TEST = 2 +EXITCODE_ENV_CHANGED = 3 +EXITCODE_NO_TESTS_RAN = 4 +EXITCODE_RERUN_FAIL = 5 +EXITCODE_INTERRUPTED = 130 # 128 + signal.SIGINT=2 + + +class TestResults: + def __init__(self): + self.bad: TestList = [] + self.good: TestList = [] + self.rerun_bad: TestList = [] + self.skipped: TestList = [] + self.resource_denied: TestList = [] + self.env_changed: TestList = [] + self.run_no_tests: TestList = [] + self.rerun: TestList = [] + self.rerun_results: list[TestResult] = [] + + self.interrupted: bool = False + self.worker_bug: bool = False + self.test_times: list[tuple[float, TestName]] = [] + self.stats = TestStats() + # used by --junit-xml + self.testsuite_xml: list[str] = [] + + def is_all_good(self): + return (not self.bad + and not self.skipped + and not self.interrupted + and not self.worker_bug) + + def get_executed(self): + return (set(self.good) | set(self.bad) | set(self.skipped) + | set(self.resource_denied) | set(self.env_changed) + | set(self.run_no_tests)) + + def no_tests_run(self): + return not any((self.good, self.bad, self.skipped, self.interrupted, + self.env_changed)) + + def get_state(self, fail_env_changed): + state = [] + if self.bad: + state.append("FAILURE") + elif fail_env_changed and self.env_changed: + state.append("ENV CHANGED") + elif self.no_tests_run(): + state.append("NO TESTS RAN") + + if self.interrupted: + state.append("INTERRUPTED") + if self.worker_bug: + state.append("WORKER BUG") + if not state: + state.append("SUCCESS") + + return ', '.join(state) + + def get_exitcode(self, fail_env_changed, fail_rerun): + exitcode = 0 + if self.bad: + exitcode = EXITCODE_BAD_TEST + elif self.interrupted: + exitcode = EXITCODE_INTERRUPTED + elif fail_env_changed and self.env_changed: + exitcode = EXITCODE_ENV_CHANGED + elif self.no_tests_run(): + exitcode = EXITCODE_NO_TESTS_RAN + elif fail_rerun and self.rerun: + exitcode = EXITCODE_RERUN_FAIL + elif self.worker_bug: + exitcode = EXITCODE_BAD_TEST + return exitcode + + def accumulate_result(self, result: TestResult, runtests: RunTests): + test_name = result.test_name + rerun = runtests.rerun + fail_env_changed = runtests.fail_env_changed + + match result.state: + case State.PASSED: + self.good.append(test_name) + case State.ENV_CHANGED: + self.env_changed.append(test_name) + self.rerun_results.append(result) + case State.SKIPPED: + self.skipped.append(test_name) + case State.RESOURCE_DENIED: + self.resource_denied.append(test_name) + case State.INTERRUPTED: + self.interrupted = True + case State.DID_NOT_RUN: + self.run_no_tests.append(test_name) + case _: + if result.is_failed(fail_env_changed): + self.bad.append(test_name) + self.rerun_results.append(result) + else: + raise ValueError(f"invalid test state: {result.state!r}") + + if result.state == State.WORKER_BUG: + self.worker_bug = True + + if result.has_meaningful_duration() and not rerun: + self.test_times.append((result.duration, test_name)) + if result.stats is not None: + self.stats.accumulate(result.stats) + if rerun: + self.rerun.append(test_name) + + xml_data = result.xml_data + if xml_data: + self.add_junit(xml_data) + + def need_rerun(self): + return bool(self.rerun_results) + + def prepare_rerun(self) -> tuple[TestTuple, FilterDict]: + tests: TestList = [] + match_tests_dict = {} + for result in self.rerun_results: + tests.append(result.test_name) + + match_tests = result.get_rerun_match_tests() + # ignore empty match list + if match_tests: + match_tests_dict[result.test_name] = match_tests + + # Clear previously failed tests + self.rerun_bad.extend(self.bad) + self.bad.clear() + self.env_changed.clear() + self.rerun_results.clear() + + return (tuple(tests), match_tests_dict) + + def add_junit(self, xml_data: list[str]): + import xml.etree.ElementTree as ET + for e in xml_data: + try: + self.testsuite_xml.append(ET.fromstring(e)) + except ET.ParseError: + print(xml_data, file=sys.__stderr__) + raise + + def write_junit(self, filename: StrPath): + if not self.testsuite_xml: + # Don't create empty XML file + return + + import xml.etree.ElementTree as ET + root = ET.Element("testsuites") + + # Manually count the totals for the overall summary + totals = {'tests': 0, 'errors': 0, 'failures': 0} + for suite in self.testsuite_xml: + root.append(suite) + for k in totals: + try: + totals[k] += int(suite.get(k, 0)) + except ValueError: + pass + + for k, v in totals.items(): + root.set(k, str(v)) + + with open(filename, 'wb') as f: + for s in ET.tostringlist(root): + f.write(s) + + def display_result(self, tests: TestTuple, quiet: bool, print_slowest: bool): + if print_slowest: + self.test_times.sort(reverse=True) + print() + print("10 slowest tests:") + for test_time, test in self.test_times[:10]: + print("- %s: %s" % (test, format_duration(test_time))) + + all_tests = [] + omitted = set(tests) - self.get_executed() + + # less important + all_tests.append((omitted, "test", "{} omitted:")) + if not quiet: + all_tests.append((self.skipped, "test", "{} skipped:")) + all_tests.append((self.resource_denied, "test", "{} skipped (resource denied):")) + all_tests.append((self.run_no_tests, "test", "{} run no tests:")) + + # more important + all_tests.append((self.env_changed, "test", "{} altered the execution environment (env changed):")) + all_tests.append((self.rerun, "re-run test", "{}:")) + all_tests.append((self.bad, "test", "{} failed:")) + + for tests_list, count_text, title_format in all_tests: + if tests_list: + print() + count_text = count(len(tests_list), count_text) + print(title_format.format(count_text)) + printlist(tests_list) + + if self.good and not quiet: + print() + text = count(len(self.good), "test") + text = f"{text} OK." + if (self.is_all_good() and len(self.good) > 1): + text = f"All {text}" + print(text) + + if self.interrupted: + print() + print("Test suite interrupted by signal SIGINT.") + + def display_summary(self, first_runtests: RunTests, filtered: bool): + # Total tests + stats = self.stats + text = f'run={stats.tests_run:,}' + if filtered: + text = f"{text} (filtered)" + report = [text] + if stats.failures: + report.append(f'failures={stats.failures:,}') + if stats.skipped: + report.append(f'skipped={stats.skipped:,}') + print(f"Total tests: {' '.join(report)}") + + # Total test files + all_tests = [self.good, self.bad, self.rerun, + self.skipped, + self.env_changed, self.run_no_tests] + run = sum(map(len, all_tests)) + text = f'run={run}' + if not first_runtests.forever: + ntest = len(first_runtests.tests) + text = f"{text}/{ntest}" + if filtered: + text = f"{text} (filtered)" + report = [text] + for name, tests in ( + ('failed', self.bad), + ('env_changed', self.env_changed), + ('skipped', self.skipped), + ('resource_denied', self.resource_denied), + ('rerun', self.rerun), + ('run_no_tests', self.run_no_tests), + ): + if tests: + report.append(f'{name}={len(tests)}') + print(f"Total test files: {' '.join(report)}") diff --git a/Lib/test/libregrtest/run_workers.py b/Lib/test/libregrtest/run_workers.py new file mode 100644 index 00000000000000..16f8331abd32f9 --- /dev/null +++ b/Lib/test/libregrtest/run_workers.py @@ -0,0 +1,607 @@ +import contextlib +import dataclasses +import faulthandler +import os.path +import queue +import signal +import subprocess +import sys +import tempfile +import threading +import time +import traceback +from typing import Literal, TextIO + +from test import support +from test.support import os_helper, MS_WINDOWS + +from .logger import Logger +from .result import TestResult, State +from .results import TestResults +from .runtests import RunTests, JsonFile, JsonFileType +from .single import PROGRESS_MIN_TIME +from .utils import ( + StrPath, TestName, + format_duration, print_warning, count, plural, get_signal_name) +from .worker import create_worker_process, USE_PROCESS_GROUP + +if MS_WINDOWS: + import locale + import msvcrt + + + +# Display the running tests if nothing happened last N seconds +PROGRESS_UPDATE = 30.0 # seconds +assert PROGRESS_UPDATE >= PROGRESS_MIN_TIME + +# Kill the main process after 5 minutes. It is supposed to write an update +# every PROGRESS_UPDATE seconds. Tolerate 5 minutes for Python slowest +# buildbot workers. +MAIN_PROCESS_TIMEOUT = 5 * 60.0 +assert MAIN_PROCESS_TIMEOUT >= PROGRESS_UPDATE + +# Time to wait until a worker completes: should be immediate +WAIT_COMPLETED_TIMEOUT = 30.0 # seconds + +# Time to wait a killed process (in seconds) +WAIT_KILLED_TIMEOUT = 60.0 + + +# We do not use a generator so multiple threads can call next(). +class MultiprocessIterator: + + """A thread-safe iterator over tests for multiprocess mode.""" + + def __init__(self, tests_iter): + self.lock = threading.Lock() + self.tests_iter = tests_iter + + def __iter__(self): + return self + + def __next__(self): + with self.lock: + if self.tests_iter is None: + raise StopIteration + return next(self.tests_iter) + + def stop(self): + with self.lock: + self.tests_iter = None + + +@dataclasses.dataclass(slots=True, frozen=True) +class MultiprocessResult: + result: TestResult + # bpo-45410: stderr is written into stdout to keep messages order + worker_stdout: str | None = None + err_msg: str | None = None + + +ExcStr = str +QueueOutput = tuple[Literal[False], MultiprocessResult] | tuple[Literal[True], ExcStr] + + +class ExitThread(Exception): + pass + + +class WorkerError(Exception): + def __init__(self, + test_name: TestName, + err_msg: str | None, + stdout: str | None, + state: str): + result = TestResult(test_name, state=state) + self.mp_result = MultiprocessResult(result, stdout, err_msg) + super().__init__() + + +class WorkerThread(threading.Thread): + def __init__(self, worker_id: int, runner: "RunWorkers") -> None: + super().__init__() + self.worker_id = worker_id + self.runtests = runner.runtests + self.pending = runner.pending + self.output = runner.output + self.timeout = runner.worker_timeout + self.log = runner.log + self.test_name: TestName | None = None + self.start_time: float | None = None + self._popen: subprocess.Popen[str] | None = None + self._killed = False + self._stopped = False + + def __repr__(self) -> str: + info = [f'WorkerThread #{self.worker_id}'] + if self.is_alive(): + info.append("running") + else: + info.append('stopped') + test = self.test_name + if test: + info.append(f'test={test}') + popen = self._popen + if popen is not None: + dt = time.monotonic() - self.start_time + info.extend((f'pid={self._popen.pid}', + f'time={format_duration(dt)}')) + return '<%s>' % ' '.join(info) + + def _kill(self) -> None: + popen = self._popen + if popen is None: + return + + if self._killed: + return + self._killed = True + + if USE_PROCESS_GROUP: + what = f"{self} process group" + else: + what = f"{self} process" + + print(f"Kill {what}", file=sys.stderr, flush=True) + try: + if USE_PROCESS_GROUP: + os.killpg(popen.pid, signal.SIGKILL) + else: + popen.kill() + except ProcessLookupError: + # popen.kill(): the process completed, the WorkerThread thread + # read its exit status, but Popen.send_signal() read the returncode + # just before Popen.wait() set returncode. + pass + except OSError as exc: + print_warning(f"Failed to kill {what}: {exc!r}") + + def stop(self) -> None: + # Method called from a different thread to stop this thread + self._stopped = True + self._kill() + + def _run_process(self, runtests: RunTests, output_fd: int, + tmp_dir: StrPath | None = None) -> int | None: + popen = create_worker_process(runtests, output_fd, tmp_dir) + self._popen = popen + self._killed = False + + try: + if self._stopped: + # If kill() has been called before self._popen is set, + # self._popen is still running. Call again kill() + # to ensure that the process is killed. + self._kill() + raise ExitThread + + try: + # gh-94026: stdout+stderr are written to tempfile + retcode = popen.wait(timeout=self.timeout) + assert retcode is not None + return retcode + except subprocess.TimeoutExpired: + if self._stopped: + # kill() has been called: communicate() fails on reading + # closed stdout + raise ExitThread + + # On timeout, kill the process + self._kill() + + # None means TIMEOUT for the caller + retcode = None + # bpo-38207: Don't attempt to call communicate() again: on it + # can hang until all child processes using stdout + # pipes completes. + except OSError: + if self._stopped: + # kill() has been called: communicate() fails + # on reading closed stdout + raise ExitThread + raise + except: + self._kill() + raise + finally: + self._wait_completed() + self._popen = None + + def create_stdout(self, stack: contextlib.ExitStack) -> TextIO: + """Create stdout temporay file (file descriptor).""" + + if MS_WINDOWS: + # gh-95027: When stdout is not a TTY, Python uses the ANSI code + # page for the sys.stdout encoding. If the main process runs in a + # terminal, sys.stdout uses WindowsConsoleIO with UTF-8 encoding. + encoding = locale.getencoding() + else: + encoding = sys.stdout.encoding + + # gh-94026: Write stdout+stderr to a tempfile as workaround for + # non-blocking pipes on Emscripten with NodeJS. + # gh-109425: Use "backslashreplace" error handler: log corrupted + # stdout+stderr, instead of failing with a UnicodeDecodeError and not + # logging stdout+stderr at all. + stdout_file = tempfile.TemporaryFile('w+', + encoding=encoding, + errors='backslashreplace') + stack.enter_context(stdout_file) + return stdout_file + + def create_json_file(self, stack: contextlib.ExitStack) -> tuple[JsonFile, TextIO | None]: + """Create JSON file.""" + + json_file_use_stdout = self.runtests.json_file_use_stdout() + if json_file_use_stdout: + json_file = JsonFile(None, JsonFileType.STDOUT) + json_tmpfile = None + else: + json_tmpfile = tempfile.TemporaryFile('w+', encoding='utf8') + stack.enter_context(json_tmpfile) + + json_fd = json_tmpfile.fileno() + if MS_WINDOWS: + json_handle = msvcrt.get_osfhandle(json_fd) + json_file = JsonFile(json_handle, + JsonFileType.WINDOWS_HANDLE) + else: + json_file = JsonFile(json_fd, JsonFileType.UNIX_FD) + return (json_file, json_tmpfile) + + def create_worker_runtests(self, test_name: TestName, json_file: JsonFile) -> RunTests: + """Create the worker RunTests.""" + + tests = (test_name,) + if self.runtests.rerun: + match_tests = self.runtests.get_match_tests(test_name) + else: + match_tests = None + + kwargs = {} + if match_tests: + kwargs['match_tests'] = match_tests + if self.runtests.output_on_failure: + kwargs['verbose'] = True + kwargs['output_on_failure'] = False + return self.runtests.copy( + tests=tests, + json_file=json_file, + **kwargs) + + def run_tmp_files(self, worker_runtests: RunTests, + stdout_fd: int) -> tuple[int | None, list[StrPath]]: + # gh-93353: Check for leaked temporary files in the parent process, + # since the deletion of temporary files can happen late during + # Python finalization: too late for libregrtest. + if not support.is_wasi: + # Don't check for leaked temporary files and directories if Python is + # run on WASI. WASI don't pass environment variables like TMPDIR to + # worker processes. + tmp_dir = tempfile.mkdtemp(prefix="test_python_") + tmp_dir = os.path.abspath(tmp_dir) + try: + retcode = self._run_process(worker_runtests, + stdout_fd, tmp_dir) + finally: + tmp_files = os.listdir(tmp_dir) + os_helper.rmtree(tmp_dir) + else: + retcode = self._run_process(worker_runtests, stdout_fd) + tmp_files = [] + + return (retcode, tmp_files) + + def read_stdout(self, stdout_file: TextIO) -> str: + stdout_file.seek(0) + try: + return stdout_file.read().strip() + except Exception as exc: + # gh-101634: Catch UnicodeDecodeError if stdout cannot be + # decoded from encoding + raise WorkerError(self.test_name, + f"Cannot read process stdout: {exc}", + stdout=None, + state=State.WORKER_BUG) + + def read_json(self, json_file: JsonFile, json_tmpfile: TextIO | None, + stdout: str) -> tuple[TestResult, str]: + try: + if json_tmpfile is not None: + json_tmpfile.seek(0) + worker_json = json_tmpfile.read() + elif json_file.file_type == JsonFileType.STDOUT: + stdout, _, worker_json = stdout.rpartition("\n") + stdout = stdout.rstrip() + else: + with json_file.open(encoding='utf8') as json_fp: + worker_json = json_fp.read() + except Exception as exc: + # gh-101634: Catch UnicodeDecodeError if stdout cannot be + # decoded from encoding + err_msg = f"Failed to read worker process JSON: {exc}" + raise WorkerError(self.test_name, err_msg, stdout, + state=State.WORKER_BUG) + + if not worker_json: + raise WorkerError(self.test_name, "empty JSON", stdout, + state=State.WORKER_BUG) + + try: + result = TestResult.from_json(worker_json) + except Exception as exc: + # gh-101634: Catch UnicodeDecodeError if stdout cannot be + # decoded from encoding + err_msg = f"Failed to parse worker process JSON: {exc}" + raise WorkerError(self.test_name, err_msg, stdout, + state=State.WORKER_BUG) + + return (result, stdout) + + def _runtest(self, test_name: TestName) -> MultiprocessResult: + with contextlib.ExitStack() as stack: + stdout_file = self.create_stdout(stack) + json_file, json_tmpfile = self.create_json_file(stack) + worker_runtests = self.create_worker_runtests(test_name, json_file) + + retcode, tmp_files = self.run_tmp_files(worker_runtests, + stdout_file.fileno()) + + stdout = self.read_stdout(stdout_file) + + if retcode is None: + raise WorkerError(self.test_name, stdout=stdout, + err_msg=None, + state=State.TIMEOUT) + if retcode != 0: + name = get_signal_name(retcode) + if name: + retcode = f"{retcode} ({name})" + raise WorkerError(self.test_name, f"Exit code {retcode}", stdout, + state=State.WORKER_FAILED) + + result, stdout = self.read_json(json_file, json_tmpfile, stdout) + + if tmp_files: + msg = (f'\n\n' + f'Warning -- {test_name} leaked temporary files ' + f'({len(tmp_files)}): {", ".join(sorted(tmp_files))}') + stdout += msg + result.set_env_changed() + + return MultiprocessResult(result, stdout) + + def run(self) -> None: + fail_fast = self.runtests.fail_fast + fail_env_changed = self.runtests.fail_env_changed + while not self._stopped: + try: + try: + test_name = next(self.pending) + except StopIteration: + break + + self.start_time = time.monotonic() + self.test_name = test_name + try: + mp_result = self._runtest(test_name) + except WorkerError as exc: + mp_result = exc.mp_result + finally: + self.test_name = None + mp_result.result.duration = time.monotonic() - self.start_time + self.output.put((False, mp_result)) + + if mp_result.result.must_stop(fail_fast, fail_env_changed): + break + except ExitThread: + break + except BaseException: + self.output.put((True, traceback.format_exc())) + break + + def _wait_completed(self) -> None: + popen = self._popen + + try: + popen.wait(WAIT_COMPLETED_TIMEOUT) + except (subprocess.TimeoutExpired, OSError) as exc: + print_warning(f"Failed to wait for {self} completion " + f"(timeout={format_duration(WAIT_COMPLETED_TIMEOUT)}): " + f"{exc!r}") + + def wait_stopped(self, start_time: float) -> None: + # bpo-38207: RunWorkers.stop_workers() called self.stop() + # which killed the process. Sometimes, killing the process from the + # main thread does not interrupt popen.communicate() in + # WorkerThread thread. This loop with a timeout is a workaround + # for that. + # + # Moreover, if this method fails to join the thread, it is likely + # that Python will hang at exit while calling threading._shutdown() + # which tries again to join the blocked thread. Regrtest.main() + # uses EXIT_TIMEOUT to workaround this second bug. + while True: + # Write a message every second + self.join(1.0) + if not self.is_alive(): + break + dt = time.monotonic() - start_time + self.log(f"Waiting for {self} thread for {format_duration(dt)}") + if dt > WAIT_KILLED_TIMEOUT: + print_warning(f"Failed to join {self} in {format_duration(dt)}") + break + + +def get_running(workers: list[WorkerThread]) -> str | None: + running: list[str] = [] + for worker in workers: + test_name = worker.test_name + if not test_name: + continue + dt = time.monotonic() - worker.start_time + if dt >= PROGRESS_MIN_TIME: + text = f'{test_name} ({format_duration(dt)})' + running.append(text) + if not running: + return None + return f"running ({len(running)}): {', '.join(running)}" + + +class RunWorkers: + def __init__(self, num_workers: int, runtests: RunTests, + logger: Logger, results: TestResults) -> None: + self.num_workers = num_workers + self.runtests = runtests + self.log = logger.log + self.display_progress = logger.display_progress + self.results: TestResults = results + + self.output: queue.Queue[QueueOutput] = queue.Queue() + tests_iter = runtests.iter_tests() + self.pending = MultiprocessIterator(tests_iter) + self.timeout = runtests.timeout + if self.timeout is not None: + # Rely on faulthandler to kill a worker process. This timouet is + # when faulthandler fails to kill a worker process. Give a maximum + # of 5 minutes to faulthandler to kill the worker. + self.worker_timeout: float | None = min(self.timeout * 1.5, self.timeout + 5 * 60) + else: + self.worker_timeout = None + self.workers: list[WorkerThread] | None = None + + jobs = self.runtests.get_jobs() + if jobs is not None: + # Don't spawn more threads than the number of jobs: + # these worker threads would never get anything to do. + self.num_workers = min(self.num_workers, jobs) + + def start_workers(self) -> None: + self.workers = [WorkerThread(index, self) + for index in range(1, self.num_workers + 1)] + jobs = self.runtests.get_jobs() + if jobs is not None: + tests = count(jobs, 'test') + else: + tests = 'tests' + nworkers = len(self.workers) + processes = plural(nworkers, "process", "processes") + msg = (f"Run {tests} in parallel using " + f"{nworkers} worker {processes}") + if self.timeout: + msg += (" (timeout: %s, worker timeout: %s)" + % (format_duration(self.timeout), + format_duration(self.worker_timeout))) + self.log(msg) + for worker in self.workers: + worker.start() + + def stop_workers(self) -> None: + start_time = time.monotonic() + for worker in self.workers: + worker.stop() + for worker in self.workers: + worker.wait_stopped(start_time) + + def _get_result(self) -> QueueOutput | None: + pgo = self.runtests.pgo + use_faulthandler = (self.timeout is not None) + + # bpo-46205: check the status of workers every iteration to avoid + # waiting forever on an empty queue. + while any(worker.is_alive() for worker in self.workers): + if use_faulthandler: + faulthandler.dump_traceback_later(MAIN_PROCESS_TIMEOUT, + exit=True) + + # wait for a thread + try: + return self.output.get(timeout=PROGRESS_UPDATE) + except queue.Empty: + pass + + if not pgo: + # display progress + running = get_running(self.workers) + if running: + self.log(running) + + # all worker threads are done: consume pending results + try: + return self.output.get(timeout=0) + except queue.Empty: + return None + + def display_result(self, mp_result: MultiprocessResult) -> None: + result = mp_result.result + pgo = self.runtests.pgo + + text = str(result) + if mp_result.err_msg: + # WORKER_BUG + text += ' (%s)' % mp_result.err_msg + elif (result.duration >= PROGRESS_MIN_TIME and not pgo): + text += ' (%s)' % format_duration(result.duration) + if not pgo: + running = get_running(self.workers) + if running: + text += f' -- {running}' + self.display_progress(self.test_index, text) + + def _process_result(self, item: QueueOutput) -> TestResult: + """Returns True if test runner must stop.""" + if item[0]: + # Thread got an exception + format_exc = item[1] + print_warning(f"regrtest worker thread failed: {format_exc}") + result = TestResult("", state=State.WORKER_BUG) + self.results.accumulate_result(result, self.runtests) + return result + + self.test_index += 1 + mp_result = item[1] + result = mp_result.result + self.results.accumulate_result(result, self.runtests) + self.display_result(mp_result) + + # Display worker stdout + if not self.runtests.output_on_failure: + show_stdout = True + else: + # --verbose3 ignores stdout on success + show_stdout = (result.state != State.PASSED) + if show_stdout: + stdout = mp_result.worker_stdout + if stdout: + print(stdout, flush=True) + + return result + + def run(self) -> None: + fail_fast = self.runtests.fail_fast + fail_env_changed = self.runtests.fail_env_changed + + self.start_workers() + + self.test_index = 0 + try: + while True: + item = self._get_result() + if item is None: + break + + result = self._process_result(item) + if result.must_stop(fail_fast, fail_env_changed): + break + except KeyboardInterrupt: + print() + self.results.interrupted = True + finally: + if self.timeout is not None: + faulthandler.cancel_dump_traceback_later() + + # Always ensure that all worker processes are no longer + # worker when we exit this function + self.pending.stop() + self.stop_workers() diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py deleted file mode 100644 index 61595277ed6d5a..00000000000000 --- a/Lib/test/libregrtest/runtest.py +++ /dev/null @@ -1,444 +0,0 @@ -import faulthandler -import functools -import gc -import importlib -import io -import os -import sys -import time -import traceback -import unittest - -from test import support -from test.support import os_helper -from test.support import threading_helper -from test.libregrtest.cmdline import Namespace -from test.libregrtest.save_env import saved_test_environment -from test.libregrtest.utils import clear_caches, format_duration, print_warning - - -class TestResult: - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - ) -> None: - self.name = name - self.duration_sec = duration_sec - self.xml_data = xml_data - - def __str__(self) -> str: - return f"{self.name} finished" - - -class Passed(TestResult): - def __str__(self) -> str: - return f"{self.name} passed" - - -class Failed(TestResult): - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - errors: list[tuple[str, str]] | None = None, - failures: list[tuple[str, str]] | None = None, - ) -> None: - super().__init__(name, duration_sec=duration_sec, xml_data=xml_data) - self.errors = errors - self.failures = failures - - def __str__(self) -> str: - if self.errors and self.failures: - le = len(self.errors) - lf = len(self.failures) - error_s = "error" + ("s" if le > 1 else "") - failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({le} {error_s}, {lf} {failure_s})" - - if self.errors: - le = len(self.errors) - error_s = "error" + ("s" if le > 1 else "") - return f"{self.name} failed ({le} {error_s})" - - if self.failures: - lf = len(self.failures) - failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({lf} {failure_s})" - - return f"{self.name} failed" - - -class UncaughtException(Failed): - def __str__(self) -> str: - return f"{self.name} failed (uncaught exception)" - - -class EnvChanged(Failed): - def __str__(self) -> str: - return f"{self.name} failed (env changed)" - - # Convert Passed to EnvChanged - @staticmethod - def from_passed(other): - return EnvChanged(other.name, other.duration_sec, other.xml_data) - - -class RefLeak(Failed): - def __str__(self) -> str: - return f"{self.name} failed (reference leak)" - - -class Skipped(TestResult): - def __str__(self) -> str: - return f"{self.name} skipped" - - -class ResourceDenied(Skipped): - def __str__(self) -> str: - return f"{self.name} skipped (resource denied)" - - -class Interrupted(TestResult): - def __str__(self) -> str: - return f"{self.name} interrupted" - - -class ChildError(Failed): - def __str__(self) -> str: - return f"{self.name} crashed" - - -class DidNotRun(TestResult): - def __str__(self) -> str: - return f"{self.name} ran no tests" - - -class Timeout(Failed): - def __str__(self) -> str: - return f"{self.name} timed out ({format_duration(self.duration_sec)})" - - -# Minimum duration of a test to display its duration or to mention that -# the test is running in background -PROGRESS_MIN_TIME = 30.0 # seconds - -# small set of tests to determine if we have a basically functioning interpreter -# (i.e. if any of these fail, then anything else is likely to follow) -STDTESTS = [ - 'test_grammar', - 'test_opcodes', - 'test_dict', - 'test_builtin', - 'test_exceptions', - 'test_types', - 'test_unittest', - 'test_doctest', - 'test_doctest2', - 'test_support' -] - -# set of tests that we don't want to be executed when using regrtest -NOTTESTS = set() - -#If these test directories are encountered recurse into them and treat each -# test_ .py or dir as a separate test module. This can increase parallelism. -# Beware this can't generally be done for any directory with sub-tests as the -# __init__.py may do things which alter what tests are to be run. - -SPLITTESTDIRS = { - "test_asyncio", -} - -# Storage of uncollectable objects -FOUND_GARBAGE = [] - - -def is_failed(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, EnvChanged): - return ns.fail_env_changed - return isinstance(result, Failed) - - -def findtestdir(path=None): - return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir - - -def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS, *, split_test_dirs=SPLITTESTDIRS, base_mod=""): - """Return a list of all applicable test modules.""" - testdir = findtestdir(testdir) - names = os.listdir(testdir) - tests = [] - others = set(stdtests) | nottests - for name in names: - mod, ext = os.path.splitext(name) - if mod[:5] == "test_" and mod not in others: - if mod in split_test_dirs: - subdir = os.path.join(testdir, mod) - mod = f"{base_mod or 'test'}.{mod}" - tests.extend(findtests(subdir, [], nottests, split_test_dirs=split_test_dirs, base_mod=mod)) - elif ext in (".py", ""): - tests.append(f"{base_mod}.{mod}" if base_mod else mod) - return stdtests + sorted(tests) - - -def get_abs_module(ns: Namespace, test_name: str) -> str: - if test_name.startswith('test.') or ns.testdir: - return test_name - else: - # Import it from the test package - return 'test.' + test_name - - -def _runtest(ns: Namespace, test_name: str) -> TestResult: - # Handle faulthandler timeout, capture stdout+stderr, XML serialization - # and measure time. - - output_on_failure = ns.verbose3 - - use_timeout = ( - ns.timeout is not None and threading_helper.can_start_thread - ) - if use_timeout: - faulthandler.dump_traceback_later(ns.timeout, exit=True) - - start_time = time.perf_counter() - try: - support.set_match_tests(ns.match_tests, ns.ignore_tests) - support.junit_xml_list = xml_list = [] if ns.xmlpath else None - if ns.failfast: - support.failfast = True - - if output_on_failure: - support.verbose = True - - stream = io.StringIO() - orig_stdout = sys.stdout - orig_stderr = sys.stderr - print_warning = support.print_warning - orig_print_warnings_stderr = print_warning.orig_stderr - - output = None - try: - sys.stdout = stream - sys.stderr = stream - # print_warning() writes into the temporary stream to preserve - # messages order. If support.environment_altered becomes true, - # warnings will be written to sys.stderr below. - print_warning.orig_stderr = stream - - result = _runtest_inner(ns, test_name, - display_failure=False) - if not isinstance(result, Passed): - output = stream.getvalue() - finally: - sys.stdout = orig_stdout - sys.stderr = orig_stderr - print_warning.orig_stderr = orig_print_warnings_stderr - - if output is not None: - sys.stderr.write(output) - sys.stderr.flush() - else: - # Tell tests to be moderately quiet - support.verbose = ns.verbose - - result = _runtest_inner(ns, test_name, - display_failure=not ns.verbose) - - if xml_list: - import xml.etree.ElementTree as ET - result.xml_data = [ - ET.tostring(x).decode('us-ascii') - for x in xml_list - ] - - result.duration_sec = time.perf_counter() - start_time - return result - finally: - if use_timeout: - faulthandler.cancel_dump_traceback_later() - support.junit_xml_list = None - - -def runtest(ns: Namespace, test_name: str) -> TestResult: - """Run a single test. - - ns -- regrtest namespace of options - test_name -- the name of the test - - Returns a TestResult sub-class depending on the kind of result received. - - If ns.xmlpath is not None, xml_data is a list containing each - generated testsuite element. - """ - try: - return _runtest(ns, test_name) - except: - if not ns.pgo: - msg = traceback.format_exc() - print(f"test {test_name} crashed -- {msg}", - file=sys.stderr, flush=True) - return Failed(test_name) - - -def _test_module(the_module): - loader = unittest.TestLoader() - tests = loader.loadTestsFromModule(the_module) - for error in loader.errors: - print(error, file=sys.stderr) - if loader.errors: - raise Exception("errors while loading tests") - support.run_unittest(tests) - - -def save_env(ns: Namespace, test_name: str): - return saved_test_environment(test_name, ns.verbose, ns.quiet, pgo=ns.pgo) - - -def _runtest_inner2(ns: Namespace, test_name: str) -> bool: - # Load the test function, run the test function, handle huntrleaks - # to detect leaks. - - abstest = get_abs_module(ns, test_name) - - # remove the module from sys.module to reload it if it was already imported - try: - del sys.modules[abstest] - except KeyError: - pass - - the_module = importlib.import_module(abstest) - - if ns.huntrleaks: - from test.libregrtest.refleak import dash_R - - # If the test has a test_main, that will run the appropriate - # tests. If not, use normal unittest test loading. - test_runner = getattr(the_module, "test_main", None) - if test_runner is None: - test_runner = functools.partial(_test_module, the_module) - - try: - with save_env(ns, test_name): - if ns.huntrleaks: - # Return True if the test leaked references - refleak = dash_R(ns, test_name, test_runner) - else: - test_runner() - refleak = False - finally: - # First kill any dangling references to open files etc. - # This can also issue some ResourceWarnings which would otherwise get - # triggered during the following test run, and possibly produce - # failures. - support.gc_collect() - - cleanup_test_droppings(test_name, ns.verbose) - - if gc.garbage: - support.environment_altered = True - print_warning(f"{test_name} created {len(gc.garbage)} " - f"uncollectable object(s).") - - # move the uncollectable objects somewhere, - # so we don't see them again - FOUND_GARBAGE.extend(gc.garbage) - gc.garbage.clear() - - support.reap_children() - - return refleak - - -def _runtest_inner( - ns: Namespace, test_name: str, display_failure: bool = True -) -> TestResult: - # Detect environment changes, handle exceptions. - - # Reset the environment_altered flag to detect if a test altered - # the environment - support.environment_altered = False - - if ns.pgo: - display_failure = False - - try: - clear_caches() - support.gc_collect() - - with save_env(ns, test_name): - refleak = _runtest_inner2(ns, test_name) - except support.ResourceDenied as msg: - if not ns.quiet and not ns.pgo: - print(f"{test_name} skipped -- {msg}", flush=True) - return ResourceDenied(test_name) - except unittest.SkipTest as msg: - if not ns.quiet and not ns.pgo: - print(f"{test_name} skipped -- {msg}", flush=True) - return Skipped(test_name) - except support.TestFailedWithDetails as exc: - msg = f"test {test_name} failed" - if display_failure: - msg = f"{msg} -- {exc}" - print(msg, file=sys.stderr, flush=True) - return Failed(test_name, errors=exc.errors, failures=exc.failures) - except support.TestFailed as exc: - msg = f"test {test_name} failed" - if display_failure: - msg = f"{msg} -- {exc}" - print(msg, file=sys.stderr, flush=True) - return Failed(test_name) - except support.TestDidNotRun: - return DidNotRun(test_name) - except KeyboardInterrupt: - print() - return Interrupted(test_name) - except: - if not ns.pgo: - msg = traceback.format_exc() - print(f"test {test_name} crashed -- {msg}", - file=sys.stderr, flush=True) - return UncaughtException(test_name) - - if refleak: - return RefLeak(test_name) - if support.environment_altered: - return EnvChanged(test_name) - return Passed(test_name) - - -def cleanup_test_droppings(test_name: str, verbose: int) -> None: - # Try to clean up junk commonly left behind. While tests shouldn't leave - # any files or directories behind, when a test fails that can be tedious - # for it to arrange. The consequences can be especially nasty on Windows, - # since if a test leaves a file open, it cannot be deleted by name (while - # there's nothing we can do about that here either, we can display the - # name of the offending test, which is a real help). - for name in (os_helper.TESTFN,): - if not os.path.exists(name): - continue - - if os.path.isdir(name): - import shutil - kind, nuker = "directory", shutil.rmtree - elif os.path.isfile(name): - kind, nuker = "file", os.unlink - else: - raise RuntimeError(f"os.path says {name!r} exists but is neither " - f"directory nor file") - - if verbose: - print_warning(f"{test_name} left behind {kind} {name!r}") - support.environment_altered = True - - try: - import stat - # fix possible permissions problems that might prevent cleanup - os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) - nuker(name) - except Exception as exc: - print_warning(f"{test_name} left behind {kind} {name!r} " - f"and it couldn't be removed: {exc}") diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py deleted file mode 100644 index 62e6c6df36518c..00000000000000 --- a/Lib/test/libregrtest/runtest_mp.py +++ /dev/null @@ -1,572 +0,0 @@ -import faulthandler -import json -import os.path -import queue -import signal -import subprocess -import sys -import tempfile -import threading -import time -import traceback -from typing import NamedTuple, NoReturn, Literal, Any, TextIO - -from test import support -from test.support import os_helper - -from test.libregrtest.cmdline import Namespace -from test.libregrtest.main import Regrtest -from test.libregrtest.runtest import ( - runtest, is_failed, TestResult, Interrupted, Timeout, ChildError, - PROGRESS_MIN_TIME, Passed, EnvChanged) -from test.libregrtest.setup import setup_tests -from test.libregrtest.utils import format_duration, print_warning - -if sys.platform == 'win32': - import locale - - -# Display the running tests if nothing happened last N seconds -PROGRESS_UPDATE = 30.0 # seconds -assert PROGRESS_UPDATE >= PROGRESS_MIN_TIME - -# Kill the main process after 5 minutes. It is supposed to write an update -# every PROGRESS_UPDATE seconds. Tolerate 5 minutes for Python slowest -# buildbot workers. -MAIN_PROCESS_TIMEOUT = 5 * 60.0 -assert MAIN_PROCESS_TIMEOUT >= PROGRESS_UPDATE - -# Time to wait until a worker completes: should be immediate -JOIN_TIMEOUT = 30.0 # seconds - -USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg")) - - -def must_stop(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, Interrupted): - return True - if ns.failfast and is_failed(result, ns): - return True - return False - - -def parse_worker_args(worker_args) -> tuple[Namespace, str]: - ns_dict, test_name = json.loads(worker_args) - ns = Namespace(**ns_dict) - return (ns, test_name) - - -def run_test_in_subprocess(testname: str, ns: Namespace, tmp_dir: str, stdout_fh: TextIO) -> subprocess.Popen: - ns_dict = vars(ns) - worker_args = (ns_dict, testname) - worker_args = json.dumps(worker_args) - if ns.python is not None: - executable = ns.python - else: - executable = [sys.executable] - cmd = [*executable, *support.args_from_interpreter_flags(), - '-u', # Unbuffered stdout and stderr - '-m', 'test.regrtest', - '--worker-args', worker_args] - - env = dict(os.environ) - if tmp_dir is not None: - env['TMPDIR'] = tmp_dir - env['TEMP'] = tmp_dir - env['TMP'] = tmp_dir - - # Running the child from the same working directory as regrtest's original - # invocation ensures that TEMPDIR for the child is the same when - # sysconfig.is_python_build() is true. See issue 15300. - kw = dict( - env=env, - stdout=stdout_fh, - # bpo-45410: Write stderr into stdout to keep messages order - stderr=stdout_fh, - text=True, - close_fds=(os.name != 'nt'), - cwd=os_helper.SAVEDCWD, - ) - if USE_PROCESS_GROUP: - kw['start_new_session'] = True - return subprocess.Popen(cmd, **kw) - - -def run_tests_worker(ns: Namespace, test_name: str) -> NoReturn: - setup_tests(ns) - - result = runtest(ns, test_name) - - print() # Force a newline (just in case) - - # Serialize TestResult as dict in JSON - print(json.dumps(result, cls=EncodeTestResult), flush=True) - sys.exit(0) - - -# We do not use a generator so multiple threads can call next(). -class MultiprocessIterator: - - """A thread-safe iterator over tests for multiprocess mode.""" - - def __init__(self, tests_iter): - self.lock = threading.Lock() - self.tests_iter = tests_iter - - def __iter__(self): - return self - - def __next__(self): - with self.lock: - if self.tests_iter is None: - raise StopIteration - return next(self.tests_iter) - - def stop(self): - with self.lock: - self.tests_iter = None - - -class MultiprocessResult(NamedTuple): - result: TestResult - # bpo-45410: stderr is written into stdout to keep messages order - stdout: str - error_msg: str - - -ExcStr = str -QueueOutput = tuple[Literal[False], MultiprocessResult] | tuple[Literal[True], ExcStr] - - -class ExitThread(Exception): - pass - - -class TestWorkerProcess(threading.Thread): - def __init__(self, worker_id: int, runner: "MultiprocessTestRunner") -> None: - super().__init__() - self.worker_id = worker_id - self.pending = runner.pending - self.output = runner.output - self.ns = runner.ns - self.timeout = runner.worker_timeout - self.regrtest = runner.regrtest - self.current_test_name = None - self.start_time = None - self._popen = None - self._killed = False - self._stopped = False - - def __repr__(self) -> str: - info = [f'TestWorkerProcess #{self.worker_id}'] - if self.is_alive(): - info.append("running") - else: - info.append('stopped') - test = self.current_test_name - if test: - info.append(f'test={test}') - popen = self._popen - if popen is not None: - dt = time.monotonic() - self.start_time - info.extend((f'pid={self._popen.pid}', - f'time={format_duration(dt)}')) - return '<%s>' % ' '.join(info) - - def _kill(self) -> None: - popen = self._popen - if popen is None: - return - - if self._killed: - return - self._killed = True - - if USE_PROCESS_GROUP: - what = f"{self} process group" - else: - what = f"{self}" - - print(f"Kill {what}", file=sys.stderr, flush=True) - try: - if USE_PROCESS_GROUP: - os.killpg(popen.pid, signal.SIGKILL) - else: - popen.kill() - except ProcessLookupError: - # popen.kill(): the process completed, the TestWorkerProcess thread - # read its exit status, but Popen.send_signal() read the returncode - # just before Popen.wait() set returncode. - pass - except OSError as exc: - print_warning(f"Failed to kill {what}: {exc!r}") - - def stop(self) -> None: - # Method called from a different thread to stop this thread - self._stopped = True - self._kill() - - def mp_result_error( - self, - test_result: TestResult, - stdout: str = '', - err_msg=None - ) -> MultiprocessResult: - test_result.duration_sec = time.monotonic() - self.start_time - return MultiprocessResult(test_result, stdout, err_msg) - - def _run_process(self, test_name: str, tmp_dir: str, stdout_fh: TextIO) -> int: - self.start_time = time.monotonic() - - self.current_test_name = test_name - try: - popen = run_test_in_subprocess(test_name, self.ns, tmp_dir, stdout_fh) - - self._killed = False - self._popen = popen - except: - self.current_test_name = None - raise - - try: - if self._stopped: - # If kill() has been called before self._popen is set, - # self._popen is still running. Call again kill() - # to ensure that the process is killed. - self._kill() - raise ExitThread - - try: - # gh-94026: stdout+stderr are written to tempfile - retcode = popen.wait(timeout=self.timeout) - assert retcode is not None - return retcode - except subprocess.TimeoutExpired: - if self._stopped: - # kill() has been called: communicate() fails on reading - # closed stdout - raise ExitThread - - # On timeout, kill the process - self._kill() - - # None means TIMEOUT for the caller - retcode = None - # bpo-38207: Don't attempt to call communicate() again: on it - # can hang until all child processes using stdout - # pipes completes. - except OSError: - if self._stopped: - # kill() has been called: communicate() fails - # on reading closed stdout - raise ExitThread - raise - except: - self._kill() - raise - finally: - self._wait_completed() - self._popen = None - self.current_test_name = None - - def _runtest(self, test_name: str) -> MultiprocessResult: - if sys.platform == 'win32': - # gh-95027: When stdout is not a TTY, Python uses the ANSI code - # page for the sys.stdout encoding. If the main process runs in a - # terminal, sys.stdout uses WindowsConsoleIO with UTF-8 encoding. - encoding = locale.getencoding() - else: - encoding = sys.stdout.encoding - - # gh-94026: Write stdout+stderr to a tempfile as workaround for - # non-blocking pipes on Emscripten with NodeJS. - with tempfile.TemporaryFile('w+', encoding=encoding) as stdout_fh: - # gh-93353: Check for leaked temporary files in the parent process, - # since the deletion of temporary files can happen late during - # Python finalization: too late for libregrtest. - if not support.is_wasi: - # Don't check for leaked temporary files and directories if Python is - # run on WASI. WASI don't pass environment variables like TMPDIR to - # worker processes. - tmp_dir = tempfile.mkdtemp(prefix="test_python_") - tmp_dir = os.path.abspath(tmp_dir) - try: - retcode = self._run_process(test_name, tmp_dir, stdout_fh) - finally: - tmp_files = os.listdir(tmp_dir) - os_helper.rmtree(tmp_dir) - else: - retcode = self._run_process(test_name, None, stdout_fh) - tmp_files = () - stdout_fh.seek(0) - - try: - stdout = stdout_fh.read().strip() - except Exception as exc: - # gh-101634: Catch UnicodeDecodeError if stdout cannot be - # decoded from encoding - err_msg = f"Cannot read process stdout: {exc}" - return self.mp_result_error(ChildError(test_name), '', err_msg) - - if retcode is None: - return self.mp_result_error(Timeout(test_name), stdout) - - err_msg = None - if retcode != 0: - err_msg = "Exit code %s" % retcode - else: - stdout, _, result = stdout.rpartition("\n") - stdout = stdout.rstrip() - if not result: - err_msg = "Failed to parse worker stdout" - else: - try: - # deserialize run_tests_worker() output - result = json.loads(result, object_hook=decode_test_result) - except Exception as exc: - err_msg = "Failed to parse worker JSON: %s" % exc - - if err_msg is not None: - return self.mp_result_error(ChildError(test_name), stdout, err_msg) - - if tmp_files: - msg = (f'\n\n' - f'Warning -- {test_name} leaked temporary files ' - f'({len(tmp_files)}): {", ".join(sorted(tmp_files))}') - stdout += msg - if isinstance(result, Passed): - result = EnvChanged.from_passed(result) - - return MultiprocessResult(result, stdout, err_msg) - - def run(self) -> None: - while not self._stopped: - try: - try: - test_name = next(self.pending) - except StopIteration: - break - - mp_result = self._runtest(test_name) - self.output.put((False, mp_result)) - - if must_stop(mp_result.result, self.ns): - break - except ExitThread: - break - except BaseException: - self.output.put((True, traceback.format_exc())) - break - - def _wait_completed(self) -> None: - popen = self._popen - - try: - popen.wait(JOIN_TIMEOUT) - except (subprocess.TimeoutExpired, OSError) as exc: - print_warning(f"Failed to wait for {self} completion " - f"(timeout={format_duration(JOIN_TIMEOUT)}): " - f"{exc!r}") - - def wait_stopped(self, start_time: float) -> None: - # bpo-38207: MultiprocessTestRunner.stop_workers() called self.stop() - # which killed the process. Sometimes, killing the process from the - # main thread does not interrupt popen.communicate() in - # TestWorkerProcess thread. This loop with a timeout is a workaround - # for that. - # - # Moreover, if this method fails to join the thread, it is likely - # that Python will hang at exit while calling threading._shutdown() - # which tries again to join the blocked thread. Regrtest.main() - # uses EXIT_TIMEOUT to workaround this second bug. - while True: - # Write a message every second - self.join(1.0) - if not self.is_alive(): - break - dt = time.monotonic() - start_time - self.regrtest.log(f"Waiting for {self} thread " - f"for {format_duration(dt)}") - if dt > JOIN_TIMEOUT: - print_warning(f"Failed to join {self} in {format_duration(dt)}") - break - - -def get_running(workers: list[TestWorkerProcess]) -> list[TestWorkerProcess]: - running = [] - for worker in workers: - current_test_name = worker.current_test_name - if not current_test_name: - continue - dt = time.monotonic() - worker.start_time - if dt >= PROGRESS_MIN_TIME: - text = '%s (%s)' % (current_test_name, format_duration(dt)) - running.append(text) - return running - - -class MultiprocessTestRunner: - def __init__(self, regrtest: Regrtest) -> None: - self.regrtest = regrtest - self.log = self.regrtest.log - self.ns = regrtest.ns - self.output: queue.Queue[QueueOutput] = queue.Queue() - self.pending = MultiprocessIterator(self.regrtest.tests) - if self.ns.timeout is not None: - # Rely on faulthandler to kill a worker process. This timouet is - # when faulthandler fails to kill a worker process. Give a maximum - # of 5 minutes to faulthandler to kill the worker. - self.worker_timeout = min(self.ns.timeout * 1.5, - self.ns.timeout + 5 * 60) - else: - self.worker_timeout = None - self.workers = None - - def start_workers(self) -> None: - self.workers = [TestWorkerProcess(index, self) - for index in range(1, self.ns.use_mp + 1)] - msg = f"Run tests in parallel using {len(self.workers)} child processes" - if self.ns.timeout: - msg += (" (timeout: %s, worker timeout: %s)" - % (format_duration(self.ns.timeout), - format_duration(self.worker_timeout))) - self.log(msg) - for worker in self.workers: - worker.start() - - def stop_workers(self) -> None: - start_time = time.monotonic() - for worker in self.workers: - worker.stop() - for worker in self.workers: - worker.wait_stopped(start_time) - - def _get_result(self) -> QueueOutput | None: - use_faulthandler = (self.ns.timeout is not None) - timeout = PROGRESS_UPDATE - - # bpo-46205: check the status of workers every iteration to avoid - # waiting forever on an empty queue. - while any(worker.is_alive() for worker in self.workers): - if use_faulthandler: - faulthandler.dump_traceback_later(MAIN_PROCESS_TIMEOUT, - exit=True) - - # wait for a thread - try: - return self.output.get(timeout=timeout) - except queue.Empty: - pass - - # display progress - running = get_running(self.workers) - if running and not self.ns.pgo: - self.log('running: %s' % ', '.join(running)) - - # all worker threads are done: consume pending results - try: - return self.output.get(timeout=0) - except queue.Empty: - return None - - def display_result(self, mp_result: MultiprocessResult) -> None: - result = mp_result.result - - text = str(result) - if mp_result.error_msg is not None: - # CHILD_ERROR - text += ' (%s)' % mp_result.error_msg - elif (result.duration_sec >= PROGRESS_MIN_TIME and not self.ns.pgo): - text += ' (%s)' % format_duration(result.duration_sec) - running = get_running(self.workers) - if running and not self.ns.pgo: - text += ' -- running: %s' % ', '.join(running) - self.regrtest.display_progress(self.test_index, text) - - def _process_result(self, item: QueueOutput) -> bool: - """Returns True if test runner must stop.""" - if item[0]: - # Thread got an exception - format_exc = item[1] - print_warning(f"regrtest worker thread failed: {format_exc}") - result = ChildError("") - self.regrtest.accumulate_result(result) - return True - - self.test_index += 1 - mp_result = item[1] - self.regrtest.accumulate_result(mp_result.result) - self.display_result(mp_result) - - if mp_result.stdout: - print(mp_result.stdout, flush=True) - - if must_stop(mp_result.result, self.ns): - return True - - return False - - def run_tests(self) -> None: - self.start_workers() - - self.test_index = 0 - try: - while True: - item = self._get_result() - if item is None: - break - - stop = self._process_result(item) - if stop: - break - except KeyboardInterrupt: - print() - self.regrtest.interrupted = True - finally: - if self.ns.timeout is not None: - faulthandler.cancel_dump_traceback_later() - - # Always ensure that all worker processes are no longer - # worker when we exit this function - self.pending.stop() - self.stop_workers() - - -def run_tests_multiprocess(regrtest: Regrtest) -> None: - MultiprocessTestRunner(regrtest).run_tests() - - -class EncodeTestResult(json.JSONEncoder): - """Encode a TestResult (sub)class object into a JSON dict.""" - - def default(self, o: Any) -> dict[str, Any]: - if isinstance(o, TestResult): - result = vars(o) - result["__test_result__"] = o.__class__.__name__ - return result - - return super().default(o) - - -def decode_test_result(d: dict[str, Any]) -> TestResult | dict[str, Any]: - """Decode a TestResult (sub)class object from a JSON dict.""" - - if "__test_result__" not in d: - return d - - cls_name = d.pop("__test_result__") - for cls in get_all_test_result_classes(): - if cls.__name__ == cls_name: - return cls(**d) - - -def get_all_test_result_classes() -> set[type[TestResult]]: - prev_count = 0 - classes = {TestResult} - while len(classes) > prev_count: - prev_count = len(classes) - to_add = [] - for cls in classes: - to_add.extend(cls.__subclasses__()) - classes.update(to_add) - return classes diff --git a/Lib/test/libregrtest/runtests.py b/Lib/test/libregrtest/runtests.py new file mode 100644 index 00000000000000..4da312db4cb02e --- /dev/null +++ b/Lib/test/libregrtest/runtests.py @@ -0,0 +1,162 @@ +import contextlib +import dataclasses +import json +import os +import subprocess +from typing import Any + +from test import support + +from .utils import ( + StrPath, StrJSON, TestTuple, FilterTuple, FilterDict) + + +class JsonFileType: + UNIX_FD = "UNIX_FD" + WINDOWS_HANDLE = "WINDOWS_HANDLE" + STDOUT = "STDOUT" + + +@dataclasses.dataclass(slots=True, frozen=True) +class JsonFile: + # file type depends on file_type: + # - UNIX_FD: file descriptor (int) + # - WINDOWS_HANDLE: handle (int) + # - STDOUT: use process stdout (None) + file: int | None + file_type: str + + def configure_subprocess(self, popen_kwargs: dict) -> None: + match self.file_type: + case JsonFileType.UNIX_FD: + # Unix file descriptor + popen_kwargs['pass_fds'] = [self.file] + case JsonFileType.WINDOWS_HANDLE: + # Windows handle + startupinfo = subprocess.STARTUPINFO() + startupinfo.lpAttributeList = {"handle_list": [self.file]} + popen_kwargs['startupinfo'] = startupinfo + + @contextlib.contextmanager + def inherit_subprocess(self): + if self.file_type == JsonFileType.WINDOWS_HANDLE: + os.set_handle_inheritable(self.file, True) + try: + yield + finally: + os.set_handle_inheritable(self.file, False) + else: + yield + + def open(self, mode='r', *, encoding): + if self.file_type == JsonFileType.STDOUT: + raise ValueError("for STDOUT file type, just use sys.stdout") + + file = self.file + if self.file_type == JsonFileType.WINDOWS_HANDLE: + import msvcrt + # Create a file descriptor from the handle + file = msvcrt.open_osfhandle(file, os.O_WRONLY) + return open(file, mode, encoding=encoding) + + +@dataclasses.dataclass(slots=True, frozen=True) +class HuntRefleak: + warmups: int + runs: int + filename: StrPath + + +@dataclasses.dataclass(slots=True, frozen=True) +class RunTests: + tests: TestTuple + fail_fast: bool + fail_env_changed: bool + match_tests: FilterTuple | None + ignore_tests: FilterTuple | None + match_tests_dict: FilterDict | None + rerun: bool + forever: bool + pgo: bool + pgo_extended: bool + output_on_failure: bool + timeout: float | None + verbose: int + quiet: bool + hunt_refleak: HuntRefleak | None + test_dir: StrPath | None + use_junit: bool + memory_limit: str | None + gc_threshold: int | None + use_resources: tuple[str, ...] + python_cmd: tuple[str, ...] | None + randomize: bool + random_seed: int | None + json_file: JsonFile | None + + def copy(self, **override): + state = dataclasses.asdict(self) + state.update(override) + return RunTests(**state) + + def get_match_tests(self, test_name) -> FilterTuple | None: + if self.match_tests_dict is not None: + return self.match_tests_dict.get(test_name, None) + else: + return None + + def get_jobs(self): + # Number of run_single_test() calls needed to run all tests. + # None means that there is not bound limit (--forever option). + if self.forever: + return None + return len(self.tests) + + def iter_tests(self): + if self.forever: + while True: + yield from self.tests + else: + yield from self.tests + + def as_json(self) -> StrJSON: + return json.dumps(self, cls=_EncodeRunTests) + + @staticmethod + def from_json(worker_json: StrJSON) -> 'RunTests': + return json.loads(worker_json, object_hook=_decode_runtests) + + def json_file_use_stdout(self) -> bool: + # Use STDOUT in two cases: + # + # - If --python command line option is used; + # - On Emscripten and WASI. + # + # On other platforms, UNIX_FD or WINDOWS_HANDLE can be used. + return ( + bool(self.python_cmd) + or support.is_emscripten + or support.is_wasi + ) + + +class _EncodeRunTests(json.JSONEncoder): + def default(self, o: Any) -> dict[str, Any]: + if isinstance(o, RunTests): + result = dataclasses.asdict(o) + result["__runtests__"] = True + return result + else: + return super().default(o) + + +def _decode_runtests(data: dict[str, Any]) -> RunTests | dict[str, Any]: + if "__runtests__" in data: + data.pop('__runtests__') + if data['hunt_refleak']: + data['hunt_refleak'] = HuntRefleak(**data['hunt_refleak']) + if data['json_file']: + data['json_file'] = JsonFile(**data['json_file']) + return RunTests(**data) + else: + return data diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index c7801b767c590c..b2cc381344b2ef 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -3,9 +3,11 @@ import os import sys import threading + from test import support from test.support import os_helper -from test.libregrtest.utils import print_warning + +from .utils import print_warning class SkipTestEnvironment(Exception): @@ -23,7 +25,7 @@ class SkipTestEnvironment(Exception): class saved_test_environment: """Save bits of the test environment and restore them at block exit. - with saved_test_environment(testname, verbose, quiet): + with saved_test_environment(test_name, verbose, quiet): #stuff Unless quiet is True, a warning is printed to stderr if any of @@ -34,8 +36,8 @@ class saved_test_environment: items is also printed. """ - def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): - self.testname = testname + def __init__(self, test_name, verbose, quiet, *, pgo): + self.test_name = test_name self.verbose = verbose self.quiet = quiet self.pgo = pgo @@ -323,7 +325,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): restore(original) if not self.quiet and not self.pgo: print_warning( - f"{name} was modified by {self.testname}\n" + f"{name} was modified by {self.test_name}\n" f" Before: {original}\n" f" After: {current} ") return False diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index b76bece7ca08b5..793347f60ad93c 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -1,24 +1,32 @@ -import atexit import faulthandler +import gc import os +import random import signal import sys import unittest from test import support from test.support.os_helper import TESTFN_UNDECODABLE, FS_NONASCII -try: - import gc -except ImportError: - gc = None -from test.libregrtest.utils import (setup_unraisable_hook, - setup_threading_excepthook) +from .runtests import RunTests +from .utils import ( + setup_unraisable_hook, setup_threading_excepthook, fix_umask, + adjust_rlimit_nofile) UNICODE_GUARD_ENV = "PYTHONREGRTEST_UNICODE_GUARD" -def setup_tests(ns): +def setup_test_dir(testdir: str | None) -> None: + if testdir: + # Prepend test directory to sys.path, so runtest() will be able + # to locate tests + sys.path.insert(0, os.path.abspath(testdir)) + + +def setup_process(): + fix_umask() + try: stderr_fd = sys.__stderr__.fileno() except (ValueError, AttributeError): @@ -40,14 +48,9 @@ def setup_tests(ns): for signum in signals: faulthandler.register(signum, chain=True, file=stderr_fd) - _adjust_resource_limits() - replace_stdout() - support.record_original_stdout(sys.stdout) + adjust_rlimit_nofile() - if ns.testdir: - # Prepend test directory to sys.path, so runtest() will be able - # to locate tests - sys.path.insert(0, os.path.abspath(ns.testdir)) + support.record_original_stdout(sys.stdout) # Some times __path__ and __file__ are not absolute (e.g. while running from # Lib/) and, if we change the CWD to run the tests in a temporary dir, some @@ -66,19 +69,6 @@ def setup_tests(ns): if getattr(module, '__file__', None): module.__file__ = os.path.abspath(module.__file__) - if ns.huntrleaks: - unittest.BaseTestSuite._cleanup = False - - if ns.memlimit is not None: - support.set_memlimit(ns.memlimit) - - if ns.threshold is not None: - gc.set_threshold(ns.threshold) - - support.suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2) - - support.use_resources = ns.use_resources - if hasattr(sys, 'addaudithook'): # Add an auditing hook for all tests to ensure PySys_Audit is tested def _test_audit_hook(name, args): @@ -88,21 +78,6 @@ def _test_audit_hook(name, args): setup_unraisable_hook() setup_threading_excepthook() - if ns.timeout is not None: - # For a slow buildbot worker, increase SHORT_TIMEOUT and LONG_TIMEOUT - support.SHORT_TIMEOUT = max(support.SHORT_TIMEOUT, ns.timeout / 40) - support.LONG_TIMEOUT = max(support.LONG_TIMEOUT, ns.timeout / 4) - - # If --timeout is short: reduce timeouts - support.LOOPBACK_TIMEOUT = min(support.LOOPBACK_TIMEOUT, ns.timeout) - support.INTERNET_TIMEOUT = min(support.INTERNET_TIMEOUT, ns.timeout) - support.SHORT_TIMEOUT = min(support.SHORT_TIMEOUT, ns.timeout) - support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout) - - if ns.xmlpath: - from test.support.testresult import RegressionTestResult - RegressionTestResult.USE_XML = True - # Ensure there's a non-ASCII character in env vars at all times to force # tests consider this case. See BPO-44647 for details. if TESTFN_UNDECODABLE and os.supports_bytes_environ: @@ -111,49 +86,46 @@ def _test_audit_hook(name, args): os.environ.setdefault(UNICODE_GUARD_ENV, FS_NONASCII) -def replace_stdout(): - """Set stdout encoder error handler to backslashreplace (as stderr error - handler) to avoid UnicodeEncodeError when printing a traceback""" - stdout = sys.stdout - try: - fd = stdout.fileno() - except ValueError: - # On IDLE, sys.stdout has no file descriptor and is not a TextIOWrapper - # object. Leaving sys.stdout unchanged. - # - # Catch ValueError to catch io.UnsupportedOperation on TextIOBase - # and ValueError on a closed stream. - return +def setup_tests(runtests: RunTests): + support.verbose = runtests.verbose + support.failfast = runtests.fail_fast + support.PGO = runtests.pgo + support.PGO_EXTENDED = runtests.pgo_extended - sys.stdout = open(fd, 'w', - encoding=stdout.encoding, - errors="backslashreplace", - closefd=False, - newline='\n') + support.set_match_tests(runtests.match_tests, runtests.ignore_tests) - def restore_stdout(): - sys.stdout.close() - sys.stdout = stdout - atexit.register(restore_stdout) + if runtests.use_junit: + support.junit_xml_list = [] + from test.support.testresult import RegressionTestResult + RegressionTestResult.USE_XML = True + else: + support.junit_xml_list = None + if runtests.memory_limit is not None: + support.set_memlimit(runtests.memory_limit) -def _adjust_resource_limits(): - """Adjust the system resource limits (ulimit) if needed.""" - try: - import resource - from resource import RLIMIT_NOFILE - except ImportError: - return - fd_limit, max_fds = resource.getrlimit(RLIMIT_NOFILE) - # On macOS the default fd limit is sometimes too low (256) for our - # test suite to succeed. Raise it to something more reasonable. - # 1024 is a common Linux default. - desired_fds = 1024 - if fd_limit < desired_fds and fd_limit < max_fds: - new_fd_limit = min(desired_fds, max_fds) - try: - resource.setrlimit(RLIMIT_NOFILE, (new_fd_limit, max_fds)) - print(f"Raised RLIMIT_NOFILE: {fd_limit} -> {new_fd_limit}") - except (ValueError, OSError) as err: - print(f"Unable to raise RLIMIT_NOFILE from {fd_limit} to " - f"{new_fd_limit}: {err}.") + support.suppress_msvcrt_asserts(runtests.verbose >= 2) + + support.use_resources = runtests.use_resources + + timeout = runtests.timeout + if timeout is not None: + # For a slow buildbot worker, increase SHORT_TIMEOUT and LONG_TIMEOUT + support.LOOPBACK_TIMEOUT = max(support.LOOPBACK_TIMEOUT, timeout / 120) + # don't increase INTERNET_TIMEOUT + support.SHORT_TIMEOUT = max(support.SHORT_TIMEOUT, timeout / 40) + support.LONG_TIMEOUT = max(support.LONG_TIMEOUT, timeout / 4) + + # If --timeout is short: reduce timeouts + support.LOOPBACK_TIMEOUT = min(support.LOOPBACK_TIMEOUT, timeout) + support.INTERNET_TIMEOUT = min(support.INTERNET_TIMEOUT, timeout) + support.SHORT_TIMEOUT = min(support.SHORT_TIMEOUT, timeout) + support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, timeout) + + if runtests.hunt_refleak: + unittest.BaseTestSuite._cleanup = False + + if runtests.gc_threshold is not None: + gc.set_threshold(runtests.gc_threshold) + + random.seed(runtests.random_seed) diff --git a/Lib/test/libregrtest/single.py b/Lib/test/libregrtest/single.py new file mode 100644 index 00000000000000..0304f858edf42c --- /dev/null +++ b/Lib/test/libregrtest/single.py @@ -0,0 +1,278 @@ +import doctest +import faulthandler +import gc +import importlib +import io +import sys +import time +import traceback +import unittest + +from test import support +from test.support import TestStats +from test.support import threading_helper + +from .result import State, TestResult +from .runtests import RunTests +from .save_env import saved_test_environment +from .setup import setup_tests +from .utils import ( + TestName, + clear_caches, remove_testfn, abs_module_name, print_warning) + + +# Minimum duration of a test to display its duration or to mention that +# the test is running in background +PROGRESS_MIN_TIME = 30.0 # seconds + + +def run_unittest(test_mod): + loader = unittest.TestLoader() + tests = loader.loadTestsFromModule(test_mod) + for error in loader.errors: + print(error, file=sys.stderr) + if loader.errors: + raise Exception("errors while loading tests") + return support.run_unittest(tests) + + +def regrtest_runner(result: TestResult, test_func, runtests: RunTests) -> None: + # Run test_func(), collect statistics, and detect reference and memory + # leaks. + if runtests.hunt_refleak: + from .refleak import runtest_refleak + refleak, test_result = runtest_refleak(result.test_name, test_func, + runtests.hunt_refleak, + runtests.quiet) + else: + test_result = test_func() + refleak = False + + if refleak: + result.state = State.REFLEAK + + stats: TestStats | None + + match test_result: + case TestStats(): + stats = test_result + case unittest.TestResult(): + stats = TestStats.from_unittest(test_result) + case doctest.TestResults(): + stats = TestStats.from_doctest(test_result) + case None: + print_warning(f"{result.test_name} test runner returned None: {test_func}") + stats = None + case _: + print_warning(f"Unknown test result type: {type(test_result)}") + stats = None + + result.stats = stats + + +# Storage of uncollectable GC objects (gc.garbage) +GC_GARBAGE = [] + + +def _load_run_test(result: TestResult, runtests: RunTests) -> None: + # Load the test module and run the tests. + test_name = result.test_name + module_name = abs_module_name(test_name, runtests.test_dir) + + # Remove the module from sys.module to reload it if it was already imported + sys.modules.pop(module_name, None) + + test_mod = importlib.import_module(module_name) + + if hasattr(test_mod, "test_main"): + # https://github.com/python/cpython/issues/89392 + raise Exception(f"Module {test_name} defines test_main() which " + f"is no longer supported by regrtest") + def test_func(): + return run_unittest(test_mod) + + try: + regrtest_runner(result, test_func, runtests) + finally: + # First kill any dangling references to open files etc. + # This can also issue some ResourceWarnings which would otherwise get + # triggered during the following test run, and possibly produce + # failures. + support.gc_collect() + + remove_testfn(test_name, runtests.verbose) + + if gc.garbage: + support.environment_altered = True + print_warning(f"{test_name} created {len(gc.garbage)} " + f"uncollectable object(s)") + + # move the uncollectable objects somewhere, + # so we don't see them again + GC_GARBAGE.extend(gc.garbage) + gc.garbage.clear() + + support.reap_children() + + +def _runtest_env_changed_exc(result: TestResult, runtests: RunTests, + display_failure: bool = True) -> None: + # Handle exceptions, detect environment changes. + + # Reset the environment_altered flag to detect if a test altered + # the environment + support.environment_altered = False + + pgo = runtests.pgo + if pgo: + display_failure = False + quiet = runtests.quiet + + test_name = result.test_name + try: + clear_caches() + support.gc_collect() + + with saved_test_environment(test_name, + runtests.verbose, quiet, pgo=pgo): + _load_run_test(result, runtests) + except support.ResourceDenied as exc: + if not quiet and not pgo: + print(f"{test_name} skipped -- {exc}", flush=True) + result.state = State.RESOURCE_DENIED + return + except unittest.SkipTest as exc: + if not quiet and not pgo: + print(f"{test_name} skipped -- {exc}", flush=True) + result.state = State.SKIPPED + return + except support.TestFailedWithDetails as exc: + msg = f"test {test_name} failed" + if display_failure: + msg = f"{msg} -- {exc}" + print(msg, file=sys.stderr, flush=True) + result.state = State.FAILED + result.errors = exc.errors + result.failures = exc.failures + result.stats = exc.stats + return + except support.TestFailed as exc: + msg = f"test {test_name} failed" + if display_failure: + msg = f"{msg} -- {exc}" + print(msg, file=sys.stderr, flush=True) + result.state = State.FAILED + result.stats = exc.stats + return + except support.TestDidNotRun: + result.state = State.DID_NOT_RUN + return + except KeyboardInterrupt: + print() + result.state = State.INTERRUPTED + return + except: + if not pgo: + msg = traceback.format_exc() + print(f"test {test_name} crashed -- {msg}", + file=sys.stderr, flush=True) + result.state = State.UNCAUGHT_EXC + return + + if support.environment_altered: + result.set_env_changed() + # Don't override the state if it was already set (REFLEAK or ENV_CHANGED) + if result.state is None: + result.state = State.PASSED + + +def _runtest(result: TestResult, runtests: RunTests) -> None: + # Capture stdout and stderr, set faulthandler timeout, + # and create JUnit XML report. + verbose = runtests.verbose + output_on_failure = runtests.output_on_failure + timeout = runtests.timeout + + use_timeout = ( + timeout is not None and threading_helper.can_start_thread + ) + if use_timeout: + faulthandler.dump_traceback_later(timeout, exit=True) + + try: + setup_tests(runtests) + + if output_on_failure: + support.verbose = True + + stream = io.StringIO() + orig_stdout = sys.stdout + orig_stderr = sys.stderr + print_warning = support.print_warning + orig_print_warnings_stderr = print_warning.orig_stderr + + output = None + try: + sys.stdout = stream + sys.stderr = stream + # print_warning() writes into the temporary stream to preserve + # messages order. If support.environment_altered becomes true, + # warnings will be written to sys.stderr below. + print_warning.orig_stderr = stream + + _runtest_env_changed_exc(result, runtests, display_failure=False) + # Ignore output if the test passed successfully + if result.state != State.PASSED: + output = stream.getvalue() + finally: + sys.stdout = orig_stdout + sys.stderr = orig_stderr + print_warning.orig_stderr = orig_print_warnings_stderr + + if output is not None: + sys.stderr.write(output) + sys.stderr.flush() + else: + # Tell tests to be moderately quiet + support.verbose = verbose + _runtest_env_changed_exc(result, runtests, + display_failure=not verbose) + + xml_list = support.junit_xml_list + if xml_list: + import xml.etree.ElementTree as ET + result.xml_data = [ET.tostring(x).decode('us-ascii') + for x in xml_list] + finally: + if use_timeout: + faulthandler.cancel_dump_traceback_later() + support.junit_xml_list = None + + +def run_single_test(test_name: TestName, runtests: RunTests) -> TestResult: + """Run a single test. + + test_name -- the name of the test + + Returns a TestResult. + + If runtests.use_junit, xml_data is a list containing each generated + testsuite element. + """ + start_time = time.perf_counter() + result = TestResult(test_name) + pgo = runtests.pgo + try: + _runtest(result, runtests) + except: + if not pgo: + msg = traceback.format_exc() + print(f"test {test_name} crashed -- {msg}", + file=sys.stderr, flush=True) + result.state = State.UNCAUGHT_EXC + + sys.stdout.flush() + sys.stderr.flush() + + result.duration = time.perf_counter() - start_time + return result diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index fd46819fd903fe..aac8395da87845 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -1,9 +1,59 @@ +import contextlib +import faulthandler +import locale import math import os.path +import platform +import random +import shlex +import signal +import subprocess import sys import sysconfig +import tempfile import textwrap +from collections.abc import Callable + from test import support +from test.support import os_helper +from test.support import threading_helper + + +# All temporary files and temporary directories created by libregrtest should +# use TMP_PREFIX so cleanup_temp_dir() can remove them all. +TMP_PREFIX = 'test_python_' +WORK_DIR_PREFIX = TMP_PREFIX +WORKER_WORK_DIR_PREFIX = WORK_DIR_PREFIX + 'worker_' + +# bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()). +# Used to protect against threading._shutdown() hang. +# Must be smaller than buildbot "1200 seconds without output" limit. +EXIT_TIMEOUT = 120.0 + + +ALL_RESOURCES = ('audio', 'curses', 'largefile', 'network', + 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui', 'walltime') + +# Other resources excluded from --use=all: +# +# - extralagefile (ex: test_zipfile64): really too slow to be enabled +# "by default" +# - tzdata: while needed to validate fully test_datetime, it makes +# test_datetime too slow (15-20 min on some buildbots) and so is disabled by +# default (see bpo-30822). +RESOURCE_NAMES = ALL_RESOURCES + ('extralargefile', 'tzdata') + + +# Types for types hints +StrPath = str +TestName = str +StrJSON = str +TestTuple = tuple[TestName, ...] +TestList = list[TestName] +# --match and --ignore options: list of patterns +# ('*' joker character can be used) +FilterTuple = tuple[TestName, ...] +FilterDict = dict[TestName, FilterTuple] def format_duration(seconds): @@ -31,7 +81,7 @@ def format_duration(seconds): return ' '.join(parts) -def removepy(names): +def strip_py_suffix(names: list[str] | None) -> None: if not names: return for idx, name in enumerate(names): @@ -40,11 +90,20 @@ def removepy(names): names[idx] = basename +def plural(n, singular, plural=None): + if n == 1: + return singular + elif plural is not None: + return plural + else: + return singular + 's' + + def count(n, word): if n == 1: - return "%d %s" % (n, word) + return f"{n} {word}" else: - return "%d %ss" % (n, word) + return f"{n} {word}s" def printlist(x, width=70, indent=4, file=None): @@ -228,6 +287,11 @@ def get_build_info(): ldflags_nodist = sysconfig.get_config_var('PY_LDFLAGS_NODIST') or '' build = [] + + # --disable-gil + if sysconfig.get_config_var('Py_NOGIL'): + build.append("nogil") + if hasattr(sys, 'gettotalrefcount'): # --with-pydebug build.append('debug') @@ -259,16 +323,8 @@ def get_build_info(): elif '-flto' in ldflags_nodist: optimizations.append('LTO') - # --enable-optimizations - pgo_options = ( - # GCC - '-fprofile-use', - # clang: -fprofile-instr-use=code.profclangd - '-fprofile-instr-use', - # ICC - "-prof-use", - ) - if any(option in cflags_nodist for option in pgo_options): + if support.check_cflags_pgo(): + # PGO (--enable-optimizations) optimizations.append('PGO') if optimizations: build.append('+'.join(optimizations)) @@ -300,3 +356,324 @@ def get_build_info(): build.append("dtrace") return build + + +def get_temp_dir(tmp_dir: StrPath | None = None) -> StrPath: + if tmp_dir: + tmp_dir = os.path.expanduser(tmp_dir) + else: + # When tests are run from the Python build directory, it is best practice + # to keep the test files in a subfolder. This eases the cleanup of leftover + # files using the "make distclean" command. + if sysconfig.is_python_build(): + if not support.is_wasi: + tmp_dir = sysconfig.get_config_var('abs_builddir') + if tmp_dir is None: + tmp_dir = sysconfig.get_config_var('abs_srcdir') + if not tmp_dir: + # gh-74470: On Windows, only srcdir is available. Using + # abs_builddir mostly matters on UNIX when building + # Python out of the source tree, especially when the + # source tree is read only. + tmp_dir = sysconfig.get_config_var('srcdir') + tmp_dir = os.path.join(tmp_dir, 'build') + else: + # WASI platform + tmp_dir = sysconfig.get_config_var('projectbase') + tmp_dir = os.path.join(tmp_dir, 'build') + + # When get_temp_dir() is called in a worker process, + # get_temp_dir() path is different than in the parent process + # which is not a WASI process. So the parent does not create + # the same "tmp_dir" than the test worker process. + os.makedirs(tmp_dir, exist_ok=True) + else: + tmp_dir = tempfile.gettempdir() + + return os.path.abspath(tmp_dir) + + +def fix_umask(): + if support.is_emscripten: + # Emscripten has default umask 0o777, which breaks some tests. + # see https://github.com/emscripten-core/emscripten/issues/17269 + old_mask = os.umask(0) + if old_mask == 0o777: + os.umask(0o027) + else: + os.umask(old_mask) + + +def get_work_dir(parent_dir: StrPath, worker: bool = False) -> StrPath: + # Define a writable temp dir that will be used as cwd while running + # the tests. The name of the dir includes the pid to allow parallel + # testing (see the -j option). + # Emscripten and WASI have stubbed getpid(), Emscripten has only + # milisecond clock resolution. Use randint() instead. + if support.is_emscripten or support.is_wasi: + nounce = random.randint(0, 1_000_000) + else: + nounce = os.getpid() + + if worker: + work_dir = WORK_DIR_PREFIX + str(nounce) + else: + work_dir = WORKER_WORK_DIR_PREFIX + str(nounce) + work_dir += os_helper.FS_NONASCII + work_dir = os.path.join(parent_dir, work_dir) + return work_dir + + +@contextlib.contextmanager +def exit_timeout(): + try: + yield + except SystemExit as exc: + # bpo-38203: Python can hang at exit in Py_Finalize(), especially + # on threading._shutdown() call: put a timeout + if threading_helper.can_start_thread: + faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True) + sys.exit(exc.code) + + +def remove_testfn(test_name: TestName, verbose: int) -> None: + # Try to clean up os_helper.TESTFN if left behind. + # + # While tests shouldn't leave any files or directories behind, when a test + # fails that can be tedious for it to arrange. The consequences can be + # especially nasty on Windows, since if a test leaves a file open, it + # cannot be deleted by name (while there's nothing we can do about that + # here either, we can display the name of the offending test, which is a + # real help). + name = os_helper.TESTFN + if not os.path.exists(name): + return + + nuker: Callable[[str], None] + if os.path.isdir(name): + import shutil + kind, nuker = "directory", shutil.rmtree + elif os.path.isfile(name): + kind, nuker = "file", os.unlink + else: + raise RuntimeError(f"os.path says {name!r} exists but is neither " + f"directory nor file") + + if verbose: + print_warning(f"{test_name} left behind {kind} {name!r}") + support.environment_altered = True + + try: + import stat + # fix possible permissions problems that might prevent cleanup + os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + nuker(name) + except Exception as exc: + print_warning(f"{test_name} left behind {kind} {name!r} " + f"and it couldn't be removed: {exc}") + + +def abs_module_name(test_name: TestName, test_dir: StrPath | None) -> TestName: + if test_name.startswith('test.') or test_dir: + return test_name + else: + # Import it from the test package + return 'test.' + test_name + + +# gh-90681: When rerunning tests, we might need to rerun the whole +# class or module suite if some its life-cycle hooks fail. +# Test level hooks are not affected. +_TEST_LIFECYCLE_HOOKS = frozenset(( + 'setUpClass', 'tearDownClass', + 'setUpModule', 'tearDownModule', +)) + +def normalize_test_name(test_full_name, *, is_error=False): + short_name = test_full_name.split(" ")[0] + if is_error and short_name in _TEST_LIFECYCLE_HOOKS: + if test_full_name.startswith(('setUpModule (', 'tearDownModule (')): + # if setUpModule() or tearDownModule() failed, don't filter + # tests with the test file name, don't use use filters. + return None + + # This means that we have a failure in a life-cycle hook, + # we need to rerun the whole module or class suite. + # Basically the error looks like this: + # ERROR: setUpClass (test.test_reg_ex.RegTest) + # or + # ERROR: setUpModule (test.test_reg_ex) + # So, we need to parse the class / module name. + lpar = test_full_name.index('(') + rpar = test_full_name.index(')') + return test_full_name[lpar + 1: rpar].split('.')[-1] + return short_name + + +def adjust_rlimit_nofile(): + """ + On macOS the default fd limit (RLIMIT_NOFILE) is sometimes too low (256) + for our test suite to succeed. Raise it to something more reasonable. 1024 + is a common Linux default. + """ + try: + import resource + except ImportError: + return + + fd_limit, max_fds = resource.getrlimit(resource.RLIMIT_NOFILE) + + desired_fds = 1024 + + if fd_limit < desired_fds and fd_limit < max_fds: + new_fd_limit = min(desired_fds, max_fds) + try: + resource.setrlimit(resource.RLIMIT_NOFILE, + (new_fd_limit, max_fds)) + print(f"Raised RLIMIT_NOFILE: {fd_limit} -> {new_fd_limit}") + except (ValueError, OSError) as err: + print_warning(f"Unable to raise RLIMIT_NOFILE from {fd_limit} to " + f"{new_fd_limit}: {err}.") + + +def get_host_runner(): + if (hostrunner := os.environ.get("_PYTHON_HOSTRUNNER")) is None: + hostrunner = sysconfig.get_config_var("HOSTRUNNER") + return hostrunner + + +def is_cross_compiled(): + return ('_PYTHON_HOST_PLATFORM' in os.environ) + + +def format_resources(use_resources: tuple[str, ...]): + use_resources = set(use_resources) + all_resources = set(ALL_RESOURCES) + + # Express resources relative to "all" + relative_all = ['all'] + for name in sorted(all_resources - use_resources): + relative_all.append(f'-{name}') + for name in sorted(use_resources - all_resources): + relative_all.append(f'{name}') + all_text = ','.join(relative_all) + all_text = f"resources: {all_text}" + + # List of enabled resources + text = ','.join(sorted(use_resources)) + text = f"resources ({len(use_resources)}): {text}" + + # Pick the shortest string (prefer relative to all if lengths are equal) + if len(all_text) <= len(text): + return all_text + else: + return text + + +def display_header(use_resources: tuple[str, ...], + python_cmd: tuple[str, ...] | None): + # Print basic platform information + print("==", platform.python_implementation(), *sys.version.split()) + print("==", platform.platform(aliased=True), + "%s-endian" % sys.byteorder) + print("== Python build:", ' '.join(get_build_info())) + print("== cwd:", os.getcwd()) + + cpu_count = os.cpu_count() + if cpu_count: + process_cpu_count = os.process_cpu_count() + if process_cpu_count and process_cpu_count != cpu_count: + cpu_count = f"{process_cpu_count} (process) / {cpu_count} (system)" + print("== CPU count:", cpu_count) + print("== encodings: locale=%s FS=%s" + % (locale.getencoding(), sys.getfilesystemencoding())) + + if use_resources: + text = format_resources(use_resources) + print(f"== {text}") + else: + print("== resources: all test resources are disabled, " + "use -u option to unskip tests") + + cross_compile = is_cross_compiled() + if cross_compile: + print("== cross compiled: Yes") + if python_cmd: + cmd = shlex.join(python_cmd) + print(f"== host python: {cmd}") + + get_cmd = [*python_cmd, '-m', 'platform'] + proc = subprocess.run( + get_cmd, + stdout=subprocess.PIPE, + text=True, + cwd=os_helper.SAVEDCWD) + stdout = proc.stdout.replace('\n', ' ').strip() + if stdout: + print(f"== host platform: {stdout}") + elif proc.returncode: + print(f"== host platform: ") + else: + hostrunner = get_host_runner() + if hostrunner: + print(f"== host runner: {hostrunner}") + + # This makes it easier to remember what to set in your local + # environment when trying to reproduce a sanitizer failure. + asan = support.check_sanitizer(address=True) + msan = support.check_sanitizer(memory=True) + ubsan = support.check_sanitizer(ub=True) + sanitizers = [] + if asan: + sanitizers.append("address") + if msan: + sanitizers.append("memory") + if ubsan: + sanitizers.append("undefined behavior") + if sanitizers: + print(f"== sanitizers: {', '.join(sanitizers)}") + for sanitizer, env_var in ( + (asan, "ASAN_OPTIONS"), + (msan, "MSAN_OPTIONS"), + (ubsan, "UBSAN_OPTIONS"), + ): + options= os.environ.get(env_var) + if sanitizer and options is not None: + print(f"== {env_var}={options!r}") + + print(flush=True) + + +def cleanup_temp_dir(tmp_dir: StrPath): + import glob + + path = os.path.join(glob.escape(tmp_dir), TMP_PREFIX + '*') + print("Cleanup %s directory" % tmp_dir) + for name in glob.glob(path): + if os.path.isdir(name): + print("Remove directory: %s" % name) + os_helper.rmtree(name) + else: + print("Remove file: %s" % name) + os_helper.unlink(name) + +WINDOWS_STATUS = { + 0xC0000005: "STATUS_ACCESS_VIOLATION", + 0xC00000FD: "STATUS_STACK_OVERFLOW", + 0xC000013A: "STATUS_CONTROL_C_EXIT", +} + +def get_signal_name(exitcode): + if exitcode < 0: + signum = -exitcode + try: + return signal.Signals(signum).name + except ValueError: + pass + + try: + return WINDOWS_STATUS[exitcode] + except KeyError: + pass + + return None diff --git a/Lib/test/libregrtest/worker.py b/Lib/test/libregrtest/worker.py new file mode 100644 index 00000000000000..a9c8be0bb65d08 --- /dev/null +++ b/Lib/test/libregrtest/worker.py @@ -0,0 +1,116 @@ +import subprocess +import sys +import os +from typing import Any, NoReturn + +from test import support +from test.support import os_helper + +from .setup import setup_process, setup_test_dir +from .runtests import RunTests, JsonFile, JsonFileType +from .single import run_single_test +from .utils import ( + StrPath, StrJSON, FilterTuple, + get_temp_dir, get_work_dir, exit_timeout) + + +USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg")) + + +def create_worker_process(runtests: RunTests, output_fd: int, + tmp_dir: StrPath | None = None) -> subprocess.Popen: + python_cmd = runtests.python_cmd + worker_json = runtests.as_json() + + python_opts = support.args_from_interpreter_flags() + if python_cmd is not None: + executable = python_cmd + # Remove -E option, since --python=COMMAND can set PYTHON environment + # variables, such as PYTHONPATH, in the worker process. + python_opts = [opt for opt in python_opts if opt != "-E"] + else: + executable = (sys.executable,) + cmd = [*executable, *python_opts, + '-u', # Unbuffered stdout and stderr + '-m', 'test.libregrtest.worker', + worker_json] + + env = dict(os.environ) + if tmp_dir is not None: + env['TMPDIR'] = tmp_dir + env['TEMP'] = tmp_dir + env['TMP'] = tmp_dir + + # Running the child from the same working directory as regrtest's original + # invocation ensures that TEMPDIR for the child is the same when + # sysconfig.is_python_build() is true. See issue 15300. + # + # Emscripten and WASI Python must start in the Python source code directory + # to get 'python.js' or 'python.wasm' file. Then worker_process() changes + # to a temporary directory created to run tests. + work_dir = os_helper.SAVEDCWD + + kwargs: dict[str, Any] = dict( + env=env, + stdout=output_fd, + # bpo-45410: Write stderr into stdout to keep messages order + stderr=output_fd, + text=True, + close_fds=True, + cwd=work_dir, + ) + if USE_PROCESS_GROUP: + kwargs['start_new_session'] = True + + # Pass json_file to the worker process + json_file = runtests.json_file + json_file.configure_subprocess(kwargs) + + with json_file.inherit_subprocess(): + return subprocess.Popen(cmd, **kwargs) + + +def worker_process(worker_json: StrJSON) -> NoReturn: + runtests = RunTests.from_json(worker_json) + test_name = runtests.tests[0] + match_tests: FilterTuple | None = runtests.match_tests + json_file: JsonFile = runtests.json_file + + setup_test_dir(runtests.test_dir) + setup_process() + + if runtests.rerun: + if match_tests: + matching = "matching: " + ", ".join(match_tests) + print(f"Re-running {test_name} in verbose mode ({matching})", flush=True) + else: + print(f"Re-running {test_name} in verbose mode", flush=True) + + result = run_single_test(test_name, runtests) + + if json_file.file_type == JsonFileType.STDOUT: + print() + result.write_json_into(sys.stdout) + else: + with json_file.open('w', encoding='utf-8') as json_fp: + result.write_json_into(json_fp) + + sys.exit(0) + + +def main(): + if len(sys.argv) != 2: + print("usage: python -m test.libregrtest.worker JSON") + sys.exit(1) + worker_json = sys.argv[1] + + tmp_dir = get_temp_dir() + work_dir = get_work_dir(tmp_dir, worker=True) + + with exit_timeout(): + with os_helper.temp_cwd(work_dir, quiet=True): + worker_process(worker_json) + + +if __name__ == "__main__": + main() diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index fe3ee80b8d461f..d9ab21d4941cdb 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -6,7 +6,7 @@ from functools import cmp_to_key from test import seq_tests -from test.support import ALWAYS_EQ, NEVER_EQ +from test.support import ALWAYS_EQ, NEVER_EQ, Py_C_RECURSION_LIMIT class CommonTest(seq_tests.CommonTest): @@ -61,7 +61,7 @@ def test_repr(self): def test_repr_deep(self): a = self.type2test([]) - for i in range(sys.getrecursionlimit() + 100): + for i in range(Py_C_RECURSION_LIMIT + 1): a = self.type2test([a]) self.assertRaises(RecursionError, repr, a) diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index a4f52cb20ad301..024c6debcd4a54 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -19,54 +19,74 @@ "(no _at_fork_reinit method)") -def _wait(): - # A crude wait/yield function not relying on synchronization primitives. - time.sleep(0.01) +def wait_threads_blocked(nthread): + # Arbitrary sleep to wait until N threads are blocked, + # like waiting for a lock. + time.sleep(0.010 * nthread) + class Bunch(object): """ A bunch of threads. """ - def __init__(self, f, n, wait_before_exit=False): + def __init__(self, func, nthread, wait_before_exit=False): """ - Construct a bunch of `n` threads running the same function `f`. + Construct a bunch of `nthread` threads running the same function `func`. If `wait_before_exit` is True, the threads won't terminate until do_finish() is called. """ - self.f = f - self.n = n + self.func = func + self.nthread = nthread self.started = [] self.finished = [] + self.exceptions = [] self._can_exit = not wait_before_exit - self.wait_thread = threading_helper.wait_threads_exit() - self.wait_thread.__enter__() + self._wait_thread = None - def task(): - tid = threading.get_ident() - self.started.append(tid) - try: - f() - finally: - self.finished.append(tid) - while not self._can_exit: - _wait() + def task(self): + tid = threading.get_ident() + self.started.append(tid) + try: + self.func() + except BaseException as exc: + self.exceptions.append(exc) + finally: + self.finished.append(tid) + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if self._can_exit: + break + + def __enter__(self): + self._wait_thread = threading_helper.wait_threads_exit(support.SHORT_TIMEOUT) + self._wait_thread.__enter__() try: - for i in range(n): - start_new_thread(task, ()) + for _ in range(self.nthread): + start_new_thread(self.task, ()) except: self._can_exit = True raise - def wait_for_started(self): - while len(self.started) < self.n: - _wait() + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(self.started) >= self.nthread: + break + + return self + + def __exit__(self, exc_type, exc_value, traceback): + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(self.finished) >= self.nthread: + break + + # Wait until threads completely exit according to _thread._count() + self._wait_thread.__exit__(None, None, None) - def wait_for_finished(self): - while len(self.finished) < self.n: - _wait() - # Wait for threads exit - self.wait_thread.__exit__(None, None, None) + # Break reference cycle + exceptions = self.exceptions + self.exceptions = None + if exceptions: + raise ExceptionGroup(f"{self.func} threads raised exceptions", + exceptions) def do_finish(self): self._can_exit = True @@ -94,6 +114,12 @@ class BaseLockTests(BaseTestCase): Tests for both recursive and non-recursive locks. """ + def wait_phase(self, phase, expected): + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(phase) >= expected: + break + self.assertEqual(len(phase), expected) + def test_constructor(self): lock = self.locktype() del lock @@ -131,41 +157,57 @@ def test_try_acquire_contended(self): result = [] def f(): result.append(lock.acquire(False)) - Bunch(f, 1).wait_for_finished() + with Bunch(f, 1): + pass self.assertFalse(result[0]) lock.release() def test_acquire_contended(self): lock = self.locktype() lock.acquire() - N = 5 def f(): lock.acquire() lock.release() - b = Bunch(f, N) - b.wait_for_started() - _wait() - self.assertEqual(len(b.finished), 0) - lock.release() - b.wait_for_finished() - self.assertEqual(len(b.finished), N) + N = 5 + with Bunch(f, N) as bunch: + # Threads block on lock.acquire() + wait_threads_blocked(N) + self.assertEqual(len(bunch.finished), 0) + + # Threads unblocked + lock.release() + + self.assertEqual(len(bunch.finished), N) def test_with(self): lock = self.locktype() def f(): lock.acquire() lock.release() - def _with(err=None): + + def with_lock(err=None): with lock: if err is not None: raise err - _with() - # Check the lock is unacquired - Bunch(f, 1).wait_for_finished() - self.assertRaises(TypeError, _with, TypeError) - # Check the lock is unacquired - Bunch(f, 1).wait_for_finished() + + # Acquire the lock, do nothing, with releases the lock + with lock: + pass + + # Check that the lock is unacquired + with Bunch(f, 1): + pass + + # Acquire the lock, raise an exception, with releases the lock + with self.assertRaises(TypeError): + with lock: + raise TypeError + + # Check that the lock is unacquired even if after an exception + # was raised in the previous "with lock:" block + with Bunch(f, 1): + pass def test_thread_leak(self): # The lock shouldn't leak a Thread instance when used from a foreign @@ -174,17 +216,11 @@ def test_thread_leak(self): def f(): lock.acquire() lock.release() - n = len(threading.enumerate()) + # We run many threads in the hope that existing threads ids won't # be recycled. - Bunch(f, 15).wait_for_finished() - if len(threading.enumerate()) != n: - # There is a small window during which a Thread instance's - # target function has finished running, but the Thread is still - # alive and registered. Avoid spurious failures by waiting a - # bit more (seen on a buildbot). - time.sleep(0.4) - self.assertEqual(n, len(threading.enumerate())) + with Bunch(f, 15): + pass def test_timeout(self): lock = self.locktype() @@ -208,7 +244,8 @@ def f(): results.append(lock.acquire(timeout=0.5)) t2 = time.monotonic() results.append(t2 - t1) - Bunch(f, 1).wait_for_finished() + with Bunch(f, 1): + pass self.assertFalse(results[0]) self.assertTimeout(results[1], 0.5) @@ -242,15 +279,13 @@ def f(): phase.append(None) with threading_helper.wait_threads_exit(): + # Thread blocked on lock.acquire() start_new_thread(f, ()) - while len(phase) == 0: - _wait() - _wait() - self.assertEqual(len(phase), 1) + self.wait_phase(phase, 1) + + # Thread unblocked lock.release() - while len(phase) == 1: - _wait() - self.assertEqual(len(phase), 2) + self.wait_phase(phase, 2) def test_different_thread(self): # Lock can be released from a different thread. @@ -258,8 +293,8 @@ def test_different_thread(self): lock.acquire() def f(): lock.release() - b = Bunch(f, 1) - b.wait_for_finished() + with Bunch(f, 1): + pass lock.acquire() lock.release() @@ -330,17 +365,52 @@ def test_release_save_unacquired(self): lock.release() self.assertRaises(RuntimeError, lock._release_save) + def test_recursion_count(self): + lock = self.locktype() + self.assertEqual(0, lock._recursion_count()) + lock.acquire() + self.assertEqual(1, lock._recursion_count()) + lock.acquire() + lock.acquire() + self.assertEqual(3, lock._recursion_count()) + lock.release() + self.assertEqual(2, lock._recursion_count()) + lock.release() + lock.release() + self.assertEqual(0, lock._recursion_count()) + + phase = [] + + def f(): + lock.acquire() + phase.append(None) + + self.wait_phase(phase, 2) + lock.release() + phase.append(None) + + with threading_helper.wait_threads_exit(): + # Thread blocked on lock.acquire() + start_new_thread(f, ()) + self.wait_phase(phase, 1) + self.assertEqual(0, lock._recursion_count()) + + # Thread unblocked + phase.append(None) + self.wait_phase(phase, 3) + self.assertEqual(0, lock._recursion_count()) + def test_different_thread(self): # Cannot release from a different thread lock = self.locktype() def f(): lock.acquire() - b = Bunch(f, 1, True) - try: - self.assertRaises(RuntimeError, lock.release) - finally: - b.do_finish() - b.wait_for_finished() + + with Bunch(f, 1, True) as bunch: + try: + self.assertRaises(RuntimeError, lock.release) + finally: + bunch.do_finish() def test__is_owned(self): lock = self.locktype() @@ -352,7 +422,8 @@ def test__is_owned(self): result = [] def f(): result.append(lock._is_owned()) - Bunch(f, 1).wait_for_finished() + with Bunch(f, 1): + pass self.assertFalse(result[0]) lock.release() self.assertTrue(lock._is_owned()) @@ -385,12 +456,15 @@ def _check_notify(self, evt): def f(): results1.append(evt.wait()) results2.append(evt.wait()) - b = Bunch(f, N) - b.wait_for_started() - _wait() - self.assertEqual(len(results1), 0) - evt.set() - b.wait_for_finished() + + with Bunch(f, N): + # Threads blocked on first evt.wait() + wait_threads_blocked(N) + self.assertEqual(len(results1), 0) + + # Threads unblocked + evt.set() + self.assertEqual(results1, [True] * N) self.assertEqual(results2, [True] * N) @@ -413,35 +487,43 @@ def f(): r = evt.wait(0.5) t2 = time.monotonic() results2.append((r, t2 - t1)) - Bunch(f, N).wait_for_finished() + + with Bunch(f, N): + pass + self.assertEqual(results1, [False] * N) for r, dt in results2: self.assertFalse(r) self.assertTimeout(dt, 0.5) + # The event is set results1 = [] results2 = [] evt.set() - Bunch(f, N).wait_for_finished() + with Bunch(f, N): + pass + self.assertEqual(results1, [True] * N) for r, dt in results2: self.assertTrue(r) def test_set_and_clear(self): - # Issue #13502: check that wait() returns true even when the event is + # gh-57711: check that wait() returns true even when the event is # cleared before the waiting thread is woken up. - evt = self.eventtype() + event = self.eventtype() results = [] - timeout = 0.250 - N = 5 def f(): - results.append(evt.wait(timeout * 4)) - b = Bunch(f, N) - b.wait_for_started() - time.sleep(timeout) - evt.set() - evt.clear() - b.wait_for_finished() + results.append(event.wait(support.LONG_TIMEOUT)) + + N = 5 + with Bunch(f, N): + # Threads blocked on event.wait() + wait_threads_blocked(N) + + # Threads unblocked + event.set() + event.clear() + self.assertEqual(results, [True] * N) @requires_fork @@ -497,15 +579,14 @@ def _check_notify(self, cond): # Note that this test is sensitive to timing. If the worker threads # don't execute in a timely fashion, the main thread may think they # are further along then they are. The main thread therefore issues - # _wait() statements to try to make sure that it doesn't race ahead - # of the workers. + # wait_threads_blocked() statements to try to make sure that it doesn't + # race ahead of the workers. # Secondly, this test assumes that condition variables are not subject # to spurious wakeups. The absence of spurious wakeups is an implementation # detail of Condition Variables in current CPython, but in general, not # a guaranteed property of condition variables as a programming # construct. In particular, it is possible that this can no longer # be conveniently guaranteed should their implementation ever change. - N = 5 ready = [] results1 = [] results2 = [] @@ -514,58 +595,83 @@ def f(): cond.acquire() ready.append(phase_num) result = cond.wait() + cond.release() results1.append((result, phase_num)) + cond.acquire() ready.append(phase_num) + result = cond.wait() cond.release() results2.append((result, phase_num)) - b = Bunch(f, N) - b.wait_for_started() - # first wait, to ensure all workers settle into cond.wait() before - # we continue. See issues #8799 and #30727. - while len(ready) < 5: - _wait() - ready.clear() - self.assertEqual(results1, []) - # Notify 3 threads at first - cond.acquire() - cond.notify(3) - _wait() - phase_num = 1 - cond.release() - while len(results1) < 3: - _wait() - self.assertEqual(results1, [(True, 1)] * 3) - self.assertEqual(results2, []) - # make sure all awaken workers settle into cond.wait() - while len(ready) < 3: - _wait() - # Notify 5 threads: they might be in their first or second wait - cond.acquire() - cond.notify(5) - _wait() - phase_num = 2 - cond.release() - while len(results1) + len(results2) < 8: - _wait() - self.assertEqual(results1, [(True, 1)] * 3 + [(True, 2)] * 2) - self.assertEqual(results2, [(True, 2)] * 3) - # make sure all workers settle into cond.wait() - while len(ready) < 5: - _wait() - # Notify all threads: they are all in their second wait - cond.acquire() - cond.notify_all() - _wait() - phase_num = 3 - cond.release() - while len(results2) < 5: - _wait() - self.assertEqual(results1, [(True, 1)] * 3 + [(True,2)] * 2) - self.assertEqual(results2, [(True, 2)] * 3 + [(True, 3)] * 2) - b.wait_for_finished() + + N = 5 + with Bunch(f, N): + # first wait, to ensure all workers settle into cond.wait() before + # we continue. See issues #8799 and #30727. + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(ready) >= N: + break + + ready.clear() + self.assertEqual(results1, []) + + # Notify 3 threads at first + count1 = 3 + cond.acquire() + cond.notify(count1) + wait_threads_blocked(count1) + + # Phase 1 + phase_num = 1 + cond.release() + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(results1) >= count1: + break + + self.assertEqual(results1, [(True, 1)] * count1) + self.assertEqual(results2, []) + + # Wait until awaken workers are blocked on cond.wait() + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(ready) >= count1 : + break + + # Notify 5 threads: they might be in their first or second wait + cond.acquire() + cond.notify(5) + wait_threads_blocked(N) + + # Phase 2 + phase_num = 2 + cond.release() + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(results1) + len(results2) >= (N + count1): + break + + count2 = N - count1 + self.assertEqual(results1, [(True, 1)] * count1 + [(True, 2)] * count2) + self.assertEqual(results2, [(True, 2)] * count1) + + # Make sure all workers settle into cond.wait() + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(ready) >= N: + break + + # Notify all threads: they are all in their second wait + cond.acquire() + cond.notify_all() + wait_threads_blocked(N) + + # Phase 3 + phase_num = 3 + cond.release() + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(results2) >= N: + break + self.assertEqual(results1, [(True, 1)] * count1 + [(True, 2)] * count2) + self.assertEqual(results2, [(True, 2)] * count1 + [(True, 3)] * count2) def test_notify(self): cond = self.condtype() @@ -575,19 +681,23 @@ def test_notify(self): def test_timeout(self): cond = self.condtype() + timeout = 0.5 results = [] - N = 5 def f(): cond.acquire() t1 = time.monotonic() - result = cond.wait(0.5) + result = cond.wait(timeout) t2 = time.monotonic() cond.release() results.append((t2 - t1, result)) - Bunch(f, N).wait_for_finished() + + N = 5 + with Bunch(f, N): + pass self.assertEqual(len(results), N) + for dt, result in results: - self.assertTimeout(dt, 0.5) + self.assertTimeout(dt, timeout) # Note that conceptually (that"s the condition variable protocol) # a wait() may succeed even if no one notifies us and before any # timeout occurs. Spurious wakeups can occur. @@ -600,17 +710,16 @@ def test_waitfor(self): state = 0 def f(): with cond: - result = cond.wait_for(lambda : state==4) + result = cond.wait_for(lambda: state == 4) self.assertTrue(result) self.assertEqual(state, 4) - b = Bunch(f, 1) - b.wait_for_started() - for i in range(4): - time.sleep(0.01) - with cond: - state += 1 - cond.notify() - b.wait_for_finished() + + with Bunch(f, 1): + for i in range(4): + time.sleep(0.010) + with cond: + state += 1 + cond.notify() def test_waitfor_timeout(self): cond = self.condtype() @@ -624,15 +733,15 @@ def f(): self.assertFalse(result) self.assertTimeout(dt, 0.1) success.append(None) - b = Bunch(f, 1) - b.wait_for_started() - # Only increment 3 times, so state == 4 is never reached. - for i in range(3): - time.sleep(0.01) - with cond: - state += 1 - cond.notify() - b.wait_for_finished() + + with Bunch(f, 1): + # Only increment 3 times, so state == 4 is never reached. + for i in range(3): + time.sleep(0.010) + with cond: + state += 1 + cond.notify() + self.assertEqual(len(success), 1) @@ -661,73 +770,107 @@ def test_acquire_destroy(self): del sem def test_acquire_contended(self): - sem = self.semtype(7) + sem_value = 7 + sem = self.semtype(sem_value) sem.acquire() - N = 10 + sem_results = [] results1 = [] results2 = [] phase_num = 0 - def f(): + + def func(): sem_results.append(sem.acquire()) results1.append(phase_num) + sem_results.append(sem.acquire()) results2.append(phase_num) - b = Bunch(f, 10) - b.wait_for_started() - while len(results1) + len(results2) < 6: - _wait() - self.assertEqual(results1 + results2, [0] * 6) - phase_num = 1 - for i in range(7): - sem.release() - while len(results1) + len(results2) < 13: - _wait() - self.assertEqual(sorted(results1 + results2), [0] * 6 + [1] * 7) - phase_num = 2 - for i in range(6): + + def wait_count(count): + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(results1) + len(results2) >= count: + break + + N = 10 + with Bunch(func, N): + # Phase 0 + count1 = sem_value - 1 + wait_count(count1) + self.assertEqual(results1 + results2, [0] * count1) + + # Phase 1 + phase_num = 1 + for i in range(sem_value): + sem.release() + count2 = sem_value + wait_count(count1 + count2) + self.assertEqual(sorted(results1 + results2), + [0] * count1 + [1] * count2) + + # Phase 2 + phase_num = 2 + count3 = (sem_value - 1) + for i in range(count3): + sem.release() + wait_count(count1 + count2 + count3) + self.assertEqual(sorted(results1 + results2), + [0] * count1 + [1] * count2 + [2] * count3) + # The semaphore is still locked + self.assertFalse(sem.acquire(False)) + + # Final release, to let the last thread finish + count4 = 1 sem.release() - while len(results1) + len(results2) < 19: - _wait() - self.assertEqual(sorted(results1 + results2), [0] * 6 + [1] * 7 + [2] * 6) - # The semaphore is still locked - self.assertFalse(sem.acquire(False)) - # Final release, to let the last thread finish - sem.release() - b.wait_for_finished() - self.assertEqual(sem_results, [True] * (6 + 7 + 6 + 1)) + + self.assertEqual(sem_results, + [True] * (count1 + count2 + count3 + count4)) def test_multirelease(self): - sem = self.semtype(7) + sem_value = 7 + sem = self.semtype(sem_value) sem.acquire() + results1 = [] results2 = [] phase_num = 0 - def f(): + def func(): sem.acquire() results1.append(phase_num) + sem.acquire() results2.append(phase_num) - b = Bunch(f, 10) - b.wait_for_started() - while len(results1) + len(results2) < 6: - _wait() - self.assertEqual(results1 + results2, [0] * 6) - phase_num = 1 - sem.release(7) - while len(results1) + len(results2) < 13: - _wait() - self.assertEqual(sorted(results1 + results2), [0] * 6 + [1] * 7) - phase_num = 2 - sem.release(6) - while len(results1) + len(results2) < 19: - _wait() - self.assertEqual(sorted(results1 + results2), [0] * 6 + [1] * 7 + [2] * 6) - # The semaphore is still locked - self.assertFalse(sem.acquire(False)) - # Final release, to let the last thread finish - sem.release() - b.wait_for_finished() + + def wait_count(count): + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(results1) + len(results2) >= count: + break + + with Bunch(func, 10): + # Phase 0 + count1 = sem_value - 1 + wait_count(count1) + self.assertEqual(results1 + results2, [0] * count1) + + # Phase 1 + phase_num = 1 + count2 = sem_value + sem.release(count2) + wait_count(count1 + count2) + self.assertEqual(sorted(results1 + results2), + [0] * count1 + [1] * count2) + + # Phase 2 + phase_num = 2 + count3 = sem_value - 1 + sem.release(count3) + wait_count(count1 + count2 + count3) + self.assertEqual(sorted(results1 + results2), + [0] * count1 + [1] * count2 + [2] * count3) + # The semaphore is still locked + self.assertFalse(sem.acquire(False)) + + # Final release, to let the last thread finish + sem.release() def test_try_acquire(self): sem = self.semtype(2) @@ -744,7 +887,8 @@ def test_try_acquire_contended(self): def f(): results.append(sem.acquire(False)) results.append(sem.acquire(False)) - Bunch(f, 5).wait_for_finished() + with Bunch(f, 5): + pass # There can be a thread switch between acquiring the semaphore and # appending the result, therefore results will not necessarily be # ordered. @@ -770,12 +914,14 @@ def test_default_value(self): def f(): sem.acquire() sem.release() - b = Bunch(f, 1) - b.wait_for_started() - _wait() - self.assertFalse(b.finished) - sem.release() - b.wait_for_finished() + + with Bunch(f, 1) as bunch: + # Thread blocked on sem.acquire() + wait_threads_blocked(1) + self.assertFalse(bunch.finished) + + # Thread unblocked + sem.release() def test_with(self): sem = self.semtype(2) @@ -846,13 +992,13 @@ class BarrierTests(BaseTestCase): def setUp(self): self.barrier = self.barriertype(self.N, timeout=self.defaultTimeout) + def tearDown(self): self.barrier.abort() def run_threads(self, f): - b = Bunch(f, self.N-1) - f() - b.wait_for_finished() + with Bunch(f, self.N): + pass def multipass(self, results, n): m = self.barrier.parties @@ -943,8 +1089,9 @@ def f(): i = self.barrier.wait() if i == self.N//2: # Wait until the other threads are all in the barrier. - while self.barrier.n_waiting < self.N-1: - time.sleep(0.001) + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if self.barrier.n_waiting >= (self.N - 1): + break self.barrier.reset() else: try: @@ -1004,25 +1151,27 @@ def f(): i = self.barrier.wait() if i == self.N // 2: # One thread is late! - time.sleep(1.0) + time.sleep(self.defaultTimeout / 2) # Default timeout is 2.0, so this is shorter. self.assertRaises(threading.BrokenBarrierError, - self.barrier.wait, 0.5) + self.barrier.wait, self.defaultTimeout / 4) self.run_threads(f) def test_default_timeout(self): """ Test the barrier's default timeout """ - # create a barrier with a low default timeout - barrier = self.barriertype(self.N, timeout=0.3) + timeout = 0.100 + barrier = self.barriertype(2, timeout=timeout) def f(): - i = barrier.wait() - if i == self.N // 2: - # One thread is later than the default timeout of 0.3s. - time.sleep(1.0) - self.assertRaises(threading.BrokenBarrierError, barrier.wait) - self.run_threads(f) + self.assertRaises(threading.BrokenBarrierError, + barrier.wait) + + start_time = time.monotonic() + with Bunch(f, 1): + pass + dt = time.monotonic() - start_time + self.assertGreaterEqual(dt, timeout) def test_single_thread(self): b = self.barriertype(1) @@ -1030,16 +1179,28 @@ def test_single_thread(self): b.wait() def test_repr(self): - b = self.barriertype(3) - self.assertRegex(repr(b), r"<\w+\.Barrier at .*: waiters=0/3>") + barrier = self.barriertype(3) + timeout = support.LONG_TIMEOUT + self.assertRegex(repr(barrier), r"<\w+\.Barrier at .*: waiters=0/3>") def f(): - b.wait(3) - bunch = Bunch(f, 2) - bunch.wait_for_started() - time.sleep(0.2) - self.assertRegex(repr(b), r"<\w+\.Barrier at .*: waiters=2/3>") - b.wait(3) - bunch.wait_for_finished() - self.assertRegex(repr(b), r"<\w+\.Barrier at .*: waiters=0/3>") - b.abort() - self.assertRegex(repr(b), r"<\w+\.Barrier at .*: broken>") + barrier.wait(timeout) + + N = 2 + with Bunch(f, N): + # Threads blocked on barrier.wait() + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if barrier.n_waiting >= N: + break + self.assertRegex(repr(barrier), + r"<\w+\.Barrier at .*: waiters=2/3>") + + # Threads unblocked + barrier.wait(timeout) + + self.assertRegex(repr(barrier), + r"<\w+\.Barrier at .*: waiters=0/3>") + + # Abort the barrier + barrier.abort() + self.assertRegex(repr(barrier), + r"<\w+\.Barrier at .*: broken>") diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 613206a0855aea..b4cfce19a7174e 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -1,7 +1,7 @@ # tests common to dict and UserDict import unittest import collections -import sys +from test.support import Py_C_RECURSION_LIMIT class BasicTestMappingProtocol(unittest.TestCase): @@ -624,7 +624,7 @@ def __repr__(self): def test_repr_deep(self): d = self._empty_mapping() - for i in range(sys.getrecursionlimit() + 100): + for i in range(Py_C_RECURSION_LIMIT + 1): d0 = d d = self._empty_mapping() d[1] = d0 diff --git a/Lib/test/cmath_testcases.txt b/Lib/test/mathdata/cmath_testcases.txt similarity index 100% rename from Lib/test/cmath_testcases.txt rename to Lib/test/mathdata/cmath_testcases.txt diff --git a/Lib/test/floating_points.txt b/Lib/test/mathdata/floating_points.txt similarity index 100% rename from Lib/test/floating_points.txt rename to Lib/test/mathdata/floating_points.txt diff --git a/Lib/test/formatfloat_testcases.txt b/Lib/test/mathdata/formatfloat_testcases.txt similarity index 100% rename from Lib/test/formatfloat_testcases.txt rename to Lib/test/mathdata/formatfloat_testcases.txt diff --git a/Lib/test/ieee754.txt b/Lib/test/mathdata/ieee754.txt similarity index 100% rename from Lib/test/ieee754.txt rename to Lib/test/mathdata/ieee754.txt diff --git a/Lib/test/math_testcases.txt b/Lib/test/mathdata/math_testcases.txt similarity index 100% rename from Lib/test/math_testcases.txt rename to Lib/test/mathdata/math_testcases.txt diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 6e87370c2065ba..ddb180ef5ef825 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2408,6 +2408,22 @@ def test_reduce_calls_base(self): y = self.loads(s) self.assertEqual(y._reduce_called, 1) + def test_reduce_ex_None(self): + c = REX_None() + with self.assertRaises(TypeError): + self.dumps(c) + + def test_reduce_None(self): + c = R_None() + with self.assertRaises(TypeError): + self.dumps(c) + + def test_pickle_setstate_None(self): + c = C_None_setstate() + p = self.dumps(c) + with self.assertRaises(TypeError): + self.loads(p) + @no_tracing def test_bad_getattr(self): # Issue #3514: crash when there is an infinite loop in __getattr__ @@ -2576,6 +2592,7 @@ def check_frame_opcodes(self, pickled): self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_framing_many_objects(self): obj = list(range(10**5)) for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): @@ -3348,6 +3365,21 @@ def __setstate__(self, state): def __reduce__(self): return type(self), (), self.state +class REX_None: + """ Setting __reduce_ex__ to None should fail """ + __reduce_ex__ = None + +class R_None: + """ Setting __reduce__ to None should fail """ + __reduce__ = None + +class C_None_setstate: + """ Setting __setstate__ to None should fail """ + def __getstate__(self): + return 1 + + __setstate__ = None + # Test classes for newobj @@ -3751,6 +3783,25 @@ def test_unpickling_buffering_readline(self): unpickler = self.unpickler_class(f) self.assertEqual(unpickler.load(), data) + def test_pickle_invalid_reducer_override(self): + # gh-103035 + obj = object() + + f = io.BytesIO() + class MyPickler(self.pickler_class): + pass + pickler = MyPickler(f) + pickler.dump(obj) + + pickler.clear_memo() + pickler.reducer_override = None + with self.assertRaises(TypeError): + pickler.dump(obj) + + pickler.clear_memo() + pickler.reducer_override = 10 + with self.assertRaises(TypeError): + pickler.dump(obj) # Tests for dispatch_table attribute @@ -3913,6 +3964,15 @@ def dumps(obj, protocol=None): self._test_dispatch_table(dumps, dt) + def test_dispatch_table_None_item(self): + # gh-93627 + obj = object() + f = io.BytesIO() + pickler = self.pickler_class(f) + pickler.dispatch_table = {type(obj): None} + with self.assertRaises(TypeError): + pickler.dump(obj) + def _test_dispatch_table(self, dumps, dispatch_table): def custom_load_dump(obj): return pickle.loads(dumps(obj, 0)) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index b84c14400d42f0..4f3ebb12ed957d 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -1,18 +1,13 @@ """ Collect various information about Python to help debugging test failures. """ -from __future__ import print_function import errno import re import sys import traceback -import unittest import warnings -MS_WINDOWS = (sys.platform == 'win32') - - def normalize_text(text): if text is None: return None @@ -112,6 +107,7 @@ def collect_sys(info_add): call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel') call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion') + call_func(info_add, 'sys.getrecursionlimit', sys, 'getrecursionlimit') encoding = sys.getfilesystemencoding() if hasattr(sys, 'getfilesystemencodeerrors'): @@ -163,6 +159,26 @@ def collect_platform(info_add): if libc_ver: info_add('platform.libc_ver', libc_ver) + try: + os_release = platform.freedesktop_os_release() + except OSError: + pass + else: + for key in ( + 'ID', + 'NAME', + 'PRETTY_NAME' + 'VARIANT', + 'VARIANT_ID', + 'VERSION', + 'VERSION_CODENAME', + 'VERSION_ID', + ): + if key not in os_release: + continue + info_add(f'platform.freedesktop_os_release[{key}]', + os_release[key]) + def collect_locale(info_add): import locale @@ -223,6 +239,7 @@ def format_attr(attr, value): 'getresgid', 'getresuid', 'getuid', + 'process_cpu_count', 'uname', ): call_func(info_add, 'os.%s' % func, os, func) @@ -252,6 +269,7 @@ def format_groups(groups): "ARCHFLAGS", "ARFLAGS", "AUDIODEV", + "BUILDPYTHON", "CC", "CFLAGS", "COLUMNS", @@ -304,15 +322,24 @@ def format_groups(groups): "VIRTUAL_ENV", "WAYLAND_DISPLAY", "WINDIR", + "_PYTHON_HOSTRUNNER", "_PYTHON_HOST_PLATFORM", "_PYTHON_PROJECT_BASE", "_PYTHON_SYSCONFIGDATA_NAME", "__PYVENV_LAUNCHER__", + + # Sanitizer options + "ASAN_OPTIONS", + "LSAN_OPTIONS", + "MSAN_OPTIONS", + "TSAN_OPTIONS", + "UBSAN_OPTIONS", )) for name, value in os.environ.items(): uname = name.upper() if (uname in ENV_VARS - # Copy PYTHON* and LC_* variables + # Copy PYTHON* variables like PYTHONPATH + # Copy LC_* variables like LC_ALL or uname.startswith(("PYTHON", "LC_")) # Visual Studio: VS140COMNTOOLS or (uname.startswith("VS") and uname.endswith("COMNTOOLS"))): @@ -465,13 +492,10 @@ def collect_datetime(info_add): def collect_sysconfig(info_add): - # On Windows, sysconfig is not reliable to get macros used - # to build Python - if MS_WINDOWS: - return - import sysconfig + info_add('sysconfig.is_python_build', sysconfig.is_python_build()) + for name in ( 'ABIFLAGS', 'ANDROID_API_LEVEL', @@ -480,6 +504,7 @@ def collect_sysconfig(info_add): 'CFLAGS', 'CFLAGSFORSHARED', 'CONFIG_ARGS', + 'HOSTRUNNER', 'HOST_GNU_TYPE', 'MACHDEP', 'MULTIARCH', @@ -492,9 +517,13 @@ def collect_sysconfig(info_add): 'PY_STDMODULE_CFLAGS', 'Py_DEBUG', 'Py_ENABLE_SHARED', + 'Py_NOGIL', 'SHELL', 'SOABI', + 'abs_builddir', + 'abs_srcdir', 'prefix', + 'srcdir', ): value = sysconfig.get_config_var(name) if name == 'ANDROID_API_LEVEL' and not value: @@ -641,7 +670,29 @@ def collect_testcapi(info_add): except ImportError: return - call_func(info_add, 'pymem.allocator', _testcapi, 'pymem_getallocatorsname') + for name in ( + 'LONG_MAX', # always 32-bit on Windows, 64-bit on 64-bit Unix + 'PY_SSIZE_T_MAX', + 'Py_C_RECURSION_LIMIT', + 'SIZEOF_TIME_T', # 32-bit or 64-bit depending on the platform + 'SIZEOF_WCHAR_T', # 16-bit or 32-bit depending on the platform + ): + copy_attr(info_add, f'_testcapi.{name}', _testcapi, name) + + +def collect_testinternalcapi(info_add): + try: + import _testinternalcapi + except ImportError: + return + + call_func(info_add, 'pymem.allocator', _testinternalcapi, 'pymem_getallocatorsname') + + for name in ( + 'SIZEOF_PYGC_HEAD', + 'SIZEOF_PYOBJECT', + ): + copy_attr(info_add, f'_testinternalcapi.{name}', _testinternalcapi, name) def collect_resource(info_add): @@ -660,6 +711,7 @@ def collect_resource(info_add): def collect_test_socket(info_add): + import unittest try: from test import test_socket except (ImportError, unittest.SkipTest): @@ -671,26 +723,83 @@ def collect_test_socket(info_add): copy_attributes(info_add, test_socket, 'test_socket.%s', attributes) -def collect_test_support(info_add): +def collect_support(info_add): try: from test import support except ImportError: return - attributes = ('IPV6_ENABLED',) - copy_attributes(info_add, support, 'test_support.%s', attributes) + attributes = ( + 'MS_WINDOWS', + 'has_fork_support', + 'has_socket_support', + 'has_strftime_extensions', + 'has_subprocess_support', + 'is_android', + 'is_emscripten', + 'is_jython', + 'is_wasi', + ) + copy_attributes(info_add, support, 'support.%s', attributes) - call_func(info_add, 'test_support._is_gui_available', support, '_is_gui_available') - call_func(info_add, 'test_support.python_is_optimized', support, 'python_is_optimized') + call_func(info_add, 'support._is_gui_available', support, '_is_gui_available') + call_func(info_add, 'support.python_is_optimized', support, 'python_is_optimized') - info_add('test_support.check_sanitizer(address=True)', + info_add('support.check_sanitizer(address=True)', support.check_sanitizer(address=True)) - info_add('test_support.check_sanitizer(memory=True)', + info_add('support.check_sanitizer(memory=True)', support.check_sanitizer(memory=True)) - info_add('test_support.check_sanitizer(ub=True)', + info_add('support.check_sanitizer(ub=True)', support.check_sanitizer(ub=True)) +def collect_support_os_helper(info_add): + try: + from test.support import os_helper + except ImportError: + return + + for name in ( + 'can_symlink', + 'can_xattr', + 'can_chmod', + 'can_dac_override', + ): + func = getattr(os_helper, name) + info_add(f'support_os_helper.{name}', func()) + + +def collect_support_socket_helper(info_add): + try: + from test.support import socket_helper + except ImportError: + return + + attributes = ( + 'IPV6_ENABLED', + 'has_gethostname', + ) + copy_attributes(info_add, socket_helper, 'support_socket_helper.%s', attributes) + + for name in ( + 'tcp_blackhole', + ): + func = getattr(socket_helper, name) + info_add(f'support_socket_helper.{name}', func()) + + +def collect_support_threading_helper(info_add): + try: + from test.support import threading_helper + except ImportError: + return + + attributes = ( + 'can_start_thread', + ) + copy_attributes(info_add, threading_helper, 'support_threading_helper.%s', attributes) + + def collect_cc(info_add): import subprocess import sysconfig @@ -845,6 +954,21 @@ def collect_fips(info_add): pass +def collect_tempfile(info_add): + import tempfile + + info_add('tempfile.gettempdir', tempfile.gettempdir()) + + +def collect_libregrtest_utils(info_add): + try: + from test.libregrtest import utils + except ImportError: + return + + info_add('libregrtests.build_info', ' '.join(utils.get_build_info())) + + def collect_info(info): error = False info_add = info.add @@ -878,14 +1002,20 @@ def collect_info(info): collect_sys, collect_sysconfig, collect_testcapi, + collect_testinternalcapi, + collect_tempfile, collect_time, collect_tkinter, collect_windows, collect_zlib, + collect_libregrtest_utils, # Collecting from tests should be last as they have side effects. collect_test_socket, - collect_test_support, + collect_support, + collect_support_os_helper, + collect_support_socket_helper, + collect_support_threading_helper, ): try: collect_func(info_add) @@ -911,7 +1041,6 @@ def dump_info(info, file=None): for key, value in infos: value = value.replace("\n", " ") print("%s: %s" % (key, value)) - print() def main(): @@ -920,6 +1049,7 @@ def main(): dump_info(info) if error: + print() print("Collection failed: exit with error", file=sys.stderr) sys.exit(1) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 0ffb3ed454eda0..46a74fe276f553 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -8,7 +8,7 @@ import os import sys -from test.libregrtest import main +from test.libregrtest.main import main # Alias for backward compatibility (just in case) diff --git a/Lib/test/sgml_input.html b/Lib/test/sgml_input.html deleted file mode 100644 index f4d2e6cc805e6a..00000000000000 --- a/Lib/test/sgml_input.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - -
- - - - - -
-
- - - - - -
- - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
  MetalCristalDeuterioEnergía  
160.6363.40639.230-80/3.965
-
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Flotas (max. 9)
Num.MisiónCantidadComienzoSalidaObjetivoLlegadaOrden
1 - Espionaje - (F) - 3[2:250:6]Wed Aug 9 18:00:02[2:242:5]Wed Aug 9 18:01:02 -
- - -
-
2 - Espionaje - (V) - 3[2:250:6]Wed Aug 9 17:59:55[2:242:1]Wed Aug 9 18:01:55 -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nueva misión: elegir naves
NavesDisponibles--
Nave pequeña de carga10máx
Nave grande de carga19máx
Crucero6máx
Reciclador1máx
Sonda de espionaje139máx
Ninguna naveTodas las naves
- -

-
- - diff --git a/Lib/test/signalinterproctester.py b/Lib/test/signalinterproctester.py index cdcd92a8baace6..073c078f45f6d7 100644 --- a/Lib/test/signalinterproctester.py +++ b/Lib/test/signalinterproctester.py @@ -1,3 +1,4 @@ +import gc import os import signal import subprocess @@ -59,6 +60,13 @@ def test_interprocess_signal(self): self.assertEqual(self.got_signals, {'SIGHUP': 1, 'SIGUSR1': 0, 'SIGALRM': 0}) + # gh-110033: Make sure that the subprocess.Popen is deleted before + # the next test which raises an exception. Otherwise, the exception + # may be raised when Popen.__del__() is executed and so be logged + # as "Exception ignored in: ". + child = None + gc.collect() + with self.assertRaises(SIGUSR1Exception): with self.subprocess_send_signal(pid, "SIGUSR1") as child: self.wait_signal(child, 'SIGUSR1') diff --git a/Lib/test/ssl_servers.py b/Lib/test/ssl_servers.py index a4bd7455d47e76..15b071e04dda1f 100644 --- a/Lib/test/ssl_servers.py +++ b/Lib/test/ssl_servers.py @@ -14,7 +14,7 @@ here = os.path.dirname(__file__) HOST = socket_helper.HOST -CERTFILE = os.path.join(here, 'keycert.pem') +CERTFILE = os.path.join(here, 'certdata', 'keycert.pem') # This one's based on HTTPServer, which is based on socketserver diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 8d210b198d248d..cecf309dca9194 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -327,11 +327,12 @@ def reference_find(p, s): for i in range(len(s)): if s.startswith(p, i): return i + if p == '' and s == '': + return 0 return -1 - rr = random.randrange - choices = random.choices - for _ in range(1000): + def check_pattern(rr): + choices = random.choices p0 = ''.join(choices('abcde', k=rr(10))) * rr(10, 20) p = p0[:len(p0) - rr(10)] # pop off some characters left = ''.join(choices('abcdef', k=rr(2000))) @@ -341,6 +342,13 @@ def reference_find(p, s): self.checkequal(reference_find(p, text), text, 'find', p) + rr = random.randrange + for _ in range(1000): + check_pattern(rr) + + # Test that empty string always work: + check_pattern(lambda *args: 0) + def test_find_many_lengths(self): haystack_repeats = [a * 10**e for e in range(6) for a in (1,2,5)] haystacks = [(n, self.fixtype("abcab"*n + "da")) for n in haystack_repeats] diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 3b332f49951f0c..21e8770ab31180 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -4,9 +4,10 @@ raise ImportError('support must be imported from the test package') import contextlib +import dataclasses import functools import getpass -import opcode +import _opcode import os import re import stat @@ -21,11 +22,6 @@ from .testresult import get_test_runner -try: - from _testcapi import unicode_legacy_string -except ImportError: - unicode_legacy_string = None - __all__ = [ # globals "PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast", @@ -50,7 +46,7 @@ "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", "requires_limited_api", "requires_specialization", # sys - "is_jython", "is_android", "is_emscripten", "is_wasi", + "MS_WINDOWS", "is_jython", "is_android", "is_emscripten", "is_wasi", "check_impl_detail", "unix_shell", "setswitchinterval", # os "get_pagesize", @@ -64,7 +60,9 @@ "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", - "Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", + "Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", "Py_C_RECURSION_LIMIT", + "skip_on_s390x", + "without_optimizer", ] @@ -77,13 +75,7 @@ # # The timeout should be long enough for connect(), recv() and send() methods # of socket.socket. -LOOPBACK_TIMEOUT = 5.0 -if sys.platform == 'win32' and ' 32 bit (ARM)' in sys.version: - # bpo-37553: test_socket.SendfileUsingSendTest is taking longer than 2 - # seconds on Windows ARM32 buildbot - LOOPBACK_TIMEOUT = 10 -elif sys.platform == 'vxworks': - LOOPBACK_TIMEOUT = 10 +LOOPBACK_TIMEOUT = 10.0 # Timeout in seconds for network requests going to the internet. The timeout is # short enough to prevent a test to wait for too long if the internet request @@ -122,17 +114,20 @@ class Error(Exception): class TestFailed(Error): """Test failed.""" + def __init__(self, msg, *args, stats=None): + self.msg = msg + self.stats = stats + super().__init__(msg, *args) + + def __str__(self): + return self.msg class TestFailedWithDetails(TestFailed): """Test failed.""" - def __init__(self, msg, errors, failures): - self.msg = msg + def __init__(self, msg, errors, failures, stats): self.errors = errors self.failures = failures - super().__init__(msg, errors, failures) - - def __str__(self): - return self.msg + super().__init__(msg, errors, failures, stats=stats) class TestDidNotRun(Error): """Test did not run any subtests.""" @@ -406,19 +401,19 @@ def check_sanitizer(*, address=False, memory=False, ub=False): raise ValueError('At least one of address, memory, or ub must be True') - _cflags = sysconfig.get_config_var('CFLAGS') or '' - _config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + cflags = sysconfig.get_config_var('CFLAGS') or '' + config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' memory_sanitizer = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args + '-fsanitize=memory' in cflags or + '--with-memory-sanitizer' in config_args ) address_sanitizer = ( - '-fsanitize=address' in _cflags or - '--with-address-sanitizer' in _config_args + '-fsanitize=address' in cflags or + '--with-address-sanitizer' in config_args ) ub_sanitizer = ( - '-fsanitize=undefined' in _cflags or - '--with-undefined-behavior-sanitizer' in _config_args + '-fsanitize=undefined' in cflags or + '--with-undefined-behavior-sanitizer' in config_args ) return ( (memory and memory_sanitizer) or @@ -434,6 +429,18 @@ def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False): skip = check_sanitizer(address=address, memory=memory, ub=ub) return unittest.skipIf(skip, reason) +# gh-89363: True if fork() can hang if Python is built with Address Sanitizer +# (ASAN): libasan race condition, dead lock in pthread_create(). +HAVE_ASAN_FORK_BUG = check_sanitizer(address=True) + + +def set_sanitizer_env_var(env, option): + for name in ('ASAN_OPTIONS', 'MSAN_OPTIONS', 'UBSAN_OPTIONS'): + if name in env: + env[name] += f':{option}' + else: + env[name] = option + def system_must_validate_cert(f): """Skip the test on TLS certificate validation failures.""" @@ -506,8 +513,7 @@ def has_no_debug_ranges(): def requires_debug_ranges(reason='requires co_positions / debug_ranges'): return unittest.skipIf(has_no_debug_ranges(), reason) -requires_legacy_unicode_capi = unittest.skipUnless(unicode_legacy_string, - 'requires legacy Unicode C API') +MS_WINDOWS = (sys.platform == 'win32') # Is not actually used in tests, but is kept for compatibility. is_jython = sys.platform.startswith('java') @@ -775,11 +781,26 @@ def python_is_optimized(): return final_opt not in ('', '-O0', '-Og') +def check_cflags_pgo(): + # Check if Python was built with ./configure --enable-optimizations: + # with Profile Guided Optimization (PGO). + cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') or '' + pgo_options = [ + # GCC + '-fprofile-use', + # clang: -fprofile-instr-use=code.profclangd + '-fprofile-instr-use', + # ICC + "-prof-use", + ] + PGO_PROF_USE_FLAG = sysconfig.get_config_var('PGO_PROF_USE_FLAG') + if PGO_PROF_USE_FLAG: + pgo_options.append(PGO_PROF_USE_FLAG) + return any(option in cflags_nodist for option in pgo_options) + + _header = 'nP' _align = '0n' -if hasattr(sys, "getobjects"): - _header = '2P' + _header - _align = '0P' _vheader = _header + 'n' def calcobjsize(fmt): @@ -884,27 +905,31 @@ def inner(*args, **kwds): MAX_Py_ssize_t = sys.maxsize -def set_memlimit(limit): - global max_memuse - global real_max_memuse +def _parse_memlimit(limit: str) -> int: sizes = { 'k': 1024, 'm': _1M, 'g': _1G, 't': 1024*_1G, } - m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit, + m = re.match(r'(\d+(?:\.\d+)?) (K|M|G|T)b?$', limit, re.IGNORECASE | re.VERBOSE) if m is None: - raise ValueError('Invalid memory limit %r' % (limit,)) - memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()]) - real_max_memuse = memlimit - if memlimit > MAX_Py_ssize_t: - memlimit = MAX_Py_ssize_t + raise ValueError(f'Invalid memory limit: {limit!r}') + return int(float(m.group(1)) * sizes[m.group(2).lower()]) + +def set_memlimit(limit: str) -> None: + global max_memuse + global real_max_memuse + memlimit = _parse_memlimit(limit) if memlimit < _2G - 1: - raise ValueError('Memory limit %r too low to be useful' % (limit,)) + raise ValueError('Memory limit {limit!r} too low to be useful') + + real_max_memuse = memlimit + memlimit = min(memlimit, MAX_Py_ssize_t) max_memuse = memlimit + class _MemoryWatchdog: """An object which periodically watches the process' memory consumption and prints it out. @@ -1087,12 +1112,11 @@ def requires_limited_api(test): import _testcapi except ImportError: return unittest.skip('needs _testcapi module')(test) - return unittest.skipUnless( - _testcapi.LIMITED_API_AVAILABLE, 'needs Limited API support')(test) + return test def requires_specialization(test): return unittest.skipUnless( - opcode.ENABLE_SPECIALIZATION, "requires specialization")(test) + _opcode.ENABLE_SPECIALIZATION, "requires specialization")(test) def _filter_suite(suite, pred): """Recursively filter test cases in a suite based on a predicate.""" @@ -1106,6 +1130,30 @@ def _filter_suite(suite, pred): newtests.append(test) suite._tests = newtests +@dataclasses.dataclass(slots=True) +class TestStats: + tests_run: int = 0 + failures: int = 0 + skipped: int = 0 + + @staticmethod + def from_unittest(result): + return TestStats(result.testsRun, + len(result.failures), + len(result.skipped)) + + @staticmethod + def from_doctest(results): + return TestStats(results.attempted, + results.failed, + results.skipped) + + def accumulate(self, stats): + self.tests_run += stats.tests_run + self.failures += stats.failures + self.skipped += stats.skipped + + def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" runner = get_test_runner(sys.stdout, @@ -1120,6 +1168,7 @@ def _run_suite(suite): if not result.testsRun and not result.skipped and not result.errors: raise TestDidNotRun if not result.wasSuccessful(): + stats = TestStats.from_unittest(result) if len(result.errors) == 1 and not result.failures: err = result.errors[0][1] elif len(result.failures) == 1 and not result.errors: @@ -1129,7 +1178,8 @@ def _run_suite(suite): if not verbose: err += "; run in verbose mode for details" errors = [(str(tc), exc_str) for tc, exc_str in result.errors] failures = [(str(tc), exc_str) for tc, exc_str in result.failures] - raise TestFailedWithDetails(err, errors, failures) + raise TestFailedWithDetails(err, errors, failures, stats=stats) + return result # By default, don't filter tests @@ -1160,7 +1210,6 @@ def _is_full_match_test(pattern): def set_match_tests(accept_patterns=None, ignore_patterns=None): global _match_test_func, _accept_test_patterns, _ignore_test_patterns - if accept_patterns is None: accept_patterns = () if ignore_patterns is None: @@ -1238,7 +1287,7 @@ def run_unittest(*classes): else: suite.addTest(loader.loadTestsFromTestCase(cls)) _filter_suite(suite, match_test) - _run_suite(suite) + return _run_suite(suite) #======================================================================= # Check for the presence of docstrings. @@ -1278,13 +1327,18 @@ def run_doctest(module, verbosity=None, optionflags=0): else: verbosity = None - f, t = doctest.testmod(module, verbose=verbosity, optionflags=optionflags) - if f: - raise TestFailed("%d of %d doctests failed" % (f, t)) + results = doctest.testmod(module, + verbose=verbosity, + optionflags=optionflags) + if results.failed: + stats = TestStats.from_doctest(results) + raise TestFailed(f"{results.failed} of {results.attempted} " + f"doctests failed", + stats=stats) if verbose: print('doctest (%s) ... %d tests with zero failures' % - (module.__name__, t)) - return f, t + (module.__name__, results.attempted)) + return results #======================================================================= @@ -1819,11 +1873,11 @@ def run_in_subinterp_with_config(code, *, own_gil=None, **config): module is enabled. """ _check_tracemalloc() - import _testcapi + import _testinternalcapi if own_gil is not None: assert 'gil' not in config, (own_gil, config) config['gil'] = 2 if own_gil else 1 - return _testcapi.run_in_subinterp_with_config(code, **config) + return _testinternalcapi.run_in_subinterp_with_config(code, **config) def _check_tracemalloc(): @@ -2208,6 +2262,39 @@ def check_disallow_instantiation(testcase, tp, *args, **kwds): msg = f"cannot create '{re.escape(qualname)}' instances" testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds) +def get_recursion_depth(): + """Get the recursion depth of the caller function. + + In the __main__ module, at the module level, it should be 1. + """ + try: + import _testinternalcapi + depth = _testinternalcapi.get_recursion_depth() + except (ImportError, RecursionError) as exc: + # sys._getframe() + frame.f_back implementation. + try: + depth = 0 + frame = sys._getframe() + while frame is not None: + depth += 1 + frame = frame.f_back + finally: + # Break any reference cycles. + frame = None + + # Ignore get_recursion_depth() frame. + return max(depth - 1, 1) + +def get_recursion_available(): + """Get the number of available frames before RecursionError. + + It depends on the current recursion depth of the caller function and + sys.getrecursionlimit(). + """ + limit = sys.getrecursionlimit() + depth = get_recursion_depth() + return limit - depth + @contextlib.contextmanager def set_recursion_limit(limit): """Temporarily change the recursion limit.""" @@ -2218,14 +2305,18 @@ def set_recursion_limit(limit): finally: sys.setrecursionlimit(original_limit) -def infinite_recursion(max_depth=75): +def infinite_recursion(max_depth=100): """Set a lower limit for tests that interact with infinite recursions (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some debug windows builds, due to not enough functions being inlined the stack size might not handle the default recursion limit (1000). See bpo-11105 for details.""" - return set_recursion_limit(max_depth) - + if max_depth < 3: + raise ValueError("max_depth must be at least 3, got {max_depth}") + depth = get_recursion_depth() + depth = max(depth - 1, 1) # Ignore infinite_recursion() frame. + limit = depth + max_depth + return set_recursion_limit(limit) def ignore_deprecations_from(module: str, *, like: str) -> object: token = object() @@ -2460,3 +2551,55 @@ def adjust_int_max_str_digits(max_digits): #For recursion tests, easily exceeds default recursion limit EXCEEDS_RECURSION_LIMIT = 5000 + +# The default C recursion limit (from Include/cpython/pystate.h). +Py_C_RECURSION_LIMIT = 1500 + +#Windows doesn't have os.uname() but it doesn't support s390x. +skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x', + 'skipped on s390x') + +Py_TRACE_REFS = hasattr(sys, 'getobjects') + +# Decorator to disable optimizer while a function run +def without_optimizer(func): + try: + import _testinternalcapi + except ImportError: + return func + @functools.wraps(func) + def wrapper(*args, **kwargs): + save_opt = _testinternalcapi.get_optimizer() + try: + _testinternalcapi.set_optimizer(None) + return func(*args, **kwargs) + finally: + _testinternalcapi.set_optimizer(save_opt) + return wrapper + + +_BASE_COPY_SRC_DIR_IGNORED_NAMES = frozenset({ + # SRC_DIR/.git + '.git', + # ignore all __pycache__/ sub-directories + '__pycache__', +}) + +# Ignore function for shutil.copytree() to copy the Python source code. +def copy_python_src_ignore(path, names): + ignored = _BASE_COPY_SRC_DIR_IGNORED_NAMES + if os.path.basename(path) == 'Doc': + ignored |= { + # SRC_DIR/Doc/build/ + 'build', + # SRC_DIR/Doc/venv/ + 'venv', + } + + # check if we are at the root of the source code + elif 'Modules' in names: + ignored |= { + # SRC_DIR/build/ + 'build', + } + return ignored diff --git a/Lib/test/support/hypothesis_helper.py b/Lib/test/support/hypothesis_helper.py index da16eb50c25958..db93eea5e912e0 100644 --- a/Lib/test/support/hypothesis_helper.py +++ b/Lib/test/support/hypothesis_helper.py @@ -10,7 +10,10 @@ hypothesis.settings.register_profile( "slow-is-ok", deadline=None, - suppress_health_check=[hypothesis.HealthCheck.too_slow], + suppress_health_check=[ + hypothesis.HealthCheck.too_slow, + hypothesis.HealthCheck.differing_executors, + ], ) hypothesis.settings.load_profile("slow-is-ok") diff --git a/Lib/test/support/import_helper.py b/Lib/test/support/import_helper.py index 67f18e530edc4b..3d804f2b590108 100644 --- a/Lib/test/support/import_helper.py +++ b/Lib/test/support/import_helper.py @@ -8,7 +8,7 @@ import unittest import warnings -from .os_helper import unlink +from .os_helper import unlink, temp_dir @contextlib.contextmanager @@ -274,3 +274,26 @@ def mock_register_at_fork(func): # memory. from unittest import mock return mock.patch('os.register_at_fork', create=True)(func) + + +@contextlib.contextmanager +def ready_to_import(name=None, source=""): + from test.support import script_helper + + # 1. Sets up a temporary directory and removes it afterwards + # 2. Creates the module file + # 3. Temporarily clears the module from sys.modules (if any) + # 4. Reverts or removes the module when cleaning up + name = name or "spam" + with temp_dir() as tempdir: + path = script_helper.make_script(tempdir, name, source) + old_module = sys.modules.pop(name, None) + try: + sys.path.insert(0, tempdir) + yield name, path + sys.path.remove(tempdir) + finally: + if old_module is not None: + sys.modules[name] = old_module + else: + sys.modules.pop(name, None) diff --git a/Lib/test/support/interpreters.py b/Lib/test/support/interpreters.py index 5c484d1170d1d9..9ba6862a9ee01a 100644 --- a/Lib/test/support/interpreters.py +++ b/Lib/test/support/interpreters.py @@ -5,9 +5,10 @@ import _xxinterpchannels as _channels # aliases: -from _xxsubinterpreters import is_shareable, RunFailedError +from _xxsubinterpreters import is_shareable from _xxinterpchannels import ( - ChannelError, ChannelNotFoundError, ChannelEmptyError, + ChannelError, ChannelNotFoundError, ChannelClosedError, + ChannelEmptyError, ChannelNotEmptyError, ) @@ -90,12 +91,26 @@ def close(self): """ return _interpreters.destroy(self._id) + # XXX Rename "run" to "exec"? def run(self, src_str, /, *, channels=None): """Run the given source code in the interpreter. - This blocks the current Python thread until done. + This is essentially the same as calling the builtin "exec" + with this interpreter, using the __dict__ of its __main__ + module as both globals and locals. + + There is no return value. + + If the code raises an unhandled exception then a RunFailedError + is raised, which summarizes the unhandled exception. The actual + exception is discarded because objects cannot be shared between + interpreters. + + This blocks the current Python thread until done. During + that time, the previous interpreter is allowed to run + in other threads. """ - _interpreters.run_string(self._id, src_str, channels) + _interpreters.exec(self._id, src_str, channels) def create_channel(): @@ -117,10 +132,16 @@ def list_all_channels(): class _ChannelEnd: """The base class for RecvChannel and SendChannel.""" - def __init__(self, id): - if not isinstance(id, (int, _channels.ChannelID)): - raise TypeError(f'id must be an int, got {id!r}') - self._id = id + _end = None + + def __init__(self, cid): + if self._end == 'send': + cid = _channels._channel_id(cid, send=True, force=True) + elif self._end == 'recv': + cid = _channels._channel_id(cid, recv=True, force=True) + else: + raise NotImplementedError(self._end) + self._id = cid def __repr__(self): return f'{type(self).__name__}(id={int(self._id)})' @@ -147,6 +168,8 @@ def id(self): class RecvChannel(_ChannelEnd): """The receiving end of a cross-interpreter channel.""" + _end = 'recv' + def recv(self, *, _sentinel=object(), _delay=10 / 1000): # 10 milliseconds """Return the next object from the channel. @@ -171,20 +194,21 @@ def recv_nowait(self, default=_NOT_SET): else: return _channels.recv(self._id, default) + def close(self): + _channels.close(self._id, recv=True) + class SendChannel(_ChannelEnd): """The sending end of a cross-interpreter channel.""" + _end = 'send' + def send(self, obj): """Send the object (i.e. its data) to the channel's receiving end. This blocks until the object is received. """ - _channels.send(self._id, obj) - # XXX We are missing a low-level channel_send_wait(). - # See bpo-32604 and gh-19829. - # Until that shows up we fake it: - time.sleep(2) + _channels.send(self._id, obj, blocking=True) def send_nowait(self, obj): """Send the object to the channel's receiving end. @@ -195,4 +219,26 @@ def send_nowait(self, obj): # XXX Note that at the moment channel_send() only ever returns # None. This should be fixed when channel_send_wait() is added. # See bpo-32604 and gh-19829. - return _channels.send(self._id, obj) + return _channels.send(self._id, obj, blocking=False) + + def send_buffer(self, obj): + """Send the object's buffer to the channel's receiving end. + + This blocks until the object is received. + """ + _channels.send_buffer(self._id, obj, blocking=True) + + def send_buffer_nowait(self, obj): + """Send the object's buffer to the channel's receiving end. + + If the object is immediately received then return True + (else False). Otherwise this is the same as send(). + """ + return _channels.send_buffer(self._id, obj, blocking=False) + + def close(self): + _channels.close(self._id, send=True) + + +# XXX This is causing leaks (gh-110318): +#_channels._register_end_types(SendChannel, RecvChannel) diff --git a/Lib/test/support/socket_helper.py b/Lib/test/support/socket_helper.py index 45f6d65c355dd4..87941ee1791b4e 100644 --- a/Lib/test/support/socket_helper.py +++ b/Lib/test/support/socket_helper.py @@ -3,6 +3,7 @@ import os.path import socket import sys +import subprocess import tempfile import unittest @@ -277,3 +278,62 @@ def create_unix_domain_name(): """ return tempfile.mktemp(prefix="test_python_", suffix='.sock', dir=os.path.curdir) + + +# consider that sysctl values should not change while tests are running +_sysctl_cache = {} + +def _get_sysctl(name): + """Get a sysctl value as an integer.""" + try: + return _sysctl_cache[name] + except KeyError: + pass + + # At least Linux and FreeBSD support the "-n" option + cmd = ['sysctl', '-n', name] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + if proc.returncode: + support.print_warning(f'{' '.join(cmd)!r} command failed with ' + f'exit code {proc.returncode}') + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + output = proc.stdout + + # Parse '0\n' to get '0' + try: + value = int(output.strip()) + except Exception as exc: + support.print_warning(f'Failed to parse {' '.join(cmd)!r} ' + f'command output {output!r}: {exc!r}') + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + + _sysctl_cache[name] = value + return value + + +def tcp_blackhole(): + if not sys.platform.startswith('freebsd'): + return False + + # gh-109015: test if FreeBSD TCP blackhole is enabled + value = _get_sysctl('net.inet.tcp.blackhole') + if value is None: + # don't skip if we fail to get the sysctl value + return False + return (value != 0) + + +def skip_if_tcp_blackhole(test): + """Decorator skipping test if TCP blackhole is enabled.""" + skip_if = unittest.skipIf( + tcp_blackhole(), + "TCP blackhole is enabled (sysctl net.inet.tcp.blackhole)" + ) + return skip_if(test) diff --git a/Lib/test/support/testresult.py b/Lib/test/support/testresult.py index 14474be222dc4b..de23fdd59ded95 100644 --- a/Lib/test/support/testresult.py +++ b/Lib/test/support/testresult.py @@ -8,6 +8,7 @@ import time import traceback import unittest +from test import support class RegressionTestResult(unittest.TextTestResult): USE_XML = False @@ -112,6 +113,8 @@ def addExpectedFailure(self, test, err): def addFailure(self, test, err): self._add_result(test, True, failure=self.__makeErrorDict(*err)) super().addFailure(test, err) + if support.failfast: + self.stop() def addSkip(self, test, reason): self._add_result(test, skipped=reason) diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 2163f1636566b7..c87cde4b3d1fab 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -12,10 +12,19 @@ if support.check_sanitizer(address=True, memory=True): - # bpo-46633: test___all__ is skipped because importing some modules - # directly can trigger known problems with ASAN (like tk). - raise unittest.SkipTest("workaround ASAN build issues on loading tests " - "like tk") + SKIP_MODULES = frozenset(( + # gh-90791: Tests involving libX11 can SEGFAULT on ASAN/MSAN builds. + # Skip modules, packages and tests using '_tkinter'. + '_tkinter', + 'tkinter', + 'test_tkinter', + 'test_ttk', + 'test_ttk_textonly', + 'idlelib', + 'test_idle', + )) +else: + SKIP_MODULES = () class NoAll(RuntimeError): @@ -83,15 +92,23 @@ def walk_modules(self, basedir, modpath): for fn in sorted(os.listdir(basedir)): path = os.path.join(basedir, fn) if os.path.isdir(path): + if fn in SKIP_MODULES: + continue pkg_init = os.path.join(path, '__init__.py') if os.path.exists(pkg_init): yield pkg_init, modpath + fn for p, m in self.walk_modules(path, modpath + fn + "."): yield p, m continue - if not fn.endswith('.py') or fn == '__init__.py': + + if fn == '__init__.py': + continue + if not fn.endswith('.py'): + continue + modname = fn.removesuffix('.py') + if modname in SKIP_MODULES: continue - yield path, modpath + fn[:-3] + yield path, modpath + modname def test_all(self): # List of denied modules and packages @@ -119,14 +136,14 @@ def test_all(self): if denied: continue if support.verbose: - print(modname) + print(f"Check {modname}", flush=True) try: # This heuristic speeds up the process by removing, de facto, # most test modules (and avoiding the auto-executing ones). with open(path, "rb") as f: if b"__all__" not in f.read(): raise NoAll(modname) - self.check_all(modname) + self.check_all(modname) except NoAll: ignored.append(modname) except FailedImport: diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index b3a9bcbe160453..c1f612dc4a63cb 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -106,7 +106,7 @@ def test_specialization_stats(self): specialized_opcodes = [ op.lower() for op in opcode._specializations - if opcode._inline_cache_entries[opcode.opmap[op]] + if opcode._inline_cache_entries.get(op, 0) ] self.assertIn('load_attr', specialized_opcodes) self.assertIn('binary_subscr', specialized_opcodes) diff --git a/Lib/test/test__xxinterpchannels.py b/Lib/test/test__xxinterpchannels.py index 750cd99b85e7a6..ff01a339c0008e 100644 --- a/Lib/test/test__xxinterpchannels.py +++ b/Lib/test/test__xxinterpchannels.py @@ -21,6 +21,13 @@ ################################## # helpers +def recv_wait(cid): + while True: + try: + return channels.recv(cid) + except channels.ChannelEmptyError: + time.sleep(0.1) + #@contextmanager #def run_threaded(id, source, **shared): # def run(): @@ -189,7 +196,7 @@ def run_action(cid, action, end, state, *, hideclosed=True): def _run_action(cid, action, end, state): if action == 'use': if end == 'send': - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) return state.incr() elif end == 'recv': if not state.pending: @@ -332,7 +339,7 @@ def test_shareable(self): chan = channels.create() obj = channels.create() - channels.send(chan, obj) + channels.send(chan, obj, blocking=False) got = channels.recv(chan) self.assertEqual(got, obj) @@ -390,7 +397,7 @@ def test_channel_list_interpreters_basic(self): """Test basic listing channel interpreters.""" interp0 = interpreters.get_main() cid = channels.create() - channels.send(cid, "send") + channels.send(cid, "send", blocking=False) # Test for a channel that has one end associated to an interpreter. send_interps = channels.list_interpreters(cid, send=True) recv_interps = channels.list_interpreters(cid, send=False) @@ -416,10 +423,10 @@ def test_channel_list_interpreters_multiple(self): interp3 = interpreters.create() cid = channels.create() - channels.send(cid, "send") + channels.send(cid, "send", blocking=False) _run_output(interp1, dedent(f""" import _xxinterpchannels as _channels - _channels.send({cid}, "send") + _channels.send({cid}, "send", blocking=False) """)) _run_output(interp2, dedent(f""" import _xxinterpchannels as _channels @@ -439,7 +446,7 @@ def test_channel_list_interpreters_destroyed(self): interp0 = interpreters.get_main() interp1 = interpreters.create() cid = channels.create() - channels.send(cid, "send") + channels.send(cid, "send", blocking=False) _run_output(interp1, dedent(f""" import _xxinterpchannels as _channels obj = _channels.recv({cid}) @@ -465,12 +472,12 @@ def test_channel_list_interpreters_released(self): interp1 = interpreters.create() interp2 = interpreters.create() cid = channels.create() - channels.send(cid, "data") + channels.send(cid, "data", blocking=False) _run_output(interp1, dedent(f""" import _xxinterpchannels as _channels obj = _channels.recv({cid}) """)) - channels.send(cid, "data") + channels.send(cid, "data", blocking=False) _run_output(interp2, dedent(f""" import _xxinterpchannels as _channels obj = _channels.recv({cid}) @@ -506,7 +513,7 @@ def test_channel_list_interpreters_closed(self): interp1 = interpreters.create() cid = channels.create() # Put something in the channel so that it's not empty. - channels.send(cid, "send") + channels.send(cid, "send", blocking=False) # Check initial state. send_interps = channels.list_interpreters(cid, send=True) @@ -528,7 +535,7 @@ def test_channel_list_interpreters_closed_send_end(self): interp1 = interpreters.create() cid = channels.create() # Put something in the channel so that it's not empty. - channels.send(cid, "send") + channels.send(cid, "send", blocking=False) # Check initial state. send_interps = channels.list_interpreters(cid, send=True) @@ -562,7 +569,7 @@ def test_channel_list_interpreters_closed_send_end(self): def test_send_recv_main(self): cid = channels.create() orig = b'spam' - channels.send(cid, orig) + channels.send(cid, orig, blocking=False) obj = channels.recv(cid) self.assertEqual(obj, orig) @@ -574,7 +581,7 @@ def test_send_recv_same_interpreter(self): import _xxinterpchannels as _channels cid = _channels.create() orig = b'spam' - _channels.send(cid, orig) + _channels.send(cid, orig, blocking=False) obj = _channels.recv(cid) assert obj is not orig assert obj == orig @@ -585,7 +592,7 @@ def test_send_recv_different_interpreters(self): id1 = interpreters.create() out = _run_output(id1, dedent(f""" import _xxinterpchannels as _channels - _channels.send({cid}, b'spam') + _channels.send({cid}, b'spam', blocking=False) """)) obj = channels.recv(cid) @@ -595,19 +602,14 @@ def test_send_recv_different_threads(self): cid = channels.create() def f(): - while True: - try: - obj = channels.recv(cid) - break - except channels.ChannelEmptyError: - time.sleep(0.1) + obj = recv_wait(cid) channels.send(cid, obj) t = threading.Thread(target=f) t.start() channels.send(cid, b'spam') + obj = recv_wait(cid) t.join() - obj = channels.recv(cid) self.assertEqual(obj, b'spam') @@ -634,8 +636,8 @@ def f(): t.start() channels.send(cid, b'spam') + obj = recv_wait(cid) t.join() - obj = channels.recv(cid) self.assertEqual(obj, b'eggs') @@ -656,10 +658,10 @@ def test_recv_default(self): default = object() cid = channels.create() obj1 = channels.recv(cid, default) - channels.send(cid, None) - channels.send(cid, 1) - channels.send(cid, b'spam') - channels.send(cid, b'eggs') + channels.send(cid, None, blocking=False) + channels.send(cid, 1, blocking=False) + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'eggs', blocking=False) obj2 = channels.recv(cid, default) obj3 = channels.recv(cid, default) obj4 = channels.recv(cid) @@ -679,7 +681,7 @@ def test_recv_sending_interp_destroyed(self): interp = interpreters.create() interpreters.run_string(interp, dedent(f""" import _xxinterpchannels as _channels - _channels.send({cid1}, b'spam') + _channels.send({cid1}, b'spam', blocking=False) """)) interpreters.destroy(interp) @@ -692,9 +694,9 @@ def test_recv_sending_interp_destroyed(self): interp = interpreters.create() interpreters.run_string(interp, dedent(f""" import _xxinterpchannels as _channels - _channels.send({cid2}, b'spam') + _channels.send({cid2}, b'spam', blocking=False) """)) - channels.send(cid2, b'eggs') + channels.send(cid2, b'eggs', blocking=False) interpreters.destroy(interp) channels.recv(cid2) @@ -703,6 +705,21 @@ def test_recv_sending_interp_destroyed(self): channels.recv(cid2) del cid2 + def test_send_buffer(self): + buf = bytearray(b'spamspamspam') + cid = channels.create() + channels.send_buffer(cid, buf, blocking=False) + obj = channels.recv(cid) + + self.assertIsNot(obj, buf) + self.assertIsInstance(obj, memoryview) + self.assertEqual(obj, buf) + + buf[4:8] = b'eggs' + self.assertEqual(obj, buf) + obj[4:8] = b'ham.' + self.assertEqual(obj, buf) + def test_allowed_types(self): cid = channels.create() objects = [ @@ -713,7 +730,7 @@ def test_allowed_types(self): ] for obj in objects: with self.subTest(obj): - channels.send(cid, obj) + channels.send(cid, obj, blocking=False) got = channels.recv(cid) self.assertEqual(got, obj) @@ -729,7 +746,7 @@ def test_run_string_arg_unresolved(self): out = _run_output(interp, dedent(""" import _xxinterpchannels as _channels print(cid.end) - _channels.send(cid, b'spam') + _channels.send(cid, b'spam', blocking=False) """), dict(cid=cid.send)) obj = channels.recv(cid) @@ -749,7 +766,7 @@ def test_run_string_arg_resolved(self): out = _run_output(interp, dedent(""" import _xxinterpchannels as _channels print(chan.id.end) - _channels.send(chan.id, b'spam') + _channels.send(chan.id, b'spam', blocking=False) """), dict(chan=cid.send)) obj = channels.recv(cid) @@ -761,7 +778,7 @@ def test_run_string_arg_resolved(self): def test_close_single_user(self): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.close(cid) @@ -776,7 +793,7 @@ def test_close_multiple_users(self): id2 = interpreters.create() interpreters.run_string(id1, dedent(f""" import _xxinterpchannels as _channels - _channels.send({cid}, b'spam') + _channels.send({cid}, b'spam', blocking=False) """)) interpreters.run_string(id2, dedent(f""" import _xxinterpchannels as _channels @@ -796,7 +813,7 @@ def test_close_multiple_users(self): def test_close_multiple_times(self): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.close(cid) @@ -813,7 +830,7 @@ def test_close_empty(self): for send, recv in tests: with self.subTest((send, recv)): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.close(cid, send=send, recv=recv) @@ -824,31 +841,31 @@ def test_close_empty(self): def test_close_defaults_with_unused_items(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) with self.assertRaises(channels.ChannelNotEmptyError): channels.close(cid) channels.recv(cid) - channels.send(cid, b'eggs') + channels.send(cid, b'eggs', blocking=False) def test_close_recv_with_unused_items_unforced(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) with self.assertRaises(channels.ChannelNotEmptyError): channels.close(cid, recv=True) channels.recv(cid) - channels.send(cid, b'eggs') + channels.send(cid, b'eggs', blocking=False) channels.recv(cid) channels.recv(cid) channels.close(cid, recv=True) def test_close_send_with_unused_items_unforced(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) channels.close(cid, send=True) with self.assertRaises(channels.ChannelClosedError): @@ -860,21 +877,21 @@ def test_close_send_with_unused_items_unforced(self): def test_close_both_with_unused_items_unforced(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) with self.assertRaises(channels.ChannelNotEmptyError): channels.close(cid, recv=True, send=True) channels.recv(cid) - channels.send(cid, b'eggs') + channels.send(cid, b'eggs', blocking=False) channels.recv(cid) channels.recv(cid) channels.close(cid, recv=True) def test_close_recv_with_unused_items_forced(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) channels.close(cid, recv=True, force=True) with self.assertRaises(channels.ChannelClosedError): @@ -884,8 +901,8 @@ def test_close_recv_with_unused_items_forced(self): def test_close_send_with_unused_items_forced(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) channels.close(cid, send=True, force=True) with self.assertRaises(channels.ChannelClosedError): @@ -895,8 +912,8 @@ def test_close_send_with_unused_items_forced(self): def test_close_both_with_unused_items_forced(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) channels.close(cid, send=True, recv=True, force=True) with self.assertRaises(channels.ChannelClosedError): @@ -915,7 +932,7 @@ def test_close_never_used(self): def test_close_by_unassociated_interp(self): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) interp = interpreters.create() interpreters.run_string(interp, dedent(f""" import _xxinterpchannels as _channels @@ -928,9 +945,9 @@ def test_close_by_unassociated_interp(self): def test_close_used_multiple_times_by_single_user(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'spam') - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.close(cid, force=True) @@ -1002,7 +1019,7 @@ class ChannelReleaseTests(TestBase): def test_single_user(self): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.release(cid, send=True, recv=True) @@ -1017,7 +1034,7 @@ def test_multiple_users(self): id2 = interpreters.create() interpreters.run_string(id1, dedent(f""" import _xxinterpchannels as _channels - _channels.send({cid}, b'spam') + _channels.send({cid}, b'spam', blocking=False) """)) out = _run_output(id2, dedent(f""" import _xxinterpchannels as _channels @@ -1033,7 +1050,7 @@ def test_multiple_users(self): def test_no_kwargs(self): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.release(cid) @@ -1044,7 +1061,7 @@ def test_no_kwargs(self): def test_multiple_times(self): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.release(cid, send=True, recv=True) @@ -1053,8 +1070,8 @@ def test_multiple_times(self): def test_with_unused_items(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'ham') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'ham', blocking=False) channels.release(cid, send=True, recv=True) with self.assertRaises(channels.ChannelClosedError): @@ -1071,7 +1088,7 @@ def test_never_used(self): def test_by_unassociated_interp(self): cid = channels.create() - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) interp = interpreters.create() interpreters.run_string(interp, dedent(f""" import _xxinterpchannels as _channels @@ -1090,7 +1107,7 @@ def test_close_if_unassociated(self): interp = interpreters.create() interpreters.run_string(interp, dedent(f""" import _xxinterpchannels as _channels - obj = _channels.send({cid}, b'spam') + obj = _channels.send({cid}, b'spam', blocking=False) _channels.release({cid}) """)) @@ -1100,9 +1117,9 @@ def test_close_if_unassociated(self): def test_partially(self): # XXX Is partial close too weird/confusing? cid = channels.create() - channels.send(cid, None) + channels.send(cid, None, blocking=False) channels.recv(cid) - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) channels.release(cid, send=True) obj = channels.recv(cid) @@ -1110,9 +1127,9 @@ def test_partially(self): def test_used_multiple_times_by_single_user(self): cid = channels.create() - channels.send(cid, b'spam') - channels.send(cid, b'spam') - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'spam', blocking=False) + channels.send(cid, b'spam', blocking=False) channels.recv(cid) channels.release(cid, send=True, recv=True) @@ -1197,7 +1214,7 @@ def _new_channel(self, creator): cid = _xxsubchannels.create() # We purposefully send back an int to avoid tying the # channel to the other interpreter. - _xxsubchannels.send({ch}, int(cid)) + _xxsubchannels.send({ch}, int(cid), blocking=False) del _xxsubinterpreters """) self._cid = channels.recv(ch) @@ -1427,8 +1444,8 @@ def run_action(self, fix, action, *, hideclosed=True): {repr(fix.state)}, hideclosed={hideclosed}, ) - channels.send({_cid}, result.pending.to_bytes(1, 'little')) - channels.send({_cid}, b'X' if result.closed else b'') + channels.send({_cid}, result.pending.to_bytes(1, 'little'), blocking=False) + channels.send({_cid}, b'X' if result.closed else b'', blocking=False) """) result = ChannelState( pending=int.from_bytes(channels.recv(_cid), 'little'), @@ -1475,7 +1492,7 @@ def _assert_closed_in_interp(self, fix, interp=None): """) run_interp(interp.id, """ with helpers.expect_channel_closed(): - channels.send(cid, b'spam') + channels.send(cid, b'spam', blocking=False) """) run_interp(interp.id, """ with helpers.expect_channel_closed(): diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py index ac2280eb7090e9..e3c917aa2eb19d 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -925,5 +925,110 @@ def f(): self.assertEqual(retcode, 0) +class RunFuncTests(TestBase): + + def setUp(self): + super().setUp() + self.id = interpreters.create() + + def test_success(self): + r, w = os.pipe() + def script(): + global w + import contextlib + with open(w, 'w', encoding="utf-8") as spipe: + with contextlib.redirect_stdout(spipe): + print('it worked!', end='') + interpreters.run_func(self.id, script, shared=dict(w=w)) + + with open(r, encoding="utf-8") as outfile: + out = outfile.read() + + self.assertEqual(out, 'it worked!') + + def test_in_thread(self): + r, w = os.pipe() + def script(): + global w + import contextlib + with open(w, 'w', encoding="utf-8") as spipe: + with contextlib.redirect_stdout(spipe): + print('it worked!', end='') + def f(): + interpreters.run_func(self.id, script, shared=dict(w=w)) + t = threading.Thread(target=f) + t.start() + t.join() + + with open(r, encoding="utf-8") as outfile: + out = outfile.read() + + self.assertEqual(out, 'it worked!') + + def test_code_object(self): + r, w = os.pipe() + + def script(): + global w + import contextlib + with open(w, 'w', encoding="utf-8") as spipe: + with contextlib.redirect_stdout(spipe): + print('it worked!', end='') + code = script.__code__ + interpreters.run_func(self.id, code, shared=dict(w=w)) + + with open(r, encoding="utf-8") as outfile: + out = outfile.read() + + self.assertEqual(out, 'it worked!') + + def test_closure(self): + spam = True + def script(): + assert spam + + with self.assertRaises(ValueError): + interpreters.run_func(self.id, script) + + # XXX This hasn't been fixed yet. + @unittest.expectedFailure + def test_return_value(self): + def script(): + return 'spam' + with self.assertRaises(ValueError): + interpreters.run_func(self.id, script) + + def test_args(self): + with self.subTest('args'): + def script(a, b=0): + assert a == b + with self.assertRaises(ValueError): + interpreters.run_func(self.id, script) + + with self.subTest('*args'): + def script(*args): + assert not args + with self.assertRaises(ValueError): + interpreters.run_func(self.id, script) + + with self.subTest('**kwargs'): + def script(**kwargs): + assert not kwargs + with self.assertRaises(ValueError): + interpreters.run_func(self.id, script) + + with self.subTest('kwonly'): + def script(*, spam=True): + assert spam + with self.assertRaises(ValueError): + interpreters.run_func(self.id, script) + + with self.subTest('posonly'): + def script(spam, /): + assert spam + with self.assertRaises(ValueError): + interpreters.run_func(self.id, script) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index a03fa4c7187b05..fa96e259b8c978 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -357,6 +357,38 @@ def test_ast_validation(self): tree = ast.parse(snippet) compile(tree, '', 'exec') + def test_optimization_levels__debug__(self): + cases = [(-1, '__debug__'), (0, '__debug__'), (1, False), (2, False)] + for (optval, expected) in cases: + with self.subTest(optval=optval, expected=expected): + res1 = ast.parse("__debug__", optimize=optval) + res2 = ast.parse(ast.parse("__debug__"), optimize=optval) + for res in [res1, res2]: + self.assertIsInstance(res.body[0], ast.Expr) + if isinstance(expected, bool): + self.assertIsInstance(res.body[0].value, ast.Constant) + self.assertEqual(res.body[0].value.value, expected) + else: + self.assertIsInstance(res.body[0].value, ast.Name) + self.assertEqual(res.body[0].value.id, expected) + + def test_optimization_levels_const_folding(self): + folded = ('Expr', (1, 0, 1, 5), ('Constant', (1, 0, 1, 5), 3, None)) + not_folded = ('Expr', (1, 0, 1, 5), + ('BinOp', (1, 0, 1, 5), + ('Constant', (1, 0, 1, 1), 1, None), + ('Add',), + ('Constant', (1, 4, 1, 5), 2, None))) + + cases = [(-1, not_folded), (0, not_folded), (1, folded), (2, folded)] + for (optval, expected) in cases: + with self.subTest(optval=optval): + tree1 = ast.parse("1 + 2", optimize=optval) + tree2 = ast.parse(ast.parse("1 + 2"), optimize=optval) + for tree in [tree1, tree2]: + res = to_tuple(tree.body[0]) + self.assertEqual(res, expected) + def test_invalid_position_information(self): invalid_linenos = [ (10, 1), (-10, -11), (10, -11), (-5, -2), (-5, 1) @@ -1084,6 +1116,7 @@ def next(self): return self enum._test_simple_enum(_Precedence, ast._Precedence) + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") @support.cpython_only def test_ast_recursion_limit(self): fail_depth = support.EXCEEDS_RECURSION_LIMIT @@ -1998,6 +2031,7 @@ def test_nameconstant(self): 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', ]) + @support.requires_resource('cpu') def test_stdlib_validates(self): stdlib = os.path.dirname(ast.__file__) tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")] diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 4f00558770dafd..a49630112af510 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -1058,8 +1058,7 @@ async def gen(): while True: yield 1 finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) + await asyncio.sleep(0) DONE = 1 async def run(): @@ -1069,7 +1068,10 @@ async def run(): del g gc_collect() # For PyPy or other GCs. - await asyncio.sleep(0.1) + # Starts running the aclose task + await asyncio.sleep(0) + # For asyncio.sleep(0) in finally block + await asyncio.sleep(0) self.loop.run_until_complete(run()) self.assertEqual(DONE, 1) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 3b4026cb73869a..c2080977e9d587 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -273,7 +273,7 @@ def cb(): self.loop.stop() self.loop._process_events = mock.Mock() - delay = 0.1 + delay = 0.100 when = self.loop.time() + delay self.loop.call_at(when, cb) @@ -282,10 +282,7 @@ def cb(): dt = self.loop.time() - t0 # 50 ms: maximum granularity of the event loop - self.assertGreaterEqual(dt, delay - 0.050, dt) - # tolerate a difference of +800 ms because some Python buildbots - # are really slow - self.assertLessEqual(dt, 0.9, dt) + self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES) with self.assertRaises(TypeError, msg="when cannot be None"): self.loop.call_at(None, cb) @@ -925,6 +922,43 @@ def test_run_forever_pre_stopped(self): self.loop.run_forever() self.loop._selector.select.assert_called_once_with(0) + def test_custom_run_forever_integration(self): + # Test that the run_forever_setup() and run_forever_cleanup() primitives + # can be used to implement a custom run_forever loop. + self.loop._process_events = mock.Mock() + + count = 0 + + def callback(): + nonlocal count + count += 1 + + self.loop.call_soon(callback) + + # Set up the custom event loop + self.loop._run_forever_setup() + + # Confirm the loop has been started + self.assertEqual(asyncio.get_running_loop(), self.loop) + self.assertTrue(self.loop.is_running()) + + # Our custom "event loop" just iterates 10 times before exiting. + for i in range(10): + self.loop._run_once() + + # Clean up the event loop + self.loop._run_forever_cleanup() + + # Confirm the loop has been cleaned up + with self.assertRaises(RuntimeError): + asyncio.get_running_loop() + self.assertFalse(self.loop.is_running()) + + # Confirm the loop actually did run, processing events 10 times, + # and invoking the callback once. + self.assertEqual(self.loop._process_events.call_count, 10) + self.assertEqual(count, 1) + async def leave_unfinalized_asyncgen(self): # Create an async generator, iterate it partially, and leave it # to be garbage collected. diff --git a/Lib/test/test_asyncio/test_eager_task_factory.py b/Lib/test/test_asyncio/test_eager_task_factory.py index fc9ad8eb43bb1b..0f8212dbec47be 100644 --- a/Lib/test/test_asyncio/test_eager_task_factory.py +++ b/Lib/test/test_asyncio/test_eager_task_factory.py @@ -7,7 +7,6 @@ from unittest import mock from asyncio import tasks from test.test_asyncio import utils as test_utils -import test.support from test.support.script_helper import assert_python_ok MOCK_ANY = mock.ANY diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index b9069056c3a436..b25c0975736e20 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1,6 +1,5 @@ """Tests for events.py.""" -import collections.abc import concurrent.futures import functools import io @@ -31,6 +30,7 @@ from asyncio import coroutines from asyncio import events from asyncio import selector_events +from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper @@ -293,10 +293,11 @@ async def coro2(): # 15.6 msec, we use fairly long sleep times here (~100 msec). def test_run_until_complete(self): + delay = 0.100 t0 = self.loop.time() - self.loop.run_until_complete(asyncio.sleep(0.1)) - t1 = self.loop.time() - self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) + self.loop.run_until_complete(asyncio.sleep(delay)) + dt = self.loop.time() - t0 + self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES) def test_run_until_complete_stopped(self): @@ -671,6 +672,7 @@ def test_create_connection_local_addr(self): self.assertEqual(port, expected) tr.close() + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_skip_different_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -692,6 +694,7 @@ async def getaddrinfo(host, port, *args, **kwargs): with self.assertRaises(OSError): self.loop.run_until_complete(f) + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_nomatch_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -1271,6 +1274,7 @@ def connection_made(self, transport): server.close() + @socket_helper.skip_if_tcp_blackhole def test_server_close(self): f = self.loop.create_server(MyProto, '0.0.0.0', 0) server = self.loop.run_until_complete(f) @@ -1689,12 +1693,9 @@ async def main(): self.loop.stop() return res - start = time.monotonic() t = self.loop.create_task(main()) self.loop.run_forever() - elapsed = time.monotonic() - start - self.assertLess(elapsed, 0.1) self.assertEqual(t.result(), 'cancelled') self.assertRaises(asyncio.CancelledError, f.result) if ov is not None: @@ -1714,7 +1715,6 @@ def _run_once(): self.loop._run_once = _run_once async def wait(): - loop = self.loop await asyncio.sleep(1e-2) await asyncio.sleep(1e-4) await asyncio.sleep(1e-6) @@ -2331,8 +2331,6 @@ def check_source_traceback(h): h = loop.call_later(0, noop) check_source_traceback(h) - @unittest.skipUnless(hasattr(collections.abc, 'Coroutine'), - 'No collections.abc.Coroutine') def test_coroutine_like_object_debug_formatting(self): # Test that asyncio can format coroutines that are instances of # collections.abc.Coroutine, but lack cr_core or gi_code attributes @@ -2762,6 +2760,8 @@ def test_get_event_loop_new_process(self): # multiprocessing.synchronize module cannot be imported. support.skip_if_broken_multiprocessing_synchronize() + self.addCleanup(multiprocessing_cleanup_tests) + async def main(): if multiprocessing.get_start_method() == 'fork': # Avoid 'fork' DeprecationWarning. diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index b1eb6f492886b3..13493d3c806d6a 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -3,6 +3,7 @@ import contextvars import re import signal +import sys import threading import unittest from test.test_asyncio import utils as test_utils @@ -101,11 +102,14 @@ async def main(expected): loop = asyncio.get_event_loop() self.assertIs(loop.get_debug(), expected) - asyncio.run(main(False)) + asyncio.run(main(False), debug=False) asyncio.run(main(True), debug=True) with mock.patch('asyncio.coroutines._is_debug_mode', lambda: True): asyncio.run(main(True)) asyncio.run(main(False), debug=False) + with mock.patch('asyncio.coroutines._is_debug_mode', lambda: False): + asyncio.run(main(True), debug=True) + asyncio.run(main(False)) def test_asyncio_run_from_running_loop(self): async def main(): @@ -269,6 +273,16 @@ async def main(): asyncio.run(main(), loop_factory=factory) factory.assert_called_once_with() + def test_loop_factory_default_event_loop(self): + async def main(): + if sys.platform == "win32": + self.assertIsInstance(asyncio.get_running_loop(), asyncio.ProactorEventLoop) + else: + self.assertIsInstance(asyncio.get_running_loop(), asyncio.SelectorEventLoop) + + + asyncio.run(main(), loop_factory=asyncio.EventLoop) + class RunnerTests(BaseTest): diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 47693ea4d3ce2e..c22b780b5edcb8 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -178,7 +178,7 @@ def test_sock_connect_resolve_using_socket_params(self, m_gai): sock.connect.assert_called_with(('127.0.0.1', 0)) def test_add_reader(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} cb = lambda: True self.loop.add_reader(1, cb) @@ -192,8 +192,8 @@ def test_add_reader(self): def test_add_reader_existing(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_WRITE, (reader, writer)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_WRITE, (reader, writer))} cb = lambda: True self.loop.add_reader(1, cb) @@ -208,8 +208,8 @@ def test_add_reader_existing(self): def test_add_reader_existing_writer(self): writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_WRITE, (None, writer)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_WRITE, (None, writer))} cb = lambda: True self.loop.add_reader(1, cb) @@ -222,8 +222,8 @@ def test_add_reader_existing_writer(self): self.assertEqual(writer, w) def test_remove_reader(self): - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_READ, (None, None)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_READ, (None, None))} self.assertFalse(self.loop.remove_reader(1)) self.assertTrue(self.loop._selector.unregister.called) @@ -231,9 +231,9 @@ def test_remove_reader(self): def test_remove_reader_read_write(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( 1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE, - (reader, writer)) + (reader, writer))} self.assertTrue( self.loop.remove_reader(1)) @@ -243,12 +243,12 @@ def test_remove_reader_read_write(self): self.loop._selector.modify.call_args[0]) def test_remove_reader_unknown(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} self.assertFalse( self.loop.remove_reader(1)) def test_add_writer(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} cb = lambda: True self.loop.add_writer(1, cb) @@ -262,8 +262,8 @@ def test_add_writer(self): def test_add_writer_existing(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_READ, (reader, writer)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_READ, (reader, writer))} cb = lambda: True self.loop.add_writer(1, cb) @@ -277,8 +277,8 @@ def test_add_writer_existing(self): self.assertEqual(cb, w._callback) def test_remove_writer(self): - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_WRITE, (None, None)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_WRITE, (None, None))} self.assertFalse(self.loop.remove_writer(1)) self.assertTrue(self.loop._selector.unregister.called) @@ -286,9 +286,9 @@ def test_remove_writer(self): def test_remove_writer_read_write(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( 1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE, - (reader, writer)) + (reader, writer))} self.assertTrue( self.loop.remove_writer(1)) @@ -298,7 +298,7 @@ def test_remove_writer_read_write(self): self.loop._selector.modify.call_args[0]) def test_remove_writer_unknown(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} self.assertFalse( self.loop.remove_writer(1)) diff --git a/Lib/test/test_asyncio/test_sock_lowlevel.py b/Lib/test/test_asyncio/test_sock_lowlevel.py index b829fd4cc69fff..075113cbe8e4a6 100644 --- a/Lib/test/test_asyncio/test_sock_lowlevel.py +++ b/Lib/test/test_asyncio/test_sock_lowlevel.py @@ -10,6 +10,10 @@ from test import support from test.support import socket_helper +if socket_helper.tcp_blackhole(): + raise unittest.SkipTest('Not relevant to ProactorEventLoop') + + def tearDownModule(): asyncio.set_event_loop_policy(None) diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 52a45f1c7c6e96..37d015339761c6 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -5,6 +5,7 @@ import unittest import weakref from test import support +from test.support import socket_helper from unittest import mock try: import ssl @@ -350,6 +351,7 @@ async def client(addr): support.gc_collect() self.assertIsNone(client_context()) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_client_buf_proto_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE @@ -502,6 +504,7 @@ async def client(addr): asyncio.wait_for(client(srv.addr), timeout=support.SHORT_TIMEOUT)) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_server_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE ANSWER = b'answer' diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 7f9dc621808358..9c92e75886c593 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -1074,6 +1074,29 @@ def test_eof_feed_when_closing_writer(self): self.assertEqual(messages, []) + def test_unclosed_resource_warnings(self): + async def inner(httpd): + rd, wr = await asyncio.open_connection(*httpd.address) + + wr.write(b'GET / HTTP/1.0\r\n\r\n') + data = await rd.readline() + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + data = await rd.read() + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + with self.assertWarns(ResourceWarning): + del wr + gc.collect() + + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + + with test_utils.run_test_server() as httpd: + self.loop.run_until_complete(inner(httpd)) + + self.assertEqual(messages, []) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index eeeca40c15cd28..179c8cb8cc17cf 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -1,6 +1,7 @@ import os import signal import sys +import textwrap import unittest import warnings from unittest import mock @@ -12,9 +13,13 @@ from test import support from test.support import os_helper -if sys.platform != 'win32': + +if support.MS_WINDOWS: + import msvcrt +else: from asyncio import unix_events + if support.check_sanitizer(address=True): raise unittest.SkipTest("Exposes ASAN flakiness in GitHub CI") @@ -270,26 +275,43 @@ async def send_signal(proc): finally: signal.signal(signal.SIGHUP, old_handler) - def prepare_broken_pipe_test(self): + def test_stdin_broken_pipe(self): # buffer large enough to feed the whole pipe buffer large_data = b'x' * support.PIPE_MAX_SIZE + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) + self.addCleanup(os.close, wfd) + if support.MS_WINDOWS: + handle = msvcrt.get_osfhandle(rfd) + os.set_handle_inheritable(handle, True) + code = textwrap.dedent(f''' + import os, msvcrt + handle = {handle} + fd = msvcrt.open_osfhandle(handle, os.O_RDONLY) + os.read(fd, 1) + ''') + from subprocess import STARTUPINFO + startupinfo = STARTUPINFO() + startupinfo.lpAttributeList = {"handle_list": [handle]} + kwargs = dict(startupinfo=startupinfo) + else: + code = f'import os; fd = {rfd}; os.read(fd, 1)' + kwargs = dict(pass_fds=(rfd,)) + # the program ends before the stdin can be fed proc = self.loop.run_until_complete( asyncio.create_subprocess_exec( - sys.executable, '-c', 'pass', + sys.executable, '-c', code, stdin=subprocess.PIPE, + **kwargs ) ) - return (proc, large_data) - - def test_stdin_broken_pipe(self): - proc, large_data = self.prepare_broken_pipe_test() - async def write_stdin(proc, data): - await asyncio.sleep(0.5) proc.stdin.write(data) + # Only exit the child process once the write buffer is filled + os.write(wfd, b'go') await proc.stdin.drain() coro = write_stdin(proc, large_data) @@ -300,7 +322,16 @@ async def write_stdin(proc, data): self.loop.run_until_complete(proc.wait()) def test_communicate_ignore_broken_pipe(self): - proc, large_data = self.prepare_broken_pipe_test() + # buffer large enough to feed the whole pipe buffer + large_data = b'x' * support.PIPE_MAX_SIZE + + # the program ends before the stdin can be fed + proc = self.loop.run_until_complete( + asyncio.create_subprocess_exec( + sys.executable, '-c', 'pass', + stdin=subprocess.PIPE, + ) + ) # communicate() must ignore BrokenPipeError when feeding stdin self.loop.set_exception_handler(lambda loop, msg: None) @@ -753,21 +784,44 @@ async def main() -> None: self.loop.run_until_complete(main()) - def test_subprocess_consistent_callbacks(self): + def test_subprocess_protocol_events(self): + # gh-108973: Test that all subprocess protocol methods are called. + # The protocol methods are not called in a determistic order. + # The order depends on the event loop and the operating system. events = [] + fds = [1, 2] + expected = [ + ('pipe_data_received', 1, b'stdout'), + ('pipe_data_received', 2, b'stderr'), + ('pipe_connection_lost', 1), + ('pipe_connection_lost', 2), + 'process_exited', + ] + per_fd_expected = [ + 'pipe_data_received', + 'pipe_connection_lost', + ] + class MyProtocol(asyncio.SubprocessProtocol): def __init__(self, exit_future: asyncio.Future) -> None: self.exit_future = exit_future def pipe_data_received(self, fd, data) -> None: events.append(('pipe_data_received', fd, data)) + self.exit_maybe() def pipe_connection_lost(self, fd, exc) -> None: - events.append('pipe_connection_lost') + events.append(('pipe_connection_lost', fd)) + self.exit_maybe() def process_exited(self) -> None: events.append('process_exited') - self.exit_future.set_result(True) + self.exit_maybe() + + def exit_maybe(self): + # Only exit when we got all expected events + if len(events) >= len(expected): + self.exit_future.set_result(True) async def main() -> None: loop = asyncio.get_running_loop() @@ -777,15 +831,24 @@ async def main() -> None: sys.executable, '-c', code, stdin=None) await exit_future transport.close() - self.assertEqual(events, [ - ('pipe_data_received', 1, b'stdout'), - ('pipe_data_received', 2, b'stderr'), - 'pipe_connection_lost', - 'pipe_connection_lost', - 'process_exited', - ]) - self.loop.run_until_complete(main()) + return events + + events = self.loop.run_until_complete(main()) + + # First, make sure that we received all events + self.assertSetEqual(set(events), set(expected)) + + # Second, check order of pipe events per file descriptor + per_fd_events = {fd: [] for fd in fds} + for event in events: + if event == 'process_exited': + continue + name, fd = event[:2] + per_fd_events[fd].append(name) + + for fd in fds: + self.assertEqual(per_fd_events[fd], per_fd_expected, (fd, events)) def test_subprocess_communicate_stdout(self): # See https://github.com/python/cpython/issues/100133 diff --git a/Lib/test/test_asyncio/test_timeouts.py b/Lib/test/test_asyncio/test_timeouts.py index 8b6b9a1fea0be8..e9b59b953518b3 100644 --- a/Lib/test/test_asyncio/test_timeouts.py +++ b/Lib/test/test_asyncio/test_timeouts.py @@ -46,7 +46,6 @@ async def test_nested_timeouts(self): self.assertTrue(cm2.expired()) async def test_waiter_cancelled(self): - loop = asyncio.get_running_loop() cancelled = False with self.assertRaises(TimeoutError): async with asyncio.timeout(0.01): @@ -59,39 +58,26 @@ async def test_waiter_cancelled(self): async def test_timeout_not_called(self): loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout(10) as cm: await asyncio.sleep(0.01) t1 = loop.time() self.assertFalse(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertGreater(cm.when(), t1) async def test_timeout_disabled(self): - loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout(None) as cm: await asyncio.sleep(0.01) - t1 = loop.time() self.assertFalse(cm.expired()) self.assertIsNone(cm.when()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) async def test_timeout_at_disabled(self): - loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout_at(None) as cm: await asyncio.sleep(0.01) - t1 = loop.time() self.assertFalse(cm.expired()) self.assertIsNone(cm.when()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) async def test_timeout_zero(self): loop = asyncio.get_running_loop() @@ -101,8 +87,6 @@ async def test_timeout_zero(self): await asyncio.sleep(10) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 <= cm.when() <= t1) async def test_timeout_zero_sleep_zero(self): @@ -113,8 +97,6 @@ async def test_timeout_zero_sleep_zero(self): await asyncio.sleep(0) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 <= cm.when() <= t1) async def test_timeout_in_the_past_sleep_zero(self): @@ -125,8 +107,6 @@ async def test_timeout_in_the_past_sleep_zero(self): await asyncio.sleep(0) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 >= cm.when() <= t1) async def test_foreign_exception_passed(self): diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index cdf3eaac68af15..d2c8cba6acfa31 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -4,6 +4,7 @@ import errno import io import multiprocessing +from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests import os import pathlib import signal @@ -11,9 +12,12 @@ import stat import sys import threading +import time import unittest from unittest import mock import warnings + +from test import support from test.support import os_helper from test.support import socket_helper from test.support import wait_process @@ -1901,6 +1905,8 @@ async def test_fork_not_share_event_loop(self): @hashlib_helper.requires_hashdigest('md5') def test_fork_signal_handling(self): + self.addCleanup(multiprocessing_cleanup_tests) + # Sending signal to the forked process should not affect the parent # process ctx = multiprocessing.get_context('fork') @@ -1911,8 +1917,14 @@ def test_fork_signal_handling(self): parent_handled = manager.Event() def child_main(): - signal.signal(signal.SIGTERM, lambda *args: child_handled.set()) + def on_sigterm(*args): + child_handled.set() + sys.exit() + + signal.signal(signal.SIGTERM, on_sigterm) child_started.set() + while True: + time.sleep(1) async def main(): loop = asyncio.get_running_loop() @@ -1922,7 +1934,7 @@ async def main(): process.start() child_started.wait() os.kill(process.pid, signal.SIGTERM) - process.join() + process.join(timeout=support.SHORT_TIMEOUT) async def func(): await asyncio.sleep(0.1) @@ -1933,11 +1945,14 @@ async def func(): asyncio.run(main()) + child_handled.wait(timeout=support.SHORT_TIMEOUT) self.assertFalse(parent_handled.is_set()) self.assertTrue(child_handled.is_set()) @hashlib_helper.requires_hashdigest('md5') def test_fork_asyncio_run(self): + self.addCleanup(multiprocessing_cleanup_tests) + ctx = multiprocessing.get_context('fork') manager = ctx.Manager() self.addCleanup(manager.shutdown) @@ -1955,6 +1970,8 @@ async def child_main(): @hashlib_helper.requires_hashdigest('md5') def test_fork_asyncio_subprocess(self): + self.addCleanup(multiprocessing_cleanup_tests) + ctx = multiprocessing.get_context('fork') manager = ctx.Manager() self.addCleanup(manager.shutdown) diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index d5c02ba4a01df9..d52f32534a0cfe 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -1,6 +1,7 @@ import asyncio import unittest import time +from test import support def tearDownModule(): @@ -65,17 +66,12 @@ async def test_wait_for_timeout_less_then_0_or_0_future_done(self): fut = loop.create_future() fut.set_result('done') - t0 = loop.time() ret = await asyncio.wait_for(fut, 0) - t1 = loop.time() self.assertEqual(ret, 'done') self.assertTrue(fut.done()) - self.assertLess(t1 - t0, 0.1) async def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): - loop = asyncio.get_running_loop() - foo_started = False async def foo(): @@ -83,12 +79,9 @@ async def foo(): foo_started = True with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(foo(), 0) - t1 = loop.time() self.assertEqual(foo_started, False) - self.assertLess(t1 - t0, 0.1) async def test_wait_for_timeout_less_then_0_or_0(self): loop = asyncio.get_running_loop() @@ -112,25 +105,21 @@ async def foo(): await started with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(fut, timeout) - t1 = loop.time() self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) self.assertEqual(foo_running, False) - self.assertLess(t1 - t0, 0.1) async def test_wait_for(self): - loop = asyncio.get_running_loop() foo_running = None async def foo(): nonlocal foo_running foo_running = True try: - await asyncio.sleep(10) + await asyncio.sleep(support.LONG_TIMEOUT) finally: foo_running = False return 'done' @@ -138,13 +127,10 @@ async def foo(): fut = asyncio.create_task(foo()) with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(fut, 0.1) - t1 = loop.time() self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) - self.assertLess(t1 - t0, 0.5) self.assertEqual(foo_running, False) async def test_wait_for_blocking(self): diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index a36119a8004f9d..6e6c90a247b291 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -163,29 +163,25 @@ def test_wait_for_handle(self): # Wait for unset event with 0.5s timeout; # result should be False at timeout - fut = self.loop._proactor.wait_for_handle(event, 0.5) + timeout = 0.5 + fut = self.loop._proactor.wait_for_handle(event, timeout) start = self.loop.time() done = self.loop.run_until_complete(fut) elapsed = self.loop.time() - start self.assertEqual(done, False) self.assertFalse(fut.result()) - # bpo-31008: Tolerate only 450 ms (at least 500 ms expected), - # because of bad clock resolution on Windows - self.assertTrue(0.45 <= elapsed <= 0.9, elapsed) + self.assertGreaterEqual(elapsed, timeout - test_utils.CLOCK_RES) _overlapped.SetEvent(event) # Wait for set event; # result should be True immediately fut = self.loop._proactor.wait_for_handle(event, 10) - start = self.loop.time() done = self.loop.run_until_complete(fut) - elapsed = self.loop.time() - start self.assertEqual(done, True) self.assertTrue(fut.result()) - self.assertTrue(0 <= elapsed < 0.3, elapsed) # asyncio issue #195: cancelling a done _WaitHandleFuture # must not crash @@ -199,11 +195,8 @@ def test_wait_for_handle_cancel(self): # CancelledError should be raised immediately fut = self.loop._proactor.wait_for_handle(event, 10) fut.cancel() - start = self.loop.time() with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(fut) - elapsed = self.loop.time() - start - self.assertTrue(0 <= elapsed < 0.1, elapsed) # asyncio issue #195: cancelling a _WaitHandleFuture twice # must not crash diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py index 6dee5bb33b2560..e1101bf42eb24e 100644 --- a/Lib/test/test_asyncio/utils.py +++ b/Lib/test/test_asyncio/utils.py @@ -36,21 +36,26 @@ from test.support import threading_helper -def data_file(filename): - if hasattr(support, 'TEST_HOME_DIR'): - fullname = os.path.join(support.TEST_HOME_DIR, filename) - if os.path.isfile(fullname): - return fullname - fullname = os.path.join(os.path.dirname(__file__), '..', filename) +# Use the maximum known clock resolution (gh-75191, gh-110088): Windows +# GetTickCount64() has a resolution of 15.6 ms. Use 20 ms to tolerate rounding +# issues. +CLOCK_RES = 0.020 + + +def data_file(*filename): + fullname = os.path.join(support.TEST_HOME_DIR, *filename) + if os.path.isfile(fullname): + return fullname + fullname = os.path.join(os.path.dirname(__file__), '..', *filename) if os.path.isfile(fullname): return fullname - raise FileNotFoundError(filename) + raise FileNotFoundError(os.path.join(filename)) -ONLYCERT = data_file('ssl_cert.pem') -ONLYKEY = data_file('ssl_key.pem') -SIGNED_CERTFILE = data_file('keycert3.pem') -SIGNING_CA = data_file('pycacert.pem') +ONLYCERT = data_file('certdata', 'ssl_cert.pem') +ONLYKEY = data_file('certdata', 'ssl_key.pem') +SIGNED_CERTFILE = data_file('certdata', 'keycert3.pem') +SIGNING_CA = data_file('certdata', 'pycacert.pem') PEERCERT = { 'OCSP': ('http://testca.pythontest.net/testca/ocsp/',), 'caIssuers': ('http://testca.pythontest.net/testca/pycacert.cer',), diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 0b69864751d83d..47e5832d311bd1 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -19,7 +19,7 @@ class AuditTest(unittest.TestCase): maxDiff = None @support.requires_subprocess() - def do_test(self, *args): + def run_test_in_subprocess(self, *args): with subprocess.Popen( [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], encoding="utf-8", @@ -27,27 +27,26 @@ def do_test(self, *args): stderr=subprocess.PIPE, ) as p: p.wait() - sys.stdout.writelines(p.stdout) - sys.stderr.writelines(p.stderr) - if p.returncode: - self.fail("".join(p.stderr)) + return p, p.stdout.read(), p.stderr.read() - @support.requires_subprocess() - def run_python(self, *args): + def do_test(self, *args): + proc, stdout, stderr = self.run_test_in_subprocess(*args) + + sys.stdout.write(stdout) + sys.stderr.write(stderr) + if proc.returncode: + self.fail(stderr) + + def run_python(self, *args, expect_stderr=False): events = [] - with subprocess.Popen( - [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], - encoding="utf-8", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) as p: - p.wait() - sys.stderr.writelines(p.stderr) - return ( - p.returncode, - [line.strip().partition(" ") for line in p.stdout], - "".join(p.stderr), - ) + proc, stdout, stderr = self.run_test_in_subprocess(*args) + if not expect_stderr or support.verbose: + sys.stderr.write(stderr) + return ( + proc.returncode, + [line.strip().partition(" ") for line in stdout.splitlines()], + stderr, + ) def test_basic(self): self.do_test("test_basic") @@ -256,6 +255,39 @@ def test_not_in_gc(self): if returncode: self.fail(stderr) + def test_time(self): + returncode, events, stderr = self.run_python("test_time", "print") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + + actual = [(ev[0], ev[2]) for ev in events] + expected = [("time.sleep", "0"), + ("time.sleep", "0.0625"), + ("time.sleep", "-1")] + + self.assertEqual(actual, expected) + + def test_time_fail(self): + returncode, events, stderr = self.run_python("test_time", "fail", + expect_stderr=True) + self.assertNotEqual(returncode, 0) + self.assertIn('hook failed', stderr.splitlines()[-1]) + + def test_sys_monitoring_register_callback(self): + returncode, events, stderr = self.run_python("test_sys_monitoring_register_callback") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [("sys.monitoring.register_callback", "(None,)")] + + self.assertEqual(actual, expected) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index a2d7d0293ce1ae..ef744f6b97259c 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -5,6 +5,7 @@ import array import re from test.support import bigmemtest, _1G, _4G +from test.support.hypothesis_helper import hypothesis # Note: "*_hex" functions are aliases for "(un)hexlify" @@ -27,6 +28,14 @@ class BinASCIITest(unittest.TestCase): def setUp(self): self.data = self.type2test(self.rawdata) + def assertConversion(self, original, converted, restored, **kwargs): + self.assertIsInstance(original, bytes) + self.assertIsInstance(converted, bytes) + self.assertIsInstance(restored, bytes) + if converted: + self.assertLess(max(converted), 128) + self.assertEqual(original, restored, msg=f'{self.type2test=} {kwargs=}') + def test_exceptions(self): # Check module exceptions self.assertTrue(issubclass(binascii.Error, Exception)) @@ -52,9 +61,7 @@ def test_returned_value(self): self.fail("{}/{} conversion raises {!r}".format(fb, fa, err)) self.assertEqual(res, raw, "{}/{} conversion: " "{!r} != {!r}".format(fb, fa, res, raw)) - self.assertIsInstance(res, bytes) - self.assertIsInstance(a, bytes) - self.assertLess(max(a), 128) + self.assertConversion(raw, a, res) self.assertIsInstance(binascii.crc_hqx(raw, 0), int) self.assertIsInstance(binascii.crc32(raw), int) @@ -222,6 +229,15 @@ def test_uu(self): with self.assertRaises(TypeError): binascii.b2a_uu(b"", True) + @hypothesis.given( + binary=hypothesis.strategies.binary(max_size=45), + backtick=hypothesis.strategies.booleans(), + ) + def test_b2a_roundtrip(self, binary, backtick): + converted = binascii.b2a_uu(self.type2test(binary), backtick=backtick) + restored = binascii.a2b_uu(self.type2test(converted)) + self.assertConversion(binary, converted, restored, backtick=backtick) + def test_crc_hqx(self): crc = binascii.crc_hqx(self.type2test(b"Test the CRC-32 of"), 0) crc = binascii.crc_hqx(self.type2test(b" this string."), crc) @@ -259,6 +275,12 @@ def test_hex(self): self.assertEqual(binascii.hexlify(self.type2test(s)), t) self.assertEqual(binascii.unhexlify(self.type2test(t)), u) + @hypothesis.given(binary=hypothesis.strategies.binary()) + def test_hex_roundtrip(self, binary): + converted = binascii.hexlify(self.type2test(binary)) + restored = binascii.unhexlify(self.type2test(converted)) + self.assertConversion(binary, converted, restored) + def test_hex_separator(self): """Test that hexlify and b2a_hex are binary versions of bytes.hex.""" # Logic of separators is tested in test_bytes.py. This checks that @@ -373,6 +395,21 @@ def test_qp(self): self.assertEqual(b2a_qp(type2test(b'a.\n')), b'a.\n') self.assertEqual(b2a_qp(type2test(b'.a')[:-1]), b'=2E') + @hypothesis.given( + binary=hypothesis.strategies.binary(), + quotetabs=hypothesis.strategies.booleans(), + istext=hypothesis.strategies.booleans(), + header=hypothesis.strategies.booleans(), + ) + def test_b2a_qp_a2b_qp_round_trip(self, binary, quotetabs, istext, header): + converted = binascii.b2a_qp( + self.type2test(binary), + quotetabs=quotetabs, istext=istext, header=header, + ) + restored = binascii.a2b_qp(self.type2test(converted), header=header) + self.assertConversion(binary, converted, restored, + quotetabs=quotetabs, istext=istext, header=header) + def test_empty_string(self): # A test for SF bug #1022953. Make sure SystemError is not raised. empty = self.type2test(b'') @@ -428,6 +465,15 @@ def test_b2a_base64_newline(self): self.assertEqual(binascii.b2a_base64(b, newline=False), b'aGVsbG8=') + @hypothesis.given( + binary=hypothesis.strategies.binary(), + newline=hypothesis.strategies.booleans(), + ) + def test_base64_roundtrip(self, binary, newline): + converted = binascii.b2a_base64(self.type2test(binary), newline=newline) + restored = binascii.a2b_base64(self.type2test(converted)) + self.assertConversion(binary, converted, restored, newline=newline) + class ArrayBinASCIITest(BinASCIITest): def type2test(self, s): diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index b679d2e8a01f92..72a06d6af450e3 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -1029,6 +1029,7 @@ def match(req, flag): ndim=ndim, shape=shape, strides=strides, lst=lst, sliced=sliced) + @support.requires_resource('cpu') def test_ndarray_getbuf(self): requests = ( # distinct flags @@ -2760,6 +2761,7 @@ def iter_roundtrip(ex, m, items, fmt): m = memoryview(ex) iter_roundtrip(ex, m, items, fmt) + @support.requires_resource('cpu') def test_memoryview_cast_1D_ND(self): # Cast between C-contiguous buffers. At least one buffer must # be 1D, at least one format must be 'c', 'b' or 'B'. diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index f5a5c037f1bf1b..b7966f8f03875b 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -369,16 +369,17 @@ def f(): """doc""" (1, False, 'doc', False, False), (2, False, None, False, False)] for optval, *expected in values: + with self.subTest(optval=optval): # test both direct compilation and compilation via AST - codeobjs = [] - codeobjs.append(compile(codestr, "", "exec", optimize=optval)) - tree = ast.parse(codestr) - codeobjs.append(compile(tree, "", "exec", optimize=optval)) - for code in codeobjs: - ns = {} - exec(code, ns) - rv = ns['f']() - self.assertEqual(rv, tuple(expected)) + codeobjs = [] + codeobjs.append(compile(codestr, "", "exec", optimize=optval)) + tree = ast.parse(codestr) + codeobjs.append(compile(tree, "", "exec", optimize=optval)) + for code in codeobjs: + ns = {} + exec(code, ns) + rv = ns['f']() + self.assertEqual(rv, tuple(expected)) def test_compile_top_level_await_no_coro(self): """Make sure top level non-await codes get the correct coroutine flags""" @@ -517,6 +518,30 @@ def test_compile_async_generator(self): exec(co, glob) self.assertEqual(type(glob['ticker']()), AsyncGeneratorType) + def test_compile_ast(self): + args = ("a*(1+2)", "f.py", "exec") + raw = compile(*args, flags = ast.PyCF_ONLY_AST).body[0] + opt1 = compile(*args, flags = ast.PyCF_OPTIMIZED_AST).body[0] + opt2 = compile(ast.parse(args[0]), *args[1:], flags = ast.PyCF_OPTIMIZED_AST).body[0] + + for tree in (raw, opt1, opt2): + self.assertIsInstance(tree.value, ast.BinOp) + self.assertIsInstance(tree.value.op, ast.Mult) + self.assertIsInstance(tree.value.left, ast.Name) + self.assertEqual(tree.value.left.id, 'a') + + raw_right = raw.value.right # expect BinOp(1, '+', 2) + self.assertIsInstance(raw_right, ast.BinOp) + self.assertIsInstance(raw_right.left, ast.Constant) + self.assertEqual(raw_right.left.value, 1) + self.assertIsInstance(raw_right.right, ast.Constant) + self.assertEqual(raw_right.right.value, 2) + + for opt in [opt1, opt2]: + opt_right = opt.value.right # expect Constant(3) + self.assertIsInstance(opt_right, ast.Constant) + self.assertEqual(opt_right.value, 3) + def test_delattr(self): sys.spam = 1 delattr(sys, 'spam') @@ -927,6 +952,7 @@ def test_filter_pickle(self): f2 = filter(filter_char, "abcdeabcde") self.check_iter_pickle(f1, list(f2), proto) + @support.requires_resource('cpu') def test_filter_dealloc(self): # Tests recursive deallocation of nested filter objects using the # thrashcan mechanism. See gh-102356 for more details. @@ -2177,8 +2203,6 @@ def _run_child(self, child, terminal_input): if pid == 0: # Child try: - # Make sure we don't get stuck if there's a problem - signal.alarm(2) os.close(r) with open(w, "w") as wpipe: child(wpipe) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 7c62b722059d12..afd506f07520d8 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -1354,7 +1354,7 @@ def do_tests(setitem): except ValueError: pass try: - setitem(b, 0, None) + setitem(b, 0, object()) self.fail("Didn't raise TypeError") except TypeError: pass diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index e4dd7fc2100b62..1f0b9adc3698b4 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -721,10 +721,10 @@ def testEOFError(self): @bigmemtest(size=_4G + 100, memuse=3.3) def testDecompress4G(self, size): # "Test BZ2Decompressor.decompress() with >4GiB input" - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - data = block * (size // blocksize + 1) + data = block * ((size-1) // blocksize + 1) compressed = bz2.compress(data) bz2d = BZ2Decompressor() decompressed = bz2d.decompress(compressed) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 0df084e17a3c8e..1f9ffc5e9a5c33 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -3,11 +3,13 @@ from test import support from test.support.script_helper import assert_python_ok, assert_python_failure -import time -import locale -import sys +import contextlib import datetime +import io +import locale import os +import sys +import time # From https://en.wikipedia.org/wiki/Leap_year_starting_on_Saturday result_0_02_text = """\ @@ -549,26 +551,92 @@ def test_months(self): # verify it "acts like a sequence" in two forms of iteration self.assertEqual(value[::-1], list(reversed(value))) - def test_locale_calendars(self): + def test_locale_text_calendar(self): + try: + cal = calendar.LocaleTextCalendar(locale='') + local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) + local_month = cal.formatmonthname(2010, 10, 10) + except locale.Error: + # cannot set the system default locale -- skip rest of test + raise unittest.SkipTest('cannot set the system default locale') + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) + self.assertIsInstance(local_month, str) + self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) + self.assertGreaterEqual(len(local_month), 10) + + cal = calendar.LocaleTextCalendar(locale=None) + local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) + local_month = cal.formatmonthname(2010, 10, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) + self.assertIsInstance(local_month, str) + self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) + self.assertGreaterEqual(len(local_month), 10) + + cal = calendar.LocaleTextCalendar(locale='C') + local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) + local_month = cal.formatmonthname(2010, 10, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) + self.assertIsInstance(local_month, str) + self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) + self.assertGreaterEqual(len(local_month), 10) + + def test_locale_html_calendar(self): + try: + cal = calendar.LocaleHTMLCalendar(locale='') + local_weekday = cal.formatweekday(1) + local_month = cal.formatmonthname(2010, 10) + except locale.Error: + # cannot set the system default locale -- skip rest of test + raise unittest.SkipTest('cannot set the system default locale') + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_month, str) + + cal = calendar.LocaleHTMLCalendar(locale=None) + local_weekday = cal.formatweekday(1) + local_month = cal.formatmonthname(2010, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_month, str) + + cal = calendar.LocaleHTMLCalendar(locale='C') + local_weekday = cal.formatweekday(1) + local_month = cal.formatmonthname(2010, 10) + self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_month, str) + + def test_locale_calendars_reset_locale_properly(self): # ensure that Locale{Text,HTML}Calendar resets the locale properly # (it is still not thread-safe though) old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) try: cal = calendar.LocaleTextCalendar(locale='') local_weekday = cal.formatweekday(1, 10) + local_weekday_abbr = cal.formatweekday(1, 3) local_month = cal.formatmonthname(2010, 10, 10) except locale.Error: # cannot set the system default locale -- skip rest of test raise unittest.SkipTest('cannot set the system default locale') self.assertIsInstance(local_weekday, str) + self.assertIsInstance(local_weekday_abbr, str) self.assertIsInstance(local_month, str) self.assertEqual(len(local_weekday), 10) + self.assertEqual(len(local_weekday_abbr), 3) self.assertGreaterEqual(len(local_month), 10) + cal = calendar.LocaleHTMLCalendar(locale='') local_weekday = cal.formatweekday(1) local_month = cal.formatmonthname(2010, 10) self.assertIsInstance(local_weekday, str) self.assertIsInstance(local_month, str) + new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) @@ -589,6 +657,21 @@ def test_locale_calendar_formatweekday(self): except locale.Error: raise unittest.SkipTest('cannot set the en_US locale') + def test_locale_calendar_formatmonthname(self): + try: + # formatmonthname uses the same month names regardless of the width argument. + cal = calendar.LocaleTextCalendar(locale='en_US') + # For too short widths, a full name (with year) is used. + self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=False), "June") + self.assertEqual(cal.formatmonthname(2022, 6, 2, withyear=True), "June 2022") + self.assertEqual(cal.formatmonthname(2022, 6, 3, withyear=False), "June") + self.assertEqual(cal.formatmonthname(2022, 6, 3, withyear=True), "June 2022") + # For long widths, a centered name is used. + self.assertEqual(cal.formatmonthname(2022, 6, 10, withyear=False), " June ") + self.assertEqual(cal.formatmonthname(2022, 6, 15, withyear=True), " June 2022 ") + except locale.Error: + raise unittest.SkipTest('cannot set the en_US locale') + def test_locale_html_calendar_custom_css_class_month_name(self): try: cal = calendar.LocaleHTMLCalendar(locale='') @@ -847,46 +930,104 @@ def conv(s): return s.replace('\n', os.linesep).encode() class CommandLineTestCase(unittest.TestCase): - def run_ok(self, *args): + def setUp(self): + self.runners = [self.run_cli_ok, self.run_cmd_ok] + + @contextlib.contextmanager + def captured_stdout_with_buffer(self): + orig_stdout = sys.stdout + buffer = io.BytesIO() + sys.stdout = io.TextIOWrapper(buffer) + try: + yield sys.stdout + finally: + sys.stdout.flush() + sys.stdout.buffer.seek(0) + sys.stdout = orig_stdout + + @contextlib.contextmanager + def captured_stderr_with_buffer(self): + orig_stderr = sys.stderr + buffer = io.BytesIO() + sys.stderr = io.TextIOWrapper(buffer) + try: + yield sys.stderr + finally: + sys.stderr.flush() + sys.stderr.buffer.seek(0) + sys.stderr = orig_stderr + + def run_cli_ok(self, *args): + with self.captured_stdout_with_buffer() as stdout: + calendar.main(args) + return stdout.buffer.read() + + def run_cmd_ok(self, *args): return assert_python_ok('-m', 'calendar', *args)[1] - def assertFailure(self, *args): + def assertCLIFails(self, *args): + with self.captured_stderr_with_buffer() as stderr: + self.assertRaises(SystemExit, calendar.main, args) + stderr = stderr.buffer.read() + self.assertIn(b'usage:', stderr) + return stderr + + def assertCmdFails(self, *args): rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) self.assertIn(b'usage:', stderr) self.assertEqual(rc, 2) + return rc, stdout, stderr + + def assertFailure(self, *args): + self.assertCLIFails(*args) + self.assertCmdFails(*args) def test_help(self): - stdout = self.run_ok('-h') + stdout = self.run_cmd_ok('-h') self.assertIn(b'usage:', stdout) self.assertIn(b'calendar.py', stdout) self.assertIn(b'--help', stdout) + # special case: stdout but sys.exit() + with self.captured_stdout_with_buffer() as output: + self.assertRaises(SystemExit, calendar.main, ['-h']) + output = output.buffer.read() + self.assertIn(b'usage:', output) + self.assertIn(b'--help', output) + def test_illegal_arguments(self): self.assertFailure('-z') self.assertFailure('spam') self.assertFailure('2004', 'spam') + self.assertFailure('2004', '1', 'spam') + self.assertFailure('2004', '1', '1') + self.assertFailure('2004', '1', '1', 'spam') self.assertFailure('-t', 'html', '2004', '1') def test_output_current_year(self): - stdout = self.run_ok() - year = datetime.datetime.now().year - self.assertIn((' %s' % year).encode(), stdout) - self.assertIn(b'January', stdout) - self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout) + for run in self.runners: + output = run() + year = datetime.datetime.now().year + self.assertIn(conv(' %s' % year), output) + self.assertIn(b'January', output) + self.assertIn(b'Mo Tu We Th Fr Sa Su', output) def test_output_year(self): - stdout = self.run_ok('2004') - self.assertEqual(stdout, conv(result_2004_text)) + for run in self.runners: + output = run('2004') + self.assertEqual(output, conv(result_2004_text)) def test_output_month(self): - stdout = self.run_ok('2004', '1') - self.assertEqual(stdout, conv(result_2004_01_text)) + for run in self.runners: + output = run('2004', '1') + self.assertEqual(output, conv(result_2004_01_text)) def test_option_encoding(self): self.assertFailure('-e') self.assertFailure('--encoding') - stdout = self.run_ok('--encoding', 'utf-16-le', '2004') - self.assertEqual(stdout, result_2004_text.encode('utf-16-le')) + for run in self.runners: + output = run('--encoding', 'utf-16-le', '2004') + self.assertEqual(output, result_2004_text.encode('utf-16-le')) def test_option_locale(self): self.assertFailure('-L') @@ -904,66 +1045,75 @@ def test_option_locale(self): locale.setlocale(locale.LC_TIME, oldlocale) except (locale.Error, ValueError): self.skipTest('cannot set the system default locale') - stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004') - self.assertIn('2004'.encode(enc), stdout) + for run in self.runners: + for type in ('text', 'html'): + output = run( + '--type', type, '--locale', lang, '--encoding', enc, '2004' + ) + self.assertIn('2004'.encode(enc), output) def test_option_width(self): self.assertFailure('-w') self.assertFailure('--width') self.assertFailure('-w', 'spam') - stdout = self.run_ok('--width', '3', '2004') - self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout) + for run in self.runners: + output = run('--width', '3', '2004') + self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', output) def test_option_lines(self): self.assertFailure('-l') self.assertFailure('--lines') self.assertFailure('-l', 'spam') - stdout = self.run_ok('--lines', '2', '2004') - self.assertIn(conv('December\n\nMo Tu We'), stdout) + for run in self.runners: + output = run('--lines', '2', '2004') + self.assertIn(conv('December\n\nMo Tu We'), output) def test_option_spacing(self): self.assertFailure('-s') self.assertFailure('--spacing') self.assertFailure('-s', 'spam') - stdout = self.run_ok('--spacing', '8', '2004') - self.assertIn(b'Su Mo', stdout) + for run in self.runners: + output = run('--spacing', '8', '2004') + self.assertIn(b'Su Mo', output) def test_option_months(self): self.assertFailure('-m') self.assertFailure('--month') self.assertFailure('-m', 'spam') - stdout = self.run_ok('--months', '1', '2004') - self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout) + for run in self.runners: + output = run('--months', '1', '2004') + self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), output) def test_option_type(self): self.assertFailure('-t') self.assertFailure('--type') self.assertFailure('-t', 'spam') - stdout = self.run_ok('--type', 'text', '2004') - self.assertEqual(stdout, conv(result_2004_text)) - stdout = self.run_ok('--type', 'html', '2004') - self.assertEqual(stdout[:6], b'Calendar for 2004', stdout) + for run in self.runners: + output = run('--type', 'text', '2004') + self.assertEqual(output, conv(result_2004_text)) + output = run('--type', 'html', '2004') + self.assertEqual(output[:6], b'Calendar for 2004', output) def test_html_output_current_year(self): - stdout = self.run_ok('--type', 'html') - year = datetime.datetime.now().year - self.assertIn(('Calendar for %s' % year).encode(), - stdout) - self.assertIn(b'January', - stdout) + for run in self.runners: + output = run('--type', 'html') + year = datetime.datetime.now().year + self.assertIn(('Calendar for %s' % year).encode(), output) + self.assertIn(b'January', output) def test_html_output_year_encoding(self): - stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004') - self.assertEqual(stdout, - result_2004_html.format(**default_format).encode('ascii')) + for run in self.runners: + output = run('-t', 'html', '--encoding', 'ascii', '2004') + self.assertEqual(output, result_2004_html.format(**default_format).encode('ascii')) def test_html_output_year_css(self): self.assertFailure('-t', 'html', '-c') self.assertFailure('-t', 'html', '--css') - stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004') - self.assertIn(b'', stdout) + for run in self.runners: + output = run('-t', 'html', '--css', 'custom.css', '2004') + self.assertIn(b'', output) class MiscTestCase(unittest.TestCase): diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 09a531f8cc627b..b1c78d7136fc9b 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,5 +1,5 @@ import unittest -from test.support import cpython_only, requires_limited_api +from test.support import cpython_only, requires_limited_api, skip_on_s390x try: import _testcapi except ImportError: @@ -65,7 +65,8 @@ def test_varargs3(self): self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False) def test_varargs1min(self): - msg = r"get expected at least 1 argument, got 0" + msg = (r"get\(\) takes at least 1 argument \(0 given\)|" + r"get expected at least 1 argument, got 0") self.assertRaisesRegex(TypeError, msg, {}.get) msg = r"expected 1 argument, got 0" @@ -76,11 +77,13 @@ def test_varargs2min(self): self.assertRaisesRegex(TypeError, msg, getattr) def test_varargs1max(self): - msg = r"input expected at most 1 argument, got 2" + msg = (r"input\(\) takes at most 1 argument \(2 given\)|" + r"input expected at most 1 argument, got 2") self.assertRaisesRegex(TypeError, msg, input, 1, 2) def test_varargs2max(self): - msg = r"get expected at most 2 arguments, got 3" + msg = (r"get\(\) takes at most 2 arguments \(3 given\)|" + r"get expected at most 2 arguments, got 3") self.assertRaisesRegex(TypeError, msg, {}.get, 1, 2, 3) def test_varargs1_kw(self): @@ -96,7 +99,7 @@ def test_varargs3_kw(self): self.assertRaisesRegex(TypeError, msg, bool, x=2) def test_varargs4_kw(self): - msg = r"^list[.]index\(\) takes no keyword arguments$" + msg = r"^(list[.])?index\(\) takes no keyword arguments$" self.assertRaisesRegex(TypeError, msg, [].index, x=2) def test_varargs5_kw(self): @@ -915,9 +918,78 @@ def test_multiple_values(self): with self.check_raises_type_error(msg): A().method_two_args("x", "y", x="oops") +@cpython_only +class TestErrorMessagesSuggestions(unittest.TestCase): + @contextlib.contextmanager + def check_suggestion_includes(self, message): + with self.assertRaises(TypeError) as cm: + yield + self.assertIn(f"Did you mean '{message}'?", str(cm.exception)) + + @contextlib.contextmanager + def check_suggestion_not_pressent(self): + with self.assertRaises(TypeError) as cm: + yield + self.assertNotIn("Did you mean", str(cm.exception)) + + def test_unexpected_keyword_suggestion_valid_positions(self): + def foo(blech=None, /, aaa=None, *args, late1=None): + pass + + cases = [ + ("blach", None), + ("aa", "aaa"), + ("orgs", None), + ("late11", "late1"), + ] + + for keyword, suggestion in cases: + with self.subTest(keyword): + ctx = self.check_suggestion_includes(suggestion) if suggestion else self.check_suggestion_not_pressent() + with ctx: + foo(**{keyword:None}) + + def test_unexpected_keyword_suggestion_kinds(self): + + def substitution(noise=None, more_noise=None, a = None, blech = None): + pass + + def elimination(noise = None, more_noise = None, a = None, blch = None): + pass + + def addition(noise = None, more_noise = None, a = None, bluchin = None): + pass + + def substitution_over_elimination(blach = None, bluc = None): + pass + + def substitution_over_addition(blach = None, bluchi = None): + pass + + def elimination_over_addition(bluc = None, blucha = None): + pass + + def case_change_over_substitution(BLuch=None, Luch = None, fluch = None): + pass + + for func, suggestion in [ + (addition, "bluchin"), + (substitution, "blech"), + (elimination, "blch"), + (addition, "bluchin"), + (substitution_over_elimination, "blach"), + (substitution_over_addition, "blach"), + (elimination_over_addition, "bluc"), + (case_change_over_substitution, "BLuch"), + ]: + with self.subTest(suggestion): + with self.check_suggestion_includes(suggestion): + func(bluch=None) + @cpython_only class TestRecursion(unittest.TestCase): + @skip_on_s390x def test_super_deep(self): def recurse(n): diff --git a/Lib/test/test_capi/check_config.py b/Lib/test/test_capi/check_config.py index aaedd82f39af50..eb99ae16f2b69e 100644 --- a/Lib/test/test_capi/check_config.py +++ b/Lib/test/test_capi/check_config.py @@ -12,7 +12,7 @@ def import_singlephase(): try: import _testsinglephase except ImportError: - sys.modules.pop('_testsinglephase') + sys.modules.pop('_testsinglephase', None) return False else: del sys.modules['_testsinglephase'] diff --git a/Lib/test/test_capi/test_abstract.py b/Lib/test/test_capi/test_abstract.py new file mode 100644 index 00000000000000..eeaef60a8b47b5 --- /dev/null +++ b/Lib/test/test_capi/test_abstract.py @@ -0,0 +1,822 @@ +import unittest +from collections import OrderedDict +import _testcapi + + +NULL = None + +class TestObject: + @property + def evil(self): + raise RuntimeError('do not get evil') + @evil.setter + def evil(self, value): + raise RuntimeError('do not set evil') + @evil.deleter + def evil(self): + raise RuntimeError('do not del evil') + +class ProxyGetItem: + def __init__(self, obj): + self.obj = obj + def __getitem__(self, key): + return self.obj[key] + +class ProxySetItem: + def __init__(self, obj): + self.obj = obj + def __setitem__(self, key, value): + self.obj[key] = value + +class ProxyDelItem: + def __init__(self, obj): + self.obj = obj + def __delitem__(self, key): + del self.obj[key] + +def gen(): + yield 'a' + yield 'b' + yield 'c' + + +class CAPITest(unittest.TestCase): + + def test_object_getattr(self): + xgetattr = _testcapi.object_getattr + obj = TestObject() + obj.a = 11 + setattr(obj, '\U0001f40d', 22) + self.assertEqual(xgetattr(obj, 'a'), 11) + self.assertRaises(AttributeError, xgetattr, obj, 'b') + self.assertEqual(xgetattr(obj, '\U0001f40d'), 22) + + self.assertRaises(RuntimeError, xgetattr, obj, 'evil') + self.assertRaises(TypeError, xgetattr, obj, 1) + # CRASHES xgetattr(obj, NULL) + # CRASHES xgetattr(NULL, 'a') + + def test_object_getattrstring(self): + getattrstring = _testcapi.object_getattrstring + obj = TestObject() + obj.a = 11 + setattr(obj, '\U0001f40d', 22) + self.assertEqual(getattrstring(obj, b'a'), 11) + self.assertRaises(AttributeError, getattrstring, obj, b'b') + self.assertEqual(getattrstring(obj, '\U0001f40d'.encode()), 22) + + self.assertRaises(RuntimeError, getattrstring, obj, b'evil') + self.assertRaises(UnicodeDecodeError, getattrstring, obj, b'\xff') + # CRASHES getattrstring(obj, NULL) + # CRASHES getattrstring(NULL, b'a') + + def test_object_getoptionalattr(self): + getoptionalattr = _testcapi.object_getoptionalattr + obj = TestObject() + obj.a = 11 + setattr(obj, '\U0001f40d', 22) + self.assertEqual(getoptionalattr(obj, 'a'), 11) + self.assertIs(getoptionalattr(obj, 'b'), AttributeError) + self.assertEqual(getoptionalattr(obj, '\U0001f40d'), 22) + + self.assertRaises(RuntimeError, getoptionalattr, obj, 'evil') + self.assertRaises(TypeError, getoptionalattr, obj, 1) + # CRASHES getoptionalattr(obj, NULL) + # CRASHES getoptionalattr(NULL, 'a') + + def test_object_getoptionalattrstring(self): + getoptionalattrstring = _testcapi.object_getoptionalattrstring + obj = TestObject() + obj.a = 11 + setattr(obj, '\U0001f40d', 22) + self.assertEqual(getoptionalattrstring(obj, b'a'), 11) + self.assertIs(getoptionalattrstring(obj, b'b'), AttributeError) + self.assertEqual(getoptionalattrstring(obj, '\U0001f40d'.encode()), 22) + + self.assertRaises(RuntimeError, getoptionalattrstring, obj, b'evil') + self.assertRaises(UnicodeDecodeError, getoptionalattrstring, obj, b'\xff') + # CRASHES getoptionalattrstring(obj, NULL) + # CRASHES getoptionalattrstring(NULL, b'a') + + def test_object_hasattr(self): + xhasattr = _testcapi.object_hasattr + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + self.assertTrue(xhasattr(obj, 'a')) + self.assertFalse(xhasattr(obj, 'b')) + self.assertTrue(xhasattr(obj, '\U0001f40d')) + + self.assertFalse(xhasattr(obj, 'evil')) + self.assertFalse(xhasattr(obj, 1)) + # CRASHES xhasattr(obj, NULL) + # CRASHES xhasattr(NULL, 'a') + + def test_object_hasattrstring(self): + hasattrstring = _testcapi.object_hasattrstring + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + self.assertTrue(hasattrstring(obj, b'a')) + self.assertFalse(hasattrstring(obj, b'b')) + self.assertTrue(hasattrstring(obj, '\U0001f40d'.encode())) + + self.assertFalse(hasattrstring(obj, b'evil')) + self.assertFalse(hasattrstring(obj, b'\xff')) + # CRASHES hasattrstring(obj, NULL) + # CRASHES hasattrstring(NULL, b'a') + + def test_object_hasattrwitherror(self): + xhasattr = _testcapi.object_hasattrwitherror + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + self.assertTrue(xhasattr(obj, 'a')) + self.assertFalse(xhasattr(obj, 'b')) + self.assertTrue(xhasattr(obj, '\U0001f40d')) + + self.assertRaises(RuntimeError, xhasattr, obj, 'evil') + self.assertRaises(TypeError, xhasattr, obj, 1) + # CRASHES xhasattr(obj, NULL) + # CRASHES xhasattr(NULL, 'a') + + def test_object_hasattrstringwitherror(self): + hasattrstring = _testcapi.object_hasattrstringwitherror + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + self.assertTrue(hasattrstring(obj, b'a')) + self.assertFalse(hasattrstring(obj, b'b')) + self.assertTrue(hasattrstring(obj, '\U0001f40d'.encode())) + + self.assertRaises(RuntimeError, hasattrstring, obj, b'evil') + self.assertRaises(UnicodeDecodeError, hasattrstring, obj, b'\xff') + # CRASHES hasattrstring(obj, NULL) + # CRASHES hasattrstring(NULL, b'a') + + def test_object_setattr(self): + xsetattr = _testcapi.object_setattr + obj = TestObject() + xsetattr(obj, 'a', 5) + self.assertEqual(obj.a, 5) + xsetattr(obj, '\U0001f40d', 8) + self.assertEqual(getattr(obj, '\U0001f40d'), 8) + + # PyObject_SetAttr(obj, attr_name, NULL) removes the attribute + xsetattr(obj, 'a', NULL) + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, xsetattr, obj, 'b', NULL) + self.assertRaises(RuntimeError, xsetattr, obj, 'evil', NULL) + + self.assertRaises(RuntimeError, xsetattr, obj, 'evil', 'good') + self.assertRaises(AttributeError, xsetattr, 42, 'a', 5) + self.assertRaises(TypeError, xsetattr, obj, 1, 5) + # CRASHES xsetattr(obj, NULL, 5) + # CRASHES xsetattr(NULL, 'a', 5) + + def test_object_setattrstring(self): + setattrstring = _testcapi.object_setattrstring + obj = TestObject() + setattrstring(obj, b'a', 5) + self.assertEqual(obj.a, 5) + setattrstring(obj, '\U0001f40d'.encode(), 8) + self.assertEqual(getattr(obj, '\U0001f40d'), 8) + + # PyObject_SetAttrString(obj, attr_name, NULL) removes the attribute + setattrstring(obj, b'a', NULL) + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, setattrstring, obj, b'b', NULL) + self.assertRaises(RuntimeError, setattrstring, obj, b'evil', NULL) + + self.assertRaises(RuntimeError, setattrstring, obj, b'evil', 'good') + self.assertRaises(AttributeError, setattrstring, 42, b'a', 5) + self.assertRaises(TypeError, setattrstring, obj, 1, 5) + self.assertRaises(UnicodeDecodeError, setattrstring, obj, b'\xff', 5) + # CRASHES setattrstring(obj, NULL, 5) + # CRASHES setattrstring(NULL, b'a', 5) + + def test_object_delattr(self): + xdelattr = _testcapi.object_delattr + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + xdelattr(obj, 'a') + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, xdelattr, obj, 'b') + xdelattr(obj, '\U0001f40d') + self.assertFalse(hasattr(obj, '\U0001f40d')) + + self.assertRaises(AttributeError, xdelattr, 42, 'numerator') + self.assertRaises(RuntimeError, xdelattr, obj, 'evil') + self.assertRaises(TypeError, xdelattr, obj, 1) + # CRASHES xdelattr(obj, NULL) + # CRASHES xdelattr(NULL, 'a') + + def test_object_delattrstring(self): + delattrstring = _testcapi.object_delattrstring + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + delattrstring(obj, b'a') + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, delattrstring, obj, b'b') + delattrstring(obj, '\U0001f40d'.encode()) + self.assertFalse(hasattr(obj, '\U0001f40d')) + + self.assertRaises(AttributeError, delattrstring, 42, b'numerator') + self.assertRaises(RuntimeError, delattrstring, obj, b'evil') + self.assertRaises(UnicodeDecodeError, delattrstring, obj, b'\xff') + # CRASHES delattrstring(obj, NULL) + # CRASHES delattrstring(NULL, b'a') + + + def test_mapping_check(self): + check = _testcapi.mapping_check + self.assertTrue(check({1: 2})) + self.assertTrue(check([1, 2])) + self.assertTrue(check((1, 2))) + self.assertTrue(check('abc')) + self.assertTrue(check(b'abc')) + self.assertFalse(check(42)) + self.assertFalse(check(object())) + self.assertFalse(check(NULL)) + + def test_mapping_size(self): + for size in _testcapi.mapping_size, _testcapi.mapping_length: + self.assertEqual(size({1: 2}), 1) + self.assertEqual(size([1, 2]), 2) + self.assertEqual(size((1, 2)), 2) + self.assertEqual(size('abc'), 3) + self.assertEqual(size(b'abc'), 3) + + self.assertRaises(TypeError, size, 42) + self.assertRaises(TypeError, size, object()) + self.assertRaises(SystemError, size, NULL) + + def test_object_getitem(self): + getitem = _testcapi.object_getitem + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertRaises(KeyError, getitem, dct, 'b') + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = ProxyGetItem(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertRaises(KeyError, getitem, dct2, 'b') + + self.assertEqual(getitem(['a', 'b', 'c'], 1), 'b') + + self.assertRaises(TypeError, getitem, 42, 'a') + self.assertRaises(TypeError, getitem, {}, []) # unhashable + self.assertRaises(SystemError, getitem, {}, NULL) + self.assertRaises(IndexError, getitem, [], 1) + self.assertRaises(TypeError, getitem, [], 'a') + self.assertRaises(SystemError, getitem, NULL, 'a') + + def test_mapping_getitemstring(self): + getitemstring = _testcapi.mapping_getitemstring + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertRaises(KeyError, getitemstring, dct, b'b') + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) + + dct2 = ProxyGetItem(dct) + self.assertEqual(getitemstring(dct2, b'a'), 1) + self.assertRaises(KeyError, getitemstring, dct2, b'b') + + self.assertRaises(TypeError, getitemstring, 42, b'a') + self.assertRaises(UnicodeDecodeError, getitemstring, {}, b'\xff') + self.assertRaises(SystemError, getitemstring, {}, NULL) + self.assertRaises(TypeError, getitemstring, [], b'a') + self.assertRaises(SystemError, getitemstring, NULL, b'a') + + def test_mapping_getoptionalitem(self): + getitem = _testcapi.mapping_getoptionalitem + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertEqual(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = ProxyGetItem(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertEqual(getitem(dct2, 'b'), KeyError) + + self.assertEqual(getitem(['a', 'b', 'c'], 1), 'b') + + self.assertRaises(TypeError, getitem, 42, 'a') + self.assertRaises(TypeError, getitem, {}, []) # unhashable + self.assertRaises(IndexError, getitem, [], 1) + self.assertRaises(TypeError, getitem, [], 'a') + # CRASHES getitem({}, NULL) + # CRASHES getitem(NULL, 'a') + + def test_mapping_getoptionalitemstring(self): + getitemstring = _testcapi.mapping_getoptionalitemstring + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertEqual(getitemstring(dct, b'b'), KeyError) + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) + + dct2 = ProxyGetItem(dct) + self.assertEqual(getitemstring(dct2, b'a'), 1) + self.assertEqual(getitemstring(dct2, b'b'), KeyError) + + self.assertRaises(TypeError, getitemstring, 42, b'a') + self.assertRaises(UnicodeDecodeError, getitemstring, {}, b'\xff') + self.assertRaises(SystemError, getitemstring, {}, NULL) + self.assertRaises(TypeError, getitemstring, [], b'a') + # CRASHES getitemstring(NULL, b'a') + + def test_mapping_haskey(self): + haskey = _testcapi.mapping_haskey + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(haskey(dct, 'a')) + self.assertFalse(haskey(dct, 'b')) + self.assertTrue(haskey(dct, '\U0001f40d')) + + dct2 = ProxyGetItem(dct) + self.assertTrue(haskey(dct2, 'a')) + self.assertFalse(haskey(dct2, 'b')) + + self.assertTrue(haskey(['a', 'b', 'c'], 1)) + + self.assertFalse(haskey(42, 'a')) + self.assertFalse(haskey({}, [])) # unhashable + self.assertFalse(haskey({}, NULL)) + self.assertFalse(haskey([], 1)) + self.assertFalse(haskey([], 'a')) + self.assertFalse(haskey(NULL, 'a')) + + def test_mapping_haskeystring(self): + haskeystring = _testcapi.mapping_haskeystring + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(haskeystring(dct, b'a')) + self.assertFalse(haskeystring(dct, b'b')) + self.assertTrue(haskeystring(dct, '\U0001f40d'.encode())) + + dct2 = ProxyGetItem(dct) + self.assertTrue(haskeystring(dct2, b'a')) + self.assertFalse(haskeystring(dct2, b'b')) + + self.assertFalse(haskeystring(42, b'a')) + self.assertFalse(haskeystring({}, b'\xff')) + self.assertFalse(haskeystring({}, NULL)) + self.assertFalse(haskeystring([], b'a')) + self.assertFalse(haskeystring(NULL, b'a')) + + def test_mapping_haskeywitherror(self): + haskey = _testcapi.mapping_haskeywitherror + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(haskey(dct, 'a')) + self.assertFalse(haskey(dct, 'b')) + self.assertTrue(haskey(dct, '\U0001f40d')) + + dct2 = ProxyGetItem(dct) + self.assertTrue(haskey(dct2, 'a')) + self.assertFalse(haskey(dct2, 'b')) + + self.assertTrue(haskey(['a', 'b', 'c'], 1)) + + self.assertRaises(TypeError, haskey, 42, 'a') + self.assertRaises(TypeError, haskey, {}, []) # unhashable + self.assertRaises(IndexError, haskey, [], 1) + self.assertRaises(TypeError, haskey, [], 'a') + + # CRASHES haskey({}, NULL)) + # CRASHES haskey(NULL, 'a')) + + def test_mapping_haskeystringwitherror(self): + haskeystring = _testcapi.mapping_haskeystringwitherror + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(haskeystring(dct, b'a')) + self.assertFalse(haskeystring(dct, b'b')) + self.assertTrue(haskeystring(dct, '\U0001f40d'.encode())) + + dct2 = ProxyGetItem(dct) + self.assertTrue(haskeystring(dct2, b'a')) + self.assertFalse(haskeystring(dct2, b'b')) + + self.assertRaises(TypeError, haskeystring, 42, b'a') + self.assertRaises(UnicodeDecodeError, haskeystring, {}, b'\xff') + self.assertRaises(SystemError, haskeystring, {}, NULL) + self.assertRaises(TypeError, haskeystring, [], b'a') + # CRASHES haskeystring(NULL, b'a') + + def test_object_setitem(self): + setitem = _testcapi.object_setitem + dct = {} + setitem(dct, 'a', 5) + self.assertEqual(dct, {'a': 5}) + setitem(dct, '\U0001f40d', 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct = {} + dct2 = ProxySetItem(dct) + setitem(dct2, 'a', 5) + self.assertEqual(dct, {'a': 5}) + + lst = ['a', 'b', 'c'] + setitem(lst, 1, 'x') + self.assertEqual(lst, ['a', 'x', 'c']) + + self.assertRaises(TypeError, setitem, 42, 'a', 5) + self.assertRaises(TypeError, setitem, {}, [], 5) # unhashable + self.assertRaises(SystemError, setitem, {}, NULL, 5) + self.assertRaises(SystemError, setitem, {}, 'a', NULL) + self.assertRaises(IndexError, setitem, [], 1, 5) + self.assertRaises(TypeError, setitem, [], 'a', 5) + self.assertRaises(TypeError, setitem, (), 1, 5) + self.assertRaises(SystemError, setitem, NULL, 'a', 5) + + def test_mapping_setitemstring(self): + setitemstring = _testcapi.mapping_setitemstring + dct = {} + setitemstring(dct, b'a', 5) + self.assertEqual(dct, {'a': 5}) + setitemstring(dct, '\U0001f40d'.encode(), 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct = {} + dct2 = ProxySetItem(dct) + setitemstring(dct2, b'a', 5) + self.assertEqual(dct, {'a': 5}) + + self.assertRaises(TypeError, setitemstring, 42, b'a', 5) + self.assertRaises(UnicodeDecodeError, setitemstring, {}, b'\xff', 5) + self.assertRaises(SystemError, setitemstring, {}, NULL, 5) + self.assertRaises(SystemError, setitemstring, {}, b'a', NULL) + self.assertRaises(TypeError, setitemstring, [], b'a', 5) + self.assertRaises(SystemError, setitemstring, NULL, b'a', 5) + + def test_object_delitem(self): + for delitem in _testcapi.object_delitem, _testcapi.mapping_delitem: + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitem(dct, 'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitem, dct, 'b') + delitem(dct, '\U0001f40d') + self.assertEqual(dct, {'c': 2}) + + dct = {'a': 1, 'c': 2} + dct2 = ProxyDelItem(dct) + delitem(dct2, 'a') + self.assertEqual(dct, {'c': 2}) + self.assertRaises(KeyError, delitem, dct2, 'b') + + lst = ['a', 'b', 'c'] + delitem(lst, 1) + self.assertEqual(lst, ['a', 'c']) + + self.assertRaises(TypeError, delitem, 42, 'a') + self.assertRaises(TypeError, delitem, {}, []) # unhashable + self.assertRaises(SystemError, delitem, {}, NULL) + self.assertRaises(IndexError, delitem, [], 1) + self.assertRaises(TypeError, delitem, [], 'a') + self.assertRaises(SystemError, delitem, NULL, 'a') + + def test_mapping_delitemstring(self): + delitemstring = _testcapi.mapping_delitemstring + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitemstring(dct, b'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitemstring, dct, b'b') + delitemstring(dct, '\U0001f40d'.encode()) + self.assertEqual(dct, {'c': 2}) + + dct = {'a': 1, 'c': 2} + dct2 = ProxyDelItem(dct) + delitemstring(dct2, b'a') + self.assertEqual(dct, {'c': 2}) + self.assertRaises(KeyError, delitemstring, dct2, b'b') + + self.assertRaises(TypeError, delitemstring, 42, b'a') + self.assertRaises(UnicodeDecodeError, delitemstring, {}, b'\xff') + self.assertRaises(SystemError, delitemstring, {}, NULL) + self.assertRaises(TypeError, delitemstring, [], b'a') + self.assertRaises(SystemError, delitemstring, NULL, b'a') + + def test_mapping_keys_valuesitems(self): + class Mapping1(dict): + def keys(self): + return list(super().keys()) + def values(self): + return list(super().values()) + def items(self): + return list(super().items()) + class Mapping2(dict): + def keys(self): + return tuple(super().keys()) + def values(self): + return tuple(super().values()) + def items(self): + return tuple(super().items()) + dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} + + for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(), + dict_obj, OrderedDict(dict_obj), + Mapping1(dict_obj), Mapping2(dict_obj)]: + self.assertListEqual(_testcapi.mapping_keys(mapping), + list(mapping.keys())) + self.assertListEqual(_testcapi.mapping_values(mapping), + list(mapping.values())) + self.assertListEqual(_testcapi.mapping_items(mapping), + list(mapping.items())) + + def test_mapping_keys_valuesitems_bad_arg(self): + self.assertRaises(AttributeError, _testcapi.mapping_keys, object()) + self.assertRaises(AttributeError, _testcapi.mapping_values, object()) + self.assertRaises(AttributeError, _testcapi.mapping_items, object()) + self.assertRaises(AttributeError, _testcapi.mapping_keys, []) + self.assertRaises(AttributeError, _testcapi.mapping_values, []) + self.assertRaises(AttributeError, _testcapi.mapping_items, []) + self.assertRaises(SystemError, _testcapi.mapping_keys, NULL) + self.assertRaises(SystemError, _testcapi.mapping_values, NULL) + self.assertRaises(SystemError, _testcapi.mapping_items, NULL) + + class BadMapping: + def keys(self): + return None + def values(self): + return None + def items(self): + return None + bad_mapping = BadMapping() + self.assertRaises(TypeError, _testcapi.mapping_keys, bad_mapping) + self.assertRaises(TypeError, _testcapi.mapping_values, bad_mapping) + self.assertRaises(TypeError, _testcapi.mapping_items, bad_mapping) + + def test_sequence_check(self): + check = _testcapi.sequence_check + self.assertFalse(check({1: 2})) + self.assertTrue(check([1, 2])) + self.assertTrue(check((1, 2))) + self.assertTrue(check('abc')) + self.assertTrue(check(b'abc')) + self.assertFalse(check(42)) + self.assertFalse(check(object())) + # CRASHES check(NULL) + + def test_sequence_size(self): + for size in _testcapi.sequence_size, _testcapi.sequence_length: + self.assertEqual(size([1, 2]), 2) + self.assertEqual(size((1, 2)), 2) + self.assertEqual(size('abc'), 3) + self.assertEqual(size(b'abc'), 3) + + self.assertRaises(TypeError, size, {}) + self.assertRaises(TypeError, size, 42) + self.assertRaises(TypeError, size, object()) + self.assertRaises(SystemError, size, NULL) + + def test_sequence_getitem(self): + getitem = _testcapi.sequence_getitem + lst = ['a', 'b', 'c'] + self.assertEqual(getitem(lst, 1), 'b') + self.assertEqual(getitem(lst, -1), 'c') + self.assertRaises(IndexError, getitem, lst, 3) + + self.assertRaises(TypeError, getitem, 42, 1) + self.assertRaises(TypeError, getitem, {}, 1) + self.assertRaises(SystemError, getitem, NULL, 1) + + def test_sequence_concat(self): + concat = _testcapi.sequence_concat + self.assertEqual(concat(['a', 'b'], [1, 2]), ['a', 'b', 1, 2]) + self.assertEqual(concat(('a', 'b'), (1, 2)), ('a', 'b', 1, 2)) + + self.assertRaises(TypeError, concat, [], ()) + self.assertRaises(TypeError, concat, (), []) + self.assertRaises(TypeError, concat, [], 42) + self.assertRaises(TypeError, concat, 42, []) + self.assertRaises(TypeError, concat, 42, 43) + self.assertRaises(SystemError, concat, [], NULL) + self.assertRaises(SystemError, concat, NULL, []) + + def test_sequence_repeat(self): + repeat = _testcapi.sequence_repeat + self.assertEqual(repeat(['a', 'b'], 2), ['a', 'b', 'a', 'b']) + self.assertEqual(repeat(('a', 'b'), 2), ('a', 'b', 'a', 'b')) + self.assertEqual(repeat(['a', 'b'], 0), []) + self.assertEqual(repeat(['a', 'b'], -1), []) + + self.assertRaises(TypeError, repeat, set(), 2) + self.assertRaises(TypeError, repeat, 42, 2) + self.assertRaises(SystemError, repeat, NULL, 2) + + def test_sequence_inplaceconcat(self): + inplaceconcat = _testcapi.sequence_inplaceconcat + lst = ['a', 'b'] + res = inplaceconcat(lst, [1, 2]) + self.assertEqual(res, ['a', 'b', 1, 2]) + self.assertIs(res, lst) + lst = ['a', 'b'] + res = inplaceconcat(lst, (1, 2)) + self.assertEqual(res, ['a', 'b', 1, 2]) + self.assertIs(res, lst) + self.assertEqual(inplaceconcat(('a', 'b'), (1, 2)), ('a', 'b', 1, 2)) + + self.assertRaises(TypeError, inplaceconcat, (), []) + self.assertRaises(TypeError, inplaceconcat, [], 42) + self.assertRaises(TypeError, inplaceconcat, 42, []) + self.assertRaises(TypeError, inplaceconcat, 42, 43) + self.assertRaises(SystemError, inplaceconcat, [], NULL) + self.assertRaises(SystemError, inplaceconcat, NULL, []) + + def test_sequence_inplacerepeat(self): + inplacerepeat = _testcapi.sequence_inplacerepeat + lst = ['a', 'b'] + res = inplacerepeat(lst, 2) + self.assertEqual(res, ['a', 'b', 'a', 'b']) + self.assertIs(res, lst) + self.assertEqual(inplacerepeat(('a', 'b'), 2), ('a', 'b', 'a', 'b')) + self.assertEqual(inplacerepeat(['a', 'b'], 0), []) + self.assertEqual(inplacerepeat(['a', 'b'], -1), []) + + self.assertRaises(TypeError, inplacerepeat, set(), 2) + self.assertRaises(TypeError, inplacerepeat, 42, 2) + self.assertRaises(SystemError, inplacerepeat, NULL, 2) + + def test_sequence_setitem(self): + setitem = _testcapi.sequence_setitem + lst = ['a', 'b', 'c'] + setitem(lst, 1, 'x') + self.assertEqual(lst, ['a', 'x', 'c']) + setitem(lst, -1, 'y') + self.assertEqual(lst, ['a', 'x', 'y']) + + setitem(lst, 0, NULL) + self.assertEqual(lst, ['x', 'y']) + self.assertRaises(IndexError, setitem, lst, 3, 'x') + + self.assertRaises(TypeError, setitem, 42, 1, 'x') + self.assertRaises(TypeError, setitem, {}, 1, 'x') + self.assertRaises(SystemError, setitem, NULL, 1, 'x') + + def test_sequence_delitem(self): + delitem = _testcapi.sequence_delitem + lst = ['a', 'b', 'c'] + delitem(lst, 1) + self.assertEqual(lst, ['a', 'c']) + delitem(lst, -1) + self.assertEqual(lst, ['a']) + self.assertRaises(IndexError, delitem, lst, 3) + + self.assertRaises(TypeError, delitem, 42, 1) + self.assertRaises(TypeError, delitem, {}, 1) + self.assertRaises(SystemError, delitem, NULL, 1) + + def test_sequence_setslice(self): + setslice = _testcapi.sequence_setslice + + # Correct case: + data = [1, 2, 3, 4, 5] + data_copy = data.copy() + + setslice(data, 1, 3, [8, 9]) + data_copy[1:3] = [8, 9] + self.assertEqual(data, data_copy) + self.assertEqual(data, [1, 8, 9, 4, 5]) + + # Custom class: + class Custom: + def __setitem__(self, index, value): + self.index = index + self.value = value + + c = Custom() + setslice(c, 0, 5, 'abc') + self.assertEqual(c.index, slice(0, 5)) + self.assertEqual(c.value, 'abc') + + # Immutable sequences must raise: + bad_seq1 = (1, 2, 3, 4) + self.assertRaises(TypeError, setslice, bad_seq1, 1, 3, (8, 9)) + self.assertEqual(bad_seq1, (1, 2, 3, 4)) + + bad_seq2 = 'abcd' + self.assertRaises(TypeError, setslice, bad_seq2, 1, 3, 'xy') + self.assertEqual(bad_seq2, 'abcd') + + # Not a sequence: + self.assertRaises(TypeError, setslice, object(), 1, 3, 'xy') + self.assertRaises(SystemError, setslice, NULL, 1, 3, 'xy') + + data_copy = data.copy() + setslice(data_copy, 1, 3, NULL) + self.assertEqual(data_copy, [1, 4, 5]) + + def test_sequence_delslice(self): + delslice = _testcapi.sequence_delslice + + # Correct case: + data = [1, 2, 3, 4, 5] + data_copy = data.copy() + + delslice(data, 1, 3) + del data_copy[1:3] + self.assertEqual(data, data_copy) + self.assertEqual(data, [1, 4, 5]) + + # Custom class: + class Custom: + def __delitem__(self, index): + self.index = index + + c = Custom() + delslice(c, 0, 5) + self.assertEqual(c.index, slice(0, 5)) + + # Immutable sequences must raise: + bad_seq1 = (1, 2, 3, 4) + self.assertRaises(TypeError, delslice, bad_seq1, 1, 3) + self.assertEqual(bad_seq1, (1, 2, 3, 4)) + + bad_seq2 = 'abcd' + self.assertRaises(TypeError, delslice, bad_seq2, 1, 3) + self.assertEqual(bad_seq2, 'abcd') + + # Not a sequence: + self.assertRaises(TypeError, delslice, object(), 1, 3) + self.assertRaises(SystemError, delslice, NULL, 1, 3) + + mapping = {1: 'a', 2: 'b', 3: 'c'} + self.assertRaises(KeyError, delslice, mapping, 1, 3) + self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) + + def test_sequence_count(self): + count = _testcapi.sequence_count + + lst = ['a', 'b', 'a'] + self.assertEqual(count(lst, 'a'), 2) + self.assertEqual(count(lst, 'c'), 0) + self.assertEqual(count(iter(lst), 'a'), 2) + self.assertEqual(count(iter(lst), 'c'), 0) + self.assertEqual(count({'a': 2}, 'a'), 1) + + self.assertRaises(TypeError, count, 42, 'a') + self.assertRaises(SystemError, count, [], NULL) + self.assertRaises(SystemError, count, [1], NULL) + self.assertRaises(SystemError, count, NULL, 'a') + + def test_sequence_contains(self): + contains = _testcapi.sequence_contains + + lst = ['a', 'b', 'a'] + self.assertEqual(contains(lst, 'a'), 1) + self.assertEqual(contains(lst, 'c'), 0) + self.assertEqual(contains(iter(lst), 'a'), 1) + self.assertEqual(contains(iter(lst), 'c'), 0) + self.assertEqual(contains({'a': 2}, 'a'), 1) + + # XXX Only for empty sequences. Should be SystemError? + self.assertEqual(contains([], NULL), 0) + + self.assertRaises(TypeError, contains, 42, 'a') + self.assertRaises(SystemError, contains, [1], NULL) + # CRASHES contains({}, NULL) + # CRASHES contains(set(), NULL) + # CRASHES contains(NULL, 'a') + + def test_sequence_index(self): + index = _testcapi.sequence_index + + lst = ['a', 'b', 'a'] + self.assertEqual(index(lst, 'a'), 0) + self.assertEqual(index(lst, 'b'), 1) + self.assertRaises(ValueError, index, lst, 'c') + self.assertEqual(index(iter(lst), 'a'), 0) + self.assertEqual(index(iter(lst), 'b'), 1) + self.assertRaises(ValueError, index, iter(lst), 'c') + dct = {'a': 2, 'b': 3} + self.assertEqual(index(dct, 'a'), 0) + self.assertEqual(index(dct, 'b'), 1) + self.assertRaises(ValueError, index, dct, 'c') + + self.assertRaises(TypeError, index, 42, 'a') + self.assertRaises(SystemError, index, [], NULL) + self.assertRaises(SystemError, index, [1], NULL) + self.assertRaises(SystemError, index, NULL, 'a') + + def test_sequence_list(self): + xlist = _testcapi.sequence_list + self.assertEqual(xlist(['a', 'b', 'c']), ['a', 'b', 'c']) + self.assertEqual(xlist(('a', 'b', 'c')), ['a', 'b', 'c']) + self.assertEqual(xlist(iter(['a', 'b', 'c'])), ['a', 'b', 'c']) + self.assertEqual(xlist(gen()), ['a', 'b', 'c']) + + self.assertRaises(TypeError, xlist, 42) + self.assertRaises(SystemError, xlist, NULL) + + def test_sequence_tuple(self): + xtuple = _testcapi.sequence_tuple + self.assertEqual(xtuple(['a', 'b', 'c']), ('a', 'b', 'c')) + self.assertEqual(xtuple(('a', 'b', 'c')), ('a', 'b', 'c')) + self.assertEqual(xtuple(iter(['a', 'b', 'c'])), ('a', 'b', 'c')) + self.assertEqual(xtuple(gen()), ('a', 'b', 'c')) + + self.assertRaises(TypeError, xtuple, 42) + self.assertRaises(SystemError, xtuple, NULL) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py new file mode 100644 index 00000000000000..11b2ca910707df --- /dev/null +++ b/Lib/test/test_capi/test_dict.py @@ -0,0 +1,426 @@ +import unittest +from collections import OrderedDict, UserDict +from types import MappingProxyType +import _testcapi + + +NULL = None +INVALID_UTF8 = b'\xff' + +class DictSubclass(dict): + def __getitem__(self, key): + raise RuntimeError('do not get evil') + def __setitem__(self, key, value): + raise RuntimeError('do not set evil') + def __delitem__(self, key): + raise RuntimeError('do not del evil') + +def gen(): + yield 'a' + yield 'b' + yield 'c' + + +class CAPITest(unittest.TestCase): + + def test_dict_check(self): + check = _testcapi.dict_check + self.assertTrue(check({1: 2})) + self.assertTrue(check(OrderedDict({1: 2}))) + self.assertFalse(check(UserDict({1: 2}))) + self.assertFalse(check([1, 2])) + self.assertFalse(check(object())) + #self.assertFalse(check(NULL)) + + def test_dict_checkexact(self): + check = _testcapi.dict_checkexact + self.assertTrue(check({1: 2})) + self.assertFalse(check(OrderedDict({1: 2}))) + self.assertFalse(check(UserDict({1: 2}))) + self.assertFalse(check([1, 2])) + self.assertFalse(check(object())) + #self.assertFalse(check(NULL)) + + def test_dict_new(self): + dict_new = _testcapi.dict_new + dct = dict_new() + self.assertEqual(dct, {}) + self.assertIs(type(dct), dict) + dct2 = dict_new() + self.assertIsNot(dct2, dct) + + def test_dictproxy_new(self): + dictproxy_new = _testcapi.dictproxy_new + for dct in {1: 2}, OrderedDict({1: 2}), UserDict({1: 2}): + proxy = dictproxy_new(dct) + self.assertIs(type(proxy), MappingProxyType) + self.assertEqual(proxy, dct) + with self.assertRaises(TypeError): + proxy[1] = 3 + self.assertEqual(proxy[1], 2) + dct[1] = 4 + self.assertEqual(proxy[1], 4) + + self.assertRaises(TypeError, dictproxy_new, []) + self.assertRaises(TypeError, dictproxy_new, 42) + # CRASHES dictproxy_new(NULL) + + def test_dict_copy(self): + copy = _testcapi.dict_copy + for dct in {1: 2}, OrderedDict({1: 2}): + dct_copy = copy(dct) + self.assertIs(type(dct_copy), dict) + self.assertEqual(dct_copy, dct) + + self.assertRaises(SystemError, copy, UserDict()) + self.assertRaises(SystemError, copy, []) + self.assertRaises(SystemError, copy, 42) + self.assertRaises(SystemError, copy, NULL) + + def test_dict_clear(self): + clear = _testcapi.dict_clear + dct = {1: 2} + clear(dct) + self.assertEqual(dct, {}) + + # NOTE: It is not safe to call it with OrderedDict. + + # Has no effect for non-dicts. + dct = UserDict({1: 2}) + clear(dct) + self.assertEqual(dct, {1: 2}) + lst = [1, 2] + clear(lst) + self.assertEqual(lst, [1, 2]) + clear(object()) + + # CRASHES? clear(NULL) + + def test_dict_size(self): + size = _testcapi.dict_size + self.assertEqual(size({1: 2}), 1) + self.assertEqual(size(OrderedDict({1: 2})), 1) + + self.assertRaises(SystemError, size, UserDict()) + self.assertRaises(SystemError, size, []) + self.assertRaises(SystemError, size, 42) + self.assertRaises(SystemError, size, object()) + self.assertRaises(SystemError, size, NULL) + + def test_dict_getitem(self): + getitem = _testcapi.dict_getitem + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertIs(getitem(dct2, 'b'), KeyError) + + self.assertIs(getitem({}, []), KeyError) # unhashable + self.assertIs(getitem(42, 'a'), KeyError) + self.assertIs(getitem([1], 0), KeyError) + # CRASHES getitem({}, NULL) + # CRASHES getitem(NULL, 'a') + + def test_dict_getitemstring(self): + getitemstring = _testcapi.dict_getitemstring + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertIs(getitemstring(dct, b'b'), KeyError) + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitemstring(dct2, b'a'), 1) + self.assertIs(getitemstring(dct2, b'b'), KeyError) + + self.assertIs(getitemstring({}, INVALID_UTF8), KeyError) + self.assertIs(getitemstring(42, b'a'), KeyError) + self.assertIs(getitemstring([], b'a'), KeyError) + # CRASHES getitemstring({}, NULL) + # CRASHES getitemstring(NULL, b'a') + + def test_dict_getitemref(self): + getitem = _testcapi.dict_getitemref + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertIs(getitem(dct2, 'b'), KeyError) + + self.assertRaises(SystemError, getitem, 42, 'a') + self.assertRaises(TypeError, getitem, {}, []) # unhashable + self.assertRaises(SystemError, getitem, [], 1) + self.assertRaises(SystemError, getitem, [], 'a') + # CRASHES getitem({}, NULL) + # CRASHES getitem(NULL, 'a') + + def test_dict_getitemstringref(self): + getitemstring = _testcapi.dict_getitemstringref + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertIs(getitemstring(dct, b'b'), KeyError) + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitemstring(dct2, b'a'), 1) + self.assertIs(getitemstring(dct2, b'b'), KeyError) + + self.assertRaises(SystemError, getitemstring, 42, b'a') + self.assertRaises(UnicodeDecodeError, getitemstring, {}, INVALID_UTF8) + self.assertRaises(SystemError, getitemstring, [], b'a') + # CRASHES getitemstring({}, NULL) + # CRASHES getitemstring(NULL, b'a') + + def test_dict_getitemwitherror(self): + getitem = _testcapi.dict_getitemwitherror + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertIs(getitem(dct2, 'b'), KeyError) + + self.assertRaises(SystemError, getitem, 42, 'a') + self.assertRaises(TypeError, getitem, {}, []) # unhashable + self.assertRaises(SystemError, getitem, [], 1) + self.assertRaises(SystemError, getitem, [], 'a') + # CRASHES getitem({}, NULL) + # CRASHES getitem(NULL, 'a') + + def test_dict_contains(self): + contains = _testcapi.dict_contains + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(contains(dct, 'a')) + self.assertFalse(contains(dct, 'b')) + self.assertTrue(contains(dct, '\U0001f40d')) + + dct2 = DictSubclass(dct) + self.assertTrue(contains(dct2, 'a')) + self.assertFalse(contains(dct2, 'b')) + + self.assertRaises(TypeError, contains, {}, []) # unhashable + # CRASHES contains({}, NULL) + # CRASHES contains(UserDict(), 'a') + # CRASHES contains(42, 'a') + # CRASHES contains(NULL, 'a') + + def test_dict_contains_string(self): + contains_string = _testcapi.dict_containsstring + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(contains_string(dct, b'a')) + self.assertFalse(contains_string(dct, b'b')) + self.assertTrue(contains_string(dct, '\U0001f40d'.encode())) + self.assertRaises(UnicodeDecodeError, contains_string, dct, INVALID_UTF8) + + dct2 = DictSubclass(dct) + self.assertTrue(contains_string(dct2, b'a')) + self.assertFalse(contains_string(dct2, b'b')) + + # CRASHES contains({}, NULL) + # CRASHES contains(NULL, b'a') + + def test_dict_setitem(self): + setitem = _testcapi.dict_setitem + dct = {} + setitem(dct, 'a', 5) + self.assertEqual(dct, {'a': 5}) + setitem(dct, '\U0001f40d', 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct2 = DictSubclass() + setitem(dct2, 'a', 5) + self.assertEqual(dct2, {'a': 5}) + + self.assertRaises(TypeError, setitem, {}, [], 5) # unhashable + self.assertRaises(SystemError, setitem, UserDict(), 'a', 5) + self.assertRaises(SystemError, setitem, [1], 0, 5) + self.assertRaises(SystemError, setitem, 42, 'a', 5) + # CRASHES setitem({}, NULL, 5) + # CRASHES setitem({}, 'a', NULL) + # CRASHES setitem(NULL, 'a', 5) + + def test_dict_setitemstring(self): + setitemstring = _testcapi.dict_setitemstring + dct = {} + setitemstring(dct, b'a', 5) + self.assertEqual(dct, {'a': 5}) + setitemstring(dct, '\U0001f40d'.encode(), 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct2 = DictSubclass() + setitemstring(dct2, b'a', 5) + self.assertEqual(dct2, {'a': 5}) + + self.assertRaises(UnicodeDecodeError, setitemstring, {}, INVALID_UTF8, 5) + self.assertRaises(SystemError, setitemstring, UserDict(), b'a', 5) + self.assertRaises(SystemError, setitemstring, 42, b'a', 5) + # CRASHES setitemstring({}, NULL, 5) + # CRASHES setitemstring({}, b'a', NULL) + # CRASHES setitemstring(NULL, b'a', 5) + + def test_dict_delitem(self): + delitem = _testcapi.dict_delitem + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitem(dct, 'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitem, dct, 'b') + delitem(dct, '\U0001f40d') + self.assertEqual(dct, {'c': 2}) + + dct2 = DictSubclass({'a': 1, 'c': 2}) + delitem(dct2, 'a') + self.assertEqual(dct2, {'c': 2}) + self.assertRaises(KeyError, delitem, dct2, 'b') + + self.assertRaises(TypeError, delitem, {}, []) # unhashable + self.assertRaises(SystemError, delitem, UserDict({'a': 1}), 'a') + self.assertRaises(SystemError, delitem, [1], 0) + self.assertRaises(SystemError, delitem, 42, 'a') + # CRASHES delitem({}, NULL) + # CRASHES delitem(NULL, 'a') + + def test_dict_delitemstring(self): + delitemstring = _testcapi.dict_delitemstring + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitemstring(dct, b'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitemstring, dct, b'b') + delitemstring(dct, '\U0001f40d'.encode()) + self.assertEqual(dct, {'c': 2}) + + dct2 = DictSubclass({'a': 1, 'c': 2}) + delitemstring(dct2, b'a') + self.assertEqual(dct2, {'c': 2}) + self.assertRaises(KeyError, delitemstring, dct2, b'b') + + self.assertRaises(UnicodeDecodeError, delitemstring, {}, INVALID_UTF8) + self.assertRaises(SystemError, delitemstring, UserDict({'a': 1}), b'a') + self.assertRaises(SystemError, delitemstring, 42, b'a') + # CRASHES delitemstring({}, NULL) + # CRASHES delitemstring(NULL, b'a') + + def test_dict_setdefault(self): + setdefault = _testcapi.dict_setdefault + dct = {} + self.assertEqual(setdefault(dct, 'a', 5), 5) + self.assertEqual(dct, {'a': 5}) + self.assertEqual(setdefault(dct, 'a', 8), 5) + self.assertEqual(dct, {'a': 5}) + + dct2 = DictSubclass() + self.assertEqual(setdefault(dct2, 'a', 5), 5) + self.assertEqual(dct2, {'a': 5}) + self.assertEqual(setdefault(dct2, 'a', 8), 5) + self.assertEqual(dct2, {'a': 5}) + + self.assertRaises(TypeError, setdefault, {}, [], 5) # unhashable + self.assertRaises(SystemError, setdefault, UserDict(), 'a', 5) + self.assertRaises(SystemError, setdefault, [1], 0, 5) + self.assertRaises(SystemError, setdefault, 42, 'a', 5) + # CRASHES setdefault({}, NULL, 5) + # CRASHES setdefault({}, 'a', NULL) + # CRASHES setdefault(NULL, 'a', 5) + + def test_mapping_keys_valuesitems(self): + class BadMapping(dict): + def keys(self): + return None + def values(self): + return None + def items(self): + return None + dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} + for mapping in [dict_obj, DictSubclass(dict_obj), BadMapping(dict_obj)]: + self.assertListEqual(_testcapi.dict_keys(mapping), + list(dict_obj.keys())) + self.assertListEqual(_testcapi.dict_values(mapping), + list(dict_obj.values())) + self.assertListEqual(_testcapi.dict_items(mapping), + list(dict_obj.items())) + + def test_dict_keys_valuesitems_bad_arg(self): + for mapping in UserDict(), [], object(): + self.assertRaises(SystemError, _testcapi.dict_keys, mapping) + self.assertRaises(SystemError, _testcapi.dict_values, mapping) + self.assertRaises(SystemError, _testcapi.dict_items, mapping) + + def test_dict_next(self): + dict_next = _testcapi.dict_next + self.assertIsNone(dict_next({}, 0)) + dct = {'a': 1, 'b': 2, 'c': 3} + pos = 0 + pairs = [] + while True: + res = dict_next(dct, pos) + if res is None: + break + rc, pos, key, value = res + self.assertEqual(rc, 1) + pairs.append((key, value)) + self.assertEqual(pairs, list(dct.items())) + + # CRASHES dict_next(NULL, 0) + + def test_dict_update(self): + update = _testcapi.dict_update + for cls1 in dict, DictSubclass: + for cls2 in dict, DictSubclass, UserDict: + dct = cls1({'a': 1, 'b': 2}) + update(dct, cls2({'b': 3, 'c': 4})) + self.assertEqual(dct, {'a': 1, 'b': 3, 'c': 4}) + + self.assertRaises(AttributeError, update, {}, []) + self.assertRaises(AttributeError, update, {}, 42) + self.assertRaises(SystemError, update, UserDict(), {}) + self.assertRaises(SystemError, update, 42, {}) + self.assertRaises(SystemError, update, {}, NULL) + self.assertRaises(SystemError, update, NULL, {}) + + def test_dict_merge(self): + merge = _testcapi.dict_merge + for cls1 in dict, DictSubclass: + for cls2 in dict, DictSubclass, UserDict: + dct = cls1({'a': 1, 'b': 2}) + merge(dct, cls2({'b': 3, 'c': 4}), 0) + self.assertEqual(dct, {'a': 1, 'b': 2, 'c': 4}) + dct = cls1({'a': 1, 'b': 2}) + merge(dct, cls2({'b': 3, 'c': 4}), 1) + self.assertEqual(dct, {'a': 1, 'b': 3, 'c': 4}) + + self.assertRaises(AttributeError, merge, {}, [], 0) + self.assertRaises(AttributeError, merge, {}, 42, 0) + self.assertRaises(SystemError, merge, UserDict(), {}, 0) + self.assertRaises(SystemError, merge, 42, {}, 0) + self.assertRaises(SystemError, merge, {}, NULL, 0) + self.assertRaises(SystemError, merge, NULL, {}, 0) + + def test_dict_mergefromseq2(self): + mergefromseq2 = _testcapi.dict_mergefromseq2 + for cls1 in dict, DictSubclass: + for cls2 in list, iter: + dct = cls1({'a': 1, 'b': 2}) + mergefromseq2(dct, cls2([('b', 3), ('c', 4)]), 0) + self.assertEqual(dct, {'a': 1, 'b': 2, 'c': 4}) + dct = cls1({'a': 1, 'b': 2}) + mergefromseq2(dct, cls2([('b', 3), ('c', 4)]), 1) + self.assertEqual(dct, {'a': 1, 'b': 3, 'c': 4}) + + self.assertRaises(ValueError, mergefromseq2, {}, [(1,)], 0) + self.assertRaises(ValueError, mergefromseq2, {}, [(1, 2, 3)], 0) + self.assertRaises(TypeError, mergefromseq2, {}, [1], 0) + self.assertRaises(TypeError, mergefromseq2, {}, 42, 0) + # CRASHES mergefromseq2(UserDict(), [], 0) + # CRASHES mergefromseq2(42, [], 0) + # CRASHES mergefromseq2({}, NULL, 0) + # CRASHES mergefromseq2(NULL, {}, 0) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_exceptions.py b/Lib/test/test_capi/test_exceptions.py index 118b575cba6df7..b96cc7922a0ee7 100644 --- a/Lib/test/test_capi/test_exceptions.py +++ b/Lib/test/test_capi/test_exceptions.py @@ -1,9 +1,12 @@ +import errno +import os import re import sys import unittest from test import support from test.support import import_helper +from test.support.os_helper import TESTFN, TESTFN_UNDECODABLE from test.support.script_helper import assert_python_failure from test.support.testcase import ExceptionIsLikeMixin @@ -12,6 +15,8 @@ # Skip this test if the _testcapi module isn't available. _testcapi = import_helper.import_module('_testcapi') +NULL = None + class Test_Exceptions(unittest.TestCase): def test_exception(self): @@ -189,6 +194,82 @@ def __repr__(self): self.assertEqual(exc.__notes__[0], 'Normalization failed: type=Broken args=') + def test_set_string(self): + """Test PyErr_SetString()""" + setstring = _testcapi.err_setstring + with self.assertRaises(ZeroDivisionError) as e: + setstring(ZeroDivisionError, b'error') + self.assertEqual(e.exception.args, ('error',)) + with self.assertRaises(ZeroDivisionError) as e: + setstring(ZeroDivisionError, 'помилка'.encode()) + self.assertEqual(e.exception.args, ('помилка',)) + + with self.assertRaises(UnicodeDecodeError): + setstring(ZeroDivisionError, b'\xff') + self.assertRaises(SystemError, setstring, list, b'error') + # CRASHES setstring(ZeroDivisionError, NULL) + # CRASHES setstring(NULL, b'error') + + def test_format(self): + """Test PyErr_Format()""" + import_helper.import_module('ctypes') + from ctypes import pythonapi, py_object, c_char_p, c_int + name = "PyErr_Format" + PyErr_Format = getattr(pythonapi, name) + PyErr_Format.argtypes = (py_object, c_char_p,) + PyErr_Format.restype = py_object + with self.assertRaises(ZeroDivisionError) as e: + PyErr_Format(ZeroDivisionError, b'%s %d', b'error', c_int(42)) + self.assertEqual(e.exception.args, ('error 42',)) + with self.assertRaises(ZeroDivisionError) as e: + PyErr_Format(ZeroDivisionError, b'%s', 'помилка'.encode()) + self.assertEqual(e.exception.args, ('помилка',)) + + with self.assertRaisesRegex(OverflowError, 'not in range'): + PyErr_Format(ZeroDivisionError, b'%c', c_int(-1)) + with self.assertRaisesRegex(ValueError, 'format string'): + PyErr_Format(ZeroDivisionError, b'\xff') + self.assertRaises(SystemError, PyErr_Format, list, b'error') + # CRASHES PyErr_Format(ZeroDivisionError, NULL) + # CRASHES PyErr_Format(py_object(), b'error') + + def test_setfromerrnowithfilename(self): + """Test PyErr_SetFromErrnoWithFilename()""" + setfromerrnowithfilename = _testcapi.err_setfromerrnowithfilename + ENOENT = errno.ENOENT + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, b'file') + self.assertEqual(e.exception.args, + (ENOENT, 'No such file or directory')) + self.assertEqual(e.exception.errno, ENOENT) + self.assertEqual(e.exception.filename, 'file') + + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, os.fsencode(TESTFN)) + self.assertEqual(e.exception.filename, TESTFN) + + if TESTFN_UNDECODABLE: + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, TESTFN_UNDECODABLE) + self.assertEqual(e.exception.filename, + os.fsdecode(TESTFN_UNDECODABLE)) + + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, NULL) + self.assertIsNone(e.exception.filename) + + with self.assertRaises(OSError) as e: + setfromerrnowithfilename(0, OSError, b'file') + self.assertEqual(e.exception.args, (0, 'Error')) + self.assertEqual(e.exception.errno, 0) + self.assertEqual(e.exception.filename, 'file') + + with self.assertRaises(ZeroDivisionError) as e: + setfromerrnowithfilename(ENOENT, ZeroDivisionError, b'file') + self.assertEqual(e.exception.args, + (ENOENT, 'No such file or directory', 'file')) + # CRASHES setfromerrnowithfilename(ENOENT, NULL, b'error') + class Test_PyUnstable_Exc_PrepReraiseStar(ExceptionIsLikeMixin, unittest.TestCase): diff --git a/Lib/test/test_capi/test_getargs.py b/Lib/test/test_capi/test_getargs.py index 01bc30779add73..7fc25f82597399 100644 --- a/Lib/test/test_capi/test_getargs.py +++ b/Lib/test/test_capi/test_getargs.py @@ -55,6 +55,8 @@ LLONG_MIN = -2**63 ULLONG_MAX = 2**64-1 +NULL = None + class Index: def __index__(self): return 99 @@ -1004,70 +1006,6 @@ def test_et_hash(self): buf = bytearray() self.assertRaises(ValueError, getargs_et_hash, 'abc\xe9', 'latin1', buf) - @support.requires_legacy_unicode_capi - def test_u(self): - from _testcapi import getargs_u - with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9') - with self.assertWarns(DeprecationWarning): - self.assertRaises(ValueError, getargs_u, 'nul:\0') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u, b'bytes') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u, bytearray(b'bytearray')) - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview')) - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u, None) - - @support.requires_legacy_unicode_capi - def test_u_hash(self): - from _testcapi import getargs_u_hash - with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_u_hash('abc\xe9'), 'abc\xe9') - with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_u_hash('nul:\0'), 'nul:\0') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u_hash, b'bytes') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u_hash, bytearray(b'bytearray')) - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview')) - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_u_hash, None) - - @support.requires_legacy_unicode_capi - def test_Z(self): - from _testcapi import getargs_Z - with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9') - with self.assertWarns(DeprecationWarning): - self.assertRaises(ValueError, getargs_Z, 'nul:\0') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_Z, b'bytes') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_Z, bytearray(b'bytearray')) - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview')) - with self.assertWarns(DeprecationWarning): - self.assertIsNone(getargs_Z(None)) - - @support.requires_legacy_unicode_capi - def test_Z_hash(self): - from _testcapi import getargs_Z_hash - with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_Z_hash('abc\xe9'), 'abc\xe9') - with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_Z_hash('nul:\0'), 'nul:\0') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_Z_hash, b'bytes') - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_Z_hash, bytearray(b'bytearray')) - with self.assertWarns(DeprecationWarning): - self.assertRaises(TypeError, getargs_Z_hash, memoryview(b'memoryview')) - with self.assertWarns(DeprecationWarning): - self.assertIsNone(getargs_Z_hash(None)) - def test_gh_99240_clear_args(self): from _testcapi import gh_99240_clear_args self.assertRaises(TypeError, gh_99240_clear_args, 'a', '\0b') @@ -1224,6 +1162,27 @@ def test_parse_tuple_and_keywords(self): self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords, (), {}, '', [42]) + def test_basic(self): + parse = _testcapi.parse_tuple_and_keywords + + self.assertEqual(parse((), {'a': 1}, 'O', ['a']), (1,)) + self.assertEqual(parse((), {}, '|O', ['a']), (NULL,)) + self.assertEqual(parse((1, 2), {}, 'OO', ['a', 'b']), (1, 2)) + self.assertEqual(parse((1,), {'b': 2}, 'OO', ['a', 'b']), (1, 2)) + self.assertEqual(parse((), {'a': 1, 'b': 2}, 'OO', ['a', 'b']), (1, 2)) + self.assertEqual(parse((), {'b': 2}, '|OO', ['a', 'b']), (NULL, 2)) + + with self.assertRaisesRegex(TypeError, + "function missing required argument 'a'"): + parse((), {}, 'O', ['a']) + with self.assertRaisesRegex(TypeError, + "'b' is an invalid keyword argument"): + parse((), {'b': 1}, '|O', ['a']) + with self.assertRaisesRegex(TypeError, + fr"argument for function given by name \('a'\) " + fr"and position \(1\)"): + parse((1,), {'a': 2}, 'O|O', ['a', 'b']) + def test_bad_use(self): # Test handling invalid format and keywords in # PyArg_ParseTupleAndKeywords() @@ -1251,20 +1210,23 @@ def test_bad_use(self): def test_positional_only(self): parse = _testcapi.parse_tuple_and_keywords - parse((1, 2, 3), {}, 'OOO', ['', '', 'a']) - parse((1, 2), {'a': 3}, 'OOO', ['', '', 'a']) + self.assertEqual(parse((1, 2, 3), {}, 'OOO', ['', '', 'a']), (1, 2, 3)) + self.assertEqual(parse((1, 2), {'a': 3}, 'OOO', ['', '', 'a']), (1, 2, 3)) with self.assertRaisesRegex(TypeError, r'function takes at least 2 positional arguments \(1 given\)'): parse((1,), {'a': 3}, 'OOO', ['', '', 'a']) - parse((1,), {}, 'O|OO', ['', '', 'a']) + self.assertEqual(parse((1,), {}, 'O|OO', ['', '', 'a']), + (1, NULL, NULL)) with self.assertRaisesRegex(TypeError, r'function takes at least 1 positional argument \(0 given\)'): parse((), {}, 'O|OO', ['', '', 'a']) - parse((1, 2), {'a': 3}, 'OO$O', ['', '', 'a']) + self.assertEqual(parse((1, 2), {'a': 3}, 'OO$O', ['', '', 'a']), + (1, 2, 3)) with self.assertRaisesRegex(TypeError, r'function takes exactly 2 positional arguments \(1 given\)'): parse((1,), {'a': 3}, 'OO$O', ['', '', 'a']) - parse((1,), {}, 'O|O$O', ['', '', 'a']) + self.assertEqual(parse((1,), {}, 'O|O$O', ['', '', 'a']), + (1, NULL, NULL)) with self.assertRaisesRegex(TypeError, r'function takes at least 1 positional argument \(0 given\)'): parse((), {}, 'O|O$O', ['', '', 'a']) diff --git a/Lib/test/test_capi/test_long.py b/Lib/test/test_capi/test_long.py index 8928fd94a1d6a3..101fe1f0de77f1 100644 --- a/Lib/test/test_capi/test_long.py +++ b/Lib/test/test_capi/test_long.py @@ -34,6 +34,36 @@ def test_compact_known(self): self.assertEqual(_testcapi.call_long_compact_api(sys.maxsize), (False, -1)) + def test_long_asint(self): + PyLong_AsInt = _testcapi.PyLong_AsInt + INT_MIN = _testcapi.INT_MIN + INT_MAX = _testcapi.INT_MAX + + # round trip (object -> int -> object) + for value in (INT_MIN, INT_MAX, -1, 0, 1, 123): + with self.subTest(value=value): + self.assertEqual(PyLong_AsInt(value), value) + + # use __index__(), not __int__() + class MyIndex: + def __index__(self): + return 10 + def __int__(self): + return 22 + self.assertEqual(PyLong_AsInt(MyIndex()), 10) + + # bound checking + with self.assertRaises(OverflowError): + PyLong_AsInt(INT_MIN - 1) + with self.assertRaises(OverflowError): + PyLong_AsInt(INT_MAX + 1) + + # invalid type + for value in (1.0, b'2', '3'): + with self.subTest(value=value): + with self.assertRaises(TypeError): + PyLong_AsInt(value) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py index a9ff410cb93ab8..72f23b1a34080e 100644 --- a/Lib/test/test_capi/test_mem.py +++ b/Lib/test/test_capi/test_mem.py @@ -8,8 +8,10 @@ from test.support.script_helper import assert_python_failure, assert_python_ok -# Skip this test if the _testcapi module isn't available. +# Skip this test if the _testcapi and _testinternalcapi extensions are not +# available. _testcapi = import_helper.import_module('_testcapi') +_testinternalcapi = import_helper.import_module('_testinternalcapi') @requires_subprocess() class PyMemDebugTests(unittest.TestCase): @@ -84,16 +86,13 @@ def test_pyobject_malloc_without_gil(self): def check_pyobject_is_freed(self, func_name): code = textwrap.dedent(f''' - import gc, os, sys, _testcapi + import gc, os, sys, _testinternalcapi # Disable the GC to avoid crash on GC collection gc.disable() - try: - _testcapi.{func_name}() - # Exit immediately to avoid a crash while deallocating - # the invalid object - os._exit(0) - except _testcapi.error: - os._exit(1) + _testinternalcapi.{func_name}() + # Exit immediately to avoid a crash while deallocating + # the invalid object + os._exit(0) ''') assert_python_ok( '-c', code, @@ -113,6 +112,9 @@ def test_pyobject_forbidden_bytes_is_freed(self): def test_pyobject_freed_is_freed(self): self.check_pyobject_is_freed('check_pyobject_freed_is_freed') + # Python built with Py_TRACE_REFS fail with a fatal error in + # _PyRefchain_Trace() on memory allocation error. + @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') def test_set_nomemory(self): code = """if 1: import _testcapi diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 4e519fa73c50cc..b3f32d860eee03 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -2,7 +2,7 @@ # these are all functions _testcapi exports whose name begins with 'test_'. import _thread -from collections import OrderedDict, deque +from collections import deque import contextlib import importlib.machinery import importlib.util @@ -51,6 +51,8 @@ import _testinternalcapi +NULL = None + def decode_stderr(err): return err.decode('utf-8', 'replace').replace('\r', '') @@ -85,9 +87,15 @@ def test_instancemethod(self): @support.requires_subprocess() def test_no_FatalError_infinite_loop(self): - run_result, _cmd_line = run_python_until_end( - '-c', 'import _testcapi; _testcapi.crash_no_current_thread()', - ) + code = textwrap.dedent(""" + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.crash_no_current_thread() + """) + + run_result, _cmd_line = run_python_until_end('-c', code) _rc, out, err = run_result self.assertEqual(out, b'') # This used to cause an infinite loop. @@ -290,157 +298,132 @@ def test_getitem_with_error(self): # test _Py_CheckFunctionResult() instead. self.assertIn('returned a result with an exception set', err) + def test_buildvalue(self): + # Test Py_BuildValue() with object arguments + buildvalue = _testcapi.py_buildvalue + self.assertEqual(buildvalue(''), None) + self.assertEqual(buildvalue('()'), ()) + self.assertEqual(buildvalue('[]'), []) + self.assertEqual(buildvalue('{}'), {}) + self.assertEqual(buildvalue('()[]{}'), ((), [], {})) + self.assertEqual(buildvalue('O', 1), 1) + self.assertEqual(buildvalue('(O)', 1), (1,)) + self.assertEqual(buildvalue('[O]', 1), [1]) + self.assertRaises(SystemError, buildvalue, '{O}', 1) + self.assertEqual(buildvalue('OO', 1, 2), (1, 2)) + self.assertEqual(buildvalue('(OO)', 1, 2), (1, 2)) + self.assertEqual(buildvalue('[OO]', 1, 2), [1, 2]) + self.assertEqual(buildvalue('{OO}', 1, 2), {1: 2}) + self.assertEqual(buildvalue('{OOOO}', 1, 2, 3, 4), {1: 2, 3: 4}) + self.assertEqual(buildvalue('((O))', 1), ((1,),)) + self.assertEqual(buildvalue('((OO))', 1, 2), ((1, 2),)) + + self.assertEqual(buildvalue(' \t,:'), None) + self.assertEqual(buildvalue('O,', 1), 1) + self.assertEqual(buildvalue(' O ', 1), 1) + self.assertEqual(buildvalue('\tO\t', 1), 1) + self.assertEqual(buildvalue('O,O', 1, 2), (1, 2)) + self.assertEqual(buildvalue('O, O', 1, 2), (1, 2)) + self.assertEqual(buildvalue('O,\tO', 1, 2), (1, 2)) + self.assertEqual(buildvalue('O O', 1, 2), (1, 2)) + self.assertEqual(buildvalue('O\tO', 1, 2), (1, 2)) + self.assertEqual(buildvalue('(O,O)', 1, 2), (1, 2)) + self.assertEqual(buildvalue('(O, O,)', 1, 2), (1, 2)) + self.assertEqual(buildvalue(' ( O O ) ', 1, 2), (1, 2)) + self.assertEqual(buildvalue('\t(\tO\tO\t)\t', 1, 2), (1, 2)) + self.assertEqual(buildvalue('[O,O]', 1, 2), [1, 2]) + self.assertEqual(buildvalue('[O, O,]', 1, 2), [1, 2]) + self.assertEqual(buildvalue(' [ O O ] ', 1, 2), [1, 2]) + self.assertEqual(buildvalue(' [\tO\tO\t] ', 1, 2), [1, 2]) + self.assertEqual(buildvalue('{O:O}', 1, 2), {1: 2}) + self.assertEqual(buildvalue('{O:O,O:O}', 1, 2, 3, 4), {1: 2, 3: 4}) + self.assertEqual(buildvalue('{O: O, O: O,}', 1, 2, 3, 4), {1: 2, 3: 4}) + self.assertEqual(buildvalue(' { O O O O } ', 1, 2, 3, 4), {1: 2, 3: 4}) + self.assertEqual(buildvalue('\t{\tO\tO\tO\tO\t}\t', 1, 2, 3, 4), {1: 2, 3: 4}) + + self.assertRaises(SystemError, buildvalue, 'O', NULL) + self.assertRaises(SystemError, buildvalue, '(O)', NULL) + self.assertRaises(SystemError, buildvalue, '[O]', NULL) + self.assertRaises(SystemError, buildvalue, '{O}', NULL) + self.assertRaises(SystemError, buildvalue, 'OO', 1, NULL) + self.assertRaises(SystemError, buildvalue, 'OO', NULL, 2) + self.assertRaises(SystemError, buildvalue, '(OO)', 1, NULL) + self.assertRaises(SystemError, buildvalue, '(OO)', NULL, 2) + self.assertRaises(SystemError, buildvalue, '[OO]', 1, NULL) + self.assertRaises(SystemError, buildvalue, '[OO]', NULL, 2) + self.assertRaises(SystemError, buildvalue, '{OO}', 1, NULL) + self.assertRaises(SystemError, buildvalue, '{OO}', NULL, 2) + + def test_buildvalue_ints(self): + # Test Py_BuildValue() with integer arguments + buildvalue = _testcapi.py_buildvalue_ints + from _testcapi import SHRT_MIN, SHRT_MAX, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX + self.assertEqual(buildvalue('i', INT_MAX), INT_MAX) + self.assertEqual(buildvalue('i', INT_MIN), INT_MIN) + self.assertEqual(buildvalue('I', UINT_MAX), UINT_MAX) + + self.assertEqual(buildvalue('h', SHRT_MAX), SHRT_MAX) + self.assertEqual(buildvalue('h', SHRT_MIN), SHRT_MIN) + self.assertEqual(buildvalue('H', USHRT_MAX), USHRT_MAX) + + self.assertEqual(buildvalue('b', 127), 127) + self.assertEqual(buildvalue('b', -128), -128) + self.assertEqual(buildvalue('B', 255), 255) + + self.assertEqual(buildvalue('c', ord('A')), b'A') + self.assertEqual(buildvalue('c', 255), b'\xff') + self.assertEqual(buildvalue('c', 256), b'\x00') + self.assertEqual(buildvalue('c', -1), b'\xff') + + self.assertEqual(buildvalue('C', 255), chr(255)) + self.assertEqual(buildvalue('C', 256), chr(256)) + self.assertEqual(buildvalue('C', sys.maxunicode), chr(sys.maxunicode)) + self.assertRaises(ValueError, buildvalue, 'C', -1) + self.assertRaises(ValueError, buildvalue, 'C', sys.maxunicode+1) + + # gh-84489 + self.assertRaises(ValueError, buildvalue, '(C )i', -1, 2) + self.assertRaises(ValueError, buildvalue, '[C ]i', -1, 2) + self.assertRaises(ValueError, buildvalue, '{Ci }i', -1, 2, 3) + def test_buildvalue_N(self): _testcapi.test_buildvalue_N() - def test_mapping_keys_values_items(self): - class Mapping1(dict): - def keys(self): - return list(super().keys()) - def values(self): - return list(super().values()) - def items(self): - return list(super().items()) - class Mapping2(dict): - def keys(self): - return tuple(super().keys()) - def values(self): - return tuple(super().values()) - def items(self): - return tuple(super().items()) - dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} - - for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(), - dict_obj, OrderedDict(dict_obj), - Mapping1(dict_obj), Mapping2(dict_obj)]: - self.assertListEqual(_testcapi.get_mapping_keys(mapping), - list(mapping.keys())) - self.assertListEqual(_testcapi.get_mapping_values(mapping), - list(mapping.values())) - self.assertListEqual(_testcapi.get_mapping_items(mapping), - list(mapping.items())) - - def test_mapping_keys_values_items_bad_arg(self): - self.assertRaises(AttributeError, _testcapi.get_mapping_keys, None) - self.assertRaises(AttributeError, _testcapi.get_mapping_values, None) - self.assertRaises(AttributeError, _testcapi.get_mapping_items, None) - - class BadMapping: - def keys(self): - return None - def values(self): - return None - def items(self): - return None - bad_mapping = BadMapping() - self.assertRaises(TypeError, _testcapi.get_mapping_keys, bad_mapping) - self.assertRaises(TypeError, _testcapi.get_mapping_values, bad_mapping) - self.assertRaises(TypeError, _testcapi.get_mapping_items, bad_mapping) - - def test_mapping_has_key(self): - dct = {'a': 1} - self.assertTrue(_testcapi.mapping_has_key(dct, 'a')) - self.assertFalse(_testcapi.mapping_has_key(dct, 'b')) - - class SubDict(dict): - pass - - dct2 = SubDict({'a': 1}) - self.assertTrue(_testcapi.mapping_has_key(dct2, 'a')) - self.assertFalse(_testcapi.mapping_has_key(dct2, 'b')) - - def test_sequence_set_slice(self): - # Correct case: - data = [1, 2, 3, 4, 5] - data_copy = data.copy() - - _testcapi.sequence_set_slice(data, 1, 3, [8, 9]) - data_copy[1:3] = [8, 9] - self.assertEqual(data, data_copy) - self.assertEqual(data, [1, 8, 9, 4, 5]) - - # Custom class: - class Custom: - def __setitem__(self, index, value): - self.index = index - self.value = value - - c = Custom() - _testcapi.sequence_set_slice(c, 0, 5, 'abc') - self.assertEqual(c.index, slice(0, 5)) - self.assertEqual(c.value, 'abc') - - # Immutable sequences must raise: - bad_seq1 = (1, 2, 3, 4) - with self.assertRaises(TypeError): - _testcapi.sequence_set_slice(bad_seq1, 1, 3, (8, 9)) - self.assertEqual(bad_seq1, (1, 2, 3, 4)) - - bad_seq2 = 'abcd' - with self.assertRaises(TypeError): - _testcapi.sequence_set_slice(bad_seq2, 1, 3, 'xy') - self.assertEqual(bad_seq2, 'abcd') - - # Not a sequence: - with self.assertRaises(TypeError): - _testcapi.sequence_set_slice(None, 1, 3, 'xy') - - def test_sequence_del_slice(self): - # Correct case: - data = [1, 2, 3, 4, 5] - data_copy = data.copy() - - _testcapi.sequence_del_slice(data, 1, 3) - del data_copy[1:3] - self.assertEqual(data, data_copy) - self.assertEqual(data, [1, 4, 5]) - - # Custom class: - class Custom: - def __delitem__(self, index): - self.index = index - - c = Custom() - _testcapi.sequence_del_slice(c, 0, 5) - self.assertEqual(c.index, slice(0, 5)) - - # Immutable sequences must raise: - bad_seq1 = (1, 2, 3, 4) - with self.assertRaises(TypeError): - _testcapi.sequence_del_slice(bad_seq1, 1, 3) - self.assertEqual(bad_seq1, (1, 2, 3, 4)) - - bad_seq2 = 'abcd' - with self.assertRaises(TypeError): - _testcapi.sequence_del_slice(bad_seq2, 1, 3) - self.assertEqual(bad_seq2, 'abcd') - - # Not a sequence: - with self.assertRaises(TypeError): - _testcapi.sequence_del_slice(None, 1, 3) - - mapping = {1: 'a', 2: 'b', 3: 'c'} - with self.assertRaises(KeyError): - _testcapi.sequence_del_slice(mapping, 1, 3) - self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) + def check_negative_refcount(self, code): + # bpo-35059: Check that Py_DECREF() reports the correct filename + # when calling _Py_NegativeRefcount() to abort Python. + code = textwrap.dedent(code) + rc, out, err = assert_python_failure('-c', code) + self.assertRegex(err, + br'_testcapimodule\.c:[0-9]+: ' + br'_Py_NegativeRefcount: Assertion failed: ' + br'object has negative ref count') @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'), - 'need _testcapi.negative_refcount') + 'need _testcapi.negative_refcount()') def test_negative_refcount(self): - # bpo-35059: Check that Py_DECREF() reports the correct filename - # when calling _Py_NegativeRefcount() to abort Python. - code = textwrap.dedent(""" + code = """ import _testcapi from test import support with support.SuppressCrashReport(): _testcapi.negative_refcount() - """) - rc, out, err = assert_python_failure('-c', code) - self.assertRegex(err, - br'_testcapimodule\.c:[0-9]+: ' - br'_Py_NegativeRefcount: Assertion failed: ' - br'object has negative ref count') + """ + self.check_negative_refcount(code) + + @unittest.skipUnless(hasattr(_testcapi, 'decref_freed_object'), + 'need _testcapi.decref_freed_object()') + @support.skip_if_sanitizer("use after free on purpose", + address=True, memory=True, ub=True) + def test_decref_freed_object(self): + code = """ + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.decref_freed_object() + """ + self.check_negative_refcount(code) def test_trashcan_subclass(self): # bpo-35983: Check that the trashcan mechanism for "list" is NOT @@ -734,7 +717,7 @@ class Base(metaclass=metaclass): # Class creation from C with warnings_helper.check_warnings( - ('.*custom tp_new.*in Python 3.14.*', DeprecationWarning), + ('.* _testcapi.Subclass .* custom tp_new.*in Python 3.14.*', DeprecationWarning), ): sub = _testcapi.make_type_with_base(Base) self.assertTrue(issubclass(sub, Base)) @@ -1115,6 +1098,46 @@ class Data(_testcapi.ObjExtraData): del d.extra self.assertIsNone(d.extra) + def test_sys_getobject(self): + getobject = _testcapi.sys_getobject + + self.assertIs(getobject(b'stdout'), sys.stdout) + with support.swap_attr(sys, '\U0001f40d', 42): + self.assertEqual(getobject('\U0001f40d'.encode()), 42) + + self.assertIs(getobject(b'nonexisting'), AttributeError) + self.assertIs(getobject(b'\xff'), AttributeError) + # CRASHES getobject(NULL) + + def test_sys_setobject(self): + setobject = _testcapi.sys_setobject + + value = ['value'] + value2 = ['value2'] + try: + self.assertEqual(setobject(b'newattr', value), 0) + self.assertIs(sys.newattr, value) + self.assertEqual(setobject(b'newattr', value2), 0) + self.assertIs(sys.newattr, value2) + self.assertEqual(setobject(b'newattr', NULL), 0) + self.assertFalse(hasattr(sys, 'newattr')) + self.assertEqual(setobject(b'newattr', NULL), 0) + finally: + with contextlib.suppress(AttributeError): + del sys.newattr + try: + self.assertEqual(setobject('\U0001f40d'.encode(), value), 0) + self.assertIs(getattr(sys, '\U0001f40d'), value) + self.assertEqual(setobject('\U0001f40d'.encode(), NULL), 0) + self.assertFalse(hasattr(sys, '\U0001f40d')) + finally: + with contextlib.suppress(AttributeError): + delattr(sys, '\U0001f40d') + + with self.assertRaises(UnicodeDecodeError): + setobject(b'\xff', value) + # CRASHES setobject(NULL, value) + @requires_limited_api class TestHeapTypeRelative(unittest.TestCase): @@ -2150,7 +2173,15 @@ def test_version_api_data(self): class Test_testinternalcapi(unittest.TestCase): locals().update((name, getattr(_testinternalcapi, name)) for name in dir(_testinternalcapi) - if name.startswith('test_')) + if name.startswith('test_') + and not name.startswith('test_lock_')) + + +@threading_helper.requires_working_threading() +class Test_PyLock(unittest.TestCase): + locals().update((name, getattr(_testinternalcapi, name)) + for name in dir(_testinternalcapi) + if name.startswith('test_lock_')) @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") @@ -2367,13 +2398,24 @@ def clear_executors(func): class TestOptimizerAPI(unittest.TestCase): + def test_get_counter_optimizer_dealloc(self): + # See gh-108727 + def f(): + _testinternalcapi.get_counter_optimizer() + + f() + def test_get_set_optimizer(self): - self.assertEqual(_testinternalcapi.get_optimizer(), None) + old = _testinternalcapi.get_optimizer() opt = _testinternalcapi.get_counter_optimizer() - _testinternalcapi.set_optimizer(opt) - self.assertEqual(_testinternalcapi.get_optimizer(), opt) - _testinternalcapi.set_optimizer(None) - self.assertEqual(_testinternalcapi.get_optimizer(), None) + try: + _testinternalcapi.set_optimizer(opt) + self.assertEqual(_testinternalcapi.get_optimizer(), opt) + _testinternalcapi.set_optimizer(None) + self.assertEqual(_testinternalcapi.get_optimizer(), None) + finally: + _testinternalcapi.set_optimizer(old) + def test_counter_optimizer(self): # Generate a new function at each call @@ -2420,13 +2462,26 @@ def long_loop(): long_loop() self.assertEqual(opt.get_count(), 10) + def test_code_restore_for_ENTER_EXECUTOR(self): + def testfunc(x): + i = 0 + while i < x: + i += 1 + + opt = _testinternalcapi.get_counter_optimizer() + with temporary_optimizer(opt): + testfunc(1000) + code, replace_code = testfunc.__code__, testfunc.__code__.replace() + self.assertEqual(code, replace_code) + self.assertEqual(hash(code), hash(replace_code)) + def get_first_executor(func): code = func.__code__ co_code = code.co_code JUMP_BACKWARD = opcode.opmap["JUMP_BACKWARD"] for i in range(0, len(co_code), 2): - if co_code[i] == JUMP_BACKWARD or 1: + if co_code[i] == JUMP_BACKWARD: try: return _testinternalcapi.get_executor(code, i) except ValueError: @@ -2449,41 +2504,45 @@ def testfunc(x): ex = get_first_executor(testfunc) self.assertIsNotNone(ex) uops = {opname for opname, _, _ in ex} - self.assertIn("SAVE_IP", uops) + self.assertIn("_SET_IP", uops) self.assertIn("LOAD_FAST", uops) def test_extended_arg(self): "Check EXTENDED_ARG handling in superblock creation" - def many_vars(): - # 260 vars, so z9 should have index 259 - a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 42 - b0 = b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = b9 = 42 - c0 = c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c9 = 42 - d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = 42 - e0 = e1 = e2 = e3 = e4 = e5 = e6 = e7 = e8 = e9 = 42 - f0 = f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = 42 - g0 = g1 = g2 = g3 = g4 = g5 = g6 = g7 = g8 = g9 = 42 - h0 = h1 = h2 = h3 = h4 = h5 = h6 = h7 = h8 = h9 = 42 - i0 = i1 = i2 = i3 = i4 = i5 = i6 = i7 = i8 = i9 = 42 - j0 = j1 = j2 = j3 = j4 = j5 = j6 = j7 = j8 = j9 = 42 - k0 = k1 = k2 = k3 = k4 = k5 = k6 = k7 = k8 = k9 = 42 - l0 = l1 = l2 = l3 = l4 = l5 = l6 = l7 = l8 = l9 = 42 - m0 = m1 = m2 = m3 = m4 = m5 = m6 = m7 = m8 = m9 = 42 - n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = n9 = 42 - o0 = o1 = o2 = o3 = o4 = o5 = o6 = o7 = o8 = o9 = 42 - p0 = p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = p9 = 42 - q0 = q1 = q2 = q3 = q4 = q5 = q6 = q7 = q8 = q9 = 42 - r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = 42 - s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = s9 = 42 - t0 = t1 = t2 = t3 = t4 = t5 = t6 = t7 = t8 = t9 = 42 - u0 = u1 = u2 = u3 = u4 = u5 = u6 = u7 = u8 = u9 = 42 - v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = 42 - w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = w8 = w9 = 42 - x0 = x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = x9 = 42 - y0 = y1 = y2 = y3 = y4 = y5 = y6 = y7 = y8 = y9 = 42 - z0 = z1 = z2 = z3 = z4 = z5 = z6 = z7 = z8 = z9 = 42 - while z9 > 0: - z9 = z9 - 1 + ns = {} + exec(textwrap.dedent(""" + def many_vars(): + # 260 vars, so z9 should have index 259 + a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 42 + b0 = b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = b9 = 42 + c0 = c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c9 = 42 + d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = 42 + e0 = e1 = e2 = e3 = e4 = e5 = e6 = e7 = e8 = e9 = 42 + f0 = f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = 42 + g0 = g1 = g2 = g3 = g4 = g5 = g6 = g7 = g8 = g9 = 42 + h0 = h1 = h2 = h3 = h4 = h5 = h6 = h7 = h8 = h9 = 42 + i0 = i1 = i2 = i3 = i4 = i5 = i6 = i7 = i8 = i9 = 42 + j0 = j1 = j2 = j3 = j4 = j5 = j6 = j7 = j8 = j9 = 42 + k0 = k1 = k2 = k3 = k4 = k5 = k6 = k7 = k8 = k9 = 42 + l0 = l1 = l2 = l3 = l4 = l5 = l6 = l7 = l8 = l9 = 42 + m0 = m1 = m2 = m3 = m4 = m5 = m6 = m7 = m8 = m9 = 42 + n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = n9 = 42 + o0 = o1 = o2 = o3 = o4 = o5 = o6 = o7 = o8 = o9 = 42 + p0 = p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = p9 = 42 + q0 = q1 = q2 = q3 = q4 = q5 = q6 = q7 = q8 = q9 = 42 + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = 42 + s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = s9 = 42 + t0 = t1 = t2 = t3 = t4 = t5 = t6 = t7 = t8 = t9 = 42 + u0 = u1 = u2 = u3 = u4 = u5 = u6 = u7 = u8 = u9 = 42 + v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = 42 + w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = w8 = w9 = 42 + x0 = x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = x9 = 42 + y0 = y1 = y2 = y3 = y4 = y5 = y6 = y7 = y8 = y9 = 42 + z0 = z1 = z2 = z3 = z4 = z5 = z6 = z7 = z8 = z9 = 42 + while z9 > 0: + z9 = z9 - 1 + """), ns, ns) + many_vars = ns["many_vars"] opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): @@ -2510,7 +2569,7 @@ def testfunc(x): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - testfunc(10) + testfunc(20) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2525,7 +2584,7 @@ def testfunc(n): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - testfunc(10) + testfunc(20) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2540,7 +2599,7 @@ def testfunc(a): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - testfunc([1, 2, 3]) + testfunc(range(20)) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2550,12 +2609,13 @@ def testfunc(a): def test_pop_jump_if_not_none(self): def testfunc(a): for x in a: + x = None if x is not None: x = 0 opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - testfunc([1, 2, 3]) + testfunc(range(20)) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2570,7 +2630,7 @@ def testfunc(n): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - testfunc(10) + testfunc(20) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2585,12 +2645,12 @@ def testfunc(n): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - testfunc(10) + testfunc(20) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) uops = {opname for opname, _, _ in ex} - self.assertIn("JUMP_TO_TOP", uops) + self.assertIn("_JUMP_TO_TOP", uops) def test_jump_forward(self): def testfunc(n): @@ -2605,7 +2665,7 @@ def testfunc(n): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - testfunc(10) + testfunc(20) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2623,8 +2683,8 @@ def testfunc(n): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - total = testfunc(10) - self.assertEqual(total, 45) + total = testfunc(20) + self.assertEqual(total, 190) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2644,9 +2704,9 @@ def testfunc(a): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - a = list(range(10)) + a = list(range(20)) total = testfunc(a) - self.assertEqual(total, 45) + self.assertEqual(total, 190) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2666,9 +2726,9 @@ def testfunc(a): opt = _testinternalcapi.get_uop_optimizer() with temporary_optimizer(opt): - a = tuple(range(10)) + a = tuple(range(20)) total = testfunc(a) - self.assertEqual(total, 45) + self.assertEqual(total, 190) ex = get_first_executor(testfunc) self.assertIsNotNone(ex) @@ -2693,5 +2753,40 @@ def testfunc(it): with self.assertRaises(StopIteration): next(it) + def test_call_py_exact_args(self): + def testfunc(n): + def dummy(x): + return x+1 + for i in range(n): + dummy(i) + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + testfunc(20) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = {opname for opname, _, _ in ex} + self.assertIn("_PUSH_FRAME", uops) + self.assertIn("_BINARY_OP_ADD_INT", uops) + + def test_branch_taken(self): + def testfunc(n): + for i in range(n): + if i < 0: + i = 0 + else: + i = 1 + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + testfunc(20) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = {opname for opname, _, _ in ex} + self.assertIn("_POP_JUMP_IF_TRUE", uops) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_pyatomic.py b/Lib/test/test_capi/test_pyatomic.py new file mode 100644 index 00000000000000..846d6d50c25969 --- /dev/null +++ b/Lib/test/test_capi/test_pyatomic.py @@ -0,0 +1,15 @@ +import unittest +from test.support import import_helper + +# Skip this test if the _testcapi module isn't available. +_testcapi = import_helper.import_module('_testcapi') + +class PyAtomicTests(unittest.TestCase): + pass + +for name in sorted(dir(_testcapi)): + if name.startswith('test_atomic'): + setattr(PyAtomicTests, name, getattr(_testcapi, name)) + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_set.py b/Lib/test/test_capi/test_set.py new file mode 100644 index 00000000000000..5235f81543e0b6 --- /dev/null +++ b/Lib/test/test_capi/test_set.py @@ -0,0 +1,265 @@ +import unittest + +from test.support import import_helper + +# Skip this test if the _testcapi or _testinternalcapi modules aren't available. +_testcapi = import_helper.import_module('_testcapi') +_testinternalcapi = import_helper.import_module('_testinternalcapi') + +class set_subclass(set): + pass + +class frozenset_subclass(frozenset): + pass + + +class BaseSetTests: + def assertImmutable(self, action, *args): + self.assertRaises(SystemError, action, frozenset(), *args) + self.assertRaises(SystemError, action, frozenset({1}), *args) + self.assertRaises(SystemError, action, frozenset_subclass(), *args) + self.assertRaises(SystemError, action, frozenset_subclass({1}), *args) + + +class TestSetCAPI(BaseSetTests, unittest.TestCase): + def test_set_check(self): + check = _testcapi.set_check + self.assertTrue(check(set())) + self.assertTrue(check({1, 2})) + self.assertFalse(check(frozenset())) + self.assertTrue(check(set_subclass())) + self.assertFalse(check(frozenset_subclass())) + self.assertFalse(check(object())) + # CRASHES: check(NULL) + + def test_set_check_exact(self): + check = _testcapi.set_checkexact + self.assertTrue(check(set())) + self.assertTrue(check({1, 2})) + self.assertFalse(check(frozenset())) + self.assertFalse(check(set_subclass())) + self.assertFalse(check(frozenset_subclass())) + self.assertFalse(check(object())) + # CRASHES: check(NULL) + + def test_frozenset_check(self): + check = _testcapi.frozenset_check + self.assertFalse(check(set())) + self.assertTrue(check(frozenset())) + self.assertTrue(check(frozenset({1, 2}))) + self.assertFalse(check(set_subclass())) + self.assertTrue(check(frozenset_subclass())) + self.assertFalse(check(object())) + # CRASHES: check(NULL) + + def test_frozenset_check_exact(self): + check = _testcapi.frozenset_checkexact + self.assertFalse(check(set())) + self.assertTrue(check(frozenset())) + self.assertTrue(check(frozenset({1, 2}))) + self.assertFalse(check(set_subclass())) + self.assertFalse(check(frozenset_subclass())) + self.assertFalse(check(object())) + # CRASHES: check(NULL) + + def test_anyset_check(self): + check = _testcapi.anyset_check + self.assertTrue(check(set())) + self.assertTrue(check({1, 2})) + self.assertTrue(check(frozenset())) + self.assertTrue(check(frozenset({1, 2}))) + self.assertTrue(check(set_subclass())) + self.assertTrue(check(frozenset_subclass())) + self.assertFalse(check(object())) + # CRASHES: check(NULL) + + def test_anyset_check_exact(self): + check = _testcapi.anyset_checkexact + self.assertTrue(check(set())) + self.assertTrue(check({1, 2})) + self.assertTrue(check(frozenset())) + self.assertTrue(check(frozenset({1, 2}))) + self.assertFalse(check(set_subclass())) + self.assertFalse(check(frozenset_subclass())) + self.assertFalse(check(object())) + # CRASHES: check(NULL) + + def test_set_new(self): + set_new = _testcapi.set_new + self.assertEqual(set_new().__class__, set) + self.assertEqual(set_new(), set()) + self.assertEqual(set_new((1, 1, 2)), {1, 2}) + self.assertEqual(set_new([1, 1, 2]), {1, 2}) + with self.assertRaisesRegex(TypeError, 'object is not iterable'): + set_new(object()) + with self.assertRaisesRegex(TypeError, 'object is not iterable'): + set_new(1) + with self.assertRaisesRegex(TypeError, "unhashable type: 'dict'"): + set_new((1, {})) + + def test_frozenset_new(self): + frozenset_new = _testcapi.frozenset_new + self.assertEqual(frozenset_new().__class__, frozenset) + self.assertEqual(frozenset_new(), frozenset()) + self.assertEqual(frozenset_new((1, 1, 2)), frozenset({1, 2})) + self.assertEqual(frozenset_new([1, 1, 2]), frozenset({1, 2})) + with self.assertRaisesRegex(TypeError, 'object is not iterable'): + frozenset_new(object()) + with self.assertRaisesRegex(TypeError, 'object is not iterable'): + frozenset_new(1) + with self.assertRaisesRegex(TypeError, "unhashable type: 'dict'"): + frozenset_new((1, {})) + + def test_set_size(self): + get_size = _testcapi.set_size + self.assertEqual(get_size(set()), 0) + self.assertEqual(get_size(frozenset()), 0) + self.assertEqual(get_size({1, 1, 2}), 2) + self.assertEqual(get_size(frozenset({1, 1, 2})), 2) + self.assertEqual(get_size(set_subclass((1, 2, 3))), 3) + self.assertEqual(get_size(frozenset_subclass((1, 2, 3))), 3) + with self.assertRaises(SystemError): + get_size(object()) + # CRASHES: get_size(NULL) + + def test_set_get_size(self): + get_size = _testcapi.set_get_size + self.assertEqual(get_size(set()), 0) + self.assertEqual(get_size(frozenset()), 0) + self.assertEqual(get_size({1, 1, 2}), 2) + self.assertEqual(get_size(frozenset({1, 1, 2})), 2) + self.assertEqual(get_size(set_subclass((1, 2, 3))), 3) + self.assertEqual(get_size(frozenset_subclass((1, 2, 3))), 3) + # CRASHES: get_size(NULL) + # CRASHES: get_size(object()) + + def test_set_contains(self): + contains = _testcapi.set_contains + for cls in (set, frozenset, set_subclass, frozenset_subclass): + with self.subTest(cls=cls): + instance = cls((1, 2)) + self.assertTrue(contains(instance, 1)) + self.assertFalse(contains(instance, 'missing')) + with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"): + contains(instance, []) + # CRASHES: contains(instance, NULL) + # CRASHES: contains(NULL, object()) + # CRASHES: contains(NULL, NULL) + + def test_add(self): + add = _testcapi.set_add + for cls in (set, set_subclass): + with self.subTest(cls=cls): + instance = cls((1, 2)) + self.assertEqual(add(instance, 1), 0) + self.assertEqual(instance, {1, 2}) + self.assertEqual(add(instance, 3), 0) + self.assertEqual(instance, {1, 2, 3}) + with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"): + add(instance, []) + with self.assertRaises(SystemError): + add(object(), 1) + self.assertImmutable(add, 1) + # CRASHES: add(NULL, object()) + # CRASHES: add(instance, NULL) + # CRASHES: add(NULL, NULL) + + def test_discard(self): + discard = _testcapi.set_discard + for cls in (set, set_subclass): + with self.subTest(cls=cls): + instance = cls((1, 2)) + self.assertEqual(discard(instance, 3), 0) + self.assertEqual(instance, {1, 2}) + self.assertEqual(discard(instance, 1), 1) + self.assertEqual(instance, {2}) + self.assertEqual(discard(instance, 2), 1) + self.assertEqual(instance, set()) + self.assertEqual(discard(instance, 2), 0) + self.assertEqual(instance, set()) + with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"): + discard(instance, []) + with self.assertRaises(SystemError): + discard(object(), 1) + self.assertImmutable(discard, 1) + # CRASHES: discard(NULL, object()) + # CRASHES: discard(instance, NULL) + # CRASHES: discard(NULL, NULL) + + def test_pop(self): + pop = _testcapi.set_pop + orig = (1, 2) + for cls in (set, set_subclass): + with self.subTest(cls=cls): + instance = cls(orig) + self.assertIn(pop(instance), orig) + self.assertEqual(len(instance), 1) + self.assertIn(pop(instance), orig) + self.assertEqual(len(instance), 0) + with self.assertRaises(KeyError): + pop(instance) + with self.assertRaises(SystemError): + pop(object()) + self.assertImmutable(pop) + # CRASHES: pop(NULL) + + def test_clear(self): + clear = _testcapi.set_clear + for cls in (set, set_subclass): + with self.subTest(cls=cls): + instance = cls((1, 2)) + self.assertEqual(clear(instance), 0) + self.assertEqual(instance, set()) + self.assertEqual(clear(instance), 0) + self.assertEqual(instance, set()) + with self.assertRaises(SystemError): + clear(object()) + self.assertImmutable(clear) + # CRASHES: clear(NULL) + + +class TestInternalCAPI(BaseSetTests, unittest.TestCase): + def test_set_update(self): + update = _testinternalcapi.set_update + for cls in (set, set_subclass): + for it in ('ab', ('a', 'b'), ['a', 'b'], + set('ab'), set_subclass('ab'), + frozenset('ab'), frozenset_subclass('ab')): + with self.subTest(cls=cls, it=it): + instance = cls() + self.assertEqual(update(instance, it), 0) + self.assertEqual(instance, {'a', 'b'}) + instance = cls(it) + self.assertEqual(update(instance, it), 0) + self.assertEqual(instance, {'a', 'b'}) + with self.assertRaisesRegex(TypeError, 'object is not iterable'): + update(cls(), 1) + with self.assertRaisesRegex(TypeError, "unhashable type: 'dict'"): + update(cls(), [{}]) + with self.assertRaises(SystemError): + update(object(), 'ab') + self.assertImmutable(update, 'ab') + # CRASHES: update(NULL, object()) + # CRASHES: update(instance, NULL) + # CRASHES: update(NULL, NULL) + + def test_set_next_entry(self): + set_next = _testinternalcapi.set_next_entry + for cls in (set, set_subclass, frozenset, frozenset_subclass): + with self.subTest(cls=cls): + instance = cls('abc') + pos = 0 + items = [] + while True: + res = set_next(instance, pos) + if res is None: + break + rc, pos, hash_, item = res + items.append(item) + self.assertEqual(rc, 1) + self.assertIn(item, instance) + self.assertEqual(hash(item), hash_) + self.assertEqual(items, list(instance)) + with self.assertRaises(SystemError): + set_next(object(), 0) + # CRASHES: set_next(NULL, 0) diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py index 622ee8993907fa..a73e669dda7ddc 100644 --- a/Lib/test/test_capi/test_unicode.py +++ b/Lib/test/test_capi/test_unicode.py @@ -1297,6 +1297,118 @@ def test_comparewithasciistring(self): # CRASHES comparewithasciistring([], b'abc') # CRASHES comparewithasciistring(NULL, b'abc') + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_equaltoutf8(self): + # Test PyUnicode_EqualToUTF8() + from _testcapi import unicode_equaltoutf8 as equaltoutf8 + from _testcapi import unicode_asutf8andsize as asutf8andsize + + strings = [ + 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', + '\U0001f600\U0001f601\U0001f602', + '\U0010ffff', + ] + for s in strings: + # Call PyUnicode_AsUTF8AndSize() which creates the UTF-8 + # encoded string cached in the Unicode object. + asutf8andsize(s, 0) + b = s.encode() + self.assertEqual(equaltoutf8(s, b), 1) # Use the UTF-8 cache. + s2 = b.decode() # New Unicode object without the UTF-8 cache. + self.assertEqual(equaltoutf8(s2, b), 1) + self.assertEqual(equaltoutf8(s + 'x', b + b'x'), 1) + self.assertEqual(equaltoutf8(s + 'x', b + b'y'), 0) + self.assertEqual(equaltoutf8(s, b + b'\0'), 1) + self.assertEqual(equaltoutf8(s2, b + b'\0'), 1) + self.assertEqual(equaltoutf8(s + '\0', b + b'\0'), 0) + self.assertEqual(equaltoutf8(s + '\0', b), 0) + self.assertEqual(equaltoutf8(s2, b + b'x'), 0) + self.assertEqual(equaltoutf8(s2, b[:-1]), 0) + self.assertEqual(equaltoutf8(s2, b[:-1] + b'x'), 0) + + self.assertEqual(equaltoutf8('', b''), 1) + self.assertEqual(equaltoutf8('', b'\0'), 1) + + # embedded null chars/bytes + self.assertEqual(equaltoutf8('abc', b'abc\0def\0'), 1) + self.assertEqual(equaltoutf8('a\0bc', b'abc'), 0) + self.assertEqual(equaltoutf8('abc', b'a\0bc'), 0) + + # Surrogate characters are always treated as not equal + self.assertEqual(equaltoutf8('\udcfe', + '\udcfe'.encode("utf8", "surrogateescape")), 0) + self.assertEqual(equaltoutf8('\udcfe', + '\udcfe'.encode("utf8", "surrogatepass")), 0) + self.assertEqual(equaltoutf8('\ud801', + '\ud801'.encode("utf8", "surrogatepass")), 0) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_equaltoutf8andsize(self): + # Test PyUnicode_EqualToUTF8AndSize() + from _testcapi import unicode_equaltoutf8andsize as equaltoutf8andsize + from _testcapi import unicode_asutf8andsize as asutf8andsize + + strings = [ + 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', + '\U0001f600\U0001f601\U0001f602', + '\U0010ffff', + ] + for s in strings: + # Call PyUnicode_AsUTF8AndSize() which creates the UTF-8 + # encoded string cached in the Unicode object. + asutf8andsize(s, 0) + b = s.encode() + self.assertEqual(equaltoutf8andsize(s, b), 1) # Use the UTF-8 cache. + s2 = b.decode() # New Unicode object without the UTF-8 cache. + self.assertEqual(equaltoutf8andsize(s2, b), 1) + self.assertEqual(equaltoutf8andsize(s + 'x', b + b'x'), 1) + self.assertEqual(equaltoutf8andsize(s + 'x', b + b'y'), 0) + self.assertEqual(equaltoutf8andsize(s, b + b'\0'), 0) + self.assertEqual(equaltoutf8andsize(s2, b + b'\0'), 0) + self.assertEqual(equaltoutf8andsize(s + '\0', b + b'\0'), 1) + self.assertEqual(equaltoutf8andsize(s + '\0', b), 0) + self.assertEqual(equaltoutf8andsize(s2, b + b'x'), 0) + self.assertEqual(equaltoutf8andsize(s2, b[:-1]), 0) + self.assertEqual(equaltoutf8andsize(s2, b[:-1] + b'x'), 0) + # Not null-terminated, + self.assertEqual(equaltoutf8andsize(s, b + b'x', len(b)), 1) + self.assertEqual(equaltoutf8andsize(s2, b + b'x', len(b)), 1) + self.assertEqual(equaltoutf8andsize(s + '\0', b + b'\0x', len(b) + 1), 1) + self.assertEqual(equaltoutf8andsize(s2, b, len(b) - 1), 0) + + self.assertEqual(equaltoutf8andsize('', b''), 1) + self.assertEqual(equaltoutf8andsize('', b'\0'), 0) + self.assertEqual(equaltoutf8andsize('', b'x', 0), 1) + + # embedded null chars/bytes + self.assertEqual(equaltoutf8andsize('abc\0def', b'abc\0def'), 1) + self.assertEqual(equaltoutf8andsize('abc\0def\0', b'abc\0def\0'), 1) + + # Surrogate characters are always treated as not equal + self.assertEqual(equaltoutf8andsize('\udcfe', + '\udcfe'.encode("utf8", "surrogateescape")), 0) + self.assertEqual(equaltoutf8andsize('\udcfe', + '\udcfe'.encode("utf8", "surrogatepass")), 0) + self.assertEqual(equaltoutf8andsize('\ud801', + '\ud801'.encode("utf8", "surrogatepass")), 0) + + def check_not_equal_encoding(text, encoding): + self.assertEqual(equaltoutf8andsize(text, text.encode(encoding)), 0) + self.assertNotEqual(text.encode(encoding), text.encode("utf8")) + + # Strings encoded to other encodings are not equal to expected UTF8-encoding string + check_not_equal_encoding('Stéphane', 'latin1') + check_not_equal_encoding('Stéphane', 'utf-16-le') # embedded null characters + check_not_equal_encoding('北京市', 'gbk') + + # CRASHES equaltoutf8andsize('abc', b'abc', -1) + # CRASHES equaltoutf8andsize(b'abc', b'abc') + # CRASHES equaltoutf8andsize([], b'abc') + # CRASHES equaltoutf8andsize(NULL, b'abc') + # CRASHES equaltoutf8andsize('abc', NULL) + @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_richcompare(self): diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index 93f6ef752d0663..6b8855ec219d27 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -294,6 +294,18 @@ class C2: pass C2.hmm = "baz" self.assert_events([C1, [C2]]) + def test_all_watchers(self): + class C: pass + with ExitStack() as stack: + last_wid = -1 + # don't make assumptions about how many watchers are already + # registered, just go until we reach the max ID + while last_wid < self.TYPE_MAX_WATCHERS - 1: + last_wid = stack.enter_context(self.watcher()) + self.watch(last_wid, C) + C.foo = "bar" + self.assert_events([C]) + def test_watch_non_type(self): with self.watcher() as wid: with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): @@ -339,12 +351,10 @@ def test_clear_unassigned_watcher_id(self): self.clear_watcher(1) def test_no_more_ids_available(self): - contexts = [self.watcher() for i in range(self.TYPE_MAX_WATCHERS)] - with ExitStack() as stack: - for ctx in contexts: - stack.enter_context(ctx) - with self.assertRaisesRegex(RuntimeError, r"no more type watcher IDs"): - self.add_watcher() + with self.assertRaisesRegex(RuntimeError, r"no more type watcher IDs"): + with ExitStack() as stack: + for _ in range(self.TYPE_MAX_WATCHERS + 1): + stack.enter_context(self.watcher()) class TestCodeObjectWatchers(unittest.TestCase): diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 894e0ca67deabc..1531aad4f1f779 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -455,8 +455,8 @@ def __init__(self): self.attr = 1 a = A() - self.assertEqual(_testcapi.hasattr_string(a, "attr"), True) - self.assertEqual(_testcapi.hasattr_string(a, "noattr"), False) + self.assertEqual(_testcapi.object_hasattrstring(a, b"attr"), 1) + self.assertEqual(_testcapi.object_hasattrstring(a, b"noattr"), 0) self.assertIsNone(sys.exception()) def testDel(self): @@ -641,6 +641,14 @@ class A: class B: y = 0 __slots__ = ('z',) + class C: + __slots__ = ("y",) + + def __setattr__(self, name, value) -> None: + if name == "z": + super().__setattr__("y", 1) + else: + super().__setattr__(name, value) error_msg = "'A' object has no attribute 'x'" with self.assertRaisesRegex(AttributeError, error_msg): @@ -653,8 +661,16 @@ class B: B().x with self.assertRaisesRegex(AttributeError, error_msg): del B().x - with self.assertRaisesRegex(AttributeError, error_msg): + with self.assertRaisesRegex( + AttributeError, + "'B' object has no attribute 'x' and no __dict__ for setting new attributes" + ): B().x = 0 + with self.assertRaisesRegex( + AttributeError, + "'C' object has no attribute 'x'" + ): + C().x = 0 error_msg = "'B' object attribute 'y' is read-only" with self.assertRaisesRegex(AttributeError, error_msg): diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index e925ecca1b9c5d..627a329bb738a2 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -2,13 +2,16 @@ # Copyright 2012-2013 by Larry Hastings. # Licensed to the PSF under a contributor agreement. +from functools import partial from test import support, test_tools from test.support import os_helper +from test.support.os_helper import TESTFN, unlink from textwrap import dedent from unittest import TestCase -import collections +import contextlib import inspect import os.path +import re import sys import unittest @@ -18,97 +21,46 @@ from clinic import DSLParser -class _ParserBase(TestCase): +def _make_clinic(*, filename='clinic_tests'): + clang = clinic.CLanguage(None) + c = clinic.Clinic(clang, filename=filename, limited_capi=False) + c.block_parser = clinic.BlockParser('', clang) + return c + + +def _expect_failure(tc, parser, code, errmsg, *, filename=None, lineno=None, + strip=True): + """Helper for the parser tests. + + tc: unittest.TestCase; passed self in the wrapper + parser: the clinic parser used for this test case + code: a str with input text (clinic code) + errmsg: the expected error message + filename: str, optional filename + lineno: int, optional line number + """ + code = dedent(code) + if strip: + code = code.strip() + errmsg = re.escape(errmsg) + with tc.assertRaisesRegex(clinic.ClinicError, errmsg) as cm: + parser(code) + if filename is not None: + tc.assertEqual(cm.exception.filename, filename) + if lineno is not None: + tc.assertEqual(cm.exception.lineno, lineno) + return cm.exception + + +class ClinicWholeFileTest(TestCase): maxDiff = None - def expect_parser_failure(self, parser, _input): - with support.captured_stdout() as stdout: - with self.assertRaises(SystemExit): - parser(_input) - return stdout.getvalue() - - def parse_function_should_fail(self, _input): - return self.expect_parser_failure(self.parse_function, _input) - - -class FakeConverter: - def __init__(self, name, args): - self.name = name - self.args = args - - -class FakeConverterFactory: - def __init__(self, name): - self.name = name - - def __call__(self, name, default, **kwargs): - return FakeConverter(self.name, kwargs) - - -class FakeConvertersDict: - def __init__(self): - self.used_converters = {} - - def get(self, name, default): - return self.used_converters.setdefault(name, FakeConverterFactory(name)) - -c = clinic.Clinic(language='C', filename = "file") - -class FakeClinic: - def __init__(self): - self.converters = FakeConvertersDict() - self.legacy_converters = FakeConvertersDict() - self.language = clinic.CLanguage(None) - self.filename = None - self.destination_buffers = {} - self.block_parser = clinic.BlockParser('', self.language) - self.modules = collections.OrderedDict() - self.classes = collections.OrderedDict() - clinic.clinic = self - self.name = "FakeClinic" - self.line_prefix = self.line_suffix = '' - self.destinations = {} - self.add_destination("block", "buffer") - self.add_destination("file", "buffer") - self.add_destination("suppress", "suppress") - d = self.destinations.get - self.field_destinations = collections.OrderedDict(( - ('docstring_prototype', d('suppress')), - ('docstring_definition', d('block')), - ('methoddef_define', d('block')), - ('impl_prototype', d('block')), - ('parser_prototype', d('suppress')), - ('parser_definition', d('block')), - ('impl_definition', d('block')), - )) - - def get_destination(self, name): - d = self.destinations.get(name) - if not d: - sys.exit("Destination does not exist: " + repr(name)) - return d - - def add_destination(self, name, type, *args): - if name in self.destinations: - sys.exit("Destination already exists: " + repr(name)) - self.destinations[name] = clinic.Destination(name, type, self, *args) - - def is_directive(self, name): - return name == "module" - - def directive(self, name, args): - self.called_directives[name] = args - - _module_and_class = clinic.Clinic._module_and_class - - -class ClinicWholeFileTest(_ParserBase): - def setUp(self): - self.clinic = clinic.Clinic(clinic.CLanguage(None), filename="test.c") + def expect_failure(self, raw, errmsg, *, filename=None, lineno=None): + _expect_failure(self, self.clinic.parse, raw, errmsg, + filename=filename, lineno=lineno) - def expect_failure(self, raw): - _input = dedent(raw).strip() - return self.expect_parser_failure(self.clinic.parse, _input) + def setUp(self): + self.clinic = _make_clinic(filename="test.c") def test_eol(self): # regression test: @@ -133,12 +85,11 @@ def test_mangled_marker_line(self): [clinic start generated code]*/ /*[clinic end generated code: foo]*/ """ - msg = ( - 'Error in file "test.c" on line 3:\n' - "Mangled Argument Clinic marker line: '/*[clinic end generated code: foo]*/'\n" + err = ( + "Mangled Argument Clinic marker line: " + "'/*[clinic end generated code: foo]*/'" ) - out = self.expect_failure(raw) - self.assertEqual(out, msg) + self.expect_failure(raw, err, filename="test.c", lineno=3) def test_checksum_mismatch(self): raw = """ @@ -146,45 +97,35 @@ def test_checksum_mismatch(self): [clinic start generated code]*/ /*[clinic end generated code: output=0123456789abcdef input=fedcba9876543210]*/ """ - msg = ( - 'Error in file "test.c" on line 3:\n' - 'Checksum mismatch!\n' - 'Expected: 0123456789abcdef\n' - 'Computed: da39a3ee5e6b4b0d\n' - ) - out = self.expect_failure(raw) - self.assertIn(msg, out) + err = ("Checksum mismatch! " + "Expected '0123456789abcdef', computed 'da39a3ee5e6b4b0d'") + self.expect_failure(raw, err, filename="test.c", lineno=3) def test_garbage_after_stop_line(self): raw = """ /*[clinic input] [clinic start generated code]*/foobarfoobar! """ - msg = ( - 'Error in file "test.c" on line 2:\n' - "Garbage after stop line: 'foobarfoobar!'\n" - ) - out = self.expect_failure(raw) - self.assertEqual(out, msg) + err = "Garbage after stop line: 'foobarfoobar!'" + self.expect_failure(raw, err, filename="test.c", lineno=2) def test_whitespace_before_stop_line(self): raw = """ /*[clinic input] [clinic start generated code]*/ """ - msg = ( - 'Error in file "test.c" on line 2:\n' - "Whitespace is not allowed before the stop line: ' [clinic start generated code]*/'\n" + err = ( + "Whitespace is not allowed before the stop line: " + "' [clinic start generated code]*/'" ) - out = self.expect_failure(raw) - self.assertEqual(out, msg) + self.expect_failure(raw, err, filename="test.c", lineno=2) def test_parse_with_body_prefix(self): clang = clinic.CLanguage(None) clang.body_prefix = "//" clang.start_line = "//[{dsl_name} start]" clang.stop_line = "//[{dsl_name} stop]" - cl = clinic.Clinic(clang, filename="test.c") + cl = clinic.Clinic(clang, filename="test.c", limited_capi=False) raw = dedent(""" //[clinic start] //module test @@ -207,12 +148,8 @@ def test_cpp_monitor_fail_nested_block_comment(self): */ */ """ - msg = ( - 'Error in file "test.c" on line 2:\n' - 'Nested block comment!\n' - ) - out = self.expect_failure(raw) - self.assertEqual(out, msg) + err = 'Nested block comment!' + self.expect_failure(raw, err, filename="test.c", lineno=2) def test_cpp_monitor_fail_invalid_format_noarg(self): raw = """ @@ -220,12 +157,8 @@ def test_cpp_monitor_fail_invalid_format_noarg(self): a() #endif """ - msg = ( - 'Error in file "test.c" on line 1:\n' - 'Invalid format for #if line: no argument!\n' - ) - out = self.expect_failure(raw) - self.assertEqual(out, msg) + err = 'Invalid format for #if line: no argument!' + self.expect_failure(raw, err, filename="test.c", lineno=1) def test_cpp_monitor_fail_invalid_format_toomanyargs(self): raw = """ @@ -233,21 +166,549 @@ def test_cpp_monitor_fail_invalid_format_toomanyargs(self): a() #endif """ - msg = ( - 'Error in file "test.c" on line 1:\n' - 'Invalid format for #ifdef line: should be exactly one argument!\n' - ) - out = self.expect_failure(raw) - self.assertEqual(out, msg) + err = 'Invalid format for #ifdef line: should be exactly one argument!' + self.expect_failure(raw, err, filename="test.c", lineno=1) def test_cpp_monitor_fail_no_matching_if(self): raw = '#else' - msg = ( - 'Error in file "test.c" on line 1:\n' - '#else without matching #if / #ifdef / #ifndef!\n' + err = '#else without matching #if / #ifdef / #ifndef!' + self.expect_failure(raw, err, filename="test.c", lineno=1) + + def test_directive_output_unknown_preset(self): + raw = """ + /*[clinic input] + output preset nosuchpreset + [clinic start generated code]*/ + """ + err = "Unknown preset 'nosuchpreset'" + self.expect_failure(raw, err) + + def test_directive_output_cant_pop(self): + raw = """ + /*[clinic input] + output pop + [clinic start generated code]*/ + """ + err = "Can't 'output pop', stack is empty" + self.expect_failure(raw, err) + + def test_directive_output_print(self): + raw = dedent(""" + /*[clinic input] + output print 'I told you once.' + [clinic start generated code]*/ + """) + out = self.clinic.parse(raw) + # The generated output will differ for every run, but we can check that + # it starts with the clinic block, we check that it contains all the + # expected fields, and we check that it contains the checksum line. + self.assertTrue(out.startswith(dedent(""" + /*[clinic input] + output print 'I told you once.' + [clinic start generated code]*/ + """))) + fields = { + "cpp_endif", + "cpp_if", + "docstring_definition", + "docstring_prototype", + "impl_definition", + "impl_prototype", + "methoddef_define", + "methoddef_ifndef", + "parser_definition", + "parser_prototype", + } + for field in fields: + with self.subTest(field=field): + self.assertIn(field, out) + last_line = out.rstrip().split("\n")[-1] + self.assertTrue( + last_line.startswith("/*[clinic end generated code: output=") + ) + + def test_directive_wrong_arg_number(self): + raw = dedent(""" + /*[clinic input] + preserve foo bar baz eggs spam ham mushrooms + [clinic start generated code]*/ + """) + err = "takes 1 positional argument but 8 were given" + self.expect_failure(raw, err) + + def test_unknown_destination_command(self): + raw = """ + /*[clinic input] + destination buffer nosuchcommand + [clinic start generated code]*/ + """ + err = "unknown destination command 'nosuchcommand'" + self.expect_failure(raw, err) + + def test_no_access_to_members_in_converter_init(self): + raw = """ + /*[python input] + class Custom_converter(CConverter): + converter = "some_c_function" + def converter_init(self): + self.function.noaccess + [python start generated code]*/ + /*[clinic input] + module test + test.fn + a: Custom + [clinic start generated code]*/ + """ + err = ( + "accessing self.function inside converter_init is disallowed!" + ) + self.expect_failure(raw, err) + + @staticmethod + @contextlib.contextmanager + def _clinic_version(new_version): + """Helper for test_version_*() tests""" + _saved = clinic.version + clinic.version = new_version + try: + yield + finally: + clinic.version = _saved + + def test_version_directive(self): + dataset = ( + # (clinic version, required version) + ('3', '2'), # required version < clinic version + ('3.1', '3.0'), # required version < clinic version + ('1.2b0', '1.2a7'), # required version < clinic version + ('5', '5'), # required version == clinic version + ('6.1', '6.1'), # required version == clinic version + ('1.2b3', '1.2b3'), # required version == clinic version + ) + for clinic_version, required_version in dataset: + with self.subTest(clinic_version=clinic_version, + required_version=required_version): + with self._clinic_version(clinic_version): + block = dedent(f""" + /*[clinic input] + version {required_version} + [clinic start generated code]*/ + """) + self.clinic.parse(block) + + def test_version_directive_insufficient_version(self): + with self._clinic_version('4'): + err = ( + "Insufficient Clinic version!\n" + " Version: 4\n" + " Required: 5" + ) + block = """ + /*[clinic input] + version 5 + [clinic start generated code]*/ + """ + self.expect_failure(block, err) + + def test_version_directive_illegal_char(self): + err = "Illegal character 'v' in version string 'v5'" + block = """ + /*[clinic input] + version v5 + [clinic start generated code]*/ + """ + self.expect_failure(block, err) + + def test_version_directive_unsupported_string(self): + err = "Unsupported version string: '.-'" + block = """ + /*[clinic input] + version .- + [clinic start generated code]*/ + """ + self.expect_failure(block, err) + + def test_clone_mismatch(self): + err = "'kind' of function and cloned function don't match!" + block = """ + /*[clinic input] + module m + @classmethod + m.f1 + a: object + [clinic start generated code]*/ + /*[clinic input] + @staticmethod + m.f2 = m.f1 + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=9) + + def test_badly_formed_return_annotation(self): + err = "Badly formed annotation for 'm.f': 'Custom'" + block = """ + /*[python input] + class Custom_return_converter(CReturnConverter): + def __init__(self): + raise ValueError("abc") + [python start generated code]*/ + /*[clinic input] + module m + m.f -> Custom + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=8) + + def test_module_already_got_one(self): + err = "Already defined module 'm'!" + block = """ + /*[clinic input] + module m + module m + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=3) + + def test_destination_already_got_one(self): + err = "Destination already exists: 'test'" + block = """ + /*[clinic input] + destination test new buffer + destination test new buffer + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=3) + + def test_destination_does_not_exist(self): + err = "Destination does not exist: '/dev/null'" + block = """ + /*[clinic input] + output everything /dev/null + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=2) + + def test_class_already_got_one(self): + err = "Already defined class 'C'!" + block = """ + /*[clinic input] + class C "" "" + class C "" "" + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=3) + + def test_cant_nest_module_inside_class(self): + err = "Can't nest a module inside a class!" + block = """ + /*[clinic input] + class C "" "" + module C.m + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=3) + + def test_dest_buffer_not_empty_at_eof(self): + expected_warning = ("Destination buffer 'buffer' not empty at " + "end of file, emptying.") + expected_generated = dedent(""" + /*[clinic input] + output everything buffer + fn + a: object + / + [clinic start generated code]*/ + /*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c4668687f5fd002]*/ + + /*[clinic input] + dump buffer + [clinic start generated code]*/ + + PyDoc_VAR(fn__doc__); + + PyDoc_STRVAR(fn__doc__, + "fn($module, a, /)\\n" + "--\\n" + "\\n"); + + #define FN_METHODDEF \\ + {"fn", (PyCFunction)fn, METH_O, fn__doc__}, + + static PyObject * + fn(PyObject *module, PyObject *a) + /*[clinic end generated code: output=be6798b148ab4e53 input=524ce2e021e4eba6]*/ + """) + block = dedent(""" + /*[clinic input] + output everything buffer + fn + a: object + / + [clinic start generated code]*/ + """) + with support.captured_stdout() as stdout: + generated = self.clinic.parse(block) + self.assertIn(expected_warning, stdout.getvalue()) + self.assertEqual(generated, expected_generated) + + def test_dest_clear(self): + err = "Can't clear destination 'file': it's not of type 'buffer'" + block = """ + /*[clinic input] + destination file clear + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=2) + + def test_directive_set_misuse(self): + err = "unknown variable 'ets'" + block = """ + /*[clinic input] + set ets tse + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=2) + + def test_directive_set_prefix(self): + block = dedent(""" + /*[clinic input] + set line_prefix '// ' + output everything suppress + output docstring_prototype buffer + fn + a: object + / + [clinic start generated code]*/ + /* We need to dump the buffer. + * If not, Argument Clinic will emit a warning */ + /*[clinic input] + dump buffer + [clinic start generated code]*/ + """) + generated = self.clinic.parse(block) + expected_docstring_prototype = "// PyDoc_VAR(fn__doc__);" + self.assertIn(expected_docstring_prototype, generated) + + def test_directive_set_suffix(self): + block = dedent(""" + /*[clinic input] + set line_suffix ' // test' + output everything suppress + output docstring_prototype buffer + fn + a: object + / + [clinic start generated code]*/ + /* We need to dump the buffer. + * If not, Argument Clinic will emit a warning */ + /*[clinic input] + dump buffer + [clinic start generated code]*/ + """) + generated = self.clinic.parse(block) + expected_docstring_prototype = "PyDoc_VAR(fn__doc__); // test" + self.assertIn(expected_docstring_prototype, generated) + + def test_directive_set_prefix_and_suffix(self): + block = dedent(""" + /*[clinic input] + set line_prefix '{block comment start} ' + set line_suffix ' {block comment end}' + output everything suppress + output docstring_prototype buffer + fn + a: object + / + [clinic start generated code]*/ + /* We need to dump the buffer. + * If not, Argument Clinic will emit a warning */ + /*[clinic input] + dump buffer + [clinic start generated code]*/ + """) + generated = self.clinic.parse(block) + expected_docstring_prototype = "/* PyDoc_VAR(fn__doc__); */" + self.assertIn(expected_docstring_prototype, generated) + + def test_directive_printout(self): + block = dedent(""" + /*[clinic input] + output everything buffer + printout test + [clinic start generated code]*/ + """) + expected = dedent(""" + /*[clinic input] + output everything buffer + printout test + [clinic start generated code]*/ + test + /*[clinic end generated code: output=4e1243bd22c66e76 input=898f1a32965d44ca]*/ + """) + generated = self.clinic.parse(block) + self.assertEqual(generated, expected) + + def test_directive_preserve_twice(self): + err = "Can't have 'preserve' twice in one block!" + block = """ + /*[clinic input] + preserve + preserve + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=3) + + def test_directive_preserve_input(self): + err = "'preserve' only works for blocks that don't produce any output!" + block = """ + /*[clinic input] + preserve + fn + a: object + / + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=6) + + def test_directive_preserve_output(self): + block = dedent(""" + /*[clinic input] + output everything buffer + preserve + [clinic start generated code]*/ + // Preserve this + /*[clinic end generated code: output=eaa49677ae4c1f7d input=559b5db18fddae6a]*/ + /*[clinic input] + dump buffer + [clinic start generated code]*/ + /*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ + """) + generated = self.clinic.parse(block) + self.assertEqual(generated, block) + + def test_directive_output_invalid_command(self): + err = dedent(""" + Invalid command or destination name 'cmd'. Must be one of: + - 'preset' + - 'push' + - 'pop' + - 'print' + - 'everything' + - 'cpp_if' + - 'docstring_prototype' + - 'docstring_definition' + - 'methoddef_define' + - 'impl_prototype' + - 'parser_prototype' + - 'parser_definition' + - 'cpp_endif' + - 'methoddef_ifndef' + - 'impl_definition' + """).strip() + block = """ + /*[clinic input] + output cmd buffer + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=2) + + def test_validate_cloned_init(self): + block = """ + /*[clinic input] + class C "void *" "" + C.meth + a: int + [clinic start generated code]*/ + /*[clinic input] + @classmethod + C.__init__ = C.meth + [clinic start generated code]*/ + """ + err = "'__init__' must be a normal method, not a class or static method" + self.expect_failure(block, err, lineno=8) + + def test_validate_cloned_new(self): + block = """ + /*[clinic input] + class C "void *" "" + C.meth + a: int + [clinic start generated code]*/ + /*[clinic input] + C.__new__ = C.meth + [clinic start generated code]*/ + """ + err = "'__new__' must be a class method" + self.expect_failure(block, err, lineno=7) + + def test_no_c_basename_cloned(self): + block = """ + /*[clinic input] + foo2 + [clinic start generated code]*/ + /*[clinic input] + foo as = foo2 + [clinic start generated code]*/ + """ + err = "No C basename provided after 'as' keyword" + self.expect_failure(block, err, lineno=5) + + def test_cloned_with_custom_c_basename(self): + raw = dedent(""" + /*[clinic input] + # Make sure we don't create spurious clinic/ directories. + output everything suppress + foo2 + [clinic start generated code]*/ + + /*[clinic input] + foo as foo1 = foo2 + [clinic start generated code]*/ + """) + self.clinic.parse(raw) + funcs = self.clinic.functions + self.assertEqual(len(funcs), 2) + self.assertEqual(funcs[1].name, "foo") + self.assertEqual(funcs[1].c_basename, "foo1") + + def test_cloned_with_illegal_c_basename(self): + block = """ + /*[clinic input] + class C "void *" "" + foo1 + [clinic start generated code]*/ + + /*[clinic input] + foo2 as .illegal. = foo1 + [clinic start generated code]*/ + """ + err = "Illegal C basename: '.illegal.'" + self.expect_failure(block, err, lineno=7) + + +class ParseFileUnitTest(TestCase): + def expect_parsing_failure( + self, *, filename, expected_error, verify=True, output=None + ): + errmsg = re.escape(dedent(expected_error).strip()) + with self.assertRaisesRegex(clinic.ClinicError, errmsg): + clinic.parse_file(filename, limited_capi=False) + + def test_parse_file_no_extension(self) -> None: + self.expect_parsing_failure( + filename="foo", + expected_error="Can't extract file type for file 'foo'" ) - out = self.expect_failure(raw) - self.assertEqual(out, msg) + + def test_parse_file_strange_extension(self) -> None: + filenames_to_errors = { + "foo.rs": "Can't identify file type for file 'foo.rs'", + "foo.hs": "Can't identify file type for file 'foo.hs'", + "foo.js": "Can't identify file type for file 'foo.js'", + } + for filename, errmsg in filenames_to_errors.items(): + with self.subTest(filename=filename): + self.expect_parsing_failure(filename=filename, expected_error=errmsg) class ClinicGroupPermuterTest(TestCase): @@ -371,8 +832,9 @@ def _test(self, input, output): blocks = list(clinic.BlockParser(input, language)) writer = clinic.BlockPrinter(language) + c = _make_clinic() for block in blocks: - writer.print_block(block) + writer.print_block(block, limited_capi=c.limited_capi, header_includes=c.includes) output = writer.f.getvalue() assert output == input, "output != input!\n\noutput " + repr(output) + "\n\n input " + repr(input) @@ -398,7 +860,7 @@ def test_round_trip_2(self): def _test_clinic(self, input, output): language = clinic.CLanguage(None) - c = clinic.Clinic(language, filename="file") + c = clinic.Clinic(language, filename="file", limited_capi=False) c.parsers['inert'] = InertParser(c) c.parsers['copy'] = CopyParser(c) computed = c.parse(input) @@ -426,14 +888,35 @@ def test_clinic_1(self): """) -class ClinicParserTest(_ParserBase): +class ClinicParserTest(TestCase): + + def parse(self, text): + c = _make_clinic() + parser = DSLParser(c) + block = clinic.Block(text) + parser.parse(block) + return block + + def parse_function(self, text, signatures_in_block=2, function_index=1): + block = self.parse(text) + s = block.signatures + self.assertEqual(len(s), signatures_in_block) + assert isinstance(s[0], clinic.Module) + assert isinstance(s[function_index], clinic.Function) + return s[function_index] + + def expect_failure(self, block, err, *, + filename=None, lineno=None, strip=True): + return _expect_failure(self, self.parse_function, block, err, + filename=filename, lineno=lineno, strip=strip) + def checkDocstring(self, fn, expected): self.assertTrue(hasattr(fn, "docstring")) - self.assertEqual(fn.docstring.strip(), - dedent(expected).strip()) + self.assertEqual(dedent(expected).strip(), + fn.docstring.strip()) def test_trivial(self): - parser = DSLParser(FakeClinic()) + parser = DSLParser(_make_clinic()) block = clinic.Block(""" module os os.access @@ -486,7 +969,7 @@ def test_param_with_continuations(self): p = function.parameters['follow_symlinks'] self.assertEqual(True, p.default) - def test_param_default_expression(self): + def test_param_default_expr_named_constant(self): function = self.parse_function(""" module os os.access @@ -496,17 +979,62 @@ def test_param_default_expression(self): self.assertEqual(sys.maxsize, p.default) self.assertEqual("MAXSIZE", p.converter.c_default) - expected_msg = ( - "Error on line 0:\n" - "When you specify a named constant ('sys.maxsize') as your default value,\n" - "you MUST specify a valid c_default.\n" + err = ( + "When you specify a named constant ('sys.maxsize') as your default value, " + "you MUST specify a valid c_default." ) - out = self.parse_function_should_fail(""" + block = """ module os os.access follow_symlinks: int = sys.maxsize - """) - self.assertEqual(out, expected_msg) + """ + self.expect_failure(block, err, lineno=2) + + def test_param_with_bizarre_default_fails_correctly(self): + template = """ + module os + os.access + follow_symlinks: int = {default} + """ + err = "Unsupported expression as default value" + for bad_default_value in ( + "{1, 2, 3}", + "3 if bool() else 4", + "[x for x in range(42)]" + ): + with self.subTest(bad_default=bad_default_value): + block = template.format(default=bad_default_value) + self.expect_failure(block, err, lineno=2) + + def test_unspecified_not_allowed_as_default_value(self): + block = """ + module os + os.access + follow_symlinks: int(c_default='MAXSIZE') = unspecified + """ + err = "'unspecified' is not a legal default value!" + exc = self.expect_failure(block, err, lineno=2) + self.assertNotIn('Malformed expression given as default value', str(exc)) + + def test_malformed_expression_as_default_value(self): + block = """ + module os + os.access + follow_symlinks: int(c_default='MAXSIZE') = 1/0 + """ + err = "Malformed expression given as default value" + self.expect_failure(block, err, lineno=2) + + def test_param_default_expr_binop(self): + err = ( + "When you specify an expression ('a + b') as your default value, " + "you MUST specify a valid c_default." + ) + block = """ + fn + follow_symlinks: int = a + b + """ + self.expect_failure(block, err, lineno=1) def test_param_no_docstring(self): function = self.parse_function(""" @@ -515,23 +1043,22 @@ def test_param_no_docstring(self): follow_symlinks: bool = True something_else: str = '' """) - p = function.parameters['follow_symlinks'] self.assertEqual(3, len(function.parameters)) conv = function.parameters['something_else'].converter self.assertIsInstance(conv, clinic.str_converter) def test_param_default_parameters_out_of_order(self): - expected_msg = ( - "Error on line 0:\n" - "Can't have a parameter without a default ('something_else')\n" - "after a parameter with a default!\n" + err = ( + "Can't have a parameter without a default ('something_else') " + "after a parameter with a default!" ) - out = self.parse_function_should_fail(""" + block = """ module os os.access follow_symlinks: bool = True - something_else: str""") - self.assertEqual(out, expected_msg) + something_else: str + """ + self.expect_failure(block, err, lineno=3) def disabled_test_converter_arguments(self): function = self.parse_function(""" @@ -549,8 +1076,12 @@ def test_function_docstring(self): path: str Path to be examined + Ensure that multiple lines are indented correctly. Perform a stat system call on the given path. + + Ensure that multiple lines are indented correctly. + Ensure that multiple lines are indented correctly. """) self.checkDocstring(function, """ stat($module, /, path) @@ -560,6 +1091,32 @@ def test_function_docstring(self): path Path to be examined + Ensure that multiple lines are indented correctly. + + Ensure that multiple lines are indented correctly. + Ensure that multiple lines are indented correctly. + """) + + def test_docstring_trailing_whitespace(self): + function = self.parse_function( + "module t\n" + "t.s\n" + " a: object\n" + " Param docstring with trailing whitespace \n" + "Func docstring summary with trailing whitespace \n" + " \n" + "Func docstring body with trailing whitespace \n" + ) + self.checkDocstring(function, """ + s($module, /, a) + -- + + Func docstring summary with trailing whitespace + + a + Param docstring with trailing whitespace + + Func docstring body with trailing whitespace """) def test_explicit_parameters_in_docstring(self): @@ -586,6 +1143,38 @@ def test_explicit_parameters_in_docstring(self): Okay, we're done here. """) + def test_docstring_with_comments(self): + function = self.parse_function(dedent(""" + module foo + foo.bar + x: int + # We're about to have + # the documentation for x. + Documentation for x. + # We've just had + # the documentation for x. + y: int + + # We're about to have + # the documentation for foo. + This is the documentation for foo. + # We've just had + # the documentation for foo. + + Okay, we're done here. + """)) + self.checkDocstring(function, """ + bar($module, /, x, y) + -- + + This is the documentation for foo. + + x + Documentation for x. + + Okay, we're done here. + """) + def test_parser_regression_special_character_in_parameter_column_of_docstring_first_line(self): function = self.parse_function(dedent(""" module os @@ -607,6 +1196,43 @@ def test_c_name(self): """) self.assertEqual("os_stat_fn", function.c_basename) + def test_base_invalid_syntax(self): + block = """ + module os + os.stat + invalid syntax: int = 42 + """ + err = dedent(r""" + Function 'stat' has an invalid parameter declaration: + \s+'invalid syntax: int = 42' + """).strip() + with self.assertRaisesRegex(clinic.ClinicError, err): + self.parse_function(block) + + def test_param_default_invalid_syntax(self): + block = """ + module os + os.stat + x: int = invalid syntax + """ + err = r"Syntax error: 'x = invalid syntax\n'" + self.expect_failure(block, err, lineno=2) + + def test_cloning_nonexistent_function_correctly_fails(self): + block = """ + cloned = fooooooooooooooooo + This is trying to clone a nonexistent function!! + """ + err = "Couldn't find existing function 'fooooooooooooooooo'!" + with support.captured_stderr() as stderr: + self.expect_failure(block, err, lineno=0) + expected_debug_print = dedent("""\ + cls=None, module=, existing='fooooooooooooooooo' + (cls or module).functions=[] + """) + stderr = stderr.getvalue() + self.assertIn(expected_debug_print, stderr) + def test_return_converter(self): function = self.parse_function(""" module os @@ -614,6 +1240,30 @@ def test_return_converter(self): """) self.assertIsInstance(function.return_converter, clinic.int_return_converter) + def test_return_converter_invalid_syntax(self): + block = """ + module os + os.stat -> invalid syntax + """ + err = "Badly formed annotation for 'os.stat': 'invalid syntax'" + self.expect_failure(block, err) + + def test_legacy_converter_disallowed_in_return_annotation(self): + block = """ + module os + os.stat -> "s" + """ + err = "Legacy converter 's' not allowed as a return converter" + self.expect_failure(block, err) + + def test_unknown_return_converter(self): + block = """ + module os + os.stat -> fooooooooooooooooooooooo + """ + err = "No available return converter called 'fooooooooooooooooooooooo'" + self.expect_failure(block, err) + def test_star(self): function = self.parse_function(""" module os @@ -757,19 +1407,12 @@ def test_nested_groups(self): Attributes for the character. """) - def parse_function_should_fail(self, s): - with support.captured_stdout() as stdout: - with self.assertRaises(SystemExit): - self.parse_function(s) - return stdout.getvalue() - def test_disallowed_grouping__two_top_groups_on_left(self): - expected_msg = ( - 'Error on line 0:\n' - 'Function two_top_groups_on_left has an unsupported group ' - 'configuration. (Unexpected state 2.b)\n' + err = ( + "Function 'two_top_groups_on_left' has an unsupported group " + "configuration. (Unexpected state 2.b)" ) - out = self.parse_function_should_fail(""" + block = """ module foo foo.two_top_groups_on_left [ @@ -779,11 +1422,11 @@ def test_disallowed_grouping__two_top_groups_on_left(self): group2 : int ] param: int - """) - self.assertEqual(out, expected_msg) + """ + self.expect_failure(block, err, lineno=5) def test_disallowed_grouping__two_top_groups_on_right(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.two_top_groups_on_right param: int @@ -793,15 +1436,15 @@ def test_disallowed_grouping__two_top_groups_on_right(self): [ group2 : int ] - """) - msg = ( - "Function two_top_groups_on_right has an unsupported group " + """ + err = ( + "Function 'two_top_groups_on_right' has an unsupported group " "configuration. (Unexpected state 6.b)" ) - self.assertIn(msg, out) + self.expect_failure(block, err) def test_disallowed_grouping__parameter_after_group_on_right(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.parameter_after_group_on_right param: int @@ -811,15 +1454,15 @@ def test_disallowed_grouping__parameter_after_group_on_right(self): ] group2 : int ] - """) - msg = ( + """ + err = ( "Function parameter_after_group_on_right has an unsupported group " "configuration. (Unexpected state 6.a)" ) - self.assertIn(msg, out) + self.expect_failure(block, err) def test_disallowed_grouping__group_after_parameter_on_left(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.group_after_parameter_on_left [ @@ -829,15 +1472,15 @@ def test_disallowed_grouping__group_after_parameter_on_left(self): ] ] param: int - """) - msg = ( - "Function group_after_parameter_on_left has an unsupported group " + """ + err = ( + "Function 'group_after_parameter_on_left' has an unsupported group " "configuration. (Unexpected state 2.b)" ) - self.assertIn(msg, out) + self.expect_failure(block, err) def test_disallowed_grouping__empty_group_on_left(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.empty_group [ @@ -846,15 +1489,15 @@ def test_disallowed_grouping__empty_group_on_left(self): group2 : int ] param: int - """) - msg = ( - "Function empty_group has an empty group.\n" + """ + err = ( + "Function 'empty_group' has an empty group. " "All groups must contain at least one parameter." ) - self.assertIn(msg, out) + self.expect_failure(block, err) def test_disallowed_grouping__empty_group_on_right(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.empty_group param: int @@ -863,24 +1506,45 @@ def test_disallowed_grouping__empty_group_on_right(self): ] group2 : int ] - """) - msg = ( - "Function empty_group has an empty group.\n" + """ + err = ( + "Function 'empty_group' has an empty group. " "All groups must contain at least one parameter." ) - self.assertIn(msg, out) + self.expect_failure(block, err) def test_disallowed_grouping__no_matching_bracket(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.empty_group param: int ] group2: int ] + """ + err = "Function 'empty_group' has a ']' without a matching '['" + self.expect_failure(block, err) + + def test_disallowed_grouping__must_be_position_only(self): + dataset = (""" + with_kwds + [ + * + a: object + ] + """, """ + with_kwds + [ + a: object + ] """) - msg = "Function empty_group has a ] without a matching [." - self.assertIn(msg, out) + err = ( + "You cannot use optional groups ('[' and ']') unless all " + "parameters are positional-only ('/')" + ) + for block in dataset: + with self.subTest(block=block): + self.expect_failure(block, err) def test_no_parameters(self): function = self.parse_function(""" @@ -909,31 +1573,37 @@ class foo.Bar "unused" "notneeded" self.assertEqual(1, len(function.parameters)) def test_illegal_module_line(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.bar => int / - """) - msg = "Illegal function name: foo.bar => int" - self.assertIn(msg, out) + """ + err = "Illegal function name: 'foo.bar => int'" + self.expect_failure(block, err) def test_illegal_c_basename(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.bar as 935 / - """) - msg = "Illegal C basename: 935" - self.assertIn(msg, out) + """ + err = "Illegal C basename: '935'" + self.expect_failure(block, err) + + def test_no_c_basename(self): + block = "foo as " + err = "No C basename provided after 'as' keyword" + self.expect_failure(block, err, strip=False) def test_single_star(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.bar * * - """) - self.assertIn("Function bar uses '*' more than once.", out) + """ + err = "Function 'bar' uses '*' more than once." + self.expect_failure(block, err) def test_parameters_required_after_star(self): dataset = ( @@ -942,39 +1612,260 @@ def test_parameters_required_after_star(self): "module foo\nfoo.bar\n this: int\n *", "module foo\nfoo.bar\n this: int\n *\nDocstring.", ) - msg = "Function bar specifies '*' without any parameters afterwards." + err = "Function 'bar' specifies '*' without following parameters." for block in dataset: with self.subTest(block=block): - out = self.parse_function_should_fail(block) - self.assertIn(msg, out) + self.expect_failure(block, err) + + def test_fulldisplayname_class(self): + dataset = ( + ("T", """ + class T "void *" "" + T.__init__ + """), + ("m.T", """ + module m + class m.T "void *" "" + @classmethod + m.T.__new__ + """), + ("m.T.C", """ + module m + class m.T "void *" "" + class m.T.C "void *" "" + m.T.C.__init__ + """), + ) + for name, code in dataset: + with self.subTest(name=name, code=code): + block = self.parse(code) + func = block.signatures[-1] + self.assertEqual(func.fulldisplayname, name) + + def test_fulldisplayname_meth(self): + dataset = ( + ("func", "func"), + ("m.func", """ + module m + m.func + """), + ("T.meth", """ + class T "void *" "" + T.meth + """), + ("m.T.meth", """ + module m + class m.T "void *" "" + m.T.meth + """), + ("m.T.C.meth", """ + module m + class m.T "void *" "" + class m.T.C "void *" "" + m.T.C.meth + """), + ) + for name, code in dataset: + with self.subTest(name=name, code=code): + block = self.parse(code) + func = block.signatures[-1] + self.assertEqual(func.fulldisplayname, name) + + def test_depr_star_invalid_format_1(self): + block = """ + module foo + foo.bar + this: int + * [from 3] + Docstring. + """ + err = ( + "Function 'bar': expected format '[from major.minor]' " + "where 'major' and 'minor' are integers; got '3'" + ) + self.expect_failure(block, err, lineno=3) + + def test_depr_star_invalid_format_2(self): + block = """ + module foo + foo.bar + this: int + * [from a.b] + Docstring. + """ + err = ( + "Function 'bar': expected format '[from major.minor]' " + "where 'major' and 'minor' are integers; got 'a.b'" + ) + self.expect_failure(block, err, lineno=3) + + def test_depr_star_invalid_format_3(self): + block = """ + module foo + foo.bar + this: int + * [from 1.2.3] + Docstring. + """ + err = ( + "Function 'bar': expected format '[from major.minor]' " + "where 'major' and 'minor' are integers; got '1.2.3'" + ) + self.expect_failure(block, err, lineno=3) + + def test_parameters_required_after_depr_star(self): + block = """ + module foo + foo.bar + this: int + * [from 3.14] + Docstring. + """ + err = ( + "Function 'bar' specifies '* [from ...]' without " + "following parameters." + ) + self.expect_failure(block, err, lineno=4) + + def test_parameters_required_after_depr_star2(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + * + b: int + Docstring. + """ + err = ( + "Function 'bar' specifies '* [from ...]' without " + "following parameters." + ) + self.expect_failure(block, err, lineno=4) + + def test_depr_star_must_come_before_star(self): + block = """ + module foo + foo.bar + this: int + * + * [from 3.14] + Docstring. + """ + err = "Function 'bar': '* [from ...]' must precede '*'" + self.expect_failure(block, err, lineno=4) + + def test_depr_star_duplicate(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + b: int + * [from 3.14] + c: int + Docstring. + """ + err = "Function 'bar' uses '* [from 3.14]' more than once." + self.expect_failure(block, err, lineno=5) + + def test_depr_star_duplicate2(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + b: int + * [from 3.15] + c: int + Docstring. + """ + err = "Function 'bar': '* [from 3.15]' must precede '* [from 3.14]'" + self.expect_failure(block, err, lineno=5) + + def test_depr_slash_duplicate(self): + block = """ + module foo + foo.bar + a: int + / [from 3.14] + b: int + / [from 3.14] + c: int + Docstring. + """ + err = "Function 'bar' uses '/ [from 3.14]' more than once." + self.expect_failure(block, err, lineno=5) + + def test_depr_slash_duplicate2(self): + block = """ + module foo + foo.bar + a: int + / [from 3.15] + b: int + / [from 3.14] + c: int + Docstring. + """ + err = "Function 'bar': '/ [from 3.14]' must precede '/ [from 3.15]'" + self.expect_failure(block, err, lineno=5) def test_single_slash(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.bar / / - """) - msg = ( - "Function bar has an unsupported group configuration. " + """ + err = ( + "Function 'bar' has an unsupported group configuration. " "(Unexpected state 0.d)" ) - self.assertIn(msg, out) + self.expect_failure(block, err) + + def test_parameters_required_before_depr_slash(self): + block = """ + module foo + foo.bar + / [from 3.14] + Docstring. + """ + err = ( + "Function 'bar' specifies '/ [from ...]' without " + "preceding parameters." + ) + self.expect_failure(block, err, lineno=2) + + def test_parameters_required_before_depr_slash2(self): + block = """ + module foo + foo.bar + a: int + / + / [from 3.14] + Docstring. + """ + err = ( + "Function 'bar' specifies '/ [from ...]' without " + "preceding parameters." + ) + self.expect_failure(block, err, lineno=4) def test_double_slash(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.bar a: int / b: int / - """) - msg = "Function bar uses '/' more than once." - self.assertIn(msg, out) + """ + err = "Function 'bar' uses '/' more than once." + self.expect_failure(block, err) def test_mix_star_and_slash(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.bar x: int @@ -982,38 +1873,84 @@ def test_mix_star_and_slash(self): * z: int / - """) - msg = ( - "Function bar mixes keyword-only and positional-only parameters, " - "which is unsupported." - ) - self.assertIn(msg, out) + """ + err = "Function 'bar': '/' must precede '*'" + self.expect_failure(block, err) + + def test_depr_star_must_come_after_slash(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + / + b: int + Docstring. + """ + err = "Function 'bar': '/' must precede '* [from ...]'" + self.expect_failure(block, err, lineno=4) + + def test_depr_star_must_come_after_depr_slash(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + / [from 3.14] + b: int + Docstring. + """ + err = "Function 'bar': '/ [from ...]' must precede '* [from ...]'" + self.expect_failure(block, err, lineno=4) + + def test_star_must_come_after_depr_slash(self): + block = """ + module foo + foo.bar + a: int + * + / [from 3.14] + b: int + Docstring. + """ + err = "Function 'bar': '/ [from ...]' must precede '*'" + self.expect_failure(block, err, lineno=4) + + def test_depr_slash_must_come_after_slash(self): + block = """ + module foo + foo.bar + a: int + / [from 3.14] + / + b: int + Docstring. + """ + err = "Function 'bar': '/' must precede '/ [from ...]'" + self.expect_failure(block, err, lineno=4) def test_parameters_not_permitted_after_slash_for_now(self): - out = self.parse_function_should_fail(""" + block = """ module foo foo.bar / x: int - """) - msg = ( - "Function bar has an unsupported group configuration. " + """ + err = ( + "Function 'bar' has an unsupported group configuration. " "(Unexpected state 0.d)" ) - self.assertIn(msg, out) + self.expect_failure(block, err) def test_parameters_no_more_than_one_vararg(self): - expected_msg = ( - "Error on line 0:\n" - "Too many var args\n" - ) - out = self.parse_function_should_fail(""" + err = "Too many var args" + block = """ module foo foo.bar *vararg1: object *vararg2: object - """) - self.assertEqual(out, expected_msg) + """ + self.expect_failure(block, err, lineno=0) def test_function_not_at_column_0(self): function = self.parse_function(""" @@ -1035,9 +1972,86 @@ def test_function_not_at_column_0(self): Nested docstring here, goeth. """) + def test_docstring_only_summary(self): + function = self.parse_function(""" + module m + m.f + summary + """) + self.checkDocstring(function, """ + f($module, /) + -- + + summary + """) + + def test_docstring_empty_lines(self): + function = self.parse_function(""" + module m + m.f + + + """) + self.checkDocstring(function, """ + f($module, /) + -- + """) + + def test_docstring_explicit_params_placement(self): + function = self.parse_function(""" + module m + m.f + a: int + Param docstring for 'a' will be included + b: int + c: int + Param docstring for 'c' will be included + This is the summary line. + + We'll now place the params section here: + {parameters} + And now for something completely different! + (Note the added newline) + """) + self.checkDocstring(function, """ + f($module, /, a, b, c) + -- + + This is the summary line. + + We'll now place the params section here: + a + Param docstring for 'a' will be included + c + Param docstring for 'c' will be included + + And now for something completely different! + (Note the added newline) + """) + + def test_indent_stack_no_tabs(self): + block = """ + module foo + foo.bar + *vararg1: object + \t*vararg2: object + """ + err = ("Tab characters are illegal in the Clinic DSL: " + r"'\t*vararg2: object'") + self.expect_failure(block, err) + + def test_indent_stack_illegal_outdent(self): + block = """ + module foo + foo.bar + a: object + b: object + """ + err = "Illegal outdent" + self.expect_failure(block, err) + def test_directive(self): - c = FakeClinic() - parser = DSLParser(c) + parser = DSLParser(_make_clinic()) parser.flag = False parser.directives['setflag'] = lambda : setattr(parser, 'flag', True) block = clinic.Block("setflag") @@ -1051,10 +2065,7 @@ def test_legacy_converters(self): self.assertIsInstance(conv, clinic.str_converter) def test_legacy_converters_non_string_constant_annotation(self): - expected_failure_message = ( - "Error on line 0:\n" - "Annotations must be either a name, a function call, or a string.\n" - ) + err = "Annotations must be either a name, a function call, or a string" dataset = ( 'module os\nos.access\n path: 42', 'module os\nos.access\n path: 42.42', @@ -1063,14 +2074,10 @@ def test_legacy_converters_non_string_constant_annotation(self): ) for block in dataset: with self.subTest(block=block): - out = self.parse_function_should_fail(block) - self.assertEqual(out, expected_failure_message) + self.expect_failure(block, err, lineno=2) def test_other_bizarre_things_in_annotations_fail(self): - expected_failure_message = ( - "Error on line 0:\n" - "Annotations must be either a name, a function call, or a string.\n" - ) + err = "Annotations must be either a name, a function call, or a string" dataset = ( 'module os\nos.access\n path: {"some": "dictionary"}', 'module os\nos.access\n path: ["list", "of", "strings"]', @@ -1078,30 +2085,24 @@ def test_other_bizarre_things_in_annotations_fail(self): ) for block in dataset: with self.subTest(block=block): - out = self.parse_function_should_fail(block) - self.assertEqual(out, expected_failure_message) + self.expect_failure(block, err, lineno=2) def test_kwarg_splats_disallowed_in_function_call_annotations(self): - expected_error_msg = ( - "Error on line 0:\n" - "Cannot use a kwarg splat in a function-call annotation\n" - ) + err = "Cannot use a kwarg splat in a function-call annotation" dataset = ( 'module fo\nfo.barbaz\n o: bool(**{None: "bang!"})', 'module fo\nfo.barbaz -> bool(**{None: "bang!"})', 'module fo\nfo.barbaz -> bool(**{"bang": 42})', 'module fo\nfo.barbaz\n o: bool(**{"bang": None})', ) - for fn in dataset: - with self.subTest(fn=fn): - out = self.parse_function_should_fail(fn) - self.assertEqual(out, expected_error_msg) + for block in dataset: + with self.subTest(block=block): + self.expect_failure(block, err) def test_self_param_placement(self): - expected_error_msg = ( - "Error on line 0:\n" + err = ( "A 'self' parameter, if specified, must be the very first thing " - "in the parameter block.\n" + "in the parameter block." ) block = """ module foo @@ -1109,27 +2110,21 @@ def test_self_param_placement(self): a: int self: self(type="PyObject *") """ - out = self.parse_function_should_fail(block) - self.assertEqual(out, expected_error_msg) + self.expect_failure(block, err, lineno=3) def test_self_param_cannot_be_optional(self): - expected_error_msg = ( - "Error on line 0:\n" - "A 'self' parameter cannot be marked optional.\n" - ) + err = "A 'self' parameter cannot be marked optional." block = """ module foo foo.func self: self(type="PyObject *") = None """ - out = self.parse_function_should_fail(block) - self.assertEqual(out, expected_error_msg) + self.expect_failure(block, err, lineno=2) def test_defining_class_param_placement(self): - expected_error_msg = ( - "Error on line 0:\n" + err = ( "A 'defining_class' parameter, if specified, must either be the " - "first thing in the parameter block, or come just after 'self'.\n" + "first thing in the parameter block, or come just after 'self'." ) block = """ module foo @@ -1138,21 +2133,16 @@ def test_defining_class_param_placement(self): a: int cls: defining_class """ - out = self.parse_function_should_fail(block) - self.assertEqual(out, expected_error_msg) + self.expect_failure(block, err, lineno=4) def test_defining_class_param_cannot_be_optional(self): - expected_error_msg = ( - "Error on line 0:\n" - "A 'defining_class' parameter cannot be marked optional.\n" - ) + err = "A 'defining_class' parameter cannot be marked optional." block = """ module foo foo.func cls: defining_class(type="PyObject *") = None """ - out = self.parse_function_should_fail(block) - self.assertEqual(out, expected_error_msg) + self.expect_failure(block, err, lineno=2) def test_slot_methods_cannot_access_defining_class(self): block = """ @@ -1162,34 +2152,38 @@ class Foo "" "" cls: defining_class a: object """ - msg = "Slot methods cannot access their defining class." - with self.assertRaisesRegex(ValueError, msg): + err = "Slot methods cannot access their defining class." + with self.assertRaisesRegex(ValueError, err): self.parse_function(block) def test_new_must_be_a_class_method(self): - expected_error_msg = ( - "Error on line 0:\n" - "__new__ must be a class method!\n" - ) - out = self.parse_function_should_fail(""" + err = "'__new__' must be a class method!" + block = """ module foo class Foo "" "" Foo.__new__ - """) - self.assertEqual(out, expected_error_msg) + """ + self.expect_failure(block, err, lineno=2) def test_init_must_be_a_normal_method(self): - expected_error_msg = ( - "Error on line 0:\n" - "__init__ must be a normal method, not a class or static method!\n" - ) - out = self.parse_function_should_fail(""" + err = "'__init__' must be a normal method, not a class or static method!" + block = """ module foo class Foo "" "" @classmethod Foo.__init__ - """) - self.assertEqual(out, expected_error_msg) + """ + self.expect_failure(block, err, lineno=3) + + def test_duplicate_coexist(self): + err = "Called @coexist twice" + block = """ + module m + @coexist + @coexist + m.fn + """ + self.expect_failure(block, err, lineno=2) def test_unused_param(self): block = self.parse(""" @@ -1229,68 +2223,492 @@ def test_unused_param(self): parser_decl = p.simple_declaration(in_parser=True) self.assertNotIn("Py_UNUSED", parser_decl) - def parse(self, text): - c = FakeClinic() - parser = DSLParser(c) - block = clinic.Block(text) - parser.parse(block) - return block - - def parse_function(self, text, signatures_in_block=2, function_index=1): - block = self.parse(text) - s = block.signatures - self.assertEqual(len(s), signatures_in_block) - assert isinstance(s[0], clinic.Module) - assert isinstance(s[function_index], clinic.Function) - return s[function_index] - def test_scaffolding(self): # test repr on special values self.assertEqual(repr(clinic.unspecified), '') self.assertEqual(repr(clinic.NULL), '') # test that fail fails - expected = ( - 'Error in file "clown.txt" on line 69:\n' - 'The igloos are melting!\n' - ) with support.captured_stdout() as stdout: - with self.assertRaises(SystemExit): - clinic.fail('The igloos are melting!', - filename='clown.txt', line_number=69) - actual = stdout.getvalue() - self.assertEqual(actual, expected) + errmsg = 'The igloos are melting' + with self.assertRaisesRegex(clinic.ClinicError, errmsg) as cm: + clinic.fail(errmsg, filename='clown.txt', line_number=69) + exc = cm.exception + self.assertEqual(exc.filename, 'clown.txt') + self.assertEqual(exc.lineno, 69) + self.assertEqual(stdout.getvalue(), "") + + def test_non_ascii_character_in_docstring(self): + block = """ + module test + test.fn + a: int + á param docstring + docstring fü bár baß + """ + with support.captured_stdout() as stdout: + self.parse(block) + # The line numbers are off; this is a known limitation. + expected = dedent("""\ + Warning in file 'clinic_tests' on line 0: + Non-ascii characters are not allowed in docstrings: 'á' + + Warning in file 'clinic_tests' on line 0: + Non-ascii characters are not allowed in docstrings: 'ü', 'á', 'ß' + + """) + self.assertEqual(stdout.getvalue(), expected) + + def test_illegal_c_identifier(self): + err = "Illegal C identifier: 17a" + block = """ + module test + test.fn + a as 17a: int + """ + self.expect_failure(block, err, lineno=2) + + def test_cannot_convert_special_method(self): + err = "'__len__' is a special method and cannot be converted" + block = """ + class T "" "" + T.__len__ + """ + self.expect_failure(block, err, lineno=1) + + def test_cannot_specify_pydefault_without_default(self): + err = "You can't specify py_default without specifying a default value!" + block = """ + fn + a: object(py_default='NULL') + """ + self.expect_failure(block, err, lineno=1) + + def test_vararg_cannot_take_default_value(self): + err = "Vararg can't take a default value!" + block = """ + fn + *args: object = None + """ + self.expect_failure(block, err, lineno=1) + + def test_default_is_not_of_correct_type(self): + err = ("int_converter: default value 2.5 for field 'a' " + "is not of type 'int'") + block = """ + fn + a: int = 2.5 + """ + self.expect_failure(block, err, lineno=1) + + def test_invalid_legacy_converter(self): + err = "'fhi' is not a valid legacy converter" + block = """ + fn + a: 'fhi' + """ + self.expect_failure(block, err, lineno=1) + + def test_parent_class_or_module_does_not_exist(self): + err = "Parent class or module 'baz' does not exist" + block = """ + module m + baz.func + """ + self.expect_failure(block, err, lineno=1) + + def test_duplicate_param_name(self): + err = "You can't have two parameters named 'a'" + block = """ + module m + m.func + a: int + a: float + """ + self.expect_failure(block, err, lineno=3) + + def test_param_requires_custom_c_name(self): + err = "Parameter 'module' requires a custom C name" + block = """ + module m + m.func + module: int + """ + self.expect_failure(block, err, lineno=2) + + def test_state_func_docstring_assert_no_group(self): + err = "Function 'func' has a ']' without a matching '['" + block = """ + module m + m.func + ] + docstring + """ + self.expect_failure(block, err, lineno=2) + + def test_state_func_docstring_no_summary(self): + err = "Docstring for 'm.func' does not have a summary line!" + block = """ + module m + m.func + docstring1 + docstring2 + """ + self.expect_failure(block, err, lineno=0) + + def test_state_func_docstring_only_one_param_template(self): + err = "You may not specify {parameters} more than once in a docstring!" + block = """ + module m + m.func + docstring summary + + these are the params: + {parameters} + these are the params again: + {parameters} + """ + self.expect_failure(block, err, lineno=0) class ClinicExternalTest(TestCase): maxDiff = None + def run_clinic(self, *args): + with ( + support.captured_stdout() as out, + support.captured_stderr() as err, + self.assertRaises(SystemExit) as cm + ): + clinic.main(args) + return out.getvalue(), err.getvalue(), cm.exception.code + + def expect_success(self, *args): + out, err, code = self.run_clinic(*args) + if code != 0: + self.fail("\n".join([f"Unexpected failure: {args=}", out, err])) + self.assertEqual(err, "") + return out + + def expect_failure(self, *args): + out, err, code = self.run_clinic(*args) + self.assertNotEqual(code, 0, f"Unexpected success: {args=}") + return out, err + def test_external(self): CLINIC_TEST = 'clinic.test.c' - # bpo-42398: Test that the destination file is left unchanged if the - # content does not change. Moreover, check also that the file - # modification time does not change in this case. source = support.findfile(CLINIC_TEST) - with open(source, 'r', encoding='utf-8') as f: + with open(source, encoding='utf-8') as f: orig_contents = f.read() - with os_helper.temp_dir() as tmp_dir: - testfile = os.path.join(tmp_dir, CLINIC_TEST) - with open(testfile, 'w', encoding='utf-8') as f: - f.write(orig_contents) - old_mtime_ns = os.stat(testfile).st_mtime_ns - - clinic.parse_file(testfile) + # Run clinic CLI and verify that it does not complain. + self.addCleanup(unlink, TESTFN) + out = self.expect_success("-f", "-o", TESTFN, source) + self.assertEqual(out, "") - with open(testfile, 'r', encoding='utf-8') as f: - new_contents = f.read() - new_mtime_ns = os.stat(testfile).st_mtime_ns + with open(TESTFN, encoding='utf-8') as f: + new_contents = f.read() self.assertEqual(new_contents, orig_contents) + + def test_no_change(self): + # bpo-42398: Test that the destination file is left unchanged if the + # content does not change. Moreover, check also that the file + # modification time does not change in this case. + code = dedent(""" + /*[clinic input] + [clinic start generated code]*/ + /*[clinic end generated code: output=da39a3ee5e6b4b0d input=da39a3ee5e6b4b0d]*/ + """) + with os_helper.temp_dir() as tmp_dir: + fn = os.path.join(tmp_dir, "test.c") + with open(fn, "w", encoding="utf-8") as f: + f.write(code) + pre_mtime = os.stat(fn).st_mtime_ns + self.expect_success(fn) + post_mtime = os.stat(fn).st_mtime_ns # Don't change the file modification time # if the content does not change - self.assertEqual(new_mtime_ns, old_mtime_ns) + self.assertEqual(pre_mtime, post_mtime) + + def test_cli_force(self): + invalid_input = dedent(""" + /*[clinic input] + output preset block + module test + test.fn + a: int + [clinic start generated code]*/ + + const char *hand_edited = "output block is overwritten"; + /*[clinic end generated code: output=bogus input=bogus]*/ + """) + fail_msg = ( + "Checksum mismatch! Expected 'bogus', computed '2ed19'. " + "Suggested fix: remove all generated code including the end marker, " + "or use the '-f' option.\n" + ) + with os_helper.temp_dir() as tmp_dir: + fn = os.path.join(tmp_dir, "test.c") + with open(fn, "w", encoding="utf-8") as f: + f.write(invalid_input) + # First, run the CLI without -f and expect failure. + # Note, we cannot check the entire fail msg, because the path to + # the tmp file will change for every run. + _, err = self.expect_failure(fn) + self.assertTrue(err.endswith(fail_msg), + f"{err!r} does not end with {fail_msg!r}") + # Then, force regeneration; success expected. + out = self.expect_success("-f", fn) + self.assertEqual(out, "") + # Verify by checking the checksum. + checksum = ( + "/*[clinic end generated code: " + "output=c16447c01510dfb3 input=9543a8d2da235301]*/\n" + ) + with open(fn, encoding='utf-8') as f: + generated = f.read() + self.assertTrue(generated.endswith(checksum), + (generated, checksum)) + + def test_cli_make(self): + c_code = dedent(""" + /*[clinic input] + [clinic start generated code]*/ + """) + py_code = "pass" + c_files = "file1.c", "file2.c" + py_files = "file1.py", "file2.py" + + def create_files(files, srcdir, code): + for fn in files: + path = os.path.join(srcdir, fn) + with open(path, "w", encoding="utf-8") as f: + f.write(code) + + with os_helper.temp_dir() as tmp_dir: + # add some folders, some C files and a Python file + create_files(c_files, tmp_dir, c_code) + create_files(py_files, tmp_dir, py_code) + + # create C files in externals/ dir + ext_path = os.path.join(tmp_dir, "externals") + with os_helper.temp_dir(path=ext_path) as externals: + create_files(c_files, externals, c_code) + + # run clinic in verbose mode with --make on tmpdir + out = self.expect_success("-v", "--make", "--srcdir", tmp_dir) + + # expect verbose mode to only mention the C files in tmp_dir + for filename in c_files: + with self.subTest(filename=filename): + path = os.path.join(tmp_dir, filename) + self.assertIn(path, out) + for filename in py_files: + with self.subTest(filename=filename): + path = os.path.join(tmp_dir, filename) + self.assertNotIn(path, out) + # don't expect C files from the externals dir + for filename in c_files: + with self.subTest(filename=filename): + path = os.path.join(ext_path, filename) + self.assertNotIn(path, out) + + def test_cli_make_exclude(self): + code = dedent(""" + /*[clinic input] + [clinic start generated code]*/ + """) + with os_helper.temp_dir(quiet=False) as tmp_dir: + # add some folders, some C files and a Python file + for fn in "file1.c", "file2.c", "file3.c", "file4.c": + path = os.path.join(tmp_dir, fn) + with open(path, "w", encoding="utf-8") as f: + f.write(code) + + # Run clinic in verbose mode with --make on tmpdir. + # Exclude file2.c and file3.c. + out = self.expect_success( + "-v", "--make", "--srcdir", tmp_dir, + "--exclude", os.path.join(tmp_dir, "file2.c"), + # The added ./ should be normalised away. + "--exclude", os.path.join(tmp_dir, "./file3.c"), + # Relative paths should also work. + "--exclude", "file4.c" + ) + + # expect verbose mode to only mention the C files in tmp_dir + self.assertIn("file1.c", out) + self.assertNotIn("file2.c", out) + self.assertNotIn("file3.c", out) + self.assertNotIn("file4.c", out) + + def test_cli_verbose(self): + with os_helper.temp_dir() as tmp_dir: + fn = os.path.join(tmp_dir, "test.c") + with open(fn, "w", encoding="utf-8") as f: + f.write("") + out = self.expect_success("-v", fn) + self.assertEqual(out.strip(), fn) + + def test_cli_help(self): + out = self.expect_success("-h") + self.assertIn("usage: clinic.py", out) + + def test_cli_converters(self): + prelude = dedent(""" + Legacy converters: + B C D L O S U Y Z Z# + b c d f h i l p s s# s* u u# w* y y# y* z z# z* + + Converters: + """) + expected_converters = ( + "bool", + "byte", + "char", + "defining_class", + "double", + "fildes", + "float", + "int", + "long", + "long_long", + "object", + "Py_buffer", + "Py_complex", + "Py_ssize_t", + "Py_UNICODE", + "PyByteArrayObject", + "PyBytesObject", + "self", + "short", + "size_t", + "slice_index", + "str", + "unicode", + "unsigned_char", + "unsigned_int", + "unsigned_long", + "unsigned_long_long", + "unsigned_short", + ) + finale = dedent(""" + Return converters: + bool() + double() + float() + init() + int() + long() + Py_ssize_t() + size_t() + unsigned_int() + unsigned_long() + + All converters also accept (c_default=None, py_default=None, annotation=None). + All return converters also accept (py_default=None). + """) + out = self.expect_success("--converters") + # We cannot simply compare the output, because the repr of the *accept* + # param may change (it's a set, thus unordered). So, let's compare the + # start and end of the expected output, and then assert that the + # converters appear lined up in alphabetical order. + self.assertTrue(out.startswith(prelude), out) + self.assertTrue(out.endswith(finale), out) + + out = out.removeprefix(prelude) + out = out.removesuffix(finale) + lines = out.split("\n") + for converter, line in zip(expected_converters, lines): + line = line.lstrip() + with self.subTest(converter=converter): + self.assertTrue( + line.startswith(converter), + f"expected converter {converter!r}, got {line!r}" + ) + + def test_cli_fail_converters_and_filename(self): + _, err = self.expect_failure("--converters", "test.c") + msg = "can't specify --converters and a filename at the same time" + self.assertIn(msg, err) + + def test_cli_fail_no_filename(self): + _, err = self.expect_failure() + self.assertIn("no input files", err) + + def test_cli_fail_output_and_multiple_files(self): + _, err = self.expect_failure("-o", "out.c", "input.c", "moreinput.c") + msg = "error: can't use -o with multiple filenames" + self.assertIn(msg, err) + + def test_cli_fail_filename_or_output_and_make(self): + msg = "can't use -o or filenames with --make" + for opts in ("-o", "out.c"), ("filename.c",): + with self.subTest(opts=opts): + _, err = self.expect_failure("--make", *opts) + self.assertIn(msg, err) + + def test_cli_fail_make_without_srcdir(self): + _, err = self.expect_failure("--make", "--srcdir", "") + msg = "error: --srcdir must not be empty with --make" + self.assertIn(msg, err) + + def test_file_dest(self): + block = dedent(""" + /*[clinic input] + destination test new file {path}.h + output everything test + func + a: object + / + [clinic start generated code]*/ + """) + expected_checksum_line = ( + "/*[clinic end generated code: " + "output=da39a3ee5e6b4b0d input=b602ab8e173ac3bd]*/\n" + ) + expected_output = dedent("""\ + /*[clinic input] + preserve + [clinic start generated code]*/ + + PyDoc_VAR(func__doc__); + PyDoc_STRVAR(func__doc__, + "func($module, a, /)\\n" + "--\\n" + "\\n"); + + #define FUNC_METHODDEF \\ + {"func", (PyCFunction)func, METH_O, func__doc__}, + + static PyObject * + func(PyObject *module, PyObject *a) + /*[clinic end generated code: output=3dde2d13002165b9 input=a9049054013a1b77]*/ + """) + with os_helper.temp_dir() as tmp_dir: + in_fn = os.path.join(tmp_dir, "test.c") + out_fn = os.path.join(tmp_dir, "test.c.h") + with open(in_fn, "w", encoding="utf-8") as f: + f.write(block) + with open(out_fn, "w", encoding="utf-8") as f: + f.write("") # Write an empty output file! + # Clinic should complain about the empty output file. + _, err = self.expect_failure(in_fn) + expected_err = (f"Modified destination file {out_fn!r}; " + "not overwriting!") + self.assertIn(expected_err, err) + # Run clinic again, this time with the -f option. + _ = self.expect_success("-f", in_fn) + # Read back the generated output. + with open(in_fn, encoding="utf-8") as f: + data = f.read() + expected_block = f"{block}{expected_checksum_line}" + self.assertEqual(data, expected_block) + with open(out_fn, encoding="utf-8") as f: + data = f.read() + self.assertEqual(data, expected_output) try: import _testclinic as ac_tester @@ -1302,6 +2720,39 @@ class ClinicFunctionalTest(unittest.TestCase): locals().update((name, getattr(ac_tester, name)) for name in dir(ac_tester) if name.startswith('test_')) + def check_depr(self, regex, fn, /, *args, **kwds): + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + # Record the line number, so we're sure we've got the correct stack + # level on the deprecation warning. + _, lineno = fn(*args, **kwds), sys._getframe().f_lineno + self.assertEqual(cm.filename, __file__) + self.assertEqual(cm.lineno, lineno) + + def check_depr_star(self, pnames, fn, /, *args, name=None, **kwds): + if name is None: + name = fn.__qualname__ + if isinstance(fn, type): + name = f'{fn.__module__}.{name}' + regex = ( + fr"Passing( more than)?( [0-9]+)? positional argument(s)? to " + fr"{re.escape(name)}\(\) is deprecated. Parameters? {pnames} will " + fr"become( a)? keyword-only parameters? in Python 3\.14" + ) + self.check_depr(regex, fn, *args, **kwds) + + def check_depr_kwd(self, pnames, fn, *args, name=None, **kwds): + if name is None: + name = fn.__qualname__ + if isinstance(fn, type): + name = f'{fn.__module__}.{name}' + pl = 's' if ' ' in pnames else '' + regex = ( + fr"Passing keyword argument{pl} {pnames} to " + fr"{re.escape(name)}\(\) is deprecated. Parameter{pl} {pnames} " + fr"will become positional-only in Python 3\.14." + ) + self.check_depr(regex, fn, *args, **kwds) + def test_objects_converter(self): with self.assertRaises(TypeError): ac_tester.objects_converter() @@ -1746,8 +3197,11 @@ def test_gh_99233_refcount(self): self.assertEqual(arg_refcount_origin, arg_refcount_after) def test_gh_99240_double_free(self): - expected_error = r'gh_99240_double_free\(\) argument 2 must be encoded string without null bytes, not str' - with self.assertRaisesRegex(TypeError, expected_error): + err = re.escape( + "gh_99240_double_free() argument 2 must be encoded string " + "without null bytes, not str" + ) + with self.assertRaisesRegex(TypeError, err): ac_tester.gh_99240_double_free('a', '\0b') def test_cloned_func_exception_message(self): @@ -1763,6 +3217,323 @@ def test_cloned_func_with_converter_exception_message(self): func = getattr(ac_tester, name) self.assertEqual(func(), name) + def test_depr_star_new(self): + cls = ac_tester.DeprStarNew + cls() + cls(a=None) + self.check_depr_star("'a'", cls, None) + + def test_depr_star_new_cloned(self): + fn = ac_tester.DeprStarNew().cloned + fn() + fn(a=None) + self.check_depr_star("'a'", fn, None, name='_testclinic.DeprStarNew.cloned') + + def test_depr_star_init(self): + cls = ac_tester.DeprStarInit + cls() + cls(a=None) + self.check_depr_star("'a'", cls, None) + + def test_depr_star_init_cloned(self): + fn = ac_tester.DeprStarInit().cloned + fn() + fn(a=None) + self.check_depr_star("'a'", fn, None, name='_testclinic.DeprStarInit.cloned') + + def test_depr_star_init_noinline(self): + cls = ac_tester.DeprStarInitNoInline + self.assertRaises(TypeError, cls, "a") + cls(a="a", b="b") + cls(a="a", b="b", c="c") + cls("a", b="b") + cls("a", b="b", c="c") + check = partial(self.check_depr_star, "'b' and 'c'", cls) + check("a", "b") + check("a", "b", "c") + check("a", "b", c="c") + self.assertRaises(TypeError, cls, "a", "b", "c", "d") + + def test_depr_kwd_new(self): + cls = ac_tester.DeprKwdNew + cls() + cls(None) + self.check_depr_kwd("'a'", cls, a=None) + + def test_depr_kwd_init(self): + cls = ac_tester.DeprKwdInit + cls() + cls(None) + self.check_depr_kwd("'a'", cls, a=None) + + def test_depr_kwd_init_noinline(self): + cls = ac_tester.DeprKwdInitNoInline + cls = ac_tester.depr_star_noinline + self.assertRaises(TypeError, cls, "a") + cls(a="a", b="b") + cls(a="a", b="b", c="c") + cls("a", b="b") + cls("a", b="b", c="c") + check = partial(self.check_depr_star, "'b' and 'c'", cls) + check("a", "b") + check("a", "b", "c") + check("a", "b", c="c") + self.assertRaises(TypeError, cls, "a", "b", "c", "d") + + def test_depr_star_pos0_len1(self): + fn = ac_tester.depr_star_pos0_len1 + fn(a=None) + self.check_depr_star("'a'", fn, "a") + + def test_depr_star_pos0_len2(self): + fn = ac_tester.depr_star_pos0_len2 + fn(a=0, b=0) + check = partial(self.check_depr_star, "'a' and 'b'", fn) + check("a", b=0) + check("a", "b") + + def test_depr_star_pos0_len3_with_kwd(self): + fn = ac_tester.depr_star_pos0_len3_with_kwd + fn(a=0, b=0, c=0, d=0) + check = partial(self.check_depr_star, "'a', 'b' and 'c'", fn) + check("a", b=0, c=0, d=0) + check("a", "b", c=0, d=0) + check("a", "b", "c", d=0) + + def test_depr_star_pos1_len1_opt(self): + fn = ac_tester.depr_star_pos1_len1_opt + fn(a=0, b=0) + fn("a", b=0) + fn(a=0) # b is optional + check = partial(self.check_depr_star, "'b'", fn) + check("a", "b") + + def test_depr_star_pos1_len1(self): + fn = ac_tester.depr_star_pos1_len1 + fn(a=0, b=0) + fn("a", b=0) + check = partial(self.check_depr_star, "'b'", fn) + check("a", "b") + + def test_depr_star_pos1_len2_with_kwd(self): + fn = ac_tester.depr_star_pos1_len2_with_kwd + fn(a=0, b=0, c=0, d=0), + fn("a", b=0, c=0, d=0), + check = partial(self.check_depr_star, "'b' and 'c'", fn) + check("a", "b", c=0, d=0), + check("a", "b", "c", d=0), + + def test_depr_star_pos2_len1(self): + fn = ac_tester.depr_star_pos2_len1 + fn(a=0, b=0, c=0) + fn("a", b=0, c=0) + fn("a", "b", c=0) + check = partial(self.check_depr_star, "'c'", fn) + check("a", "b", "c") + + def test_depr_star_pos2_len2(self): + fn = ac_tester.depr_star_pos2_len2 + fn(a=0, b=0, c=0, d=0) + fn("a", b=0, c=0, d=0) + fn("a", "b", c=0, d=0) + check = partial(self.check_depr_star, "'c' and 'd'", fn) + check("a", "b", "c", d=0) + check("a", "b", "c", "d") + + def test_depr_star_pos2_len2_with_kwd(self): + fn = ac_tester.depr_star_pos2_len2_with_kwd + fn(a=0, b=0, c=0, d=0, e=0) + fn("a", b=0, c=0, d=0, e=0) + fn("a", "b", c=0, d=0, e=0) + check = partial(self.check_depr_star, "'c' and 'd'", fn) + check("a", "b", "c", d=0, e=0) + check("a", "b", "c", "d", e=0) + + def test_depr_star_noinline(self): + fn = ac_tester.depr_star_noinline + self.assertRaises(TypeError, fn, "a") + fn(a="a", b="b") + fn(a="a", b="b", c="c") + fn("a", b="b") + fn("a", b="b", c="c") + check = partial(self.check_depr_star, "'b' and 'c'", fn) + check("a", "b") + check("a", "b", "c") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + + def test_depr_star_multi(self): + fn = ac_tester.depr_star_multi + self.assertRaises(TypeError, fn, "a") + fn("a", b="b", c="c", d="d", e="e", f="f", g="g", h="h") + errmsg = ( + "Passing more than 1 positional argument to depr_star_multi() is deprecated. " + "Parameter 'b' will become a keyword-only parameter in Python 3.16. " + "Parameters 'c' and 'd' will become keyword-only parameters in Python 3.15. " + "Parameters 'e', 'f' and 'g' will become keyword-only parameters in Python 3.14.") + check = partial(self.check_depr, re.escape(errmsg), fn) + check("a", "b", c="c", d="d", e="e", f="f", g="g", h="h") + check("a", "b", "c", d="d", e="e", f="f", g="g", h="h") + check("a", "b", "c", "d", e="e", f="f", g="g", h="h") + check("a", "b", "c", "d", "e", f="f", g="g", h="h") + check("a", "b", "c", "d", "e", "f", g="g", h="h") + check("a", "b", "c", "d", "e", "f", "g", h="h") + self.assertRaises(TypeError, fn, "a", "b", "c", "d", "e", "f", "g", "h") + + def test_depr_kwd_required_1(self): + fn = ac_tester.depr_kwd_required_1 + fn("a", "b") + self.assertRaises(TypeError, fn, "a") + self.assertRaises(TypeError, fn, "a", "b", "c") + check = partial(self.check_depr_kwd, "'b'", fn) + check("a", b="b") + self.assertRaises(TypeError, fn, a="a", b="b") + + def test_depr_kwd_required_2(self): + fn = ac_tester.depr_kwd_required_2 + fn("a", "b", "c") + self.assertRaises(TypeError, fn, "a", "b") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", "b", c="c") + check("a", b="b", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + + def test_depr_kwd_optional_1(self): + fn = ac_tester.depr_kwd_optional_1 + fn("a") + fn("a", "b") + self.assertRaises(TypeError, fn) + self.assertRaises(TypeError, fn, "a", "b", "c") + check = partial(self.check_depr_kwd, "'b'", fn) + check("a", b="b") + self.assertRaises(TypeError, fn, a="a", b="b") + + def test_depr_kwd_optional_2(self): + fn = ac_tester.depr_kwd_optional_2 + fn("a") + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn) + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", b="b") + check("a", c="c") + check("a", b="b", c="c") + check("a", c="c", b="b") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + + def test_depr_kwd_optional_3(self): + fn = ac_tester.depr_kwd_optional_3 + fn() + fn("a") + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'a', 'b' and 'c'", fn) + check("a", "b", c="c") + check("a", b="b") + check(a="a") + + def test_depr_kwd_required_optional(self): + fn = ac_tester.depr_kwd_required_optional + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn) + self.assertRaises(TypeError, fn, "a") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", b="b") + check("a", b="b", c="c") + check("a", c="c", b="b") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, "a", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + + def test_depr_kwd_noinline(self): + fn = ac_tester.depr_kwd_noinline + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn, "a") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", b="b") + check("a", b="b", c="c") + check("a", c="c", b="b") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, "a", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + + def test_depr_kwd_multi(self): + fn = ac_tester.depr_kwd_multi + fn("a", "b", "c", "d", "e", "f", "g", h="h") + errmsg = ( + "Passing keyword arguments 'b', 'c', 'd', 'e', 'f' and 'g' to depr_kwd_multi() is deprecated. " + "Parameter 'b' will become positional-only in Python 3.14. " + "Parameters 'c' and 'd' will become positional-only in Python 3.15. " + "Parameters 'e', 'f' and 'g' will become positional-only in Python 3.16.") + check = partial(self.check_depr, re.escape(errmsg), fn) + check("a", "b", "c", "d", "e", "f", g="g", h="h") + check("a", "b", "c", "d", "e", f="f", g="g", h="h") + check("a", "b", "c", "d", e="e", f="f", g="g", h="h") + check("a", "b", "c", d="d", e="e", f="f", g="g", h="h") + check("a", "b", c="c", d="d", e="e", f="f", g="g", h="h") + check("a", b="b", c="c", d="d", e="e", f="f", g="g", h="h") + self.assertRaises(TypeError, fn, a="a", b="b", c="c", d="d", e="e", f="f", g="g", h="h") + + def test_depr_multi(self): + fn = ac_tester.depr_multi + self.assertRaises(TypeError, fn, "a", "b", "c", "d", "e", "f", "g") + errmsg = ( + "Passing more than 4 positional arguments to depr_multi() is deprecated. " + "Parameter 'e' will become a keyword-only parameter in Python 3.15. " + "Parameter 'f' will become a keyword-only parameter in Python 3.14.") + check = partial(self.check_depr, re.escape(errmsg), fn) + check("a", "b", "c", "d", "e", "f", g="g") + check("a", "b", "c", "d", "e", f="f", g="g") + fn("a", "b", "c", "d", e="e", f="f", g="g") + fn("a", "b", "c", d="d", e="e", f="f", g="g") + errmsg = ( + "Passing keyword arguments 'b' and 'c' to depr_multi() is deprecated. " + "Parameter 'b' will become positional-only in Python 3.14. " + "Parameter 'c' will become positional-only in Python 3.15.") + check = partial(self.check_depr, re.escape(errmsg), fn) + check("a", "b", c="c", d="d", e="e", f="f", g="g") + check("a", b="b", c="c", d="d", e="e", f="f", g="g") + self.assertRaises(TypeError, fn, a="a", b="b", c="c", d="d", e="e", f="f", g="g") + + +try: + import _testclinic_limited +except ImportError: + _testclinic_limited = None + +@unittest.skipIf(_testclinic_limited is None, "_testclinic_limited is missing") +class LimitedCAPIFunctionalTest(unittest.TestCase): + locals().update((name, getattr(_testclinic_limited, name)) + for name in dir(_testclinic_limited) if name.startswith('test_')) + + def test_my_int_func(self): + with self.assertRaises(TypeError): + _testclinic_limited.my_int_func() + self.assertEqual(_testclinic_limited.my_int_func(3), 3) + with self.assertRaises(TypeError): + _testclinic_limited.my_int_func(1.0) + with self.assertRaises(TypeError): + _testclinic_limited.my_int_func("xyz") + + def test_my_int_sum(self): + with self.assertRaises(TypeError): + _testclinic_limited.my_int_sum() + with self.assertRaises(TypeError): + _testclinic_limited.my_int_sum(1) + self.assertEqual(_testclinic_limited.my_int_sum(1, 2), 3) + with self.assertRaises(TypeError): + _testclinic_limited.my_int_sum(1.0, 2) + with self.assertRaises(TypeError): + _testclinic_limited.my_int_sum(1, "str") + + class PermutationTests(unittest.TestCase): """Test permutation support functions.""" @@ -2034,5 +3805,95 @@ def test_suffix_all_lines(self): self.assertEqual(out, expected) +class ClinicReprTests(unittest.TestCase): + def test_Block_repr(self): + block = clinic.Block("foo") + expected_repr = "" + self.assertEqual(repr(block), expected_repr) + + block2 = clinic.Block("bar", "baz", [], "eggs", "spam") + expected_repr_2 = "" + self.assertEqual(repr(block2), expected_repr_2) + + block3 = clinic.Block( + input="longboi_" * 100, + dsl_name="wow_so_long", + signatures=[], + output="very_long_" * 100, + indent="" + ) + expected_repr_3 = ( + "" + ) + self.assertEqual(repr(block3), expected_repr_3) + + def test_Destination_repr(self): + c = _make_clinic() + + destination = clinic.Destination( + "foo", type="file", clinic=c, args=("eggs",) + ) + self.assertEqual( + repr(destination), "" + ) + + destination2 = clinic.Destination("bar", type="buffer", clinic=c) + self.assertEqual(repr(destination2), "") + + def test_Module_repr(self): + module = clinic.Module("foo", _make_clinic()) + self.assertRegex(repr(module), r"") + + def test_Class_repr(self): + cls = clinic.Class("foo", _make_clinic(), None, 'some_typedef', 'some_type_object') + self.assertRegex(repr(cls), r"") + + def test_FunctionKind_repr(self): + self.assertEqual( + repr(clinic.FunctionKind.INVALID), "" + ) + self.assertEqual( + repr(clinic.FunctionKind.CLASS_METHOD), "" + ) + + def test_Function_and_Parameter_reprs(self): + function = clinic.Function( + name='foo', + module=_make_clinic(), + cls=None, + c_basename=None, + full_name='foofoo', + return_converter=clinic.init_return_converter(), + kind=clinic.FunctionKind.METHOD_INIT, + coexist=False + ) + self.assertEqual(repr(function), "") + + converter = clinic.self_converter('bar', 'bar', function) + parameter = clinic.Parameter( + "bar", + kind=inspect.Parameter.POSITIONAL_OR_KEYWORD, + function=function, + converter=converter + ) + self.assertEqual(repr(parameter), "") + + def test_Monitor_repr(self): + monitor = clinic.cpp.Monitor() + self.assertRegex(repr(monitor), r"") + + monitor.line_number = 42 + monitor.stack.append(("token1", "condition1")) + self.assertRegex( + repr(monitor), r"" + ) + + monitor.stack.append(("token2", "condition2")) + self.assertRegex( + repr(monitor), + r"" + ) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 94298003063593..eaf19aa160e860 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -717,11 +717,11 @@ def test_xdev(self): # Memory allocator debug hooks try: - import _testcapi + import _testinternalcapi except ImportError: pass else: - code = "import _testcapi; print(_testcapi.pymem_getallocatorsname())" + code = "import _testinternalcapi; print(_testinternalcapi.pymem_getallocatorsname())" with support.SuppressCrashReport(): out = self.run_xdev("-c", code, check_exitcode=False) if support.with_pymalloc(): @@ -783,7 +783,7 @@ def test_warnings_filter_precedence(self): self.assertEqual(out, expected_filters) def check_pythonmalloc(self, env_var, name): - code = 'import _testcapi; print(_testcapi.pymem_getallocatorsname())' + code = 'import _testinternalcapi; print(_testinternalcapi.pymem_getallocatorsname())' env = dict(os.environ) env.pop('PYTHONDEVMODE', None) if env_var is not None: @@ -799,6 +799,7 @@ def check_pythonmalloc(self, env_var, name): self.assertEqual(proc.stdout.rstrip(), name) self.assertEqual(proc.returncode, 0) + @support.cpython_only def test_pythonmalloc(self): # Test the PYTHONMALLOC environment variable pymalloc = support.with_pymalloc() @@ -877,11 +878,8 @@ def test_int_max_str_digits(self): assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='foo') assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='100') - def res2int(res): - out = res.out.strip().decode("utf-8") - return tuple(int(i) for i in out.split()) - res = assert_python_ok('-c', code) + res2int = self.res2int current_max = sys.get_int_max_str_digits() self.assertEqual(res2int(res), (current_max, current_max)) res = assert_python_ok('-X', 'int_max_str_digits=0', '-c', code) @@ -901,6 +899,26 @@ def res2int(res): ) self.assertEqual(res2int(res), (6000, 6000)) + def test_cpu_count(self): + code = "import os; print(os.cpu_count(), os.process_cpu_count())" + res = assert_python_ok('-X', 'cpu_count=4321', '-c', code) + self.assertEqual(self.res2int(res), (4321, 4321)) + res = assert_python_ok('-c', code, PYTHON_CPU_COUNT='1234') + self.assertEqual(self.res2int(res), (1234, 1234)) + + def test_cpu_count_default(self): + code = "import os; print(os.cpu_count(), os.process_cpu_count())" + res = assert_python_ok('-X', 'cpu_count=default', '-c', code) + self.assertEqual(self.res2int(res), (os.cpu_count(), os.process_cpu_count())) + res = assert_python_ok('-X', 'cpu_count=default', '-c', code, PYTHON_CPU_COUNT='1234') + self.assertEqual(self.res2int(res), (os.cpu_count(), os.process_cpu_count())) + es = assert_python_ok('-c', code, PYTHON_CPU_COUNT='default') + self.assertEqual(self.res2int(res), (os.cpu_count(), os.process_cpu_count())) + + def res2int(self, res): + out = res.out.strip().decode("utf-8") + return tuple(int(i) for i in out.split()) + @unittest.skipIf(interpreter_requires_environment(), 'Cannot run -I tests when PYTHON env vars are required.') diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 1b588826010717..614c6b3c3b5299 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -203,6 +203,8 @@ def check_repl_stderr_flush(self, separate_stderr=False): stderr = p.stderr if separate_stderr else p.stdout self.assertIn(b'Traceback ', stderr.readline()) self.assertIn(b'File ""', stderr.readline()) + self.assertIn(b'1/0', stderr.readline()) + self.assertIn(b' ~^~', stderr.readline()) self.assertIn(b'ZeroDivisionError', stderr.readline()) def test_repl_stdout_flush(self): diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index ca06a39f5df142..a961ddbe17a3d3 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -125,6 +125,7 @@ """ +import copy import inspect import sys import threading @@ -264,7 +265,7 @@ def func2(): ("co_posonlyargcount", 0), ("co_kwonlyargcount", 0), ("co_nlocals", 1), - ("co_stacksize", 0), + ("co_stacksize", 1), ("co_flags", code.co_flags | inspect.CO_COROUTINE), ("co_firstlineno", 100), ("co_code", code2.co_code), @@ -280,11 +281,17 @@ def func2(): with self.subTest(attr=attr, value=value): new_code = code.replace(**{attr: value}) self.assertEqual(getattr(new_code, attr), value) + new_code = copy.replace(code, **{attr: value}) + self.assertEqual(getattr(new_code, attr), value) new_code = code.replace(co_varnames=code2.co_varnames, co_nlocals=code2.co_nlocals) self.assertEqual(new_code.co_varnames, code2.co_varnames) self.assertEqual(new_code.co_nlocals, code2.co_nlocals) + new_code = copy.replace(code, co_varnames=code2.co_varnames, + co_nlocals=code2.co_nlocals) + self.assertEqual(new_code.co_varnames, code2.co_varnames) + self.assertEqual(new_code.co_nlocals, code2.co_nlocals) def test_nlocals_mismatch(self): def func(): @@ -498,6 +505,25 @@ def test_code_hash_uses_bytecode(self): self.assertNotEqual(c, c1) self.assertNotEqual(hash(c), hash(c1)) + @cpython_only + def test_code_equal_with_instrumentation(self): + """ GH-109052 + + Make sure the instrumentation doesn't affect the code equality + The validity of this test relies on the fact that "x is x" and + "x in x" have only one different instruction and the instructions + have the same argument. + + """ + code1 = compile("x is x", "example.py", "eval") + code2 = compile("x in x", "example.py", "eval") + sys._getframe().f_trace_opcodes = True + sys.settrace(lambda *args: None) + exec(code1, {'x': []}) + exec(code2, {'x': []}) + self.assertNotEqual(code1, code2) + sys.settrace(None) + def isinterned(s): return s is sys.intern(('_' + s + '_')[1:-1]) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 91d7eaf997ae20..ff511a625a0194 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1,7 +1,9 @@ import codecs import contextlib +import copy import io import locale +import pickle import sys import unittest import encodings @@ -1760,6 +1762,76 @@ def test_file_closes_if_lookup_error_raised(self): file().close.assert_called() + def test_copy(self): + orig = codecs.lookup('utf-8') + dup = copy.copy(orig) + self.assertIsNot(dup, orig) + self.assertEqual(dup, orig) + self.assertTrue(orig._is_text_encoding) + self.assertEqual(dup.encode, orig.encode) + self.assertEqual(dup.name, orig.name) + self.assertEqual(dup.incrementalencoder, orig.incrementalencoder) + + # Test a CodecInfo with _is_text_encoding equal to false. + orig = codecs.lookup("base64") + dup = copy.copy(orig) + self.assertIsNot(dup, orig) + self.assertEqual(dup, orig) + self.assertFalse(orig._is_text_encoding) + self.assertEqual(dup.encode, orig.encode) + self.assertEqual(dup.name, orig.name) + self.assertEqual(dup.incrementalencoder, orig.incrementalencoder) + + def test_deepcopy(self): + orig = codecs.lookup('utf-8') + dup = copy.deepcopy(orig) + self.assertIsNot(dup, orig) + self.assertEqual(dup, orig) + self.assertTrue(orig._is_text_encoding) + self.assertEqual(dup.encode, orig.encode) + self.assertEqual(dup.name, orig.name) + self.assertEqual(dup.incrementalencoder, orig.incrementalencoder) + + # Test a CodecInfo with _is_text_encoding equal to false. + orig = codecs.lookup("base64") + dup = copy.deepcopy(orig) + self.assertIsNot(dup, orig) + self.assertEqual(dup, orig) + self.assertFalse(orig._is_text_encoding) + self.assertEqual(dup.encode, orig.encode) + self.assertEqual(dup.name, orig.name) + self.assertEqual(dup.incrementalencoder, orig.incrementalencoder) + + def test_pickle(self): + codec_info = codecs.lookup('utf-8') + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + pickled_codec_info = pickle.dumps(codec_info) + unpickled_codec_info = pickle.loads(pickled_codec_info) + self.assertIsNot(codec_info, unpickled_codec_info) + self.assertEqual(codec_info, unpickled_codec_info) + self.assertEqual(codec_info.name, unpickled_codec_info.name) + self.assertEqual( + codec_info.incrementalencoder, + unpickled_codec_info.incrementalencoder + ) + self.assertTrue(unpickled_codec_info._is_text_encoding) + + # Test a CodecInfo with _is_text_encoding equal to false. + codec_info = codecs.lookup('base64') + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + pickled_codec_info = pickle.dumps(codec_info) + unpickled_codec_info = pickle.loads(pickled_codec_info) + self.assertIsNot(codec_info, unpickled_codec_info) + self.assertEqual(codec_info, unpickled_codec_info) + self.assertEqual(codec_info.name, unpickled_codec_info.name) + self.assertEqual( + codec_info.incrementalencoder, + unpickled_codec_info.incrementalencoder + ) + self.assertFalse(unpickled_codec_info._is_text_encoding) + class StreamReaderTest(unittest.TestCase): @@ -1771,6 +1843,61 @@ def test_readlines(self): f = self.reader(self.stream) self.assertEqual(f.readlines(), ['\ud55c\n', '\uae00']) + def test_copy(self): + f = self.reader(Queue(b'\xed\x95\x9c\n\xea\xb8\x80')) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = self.reader(Queue(b'\xed\x95\x9c\n\xea\xb8\x80')) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + pickle.dumps(f, proto) + + +class StreamWriterTest(unittest.TestCase): + + def setUp(self): + self.writer = codecs.getwriter('utf-8') + + def test_copy(self): + f = self.writer(Queue(b'')) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = self.writer(Queue(b'')) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + pickle.dumps(f, proto) + + +class StreamReaderWriterTest(unittest.TestCase): + + def setUp(self): + self.reader = codecs.getreader('latin1') + self.writer = codecs.getwriter('utf-8') + + def test_copy(self): + f = codecs.StreamReaderWriter(Queue(b''), self.reader, self.writer) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = codecs.StreamReaderWriter(Queue(b''), self.reader, self.writer) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + pickle.dumps(f, proto) + class EncodedFileTest(unittest.TestCase): @@ -3346,6 +3473,28 @@ def test_seeking_write(self): self.assertEqual(sr.readline(), b'abc\n') self.assertEqual(sr.readline(), b'789\n') + def test_copy(self): + bio = io.BytesIO() + codec = codecs.lookup('ascii') + sr = codecs.StreamRecoder(bio, codec.encode, codec.decode, + encodings.ascii.StreamReader, encodings.ascii.StreamWriter) + + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + copy.copy(sr) + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + copy.deepcopy(sr) + + def test_pickle(self): + q = Queue(b'') + codec = codecs.lookup('ascii') + sr = codecs.StreamRecoder(q, codec.encode, codec.decode, + encodings.ascii.StreamReader, encodings.ascii.StreamWriter) + + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + pickle.dumps(sr, proto) + @unittest.skipIf(_testinternalcapi is None, 'need _testinternalcapi module') class LocaleCodecTest(unittest.TestCase): @@ -3488,9 +3637,10 @@ class Rot13UtilTest(unittest.TestCase): $ echo "Hello World" | python -m encodings.rot_13 """ def test_rot13_func(self): + from encodings.rot_13 import rot13 infile = io.StringIO('Gb or, be abg gb or, gung vf gur dhrfgvba') outfile = io.StringIO() - encodings.rot_13.rot13(infile, outfile) + rot13(infile, outfile) outfile.seek(0) plain_text = outfile.read() self.assertEqual( diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 85ce0a4b39d854..c4452e38934cf8 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -11,10 +11,9 @@ import warnings from test import support from test.support import (script_helper, requires_debug_ranges, - requires_specialization) + requires_specialization, Py_C_RECURSION_LIMIT) from test.support.os_helper import FakePath - class TestSpecifics(unittest.TestCase): def compile_single(self, source): @@ -112,7 +111,7 @@ def __getitem__(self, key): @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_extended_arg(self): - repeat = 2000 + repeat = int(Py_C_RECURSION_LIMIT * 0.9) longexpr = 'x = x or ' + '-x' * repeat g = {} code = textwrap.dedent(''' @@ -444,6 +443,33 @@ def f(): self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames) self.assertIn("__package__", A.f.__code__.co_varnames) + def test_compile_invalid_namedexpr(self): + # gh-109351 + m = ast.Module( + body=[ + ast.Expr( + value=ast.ListComp( + elt=ast.NamedExpr( + target=ast.Constant(value=1), + value=ast.Constant(value=3), + ), + generators=[ + ast.comprehension( + target=ast.Name(id="x", ctx=ast.Store()), + iter=ast.Name(id="y", ctx=ast.Load()), + ifs=[], + is_async=0, + ) + ], + ) + ) + ], + type_ignores=[], + ) + + with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"): + compile(ast.fix_missing_locations(m), "", "exec") + def test_compile_ast(self): fname = __file__ if fname.lower().endswith('pyc'): @@ -479,6 +505,26 @@ def test_compile_ast(self): ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '', 'exec') + def test_compile_invalid_typealias(self): + # gh-109341 + m = ast.Module( + body=[ + ast.TypeAlias( + name=ast.Subscript( + value=ast.Name(id="foo", ctx=ast.Load()), + slice=ast.Constant(value="x"), + ctx=ast.Store(), + ), + type_params=[], + value=ast.Name(id="Callable", ctx=ast.Load()), + ) + ], + type_ignores=[], + ) + + with self.assertRaisesRegex(TypeError, "TypeAlias with non-Name name"): + compile(ast.fix_missing_locations(m), "", "exec") + def test_dict_evaluation_order(self): i = 0 @@ -558,16 +604,12 @@ def test_yet_more_evil_still_undecodable(self): @support.cpython_only @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_compiler_recursion_limit(self): - # Expected limit is sys.getrecursionlimit() * the scaling factor - # in symtable.c (currently 3) - # We expect to fail *at* that limit, because we use up some of - # the stack depth limit in the test suite code - # So we check the expected limit and 75% of that - # XXX (ncoghlan): duplicating the scaling factor here is a little - # ugly. Perhaps it should be exposed somewhere... - fail_depth = sys.getrecursionlimit() * 3 - crash_depth = sys.getrecursionlimit() * 300 - success_depth = int(fail_depth * 0.75) + # Expected limit is Py_C_RECURSION_LIMIT * 2 + # Duplicating the limit here is a little ugly. + # Perhaps it should be exposed somewhere... + fail_depth = Py_C_RECURSION_LIMIT * 2 + 1 + crash_depth = Py_C_RECURSION_LIMIT * 100 + success_depth = int(Py_C_RECURSION_LIMIT * 1.8) def check_limit(prefix, repeated, mode="single"): expect_ok = prefix + repeated * success_depth @@ -789,6 +831,7 @@ def test_path_like_objects(self): # An implicit test for PyUnicode_FSDecoder(). compile("42", FakePath("test_compile_pathlike"), "single") + @support.requires_resource('cpu') def test_stack_overflow(self): # bpo-31113: Stack overflow when compile a long sequence of # complex statements. @@ -1036,6 +1079,20 @@ async def test(aseq): code_lines = self.get_code_lines(test.__code__) self.assertEqual(expected_lines, code_lines) + def test_lineno_of_backward_jump(self): + # Issue gh-107901 + def f(): + for i in x: + if y: + pass + + linenos = list(inst.positions.lineno + for inst in dis.get_instructions(f.__code__) + if inst.opname == 'JUMP_BACKWARD') + + self.assertTrue(len(linenos) > 0) + self.assertTrue(all(l is not None for l in linenos)) + def test_big_dict_literal(self): # The compiler has a flushing point in "compiler_dict" that calls compiles # a portion of the dictionary literal when the loop that iterates over the items @@ -1195,6 +1252,36 @@ def f(): return a, b self.assertEqual(f(), (54, 96)) + def test_duplicated_small_exit_block(self): + # See gh-109627 + def f(): + while element and something: + try: + return something + except: + pass + + def test_cold_block_moved_to_end(self): + # See gh-109719 + def f(): + while name: + try: + break + except: + pass + else: + 1 if 1 else 1 + + def test_remove_empty_basic_block_with_jump_target_label(self): + # See gh-109823 + def f(x): + while x: + 0 if 1 else 0 + + def test_remove_redundant_nop_edge_case(self): + # See gh-109889 + def f(): + a if (1 if b else c) else d @requires_debug_ranges() class TestSourcePositions(unittest.TestCase): @@ -1320,18 +1407,18 @@ def test_multiline_assert(self): snippet = textwrap.dedent("""\ assert (a > 0 and bb > 0 and - ccc == 4), "error msg" + ccc == 1000000), "error msg" """) compiled_code, _ = self.check_positions_against_ast(snippet) self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_ASSERTION_ERROR', - line=1, end_line=3, column=0, end_column=30, occurrence=1) + line=1, end_line=3, column=0, end_column=36, occurrence=1) # The "error msg": self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_CONST', - line=3, end_line=3, column=19, end_column=30, occurrence=4) + line=3, end_line=3, column=25, end_column=36, occurrence=4) self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', - line=1, end_line=3, column=0, end_column=30, occurrence=1) + line=1, end_line=3, column=0, end_column=36, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'RAISE_VARARGS', - line=1, end_line=3, column=0, end_column=30, occurrence=1) + line=1, end_line=3, column=8, end_column=22, occurrence=1) def test_multiline_generator_expression(self): snippet = textwrap.dedent("""\ @@ -1741,6 +1828,13 @@ def test_column_offset_deduplication(self): list(code.co_consts[1].co_positions()), ) + def test_load_super_attr(self): + source = "class C:\n def __init__(self):\n super().__init__()" + code = compile(source, "", "exec").co_consts[0].co_consts[1] + self.assertOpcodeSourcePositionIs( + code, "LOAD_GLOBAL", line=3, end_line=3, column=4, end_column=9 + ) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 05154c8f1c6057..9cd92ad365c5a9 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -18,6 +18,7 @@ try: # compileall relies on ProcessPoolExecutor if ProcessPoolExecutor exists # and it can function. + from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from concurrent.futures import ProcessPoolExecutor from concurrent.futures.process import _check_system_limits _check_system_limits() @@ -54,6 +55,8 @@ class CompileallTestsBase: def setUp(self): self.directory = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, self.directory) + self.source_path = os.path.join(self.directory, '_test.py') self.bc_path = importlib.util.cache_from_source(self.source_path) with open(self.source_path, 'w', encoding="utf-8") as file: @@ -66,9 +69,6 @@ def setUp(self): self.source_path3 = os.path.join(self.subdirectory, '_test3.py') shutil.copyfile(self.source_path, self.source_path3) - def tearDown(self): - shutil.rmtree(self.directory) - def add_bad_source_file(self): self.bad_source_path = os.path.join(self.directory, '_test_bad.py') with open(self.bad_source_path, 'w', encoding="utf-8") as file: @@ -307,9 +307,13 @@ def _test_ddir_only(self, *, ddir, parallel=True): script_helper.make_script(path, "__init__", "") mods.append(script_helper.make_script(path, "mod", "def fn(): 1/0\nfn()\n")) + + if parallel: + self.addCleanup(multiprocessing_cleanup_tests) compileall.compile_dir( self.directory, quiet=True, ddir=ddir, workers=2 if parallel else 1) + self.assertTrue(mods) for mod in mods: self.assertTrue(mod.startswith(self.directory), mod) @@ -551,6 +555,7 @@ def test_no_args_compiles_path(self): self.assertNotCompiled(self.barfn) @without_source_date_epoch # timestamp invalidation test + @support.requires_resource('cpu') def test_no_args_respects_force_flag(self): bazfn = script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: @@ -568,6 +573,7 @@ def test_no_args_respects_force_flag(self): mtime2 = os.stat(pycpath).st_mtime self.assertNotEqual(mtime, mtime2) + @support.requires_resource('cpu') def test_no_args_respects_quiet_flag(self): script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: diff --git a/Lib/test/test_compiler_assemble.py b/Lib/test/test_compiler_assemble.py index 6df72cbc54666b..5696433e529d0a 100644 --- a/Lib/test/test_compiler_assemble.py +++ b/Lib/test/test_compiler_assemble.py @@ -94,12 +94,12 @@ def inner(): instructions = [ ('RESUME', 0,), - ('PUSH_NULL', 0, 1), ('LOAD_CLOSURE', 0, 1), ('BUILD_TUPLE', 1, 1), ('LOAD_CONST', 1, 1), ('MAKE_FUNCTION', 0, 2), ('SET_FUNCTION_ATTRIBUTE', 8, 2), + ('PUSH_NULL', 0, 1), ('CALL', 0, 2), # (lambda: x)() ('LOAD_CONST', 2, 2), # 2 ('BINARY_OP', 6, 2), # % diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py index d99bb8c6cd472d..6d7731ddba02c5 100644 --- a/Lib/test/test_compiler_codegen.py +++ b/Lib/test/test_compiler_codegen.py @@ -41,8 +41,8 @@ def test_for_loop(self): loop_lbl := self.Label(), ('FOR_ITER', exit_lbl := self.Label(), 1), ('STORE_NAME', 1, 1), - ('PUSH_NULL', None, 2), ('LOAD_NAME', 2, 2), + ('PUSH_NULL', None, 2), ('LOAD_NAME', 1, 2), ('CALL', 1, 2), ('POP_TOP', None), diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py deleted file mode 100644 index 39dbe234e765e8..00000000000000 --- a/Lib/test/test_concurrent_futures.py +++ /dev/null @@ -1,1677 +0,0 @@ -from test import support -from test.support import import_helper -from test.support import threading_helper - -# Skip tests if _multiprocessing wasn't built. -import_helper.import_module('_multiprocessing') - -from test.support import hashlib_helper -from test.support.script_helper import assert_python_ok - -import contextlib -import itertools -import logging -from logging.handlers import QueueHandler -import os -import queue -import signal -import sys -import threading -import time -import unittest -import weakref -from pickle import PicklingError - -from concurrent import futures -from concurrent.futures._base import ( - PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, - BrokenExecutor) -from concurrent.futures.process import BrokenProcessPool, _check_system_limits - -import multiprocessing.process -import multiprocessing.util -import multiprocessing as mp - - -if support.check_sanitizer(address=True, memory=True): - # bpo-46633: Skip the test because it is too slow when Python is built - # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. - raise unittest.SkipTest("test too slow on ASAN/MSAN build") - - -def create_future(state=PENDING, exception=None, result=None): - f = Future() - f._state = state - f._exception = exception - f._result = result - return f - - -PENDING_FUTURE = create_future(state=PENDING) -RUNNING_FUTURE = create_future(state=RUNNING) -CANCELLED_FUTURE = create_future(state=CANCELLED) -CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED) -EXCEPTION_FUTURE = create_future(state=FINISHED, exception=OSError()) -SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42) - -INITIALIZER_STATUS = 'uninitialized' - -def mul(x, y): - return x * y - -def capture(*args, **kwargs): - return args, kwargs - -def sleep_and_raise(t): - time.sleep(t) - raise Exception('this is an exception') - -def sleep_and_print(t, msg): - time.sleep(t) - print(msg) - sys.stdout.flush() - -def init(x): - global INITIALIZER_STATUS - INITIALIZER_STATUS = x - -def get_init_status(): - return INITIALIZER_STATUS - -def init_fail(log_queue=None): - if log_queue is not None: - logger = logging.getLogger('concurrent.futures') - logger.addHandler(QueueHandler(log_queue)) - logger.setLevel('CRITICAL') - logger.propagate = False - time.sleep(0.1) # let some futures be scheduled - raise ValueError('error in initializer') - - -class MyObject(object): - def my_method(self): - pass - - -class EventfulGCObj(): - def __init__(self, mgr): - self.event = mgr.Event() - - def __del__(self): - self.event.set() - - -def make_dummy_object(_): - return MyObject() - - -class BaseTestCase(unittest.TestCase): - def setUp(self): - self._thread_key = threading_helper.threading_setup() - - def tearDown(self): - support.reap_children() - threading_helper.threading_cleanup(*self._thread_key) - - -class ExecutorMixin: - worker_count = 5 - executor_kwargs = {} - - def setUp(self): - super().setUp() - - self.t1 = time.monotonic() - if hasattr(self, "ctx"): - self.executor = self.executor_type( - max_workers=self.worker_count, - mp_context=self.get_context(), - **self.executor_kwargs) - else: - self.executor = self.executor_type( - max_workers=self.worker_count, - **self.executor_kwargs) - - def tearDown(self): - self.executor.shutdown(wait=True) - self.executor = None - - dt = time.monotonic() - self.t1 - if support.verbose: - print("%.2fs" % dt, end=' ') - self.assertLess(dt, 300, "synchronization issue: test lasted too long") - - super().tearDown() - - def get_context(self): - return mp.get_context(self.ctx) - - -class ThreadPoolMixin(ExecutorMixin): - executor_type = futures.ThreadPoolExecutor - - -class ProcessPoolForkMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "fork" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -class ProcessPoolSpawnMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "spawn" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - return super().get_context() - - -class ProcessPoolForkserverMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "forkserver" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -def create_executor_tests(mixin, bases=(BaseTestCase,), - executor_mixins=(ThreadPoolMixin, - ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)): - def strip_mixin(name): - if name.endswith(('Mixin', 'Tests')): - return name[:-5] - elif name.endswith('Test'): - return name[:-4] - else: - return name - - for exe in executor_mixins: - name = ("%s%sTest" - % (strip_mixin(exe.__name__), strip_mixin(mixin.__name__))) - cls = type(name, (mixin,) + (exe,) + bases, {}) - globals()[name] = cls - - -class InitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - global INITIALIZER_STATUS - INITIALIZER_STATUS = 'uninitialized' - self.executor_kwargs = dict(initializer=init, - initargs=('initialized',)) - super().setUp() - - def test_initializer(self): - futures = [self.executor.submit(get_init_status) - for _ in range(self.worker_count)] - - for f in futures: - self.assertEqual(f.result(), 'initialized') - - -class FailingInitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - if hasattr(self, "ctx"): - # Pass a queue to redirect the child's logging output - self.mp_context = self.get_context() - self.log_queue = self.mp_context.Queue() - self.executor_kwargs = dict(initializer=init_fail, - initargs=(self.log_queue,)) - else: - # In a thread pool, the child shares our logging setup - # (see _assert_logged()) - self.mp_context = None - self.log_queue = None - self.executor_kwargs = dict(initializer=init_fail) - super().setUp() - - def test_initializer(self): - with self._assert_logged('ValueError: error in initializer'): - try: - future = self.executor.submit(get_init_status) - except BrokenExecutor: - # Perhaps the executor is already broken - pass - else: - with self.assertRaises(BrokenExecutor): - future.result() - - # At some point, the executor should break - for _ in support.sleeping_retry(support.SHORT_TIMEOUT, - "executor not broken"): - if self.executor._broken: - break - - # ... and from this point submit() is guaranteed to fail - with self.assertRaises(BrokenExecutor): - self.executor.submit(get_init_status) - - @contextlib.contextmanager - def _assert_logged(self, msg): - if self.log_queue is not None: - yield - output = [] - try: - while True: - output.append(self.log_queue.get_nowait().getMessage()) - except queue.Empty: - pass - else: - with self.assertLogs('concurrent.futures', 'CRITICAL') as cm: - yield - output = cm.output - self.assertTrue(any(msg in line for line in output), - output) - - -create_executor_tests(InitializerMixin) -create_executor_tests(FailingInitializerMixin) - - -class ExecutorShutdownTest: - def test_run_after_shutdown(self): - self.executor.shutdown() - self.assertRaises(RuntimeError, - self.executor.submit, - pow, 2, 5) - - def test_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - from concurrent.futures import {executor_type} - from time import sleep - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - context = '{context}' - if context == "": - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(sleep_and_print, 1.0, "apple") - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - def test_submit_after_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - import atexit - @atexit.register - def run_last(): - try: - t.submit(id, None) - except RuntimeError: - print("runtime-error") - raise - from concurrent.futures import {executor_type} - if __name__ == "__main__": - context = '{context}' - if not context: - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(id, 42).result() - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) - self.assertEqual(out.strip(), b"runtime-error") - - def test_hang_issue12364(self): - fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] - self.executor.shutdown() - for f in fs: - f.result() - - def test_cancel_futures(self): - assert self.worker_count <= 5, "test needs few workers" - fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] - self.executor.shutdown(cancel_futures=True) - # We can't guarantee the exact number of cancellations, but we can - # guarantee that *some* were cancelled. With few workers, many of - # the submitted futures should have been cancelled. - cancelled = [fut for fut in fs if fut.cancelled()] - self.assertGreater(len(cancelled), 20) - - # Ensure the other futures were able to finish. - # Use "not fut.cancelled()" instead of "fut.done()" to include futures - # that may have been left in a pending state. - others = [fut for fut in fs if not fut.cancelled()] - for fut in others: - self.assertTrue(fut.done(), msg=f"{fut._state=}") - self.assertIsNone(fut.exception()) - - # Similar to the number of cancelled futures, we can't guarantee the - # exact number that completed. But, we can guarantee that at least - # one finished. - self.assertGreater(len(others), 0) - - def test_hang_gh83386(self): - """shutdown(wait=False) doesn't hang at exit with running futures. - - See https://github.com/python/cpython/issues/83386. - """ - if self.executor_type == futures.ProcessPoolExecutor: - raise unittest.SkipTest( - "Hangs, see https://github.com/python/cpython/issues/83386") - - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import {executor_type} - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - if {context!r}: multiprocessing.set_start_method({context!r}) - t = {executor_type}(max_workers=3) - t.submit(sleep_and_print, 1.0, "apple") - t.shutdown(wait=False) - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, 'ctx', None))) - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - def test_hang_gh94440(self): - """shutdown(wait=True) doesn't hang when a future was submitted and - quickly canceled right before shutdown. - - See https://github.com/python/cpython/issues/94440. - """ - if not hasattr(signal, 'alarm'): - raise unittest.SkipTest( - "Tested platform does not support the alarm signal") - - def timeout(_signum, _frame): - raise RuntimeError("timed out waiting for shutdown") - - kwargs = {} - if getattr(self, 'ctx', None): - kwargs['mp_context'] = self.get_context() - executor = self.executor_type(max_workers=1, **kwargs) - executor.submit(int).result() - old_handler = signal.signal(signal.SIGALRM, timeout) - try: - signal.alarm(5) - executor.submit(int).cancel() - executor.shutdown(wait=True) - finally: - signal.alarm(0) - signal.signal(signal.SIGALRM, old_handler) - - -class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): - def test_threads_terminate(self): - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._threads), 3) - for i in range(3): - sem.release() - self.executor.shutdown() - for t in self.executor._threads: - t.join() - - def test_context_manager_shutdown(self): - with futures.ThreadPoolExecutor(max_workers=5) as e: - executor = e - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for t in executor._threads: - t.join() - - def test_del_shutdown(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the threads when calling - # shutdown with wait=False - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - executor.shutdown(wait=False) - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - - def test_thread_names_assigned(self): - executor = futures.ThreadPoolExecutor( - max_workers=5, thread_name_prefix='SpecialPool') - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - self.assertRegex(t.name, r'^SpecialPool_[0-4]$') - t.join() - - def test_thread_names_default(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - # Ensure that our default name is reasonably sane and unique when - # no thread_name_prefix was supplied. - self.assertRegex(t.name, r'ThreadPoolExecutor-\d+_[0-4]$') - t.join() - - def test_cancel_futures_wait_false(self): - # Can only be reliably tested for TPE, since PPE often hangs with - # `wait=False` (even without *cancel_futures*). - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import ThreadPoolExecutor - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - t = ThreadPoolExecutor() - t.submit(sleep_and_print, .1, "apple") - t.shutdown(wait=False, cancel_futures=True) - """) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - -class ProcessPoolShutdownTest(ExecutorShutdownTest): - def test_processes_terminate(self): - def acquire_lock(lock): - lock.acquire() - - mp_context = self.get_context() - if mp_context.get_start_method(allow_none=False) == "fork": - # fork pre-spawns, not on demand. - expected_num_processes = self.worker_count - else: - expected_num_processes = 3 - - sem = mp_context.Semaphore(0) - for _ in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._processes), expected_num_processes) - for _ in range(3): - sem.release() - processes = self.executor._processes - self.executor.shutdown() - - for p in processes.values(): - p.join() - - def test_context_manager_shutdown(self): - with futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) as e: - processes = e._processes - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for p in processes.values(): - p.join() - - def test_del_shutdown(self): - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - executor_manager_thread = executor._executor_manager_thread - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - del executor - support.gc_collect() # For PyPy or other GCs. - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the processes when calling - # shutdown with wait=False - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - executor.shutdown(wait=False) - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the executor got - # shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - -create_executor_tests(ProcessPoolShutdownTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class WaitTests: - def test_20369(self): - # See https://bugs.python.org/issue20369 - future = self.executor.submit(time.sleep, 1.5) - done, not_done = futures.wait([future, future], - return_when=futures.ALL_COMPLETED) - self.assertEqual({future}, done) - self.assertEqual(set(), not_done) - - - def test_first_completed(self): - future1 = self.executor.submit(mul, 21, 2) - future2 = self.executor.submit(time.sleep, 1.5) - - done, not_done = futures.wait( - [CANCELLED_FUTURE, future1, future2], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual(set([future1]), done) - self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done) - - def test_first_completed_some_already_completed(self): - future1 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual( - set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]), - finished) - self.assertEqual(set([future1]), pending) - - def test_first_exception(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(sleep_and_raise, 1.5) - future3 = self.executor.submit(time.sleep, 3) - - finished, pending = futures.wait( - [future1, future2, future3], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([future1, future2]), finished) - self.assertEqual(set([future3]), pending) - - def test_first_exception_some_already_complete(self): - future1 = self.executor.submit(divmod, 21, 0) - future2 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1, future2], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1]), finished) - self.assertEqual(set([CANCELLED_FUTURE, future2]), pending) - - def test_first_exception_one_already_failed(self): - future1 = self.executor.submit(time.sleep, 2) - - finished, pending = futures.wait( - [EXCEPTION_FUTURE, future1], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([EXCEPTION_FUTURE]), finished) - self.assertEqual(set([future1]), pending) - - def test_all_completed(self): - future1 = self.executor.submit(divmod, 2, 0) - future2 = self.executor.submit(mul, 2, 21) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2], - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2]), finished) - self.assertEqual(set(), pending) - - def test_timeout(self): - future1 = self.executor.submit(mul, 6, 7) - future2 = self.executor.submit(time.sleep, 6) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2], - timeout=5, - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1]), finished) - self.assertEqual(set([future2]), pending) - - -class ThreadPoolWaitTests(ThreadPoolMixin, WaitTests, BaseTestCase): - - def test_pending_calls_race(self): - # Issue #14406: multi-threaded race condition when waiting on all - # futures. - event = threading.Event() - def future_func(): - event.wait() - oldswitchinterval = sys.getswitchinterval() - sys.setswitchinterval(1e-6) - try: - fs = {self.executor.submit(future_func) for i in range(100)} - event.set() - futures.wait(fs, return_when=futures.ALL_COMPLETED) - finally: - sys.setswitchinterval(oldswitchinterval) - - -create_executor_tests(WaitTests, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class AsCompletedTests: - def test_no_timeout(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(mul, 7, 6) - - completed = set(futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2])) - self.assertEqual(set( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2]), - completed) - - def test_future_times_out(self): - """Test ``futures.as_completed`` timing out before - completing it's final future.""" - already_completed = {CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE} - - for timeout in (0, 0.01): - with self.subTest(timeout): - - future = self.executor.submit(time.sleep, 0.1) - completed_futures = set() - try: - for f in futures.as_completed( - already_completed | {future}, - timeout - ): - completed_futures.add(f) - except futures.TimeoutError: - pass - - # Check that ``future`` wasn't completed. - self.assertEqual(completed_futures, already_completed) - - def test_duplicate_futures(self): - # Issue 20367. Duplicate futures should not raise exceptions or give - # duplicate responses. - # Issue #31641: accept arbitrary iterables. - future1 = self.executor.submit(time.sleep, 2) - completed = [ - f for f in futures.as_completed(itertools.repeat(future1, 3)) - ] - self.assertEqual(len(completed), 1) - - def test_free_reference_yielded_future(self): - # Issue #14406: Generator should not keep references - # to finished futures. - futures_list = [Future() for _ in range(8)] - futures_list.append(create_future(state=CANCELLED_AND_NOTIFIED)) - futures_list.append(create_future(state=FINISHED, result=42)) - - with self.assertRaises(futures.TimeoutError): - for future in futures.as_completed(futures_list, timeout=0): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - futures_list[0].set_result("test") - for future in futures.as_completed(futures_list): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - if futures_list: - futures_list[0].set_result("test") - - def test_correct_timeout_exception_msg(self): - futures_list = [CANCELLED_AND_NOTIFIED_FUTURE, PENDING_FUTURE, - RUNNING_FUTURE, SUCCESSFUL_FUTURE] - - with self.assertRaises(futures.TimeoutError) as cm: - list(futures.as_completed(futures_list, timeout=0)) - - self.assertEqual(str(cm.exception), '2 (of 4) futures unfinished') - - -create_executor_tests(AsCompletedTests) - - -class ExecutorTest: - # Executor.shutdown() and context manager usage is tested by - # ExecutorShutdownTest. - def test_submit(self): - future = self.executor.submit(pow, 2, 8) - self.assertEqual(256, future.result()) - - def test_submit_keyword(self): - future = self.executor.submit(mul, 2, y=8) - self.assertEqual(16, future.result()) - future = self.executor.submit(capture, 1, self=2, fn=3) - self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) - with self.assertRaises(TypeError): - self.executor.submit(fn=capture, arg=1) - with self.assertRaises(TypeError): - self.executor.submit(arg=1) - - def test_map(self): - self.assertEqual( - list(self.executor.map(pow, range(10), range(10))), - list(map(pow, range(10), range(10)))) - - self.assertEqual( - list(self.executor.map(pow, range(10), range(10), chunksize=3)), - list(map(pow, range(10), range(10)))) - - def test_map_exception(self): - i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) - self.assertEqual(i.__next__(), (0, 1)) - self.assertEqual(i.__next__(), (0, 1)) - self.assertRaises(ZeroDivisionError, i.__next__) - - def test_map_timeout(self): - results = [] - try: - for i in self.executor.map(time.sleep, - [0, 0, 6], - timeout=5): - results.append(i) - except futures.TimeoutError: - pass - else: - self.fail('expected TimeoutError') - - self.assertEqual([None, None], results) - - def test_shutdown_race_issue12456(self): - # Issue #12456: race condition at shutdown where trying to post a - # sentinel in the call queue blocks (the queue is full while processes - # have exited). - self.executor.map(str, [2] * (self.worker_count + 1)) - self.executor.shutdown() - - @support.cpython_only - def test_no_stale_references(self): - # Issue #16284: check that the executors don't unnecessarily hang onto - # references. - my_object = MyObject() - my_object_collected = threading.Event() - my_object_callback = weakref.ref( - my_object, lambda obj: my_object_collected.set()) - # Deliberately discarding the future. - self.executor.submit(my_object.my_method) - del my_object - - collected = my_object_collected.wait(timeout=support.SHORT_TIMEOUT) - self.assertTrue(collected, - "Stale reference not collected within timeout.") - - def test_max_workers_negative(self): - for number in (0, -1): - with self.assertRaisesRegex(ValueError, - "max_workers must be greater " - "than 0"): - self.executor_type(max_workers=number) - - def test_free_reference(self): - # Issue #14406: Result iterator should not keep an internal - # reference to result objects. - for obj in self.executor.map(make_dummy_object, range(10)): - wr = weakref.ref(obj) - del obj - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - -class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase): - def test_map_submits_without_iteration(self): - """Tests verifying issue 11777.""" - finished = [] - def record_finished(n): - finished.append(n) - - self.executor.map(record_finished, range(10)) - self.executor.shutdown(wait=True) - self.assertCountEqual(finished, range(10)) - - def test_default_workers(self): - executor = self.executor_type() - expected = min(32, (os.cpu_count() or 1) + 4) - self.assertEqual(executor._max_workers, expected) - - def test_saturation(self): - executor = self.executor_type(4) - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(15 * executor._max_workers): - executor.submit(acquire_lock, sem) - self.assertEqual(len(executor._threads), executor._max_workers) - for i in range(15 * executor._max_workers): - sem.release() - executor.shutdown(wait=True) - - def test_idle_thread_reuse(self): - executor = self.executor_type() - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._threads), 1) - executor.shutdown(wait=True) - - @unittest.skipUnless(hasattr(os, 'register_at_fork'), 'need os.register_at_fork') - def test_hang_global_shutdown_lock(self): - # bpo-45021: _global_shutdown_lock should be reinitialized in the child - # process, otherwise it will never exit - def submit(pool): - pool.submit(submit, pool) - - with futures.ThreadPoolExecutor(1) as pool: - pool.submit(submit, pool) - - for _ in range(50): - with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: - workers.submit(tuple) - - def test_executor_map_current_future_cancel(self): - stop_event = threading.Event() - log = [] - - def log_n_wait(ident): - log.append(f"{ident=} started") - try: - stop_event.wait() - finally: - log.append(f"{ident=} stopped") - - with self.executor_type(max_workers=1) as pool: - # submit work to saturate the pool - fut = pool.submit(log_n_wait, ident="first") - try: - with contextlib.closing( - pool.map(log_n_wait, ["second", "third"], timeout=0) - ) as gen: - with self.assertRaises(TimeoutError): - next(gen) - finally: - stop_event.set() - fut.result() - # ident='second' is cancelled as a result of raising a TimeoutError - # ident='third' is cancelled because it remained in the collection of futures - self.assertListEqual(log, ["ident='first' started", "ident='first' stopped"]) - - -class ProcessPoolExecutorTest(ExecutorTest): - - @unittest.skipUnless(sys.platform=='win32', 'Windows-only process limit') - def test_max_workers_too_large(self): - with self.assertRaisesRegex(ValueError, - "max_workers must be <= 61"): - futures.ProcessPoolExecutor(max_workers=62) - - def test_killed_child(self): - # When a child process is abruptly terminated, the whole pool gets - # "broken". - futures = [self.executor.submit(time.sleep, 3)] - # Get one of the processes, and terminate (kill) it - p = next(iter(self.executor._processes.values())) - p.terminate() - for fut in futures: - self.assertRaises(BrokenProcessPool, fut.result) - # Submitting other jobs fails as well. - self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) - - def test_map_chunksize(self): - def bad_map(): - list(self.executor.map(pow, range(40), range(40), chunksize=-1)) - - ref = list(map(pow, range(40), range(40))) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=6)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=50)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=40)), - ref) - self.assertRaises(ValueError, bad_map) - - @classmethod - def _test_traceback(cls): - raise RuntimeError(123) # some comment - - def test_traceback(self): - # We want ensure that the traceback from the child process is - # contained in the traceback raised in the main process. - future = self.executor.submit(self._test_traceback) - with self.assertRaises(Exception) as cm: - future.result() - - exc = cm.exception - self.assertIs(type(exc), RuntimeError) - self.assertEqual(exc.args, (123,)) - cause = exc.__cause__ - self.assertIs(type(cause), futures.process._RemoteTraceback) - self.assertIn('raise RuntimeError(123) # some comment', cause.tb) - - with support.captured_stderr() as f1: - try: - raise exc - except RuntimeError: - sys.excepthook(*sys.exc_info()) - self.assertIn('raise RuntimeError(123) # some comment', - f1.getvalue()) - - @hashlib_helper.requires_hashdigest('md5') - def test_ressources_gced_in_workers(self): - # Ensure that argument for a job are correctly gc-ed after the job - # is finished - mgr = self.get_context().Manager() - obj = EventfulGCObj(mgr) - future = self.executor.submit(id, obj) - future.result() - - self.assertTrue(obj.event.wait(timeout=1)) - - # explicitly destroy the object to ensure that EventfulGCObj.__del__() - # is called while manager is still running. - obj = None - support.gc_collect() - - mgr.shutdown() - mgr.join() - - def test_saturation(self): - executor = self.executor - mp_context = self.get_context() - sem = mp_context.Semaphore(0) - job_count = 15 * executor._max_workers - for _ in range(job_count): - executor.submit(sem.acquire) - self.assertEqual(len(executor._processes), executor._max_workers) - for _ in range(job_count): - sem.release() - - def test_idle_process_reuse_one(self): - executor = self.executor - assert executor._max_workers >= 4 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._processes), 1) - - def test_idle_process_reuse_multiple(self): - executor = self.executor - assert executor._max_workers <= 5 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 12, 7).result() - executor.submit(mul, 33, 25) - executor.submit(mul, 25, 26).result() - executor.submit(mul, 18, 29) - executor.submit(mul, 1, 2).result() - executor.submit(mul, 0, 9) - self.assertLessEqual(len(executor._processes), 3) - executor.shutdown() - - def test_max_tasks_per_child(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - with self.assertRaises(ValueError): - self.executor_type(1, mp_context=context, max_tasks_per_child=3) - return - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 1, mp_context=context, max_tasks_per_child=3) - f1 = executor.submit(os.getpid) - original_pid = f1.result() - # The worker pid remains the same as the worker could be reused - f2 = executor.submit(os.getpid) - self.assertEqual(f2.result(), original_pid) - self.assertEqual(len(executor._processes), 1) - f3 = executor.submit(os.getpid) - self.assertEqual(f3.result(), original_pid) - - # A new worker is spawned, with a statistically different pid, - # while the previous was reaped. - f4 = executor.submit(os.getpid) - new_pid = f4.result() - self.assertNotEqual(original_pid, new_pid) - self.assertEqual(len(executor._processes), 1) - - executor.shutdown() - - def test_max_tasks_per_child_defaults_to_spawn_context(self): - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type(1, max_tasks_per_child=3) - self.assertEqual(executor._mp_context.get_start_method(), "spawn") - - def test_max_tasks_early_shutdown(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 3, mp_context=context, max_tasks_per_child=1) - futures = [] - for i in range(6): - futures.append(executor.submit(mul, i, i)) - executor.shutdown() - for i, future in enumerate(futures): - self.assertEqual(future.result(), mul(i, i)) - - -create_executor_tests(ProcessPoolExecutorTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - -def _crash(delay=None): - """Induces a segfault.""" - if delay: - time.sleep(delay) - import faulthandler - faulthandler.disable() - faulthandler._sigsegv() - - -def _crash_with_data(data): - """Induces a segfault with dummy data in input.""" - _crash() - - -def _exit(): - """Induces a sys exit with exitcode 1.""" - sys.exit(1) - - -def _raise_error(Err): - """Function that raises an Exception in process.""" - raise Err() - - -def _raise_error_ignore_stderr(Err): - """Function that raises an Exception in process and ignores stderr.""" - import io - sys.stderr = io.StringIO() - raise Err() - - -def _return_instance(cls): - """Function that returns a instance of cls.""" - return cls() - - -class CrashAtPickle(object): - """Bad object that triggers a segfault at pickling time.""" - def __reduce__(self): - _crash() - - -class CrashAtUnpickle(object): - """Bad object that triggers a segfault at unpickling time.""" - def __reduce__(self): - return _crash, () - - -class ExitAtPickle(object): - """Bad object that triggers a process exit at pickling time.""" - def __reduce__(self): - _exit() - - -class ExitAtUnpickle(object): - """Bad object that triggers a process exit at unpickling time.""" - def __reduce__(self): - return _exit, () - - -class ErrorAtPickle(object): - """Bad object that triggers an error at pickling time.""" - def __reduce__(self): - from pickle import PicklingError - raise PicklingError("Error in pickle") - - -class ErrorAtUnpickle(object): - """Bad object that triggers an error at unpickling time.""" - def __reduce__(self): - from pickle import UnpicklingError - return _raise_error_ignore_stderr, (UnpicklingError, ) - - -class ExecutorDeadlockTest: - TIMEOUT = support.SHORT_TIMEOUT - - def _fail_on_deadlock(self, executor): - # If we did not recover before TIMEOUT seconds, consider that the - # executor is in a deadlock state and forcefully clean all its - # composants. - import faulthandler - from tempfile import TemporaryFile - with TemporaryFile(mode="w+") as f: - faulthandler.dump_traceback(file=f) - f.seek(0) - tb = f.read() - for p in executor._processes.values(): - p.terminate() - # This should be safe to call executor.shutdown here as all possible - # deadlocks should have been broken. - executor.shutdown(wait=True) - print(f"\nTraceback:\n {tb}", file=sys.__stderr__) - self.fail(f"Executor deadlock:\n\n{tb}") - - - def _check_crash(self, error, func, *args, ignore_stderr=False): - # test for deadlock caused by crashes in a pool - self.executor.shutdown(wait=True) - - executor = self.executor_type( - max_workers=2, mp_context=self.get_context()) - res = executor.submit(func, *args) - - if ignore_stderr: - cm = support.captured_stderr() - else: - cm = contextlib.nullcontext() - - try: - with self.assertRaises(error): - with cm: - res.result(timeout=self.TIMEOUT) - except futures.TimeoutError: - # If we did not recover before TIMEOUT seconds, - # consider that the executor is in a deadlock state - self._fail_on_deadlock(executor) - executor.shutdown(wait=True) - - def test_error_at_task_pickle(self): - # Check problem occurring while pickling a task in - # the task_handler thread - self._check_crash(PicklingError, id, ErrorAtPickle()) - - def test_exit_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ExitAtUnpickle()) - - def test_error_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ErrorAtUnpickle()) - - def test_crash_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, CrashAtUnpickle()) - - def test_crash_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(BrokenProcessPool, _crash) - - def test_exit_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(SystemExit, _exit) - - def test_error_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(RuntimeError, _raise_error, RuntimeError) - - def test_crash_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(BrokenProcessPool, _return_instance, CrashAtPickle) - - def test_exit_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(SystemExit, _return_instance, ExitAtPickle) - - def test_error_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(PicklingError, _return_instance, ErrorAtPickle) - - def test_error_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, - _return_instance, ErrorAtUnpickle, - ignore_stderr=True) - - def test_exit_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, _return_instance, ExitAtUnpickle) - - def test_shutdown_deadlock(self): - # Test that the pool calling shutdown do not cause deadlock - # if a worker fails after the shutdown call. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - f = executor.submit(_crash, delay=.1) - executor.shutdown(wait=True) - with self.assertRaises(BrokenProcessPool): - f.result() - - def test_shutdown_deadlock_pickle(self): - # Test that the pool calling shutdown with wait=False does not cause - # a deadlock if a task fails at pickle after the shutdown call. - # Reported in bpo-39104. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - - # Start the executor and get the executor_manager_thread to collect - # the threads and avoid dangling thread that should be cleaned up - # asynchronously. - executor.submit(id, 42).result() - executor_manager = executor._executor_manager_thread - - # Submit a task that fails at pickle and shutdown the executor - # without waiting - f = executor.submit(id, ErrorAtPickle()) - executor.shutdown(wait=False) - with self.assertRaises(PicklingError): - f.result() - - # Make sure the executor is eventually shutdown and do not leave - # dangling threads - executor_manager.join() - - def test_crash_big_data(self): - # Test that there is a clean exception instad of a deadlock when a - # child process crashes while some data is being written into the - # queue. - # https://github.com/python/cpython/issues/94777 - self.executor.shutdown(wait=True) - data = "a" * support.PIPE_MAX_SIZE - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - with self.assertRaises(BrokenProcessPool): - list(executor.map(_crash_with_data, [data] * 10)) - - -create_executor_tests(ExecutorDeadlockTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class FutureTests(BaseTestCase): - def test_done_callback_with_result(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.add_done_callback(fn) - f.set_result(5) - self.assertEqual(5, callback_result) - - def test_done_callback_with_exception(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.add_done_callback(fn) - f.set_exception(Exception('test')) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_with_cancel(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - f.add_done_callback(fn) - self.assertTrue(f.cancel()) - self.assertTrue(was_cancelled) - - def test_done_callback_raises(self): - with support.captured_stderr() as stderr: - raising_was_called = False - fn_was_called = False - - def raising_fn(callback_future): - nonlocal raising_was_called - raising_was_called = True - raise Exception('doh!') - - def fn(callback_future): - nonlocal fn_was_called - fn_was_called = True - - f = Future() - f.add_done_callback(raising_fn) - f.add_done_callback(fn) - f.set_result(5) - self.assertTrue(raising_was_called) - self.assertTrue(fn_was_called) - self.assertIn('Exception: doh!', stderr.getvalue()) - - def test_done_callback_already_successful(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.set_result(5) - f.add_done_callback(fn) - self.assertEqual(5, callback_result) - - def test_done_callback_already_failed(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.set_exception(Exception('test')) - f.add_done_callback(fn) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_already_cancelled(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - self.assertTrue(f.cancel()) - f.add_done_callback(fn) - self.assertTrue(was_cancelled) - - def test_done_callback_raises_already_succeeded(self): - with support.captured_stderr() as stderr: - def raising_fn(callback_future): - raise Exception('doh!') - - f = Future() - - # Set the result first to simulate a future that runs instantly, - # effectively allowing the callback to be run immediately. - f.set_result(5) - f.add_done_callback(raising_fn) - - self.assertIn('exception calling callback for', stderr.getvalue()) - self.assertIn('doh!', stderr.getvalue()) - - - def test_repr(self): - self.assertRegex(repr(PENDING_FUTURE), - '') - self.assertRegex(repr(RUNNING_FUTURE), - '') - self.assertRegex(repr(CANCELLED_FUTURE), - '') - self.assertRegex(repr(CANCELLED_AND_NOTIFIED_FUTURE), - '') - self.assertRegex( - repr(EXCEPTION_FUTURE), - '') - self.assertRegex( - repr(SUCCESSFUL_FUTURE), - '') - - - def test_cancel(self): - f1 = create_future(state=PENDING) - f2 = create_future(state=RUNNING) - f3 = create_future(state=CANCELLED) - f4 = create_future(state=CANCELLED_AND_NOTIFIED) - f5 = create_future(state=FINISHED, exception=OSError()) - f6 = create_future(state=FINISHED, result=5) - - self.assertTrue(f1.cancel()) - self.assertEqual(f1._state, CANCELLED) - - self.assertFalse(f2.cancel()) - self.assertEqual(f2._state, RUNNING) - - self.assertTrue(f3.cancel()) - self.assertEqual(f3._state, CANCELLED) - - self.assertTrue(f4.cancel()) - self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED) - - self.assertFalse(f5.cancel()) - self.assertEqual(f5._state, FINISHED) - - self.assertFalse(f6.cancel()) - self.assertEqual(f6._state, FINISHED) - - def test_cancelled(self): - self.assertFalse(PENDING_FUTURE.cancelled()) - self.assertFalse(RUNNING_FUTURE.cancelled()) - self.assertTrue(CANCELLED_FUTURE.cancelled()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled()) - self.assertFalse(EXCEPTION_FUTURE.cancelled()) - self.assertFalse(SUCCESSFUL_FUTURE.cancelled()) - - def test_done(self): - self.assertFalse(PENDING_FUTURE.done()) - self.assertFalse(RUNNING_FUTURE.done()) - self.assertTrue(CANCELLED_FUTURE.done()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done()) - self.assertTrue(EXCEPTION_FUTURE.done()) - self.assertTrue(SUCCESSFUL_FUTURE.done()) - - def test_running(self): - self.assertFalse(PENDING_FUTURE.running()) - self.assertTrue(RUNNING_FUTURE.running()) - self.assertFalse(CANCELLED_FUTURE.running()) - self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running()) - self.assertFalse(EXCEPTION_FUTURE.running()) - self.assertFalse(SUCCESSFUL_FUTURE.running()) - - def test_result_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.result, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0) - self.assertRaises(OSError, EXCEPTION_FUTURE.result, timeout=0) - self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42) - - def test_result_with_success(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.set_result(42) - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertEqual(f1.result(timeout=5), 42) - t.join() - - def test_result_with_cancel(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.cancel() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertRaises(futures.CancelledError, - f1.result, timeout=support.SHORT_TIMEOUT) - t.join() - - def test_exception_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.exception, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0) - self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0), - OSError)) - self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None) - - def test_exception_with_success(self): - def notification(): - # Wait until the main thread is waiting for the exception. - time.sleep(1) - with f1._condition: - f1._state = FINISHED - f1._exception = OSError() - f1._condition.notify_all() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertTrue(isinstance(f1.exception(timeout=support.SHORT_TIMEOUT), OSError)) - t.join() - - def test_multiple_set_result(self): - f = create_future(state=PENDING) - f.set_result(1) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: ' - ): - f.set_result(2) - - self.assertTrue(f.done()) - self.assertEqual(f.result(), 1) - - def test_multiple_set_exception(self): - f = create_future(state=PENDING) - e = ValueError() - f.set_exception(e) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: ' - ): - f.set_exception(Exception()) - - self.assertEqual(f.exception(), e) - - -def setUpModule(): - unittest.addModuleCleanup(multiprocessing.util._cleanup_tests) - thread_info = threading_helper.threading_setup() - unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_concurrent_futures/__init__.py b/Lib/test/test_concurrent_futures/__init__.py new file mode 100644 index 00000000000000..430fa93aa456a2 --- /dev/null +++ b/Lib/test/test_concurrent_futures/__init__.py @@ -0,0 +1,16 @@ +import os.path +import unittest +from test import support +from test.support import import_helper + +# Skip tests if _multiprocessing wasn't built. +import_helper.import_module('_multiprocessing') + +if support.check_sanitizer(address=True, memory=True): + # gh-90791: Skip the test because it is too slow when Python is built + # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. + raise unittest.SkipTest("test too slow on ASAN/MSAN build") + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_concurrent_futures/executor.py b/Lib/test/test_concurrent_futures/executor.py new file mode 100644 index 00000000000000..1e7d4344740943 --- /dev/null +++ b/Lib/test/test_concurrent_futures/executor.py @@ -0,0 +1,108 @@ +import threading +import time +import weakref +from concurrent import futures +from test import support + + +def mul(x, y): + return x * y + +def capture(*args, **kwargs): + return args, kwargs + + +class MyObject(object): + def my_method(self): + pass + + +def make_dummy_object(_): + return MyObject() + + +class ExecutorTest: + # Executor.shutdown() and context manager usage is tested by + # ExecutorShutdownTest. + def test_submit(self): + future = self.executor.submit(pow, 2, 8) + self.assertEqual(256, future.result()) + + def test_submit_keyword(self): + future = self.executor.submit(mul, 2, y=8) + self.assertEqual(16, future.result()) + future = self.executor.submit(capture, 1, self=2, fn=3) + self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) + with self.assertRaises(TypeError): + self.executor.submit(fn=capture, arg=1) + with self.assertRaises(TypeError): + self.executor.submit(arg=1) + + def test_map(self): + self.assertEqual( + list(self.executor.map(pow, range(10), range(10))), + list(map(pow, range(10), range(10)))) + + self.assertEqual( + list(self.executor.map(pow, range(10), range(10), chunksize=3)), + list(map(pow, range(10), range(10)))) + + def test_map_exception(self): + i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) + self.assertEqual(i.__next__(), (0, 1)) + self.assertEqual(i.__next__(), (0, 1)) + self.assertRaises(ZeroDivisionError, i.__next__) + + @support.requires_resource('walltime') + def test_map_timeout(self): + results = [] + try: + for i in self.executor.map(time.sleep, + [0, 0, 6], + timeout=5): + results.append(i) + except futures.TimeoutError: + pass + else: + self.fail('expected TimeoutError') + + self.assertEqual([None, None], results) + + def test_shutdown_race_issue12456(self): + # Issue #12456: race condition at shutdown where trying to post a + # sentinel in the call queue blocks (the queue is full while processes + # have exited). + self.executor.map(str, [2] * (self.worker_count + 1)) + self.executor.shutdown() + + @support.cpython_only + def test_no_stale_references(self): + # Issue #16284: check that the executors don't unnecessarily hang onto + # references. + my_object = MyObject() + my_object_collected = threading.Event() + my_object_callback = weakref.ref( + my_object, lambda obj: my_object_collected.set()) + # Deliberately discarding the future. + self.executor.submit(my_object.my_method) + del my_object + + collected = my_object_collected.wait(timeout=support.SHORT_TIMEOUT) + self.assertTrue(collected, + "Stale reference not collected within timeout.") + + def test_max_workers_negative(self): + for number in (0, -1): + with self.assertRaisesRegex(ValueError, + "max_workers must be greater " + "than 0"): + self.executor_type(max_workers=number) + + def test_free_reference(self): + # Issue #14406: Result iterator should not keep an internal + # reference to result objects. + for obj in self.executor.map(make_dummy_object, range(10)): + wr = weakref.ref(obj) + del obj + support.gc_collect() # For PyPy or other GCs. + self.assertIsNone(wr()) diff --git a/Lib/test/test_concurrent_futures/test_as_completed.py b/Lib/test/test_concurrent_futures/test_as_completed.py new file mode 100644 index 00000000000000..c90b0021d85fc7 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_as_completed.py @@ -0,0 +1,118 @@ +import itertools +import time +import unittest +import weakref +from concurrent import futures +from concurrent.futures._base import ( + CANCELLED_AND_NOTIFIED, FINISHED, Future) + +from test import support + +from .util import ( + PENDING_FUTURE, RUNNING_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, SUCCESSFUL_FUTURE, + create_future, create_executor_tests, setup_module) + + +def mul(x, y): + return x * y + + +class AsCompletedTests: + def test_no_timeout(self): + future1 = self.executor.submit(mul, 2, 21) + future2 = self.executor.submit(mul, 7, 6) + + completed = set(futures.as_completed( + [CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + future1, future2])) + self.assertEqual(set( + [CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + future1, future2]), + completed) + + def test_future_times_out(self): + """Test ``futures.as_completed`` timing out before + completing it's final future.""" + already_completed = {CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE} + + # Windows clock resolution is around 15.6 ms + short_timeout = 0.100 + for timeout in (0, short_timeout): + with self.subTest(timeout): + + completed_futures = set() + future = self.executor.submit(time.sleep, short_timeout * 10) + + try: + for f in futures.as_completed( + already_completed | {future}, + timeout + ): + completed_futures.add(f) + except futures.TimeoutError: + pass + + # Check that ``future`` wasn't completed. + self.assertEqual(completed_futures, already_completed) + + def test_duplicate_futures(self): + # Issue 20367. Duplicate futures should not raise exceptions or give + # duplicate responses. + # Issue #31641: accept arbitrary iterables. + future1 = self.executor.submit(time.sleep, 2) + completed = [ + f for f in futures.as_completed(itertools.repeat(future1, 3)) + ] + self.assertEqual(len(completed), 1) + + def test_free_reference_yielded_future(self): + # Issue #14406: Generator should not keep references + # to finished futures. + futures_list = [Future() for _ in range(8)] + futures_list.append(create_future(state=CANCELLED_AND_NOTIFIED)) + futures_list.append(create_future(state=FINISHED, result=42)) + + with self.assertRaises(futures.TimeoutError): + for future in futures.as_completed(futures_list, timeout=0): + futures_list.remove(future) + wr = weakref.ref(future) + del future + support.gc_collect() # For PyPy or other GCs. + self.assertIsNone(wr()) + + futures_list[0].set_result("test") + for future in futures.as_completed(futures_list): + futures_list.remove(future) + wr = weakref.ref(future) + del future + support.gc_collect() # For PyPy or other GCs. + self.assertIsNone(wr()) + if futures_list: + futures_list[0].set_result("test") + + def test_correct_timeout_exception_msg(self): + futures_list = [CANCELLED_AND_NOTIFIED_FUTURE, PENDING_FUTURE, + RUNNING_FUTURE, SUCCESSFUL_FUTURE] + + with self.assertRaises(futures.TimeoutError) as cm: + list(futures.as_completed(futures_list, timeout=0)) + + self.assertEqual(str(cm.exception), '2 (of 4) futures unfinished') + + +create_executor_tests(globals(), AsCompletedTests) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_deadlock.py b/Lib/test/test_concurrent_futures/test_deadlock.py new file mode 100644 index 00000000000000..3c30c4558c0b3e --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_deadlock.py @@ -0,0 +1,332 @@ +import contextlib +import queue +import signal +import sys +import time +import unittest +import unittest.mock +from pickle import PicklingError +from concurrent import futures +from concurrent.futures.process import BrokenProcessPool, _ThreadWakeup + +from test import support + +from .util import ( + create_executor_tests, setup_module, + ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin) + + +def _crash(delay=None): + """Induces a segfault.""" + if delay: + time.sleep(delay) + import faulthandler + faulthandler.disable() + faulthandler._sigsegv() + + +def _crash_with_data(data): + """Induces a segfault with dummy data in input.""" + _crash() + + +def _exit(): + """Induces a sys exit with exitcode 1.""" + sys.exit(1) + + +def _raise_error(Err): + """Function that raises an Exception in process.""" + raise Err() + + +def _raise_error_ignore_stderr(Err): + """Function that raises an Exception in process and ignores stderr.""" + import io + sys.stderr = io.StringIO() + raise Err() + + +def _return_instance(cls): + """Function that returns a instance of cls.""" + return cls() + + +class CrashAtPickle(object): + """Bad object that triggers a segfault at pickling time.""" + def __reduce__(self): + _crash() + + +class CrashAtUnpickle(object): + """Bad object that triggers a segfault at unpickling time.""" + def __reduce__(self): + return _crash, () + + +class ExitAtPickle(object): + """Bad object that triggers a process exit at pickling time.""" + def __reduce__(self): + _exit() + + +class ExitAtUnpickle(object): + """Bad object that triggers a process exit at unpickling time.""" + def __reduce__(self): + return _exit, () + + +class ErrorAtPickle(object): + """Bad object that triggers an error at pickling time.""" + def __reduce__(self): + from pickle import PicklingError + raise PicklingError("Error in pickle") + + +class ErrorAtUnpickle(object): + """Bad object that triggers an error at unpickling time.""" + def __reduce__(self): + from pickle import UnpicklingError + return _raise_error_ignore_stderr, (UnpicklingError, ) + + +class ExecutorDeadlockTest: + TIMEOUT = support.LONG_TIMEOUT + + def _fail_on_deadlock(self, executor): + # If we did not recover before TIMEOUT seconds, consider that the + # executor is in a deadlock state and forcefully clean all its + # composants. + import faulthandler + from tempfile import TemporaryFile + with TemporaryFile(mode="w+") as f: + faulthandler.dump_traceback(file=f) + f.seek(0) + tb = f.read() + for p in executor._processes.values(): + p.terminate() + # This should be safe to call executor.shutdown here as all possible + # deadlocks should have been broken. + executor.shutdown(wait=True) + print(f"\nTraceback:\n {tb}", file=sys.__stderr__) + self.fail(f"Executor deadlock:\n\n{tb}") + + + def _check_crash(self, error, func, *args, ignore_stderr=False): + # test for deadlock caused by crashes in a pool + self.executor.shutdown(wait=True) + + executor = self.executor_type( + max_workers=2, mp_context=self.get_context()) + res = executor.submit(func, *args) + + if ignore_stderr: + cm = support.captured_stderr() + else: + cm = contextlib.nullcontext() + + try: + with self.assertRaises(error): + with cm: + res.result(timeout=self.TIMEOUT) + except futures.TimeoutError: + # If we did not recover before TIMEOUT seconds, + # consider that the executor is in a deadlock state + self._fail_on_deadlock(executor) + executor.shutdown(wait=True) + + def test_error_at_task_pickle(self): + # Check problem occurring while pickling a task in + # the task_handler thread + self._check_crash(PicklingError, id, ErrorAtPickle()) + + def test_exit_at_task_unpickle(self): + # Check problem occurring while unpickling a task on workers + self._check_crash(BrokenProcessPool, id, ExitAtUnpickle()) + + def test_error_at_task_unpickle(self): + # gh-109832: Restore stderr overriden by _raise_error_ignore_stderr() + self.addCleanup(setattr, sys, 'stderr', sys.stderr) + + # Check problem occurring while unpickling a task on workers + self._check_crash(BrokenProcessPool, id, ErrorAtUnpickle()) + + def test_crash_at_task_unpickle(self): + # Check problem occurring while unpickling a task on workers + self._check_crash(BrokenProcessPool, id, CrashAtUnpickle()) + + def test_crash_during_func_exec_on_worker(self): + # Check problem occurring during func execution on workers + self._check_crash(BrokenProcessPool, _crash) + + def test_exit_during_func_exec_on_worker(self): + # Check problem occurring during func execution on workers + self._check_crash(SystemExit, _exit) + + def test_error_during_func_exec_on_worker(self): + # Check problem occurring during func execution on workers + self._check_crash(RuntimeError, _raise_error, RuntimeError) + + def test_crash_during_result_pickle_on_worker(self): + # Check problem occurring while pickling a task result + # on workers + self._check_crash(BrokenProcessPool, _return_instance, CrashAtPickle) + + def test_exit_during_result_pickle_on_worker(self): + # Check problem occurring while pickling a task result + # on workers + self._check_crash(SystemExit, _return_instance, ExitAtPickle) + + def test_error_during_result_pickle_on_worker(self): + # Check problem occurring while pickling a task result + # on workers + self._check_crash(PicklingError, _return_instance, ErrorAtPickle) + + def test_error_during_result_unpickle_in_result_handler(self): + # gh-109832: Restore stderr overriden by _raise_error_ignore_stderr() + self.addCleanup(setattr, sys, 'stderr', sys.stderr) + + # Check problem occurring while unpickling a task in + # the result_handler thread + self._check_crash(BrokenProcessPool, + _return_instance, ErrorAtUnpickle, + ignore_stderr=True) + + def test_exit_during_result_unpickle_in_result_handler(self): + # Check problem occurring while unpickling a task in + # the result_handler thread + self._check_crash(BrokenProcessPool, _return_instance, ExitAtUnpickle) + + def test_shutdown_deadlock(self): + # Test that the pool calling shutdown do not cause deadlock + # if a worker fails after the shutdown call. + self.executor.shutdown(wait=True) + with self.executor_type(max_workers=2, + mp_context=self.get_context()) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + f = executor.submit(_crash, delay=.1) + executor.shutdown(wait=True) + with self.assertRaises(BrokenProcessPool): + f.result() + + def test_shutdown_deadlock_pickle(self): + # Test that the pool calling shutdown with wait=False does not cause + # a deadlock if a task fails at pickle after the shutdown call. + # Reported in bpo-39104. + self.executor.shutdown(wait=True) + with self.executor_type(max_workers=2, + mp_context=self.get_context()) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + + # Start the executor and get the executor_manager_thread to collect + # the threads and avoid dangling thread that should be cleaned up + # asynchronously. + executor.submit(id, 42).result() + executor_manager = executor._executor_manager_thread + + # Submit a task that fails at pickle and shutdown the executor + # without waiting + f = executor.submit(id, ErrorAtPickle()) + executor.shutdown(wait=False) + with self.assertRaises(PicklingError): + f.result() + + # Make sure the executor is eventually shutdown and do not leave + # dangling threads + executor_manager.join() + + def test_crash_big_data(self): + # Test that there is a clean exception instad of a deadlock when a + # child process crashes while some data is being written into the + # queue. + # https://github.com/python/cpython/issues/94777 + self.executor.shutdown(wait=True) + data = "a" * support.PIPE_MAX_SIZE + with self.executor_type(max_workers=2, + mp_context=self.get_context()) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + with self.assertRaises(BrokenProcessPool): + list(executor.map(_crash_with_data, [data] * 10)) + + executor.shutdown(wait=True) + + def test_gh105829_should_not_deadlock_if_wakeup_pipe_full(self): + # Issue #105829: The _ExecutorManagerThread wakeup pipe could + # fill up and block. See: https://github.com/python/cpython/issues/105829 + + # Lots of cargo culting while writing this test, apologies if + # something is really stupid... + + self.executor.shutdown(wait=True) + + if not hasattr(signal, 'alarm'): + raise unittest.SkipTest( + "Tested platform does not support the alarm signal") + + def timeout(_signum, _frame): + import faulthandler + faulthandler.dump_traceback() + + raise RuntimeError("timed out while submitting jobs?") + + thread_run = futures.process._ExecutorManagerThread.run + def mock_run(self): + # Delay thread startup so the wakeup pipe can fill up and block + time.sleep(3) + thread_run(self) + + class MockWakeup(_ThreadWakeup): + """Mock wakeup object to force the wakeup to block""" + def __init__(self): + super().__init__() + self._dummy_queue = queue.Queue(maxsize=1) + + def wakeup(self): + self._dummy_queue.put(None, block=True) + super().wakeup() + + def clear(self): + super().clear() + try: + while True: + self._dummy_queue.get_nowait() + except queue.Empty: + pass + + with (unittest.mock.patch.object(futures.process._ExecutorManagerThread, + 'run', mock_run), + unittest.mock.patch('concurrent.futures.process._ThreadWakeup', + MockWakeup)): + with self.executor_type(max_workers=2, + mp_context=self.get_context()) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + + job_num = 100 + job_data = range(job_num) + + # Need to use sigalarm for timeout detection because + # Executor.submit is not guarded by any timeout (both + # self._work_ids.put(self._queue_count) and + # self._executor_manager_thread_wakeup.wakeup() might + # timeout, maybe more?). In this specific case it was + # the wakeup call that deadlocked on a blocking pipe. + old_handler = signal.signal(signal.SIGALRM, timeout) + try: + signal.alarm(int(self.TIMEOUT)) + self.assertEqual(job_num, len(list(executor.map(int, job_data)))) + finally: + signal.alarm(0) + signal.signal(signal.SIGALRM, old_handler) + + +create_executor_tests(globals(), ExecutorDeadlockTest, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_future.py b/Lib/test/test_concurrent_futures/test_future.py new file mode 100644 index 00000000000000..4066ea1ee4b367 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_future.py @@ -0,0 +1,291 @@ +import threading +import time +import unittest +from concurrent import futures +from concurrent.futures._base import ( + PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future) + +from test import support + +from .util import ( + PENDING_FUTURE, RUNNING_FUTURE, CANCELLED_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, SUCCESSFUL_FUTURE, + BaseTestCase, create_future, setup_module) + + +class FutureTests(BaseTestCase): + def test_done_callback_with_result(self): + callback_result = None + def fn(callback_future): + nonlocal callback_result + callback_result = callback_future.result() + + f = Future() + f.add_done_callback(fn) + f.set_result(5) + self.assertEqual(5, callback_result) + + def test_done_callback_with_exception(self): + callback_exception = None + def fn(callback_future): + nonlocal callback_exception + callback_exception = callback_future.exception() + + f = Future() + f.add_done_callback(fn) + f.set_exception(Exception('test')) + self.assertEqual(('test',), callback_exception.args) + + def test_done_callback_with_cancel(self): + was_cancelled = None + def fn(callback_future): + nonlocal was_cancelled + was_cancelled = callback_future.cancelled() + + f = Future() + f.add_done_callback(fn) + self.assertTrue(f.cancel()) + self.assertTrue(was_cancelled) + + def test_done_callback_raises(self): + with support.captured_stderr() as stderr: + raising_was_called = False + fn_was_called = False + + def raising_fn(callback_future): + nonlocal raising_was_called + raising_was_called = True + raise Exception('doh!') + + def fn(callback_future): + nonlocal fn_was_called + fn_was_called = True + + f = Future() + f.add_done_callback(raising_fn) + f.add_done_callback(fn) + f.set_result(5) + self.assertTrue(raising_was_called) + self.assertTrue(fn_was_called) + self.assertIn('Exception: doh!', stderr.getvalue()) + + def test_done_callback_already_successful(self): + callback_result = None + def fn(callback_future): + nonlocal callback_result + callback_result = callback_future.result() + + f = Future() + f.set_result(5) + f.add_done_callback(fn) + self.assertEqual(5, callback_result) + + def test_done_callback_already_failed(self): + callback_exception = None + def fn(callback_future): + nonlocal callback_exception + callback_exception = callback_future.exception() + + f = Future() + f.set_exception(Exception('test')) + f.add_done_callback(fn) + self.assertEqual(('test',), callback_exception.args) + + def test_done_callback_already_cancelled(self): + was_cancelled = None + def fn(callback_future): + nonlocal was_cancelled + was_cancelled = callback_future.cancelled() + + f = Future() + self.assertTrue(f.cancel()) + f.add_done_callback(fn) + self.assertTrue(was_cancelled) + + def test_done_callback_raises_already_succeeded(self): + with support.captured_stderr() as stderr: + def raising_fn(callback_future): + raise Exception('doh!') + + f = Future() + + # Set the result first to simulate a future that runs instantly, + # effectively allowing the callback to be run immediately. + f.set_result(5) + f.add_done_callback(raising_fn) + + self.assertIn('exception calling callback for', stderr.getvalue()) + self.assertIn('doh!', stderr.getvalue()) + + + def test_repr(self): + self.assertRegex(repr(PENDING_FUTURE), + '') + self.assertRegex(repr(RUNNING_FUTURE), + '') + self.assertRegex(repr(CANCELLED_FUTURE), + '') + self.assertRegex(repr(CANCELLED_AND_NOTIFIED_FUTURE), + '') + self.assertRegex( + repr(EXCEPTION_FUTURE), + '') + self.assertRegex( + repr(SUCCESSFUL_FUTURE), + '') + + def test_cancel(self): + f1 = create_future(state=PENDING) + f2 = create_future(state=RUNNING) + f3 = create_future(state=CANCELLED) + f4 = create_future(state=CANCELLED_AND_NOTIFIED) + f5 = create_future(state=FINISHED, exception=OSError()) + f6 = create_future(state=FINISHED, result=5) + + self.assertTrue(f1.cancel()) + self.assertEqual(f1._state, CANCELLED) + + self.assertFalse(f2.cancel()) + self.assertEqual(f2._state, RUNNING) + + self.assertTrue(f3.cancel()) + self.assertEqual(f3._state, CANCELLED) + + self.assertTrue(f4.cancel()) + self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED) + + self.assertFalse(f5.cancel()) + self.assertEqual(f5._state, FINISHED) + + self.assertFalse(f6.cancel()) + self.assertEqual(f6._state, FINISHED) + + def test_cancelled(self): + self.assertFalse(PENDING_FUTURE.cancelled()) + self.assertFalse(RUNNING_FUTURE.cancelled()) + self.assertTrue(CANCELLED_FUTURE.cancelled()) + self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled()) + self.assertFalse(EXCEPTION_FUTURE.cancelled()) + self.assertFalse(SUCCESSFUL_FUTURE.cancelled()) + + def test_done(self): + self.assertFalse(PENDING_FUTURE.done()) + self.assertFalse(RUNNING_FUTURE.done()) + self.assertTrue(CANCELLED_FUTURE.done()) + self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done()) + self.assertTrue(EXCEPTION_FUTURE.done()) + self.assertTrue(SUCCESSFUL_FUTURE.done()) + + def test_running(self): + self.assertFalse(PENDING_FUTURE.running()) + self.assertTrue(RUNNING_FUTURE.running()) + self.assertFalse(CANCELLED_FUTURE.running()) + self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running()) + self.assertFalse(EXCEPTION_FUTURE.running()) + self.assertFalse(SUCCESSFUL_FUTURE.running()) + + def test_result_with_timeout(self): + self.assertRaises(futures.TimeoutError, + PENDING_FUTURE.result, timeout=0) + self.assertRaises(futures.TimeoutError, + RUNNING_FUTURE.result, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_FUTURE.result, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0) + self.assertRaises(OSError, EXCEPTION_FUTURE.result, timeout=0) + self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42) + + def test_result_with_success(self): + # TODO(brian@sweetapp.com): This test is timing dependent. + def notification(): + # Wait until the main thread is waiting for the result. + time.sleep(1) + f1.set_result(42) + + f1 = create_future(state=PENDING) + t = threading.Thread(target=notification) + t.start() + + self.assertEqual(f1.result(timeout=5), 42) + t.join() + + def test_result_with_cancel(self): + # TODO(brian@sweetapp.com): This test is timing dependent. + def notification(): + # Wait until the main thread is waiting for the result. + time.sleep(1) + f1.cancel() + + f1 = create_future(state=PENDING) + t = threading.Thread(target=notification) + t.start() + + self.assertRaises(futures.CancelledError, + f1.result, timeout=support.SHORT_TIMEOUT) + t.join() + + def test_exception_with_timeout(self): + self.assertRaises(futures.TimeoutError, + PENDING_FUTURE.exception, timeout=0) + self.assertRaises(futures.TimeoutError, + RUNNING_FUTURE.exception, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_FUTURE.exception, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0) + self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0), + OSError)) + self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None) + + def test_exception_with_success(self): + def notification(): + # Wait until the main thread is waiting for the exception. + time.sleep(1) + with f1._condition: + f1._state = FINISHED + f1._exception = OSError() + f1._condition.notify_all() + + f1 = create_future(state=PENDING) + t = threading.Thread(target=notification) + t.start() + + self.assertTrue(isinstance(f1.exception(timeout=support.SHORT_TIMEOUT), OSError)) + t.join() + + def test_multiple_set_result(self): + f = create_future(state=PENDING) + f.set_result(1) + + with self.assertRaisesRegex( + futures.InvalidStateError, + 'FINISHED: ' + ): + f.set_result(2) + + self.assertTrue(f.done()) + self.assertEqual(f.result(), 1) + + def test_multiple_set_exception(self): + f = create_future(state=PENDING) + e = ValueError() + f.set_exception(e) + + with self.assertRaisesRegex( + futures.InvalidStateError, + 'FINISHED: ' + ): + f.set_exception(Exception()) + + self.assertEqual(f.exception(), e) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_init.py b/Lib/test/test_concurrent_futures/test_init.py new file mode 100644 index 00000000000000..ce01e0ff0f287a --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_init.py @@ -0,0 +1,117 @@ +import contextlib +import logging +import queue +import time +import unittest +from concurrent.futures._base import BrokenExecutor +from logging.handlers import QueueHandler + +from test import support + +from .util import ExecutorMixin, create_executor_tests, setup_module + + +INITIALIZER_STATUS = 'uninitialized' + +def init(x): + global INITIALIZER_STATUS + INITIALIZER_STATUS = x + +def get_init_status(): + return INITIALIZER_STATUS + +def init_fail(log_queue=None): + if log_queue is not None: + logger = logging.getLogger('concurrent.futures') + logger.addHandler(QueueHandler(log_queue)) + logger.setLevel('CRITICAL') + logger.propagate = False + time.sleep(0.1) # let some futures be scheduled + raise ValueError('error in initializer') + + +class InitializerMixin(ExecutorMixin): + worker_count = 2 + + def setUp(self): + global INITIALIZER_STATUS + INITIALIZER_STATUS = 'uninitialized' + self.executor_kwargs = dict(initializer=init, + initargs=('initialized',)) + super().setUp() + + def test_initializer(self): + futures = [self.executor.submit(get_init_status) + for _ in range(self.worker_count)] + + for f in futures: + self.assertEqual(f.result(), 'initialized') + + +class FailingInitializerMixin(ExecutorMixin): + worker_count = 2 + + def setUp(self): + if hasattr(self, "ctx"): + # Pass a queue to redirect the child's logging output + self.mp_context = self.get_context() + self.log_queue = self.mp_context.Queue() + self.executor_kwargs = dict(initializer=init_fail, + initargs=(self.log_queue,)) + else: + # In a thread pool, the child shares our logging setup + # (see _assert_logged()) + self.mp_context = None + self.log_queue = None + self.executor_kwargs = dict(initializer=init_fail) + super().setUp() + + def test_initializer(self): + with self._assert_logged('ValueError: error in initializer'): + try: + future = self.executor.submit(get_init_status) + except BrokenExecutor: + # Perhaps the executor is already broken + pass + else: + with self.assertRaises(BrokenExecutor): + future.result() + + # At some point, the executor should break + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, + "executor not broken"): + if self.executor._broken: + break + + # ... and from this point submit() is guaranteed to fail + with self.assertRaises(BrokenExecutor): + self.executor.submit(get_init_status) + + @contextlib.contextmanager + def _assert_logged(self, msg): + if self.log_queue is not None: + yield + output = [] + try: + while True: + output.append(self.log_queue.get_nowait().getMessage()) + except queue.Empty: + pass + else: + with self.assertLogs('concurrent.futures', 'CRITICAL') as cm: + yield + output = cm.output + self.assertTrue(any(msg in line for line in output), + output) + + +create_executor_tests(globals(), InitializerMixin) +create_executor_tests(globals(), FailingInitializerMixin) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_process_pool.py b/Lib/test/test_concurrent_futures/test_process_pool.py new file mode 100644 index 00000000000000..c73c2da1a01088 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_process_pool.py @@ -0,0 +1,231 @@ +import os +import sys +import threading +import time +import unittest +from concurrent import futures +from concurrent.futures.process import BrokenProcessPool + +from test import support +from test.support import hashlib_helper + +from .executor import ExecutorTest, mul +from .util import ( + ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin, + create_executor_tests, setup_module) + + +class EventfulGCObj(): + def __init__(self, mgr): + self.event = mgr.Event() + + def __del__(self): + self.event.set() + + +class ProcessPoolExecutorTest(ExecutorTest): + + @unittest.skipUnless(sys.platform=='win32', 'Windows-only process limit') + def test_max_workers_too_large(self): + with self.assertRaisesRegex(ValueError, + "max_workers must be <= 61"): + futures.ProcessPoolExecutor(max_workers=62) + + def test_killed_child(self): + # When a child process is abruptly terminated, the whole pool gets + # "broken". + futures = [self.executor.submit(time.sleep, 3)] + # Get one of the processes, and terminate (kill) it + p = next(iter(self.executor._processes.values())) + p.terminate() + for fut in futures: + self.assertRaises(BrokenProcessPool, fut.result) + # Submitting other jobs fails as well. + self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) + + def test_map_chunksize(self): + def bad_map(): + list(self.executor.map(pow, range(40), range(40), chunksize=-1)) + + ref = list(map(pow, range(40), range(40))) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=6)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=50)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=40)), + ref) + self.assertRaises(ValueError, bad_map) + + @classmethod + def _test_traceback(cls): + raise RuntimeError(123) # some comment + + def test_traceback(self): + # We want ensure that the traceback from the child process is + # contained in the traceback raised in the main process. + future = self.executor.submit(self._test_traceback) + with self.assertRaises(Exception) as cm: + future.result() + + exc = cm.exception + self.assertIs(type(exc), RuntimeError) + self.assertEqual(exc.args, (123,)) + cause = exc.__cause__ + self.assertIs(type(cause), futures.process._RemoteTraceback) + self.assertIn('raise RuntimeError(123) # some comment', cause.tb) + + with support.captured_stderr() as f1: + try: + raise exc + except RuntimeError: + sys.excepthook(*sys.exc_info()) + self.assertIn('raise RuntimeError(123) # some comment', + f1.getvalue()) + + @hashlib_helper.requires_hashdigest('md5') + def test_ressources_gced_in_workers(self): + # Ensure that argument for a job are correctly gc-ed after the job + # is finished + mgr = self.get_context().Manager() + obj = EventfulGCObj(mgr) + future = self.executor.submit(id, obj) + future.result() + + self.assertTrue(obj.event.wait(timeout=1)) + + # explicitly destroy the object to ensure that EventfulGCObj.__del__() + # is called while manager is still running. + obj = None + support.gc_collect() + + mgr.shutdown() + mgr.join() + + def test_saturation(self): + executor = self.executor + mp_context = self.get_context() + sem = mp_context.Semaphore(0) + job_count = 15 * executor._max_workers + for _ in range(job_count): + executor.submit(sem.acquire) + self.assertEqual(len(executor._processes), executor._max_workers) + for _ in range(job_count): + sem.release() + + def test_idle_process_reuse_one(self): + executor = self.executor + assert executor._max_workers >= 4 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") + executor.submit(mul, 21, 2).result() + executor.submit(mul, 6, 7).result() + executor.submit(mul, 3, 14).result() + self.assertEqual(len(executor._processes), 1) + + def test_idle_process_reuse_multiple(self): + executor = self.executor + assert executor._max_workers <= 5 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") + executor.submit(mul, 12, 7).result() + executor.submit(mul, 33, 25) + executor.submit(mul, 25, 26).result() + executor.submit(mul, 18, 29) + executor.submit(mul, 1, 2).result() + executor.submit(mul, 0, 9) + self.assertLessEqual(len(executor._processes), 3) + executor.shutdown() + + def test_max_tasks_per_child(self): + context = self.get_context() + if context.get_start_method(allow_none=False) == "fork": + with self.assertRaises(ValueError): + self.executor_type(1, mp_context=context, max_tasks_per_child=3) + return + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type( + 1, mp_context=context, max_tasks_per_child=3) + f1 = executor.submit(os.getpid) + original_pid = f1.result() + # The worker pid remains the same as the worker could be reused + f2 = executor.submit(os.getpid) + self.assertEqual(f2.result(), original_pid) + self.assertEqual(len(executor._processes), 1) + f3 = executor.submit(os.getpid) + self.assertEqual(f3.result(), original_pid) + + # A new worker is spawned, with a statistically different pid, + # while the previous was reaped. + f4 = executor.submit(os.getpid) + new_pid = f4.result() + self.assertNotEqual(original_pid, new_pid) + self.assertEqual(len(executor._processes), 1) + + executor.shutdown() + + def test_max_tasks_per_child_defaults_to_spawn_context(self): + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type(1, max_tasks_per_child=3) + self.assertEqual(executor._mp_context.get_start_method(), "spawn") + + def test_max_tasks_early_shutdown(self): + context = self.get_context() + if context.get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type( + 3, mp_context=context, max_tasks_per_child=1) + futures = [] + for i in range(6): + futures.append(executor.submit(mul, i, i)) + executor.shutdown() + for i, future in enumerate(futures): + self.assertEqual(future.result(), mul(i, i)) + + def test_python_finalization_error(self): + # gh-109047: Catch RuntimeError on thread creation + # during Python finalization. + + context = self.get_context() + + # gh-109047: Mock the threading.start_new_thread() function to inject + # RuntimeError: simulate the error raised during Python finalization. + # Block the second creation: create _ExecutorManagerThread, but block + # QueueFeederThread. + orig_start_new_thread = threading._start_new_thread + nthread = 0 + def mock_start_new_thread(func, *args): + nonlocal nthread + if nthread >= 1: + raise RuntimeError("can't create new thread at " + "interpreter shutdown") + nthread += 1 + return orig_start_new_thread(func, *args) + + with support.swap_attr(threading, '_start_new_thread', + mock_start_new_thread): + executor = self.executor_type(max_workers=2, mp_context=context) + with executor: + with self.assertRaises(BrokenProcessPool): + list(executor.map(mul, [(2, 3)] * 10)) + executor.shutdown() + + +create_executor_tests(globals(), ProcessPoolExecutorTest, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py new file mode 100644 index 00000000000000..45dab7a75fdd50 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -0,0 +1,343 @@ +import signal +import sys +import threading +import time +import unittest +from concurrent import futures + +from test import support +from test.support.script_helper import assert_python_ok + +from .util import ( + BaseTestCase, ThreadPoolMixin, ProcessPoolForkMixin, + ProcessPoolForkserverMixin, ProcessPoolSpawnMixin, + create_executor_tests, setup_module) + + +def sleep_and_print(t, msg): + time.sleep(t) + print(msg) + sys.stdout.flush() + + +class ExecutorShutdownTest: + def test_run_after_shutdown(self): + self.executor.shutdown() + self.assertRaises(RuntimeError, + self.executor.submit, + pow, 2, 5) + + def test_interpreter_shutdown(self): + # Test the atexit hook for shutdown of worker threads and processes + rc, out, err = assert_python_ok('-c', """if 1: + from concurrent.futures import {executor_type} + from time import sleep + from test.test_concurrent_futures.test_shutdown import sleep_and_print + if __name__ == "__main__": + context = '{context}' + if context == "": + t = {executor_type}(5) + else: + from multiprocessing import get_context + context = get_context(context) + t = {executor_type}(5, mp_context=context) + t.submit(sleep_and_print, 1.0, "apple") + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, "ctx", ""))) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertFalse(err) + self.assertEqual(out.strip(), b"apple") + + def test_submit_after_interpreter_shutdown(self): + # Test the atexit hook for shutdown of worker threads and processes + rc, out, err = assert_python_ok('-c', """if 1: + import atexit + @atexit.register + def run_last(): + try: + t.submit(id, None) + except RuntimeError: + print("runtime-error") + raise + from concurrent.futures import {executor_type} + if __name__ == "__main__": + context = '{context}' + if not context: + t = {executor_type}(5) + else: + from multiprocessing import get_context + context = get_context(context) + t = {executor_type}(5, mp_context=context) + t.submit(id, 42).result() + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, "ctx", ""))) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) + self.assertEqual(out.strip(), b"runtime-error") + + def test_hang_issue12364(self): + fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] + self.executor.shutdown() + for f in fs: + f.result() + + def test_cancel_futures(self): + assert self.worker_count <= 5, "test needs few workers" + fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] + self.executor.shutdown(cancel_futures=True) + # We can't guarantee the exact number of cancellations, but we can + # guarantee that *some* were cancelled. With few workers, many of + # the submitted futures should have been cancelled. + cancelled = [fut for fut in fs if fut.cancelled()] + self.assertGreater(len(cancelled), 20) + + # Ensure the other futures were able to finish. + # Use "not fut.cancelled()" instead of "fut.done()" to include futures + # that may have been left in a pending state. + others = [fut for fut in fs if not fut.cancelled()] + for fut in others: + self.assertTrue(fut.done(), msg=f"{fut._state=}") + self.assertIsNone(fut.exception()) + + # Similar to the number of cancelled futures, we can't guarantee the + # exact number that completed. But, we can guarantee that at least + # one finished. + self.assertGreater(len(others), 0) + + def test_hang_gh83386(self): + """shutdown(wait=False) doesn't hang at exit with running futures. + + See https://github.com/python/cpython/issues/83386. + """ + if self.executor_type == futures.ProcessPoolExecutor: + raise unittest.SkipTest( + "Hangs, see https://github.com/python/cpython/issues/83386") + + rc, out, err = assert_python_ok('-c', """if True: + from concurrent.futures import {executor_type} + from test.test_concurrent_futures.test_shutdown import sleep_and_print + if __name__ == "__main__": + if {context!r}: multiprocessing.set_start_method({context!r}) + t = {executor_type}(max_workers=3) + t.submit(sleep_and_print, 1.0, "apple") + t.shutdown(wait=False) + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, 'ctx', None))) + self.assertFalse(err) + self.assertEqual(out.strip(), b"apple") + + def test_hang_gh94440(self): + """shutdown(wait=True) doesn't hang when a future was submitted and + quickly canceled right before shutdown. + + See https://github.com/python/cpython/issues/94440. + """ + if not hasattr(signal, 'alarm'): + raise unittest.SkipTest( + "Tested platform does not support the alarm signal") + + def timeout(_signum, _frame): + raise RuntimeError("timed out waiting for shutdown") + + kwargs = {} + if getattr(self, 'ctx', None): + kwargs['mp_context'] = self.get_context() + executor = self.executor_type(max_workers=1, **kwargs) + executor.submit(int).result() + old_handler = signal.signal(signal.SIGALRM, timeout) + try: + signal.alarm(5) + executor.submit(int).cancel() + executor.shutdown(wait=True) + finally: + signal.alarm(0) + signal.signal(signal.SIGALRM, old_handler) + + +class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): + def test_threads_terminate(self): + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(3): + self.executor.submit(acquire_lock, sem) + self.assertEqual(len(self.executor._threads), 3) + for i in range(3): + sem.release() + self.executor.shutdown() + for t in self.executor._threads: + t.join() + + def test_context_manager_shutdown(self): + with futures.ThreadPoolExecutor(max_workers=5) as e: + executor = e + self.assertEqual(list(e.map(abs, range(-5, 5))), + [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) + + for t in executor._threads: + t.join() + + def test_del_shutdown(self): + executor = futures.ThreadPoolExecutor(max_workers=5) + res = executor.map(abs, range(-5, 5)) + threads = executor._threads + del executor + + for t in threads: + t.join() + + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + def test_shutdown_no_wait(self): + # Ensure that the executor cleans up the threads when calling + # shutdown with wait=False + executor = futures.ThreadPoolExecutor(max_workers=5) + res = executor.map(abs, range(-5, 5)) + threads = executor._threads + executor.shutdown(wait=False) + for t in threads: + t.join() + + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + + def test_thread_names_assigned(self): + executor = futures.ThreadPoolExecutor( + max_workers=5, thread_name_prefix='SpecialPool') + executor.map(abs, range(-5, 5)) + threads = executor._threads + del executor + support.gc_collect() # For PyPy or other GCs. + + for t in threads: + self.assertRegex(t.name, r'^SpecialPool_[0-4]$') + t.join() + + def test_thread_names_default(self): + executor = futures.ThreadPoolExecutor(max_workers=5) + executor.map(abs, range(-5, 5)) + threads = executor._threads + del executor + support.gc_collect() # For PyPy or other GCs. + + for t in threads: + # Ensure that our default name is reasonably sane and unique when + # no thread_name_prefix was supplied. + self.assertRegex(t.name, r'ThreadPoolExecutor-\d+_[0-4]$') + t.join() + + def test_cancel_futures_wait_false(self): + # Can only be reliably tested for TPE, since PPE often hangs with + # `wait=False` (even without *cancel_futures*). + rc, out, err = assert_python_ok('-c', """if True: + from concurrent.futures import ThreadPoolExecutor + from test.test_concurrent_futures.test_shutdown import sleep_and_print + if __name__ == "__main__": + t = ThreadPoolExecutor() + t.submit(sleep_and_print, .1, "apple") + t.shutdown(wait=False, cancel_futures=True) + """) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertFalse(err) + self.assertEqual(out.strip(), b"apple") + + +class ProcessPoolShutdownTest(ExecutorShutdownTest): + def test_processes_terminate(self): + def acquire_lock(lock): + lock.acquire() + + mp_context = self.get_context() + if mp_context.get_start_method(allow_none=False) == "fork": + # fork pre-spawns, not on demand. + expected_num_processes = self.worker_count + else: + expected_num_processes = 3 + + sem = mp_context.Semaphore(0) + for _ in range(3): + self.executor.submit(acquire_lock, sem) + self.assertEqual(len(self.executor._processes), expected_num_processes) + for _ in range(3): + sem.release() + processes = self.executor._processes + self.executor.shutdown() + + for p in processes.values(): + p.join() + + def test_context_manager_shutdown(self): + with futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) as e: + processes = e._processes + self.assertEqual(list(e.map(abs, range(-5, 5))), + [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) + + for p in processes.values(): + p.join() + + def test_del_shutdown(self): + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) + res = executor.map(abs, range(-5, 5)) + executor_manager_thread = executor._executor_manager_thread + processes = executor._processes + call_queue = executor._call_queue + executor_manager_thread = executor._executor_manager_thread + del executor + support.gc_collect() # For PyPy or other GCs. + + # Make sure that all the executor resources were properly cleaned by + # the shutdown process + executor_manager_thread.join() + for p in processes.values(): + p.join() + call_queue.join_thread() + + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + def test_shutdown_no_wait(self): + # Ensure that the executor cleans up the processes when calling + # shutdown with wait=False + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) + res = executor.map(abs, range(-5, 5)) + processes = executor._processes + call_queue = executor._call_queue + executor_manager_thread = executor._executor_manager_thread + executor.shutdown(wait=False) + + # Make sure that all the executor resources were properly cleaned by + # the shutdown process + executor_manager_thread.join() + for p in processes.values(): + p.join() + call_queue.join_thread() + + # Make sure the results were all computed before the executor got + # shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + +create_executor_tests(globals(), ProcessPoolShutdownTest, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_thread_pool.py b/Lib/test/test_concurrent_futures/test_thread_pool.py new file mode 100644 index 00000000000000..5926a632aa4bec --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_thread_pool.py @@ -0,0 +1,100 @@ +import contextlib +import multiprocessing as mp +import multiprocessing.process +import multiprocessing.util +import os +import threading +import unittest +from concurrent import futures +from test import support + +from .executor import ExecutorTest, mul +from .util import BaseTestCase, ThreadPoolMixin, setup_module + + +class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase): + def test_map_submits_without_iteration(self): + """Tests verifying issue 11777.""" + finished = [] + def record_finished(n): + finished.append(n) + + self.executor.map(record_finished, range(10)) + self.executor.shutdown(wait=True) + self.assertCountEqual(finished, range(10)) + + def test_default_workers(self): + executor = self.executor_type() + expected = min(32, (os.process_cpu_count() or 1) + 4) + self.assertEqual(executor._max_workers, expected) + + def test_saturation(self): + executor = self.executor_type(4) + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(15 * executor._max_workers): + executor.submit(acquire_lock, sem) + self.assertEqual(len(executor._threads), executor._max_workers) + for i in range(15 * executor._max_workers): + sem.release() + executor.shutdown(wait=True) + + def test_idle_thread_reuse(self): + executor = self.executor_type() + executor.submit(mul, 21, 2).result() + executor.submit(mul, 6, 7).result() + executor.submit(mul, 3, 14).result() + self.assertEqual(len(executor._threads), 1) + executor.shutdown(wait=True) + + @unittest.skipUnless(hasattr(os, 'register_at_fork'), 'need os.register_at_fork') + @support.requires_resource('cpu') + def test_hang_global_shutdown_lock(self): + # bpo-45021: _global_shutdown_lock should be reinitialized in the child + # process, otherwise it will never exit + def submit(pool): + pool.submit(submit, pool) + + with futures.ThreadPoolExecutor(1) as pool: + pool.submit(submit, pool) + + for _ in range(50): + with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: + workers.submit(tuple) + + def test_executor_map_current_future_cancel(self): + stop_event = threading.Event() + log = [] + + def log_n_wait(ident): + log.append(f"{ident=} started") + try: + stop_event.wait() + finally: + log.append(f"{ident=} stopped") + + with self.executor_type(max_workers=1) as pool: + # submit work to saturate the pool + fut = pool.submit(log_n_wait, ident="first") + try: + with contextlib.closing( + pool.map(log_n_wait, ["second", "third"], timeout=0) + ) as gen: + with self.assertRaises(TimeoutError): + next(gen) + finally: + stop_event.set() + fut.result() + # ident='second' is cancelled as a result of raising a TimeoutError + # ident='third' is cancelled because it remained in the collection of futures + self.assertListEqual(log, ["ident='first' started", "ident='first' stopped"]) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_wait.py b/Lib/test/test_concurrent_futures/test_wait.py new file mode 100644 index 00000000000000..ff486202092c81 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_wait.py @@ -0,0 +1,165 @@ +import sys +import threading +import time +import unittest +from concurrent import futures +from test import support + +from .util import ( + CANCELLED_FUTURE, CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + create_executor_tests, setup_module, + BaseTestCase, ThreadPoolMixin, + ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin) + + +def mul(x, y): + return x * y + +def sleep_and_raise(t): + time.sleep(t) + raise Exception('this is an exception') + + +class WaitTests: + def test_20369(self): + # See https://bugs.python.org/issue20369 + future = self.executor.submit(time.sleep, 1.5) + done, not_done = futures.wait([future, future], + return_when=futures.ALL_COMPLETED) + self.assertEqual({future}, done) + self.assertEqual(set(), not_done) + + + def test_first_completed(self): + future1 = self.executor.submit(mul, 21, 2) + future2 = self.executor.submit(time.sleep, 1.5) + + done, not_done = futures.wait( + [CANCELLED_FUTURE, future1, future2], + return_when=futures.FIRST_COMPLETED) + + self.assertEqual(set([future1]), done) + self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done) + + def test_first_completed_some_already_completed(self): + future1 = self.executor.submit(time.sleep, 1.5) + + finished, pending = futures.wait( + [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1], + return_when=futures.FIRST_COMPLETED) + + self.assertEqual( + set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]), + finished) + self.assertEqual(set([future1]), pending) + + @support.requires_resource('walltime') + def test_first_exception(self): + future1 = self.executor.submit(mul, 2, 21) + future2 = self.executor.submit(sleep_and_raise, 1.5) + future3 = self.executor.submit(time.sleep, 3) + + finished, pending = futures.wait( + [future1, future2, future3], + return_when=futures.FIRST_EXCEPTION) + + self.assertEqual(set([future1, future2]), finished) + self.assertEqual(set([future3]), pending) + + def test_first_exception_some_already_complete(self): + future1 = self.executor.submit(divmod, 21, 0) + future2 = self.executor.submit(time.sleep, 1.5) + + finished, pending = futures.wait( + [SUCCESSFUL_FUTURE, + CANCELLED_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + future1, future2], + return_when=futures.FIRST_EXCEPTION) + + self.assertEqual(set([SUCCESSFUL_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + future1]), finished) + self.assertEqual(set([CANCELLED_FUTURE, future2]), pending) + + def test_first_exception_one_already_failed(self): + future1 = self.executor.submit(time.sleep, 2) + + finished, pending = futures.wait( + [EXCEPTION_FUTURE, future1], + return_when=futures.FIRST_EXCEPTION) + + self.assertEqual(set([EXCEPTION_FUTURE]), finished) + self.assertEqual(set([future1]), pending) + + def test_all_completed(self): + future1 = self.executor.submit(divmod, 2, 0) + future2 = self.executor.submit(mul, 2, 21) + + finished, pending = futures.wait( + [SUCCESSFUL_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + future1, + future2], + return_when=futures.ALL_COMPLETED) + + self.assertEqual(set([SUCCESSFUL_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + future1, + future2]), finished) + self.assertEqual(set(), pending) + + def test_timeout(self): + short_timeout = 0.050 + long_timeout = short_timeout * 10 + + future = self.executor.submit(time.sleep, long_timeout) + + finished, pending = futures.wait( + [CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + future], + timeout=short_timeout, + return_when=futures.ALL_COMPLETED) + + self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE]), + finished) + self.assertEqual(set([future]), pending) + + +class ThreadPoolWaitTests(ThreadPoolMixin, WaitTests, BaseTestCase): + + def test_pending_calls_race(self): + # Issue #14406: multi-threaded race condition when waiting on all + # futures. + event = threading.Event() + def future_func(): + event.wait() + oldswitchinterval = sys.getswitchinterval() + sys.setswitchinterval(1e-6) + try: + fs = {self.executor.submit(future_func) for i in range(100)} + event.set() + futures.wait(fs, return_when=futures.ALL_COMPLETED) + finally: + sys.setswitchinterval(oldswitchinterval) + + +create_executor_tests(globals(), WaitTests, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/util.py b/Lib/test/test_concurrent_futures/util.py new file mode 100644 index 00000000000000..dc48bec796b87f --- /dev/null +++ b/Lib/test/test_concurrent_futures/util.py @@ -0,0 +1,141 @@ +import multiprocessing +import sys +import time +import unittest +from concurrent import futures +from concurrent.futures._base import ( + PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, + ) +from concurrent.futures.process import _check_system_limits + +from test import support +from test.support import threading_helper + + +def create_future(state=PENDING, exception=None, result=None): + f = Future() + f._state = state + f._exception = exception + f._result = result + return f + + +PENDING_FUTURE = create_future(state=PENDING) +RUNNING_FUTURE = create_future(state=RUNNING) +CANCELLED_FUTURE = create_future(state=CANCELLED) +CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED) +EXCEPTION_FUTURE = create_future(state=FINISHED, exception=OSError()) +SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42) + + +class BaseTestCase(unittest.TestCase): + def setUp(self): + self._thread_key = threading_helper.threading_setup() + + def tearDown(self): + support.reap_children() + threading_helper.threading_cleanup(*self._thread_key) + + +class ExecutorMixin: + worker_count = 5 + executor_kwargs = {} + + def setUp(self): + super().setUp() + + self.t1 = time.monotonic() + if hasattr(self, "ctx"): + self.executor = self.executor_type( + max_workers=self.worker_count, + mp_context=self.get_context(), + **self.executor_kwargs) + else: + self.executor = self.executor_type( + max_workers=self.worker_count, + **self.executor_kwargs) + + def tearDown(self): + self.executor.shutdown(wait=True) + self.executor = None + + dt = time.monotonic() - self.t1 + if support.verbose: + print("%.2fs" % dt, end=' ') + self.assertLess(dt, 300, "synchronization issue: test lasted too long") + + super().tearDown() + + def get_context(self): + return multiprocessing.get_context(self.ctx) + + +class ThreadPoolMixin(ExecutorMixin): + executor_type = futures.ThreadPoolExecutor + + +class ProcessPoolForkMixin(ExecutorMixin): + executor_type = futures.ProcessPoolExecutor + ctx = "fork" + + def get_context(self): + try: + _check_system_limits() + except NotImplementedError: + self.skipTest("ProcessPoolExecutor unavailable on this system") + if sys.platform == "win32": + self.skipTest("require unix system") + return super().get_context() + + +class ProcessPoolSpawnMixin(ExecutorMixin): + executor_type = futures.ProcessPoolExecutor + ctx = "spawn" + + def get_context(self): + try: + _check_system_limits() + except NotImplementedError: + self.skipTest("ProcessPoolExecutor unavailable on this system") + return super().get_context() + + +class ProcessPoolForkserverMixin(ExecutorMixin): + executor_type = futures.ProcessPoolExecutor + ctx = "forkserver" + + def get_context(self): + try: + _check_system_limits() + except NotImplementedError: + self.skipTest("ProcessPoolExecutor unavailable on this system") + if sys.platform == "win32": + self.skipTest("require unix system") + return super().get_context() + + +def create_executor_tests(remote_globals, mixin, bases=(BaseTestCase,), + executor_mixins=(ThreadPoolMixin, + ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)): + def strip_mixin(name): + if name.endswith(('Mixin', 'Tests')): + return name[:-5] + elif name.endswith('Test'): + return name[:-4] + else: + return name + + module = remote_globals['__name__'] + for exe in executor_mixins: + name = ("%s%sTest" + % (strip_mixin(exe.__name__), strip_mixin(mixin.__name__))) + cls = type(name, (mixin,) + (exe,) + bases, {'__module__': module}) + remote_globals[name] = cls + + +def setup_module(): + unittest.addModuleCleanup(multiprocessing.util._cleanup_tests) + thread_info = threading_helper.threading_setup() + unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index b1aece4f5c9c49..255be306156c0b 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -6,10 +6,11 @@ import time import unittest import weakref +from test import support from test.support import threading_helper try: - from _testcapi import hamt + from _testinternalcapi import hamt except ImportError: hamt = None @@ -431,7 +432,7 @@ class EqError(Exception): pass -@unittest.skipIf(hamt is None, '_testcapi lacks "hamt()" function') +@unittest.skipIf(hamt is None, '_testinternalcapi.hamt() not available') class HamtTest(unittest.TestCase): def test_hashkey_helper_1(self): @@ -570,6 +571,7 @@ def test_hamt_collision_3(self): self.assertEqual({k.name for k in h.keys()}, {'C', 'D', 'E'}) + @support.requires_resource('cpu') def test_hamt_stress(self): COLLECTION_SIZE = 7000 TEST_ITERS_EVERY = 647 diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index ecc5a43dad43da..5d94ec7cae4706 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -167,9 +167,24 @@ def whoo(): yield ctx = whoo() ctx.__enter__() - self.assertRaises( - RuntimeError, ctx.__exit__, TypeError, TypeError("foo"), None - ) + with self.assertRaises(RuntimeError): + ctx.__exit__(TypeError, TypeError("foo"), None) + if support.check_impl_detail(cpython=True): + # The "gen" attribute is an implementation detail. + self.assertFalse(ctx.gen.gi_suspended) + + def test_contextmanager_trap_second_yield(self): + @contextmanager + def whoo(): + yield + yield + ctx = whoo() + ctx.__enter__() + with self.assertRaises(RuntimeError): + ctx.__exit__(None, None, None) + if support.check_impl_detail(cpython=True): + # The "gen" attribute is an implementation detail. + self.assertFalse(ctx.gen.gi_suspended) def test_contextmanager_except(self): state = [] @@ -1085,7 +1100,7 @@ def first(): class TestExitStack(TestBaseExitStack, unittest.TestCase): exit_stack = ExitStack callback_error_internal_frames = [ - ('__exit__', 'raise exc_details[1]'), + ('__exit__', 'raise exc'), ('__exit__', 'if cb(*exc_details):'), ] diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index bb72ae74e5845f..ca7315783b9674 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -2,7 +2,6 @@ from contextlib import ( asynccontextmanager, AbstractAsyncContextManager, AsyncExitStack, nullcontext, aclosing, contextmanager) -import functools from test import support import unittest import traceback @@ -11,21 +10,12 @@ support.requires_working_socket(module=True) -def _async_test(func): - """Decorator to turn an async function into a test case.""" - @functools.wraps(func) - def wrapper(*args, **kwargs): - coro = func(*args, **kwargs) - asyncio.run(coro) - return wrapper - def tearDownModule(): asyncio.set_event_loop_policy(None) -class TestAbstractAsyncContextManager(unittest.TestCase): +class TestAbstractAsyncContextManager(unittest.IsolatedAsyncioTestCase): - @_async_test async def test_enter(self): class DefaultEnter(AbstractAsyncContextManager): async def __aexit__(self, *args): @@ -37,7 +27,6 @@ async def __aexit__(self, *args): async with manager as context: self.assertIs(manager, context) - @_async_test async def test_slots(self): class DefaultAsyncContextManager(AbstractAsyncContextManager): __slots__ = () @@ -49,7 +38,6 @@ async def __aexit__(self, *args): manager = DefaultAsyncContextManager() manager.var = 42 - @_async_test async def test_async_gen_propagates_generator_exit(self): # A regression test for https://bugs.python.org/issue33786. @@ -61,15 +49,11 @@ async def gen(): async with ctx(): yield 11 - ret = [] - exc = ValueError(22) - with self.assertRaises(ValueError): - async with ctx(): - async for val in gen(): - ret.append(val) - raise exc - - self.assertEqual(ret, [11]) + g = gen() + async for val in g: + self.assertEqual(val, 11) + break + await g.aclose() def test_exit_is_abstract(self): class MissingAexit(AbstractAsyncContextManager): @@ -104,9 +88,8 @@ class NoneAexit(ManagerFromScratch): self.assertFalse(issubclass(NoneAexit, AbstractAsyncContextManager)) -class AsyncContextManagerTestCase(unittest.TestCase): +class AsyncContextManagerTestCase(unittest.IsolatedAsyncioTestCase): - @_async_test async def test_contextmanager_plain(self): state = [] @asynccontextmanager @@ -120,7 +103,6 @@ async def woohoo(): state.append(x) self.assertEqual(state, [1, 42, 999]) - @_async_test async def test_contextmanager_finally(self): state = [] @asynccontextmanager @@ -138,7 +120,6 @@ async def woohoo(): raise ZeroDivisionError() self.assertEqual(state, [1, 42, 999]) - @_async_test async def test_contextmanager_traceback(self): @asynccontextmanager async def f(): @@ -194,7 +175,6 @@ class StopAsyncIterationSubclass(StopAsyncIteration): self.assertEqual(frames[0].name, 'test_contextmanager_traceback') self.assertEqual(frames[0].line, 'raise stop_exc') - @_async_test async def test_contextmanager_no_reraise(self): @asynccontextmanager async def whee(): @@ -204,7 +184,6 @@ async def whee(): # Calling __aexit__ should not result in an exception self.assertFalse(await ctx.__aexit__(TypeError, TypeError("foo"), None)) - @_async_test async def test_contextmanager_trap_yield_after_throw(self): @asynccontextmanager async def whoo(): @@ -216,8 +195,10 @@ async def whoo(): await ctx.__aenter__() with self.assertRaises(RuntimeError): await ctx.__aexit__(TypeError, TypeError('foo'), None) + if support.check_impl_detail(cpython=True): + # The "gen" attribute is an implementation detail. + self.assertFalse(ctx.gen.ag_suspended) - @_async_test async def test_contextmanager_trap_no_yield(self): @asynccontextmanager async def whoo(): @@ -227,7 +208,6 @@ async def whoo(): with self.assertRaises(RuntimeError): await ctx.__aenter__() - @_async_test async def test_contextmanager_trap_second_yield(self): @asynccontextmanager async def whoo(): @@ -237,8 +217,10 @@ async def whoo(): await ctx.__aenter__() with self.assertRaises(RuntimeError): await ctx.__aexit__(None, None, None) + if support.check_impl_detail(cpython=True): + # The "gen" attribute is an implementation detail. + self.assertFalse(ctx.gen.ag_suspended) - @_async_test async def test_contextmanager_non_normalised(self): @asynccontextmanager async def whoo(): @@ -252,7 +234,6 @@ async def whoo(): with self.assertRaises(SyntaxError): await ctx.__aexit__(RuntimeError, None, None) - @_async_test async def test_contextmanager_except(self): state = [] @asynccontextmanager @@ -270,7 +251,6 @@ async def woohoo(): raise ZeroDivisionError(999) self.assertEqual(state, [1, 42, 999]) - @_async_test async def test_contextmanager_except_stopiter(self): @asynccontextmanager async def woohoo(): @@ -297,7 +277,6 @@ class StopAsyncIterationSubclass(StopAsyncIteration): else: self.fail(f'{stop_exc} was suppressed') - @_async_test async def test_contextmanager_wrap_runtimeerror(self): @asynccontextmanager async def woohoo(): @@ -342,14 +321,12 @@ def test_contextmanager_doc_attrib(self): self.assertEqual(baz.__doc__, "Whee!") @support.requires_docstrings - @_async_test async def test_instance_docstring_given_cm_docstring(self): baz = self._create_contextmanager_attribs()(None) self.assertEqual(baz.__doc__, "Whee!") async with baz: pass # suppress warning - @_async_test async def test_keywords(self): # Ensure no keyword arguments are inhibited @asynccontextmanager @@ -358,7 +335,6 @@ async def woohoo(self, func, args, kwds): async with woohoo(self=11, func=22, args=33, kwds=44) as target: self.assertEqual(target, (11, 22, 33, 44)) - @_async_test async def test_recursive(self): depth = 0 ncols = 0 @@ -385,7 +361,6 @@ async def recursive(): self.assertEqual(ncols, 10) self.assertEqual(depth, 0) - @_async_test async def test_decorator(self): entered = False @@ -404,7 +379,6 @@ async def test(): await test() self.assertFalse(entered) - @_async_test async def test_decorator_with_exception(self): entered = False @@ -427,7 +401,6 @@ async def test(): await test() self.assertFalse(entered) - @_async_test async def test_decorating_method(self): @asynccontextmanager @@ -462,7 +435,7 @@ async def method(self, a, b, c=None): self.assertEqual(test.b, 2) -class AclosingTestCase(unittest.TestCase): +class AclosingTestCase(unittest.IsolatedAsyncioTestCase): @support.requires_docstrings def test_instance_docs(self): @@ -470,7 +443,6 @@ def test_instance_docs(self): obj = aclosing(None) self.assertEqual(obj.__doc__, cm_docstring) - @_async_test async def test_aclosing(self): state = [] class C: @@ -482,7 +454,6 @@ async def aclose(self): self.assertEqual(x, y) self.assertEqual(state, [1]) - @_async_test async def test_aclosing_error(self): state = [] class C: @@ -496,7 +467,6 @@ async def aclose(self): 1 / 0 self.assertEqual(state, [1]) - @_async_test async def test_aclosing_bpo41229(self): state = [] @@ -522,7 +492,7 @@ async def agenfunc(): self.assertEqual(state, [1]) -class TestAsyncExitStack(TestBaseExitStack, unittest.TestCase): +class TestAsyncExitStack(TestBaseExitStack, unittest.IsolatedAsyncioTestCase): class SyncAsyncExitStack(AsyncExitStack): @staticmethod def run_coroutine(coro): @@ -557,17 +527,10 @@ def __exit__(self, *exc_details): ('__exit__', 'return self.run_coroutine(self.__aexit__(*exc_details))'), ('run_coroutine', 'raise exc'), ('run_coroutine', 'raise exc'), - ('__aexit__', 'raise exc_details[1]'), + ('__aexit__', 'raise exc'), ('__aexit__', 'cb_suppress = cb(*exc_details)'), ] - def setUp(self): - self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(self.loop) - self.addCleanup(self.loop.close) - self.addCleanup(asyncio.set_event_loop_policy, None) - - @_async_test async def test_async_callback(self): expected = [ ((), {}), @@ -610,7 +573,6 @@ async def _exit(*args, **kwds): stack.push_async_callback(callback=_exit, arg=3) self.assertEqual(result, []) - @_async_test async def test_async_push(self): exc_raised = ZeroDivisionError async def _expect_exc(exc_type, exc, exc_tb): @@ -646,7 +608,6 @@ async def __aexit__(self, *exc_details): self.assertIs(stack._exit_callbacks[-1][1], _expect_exc) 1/0 - @_async_test async def test_enter_async_context(self): class TestCM(object): async def __aenter__(self): @@ -668,7 +629,6 @@ async def _exit(): self.assertEqual(result, [1, 2, 3, 4]) - @_async_test async def test_enter_async_context_errors(self): class LacksEnterAndExit: pass @@ -688,7 +648,6 @@ async def __aenter__(self): await stack.enter_async_context(LacksExit()) self.assertFalse(stack._exit_callbacks) - @_async_test async def test_async_exit_exception_chaining(self): # Ensure exception chaining matches the reference behaviour async def raise_exc(exc): @@ -720,7 +679,6 @@ async def suppress_exc(*exc_details): self.assertIsInstance(inner_exc, ValueError) self.assertIsInstance(inner_exc.__context__, ZeroDivisionError) - @_async_test async def test_async_exit_exception_explicit_none_context(self): # Ensure AsyncExitStack chaining matches actual nested `with` statements # regarding explicit __context__ = None. @@ -755,7 +713,6 @@ async def my_cm_with_exit_stack(): else: self.fail("Expected IndexError, but no exception was raised") - @_async_test async def test_instance_bypass_async(self): class Example(object): pass cm = Example() @@ -768,8 +725,7 @@ class Example(object): pass self.assertIs(stack._exit_callbacks[-1][1], cm) -class TestAsyncNullcontext(unittest.TestCase): - @_async_test +class TestAsyncNullcontext(unittest.IsolatedAsyncioTestCase): async def test_async_nullcontext(self): class C: pass diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index 826e46824e004c..60735ba89a80ee 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -4,7 +4,7 @@ import copyreg import weakref import abc -from operator import le, lt, ge, gt, eq, ne +from operator import le, lt, ge, gt, eq, ne, attrgetter import unittest from test import support @@ -899,7 +899,81 @@ def m(self): g.b() +class TestReplace(unittest.TestCase): + + def test_unsupported(self): + self.assertRaises(TypeError, copy.replace, 1) + self.assertRaises(TypeError, copy.replace, []) + self.assertRaises(TypeError, copy.replace, {}) + def f(): pass + self.assertRaises(TypeError, copy.replace, f) + class A: pass + self.assertRaises(TypeError, copy.replace, A) + self.assertRaises(TypeError, copy.replace, A()) + + def test_replace_method(self): + class A: + def __new__(cls, x, y=0): + self = object.__new__(cls) + self.x = x + self.y = y + return self + + def __init__(self, *args, **kwargs): + self.z = self.x + self.y + + def __replace__(self, **changes): + x = changes.get('x', self.x) + y = changes.get('y', self.y) + return type(self)(x, y) + + attrs = attrgetter('x', 'y', 'z') + a = A(11, 22) + self.assertEqual(attrs(copy.replace(a)), (11, 22, 33)) + self.assertEqual(attrs(copy.replace(a, x=1)), (1, 22, 23)) + self.assertEqual(attrs(copy.replace(a, y=2)), (11, 2, 13)) + self.assertEqual(attrs(copy.replace(a, x=1, y=2)), (1, 2, 3)) + + def test_namedtuple(self): + from collections import namedtuple + from typing import NamedTuple + PointFromCall = namedtuple('Point', 'x y', defaults=(0,)) + class PointFromInheritance(PointFromCall): + pass + class PointFromClass(NamedTuple): + x: int + y: int = 0 + for Point in (PointFromCall, PointFromInheritance, PointFromClass): + with self.subTest(Point=Point): + p = Point(11, 22) + self.assertIsInstance(p, Point) + self.assertEqual(copy.replace(p), (11, 22)) + self.assertIsInstance(copy.replace(p), Point) + self.assertEqual(copy.replace(p, x=1), (1, 22)) + self.assertEqual(copy.replace(p, y=2), (11, 2)) + self.assertEqual(copy.replace(p, x=1, y=2), (1, 2)) + with self.assertRaisesRegex(ValueError, 'unexpected field name'): + copy.replace(p, x=1, error=2) + + def test_dataclass(self): + from dataclasses import dataclass + @dataclass + class C: + x: int + y: int = 0 + + attrs = attrgetter('x', 'y') + c = C(11, 22) + self.assertEqual(attrs(copy.replace(c)), (11, 22)) + self.assertEqual(attrs(copy.replace(c, x=1)), (1, 22)) + self.assertEqual(attrs(copy.replace(c, y=2)), (11, 2)) + self.assertEqual(attrs(copy.replace(c, x=1, y=2)), (1, 2)) + with self.assertRaisesRegex(TypeError, 'unexpected keyword argument'): + copy.replace(c, x=1, error=2) + + def global_foo(x, y): return x+y + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_cppext.py b/Lib/test/test_cppext/__init__.py similarity index 81% rename from Lib/test/test_cppext.py rename to Lib/test/test_cppext/__init__.py index 7a143f44640137..4d9ee3cb2228ae 100644 --- a/Lib/test/test_cppext.py +++ b/Lib/test/test_cppext/__init__.py @@ -9,23 +9,27 @@ from test import support -MS_WINDOWS = (sys.platform == 'win32') - - -SETUP_TESTCPPEXT = support.findfile('setup_testcppext.py') +SOURCE = os.path.join(os.path.dirname(__file__), 'extension.cpp') +SETUP = os.path.join(os.path.dirname(__file__), 'setup.py') +# gh-110119: pip does not currently support 't' in the ABI flag use by +# --disable-gil builds. Once it does, we can remove this skip. +@unittest.skipIf(sysconfig.get_config_var('Py_NOGIL') == 1, + 'test does not work with --disable-gil') @support.requires_subprocess() class TestCPPExt(unittest.TestCase): + @support.requires_resource('cpu') def test_build_cpp11(self): self.check_build(False, '_testcpp11ext') + @support.requires_resource('cpu') def test_build_cpp03(self): self.check_build(True, '_testcpp03ext') # With MSVC, the linker fails with: cannot open file 'python311.lib' # https://github.com/python/cpython/pull/32175#issuecomment-1111175897 - @unittest.skipIf(MS_WINDOWS, 'test fails on Windows') + @unittest.skipIf(support.MS_WINDOWS, 'test fails on Windows') # Building and running an extension in clang sanitizing mode is not # straightforward @unittest.skipIf( @@ -41,7 +45,8 @@ def check_build(self, std_cpp03, extension_name): def _check_build(self, std_cpp03, extension_name, python_exe): pkg_dir = 'pkg' os.mkdir(pkg_dir) - shutil.copy(SETUP_TESTCPPEXT, os.path.join(pkg_dir, "setup.py")) + shutil.copy(SETUP, os.path.join(pkg_dir, os.path.basename(SETUP))) + shutil.copy(SOURCE, os.path.join(pkg_dir, os.path.basename(SOURCE))) def run_cmd(operation, cmd): env = os.environ.copy() diff --git a/Lib/test/_testcppext.cpp b/Lib/test/test_cppext/extension.cpp similarity index 99% rename from Lib/test/_testcppext.cpp rename to Lib/test/test_cppext/extension.cpp index 82b471312dd2b9..90669b10cb2c6d 100644 --- a/Lib/test/_testcppext.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -1,5 +1,7 @@ // gh-91321: Very basic C++ test extension to check that the Python C API is // compatible with C++ and does not emit C++ compiler warnings. +// +// The code is only built, not executed. // Always enable assertions #undef NDEBUG diff --git a/Lib/test/setup_testcppext.py b/Lib/test/test_cppext/setup.py similarity index 64% rename from Lib/test/setup_testcppext.py rename to Lib/test/test_cppext/setup.py index 22fe750085fd70..c7ba1efb4dd05a 100644 --- a/Lib/test/setup_testcppext.py +++ b/Lib/test/test_cppext/setup.py @@ -1,17 +1,16 @@ # gh-91321: Build a basic C++ test extension to check that the Python C API is # compatible with C++ and does not emit C++ compiler warnings. import os +import shlex import sys +import sysconfig from test import support from setuptools import setup, Extension -MS_WINDOWS = (sys.platform == 'win32') - - -SOURCE = support.findfile('_testcppext.cpp') -if not MS_WINDOWS: +SOURCE = 'extension.cpp' +if not support.MS_WINDOWS: # C++ compiler flags for GCC and clang CPPFLAGS = [ # gh-91321: The purpose of _testcppext extension is to check that building @@ -31,6 +30,17 @@ def main(): cppflags = [*CPPFLAGS, f'-std={std}'] + # gh-105776: When "gcc -std=11" is used as the C++ compiler, -std=c11 + # option emits a C++ compiler warning. Remove "-std11" option from the + # CC command. + cmd = (sysconfig.get_config_var('CC') or '') + if cmd is not None: + cmd = shlex.split(cmd) + cmd = [arg for arg in cmd if not arg.startswith('-std=')] + cmd = shlex.join(cmd) + # CC env var overrides sysconfig CC variable in setuptools + os.environ['CC'] = cmd + cpp_ext = Extension( name, sources=[SOURCE], diff --git a/Lib/test/test_crashers.py b/Lib/test/test_crashers.py deleted file mode 100644 index 31b712028f8a12..00000000000000 --- a/Lib/test/test_crashers.py +++ /dev/null @@ -1,37 +0,0 @@ -# Tests that the crashers in the Lib/test/crashers directory actually -# do crash the interpreter as expected -# -# If a crasher is fixed, it should be moved elsewhere in the test suite to -# ensure it continues to work correctly. - -import unittest -import glob -import os.path -import test.support -from test.support.script_helper import assert_python_failure - -CRASHER_DIR = os.path.join(os.path.dirname(__file__), "crashers") -CRASHER_FILES = os.path.join(glob.escape(CRASHER_DIR), "*.py") - -infinite_loops = ["infinite_loop_re.py", "nasty_eq_vs_dict.py"] - -class CrasherTest(unittest.TestCase): - - @unittest.skip("these tests are too fragile") - @test.support.cpython_only - def test_crashers_crash(self): - for fname in glob.glob(CRASHER_FILES): - if os.path.basename(fname) in infinite_loops: - continue - # Some "crashers" only trigger an exception rather than a - # segfault. Consider that an acceptable outcome. - if test.support.verbose: - print("Checking crasher:", fname) - assert_python_failure(fname) - - -def tearDownModule(): - test.support.reap_children() - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 6a4180e6d1b0a1..97b9bba24bcbca 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -10,7 +10,7 @@ import gc import pickle from test import support -from test.support import warnings_helper, import_helper, check_disallow_instantiation +from test.support import import_helper, check_disallow_instantiation from itertools import permutations from textwrap import dedent from collections import OrderedDict @@ -281,18 +281,6 @@ def test_writerows_errors(self): self.assertRaises(TypeError, writer.writerows, None) self.assertRaises(OSError, writer.writerows, BadIterable()) - @support.cpython_only - @support.requires_legacy_unicode_capi - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_writerows_legacy_strings(self): - import _testcapi - c = _testcapi.unicode_legacy_string('a') - with TemporaryFile("w+", encoding="utf-8", newline='') as fileobj: - writer = csv.writer(fileobj) - writer.writerows([[c]]) - fileobj.seek(0) - self.assertEqual(fileobj.read(), "a\r\n") - def _read_test(self, input, expect, **kwargs): reader = csv.reader(input, **kwargs) result = list(reader) diff --git a/Lib/test/test_ctypes/test_as_parameter.py b/Lib/test/test_ctypes/test_as_parameter.py index 39f70e864757d5..a1a8745e737fa2 100644 --- a/Lib/test/test_ctypes/test_as_parameter.py +++ b/Lib/test/test_ctypes/test_as_parameter.py @@ -192,7 +192,7 @@ class S8I(Structure): (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) def test_recursive_as_param(self): - class A(object): + class A: pass a = A() @@ -201,7 +201,7 @@ class A(object): c_int.from_param(a) -class AsParamWrapper(object): +class AsParamWrapper: def __init__(self, param): self._as_parameter_ = param @@ -209,7 +209,7 @@ class AsParamWrapperTestCase(BasicWrapTestCase): wrap = AsParamWrapper -class AsParamPropertyWrapper(object): +class AsParamPropertyWrapper: def __init__(self, param): self._param = param diff --git a/Lib/test/test_ctypes/test_callbacks.py b/Lib/test/test_ctypes/test_callbacks.py index 037677e37ab34a..6fe3e119672409 100644 --- a/Lib/test/test_ctypes/test_callbacks.py +++ b/Lib/test/test_ctypes/test_callbacks.py @@ -120,7 +120,7 @@ def test_unsupported_restype_2(self): def test_issue_7959(self): proto = self.functype.__func__(None) - class X(object): + class X: def func(self): pass def __init__(self): self.v = proto(self.func) diff --git a/Lib/test/test_ctypes/test_functions.py b/Lib/test/test_ctypes/test_functions.py index 9cf680f16620ac..08eecbc9ea4442 100644 --- a/Lib/test/test_ctypes/test_functions.py +++ b/Lib/test/test_ctypes/test_functions.py @@ -4,8 +4,8 @@ import unittest from ctypes import (CDLL, Structure, Array, CFUNCTYPE, byref, POINTER, pointer, ArgumentError, - c_char, c_wchar, c_byte, c_char_p, - c_short, c_int, c_long, c_longlong, + c_char, c_wchar, c_byte, c_char_p, c_wchar_p, + c_short, c_int, c_long, c_longlong, c_void_p, c_float, c_double, c_longdouble) from _ctypes import _Pointer, _SimpleCData @@ -92,6 +92,54 @@ def test_wchar_parm(self): "argument 2: TypeError: one character unicode string " "expected") + def test_c_char_p_parm(self): + """Test the error message when converting an incompatible type to c_char_p.""" + proto = CFUNCTYPE(c_int, c_char_p) + def callback(*args): + return 0 + + callback = proto(callback) + self.assertEqual(callback(b"abc"), 0) + + with self.assertRaises(ArgumentError) as cm: + callback(10) + + self.assertEqual(str(cm.exception), + "argument 1: TypeError: 'int' object cannot be " + "interpreted as ctypes.c_char_p") + + def test_c_wchar_p_parm(self): + """Test the error message when converting an incompatible type to c_wchar_p.""" + proto = CFUNCTYPE(c_int, c_wchar_p) + def callback(*args): + return 0 + + callback = proto(callback) + self.assertEqual(callback("abc"), 0) + + with self.assertRaises(ArgumentError) as cm: + callback(10) + + self.assertEqual(str(cm.exception), + "argument 1: TypeError: 'int' object cannot be " + "interpreted as ctypes.c_wchar_p") + + def test_c_void_p_parm(self): + """Test the error message when converting an incompatible type to c_void_p.""" + proto = CFUNCTYPE(c_int, c_void_p) + def callback(*args): + return 0 + + callback = proto(callback) + self.assertEqual(callback(5), 0) + + with self.assertRaises(ArgumentError) as cm: + callback(2.5) + + self.assertEqual(str(cm.exception), + "argument 1: TypeError: 'float' object cannot be " + "interpreted as ctypes.c_void_p") + def test_wchar_result(self): f = dll._testfunc_i_bhilfd f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double] diff --git a/Lib/test/test_ctypes/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py index fd318f9a18e533..29108a28ec16e1 100644 --- a/Lib/test/test_ctypes/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -86,7 +86,7 @@ def test_byref(self): def test_floats(self): # c_float and c_double can be created from # Python int and float - class FloatLike(object): + class FloatLike: def __float__(self): return 2.0 f = FloatLike() @@ -97,15 +97,15 @@ def __float__(self): self.assertEqual(t(f).value, 2.0) def test_integers(self): - class FloatLike(object): + class FloatLike: def __float__(self): return 2.0 f = FloatLike() - class IntLike(object): + class IntLike: def __int__(self): return 2 d = IntLike() - class IndexLike(object): + class IndexLike: def __index__(self): return 2 i = IndexLike() diff --git a/Lib/test/test_ctypes/test_objects.py b/Lib/test/test_ctypes/test_objects.py index 23c92b01a11107..fb01421b955951 100644 --- a/Lib/test/test_ctypes/test_objects.py +++ b/Lib/test/test_ctypes/test_objects.py @@ -55,14 +55,12 @@ import doctest import unittest -import test.test_ctypes.test_objects -class TestCase(unittest.TestCase): - def test(self): - failures, tests = doctest.testmod(test.test_ctypes.test_objects) - self.assertFalse(failures, 'doctests failed, see output above') +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests if __name__ == '__main__': - doctest.testmod(test.test_ctypes.test_objects) + unittest.main() diff --git a/Lib/test/test_ctypes/test_parameters.py b/Lib/test/test_ctypes/test_parameters.py index 40979212a627d8..d1eeee6b0306fe 100644 --- a/Lib/test/test_ctypes/test_parameters.py +++ b/Lib/test/test_ctypes/test_parameters.py @@ -157,7 +157,7 @@ def test_noctypes_argtype(self): # TypeError: has no from_param method self.assertRaises(TypeError, setattr, func, "argtypes", (object,)) - class Adapter(object): + class Adapter: def from_param(cls, obj): return None @@ -165,7 +165,7 @@ def from_param(cls, obj): self.assertEqual(func(None), None) self.assertEqual(func(object()), None) - class Adapter(object): + class Adapter: def from_param(cls, obj): return obj @@ -174,7 +174,7 @@ def from_param(cls, obj): self.assertRaises(ArgumentError, func, object()) self.assertEqual(func(c_void_p(42)), 42) - class Adapter(object): + class Adapter: def from_param(cls, obj): raise ValueError(obj) diff --git a/Lib/test/test_ctypes/test_values.py b/Lib/test/test_ctypes/test_values.py index 9f8b69409cb880..d0b4803dff8529 100644 --- a/Lib/test/test_ctypes/test_values.py +++ b/Lib/test/test_ctypes/test_values.py @@ -58,7 +58,6 @@ class struct_frozen(Structure): ("code", POINTER(c_ubyte)), ("size", c_int), ("is_package", c_int), - ("get_code", POINTER(c_ubyte)), # Function ptr ] FrozenTable = POINTER(struct_frozen) diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses/__init__.py similarity index 97% rename from Lib/test/test_dataclasses.py rename to Lib/test/test_dataclasses/__init__.py index 6669f1c57e2e78..272d427875ae40 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -134,7 +134,7 @@ class C: # Non-defaults following defaults. with self.assertRaisesRegex(TypeError, "non-default argument 'y' follows " - "default argument"): + "default argument 'x'"): @dataclass class C: x: int = 0 @@ -143,7 +143,7 @@ class C: # A derived class adds a non-default field after a default one. with self.assertRaisesRegex(TypeError, "non-default argument 'y' follows " - "default argument"): + "default argument 'x'"): @dataclass class B: x: int = 0 @@ -156,7 +156,7 @@ class C(B): # a field which didn't use to have a default. with self.assertRaisesRegex(TypeError, "non-default argument 'y' follows " - "default argument"): + "default argument 'x'"): @dataclass class B: x: int @@ -2863,6 +2863,101 @@ class C: class D(C): j: int + def test_inherit_frozen_mutliple_inheritance(self): + @dataclass + class NotFrozen: + pass + + @dataclass(frozen=True) + class Frozen: + pass + + class NotDataclass: + pass + + for bases in ( + (NotFrozen, Frozen), + (Frozen, NotFrozen), + (Frozen, NotDataclass), + (NotDataclass, Frozen), + ): + with self.subTest(bases=bases): + with self.assertRaisesRegex( + TypeError, + 'cannot inherit non-frozen dataclass from a frozen one', + ): + @dataclass + class NotFrozenChild(*bases): + pass + + for bases in ( + (NotFrozen, Frozen), + (Frozen, NotFrozen), + (NotFrozen, NotDataclass), + (NotDataclass, NotFrozen), + ): + with self.subTest(bases=bases): + with self.assertRaisesRegex( + TypeError, + 'cannot inherit frozen dataclass from a non-frozen one', + ): + @dataclass(frozen=True) + class FrozenChild(*bases): + pass + + def test_inherit_frozen_mutliple_inheritance_regular_mixins(self): + @dataclass(frozen=True) + class Frozen: + pass + + class NotDataclass: + pass + + class C1(Frozen, NotDataclass): + pass + self.assertEqual(C1.__mro__, (C1, Frozen, NotDataclass, object)) + + class C2(NotDataclass, Frozen): + pass + self.assertEqual(C2.__mro__, (C2, NotDataclass, Frozen, object)) + + @dataclass(frozen=True) + class C3(Frozen, NotDataclass): + pass + self.assertEqual(C3.__mro__, (C3, Frozen, NotDataclass, object)) + + @dataclass(frozen=True) + class C4(NotDataclass, Frozen): + pass + self.assertEqual(C4.__mro__, (C4, NotDataclass, Frozen, object)) + + def test_multiple_frozen_dataclasses_inheritance(self): + @dataclass(frozen=True) + class FrozenA: + pass + + @dataclass(frozen=True) + class FrozenB: + pass + + class C1(FrozenA, FrozenB): + pass + self.assertEqual(C1.__mro__, (C1, FrozenA, FrozenB, object)) + + class C2(FrozenB, FrozenA): + pass + self.assertEqual(C2.__mro__, (C2, FrozenB, FrozenA, object)) + + @dataclass(frozen=True) + class C3(FrozenA, FrozenB): + pass + self.assertEqual(C3.__mro__, (C3, FrozenA, FrozenB, object)) + + @dataclass(frozen=True) + class C4(FrozenB, FrozenA): + pass + self.assertEqual(C4.__mro__, (C4, FrozenB, FrozenA, object)) + def test_inherit_nonfrozen_from_empty(self): @dataclass class C: @@ -3684,10 +3779,10 @@ class C: self.assertEqual(C(10).x, 10) def test_classvar_module_level_import(self): - from test import dataclass_module_1 - from test import dataclass_module_1_str - from test import dataclass_module_2 - from test import dataclass_module_2_str + from test.test_dataclasses import dataclass_module_1 + from test.test_dataclasses import dataclass_module_1_str + from test.test_dataclasses import dataclass_module_2 + from test.test_dataclasses import dataclass_module_2_str for m in (dataclass_module_1, dataclass_module_1_str, dataclass_module_2, dataclass_module_2_str, @@ -3725,7 +3820,7 @@ def test_classvar_module_level_import(self): self.assertNotIn('not_iv4', c.__dict__) def test_text_annotations(self): - from test import dataclass_textanno + from test.test_dataclasses import dataclass_textanno self.assertEqual( get_type_hints(dataclass_textanno.Bar), @@ -3965,9 +4060,9 @@ class C: self.assertEqual((c1.x, c1.y, c1.z, c1.t), (3, 2, 10, 100)) - with self.assertRaisesRegex(ValueError, 'init=False'): + with self.assertRaisesRegex(TypeError, 'init=False'): replace(c, x=3, z=20, t=50) - with self.assertRaisesRegex(ValueError, 'init=False'): + with self.assertRaisesRegex(TypeError, 'init=False'): replace(c, z=20) replace(c, x=3, z=20, t=50) @@ -4020,10 +4115,10 @@ class C: self.assertEqual((c1.x, c1.y), (5, 10)) # Trying to replace y is an error. - with self.assertRaisesRegex(ValueError, 'init=False'): + with self.assertRaisesRegex(TypeError, 'init=False'): replace(c, x=2, y=30) - with self.assertRaisesRegex(ValueError, 'init=False'): + with self.assertRaisesRegex(TypeError, 'init=False'): replace(c, y=30) def test_classvar(self): @@ -4056,8 +4151,8 @@ def __post_init__(self, y): c = C(1, 10) self.assertEqual(c.x, 10) - with self.assertRaisesRegex(ValueError, r"InitVar 'y' must be " - "specified with replace()"): + with self.assertRaisesRegex(TypeError, r"InitVar 'y' must be " + r"specified with replace\(\)"): replace(c, x=3) c = replace(c, x=3, y=5) self.assertEqual(c.x, 15) @@ -4521,7 +4616,7 @@ class A: # Make sure we still check for non-kwarg non-defaults not following # defaults. - err_regex = "non-default argument 'z' follows default argument" + err_regex = "non-default argument 'z' follows default argument 'a'" with self.assertRaisesRegex(TypeError, err_regex): @dataclass class A: diff --git a/Lib/test/dataclass_module_1.py b/Lib/test/test_dataclasses/dataclass_module_1.py similarity index 100% rename from Lib/test/dataclass_module_1.py rename to Lib/test/test_dataclasses/dataclass_module_1.py diff --git a/Lib/test/dataclass_module_1_str.py b/Lib/test/test_dataclasses/dataclass_module_1_str.py similarity index 100% rename from Lib/test/dataclass_module_1_str.py rename to Lib/test/test_dataclasses/dataclass_module_1_str.py diff --git a/Lib/test/dataclass_module_2.py b/Lib/test/test_dataclasses/dataclass_module_2.py similarity index 100% rename from Lib/test/dataclass_module_2.py rename to Lib/test/test_dataclasses/dataclass_module_2.py diff --git a/Lib/test/dataclass_module_2_str.py b/Lib/test/test_dataclasses/dataclass_module_2_str.py similarity index 100% rename from Lib/test/dataclass_module_2_str.py rename to Lib/test/test_dataclasses/dataclass_module_2_str.py diff --git a/Lib/test/dataclass_textanno.py b/Lib/test/test_dataclasses/dataclass_textanno.py similarity index 100% rename from Lib/test/dataclass_textanno.py rename to Lib/test/test_dataclasses/dataclass_textanno.py diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py index f21eebc6530c76..e3924d8ec8b5c1 100644 --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -155,6 +155,21 @@ def test_keys(self): self.assertNotIn(b'xxx', d) self.assertRaises(KeyError, lambda: d[b'xxx']) + def test_clear(self): + with dbm.open(_fname, 'c') as d: + self.assertEqual(d.keys(), []) + a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')] + for k, v in a: + d[k] = v + for k, _ in a: + self.assertIn(k, d) + self.assertEqual(len(d), len(a)) + + d.clear() + self.assertEqual(len(d), 0) + for k, _ in a: + self.assertNotIn(k, d) + def setUp(self): self.addCleanup(setattr, dbm, '_defaultmod', dbm._defaultmod) dbm._defaultmod = self.module diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 73602cab5180fc..e20addf1f04f1b 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -192,6 +192,20 @@ def test_open_with_bytes_path(self): def test_open_with_pathlib_bytes_path(self): gdbm.open(FakePath(os.fsencode(filename)), "c").close() + def test_clear(self): + kvs = [('foo', 'bar'), ('1234', '5678')] + with gdbm.open(filename, 'c') as db: + for k, v in kvs: + db[k] = v + self.assertIn(k, db) + self.assertEqual(len(db), len(kvs)) + + db.clear() + for k, v in kvs: + self.assertNotIn(k, db) + self.assertEqual(len(db), 0) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py index 8f37e3cc624e2e..e0f31c9a9a337d 100644 --- a/Lib/test/test_dbm_ndbm.py +++ b/Lib/test/test_dbm_ndbm.py @@ -147,6 +147,19 @@ def test_bool_on_closed_db_raises(self): db['a'] = 'b' self.assertRaises(dbm.ndbm.error, bool, db) + def test_clear(self): + kvs = [('foo', 'bar'), ('1234', '5678')] + with dbm.ndbm.open(self.filename, 'c') as db: + for k, v in kvs: + db[k] = v + self.assertIn(k, db) + self.assertEqual(len(db), len(kvs)) + + db.clear() + for k, v in kvs: + self.assertNotIn(k, db) + self.assertEqual(len(db), 0) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index db67f37608f1f2..7a5fe62b467372 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -34,14 +34,13 @@ import locale from test.support import (is_resource_enabled, requires_IEEE_754, requires_docstrings, - requires_legacy_unicode_capi, check_sanitizer, + check_sanitizer, check_disallow_instantiation) from test.support import (TestFailed, run_with_locale, cpython_only, darwin_malloc_err_warning, is_emscripten) from test.support.import_helper import import_fresh_module from test.support import threading_helper -from test.support import warnings_helper import random import inspect import threading @@ -587,18 +586,6 @@ def test_explicit_from_string(self): # underscores don't prevent errors self.assertRaises(InvalidOperation, Decimal, "1_2_\u00003") - @cpython_only - @requires_legacy_unicode_capi - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_from_legacy_strings(self): - import _testcapi - Decimal = self.decimal.Decimal - context = self.decimal.Context() - - s = _testcapi.unicode_legacy_string('9.999999') - self.assertEqual(str(Decimal(s)), '9.999999') - self.assertEqual(str(context.create_decimal(s)), '9.999999') - def test_explicit_from_tuples(self): Decimal = self.decimal.Decimal @@ -1235,6 +1222,23 @@ def get_fmt(x, override=None, fmt='n'): self.assertEqual(get_fmt(Decimal('-1.5'), dotsep_wide, '020n'), '-0\u00b4000\u00b4000\u00b4000\u00b4001\u00bf5') + def test_deprecated_N_format(self): + Decimal = self.decimal.Decimal + h = Decimal('6.62607015e-34') + if self.decimal == C: + with self.assertWarns(DeprecationWarning) as cm: + r = format(h, 'N') + self.assertEqual(cm.filename, __file__) + self.assertEqual(r, format(h, 'n').upper()) + with self.assertWarns(DeprecationWarning) as cm: + r = format(h, '010.3N') + self.assertEqual(cm.filename, __file__) + self.assertEqual(r, format(h, '010.3n').upper()) + else: + self.assertRaises(ValueError, format, h, 'N') + self.assertRaises(ValueError, format, h, '010.3N') + + @run_with_locale('LC_ALL', 'ps_AF') def test_wide_char_separator_decimal_point(self): # locale with wide char separator and decimal point @@ -2919,23 +2923,6 @@ def test_none_args(self): assert_signals(self, c, 'traps', [InvalidOperation, DivisionByZero, Overflow]) - @cpython_only - @requires_legacy_unicode_capi - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_from_legacy_strings(self): - import _testcapi - c = self.decimal.Context() - - for rnd in RoundingModes: - c.rounding = _testcapi.unicode_legacy_string(rnd) - self.assertEqual(c.rounding, rnd) - - s = _testcapi.unicode_legacy_string('') - self.assertRaises(TypeError, setattr, c, 'rounding', s) - - s = _testcapi.unicode_legacy_string('ROUND_\x00UP') - self.assertRaises(TypeError, setattr, c, 'rounding', s) - def test_pickle(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -5701,6 +5688,36 @@ def test_c_disallow_instantiation(self): ContextManager = type(C.localcontext()) check_disallow_instantiation(self, ContextManager) + def test_c_signaldict_segfault(self): + # See gh-106263 for details. + SignalDict = type(C.Context().flags) + sd = SignalDict() + err_msg = "invalid signal dict" + + with self.assertRaisesRegex(ValueError, err_msg): + len(sd) + + with self.assertRaisesRegex(ValueError, err_msg): + iter(sd) + + with self.assertRaisesRegex(ValueError, err_msg): + repr(sd) + + with self.assertRaisesRegex(ValueError, err_msg): + sd[C.InvalidOperation] = True + + with self.assertRaisesRegex(ValueError, err_msg): + sd[C.InvalidOperation] + + with self.assertRaisesRegex(ValueError, err_msg): + sd == C.Context().flags + + with self.assertRaisesRegex(ValueError, err_msg): + C.Context().flags == sd + + with self.assertRaisesRegex(ValueError, err_msg): + sd.copy() + @requires_docstrings @requires_cdecimal class SignatureTest(unittest.TestCase): diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index ad3eefba365856..4a3db80ca43c27 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -989,8 +989,8 @@ class EditableScrollablePane(ScrollablePane,EditablePane): pass def test_mro_disagreement(self): # Testing error messages for MRO disagreement... - mro_err_msg = """Cannot create a consistent method resolution -order (MRO) for bases """ + mro_err_msg = ("Cannot create a consistent method resolution " + "order (MRO) for bases ") def raises(exc, expected, callable, *args): try: @@ -1989,7 +1989,7 @@ def __getattr__(self, attr): ns = {} exec(code, ns) number_attrs = ns["number_attrs"] - # Warm up the the function for quickening (PEP 659) + # Warm up the function for quickening (PEP 659) for _ in range(30): self.assertEqual(number_attrs(Numbers()), list(range(280))) @@ -4457,6 +4457,7 @@ class Oops(object): o.whatever = Provoker(o) del o + @support.requires_resource('cpu') def test_wrapper_segfault(self): # SF 927248: deeply nested wrappers could cause stack overflow f = lambda:None @@ -4756,24 +4757,24 @@ class Thing: thing = Thing() for i in range(20): with self.assertRaises(TypeError): - # PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS + # CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS list.sort(thing) for i in range(20): with self.assertRaises(TypeError): - # PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS + # CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS str.split(thing) for i in range(20): with self.assertRaises(TypeError): - # PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS + # CALL_METHOD_DESCRIPTOR_NOARGS str.upper(thing) for i in range(20): with self.assertRaises(TypeError): - # PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST + # CALL_METHOD_DESCRIPTOR_FAST str.strip(thing) from collections import deque for i in range(20): with self.assertRaises(TypeError): - # PRECALL_NO_KW_METHOD_DESCRIPTOR_O + # CALL_METHOD_DESCRIPTOR_O deque.append(thing, thing) def test_repr_as_str(self): diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py index 7796031ed0602f..13e3ea41bdb76c 100644 --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -139,7 +139,7 @@ def merge(self, other): >>> a.x1 = 1 Traceback (most recent call last): File "", line 1, in ? - AttributeError: 'defaultdict2' object has no attribute 'x1' + AttributeError: 'defaultdict2' object has no attribute 'x1' and no __dict__ for setting new attributes >>> """ diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 79638340059f65..620d0ca4f4c2da 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -8,7 +8,7 @@ import unittest import weakref from test import support -from test.support import import_helper +from test.support import import_helper, Py_C_RECURSION_LIMIT class DictTest(unittest.TestCase): @@ -596,7 +596,7 @@ def __repr__(self): def test_repr_deep(self): d = {} - for i in range(sys.getrecursionlimit() + 100): + for i in range(Py_C_RECURSION_LIMIT + 1): d = {1: d} self.assertRaises(RecursionError, repr, d) @@ -1582,8 +1582,8 @@ class CAPITest(unittest.TestCase): # Test _PyDict_GetItem_KnownHash() @support.cpython_only def test_getitem_knownhash(self): - _testcapi = import_helper.import_module('_testcapi') - dict_getitem_knownhash = _testcapi.dict_getitem_knownhash + _testinternalcapi = import_helper.import_module('_testinternalcapi') + dict_getitem_knownhash = _testinternalcapi.dict_getitem_knownhash d = {'x': 1, 'y': 2, 'z': 3} self.assertEqual(dict_getitem_knownhash(d, 'x', hash('x')), 1) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index 924f4a6829e19c..cad568b6ac4c2d 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -1,8 +1,8 @@ import collections.abc import copy import pickle -import sys import unittest +from test.support import Py_C_RECURSION_LIMIT class DictSetTest(unittest.TestCase): @@ -279,7 +279,7 @@ def test_recursive_repr(self): def test_deeply_nested_repr(self): d = {} - for i in range(sys.getrecursionlimit() + 100): + for i in range(Py_C_RECURSION_LIMIT//2 + 100): d = {42: d.values()} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 8597b8f14ac058..8ab0e1ecbc4a7f 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -102,7 +102,7 @@ def _f(a): dis_f = """\ %3d RESUME 0 -%3d LOAD_GLOBAL 1 (NULL + print) +%3d LOAD_GLOBAL 1 (print + NULL) LOAD_FAST 0 (a) CALL 1 POP_TOP @@ -131,7 +131,7 @@ def bug708901(): dis_bug708901 = """\ %3d RESUME 0 -%3d LOAD_GLOBAL 1 (NULL + range) +%3d LOAD_GLOBAL 1 (range + NULL) LOAD_CONST 1 (1) %3d LOAD_CONST 2 (10) @@ -196,11 +196,11 @@ def bug42562(): # Extended arg followed by NOP code_bug_45757 = bytes([ - 0x90, 0x01, # EXTENDED_ARG 0x01 - 0x09, 0xFF, # NOP 0xFF - 0x90, 0x01, # EXTENDED_ARG 0x01 - 0x64, 0x29, # LOAD_CONST 0x29 - 0x53, 0x00, # RETURN_VALUE 0x00 + opcode.opmap['EXTENDED_ARG'], 0x01, # EXTENDED_ARG 0x01 + opcode.opmap['NOP'], 0xFF, # NOP 0xFF + opcode.opmap['EXTENDED_ARG'], 0x01, # EXTENDED_ARG 0x01 + opcode.opmap['LOAD_CONST'], 0x29, # LOAD_CONST 0x29 + opcode.opmap['RETURN_VALUE'], 0x00, # RETURN_VALUE 0x00 ]) dis_bug_45757 = """\ @@ -236,12 +236,12 @@ def wrap_func_w_kwargs(): dis_kw_names = """\ %3d RESUME 0 -%3d LOAD_GLOBAL 1 (NULL + func_w_kwargs) +%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) LOAD_CONST 1 (1) LOAD_CONST 2 (2) LOAD_CONST 3 (5) - KW_NAMES 4 (('c',)) - CALL 3 + LOAD_CONST 4 (('c',)) + CALL_KW 3 POP_TOP RETURN_CONST 0 (None) """ % (wrap_func_w_kwargs.__code__.co_firstlineno, @@ -345,8 +345,8 @@ def wrap_func_w_kwargs(): LOAD_CONST 1 ('x') STORE_SUBSCR - 3 PUSH_NULL - LOAD_NAME 3 (fun) + 3 LOAD_NAME 3 (fun) + PUSH_NULL LOAD_CONST 0 (1) CALL 1 LOAD_NAME 2 (__annotations__) @@ -355,8 +355,8 @@ def wrap_func_w_kwargs(): 4 LOAD_CONST 0 (1) LOAD_NAME 4 (lst) - PUSH_NULL LOAD_NAME 3 (fun) + PUSH_NULL LOAD_CONST 3 (0) CALL 1 STORE_SUBSCR @@ -388,43 +388,46 @@ def wrap_func_w_kwargs(): """ dis_traceback = """\ -%3d RESUME 0 +%4d RESUME 0 -%3d NOP +%4d NOP -%3d LOAD_CONST 1 (1) - LOAD_CONST 2 (0) - --> BINARY_OP 11 (/) - POP_TOP +%4d LOAD_CONST 1 (1) + LOAD_CONST 2 (0) + --> BINARY_OP 11 (/) + POP_TOP -%3d LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE - >> PUSH_EXC_INFO - -%3d LOAD_GLOBAL 0 (Exception) - CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 23 (to 80) - STORE_FAST 0 (e) - -%3d LOAD_FAST 0 (e) - LOAD_ATTR 2 (__traceback__) - STORE_FAST 1 (tb) - POP_EXCEPT - LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - -%3d LOAD_FAST 1 (tb) - RETURN_VALUE - >> LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - RERAISE 1 - -%3d >> RERAISE 0 - >> COPY 3 - POP_EXCEPT - RERAISE 1 +%4d LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE + +None >> PUSH_EXC_INFO + +%4d LOAD_GLOBAL 0 (Exception) + CHECK_EXC_MATCH + POP_JUMP_IF_FALSE 23 (to 82) + STORE_FAST 0 (e) + +%4d LOAD_FAST 0 (e) + LOAD_ATTR 2 (__traceback__) + STORE_FAST 1 (tb) + POP_EXCEPT + LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + +%4d LOAD_FAST 1 (tb) + RETURN_VALUE + +None >> LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + RERAISE 1 + +%4d >> RERAISE 0 + +None >> COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 4 rows """ % (TRACEBACK_CODE.co_firstlineno, @@ -467,41 +470,42 @@ def _with(c): y = 2 dis_with = """\ -%3d RESUME 0 +%4d RESUME 0 -%3d LOAD_FAST 0 (c) - BEFORE_WITH - POP_TOP +%4d LOAD_FAST 0 (c) + BEFORE_WITH + POP_TOP -%3d LOAD_CONST 1 (1) - STORE_FAST 1 (x) +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) -%3d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - POP_TOP +%4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP -%3d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) -%3d >> PUSH_EXC_INFO - WITH_EXCEPT_START - TO_BOOL - POP_JUMP_IF_TRUE 1 (to 50) - RERAISE 2 - >> POP_TOP - POP_EXCEPT - POP_TOP - POP_TOP +%4d >> PUSH_EXC_INFO + WITH_EXCEPT_START + TO_BOOL + POP_JUMP_IF_TRUE 1 (to 52) + RERAISE 2 + >> POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP -%3d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - >> COPY 3 - POP_EXCEPT - RERAISE 1 +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +None >> COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 2 rows """ % (_with.__code__.co_firstlineno, @@ -519,71 +523,76 @@ async def _asyncwith(c): y = 2 dis_asyncwith = """\ -%3d RETURN_GENERATOR - POP_TOP - RESUME 0 - -%3d LOAD_FAST 0 (c) - BEFORE_ASYNC_WITH - GET_AWAITABLE 1 - LOAD_CONST 0 (None) - >> SEND 3 (to 24) - YIELD_VALUE 2 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to 14) - >> END_SEND - POP_TOP +%4d RETURN_GENERATOR + POP_TOP + RESUME 0 + +%4d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) + >> SEND 3 (to 24) + YIELD_VALUE 2 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to 14) + >> END_SEND + POP_TOP -%3d LOAD_CONST 1 (1) - STORE_FAST 1 (x) - -%3d LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - CALL 2 - GET_AWAITABLE 2 - LOAD_CONST 0 (None) - >> SEND 3 (to 60) - YIELD_VALUE 2 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to 50) - >> END_SEND - POP_TOP +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%4d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + >> SEND 3 (to 60) + YIELD_VALUE 2 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to 50) + >> END_SEND + POP_TOP -%3d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) -%3d >> CLEANUP_THROW - JUMP_BACKWARD 26 (to 24) - >> CLEANUP_THROW - JUMP_BACKWARD 11 (to 60) - >> PUSH_EXC_INFO - WITH_EXCEPT_START - GET_AWAITABLE 2 - LOAD_CONST 0 (None) - >> SEND 4 (to 102) - YIELD_VALUE 3 - RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to 90) - >> CLEANUP_THROW - >> END_SEND - TO_BOOL - POP_JUMP_IF_TRUE 1 (to 116) - RERAISE 2 - >> POP_TOP - POP_EXCEPT - POP_TOP - POP_TOP +%4d >> CLEANUP_THROW + +None JUMP_BACKWARD 26 (to 24) + +%4d >> CLEANUP_THROW + +None JUMP_BACKWARD 11 (to 60) + +%4d >> PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + >> SEND 4 (to 102) + YIELD_VALUE 3 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to 90) + >> CLEANUP_THROW + >> END_SEND + TO_BOOL + POP_JUMP_IF_TRUE 1 (to 118) + RERAISE 2 + >> POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP -%3d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - >> COPY 3 - POP_EXCEPT - RERAISE 1 - >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +None >> COPY 3 + POP_EXCEPT + RERAISE 1 + >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: 12 rows """ % (_asyncwith.__code__.co_firstlineno, @@ -592,6 +601,8 @@ async def _asyncwith(c): _asyncwith.__code__.co_firstlineno + 1, _asyncwith.__code__.co_firstlineno + 3, _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 1, _asyncwith.__code__.co_firstlineno + 3, ) @@ -609,61 +620,69 @@ def _tryfinallyconst(b): b() dis_tryfinally = """\ -%3d RESUME 0 +%4d RESUME 0 -%3d NOP +%4d NOP -%3d LOAD_FAST 0 (a) +%4d LOAD_FAST 0 (a) -%3d PUSH_NULL - LOAD_FAST 1 (b) - CALL 0 - POP_TOP - RETURN_VALUE - >> PUSH_EXC_INFO - PUSH_NULL - LOAD_FAST 1 (b) - CALL 0 - POP_TOP - RERAISE 0 - >> COPY 3 - POP_EXCEPT - RERAISE 1 +%4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_VALUE + +None >> PUSH_EXC_INFO + +%4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 + +None >> COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 2 rows """ % (_tryfinally.__code__.co_firstlineno, _tryfinally.__code__.co_firstlineno + 1, _tryfinally.__code__.co_firstlineno + 2, _tryfinally.__code__.co_firstlineno + 4, + _tryfinally.__code__.co_firstlineno + 4, ) dis_tryfinallyconst = """\ -%3d RESUME 0 +%4d RESUME 0 -%3d NOP +%4d NOP -%3d NOP +%4d NOP -%3d PUSH_NULL - LOAD_FAST 0 (b) - CALL 0 - POP_TOP - RETURN_CONST 1 (1) - PUSH_EXC_INFO - PUSH_NULL - LOAD_FAST 0 (b) - CALL 0 - POP_TOP - RERAISE 0 - >> COPY 3 - POP_EXCEPT - RERAISE 1 +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_CONST 1 (1) + +None PUSH_EXC_INFO + +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 + +None >> COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: 1 row """ % (_tryfinallyconst.__code__.co_firstlineno, _tryfinallyconst.__code__.co_firstlineno + 1, _tryfinallyconst.__code__.co_firstlineno + 2, _tryfinallyconst.__code__.co_firstlineno + 4, + _tryfinallyconst.__code__.co_firstlineno + 4, ) def _g(x): @@ -683,19 +702,19 @@ def foo(x): return foo dis_nested_0 = """\ - MAKE_CELL 0 (y) +None MAKE_CELL 0 (y) -%3d RESUME 0 +%4d RESUME 0 -%3d LOAD_FAST 0 (y) - BUILD_TUPLE 1 - LOAD_CONST 1 () - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - STORE_FAST 1 (foo) +%4d LOAD_FAST 0 (y) + BUILD_TUPLE 1 + LOAD_CONST 1 () + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + STORE_FAST 1 (foo) -%3d LOAD_FAST 1 (foo) - RETURN_VALUE +%4d LOAD_FAST 1 (foo) + RETURN_VALUE """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -705,22 +724,22 @@ def foo(x): dis_nested_1 = """%s Disassembly of : - COPY_FREE_VARS 1 - MAKE_CELL 0 (x) - -%3d RESUME 0 - -%3d LOAD_GLOBAL 1 (NULL + list) - LOAD_FAST 0 (x) - BUILD_TUPLE 1 - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - SET_FUNCTION_ATTRIBUTE 8 (closure) - LOAD_DEREF 1 (y) - GET_ITER - CALL 0 - CALL 1 - RETURN_VALUE +None COPY_FREE_VARS 1 + MAKE_CELL 0 (x) + +%4d RESUME 0 + +%4d LOAD_GLOBAL 1 (list + NULL) + LOAD_FAST 0 (x) + BUILD_TUPLE 1 + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + SET_FUNCTION_ATTRIBUTE 8 (closure) + LOAD_DEREF 1 (y) + GET_ITER + CALL 0 + CALL 1 + RETURN_VALUE """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, @@ -732,25 +751,26 @@ def foo(x): dis_nested_2 = """%s Disassembly of at 0x..., file "%s", line %d>: - COPY_FREE_VARS 1 +None COPY_FREE_VARS 1 -%3d RETURN_GENERATOR - POP_TOP - RESUME 0 - LOAD_FAST 0 (.0) - >> FOR_ITER 10 (to 34) - STORE_FAST 1 (z) - LOAD_DEREF 2 (x) - LOAD_FAST 1 (z) - BINARY_OP 0 (+) - YIELD_VALUE 1 - RESUME 1 - POP_TOP - JUMP_BACKWARD 12 (to 10) - >> END_FOR - RETURN_CONST 0 (None) - >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) - RERAISE 1 +%4d RETURN_GENERATOR + POP_TOP + RESUME 0 + LOAD_FAST 0 (.0) + >> FOR_ITER 10 (to 34) + STORE_FAST 1 (z) + LOAD_DEREF 2 (x) + LOAD_FAST 1 (z) + BINARY_OP 0 (+) + YIELD_VALUE 1 + RESUME 1 + POP_TOP + JUMP_BACKWARD 12 (to 10) + >> END_FOR + RETURN_CONST 0 (None) + +None >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: 1 row """ % (dis_nested_1, @@ -764,7 +784,7 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ -%3d 0 RESUME 0 +%3d 0 RESUME_CHECK 0 %3d 2 LOAD_FAST_LOAD_FAST 1 (x, y) 4 STORE_FAST_STORE_FAST 50 (b, a) @@ -781,7 +801,7 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ -%3d RESUME 0 +%3d RESUME_CHECK 0 %3d BUILD_LIST 0 LOAD_CONST 1 ((1, 2, 3)) @@ -792,7 +812,7 @@ def loop_test(): >> FOR_ITER_LIST 14 (to 48) STORE_FAST 0 (i) -%3d LOAD_GLOBAL_MODULE 1 (NULL + load_test) +%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) LOAD_FAST 0 (i) CALL_PY_WITH_DEFAULTS 1 POP_TOP @@ -931,7 +951,7 @@ def do_disassembly_test(self, func, expected, with_offsets=False): with_offsets) def test_opmap(self): - self.assertEqual(dis.opmap["NOP"], 9) + self.assertEqual(dis.opmap["CACHE"], 0) self.assertIn(dis.opmap["LOAD_CONST"], dis.hasconst) self.assertIn(dis.opmap["STORE_NAME"], dis.hasname) @@ -940,7 +960,6 @@ def test_opname(self): def test_boundaries(self): self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG) - self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT) def test_widths(self): long_opcodes = set(['JUMP_BACKWARD_NO_INTERRUPT', @@ -980,7 +999,7 @@ def test_bug_46724(self): self.do_disassembly_test(bug46724, dis_bug46724) def test_kw_names(self): - # Test that value is displayed for KW_NAMES + # Test that value is displayed for keyword argument names: self.do_disassembly_test(wrap_func_w_kwargs, dis_kw_names) def test_intrinsic_1(self): @@ -1174,7 +1193,7 @@ def test_super_instructions(self): @requires_specialization def test_binary_specialize(self): binary_op_quicken = """\ - 0 0 RESUME 0 + 0 0 RESUME_CHECK 0 1 2 LOAD_NAME 0 (a) 4 LOAD_NAME 1 (b) @@ -1192,7 +1211,7 @@ def test_binary_specialize(self): self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)", True) binary_subscr_quicken = """\ - 0 0 RESUME 0 + 0 0 RESUME_CHECK 0 1 2 LOAD_NAME 0 (a) 4 LOAD_CONST 0 (0) @@ -1213,7 +1232,7 @@ def test_binary_specialize(self): @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 0 RESUME 0 + 0 0 RESUME_CHECK 0 1 2 LOAD_CONST 0 ('a') 4 LOAD_ATTR_SLOT 0 (__class__) @@ -1228,12 +1247,12 @@ def test_load_attr_specialize(self): @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 RESUME 0 + 0 RESUME_CHECK 0 - 1 PUSH_NULL - LOAD_NAME 0 (str) + 1 LOAD_NAME 0 (str) + PUSH_NULL LOAD_CONST 0 (1) - CALL_NO_KW_STR_1 1 + CALL_STR_1 1 RETURN_VALUE """ co = compile("str(1)", "", "eval") @@ -1244,10 +1263,15 @@ def test_call_specialize(self): @cpython_only @requires_specialization def test_loop_quicken(self): + import _testinternalcapi # Loop can trigger a quicken where the loop is located self.code_quicken(loop_test, 1) got = self.get_disassembly(loop_test, adaptive=True) - self.do_disassembly_compare(got, dis_loop_test_quickened_code) + expected = dis_loop_test_quickened_code + if _testinternalcapi.get_optimizer(): + # We *may* see ENTER_EXECUTOR in the disassembly + got = got.replace("ENTER_EXECUTOR", "JUMP_BACKWARD ") + self.do_disassembly_compare(got, expected) @cpython_only def test_extended_arg_quick(self): @@ -1608,202 +1632,202 @@ def _prepare_test_cases(): result = result.replace(repr(code_object_inner), "code_object_inner") print(result) -# _prepare_test_cases() +# from test.test_dis import _prepare_test_cases; _prepare_test_cases() Instruction = dis.Instruction expected_opinfo_outer = [ - Instruction(opname='MAKE_CELL', opcode=135, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_CELL', opcode=135, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=1, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=24, start_offset=24, starts_line=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=1, argrepr='1', offset=40, start_offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=52, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=1, argrepr='1', offset=40, start_offset=40, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='BUILD_LIST', opcode=47, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='BUILD_MAP', opcode=48, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, is_jump_target=False, positions=None), ] expected_opinfo_f = [ - Instruction(opname='COPY_FREE_VARS', opcode=149, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_CELL', opcode=135, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_CELL', opcode=135, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=30, start_offset=30, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY_FREE_VARS', opcode=62, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=52, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=106, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, is_jump_target=False, positions=None), ] expected_opinfo_inner = [ - Instruction(opname='COPY_FREE_VARS', opcode=149, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=4, start_offset=4, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=168, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY_FREE_VARS', opcode=62, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=84, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=88, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, is_jump_target=False, positions=None), ] expected_opinfo_jumpy = [ - Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=1, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='range', argrepr='NULL + range', offset=2, start_offset=2, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=93, arg=28, argval=84, argrepr='to 84', offset=24, start_offset=24, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=30, start_offset=30, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=2, argval=66, argrepr='to 66', offset=60, start_offset=60, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=21, argval=24, argrepr='to 24', offset=62, start_offset=62, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=66, start_offset=66, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=68, start_offset=68, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=148, argval='>', argrepr='bool(>)', offset=70, start_offset=70, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=2, argval=80, argrepr='to 80', offset=74, start_offset=74, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=28, argval=24, argrepr='to 24', offset=76, start_offset=76, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=80, start_offset=80, starts_line=8, is_jump_target=True, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=108, argrepr='to 108', offset=82, start_offset=82, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='END_FOR', opcode=4, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=3, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=86, start_offset=86, starts_line=10, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=96, start_offset=96, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=98, start_offset=98, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=106, start_offset=106, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST_CHECK', opcode=127, arg=0, argval='i', argrepr='i', offset=108, start_offset=108, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='TO_BOOL', opcode=6, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=37, argval=194, argrepr='to 194', offset=118, start_offset=118, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=120, start_offset=120, starts_line=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=130, start_offset=130, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=132, start_offset=132, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=140, start_offset=140, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=142, start_offset=142, starts_line=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=144, start_offset=144, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=146, start_offset=146, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=150, start_offset=150, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, start_offset=152, starts_line=14, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=154, start_offset=154, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=148, argval='>', argrepr='bool(>)', offset=156, start_offset=156, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=2, argval=166, argrepr='to 166', offset=160, start_offset=160, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=29, argval=108, argrepr='to 108', offset=162, start_offset=162, starts_line=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=166, start_offset=166, starts_line=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=168, start_offset=168, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=18, argval='<', argrepr='bool(<)', offset=170, start_offset=170, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=178, argrepr='to 178', offset=174, start_offset=174, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=19, argval=216, argrepr='to 216', offset=176, start_offset=176, starts_line=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=178, start_offset=178, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='TO_BOOL', opcode=6, arg=None, argval=None, argrepr='', offset=180, start_offset=180, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=2, argval=194, argrepr='to 194', offset=188, start_offset=188, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=37, argval=120, argrepr='to 120', offset=190, start_offset=190, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=194, start_offset=194, starts_line=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=204, start_offset=204, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=206, start_offset=206, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=214, start_offset=214, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=216, start_offset=216, starts_line=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=218, start_offset=218, starts_line=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=220, start_offset=220, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=222, start_offset=222, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=228, start_offset=228, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=230, start_offset=230, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=232, start_offset=232, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=234, start_offset=234, starts_line=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=244, start_offset=244, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=246, start_offset=246, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=254, start_offset=254, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=256, start_offset=256, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=258, start_offset=258, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=260, start_offset=260, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=262, start_offset=262, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=270, start_offset=270, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=272, start_offset=272, starts_line=28, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=282, start_offset=282, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=284, start_offset=284, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=292, start_offset=292, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=294, start_offset=294, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=298, start_offset=298, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='TO_BOOL', opcode=6, arg=None, argval=None, argrepr='', offset=300, start_offset=300, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=312, argrepr='to 312', offset=308, start_offset=308, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=310, start_offset=310, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=314, start_offset=314, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=316, start_offset=316, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=318, start_offset=318, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=26, argval=272, argrepr='to 272', offset=320, start_offset=320, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=324, start_offset=324, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=328, start_offset=328, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=332, start_offset=332, starts_line=22, is_jump_target=False, positions=None), - Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=342, start_offset=342, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=15, argval=376, argrepr='to 376', offset=344, start_offset=344, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=348, start_offset=348, starts_line=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=358, start_offset=358, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=360, start_offset=360, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=370, start_offset=370, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=52, argval=272, argrepr='to 272', offset=372, start_offset=372, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=376, start_offset=376, starts_line=22, is_jump_target=True, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=378, start_offset=378, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=380, start_offset=380, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=382, start_offset=382, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=386, start_offset=386, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=396, start_offset=396, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=406, start_offset=406, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=408, start_offset=408, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=410, start_offset=410, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=412, start_offset=412, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to 88', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=True, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to 68', offset=60, start_offset=60, starts_line=False, line_number=5, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to 24', offset=64, start_offset=64, starts_line=True, line_number=6, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to 84', offset=76, start_offset=76, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to 24', offset=80, start_offset=80, starts_line=False, line_number=7, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, is_jump_target=True, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to 112', offset=86, start_offset=86, starts_line=False, line_number=8, is_jump_target=False, positions=None), + Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=102, start_offset=102, starts_line=False, line_number=10, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST_CHECK', opcode=87, arg=0, argval='i', argrepr='i', offset=112, start_offset=112, starts_line=True, line_number=11, is_jump_target=True, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to 206', offset=122, start_offset=122, starts_line=False, line_number=11, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=126, start_offset=126, starts_line=True, line_number=12, is_jump_target=True, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=136, start_offset=136, starts_line=False, line_number=12, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=148, start_offset=148, starts_line=True, line_number=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=1, argrepr='1', offset=150, start_offset=150, starts_line=False, line_number=13, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=45, arg=23, argval=23, argrepr='-=', offset=152, start_offset=152, starts_line=False, line_number=13, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=False, line_number=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to 174', offset=166, start_offset=166, starts_line=False, line_number=14, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to 112', offset=170, start_offset=170, starts_line=True, line_number=15, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to 188', offset=182, start_offset=182, starts_line=False, line_number=16, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to 228', offset=186, start_offset=186, starts_line=True, line_number=17, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, is_jump_target=True, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to 206', offset=198, start_offset=198, starts_line=False, line_number=11, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to 126', offset=202, start_offset=202, starts_line=False, line_number=11, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=19, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=30, arg=None, argval=None, argrepr='', offset=228, start_offset=228, starts_line=True, line_number=20, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=5, argval=1, argrepr='1', offset=230, start_offset=230, starts_line=True, line_number=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=7, argval=0, argrepr='0', offset=232, start_offset=232, starts_line=False, line_number=21, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=45, arg=11, argval=11, argrepr='/', offset=234, start_offset=234, starts_line=False, line_number=21, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=238, start_offset=238, starts_line=False, line_number=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=240, start_offset=240, starts_line=True, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='BEFORE_WITH', opcode=2, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=110, arg=1, argval='dodgy', argrepr='dodgy', offset=244, start_offset=244, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=246, start_offset=246, starts_line=True, line_number=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=256, start_offset=256, starts_line=False, line_number=26, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=258, start_offset=258, starts_line=False, line_number=26, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=268, start_offset=268, starts_line=True, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=270, start_offset=270, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=0, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=2, argval=2, argrepr='', offset=274, start_offset=274, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=282, start_offset=282, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=284, start_offset=284, starts_line=True, line_number=28, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=294, start_offset=294, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=306, start_offset=306, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=True, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to 326', offset=320, start_offset=320, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, is_jump_target=True, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to 284', offset=334, start_offset=334, starts_line=False, line_number=25, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=346, start_offset=346, starts_line=True, line_number=22, is_jump_target=False, positions=None), + Instruction(opname='CHECK_EXC_MATCH', opcode=7, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=22, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to 392', offset=358, start_offset=358, starts_line=False, line_number=22, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=364, start_offset=364, starts_line=True, line_number=23, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, start_offset=374, starts_line=False, line_number=23, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to 284', offset=388, start_offset=388, starts_line=False, line_number=23, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, is_jump_target=True, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=402, start_offset=402, starts_line=True, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=412, start_offset=412, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=True, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling def simple(): pass expected_opinfo_simple = [ - Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=simple.__code__.co_firstlineno, is_jump_target=False, positions=None), - Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=None, is_jump_target=False), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, is_jump_target=False, positions=None), + Instruction(opname='RETURN_CONST', opcode=103, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, is_jump_target=False), ] @@ -1913,7 +1937,12 @@ def roots(a, b, c): if show_caches or op != cache_opcode ] dis_positions = [ - instruction.positions + None if instruction.positions is None else ( + instruction.positions.lineno, + instruction.positions.end_lineno, + instruction.positions.col_offset, + instruction.positions.end_col_offset, + ) for instruction in dis.get_instructions( code, adaptive=adaptive, show_caches=show_caches ) @@ -1922,7 +1951,7 @@ def roots(a, b, c): def test_oparg_alias(self): instruction = Instruction(opname="NOP", opcode=dis.opmap["NOP"], arg=None, argval=None, - argrepr='', offset=10, start_offset=10, starts_line=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, positions=None) self.assertEqual(instruction.arg, instruction.oparg) @@ -1930,7 +1959,7 @@ def test_baseopname_and_baseopcode(self): # Standard instructions for name, code in dis.opmap.items(): instruction = Instruction(opname=name, opcode=code, arg=None, argval=None, argrepr='', offset=0, - start_offset=0, starts_line=1, is_jump_target=False, positions=None) + start_offset=0, starts_line=True, line_number=1, is_jump_target=False, positions=None) baseopname = instruction.baseopname baseopcode = instruction.baseopcode self.assertIsNotNone(baseopname) @@ -1939,9 +1968,9 @@ def test_baseopname_and_baseopcode(self): self.assertEqual(code, baseopcode) # Specialized instructions - for name in opcode._specialized_instructions: + for name in opcode._specialized_opmap: instruction = Instruction(opname=name, opcode=dis._all_opmap[name], arg=None, argval=None, argrepr='', - offset=0, start_offset=0, starts_line=1, is_jump_target=False, positions=None) + offset=0, start_offset=0, starts_line=True, line_number=1, is_jump_target=False, positions=None) baseopname = instruction.baseopname baseopcode = instruction.baseopcode self.assertIn(name, opcode._specializations[baseopname]) @@ -1950,25 +1979,25 @@ def test_baseopname_and_baseopcode(self): def test_jump_target(self): # Non-jump instructions should return None instruction = Instruction(opname="NOP", opcode=dis.opmap["NOP"], arg=None, argval=None, - argrepr='', offset=10, start_offset=10, starts_line=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, positions=None) self.assertIsNone(instruction.jump_target) delta = 100 instruction = Instruction(opname="JUMP_FORWARD", opcode=dis.opmap["JUMP_FORWARD"], arg=delta, argval=delta, - argrepr='', offset=10, start_offset=10, starts_line=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, positions=None) self.assertEqual(10 + 2 + 100*2, instruction.jump_target) # Test negative deltas instruction = Instruction(opname="JUMP_BACKWARD", opcode=dis.opmap["JUMP_BACKWARD"], arg=delta, argval=delta, - argrepr='', offset=200, start_offset=200, starts_line=1, is_jump_target=False, + argrepr='', offset=200, start_offset=200, starts_line=True, line_number=1, is_jump_target=False, positions=None) self.assertEqual(200 + 2 - 100*2 + 2*1, instruction.jump_target) # Make sure cache entries are handled instruction = Instruction(opname="SEND", opcode=dis.opmap["SEND"], arg=delta, argval=delta, - argrepr='', offset=10, start_offset=10, starts_line=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, is_jump_target=False, positions=None) self.assertEqual(10 + 2 + 1*2 + 100*2, instruction.jump_target) @@ -1994,6 +2023,7 @@ def test_start_offset(self): opcode.opmap["EXTENDED_ARG"], 0x01, opcode.opmap["EXTENDED_ARG"], 0x01, opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF, + opcode.opmap["CACHE"], 0x00, ]) jump = list(dis._get_instructions_bytes(code))[-1] self.assertEqual(8, jump.offset) @@ -2003,18 +2033,20 @@ def test_start_offset(self): opcode.opmap["LOAD_FAST"], 0x00, opcode.opmap["EXTENDED_ARG"], 0x01, opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF, + opcode.opmap["CACHE"], 0x00, opcode.opmap["EXTENDED_ARG"], 0x01, opcode.opmap["EXTENDED_ARG"], 0x01, opcode.opmap["EXTENDED_ARG"], 0x01, opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF, + opcode.opmap["CACHE"], 0x00, ]) instructions = list(dis._get_instructions_bytes(code)) # 1st jump self.assertEqual(4, instructions[2].offset) self.assertEqual(2, instructions[2].start_offset) # 2nd jump - self.assertEqual(12, instructions[6].offset) - self.assertEqual(6, instructions[6].start_offset) + self.assertEqual(14, instructions[6].offset) + self.assertEqual(8, instructions[6].start_offset) def test_cache_offset_and_end_offset(self): code = bytes([ diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index bea52c6de7ec6d..6e12e82a7a0084 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -111,6 +111,14 @@ def a_classmethod_property(cls): """ return cls.a_class_attribute + @functools.cached_property + def a_cached_property(self): + """ + >>> print(SampleClass(29).get()) + 29 + """ + return "hello" + class NestedClass: """ >>> x = SampleClass.NestedClass(5) @@ -515,6 +523,7 @@ def basics(): r""" 3 SampleClass.NestedClass 1 SampleClass.NestedClass.__init__ 1 SampleClass.__init__ + 1 SampleClass.a_cached_property 2 SampleClass.a_classmethod 1 SampleClass.a_classmethod_property 1 SampleClass.a_property @@ -571,6 +580,7 @@ def basics(): r""" 3 some_module.SampleClass.NestedClass 1 some_module.SampleClass.NestedClass.__init__ 1 some_module.SampleClass.__init__ + 1 some_module.SampleClass.a_cached_property 2 some_module.SampleClass.a_classmethod 1 some_module.SampleClass.a_classmethod_property 1 some_module.SampleClass.a_property @@ -613,6 +623,7 @@ def basics(): r""" 3 SampleClass.NestedClass 1 SampleClass.NestedClass.__init__ 1 SampleClass.__init__ + 1 SampleClass.a_cached_property 2 SampleClass.a_classmethod 1 SampleClass.a_classmethod_property 1 SampleClass.a_property @@ -634,6 +645,7 @@ def basics(): r""" 0 SampleClass.NestedClass.get 0 SampleClass.NestedClass.square 1 SampleClass.__init__ + 1 SampleClass.a_cached_property 2 SampleClass.a_classmethod 1 SampleClass.a_classmethod_property 1 SampleClass.a_property @@ -736,19 +748,49 @@ def non_Python_modules(): r""" """ +class TestDocTest(unittest.TestCase): + + def test_run(self): + test = ''' + >>> 1 + 1 + 11 + >>> 2 + 3 # doctest: +SKIP + "23" + >>> 5 + 7 + 57 + ''' + + def myfunc(): + pass + myfunc.__doc__ = test + + # test DocTestFinder.run() + test = doctest.DocTestFinder().find(myfunc)[0] + with support.captured_stdout(): + with support.captured_stderr(): + results = doctest.DocTestRunner(verbose=False).run(test) + + # test TestResults + self.assertIsInstance(results, doctest.TestResults) + self.assertEqual(results.failed, 2) + self.assertEqual(results.attempted, 3) + self.assertEqual(results.skipped, 1) + self.assertEqual(tuple(results), (2, 3)) + x, y = results + self.assertEqual((x, y), (2, 3)) + + class TestDocTestFinder(unittest.TestCase): def test_issue35753(self): # This import of `call` should trigger issue35753 when - # `support.run_doctest` is called due to unwrap failing, + # DocTestFinder.find() is called due to inspect.unwrap() failing, # however with a patched doctest this should succeed. from unittest.mock import call dummy_module = types.ModuleType("dummy") dummy_module.__dict__['inject_call'] = call - try: - support.run_doctest(dummy_module, verbosity=True) - except ValueError as e: - raise support.TestFailed("Doctest unwrap failed") from e + finder = doctest.DocTestFinder() + self.assertEqual(finder.find(dummy_module), []) def test_empty_namespace_package(self): pkg_name = 'doctest_empty_pkg' diff --git a/Lib/test/test_dtrace.py b/Lib/test/test_dtrace.py index 4b971deacc1a5c..e1adf8e9748506 100644 --- a/Lib/test/test_dtrace.py +++ b/Lib/test/test_dtrace.py @@ -3,6 +3,7 @@ import re import subprocess import sys +import sysconfig import types import unittest @@ -173,6 +174,87 @@ class SystemTapOptimizedTests(TraceTests, unittest.TestCase): backend = SystemTapBackend() optimize_python = 2 +class CheckDtraceProbes(unittest.TestCase): + @classmethod + def setUpClass(cls): + if sysconfig.get_config_var('WITH_DTRACE'): + readelf_major_version, readelf_minor_version = cls.get_readelf_version() + if support.verbose: + print(f"readelf version: {readelf_major_version}.{readelf_minor_version}") + else: + raise unittest.SkipTest("CPython must be configured with the --with-dtrace option.") + + + @staticmethod + def get_readelf_version(): + try: + cmd = ["readelf", "--version"] + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + ) + with proc: + version, stderr = proc.communicate() + + if proc.returncode: + raise Exception( + f"Command {' '.join(cmd)!r} failed " + f"with exit code {proc.returncode}: " + f"stdout={version!r} stderr={stderr!r}" + ) + except OSError: + raise unittest.SkipTest("Couldn't find readelf on the path") + + # Regex to parse: + # 'GNU readelf (GNU Binutils) 2.40.0\n' -> 2.40 + match = re.search(r"^(?:GNU) readelf.*?\b(\d+)\.(\d+)", version) + if match is None: + raise unittest.SkipTest(f"Unable to parse readelf version: {version}") + + return int(match.group(1)), int(match.group(2)) + + def get_readelf_output(self): + command = ["readelf", "-n", sys.executable] + stdout, _ = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True, + ).communicate() + return stdout + + def test_check_probes(self): + readelf_output = self.get_readelf_output() + + available_probe_names = [ + "Name: import__find__load__done", + "Name: import__find__load__start", + "Name: audit", + "Name: gc__start", + "Name: gc__done", + ] + + for probe_name in available_probe_names: + with self.subTest(probe_name=probe_name): + self.assertIn(probe_name, readelf_output) + + @unittest.expectedFailure + def test_missing_probes(self): + readelf_output = self.get_readelf_output() + + # Missing probes will be added in the future. + missing_probe_names = [ + "Name: function__entry", + "Name: function__return", + "Name: line", + ] + + for probe_name in missing_probe_names: + with self.subTest(probe_name=probe_name): + self.assertIn(probe_name, readelf_output) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_dynamic.py b/Lib/test/test_dynamic.py index 7e12d428e0fde2..0aa3be6a1bde6a 100644 --- a/Lib/test/test_dynamic.py +++ b/Lib/test/test_dynamic.py @@ -145,7 +145,7 @@ def __missing__(self, key): code = "lambda: " + "+".join(f"_number_{i}" for i in range(variables)) sum_func = eval(code, MyGlobals()) expected = sum(range(variables)) - # Warm up the the function for quickening (PEP 659) + # Warm up the function for quickening (PEP 659) for _ in range(30): self.assertEqual(sum_func(), expected) diff --git a/Lib/test/test_eintr.py b/Lib/test/test_eintr.py index 528147802ba47e..49b15f1a2dba92 100644 --- a/Lib/test/test_eintr.py +++ b/Lib/test/test_eintr.py @@ -9,6 +9,7 @@ class EINTRTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") + @support.requires_resource('walltime') def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). diff --git a/Lib/test/test_email/data/msg_47.txt b/Lib/test/test_email/data/msg_47.txt new file mode 100644 index 00000000000000..bb48b47d96baf8 --- /dev/null +++ b/Lib/test/test_email/data/msg_47.txt @@ -0,0 +1,14 @@ +Date: 01 Jan 2001 00:01+0000 +From: arthur@example.example +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary=foo + +--foo +Content-Type: text/plain +bar + +--foo +Content-Type: text/html +

baz

+ +--foo-- \ No newline at end of file diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 5238944d6b4788..512464f87162cd 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -38,6 +38,7 @@ from email import quoprimime from email import utils +from test import support from test.support import threading_helper from test.support.os_helper import unlink from test.test_email import openfile, TestEmailBase @@ -2235,7 +2236,7 @@ def test_multipart_valid_cte_no_defect(self): "\nContent-Transfer-Encoding: {}".format(cte))) self.assertEqual(len(msg.defects), 0) - # test_headerregistry.TestContentTyopeHeader invalid_1 and invalid_2. + # test_headerregistry.TestContentTypeHeader invalid_1 and invalid_2. def test_invalid_content_type(self): eq = self.assertEqual neq = self.ndiffAssertEqual @@ -3319,90 +3320,32 @@ def test_getaddresses(self): [('Al Person', 'aperson@dom.ain'), ('Bud Person', 'bperson@dom.ain')]) - def test_getaddresses_parsing_errors(self): - """Test for parsing errors from CVE-2023-27043""" - eq = self.assertEqual - eq(utils.getaddresses(['alice@example.org(']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org)']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org<']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org>']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org@']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org,']), - [('', 'alice@example.org'), ('', 'bob@example.com')]) - eq(utils.getaddresses(['alice@example.org;']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org:']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org.']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org"']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org[']), - [('', '')]) - eq(utils.getaddresses(['alice@example.org]']), - [('', '')]) - - def test_parseaddr_parsing_errors(self): - """Test for parsing errors from CVE-2023-27043""" - eq = self.assertEqual - eq(utils.parseaddr(['alice@example.org(']), - ('', '')) - eq(utils.parseaddr(['alice@example.org)']), - ('', '')) - eq(utils.parseaddr(['alice@example.org<']), - ('', '')) - eq(utils.parseaddr(['alice@example.org>']), - ('', '')) - eq(utils.parseaddr(['alice@example.org@']), - ('', '')) - eq(utils.parseaddr(['alice@example.org,']), - ('', '')) - eq(utils.parseaddr(['alice@example.org;']), - ('', '')) - eq(utils.parseaddr(['alice@example.org:']), - ('', '')) - eq(utils.parseaddr(['alice@example.org.']), - ('', '')) - eq(utils.parseaddr(['alice@example.org"']), - ('', '')) - eq(utils.parseaddr(['alice@example.org[']), - ('', '')) - eq(utils.parseaddr(['alice@example.org]']), - ('', '')) + def test_getaddresses_comma_in_name(self): + """GH-106669 regression test.""" + self.assertEqual( + utils.getaddresses( + [ + '"Bud, Person" ', + 'aperson@dom.ain (Al Person)', + '"Mariusz Felisiak" ', + ] + ), + [ + ('Bud, Person', 'bperson@dom.ain'), + ('Al Person', 'aperson@dom.ain'), + ('Mariusz Felisiak', 'to@example.com'), + ], + ) def test_getaddresses_nasty(self): eq = self.assertEqual eq(utils.getaddresses(['foo: ;']), [('', '')]) - eq(utils.getaddresses(['[]*-- =~$']), [('', '')]) + eq(utils.getaddresses( + ['[]*-- =~$']), + [('', ''), ('', ''), ('', '*--')]) eq(utils.getaddresses( ['foo: ;', '"Jason R. Mastaler" ']), [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) - eq(utils.getaddresses( - [r'Pete(A nice \) chap) ']), - [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]) - eq(utils.getaddresses( - ['(Empty list)(start)Undisclosed recipients :(nobody(I know))']), - [('', '')]) - eq(utils.getaddresses( - ['Mary <@machine.tld:mary@example.net>, , jdoe@test . example']), - [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]) - eq(utils.getaddresses( - ['John Doe ']), - [('John Doe (comment)', 'jdoe@machine.example')]) - eq(utils.getaddresses( - ['"Mary Smith: Personal Account" ']), - [('Mary Smith: Personal Account', 'smith@home.example')]) - eq(utils.getaddresses( - ['Undisclosed recipients:;']), - [('', '')]) - eq(utils.getaddresses( - [r', "Giant; \"Big\" Box" ']), - [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]) def test_getaddresses_embedded_comment(self): """Test proper handling of a nested comment""" @@ -3416,6 +3359,7 @@ def test_getaddresses_header_obj(self): self.assertEqual(addrs[0][1], 'aperson@dom.ain') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_make_msgid_collisions(self): # Test make_msgid uniqueness, even with multiple threads class MsgidsThread(Thread): @@ -3770,6 +3714,16 @@ def test_bytes_header_parser(self): self.assertIsInstance(msg.get_payload(), str) self.assertIsInstance(msg.get_payload(decode=True), bytes) + def test_header_parser_multipart_is_valid(self): + # Don't flag valid multipart emails as having defects + with openfile('msg_47.txt', encoding="utf-8") as fp: + msgdata = fp.read() + + parser = email.parser.Parser(policy=email.policy.default) + parsed_msg = parser.parsestr(msgdata, headersonly=True) + + self.assertEqual(parsed_msg.defects, []) + def test_bytes_parser_does_not_close_file(self): with openfile('msg_02.txt', 'rb') as fp: email.parser.BytesParser().parse(fp) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 582392ecddcb91..5a8690a4836dd6 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1,8 +1,6 @@ # Run the tests in Programs/_testembed.c (tests for the CPython embedding APIs) from test import support -from test.support import import_helper -from test.support import os_helper -from test.support import requires_specialization +from test.support import import_helper, os_helper, MS_WINDOWS import unittest from collections import namedtuple @@ -21,11 +19,11 @@ if not support.has_subprocess_support: raise unittest.SkipTest("test module requires subprocess") -MS_WINDOWS = (os.name == 'nt') MACOS = (sys.platform == 'darwin') PYMEM_ALLOCATOR_NOT_SET = 0 PYMEM_ALLOCATOR_DEBUG = 2 PYMEM_ALLOCATOR_MALLOC = 3 +Py_STATS = hasattr(sys, '_stats_on') # _PyCoreConfig_InitCompatConfig() API_COMPAT = 1 @@ -347,7 +345,7 @@ def test_simple_initialization_api(self): out, err = self.run_embedded_interpreter("test_repeated_simple_init") self.assertEqual(out, 'Finalized\n' * INIT_LOOPS) - @requires_specialization + @support.requires_specialization def test_specialized_static_code_gets_unspecialized_at_Py_FINALIZE(self): # https://github.com/python/cpython/issues/92031 @@ -361,7 +359,7 @@ def is_specialized(f): for instruction in dis.get_instructions(f, adaptive=True): opname = instruction.opname if ( - opname in opcode._specialized_instructions + opname in opcode._specialized_opmap # Exclude superinstructions: and "__" not in opname ): @@ -447,6 +445,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_hash_seed': 0, 'hash_seed': 0, 'int_max_str_digits': sys.int_info.default_max_str_digits, + 'cpu_count': -1, 'faulthandler': 0, 'tracemalloc': 0, 'perf_profiling': 0, @@ -454,6 +453,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'code_debug_ranges': 1, 'show_ref_count': 0, 'dump_refs': 0, + 'dump_refs_file': None, 'malloc_stats': 0, 'filesystem_encoding': GET_DEFAULT_CONFIG, @@ -503,6 +503,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'run_command': None, 'run_module': None, 'run_filename': None, + 'sys_path_0': None, '_install_importlib': 1, 'check_hash_pycs_mode': 'default', @@ -512,6 +513,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'safe_path': 0, '_is_python_build': IGNORE_CONFIG, } + if Py_STATS: + CONFIG_COMPAT['_pystats'] = 0 if MS_WINDOWS: CONFIG_COMPAT.update({ 'legacy_windows_stdio': 0, @@ -891,10 +894,13 @@ def test_init_from_config(self): 'module_search_paths': self.IGNORE_CONFIG, 'safe_path': 1, 'int_max_str_digits': 31337, + 'cpu_count': 4321, 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, } + if Py_STATS: + config['_pystats'] = 1 self.check_all_configs("test_init_from_config", config, preconfig, api=API_COMPAT) @@ -927,6 +933,8 @@ def test_init_compat_env(self): 'safe_path': 1, 'int_max_str_digits': 4567, } + if Py_STATS: + config['_pystats'] = 1 self.check_all_configs("test_init_compat_env", config, preconfig, api=API_COMPAT) @@ -960,6 +968,8 @@ def test_init_python_env(self): 'safe_path': 1, 'int_max_str_digits': 4567, } + if Py_STATS: + config['_pystats'] = 1 self.check_all_configs("test_init_python_env", config, preconfig, api=API_PYTHON) @@ -1122,6 +1132,7 @@ def test_init_run_main(self): 'program_name': './python3', 'run_command': code + '\n', 'parse_argv': 2, + 'sys_path_0': '', } self.check_all_configs("test_init_run_main", config, api=API_PYTHON) @@ -1137,6 +1148,7 @@ def test_init_main(self): 'run_command': code + '\n', 'parse_argv': 2, '_init_main': 0, + 'sys_path_0': '', } self.check_all_configs("test_init_main", config, api=API_PYTHON, @@ -1703,6 +1715,9 @@ def test_open_code_hook(self): def test_audit(self): self.run_embedded_interpreter("test_audit") + def test_audit_tuple(self): + self.run_embedded_interpreter("test_audit_tuple") + def test_audit_subinterpreter(self): self.run_embedded_interpreter("test_audit_subinterpreter") diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index a286411f7bcf57..8c1f285f7b3bc2 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -38,6 +38,25 @@ def load_tests(loader, tests, ignore): )) return tests +def reraise_if_not_enum(*enum_types_or_exceptions): + from functools import wraps + + def decorator(func): + @wraps(func) + def inner(*args, **kwargs): + excs = [ + e + for e in enum_types_or_exceptions + if isinstance(e, Exception) + ] + if len(excs) == 1: + raise excs[0] + elif excs: + raise ExceptionGroup('Enum Exceptions', excs) + return func(*args, **kwargs) + return inner + return decorator + MODULE = __name__ SHORT_MODULE = MODULE.split('.')[-1] @@ -75,30 +94,42 @@ class FlagStooges(Flag): except Exception as exc: FlagStooges = exc -class FlagStoogesWithZero(Flag): - NOFLAG = 0 - LARRY = 1 - CURLY = 2 - MOE = 4 - BIG = 389 - -class IntFlagStooges(IntFlag): - LARRY = 1 - CURLY = 2 - MOE = 4 - BIG = 389 - -class IntFlagStoogesWithZero(IntFlag): - NOFLAG = 0 - LARRY = 1 - CURLY = 2 - MOE = 4 - BIG = 389 +try: + class FlagStoogesWithZero(Flag): + NOFLAG = 0 + LARRY = 1 + CURLY = 2 + MOE = 4 + BIG = 389 +except Exception as exc: + FlagStoogesWithZero = exc + +try: + class IntFlagStooges(IntFlag): + LARRY = 1 + CURLY = 2 + MOE = 4 + BIG = 389 +except Exception as exc: + IntFlagStooges = exc + +try: + class IntFlagStoogesWithZero(IntFlag): + NOFLAG = 0 + LARRY = 1 + CURLY = 2 + MOE = 4 + BIG = 389 +except Exception as exc: + IntFlagStoogesWithZero = exc # for pickle test and subclass tests -class Name(StrEnum): - BDFL = 'Guido van Rossum' - FLUFL = 'Barry Warsaw' +try: + class Name(StrEnum): + BDFL = 'Guido van Rossum' + FLUFL = 'Barry Warsaw' +except Exception as exc: + Name = exc try: Question = Enum('Question', 'who what when where why', module=__name__) @@ -204,26 +235,35 @@ def __get__(self, instance, ownerclass): # for global repr tests -@enum.global_enum -class HeadlightsK(IntFlag, boundary=enum.KEEP): - OFF_K = 0 - LOW_BEAM_K = auto() - HIGH_BEAM_K = auto() - FOG_K = auto() +try: + @enum.global_enum + class HeadlightsK(IntFlag, boundary=enum.KEEP): + OFF_K = 0 + LOW_BEAM_K = auto() + HIGH_BEAM_K = auto() + FOG_K = auto() +except Exception as exc: + HeadlightsK = exc -@enum.global_enum -class HeadlightsC(IntFlag, boundary=enum.CONFORM): - OFF_C = 0 - LOW_BEAM_C = auto() - HIGH_BEAM_C = auto() - FOG_C = auto() +try: + @enum.global_enum + class HeadlightsC(IntFlag, boundary=enum.CONFORM): + OFF_C = 0 + LOW_BEAM_C = auto() + HIGH_BEAM_C = auto() + FOG_C = auto() +except Exception as exc: + HeadlightsC = exc -@enum.global_enum -class NoName(Flag): - ONE = 1 - TWO = 2 +try: + @enum.global_enum + class NoName(Flag): + ONE = 1 + TWO = 2 +except Exception as exc: + NoName = exc # tests @@ -236,11 +276,83 @@ class _EnumTests: values = None def setUp(self): - class BaseEnum(self.enum_type): + if self.__class__.__name__[-5:] == 'Class': + class BaseEnum(self.enum_type): + @enum.property + def first(self): + return '%s is first!' % self.name + class MainEnum(BaseEnum): + first = auto() + second = auto() + third = auto() + if issubclass(self.enum_type, Flag): + dupe = 3 + else: + dupe = third + self.MainEnum = MainEnum + # + class NewStrEnum(self.enum_type): + def __str__(self): + return self.name.upper() + first = auto() + self.NewStrEnum = NewStrEnum + # + class NewFormatEnum(self.enum_type): + def __format__(self, spec): + return self.name.upper() + first = auto() + self.NewFormatEnum = NewFormatEnum + # + class NewStrFormatEnum(self.enum_type): + def __str__(self): + return self.name.title() + def __format__(self, spec): + return ''.join(reversed(self.name)) + first = auto() + self.NewStrFormatEnum = NewStrFormatEnum + # + class NewBaseEnum(self.enum_type): + def __str__(self): + return self.name.title() + def __format__(self, spec): + return ''.join(reversed(self.name)) + self.NewBaseEnum = NewBaseEnum + class NewSubEnum(NewBaseEnum): + first = auto() + self.NewSubEnum = NewSubEnum + # + class LazyGNV(self.enum_type): + def _generate_next_value_(name, start, last, values): + pass + self.LazyGNV = LazyGNV + # + class BusyGNV(self.enum_type): + @staticmethod + def _generate_next_value_(name, start, last, values): + pass + self.BusyGNV = BusyGNV + # + self.is_flag = False + self.names = ['first', 'second', 'third'] + if issubclass(MainEnum, StrEnum): + self.values = self.names + elif MainEnum._member_type_ is str: + self.values = ['1', '2', '3'] + elif issubclass(self.enum_type, Flag): + self.values = [1, 2, 4] + self.is_flag = True + self.dupe2 = MainEnum(5) + else: + self.values = self.values or [1, 2, 3] + # + if not getattr(self, 'source_values', False): + self.source_values = self.values + elif self.__class__.__name__[-8:] == 'Function': @enum.property def first(self): return '%s is first!' % self.name - class MainEnum(BaseEnum): + BaseEnum = self.enum_type('BaseEnum', {'first':first}) + # first = auto() second = auto() third = auto() @@ -248,63 +360,58 @@ class MainEnum(BaseEnum): dupe = 3 else: dupe = third - self.MainEnum = MainEnum - # - class NewStrEnum(self.enum_type): + self.MainEnum = MainEnum = BaseEnum('MainEnum', dict(first=first, second=second, third=third, dupe=dupe)) + # def __str__(self): return self.name.upper() first = auto() - self.NewStrEnum = NewStrEnum - # - class NewFormatEnum(self.enum_type): + self.NewStrEnum = self.enum_type('NewStrEnum', (('first',first),('__str__',__str__))) + # def __format__(self, spec): return self.name.upper() first = auto() - self.NewFormatEnum = NewFormatEnum - # - class NewStrFormatEnum(self.enum_type): + self.NewFormatEnum = self.enum_type('NewFormatEnum', [('first',first),('__format__',__format__)]) + # def __str__(self): return self.name.title() def __format__(self, spec): return ''.join(reversed(self.name)) first = auto() - self.NewStrFormatEnum = NewStrFormatEnum - # - class NewBaseEnum(self.enum_type): + self.NewStrFormatEnum = self.enum_type('NewStrFormatEnum', dict(first=first, __format__=__format__, __str__=__str__)) + # def __str__(self): return self.name.title() def __format__(self, spec): return ''.join(reversed(self.name)) - class NewSubEnum(NewBaseEnum): - first = auto() - self.NewSubEnum = NewSubEnum - # - class LazyGNV(self.enum_type): + self.NewBaseEnum = self.enum_type('NewBaseEnum', dict(__format__=__format__, __str__=__str__)) + self.NewSubEnum = self.NewBaseEnum('NewSubEnum', 'first') + # def _generate_next_value_(name, start, last, values): pass - self.LazyGNV = LazyGNV - # - class BusyGNV(self.enum_type): + self.LazyGNV = self.enum_type('LazyGNV', {'_generate_next_value_':_generate_next_value_}) + # @staticmethod def _generate_next_value_(name, start, last, values): pass - self.BusyGNV = BusyGNV - # - self.is_flag = False - self.names = ['first', 'second', 'third'] - if issubclass(MainEnum, StrEnum): - self.values = self.names - elif MainEnum._member_type_ is str: - self.values = ['1', '2', '3'] - elif issubclass(self.enum_type, Flag): - self.values = [1, 2, 4] - self.is_flag = True - self.dupe2 = MainEnum(5) + self.BusyGNV = self.enum_type('BusyGNV', {'_generate_next_value_':_generate_next_value_}) + # + self.is_flag = False + self.names = ['first', 'second', 'third'] + if issubclass(MainEnum, StrEnum): + self.values = self.names + elif MainEnum._member_type_ is str: + self.values = ['1', '2', '3'] + elif issubclass(self.enum_type, Flag): + self.values = [1, 2, 4] + self.is_flag = True + self.dupe2 = MainEnum(5) + else: + self.values = self.values or [1, 2, 3] + # + if not getattr(self, 'source_values', False): + self.source_values = self.values else: - self.values = self.values or [1, 2, 3] - # - if not getattr(self, 'source_values', False): - self.source_values = self.values + raise ValueError('unknown enum style: %r' % self.__class__.__name__) def assertFormatIsValue(self, spec, member): self.assertEqual(spec.format(member), spec.format(member.value)) @@ -332,6 +439,17 @@ def spam(cls): with self.assertRaises(AttributeError): del Season.SPRING.name + def test_bad_new_super(self): + with self.assertRaisesRegex( + TypeError, + 'has no members defined', + ): + class BadSuper(self.enum_type): + def __new__(cls, value): + obj = super().__new__(cls, value) + return obj + failed = 1 + def test_basics(self): TE = self.MainEnum if self.is_flag: @@ -387,7 +505,7 @@ def test_contains_tf(self): MainEnum = self.MainEnum self.assertIn(MainEnum.first, MainEnum) self.assertTrue(self.values[0] in MainEnum) - if type(self) is not TestStrEnum: + if type(self) not in (TestStrEnumClass, TestStrEnumFunction): self.assertFalse('first' in MainEnum) val = MainEnum.dupe self.assertIn(val, MainEnum) @@ -482,6 +600,10 @@ class SubEnum(SuperEnum): self.assertTrue('description' not in dir(SubEnum)) self.assertTrue('description' in dir(SubEnum.sample), dir(SubEnum.sample)) + def test_empty_enum_has_no_values(self): + with self.assertRaisesRegex(TypeError, "<.... 'NewBaseEnum'> has no members"): + self.NewBaseEnum(7) + def test_enum_in_enum_out(self): Main = self.MainEnum self.assertIs(Main(Main.first), Main.first) @@ -909,15 +1031,23 @@ class OpenXYZ(self.enum_type): self.assertTrue(~OpenXYZ(0), (X|Y|Z)) -class TestPlainEnum(_EnumTests, _PlainOutputTests, unittest.TestCase): +class TestPlainEnumClass(_EnumTests, _PlainOutputTests, unittest.TestCase): enum_type = Enum -class TestPlainFlag(_EnumTests, _PlainOutputTests, _FlagTests, unittest.TestCase): +class TestPlainEnumFunction(_EnumTests, _PlainOutputTests, unittest.TestCase): + enum_type = Enum + + +class TestPlainFlagClass(_EnumTests, _PlainOutputTests, _FlagTests, unittest.TestCase): enum_type = Flag -class TestIntEnum(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestPlainFlagFunction(_EnumTests, _PlainOutputTests, _FlagTests, unittest.TestCase): + enum_type = Flag + + +class TestIntEnumClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): enum_type = IntEnum # def test_shadowed_attr(self): @@ -929,7 +1059,17 @@ class Number(IntEnum): self.assertIs(Number.numerator.divisor, Number.divisor) -class TestStrEnum(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestIntEnumFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + enum_type = IntEnum + # + def test_shadowed_attr(self): + Number = IntEnum('Number', ('divisor', 'numerator')) + # + self.assertEqual(Number.divisor.numerator, 1) + self.assertIs(Number.numerator.divisor, Number.divisor) + + +class TestStrEnumClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): enum_type = StrEnum # def test_shadowed_attr(self): @@ -942,64 +1082,141 @@ class Book(StrEnum): self.assertIs(Book.title.author, Book.author) -class TestIntFlag(_EnumTests, _MinimalOutputTests, _FlagTests, unittest.TestCase): +class TestStrEnumFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + enum_type = StrEnum + # + def test_shadowed_attr(self): + Book = StrEnum('Book', ('author', 'title')) + # + self.assertEqual(Book.author.title(), 'Author') + self.assertEqual(Book.title.title(), 'Title') + self.assertIs(Book.title.author, Book.author) + + +class TestIntFlagClass(_EnumTests, _MinimalOutputTests, _FlagTests, unittest.TestCase): + enum_type = IntFlag + + +class TestIntFlagFunction(_EnumTests, _MinimalOutputTests, _FlagTests, unittest.TestCase): enum_type = IntFlag -class TestMixedInt(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestMixedIntClass(_EnumTests, _MixedOutputTests, unittest.TestCase): class enum_type(int, Enum): pass -class TestMixedStr(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestMixedIntFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + enum_type = Enum('enum_type', type=int) + + +class TestMixedStrClass(_EnumTests, _MixedOutputTests, unittest.TestCase): class enum_type(str, Enum): pass -class TestMixedIntFlag(_EnumTests, _MixedOutputTests, _FlagTests, unittest.TestCase): +class TestMixedStrFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + enum_type = Enum('enum_type', type=str) + + +class TestMixedIntFlagClass(_EnumTests, _MixedOutputTests, _FlagTests, unittest.TestCase): class enum_type(int, Flag): pass -class TestMixedDate(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestMixedIntFlagFunction(_EnumTests, _MixedOutputTests, _FlagTests, unittest.TestCase): + enum_type = Flag('enum_type', type=int) + +class TestMixedDateClass(_EnumTests, _MixedOutputTests, unittest.TestCase): + # values = [date(2021, 12, 25), date(2020, 3, 15), date(2019, 11, 27)] source_values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] - + # class enum_type(date, Enum): + @staticmethod def _generate_next_value_(name, start, count, last_values): values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] return values[count] -class TestMinimalDate(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestMixedDateFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + # + values = [date(2021, 12, 25), date(2020, 3, 15), date(2019, 11, 27)] + source_values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] + # + # staticmethod decorator will be added by EnumType if not present + def _generate_next_value_(name, start, count, last_values): + values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] + return values[count] + # + enum_type = Enum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=date) + +class TestMinimalDateClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # values = [date(2023, 12, 1), date(2016, 2, 29), date(2009, 1, 1)] source_values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] - + # class enum_type(date, ReprEnum): + # staticmethod decorator will be added by EnumType if absent def _generate_next_value_(name, start, count, last_values): values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] return values[count] -class TestMixedFloat(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestMinimalDateFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # + values = [date(2023, 12, 1), date(2016, 2, 29), date(2009, 1, 1)] + source_values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] + # + @staticmethod + def _generate_next_value_(name, start, count, last_values): + values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] + return values[count] + # + enum_type = ReprEnum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=date) - values = [1.1, 2.2, 3.3] +class TestMixedFloatClass(_EnumTests, _MixedOutputTests, unittest.TestCase): + # + values = [1.1, 2.2, 3.3] + # class enum_type(float, Enum): def _generate_next_value_(name, start, count, last_values): values = [1.1, 2.2, 3.3] return values[count] -class TestMinimalFloat(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestMixedFloatFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + # + values = [1.1, 2.2, 3.3] + # + def _generate_next_value_(name, start, count, last_values): + values = [1.1, 2.2, 3.3] + return values[count] + # + enum_type = Enum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=float) + +class TestMinimalFloatClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # values = [4.4, 5.5, 6.6] - + # class enum_type(float, ReprEnum): def _generate_next_value_(name, start, count, last_values): values = [4.4, 5.5, 6.6] return values[count] +class TestMinimalFloatFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # + values = [4.4, 5.5, 6.6] + # + def _generate_next_value_(name, start, count, last_values): + values = [4.4, 5.5, 6.6] + return values[count] + # + enum_type = ReprEnum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=float) + + class TestSpecial(unittest.TestCase): """ various operations that are not attributable to every possible enum @@ -1124,9 +1341,8 @@ def red(self): green = 2 blue = 3 + @reraise_if_not_enum(Theory) def test_enum_function_with_qualname(self): - if isinstance(Theory, Exception): - raise Theory self.assertEqual(Theory.__qualname__, 'spanish_inquisition') def test_enum_of_types(self): @@ -1355,6 +1571,7 @@ class MyUnBrokenEnum(UnBrokenInt, Enum): test_pickle_dump_load(self.assertIs, MyUnBrokenEnum.I) test_pickle_dump_load(self.assertIs, MyUnBrokenEnum) + @reraise_if_not_enum(FloatStooges) def test_floatenum_fromhex(self): h = float.hex(FloatStooges.MOE.value) self.assertIs(FloatStooges.fromhex(h), FloatStooges.MOE) @@ -1475,6 +1692,7 @@ class ThreePart(Enum): self.assertIs(ThreePart((3, 3.0, 'three')), ThreePart.THREE) self.assertIs(ThreePart(3, 3.0, 'three'), ThreePart.THREE) + @reraise_if_not_enum(IntStooges) def test_intenum_from_bytes(self): self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE) with self.assertRaises(ValueError): @@ -1503,33 +1721,28 @@ def repr(self): class Huh(MyStr, MyInt, Enum): One = 1 + @reraise_if_not_enum(Stooges) def test_pickle_enum(self): - if isinstance(Stooges, Exception): - raise Stooges test_pickle_dump_load(self.assertIs, Stooges.CURLY) test_pickle_dump_load(self.assertIs, Stooges) + @reraise_if_not_enum(IntStooges) def test_pickle_int(self): - if isinstance(IntStooges, Exception): - raise IntStooges test_pickle_dump_load(self.assertIs, IntStooges.CURLY) test_pickle_dump_load(self.assertIs, IntStooges) + @reraise_if_not_enum(FloatStooges) def test_pickle_float(self): - if isinstance(FloatStooges, Exception): - raise FloatStooges test_pickle_dump_load(self.assertIs, FloatStooges.CURLY) test_pickle_dump_load(self.assertIs, FloatStooges) + @reraise_if_not_enum(Answer) def test_pickle_enum_function(self): - if isinstance(Answer, Exception): - raise Answer test_pickle_dump_load(self.assertIs, Answer.him) test_pickle_dump_load(self.assertIs, Answer) + @reraise_if_not_enum(Question) def test_pickle_enum_function_with_module(self): - if isinstance(Question, Exception): - raise Question test_pickle_dump_load(self.assertIs, Question.who) test_pickle_dump_load(self.assertIs, Question) @@ -1592,9 +1805,8 @@ class Season(Enum): [Season.SUMMER, Season.WINTER, Season.AUTUMN, Season.SPRING], ) + @reraise_if_not_enum(Name) def test_subclassing(self): - if isinstance(Name, Exception): - raise Name self.assertEqual(Name.BDFL, 'Guido van Rossum') self.assertTrue(Name.BDFL, Name('Guido van Rossum')) self.assertIs(Name.BDFL, getattr(Name, 'BDFL')) @@ -2764,11 +2976,13 @@ class SecondFailedStrEnum(CustomStrEnum): class ThirdFailedStrEnum(CustomStrEnum): one = '1' two = 2 # this will become '2' - with self.assertRaisesRegex(TypeError, '.encoding. must be str, not '): + with self.assertRaisesRegex(TypeError, + r"argument (2|'encoding') must be str, not "): class ThirdFailedStrEnum(CustomStrEnum): one = '1' two = b'2', sys.getdefaultencoding - with self.assertRaisesRegex(TypeError, '.errors. must be str, not '): + with self.assertRaisesRegex(TypeError, + r"argument (3|'errors') must be str, not "): class ThirdFailedStrEnum(CustomStrEnum): one = '1' two = b'2', 'ascii', 9 @@ -3330,9 +3544,13 @@ def test_programatic_function_from_dict(self): self.assertIn(e, Perm) self.assertIs(type(e), Perm) + @reraise_if_not_enum( + FlagStooges, + FlagStoogesWithZero, + IntFlagStooges, + IntFlagStoogesWithZero, + ) def test_pickle(self): - if isinstance(FlagStooges, Exception): - raise FlagStooges test_pickle_dump_load(self.assertIs, FlagStooges.CURLY) test_pickle_dump_load(self.assertEqual, FlagStooges.CURLY|FlagStooges.MOE) @@ -3637,6 +3855,7 @@ def test_type(self): self.assertTrue(isinstance(Open.WO | Open.RW, Open)) self.assertEqual(Open.WO | Open.RW, 3) + @reraise_if_not_enum(HeadlightsK) def test_global_repr_keep(self): self.assertEqual( repr(HeadlightsK(0)), @@ -3651,6 +3870,7 @@ def test_global_repr_keep(self): '%(m)s.HeadlightsK(8)' % {'m': SHORT_MODULE}, ) + @reraise_if_not_enum(HeadlightsC) def test_global_repr_conform1(self): self.assertEqual( repr(HeadlightsC(0)), @@ -3665,6 +3885,7 @@ def test_global_repr_conform1(self): '%(m)s.OFF_C' % {'m': SHORT_MODULE}, ) + @reraise_if_not_enum(NoName) def test_global_enum_str(self): self.assertEqual(str(NoName.ONE & NoName.TWO), 'NoName(0)') self.assertEqual(str(NoName(0)), 'NoName(0)') @@ -4470,8 +4691,6 @@ def _generate_next_value_(name, start, count, last): self.assertEqual(Huh.TWO.value, (2, 2)) self.assertEqual(Huh.THREE.value, (3, 3, 3)) -class TestEnumTypeSubclassing(unittest.TestCase): - pass expected_help_output_with_docs = """\ Help on class Color in module %s: diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 2658e027ff3e2b..20122679223843 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,7 +1,7 @@ import collections.abc import types import unittest - +from test.support import Py_C_RECURSION_LIMIT class TestExceptionGroupTypeHierarchy(unittest.TestCase): def test_exception_group_types(self): @@ -460,7 +460,7 @@ def test_basics_split_by_predicate__match(self): class DeepRecursionInSplitAndSubgroup(unittest.TestCase): def make_deep_eg(self): e = TypeError(1) - for i in range(2000): + for i in range(Py_C_RECURSION_LIMIT + 1): e = ExceptionGroup('eg', [e]) return e diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index f3554f1c4bb3f3..eafa7d84638b76 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -253,7 +253,7 @@ def testSyntaxErrorOffset(self): check('try:\n pass\nexcept*:\n pass', 3, 8) check('try:\n pass\nexcept*:\n pass\nexcept* ValueError:\n pass', 3, 8) - # Errors thrown by tokenizer.c + # Errors thrown by the tokenizer check('(0x+1)', 1, 3) check('x = 0xI', 1, 6) check('0010 + 2', 1, 1) @@ -318,6 +318,12 @@ def baz(): check('(yield i) = 2', 1, 2) check('def f(*):\n pass', 1, 7) + @support.requires_resource('cpu') + @support.bigmemtest(support._2G, memuse=1.5) + def testMemoryErrorBigSource(self, _size): + with self.assertRaises(OverflowError): + exec(f"if True:\n {' ' * 2**31}print('hello world')") + @cpython_only def testSettingException(self): # test that setting an exception at the C level works even if the @@ -1350,6 +1356,7 @@ def g(): @cpython_only + @support.requires_resource('cpu') def test_trashcan_recursion(self): # See bpo-33930 @@ -1484,6 +1491,9 @@ def recurse_in_body_and_except(): @cpython_only + # Python built with Py_TRACE_REFS fail with a fatal error in + # _PyRefchain_Trace() on memory allocation error. + @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') def test_recursion_normalizing_with_no_memory(self): # Issue #30697. Test that in the abort that occurs when there is no # memory left and the size of the Python frames stack is greater than @@ -1652,6 +1662,9 @@ def test_unhandled(self): self.assertTrue(report.endswith("\n")) @cpython_only + # Python built with Py_TRACE_REFS fail with a fatal error in + # _PyRefchain_Trace() on memory allocation error. + @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') def test_memory_error_in_PyErr_PrintEx(self): code = """if 1: import _testcapi @@ -1931,6 +1944,123 @@ def test_copy_pickle(self): self.assertEqual(exc.name, orig.name) self.assertEqual(exc.path, orig.path) + +class AssertionErrorTests(unittest.TestCase): + def tearDown(self): + unlink(TESTFN) + + def write_source(self, source): + with open(TESTFN, 'w') as testfile: + testfile.write(dedent(source)) + _rc, _out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN) + return err.decode('utf-8').splitlines() + + def test_assertion_error_location(self): + cases = [ + ('assert None', + [ + ' assert None', + ' ^^^^', + 'AssertionError', + ], + ), + ('assert 0', + [ + ' assert 0', + ' ^', + 'AssertionError', + ], + ), + ('assert 1 > 2', + [ + ' assert 1 > 2', + ' ^^^^^', + 'AssertionError', + ], + ), + ('assert 1 > 2 and 3 > 2', + [ + ' assert 1 > 2 and 3 > 2', + ' ^^^^^^^^^^^^^^^', + 'AssertionError', + ], + ), + ('assert 1 > 2, "message"', + [ + ' assert 1 > 2, "message"', + ' ^^^^^', + 'AssertionError: message', + ], + ), + + # Multiline: + (""" + assert ( + 1 > 2) + """, + [ + ' 1 > 2)', + ' ^^^^^', + 'AssertionError', + ], + ), + (""" + assert ( + 1 > 2), "Message" + """, + [ + ' 1 > 2), "Message"', + ' ^^^^^', + 'AssertionError: Message', + ], + ), + (""" + assert ( + 1 > 2), \\ + "Message" + """, + [ + ' 1 > 2), \\', + ' ^^^^^', + 'AssertionError: Message', + ], + ), + ] + for source, expected in cases: + with self.subTest(source): + result = self.write_source(source) + self.assertEqual(result[-3:], expected) + + def test_multiline_not_highlighted(self): + cases = [ + (""" + assert ( + 1 > 2 + ) + """, + [ + ' 1 > 2', + 'AssertionError', + ], + ), + (""" + assert ( + 1 < 2 and + 3 > 4 + ) + """, + [ + ' 1 < 2 and', + 'AssertionError', + ], + ), + ] + for source, expected in cases: + with self.subTest(source): + result = self.write_source(source) + self.assertEqual(result[-2:], expected) + + class SyntaxErrorTests(unittest.TestCase): def test_range_of_offsets(self): cases = [ diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index 2e97de592712c0..d0473500a17735 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -7,9 +7,7 @@ import subprocess import sys from test import support -from test.support import os_helper -from test.support import script_helper, is_android -from test.support import skip_if_sanitizer +from test.support import os_helper, script_helper, is_android, MS_WINDOWS import tempfile import unittest from textwrap import dedent @@ -23,7 +21,6 @@ raise unittest.SkipTest("test module requires subprocess") TIMEOUT = 0.5 -MS_WINDOWS = (os.name == 'nt') def expected_traceback(lineno1, lineno2, header, min_count=1): @@ -36,7 +33,7 @@ def expected_traceback(lineno1, lineno2, header, min_count=1): return '^' + regex + '$' def skip_segfault_on_android(test): - # Issue #32138: Raising SIGSEGV on Android may not cause a crash. + # gh-76319: Raising SIGSEGV on Android may not cause a crash. return unittest.skipIf(is_android, 'raising SIGSEGV on Android is unreliable')(test) @@ -64,8 +61,16 @@ def get_output(self, code, filename=None, fd=None): pass_fds = [] if fd is not None: pass_fds.append(fd) + env = dict(os.environ) + + # Sanitizers must not handle SIGSEGV (ex: for test_enable_fd()) + option = 'handle_segv=0' + support.set_sanitizer_env_var(env, option) + with support.SuppressCrashReport(): - process = script_helper.spawn_python('-c', code, pass_fds=pass_fds) + process = script_helper.spawn_python('-c', code, + pass_fds=pass_fds, + env=env) with process: output, stderr = process.communicate() exitcode = process.wait() @@ -304,8 +309,6 @@ def test_gil_released(self): 3, 'Segmentation fault') - @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " - "builds change crashing process output.") @skip_segfault_on_android def test_enable_file(self): with temporary_filename() as filename: @@ -321,8 +324,6 @@ def test_enable_file(self): @unittest.skipIf(sys.platform == "win32", "subprocess doesn't support pass_fds on Windows") - @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " - "builds change crashing process output.") @skip_segfault_on_android def test_enable_fd(self): with tempfile.TemporaryFile('wb+') as fp: @@ -676,6 +677,7 @@ def test_dump_traceback_later_fd(self): with tempfile.TemporaryFile('wb+') as fp: self.check_dump_traceback_later(fd=fp.fileno()) + @support.requires_resource('walltime') def test_dump_traceback_later_twice(self): self.check_dump_traceback_later(loops=2) diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 5da75615b41d79..203dd6fe57dcd9 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -16,37 +16,6 @@ -def get_lockdata(): - try: - os.O_LARGEFILE - except AttributeError: - start_len = "ll" - else: - start_len = "qq" - - if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd')) - or sys.platform == 'darwin'): - if struct.calcsize('l') == 8: - off_t = 'l' - pid_t = 'i' - else: - off_t = 'lxxxx' - pid_t = 'l' - lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0, - fcntl.F_WRLCK, 0) - elif sys.platform.startswith('gnukfreebsd'): - lockdata = struct.pack('qqihhi', 0, 0, 0, fcntl.F_WRLCK, 0, 0) - elif sys.platform in ['hp-uxB', 'unixware7']: - lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) - else: - lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) - if lockdata: - if verbose: - print('struct.pack: ', repr(lockdata)) - return lockdata - -lockdata = get_lockdata() - class BadFile: def __init__(self, fn): self.fn = fn @@ -78,12 +47,43 @@ def tearDown(self): self.f.close() unlink(TESTFN) + @staticmethod + def get_lockdata(): + try: + os.O_LARGEFILE + except AttributeError: + start_len = "ll" + else: + start_len = "qq" + + if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd')) + or sys.platform == 'darwin'): + if struct.calcsize('l') == 8: + off_t = 'l' + pid_t = 'i' + else: + off_t = 'lxxxx' + pid_t = 'l' + lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0, + fcntl.F_WRLCK, 0) + elif sys.platform.startswith('gnukfreebsd'): + lockdata = struct.pack('qqihhi', 0, 0, 0, fcntl.F_WRLCK, 0, 0) + elif sys.platform in ['hp-uxB', 'unixware7']: + lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) + else: + lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) + if lockdata: + if verbose: + print('struct.pack: ', repr(lockdata)) + return lockdata + def test_fcntl_fileno(self): # the example from the library docs self.f = open(TESTFN, 'wb') rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) if verbose: print('Status from fcntl with O_NONBLOCK: ', rv) + lockdata = self.get_lockdata() rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETLKW, lockdata) if verbose: print('String from fcntl with F_SETLKW: ', repr(rv)) @@ -95,6 +95,7 @@ def test_fcntl_file_descriptor(self): rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK) if verbose: print('Status from fcntl with O_NONBLOCK: ', rv) + lockdata = self.get_lockdata() rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata) if verbose: print('String from fcntl with F_SETLKW: ', repr(rv)) diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index c4ee1e08251d63..b6daae7e9280ff 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -25,7 +25,7 @@ #locate file with float format test values test_dir = os.path.dirname(__file__) or os.curdir -format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') +format_testfile = os.path.join(test_dir, 'mathdata', 'formatfloat_testcases.txt') class FloatSubclass(float): pass @@ -733,8 +733,13 @@ def test_format_testfile(self): lhs, rhs = map(str.strip, line.split('->')) fmt, arg = lhs.split() - self.assertEqual(fmt % float(arg), rhs) - self.assertEqual(fmt % -float(arg), '-' + rhs) + f = float(arg) + self.assertEqual(fmt % f, rhs) + self.assertEqual(fmt % -f, '-' + rhs) + if fmt != '%r': + fmt2 = fmt[1:] + self.assertEqual(format(f, fmt2), rhs) + self.assertEqual(format(-f, fmt2), '-' + rhs) def test_issue5864(self): self.assertEqual(format(123.456, '.4'), '123.5') @@ -763,6 +768,7 @@ def test_issue35560(self): class ReprTestCase(unittest.TestCase): def test_repr(self): with open(os.path.join(os.path.split(__file__)[0], + 'mathdata', 'floating_points.txt'), encoding="utf-8") as floats_file: for line in floats_file: line = line.strip() diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index e112f49d2e7944..499e3b6e656faa 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -7,6 +7,7 @@ import operator import fractions import functools +import os import sys import typing import unittest @@ -15,6 +16,9 @@ from pickle import dumps, loads F = fractions.Fraction +#locate file with float format test values +test_dir = os.path.dirname(__file__) or os.curdir +format_testfile = os.path.join(test_dir, 'mathdata', 'formatfloat_testcases.txt') class DummyFloat(object): """Dummy float class for testing comparisons with Fractions""" @@ -1220,6 +1224,30 @@ def test_invalid_formats(self): with self.assertRaises(ValueError): format(fraction, spec) + @requires_IEEE_754 + def test_float_format_testfile(self): + with open(format_testfile, encoding="utf-8") as testfile: + for line in testfile: + if line.startswith('--'): + continue + line = line.strip() + if not line: + continue + + lhs, rhs = map(str.strip, line.split('->')) + fmt, arg = lhs.split() + if fmt == '%r': + continue + fmt2 = fmt[1:] + with self.subTest(fmt=fmt, arg=arg): + f = F(float(arg)) + self.assertEqual(format(f, fmt2), rhs) + if f: # skip negative zero + self.assertEqual(format(-f, fmt2), '-' + rhs) + f = F(arg) + self.assertEqual(float(format(f, fmt2)), float(rhs)) + self.assertEqual(float(format(-f, fmt2)), float('-' + rhs)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 6bb0144e9b1ed7..9491c7facdf077 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -322,7 +322,7 @@ def f(): sneaky_frame_object = None gc.enable() next(g) - # g.gi_frame should be the the frame object from the callback (the + # g.gi_frame should be the frame object from the callback (the # one that was *requested* second, but *created* first): self.assertIs(g.gi_frame, sneaky_frame_object) finally: diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index cb14bba2602def..dd8c2dd628ee13 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -514,6 +514,54 @@ def test_ast_fstring_empty_format_spec(self): self.assertEqual(type(format_spec), ast.JoinedStr) self.assertEqual(len(format_spec.values), 0) + def test_ast_fstring_format_spec(self): + expr = "f'{1:{name}}'" + + mod = ast.parse(expr) + self.assertEqual(type(mod), ast.Module) + self.assertEqual(len(mod.body), 1) + + fstring = mod.body[0].value + self.assertEqual(type(fstring), ast.JoinedStr) + self.assertEqual(len(fstring.values), 1) + + fv = fstring.values[0] + self.assertEqual(type(fv), ast.FormattedValue) + + format_spec = fv.format_spec + self.assertEqual(type(format_spec), ast.JoinedStr) + self.assertEqual(len(format_spec.values), 1) + + format_spec_value = format_spec.values[0] + self.assertEqual(type(format_spec_value), ast.FormattedValue) + self.assertEqual(format_spec_value.value.id, 'name') + + expr = "f'{1:{name1}{name2}}'" + + mod = ast.parse(expr) + self.assertEqual(type(mod), ast.Module) + self.assertEqual(len(mod.body), 1) + + fstring = mod.body[0].value + self.assertEqual(type(fstring), ast.JoinedStr) + self.assertEqual(len(fstring.values), 1) + + fv = fstring.values[0] + self.assertEqual(type(fv), ast.FormattedValue) + + format_spec = fv.format_spec + self.assertEqual(type(format_spec), ast.JoinedStr) + self.assertEqual(len(format_spec.values), 2) + + format_spec_value = format_spec.values[0] + self.assertEqual(type(format_spec_value), ast.FormattedValue) + self.assertEqual(format_spec_value.value.id, 'name1') + + format_spec_value = format_spec.values[1] + self.assertEqual(type(format_spec_value), ast.FormattedValue) + self.assertEqual(format_spec_value.value.id, 'name2') + + def test_docstring(self): def f(): f'''Not a docstring''' @@ -1027,6 +1075,10 @@ def test_lambda(self): "f'{lambda x:}'", "f'{lambda :}'", ]) + # Ensure the detection of invalid lambdas doesn't trigger detection + # for valid lambdas in the second error pass + with self.assertRaisesRegex(SyntaxError, "invalid syntax"): + compile("lambda name_3=f'{name_4}': {name_3}\n1 $ 1", "", "exec") # but don't emit the paren warning in general cases with self.assertRaisesRegex(SyntaxError, "f-string: expecting a valid expression after '{'"): @@ -1673,5 +1725,15 @@ def test_debug_in_file(self): self.assertEqual(stdout.decode('utf-8').strip().replace('\r\n', '\n').replace('\r', '\n'), "3\n=3") + def test_syntax_warning_infinite_recursion_in_file(self): + with temp_cwd(): + script = 'script.py' + with open(script, 'w') as f: + f.write(r"print(f'\{1}')") + + _, stdout, stderr = assert_python_ok(script) + self.assertIn(rb'\1', stdout) + self.assertEqual(len(stderr.strip().splitlines()), 2) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index 544228e3bab47b..2f191ea7a44c16 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -32,7 +32,7 @@ DEFAULT_ENCODING = 'utf-8' # the dummy data returned by server over the data channel when # RETR, LIST, NLST, MLSD commands are issued -RETR_DATA = 'abcde12345\r\n' * 1000 + 'non-ascii char \xAE\r\n' +RETR_DATA = 'abcde\xB9\xB2\xB3\xA4\xA6\r\n' * 1000 LIST_DATA = 'foo\r\nbar\r\n non-ascii char \xAE\r\n' NLST_DATA = 'foo\r\nbar\r\n non-ascii char \xAE\r\n' MLSD_DATA = ("type=cdir;perm=el;unique==keVO1+ZF4; test\r\n" @@ -67,11 +67,11 @@ class DummyDTPHandler(asynchat.async_chat): def __init__(self, conn, baseclass): asynchat.async_chat.__init__(self, conn) self.baseclass = baseclass - self.baseclass.last_received_data = '' + self.baseclass.last_received_data = bytearray() self.encoding = baseclass.encoding def handle_read(self): - new_data = self.recv(1024).decode(self.encoding, 'replace') + new_data = self.recv(1024) self.baseclass.last_received_data += new_data def handle_close(self): @@ -107,7 +107,7 @@ def __init__(self, conn, encoding=DEFAULT_ENCODING): self.in_buffer = [] self.dtp = None self.last_received_cmd = None - self.last_received_data = '' + self.last_received_data = bytearray() self.next_response = '' self.next_data = None self.rest = None @@ -325,8 +325,8 @@ def handle_error(self): if ssl is not None: - CERTFILE = os.path.join(os.path.dirname(__file__), "keycert3.pem") - CAFILE = os.path.join(os.path.dirname(__file__), "pycacert.pem") + CERTFILE = os.path.join(os.path.dirname(__file__), "certdata", "keycert3.pem") + CAFILE = os.path.join(os.path.dirname(__file__), "certdata", "pycacert.pem") class SSLConnection(asyncore.dispatcher): """An asyncore.dispatcher subclass supporting TLS/SSL.""" @@ -590,19 +590,17 @@ def test_abort(self): self.client.abort() def test_retrbinary(self): - def callback(data): - received.append(data.decode(self.client.encoding)) received = [] - self.client.retrbinary('retr', callback) - self.check_data(''.join(received), RETR_DATA) + self.client.retrbinary('retr', received.append) + self.check_data(b''.join(received), + RETR_DATA.encode(self.client.encoding)) def test_retrbinary_rest(self): - def callback(data): - received.append(data.decode(self.client.encoding)) for rest in (0, 10, 20): received = [] - self.client.retrbinary('retr', callback, rest=rest) - self.check_data(''.join(received), RETR_DATA[rest:]) + self.client.retrbinary('retr', received.append, rest=rest) + self.check_data(b''.join(received), + RETR_DATA[rest:].encode(self.client.encoding)) def test_retrlines(self): received = [] @@ -612,7 +610,8 @@ def test_retrlines(self): def test_storbinary(self): f = io.BytesIO(RETR_DATA.encode(self.client.encoding)) self.client.storbinary('stor', f) - self.check_data(self.server.handler_instance.last_received_data, RETR_DATA) + self.check_data(self.server.handler_instance.last_received_data, + RETR_DATA.encode(self.server.encoding)) # test new callback arg flag = [] f.seek(0) @@ -631,7 +630,8 @@ def test_storlines(self): data = RETR_DATA.replace('\r\n', '\n').encode(self.client.encoding) f = io.BytesIO(data) self.client.storlines('stor', f) - self.check_data(self.server.handler_instance.last_received_data, RETR_DATA) + self.check_data(self.server.handler_instance.last_received_data, + RETR_DATA.encode(self.server.encoding)) # test new callback arg flag = [] f.seek(0) @@ -649,7 +649,7 @@ def test_nlst(self): def test_dir(self): l = [] - self.client.dir(lambda x: l.append(x)) + self.client.dir(l.append) self.assertEqual(''.join(l), LIST_DATA.replace('\r\n', '')) def test_mlsd(self): @@ -889,12 +889,10 @@ def test_makepasv(self): def test_transfer(self): def retr(): - def callback(data): - received.append(data.decode(self.client.encoding)) received = [] - self.client.retrbinary('retr', callback) - self.assertEqual(len(''.join(received)), len(RETR_DATA)) - self.assertEqual(''.join(received), RETR_DATA) + self.client.retrbinary('retr', received.append) + self.assertEqual(b''.join(received), + RETR_DATA.encode(self.client.encoding)) self.client.set_pasv(True) retr() self.client.set_pasv(False) diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index e08d72877d8aef..35b473d5e9a0b4 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -194,16 +194,19 @@ def test___qualname__(self): def test___type_params__(self): def generic[T](): pass def not_generic(): pass + lambda_ = lambda: ... T, = generic.__type_params__ self.assertIsInstance(T, typing.TypeVar) self.assertEqual(generic.__type_params__, (T,)) - self.assertEqual(not_generic.__type_params__, ()) - with self.assertRaises(TypeError): - del not_generic.__type_params__ - with self.assertRaises(TypeError): - not_generic.__type_params__ = 42 - not_generic.__type_params__ = (T,) - self.assertEqual(not_generic.__type_params__, (T,)) + for func in (not_generic, lambda_): + with self.subTest(func=func): + self.assertEqual(func.__type_params__, ()) + with self.assertRaises(TypeError): + del func.__type_params__ + with self.assertRaises(TypeError): + func.__type_params__ = 42 + func.__type_params__ = (T,) + self.assertEqual(func.__type_params__, (T,)) def test___code__(self): num_one, num_two = 7, 8 diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index c4eca0f5b79511..e4de2c5ede15f1 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -26,10 +26,16 @@ py_functools = import_helper.import_fresh_module('functools', blocked=['_functools']) -c_functools = import_helper.import_fresh_module('functools') +c_functools = import_helper.import_fresh_module('functools', + fresh=['_functools']) decimal = import_helper.import_fresh_module('decimal', fresh=['_decimal']) +_partial_types = [py_functools.partial] +if c_functools: + _partial_types.append(c_functools.partial) + + @contextlib.contextmanager def replaced_module(name, replacement): original_module = sys.modules[name] @@ -201,7 +207,7 @@ def test_repr(self): kwargs = {'a': object(), 'b': object()} kwargs_reprs = ['a={a!r}, b={b!r}'.format_map(kwargs), 'b={b!r}, a={a!r}'.format_map(kwargs)] - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -223,7 +229,7 @@ def test_repr(self): for kwargs_repr in kwargs_reprs]) def test_recursive_repr(self): - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -250,7 +256,7 @@ def test_recursive_repr(self): f.__setstate__((capture, (), {}, {})) def test_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(signature, ['asdf'], bar=[True]) f.attr = [] for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -333,7 +339,7 @@ def test_setstate_subclasses(self): self.assertIs(type(r[0]), tuple) def test_recursive_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(capture) f.__setstate__((f, (), {}, {})) try: @@ -387,14 +393,9 @@ def __getitem__(self, key): @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): if c_functools: + module = c_functools partial = c_functools.partial - class AllowPickle: - def __enter__(self): - return self - def __exit__(self, type, value, tb): - return False - def test_attributes_unwritable(self): # attributes should not be writable p = self.partial(capture, 1, 2, a=10, b=20) @@ -437,15 +438,9 @@ def __str__(self): class TestPartialPy(TestPartial, unittest.TestCase): + module = py_functools partial = py_functools.partial - class AllowPickle: - def __init__(self): - self._cm = replaced_module("functools", py_functools) - def __enter__(self): - return self._cm.__enter__() - def __exit__(self, type, value, tb): - return self._cm.__exit__(type, value, tb) if c_functools: class CPartialSubclass(c_functools.partial): @@ -1872,9 +1867,10 @@ def orig(): ... def py_cached_func(x, y): return 3 * x + y -@c_functools.lru_cache() -def c_cached_func(x, y): - return 3 * x + y +if c_functools: + @c_functools.lru_cache() + def c_cached_func(x, y): + return 3 * x + y class TestLRUPy(TestLRU, unittest.TestCase): @@ -1891,18 +1887,20 @@ def cached_staticmeth(x, y): return 3 * x + y +@unittest.skipUnless(c_functools, 'requires the C _functools module') class TestLRUC(TestLRU, unittest.TestCase): - module = c_functools - cached_func = c_cached_func, + if c_functools: + module = c_functools + cached_func = c_cached_func, - @module.lru_cache() - def cached_meth(self, x, y): - return 3 * x + y + @module.lru_cache() + def cached_meth(self, x, y): + return 3 * x + y - @staticmethod - @module.lru_cache() - def cached_staticmeth(x, y): - return 3 * x + y + @staticmethod + @module.lru_cache() + def cached_staticmeth(x, y): + return 3 * x + y class TestSingleDispatch(unittest.TestCase): @@ -2474,6 +2472,74 @@ def _(arg): self.assertTrue(A.t('')) self.assertEqual(A.t(0.0), 0.0) + def test_slotted_class(self): + class Slot: + __slots__ = ('a', 'b') + @functools.singledispatchmethod + def go(self, item, arg): + pass + + @go.register + def _(self, item: int, arg): + return item + arg + + s = Slot() + self.assertEqual(s.go(1, 1), 2) + + def test_classmethod_slotted_class(self): + class Slot: + __slots__ = ('a', 'b') + @functools.singledispatchmethod + @classmethod + def go(cls, item, arg): + pass + + @go.register + @classmethod + def _(cls, item: int, arg): + return item + arg + + s = Slot() + self.assertEqual(s.go(1, 1), 2) + self.assertEqual(Slot.go(1, 1), 2) + + def test_staticmethod_slotted_class(self): + class A: + __slots__ = ['a'] + @functools.singledispatchmethod + @staticmethod + def t(arg): + return arg + @t.register(int) + @staticmethod + def _(arg): + return isinstance(arg, int) + @t.register(str) + @staticmethod + def _(arg): + return isinstance(arg, str) + a = A() + + self.assertTrue(A.t(0)) + self.assertTrue(A.t('')) + self.assertEqual(A.t(0.0), 0.0) + self.assertTrue(a.t(0)) + self.assertTrue(a.t('')) + self.assertEqual(a.t(0.0), 0.0) + + def test_assignment_behavior(self): + # see gh-106448 + class A: + @functools.singledispatchmethod + def t(arg): + return arg + + a = A() + a.t.foo = 'bar' + a2 = A() + with self.assertRaises(AttributeError): + a2.t.foo + def test_classmethod_register(self): class A: def __init__(self, arg): @@ -3037,6 +3103,9 @@ def test_access_from_class(self): def test_doc(self): self.assertEqual(CachedCostItem.cost.__doc__, "The cost of the item.") + def test_module(self): + self.assertEqual(CachedCostItem.cost.__module__, CachedCostItem.__module__) + def test_subclass_with___set__(self): """Caching still works for a subclass defining __set__.""" class readonly_cached_property(py_functools.cached_property): diff --git a/Lib/test/test_future_stmt/__init__.py b/Lib/test/test_future_stmt/__init__.py new file mode 100644 index 00000000000000..f2a39a3fe29c7f --- /dev/null +++ b/Lib/test/test_future_stmt/__init__.py @@ -0,0 +1,6 @@ +import os +from test import support + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/badsyntax_future10.py b/Lib/test/test_future_stmt/badsyntax_future.py similarity index 100% rename from Lib/test/badsyntax_future10.py rename to Lib/test/test_future_stmt/badsyntax_future.py diff --git a/Lib/test/future_test1.py b/Lib/test/test_future_stmt/import_nested_scope_twice.py similarity index 100% rename from Lib/test/future_test1.py rename to Lib/test/test_future_stmt/import_nested_scope_twice.py diff --git a/Lib/test/future_test2.py b/Lib/test/test_future_stmt/nested_scope.py similarity index 100% rename from Lib/test/future_test2.py rename to Lib/test/test_future_stmt/nested_scope.py diff --git a/Lib/test/test_future.py b/Lib/test/test_future_stmt/test_future.py similarity index 74% rename from Lib/test/test_future.py rename to Lib/test/test_future_stmt/test_future.py index 4730bfafbd9cfe..2c8ceb664cb362 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -10,6 +10,8 @@ import re import sys +TOP_LEVEL_MSG = 'from __future__ imports must occur at the beginning of the file' + rx = re.compile(r'\((\S+).py, line (\d+)') def get_error_location(msg): @@ -18,65 +20,141 @@ def get_error_location(msg): class FutureTest(unittest.TestCase): - def check_syntax_error(self, err, basename, lineno, offset=1): - self.assertIn('%s.py, line %d' % (basename, lineno), str(err)) - self.assertEqual(os.path.basename(err.filename), basename + '.py') + def check_syntax_error(self, err, basename, + *, + lineno, + message=TOP_LEVEL_MSG, offset=1): + if basename != '': + basename += '.py' + + self.assertEqual(f'{message} ({basename}, line {lineno})', str(err)) + self.assertEqual(os.path.basename(err.filename), basename) self.assertEqual(err.lineno, lineno) self.assertEqual(err.offset, offset) - def test_future1(self): - with import_helper.CleanImport('future_test1'): - from test import future_test1 - self.assertEqual(future_test1.result, 6) + def assertSyntaxError(self, code, + *, + lineno=1, + message=TOP_LEVEL_MSG, offset=1, + parametrize_docstring=True): + code = dedent(code.lstrip('\n')) + for add_docstring in ([False, True] if parametrize_docstring else [False]): + with self.subTest(code=code, add_docstring=add_docstring): + if add_docstring: + code = '"""Docstring"""\n' + code + lineno += 1 + with self.assertRaises(SyntaxError) as cm: + exec(code) + self.check_syntax_error(cm.exception, "", + lineno=lineno, + message=message, + offset=offset) + + def test_import_nested_scope_twice(self): + # Import the name nested_scopes twice to trigger SF bug #407394 + with import_helper.CleanImport( + 'test.test_future_stmt.import_nested_scope_twice', + ): + from test.test_future_stmt import import_nested_scope_twice + self.assertEqual(import_nested_scope_twice.result, 6) + + def test_nested_scope(self): + with import_helper.CleanImport('test.test_future_stmt.nested_scope'): + from test.test_future_stmt import nested_scope + self.assertEqual(nested_scope.result, 6) + + def test_future_single_import(self): + with import_helper.CleanImport( + 'test.test_future_stmt.test_future_single_import', + ): + from test.test_future_stmt import test_future_single_import + + def test_future_multiple_imports(self): + with import_helper.CleanImport( + 'test.test_future_stmt.test_future_multiple_imports', + ): + from test.test_future_stmt import test_future_multiple_imports + + def test_future_multiple_features(self): + with import_helper.CleanImport( + "test.test_future_stmt.test_future_multiple_features", + ): + from test.test_future_stmt import test_future_multiple_features + + def test_unknown_future_flag(self): + code = """ + from __future__ import nested_scopes + from __future__ import rested_snopes # typo error here: nested => rested + """ + self.assertSyntaxError( + code, lineno=2, + message='future feature rested_snopes is not defined', + ) - def test_future2(self): - with import_helper.CleanImport('future_test2'): - from test import future_test2 - self.assertEqual(future_test2.result, 6) + def test_future_import_not_on_top(self): + code = """ + import some_module + from __future__ import annotations + """ + self.assertSyntaxError(code, lineno=2) - def test_future3(self): - with import_helper.CleanImport('test_future3'): - from test import test_future3 + code = """ + import __future__ + from __future__ import annotations + """ + self.assertSyntaxError(code, lineno=2) - def test_badfuture3(self): - with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future3 - self.check_syntax_error(cm.exception, "badsyntax_future3", 3) + code = """ + from __future__ import absolute_import + "spam, bar, blah" + from __future__ import print_function + """ + self.assertSyntaxError(code, lineno=3) - def test_badfuture4(self): - with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future4 - self.check_syntax_error(cm.exception, "badsyntax_future4", 3) + def test_future_import_with_extra_string(self): + code = """ + '''Docstring''' + "this isn't a doc string" + from __future__ import nested_scopes + """ + self.assertSyntaxError(code, lineno=3, parametrize_docstring=False) - def test_badfuture5(self): - with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future5 - self.check_syntax_error(cm.exception, "badsyntax_future5", 4) + def test_multiple_import_statements_on_same_line(self): + # With `\`: + code = """ + from __future__ import nested_scopes; import string; from __future__ import \ + nested_scopes + """ + self.assertSyntaxError(code, offset=54) - def test_badfuture6(self): - with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future6 - self.check_syntax_error(cm.exception, "badsyntax_future6", 3) + # Without `\`: + code = """ + from __future__ import nested_scopes; import string; from __future__ import nested_scopes + """ + self.assertSyntaxError(code, offset=54) - def test_badfuture7(self): - with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future7 - self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 54) + def test_future_import_star(self): + code = """ + from __future__ import * + """ + self.assertSyntaxError(code, message='future feature * is not defined') - def test_badfuture8(self): - with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future8 - self.check_syntax_error(cm.exception, "badsyntax_future8", 3) + def test_future_import_braces(self): + code = """ + from __future__ import braces + """ + # Congrats, you found an easter egg! + self.assertSyntaxError(code, message='not a chance') - def test_badfuture9(self): - with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future9 - self.check_syntax_error(cm.exception, "badsyntax_future9", 3) + code = """ + from __future__ import nested_scopes, braces + """ + self.assertSyntaxError(code, message='not a chance') - def test_badfuture10(self): + def test_module_with_future_import_not_on_top(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future10 - self.check_syntax_error(cm.exception, "badsyntax_future10", 3) + from test.test_future_stmt import badsyntax_future + self.check_syntax_error(cm.exception, "badsyntax_future", lineno=3) def test_ensure_flags_dont_clash(self): # bpo-39562: test that future flags and compiler flags doesn't clash @@ -113,10 +191,6 @@ def test_parserhack(self): else: self.fail("syntax error didn't occur") - def test_multiple_features(self): - with import_helper.CleanImport("test.test_future5"): - from test import test_future5 - def test_unicode_literals_exec(self): scope = {} exec("from __future__ import unicode_literals; x = ''", {}, scope) diff --git a/Lib/test/test___future__.py b/Lib/test/test_future_stmt/test_future_flags.py similarity index 100% rename from Lib/test/test___future__.py rename to Lib/test/test_future_stmt/test_future_flags.py diff --git a/Lib/test/test_future5.py b/Lib/test/test_future_stmt/test_future_multiple_features.py similarity index 100% rename from Lib/test/test_future5.py rename to Lib/test/test_future_stmt/test_future_multiple_features.py diff --git a/Lib/test/test_future4.py b/Lib/test/test_future_stmt/test_future_multiple_imports.py similarity index 100% rename from Lib/test/test_future4.py rename to Lib/test/test_future_stmt/test_future_multiple_imports.py diff --git a/Lib/test/test_future3.py b/Lib/test/test_future_stmt/test_future_single_import.py similarity index 100% rename from Lib/test/test_future3.py rename to Lib/test/test_future_stmt/test_future_single_import.py diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py deleted file mode 100644 index 85009089f21d2f..00000000000000 --- a/Lib/test/test_gdb.py +++ /dev/null @@ -1,1052 +0,0 @@ -# Verify that gdb can pretty-print the various PyObject* types -# -# The code for testing gdb was adapted from similar work in Unladen Swallow's -# Lib/test/test_jit_gdb.py - -import os -import platform -import re -import subprocess -import sys -import sysconfig -import textwrap -import unittest - -from test import support -from test.support import findfile, python_is_optimized - -def get_gdb_version(): - try: - cmd = ["gdb", "-nx", "--version"] - proc = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) - with proc: - version, stderr = proc.communicate() - - if proc.returncode: - raise Exception(f"Command {' '.join(cmd)!r} failed " - f"with exit code {proc.returncode}: " - f"stdout={version!r} stderr={stderr!r}") - except OSError: - # This is what "no gdb" looks like. There may, however, be other - # errors that manifest this way too. - raise unittest.SkipTest("Couldn't find gdb on the path") - - # Regex to parse: - # 'GNU gdb (GDB; SUSE Linux Enterprise 12) 7.7\n' -> 7.7 - # 'GNU gdb (GDB) Fedora 7.9.1-17.fc22\n' -> 7.9 - # 'GNU gdb 6.1.1 [FreeBSD]\n' -> 6.1 - # 'GNU gdb (GDB) Fedora (7.5.1-37.fc18)\n' -> 7.5 - # 'HP gdb 6.7 for HP Itanium (32 or 64 bit) and target HP-UX 11iv2 and 11iv3.\n' -> 6.7 - match = re.search(r"^(?:GNU|HP) gdb.*?\b(\d+)\.(\d+)", version) - if match is None: - raise Exception("unable to parse GDB version: %r" % version) - return (version, int(match.group(1)), int(match.group(2))) - -gdb_version, gdb_major_version, gdb_minor_version = get_gdb_version() -if gdb_major_version < 7: - raise unittest.SkipTest("gdb versions before 7.0 didn't support python " - "embedding. Saw %s.%s:\n%s" - % (gdb_major_version, gdb_minor_version, - gdb_version)) - -if not sysconfig.is_python_build(): - raise unittest.SkipTest("test_gdb only works on source builds at the moment.") - -if 'Clang' in platform.python_compiler() and sys.platform == 'darwin': - raise unittest.SkipTest("test_gdb doesn't work correctly when python is" - " built with LLVM clang") - -if ((sysconfig.get_config_var('PGO_PROF_USE_FLAG') or 'xxx') in - (sysconfig.get_config_var('PY_CORE_CFLAGS') or '')): - raise unittest.SkipTest("test_gdb is not reliable on PGO builds") - -# Location of custom hooks file in a repository checkout. -checkout_hook_path = os.path.join(os.path.dirname(sys.executable), - 'python-gdb.py') - -PYTHONHASHSEED = '123' - - -def cet_protection(): - cflags = sysconfig.get_config_var('CFLAGS') - if not cflags: - return False - flags = cflags.split() - # True if "-mcet -fcf-protection" options are found, but false - # if "-fcf-protection=none" or "-fcf-protection=return" is found. - return (('-mcet' in flags) - and any((flag.startswith('-fcf-protection') - and not flag.endswith(("=none", "=return"))) - for flag in flags)) - -# Control-flow enforcement technology -CET_PROTECTION = cet_protection() - - -def run_gdb(*args, **env_vars): - """Runs gdb in --batch mode with the additional arguments given by *args. - - Returns its (stdout, stderr) decoded from utf-8 using the replace handler. - """ - if env_vars: - env = os.environ.copy() - env.update(env_vars) - else: - env = None - # -nx: Do not execute commands from any .gdbinit initialization files - # (issue #22188) - base_cmd = ('gdb', '--batch', '-nx') - if (gdb_major_version, gdb_minor_version) >= (7, 4): - base_cmd += ('-iex', 'add-auto-load-safe-path ' + checkout_hook_path) - proc = subprocess.Popen(base_cmd + args, - # Redirect stdin to prevent GDB from messing with - # the terminal settings - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=env) - with proc: - out, err = proc.communicate() - return out.decode('utf-8', 'replace'), err.decode('utf-8', 'replace') - -# Verify that "gdb" was built with the embedded python support enabled: -gdbpy_version, _ = run_gdb("--eval-command=python import sys; print(sys.version_info)") -if not gdbpy_version: - raise unittest.SkipTest("gdb not built with embedded python support") - -if "major=2" in gdbpy_version: - raise unittest.SkipTest("gdb built with Python 2") - -# Verify that "gdb" can load our custom hooks, as OS security settings may -# disallow this without a customized .gdbinit. -_, gdbpy_errors = run_gdb('--args', sys.executable) -if "auto-loading has been declined" in gdbpy_errors: - msg = "gdb security settings prevent use of custom hooks: " - raise unittest.SkipTest(msg + gdbpy_errors.rstrip()) - -def gdb_has_frame_select(): - # Does this build of gdb have gdb.Frame.select ? - stdout, _ = run_gdb("--eval-command=python print(dir(gdb.Frame))") - m = re.match(r'.*\[(.*)\].*', stdout) - if not m: - raise unittest.SkipTest("Unable to parse output from gdb.Frame.select test") - gdb_frame_dir = m.group(1).split(', ') - return "'select'" in gdb_frame_dir - -HAS_PYUP_PYDOWN = gdb_has_frame_select() - -BREAKPOINT_FN='builtin_id' - -@unittest.skipIf(support.PGO, "not useful for PGO") -class DebuggerTests(unittest.TestCase): - - """Test that the debugger can debug Python.""" - - def get_stack_trace(self, source=None, script=None, - breakpoint=BREAKPOINT_FN, - cmds_after_breakpoint=None, - import_site=False, - ignore_stderr=False): - ''' - Run 'python -c SOURCE' under gdb with a breakpoint. - - Support injecting commands after the breakpoint is reached - - Returns the stdout from gdb - - cmds_after_breakpoint: if provided, a list of strings: gdb commands - ''' - # We use "set breakpoint pending yes" to avoid blocking with a: - # Function "foo" not defined. - # Make breakpoint pending on future shared library load? (y or [n]) - # error, which typically happens python is dynamically linked (the - # breakpoints of interest are to be found in the shared library) - # When this happens, we still get: - # Function "textiowrapper_write" not defined. - # emitted to stderr each time, alas. - - # Initially I had "--eval-command=continue" here, but removed it to - # avoid repeated print breakpoints when traversing hierarchical data - # structures - - # Generate a list of commands in gdb's language: - commands = ['set breakpoint pending yes', - 'break %s' % breakpoint, - - # The tests assume that the first frame of printed - # backtrace will not contain program counter, - # that is however not guaranteed by gdb - # therefore we need to use 'set print address off' to - # make sure the counter is not there. For example: - # #0 in PyObject_Print ... - # is assumed, but sometimes this can be e.g. - # #0 0x00003fffb7dd1798 in PyObject_Print ... - 'set print address off', - - 'run'] - - # GDB as of 7.4 onwards can distinguish between the - # value of a variable at entry vs current value: - # http://sourceware.org/gdb/onlinedocs/gdb/Variables.html - # which leads to the selftests failing with errors like this: - # AssertionError: 'v@entry=()' != '()' - # Disable this: - if (gdb_major_version, gdb_minor_version) >= (7, 4): - commands += ['set print entry-values no'] - - if cmds_after_breakpoint: - if CET_PROTECTION: - # bpo-32962: When Python is compiled with -mcet - # -fcf-protection, function arguments are unusable before - # running the first instruction of the function entry point. - # The 'next' command makes the required first step. - commands += ['next'] - commands += cmds_after_breakpoint - else: - commands += ['backtrace'] - - # print commands - - # Use "commands" to generate the arguments with which to invoke "gdb": - args = ['--eval-command=%s' % cmd for cmd in commands] - args += ["--args", - sys.executable] - args.extend(subprocess._args_from_interpreter_flags()) - - if not import_site: - # -S suppresses the default 'import site' - args += ["-S"] - - if source: - args += ["-c", source] - elif script: - args += [script] - - # Use "args" to invoke gdb, capturing stdout, stderr: - out, err = run_gdb(*args, PYTHONHASHSEED=PYTHONHASHSEED) - - if not ignore_stderr: - for line in err.splitlines(): - print(line, file=sys.stderr) - - # bpo-34007: Sometimes some versions of the shared libraries that - # are part of the traceback are compiled in optimised mode and the - # Program Counter (PC) is not present, not allowing gdb to walk the - # frames back. When this happens, the Python bindings of gdb raise - # an exception, making the test impossible to succeed. - if "PC not saved" in err: - raise unittest.SkipTest("gdb cannot walk the frame object" - " because the Program Counter is" - " not present") - - # bpo-40019: Skip the test if gdb failed to read debug information - # because the Python binary is optimized. - for pattern in ( - '(frame information optimized out)', - 'Unable to read information on python frame', - ): - if pattern in out: - raise unittest.SkipTest(f"{pattern!r} found in gdb output") - - return out - - def get_gdb_repr(self, source, - cmds_after_breakpoint=None, - import_site=False): - # Given an input python source representation of data, - # run "python -c'id(DATA)'" under gdb with a breakpoint on - # builtin_id and scrape out gdb's representation of the "op" - # parameter, and verify that the gdb displays the same string - # - # Verify that the gdb displays the expected string - # - # For a nested structure, the first time we hit the breakpoint will - # give us the top-level structure - - # NOTE: avoid decoding too much of the traceback as some - # undecodable characters may lurk there in optimized mode - # (issue #19743). - cmds_after_breakpoint = cmds_after_breakpoint or ["backtrace 1"] - gdb_output = self.get_stack_trace(source, breakpoint=BREAKPOINT_FN, - cmds_after_breakpoint=cmds_after_breakpoint, - import_site=import_site) - # gdb can insert additional '\n' and space characters in various places - # in its output, depending on the width of the terminal it's connected - # to (using its "wrap_here" function) - m = re.search( - # Match '#0 builtin_id(self=..., v=...)' - r'#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)?\)' - # Match ' at Python/bltinmodule.c'. - # bpo-38239: builtin_id() is defined in Python/bltinmodule.c, - # but accept any "Directory\file.c" to support Link Time - # Optimization (LTO). - r'\s+at\s+\S*[A-Za-z]+/[A-Za-z0-9_-]+\.c', - gdb_output, re.DOTALL) - if not m: - self.fail('Unexpected gdb output: %r\n%s' % (gdb_output, gdb_output)) - return m.group(1), gdb_output - - def assertEndsWith(self, actual, exp_end): - '''Ensure that the given "actual" string ends with "exp_end"''' - self.assertTrue(actual.endswith(exp_end), - msg='%r did not end with %r' % (actual, exp_end)) - - def assertMultilineMatches(self, actual, pattern): - m = re.match(pattern, actual, re.DOTALL) - if not m: - self.fail(msg='%r did not match %r' % (actual, pattern)) - - def get_sample_script(self): - return findfile('gdb_sample.py') - -class PrettyPrintTests(DebuggerTests): - def test_getting_backtrace(self): - gdb_output = self.get_stack_trace('id(42)') - self.assertTrue(BREAKPOINT_FN in gdb_output) - - def assertGdbRepr(self, val, exp_repr=None): - # Ensure that gdb's rendering of the value in a debugged process - # matches repr(value) in this process: - gdb_repr, gdb_output = self.get_gdb_repr('id(' + ascii(val) + ')') - if not exp_repr: - exp_repr = repr(val) - self.assertEqual(gdb_repr, exp_repr, - ('%r did not equal expected %r; full output was:\n%s' - % (gdb_repr, exp_repr, gdb_output))) - - def test_int(self): - 'Verify the pretty-printing of various int values' - self.assertGdbRepr(42) - self.assertGdbRepr(0) - self.assertGdbRepr(-7) - self.assertGdbRepr(1000000000000) - self.assertGdbRepr(-1000000000000000) - - def test_singletons(self): - 'Verify the pretty-printing of True, False and None' - self.assertGdbRepr(True) - self.assertGdbRepr(False) - self.assertGdbRepr(None) - - def test_dicts(self): - 'Verify the pretty-printing of dictionaries' - self.assertGdbRepr({}) - self.assertGdbRepr({'foo': 'bar'}, "{'foo': 'bar'}") - # Python preserves insertion order since 3.6 - self.assertGdbRepr({'foo': 'bar', 'douglas': 42}, "{'foo': 'bar', 'douglas': 42}") - - def test_lists(self): - 'Verify the pretty-printing of lists' - self.assertGdbRepr([]) - self.assertGdbRepr(list(range(5))) - - def test_bytes(self): - 'Verify the pretty-printing of bytes' - self.assertGdbRepr(b'') - self.assertGdbRepr(b'And now for something hopefully the same') - self.assertGdbRepr(b'string with embedded NUL here \0 and then some more text') - self.assertGdbRepr(b'this is a tab:\t' - b' this is a slash-N:\n' - b' this is a slash-R:\r' - ) - - self.assertGdbRepr(b'this is byte 255:\xff and byte 128:\x80') - - self.assertGdbRepr(bytes([b for b in range(255)])) - - def test_strings(self): - 'Verify the pretty-printing of unicode strings' - # We cannot simply call locale.getpreferredencoding() here, - # as GDB might have been linked against a different version - # of Python with a different encoding and coercion policy - # with respect to PEP 538 and PEP 540. - out, err = run_gdb( - '--eval-command', - 'python import locale; print(locale.getpreferredencoding())') - - encoding = out.rstrip() - if err or not encoding: - raise RuntimeError( - f'unable to determine the preferred encoding ' - f'of embedded Python in GDB: {err}') - - def check_repr(text): - try: - text.encode(encoding) - except UnicodeEncodeError: - self.assertGdbRepr(text, ascii(text)) - else: - self.assertGdbRepr(text) - - self.assertGdbRepr('') - self.assertGdbRepr('And now for something hopefully the same') - self.assertGdbRepr('string with embedded NUL here \0 and then some more text') - - # Test printing a single character: - # U+2620 SKULL AND CROSSBONES - check_repr('\u2620') - - # Test printing a Japanese unicode string - # (I believe this reads "mojibake", using 3 characters from the CJK - # Unified Ideographs area, followed by U+3051 HIRAGANA LETTER KE) - check_repr('\u6587\u5b57\u5316\u3051') - - # Test a character outside the BMP: - # U+1D121 MUSICAL SYMBOL C CLEF - # This is: - # UTF-8: 0xF0 0x9D 0x84 0xA1 - # UTF-16: 0xD834 0xDD21 - check_repr(chr(0x1D121)) - - def test_tuples(self): - 'Verify the pretty-printing of tuples' - self.assertGdbRepr(tuple(), '()') - self.assertGdbRepr((1,), '(1,)') - self.assertGdbRepr(('foo', 'bar', 'baz')) - - def test_sets(self): - 'Verify the pretty-printing of sets' - if (gdb_major_version, gdb_minor_version) < (7, 3): - self.skipTest("pretty-printing of sets needs gdb 7.3 or later") - self.assertGdbRepr(set(), "set()") - self.assertGdbRepr(set(['a']), "{'a'}") - # PYTHONHASHSEED is need to get the exact frozenset item order - if not sys.flags.ignore_environment: - self.assertGdbRepr(set(['a', 'b']), "{'a', 'b'}") - self.assertGdbRepr(set([4, 5, 6]), "{4, 5, 6}") - - # Ensure that we handle sets containing the "dummy" key value, - # which happens on deletion: - gdb_repr, gdb_output = self.get_gdb_repr('''s = set(['a','b']) -s.remove('a') -id(s)''') - self.assertEqual(gdb_repr, "{'b'}") - - def test_frozensets(self): - 'Verify the pretty-printing of frozensets' - if (gdb_major_version, gdb_minor_version) < (7, 3): - self.skipTest("pretty-printing of frozensets needs gdb 7.3 or later") - self.assertGdbRepr(frozenset(), "frozenset()") - self.assertGdbRepr(frozenset(['a']), "frozenset({'a'})") - # PYTHONHASHSEED is need to get the exact frozenset item order - if not sys.flags.ignore_environment: - self.assertGdbRepr(frozenset(['a', 'b']), "frozenset({'a', 'b'})") - self.assertGdbRepr(frozenset([4, 5, 6]), "frozenset({4, 5, 6})") - - def test_exceptions(self): - # Test a RuntimeError - gdb_repr, gdb_output = self.get_gdb_repr(''' -try: - raise RuntimeError("I am an error") -except RuntimeError as e: - id(e) -''') - self.assertEqual(gdb_repr, - "RuntimeError('I am an error',)") - - - # Test division by zero: - gdb_repr, gdb_output = self.get_gdb_repr(''' -try: - a = 1 / 0 -except ZeroDivisionError as e: - id(e) -''') - self.assertEqual(gdb_repr, - "ZeroDivisionError('division by zero',)") - - def test_modern_class(self): - 'Verify the pretty-printing of new-style class instances' - gdb_repr, gdb_output = self.get_gdb_repr(''' -class Foo: - pass -foo = Foo() -foo.an_int = 42 -id(foo)''') - m = re.match(r'', gdb_repr) - self.assertTrue(m, - msg='Unexpected new-style class rendering %r' % gdb_repr) - - def test_subclassing_list(self): - 'Verify the pretty-printing of an instance of a list subclass' - gdb_repr, gdb_output = self.get_gdb_repr(''' -class Foo(list): - pass -foo = Foo() -foo += [1, 2, 3] -foo.an_int = 42 -id(foo)''') - m = re.match(r'', gdb_repr) - - self.assertTrue(m, - msg='Unexpected new-style class rendering %r' % gdb_repr) - - def test_subclassing_tuple(self): - 'Verify the pretty-printing of an instance of a tuple subclass' - # This should exercise the negative tp_dictoffset code in the - # new-style class support - gdb_repr, gdb_output = self.get_gdb_repr(''' -class Foo(tuple): - pass -foo = Foo((1, 2, 3)) -foo.an_int = 42 -id(foo)''') - m = re.match(r'', gdb_repr) - - self.assertTrue(m, - msg='Unexpected new-style class rendering %r' % gdb_repr) - - def assertSane(self, source, corruption, exprepr=None): - '''Run Python under gdb, corrupting variables in the inferior process - immediately before taking a backtrace. - - Verify that the variable's representation is the expected failsafe - representation''' - if corruption: - cmds_after_breakpoint=[corruption, 'backtrace'] - else: - cmds_after_breakpoint=['backtrace'] - - gdb_repr, gdb_output = \ - self.get_gdb_repr(source, - cmds_after_breakpoint=cmds_after_breakpoint) - if exprepr: - if gdb_repr == exprepr: - # gdb managed to print the value in spite of the corruption; - # this is good (see http://bugs.python.org/issue8330) - return - - # Match anything for the type name; 0xDEADBEEF could point to - # something arbitrary (see http://bugs.python.org/issue8330) - pattern = '<.* at remote 0x-?[0-9a-f]+>' - - m = re.match(pattern, gdb_repr) - if not m: - self.fail('Unexpected gdb representation: %r\n%s' % \ - (gdb_repr, gdb_output)) - - def test_NULL_ptr(self): - 'Ensure that a NULL PyObject* is handled gracefully' - gdb_repr, gdb_output = ( - self.get_gdb_repr('id(42)', - cmds_after_breakpoint=['set variable v=0', - 'backtrace']) - ) - - self.assertEqual(gdb_repr, '0x0') - - def test_NULL_ob_type(self): - 'Ensure that a PyObject* with NULL ob_type is handled gracefully' - self.assertSane('id(42)', - 'set v->ob_type=0') - - def test_corrupt_ob_type(self): - 'Ensure that a PyObject* with a corrupt ob_type is handled gracefully' - self.assertSane('id(42)', - 'set v->ob_type=0xDEADBEEF', - exprepr='42') - - def test_corrupt_tp_flags(self): - 'Ensure that a PyObject* with a type with corrupt tp_flags is handled' - self.assertSane('id(42)', - 'set v->ob_type->tp_flags=0x0', - exprepr='42') - - def test_corrupt_tp_name(self): - 'Ensure that a PyObject* with a type with corrupt tp_name is handled' - self.assertSane('id(42)', - 'set v->ob_type->tp_name=0xDEADBEEF', - exprepr='42') - - def test_builtins_help(self): - 'Ensure that the new-style class _Helper in site.py can be handled' - - if sys.flags.no_site: - self.skipTest("need site module, but -S option was used") - - # (this was the issue causing tracebacks in - # http://bugs.python.org/issue8032#msg100537 ) - gdb_repr, gdb_output = self.get_gdb_repr('id(__builtins__.help)', import_site=True) - - m = re.match(r'<_Helper\(\) at remote 0x-?[0-9a-f]+>', gdb_repr) - self.assertTrue(m, - msg='Unexpected rendering %r' % gdb_repr) - - def test_selfreferential_list(self): - '''Ensure that a reference loop involving a list doesn't lead proxyval - into an infinite loop:''' - gdb_repr, gdb_output = \ - self.get_gdb_repr("a = [3, 4, 5] ; a.append(a) ; id(a)") - self.assertEqual(gdb_repr, '[3, 4, 5, [...]]') - - gdb_repr, gdb_output = \ - self.get_gdb_repr("a = [3, 4, 5] ; b = [a] ; a.append(b) ; id(a)") - self.assertEqual(gdb_repr, '[3, 4, 5, [[...]]]') - - def test_selfreferential_dict(self): - '''Ensure that a reference loop involving a dict doesn't lead proxyval - into an infinite loop:''' - gdb_repr, gdb_output = \ - self.get_gdb_repr("a = {} ; b = {'bar':a} ; a['foo'] = b ; id(a)") - - self.assertEqual(gdb_repr, "{'foo': {'bar': {...}}}") - - def test_selfreferential_old_style_instance(self): - gdb_repr, gdb_output = \ - self.get_gdb_repr(''' -class Foo: - pass -foo = Foo() -foo.an_attr = foo -id(foo)''') - self.assertTrue(re.match(r'\) at remote 0x-?[0-9a-f]+>', - gdb_repr), - 'Unexpected gdb representation: %r\n%s' % \ - (gdb_repr, gdb_output)) - - def test_selfreferential_new_style_instance(self): - gdb_repr, gdb_output = \ - self.get_gdb_repr(''' -class Foo(object): - pass -foo = Foo() -foo.an_attr = foo -id(foo)''') - self.assertTrue(re.match(r'\) at remote 0x-?[0-9a-f]+>', - gdb_repr), - 'Unexpected gdb representation: %r\n%s' % \ - (gdb_repr, gdb_output)) - - gdb_repr, gdb_output = \ - self.get_gdb_repr(''' -class Foo(object): - pass -a = Foo() -b = Foo() -a.an_attr = b -b.an_attr = a -id(a)''') - self.assertTrue(re.match(r'\) at remote 0x-?[0-9a-f]+>\) at remote 0x-?[0-9a-f]+>', - gdb_repr), - 'Unexpected gdb representation: %r\n%s' % \ - (gdb_repr, gdb_output)) - - def test_truncation(self): - 'Verify that very long output is truncated' - gdb_repr, gdb_output = self.get_gdb_repr('id(list(range(1000)))') - self.assertEqual(gdb_repr, - "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, " - "14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, " - "27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, " - "40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, " - "53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, " - "66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, " - "79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, " - "92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, " - "104, 105, 106, 107, 108, 109, 110, 111, 112, 113, " - "114, 115, 116, 117, 118, 119, 120, 121, 122, 123, " - "124, 125, 126, 127, 128, 129, 130, 131, 132, 133, " - "134, 135, 136, 137, 138, 139, 140, 141, 142, 143, " - "144, 145, 146, 147, 148, 149, 150, 151, 152, 153, " - "154, 155, 156, 157, 158, 159, 160, 161, 162, 163, " - "164, 165, 166, 167, 168, 169, 170, 171, 172, 173, " - "174, 175, 176, 177, 178, 179, 180, 181, 182, 183, " - "184, 185, 186, 187, 188, 189, 190, 191, 192, 193, " - "194, 195, 196, 197, 198, 199, 200, 201, 202, 203, " - "204, 205, 206, 207, 208, 209, 210, 211, 212, 213, " - "214, 215, 216, 217, 218, 219, 220, 221, 222, 223, " - "224, 225, 226...(truncated)") - self.assertEqual(len(gdb_repr), - 1024 + len('...(truncated)')) - - def test_builtin_method(self): - gdb_repr, gdb_output = self.get_gdb_repr('import sys; id(sys.stdout.readlines)') - self.assertTrue(re.match(r'', - gdb_repr), - 'Unexpected gdb representation: %r\n%s' % \ - (gdb_repr, gdb_output)) - - def test_frames(self): - gdb_output = self.get_stack_trace(''' -import sys -def foo(a, b, c): - return sys._getframe(0) - -f = foo(3, 4, 5) -id(f)''', - breakpoint='builtin_id', - cmds_after_breakpoint=['print (PyFrameObject*)v'] - ) - self.assertTrue(re.match(r'.*\s+\$1 =\s+Frame 0x-?[0-9a-f]+, for file , line 4, in foo \(a=3.*', - gdb_output, - re.DOTALL), - 'Unexpected gdb representation: %r\n%s' % (gdb_output, gdb_output)) - -@unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") -class PyListTests(DebuggerTests): - def assertListing(self, expected, actual): - self.assertEndsWith(actual, expected) - - def test_basic_command(self): - 'Verify that the "py-list" command works' - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-list']) - - self.assertListing(' 5 \n' - ' 6 def bar(a, b, c):\n' - ' 7 baz(a, b, c)\n' - ' 8 \n' - ' 9 def baz(*args):\n' - ' >10 id(42)\n' - ' 11 \n' - ' 12 foo(1, 2, 3)\n', - bt) - - def test_one_abs_arg(self): - 'Verify the "py-list" command with one absolute argument' - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-list 9']) - - self.assertListing(' 9 def baz(*args):\n' - ' >10 id(42)\n' - ' 11 \n' - ' 12 foo(1, 2, 3)\n', - bt) - - def test_two_abs_args(self): - 'Verify the "py-list" command with two absolute arguments' - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-list 1,3']) - - self.assertListing(' 1 # Sample script for use by test_gdb.py\n' - ' 2 \n' - ' 3 def foo(a, b, c):\n', - bt) - -SAMPLE_WITH_C_CALL = """ - -from _testcapi import pyobject_vectorcall - -def foo(a, b, c): - bar(a, b, c) - -def bar(a, b, c): - pyobject_vectorcall(baz, (a, b, c), None) - -def baz(*args): - id(42) - -foo(1, 2, 3) - -""" - - -class StackNavigationTests(DebuggerTests): - @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - def test_pyup_command(self): - 'Verify that the "py-up" command works' - bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL, - cmds_after_breakpoint=['py-up', 'py-up']) - self.assertMultilineMatches(bt, - r'''^.* -#[0-9]+ Frame 0x-?[0-9a-f]+, for file , line 12, in baz \(args=\(1, 2, 3\)\) -#[0-9]+ -$''') - - @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") - def test_down_at_bottom(self): - 'Verify handling of "py-down" at the bottom of the stack' - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-down']) - self.assertEndsWith(bt, - 'Unable to find a newer python frame\n') - - @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") - def test_up_at_top(self): - 'Verify handling of "py-up" at the top of the stack' - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up'] * 5) - self.assertEndsWith(bt, - 'Unable to find an older python frame\n') - - @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - def test_up_then_down(self): - 'Verify "py-up" followed by "py-down"' - bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL, - cmds_after_breakpoint=['py-up', 'py-up', 'py-down']) - self.assertMultilineMatches(bt, - r'''^.* -#[0-9]+ Frame 0x-?[0-9a-f]+, for file , line 12, in baz \(args=\(1, 2, 3\)\) -#[0-9]+ -#[0-9]+ Frame 0x-?[0-9a-f]+, for file , line 12, in baz \(args=\(1, 2, 3\)\) -$''') - -class PyBtTests(DebuggerTests): - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - def test_bt(self): - 'Verify that the "py-bt" command works' - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-bt']) - self.assertMultilineMatches(bt, - r'''^.* -Traceback \(most recent call first\): - - File ".*gdb_sample.py", line 10, in baz - id\(42\) - File ".*gdb_sample.py", line 7, in bar - baz\(a, b, c\) - File ".*gdb_sample.py", line 4, in foo - bar\(a=a, b=b, c=c\) - File ".*gdb_sample.py", line 12, in - foo\(1, 2, 3\) -''') - - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - def test_bt_full(self): - 'Verify that the "py-bt-full" command works' - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-bt-full']) - self.assertMultilineMatches(bt, - r'''^.* -#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\) - baz\(a, b, c\) -#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \(a=1, b=2, c=3\) - bar\(a=a, b=b, c=c\) -#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in \(\) - foo\(1, 2, 3\) -''') - - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - def test_threads(self): - 'Verify that "py-bt" indicates threads that are waiting for the GIL' - cmd = ''' -from threading import Thread - -class TestThread(Thread): - # These threads would run forever, but we'll interrupt things with the - # debugger - def run(self): - i = 0 - while 1: - i += 1 - -t = {} -for i in range(4): - t[i] = TestThread() - t[i].start() - -# Trigger a breakpoint on the main thread -id(42) - -''' - # Verify with "py-bt": - gdb_output = self.get_stack_trace(cmd, - cmds_after_breakpoint=['thread apply all py-bt']) - self.assertIn('Waiting for the GIL', gdb_output) - - # Verify with "py-bt-full": - gdb_output = self.get_stack_trace(cmd, - cmds_after_breakpoint=['thread apply all py-bt-full']) - self.assertIn('Waiting for the GIL', gdb_output) - - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - # Some older versions of gdb will fail with - # "Cannot find new threads: generic error" - # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround - def test_gc(self): - 'Verify that "py-bt" indicates if a thread is garbage-collecting' - cmd = ('from gc import collect\n' - 'id(42)\n' - 'def foo():\n' - ' collect()\n' - 'def bar():\n' - ' foo()\n' - 'bar()\n') - # Verify with "py-bt": - gdb_output = self.get_stack_trace(cmd, - cmds_after_breakpoint=['break update_refs', 'continue', 'py-bt'], - ) - self.assertIn('Garbage-collecting', gdb_output) - - # Verify with "py-bt-full": - gdb_output = self.get_stack_trace(cmd, - cmds_after_breakpoint=['break update_refs', 'continue', 'py-bt-full'], - ) - self.assertIn('Garbage-collecting', gdb_output) - - - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - # Some older versions of gdb will fail with - # "Cannot find new threads: generic error" - # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround - # - # gdb will also generate many erroneous errors such as: - # Function "meth_varargs" not defined. - # This is because we are calling functions from an "external" module - # (_testcapimodule) rather than compiled-in functions. It seems difficult - # to suppress these. See also the comment in DebuggerTests.get_stack_trace - def test_pycfunction(self): - 'Verify that "py-bt" displays invocations of PyCFunction instances' - # bpo-46600: If the compiler inlines _null_to_none() in meth_varargs() - # (ex: clang -Og), _null_to_none() is the frame #1. Otherwise, - # meth_varargs() is the frame #1. - expected_frame = r'#(1|2)' - # Various optimizations multiply the code paths by which these are - # called, so test a variety of calling conventions. - for func_name, args in ( - ('meth_varargs', ''), - ('meth_varargs_keywords', ''), - ('meth_o', '[]'), - ('meth_noargs', ''), - ('meth_fastcall', ''), - ('meth_fastcall_keywords', ''), - ): - for obj in ( - '_testcapi', - '_testcapi.MethClass', - '_testcapi.MethClass()', - '_testcapi.MethStatic()', - - # XXX: bound methods don't yet give nice tracebacks - # '_testcapi.MethInstance()', - ): - with self.subTest(f'{obj}.{func_name}'): - cmd = textwrap.dedent(f''' - import _testcapi - def foo(): - {obj}.{func_name}({args}) - def bar(): - foo() - bar() - ''') - # Verify with "py-bt": - gdb_output = self.get_stack_trace( - cmd, - breakpoint=func_name, - cmds_after_breakpoint=['bt', 'py-bt'], - # bpo-45207: Ignore 'Function "meth_varargs" not - # defined.' message in stderr. - ignore_stderr=True, - ) - self.assertIn(f'\n.*") - -class PyLocalsTests(DebuggerTests): - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - def test_basic_command(self): - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-locals']) - self.assertMultilineMatches(bt, - r".*\nargs = \(1, 2, 3\)\n.*") - - @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") - @unittest.skipIf(python_is_optimized(), - "Python was compiled with optimizations") - def test_locals_after_up(self): - bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-up', 'py-locals']) - self.assertMultilineMatches(bt, - r'''^.* -Locals for foo -a = 1 -b = 2 -c = 3 -Locals for -.*$''') - - -def setUpModule(): - if support.verbose: - print("GDB version %s.%s:" % (gdb_major_version, gdb_minor_version)) - for line in gdb_version.splitlines(): - print(" " * 4 + line) - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_gdb/__init__.py b/Lib/test/test_gdb/__init__.py new file mode 100644 index 00000000000000..99557739af6748 --- /dev/null +++ b/Lib/test/test_gdb/__init__.py @@ -0,0 +1,29 @@ +# Verify that gdb can pretty-print the various PyObject* types +# +# The code for testing gdb was adapted from similar work in Unladen Swallow's +# Lib/test/test_jit_gdb.py + +import os +import sysconfig +import unittest +from test import support + + +if support.MS_WINDOWS: + # On Windows, Python is usually built by MSVC. Passing /p:DebugSymbols=true + # option to MSBuild produces PDB debug symbols, but gdb doesn't support PDB + # debug symbol files. + raise unittest.SkipTest("test_gdb doesn't work on Windows") + +if support.PGO: + raise unittest.SkipTest("test_gdb is not useful for PGO") + +if not sysconfig.is_python_build(): + raise unittest.SkipTest("test_gdb only works on source builds at the moment.") + +if support.check_cflags_pgo(): + raise unittest.SkipTest("test_gdb is not reliable on PGO builds") + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/gdb_sample.py b/Lib/test/test_gdb/gdb_sample.py similarity index 75% rename from Lib/test/gdb_sample.py rename to Lib/test/test_gdb/gdb_sample.py index 4188f50136fb97..a7f23db73ea6e6 100644 --- a/Lib/test/gdb_sample.py +++ b/Lib/test/test_gdb/gdb_sample.py @@ -1,4 +1,4 @@ -# Sample script for use by test_gdb.py +# Sample script for use by test_gdb def foo(a, b, c): bar(a=a, b=b, c=c) diff --git a/Lib/test/test_gdb/test_backtrace.py b/Lib/test/test_gdb/test_backtrace.py new file mode 100644 index 00000000000000..c41e7cb7c210de --- /dev/null +++ b/Lib/test/test_gdb/test_backtrace.py @@ -0,0 +1,134 @@ +import textwrap +import unittest +from test import support +from test.support import python_is_optimized + +from .util import setup_module, DebuggerTests, CET_PROTECTION, SAMPLE_SCRIPT + + +def setUpModule(): + setup_module() + + +class PyBtTests(DebuggerTests): + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_bt(self): + 'Verify that the "py-bt" command works' + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-bt']) + self.assertMultilineMatches(bt, + r'''^.* +Traceback \(most recent call first\): + + File ".*gdb_sample.py", line 10, in baz + id\(42\) + File ".*gdb_sample.py", line 7, in bar + baz\(a, b, c\) + File ".*gdb_sample.py", line 4, in foo + bar\(a=a, b=b, c=c\) + File ".*gdb_sample.py", line 12, in + foo\(1, 2, 3\) +''') + + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_bt_full(self): + 'Verify that the "py-bt-full" command works' + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-bt-full']) + self.assertMultilineMatches(bt, + r'''^.* +#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\) + baz\(a, b, c\) +#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \(a=1, b=2, c=3\) + bar\(a=a, b=b, c=c\) +#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in \(\) + foo\(1, 2, 3\) +''') + + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + @support.requires_resource('cpu') + def test_threads(self): + 'Verify that "py-bt" indicates threads that are waiting for the GIL' + cmd = ''' +from threading import Thread + +class TestThread(Thread): + # These threads would run forever, but we'll interrupt things with the + # debugger + def run(self): + i = 0 + while 1: + i += 1 + +t = {} +for i in range(4): + t[i] = TestThread() + t[i].start() + +# Trigger a breakpoint on the main thread +id(42) + +''' + # Verify with "py-bt": + gdb_output = self.get_stack_trace(cmd, + cmds_after_breakpoint=['thread apply all py-bt']) + self.assertIn('Waiting for the GIL', gdb_output) + + # Verify with "py-bt-full": + gdb_output = self.get_stack_trace(cmd, + cmds_after_breakpoint=['thread apply all py-bt-full']) + self.assertIn('Waiting for the GIL', gdb_output) + + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + # Some older versions of gdb will fail with + # "Cannot find new threads: generic error" + # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround + def test_gc(self): + 'Verify that "py-bt" indicates if a thread is garbage-collecting' + cmd = ('from gc import collect\n' + 'id(42)\n' + 'def foo():\n' + ' collect()\n' + 'def bar():\n' + ' foo()\n' + 'bar()\n') + # Verify with "py-bt": + gdb_output = self.get_stack_trace(cmd, + cmds_after_breakpoint=['break update_refs', 'continue', 'py-bt'], + ) + self.assertIn('Garbage-collecting', gdb_output) + + # Verify with "py-bt-full": + gdb_output = self.get_stack_trace(cmd, + cmds_after_breakpoint=['break update_refs', 'continue', 'py-bt-full'], + ) + self.assertIn('Garbage-collecting', gdb_output) + + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_wrapper_call(self): + cmd = textwrap.dedent(''' + class MyList(list): + def __init__(self): + super(*[]).__init__() # wrapper_call() + + id("first break point") + l = MyList() + ''') + cmds_after_breakpoint = ['break wrapper_call', 'continue'] + if CET_PROTECTION: + # bpo-32962: same case as in get_stack_trace(): + # we need an additional 'next' command in order to read + # arguments of the innermost function of the call stack. + cmds_after_breakpoint.append('next') + cmds_after_breakpoint.append('py-bt') + + # Verify with "py-bt": + gdb_output = self.get_stack_trace(cmd, + cmds_after_breakpoint=cmds_after_breakpoint) + self.assertRegex(gdb_output, + r"10 id(42)\n' + ' 11 \n' + ' 12 foo(1, 2, 3)\n', + bt) + + def test_one_abs_arg(self): + 'Verify the "py-list" command with one absolute argument' + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-list 9']) + + self.assertListing(' 9 def baz(*args):\n' + ' >10 id(42)\n' + ' 11 \n' + ' 12 foo(1, 2, 3)\n', + bt) + + def test_two_abs_args(self): + 'Verify the "py-list" command with two absolute arguments' + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-list 1,3']) + + self.assertListing(' 1 # Sample script for use by test_gdb\n' + ' 2 \n' + ' 3 def foo(a, b, c):\n', + bt) + +SAMPLE_WITH_C_CALL = """ + +from _testcapi import pyobject_vectorcall + +def foo(a, b, c): + bar(a, b, c) + +def bar(a, b, c): + pyobject_vectorcall(baz, (a, b, c), None) + +def baz(*args): + id(42) + +foo(1, 2, 3) + +""" + + +class StackNavigationTests(DebuggerTests): + @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_pyup_command(self): + 'Verify that the "py-up" command works' + bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL, + cmds_after_breakpoint=['py-up', 'py-up']) + self.assertMultilineMatches(bt, + r'''^.* +#[0-9]+ Frame 0x-?[0-9a-f]+, for file , line 12, in baz \(args=\(1, 2, 3\)\) +#[0-9]+ +$''') + + @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + def test_down_at_bottom(self): + 'Verify handling of "py-down" at the bottom of the stack' + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-down']) + self.assertEndsWith(bt, + 'Unable to find a newer python frame\n') + + @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + def test_up_at_top(self): + 'Verify handling of "py-up" at the top of the stack' + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-up'] * 5) + self.assertEndsWith(bt, + 'Unable to find an older python frame\n') + + @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_up_then_down(self): + 'Verify "py-up" followed by "py-down"' + bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL, + cmds_after_breakpoint=['py-up', 'py-up', 'py-down']) + self.assertMultilineMatches(bt, + r'''^.* +#[0-9]+ Frame 0x-?[0-9a-f]+, for file , line 12, in baz \(args=\(1, 2, 3\)\) +#[0-9]+ +#[0-9]+ Frame 0x-?[0-9a-f]+, for file , line 12, in baz \(args=\(1, 2, 3\)\) +$''') + +class PyPrintTests(DebuggerTests): + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_basic_command(self): + 'Verify that the "py-print" command works' + bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL, + cmds_after_breakpoint=['py-up', 'py-print args']) + self.assertMultilineMatches(bt, + r".*\nlocal 'args' = \(1, 2, 3\)\n.*") + + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + def test_print_after_up(self): + bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL, + cmds_after_breakpoint=['py-up', 'py-up', 'py-print c', 'py-print b', 'py-print a']) + self.assertMultilineMatches(bt, + r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*") + + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_printing_global(self): + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-up', 'py-print __name__']) + self.assertMultilineMatches(bt, + r".*\nglobal '__name__' = '__main__'\n.*") + + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_printing_builtin(self): + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-up', 'py-print len']) + self.assertMultilineMatches(bt, + r".*\nbuiltin 'len' = \n.*") + +class PyLocalsTests(DebuggerTests): + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_basic_command(self): + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-up', 'py-locals']) + self.assertMultilineMatches(bt, + r".*\nargs = \(1, 2, 3\)\n.*") + + @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + @unittest.skipIf(python_is_optimized(), + "Python was compiled with optimizations") + def test_locals_after_up(self): + bt = self.get_stack_trace(script=SAMPLE_SCRIPT, + cmds_after_breakpoint=['py-up', 'py-up', 'py-locals']) + self.assertMultilineMatches(bt, + r'''^.* +Locals for foo +a = 1 +b = 2 +c = 3 +Locals for +.*$''') diff --git a/Lib/test/test_gdb/test_pretty_print.py b/Lib/test/test_gdb/test_pretty_print.py new file mode 100644 index 00000000000000..dfc77d65ab16a4 --- /dev/null +++ b/Lib/test/test_gdb/test_pretty_print.py @@ -0,0 +1,438 @@ +import re +import sys +from test import support + +from .util import ( + BREAKPOINT_FN, GDB_VERSION, + run_gdb, setup_module, DebuggerTests) + + +def setUpModule(): + setup_module() + + +class PrettyPrintTests(DebuggerTests): + def get_gdb_repr(self, source, + cmds_after_breakpoint=None, + import_site=False): + # Given an input python source representation of data, + # run "python -c'id(DATA)'" under gdb with a breakpoint on + # builtin_id and scrape out gdb's representation of the "op" + # parameter, and verify that the gdb displays the same string + # + # Verify that the gdb displays the expected string + # + # For a nested structure, the first time we hit the breakpoint will + # give us the top-level structure + + # NOTE: avoid decoding too much of the traceback as some + # undecodable characters may lurk there in optimized mode + # (issue #19743). + cmds_after_breakpoint = cmds_after_breakpoint or ["backtrace 1"] + gdb_output = self.get_stack_trace(source, breakpoint=BREAKPOINT_FN, + cmds_after_breakpoint=cmds_after_breakpoint, + import_site=import_site) + # gdb can insert additional '\n' and space characters in various places + # in its output, depending on the width of the terminal it's connected + # to (using its "wrap_here" function) + m = re.search( + # Match '#0 builtin_id(self=..., v=...)' + r'#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)?\)' + # Match ' at Python/bltinmodule.c'. + # bpo-38239: builtin_id() is defined in Python/bltinmodule.c, + # but accept any "Directory\file.c" to support Link Time + # Optimization (LTO). + r'\s+at\s+\S*[A-Za-z]+/[A-Za-z0-9_-]+\.c', + gdb_output, re.DOTALL) + if not m: + self.fail('Unexpected gdb output: %r\n%s' % (gdb_output, gdb_output)) + return m.group(1), gdb_output + + def test_getting_backtrace(self): + gdb_output = self.get_stack_trace('id(42)') + self.assertTrue(BREAKPOINT_FN in gdb_output) + + def assertGdbRepr(self, val, exp_repr=None): + # Ensure that gdb's rendering of the value in a debugged process + # matches repr(value) in this process: + gdb_repr, gdb_output = self.get_gdb_repr('id(' + ascii(val) + ')') + if not exp_repr: + exp_repr = repr(val) + self.assertEqual(gdb_repr, exp_repr, + ('%r did not equal expected %r; full output was:\n%s' + % (gdb_repr, exp_repr, gdb_output))) + + @support.requires_resource('cpu') + def test_int(self): + 'Verify the pretty-printing of various int values' + self.assertGdbRepr(42) + self.assertGdbRepr(0) + self.assertGdbRepr(-7) + self.assertGdbRepr(1000000000000) + self.assertGdbRepr(-1000000000000000) + + def test_singletons(self): + 'Verify the pretty-printing of True, False and None' + self.assertGdbRepr(True) + self.assertGdbRepr(False) + self.assertGdbRepr(None) + + def test_dicts(self): + 'Verify the pretty-printing of dictionaries' + self.assertGdbRepr({}) + self.assertGdbRepr({'foo': 'bar'}, "{'foo': 'bar'}") + # Python preserves insertion order since 3.6 + self.assertGdbRepr({'foo': 'bar', 'douglas': 42}, "{'foo': 'bar', 'douglas': 42}") + + def test_lists(self): + 'Verify the pretty-printing of lists' + self.assertGdbRepr([]) + self.assertGdbRepr(list(range(5))) + + @support.requires_resource('cpu') + def test_bytes(self): + 'Verify the pretty-printing of bytes' + self.assertGdbRepr(b'') + self.assertGdbRepr(b'And now for something hopefully the same') + self.assertGdbRepr(b'string with embedded NUL here \0 and then some more text') + self.assertGdbRepr(b'this is a tab:\t' + b' this is a slash-N:\n' + b' this is a slash-R:\r' + ) + + self.assertGdbRepr(b'this is byte 255:\xff and byte 128:\x80') + + self.assertGdbRepr(bytes([b for b in range(255)])) + + @support.requires_resource('cpu') + def test_strings(self): + 'Verify the pretty-printing of unicode strings' + # We cannot simply call locale.getpreferredencoding() here, + # as GDB might have been linked against a different version + # of Python with a different encoding and coercion policy + # with respect to PEP 538 and PEP 540. + stdout, stderr = run_gdb( + '--eval-command', + 'python import locale; print(locale.getpreferredencoding())') + + encoding = stdout + if stderr or not encoding: + raise RuntimeError( + f'unable to determine the Python locale preferred encoding ' + f'of embedded Python in GDB\n' + f'stdout={stdout!r}\n' + f'stderr={stderr!r}') + + def check_repr(text): + try: + text.encode(encoding) + except UnicodeEncodeError: + self.assertGdbRepr(text, ascii(text)) + else: + self.assertGdbRepr(text) + + self.assertGdbRepr('') + self.assertGdbRepr('And now for something hopefully the same') + self.assertGdbRepr('string with embedded NUL here \0 and then some more text') + + # Test printing a single character: + # U+2620 SKULL AND CROSSBONES + check_repr('\u2620') + + # Test printing a Japanese unicode string + # (I believe this reads "mojibake", using 3 characters from the CJK + # Unified Ideographs area, followed by U+3051 HIRAGANA LETTER KE) + check_repr('\u6587\u5b57\u5316\u3051') + + # Test a character outside the BMP: + # U+1D121 MUSICAL SYMBOL C CLEF + # This is: + # UTF-8: 0xF0 0x9D 0x84 0xA1 + # UTF-16: 0xD834 0xDD21 + check_repr(chr(0x1D121)) + + def test_tuples(self): + 'Verify the pretty-printing of tuples' + self.assertGdbRepr(tuple(), '()') + self.assertGdbRepr((1,), '(1,)') + self.assertGdbRepr(('foo', 'bar', 'baz')) + + @support.requires_resource('cpu') + def test_sets(self): + 'Verify the pretty-printing of sets' + if GDB_VERSION < (7, 3): + self.skipTest("pretty-printing of sets needs gdb 7.3 or later") + self.assertGdbRepr(set(), "set()") + self.assertGdbRepr(set(['a']), "{'a'}") + # PYTHONHASHSEED is need to get the exact frozenset item order + if not sys.flags.ignore_environment: + self.assertGdbRepr(set(['a', 'b']), "{'a', 'b'}") + self.assertGdbRepr(set([4, 5, 6]), "{4, 5, 6}") + + # Ensure that we handle sets containing the "dummy" key value, + # which happens on deletion: + gdb_repr, gdb_output = self.get_gdb_repr('''s = set(['a','b']) +s.remove('a') +id(s)''') + self.assertEqual(gdb_repr, "{'b'}") + + @support.requires_resource('cpu') + def test_frozensets(self): + 'Verify the pretty-printing of frozensets' + if GDB_VERSION < (7, 3): + self.skipTest("pretty-printing of frozensets needs gdb 7.3 or later") + self.assertGdbRepr(frozenset(), "frozenset()") + self.assertGdbRepr(frozenset(['a']), "frozenset({'a'})") + # PYTHONHASHSEED is need to get the exact frozenset item order + if not sys.flags.ignore_environment: + self.assertGdbRepr(frozenset(['a', 'b']), "frozenset({'a', 'b'})") + self.assertGdbRepr(frozenset([4, 5, 6]), "frozenset({4, 5, 6})") + + def test_exceptions(self): + # Test a RuntimeError + gdb_repr, gdb_output = self.get_gdb_repr(''' +try: + raise RuntimeError("I am an error") +except RuntimeError as e: + id(e) +''') + self.assertEqual(gdb_repr, + "RuntimeError('I am an error',)") + + + # Test division by zero: + gdb_repr, gdb_output = self.get_gdb_repr(''' +try: + a = 1 / 0 +except ZeroDivisionError as e: + id(e) +''') + self.assertEqual(gdb_repr, + "ZeroDivisionError('division by zero',)") + + def test_modern_class(self): + 'Verify the pretty-printing of new-style class instances' + gdb_repr, gdb_output = self.get_gdb_repr(''' +class Foo: + pass +foo = Foo() +foo.an_int = 42 +id(foo)''') + m = re.match(r'', gdb_repr) + self.assertTrue(m, + msg='Unexpected new-style class rendering %r' % gdb_repr) + + def test_subclassing_list(self): + 'Verify the pretty-printing of an instance of a list subclass' + gdb_repr, gdb_output = self.get_gdb_repr(''' +class Foo(list): + pass +foo = Foo() +foo += [1, 2, 3] +foo.an_int = 42 +id(foo)''') + m = re.match(r'', gdb_repr) + + self.assertTrue(m, + msg='Unexpected new-style class rendering %r' % gdb_repr) + + def test_subclassing_tuple(self): + 'Verify the pretty-printing of an instance of a tuple subclass' + # This should exercise the negative tp_dictoffset code in the + # new-style class support + gdb_repr, gdb_output = self.get_gdb_repr(''' +class Foo(tuple): + pass +foo = Foo((1, 2, 3)) +foo.an_int = 42 +id(foo)''') + m = re.match(r'', gdb_repr) + + self.assertTrue(m, + msg='Unexpected new-style class rendering %r' % gdb_repr) + + def assertSane(self, source, corruption, exprepr=None): + '''Run Python under gdb, corrupting variables in the inferior process + immediately before taking a backtrace. + + Verify that the variable's representation is the expected failsafe + representation''' + if corruption: + cmds_after_breakpoint=[corruption, 'backtrace'] + else: + cmds_after_breakpoint=['backtrace'] + + gdb_repr, gdb_output = \ + self.get_gdb_repr(source, + cmds_after_breakpoint=cmds_after_breakpoint) + if exprepr: + if gdb_repr == exprepr: + # gdb managed to print the value in spite of the corruption; + # this is good (see http://bugs.python.org/issue8330) + return + + # Match anything for the type name; 0xDEADBEEF could point to + # something arbitrary (see http://bugs.python.org/issue8330) + pattern = '<.* at remote 0x-?[0-9a-f]+>' + + m = re.match(pattern, gdb_repr) + if not m: + self.fail('Unexpected gdb representation: %r\n%s' % \ + (gdb_repr, gdb_output)) + + def test_NULL_ptr(self): + 'Ensure that a NULL PyObject* is handled gracefully' + gdb_repr, gdb_output = ( + self.get_gdb_repr('id(42)', + cmds_after_breakpoint=['set variable v=0', + 'backtrace']) + ) + + self.assertEqual(gdb_repr, '0x0') + + def test_NULL_ob_type(self): + 'Ensure that a PyObject* with NULL ob_type is handled gracefully' + self.assertSane('id(42)', + 'set v->ob_type=0') + + def test_corrupt_ob_type(self): + 'Ensure that a PyObject* with a corrupt ob_type is handled gracefully' + self.assertSane('id(42)', + 'set v->ob_type=0xDEADBEEF', + exprepr='42') + + def test_corrupt_tp_flags(self): + 'Ensure that a PyObject* with a type with corrupt tp_flags is handled' + self.assertSane('id(42)', + 'set v->ob_type->tp_flags=0x0', + exprepr='42') + + def test_corrupt_tp_name(self): + 'Ensure that a PyObject* with a type with corrupt tp_name is handled' + self.assertSane('id(42)', + 'set v->ob_type->tp_name=0xDEADBEEF', + exprepr='42') + + def test_builtins_help(self): + 'Ensure that the new-style class _Helper in site.py can be handled' + + if sys.flags.no_site: + self.skipTest("need site module, but -S option was used") + + # (this was the issue causing tracebacks in + # http://bugs.python.org/issue8032#msg100537 ) + gdb_repr, gdb_output = self.get_gdb_repr('id(__builtins__.help)', import_site=True) + + m = re.match(r'<_Helper\(\) at remote 0x-?[0-9a-f]+>', gdb_repr) + self.assertTrue(m, + msg='Unexpected rendering %r' % gdb_repr) + + def test_selfreferential_list(self): + '''Ensure that a reference loop involving a list doesn't lead proxyval + into an infinite loop:''' + gdb_repr, gdb_output = \ + self.get_gdb_repr("a = [3, 4, 5] ; a.append(a) ; id(a)") + self.assertEqual(gdb_repr, '[3, 4, 5, [...]]') + + gdb_repr, gdb_output = \ + self.get_gdb_repr("a = [3, 4, 5] ; b = [a] ; a.append(b) ; id(a)") + self.assertEqual(gdb_repr, '[3, 4, 5, [[...]]]') + + def test_selfreferential_dict(self): + '''Ensure that a reference loop involving a dict doesn't lead proxyval + into an infinite loop:''' + gdb_repr, gdb_output = \ + self.get_gdb_repr("a = {} ; b = {'bar':a} ; a['foo'] = b ; id(a)") + + self.assertEqual(gdb_repr, "{'foo': {'bar': {...}}}") + + def test_selfreferential_old_style_instance(self): + gdb_repr, gdb_output = \ + self.get_gdb_repr(''' +class Foo: + pass +foo = Foo() +foo.an_attr = foo +id(foo)''') + self.assertTrue(re.match(r'\) at remote 0x-?[0-9a-f]+>', + gdb_repr), + 'Unexpected gdb representation: %r\n%s' % \ + (gdb_repr, gdb_output)) + + def test_selfreferential_new_style_instance(self): + gdb_repr, gdb_output = \ + self.get_gdb_repr(''' +class Foo(object): + pass +foo = Foo() +foo.an_attr = foo +id(foo)''') + self.assertTrue(re.match(r'\) at remote 0x-?[0-9a-f]+>', + gdb_repr), + 'Unexpected gdb representation: %r\n%s' % \ + (gdb_repr, gdb_output)) + + gdb_repr, gdb_output = \ + self.get_gdb_repr(''' +class Foo(object): + pass +a = Foo() +b = Foo() +a.an_attr = b +b.an_attr = a +id(a)''') + self.assertTrue(re.match(r'\) at remote 0x-?[0-9a-f]+>\) at remote 0x-?[0-9a-f]+>', + gdb_repr), + 'Unexpected gdb representation: %r\n%s' % \ + (gdb_repr, gdb_output)) + + def test_truncation(self): + 'Verify that very long output is truncated' + gdb_repr, gdb_output = self.get_gdb_repr('id(list(range(1000)))') + self.assertEqual(gdb_repr, + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, " + "14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, " + "27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, " + "40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, " + "53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, " + "66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, " + "79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, " + "92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, " + "104, 105, 106, 107, 108, 109, 110, 111, 112, 113, " + "114, 115, 116, 117, 118, 119, 120, 121, 122, 123, " + "124, 125, 126, 127, 128, 129, 130, 131, 132, 133, " + "134, 135, 136, 137, 138, 139, 140, 141, 142, 143, " + "144, 145, 146, 147, 148, 149, 150, 151, 152, 153, " + "154, 155, 156, 157, 158, 159, 160, 161, 162, 163, " + "164, 165, 166, 167, 168, 169, 170, 171, 172, 173, " + "174, 175, 176, 177, 178, 179, 180, 181, 182, 183, " + "184, 185, 186, 187, 188, 189, 190, 191, 192, 193, " + "194, 195, 196, 197, 198, 199, 200, 201, 202, 203, " + "204, 205, 206, 207, 208, 209, 210, 211, 212, 213, " + "214, 215, 216, 217, 218, 219, 220, 221, 222, 223, " + "224, 225, 226...(truncated)") + self.assertEqual(len(gdb_repr), + 1024 + len('...(truncated)')) + + def test_builtin_method(self): + gdb_repr, gdb_output = self.get_gdb_repr('import sys; id(sys.stdout.readlines)') + self.assertTrue(re.match(r'', + gdb_repr), + 'Unexpected gdb representation: %r\n%s' % \ + (gdb_repr, gdb_output)) + + def test_frames(self): + gdb_output = self.get_stack_trace(''' +import sys +def foo(a, b, c): + return sys._getframe(0) + +f = foo(3, 4, 5) +id(f)''', + breakpoint='builtin_id', + cmds_after_breakpoint=['print (PyFrameObject*)v'] + ) + self.assertTrue(re.match(r'.*\s+\$1 =\s+Frame 0x-?[0-9a-f]+, for file , line 4, in foo \(a=3.*', + gdb_output, + re.DOTALL), + 'Unexpected gdb representation: %r\n%s' % (gdb_output, gdb_output)) diff --git a/Lib/test/test_gdb/util.py b/Lib/test/test_gdb/util.py new file mode 100644 index 00000000000000..7f4e3cba3534bd --- /dev/null +++ b/Lib/test/test_gdb/util.py @@ -0,0 +1,286 @@ +import os +import re +import shlex +import subprocess +import sys +import sysconfig +import unittest +from test import support + + +# Location of custom hooks file in a repository checkout. +CHECKOUT_HOOK_PATH = os.path.join(os.path.dirname(sys.executable), + 'python-gdb.py') + +SAMPLE_SCRIPT = os.path.join(os.path.dirname(__file__), 'gdb_sample.py') +BREAKPOINT_FN = 'builtin_id' + +PYTHONHASHSEED = '123' + + +def clean_environment(): + # Remove PYTHON* environment variables such as PYTHONHOME + return {name: value for name, value in os.environ.items() + if not name.startswith('PYTHON')} + + +# Temporary value until it's initialized by get_gdb_version() below +GDB_VERSION = (0, 0) + +def run_gdb(*args, exitcode=0, **env_vars): + """Runs gdb in --batch mode with the additional arguments given by *args. + + Returns its (stdout, stderr) decoded from utf-8 using the replace handler. + """ + env = clean_environment() + if env_vars: + env.update(env_vars) + + cmd = ['gdb', + # Batch mode: Exit after processing all the command files + # specified with -x/--command + '--batch', + # -nx: Do not execute commands from any .gdbinit initialization + # files (gh-66384) + '-nx'] + if GDB_VERSION >= (7, 4): + cmd.extend(('--init-eval-command', + f'add-auto-load-safe-path {CHECKOUT_HOOK_PATH}')) + cmd.extend(args) + + proc = subprocess.run( + cmd, + # Redirect stdin to prevent gdb from messing with the terminal settings + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="utf8", errors="backslashreplace", + env=env) + + stdout = proc.stdout + stderr = proc.stderr + if proc.returncode != exitcode: + cmd_text = shlex.join(cmd) + raise Exception(f"{cmd_text} failed with exit code {proc.returncode}, " + f"expected exit code {exitcode}:\n" + f"stdout={stdout!r}\n" + f"stderr={stderr!r}") + + return (stdout, stderr) + + +def get_gdb_version(): + try: + stdout, stderr = run_gdb('--version') + except OSError: + # This is what "no gdb" looks like. There may, however, be other + # errors that manifest this way too. + raise unittest.SkipTest("Couldn't find gdb program on the path") + + # Regex to parse: + # 'GNU gdb (GDB; SUSE Linux Enterprise 12) 7.7\n' -> 7.7 + # 'GNU gdb (GDB) Fedora 7.9.1-17.fc22\n' -> 7.9 + # 'GNU gdb 6.1.1 [FreeBSD]\n' -> 6.1 + # 'GNU gdb (GDB) Fedora (7.5.1-37.fc18)\n' -> 7.5 + # 'HP gdb 6.7 for HP Itanium (32 or 64 bit) and target HP-UX 11iv2 and 11iv3.\n' -> 6.7 + match = re.search(r"^(?:GNU|HP) gdb.*?\b(\d+)\.(\d+)", stdout) + if match is None: + raise Exception("unable to parse gdb version: %r" % stdout) + version_text = stdout + major = int(match.group(1)) + minor = int(match.group(2)) + version = (major, minor) + return (version_text, version) + +GDB_VERSION_TEXT, GDB_VERSION = get_gdb_version() +if GDB_VERSION < (7, 0): + raise unittest.SkipTest( + f"gdb versions before 7.0 didn't support python embedding. " + f"Saw gdb version {GDB_VERSION[0]}.{GDB_VERSION[1]}:\n" + f"{GDB_VERSION_TEXT}") + + +def check_usable_gdb(): + # Verify that "gdb" was built with the embedded Python support enabled and + # verify that "gdb" can load our custom hooks, as OS security settings may + # disallow this without a customized .gdbinit. + stdout, stderr = run_gdb( + '--eval-command=python import sys; print(sys.version_info)', + '--args', sys.executable) + + if "auto-loading has been declined" in stderr: + raise unittest.SkipTest( + f"gdb security settings prevent use of custom hooks; " + f"stderr: {stderr!r}") + + if not stdout: + raise unittest.SkipTest( + f"gdb not built with embedded python support; " + f"stderr: {stderr!r}") + + if "major=2" in stdout: + raise unittest.SkipTest("gdb built with Python 2") + +check_usable_gdb() + + +# Control-flow enforcement technology +def cet_protection(): + cflags = sysconfig.get_config_var('CFLAGS') + if not cflags: + return False + flags = cflags.split() + # True if "-mcet -fcf-protection" options are found, but false + # if "-fcf-protection=none" or "-fcf-protection=return" is found. + return (('-mcet' in flags) + and any((flag.startswith('-fcf-protection') + and not flag.endswith(("=none", "=return"))) + for flag in flags)) +CET_PROTECTION = cet_protection() + + +def setup_module(): + if support.verbose: + print(f"gdb version {GDB_VERSION[0]}.{GDB_VERSION[1]}:") + for line in GDB_VERSION_TEXT.splitlines(): + print(" " * 4 + line) + print() + + +class DebuggerTests(unittest.TestCase): + + """Test that the debugger can debug Python.""" + + def get_stack_trace(self, source=None, script=None, + breakpoint=BREAKPOINT_FN, + cmds_after_breakpoint=None, + import_site=False, + ignore_stderr=False): + ''' + Run 'python -c SOURCE' under gdb with a breakpoint. + + Support injecting commands after the breakpoint is reached + + Returns the stdout from gdb + + cmds_after_breakpoint: if provided, a list of strings: gdb commands + ''' + # We use "set breakpoint pending yes" to avoid blocking with a: + # Function "foo" not defined. + # Make breakpoint pending on future shared library load? (y or [n]) + # error, which typically happens python is dynamically linked (the + # breakpoints of interest are to be found in the shared library) + # When this happens, we still get: + # Function "textiowrapper_write" not defined. + # emitted to stderr each time, alas. + + # Initially I had "--eval-command=continue" here, but removed it to + # avoid repeated print breakpoints when traversing hierarchical data + # structures + + # Generate a list of commands in gdb's language: + commands = [ + 'set breakpoint pending yes', + 'break %s' % breakpoint, + + # The tests assume that the first frame of printed + # backtrace will not contain program counter, + # that is however not guaranteed by gdb + # therefore we need to use 'set print address off' to + # make sure the counter is not there. For example: + # #0 in PyObject_Print ... + # is assumed, but sometimes this can be e.g. + # #0 0x00003fffb7dd1798 in PyObject_Print ... + 'set print address off', + + 'run', + ] + + # GDB as of 7.4 onwards can distinguish between the + # value of a variable at entry vs current value: + # http://sourceware.org/gdb/onlinedocs/gdb/Variables.html + # which leads to the selftests failing with errors like this: + # AssertionError: 'v@entry=()' != '()' + # Disable this: + if GDB_VERSION >= (7, 4): + commands += ['set print entry-values no'] + + if cmds_after_breakpoint: + if CET_PROTECTION: + # bpo-32962: When Python is compiled with -mcet + # -fcf-protection, function arguments are unusable before + # running the first instruction of the function entry point. + # The 'next' command makes the required first step. + commands += ['next'] + commands += cmds_after_breakpoint + else: + commands += ['backtrace'] + + # print commands + + # Use "commands" to generate the arguments with which to invoke "gdb": + args = ['--eval-command=%s' % cmd for cmd in commands] + args += ["--args", + sys.executable] + args.extend(subprocess._args_from_interpreter_flags()) + + if not import_site: + # -S suppresses the default 'import site' + args += ["-S"] + + if source: + args += ["-c", source] + elif script: + args += [script] + + # Use "args" to invoke gdb, capturing stdout, stderr: + out, err = run_gdb(*args, PYTHONHASHSEED=PYTHONHASHSEED) + + if not ignore_stderr: + for line in err.splitlines(): + print(line, file=sys.stderr) + + # bpo-34007: Sometimes some versions of the shared libraries that + # are part of the traceback are compiled in optimised mode and the + # Program Counter (PC) is not present, not allowing gdb to walk the + # frames back. When this happens, the Python bindings of gdb raise + # an exception, making the test impossible to succeed. + if "PC not saved" in err: + raise unittest.SkipTest("gdb cannot walk the frame object" + " because the Program Counter is" + " not present") + + # bpo-40019: Skip the test if gdb failed to read debug information + # because the Python binary is optimized. + for pattern in ( + '(frame information optimized out)', + 'Unable to read information on python frame', + + # gh-91960: On Python built with "clang -Og", gdb gets + # "frame=" for _PyEval_EvalFrameDefault() parameter + '(unable to read python frame information)', + + # gh-104736: On Python built with "clang -Og" on ppc64le, + # "py-bt" displays a truncated or not traceback, but "where" + # logs this error message: + 'Backtrace stopped: frame did not save the PC', + + # gh-104736: When "bt" command displays something like: + # "#1 0x0000000000000000 in ?? ()", the traceback is likely + # truncated or wrong. + ' ?? ()', + ): + if pattern in out: + raise unittest.SkipTest(f"{pattern!r} found in gdb output") + + return out + + def assertEndsWith(self, actual, exp_end): + '''Ensure that the given "actual" string ends with "exp_end"''' + self.assertTrue(actual.endswith(exp_end), + msg='%r did not end with %r' % (actual, exp_end)) + + def assertMultilineMatches(self, actual, pattern): + m = re.match(pattern, actual, re.DOTALL) + if not m: + self.fail(msg='%r did not match %r' % (actual, pattern)) diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index ba0e5e8b0f6954..790e6b1b1b91e6 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -1,14 +1,44 @@ +import contextlib +import os +import sys import tempfile import unittest -import os +from test import support from test import test_tools + +def skip_if_different_mount_drives(): + if sys.platform != 'win32': + return + ROOT = os.path.dirname(os.path.dirname(__file__)) + root_drive = os.path.splitroot(ROOT)[0] + cwd_drive = os.path.splitroot(os.getcwd())[0] + if root_drive != cwd_drive: + # generate_cases.py uses relpath() which raises ValueError if ROOT + # and the current working different have different mount drives + # (on Windows). + raise unittest.SkipTest( + f"the current working directory and the Python source code " + f"directory have different mount drives " + f"({cwd_drive} and {root_drive})" + ) +skip_if_different_mount_drives() + + test_tools.skip_if_missing('cases_generator') with test_tools.imports_under_tool('cases_generator'): import generate_cases - from parser import StackEffect + import analysis + import formatting + from parsing import StackEffect + +def handle_stderr(): + if support.verbose > 1: + return contextlib.nullcontext() + else: + return support.captured_stderr() class TestEffects(unittest.TestCase): def test_effect_sizes(self): @@ -27,45 +57,28 @@ def test_effect_sizes(self): StackEffect("q", "", "", ""), StackEffect("r", "", "", ""), ] - self.assertEqual(generate_cases.effect_size(x), (1, "")) - self.assertEqual(generate_cases.effect_size(y), (0, "oparg")) - self.assertEqual(generate_cases.effect_size(z), (0, "oparg*2")) + self.assertEqual(formatting.effect_size(x), (1, "")) + self.assertEqual(formatting.effect_size(y), (0, "oparg")) + self.assertEqual(formatting.effect_size(z), (0, "oparg*2")) self.assertEqual( - generate_cases.list_effect_size(input_effects), + formatting.list_effect_size(input_effects), (1, "oparg + oparg*2"), ) self.assertEqual( - generate_cases.list_effect_size(output_effects), + formatting.list_effect_size(output_effects), (2, "oparg*4"), ) self.assertEqual( - generate_cases.list_effect_size(other_effects), + formatting.list_effect_size(other_effects), (2, "(oparg<<1)"), ) - self.assertEqual( - generate_cases.string_effect_size( - generate_cases.list_effect_size(input_effects), - ), "1 + oparg + oparg*2", - ) - self.assertEqual( - generate_cases.string_effect_size( - generate_cases.list_effect_size(output_effects), - ), - "2 + oparg*4", - ) - self.assertEqual( - generate_cases.string_effect_size( - generate_cases.list_effect_size(other_effects), - ), - "2 + (oparg<<1)", - ) - class TestGeneratedCases(unittest.TestCase): def setUp(self) -> None: super().setUp() + self.maxDiff = None self.temp_dir = tempfile.gettempdir() self.temp_input_filename = os.path.join(self.temp_dir, "input.txt") @@ -90,23 +103,18 @@ def tearDown(self) -> None: def run_cases_test(self, input: str, expected: str): with open(self.temp_input_filename, "w+") as temp_input: - temp_input.write(generate_cases.BEGIN_MARKER) + temp_input.write(analysis.BEGIN_MARKER) temp_input.write(input) - temp_input.write(generate_cases.END_MARKER) + temp_input.write(analysis.END_MARKER) temp_input.flush() - a = generate_cases.Analyzer( - [self.temp_input_filename], - self.temp_output_filename, - self.temp_metadata_filename, - self.temp_pymetadata_filename, - self.temp_executor_filename, - ) - a.parse() - a.analyze() - if a.errors: - raise RuntimeError(f"Found {a.errors} errors") - a.write_instructions() + a = generate_cases.Generator([self.temp_input_filename]) + with handle_stderr(): + a.parse() + a.analyze() + if a.errors: + raise RuntimeError(f"Found {a.errors} errors") + a.write_instructions(self.temp_output_filename, False) with open(self.temp_output_filename) as temp_output: lines = temp_output.readlines() @@ -144,7 +152,8 @@ def test_inst_one_pop(self): """ output = """ TARGET(OP) { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; spam(); STACK_SHRINK(1); DISPATCH(); @@ -177,8 +186,9 @@ def test_inst_one_push_one_pop(self): """ output = """ TARGET(OP) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; spam(); stack_pointer[-1] = res; DISPATCH(); @@ -194,9 +204,11 @@ def test_binary_op(self): """ output = """ TARGET(OP) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; spam(); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -213,9 +225,11 @@ def test_overlap(self): """ output = """ TARGET(OP) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *result; + right = stack_pointer[-1]; + left = stack_pointer[-2]; spam(); stack_pointer[-1] = result; DISPATCH(); @@ -225,22 +239,29 @@ def test_overlap(self): def test_predictions_and_eval_breaker(self): input = """ - inst(OP1, (--)) { + inst(OP1, (arg -- rest)) { } inst(OP3, (arg -- res)) { - DEOPT_IF(xxx, OP1); + DEOPT_IF(xxx); CHECK_EVAL_BREAKER(); } + family(OP1, INLINE_CACHE_ENTRIES_OP1) = { OP3 }; """ output = """ TARGET(OP1) { PREDICTED(OP1); + static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size"); + PyObject *arg; + PyObject *rest; + arg = stack_pointer[-1]; + stack_pointer[-1] = rest; DISPATCH(); } TARGET(OP3) { - PyObject *arg = stack_pointer[-1]; + PyObject *arg; PyObject *res; + arg = stack_pointer[-1]; DEOPT_IF(xxx, OP1); stack_pointer[-1] = res; CHECK_EVAL_BREAKER(); @@ -285,9 +306,11 @@ def test_error_if_pop(self): """ output = """ TARGET(OP) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; if (cond) goto pop_2_label; STACK_SHRINK(1); stack_pointer[-1] = res; @@ -303,7 +326,8 @@ def test_cache_effect(self): """ output = """ TARGET(OP) { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; uint16_t counter = read_u16(&next_instr[0].cache); uint32_t extra = read_u32(&next_instr[1].cache); STACK_SHRINK(1); @@ -342,8 +366,10 @@ def test_macro_instruction(self): """ output = """ TARGET(OP1) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; + right = stack_pointer[-1]; + left = stack_pointer[-2]; uint16_t counter = read_u16(&next_instr[0].cache); op1(left, right); next_instr += 1; @@ -351,38 +377,39 @@ def test_macro_instruction(self): } TARGET(OP) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; - PyObject *_tmp_3 = stack_pointer[-3]; + PREDICTED(OP); + static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); + PyObject *right; + PyObject *left; + PyObject *arg2; + PyObject *res; + // OP1 + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; uint16_t counter = read_u16(&next_instr[0].cache); op1(left, right); - _tmp_2 = left; - _tmp_1 = right; } + // OP2 + arg2 = stack_pointer[-3]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *arg2 = _tmp_3; - PyObject *res; uint32_t extra = read_u32(&next_instr[3].cache); res = op2(arg2, left, right); - _tmp_3 = res; } - next_instr += 5; - static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); STACK_SHRINK(2); - stack_pointer[-1] = _tmp_3; + stack_pointer[-1] = res; + next_instr += 5; DISPATCH(); } TARGET(OP3) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; - PyObject *arg2 = stack_pointer[-3]; + PyObject *right; + PyObject *left; + PyObject *arg2; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; + arg2 = stack_pointer[-3]; res = op3(arg2, left, right); STACK_SHRINK(2); stack_pointer[-1] = res; @@ -400,9 +427,12 @@ def test_array_input(self): """ output = """ TARGET(OP) { - PyObject *above = stack_pointer[-1]; - PyObject **values = (stack_pointer - (1 + oparg*2)); - PyObject *below = stack_pointer[-(2 + oparg*2)]; + PyObject *above; + PyObject **values; + PyObject *below; + above = stack_pointer[-1]; + values = stack_pointer - 1 - oparg*2; + below = stack_pointer[-2 - oparg*2]; spam(); STACK_SHRINK(oparg*2); STACK_SHRINK(2); @@ -420,12 +450,13 @@ def test_array_output(self): output = """ TARGET(OP) { PyObject *below; - PyObject **values = stack_pointer - (2) + 1; + PyObject **values; PyObject *above; + values = stack_pointer - 1; spam(values, oparg); STACK_GROW(oparg*3); + stack_pointer[-2 - oparg*3] = below; stack_pointer[-1] = above; - stack_pointer[-(2 + oparg*3)] = below; DISPATCH(); } """ @@ -439,8 +470,9 @@ def test_array_input_output(self): """ output = """ TARGET(OP) { - PyObject **values = (stack_pointer - oparg); + PyObject **values; PyObject *above; + values = stack_pointer - oparg; spam(values, oparg); STACK_GROW(1); stack_pointer[-1] = above; @@ -457,8 +489,10 @@ def test_array_error_if(self): """ output = """ TARGET(OP) { - PyObject **values = (stack_pointer - oparg); - PyObject *extra = stack_pointer[-(1 + oparg)]; + PyObject **values; + PyObject *extra; + values = stack_pointer - oparg; + extra = stack_pointer[-1 - oparg]; if (oparg == 0) { STACK_SHRINK(oparg); goto pop_1_somewhere; } STACK_SHRINK(oparg); STACK_SHRINK(1); @@ -475,18 +509,21 @@ def test_cond_effect(self): """ output = """ TARGET(OP) { - PyObject *cc = stack_pointer[-1]; - PyObject *input = ((oparg & 1) == 1) ? stack_pointer[-(1 + (((oparg & 1) == 1) ? 1 : 0))] : NULL; - PyObject *aa = stack_pointer[-(2 + (((oparg & 1) == 1) ? 1 : 0))]; + PyObject *cc; + PyObject *input = NULL; + PyObject *aa; PyObject *xx; PyObject *output = NULL; PyObject *zz; + cc = stack_pointer[-1]; + if ((oparg & 1) == 1) { input = stack_pointer[-1 - ((oparg & 1) == 1 ? 1 : 0)]; } + aa = stack_pointer[-2 - ((oparg & 1) == 1 ? 1 : 0)]; output = spam(oparg, input); STACK_SHRINK((((oparg & 1) == 1) ? 1 : 0)); STACK_GROW(((oparg & 2) ? 1 : 0)); + stack_pointer[-2 - (oparg & 2 ? 1 : 0)] = xx; + if (oparg & 2) { stack_pointer[-1 - (oparg & 2 ? 1 : 0)] = output; } stack_pointer[-1] = zz; - if (oparg & 2) { stack_pointer[-(1 + ((oparg & 2) ? 1 : 0))] = output; } - stack_pointer[-(2 + ((oparg & 2) ? 1 : 0))] = xx; DISPATCH(); } """ @@ -504,34 +541,98 @@ def test_macro_cond_effect(self): """ output = """ TARGET(M) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; - PyObject *_tmp_3 = stack_pointer[-3]; + PyObject *right; + PyObject *middle; + PyObject *left; + PyObject *deep; + PyObject *extra = NULL; + PyObject *res; + // A + right = stack_pointer[-1]; + middle = stack_pointer[-2]; + left = stack_pointer[-3]; { - PyObject *right = _tmp_1; - PyObject *middle = _tmp_2; - PyObject *left = _tmp_3; # Body of A } + // B { - PyObject *deep; - PyObject *extra = NULL; - PyObject *res; # Body of B - _tmp_3 = deep; - if (oparg) { _tmp_2 = extra; } - _tmp_1 = res; } STACK_SHRINK(1); STACK_GROW((oparg ? 1 : 0)); - stack_pointer[-1] = _tmp_1; - if (oparg) { stack_pointer[-2] = _tmp_2; } - stack_pointer[-3] = _tmp_3; + stack_pointer[-2 - (oparg ? 1 : 0)] = deep; + if (oparg) { stack_pointer[-1 - (oparg ? 1 : 0)] = extra; } + stack_pointer[-1] = res; DISPATCH(); } """ self.run_cases_test(input, output) + def test_macro_push_push(self): + input = """ + op(A, (-- val1)) { + val1 = spam(); + } + op(B, (-- val2)) { + val2 = spam(); + } + macro(M) = A + B; + """ + output = """ + TARGET(M) { + PyObject *val1; + PyObject *val2; + // A + { + val1 = spam(); + } + // B + { + val2 = spam(); + } + STACK_GROW(2); + stack_pointer[-2] = val1; + stack_pointer[-1] = val2; + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_override_inst(self): + input = """ + inst(OP, (--)) { + spam(); + } + override inst(OP, (--)) { + ham(); + } + """ + output = """ + TARGET(OP) { + ham(); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_override_op(self): + input = """ + op(OP, (--)) { + spam(); + } + macro(M) = OP; + override op(OP, (--)) { + ham(); + } + """ + output = """ + TARGET(M) { + ham(); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index a8a344ab8de48d..d48f0d47ba1962 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -2258,6 +2258,7 @@ def printsolution(self, x): caught ValueError (xyz) >>> import warnings +>>> old_filters = warnings.filters.copy() >>> warnings.filterwarnings("ignore", category=DeprecationWarning) # Filter DeprecationWarning: regarding the (type, val, tb) signature of throw(). @@ -2331,8 +2332,7 @@ def printsolution(self, x): ... ValueError: 7 ->>> warnings.filters.pop(0) -('ignore', None, , None, 0) +>>> warnings.filters[:] = old_filters # Re-enable DeprecationWarning: the (type, val, tb) exception representation is deprecated, # and may be removed in a future version of Python. diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 489044f8090d3b..4f311c2d498e9f 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -460,6 +460,10 @@ def test_normpath_issue5827(self): for path in ('', '.', '/', '\\', '///foo/.//bar//'): self.assertIsInstance(self.pathmodule.normpath(path), str) + def test_normpath_issue106242(self): + for path in ('\x00', 'foo\x00bar', '\x00\x00', '\x00foo', 'foo\x00'): + self.assertEqual(self.pathmodule.normpath(path), path) + def test_abspath_issue3426(self): # Check that abspath returns unicode when the arg is unicode # with both ASCII and non-ASCII cwds. diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index c96a33b77fe272..c8b3442de4aa77 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -1,8 +1,8 @@ # test_getopt.py # David Goodger 2000-08-19 -from test.support import verbose, run_doctest from test.support.os_helper import EnvironmentVarGuard +import doctest import unittest import getopt @@ -134,48 +134,49 @@ def test_gnu_getopt(self): self.assertEqual(opts, [('-a', '')]) self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2']) - def test_libref_examples(self): - s = """ - Examples from the Library Reference: Doc/lib/libgetopt.tex + def test_issue4629(self): + longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) + self.assertEqual(longopts, [('--help', '')]) + longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) + self.assertEqual(longopts, [('--help', 'x')]) + self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) - An example using only Unix style options: +def test_libref_examples(): + """ + Examples from the Library Reference: Doc/lib/libgetopt.tex + An example using only Unix style options: - >>> import getopt - >>> args = '-a -b -cfoo -d bar a1 a2'.split() - >>> args - ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'abc:d:') - >>> optlist - [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] - >>> args - ['a1', 'a2'] - Using long option names is equally easy: + >>> import getopt + >>> args = '-a -b -cfoo -d bar a1 a2'.split() + >>> args + ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'abc:d:') + >>> optlist + [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] + >>> args + ['a1', 'a2'] + Using long option names is equally easy: - >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' - >>> args = s.split() - >>> args - ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'x', [ - ... 'condition=', 'output-file=', 'testing']) - >>> optlist - [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] - >>> args - ['a1', 'a2'] - """ - import types - m = types.ModuleType("libreftest", s) - run_doctest(m, verbose) + >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' + >>> args = s.split() + >>> args + ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'x', [ + ... 'condition=', 'output-file=', 'testing']) + >>> optlist + [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] + >>> args + ['a1', 'a2'] + """ + +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests - def test_issue4629(self): - longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) - self.assertEqual(longopts, [('--help', '')]) - longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) - self.assertEqual(longopts, [('--help', 'x')]) - self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index 1608d1b18e98fb..dd33b9b88f6768 100644 --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -2,6 +2,7 @@ import base64 import gettext import unittest +from functools import partial from test import support from test.support import os_helper @@ -115,9 +116,16 @@ MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo') +def reset_gettext(): + gettext._localedirs.clear() + gettext._current_domain = 'messages' + gettext._translations.clear() + + class GettextBaseTest(unittest.TestCase): - def setUp(self): - self.addCleanup(os_helper.rmtree, os.path.split(LOCALEDIR)[0]) + @classmethod + def setUpClass(cls): + cls.addClassCleanup(os_helper.rmtree, os.path.split(LOCALEDIR)[0]) if not os.path.isdir(LOCALEDIR): os.makedirs(LOCALEDIR) with open(MOFILE, 'wb') as fp: @@ -130,9 +138,12 @@ def setUp(self): fp.write(base64.decodebytes(UMO_DATA)) with open(MMOFILE, 'wb') as fp: fp.write(base64.decodebytes(MMO_DATA)) + + def setUp(self): self.env = self.enterContext(os_helper.EnvironmentVarGuard()) self.env['LANGUAGE'] = 'xx' - gettext._translations.clear() + reset_gettext() + self.addCleanup(reset_gettext) GNU_MO_DATA_ISSUE_17898 = b'''\ @@ -309,47 +320,137 @@ def test_multiline_strings(self): trggrkg zrffntr pngnybt yvoenel.''') -class PluralFormsTestCase(GettextBaseTest): +class PluralFormsTests: + + def _test_plural_forms(self, ngettext, gettext, + singular, plural, tsingular, tplural, + numbers_only=True): + x = ngettext(singular, plural, 1) + self.assertEqual(x, tsingular) + x = ngettext(singular, plural, 2) + self.assertEqual(x, tplural) + x = gettext(singular) + self.assertEqual(x, tsingular) + + if numbers_only: + lineno = self._test_plural_forms.__code__.co_firstlineno + 9 + with self.assertWarns(DeprecationWarning) as cm: + x = ngettext(singular, plural, 1.0) + self.assertEqual(cm.filename, __file__) + self.assertEqual(cm.lineno, lineno + 4) + self.assertEqual(x, tsingular) + with self.assertWarns(DeprecationWarning) as cm: + x = ngettext(singular, plural, 1.1) + self.assertEqual(cm.filename, __file__) + self.assertEqual(cm.lineno, lineno + 9) + self.assertEqual(x, tplural) + with self.assertRaises(TypeError): + ngettext(singular, plural, None) + else: + x = ngettext(singular, plural, None) + self.assertEqual(x, tplural) + + def test_plural_forms(self): + self._test_plural_forms( + self.ngettext, self.gettext, + 'There is %s file', 'There are %s files', + 'Hay %s fichero', 'Hay %s ficheros') + self._test_plural_forms( + self.ngettext, self.gettext, + '%d file deleted', '%d files deleted', + '%d file deleted', '%d files deleted') + + def test_plural_context_forms(self): + ngettext = partial(self.npgettext, 'With context') + gettext = partial(self.pgettext, 'With context') + self._test_plural_forms( + ngettext, gettext, + 'There is %s file', 'There are %s files', + 'Hay %s fichero (context)', 'Hay %s ficheros (context)') + self._test_plural_forms( + ngettext, gettext, + '%d file deleted', '%d files deleted', + '%d file deleted', '%d files deleted') + + def test_plural_wrong_context_forms(self): + self._test_plural_forms( + partial(self.npgettext, 'Unknown context'), + partial(self.pgettext, 'Unknown context'), + 'There is %s file', 'There are %s files', + 'There is %s file', 'There are %s files') + + +class GNUTranslationsPluralFormsTestCase(PluralFormsTests, GettextBaseTest): def setUp(self): GettextBaseTest.setUp(self) - self.mofile = MOFILE + # Set up the bindings + gettext.bindtextdomain('gettext', os.curdir) + gettext.textdomain('gettext') - def test_plural_forms1(self): - eq = self.assertEqual - x = gettext.ngettext('There is %s file', 'There are %s files', 1) - eq(x, 'Hay %s fichero') - x = gettext.ngettext('There is %s file', 'There are %s files', 2) - eq(x, 'Hay %s ficheros') + self.gettext = gettext.gettext + self.ngettext = gettext.ngettext + self.pgettext = gettext.pgettext + self.npgettext = gettext.npgettext - def test_plural_context_forms1(self): - eq = self.assertEqual - x = gettext.npgettext('With context', - 'There is %s file', 'There are %s files', 1) - eq(x, 'Hay %s fichero (context)') - x = gettext.npgettext('With context', - 'There is %s file', 'There are %s files', 2) - eq(x, 'Hay %s ficheros (context)') - - def test_plural_forms2(self): - eq = self.assertEqual - with open(self.mofile, 'rb') as fp: - t = gettext.GNUTranslations(fp) - x = t.ngettext('There is %s file', 'There are %s files', 1) - eq(x, 'Hay %s fichero') - x = t.ngettext('There is %s file', 'There are %s files', 2) - eq(x, 'Hay %s ficheros') - def test_plural_context_forms2(self): - eq = self.assertEqual - with open(self.mofile, 'rb') as fp: +class GNUTranslationsWithDomainPluralFormsTestCase(PluralFormsTests, GettextBaseTest): + def setUp(self): + GettextBaseTest.setUp(self) + # Set up the bindings + gettext.bindtextdomain('gettext', os.curdir) + + self.gettext = partial(gettext.dgettext, 'gettext') + self.ngettext = partial(gettext.dngettext, 'gettext') + self.pgettext = partial(gettext.dpgettext, 'gettext') + self.npgettext = partial(gettext.dnpgettext, 'gettext') + + def test_plural_forms_wrong_domain(self): + self._test_plural_forms( + partial(gettext.dngettext, 'unknown'), + partial(gettext.dgettext, 'unknown'), + 'There is %s file', 'There are %s files', + 'There is %s file', 'There are %s files', + numbers_only=False) + + def test_plural_context_forms_wrong_domain(self): + self._test_plural_forms( + partial(gettext.dnpgettext, 'unknown', 'With context'), + partial(gettext.dpgettext, 'unknown', 'With context'), + 'There is %s file', 'There are %s files', + 'There is %s file', 'There are %s files', + numbers_only=False) + + +class GNUTranslationsClassPluralFormsTestCase(PluralFormsTests, GettextBaseTest): + def setUp(self): + GettextBaseTest.setUp(self) + with open(MOFILE, 'rb') as fp: t = gettext.GNUTranslations(fp) - x = t.npgettext('With context', - 'There is %s file', 'There are %s files', 1) - eq(x, 'Hay %s fichero (context)') - x = t.npgettext('With context', - 'There is %s file', 'There are %s files', 2) - eq(x, 'Hay %s ficheros (context)') + self.gettext = t.gettext + self.ngettext = t.ngettext + self.pgettext = t.pgettext + self.npgettext = t.npgettext + + def test_plural_forms_null_translations(self): + t = gettext.NullTranslations() + self._test_plural_forms( + t.ngettext, t.gettext, + 'There is %s file', 'There are %s files', + 'There is %s file', 'There are %s files', + numbers_only=False) + + def test_plural_context_forms_null_translations(self): + t = gettext.NullTranslations() + self._test_plural_forms( + partial(t.npgettext, 'With context'), + partial(t.pgettext, 'With context'), + 'There is %s file', 'There are %s files', + 'There is %s file', 'There are %s files', + numbers_only=False) + + +class PluralFormsInternalTestCase: # Examples from http://www.gnu.org/software/gettext/manual/gettext.html def test_ja(self): diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index ee105a3de17f8a..8501006b799262 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -12,9 +12,9 @@ # different import patterns to check that __annotations__ does not interfere # with import machinery -import test.ann_module as ann_module +import test.typinganndata.ann_module as ann_module import typing -from test import ann_module2 +from test.typinganndata import ann_module2 import test # These are shared with test_tokenize and other test modules. @@ -236,6 +236,10 @@ def check(test, error=False): check(f"[{num}for x in ()]") check(f"{num}spam", error=True) + # gh-88943: Invalid non-ASCII character following a numerical literal. + with self.assertRaisesRegex(SyntaxError, r"invalid character 'â„' \(U\+2044\)"): + compile(f"{num}â„7", "", "eval") + with self.assertWarnsRegex(SyntaxWarning, r'invalid \w+ literal'): compile(f"{num}is x", "", "eval") with warnings.catch_warnings(): @@ -350,6 +354,11 @@ def test_var_annot_syntax_errors(self): check_syntax_error(self, "x: int: str") check_syntax_error(self, "def f():\n" " nonlocal x: int\n") + check_syntax_error(self, "def f():\n" + " global x: int\n") + check_syntax_error(self, "x: int = y = 1") + check_syntax_error(self, "z = w: int = 1") + check_syntax_error(self, "x: int = y: int = 1") # AST pass check_syntax_error(self, "[x, 0]: int\n") check_syntax_error(self, "f(): int\n") @@ -363,6 +372,12 @@ def test_var_annot_syntax_errors(self): check_syntax_error(self, "def f():\n" " global x\n" " x: int\n") + check_syntax_error(self, "def f():\n" + " x: int\n" + " nonlocal x\n") + check_syntax_error(self, "def f():\n" + " nonlocal x\n" + " x: int\n") def test_var_annot_basic_semantics(self): # execution order @@ -452,7 +467,7 @@ def test_var_annot_module_semantics(self): def test_var_annot_in_module(self): # check that functions fail the same way when executed # outside of module where they were defined - ann_module3 = import_helper.import_fresh_module("test.ann_module3") + ann_module3 = import_helper.import_fresh_module("test.typinganndata.ann_module3") with self.assertRaises(NameError): ann_module3.f_bad_ann() with self.assertRaises(NameError): diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index b06b3b09411d62..128f933787a3f6 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -665,6 +665,18 @@ def flush(self, mode=-1): ] self.assertEqual(fc.modes, expected_modes) + def test_write_seek_write(self): + # Make sure that offset is up-to-date before seeking + # See issue GH-108111 + b = io.BytesIO() + message = b"important message here." + with gzip.GzipFile(fileobj=b, mode='w') as f: + f.write(message) + f.seek(len(message)) + f.write(message) + data = b.getvalue() + self.assertEqual(gzip.decompress(data), message * 2) + class TestOpen(BaseTest): def test_binary_modes(self): diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index fe8105ee2bb3fa..5d5832b62b2f94 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -21,11 +21,13 @@ here = os.path.dirname(__file__) # Self-signed cert file for 'localhost' -CERT_localhost = os.path.join(here, 'keycert.pem') +CERT_localhost = os.path.join(here, 'certdata', 'keycert.pem') # Self-signed cert file for 'fakehostname' -CERT_fakehostname = os.path.join(here, 'keycert2.pem') +CERT_fakehostname = os.path.join(here, 'certdata', 'keycert2.pem') # Self-signed cert file for self-signed.pythontest.net -CERT_selfsigned_pythontestdotnet = os.path.join(here, 'selfsigned_pythontestdotnet.pem') +CERT_selfsigned_pythontestdotnet = os.path.join( + here, 'certdata', 'selfsigned_pythontestdotnet.pem', +) # constants for testing chunked encoding chunked_start = ( @@ -1954,6 +1956,7 @@ def test_networked_good_cert(self): h.close() self.assertIn('nginx', server_string) + @support.requires_resource('walltime') def test_networked_bad_cert(self): # We feed a "CA" cert that is unrelated to the server's cert import ssl diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index cfd8a101dcc1c1..9fa6ecf9c08e27 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -699,11 +699,20 @@ def test_html_escape_filename(self): "This test can't be run reliably as root (issue #13308).") class CGIHTTPServerTestCase(BaseTestCase): class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler): - pass + _test_case_self = None # populated by each setUp() method call. + + def __init__(self, *args, **kwargs): + with self._test_case_self.assertWarnsRegex( + DeprecationWarning, + r'http\.server\.CGIHTTPRequestHandler'): + # This context also happens to catch and silence the + # threading DeprecationWarning from os.fork(). + super().__init__(*args, **kwargs) linesep = os.linesep.encode('ascii') def setUp(self): + self.request_handler._test_case_self = self # practical, but yuck. BaseTestCase.setUp(self) self.cwd = os.getcwd() self.parent_dir = tempfile.mkdtemp() @@ -780,6 +789,7 @@ def setUp(self): os.chdir(self.parent_dir) def tearDown(self): + self.request_handler._test_case_self = None try: os.chdir(self.cwd) if self._pythonexe_symlink: diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index ebb1e8eb823b51..3d8b7ecc0ecb6d 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -3,6 +3,7 @@ from test.support import check_sanitizer if check_sanitizer(address=True, memory=True): + # See gh-90791 for details raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") # Skip test_idle if _tkinter, tkinter, or idlelib are missing. diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 2b2f1f76d26db3..b97474acca370f 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -10,7 +10,7 @@ import threading import socket -from test.support import verbose, run_with_tz, run_with_locale, cpython_only +from test.support import verbose, run_with_tz, run_with_locale, cpython_only, requires_resource from test.support import hashlib_helper from test.support import threading_helper import unittest @@ -23,8 +23,8 @@ support.requires_working_socket(module=True) -CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") -CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") +CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "keycert3.pem") +CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "pycacert.pem") class TestImaplib(unittest.TestCase): @@ -74,6 +74,7 @@ def test_that_Time2Internaldate_returns_a_result(self): for t in self.timevalues(): imaplib.Time2Internaldate(t) + @socket_helper.skip_if_tcp_blackhole def test_imap4_host_default_value(self): # Check whether the IMAP4_PORT is truly unavailable. with socket.socket() as s: @@ -456,6 +457,7 @@ def test_simple_with_statement(self): with self.imap_class(*server.server_address): pass + @requires_resource('walltime') def test_imaplib_timeout_test(self): _, server = self._setup(SimpleIMAPHandler) addr = server.server_address[1] @@ -549,6 +551,7 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): imap_class = IMAP4_SSL server_class = SecureTCPServer + @requires_resource('walltime') def test_ssl_raises(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) @@ -563,6 +566,7 @@ def test_ssl_raises(self): ssl_context=ssl_context) client.shutdown() + @requires_resource('walltime') def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index ec8ccf0bd78d37..aa465c70dfbcd0 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1,5 +1,4 @@ import builtins -import contextlib import errno import glob import json @@ -22,17 +21,17 @@ import types import unittest from unittest import mock -import _testinternalcapi import _imp from test.support import os_helper from test.support import ( STDLIB_DIR, swap_attr, swap_item, cpython_only, is_emscripten, - is_wasi, run_in_subinterp, run_in_subinterp_with_config) + is_wasi, run_in_subinterp, run_in_subinterp_with_config, Py_TRACE_REFS) from test.support.import_helper import ( - forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) + forget, make_legacy_pyc, unlink, unload, ready_to_import, + DirsOnSysPath, CleanImport) from test.support.os_helper import ( - TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE, temp_dir) + TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE) from test.support import script_helper from test.support import threading_helper from test.test_importlib.util import uncache @@ -49,6 +48,10 @@ import _xxsubinterpreters as _interpreters except ModuleNotFoundError: _interpreters = None +try: + import _testinternalcapi +except ImportError: + _testinternalcapi = None skip_if_dont_write_bytecode = unittest.skipIf( @@ -97,7 +100,6 @@ def require_frozen(module, *, skip=True): def require_pure_python(module, *, skip=False): _require_loader(module, SourceFileLoader, skip) - def remove_files(name): for f in (name + ".py", name + ".pyc", @@ -126,40 +128,35 @@ def wrapper(self): return deco -@contextlib.contextmanager -def _ready_to_import(name=None, source=""): - # sets up a temporary directory and removes it - # creates the module file - # temporarily clears the module from sys.modules (if any) - # reverts or removes the module when cleaning up - name = name or "spam" - with temp_dir() as tempdir: - path = script_helper.make_script(tempdir, name, source) - old_module = sys.modules.pop(name, None) - try: - sys.path.insert(0, tempdir) - yield name, path - sys.path.remove(tempdir) - finally: - if old_module is not None: - sys.modules[name] = old_module - elif name in sys.modules: - del sys.modules[name] - - -def requires_subinterpreters(meth): - """Decorator to skip a test if subinterpreters are not supported.""" - return unittest.skipIf(_interpreters is None, - 'subinterpreters required')(meth) +if _testsinglephase is not None: + def restore__testsinglephase(*, _orig=_testsinglephase): + # We started with the module imported and want to restore + # it to its nominal state. + sys.modules.pop('_testsinglephase', None) + _orig._clear_globals() + _testinternalcapi.clear_extension('_testsinglephase', _orig.__file__) + import _testsinglephase def requires_singlephase_init(meth): """Decorator to skip if single-phase init modules are not supported.""" + if not isinstance(meth, type): + def meth(self, _meth=meth): + try: + return _meth(self) + finally: + restore__testsinglephase() meth = cpython_only(meth) return unittest.skipIf(_testsinglephase is None, 'test requires _testsinglephase module')(meth) +def requires_subinterpreters(meth): + """Decorator to skip a test if subinterpreters are not supported.""" + return unittest.skipIf(_interpreters is None, + 'subinterpreters required')(meth) + + class ModuleSnapshot(types.SimpleNamespace): """A representation of a module for testing. @@ -386,7 +383,7 @@ def test_from_import_missing_attr_path_is_canonical(self): def test_from_import_star_invalid_type(self): import re - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): with open(path, 'w', encoding='utf-8') as f: f.write("__all__ = [b'invalid_type']") globals = {} @@ -395,7 +392,7 @@ def test_from_import_star_invalid_type(self): ): exec(f"from {name} import *", globals) self.assertNotIn(b"invalid_type", globals) - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): with open(path, 'w', encoding='utf-8') as f: f.write("globals()[b'invalid_type'] = object()") globals = {} @@ -803,7 +800,7 @@ class FilePermissionTests(unittest.TestCase): ) def test_creation_mode(self): mask = 0o022 - with temp_umask(mask), _ready_to_import() as (name, path): + with temp_umask(mask), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) module = __import__(name) if not os.path.exists(cached_path): @@ -822,7 +819,7 @@ def test_creation_mode(self): def test_cached_mode_issue_2051(self): # permissions of .pyc should match those of .py, regardless of mask mode = 0o600 - with temp_umask(0o022), _ready_to_import() as (name, path): + with temp_umask(0o022), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) os.chmod(path, mode) __import__(name) @@ -838,7 +835,7 @@ def test_cached_mode_issue_2051(self): @os_helper.skip_unless_working_chmod def test_cached_readonly(self): mode = 0o400 - with temp_umask(0o022), _ready_to_import() as (name, path): + with temp_umask(0o022), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) os.chmod(path, mode) __import__(name) @@ -853,7 +850,7 @@ def test_cached_readonly(self): def test_pyc_always_writable(self): # Initially read-only .pyc files on Windows used to cause problems # with later updates, see issue #6074 for details - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): # Write a Python file, make it read-only and import it with open(path, 'w', encoding='utf-8') as f: f.write("x = 'original'\n") @@ -1790,12 +1787,12 @@ def check_compatible_fresh(self, name, *, strict=False, isolated=False): check_multi_interp_extensions=strict, ) _, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f''' - import _testcapi, sys + import _testinternalcapi, sys assert ( {name!r} in sys.builtin_module_names or {name!r} not in sys.modules ), repr({name!r}) - ret = _testcapi.run_in_subinterp_with_config( + ret = _testinternalcapi.run_in_subinterp_with_config( {self.import_script(name, "sys.stdout.fileno()")!r}, **{kwargs}, ) @@ -1814,9 +1811,9 @@ def check_incompatible_fresh(self, name, *, isolated=False): check_multi_interp_extensions=True, ) _, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f''' - import _testcapi, sys + import _testinternalcapi, sys assert {name!r} not in sys.modules, {name!r} - ret = _testcapi.run_in_subinterp_with_config( + ret = _testinternalcapi.run_in_subinterp_with_config( {self.import_script(name, "sys.stdout.fileno()")!r}, **{kwargs}, ) @@ -1962,6 +1959,20 @@ def test_isolated_config(self): with self.subTest(f'{module}: strict, fresh'): self.check_compatible_fresh(module, strict=True, isolated=True) + @requires_subinterpreters + @requires_singlephase_init + def test_disallowed_reimport(self): + # See https://github.com/python/cpython/issues/104621. + script = textwrap.dedent(''' + import _testsinglephase + print(_testsinglephase) + ''') + interpid = _interpreters.create() + with self.assertRaises(_interpreters.RunFailedError): + _interpreters.run_string(interpid, script) + with self.assertRaises(_interpreters.RunFailedError): + _interpreters.run_string(interpid, script) + class TestSinglePhaseSnapshot(ModuleSnapshot): @@ -2017,6 +2028,10 @@ def setUpClass(cls): # Start fresh. cls.clean_up() + @classmethod + def tearDownClass(cls): + restore__testsinglephase() + def tearDown(self): # Clean up the module. self.clean_up() @@ -2093,7 +2108,7 @@ def clean_up(): _interpreters.run_string(interpid, textwrap.dedent(f''' name = {self.NAME!r} if name in sys.modules: - sys.modules[name]._clear_globals() + sys.modules.pop(name)._clear_globals() _testinternalcapi.clear_extension(name, {self.FILE!r}) ''')) _interpreters.destroy(interpid) @@ -2522,6 +2537,12 @@ def test_basic_multiple_interpreters_main_no_reset(self): def test_basic_multiple_interpreters_deleted_no_reset(self): # without resetting; already loaded in a deleted interpreter + if Py_TRACE_REFS: + # It's a Py_TRACE_REFS build. + # This test breaks interpreter isolation a little, + # which causes problems on Py_TRACE_REF builds. + raise unittest.SkipTest('crashes on Py_TRACE_REFS builds') + # At this point: # * alive in 0 interpreters # * module def may or may not be loaded already diff --git a/Lib/test/test_importlib/import_/test_packages.py b/Lib/test/test_importlib/import_/test_packages.py index eb0831f7d6d54b..0c29d6083265fa 100644 --- a/Lib/test/test_importlib/import_/test_packages.py +++ b/Lib/test/test_importlib/import_/test_packages.py @@ -1,7 +1,6 @@ from test.test_importlib import util import sys import unittest -from test import support from test.support import import_helper diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py index ba9cf51c261d52..befac5d62b0abf 100644 --- a/Lib/test/test_importlib/test_locks.py +++ b/Lib/test/test_importlib/test_locks.py @@ -29,6 +29,8 @@ class ModuleLockAsRLockTests: test_timeout = None # _release_save() unsupported test_release_save_unacquired = None + # _recursion_count() unsupported + test_recursion_count = None # lock status in repr unsupported test_repr = None test_locked_repr = None @@ -91,7 +93,8 @@ def f(): b.release() if ra: a.release() - lock_tests.Bunch(f, NTHREADS).wait_for_finished() + with lock_tests.Bunch(f, NTHREADS): + pass self.assertEqual(len(results), NTHREADS) return results diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py index a7586b3d95dc14..a60a4c4cebcf1a 100644 --- a/Lib/test/test_importlib/test_windows.py +++ b/Lib/test/test_importlib/test_windows.py @@ -4,6 +4,7 @@ import os import re import sys +import sysconfig import unittest from test.support import import_helper from contextlib import contextmanager @@ -111,8 +112,10 @@ def test_module_not_found(self): class WindowsExtensionSuffixTests: def test_tagged_suffix(self): suffixes = self.machinery.EXTENSION_SUFFIXES - expected_tag = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info, - re.sub('[^a-zA-Z0-9]', '_', get_platform())) + abi_flags = "t" if sysconfig.get_config_var("Py_NOGIL") else "" + ver = sys.version_info + platform = re.sub('[^a-zA-Z0-9]', '_', get_platform()) + expected_tag = f".cp{ver.major}{ver.minor}{abi_flags}-{platform}.pyd" try: untagged_i = suffixes.index(".pyd") except ValueError: diff --git a/Lib/test/test_inspect/__init__.py b/Lib/test/test_inspect/__init__.py new file mode 100644 index 00000000000000..f2a39a3fe29c7f --- /dev/null +++ b/Lib/test/test_inspect/__init__.py @@ -0,0 +1,6 @@ +import os +from test import support + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/inspect_fodder.py b/Lib/test/test_inspect/inspect_fodder.py similarity index 100% rename from Lib/test/inspect_fodder.py rename to Lib/test/test_inspect/inspect_fodder.py diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/test_inspect/inspect_fodder2.py similarity index 100% rename from Lib/test/inspect_fodder2.py rename to Lib/test/test_inspect/inspect_fodder2.py diff --git a/Lib/test/inspect_stock_annotations.py b/Lib/test/test_inspect/inspect_stock_annotations.py similarity index 100% rename from Lib/test/inspect_stock_annotations.py rename to Lib/test/test_inspect/inspect_stock_annotations.py diff --git a/Lib/test/inspect_stringized_annotations.py b/Lib/test/test_inspect/inspect_stringized_annotations.py similarity index 100% rename from Lib/test/inspect_stringized_annotations.py rename to Lib/test/test_inspect/inspect_stringized_annotations.py diff --git a/Lib/test/inspect_stringized_annotations_2.py b/Lib/test/test_inspect/inspect_stringized_annotations_2.py similarity index 100% rename from Lib/test/inspect_stringized_annotations_2.py rename to Lib/test/test_inspect/inspect_stringized_annotations_2.py diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect/test_inspect.py similarity index 95% rename from Lib/test/test_inspect.py rename to Lib/test/test_inspect/test_inspect.py index 33a593f3591d68..31ac6b1070a0a2 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -1,6 +1,7 @@ import asyncio import builtins import collections +import copy import datetime import functools import importlib @@ -13,14 +14,18 @@ import _pickle import pickle import shutil +import stat import sys +import time import types +import tempfile import textwrap import unicodedata import unittest import unittest.mock import warnings + try: from concurrent.futures import ThreadPoolExecutor except ImportError: @@ -28,17 +33,16 @@ from test.support import cpython_only from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ -from test.support.import_helper import DirsOnSysPath +from test.support.import_helper import DirsOnSysPath, ready_to_import from test.support.os_helper import TESTFN from test.support.script_helper import assert_python_ok, assert_python_failure -from test import inspect_fodder as mod -from test import inspect_fodder2 as mod2 from test import support -from test import inspect_stock_annotations -from test import inspect_stringized_annotations -from test import inspect_stringized_annotations_2 -from test.test_import import _ready_to_import +from . import inspect_fodder as mod +from . import inspect_fodder2 as mod2 +from . import inspect_stock_annotations +from . import inspect_stringized_annotations +from . import inspect_stringized_annotations_2 # Functions tested in this suite: @@ -135,6 +139,14 @@ def gen_coroutine_function_example(self): yield return 'spam' +def meth_noargs(): pass +def meth_o(object, /): pass +def meth_self_noargs(self, /): pass +def meth_self_o(self, object, /): pass +def meth_type_noargs(type, /): pass +def meth_type_o(type, object, /): pass + + class TestPredicates(IsTestBase): def test_excluding_predicates(self): @@ -963,6 +975,36 @@ def test_nested_class_definition_inside_function(self): self.assertSourceEqual(mod2.cls213, 218, 222) self.assertSourceEqual(mod2.cls213().func219(), 220, 221) + def test_class_with_method_from_other_module(self): + with tempfile.TemporaryDirectory() as tempdir: + with open(os.path.join(tempdir, 'inspect_actual%spy' % os.extsep), + 'w', encoding='utf-8') as f: + f.write(textwrap.dedent(""" + import inspect_other + class A: + def f(self): + pass + class A: + def f(self): + pass # correct one + A.f = inspect_other.A.f + """)) + + with open(os.path.join(tempdir, 'inspect_other%spy' % os.extsep), + 'w', encoding='utf-8') as f: + f.write(textwrap.dedent(""" + class A: + def f(self): + pass + """)) + + with DirsOnSysPath(tempdir): + import inspect_actual + self.assertIn("correct", inspect.getsource(inspect_actual.A)) + # Remove the module from sys.modules to force it to be reloaded. + # This is necessary when the test is run multiple times. + sys.modules.pop("inspect_actual") + @unittest.skipIf( support.is_emscripten or support.is_wasi, "socket.accept is broken" @@ -1142,6 +1184,47 @@ def test_getfullargspec_builtin_func_no_signature(self): with self.assertRaises(TypeError): inspect.getfullargspec(builtin) + cls = _testcapi.DocStringNoSignatureTest + obj = _testcapi.DocStringNoSignatureTest() + tests = [ + (_testcapi.docstring_no_signature_noargs, meth_noargs), + (_testcapi.docstring_no_signature_o, meth_o), + (cls.meth_noargs, meth_self_noargs), + (cls.meth_o, meth_self_o), + (obj.meth_noargs, meth_self_noargs), + (obj.meth_o, meth_self_o), + (cls.meth_noargs_class, meth_type_noargs), + (cls.meth_o_class, meth_type_o), + (cls.meth_noargs_static, meth_noargs), + (cls.meth_o_static, meth_o), + (cls.meth_noargs_coexist, meth_self_noargs), + (cls.meth_o_coexist, meth_self_o), + + (time.time, meth_noargs), + (str.lower, meth_self_noargs), + (''.lower, meth_self_noargs), + (set.add, meth_self_o), + (set().add, meth_self_o), + (set.__contains__, meth_self_o), + (set().__contains__, meth_self_o), + (datetime.datetime.__dict__['utcnow'], meth_type_noargs), + (datetime.datetime.utcnow, meth_type_noargs), + (dict.__dict__['__class_getitem__'], meth_type_o), + (dict.__class_getitem__, meth_type_o), + ] + try: + import _stat + except ImportError: + # if the _stat extension is not available, stat.S_IMODE() is + # implemented in Python, not in C + pass + else: + tests.append((stat.S_IMODE, meth_o)) + for builtin, template in tests: + with self.subTest(builtin): + self.assertEqual(inspect.getfullargspec(builtin), + inspect.getfullargspec(template)) + def test_getfullargspec_definition_order_preserved_on_kwonly(self): for fn in signatures_with_lexicographic_keyword_only_parameters(): signature = inspect.getfullargspec(fn) @@ -2857,6 +2940,47 @@ def test_signature_on_builtins_no_signature(self): 'no signature found for builtin'): inspect.signature(str) + cls = _testcapi.DocStringNoSignatureTest + obj = _testcapi.DocStringNoSignatureTest() + tests = [ + (_testcapi.docstring_no_signature_noargs, meth_noargs), + (_testcapi.docstring_no_signature_o, meth_o), + (cls.meth_noargs, meth_self_noargs), + (cls.meth_o, meth_self_o), + (obj.meth_noargs, meth_noargs), + (obj.meth_o, meth_o), + (cls.meth_noargs_class, meth_noargs), + (cls.meth_o_class, meth_o), + (cls.meth_noargs_static, meth_noargs), + (cls.meth_o_static, meth_o), + (cls.meth_noargs_coexist, meth_self_noargs), + (cls.meth_o_coexist, meth_self_o), + + (time.time, meth_noargs), + (str.lower, meth_self_noargs), + (''.lower, meth_noargs), + (set.add, meth_self_o), + (set().add, meth_o), + (set.__contains__, meth_self_o), + (set().__contains__, meth_o), + (datetime.datetime.__dict__['utcnow'], meth_type_noargs), + (datetime.datetime.utcnow, meth_noargs), + (dict.__dict__['__class_getitem__'], meth_type_o), + (dict.__class_getitem__, meth_o), + ] + try: + import _stat + except ImportError: + # if the _stat extension is not available, stat.S_IMODE() is + # implemented in Python, not in C + pass + else: + tests.append((stat.S_IMODE, meth_o)) + for builtin, template in tests: + with self.subTest(builtin): + self.assertEqual(inspect.signature(builtin), + inspect.signature(template)) + def test_signature_on_non_function(self): with self.assertRaisesRegex(TypeError, 'is not a callable object'): inspect.signature(42) @@ -3706,6 +3830,28 @@ def test(a_po, /, *, b, **kwargs): P('bar', P.VAR_POSITIONAL)])), '(foo, /, *bar)') + def test_signature_replace_parameters(self): + def test(a, b) -> 42: + pass + + sig = inspect.signature(test) + parameters = sig.parameters + sig = sig.replace(parameters=list(parameters.values())[1:]) + self.assertEqual(list(sig.parameters), ['b']) + self.assertEqual(sig.parameters['b'], parameters['b']) + self.assertEqual(sig.return_annotation, 42) + sig = sig.replace(parameters=()) + self.assertEqual(dict(sig.parameters), {}) + + sig = inspect.signature(test) + parameters = sig.parameters + sig = copy.replace(sig, parameters=list(parameters.values())[1:]) + self.assertEqual(list(sig.parameters), ['b']) + self.assertEqual(sig.parameters['b'], parameters['b']) + self.assertEqual(sig.return_annotation, 42) + sig = copy.replace(sig, parameters=()) + self.assertEqual(dict(sig.parameters), {}) + def test_signature_replace_anno(self): def test() -> 42: pass @@ -3719,6 +3865,15 @@ def test() -> 42: self.assertEqual(sig.return_annotation, 42) self.assertEqual(sig, inspect.signature(test)) + sig = inspect.signature(test) + sig = copy.replace(sig, return_annotation=None) + self.assertIs(sig.return_annotation, None) + sig = copy.replace(sig, return_annotation=sig.empty) + self.assertIs(sig.return_annotation, sig.empty) + sig = copy.replace(sig, return_annotation=42) + self.assertEqual(sig.return_annotation, 42) + self.assertEqual(sig, inspect.signature(test)) + def test_signature_replaced(self): def test(): pass @@ -4063,41 +4218,66 @@ def test_signature_parameter_replace(self): p = inspect.Parameter('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY) - self.assertIsNot(p, p.replace()) - self.assertEqual(p, p.replace()) + self.assertIsNot(p.replace(), p) + self.assertEqual(p.replace(), p) + self.assertIsNot(copy.replace(p), p) + self.assertEqual(copy.replace(p), p) p2 = p.replace(annotation=1) self.assertEqual(p2.annotation, 1) p2 = p2.replace(annotation=p2.empty) - self.assertEqual(p, p2) + self.assertEqual(p2, p) + p3 = copy.replace(p, annotation=1) + self.assertEqual(p3.annotation, 1) + p3 = copy.replace(p3, annotation=p3.empty) + self.assertEqual(p3, p) p2 = p2.replace(name='bar') self.assertEqual(p2.name, 'bar') self.assertNotEqual(p2, p) + p3 = copy.replace(p3, name='bar') + self.assertEqual(p3.name, 'bar') + self.assertNotEqual(p3, p) with self.assertRaisesRegex(ValueError, 'name is a required attribute'): p2 = p2.replace(name=p2.empty) + with self.assertRaisesRegex(ValueError, + 'name is a required attribute'): + p3 = copy.replace(p3, name=p3.empty) p2 = p2.replace(name='foo', default=None) self.assertIs(p2.default, None) self.assertNotEqual(p2, p) + p3 = copy.replace(p3, name='foo', default=None) + self.assertIs(p3.default, None) + self.assertNotEqual(p3, p) p2 = p2.replace(name='foo', default=p2.empty) self.assertIs(p2.default, p2.empty) - + p3 = copy.replace(p3, name='foo', default=p3.empty) + self.assertIs(p3.default, p3.empty) p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD) self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD) self.assertNotEqual(p2, p) + p3 = copy.replace(p3, default=42, kind=p3.POSITIONAL_OR_KEYWORD) + self.assertEqual(p3.kind, p3.POSITIONAL_OR_KEYWORD) + self.assertNotEqual(p3, p) with self.assertRaisesRegex(ValueError, "value " "is not a valid Parameter.kind"): p2 = p2.replace(kind=p2.empty) + with self.assertRaisesRegex(ValueError, + "value " + "is not a valid Parameter.kind"): + p3 = copy.replace(p3, kind=p3.empty) p2 = p2.replace(kind=p2.KEYWORD_ONLY) self.assertEqual(p2, p) + p3 = copy.replace(p3, kind=p3.KEYWORD_ONLY) + self.assertEqual(p3, p) def test_signature_parameter_positional_only(self): with self.assertRaisesRegex(TypeError, 'name must be a str'): @@ -4618,7 +4798,7 @@ def func(*args, **kwargs): def test_base_class_have_text_signature(self): # see issue 43118 - from test.ann_module7 import BufferedReader + from test.typinganndata.ann_module7 import BufferedReader class MyBufferedReader(BufferedReader): """buffer reader class.""" @@ -4773,7 +4953,7 @@ def assertInspectEqual(self, path, source): def test_getsource_reload(self): # see issue 1218234 - with _ready_to_import('reload_bug', self.src_before) as (name, path): + with ready_to_import('reload_bug', self.src_before) as (name, path): module = importlib.import_module(name) self.assertInspectEqual(path, module) with open(path, 'w', encoding='utf-8') as src: diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py index d1bebe47158322..0910b51bfe5dbd 100644 --- a/Lib/test/test_interpreters.py +++ b/Lib/test/test_interpreters.py @@ -1,5 +1,8 @@ import contextlib +import json import os +import os.path +import sys import threading from textwrap import dedent import unittest @@ -7,6 +10,8 @@ from test import support from test.support import import_helper +from test.support import threading_helper +from test.support import os_helper _interpreters = import_helper.import_module('_xxsubinterpreters') _channels = import_helper.import_module('_xxinterpchannels') from test.support import interpreters @@ -63,6 +68,17 @@ def run(): class TestBase(unittest.TestCase): + def pipe(self): + def ensure_closed(fd): + try: + os.close(fd) + except OSError: + pass + r, w = os.pipe() + self.addCleanup(lambda: ensure_closed(r)) + self.addCleanup(lambda: ensure_closed(w)) + return r, w + def tearDown(self): clean_up_interpreters() @@ -256,6 +272,16 @@ def test_subinterpreter(self): self.assertTrue(interp.is_running()) self.assertFalse(interp.is_running()) + def test_finished(self): + r, w = self.pipe() + interp = interpreters.create() + interp.run(f"""if True: + import os + os.write({w}, b'x') + """) + self.assertFalse(interp.is_running()) + self.assertEqual(os.read(r, 1), b'x') + def test_from_subinterpreter(self): interp = interpreters.create() out = _run_output(interp, dedent(f""" @@ -283,6 +309,31 @@ def test_bad_id(self): with self.assertRaises(ValueError): interp.is_running() + def test_with_only_background_threads(self): + r_interp, w_interp = self.pipe() + r_thread, w_thread = self.pipe() + + DONE = b'D' + FINISHED = b'F' + + interp = interpreters.create() + interp.run(f"""if True: + import os + import threading + + def task(): + v = os.read({r_thread}, 1) + assert v == {DONE!r} + os.write({w_interp}, {FINISHED!r}) + t = threading.Thread(target=task) + t.start() + """) + self.assertFalse(interp.is_running()) + + os.write(w_thread, DONE) + interp.run('t.join()') + self.assertEqual(os.read(r_interp, 1), FINISHED) + class TestInterpreterClose(TestBase): @@ -384,6 +435,37 @@ def test_still_running(self): interp.close() self.assertTrue(interp.is_running()) + def test_subthreads_still_running(self): + r_interp, w_interp = self.pipe() + r_thread, w_thread = self.pipe() + + FINISHED = b'F' + + interp = interpreters.create() + interp.run(f"""if True: + import os + import threading + import time + + done = False + + def notify_fini(): + global done + done = True + t.join() + threading._register_atexit(notify_fini) + + def task(): + while not done: + time.sleep(0.1) + os.write({w_interp}, {FINISHED!r}) + t = threading.Thread(target=task) + t.start() + """) + interp.close() + + self.assertEqual(os.read(r_interp, 1), FINISHED) + class TestInterpreterRun(TestBase): @@ -460,9 +542,231 @@ def test_bytes_for_script(self): with self.assertRaises(TypeError): interp.run(b'print("spam")') + def test_with_background_threads_still_running(self): + r_interp, w_interp = self.pipe() + r_thread, w_thread = self.pipe() + + RAN = b'R' + DONE = b'D' + FINISHED = b'F' + + interp = interpreters.create() + interp.run(f"""if True: + import os + import threading + + def task(): + v = os.read({r_thread}, 1) + assert v == {DONE!r} + os.write({w_interp}, {FINISHED!r}) + t = threading.Thread(target=task) + t.start() + os.write({w_interp}, {RAN!r}) + """) + interp.run(f"""if True: + os.write({w_interp}, {RAN!r}) + """) + + os.write(w_thread, DONE) + interp.run('t.join()') + self.assertEqual(os.read(r_interp, 1), RAN) + self.assertEqual(os.read(r_interp, 1), RAN) + self.assertEqual(os.read(r_interp, 1), FINISHED) + # test_xxsubinterpreters covers the remaining Interpreter.run() behavior. +class StressTests(TestBase): + + # In these tests we generally want a lot of interpreters, + # but not so many that any test takes too long. + + @support.requires_resource('cpu') + def test_create_many_sequential(self): + alive = [] + for _ in range(100): + interp = interpreters.create() + alive.append(interp) + + @support.requires_resource('cpu') + def test_create_many_threaded(self): + alive = [] + def task(): + interp = interpreters.create() + alive.append(interp) + threads = (threading.Thread(target=task) for _ in range(200)) + with threading_helper.start_threads(threads): + pass + + +class StartupTests(TestBase): + + # We want to ensure the initial state of subinterpreters + # matches expectations. + + _subtest_count = 0 + + @contextlib.contextmanager + def subTest(self, *args): + with super().subTest(*args) as ctx: + self._subtest_count += 1 + try: + yield ctx + finally: + if self._debugged_in_subtest: + if self._subtest_count == 1: + # The first subtest adds a leading newline, so we + # compensate here by not printing a trailing newline. + print('### end subtest debug ###', end='') + else: + print('### end subtest debug ###') + self._debugged_in_subtest = False + + def debug(self, msg, *, header=None): + if header: + self._debug(f'--- {header} ---') + if msg: + if msg.endswith(os.linesep): + self._debug(msg[:-len(os.linesep)]) + else: + self._debug(msg) + self._debug('') + self._debug('------') + else: + self._debug(msg) + + _debugged = False + _debugged_in_subtest = False + def _debug(self, msg): + if not self._debugged: + print() + self._debugged = True + if self._subtest is not None: + if True: + if not self._debugged_in_subtest: + self._debugged_in_subtest = True + print('### start subtest debug ###') + print(msg) + else: + print(msg) + + def create_temp_dir(self): + import tempfile + tmp = tempfile.mkdtemp(prefix='test_interpreters_') + tmp = os.path.realpath(tmp) + self.addCleanup(os_helper.rmtree, tmp) + return tmp + + def write_script(self, *path, text): + filename = os.path.join(*path) + dirname = os.path.dirname(filename) + if dirname: + os.makedirs(dirname, exist_ok=True) + with open(filename, 'w', encoding='utf-8') as outfile: + outfile.write(dedent(text)) + return filename + + @support.requires_subprocess() + def run_python(self, argv, *, cwd=None): + # This method is inspired by + # EmbeddingTestsMixin.run_embedded_interpreter() in test_embed.py. + import shlex + import subprocess + if isinstance(argv, str): + argv = shlex.split(argv) + argv = [sys.executable, *argv] + try: + proc = subprocess.run( + argv, + cwd=cwd, + capture_output=True, + text=True, + ) + except Exception as exc: + self.debug(f'# cmd: {shlex.join(argv)}') + if isinstance(exc, FileNotFoundError) and not exc.filename: + if os.path.exists(argv[0]): + exists = 'exists' + else: + exists = 'does not exist' + self.debug(f'{argv[0]} {exists}') + raise # re-raise + assert proc.stderr == '' or proc.returncode != 0, proc.stderr + if proc.returncode != 0 and support.verbose: + self.debug(f'# python3 {shlex.join(argv[1:])} failed:') + self.debug(proc.stdout, header='stdout') + self.debug(proc.stderr, header='stderr') + self.assertEqual(proc.returncode, 0) + self.assertEqual(proc.stderr, '') + return proc.stdout + + def test_sys_path_0(self): + # The main interpreter's sys.path[0] should be used by subinterpreters. + script = ''' + import sys + from test.support import interpreters + + orig = sys.path[0] + + interp = interpreters.create() + interp.run(f"""if True: + import json + import sys + print(json.dumps({{ + 'main': {orig!r}, + 'sub': sys.path[0], + }}, indent=4), flush=True) + """) + ''' + # / + # pkg/ + # __init__.py + # __main__.py + # script.py + # script.py + cwd = self.create_temp_dir() + self.write_script(cwd, 'pkg', '__init__.py', text='') + self.write_script(cwd, 'pkg', '__main__.py', text=script) + self.write_script(cwd, 'pkg', 'script.py', text=script) + self.write_script(cwd, 'script.py', text=script) + + cases = [ + ('script.py', cwd), + ('-m script', cwd), + ('-m pkg', cwd), + ('-m pkg.script', cwd), + ('-c "import script"', ''), + ] + for argv, expected in cases: + with self.subTest(f'python3 {argv}'): + out = self.run_python(argv, cwd=cwd) + data = json.loads(out) + sp0_main, sp0_sub = data['main'], data['sub'] + self.assertEqual(sp0_sub, sp0_main) + self.assertEqual(sp0_sub, expected) + # XXX Also check them all with the -P cmdline flag? + + +class FinalizationTests(TestBase): + + def test_gh_109793(self): + import subprocess + argv = [sys.executable, '-c', '''if True: + import _xxsubinterpreters as _interpreters + interpid = _interpreters.create() + raise Exception + '''] + proc = subprocess.run(argv, capture_output=True, text=True) + self.assertIn('Traceback', proc.stderr) + if proc.returncode == 0 and support.verbose: + print() + print("--- cmd unexpected succeeded ---") + print(f"stdout:\n{proc.stdout}") + print(f"stderr:\n{proc.stderr}") + print("------") + self.assertEqual(proc.returncode, 1) + + class TestIsShareable(TestBase): def test_default_shareables(self): @@ -529,6 +833,23 @@ def test_list_all(self): after = set(interpreters.list_all_channels()) self.assertEqual(after, created) + @unittest.expectedFailure # See gh-110318: + def test_shareable(self): + rch, sch = interpreters.create_channel() + + self.assertTrue( + interpreters.is_shareable(rch)) + self.assertTrue( + interpreters.is_shareable(sch)) + + sch.send_nowait(rch) + sch.send_nowait(sch) + rch2 = rch.recv() + sch2 = rch.recv() + + self.assertEqual(rch2, rch) + self.assertEqual(sch2, sch) + class TestRecvChannelAttrs(TestBase): @@ -643,8 +964,8 @@ def f(): orig = b'spam' s.send(orig) - t.join() obj = r.recv() + t.join() self.assertEqual(obj, orig) self.assertIsNot(obj, orig) @@ -746,3 +1067,46 @@ def test_recv_nowait_default(self): self.assertEqual(obj4, b'spam') self.assertEqual(obj5, b'eggs') self.assertIs(obj6, default) + + def test_send_buffer(self): + buf = bytearray(b'spamspamspam') + obj = None + rch, sch = interpreters.create_channel() + + def f(): + nonlocal obj + while True: + try: + obj = rch.recv() + break + except interpreters.ChannelEmptyError: + time.sleep(0.1) + t = threading.Thread(target=f) + t.start() + + sch.send_buffer(buf) + t.join() + + self.assertIsNot(obj, buf) + self.assertIsInstance(obj, memoryview) + self.assertEqual(obj, buf) + + buf[4:8] = b'eggs' + self.assertEqual(obj, buf) + obj[4:8] = b'ham.' + self.assertEqual(obj, buf) + + def test_send_buffer_nowait(self): + buf = bytearray(b'spamspamspam') + rch, sch = interpreters.create_channel() + sch.send_buffer_nowait(buf) + obj = rch.recv() + + self.assertIsNot(obj, buf) + self.assertIsInstance(obj, memoryview) + self.assertEqual(obj, buf) + + buf[4:8] = b'eggs' + self.assertEqual(obj, buf) + obj[4:8] = b'ham.' + self.assertEqual(obj, buf) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 26ae40d93c84eb..022cf21a4709a2 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1541,8 +1541,8 @@ def test_read_all(self): self.assertEqual(b"abcdefg", bufio.read()) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes with exactly the same number of 0's, @@ -1930,8 +1930,8 @@ def test_truncate_after_write(self): f.truncate() self.assertEqual(f.tell(), buffer_size + 2) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes from many threads and test they were @@ -4468,10 +4468,12 @@ def run(): self.assertFalse(err.strip('.!')) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stdout_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stdout') @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stderr_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stderr') @@ -4645,11 +4647,13 @@ def alarm_handler(sig, frame): os.close(r) @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_buffered(self): self.check_interrupted_read_retry(lambda x: x.decode('latin1'), mode="rb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_text(self): self.check_interrupted_read_retry(lambda x: x, mode="r", encoding="latin1") @@ -4723,10 +4727,12 @@ def alarm2(sig, frame): raise @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_buffered(self): self.check_interrupted_write_retry(b"x", mode="wb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_text(self): self.check_interrupted_write_retry("x", mode="w", encoding="latin1") diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index a5388b2e5debd8..6f204948c9fc48 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1321,6 +1321,17 @@ def testGetIp(self): self.assertEqual(str(self.ipv6_scoped_interface.ip), '2001:658:22a:cafe:200::1') + def testIPv6IPv4MappedStringRepresentation(self): + long_prefix = '0000:0000:0000:0000:0000:ffff:' + short_prefix = '::ffff:' + ipv4 = '1.2.3.4' + ipv6_ipv4_str = short_prefix + ipv4 + ipv6_ipv4_addr = ipaddress.IPv6Address(ipv6_ipv4_str) + ipv6_ipv4_iface = ipaddress.IPv6Interface(ipv6_ipv4_str) + self.assertEqual(str(ipv6_ipv4_addr), ipv6_ipv4_str) + self.assertEqual(ipv6_ipv4_addr.exploded, long_prefix + ipv4) + self.assertEqual(str(ipv6_ipv4_iface.ip), ipv6_ipv4_str) + def testGetScopeId(self): self.assertEqual(self.ipv6_address.scope_id, None) diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 4d6ea780e15373..512745e45350d1 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -2401,6 +2401,7 @@ def gen2(x): self.assertEqual(hist, [0,1]) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_long_chain_of_empty_iterables(self): # Make sure itertools.chain doesn't run into recursion limits when # dealing with long chains of empty iterables. Even with a high diff --git a/Lib/test/test_largefile.py b/Lib/test/test_largefile.py index 3c11c59baef6e5..3b0930fe69e30e 100644 --- a/Lib/test/test_largefile.py +++ b/Lib/test/test_largefile.py @@ -8,7 +8,7 @@ import socket import shutil import threading -from test.support import requires, bigmemtest +from test.support import requires, bigmemtest, requires_resource from test.support import SHORT_TIMEOUT from test.support import socket_helper from test.support.os_helper import TESTFN, unlink @@ -173,6 +173,7 @@ class TestCopyfile(LargeFileTest, unittest.TestCase): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): # Internally shutil.copyfile() can use "fast copy" methods like # os.sendfile(). @@ -222,6 +223,7 @@ def run(sock): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): port = socket_helper.find_unused_port() with socket.create_server(("", port)) as sock: diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index 362b507d158288..bcd4ed63bf25a0 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -717,3 +717,25 @@ def test_literal_shebang_invalid_template(self): f"{expect} arg1 {script}", data["stdout"].strip(), ) + + def test_shebang_command_in_venv(self): + stem = "python-that-is-not-on-path" + + # First ensure that our test name doesn't exist, and the launcher does + # not match any installed env + with self.script(f'#! /usr/bin/env {stem} arg1') as script: + data = self.run_py([script], expect_returncode=103) + + with self.fake_venv() as (venv_exe, env): + # Put a real Python (ourselves) on PATH as a distraction. + # The active VIRTUAL_ENV should be preferred when the name isn't an + # exact match. + env["PATH"] = f"{Path(sys.executable).parent};{os.environ['PATH']}" + + with self.script(f'#! /usr/bin/env {stem} arg1') as script: + data = self.run_py([script], env=env) + self.assertEqual(data["stdout"].strip(), f"{venv_exe} arg1 {script}") + + with self.script(f'#! /usr/bin/env {Path(sys.executable).stem} arg1') as script: + data = self.run_py([script], env=env) + self.assertEqual(data["stdout"].strip(), f"{sys.executable} arg1 {script}") diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index 9f28ced32bd26c..12f7bbd123b30c 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -125,7 +125,7 @@ def get_output(moddict, name): self.assertIs(type(e), raises) else: for k, v in (outputs or {}).items(): - self.assertEqual(get_output(newns, k), v) + self.assertEqual(get_output(newns, k), v, k) def test_lambdas_with_iteration_var_as_default(self): code = """ @@ -561,6 +561,58 @@ def test_iter_var_available_in_locals(self): } ) + def test_comp_in_try_except(self): + template = """ + value = ["ab"] + result = snapshot = None + try: + result = [{func}(value) for value in value] + except: + snapshot = value + raise + """ + # No exception. + code = template.format(func='len') + self._check_in_scopes(code, {"value": ["ab"], "result": [2], "snapshot": None}) + # Handles exception. + code = template.format(func='int') + self._check_in_scopes(code, {"value": ["ab"], "result": None, "snapshot": ["ab"]}, + raises=ValueError) + + def test_comp_in_try_finally(self): + template = """ + value = ["ab"] + result = snapshot = None + try: + result = [{func}(value) for value in value] + finally: + snapshot = value + """ + # No exception. + code = template.format(func='len') + self._check_in_scopes(code, {"value": ["ab"], "result": [2], "snapshot": ["ab"]}) + # Handles exception. + code = template.format(func='int') + self._check_in_scopes(code, {"value": ["ab"], "result": None, "snapshot": ["ab"]}, + raises=ValueError) + + def test_exception_in_post_comp_call(self): + code = """ + value = [1, None] + try: + [v for v in value].sort() + except: + pass + """ + self._check_in_scopes(code, {"value": [1, None]}) + + def test_frame_locals(self): + code = """ + val = [sys._getframe().f_locals for a in [0]][0]["a"] + """ + import sys + self._check_in_scopes(code, {"val": 0}, ns={"sys": sys}) + __test__ = {'doctests' : doctests} diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 18258c22874ae0..ab969ce26a69e7 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -76,6 +76,13 @@ pass +# gh-89363: Skip fork() test if Python is built with Address Sanitizer (ASAN) +# to work around a libasan race condition, dead lock in pthread_create(). +skip_if_asan_fork = unittest.skipIf( + support.HAVE_ASAN_FORK_BUG, + "libasan has a pthread_create() dead lock related to thread+fork") + + class BaseTest(unittest.TestCase): """Base class for logging tests.""" @@ -90,8 +97,7 @@ def setUp(self): self._threading_key = threading_helper.threading_setup() logger_dict = logging.getLogger().manager.loggerDict - logging._acquireLock() - try: + with logging._lock: self.saved_handlers = logging._handlers.copy() self.saved_handler_list = logging._handlerList[:] self.saved_loggers = saved_loggers = logger_dict.copy() @@ -101,8 +107,6 @@ def setUp(self): for name in saved_loggers: logger_states[name] = getattr(saved_loggers[name], 'disabled', None) - finally: - logging._releaseLock() # Set two unused loggers self.logger1 = logging.getLogger("\xab\xd7\xbb") @@ -136,8 +140,7 @@ def tearDown(self): self.root_logger.removeHandler(h) h.close() self.root_logger.setLevel(self.original_logging_level) - logging._acquireLock() - try: + with logging._lock: logging._levelToName.clear() logging._levelToName.update(self.saved_level_to_name) logging._nameToLevel.clear() @@ -154,8 +157,6 @@ def tearDown(self): for name in self.logger_states: if logger_states[name] is not None: self.saved_loggers[name].disabled = logger_states[name] - finally: - logging._releaseLock() self.doCleanups() threading_helper.threading_cleanup(*self._threading_key) @@ -680,6 +681,7 @@ def test_path_objects(self): support.is_emscripten, "Emscripten cannot fstat unlinked files." ) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_race(self): # Issue #14632 refers. def remove_loop(fname, tries): @@ -729,6 +731,7 @@ def remove_loop(fname, tries): # register_at_fork mechanism is also present and used. @support.requires_fork() @threading_helper.requires_working_threading() + @skip_if_asan_fork def test_post_fork_child_no_deadlock(self): """Ensure child logging locks are not held; bpo-6721 & bpo-36533.""" class _OurHandler(logging.Handler): @@ -738,11 +741,8 @@ def __init__(self): stream=open('/dev/null', 'wt', encoding='utf-8')) def emit(self, record): - self.sub_handler.acquire() - try: + with self.sub_handler.lock: self.sub_handler.emit(record) - finally: - self.sub_handler.release() self.assertEqual(len(logging._handlers), 0) refed_h = _OurHandler() @@ -758,29 +758,22 @@ def emit(self, record): fork_happened__release_locks_and_end_thread = threading.Event() def lock_holder_thread_fn(): - logging._acquireLock() - try: - refed_h.acquire() - try: - # Tell the main thread to do the fork. - locks_held__ready_to_fork.set() - - # If the deadlock bug exists, the fork will happen - # without dealing with the locks we hold, deadlocking - # the child. - - # Wait for a successful fork or an unreasonable amount of - # time before releasing our locks. To avoid a timing based - # test we'd need communication from os.fork() as to when it - # has actually happened. Given this is a regression test - # for a fixed issue, potentially less reliably detecting - # regression via timing is acceptable for simplicity. - # The test will always take at least this long. :( - fork_happened__release_locks_and_end_thread.wait(0.5) - finally: - refed_h.release() - finally: - logging._releaseLock() + with logging._lock, refed_h.lock: + # Tell the main thread to do the fork. + locks_held__ready_to_fork.set() + + # If the deadlock bug exists, the fork will happen + # without dealing with the locks we hold, deadlocking + # the child. + + # Wait for a successful fork or an unreasonable amount of + # time before releasing our locks. To avoid a timing based + # test we'd need communication from os.fork() as to when it + # has actually happened. Given this is a regression test + # for a fixed issue, potentially less reliably detecting + # regression via timing is acceptable for simplicity. + # The test will always take at least this long. :( + fork_happened__release_locks_and_end_thread.wait(0.5) lock_holder_thread = threading.Thread( target=lock_holder_thread_fn, @@ -2079,17 +2072,17 @@ def test_output(self): # The log message sent to the SysLogHandler is properly received. logger = logging.getLogger("slh") logger.error("sp\xe4m") - self.handled.wait() + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00') self.handled.clear() self.sl_hdlr.append_nul = False logger.error("sp\xe4m") - self.handled.wait() + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m') self.handled.clear() self.sl_hdlr.ident = "h\xe4m-" logger.error("sp\xe4m") - self.handled.wait() + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>h\xc3\xa4m-sp\xc3\xa4m') def test_udp_reconnection(self): @@ -2097,7 +2090,7 @@ def test_udp_reconnection(self): self.sl_hdlr.close() self.handled.clear() logger.error("sp\xe4m") - self.handled.wait(0.1) + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00') @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") @@ -2169,7 +2162,7 @@ def test_output(self): sslctx = None else: here = os.path.dirname(__file__) - localhost_cert = os.path.join(here, "keycert.pem") + localhost_cert = os.path.join(here, "certdata", "keycert.pem") sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) sslctx.load_cert_chain(localhost_cert) @@ -3662,7 +3655,28 @@ def test_baseconfig(self): d = { 'atuple': (1, 2, 3), 'alist': ['a', 'b', 'c'], - 'adict': {'d': 'e', 'f': 3 }, + 'adict': { + 'd': 'e', 'f': 3 , + 'alpha numeric 1 with spaces' : 5, + 'aplha numeric 1 %( - © ©ß¯' : 9, + 'alpha numeric ] 1 with spaces' : 15, + 'aplha ]] numeric 1 %( - © ©ß¯]' : 19, + ' aplha [ numeric 1 %( - © ©ß¯] ' : 11, + ' aplha ' : 32, + '' : 10, + 'nest4' : { + 'd': 'e', 'f': 3 , + 'alpha numeric 1 with spaces' : 5, + 'aplha numeric 1 %( - © ©ß¯' : 9, + '' : 10, + 'somelist' : ('g', ('h', 'i'), 'j'), + 'somedict' : { + 'a' : 1, + 'a with 1 and space' : 3, + 'a with ( and space' : 4, + } + } + }, 'nest1': ('g', ('h', 'i'), 'j'), 'nest2': ['k', ['l', 'm'], 'n'], 'nest3': ['o', 'cfg://alist', 'p'], @@ -3674,11 +3688,36 @@ def test_baseconfig(self): self.assertEqual(bc.convert('cfg://nest2[1][1]'), 'm') self.assertEqual(bc.convert('cfg://adict.d'), 'e') self.assertEqual(bc.convert('cfg://adict[f]'), 3) + self.assertEqual(bc.convert('cfg://adict[alpha numeric 1 with spaces]'), 5) + self.assertEqual(bc.convert('cfg://adict[aplha numeric 1 %( - © ©ß¯]'), 9) + self.assertEqual(bc.convert('cfg://adict[]'), 10) + self.assertEqual(bc.convert('cfg://adict.nest4.d'), 'e') + self.assertEqual(bc.convert('cfg://adict.nest4[d]'), 'e') + self.assertEqual(bc.convert('cfg://adict[nest4].d'), 'e') + self.assertEqual(bc.convert('cfg://adict[nest4][f]'), 3) + self.assertEqual(bc.convert('cfg://adict[nest4][alpha numeric 1 with spaces]'), 5) + self.assertEqual(bc.convert('cfg://adict[nest4][aplha numeric 1 %( - © ©ß¯]'), 9) + self.assertEqual(bc.convert('cfg://adict[nest4][]'), 10) + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][0]'), 'g') + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][1][0]'), 'h') + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][1][1]'), 'i') + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][2]'), 'j') + self.assertEqual(bc.convert('cfg://adict[nest4].somedict.a'), 1) + self.assertEqual(bc.convert('cfg://adict[nest4].somedict[a]'), 1) + self.assertEqual(bc.convert('cfg://adict[nest4].somedict[a with 1 and space]'), 3) + self.assertEqual(bc.convert('cfg://adict[nest4].somedict[a with ( and space]'), 4) + self.assertEqual(bc.convert('cfg://adict.nest4.somelist[1][1]'), 'i') + self.assertEqual(bc.convert('cfg://adict.nest4.somelist[2]'), 'j') + self.assertEqual(bc.convert('cfg://adict.nest4.somedict.a'), 1) + self.assertEqual(bc.convert('cfg://adict.nest4.somedict[a]'), 1) v = bc.convert('cfg://nest3') self.assertEqual(v.pop(1), ['a', 'b', 'c']) self.assertRaises(KeyError, bc.convert, 'cfg://nosuch') self.assertRaises(ValueError, bc.convert, 'cfg://!') self.assertRaises(KeyError, bc.convert, 'cfg://adict[2]') + self.assertRaises(KeyError, bc.convert, 'cfg://adict[alpha numeric ] 1 with spaces]') + self.assertRaises(ValueError, bc.convert, 'cfg://adict[ aplha ]] numeric 1 %( - © ©ß¯] ]') + self.assertRaises(ValueError, bc.convert, 'cfg://adict[ aplha [ numeric 1 %( - © ©ß¯] ]') def test_namedtuple(self): # see bpo-39142 @@ -5433,6 +5472,46 @@ def process(self, msg, kwargs): self.assertIs(adapter.manager, orig_manager) self.assertIs(self.logger.manager, orig_manager) + def test_extra_in_records(self): + self.adapter = logging.LoggerAdapter(logger=self.logger, + extra={'foo': '1'}) + + self.adapter.critical('foo should be here') + self.assertEqual(len(self.recording.records), 1) + record = self.recording.records[0] + self.assertTrue(hasattr(record, 'foo')) + self.assertEqual(record.foo, '1') + + def test_extra_not_merged_by_default(self): + self.adapter.critical('foo should NOT be here', extra={'foo': 'nope'}) + self.assertEqual(len(self.recording.records), 1) + record = self.recording.records[0] + self.assertFalse(hasattr(record, 'foo')) + + def test_extra_merged(self): + self.adapter = logging.LoggerAdapter(logger=self.logger, + extra={'foo': '1'}, + merge_extra=True) + + self.adapter.critical('foo and bar should be here', extra={'bar': '2'}) + self.assertEqual(len(self.recording.records), 1) + record = self.recording.records[0] + self.assertTrue(hasattr(record, 'foo')) + self.assertTrue(hasattr(record, 'bar')) + self.assertEqual(record.foo, '1') + self.assertEqual(record.bar, '2') + + def test_extra_merged_log_call_has_precedence(self): + self.adapter = logging.LoggerAdapter(logger=self.logger, + extra={'foo': '1'}, + merge_extra=True) + + self.adapter.critical('foo shall be min', extra={'foo': '2'}) + self.assertEqual(len(self.recording.records), 1) + record = self.recording.records[0] + self.assertTrue(hasattr(record, 'foo')) + self.assertEqual(record.foo, '2') + class LoggerTest(BaseTest, AssertErrorMessage): diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py index ac53bdda2f1747..13b200912f6abd 100644 --- a/Lib/test/test_lzma.py +++ b/Lib/test/test_lzma.py @@ -352,10 +352,10 @@ def test_compressor_bigmem(self, size): @bigmemtest(size=_4G + 100, memuse=3) def test_decompressor_bigmem(self, size): lzd = LZMADecompressor() - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - input = block * (size // blocksize + 1) + input = block * ((size-1) // blocksize + 1) cdata = lzma.compress(input) ddata = lzd.decompress(cdata) self.assertEqual(ddata, input) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 2bda61012164d1..d5d2197c36b254 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -33,8 +33,8 @@ else: file = __file__ test_dir = os.path.dirname(file) or os.curdir -math_testcases = os.path.join(test_dir, 'math_testcases.txt') -test_file = os.path.join(test_dir, 'cmath_testcases.txt') +math_testcases = os.path.join(test_dir, 'mathdata', 'math_testcases.txt') +test_file = os.path.join(test_dir, 'mathdata', 'cmath_testcases.txt') def to_ulps(x): @@ -235,6 +235,10 @@ def __init__(self, value): def __index__(self): return self.value +class BadDescr: + def __get__(self, obj, objtype=None): + raise ValueError + class MathTests(unittest.TestCase): def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0): @@ -324,6 +328,7 @@ def testAtan2(self): self.ftest('atan2(0, 1)', math.atan2(0, 1), 0) self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4) self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2) + self.ftest('atan2(1, -1)', math.atan2(1, -1), 3*math.pi/4) # math.atan2(0, x) self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi) @@ -417,16 +422,22 @@ def __ceil__(self): return 42 class TestNoCeil: pass + class TestBadCeil: + __ceil__ = BadDescr() self.assertEqual(math.ceil(TestCeil()), 42) self.assertEqual(math.ceil(FloatCeil()), 42) self.assertEqual(math.ceil(FloatLike(42.5)), 43) self.assertRaises(TypeError, math.ceil, TestNoCeil()) + self.assertRaises(ValueError, math.ceil, TestBadCeil()) t = TestNoCeil() t.__ceil__ = lambda *args: args self.assertRaises(TypeError, math.ceil, t) self.assertRaises(TypeError, math.ceil, t, 0) + self.assertEqual(math.ceil(FloatLike(+1.0)), +1.0) + self.assertEqual(math.ceil(FloatLike(-1.0)), -1.0) + @requires_IEEE_754 def testCopysign(self): self.assertEqual(math.copysign(1, 42), 1.0) @@ -567,16 +578,22 @@ def __floor__(self): return 42 class TestNoFloor: pass + class TestBadFloor: + __floor__ = BadDescr() self.assertEqual(math.floor(TestFloor()), 42) self.assertEqual(math.floor(FloatFloor()), 42) self.assertEqual(math.floor(FloatLike(41.9)), 41) self.assertRaises(TypeError, math.floor, TestNoFloor()) + self.assertRaises(ValueError, math.floor, TestBadFloor()) t = TestNoFloor() t.__floor__ = lambda *args: args self.assertRaises(TypeError, math.floor, t) self.assertRaises(TypeError, math.floor, t, 0) + self.assertEqual(math.floor(FloatLike(+1.0)), +1.0) + self.assertEqual(math.floor(FloatLike(-1.0)), -1.0) + def testFmod(self): self.assertRaises(TypeError, math.fmod) self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0) @@ -598,6 +615,7 @@ def testFmod(self): self.assertEqual(math.fmod(-3.0, NINF), -3.0) self.assertEqual(math.fmod(0.0, 3.0), 0.0) self.assertEqual(math.fmod(0.0, NINF), 0.0) + self.assertRaises(ValueError, math.fmod, INF, INF) def testFrexp(self): self.assertRaises(TypeError, math.frexp) @@ -714,6 +732,11 @@ def msum(iterable): s = msum(vals) self.assertEqual(msum(vals), math.fsum(vals)) + self.assertEqual(math.fsum([1.0, math.inf]), math.inf) + self.assertRaises(OverflowError, math.fsum, [1e+308, 1e+308]) + self.assertRaises(ValueError, math.fsum, [math.inf, -math.inf]) + self.assertRaises(TypeError, math.fsum, ['spam']) + def testGcd(self): gcd = math.gcd self.assertEqual(gcd(0, 0), 0) @@ -831,6 +854,8 @@ def testHypot(self): scale = FLOAT_MIN / 2.0 ** exp self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale) + self.assertRaises(TypeError, math.hypot, *([1.0]*18), 'spam') + @requires_IEEE_754 @unittest.skipIf(HAVE_DOUBLE_ROUNDING, "hypot() loses accuracy on machines with double rounding") @@ -966,6 +991,8 @@ class T(tuple): dist((1, 2, 3, 4), (5, 6, 7)) with self.assertRaises(ValueError): # Check dimension agree dist((1, 2, 3), (4, 5, 6, 7)) + with self.assertRaises(TypeError): + dist((1,)*17 + ("spam",), (1,)*18) with self.assertRaises(TypeError): # Rejects invalid types dist("abc", "xyz") int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5) @@ -973,6 +1000,10 @@ class T(tuple): dist((1, int_too_big_for_float), (2, 3)) with self.assertRaises((ValueError, OverflowError)): dist((2, 3), (1, int_too_big_for_float)) + with self.assertRaises(TypeError): + dist((1,), 2) + with self.assertRaises(TypeError): + dist([1], 2) # Verify that the one dimensional case is equivalent to abs() for i in range(20): @@ -1111,6 +1142,7 @@ def test_lcm(self): def testLdexp(self): self.assertRaises(TypeError, math.ldexp) + self.assertRaises(TypeError, math.ldexp, 2.0, 1.1) self.ftest('ldexp(0,1)', math.ldexp(0,1), 0) self.ftest('ldexp(1,1)', math.ldexp(1,1), 2) self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5) @@ -1153,6 +1185,7 @@ def testLog(self): 2302.5850929940457) self.assertRaises(ValueError, math.log, -1.5) self.assertRaises(ValueError, math.log, -10**1000) + self.assertRaises(ValueError, math.log, 10, -10) self.assertRaises(ValueError, math.log, NINF) self.assertEqual(math.log(INF), INF) self.assertTrue(math.isnan(math.log(NAN))) @@ -2378,6 +2411,14 @@ def __float__(self): # argument to a float. self.assertFalse(getattr(y, "converted", False)) + def test_input_exceptions(self): + self.assertRaises(TypeError, math.exp, "spam") + self.assertRaises(TypeError, math.erf, "spam") + self.assertRaises(TypeError, math.atan2, "spam", 1.0) + self.assertRaises(TypeError, math.atan2, 1.0, "spam") + self.assertRaises(TypeError, math.atan2, 1.0) + self.assertRaises(TypeError, math.atan2, 1.0, 2.0, 3.0) + # Custom assertions. def assertIsNaN(self, value): @@ -2518,7 +2559,7 @@ def test_fractions(self): def load_tests(loader, tests, pattern): from doctest import DocFileSuite - tests.addTest(DocFileSuite("ieee754.txt")) + tests.addTest(DocFileSuite(os.path.join("mathdata", "ieee754.txt"))) return tests if __name__ == '__main__': diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 699265ccadc7f9..3ecd1af31eea77 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -505,6 +505,46 @@ def testWriteXML(self): dom.unlink() self.confirm(str == domstr) + def test_toxml_quote_text(self): + dom = Document() + elem = dom.appendChild(dom.createElement('elem')) + elem.appendChild(dom.createTextNode('&<>"')) + cr = elem.appendChild(dom.createElement('cr')) + cr.appendChild(dom.createTextNode('\r')) + crlf = elem.appendChild(dom.createElement('crlf')) + crlf.appendChild(dom.createTextNode('\r\n')) + lflf = elem.appendChild(dom.createElement('lflf')) + lflf.appendChild(dom.createTextNode('\n\n')) + ws = elem.appendChild(dom.createElement('ws')) + ws.appendChild(dom.createTextNode('\t\n\r ')) + domstr = dom.toxml() + dom.unlink() + self.assertEqual(domstr, '' + '&<>"' + '\r' + '\r\n' + '\n\n' + '\t\n\r ') + + def test_toxml_quote_attrib(self): + dom = Document() + elem = dom.appendChild(dom.createElement('elem')) + elem.setAttribute("a", '&<>"') + elem.setAttribute("cr", "\r") + elem.setAttribute("lf", "\n") + elem.setAttribute("crlf", "\r\n") + elem.setAttribute("lflf", "\n\n") + elem.setAttribute("ws", "\t\n\r ") + domstr = dom.toxml() + dom.unlink() + self.assertEqual(domstr, '' + '') + def testAltNewline(self): str = '\n\n' dom = parseString(str) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index bab868600895c1..dfcf3039422af5 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -255,10 +255,15 @@ def test_access_parameter(self): # Try writing with PROT_EXEC and without PROT_WRITE prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0) with open(TESTFN, "r+b") as f: - m = mmap.mmap(f.fileno(), mapsize, prot=prot) - self.assertRaises(TypeError, m.write, b"abcdef") - self.assertRaises(TypeError, m.write_byte, 0) - m.close() + try: + m = mmap.mmap(f.fileno(), mapsize, prot=prot) + except PermissionError: + # on macOS 14, PROT_READ | PROT_EXEC is not allowed + pass + else: + self.assertRaises(TypeError, m.write, b"abcdef") + self.assertRaises(TypeError, m.write_byte, 0) + m.close() def test_bad_file_desc(self): # Try opening a bad file descriptor... diff --git a/Lib/test/test_module.py b/Lib/test/test_module/__init__.py similarity index 91% rename from Lib/test/test_module.py rename to Lib/test/test_module/__init__.py index c7eb92290e1b6d..2524e6c87cb459 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module/__init__.py @@ -126,8 +126,8 @@ def test_weakref(self): self.assertIs(wr(), None) def test_module_getattr(self): - import test.good_getattr as gga - from test.good_getattr import test + import test.test_module.good_getattr as gga + from test.test_module.good_getattr import test self.assertEqual(test, "There is test") self.assertEqual(gga.x, 1) self.assertEqual(gga.y, 2) @@ -135,46 +135,46 @@ def test_module_getattr(self): "Deprecated, use whatever instead"): gga.yolo self.assertEqual(gga.whatever, "There is whatever") - del sys.modules['test.good_getattr'] + del sys.modules['test.test_module.good_getattr'] def test_module_getattr_errors(self): - import test.bad_getattr as bga - from test import bad_getattr2 + import test.test_module.bad_getattr as bga + from test.test_module import bad_getattr2 self.assertEqual(bga.x, 1) self.assertEqual(bad_getattr2.x, 1) with self.assertRaises(TypeError): bga.nope with self.assertRaises(TypeError): bad_getattr2.nope - del sys.modules['test.bad_getattr'] - if 'test.bad_getattr2' in sys.modules: - del sys.modules['test.bad_getattr2'] + del sys.modules['test.test_module.bad_getattr'] + if 'test.test_module.bad_getattr2' in sys.modules: + del sys.modules['test.test_module.bad_getattr2'] def test_module_dir(self): - import test.good_getattr as gga + import test.test_module.good_getattr as gga self.assertEqual(dir(gga), ['a', 'b', 'c']) - del sys.modules['test.good_getattr'] + del sys.modules['test.test_module.good_getattr'] def test_module_dir_errors(self): - import test.bad_getattr as bga - from test import bad_getattr2 + import test.test_module.bad_getattr as bga + from test.test_module import bad_getattr2 with self.assertRaises(TypeError): dir(bga) with self.assertRaises(TypeError): dir(bad_getattr2) - del sys.modules['test.bad_getattr'] - if 'test.bad_getattr2' in sys.modules: - del sys.modules['test.bad_getattr2'] + del sys.modules['test.test_module.bad_getattr'] + if 'test.test_module.bad_getattr2' in sys.modules: + del sys.modules['test.test_module.bad_getattr2'] def test_module_getattr_tricky(self): - from test import bad_getattr3 + from test.test_module import bad_getattr3 # these lookups should not crash with self.assertRaises(AttributeError): bad_getattr3.one with self.assertRaises(AttributeError): bad_getattr3.delgetattr - if 'test.bad_getattr3' in sys.modules: - del sys.modules['test.bad_getattr3'] + if 'test.test_module.bad_getattr3' in sys.modules: + del sys.modules['test.test_module.bad_getattr3'] def test_module_repr_minimal(self): # reprs when modules have no __file__, __name__, or __loader__ @@ -324,7 +324,9 @@ def test_annotations_getset_raises(self): del foo.__annotations__ def test_annotations_are_created_correctly(self): - ann_module4 = import_helper.import_fresh_module('test.ann_module4') + ann_module4 = import_helper.import_fresh_module( + 'test.typinganndata.ann_module4', + ) self.assertTrue("__annotations__" in ann_module4.__dict__) del ann_module4.__annotations__ self.assertFalse("__annotations__" in ann_module4.__dict__) diff --git a/Lib/test/bad_getattr.py b/Lib/test/test_module/bad_getattr.py similarity index 100% rename from Lib/test/bad_getattr.py rename to Lib/test/test_module/bad_getattr.py diff --git a/Lib/test/bad_getattr2.py b/Lib/test/test_module/bad_getattr2.py similarity index 100% rename from Lib/test/bad_getattr2.py rename to Lib/test/test_module/bad_getattr2.py diff --git a/Lib/test/bad_getattr3.py b/Lib/test/test_module/bad_getattr3.py similarity index 100% rename from Lib/test/bad_getattr3.py rename to Lib/test/test_module/bad_getattr3.py diff --git a/Lib/test/good_getattr.py b/Lib/test/test_module/good_getattr.py similarity index 100% rename from Lib/test/good_getattr.py rename to Lib/test/test_module/good_getattr.py diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index f854c582846660..3b8ecb765c23f0 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -8,7 +8,7 @@ import textwrap import types import unittest - +import asyncio PAIR = (0,1) @@ -136,20 +136,27 @@ def test_c_return_count(self): E = sys.monitoring.events -SIMPLE_EVENTS = [ +INSTRUMENTED_EVENTS = [ (E.PY_START, "start"), (E.PY_RESUME, "resume"), (E.PY_RETURN, "return"), (E.PY_YIELD, "yield"), (E.JUMP, "jump"), (E.BRANCH, "branch"), +] + +EXCEPT_EVENTS = [ (E.RAISE, "raise"), (E.PY_UNWIND, "unwind"), (E.EXCEPTION_HANDLED, "exception_handled"), +] + +SIMPLE_EVENTS = INSTRUMENTED_EVENTS + EXCEPT_EVENTS + [ (E.C_RAISE, "c_raise"), (E.C_RETURN, "c_return"), ] + SIMPLE_EVENT_SET = functools.reduce(operator.or_, [ev for (ev, _) in SIMPLE_EVENTS], 0) | E.CALL @@ -243,7 +250,6 @@ def check_events(self, func, expected=None): expected = func.events self.assertEqual(events, expected) - class MonitoringEventsTest(MonitoringEventsBase, unittest.TestCase): def test_just_pass(self): @@ -495,6 +501,22 @@ def test_two_with_disable(self): self.assertEqual(sys.monitoring._all_events(), {}) sys.monitoring.restart_events() + def test_with_instruction_event(self): + """Test that the second tool can set events with instruction events set by the first tool.""" + def f(): + pass + code = f.__code__ + + try: + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.set_local_events(TEST_TOOL, code, E.INSTRUCTION | E.LINE) + sys.monitoring.set_local_events(TEST_TOOL2, code, E.LINE) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + self.assertEqual(sys.monitoring._all_events(), {}) + + class LineMonitoringTest(MonitoringTestBase, unittest.TestCase): def test_lines_single(self): @@ -619,6 +641,49 @@ def func2(): self.check_lines(func2, [1,2,3,4,5,6]) +class TestDisable(MonitoringTestBase, unittest.TestCase): + + def gen(self, cond): + for i in range(10): + if cond: + yield 1 + else: + yield 2 + + def raise_handle_reraise(self): + try: + 1/0 + except: + raise + + def test_disable_legal_events(self): + for event, name in INSTRUMENTED_EVENTS: + try: + counter = CounterWithDisable() + counter.disable = True + sys.monitoring.register_callback(TEST_TOOL, event, counter) + sys.monitoring.set_events(TEST_TOOL, event) + for _ in self.gen(1): + pass + self.assertLess(counter.count, 4) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, event, None) + + + def test_disable_illegal_events(self): + for event, name in EXCEPT_EVENTS: + try: + counter = CounterWithDisable() + counter.disable = True + sys.monitoring.register_callback(TEST_TOOL, event, counter) + sys.monitoring.set_events(TEST_TOOL, event) + with self.assertRaises(ValueError): + self.raise_handle_reraise() + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, event, None) + class ExceptionRecorder: @@ -632,7 +697,7 @@ def __call__(self, code, offset, exc): class CheckEvents(MonitoringTestBase, unittest.TestCase): - def check_events(self, func, expected, tool=TEST_TOOL, recorders=(ExceptionRecorder,)): + def get_events(self, func, tool, recorders): try: self.assertEqual(sys.monitoring._all_events(), {}) event_list = [] @@ -646,19 +711,70 @@ def check_events(self, func, expected, tool=TEST_TOOL, recorders=(ExceptionRecor sys.monitoring.set_events(tool, 0) for recorder in recorders: sys.monitoring.register_callback(tool, recorder.event_type, None) - self.assertEqual(event_list, expected) + return event_list finally: sys.monitoring.set_events(tool, 0) for recorder in recorders: sys.monitoring.register_callback(tool, recorder.event_type, None) + def check_events(self, func, expected, tool=TEST_TOOL, recorders=(ExceptionRecorder,)): + events = self.get_events(func, tool, recorders) + if events != expected: + print(events, file = sys.stderr) + self.assertEqual(events, expected) + + def check_balanced(self, func, recorders): + events = self.get_events(func, TEST_TOOL, recorders) + self.assertEqual(len(events)%2, 0) + for r, h in zip(events[::2],events[1::2]): + r0 = r[0] + self.assertIn(r0, ("raise", "reraise")) + h0 = h[0] + self.assertIn(h0, ("handled", "unwind")) + self.assertEqual(r[1], h[1]) + + class StopiterationRecorder(ExceptionRecorder): event_type = E.STOP_ITERATION -class ExceptionMontoringTest(CheckEvents): +class ReraiseRecorder(ExceptionRecorder): + + event_type = E.RERAISE + + def __call__(self, code, offset, exc): + self.events.append(("reraise", type(exc))) + +class UnwindRecorder(ExceptionRecorder): + + event_type = E.PY_UNWIND + + def __call__(self, code, offset, exc): + self.events.append(("unwind", type(exc))) + +class ExceptionHandledRecorder(ExceptionRecorder): + + event_type = E.EXCEPTION_HANDLED + + def __call__(self, code, offset, exc): + self.events.append(("handled", type(exc))) + +class ThrowRecorder(ExceptionRecorder): + + event_type = E.PY_THROW + + def __call__(self, code, offset, exc): + self.events.append(("throw", type(exc))) + +class ExceptionMonitoringTest(CheckEvents): - recorder = ExceptionRecorder + + exception_recorders = ( + ExceptionRecorder, + ReraiseRecorder, + ExceptionHandledRecorder, + UnwindRecorder + ) def test_simple_try_except(self): @@ -672,6 +788,8 @@ def func1(): self.check_events(func1, [("raise", KeyError)]) + def test_implicit_stop_iteration(self): + def gen(): yield 1 return 2 @@ -682,6 +800,142 @@ def implicit_stop_iteration(): self.check_events(implicit_stop_iteration, [("raise", StopIteration)], recorders=(StopiterationRecorder,)) + initial = [ + ("raise", ZeroDivisionError), + ("handled", ZeroDivisionError) + ] + + reraise = [ + ("reraise", ZeroDivisionError), + ("handled", ZeroDivisionError) + ] + + def test_explicit_reraise(self): + + def func(): + try: + try: + 1/0 + except: + raise + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_explicit_reraise_named(self): + + def func(): + try: + try: + 1/0 + except Exception as ex: + raise + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_implicit_reraise(self): + + def func(): + try: + try: + 1/0 + except ValueError: + pass + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + + def test_implicit_reraise_named(self): + + def func(): + try: + try: + 1/0 + except ValueError as ex: + pass + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_try_finally(self): + + def func(): + try: + try: + 1/0 + finally: + pass + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_async_for(self): + + def func(): + + async def async_generator(): + for i in range(1): + raise ZeroDivisionError + yield i + + async def async_loop(): + try: + async for item in async_generator(): + pass + except Exception: + pass + + try: + async_loop().send(None) + except StopIteration: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_throw(self): + + def gen(): + yield 1 + yield 2 + + def func(): + try: + g = gen() + next(g) + g.throw(IndexError) + except IndexError: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + events = self.get_events( + func, + TEST_TOOL, + self.exception_recorders + (ThrowRecorder,) + ) + self.assertEqual(events[0], ("throw", IndexError)) + class LineRecorder: event_type = E.LINE @@ -733,12 +987,12 @@ def func1(): line3 = 3 self.check_events(func1, recorders = MANY_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('call', 'func1', sys.monitoring.MISSING), ('line', 'func1', 1), ('line', 'func1', 2), ('line', 'func1', 3), - ('line', 'check_events', 11), + ('line', 'get_events', 11), ('call', 'set_events', 2)]) def test_c_call(self): @@ -749,14 +1003,14 @@ def func2(): line3 = 3 self.check_events(func2, recorders = MANY_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('call', 'func2', sys.monitoring.MISSING), ('line', 'func2', 1), ('line', 'func2', 2), ('call', 'append', [2]), ('C return', 'append', [2]), ('line', 'func2', 3), - ('line', 'check_events', 11), + ('line', 'get_events', 11), ('call', 'set_events', 2)]) def test_try_except(self): @@ -770,7 +1024,7 @@ def func3(): line = 6 self.check_events(func3, recorders = MANY_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('call', 'func3', sys.monitoring.MISSING), ('line', 'func3', 1), ('line', 'func3', 2), @@ -779,7 +1033,7 @@ def func3(): ('line', 'func3', 4), ('line', 'func3', 5), ('line', 'func3', 6), - ('line', 'check_events', 11), + ('line', 'get_events', 11), ('call', 'set_events', 2)]) class InstructionRecorder: @@ -791,7 +1045,7 @@ def __init__(self, events): def __call__(self, code, offset): # Filter out instructions in check_events to lower noise - if code.co_name != "check_events": + if code.co_name != "get_events": self.events.append(("instruction", code.co_name, offset)) @@ -808,7 +1062,7 @@ def func1(): line3 = 3 self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func1', 1), ('instruction', 'func1', 2), ('instruction', 'func1', 4), @@ -819,7 +1073,7 @@ def func1(): ('instruction', 'func1', 10), ('instruction', 'func1', 12), ('instruction', 'func1', 14), - ('line', 'check_events', 11)]) + ('line', 'get_events', 11)]) def test_c_call(self): @@ -829,7 +1083,7 @@ def func2(): line3 = 3 self.check_events(func2, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func2', 1), ('instruction', 'func2', 2), ('instruction', 'func2', 4), @@ -843,7 +1097,7 @@ def func2(): ('instruction', 'func2', 40), ('instruction', 'func2', 42), ('instruction', 'func2', 44), - ('line', 'check_events', 11)]) + ('line', 'get_events', 11)]) def test_try_except(self): @@ -856,7 +1110,7 @@ def func3(): line = 6 self.check_events(func3, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func3', 1), ('instruction', 'func3', 2), ('line', 'func3', 2), @@ -876,7 +1130,7 @@ def func3(): ('instruction', 'func3', 30), ('instruction', 'func3', 32), ('instruction', 'func3', 34), - ('line', 'check_events', 11)]) + ('line', 'get_events', 11)]) def test_with_restart(self): def func1(): @@ -885,7 +1139,7 @@ def func1(): line3 = 3 self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func1', 1), ('instruction', 'func1', 2), ('instruction', 'func1', 4), @@ -896,12 +1150,12 @@ def func1(): ('instruction', 'func1', 10), ('instruction', 'func1', 12), ('instruction', 'func1', 14), - ('line', 'check_events', 11)]) + ('line', 'get_events', 11)]) sys.monitoring.restart_events() self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func1', 1), ('instruction', 'func1', 2), ('instruction', 'func1', 4), @@ -912,9 +1166,26 @@ def func1(): ('instruction', 'func1', 10), ('instruction', 'func1', 12), ('instruction', 'func1', 14), - ('line', 'check_events', 11)]) + ('line', 'get_events', 11)]) + + def test_turn_off_only_instruction(self): + """ + LINE events should be recorded after INSTRUCTION event is turned off + """ + events = [] + def line(*args): + events.append("line") + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, line) + sys.monitoring.register_callback(TEST_TOOL, E.INSTRUCTION, lambda *args: None) + sys.monitoring.set_events(TEST_TOOL, E.LINE | E.INSTRUCTION) + sys.monitoring.set_events(TEST_TOOL, E.LINE) + events = [] + a = 0 + sys.monitoring.set_events(TEST_TOOL, 0) + self.assertGreater(len(events), 0) -class TestInstallIncrementallly(MonitoringTestBase, unittest.TestCase): +class TestInstallIncrementally(MonitoringTestBase, unittest.TestCase): def check_events(self, func, must_include, tool=TEST_TOOL, recorders=(ExceptionRecorder,)): try: @@ -943,19 +1214,19 @@ def func1(): MUST_INCLUDE_LI = [ ('instruction', 'func1', 2), - ('line', 'func1', 1), + ('line', 'func1', 2), ('instruction', 'func1', 4), ('instruction', 'func1', 6)] def test_line_then_instruction(self): recorders = [ LineRecorder, InstructionRecorder ] self.check_events(self.func1, - recorders = recorders, must_include = self.EXPECTED_LI) + recorders = recorders, must_include = self.MUST_INCLUDE_LI) def test_instruction_then_line(self): - recorders = [ InstructionRecorder, LineRecorderLowNoise ] + recorders = [ InstructionRecorder, LineRecorder ] self.check_events(self.func1, - recorders = recorders, must_include = self.EXPECTED_LI) + recorders = recorders, must_include = self.MUST_INCLUDE_LI) @staticmethod def func2(): @@ -970,19 +1241,21 @@ def func2(): - def test_line_then_instruction(self): + def test_call_then_instruction(self): recorders = [ CallRecorder, InstructionRecorder ] self.check_events(self.func2, recorders = recorders, must_include = self.MUST_INCLUDE_CI) - def test_instruction_then_line(self): + def test_instruction_then_call(self): recorders = [ InstructionRecorder, CallRecorder ] self.check_events(self.func2, recorders = recorders, must_include = self.MUST_INCLUDE_CI) +LOCAL_RECORDERS = CallRecorder, LineRecorder, CReturnRecorder, CRaiseRecorder + class TestLocalEvents(MonitoringTestBase, unittest.TestCase): - def check_events(self, func, expected, tool=TEST_TOOL, recorders=(ExceptionRecorder,)): + def check_events(self, func, expected, tool=TEST_TOOL, recorders=()): try: self.assertEqual(sys.monitoring._all_events(), {}) event_list = [] @@ -1010,7 +1283,7 @@ def func1(): line2 = 2 line3 = 3 - self.check_events(func1, recorders = MANY_RECORDERS, expected = [ + self.check_events(func1, recorders = LOCAL_RECORDERS, expected = [ ('line', 'func1', 1), ('line', 'func1', 2), ('line', 'func1', 3)]) @@ -1022,7 +1295,7 @@ def func2(): [].append(2) line3 = 3 - self.check_events(func2, recorders = MANY_RECORDERS, expected = [ + self.check_events(func2, recorders = LOCAL_RECORDERS, expected = [ ('line', 'func2', 1), ('line', 'func2', 2), ('call', 'append', [2]), @@ -1039,15 +1312,17 @@ def func3(): line = 5 line = 6 - self.check_events(func3, recorders = MANY_RECORDERS, expected = [ + self.check_events(func3, recorders = LOCAL_RECORDERS, expected = [ ('line', 'func3', 1), ('line', 'func3', 2), ('line', 'func3', 3), - ('raise', KeyError), ('line', 'func3', 4), ('line', 'func3', 5), ('line', 'func3', 6)]) + def test_set_non_local_event(self): + with self.assertRaises(ValueError): + sys.monitoring.set_local_events(TEST_TOOL, just_call.__code__, E.RAISE) def line_from_offset(code, offset): for start, end, line in code.co_lines(): @@ -1106,31 +1381,31 @@ def func(): self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [ ('branch', 'func', 2, 2), - ('branch', 'func', 3, 6), + ('branch', 'func', 3, 4), ('jump', 'func', 6, 2), ('branch', 'func', 2, 2), - ('branch', 'func', 3, 4), + ('branch', 'func', 3, 3), ('jump', 'func', 4, 2), ('branch', 'func', 2, 2)]) self.check_events(func, recorders = JUMP_BRANCH_AND_LINE_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func', 1), ('line', 'func', 2), ('branch', 'func', 2, 2), ('line', 'func', 3), - ('branch', 'func', 3, 6), + ('branch', 'func', 3, 4), ('line', 'func', 6), ('jump', 'func', 6, 2), ('line', 'func', 2), ('branch', 'func', 2, 2), ('line', 'func', 3), - ('branch', 'func', 3, 4), + ('branch', 'func', 3, 3), ('line', 'func', 4), ('jump', 'func', 4, 2), ('line', 'func', 2), ('branch', 'func', 2, 2), - ('line', 'check_events', 11)]) + ('line', 'get_events', 11)]) def test_except_star(self): @@ -1149,7 +1424,7 @@ def func(): self.check_events(func, recorders = JUMP_BRANCH_AND_LINE_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func', 1), ('line', 'func', 2), ('line', 'func', 3), @@ -1158,12 +1433,12 @@ def func(): ('line', 'func', 5), ('line', 'meth', 1), ('jump', 'func', 5, 5), - ('jump', 'func', 5, '[offset=112]'), - ('branch', 'func', '[offset=118]', '[offset=120]'), - ('line', 'check_events', 11)]) + ('jump', 'func', 5, '[offset=114]'), + ('branch', 'func', '[offset=120]', '[offset=122]'), + ('line', 'get_events', 11)]) self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('line', 'func', 1), ('line', 'func', 2), ('line', 'func', 3), @@ -1174,10 +1449,10 @@ def func(): ('line', 'meth', 1), ('return', None), ('jump', 'func', 5, 5), - ('jump', 'func', 5, '[offset=112]'), - ('branch', 'func', '[offset=118]', '[offset=120]'), + ('jump', 'func', 5, '[offset=114]'), + ('branch', 'func', '[offset=120]', '[offset=122]'), ('return', None), - ('line', 'check_events', 11)]) + ('line', 'get_events', 11)]) class TestLoadSuperAttr(CheckEvents): RECORDERS = CallRecorder, LineRecorder, CRaiseRecorder, CReturnRecorder @@ -1229,7 +1504,7 @@ def f(): """ d = self._exec_super(codestr, optimized) expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('call', 'f', sys.monitoring.MISSING), ('line', 'f', 1), ('call', 'method', d["b"]), @@ -1242,7 +1517,7 @@ def f(): ('call', 'method', 1), ('line', 'method', 1), ('line', 'method', 1), - ('line', 'check_events', 11), + ('line', 'get_events', 11), ('call', 'set_events', 2), ] return d["f"], expected @@ -1280,7 +1555,7 @@ def f(): """ d = self._exec_super(codestr, optimized) expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('call', 'f', sys.monitoring.MISSING), ('line', 'f', 1), ('line', 'f', 2), @@ -1293,7 +1568,7 @@ def f(): ('C raise', 'super', 1), ('line', 'f', 3), ('line', 'f', 4), - ('line', 'check_events', 11), + ('line', 'get_events', 11), ('call', 'set_events', 2), ] return d["f"], expected @@ -1321,7 +1596,7 @@ def f(): """ d = self._exec_super(codestr, optimized) expected = [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('call', 'f', sys.monitoring.MISSING), ('line', 'f', 1), ('call', 'method', d["b"]), @@ -1330,7 +1605,7 @@ def f(): ('C return', 'super', sys.monitoring.MISSING), ('line', 'method', 2), ('line', 'method', 1), - ('line', 'check_events', 11), + ('line', 'get_events', 11), ('call', 'set_events', 2) ] return d["f"], expected @@ -1355,7 +1630,7 @@ def f(): def get_expected(name, call_method, ns): repr_arg = 0 if name == "int" else sys.monitoring.MISSING return [ - ('line', 'check_events', 10), + ('line', 'get_events', 10), ('call', 'f', sys.monitoring.MISSING), ('line', 'f', 1), ('call', 'method', ns["c"]), @@ -1368,7 +1643,7 @@ def get_expected(name, call_method, ns): ('C return', '__repr__', repr_arg), ] if call_method else [] ), - ('line', 'check_events', 11), + ('line', 'get_events', 11), ('call', 'set_events', 2), ] @@ -1460,3 +1735,56 @@ def run(): self.assertEqual(caught, "inner") finally: sys.monitoring.set_events(TEST_TOOL, 0) + + def test_108390(self): + + class Foo: + def __init__(self, set_event): + if set_event: + sys.monitoring.set_events(TEST_TOOL, E.PY_RESUME) + + def make_foo_optimized_then_set_event(): + for i in range(100): + Foo(i == 99) + + try: + make_foo_optimized_then_set_event() + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + + def test_gh108976(self): + sys.monitoring.use_tool_id(0, "test") + self.addCleanup(sys.monitoring.free_tool_id, 0) + sys.monitoring.set_events(0, 0) + sys.monitoring.register_callback(0, E.LINE, lambda *args: sys.monitoring.set_events(0, 0)) + sys.monitoring.register_callback(0, E.INSTRUCTION, lambda *args: 0) + sys.monitoring.set_events(0, E.LINE | E.INSTRUCTION) + sys.monitoring.set_events(0, 0) + + +class TestOptimizer(MonitoringTestBase, unittest.TestCase): + + def setUp(self): + import _testinternalcapi + self.old_opt = _testinternalcapi.get_optimizer() + opt = _testinternalcapi.get_counter_optimizer() + _testinternalcapi.set_optimizer(opt) + super(TestOptimizer, self).setUp() + + def tearDown(self): + import _testinternalcapi + super(TestOptimizer, self).tearDown() + _testinternalcapi.set_optimizer(self.old_opt) + + def test_for_loop(self): + def test_func(x): + i = 0 + while i < x: + i += 1 + + code = test_func.__code__ + sys.monitoring.set_local_events(TEST_TOOL, code, E.PY_START) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), E.PY_START) + test_func(1000) + sys.monitoring.set_local_events(TEST_TOOL, code, 0) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), 0) diff --git a/Lib/test/test_msvcrt.py b/Lib/test/test_msvcrt.py new file mode 100644 index 00000000000000..600c4446fd5cd4 --- /dev/null +++ b/Lib/test/test_msvcrt.py @@ -0,0 +1,120 @@ +import os +import subprocess +import sys +import unittest +from textwrap import dedent + +from test.support import os_helper, requires_resource +from test.support.os_helper import TESTFN, TESTFN_ASCII + +if sys.platform != "win32": + raise unittest.SkipTest("windows related tests") + +import _winapi +import msvcrt + + +class TestFileOperations(unittest.TestCase): + def test_locking(self): + with open(TESTFN, "w") as f: + self.addCleanup(os_helper.unlink, TESTFN) + + msvcrt.locking(f.fileno(), msvcrt.LK_LOCK, 1) + self.assertRaises(OSError, msvcrt.locking, f.fileno(), msvcrt.LK_NBLCK, 1) + + def test_unlockfile(self): + with open(TESTFN, "w") as f: + self.addCleanup(os_helper.unlink, TESTFN) + + msvcrt.locking(f.fileno(), msvcrt.LK_LOCK, 1) + msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, 1) + msvcrt.locking(f.fileno(), msvcrt.LK_LOCK, 1) + + def test_setmode(self): + with open(TESTFN, "w") as f: + self.addCleanup(os_helper.unlink, TESTFN) + + msvcrt.setmode(f.fileno(), os.O_BINARY) + msvcrt.setmode(f.fileno(), os.O_TEXT) + + def test_open_osfhandle(self): + h = _winapi.CreateFile(TESTFN_ASCII, _winapi.GENERIC_WRITE, 0, 0, 1, 128, 0) + self.addCleanup(os_helper.unlink, TESTFN_ASCII) + + try: + fd = msvcrt.open_osfhandle(h, os.O_RDONLY) + h = None + os.close(fd) + finally: + if h: + _winapi.CloseHandle(h) + + def test_get_osfhandle(self): + with open(TESTFN, "w") as f: + self.addCleanup(os_helper.unlink, TESTFN) + + msvcrt.get_osfhandle(f.fileno()) + + +c = '\u5b57' # unicode CJK char (meaning 'character') for 'wide-char' tests +c_encoded = b'\x57\x5b' # utf-16-le (which windows internally used) encoded char for this CJK char + + +class TestConsoleIO(unittest.TestCase): + # CREATE_NEW_CONSOLE creates a "popup" window. + @requires_resource('gui') + def run_in_separated_process(self, code): + # Run test in a seprated process to avoid stdin conflicts. + # See: gh-110147 + cmd = [sys.executable, '-c', code] + subprocess.run(cmd, check=True, capture_output=True, + creationflags=subprocess.CREATE_NEW_CONSOLE) + + def test_kbhit(self): + code = dedent(''' + import msvcrt + assert msvcrt.kbhit() == 0 + ''') + self.run_in_separated_process(code) + + def test_getch(self): + msvcrt.ungetch(b'c') + self.assertEqual(msvcrt.getch(), b'c') + + def check_getwch(self, funcname): + code = dedent(f''' + import msvcrt + from _testconsole import write_input + with open("CONIN$", "rb", buffering=0) as stdin: + write_input(stdin, {ascii(c_encoded)}) + assert msvcrt.{funcname}() == "{c}" + ''') + self.run_in_separated_process(code) + + def test_getwch(self): + self.check_getwch('getwch') + + def test_getche(self): + msvcrt.ungetch(b'c') + self.assertEqual(msvcrt.getche(), b'c') + + def test_getwche(self): + self.check_getwch('getwche') + + def test_putch(self): + msvcrt.putch(b'c') + + def test_putwch(self): + msvcrt.putwch(c) + + +class TestOther(unittest.TestCase): + def test_heap_min(self): + try: + msvcrt.heapmin() + except OSError: + pass + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py index cf8bb5e3a0520d..6451df14696933 100644 --- a/Lib/test/test_multibytecodec.py +++ b/Lib/test/test_multibytecodec.py @@ -363,6 +363,7 @@ def test_iso2022_jp_g0(self): e = '\u3406'.encode(encoding) self.assertFalse(any(x > 0x80 for x in e)) + @support.requires_resource('cpu') def test_bug1572832(self): for x in range(0x10000, 0x110000): # Any ISO 2022 codec will cause the segfault diff --git a/Lib/test/test_multiprocessing_fork.py b/Lib/test/test_multiprocessing_fork/__init__.py similarity index 66% rename from Lib/test/test_multiprocessing_fork.py rename to Lib/test/test_multiprocessing_fork/__init__.py index 5000edb7c5c299..aa1fff50b28f5f 100644 --- a/Lib/test/test_multiprocessing_fork.py +++ b/Lib/test/test_multiprocessing_fork/__init__.py @@ -1,7 +1,6 @@ -import unittest -import test._test_multiprocessing - +import os.path import sys +import unittest from test import support if support.PGO: @@ -13,7 +12,5 @@ if sys.platform == 'darwin': raise unittest.SkipTest("test may crash on macOS (bpo-33725)") -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'fork') - -if __name__ == '__main__': - unittest.main() +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_multiprocessing_fork/test_manager.py b/Lib/test/test_multiprocessing_fork/test_manager.py new file mode 100644 index 00000000000000..9efbb83bbb73bf --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_manager.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', only_type="manager") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_fork/test_misc.py b/Lib/test/test_multiprocessing_fork/test_misc.py new file mode 100644 index 00000000000000..891a494020c3a1 --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_misc.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', exclude_types=True) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_fork/test_processes.py b/Lib/test/test_multiprocessing_fork/test_processes.py new file mode 100644 index 00000000000000..e64e9afc0100e8 --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_processes.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', only_type="processes") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_fork/test_threads.py b/Lib/test/test_multiprocessing_fork/test_threads.py new file mode 100644 index 00000000000000..1670e34cb17f25 --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_threads.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', only_type="threads") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver.py b/Lib/test/test_multiprocessing_forkserver/__init__.py similarity index 58% rename from Lib/test/test_multiprocessing_forkserver.py rename to Lib/test/test_multiprocessing_forkserver/__init__.py index 6ad5faf9e8a329..d91715a344dfa7 100644 --- a/Lib/test/test_multiprocessing_forkserver.py +++ b/Lib/test/test_multiprocessing_forkserver/__init__.py @@ -1,7 +1,6 @@ -import unittest -import test._test_multiprocessing - +import os.path import sys +import unittest from test import support if support.PGO: @@ -10,7 +9,5 @@ if sys.platform == "win32": raise unittest.SkipTest("forkserver is not available on Windows") -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'forkserver') - -if __name__ == '__main__': - unittest.main() +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_multiprocessing_forkserver/test_manager.py b/Lib/test/test_multiprocessing_forkserver/test_manager.py new file mode 100644 index 00000000000000..14f8f10dfb4e2f --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_manager.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', only_type="manager") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver/test_misc.py b/Lib/test/test_multiprocessing_forkserver/test_misc.py new file mode 100644 index 00000000000000..9cae1b50f71e00 --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_misc.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', exclude_types=True) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver/test_processes.py b/Lib/test/test_multiprocessing_forkserver/test_processes.py new file mode 100644 index 00000000000000..360967cf1ae152 --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_processes.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', only_type="processes") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver/test_threads.py b/Lib/test/test_multiprocessing_forkserver/test_threads.py new file mode 100644 index 00000000000000..719c752aa05350 --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_threads.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', only_type="threads") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn.py b/Lib/test/test_multiprocessing_spawn.py deleted file mode 100644 index 6558952308f25c..00000000000000 --- a/Lib/test/test_multiprocessing_spawn.py +++ /dev/null @@ -1,12 +0,0 @@ -import unittest -import test._test_multiprocessing - -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'spawn') - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/__init__.py b/Lib/test/test_multiprocessing_spawn/__init__.py new file mode 100644 index 00000000000000..3fd0f9b390612a --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/__init__.py @@ -0,0 +1,9 @@ +import os.path +import unittest +from test import support + +if support.PGO: + raise unittest.SkipTest("test is not helpful for PGO") + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_multiprocessing_spawn/test_manager.py b/Lib/test/test_multiprocessing_spawn/test_manager.py new file mode 100644 index 00000000000000..b40bea0bf61581 --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_manager.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', only_type="manager") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/test_misc.py b/Lib/test/test_multiprocessing_spawn/test_misc.py new file mode 100644 index 00000000000000..32f37c5cc81ee1 --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_misc.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', exclude_types=True) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/test_processes.py b/Lib/test/test_multiprocessing_spawn/test_processes.py new file mode 100644 index 00000000000000..af764b0d8483ab --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_processes.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', only_type="processes") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/test_threads.py b/Lib/test/test_multiprocessing_spawn/test_threads.py new file mode 100644 index 00000000000000..c1257749b9c419 --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_threads.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', only_type="threads") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py index 573d636de956d1..81e11a293cc4c8 100644 --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,5 +1,5 @@ import netrc, os, unittest, sys, textwrap -from test.support import os_helper, run_unittest +from test.support import os_helper try: import pwd @@ -308,8 +308,6 @@ def test_security(self): self.assertEqual(nrc.hosts['foo.domain.com'], ('anonymous', '', 'pass')) -def test_main(): - run_unittest(NetrcTestCase) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 538d758624c9d6..3e710d1c6dabe4 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -2,6 +2,7 @@ import ntpath import os import string +import subprocess import sys import unittest import warnings @@ -394,6 +395,10 @@ def test_realpath_basic(self): d = drives.pop().encode() self.assertEqual(ntpath.realpath(d), d) + # gh-106242: Embedded nulls and non-strict fallback to abspath + self.assertEqual(ABSTFN + "\0spam", + ntpath.realpath(os_helper.TESTFN + "\0spam", strict=False)) + @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_strict(self): @@ -404,6 +409,8 @@ def test_realpath_strict(self): self.addCleanup(os_helper.unlink, ABSTFN) self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN, strict=True) self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN + "2", strict=True) + # gh-106242: Embedded nulls should raise OSError (not ValueError) + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "\0spam", strict=True) @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') @@ -631,6 +638,48 @@ def test_realpath_cwd(self): with os_helper.change_cwd(test_dir_short): self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + def test_realpath_permission(self): + # Test whether python can resolve the real filename of a + # shortened file name even if it does not have permission to access it. + ABSTFN = ntpath.realpath(os_helper.TESTFN) + + os_helper.unlink(ABSTFN) + os_helper.rmtree(ABSTFN) + os.mkdir(ABSTFN) + self.addCleanup(os_helper.rmtree, ABSTFN) + + test_file = ntpath.join(ABSTFN, "LongFileName123.txt") + test_file_short = ntpath.join(ABSTFN, "LONGFI~1.TXT") + + with open(test_file, "wb") as f: + f.write(b"content") + # Automatic generation of short names may be disabled on + # NTFS volumes for the sake of performance. + # They're not supported at all on ReFS and exFAT. + subprocess.run( + # Try to set the short name manually. + ['fsutil.exe', 'file', 'setShortName', test_file, 'LONGFI~1.TXT'], + creationflags=subprocess.DETACHED_PROCESS + ) + + try: + self.assertPathEqual(test_file, ntpath.realpath(test_file_short)) + except AssertionError: + raise unittest.SkipTest('the filesystem seems to lack support for short filenames') + + # Deny the right to [S]YNCHRONIZE on the file to + # force nt._getfinalpathname to fail with ERROR_ACCESS_DENIED. + p = subprocess.run( + ['icacls.exe', test_file, '/deny', '*S-1-5-32-545:(S)'], + creationflags=subprocess.DETACHED_PROCESS + ) + + if p.returncode: + raise unittest.SkipTest('failed to deny access to the test file') + + self.assertPathEqual(test_file, ntpath.realpath(test_file_short)) + def test_expandvars(self): with os_helper.EnvironmentVarGuard() as env: env.clear() @@ -1036,6 +1085,7 @@ def test_path_normcase(self): self._check_function(self.path.normcase) if sys.platform == 'win32': self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ') + self.assertEqual(ntpath.normcase('abc\x00def'), 'abc\x00def') def test_path_isabs(self): self._check_function(self.path.isabs) diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 564dc4745ae64e..2b2783d57be8f4 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -1,8 +1,28 @@ +import copy +import pickle import dis import threading import types import unittest -from test.support import threading_helper +from test.support import threading_helper, check_impl_detail + +# Skip this module on other interpreters, it is cpython specific: +if check_impl_detail(cpython=False): + raise unittest.SkipTest('implementation detail specific to cpython') + +import _testinternalcapi + + +def disabling_optimizer(func): + def wrapper(*args, **kwargs): + old_opt = _testinternalcapi.get_optimizer() + _testinternalcapi.set_optimizer(None) + try: + return func(*args, **kwargs) + finally: + _testinternalcapi.set_optimizer(old_opt) + + return wrapper class TestLoadSuperAttrCache(unittest.TestCase): @@ -499,6 +519,7 @@ def assert_specialized(self, f, opname): opnames = {instruction.opname for instruction in instructions} self.assertIn(opname, opnames) + @disabling_optimizer def assert_races_do_not_crash( self, opname, get_items, read, write, *, check_items=False ): @@ -865,8 +886,10 @@ class C: items = [] for _ in range(self.ITEMS): item = C() - item.__dict__ item.a = None + # Resize into a combined unicode dict: + for i in range(29): + setattr(item, f"_{i}", None) items.append(item) return items @@ -932,7 +955,9 @@ class C: items = [] for _ in range(self.ITEMS): item = C() - item.__dict__ + # Resize into a combined unicode dict: + for i in range(29): + setattr(item, f"_{i}", None) items.append(item) return items @@ -993,6 +1018,124 @@ def write(items): opname = "UNPACK_SEQUENCE_LIST" self.assert_races_do_not_crash(opname, get_items, read, write) +class C: + pass + +class TestInstanceDict(unittest.TestCase): + + def setUp(self): + c = C() + c.a, c.b, c.c = 0,0,0 + + def test_values_on_instance(self): + c = C() + c.a = 1 + C().b = 2 + c.c = 3 + self.assertEqual( + _testinternalcapi.get_object_dict_values(c), + (1, '', 3) + ) + + def test_dict_materialization(self): + c = C() + c.a = 1 + c.b = 2 + c.__dict__ + self.assertIs( + _testinternalcapi.get_object_dict_values(c), + None + ) + + def test_dict_dematerialization(self): + c = C() + c.a = 1 + c.b = 2 + c.__dict__ + self.assertIs( + _testinternalcapi.get_object_dict_values(c), + None + ) + for _ in range(100): + c.a + self.assertEqual( + _testinternalcapi.get_object_dict_values(c), + (1, 2, '') + ) + + def test_dict_dematerialization_multiple_refs(self): + c = C() + c.a = 1 + c.b = 2 + d = c.__dict__ + for _ in range(100): + c.a + self.assertIs( + _testinternalcapi.get_object_dict_values(c), + None + ) + self.assertIs(c.__dict__, d) + + def test_dict_dematerialization_copy(self): + c = C() + c.a = 1 + c.b = 2 + c2 = copy.copy(c) + for _ in range(100): + c.a + c2.a + self.assertEqual( + _testinternalcapi.get_object_dict_values(c), + (1, 2, '') + ) + self.assertEqual( + _testinternalcapi.get_object_dict_values(c2), + (1, 2, '') + ) + c3 = copy.deepcopy(c) + for _ in range(100): + c.a + c3.a + self.assertEqual( + _testinternalcapi.get_object_dict_values(c), + (1, 2, '') + ) + #NOTE -- c3.__dict__ does not de-materialize + + def test_dict_dematerialization_pickle(self): + c = C() + c.a = 1 + c.b = 2 + c2 = pickle.loads(pickle.dumps(c)) + for _ in range(100): + c.a + c2.a + self.assertEqual( + _testinternalcapi.get_object_dict_values(c), + (1, 2, '') + ) + self.assertEqual( + _testinternalcapi.get_object_dict_values(c2), + (1, 2, '') + ) + + def test_dict_dematerialization_subclass(self): + class D(dict): pass + c = C() + c.a = 1 + c.b = 2 + c.__dict__ = D(c.__dict__) + for _ in range(100): + c.a + self.assertIs( + _testinternalcapi.get_object_dict_values(c), + None + ) + self.assertEqual( + c.__dict__, + {'a':1, 'b':2} + ) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py index e880c3f1ac875e..72488b2bb6b4ff 100644 --- a/Lib/test/test_opcodes.py +++ b/Lib/test/test_opcodes.py @@ -1,7 +1,8 @@ # Python test set -- part 2, opcodes import unittest -from test import ann_module, support +from test import support +from test.typinganndata import ann_module class OpcodeTest(unittest.TestCase): diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py index decbcc2419c9fc..4571b23dfe7c1a 100644 --- a/Lib/test/test_ordered_dict.py +++ b/Lib/test/test_ordered_dict.py @@ -122,6 +122,17 @@ def items(self): self.OrderedDict(Spam()) self.assertEqual(calls, ['keys']) + def test_overridden_init(self): + # Sync-up pure Python OD class with C class where + # a consistent internal state is created in __new__ + # rather than __init__. + OrderedDict = self.OrderedDict + class ODNI(OrderedDict): + def __init__(*args, **kwargs): + pass + od = ODNI() + od['a'] = 1 # This used to fail because __init__ was bypassed + def test_fromkeys(self): OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 99e9ed213e5615..c23de4dbe2b636 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -14,6 +14,7 @@ import os import pickle import select +import selectors import shutil import signal import socket @@ -737,7 +738,7 @@ def test_access_denied(self): # denied. See issue 28075. # os.environ['TEMP'] should be located on a volume that # supports file ACLs. - fname = os.path.join(os.environ['TEMP'], self.fname) + fname = os.path.join(os.environ['TEMP'], self.fname + "_access") self.addCleanup(os_helper.unlink, fname) create_file(fname, b'ABC') # Deny the right to [S]YNCHRONIZE on the file to @@ -913,6 +914,13 @@ def set_time(filename): os.utime(self.fname, None) self._test_utime_current(set_time) + def test_utime_nonexistent(self): + now = time.time() + filename = 'nonexistent' + with self.assertRaises(FileNotFoundError) as cm: + os.utime(filename, (now, now)) + self.assertEqual(cm.exception.filename, filename) + def get_file_system(self, path): if sys.platform == 'win32': root = os.path.splitdrive(os.path.abspath(path))[0] + '\\' @@ -2559,30 +2567,34 @@ def _kill_with_event(self, event, name): tagname = "test_os_%s" % uuid.uuid1() m = mmap.mmap(-1, 1, tagname) m[0] = 0 + # Run a script which has console control handling enabled. - proc = subprocess.Popen([sys.executable, - os.path.join(os.path.dirname(__file__), - "win_console_handler.py"), tagname], - creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) - # Let the interpreter startup before we send signals. See #3137. - count, max = 0, 100 - while count < max and proc.poll() is None: - if m[0] == 1: - break - time.sleep(0.1) - count += 1 - else: - # Forcefully kill the process if we weren't able to signal it. - os.kill(proc.pid, signal.SIGINT) - self.fail("Subprocess didn't finish initialization") - os.kill(proc.pid, event) - # proc.send_signal(event) could also be done here. - # Allow time for the signal to be passed and the process to exit. - time.sleep(0.5) - if not proc.poll(): - # Forcefully kill the process if we weren't able to signal it. - os.kill(proc.pid, signal.SIGINT) - self.fail("subprocess did not stop on {}".format(name)) + script = os.path.join(os.path.dirname(__file__), + "win_console_handler.py") + cmd = [sys.executable, script, tagname] + proc = subprocess.Popen(cmd, + creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) + + with proc: + # Let the interpreter startup before we send signals. See #3137. + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if proc.poll() is None: + break + else: + # Forcefully kill the process if we weren't able to signal it. + proc.kill() + self.fail("Subprocess didn't finish initialization") + + os.kill(proc.pid, event) + + try: + # proc.send_signal(event) could also be done here. + # Allow time for the signal to be passed and the process to exit. + proc.wait(timeout=support.SHORT_TIMEOUT) + except subprocess.TimeoutExpired: + # Forcefully kill the process if we weren't able to signal it. + proc.kill() + self.fail("subprocess did not stop on {}".format(name)) @unittest.skip("subprocesses aren't inheriting Ctrl+C property") @support.requires_subprocess() @@ -3915,6 +3927,328 @@ def test_eventfd_select(self): self.assertEqual((rfd, wfd, xfd), ([fd], [], [])) os.eventfd_read(fd) +@unittest.skipUnless(hasattr(os, 'timerfd_create'), 'requires os.timerfd_create') +@support.requires_linux_version(2, 6, 30) +class TimerfdTests(unittest.TestCase): + # Tolerate a difference of 1 ms + CLOCK_RES_NS = 1_000_000 + CLOCK_RES = CLOCK_RES_NS * 1e-9 + + def timerfd_create(self, *args, **kwargs): + fd = os.timerfd_create(*args, **kwargs) + self.assertGreaterEqual(fd, 0) + self.assertFalse(os.get_inheritable(fd)) + self.addCleanup(os.close, fd) + return fd + + def read_count_signaled(self, fd): + # read 8 bytes + data = os.read(fd, 8) + return int.from_bytes(data, byteorder=sys.byteorder) + + def test_timerfd_initval(self): + fd = self.timerfd_create(time.CLOCK_REALTIME) + + initial_expiration = 0.25 + interval = 0.125 + + # 1st call + next_expiration, interval2 = os.timerfd_settime(fd, initial=initial_expiration, interval=interval) + self.assertAlmostEqual(interval2, 0.0, places=3) + self.assertAlmostEqual(next_expiration, 0.0, places=3) + + # 2nd call + next_expiration, interval2 = os.timerfd_settime(fd, initial=initial_expiration, interval=interval) + self.assertAlmostEqual(interval2, interval, places=3) + self.assertAlmostEqual(next_expiration, initial_expiration, places=3) + + # timerfd_gettime + next_expiration, interval2 = os.timerfd_gettime(fd) + self.assertAlmostEqual(interval2, interval, places=3) + self.assertAlmostEqual(next_expiration, initial_expiration, places=3) + + def test_timerfd_non_blocking(self): + fd = self.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK) + + # 0.1 second later + initial_expiration = 0.1 + os.timerfd_settime(fd, initial=initial_expiration, interval=0) + + # read() raises OSError with errno is EAGAIN for non-blocking timer. + with self.assertRaises(OSError) as ctx: + self.read_count_signaled(fd) + self.assertEqual(ctx.exception.errno, errno.EAGAIN) + + # Wait more than 0.1 seconds + time.sleep(initial_expiration + 0.1) + + # confirm if timerfd is readable and read() returns 1 as bytes. + self.assertEqual(self.read_count_signaled(fd), 1) + + def test_timerfd_negative(self): + one_sec_in_nsec = 10**9 + fd = self.timerfd_create(time.CLOCK_REALTIME) + + test_flags = [0, os.TFD_TIMER_ABSTIME] + if hasattr(os, 'TFD_TIMER_CANCEL_ON_SET'): + test_flags.append(os.TFD_TIMER_ABSTIME | os.TFD_TIMER_CANCEL_ON_SET) + + # Any of 'initial' and 'interval' is negative value. + for initial, interval in ( (-1, 0), (1, -1), (-1, -1), (-0.1, 0), (1, -0.1), (-0.1, -0.1)): + for flags in test_flags: + with self.subTest(flags=flags, initial=initial, interval=interval): + with self.assertRaises(OSError) as context: + os.timerfd_settime(fd, flags=flags, initial=initial, interval=interval) + self.assertEqual(context.exception.errno, errno.EINVAL) + + with self.assertRaises(OSError) as context: + initial_ns = int( one_sec_in_nsec * initial ) + interval_ns = int( one_sec_in_nsec * interval ) + os.timerfd_settime_ns(fd, flags=flags, initial=initial_ns, interval=interval_ns) + self.assertEqual(context.exception.errno, errno.EINVAL) + + def test_timerfd_interval(self): + fd = self.timerfd_create(time.CLOCK_REALTIME) + + # 1 second + initial_expiration = 1 + # 0.5 second + interval = 0.5 + + os.timerfd_settime(fd, initial=initial_expiration, interval=interval) + + # timerfd_gettime + next_expiration, interval2 = os.timerfd_gettime(fd) + self.assertAlmostEqual(interval2, interval, places=3) + self.assertAlmostEqual(next_expiration, initial_expiration, places=3) + + count = 3 + t = time.perf_counter() + for _ in range(count): + self.assertEqual(self.read_count_signaled(fd), 1) + t = time.perf_counter() - t + + total_time = initial_expiration + interval * (count - 1) + self.assertGreater(t, total_time) + + # wait 3.5 time of interval + time.sleep( (count+0.5) * interval) + self.assertEqual(self.read_count_signaled(fd), count) + + def test_timerfd_TFD_TIMER_ABSTIME(self): + fd = self.timerfd_create(time.CLOCK_REALTIME) + + now = time.clock_gettime(time.CLOCK_REALTIME) + + # 1 second later from now. + offset = 1 + initial_expiration = now + offset + # not interval timer + interval = 0 + + os.timerfd_settime(fd, flags=os.TFD_TIMER_ABSTIME, initial=initial_expiration, interval=interval) + + # timerfd_gettime + # Note: timerfd_gettime returns relative values even if TFD_TIMER_ABSTIME is specified. + next_expiration, interval2 = os.timerfd_gettime(fd) + self.assertAlmostEqual(interval2, interval, places=3) + self.assertAlmostEqual(next_expiration, offset, places=3) + + t = time.perf_counter() + count_signaled = self.read_count_signaled(fd) + t = time.perf_counter() - t + self.assertEqual(count_signaled, 1) + + self.assertGreater(t, offset - self.CLOCK_RES) + + def test_timerfd_select(self): + fd = self.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK) + + rfd, wfd, xfd = select.select([fd], [fd], [fd], 0) + self.assertEqual((rfd, wfd, xfd), ([], [], [])) + + # 0.25 second + initial_expiration = 0.25 + # every 0.125 second + interval = 0.125 + + os.timerfd_settime(fd, initial=initial_expiration, interval=interval) + + count = 3 + t = time.perf_counter() + for _ in range(count): + rfd, wfd, xfd = select.select([fd], [fd], [fd], initial_expiration + interval) + self.assertEqual((rfd, wfd, xfd), ([fd], [], [])) + self.assertEqual(self.read_count_signaled(fd), 1) + t = time.perf_counter() - t + + total_time = initial_expiration + interval * (count - 1) + self.assertGreater(t, total_time) + + def check_timerfd_poll(self, nanoseconds): + fd = self.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK) + + selector = selectors.DefaultSelector() + selector.register(fd, selectors.EVENT_READ) + self.addCleanup(selector.close) + + sec_to_nsec = 10 ** 9 + # 0.25 second + initial_expiration_ns = sec_to_nsec // 4 + # every 0.125 second + interval_ns = sec_to_nsec // 8 + + if nanoseconds: + os.timerfd_settime_ns(fd, + initial=initial_expiration_ns, + interval=interval_ns) + else: + os.timerfd_settime(fd, + initial=initial_expiration_ns / sec_to_nsec, + interval=interval_ns / sec_to_nsec) + + count = 3 + if nanoseconds: + t = time.perf_counter_ns() + else: + t = time.perf_counter() + for i in range(count): + timeout_margin_ns = interval_ns + if i == 0: + timeout_ns = initial_expiration_ns + interval_ns + timeout_margin_ns + else: + timeout_ns = interval_ns + timeout_margin_ns + + ready = selector.select(timeout_ns / sec_to_nsec) + self.assertEqual(len(ready), 1, ready) + event = ready[0][1] + self.assertEqual(event, selectors.EVENT_READ) + + self.assertEqual(self.read_count_signaled(fd), 1) + + total_time = initial_expiration_ns + interval_ns * (count - 1) + if nanoseconds: + dt = time.perf_counter_ns() - t + self.assertGreater(dt, total_time) + else: + dt = time.perf_counter() - t + self.assertGreater(dt, total_time / sec_to_nsec) + selector.unregister(fd) + + def test_timerfd_poll(self): + self.check_timerfd_poll(False) + + def test_timerfd_ns_poll(self): + self.check_timerfd_poll(True) + + def test_timerfd_ns_initval(self): + one_sec_in_nsec = 10**9 + limit_error = one_sec_in_nsec // 10**3 + fd = self.timerfd_create(time.CLOCK_REALTIME) + + # 1st call + initial_expiration_ns = 0 + interval_ns = one_sec_in_nsec // 1000 + next_expiration_ns, interval_ns2 = os.timerfd_settime_ns(fd, initial=initial_expiration_ns, interval=interval_ns) + self.assertEqual(interval_ns2, 0) + self.assertEqual(next_expiration_ns, 0) + + # 2nd call + next_expiration_ns, interval_ns2 = os.timerfd_settime_ns(fd, initial=initial_expiration_ns, interval=interval_ns) + self.assertEqual(interval_ns2, interval_ns) + self.assertEqual(next_expiration_ns, initial_expiration_ns) + + # timerfd_gettime + next_expiration_ns, interval_ns2 = os.timerfd_gettime_ns(fd) + self.assertEqual(interval_ns2, interval_ns) + self.assertLessEqual(next_expiration_ns, initial_expiration_ns) + + self.assertAlmostEqual(next_expiration_ns, initial_expiration_ns, delta=limit_error) + + def test_timerfd_ns_interval(self): + one_sec_in_nsec = 10**9 + limit_error = one_sec_in_nsec // 10**3 + fd = self.timerfd_create(time.CLOCK_REALTIME) + + # 1 second + initial_expiration_ns = one_sec_in_nsec + # every 0.5 second + interval_ns = one_sec_in_nsec // 2 + + os.timerfd_settime_ns(fd, initial=initial_expiration_ns, interval=interval_ns) + + # timerfd_gettime + next_expiration_ns, interval_ns2 = os.timerfd_gettime_ns(fd) + self.assertEqual(interval_ns2, interval_ns) + self.assertLessEqual(next_expiration_ns, initial_expiration_ns) + + count = 3 + t = time.perf_counter_ns() + for _ in range(count): + self.assertEqual(self.read_count_signaled(fd), 1) + t = time.perf_counter_ns() - t + + total_time_ns = initial_expiration_ns + interval_ns * (count - 1) + self.assertGreater(t, total_time_ns) + + # wait 3.5 time of interval + time.sleep( (count+0.5) * interval_ns / one_sec_in_nsec) + self.assertEqual(self.read_count_signaled(fd), count) + + + def test_timerfd_ns_TFD_TIMER_ABSTIME(self): + one_sec_in_nsec = 10**9 + limit_error = one_sec_in_nsec // 10**3 + fd = self.timerfd_create(time.CLOCK_REALTIME) + + now_ns = time.clock_gettime_ns(time.CLOCK_REALTIME) + + # 1 second later from now. + offset_ns = one_sec_in_nsec + initial_expiration_ns = now_ns + offset_ns + # not interval timer + interval_ns = 0 + + os.timerfd_settime_ns(fd, flags=os.TFD_TIMER_ABSTIME, initial=initial_expiration_ns, interval=interval_ns) + + # timerfd_gettime + # Note: timerfd_gettime returns relative values even if TFD_TIMER_ABSTIME is specified. + next_expiration_ns, interval_ns2 = os.timerfd_gettime_ns(fd) + self.assertLess(abs(interval_ns2 - interval_ns), limit_error) + self.assertLess(abs(next_expiration_ns - offset_ns), limit_error) + + t = time.perf_counter_ns() + count_signaled = self.read_count_signaled(fd) + t = time.perf_counter_ns() - t + self.assertEqual(count_signaled, 1) + + self.assertGreater(t, offset_ns - self.CLOCK_RES_NS) + + def test_timerfd_ns_select(self): + one_sec_in_nsec = 10**9 + + fd = self.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK) + + rfd, wfd, xfd = select.select([fd], [fd], [fd], 0) + self.assertEqual((rfd, wfd, xfd), ([], [], [])) + + # 0.25 second + initial_expiration_ns = one_sec_in_nsec // 4 + # every 0.125 second + interval_ns = one_sec_in_nsec // 8 + + os.timerfd_settime_ns(fd, initial=initial_expiration_ns, interval=interval_ns) + + count = 3 + t = time.perf_counter_ns() + for _ in range(count): + rfd, wfd, xfd = select.select([fd], [fd], [fd], (initial_expiration_ns + interval_ns) / 1e9 ) + self.assertEqual((rfd, wfd, xfd), ([fd], [], [])) + self.assertEqual(self.read_count_signaled(fd), 1) + t = time.perf_counter_ns() - t + + total_time_ns = initial_expiration_ns + interval_ns * (count - 1) + self.assertGreater(t, total_time_ns) class OSErrorTests(unittest.TestCase): def setUp(self): @@ -3989,14 +4323,42 @@ def test_oserror_filename(self): self.fail(f"No exception thrown by {func}") class CPUCountTests(unittest.TestCase): + def check_cpu_count(self, cpus): + if cpus is None: + self.skipTest("Could not determine the number of CPUs") + + self.assertIsInstance(cpus, int) + self.assertGreater(cpus, 0) + def test_cpu_count(self): cpus = os.cpu_count() - if cpus is not None: - self.assertIsInstance(cpus, int) - self.assertGreater(cpus, 0) - else: + self.check_cpu_count(cpus) + + def test_process_cpu_count(self): + cpus = os.process_cpu_count() + self.assertLessEqual(cpus, os.cpu_count()) + self.check_cpu_count(cpus) + + @unittest.skipUnless(hasattr(os, 'sched_setaffinity'), + "don't have sched affinity support") + def test_process_cpu_count_affinity(self): + ncpu = os.cpu_count() + if ncpu is None: self.skipTest("Could not determine the number of CPUs") + # Disable one CPU + mask = os.sched_getaffinity(0) + if len(mask) <= 1: + self.skipTest(f"sched_getaffinity() returns less than " + f"2 CPUs: {sorted(mask)}") + self.addCleanup(os.sched_setaffinity, 0, list(mask)) + mask.pop() + os.sched_setaffinity(0, mask) + + # test process_cpu_count() + affinity = os.process_cpu_count() + self.assertEqual(affinity, ncpu - 1) + # FD inheritance check is only useful for systems with process support. @support.requires_subprocess() diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 78948e3b720320..2781e019220353 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -11,6 +11,7 @@ import tempfile import unittest from unittest import mock +from urllib.request import pathname2url from test.support import import_helper from test.support import set_recursion_limit @@ -613,6 +614,7 @@ def test_with_name_common(self): self.assertRaises(ValueError, P('.').with_name, 'd.xml') self.assertRaises(ValueError, P('/').with_name, 'd.xml') self.assertRaises(ValueError, P('a/b').with_name, '') + self.assertRaises(ValueError, P('a/b').with_name, '.') self.assertRaises(ValueError, P('a/b').with_name, '/c') self.assertRaises(ValueError, P('a/b').with_name, 'c/') self.assertRaises(ValueError, P('a/b').with_name, 'c/d') @@ -630,6 +632,7 @@ def test_with_stem_common(self): self.assertRaises(ValueError, P('.').with_stem, 'd') self.assertRaises(ValueError, P('/').with_stem, 'd') self.assertRaises(ValueError, P('a/b').with_stem, '') + self.assertRaises(ValueError, P('a/b').with_stem, '.') self.assertRaises(ValueError, P('a/b').with_stem, '/c') self.assertRaises(ValueError, P('a/b').with_stem, 'c/') self.assertRaises(ValueError, P('a/b').with_stem, 'c/d') @@ -693,8 +696,14 @@ def test_relative_to_common(self): self.assertRaises(ValueError, p.relative_to, P('a/b/c')) self.assertRaises(ValueError, p.relative_to, P('a/c')) self.assertRaises(ValueError, p.relative_to, P('/a')) + self.assertRaises(ValueError, p.relative_to, P("../a")) + self.assertRaises(ValueError, p.relative_to, P("a/..")) + self.assertRaises(ValueError, p.relative_to, P("/a/..")) self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) self.assertRaises(ValueError, p.relative_to, P('/a'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True) p = P('/a/b') self.assertEqual(p.relative_to(P('/')), P('a/b')) self.assertEqual(p.relative_to('/'), P('a/b')) @@ -723,8 +732,14 @@ def test_relative_to_common(self): self.assertRaises(ValueError, p.relative_to, P()) self.assertRaises(ValueError, p.relative_to, '') self.assertRaises(ValueError, p.relative_to, P('a')) + self.assertRaises(ValueError, p.relative_to, P("../a")) + self.assertRaises(ValueError, p.relative_to, P("a/..")) + self.assertRaises(ValueError, p.relative_to, P("/a/..")) self.assertRaises(ValueError, p.relative_to, P(''), walk_up=True) self.assertRaises(ValueError, p.relative_to, P('a'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True) def test_is_relative_to_common(self): P = self.cls @@ -1222,8 +1237,10 @@ def test_with_name(self): self.assertRaises(ValueError, P('c:').with_name, 'd.xml') self.assertRaises(ValueError, P('c:/').with_name, 'd.xml') self.assertRaises(ValueError, P('//My/Share').with_name, 'd.xml') - self.assertRaises(ValueError, P('c:a/b').with_name, 'd:') - self.assertRaises(ValueError, P('c:a/b').with_name, 'd:e') + self.assertEqual(str(P('a').with_name('d:')), '.\\d:') + self.assertEqual(str(P('a').with_name('d:e')), '.\\d:e') + self.assertEqual(P('c:a/b').with_name('d:'), P('c:a/d:')) + self.assertEqual(P('c:a/b').with_name('d:e'), P('c:a/d:e')) self.assertRaises(ValueError, P('c:a/b').with_name, 'd:/e') self.assertRaises(ValueError, P('c:a/b').with_name, '//My/Share') @@ -1236,8 +1253,10 @@ def test_with_stem(self): self.assertRaises(ValueError, P('c:').with_stem, 'd') self.assertRaises(ValueError, P('c:/').with_stem, 'd') self.assertRaises(ValueError, P('//My/Share').with_stem, 'd') - self.assertRaises(ValueError, P('c:a/b').with_stem, 'd:') - self.assertRaises(ValueError, P('c:a/b').with_stem, 'd:e') + self.assertEqual(str(P('a').with_stem('d:')), '.\\d:') + self.assertEqual(str(P('a').with_stem('d:e')), '.\\d:e') + self.assertEqual(P('c:a/b').with_stem('d:'), P('c:a/d:')) + self.assertEqual(P('c:a/b').with_stem('d:e'), P('c:a/d:e')) self.assertRaises(ValueError, P('c:a/b').with_stem, 'd:/e') self.assertRaises(ValueError, P('c:a/b').with_stem, '//My/Share') @@ -1570,14 +1589,176 @@ def test_group(self): # -# Tests for the concrete classes. +# Tests for the virtual classes. # -class PathTest(unittest.TestCase): - """Tests for the FS-accessing functionalities of the Path classes.""" +class PathBaseTest(PurePathTest): + cls = pathlib._PathBase - cls = pathlib.Path - can_symlink = os_helper.can_symlink() + def test_unsupported_operation(self): + P = self.cls + p = self.cls() + e = pathlib.UnsupportedOperation + self.assertRaises(e, p.stat) + self.assertRaises(e, p.lstat) + self.assertRaises(e, p.exists) + self.assertRaises(e, p.samefile, 'foo') + self.assertRaises(e, p.is_dir) + self.assertRaises(e, p.is_file) + self.assertRaises(e, p.is_mount) + self.assertRaises(e, p.is_symlink) + self.assertRaises(e, p.is_block_device) + self.assertRaises(e, p.is_char_device) + self.assertRaises(e, p.is_fifo) + self.assertRaises(e, p.is_socket) + self.assertRaises(e, p.open) + self.assertRaises(e, p.read_bytes) + self.assertRaises(e, p.read_text) + self.assertRaises(e, p.write_bytes, b'foo') + self.assertRaises(e, p.write_text, 'foo') + self.assertRaises(e, p.iterdir) + self.assertRaises(e, p.glob, '*') + self.assertRaises(e, p.rglob, '*') + self.assertRaises(e, lambda: list(p.walk())) + self.assertRaises(e, p.absolute) + self.assertRaises(e, P.cwd) + self.assertRaises(e, p.expanduser) + self.assertRaises(e, p.home) + self.assertRaises(e, p.readlink) + self.assertRaises(e, p.symlink_to, 'foo') + self.assertRaises(e, p.hardlink_to, 'foo') + self.assertRaises(e, p.mkdir) + self.assertRaises(e, p.touch) + self.assertRaises(e, p.rename, 'foo') + self.assertRaises(e, p.replace, 'foo') + self.assertRaises(e, p.chmod, 0o755) + self.assertRaises(e, p.lchmod, 0o755) + self.assertRaises(e, p.unlink) + self.assertRaises(e, p.rmdir) + self.assertRaises(e, p.owner) + self.assertRaises(e, p.group) + self.assertRaises(e, p.as_uri) + + def test_as_uri_common(self): + e = pathlib.UnsupportedOperation + self.assertRaises(e, self.cls().as_uri) + + def test_fspath_common(self): + self.assertRaises(TypeError, os.fspath, self.cls()) + + def test_as_bytes_common(self): + self.assertRaises(TypeError, bytes, self.cls()) + + def test_matches_path_api(self): + our_names = {name for name in dir(self.cls) if name[0] != '_'} + path_names = {name for name in dir(pathlib.Path) if name[0] != '_'} + self.assertEqual(our_names, path_names) + for attr_name in our_names: + our_attr = getattr(self.cls, attr_name) + path_attr = getattr(pathlib.Path, attr_name) + self.assertEqual(our_attr.__doc__, path_attr.__doc__) + + +class DummyPathIO(io.BytesIO): + """ + Used by DummyPath to implement `open('w')` + """ + + def __init__(self, files, path): + super().__init__() + self.files = files + self.path = path + + def close(self): + self.files[self.path] = self.getvalue() + super().close() + + +class DummyPath(pathlib._PathBase): + """ + Simple implementation of PathBase that keeps files and directories in + memory. + """ + _files = {} + _directories = {} + _symlinks = {} + + def stat(self, *, follow_symlinks=True): + if follow_symlinks: + path = str(self.resolve()) + else: + path = str(self.parent.resolve() / self.name) + if path in self._files: + st_mode = stat.S_IFREG + elif path in self._directories: + st_mode = stat.S_IFDIR + elif path in self._symlinks: + st_mode = stat.S_IFLNK + else: + raise FileNotFoundError(errno.ENOENT, "Not found", str(self)) + return os.stat_result((st_mode, hash(str(self)), 0, 0, 0, 0, 0, 0, 0, 0)) + + def open(self, mode='r', buffering=-1, encoding=None, + errors=None, newline=None): + if buffering != -1: + raise NotImplementedError + path_obj = self.resolve() + path = str(path_obj) + name = path_obj.name + parent = str(path_obj.parent) + if path in self._directories: + raise IsADirectoryError(errno.EISDIR, "Is a directory", path) + + text = 'b' not in mode + mode = ''.join(c for c in mode if c not in 'btU') + if mode == 'r': + if path not in self._files: + raise FileNotFoundError(errno.ENOENT, "File not found", path) + stream = io.BytesIO(self._files[path]) + elif mode == 'w': + if parent not in self._directories: + raise FileNotFoundError(errno.ENOENT, "File not found", parent) + stream = DummyPathIO(self._files, path) + self._files[path] = b'' + self._directories[parent].add(name) + else: + raise NotImplementedError + if text: + stream = io.TextIOWrapper(stream, encoding=encoding, errors=errors, newline=newline) + return stream + + def iterdir(self): + path = str(self.resolve()) + if path in self._files: + raise NotADirectoryError(errno.ENOTDIR, "Not a directory", path) + elif path in self._directories: + return (self / name for name in self._directories[path]) + else: + raise FileNotFoundError(errno.ENOENT, "File not found", path) + + def mkdir(self, mode=0o777, parents=False, exist_ok=False): + path = str(self.resolve()) + if path in self._directories: + if exist_ok: + return + else: + raise FileExistsError(errno.EEXIST, "File exists", path) + try: + if self.name: + self._directories[str(self.parent)].add(self.name) + self._directories[path] = set() + except KeyError: + if not parents: + raise FileNotFoundError(errno.ENOENT, "File not found", str(self.parent)) from None + self.parent.mkdir(parents=True, exist_ok=True) + self.mkdir(mode, parents=False, exist_ok=exist_ok) + + +class DummyPathTest(unittest.TestCase): + """Tests for PathBase methods that use stat(), open() and iterdir().""" + + cls = DummyPath + can_symlink = False # (BASE) # | @@ -1600,37 +1781,42 @@ class PathTest(unittest.TestCase): # def setUp(self): - def cleanup(): - os.chmod(join('dirE'), 0o777) - os_helper.rmtree(BASE) - self.addCleanup(cleanup) - os.mkdir(BASE) - os.mkdir(join('dirA')) - os.mkdir(join('dirB')) - os.mkdir(join('dirC')) - os.mkdir(join('dirC', 'dirD')) - os.mkdir(join('dirE')) - with open(join('fileA'), 'wb') as f: + pathmod = self.cls.pathmod + p = self.cls(BASE) + p.mkdir(parents=True) + p.joinpath('dirA').mkdir() + p.joinpath('dirB').mkdir() + p.joinpath('dirC').mkdir() + p.joinpath('dirC', 'dirD').mkdir() + p.joinpath('dirE').mkdir() + with p.joinpath('fileA').open('wb') as f: f.write(b"this is file A\n") - with open(join('dirB', 'fileB'), 'wb') as f: + with p.joinpath('dirB', 'fileB').open('wb') as f: f.write(b"this is file B\n") - with open(join('dirC', 'fileC'), 'wb') as f: + with p.joinpath('dirC', 'fileC').open('wb') as f: f.write(b"this is file C\n") - with open(join('dirC', 'novel.txt'), 'wb') as f: + with p.joinpath('dirC', 'novel.txt').open('wb') as f: f.write(b"this is a novel\n") - with open(join('dirC', 'dirD', 'fileD'), 'wb') as f: + with p.joinpath('dirC', 'dirD', 'fileD').open('wb') as f: f.write(b"this is file D\n") - os.chmod(join('dirE'), 0) if self.can_symlink: - # Relative symlinks. - os.symlink('fileA', join('linkA')) - os.symlink('non-existing', join('brokenLink')) - os.symlink('dirB', join('linkB'), target_is_directory=True) - os.symlink(os.path.join('..', 'dirB'), join('dirA', 'linkC'), target_is_directory=True) - # This one goes upwards, creating a loop. - os.symlink(os.path.join('..', 'dirB'), join('dirB', 'linkD'), target_is_directory=True) - # Broken symlink (pointing to itself). - os.symlink('brokenLinkLoop', join('brokenLinkLoop')) + p.joinpath('linkA').symlink_to('fileA') + p.joinpath('brokenLink').symlink_to('non-existing') + p.joinpath('linkB').symlink_to('dirB') + p.joinpath('dirA', 'linkC').symlink_to(pathmod.join('..', 'dirB')) + p.joinpath('dirB', 'linkD').symlink_to(pathmod.join('..', 'dirB')) + p.joinpath('brokenLinkLoop').symlink_to('brokenLinkLoop') + + def tearDown(self): + cls = self.cls + cls._files.clear() + cls._directories.clear() + cls._symlinks.clear() + + def tempdir(self): + path = self.cls(BASE).with_name('tmp-dirD') + path.mkdir() + return path def assertFileNotFound(self, func, *args, **kwargs): with self.assertRaises(FileNotFoundError) as cm: @@ -1754,7 +1940,7 @@ def test_iterdir_nodir(self): # __iter__ on something that is not a directory. p = self.cls(BASE, 'fileA') with self.assertRaises(OSError) as cm: - next(p.iterdir()) + p.iterdir() # ENOENT or EINVAL under Windows, ENOTDIR otherwise # (see issue #12802). self.assertIn(cm.exception.errno, (errno.ENOTDIR, @@ -1891,11 +2077,11 @@ def _check(glob, expected): "dirC/dirD", "dirC/dirD/fileD"]) _check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"]) _check(p.rglob("**/file*"), ["dirC/fileC", "dirC/dirD/fileD"]) - _check(p.rglob("dir*/**"), ["dirC/dirD"]) + _check(p.rglob("dir*/**/"), ["dirC/dirD"]) _check(p.rglob("*/*"), ["dirC/dirD/fileD"]) _check(p.rglob("*/"), ["dirC/dirD"]) _check(p.rglob(""), ["dirC", "dirC/dirD"]) - _check(p.rglob("**"), ["dirC", "dirC/dirD"]) + _check(p.rglob("**/"), ["dirC", "dirC/dirD"]) # gh-91616, a re module regression _check(p.rglob("*.txt"), ["dirC/novel.txt"]) _check(p.rglob("*.*"), ["dirC/novel.txt"]) @@ -1979,9 +2165,11 @@ def test_rglob_symlink_loop(self): def test_glob_many_open_files(self): depth = 30 P = self.cls - base = P(BASE) / 'deep' - p = P(base, *(['d']*depth)) - p.mkdir(parents=True) + p = base = P(BASE) / 'deep' + p.mkdir() + for _ in range(depth): + p /= 'd' + p.mkdir() pattern = '/'.join(['*'] * depth) iters = [base.glob(pattern) for j in range(100)] for it in iters: @@ -2045,7 +2233,20 @@ def test_glob_above_recursion_limit(self): path.mkdir(parents=True) with set_recursion_limit(recursion_limit): - list(base.glob('**')) + list(base.glob('**/')) + + def test_glob_recursive_no_trailing_slash(self): + P = self.cls + p = P(BASE) + with self.assertWarns(FutureWarning): + p.glob('**') + with self.assertWarns(FutureWarning): + p.glob('*/**') + with self.assertWarns(FutureWarning): + p.rglob('**') + with self.assertWarns(FutureWarning): + p.rglob('*/**') + def test_readlink(self): if not self.can_symlink: @@ -2055,6 +2256,7 @@ def test_readlink(self): self.assertEqual((P / 'brokenLink').readlink(), self.cls('non-existing')) self.assertEqual((P / 'linkB').readlink(), self.cls('dirB')) + self.assertEqual((P / 'linkB' / 'linkD').readlink(), self.cls('../dirB')) with self.assertRaises(OSError): (P / 'fileA').readlink() @@ -2103,7 +2305,7 @@ def test_resolve_common(self): self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB', 'foo', 'in', 'spam'), False) p = P(BASE, 'dirA', 'linkC', '..', 'foo', 'in', 'spam') - if os.name == 'nt': + if os.name == 'nt' and isinstance(p, pathlib.Path): # In Windows, if linkY points to dirB, 'dirA\linkY\..' # resolves to 'dirA' without resolving linkY first. self._check_resolve_relative(p, P(BASE, 'dirA', 'foo', 'in', @@ -2113,9 +2315,7 @@ def test_resolve_common(self): # resolves to 'dirB/..' first before resolving to parent of dirB. self._check_resolve_relative(p, P(BASE, 'foo', 'in', 'spam'), False) # Now create absolute symlinks. - d = os_helper._longpath(tempfile.mkdtemp(suffix='-dirD', - dir=os.getcwd())) - self.addCleanup(os_helper.rmtree, d) + d = self.tempdir() P(BASE, 'dirA', 'linkX').symlink_to(d) P(BASE, str(d), 'linkY').symlink_to(join('dirB')) p = P(BASE, 'dirA', 'linkX', 'linkY', 'fileB') @@ -2125,7 +2325,7 @@ def test_resolve_common(self): self._check_resolve_relative(p, P(BASE, 'dirB', 'foo', 'in', 'spam'), False) p = P(BASE, 'dirA', 'linkX', 'linkY', '..', 'foo', 'in', 'spam') - if os.name == 'nt': + if os.name == 'nt' and isinstance(p, pathlib.Path): # In Windows, if linkY points to dirB, 'dirA\linkY\..' # resolves to 'dirA' without resolving linkY first. self._check_resolve_relative(p, P(d, 'foo', 'in', 'spam'), False) @@ -2149,6 +2349,38 @@ def test_resolve_dot(self): # Non-strict self.assertEqual(r.resolve(strict=False), p / '3' / '4') + def _check_symlink_loop(self, *args): + path = self.cls(*args) + with self.assertRaises(OSError) as cm: + path.resolve(strict=True) + self.assertEqual(cm.exception.errno, errno.ELOOP) + + def test_resolve_loop(self): + if not self.can_symlink: + self.skipTest("symlinks required") + if os.name == 'nt' and issubclass(self.cls, pathlib.Path): + self.skipTest("symlink loops work differently with concrete Windows paths") + # Loops with relative symlinks. + self.cls(BASE, 'linkX').symlink_to('linkX/inside') + self._check_symlink_loop(BASE, 'linkX') + self.cls(BASE, 'linkY').symlink_to('linkY') + self._check_symlink_loop(BASE, 'linkY') + self.cls(BASE, 'linkZ').symlink_to('linkZ/../linkZ') + self._check_symlink_loop(BASE, 'linkZ') + # Non-strict + p = self.cls(BASE, 'linkZ', 'foo') + self.assertEqual(p.resolve(strict=False), p) + # Loops with absolute symlinks. + self.cls(BASE, 'linkU').symlink_to(join('linkU/inside')) + self._check_symlink_loop(BASE, 'linkU') + self.cls(BASE, 'linkV').symlink_to(join('linkV')) + self._check_symlink_loop(BASE, 'linkV') + self.cls(BASE, 'linkW').symlink_to(join('linkW/../linkW')) + self._check_symlink_loop(BASE, 'linkW') + # Non-strict + q = self.cls(BASE, 'linkW', 'foo') + self.assertEqual(q.resolve(strict=False), q) + def test_stat(self): statA = self.cls(BASE).joinpath('fileA').stat() statB = self.cls(BASE).joinpath('dirB', 'fileB').stat() @@ -2357,6 +2589,10 @@ def _check_complex_symlinks(self, link0_target): self.assertEqualNormCase(str(p), BASE) # Resolve relative paths. + try: + self.cls().absolute() + except pathlib.UnsupportedOperation: + return old_path = os.getcwd() os.chdir(BASE) try: @@ -2384,6 +2620,50 @@ def test_complex_symlinks_relative(self): def test_complex_symlinks_relative_dot_dot(self): self._check_complex_symlinks(os.path.join('dirA', '..')) + +class DummyPathWithSymlinks(DummyPath): + def readlink(self): + path = str(self.parent.resolve() / self.name) + if path in self._symlinks: + return self.with_segments(self._symlinks[path]) + elif path in self._files or path in self._directories: + raise OSError(errno.EINVAL, "Not a symlink", path) + else: + raise FileNotFoundError(errno.ENOENT, "File not found", path) + + def symlink_to(self, target, target_is_directory=False): + self._directories[str(self.parent)].add(self.name) + self._symlinks[str(self)] = str(target) + + +class DummyPathWithSymlinksTest(DummyPathTest): + cls = DummyPathWithSymlinks + can_symlink = True + + +# +# Tests for the concrete classes. +# + +class PathTest(DummyPathTest): + """Tests for the FS-accessing functionalities of the Path classes.""" + cls = pathlib.Path + can_symlink = os_helper.can_symlink() + + def setUp(self): + super().setUp() + os.chmod(join('dirE'), 0) + + def tearDown(self): + os.chmod(join('dirE'), 0o777) + os_helper.rmtree(BASE) + + def tempdir(self): + d = os_helper._longpath(tempfile.mkdtemp(suffix='-dirD', + dir=os.getcwd())) + self.addCleanup(os_helper.rmtree, d) + return d + def test_concrete_class(self): if self.cls is pathlib.Path: expected = pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath @@ -3153,11 +3433,6 @@ def test_absolute(self): self.assertEqual(str(P('//a').absolute()), '//a') self.assertEqual(str(P('//a/b').absolute()), '//a/b') - def _check_symlink_loop(self, *args, strict=True): - path = self.cls(*args) - with self.assertRaises(RuntimeError): - print(path.resolve(strict)) - @unittest.skipIf( is_emscripten or is_wasi, "umask is not implemented on Emscripten/WASI." @@ -3204,28 +3479,6 @@ def test_touch_mode(self): st = os.stat(join('masked_new_file')) self.assertEqual(stat.S_IMODE(st.st_mode), 0o750) - def test_resolve_loop(self): - if not self.can_symlink: - self.skipTest("symlinks required") - # Loops with relative symlinks. - os.symlink('linkX/inside', join('linkX')) - self._check_symlink_loop(BASE, 'linkX') - os.symlink('linkY', join('linkY')) - self._check_symlink_loop(BASE, 'linkY') - os.symlink('linkZ/../linkZ', join('linkZ')) - self._check_symlink_loop(BASE, 'linkZ') - # Non-strict - self._check_symlink_loop(BASE, 'linkZ', 'foo', strict=False) - # Loops with absolute symlinks. - os.symlink(join('linkU/inside'), join('linkU')) - self._check_symlink_loop(BASE, 'linkU') - os.symlink(join('linkV'), join('linkV')) - self._check_symlink_loop(BASE, 'linkV') - os.symlink(join('linkW/../linkW'), join('linkW')) - self._check_symlink_loop(BASE, 'linkW') - # Non-strict - self._check_symlink_loop(BASE, 'linkW', 'foo', strict=False) - def test_glob(self): P = self.cls p = P(BASE) @@ -3322,6 +3575,24 @@ def test_handling_bad_descriptor(self): self.fail("Bad file descriptor not handled.") raise + def test_from_uri(self): + P = self.cls + self.assertEqual(P.from_uri('file:/foo/bar'), P('/foo/bar')) + self.assertEqual(P.from_uri('file://foo/bar'), P('//foo/bar')) + self.assertEqual(P.from_uri('file:///foo/bar'), P('/foo/bar')) + self.assertEqual(P.from_uri('file:////foo/bar'), P('//foo/bar')) + self.assertEqual(P.from_uri('file://localhost/foo/bar'), P('/foo/bar')) + self.assertRaises(ValueError, P.from_uri, 'foo/bar') + self.assertRaises(ValueError, P.from_uri, '/foo/bar') + self.assertRaises(ValueError, P.from_uri, '//foo/bar') + self.assertRaises(ValueError, P.from_uri, 'file:foo/bar') + self.assertRaises(ValueError, P.from_uri, 'http://foo/bar') + + def test_from_uri_pathname2url(self): + P = self.cls + self.assertEqual(P.from_uri('file:' + pathname2url('/foo/bar')), P('/foo/bar')) + self.assertEqual(P.from_uri('file:' + pathname2url('//foo/bar')), P('//foo/bar')) + @only_nt class WindowsPathTest(PathTest): @@ -3441,6 +3712,31 @@ def check(): env['HOME'] = 'C:\\Users\\eve' check() + def test_from_uri(self): + P = self.cls + # DOS drive paths + self.assertEqual(P.from_uri('file:c:/path/to/file'), P('c:/path/to/file')) + self.assertEqual(P.from_uri('file:c|/path/to/file'), P('c:/path/to/file')) + self.assertEqual(P.from_uri('file:/c|/path/to/file'), P('c:/path/to/file')) + self.assertEqual(P.from_uri('file:///c|/path/to/file'), P('c:/path/to/file')) + # UNC paths + self.assertEqual(P.from_uri('file://server/path/to/file'), P('//server/path/to/file')) + self.assertEqual(P.from_uri('file:////server/path/to/file'), P('//server/path/to/file')) + self.assertEqual(P.from_uri('file://///server/path/to/file'), P('//server/path/to/file')) + # Localhost paths + self.assertEqual(P.from_uri('file://localhost/c:/path/to/file'), P('c:/path/to/file')) + self.assertEqual(P.from_uri('file://localhost/c|/path/to/file'), P('c:/path/to/file')) + # Invalid paths + self.assertRaises(ValueError, P.from_uri, 'foo/bar') + self.assertRaises(ValueError, P.from_uri, 'c:/foo/bar') + self.assertRaises(ValueError, P.from_uri, '//foo/bar') + self.assertRaises(ValueError, P.from_uri, 'file:foo/bar') + self.assertRaises(ValueError, P.from_uri, 'http://foo/bar') + + def test_from_uri_pathname2url(self): + P = self.cls + self.assertEqual(P.from_uri('file:' + pathname2url(r'c:\path\to\file')), P('c:/path/to/file')) + self.assertEqual(P.from_uri('file:' + pathname2url(r'\\server\path\to\file')), P('//server/path/to/file')) class PathSubclassTest(PathTest): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index a66953557e52dc..ff677aeb795442 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -664,8 +664,10 @@ def test_pdb_alias_command(): ... o.method() >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'alias pi', ... 'alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")', ... 'alias ps pi self', + ... 'alias ps', ... 'pi o', ... 's', ... 'ps', @@ -674,8 +676,12 @@ def test_pdb_alias_command(): ... test_function() > (4)test_function() -> o.method() + (Pdb) alias pi + *** Unknown alias 'pi' (Pdb) alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}") (Pdb) alias ps pi self + (Pdb) alias ps + ps = pi self (Pdb) pi o o.attr1 = 10 o.attr2 = str @@ -826,6 +832,414 @@ def test_convenience_variables(): (Pdb) continue """ + +def test_post_mortem_chained(): + """Test post mortem traceback debugging of chained exception + + >>> def test_function_2(): + ... try: + ... 1/0 + ... finally: + ... print('Exception!') + + >>> def test_function_reraise(): + ... try: + ... test_function_2() + ... except ZeroDivisionError as e: + ... raise ZeroDivisionError('reraised') from e + + >>> def test_function(): + ... import pdb; + ... instance = pdb.Pdb(nosigint=True, readrc=False) + ... try: + ... test_function_reraise() + ... except Exception as e: + ... pdb._post_mortem(e, instance) + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... 'exceptions', + ... 'exceptions 0', + ... '$_exception', + ... 'up', + ... 'down', + ... 'exceptions 1', + ... '$_exception', + ... 'up', + ... 'down', + ... 'exceptions -1', + ... 'exceptions 3', + ... 'up', + ... 'exit', + ... ]): + ... try: + ... test_function() + ... except ZeroDivisionError: + ... print('Correctly reraised.') + Exception! + > (5)test_function_reraise() + -> raise ZeroDivisionError('reraised') from e + (Pdb) exceptions + 0 ZeroDivisionError('division by zero') + > 1 ZeroDivisionError('reraised') + (Pdb) exceptions 0 + > (3)test_function_2() + -> 1/0 + (Pdb) $_exception + ZeroDivisionError('division by zero') + (Pdb) up + > (3)test_function_reraise() + -> test_function_2() + (Pdb) down + > (3)test_function_2() + -> 1/0 + (Pdb) exceptions 1 + > (5)test_function_reraise() + -> raise ZeroDivisionError('reraised') from e + (Pdb) $_exception + ZeroDivisionError('reraised') + (Pdb) up + > (5)test_function() + -> test_function_reraise() + (Pdb) down + > (5)test_function_reraise() + -> raise ZeroDivisionError('reraised') from e + (Pdb) exceptions -1 + *** No exception with that number + (Pdb) exceptions 3 + *** No exception with that number + (Pdb) up + > (5)test_function() + -> test_function_reraise() + (Pdb) exit + """ + + +def test_post_mortem_cause_no_context(): + """Test post mortem traceback debugging of chained exception + + >>> def make_exc_with_stack(type_, *content, from_=None): + ... try: + ... raise type_(*content) from from_ + ... except Exception as out: + ... return out + ... + + >>> def main(): + ... try: + ... raise ValueError('Context Not Shown') + ... except Exception as e1: + ... raise ValueError("With Cause") from make_exc_with_stack(TypeError,'The Cause') + + >>> def test_function(): + ... import pdb; + ... instance = pdb.Pdb(nosigint=True, readrc=False) + ... try: + ... main() + ... except Exception as e: + ... pdb._post_mortem(e, instance) + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... 'exceptions', + ... 'exceptions 0', + ... 'exceptions 1', + ... 'up', + ... 'down', + ... 'exit', + ... ]): + ... try: + ... test_function() + ... except ValueError: + ... print('Ok.') + > (5)main() + -> raise ValueError("With Cause") from make_exc_with_stack(TypeError,'The Cause') + (Pdb) exceptions + 0 TypeError('The Cause') + > 1 ValueError('With Cause') + (Pdb) exceptions 0 + > (3)make_exc_with_stack() + -> raise type_(*content) from from_ + (Pdb) exceptions 1 + > (5)main() + -> raise ValueError("With Cause") from make_exc_with_stack(TypeError,'The Cause') + (Pdb) up + > (5)test_function() + -> main() + (Pdb) down + > (5)main() + -> raise ValueError("With Cause") from make_exc_with_stack(TypeError,'The Cause') + (Pdb) exit""" + + +def test_post_mortem_context_of_the_cause(): + """Test post mortem traceback debugging of chained exception + + + >>> def main(): + ... try: + ... raise TypeError('Context of the cause') + ... except Exception as e1: + ... try: + ... raise ValueError('Root Cause') + ... except Exception as e2: + ... ex = e2 + ... raise ValueError("With Cause, and cause has context") from ex + + >>> def test_function(): + ... import pdb; + ... instance = pdb.Pdb(nosigint=True, readrc=False) + ... try: + ... main() + ... except Exception as e: + ... pdb._post_mortem(e, instance) + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... 'exceptions', + ... 'exceptions 2', + ... 'up', + ... 'down', + ... 'exceptions 3', + ... 'up', + ... 'down', + ... 'exceptions 4', + ... 'up', + ... 'down', + ... 'exit', + ... ]): + ... try: + ... test_function() + ... except ValueError: + ... print('Correctly reraised.') + > (9)main() + -> raise ValueError("With Cause, and cause has context") from ex + (Pdb) exceptions + 0 TypeError('Context of the cause') + 1 ValueError('Root Cause') + > 2 ValueError('With Cause, and cause has context') + (Pdb) exceptions 2 + > (9)main() + -> raise ValueError("With Cause, and cause has context") from ex + (Pdb) up + > (5)test_function() + -> main() + (Pdb) down + > (9)main() + -> raise ValueError("With Cause, and cause has context") from ex + (Pdb) exceptions 3 + *** No exception with that number + (Pdb) up + > (5)test_function() + -> main() + (Pdb) down + > (9)main() + -> raise ValueError("With Cause, and cause has context") from ex + (Pdb) exceptions 4 + *** No exception with that number + (Pdb) up + > (5)test_function() + -> main() + (Pdb) down + > (9)main() + -> raise ValueError("With Cause, and cause has context") from ex + (Pdb) exit + """ + + +def test_post_mortem_from_none(): + """Test post mortem traceback debugging of chained exception + + In particular that cause from None (which sets __supress_context__ to True) + does not show context. + + + >>> def main(): + ... try: + ... raise TypeError('Context of the cause') + ... except Exception as e1: + ... raise ValueError("With Cause, and cause has context") from None + + >>> def test_function(): + ... import pdb; + ... instance = pdb.Pdb(nosigint=True, readrc=False) + ... try: + ... main() + ... except Exception as e: + ... pdb._post_mortem(e, instance) + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... 'exceptions', + ... 'exit', + ... ]): + ... try: + ... test_function() + ... except ValueError: + ... print('Correctly reraised.') + > (5)main() + -> raise ValueError("With Cause, and cause has context") from None + (Pdb) exceptions + > 0 ValueError('With Cause, and cause has context') + (Pdb) exit + """ + + +def test_post_mortem_from_no_stack(): + """Test post mortem traceback debugging of chained exception + + especially when one exception has no stack. + + >>> def main(): + ... raise Exception() from Exception() + + + >>> def test_function(): + ... import pdb; + ... instance = pdb.Pdb(nosigint=True, readrc=False) + ... try: + ... main() + ... except Exception as e: + ... pdb._post_mortem(e, instance) + + >>> with PdbTestInput( # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... ["exceptions", + ... "exceptions 0", + ... "exit"], + ... ): + ... try: + ... test_function() + ... except ValueError: + ... print('Correctly reraised.') + > (2)main() + -> raise Exception() from Exception() + (Pdb) exceptions + - Exception() + > 1 Exception() + (Pdb) exceptions 0 + *** This exception does not have a traceback, cannot jump to it + (Pdb) exit + """ + + +def test_post_mortem_single_no_stack(): + """Test post mortem called when origin exception has no stack + + + >>> def test_function(): + ... import pdb; + ... instance = pdb.Pdb(nosigint=True, readrc=False) + ... import sys + ... sys.last_exc = Exception() + ... pdb._post_mortem(sys.last_exc, instance) + + >>> with PdbTestInput( # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... [] + ... ): + ... try: + ... test_function() + ... except ValueError as e: + ... print(e) + A valid traceback must be passed if no exception is being handled + """ + +def test_post_mortem_complex(): + """Test post mortem traceback debugging of chained exception + + Test with simple and complex cycles, exception groups,... + + >>> def make_ex_with_stack(type_, *content, from_=None): + ... try: + ... raise type_(*content) from from_ + ... except Exception as out: + ... return out + ... + + >>> def cycle(): + ... try: + ... raise ValueError("Cycle Leaf") + ... except Exception as e: + ... raise e from e + ... + + >>> def tri_cycle(): + ... a = make_ex_with_stack(ValueError, "Cycle1") + ... b = make_ex_with_stack(ValueError, "Cycle2") + ... c = make_ex_with_stack(ValueError, "Cycle3") + ... + ... a.__cause__ = b + ... b.__cause__ = c + ... + ... raise c from a + ... + + >>> def cause(): + ... try: + ... raise ValueError("Cause Leaf") + ... except Exception as e: + ... raise e + ... + + >>> def context(n=10): + ... try: + ... raise ValueError(f"Context Leaf {n}") + ... except Exception as e: + ... if n == 0: + ... raise ValueError(f"With Context {n}") from e + ... else: + ... context(n - 1) + ... + + >>> def main(): + ... try: + ... cycle() + ... except Exception as e1: + ... try: + ... tri_cycle() + ... except Exception as e2: + ... ex = e2 + ... raise ValueError("With Context and With Cause") from ex + + + >>> def test_function(): + ... import pdb; + ... instance = pdb.Pdb(nosigint=True, readrc=False) + ... try: + ... main() + ... except Exception as e: + ... pdb._post_mortem(e, instance) + + >>> with PdbTestInput( # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... ["exceptions", + ... "exceptions 0", + ... "exceptions 1", + ... "exceptions 2", + ... "exceptions 3", + ... "exit"], + ... ): + ... try: + ... test_function() + ... except ValueError: + ... print('Correctly reraised.') + > (9)main() + -> raise ValueError("With Context and With Cause") from ex + (Pdb) exceptions + 0 ValueError('Cycle2') + 1 ValueError('Cycle1') + 2 ValueError('Cycle3') + > 3 ValueError('With Context and With Cause') + (Pdb) exceptions 0 + > (3)make_ex_with_stack() + -> raise type_(*content) from from_ + (Pdb) exceptions 1 + > (3)make_ex_with_stack() + -> raise type_(*content) from from_ + (Pdb) exceptions 2 + > (3)make_ex_with_stack() + -> raise type_(*content) from from_ + (Pdb) exceptions 3 + > (9)main() + -> raise ValueError("With Context and With Cause") from ex + (Pdb) exit + """ + + def test_post_mortem(): """Test post mortem traceback debugging. @@ -1614,6 +2028,46 @@ def test_pdb_multiline_statement(): (Pdb) c """ +def test_pdb_show_attribute_and_item(): + """Test for multiline statement + + >>> def test_function(): + ... n = lambda x: x + ... c = {"a": 1} + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... pass + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'c["a"]', + ... 'c.get("a")', + ... 'n(1)', + ... 'j=1', + ... 'j+1', + ... 'r"a"', + ... 'next(iter([1]))', + ... 'list((0, 1))', + ... 'c' + ... ]): + ... test_function() + > (5)test_function() + -> pass + (Pdb) c["a"] + 1 + (Pdb) c.get("a") + 1 + (Pdb) n(1) + 1 + (Pdb) j=1 + (Pdb) j+1 + 2 + (Pdb) r"a" + 'a' + (Pdb) next(iter([1])) + 1 + (Pdb) list((0, 1)) + [0, 1] + (Pdb) c + """ def test_pdb_issue_20766(): """Test for reference leaks when the SIGINT handler is set. @@ -1855,6 +2309,24 @@ def test_pdb_issue_gh_101517(): (Pdb) continue """ +def test_pdb_issue_gh_108976(): + """See GH-108976 + Make sure setting f_trace_opcodes = True won't crash pdb + >>> def test_function(): + ... import sys + ... sys._getframe().f_trace_opcodes = True + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... a = 1 + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'continue' + ... ]): + ... test_function() + bdb.Bdb.dispatch: unknown debugging event: 'opcode' + > (5)test_function() + -> a = 1 + (Pdb) continue + """ + def test_pdb_ambiguous_statements(): """See GH-104301 @@ -1878,6 +2350,53 @@ def test_pdb_ambiguous_statements(): (Pdb) continue """ +def test_pdb_issue_gh_65052(): + """See GH-65052 + + args, retval and display should not crash if the object is not displayable + >>> class A: + ... def __new__(cls): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... return object.__new__(cls) + ... def __init__(self): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... self.a = 1 + ... def __repr__(self): + ... return self.a + + >>> def test_function(): + ... A() + >>> with PdbTestInput([ # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE + ... 's', + ... 'retval', + ... 'continue', + ... 'args', + ... 'display self', + ... 'display', + ... 'continue', + ... ]): + ... test_function() + > (4)__new__() + -> return object.__new__(cls) + (Pdb) s + --Return-- + > (4)__new__()-> + -> return object.__new__(cls) + (Pdb) retval + *** repr(retval) failed: AttributeError: 'A' object has no attribute 'a' *** + (Pdb) continue + > (7)__init__() + -> self.a = 1 + (Pdb) args + self = *** repr(self) failed: AttributeError: 'A' object has no attribute 'a' *** + (Pdb) display self + display self: *** repr(self) failed: AttributeError: 'A' object has no attribute 'a' *** + (Pdb) display + Currently displaying: + self: *** repr(self) failed: AttributeError: 'A' object has no attribute 'a' *** + (Pdb) continue + """ + @support.requires_subprocess() class PdbTestCase(unittest.TestCase): diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 82b0b50d0ea437..b825b27060e86b 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -4,6 +4,7 @@ import textwrap import unittest +from test import support from test.support.bytecode_helper import BytecodeTestCase, CfgOptimizationTestCase @@ -522,6 +523,7 @@ def genexpr(): return (y for x in a for y in [f(x)]) self.assertEqual(count_instr_recursively(genexpr, 'FOR_ITER'), 1) + @support.requires_resource('cpu') def test_format_combinations(self): flags = '-+ #0' testcases = [ @@ -991,6 +993,7 @@ def test_conditional_jump_forward_non_const_condition(self): ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), ('LOAD_CONST', 2, 13), + ('RETURN_VALUE', 13), lbl, ('LOAD_CONST', 3, 14), ('RETURN_VALUE', 14), @@ -998,7 +1001,7 @@ def test_conditional_jump_forward_non_const_condition(self): expected_insts = [ ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), - ('LOAD_CONST', 1, 13), + ('RETURN_CONST', 1, 13), lbl, ('RETURN_CONST', 2, 14), ] @@ -1072,6 +1075,7 @@ def test_no_unsafe_static_swap(self): ('STORE_FAST', 1, 4), ('STORE_FAST', 1, 4), ('POP_TOP', 0, 4), + ('LOAD_CONST', 0, 5), ('RETURN_VALUE', 5) ] expected_insts = [ @@ -1080,7 +1084,7 @@ def test_no_unsafe_static_swap(self): ('NOP', 0, 3), ('STORE_FAST', 1, 4), ('POP_TOP', 0, 4), - ('RETURN_VALUE', 5) + ('RETURN_CONST', 0) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) @@ -1092,6 +1096,7 @@ def test_dead_store_elimination_in_same_lineno(self): ('STORE_FAST', 1, 4), ('STORE_FAST', 1, 4), ('STORE_FAST', 1, 4), + ('LOAD_CONST', 0, 5), ('RETURN_VALUE', 5) ] expected_insts = [ @@ -1100,7 +1105,7 @@ def test_dead_store_elimination_in_same_lineno(self): ('NOP', 0, 3), ('POP_TOP', 0, 4), ('STORE_FAST', 1, 4), - ('RETURN_VALUE', 5) + ('RETURN_CONST', 0, 5) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) @@ -1112,9 +1117,19 @@ def test_no_dead_store_elimination_in_different_lineno(self): ('STORE_FAST', 1, 4), ('STORE_FAST', 1, 5), ('STORE_FAST', 1, 6), + ('LOAD_CONST', 0, 5), ('RETURN_VALUE', 5) ] - self.cfg_optimization_test(insts, insts, consts=list(range(3)), nlocals=1) + expected_insts = [ + ('LOAD_CONST', 0, 1), + ('LOAD_CONST', 1, 2), + ('LOAD_CONST', 2, 3), + ('STORE_FAST', 1, 4), + ('STORE_FAST', 1, 5), + ('STORE_FAST', 1, 6), + ('RETURN_CONST', 0, 5) + ] + self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) if __name__ == "__main__": diff --git a/Lib/test/test_peg_generator/__init__.py b/Lib/test/test_peg_generator/__init__.py index 77f72fcc7c6e3b..b32db4426f251d 100644 --- a/Lib/test/test_peg_generator/__init__.py +++ b/Lib/test/test_peg_generator/__init__.py @@ -1,13 +1,10 @@ import os.path -import unittest from test import support from test.support import load_package_tests -if support.check_sanitizer(address=True, memory=True): - # bpo-46633: Skip the test because it is too slow when Python is built - # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. - raise unittest.SkipTest("test too slow on ASAN/MSAN build") +# Creating a virtual environment and building C extensions is slow +support.requires('cpu') # Load all tests in package diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py index f9105a9f23bd6d..9e273e99e387a4 100644 --- a/Lib/test/test_peg_generator/test_c_parser.py +++ b/Lib/test/test_peg_generator/test_c_parser.py @@ -404,7 +404,7 @@ def test_ternary_operator(self) -> None: a='[' b=NAME c=for_if_clauses d=']' { _PyAST_ListComp(b, c, EXTRA) } ) for_if_clauses[asdl_comprehension_seq*]: ( - a[asdl_comprehension_seq*]=(y=[ASYNC] 'for' a=NAME 'in' b=NAME c[asdl_expr_seq*]=('if' z=NAME { z })* + a[asdl_comprehension_seq*]=(y=['async'] 'for' a=NAME 'in' b=NAME c[asdl_expr_seq*]=('if' z=NAME { z })* { _PyAST_comprehension(_PyAST_Name(((expr_ty) a)->v.Name.id, Store, EXTRA), b, c, (y == NULL) ? 0 : 1, p->arena) })+ { a } ) """ diff --git a/Lib/test/test_peg_generator/test_pegen.py b/Lib/test/test_peg_generator/test_pegen.py index 3af2c0cf47d20a..86db767b99a228 100644 --- a/Lib/test/test_peg_generator/test_pegen.py +++ b/Lib/test/test_peg_generator/test_pegen.py @@ -42,6 +42,15 @@ def test_parse_grammar(self) -> None: ) self.assertEqual(repr(rules["term"]), expected_repr) + def test_repeated_rules(self) -> None: + grammar_source = """ + start: the_rule NEWLINE + the_rule: 'b' NEWLINE + the_rule: 'a' NEWLINE + """ + with self.assertRaisesRegex(GrammarError, "Repeated rule 'the_rule'"): + parse_string(grammar_source, GrammarParser) + def test_long_rule_str(self) -> None: grammar_source = """ start: zero | one | one zero | one one | one zero zero | one zero one | one one zero | one one one diff --git a/Lib/test/test_pep646_syntax.py b/Lib/test/test_pep646_syntax.py index 3ffa82dc55fa23..aac089b190bc11 100644 --- a/Lib/test/test_pep646_syntax.py +++ b/Lib/test/test_pep646_syntax.py @@ -1,3 +1,6 @@ +import doctest +import unittest + doctests = """ Setup @@ -317,10 +320,10 @@ __test__ = {'doctests' : doctests} -def test_main(verbose=False): - from test import support - from test import test_pep646_syntax - support.run_doctest(test_pep646_syntax, verbose) +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + if __name__ == "__main__": - test_main(verbose=True) + unittest.main() diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py index 5418f9f35485f8..fe8707a156e9dc 100644 --- a/Lib/test/test_perf_profiler.py +++ b/Lib/test/test_perf_profiler.py @@ -17,6 +17,11 @@ if not support.has_subprocess_support: raise unittest.SkipTest("test module requires subprocess") +if support.check_sanitizer(address=True, memory=True, ub=True): + # gh-109580: Skip the test because it does crash randomly if Python is + # built with ASAN. + raise unittest.SkipTest("test crash randomly on ASAN/MSAN/UBSAN build") + def supports_trampoline_profiling(): perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") @@ -287,7 +292,6 @@ def run_perf(cwd, *args, **env_vars): @unittest.skipUnless(perf_command_works(), "perf command doesn't work") @unittest.skipUnless(is_unwinding_reliable(), "Unwinding is unreliable") -@support.skip_if_sanitizer(address=True, memory=True, ub=True) class TestPerfProfiler(unittest.TestCase): def setUp(self): super().setUp() diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index 02165a0244ddf4..1847ae95db9292 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -8,7 +8,7 @@ import time import unittest from test.support import ( - cpython_only, requires_subprocess, requires_working_socket + cpython_only, requires_subprocess, requires_working_socket, requires_resource ) from test.support import threading_helper from test.support.os_helper import TESTFN @@ -124,6 +124,7 @@ def fileno(self): # select(), modified to use poll() instead. @requires_subprocess() + @requires_resource('walltime') def test_poll2(self): cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index fa41ba0b6e4637..869f9431b928bb 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -29,8 +29,8 @@ import ssl SUPPORTS_SSL = True - CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") - CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "keycert3.pem") + CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "pycacert.pem") requires_ssl = skipUnless(SUPPORTS_SSL, 'SSL not supported') diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 444f8abe4607b7..9d72dba159c6be 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1205,6 +1205,7 @@ def test_sched_getaffinity(self): @requires_sched_affinity def test_sched_setaffinity(self): mask = posix.sched_getaffinity(0) + self.addCleanup(posix.sched_setaffinity, 0, list(mask)) if len(mask) > 1: # Empty masks are forbidden mask.pop() diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index c9c2b42861c6f4..f31a68c5d84e03 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -76,21 +76,22 @@ def expectedFailureIfStdinIsTTY(fun): pass return fun + +def write_all(fd, data): + written = os.write(fd, data) + if written != len(data): + # gh-73256, gh-110673: It should never happen, but check just in case + raise Exception(f"short write: os.write({fd}, {len(data)} bytes) " + f"wrote {written} bytes") + + # Marginal testing of pty suite. Cannot do extensive 'do or fail' testing # because pty code is not too portable. class PtyTest(unittest.TestCase): def setUp(self): - old_alarm = signal.signal(signal.SIGALRM, self.handle_sig) - self.addCleanup(signal.signal, signal.SIGALRM, old_alarm) - old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup) self.addCleanup(signal.signal, signal.SIGHUP, old_sighup) - # isatty() and close() can hang on some platforms. Set an alarm - # before running the test to make sure we don't hang forever. - self.addCleanup(signal.alarm, 0) - signal.alarm(10) - # Save original stdin window size. self.stdin_dim = None if _HAVE_WINSZ: @@ -101,9 +102,6 @@ def setUp(self): except tty.error: pass - def handle_sig(self, sig, frame): - self.fail("isatty hung") - @staticmethod def handle_sighup(signum, frame): pass @@ -181,14 +179,14 @@ def test_openpty(self): os.set_blocking(master_fd, blocking) debug("Writing to slave_fd") - os.write(slave_fd, TEST_STRING_1) + write_all(slave_fd, TEST_STRING_1) s1 = _readline(master_fd) self.assertEqual(b'I wish to buy a fish license.\n', normalize_output(s1)) debug("Writing chunked output") - os.write(slave_fd, TEST_STRING_2[:5]) - os.write(slave_fd, TEST_STRING_2[5:]) + write_all(slave_fd, TEST_STRING_2[:5]) + write_all(slave_fd, TEST_STRING_2[5:]) s2 = _readline(master_fd) self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2)) @@ -371,8 +369,8 @@ def test__copy_to_each(self): masters = [s.fileno() for s in socketpair] # Feed data. Smaller than PIPEBUF. These writes will not block. - os.write(masters[1], b'from master') - os.write(write_to_stdin_fd, b'from stdin') + write_all(masters[1], b'from master') + write_all(write_to_stdin_fd, b'from stdin') # Expect three select calls, the last one will cause IndexError pty.select = self._mock_select diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 5e0a44ad9691ec..c4e6551f605782 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -132,7 +132,9 @@ def test_exceptions_propagate(self): os.chmod(self.directory, mode.st_mode) def test_bad_coding(self): - bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + bad_coding = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'bad_coding2.py') with support.captured_stderr(): self.assertIsNone(py_compile.compile(bad_coding, doraise=False)) self.assertFalse(os.path.exists( @@ -195,7 +197,9 @@ def test_invalidation_mode(self): self.assertEqual(flags, 0b1) def test_quiet(self): - bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + bad_coding = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'bad_coding2.py') with support.captured_stderr() as stderr: self.assertIsNone(py_compile.compile(bad_coding, doraise=False, quiet=2)) self.assertIsNone(py_compile.compile(bad_coding, doraise=True, quiet=2)) @@ -260,14 +264,18 @@ def test_with_files(self): self.assertTrue(os.path.exists(self.cache_path)) def test_bad_syntax(self): - bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py') + bad_syntax = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'badsyntax_3131.py') rc, stdout, stderr = self.pycompilecmd_failure(bad_syntax) self.assertEqual(rc, 1) self.assertEqual(stdout, b'') self.assertIn(b'SyntaxError', stderr) def test_bad_syntax_with_quiet(self): - bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py') + bad_syntax = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'badsyntax_3131.py') rc, stdout, stderr = self.pycompilecmd_failure('-q', bad_syntax) self.assertEqual(rc, 1) self.assertEqual(stdout, b'') diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index ddb5187f90da9b..70c5ebd694ca88 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -1,3 +1,4 @@ +import datetime import os import sys import contextlib @@ -12,6 +13,7 @@ import stat import tempfile import test.support +import time import types import typing import unittest @@ -22,6 +24,7 @@ from io import StringIO from collections import namedtuple from urllib.request import urlopen, urlcleanup +from test import support from test.support import import_helper from test.support import os_helper from test.support.script_helper import (assert_python_ok, @@ -1180,6 +1183,148 @@ def test_module_level_callable(self): self.assertEqual(self._get_summary_line(os.stat), "stat(path, *, dir_fd=None, follow_symlinks=True)") + def test_module_level_callable_noargs(self): + self.assertEqual(self._get_summary_line(time.time), + "time()") + + def test_module_level_callable_o(self): + try: + import _stat + except ImportError: + # stat.S_IMODE() and _stat.S_IMODE() have a different signature + self.skipTest('_stat extension is missing') + + self.assertEqual(self._get_summary_line(_stat.S_IMODE), + "S_IMODE(object, /)") + + def test_unbound_builtin_method_noargs(self): + self.assertEqual(self._get_summary_line(str.lower), + "lower(self, /)") + + def test_bound_builtin_method_noargs(self): + self.assertEqual(self._get_summary_line(''.lower), + "lower() method of builtins.str instance") + + def test_unbound_builtin_method_o(self): + self.assertEqual(self._get_summary_line(set.add), + "add(self, object, /)") + + def test_bound_builtin_method_o(self): + self.assertEqual(self._get_summary_line(set().add), + "add(object, /) method of builtins.set instance") + + def test_unbound_builtin_method_coexist_o(self): + self.assertEqual(self._get_summary_line(set.__contains__), + "__contains__(self, object, /)") + + def test_bound_builtin_method_coexist_o(self): + self.assertEqual(self._get_summary_line(set().__contains__), + "__contains__(object, /) method of builtins.set instance") + + def test_unbound_builtin_classmethod_noargs(self): + self.assertEqual(self._get_summary_line(datetime.datetime.__dict__['utcnow']), + "utcnow(type, /)") + + def test_bound_builtin_classmethod_noargs(self): + self.assertEqual(self._get_summary_line(datetime.datetime.utcnow), + "utcnow() method of builtins.type instance") + + def test_unbound_builtin_classmethod_o(self): + self.assertEqual(self._get_summary_line(dict.__dict__['__class_getitem__']), + "__class_getitem__(type, object, /)") + + def test_bound_builtin_classmethod_o(self): + self.assertEqual(self._get_summary_line(dict.__class_getitem__), + "__class_getitem__(object, /) method of builtins.type instance") + + @support.cpython_only + def test_module_level_callable_unrepresentable_default(self): + import _testcapi + builtin = _testcapi.func_with_unrepresentable_signature + self.assertEqual(self._get_summary_line(builtin), + "func_with_unrepresentable_signature(a, b=)") + + @support.cpython_only + def test_builtin_staticmethod_unrepresentable_default(self): + self.assertEqual(self._get_summary_line(str.maketrans), + "maketrans(x, y=, z=, /)") + import _testcapi + cls = _testcapi.DocStringUnrepresentableSignatureTest + self.assertEqual(self._get_summary_line(cls.staticmeth), + "staticmeth(a, b=)") + + @support.cpython_only + def test_unbound_builtin_method_unrepresentable_default(self): + self.assertEqual(self._get_summary_line(dict.pop), + "pop(self, key, default=, /)") + import _testcapi + cls = _testcapi.DocStringUnrepresentableSignatureTest + self.assertEqual(self._get_summary_line(cls.meth), + "meth(self, /, a, b=)") + + @support.cpython_only + def test_bound_builtin_method_unrepresentable_default(self): + self.assertEqual(self._get_summary_line({}.pop), + "pop(key, default=, /) " + "method of builtins.dict instance") + import _testcapi + obj = _testcapi.DocStringUnrepresentableSignatureTest() + self.assertEqual(self._get_summary_line(obj.meth), + "meth(a, b=) " + "method of _testcapi.DocStringUnrepresentableSignatureTest instance") + + @support.cpython_only + def test_unbound_builtin_classmethod_unrepresentable_default(self): + import _testcapi + cls = _testcapi.DocStringUnrepresentableSignatureTest + descr = cls.__dict__['classmeth'] + self.assertEqual(self._get_summary_line(descr), + "classmeth(type, /, a, b=)") + + @support.cpython_only + def test_bound_builtin_classmethod_unrepresentable_default(self): + import _testcapi + cls = _testcapi.DocStringUnrepresentableSignatureTest + self.assertEqual(self._get_summary_line(cls.classmeth), + "classmeth(a, b=) method of builtins.type instance") + + def test_overridden_text_signature(self): + class C: + def meth(*args, **kwargs): + pass + @classmethod + def cmeth(*args, **kwargs): + pass + @staticmethod + def smeth(*args, **kwargs): + pass + for text_signature, unbound, bound in [ + ("($slf)", "(slf, /)", "()"), + ("($slf, /)", "(slf, /)", "()"), + ("($slf, /, arg)", "(slf, /, arg)", "(arg)"), + ("($slf, /, arg=)", "(slf, /, arg=)", "(arg=)"), + ("($slf, arg, /)", "(slf, arg, /)", "(arg, /)"), + ("($slf, arg=, /)", "(slf, arg=, /)", "(arg=, /)"), + ("(/, slf, arg)", "(/, slf, arg)", "(/, slf, arg)"), + ("(/, slf, arg=)", "(/, slf, arg=)", "(/, slf, arg=)"), + ("(slf, /, arg)", "(slf, /, arg)", "(arg)"), + ("(slf, /, arg=)", "(slf, /, arg=)", "(arg=)"), + ("(slf, arg, /)", "(slf, arg, /)", "(arg, /)"), + ("(slf, arg=, /)", "(slf, arg=, /)", "(arg=, /)"), + ]: + with self.subTest(text_signature): + C.meth.__text_signature__ = text_signature + self.assertEqual(self._get_summary_line(C.meth), + "meth" + unbound) + self.assertEqual(self._get_summary_line(C().meth), + "meth" + bound + " method of test.test_pydoc.C instance") + C.cmeth.__func__.__text_signature__ = text_signature + self.assertEqual(self._get_summary_line(C.cmeth), + "cmeth" + bound + " method of builtins.type instance") + C.smeth.__text_signature__ = text_signature + self.assertEqual(self._get_summary_line(C.smeth), + "smeth" + unbound) + @requires_docstrings def test_staticmethod(self): class X: diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 863c1194672c1c..a542abaf1f35aa 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -1,18 +1,19 @@ # XXX TypeErrors on calling handlers, or on bad return values from a # handler, are obscure and unhelpful. -from io import BytesIO import os -import platform import sys import sysconfig import unittest import traceback +from io import BytesIO +from test import support +from test.support import os_helper from xml.parsers import expat from xml.parsers.expat import errors -from test.support import sortdict, is_emscripten, is_wasi +from test.support import sortdict class SetAttributeTest(unittest.TestCase): @@ -281,12 +282,10 @@ def test_legal(self): expat.ParserCreate(namespace_separator=' ') def test_illegal(self): - try: + with self.assertRaisesRegex(TypeError, + r"ParserCreate\(\) argument (2|'namespace_separator') " + r"must be str or None, not int"): expat.ParserCreate(namespace_separator=42) - self.fail() - except TypeError as e: - self.assertEqual(str(e), - "ParserCreate() argument 'namespace_separator' must be str or None, not int") try: expat.ParserCreate(namespace_separator='too long') @@ -441,37 +440,59 @@ def test7(self): # Test handling of exception from callback: class HandlerExceptionTest(unittest.TestCase): def StartElementHandler(self, name, attrs): - raise RuntimeError(name) + raise RuntimeError(f'StartElementHandler: <{name}>') def check_traceback_entry(self, entry, filename, funcname): - self.assertEqual(os.path.basename(entry[0]), filename) - self.assertEqual(entry[2], funcname) + self.assertEqual(os.path.basename(entry.filename), filename) + self.assertEqual(entry.name, funcname) + @support.cpython_only def test_exception(self): + # gh-66652: test _PyTraceback_Add() used by pyexpat.c to inject frames + + # Change the current directory to the Python source code directory + # if it is available. + src_dir = sysconfig.get_config_var('abs_builddir') + if src_dir: + have_source = os.path.isdir(src_dir) + else: + have_source = False + if have_source: + with os_helper.change_cwd(src_dir): + self._test_exception(have_source) + else: + self._test_exception(have_source) + + def _test_exception(self, have_source): + # Use path relative to the current directory which should be the Python + # source code directory (if it is available). + PYEXPAT_C = os.path.join('Modules', 'pyexpat.c') + parser = expat.ParserCreate() parser.StartElementHandler = self.StartElementHandler try: parser.Parse(b"", True) - self.fail() - except RuntimeError as e: - self.assertEqual(e.args[0], 'a', - "Expected RuntimeError for element 'a', but" + \ - " found %r" % e.args[0]) - # Check that the traceback contains the relevant line in pyexpat.c - entries = traceback.extract_tb(e.__traceback__) - self.assertEqual(len(entries), 3) - self.check_traceback_entry(entries[0], - "test_pyexpat.py", "test_exception") - self.check_traceback_entry(entries[1], - "pyexpat.c", "StartElement") - self.check_traceback_entry(entries[2], - "test_pyexpat.py", "StartElementHandler") - if (sysconfig.is_python_build() - and not (sys.platform == 'win32' and platform.machine() == 'ARM') - and not is_emscripten - and not is_wasi - ): - self.assertIn('call_with_frame("StartElement"', entries[1][3]) + + self.fail("the parser did not raise RuntimeError") + except RuntimeError as exc: + self.assertEqual(exc.args[0], 'StartElementHandler: ', exc) + entries = traceback.extract_tb(exc.__traceback__) + + self.assertEqual(len(entries), 3, entries) + self.check_traceback_entry(entries[0], + "test_pyexpat.py", "_test_exception") + self.check_traceback_entry(entries[1], + os.path.basename(PYEXPAT_C), + "StartElement") + self.check_traceback_entry(entries[2], + "test_pyexpat.py", "StartElementHandler") + + # Check that the traceback contains the relevant line in + # Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not + # available. + if have_source and os.path.exists(PYEXPAT_C): + self.assertIn('call_with_frame("StartElement"', + entries[1].line) # Test Current* members: diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index a6f5af17d7d51b..301d4a516568b2 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -127,8 +127,10 @@ def test_basic_re_sub(self): self.assertEqual(re.sub("(?i)b+", "x", "bbbb BBBB"), 'x x') self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y'), '9.3 -3 24x100y') - self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y', 3), - '9.3 -3 23x99y') + with self.assertWarns(DeprecationWarning) as w: + self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y', 3), + '9.3 -3 23x99y') + self.assertEqual(w.filename, __file__) self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y', count=3), '9.3 -3 23x99y') @@ -235,9 +237,42 @@ def test_sub_template_numeric_escape(self): def test_qualified_re_sub(self): self.assertEqual(re.sub('a', 'b', 'aaaaa'), 'bbbbb') - self.assertEqual(re.sub('a', 'b', 'aaaaa', 1), 'baaaa') + with self.assertWarns(DeprecationWarning) as w: + self.assertEqual(re.sub('a', 'b', 'aaaaa', 1), 'baaaa') + self.assertEqual(w.filename, __file__) self.assertEqual(re.sub('a', 'b', 'aaaaa', count=1), 'baaaa') + with self.assertRaisesRegex(TypeError, + r"sub\(\) got multiple values for argument 'count'"): + re.sub('a', 'b', 'aaaaa', 1, count=1) + with self.assertRaisesRegex(TypeError, + r"sub\(\) got multiple values for argument 'flags'"): + re.sub('a', 'b', 'aaaaa', 1, 0, flags=0) + with self.assertRaisesRegex(TypeError, + r"sub\(\) takes from 3 to 5 positional arguments but 6 " + r"were given"): + re.sub('a', 'b', 'aaaaa', 1, 0, 0) + + def test_misuse_flags(self): + with self.assertWarns(DeprecationWarning) as w: + result = re.sub('a', 'b', 'aaaaa', re.I) + self.assertEqual(result, re.sub('a', 'b', 'aaaaa', count=int(re.I))) + self.assertEqual(str(w.warning), + "'count' is passed as positional argument") + self.assertEqual(w.filename, __file__) + with self.assertWarns(DeprecationWarning) as w: + result = re.subn("b*", "x", "xyz", re.I) + self.assertEqual(result, re.subn("b*", "x", "xyz", count=int(re.I))) + self.assertEqual(str(w.warning), + "'count' is passed as positional argument") + self.assertEqual(w.filename, __file__) + with self.assertWarns(DeprecationWarning) as w: + result = re.split(":", ":a:b::c", re.I) + self.assertEqual(result, re.split(":", ":a:b::c", maxsplit=int(re.I))) + self.assertEqual(str(w.warning), + "'maxsplit' is passed as positional argument") + self.assertEqual(w.filename, __file__) + def test_bug_114660(self): self.assertEqual(re.sub(r'(\S)\s+(\S)', r'\1 \2', 'hello there'), 'hello there') @@ -344,9 +379,22 @@ def test_re_subn(self): self.assertEqual(re.subn("b+", "x", "bbbb BBBB"), ('x BBBB', 1)) self.assertEqual(re.subn("b+", "x", "xyz"), ('xyz', 0)) self.assertEqual(re.subn("b*", "x", "xyz"), ('xxxyxzx', 4)) - self.assertEqual(re.subn("b*", "x", "xyz", 2), ('xxxyz', 2)) + with self.assertWarns(DeprecationWarning) as w: + self.assertEqual(re.subn("b*", "x", "xyz", 2), ('xxxyz', 2)) + self.assertEqual(w.filename, __file__) self.assertEqual(re.subn("b*", "x", "xyz", count=2), ('xxxyz', 2)) + with self.assertRaisesRegex(TypeError, + r"subn\(\) got multiple values for argument 'count'"): + re.subn('a', 'b', 'aaaaa', 1, count=1) + with self.assertRaisesRegex(TypeError, + r"subn\(\) got multiple values for argument 'flags'"): + re.subn('a', 'b', 'aaaaa', 1, 0, flags=0) + with self.assertRaisesRegex(TypeError, + r"subn\(\) takes from 3 to 5 positional arguments but 6 " + r"were given"): + re.subn('a', 'b', 'aaaaa', 1, 0, 0) + def test_re_split(self): for string in ":a:b::c", S(":a:b::c"): self.assertTypedEqual(re.split(":", string), @@ -401,7 +449,9 @@ def test_re_split(self): self.assertTypedEqual(re.split(sep, ':a:b::c'), expected) def test_qualified_re_split(self): - self.assertEqual(re.split(":", ":a:b::c", 2), ['', 'a', 'b::c']) + with self.assertWarns(DeprecationWarning) as w: + self.assertEqual(re.split(":", ":a:b::c", 2), ['', 'a', 'b::c']) + self.assertEqual(w.filename, __file__) self.assertEqual(re.split(":", ":a:b::c", maxsplit=2), ['', 'a', 'b::c']) self.assertEqual(re.split(':', 'a:b:c:d', maxsplit=2), ['a', 'b', 'c:d']) self.assertEqual(re.split("(:)", ":a:b::c", maxsplit=2), @@ -411,6 +461,17 @@ def test_qualified_re_split(self): self.assertEqual(re.split("(:*)", ":a:b::c", maxsplit=2), ['', ':', '', '', 'a:b::c']) + with self.assertRaisesRegex(TypeError, + r"split\(\) got multiple values for argument 'maxsplit'"): + re.split(":", ":a:b::c", 2, maxsplit=2) + with self.assertRaisesRegex(TypeError, + r"split\(\) got multiple values for argument 'flags'"): + re.split(":", ":a:b::c", 2, 0, flags=0) + with self.assertRaisesRegex(TypeError, + r"split\(\) takes from 2 to 4 positional arguments but 5 " + r"were given"): + re.split(":", ":a:b::c", 2, 0, 0) + def test_re_findall(self): self.assertEqual(re.findall(":+", "abc"), []) for string in "a:b::c:::d", S("a:b::c:::d"): @@ -2342,6 +2403,26 @@ def test_bug_gh91616(self): self.assertTrue(re.fullmatch(r'(?s:(?>.*?\.).*)\Z', "a.txt")) # reproducer self.assertTrue(re.fullmatch(r'(?s:(?=(?P.*?\.))(?P=g0).*)\Z', "a.txt")) + def test_bug_gh100061(self): + # gh-100061 + self.assertEqual(re.match('(?>(?:.(?!D))+)', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?:.(?!D))++', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?>(?:.(?!D))*)', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?:.(?!D))*+', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?>(?:.(?!D))?)', 'CDE').span(), (0, 0)) + self.assertEqual(re.match('(?:.(?!D))?+', 'CDE').span(), (0, 0)) + self.assertEqual(re.match('(?>(?:.(?!D)){1,3})', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?:.(?!D)){1,3}+', 'ABCDE').span(), (0, 2)) + # gh-106052 + self.assertEqual(re.match("(?>(?:ab?c)+)", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?:ab?c)++", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?>(?:ab?c)*)", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?:ab?c)*+", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?>(?:ab?c)?)", "a").span(), (0, 0)) + self.assertEqual(re.match("(?:ab?c)?+", "a").span(), (0, 0)) + self.assertEqual(re.match("(?>(?:ab?c){1,3})", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?:ab?c){1,3}+", "aca").span(), (0, 2)) + @unittest.skipIf(multiprocessing is None, 'test requires multiprocessing') def test_regression_gh94675(self): pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*' @@ -2362,6 +2443,9 @@ def test_regression_gh94675(self): p.terminate() p.join() + def test_fail(self): + self.assertEqual(re.search(r'12(?!)|3', '123')[0], '3') + def get_debug_out(pat): with captured_stdout() as out: @@ -2651,6 +2735,9 @@ def test_dealloc(self): _sre.compile("abc", 0, [long_overflow], 0, {}, ()) with self.assertRaises(TypeError): _sre.compile({}, 0, [], 0, [], []) + # gh-110590: `TypeError` was overwritten with `OverflowError`: + with self.assertRaises(TypeError): + _sre.compile('', 0, ['abc'], 0, {}, ()) @cpython_only def test_repeat_minmax_overflow_maxrepeat(self): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 806b932a164df8..cfe8b579703cb6 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -5,22 +5,29 @@ """ import contextlib +import dataclasses import glob import io import locale import os.path import platform +import random import re +import shlex +import signal import subprocess import sys import sysconfig import tempfile import textwrap import unittest -from test import libregrtest from test import support -from test.support import os_helper -from test.libregrtest import utils, setup +from test.support import os_helper, TestStats, without_optimizer +from test.libregrtest import cmdline +from test.libregrtest import main +from test.libregrtest import setup +from test.libregrtest import utils +from test.libregrtest.utils import normalize_test_name if not support.has_subprocess_support: raise unittest.SkipTest("test module requires subprocess") @@ -32,6 +39,7 @@ EXITCODE_BAD_TEST = 2 EXITCODE_ENV_CHANGED = 3 EXITCODE_NO_TESTS_RAN = 4 +EXITCODE_RERUN_FAIL = 5 EXITCODE_INTERRUPTED = 130 TEST_INTERRUPTED = textwrap.dedent(""" @@ -49,9 +57,13 @@ class ParseArgsTestCase(unittest.TestCase): Test regrtest's argument parsing, function _parse_args(). """ + @staticmethod + def parse_args(args): + return cmdline._parse_args(args) + def checkError(self, args, msg): with support.captured_stderr() as err, self.assertRaises(SystemExit): - libregrtest._parse_args(args) + self.parse_args(args) self.assertIn(msg, err.getvalue()) def test_help(self): @@ -59,83 +71,93 @@ def test_help(self): with self.subTest(opt=opt): with support.captured_stdout() as out, \ self.assertRaises(SystemExit): - libregrtest._parse_args([opt]) + self.parse_args([opt]) self.assertIn('Run Python regression tests.', out.getvalue()) def test_timeout(self): - ns = libregrtest._parse_args(['--timeout', '4.2']) + ns = self.parse_args(['--timeout', '4.2']) self.assertEqual(ns.timeout, 4.2) + + # negative, zero and empty string are treated as "no timeout" + for value in ('-1', '0', ''): + with self.subTest(value=value): + ns = self.parse_args([f'--timeout={value}']) + self.assertEqual(ns.timeout, None) + self.checkError(['--timeout'], 'expected one argument') - self.checkError(['--timeout', 'foo'], 'invalid float value') + self.checkError(['--timeout', 'foo'], 'invalid timeout value:') def test_wait(self): - ns = libregrtest._parse_args(['--wait']) + ns = self.parse_args(['--wait']) self.assertTrue(ns.wait) - def test_worker_args(self): - ns = libregrtest._parse_args(['--worker-args', '[[], {}]']) - self.assertEqual(ns.worker_args, '[[], {}]') - self.checkError(['--worker-args'], 'expected one argument') - def test_start(self): for opt in '-S', '--start': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, 'foo']) + ns = self.parse_args([opt, 'foo']) self.assertEqual(ns.start, 'foo') self.checkError([opt], 'expected one argument') def test_verbose(self): - ns = libregrtest._parse_args(['-v']) + ns = self.parse_args(['-v']) self.assertEqual(ns.verbose, 1) - ns = libregrtest._parse_args(['-vvv']) + ns = self.parse_args(['-vvv']) self.assertEqual(ns.verbose, 3) - ns = libregrtest._parse_args(['--verbose']) + ns = self.parse_args(['--verbose']) self.assertEqual(ns.verbose, 1) - ns = libregrtest._parse_args(['--verbose'] * 3) + ns = self.parse_args(['--verbose'] * 3) self.assertEqual(ns.verbose, 3) - ns = libregrtest._parse_args([]) + ns = self.parse_args([]) self.assertEqual(ns.verbose, 0) - def test_verbose2(self): - for opt in '-w', '--verbose2': + def test_rerun(self): + for opt in '-w', '--rerun', '--verbose2': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) - self.assertTrue(ns.verbose2) + ns = self.parse_args([opt]) + self.assertTrue(ns.rerun) def test_verbose3(self): for opt in '-W', '--verbose3': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.verbose3) def test_quiet(self): for opt in '-q', '--quiet': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.quiet) self.assertEqual(ns.verbose, 0) def test_slowest(self): for opt in '-o', '--slowest': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.print_slow) def test_header(self): - ns = libregrtest._parse_args(['--header']) + ns = self.parse_args(['--header']) self.assertTrue(ns.header) - ns = libregrtest._parse_args(['--verbose']) + ns = self.parse_args(['--verbose']) self.assertTrue(ns.header) def test_randomize(self): for opt in '-r', '--randomize': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.randomize) + with os_helper.EnvironmentVarGuard() as env: + env['SOURCE_DATE_EPOCH'] = '1' + + ns = self.parse_args(['--randomize']) + regrtest = main.Regrtest(ns) + self.assertFalse(regrtest.randomize) + self.assertIsNone(regrtest.random_seed) + def test_randseed(self): - ns = libregrtest._parse_args(['--randseed', '12345']) + ns = self.parse_args(['--randseed', '12345']) self.assertEqual(ns.random_seed, 12345) self.assertTrue(ns.randomize) self.checkError(['--randseed'], 'expected one argument') @@ -144,7 +166,7 @@ def test_randseed(self): def test_fromfile(self): for opt in '-f', '--fromfile': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, 'foo']) + ns = self.parse_args([opt, 'foo']) self.assertEqual(ns.fromfile, 'foo') self.checkError([opt], 'expected one argument') self.checkError([opt, 'foo', '-s'], "don't go together") @@ -152,20 +174,20 @@ def test_fromfile(self): def test_exclude(self): for opt in '-x', '--exclude': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.exclude) def test_single(self): for opt in '-s', '--single': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.single) self.checkError([opt, '-f', 'foo'], "don't go together") def test_ignore(self): for opt in '-i', '--ignore': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, 'pattern']) + ns = self.parse_args([opt, 'pattern']) self.assertEqual(ns.ignore_tests, ['pattern']) self.checkError([opt], 'expected one argument') @@ -175,7 +197,7 @@ def test_ignore(self): print('matchfile2', file=fp) filename = os.path.abspath(os_helper.TESTFN) - ns = libregrtest._parse_args(['-m', 'match', + ns = self.parse_args(['-m', 'match', '--ignorefile', filename]) self.assertEqual(ns.ignore_tests, ['matchfile1', 'matchfile2']) @@ -183,11 +205,11 @@ def test_ignore(self): def test_match(self): for opt in '-m', '--match': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, 'pattern']) + ns = self.parse_args([opt, 'pattern']) self.assertEqual(ns.match_tests, ['pattern']) self.checkError([opt], 'expected one argument') - ns = libregrtest._parse_args(['-m', 'pattern1', + ns = self.parse_args(['-m', 'pattern1', '-m', 'pattern2']) self.assertEqual(ns.match_tests, ['pattern1', 'pattern2']) @@ -197,7 +219,7 @@ def test_match(self): print('matchfile2', file=fp) filename = os.path.abspath(os_helper.TESTFN) - ns = libregrtest._parse_args(['-m', 'match', + ns = self.parse_args(['-m', 'match', '--matchfile', filename]) self.assertEqual(ns.match_tests, ['match', 'matchfile1', 'matchfile2']) @@ -205,65 +227,65 @@ def test_match(self): def test_failfast(self): for opt in '-G', '--failfast': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, '-v']) + ns = self.parse_args([opt, '-v']) self.assertTrue(ns.failfast) - ns = libregrtest._parse_args([opt, '-W']) + ns = self.parse_args([opt, '-W']) self.assertTrue(ns.failfast) self.checkError([opt], '-G/--failfast needs either -v or -W') def test_use(self): for opt in '-u', '--use': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, 'gui,network']) + ns = self.parse_args([opt, 'gui,network']) self.assertEqual(ns.use_resources, ['gui', 'network']) - ns = libregrtest._parse_args([opt, 'gui,none,network']) + ns = self.parse_args([opt, 'gui,none,network']) self.assertEqual(ns.use_resources, ['network']) - expected = list(libregrtest.ALL_RESOURCES) + expected = list(cmdline.ALL_RESOURCES) expected.remove('gui') - ns = libregrtest._parse_args([opt, 'all,-gui']) + ns = self.parse_args([opt, 'all,-gui']) self.assertEqual(ns.use_resources, expected) self.checkError([opt], 'expected one argument') self.checkError([opt, 'foo'], 'invalid resource') # all + a resource not part of "all" - ns = libregrtest._parse_args([opt, 'all,tzdata']) + ns = self.parse_args([opt, 'all,tzdata']) self.assertEqual(ns.use_resources, - list(libregrtest.ALL_RESOURCES) + ['tzdata']) + list(cmdline.ALL_RESOURCES) + ['tzdata']) # test another resource which is not part of "all" - ns = libregrtest._parse_args([opt, 'extralargefile']) + ns = self.parse_args([opt, 'extralargefile']) self.assertEqual(ns.use_resources, ['extralargefile']) def test_memlimit(self): for opt in '-M', '--memlimit': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, '4G']) + ns = self.parse_args([opt, '4G']) self.assertEqual(ns.memlimit, '4G') self.checkError([opt], 'expected one argument') def test_testdir(self): - ns = libregrtest._parse_args(['--testdir', 'foo']) + ns = self.parse_args(['--testdir', 'foo']) self.assertEqual(ns.testdir, os.path.join(os_helper.SAVEDCWD, 'foo')) self.checkError(['--testdir'], 'expected one argument') def test_runleaks(self): for opt in '-L', '--runleaks': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.runleaks) def test_huntrleaks(self): for opt in '-R', '--huntrleaks': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, ':']) + ns = self.parse_args([opt, ':']) self.assertEqual(ns.huntrleaks, (5, 4, 'reflog.txt')) - ns = libregrtest._parse_args([opt, '6:']) + ns = self.parse_args([opt, '6:']) self.assertEqual(ns.huntrleaks, (6, 4, 'reflog.txt')) - ns = libregrtest._parse_args([opt, ':3']) + ns = self.parse_args([opt, ':3']) self.assertEqual(ns.huntrleaks, (5, 3, 'reflog.txt')) - ns = libregrtest._parse_args([opt, '6:3:leaks.log']) + ns = self.parse_args([opt, '6:3:leaks.log']) self.assertEqual(ns.huntrleaks, (6, 3, 'leaks.log')) self.checkError([opt], 'expected one argument') self.checkError([opt, '6'], @@ -274,7 +296,7 @@ def test_huntrleaks(self): def test_multiprocess(self): for opt in '-j', '--multiprocess': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, '2']) + ns = self.parse_args([opt, '2']) self.assertEqual(ns.use_mp, 2) self.checkError([opt], 'expected one argument') self.checkError([opt, 'foo'], 'invalid int value') @@ -284,13 +306,13 @@ def test_multiprocess(self): def test_coverage(self): for opt in '-T', '--coverage': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.trace) def test_coverdir(self): for opt in '-D', '--coverdir': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, 'foo']) + ns = self.parse_args([opt, 'foo']) self.assertEqual(ns.coverdir, os.path.join(os_helper.SAVEDCWD, 'foo')) self.checkError([opt], 'expected one argument') @@ -298,13 +320,13 @@ def test_coverdir(self): def test_nocoverdir(self): for opt in '-N', '--nocoverdir': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertIsNone(ns.coverdir) def test_threshold(self): for opt in '-t', '--threshold': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt, '1000']) + ns = self.parse_args([opt, '1000']) self.assertEqual(ns.threshold, 1000) self.checkError([opt], 'expected one argument') self.checkError([opt, 'foo'], 'invalid int value') @@ -313,7 +335,7 @@ def test_nowindows(self): for opt in '-n', '--nowindows': with self.subTest(opt=opt): with contextlib.redirect_stderr(io.StringIO()) as stderr: - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.nowindows) err = stderr.getvalue() self.assertIn('the --nowindows (-n) option is deprecated', err) @@ -321,39 +343,39 @@ def test_nowindows(self): def test_forever(self): for opt in '-F', '--forever': with self.subTest(opt=opt): - ns = libregrtest._parse_args([opt]) + ns = self.parse_args([opt]) self.assertTrue(ns.forever) def test_unrecognized_argument(self): self.checkError(['--xxx'], 'usage:') def test_long_option__partial(self): - ns = libregrtest._parse_args(['--qui']) + ns = self.parse_args(['--qui']) self.assertTrue(ns.quiet) self.assertEqual(ns.verbose, 0) def test_two_options(self): - ns = libregrtest._parse_args(['--quiet', '--exclude']) + ns = self.parse_args(['--quiet', '--exclude']) self.assertTrue(ns.quiet) self.assertEqual(ns.verbose, 0) self.assertTrue(ns.exclude) def test_option_with_empty_string_value(self): - ns = libregrtest._parse_args(['--start', '']) + ns = self.parse_args(['--start', '']) self.assertEqual(ns.start, '') def test_arg(self): - ns = libregrtest._parse_args(['foo']) + ns = self.parse_args(['foo']) self.assertEqual(ns.args, ['foo']) def test_option_and_arg(self): - ns = libregrtest._parse_args(['--quiet', 'foo']) + ns = self.parse_args(['--quiet', 'foo']) self.assertTrue(ns.quiet) self.assertEqual(ns.verbose, 0) self.assertEqual(ns.args, ['foo']) def test_arg_option_arg(self): - ns = libregrtest._parse_args(['test_unaryop', '-v', 'test_binop']) + ns = self.parse_args(['test_unaryop', '-v', 'test_binop']) self.assertEqual(ns.verbose, 1) self.assertEqual(ns.args, ['test_unaryop', 'test_binop']) @@ -361,6 +383,62 @@ def test_unknown_option(self): self.checkError(['--unknown-option'], 'unrecognized arguments: --unknown-option') + def check_ci_mode(self, args, use_resources, rerun=True): + ns = cmdline._parse_args(args) + + # Check Regrtest attributes which are more reliable than Namespace + # which has an unclear API + regrtest = main.Regrtest(ns) + self.assertEqual(regrtest.num_workers, -1) + self.assertEqual(regrtest.want_rerun, rerun) + self.assertTrue(regrtest.randomize) + self.assertIsInstance(regrtest.random_seed, int) + self.assertTrue(regrtest.fail_env_changed) + self.assertTrue(regrtest.fail_rerun) + self.assertTrue(regrtest.print_slowest) + self.assertTrue(regrtest.output_on_failure) + self.assertEqual(sorted(regrtest.use_resources), sorted(use_resources)) + return regrtest + + def test_fast_ci(self): + args = ['--fast-ci'] + use_resources = sorted(cmdline.ALL_RESOURCES) + use_resources.remove('cpu') + regrtest = self.check_ci_mode(args, use_resources) + self.assertEqual(regrtest.timeout, 10 * 60) + + def test_fast_ci_python_cmd(self): + args = ['--fast-ci', '--python', 'python -X dev'] + use_resources = sorted(cmdline.ALL_RESOURCES) + use_resources.remove('cpu') + regrtest = self.check_ci_mode(args, use_resources, rerun=False) + self.assertEqual(regrtest.timeout, 10 * 60) + self.assertEqual(regrtest.python_cmd, ('python', '-X', 'dev')) + + def test_fast_ci_resource(self): + # it should be possible to override resources + args = ['--fast-ci', '-u', 'network'] + use_resources = ['network'] + self.check_ci_mode(args, use_resources) + + def test_slow_ci(self): + args = ['--slow-ci'] + use_resources = sorted(cmdline.ALL_RESOURCES) + regrtest = self.check_ci_mode(args, use_resources) + self.assertEqual(regrtest.timeout, 20 * 60) + + def test_dont_add_python_opts(self): + args = ['--dont-add-python-opts'] + ns = cmdline._parse_args(args) + self.assertFalse(ns._add_python_opts) + + +@dataclasses.dataclass(slots=True) +class Rerun: + name: str + match: str | None + success: bool + class BaseTestCase(unittest.TestCase): TEST_UNIQUE_ID = 1 @@ -409,8 +487,12 @@ def regex_search(self, regex, output): self.fail("%r not found in %r" % (regex, output)) return match - def check_line(self, output, regex): - regex = re.compile(r'^' + regex, re.MULTILINE) + def check_line(self, output, pattern, full=False, regex=True): + if not regex: + pattern = re.escape(pattern) + if full: + pattern += '\n' + regex = re.compile(r'^' + pattern, re.MULTILINE) self.assertRegex(output, regex) def parse_executed_tests(self, output): @@ -419,29 +501,47 @@ def parse_executed_tests(self, output): parser = re.finditer(regex, output, re.MULTILINE) return list(match.group(1) for match in parser) - def check_executed_tests(self, output, tests, skipped=(), failed=(), + def check_executed_tests(self, output, tests, *, stats, + skipped=(), failed=(), env_changed=(), omitted=(), - rerun={}, no_test_ran=(), - randomize=False, interrupted=False, - fail_env_changed=False): + rerun=None, run_no_tests=(), + resource_denied=(), + randomize=False, parallel=False, interrupted=False, + fail_env_changed=False, + forever=False, filtered=False): if isinstance(tests, str): tests = [tests] if isinstance(skipped, str): skipped = [skipped] + if isinstance(resource_denied, str): + resource_denied = [resource_denied] if isinstance(failed, str): failed = [failed] if isinstance(env_changed, str): env_changed = [env_changed] if isinstance(omitted, str): omitted = [omitted] - if isinstance(no_test_ran, str): - no_test_ran = [no_test_ran] + if isinstance(run_no_tests, str): + run_no_tests = [run_no_tests] + if isinstance(stats, int): + stats = TestStats(stats) + if parallel: + randomize = True + + rerun_failed = [] + if rerun is not None and not env_changed: + failed = [rerun.name] + if not rerun.success: + rerun_failed.append(rerun.name) executed = self.parse_executed_tests(output) + total_tests = list(tests) + if rerun is not None: + total_tests.append(rerun.name) if randomize: - self.assertEqual(set(executed), set(tests), output) + self.assertEqual(set(executed), set(total_tests), output) else: - self.assertEqual(executed, tests, output) + self.assertEqual(executed, total_tests, output) def plural(count): return 's' if count != 1 else '' @@ -457,12 +557,17 @@ def list_regex(line_format, tests): regex = list_regex('%s test%s skipped', skipped) self.check_line(output, regex) + if resource_denied: + regex = list_regex(r'%s test%s skipped \(resource denied\)', resource_denied) + self.check_line(output, regex) + if failed: regex = list_regex('%s test%s failed', failed) self.check_line(output, regex) if env_changed: - regex = list_regex('%s test%s altered the execution environment', + regex = list_regex(r'%s test%s altered the execution environment ' + r'\(env changed\)', env_changed) self.check_line(output, regex) @@ -470,53 +575,95 @@ def list_regex(line_format, tests): regex = list_regex('%s test%s omitted', omitted) self.check_line(output, regex) - if rerun: - regex = list_regex('%s re-run test%s', rerun.keys()) + if rerun is not None: + regex = list_regex('%s re-run test%s', [rerun.name]) self.check_line(output, regex) - regex = LOG_PREFIX + r"Re-running failed tests in verbose mode" + regex = LOG_PREFIX + r"Re-running 1 failed tests in verbose mode" + self.check_line(output, regex) + regex = fr"Re-running {rerun.name} in verbose mode" + if rerun.match: + regex = fr"{regex} \(matching: {rerun.match}\)" self.check_line(output, regex) - for name, match in rerun.items(): - regex = LOG_PREFIX + f"Re-running {name} in verbose mode \\(matching: {match}\\)" - self.check_line(output, regex) - if no_test_ran: - regex = list_regex('%s test%s run no tests', no_test_ran) + if run_no_tests: + regex = list_regex('%s test%s run no tests', run_no_tests) self.check_line(output, regex) - good = (len(tests) - len(skipped) - len(failed) - - len(omitted) - len(env_changed) - len(no_test_ran)) + good = (len(tests) - len(skipped) - len(resource_denied) - len(failed) + - len(omitted) - len(env_changed) - len(run_no_tests)) if good: - regex = r'%s test%s OK\.$' % (good, plural(good)) - if not skipped and not failed and good > 1: + regex = r'%s test%s OK\.' % (good, plural(good)) + if not skipped and not failed and (rerun is None or rerun.success) and good > 1: regex = 'All %s' % regex - self.check_line(output, regex) + self.check_line(output, regex, full=True) if interrupted: self.check_line(output, 'Test suite interrupted by signal SIGINT.') - result = [] + # Total tests + text = f'run={stats.tests_run:,}' + if filtered: + text = fr'{text} \(filtered\)' + parts = [text] + if stats.failures: + parts.append(f'failures={stats.failures:,}') + if stats.skipped: + parts.append(f'skipped={stats.skipped:,}') + line = fr'Total tests: {" ".join(parts)}' + self.check_line(output, line, full=True) + + # Total test files + run = len(total_tests) - len(resource_denied) + if rerun is not None: + total_failed = len(rerun_failed) + total_rerun = 1 + else: + total_failed = len(failed) + total_rerun = 0 + if interrupted: + run = 0 + text = f'run={run}' + if not forever: + text = f'{text}/{len(tests)}' + if filtered: + text = fr'{text} \(filtered\)' + report = [text] + for name, ntest in ( + ('failed', total_failed), + ('env_changed', len(env_changed)), + ('skipped', len(skipped)), + ('resource_denied', len(resource_denied)), + ('rerun', total_rerun), + ('run_no_tests', len(run_no_tests)), + ): + if ntest: + report.append(f'{name}={ntest}') + line = fr'Total test files: {" ".join(report)}' + self.check_line(output, line, full=True) + + # Result + state = [] if failed: - result.append('FAILURE') + state.append('FAILURE') elif fail_env_changed and env_changed: - result.append('ENV CHANGED') + state.append('ENV CHANGED') if interrupted: - result.append('INTERRUPTED') - if not any((good, result, failed, interrupted, skipped, + state.append('INTERRUPTED') + if not any((good, failed, interrupted, skipped, env_changed, fail_env_changed)): - result.append("NO TESTS RAN") - elif not result: - result.append('SUCCESS') - result = ', '.join(result) - if rerun: - self.check_line(output, 'Tests result: FAILURE') - result = 'FAILURE then %s' % result - - self.check_line(output, 'Tests result: %s' % result) + state.append("NO TESTS RAN") + elif not state: + state.append('SUCCESS') + state = ', '.join(state) + if rerun is not None: + new_state = 'SUCCESS' if rerun.success else 'FAILURE' + state = f'{state} then {new_state}' + self.check_line(output, f'Result: {state}', full=True) def parse_random_seed(self, output): match = self.regex_search(r'Using random seed ([0-9]+)', output) randseed = int(match.group(1)) - self.assertTrue(0 <= randseed <= 10000000, randseed) + self.assertTrue(0 <= randseed, randseed) return randseed def run_command(self, args, input=None, exitcode=0, **kw): @@ -525,18 +672,18 @@ def run_command(self, args, input=None, exitcode=0, **kw): if 'stderr' not in kw: kw['stderr'] = subprocess.STDOUT proc = subprocess.run(args, - universal_newlines=True, + text=True, input=input, stdout=subprocess.PIPE, **kw) if proc.returncode != exitcode: - msg = ("Command %s failed with exit code %s\n" + msg = ("Command %s failed with exit code %s, but exit code %s expected!\n" "\n" "stdout:\n" "---\n" "%s\n" "---\n" - % (str(args), proc.returncode, proc.stdout)) + % (str(args), proc.returncode, exitcode, proc.stdout)) if proc.stderr: msg += ("\n" "stderr:\n" @@ -548,7 +695,11 @@ def run_command(self, args, input=None, exitcode=0, **kw): return proc def run_python(self, args, **kw): - args = [sys.executable, '-X', 'faulthandler', '-I', *args] + extraargs = [] + if 'uops' in sys._xoptions: + # Pass -X uops along + extraargs.extend(['-X', 'uops']) + args = [sys.executable, *extraargs, '-X', 'faulthandler', '-I', *args] proc = self.run_command(args, **kw) return proc.stdout @@ -600,10 +751,11 @@ def setUp(self): def check_output(self, output): self.parse_random_seed(output) - self.check_executed_tests(output, self.tests, randomize=True) + self.check_executed_tests(output, self.tests, + randomize=True, stats=len(self.tests)) - def run_tests(self, args): - output = self.run_python(args) + def run_tests(self, args, env=None): + output = self.run_python(args, env=env) self.check_output(output) def test_script_regrtest(self): @@ -644,14 +796,6 @@ def test_script_autotest(self): args = [*self.python_args, script, *self.regrtest_args, *self.tests] self.run_tests(args) - @unittest.skipUnless(sysconfig.is_python_build(), - 'run_tests.py script is not installed') - def test_tools_script_run_tests(self): - # Tools/scripts/run_tests.py - script = os.path.join(ROOT_DIR, 'Tools', 'scripts', 'run_tests.py') - args = [script, *self.regrtest_args, *self.tests] - self.run_tests(args) - def run_batch(self, *args): proc = self.run_command(args) self.check_output(proc.stdout) @@ -700,6 +844,40 @@ def run_tests(self, *testargs, **kw): cmdargs = ['-m', 'test', '--testdir=%s' % self.tmptestdir, *testargs] return self.run_python(cmdargs, **kw) + def test_success(self): + code = textwrap.dedent(""" + import unittest + + class PassingTests(unittest.TestCase): + def test_test1(self): + pass + + def test_test2(self): + pass + + def test_test3(self): + pass + """) + tests = [self.create_test(f'ok{i}', code=code) for i in range(1, 6)] + + output = self.run_tests(*tests) + self.check_executed_tests(output, tests, + stats=3 * len(tests)) + + def test_skip(self): + code = textwrap.dedent(""" + import unittest + raise unittest.SkipTest("nope") + """) + test_ok = self.create_test('ok') + test_skip = self.create_test('skip', code=code) + tests = [test_ok, test_skip] + + output = self.run_tests(*tests) + self.check_executed_tests(output, tests, + skipped=[test_skip], + stats=1) + def test_failing_test(self): # test a failing test code = textwrap.dedent(""" @@ -714,7 +892,8 @@ def test_failing(self): tests = [test_ok, test_failing] output = self.run_tests(*tests, exitcode=EXITCODE_BAD_TEST) - self.check_executed_tests(output, tests, failed=test_failing) + self.check_executed_tests(output, tests, failed=test_failing, + stats=TestStats(2, 1)) def test_resources(self): # test -u command line option @@ -733,17 +912,19 @@ def test_pass(self): # -u all: 2 resources enabled output = self.run_tests('-u', 'all', *test_names) - self.check_executed_tests(output, test_names) + self.check_executed_tests(output, test_names, stats=2) # -u audio: 1 resource enabled output = self.run_tests('-uaudio', *test_names) self.check_executed_tests(output, test_names, - skipped=tests['network']) + resource_denied=tests['network'], + stats=1) # no option: 0 resources enabled - output = self.run_tests(*test_names) + output = self.run_tests(*test_names, exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, test_names, - skipped=test_names) + resource_denied=test_names, + stats=0) def test_random(self): # test -r and --randseed command line option @@ -769,6 +950,10 @@ def test_random(self): test_random2 = int(match.group(1)) self.assertEqual(test_random2, test_random) + # check that random.seed is used by default + output = self.run_tests(test, exitcode=EXITCODE_NO_TESTS_RAN) + self.assertIsInstance(self.parse_random_seed(output), int) + def test_fromfile(self): # test --fromfile tests = [self.create_test() for index in range(5)] @@ -791,7 +976,8 @@ def test_fromfile(self): previous = name output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + stats = len(tests) + self.check_executed_tests(output, tests, stats=stats) # test format '[2/7] test_opcodes' with open(filename, "w") as fp: @@ -799,7 +985,7 @@ def test_fromfile(self): print("[%s/%s] %s" % (index, len(tests), name), file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'test_opcodes' with open(filename, "w") as fp: @@ -807,7 +993,7 @@ def test_fromfile(self): print(name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'Lib/test/test_opcodes.py' with open(filename, "w") as fp: @@ -815,20 +1001,20 @@ def test_fromfile(self): print('Lib/test/%s.py' % name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) def test_interrupted(self): code = TEST_INTERRUPTED test = self.create_test('sigint', code=code) output = self.run_tests(test, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, omitted=test, - interrupted=True) + interrupted=True, stats=0) def test_slowest(self): # test --slowest tests = [self.create_test() for index in range(3)] output = self.run_tests("--slowest", *tests) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=len(tests)) regex = ('10 slowest tests:\n' '(?:- %s: .*\n){%s}' % (self.TESTNAME_REGEX, len(tests))) @@ -847,7 +1033,8 @@ def test_slowest_interrupted(self): args = ("--slowest", test) output = self.run_tests(*args, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, - omitted=test, interrupted=True) + omitted=test, interrupted=True, + stats=0) regex = ('10 slowest tests:\n') self.check_line(output, regex) @@ -856,7 +1043,7 @@ def test_coverage(self): # test --coverage test = self.create_test('coverage') output = self.run_tests("--coverage", test) - self.check_executed_tests(output, [test]) + self.check_executed_tests(output, [test], stats=1) regex = (r'lines +cov% +module +\(path\)\n' r'(?: *[0-9]+ *[0-9]{1,2}% *[^ ]+ +\([^)]+\)+)+') self.check_line(output, regex) @@ -885,18 +1072,36 @@ def test_run(self): builtins.__dict__['RUN'] = 1 """) test = self.create_test('forever', code=code) - output = self.run_tests('--forever', test, exitcode=EXITCODE_BAD_TEST) - self.check_executed_tests(output, [test]*3, failed=test) - def check_leak(self, code, what): + # --forever + output = self.run_tests('--forever', test, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [test]*3, failed=test, + stats=TestStats(3, 1), + forever=True) + + # --forever --rerun + output = self.run_tests('--forever', '--rerun', test, exitcode=0) + self.check_executed_tests(output, [test]*3, + rerun=Rerun(test, + match='test_run', + success=True), + stats=TestStats(4, 1), + forever=True) + + @without_optimizer + def check_leak(self, code, what, *, run_workers=False): test = self.create_test('huntrleaks', code=code) filename = 'reflog.txt' self.addCleanup(os_helper.unlink, filename) - output = self.run_tests('--huntrleaks', '3:3:', test, + cmd = ['--huntrleaks', '3:3:'] + if run_workers: + cmd.append('-j1') + cmd.append(test) + output = self.run_tests(*cmd, exitcode=EXITCODE_BAD_TEST, stderr=subprocess.STDOUT) - self.check_executed_tests(output, [test], failed=test) + self.check_executed_tests(output, [test], failed=test, stats=1) line = 'beginning 6 repetitions\n123456\n......\n' self.check_line(output, re.escape(line)) @@ -909,7 +1114,7 @@ def check_leak(self, code, what): self.assertIn(line2, reflog) @unittest.skipUnless(support.Py_DEBUG, 'need a debug build') - def test_huntrleaks(self): + def check_huntrleaks(self, *, run_workers: bool): # test --huntrleaks code = textwrap.dedent(""" import unittest @@ -920,7 +1125,13 @@ class RefLeakTest(unittest.TestCase): def test_leak(self): GLOBAL_LIST.append(object()) """) - self.check_leak(code, 'references') + self.check_leak(code, 'references', run_workers=run_workers) + + def test_huntrleaks(self): + self.check_huntrleaks(run_workers=False) + + def test_huntrleaks_mp(self): + self.check_huntrleaks(run_workers=True) @unittest.skipUnless(support.Py_DEBUG, 'need a debug build') def test_huntrleaks_fd_leak(self): @@ -978,7 +1189,7 @@ def test_crashed(self): tests = [crash_test] output = self.run_tests("-j2", *tests, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, tests, failed=crash_test, - randomize=True) + parallel=True, stats=0) def parse_methods(self, output): regex = re.compile("^(test[^ ]+).*ok$", flags=re.MULTILINE) @@ -998,8 +1209,6 @@ def test_method3(self): def test_method4(self): pass """) - all_methods = ['test_method1', 'test_method2', - 'test_method3', 'test_method4'] testname = self.create_test(code=code) # only run a subset @@ -1073,13 +1282,23 @@ def test_env_changed(self): # don't fail by default output = self.run_tests(testname) - self.check_executed_tests(output, [testname], env_changed=testname) + self.check_executed_tests(output, [testname], + env_changed=testname, stats=1) # fail with --fail-env-changed output = self.run_tests("--fail-env-changed", testname, exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=testname, - fail_env_changed=True) + fail_env_changed=True, stats=1) + + # rerun + output = self.run_tests("--rerun", testname) + self.check_executed_tests(output, [testname], + env_changed=testname, + rerun=Rerun(testname, + match=None, + success=True), + stats=2) def test_rerun_fail(self): # FAILURE then FAILURE @@ -1096,30 +1315,55 @@ def test_fail_always(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname, rerun={testname: "test_fail_always"}) + rerun=Rerun(testname, + "test_fail_always", + success=False), + stats=TestStats(3, 2)) def test_rerun_success(self): # FAILURE then SUCCESS - code = textwrap.dedent(""" - import builtins + marker_filename = os.path.abspath("regrtest_marker_filename") + self.addCleanup(os_helper.unlink, marker_filename) + self.assertFalse(os.path.exists(marker_filename)) + + code = textwrap.dedent(f""" + import os.path import unittest + marker_filename = {marker_filename!r} + class Tests(unittest.TestCase): def test_succeed(self): return def test_fail_once(self): - if not hasattr(builtins, '_test_failed'): - builtins._test_failed = True + if not os.path.exists(marker_filename): + open(marker_filename, "w").close() self.fail("bug") """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=0) + # FAILURE then SUCCESS => exit code 0 + output = self.run_tests("--rerun", testname, exitcode=0) + self.check_executed_tests(output, [testname], + rerun=Rerun(testname, + match="test_fail_once", + success=True), + stats=TestStats(3, 1)) + os_helper.unlink(marker_filename) + + # with --fail-rerun, exit code EXITCODE_RERUN_FAIL + # on "FAILURE then SUCCESS" state. + output = self.run_tests("--rerun", "--fail-rerun", testname, + exitcode=EXITCODE_RERUN_FAIL) self.check_executed_tests(output, [testname], - rerun={testname: "test_fail_once"}) + rerun=Rerun(testname, + match="test_fail_once", + success=True), + stats=TestStats(3, 1)) + os_helper.unlink(marker_filename) def test_rerun_setup_class_hook_failure(self): # FAILURE then FAILURE @@ -1136,10 +1380,13 @@ def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}) + rerun=Rerun(testname, + match="ExampleTests", + success=False), + stats=0) def test_rerun_teardown_class_hook_failure(self): # FAILURE then FAILURE @@ -1156,10 +1403,13 @@ def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}) + rerun=Rerun(testname, + match="ExampleTests", + success=False), + stats=2) def test_rerun_setup_module_hook_failure(self): # FAILURE then FAILURE @@ -1175,10 +1425,13 @@ def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: testname}) + rerun=Rerun(testname, + match=None, + success=False), + stats=0) def test_rerun_teardown_module_hook_failure(self): # FAILURE then FAILURE @@ -1194,10 +1447,13 @@ def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) - self.check_executed_tests(output, testname, + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [testname], failed=[testname], - rerun={testname: testname}) + rerun=Rerun(testname, + match=None, + success=False), + stats=2) def test_rerun_setup_hook_failure(self): # FAILURE then FAILURE @@ -1213,10 +1469,13 @@ def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_rerun_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1232,10 +1491,13 @@ def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_rerun_async_setup_hook_failure(self): # FAILURE then FAILURE @@ -1251,10 +1513,12 @@ async def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, - failed=[testname], - rerun={testname: "test_success"}) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_rerun_async_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1270,10 +1534,13 @@ async def test_success(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_no_tests_ran(self): code = textwrap.dedent(""" @@ -1287,7 +1554,9 @@ def test_bug(self): output = self.run_tests(testname, "-m", "nosuchtest", exitcode=EXITCODE_NO_TESTS_RAN) - self.check_executed_tests(output, [testname], no_test_ran=testname) + self.check_executed_tests(output, [testname], + run_no_tests=testname, + stats=0, filtered=True) def test_no_tests_ran_skip(self): code = textwrap.dedent(""" @@ -1300,7 +1569,8 @@ def test_skipped(self): testname = self.create_test(code=code) output = self.run_tests(testname) - self.check_executed_tests(output, [testname]) + self.check_executed_tests(output, [testname], + stats=TestStats(1, skipped=1)) def test_no_tests_ran_multiple_tests_nonexistent(self): code = textwrap.dedent(""" @@ -1316,7 +1586,8 @@ def test_bug(self): output = self.run_tests(testname, testname2, "-m", "nosuchtest", exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname, testname2]) + run_no_tests=[testname, testname2], + stats=0, filtered=True) def test_no_test_ran_some_test_exist_some_not(self): code = textwrap.dedent(""" @@ -1339,7 +1610,8 @@ def test_other_bug(self): output = self.run_tests(testname, testname2, "-m", "nosuchtest", "-m", "test_other_bug", exitcode=0) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname]) + run_no_tests=[testname], + stats=1, filtered=True) @support.cpython_only def test_uncollectable(self): @@ -1366,7 +1638,8 @@ def test_garbage(self): exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) def test_multiprocessing_timeout(self): code = textwrap.dedent(r""" @@ -1392,7 +1665,7 @@ def test_sleep(self): output = self.run_tests("-j2", "--timeout=1.0", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname) + failed=testname, stats=0) self.assertRegex(output, re.compile('%s timed out' % testname, re.MULTILINE)) @@ -1426,7 +1699,8 @@ def test_unraisable_exc(self): exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Unraisable exception", output) self.assertIn("Exception: weakref callback bug", output) @@ -1458,7 +1732,8 @@ def test_threading_excepthook(self): exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Uncaught thread exception", output) self.assertIn("Exception: bug in thread", output) @@ -1499,7 +1774,8 @@ def test_print_warning(self): output = self.run_tests(*cmd, exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertRegex(output, regex) def test_unicode_guard_env(self): @@ -1546,15 +1822,15 @@ def test_leak_tmp_file(self): self.check_executed_tests(output, testnames, env_changed=testnames, fail_env_changed=True, - randomize=True) + parallel=True, + stats=len(testnames)) for testname in testnames: self.assertIn(f"Warning -- {testname} leaked temporary " f"files (1): mytmpfile", output) - def test_mp_decode_error(self): - # gh-101634: If a worker stdout cannot be decoded, report a failed test - # and a non-zero exit code. + def test_worker_decode_error(self): + # gh-109425: Use "backslashreplace" error handler to decode stdout. if sys.platform == 'win32': encoding = locale.getencoding() else: @@ -1562,30 +1838,242 @@ def test_mp_decode_error(self): if encoding is None: encoding = sys.__stdout__.encoding if encoding is None: - self.skipTest(f"cannot get regrtest worker encoding") - - nonascii = b"byte:\xa0\xa9\xff\n" + self.skipTest("cannot get regrtest worker encoding") + + nonascii = bytes(ch for ch in range(128, 256)) + corrupted_output = b"nonascii:%s\n" % (nonascii,) + # gh-108989: On Windows, assertion errors are written in UTF-16: when + # decoded each letter is follow by a NUL character. + assertion_failed = 'Assertion failed: tstate_is_alive(tstate)\n' + corrupted_output += assertion_failed.encode('utf-16-le') try: - nonascii.decode(encoding) + corrupted_output.decode(encoding) except UnicodeDecodeError: pass else: - self.skipTest(f"{encoding} can decode non-ASCII bytes {nonascii!a}") + self.skipTest(f"{encoding} can decode non-ASCII bytes") + + expected_line = corrupted_output.decode(encoding, 'backslashreplace') code = textwrap.dedent(fr""" import sys + import unittest + + class Tests(unittest.TestCase): + def test_pass(self): + pass + # bytes which cannot be decoded from UTF-8 - nonascii = {nonascii!a} - sys.stdout.buffer.write(nonascii) + corrupted_output = {corrupted_output!a} + sys.stdout.buffer.write(corrupted_output) sys.stdout.buffer.flush() """) testname = self.create_test(code=code) + output = self.run_tests("--fail-env-changed", "-v", "-j1", testname) + self.check_executed_tests(output, [testname], + parallel=True, + stats=1) + self.check_line(output, expected_line, regex=False) + + def test_doctest(self): + code = textwrap.dedent(r''' + import doctest + import sys + from test import support + + def my_function(): + """ + Pass: + + >>> 1 + 1 + 2 + + Failure: + + >>> 2 + 3 + 23 + >>> 1 + 1 + 11 + + Skipped test (ignored): + + >>> id(1.0) # doctest: +SKIP + 7948648 + """ + + def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + ''') + testname = self.create_test(code=code) + output = self.run_tests("--fail-env-changed", "-v", "-j1", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], failed=[testname], - randomize=True) + parallel=True, + stats=TestStats(1, 1, 0)) + + def _check_random_seed(self, run_workers: bool): + # gh-109276: When -r/--randomize is used, random.seed() is called + # with the same random seed before running each test file. + code = textwrap.dedent(r''' + import random + import unittest + + class RandomSeedTest(unittest.TestCase): + def test_randint(self): + numbers = [random.randint(0, 1000) for _ in range(10)] + print(f"Random numbers: {numbers}") + ''') + tests = [self.create_test(name=f'test_random{i}', code=code) + for i in range(1, 3+1)] + + random_seed = 856_656_202 + cmd = ["--randomize", f"--randseed={random_seed}"] + if run_workers: + # run as many worker processes than the number of tests + cmd.append(f'-j{len(tests)}') + cmd.extend(tests) + output = self.run_tests(*cmd) + + random.seed(random_seed) + # Make the assumption that nothing consume entropy between libregrest + # setup_tests() which calls random.seed() and RandomSeedTest calling + # random.randint(). + numbers = [random.randint(0, 1000) for _ in range(10)] + expected = f"Random numbers: {numbers}" + + regex = r'^Random numbers: .*$' + matches = re.findall(regex, output, flags=re.MULTILINE) + self.assertEqual(matches, [expected] * len(tests)) + + def test_random_seed(self): + self._check_random_seed(run_workers=False) + + def test_random_seed_workers(self): + self._check_random_seed(run_workers=True) + + def test_python_command(self): + code = textwrap.dedent(r""" + import sys + import unittest + + class WorkerTests(unittest.TestCase): + def test_dev_mode(self): + self.assertTrue(sys.flags.dev_mode) + """) + tests = [self.create_test(code=code) for _ in range(3)] + + # Custom Python command: "python -X dev" + python_cmd = [sys.executable, '-X', 'dev'] + # test.libregrtest.cmdline uses shlex.split() to parse the Python + # command line string + python_cmd = shlex.join(python_cmd) + + output = self.run_tests("--python", python_cmd, "-j0", *tests) + self.check_executed_tests(output, tests, + stats=len(tests), parallel=True) + + def check_add_python_opts(self, option): + # --fast-ci and --slow-ci add "-u -W default -bb -E" options to Python + code = textwrap.dedent(r""" + import sys + import unittest + from test import support + try: + from _testinternalcapi import get_config + except ImportError: + get_config = None + + # WASI/WASM buildbots don't use -E option + use_environment = (support.is_emscripten or support.is_wasi) + + class WorkerTests(unittest.TestCase): + @unittest.skipUnless(get_config is None, 'need get_config()') + def test_config(self): + config = get_config()['config'] + # -u option + self.assertEqual(config['buffered_stdio'], 0) + # -W default option + self.assertTrue(config['warnoptions'], ['default']) + # -bb option + self.assertTrue(config['bytes_warning'], 2) + # -E option + self.assertTrue(config['use_environment'], use_environment) + + def test_python_opts(self): + # -u option + self.assertTrue(sys.__stdout__.write_through) + self.assertTrue(sys.__stderr__.write_through) + + # -W default option + self.assertTrue(sys.warnoptions, ['default']) + + # -bb option + self.assertEqual(sys.flags.bytes_warning, 2) + + # -E option + self.assertEqual(not sys.flags.ignore_environment, + use_environment) + """) + testname = self.create_test(code=code) + + # Use directly subprocess to control the exact command line + cmd = [sys.executable, + "-m", "test", option, + f'--testdir={self.tmptestdir}', + testname] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + self.assertEqual(proc.returncode, 0, proc) + + def test_add_python_opts(self): + for opt in ("--fast-ci", "--slow-ci"): + with self.subTest(opt=opt): + self.check_add_python_opts(opt) + + # gh-76319: Raising SIGSEGV on Android may not cause a crash. + @unittest.skipIf(support.is_android, + 'raising SIGSEGV on Android is unreliable') + def test_worker_output_on_failure(self): + try: + from faulthandler import _sigsegv + except ImportError: + self.skipTest("need faulthandler._sigsegv") + + code = textwrap.dedent(r""" + import faulthandler + import unittest + from test import support + + class CrashTests(unittest.TestCase): + def test_crash(self): + print("just before crash!", flush=True) + + with support.SuppressCrashReport(): + faulthandler._sigsegv(True) + """) + testname = self.create_test(code=code) + + # Sanitizers must not handle SIGSEGV (ex: for test_enable_fd()) + env = dict(os.environ) + option = 'handle_segv=0' + support.set_sanitizer_env_var(env, option) + + output = self.run_tests("-j1", testname, + exitcode=EXITCODE_BAD_TEST, + env=env) + self.check_executed_tests(output, testname, + failed=[testname], + stats=0, parallel=True) + if not support.MS_WINDOWS: + exitcode = -int(signal.SIGSEGV) + self.assertIn(f"Exit code {exitcode} (SIGSEGV)", output) + self.check_line(output, "just before crash!", full=True, regex=False) class TestUtils(unittest.TestCase): @@ -1611,6 +2099,46 @@ def test_format_duration(self): self.assertEqual(utils.format_duration(3 * 3600 + 1), '3 hour 1 sec') + def test_normalize_test_name(self): + normalize = normalize_test_name + self.assertEqual(normalize('test_access (test.test_os.FileTests.test_access)'), + 'test_access') + self.assertEqual(normalize('setUpClass (test.test_os.ChownFileTests)', is_error=True), + 'ChownFileTests') + self.assertEqual(normalize('test_success (test.test_bug.ExampleTests.test_success)', is_error=True), + 'test_success') + self.assertIsNone(normalize('setUpModule (test.test_x)', is_error=True)) + self.assertIsNone(normalize('tearDownModule (test.test_module)', is_error=True)) + + def test_get_signal_name(self): + for exitcode, expected in ( + (-int(signal.SIGINT), 'SIGINT'), + (-int(signal.SIGSEGV), 'SIGSEGV'), + (3221225477, "STATUS_ACCESS_VIOLATION"), + (0xC00000FD, "STATUS_STACK_OVERFLOW"), + ): + self.assertEqual(utils.get_signal_name(exitcode), expected, exitcode) + + def test_format_resources(self): + format_resources = utils.format_resources + ALL_RESOURCES = utils.ALL_RESOURCES + self.assertEqual( + format_resources(("network",)), + 'resources (1): network') + self.assertEqual( + format_resources(("audio", "decimal", "network")), + 'resources (3): audio,decimal,network') + self.assertEqual( + format_resources(ALL_RESOURCES), + 'resources: all') + self.assertEqual( + format_resources(tuple(name for name in ALL_RESOURCES + if name != "cpu")), + 'resources: all,-cpu') + self.assertEqual( + format_resources((*ALL_RESOURCES, "tzdata")), + 'resources: all,tzdata') + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index ddb4aa68048df1..2ee5117bcd7bd4 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -5,6 +5,7 @@ import unittest import subprocess from textwrap import dedent +from test import support from test.support import cpython_only, has_subprocess_support, SuppressCrashReport from test.support.script_helper import kill_python @@ -59,6 +60,9 @@ def run_on_interactive_mode(source): class TestInteractiveInterpreter(unittest.TestCase): @cpython_only + # Python built with Py_TRACE_REFS fail with a fatal error in + # _PyRefchain_Trace() on memory allocation error. + @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') def test_no_memory(self): # Issue #30696: Fix the interactive interpreter looping endlessly when # no memory. Check also that the fix does not break the interactive @@ -127,6 +131,68 @@ def test_close_stdin(self): self.assertEqual(process.returncode, 0) self.assertIn('before close', output) + def test_interactive_traceback_reporting(self): + user_input = "1 / 0 / 3 / 4" + p = spawn_repl() + p.stdin.write(user_input) + output = kill_python(p) + self.assertEqual(p.returncode, 0) + + traceback_lines = output.splitlines()[-6:-1] + expected_lines = [ + "Traceback (most recent call last):", + " File \"\", line 1, in ", + " 1 / 0 / 3 / 4", + " ~~^~~", + "ZeroDivisionError: division by zero", + ] + self.assertEqual(traceback_lines, expected_lines) + + def test_interactive_traceback_reporting_multiple_input(self): + user_input1 = dedent(""" + def foo(x): + 1 / x + + """) + p = spawn_repl() + p.stdin.write(user_input1) + user_input2 = "foo(0)" + p.stdin.write(user_input2) + output = kill_python(p) + self.assertEqual(p.returncode, 0) + + traceback_lines = output.splitlines()[-7:-1] + expected_lines = [ + ' File "", line 1, in ', + ' foo(0)', + ' File "", line 2, in foo', + ' 1 / x', + ' ~~^~~', + 'ZeroDivisionError: division by zero' + ] + self.assertEqual(traceback_lines, expected_lines) + + def test_interactive_source_is_in_linecache(self): + user_input = dedent(""" + def foo(x): + return x + 1 + + def bar(x): + return foo(x) + 2 + """) + p = spawn_repl() + p.stdin.write(user_input) + user_input2 = dedent(""" + import linecache + print(linecache.cache['']) + """) + p.stdin.write(user_input2) + output = kill_python(p) + self.assertEqual(p.returncode, 0) + expected = "(30, None, [\'def foo(x):\\n\', \' return x + 1\\n\', \'\\n\'], \'\')" + self.assertIn(expected, output, expected) + + class TestInteractiveModeSyntaxErrors(unittest.TestCase): diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py index e7216d427200c1..3e93b561c143d8 100644 --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -765,5 +765,25 @@ def test_assigned_attributes(self): for name in assigned: self.assertIs(getattr(wrapper, name), getattr(wrapped, name)) + def test__wrapped__(self): + class X: + def __repr__(self): + return 'X()' + f = __repr__ # save reference to check it later + __repr__ = recursive_repr()(__repr__) + + self.assertIs(X.f, X.__repr__.__wrapped__) + + def test__type_params__(self): + class My: + @recursive_repr() + def __repr__[T: str](self, default: T = '') -> str: + return default + + type_params = My().__repr__.__type_params__ + self.assertEqual(len(type_params), 1) + self.assertEqual(type_params[0].__name__, 'T') + self.assertEqual(type_params[0].__bound__, str) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py index 6b5fc9a0247f4b..7347fca71be2fe 100644 --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -53,7 +53,10 @@ def test_attr_matches(self): ['str.{}('.format(x) for x in dir(str) if x.startswith('s')]) self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), []) - expected = sorted({'None.%s%s' % (x, '(' if x != '__doc__' else '') + expected = sorted({'None.%s%s' % (x, + '()' if x == '__init_subclass__' + else '' if x == '__doc__' + else '(') for x in dir(None)}) self.assertEqual(self.stdcompleter.attr_matches('None.'), expected) self.assertEqual(self.stdcompleter.attr_matches('None._'), expected) diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 6aaa288c14e1d7..628c8cae38a751 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -12,7 +12,7 @@ import textwrap import unittest import warnings -from test.support import no_tracing, verbose, requires_subprocess +from test.support import no_tracing, verbose, requires_subprocess, requires_resource from test.support.import_helper import forget, make_legacy_pyc, unload from test.support.os_helper import create_empty_file, temp_dir from test.support.script_helper import make_script, make_zip_script @@ -733,6 +733,7 @@ def test_zipfile_error(self): self._check_import_error(zip_name, msg) @no_tracing + @requires_resource('cpu') def test_main_recursion_error(self): with temp_dir() as script_dir, temp_dir() as dummy_dir: mod_name = '__main__' diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index 4545cbadb796fd..677349c2bfca93 100644 --- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -285,6 +285,35 @@ def test_select(self): self.assertEqual([(wr_key, selectors.EVENT_WRITE)], result) + def test_select_read_write(self): + # gh-110038: when a file descriptor is registered for both read and + # write, the two events must be seen on a single call to select(). + s = self.SELECTOR() + self.addCleanup(s.close) + + sock1, sock2 = self.make_socketpair() + sock2.send(b"foo") + my_key = s.register(sock1, selectors.EVENT_READ | selectors.EVENT_WRITE) + + seen_read, seen_write = False, False + result = s.select() + # We get the read and write either in the same result entry or in two + # distinct entries with the same key. + self.assertLessEqual(len(result), 2) + for key, events in result: + self.assertTrue(isinstance(key, selectors.SelectorKey)) + self.assertEqual(key, my_key) + self.assertFalse(events & ~(selectors.EVENT_READ | + selectors.EVENT_WRITE)) + if events & selectors.EVENT_READ: + self.assertFalse(seen_read) + seen_read = True + if events & selectors.EVENT_WRITE: + self.assertFalse(seen_write) + seen_write = True + self.assertTrue(seen_read) + self.assertTrue(seen_write) + def test_context_manager(self): s = self.SELECTOR() self.addCleanup(s.close) @@ -455,6 +484,7 @@ class ScalableSelectorMixIn: # see issue #18963 for why it's skipped on older OS X versions @support.requires_mac_ver(10, 5) @unittest.skipUnless(resource, "Test needs resource module") + @support.requires_resource('cpu') def test_above_fd_setsize(self): # A scalable implementation should have no problem with more than # FD_SETSIZE file descriptors. Since we don't know the value, we just diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 2dd65240f5faec..d9102eb98a54a6 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -635,10 +635,6 @@ def __le__(self, some_set): myset >= myobj self.assertTrue(myobj.le_called) - @unittest.skipUnless(hasattr(set, "test_c_api"), - 'C API test only available in a debug build') - def test_c_api(self): - self.assertEqual(set().test_c_api(), True) class SetSubclass(set): pass diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 93f20a6ff41332..d231e66b7b889f 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1839,6 +1839,49 @@ def test_register_archive_format(self): formats = [name for name, params in get_archive_formats()] self.assertNotIn('xxx', formats) + def test_make_tarfile_rootdir_nodir(self): + # GH-99203 + self.addCleanup(os_helper.unlink, f'{TESTFN}.tar') + for dry_run in (False, True): + with self.subTest(dry_run=dry_run): + tmp_dir = self.mkdtemp() + nonexisting_file = os.path.join(tmp_dir, 'nonexisting') + with self.assertRaises(FileNotFoundError) as cm: + make_archive(TESTFN, 'tar', nonexisting_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOENT) + self.assertEqual(cm.exception.filename, nonexisting_file) + self.assertFalse(os.path.exists(f'{TESTFN}.tar')) + + tmp_fd, tmp_file = tempfile.mkstemp(dir=tmp_dir) + os.close(tmp_fd) + with self.assertRaises(NotADirectoryError) as cm: + make_archive(TESTFN, 'tar', tmp_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOTDIR) + self.assertEqual(cm.exception.filename, tmp_file) + self.assertFalse(os.path.exists(f'{TESTFN}.tar')) + + @support.requires_zlib() + def test_make_zipfile_rootdir_nodir(self): + # GH-99203 + self.addCleanup(os_helper.unlink, f'{TESTFN}.zip') + for dry_run in (False, True): + with self.subTest(dry_run=dry_run): + tmp_dir = self.mkdtemp() + nonexisting_file = os.path.join(tmp_dir, 'nonexisting') + with self.assertRaises(FileNotFoundError) as cm: + make_archive(TESTFN, 'zip', nonexisting_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOENT) + self.assertEqual(cm.exception.filename, nonexisting_file) + self.assertFalse(os.path.exists(f'{TESTFN}.zip')) + + tmp_fd, tmp_file = tempfile.mkstemp(dir=tmp_dir) + os.close(tmp_fd) + with self.assertRaises(NotADirectoryError) as cm: + make_archive(TESTFN, 'zip', tmp_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOTDIR) + self.assertEqual(cm.exception.filename, tmp_file) + self.assertFalse(os.path.exists(f'{TESTFN}.zip')) + ### shutil.unpack_archive def check_unpack_archive(self, format, **kwargs): @@ -2024,6 +2067,14 @@ def setUp(self): self.curdir = os.curdir self.ext = ".EXE" + def to_text_type(self, s): + ''' + In this class we're testing with str, so convert s to a str + ''' + if isinstance(s, bytes): + return s.decode() + return s + def test_basic(self): # Given an EXE in a directory, it should be returned. rv = shutil.which(self.file, path=self.dir) @@ -2211,9 +2262,9 @@ def test_empty_path_no_PATH(self): @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') def test_pathext(self): - ext = ".xyz" + ext = self.to_text_type(".xyz") temp_filexyz = tempfile.NamedTemporaryFile(dir=self.temp_dir, - prefix="Tmp2", suffix=ext) + prefix=self.to_text_type("Tmp2"), suffix=ext) os.chmod(temp_filexyz.name, stat.S_IXUSR) self.addCleanup(temp_filexyz.close) @@ -2222,16 +2273,16 @@ def test_pathext(self): program = os.path.splitext(program)[0] with os_helper.EnvironmentVarGuard() as env: - env['PATHEXT'] = ext + env['PATHEXT'] = ext if isinstance(ext, str) else ext.decode() rv = shutil.which(program, path=self.temp_dir) self.assertEqual(rv, temp_filexyz.name) # Issue 40592: See https://bugs.python.org/issue40592 @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') def test_pathext_with_empty_str(self): - ext = ".xyz" + ext = self.to_text_type(".xyz") temp_filexyz = tempfile.NamedTemporaryFile(dir=self.temp_dir, - prefix="Tmp2", suffix=ext) + prefix=self.to_text_type("Tmp2"), suffix=ext) self.addCleanup(temp_filexyz.close) # strip path and extension @@ -2239,7 +2290,7 @@ def test_pathext_with_empty_str(self): program = os.path.splitext(program)[0] with os_helper.EnvironmentVarGuard() as env: - env['PATHEXT'] = f"{ext};" # note the ; + env['PATHEXT'] = f"{ext if isinstance(ext, str) else ext.decode()};" # note the ; rv = shutil.which(program, path=self.temp_dir) self.assertEqual(rv, temp_filexyz.name) @@ -2247,13 +2298,14 @@ def test_pathext_with_empty_str(self): @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') def test_pathext_applied_on_files_in_path(self): with os_helper.EnvironmentVarGuard() as env: - env["PATH"] = self.temp_dir + env["PATH"] = self.temp_dir if isinstance(self.temp_dir, str) else self.temp_dir.decode() env["PATHEXT"] = ".test" - test_path = pathlib.Path(self.temp_dir) / "test_program.test" - test_path.touch(mode=0o755) + test_path = os.path.join(self.temp_dir, self.to_text_type("test_program.test")) + open(test_path, 'w').close() + os.chmod(test_path, 0o755) - self.assertEqual(shutil.which("test_program"), str(test_path)) + self.assertEqual(shutil.which(self.to_text_type("test_program")), test_path) # See GH-75586 @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') @@ -2269,6 +2321,50 @@ def test_win_path_needs_curdir(self): self.assertFalse(shutil._win_path_needs_curdir('dontcare', os.X_OK)) need_curdir_mock.assert_called_once_with('dontcare') + # See GH-109590 + @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') + def test_pathext_preferred_for_execute(self): + with os_helper.EnvironmentVarGuard() as env: + env["PATH"] = self.temp_dir if isinstance(self.temp_dir, str) else self.temp_dir.decode() + env["PATHEXT"] = ".test" + + exe = os.path.join(self.temp_dir, self.to_text_type("test.exe")) + open(exe, 'w').close() + os.chmod(exe, 0o755) + + # default behavior allows a direct match if nothing in PATHEXT matches + self.assertEqual(shutil.which(self.to_text_type("test.exe")), exe) + + dot_test = os.path.join(self.temp_dir, self.to_text_type("test.exe.test")) + open(dot_test, 'w').close() + os.chmod(dot_test, 0o755) + + # now we have a PATHEXT match, so it take precedence + self.assertEqual(shutil.which(self.to_text_type("test.exe")), dot_test) + + # but if we don't use os.X_OK we don't change the order based off PATHEXT + # and therefore get the direct match. + self.assertEqual(shutil.which(self.to_text_type("test.exe"), mode=os.F_OK), exe) + + # See GH-109590 + @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') + def test_pathext_given_extension_preferred(self): + with os_helper.EnvironmentVarGuard() as env: + env["PATH"] = self.temp_dir if isinstance(self.temp_dir, str) else self.temp_dir.decode() + env["PATHEXT"] = ".exe2;.exe" + + exe = os.path.join(self.temp_dir, self.to_text_type("test.exe")) + open(exe, 'w').close() + os.chmod(exe, 0o755) + + exe2 = os.path.join(self.temp_dir, self.to_text_type("test.exe2")) + open(exe2, 'w').close() + os.chmod(exe2, 0o755) + + # even though .exe2 is preferred in PATHEXT, we matched directly to test.exe + self.assertEqual(shutil.which(self.to_text_type("test.exe")), exe) + self.assertEqual(shutil.which(self.to_text_type("test")), exe2) + class TestWhichBytes(TestWhich): def setUp(self): @@ -2276,9 +2372,18 @@ def setUp(self): self.dir = os.fsencode(self.dir) self.file = os.fsencode(self.file) self.temp_file.name = os.fsencode(self.temp_file.name) + self.temp_dir = os.fsencode(self.temp_dir) self.curdir = os.fsencode(self.curdir) self.ext = os.fsencode(self.ext) + def to_text_type(self, s): + ''' + In this class we're testing with bytes, so convert s to a bytes + ''' + if isinstance(s, str): + return s.encode() + return s + class TestMove(BaseTest, unittest.TestCase): diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 25afd6aabe0751..f2ae28c38dd72d 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -745,6 +745,7 @@ def test_siginterrupt_on(self): interrupted = self.readpipe_interrupted(True) self.assertTrue(interrupted) + @support.requires_resource('walltime') def test_siginterrupt_off(self): # If a signal handler is installed and siginterrupt is called with # a false value for the second argument, when that signal arrives, it @@ -1338,7 +1339,7 @@ def set_interrupts(): num_sent_signals += 1 def cycle_handlers(): - while num_sent_signals < 100: + while num_sent_signals < 100 or num_received_signals < 1: for i in range(20000): # Cycle between a Python-defined and a non-Python handler for handler in [custom_handler, signal.SIG_IGN]: @@ -1371,7 +1372,7 @@ def cycle_handlers(): if not ignored: # Sanity check that some signals were received, but not all self.assertGreater(num_received_signals, 0) - self.assertLess(num_received_signals, num_sent_signals) + self.assertLessEqual(num_received_signals, num_sent_signals) finally: do_stop = True t.join() diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 9e701fd847acdf..e8ec3b35881fec 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -465,10 +465,10 @@ def test_sitecustomize_executed(self): else: self.fail("sitecustomize not imported automatically") - @test.support.requires_resource('network') - @test.support.system_must_validate_cert @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), 'need SSL support to download license') + @test.support.requires_resource('network') + @test.support.system_must_validate_cert def test_license_exists_at_url(self): # This test is a bit fragile since it depends on the format of the # string displayed by license in the absence of a LICENSE file. @@ -576,7 +576,7 @@ def _create_underpth_exe(self, lines, exe_pth=True): _pth_file = os.path.splitext(exe_file)[0] + '._pth' else: _pth_file = os.path.splitext(dll_file)[0] + '._pth' - with open(_pth_file, 'w') as f: + with open(_pth_file, 'w', encoding='utf8') as f: for line in lines: print(line, file=f) return exe_file @@ -613,7 +613,7 @@ def test_underpth_basic(self): os.path.dirname(exe_file), pth_lines) - output = subprocess.check_output([exe_file, '-c', + output = subprocess.check_output([exe_file, '-X', 'utf8', '-c', 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' ], encoding='utf-8', errors='surrogateescape') actual_sys_path = output.rstrip().split('\n') diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index b6d5b8c3d82580..f2e02dab1c3ca5 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -831,6 +831,7 @@ class SimSMTPChannel(smtpd.SMTPChannel): def __init__(self, extra_features, *args, **kw): self._extrafeatures = ''.join( [ "250-{0}\r\n".format(x) for x in extra_features ]) + self.all_received_lines = [] super(SimSMTPChannel, self).__init__(*args, **kw) # AUTH related stuff. It would be nice if support for this were in smtpd. @@ -845,6 +846,7 @@ def found_terminator(self): self.smtp_state = self.COMMAND self.push('%s %s' % (e.smtp_code, e.smtp_error)) return + self.all_received_lines.append(self.received_lines) super().found_terminator() @@ -1349,6 +1351,18 @@ def test_name_field_not_included_in_envelop_addresses(self): self.assertEqual(self.serv._addresses['from'], 'michael@example.com') self.assertEqual(self.serv._addresses['tos'], ['rene@example.com']) + def test_lowercase_mail_from_rcpt_to(self): + m = 'A test message' + smtp = smtplib.SMTP( + HOST, self.port, local_hostname='localhost', + timeout=support.LOOPBACK_TIMEOUT) + self.addCleanup(smtp.close) + + smtp.sendmail('John', 'Sally', m) + + self.assertIn(['mail from: size=14'], self.serv._SMTPchannel.all_received_lines) + self.assertIn(['rcpt to:'], self.serv._SMTPchannel.all_received_lines) + class SimSMTPUTF8Server(SimSMTPServer): diff --git a/Lib/test/test_smtpnet.py b/Lib/test/test_smtpnet.py index 72f51cd8d81f59..2e0dc1aa276f35 100644 --- a/Lib/test/test_smtpnet.py +++ b/Lib/test/test_smtpnet.py @@ -61,6 +61,7 @@ def test_connect_default_port(self): server.ehlo() server.quit() + @support.requires_resource('walltime') def test_connect_using_sslcontext(self): context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.check_hostname = False diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 0eaf64257c3b81..86701caf05399e 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -215,24 +215,6 @@ def setUp(self): self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDPLITE) self.port = socket_helper.bind_port(self.serv) -class ThreadSafeCleanupTestCase: - """Subclass of unittest.TestCase with thread-safe cleanup methods. - - This subclass protects the addCleanup() and doCleanups() methods - with a recursive lock. - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._cleanup_lock = threading.RLock() - - def addCleanup(self, *args, **kwargs): - with self._cleanup_lock: - return super().addCleanup(*args, **kwargs) - - def doCleanups(self, *args, **kwargs): - with self._cleanup_lock: - return super().doCleanups(*args, **kwargs) class SocketCANTest(unittest.TestCase): @@ -626,8 +608,7 @@ def setUp(self): self.serv.listen() -class ThreadedSocketTestMixin(ThreadSafeCleanupTestCase, SocketTestBase, - ThreadableTest): +class ThreadedSocketTestMixin(SocketTestBase, ThreadableTest): """Mixin to add client socket and allow client/server tests. Client socket is self.cli and its address is self.cli_addr. See @@ -2813,7 +2794,7 @@ def _testRecvFromNegative(self): # here assumes that datagram delivery on the local machine will be # reliable. -class SendrecvmsgBase(ThreadSafeCleanupTestCase): +class SendrecvmsgBase: # Base class for sendmsg()/recvmsg() tests. # Time in seconds to wait before considering a test failed, or @@ -4679,7 +4660,6 @@ def testInterruptedRecvmsgIntoTimeout(self): @unittest.skipUnless(hasattr(signal, "alarm") or hasattr(signal, "setitimer"), "Don't have signal.alarm or signal.setitimer") class InterruptedSendTimeoutTest(InterruptedTimeoutBase, - ThreadSafeCleanupTestCase, SocketListeningTestMixin, TCPTestBase): # Test interrupting the interruptible send*() methods with signals # when a timeout is set. @@ -5288,6 +5268,7 @@ def mocked_socket_module(self): finally: socket.socket = old_socket + @socket_helper.skip_if_tcp_blackhole def test_connect(self): port = socket_helper.find_unused_port() cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -5296,6 +5277,7 @@ def test_connect(self): cli.connect((HOST, port)) self.assertEqual(cm.exception.errno, errno.ECONNREFUSED) + @socket_helper.skip_if_tcp_blackhole def test_create_connection(self): # Issue #9792: errors raised by create_connection() should have # a proper errno attribute. @@ -5354,6 +5336,7 @@ def test_create_connection_timeout(self): class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest): + cli = None def __init__(self, methodName='runTest'): SocketTCPTest.__init__(self, methodName=methodName) @@ -5363,7 +5346,8 @@ def clientSetUp(self): self.source_port = socket_helper.find_unused_port() def clientTearDown(self): - self.cli.close() + if self.cli is not None: + self.cli.close() self.cli = None ThreadableTest.clientTearDown(self) @@ -6472,12 +6456,16 @@ def test_sha256(self): self.assertEqual(op.recv(512), expected) def test_hmac_sha1(self): - expected = bytes.fromhex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79") + # gh-109396: In FIPS mode, Linux 6.5 requires a key + # of at least 112 bits. Use a key of 152 bits. + key = b"Python loves AF_ALG" + data = b"what do ya want for nothing?" + expected = bytes.fromhex("193dbb43c6297b47ea6277ec0ce67119a3f3aa66") with self.create_alg('hash', 'hmac(sha1)') as algo: - algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b"Jefe") + algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, key) op, _ = algo.accept() with op: - op.sendall(b"what do ya want for nothing?") + op.sendall(data) self.assertEqual(op.recv(512), expected) # Although it should work with 3.19 and newer the test blocks on diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index c81d559cde315d..0f62f9eb200e42 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -32,11 +32,6 @@ HAVE_FORKING = test.support.has_fork_support requires_forking = unittest.skipUnless(HAVE_FORKING, 'requires forking') -def signal_alarm(n): - """Call signal.alarm when it exists (i.e. not on Windows).""" - if hasattr(signal, 'alarm'): - signal.alarm(n) - # Remember real select() to avoid interferences with mocking _real_select = select.select @@ -68,12 +63,10 @@ class SocketServerTest(unittest.TestCase): """Test all socket servers.""" def setUp(self): - signal_alarm(60) # Kill deadlocks after 60 seconds. self.port_seed = 0 self.test_files = [] def tearDown(self): - signal_alarm(0) # Didn't deadlock. reap_children() for fn in self.test_files: diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index b05173ad00d442..61b00778f8361c 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import unittest -from test.support import script_helper, captured_stdout, requires_subprocess +from test.support import script_helper, captured_stdout, requires_subprocess, requires_resource from test.support.os_helper import TESTFN, unlink, rmtree from test.support.import_helper import unload import importlib @@ -68,6 +68,7 @@ def test_issue7820(self): def test_20731(self): sub = subprocess.Popen([sys.executable, os.path.join(os.path.dirname(__file__), + 'tokenizedata', 'coding20731.py')], stderr=subprocess.PIPE) err = sub.communicate()[1] @@ -100,10 +101,10 @@ def test_bad_coding2(self): self.verify_bad_module(module_name) def verify_bad_module(self, module_name): - self.assertRaises(SyntaxError, __import__, 'test.' + module_name) + self.assertRaises(SyntaxError, __import__, 'test.tokenizedata.' + module_name) path = os.path.dirname(__file__) - filename = os.path.join(path, module_name + '.py') + filename = os.path.join(path, 'tokenizedata', module_name + '.py') with open(filename, "rb") as fp: bytes = fp.read() self.assertRaises(SyntaxError, compile, bytes, filename, 'exec') @@ -250,10 +251,11 @@ def test_crcrcrlf2(self): class UTF8ValidatorTest(unittest.TestCase): @unittest.skipIf(not sys.platform.startswith("linux"), "Too slow to run on non-Linux platforms") + @requires_resource('cpu') def test_invalid_utf8(self): # This is a port of test_utf8_decode_invalid_sequences in # test_unicode.py to exercise the separate utf8 validator in - # Parser/tokenizer.c used when reading source files. + # Parser/tokenizer/helpers.c used when reading source files. # That file is written using low-level C file I/O, so the only way to # test it is to write actual files to disk. diff --git a/Lib/test/test_sqlite3/test_backup.py b/Lib/test/test_sqlite3/test_backup.py index 87ab29c54d65e2..c7400d8b2165e6 100644 --- a/Lib/test/test_sqlite3/test_backup.py +++ b/Lib/test/test_sqlite3/test_backup.py @@ -1,6 +1,8 @@ import sqlite3 as sqlite import unittest +from .util import memory_database + class BackupTests(unittest.TestCase): def setUp(self): @@ -32,32 +34,32 @@ def test_bad_target_same_connection(self): self.cx.backup(self.cx) def test_bad_target_closed_connection(self): - bck = sqlite.connect(':memory:') - bck.close() - with self.assertRaises(sqlite.ProgrammingError): - self.cx.backup(bck) + with memory_database() as bck: + bck.close() + with self.assertRaises(sqlite.ProgrammingError): + self.cx.backup(bck) def test_bad_source_closed_connection(self): - bck = sqlite.connect(':memory:') - source = sqlite.connect(":memory:") - source.close() - with self.assertRaises(sqlite.ProgrammingError): - source.backup(bck) + with memory_database() as bck: + source = sqlite.connect(":memory:") + source.close() + with self.assertRaises(sqlite.ProgrammingError): + source.backup(bck) def test_bad_target_in_transaction(self): - bck = sqlite.connect(':memory:') - bck.execute('CREATE TABLE bar (key INTEGER)') - bck.executemany('INSERT INTO bar (key) VALUES (?)', [(3,), (4,)]) - with self.assertRaises(sqlite.OperationalError) as cm: - self.cx.backup(bck) + with memory_database() as bck: + bck.execute('CREATE TABLE bar (key INTEGER)') + bck.executemany('INSERT INTO bar (key) VALUES (?)', [(3,), (4,)]) + with self.assertRaises(sqlite.OperationalError) as cm: + self.cx.backup(bck) def test_keyword_only_args(self): with self.assertRaises(TypeError): - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, 1) def test_simple(self): - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck) self.verify_backup(bck) @@ -67,7 +69,7 @@ def test_progress(self): def progress(status, remaining, total): journal.append(status) - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, pages=1, progress=progress) self.verify_backup(bck) @@ -81,7 +83,7 @@ def test_progress_all_pages_at_once_1(self): def progress(status, remaining, total): journal.append(remaining) - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, progress=progress) self.verify_backup(bck) @@ -94,7 +96,7 @@ def test_progress_all_pages_at_once_2(self): def progress(status, remaining, total): journal.append(remaining) - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, pages=-1, progress=progress) self.verify_backup(bck) @@ -103,7 +105,7 @@ def progress(status, remaining, total): def test_non_callable_progress(self): with self.assertRaises(TypeError) as cm: - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, pages=1, progress='bar') self.assertEqual(str(cm.exception), 'progress argument must be a callable') @@ -116,7 +118,7 @@ def progress(status, remaining, total): self.cx.commit() journal.append(remaining) - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, pages=1, progress=progress) self.verify_backup(bck) @@ -135,17 +137,17 @@ def progress(status, remaining, total): raise SystemError('nearly out of space') with self.assertRaises(SystemError) as err: - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, progress=progress) self.assertEqual(str(err.exception), 'nearly out of space') def test_database_source_name(self): - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, name='main') - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, name='temp') with self.assertRaises(sqlite.OperationalError) as cm: - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, name='non-existing') self.assertIn("unknown database", str(cm.exception)) @@ -153,7 +155,7 @@ def test_database_source_name(self): self.cx.execute('CREATE TABLE attached_db.foo (key INTEGER)') self.cx.executemany('INSERT INTO attached_db.foo (key) VALUES (?)', [(3,), (4,)]) self.cx.commit() - with sqlite.connect(':memory:') as bck: + with memory_database() as bck: self.cx.backup(bck, name='attached_db') self.verify_backup(bck) diff --git a/Lib/test/test_sqlite3/test_cli.py b/Lib/test/test_sqlite3/test_cli.py index d374f8ee4fc8d3..303f9e03b5383f 100644 --- a/Lib/test/test_sqlite3/test_cli.py +++ b/Lib/test/test_sqlite3/test_cli.py @@ -1,42 +1,35 @@ """sqlite3 CLI tests.""" - -import sqlite3 as sqlite -import subprocess -import sys +import sqlite3 import unittest -from test.support import SHORT_TIMEOUT, requires_subprocess +from sqlite3.__main__ import main as cli from test.support.os_helper import TESTFN, unlink +from test.support import captured_stdout, captured_stderr, captured_stdin -@requires_subprocess() class CommandLineInterface(unittest.TestCase): def _do_test(self, *args, expect_success=True): - with subprocess.Popen( - [sys.executable, "-Xutf8", "-m", "sqlite3", *args], - encoding="utf-8", - bufsize=0, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) as proc: - proc.wait() - if expect_success == bool(proc.returncode): - self.fail("".join(proc.stderr)) - stdout = proc.stdout.read() - stderr = proc.stderr.read() - if expect_success: - self.assertEqual(stderr, "") - else: - self.assertEqual(stdout, "") - return stdout, stderr + with ( + captured_stdout() as out, + captured_stderr() as err, + self.assertRaises(SystemExit) as cm + ): + cli(args) + return out.getvalue(), err.getvalue(), cm.exception.code def expect_success(self, *args): - out, _ = self._do_test(*args) + out, err, code = self._do_test(*args) + self.assertEqual(code, 0, + "\n".join([f"Unexpected failure: {args=}", out, err])) + self.assertEqual(err, "") return out def expect_failure(self, *args): - _, err = self._do_test(*args, expect_success=False) + out, err, code = self._do_test(*args, expect_success=False) + self.assertNotEqual(code, 0, + "\n".join([f"Unexpected failure: {args=}", out, err])) + self.assertEqual(out, "") return err def test_cli_help(self): @@ -45,7 +38,7 @@ def test_cli_help(self): def test_cli_version(self): out = self.expect_success("-v") - self.assertIn(sqlite.sqlite_version, out) + self.assertIn(sqlite3.sqlite_version, out) def test_cli_execute_sql(self): out = self.expect_success(":memory:", "select 1") @@ -68,87 +61,94 @@ def test_cli_on_disk_db(self): self.assertIn("(0,)", out) -@requires_subprocess() class InteractiveSession(unittest.TestCase): - TIMEOUT = SHORT_TIMEOUT / 10. MEMORY_DB_MSG = "Connected to a transient in-memory database" PS1 = "sqlite> " PS2 = "... " - def start_cli(self, *args): - return subprocess.Popen( - [sys.executable, "-Xutf8", "-m", "sqlite3", *args], - encoding="utf-8", - bufsize=0, - stdin=subprocess.PIPE, - # Note: the banner is printed to stderr, the prompt to stdout. - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - - def expect_success(self, proc): - proc.wait() - if proc.returncode: - self.fail("".join(proc.stderr)) + def run_cli(self, *args, commands=()): + with ( + captured_stdin() as stdin, + captured_stdout() as stdout, + captured_stderr() as stderr, + self.assertRaises(SystemExit) as cm + ): + for cmd in commands: + stdin.write(cmd + "\n") + stdin.seek(0) + cli(args) + + out = stdout.getvalue() + err = stderr.getvalue() + self.assertEqual(cm.exception.code, 0, + f"Unexpected failure: {args=}\n{out}\n{err}") + return out, err def test_interact(self): - with self.start_cli() as proc: - out, err = proc.communicate(timeout=self.TIMEOUT) - self.assertIn(self.MEMORY_DB_MSG, err) - self.assertIn(self.PS1, out) - self.expect_success(proc) + out, err = self.run_cli() + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 1) + self.assertEqual(out.count(self.PS2), 0) def test_interact_quit(self): - with self.start_cli() as proc: - out, err = proc.communicate(input=".quit", timeout=self.TIMEOUT) - self.assertIn(self.MEMORY_DB_MSG, err) - self.assertIn(self.PS1, out) - self.expect_success(proc) + out, err = self.run_cli(commands=(".quit",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 1) + self.assertEqual(out.count(self.PS2), 0) def test_interact_version(self): - with self.start_cli() as proc: - out, err = proc.communicate(input=".version", timeout=self.TIMEOUT) - self.assertIn(self.MEMORY_DB_MSG, err) - self.assertIn(sqlite.sqlite_version, out) - self.expect_success(proc) + out, err = self.run_cli(commands=(".version",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(sqlite3.sqlite_version + "\n", out) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 0) + self.assertIn(sqlite3.sqlite_version, out) def test_interact_valid_sql(self): - with self.start_cli() as proc: - out, err = proc.communicate(input="select 1;", - timeout=self.TIMEOUT) - self.assertIn(self.MEMORY_DB_MSG, err) - self.assertIn("(1,)", out) - self.expect_success(proc) + out, err = self.run_cli(commands=("SELECT 1;",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("(1,)\n", out) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 0) + + def test_interact_incomplete_multiline_sql(self): + out, err = self.run_cli(commands=("SELECT 1",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertTrue(out.endswith(self.PS2)) + self.assertEqual(out.count(self.PS1), 1) + self.assertEqual(out.count(self.PS2), 1) def test_interact_valid_multiline_sql(self): - with self.start_cli() as proc: - out, err = proc.communicate(input="select 1\n;", - timeout=self.TIMEOUT) - self.assertIn(self.MEMORY_DB_MSG, err) - self.assertIn(self.PS2, out) - self.assertIn("(1,)", out) - self.expect_success(proc) + out, err = self.run_cli(commands=("SELECT 1\n;",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS2, out) + self.assertIn("(1,)\n", out) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 1) def test_interact_invalid_sql(self): - with self.start_cli() as proc: - out, err = proc.communicate(input="sel;", timeout=self.TIMEOUT) - self.assertIn(self.MEMORY_DB_MSG, err) - self.assertIn("OperationalError (SQLITE_ERROR)", err) - self.expect_success(proc) + out, err = self.run_cli(commands=("sel;",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("OperationalError (SQLITE_ERROR)", err) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 0) def test_interact_on_disk_file(self): self.addCleanup(unlink, TESTFN) - with self.start_cli(TESTFN) as proc: - out, err = proc.communicate(input="create table t(t);", - timeout=self.TIMEOUT) - self.assertIn(TESTFN, err) - self.assertIn(self.PS1, out) - self.expect_success(proc) - with self.start_cli(TESTFN, "select count(t) from t") as proc: - out = proc.stdout.read() - err = proc.stderr.read() - self.assertIn("(0,)", out) - self.expect_success(proc) + + out, err = self.run_cli(TESTFN, commands=("CREATE TABLE t(t);",)) + self.assertIn(TESTFN, err) + self.assertTrue(out.endswith(self.PS1)) + + out, _ = self.run_cli(TESTFN, commands=("SELECT count(t) FROM t;",)) + self.assertIn("(0,)\n", out) if __name__ == "__main__": diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 3f9bd0248a8b96..f3efe0f52f4fd7 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -33,26 +33,14 @@ SHORT_TIMEOUT, check_disallow_instantiation, requires_subprocess, is_emscripten, is_wasi ) +from test.support import gc_collect from test.support import threading_helper from _testcapi import INT_MAX, ULLONG_MAX from os import SEEK_SET, SEEK_CUR, SEEK_END from test.support.os_helper import TESTFN, TESTFN_UNDECODABLE, unlink, temp_dir, FakePath - -# Helper for temporary memory databases -def memory_database(*args, **kwargs): - cx = sqlite.connect(":memory:", *args, **kwargs) - return contextlib.closing(cx) - - -# Temporarily limit a database connection parameter -@contextlib.contextmanager -def cx_limit(cx, category=sqlite.SQLITE_LIMIT_SQL_LENGTH, limit=128): - try: - _prev = cx.setlimit(category, limit) - yield limit - finally: - cx.setlimit(category, _prev) +from .util import memory_database, cx_limit +from .util import MemoryDatabaseMixin class ModuleTests(unittest.TestCase): @@ -326,9 +314,9 @@ def test_extended_error_code_on_exception(self): self.assertEqual(exc.sqlite_errorname, "SQLITE_CONSTRAINT_CHECK") def test_disallow_instantiation(self): - cx = sqlite.connect(":memory:") - check_disallow_instantiation(self, type(cx("select 1"))) - check_disallow_instantiation(self, sqlite.Blob) + with memory_database() as cx: + check_disallow_instantiation(self, type(cx("select 1"))) + check_disallow_instantiation(self, sqlite.Blob) def test_complete_statement(self): self.assertFalse(sqlite.complete_statement("select t")) @@ -342,6 +330,7 @@ def setUp(self): cu = self.cx.cursor() cu.execute("create table test(id integer primary key, name text)") cu.execute("insert into test(name) values (?)", ("foo",)) + cu.close() def tearDown(self): self.cx.close() @@ -412,21 +401,22 @@ def test_exceptions(self): def test_in_transaction(self): # Can't use db from setUp because we want to test initial state. - cx = sqlite.connect(":memory:") - cu = cx.cursor() - self.assertEqual(cx.in_transaction, False) - cu.execute("create table transactiontest(id integer primary key, name text)") - self.assertEqual(cx.in_transaction, False) - cu.execute("insert into transactiontest(name) values (?)", ("foo",)) - self.assertEqual(cx.in_transaction, True) - cu.execute("select name from transactiontest where name=?", ["foo"]) - row = cu.fetchone() - self.assertEqual(cx.in_transaction, True) - cx.commit() - self.assertEqual(cx.in_transaction, False) - cu.execute("select name from transactiontest where name=?", ["foo"]) - row = cu.fetchone() - self.assertEqual(cx.in_transaction, False) + with memory_database() as cx: + cu = cx.cursor() + self.assertEqual(cx.in_transaction, False) + cu.execute("create table transactiontest(id integer primary key, name text)") + self.assertEqual(cx.in_transaction, False) + cu.execute("insert into transactiontest(name) values (?)", ("foo",)) + self.assertEqual(cx.in_transaction, True) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, True) + cx.commit() + self.assertEqual(cx.in_transaction, False) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, False) + cu.close() def test_in_transaction_ro(self): with self.assertRaises(AttributeError): @@ -450,10 +440,9 @@ def test_connection_exceptions(self): self.assertIs(getattr(sqlite, exc), getattr(self.cx, exc)) def test_interrupt_on_closed_db(self): - cx = sqlite.connect(":memory:") - cx.close() + self.cx.close() with self.assertRaises(sqlite.ProgrammingError): - cx.interrupt() + self.cx.interrupt() def test_interrupt(self): self.assertIsNone(self.cx.interrupt()) @@ -521,29 +510,29 @@ def test_connection_init_good_isolation_levels(self): self.assertEqual(cx.isolation_level, level) def test_connection_reinit(self): - db = ":memory:" - cx = sqlite.connect(db) - cx.text_factory = bytes - cx.row_factory = sqlite.Row - cu = cx.cursor() - cu.execute("create table foo (bar)") - cu.executemany("insert into foo (bar) values (?)", - ((str(v),) for v in range(4))) - cu.execute("select bar from foo") - - rows = [r for r in cu.fetchmany(2)] - self.assertTrue(all(isinstance(r, sqlite.Row) for r in rows)) - self.assertEqual([r[0] for r in rows], [b"0", b"1"]) - - cx.__init__(db) - cx.execute("create table foo (bar)") - cx.executemany("insert into foo (bar) values (?)", - ((v,) for v in ("a", "b", "c", "d"))) - - # This uses the old database, old row factory, but new text factory - rows = [r for r in cu.fetchall()] - self.assertTrue(all(isinstance(r, sqlite.Row) for r in rows)) - self.assertEqual([r[0] for r in rows], ["2", "3"]) + with memory_database() as cx: + cx.text_factory = bytes + cx.row_factory = sqlite.Row + cu = cx.cursor() + cu.execute("create table foo (bar)") + cu.executemany("insert into foo (bar) values (?)", + ((str(v),) for v in range(4))) + cu.execute("select bar from foo") + + rows = [r for r in cu.fetchmany(2)] + self.assertTrue(all(isinstance(r, sqlite.Row) for r in rows)) + self.assertEqual([r[0] for r in rows], [b"0", b"1"]) + + cx.__init__(":memory:") + cx.execute("create table foo (bar)") + cx.executemany("insert into foo (bar) values (?)", + ((v,) for v in ("a", "b", "c", "d"))) + + # This uses the old database, old row factory, but new text factory + rows = [r for r in cu.fetchall()] + self.assertTrue(all(isinstance(r, sqlite.Row) for r in rows)) + self.assertEqual([r[0] for r in rows], ["2", "3"]) + cu.close() def test_connection_bad_reinit(self): cx = sqlite.connect(":memory:") @@ -582,6 +571,25 @@ def test_connection_config(self): with self.assertRaisesRegex(sqlite.IntegrityError, "constraint"): cx.execute("insert into u values(0)") + def test_connect_positional_arguments(self): + regex = ( + r"Passing more than 1 positional argument to sqlite3.connect\(\)" + " is deprecated. Parameters 'timeout', 'detect_types', " + "'isolation_level', 'check_same_thread', 'factory', " + "'cached_statements' and 'uri' will become keyword-only " + "parameters in Python 3.15." + ) + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + cx = sqlite.connect(":memory:", 1.0) + cx.close() + self.assertEqual(cm.filename, __file__) + + def test_connection_resource_warning(self): + with self.assertWarns(ResourceWarning): + cx = sqlite.connect(":memory:") + del cx + gc_collect() + class UninitialisedConnectionTests(unittest.TestCase): def setUp(self): @@ -1558,12 +1566,12 @@ def run(con, err): except sqlite.Error: err.append("multi-threading not allowed") - con = sqlite.connect(":memory:", check_same_thread=False) - err = [] - t = threading.Thread(target=run, kwargs={"con": con, "err": err}) - t.start() - t.join() - self.assertEqual(len(err), 0, "\n".join(err)) + with memory_database(check_same_thread=False) as con: + err = [] + t = threading.Thread(target=run, kwargs={"con": con, "err": err}) + t.start() + t.join() + self.assertEqual(len(err), 0, "\n".join(err)) class ConstructorTests(unittest.TestCase): @@ -1589,9 +1597,16 @@ def test_binary(self): b = sqlite.Binary(b"\0'") class ExtensionTests(unittest.TestCase): + def setUp(self): + self.con = sqlite.connect(":memory:") + self.cur = self.con.cursor() + + def tearDown(self): + self.cur.close() + self.con.close() + def test_script_string_sql(self): - con = sqlite.connect(":memory:") - cur = con.cursor() + cur = self.cur cur.executescript(""" -- bla bla /* a stupid comment */ @@ -1603,40 +1618,40 @@ def test_script_string_sql(self): self.assertEqual(res, 5) def test_script_syntax_error(self): - con = sqlite.connect(":memory:") - cur = con.cursor() with self.assertRaises(sqlite.OperationalError): - cur.executescript("create table test(x); asdf; create table test2(x)") + self.cur.executescript(""" + CREATE TABLE test(x); + asdf; + CREATE TABLE test2(x) + """) def test_script_error_normal(self): - con = sqlite.connect(":memory:") - cur = con.cursor() with self.assertRaises(sqlite.OperationalError): - cur.executescript("create table test(sadfsadfdsa); select foo from hurz;") + self.cur.executescript(""" + CREATE TABLE test(sadfsadfdsa); + SELECT foo FROM hurz; + """) def test_cursor_executescript_as_bytes(self): - con = sqlite.connect(":memory:") - cur = con.cursor() with self.assertRaises(TypeError): - cur.executescript(b"create table test(foo); insert into test(foo) values (5);") + self.cur.executescript(b""" + CREATE TABLE test(foo); + INSERT INTO test(foo) VALUES (5); + """) def test_cursor_executescript_with_null_characters(self): - con = sqlite.connect(":memory:") - cur = con.cursor() with self.assertRaises(ValueError): - cur.executescript(""" - create table a(i);\0 - insert into a(i) values (5); - """) + self.cur.executescript(""" + CREATE TABLE a(i);\0 + INSERT INTO a(i) VALUES (5); + """) def test_cursor_executescript_with_surrogates(self): - con = sqlite.connect(":memory:") - cur = con.cursor() with self.assertRaises(UnicodeEncodeError): - cur.executescript(""" - create table a(s); - insert into a(s) values ('\ud8ff'); - """) + self.cur.executescript(""" + CREATE TABLE a(s); + INSERT INTO a(s) VALUES ('\ud8ff'); + """) def test_cursor_executescript_too_large_script(self): msg = "query string is too large" @@ -1646,19 +1661,18 @@ def test_cursor_executescript_too_large_script(self): cx.executescript("select 'too large'".ljust(lim+1)) def test_cursor_executescript_tx_control(self): - con = sqlite.connect(":memory:") + con = self.con con.execute("begin") self.assertTrue(con.in_transaction) con.executescript("select 1") self.assertFalse(con.in_transaction) def test_connection_execute(self): - con = sqlite.connect(":memory:") - result = con.execute("select 5").fetchone()[0] + result = self.con.execute("select 5").fetchone()[0] self.assertEqual(result, 5, "Basic test of Connection.execute") def test_connection_executemany(self): - con = sqlite.connect(":memory:") + con = self.con con.execute("create table test(foo)") con.executemany("insert into test(foo) values (?)", [(3,), (4,)]) result = con.execute("select foo from test order by foo").fetchall() @@ -1666,47 +1680,44 @@ def test_connection_executemany(self): self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany") def test_connection_executescript(self): - con = sqlite.connect(":memory:") - con.executescript("create table test(foo); insert into test(foo) values (5);") + con = self.con + con.executescript(""" + CREATE TABLE test(foo); + INSERT INTO test(foo) VALUES (5); + """) result = con.execute("select foo from test").fetchone()[0] self.assertEqual(result, 5, "Basic test of Connection.executescript") + class ClosedConTests(unittest.TestCase): + def check(self, fn, *args, **kwds): + regex = "Cannot operate on a closed database." + with self.assertRaisesRegex(sqlite.ProgrammingError, regex): + fn(*args, **kwds) + + def setUp(self): + self.con = sqlite.connect(":memory:") + self.cur = self.con.cursor() + self.con.close() + def test_closed_con_cursor(self): - con = sqlite.connect(":memory:") - con.close() - with self.assertRaises(sqlite.ProgrammingError): - cur = con.cursor() + self.check(self.con.cursor) def test_closed_con_commit(self): - con = sqlite.connect(":memory:") - con.close() - with self.assertRaises(sqlite.ProgrammingError): - con.commit() + self.check(self.con.commit) def test_closed_con_rollback(self): - con = sqlite.connect(":memory:") - con.close() - with self.assertRaises(sqlite.ProgrammingError): - con.rollback() + self.check(self.con.rollback) def test_closed_cur_execute(self): - con = sqlite.connect(":memory:") - cur = con.cursor() - con.close() - with self.assertRaises(sqlite.ProgrammingError): - cur.execute("select 4") + self.check(self.cur.execute, "select 4") def test_closed_create_function(self): - con = sqlite.connect(":memory:") - con.close() - def f(x): return 17 - with self.assertRaises(sqlite.ProgrammingError): - con.create_function("foo", 1, f) + def f(x): + return 17 + self.check(self.con.create_function, "foo", 1, f) def test_closed_create_aggregate(self): - con = sqlite.connect(":memory:") - con.close() class Agg: def __init__(self): pass @@ -1714,34 +1725,25 @@ def step(self, x): pass def finalize(self): return 17 - with self.assertRaises(sqlite.ProgrammingError): - con.create_aggregate("foo", 1, Agg) + self.check(self.con.create_aggregate, "foo", 1, Agg) def test_closed_set_authorizer(self): - con = sqlite.connect(":memory:") - con.close() def authorizer(*args): return sqlite.DENY - with self.assertRaises(sqlite.ProgrammingError): - con.set_authorizer(authorizer) + self.check(self.con.set_authorizer, authorizer) def test_closed_set_progress_callback(self): - con = sqlite.connect(":memory:") - con.close() - def progress(): pass - with self.assertRaises(sqlite.ProgrammingError): - con.set_progress_handler(progress, 100) + def progress(): + pass + self.check(self.con.set_progress_handler, progress, 100) def test_closed_call(self): - con = sqlite.connect(":memory:") - con.close() - with self.assertRaises(sqlite.ProgrammingError): - con() + self.check(self.con) + -class ClosedCurTests(unittest.TestCase): +class ClosedCurTests(MemoryDatabaseMixin, unittest.TestCase): def test_closed(self): - con = sqlite.connect(":memory:") - cur = con.cursor() + cur = self.cx.cursor() cur.close() for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"): @@ -1852,7 +1854,7 @@ def test_on_conflict_replace(self): @requires_subprocess() class MultiprocessTests(unittest.TestCase): - CONNECTION_TIMEOUT = SHORT_TIMEOUT / 1000. # Defaults to 30 ms + CONNECTION_TIMEOUT = 0 # Disable the busy timeout. def tearDown(self): unlink(TESTFN) diff --git a/Lib/test/test_sqlite3/test_dump.py b/Lib/test/test_sqlite3/test_dump.py index d0c24b9c60e613..14a18c1ad37102 100644 --- a/Lib/test/test_sqlite3/test_dump.py +++ b/Lib/test/test_sqlite3/test_dump.py @@ -1,17 +1,12 @@ # Author: Paul Kippes import unittest -import sqlite3 as sqlite -from .test_dbapi import memory_database +from .util import memory_database +from .util import MemoryDatabaseMixin -class DumpTests(unittest.TestCase): - def setUp(self): - self.cx = sqlite.connect(":memory:") - self.cu = self.cx.cursor() - def tearDown(self): - self.cx.close() +class DumpTests(MemoryDatabaseMixin, unittest.TestCase): def test_table_dump(self): expected_sqls = [ @@ -117,6 +112,26 @@ def __getitem__(self, index): got = list(self.cx.iterdump()) self.assertEqual(expected, got) + def test_dump_virtual_tables(self): + # gh-64662 + expected = [ + "BEGIN TRANSACTION;", + "PRAGMA writable_schema=ON;", + ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','test','test',0,'CREATE VIRTUAL TABLE test USING fts4(example)');"), + "CREATE TABLE 'test_content'(docid INTEGER PRIMARY KEY, 'c0example');", + "CREATE TABLE 'test_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", + ("CREATE TABLE 'test_segdir'(level INTEGER,idx INTEGER,start_block INTEGER," + "leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));"), + "CREATE TABLE 'test_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", + "CREATE TABLE 'test_stat'(id INTEGER PRIMARY KEY, value BLOB);", + "PRAGMA writable_schema=OFF;", + "COMMIT;" + ] + self.cu.execute("CREATE VIRTUAL TABLE test USING fts4(example)") + actual = list(self.cx.iterdump()) + self.assertEqual(expected, actual) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index 7c36135ecadccd..48d35b54a2e239 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -24,6 +24,9 @@ import sqlite3 as sqlite from collections.abc import Sequence +from .util import memory_database +from .util import MemoryDatabaseMixin + def dict_factory(cursor, row): d = {} @@ -45,10 +48,12 @@ class OkFactory(sqlite.Connection): def __init__(self, *args, **kwargs): sqlite.Connection.__init__(self, *args, **kwargs) - for factory in DefectFactory, OkFactory: - with self.subTest(factory=factory): - con = sqlite.connect(":memory:", factory=factory) - self.assertIsInstance(con, factory) + with memory_database(factory=OkFactory) as con: + self.assertIsInstance(con, OkFactory) + regex = "Base Connection.__init__ not called." + with self.assertRaisesRegex(sqlite.ProgrammingError, regex): + with memory_database(factory=DefectFactory) as con: + self.assertIsInstance(con, DefectFactory) def test_connection_factory_relayed_call(self): # gh-95132: keyword args must not be passed as positional args @@ -57,26 +62,30 @@ def __init__(self, *args, **kwargs): kwargs["isolation_level"] = None super(Factory, self).__init__(*args, **kwargs) - con = sqlite.connect(":memory:", factory=Factory) - self.assertIsNone(con.isolation_level) - self.assertIsInstance(con, Factory) + with memory_database(factory=Factory) as con: + self.assertIsNone(con.isolation_level) + self.assertIsInstance(con, Factory) def test_connection_factory_as_positional_arg(self): class Factory(sqlite.Connection): def __init__(self, *args, **kwargs): super(Factory, self).__init__(*args, **kwargs) - con = sqlite.connect(":memory:", 5.0, 0, None, True, Factory) - self.assertIsNone(con.isolation_level) - self.assertIsInstance(con, Factory) + regex = ( + r"Passing more than 1 positional argument to _sqlite3.Connection\(\) " + r"is deprecated. Parameters 'timeout', 'detect_types', " + r"'isolation_level', 'check_same_thread', 'factory', " + r"'cached_statements' and 'uri' will become keyword-only " + r"parameters in Python 3.15." + ) + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + with memory_database(5.0, 0, None, True, Factory) as con: + self.assertIsNone(con.isolation_level) + self.assertIsInstance(con, Factory) + self.assertEqual(cm.filename, __file__) -class CursorFactoryTests(unittest.TestCase): - def setUp(self): - self.con = sqlite.connect(":memory:") - - def tearDown(self): - self.con.close() +class CursorFactoryTests(MemoryDatabaseMixin, unittest.TestCase): def test_is_instance(self): cur = self.con.cursor() @@ -94,9 +103,8 @@ def test_invalid_factory(self): # invalid callable returning non-cursor self.assertRaises(TypeError, self.con.cursor, lambda con: None) -class RowFactoryTestsBackwardsCompat(unittest.TestCase): - def setUp(self): - self.con = sqlite.connect(":memory:") + +class RowFactoryTestsBackwardsCompat(MemoryDatabaseMixin, unittest.TestCase): def test_is_produced_by_factory(self): cur = self.con.cursor(factory=MyCursor) @@ -105,12 +113,12 @@ def test_is_produced_by_factory(self): self.assertIsInstance(row, dict) cur.close() - def tearDown(self): - self.con.close() -class RowFactoryTests(unittest.TestCase): +class RowFactoryTests(MemoryDatabaseMixin, unittest.TestCase): + def setUp(self): - self.con = sqlite.connect(":memory:") + super().setUp() + self.con.row_factory = sqlite.Row def test_custom_factory(self): self.con.row_factory = lambda cur, row: list(row) @@ -118,7 +126,6 @@ def test_custom_factory(self): self.assertIsInstance(row, list) def test_sqlite_row_index(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a_1, 2 as b").fetchone() self.assertIsInstance(row, sqlite.Row) @@ -149,7 +156,6 @@ def test_sqlite_row_index(self): row[complex()] # index must be int or string def test_sqlite_row_index_unicode(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as \xff").fetchone() self.assertEqual(row["\xff"], 1) with self.assertRaises(IndexError): @@ -159,7 +165,6 @@ def test_sqlite_row_index_unicode(self): def test_sqlite_row_slice(self): # A sqlite.Row can be sliced like a list. - self.con.row_factory = sqlite.Row row = self.con.execute("select 1, 2, 3, 4").fetchone() self.assertEqual(row[0:0], ()) self.assertEqual(row[0:1], (1,)) @@ -176,8 +181,7 @@ def test_sqlite_row_slice(self): self.assertEqual(row[3:0:-2], (4, 2)) def test_sqlite_row_iter(self): - """Checks if the row object is iterable""" - self.con.row_factory = sqlite.Row + # Checks if the row object is iterable. row = self.con.execute("select 1 as a, 2 as b").fetchone() # Is iterable in correct order and produces valid results: @@ -189,23 +193,20 @@ def test_sqlite_row_iter(self): self.assertEqual(items, [1, 2]) def test_sqlite_row_as_tuple(self): - """Checks if the row object can be converted to a tuple""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be converted to a tuple. row = self.con.execute("select 1 as a, 2 as b").fetchone() t = tuple(row) self.assertEqual(t, (row['a'], row['b'])) def test_sqlite_row_as_dict(self): - """Checks if the row object can be correctly converted to a dictionary""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be correctly converted to a dictionary. row = self.con.execute("select 1 as a, 2 as b").fetchone() d = dict(row) self.assertEqual(d["a"], row["a"]) self.assertEqual(d["b"], row["b"]) def test_sqlite_row_hash_cmp(self): - """Checks if the row object compares and hashes correctly""" - self.con.row_factory = sqlite.Row + # Checks if the row object compares and hashes correctly. row_1 = self.con.execute("select 1 as a, 2 as b").fetchone() row_2 = self.con.execute("select 1 as a, 2 as b").fetchone() row_3 = self.con.execute("select 1 as a, 3 as b").fetchone() @@ -238,30 +239,29 @@ def test_sqlite_row_hash_cmp(self): self.assertEqual(hash(row_1), hash(row_2)) def test_sqlite_row_as_sequence(self): - """ Checks if the row object can act like a sequence """ - self.con.row_factory = sqlite.Row + # Checks if the row object can act like a sequence. row = self.con.execute("select 1 as a, 2 as b").fetchone() as_tuple = tuple(row) self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) self.assertIsInstance(row, Sequence) + def test_sqlite_row_keys(self): + # Checks if the row object can return a list of columns as strings. + row = self.con.execute("select 1 as a, 2 as b").fetchone() + self.assertEqual(row.keys(), ['a', 'b']) + def test_fake_cursor_class(self): # Issue #24257: Incorrect use of PyObject_IsInstance() caused # segmentation fault. # Issue #27861: Also applies for cursor factory. class FakeCursor(str): __class__ = sqlite.Cursor - self.con.row_factory = sqlite.Row self.assertRaises(TypeError, self.con.cursor, FakeCursor) self.assertRaises(TypeError, sqlite.Row, FakeCursor(), ()) - def tearDown(self): - self.con.close() -class TextFactoryTests(unittest.TestCase): - def setUp(self): - self.con = sqlite.connect(":memory:") +class TextFactoryTests(MemoryDatabaseMixin, unittest.TestCase): def test_unicode(self): austria = "Österreich" @@ -282,15 +282,17 @@ def test_custom(self): self.assertEqual(type(row[0]), str, "type of row[0] must be unicode") self.assertTrue(row[0].endswith("reich"), "column must contain original data") - def tearDown(self): - self.con.close() class TextFactoryTestsWithEmbeddedZeroBytes(unittest.TestCase): + def setUp(self): self.con = sqlite.connect(":memory:") self.con.execute("create table test (value text)") self.con.execute("insert into test (value) values (?)", ("a\x00b",)) + def tearDown(self): + self.con.close() + def test_string(self): # text_factory defaults to str row = self.con.execute("select value from test").fetchone() @@ -316,9 +318,6 @@ def test_custom(self): self.assertIs(type(row[0]), bytes) self.assertEqual(row[0], b"a\x00b") - def tearDown(self): - self.con.close() - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_hooks.py b/Lib/test/test_sqlite3/test_hooks.py index 89230c08cc9143..49e72f8fcfbcbd 100644 --- a/Lib/test/test_sqlite3/test_hooks.py +++ b/Lib/test/test_sqlite3/test_hooks.py @@ -26,34 +26,31 @@ from test.support.os_helper import TESTFN, unlink -from test.test_sqlite3.test_dbapi import memory_database, cx_limit -from test.test_sqlite3.test_userfunctions import with_tracebacks +from .util import memory_database, cx_limit, with_tracebacks +from .util import MemoryDatabaseMixin -class CollationTests(unittest.TestCase): +class CollationTests(MemoryDatabaseMixin, unittest.TestCase): + def test_create_collation_not_string(self): - con = sqlite.connect(":memory:") with self.assertRaises(TypeError): - con.create_collation(None, lambda x, y: (x > y) - (x < y)) + self.con.create_collation(None, lambda x, y: (x > y) - (x < y)) def test_create_collation_not_callable(self): - con = sqlite.connect(":memory:") with self.assertRaises(TypeError) as cm: - con.create_collation("X", 42) + self.con.create_collation("X", 42) self.assertEqual(str(cm.exception), 'parameter must be callable') def test_create_collation_not_ascii(self): - con = sqlite.connect(":memory:") - con.create_collation("collä", lambda x, y: (x > y) - (x < y)) + self.con.create_collation("collä", lambda x, y: (x > y) - (x < y)) def test_create_collation_bad_upper(self): class BadUpperStr(str): def upper(self): return None - con = sqlite.connect(":memory:") mycoll = lambda x, y: -((x > y) - (x < y)) - con.create_collation(BadUpperStr("mycoll"), mycoll) - result = con.execute(""" + self.con.create_collation(BadUpperStr("mycoll"), mycoll) + result = self.con.execute(""" select x from ( select 'a' as x union @@ -68,8 +65,7 @@ def mycoll(x, y): # reverse order return -((x > y) - (x < y)) - con = sqlite.connect(":memory:") - con.create_collation("mycoll", mycoll) + self.con.create_collation("mycoll", mycoll) sql = """ select x from ( select 'a' as x @@ -79,21 +75,20 @@ def mycoll(x, y): select 'c' as x ) order by x collate mycoll """ - result = con.execute(sql).fetchall() + result = self.con.execute(sql).fetchall() self.assertEqual(result, [('c',), ('b',), ('a',)], msg='the expected order was not returned') - con.create_collation("mycoll", None) + self.con.create_collation("mycoll", None) with self.assertRaises(sqlite.OperationalError) as cm: - result = con.execute(sql).fetchall() + result = self.con.execute(sql).fetchall() self.assertEqual(str(cm.exception), 'no such collation sequence: mycoll') def test_collation_returns_large_integer(self): def mycoll(x, y): # reverse order return -((x > y) - (x < y)) * 2**32 - con = sqlite.connect(":memory:") - con.create_collation("mycoll", mycoll) + self.con.create_collation("mycoll", mycoll) sql = """ select x from ( select 'a' as x @@ -103,7 +98,7 @@ def mycoll(x, y): select 'c' as x ) order by x collate mycoll """ - result = con.execute(sql).fetchall() + result = self.con.execute(sql).fetchall() self.assertEqual(result, [('c',), ('b',), ('a',)], msg="the expected order was not returned") @@ -112,7 +107,7 @@ def test_collation_register_twice(self): Register two different collation functions under the same name. Verify that the last one is actually used. """ - con = sqlite.connect(":memory:") + con = self.con con.create_collation("mycoll", lambda x, y: (x > y) - (x < y)) con.create_collation("mycoll", lambda x, y: -((x > y) - (x < y))) result = con.execute(""" @@ -126,25 +121,26 @@ def test_deregister_collation(self): Register a collation, then deregister it. Make sure an error is raised if we try to use it. """ - con = sqlite.connect(":memory:") + con = self.con con.create_collation("mycoll", lambda x, y: (x > y) - (x < y)) con.create_collation("mycoll", None) with self.assertRaises(sqlite.OperationalError) as cm: con.execute("select 'a' as x union select 'b' as x order by x collate mycoll") self.assertEqual(str(cm.exception), 'no such collation sequence: mycoll') -class ProgressTests(unittest.TestCase): + +class ProgressTests(MemoryDatabaseMixin, unittest.TestCase): + def test_progress_handler_used(self): """ Test that the progress handler is invoked once it is set. """ - con = sqlite.connect(":memory:") progress_calls = [] def progress(): progress_calls.append(None) return 0 - con.set_progress_handler(progress, 1) - con.execute(""" + self.con.set_progress_handler(progress, 1) + self.con.execute(""" create table foo(a, b) """) self.assertTrue(progress_calls) @@ -153,7 +149,7 @@ def test_opcode_count(self): """ Test that the opcode argument is respected. """ - con = sqlite.connect(":memory:") + con = self.con progress_calls = [] def progress(): progress_calls.append(None) @@ -176,11 +172,10 @@ def test_cancel_operation(self): """ Test that returning a non-zero value stops the operation in progress. """ - con = sqlite.connect(":memory:") def progress(): return 1 - con.set_progress_handler(progress, 1) - curs = con.cursor() + self.con.set_progress_handler(progress, 1) + curs = self.con.cursor() self.assertRaises( sqlite.OperationalError, curs.execute, @@ -190,7 +185,7 @@ def test_clear_handler(self): """ Test that setting the progress handler to None clears the previously set handler. """ - con = sqlite.connect(":memory:") + con = self.con action = 0 def progress(): nonlocal action @@ -203,31 +198,42 @@ def progress(): @with_tracebacks(ZeroDivisionError, name="bad_progress") def test_error_in_progress_handler(self): - con = sqlite.connect(":memory:") def bad_progress(): 1 / 0 - con.set_progress_handler(bad_progress, 1) + self.con.set_progress_handler(bad_progress, 1) with self.assertRaises(sqlite.OperationalError): - con.execute(""" + self.con.execute(""" create table foo(a, b) """) @with_tracebacks(ZeroDivisionError, name="bad_progress") def test_error_in_progress_handler_result(self): - con = sqlite.connect(":memory:") class BadBool: def __bool__(self): 1 / 0 def bad_progress(): return BadBool() - con.set_progress_handler(bad_progress, 1) + self.con.set_progress_handler(bad_progress, 1) with self.assertRaises(sqlite.OperationalError): - con.execute(""" + self.con.execute(""" create table foo(a, b) """) + def test_progress_handler_keyword_args(self): + regex = ( + r"Passing keyword argument 'progress_handler' to " + r"_sqlite3.Connection.set_progress_handler\(\) is deprecated. " + r"Parameter 'progress_handler' will become positional-only in " + r"Python 3.15." + ) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.set_progress_handler(progress_handler=lambda: None, n=1) + self.assertEqual(cm.filename, __file__) + + +class TraceCallbackTests(MemoryDatabaseMixin, unittest.TestCase): -class TraceCallbackTests(unittest.TestCase): @contextlib.contextmanager def check_stmt_trace(self, cx, expected): try: @@ -242,12 +248,11 @@ def test_trace_callback_used(self): """ Test that the trace callback is invoked once it is set. """ - con = sqlite.connect(":memory:") traced_statements = [] def trace(statement): traced_statements.append(statement) - con.set_trace_callback(trace) - con.execute("create table foo(a, b)") + self.con.set_trace_callback(trace) + self.con.execute("create table foo(a, b)") self.assertTrue(traced_statements) self.assertTrue(any("create table foo" in stmt for stmt in traced_statements)) @@ -255,7 +260,7 @@ def test_clear_trace_callback(self): """ Test that setting the trace callback to None clears the previously set callback. """ - con = sqlite.connect(":memory:") + con = self.con traced_statements = [] def trace(statement): traced_statements.append(statement) @@ -269,7 +274,7 @@ def test_unicode_content(self): Test that the statement can contain unicode literals. """ unicode_value = '\xf6\xe4\xfc\xd6\xc4\xdc\xdf\u20ac' - con = sqlite.connect(":memory:") + con = self.con traced_statements = [] def trace(statement): traced_statements.append(statement) @@ -347,6 +352,18 @@ def test_trace_bad_handler(self): cx.set_trace_callback(lambda stmt: 5/0) cx.execute("select 1") + def test_trace_keyword_args(self): + regex = ( + r"Passing keyword argument 'trace_callback' to " + r"_sqlite3.Connection.set_trace_callback\(\) is deprecated. " + r"Parameter 'trace_callback' will become positional-only in " + r"Python 3.15." + ) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.set_trace_callback(trace_callback=lambda: None) + self.assertEqual(cm.filename, __file__) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_regression.py b/Lib/test/test_sqlite3/test_regression.py index 7e8221e7227e6e..db4e13222da9da 100644 --- a/Lib/test/test_sqlite3/test_regression.py +++ b/Lib/test/test_sqlite3/test_regression.py @@ -28,15 +28,12 @@ from test import support from unittest.mock import patch -from test.test_sqlite3.test_dbapi import memory_database, cx_limit +from .util import memory_database, cx_limit +from .util import MemoryDatabaseMixin -class RegressionTests(unittest.TestCase): - def setUp(self): - self.con = sqlite.connect(":memory:") - def tearDown(self): - self.con.close() +class RegressionTests(MemoryDatabaseMixin, unittest.TestCase): def test_pragma_user_version(self): # This used to crash pysqlite because this pragma command returns NULL for the column name @@ -45,28 +42,24 @@ def test_pragma_user_version(self): def test_pragma_schema_version(self): # This still crashed pysqlite <= 2.2.1 - con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES) - try: + with memory_database(detect_types=sqlite.PARSE_COLNAMES) as con: cur = self.con.cursor() cur.execute("pragma schema_version") - finally: - cur.close() - con.close() def test_statement_reset(self): # pysqlite 2.1.0 to 2.2.0 have the problem that not all statements are # reset before a rollback, but only those that are still in the # statement cache. The others are not accessible from the connection object. - con = sqlite.connect(":memory:", cached_statements=5) - cursors = [con.cursor() for x in range(5)] - cursors[0].execute("create table test(x)") - for i in range(10): - cursors[0].executemany("insert into test(x) values (?)", [(x,) for x in range(10)]) + with memory_database(cached_statements=5) as con: + cursors = [con.cursor() for x in range(5)] + cursors[0].execute("create table test(x)") + for i in range(10): + cursors[0].executemany("insert into test(x) values (?)", [(x,) for x in range(10)]) - for i in range(5): - cursors[i].execute(" " * i + "select x from test") + for i in range(5): + cursors[i].execute(" " * i + "select x from test") - con.rollback() + con.rollback() def test_column_name_with_spaces(self): cur = self.con.cursor() @@ -81,17 +74,15 @@ def test_statement_finalization_on_close_db(self): # cache when closing the database. statements that were still # referenced in cursors weren't closed and could provoke " # "OperationalError: Unable to close due to unfinalised statements". - con = sqlite.connect(":memory:") cursors = [] # default statement cache size is 100 for i in range(105): - cur = con.cursor() + cur = self.con.cursor() cursors.append(cur) cur.execute("select 1 x union select " + str(i)) - con.close() def test_on_conflict_rollback(self): - con = sqlite.connect(":memory:") + con = self.con con.execute("create table foo(x, unique(x) on conflict rollback)") con.execute("insert into foo(x) values (1)") try: @@ -126,16 +117,16 @@ def test_type_map_usage(self): a statement. This test exhibits the problem. """ SELECT = "select * from foo" - con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES) - cur = con.cursor() - cur.execute("create table foo(bar timestamp)") - with self.assertWarnsRegex(DeprecationWarning, "adapter"): - cur.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) - cur.execute(SELECT) - cur.execute("drop table foo") - cur.execute("create table foo(bar integer)") - cur.execute("insert into foo(bar) values (5)") - cur.execute(SELECT) + with memory_database(detect_types=sqlite.PARSE_DECLTYPES) as con: + cur = con.cursor() + cur.execute("create table foo(bar timestamp)") + with self.assertWarnsRegex(DeprecationWarning, "adapter"): + cur.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) + cur.execute(SELECT) + cur.execute("drop table foo") + cur.execute("create table foo(bar integer)") + cur.execute("insert into foo(bar) values (5)") + cur.execute(SELECT) def test_bind_mutating_list(self): # Issue41662: Crash when mutate a list of parameters during iteration. @@ -144,11 +135,11 @@ def __conform__(self, protocol): parameters.clear() return "..." parameters = [X(), 0] - con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES) - con.execute("create table foo(bar X, baz integer)") - # Should not crash - with self.assertRaises(IndexError): - con.execute("insert into foo(bar, baz) values (?, ?)", parameters) + with memory_database(detect_types=sqlite.PARSE_DECLTYPES) as con: + con.execute("create table foo(bar X, baz integer)") + # Should not crash + with self.assertRaises(IndexError): + con.execute("insert into foo(bar, baz) values (?, ?)", parameters) def test_error_msg_decode_error(self): # When porting the module to Python 3.0, the error message about @@ -173,7 +164,7 @@ def upper(self): def __del__(self): con.isolation_level = "" - con = sqlite.connect(":memory:") + con = self.con con.isolation_level = None for level in "", "DEFERRED", "IMMEDIATE", "EXCLUSIVE": with self.subTest(level=level): @@ -204,8 +195,7 @@ class Cursor(sqlite.Cursor): def __init__(self, con): pass - con = sqlite.connect(":memory:") - cur = Cursor(con) + cur = Cursor(self.con) with self.assertRaises(sqlite.ProgrammingError): cur.execute("select 4+5").fetchall() with self.assertRaisesRegex(sqlite.ProgrammingError, @@ -238,7 +228,9 @@ def test_auto_commit(self): 2.5.3 introduced a regression so that these could no longer be created. """ - con = sqlite.connect(":memory:", isolation_level=None) + with memory_database(isolation_level=None) as con: + self.assertIsNone(con.isolation_level) + self.assertFalse(con.in_transaction) def test_pragma_autocommit(self): """ @@ -273,9 +265,7 @@ def test_recursive_cursor_use(self): Recursively using a cursor, such as when reusing it from a generator led to segfaults. Now we catch recursive cursor usage and raise a ProgrammingError. """ - con = sqlite.connect(":memory:") - - cur = con.cursor() + cur = self.con.cursor() cur.execute("create table a (bar)") cur.execute("create table b (baz)") @@ -295,29 +285,30 @@ def test_convert_timestamp_microsecond_padding(self): since the microsecond string "456" actually represents "456000". """ - con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES) - cur = con.cursor() - cur.execute("CREATE TABLE t (x TIMESTAMP)") + with memory_database(detect_types=sqlite.PARSE_DECLTYPES) as con: + cur = con.cursor() + cur.execute("CREATE TABLE t (x TIMESTAMP)") - # Microseconds should be 456000 - cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.456')") + # Microseconds should be 456000 + cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.456')") - # Microseconds should be truncated to 123456 - cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.123456789')") + # Microseconds should be truncated to 123456 + cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.123456789')") - cur.execute("SELECT * FROM t") - with self.assertWarnsRegex(DeprecationWarning, "converter"): - values = [x[0] for x in cur.fetchall()] + cur.execute("SELECT * FROM t") + with self.assertWarnsRegex(DeprecationWarning, "converter"): + values = [x[0] for x in cur.fetchall()] - self.assertEqual(values, [ - datetime.datetime(2012, 4, 4, 15, 6, 0, 456000), - datetime.datetime(2012, 4, 4, 15, 6, 0, 123456), - ]) + self.assertEqual(values, [ + datetime.datetime(2012, 4, 4, 15, 6, 0, 456000), + datetime.datetime(2012, 4, 4, 15, 6, 0, 123456), + ]) def test_invalid_isolation_level_type(self): # isolation level is a string, not an integer - self.assertRaises(TypeError, - sqlite.connect, ":memory:", isolation_level=123) + regex = "isolation_level must be str or None" + with self.assertRaisesRegex(TypeError, regex): + memory_database(isolation_level=123).__enter__() def test_null_character(self): @@ -333,7 +324,7 @@ def test_null_character(self): cur.execute, query) def test_surrogates(self): - con = sqlite.connect(":memory:") + con = self.con self.assertRaises(UnicodeEncodeError, con, "select '\ud8ff'") self.assertRaises(UnicodeEncodeError, con, "select '\udcff'") cur = con.cursor() @@ -359,7 +350,7 @@ def test_commit_cursor_reset(self): to return rows multiple times when fetched from cursors after commit. See issues 10513 and 23129 for details. """ - con = sqlite.connect(":memory:") + con = self.con con.executescript(""" create table t(c); create table t2(c); @@ -391,10 +382,9 @@ def test_bpo31770(self): """ def callback(*args): pass - con = sqlite.connect(":memory:") - cur = sqlite.Cursor(con) + cur = sqlite.Cursor(self.con) ref = weakref.ref(cur, callback) - cur.__init__(con) + cur.__init__(self.con) del cur # The interpreter shouldn't crash when ref is collected. del ref @@ -425,6 +415,7 @@ def test_return_empty_bytestring(self): def test_table_lock_cursor_replace_stmt(self): with memory_database() as con: + con = self.con cur = con.cursor() cur.execute("create table t(t)") cur.executemany("insert into t values(?)", diff --git a/Lib/test/test_sqlite3/test_transactions.py b/Lib/test/test_sqlite3/test_transactions.py index 5d211dd47b0b6b..a3de7a7a82ec1c 100644 --- a/Lib/test/test_sqlite3/test_transactions.py +++ b/Lib/test/test_sqlite3/test_transactions.py @@ -24,22 +24,21 @@ import sqlite3 as sqlite from contextlib import contextmanager -from test.support import LOOPBACK_TIMEOUT from test.support.os_helper import TESTFN, unlink from test.support.script_helper import assert_python_ok -from test.test_sqlite3.test_dbapi import memory_database - - -TIMEOUT = LOOPBACK_TIMEOUT / 10 +from .util import memory_database +from .util import MemoryDatabaseMixin class TransactionTests(unittest.TestCase): def setUp(self): - self.con1 = sqlite.connect(TESTFN, timeout=TIMEOUT) + # We can disable the busy handlers, since we control + # the order of SQLite C API operations. + self.con1 = sqlite.connect(TESTFN, timeout=0) self.cur1 = self.con1.cursor() - self.con2 = sqlite.connect(TESTFN, timeout=TIMEOUT) + self.con2 = sqlite.connect(TESTFN, timeout=0) self.cur2 = self.con2.cursor() def tearDown(self): @@ -119,10 +118,8 @@ def test_raise_timeout(self): self.cur2.execute("insert into test(i) values (5)") def test_locking(self): - """ - This tests the improved concurrency with pysqlite 2.3.4. You needed - to roll back con2 before you could commit con1. - """ + # This tests the improved concurrency with pysqlite 2.3.4. You needed + # to roll back con2 before you could commit con1. self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") with self.assertRaises(sqlite.OperationalError): @@ -132,14 +129,14 @@ def test_locking(self): def test_rollback_cursor_consistency(self): """Check that cursors behave correctly after rollback.""" - con = sqlite.connect(":memory:") - cur = con.cursor() - cur.execute("create table test(x)") - cur.execute("insert into test(x) values (5)") - cur.execute("select 1 union select 2 union select 3") + with memory_database() as con: + cur = con.cursor() + cur.execute("create table test(x)") + cur.execute("insert into test(x) values (5)") + cur.execute("select 1 union select 2 union select 3") - con.rollback() - self.assertEqual(cur.fetchall(), [(1,), (2,), (3,)]) + con.rollback() + self.assertEqual(cur.fetchall(), [(1,), (2,), (3,)]) def test_multiple_cursors_and_iternext(self): # gh-94028: statements are cleared and reset in cursor iternext. @@ -218,10 +215,7 @@ def test_no_duplicate_rows_after_rollback_new_query(self): -class SpecialCommandTests(unittest.TestCase): - def setUp(self): - self.con = sqlite.connect(":memory:") - self.cur = self.con.cursor() +class SpecialCommandTests(MemoryDatabaseMixin, unittest.TestCase): def test_drop_table(self): self.cur.execute("create table test(i)") @@ -233,14 +227,8 @@ def test_pragma(self): self.cur.execute("insert into test(i) values (5)") self.cur.execute("pragma count_changes=1") - def tearDown(self): - self.cur.close() - self.con.close() - -class TransactionalDDL(unittest.TestCase): - def setUp(self): - self.con = sqlite.connect(":memory:") +class TransactionalDDL(MemoryDatabaseMixin, unittest.TestCase): def test_ddl_does_not_autostart_transaction(self): # For backwards compatibility reasons, DDL statements should not @@ -268,9 +256,6 @@ def test_transactional_ddl(self): with self.assertRaises(sqlite.OperationalError): self.con.execute("select * from test") - def tearDown(self): - self.con.close() - class IsolationLevelFromInit(unittest.TestCase): CREATE = "create table t(t)" diff --git a/Lib/test/test_sqlite3/test_userfunctions.py b/Lib/test/test_sqlite3/test_userfunctions.py index 05c2fb3aa6f8f2..c6c3db159add64 100644 --- a/Lib/test/test_sqlite3/test_userfunctions.py +++ b/Lib/test/test_sqlite3/test_userfunctions.py @@ -21,54 +21,15 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import contextlib -import functools -import io -import re import sys import unittest import sqlite3 as sqlite from unittest.mock import Mock, patch -from test.support import bigmemtest, catch_unraisable_exception, gc_collect - -from test.test_sqlite3.test_dbapi import cx_limit - - -def with_tracebacks(exc, regex="", name=""): - """Convenience decorator for testing callback tracebacks.""" - def decorator(func): - _regex = re.compile(regex) if regex else None - @functools.wraps(func) - def wrapper(self, *args, **kwargs): - with catch_unraisable_exception() as cm: - # First, run the test with traceback enabled. - with check_tracebacks(self, cm, exc, _regex, name): - func(self, *args, **kwargs) - - # Then run the test with traceback disabled. - func(self, *args, **kwargs) - return wrapper - return decorator - - -@contextlib.contextmanager -def check_tracebacks(self, cm, exc, regex, obj_name): - """Convenience context manager for testing callback tracebacks.""" - sqlite.enable_callback_tracebacks(True) - try: - buf = io.StringIO() - with contextlib.redirect_stderr(buf): - yield - - self.assertEqual(cm.unraisable.exc_type, exc) - if regex: - msg = str(cm.unraisable.exc_value) - self.assertIsNotNone(regex.search(msg)) - if obj_name: - self.assertEqual(cm.unraisable.object.__name__, obj_name) - finally: - sqlite.enable_callback_tracebacks(False) +from test.support import bigmemtest, gc_collect + +from .util import cx_limit, memory_database +from .util import with_tracebacks def func_returntext(): @@ -405,19 +366,19 @@ def test_func_deterministic_keyword_only(self): def test_function_destructor_via_gc(self): # See bpo-44304: The destructor of the user function can # crash if is called without the GIL from the gc functions - dest = sqlite.connect(':memory:') def md5sum(t): return - dest.create_function("md5", 1, md5sum) - x = dest("create table lang (name, first_appeared)") - del md5sum, dest + with memory_database() as dest: + dest.create_function("md5", 1, md5sum) + x = dest("create table lang (name, first_appeared)") + del md5sum, dest - y = [x] - y.append(y) + y = [x] + y.append(y) - del x,y - gc_collect() + del x,y + gc_collect() @with_tracebacks(OverflowError) def test_func_return_too_large_int(self): @@ -460,6 +421,29 @@ def test_func_return_illegal_value(self): self.assertRaisesRegex(sqlite.OperationalError, msg, self.con.execute, "select badreturn()") + def test_func_keyword_args(self): + regex = ( + r"Passing keyword arguments 'name', 'narg' and 'func' to " + r"_sqlite3.Connection.create_function\(\) is deprecated. " + r"Parameters 'name', 'narg' and 'func' will become " + r"positional-only in Python 3.15." + ) + + def noop(): + return None + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.create_function("noop", 0, func=noop) + self.assertEqual(cm.filename, __file__) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.create_function("noop", narg=0, func=noop) + self.assertEqual(cm.filename, __file__) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.create_function(name="noop", narg=0, func=noop) + self.assertEqual(cm.filename, __file__) + class WindowSumInt: def __init__(self): @@ -514,6 +498,10 @@ def setUp(self): """ self.con.create_window_function("sumint", 1, WindowSumInt) + def tearDown(self): + self.cur.close() + self.con.close() + def test_win_sum_int(self): self.cur.execute(self.query % "sumint") self.assertEqual(self.cur.fetchall(), self.expected) @@ -634,6 +622,7 @@ def setUp(self): """) cur.execute("insert into test(t, i, f, n, b) values (?, ?, ?, ?, ?)", ("foo", 5, 3.14, None, memoryview(b"blob"),)) + cur.close() self.con.create_aggregate("nostep", 1, AggrNoStep) self.con.create_aggregate("nofinalize", 1, AggrNoFinalize) @@ -646,9 +635,7 @@ def setUp(self): self.con.create_aggregate("aggtxt", 1, AggrText) def tearDown(self): - #self.cur.close() - #self.con.close() - pass + self.con.close() def test_aggr_error_on_create(self): with self.assertRaises(sqlite.OperationalError): @@ -750,6 +737,27 @@ def test_aggr_text(self): val = cur.fetchone()[0] self.assertEqual(val, txt) + def test_agg_keyword_args(self): + regex = ( + r"Passing keyword arguments 'name', 'n_arg' and 'aggregate_class' to " + r"_sqlite3.Connection.create_aggregate\(\) is deprecated. " + r"Parameters 'name', 'n_arg' and 'aggregate_class' will become " + r"positional-only in Python 3.15." + ) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.create_aggregate("test", 1, aggregate_class=AggrText) + self.assertEqual(cm.filename, __file__) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.create_aggregate("test", n_arg=1, aggregate_class=AggrText) + self.assertEqual(cm.filename, __file__) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.create_aggregate(name="test", n_arg=0, + aggregate_class=AggrText) + self.assertEqual(cm.filename, __file__) + class AuthorizerTests(unittest.TestCase): @staticmethod @@ -775,7 +783,7 @@ def setUp(self): self.con.set_authorizer(self.authorizer_cb) def tearDown(self): - pass + self.con.close() def test_table_access(self): with self.assertRaises(sqlite.DatabaseError) as cm: @@ -792,6 +800,18 @@ def test_clear_authorizer(self): self.con.execute("select * from t2") self.con.execute("select c2 from t1") + def test_authorizer_keyword_args(self): + regex = ( + r"Passing keyword argument 'authorizer_callback' to " + r"_sqlite3.Connection.set_authorizer\(\) is deprecated. " + r"Parameter 'authorizer_callback' will become positional-only in " + r"Python 3.15." + ) + + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + self.con.set_authorizer(authorizer_callback=lambda: None) + self.assertEqual(cm.filename, __file__) + class AuthorizerRaiseExceptionTests(AuthorizerTests): @staticmethod diff --git a/Lib/test/test_sqlite3/util.py b/Lib/test/test_sqlite3/util.py new file mode 100644 index 00000000000000..5599823838beea --- /dev/null +++ b/Lib/test/test_sqlite3/util.py @@ -0,0 +1,77 @@ +import contextlib +import functools +import io +import re +import sqlite3 +import test.support + + +# Helper for temporary memory databases +def memory_database(*args, **kwargs): + cx = sqlite3.connect(":memory:", *args, **kwargs) + return contextlib.closing(cx) + + +# Temporarily limit a database connection parameter +@contextlib.contextmanager +def cx_limit(cx, category=sqlite3.SQLITE_LIMIT_SQL_LENGTH, limit=128): + try: + _prev = cx.setlimit(category, limit) + yield limit + finally: + cx.setlimit(category, _prev) + + +def with_tracebacks(exc, regex="", name=""): + """Convenience decorator for testing callback tracebacks.""" + def decorator(func): + _regex = re.compile(regex) if regex else None + @functools.wraps(func) + def wrapper(self, *args, **kwargs): + with test.support.catch_unraisable_exception() as cm: + # First, run the test with traceback enabled. + with check_tracebacks(self, cm, exc, _regex, name): + func(self, *args, **kwargs) + + # Then run the test with traceback disabled. + func(self, *args, **kwargs) + return wrapper + return decorator + + +@contextlib.contextmanager +def check_tracebacks(self, cm, exc, regex, obj_name): + """Convenience context manager for testing callback tracebacks.""" + sqlite3.enable_callback_tracebacks(True) + try: + buf = io.StringIO() + with contextlib.redirect_stderr(buf): + yield + + self.assertEqual(cm.unraisable.exc_type, exc) + if regex: + msg = str(cm.unraisable.exc_value) + self.assertIsNotNone(regex.search(msg)) + if obj_name: + self.assertEqual(cm.unraisable.object.__name__, obj_name) + finally: + sqlite3.enable_callback_tracebacks(False) + + +class MemoryDatabaseMixin: + + def setUp(self): + self.con = sqlite3.connect(":memory:") + self.cur = self.con.cursor() + + def tearDown(self): + self.cur.close() + self.con.close() + + @property + def cx(self): + return self.con + + @property + def cu(self): + return self.cur diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 6117ca3fdba1b7..06304dcb4ec7b8 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -10,11 +10,14 @@ from test.support import threading_helper from test.support import warnings_helper from test.support import asyncore +import re import socket import select +import struct import time import enum import gc +import http.client import os import errno import pprint @@ -57,10 +60,10 @@ PROTOCOL_TO_TLS_VERSION[proto] = ver def data_file(*name): - return os.path.join(os.path.dirname(__file__), *name) + return os.path.join(os.path.dirname(__file__), "certdata", *name) # The custom key and certificate files used in test_ssl are generated -# using Lib/test/make_ssl_certs.py. +# using Lib/test/certdata/make_ssl_certs.py. # Other certificates are simply fetched from the internet servers they # are meant to authenticate. @@ -638,7 +641,7 @@ def test_openssl111_deprecations(self): def bad_cert_test(self, certfile): """Check that trying to use the given client certificate fails""" certfile = os.path.join(os.path.dirname(__file__) or os.curdir, - certfile) + "certdata", certfile) sock = socket.socket() self.addCleanup(sock.close) with self.assertRaises(ssl.SSLError): @@ -2179,6 +2182,7 @@ def test_timeout_connect_ex(self): self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'Needs IPv6') + @support.requires_resource('walltime') def test_get_server_certificate_ipv6(self): with socket_helper.transient_internet('ipv6.google.com'): _test_get_server_certificate(self, 'ipv6.google.com', 443) @@ -2737,6 +2741,7 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, class ThreadedTests(unittest.TestCase): + @support.requires_resource('walltime') def test_echo(self): """Basic test of an SSL client connecting to a server""" if support.verbose: @@ -3304,12 +3309,12 @@ def test_socketserver(self): # try to connect if support.verbose: sys.stdout.write('\n') - with open(CERTFILE, 'rb') as f: + # Get this test file itself: + with open(__file__, 'rb') as f: d1 = f.read() d2 = '' # now fetch the same data from the HTTPS server - url = 'https://localhost:%d/%s' % ( - server.port, os.path.split(CERTFILE)[1]) + url = f'https://localhost:{server.port}/test_ssl.py' context = ssl.create_default_context(cafile=SIGNING_CA) f = urllib.request.urlopen(url, context=context) try: @@ -4659,6 +4664,254 @@ def sni_cb(sock, servername, ctx): s.connect((HOST, server.port)) +def set_socket_so_linger_on_with_zero_timeout(sock): + sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)) + + +class TestPreHandshakeClose(unittest.TestCase): + """Verify behavior of close sockets with received data before to the handshake. + """ + + class SingleConnectionTestServerThread(threading.Thread): + + def __init__(self, *, name, call_after_accept, timeout=None): + self.call_after_accept = call_after_accept + self.received_data = b'' # set by .run() + self.wrap_error = None # set by .run() + self.listener = None # set by .start() + self.port = None # set by .start() + if timeout is None: + self.timeout = support.SHORT_TIMEOUT + else: + self.timeout = timeout + super().__init__(name=name) + + def __enter__(self): + self.start() + return self + + def __exit__(self, *args): + try: + if self.listener: + self.listener.close() + except OSError: + pass + self.join() + self.wrap_error = None # avoid dangling references + + def start(self): + self.ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + self.ssl_ctx.verify_mode = ssl.CERT_REQUIRED + self.ssl_ctx.load_verify_locations(cafile=ONLYCERT) + self.ssl_ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY) + self.listener = socket.socket() + self.port = socket_helper.bind_port(self.listener) + self.listener.settimeout(self.timeout) + self.listener.listen(1) + super().start() + + def run(self): + try: + conn, address = self.listener.accept() + except TimeoutError: + # on timeout, just close the listener + return + finally: + self.listener.close() + + with conn: + if self.call_after_accept(conn): + return + try: + tls_socket = self.ssl_ctx.wrap_socket(conn, server_side=True) + except OSError as err: # ssl.SSLError inherits from OSError + self.wrap_error = err + else: + try: + self.received_data = tls_socket.recv(400) + except OSError: + pass # closed, protocol error, etc. + + def non_linux_skip_if_other_okay_error(self, err): + if sys.platform == "linux": + return # Expect the full test setup to always work on Linux. + if (isinstance(err, ConnectionResetError) or + (isinstance(err, OSError) and err.errno == errno.EINVAL) or + re.search('wrong.version.number', getattr(err, "reason", ""), re.I)): + # On Windows the TCP RST leads to a ConnectionResetError + # (ECONNRESET) which Linux doesn't appear to surface to userspace. + # If wrap_socket() winds up on the "if connected:" path and doing + # the actual wrapping... we get an SSLError from OpenSSL. Typically + # WRONG_VERSION_NUMBER. While appropriate, neither is the scenario + # we're specifically trying to test. The way this test is written + # is known to work on Linux. We'll skip it anywhere else that it + # does not present as doing so. + try: + self.skipTest(f"Could not recreate conditions on {sys.platform}:" + f" {err=}") + finally: + # gh-108342: Explicitly break the reference cycle + err = None + + # If maintaining this conditional winds up being a problem. + # just turn this into an unconditional skip anything but Linux. + # The important thing is that our CI has the logic covered. + + def test_preauth_data_to_tls_server(self): + server_accept_called = threading.Event() + ready_for_server_wrap_socket = threading.Event() + + def call_after_accept(unused): + server_accept_called.set() + if not ready_for_server_wrap_socket.wait(support.SHORT_TIMEOUT): + raise RuntimeError("wrap_socket event never set, test may fail.") + return False # Tell the server thread to continue. + + server = self.SingleConnectionTestServerThread( + call_after_accept=call_after_accept, + name="preauth_data_to_tls_server") + self.enterContext(server) # starts it & unittest.TestCase stops it. + + with socket.socket() as client: + client.connect(server.listener.getsockname()) + # This forces an immediate connection close via RST on .close(). + set_socket_so_linger_on_with_zero_timeout(client) + client.setblocking(False) + + server_accept_called.wait() + client.send(b"DELETE /data HTTP/1.0\r\n\r\n") + client.close() # RST + + ready_for_server_wrap_socket.set() + server.join() + + wrap_error = server.wrap_error + server.wrap_error = None + try: + self.assertEqual(b"", server.received_data) + self.assertIsInstance(wrap_error, OSError) # All platforms. + self.non_linux_skip_if_other_okay_error(wrap_error) + self.assertIsInstance(wrap_error, ssl.SSLError) + self.assertIn("before TLS handshake with data", wrap_error.args[1]) + self.assertIn("before TLS handshake with data", wrap_error.reason) + self.assertNotEqual(0, wrap_error.args[0]) + self.assertIsNone(wrap_error.library, msg="attr must exist") + finally: + # gh-108342: Explicitly break the reference cycle + wrap_error = None + server = None + + def test_preauth_data_to_tls_client(self): + server_can_continue_with_wrap_socket = threading.Event() + client_can_continue_with_wrap_socket = threading.Event() + + def call_after_accept(conn_to_client): + if not server_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT): + print("ERROR: test client took too long") + + # This forces an immediate connection close via RST on .close(). + set_socket_so_linger_on_with_zero_timeout(conn_to_client) + conn_to_client.send( + b"HTTP/1.0 307 Temporary Redirect\r\n" + b"Location: https://example.com/someone-elses-server\r\n" + b"\r\n") + conn_to_client.close() # RST + client_can_continue_with_wrap_socket.set() + return True # Tell the server to stop. + + server = self.SingleConnectionTestServerThread( + call_after_accept=call_after_accept, + name="preauth_data_to_tls_client") + self.enterContext(server) # starts it & unittest.TestCase stops it. + # Redundant; call_after_accept sets SO_LINGER on the accepted conn. + set_socket_so_linger_on_with_zero_timeout(server.listener) + + with socket.socket() as client: + client.connect(server.listener.getsockname()) + server_can_continue_with_wrap_socket.set() + + if not client_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT): + self.fail("test server took too long") + ssl_ctx = ssl.create_default_context() + try: + tls_client = ssl_ctx.wrap_socket( + client, server_hostname="localhost") + except OSError as err: # SSLError inherits from OSError + wrap_error = err + received_data = b"" + else: + wrap_error = None + received_data = tls_client.recv(400) + tls_client.close() + + server.join() + try: + self.assertEqual(b"", received_data) + self.assertIsInstance(wrap_error, OSError) # All platforms. + self.non_linux_skip_if_other_okay_error(wrap_error) + self.assertIsInstance(wrap_error, ssl.SSLError) + self.assertIn("before TLS handshake with data", wrap_error.args[1]) + self.assertIn("before TLS handshake with data", wrap_error.reason) + self.assertNotEqual(0, wrap_error.args[0]) + self.assertIsNone(wrap_error.library, msg="attr must exist") + finally: + # gh-108342: Explicitly break the reference cycle + wrap_error = None + server = None + + def test_https_client_non_tls_response_ignored(self): + server_responding = threading.Event() + + class SynchronizedHTTPSConnection(http.client.HTTPSConnection): + def connect(self): + # Call clear text HTTP connect(), not the encrypted HTTPS (TLS) + # connect(): wrap_socket() is called manually below. + http.client.HTTPConnection.connect(self) + + # Wait for our fault injection server to have done its thing. + if not server_responding.wait(support.SHORT_TIMEOUT) and support.verbose: + sys.stdout.write("server_responding event never set.") + self.sock = self._context.wrap_socket( + self.sock, server_hostname=self.host) + + def call_after_accept(conn_to_client): + # This forces an immediate connection close via RST on .close(). + set_socket_so_linger_on_with_zero_timeout(conn_to_client) + conn_to_client.send( + b"HTTP/1.0 402 Payment Required\r\n" + b"\r\n") + conn_to_client.close() # RST + server_responding.set() + return True # Tell the server to stop. + + timeout = 2.0 + server = self.SingleConnectionTestServerThread( + call_after_accept=call_after_accept, + name="non_tls_http_RST_responder", + timeout=timeout) + self.enterContext(server) # starts it & unittest.TestCase stops it. + # Redundant; call_after_accept sets SO_LINGER on the accepted conn. + set_socket_so_linger_on_with_zero_timeout(server.listener) + + connection = SynchronizedHTTPSConnection( + server.listener.getsockname()[0], + port=server.port, + context=ssl.create_default_context(), + timeout=timeout, + ) + + # There are lots of reasons this raises as desired, long before this + # test was added. Sending the request requires a successful TLS wrapped + # socket; that fails if the connection is broken. It may seem pointless + # to test this. It serves as an illustration of something that we never + # want to happen... properly not happening. + with self.assertRaises(OSError): + connection.request("HEAD", "/test", headers={"Host": "localhost"}) + response = connection.getresponse() + + server.join() + + class TestEnumerations(unittest.TestCase): def test_tlsversion(self): diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 4e74bb374c93bf..e06f9cabf4366b 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -144,7 +144,9 @@ def test_windows_feature_macros(self): "PyDict_DelItem", "PyDict_DelItemString", "PyDict_GetItem", + "PyDict_GetItemRef", "PyDict_GetItemString", + "PyDict_GetItemStringRef", "PyDict_GetItemWithError", "PyDict_Items", "PyDict_Keys", @@ -373,6 +375,7 @@ def test_windows_feature_macros(self): "PyList_Type", "PyLongRangeIter_Type", "PyLong_AsDouble", + "PyLong_AsInt", "PyLong_AsLong", "PyLong_AsLongAndOverflow", "PyLong_AsLongLong", @@ -402,6 +405,8 @@ def test_windows_feature_macros(self): "PyMapping_GetOptionalItemString", "PyMapping_HasKey", "PyMapping_HasKeyString", + "PyMapping_HasKeyStringWithError", + "PyMapping_HasKeyWithError", "PyMapping_Items", "PyMapping_Keys", "PyMapping_Length", @@ -539,6 +544,8 @@ def test_windows_feature_macros(self): "PyObject_GetTypeData", "PyObject_HasAttr", "PyObject_HasAttrString", + "PyObject_HasAttrStringWithError", + "PyObject_HasAttrWithError", "PyObject_Hash", "PyObject_HashNotImplemented", "PyObject_Init", @@ -763,6 +770,8 @@ def test_windows_feature_macros(self): "PyUnicode_DecodeUnicodeEscape", "PyUnicode_EncodeFSDefault", "PyUnicode_EncodeLocale", + "PyUnicode_EqualToUTF8", + "PyUnicode_EqualToUTF8AndSize", "PyUnicode_FSConverter", "PyUnicode_FSDecoder", "PyUnicode_Find", @@ -844,6 +853,7 @@ def test_windows_feature_macros(self): "Py_InitializeEx", "Py_Is", "Py_IsFalse", + "Py_IsFinalizing", "Py_IsInitialized", "Py_IsNone", "Py_IsTrue", diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index 4ba37aed2dc9db..0eced2fcf98376 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -122,8 +122,11 @@ def test_mode(self): st_mode, modestr = self.get_mode() self.assertEqual(modestr, '-rwx------') self.assertS_IS("REG", st_mode) - self.assertEqual(self.statmod.S_IMODE(st_mode), + imode = self.statmod.S_IMODE(st_mode) + self.assertEqual(imode, self.statmod.S_IRWXU) + self.assertEqual(self.statmod.filemode(imode), + '?rwx------') os.chmod(TESTFN, 0o070) st_mode, modestr = self.get_mode() @@ -238,6 +241,7 @@ def test_file_attribute_constants(self): self.assertEqual(value, modvalue, key) +@unittest.skipIf(c_stat is None, 'need _stat extension') class TestFilemodeCStat(TestFilemode, unittest.TestCase): statmod = c_stat diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index f0fa6454b1f91a..b24fc3c3d077fe 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -28,6 +28,12 @@ # === Helper functions and class === +# Test copied from Lib/test/test_math.py +# detect evidence of double-rounding: fsum is not always correctly +# rounded on machines that suffer from double rounding. +x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer +HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4) + def sign(x): """Return -1.0 for negatives, including -0.0, otherwise +1.0.""" return math.copysign(1, x) @@ -692,14 +698,6 @@ def test_check_all(self): 'missing name "%s" in __all__' % name) -class DocTests(unittest.TestCase): - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -OO and above") - def test_doc_tests(self): - failed, tried = doctest.testmod(statistics, optionflags=doctest.ELLIPSIS) - self.assertGreater(tried, 0) - self.assertEqual(failed, 0) - class StatisticsErrorTest(unittest.TestCase): def test_has_exception(self): errmsg = ( @@ -2139,6 +2137,7 @@ def test_integer_sqrt_of_frac_rto(self): self.assertTrue(m * (r - 1)**2 < n < m * (r + 1)**2) @requires_IEEE_754 + @support.requires_resource('cpu') def test_float_sqrt_of_frac(self): def is_root_correctly_rounded(x: Fraction, root: float) -> bool: @@ -2455,6 +2454,11 @@ def f(x): data = random.choices(range(100), k=k) q1, q2, q3 = quantiles(data, method='inclusive') self.assertEqual(q2, statistics.median(data)) + # Base case with a single data point: When estimating quantiles from + # a sample, we want to be able to add one sample point at a time, + # getting increasingly better estimates. + self.assertEqual(quantiles([10], n=4), [10.0, 10.0, 10.0]) + self.assertEqual(quantiles([10], n=4, method='exclusive'), [10.0, 10.0, 10.0]) def test_equal_inputs(self): quantiles = statistics.quantiles @@ -2505,7 +2509,7 @@ def test_error_cases(self): with self.assertRaises(ValueError): quantiles([10, 20, 30], method='X') # method is unknown with self.assertRaises(StatisticsError): - quantiles([10], n=4) # not enough data points + quantiles([], n=4) # not enough data points with self.assertRaises(TypeError): quantiles([10, None, 30], n=4) # data is non-numeric @@ -2564,6 +2568,79 @@ def test_different_scales(self): self.assertAlmostEqual(statistics.correlation(x, y), 1) self.assertAlmostEqual(statistics.covariance(x, y), 0.1) + def test_sqrtprod_helper_function_fundamentals(self): + # Verify that results are close to sqrt(x * y) + for i in range(100): + x = random.expovariate() + y = random.expovariate() + expected = math.sqrt(x * y) + actual = statistics._sqrtprod(x, y) + with self.subTest(x=x, y=y, expected=expected, actual=actual): + self.assertAlmostEqual(expected, actual) + + x, y, target = 0.8035720646477457, 0.7957468097636939, 0.7996498651651661 + self.assertEqual(statistics._sqrtprod(x, y), target) + self.assertNotEqual(math.sqrt(x * y), target) + + # Test that range extremes avoid underflow and overflow + smallest = sys.float_info.min * sys.float_info.epsilon + self.assertEqual(statistics._sqrtprod(smallest, smallest), smallest) + biggest = sys.float_info.max + self.assertEqual(statistics._sqrtprod(biggest, biggest), biggest) + + # Check special values and the sign of the result + special_values = [0.0, -0.0, 1.0, -1.0, 4.0, -4.0, + math.nan, -math.nan, math.inf, -math.inf] + for x, y in itertools.product(special_values, repeat=2): + try: + expected = math.sqrt(x * y) + except ValueError: + expected = 'ValueError' + try: + actual = statistics._sqrtprod(x, y) + except ValueError: + actual = 'ValueError' + with self.subTest(x=x, y=y, expected=expected, actual=actual): + if isinstance(expected, str) and expected == 'ValueError': + self.assertEqual(actual, 'ValueError') + continue + self.assertIsInstance(actual, float) + if math.isnan(expected): + self.assertTrue(math.isnan(actual)) + continue + self.assertEqual(actual, expected) + self.assertEqual(sign(actual), sign(expected)) + + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "accuracy not guaranteed on machines with double rounding") + @support.cpython_only # Allow for a weaker sumprod() implmentation + def test_sqrtprod_helper_function_improved_accuracy(self): + # Test a known example where accuracy is improved + x, y, target = 0.8035720646477457, 0.7957468097636939, 0.7996498651651661 + self.assertEqual(statistics._sqrtprod(x, y), target) + self.assertNotEqual(math.sqrt(x * y), target) + + def reference_value(x: float, y: float) -> float: + x = decimal.Decimal(x) + y = decimal.Decimal(y) + with decimal.localcontext() as ctx: + ctx.prec = 200 + return float((x * y).sqrt()) + + # Verify that the new function with improved accuracy + # agrees with a reference value more often than old version. + new_agreements = 0 + old_agreements = 0 + for i in range(10_000): + x = random.expovariate() + y = random.expovariate() + new = statistics._sqrtprod(x, y) + old = math.sqrt(x * y) + ref = reference_value(x, y) + new_agreements += (new == ref) + old_agreements += (old == ref) + self.assertGreater(new_agreements, old_agreements) def test_correlation_spearman(self): # https://statistics.laerd.com/statistical-guides/spearmans-rank-order-correlation-statistical-guide-2.php @@ -2770,6 +2847,7 @@ def test_cdf(self): self.assertTrue(math.isnan(X.cdf(float('NaN')))) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_inv_cdf(self): NormalDist = self.module.NormalDist @@ -3064,6 +3142,7 @@ def tearDown(self): def load_tests(loader, tests, ignore): """Used for doctest/unittest integration.""" tests.addTests(doctest.DocTestSuite()) + tests.addTests(doctest.DocTestSuite(statistics)) return tests diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py index a6bcc2455de15e..814ef111c5bec8 100644 --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -812,16 +812,6 @@ def test_isidentifier(self): self.assertFalse("©".isidentifier()) self.assertFalse("0".isidentifier()) - @support.cpython_only - @support.requires_legacy_unicode_capi - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_isidentifier_legacy(self): - u = 'ð–€ð–“ð–Žð–ˆð–”ð–‰ð–Š' - self.assertTrue(u.isidentifier()) - with warnings_helper.check_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertTrue(_testcapi.unicode_legacy_string(u).isidentifier()) - def test_isprintable(self): self.assertTrue("".isprintable()) self.assertTrue(" ".isprintable()) @@ -2489,26 +2479,6 @@ def test_getnewargs(self): self.assertEqual(args[0], text) self.assertEqual(len(args), 1) - @support.cpython_only - @support.requires_legacy_unicode_capi - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_resize(self): - for length in range(1, 100, 7): - # generate a fresh string (refcount=1) - text = 'a' * length + 'b' - - # fill wstr internal field - with self.assertWarns(DeprecationWarning): - abc = _testcapi.getargs_u(text) - self.assertEqual(abc, text) - - # resize text: wstr field must be cleared and then recomputed - text += 'c' - with self.assertWarns(DeprecationWarning): - abcdef = _testcapi.getargs_u(text) - self.assertNotEqual(abc, abcdef) - self.assertEqual(abcdef, text) - def test_compare(self): # Issue #17615 N = 10 diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 6b1f22f66fd157..c76649cdcd9cce 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -774,6 +774,10 @@ def test_error_propagation(fmt_str): test_error_propagation('N') test_error_propagation('n') + def test_repr(self): + s = struct.Struct('=i2H') + self.assertEqual(repr(s), f'Struct({s.format!r})') + class UnpackIteratorTest(unittest.TestCase): """ Tests for iterative unpacking (struct.Struct.iter_unpack). diff --git a/Lib/test/test_structseq.py b/Lib/test/test_structseq.py index a9fe193028ebe4..6aec63e2603412 100644 --- a/Lib/test/test_structseq.py +++ b/Lib/test/test_structseq.py @@ -1,4 +1,7 @@ +import copy import os +import pickle +import re import time import unittest @@ -89,10 +92,69 @@ def test_constructor(self): self.assertRaises(TypeError, t, "123") self.assertRaises(TypeError, t, "123", dict={}) self.assertRaises(TypeError, t, "123456789", dict=None) + self.assertRaises(TypeError, t, seq="123456789", dict={}) + + self.assertEqual(t("123456789"), tuple("123456789")) + self.assertEqual(t("123456789", {}), tuple("123456789")) + self.assertEqual(t("123456789", dict={}), tuple("123456789")) + self.assertEqual(t(sequence="123456789", dict={}), tuple("123456789")) + + self.assertEqual(t("1234567890"), tuple("123456789")) + self.assertEqual(t("1234567890").tm_zone, "0") + self.assertEqual(t("123456789", {"tm_zone": "some zone"}), tuple("123456789")) + self.assertEqual(t("123456789", {"tm_zone": "some zone"}).tm_zone, "some zone") s = "123456789" self.assertEqual("".join(t(s)), s) + def test_constructor_with_duplicate_fields(self): + t = time.struct_time + + error_message = re.escape("got duplicate or unexpected field name(s)") + with self.assertRaisesRegex(TypeError, error_message): + t("1234567890", dict={"tm_zone": "some zone"}) + with self.assertRaisesRegex(TypeError, error_message): + t("1234567890", dict={"tm_zone": "some zone", "tm_mon": 1}) + with self.assertRaisesRegex(TypeError, error_message): + t("1234567890", dict={"error": 0, "tm_zone": "some zone"}) + with self.assertRaisesRegex(TypeError, error_message): + t("1234567890", dict={"error": 0, "tm_zone": "some zone", "tm_mon": 1}) + + def test_constructor_with_duplicate_unnamed_fields(self): + assert os.stat_result.n_unnamed_fields > 0 + n_visible_fields = os.stat_result.n_sequence_fields + + r = os.stat_result(range(n_visible_fields), {'st_atime': -1.0}) + self.assertEqual(r.st_atime, -1.0) + self.assertEqual(r, tuple(range(n_visible_fields))) + + r = os.stat_result((*range(n_visible_fields), -1.0)) + self.assertEqual(r.st_atime, -1.0) + self.assertEqual(r, tuple(range(n_visible_fields))) + + with self.assertRaisesRegex(TypeError, + re.escape("got duplicate or unexpected field name(s)")): + os.stat_result((*range(n_visible_fields), -1.0), {'st_atime': -1.0}) + + def test_constructor_with_unknown_fields(self): + t = time.struct_time + + error_message = re.escape("got duplicate or unexpected field name(s)") + with self.assertRaisesRegex(TypeError, error_message): + t("123456789", dict={"tm_year": 0}) + with self.assertRaisesRegex(TypeError, error_message): + t("123456789", dict={"tm_year": 0, "tm_mon": 1}) + with self.assertRaisesRegex(TypeError, error_message): + t("123456789", dict={"tm_zone": "some zone", "tm_mon": 1}) + with self.assertRaisesRegex(TypeError, error_message): + t("123456789", dict={"tm_zone": "some zone", "error": 0}) + with self.assertRaisesRegex(TypeError, error_message): + t("123456789", dict={"error": 0, "tm_zone": "some zone", "tm_mon": 1}) + with self.assertRaisesRegex(TypeError, error_message): + t("123456789", dict={"error": 0}) + with self.assertRaisesRegex(TypeError, error_message): + t("123456789", dict={"tm_zone": "some zone", "error": 0}) + def test_eviltuple(self): class Exc(Exception): pass @@ -106,9 +168,78 @@ def __len__(self): self.assertRaises(Exc, time.struct_time, C()) - def test_reduce(self): + def test_pickling(self): t = time.gmtime() - x = t.__reduce__() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(t, proto) + t2 = pickle.loads(p) + self.assertEqual(t2.__class__, t.__class__) + self.assertEqual(t2, t) + self.assertEqual(t2.tm_year, t.tm_year) + self.assertEqual(t2.tm_zone, t.tm_zone) + + def test_pickling_with_unnamed_fields(self): + assert os.stat_result.n_unnamed_fields > 0 + + r = os.stat_result(range(os.stat_result.n_sequence_fields), + {'st_atime': 1.0, 'st_atime_ns': 2.0}) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(r, proto) + r2 = pickle.loads(p) + self.assertEqual(r2.__class__, r.__class__) + self.assertEqual(r2, r) + self.assertEqual(r2.st_mode, r.st_mode) + self.assertEqual(r2.st_atime, r.st_atime) + self.assertEqual(r2.st_atime_ns, r.st_atime_ns) + + def test_copying(self): + n_fields = time.struct_time.n_fields + t = time.struct_time([[i] for i in range(n_fields)]) + + t2 = copy.copy(t) + self.assertEqual(t2.__class__, t.__class__) + self.assertEqual(t2, t) + self.assertEqual(t2.tm_year, t.tm_year) + self.assertEqual(t2.tm_zone, t.tm_zone) + self.assertIs(t2[0], t[0]) + self.assertIs(t2.tm_year, t.tm_year) + + t3 = copy.deepcopy(t) + self.assertEqual(t3.__class__, t.__class__) + self.assertEqual(t3, t) + self.assertEqual(t3.tm_year, t.tm_year) + self.assertEqual(t3.tm_zone, t.tm_zone) + self.assertIsNot(t3[0], t[0]) + self.assertIsNot(t3.tm_year, t.tm_year) + + def test_copying_with_unnamed_fields(self): + assert os.stat_result.n_unnamed_fields > 0 + + n_sequence_fields = os.stat_result.n_sequence_fields + r = os.stat_result([[i] for i in range(n_sequence_fields)], + {'st_atime': [1.0], 'st_atime_ns': [2.0]}) + + r2 = copy.copy(r) + self.assertEqual(r2.__class__, r.__class__) + self.assertEqual(r2, r) + self.assertEqual(r2.st_mode, r.st_mode) + self.assertEqual(r2.st_atime, r.st_atime) + self.assertEqual(r2.st_atime_ns, r.st_atime_ns) + self.assertIs(r2[0], r[0]) + self.assertIs(r2.st_mode, r.st_mode) + self.assertIs(r2.st_atime, r.st_atime) + self.assertIs(r2.st_atime_ns, r.st_atime_ns) + + r3 = copy.deepcopy(r) + self.assertEqual(r3.__class__, r.__class__) + self.assertEqual(r3, r) + self.assertEqual(r3.st_mode, r.st_mode) + self.assertEqual(r3.st_atime, r.st_atime) + self.assertEqual(r3.st_atime_ns, r.st_atime_ns) + self.assertIsNot(r3[0], r[0]) + self.assertIsNot(r3.st_mode, r.st_mode) + self.assertIsNot(r3.st_atime, r.st_atime) + self.assertIsNot(r3.st_atime_ns, r.st_atime_ns) def test_extended_getslice(self): # Test extended slicing by comparing with list slicing. @@ -133,6 +264,84 @@ def test_match_args_with_unnamed_fields(self): self.assertEqual(os.stat_result.n_unnamed_fields, 3) self.assertEqual(os.stat_result.__match_args__, expected_args) + def test_copy_replace_all_fields_visible(self): + assert os.times_result.n_unnamed_fields == 0 + assert os.times_result.n_sequence_fields == os.times_result.n_fields + + t = os.times() + + # visible fields + self.assertEqual(copy.replace(t), t) + self.assertIsInstance(copy.replace(t), os.times_result) + self.assertEqual(copy.replace(t, user=1.5), (1.5, *t[1:])) + self.assertEqual(copy.replace(t, system=2.5), (t[0], 2.5, *t[2:])) + self.assertEqual(copy.replace(t, user=1.5, system=2.5), (1.5, 2.5, *t[2:])) + + # unknown fields + with self.assertRaisesRegex(TypeError, 'unexpected field name'): + copy.replace(t, error=-1) + with self.assertRaisesRegex(TypeError, 'unexpected field name'): + copy.replace(t, user=1, error=-1) + + def test_copy_replace_with_invisible_fields(self): + assert time.struct_time.n_unnamed_fields == 0 + assert time.struct_time.n_sequence_fields < time.struct_time.n_fields + + t = time.gmtime(0) + + # visible fields + t2 = copy.replace(t) + self.assertEqual(t2, (1970, 1, 1, 0, 0, 0, 3, 1, 0)) + self.assertIsInstance(t2, time.struct_time) + t3 = copy.replace(t, tm_year=2000) + self.assertEqual(t3, (2000, 1, 1, 0, 0, 0, 3, 1, 0)) + self.assertEqual(t3.tm_year, 2000) + t4 = copy.replace(t, tm_mon=2) + self.assertEqual(t4, (1970, 2, 1, 0, 0, 0, 3, 1, 0)) + self.assertEqual(t4.tm_mon, 2) + t5 = copy.replace(t, tm_year=2000, tm_mon=2) + self.assertEqual(t5, (2000, 2, 1, 0, 0, 0, 3, 1, 0)) + self.assertEqual(t5.tm_year, 2000) + self.assertEqual(t5.tm_mon, 2) + + # named invisible fields + self.assertTrue(hasattr(t, 'tm_zone'), f"{t} has no attribute 'tm_zone'") + with self.assertRaisesRegex(AttributeError, 'readonly attribute'): + t.tm_zone = 'some other zone' + self.assertEqual(t2.tm_zone, t.tm_zone) + self.assertEqual(t3.tm_zone, t.tm_zone) + self.assertEqual(t4.tm_zone, t.tm_zone) + t6 = copy.replace(t, tm_zone='some other zone') + self.assertEqual(t, t6) + self.assertEqual(t6.tm_zone, 'some other zone') + t7 = copy.replace(t, tm_year=2000, tm_zone='some other zone') + self.assertEqual(t7, (2000, 1, 1, 0, 0, 0, 3, 1, 0)) + self.assertEqual(t7.tm_year, 2000) + self.assertEqual(t7.tm_zone, 'some other zone') + + # unknown fields + with self.assertRaisesRegex(TypeError, 'unexpected field name'): + copy.replace(t, error=2) + with self.assertRaisesRegex(TypeError, 'unexpected field name'): + copy.replace(t, tm_year=2000, error=2) + with self.assertRaisesRegex(TypeError, 'unexpected field name'): + copy.replace(t, tm_zone='some other zone', error=2) + + def test_copy_replace_with_unnamed_fields(self): + assert os.stat_result.n_unnamed_fields > 0 + + r = os.stat_result(range(os.stat_result.n_sequence_fields)) + + error_message = re.escape('__replace__() is not supported') + with self.assertRaisesRegex(TypeError, error_message): + copy.replace(r) + with self.assertRaisesRegex(TypeError, error_message): + copy.replace(r, st_mode=1) + with self.assertRaisesRegex(TypeError, error_message): + copy.replace(r, error=2) + with self.assertRaisesRegex(TypeError, error_message): + copy.replace(r, st_mode=1, error=2) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 817eab0c8a7e19..a865df1082fba3 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -269,6 +269,7 @@ def test_check_output_stdin_with_input_arg(self): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): # check_output() function with timeout arg with self.assertRaises(subprocess.TimeoutExpired) as c: @@ -748,31 +749,36 @@ def test_pipesizes(self): @unittest.skipUnless(fcntl and hasattr(fcntl, 'F_GETPIPE_SZ'), 'fcntl.F_GETPIPE_SZ required for test.') def test_pipesize_default(self): - p = subprocess.Popen( + proc = subprocess.Popen( [sys.executable, "-c", 'import sys; sys.stdin.read(); sys.stdout.write("out"); ' 'sys.stderr.write("error!")'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, pipesize=-1) - try: - fp_r, fp_w = os.pipe() + + with proc: try: - default_pipesize = fcntl.fcntl(fp_w, fcntl.F_GETPIPE_SZ) - for fifo in [p.stdin, p.stdout, p.stderr]: - self.assertEqual( - fcntl.fcntl(fifo.fileno(), fcntl.F_GETPIPE_SZ), - default_pipesize) + fp_r, fp_w = os.pipe() + try: + default_read_pipesize = fcntl.fcntl(fp_r, fcntl.F_GETPIPE_SZ) + default_write_pipesize = fcntl.fcntl(fp_w, fcntl.F_GETPIPE_SZ) + finally: + os.close(fp_r) + os.close(fp_w) + + self.assertEqual( + fcntl.fcntl(proc.stdin.fileno(), fcntl.F_GETPIPE_SZ), + default_read_pipesize) + self.assertEqual( + fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETPIPE_SZ), + default_write_pipesize) + self.assertEqual( + fcntl.fcntl(proc.stderr.fileno(), fcntl.F_GETPIPE_SZ), + default_write_pipesize) + # On other platforms we cannot test the pipe size (yet). But above + # code using pipesize=-1 should not crash. finally: - os.close(fp_r) - os.close(fp_w) - # On other platforms we cannot test the pipe size (yet). But above - # code using pipesize=-1 should not crash. - p.stdin.close() - p.stdout.close() - p.stderr.close() - finally: - p.kill() - p.wait() + proc.kill() def test_env(self): newenv = os.environ.copy() @@ -1292,6 +1298,7 @@ def test_bufsize_equal_one_binary_mode(self): with self.assertWarnsRegex(RuntimeWarning, 'line buffering'): self._test_bufsize_equal_one(line, b'', universal_newlines=False) + @support.requires_resource('cpu') def test_leaking_fds_on_error(self): # see bug #5179: Popen leaks file descriptors to PIPEs if # the child fails to execute; this will eventually exhaust @@ -1642,6 +1649,7 @@ def test_check_output_stdin_with_input_arg(self): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): with self.assertRaises(subprocess.TimeoutExpired) as c: cp = self.run_python(( diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 664cf70b3cf0fa..43162c540b55ae 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -5,6 +5,9 @@ from test import shadowed_super +ADAPTIVE_WARMUP_DELAY = 2 + + class A: def f(self): return 'A' @@ -419,8 +422,47 @@ def test(name): super(MyType, type(mytype)).__setattr__(mytype, "bar", 1) self.assertEqual(mytype.bar, 1) - test("foo1") - test("foo2") + for _ in range(ADAPTIVE_WARMUP_DELAY): + test("foo1") + + def test_reassigned_new(self): + class A: + def __new__(cls): + pass + + def __init_subclass__(cls): + if "__new__" not in cls.__dict__: + cls.__new__ = cls.__new__ + + class B(A): + pass + + class C(B): + def __new__(cls): + return super().__new__(cls) + + for _ in range(ADAPTIVE_WARMUP_DELAY): + C() + + def test_mixed_staticmethod_hierarchy(self): + # This test is just a desugared version of `test_reassigned_new` + class A: + @staticmethod + def some(cls, *args, **kwargs): + self.assertFalse(args) + self.assertFalse(kwargs) + + class B(A): + def some(cls, *args, **kwargs): + return super().some(cls, *args, **kwargs) + + class C(B): + @staticmethod + def some(cls): + return super().some(cls) + + for _ in range(ADAPTIVE_WARMUP_DELAY): + C.some(C) if __name__ == "__main__": diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index cd1679dd23281c..97de81677b10bc 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -7,6 +7,7 @@ import stat import subprocess import sys +import sysconfig import tempfile import textwrap import unittest @@ -497,6 +498,7 @@ def check_options(self, args, func, expected=None): self.assertEqual(proc.stdout.rstrip(), repr(expected)) self.assertEqual(proc.returncode, 0) + @support.requires_resource('cpu') def test_args_from_interpreter_flags(self): # Test test.support.args_from_interpreter_flags() for opts in ( @@ -684,6 +686,157 @@ def test_has_strftime_extensions(self): else: self.assertTrue(support.has_strftime_extensions) + def test_get_recursion_depth(self): + # test support.get_recursion_depth() + code = textwrap.dedent(""" + from test import support + import sys + + def check(cond): + if not cond: + raise AssertionError("test failed") + + # depth 1 + check(support.get_recursion_depth() == 1) + + # depth 2 + def test_func(): + check(support.get_recursion_depth() == 2) + test_func() + + def test_recursive(depth, limit): + if depth >= limit: + # cannot call get_recursion_depth() at this depth, + # it can raise RecursionError + return + get_depth = support.get_recursion_depth() + print(f"test_recursive: {depth}/{limit}: " + f"get_recursion_depth() says {get_depth}") + check(get_depth == depth) + test_recursive(depth + 1, limit) + + # depth up to 25 + with support.infinite_recursion(max_depth=25): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit) + + # depth up to 500 + with support.infinite_recursion(max_depth=500): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit) + """) + script_helper.assert_python_ok("-c", code) + + def test_recursion(self): + # Test infinite_recursion() and get_recursion_available() functions. + def recursive_function(depth): + if depth: + recursive_function(depth - 1) + + for max_depth in (5, 25, 250): + with support.infinite_recursion(max_depth): + available = support.get_recursion_available() + + # Recursion up to 'available' additional frames should be OK. + recursive_function(available) + + # Recursion up to 'available+1' additional frames must raise + # RecursionError. Avoid self.assertRaises(RecursionError) which + # can consume more than 3 frames and so raises RecursionError. + try: + recursive_function(available + 1) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + # Test the bare minimumum: max_depth=3 + with support.infinite_recursion(3): + try: + recursive_function(3) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + def test_parse_memlimit(self): + parse = support._parse_memlimit + KiB = 1024 + MiB = KiB * 1024 + GiB = MiB * 1024 + TiB = GiB * 1024 + self.assertEqual(parse('0k'), 0) + self.assertEqual(parse('3k'), 3 * KiB) + self.assertEqual(parse('2.4m'), int(2.4 * MiB)) + self.assertEqual(parse('4g'), int(4 * GiB)) + self.assertEqual(parse('1t'), TiB) + + for limit in ('', '3', '3.5.10k', '10x'): + with self.subTest(limit=limit): + with self.assertRaises(ValueError): + parse(limit) + + def test_set_memlimit(self): + _4GiB = 4 * 1024 ** 3 + TiB = 1024 ** 4 + old_max_memuse = support.max_memuse + old_real_max_memuse = support.real_max_memuse + try: + if sys.maxsize > 2**32: + support.set_memlimit('4g') + self.assertEqual(support.max_memuse, _4GiB) + self.assertEqual(support.real_max_memuse, _4GiB) + + big = 2**100 // TiB + support.set_memlimit(f'{big}t') + self.assertEqual(support.max_memuse, sys.maxsize) + self.assertEqual(support.real_max_memuse, big * TiB) + else: + support.set_memlimit('4g') + self.assertEqual(support.max_memuse, sys.maxsize) + self.assertEqual(support.real_max_memuse, _4GiB) + finally: + support.max_memuse = old_max_memuse + support.real_max_memuse = old_real_max_memuse + + def test_copy_python_src_ignore(self): + # Get source directory + src_dir = sysconfig.get_config_var('abs_srcdir') + if not src_dir: + src_dir = sysconfig.get_config_var('srcdir') + src_dir = os.path.abspath(src_dir) + + # Check that the source code is available + if not os.path.exists(src_dir): + self.skipTest(f"cannot access Python source code directory:" + f" {src_dir!r}") + # Check that the landmark copy_python_src_ignore() expects is available + # (Previously we looked for 'Lib\os.py', which is always present on Windows.) + landmark = os.path.join(src_dir, 'Modules') + if not os.path.exists(landmark): + self.skipTest(f"cannot access Python source code directory:" + f" {landmark!r} landmark is missing") + + # Test support.copy_python_src_ignore() + + # Source code directory + ignored = {'.git', '__pycache__'} + names = os.listdir(src_dir) + self.assertEqual(support.copy_python_src_ignore(src_dir, names), + ignored | {'build'}) + + # Doc/ directory + path = os.path.join(src_dir, 'Doc') + self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), + ignored | {'build', 'venv'}) + + # Another directory + path = os.path.join(src_dir, 'Objects') + self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), + ignored) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled @@ -695,7 +848,6 @@ def test_has_strftime_extensions(self): # EnvironmentVarGuard # transient_internet # run_with_locale - # set_memlimit # bigmemtest # precisionbigmemtest # bigaddrspacetest diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 25714aecda3a15..82c1d7c856a1e5 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -40,6 +40,15 @@ def foo(): def namespace_test(): pass def namespace_test(): pass + +type Alias = int +type GenericAlias[T] = list[T] + +def generic_spam[T](a): + pass + +class GenericMine[T: int]: + pass """ @@ -59,6 +68,14 @@ class SymtableTest(unittest.TestCase): internal = find_block(spam, "internal") other_internal = find_block(spam, "other_internal") foo = find_block(top, "foo") + Alias = find_block(top, "Alias") + GenericAlias = find_block(top, "GenericAlias") + GenericAlias_inner = find_block(GenericAlias, "GenericAlias") + generic_spam = find_block(top, "generic_spam") + generic_spam_inner = find_block(generic_spam, "generic_spam") + GenericMine = find_block(top, "GenericMine") + GenericMine_inner = find_block(GenericMine, "GenericMine") + T = find_block(GenericMine, "T") def test_type(self): self.assertEqual(self.top.get_type(), "module") @@ -66,6 +83,15 @@ def test_type(self): self.assertEqual(self.a_method.get_type(), "function") self.assertEqual(self.spam.get_type(), "function") self.assertEqual(self.internal.get_type(), "function") + self.assertEqual(self.foo.get_type(), "function") + self.assertEqual(self.Alias.get_type(), "type alias") + self.assertEqual(self.GenericAlias.get_type(), "type parameter") + self.assertEqual(self.GenericAlias_inner.get_type(), "type alias") + self.assertEqual(self.generic_spam.get_type(), "type parameter") + self.assertEqual(self.generic_spam_inner.get_type(), "function") + self.assertEqual(self.GenericMine.get_type(), "type parameter") + self.assertEqual(self.GenericMine_inner.get_type(), "class") + self.assertEqual(self.T.get_type(), "TypeVar bound") def test_id(self): self.assertGreater(self.top.get_id(), 0) @@ -73,6 +99,11 @@ def test_id(self): self.assertGreater(self.a_method.get_id(), 0) self.assertGreater(self.spam.get_id(), 0) self.assertGreater(self.internal.get_id(), 0) + self.assertGreater(self.foo.get_id(), 0) + self.assertGreater(self.Alias.get_id(), 0) + self.assertGreater(self.GenericAlias.get_id(), 0) + self.assertGreater(self.generic_spam.get_id(), 0) + self.assertGreater(self.GenericMine.get_id(), 0) def test_optimized(self): self.assertFalse(self.top.is_optimized()) @@ -251,6 +282,10 @@ def test_symtable_repr(self): self.assertEqual(str(self.top), "") self.assertEqual(str(self.spam), "") + def test_symtable_entry_repr(self): + expected = f"" + self.assertEqual(repr(self.top._table), expected) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index f3d6cd7bad0eec..52fc3573ddb7e0 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1955,6 +1955,17 @@ def f(x: *b) ... SyntaxError: yield expression cannot be used within the definition of a generic + >>> f(**x, *y) + Traceback (most recent call last): + SyntaxError: iterable argument unpacking follows keyword argument unpacking + + >>> f(**x, *) + Traceback (most recent call last): + SyntaxError: iterable argument unpacking follows keyword argument unpacking + + >>> f(x, *:) + Traceback (most recent call last): + SyntaxError: invalid syntax """ import re @@ -2335,7 +2346,7 @@ def test_error_on_parser_stack_overflow(self): source = "-" * 100000 + "4" for mode in ["exec", "eval", "single"]: with self.subTest(mode=mode): - with self.assertRaises(MemoryError): + with self.assertRaisesRegex(MemoryError, r"too complex"): compile(source, "", mode) @support.cpython_only diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 37f75ad54387a0..da213506151594 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1,9 +1,11 @@ import builtins import codecs +import _datetime import gc import locale import operator import os +import random import struct import subprocess import sys @@ -14,14 +16,20 @@ from test.support.script_helper import assert_python_ok, assert_python_failure from test.support import threading_helper from test.support import import_helper +try: + from test.support import interpreters +except ImportError: + interpreters = None import textwrap import unittest import warnings -# count the number of test runs, used to create unique -# strings to intern in test_intern() -INTERN_NUMRUNS = 0 +def requires_subinterpreters(meth): + """Decorator to skip a test if subinterpreters are not supported.""" + return unittest.skipIf(interpreters is None, + 'subinterpreters required')(meth) + DICT_KEY_STRUCT_FORMAT = 'n2BI2n' @@ -167,7 +175,8 @@ def test_excepthook_bytes_filename(self): def test_excepthook(self): with test.support.captured_output("stderr") as stderr: - sys.excepthook(1, '1', 1) + with test.support.catch_unraisable_exception(): + sys.excepthook(1, '1', 1) self.assertTrue("TypeError: print_exception(): Exception expected for " \ "value, str found" in stderr.getvalue()) @@ -269,20 +278,29 @@ def test_switchinterval(self): finally: sys.setswitchinterval(orig) - def test_recursionlimit(self): + def test_getrecursionlimit(self): + limit = sys.getrecursionlimit() + self.assertIsInstance(limit, int) + self.assertGreater(limit, 1) + self.assertRaises(TypeError, sys.getrecursionlimit, 42) - oldlimit = sys.getrecursionlimit() - self.assertRaises(TypeError, sys.setrecursionlimit) - self.assertRaises(ValueError, sys.setrecursionlimit, -42) - sys.setrecursionlimit(10000) - self.assertEqual(sys.getrecursionlimit(), 10000) - sys.setrecursionlimit(oldlimit) + + def test_setrecursionlimit(self): + old_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(10_005) + self.assertEqual(sys.getrecursionlimit(), 10_005) + + self.assertRaises(TypeError, sys.setrecursionlimit) + self.assertRaises(ValueError, sys.setrecursionlimit, -42) + finally: + sys.setrecursionlimit(old_limit) def test_recursionlimit_recovery(self): if hasattr(sys, 'gettrace') and sys.gettrace(): self.skipTest('fatal error if run with a trace function') - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() def f(): f() try: @@ -301,35 +319,31 @@ def f(): with self.assertRaises(RecursionError): f() finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) @test.support.cpython_only - def test_setrecursionlimit_recursion_depth(self): + def test_setrecursionlimit_to_depth(self): # Issue #25274: Setting a low recursion limit must be blocked if the # current recursion depth is already higher than limit. - from _testinternalcapi import get_recursion_depth - - def set_recursion_limit_at_depth(depth, limit): - recursion_depth = get_recursion_depth() - if recursion_depth >= depth: - with self.assertRaises(RecursionError) as cm: - sys.setrecursionlimit(limit) - self.assertRegex(str(cm.exception), - "cannot set the recursion limit to [0-9]+ " - "at the recursion depth [0-9]+: " - "the limit is too low") - else: - set_recursion_limit_at_depth(depth, limit) - - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() try: - sys.setrecursionlimit(1000) - - for limit in (10, 25, 50, 75, 100, 150, 200): - set_recursion_limit_at_depth(limit, limit) + depth = support.get_recursion_depth() + with self.subTest(limit=sys.getrecursionlimit(), depth=depth): + # depth + 1 is OK + sys.setrecursionlimit(depth + 1) + + # reset the limit to be able to call self.assertRaises() + # context manager + sys.setrecursionlimit(old_limit) + with self.assertRaises(RecursionError) as cm: + sys.setrecursionlimit(depth) + self.assertRegex(str(cm.exception), + "cannot set the recursion limit to [0-9]+ " + "at the recursion depth [0-9]+: " + "the limit is too low") finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) def test_getwindowsversion(self): # Raise SkipTest if sys doesn't have getwindowsversion attribute @@ -497,7 +511,7 @@ def test_current_exceptions(self): # Spawn a thread that blocks at a known place. Then the main # thread does sys._current_frames(), and verifies that the frames # returned make sense. - entered_g = threading.Event() + g_raised = threading.Event() leave_g = threading.Event() thread_info = [] # the thread's id @@ -506,22 +520,19 @@ def f123(): def g456(): thread_info.append(threading.get_ident()) - entered_g.set() while True: try: raise ValueError("oops") except ValueError: + g_raised.set() if leave_g.wait(timeout=support.LONG_TIMEOUT): break t = threading.Thread(target=f123) t.start() - entered_g.wait() + g_raised.wait(timeout=support.LONG_TIMEOUT) try: - # At this point, t has finished its entered_g.set(), although it's - # impossible to guess whether it's still on that line or has moved on - # to its leave_g.wait(). self.assertEqual(len(thread_info), 1) thread_id = thread_info[0] @@ -680,10 +691,8 @@ def test_43581(self): self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding) def test_intern(self): - global INTERN_NUMRUNS - INTERN_NUMRUNS += 1 self.assertRaises(TypeError, sys.intern) - s = "never interned before" + str(INTERN_NUMRUNS) + s = "never interned before" + str(random.randrange(0, 10**9)) self.assertTrue(sys.intern(s) is s) s2 = s.swapcase().swapcase() self.assertTrue(sys.intern(s2) is s) @@ -699,6 +708,34 @@ def __hash__(self): self.assertRaises(TypeError, sys.intern, S("abc")) + @requires_subinterpreters + def test_subinterp_intern_dynamically_allocated(self): + s = "never interned before" + str(random.randrange(0, 10**9)) + t = sys.intern(s) + self.assertIs(t, s) + + interp = interpreters.create() + interp.run(textwrap.dedent(f''' + import sys + t = sys.intern({s!r}) + assert id(t) != {id(s)}, (id(t), {id(s)}) + assert id(t) != {id(t)}, (id(t), {id(t)}) + ''')) + + @requires_subinterpreters + def test_subinterp_intern_statically_allocated(self): + # See Tools/build/generate_global_objects.py for the list + # of strings that are always statically allocated. + s = '__init__' + t = sys.intern(s) + + interp = interpreters.create() + interp.run(textwrap.dedent(f''' + import sys + t = sys.intern({s!r}) + assert id(t) == {id(t)}, (id(t), {id(t)}) + ''')) + def test_sys_flags(self): self.assertTrue(sys.flags) attrs = ("debug", @@ -960,12 +997,12 @@ def test_debugmallocstats(self): "sys.getallocatedblocks unavailable on this build") def test_getallocatedblocks(self): try: - import _testcapi + import _testinternalcapi except ImportError: with_pymalloc = support.with_pymalloc() else: try: - alloc_name = _testcapi.pymem_getallocatorsname() + alloc_name = _testinternalcapi.pymem_getallocatorsname() except RuntimeError as exc: # "cannot get allocators name" (ex: tracemalloc is used) with_pymalloc = True @@ -1134,15 +1171,52 @@ def test_stdlib_dir(self): self.assertEqual(os.path.normpath(sys._stdlib_dir), os.path.normpath(expected)) + @unittest.skipUnless(hasattr(sys, 'getobjects'), 'need sys.getobjects()') + def test_getobjects(self): + # sys.getobjects(0) + all_objects = sys.getobjects(0) + self.assertIsInstance(all_objects, list) + self.assertGreater(len(all_objects), 0) + + # sys.getobjects(0, MyType) + class MyType: + pass + size = 100 + my_objects = [MyType() for _ in range(size)] + get_objects = sys.getobjects(0, MyType) + self.assertEqual(len(get_objects), size) + for obj in get_objects: + self.assertIsInstance(obj, MyType) + + # sys.getobjects(3, MyType) + get_objects = sys.getobjects(3, MyType) + self.assertEqual(len(get_objects), 3) + + @unittest.skipUnless(hasattr(sys, '_stats_on'), 'need Py_STATS build') + def test_pystats(self): + # Call the functions, just check that they don't crash + # Cannot save/restore state. + sys._stats_on() + sys._stats_off() + sys._stats_clear() + sys._stats_dump() + + @test.support.cpython_only + @unittest.skipUnless(hasattr(sys, 'abiflags'), 'need sys.abiflags') + def test_disable_gil_abi(self): + abi_threaded = 't' in sys.abiflags + py_nogil = (sysconfig.get_config_var('Py_NOGIL') == 1) + self.assertEqual(py_nogil, abi_threaded) + @test.support.cpython_only class UnraisableHookTest(unittest.TestCase): def write_unraisable_exc(self, exc, err_msg, obj): - import _testcapi + import _testinternalcapi import types err_msg2 = f"Exception ignored {err_msg}" try: - _testcapi.write_unraisable_exc(exc, err_msg, obj) + _testinternalcapi.write_unraisable_exc(exc, err_msg, obj) return types.SimpleNamespace(exc_type=type(exc), exc_value=exc, exc_traceback=exc.__traceback__, @@ -1506,7 +1580,7 @@ def delx(self): del self.__x x = property(getx, setx, delx, "") check(x, size('5Pi')) # PyCapsule - # XXX + check(_datetime.datetime_CAPI, size('6P')) # rangeiterator check(iter(range(1)), size('3l')) check(iter(range(2**65)), size('3P')) diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 49e076c77d167a..9e8936630de920 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -255,6 +255,25 @@ def g(p): (1, 'return', g_ident), ]) + def test_unfinished_generator(self): + def f(): + for i in range(2): + yield i + def g(p): + next(f()) + + f_ident = ident(f) + g_ident = ident(g) + self.check_events(g, [(1, 'call', g_ident), + (2, 'call', f_ident), + (2, 'return', f_ident), + # once more; the generator is being garbage collected + # and it will do a PY_THROW + (2, 'call', f_ident), + (2, 'return', f_ident), + (1, 'return', g_ident), + ]) + def test_stop_iteration(self): def f(): for i in range(2): @@ -439,7 +458,6 @@ def __del__(self): sys.setprofile(foo) self.assertEqual(sys.getprofile(), bar) - def test_same_object(self): def foo(*args): ... @@ -448,6 +466,18 @@ def foo(*args): del foo sys.setprofile(sys.getprofile()) + def test_profile_after_trace_opcodes(self): + def f(): + ... + + sys._getframe().f_trace_opcodes = True + prev_trace = sys.gettrace() + sys.settrace(lambda *args: None) + f() + sys.settrace(prev_trace) + sys.setprofile(lambda *args: None) + f() + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 4462b5c712d662..f02169602e4925 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -8,6 +8,7 @@ from functools import wraps import asyncio from test.support import import_helper +import contextlib support.requires_working_socket(module=True) @@ -40,6 +41,20 @@ async def asynciter(iterable): for x in iterable: yield x +def clean_asynciter(test): + @wraps(test) + async def wrapper(*args, **kwargs): + cleanups = [] + def wrapped_asynciter(iterable): + it = asynciter(iterable) + cleanups.append(it.aclose) + return it + try: + return await test(*args, **kwargs, asynciter=wrapped_asynciter) + finally: + while cleanups: + await cleanups.pop()() + return wrapper # A very basic example. If this fails, we're in deep trouble. def basic(): @@ -302,6 +317,13 @@ def generator_example(): [(5, 'line'), (5, 'return')]) +def lineno_matches_lasti(frame): + last_line = None + for start, end, line in frame.f_code.co_lines(): + if start <= frame.f_lasti < end: + last_line = line + return last_line == frame.f_lineno + class Tracer: def __init__(self, trace_line_events=None, trace_opcode_events=None): self.trace_line_events = trace_line_events @@ -315,6 +337,7 @@ def _reconfigure_frame(self, frame): frame.f_trace_opcodes = self.trace_opcode_events def trace(self, frame, event, arg): + assert lineno_matches_lasti(frame) self._reconfigure_frame(frame) self.events.append((frame.f_lineno, event)) return self.trace @@ -906,6 +929,35 @@ def func(): (6, 'line'), (6, 'return')]) + def test_finally_with_conditional(self): + + # See gh-105658 + condition = True + def func(): + try: + try: + raise Exception + finally: + if condition: + result = 1 + result = 2 + except: + result = 3 + return result + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (5, 'line'), + (6, 'line'), + (8, 'line'), + (9, 'line'), + (10, 'line'), + (10, 'return')]) + def test_break_to_continue1(self): def func(): @@ -1653,7 +1705,6 @@ def error_once(frame, event, arg): except Exception as ex: count = 0 tb = ex.__traceback__ - print(tb) while tb: if tb.tb_frame.f_code.co_name == "test_settrace_error": count += 1 @@ -1876,6 +1927,7 @@ def __init__(self, function, jumpFrom, jumpTo, event='line', def trace(self, frame, event, arg): if self.done: return + assert lineno_matches_lasti(frame) # frame.f_code.co_firstlineno is the first line of the decorator when # 'function' is decorated and the decorator may be written using # multiple physical lines when it is too long. Use the first line @@ -1922,6 +1974,8 @@ def no_jump_without_trace_function(): class JumpTestCase(unittest.TestCase): + unbound_locals = r"assigning None to [0-9]+ unbound local" + def setUp(self): self.addCleanup(sys.settrace, sys.gettrace()) sys.settrace(None) @@ -1933,33 +1987,47 @@ def compare_jump_output(self, expected, received): "Received: " + repr(received)) def run_test(self, func, jumpFrom, jumpTo, expected, error=None, - event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + event='line', decorated=False, warning=None): + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] - if error is None: + + with contextlib.ExitStack() as stack: + if error is not None: + stack.enter_context(self.assertRaisesRegex(*error)) + if warning is not None: + stack.enter_context(self.assertWarnsRegex(*warning)) func(output) - else: - with self.assertRaisesRegex(*error): - func(output) + sys.settrace(None) self.compare_jump_output(expected, output) def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None, - event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + event='line', decorated=False, warning=None): + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] - if error is None: + + with contextlib.ExitStack() as stack: + if error is not None: + stack.enter_context(self.assertRaisesRegex(*error)) + if warning is not None: + stack.enter_context(self.assertWarnsRegex(*warning)) asyncio.run(func(output)) - else: - with self.assertRaisesRegex(*error): - asyncio.run(func(output)) + sys.settrace(None) asyncio.set_event_loop_policy(None) self.compare_jump_output(expected, output) - def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): + def jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None): """Decorator that creates a test that makes a jump from one place to another in the following code. """ @@ -1967,11 +2035,11 @@ def decorator(func): @wraps(func) def test(self): self.run_test(func, jumpFrom, jumpTo, expected, - error=error, event=event, decorated=True) + error=error, event=event, decorated=True, warning=warning) return test return decorator - def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): + def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None): """Decorator that creates a test that makes a jump from one place to another in the following asynchronous code. """ @@ -1979,7 +2047,7 @@ def decorator(func): @wraps(func) def test(self): self.run_async_test(func, jumpFrom, jumpTo, expected, - error=error, event=event, decorated=True) + error=error, event=event, decorated=True, warning=warning) return test return decorator @@ -1996,7 +2064,7 @@ def test_jump_simple_backwards(output): output.append(1) output.append(2) - @jump_test(3, 5, [2, 5]) + @jump_test(3, 5, [2, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_out_of_block_forwards(output): for i in 1, 2: output.append(2) @@ -2015,7 +2083,8 @@ def test_jump_out_of_block_backwards(output): output.append(7) @async_jump_test(4, 5, [3, 5]) - async def test_jump_out_of_async_for_block_forwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_forwards(output, asynciter): for i in [1]: async for i in asynciter([1, 2]): output.append(3) @@ -2023,7 +2092,8 @@ async def test_jump_out_of_async_for_block_forwards(output): output.append(5) @async_jump_test(5, 2, [2, 4, 2, 4, 5, 6]) - async def test_jump_out_of_async_for_block_backwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_backwards(output, asynciter): for i in [1]: output.append(2) async for i in asynciter([1]): @@ -2082,7 +2152,7 @@ def test_jump_in_nested_finally_3(output): output.append(11) output.append(12) - @jump_test(5, 11, [2, 4], (ValueError, 'exception')) + @jump_test(5, 11, [2, 4], (ValueError, 'comes after the current code block')) def test_no_jump_over_return_try_finally_in_finally_block(output): try: output.append(2) @@ -2210,7 +2280,7 @@ def test_jump_within_except_block(output): output.append(6) output.append(7) - @jump_test(6, 1, [1, 5, 1, 5]) + @jump_test(6, 1, [1, 5, 1, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_over_try_except(output): output.append(1) try: @@ -2306,7 +2376,7 @@ def test_jump_out_of_complex_nested_blocks(output): output.append(11) output.append(12) - @jump_test(3, 5, [1, 2, 5]) + @jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_out_of_with_assignment(output): output.append(1) with tracecontext(output, 2) \ @@ -2314,7 +2384,7 @@ def test_jump_out_of_with_assignment(output): output.append(4) output.append(5) - @async_jump_test(3, 5, [1, 2, 5]) + @async_jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals)) async def test_jump_out_of_async_with_assignment(output): output.append(1) async with asynctracecontext(output, 2) \ @@ -2350,7 +2420,7 @@ def test_jump_over_break_in_try_finally_block(output): break output.append(13) - @jump_test(1, 7, [7, 8]) + @jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals)) def test_jump_over_for_block_before_else(output): output.append(1) if not output: # always false @@ -2361,7 +2431,7 @@ def test_jump_over_for_block_before_else(output): output.append(7) output.append(8) - @async_jump_test(1, 7, [7, 8]) + @async_jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals)) async def test_jump_over_async_for_block_before_else(output): output.append(1) if not output: # always false @@ -2436,6 +2506,7 @@ def test_no_jump_backwards_into_for_block(output): output.append(2) output.append(3) + @async_jump_test(3, 2, [2, 2], (ValueError, "can't jump into the body of a for loop")) async def test_no_jump_backwards_into_async_for_block(output): async for i in asynciter([1, 2]): @@ -2501,7 +2572,7 @@ def test_jump_backwards_into_try_except_block(output): output.append(6) # 'except' with a variable creates an implicit finally block - @jump_test(5, 7, [4, 7, 8]) + @jump_test(5, 7, [4, 7, 8], warning=(RuntimeWarning, unbound_locals)) def test_jump_between_except_blocks_2(output): try: 1/0 @@ -2664,7 +2735,7 @@ def test_large_function(self): output.append(x) # line 1007 return""" % ('\n' * 1000,), d) f = d['f'] - self.run_test(f, 2, 1007, [0]) + self.run_test(f, 2, 1007, [0], warning=(RuntimeWarning, self.unbound_locals)) def test_jump_to_firstlineno(self): # This tests that PDB can jump back to the first line in a @@ -2714,7 +2785,7 @@ def gen(): next(gen()) output.append(5) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_forward_over_listcomp(output): output.append(1) x = [i for i in range(10)] @@ -2722,13 +2793,13 @@ def test_jump_forward_over_listcomp(output): # checking for segfaults. # See https://github.com/python/cpython/issues/92311 - @jump_test(3, 1, []) + @jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals)) def test_jump_backward_over_listcomp(output): a = 1 x = [i for i in range(10)] c = 3 - @jump_test(8, 2, [2, 7, 2]) + @jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals)) def test_jump_backward_over_listcomp_v2(output): flag = False output.append(2) @@ -2739,19 +2810,19 @@ def test_jump_backward_over_listcomp_v2(output): output.append(7) output.append(8) - @async_jump_test(2, 3, [1, 3]) + @async_jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) async def test_jump_forward_over_async_listcomp(output): output.append(1) x = [i async for i in asynciter(range(10))] output.append(3) - @async_jump_test(3, 1, []) + @async_jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals)) async def test_jump_backward_over_async_listcomp(output): a = 1 x = [i async for i in asynciter(range(10))] c = 3 - @async_jump_test(8, 2, [2, 7, 2]) + @async_jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals)) async def test_jump_backward_over_async_listcomp_v2(output): flag = False output.append(2) @@ -2820,13 +2891,13 @@ def test_jump_with_null_on_stack_load_attr(output): ) output.append(15) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_extended_args_unpack_ex_simple(output): output.append(1) _, *_, _ = output.append(2) or "Spam" output.append(3) - @jump_test(3, 4, [1, 4, 4, 5]) + @jump_test(3, 4, [1, 4, 4, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_extended_args_unpack_ex_tricky(output): output.append(1) ( @@ -2834,6 +2905,7 @@ def test_jump_extended_args_unpack_ex_tricky(output): ) = output.append(4) or "Spam" output.append(5) + @support.requires_resource('cpu') def test_jump_extended_args_for_iter(self): # In addition to failing when extended arg handling is broken, this can # also hang for a *very* long time: @@ -2847,9 +2919,9 @@ def test_jump_extended_args_for_iter(self): namespace = {} exec("\n".join(source), namespace) f = namespace["f"] - self.run_test(f, 2, 100_000, [1, 100_000]) + self.run_test(f, 2, 100_000, [1, 100_000], warning=(RuntimeWarning, self.unbound_locals)) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_or_pop(output): output.append(1) _ = output.append(2) and "Spam" diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index b6dbf3d52cb4c3..2a6813f00bccc6 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -16,8 +16,11 @@ from sysconfig import (get_paths, get_platform, get_config_vars, get_path, get_path_names, _INSTALL_SCHEMES, get_default_scheme, get_scheme_names, get_config_var, - _expand_vars, _get_preferred_schemes, _main) + _expand_vars, _get_preferred_schemes) +from sysconfig.__main__ import _main, _parse_makefile +import _imp import _osx_support +import _sysconfig HAS_USER_BASE = sysconfig._HAS_USER_BASE @@ -394,6 +397,24 @@ def test_ldshared_value(self): self.assertIn(ldflags, ldshared) + @unittest.skipIf(not _imp.extension_suffixes(), "stub loader has no suffixes") + def test_soabi(self): + soabi = sysconfig.get_config_var('SOABI') + self.assertIn(soabi, _imp.extension_suffixes()[0]) + + def test_library(self): + library = sysconfig.get_config_var('LIBRARY') + ldlibrary = sysconfig.get_config_var('LDLIBRARY') + major, minor = sys.version_info[:2] + if sys.platform == 'win32': + self.assertTrue(library.startswith(f'python{major}{minor}')) + self.assertTrue(library.endswith('.dll')) + self.assertEqual(library, ldlibrary) + else: + self.assertTrue(library.startswith(f'libpython{major}.{minor}')) + self.assertTrue(library.endswith('.a')) + self.assertTrue(ldlibrary.startswith(f'libpython{major}.{minor}')) + @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX") @requires_subprocess() def test_platform_in_subprocess(self): @@ -472,10 +493,8 @@ def test_srcdir_independent_of_cwd(self): @unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None, 'EXT_SUFFIX required for this test') + @unittest.skipIf(not _imp.extension_suffixes(), "stub loader has no suffixes") def test_EXT_SUFFIX_in_vars(self): - import _imp - if not _imp.extension_suffixes(): - self.skipTest("stub loader has no suffixes") vars = sysconfig.get_config_vars() self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0]) @@ -521,7 +540,7 @@ def test_parse_makefile(self): print("var5=dollar$$5", file=makefile) print("var6=${var3}/lib/python3.5/config-$(VAR2)$(var5)" "-x86_64-linux-gnu", file=makefile) - vars = sysconfig._parse_makefile(TESTFN) + vars = _parse_makefile(TESTFN) self.assertEqual(vars, { 'var1': 'ab42', 'VAR2': 'b42', diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 2eda7fc4ceac71..cc26da05daeafc 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1,3 +1,4 @@ +import errno import sys import os import io @@ -938,6 +939,23 @@ class LzmaDetectReadTest(LzmaTest, DetectReadTest): pass +class GzipBrokenHeaderCorrectException(GzipTest, unittest.TestCase): + """ + See: https://github.com/python/cpython/issues/107396 + """ + def runTest(self): + f = io.BytesIO( + b'\x1f\x8b' # header + b'\x08' # compression method + b'\x04' # flags + b'\0\0\0\0\0\0' # timestamp, compression data, OS ID + b'\0\x01' # size + b'\0\0\0\0\0' # corrupt data (zeros) + ) + with self.assertRaises(tarfile.ReadError): + tarfile.open(fileobj=f, mode='r|gz') + + class MemberReadTest(ReadTest, unittest.TestCase): def _test_member(self, tarinfo, chksum=None, **kwargs): @@ -2570,16 +2588,17 @@ def tarfilecmd_failure(self, *args): return script_helper.assert_python_failure('-m', 'tarfile', *args) def make_simple_tarfile(self, tar_name): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] self.addCleanup(os_helper.unlink, tar_name) with tarfile.open(tar_name, 'w') as tf: for tardata in files: tf.add(tardata, arcname=os.path.basename(tardata)) def make_evil_tarfile(self, tar_name): - files = [support.findfile('tokenize_tests.txt')] self.addCleanup(os_helper.unlink, tar_name) with tarfile.open(tar_name, 'w') as tf: benign = tarfile.TarInfo('benign') @@ -2660,9 +2679,11 @@ def test_list_command_invalid_file(self): self.assertEqual(rc, 1) def test_create_command(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for opt in '-c', '--create': try: out = self.tarfilecmd(opt, tmpname, *files) @@ -2673,9 +2694,11 @@ def test_create_command(self): os_helper.unlink(tmpname) def test_create_command_verbose(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for opt in '-v', '--verbose': try: out = self.tarfilecmd(opt, '-c', tmpname, *files, @@ -2687,7 +2710,7 @@ def test_create_command_verbose(self): os_helper.unlink(tmpname) def test_create_command_dotless_filename(self): - files = [support.findfile('tokenize_tests.txt')] + files = [support.findfile('tokenize_tests.txt', subdir='tokenizedata')] try: out = self.tarfilecmd('-c', dotlessname, *files) self.assertEqual(out, b'') @@ -2698,7 +2721,7 @@ def test_create_command_dotless_filename(self): def test_create_command_dot_started_filename(self): tar_name = os.path.join(TEMPDIR, ".testtar") - files = [support.findfile('tokenize_tests.txt')] + files = [support.findfile('tokenize_tests.txt', subdir='tokenizedata')] try: out = self.tarfilecmd('-c', tar_name, *files) self.assertEqual(out, b'') @@ -2708,9 +2731,11 @@ def test_create_command_dot_started_filename(self): os_helper.unlink(tar_name) def test_create_command_compressed(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for filetype in (GzipTest, Bz2Test, LzmaTest): if not filetype.open: continue @@ -3337,10 +3362,12 @@ def __exit__(self, *exc): self.bio = None def add(self, name, *, type=None, symlink_to=None, hardlink_to=None, - mode=None, **kwargs): + mode=None, size=None, **kwargs): """Add a member to the test archive. Call within `with`.""" name = str(name) tarinfo = tarfile.TarInfo(name).replace(**kwargs) + if size is not None: + tarinfo.size = size if mode: tarinfo.mode = _filemode_to_int(mode) if symlink_to is not None: @@ -3416,7 +3443,8 @@ def check_context(self, tar, filter): raise self.raised_exception self.assertEqual(self.expected_paths, set()) - def expect_file(self, name, type=None, symlink_to=None, mode=None): + def expect_file(self, name, type=None, symlink_to=None, mode=None, + size=None): """Check a single file. See check_context.""" if self.raised_exception: raise self.raised_exception @@ -3445,6 +3473,8 @@ def expect_file(self, name, type=None, symlink_to=None, mode=None): self.assertTrue(path.is_fifo()) else: raise NotImplementedError(type) + if size is not None: + self.assertEqual(path.stat().st_size, size) for parent in path.parents: self.expected_paths.discard(parent) @@ -3491,8 +3521,15 @@ def test_parent_symlink(self): # Test interplaying symlinks # Inspired by 'dirsymlink2a' in jwilk/traversal-archives with ArchiveMaker() as arc: + + # `current` links to `.` which is both: + # - the destination directory + # - `current` itself arc.add('current', symlink_to='.') + + # effectively points to ./../ arc.add('parent', symlink_to='current/..') + arc.add('parent/evil') if os_helper.can_symlink(): @@ -3534,9 +3571,46 @@ def test_parent_symlink(self): def test_parent_symlink2(self): # Test interplaying symlinks # Inspired by 'dirsymlink2b' in jwilk/traversal-archives + + # Posix and Windows have different pathname resolution: + # either symlink or a '..' component resolve first. + # Let's see which we are on. + if os_helper.can_symlink(): + testpath = os.path.join(TEMPDIR, 'resolution_test') + os.mkdir(testpath) + + # testpath/current links to `.` which is all of: + # - `testpath` + # - `testpath/current` + # - `testpath/current/current` + # - etc. + os.symlink('.', os.path.join(testpath, 'current')) + + # we'll test where `testpath/current/../file` ends up + with open(os.path.join(testpath, 'current', '..', 'file'), 'w'): + pass + + if os.path.exists(os.path.join(testpath, 'file')): + # Windows collapses 'current\..' to '.' first, leaving + # 'testpath\file' + dotdot_resolves_early = True + elif os.path.exists(os.path.join(testpath, '..', 'file')): + # Posix resolves 'current' to '.' first, leaving + # 'testpath/../file' + dotdot_resolves_early = False + else: + raise AssertionError('Could not determine link resolution') + with ArchiveMaker() as arc: + + # `current` links to `.` which is both the destination directory + # and `current` itself arc.add('current', symlink_to='.') + + # `current/parent` is also available as `./parent`, + # and effectively points to `./../` arc.add('current/parent', symlink_to='..') + arc.add('parent/evil') with self.check_context(arc.open(), 'fully_trusted'): @@ -3550,6 +3624,7 @@ def test_parent_symlink2(self): with self.check_context(arc.open(), 'tar'): if os_helper.can_symlink(): + # Fail when extracting a file outside destination self.expect_exception( tarfile.OutsideDestinationError, "'parent/evil' would be extracted to " @@ -3560,10 +3635,24 @@ def test_parent_symlink2(self): self.expect_file('parent/evil') with self.check_context(arc.open(), 'data'): - self.expect_exception( - tarfile.LinkOutsideDestinationError, - """'current/parent' would link to ['"].*['"], """ - + "which is outside the destination") + if os_helper.can_symlink(): + if dotdot_resolves_early: + # Fail when extracting a file outside destination + self.expect_exception( + tarfile.OutsideDestinationError, + "'parent/evil' would be extracted to " + + """['"].*evil['"], which is outside """ + + "the destination") + else: + # Fail as soon as we have a symlink outside the destination + self.expect_exception( + tarfile.LinkOutsideDestinationError, + "'current/parent' would link to " + + """['"].*outerdir['"], which is outside """ + + "the destination") + else: + self.expect_file('current/') + self.expect_file('parent/evil') @symlink_test def test_absolute_symlink(self): @@ -3593,12 +3682,30 @@ def test_absolute_symlink(self): with self.check_context(arc.open(), 'data'): self.expect_exception( tarfile.AbsoluteLinkError, - "'parent' is a symlink to an absolute path") + "'parent' is a link to an absolute path") + + def test_absolute_hardlink(self): + # Test hardlink to an absolute path + # Inspired by 'dirsymlink' in https://github.com/jwilk/traversal-archives + with ArchiveMaker() as arc: + arc.add('parent', hardlink_to=self.outerdir / 'foo') + + with self.check_context(arc.open(), 'fully_trusted'): + self.expect_exception(KeyError, ".*foo. not found") + + with self.check_context(arc.open(), 'tar'): + self.expect_exception(KeyError, ".*foo. not found") + + with self.check_context(arc.open(), 'data'): + self.expect_exception( + tarfile.AbsoluteLinkError, + "'parent' is a link to an absolute path") @symlink_test def test_sly_relative0(self): # Inspired by 'relative0' in jwilk/traversal-archives with ArchiveMaker() as arc: + # points to `../../tmp/moo` arc.add('../moo', symlink_to='..//tmp/moo') try: @@ -3649,6 +3756,56 @@ def test_sly_relative2(self): + """['"].*moo['"], which is outside the """ + "destination") + @symlink_test + def test_deep_symlink(self): + # Test that symlinks and hardlinks inside a directory + # point to the correct file (`target` of size 3). + # If links aren't supported we get a copy of the file. + with ArchiveMaker() as arc: + arc.add('targetdir/target', size=3) + # a hardlink's linkname is relative to the archive + arc.add('linkdir/hardlink', hardlink_to=os.path.join( + 'targetdir', 'target')) + # a symlink's linkname is relative to the link's directory + arc.add('linkdir/symlink', symlink_to=os.path.join( + '..', 'targetdir', 'target')) + + for filter in 'tar', 'data', 'fully_trusted': + with self.check_context(arc.open(), filter): + self.expect_file('targetdir/target', size=3) + self.expect_file('linkdir/hardlink', size=3) + if os_helper.can_symlink(): + self.expect_file('linkdir/symlink', size=3, + symlink_to='../targetdir/target') + else: + self.expect_file('linkdir/symlink', size=3) + + @symlink_test + def test_chains(self): + # Test chaining of symlinks/hardlinks. + # Symlinks are created before the files they point to. + with ArchiveMaker() as arc: + arc.add('linkdir/symlink', symlink_to='hardlink') + arc.add('symlink2', symlink_to=os.path.join( + 'linkdir', 'hardlink2')) + arc.add('targetdir/target', size=3) + arc.add('linkdir/hardlink', hardlink_to='targetdir/target') + arc.add('linkdir/hardlink2', hardlink_to='linkdir/symlink') + + for filter in 'tar', 'data', 'fully_trusted': + with self.check_context(arc.open(), filter): + self.expect_file('targetdir/target', size=3) + self.expect_file('linkdir/hardlink', size=3) + self.expect_file('linkdir/hardlink2', size=3) + if os_helper.can_symlink(): + self.expect_file('linkdir/symlink', size=3, + symlink_to='hardlink') + self.expect_file('symlink2', size=3, + symlink_to='linkdir/hardlink2') + else: + self.expect_file('linkdir/symlink', size=3) + self.expect_file('symlink2', size=3) + def test_modes(self): # Test how file modes are extracted # (Note that the modes are ignored on platforms without working chmod) @@ -3659,34 +3816,55 @@ def test_modes(self): arc.add('read_group_only', mode='?---r-----') arc.add('no_bits', mode='?---------') arc.add('dir/', mode='?---rwsrwt') + arc.add('dir_all_bits/', mode='?rwsrwsrwt') - # On some systems, setting the sticky bit is a no-op. - # Check if that's the case. + # On some systems, setting the uid, gid, and/or sticky bit is a no-ops. + # Check which bits we can set, so we can compare tarfile machinery to + # a simple chmod. tmp_filename = os.path.join(TEMPDIR, "tmp.file") with open(tmp_filename, 'w'): pass - os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) - have_sticky_files = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) - os.unlink(tmp_filename) + try: + new_mode = (os.stat(tmp_filename).st_mode + | stat.S_ISVTX | stat.S_ISGID | stat.S_ISUID) + try: + os.chmod(tmp_filename, new_mode) + except OSError as exc: + if exc.errno == getattr(errno, "EFTYPE", 0): + # gh-108948: On FreeBSD, regular users cannot set + # the sticky bit. + self.skipTest("chmod() failed with EFTYPE: " + "regular users cannot set sticky bit") + else: + raise + + got_mode = os.stat(tmp_filename).st_mode + _t_file = 't' if (got_mode & stat.S_ISVTX) else 'x' + _suid_file = 's' if (got_mode & stat.S_ISUID) else 'x' + _sgid_file = 's' if (got_mode & stat.S_ISGID) else 'x' + finally: + os.unlink(tmp_filename) os.mkdir(tmp_filename) - os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) - have_sticky_dirs = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) + new_mode = (os.stat(tmp_filename).st_mode + | stat.S_ISVTX | stat.S_ISGID | stat.S_ISUID) + os.chmod(tmp_filename, new_mode) + got_mode = os.stat(tmp_filename).st_mode + _t_dir = 't' if (got_mode & stat.S_ISVTX) else 'x' + _suid_dir = 's' if (got_mode & stat.S_ISUID) else 'x' + _sgid_dir = 's' if (got_mode & stat.S_ISGID) else 'x' os.rmdir(tmp_filename) with self.check_context(arc.open(), 'fully_trusted'): - if have_sticky_files: - self.expect_file('all_bits', mode='?rwsrwsrwt') - else: - self.expect_file('all_bits', mode='?rwsrwsrwx') + self.expect_file('all_bits', + mode=f'?rw{_suid_file}rw{_sgid_file}rw{_t_file}') self.expect_file('perm_bits', mode='?rwxrwxrwx') self.expect_file('exec_group_other', mode='?rw-rwxrwx') self.expect_file('read_group_only', mode='?---r-----') self.expect_file('no_bits', mode='?---------') - if have_sticky_dirs: - self.expect_file('dir/', mode='?---rwsrwt') - else: - self.expect_file('dir/', mode='?---rwsrwx') + self.expect_file('dir/', mode=f'?---rw{_sgid_dir}rw{_t_dir}') + self.expect_file('dir_all_bits/', + mode=f'?rw{_suid_dir}rw{_sgid_dir}rw{_t_dir}') with self.check_context(arc.open(), 'tar'): self.expect_file('all_bits', mode='?rwxr-xr-x') @@ -3695,6 +3873,7 @@ def test_modes(self): self.expect_file('read_group_only', mode='?---r-----') self.expect_file('no_bits', mode='?---------') self.expect_file('dir/', mode='?---r-xr-x') + self.expect_file('dir_all_bits/', mode='?rwxr-xr-x') with self.check_context(arc.open(), 'data'): normal_dir_mode = stat.filemode(stat.S_IMODE( @@ -3705,6 +3884,7 @@ def test_modes(self): self.expect_file('read_group_only', mode='?rw-r-----') self.expect_file('no_bits', mode='?rw-------') self.expect_file('dir/', mode=normal_dir_mode) + self.expect_file('dir_all_bits/', mode=normal_dir_mode) def test_pipe(self): # Test handling of a special file diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index d07b83acb1b505..ebdb58f91d3d8a 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -20,14 +20,6 @@ tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.'))) -_tk_patchlevel = None -def get_tk_patchlevel(): - global _tk_patchlevel - if _tk_patchlevel is None: - tcl = Tcl() - _tk_patchlevel = tcl.info_patchlevel() - return _tk_patchlevel - class TkinterTest(unittest.TestCase): @@ -571,7 +563,6 @@ def test_splitlist(self): (1, '2', (3.4,)) if self.wantobjects else ('1', '2', '3.4')), ] - tk_patchlevel = get_tk_patchlevel() if not self.wantobjects: expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') else: @@ -580,8 +571,8 @@ def test_splitlist(self): (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), expected), ] - dbg_info = ('want objects? %s, Tcl version: %s, Tk patchlevel: %s' - % (self.wantobjects, tcl_version, tk_patchlevel)) + dbg_info = ('want objects? %s, Tcl version: %s, Tcl patchlevel: %s' + % (self.wantobjects, tcl_version, self.interp.info_patchlevel())) for arg, res in testcases: self.assertEqual(splitlist(arg), res, 'arg=%a, %s' % (arg, dbg_info)) diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index db08fb1c7f2a42..1673507e2f7c91 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1834,9 +1834,25 @@ def test_modes(self): d.cleanup() self.assertFalse(os.path.exists(d.name)) - @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.lchflags') + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') def test_flags(self): flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + + # skip the test if these flags are not supported (ex: FreeBSD 13) + filename = os_helper.TESTFN + try: + open(filename, "w").close() + try: + os.chflags(filename, flags) + except OSError as exc: + # "OSError: [Errno 45] Operation not supported" + self.skipTest(f"chflags() doesn't support " + f"UF_IMMUTABLE|UF_NOUNLINK: {exc}") + else: + os.chflags(filename, 0) + finally: + os_helper.unlink(filename) + d = self.do_create(recurse=3, dirs=2, files=2) with d: # Change files and directories flags recursively. diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py new file mode 100644 index 00000000000000..58698ffac2d981 --- /dev/null +++ b/Lib/test/test_termios.py @@ -0,0 +1,220 @@ +import errno +import os +import sys +import tempfile +import unittest +from test.support.import_helper import import_module + +termios = import_module('termios') + + +@unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") +class TestFunctions(unittest.TestCase): + + def setUp(self): + master_fd, self.fd = os.openpty() + self.addCleanup(os.close, master_fd) + self.stream = self.enterContext(open(self.fd, 'wb', buffering=0)) + tmp = self.enterContext(tempfile.TemporaryFile(mode='wb', buffering=0)) + self.bad_fd = tmp.fileno() + + def assertRaisesTermiosError(self, errno, callable, *args): + with self.assertRaises(termios.error) as cm: + callable(*args) + self.assertEqual(cm.exception.args[0], errno) + + def test_tcgetattr(self): + attrs = termios.tcgetattr(self.fd) + self.assertIsInstance(attrs, list) + self.assertEqual(len(attrs), 7) + for i in range(6): + self.assertIsInstance(attrs[i], int) + iflag, oflag, cflag, lflag, ispeed, ospeed, cc = attrs + self.assertIsInstance(cc, list) + self.assertEqual(len(cc), termios.NCCS) + for i, x in enumerate(cc): + if ((lflag & termios.ICANON) == 0 and + (i == termios.VMIN or i == termios.VTIME)): + self.assertIsInstance(x, int) + else: + self.assertIsInstance(x, bytes) + self.assertEqual(len(x), 1) + self.assertEqual(termios.tcgetattr(self.stream), attrs) + + def test_tcgetattr_errors(self): + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcgetattr, self.bad_fd) + self.assertRaises(ValueError, termios.tcgetattr, -1) + self.assertRaises(OverflowError, termios.tcgetattr, 2**1000) + self.assertRaises(TypeError, termios.tcgetattr, object()) + self.assertRaises(TypeError, termios.tcgetattr) + + def test_tcsetattr(self): + attrs = termios.tcgetattr(self.fd) + termios.tcsetattr(self.fd, termios.TCSANOW, attrs) + termios.tcsetattr(self.fd, termios.TCSADRAIN, attrs) + termios.tcsetattr(self.fd, termios.TCSAFLUSH, attrs) + termios.tcsetattr(self.stream, termios.TCSANOW, attrs) + + def test_tcsetattr_errors(self): + attrs = termios.tcgetattr(self.fd) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, tuple(attrs)) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs[:-1]) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs + [0]) + for i in range(6): + attrs2 = attrs[:] + attrs2[i] = 2**1000 + self.assertRaises(OverflowError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[i] = object() + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs[:-1] + [attrs[-1][:-1]]) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs[:-1] + [attrs[-1] + [b'\0']]) + for i in range(len(attrs[-1])): + attrs2 = attrs[:] + attrs2[-1] = attrs2[-1][:] + attrs2[-1][i] = 2**1000 + self.assertRaises(OverflowError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[-1][i] = object() + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[-1][i] = b'' + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[-1][i] = b'\0\0' + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, object()) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW) + self.assertRaisesTermiosError(errno.EINVAL, termios.tcsetattr, self.fd, -1, attrs) + self.assertRaises(OverflowError, termios.tcsetattr, self.fd, 2**1000, attrs) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, object(), attrs) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcsetattr, self.bad_fd, termios.TCSANOW, attrs) + self.assertRaises(ValueError, termios.tcsetattr, -1, termios.TCSANOW, attrs) + self.assertRaises(OverflowError, termios.tcsetattr, 2**1000, termios.TCSANOW, attrs) + self.assertRaises(TypeError, termios.tcsetattr, object(), termios.TCSANOW, attrs) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW) + + def test_tcsendbreak(self): + try: + termios.tcsendbreak(self.fd, 1) + except termios.error as exc: + if exc.args[0] == errno.ENOTTY and sys.platform.startswith('freebsd'): + self.skipTest('termios.tcsendbreak() is not supported ' + 'with pseudo-terminals (?) on this platform') + raise + termios.tcsendbreak(self.stream, 1) + + def test_tcsendbreak_errors(self): + self.assertRaises(OverflowError, termios.tcsendbreak, self.fd, 2**1000) + self.assertRaises(TypeError, termios.tcsendbreak, self.fd, 0.0) + self.assertRaises(TypeError, termios.tcsendbreak, self.fd, object()) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcsendbreak, self.bad_fd, 0) + self.assertRaises(ValueError, termios.tcsendbreak, -1, 0) + self.assertRaises(OverflowError, termios.tcsendbreak, 2**1000, 0) + self.assertRaises(TypeError, termios.tcsendbreak, object(), 0) + self.assertRaises(TypeError, termios.tcsendbreak, self.fd) + + def test_tcdrain(self): + termios.tcdrain(self.fd) + termios.tcdrain(self.stream) + + def test_tcdrain_errors(self): + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcdrain, self.bad_fd) + self.assertRaises(ValueError, termios.tcdrain, -1) + self.assertRaises(OverflowError, termios.tcdrain, 2**1000) + self.assertRaises(TypeError, termios.tcdrain, object()) + self.assertRaises(TypeError, termios.tcdrain) + + def test_tcflush(self): + termios.tcflush(self.fd, termios.TCIFLUSH) + termios.tcflush(self.fd, termios.TCOFLUSH) + termios.tcflush(self.fd, termios.TCIOFLUSH) + + def test_tcflush_errors(self): + self.assertRaisesTermiosError(errno.EINVAL, termios.tcflush, self.fd, -1) + self.assertRaises(OverflowError, termios.tcflush, self.fd, 2**1000) + self.assertRaises(TypeError, termios.tcflush, self.fd, object()) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcflush, self.bad_fd, termios.TCIFLUSH) + self.assertRaises(ValueError, termios.tcflush, -1, termios.TCIFLUSH) + self.assertRaises(OverflowError, termios.tcflush, 2**1000, termios.TCIFLUSH) + self.assertRaises(TypeError, termios.tcflush, object(), termios.TCIFLUSH) + self.assertRaises(TypeError, termios.tcflush, self.fd) + + def test_tcflow(self): + termios.tcflow(self.fd, termios.TCOOFF) + termios.tcflow(self.fd, termios.TCOON) + termios.tcflow(self.fd, termios.TCIOFF) + termios.tcflow(self.fd, termios.TCION) + + def test_tcflow_errors(self): + self.assertRaisesTermiosError(errno.EINVAL, termios.tcflow, self.fd, -1) + self.assertRaises(OverflowError, termios.tcflow, self.fd, 2**1000) + self.assertRaises(TypeError, termios.tcflow, self.fd, object()) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcflow, self.bad_fd, termios.TCOON) + self.assertRaises(ValueError, termios.tcflow, -1, termios.TCOON) + self.assertRaises(OverflowError, termios.tcflow, 2**1000, termios.TCOON) + self.assertRaises(TypeError, termios.tcflow, object(), termios.TCOON) + self.assertRaises(TypeError, termios.tcflow, self.fd) + + def test_tcgetwinsize(self): + size = termios.tcgetwinsize(self.fd) + self.assertIsInstance(size, tuple) + self.assertEqual(len(size), 2) + self.assertIsInstance(size[0], int) + self.assertIsInstance(size[1], int) + self.assertEqual(termios.tcgetwinsize(self.stream), size) + + def test_tcgetwinsize_errors(self): + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcgetwinsize, self.bad_fd) + self.assertRaises(ValueError, termios.tcgetwinsize, -1) + self.assertRaises(OverflowError, termios.tcgetwinsize, 2**1000) + self.assertRaises(TypeError, termios.tcgetwinsize, object()) + self.assertRaises(TypeError, termios.tcgetwinsize) + + def test_tcsetwinsize(self): + size = termios.tcgetwinsize(self.fd) + termios.tcsetwinsize(self.fd, size) + termios.tcsetwinsize(self.fd, list(size)) + termios.tcsetwinsize(self.stream, size) + + def test_tcsetwinsize_errors(self): + size = termios.tcgetwinsize(self.fd) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, size[:-1]) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, size + (0,)) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, object()) + self.assertRaises(OverflowError, termios.tcsetwinsize, self.fd, (size[0], 2**1000)) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (size[0], float(size[1]))) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (size[0], object())) + self.assertRaises(OverflowError, termios.tcsetwinsize, self.fd, (2**1000, size[1])) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (float(size[0]), size[1])) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (object(), size[1])) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcsetwinsize, self.bad_fd, size) + self.assertRaises(ValueError, termios.tcsetwinsize, -1, size) + self.assertRaises(OverflowError, termios.tcsetwinsize, 2**1000, size) + self.assertRaises(TypeError, termios.tcsetwinsize, object(), size) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd) + + +class TestModule(unittest.TestCase): + def test_constants(self): + self.assertIsInstance(termios.B0, int) + self.assertIsInstance(termios.B38400, int) + self.assertIsInstance(termios.TCSANOW, int) + self.assertIsInstance(termios.TCSADRAIN, int) + self.assertIsInstance(termios.TCSAFLUSH, int) + self.assertIsInstance(termios.TCIFLUSH, int) + self.assertIsInstance(termios.TCOFLUSH, int) + self.assertIsInstance(termios.TCIOFLUSH, int) + self.assertIsInstance(termios.TCOOFF, int) + self.assertIsInstance(termios.TCOON, int) + self.assertIsInstance(termios.TCIOFF, int) + self.assertIsInstance(termios.TCION, int) + self.assertIsInstance(termios.VTIME, int) + self.assertIsInstance(termios.VMIN, int) + self.assertIsInstance(termios.NCCS, int) + self.assertLess(termios.VTIME, termios.NCCS) + self.assertLess(termios.VMIN, termios.NCCS) + + def test_exception(self): + self.assertTrue(issubclass(termios.error, Exception)) + self.assertFalse(issubclass(termios.error, OSError)) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 4a91eef31c4b8b..00a64372b394dc 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -26,6 +26,11 @@ from test import lock_tests from test import support +try: + from test.support import interpreters +except ModuleNotFoundError: + interpreters = None + threading_helper.requires_working_threading(module=True) # Between fork() and exec(), only async-safe functions are allowed (issues @@ -35,6 +40,22 @@ platforms_to_skip = ('netbsd5', 'hp-ux11') +def skip_unless_reliable_fork(test): + if not support.has_fork_support: + return unittest.skip("requires working os.fork()")(test) + if sys.platform in platforms_to_skip: + return unittest.skip("due to known OS bug related to thread+fork")(test) + if support.HAVE_ASAN_FORK_BUG: + return unittest.skip("libasan has a pthread_create() dead lock related to thread+fork")(test) + return test + + +def requires_subinterpreters(meth): + """Decorator to skip a test if subinterpreters are not supported.""" + return unittest.skipIf(interpreters is None, + 'subinterpreters required')(meth) + + def restore_default_excepthook(testcase): testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook) threading.excepthook = threading.__excepthook__ @@ -539,7 +560,7 @@ def test_daemon_param(self): t = threading.Thread(daemon=True) self.assertTrue(t.daemon) - @support.requires_fork() + @skip_unless_reliable_fork def test_dummy_thread_after_fork(self): # Issue #14308: a dummy thread in the active list doesn't mess up # the after-fork mechanism. @@ -571,7 +592,7 @@ def background_thread(evt): self.assertEqual(out, b'') self.assertEqual(err, b'') - @support.requires_fork() + @skip_unless_reliable_fork def test_is_alive_after_fork(self): # Try hard to trigger #18418: is_alive() could sometimes be True on # threads that vanished after a fork. @@ -607,7 +628,7 @@ def f(): th.start() th.join() - @support.requires_fork() + @skip_unless_reliable_fork @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork(self): code = """if 1: @@ -628,8 +649,7 @@ def test_main_thread_after_fork(self): self.assertEqual(err, b"") self.assertEqual(data, "MainThread\nTrue\nTrue\n") - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") - @support.requires_fork() + @skip_unless_reliable_fork @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork_from_nonmain_thread(self): code = """if 1: @@ -1076,8 +1096,7 @@ def test_1_join_on_shutdown(self): """ self._run_and_join(script) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_2_join_in_forked_process(self): # Like the test above, but from a forked interpreter script = """if 1: @@ -1097,8 +1116,7 @@ def test_2_join_in_forked_process(self): """ self._run_and_join(script) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_3_join_in_forked_from_thread(self): # Like the test above, but fork() was called from a worker thread # In the forked process, the main Thread object must be marked as stopped. @@ -1168,8 +1186,7 @@ def main(): rc, out, err = assert_python_ok('-c', script) self.assertFalse(err) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_reinit_tls_after_fork(self): # Issue #13817: fork() would deadlock in a multithreaded program with # the ad-hoc TLS implementation. @@ -1195,7 +1212,7 @@ def do_fork_and_wait(): for t in threads: t.join() - @support.requires_fork() + @skip_unless_reliable_fork def test_clear_threads_states_after_fork(self): # Issue #17094: check that threads states are cleared after fork() @@ -1298,6 +1315,44 @@ def f(): # The thread was joined properly. self.assertEqual(os.read(r, 1), b"x") + @requires_subinterpreters + def test_threads_join_with_no_main(self): + r_interp, w_interp = self.pipe() + + INTERP = b'I' + FINI = b'F' + DONE = b'D' + + interp = interpreters.create() + interp.run(f"""if True: + import os + import threading + import time + + done = False + + def notify_fini(): + global done + done = True + os.write({w_interp}, {FINI!r}) + t.join() + threading._register_atexit(notify_fini) + + def task(): + while not done: + time.sleep(0.1) + os.write({w_interp}, {DONE!r}) + t = threading.Thread(target=task) + t.start() + + os.write({w_interp}, {INTERP!r}) + """) + interp.close() + + self.assertEqual(os.read(r_interp, 1), INTERP) + self.assertEqual(os.read(r_interp, 1), FINI) + self.assertEqual(os.read(r_interp, 1), DONE) + @cpython_only def test_daemon_threads_fatal_error(self): subinterp_code = f"""if 1: @@ -1748,6 +1803,30 @@ class PyRLockTests(lock_tests.RLockTests): class CRLockTests(lock_tests.RLockTests): locktype = staticmethod(threading._CRLock) + def test_signature(self): # gh-102029 + with warnings.catch_warnings(record=True) as warnings_log: + threading.RLock() + self.assertEqual(warnings_log, []) + + arg_types = [ + ((1,), {}), + ((), {'a': 1}), + ((1, 2), {'a': 1}), + ] + for args, kwargs in arg_types: + with self.subTest(args=args, kwargs=kwargs): + with self.assertWarns(DeprecationWarning): + threading.RLock(*args, **kwargs) + + # Subtypes with custom `__init__` are allowed (but, not recommended): + class CustomRLock(self.locktype): + def __init__(self, a, *, b) -> None: + super().__init__() + + with warnings.catch_warnings(record=True) as warnings_log: + CustomRLock(1, b=2) + self.assertEqual(warnings_log, []) + class EventTests(lock_tests.EventTests): eventtype = staticmethod(threading.Event) @@ -1755,6 +1834,9 @@ class ConditionAsRLockTests(lock_tests.RLockTests): # Condition uses an RLock by default and exports its API. locktype = staticmethod(threading.Condition) + def test_recursion_count(self): + self.skipTest("Condition does not expose _recursion_count()") + class ConditionTests(lock_tests.ConditionTests): condtype = staticmethod(threading.Condition) diff --git a/Lib/test/test_timeout.py b/Lib/test/test_timeout.py index 30e843a423a777..35ff56f1a5ee09 100644 --- a/Lib/test/test_timeout.py +++ b/Lib/test/test_timeout.py @@ -148,13 +148,12 @@ 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 # from Python because it's a function of the underlying TCP/IP stack. - # So, the following Snakebite host has been defined: - blackhole = resolve_address('blackhole.snakebite.net', 56666) + # So, the following port on the pythontest.net host has been defined: + blackhole = resolve_address('pythontest.net', 56666) # Blackhole has been configured to silently drop any incoming packets. # No RSTs (for TCP) or ICMP UNREACH (for UDP/ICMP) will be sent back @@ -166,7 +165,7 @@ def testConnectTimeout(self): # to firewalling or general network configuration. In order to improve # our confidence in testing the blackhole, a corresponding 'whitehole' # has also been set up using one port higher: - whitehole = resolve_address('whitehole.snakebite.net', 56667) + whitehole = resolve_address('pythontest.net', 56667) # This address has been configured to immediately drop any incoming # packets as well, but it does it respectfully with regards to the @@ -180,20 +179,15 @@ def testConnectTimeout(self): # timeframe). # For the records, the whitehole/blackhole configuration has been set - # up using the 'pf' firewall (available on BSDs), using the following: + # up using the 'iptables' firewall, using the following rules: # - # ext_if="bge0" - # - # blackhole_ip="35.8.247.6" - # whitehole_ip="35.8.247.6" - # blackhole_port="56666" - # whitehole_port="56667" - # - # block return in log quick on $ext_if proto { tcp udp } \ - # from any to $whitehole_ip port $whitehole_port - # block drop in log quick on $ext_if proto { tcp udp } \ - # from any to $blackhole_ip port $blackhole_port + # -A INPUT -p tcp --destination-port 56666 -j DROP + # -A INPUT -p udp --destination-port 56666 -j DROP + # -A INPUT -p tcp --destination-port 56667 -j REJECT + # -A INPUT -p udp --destination-port 56667 -j REJECT # + # See https://github.com/python/psf-salt/blob/main/pillar/base/firewall/snakebite.sls + # for the current configuration. skip = True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/Lib/test/test_tkinter/__init__.py b/Lib/test/test_tkinter/__init__.py index b1181bc04b7953..aa196c12c804ac 100644 --- a/Lib/test/test_tkinter/__init__.py +++ b/Lib/test/test_tkinter/__init__.py @@ -10,6 +10,7 @@ if check_sanitizer(address=True, memory=True): + # See gh-90791 for details raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") # Skip test if _tkinter wasn't built. diff --git a/Lib/test/test_tkinter/support.py b/Lib/test/test_tkinter/support.py index 9154ebac5c48f8..a37705f0ae6feb 100644 --- a/Lib/test/test_tkinter/support.py +++ b/Lib/test/test_tkinter/support.py @@ -1,6 +1,5 @@ import functools import tkinter -import unittest class AbstractTkTest: @@ -79,28 +78,28 @@ def simulate_mouse_click(widget, x, y): import _tkinter tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.'))) +tk_version = tuple(map(int, _tkinter.TK_VERSION.split('.'))) -def requires_tcl(*version): - if len(version) <= 2: - return unittest.skipUnless(tcl_version >= version, - 'requires Tcl version >= ' + '.'.join(map(str, version))) +def requires_tk(*version): + if len(version) <= 2 and tk_version >= version: + return lambda test: test def deco(test): @functools.wraps(test) def newtest(self): - if get_tk_patchlevel() < version: - self.skipTest('requires Tcl version >= ' + + root = getattr(self, 'root', None) + if get_tk_patchlevel(root) < version: + self.skipTest('requires Tk version >= ' + '.'.join(map(str, version))) test(self) return newtest return deco _tk_patchlevel = None -def get_tk_patchlevel(): +def get_tk_patchlevel(root): global _tk_patchlevel if _tk_patchlevel is None: - tcl = tkinter.Tcl() - _tk_patchlevel = tcl.info_patchlevel() + _tk_patchlevel = tkinter._parse_version(root.tk.globalgetvar('tk_patchLevel')) return _tk_patchlevel units = { diff --git a/Lib/test/test_tkinter/test_images.py b/Lib/test/test_tkinter/test_images.py index c07de867ce04b7..317b0a5c8f4a30 100644 --- a/Lib/test/test_tkinter/test_images.py +++ b/Lib/test/test_tkinter/test_images.py @@ -2,7 +2,7 @@ import tkinter from test import support from test.support import os_helper -from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tcl +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tk support.requires('gui') @@ -144,6 +144,14 @@ def test_configure_foreground(self): self.assertEqual(image['foreground'], '-foreground {} {} #000000 yellow') + def test_bug_100814(self): + # gh-100814: Passing a callable option value causes AttributeError. + with self.assertRaises(tkinter.TclError): + tkinter.BitmapImage('::img::test', master=self.root, spam=print) + image = tkinter.BitmapImage('::img::test', master=self.root) + with self.assertRaises(tkinter.TclError): + image.configure(spam=print) + class PhotoImageTest(AbstractTkTest, unittest.TestCase): @@ -213,11 +221,11 @@ def test_create_from_gif_file(self): def test_create_from_gif_data(self): self.check_create_from_data('gif') - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_create_from_png_file(self): self.check_create_from_file('png') - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_create_from_png_data(self): self.check_create_from_data('png') @@ -274,6 +282,14 @@ def test_configure_palette(self): image.configure(palette='3/4/2') self.assertEqual(image['palette'], '3/4/2') + def test_bug_100814(self): + # gh-100814: Passing a callable option value causes AttributeError. + with self.assertRaises(tkinter.TclError): + tkinter.PhotoImage('::img::test', master=self.root, spam=print) + image = tkinter.PhotoImage('::img::test', master=self.root) + with self.assertRaises(tkinter.TclError): + image.configure(spam=print) + def test_blank(self): image = self.create() image.blank() diff --git a/Lib/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py index d1aca58d15fbd8..0ae27610be6078 100644 --- a/Lib/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -1,9 +1,10 @@ import functools import unittest import tkinter +from tkinter import TclError import enum from test import support -from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tk support.requires('gui') @@ -36,6 +37,59 @@ def test_generated_names(self): for name in str(b).split('.'): self.assertFalse(name.isidentifier(), msg=repr(name)) + @requires_tk(8, 6, 6) + def test_tk_busy(self): + root = self.root + f = tkinter.Frame(root, name='myframe') + f2 = tkinter.Frame(root) + f.pack() + f2.pack() + b = tkinter.Button(f) + b.pack() + f.tk_busy_hold() + with self.assertRaisesRegex(TclError, 'unknown option "-spam"'): + f.tk_busy_configure(spam='eggs') + with self.assertRaisesRegex(TclError, 'unknown option "-spam"'): + f.tk_busy_cget('spam') + with self.assertRaisesRegex(TclError, 'unknown option "-spam"'): + f.tk_busy_configure('spam') + self.assertIsInstance(f.tk_busy_configure(), dict) + + self.assertTrue(f.tk_busy_status()) + self.assertFalse(root.tk_busy_status()) + self.assertFalse(f2.tk_busy_status()) + self.assertFalse(b.tk_busy_status()) + self.assertIn(f, f.tk_busy_current()) + self.assertIn(f, f.tk_busy_current('*.m?f*me')) + self.assertNotIn(f, f.tk_busy_current('*spam')) + + f.tk_busy_forget() + self.assertFalse(f.tk_busy_status()) + self.assertFalse(f.tk_busy_current()) + with self.assertRaisesRegex(TclError, "can't find busy window"): + f.tk_busy_configure() + with self.assertRaisesRegex(TclError, "can't find busy window"): + f.tk_busy_forget() + + @requires_tk(8, 6, 6) + def test_tk_busy_with_cursor(self): + root = self.root + if root._windowingsystem == 'aqua': + self.skipTest('the cursor option is not supported on OSX/Aqua') + f = tkinter.Frame(root, name='myframe') + f.pack() + f.tk_busy_hold(cursor='gumby') + + self.assertEqual(f.tk_busy_cget('cursor'), 'gumby') + f.tk_busy_configure(cursor='heart') + self.assertEqual(f.tk_busy_cget('cursor'), 'heart') + self.assertEqual(f.tk_busy_configure()['cursor'][4], 'heart') + self.assertEqual(f.tk_busy_configure('cursor')[4], 'heart') + + f.tk_busy_forget() + with self.assertRaisesRegex(TclError, "can't find busy window"): + f.tk_busy_cget('cursor') + def test_tk_setPalette(self): root = self.root root.tk_setPalette('black') diff --git a/Lib/test/test_tkinter/test_widgets.py b/Lib/test/test_tkinter/test_widgets.py index 34e67c0cbc44a3..d3f942db7baf9a 100644 --- a/Lib/test/test_tkinter/test_widgets.py +++ b/Lib/test/test_tkinter/test_widgets.py @@ -4,7 +4,7 @@ import os from test.support import requires -from test.test_tkinter.support import (requires_tcl, +from test.test_tkinter.support import (requires_tk, get_tk_patchlevel, widget_eq, AbstractDefaultRootTest) from test.test_tkinter.widget_tests import ( @@ -613,7 +613,7 @@ def test_configure_inactiveselectbackground(self): widget = self.create() self.checkColorParam(widget, 'inactiveselectbackground') - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_configure_insertunfocussed(self): widget = self.create() self.checkEnumParam(widget, 'insertunfocussed', @@ -924,7 +924,7 @@ def test_coords(self): for i in range(4): self.assertIsInstance(coords[i], float) - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_moveto(self): widget = self.create() i1 = widget.create_rectangle(1, 1, 20, 20, tags='group') @@ -969,7 +969,7 @@ def test_configure_activestyle(self): self.checkEnumParam(widget, 'activestyle', 'dotbox', 'none', 'underline') - test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) + test_configure_justify = requires_tk(8, 6, 5)(StandardOptionsTests.test_configure_justify) def test_configure_listvariable(self): widget = self.create() @@ -1108,7 +1108,7 @@ def test_configure_digits(self): def test_configure_from(self): widget = self.create() - conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round + conv = float if get_tk_patchlevel(self.root) >= (8, 6, 10) else float_round self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) def test_configure_label(self): @@ -1235,19 +1235,19 @@ def test_configure_opaqueresize(self): widget = self.create() self.checkBooleanParam(widget, 'opaqueresize') - @requires_tcl(8, 6, 5) + @requires_tk(8, 6, 5) def test_configure_proxybackground(self): widget = self.create() self.checkColorParam(widget, 'proxybackground') - @requires_tcl(8, 6, 5) + @requires_tk(8, 6, 5) def test_configure_proxyborderwidth(self): widget = self.create() self.checkPixelsParam(widget, 'proxyborderwidth', 0, 1.3, 2.9, 6, -2, '10p', conv=False) - @requires_tcl(8, 6, 5) + @requires_tk(8, 6, 5) def test_configure_proxyrelief(self): widget = self.create() self.checkReliefParam(widget, 'proxyrelief') diff --git a/Lib/test/test_tkinter/widget_tests.py b/Lib/test/test_tkinter/widget_tests.py index f60087a6e9f385..31f82f459beefd 100644 --- a/Lib/test/test_tkinter/widget_tests.py +++ b/Lib/test/test_tkinter/widget_tests.py @@ -1,7 +1,7 @@ # Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py import tkinter -from test.test_tkinter.support import (AbstractTkTest, tcl_version, +from test.test_tkinter.support import (AbstractTkTest, tk_version, pixels_conv, tcl_obj_eq) import test.support @@ -22,7 +22,7 @@ def scaling(self): return self._scaling def _str(self, value): - if not self._stringify and self.wantobjects and tcl_version >= (8, 6): + if not self._stringify and self.wantobjects and tk_version >= (8, 6): return value if isinstance(value, tuple): return ' '.join(map(self._str, value)) @@ -156,7 +156,7 @@ def checkReliefParam(self, widget, name): 'flat', 'groove', 'raised', 'ridge', 'solid', 'sunken') errmsg='bad relief "spam": must be '\ 'flat, groove, raised, ridge, solid, or sunken' - if tcl_version < (8, 6): + if tk_version < (8, 6): errmsg = None self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg) diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index d1552d8a20808f..41b9ebe3374d62 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -566,6 +566,55 @@ def test_string(self): OP '=' (3, 0) (3, 1) OP '}' (3, 1) (3, 2) FSTRING_END "'''" (3, 2) (3, 5) + """) + self.check_tokenize("""\ +f'''__{ + x:a +}__'''""", """\ + FSTRING_START "f'''" (1, 0) (1, 4) + FSTRING_MIDDLE '__' (1, 4) (1, 6) + OP '{' (1, 6) (1, 7) + NL '\\n' (1, 7) (1, 8) + NAME 'x' (2, 4) (2, 5) + OP ':' (2, 5) (2, 6) + FSTRING_MIDDLE 'a\\n' (2, 6) (3, 0) + OP '}' (3, 0) (3, 1) + FSTRING_MIDDLE '__' (3, 1) (3, 3) + FSTRING_END "'''" (3, 3) (3, 6) + """) + self.check_tokenize("""\ +f'''__{ + x:a + b + c + d +}__'''""", """\ + FSTRING_START "f'''" (1, 0) (1, 4) + FSTRING_MIDDLE '__' (1, 4) (1, 6) + OP '{' (1, 6) (1, 7) + NL '\\n' (1, 7) (1, 8) + NAME 'x' (2, 4) (2, 5) + OP ':' (2, 5) (2, 6) + FSTRING_MIDDLE 'a\\n b\\n c\\n d\\n' (2, 6) (6, 0) + OP '}' (6, 0) (6, 1) + FSTRING_MIDDLE '__' (6, 1) (6, 3) + FSTRING_END "'''" (6, 3) (6, 6) + """) + self.check_tokenize("""\ +f'__{ + x:d +}__'""", """\ + FSTRING_START "f'" (1, 0) (1, 2) + FSTRING_MIDDLE '__' (1, 2) (1, 4) + OP '{' (1, 4) (1, 5) + NL '\\n' (1, 5) (1, 6) + NAME 'x' (2, 4) (2, 5) + OP ':' (2, 5) (2, 6) + FSTRING_MIDDLE 'd' (2, 6) (2, 7) + NL '\\n' (2, 7) (2, 8) + OP '}' (3, 0) (3, 1) + FSTRING_MIDDLE '__' (3, 1) (3, 3) + FSTRING_END "'" (3, 3) (3, 4) """) def test_function(self): @@ -1200,7 +1249,7 @@ class TestTokenizerAdheresToPep0263(TestCase): """ def _testFile(self, filename): - path = os.path.join(os.path.dirname(__file__), filename) + path = os.path.join(os.path.dirname(__file__), 'tokenizedata', filename) with open(path, 'rb') as f: TestRoundtrip.check_roundtrip(self, f) @@ -1386,7 +1435,7 @@ def test_cookie_second_line_empty_first_line(self): self.assertEqual(consumed_lines, expected) def test_latin1_normalization(self): - # See get_normal_name() in tokenizer.c. + # See get_normal_name() in Parser/tokenizer/helpers.c. encodings = ("latin-1", "iso-8859-1", "iso-latin-1", "latin-1-unix", "iso-8859-1-unix", "iso-latin-1-mac") for encoding in encodings: @@ -1411,7 +1460,7 @@ def test_syntaxerror_latin1(self): def test_utf8_normalization(self): - # See get_normal_name() in tokenizer.c. + # See get_normal_name() in Parser/tokenizer/helpers.c. encodings = ("utf-8", "utf-8-mac", "utf-8-unix") for encoding in encodings: for rep in ("-", "_"): @@ -1794,7 +1843,7 @@ def test_roundtrip(self): self.check_roundtrip("if x == 1 : \n" " print(x)\n") - fn = support.findfile("tokenize_tests.txt") + fn = support.findfile("tokenize_tests.txt", subdir="tokenizedata") with open(fn, 'rb') as f: self.check_roundtrip(f) self.check_roundtrip("if x == 1:\n" @@ -1849,8 +1898,7 @@ def test_random_files(self): # pass the '-ucpu' option to process the full directory. import glob, random - fn = support.findfile("tokenize_tests.txt") - tempdir = os.path.dirname(fn) or os.curdir + tempdir = os.path.dirname(__file__) or os.curdir testfiles = glob.glob(os.path.join(glob.escape(tempdir), "test*.py")) # Tokenize is broken on test_pep3131.py because regular expressions are @@ -1860,10 +1908,10 @@ def test_random_files(self): testfiles.remove(os.path.join(tempdir, "test_unicode_identifiers.py")) - # TODO: Remove this once we can unparse PEP 701 syntax + # TODO: Remove this once we can untokenize PEP 701 syntax testfiles.remove(os.path.join(tempdir, "test_fstring.py")) - for f in ('buffer', 'builtin', 'fileio', 'inspect', 'os', 'platform', 'sys'): + for f in ('buffer', 'builtin', 'fileio', 'os', 'platform', 'sys'): testfiles.remove(os.path.join(tempdir, "test_%s.py") % f) if not support.is_resource_enabled("cpu"): @@ -2278,6 +2326,54 @@ def test_string(self): FSTRING_START \'f"\' (1, 0) (1, 2) FSTRING_MIDDLE 'hola\\\\\\\\\\\\r\\\\ndfgf' (1, 2) (1, 16) FSTRING_END \'"\' (1, 16) (1, 17) + """) + + self.check_tokenize("""\ +f'''__{ + x:a +}__'''""", """\ + FSTRING_START "f'''" (1, 0) (1, 4) + FSTRING_MIDDLE '__' (1, 4) (1, 6) + LBRACE '{' (1, 6) (1, 7) + NAME 'x' (2, 4) (2, 5) + COLON ':' (2, 5) (2, 6) + FSTRING_MIDDLE 'a\\n' (2, 6) (3, 0) + RBRACE '}' (3, 0) (3, 1) + FSTRING_MIDDLE '__' (3, 1) (3, 3) + FSTRING_END "'''" (3, 3) (3, 6) + """) + + self.check_tokenize("""\ +f'''__{ + x:a + b + c + d +}__'''""", """\ + FSTRING_START "f'''" (1, 0) (1, 4) + FSTRING_MIDDLE '__' (1, 4) (1, 6) + LBRACE '{' (1, 6) (1, 7) + NAME 'x' (2, 4) (2, 5) + COLON ':' (2, 5) (2, 6) + FSTRING_MIDDLE 'a\\n b\\n c\\n d\\n' (2, 6) (6, 0) + RBRACE '}' (6, 0) (6, 1) + FSTRING_MIDDLE '__' (6, 1) (6, 3) + FSTRING_END "'''" (6, 3) (6, 6) + """) + + self.check_tokenize("""\ +f'__{ + x:d +}__'""", """\ + FSTRING_START "f'" (1, 0) (1, 2) + FSTRING_MIDDLE '__' (1, 2) (1, 4) + LBRACE '{' (1, 4) (1, 5) + NAME 'x' (2, 4) (2, 5) + COLON ':' (2, 5) (2, 6) + FSTRING_MIDDLE 'd' (2, 6) (2, 7) + RBRACE '}' (3, 0) (3, 1) + FSTRING_MIDDLE '__' (3, 1) (3, 3) + FSTRING_END "'" (3, 3) (3, 4) """) def test_function(self): @@ -2521,7 +2617,7 @@ def test_tabs(self): def test_async(self): self.check_tokenize('async = 1', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) EQUAL '=' (1, 6) (1, 7) NUMBER '1' (1, 8) (1, 9) """) @@ -2530,21 +2626,21 @@ def test_async(self): NAME 'a' (1, 0) (1, 1) EQUAL '=' (1, 2) (1, 3) LPAR '(' (1, 4) (1, 5) - ASYNC 'async' (1, 5) (1, 10) + NAME 'async' (1, 5) (1, 10) EQUAL '=' (1, 11) (1, 12) NUMBER '1' (1, 13) (1, 14) RPAR ')' (1, 14) (1, 15) """) self.check_tokenize('async()', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) LPAR '(' (1, 5) (1, 6) RPAR ')' (1, 6) (1, 7) """) self.check_tokenize('class async(Bar):pass', """\ NAME 'class' (1, 0) (1, 5) - ASYNC 'async' (1, 6) (1, 11) + NAME 'async' (1, 6) (1, 11) LPAR '(' (1, 11) (1, 12) NAME 'Bar' (1, 12) (1, 15) RPAR ')' (1, 15) (1, 16) @@ -2554,13 +2650,13 @@ def test_async(self): self.check_tokenize('class async:pass', """\ NAME 'class' (1, 0) (1, 5) - ASYNC 'async' (1, 6) (1, 11) + NAME 'async' (1, 6) (1, 11) COLON ':' (1, 11) (1, 12) NAME 'pass' (1, 12) (1, 16) """) self.check_tokenize('await = 1', """\ - AWAIT 'await' (1, 0) (1, 5) + NAME 'await' (1, 0) (1, 5) EQUAL '=' (1, 6) (1, 7) NUMBER '1' (1, 8) (1, 9) """) @@ -2568,11 +2664,11 @@ def test_async(self): self.check_tokenize('foo.async', """\ NAME 'foo' (1, 0) (1, 3) DOT '.' (1, 3) (1, 4) - ASYNC 'async' (1, 4) (1, 9) + NAME 'async' (1, 4) (1, 9) """) self.check_tokenize('async for a in b: pass', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NAME 'for' (1, 6) (1, 9) NAME 'a' (1, 10) (1, 11) NAME 'in' (1, 12) (1, 14) @@ -2582,7 +2678,7 @@ def test_async(self): """) self.check_tokenize('async with a as b: pass', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NAME 'with' (1, 6) (1, 10) NAME 'a' (1, 11) (1, 12) NAME 'as' (1, 13) (1, 15) @@ -2592,45 +2688,45 @@ def test_async(self): """) self.check_tokenize('async.foo', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) DOT '.' (1, 5) (1, 6) NAME 'foo' (1, 6) (1, 9) """) self.check_tokenize('async', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) """) self.check_tokenize('async\n#comment\nawait', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NEWLINE '' (1, 5) (1, 5) - AWAIT 'await' (3, 0) (3, 5) + NAME 'await' (3, 0) (3, 5) """) self.check_tokenize('async\n...\nawait', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NEWLINE '' (1, 5) (1, 5) ELLIPSIS '...' (2, 0) (2, 3) NEWLINE '' (2, 3) (2, 3) - AWAIT 'await' (3, 0) (3, 5) + NAME 'await' (3, 0) (3, 5) """) self.check_tokenize('async\nawait', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NEWLINE '' (1, 5) (1, 5) - AWAIT 'await' (2, 0) (2, 5) + NAME 'await' (2, 0) (2, 5) """) self.check_tokenize('foo.async + 1', """\ NAME 'foo' (1, 0) (1, 3) DOT '.' (1, 3) (1, 4) - ASYNC 'async' (1, 4) (1, 9) + NAME 'async' (1, 4) (1, 9) PLUS '+' (1, 10) (1, 11) NUMBER '1' (1, 12) (1, 13) """) self.check_tokenize('async def foo(): pass', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NAME 'def' (1, 6) (1, 9) NAME 'foo' (1, 10) (1, 13) LPAR '(' (1, 13) (1, 14) @@ -2647,7 +2743,7 @@ def foo(await): await async += 1 ''', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NAME 'def' (1, 6) (1, 9) NAME 'foo' (1, 10) (1, 13) LPAR '(' (1, 13) (1, 14) @@ -2658,12 +2754,12 @@ def foo(await): NAME 'def' (2, 2) (2, 5) NAME 'foo' (2, 6) (2, 9) LPAR '(' (2, 9) (2, 10) - AWAIT 'await' (2, 10) (2, 15) + NAME 'await' (2, 10) (2, 15) RPAR ')' (2, 15) (2, 16) COLON ':' (2, 16) (2, 17) NEWLINE '' (2, 17) (2, 17) INDENT '' (3, -1) (3, -1) - AWAIT 'await' (3, 4) (3, 9) + NAME 'await' (3, 4) (3, 9) EQUAL '=' (3, 10) (3, 11) NUMBER '1' (3, 12) (3, 13) NEWLINE '' (3, 13) (3, 13) @@ -2673,18 +2769,18 @@ def foo(await): COLON ':' (4, 6) (4, 7) NEWLINE '' (4, 7) (4, 7) INDENT '' (5, -1) (5, -1) - AWAIT 'await' (5, 4) (5, 9) + NAME 'await' (5, 4) (5, 9) NEWLINE '' (5, 9) (5, 9) DEDENT '' (6, -1) (6, -1) DEDENT '' (6, -1) (6, -1) - ASYNC 'async' (6, 0) (6, 5) + NAME 'async' (6, 0) (6, 5) PLUSEQUAL '+=' (6, 6) (6, 8) NUMBER '1' (6, 9) (6, 10) NEWLINE '' (6, 10) (6, 10) """) self.check_tokenize('async def foo():\n async for i in 1: pass', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NAME 'def' (1, 6) (1, 9) NAME 'foo' (1, 10) (1, 13) LPAR '(' (1, 13) (1, 14) @@ -2692,7 +2788,7 @@ def foo(await): COLON ':' (1, 15) (1, 16) NEWLINE '' (1, 16) (1, 16) INDENT '' (2, -1) (2, -1) - ASYNC 'async' (2, 2) (2, 7) + NAME 'async' (2, 2) (2, 7) NAME 'for' (2, 8) (2, 11) NAME 'i' (2, 12) (2, 13) NAME 'in' (2, 14) (2, 16) @@ -2703,14 +2799,14 @@ def foo(await): """) self.check_tokenize('async def foo(async): await', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NAME 'def' (1, 6) (1, 9) NAME 'foo' (1, 10) (1, 13) LPAR '(' (1, 13) (1, 14) - ASYNC 'async' (1, 14) (1, 19) + NAME 'async' (1, 14) (1, 19) RPAR ')' (1, 19) (1, 20) COLON ':' (1, 20) (1, 21) - AWAIT 'await' (1, 22) (1, 27) + NAME 'await' (1, 22) (1, 27) """) self.check_tokenize('''\ @@ -2734,7 +2830,7 @@ async def bar(): pass COLON ':' (3, 11) (3, 12) NAME 'pass' (3, 13) (3, 17) NEWLINE '' (3, 17) (3, 17) - ASYNC 'async' (4, 2) (4, 7) + NAME 'async' (4, 2) (4, 7) NAME 'def' (4, 8) (4, 11) NAME 'bar' (4, 12) (4, 15) LPAR '(' (4, 15) (4, 16) @@ -2742,7 +2838,7 @@ async def bar(): pass COLON ':' (4, 17) (4, 18) NAME 'pass' (4, 19) (4, 23) NEWLINE '' (4, 23) (4, 23) - AWAIT 'await' (6, 2) (6, 7) + NAME 'await' (6, 2) (6, 7) EQUAL '=' (6, 8) (6, 9) NUMBER '2' (6, 10) (6, 11) DEDENT '' (6, -1) (6, -1) @@ -2755,7 +2851,7 @@ def baz(): pass async def bar(): pass await = 2''', """\ - ASYNC 'async' (1, 0) (1, 5) + NAME 'async' (1, 0) (1, 5) NAME 'def' (1, 6) (1, 9) NAME 'f' (1, 10) (1, 11) LPAR '(' (1, 11) (1, 12) @@ -2770,7 +2866,7 @@ async def bar(): pass COLON ':' (3, 11) (3, 12) NAME 'pass' (3, 13) (3, 17) NEWLINE '' (3, 17) (3, 17) - ASYNC 'async' (4, 2) (4, 7) + NAME 'async' (4, 2) (4, 7) NAME 'def' (4, 8) (4, 11) NAME 'bar' (4, 12) (4, 15) LPAR '(' (4, 15) (4, 16) @@ -2778,7 +2874,7 @@ async def bar(): pass COLON ':' (4, 17) (4, 18) NAME 'pass' (4, 19) (4, 23) NEWLINE '' (4, 23) (4, 23) - AWAIT 'await' (6, 2) (6, 7) + NAME 'await' (6, 2) (6, 7) EQUAL '=' (6, 8) (6, 9) NUMBER '2' (6, 10) (6, 11) DEDENT '' (6, -1) (6, -1) diff --git a/Lib/test/test_tomllib/test_misc.py b/Lib/test/test_tomllib/test_misc.py index a477a219fd9ebd..9e677a337a2835 100644 --- a/Lib/test/test_tomllib/test_misc.py +++ b/Lib/test/test_tomllib/test_misc.py @@ -9,6 +9,7 @@ import sys import tempfile import unittest +from test import support from . import tomllib @@ -92,13 +93,23 @@ def test_deepcopy(self): self.assertEqual(obj_copy, expected_obj) def test_inline_array_recursion_limit(self): - # 465 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.465) - recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" - tomllib.loads(recursive_array_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 2) - 2 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) def test_inline_table_recursion_limit(self): - # 310 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.31) - recursive_table_toml = nest_count * "key = {" + nest_count * "}" - tomllib.loads(recursive_table_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 3) - 1 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py index 2102b9fceff568..c4395c7c0ad0c9 100644 --- a/Lib/test/test_tools/__init__.py +++ b/Lib/test/test_tools/__init__.py @@ -7,12 +7,6 @@ from test.support import import_helper -if support.check_sanitizer(address=True, memory=True): - # bpo-46633: Skip the test because it is too slow when Python is built - # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. - raise unittest.SkipTest("test too slow on ASAN/MSAN build") - - if not support.has_subprocess_support: raise unittest.SkipTest("test module requires subprocess") diff --git a/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py index 2ba36ca208f967..671ec2961e7f8f 100644 --- a/Lib/test/test_tools/test_freeze.py +++ b/Lib/test/test_tools/test_freeze.py @@ -15,8 +15,13 @@ @support.requires_zlib() @unittest.skipIf(sys.platform.startswith('win'), 'not supported on Windows') @support.skip_if_buildbot('not all buildbots have enough space') +# gh-103053: Skip test if Python is built with Profile Guided Optimization +# (PGO), since the test is just too slow in this case. +@unittest.skipIf(support.check_cflags_pgo(), + 'test is too slow with PGO') class TestFreeze(unittest.TestCase): + @support.requires_resource('cpu') # Building Python is slow def test_freeze_simple_script(self): script = textwrap.dedent(""" import sys diff --git a/Lib/test/test_tools/test_reindent.py b/Lib/test/test_tools/test_reindent.py index 3b0c793a38e4da..64e31c2b7703c0 100644 --- a/Lib/test/test_tools/test_reindent.py +++ b/Lib/test/test_tools/test_reindent.py @@ -25,7 +25,7 @@ def test_help(self): self.assertGreater(err, b'') def test_reindent_file_with_bad_encoding(self): - bad_coding_path = findfile('bad_coding.py') + bad_coding_path = findfile('bad_coding.py', subdir='tokenizedata') rc, out, err = assert_python_ok(self.script, '-r', bad_coding_path) self.assertEqual(out, b'') self.assertNotEqual(err, b'') diff --git a/Lib/test/test_tools/test_sundry.py b/Lib/test/test_tools/test_sundry.py index 2f8ba272164d32..d0b702d392cdf6 100644 --- a/Lib/test/test_tools/test_sundry.py +++ b/Lib/test/test_tools/test_sundry.py @@ -19,17 +19,11 @@ class TestSundryScripts(unittest.TestCase): # cleanly the logging module. @import_helper.mock_register_at_fork def test_sundry(self, mock_os): - old_modules = import_helper.modules_setup() - try: - for fn in os.listdir(scriptsdir): - if not fn.endswith('.py'): - continue - - name = fn[:-3] - import_tool(name) - finally: - # Unload all modules loaded in this test - import_helper.modules_cleanup(*old_modules) + for fn in os.listdir(scriptsdir): + if not fn.endswith('.py'): + continue + name = fn[:-3] + import_tool(name) if __name__ == '__main__': diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index 73339ebdb7c4e9..c1e289bcaff9e5 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -1,7 +1,7 @@ import os from pickle import dump import sys -from test.support import captured_stdout +from test.support import captured_stdout, requires_resource from test.support.os_helper import (TESTFN, rmtree, unlink) from test.support.script_helper import assert_python_ok, assert_python_failure import textwrap @@ -360,13 +360,19 @@ def tearDown(self): rmtree(TESTFN) unlink(TESTFN) - def _coverage(self, tracer, - cmd='import test.support, test.test_pprint;' - 'test.support.run_unittest(test.test_pprint.QueryTestCase)'): + DEFAULT_SCRIPT = '''if True: + import unittest + from test.test_pprint import QueryTestCase + loader = unittest.TestLoader() + tests = loader.loadTestsFromTestCase(QueryTestCase) + tests(unittest.TestResult()) + ''' + def _coverage(self, tracer, cmd=DEFAULT_SCRIPT): tracer.run(cmd) r = tracer.results() r.write_results(show_missing=True, summary=True, coverdir=TESTFN) + @requires_resource('cpu') def test_coverage(self): tracer = trace.Trace(trace=0, count=1) with captured_stdout() as stdout: diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index da7d1fb559203e..9bb1786c5472f5 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -596,6 +596,24 @@ def f_with_binary_operator(): result_lines = self.get_exception(f_with_binary_operator) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_binary_operators_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = 1 + b = "" + return ( a ) + b + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return ( a ) + b\n' + ' ~~~~~~~~~~^~~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript(self): def f_with_subscript(): some_dict = {'x': {'y': None}} @@ -630,6 +648,24 @@ def f_with_subscript(): result_lines = self.get_exception(f_with_subscript) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = [] + b = c = 1 + return b [ a ] + c + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return b [ a ] + c\n' + ' ~~~~~~^^^^^^^^^\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_traceback_specialization_with_syntax_error(self): bytecode = compile("1 / 0 / 1 / 2\n", TESTFN, "exec") @@ -918,7 +954,7 @@ class CPythonTracebackErrorCaretTests( @cpython_only @requires_debug_ranges() -class CPythonTracebackErrorCaretTests( +class CPythonTracebackLegacyErrorCaretTests( CAPIExceptionFormattingLegacyMixin, TracebackErrorLocationCaretTestBase, unittest.TestCase, @@ -927,7 +963,9 @@ class CPythonTracebackErrorCaretTests( Same set of tests as above but with Python's legacy internal traceback printing. """ -class TracebackFormatTests(unittest.TestCase): + +class TracebackFormatMixin: + DEBUG_RANGES = True def some_exception(self): raise KeyError('blah') @@ -1101,6 +1139,8 @@ def g(count=10): ) expected = (tb_line + result_g).splitlines() actual = stderr_g.getvalue().splitlines() + if not self.DEBUG_RANGES: + expected = [line for line in expected if not set(line.strip()) == {"^"}] self.assertEqual(actual, expected) # Check 2 different repetitive sections @@ -1137,6 +1177,8 @@ def h(count=10): ) expected = (result_h + result_g).splitlines() actual = stderr_h.getvalue().splitlines() + if not self.DEBUG_RANGES: + expected = [line for line in expected if not set(line.strip()) == {"^"}] self.assertEqual(actual, expected) # Check the boundary conditions. First, test just below the cutoff. @@ -1163,11 +1205,13 @@ def h(count=10): ) tb_line = ( 'Traceback (most recent call last):\n' - f' File "{__file__}", line {lineno_g+77}, in _check_recursive_traceback_display\n' + f' File "{__file__}", line {lineno_g+81}, in _check_recursive_traceback_display\n' ' g(traceback._RECURSIVE_CUTOFF)\n' ) expected = (tb_line + result_g).splitlines() actual = stderr_g.getvalue().splitlines() + if not self.DEBUG_RANGES: + expected = [line for line in expected if not set(line.strip()) == {"^"}] self.assertEqual(actual, expected) # Second, test just above the cutoff. @@ -1195,24 +1239,24 @@ def h(count=10): ) tb_line = ( 'Traceback (most recent call last):\n' - f' File "{__file__}", line {lineno_g+108}, in _check_recursive_traceback_display\n' + f' File "{__file__}", line {lineno_g+114}, in _check_recursive_traceback_display\n' ' g(traceback._RECURSIVE_CUTOFF + 1)\n' ) expected = (tb_line + result_g).splitlines() actual = stderr_g.getvalue().splitlines() + if not self.DEBUG_RANGES: + expected = [line for line in expected if not set(line.strip()) == {"^"}] self.assertEqual(actual, expected) @requires_debug_ranges() - def test_recursive_traceback_python(self): - self._check_recursive_traceback_display(traceback.print_exc) - - @cpython_only - @requires_debug_ranges() - def test_recursive_traceback_cpython_internal(self): - from _testcapi import exception_print - def render_exc(): - exception_print(sys.exception()) - self._check_recursive_traceback_display(render_exc) + def test_recursive_traceback(self): + if self.DEBUG_RANGES: + self._check_recursive_traceback_display(traceback.print_exc) + else: + from _testcapi import exception_print + def render_exc(): + exception_print(sys.exception()) + self._check_recursive_traceback_display(render_exc) def test_format_stack(self): def fmt(): @@ -1285,7 +1329,8 @@ def test_exception_group_deep_recursion_traceback(self): def test_print_exception_bad_type_capi(self): from _testcapi import exception_print with captured_output("stderr") as stderr: - exception_print(42) + with support.catch_unraisable_exception(): + exception_print(42) self.assertEqual( stderr.getvalue(), ('TypeError: print_exception(): ' @@ -1309,6 +1354,24 @@ def test_print_exception_bad_type_python(self): boundaries = re.compile( '(%s|%s)' % (re.escape(cause_message), re.escape(context_message))) +class TestTracebackFormat(unittest.TestCase, TracebackFormatMixin): + pass + +@cpython_only +class TestFallbackTracebackFormat(unittest.TestCase, TracebackFormatMixin): + DEBUG_RANGES = False + def setUp(self) -> None: + self.original_unraisable_hook = sys.unraisablehook + sys.unraisablehook = lambda *args: None + self.original_hook = traceback._print_exception_bltin + traceback._print_exception_bltin = lambda *args: 1/0 + return super().setUp() + + def tearDown(self) -> None: + traceback._print_exception_bltin = self.original_hook + sys.unraisablehook = self.original_unraisable_hook + return super().tearDown() + class BaseExceptionReportingTests: def get_exception(self, exception_or_callable): @@ -1563,27 +1626,28 @@ def __repr__(self): err_msg = "b'please do not show me as numbers'" self.assertEqual(self.get_report(e), vanilla + err_msg + '\n') - def test_exception_with_note_with_multiple_notes(self): - e = ValueError(42) - vanilla = self.get_report(e) + def test_exception_with_multiple_notes(self): + for e in [ValueError(42), SyntaxError('bad syntax')]: + with self.subTest(e=e): + vanilla = self.get_report(e) - e.add_note('Note 1') - e.add_note('Note 2') - e.add_note('Note 3') + e.add_note('Note 1') + e.add_note('Note 2') + e.add_note('Note 3') - self.assertEqual( - self.get_report(e), - vanilla + 'Note 1\n' + 'Note 2\n' + 'Note 3\n') + self.assertEqual( + self.get_report(e), + vanilla + 'Note 1\n' + 'Note 2\n' + 'Note 3\n') - del e.__notes__ - e.add_note('Note 4') - del e.__notes__ - e.add_note('Note 5') - e.add_note('Note 6') + del e.__notes__ + e.add_note('Note 4') + del e.__notes__ + e.add_note('Note 5') + e.add_note('Note 6') - self.assertEqual( - self.get_report(e), - vanilla + 'Note 5\n' + 'Note 6\n') + self.assertEqual( + self.get_report(e), + vanilla + 'Note 5\n' + 'Note 6\n') def test_exception_qualname(self): class A: @@ -3539,6 +3603,7 @@ def CHECK(a, b, expected): CHECK("AttributeError", "AttributeErrorTests", 10) CHECK("ABA", "AAB", 4) + @support.requires_resource('cpu') def test_levenshtein_distance_short_circuit(self): if not LEVENSHTEIN_DATA_FILE.is_file(): self.fail( diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 4af4ca3b977236..bea124521032d1 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -173,9 +173,11 @@ def test_set_traceback_limit(self): self.assertEqual(len(traceback), 1) self.assertEqual(traceback, obj_traceback) - def find_trace(self, traces, traceback): + def find_trace(self, traces, traceback, size): + # filter also by size to ignore the memory allocated by + # _PyRefchain_Trace() if Python is built with Py_TRACE_REFS. for trace in traces: - if trace[2] == traceback._frames: + if trace[2] == traceback._frames and trace[1] == size: return trace self.fail("trace not found") @@ -186,11 +188,10 @@ def test_get_traces(self): obj, obj_traceback = allocate_bytes(obj_size) traces = tracemalloc._get_traces() - trace = self.find_trace(traces, obj_traceback) + trace = self.find_trace(traces, obj_traceback, obj_size) self.assertIsInstance(trace, tuple) domain, size, traceback, length = trace - self.assertEqual(size, obj_size) self.assertEqual(traceback, obj_traceback._frames) tracemalloc.stop() @@ -208,17 +209,18 @@ def allocate_bytes4(size): # Ensure that two identical tracebacks are not duplicated tracemalloc.stop() tracemalloc.start(4) - obj_size = 123 - obj1, obj1_traceback = allocate_bytes4(obj_size) - obj2, obj2_traceback = allocate_bytes4(obj_size) + obj1_size = 123 + obj2_size = 125 + obj1, obj1_traceback = allocate_bytes4(obj1_size) + obj2, obj2_traceback = allocate_bytes4(obj2_size) traces = tracemalloc._get_traces() obj1_traceback._frames = tuple(reversed(obj1_traceback._frames)) obj2_traceback._frames = tuple(reversed(obj2_traceback._frames)) - trace1 = self.find_trace(traces, obj1_traceback) - trace2 = self.find_trace(traces, obj2_traceback) + trace1 = self.find_trace(traces, obj1_traceback, obj1_size) + trace2 = self.find_trace(traces, obj2_traceback, obj2_size) domain1, size1, traceback1, length1 = trace1 domain2, size2, traceback2, length2 = trace2 self.assertIs(traceback2, traceback1) diff --git a/Lib/test/test_ttk/test_style.py b/Lib/test/test_ttk/test_style.py index 0ec95cf6b5ffc9..f9c56ec2357451 100644 --- a/Lib/test/test_ttk/test_style.py +++ b/Lib/test/test_ttk/test_style.py @@ -170,7 +170,7 @@ def test_map_custom_copy(self): newname = f'C.{name}' self.assertEqual(style.map(newname), {}) style.map(newname, **default) - if theme == 'alt' and name == '.' and get_tk_patchlevel() < (8, 6, 1): + if theme == 'alt' and name == '.' and get_tk_patchlevel(self.root) < (8, 6, 1): default['embossed'] = [('disabled', '1')] self.assertEqual(style.map(newname), default) for key, value in default.items(): diff --git a/Lib/test/test_ttk/test_widgets.py b/Lib/test/test_ttk/test_widgets.py index 79d65b496abdc6..fd1a748a498ac5 100644 --- a/Lib/test/test_ttk/test_widgets.py +++ b/Lib/test/test_ttk/test_widgets.py @@ -5,7 +5,7 @@ import sys from test.test_ttk_textonly import MockTclObj -from test.test_tkinter.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, +from test.test_tkinter.support import (AbstractTkTest, tk_version, get_tk_patchlevel, simulate_mouse_click, AbstractDefaultRootTest) from test.test_tkinter.widget_tests import (add_standard_options, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests) @@ -19,7 +19,7 @@ def test_configure_class(self): widget = self.create() self.assertEqual(widget['class'], '') errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): + if get_tk_patchlevel(self.root) < (8, 6, 0, 'beta', 3): errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg) widget2 = self.create(class_='Foo') @@ -560,7 +560,7 @@ def test_configure_orient(self): widget = self.create() self.assertEqual(str(widget['orient']), 'vertical') errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): + if get_tk_patchlevel(self.root) < (8, 6, 0, 'beta', 3): errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'orient', 'horizontal', errmsg=errmsg) @@ -1526,7 +1526,7 @@ def test_heading(self): def test_heading_callback(self): def simulate_heading_click(x, y): - if tcl_version >= (8, 6): + if tk_version >= (8, 6): self.assertEqual(self.tv.identify_column(x), '#0') self.assertEqual(self.tv.identify_region(x, y), 'heading') simulate_mouse_click(self.tv, x, y) diff --git a/Lib/test/test_tty.py b/Lib/test/test_tty.py new file mode 100644 index 00000000000000..6993047492b5ec --- /dev/null +++ b/Lib/test/test_tty.py @@ -0,0 +1,80 @@ +import os +import unittest +from test.support.import_helper import import_module + +termios = import_module('termios') +tty = import_module('tty') + + +@unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") +class TestTty(unittest.TestCase): + + def setUp(self): + master_fd, self.fd = os.openpty() + self.addCleanup(os.close, master_fd) + self.stream = self.enterContext(open(self.fd, 'wb', buffering=0)) + self.fd = self.stream.fileno() + self.mode = termios.tcgetattr(self.fd) + self.addCleanup(termios.tcsetattr, self.fd, termios.TCSANOW, self.mode) + self.addCleanup(termios.tcsetattr, self.fd, termios.TCSAFLUSH, self.mode) + + def check_cbreak(self, mode): + self.assertEqual(mode[0] & termios.ICRNL, 0) + self.assertEqual(mode[3] & termios.ECHO, 0) + self.assertEqual(mode[3] & termios.ICANON, 0) + self.assertEqual(mode[6][termios.VMIN], 1) + self.assertEqual(mode[6][termios.VTIME], 0) + + def check_raw(self, mode): + self.check_cbreak(mode) + self.assertEqual(mode[0] & termios.ISTRIP, 0) + self.assertEqual(mode[0] & termios.ICRNL, 0) + self.assertEqual(mode[1] & termios.OPOST, 0) + self.assertEqual(mode[2] & termios.PARENB, termios.CS8 & termios.PARENB) + self.assertEqual(mode[2] & termios.CSIZE, termios.CS8 & termios.CSIZE) + self.assertEqual(mode[2] & termios.CS8, termios.CS8) + self.assertEqual(mode[3] & termios.ECHO, 0) + self.assertEqual(mode[3] & termios.ICANON, 0) + self.assertEqual(mode[3] & termios.ISIG, 0) + self.assertEqual(mode[6][termios.VMIN], 1) + self.assertEqual(mode[6][termios.VTIME], 0) + + def test_cfmakeraw(self): + mode = termios.tcgetattr(self.fd) + self.assertEqual(mode, self.mode) + tty.cfmakeraw(mode) + self.check_raw(mode) + self.assertEqual(mode[4], self.mode[4]) + self.assertEqual(mode[5], self.mode[5]) + + def test_cfmakecbreak(self): + mode = termios.tcgetattr(self.fd) + self.assertEqual(mode, self.mode) + tty.cfmakecbreak(mode) + self.check_cbreak(mode) + self.assertEqual(mode[1], self.mode[1]) + self.assertEqual(mode[2], self.mode[2]) + self.assertEqual(mode[4], self.mode[4]) + self.assertEqual(mode[5], self.mode[5]) + + def test_setraw(self): + mode = tty.setraw(self.fd) + mode2 = termios.tcgetattr(self.fd) + self.check_raw(mode2) + mode3 = tty.setraw(self.fd, termios.TCSANOW) + self.assertEqual(mode3, mode2) + tty.setraw(self.stream) + tty.setraw(fd=self.fd, when=termios.TCSANOW) + + def test_setcbreak(self): + mode = tty.setcbreak(self.fd) + mode2 = termios.tcgetattr(self.fd) + self.check_cbreak(mode2) + mode3 = tty.setcbreak(self.fd, termios.TCSANOW) + self.assertEqual(mode3, mode2) + tty.setcbreak(self.stream) + tty.setcbreak(fd=self.fd, when=termios.TCSANOW) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py index 3f9f129a3dd200..14121a590a5026 100644 --- a/Lib/test/test_turtle.py +++ b/Lib/test/test_turtle.py @@ -461,5 +461,25 @@ def test_teleport(self): self.assertTrue(tpen.isdown()) +class TestModuleLevel(unittest.TestCase): + def test_all_signatures(self): + import inspect + + known_signatures = { + 'teleport': + '(x=None, y=None, *, fill_gap: bool = False) -> None', + 'undo': '()', + 'goto': '(x, y=None)', + 'bgcolor': '(*args)', + 'pen': '(pen=None, **pendict)', + } + + for name in known_signatures: + with self.subTest(name=name): + obj = getattr(turtle, name) + sig = inspect.signature(obj) + self.assertEqual(str(sig), known_signatures[name]) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_type_aliases.py b/Lib/test/test_type_aliases.py index 0ce97f57de6860..8f0a998e1f3dc1 100644 --- a/Lib/test/test_type_aliases.py +++ b/Lib/test/test_type_aliases.py @@ -168,6 +168,24 @@ def test_recursive_repr(self): self.assertEqual(repr(GenericRecursive[GenericRecursive[int]]), "GenericRecursive[GenericRecursive[int]]") + def test_raising(self): + type MissingName = list[_My_X] + with self.assertRaisesRegex( + NameError, + "cannot access free variable '_My_X' where it is not associated with a value", + ): + MissingName.__value__ + _My_X = int + self.assertEqual(MissingName.__value__, list[int]) + del _My_X + # Cache should still work: + self.assertEqual(MissingName.__value__, list[int]) + + # Explicit exception: + type ExprException = 1 / 0 + with self.assertRaises(ZeroDivisionError): + ExprException.__value__ + class TypeAliasConstructorTest(unittest.TestCase): def test_basic(self): diff --git a/Lib/test/test_type_cache.py b/Lib/test/test_type_cache.py index 24f83cd3e172c7..72587ecc11b6f3 100644 --- a/Lib/test/test_type_cache.py +++ b/Lib/test/test_type_cache.py @@ -58,4 +58,4 @@ class C: if __name__ == "__main__": - support.run_unittest(TypeCacheTests) + unittest.main() diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index aba4a44be9da96..9a11fab237235e 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -260,8 +260,8 @@ def test_asyncdef(self): self.assertEqual(tree.body[1].type_comment, None) def test_asyncvar(self): - for tree in self.parse_all(asyncvar, maxver=6): - pass + with self.assertRaises(SyntaxError): + self.classic_parse(asyncvar) def test_asynccomp(self): for tree in self.parse_all(asynccomp, minver=6): diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py index bced641a9661fd..25ee188731f31f 100644 --- a/Lib/test/test_type_params.py +++ b/Lib/test/test_type_params.py @@ -148,6 +148,10 @@ def test_disallowed_expressions(self): check_syntax_error(self, "def f[T: [(x := 3) for _ in range(2)]](): pass") check_syntax_error(self, "type T = [(x := 3) for _ in range(2)]") + def test_incorrect_mro_explicit_object(self): + with self.assertRaisesRegex(TypeError, r"\(MRO\) for bases object, Generic"): + class My[X](object): ... + class TypeParamsNonlocalTest(unittest.TestCase): def test_nonlocal_disallowed_01(self): @@ -408,6 +412,99 @@ def test_comprehension_02(self): func, = T.__bound__ self.assertEqual(func(), 1) + def test_gen_exp_in_nested_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner(make_base(T for _ in (1,)), make_base(T)): + pass + """ + C = run_code(code)["C"] + T, = C.__type_params__ + base1, base2 = C.Inner.__bases__ + self.assertEqual(list(base1.__arg__), [T]) + self.assertEqual(base2.__arg__, "class") + + def test_gen_exp_in_nested_generic_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner[U](make_base(T for _ in (1,)), make_base(T)): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_listcomp_in_nested_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner(make_base([T for _ in (1,)]), make_base(T)): + pass + """ + C = run_code(code)["C"] + T, = C.__type_params__ + base1, base2 = C.Inner.__bases__ + self.assertEqual(base1.__arg__, [T]) + self.assertEqual(base2.__arg__, "class") + + def test_listcomp_in_nested_generic_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner[U](make_base([T for _ in (1,)]), make_base(T)): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_gen_exp_in_generic_method(self): + code = """ + class C[T]: + T = "class" + def meth[U](x: (T for _ in (1,)), y: T): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_nested_scope_in_generic_alias(self): + code = """ + class C[T]: + T = "class" + {} + """ + error_cases = [ + "type Alias1[T] = lambda: T", + "type Alias2 = lambda: T", + "type Alias3[T] = (T for _ in (1,))", + "type Alias4 = (T for _ in (1,))", + "type Alias5[T] = [T for _ in (1,)]", + "type Alias6 = [T for _ in (1,)]", + ] + for case in error_cases: + with self.subTest(case=case): + with self.assertRaisesRegex(SyntaxError, + r"Cannot use [a-z]+ in annotation scope within class scope"): + run_code(code.format(case)) + + +def make_base(arg): + class Base: + __arg__ = arg + return Base + def global_generic_func[T](): pass @@ -597,6 +694,19 @@ class Cls: cls = ns["outer"]() self.assertEqual(cls.Alias.__value__, "class") + def test_nested_free(self): + ns = run_code(""" + def f(): + T = str + class C: + T = int + class D[U](T): + x = T + return C + """) + C = ns["f"]() + self.assertIn(int, C.D.__bases__) + self.assertIs(C.D.x, str) class TypeParamsManglingTest(unittest.TestCase): def test_mangling(self): @@ -952,3 +1062,43 @@ class NewStyle[T]: for case in cases: with self.subTest(case=case): weakref.ref(case) + + +class TypeParamsRuntimeTest(unittest.TestCase): + def test_name_error(self): + # gh-109118: This crashed the interpreter due to a refcounting bug + code = """ + class name_2[name_5]: + class name_4[name_5](name_0): + pass + """ + with self.assertRaises(NameError): + run_code(code) + + # Crashed with a slightly different stack trace + code = """ + class name_2[name_5]: + class name_4[name_5: name_5](name_0): + pass + """ + with self.assertRaises(NameError): + run_code(code) + + def test_broken_class_namespace(self): + code = """ + class WeirdMapping(dict): + def __missing__(self, key): + if key == "T": + raise RuntimeError + raise KeyError(key) + + class Meta(type): + def __prepare__(name, bases): + return WeirdMapping() + + class MyClass[V](metaclass=Meta): + class Inner[U](T): + pass + """ + with self.assertRaises(RuntimeError): + run_code(code) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 81744940f25b82..da32c4ea6477ce 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -4,6 +4,7 @@ import collections.abc from collections import namedtuple import copy +import _datetime import gc import inspect import pickle @@ -636,6 +637,9 @@ def test_traceback_and_frame_types(self): self.assertIsInstance(exc.__traceback__, types.TracebackType) self.assertIsInstance(exc.__traceback__.tb_frame, types.FrameType) + def test_capsule_type(self): + self.assertIsInstance(_datetime.datetime_CAPI, types.CapsuleType) + class UnionTests(unittest.TestCase): @@ -1397,6 +1401,7 @@ class A: pass class B(typing.Generic[T]): pass class C(B[int]): pass class D(B[str], float): pass + self.assertEqual(types.get_original_bases(A), (object,)) self.assertEqual(types.get_original_bases(B), (typing.Generic[T],)) self.assertEqual(types.get_original_bases(C), (B[int],)) @@ -1409,6 +1414,18 @@ class F(list[int]): pass self.assertEqual(types.get_original_bases(E), (list[T],)) self.assertEqual(types.get_original_bases(F), (list[int],)) + class FirstBase(typing.Generic[T]): pass + class SecondBase(typing.Generic[T]): pass + class First(FirstBase[int]): pass + class Second(SecondBase[int]): pass + class G(First, Second): pass + self.assertEqual(types.get_original_bases(G), (First, Second)) + + class First_(typing.Generic[T]): pass + class Second_(typing.Generic[T]): pass + class H(First_, Second_): pass + self.assertEqual(types.get_original_bases(H), (First_, Second_)) + class ClassBasedNamedTuple(typing.NamedTuple): x: int @@ -1887,6 +1904,33 @@ def test_pickle(self): self.assertEqual(ns, ns_roundtrip, pname) + def test_replace(self): + ns = types.SimpleNamespace(x=11, y=22) + + ns2 = copy.replace(ns) + self.assertEqual(ns2, ns) + self.assertIsNot(ns2, ns) + self.assertIs(type(ns2), types.SimpleNamespace) + self.assertEqual(vars(ns2), {'x': 11, 'y': 22}) + ns2.x = 3 + self.assertEqual(ns.x, 11) + ns.x = 4 + self.assertEqual(ns2.x, 3) + + self.assertEqual(vars(copy.replace(ns, x=1)), {'x': 1, 'y': 22}) + self.assertEqual(vars(copy.replace(ns, y=2)), {'x': 4, 'y': 2}) + self.assertEqual(vars(copy.replace(ns, x=1, y=2)), {'x': 1, 'y': 2}) + + def test_replace_subclass(self): + class Spam(types.SimpleNamespace): + pass + + spam = Spam(ham=8, eggs=9) + spam2 = copy.replace(spam, ham=5) + + self.assertIs(type(spam2), Spam) + self.assertEqual(vars(spam2), {'ham': 5, 'eggs': 9}) + def test_fake_namespace_compare(self): # Issue #24257: Incorrect use of PyObject_IsInstance() caused # SystemError. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 0450a87577ecea..1a1e0a259fd042 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -185,7 +185,7 @@ def test_cannot_subclass(self): class A(self.bottom_type): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class A(type(self.bottom_type)): + class B(type(self.bottom_type)): pass def test_cannot_instantiate(self): @@ -282,7 +282,7 @@ class C(type(Self)): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Self'): - class C(Self): + class D(Self): pass def test_cannot_init(self): @@ -339,7 +339,7 @@ class C(type(LiteralString)): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.LiteralString'): - class C(LiteralString): + class D(LiteralString): pass def test_cannot_init(self): @@ -483,7 +483,7 @@ class V(TypeVar): pass T = TypeVar("T") with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_INSTANCE % 'TypeVar'): - class V(T): pass + class W(T): pass def test_cannot_instantiate_vars(self): with self.assertRaises(TypeError): @@ -544,6 +544,22 @@ def test_bad_var_substitution(self): with self.assertRaises(TypeError): list[T][arg] + def test_many_weakrefs(self): + # gh-108295: this used to segfault + for cls in (ParamSpec, TypeVarTuple, TypeVar): + with self.subTest(cls=cls): + vals = weakref.WeakValueDictionary() + + for x in range(10): + vals[x] = cls(str(x)) + del vals + + def test_constructor(self): + T = TypeVar(name="T") + self.assertEqual(T.__name__, "T") + self.assertEqual(T.__constraints__, ()) + self.assertIs(T.__bound__, None) + def template_replace(templates: list[str], replacements: dict[str, list[str]]) -> list[tuple[str]]: """Renders templates with possible combinations of replacements. @@ -1234,20 +1250,20 @@ class C(TypeVarTuple): pass Ts = TypeVarTuple('Ts') with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_INSTANCE % 'TypeVarTuple'): - class C(Ts): pass + class D(Ts): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(Unpack)): pass + class E(type(Unpack)): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(*Ts)): pass + class F(type(*Ts)): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(Unpack[Ts])): pass + class G(type(Unpack[Ts])): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Unpack'): - class C(Unpack): pass + class H(Unpack): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): - class C(*Ts): pass + class I(*Ts): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): - class C(Unpack[Ts]): pass + class J(Unpack[Ts]): pass def test_variadic_class_args_are_correct(self): T = TypeVar('T') @@ -1421,12 +1437,12 @@ def test_variadic_class_with_duplicate_typevartuples_fails(self): with self.assertRaises(TypeError): class C(Generic[*Ts1, *Ts1]): pass with self.assertRaises(TypeError): - class C(Generic[Unpack[Ts1], Unpack[Ts1]]): pass + class D(Generic[Unpack[Ts1], Unpack[Ts1]]): pass with self.assertRaises(TypeError): - class C(Generic[*Ts1, *Ts2, *Ts1]): pass + class E(Generic[*Ts1, *Ts2, *Ts1]): pass with self.assertRaises(TypeError): - class C(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass + class F(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass def test_type_concatenation_in_variadic_class_argument_list_succeeds(self): Ts = TypeVarTuple('Ts') @@ -1794,11 +1810,11 @@ def test_cannot_subclass(self): class C(Union): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(Union)): + class D(type(Union)): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Union\[int, str\]'): - class C(Union[int, str]): + class E(Union[int, str]): pass def test_cannot_instantiate(self): @@ -2547,10 +2563,10 @@ class BP(Protocol): pass class P(C, Protocol): pass with self.assertRaises(TypeError): - class P(Protocol, C): + class Q(Protocol, C): pass with self.assertRaises(TypeError): - class P(BP, C, Protocol): + class R(BP, C, Protocol): pass class D(BP, C): pass @@ -2826,7 +2842,7 @@ class NotAProtocolButAnImplicitSubclass3: meth: Callable[[], None] meth2: Callable[[int, str], bool] def meth(self): pass - def meth(self, x, y): return True + def meth2(self, x, y): return True self.assertNotIsSubclass(AnnotatedButNotAProtocol, CallableMembersProto) self.assertIsSubclass(NotAProtocolButAnImplicitSubclass, CallableMembersProto) @@ -3648,11 +3664,11 @@ def test_protocols_bad_subscripts(self): with self.assertRaises(TypeError): class P(Protocol[T, T]): pass with self.assertRaises(TypeError): - class P(Protocol[int]): pass + class Q(Protocol[int]): pass with self.assertRaises(TypeError): - class P(Protocol[T], Protocol[S]): pass + class R(Protocol[T], Protocol[S]): pass with self.assertRaises(TypeError): - class P(typing.Mapping[T, S], Protocol[T]): pass + class S(typing.Mapping[T, S], Protocol[T]): pass def test_generic_protocols_repr(self): T = TypeVar('T') @@ -3791,6 +3807,39 @@ class E: self.assertIsInstance(E(), D) + def test_runtime_checkable_with_match_args(self): + @runtime_checkable + class P_regular(Protocol): + x: int + y: int + + @runtime_checkable + class P_match(Protocol): + __match_args__ = ('x', 'y') + x: int + y: int + + class Regular: + def __init__(self, x: int, y: int): + self.x = x + self.y = y + + class WithMatch: + __match_args__ = ('x', 'y', 'z') + def __init__(self, x: int, y: int, z: int): + self.x = x + self.y = y + self.z = z + + class Nope: ... + + self.assertIsInstance(Regular(1, 2), P_regular) + self.assertIsInstance(Regular(1, 2), P_match) + self.assertIsInstance(WithMatch(1, 2, 3), P_regular) + self.assertIsInstance(WithMatch(1, 2, 3), P_match) + self.assertNotIsInstance(Nope(), P_regular) + self.assertNotIsInstance(Nope(), P_match) + def test_supports_int(self): self.assertIsSubclass(int, typing.SupportsInt) self.assertNotIsSubclass(str, typing.SupportsInt) @@ -4084,12 +4133,28 @@ class NewGeneric(Generic): ... with self.assertRaises(TypeError): class MyGeneric(Generic[T], Generic[S]): ... with self.assertRaises(TypeError): - class MyGeneric(List[T], Generic[S]): ... + class MyGeneric2(List[T], Generic[S]): ... with self.assertRaises(TypeError): Generic[()] - class C(Generic[T]): pass + class D(Generic[T]): pass with self.assertRaises(TypeError): - C[()] + D[()] + + def test_generic_subclass_checks(self): + for typ in [list[int], List[int], + tuple[int, str], Tuple[int, str], + typing.Callable[..., None], + collections.abc.Callable[..., None]]: + with self.subTest(typ=typ): + self.assertRaises(TypeError, issubclass, typ, object) + self.assertRaises(TypeError, issubclass, typ, type) + self.assertRaises(TypeError, issubclass, typ, typ) + self.assertRaises(TypeError, issubclass, object, typ) + + # isinstance is fine: + self.assertTrue(isinstance(typ, object)) + # but, not when the right arg is also a generic: + self.assertRaises(TypeError, isinstance, typ, typ) def test_init(self): T = TypeVar('T') @@ -4810,7 +4875,7 @@ class Test(Generic[T], Final): class Subclass(Test): pass with self.assertRaises(FinalException): - class Subclass(Test[int]): + class Subclass2(Test[int]): pass def test_nested(self): @@ -5048,15 +5113,15 @@ def test_cannot_subclass(self): class C(type(ClassVar)): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(ClassVar[int])): + class D(type(ClassVar[int])): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.ClassVar'): - class C(ClassVar): + class E(ClassVar): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.ClassVar\[int\]'): - class C(ClassVar[int]): + class F(ClassVar[int]): pass def test_cannot_init(self): @@ -5098,15 +5163,15 @@ def test_cannot_subclass(self): class C(type(Final)): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(Final[int])): + class D(type(Final[int])): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Final'): - class C(Final): + class E(Final): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Final\[int\]'): - class C(Final[int]): + class F(Final[int]): pass def test_cannot_init(self): @@ -5361,7 +5426,7 @@ def test_errors(self): # We need this to make sure that `@no_type_check` respects `__module__` attr: -from test import ann_module8 +from test.typinganndata import ann_module8 @no_type_check class NoTypeCheck_Outer: @@ -5952,7 +6017,9 @@ def test_overload_registry_repeated(self): # Definitions needed for features introduced in Python 3.6 -from test import ann_module, ann_module2, ann_module3, ann_module5, ann_module6 +from test.typinganndata import ( + ann_module, ann_module2, ann_module3, ann_module5, ann_module6, +) T_a = TypeVar('T_a') @@ -7237,15 +7304,15 @@ class A: class X(NamedTuple, A): x: int with self.assertRaises(TypeError): - class X(NamedTuple, tuple): + class Y(NamedTuple, tuple): x: int with self.assertRaises(TypeError): - class X(NamedTuple, NamedTuple): + class Z(NamedTuple, NamedTuple): x: int - class A(NamedTuple): + class B(NamedTuple): x: int with self.assertRaises(TypeError): - class X(NamedTuple, A): + class C(NamedTuple, B): y: str def test_generic(self): @@ -7558,6 +7625,17 @@ def test_total(self): self.assertEqual(Options.__required_keys__, frozenset()) self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'}) + def test_total_inherits_non_total(self): + class TD1(TypedDict, total=False): + a: int + + self.assertIs(TD1.__total__, False) + + class TD2(TD1): + b: str + + self.assertIs(TD2.__total__, True) + def test_optional_keys(self): class Point2Dor3D(Point2D, total=False): z: int @@ -7998,15 +8076,15 @@ def test_cannot_subclass(self): class C(type(Required)): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(Required[int])): + class D(type(Required[int])): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Required'): - class C(Required): + class E(Required): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Required\[int\]'): - class C(Required[int]): + class F(Required[int]): pass def test_cannot_init(self): @@ -8046,15 +8124,15 @@ def test_cannot_subclass(self): class C(type(NotRequired)): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(NotRequired[int])): + class D(type(NotRequired[int])): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.NotRequired'): - class C(NotRequired): + class E(NotRequired): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.NotRequired\[int\]'): - class C(NotRequired[int]): + class F(NotRequired[int]): pass def test_cannot_init(self): @@ -8153,7 +8231,7 @@ class A(typing.Match): TypeError, r"type 're\.Pattern' is not an acceptable base type", ): - class A(typing.Pattern): + class B(typing.Pattern): pass @@ -8161,8 +8239,7 @@ class AnnotatedTests(BaseTestCase): def test_new(self): with self.assertRaisesRegex( - TypeError, - 'Type Annotated cannot be instantiated', + TypeError, 'Cannot instantiate typing.Annotated', ): Annotated() @@ -8501,7 +8578,7 @@ class C(TypeAlias): pass with self.assertRaises(TypeError): - class C(type(TypeAlias)): + class D(type(TypeAlias)): pass def test_repr(self): @@ -8891,19 +8968,19 @@ def test_cannot_subclass(self): with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpec'): class C(ParamSpec): pass with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecArgs'): - class C(ParamSpecArgs): pass + class D(ParamSpecArgs): pass with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecKwargs'): - class C(ParamSpecKwargs): pass + class E(ParamSpecKwargs): pass P = ParamSpec('P') with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_INSTANCE % 'ParamSpec'): - class C(P): pass + class F(P): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_INSTANCE % 'ParamSpecArgs'): - class C(P.args): pass + class G(P.args): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_INSTANCE % 'ParamSpecKwargs'): - class C(P.kwargs): pass + class H(P.kwargs): pass class ConcatenateTests(BaseTestCase): @@ -8984,15 +9061,15 @@ def test_cannot_subclass(self): class C(type(TypeGuard)): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): - class C(type(TypeGuard[int])): + class D(type(TypeGuard[int])): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.TypeGuard'): - class C(TypeGuard): + class E(TypeGuard): pass with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.TypeGuard\[int\]'): - class C(TypeGuard[int]): + class F(TypeGuard[int]): pass def test_cannot_init(self): @@ -9335,6 +9412,10 @@ def test_all(self): self.assertIn('SupportsComplex', a) def test_all_exported_names(self): + # ensure all dynamically created objects are actualised + for name in typing.__all__: + getattr(typing, name) + actual_all = set(typing.__all__) computed_all = { k for k, v in vars(typing).items() diff --git a/Lib/test/test_unicode_identifiers.py b/Lib/test/test_unicode_identifiers.py index 5b9ced5d1cb837..63c6c055824b20 100644 --- a/Lib/test/test_unicode_identifiers.py +++ b/Lib/test/test_unicode_identifiers.py @@ -19,7 +19,7 @@ def test_non_bmp_normalized(self): def test_invalid(self): try: - from test import badsyntax_3131 + from test.tokenizedata import badsyntax_3131 except SyntaxError as err: self.assertEqual(str(err), "invalid character '€' (U+20AC) (badsyntax_3131.py, line 2)") diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 3dc0790ca15b41..6adf03316ca0bb 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -18,7 +18,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'e708c31c0d51f758adf475cb7201cf80917362be' + expectedchecksum = '63aa77dcb36b0e1df082ee2a6071caeda7f0955e' @requires_resource('cpu') def test_method_checksum(self): @@ -71,7 +71,7 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): # Update this if the database changes. Make sure to do a full rebuild # (e.g. 'make distclean && make') to get the correct checksum. - expectedchecksum = '26ff0d31c14194b4606a5b3a81ac36df3a14e331' + expectedchecksum = '232affd2a50ec4bd69d2482aa0291385cbdefaba' @requires_resource('cpu') def test_function_checksum(self): @@ -313,6 +313,7 @@ def test_ucd_510(self): self.assertTrue("\u1d79".upper()=='\ua77d') self.assertTrue(".".upper()=='.') + @requires_resource('cpu') def test_bug_5828(self): self.assertEqual("\u1d79".lower(), "\u1d79") # Only U+0000 should have U+0000 as its upper/lower/titlecase variant @@ -353,6 +354,7 @@ def unistr(data): return "".join([chr(x) for x in data]) @requires_resource('network') + @requires_resource('cpu') def test_normalization(self): TESTDATAFILE = "NormalizationTest.txt" TESTDATAURL = f"http://www.pythontest.net/unicode/{unicodedata.unidata_version}/{TESTDATAFILE}" diff --git a/Lib/test/test_unittest/test_discovery.py b/Lib/test/test_unittest/test_discovery.py index 946fa1258ea25e..dcb72d73efceab 100644 --- a/Lib/test/test_unittest/test_discovery.py +++ b/Lib/test/test_unittest/test_discovery.py @@ -6,7 +6,6 @@ import pickle from test import support from test.support import import_helper -import test.test_importlib.util import unittest import unittest.mock @@ -572,7 +571,7 @@ def _get_module_from_name(name): result = unittest.TestResult() suite.run(result) self.assertEqual(len(result.skipped), 1) - self.assertEqual(result.testsRun, 1) + self.assertEqual(result.testsRun, 0) self.assertEqual(import_calls, ['my_package']) # Check picklability @@ -826,6 +825,8 @@ def restore(): 'as dotted module names') def test_discovery_failed_discovery(self): + from test.test_importlib import util + loader = unittest.TestLoader() package = types.ModuleType('package') @@ -837,7 +838,7 @@ def _import(packagename, *args, **kwargs): # Since loader.discover() can modify sys.path, restore it when done. with import_helper.DirsOnSysPath(): # Make sure to remove 'package' from sys.modules when done. - with test.test_importlib.util.uncache('package'): + with util.uncache('package'): with self.assertRaises(TypeError) as cm: loader.discover('package') self.assertEqual(str(cm.exception), diff --git a/Lib/test/test_unittest/test_loader.py b/Lib/test/test_unittest/test_loader.py index f32450c9223d8b..83dd25ca54623f 100644 --- a/Lib/test/test_unittest/test_loader.py +++ b/Lib/test/test_unittest/test_loader.py @@ -82,6 +82,22 @@ def runTest(self): self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [Foo('runTest')]) + # "Do not load any tests from `TestCase` class itself." + def test_loadTestsFromTestCase__from_TestCase(self): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromTestCase(unittest.TestCase) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + + # "Do not load any tests from `FunctionTestCase` class." + def test_loadTestsFromTestCase__from_FunctionTestCase(self): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromTestCase(unittest.FunctionTestCase) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + ################################################################ ### /Tests for TestLoader.loadTestsFromTestCase @@ -103,6 +119,19 @@ def test(self): expected = [loader.suiteClass([MyTestCase('test')])] self.assertEqual(list(suite), expected) + # "This test ensures that internal `TestCase` subclasses are not loaded" + def test_loadTestsFromModule__TestCase_subclass_internals(self): + # See https://github.com/python/cpython/issues/84867 + m = types.ModuleType('m') + # Simulate imported names: + m.TestCase = unittest.TestCase + m.FunctionTestCase = unittest.FunctionTestCase + + loader = unittest.TestLoader() + suite = loader.loadTestsFromModule(m) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + # "This method searches `module` for classes derived from TestCase" # # What happens if no tests are found (no TestCase instances)? diff --git a/Lib/test/test_unittest/test_runner.py b/Lib/test/test_unittest/test_runner.py index f3b2c0cffd4513..1b9cef43e3f9c5 100644 --- a/Lib/test/test_unittest/test_runner.py +++ b/Lib/test/test_unittest/test_runner.py @@ -24,6 +24,13 @@ def getRunner(): stream=io.StringIO()) +class CustomError(Exception): + pass + +# For test output compat: +CustomErrorRepr = f"{__name__ + '.' if __name__ != '__main__' else ''}CustomError" + + def runTests(*cases): suite = unittest.TestSuite() for case in cases: @@ -46,7 +53,7 @@ def cleanup(ordering, blowUp=False): ordering.append('cleanup_good') else: ordering.append('cleanup_exc') - raise Exception('CleanUpExc') + raise CustomError('CleanUpExc') class TestCM: @@ -108,8 +115,8 @@ def testNothing(self): result = unittest.TestResult() outcome = test._outcome = _Outcome(result=result) - CleanUpExc = Exception('foo') - exc2 = Exception('bar') + CleanUpExc = CustomError('foo') + exc2 = CustomError('bar') def cleanup1(): raise CleanUpExc @@ -125,10 +132,10 @@ def cleanup2(): (_, msg2), (_, msg1) = result.errors self.assertIn('in cleanup1', msg1) self.assertIn('raise CleanUpExc', msg1) - self.assertIn('Exception: foo', msg1) + self.assertIn(f'{CustomErrorRepr}: foo', msg1) self.assertIn('in cleanup2', msg2) self.assertIn('raise exc2', msg2) - self.assertIn('Exception: bar', msg2) + self.assertIn(f'{CustomErrorRepr}: bar', msg2) def testCleanupInRun(self): blowUp = False @@ -139,7 +146,7 @@ def setUp(self): ordering.append('setUp') test.addCleanup(cleanup2) if blowUp: - raise Exception('foo') + raise CustomError('foo') def testNothing(self): ordering.append('test') @@ -280,7 +287,7 @@ def setUpClass(cls): ordering.append('setUpClass') cls.addClassCleanup(cleanup, ordering) if blowUp: - raise Exception() + raise CustomError() def testNothing(self): ordering.append('test') @classmethod @@ -306,7 +313,7 @@ def setUpClass(cls): ordering.append('setUpClass') cls.addClassCleanup(cleanup, ordering) if blowUp: - raise Exception() + raise CustomError() def testNothing(self): ordering.append('test') @classmethod @@ -346,7 +353,7 @@ def tearDownClass(cls): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'CleanUpExc') self.assertEqual(ordering, @@ -366,10 +373,10 @@ def testNothing(self): @classmethod def tearDownClass(cls): ordering.append('tearDownClass') - raise Exception('TearDownClassExc') + raise CustomError('TearDownClassExc') suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownClassExc') self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) @@ -379,7 +386,7 @@ def tearDownClass(cls): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownClassExc') self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) @@ -392,16 +399,22 @@ def testNothing(self): pass def cleanup1(): - raise Exception('cleanup1') + raise CustomError('cleanup1') def cleanup2(): - raise Exception('cleanup2') + raise CustomError('cleanup2') TestableTest.addClassCleanup(cleanup1) TestableTest.addClassCleanup(cleanup2) - with self.assertRaises(Exception) as e: - TestableTest.doClassCleanups() - self.assertEqual(e, 'cleanup1') + TestableTest.doClassCleanups() + + self.assertEqual(len(TestableTest.tearDown_exceptions), 2) + + e1, e2 = TestableTest.tearDown_exceptions + self.assertIsInstance(e1[1], CustomError) + self.assertEqual(str(e1[1]), 'cleanup2') + self.assertIsInstance(e2[1], CustomError) + self.assertEqual(str(e2[1]), 'cleanup1') def test_with_errors_addCleanUp(self): ordering = [] @@ -421,7 +434,7 @@ def tearDownClass(cls): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'cleanup_exc', 'tearDownClass', 'cleanup_good']) @@ -444,7 +457,7 @@ def tearDownClass(cls): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'test', 'cleanup_good', 'tearDownClass', 'cleanup_exc']) @@ -460,11 +473,11 @@ def setUpClass(cls): ordering.append('setUpClass') cls.addClassCleanup(cleanup, ordering, blowUp=True) if class_blow_up: - raise Exception('ClassExc') + raise CustomError('ClassExc') def setUp(self): ordering.append('setUp') if method_blow_up: - raise Exception('MethodExc') + raise CustomError('MethodExc') def testNothing(self): ordering.append('test') @classmethod @@ -473,7 +486,7 @@ def tearDownClass(cls): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'test', 'tearDownClass', 'cleanup_exc']) @@ -483,9 +496,9 @@ def tearDownClass(cls): method_blow_up = False result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: ClassExc') + f'{CustomErrorRepr}: ClassExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'cleanup_exc']) @@ -494,9 +507,9 @@ def tearDownClass(cls): method_blow_up = True result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: MethodExc') + f'{CustomErrorRepr}: MethodExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'tearDownClass', 'cleanup_exc']) @@ -513,11 +526,11 @@ def testNothing(self): @classmethod def tearDownClass(cls): ordering.append('tearDownClass') - raise Exception('TearDownExc') + raise CustomError('TearDownExc') result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: TearDownExc') + f'{CustomErrorRepr}: TearDownExc') self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) @@ -620,7 +633,7 @@ def module_cleanup_good(*args, **kwargs): module_cleanups.append((3, args, kwargs)) def module_cleanup_bad(*args, **kwargs): - raise Exception('CleanUpExc') + raise CustomError('CleanUpExc') class Module(object): unittest.addModuleCleanup(module_cleanup_good, 1, 2, 3, @@ -630,7 +643,7 @@ class Module(object): [(module_cleanup_good, (1, 2, 3), dict(four='hello', five='goodbye')), (module_cleanup_bad, (), {})]) - with self.assertRaises(Exception) as e: + with self.assertRaises(CustomError) as e: unittest.case.doModuleCleanups() self.assertEqual(str(e.exception), 'CleanUpExc') self.assertEqual(unittest.case._module_cleanups, []) @@ -659,7 +672,7 @@ def setUpModule(): ordering.append('setUpModule') unittest.addModuleCleanup(cleanup, ordering) if blowUp: - raise Exception('setUpModule Exc') + raise CustomError('setUpModule Exc') @staticmethod def tearDownModule(): ordering.append('tearDownModule') @@ -679,7 +692,7 @@ def tearDownClass(cls): result = runTests(TestableTest) self.assertEqual(ordering, ['setUpModule', 'cleanup_good']) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: setUpModule Exc') + f'{CustomErrorRepr}: setUpModule Exc') ordering = [] blowUp = False @@ -699,7 +712,7 @@ def setUpModule(): ordering.append('setUpModule') unittest.addModuleCleanup(cleanup, ordering) if blowUp: - raise Exception() + raise CustomError() @staticmethod def tearDownModule(): ordering.append('tearDownModule') @@ -710,7 +723,7 @@ def setUpModule(): ordering.append('setUpModule2') unittest.addModuleCleanup(cleanup, ordering) if blowUp2: - raise Exception() + raise CustomError() @staticmethod def tearDownModule(): ordering.append('tearDownModule2') @@ -799,7 +812,7 @@ def setUpModule(): @staticmethod def tearDownModule(): ordering.append('tearDownModule') - raise Exception('CleanUpExc') + raise CustomError('CleanUpExc') class TestableTest(unittest.TestCase): @classmethod @@ -815,7 +828,7 @@ def tearDownClass(cls): sys.modules['Module'] = Module result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 'tearDownModule', 'cleanup_good']) @@ -855,7 +868,7 @@ def tearDownClass(cls): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', @@ -873,7 +886,7 @@ def setUpModule(): @staticmethod def tearDownModule(): ordering.append('tearDownModule') - raise Exception('TearDownModuleExc') + raise CustomError('TearDownModuleExc') class TestableTest(unittest.TestCase): @classmethod @@ -888,7 +901,7 @@ def tearDownClass(cls): TestableTest.__module__ = 'Module' sys.modules['Module'] = Module suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownModuleExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', @@ -899,7 +912,7 @@ def tearDownClass(cls): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownModuleExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', @@ -978,7 +991,7 @@ def tearDownClass(cls): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 'cleanup_exc', 'tearDownModule', 'cleanup_good']) @@ -1008,7 +1021,7 @@ def tearDown(self): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUp', 'test', 'tearDown', 'cleanup_exc', 'tearDownModule', 'cleanup_good']) @@ -1024,7 +1037,7 @@ def setUpModule(): ordering.append('setUpModule') unittest.addModuleCleanup(cleanup, ordering, blowUp=True) if module_blow_up: - raise Exception('ModuleExc') + raise CustomError('ModuleExc') @staticmethod def tearDownModule(): ordering.append('tearDownModule') @@ -1034,11 +1047,11 @@ class TestableTest(unittest.TestCase): def setUpClass(cls): ordering.append('setUpClass') if class_blow_up: - raise Exception('ClassExc') + raise CustomError('ClassExc') def setUp(self): ordering.append('setUp') if method_blow_up: - raise Exception('MethodExc') + raise CustomError('MethodExc') def testNothing(self): ordering.append('test') @classmethod @@ -1050,7 +1063,7 @@ def tearDownClass(cls): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'setUp', 'test', 'tearDownClass', 'tearDownModule', @@ -1062,9 +1075,9 @@ def tearDownClass(cls): method_blow_up = False result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: ModuleExc') + f'{CustomErrorRepr}: ModuleExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'cleanup_exc']) ordering = [] @@ -1073,9 +1086,9 @@ def tearDownClass(cls): method_blow_up = False result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: ClassExc') + f'{CustomErrorRepr}: ClassExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'tearDownModule', 'cleanup_exc']) @@ -1085,9 +1098,9 @@ def tearDownClass(cls): method_blow_up = True result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: MethodExc') + f'{CustomErrorRepr}: MethodExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'setUp', 'tearDownClass', 'tearDownModule', 'cleanup_exc']) diff --git a/Lib/test/test_unittest/test_skipping.py b/Lib/test/test_unittest/test_skipping.py index f146dcac18ecc0..1a6af06d32b433 100644 --- a/Lib/test/test_unittest/test_skipping.py +++ b/Lib/test/test_unittest/test_skipping.py @@ -103,16 +103,16 @@ def test_dont_skip(self): pass result = LoggingResult(events) self.assertIs(suite.run(result), result) self.assertEqual(len(result.skipped), 1) - expected = ['startTest', 'addSkip', 'stopTest', - 'startTest', 'addSuccess', 'stopTest'] + expected = ['addSkip', 'stopTest', 'startTest', + 'addSuccess', 'stopTest'] self.assertEqual(events, expected) - self.assertEqual(result.testsRun, 2) + self.assertEqual(result.testsRun, 1) self.assertEqual(result.skipped, [(test_do_skip, "testing")]) self.assertTrue(result.wasSuccessful()) events = [] result = test_do_skip.run() - self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', + self.assertEqual(events, ['startTestRun', 'addSkip', 'stopTest', 'stopTestRun']) self.assertEqual(result.skipped, [(test_do_skip, "testing")]) @@ -135,13 +135,13 @@ def test_1(self): test = Foo("test_1") suite = unittest.TestSuite([test]) self.assertIs(suite.run(result), result) - self.assertEqual(events, ['startTest', 'addSkip', 'stopTest']) + self.assertEqual(events, ['addSkip', 'stopTest']) self.assertEqual(result.skipped, [(test, "testing")]) self.assertEqual(record, []) events = [] result = test.run() - self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', + self.assertEqual(events, ['startTestRun', 'addSkip', 'stopTest', 'stopTestRun']) self.assertEqual(result.skipped, [(test, "testing")]) self.assertEqual(record, []) diff --git a/Lib/test/test_unittest/testmock/testmock.py b/Lib/test/test_unittest/testmock/testmock.py index bb09913d70b7ca..d23eb87696f406 100644 --- a/Lib/test/test_unittest/testmock/testmock.py +++ b/Lib/test/test_unittest/testmock/testmock.py @@ -2270,7 +2270,7 @@ def test_misspelled_arguments(self): class Foo(): one = 'one' # patch, patch.object and create_autospec need to check for misspelled - # arguments explicitly and throw a RuntimError if found. + # arguments explicitly and throw a RuntimeError if found. with self.assertRaises(RuntimeError): with patch(f'{__name__}.Something.meth', autospect=True): pass with self.assertRaises(RuntimeError): diff --git a/Lib/test/test_unittest/testmock/testthreadingmock.py b/Lib/test/test_unittest/testmock/testthreadingmock.py index 94e71921d9bc03..a02b532ed447cd 100644 --- a/Lib/test/test_unittest/testmock/testthreadingmock.py +++ b/Lib/test/test_unittest/testmock/testthreadingmock.py @@ -3,7 +3,7 @@ import concurrent.futures from test.support import threading_helper -from unittest.mock import patch, ThreadingMock, call +from unittest.mock import patch, ThreadingMock threading_helper.requires_working_threading(module=True) diff --git a/Lib/test/test_unpack.py b/Lib/test/test_unpack.py index f5ca1d455b5c6f..515ec128a08a9c 100644 --- a/Lib/test/test_unpack.py +++ b/Lib/test/test_unpack.py @@ -162,7 +162,7 @@ def test_extended_oparg_not_ignored(self): ns = {} exec(code, ns) unpack_400 = ns["unpack_400"] - # Warm up the the function for quickening (PEP 659) + # Warm up the function for quickening (PEP 659) for _ in range(30): y = unpack_400(range(400)) self.assertEqual(y, 399) diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index b3efb61e83049e..6f698a8d891815 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -197,6 +197,10 @@ def test_fstrings_complicated(self): self.check_ast_roundtrip('''f"a\\r\\nb"''') self.check_ast_roundtrip('''f"\\u2028{'x'}"''') + def test_fstrings_pep701(self): + self.check_ast_roundtrip('f" something { my_dict["key"] } something else "') + self.check_ast_roundtrip('f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"') + def test_strings(self): self.check_ast_roundtrip("u'foo'") self.check_ast_roundtrip("r'foo'") @@ -378,8 +382,15 @@ def test_invalid_fstring_value(self): ) ) - def test_invalid_fstring_backslash(self): - self.check_invalid(ast.FormattedValue(value=ast.Constant(value="\\\\"))) + def test_fstring_backslash(self): + # valid since Python 3.12 + self.assertEqual(ast.unparse( + ast.FormattedValue( + value=ast.Constant(value="\\\\"), + conversion=-1, + format_spec=None, + ) + ), "{'\\\\\\\\'}") def test_invalid_yield_from(self): self.check_invalid(ast.YieldFrom(value=None)) @@ -502,11 +513,11 @@ def test_class_bases_and_keywords(self): self.check_src_roundtrip("class X(*args, **kwargs):\n pass") def test_fstrings(self): - self.check_src_roundtrip('''f\'\'\'-{f"""*{f"+{f'.{x}.'}+"}*"""}-\'\'\'''') - self.check_src_roundtrip('''f"\\u2028{'x'}"''') + self.check_src_roundtrip("f'-{f'*{f'+{f'.{x}.'}+'}*'}-'") + self.check_src_roundtrip("f'\\u2028{'x'}'") self.check_src_roundtrip(r"f'{x}\n'") - self.check_src_roundtrip('''f''\'{"""\n"""}\\n''\'''') - self.check_src_roundtrip('''f''\'{f"""{x}\n"""}\\n''\'''') + self.check_src_roundtrip("f'{'\\n'}\\n'") + self.check_src_roundtrip("f'{f'{x}\\n'}\\n'") def test_docstrings(self): docstrings = ( @@ -624,6 +635,20 @@ def test_star_expr_assign_target_multiple(self): self.check_src_roundtrip("[a, b] = [c, d] = [e, f] = g") self.check_src_roundtrip("a, b = [c, d] = e, f = g") + def test_multiquote_joined_string(self): + self.check_ast_roundtrip("f\"'''{1}\\\"\\\"\\\"\" ") + self.check_ast_roundtrip("""f"'''{1}""\\"" """) + self.check_ast_roundtrip("""f'""\"{1}''' """) + self.check_ast_roundtrip("""f'""\"{1}""\\"' """) + + self.check_ast_roundtrip("""f"'''{"\\n"}""\\"" """) + self.check_ast_roundtrip("""f'""\"{"\\n"}''' """) + self.check_ast_roundtrip("""f'""\"{"\\n"}""\\"' """) + + self.check_ast_roundtrip("""f'''""\"''\\'{"\\n"}''' """) + self.check_ast_roundtrip("""f'''""\"''\\'{"\\n\\"'"}''' """) + self.check_ast_roundtrip("""f'''""\"''\\'{""\"\\n\\"'''""\" '''\\n'''}''' """) + class ManualASTCreationTestCase(unittest.TestCase): """Test that AST nodes created without a type_params field unparse correctly.""" @@ -705,7 +730,8 @@ class DirectoryTestCase(ASTTestCase): test_directories = (lib_dir, lib_dir / "test") run_always_files = {"test_grammar.py", "test_syntax.py", "test_compile.py", "test_ast.py", "test_asdl_parser.py", "test_fstring.py", - "test_patma.py", "test_type_alias.py", "test_type_params.py"} + "test_patma.py", "test_type_alias.py", "test_type_params.py", + "test_tokenize.py"} _files_to_test = None diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index 0dcdbac76b50f2..50c491a3cfd3d0 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -21,9 +21,9 @@ here = os.path.dirname(__file__) # Self-signed cert file for 'localhost' -CERT_localhost = os.path.join(here, 'keycert.pem') +CERT_localhost = os.path.join(here, 'certdata', 'keycert.pem') # Self-signed cert file for 'fakehostname' -CERT_fakehostname = os.path.join(here, 'keycert2.pem') +CERT_fakehostname = os.path.join(here, 'certdata', 'keycert2.pem') # Loopback http server infrastructure diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index d8d882b2d33589..f0874d8d3ce463 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -133,6 +133,7 @@ def setUp(self): # XXX The rest of these tests aren't very good -- they don't check much. # They do sometimes catch some major disasters, though. + @support.requires_resource('walltime') def test_ftp(self): # Testing the same URL twice exercises the caching in CacheFTPHandler urls = [ @@ -196,6 +197,7 @@ def test_urlwithfrag(self): self.assertEqual(res.geturl(), "http://www.pythontest.net/index.html#frag") + @support.requires_resource('walltime') def test_redirect_url_withfrag(self): redirect_url_with_frag = "http://www.pythontest.net/redir/with_frag/" with socket_helper.transient_internet(redirect_url_with_frag): @@ -334,6 +336,7 @@ def test_http_timeout(self): FTP_HOST = 'ftp://www.pythontest.net/' + @support.requires_resource('walltime') def test_ftp_basic(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST, timeout=None): @@ -352,6 +355,7 @@ def test_ftp_default_timeout(self): socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + @support.requires_resource('walltime') def test_ftp_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST): @@ -363,6 +367,7 @@ def test_ftp_no_timeout(self): socket.setdefaulttimeout(None) self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) + @support.requires_resource('walltime') def test_ftp_timeout(self): with socket_helper.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index 773101ce41f602..49a3b5afdebb2f 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -109,6 +109,7 @@ def test_getcode(self): open_url.close() self.assertEqual(code, 404) + @support.requires_resource('walltime') def test_bad_address(self): # Make sure proper exception is raised when connecting to a bogus # address. @@ -191,6 +192,7 @@ def test_header(self): logo = "http://www.pythontest.net/" + @support.requires_resource('walltime') def test_data_header(self): with self.urlretrieve(self.logo) as (file_location, fileheaders): datevalue = fileheaders.get('Date') diff --git a/Lib/test/test_utf8_mode.py b/Lib/test/test_utf8_mode.py index ec29ba6d51b127..f66881044e16df 100644 --- a/Lib/test/test_utf8_mode.py +++ b/Lib/test/test_utf8_mode.py @@ -9,10 +9,9 @@ import unittest from test import support from test.support.script_helper import assert_python_ok, assert_python_failure -from test.support import os_helper +from test.support import os_helper, MS_WINDOWS -MS_WINDOWS = (sys.platform == 'win32') POSIX_LOCALES = ('C', 'POSIX') VXWORKS = (sys.platform == "vxworks") diff --git a/Lib/test/test_utf8source.py b/Lib/test/test_utf8source.py index 97dced8a622889..c42b6aaaab579d 100644 --- a/Lib/test/test_utf8source.py +++ b/Lib/test/test_utf8source.py @@ -1,5 +1,3 @@ -# This file is marked as binary in the CVS, to prevent MacCVS from recoding it. - import unittest class PEP3120Test(unittest.TestCase): @@ -16,7 +14,7 @@ def test_pep3120(self): def test_badsyntax(self): try: - import test.badsyntax_pep3120 + import test.tokenizedata.badsyntax_pep3120 except SyntaxError as msg: msg = str(msg).lower() self.assertTrue('utf-8' in msg) diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 3d19b2b2e905f3..890672c5d27eec 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -20,7 +20,8 @@ from test.support import (captured_stdout, captured_stderr, skip_if_broken_multiprocessing_synchronize, verbose, requires_subprocess, is_emscripten, is_wasi, - requires_venv_with_pip, TEST_HOME_DIR) + requires_venv_with_pip, TEST_HOME_DIR, + requires_resource, copy_python_src_ignore) from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) import unittest import venv @@ -81,6 +82,13 @@ def setUp(self): def tearDown(self): rmtree(self.env_dir) + def envpy(self, *, real_env_dir=False): + if real_env_dir: + env_dir = os.path.realpath(self.env_dir) + else: + env_dir = self.env_dir + return os.path.join(env_dir, self.bindir, self.exe) + def run_with_capture(self, func, *args, **kwargs): with captured_stdout() as output: with captured_stderr() as error: @@ -137,7 +145,8 @@ def _check_output_of_default_create(self): self.assertIn('executable = %s' % os.path.realpath(sys.executable), data) copies = '' if os.name=='nt' else ' --copies' - cmd = f'command = {sys.executable} -m venv{copies} --without-pip {self.env_dir}' + cmd = (f'command = {sys.executable} -m venv{copies} --without-pip ' + f'--without-scm-ignore-files {self.env_dir}') self.assertIn(cmd, data) fn = self.get_env_file(self.bindir, self.exe) if not os.path.exists(fn): # diagnostics for Windows buildbot failures @@ -147,35 +156,37 @@ def _check_output_of_default_create(self): self.assertTrue(os.path.exists(fn), 'File %r should exist.' % fn) def test_config_file_command_key(self): - attrs = [ - (None, None), - ('symlinks', '--copies'), - ('with_pip', '--without-pip'), - ('system_site_packages', '--system-site-packages'), - ('clear', '--clear'), - ('upgrade', '--upgrade'), - ('upgrade_deps', '--upgrade-deps'), - ('prompt', '--prompt'), + options = [ + (None, None, None), # Default case. + ('--copies', 'symlinks', False), + ('--without-pip', 'with_pip', False), + ('--system-site-packages', 'system_site_packages', True), + ('--clear', 'clear', True), + ('--upgrade', 'upgrade', True), + ('--upgrade-deps', 'upgrade_deps', True), + ('--prompt', 'prompt', True), + ('--without-scm-ignore-files', 'scm_ignore_files', frozenset()), ] - for attr, opt in attrs: - rmtree(self.env_dir) - if not attr: - b = venv.EnvBuilder() - else: - b = venv.EnvBuilder( - **{attr: False if attr in ('with_pip', 'symlinks') else True}) - b.upgrade_dependencies = Mock() # avoid pip command to upgrade deps - b._setup_pip = Mock() # avoid pip setup - self.run_with_capture(b.create, self.env_dir) - data = self.get_text_file_contents('pyvenv.cfg') - if not attr: - for opt in ('--system-site-packages', '--clear', '--upgrade', - '--upgrade-deps', '--prompt'): - self.assertNotRegex(data, rf'command = .* {opt}') - elif os.name=='nt' and attr=='symlinks': - pass - else: - self.assertRegex(data, rf'command = .* {opt}') + for opt, attr, value in options: + with self.subTest(opt=opt, attr=attr, value=value): + rmtree(self.env_dir) + if not attr: + kwargs = {} + else: + kwargs = {attr: value} + b = venv.EnvBuilder(**kwargs) + b.upgrade_dependencies = Mock() # avoid pip command to upgrade deps + b._setup_pip = Mock() # avoid pip setup + self.run_with_capture(b.create, self.env_dir) + data = self.get_text_file_contents('pyvenv.cfg') + if not attr or opt.endswith('git'): + for opt in ('--system-site-packages', '--clear', '--upgrade', + '--upgrade-deps', '--prompt'): + self.assertNotRegex(data, rf'command = .* {opt}') + elif os.name=='nt' and attr=='symlinks': + pass + else: + self.assertRegex(data, rf'command = .* {opt}') def test_prompt(self): env_name = os.path.split(self.env_dir)[1] @@ -208,8 +219,7 @@ def test_prompt(self): def test_upgrade_dependencies(self): builder = venv.EnvBuilder() bin_path = 'Scripts' if sys.platform == 'win32' else 'bin' - python_exe_realpath = os.path.realpath(sys._base_executable) - python_exe = os.path.split(python_exe_realpath)[1] + python_exe = os.path.split(sys.executable)[1] with tempfile.TemporaryDirectory() as fake_env_dir: expect_exe = os.path.normcase( os.path.join(fake_env_dir, bin_path, python_exe) @@ -243,8 +253,7 @@ def test_prefixes(self): # check a venv's prefixes rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) - envpy = os.path.join(self.env_dir, self.bindir, self.exe) - cmd = [envpy, '-c', None] + cmd = [self.envpy(), '-c', None] for prefix, expected in ( ('prefix', self.env_dir), ('exec_prefix', self.env_dir), @@ -261,8 +270,7 @@ def test_sysconfig(self): """ rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir, symlinks=False) - envpy = os.path.join(self.env_dir, self.bindir, self.exe) - cmd = [envpy, '-c', None] + cmd = [self.envpy(), '-c', None] for call, expected in ( # installation scheme ('get_preferred_scheme("prefix")', 'venv'), @@ -284,8 +292,7 @@ def test_sysconfig_symlinks(self): """ rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir, symlinks=True) - envpy = os.path.join(self.env_dir, self.bindir, self.exe) - cmd = [envpy, '-c', None] + cmd = [self.envpy(), '-c', None] for call, expected in ( # installation scheme ('get_preferred_scheme("prefix")', 'venv'), @@ -424,8 +431,7 @@ def test_executable(self): """ rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) - envpy = os.path.join(os.path.realpath(self.env_dir), - self.bindir, self.exe) + envpy = self.envpy(real_env_dir=True) out, err = check_output([envpy, '-c', 'import sys; print(sys.executable)']) self.assertEqual(out.strip(), envpy.encode()) @@ -438,8 +444,7 @@ def test_executable_symlinks(self): rmtree(self.env_dir) builder = venv.EnvBuilder(clear=True, symlinks=True) builder.create(self.env_dir) - envpy = os.path.join(os.path.realpath(self.env_dir), - self.bindir, self.exe) + envpy = self.envpy(real_env_dir=True) out, err = check_output([envpy, '-c', 'import sys; print(sys.executable)']) self.assertEqual(out.strip(), envpy.encode()) @@ -454,7 +459,6 @@ def test_unicode_in_batch_file(self): builder = venv.EnvBuilder(clear=True) builder.create(env_dir) activate = os.path.join(env_dir, self.bindir, 'activate.bat') - envpy = os.path.join(env_dir, self.bindir, self.exe) out, err = check_output( [activate, '&', self.exe, '-c', 'print(0)'], encoding='oem', @@ -473,9 +477,7 @@ def test_multiprocessing(self): rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) - envpy = os.path.join(os.path.realpath(self.env_dir), - self.bindir, self.exe) - out, err = check_output([envpy, '-c', + out, err = check_output([self.envpy(real_env_dir=True), '-c', 'from multiprocessing import Pool; ' 'pool = Pool(1); ' 'print(pool.apply_async("Python".lower).get(3)); ' @@ -491,10 +493,8 @@ def test_multiprocessing_recursion(self): rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) - envpy = os.path.join(os.path.realpath(self.env_dir), - self.bindir, self.exe) script = os.path.join(TEST_HOME_DIR, '_test_venv_multiprocessing.py') - subprocess.check_call([envpy, script]) + subprocess.check_call([self.envpy(real_env_dir=True), script]) @unittest.skipIf(os.name == 'nt', 'not relevant on Windows') def test_deactivate_with_strict_bash_opts(self): @@ -521,9 +521,7 @@ def test_macos_env(self): builder = venv.EnvBuilder() builder.create(self.env_dir) - envpy = os.path.join(os.path.realpath(self.env_dir), - self.bindir, self.exe) - out, err = check_output([envpy, '-c', + out, err = check_output([self.envpy(real_env_dir=True), '-c', 'import os; print("__PYVENV_LAUNCHER__" in os.environ)']) self.assertEqual(out.strip(), 'False'.encode()) @@ -552,8 +550,7 @@ def test_zippath_from_non_installed_posix(self): self.addCleanup(rmtree, non_installed_dir) bindir = os.path.join(non_installed_dir, self.bindir) os.mkdir(bindir) - python_exe_realpath = os.path.realpath(sys._base_executable) - shutil.copy2(python_exe_realpath, bindir) + shutil.copy2(sys.executable, bindir) libdir = os.path.join(non_installed_dir, platlibdir, self.lib[1]) os.makedirs(libdir) landmark = os.path.join(libdir, "os.py") @@ -562,6 +559,7 @@ def test_zippath_from_non_installed_posix(self): platlibdir, stdlib_zip) additional_pythonpath_for_non_installed = [] + # Copy stdlib files to the non-installed python so venv can # correctly calculate the prefix. for eachpath in sys.path: @@ -571,14 +569,19 @@ def test_zippath_from_non_installed_posix(self): eachpath, os.path.join(non_installed_dir, platlibdir)) elif os.path.isfile(os.path.join(eachpath, "os.py")): - for name in os.listdir(eachpath): + names = os.listdir(eachpath) + ignored_names = copy_python_src_ignore(eachpath, names) + for name in names: + if name in ignored_names: + continue if name == "site-packages": continue fn = os.path.join(eachpath, name) if os.path.isfile(fn): shutil.copy(fn, libdir) elif os.path.isdir(fn): - shutil.copytree(fn, os.path.join(libdir, name)) + shutil.copytree(fn, os.path.join(libdir, name), + ignore=copy_python_src_ignore) else: additional_pythonpath_for_non_installed.append( eachpath) @@ -586,6 +589,7 @@ def test_zippath_from_non_installed_posix(self): "-m", "venv", "--without-pip", + "--without-scm-ignore-files", self.env_dir] # Our fake non-installed python is not fully functional because # it cannot find the extensions. Set PYTHONPATH so it can run the @@ -597,7 +601,7 @@ def test_zippath_from_non_installed_posix(self): # libpython.so ld_library_path = sysconfig.get_config_var("LIBDIR") if not ld_library_path or sysconfig.is_python_build(): - ld_library_path = os.path.abspath(os.path.dirname(python_exe_realpath)) + ld_library_path = os.path.abspath(os.path.dirname(sys.executable)) if sys.platform == 'darwin': ld_library_path_env = "DYLD_LIBRARY_PATH" else: @@ -610,13 +614,13 @@ def test_zippath_from_non_installed_posix(self): # prevent https://github.com/python/cpython/issues/104839 child_env["ASAN_OPTIONS"] = asan_options subprocess.check_call(cmd, env=child_env) - envpy = os.path.join(self.env_dir, self.bindir, self.exe) # Now check the venv created from the non-installed python has # correct zip path in pythonpath. - cmd = [envpy, '-S', '-c', 'import sys; print(sys.path)'] + cmd = [self.envpy(), '-S', '-c', 'import sys; print(sys.path)'] out, err = check_output(cmd) self.assertTrue(zip_landmark.encode() in out) + @requireVenvCreate def test_activate_shell_script_has_no_dos_newlines(self): """ Test that the `activate` shell script contains no CR LF. @@ -633,13 +637,80 @@ def test_activate_shell_script_has_no_dos_newlines(self): error_message = f"CR LF found in line {i}" self.assertFalse(line.endswith(b'\r\n'), error_message) + @requireVenvCreate + def test_scm_ignore_files_git(self): + """ + Test that a .gitignore file is created when "git" is specified. + The file should contain a `*\n` line. + """ + self.run_with_capture(venv.create, self.env_dir, + scm_ignore_files={'git'}) + file_lines = self.get_text_file_contents('.gitignore').splitlines() + self.assertIn('*', file_lines) + + @requireVenvCreate + def test_create_scm_ignore_files_multiple(self): + """ + Test that ``scm_ignore_files`` can work with multiple SCMs. + """ + bzrignore_name = ".bzrignore" + contents = "# For Bazaar.\n*\n" + + class BzrEnvBuilder(venv.EnvBuilder): + def create_bzr_ignore_file(self, context): + gitignore_path = os.path.join(context.env_dir, bzrignore_name) + with open(gitignore_path, 'w', encoding='utf-8') as file: + file.write(contents) + + builder = BzrEnvBuilder(scm_ignore_files={'git', 'bzr'}) + self.run_with_capture(builder.create, self.env_dir) + + gitignore_lines = self.get_text_file_contents('.gitignore').splitlines() + self.assertIn('*', gitignore_lines) + + bzrignore = self.get_text_file_contents(bzrignore_name) + self.assertEqual(bzrignore, contents) + + @requireVenvCreate + def test_create_scm_ignore_files_empty(self): + """ + Test that no default ignore files are created when ``scm_ignore_files`` + is empty. + """ + # scm_ignore_files is set to frozenset() by default. + self.run_with_capture(venv.create, self.env_dir) + with self.assertRaises(FileNotFoundError): + self.get_text_file_contents('.gitignore') + + self.assertIn("--without-scm-ignore-files", + self.get_text_file_contents('pyvenv.cfg')) + + @requireVenvCreate + def test_cli_with_scm_ignore_files(self): + """ + Test that default SCM ignore files are created by default via the CLI. + """ + self.run_with_capture(venv.main, ['--without-pip', self.env_dir]) + + gitignore_lines = self.get_text_file_contents('.gitignore').splitlines() + self.assertIn('*', gitignore_lines) + + @requireVenvCreate + def test_cli_without_scm_ignore_files(self): + """ + Test that ``--without-scm-ignore-files`` doesn't create SCM ignore files. + """ + args = ['--without-pip', '--without-scm-ignore-files', self.env_dir] + self.run_with_capture(venv.main, args) + + with self.assertRaises(FileNotFoundError): + self.get_text_file_contents('.gitignore') + @requireVenvCreate class EnsurePipTest(BaseTest): """Test venv module installation of pip.""" def assert_pip_not_installed(self): - envpy = os.path.join(os.path.realpath(self.env_dir), - self.bindir, self.exe) - out, err = check_output([envpy, '-c', + out, err = check_output([self.envpy(real_env_dir=True), '-c', 'try:\n import pip\nexcept ImportError:\n print("OK")']) # We force everything to text, so unittest gives the detailed diff # if we get unexpected results @@ -706,9 +777,9 @@ def do_test_with_pip(self, system_site_packages): system_site_packages=system_site_packages, with_pip=True) # Ensure pip is available in the virtual environment - envpy = os.path.join(os.path.realpath(self.env_dir), self.bindir, self.exe) # Ignore DeprecationWarning since pip code is not part of Python - out, err = check_output([envpy, '-W', 'ignore::DeprecationWarning', + out, err = check_output([self.envpy(real_env_dir=True), + '-W', 'ignore::DeprecationWarning', '-W', 'ignore::ImportWarning', '-I', '-m', 'pip', '--version']) # We force everything to text, so unittest gives the detailed diff @@ -729,7 +800,7 @@ def do_test_with_pip(self, system_site_packages): # It seems ensurepip._uninstall calls subprocesses which do not # inherit the interpreter settings. envvars["PYTHONWARNINGS"] = "ignore" - out, err = check_output([envpy, + out, err = check_output([self.envpy(real_env_dir=True), '-W', 'ignore::DeprecationWarning', '-W', 'ignore::ImportWarning', '-I', '-m', 'ensurepip._uninstall']) @@ -777,6 +848,7 @@ def nicer_error(self): ) @requires_venv_with_pip() + @requires_resource('cpu') def test_with_pip(self): self.do_test_with_pip(False) self.do_test_with_pip(True) diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 1bc1d05f7daba9..4cdd66d3769e0c 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -1933,6 +1933,7 @@ def test_threaded_weak_key_dict_copy(self): self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_key_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. @@ -1945,6 +1946,7 @@ def test_threaded_weak_value_dict_copy(self): self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_value_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. diff --git a/Lib/test/test_weakset.py b/Lib/test/test_weakset.py index d6c88596cff71f..76e8e5c8ab7d3c 100644 --- a/Lib/test/test_weakset.py +++ b/Lib/test/test_weakset.py @@ -44,7 +44,7 @@ def setUp(self): def test_methods(self): weaksetmethods = dir(WeakSet) for method in dir(set): - if method == 'test_c_api' or method.startswith('_'): + if method.startswith('_'): continue self.assertIn(method, weaksetmethods, "WeakSet missing method " + method) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index b9352cb865d027..6d413aa68a338d 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -365,6 +365,7 @@ def test_path_cache(self): from xml.etree import ElementPath elem = ET.XML(SAMPLE_XML) + ElementPath._cache.clear() for i in range(10): ET.ElementTree(elem).find('./'+str(i)) cache_len_10 = len(ElementPath._cache) for i in range(10): ET.ElementTree(elem).find('./'+str(i)) @@ -3926,8 +3927,9 @@ def test_issue14818(self): # -------------------------------------------------------------------- class NoAcceleratorTest(unittest.TestCase): - def setUp(self): - if not pyET: + @classmethod + def setUpClass(cls): + if ET is not pyET: raise unittest.SkipTest('only for the Python version') # Test that the C accelerator was not imported for pyET @@ -4192,8 +4194,7 @@ def get_option(config, option_name, default=None): # -------------------------------------------------------------------- - -def test_main(module=None): +def setUpModule(module=None): # When invoked without a module, runs the Python ET tests by loading pyET. # Otherwise, uses the given module as the ET. global pyET @@ -4205,63 +4206,30 @@ def test_main(module=None): global ET ET = module - test_classes = [ - ModuleTest, - ElementSlicingTest, - BasicElementTest, - BadElementTest, - BadElementPathTest, - ElementTreeTest, - IOTest, - ParseErrorTest, - XIncludeTest, - ElementTreeTypeTest, - ElementFindTest, - ElementIterTest, - TreeBuilderTest, - XMLParserTest, - XMLPullParserTest, - BugsTest, - KeywordArgsTest, - BoolTest, - C14NTest, - ] - - # These tests will only run for the pure-Python version that doesn't import - # _elementtree. We can't use skipUnless here, because pyET is filled in only - # after the module is loaded. - if pyET is not ET: - test_classes.extend([ - NoAcceleratorTest, - ]) + # don't interfere with subsequent tests + def cleanup(): + global ET, pyET + ET = pyET = None + unittest.addModuleCleanup(cleanup) # Provide default namespace mapping and path cache. from xml.etree import ElementPath nsmap = ET.register_namespace._namespace_map # Copy the default namespace mapping nsmap_copy = nsmap.copy() + unittest.addModuleCleanup(nsmap.update, nsmap_copy) + unittest.addModuleCleanup(nsmap.clear) + # Copy the path cache (should be empty) path_cache = ElementPath._cache + unittest.addModuleCleanup(setattr, ElementPath, "_cache", path_cache) ElementPath._cache = path_cache.copy() + # Align the Comment/PI factories. if hasattr(ET, '_set_factories'): old_factories = ET._set_factories(ET.Comment, ET.PI) - else: - old_factories = None - - try: - support.run_unittest(*test_classes) - finally: - from xml.etree import ElementPath - # Restore mapping and path cache - nsmap.clear() - nsmap.update(nsmap_copy) - ElementPath._cache = path_cache - if old_factories is not None: - ET._set_factories(*old_factories) - # don't interfere with subsequent tests - ET = pyET = None + unittest.addModuleCleanup(ET._set_factories, *old_factories) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index fd27b575ec8dc9..3a0fc572f457ff 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -254,20 +254,25 @@ def test_element_with_children(self): self.check_sizeof(e, self.elementsize + self.extra + struct.calcsize('8P')) -def test_main(): - from test import test_xml_etree - - # Run the tests specific to the C implementation - support.run_unittest( - MiscTests, - TestAliasWorking, - TestAcceleratorImported, - SizeofTest, - ) - # Run the same test suite as the Python module - test_xml_etree.test_main(module=cET) +def install_tests(): + # Test classes should have __module__ referring to this module. + from test import test_xml_etree + for name, base in vars(test_xml_etree).items(): + if isinstance(base, type) and issubclass(base, unittest.TestCase): + class Temp(base): + pass + Temp.__name__ = Temp.__qualname__ = name + Temp.__module__ = __name__ + assert name not in globals() + globals()[name] = Temp + +install_tests() + +def setUpModule(): + from test import test_xml_etree + test_xml_etree.setUpModule(module=cET) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index edc741dbc60088..6c4b8384a3202e 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -1037,38 +1037,47 @@ def test_path2(self): self.assertEqual(p.add(6,8), 6+8) self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8) + @support.requires_resource('walltime') def test_path3(self): p = xmlrpclib.ServerProxy(URL+"/is/broken") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_invalid_path(self): p = xmlrpclib.ServerProxy(URL+"/invalid") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_path_query_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag") self.assertEqual(p.test(), "/foo?k=v#frag") + @support.requires_resource('walltime') def test_path_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo#frag") self.assertEqual(p.test(), "/foo#frag") + @support.requires_resource('walltime') def test_path_query(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v") self.assertEqual(p.test(), "/foo?k=v") + @support.requires_resource('walltime') def test_empty_path(self): p = xmlrpclib.ServerProxy(URL) self.assertEqual(p.test(), "/RPC2") + @support.requires_resource('walltime') def test_root_path(self): p = xmlrpclib.ServerProxy(URL + "/") self.assertEqual(p.test(), "/") + @support.requires_resource('walltime') def test_empty_path_query(self): p = xmlrpclib.ServerProxy(URL + "?k=v") self.assertEqual(p.test(), "?k=v") + @support.requires_resource('walltime') def test_empty_path_fragment(self): p = xmlrpclib.ServerProxy(URL + "#frag") self.assertEqual(p.test(), "#frag") diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 9960259c4cde0c..0f6c0f2107ce6b 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -3203,14 +3203,14 @@ def test_no_data(self): b = s.pack(2, 0) c = s.pack(3, 0) - self.assertEqual(b'', zipfile._strip_extra(a, (self.ZIP64_EXTRA,))) - self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,))) + self.assertEqual(b'', zipfile._Extra.strip(a, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._Extra.strip(b, (self.ZIP64_EXTRA,))) self.assertEqual( - b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,))) + b+b"z", zipfile._Extra.strip(b+b"z", (self.ZIP64_EXTRA,))) - self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,))) - self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,))) - self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._Extra.strip(a+b+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._Extra.strip(b+a+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._Extra.strip(b+c+a, (self.ZIP64_EXTRA,))) def test_with_data(self): s = struct.Struct("4GiB input" - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - data = block * (size // blocksize + 1) + data = block * ((size-1) // blocksize + 1) compressed = zlib.compress(data) zlibd = zlib._ZlibDecompressor() decompressed = zlibd.decompress(compressed) diff --git a/Modules/_testcapi/pytime.c b/Lib/test/tokenizedata/__init__.py similarity index 100% rename from Modules/_testcapi/pytime.c rename to Lib/test/tokenizedata/__init__.py diff --git a/Lib/test/bad_coding.py b/Lib/test/tokenizedata/bad_coding.py similarity index 100% rename from Lib/test/bad_coding.py rename to Lib/test/tokenizedata/bad_coding.py diff --git a/Lib/test/bad_coding2.py b/Lib/test/tokenizedata/bad_coding2.py similarity index 100% rename from Lib/test/bad_coding2.py rename to Lib/test/tokenizedata/bad_coding2.py diff --git a/Lib/test/badsyntax_3131.py b/Lib/test/tokenizedata/badsyntax_3131.py similarity index 100% rename from Lib/test/badsyntax_3131.py rename to Lib/test/tokenizedata/badsyntax_3131.py diff --git a/Lib/test/badsyntax_pep3120.py b/Lib/test/tokenizedata/badsyntax_pep3120.py similarity index 100% rename from Lib/test/badsyntax_pep3120.py rename to Lib/test/tokenizedata/badsyntax_pep3120.py diff --git a/Lib/test/coding20731.py b/Lib/test/tokenizedata/coding20731.py similarity index 100% rename from Lib/test/coding20731.py rename to Lib/test/tokenizedata/coding20731.py diff --git a/Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt b/Lib/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt similarity index 100% rename from Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt rename to Lib/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt diff --git a/Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt b/Lib/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt similarity index 100% rename from Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt rename to Lib/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt diff --git a/Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt b/Lib/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt similarity index 100% rename from Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt rename to Lib/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt diff --git a/Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt b/Lib/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt similarity index 100% rename from Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt rename to Lib/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt diff --git a/Lib/test/tokenize_tests.txt b/Lib/test/tokenizedata/tokenize_tests.txt similarity index 100% rename from Lib/test/tokenize_tests.txt rename to Lib/test/tokenizedata/tokenize_tests.txt diff --git a/Lib/test/ann_module.py b/Lib/test/typinganndata/ann_module.py similarity index 100% rename from Lib/test/ann_module.py rename to Lib/test/typinganndata/ann_module.py diff --git a/Lib/test/ann_module2.py b/Lib/test/typinganndata/ann_module2.py similarity index 100% rename from Lib/test/ann_module2.py rename to Lib/test/typinganndata/ann_module2.py diff --git a/Lib/test/ann_module3.py b/Lib/test/typinganndata/ann_module3.py similarity index 100% rename from Lib/test/ann_module3.py rename to Lib/test/typinganndata/ann_module3.py diff --git a/Lib/test/ann_module4.py b/Lib/test/typinganndata/ann_module4.py similarity index 100% rename from Lib/test/ann_module4.py rename to Lib/test/typinganndata/ann_module4.py diff --git a/Lib/test/ann_module5.py b/Lib/test/typinganndata/ann_module5.py similarity index 100% rename from Lib/test/ann_module5.py rename to Lib/test/typinganndata/ann_module5.py diff --git a/Lib/test/ann_module6.py b/Lib/test/typinganndata/ann_module6.py similarity index 100% rename from Lib/test/ann_module6.py rename to Lib/test/typinganndata/ann_module6.py diff --git a/Lib/test/ann_module7.py b/Lib/test/typinganndata/ann_module7.py similarity index 100% rename from Lib/test/ann_module7.py rename to Lib/test/typinganndata/ann_module7.py diff --git a/Lib/test/ann_module8.py b/Lib/test/typinganndata/ann_module8.py similarity index 100% rename from Lib/test/ann_module8.py rename to Lib/test/typinganndata/ann_module8.py diff --git a/Lib/textwrap.py b/Lib/textwrap.py index 98bedd27ea3a11..7ca393d1c371aa 100644 --- a/Lib/textwrap.py +++ b/Lib/textwrap.py @@ -476,13 +476,19 @@ def indent(text, prefix, predicate=None): consist solely of whitespace characters. """ if predicate is None: - def predicate(line): - return line.strip() - - def prefixed_lines(): - for line in text.splitlines(True): - yield (prefix + line if predicate(line) else line) - return ''.join(prefixed_lines()) + # str.splitlines(True) doesn't produce empty string. + # ''.splitlines(True) => [] + # 'foo\n'.splitlines(True) => ['foo\n'] + # So we can use just `not s.isspace()` here. + predicate = lambda s: not s.isspace() + + prefixed_lines = [] + for line in text.splitlines(True): + if predicate(line): + prefixed_lines.append(prefix) + prefixed_lines.append(line) + + return ''.join(prefixed_lines) if __name__ == "__main__": diff --git a/Lib/threading.py b/Lib/threading.py index e036cb891e196d..41c3a9ff93856f 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -4,6 +4,7 @@ import sys as _sys import _thread import functools +import warnings from time import monotonic as _time from _weakrefset import WeakSet @@ -37,6 +38,7 @@ _allocate_lock = _thread.allocate_lock _set_sentinel = _thread._set_sentinel get_ident = _thread.get_ident +_is_main_interpreter = _thread._is_main_interpreter try: get_native_id = _thread.get_native_id _HAVE_THREAD_NATIVE_ID = True @@ -116,6 +118,12 @@ def RLock(*args, **kwargs): acquired it. """ + if args or kwargs: + warnings.warn( + 'Passing arguments to RLock is deprecated and will be removed in 3.15', + DeprecationWarning, + stacklevel=2, + ) if _CRLock is None: return _PyRLock(*args, **kwargs) return _CRLock(*args, **kwargs) @@ -238,6 +246,13 @@ def _release_save(self): def _is_owned(self): return self._owner == get_ident() + # Internal method used for reentrancy checks + + def _recursion_count(self): + if self._owner != get_ident(): + return 0 + return self._count + _PyRLock = _RLock @@ -1560,7 +1575,7 @@ def _shutdown(): # the main thread's tstate_lock - that won't happen until the interpreter # is nearly dead. So we release it here. Note that just calling _stop() # isn't enough: other threads may already be waiting on _tstate_lock. - if _main_thread._is_stopped: + if _main_thread._is_stopped and _is_main_interpreter(): # _shutdown() was already called return @@ -1578,8 +1593,11 @@ def _shutdown(): # The main thread isn't finished yet, so its thread state lock can't # have been released. assert tlock is not None - assert tlock.locked() - tlock.release() + if tlock.locked(): + # It should have been released already by + # _PyInterpreterState_SetNotRunningMain(), but there may be + # embedders that aren't calling that yet. + tlock.release() _main_thread._stop() else: # bpo-1596321: _shutdown() must be called in the main thread. @@ -1613,6 +1631,7 @@ def main_thread(): In normal conditions, the main thread is the thread from which the Python interpreter was started. """ + # XXX Figure this out for subinterpreters. (See gh-75698.) return _main_thread # get thread-local implementation, either from the thread diff --git a/Lib/timeit.py b/Lib/timeit.py index 0cf8db67723a49..02cfafaf36e5d1 100755 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -50,9 +50,9 @@ """ import gc +import itertools import sys import time -import itertools __all__ = ["Timer", "timeit", "repeat", "default_timer"] @@ -77,9 +77,11 @@ def inner(_it, _timer{init}): return _t1 - _t0 """ + def reindent(src, indent): """Helper to reindent a multi-line statement.""" - return src.replace("\n", "\n" + " "*indent) + return src.replace("\n", "\n" + " " * indent) + class Timer: """Class for timing execution speed of small code snippets. @@ -166,7 +168,7 @@ def timeit(self, number=default_number): To be precise, this executes the setup statement once, and then returns the time it takes to execute the main statement - a number of times, as a float measured in seconds. The + a number of times, as float seconds if using the default timer. The argument is the number of times through the loop, defaulting to one million. The main statement, the setup statement and the timer function to be used are passed to the constructor. @@ -228,16 +230,19 @@ def autorange(self, callback=None): return (number, time_taken) i *= 10 + def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None): """Convenience function to create Timer object and call timeit method.""" return Timer(stmt, setup, timer, globals).timeit(number) + def repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number, globals=None): """Convenience function to create Timer object and call repeat method.""" return Timer(stmt, setup, timer, globals).repeat(repeat, number) + def main(args=None, *, _wrap_timer=None): """Main program, used when run as a script. @@ -269,7 +274,7 @@ def main(args=None, *, _wrap_timer=None): timer = default_timer stmt = "\n".join(args) or "pass" - number = 0 # auto-determine + number = 0 # auto-determine setup = [] repeat = default_repeat verbose = 0 @@ -286,7 +291,7 @@ def main(args=None, *, _wrap_timer=None): time_unit = a else: print("Unrecognized unit. Please select nsec, usec, msec, or sec.", - file=sys.stderr) + file=sys.stderr) return 2 if o in ("-r", "--repeat"): repeat = int(a) @@ -320,7 +325,7 @@ def callback(number, time_taken): msg = "{num} loop{s} -> {secs:.{prec}g} secs" plural = (number != 1) print(msg.format(num=number, s='s' if plural else '', - secs=time_taken, prec=precision)) + secs=time_taken, prec=precision)) try: number, _ = t.autorange(callback) except: @@ -371,5 +376,6 @@ def format_time(dt): UserWarning, '', 0) return None + if __name__ == "__main__": sys.exit(main()) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index c675c511e04533..440e7f100c8c47 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -901,6 +901,85 @@ def bell(self, displayof=0): """Ring a display's bell.""" self.tk.call(('bell',) + self._displayof(displayof)) + def tk_busy_cget(self, option): + """Return the value of busy configuration option. + + The widget must have been previously made busy by + tk_busy_hold(). Option may have any of the values accepted by + tk_busy_hold(). + """ + return self.tk.call('tk', 'busy', 'cget', self._w, '-'+option) + busy_cget = tk_busy_cget + + def tk_busy_configure(self, cnf=None, **kw): + """Query or modify the busy configuration options. + + The widget must have been previously made busy by + tk_busy_hold(). Options may have any of the values accepted by + tk_busy_hold(). + + Please note that the option database is referenced by the widget + name or class. For example, if a Frame widget with name "frame" + is to be made busy, the busy cursor can be specified for it by + either call: + + w.option_add('*frame.busyCursor', 'gumby') + w.option_add('*Frame.BusyCursor', 'gumby') + """ + if kw: + cnf = _cnfmerge((cnf, kw)) + elif cnf: + cnf = _cnfmerge(cnf) + if cnf is None: + return self._getconfigure( + 'tk', 'busy', 'configure', self._w) + if isinstance(cnf, str): + return self._getconfigure1( + 'tk', 'busy', 'configure', self._w, '-'+cnf) + self.tk.call('tk', 'busy', 'configure', self._w, *self._options(cnf)) + busy_config = busy_configure = tk_busy_config = tk_busy_configure + + def tk_busy_current(self, pattern=None): + """Return a list of widgets that are currently busy. + + If a pattern is given, only busy widgets whose path names match + a pattern are returned. + """ + return [self._nametowidget(x) for x in + self.tk.splitlist(self.tk.call( + 'tk', 'busy', 'current', pattern))] + busy_current = tk_busy_current + + def tk_busy_forget(self): + """Make this widget no longer busy. + + User events will again be received by the widget. + """ + self.tk.call('tk', 'busy', 'forget', self._w) + busy_forget = tk_busy_forget + + def tk_busy_hold(self, **kw): + """Make this widget appear busy. + + The specified widget and its descendants will be blocked from + user interactions. Normally update() should be called + immediately afterward to insure that the hold operation is in + effect before the application starts its processing. + + The only supported configuration option is: + + cursor: the cursor to be displayed when the widget is made + busy. + """ + self.tk.call('tk', 'busy', 'hold', self._w, *self._options(kw)) + busy = busy_hold = tk_busy = tk_busy_hold + + def tk_busy_status(self): + """Return True if the widget is busy, False otherwise.""" + return self.tk.getboolean(self.tk.call( + 'tk', 'busy', 'status', self._w)) + busy_status = tk_busy_status + # Clipboard handling: def clipboard_get(self, **kw): """Retrieve data from the clipboard on window's display. @@ -4069,8 +4148,6 @@ def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): elif kw: cnf = kw options = () for k, v in cnf.items(): - if callable(v): - v = self._register(v) options = options + ('-'+k, v) self.tk.call(('image', 'create', imgtype, name,) + options) self.name = name @@ -4097,8 +4174,6 @@ def configure(self, **kw): for k, v in _cnfmerge(kw).items(): if v is not None: if k[-1] == '_': k = k[:-1] - if callable(v): - v = self._register(v) res = res + ('-'+k, v) self.tk.call((self.name, 'config') + res) diff --git a/Lib/token.py b/Lib/token.py index 487f6edd3c951c..b620317106e173 100644 --- a/Lib/token.py +++ b/Lib/token.py @@ -59,20 +59,18 @@ COLONEQUAL = 53 EXCLAMATION = 54 OP = 55 -AWAIT = 56 -ASYNC = 57 -TYPE_IGNORE = 58 -TYPE_COMMENT = 59 -SOFT_KEYWORD = 60 -FSTRING_START = 61 -FSTRING_MIDDLE = 62 -FSTRING_END = 63 -COMMENT = 64 -NL = 65 +TYPE_IGNORE = 56 +TYPE_COMMENT = 57 +SOFT_KEYWORD = 58 +FSTRING_START = 59 +FSTRING_MIDDLE = 60 +FSTRING_END = 61 +COMMENT = 62 +NL = 63 # These aren't used by the C tokenizer but are needed for tokenize.py -ERRORTOKEN = 66 -ENCODING = 67 -N_TOKENS = 68 +ERRORTOKEN = 64 +ENCODING = 65 +N_TOKENS = 66 # Special definitions for cooperation with parser NT_OFFSET = 256 diff --git a/Lib/tokenize.py b/Lib/tokenize.py index c21876fb403d8f..0ab1893d42f72f 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -298,7 +298,7 @@ def untokenize(iterable): def _get_normal_name(orig_enc): - """Imitates get_normal_name in tokenizer.c.""" + """Imitates get_normal_name in Parser/tokenizer/helpers.c.""" # Only care about the first 12 characters. enc = orig_enc[:12].lower().replace("_", "-") if enc == "utf-8" or enc.startswith("utf-8-"): diff --git a/Lib/traceback.py b/Lib/traceback.py index 354754b9560a19..7cc84b9c762aeb 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -125,6 +125,14 @@ def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ te.print(file=file, chain=chain) +BUILTIN_EXCEPTION_LIMIT = object() + + +def _print_exception_bltin(exc, /): + file = sys.stderr if sys.stderr is not None else sys.__stderr__ + return print_exception(exc, limit=BUILTIN_EXCEPTION_LIMIT, file=file) + + def format_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ chain=True): """Format a stack trace and the exception information. @@ -406,12 +414,16 @@ def _extract_from_extended_frame_gen(klass, frame_gen, *, limit=None, # (frame, (lineno, end_lineno, colno, end_colno)) in the stack. # Only lineno is required, the remaining fields can be None if the # information is not available. - if limit is None: + builtin_limit = limit is BUILTIN_EXCEPTION_LIMIT + if limit is None or builtin_limit: limit = getattr(sys, 'tracebacklimit', None) if limit is not None and limit < 0: limit = 0 if limit is not None: - if limit >= 0: + if builtin_limit: + frame_gen = tuple(frame_gen) + frame_gen = frame_gen[len(frame_gen) - limit:] + elif limit >= 0: frame_gen = itertools.islice(frame_gen, limit) else: frame_gen = collections.deque(frame_gen, maxlen=-limit) @@ -422,7 +434,6 @@ def _extract_from_extended_frame_gen(klass, frame_gen, *, limit=None, co = f.f_code filename = co.co_filename name = co.co_name - fnames.add(filename) linecache.lazycache(filename, f.f_globals) # Must defer line lookups until we have called checkcache. @@ -435,6 +446,7 @@ def _extract_from_extended_frame_gen(klass, frame_gen, *, limit=None, end_lineno=end_lineno, colno=colno, end_colno=end_colno)) for filename in fnames: linecache.checkcache(filename) + # If immediate lookup was desired, trigger lookups now. if lookup_lines: for f in result: @@ -467,8 +479,12 @@ def format_frame_summary(self, frame_summary): gets called for every frame to be printed in the stack summary. """ row = [] - row.append(' File "{}", line {}, in {}\n'.format( - frame_summary.filename, frame_summary.lineno, frame_summary.name)) + if frame_summary.filename.startswith("", line {}, in {}\n'.format( + frame_summary.lineno, frame_summary.name)) + else: + row.append(' File "{}", line {}, in {}\n'.format( + frame_summary.filename, frame_summary.lineno, frame_summary.name)) if frame_summary.line: stripped_line = frame_summary.line.strip() row.append(' {}\n'.format(stripped_line)) @@ -608,11 +624,21 @@ def _extract_caret_anchors_from_line_segment(segment): and not operator_str[operator_offset + 1].isspace() ): right_anchor += 1 + + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch in ")#"): + left_anchor += 1 + right_anchor += 1 return _Anchors(normalize(left_anchor), normalize(right_anchor)) case ast.Subscript(): - subscript_start = normalize(expr.value.end_col_offset) - subscript_end = normalize(expr.slice.end_col_offset + 1) - return _Anchors(subscript_start, subscript_end) + left_anchor = normalize(expr.value.end_col_offset) + right_anchor = normalize(expr.slice.end_col_offset + 1) + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch != "["): + left_anchor += 1 + while right_anchor < len(segment) and ((ch := segment[right_anchor]).isspace() or ch != "]"): + right_anchor += 1 + if right_anchor < len(segment): + right_anchor += 1 + return _Anchors(left_anchor, right_anchor) return None @@ -731,9 +757,9 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, wrong_name = getattr(exc_value, "name", None) if wrong_name is not None and wrong_name in sys.stdlib_module_names: if suggestion: - self._str += f" Or did you forget to import '{wrong_name}'" + self._str += f" Or did you forget to import '{wrong_name}'?" else: - self._str += f". Did you forget to import '{wrong_name}'" + self._str += f". Did you forget to import '{wrong_name}'?" if lookup_lines: self._load_lines() self.__suppress_context__ = \ @@ -894,7 +920,11 @@ def _format_syntax_error(self, stype): if self.offset is not None: offset = self.offset end_offset = self.end_offset if self.end_offset not in {None, 0} else offset - if offset == end_offset or end_offset == -1: + if self.text and offset > len(self.text): + offset = len(self.text) + 1 + if self.text and end_offset > len(self.text): + end_offset = len(self.text) + 1 + if offset >= end_offset or end_offset < 0: end_offset = offset + 1 # Convert 1-based column offset to 0-based index into stripped text diff --git a/Lib/turtle.py b/Lib/turtle.py index e542bc956897e9..7bfe81351b0b34 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -874,7 +874,7 @@ def __init__(self, type_, data=None): if isinstance(data, str): if data.lower().endswith(".gif") and isfile(data): data = TurtleScreen._image(data) - # else data assumed to be Photoimage + # else data assumed to be PhotoImage elif type_ == "compound": data = [] else: @@ -3920,28 +3920,33 @@ def getmethparlist(ob): function definition and the second is suitable for use in function call. The "self" parameter is not included. """ - defText = callText = "" + orig_sig = inspect.signature(ob) # bit of a hack for methods - turn it into a function # but we drop the "self" param. # Try and build one for Python defined functions - args, varargs, varkw = inspect.getargs(ob.__code__) - items2 = args[1:] - realArgs = args[1:] - defaults = ob.__defaults__ or [] - defaults = ["=%r" % (value,) for value in defaults] - defaults = [""] * (len(realArgs)-len(defaults)) + defaults - items1 = [arg + dflt for arg, dflt in zip(realArgs, defaults)] - if varargs is not None: - items1.append("*" + varargs) - items2.append("*" + varargs) - if varkw is not None: - items1.append("**" + varkw) - items2.append("**" + varkw) - defText = ", ".join(items1) - defText = "(%s)" % defText - callText = ", ".join(items2) - callText = "(%s)" % callText - return defText, callText + func_sig = orig_sig.replace( + parameters=list(orig_sig.parameters.values())[1:], + ) + + call_args = [] + for param in func_sig.parameters.values(): + match param.kind: + case ( + inspect.Parameter.POSITIONAL_ONLY + | inspect.Parameter.POSITIONAL_OR_KEYWORD + ): + call_args.append(param.name) + case inspect.Parameter.VAR_POSITIONAL: + call_args.append(f'*{param.name}') + case inspect.Parameter.KEYWORD_ONLY: + call_args.append(f'{param.name}={param.name}') + case inspect.Parameter.VAR_KEYWORD: + call_args.append(f'**{param.name}') + case _: + raise RuntimeError('Unsupported parameter kind', param.kind) + call_text = f'({', '.join(call_args)})' + + return str(func_sig), call_text def _turtle_docrevise(docstr): """To reduce docstrings from RawTurtle class for functions diff --git a/Lib/types.py b/Lib/types.py index 6110e6e1de7249..1484c22ee9dffa 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -1,6 +1,7 @@ """ Define names for built-in types that aren't directly accessible as a builtin. """ + import sys # Iterators in Python aren't a matter of type but of protocol. A large @@ -165,14 +166,11 @@ class Baz(list[str]): ... assert get_original_bases(int) == (object,) """ try: - return cls.__orig_bases__ + return cls.__dict__.get("__orig_bases__", cls.__bases__) except AttributeError: - try: - return cls.__bases__ - except AttributeError: - raise TypeError( - f'Expected an instance of type, not {type(cls).__name__!r}' - ) from None + raise TypeError( + f"Expected an instance of type, not {type(cls).__name__!r}" + ) from None class DynamicClassAttribute: @@ -333,4 +331,11 @@ def wrapped(*args, **kwargs): NoneType = type(None) NotImplementedType = type(NotImplemented) +def __getattr__(name): + if name == 'CapsuleType': + import _socket + return type(_socket.CAPI) + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + __all__ = [n for n in globals() if n[:1] != '_'] +__all__ += ['CapsuleType'] diff --git a/Lib/typing.py b/Lib/typing.py index 387b4c5ad5284b..14845b36028ca1 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -23,10 +23,8 @@ from collections import defaultdict import collections.abc import copyreg -import contextlib import functools import operator -import re as stdlib_re # Avoid confusion with the typing.re namespace on <=3.11 import sys import types from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias @@ -939,13 +937,6 @@ def _is_typevar_like(x: Any) -> bool: return isinstance(x, (TypeVar, ParamSpec)) or _is_unpacked_typevartuple(x) -class _PickleUsingNameMixin: - """Mixin enabling pickling based on self.__name__.""" - - def __reduce__(self): - return self.__name__ - - def _typevar_subst(self, arg): msg = "Parameters to generic types must be types." arg = _type_check(arg, msg, is_argument=True) @@ -1678,7 +1669,8 @@ class _TypingEllipsis: _SPECIAL_NAMES = frozenset({ '__abstractmethods__', '__annotations__', '__dict__', '__doc__', '__init__', '__module__', '__new__', '__slots__', - '__subclasshook__', '__weakref__', '__class_getitem__' + '__subclasshook__', '__weakref__', '__class_getitem__', + '__match_args__', }) # These special attributes will be not collected as protocol members. @@ -2001,7 +1993,8 @@ def __mro_entries__(self, bases): return (self.__origin__,) -class Annotated: +@_SpecialForm +def Annotated(self, params): """Add context-specific metadata to a type. Example: Annotated[int, runtime_check.Unsigned] indicates to the @@ -2048,30 +2041,17 @@ class Annotated: where T1, T2 etc. are TypeVars, which would be invalid, because only one type should be passed to Annotated. """ - - __slots__ = () - - def __new__(cls, *args, **kwargs): - raise TypeError("Type Annotated cannot be instantiated.") - - @_tp_cache - def __class_getitem__(cls, params): - if not isinstance(params, tuple) or len(params) < 2: - raise TypeError("Annotated[...] should be used " - "with at least two arguments (a type and an " - "annotation).") - if _is_unpacked_typevartuple(params[0]): - raise TypeError("Annotated[...] should not be used with an " - "unpacked TypeVarTuple") - msg = "Annotated[t, ...]: t must be a type." - origin = _type_check(params[0], msg, allow_special_forms=True) - metadata = tuple(params[1:]) - return _AnnotatedAlias(origin, metadata) - - def __init_subclass__(cls, *args, **kwargs): - raise TypeError( - "Cannot subclass {}.Annotated".format(cls.__module__) - ) + if not isinstance(params, tuple) or len(params) < 2: + raise TypeError("Annotated[...] should be used " + "with at least two arguments (a type and an " + "annotation).") + if _is_unpacked_typevartuple(params[0]): + raise TypeError("Annotated[...] should not be used with an " + "unpacked TypeVarTuple") + msg = "Annotated[t, ...]: t must be a type." + origin = _type_check(params[0], msg, allow_special_forms=True) + metadata = tuple(params[1:]) + return _AnnotatedAlias(origin, metadata) def runtime_checkable(cls): @@ -2592,8 +2572,6 @@ class Other(Leaf): # Error reported by type checker KeysView = _alias(collections.abc.KeysView, 1) ItemsView = _alias(collections.abc.ItemsView, 2) ValuesView = _alias(collections.abc.ValuesView, 1) -ContextManager = _alias(contextlib.AbstractContextManager, 1, name='ContextManager') -AsyncContextManager = _alias(contextlib.AbstractAsyncContextManager, 1, name='AsyncContextManager') Dict = _alias(dict, 2, inst=False, name='Dict') DefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict') OrderedDict = _alias(collections.OrderedDict, 2) @@ -2898,8 +2876,7 @@ def __new__(cls, name, bases, ns, total=True): tp_dict.__annotations__ = annotations tp_dict.__required_keys__ = frozenset(required_keys) tp_dict.__optional_keys__ = frozenset(optional_keys) - if not hasattr(tp_dict, '__total__'): - tp_dict.__total__ = total + tp_dict.__total__ = total return tp_dict __call__ = dict # static method @@ -3251,10 +3228,6 @@ def __enter__(self) -> 'TextIO': pass -Pattern = _alias(stdlib_re.Pattern, 1) -Match = _alias(stdlib_re.Match, 1) - - def reveal_type[T](obj: T, /) -> T: """Reveal the inferred type of a variable. @@ -3439,3 +3412,21 @@ def get_protocol_members(tp: type, /) -> frozenset[str]: if not is_protocol(tp): raise TypeError(f'{tp!r} is not a Protocol') return frozenset(tp.__protocol_attrs__) + + +def __getattr__(attr): + """Improve the import time of the typing module. + + Soft-deprecated objects which are costly to create + are only created on-demand here. + """ + if attr in {"Pattern", "Match"}: + import re + obj = _alias(getattr(re, attr), 1) + elif attr in {"ContextManager", "AsyncContextManager"}: + import contextlib + obj = _alias(getattr(contextlib, f"Abstract{attr}"), 1, name=attr) + else: + raise AttributeError(f"module {__name__!r} has no attribute {attr!r}") + globals()[attr] = obj + return obj diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 001b640dc43ad6..811557498bb30e 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -606,7 +606,6 @@ def run(self, result=None): else: stopTestRun = None - result.startTest(self) try: testMethod = getattr(self, self._testMethodName) if (getattr(self.__class__, "__unittest_skip__", False) or @@ -617,6 +616,9 @@ def run(self, result=None): _addSkip(result, self, skip_why) return result + # Increase the number of tests only if it hasn't been skipped + result.startTest(self) + expecting_failure = ( getattr(self, "__unittest_expecting_failure__", False) or getattr(testMethod, "__unittest_expecting_failure__", False) diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index 678d627d7c6926..9a3e5cc4bf30e5 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -84,9 +84,13 @@ def loadTestsFromTestCase(self, testCaseClass): raise TypeError("Test cases should not be derived from " "TestSuite. Maybe you meant to derive from " "TestCase?") - testCaseNames = self.getTestCaseNames(testCaseClass) - if not testCaseNames and hasattr(testCaseClass, 'runTest'): - testCaseNames = ['runTest'] + if testCaseClass in (case.TestCase, case.FunctionTestCase): + # We don't load any tests from base types that should not be loaded. + testCaseNames = [] + else: + testCaseNames = self.getTestCaseNames(testCaseClass) + if not testCaseNames and hasattr(testCaseClass, 'runTest'): + testCaseNames = ['runTest'] loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) return loaded_suite @@ -95,7 +99,11 @@ def loadTestsFromModule(self, module, *, pattern=None): tests = [] for name in dir(module): obj = getattr(module, name) - if isinstance(obj, type) and issubclass(obj, case.TestCase): + if ( + isinstance(obj, type) + and issubclass(obj, case.TestCase) + and obj not in (case.TestCase, case.FunctionTestCase) + ): tests.append(self.loadTestsFromTestCase(obj)) load_tests = getattr(module, 'load_tests', None) @@ -164,7 +172,11 @@ def loadTestsFromName(self, name, module=None): if isinstance(obj, types.ModuleType): return self.loadTestsFromModule(obj) - elif isinstance(obj, type) and issubclass(obj, case.TestCase): + elif ( + isinstance(obj, type) + and issubclass(obj, case.TestCase) + and obj not in (case.TestCase, case.FunctionTestCase) + ): return self.loadTestsFromTestCase(obj) elif (isinstance(obj, types.FunctionType) and isinstance(parent, type) and diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index 3ace0a5b7bf2ef..9e56f658027f4d 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -97,10 +97,12 @@ def _restoreStdout(self): sys.stdout = self._original_stdout sys.stderr = self._original_stderr - self._stdout_buffer.seek(0) - self._stdout_buffer.truncate() - self._stderr_buffer.seek(0) - self._stderr_buffer.truncate() + if self._stdout_buffer is not None: + self._stdout_buffer.seek(0) + self._stdout_buffer.truncate() + if self._stderr_buffer is not None: + self._stderr_buffer.seek(0) + self._stderr_buffer.truncate() def stopTestRun(self): """Called once after all tests are executed. diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 2173c9b13e5cf7..d960bf3bd82ac5 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -41,11 +41,13 @@ class EnvBuilder: environment :param prompt: Alternative terminal prefix for the environment. :param upgrade_deps: Update the base venv modules to the latest on PyPI + :param scm_ignore_files: Create ignore files for the SCMs specified by the + iterable. """ def __init__(self, system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, - upgrade_deps=False): + upgrade_deps=False, *, scm_ignore_files=frozenset()): self.system_site_packages = system_site_packages self.clear = clear self.symlinks = symlinks @@ -56,6 +58,7 @@ def __init__(self, system_site_packages=False, clear=False, prompt = os.path.basename(os.getcwd()) self.prompt = prompt self.upgrade_deps = upgrade_deps + self.scm_ignore_files = frozenset(map(str.lower, scm_ignore_files)) def create(self, env_dir): """ @@ -66,6 +69,8 @@ def create(self, env_dir): """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) + for scm in self.scm_ignore_files: + getattr(self, f"create_{scm}_ignore_file")(context) # See issue 24875. We need system_site_packages to be False # until after pip is installed. true_system_site_packages = self.system_site_packages @@ -210,6 +215,8 @@ def create_configuration(self, context): args.append('--upgrade-deps') if self.orig_prompt is not None: args.append(f'--prompt="{self.orig_prompt}"') + if not self.scm_ignore_files: + args.append('--without-scm-ignore-files') args.append(context.env_dir) args = ' '.join(args) @@ -278,6 +285,19 @@ def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): shutil.copyfile(src, dst) + def create_git_ignore_file(self, context): + """ + Create a .gitignore file in the environment directory. + + The contents of the file cause the entire environment directory to be + ignored by git. + """ + gitignore_path = os.path.join(context.env_dir, '.gitignore') + with open(gitignore_path, 'w', encoding='utf-8') as file: + file.write('# Created by venv; ' + 'see https://docs.python.org/3/library/venv.html\n') + file.write('*\n') + def setup_python(self, context): """ Set up a Python executable in the environment. @@ -461,11 +481,13 @@ def upgrade_dependencies(self, context): def create(env_dir, system_site_packages=False, clear=False, - symlinks=False, with_pip=False, prompt=None, upgrade_deps=False): + symlinks=False, with_pip=False, prompt=None, upgrade_deps=False, + *, scm_ignore_files=frozenset()): """Create a virtual environment in a directory.""" builder = EnvBuilder(system_site_packages=system_site_packages, clear=clear, symlinks=symlinks, with_pip=with_pip, - prompt=prompt, upgrade_deps=upgrade_deps) + prompt=prompt, upgrade_deps=upgrade_deps, + scm_ignore_files=scm_ignore_files) builder.create(env_dir) @@ -525,6 +547,11 @@ def main(args=None): dest='upgrade_deps', help=f'Upgrade core dependencies ({", ".join(CORE_VENV_DEPS)}) ' 'to the latest version in PyPI') + parser.add_argument('--without-scm-ignore-files', dest='scm_ignore_files', + action='store_const', const=frozenset(), + default=frozenset(['git']), + help='Skips adding SCM ignore files to the environment ' + 'directory (Git is supported by default).') options = parser.parse_args(args) if options.upgrade and options.clear: raise ValueError('you cannot supply --upgrade and --clear together.') @@ -534,7 +561,8 @@ def main(args=None): upgrade=options.upgrade, with_pip=options.with_pip, prompt=options.prompt, - upgrade_deps=options.upgrade_deps) + upgrade_deps=options.upgrade_deps, + scm_ignore_files=options.scm_ignore_files) for d in options.dirs: builder.create(d) diff --git a/Lib/venv/__main__.py b/Lib/venv/__main__.py index 912423e4a78198..88f55439dc210c 100644 --- a/Lib/venv/__main__.py +++ b/Lib/venv/__main__.py @@ -6,5 +6,5 @@ main() rc = 0 except Exception as e: - print('Error: %s' % e, file=sys.stderr) + print('Error:', e, file=sys.stderr) sys.exit(rc) diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index ef8a159833bbc0..db51f350ea0153 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -300,12 +300,28 @@ def _in_document(node): node = node.parentNode return False -def _write_data(writer, data): +def _write_data(writer, text, attr): "Writes datachars to writer." - if data: - data = data.replace("&", "&").replace("<", "<"). \ - replace("\"", """).replace(">", ">") - writer.write(data) + if not text: + return + # See the comments in ElementTree.py for behavior and + # implementation details. + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if attr: + if '"' in text: + text = text.replace('"', """) + if "\r" in text: + text = text.replace("\r", " ") + if "\n" in text: + text = text.replace("\n", " ") + if "\t" in text: + text = text.replace("\t", " ") + writer.write(text) def _get_elements_by_tagName_helper(parent, name, rc): for node in parent.childNodes: @@ -883,7 +899,7 @@ def writexml(self, writer, indent="", addindent="", newl=""): for a_name in attrs.keys(): writer.write(" %s=\"" % a_name) - _write_data(writer, attrs[a_name].value) + _write_data(writer, attrs[a_name].value, True) writer.write("\"") if self.childNodes: writer.write(">") @@ -1112,7 +1128,7 @@ def splitText(self, offset): return newText def writexml(self, writer, indent="", addindent="", newl=""): - _write_data(writer, "%s%s%s" % (indent, self.data, newl)) + _write_data(writer, "%s%s%s" % (indent, self.data, newl), False) # DOM Level 3 (WD 9 April 2002) diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 9fc1840ba1e534..2c963de18e4f95 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -188,28 +188,42 @@ class LargeZipFile(Exception): _DD_SIGNATURE = 0x08074b50 -_EXTRA_FIELD_STRUCT = struct.Struct(' "$${bin}.fdata"; \ @@ -767,15 +785,18 @@ coverage-report: regen-token regen-frozen @ # build with coverage info $(MAKE) coverage @ # run tests, ignore failures - $(TESTRUNNER) $(TESTOPTS) || true + $(TESTRUNNER) --fast-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) || true @ # build lcov report $(MAKE) coverage-lcov # Run "Argument Clinic" over all source files .PHONY: clinic clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --exclude Lib/test/clinic.test.c --srcdir $(srcdir) + +.PHONY: clinic-tests +clinic-tests: check-clean-src $(srcdir)/Lib/test/clinic.test.c + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py -f $(srcdir)/Lib/test/clinic.test.c # Build the interpreter $(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) @@ -1245,13 +1266,11 @@ regen-frozen: Tools/build/freeze_modules.py $(FROZEN_FILES_IN) ############################################################################ # Deepfreeze targets -.PHONY: regen-deepfreeze -regen-deepfreeze: $(DEEPFREEZE_OBJS) - -DEEPFREEZE_DEPS=$(srcdir)/Tools/build/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) +DEEPFREEZE_C = Python/deepfreeze/deepfreeze.c +DEEPFREEZE_DEPS=$(srcdir)/Tools/build/deepfreeze.py Include/internal/pycore_global_strings.h $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) # BEGIN: deepfreeze modules -Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) +$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS) $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \ Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap \ Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external \ @@ -1278,8 +1297,6 @@ Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) Python/frozen_modules/frozen_only.h:frozen_only \ -o Python/deepfreeze/deepfreeze.c # END: deepfreeze modules - @echo "Note: Deepfreeze may have added some global objects," - @echo " so run 'make regen-global-objects' if necessary." # We keep this renamed target around for folks with muscle memory. .PHONY: regen-importlib @@ -1288,11 +1305,11 @@ regen-importlib: regen-frozen ############################################################################ # Global objects +# Dependencies which can add and/or remove _Py_ID() identifiers: +# - "make clinic" .PHONY: regen-global-objects -regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py +regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py clinic $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py - @echo "Note: Global objects can be added or removed by other tools (e.g. deepfreeze), " - @echo " so be sure to re-run regen-global-objects after those tools." ############################################################################ # ABI @@ -1314,9 +1331,10 @@ regen-limited-abi: all ############################################################################ # Regenerate all generated files +# "clinic" is regenerated implicitly via "regen-global-objects". .PHONY: regen-all -regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \ - regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \ +regen-all: regen-cases regen-typeslots \ + regen-token regen-ast regen-keyword regen-sre regen-frozen \ regen-pegen-metaparser regen-pegen regen-test-frozenmain \ regen-test-levenshtein regen-global-objects @echo @@ -1395,11 +1413,13 @@ regen-pegen-metaparser: .PHONY: regen-pegen regen-pegen: @$(MKDIR_P) $(srcdir)/Parser + @$(MKDIR_P) $(srcdir)/Parser/tokenizer + @$(MKDIR_P) $(srcdir)/Parser/lexer PYTHONPATH=$(srcdir)/Tools/peg_generator $(PYTHON_FOR_REGEN) -m pegen -q c \ $(srcdir)/Grammar/python.gram \ $(srcdir)/Grammar/Tokens \ - -o $(srcdir)/Parser/parser.new.c - $(UPDATE_FILE) $(srcdir)/Parser/parser.c $(srcdir)/Parser/parser.new.c + -o $(srcdir)/Parser/parser.c.new + $(UPDATE_FILE) $(srcdir)/Parser/parser.c $(srcdir)/Parser/parser.c.new .PHONY: regen-ast regen-ast: @@ -1419,20 +1439,6 @@ regen-ast: $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_ast_state.h $(srcdir)/Include/internal/pycore_ast_state.h.new $(UPDATE_FILE) $(srcdir)/Python/Python-ast.c $(srcdir)/Python/Python-ast.c.new -.PHONY: regen-opcode -regen-opcode: - # Regenerate Include/opcode.h from Lib/opcode.py - # using Tools/build/generate_opcode_h.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_opcode_h.py \ - $(srcdir)/Lib/opcode.py \ - $(srcdir)/Lib/_opcode_metadata.py \ - $(srcdir)/Include/opcode.h.new \ - $(srcdir)/Include/internal/pycore_opcode.h.new \ - $(srcdir)/Include/internal/pycore_intrinsics.h.new - $(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new - $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode.h $(srcdir)/Include/internal/pycore_opcode.h.new - $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_intrinsics.h $(srcdir)/Include/internal/pycore_intrinsics.h.new - .PHONY: regen-token regen-token: # Regenerate Doc/library/token-list.inc from Grammar/Tokens @@ -1532,13 +1538,6 @@ Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c $(UNICODE_DEPS) Objects/dictobject.o: $(srcdir)/Objects/stringlib/eq.h Objects/setobject.o: $(srcdir)/Objects/stringlib/eq.h -.PHONY: regen-opcode-targets -regen-opcode-targets: - # Regenerate Python/opcode_targets.h from Lib/opcode.py - # using Python/makeopcodetargets.py - $(PYTHON_FOR_REGEN) $(srcdir)/Python/makeopcodetargets.py \ - $(srcdir)/Python/opcode_targets.h.new - $(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new .PHONY: regen-cases regen-cases: @@ -1549,13 +1548,19 @@ regen-cases: $(srcdir)/Tools/cases_generator/generate_cases.py \ $(CASESFLAG) \ -o $(srcdir)/Python/generated_cases.c.h.new \ + -n $(srcdir)/Include/opcode_ids.h.new \ + -t $(srcdir)/Python/opcode_targets.h.new \ -m $(srcdir)/Include/internal/pycore_opcode_metadata.h.new \ -e $(srcdir)/Python/executor_cases.c.h.new \ -p $(srcdir)/Lib/_opcode_metadata.py.new \ + -a $(srcdir)/Python/abstract_interp_cases.c.h.new \ $(srcdir)/Python/bytecodes.c $(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new + $(UPDATE_FILE) $(srcdir)/Include/opcode_ids.h $(srcdir)/Include/opcode_ids.h.new + $(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode_metadata.h $(srcdir)/Include/internal/pycore_opcode_metadata.h.new $(UPDATE_FILE) $(srcdir)/Python/executor_cases.c.h $(srcdir)/Python/executor_cases.c.h.new + $(UPDATE_FILE) $(srcdir)/Python/abstract_interp_cases.c.h $(srcdir)/Python/abstract_interp_cases.c.h.new $(UPDATE_FILE) $(srcdir)/Lib/_opcode_metadata.py $(srcdir)/Lib/_opcode_metadata.py.new Python/compile.o: $(srcdir)/Include/internal/pycore_opcode_metadata.h @@ -1564,16 +1569,25 @@ Python/ceval.o: \ $(srcdir)/Python/ceval_macros.h \ $(srcdir)/Python/condvar.h \ $(srcdir)/Python/generated_cases.c.h \ - $(srcdir)/Python/executor_cases.c.h \ - $(srcdir)/Include/internal/pycore_opcode_metadata.h \ $(srcdir)/Python/opcode_targets.h +Python/executor.o: \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ + $(srcdir)/Include/internal/pycore_optimizer.h \ + $(srcdir)/Python/ceval_macros.h \ + $(srcdir)/Python/executor_cases.c.h + Python/flowgraph.o: \ $(srcdir)/Include/internal/pycore_opcode_metadata.h Python/optimizer.o: \ $(srcdir)/Python/executor_cases.c.h \ - $(srcdir)/Include/internal/pycore_opcode_metadata.h + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ + $(srcdir)/Include/internal/pycore_optimizer.h + +Python/optimizer_analysis.o: \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ + $(srcdir)/Include/internal/pycore_optimizer.h Python/frozen.o: $(FROZEN_FILES_OUT) @@ -1642,6 +1656,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/object.h \ $(srcdir)/Include/objimpl.h \ $(srcdir)/Include/opcode.h \ + $(srcdir)/Include/opcode_ids.h \ $(srcdir)/Include/osdefs.h \ $(srcdir)/Include/osmodule.h \ $(srcdir)/Include/patchlevel.h \ @@ -1712,6 +1727,9 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/optimizer.h \ $(srcdir)/Include/cpython/picklebufobject.h \ $(srcdir)/Include/cpython/pthread_stubs.h \ + $(srcdir)/Include/cpython/pyatomic.h \ + $(srcdir)/Include/cpython/pyatomic_gcc.h \ + $(srcdir)/Include/cpython/pyatomic_std.h \ $(srcdir)/Include/cpython/pyctype.h \ $(srcdir)/Include/cpython/pydebug.h \ $(srcdir)/Include/cpython/pyerrors.h \ @@ -1720,6 +1738,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/pylifecycle.h \ $(srcdir)/Include/cpython/pymem.h \ $(srcdir)/Include/cpython/pystate.h \ + $(srcdir)/Include/cpython/pystats.h \ $(srcdir)/Include/cpython/pythonrun.h \ $(srcdir)/Include/cpython/pythread.h \ $(srcdir)/Include/cpython/setobject.h \ @@ -1737,11 +1756,11 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_ast_state.h \ $(srcdir)/Include/internal/pycore_atexit.h \ $(srcdir)/Include/internal/pycore_atomic.h \ - $(srcdir)/Include/internal/pycore_atomic_funcs.h \ $(srcdir)/Include/internal/pycore_bitutils.h \ $(srcdir)/Include/internal/pycore_bytes_methods.h \ $(srcdir)/Include/internal/pycore_bytesobject.h \ $(srcdir)/Include/internal/pycore_call.h \ + $(srcdir)/Include/internal/pycore_capsule.h \ $(srcdir)/Include/internal/pycore_ceval.h \ $(srcdir)/Include/internal/pycore_ceval_state.h \ $(srcdir)/Include/internal/pycore_code.h \ @@ -1768,11 +1787,14 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_global_objects_fini_generated.h \ $(srcdir)/Include/internal/pycore_hamt.h \ $(srcdir)/Include/internal/pycore_hashtable.h \ + $(srcdir)/Include/internal/pycore_identifier.h \ $(srcdir)/Include/internal/pycore_import.h \ $(srcdir)/Include/internal/pycore_initconfig.h \ $(srcdir)/Include/internal/pycore_interp.h \ $(srcdir)/Include/internal/pycore_intrinsics.h \ $(srcdir)/Include/internal/pycore_list.h \ + $(srcdir)/Include/internal/pycore_llist.h \ + $(srcdir)/Include/internal/pycore_lock.h \ $(srcdir)/Include/internal/pycore_long.h \ $(srcdir)/Include/internal/pycore_modsupport.h \ $(srcdir)/Include/internal/pycore_moduleobject.h \ @@ -1781,21 +1803,28 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_object_state.h \ $(srcdir)/Include/internal/pycore_obmalloc.h \ $(srcdir)/Include/internal/pycore_obmalloc_init.h \ - $(srcdir)/Include/internal/pycore_opcode.h \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ $(srcdir)/Include/internal/pycore_opcode_utils.h \ + $(srcdir)/Include/internal/pycore_optimizer.h \ + $(srcdir)/Include/internal/pycore_parking_lot.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \ $(srcdir)/Include/internal/pycore_pyarena.h \ + $(srcdir)/Include/internal/pycore_pybuffer.h \ $(srcdir)/Include/internal/pycore_pyerrors.h \ $(srcdir)/Include/internal/pycore_pyhash.h \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ $(srcdir)/Include/internal/pycore_pymem.h \ $(srcdir)/Include/internal/pycore_pymem_init.h \ $(srcdir)/Include/internal/pycore_pystate.h \ + $(srcdir)/Include/internal/pycore_pystats.h \ + $(srcdir)/Include/internal/pycore_pythonrun.h \ $(srcdir)/Include/internal/pycore_pythread.h \ $(srcdir)/Include/internal/pycore_range.h \ $(srcdir)/Include/internal/pycore_runtime.h \ $(srcdir)/Include/internal/pycore_runtime_init_generated.h \ $(srcdir)/Include/internal/pycore_runtime_init.h \ + $(srcdir)/Include/internal/pycore_semaphore.h \ + $(srcdir)/Include/internal/pycore_setobject.h \ $(srcdir)/Include/internal/pycore_signal.h \ $(srcdir)/Include/internal/pycore_sliceobject.h \ $(srcdir)/Include/internal/pycore_strhex.h \ @@ -1828,8 +1857,8 @@ $(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS) TESTOPTS= $(EXTRATESTOPTS) TESTPYTHON= $(RUNSHARED) $(PYTHON_FOR_BUILD) $(TESTPYTHONOPTS) -TESTRUNNER= $(TESTPYTHON) $(srcdir)/Tools/scripts/run_tests.py -TESTTIMEOUT= 1200 +TESTRUNNER= $(TESTPYTHON) -m test +TESTTIMEOUT= # Remove "test_python_*" directories of previous failed test jobs. # Pass TESTOPTS options because it can contain --tempdir option. @@ -1839,56 +1868,38 @@ cleantest: all # Run a basic set of regression tests. # This excludes some tests that are particularly resource-intensive. +# Similar to buildbottest, but use --fast-ci option, instead of --slow-ci. .PHONY: test test: all - $(TESTRUNNER) $(TESTOPTS) - -# Run the full test suite twice - once without .pyc files, and once with. -# In the past, we've had problems where bugs in the marshalling or -# elsewhere caused bytecode read from .pyc files to behave differently -# than bytecode generated directly from a .py source file. Sometimes -# the bytecode read from a .pyc file had the bug, sometimes the directly -# generated bytecode. This is sometimes a very shy bug needing a lot of -# sample data. -.PHONY: testall -testall: all - -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f - $(TESTPYTHON) -E $(srcdir)/Lib/compileall.py - -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f - -$(TESTRUNNER) -u all $(TESTOPTS) - $(TESTRUNNER) -u all $(TESTOPTS) + $(TESTRUNNER) --fast-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) # Run the test suite for both architectures in a Universal build on OSX. # Must be run on an Intel box. .PHONY: testuniversal testuniversal: all - @if [ `arch` != 'i386' ]; then \ - echo "This can only be used on OSX/i386" ;\ - exit 1 ;\ - fi - $(TESTRUNNER) -u all $(TESTOPTS) - $(RUNSHARED) /usr/libexec/oah/translate \ - ./$(BUILDPYTHON) -E -m test -j 0 -u all $(TESTOPTS) - -# Like testall, but with only one pass and without multiple processes. -# Run an optional script to include information about the build environment. + @if [ `arch` != 'i386' ]; then \ + echo "This can only be used on OSX/i386" ;\ + exit 1 ;\ + fi + $(TESTRUNNER) --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) + $(RUNSHARED) /usr/libexec/oah/translate \ + ./$(BUILDPYTHON) -E -m test -j 0 -u all $(TESTOPTS) + +# Like test, but using --slow-ci which enables all test resources and use +# longer timeout. Run an optional pybuildbot.identify script to include +# information about the build environment. .PHONY: buildbottest buildbottest: all - -@if which pybuildbot.identify >/dev/null 2>&1; then \ - pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ - fi - $(TESTRUNNER) -j 1 -u all -W --slowest --fail-env-changed --timeout=$(TESTTIMEOUT) $(TESTOPTS) - -# Like testall, but run Python tests with HOSTRUNNER directly. -.PHONY: hostrunnertest -hostrunnertest: all - $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test -u all $(TESTOPTS) + -@if which pybuildbot.identify >/dev/null 2>&1; then \ + pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ + fi + $(TESTRUNNER) --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) .PHONY: pythoninfo pythoninfo: all $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo -QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io \ +QUICKTESTOPTS= -x test_subprocess test_io \ test_multibytecodec test_urllib2_localnet test_itertools \ test_multiprocessing_fork test_multiprocessing_spawn \ test_multiprocessing_forkserver \ @@ -1897,7 +1908,7 @@ QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io \ .PHONY: quicktest quicktest: all - $(TESTRUNNER) $(QUICKTESTOPTS) + $(TESTRUNNER) --fast-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) $(QUICKTESTOPTS) # SSL tests .PHONY: multisslcompile @@ -1937,8 +1948,7 @@ altinstall: commoninstall .PHONY: commoninstall commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ altbininstall libinstall inclinstall libainstall \ - sharedinstall altmaninstall \ - @FRAMEWORKALTINSTALLLAST@ + sharedinstall altmaninstall @FRAMEWORKALTINSTALLLAST@ # Install shared libraries enabled by Setup DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) @@ -2117,6 +2127,7 @@ LIBSUBDIRS= asyncio \ re \ site-packages \ sqlite3 \ + sysconfig \ tkinter \ tomllib \ turtledemo \ @@ -2132,7 +2143,8 @@ LIBSUBDIRS= asyncio \ TESTSUBDIRS= idlelib/idle_test \ test \ test/audiodata \ - test/capath \ + test/certdata \ + test/certdata/capath \ test/cjkencodings \ test/crashers \ test/data \ @@ -2141,14 +2153,20 @@ TESTSUBDIRS= idlelib/idle_test \ test/encoded_modules \ test/leakers \ test/libregrtest \ + test/mathdata \ test/subprocessdata \ test/support \ test/support/_hypothesis_stubs \ test/test_asyncio \ test/test_capi \ + test/test_cppext \ test/test_ctypes \ + test/test_dataclasses \ test/test_email \ test/test_email/data \ + test/test_future_stmt \ + test/test_gdb \ + test/test_inspect \ test/test_import \ test/test_import/data \ test/test_import/data/circular_imports \ @@ -2202,6 +2220,7 @@ TESTSUBDIRS= idlelib/idle_test \ test/test_importlib/resources/zipdata02 \ test/test_importlib/source \ test/test_json \ + test/test_module \ test/test_peg_generator \ test/test_sqlite3 \ test/test_tkinter \ @@ -2234,6 +2253,7 @@ TESTSUBDIRS= idlelib/idle_test \ test/test_zoneinfo \ test/test_zoneinfo/data \ test/tkinterdata \ + test/tokenizedata \ test/tracedmodules \ test/typinganndata \ test/xmltestdata \ @@ -2584,6 +2604,7 @@ recheck: autoconf: (cd $(srcdir); autoreconf -ivf -Werror) +# See https://github.com/tiran/cpython_autoconf container .PHONY: regen-configure regen-configure: @if command -v podman >/dev/null; then RUNTIME="podman"; else RUNTIME="docker"; fi; \ @@ -2789,7 +2810,8 @@ MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_ MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_SHA3.h Modules/_hacl/Hacl_Hash_SHA3.c MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data.h $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h -MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/testcapi_long.h $(srcdir)/Modules/_testcapi/parts.h +MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/testcapi_long.h $(srcdir)/Modules/_testcapi/parts.h $(srcdir)/Modules/_testcapi/util.h +MODULE__TESTINTERNALCAPI_DEPS=$(srcdir)/Modules/_testinternalcapi/parts.h MODULE__SQLITE3_DEPS=$(srcdir)/Modules/_sqlite/connection.h $(srcdir)/Modules/_sqlite/cursor.h $(srcdir)/Modules/_sqlite/microprotocols.h $(srcdir)/Modules/_sqlite/module.h $(srcdir)/Modules/_sqlite/prepare_protocol.h $(srcdir)/Modules/_sqlite/row.h $(srcdir)/Modules/_sqlite/util.h CODECS_COMMON_HEADERS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h $(srcdir)/Modules/cjkcodecs/cjkcodecs.h diff --git a/Misc/ACKS b/Misc/ACKS index 645ad5b700baaa..94cb1965676f48 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -254,6 +254,7 @@ Curtis Bucher Colm Buckley Erik de Bueger Jan-Hein Bührman +Marc Bürg Lars Buitinck Artem Bulgakov Dick Bulterman @@ -289,6 +290,7 @@ Edward Catmur Lorenzo M. Catucci Bruno Cauet Donn Cave +James Cave Charles Cazabon Jesús Cea Avión Per Cederqvist @@ -347,6 +349,7 @@ Robbie Clemons Steve Clift Hervé Coatanhay Riccardo Coccioli +Jacob Coffee Nick Coghlan Josh Cogliati Noam Cohen @@ -502,6 +505,7 @@ Daniel Ellis Phil Elson David Ely Victor van den Elzen +Vlad Emelianov Jeff Epler Tom Epperly Gökcen Eraslan @@ -1149,6 +1153,7 @@ Colin Marc Vincent Marchetti David Marek Doug Marien +Chris Markiewicz Sven Marnach John Marshall Alex Martelli @@ -1189,6 +1194,7 @@ Andrew McNamara Caolan McNamara Jeff McNeil Craig McPheeters +Corvin McPherson Lambert Meertens Bill van Melle Lucas Prado Melo @@ -1266,7 +1272,7 @@ R. David Murray Matti Mäki Jörg Müller Kaushik N -Dong-hee Na +Donghee Na Dale Nagata John Nagle Takahiro Nakayama @@ -1328,6 +1334,7 @@ Ethan Onstott Ken Jin Ooi Piet van Oostrum Tomas Oppelstrup +Itamar Oren Jason Orendorff Yan "yyyyyyyan" Orestes Bastien Orivel @@ -1338,7 +1345,6 @@ Michele Orrù Tomáš Orsava Oleg Oshmyan Denis Osipov -Itamar Ostricher Denis S. Otkidach Peter Otten Michael Otteneder @@ -1367,6 +1373,7 @@ Peter Parente Alexandre Parenteau Dan Parisien HyeSoo Park +Moonsik Park William Park Claude Paroz Heikki Partanen @@ -1700,10 +1707,12 @@ Ngalim Siregar Kragen Sitaker Kaartic Sivaraam StanisÅ‚aw Skonieczny +Bart Skowron Roman Skurikhin Ville Skyttä Michael Sloan Nick Sloan +Tyler Smart Radek Smejkal Václav Å milauer Casper W. Smet @@ -1864,6 +1873,7 @@ Steven Troxler Brent Tubbs Anthony Tuininga Erno Tukia +Adam Turner David Turner Stephen Turner Itamar Turner-Trauring @@ -2071,7 +2081,5 @@ Jelle Zijlstra Gennadiy Zlobin Doug Zongker Peter Ã…strand -Vlad Emelianov -Andrey Doroschenko (Entries should be added in rough alphabetical order by last names) diff --git a/Misc/NEWS.d/3.10.0a1.rst b/Misc/NEWS.d/3.10.0a1.rst index 301612c4307da4..a9f25b482508ba 100644 --- a/Misc/NEWS.d/3.10.0a1.rst +++ b/Misc/NEWS.d/3.10.0a1.rst @@ -68,7 +68,7 @@ getting the ``__bases__`` attribute leads to infinite recursion. .. section: Core and Builtins Speed up calls to ``reversed()`` by using the :pep:`590` ``vectorcall`` -calling convention. Patch by Dong-hee Na. +calling convention. Patch by Donghee Na. .. @@ -88,7 +88,7 @@ convention. Patch by Dennis Sweeney. .. section: Core and Builtins Speed up calls to ``bool()`` by using the :pep:`590` ``vectorcall`` calling -convention. Patch by Dong-hee Na. +convention. Patch by Donghee Na. .. @@ -228,8 +228,8 @@ format string in f-string and :meth:`str.format`. .. section: Core and Builtins The implementation of :func:`signal.siginterrupt` now uses -:c:func:`sigaction` (if it is available in the system) instead of the -deprecated :c:func:`siginterrupt`. Patch by Pablo Galindo. +:c:func:`!sigaction` (if it is available in the system) instead of the +deprecated :c:func:`!siginterrupt`. Patch by Pablo Galindo. .. @@ -715,7 +715,7 @@ Fix refleak in _Py_fopen_obj() when PySys_Audit() fails .. section: Core and Builtins Add a state to the :mod:`!nis` module (:pep:`3121`) and apply the multiphase -initialization. Patch by Dong-hee Na. +initialization. Patch by Donghee Na. .. @@ -936,7 +936,7 @@ class. Patch by Pablo Galindo. .. section: Core and Builtins :c:func:`Py_TYPE()` is changed to the inline static function. Patch by -Dong-hee Na. +Donghee Na. .. @@ -2176,7 +2176,7 @@ None. .. nonce: YoYoYo .. section: Library -Add a new :data:`os.RWF_APPEND` flag for :func:`os.pwritev`. +Add a new :const:`os.RWF_APPEND` flag for :func:`os.pwritev`. .. @@ -2304,7 +2304,7 @@ Restored the deprecated :mod:`xml.etree.cElementTree` module. .. nonce: ZCk0_c .. section: Library -:data:`~mmap.MAP_POPULATE` constant has now been added to the list of +:const:`~mmap.MAP_POPULATE` constant has now been added to the list of exported :mod:`mmap` module flags. .. @@ -2596,7 +2596,7 @@ remove multiple items from a list". .. section: Documentation Fix RemovedInSphinx40Warning when building the documentation. Patch by -Dong-hee Na. +Donghee Na. .. @@ -2862,7 +2862,7 @@ Make test_gdb properly run on HP-UX. Patch by Michael Osipov. .. section: Build Update :c:macro:`Py_UNREACHABLE` to use __builtin_unreachable() if only the -compiler is able to use it. Patch by Dong-hee Na. +compiler is able to use it. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.10.0a2.rst b/Misc/NEWS.d/3.10.0a2.rst index 061a82e90afd6b..78f4377656b0cc 100644 --- a/Misc/NEWS.d/3.10.0a2.rst +++ b/Misc/NEWS.d/3.10.0a2.rst @@ -185,7 +185,7 @@ Removed special methods ``__int__``, ``__float__``, ``__floordiv__``, Micro optimization when compute :c:member:`~PySequenceMethods.sq_item` and :c:member:`~PyMappingMethods.mp_subscript` of :class:`range`. Patch by -Dong-hee Na. +Donghee Na. .. @@ -205,7 +205,7 @@ error message using the current locale's encoding. .. nonce: iLoMVF .. section: Core and Builtins -Micro optimization for range.index if step is 1. Patch by Dong-hee Na. +Micro optimization for range.index if step is 1. Patch by Donghee Na. .. @@ -604,7 +604,7 @@ changes the working directory. PR by Anthony Sottile. .. nonce: 9wXTtY .. section: Library -The :mod:`shelve` module now uses :data:`pickle.DEFAULT_PROTOCOL` by default +The :mod:`shelve` module now uses :const:`pickle.DEFAULT_PROTOCOL` by default instead of :mod:`pickle` protocol ``3``. .. @@ -847,8 +847,8 @@ Victor Stinner. .. section: C API Fix potential crash in deallocating method objects when dynamically -allocated `PyMethodDef`'s lifetime is managed through the ``self`` argument -of a `PyCFunction`. +allocated :c:type:`PyMethodDef`'s lifetime is managed through the ``self`` argument +of a :c:type:`PyCFunction`. .. diff --git a/Misc/NEWS.d/3.10.0a3.rst b/Misc/NEWS.d/3.10.0a3.rst index f24b6d43e5783f..7112819c1b4118 100644 --- a/Misc/NEWS.d/3.10.0a3.rst +++ b/Misc/NEWS.d/3.10.0a3.rst @@ -153,7 +153,7 @@ Allow an unparenthesized walrus in subscript indexes. .. section: Core and Builtins Make sure that the compiler front-end produces a well-formed control flow -graph. Be be more aggressive in the compiler back-end, as it is now safe to +graph. Be more aggressive in the compiler back-end, as it is now safe to do so. .. @@ -394,7 +394,7 @@ Removed the ``formatter`` module, which was deprecated in Python 3.4. It is somewhat obsolete, little used, and not tested. It was originally scheduled to be removed in Python 3.6, but such removals were delayed until after Python 2.7 EOL. Existing users should copy whatever classes they use into -their code. Patch by Dong-hee Na and and Terry J. Reedy. +their code. Patch by Donghee Na and and Terry J. Reedy. .. @@ -1466,7 +1466,7 @@ success. Patch by Victor Stinner. .. nonce: S3FWTP .. section: C API -The :c:data:`METH_FASTCALL` calling convention is added to the limited API. +The :c:macro:`METH_FASTCALL` calling convention is added to the limited API. The functions :c:func:`PyModule_AddType`, :c:func:`PyType_FromModuleAndSpec`, :c:func:`PyType_GetModule` and :c:func:`PyType_GetModuleState` are added to the limited API on Windows. diff --git a/Misc/NEWS.d/3.10.0a4.rst b/Misc/NEWS.d/3.10.0a4.rst index 95f9319668db45..414823f162d85c 100644 --- a/Misc/NEWS.d/3.10.0a4.rst +++ b/Misc/NEWS.d/3.10.0a4.rst @@ -105,7 +105,7 @@ blocks .. section: Core and Builtins Make the :mod:`atexit` module state per-interpreter. It is now safe have -more than one :mod:`atexit` module instance. Patch by Dong-hee Na and Victor +more than one :mod:`atexit` module instance. Patch by Donghee Na and Victor Stinner. .. @@ -768,7 +768,7 @@ results. Patch by Ammar Askar. .. section: Tests Update test_nntplib to use official group name of news.aioe.org for testing. -Patch by Dong-hee Na. +Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.10.0a5.rst b/Misc/NEWS.d/3.10.0a5.rst index 497e3849171831..dc95e8ce072fd9 100644 --- a/Misc/NEWS.d/3.10.0a5.rst +++ b/Misc/NEWS.d/3.10.0a5.rst @@ -667,4 +667,4 @@ exception (if an exception is set). Patch by Victor Stinner. .. section: C API Fixed a compiler warning in :c:func:`Py_UNICODE_ISSPACE()` on platforms with -signed ``wchar_t``. +signed :c:type:`wchar_t`. diff --git a/Misc/NEWS.d/3.10.0a6.rst b/Misc/NEWS.d/3.10.0a6.rst index 803df6f51ce628..c379b968c9885b 100644 --- a/Misc/NEWS.d/3.10.0a6.rst +++ b/Misc/NEWS.d/3.10.0a6.rst @@ -294,8 +294,8 @@ actual dictionary. This created problems for introspection tools. .. nonce: SwcSuU .. section: Library -Added :data:`~os.O_EVTONLY`, :data:`~os.O_FSYNC`, :data:`~os.O_SYMLINK` and -:data:`~os.O_NOFOLLOW_ANY` for macOS. Patch by Dong-hee Na. +Added :const:`~os.O_EVTONLY`, :const:`~os.O_FSYNC`, :const:`~os.O_SYMLINK` and +:const:`~os.O_NOFOLLOW_ANY` for macOS. Patch by Donghee Na. .. @@ -304,7 +304,7 @@ Added :data:`~os.O_EVTONLY`, :data:`~os.O_FSYNC`, :data:`~os.O_SYMLINK` and .. nonce: a7Dote .. section: Library -Adds :data:`resource.RLIMIT_KQUEUES` constant from FreeBSD to the +Adds :const:`resource.RLIMIT_KQUEUES` constant from FreeBSD to the :mod:`resource` module. .. diff --git a/Misc/NEWS.d/3.10.0a7.rst b/Misc/NEWS.d/3.10.0a7.rst index 286d0a8a7e9190..3a1694f444616a 100644 --- a/Misc/NEWS.d/3.10.0a7.rst +++ b/Misc/NEWS.d/3.10.0a7.rst @@ -113,7 +113,7 @@ in f-strings. Patch by Pablo Galindo. .. section: Core and Builtins Speed up calls to ``map()`` by using the :pep:`590` ``vectorcall`` calling -convention. Patch by Dong-hee Na. +convention. Patch by Donghee Na. .. @@ -215,8 +215,8 @@ a non-Python signal handler. .. nonce: VouZjn .. section: Core and Builtins -Add ``__match_args__`` to :c:type:`structsequence` based classes. Patch by -Pablo Galindo. +Add ``__match_args__`` to :ref:`struct sequence objects `. +Patch by Pablo Galindo. .. @@ -240,7 +240,7 @@ of processes that don't use sigaltstack. .. section: Core and Builtins Speed up calls to ``filter()`` by using the :pep:`590` ``vectorcall`` -calling convention. Patch by Dong-hee Na. +calling convention. Patch by Donghee Na. .. @@ -713,7 +713,7 @@ this situation. Also ensures that the :func:`tempfile.gettempdir()` and .. section: Library Expose ``X509_V_FLAG_ALLOW_PROXY_CERTS`` as -:data:`~ssl.VERIFY_ALLOW_PROXY_CERTS` to allow proxy certificate validation +:const:`~ssl.VERIFY_ALLOW_PROXY_CERTS` to allow proxy certificate validation as explained in https://www.openssl.org/docs/man1.1.1/man7/proxy-certificates.html. diff --git a/Misc/NEWS.d/3.10.0b1.rst b/Misc/NEWS.d/3.10.0b1.rst index f29fc6632db26c..e7b6b93d0b6df3 100644 --- a/Misc/NEWS.d/3.10.0b1.rst +++ b/Misc/NEWS.d/3.10.0b1.rst @@ -516,7 +516,7 @@ encoding. .. section: Library Removed an unnecessary list comprehension before looping from -:func:`urllib.parse.parse_qsl`. Patch by Christoph Zwerschke and Dong-hee +:func:`urllib.parse.parse_qsl`. Patch by Christoph Zwerschke and Donghee Na. .. @@ -871,7 +871,7 @@ assert_called_once_with) will unconditionally pass. .. nonce: -1XPDH .. section: Library -Add :data:`ssl.OP_IGNORE_UNEXPECTED_EOF` constants (OpenSSL 3.0.0) +Add :const:`ssl.OP_IGNORE_UNEXPECTED_EOF` constants (OpenSSL 3.0.0) .. @@ -1375,8 +1375,8 @@ Add "Annotations Best Practices" document as a new HOWTO. .. nonce: K5aSl1 .. section: Documentation -Document the new :const:`Py_TPFLAGS_MAPPING` and -:const:`Py_TPFLAGS_SEQUENCE` type flags. +Document the new :c:macro:`Py_TPFLAGS_MAPPING` and +:c:macro:`Py_TPFLAGS_SEQUENCE` type flags. .. @@ -1711,7 +1711,7 @@ IDLE's shell now shows prompts in a separate side-bar. .. nonce: wvWt23 .. section: C API -Add a new :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow +Add a new :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow creating type instances. Patch by Victor Stinner. .. @@ -1759,7 +1759,7 @@ module. .. nonce: Co3YhZ .. section: C API -Introduce :const:`Py_TPFLAGS_IMMUTABLETYPE` flag for immutable type objects, +Introduce :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag for immutable type objects, and modify :c:func:`PyType_Ready` to set it for static types. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/3.11.0a1.rst b/Misc/NEWS.d/3.11.0a1.rst index 2f40252344f36a..7c991e7667b01a 100644 --- a/Misc/NEWS.d/3.11.0a1.rst +++ b/Misc/NEWS.d/3.11.0a1.rst @@ -292,7 +292,7 @@ Fixed pickling of range iterators that iterated for over ``2**32`` times. .. section: Core and Builtins A :exc:`SyntaxError` is now raised when trying to delete :const:`__debug__`. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -415,7 +415,7 @@ type :class:`float` or :class:`complex`. .. section: Core and Builtins A debug variable :envvar:`PYTHONDUMPREFSFILE` is added for creating a dump -file which is generated by :option:`--with-trace-refs`. Patch by Dong-hee +file which is generated by :option:`--with-trace-refs`. Patch by Donghee Na. .. @@ -670,7 +670,7 @@ Parameter substitution of the union type with wrong types now raises .. section: Core and Builtins Update ``property_descr_set`` to use vectorcall if possible. Patch by -Dong-hee Na. +Donghee Na. .. @@ -732,7 +732,7 @@ Collapse union of equal types. E.g. the result of ``int | int`` is now On Windows, :func:`os.urandom`: uses BCryptGenRandom API instead of CryptGenRandom API which is deprecated from Microsoft Windows API. Patch by -Dong-hee Na. +Donghee Na. .. @@ -888,7 +888,7 @@ zlib.decompress on input data that expands that large. .. nonce: YHuV_s .. section: Core and Builtins -Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit +Heap types with the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit the :pep:`590` vectorcall protocol. Previously, this was only possible for :ref:`static types `. Patch by Erlend E. Aasland. @@ -1468,8 +1468,8 @@ an installed expat library <= 2.2.0. On Unix, if the ``sem_clockwait()`` function is available in the C library (glibc 2.30 and newer), the :meth:`threading.Lock.acquire` method now uses -the monotonic clock (:data:`time.CLOCK_MONOTONIC`) for the timeout, rather -than using the system clock (:data:`time.CLOCK_REALTIME`), to not be +the monotonic clock (:const:`time.CLOCK_MONOTONIC`) for the timeout, rather +than using the system clock (:const:`time.CLOCK_REALTIME`), to not be affected by system clock changes. Patch by Victor Stinner. .. @@ -1657,7 +1657,7 @@ Patch by Hugo van Kemenade. .. section: Library Pure ASCII strings are now normalized in constant time by -:func:`unicodedata.normalize`. Patch by Dong-hee Na. +:func:`unicodedata.normalize`. Patch by Donghee Na. .. @@ -1968,7 +1968,7 @@ A new function ``operator.call`` has been added, such that :class:`!webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. It is untested and undocumented and also not used by :mod:`webbrowser` itself. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -2087,8 +2087,8 @@ Upgrade bundled pip to 21.2.3 and setuptools to 57.4.0 .. section: Library Fix the :func:`os.set_inheritable` function on FreeBSD 14 for file -descriptor opened with the :data:`~os.O_PATH` flag: ignore the -:data:`~errno.EBADF` error on ``ioctl()``, fallback on the ``fcntl()`` +descriptor opened with the :const:`~os.O_PATH` flag: ignore the +:const:`~errno.EBADF` error on ``ioctl()``, fallback on the ``fcntl()`` implementation. Patch by Victor Stinner. .. @@ -2465,7 +2465,7 @@ generator .. section: Library Make the implementation consistency of :func:`~operator.indexOf` between C -and Python versions. Patch by Dong-hee Na. +and Python versions. Patch by Donghee Na. .. @@ -2575,7 +2575,7 @@ E. Aasland. .. nonce: bamAGF .. section: Library -Set the proper :const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` +Set the proper :c:macro:`Py_TPFLAGS_MAPPING` and :c:macro:`Py_TPFLAGS_SEQUENCE` flags for subclasses created before a parent has been registered as a :class:`collections.abc.Mapping` or :class:`collections.abc.Sequence`. @@ -2693,7 +2693,7 @@ libgcc_s.so file (ex: EMFILE error). Patch by Victor Stinner. .. section: Library The _thread.RLock type now fully implement the GC protocol: add a traverse -function and the :const:`Py_TPFLAGS_HAVE_GC` flag. Patch by Victor Stinner. +function and the :c:macro:`Py_TPFLAGS_HAVE_GC` flag. Patch by Victor Stinner. .. @@ -2752,7 +2752,7 @@ of reserved filenames, including those with trailing spaces or colons. .. section: Library Fix :meth:`~email.message.MIMEPart.as_string` to pass unixfrom properly. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -2809,7 +2809,7 @@ behaves differently than the similar implementation in :mod:`sysconfig`. .. section: Library :class:`smtpd.MailmanProxy` is now removed as it is unusable without an -external module, ``mailman``. Patch by Dong-hee Na. +external module, ``mailman``. Patch by Donghee Na. .. @@ -2916,7 +2916,7 @@ Support PEP 515 for Fraction's initialization from string. .. nonce: qFBYpp .. section: Library -Remove deprecated functions in the :mod:`gettext`. Patch by Dong-hee Na. +Remove deprecated functions in the :mod:`gettext`. Patch by Donghee Na. .. @@ -4471,7 +4471,7 @@ and modify the frozen modules. .. section: Build Add support for building with clang thin lto via --with-lto=thin/full. Patch -by Dong-hee Na and Brett Holman. +by Donghee Na and Brett Holman. .. @@ -4798,7 +4798,7 @@ Allow the Argument Clinic tool to handle ``__complex__`` special methods. Removed the 'test2to3' demo project that demonstrated using lib2to3 to support Python 2.x and Python 3.x from a single source in a distutils -package. Patch by Dong-hee Na +package. Patch by Donghee Na .. @@ -5014,7 +5014,7 @@ must now be used to set an object type and size. Patch by Victor Stinner. .. section: C API The :c:func:`PyType_Ready` function now raises an error if a type is defined -with the :const:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function +with the :c:macro:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function (:c:member:`PyTypeObject.tp_traverse`). Patch by Victor Stinner. .. @@ -5036,15 +5036,15 @@ Limited API. Deprecate the following functions to configure the Python initialization: -* :c:func:`PySys_AddWarnOptionUnicode` -* :c:func:`PySys_AddWarnOption` -* :c:func:`PySys_AddXOption` -* :c:func:`PySys_HasWarnOptions` -* :c:func:`Py_SetPath` -* :c:func:`Py_SetProgramName` -* :c:func:`Py_SetPythonHome` -* :c:func:`Py_SetStandardStreamEncoding` -* :c:func:`_Py_SetProgramFullPath` +* :c:func:`!PySys_AddWarnOptionUnicode` +* :c:func:`!PySys_AddWarnOption` +* :c:func:`!PySys_AddXOption` +* :c:func:`!PySys_HasWarnOptions` +* :c:func:`!Py_SetPath` +* :c:func:`!Py_SetProgramName` +* :c:func:`!Py_SetPythonHome` +* :c:func:`!Py_SetStandardStreamEncoding` +* :c:func:`!_Py_SetProgramFullPath` Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization Configuration ` instead (:pep:`587`). diff --git a/Misc/NEWS.d/3.11.0a2.rst b/Misc/NEWS.d/3.11.0a2.rst index cf26137dff19ef..503e489b658e4d 100644 --- a/Misc/NEWS.d/3.11.0a2.rst +++ b/Misc/NEWS.d/3.11.0a2.rst @@ -142,7 +142,7 @@ Add SipHash13 for string hash algorithm and use it by default. .. nonce: CTUT8s .. section: Core and Builtins -Fix reference leak from descr_check. Patch by Dong-hee Na. +Fix reference leak from descr_check. Patch by Donghee Na. .. @@ -263,7 +263,7 @@ Improve the generated bytecode for class and mapping patterns. .. section: Core and Builtins Speed up calls to ``enumerate()`` by using the :pep:`590` ``vectorcall`` -calling convention. Patch by Dong-hee Na. +calling convention. Patch by Donghee Na. .. @@ -396,7 +396,7 @@ Patch by Inada Naoki. .. section: Library Update :class:`~typing.ForwardRef` to support ``|`` operator. Patch by -Dong-hee Na. +Donghee Na. .. @@ -486,7 +486,7 @@ Patch by Joongi Kim. .. section: Library Empty escapechar/quotechar is not allowed when initializing -:class:`csv.Dialect`. Patch by Vajrasky Kok and Dong-hee Na. +:class:`csv.Dialect`. Patch by Vajrasky Kok and Donghee Na. .. @@ -569,7 +569,7 @@ formatting options. .. section: Library Improve error message of :class:`csv.Dialect` when initializing. Patch by -Vajrasky Kok and Dong-hee Na. +Vajrasky Kok and Donghee Na. .. diff --git a/Misc/NEWS.d/3.11.0a3.rst b/Misc/NEWS.d/3.11.0a3.rst index 7fdc191c244849..a96a59115797ee 100644 --- a/Misc/NEWS.d/3.11.0a3.rst +++ b/Misc/NEWS.d/3.11.0a3.rst @@ -615,7 +615,7 @@ Launch GNOME web browsers via gio tool instead of obsolete gvfs-open .. section: Library On Windows, :func:`time.sleep` now uses a waitable timer which supports -high-resolution timers. Patch by Dong-hee Na and Eryk Sun. +high-resolution timers. Patch by Donghee Na and Eryk Sun. .. diff --git a/Misc/NEWS.d/3.11.0a4.rst b/Misc/NEWS.d/3.11.0a4.rst index bcb6e8b7bdde31..3dd335929d655f 100644 --- a/Misc/NEWS.d/3.11.0a4.rst +++ b/Misc/NEWS.d/3.11.0a4.rst @@ -839,7 +839,7 @@ patch by Kumar Aditya. .. nonce: jeiPiX .. section: Library -Added :data:`signal.SIGSTKFLT` on platforms where this signal is defined. +Added :const:`signal.SIGSTKFLT` on platforms where this signal is defined. .. diff --git a/Misc/NEWS.d/3.11.0a5.rst b/Misc/NEWS.d/3.11.0a5.rst index c28078da8d8339..08d94e82ed8ccf 100644 --- a/Misc/NEWS.d/3.11.0a5.rst +++ b/Misc/NEWS.d/3.11.0a5.rst @@ -127,7 +127,7 @@ Aditya. .. section: Core and Builtins Speed up calls to :meth:`weakref.ref.__call__` by using the :pep:`590` -``vectorcall`` calling convention. Patch by Dong-hee Na. +``vectorcall`` calling convention. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.11.0a6.rst b/Misc/NEWS.d/3.11.0a6.rst index 8621edcfb04bb3..52055b3fafd485 100644 --- a/Misc/NEWS.d/3.11.0a6.rst +++ b/Misc/NEWS.d/3.11.0a6.rst @@ -352,7 +352,7 @@ rather than ``JUMP_FORWARD`` with an argument of ``(2**32)+offset``. .. nonce: 3Z_qxd .. section: Core and Builtins -Correct the docstring for the :meth:`__bool__` method. Patch by Jelle +Correct the docstring for the :meth:`~object.__bool__` method. Patch by Jelle Zijlstra. .. @@ -382,7 +382,7 @@ involving lots of brackets. Patch by Pablo Galindo. .. section: Core and Builtins :mod:`ctypes` now allocates memory on the stack instead of on the heap to -pass arguments while calling a Python callback function. Patch by Dong-hee +pass arguments while calling a Python callback function. Patch by Donghee Na. .. @@ -441,7 +441,7 @@ Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. .. section: Core and Builtins Use :c:func:`PyObject_Vectorcall` while calling ctypes callback function. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -514,7 +514,7 @@ For performance, use the optimized string-searching implementations from .. section: Library :class:`~http.server.SimpleHTTPRequestHandler` now uses HTML5 grammar. Patch -by Dong-hee Na. +by Donghee Na. .. diff --git a/Misc/NEWS.d/3.11.0a7.rst b/Misc/NEWS.d/3.11.0a7.rst index d3e59a2195669f..6e41f9cbd933b5 100644 --- a/Misc/NEWS.d/3.11.0a7.rst +++ b/Misc/NEWS.d/3.11.0a7.rst @@ -89,7 +89,7 @@ problem. Define :c:macro:`PY_CALL_TRAMPOLINE` to enable call trampolines. .. section: Core and Builtins Some Windows system error codes(>= 10000) are now mapped into the correct -errno and may now raise a subclass of :exc:`OSError`. Patch by Dong-hee Na. +errno and may now raise a subclass of :exc:`OSError`. Patch by Donghee Na. .. @@ -275,7 +275,7 @@ initializing to ``list_extend``. Patch by Jeremiah Pascual. .. nonce: cnaIK3 .. section: Core and Builtins -Speed up throwing exception in generator with :const:`METH_FASTCALL` calling +Speed up throwing exception in generator with :c:macro:`METH_FASTCALL` calling convention. Patch by Kumar Aditya. .. @@ -1599,7 +1599,7 @@ Call the public :func:`sys.get_asyncgen_hooks` and .. section: C API Remove private functions ``_PySys_GetObjectId()`` and -``_PySys_SetObjectId()``. Patch by Dong-hee Na. +``_PySys_SetObjectId()``. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.11.0b1.rst b/Misc/NEWS.d/3.11.0b1.rst index 1338819375bc89..a4cdda2cafdb43 100644 --- a/Misc/NEWS.d/3.11.0b1.rst +++ b/Misc/NEWS.d/3.11.0b1.rst @@ -185,7 +185,7 @@ functions leave the current exception unchanged. Patch by Victor Stinner. .. section: Core and Builtins Fix a minor memory leak at exit: release the memory of the -:class:`generic_alias_iterator` type. Patch by Dong-hee Na. +:class:`generic_alias_iterator` type. Patch by Donghee Na. .. @@ -817,8 +817,8 @@ it is ever needed and document the existing mechanism for ``posix_spawn()``. .. nonce: HFtERN .. section: Library -Fix :data:`signal.NSIG` value on FreeBSD to accept signal numbers greater -than 32, like :data:`signal.SIGRTMIN` and :data:`signal.SIGRTMAX`. Patch by +Fix :const:`signal.NSIG` value on FreeBSD to accept signal numbers greater +than 32, like :const:`signal.SIGRTMIN` and :const:`signal.SIGRTMAX`. Patch by Victor Stinner. .. @@ -1799,7 +1799,7 @@ The documentation now lists which members of C structs are part of the .. nonce: FIVe9I .. section: Documentation -All docstrings in code snippets are now wrapped into :func:`PyDoc_STR` to +All docstrings in code snippets are now wrapped into :c:macro:`PyDoc_STR` to follow the guideline of `PEP 7's Documentation Strings paragraph `_. Patch by Oleg Iarygin. @@ -2028,8 +2028,8 @@ https://gitlab.com/warsaw/pynche .. nonce: 3mQ54t .. section: C API -Deprecate the C functions: :c:func:`PySys_SetArgv`, -:c:func:`PySys_SetArgvEx`, :c:func:`PySys_SetPath`. Patch by Victor Stinner. +Deprecate the C functions: :c:func:`!PySys_SetArgv`, +:c:func:`!PySys_SetArgvEx`, :c:func:`!PySys_SetPath`. Patch by Victor Stinner. .. @@ -2068,9 +2068,9 @@ casts when the Python C API is used in C++. Patch by Victor Stinner. .. nonce: Cx-95G .. section: C API -Mark functions as deprecated by :pep:`623`: :c:func:`PyUnicode_AS_DATA`, -:c:func:`PyUnicode_AS_UNICODE`, :c:func:`PyUnicode_GET_DATA_SIZE`, -:c:func:`PyUnicode_GET_SIZE`. Patch by Victor Stinner. +Mark functions as deprecated by :pep:`623`: :c:func:`!PyUnicode_AS_DATA`, +:c:func:`!PyUnicode_AS_UNICODE`, :c:func:`!PyUnicode_GET_DATA_SIZE`, +:c:func:`!PyUnicode_GET_SIZE`. Patch by Victor Stinner. .. diff --git a/Misc/NEWS.d/3.12.0a1.rst b/Misc/NEWS.d/3.12.0a1.rst index d706343adf583c..633738de92bef7 100644 --- a/Misc/NEWS.d/3.12.0a1.rst +++ b/Misc/NEWS.d/3.12.0a1.rst @@ -82,7 +82,7 @@ the test failed). .. nonce: eOBh8M .. section: Core and Builtins -Suppress ImportError for invalid query for help() command. Patch by Dong-hee +Suppress ImportError for invalid query for help() command. Patch by Donghee Na. .. @@ -164,7 +164,7 @@ to calculate those doing pointer arithmetic. .. section: Core and Builtins :func:`os.sched_yield` now release the GIL while calling sched_yield(2). -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -203,7 +203,7 @@ the interpreter. .. nonce: LYAWlE .. section: Core and Builtins -Bugfix: :func:`PyFunction_GetAnnotations` should return a borrowed +Bugfix: :c:func:`PyFunction_GetAnnotations` should return a borrowed reference. It was returning a new reference. .. @@ -465,7 +465,7 @@ Remove dead code from ``CALL_FUNCTION_EX`` opcode. .. nonce: VE8-zf .. section: Core and Builtins -:class:`memoryview` now supports half-floats. Patch by Dong-hee Na and +:class:`memoryview` now supports half-floats. Patch by Donghee Na and Antoine Pitrou. .. @@ -736,7 +736,7 @@ new types. .. nonce: 6eoc8k .. section: Core and Builtins -On WASI :data:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`. +On WASI :const:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`. The :mod:`errno` modules exposes the new error number. ``getpath.py`` now ignores :exc:`PermissionError` when it cannot open landmark files ``pybuilddir.txt`` and ``pyenv.cfg``. @@ -857,7 +857,7 @@ code objects could be "deduplicated" during compilation. .. section: Core and Builtins Reduce allocation size of :class:`list` from :meth:`str.split` and -:meth:`str.rsplit`. Patch by Dong-hee Na and Inada Naoki. +:meth:`str.rsplit`. Patch by Donghee Na and Inada Naoki. .. @@ -2649,7 +2649,7 @@ calling any callbacks. Patch by Kumar Aditya. .. nonce: i807-g .. section: Library -Fail gracefully if :data:`~errno.EPERM` or :data:`~errno.ENOSYS` is raised +Fail gracefully if :const:`~errno.EPERM` or :const:`~errno.ENOSYS` is raised when loading :mod:`!crypt` methods. This may happen when trying to load ``MD5`` on a Linux kernel with :abbr:`FIPS (Federal Information Processing Standard)` enabled. @@ -2698,8 +2698,8 @@ Upgrade bundled pip to 22.2. .. nonce: VT34A5 .. section: Library -Fix check for existence of :data:`os.EFD_CLOEXEC`, :data:`os.EFD_NONBLOCK` -and :data:`os.EFD_SEMAPHORE` flags on older kernel versions where these +Fix check for existence of :const:`os.EFD_CLOEXEC`, :const:`os.EFD_NONBLOCK` +and :const:`os.EFD_SEMAPHORE` flags on older kernel versions where these flags are not present. Patch by Kumar Aditya. .. @@ -2752,7 +2752,7 @@ by Shin-myoung-serp. .. section: Library Add deprecation warning for enum ``member.member`` access (e.g. -``Color.RED.BLUE``). +``Color.RED.BLUE``). Remove ``EnumMeta.__getattr__``. .. @@ -3553,7 +3553,7 @@ Make :class:`multiprocessing.Pool` raise an exception if .. nonce: HY0Uzj .. section: Library -Add :data:`os.PIDFD_NONBLOCK` flag to open a file descriptor for a process +Add :const:`os.PIDFD_NONBLOCK` flag to open a file descriptor for a process with :func:`os.pidfd_open` in non-blocking mode. Patch by Kumar Aditya. .. @@ -3742,7 +3742,7 @@ Fix :func:`ast.unparse` when ``ImportFrom.level`` is None Now :func:`~dis.dis` and :func:`~dis.get_instructions` handle operand values for instructions prefixed by ``EXTENDED_ARG_QUICK``. Patch by Sam Gross and -Dong-hee Na. +Donghee Na. .. @@ -4171,7 +4171,7 @@ Add an index_pages parameter to support using non-default index page names. .. nonce: qtT3CE .. section: Library -Drop support for :class:`bytes` on :attr:`sys.path`. +Drop support for :class:`bytes` on :data:`sys.path`. .. @@ -5004,7 +5004,7 @@ Patch by Illia Volochii and Adam Turner. .. section: Build Fix the build process of clang compiler for :program:`_bootstrap_python` if -LTO optimization is applied. Patch by Matthias Görgens and Dong-hee Na. +LTO optimization is applied. Patch by Matthias Görgens and Donghee Na. .. @@ -5024,7 +5024,7 @@ LTO optimization is applied. Patch by Matthias Görgens and Dong-hee Na. .. section: Build CPython now uses the ThinLTO option as the default policy if the Clang -compiler accepts the flag. Patch by Dong-hee Na. +compiler accepts the flag. Patch by Donghee Na. .. @@ -5308,7 +5308,7 @@ parameter. Patch by Kumar Aditya. .. section: Build Python now always use the ``%zu`` and ``%zd`` printf formats to format a -``size_t`` or ``Py_ssize_t`` number. Building Python 3.12 requires a C11 +:c:type:`size_t` or ``Py_ssize_t`` number. Building Python 3.12 requires a C11 compiler, so these printf formats are now always supported. Patch by Victor Stinner. @@ -5350,7 +5350,7 @@ in a virtual environment. .. nonce: FbHZuS .. section: Windows -Fix :file:`py.exe` launcher handling of ``-V:/`` option when +Fix :file:`py.exe` launcher handling of :samp:`-V:{}/` option when default preferences have been set in environment variables or configuration files. @@ -5856,8 +5856,8 @@ Configuration for the :ref:`integer string conversion length limitation Extensions classes that set ``tp_dictoffset`` and ``tp_weaklistoffset`` lose the support for multiple inheritance, but are now safe. Extension classes -should use :const:`Py_TPFLAGS_MANAGED_DICT` and -:const:`Py_TPFLAGS_MANAGED_WEAKREF` instead. +should use :c:macro:`Py_TPFLAGS_MANAGED_DICT` and +:c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead. .. @@ -5898,7 +5898,7 @@ Support C extensions using managed dictionaries by setting the .. nonce: QoDHEu .. section: C API -API for implementing vectorcall (:c:data:`Py_TPFLAGS_HAVE_VECTORCALL`, +API for implementing vectorcall (:c:macro:`Py_TPFLAGS_HAVE_VECTORCALL`, :c:func:`PyVectorcall_NARGS` and :c:func:`PyVectorcall_Call`) was added to the limited API and stable ABI. @@ -5920,12 +5920,12 @@ Philip Georgi. .. nonce: -DdGEy .. section: C API -The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class +The :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class when the class's :py:meth:`~object.__call__` method is reassigned. This makes vectorcall safe to use with mutable types (i.e. heap types without the :const:`immutable ` flag). Mutable types that do not override :c:member:`~PyTypeObject.tp_call` now inherit the -:const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. +:c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag. .. @@ -5934,7 +5934,7 @@ not override :c:member:`~PyTypeObject.tp_call` now inherit the .. nonce: aiRSgr .. section: C API -Creating :c:data:`immutable types ` with mutable +Creating :c:macro:`immutable types ` with mutable bases is deprecated and is planned to be disabled in Python 3.14. .. diff --git a/Misc/NEWS.d/3.12.0a2.rst b/Misc/NEWS.d/3.12.0a2.rst index d871384903e7cd..1a04ed473f329d 100644 --- a/Misc/NEWS.d/3.12.0a2.rst +++ b/Misc/NEWS.d/3.12.0a2.rst @@ -8,7 +8,7 @@ The IDNA codec decoder used on DNS hostnames by :mod:`socket` or :mod:`asyncio` related name resolution functions no longer involves a quadratic algorithm. This prevents a potential CPU denial of service if an out-of-spec excessive length hostname involving bidirectional characters -were decoded. Some protocols such as :mod:`urllib` http ``3xx`` redirects +were decoded. Some protocols such as :mod:`urllib` http :samp:`3{xx}` redirects potentially allow for an attacker to supply such a name. Individual labels within an IDNA encoded DNS name will now raise an error @@ -111,7 +111,7 @@ back to alternative names ("python", "python."). .. section: Core and Builtins Update :mod:`faulthandler` to emit an error message with the proper -unexpected signal number. Patch by Dong-hee Na. +unexpected signal number. Patch by Donghee Na. .. @@ -279,7 +279,7 @@ Fix source locations of :keyword:`match` sub-patterns. Added the methods :c:func:`PyObject_Vectorcall` and :c:func:`PyObject_VectorcallMethod` to the :ref:`Limited API ` along -with the auxiliary macro constant :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`. +with the auxiliary macro constant :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET`. The availability of these functions enables more efficient :PEP:`590` vector calls from binary extension modules that avoid argument boxing/unboxing @@ -397,7 +397,7 @@ longobject.c to speed up some operations. .. nonce: nSGEkG .. section: Core and Builtins -Expose :data:`~socket.ETH_P_ALL` and some of the :ref:`ETHERTYPE_* constants +Expose :const:`~socket.ETH_P_ALL` and some of the :ref:`ETHERTYPE_* constants ` in :mod:`socket`. Patch by Noam Cohen. .. diff --git a/Misc/NEWS.d/3.12.0a3.rst b/Misc/NEWS.d/3.12.0a3.rst index 3d1e43350d136e..ce128fd5f80c77 100644 --- a/Misc/NEWS.d/3.12.0a3.rst +++ b/Misc/NEWS.d/3.12.0a3.rst @@ -9,7 +9,7 @@ within a garbage request to be printed to the stderr server log. This is done by changing the :mod:`http.server` :class:`BaseHTTPRequestHandler` ``.log_message`` method to replace control -characters with a ``\xHH`` hex escape before printing. +characters with a :samp:`\\x{HH}` hex escape before printing. .. @@ -153,7 +153,7 @@ to specialize attribute accesses on types that haven't had .. section: Core and Builtins Allow some features of :mod:`syslog` to the main interpreter only. Patch by -Dong-hee Na. +Donghee Na. .. @@ -505,7 +505,7 @@ return True from this method; now they correctly return False. .. nonce: ZoOY5G .. section: Library -Add an :data:`~ssl.OP_ENABLE_KTLS` option for enabling the use of the kernel +Add an :const:`~ssl.OP_ENABLE_KTLS` option for enabling the use of the kernel TLS (kTLS). Patch by Illia Volochii. .. diff --git a/Misc/NEWS.d/3.12.0a4.rst b/Misc/NEWS.d/3.12.0a4.rst index dd26d4d964d6b7..75246f3f13503e 100644 --- a/Misc/NEWS.d/3.12.0a4.rst +++ b/Misc/NEWS.d/3.12.0a4.rst @@ -23,10 +23,10 @@ Remove :opcode:`UNARY_POSITIVE`, :opcode:`ASYNC_GEN_WRAP` and .. nonce: D7H6j4 .. section: Core and Builtins -Add new :opcode:`CALL_INSTRINSIC_1` instruction. Remove +Add new :opcode:`CALL_INTRINSIC_1` instruction. Remove :opcode:`IMPORT_STAR`, :opcode:`PRINT_EXPR` and :opcode:`STOPITERATION_ERROR`, replacing them with the -:opcode:`CALL_INSTRINSIC_1` instruction. +:opcode:`CALL_INTRINSIC_1` instruction. .. @@ -317,7 +317,7 @@ Improve performance of ``list.pop`` for small lists. .. nonce: yP4Na0 .. section: Core and Builtins -Add :data:`ssl.OP_LEGACY_SERVER_CONNECT` +Add :const:`ssl.OP_LEGACY_SERVER_CONNECT` .. @@ -356,7 +356,7 @@ arrays. .. nonce: mHRdQn .. section: Library -Add :data:`socket.IP_PKTINFO` constant. +Add :const:`socket.IP_PKTINFO` constant. .. @@ -676,7 +676,7 @@ parameter names in the C implementation. Patch by Alex Waygood. .. section: Library Update :exc:`~urllib.error.HTTPError` to be initialized properly, even if -the ``fp`` is ``None``. Patch by Dong-hee Na. +the ``fp`` is ``None``. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.12.0a5.rst b/Misc/NEWS.d/3.12.0a5.rst index f6f8de46cf70d9..8cf90b0e9cde46 100644 --- a/Misc/NEWS.d/3.12.0a5.rst +++ b/Misc/NEWS.d/3.12.0a5.rst @@ -38,7 +38,7 @@ would get out of sync, causing inconsistent behavior and crashes. .. section: Core and Builtins Fix wrong lineno in exception message on :keyword:`continue` or -:keyword:`break` which are not in a loop. Patch by Dong-hee Na. +:keyword:`break` which are not in a loop. Patch by Donghee Na. .. @@ -48,7 +48,7 @@ Fix wrong lineno in exception message on :keyword:`continue` or .. section: Core and Builtins Fix :func:`~unicodedata.is_normalized` to properly handle the UCD 3.2.0 -cases. Patch by Dong-hee Na. +cases. Patch by Donghee Na. .. @@ -507,7 +507,7 @@ inheritance. .. section: Build Update BOLT configration not to use depreacted usage of ``--split -functions``. Patch by Dong-hee Na. +functions``. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.12.0a6.rst b/Misc/NEWS.d/3.12.0a6.rst index f6beb5b7ec3dbc..5bd600cd8b6fc0 100644 --- a/Misc/NEWS.d/3.12.0a6.rst +++ b/Misc/NEWS.d/3.12.0a6.rst @@ -220,7 +220,7 @@ access of ``builtins.__dict__`` keys mutates the iter object. .. section: Core and Builtins Update :mod:`tracemalloc` to handle presize of object properly. Patch by -Dong-hee Na. +Donghee Na. .. @@ -303,7 +303,7 @@ Kim. .. nonce: Vxz0Mr .. section: Library -Add :data:`mmap.MAP_ALIGNED_SUPER` FreeBSD and :data:`mmap.MAP_CONCEAL` +Add :const:`mmap.MAP_ALIGNED_SUPER` FreeBSD and :const:`mmap.MAP_CONCEAL` OpenBSD constants to :mod:`mmap`. Patch by Yeojin Kim. .. diff --git a/Misc/NEWS.d/3.12.0a7.rst b/Misc/NEWS.d/3.12.0a7.rst index 8f078e50823a00..1ef81747558857 100644 --- a/Misc/NEWS.d/3.12.0a7.rst +++ b/Misc/NEWS.d/3.12.0a7.rst @@ -605,7 +605,7 @@ reported unauthenticated EOFs (i.e. without close_notify) as a clean TLS-level EOF. It now raises :exc:`~ssl.SSLEOFError`, matching the behavior in previous versions of OpenSSL. The :attr:`~ssl.SSLContext.options` attribute on :class:`~ssl.SSLContext` also no longer includes -:data:`~ssl.OP_IGNORE_UNEXPECTED_EOF` by default. This option may be set to +:const:`~ssl.OP_IGNORE_UNEXPECTED_EOF` by default. This option may be set to specify the previous OpenSSL 3.0 behavior. .. diff --git a/Misc/NEWS.d/3.12.0b1.rst b/Misc/NEWS.d/3.12.0b1.rst index 96d76f89fa9c23..0944dfd0e90ab9 100644 --- a/Misc/NEWS.d/3.12.0b1.rst +++ b/Misc/NEWS.d/3.12.0b1.rst @@ -213,7 +213,7 @@ attribute. .. section: Core and Builtins Reduce object creation while calling callback function from gc. Patch by -Dong-hee Na. +Donghee Na. .. @@ -464,7 +464,7 @@ unpickled. .. section: Core and Builtins Migrate :meth:`~ssl.SSLContext.set_ecdh_curve` method not to use deprecated -OpenSSL APIs. Patch by Dong-hee Na. +OpenSSL APIs. Patch by Donghee Na. .. @@ -842,7 +842,7 @@ filesystem case. .. section: Library Improve performance of :meth:`pathlib.Path.glob` by using -:data:`re.IGNORECASE` to implement case-insensitive matching. +:const:`re.IGNORECASE` to implement case-insensitive matching. .. @@ -1205,7 +1205,7 @@ the future, it will raise a ``KeyError``. Fixed a bug where :mod:`pdb` crashes when reading source file with different encoding by replacing :func:`io.open` with :func:`io.open_code`. The new -method would also call into the hook set by :func:`PyFile_SetOpenCodeHook`. +method would also call into the hook set by :c:func:`PyFile_SetOpenCodeHook`. .. @@ -1882,7 +1882,7 @@ both cases. .. nonce: 564i32 .. section: Library -Add :data:`~csv.QUOTE_STRINGS` and :data:`~csv.QUOTE_NOTNULL` to the suite +Add :const:`~csv.QUOTE_STRINGS` and :const:`~csv.QUOTE_NOTNULL` to the suite of :mod:`csv` module quoting styles. .. @@ -1955,7 +1955,7 @@ introduced in :pep:`692`. .. section: Documentation Clarifying documentation about the url parameter to urllib.request.urlopen -and urllib.request.Requst needing to be encoded properly. +and urllib.request.Request needing to be encoded properly. .. @@ -2073,7 +2073,7 @@ Define ``.PHONY`` / virtual make targets consistently and properly. .. nonce: -W9BJS .. section: Build -Add gcc fallback of mkfifoat/mknodat for macOS. Patch by Dong-hee Na. +Add gcc fallback of mkfifoat/mknodat for macOS. Patch by Donghee Na. .. @@ -2372,7 +2372,7 @@ Add a new C-API function to eagerly assign a version tag to a PyTypeObject: .. section: C API :c:func:`PyObject_GC_Resize` should calculate preheader size if needed. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -2382,7 +2382,7 @@ Patch by Dong-hee Na. .. section: C API Add support of more formatting options (left aligning, octals, uppercase -hexadecimals, :c:expr:`intmax_t`, :c:expr:`ptrdiff_t`, :c:expr:`wchar_t` C +hexadecimals, :c:type:`intmax_t`, :c:type:`ptrdiff_t`, :c:type:`wchar_t` C strings, variable width and precision) in :c:func:`PyUnicode_FromFormat` and :c:func:`PyUnicode_FromFormatV`. diff --git a/Misc/NEWS.d/3.13.0a1.rst b/Misc/NEWS.d/3.13.0a1.rst new file mode 100644 index 00000000000000..102bddcee5c5c2 --- /dev/null +++ b/Misc/NEWS.d/3.13.0a1.rst @@ -0,0 +1,6748 @@ +.. date: 2023-08-22-17-39-12 +.. gh-issue: 108310 +.. nonce: fVM3sg +.. release date: 2023-10-13 +.. section: Security + +Fixed an issue where instances of :class:`ssl.SSLSocket` were vulnerable to +a bypass of the TLS handshake and included protections (like certificate +verification) and treating sent unencrypted data as if it were +post-handshake TLS encrypted data. Security issue reported as +`CVE-2023-40217 +`_ by Aapo +Oksman. Patch by Gregory P. Smith. + +.. + +.. date: 2023-08-05-03-51-05 +.. gh-issue: 107774 +.. nonce: VPjaTR +.. section: Security + +PEP 669 specifies that ``sys.monitoring.register_callback`` will generate an +audit event. Pre-releases of Python 3.12 did not generate the audit event. +This is now fixed. + +.. + +.. date: 2023-06-13-20-52-24 +.. gh-issue: 102988 +.. nonce: Kei7Vf +.. section: Security + +Reverted the :mod:`email.utils` security improvement change released in +3.12beta4 that unintentionally caused :mod:`email.utils.getaddresses` to +fail to parse email addresses with a comma in the quoted name field. See +:gh:`106669`. + +.. + +.. date: 2023-05-24-09-29-08 +.. gh-issue: 99108 +.. nonce: hwS2cr +.. section: Security + +Refresh our new HACL* built-in :mod:`hashlib` code from upstream. Built-in +SHA2 should be faster and an issue with SHA3 on 32-bit platforms is fixed. + +.. + +.. date: 2023-03-07-21-46-29 +.. gh-issue: 102509 +.. nonce: 5ouaH_ +.. section: Security + +Start initializing ``ob_digit`` during creation of :c:type:`PyLongObject` +objects. Patch by Illia Volochii. + +.. + +.. date: 2023-10-12-15-03-24 +.. gh-issue: 110782 +.. nonce: EqzIzi +.. section: Core and Builtins + +Fix crash when :class:`typing.TypeVar` is constructed with a keyword +argument. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-10-12-06-32-25 +.. gh-issue: 110752 +.. nonce: FYfI0h +.. section: Core and Builtins + +Reset ``ceval.eval_breaker`` in :func:`interpreter_clear` + +.. + +.. date: 2023-10-11-16-56-54 +.. gh-issue: 110721 +.. nonce: afcSsH +.. section: Core and Builtins + +Use the :mod:`traceback` implementation for the default +:c:func:`PyErr_Display` functionality. Patch by Pablo Galindo + +.. + +.. date: 2023-10-11-13-46-14 +.. gh-issue: 110696 +.. nonce: J9kSzr +.. section: Core and Builtins + +Fix incorrect error message for invalid argument unpacking. Patch by Pablo +Galindo + +.. + +.. date: 2023-10-11-12-48-03 +.. gh-issue: 104169 +.. nonce: bPoX8u +.. section: Core and Builtins + +Split the tokenizer into two separate directories: - One part includes the +actual lexeme producing logic and lives in ``Parser/lexer``. - The second +part wraps the lexer according to the different tokenization modes we have +(string, utf-8, file, interactive, readline) and lives in +``Parser/tokenizer``. + +.. + +.. date: 2023-10-11-11-39-22 +.. gh-issue: 110688 +.. nonce: lB6Q7t +.. section: Core and Builtins + +Remove undocumented ``test_c_api`` method from :class:`set`, which was only +defined for testing purposes under ``Py_DEBUG``. Now we have proper CAPI +tests. + +.. + +.. date: 2023-10-10-00-49-35 +.. gh-issue: 104584 +.. nonce: z94TuJ +.. section: Core and Builtins + +Fix a reference leak when running with :envvar:`PYTHONUOPS` or :option:`-X +uops <-X>` enabled. + +.. + +.. date: 2023-10-08-20-08-54 +.. gh-issue: 110514 +.. nonce: Q9bdRU +.. section: Core and Builtins + +Add ``PY_THROW`` to :func:`sys.setprofile` events + +.. + +.. date: 2023-10-06-22-30-25 +.. gh-issue: 110489 +.. nonce: rI2n8A +.. section: Core and Builtins + +Optimise :func:`math.ceil` when the input is exactly a float, resulting in +about a 10% improvement. + +.. + +.. date: 2023-10-06-12-00-43 +.. gh-issue: 110455 +.. nonce: 8BjNGg +.. section: Core and Builtins + +Guard ``assert(tstate->thread_id > 0)`` with ``#ifndef HAVE_PTHREAD_STUBS``. +This allows for for pydebug builds to work under WASI which (currently) +lacks thread support. + +.. + +.. date: 2023-10-03-23-26-18 +.. gh-issue: 110309 +.. nonce: Y8nDOF +.. section: Core and Builtins + +Remove unnecessary empty constant nodes in the ast of f-string specs. + +.. + +.. date: 2023-10-03-11-43-48 +.. gh-issue: 110259 +.. nonce: ka93x5 +.. section: Core and Builtins + +Correctly identify the format spec in f-strings (with single or triple +quotes) that have multiple lines in the expression part and include a +formatting spec. Patch by Pablo Galindo + +.. + +.. date: 2023-10-02-23-17-08 +.. gh-issue: 110237 +.. nonce: _Xub0z +.. section: Core and Builtins + +Fix missing error checks for calls to ``PyList_Append`` in +``_PyEval_MatchClass``. + +.. + +.. date: 2023-10-01-02-58-00 +.. gh-issue: 110164 +.. nonce: z7TMCq +.. section: Core and Builtins + +regrtest: If the ``SOURCE_DATE_EPOCH`` environment variable is defined, +regrtest now disables tests randomization. Patch by Victor Stinner. + +.. + +.. date: 2023-09-27-21-35-49 +.. gh-issue: 109889 +.. nonce: t5hIRT +.. section: Core and Builtins + +Fix the compiler's redundant NOP detection algorithm to skip over NOPs with +no line number when looking for the next instruction's lineno. + +.. + +.. date: 2023-09-27-18-01-06 +.. gh-issue: 109853 +.. nonce: coQQiL +.. section: Core and Builtins + +``sys.path[0]`` is now set correctly for subinterpreters. + +.. + +.. date: 2023-09-26-21-26-54 +.. gh-issue: 109923 +.. nonce: WO3CHi +.. section: Core and Builtins + +Set line number on the ``POP_TOP`` that follows a ``RETURN_GENERATOR``. + +.. + +.. date: 2023-09-26-14-00-25 +.. gh-issue: 105716 +.. nonce: SUJkW1 +.. section: Core and Builtins + +Subinterpreters now correctly handle the case where they have threads +running in the background. Before, such threads would interfere with +cleaning up and destroying them, as well as prevent running another script. + +.. + +.. date: 2023-09-26-03-46-55 +.. gh-issue: 109369 +.. nonce: OJbxbF +.. section: Core and Builtins + +The internal eval_breaker and supporting flags, plus the monitoring version +have been merged into a single atomic integer to speed up checks. + +.. + +.. date: 2023-09-25-14-28-14 +.. gh-issue: 109823 +.. nonce: kbVTKF +.. section: Core and Builtins + +Fix bug where compiler does not adjust labels when removing an empty basic +block which is a jump target. + +.. + +.. date: 2023-09-25-09-24-10 +.. gh-issue: 109793 +.. nonce: zFQBkv +.. section: Core and Builtins + +The main thread no longer exits prematurely when a subinterpreter is cleaned +up during runtime finalization. The bug was a problem particularly because, +when triggered, the Python process would always return with a 0 exitcode, +even if it failed. + +.. + +.. date: 2023-09-22-13-38-17 +.. gh-issue: 109719 +.. nonce: fx5OTz +.. section: Core and Builtins + +Fix missing jump target labels when compiler reorders cold/warm blocks. + +.. + +.. date: 2023-09-22-01-44-53 +.. gh-issue: 109595 +.. nonce: fVINgD +.. section: Core and Builtins + +Add :option:`-X cpu_count <-X>` command line option to override return +results of :func:`os.cpu_count` and :func:`os.process_cpu_count`. This +option is useful for users who need to limit CPU resources of a container +system without having to modify the container (application code). Patch by +Donghee Na. + +.. + +.. date: 2023-09-20-23-04-15 +.. gh-issue: 109627 +.. nonce: xxe7De +.. section: Core and Builtins + +Fix bug where the compiler does not assign a new jump target label to a +duplicated small exit block. + +.. + +.. date: 2023-09-20-13-18-08 +.. gh-issue: 109596 +.. nonce: RG0K2G +.. section: Core and Builtins + +Fix some tokens in the grammar that were incorrectly marked as soft +keywords. Also fix some repeated rule names and ensure that repeated rules +are not allowed. Patch by Pablo Galindo + +.. + +.. date: 2023-09-18-15-35-08 +.. gh-issue: 109496 +.. nonce: Kleoz3 +.. section: Core and Builtins + +On a Python built in debug mode, :c:func:`Py_DECREF()` now calls +``_Py_NegativeRefcount()`` if the object is a dangling pointer to +deallocated memory: memory filled with ``0xDD`` "dead byte" by the debug +hook on memory allocators. The fix is to check the reference count *before* +checking for ``_Py_IsImmortal()``. Patch by Victor Stinner. + +.. + +.. date: 2023-09-14-20-15-57 +.. gh-issue: 107265 +.. nonce: qHZL_6 +.. section: Core and Builtins + +Deopt opcodes hidden by the executor when base opcode is needed + +.. + +.. date: 2023-09-13-21-04-04 +.. gh-issue: 109371 +.. nonce: HPEJr8 +.. section: Core and Builtins + +Deopted instructions correctly for tool initialization and modified the +incorrect assertion in instrumentation, when a previous tool already sets +INSTRUCTION events + +.. + +.. date: 2023-09-13-19-16-51 +.. gh-issue: 105658 +.. nonce: z2nR2u +.. section: Core and Builtins + +Fix bug where the line trace of an except block ending with a conditional +includes an excess event with the line of the conditional expression. + +.. + +.. date: 2023-09-13-08-42-45 +.. gh-issue: 109219 +.. nonce: UiN8sc +.. section: Core and Builtins + +Fix compiling type param scopes that use a name which is also free in an +inner scope. + +.. + +.. date: 2023-09-12-16-00-42 +.. gh-issue: 109351 +.. nonce: kznGeR +.. section: Core and Builtins + +Fix crash when compiling an invalid AST involving a named (walrus) +expression. + +.. + +.. date: 2023-09-12-15-45-49 +.. gh-issue: 109341 +.. nonce: 4V5bkm +.. section: Core and Builtins + +Fix crash when compiling an invalid AST involving a :class:`ast.TypeAlias`. + +.. + +.. date: 2023-09-11-15-51-55 +.. gh-issue: 109195 +.. nonce: iwxmuo +.. section: Core and Builtins + +Fix source location for the ``LOAD_*`` instruction preceding a +``LOAD_SUPER_ATTR`` to load the ``super`` global (or shadowing variable) so +that it encompasses only the name ``super`` and not the following +parentheses. + +.. + +.. date: 2023-09-11-15-11-03 +.. gh-issue: 109256 +.. nonce: 6mfhvF +.. section: Core and Builtins + +Opcode IDs for specialized opcodes are allocated in their own range to +improve stability of the IDs for the 'real' opcodes. + +.. + +.. date: 2023-09-11-12-41-42 +.. gh-issue: 109216 +.. nonce: 60QOSb +.. section: Core and Builtins + +Fix possible memory leak in :opcode:`BUILD_MAP`. + +.. + +.. date: 2023-09-10-18-53-55 +.. gh-issue: 109207 +.. nonce: Fei8bY +.. section: Core and Builtins + +Fix a SystemError in ``__repr__`` of symtable entry object. + +.. + +.. date: 2023-09-09-21-17-18 +.. gh-issue: 109179 +.. nonce: ZR8qs2 +.. section: Core and Builtins + +Fix bug where the C traceback display drops notes from :exc:`SyntaxError`. + +.. + +.. date: 2023-09-09-12-49-46 +.. gh-issue: 109118 +.. nonce: gx0X4h +.. section: Core and Builtins + +Disallow nested scopes (lambdas, generator expressions, and comprehensions) +within PEP 695 annotation scopes that are nested within classes. + +.. + +.. date: 2023-09-08-18-31-04 +.. gh-issue: 109156 +.. nonce: KK1EXI +.. section: Core and Builtins + +Add tests for de-instrumenting instructions while keeping the +instrumentation for lines + +.. + +.. date: 2023-09-08-01-50-41 +.. gh-issue: 109114 +.. nonce: adqgtb +.. section: Core and Builtins + +Relax the detection of the error message for invalid lambdas inside +f-strings to not search for arbitrary replacement fields to avoid false +positives. Patch by Pablo Galindo + +.. + +.. date: 2023-09-07-20-52-27 +.. gh-issue: 105848 +.. nonce: p799D1 +.. section: Core and Builtins + +Add a new :opcode:`CALL_KW` opcode, used for calls containing keyword +arguments. Also, fix a possible crash when jumping over method calls in a +debugger. + +.. + +.. date: 2023-09-07-18-49-01 +.. gh-issue: 109052 +.. nonce: TBU4nC +.. section: Core and Builtins + +Use the base opcode when comparing code objects to avoid interference from +instrumentation + +.. + +.. date: 2023-09-07-18-24-42 +.. gh-issue: 109118 +.. nonce: yPXRAe +.. section: Core and Builtins + +Fix interpreter crash when a NameError is raised inside the type parameters +of a generic class. + +.. + +.. date: 2023-09-07-16-05-36 +.. gh-issue: 88943 +.. nonce: rH_X3W +.. section: Core and Builtins + +Improve syntax error for non-ASCII character that follows a numerical +literal. It now points on the invalid non-ASCII character, not on the valid +numerical literal. + +.. + +.. date: 2023-09-06-22-50-25 +.. gh-issue: 108976 +.. nonce: MUKaIJ +.. section: Core and Builtins + +Fix crash that occurs after de-instrumenting a code object in a monitoring +callback. + +.. + +.. date: 2023-09-06-13-28-42 +.. gh-issue: 108732 +.. nonce: I6DkEQ +.. section: Core and Builtins + +Make iteration variables of module- and class-scoped comprehensions visible +to pdb and other tools that use ``frame.f_locals`` again. + +.. + +.. date: 2023-09-05-20-52-17 +.. gh-issue: 108959 +.. nonce: 6z45Sy +.. section: Core and Builtins + +Fix caret placement for error locations for subscript and binary operations +that involve non-semantic parentheses and spaces. Patch by Pablo Galindo + +.. + +.. date: 2023-09-05-11-31-27 +.. gh-issue: 104584 +.. nonce: IRSXA2 +.. section: Core and Builtins + +Fix a crash when running with :envvar:`PYTHONUOPS` or :option:`-X uops <-X>` +enabled and an error occurs during optimization. + +.. + +.. date: 2023-08-31-21-29-28 +.. gh-issue: 108727 +.. nonce: blNRGM +.. section: Core and Builtins + +Define ``tp_dealloc`` for ``CounterOptimizer_Type``. This fixes a segfault +on deallocation. + +.. + +.. date: 2023-08-30-15-41-47 +.. gh-issue: 108520 +.. nonce: u0ZGP_ +.. section: Core and Builtins + +Fix :meth:`multiprocessing.synchronize.SemLock.__setstate__` to properly +initialize :attr:`multiprocessing.synchronize.SemLock._is_fork_ctx`. This +fixes a regression when passing a SemLock accross nested processes. + +Rename :attr:`multiprocessing.synchronize.SemLock.is_fork_ctx` to +:attr:`multiprocessing.synchronize.SemLock._is_fork_ctx` to avoid exposing +it as public API. + +.. + +.. date: 2023-08-29-17-53-12 +.. gh-issue: 108654 +.. nonce: jbkDVo +.. section: Core and Builtins + +Restore locals shadowed by an inlined comprehension if the comprehension +raises an exception. + +.. + +.. date: 2023-08-28-22-22-15 +.. gh-issue: 108488 +.. nonce: e8-fxg +.. section: Core and Builtins + +Change the initialization of inline cache entries so that the cache entry +for ``JUMP_BACKWARD`` is initialized to zero, instead of the +``adaptive_counter_warmup()`` value used for all other instructions. This +counter, unique among instructions, counts up from zero. + +.. + +.. date: 2023-08-28-03-38-28 +.. gh-issue: 108716 +.. nonce: HJBPwt +.. section: Core and Builtins + +Turn off deep-freezing of code objects. Modules are still frozen, so that a +file system search is not needed for common modules. + +.. + +.. date: 2023-08-26-10-36-45 +.. gh-issue: 108614 +.. nonce: wl5l-W +.. section: Core and Builtins + +Add RESUME_CHECK instruction, to avoid having to handle instrumentation, +signals, and contexts switches in the tier 2 execution engine. + +.. + +.. date: 2023-08-26-04-31-01 +.. gh-issue: 108487 +.. nonce: 1Gbr9k +.. section: Core and Builtins + +Move an assert that would cause a spurious crash in a devious case that +should only trigger deoptimization. + +.. + +.. date: 2023-08-25-14-51-06 +.. gh-issue: 106176 +.. nonce: D1EA2a +.. section: Core and Builtins + +Use a ``WeakValueDictionary`` to track the lists containing the modules each +thread is currently importing. This helps avoid a reference leak from +keeping the list around longer than necessary. Weakrefs are used as GC can't +interrupt the cleanup. + +.. + +.. date: 2023-08-23-14-54-15 +.. gh-issue: 105481 +.. nonce: 40q-c4 +.. section: Core and Builtins + +The regen-opcode build stage was removed and its work is now done in +regen-cases. + +.. + +.. date: 2023-08-21-21-13-30 +.. gh-issue: 107901 +.. nonce: hszvdk +.. section: Core and Builtins + +Fix missing line number on :opcode:`JUMP_BACKWARD` at the end of a for loop. + +.. + +.. date: 2023-08-18-18-21-27 +.. gh-issue: 108113 +.. nonce: 1h0poE +.. section: Core and Builtins + +The :func:`compile` built-in can now accept a new flag, +``ast.PyCF_OPTIMIZED_AST``, which is similar to ``ast.PyCF_ONLY_AST`` except +that the returned ``AST`` is optimized according to the value of the +``optimize`` argument. + +:func:`ast.parse` now accepts an optional argument ``optimize`` which is +passed on to the :func:`compile` built-in. This makes it possible to obtain +an optimized ``AST``. + +.. + +.. date: 2023-08-15-13-06-05 +.. gh-issue: 107971 +.. nonce: lPbx04 +.. section: Core and Builtins + +Opcode IDs are generated from bytecodes.c instead of being hard coded in +opcode.py. + +.. + +.. date: 2023-08-15-11-09-50 +.. gh-issue: 107944 +.. nonce: zQLp3j +.. section: Core and Builtins + +Improve error message for function calls with bad keyword arguments. Patch +by Pablo Galindo + +.. + +.. date: 2023-08-13-17-18-22 +.. gh-issue: 108390 +.. nonce: TkBccC +.. section: Core and Builtins + +Raise an exception when setting a non-local event (``RAISE``, +``EXCEPTION_HANDLED``, etc.) in ``sys.monitoring.set_local_events``. + +Fixes crash when tracing in recursive calls to Python classes. + +.. + +.. date: 2023-08-11-16-18-19 +.. gh-issue: 108035 +.. nonce: e2msOD +.. section: Core and Builtins + +Remove the ``_PyCFrame`` struct, moving the pointer to the current +intepreter frame back to the threadstate, as it was for 3.10 and earlier. +The ``_PyCFrame`` existed as a performance optimization for tracing. Since +PEP 669 has been implemented, this optimization no longer applies. + +.. + +.. date: 2023-08-10-17-36-27 +.. gh-issue: 91051 +.. nonce: LfaeNW +.. section: Core and Builtins + +Fix abort / segfault when using all eight type watcher slots, on platforms +where ``char`` is signed by default. + +.. + +.. date: 2023-08-10-00-00-48 +.. gh-issue: 106581 +.. nonce: o7zDty +.. section: Core and Builtins + +Fix possible assertion failures and missing instrumentation events when +:envvar:`PYTHONUOPS` or :option:`-X uops <-X>` is enabled. + +.. + +.. date: 2023-08-09-15-05-27 +.. gh-issue: 107526 +.. nonce: PB32z- +.. section: Core and Builtins + +Revert converting ``vars``, ``dir``, ``next``, ``getattr``, and ``iter`` to +argument clinic. + +.. + +.. date: 2023-08-09-08-31-20 +.. gh-issue: 84805 +.. nonce: 7JRWua +.. section: Core and Builtins + +Autogenerate signature for :c:macro:`METH_NOARGS` and :c:macro:`METH_O` +extension functions. + +.. + +.. date: 2023-08-08-02-46-46 +.. gh-issue: 107758 +.. nonce: R5kyBI +.. section: Core and Builtins + +Make the ``dump_stack()`` routine used by the ``lltrace`` feature (low-level +interpreter debugging) robust against recursion by ensuring that it never +calls a ``__repr__`` method implemented in Python. Also make the similar +output for Tier-2 uops appear on ``stdout`` (instead of ``stderr``), to +match the ``lltrace`` code in ceval.c. + +.. + +.. date: 2023-08-05-15-45-07 +.. gh-issue: 107659 +.. nonce: QgtQ5M +.. section: Core and Builtins + +Add docstrings for :func:`ctypes.pointer` and :func:`ctypes.POINTER`. + +.. + +.. date: 2023-08-05-09-06-56 +.. gh-issue: 105848 +.. nonce: Drc-1- +.. section: Core and Builtins + +Modify the bytecode so that the actual callable for a :opcode:`CALL` is at a +consistent position on the stack (regardless of whether or not +bound-method-calling optimizations are active). + +.. + +.. date: 2023-08-05-04-47-18 +.. gh-issue: 107674 +.. nonce: 0sYhR2 +.. section: Core and Builtins + +Fixed performance regression in ``sys.settrace``. + +.. + +.. date: 2023-08-04-21-25-26 +.. gh-issue: 107724 +.. nonce: EbBXMr +.. section: Core and Builtins + +In pre-release versions of 3.12, up to rc1, the sys.monitoring callback +function for the ``PY_THROW`` event was missing the third, exception +argument. That is now fixed. + +.. + +.. date: 2023-08-03-13-38-14 +.. gh-issue: 84436 +.. nonce: gl1wHx +.. section: Core and Builtins + +Skip reference count modifications for many known immortal objects. + +.. + +.. date: 2023-08-03-11-13-09 +.. gh-issue: 107596 +.. nonce: T3yPGI +.. section: Core and Builtins + +Specialize subscripting :class:`str` objects by :class:`int` indexes. + +.. + +.. date: 2023-08-02-12-24-51 +.. gh-issue: 107080 +.. nonce: PNolFU +.. section: Core and Builtins + +Trace refs builds (``--with-trace-refs``) were crashing when used with +isolated subinterpreters. The problematic global state has been isolated to +each interpreter. Other fixing the crashes, this change does not affect +users. + +.. + +.. date: 2023-08-02-09-55-21 +.. gh-issue: 107557 +.. nonce: P1z-in +.. section: Core and Builtins + +Generate the cases needed for the barebones tier 2 abstract interpreter for +optimization passes in CPython. + +.. + +.. date: 2023-08-01-09-41-36 +.. gh-issue: 106608 +.. nonce: OFZogw +.. section: Core and Builtins + +Make ``_PyUOpExecutorObject`` variable length. + +.. + +.. date: 2023-07-30-18-05-11 +.. gh-issue: 100964 +.. nonce: HluhBJ +.. section: Core and Builtins + +Clear generators' exception state after ``return`` to break reference +cycles. + +.. + +.. date: 2023-07-30-14-18-49 +.. gh-issue: 107455 +.. nonce: Es53l7 +.. section: Core and Builtins + +Improve error messages when converting an incompatible type to +:class:`ctypes.c_char_p`, :class:`ctypes.c_wchar_p` and +:class:`ctypes.c_void_p`. + +.. + +.. date: 2023-07-30-05-20-16 +.. gh-issue: 107263 +.. nonce: q0IU2M +.. section: Core and Builtins + +Increase C recursion limit for functions other than the main interpreter +from 800 to 1500. This should allow functions like ``list.__repr__`` and +``json.dumps`` to handle all the inputs that they could prior to 3.12 + +.. + +.. date: 2023-07-29-22-01-30 +.. gh-issue: 104584 +.. nonce: tINuoA +.. section: Core and Builtins + +Fix an issue which caused incorrect inline caches to be read when running +with :envvar:`PYTHONUOPS` or :option:`-X uops <-X>` enabled. + +.. + +.. date: 2023-07-27-11-47-29 +.. gh-issue: 104432 +.. nonce: oGHF-z +.. section: Core and Builtins + +Fix potential unaligned memory access on C APIs involving returned sequences +of ``char *`` pointers within the :mod:`grp` and :mod:`socket` modules. +These were revealed using a ``-fsaniziter=alignment`` build on ARM macOS. +Patch by Christopher Chavez. + +.. + +.. date: 2023-07-27-11-18-04 +.. gh-issue: 106078 +.. nonce: WEy2Yn +.. section: Core and Builtins + +Isolate :mod:`!_decimal` (apply :pep:`687`). Patch by Charlie Zhao. + +.. + +.. date: 2023-07-26-21-28-06 +.. gh-issue: 106898 +.. nonce: 8Wjuiv +.. section: Core and Builtins + +Add the exception as the third argument to ``PY_UNIND`` callbacks in +``sys.monitoring``. This makes the ``PY_UNWIND`` callback consistent with +the other exception hanlding callbacks. + +.. + +.. date: 2023-07-26-18-53-34 +.. gh-issue: 106895 +.. nonce: DdEwV8 +.. section: Core and Builtins + +Raise a ``ValueError`` when a monitoring callback funtion returns +``DISABLE`` for events that cannot be disabled locally. + +.. + +.. date: 2023-07-26-12-18-10 +.. gh-issue: 106897 +.. nonce: EsGurc +.. section: Core and Builtins + +Add a ``RERAISE`` event to ``sys.monitoring``, which occurs when an +exception is reraise, either explicitly by a plain ``raise`` statement, or +implicitly in an ``except`` or ``finally`` block. + +.. + +.. date: 2023-07-25-22-35-35 +.. gh-issue: 77377 +.. nonce: EHAbXx +.. section: Core and Builtins + +Ensure that multiprocessing synchronization objects created in a fork +context are not sent to a different process created in a spawn context. This +changes a segfault into an actionable RuntimeError in the parent process. + +.. + +.. date: 2023-07-25-15-29-26 +.. gh-issue: 106931 +.. nonce: kKU1le +.. section: Core and Builtins + +Statically allocated string objects are now interned globally instead of +per-interpreter. This fixes a situation where such a string would only be +interned in a single interpreter. Normal string objects are unaffected. + +.. + +.. date: 2023-07-24-11-11-41 +.. gh-issue: 104621 +.. nonce: vM8Y_l +.. section: Core and Builtins + +Unsupported modules now always fail to be imported. + +.. + +.. date: 2023-07-23-21-16-54 +.. gh-issue: 107122 +.. nonce: VNuNcq +.. section: Core and Builtins + +Add :meth:`dbm.ndbm.ndbm.clear` to :mod:`dbm.ndbm`. Patch By Donghee Na. + +.. + +.. date: 2023-07-23-13-07-34 +.. gh-issue: 107122 +.. nonce: 9HFUyb +.. section: Core and Builtins + +Add :meth:`dbm.gnu.gdbm.clear` to :mod:`dbm.gnu`. Patch By Donghee Na. + +.. + +.. date: 2023-07-22-14-35-38 +.. gh-issue: 107015 +.. nonce: Ghp58t +.. section: Core and Builtins + +The ASYNC and AWAIT tokens are removed from the Grammar, which removes the +posibility of making ``async`` and ``await`` soft keywords when using +``feature_version<7`` in :func:`ast.parse`. + +.. + +.. date: 2023-07-21-14-37-48 +.. gh-issue: 106917 +.. nonce: 1jWp_m +.. section: Core and Builtins + +Fix classmethod-style :func:`super` method calls (i.e., where the second +argument to :func:`super`, or the implied second argument drawn from +``self/cls`` in the case of zero-arg super, is a type) when the target of +the call is not a classmethod. + +.. + +.. date: 2023-07-20-15-15-57 +.. gh-issue: 105699 +.. nonce: DdqHFg +.. section: Core and Builtins + +Python no longer crashes due an infrequent race when initialzing +per-interpreter interned strings. The crash would manifest when the +interpreter was finalized. + +.. + +.. date: 2023-07-20-12-21-37 +.. gh-issue: 105699 +.. nonce: 08ywGV +.. section: Core and Builtins + +Python no longer crashes due to an infrequent race in setting +``Py_FileSystemDefaultEncoding`` and ``Py_FileSystemDefaultEncodeErrors`` +(both deprecated), when simultaneously initializing two isolated +subinterpreters. Now they are only set during runtime initialization. + +.. + +.. date: 2023-07-20-01-15-58 +.. gh-issue: 106908 +.. nonce: cDmcVI +.. section: Core and Builtins + +Fix various hangs, reference leaks, test failures, and tracing/introspection +bugs when running with :envvar:`PYTHONUOPS` or :option:`-X uops <-X>` +enabled. + +.. + +.. date: 2023-07-18-16-13-51 +.. gh-issue: 106092 +.. nonce: bObgRM +.. section: Core and Builtins + +Fix a segmentation fault caused by a use-after-free bug in ``frame_dealloc`` +when the trashcan delays the deallocation of a ``PyFrameObject``. + +.. + +.. date: 2023-07-16-07-55-19 +.. gh-issue: 106485 +.. nonce: wPb1bH +.. section: Core and Builtins + +Reduce the number of materialized instances dictionaries by dematerializing +them when possible. + +.. + +.. date: 2023-07-13-15-59-07 +.. gh-issue: 106719 +.. nonce: jmVrsv +.. section: Core and Builtins + +No longer suppress arbitrary errors in the ``__annotations__`` getter and +setter in the type and module types. + +.. + +.. date: 2023-07-13-14-55-45 +.. gh-issue: 106723 +.. nonce: KsMufQ +.. section: Core and Builtins + +Propagate ``frozen_modules`` to multiprocessing spawned process +interpreters. + +.. + +.. date: 2023-07-12-11-18-55 +.. gh-issue: 104909 +.. nonce: DRUsuh +.. section: Core and Builtins + +Split :opcode:`LOAD_ATTR_INSTANCE_VALUE` into micro-ops. + +.. + +.. date: 2023-07-12-10-48-08 +.. gh-issue: 104909 +.. nonce: sWjcr2 +.. section: Core and Builtins + +Split :opcode:`LOAD_GLOBAL` specializations into micro-ops. + +.. + +.. date: 2023-07-10-15-30-45 +.. gh-issue: 106597 +.. nonce: WAZ14y +.. section: Core and Builtins + +A new debug structure of offsets has been added to the ``_PyRuntimeState`` +that will help out-of-process debuggers and profilers to obtain the offsets +to relevant interpreter structures in a way that is agnostic of how Python +was compiled and that doesn't require copying the headers. Patch by Pablo +Galindo + +.. + +.. date: 2023-07-06-22-46-05 +.. gh-issue: 106487 +.. nonce: u3KfAD +.. section: Core and Builtins + +Allow the *count* argument of :meth:`str.replace` to be a keyword. Patch by +Hugo van Kemenade. + +.. + +.. date: 2023-07-06-00-35-44 +.. gh-issue: 96844 +.. nonce: kwvoS- +.. section: Core and Builtins + +Improve error message of :meth:`list.remove`. Patch by Donghee Na. + +.. + +.. date: 2023-07-04-20-42-54 +.. gh-issue: 81283 +.. nonce: hfh_MD +.. section: Core and Builtins + +Compiler now strips indents from docstrings. It reduces ``pyc`` file size 5% +when the module is heavily documented. This change affects to ``__doc__`` so +tools like doctest will be affected. + +.. + +.. date: 2023-07-04-09-51-45 +.. gh-issue: 106396 +.. nonce: DmYp7x +.. section: Core and Builtins + +When the format specification of an f-string expression is empty, the parser +now generates an empty :class:`ast.JoinedStr` node for it instead of an +one-element :class:`ast.JoinedStr` with an empty string +:class:`ast.Constant`. + +.. + +.. date: 2023-07-04-04-50-14 +.. gh-issue: 100288 +.. nonce: yNQ1ez +.. section: Core and Builtins + +Specialize :opcode:`LOAD_ATTR` for non-descriptors on the class. Adds +:opcode:`LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES` and +:opcode:`LOAD_ATTR_NONDESCRIPTOR_NO_DICT`. + +.. + +.. date: 2023-07-03-11-38-43 +.. gh-issue: 106008 +.. nonce: HDf1zd +.. section: Core and Builtins + +Fix possible reference leaks when failing to optimize comparisons with +:const:`None` in the bytecode compiler. + +.. + +.. date: 2023-06-29-09-46-41 +.. gh-issue: 106145 +.. nonce: QC6-Kq +.. section: Core and Builtins + +Make ``end_lineno`` and ``end_col_offset`` required on ``type_param`` ast +nodes. + +.. + +.. date: 2023-06-29-09-42-56 +.. gh-issue: 106213 +.. nonce: TCUgzM +.. section: Core and Builtins + +Changed the way that Emscripten call trampolines work for compatibility with +Wasm/JS Promise integration. + +.. + +.. date: 2023-06-28-15-19-59 +.. gh-issue: 106182 +.. nonce: cDSFi0 +.. section: Core and Builtins + +:func:`sys.getfilesystemencoding` and :mod:`sys.getfilesystemencodeerrors` +now return interned Unicode object. + +.. + +.. date: 2023-06-28-13-19-20 +.. gh-issue: 106210 +.. nonce: oE7VMn +.. section: Core and Builtins + +Removed Emscripten import trampoline as it was no longer necessary for +Pyodide. + +.. + +.. date: 2023-06-27-00-58-26 +.. gh-issue: 104584 +.. nonce: Wu-uXy +.. section: Core and Builtins + +Added a new, experimental, tracing optimizer and interpreter (a.k.a. "tier +2"). This currently pessimizes, so don't use yet -- this is infrastructure +so we can experiment with optimizing passes. To enable it, pass ``-Xuops`` +or set ``PYTHONUOPS=1``. To get debug output, set ``PYTHONUOPSDEBUG=N`` +where ``N`` is a debug level (0-4, where 0 is no debug output and 4 is +excessively verbose). + +.. + +.. date: 2023-06-24-10-34-27 +.. gh-issue: 105775 +.. nonce: OqjoGV +.. section: Core and Builtins + +:opcode:`LOAD_CLOSURE` is now a pseudo-op. + +.. + +.. date: 2023-06-23-16-51-02 +.. gh-issue: 105730 +.. nonce: 16haMe +.. section: Core and Builtins + +Allow any callable other than type objects as the condition predicate in +:meth:`BaseExceptionGroup.split` and :meth:`BaseExceptionGroup.subgroup`. + +.. + +.. date: 2023-06-22-19-16-24 +.. gh-issue: 105979 +.. nonce: TDP2CU +.. section: Core and Builtins + +Fix crash in :func:`!_imp.get_frozen_object` due to improper exception +handling. + +.. + +.. date: 2023-06-22-17-37-35 +.. gh-issue: 106003 +.. nonce: 2Vc_Tw +.. section: Core and Builtins + +Add a new :opcode:`TO_BOOL` instruction, which performs boolean conversions +for :opcode:`POP_JUMP_IF_TRUE`, :opcode:`POP_JUMP_IF_FALSE`, and +:opcode:`UNARY_NOT` (which all expect exact :class:`bool` values now). Also, +modify the oparg of :opcode:`COMPARE_OP` to include an optional "boolean +conversion" flag. + +.. + +.. date: 2023-06-22-14-19-17 +.. gh-issue: 98931 +.. nonce: PPgvSF +.. section: Core and Builtins + +Ensure custom :exc:`SyntaxError` error messages are raised for invalid +imports with multiple targets. Patch by Pablo Galindo + +.. + +.. date: 2023-06-20-10-53-17 +.. gh-issue: 105724 +.. nonce: d23L4M +.. section: Core and Builtins + +Improve ``assert`` error messages by providing exact error range. + +.. + +.. date: 2023-06-19-11-04-01 +.. gh-issue: 105908 +.. nonce: 7oanny +.. section: Core and Builtins + +Fixed bug where :gh:`99111` breaks future import ``barry_as_FLUFL`` in the +Python REPL. + +.. + +.. date: 2023-06-15-22-11-43 +.. gh-issue: 105840 +.. nonce: Fum_g_ +.. section: Core and Builtins + +Fix possible crashes when specializing function calls with too many +``__defaults__``. + +.. + +.. date: 2023-06-15-15-54-47 +.. gh-issue: 105831 +.. nonce: -MC9Zs +.. section: Core and Builtins + +Fix an f-string bug, where using a debug expression (the ``=`` sign) that +appears in the last line of a file results to the debug buffer that holds +the expression text being one character too small. + +.. + +.. date: 2023-06-14-22-52-06 +.. gh-issue: 105800 +.. nonce: hdpPzZ +.. section: Core and Builtins + +Correctly issue :exc:`SyntaxWarning` in f-strings if invalid sequences are +used. Patch by Pablo Galindo + +.. + +.. date: 2023-06-12-16-38-31 +.. gh-issue: 105340 +.. nonce: _jRHXe +.. section: Core and Builtins + +Include the comprehension iteration variable in ``locals()`` inside a +module- or class-scope comprehension. + +.. + +.. date: 2023-06-11-09-14-30 +.. gh-issue: 105331 +.. nonce: nlZvoW +.. section: Core and Builtins + +Raise :exc:`ValueError` if the ``delay`` argument to :func:`asyncio.sleep` +is a NaN (matching :func:`time.sleep`). + +.. + +.. date: 2023-06-10-21-38-49 +.. gh-issue: 105587 +.. nonce: rL3rzv +.. section: Core and Builtins + +The runtime can't guarantee that immortal objects will not be mutated by +Extensions. Thus, this modifies _PyStaticObject_CheckRefcnt to warn instead +of asserting. + +.. + +.. date: 2023-06-09-15-25-12 +.. gh-issue: 105564 +.. nonce: sFdUu4 +.. section: Core and Builtins + +Don't include artificil newlines in the ``line`` attribute of tokens in the +APIs of the :mod:`tokenize` module. Patch by Pablo Galindo + +.. + +.. date: 2023-06-09-12-59-18 +.. gh-issue: 105549 +.. nonce: PYfTNp +.. section: Core and Builtins + +Tokenize separately ``NUMBER`` and ``NAME`` tokens that are not ambiguous. +Patch by Pablo Galindo. + +.. + +.. date: 2023-06-09-11-19-51 +.. gh-issue: 105588 +.. nonce: Y5ovpY +.. section: Core and Builtins + +Fix an issue that could result in crashes when compiling malformed +:mod:`ast` nodes. + +.. + +.. date: 2023-06-09-10-48-17 +.. gh-issue: 100987 +.. nonce: mK-xny +.. section: Core and Builtins + +Allow objects other than code objects as the "executable" in internal +frames. In the long term, this can help tools like Cython and PySpy interact +more efficiently. In the shorter term, it allows us to perform some +optimizations more simply. + +.. + +.. date: 2023-06-08-10-10-07 +.. gh-issue: 105375 +.. nonce: 35VGDd +.. section: Core and Builtins + +Fix bugs in the :mod:`builtins` module where exceptions could end up being +overwritten. + +.. + +.. date: 2023-06-08-09-54-37 +.. gh-issue: 105375 +.. nonce: kqKT3E +.. section: Core and Builtins + +Fix bug in the compiler where an exception could end up being overwritten. + +.. + +.. date: 2023-06-08-09-25-52 +.. gh-issue: 105375 +.. nonce: ocB7fT +.. section: Core and Builtins + +Improve error handling in :c:func:`PyUnicode_BuildEncodingMap` where an +exception could end up being overwritten. + +.. + +.. date: 2023-06-08-09-10-15 +.. gh-issue: 105486 +.. nonce: dev-WS +.. section: Core and Builtins + +Change the repr of ``ParamSpec`` list of args in ``types.GenericAlias``. + +.. + +.. date: 2023-06-07-21-27-55 +.. gh-issue: 105678 +.. nonce: wKOr7F +.. section: Core and Builtins + +Break the ``MAKE_FUNCTION`` instruction into two parts, ``MAKE_FUNCTION`` +which makes the function and ``SET_FUNCTION_ATTRIBUTE`` which sets the +attributes on the function. This makes the stack effect of ``MAKE_FUNCTION`` +regular to ease optimization and code generation. + +.. + +.. date: 2023-06-07-12-20-59 +.. gh-issue: 105435 +.. nonce: 6VllI0 +.. section: Core and Builtins + +Fix spurious newline character if file ends on a comment without a newline. +Patch by Pablo Galindo + +.. + +.. date: 2023-06-06-17-10-42 +.. gh-issue: 105390 +.. nonce: DvqI-e +.. section: Core and Builtins + +Correctly raise :exc:`tokenize.TokenError` exceptions instead of +:exc:`SyntaxError` for tokenize errors such as incomplete input. Patch by +Pablo Galindo + +.. + +.. date: 2023-06-06-11-37-53 +.. gh-issue: 105259 +.. nonce: E2BGKL +.. section: Core and Builtins + +Don't include newline character for trailing ``NEWLINE`` tokens emitted in +the :mod:`tokenize` module. Patch by Pablo Galindo + +.. + +.. date: 2023-06-05-23-38-43 +.. gh-issue: 104635 +.. nonce: VYZhVh +.. section: Core and Builtins + +Eliminate redundant :opcode:`STORE_FAST` instructions in the compiler. Patch +by Donghee Na and Carl Meyer. + +.. + +.. date: 2023-06-05-17-35-50 +.. gh-issue: 105324 +.. nonce: BqhiJJ +.. section: Core and Builtins + +Fix the main function of the :mod:`tokenize` module when reading from +``sys.stdin``. Patch by Pablo Galindo + +.. + +.. date: 2023-06-05-08-30-49 +.. gh-issue: 33092 +.. nonce: hZ0xSI +.. section: Core and Builtins + +Simplify and speed up interpreter for f-strings. Removes ``FORMAT_VALUE`` +opcode. Add ``CONVERT_VALUE``, ``FORMAT_SIMPLE`` and ``FORMAT_WITH_SPEC`` +opcode. Compiler emits more efficient sequence for each format expression. + +.. + +.. date: 2023-06-03-04-28-28 +.. gh-issue: 105229 +.. nonce: stEmfp +.. section: Core and Builtins + +Remove remaining two-codeunit superinstructions. All remaining +superinstructions only take a single codeunit, simplifying instrumentation +and quickening. + +.. + +.. date: 2023-06-02-19-37-29 +.. gh-issue: 105235 +.. nonce: fgFGTi +.. section: Core and Builtins + +Prevent out-of-bounds memory access during ``mmap.find()`` calls. + +.. + +.. date: 2023-06-02-17-39-19 +.. gh-issue: 98963 +.. nonce: J4wJgk +.. section: Core and Builtins + +Restore the ability for a subclass of :class:`property` to define +``__slots__`` or otherwise be dict-less by ignoring failures to set a +docstring on such a class. This behavior had regressed in 3.12beta1. An +:exc:`AttributeError` where there had not previously been one was disruptive +to existing code. + +.. + +.. date: 2023-06-02-15-15-41 +.. gh-issue: 104812 +.. nonce: dfZiG5 +.. section: Core and Builtins + +The "pending call" machinery now works for all interpreters, not just the +main interpreter, and runs in all threads, not just the main thread. Some +calls are still only done in the main thread, ergo in the main interpreter. +This change does not affect signal handling nor the existing public C-API +(``Py_AddPendingCall()``), which both still only target the main thread. The +new functionality is meant strictly for internal use for now, since +consequences of its use are not well understood yet outside some very +restricted cases. This change brings the capability in line with the +intention when the state was made per-interpreter several years ago. + +.. + +.. date: 2023-06-02-11-37-12 +.. gh-issue: 105194 +.. nonce: 4eu56B +.. section: Core and Builtins + +Do not escape with backslashes f-string format specifiers. Patch by Pablo +Galindo + +.. + +.. date: 2023-06-02-01-27-35 +.. gh-issue: 105229 +.. nonce: U05x4G +.. section: Core and Builtins + +Replace some dynamic superinstructions with single instruction equivalents. + +.. + +.. date: 2023-06-01-11-37-03 +.. gh-issue: 105162 +.. nonce: r8VCXk +.. section: Core and Builtins + +Fixed bug in generator.close()/throw() where an inner iterator would be +ignored when the outer iterator was instrumented. + +.. + +.. date: 2023-05-31-19-35-22 +.. gh-issue: 105164 +.. nonce: 6Wajph +.. section: Core and Builtins + +Ensure annotations are set up correctly if the only annotation in a block is +within a :keyword:`match` block. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-31-16-22-29 +.. gh-issue: 105148 +.. nonce: MOlb1d +.. section: Core and Builtins + +Make ``_PyASTOptimizeState`` internal to ast_opt.c. Make ``_PyAST_Optimize`` +take two integers instead of a pointer to this struct. This avoids the need +to include pycore_compile.h in ast_opt.c. + +.. + +.. date: 2023-05-31-08-10-59 +.. gh-issue: 104799 +.. nonce: 8kDWti +.. section: Core and Builtins + +Attributes of :mod:`ast` nodes that are lists now default to the empty list +if omitted. This means that some code that previously raised +:exc:`TypeError` when the AST node was used will now proceed with the empty +list instead. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-30-20-30-57 +.. gh-issue: 105111 +.. nonce: atn0_6 +.. section: Core and Builtins + +Remove the old trashcan macros ``Py_TRASHCAN_SAFE_BEGIN`` and +``Py_TRASHCAN_SAFE_END``. They should be replaced by the new macros +``Py_TRASHCAN_BEGIN`` and ``Py_TRASHCAN_END``. + +.. + +.. date: 2023-05-30-08-09-43 +.. gh-issue: 105035 +.. nonce: OWUlHy +.. section: Core and Builtins + +Fix :func:`super` calls on types with custom +:c:member:`~PyTypeObject.tp_getattro` implementation (e.g. meta-types.) + +.. + +.. date: 2023-05-27-21-50-48 +.. gh-issue: 105017 +.. nonce: 4sDyDV +.. section: Core and Builtins + +Show CRLF lines in the tokenize string attribute in both NL and NEWLINE +tokens. Patch by Marta Gómez. + +.. + +.. date: 2023-05-27-16-57-11 +.. gh-issue: 105013 +.. nonce: IsDgDY +.. section: Core and Builtins + +Fix handling of multiline parenthesized lambdas in +:func:`inspect.getsource`. Patch by Pablo Galindo + +.. + +.. date: 2023-05-27-16-23-16 +.. gh-issue: 105017 +.. nonce: KQrsC0 +.. section: Core and Builtins + +Do not include an additional final ``NL`` token when parsing files having +CRLF lines. Patch by Marta Gómez. + +.. + +.. date: 2023-05-26-15-16-11 +.. gh-issue: 104976 +.. nonce: 6dLitD +.. section: Core and Builtins + +Ensure that trailing ``DEDENT`` :class:`tokenize.TokenInfo` objects emitted +by the :mod:`tokenize` module are reported as in Python 3.11. Patch by Pablo +Galindo + +.. + +.. date: 2023-05-26-14-09-47 +.. gh-issue: 104972 +.. nonce: El2UjE +.. section: Core and Builtins + +Ensure that the ``line`` attribute in :class:`tokenize.TokenInfo` objects in +the :mod:`tokenize` module are always correct. Patch by Pablo Galindo + +.. + +.. date: 2023-05-25-21-40-39 +.. gh-issue: 104955 +.. nonce: LZx7jf +.. section: Core and Builtins + +Fix signature for the new :meth:`~object.__release_buffer__` slot. Patch by +Jelle Zijlstra. + +.. + +.. date: 2023-05-24-12-10-54 +.. gh-issue: 104690 +.. nonce: HX3Jou +.. section: Core and Builtins + +Starting new threads and process creation through :func:`os.fork` during +interpreter shutdown (such as from :mod:`atexit` handlers) is no longer +supported. It can lead to race condition between the main Python runtime +thread freeing thread states while internal :mod:`threading` routines are +trying to allocate and use the state of just created threads. Or forked +children trying to use the mid-shutdown runtime and thread state in the +child process. + +.. + +.. date: 2023-05-24-10-19-35 +.. gh-issue: 104879 +.. nonce: v-29NL +.. section: Core and Builtins + +Fix crash when accessing the ``__module__`` attribute of type aliases +defined outside a module. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-24-09-59-56 +.. gh-issue: 104825 +.. nonce: mQesie +.. section: Core and Builtins + +Tokens emitted by the :mod:`tokenize` module do not include an implicit +``\n`` character in the ``line`` attribute anymore. Patch by Pablo Galindo + +.. + +.. date: 2023-05-23-00-36-02 +.. gh-issue: 104770 +.. nonce: poSkyY +.. section: Core and Builtins + +If a generator returns a value upon being closed, the value is now returned +by :meth:`generator.close`. + +.. + +.. date: 2023-05-18-12-48-39 +.. gh-issue: 89091 +.. nonce: FDzRcW +.. section: Core and Builtins + +Raise :exc:`RuntimeWarning` for unawaited async generator methods like +:meth:`~agen.asend`, :meth:`~agen.athrow` and :meth:`~agen.aclose`. Patch by +Kumar Aditya. + +.. + +.. date: 2023-04-04-00-40-04 +.. gh-issue: 96663 +.. nonce: PdR9hK +.. section: Core and Builtins + +Add a better, more introspect-able error message when setting attributes on +classes without a ``__dict__`` and no slot member for the attribute. + +.. + +.. date: 2023-03-26-19-11-10 +.. gh-issue: 93627 +.. nonce: 0UgwBL +.. section: Core and Builtins + +Update the Python pickle module implementation to match the C implementation +of the pickle module. For objects setting reduction methods like +:meth:`~object.__reduce_ex__` or :meth:`~object.__reduce__` to ``None``, +pickling will result in a :exc:`TypeError`. + +.. + +.. date: 2023-01-13-11-37-41 +.. gh-issue: 101006 +.. nonce: fuLvn2 +.. section: Core and Builtins + +Improve error handling when read :mod:`marshal` data. + +.. + +.. date: 2022-11-10-13-04-35 +.. gh-issue: 91095 +.. nonce: 4E3Pwn +.. section: Core and Builtins + +Specializes calls to most Python classes. Specifically, any class that +inherits from ``object``, or another Python class, and does not override +``__new__``. + +The specialized instruction does the following: + +1. Creates the object (by calling ``object.__new__``) +2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) +3. Pushes the frame for ``__init__`` to the frame stack + +Speeds up the instantiation of most Python classes. + +.. + +.. date: 2023-10-13-01-31-27 +.. gh-issue: 110786 +.. nonce: sThp-A +.. section: Library + +:mod:`sysconfig`'s CLI now ignores :exc:`BrokenPipeError`, making it exit +normally if its output is being piped and the pipe closes. + +.. + +.. date: 2023-10-13-00-14-17 +.. gh-issue: 103480 +.. nonce: lmdf1J +.. section: Library + +The :mod:`sysconfig` module is now a package, instead of a single-file +module. + +.. + +.. date: 2023-10-11-18-43-43 +.. gh-issue: 110733 +.. nonce: UlrgVm +.. section: Library + +Micro-optimization: Avoid calling ``min()``, ``max()`` in +:meth:`BaseEventLoop._run_once`. + +.. + +.. date: 2023-10-11-15-07-21 +.. gh-issue: 94597 +.. nonce: NbPC8t +.. section: Library + +Added :class:`asyncio.EventLoop` for use with the :func:`asyncio.run` +*loop_factory* kwarg to avoid calling the asyncio policy system. + +.. + +.. date: 2023-10-11-11-00-11 +.. gh-issue: 110682 +.. nonce: bXRFaX +.. section: Library + +:func:`runtime-checkable protocols ` used to +consider ``__match_args__`` a protocol member in ``__instancecheck__`` if it +was present on the protocol. Now, this attribute is ignored if it is +present. + +.. + +.. date: 2023-10-10-22-54-56 +.. gh-issue: 110488 +.. nonce: 2I7OiZ +.. section: Library + +Fix a couple of issues in :meth:`pathlib.PurePath.with_name`: a single dot +was incorrectly considered a valid name, and in :class:`PureWindowsPath`, a +name with an NTFS alternate data stream, like ``a:b``, was incorrectly +considered invalid. + +.. + +.. date: 2023-10-10-10-46-55 +.. gh-issue: 110590 +.. nonce: fatz-h +.. section: Library + +Fix a bug in :meth:`!_sre.compile` where :exc:`TypeError` would be +overwritten by :exc:`OverflowError` when the *code* argument was a list of +non-ints. + +.. + +.. date: 2023-10-09-19-09-32 +.. gh-issue: 65052 +.. nonce: C2mRlo +.. section: Library + +Prevent :mod:`pdb` from crashing when trying to display undisplayable +objects + +.. + +.. date: 2023-10-08-18-15-02 +.. gh-issue: 110519 +.. nonce: RDGe8- +.. section: Library + +Deprecation warning about non-integer number in :mod:`gettext` now alwais +refers to the line in the user code where gettext function or method is +used. Previously it could refer to a line in ``gettext`` code. + +.. + +.. date: 2023-10-07-21-12-28 +.. gh-issue: 89902 +.. nonce: dCokZj +.. section: Library + +Deprecate non-standard format specifier "N" for :class:`decimal.Decimal`. It +was not documented and only supported in the C implementation. + +.. + +.. date: 2023-10-07-13-50-12 +.. gh-issue: 110378 +.. nonce: Y4L8fl +.. section: Library + +:func:`~contextlib.contextmanager` and +:func:`~contextlib.asynccontextmanager` context managers now close an +invalid underlying generator object that yields more then one value. + +.. + +.. date: 2023-10-07-00-18-40 +.. gh-issue: 106670 +.. nonce: kCGyRc +.. section: Library + +In :mod:`pdb`, set convenience variable ``$_exception`` for post mortem +debugging. + +.. + +.. date: 2023-10-04-18-56-29 +.. gh-issue: 110365 +.. nonce: LCxiau +.. section: Library + +Fix :func:`termios.tcsetattr` bug that was overwritting existing errors +during parsing integers from ``term`` list. + +.. + +.. date: 2023-10-03-15-17-03 +.. gh-issue: 109653 +.. nonce: 9DYOMD +.. section: Library + +Slightly improve the import time of several standard-library modules by +deferring imports of :mod:`warnings` within those modules. Patch by Alex +Waygood. + +.. + +.. date: 2023-10-03-14-07-05 +.. gh-issue: 110273 +.. nonce: QaDUmS +.. section: Library + +:func:`dataclasses.replace` now raises TypeError instead of ValueError if +specify keyword argument for a field declared with init=False or miss +keyword argument for required InitVar field. + +.. + +.. date: 2023-10-03-00-04-26 +.. gh-issue: 110249 +.. nonce: K0mMrs +.. section: Library + +Add ``--inline-caches`` flag to ``dis`` command line. + +.. + +.. date: 2023-10-02-15-40-10 +.. gh-issue: 109653 +.. nonce: iB0peK +.. section: Library + +Fix a Python 3.12 regression in the import time of :mod:`random`. Patch by +Alex Waygood. + +.. + +.. date: 2023-10-02-15-07-28 +.. gh-issue: 110222 +.. nonce: zl_oHh +.. section: Library + +Add support of struct sequence objects in :func:`copy.replace`. Patched by +Xuehai Pan. + +.. + +.. date: 2023-10-01-01-47-21 +.. gh-issue: 109649 +.. nonce: BizOaD +.. section: Library + +:mod:`multiprocessing`, :mod:`concurrent.futures`, :mod:`compileall`: +Replace :func:`os.cpu_count` with :func:`os.process_cpu_count` to select the +default number of worker threads and processes. Get the CPU affinity if +supported. Patch by Victor Stinner. + +.. + +.. date: 2023-09-30-12-50-47 +.. gh-issue: 110150 +.. nonce: 9j0Ij5 +.. section: Library + +Fix base case handling in statistics.quantiles. Now allows a single data +point. + +.. + +.. date: 2023-09-28-18-53-11 +.. gh-issue: 110036 +.. nonce: fECxTj +.. section: Library + +On Windows, multiprocessing ``Popen.terminate()`` now catchs +:exc:`PermissionError` and get the process exit code. If the process is +still running, raise again the :exc:`PermissionError`. Otherwise, the +process terminated as expected: store its exit code. Patch by Victor +Stinner. + +.. + +.. date: 2023-09-28-18-50-33 +.. gh-issue: 110038 +.. nonce: nx_gCu +.. section: Library + +Fixed an issue that caused :meth:`KqueueSelector.select` to not return all +the ready events in some cases when a file descriptor is registered for both +read and write. + +.. + +.. date: 2023-09-28-18-08-02 +.. gh-issue: 110045 +.. nonce: 0YIGKv +.. section: Library + +Update the :mod:`symtable` module to support the new scopes introduced by +:pep:`695`. + +.. + +.. date: 2023-09-28-12-32-57 +.. gh-issue: 88402 +.. nonce: hoa3Gx +.. section: Library + +Add new variables to :py:meth:`sysconfig.get_config_vars` on Windows: +``LIBRARY``, ``LDLIBRARY``, ``LIBDIR``, ``SOABI``, and ``Py_NOGIL``. + +.. + +.. date: 2023-09-25-23-00-37 +.. gh-issue: 109631 +.. nonce: eWSqpO +.. section: Library + +:mod:`re` functions such as :func:`re.findall`, :func:`re.split`, +:func:`re.search` and :func:`re.sub` which perform short repeated matches +can now be interrupted by user. + +.. + +.. date: 2023-09-25-10-47-22 +.. gh-issue: 109653 +.. nonce: TUHrId +.. section: Library + +Reduce the import time of :mod:`email.utils` by around 43%. This results in +the import time of :mod:`email.message` falling by around 18%, which in turn +reduces the import time of :mod:`importlib.metadata` by around 6%. Patch by +Alex Waygood. + +.. + +.. date: 2023-09-25-09-59-59 +.. gh-issue: 109818 +.. nonce: dLRtT- +.. section: Library + +Fix :func:`reprlib.recursive_repr` not copying ``__type_params__`` from +decorated function. + +.. + +.. date: 2023-09-25-02-11-14 +.. gh-issue: 109047 +.. nonce: b1TrqG +.. section: Library + +:mod:`concurrent.futures`: The *executor manager thread* now catches +exceptions when adding an item to the *call queue*. During Python +finalization, creating a new thread can now raise :exc:`RuntimeError`. Catch +the exception and call ``terminate_broken()`` in this case. Patch by Victor +Stinner. + +.. + +.. date: 2023-09-24-16-43-33 +.. gh-issue: 109782 +.. nonce: gMC_7z +.. section: Library + +Ensure the signature of :func:`os.path.isdir` is identical on all platforms. +Patch by Amin Alaee. + +.. + +.. date: 2023-09-24-13-28-35 +.. gh-issue: 109653 +.. nonce: 9IFU0B +.. section: Library + +Improve import time of :mod:`functools` by around 13%. Patch by Alex +Waygood. + +.. + +.. date: 2023-09-24-06-04-14 +.. gh-issue: 109590 +.. nonce: 9EMofC +.. section: Library + +:func:`shutil.which` will prefer files with an extension in ``PATHEXT`` if +the given mode includes ``os.X_OK`` on win32. If no ``PATHEXT`` match is +found, a file without an extension in ``PATHEXT`` can be returned. This +change will have :func:`shutil.which` act more similarly to previous +behavior in Python 3.11. + +.. + +.. date: 2023-09-23-12-47-45 +.. gh-issue: 109653 +.. nonce: 9wZBfs +.. section: Library + +Reduce the import time of :mod:`enum` by over 50%. Patch by Alex Waygood. + +.. + +.. date: 2023-09-22-20-16-44 +.. gh-issue: 109593 +.. nonce: LboaNM +.. section: Library + +Avoid deadlocking on a reentrant call to the multiprocessing resource +tracker. Such a reentrant call, though unlikely, can happen if a GC pass +invokes the finalizer for a multiprocessing object such as SemLock. + +.. + +.. date: 2023-09-21-19-42-22 +.. gh-issue: 109653 +.. nonce: bL3iLH +.. section: Library + +Reduce the import time of :mod:`typing` by around a third. Patch by Alex +Waygood. + +.. + +.. date: 2023-09-21-16-21-19 +.. gh-issue: 109649 +.. nonce: YYCjAF +.. section: Library + +Add :func:`os.process_cpu_count` function to get the number of logical CPUs +usable by the calling thread of the current process. Patch by Victor +Stinner. + +.. + +.. date: 2023-09-21-14-26-44 +.. gh-issue: 74481 +.. nonce: KAUDcD +.. section: Library + +Add ``set_error_mode`` related constants in ``msvcrt`` module in Python +debug build. + +.. + +.. date: 2023-09-20-17-45-46 +.. gh-issue: 109613 +.. nonce: P13ogN +.. section: Library + +Fix :func:`os.stat` and :meth:`os.DirEntry.stat`: check for exceptions. +Previously, on Python built in debug mode, these functions could trigger a +fatal Python error (and abort the process) when a function succeeded with an +exception set. Patch by Victor Stinner. + +.. + +.. date: 2023-09-20-07-38-14 +.. gh-issue: 109599 +.. nonce: IaSLJz +.. section: Library + +Expose the type of PyCapsule objects as ``types.CapsuleType``. + +.. + +.. date: 2023-09-19-17-56-24 +.. gh-issue: 109109 +.. nonce: WJvvX2 +.. section: Library + +You can now get the raw TLS certificate chains from TLS connections via +:meth:`ssl.SSLSocket.get_verified_chain` and +:meth:`ssl.SSLSocket.get_unverified_chain` methods. + +Contributed by Mateusz Nowak. + +.. + +.. date: 2023-09-19-01-22-43 +.. gh-issue: 109559 +.. nonce: ijaycU +.. section: Library + +Update :mod:`unicodedata` database to Unicode 15.1.0. + +.. + +.. date: 2023-09-18-07-43-22 +.. gh-issue: 109543 +.. nonce: 1tOGoV +.. section: Library + +Remove unnecessary :func:`hasattr` check during :data:`typing.TypedDict` +creation. + +.. + +.. date: 2023-09-16-15-44-16 +.. gh-issue: 109495 +.. nonce: m2H5Bk +.. section: Library + +Remove unnecessary extra ``__slots__`` in :py:class:`datetime`\'s pure +python implementation to reduce memory size, as they are defined in the +superclass. Patch by James Hilton-Balfe + +.. + +.. date: 2023-09-15-17-12-53 +.. gh-issue: 109461 +.. nonce: VNFPTK +.. section: Library + +:mod:`logging`: Use a context manager for lock acquisition. + +.. + +.. date: 2023-09-15-12-20-23 +.. gh-issue: 109096 +.. nonce: VksX1D +.. section: Library + +:class:`http.server.CGIHTTPRequestHandler` has been deprecated for removal +in 3.15. Its design is old and the web world has long since moved beyond +CGI. + +.. + +.. date: 2023-09-15-10-42-30 +.. gh-issue: 109409 +.. nonce: RlffA3 +.. section: Library + +Fix error when it was possible to inherit a frozen dataclass from multiple +parents some of which were possibly not frozen. + +.. + +.. date: 2023-09-13-17-22-44 +.. gh-issue: 109375 +.. nonce: ijJHZ9 +.. section: Library + +The :mod:`pdb` ``alias`` command now prevents registering aliases without +arguments. + +.. + +.. date: 2023-09-12-13-01-55 +.. gh-issue: 109319 +.. nonce: YaCMtW +.. section: Library + +Deprecate the ``dis.HAVE_ARGUMENT`` field in favour of ``dis.hasarg``. + +.. + +.. date: 2023-09-11-00-32-18 +.. gh-issue: 107219 +.. nonce: 3zqyFT +.. section: Library + +Fix a race condition in ``concurrent.futures``. When a process in the +process pool was terminated abruptly (while the future was running or +pending), close the connection write end. If the call queue is blocked on +sending bytes to a worker process, closing the connection write end +interrupts the send, so the queue can be closed. Patch by Victor Stinner. + +.. + +.. date: 2023-09-10-20-23-20 +.. gh-issue: 66143 +.. nonce: 71xvgL +.. section: Library + +The :class:`codecs.CodecInfo` object has been made copyable and pickleable. +Patched by Robert Lehmann and Furkan Onder. + +.. + +.. date: 2023-09-09-17-09-54 +.. gh-issue: 109187 +.. nonce: dIayNW +.. section: Library + +:meth:`pathlib.Path.resolve` now treats symlink loops like other errors: in +strict mode, :exc:`OSError` is raised, and in non-strict mode, no exception +is raised. + +.. + +.. date: 2023-09-09-15-08-37 +.. gh-issue: 50644 +.. nonce: JUAZOh +.. section: Library + +Attempts to pickle or create a shallow or deep copy of :mod:`codecs` streams +now raise a TypeError. Previously, copying failed with a RecursionError, +while pickling produced wrong results that eventually caused unpickling to +fail with a RecursionError. + +.. + +.. date: 2023-09-09-09-05-41 +.. gh-issue: 109174 +.. nonce: OJea5s +.. section: Library + +Add support of :class:`types.SimpleNamespace` in :func:`copy.replace`. + +.. + +.. date: 2023-09-08-22-26-26 +.. gh-issue: 109164 +.. nonce: -9BFWR +.. section: Library + +:mod:`pdb`: Replace :mod:`getopt` with :mod:`argparse` for parsing command +line arguments. + +.. + +.. date: 2023-09-08-19-44-01 +.. gh-issue: 109151 +.. nonce: GkzkQu +.. section: Library + +Enable ``readline`` editing features in the :ref:`sqlite3 command-line +interface ` (``python -m sqlite3``). + +.. + +.. date: 2023-09-08-12-09-55 +.. gh-issue: 108987 +.. nonce: x5AIG8 +.. section: Library + +Fix :func:`_thread.start_new_thread` race condition. If a thread is created +during Python finalization, the newly spawned thread now exits immediately +instead of trying to access freed memory and lead to a crash. Patch by +Victor Stinner. + +.. + +.. date: 2023-09-06-19-33-41 +.. gh-issue: 108682 +.. nonce: 35Xnc5 +.. section: Library + +Enum: require ``names=()`` or ``type=...`` to create an empty enum using the +functional syntax. + +.. + +.. date: 2023-09-06-14-47-28 +.. gh-issue: 109033 +.. nonce: piUzDx +.. section: Library + +Exceptions raised by os.utime builtin function now include the related +filename + +.. + +.. date: 2023-09-06-06-17-23 +.. gh-issue: 108843 +.. nonce: WJMhsS +.. section: Library + +Fix an issue in :func:`ast.unparse` when unparsing f-strings containing many +quote types. + +.. + +.. date: 2023-09-03-04-37-52 +.. gh-issue: 108469 +.. nonce: kusj40 +.. section: Library + +:func:`ast.unparse` now supports new :term:`f-string` syntax introduced in +Python 3.12. Note that the :term:`f-string` quotes are reselected for +simplicity under the new syntax. (Patch by Steven Sun) + +.. + +.. date: 2023-09-01-13-14-08 +.. gh-issue: 108751 +.. nonce: 2itqwe +.. section: Library + +Add :func:`copy.replace` function which allows to create a modified copy of +an object. It supports named tuples, dataclasses, and many other objects. + +.. + +.. date: 2023-08-30-20-10-28 +.. gh-issue: 108682 +.. nonce: c2gzLQ +.. section: Library + +Enum: raise :exc:`TypeError` if ``super().__new__()`` is called from a +custom ``__new__``. + +.. + +.. date: 2023-08-29-11-29-15 +.. gh-issue: 108278 +.. nonce: -UhsnJ +.. section: Library + +Deprecate passing the callback callable by keyword for the following +:class:`sqlite3.Connection` APIs: + +* :meth:`~sqlite3.Connection.set_authorizer` +* :meth:`~sqlite3.Connection.set_progress_handler` +* :meth:`~sqlite3.Connection.set_trace_callback` + +The affected parameters will become positional-only in Python 3.15. + +Patch by Erlend E. Aasland. + +.. + +.. date: 2023-08-26-12-35-39 +.. gh-issue: 105829 +.. nonce: kyYhWI +.. section: Library + +Fix concurrent.futures.ProcessPoolExecutor deadlock + +.. + +.. date: 2023-08-26-08-38-57 +.. gh-issue: 108295 +.. nonce: Pn0QRM +.. section: Library + +Fix crashes related to use of weakrefs on :data:`typing.TypeVar`. + +.. + +.. date: 2023-08-25-00-14-34 +.. gh-issue: 108463 +.. nonce: mQApp_ +.. section: Library + +Make expressions/statements work as expected in pdb + +.. + +.. date: 2023-08-23-22-08-32 +.. gh-issue: 108277 +.. nonce: KLV-6T +.. section: Library + +Add :func:`os.timerfd_create`, :func:`os.timerfd_settime`, +:func:`os.timerfd_gettime`, :func:`os.timerfd_settime_ns`, and +:func:`os.timerfd_gettime_ns` to provide a low level interface for Linux's +timer notification file descriptor. + +.. + +.. date: 2023-08-23-17-34-39 +.. gh-issue: 107811 +.. nonce: 3Fng72 +.. section: Library + +:mod:`tarfile`: extraction of members with overly large UID or GID (e.g. on +an OS with 32-bit :c:type:`!id_t`) now fails in the same way as failing to +set the ID. + +.. + +.. date: 2023-08-22-22-29-42 +.. gh-issue: 64662 +.. nonce: jHl_Bt +.. section: Library + +Fix support for virtual tables in :meth:`sqlite3.Connection.iterdump`. Patch +by Aviv Palivoda. + +.. + +.. date: 2023-08-22-17-27-12 +.. gh-issue: 108111 +.. nonce: N7a4u_ +.. section: Library + +Fix a regression introduced in GH-101251 for 3.12, resulting in an incorrect +offset calculation in :meth:`gzip.GzipFile.seek`. + +.. + +.. date: 2023-08-22-16-18-49 +.. gh-issue: 108294 +.. nonce: KEeUcM +.. section: Library + +:func:`time.sleep` now raises an auditing event. + +.. + +.. date: 2023-08-22-13-51-10 +.. gh-issue: 108278 +.. nonce: 11d_qG +.. section: Library + +Deprecate passing name, number of arguments, and the callable as keyword +arguments, for the following :class:`sqlite3.Connection` APIs: + +* :meth:`~sqlite3.Connection.create_function` +* :meth:`~sqlite3.Connection.create_aggregate` + +The affected parameters will become positional-only in Python 3.15. + +Patch by Erlend E. Aasland. + +.. + +.. date: 2023-08-22-12-05-47 +.. gh-issue: 108322 +.. nonce: kf3NJX +.. section: Library + +Speed-up NormalDist.samples() by using the inverse CDF method instead of +calling random.gauss(). + +.. + +.. date: 2023-08-18-22-58-07 +.. gh-issue: 83417 +.. nonce: 61J4yM +.. section: Library + +Add the ability for venv to create a ``.gitignore`` file which causes the +created environment to be ignored by Git. It is on by default when venv is +called via its CLI. + +.. + +.. date: 2023-08-17-14-45-25 +.. gh-issue: 105736 +.. nonce: NJsH7r +.. section: Library + +Harmonized the pure Python version of :class:`~collections.OrderedDict` with +the C version. Now, both versions set up their internal state in +``__new__``. Formerly, the pure Python version did the set up in +``__init__``. + +.. + +.. date: 2023-08-17-12-59-35 +.. gh-issue: 108083 +.. nonce: 9J7UcT +.. section: Library + +Fix bugs in the constructor of :mod:`sqlite3.Connection` and +:meth:`sqlite3.Connection.close` where exceptions could be leaked. Patch by +Erlend E. Aasland. + +.. + +.. date: 2023-08-16-21-20-55 +.. gh-issue: 107932 +.. nonce: I7hFsp +.. section: Library + +Fix ``dis`` module to properly report and display bytecode that do not have +source lines. + +.. + +.. date: 2023-08-16-14-30-13 +.. gh-issue: 105539 +.. nonce: 29lA6c +.. section: Library + +:mod:`sqlite3` now emits an :exc:`ResourceWarning` if a +:class:`sqlite3.Connection` object is not :meth:`closed +` explicitly. Patch by Erlend E. Aasland. + +.. + +.. date: 2023-08-16-00-24-07 +.. gh-issue: 107995 +.. nonce: TlTp5t +.. section: Library + +The ``__module__`` attribute on instances of +:class:`functools.cached_property` is now set to the name of the module in +which the cached_property is defined, rather than "functools". This means +that doctests in ``cached_property`` docstrings are now properly collected +by the :mod:`doctest` module. Patch by Tyler Smart. + +.. + +.. date: 2023-08-15-18-20-00 +.. gh-issue: 107963 +.. nonce: 20g5BG +.. section: Library + +Fix :func:`multiprocessing.set_forkserver_preload` to check the given list +of modules names. Patch by Donghee Na. + +.. + +.. date: 2023-08-14-23-11-11 +.. gh-issue: 106242 +.. nonce: 71HMym +.. section: Library + +Fixes :func:`os.path.normpath` to handle embedded null characters without +truncating the path. + +.. + +.. date: 2023-08-14-20-18-59 +.. gh-issue: 81555 +.. nonce: cWdP4a +.. section: Library + +:mod:`xml.dom.minidom` now only quotes ``"`` in attributes. + +.. + +.. date: 2023-08-14-20-01-14 +.. gh-issue: 50002 +.. nonce: E-bpj8 +.. section: Library + +:mod:`xml.dom.minidom` now preserves whitespaces in attributes. + +.. + +.. date: 2023-08-14-19-49-02 +.. gh-issue: 93057 +.. nonce: 5nJwO5 +.. section: Library + +Passing more than one positional argument to :func:`sqlite3.connect` and the +:class:`sqlite3.Connection` constructor is deprecated. The remaining +parameters will become keyword-only in Python 3.15. Patch by Erlend E. +Aasland. + +.. + +.. date: 2023-08-14-17-15-59 +.. gh-issue: 76913 +.. nonce: LLD0rT +.. section: Library + +Add *merge_extra* parameter/feature to :class:`logging.LoggerAdapter` + +.. + +.. date: 2023-08-14-11-18-13 +.. gh-issue: 107913 +.. nonce: 4ooY6i +.. section: Library + +Fix possible losses of ``errno`` and ``winerror`` values in :exc:`OSError` +exceptions if they were cleared or modified by the cleanup code before +creating the exception object. + +.. + +.. date: 2023-08-10-17-36-22 +.. gh-issue: 107845 +.. nonce: dABiMJ +.. section: Library + +:func:`tarfile.data_filter` now takes the location of symlinks into account +when determining their target, so it will no longer reject some valid +tarballs with ``LinkOutsideDestinationError``. + +.. + +.. date: 2023-08-09-15-37-20 +.. gh-issue: 107812 +.. nonce: CflAXa +.. section: Library + +Extend socket's netlink support to the FreeBSD platform. + +.. + +.. date: 2023-08-09-13-49-37 +.. gh-issue: 107805 +.. nonce: ezem0k +.. section: Library + +Fix signatures of module-level generated functions in :mod:`turtle`. + +.. + +.. date: 2023-08-08-19-57-45 +.. gh-issue: 107782 +.. nonce: mInjFE +.. section: Library + +:mod:`pydoc` is now able to show signatures which are not representable in +Python, e.g. for ``getattr`` and ``dict.pop``. + +.. + +.. date: 2023-08-08-16-09-59 +.. gh-issue: 56166 +.. nonce: WUMhYG +.. section: Library + +Deprecate passing optional arguments *maxsplit*, *count* and *flags* in +module-level functions :func:`re.split`, :func:`re.sub` and :func:`re.subn` +as positional. They should only be passed by keyword. + +.. + +.. date: 2023-08-07-14-24-42 +.. gh-issue: 107710 +.. nonce: xfOCfj +.. section: Library + +Speed up :func:`logging.getHandlerNames`. + +.. + +.. date: 2023-08-07-14-12-07 +.. gh-issue: 107715 +.. nonce: 238r2f +.. section: Library + +Fix :meth:`doctest.DocTestFinder.find` in presence of class names with +special characters. Patch by Gertjan van Zwieten. + +.. + +.. date: 2023-08-06-15-29-00 +.. gh-issue: 100814 +.. nonce: h195gW +.. section: Library + +Passing a callable object as an option value to a Tkinter image now raises +the expected TclError instead of an AttributeError. + +.. + +.. date: 2023-08-06-10-52-12 +.. gh-issue: 72684 +.. nonce: Ls2mSf +.. section: Library + +Add :mod:`tkinter` widget methods: :meth:`!tk_busy_hold`, +:meth:`!tk_busy_configure`, :meth:`!tk_busy_cget`, :meth:`!tk_busy_forget`, +:meth:`!tk_busy_current`, and :meth:`!tk_busy_status`. + +.. + +.. date: 2023-08-05-05-10-41 +.. gh-issue: 106684 +.. nonce: P9zRXb +.. section: Library + +Raise :exc:`ResourceWarning` when :class:`asyncio.StreamWriter` is not +closed leading to memory leaks. Patch by Kumar Aditya. + +.. + +.. date: 2023-08-04-19-00-53 +.. gh-issue: 107465 +.. nonce: Vc1Il3 +.. section: Library + +Add :meth:`pathlib.Path.from_uri` classmethod. + +.. + +.. date: 2023-08-03-12-52-19 +.. gh-issue: 107077 +.. nonce: -pzHD6 +.. section: Library + +Seems that in some conditions, OpenSSL will return ``SSL_ERROR_SYSCALL`` +instead of ``SSL_ERROR_SSL`` when a certification verification has failed, +but the error parameters will still contain ``ERR_LIB_SSL`` and +``SSL_R_CERTIFICATE_VERIFY_FAILED``. We are now detecting this situation and +raising the appropiate ``ssl.SSLCertVerificationError``. Patch by Pablo +Galindo + +.. + +.. date: 2023-08-03-11-31-11 +.. gh-issue: 107576 +.. nonce: pO_s9I +.. section: Library + +Fix :func:`types.get_original_bases` to only return :attr:`!__orig_bases__` +if it is present on ``cls`` directly. Patch by James Hilton-Balfe. + +.. + +.. date: 2023-08-01-21-43-58 +.. gh-issue: 105481 +.. nonce: cl2ajS +.. section: Library + +Remove ``opcode.is_pseudo``, ``opcode.MIN_PSEUDO_OPCODE`` and +``opcode.MAX_PSEUDO_OPCODE``, which were added in 3.12, were never +documented and were not intended to be used externally. + +.. + +.. date: 2023-08-01-15-17-20 +.. gh-issue: 105481 +.. nonce: vMbmj_ +.. section: Library + +:data:`opcode.ENABLE_SPECIALIZATION` (which was added in 3.12 but never +documented or intended for external usage) is moved to +:data:`_opcode.ENABLE_SPECIALIZATION` where tests can access it. + +.. + +.. date: 2023-07-31-07-36-24 +.. gh-issue: 107396 +.. nonce: 3_Kh6D +.. section: Library + +tarfiles; Fixed use before assignment of self.exception for gzip +decompression + +.. + +.. date: 2023-07-29-02-36-50 +.. gh-issue: 107409 +.. nonce: HG27Nu +.. section: Library + +Set :attr:`!__wrapped__` attribute in :func:`reprlib.recursive_repr`. + +.. + +.. date: 2023-07-29-02-01-24 +.. gh-issue: 107406 +.. nonce: ze6sQP +.. section: Library + +Implement new :meth:`__repr__` method for :class:`struct.Struct`. Now it +returns ``Struct()``. + +.. + +.. date: 2023-07-28-14-56-35 +.. gh-issue: 107369 +.. nonce: bvTq8F +.. section: Library + +Optimize :func:`textwrap.indent`. It is ~30% faster for large input. Patch +by Inada Naoki. + +.. + +.. date: 2023-07-26-22-52-48 +.. gh-issue: 78722 +.. nonce: 6SKBLt +.. section: Library + +Fix issue where :meth:`pathlib.Path.iterdir` did not raise :exc:`OSError` +until iterated. + +.. + +.. date: 2023-07-23-13-05-32 +.. gh-issue: 105578 +.. nonce: XAQtyR +.. section: Library + +Deprecate :class:`typing.AnyStr` in favor of the new Type Parameter syntax. +See PEP 695. + +.. + +.. date: 2023-07-23-12-26-23 +.. gh-issue: 62519 +.. nonce: w8-81X +.. section: Library + +Make :func:`gettext.pgettext` search plural definitions when translation is +not found. + +.. + +.. date: 2023-07-22-21-57-34 +.. gh-issue: 107089 +.. nonce: Dnget2 +.. section: Library + +Shelves opened with :func:`shelve.open` have a much faster :meth:`clear` +method. Patch by James Cave. + +.. + +.. date: 2023-07-22-16-44-58 +.. gh-issue: 82500 +.. nonce: cQYoPj +.. section: Library + +Fix overflow on 32-bit systems with :mod:`asyncio` :func:`os.sendfile` +implemention. + +.. + +.. date: 2023-07-22-15-51-33 +.. gh-issue: 83006 +.. nonce: 21zaCz +.. section: Library + +Document behavior of :func:`shutil.disk_usage` for non-mounted filesystems +on Unix. + +.. + +.. date: 2023-07-22-14-29-34 +.. gh-issue: 65495 +.. nonce: fw84qM +.. section: Library + +Use lowercase ``mail from`` and ``rcpt to`` in :class:`smptlib.SMTP`. + +.. + +.. date: 2023-07-22-13-09-28 +.. gh-issue: 106186 +.. nonce: EIsUNG +.. section: Library + +Do not report ``MultipartInvariantViolationDefect`` defect when the +:class:`email.parser.Parser` class is used to parse emails with +``headersonly=True``. + +.. + +.. date: 2023-07-22-12-53-53 +.. gh-issue: 105002 +.. nonce: gkfsW0 +.. section: Library + +Fix invalid result from :meth:`PurePath.relative_to` method when attempting +to walk a "``..``" segment in *other* with *walk_up* enabled. A +:exc:`ValueError` exception is now raised in this case. + +.. + +.. date: 2023-07-20-06-00-35 +.. gh-issue: 106739 +.. nonce: W1hygr +.. section: Library + +Add the ``rtype_cache`` to the warning message (as an addition to the type +of leaked objects and the number of leaked objects already included in the +message) to make debugging leaked objects easier when the multiprocessing +resource tracker process finds leaked objects at shutdown. This helps more +quickly identify what was leaked and/or why the leaked object was not +properly cleaned up. + +.. + +.. date: 2023-07-19-10-45-24 +.. gh-issue: 106751 +.. nonce: 3HJ1of +.. section: Library + +Optimize :meth:`SelectSelector.select` for many iteration case. Patch By +Donghee Na. + +.. + +.. date: 2023-07-19-09-11-08 +.. gh-issue: 106751 +.. nonce: U9nD_B +.. section: Library + +Optimize :meth:`_PollLikeSelector.select` for many iteration case. + +.. + +.. date: 2023-07-18-23-05-12 +.. gh-issue: 106751 +.. nonce: tVvzN_ +.. section: Library + +Optimize :meth:`KqueueSelector.select` for many iteration case. Patch By +Donghee Na. + +.. + +.. date: 2023-07-17-21-45-15 +.. gh-issue: 106831 +.. nonce: RqVq9X +.. section: Library + +Fix potential missing ``NULL`` check of ``d2i_SSL_SESSION`` result in +``_ssl.c``. + +.. + +.. date: 2023-07-17-16-46-00 +.. gh-issue: 105481 +.. nonce: fek_Nn +.. section: Library + +The various opcode lists in the :mod:`dis` module are now generated from +bytecodes.c instead of explicitly constructed in opcode.py. + +.. + +.. date: 2023-07-16-23-59-33 +.. gh-issue: 106727 +.. nonce: bk3uCu +.. section: Library + +Make :func:`inspect.getsource` smarter for class for same name definitions + +.. + +.. date: 2023-07-16-10-40-34 +.. gh-issue: 106789 +.. nonce: NvyE3C +.. section: Library + +Remove import of :mod:`pprint` from :mod:`sysconfig`. + +.. + +.. date: 2023-07-15-12-52-50 +.. gh-issue: 105726 +.. nonce: NGthO8 +.. section: Library + +Added ``__slots__`` to :class:`contextlib.AbstractContextManager` and +:class:`contextlib.AbstractAsyncContextManager` so that child classes can +use ``__slots__``. + +.. + +.. date: 2023-07-15-10-24-56 +.. gh-issue: 106774 +.. nonce: FJcqCj +.. section: Library + +Update the bundled copy of pip to version 23.2.1. + +.. + +.. date: 2023-07-14-20-31-09 +.. gh-issue: 106751 +.. nonce: 52F6yQ +.. section: Library + +:mod:`selectors`: Optimize ``EpollSelector.select()`` code by moving some +code outside of the loop. + +.. + +.. date: 2023-07-14-16-54-13 +.. gh-issue: 106752 +.. nonce: BT1Yxw +.. section: Library + +Fixed several bugs in zipfile.Path, including: in +:meth:`zipfile.Path.match`, Windows separators are no longer honored (and +never were meant to be); Fixed ``name``/``suffix``/``suffixes``/``stem`` +operations when no filename is present and the Path is not at the root of +the zipfile; Reworked glob for performance and more correct matching +behavior. + +.. + +.. date: 2023-07-14-14-53-58 +.. gh-issue: 105293 +.. nonce: kimf_i +.. section: Library + +Remove call to ``SSL_CTX_set_session_id_context`` during client side context +creation in the :mod:`ssl` module. + +.. + +.. date: 2023-07-14-01-47-39 +.. gh-issue: 106734 +.. nonce: eMYSoz +.. section: Library + +Disable tab completion in multiline mode of :mod:`pdb` + +.. + +.. date: 2023-07-13-16-04-15 +.. gh-issue: 105481 +.. nonce: pYSwMj +.. section: Library + +Expose opcode metadata through :mod:`_opcode`. + +.. + +.. date: 2023-07-12-10-59-08 +.. gh-issue: 106670 +.. nonce: goQ2Sy +.. section: Library + +Add the new ``exceptions`` command to the Pdb debugger. It makes it possible +to move between chained exceptions when using post mortem debugging. + +.. + +.. date: 2023-07-12-04-58-45 +.. gh-issue: 106602 +.. nonce: dGCcXe +.. section: Library + +Add __copy__ and __deepcopy__ in :mod:`enum` + +.. + +.. date: 2023-07-12-03-04-45 +.. gh-issue: 106664 +.. nonce: ZeUG78 +.. section: Library + +:mod:`selectors`: Add ``_SelectorMapping.get()`` method and optimize +``_SelectorMapping.__getitem__()``. + +.. + +.. date: 2023-07-11-16-36-22 +.. gh-issue: 106628 +.. nonce: Kx8Zvc +.. section: Library + +Speed up parsing of emails by about 20% by not compiling a new regular +expression for every single email. + +.. + +.. date: 2023-07-11-12-34-04 +.. gh-issue: 89427 +.. nonce: GOkCp9 +.. section: Library + +Set the environment variable ``VIRTUAL_ENV_PROMPT`` at :mod:`venv` +activation, even when ``VIRTUAL_ENV_DISABLE_PROMPT`` is set. + +.. + +.. date: 2023-07-11-09-25-40 +.. gh-issue: 106530 +.. nonce: VgXrMx +.. section: Library + +Revert a change to :func:`colorsys.rgb_to_hls` that caused division by zero +for certain almost-white inputs. Patch by Terry Jan Reedy. + +.. + +.. date: 2023-07-11-08-56-40 +.. gh-issue: 106584 +.. nonce: g-SBtC +.. section: Library + +Fix exit code for ``unittest`` if all tests are skipped. Patch by Egor +Eliseev. + +.. + +.. date: 2023-07-09-13-10-54 +.. gh-issue: 106566 +.. nonce: NN35-U +.. section: Library + +Optimize ``(?!)`` (pattern which alwais fails) in regular expressions. + +.. + +.. date: 2023-07-09-01-59-24 +.. gh-issue: 106554 +.. nonce: 37c53J +.. section: Library + +:mod:`selectors`: Reduce Selector overhead by using a ``dict.get()`` to +lookup file descriptors. + +.. + +.. date: 2023-07-09-00-36-33 +.. gh-issue: 106558 +.. nonce: Zqsj6F +.. section: Library + +Remove ref cycle in callers of +:func:`~multiprocessing.managers.convert_to_error` by deleting ``result`` +from scope in a ``finally`` block. + +.. + +.. date: 2023-07-07-21-15-17 +.. gh-issue: 100502 +.. nonce: Iici1B +.. section: Library + +Add :attr:`pathlib.PurePath.pathmod` class attribute that stores the +implementation of :mod:`os.path` used for low-level path operations: either +``posixpath`` or ``ntpath``. + +.. + +.. date: 2023-07-07-18-22-07 +.. gh-issue: 106527 +.. nonce: spHQ0W +.. section: Library + +Reduce overhead to add and remove :mod:`asyncio` readers and writers. + +.. + +.. date: 2023-07-07-17-44-03 +.. gh-issue: 106524 +.. nonce: XkBV8h +.. section: Library + +Fix crash in :func:`!_sre.template` with templates containing invalid group +indices. + +.. + +.. date: 2023-07-07-16-19-59 +.. gh-issue: 106531 +.. nonce: eMfNm8 +.. section: Library + +Removed ``_legacy`` and the names it provided from ``importlib.resources``: +``Resource``, ``contents``, ``is_resource``, ``open_binary``, ``open_text``, +``path``, ``read_binary``, and ``read_text``. + +.. + +.. date: 2023-07-07-14-52-31 +.. gh-issue: 106052 +.. nonce: ak8nbs +.. section: Library + +:mod:`re` module: fix the matching of possessive quantifiers in the case of +a subpattern containing backtracking. + +.. + +.. date: 2023-07-07-13-47-28 +.. gh-issue: 106510 +.. nonce: 9n5BdC +.. section: Library + +Improve debug output for atomic groups in regular expressions. + +.. + +.. date: 2023-07-07-03-05-58 +.. gh-issue: 106503 +.. nonce: ltfeiH +.. section: Library + +Fix ref cycle in :class:`!asyncio._SelectorSocketTransport` by removing +``_write_ready`` in ``close``. + +.. + +.. date: 2023-07-05-14-34-10 +.. gh-issue: 105497 +.. nonce: HU5u89 +.. section: Library + +Fix flag mask inversion when unnamed flags exist. + +.. + +.. date: 2023-07-05-13-08-23 +.. gh-issue: 90876 +.. nonce: Qvlkfl +.. section: Library + +Prevent :mod:`multiprocessing.spawn` from failing to *import* in +environments where ``sys.executable`` is ``None``. This regressed in 3.11 +with the addition of support for path-like objects in multiprocessing. + +.. + +.. date: 2023-07-04-07-25-30 +.. gh-issue: 106403 +.. nonce: GmefbV +.. section: Library + +Instances of :class:`typing.TypeVar`, :class:`typing.ParamSpec`, +:class:`typing.ParamSpecArgs`, :class:`typing.ParamSpecKwargs`, and +:class:`typing.TypeVarTuple` once again support weak references, fixing a +regression introduced in Python 3.12.0 beta 1. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-07-03-20-23-56 +.. gh-issue: 89812 +.. nonce: cFkDOE +.. section: Library + +Add private ``pathlib._PathBase`` class, which provides experimental support +for virtual filesystems, and may be made public in a future version of +Python. + +.. + +.. date: 2023-07-03-15-09-44 +.. gh-issue: 106292 +.. nonce: 3npldV +.. section: Library + +Check for an instance-dict cached value in the :meth:`__get__` method of +:func:`functools.cached_property`. This better matches the pre-3.12 behavior +and improves compatibility for users subclassing +:func:`functools.cached_property` and adding a :meth:`__set__` method. + +.. + +.. date: 2023-07-03-03-46-20 +.. gh-issue: 106350 +.. nonce: LLcTEe +.. section: Library + +Detect possible memory allocation failure in the libtommath function +:c:func:`mp_init` used by the ``_tkinter`` module. + +.. + +.. date: 2023-07-02-10-56-41 +.. gh-issue: 106330 +.. nonce: QSkIUH +.. section: Library + +Fix incorrect matching of empty paths in :meth:`pathlib.PurePath.match`. +This bug was introduced in Python 3.12.0 beta 1. + +.. + +.. date: 2023-07-01-16-51-55 +.. gh-issue: 106309 +.. nonce: hSlB17 +.. section: Library + +Deprecate :func:`typing.no_type_check_decorator`. No major type checker ever +added support for this decorator. Patch by Alex Waygood. + +.. + +.. date: 2023-07-01-16-40-54 +.. gh-issue: 102541 +.. nonce: C1ahtk +.. section: Library + +Make pydoc.doc catch bad module ImportError when output stream is not None. + +.. + +.. date: 2023-06-30-16-42-44 +.. gh-issue: 106263 +.. nonce: tk-t93 +.. section: Library + +Fix crash when calling ``repr`` with a manually constructed SignalDict +object. Patch by Charlie Zhao. + +.. + +.. date: 2023-06-29-15-10-44 +.. gh-issue: 106236 +.. nonce: EAIX4l +.. section: Library + +Replace ``assert`` statements with ``raise RuntimeError`` in +:mod:`threading`, so that ``_DummyThread`` cannot be joined even with +``-OO``. + +.. + +.. date: 2023-06-29-12-40-52 +.. gh-issue: 106238 +.. nonce: VulKb9 +.. section: Library + +Fix rare concurrency bug in lock acquisition by the logging package. + +.. + +.. date: 2023-06-27-23-22-37 +.. gh-issue: 106152 +.. nonce: ya5jBT +.. section: Library + +Added PY_THROW event hook for :mod:`cProfile` for generators + +.. + +.. date: 2023-06-25-12-28-55 +.. gh-issue: 106075 +.. nonce: W7tMRb +.. section: Library + +Added ``asyncio.taskgroups.__all__`` to ``asyncio.__all__`` for export in +star imports. + +.. + +.. date: 2023-06-25-06-57-24 +.. gh-issue: 104527 +.. nonce: TJEUkd +.. section: Library + +Zipapp will now skip over apending an archive to itself. + +.. + +.. date: 2023-06-23-22-52-24 +.. gh-issue: 106046 +.. nonce: OdLiLJ +.. section: Library + +Improve the error message from :func:`os.fspath` if called on an object +where ``__fspath__`` is set to ``None``. Patch by Alex Waygood. + +.. + +.. date: 2023-06-22-15-21-11 +.. gh-issue: 105987 +.. nonce: T7Kzrb +.. section: Library + +Fix crash due to improper reference counting in :mod:`asyncio` eager task +factory internal routines. + +.. + +.. date: 2023-06-21-19-04-27 +.. gh-issue: 105974 +.. nonce: M47n3t +.. section: Library + +Fix bug where a :class:`typing.Protocol` class that had one or more +non-callable members would raise :exc:`TypeError` when :func:`issubclass` +was called against it, even if it defined a custom ``__subclasshook__`` +method. The behaviour in Python 3.11 and lower -- which has now been +restored -- was not to raise :exc:`TypeError` in these situations if a +custom ``__subclasshook__`` method was defined. Patch by Alex Waygood. + +.. + +.. date: 2023-06-20-23-18-45 +.. gh-issue: 96145 +.. nonce: o5dTRM +.. section: Library + +Reverted addition of ``json.AttrDict``. + +.. + +.. date: 2023-06-19-22-20-41 +.. gh-issue: 89812 +.. nonce: z2l_e8 +.. section: Library + +Add :exc:`pathlib.UnsupportedOperation`, which is raised instead of +:exc:`NotImplementedError` when a path operation isn't supported. + +.. + +.. date: 2023-06-19-11-31-55 +.. gh-issue: 105808 +.. nonce: NL-quu +.. section: Library + +Fix a regression introduced in GH-101251 for 3.12, causing +:meth:`gzip.GzipFile.flush` to not flush the compressor (nor pass along the +``zip_mode`` argument). + +.. + +.. date: 2023-06-17-12-13-57 +.. gh-issue: 105481 +.. nonce: KgBH5w +.. section: Library + +:func:`~dis.stack_effect` no longer raises an exception if an ``oparg`` is +provided for an ``opcode`` that doesn't use its arg, or when it is not +provided for an ``opcode`` that does use it. In the latter case, the stack +effect is returned for ``oparg=0``. + +.. + +.. date: 2023-06-15-18-11-47 +.. gh-issue: 104799 +.. nonce: BcLzbP +.. section: Library + +Enable :func:`ast.unparse` to unparse function and class definitions created +without the new ``type_params`` field from :pep:`695`. Patch by Jelle +Zijlstra. + +.. + +.. date: 2023-06-14-18-41-18 +.. gh-issue: 105793 +.. nonce: YSoykM +.. section: Library + +Add *follow_symlinks* keyword-only argument to :meth:`pathlib.Path.is_dir` +and :meth:`~pathlib.Path.is_file`, defaulting to ``True``. + +.. + +.. date: 2023-06-14-14-32-31 +.. gh-issue: 105570 +.. nonce: sFTtQU +.. section: Library + +Deprecate two methods of creating :class:`typing.TypedDict` classes with 0 +fields using the functional syntax: ``TD = TypedDict("TD")`` and ``TD = +TypedDict("TD", None)``. Both will be disallowed in Python 3.15. To create a +``TypedDict`` class with 0 fields, either use ``class TD(TypedDict): pass`` +or ``TD = TypedDict("TD", {})``. + +.. + +.. date: 2023-06-14-10-27-34 +.. gh-issue: 105745 +.. nonce: l1ttOQ +.. section: Library + +Fix ``webbrowser.Konqueror.open`` method. + +.. + +.. date: 2023-06-13-19-38-12 +.. gh-issue: 105733 +.. nonce: WOp0mG +.. section: Library + +:mod:`ctypes`: Deprecate undocumented :func:`!ctypes.SetPointerType` and +:func:`!ctypes.ARRAY` functions. Patch by Victor Stinner. + +.. + +.. date: 2023-06-12-15-17-34 +.. gh-issue: 105687 +.. nonce: ZUonKm +.. section: Library + +Remove deprecated ``re.template``, ``re.T``, ``re.TEMPLATE``, +``sre_constans.SRE_FLAG_TEMPLATE``. + +.. + +.. date: 2023-06-12-10-40-38 +.. gh-issue: 105684 +.. nonce: yiHkFD +.. section: Library + +Supporting :meth:`asyncio.Task.set_name` is now mandatory for third party +task implementations. The undocumented :func:`!_set_task_name` function +(deprecated since 3.8) has been removed. Patch by Kumar Aditya. + +.. + +.. date: 2023-06-11-22-46-06 +.. gh-issue: 105375 +.. nonce: YkhSNt +.. section: Library + +Fix a bug in :c:func:`!_Unpickler_SetInputStream` where an exception could +end up being overwritten in case of failure. + +.. + +.. date: 2023-06-10-12-20-17 +.. gh-issue: 105626 +.. nonce: XyZein +.. section: Library + +Change the default return value of +:meth:`http.client.HTTPConnection.get_proxy_response_headers` to be ``None`` +and not ``{}``. + +.. + +.. date: 2023-06-09-23-46-23 +.. gh-issue: 105375 +.. nonce: 9KaioS +.. section: Library + +Fix bugs in :mod:`sys` where exceptions could end up being overwritten +because of deferred error handling. + +.. + +.. date: 2023-06-09-23-00-13 +.. gh-issue: 105605 +.. nonce: YuwqxY +.. section: Library + +Harden :mod:`pyexpat` error handling during module initialisation to prevent +exceptions from possibly being overwritten, and objects from being +dereferenced twice. + +.. + +.. date: 2023-06-09-22-52-45 +.. gh-issue: 105375 +.. nonce: 6igkhn +.. section: Library + +Fix bug in :mod:`decimal` where an exception could end up being overwritten. + +.. + +.. date: 2023-06-09-22-45-26 +.. gh-issue: 105375 +.. nonce: 9rp6tG +.. section: Library + +Fix bugs in :mod:`!_datetime` where exceptions could be overwritten in case +of module initialisation failure. + +.. + +.. date: 2023-06-09-22-16-46 +.. gh-issue: 105375 +.. nonce: EgVJOP +.. section: Library + +Fix bugs in :mod:`!_ssl` initialisation which could lead to leaked +references and overwritten exceptions. + +.. + +.. date: 2023-06-09-21-46-52 +.. gh-issue: 105375 +.. nonce: yrJelV +.. section: Library + +Fix a bug in :class:`array.array` where an exception could end up being +overwritten. + +.. + +.. date: 2023-06-09-21-40-45 +.. gh-issue: 105375 +.. nonce: _sZilh +.. section: Library + +Fix bugs in :mod:`_ctypes` where exceptions could end up being overwritten. + +.. + +.. date: 2023-06-09-21-30-59 +.. gh-issue: 105375 +.. nonce: eewafp +.. section: Library + +Fix a bug in the :mod:`posix` module where an exception could be +overwritten. + +.. + +.. date: 2023-06-09-21-25-14 +.. gh-issue: 105375 +.. nonce: 95g1eI +.. section: Library + +Fix bugs in :mod:`!_elementtree` where exceptions could be overwritten. + +.. + +.. date: 2023-06-09-21-11-28 +.. gh-issue: 105375 +.. nonce: 4Mxn7t +.. section: Library + +Fix bugs in :mod:`zoneinfo` where exceptions could be overwritten. + +.. + +.. date: 2023-06-09-21-04-39 +.. gh-issue: 105375 +.. nonce: bTcqS9 +.. section: Library + +Fix bugs in :mod:`errno` where exceptions could be overwritten. + +.. + +.. date: 2023-06-09-20-34-23 +.. gh-issue: 105566 +.. nonce: YxlGg1 +.. section: Library + +Deprecate creating a :class:`typing.NamedTuple` class using keyword +arguments to denote the fields (``NT = NamedTuple("NT", x=int, y=str)``). +This will be disallowed in Python 3.15. Use the class-based syntax or the +functional syntax instead. + +Two methods of creating ``NamedTuple`` classes with 0 fields using the +functional syntax are also deprecated, and will be disallowed in Python +3.15: ``NT = NamedTuple("NT")`` and ``NT = NamedTuple("NT", None)``. To +create a ``NamedTuple`` class with 0 fields, either use ``class +NT(NamedTuple): pass`` or ``NT = NamedTuple("NT", [])``. + +.. + +.. date: 2023-06-09-08-38-30 +.. gh-issue: 105545 +.. nonce: 2q3ysu +.. section: Library + +Remove deprecated in 3.11 ``webbrowser.MacOSXOSAScript._name`` attribute. + +.. + +.. date: 2023-06-08-17-49-46 +.. gh-issue: 105497 +.. nonce: K6Q8nU +.. section: Library + +Fix flag inversion when alias/mask members exist. + +.. + +.. date: 2023-06-08-15-56-45 +.. gh-issue: 105509 +.. nonce: YIG57j +.. section: Library + +:data:`typing.Annotated` is now implemented as an instance of +``typing._SpecialForm`` rather than a class. This should have no user-facing +impact for users of the :mod:`typing` module public API. + +.. + +.. date: 2023-06-08-08-58-36 +.. gh-issue: 105375 +.. nonce: bTcqS9 +.. section: Library + +Fix bugs in :mod:`pickle` where exceptions could be overwritten. + +.. + +.. date: 2023-06-07-00-13-00 +.. gh-issue: 70303 +.. nonce: frwUKH +.. section: Library + +Emit :exc:`FutureWarning` from :meth:`pathlib.Path.glob` and +:meth:`~pathlib.Path.rglob` if the given pattern ends with "``**``". In a +future Python release, patterns with this ending will match both files and +directories. Add a trailing slash to only match directories. + +.. + +.. date: 2023-06-07-00-09-52 +.. gh-issue: 105375 +.. nonce: Y_9D4n +.. section: Library + +Fix a bug in :mod:`sqlite3` where an exception could be overwritten in the +:meth:`collation ` callback. + +.. + +.. date: 2023-06-06-16-00-03 +.. gh-issue: 105382 +.. nonce: A1LgzA +.. section: Library + +Remove *cafile*, *capath* and *cadefault* parameters of the +:func:`urllib.request.urlopen` function, deprecated in Python 3.6. Patch by +Victor Stinner. + +.. + +.. date: 2023-06-06-15-32-44 +.. gh-issue: 105376 +.. nonce: W4oDQp +.. section: Library + +:mod:`logging`: Remove undocumented and untested ``Logger.warn()`` and +``LoggerAdapter.warn()`` methods and ``logging.warn()`` function. Deprecated +since Python 3.3, they were aliases to the :meth:`logging.Logger.warning` +method, :meth:`!logging.LoggerAdapter.warning` method and +:func:`logging.warning` function. Patch by Victor Stinner. + +.. + +.. date: 2023-06-06-11-50-33 +.. gh-issue: 105332 +.. nonce: tmpgRA +.. section: Library + +Revert pickling method from by-name back to by-value. + +.. + +.. date: 2023-06-05-14-43-56 +.. gh-issue: 104554 +.. nonce: pwfKIo +.. section: Library + +Add RTSPS scheme support in urllib.parse + +.. + +.. date: 2023-06-04-23-20-56 +.. gh-issue: 105292 +.. nonce: ns6XQR +.. section: Library + +Add option to :func:`traceback.format_exception_only` to recurse into the +nested exception of a :exc:`BaseExceptionGroup`. + +.. + +.. date: 2023-06-04-12-16-47 +.. gh-issue: 105280 +.. nonce: srRbCe +.. section: Library + +Fix bug where ``isinstance([], collections.abc.Mapping)`` could evaluate to +``True`` if garbage collection happened at the wrong time. The bug was +caused by changes to the implementation of :class:`typing.Protocol` in +Python 3.12. + +.. + +.. date: 2023-06-02-23-32-17 +.. gh-issue: 80480 +.. nonce: savBw9 +.. section: Library + +:mod:`array`: Add ``'w'`` typecode that represents ``Py_UCS4``. + +.. + +.. date: 2023-06-02-14-57-11 +.. gh-issue: 105239 +.. nonce: SAmuuj +.. section: Library + +Fix longstanding bug where ``issubclass(object, typing.Protocol)`` would +evaluate to ``True`` in some edge cases. Patch by Alex Waygood. + +.. + +.. date: 2023-06-02-14-23-41 +.. gh-issue: 104310 +.. nonce: UamCOB +.. section: Library + +In the beta 1 release we added a utility function for extension module +authors, to use when testing their module for support in multiple +interpreters or under a per-interpreter GIL. The name of that function has +changed from ``allowing_all_extensions`` to +``_incompatible_extension_module_restrictions``. The default for the +"disable_check" argument has change from ``True`` to ``False``, to better +match the new function name. + +.. + +.. date: 2023-06-02-02-38-26 +.. gh-issue: 105080 +.. nonce: 2imGMg +.. section: Library + +Fixed inconsistent signature on derived classes for +:func:`inspect.signature` + +.. + +.. date: 2023-05-31-16-58-42 +.. gh-issue: 105144 +.. nonce: Oqfn0V +.. section: Library + +Fix a recent regression in the :mod:`typing` module. The regression meant +that doing ``class Foo(X, typing.Protocol)``, where ``X`` was a class that +had :class:`abc.ABCMeta` as its metaclass, would then cause subsequent +``isinstance(1, X)`` calls to erroneously raise :exc:`TypeError`. Patch by +Alex Waygood. + +.. + +.. date: 2023-05-30-18-45-02 +.. gh-issue: 62948 +.. nonce: 1-5wMR +.. section: Library + +The :class:`io.IOBase` finalizer now logs the ``close()`` method errors with +:data:`sys.unraisablehook`. Previously, errors were ignored silently by +default, and only logged in :ref:`Python Development Mode ` or on +:ref:`Python built on debug mode `. Patch by Victor Stinner. + +.. + +.. date: 2023-05-30-17-39-03 +.. gh-issue: 105096 +.. nonce: pw00FW +.. section: Library + +:mod:`wave`: Deprecate the ``getmark()``, ``setmark()`` and ``getmarkers()`` +methods of the :class:`wave.Wave_read` and :class:`wave.Wave_write` classes. +They will be removed in Python 3.15. Patch by Victor Stinner. + +.. + +.. date: 2023-05-26-21-33-24 +.. gh-issue: 104992 +.. nonce: dbq9WK +.. section: Library + +Remove the untested and undocumented :meth:`!unittest.TestProgram.usageExit` +method, deprecated in Python 3.11. Patch by Hugo van Kemenade. + +.. + +.. date: 2023-05-26-21-24-06 +.. gh-issue: 104996 +.. nonce: aaW78g +.. section: Library + +Improve performance of :class:`pathlib.PurePath` initialisation by deferring +joining of paths when multiple arguments are given. + +.. + +.. date: 2023-05-26-01-31-30 +.. gh-issue: 101588 +.. nonce: RaqxFy +.. section: Library + +Deprecate undocumented copy/deepcopy/pickle support for itertools. + +.. + +.. date: 2023-05-25-23-34-54 +.. gh-issue: 103631 +.. nonce: x5Urye +.. section: Library + +Fix ``pathlib.PurePosixPath(pathlib.PureWindowsPath(...))`` not converting +path separators to restore 3.11 compatible behavior. + +.. + +.. date: 2023-05-25-22-54-20 +.. gh-issue: 104947 +.. nonce: hi6TUr +.. section: Library + +Make comparisons between :class:`pathlib.PureWindowsPath` objects consistent +across Windows and Posix to match 3.11 behavior. + +.. + +.. date: 2023-05-25-17-25-16 +.. gh-issue: 104773 +.. nonce: O6TOMc +.. section: Library + +:pep:`594`: Remove the :mod:`!audioop` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-25-16-50-43 +.. gh-issue: 104773 +.. nonce: pmg0Fr +.. section: Library + +:pep:`594`: Remove the :mod:`!aifc` module, deprecated in Python 3.11. Patch +by Victor Stinner. + +.. + +.. date: 2023-05-25-15-54-02 +.. gh-issue: 104773 +.. nonce: nW-5MI +.. section: Library + +:pep:`594`: Remove the :mod:`!uu` module, deprecated in Python 3.11. Patch +by Victor Stinner. + +.. + +.. date: 2023-05-25-08-50-47 +.. gh-issue: 104935 +.. nonce: -rm1BR +.. section: Library + +Fix bugs with the interaction between :func:`typing.runtime_checkable` and +:class:`typing.Generic` that were introduced by the :pep:`695` +implementation. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-25-00-53-08 +.. gh-issue: 104773 +.. nonce: Iyjtt0 +.. section: Library + +:pep:`594`: Remove the :mod:`!crypt` module and its private :mod:`!_crypt` +extension, deprecated in Python 3.11. Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-23-40-22 +.. gh-issue: 104773 +.. nonce: FHA99J +.. section: Library + +:pep:`594`: Remove the :mod:`!nis` module, deprecated in Python 3.11. Patch +by Victor Stinner. + +.. + +.. date: 2023-05-24-22-50-21 +.. gh-issue: 104898 +.. nonce: UbT2S4 +.. section: Library + +Add missing :attr:`~object.__slots__` to :class:`os.PathLike`. + +.. + +.. date: 2023-05-24-22-47-13 +.. gh-issue: 104773 +.. nonce: itOIf3 +.. section: Library + +:pep:`594`: Remove the :mod:`!xdrlib` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-22-22-03 +.. gh-issue: 104773 +.. nonce: NwpjhZ +.. section: Library + +:pep:`594`: Remove the :mod:`!nntplib` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-21-30-40 +.. gh-issue: 104886 +.. nonce: 8TuV-_ +.. section: Library + +Remove the undocumented :class:`!configparser.LegacyInterpolation` class, +deprecated in the docstring since Python 3.2, and with a deprecation warning +since Python 3.11. Patch by Hugo van Kemenade. + +.. + +.. date: 2023-05-24-20-21-27 +.. gh-issue: 104786 +.. nonce: SmgT5_ +.. section: Library + +Remove kwargs-based :class:`typing.TypedDict` creation + +.. + +.. date: 2023-05-24-19-48-16 +.. gh-issue: 104876 +.. nonce: Z00Qnk +.. section: Library + +Remove the :meth:`!turtle.RawTurtle.settiltangle` method, deprecated in docs +since Python 3.1 and with a deprecation warning since Python 3.11. Patch by +Hugo van Kemenade. + +.. + +.. date: 2023-05-24-18-48-10 +.. gh-issue: 104773 +.. nonce: TrgUeO +.. section: Library + +:pep:`594`: Removed the :mod:`!msilib` package, deprecated in Python 3.11. + +.. + +.. date: 2023-05-24-17-47-25 +.. gh-issue: 104773 +.. nonce: TzUSY2 +.. section: Library + +:pep:`594`: Remove the :mod:`!spwd` module, deprecated in Python 3.11: the +`python-pam project `_ can be used +instead. Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-17-22-56 +.. gh-issue: 75552 +.. nonce: _QlrpQ +.. section: Library + +Removed the ``tkinter.tix`` module, deprecated since Python 3.6. + +.. + +.. date: 2023-05-24-15-57-34 +.. gh-issue: 104773 +.. nonce: IHWRgg +.. section: Library + +:pep:`594`: Remove the :mod:`!chunk` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-15-17-05 +.. gh-issue: 104773 +.. nonce: EmFIQ5 +.. section: Library + +:pep:`594`: Remove the :mod:`!mailcap` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-14-58-13 +.. gh-issue: 104773 +.. nonce: sQaXrY +.. section: Library + +:pep:`594`: Remove the :mod:`!sunau` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-14-30-14 +.. gh-issue: 104780 +.. nonce: nXGIJt +.. section: Library + +:pep:`594`: Remove the :mod:`!ossaudiodev` module, deprecated in Python +3.11. Patch Victor Stinner. + +.. + +.. date: 2023-05-24-11-45-22 +.. gh-issue: 104773 +.. nonce: R0Br4- +.. section: Library + +:pep:`594`: Remove the :mod:`!pipes` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-24-09-55-33 +.. gh-issue: 104873 +.. nonce: BKQ54y +.. section: Library + +Add :func:`typing.get_protocol_members` to return the set of members +defining a :class:`typing.Protocol`. Add :func:`typing.is_protocol` to +check whether a class is a :class:`typing.Protocol`. Patch by Jelle +Zijlstra. + +.. + +.. date: 2023-05-24-09-34-23 +.. gh-issue: 104874 +.. nonce: oqyJSy +.. section: Library + +Document the ``__name__`` and ``__supertype__`` attributes of +:class:`typing.NewType`. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-24-08-45-04 +.. gh-issue: 104835 +.. nonce: bN_B-B +.. section: Library + +Removed the following :mod:`unittest` functions, deprecated in Python 3.11: + +* :func:`!unittest.findTestCases` +* :func:`!unittest.makeSuite` +* :func:`!unittest.getTestCaseNames` + +Use :class:`~unittest.TestLoader` methods instead: + +* :meth:`unittest.TestLoader.loadTestsFromModule` +* :meth:`unittest.TestLoader.loadTestsFromTestCase` +* :meth:`unittest.TestLoader.getTestCaseNames` + +Patch by Hugo van Kemenade. + +.. + +.. date: 2023-05-23-21-25-54 +.. gh-issue: 104804 +.. nonce: 78fiE6 +.. section: Library + +Remove the untested and undocumented :mod:`webbrowser` :class:`!MacOSX` +class, deprecated in Python 3.11. Patch by Hugo van Kemenade. + +.. + +.. date: 2023-05-23-19-53-18 +.. gh-issue: 83863 +.. nonce: eRI5JG +.. section: Library + +Support for using :class:`pathlib.Path` objects as context managers has been +removed. Before Python 3.9, exiting the context manager marked a path as +"closed", which caused some (but not all!) methods to raise when called. +Since Python 3.9, using a path as a context manager does nothing. + +.. + +.. date: 2023-05-23-18-31-49 +.. gh-issue: 104799 +.. nonce: MJYOw6 +.. section: Library + +Adjust the location of the (see :pep:`695`) ``type_params`` field on +:class:`ast.ClassDef`, :class:`ast.AsyncFunctionDef`, and +:class:`ast.FunctionDef` to better preserve backward compatibility. Patch by +Jelle Zijlstra + +.. + +.. date: 2023-05-23-17-43-52 +.. gh-issue: 104797 +.. nonce: NR7KzF +.. section: Library + +Allow :class:`typing.Protocol` classes to inherit from +:class:`collections.abc.Buffer`. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-23-04-01-27 +.. gh-issue: 104783 +.. nonce: QyhIoq +.. section: Library + +Remove ``locale.resetlocale()`` function deprecated in Python 3.11. Patch by +Victor Stinner. + +.. + +.. date: 2023-05-23-03-36-47 +.. gh-issue: 104780 +.. nonce: P4e3Yf +.. section: Library + +Remove the ``2to3`` program and the :mod:`!lib2to3` module, deprecated in +Python 3.11. Patch by Victor Stinner. + +.. + +.. date: 2023-05-23-02-20-13 +.. gh-issue: 104773 +.. nonce: 7K59zr +.. section: Library + +:pep:`594`: Remove the :mod:`!telnetlib` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-23-02-13-11 +.. gh-issue: 104773 +.. nonce: JNiEjv +.. section: Library + +:pep:`594`: Remove the :mod:`!imghdr` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-23-01-47-57 +.. gh-issue: 104773 +.. nonce: I6MQhb +.. section: Library + +:pep:`594`: Remove the :mod:`!cgi`` and :mod:`!cgitb` modules, deprecated in +Python 3.11. Patch by Victor Stinner. + +.. + +.. date: 2023-05-23-01-37-40 +.. gh-issue: 104773 +.. nonce: 8c-GsG +.. section: Library + +:pep:`594`: Remove the :mod:`!sndhdr` module, deprecated in Python 3.11. +Patch by Victor Stinner. + +.. + +.. date: 2023-05-22-18-39-53 +.. gh-issue: 104372 +.. nonce: 7tDRaK +.. section: Library + +On Linux where :mod:`subprocess` can use the ``vfork()`` syscall for faster +spawning, prevent the parent process from blocking other threads by dropping +the GIL while it waits for the vfork'ed child process ``exec()`` outcome. +This prevents spawning a binary from a slow filesystem from blocking the +rest of the application. + +.. + +.. date: 2023-05-19-19-46-22 +.. gh-issue: 99108 +.. nonce: wqCg0t +.. section: Library + +We now release the GIL around built-in :mod:`hashlib` computations of +reasonable size for the SHA families and MD5 hash functions, matching what +our OpenSSL backed hash computations already does. + +.. + +.. date: 2023-05-15-18-57-42 +.. gh-issue: 102613 +.. nonce: YD9yx- +.. section: Library + +Improve performance of :meth:`pathlib.Path.glob` when expanding a pattern +with a non-terminal "``**``" component by filtering walked paths through a +regular expression, rather than calling :func:`os.scandir` more than once on +each directory. + +.. + +.. date: 2023-05-11-23-03-00 +.. gh-issue: 104399 +.. nonce: MMatTP +.. section: Library + +Prepare the ``_tkinter`` module for building with Tcl 9.0 and future +libtommath by replacing usage of deprecated functions +:c:func:`mp_to_unsigned_bin_n` and :c:func:`mp_unsigned_bin_size` when +necessary. + +.. + +.. date: 2023-04-28-09-31-21 +.. gh-issue: 102676 +.. nonce: J8qDRa +.. section: Library + +Add fields ``start_offset``, ``cache_offset``, ``end_offset``, +``baseopname``, ``baseopcode``, ``jump_target`` and ``oparg`` to +:class:`dis.Instruction`. + +.. + +.. date: 2023-04-15-23-26-16 +.. gh-issue: 103558 +.. nonce: w9OzK4 +.. section: Library + +Fixed ``parent`` argument validation mechanism of :mod:`argparse`. Improved +test coverage. + +.. + +.. date: 2023-04-12-03-03-27 +.. gh-issue: 103464 +.. nonce: Oa_8IW +.. section: Library + +Provide helpful usage messages when parsing incorrect :mod:`pdb` commands. + +.. + +.. date: 2023-04-09-05-30-41 +.. gh-issue: 103384 +.. nonce: zAV7iB +.. section: Library + +Generalize the regex pattern ``BaseConfigurator.INDEX_PATTERN`` to allow +spaces and non-alphanumeric characters in keys. + +.. + +.. date: 2023-04-09-03-53-02 +.. gh-issue: 103124 +.. nonce: JspiNN +.. section: Library + +Added multiline statement support for :mod:`pdb` + +.. + +.. date: 2023-04-08-12-43-52 +.. gh-issue: 101162 +.. nonce: yOCd_J +.. section: Library + +Forbid using :func:`builtins.issubclass` with :class:`types.GenericAlias` as +the first argument. + +.. + +.. date: 2023-04-03-08-09-40 +.. gh-issue: 103200 +.. nonce: lq1Etz +.. section: Library + +Fix cache repopulation semantics of zipimport.invalidate_caches(). The cache +is now repopulated upon retrieving files with an invalid cache, not when the +cache is invalidated. + +.. + +.. date: 2023-03-14-01-19-57 +.. gh-issue: 100061 +.. nonce: CiXJYn +.. section: Library + +Fix a bug that causes wrong matches for regular expressions with possessive +qualifier. + +.. + +.. date: 2023-03-12-03-37-03 +.. gh-issue: 77609 +.. nonce: aOQttm +.. section: Library + +Add *follow_symlinks* argument to :meth:`pathlib.Path.glob` and +:meth:`~pathlib.Path.rglob`, defaulting to false. + +.. + +.. date: 2023-03-12-01-17-15 +.. gh-issue: 102541 +.. nonce: LK1adc +.. section: Library + +Hide traceback in :func:`help` prompt, when import failed. + +.. + +.. date: 2023-03-08-19-30-53 +.. gh-issue: 102120 +.. nonce: xkQ5Wr +.. section: Library + +Added a stream mode to ``tarfile`` that allows for reading archives without +caching info about the inner files. + +.. + +.. date: 2023-02-20-15-41-59 +.. gh-issue: 102029 +.. nonce: 9ZPG99 +.. section: Library + +Deprecate passing any arguments to :func:`threading.RLock`. + +.. + +.. date: 2023-02-20-12-00-11 +.. gh-issue: 88233 +.. nonce: o5Zb0t +.. section: Library + +Refactored ``zipfile._strip_extra`` to use higher level abstactions for +extras instead of a heavy-state loop. + +.. + +.. date: 2023-02-18-22-55-48 +.. gh-issue: 102024 +.. nonce: RUmg_D +.. section: Library + +Reduce calls of ``_idle_semaphore.release()`` in +:func:`concurrent.futures.thread._worker`. + +.. + +.. date: 2023-02-17-18-56-46 +.. gh-issue: 73435 +.. nonce: 7sTJHk +.. section: Library + +Add support for recursive wildcards in :meth:`pathlib.PurePath.match`. + +.. + +.. date: 2022-12-24-12-50-54 +.. gh-issue: 84867 +.. nonce: OhaLbU +.. section: Library + +:class:`unittest.TestLoader` no longer loads test cases from exact +:class:`unittest.TestCase` and :class:`unittest.FunctionTestCase` classes. + +.. + +.. date: 2022-11-26-22-05-22 +.. gh-issue: 99203 +.. nonce: j0DUae +.. section: Library + +Restore following CPython <= 3.10.5 behavior of :func:`shutil.make_archive`: +do not create an empty archive if ``root_dir`` is not a directory, and, in +that case, raise :class:`FileNotFoundError` or :class:`NotADirectoryError` +regardless of ``format`` choice. Beyond the brought-back behavior, the +function may now also raise these exceptions in ``dry_run`` mode. + +.. + +.. date: 2022-08-07-11-10-26 +.. gh-issue: 80480 +.. nonce: IFccj3 +.. section: Library + +Emit :exc:`DeprecationWarning` for :mod:`array`'s ``'u'`` type code, +deprecated in docs since Python 3.3. + +.. + +.. date: 2022-07-18-14-20-56 +.. gh-issue: 94924 +.. nonce: X0buz2 +.. section: Library + +:func:`unittest.mock.create_autospec` now properly returns coroutine +functions compatible with :func:`inspect.iscoroutinefunction` + +.. + +.. date: 2022-07-12-18-45-13 +.. gh-issue: 94777 +.. nonce: mOybx7 +.. section: Library + +Fix hanging :mod:`multiprocessing` ``ProcessPoolExecutor`` when a child +process crashes while data is being written in the call queue. + +.. + +.. date: 2022-05-17-10-46-44 +.. gh-issue: 92871 +.. nonce: GVogrT +.. section: Library + +Remove the ``typing.io`` and ``typing.re`` namespaces, deprecated since +Python 3.8. All items are still available from the main :mod:`typing` +module. + +.. + +.. bpo: 43633 +.. date: 2021-10-31-16-06-28 +.. nonce: vflwXv +.. section: Library + +Improve the textual representation of IPv4-mapped IPv6 addresses +(:rfc:`4291` Sections 2.2, 2.5.5.2) in :mod:`ipaddress`. Patch by Oleksandr +Pavliuk. + +.. + +.. bpo: 44850 +.. date: 2021-08-16-17-52-26 +.. nonce: r8jx5u +.. section: Library + +Improve performance of :func:`operator.methodcaller` using the :pep:`590` +``vectorcall`` convention. Patch by Anthony Lee and Pieter Eendebak. + +.. + +.. bpo: 44185 +.. date: 2021-06-24-20-45-03 +.. nonce: ZHb8yJ +.. section: Library + +:func:`unittest.mock.mock_open` will call the :func:`close` method of the +file handle mock when it is exiting from the context manager. Patch by Samet +Yaslan. + +.. + +.. bpo: 40988 +.. date: 2020-11-10-07-04-15 +.. nonce: 5kBC-O +.. section: Library + +Improve performance of :class:`functools.singledispatchmethod` by caching +the generated dispatch wrapper. Optimization suggested by frederico. Patch +by @mental32, Alex Waygood and Pieter Eendebak. + +.. + +.. bpo: 41768 +.. date: 2020-09-16-16-53-06 +.. nonce: 8_fWkC +.. section: Library + +:mod:`unittest.mock` speccing no longer calls class properties. Patch by +Melanie Witt. + +.. + +.. bpo: 18319 +.. date: 2020-05-03-00-33-15 +.. nonce: faPTlx +.. section: Library + +Ensure ``gettext(msg)`` retrieve translations even if a plural form exists. +In other words: ``gettext(msg) == ngettext(msg, '', 1)``. + +.. + +.. bpo: 17013 +.. date: 2019-09-13-13-28-10 +.. nonce: NWcgE3 +.. section: Library + +Add ``ThreadingMock`` to :mod:`unittest.mock` that can be used to create +Mock objects that can wait until they are called. Patch by Karthikeyan +Singaravelan and Mario Corchero. + +.. + +.. date: 2023-09-10-02-39-06 +.. gh-issue: 109209 +.. nonce: 0LBewo +.. section: Documentation + +The minimum Sphinx version required for the documentation is now 4.2. + +.. + +.. date: 2023-09-03-13-43-49 +.. gh-issue: 108826 +.. nonce: KG7abS +.. section: Documentation + +:mod:`dis` module command-line interface is now mentioned in documentation. + +.. + +.. date: 2023-07-26-16-33-04 +.. gh-issue: 107305 +.. nonce: qB2LS4 +.. section: Documentation + +Add documentation for :c:type:`PyInterpreterConfig` and +:c:func:`Py_NewInterpreterFromConfig`. Also clarify some of the nearby docs +relative to per-interpreter GIL. + +.. + +.. date: 2023-07-22-15-14-13 +.. gh-issue: 107008 +.. nonce: 3JQ1Vt +.. section: Documentation + +Document the :mod:`curses` module variables :const:`~curses.LINES` and +:const:`~curses.COLS`. + +.. + +.. date: 2023-07-21-11-51-57 +.. gh-issue: 106948 +.. nonce: K_JQ7j +.. section: Documentation + +Add a number of standard external names to ``nitpick_ignore``. + +.. + +.. date: 2023-06-30-19-28-59 +.. gh-issue: 106232 +.. nonce: hQ4-tz +.. section: Documentation + +Make timeit doc command lines compatible with Windows by using double quotes +for arguments. This works on linux and macOS also. + +.. + +.. date: 2023-05-31-23-05-51 +.. gh-issue: 105172 +.. nonce: SVfvkD +.. section: Documentation + +Fixed :func:`functools.lru_cache` docstring accounting for ``typed`` +argument's different handling of str and int. Patch by Bar Harel. + +.. + +.. date: 2023-05-29-14-10-24 +.. gh-issue: 105052 +.. nonce: MGFwbm +.. section: Documentation + +Update ``timeit`` doc to specify that time in seconds is just the default. + +.. + +.. date: 2023-05-28-21-01-00 +.. gh-issue: 89455 +.. nonce: qAKRrA +.. section: Documentation + +Add missing documentation for the ``max_group_depth`` and +``max_group_width`` parameters and the ``exceptions`` attribute of the +:class:`traceback.TracebackException` class. + +.. + +.. date: 2023-05-28-19-08-42 +.. gh-issue: 89412 +.. nonce: j4cg7K +.. section: Documentation + +Add missing documentation for the ``end_lineno`` and ``end_offset`` +attributes of the :class:`traceback.TracebackException` class. + +.. + +.. date: 2023-05-25-22-34-31 +.. gh-issue: 104943 +.. nonce: J2v1Pc +.. section: Documentation + +Remove mentions of old Python versions in :class:`typing.NamedTuple`. + +.. + +.. date: 2023-05-16-22-08-24 +.. gh-issue: 54738 +.. nonce: mJvCnj +.. section: Documentation + +Add documentation on how to localize the :mod:`argparse` module. + +.. + +.. date: 2023-03-19-09-39-31 +.. gh-issue: 102823 +.. nonce: OzsOz0 +.. section: Documentation + +Document the return type of ``x // y`` when ``x`` and ``y`` have type +:class:`float`. + +.. + +.. date: 2023-03-16-15-39-26 +.. gh-issue: 102759 +.. nonce: ehpHw6 +.. section: Documentation + +Align function signature for ``functools.reduce`` in documentation and +docstring with the C implementation. + +.. + +.. date: 2023-10-10-23-20-13 +.. gh-issue: 110647 +.. nonce: jKG3sY +.. section: Tests + +Fix test_stress_modifying_handlers() of test_signal. Patch by Victor +Stinner. + +.. + +.. date: 2023-10-06-02-32-18 +.. gh-issue: 103053 +.. nonce: VfxBLI +.. section: Tests + +Fix test_tools.test_freeze on FreeBSD: run "make distclean" instead of "make +clean" in the copied source directory to remove also the "python" program. +Patch by Victor Stinner. + +.. + +.. date: 2023-10-05-19-33-49 +.. gh-issue: 110167 +.. nonce: mIdj3v +.. section: Tests + +Fix a deadlock in test_socket when server fails with a timeout but the +client is still running in its thread. Don't hold a lock to call cleanup +functions in doCleanups(). One of the cleanup function waits until the +client completes, whereas the client could deadlock if it called +addCleanup() in such situation. Patch by Victor Stinner. + +.. + +.. date: 2023-10-05-14-22-48 +.. gh-issue: 110388 +.. nonce: 1-HQJO +.. section: Tests + +Add tests for :mod:`tty`. + +.. + +.. date: 2023-10-05-13-46-50 +.. gh-issue: 81002 +.. nonce: bOcuV6 +.. section: Tests + +Add tests for :mod:`termios`. + +.. + +.. date: 2023-10-04-18-27-47 +.. gh-issue: 110367 +.. nonce: Nnq1I7 +.. section: Tests + +regrtest: When using worker processes (-jN) with --verbose3 option, regrtest +can now display the worker output even if a worker process does crash. +Previously, sys.stdout and sys.stderr were replaced and so the worker output +was lost on a crash. Patch by Victor Stinner. + +.. + +.. date: 2023-10-03-10-54-09 +.. gh-issue: 110267 +.. nonce: O-c47G +.. section: Tests + +Add tests for pickling and copying PyStructSequence objects. Patched by +Xuehai Pan. + +.. + +.. date: 2023-10-01-10-27-02 +.. gh-issue: 110171 +.. nonce: ZPlo0h +.. section: Tests + +``libregrtest`` now always sets and shows ``random.seed``, so tests are more +reproducible. Use ``--randseed`` flag to pass the explicit random seed for +tests. + +.. + +.. date: 2023-09-30-20-18-38 +.. gh-issue: 110152 +.. nonce: 4Kxve1 +.. section: Tests + +Remove ``Tools/scripts/run_tests.py`` and ``make hostrunnertest``. Just run +``./python -m test --slow-ci``, ``make buildbottest`` or ``make test`` +instead. Python test runner (regrtest) now handles cross-compilation and +HOSTRUNNER. It also adds options to Python such fast ``-u -E -W default +-bb`` when ``--fast-ci`` or ``--slow-ci`` option is used. Patch by Victor +Stinner. + +.. + +.. date: 2023-09-29-14-11-30 +.. gh-issue: 110031 +.. nonce: fQnFnc +.. section: Tests + +Skip test_threading tests using thread+fork if Python is built with Address +Sanitizer (ASAN). Patch by Victor Stinner. + +.. + +.. date: 2023-09-29-12-48-42 +.. gh-issue: 110088 +.. nonce: qUhRga +.. section: Tests + +Fix test_asyncio timeouts: don't measure the maximum duration, a test should +not measure a CI performance. Only measure the minimum duration when a task +has a timeout or delay. Add ``CLOCK_RES`` to ``test_asyncio.utils``. Patch +by Victor Stinner. + +.. + +.. date: 2023-09-29-00-19-21 +.. gh-issue: 109974 +.. nonce: Sh_g-r +.. section: Tests + +Fix race conditions in test_threading lock tests. Wait until a condition is +met rather than using :func:`time.sleep` with a hardcoded number of seconds. +Patch by Victor Stinner. + +.. + +.. date: 2023-09-28-18-14-52 +.. gh-issue: 110033 +.. nonce: 2yHMx0 +.. section: Tests + +Fix ``test_interprocess_signal()`` of ``test_signal``. Make sure that the +``subprocess.Popen`` object is deleted before the test raising an exception +in a signal handler. Otherwise, ``Popen.__del__()`` can get the exception +which is logged as ``Exception ignored in: ...`` and the test fails. Patch +by Victor Stinner. + +.. + +.. date: 2023-09-28-14-47-14 +.. gh-issue: 109594 +.. nonce: DB5KPP +.. section: Tests + +Fix test_timeout() of test_concurrent_futures.test_wait. Remove the future +which may or may not complete depending if it takes longer than the timeout +ot not. Keep the second future which does not complete before wait() +timeout. Patch by Victor Stinner. + +.. + +.. date: 2023-09-28-12-25-19 +.. gh-issue: 109972 +.. nonce: GYnwIP +.. section: Tests + +Split test_gdb.py file into a test_gdb package made of multiple tests, so +tests can now be run in parallel. Patch by Victor Stinner. + +.. + +.. date: 2023-09-26-18-12-01 +.. gh-issue: 109566 +.. nonce: CP0Vhf +.. section: Tests + +regrtest: When ``--fast-ci`` or ``--slow-ci`` option is used, regrtest now +replaces the current process with a new process to add ``-u -W default -bb +-E`` options to Python. Patch by Victor Stinner. + +.. + +.. date: 2023-09-26-00-49-18 +.. gh-issue: 109748 +.. nonce: nxlT1i +.. section: Tests + +Fix ``test_zippath_from_non_installed_posix()`` of test_venv: don't copy +``__pycache__/`` sub-directories, because they can be modified by other +Python tests running in parallel. Patch by Victor Stinner. + +.. + +.. date: 2023-09-25-23-59-37 +.. gh-issue: 109739 +.. nonce: MUn7K5 +.. section: Tests + +regrtest: Fix reference leak check on Windows. Disable the load tracker on +Windows in the reference leak check mode (-R option). Patch by Victor +Stinner. + +.. + +.. date: 2023-09-25-14-41-18 +.. gh-issue: 109276 +.. nonce: uC_cWo +.. section: Tests + +regrtest: When a test fails with "env changed" and the --rerun option is +used, the test is now re-run in verbose mode in a fresh process. Patch by +Victor Stinner. + +.. + +.. date: 2023-09-20-02-32-17 +.. gh-issue: 103053 +.. nonce: AoUJuK +.. section: Tests + +Skip test_freeze_simple_script() of test_tools.test_freeze if Python is +built with ``./configure --enable-optimizations``, which means with Profile +Guided Optimization (PGO): it just makes the test too slow. The freeze tool +is tested by many other CIs with other (faster) compiler flags. Patch by +Victor Stinner. + +.. + +.. date: 2023-09-19-19-08-22 +.. gh-issue: 109580 +.. nonce: G02Zam +.. section: Tests + +Skip ``test_perf_profiler`` if Python is built with ASAN, MSAN or UBSAN +sanitizer. Python does crash randomly in this test on such build. Patch by +Victor Stinner. + +.. + +.. date: 2023-09-19-13-33-20 +.. gh-issue: 109566 +.. nonce: aX0g9o +.. section: Tests + +regrtest: Add ``--fast-ci`` and ``--slow-ci`` options. ``--fast-ci`` uses a +default timeout of 10 minutes and ``-u all,-cpu`` (skip slowest tests). +``--slow-ci`` uses a default timeout of 20 minues and ``-u all`` (run all +tests). Patch by Victor Stinner. + +.. + +.. date: 2023-09-14-23-27-40 +.. gh-issue: 109425 +.. nonce: j-uFep +.. section: Tests + +libregrtest now decodes stdout of test worker processes with the +"backslashreplace" error handler to log corrupted stdout, instead of failing +with an error and not logging the stdout. Patch by Victor Stinner. + +.. + +.. date: 2023-09-14-22-58-47 +.. gh-issue: 109396 +.. nonce: J1a4jR +.. section: Tests + +Fix ``test_socket.test_hmac_sha1()`` in FIPS mode. Use a longer key: FIPS +mode requires at least of at least 112 bits. The previous key was only 32 +bits. Patch by Victor Stinner. + +.. + +.. date: 2023-09-13-05-58-09 +.. gh-issue: 104736 +.. nonce: lA25Fu +.. section: Tests + +Fix test_gdb on Python built with LLVM clang 16 on Linux ppc64le (ex: Fedora +38). Search patterns in gdb "bt" command output to detect when gdb fails to +retrieve the traceback. For example, skip a test if ``Backtrace stopped: +frame did not save the PC`` is found. Patch by Victor Stinner. + +.. + +.. date: 2023-09-11-19-11-57 +.. gh-issue: 109276 +.. nonce: qxI4OG +.. section: Tests + +libregrtest now calls :func:`random.seed()` before running each test file +when ``-r/--randomize`` command line option is used. Moreover, it's also +called in worker processes. It should help to make tests more +deterministic. Previously, it was only called once in the main process +before running all test files and it was not called in worker processes. +Patch by Victor Stinner. + +.. + +.. date: 2023-09-11-18-19-52 +.. gh-issue: 109276 +.. nonce: btfFtT +.. section: Tests + +libregrtest now uses a separated file descriptor to write test result as +JSON. Previously, if a test wrote debug messages late around the JSON, the +main test process failed to parse JSON. Patch by Victor Stinner. + +.. + +.. date: 2023-09-10-23-05-50 +.. gh-issue: 108996 +.. nonce: tJBru6 +.. section: Tests + +Fix and enable ``test_msvcrt``. + +.. + +.. date: 2023-09-10-22-32-20 +.. gh-issue: 109237 +.. nonce: SvgKwD +.. section: Tests + +Fix ``test_site.test_underpth_basic()`` when the working directory contains +at least one non-ASCII character: encode the ``._pth`` file to UTF-8 and +enable the UTF-8 Mode to use UTF-8 for the child process stdout. Patch by +Victor Stinner. + +.. + +.. date: 2023-09-10-19-59-57 +.. gh-issue: 109230 +.. nonce: SRNLFQ +.. section: Tests + +Fix ``test_pyexpat.test_exception()``: it can now be run from a directory +different than Python source code directory. Before, the test failed in this +case. Skip the test if Modules/pyexpat.c source is not available. Skip also +the test on Python implementations other than CPython. Patch by Victor +Stinner. + +.. + +.. date: 2023-09-06-22-06-22 +.. gh-issue: 108996 +.. nonce: IBhR3U +.. section: Tests + +Add tests for ``msvcrt``. + +.. + +.. date: 2023-09-06-18-27-53 +.. gh-issue: 109015 +.. nonce: 1dS1AQ +.. section: Tests + +Fix test_asyncio, test_imaplib and test_socket tests on FreeBSD if the TCP +blackhole is enabled (``sysctl net.inet.tcp.blackhole``). Skip the few tests +which failed with ``ETIMEDOUT`` which such non standard configuration. +Currently, the `FreeBSD GCP image enables TCP and UDP blackhole +`_ (``sysctl net.inet.tcp.blackhole=2`` +and ``sysctl net.inet.udp.blackhole=1``). Patch by Victor Stinner. + +.. + +.. date: 2023-09-06-15-36-51 +.. gh-issue: 91960 +.. nonce: P3nD5v +.. section: Tests + +Skip ``test_gdb`` if gdb is unable to retrieve Python frame objects: if a +frame is ````. When Python is built with "clang -Og", gdb can +fail to retrive the *frame* parameter of ``_PyEval_EvalFrameDefault()``. In +this case, tests like ``py_bt()`` are likely to fail. Without getting access +to Python frames, ``python-gdb.py`` is mostly clueless on retrieving the +Python traceback. Moreover, ``test_gdb`` is no longer skipped on macOS if +Python is built with Clang. Patch by Victor Stinner. + +.. + +.. date: 2023-09-05-23-00-09 +.. gh-issue: 108962 +.. nonce: R4NwuU +.. section: Tests + +Skip ``test_tempfile.test_flags()`` if ``chflags()`` fails with "OSError: +[Errno 45] Operation not supported" (ex: on FreeBSD 13). Patch by Victor +Stinner. + +.. + +.. date: 2023-09-05-21-42-54 +.. gh-issue: 91960 +.. nonce: abClTs +.. section: Tests + +FreeBSD 13.2 CI coverage for pull requests is now provided by Cirrus-CI (a +hosted CI service that supports Linux, macOS, Windows, and FreeBSD). + +.. + +.. date: 2023-09-04-15-18-14 +.. gh-issue: 89392 +.. nonce: 8A4T5p +.. section: Tests + +Removed support of ``test_main()`` function in tests. They now always use +normal unittest test runner. + +.. + +.. date: 2023-09-03-21-41-10 +.. gh-issue: 108851 +.. nonce: xFTYOE +.. section: Tests + +Fix ``test_tomllib`` recursion tests for WASI buildbots: reduce the +recursion limit and compute the maximum nested array/dict depending on the +current available recursion limit. Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-21-18-35 +.. gh-issue: 108851 +.. nonce: CCuHyI +.. section: Tests + +Add ``get_recursion_available()`` and ``get_recursion_depth()`` functions to +the :mod:`test.support` module. Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-20-15-49 +.. gh-issue: 108834 +.. nonce: Osvmhf +.. section: Tests + +Add ``--fail-rerun option`` option to regrtest: if a test failed when then +passed when rerun in verbose mode, exit the process with exit code 2 +(error), instead of exit code 0 (success). Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-06-17-12 +.. gh-issue: 108834 +.. nonce: fjV-CJ +.. section: Tests + +Rename regrtest ``--verbose2`` option (``-w``) to ``--rerun``. Keep +``--verbose2`` as a deprecated alias. Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-02-01-55 +.. gh-issue: 108834 +.. nonce: iAwXzj +.. section: Tests + +When regrtest reruns failed tests in verbose mode (``./python -m test +--rerun``), tests are now rerun in fresh worker processes rather than being +executed in the main process. If a test does crash or is killed by a +timeout, the main process can detect and handle the killed worker process. +Tests are rerun in parallel if the ``-jN`` option is used to run tests in +parallel. Patch by Victor Stinner. + +.. + +.. date: 2023-09-02-19-06-52 +.. gh-issue: 108822 +.. nonce: arTbBI +.. section: Tests + +``regrtest`` now computes statistics on all tests: successes, failures and +skipped. ``test_netrc``, ``test_pep646_syntax`` and ``test_xml_etree`` now +return results in their ``test_main()`` function. Patch by Victor Stinner +and Alex Waygood. + +.. + +.. date: 2023-09-02-05-13-38 +.. gh-issue: 108794 +.. nonce: tGHXBt +.. section: Tests + +The :meth:`doctest.DocTestRunner.run` method now counts the number of +skipped tests. Add :attr:`doctest.DocTestRunner.skips` and +:attr:`doctest.TestResults.skipped` attributes. Patch by Victor Stinner. + +.. + +.. date: 2023-08-24-06-10-36 +.. gh-issue: 108388 +.. nonce: YCVB0D +.. section: Tests + +Convert test_concurrent_futures to a package of 7 sub-tests. Patch by Victor +Stinner. + +.. + +.. date: 2023-08-24-04-23-35 +.. gh-issue: 108388 +.. nonce: mr0MeE +.. section: Tests + +Split test_multiprocessing_fork, test_multiprocessing_forkserver and +test_multiprocessing_spawn into test packages. Each package is made of 4 +sub-tests: processes, threads, manager and misc. It allows running more +tests in parallel and so reduce the total test duration. Patch by Victor +Stinner. + +.. + +.. date: 2023-08-23-04-08-18 +.. gh-issue: 105776 +.. nonce: oE6wp_ +.. section: Tests + +Fix test_cppext when the C compiler command ``-std=c11`` option: remove +``-std=`` options from the compiler command. Patch by Victor Stinner. + +.. + +.. date: 2023-08-05-14-01-07 +.. gh-issue: 107652 +.. nonce: 5OxOlT +.. section: Tests + +Set up CIFuzz to run fuzz targets in GitHub Actions. Patch by Illia +Volochii. + +.. + +.. date: 2023-07-25-14-36-33 +.. gh-issue: 107237 +.. nonce: y1pY79 +.. section: Tests + +``test_logging``: Fix ``test_udp_reconnection()`` by increasing the timeout +from 100 ms to 5 minutes (LONG_TIMEOUT). Patch by Victor Stinner. + +.. + +.. date: 2023-07-24-16-56-59 +.. gh-issue: 107178 +.. nonce: Gq1usE +.. section: Tests + +Add the C API test for functions in the Mapping Protocol, the Sequence +Protocol and some functions in the Object Protocol. + +.. + +.. date: 2023-07-22-13-49-40 +.. gh-issue: 106714 +.. nonce: btYI5S +.. section: Tests + +test_capi: Fix test_no_FatalError_infinite_loop() to no longer write a +coredump, by using test.support.SuppressCrashReport. Patch by Victor +Stinner. + +.. + +.. date: 2023-07-16-02-57-08 +.. gh-issue: 104090 +.. nonce: cKtK7g +.. section: Tests + +Avoid creating a reference to the test object in +:meth:`~unittest.TestResult.collectedDurations`. + +.. + +.. date: 2023-07-14-16-20-06 +.. gh-issue: 106752 +.. nonce: gd1i6D +.. section: Tests + +Moved tests for ``zipfile.Path`` into ``Lib/test/test_zipfile/_path``. Made +``zipfile._path`` a package. + +.. + +.. date: 2023-07-12-14-07-07 +.. gh-issue: 106690 +.. nonce: NDz-oG +.. section: Tests + +Add .coveragerc to cpython repository for use with coverage package. + +.. + +.. date: 2023-06-28-02-51-08 +.. gh-issue: 101634 +.. nonce: Rayczr +.. section: Tests + +When running the Python test suite with ``-jN`` option, if a worker stdout +cannot be decoded from the locale encoding report a failed testn so the +exitcode is non-zero. Patch by Victor Stinner. + +.. + +.. date: 2023-05-29-14-49-46 +.. gh-issue: 105084 +.. nonce: lvVvoj +.. section: Tests + +When the Python build is configured ``--with-wheel-pkg-dir``, tests +requiring the ``setuptools`` and ``wheel`` wheels will search for the wheels +in ``WHEEL_PKG_DIR``. + +.. + +.. date: 2023-05-19-08-06-06 +.. gh-issue: 81005 +.. nonce: -q7m9W +.. section: Tests + +String tests are modified to reflect that ``str`` and ``unicode`` are merged +in Python 3. Patch by Daniel Fortunov. + +.. + +.. date: 2023-04-05-06-45-20 +.. gh-issue: 103186 +.. nonce: 640Eg- +.. section: Tests + +Suppress and assert expected RuntimeWarnings in test_sys_settrace.py + +.. + +.. date: 2022-06-09-21-27-38 +.. gh-issue: 69714 +.. nonce: 49tyHW +.. section: Tests + +Add additional tests to :mod:`calendar` to achieve full test coverage. + +.. + +.. date: 2023-10-06-02-15-23 +.. gh-issue: 103053 +.. nonce: --7JUF +.. section: Build + +"make check-clean-src" now also checks if the "python" program is found in +the source directory: fail with an error if it does exist. Patch by Victor +Stinner. + +.. + +.. date: 2023-10-05-11-46-20 +.. gh-issue: 109191 +.. nonce: imUkVN +.. section: Build + +Fix compile error when building with recent versions of libedit. + +.. + +.. date: 2023-10-03-17-55-09 +.. gh-issue: 110276 +.. nonce: luaKRg +.. section: Build + +No longer ignore :envvar:`PROFILE_TASK` failure silently: command used by +Profile Guided Optimization (PGO). Patch by Victor Stinner. + +.. + +.. date: 2023-09-29-21-01-48 +.. gh-issue: 109566 +.. nonce: _enldb +.. section: Build + +Remove ``make testall`` target: use ``make buildbottest`` instead. Patch by +Victor Stinner. + +.. + +.. date: 2023-09-26-16-00-50 +.. gh-issue: 109740 +.. nonce: wboWdQ +.. section: Build + +The experimental ``--disable-gil`` configure flag now includes "t" (for +"threaded") in extension ABI tags. + +.. + +.. date: 2023-09-07-19-58-05 +.. gh-issue: 109054 +.. nonce: 5r3S3l +.. section: Build + +Fix building the ``_testcapi`` extension on Linux AArch64 which requires +linking to libatomic when ```` is used: the +``_Py_atomic_or_uint64()`` function requires libatomic +``__atomic_fetch_or_8()`` on this platform. The configure script now checks +if linking to libatomic is needed and generates a new LIBATOMIC variable +used to build the _testcapi extension. Patch by Victor Stinner. + +.. + +.. date: 2023-09-02-18-04-15 +.. gh-issue: 63760 +.. nonce: r8hJ6q +.. section: Build + +Fix Solaris build: no longer redefine the ``gethostname()`` function. +Solaris defines the function since 2005. Patch by Victor Stinner, original +patch by Jakub Kulík. + +.. + +.. date: 2023-09-01-01-39-26 +.. gh-issue: 108740 +.. nonce: JHExAQ +.. section: Build + +Fix a race condition in ``make regen-all``. The ``deepfreeze.c`` source and +files generated by Argument Clinic are now generated or updated before +generating "global objects". Previously, some identifiers may miss depending +on the order in which these files were generated. Patch by Victor Stinner. + +.. + +.. date: 2023-08-30-02-52-52 +.. gh-issue: 108634 +.. nonce: 3dpBvf +.. section: Build + +Python built with :file:`configure` :option:`--with-trace-refs` (tracing +references) is now ABI compatible with Python release build and :ref:`debug +build `. Patch by Victor Stinner. + +.. + +.. date: 2023-08-29-15-05-09 +.. gh-issue: 85283 +.. nonce: tlK7G7 +.. section: Build + +The ``_stat`` C extension is now built with the :ref:`limited C API +`. Patch by Victor Stinner. + +.. + +.. date: 2023-08-24-18-36-31 +.. gh-issue: 108447 +.. nonce: Ofsygr +.. section: Build + +Fix x86_64 GNU/Hurd build + +.. + +.. date: 2023-08-09-17-05-33 +.. gh-issue: 107814 +.. nonce: c0Oapq +.. section: Build + +When calling ``find_python.bat`` with ``-q`` it did not properly silence the +output of nuget. That is now fixed. + +.. + +.. date: 2023-08-01-17-12-53 +.. gh-issue: 105481 +.. nonce: 42nsDE +.. section: Build + +Remove the make target ``regen-opcode-targets``, merge its work into +``regen-opcode`` which repeats most of the calculation. This simplifies the +code for the build and reduces code duplication. + +.. + +.. date: 2023-07-28-18-17-33 +.. gh-issue: 106881 +.. nonce: U3Ezdq +.. section: Build + +Check for ``linux/limits.h`` before including it in +``Modules/posixmodule.c``. + +.. + +.. date: 2023-07-25-02-30-00 +.. gh-issue: 95855 +.. nonce: wA7rAf +.. section: Build + +Refactor platform triplet detection code and add detection for MIPS soft +float and musl libc. + +.. + +.. date: 2023-07-23-00-38-51 +.. gh-issue: 106962 +.. nonce: VVYrWB +.. section: Build + +Detect MPI compilers in :file:`configure`. + +.. + +.. date: 2023-06-26-21-56-29 +.. gh-issue: 106118 +.. nonce: 0cCfhl +.. section: Build + +Fix compilation for platforms without :data:`!O_CLOEXEC`. The issue was +introduced with Python 3.12b1 in :gh:`103295`. Patch by Erlend Aasland. + +.. + +.. date: 2023-06-16-23-40-49 +.. gh-issue: 105875 +.. nonce: naj8v5 +.. section: Build + +SQLite 3.15.2 or newer is required to build the :mod:`sqlite3` extension +module. Patch by Erlend Aasland. + +.. + +.. date: 2023-06-06-09-08-10 +.. gh-issue: 90005 +.. nonce: 8mmeJQ +.. section: Build + +Fix a regression in :file:`configure` where we could end up unintentionally +linking with ``libbsd``. + +.. + +.. date: 2023-06-02-19-12-45 +.. gh-issue: 102404 +.. nonce: Ry9piA +.. section: Build + +Document how to perform a WASI build on Linux. Also add +Tools/wasm/build_wasi.sh as a reference implementation of the docs. + +.. + +.. date: 2023-05-26-15-44-20 +.. gh-issue: 89886 +.. nonce: _iSW-p +.. section: Build + +Autoconf 2.71 and aclocal 1.16.4 is now required to regenerate +:file:`!configure`. + +.. + +.. date: 2023-05-20-23-49-30 +.. gh-issue: 104692 +.. nonce: s5UIu5 +.. section: Build + +Include ``commoninstall`` as a prerequisite for ``bininstall`` + +This ensures that ``commoninstall`` is completed before ``bininstall`` is +started when parallel builds are used (``make -j install``), and so the +``python3`` symlink is only installed after all standard library modules are +installed. + +.. + +.. date: 2023-02-03-21-36-42 +.. gh-issue: 101538 +.. nonce: sF5F6S +.. section: Build + +Add experimental wasi-threads support. Patch by Takashi Yamamoto. + +.. + +.. date: 2023-10-06-14-20-14 +.. gh-issue: 110437 +.. nonce: xpYy9q +.. section: Windows + +Allows overriding the source of VC redistributables so that releases can be +guaranteed to never downgrade between updates. + +.. + +.. date: 2023-10-05-15-23-23 +.. gh-issue: 109286 +.. nonce: N8OzMg +.. section: Windows + +Update Windows installer to use SQLite 3.43.1. + +.. + +.. date: 2023-10-03-12-30-59 +.. gh-issue: 82367 +.. nonce: nxwfMx +.. section: Windows + +:func:`os.path.realpath` now resolves MS-DOS style file names even if the +file is not accessible. Patch by Moonsik Park. + +.. + +.. date: 2023-09-28-17-09-23 +.. gh-issue: 109991 +.. nonce: CIMftz +.. section: Windows + +Update Windows build to use OpenSSL 3.0.11. + +.. + +.. date: 2023-08-22-00-36-57 +.. gh-issue: 106242 +.. nonce: q24ITw +.. section: Windows + +Fixes :func:`~os.path.realpath` to behave consistently when passed a path +containing an embedded null character on Windows. In strict mode, it now +raises :exc:`OSError` instead of the unexpected :exc:`ValueError`, and in +non-strict mode will make the path absolute. + +.. + +.. date: 2023-08-18-00-01-21 +.. gh-issue: 83180 +.. nonce: DdLffv +.. section: Windows + +Changes the :ref:`launcher` to prefer an active virtual environment when the +launched script has a shebang line using a Unix-like virtual command, even +if the command requests a specific version of Python. + +.. + +.. date: 2023-07-18-13-01-26 +.. gh-issue: 106844 +.. nonce: mci4xO +.. section: Windows + +Fix integer overflow and truncating by the null character in +:func:`!_winapi.LCMapStringEx` which affects :func:`ntpath.normcase`. + +.. + +.. date: 2023-06-08-11-30-17 +.. gh-issue: 105436 +.. nonce: 1qlDxw +.. section: Windows + +Ensure that an empty environment block is terminated by two null characters, +as is required by Windows. + +.. + +.. date: 2023-05-31-16-14-31 +.. gh-issue: 105146 +.. nonce: gNjqq8 +.. section: Windows + +Updated the links at the end of the installer to point to Discourse rather +than the mailing lists. + +.. + +.. date: 2023-05-29-17-09-31 +.. gh-issue: 103646 +.. nonce: U8oGQx +.. section: Windows + +When installed from the Microsoft Store, ``pip`` no longer defaults to +per-user installs. However, as the install directory is unwritable, it +should automatically decide to do a per-user install anyway. This should +resolve issues when ``pip`` is passed an option that conflicts with +``--user``. + +.. + +.. date: 2023-05-29-11-38-53 +.. gh-issue: 88745 +.. nonce: cldf9G +.. section: Windows + +Improve performance of :func:`shutil.copy2` by using the operating system's +``CopyFile2`` function. This may result in subtle changes to metadata copied +along with some files, bringing them in line with normal OS behavior. + +.. + +.. date: 2023-05-24-21-00-57 +.. gh-issue: 104820 +.. nonce: ibyrpp +.. section: Windows + +Fixes :func:`~os.stat` and related functions on file systems that do not +support file ID requests. This includes FAT32 and exFAT. + +.. + +.. date: 2023-05-23-19-26-28 +.. gh-issue: 104803 +.. nonce: gqxYml +.. section: Windows + +Add :func:`os.path.isdevdrive` to detect whether a path is on a Windows Dev +Drive. Returns ``False`` on platforms that do not support Dev Drive, and is +absent on non-Windows platforms. + +.. + +.. date: 2023-10-04-23-38-24 +.. gh-issue: 109286 +.. nonce: 1ZLMaq +.. section: macOS + +Update macOS installer to use SQLite 3.43.1. + +.. + +.. date: 2023-09-27-22-35-22 +.. gh-issue: 109991 +.. nonce: -xJzaF +.. section: macOS + +Update macOS installer to use OpenSSL 3.0.11. + +.. + +.. date: 2023-07-30-23-42-20 +.. gh-issue: 99079 +.. nonce: JAtoh1 +.. section: macOS + +Update macOS installer to use OpenSSL 3.0.9. + +.. + +.. date: 2023-05-23-17-19-49 +.. gh-issue: 104719 +.. nonce: rvYXH- +.. section: IDLE + +Remove IDLE's modification of tokenize.tabsize and test other uses of +tokenize data and methods. + +.. + +.. date: 2023-09-27-23-31-54 +.. gh-issue: 109991 +.. nonce: sUUYY8 +.. section: Tools/Demos + +Update GitHub CI workflows to use OpenSSL 3.0.11 and multissltests to use +1.1.1w, 3.0.11, and 3.1.3. + +.. + +.. date: 2023-08-25-22-40-12 +.. gh-issue: 108494 +.. nonce: 4RbDdu +.. section: Tools/Demos + +`Argument Clinic `__ +now has a partial support of the :ref:`Limited API `: see +`documentation in the Python Developer's Guide +`__ +Patch by Victor Stinner. + +.. + +.. date: 2023-08-15-19-50-49 +.. gh-issue: 107704 +.. nonce: Uu84vd +.. section: Tools/Demos + +It is now possible to deprecate passing keyword arguments for +keyword-or-positional parameters with Argument Clinic, using the new ``/ +[from X.Y]`` syntax. (To be read as *"positional-only from Python version +X.Y"*.) See `documentation in the Python Developer's Guide +`__ +for more information. + +.. + +.. date: 2023-08-13-11-18-06 +.. gh-issue: 107880 +.. nonce: gBVVQ7 +.. section: Tools/Demos + +Argument Clinic can now clone :meth:`!__init__` and :meth:`!__new__` +methods. + +.. + +.. date: 2023-08-08-12-21-41 +.. gh-issue: 104683 +.. nonce: DRsAQE +.. section: Tools/Demos + +Add ``--exclude`` option to Argument Clinic CLI. + +.. + +.. date: 2023-08-07-16-30-48 +.. gh-issue: 95065 +.. nonce: -im4R5 +.. section: Tools/Demos + +Argument Clinic now supports overriding automatically generated signature by +using directive ``@text_signature``. See `documentation in the Python +Developer's Guide +`__ + +.. + +.. date: 2023-08-04-00-04-40 +.. gh-issue: 107609 +.. nonce: 2DqgtL +.. section: Tools/Demos + +Fix duplicate module check in Argument Clinic. Previously, a duplicate +definition would incorrectly be silently accepted. Patch by Erlend E. +Aasland. + +.. + +.. date: 2023-07-30-23-32-16 +.. gh-issue: 107467 +.. nonce: 5O9p3G +.. section: Tools/Demos + +The Argument Clinic command-line tool now prints to stderr instead of stdout +on failure. + +.. + +.. date: 2023-07-21-23-16-05 +.. gh-issue: 106970 +.. nonce: NLRnml +.. section: Tools/Demos + +Fix bugs in the Argument Clinic ``destination clear`` command; the +destination buffers would never be cleared, and the ``destination`` +directive parser would simply continue to the fault handler after processing +the command. Patch by Erlend E. Aasland. + +.. + +.. date: 2023-07-13-12-08-35 +.. gh-issue: 106706 +.. nonce: 29zp8E +.. section: Tools/Demos + +Change bytecode syntax for families to remove redundant name matching pseudo +syntax. + +.. + +.. date: 2023-07-03-14-06-19 +.. gh-issue: 106359 +.. nonce: RfJuR0 +.. section: Tools/Demos + +Argument Clinic now explicitly forbids "kwarg splats" in function calls used +as annotations. + +.. + +.. date: 2023-04-05-07-19-36 +.. gh-issue: 103186 +.. nonce: yEozgK +.. section: Tools/Demos + +``freeze`` now fetches ``CONFIG_ARGS`` from the original CPython instance +the Makefile uses to call utility scripts. Patch by Ijtaba Hussain. + +.. + +.. date: 2022-07-23-00-33-28 +.. gh-issue: 95065 +.. nonce: NfCCpp +.. section: Tools/Demos + +It is now possible to deprecate passing parameters positionally with +Argument Clinic, using the new ``* [from X.Y]`` syntax. (To be read as +*"keyword-only from Python version X.Y"*.) See `documentation in the Python +Developer's Guide +`__ +for more information. Patch by Erlend E. Aasland with help from Alex +Waygood, Nikita Sobolev, and Serhiy Storchaka. + +.. + +.. date: 2023-10-11-17-29-52 +.. gh-issue: 85283 +.. nonce: OsqIBF +.. section: C API + +If the :c:macro:`Py_LIMITED_API` macro is defined, +:c:macro:`!Py_BUILD_CORE`, :c:macro:`!Py_BUILD_CORE_BUILTIN` and +:c:macro:`!Py_BUILD_CORE_MODULE` macros are now undefined by ````. +Patch by Victor Stinner. + +.. + +.. date: 2023-10-03-19-01-20 +.. gh-issue: 110289 +.. nonce: YBIHEz +.. section: C API + +Add :c:func:`PyUnicode_EqualToUTF8AndSize` and +:c:func:`PyUnicode_EqualToUTF8` functions. + +.. + +.. date: 2023-10-03-06-19-10 +.. gh-issue: 110235 +.. nonce: uec5AG +.. section: C API + +Raise :exc:`TypeError` for duplicate/unknown fields in ``PyStructSequence`` +constructor. Patched by Xuehai Pan. + +.. + +.. date: 2023-10-02-13-39-57 +.. gh-issue: 110014 +.. nonce: gfQ4jU +.. section: C API + +Remove undocumented ``PY_TIMEOUT_MAX`` constant from the limited C API. +Patch by Victor Stinner. + +.. + +.. date: 2023-09-17-21-47-31 +.. gh-issue: 109521 +.. nonce: JDF6i9 +.. section: C API + +:c:func:`PyImport_GetImporter` now sets RuntimeError if it fails to get +:data:`sys.path_hooks` or :data:`sys.path_importer_cache` or they are not +list and dict correspondingly. Previously it could return NULL without +setting error in obscure cases, crash or raise SystemError if these +attributes have wrong type. + +.. + +.. date: 2023-09-12-13-09-36 +.. gh-issue: 108724 +.. nonce: -yMsC8 +.. section: C API + +Add :c:type:`PyMutex` internal-only lightweight locking API. + +.. + +.. date: 2023-09-06-00-14-49 +.. gh-issue: 85283 +.. nonce: GKY0Cc +.. section: C API + +Add :c:func:`PySys_AuditTuple` function: similar to :c:func:`PySys_Audit`, +but pass event arguments as a Python :class:`tuple` object. Patch by Victor +Stinner. + +.. + +.. date: 2023-09-04-11-47-12 +.. gh-issue: 108867 +.. nonce: Cr_LKd +.. section: C API + +Add :c:func:`PyThreadState_GetUnchecked()` function: similar to +:c:func:`PyThreadState_Get()`, but don't kill the process with a fatal error +if it is NULL. The caller is responsible to check if the result is NULL. +Previously, the function was private and known as +``_PyThreadState_UncheckedGet()``. Patch by Victor Stinner. + +.. + +.. date: 2023-09-02-22-35-55 +.. gh-issue: 108765 +.. nonce: 4TOdBT +.. section: C API + +``Python.h`` no longer includes the ```` standard header file. If +needed, it should now be included explicitly. For example, it provides +``isalpha()`` and ``tolower()`` functions which are locale dependent. Python +provides locale independent functions, like :c:func:`!Py_ISALPHA` and +:c:func:`!Py_TOLOWER`. Patch by Victor Stinner. + +.. + +.. date: 2023-09-01-21-10-29 +.. gh-issue: 108765 +.. nonce: eeXtYF +.. section: C API + +``Python.h`` no longer includes the ```` standard header file. If +needed, it should now be included explicitly. For example, it provides the +functions: ``close()``, ``getpagesize()``, ``getpid()`` and ``sysconf()``. +Patch by Victor Stinner. + +.. + +.. date: 2023-09-01-20-41-49 +.. gh-issue: 108765 +.. nonce: 5dXc1r +.. section: C API + +``Python.h`` no longer includes the ```` standard header. It was +included for the ``finite()`` function which is now provided by the +```` header. It should now be included explicitly if needed. Remove +also the ``HAVE_IEEEFP_H`` macro. Patch by Victor Stinner. + +.. + +.. date: 2023-09-01-18-42-31 +.. gh-issue: 108765 +.. nonce: IyYNDu +.. section: C API + +``Python.h`` no longer includes these standard header files: ````, +```` and ````. If needed, they should now be +included explicitly. For example, ```` provides the ``clock()`` and +``gmtime()`` functions, ```` provides the ``select()`` +function, and ```` provides the ``futimes()``, +``gettimeofday()`` and ``setitimer()`` functions. Patch by Victor Stinner. + +.. + +.. date: 2023-09-01-16-28-09 +.. gh-issue: 108511 +.. nonce: gg-QDG +.. section: C API + +Add functions :c:func:`PyObject_HasAttrWithError`, +:c:func:`PyObject_HasAttrStringWithError`, +:c:func:`PyMapping_HasKeyWithError` and +:c:func:`PyMapping_HasKeyStringWithError`. + +.. + +.. date: 2023-09-01-15-35-05 +.. gh-issue: 107073 +.. nonce: zCz0iN +.. section: C API + +Add :c:func:`PyObject_VisitManagedDict` and +:c:func:`PyObject_ClearManagedDict` functions which must be called by the +traverse and clear functions of a type using +:c:macro:`Py_TPFLAGS_MANAGED_DICT` flag. Patch by Victor Stinner. + +.. + +.. date: 2023-08-30-02-54-06 +.. gh-issue: 108634 +.. nonce: oV3Xzk +.. section: C API + +Python built with :file:`configure` :option:`--with-trace-refs` (tracing +references) now supports the :ref:`Limited API `. Patch by +Victor Stinner. + +.. + +.. date: 2023-08-24-20-08-02 +.. gh-issue: 108014 +.. nonce: 20DOSS +.. section: C API + +Add :c:func:`PyLong_AsInt` function: similar to :c:func:`PyLong_AsLong`, but +store the result in a C :c:expr:`int` instead of a C :c:expr:`long`. +Previously, it was known as the private function :c:func:`!_PyLong_AsInt` +(with an underscore prefix). Patch by Victor Stinner. + +.. + +.. date: 2023-08-22-18-45-20 +.. gh-issue: 108314 +.. nonce: nOlmwq +.. section: C API + +Add :c:func:`PyDict_ContainsString` function: same as +:c:func:`PyDict_Contains`, but *key* is specified as a :c:expr:`const char*` +UTF-8 encoded bytes string, rather than a :c:expr:`PyObject*`. Patch by +Victor Stinner. + +.. + +.. date: 2023-08-22-13-00-54 +.. gh-issue: 108337 +.. nonce: wceHZm +.. section: C API + +Add atomic operations on additional data types in pyatomic.h. + +.. + +.. date: 2023-08-16-17-16-19 +.. gh-issue: 108014 +.. nonce: wXN3CF +.. section: C API + +Add :c:func:`Py_IsFinalizing` function: check if the main Python interpreter +is :term:`shutting down `. Patch by Victor Stinner. + +.. + +.. date: 2023-08-14-10-59-03 +.. gh-issue: 107916 +.. nonce: KH4Muo +.. section: C API + +C API functions :c:func:`PyErr_SetFromErrnoWithFilename`, +:c:func:`PyErr_SetExcFromWindowsErrWithFilename` and +:c:func:`PyErr_SetFromWindowsErrWithFilename` save now the error code before +calling :c:func:`PyUnicode_DecodeFSDefault`. + +.. + +.. date: 2023-08-13-12-33-00 +.. gh-issue: 107915 +.. nonce: jQ0wOi +.. section: C API + +Such C API functions as ``PyErr_SetString()``, ``PyErr_Format()``, +``PyErr_SetFromErrnoWithFilename()`` and many others no longer crash or +ignore errors if it failed to format the error message or decode the +filename. Instead, they keep a corresponding error. + +.. + +.. date: 2023-08-10-11-12-25 +.. gh-issue: 107810 +.. nonce: oJ40Qx +.. section: C API + +Improve :exc:`DeprecationWarning` for uses of :c:type:`PyType_Spec` with +metaclasses that have custom ``tp_new``. + +.. + +.. date: 2023-07-25-17-23-08 +.. gh-issue: 107249 +.. nonce: xqk2ke +.. section: C API + +Implement the :c:macro:`Py_UNUSED` macro for Windows MSVC compiler. Patch by +Victor Stinner. + +.. + +.. date: 2023-07-25-13-41-09 +.. gh-issue: 107226 +.. nonce: N919zH +.. section: C API + +:c:func:`PyModule_AddObjectRef` is now only available in the limited API +version 3.10 or later. + +.. + +.. date: 2023-07-22-14-40-48 +.. gh-issue: 106320 +.. nonce: H3u7x4 +.. section: C API + +Remove private ``_PyUnicode_AsString()`` alias to +:c:func:`PyUnicode_AsUTF8`. It was kept for backward compatibility with +Python 3.0 - 3.2. The :c:func:`PyUnicode_AsUTF8` is available since Python +3.3. The :c:func:`PyUnicode_AsUTF8String` function can be used to keep +compatibility with Python 3.2 and older. Patch by Victor Stinner. + +.. + +.. date: 2023-07-11-01-07-39 +.. gh-issue: 106572 +.. nonce: y1b35X +.. section: C API + +Convert :c:func:`PyObject_DelAttr` and :c:func:`PyObject_DelAttrString` +macros to functions. Patch by Victor Stinner. + +.. + +.. date: 2023-07-08-12-24-17 +.. gh-issue: 106307 +.. nonce: FVnkBw +.. section: C API + +Add :c:func:`PyMapping_GetOptionalItem` function. + +.. + +.. date: 2023-07-07-19-14-00 +.. gh-issue: 106521 +.. nonce: Veh9f3 +.. section: C API + +Add :c:func:`PyObject_GetOptionalAttr` and +:c:func:`PyObject_GetOptionalAttrString` functions. + +.. + +.. date: 2023-07-02-00-00-20 +.. gh-issue: 106320 +.. nonce: tZWcvG +.. section: C API + +Remove ``_PyInterpreterState_Get()`` alias to +:c:func:`PyInterpreterState_Get()` which was kept for backward compatibility +with Python 3.8. Patch by Victor Stinner. + +.. + +.. date: 2023-07-01-21-23-33 +.. gh-issue: 106316 +.. nonce: hp2Ijw +.. section: C API + +Remove ``cpython/pytime.h`` header file: it only contained private +functions. Patch by Victor Stinner. + +.. + +.. date: 2023-06-30-09-33-25 +.. gh-issue: 106023 +.. nonce: YvYiE4 +.. section: C API + +Remove private ``_PyObject_FastCall()`` function: use +``PyObject_Vectorcall()`` which is available since Python 3.8 (:pep:`590`). +Patch by Victor Stinner. + +.. + +.. date: 2023-06-28-02-30-50 +.. gh-issue: 106168 +.. nonce: NFOZPv +.. section: C API + +If Python is built in :ref:`debug mode ` or :option:`with +assertions <--with-assertions>`, :c:func:`PyTuple_SET_ITEM` and +:c:func:`PyList_SET_ITEM` now check the index argument with an assertion. If +the assertion fails, make sure that the size is set before. Patch by Victor +Stinner. + +.. + +.. date: 2023-06-25-18-01-27 +.. gh-issue: 106084 +.. nonce: PEzqU3 +.. section: C API + +Remove the old aliases to functions calling functions which were kept for +backward compatibility with Python 3.8 provisional API: + +* ``_PyObject_CallMethodNoArgs()``: use ``PyObject_CallMethodNoArgs()`` +* ``_PyObject_CallMethodOneArg()``: use ``PyObject_CallMethodOneArg()`` +* ``_PyObject_CallOneArg()``: use ``PyObject_CallOneArg()`` +* ``_PyObject_FastCallDict()``: use ``PyObject_VectorcallDict()`` +* ``_PyObject_Vectorcall()``: use ``PyObject_Vectorcall()`` +* ``_PyObject_VectorcallMethod()``: use ``PyObject_VectorcallMethod()`` +* ``_PyVectorcall_Function()``: use ``PyVectorcall_Function()`` + +Just remove the underscore prefix to update your code. Patch by Victor +Stinner. + +.. + +.. date: 2023-06-23-02-57-15 +.. gh-issue: 106004 +.. nonce: -OToh6 +.. section: C API + +Adds :c:func:`PyDict_GetItemRef` and :c:func:`PyDict_GetItemStringRef` +functions: similar to :c:func:`PyDict_GetItemWithError` but returning a +:term:`strong reference` instead of a :term:`borrowed reference`. Patch by +Victor Stinner. + +.. + +.. date: 2023-06-22-00-25-55 +.. gh-issue: 105927 +.. nonce: GRxZtI +.. section: C API + +Deprecate the :c:func:`PyWeakref_GetObject` and +:c:func:`PyWeakref_GET_OBJECT` functions: use the new +:c:func:`PyWeakref_GetRef` function instead. Patch by Victor Stinner. + +.. + +.. date: 2023-06-20-08-59-05 +.. gh-issue: 105927 +.. nonce: DfGeEA +.. section: C API + +Add :c:func:`PyWeakref_GetRef` function: similar to +:c:func:`PyWeakref_GetObject` but returns a :term:`strong reference`, or +``NULL`` if the referent is no longer live. Patch by Victor Stinner. + +.. + +.. date: 2023-06-19-20-02-16 +.. gh-issue: 105922 +.. nonce: o4T6wO +.. section: C API + +Add :c:func:`PyImport_AddModuleRef`: similar to +:c:func:`PyImport_AddModule`, but return a :term:`strong reference` instead +of a :term:`borrowed reference`. Patch by Victor Stinner. + +.. + +.. date: 2023-06-13-14-24-55 +.. gh-issue: 105227 +.. nonce: HDL9aF +.. section: C API + +The new :c:func:`PyType_GetDict` provides the dictionary for the given type +object that is normally exposed by ``cls.__dict__``. Normally it's +sufficient to use :c:member:`~PyTypeObject.tp_dict`, but for the static +builtin types :c:member:`!tp_dict` is now always ``NULL``. +:c:func:`!PyType_GetDict()` provides the correct dict object instead. + +.. + +.. date: 2023-06-09-23-34-25 +.. gh-issue: 105375 +.. nonce: n7amiF +.. section: C API + +Fix a bug in :c:func:`PyErr_WarnExplicit` where an exception could end up +being overwritten if the API failed internally. + +.. + +.. date: 2023-06-09-19-16-57 +.. gh-issue: 105603 +.. nonce: -z6G22 +.. section: C API + +We've renamed the new (in 3.12) ``PyInterpreterConfig.own_gil`` to +``PyInterpreterConfig.gil`` and changed the meaning of the value from "bool" +to an integer with supported values of ``PyInterpreterConfig_DEFAULT_GIL``, +``PyInterpreterConfig_SHARED_GIL``, and ``PyInterpreterConfig_OWN_GIL``. The +default is "shared". + +.. + +.. date: 2023-06-09-12-35-55 +.. gh-issue: 105387 +.. nonce: wM_oL- +.. section: C API + +In the limited C API version 3.12, :c:func:`Py_INCREF` and +:c:func:`Py_DECREF` functions are now implemented as opaque function calls +to hide implementation details. Patch by Victor Stinner. + +.. + +.. date: 2023-06-06-17-43-28 +.. gh-issue: 105396 +.. nonce: FQJG5B +.. section: C API + +Deprecate the :c:func:`PyImport_ImportModuleNoBlock` function which is just +an alias to :c:func:`PyImport_ImportModule` since Python 3.3. Patch by +Victor Stinner. + +.. + +.. date: 2023-06-06-14-14-41 +.. gh-issue: 103968 +.. nonce: BTO6II +.. section: C API + +:c:func:`PyType_FromMetaclass` now allows metaclasses with ``tp_new`` set to +``NULL``. + +.. + +.. date: 2023-06-06-10-57-18 +.. gh-issue: 105268 +.. nonce: OTJUko +.. section: C API + +Remove the old private, undocumented and untested ``_PyGC_FINALIZED()`` +macro which was kept for backward compatibility with Python 3.8 and older. +Patch by Victor Stinner. + +.. + +.. date: 2023-06-01-11-24-03 +.. gh-issue: 105182 +.. nonce: l5sCw4 +.. section: C API + +Remove ``PyEval_AcquireLock()`` and ``PyEval_ReleaseLock()`` functions, +deprecated in Python 3.2. Patch by Victor Stinner. + +.. + +.. date: 2023-06-01-11-23-28 +.. gh-issue: 105182 +.. nonce: kLEHl- +.. section: C API + +Remove ``PyEval_InitThreads()`` and ``PyEval_ThreadsInitialized()`` +functions, deprecated in Python 3.9. Patch by Victor Stinner. + +.. + +.. date: 2023-06-01-09-40-30 +.. gh-issue: 105145 +.. nonce: WOOE-w +.. section: C API + +Deprecate old Python initialization functions: + +* :c:func:`PySys_ResetWarnOptions` +* :c:func:`Py_GetExecPrefix` +* :c:func:`Py_GetPath` +* :c:func:`Py_GetPrefix` +* :c:func:`Py_GetProgramFullPath` +* :c:func:`Py_GetProgramName` +* :c:func:`Py_GetPythonHome` + +Patch by Victor Stinner. + +.. + +.. date: 2023-05-31-19-38-45 +.. gh-issue: 85275 +.. nonce: doojgE +.. section: C API + +``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``, +``PyObject_CheckReadBuffer()``, and ``PyObject_AsWriteBuffer()`` are +removed. Please migrate to new buffer protocol; :c:func:`PyObject_GetBuffer` +and :c:func:`PyBuffer_Release`. + +.. + +.. date: 2023-05-31-18-37-57 +.. gh-issue: 105156 +.. nonce: R4El5V +.. section: C API + +Deprecate the old ``Py_UNICODE`` and ``PY_UNICODE_TYPE`` types: use directly +the :c:type:`wchar_t` type instead. Since Python 3.3, ``Py_UNICODE`` and +``PY_UNICODE_TYPE`` are just aliases to :c:type:`wchar_t`. Patch by Victor +Stinner. + +.. + +.. date: 2023-05-31-16-51-18 +.. gh-issue: 105145 +.. nonce: b3B6lJ +.. section: C API + +Remove the following old functions to configure the Python initialization, +deprecated in Python 3.11: + +* ``PySys_AddWarnOptionUnicode()`` +* ``PySys_AddWarnOption()`` +* ``PySys_AddXOption()`` +* ``PySys_HasWarnOptions()`` +* ``PySys_SetArgvEx()`` +* ``PySys_SetArgv()`` +* ``PySys_SetPath()`` +* ``Py_SetPath()`` +* ``Py_SetProgramName()`` +* ``Py_SetPythonHome()`` +* ``Py_SetStandardStreamEncoding()`` +* ``_Py_SetProgramFullPath()`` + +Patch by Victor Stinner. + +.. + +.. date: 2023-05-30-19-11-09 +.. gh-issue: 105107 +.. nonce: YQwMnm +.. section: C API + +Remove functions deprecated in Python 3.9. + +* ``PyEval_CallObject()``, ``PyEval_CallObjectWithKeywords()``: use + :c:func:`PyObject_CallNoArgs` and :c:func:`PyObject_Call` (positional + arguments must not be *NULL*) instead. +* ``PyEval_CallFunction()``: use :c:func:`PyObject_CallFunction` instead. +* ``PyEval_CallMethod()``: use :c:func:`PyObject_CallMethod` instead. +* ``PyCFunction_Call()``: use :c:func:`PyObject_Call` instead. + +Patch by Victor Stinner. + +.. + +.. date: 2023-05-30-17-45-32 +.. gh-issue: 105115 +.. nonce: iRho1K +.. section: C API + +``PyTypeObject.tp_bases`` (and ``tp_mro``) for builtin static types are now +shared by all interpreters, whereas in 3.12-beta1 they were stored on +``PyInterpreterState``. Also note that now the tuples are immortal objects. + +.. + +.. date: 2023-05-30-10-15-13 +.. gh-issue: 105071 +.. nonce: dPtp7c +.. section: C API + +Add ``PyUnstable_Exc_PrepReraiseStar`` to the unstable C api to expose the +implementation of :keyword:`except* `. + +.. + +.. date: 2023-05-29-16-09-27 +.. gh-issue: 104922 +.. nonce: L23qaU +.. section: C API + +``PY_SSIZE_T_CLEAN`` is no longer required to use ``'#'`` formats in APIs +like :c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue`. They uses +``Py_ssize_t`` for ``'#'`` regardless ``PY_SSIZE_T_CLEAN``. + +.. + +.. date: 2023-05-25-15-44-48 +.. gh-issue: 104584 +.. nonce: cSAoRh +.. section: C API + +Add an unstable C API for hooking in an optimizer. This is mainly internal, +but marked "unstable" to allow third-party experimentation. + +.. + +.. date: 2023-05-19-10-22-34 +.. gh-issue: 104668 +.. nonce: MLX1g9 +.. section: C API + +Don't call :c:var:`PyOS_InputHook` or :c:var:`PyOS_ReadlineFunctionPointer` +in subinterpreters, since it's generally difficult to avoid using global +state in their registered callbacks. This also avoids situations where +extensions may find themselves running in a subinterpreter they don't +support (or haven't yet been loaded in). + +.. + +.. bpo: 42327 +.. date: 2020-11-11-22-36-29 +.. nonce: ODSZBM +.. section: C API + +Add :c:func:`PyModule_Add` function: similar to +:c:func:`PyModule_AddObjectRef` and :c:func:`PyModule_AddObject`, but always +steals a reference to the value. + +.. + +.. bpo: 40309 +.. date: 2020-06-25-09-44-59 +.. nonce: CuoGoQ +.. section: C API + +Properly handle trailing spaces before closing parenthesis in +:c:func:`Py_BuildValue` format strings. diff --git a/Misc/NEWS.d/3.5.0rc1.rst b/Misc/NEWS.d/3.5.0rc1.rst index 1fb9bc6c04da38..64e9435b252acb 100644 --- a/Misc/NEWS.d/3.5.0rc1.rst +++ b/Misc/NEWS.d/3.5.0rc1.rst @@ -168,7 +168,7 @@ Sanad Zaki Rizvi. Idle editor default font. Switch from Courier to platform-sensitive TkFixedFont. This should not affect current customized font selections. If -there is a problem, edit $HOME/.idlerc/config-main.cfg and remove 'fontxxx' +there is a problem, edit $HOME/.idlerc/config-main.cfg and remove ':samp:`font{xxx}`' entries from [Editor Window]. Patch by Mark Roseman. .. diff --git a/Misc/NEWS.d/3.5.1rc1.rst b/Misc/NEWS.d/3.5.1rc1.rst index dc247ce2096a7d..05e1ecfaf6bc79 100644 --- a/Misc/NEWS.d/3.5.1rc1.rst +++ b/Misc/NEWS.d/3.5.1rc1.rst @@ -189,7 +189,7 @@ comprehensions correspond to the opening brace. .. nonce: 0Gh-Ty .. section: Core and Builtins -Hide the private _Py_atomic_xxx symbols from the public Python.h header to +Hide the private :samp:`_Py_atomic_{xxx}` symbols from the public Python.h header to fix a compilation error with OpenMP. PyThreadState_GET() becomes an alias to PyThreadState_Get() to avoid ABI incompatibilities. diff --git a/Misc/NEWS.d/3.5.4.rst b/Misc/NEWS.d/3.5.4.rst index cd0ca4872f1ab0..7839fa2709ecf2 100644 --- a/Misc/NEWS.d/3.5.4.rst +++ b/Misc/NEWS.d/3.5.4.rst @@ -5,4 +5,4 @@ .. section: Library ftplib.FTP.putline() now throws ValueError on commands that contains CR or -LF. Patch by Dong-hee Na. +LF. Patch by Donghee Na. diff --git a/Misc/NEWS.d/3.5.4rc1.rst b/Misc/NEWS.d/3.5.4rc1.rst index 04a035a41e7461..d65d5d14ee78bb 100644 --- a/Misc/NEWS.d/3.5.4rc1.rst +++ b/Misc/NEWS.d/3.5.4rc1.rst @@ -340,7 +340,7 @@ not keep objects alive longer than expected. .. section: Library inspect.signature() now supports callables with variable-argument parameters -wrapped with partialmethod. Patch by Dong-hee Na. +wrapped with partialmethod. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.6.0a1.rst b/Misc/NEWS.d/3.6.0a1.rst index 53f09b3dfe3363..98f1215fb91873 100644 --- a/Misc/NEWS.d/3.6.0a1.rst +++ b/Misc/NEWS.d/3.6.0a1.rst @@ -125,7 +125,7 @@ Setuptools 19.0. .. section: Core and Builtins Memory functions of the :c:func:`PyMem_Malloc` domain -(:c:data:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc allocator +(:c:macro:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc allocator ` rather than system :c:func:`malloc`. Applications calling :c:func:`PyMem_Malloc` without holding the GIL can now crash: use ``PYTHONMALLOC=debug`` environment variable to validate the usage of memory diff --git a/Misc/NEWS.d/3.6.0rc1.rst b/Misc/NEWS.d/3.6.0rc1.rst index 15769f950db239..658f8c902d8704 100644 --- a/Misc/NEWS.d/3.6.0rc1.rst +++ b/Misc/NEWS.d/3.6.0rc1.rst @@ -69,8 +69,8 @@ supported. .. nonce: ilNIWN .. section: Library -Add new :data:`socket.TCP_CONGESTION` (Linux 2.6.13) and -:data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by +Add new :const:`socket.TCP_CONGESTION` (Linux 2.6.13) and +:const:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by Omar Sandoval. .. diff --git a/Misc/NEWS.d/3.6.2rc1.rst b/Misc/NEWS.d/3.6.2rc1.rst index cdf4c3d541c4ca..28eb88f79130c5 100644 --- a/Misc/NEWS.d/3.6.2rc1.rst +++ b/Misc/NEWS.d/3.6.2rc1.rst @@ -77,7 +77,7 @@ delivered to the innermost frame. .. section: Core and Builtins sys.getsizeof() on a code object now returns the sizes which includes the -code struct and sizes of objects which it references. Patch by Dong-hee Na. +code struct and sizes of objects which it references. Patch by Donghee Na. .. @@ -163,7 +163,7 @@ no longer ignored. Patch by Mircea Cosbuc. .. nonce: I2mDTz .. section: Library -Functional API of enum allows to create empty enums. Patched by Dong-hee Na +Functional API of enum allows to create empty enums. Patched by Donghee Na .. @@ -202,7 +202,7 @@ not keep objects alive longer than expected. .. section: Library inspect.signature() now supports callables with variable-argument parameters -wrapped with partialmethod. Patch by Dong-hee Na. +wrapped with partialmethod. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.6.3rc1.rst b/Misc/NEWS.d/3.6.3rc1.rst index 4dc2eef5d3b61b..4b2aae9dc88441 100644 --- a/Misc/NEWS.d/3.6.3rc1.rst +++ b/Misc/NEWS.d/3.6.3rc1.rst @@ -506,7 +506,7 @@ Fix handling of long oids in ssl. Based on patch by Christian Heimes. .. section: Library ftplib.FTP.putline() now throws ValueError on commands that contains CR or -LF. Patch by Dong-hee Na. +LF. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/3.6.6rc1.rst b/Misc/NEWS.d/3.6.6rc1.rst index 71a5c3ec595ba2..9624195c79043b 100644 --- a/Misc/NEWS.d/3.6.6rc1.rst +++ b/Misc/NEWS.d/3.6.6rc1.rst @@ -289,7 +289,7 @@ literals on pydoc. Patch by Andrés Delfino. .. section: Library Update error message when constructing invalid inspect.Parameters Patch by -Dong-hee Na. +Donghee Na. .. diff --git a/Misc/NEWS.d/3.7.0a1.rst b/Misc/NEWS.d/3.7.0a1.rst index ef93454784b77f..bee424241fd712 100644 --- a/Misc/NEWS.d/3.7.0a1.rst +++ b/Misc/NEWS.d/3.7.0a1.rst @@ -529,7 +529,7 @@ name are now supported. .. section: Core and Builtins sys.getsizeof() on a code object now returns the sizes which includes the -code struct and sizes of objects which it references. Patch by Dong-hee Na. +code struct and sizes of objects which it references. Patch by Donghee Na. .. @@ -2260,7 +2260,7 @@ Update zlib to 1.2.11. .. section: Library ftplib.FTP.putline() now throws ValueError on commands that contains CR or -LF. Patch by Dong-hee Na. +LF. Patch by Donghee Na. .. @@ -2329,7 +2329,7 @@ always return bytes. .. nonce: I2mDTz .. section: Library -Functional API of enum allows to create empty enums. Patched by Dong-hee Na +Functional API of enum allows to create empty enums. Patched by Donghee Na .. @@ -2612,7 +2612,7 @@ Fix handling escape characters in HZ codec. Based on patch by Ma Lin. .. section: Library inspect.signature() now supports callables with variable-argument parameters -wrapped with partialmethod. Patch by Dong-hee Na. +wrapped with partialmethod. Patch by Donghee Na. .. @@ -3274,7 +3274,7 @@ Added support for bytes paths in os.fwalk(). .. nonce: 37jMwb .. section: Library -Add new :data:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constant. Patch by +Add new :const:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constant. Patch by Nathaniel J. Smith. .. @@ -3871,8 +3871,8 @@ as an integer. Function only available on Android. .. nonce: ilNIWN .. section: Library -Add new :data:`socket.TCP_CONGESTION` (Linux 2.6.13) and -:data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by +Add new :const:`socket.TCP_CONGESTION` (Linux 2.6.13) and +:const:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by Omar Sandoval. .. diff --git a/Misc/NEWS.d/3.7.0a3.rst b/Misc/NEWS.d/3.7.0a3.rst index 368efb73567c40..a968616f55be68 100644 --- a/Misc/NEWS.d/3.7.0a3.rst +++ b/Misc/NEWS.d/3.7.0a3.rst @@ -539,7 +539,7 @@ optional .. section: Library Updates 2to3 to convert from operator.isCallable(obj) to callable(obj). -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -549,7 +549,7 @@ Patch by Dong-hee Na. .. section: Library inspect.signature should follow :pep:`8`, if the parameter has an annotation -and a default value. Patch by Dong-hee Na. +and a default value. Patch by Donghee Na. .. @@ -754,8 +754,8 @@ now accepts characters as arguments. Based on patch by Steve Fink. .. nonce: DYQL0g .. section: Library -Add 3 new clock identifiers: :data:`time.CLOCK_BOOTTIME`, -:data:`time.CLOCK_PROF` and :data:`time.CLOCK_UPTIME`. +Add 3 new clock identifiers: :const:`time.CLOCK_BOOTTIME`, +:const:`time.CLOCK_PROF` and :const:`time.CLOCK_UPTIME`. .. diff --git a/Misc/NEWS.d/3.7.0a4.rst b/Misc/NEWS.d/3.7.0a4.rst index f19d1a1823584b..ebae046a7a6ba0 100644 --- a/Misc/NEWS.d/3.7.0a4.rst +++ b/Misc/NEWS.d/3.7.0a4.rst @@ -842,5 +842,5 @@ Moved the pygetopt.h header into internal/, since it has no public APIs. .. nonce: LbyQt6 .. section: C API -:c:func:`Py_SetProgramName` and :c:func:`Py_SetPythonHome` now take the +:c:func:`!Py_SetProgramName` and :c:func:`!Py_SetPythonHome` now take the ``const wchar *`` arguments instead of ``wchar *``. diff --git a/Misc/NEWS.d/3.7.0b5.rst b/Misc/NEWS.d/3.7.0b5.rst index 20476993b9652a..fb29109869188b 100644 --- a/Misc/NEWS.d/3.7.0b5.rst +++ b/Misc/NEWS.d/3.7.0b5.rst @@ -418,7 +418,7 @@ trigger a ``DeprecationWarning`` and have been marked for removal in Python .. section: Library Update error message when constructing invalid inspect.Parameters Patch by -Dong-hee Na. +Donghee Na. .. diff --git a/Misc/NEWS.d/3.8.0a1.rst b/Misc/NEWS.d/3.8.0a1.rst index 2634832b78a96e..0dc6e945719ec7 100644 --- a/Misc/NEWS.d/3.8.0a1.rst +++ b/Misc/NEWS.d/3.8.0a1.rst @@ -380,7 +380,7 @@ Implement :pep:`572` (assignment expressions). Patch by Emily Morehouse. .. nonce: voIdcp .. section: Core and Builtins -Speed up :class:`namedtuple` attribute access by 1.6x using a C fast-path +Speed up :func:`namedtuple` attribute access by 1.6x using a C fast-path for the name descriptors. Patch by Pablo Galindo. .. @@ -1934,7 +1934,7 @@ failure. .. nonce: _ct_0H .. section: Library -The :data:`time.CLOCK_UPTIME_RAW` constant is now available for macOS 10.12. +The :const:`time.CLOCK_UPTIME_RAW` constant is now available for macOS 10.12. .. @@ -1965,7 +1965,7 @@ result of an internal future if it's already done. .. section: Library Add a deprecated warning for the :meth:`threading.Thread.isAlive` method. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -4974,7 +4974,7 @@ Enum members. .. section: Library Update error message when constructing invalid inspect.Parameters Patch by -Dong-hee Na. +Donghee Na. .. @@ -8253,7 +8253,7 @@ Explain how IDLE's Shell displays output. Improve the doc about IDLE running user code. The section is renamed from "IDLE -- console differences" is renamed "Running user code". It mostly -covers the implications of using custom sys.stdxxx objects. +covers the implications of using custom :samp:`sys.std{xxx}` objects. .. @@ -8765,7 +8765,7 @@ for relative path to files in current directory. .. nonce: fmehdG .. section: C API -The :c:func:`PyByteArray_Init` and :c:func:`PyByteArray_Fini` functions have +The :c:func:`!PyByteArray_Init` and :c:func:`!PyByteArray_Fini` functions have been removed. They did nothing since Python 2.7.4 and Python 3.2.0, were excluded from the limited API (stable ABI), and were not documented. @@ -8836,7 +8836,7 @@ Py_LIMITED_API. Patch by Arthur Neufeld. .. nonce: gFd85N .. section: C API -The :c:func:`_PyObject_GC_TRACK` and :c:func:`_PyObject_GC_UNTRACK` macros +The :c:func:`!_PyObject_GC_TRACK` and :c:func:`!_PyObject_GC_UNTRACK` macros have been removed from the public C API. .. diff --git a/Misc/NEWS.d/3.8.0a4.rst b/Misc/NEWS.d/3.8.0a4.rst index 9841195210c9e7..7e8bfa5c4364a9 100644 --- a/Misc/NEWS.d/3.8.0a4.rst +++ b/Misc/NEWS.d/3.8.0a4.rst @@ -92,7 +92,7 @@ the field. .. nonce: wejLoC .. section: Core and Builtins -On AIX, :attr:`sys.platform` doesn't contain the major version anymore. +On AIX, :data:`sys.platform` doesn't contain the major version anymore. Always return ``'aix'``, instead of ``'aix3'`` .. ``'aix7'``. Since older Python versions include the version number, it is recommended to always use ``sys.platform.startswith('aix')``. Contributed by M. Felt. @@ -124,7 +124,7 @@ Galindo. .. nonce: CjRps3 .. section: Core and Builtins -:c:func:`PyEval_AcquireLock` and :c:func:`PyEval_AcquireThread` now +:c:func:`!PyEval_AcquireLock` and :c:func:`!PyEval_AcquireThread` now terminate the current thread if called while the interpreter is finalizing, making them consistent with :c:func:`PyEval_RestoreThread`, :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`. @@ -955,7 +955,7 @@ Add a new :mod:`_testinternalcapi` module to test the internal C API. .. section: Tests Fix ``test_imap4_host_default_value()`` of ``test_imaplib``: catch also -:data:`errno.ENETUNREACH` error. +:const:`errno.ENETUNREACH` error. .. @@ -1087,7 +1087,7 @@ on the ABI. Change ``PyAPI_FUNC(type)``, ``PyAPI_DATA(type)`` and ``PyMODINIT_FUNC`` macros of ``pyport.h`` when ``Py_BUILD_CORE_MODULE`` is defined. The ``Py_BUILD_CORE_MODULE`` define must be now be used to build a C extension -as a dynamic library accessing Python internals: export the PyInit_xxx() +as a dynamic library accessing Python internals: export the :samp:`PyInit_{xxx}()` function in DLL exports on Windows. .. @@ -1344,7 +1344,7 @@ Fix the argument handling in Tools/scripts/lll.py. .. nonce: vghb86 .. section: C API -Fix memory leak in :c:func:`Py_SetStandardStreamEncoding`: release memory if +Fix memory leak in :c:func:`!Py_SetStandardStreamEncoding`: release memory if the function is called twice. .. diff --git a/Misc/NEWS.d/3.8.0b1.rst b/Misc/NEWS.d/3.8.0b1.rst index 72e6b31874e373..c5e27b04ef8e8b 100644 --- a/Misc/NEWS.d/3.8.0b1.rst +++ b/Misc/NEWS.d/3.8.0b1.rst @@ -2047,6 +2047,6 @@ unbound methods. These are objects supporting the optimization given by the .. nonce: FR-dMP .. section: C API -The :c:func:`PyEval_ReInitThreads` function has been removed from the C API. +The :c:func:`!PyEval_ReInitThreads` function has been removed from the C API. It should not be called explicitly: use :c:func:`PyOS_AfterFork_Child` instead. diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst index 5ae14293df3e33..9818c17705074b 100644 --- a/Misc/NEWS.d/3.9.0a1.rst +++ b/Misc/NEWS.d/3.9.0a1.rst @@ -33,7 +33,7 @@ Fixes audit event for :func:`os.system` to be named ``os.system``. .. section: Security Escape the server title of :class:`xmlrpc.server.DocXMLRPCServer` when -rendering the document page as HTML. (Contributed by Dong-hee Na in +rendering the document page as HTML. (Contributed by Donghee Na in :issue:`38243`.) .. @@ -203,7 +203,7 @@ arguments in decorators. .. section: Core and Builtins Fix a segmentation fault when using reverse iterators of empty ``dict`` -objects. Patch by Dong-hee Na and Inada Naoki. +objects. Patch by Donghee Na and Inada Naoki. .. @@ -280,7 +280,7 @@ visited by ``tp_traverse()`` are valid. .. section: Core and Builtins Remove unnecessary intersection and update set operation in dictview with -empty set. (Contributed by Dong-hee Na in :issue:`38210`.) +empty set. (Contributed by Donghee Na in :issue:`38210`.) .. @@ -1164,7 +1164,7 @@ defines them with eponymous methods. .. nonce: bmhquU .. section: Library -Add :data:`os.P_PIDFD` constant, which may be passed to :func:`os.waitid` to +Add :const:`os.P_PIDFD` constant, which may be passed to :func:`os.waitid` to wait on a Linux process file descriptor. .. @@ -1193,8 +1193,8 @@ Expose the Linux ``pidfd_open`` syscall as :func:`os.pidfd_open`. .. nonce: 7jvYFA .. section: Library -Added constants :data:`~fcntl.F_OFD_GETLK`, :data:`~fcntl.F_OFD_SETLK` and -:data:`~fcntl.F_OFD_SETLKW` to the :mod:`fcntl` module. Patch by Dong-hee +Added constants :const:`~fcntl.F_OFD_GETLK`, :const:`~fcntl.F_OFD_SETLK` and +:const:`~fcntl.F_OFD_SETLKW` to the :mod:`fcntl` module. Patch by Donghee Na. .. @@ -1283,8 +1283,8 @@ Fixed erroneous equality comparison in statistics.NormalDist(). .. nonce: 86ExWB .. section: Library -Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for -:attr:`si_code`. Patch by Dong-hee Na. +Added :const:`~os.CLD_KILLED` and :const:`~os.CLD_STOPPED` for +:attr:`si_code`. Patch by Donghee Na. .. @@ -1355,8 +1355,8 @@ objects, patch by Samuel Colvin. .. 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 +Add missing :const:`stat.S_IFDOOR`, :const:`stat.S_IFPORT`, +:const:`stat.S_IFWHT`, :func:`stat.S_ISDOOR`, :func:`stat.S_ISPORT`, and :func:`stat.S_ISWHT` values to the Python implementation of :mod:`stat`. .. @@ -1882,7 +1882,7 @@ avoid dynamic lookup. .. section: Library Update :class:`importlib.machinery.BuiltinImporter` to use -``loader._ORIGIN`` instead of a hardcoded value. Patch by Dong-hee Na. +``loader._ORIGIN`` instead of a hardcoded value. Patch by Donghee Na. .. @@ -2080,7 +2080,7 @@ method which emits a deprecation warning and calls corresponding methody .. 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 +for both C and Python implementations. Patch by Donghee Na .. @@ -2201,7 +2201,7 @@ uses more than ``SIGSTKSZ`` bytes of stack memory on some platforms. .. nonce: AmXrik .. section: Library -Add C fastpath for statistics.NormalDist.inv_cdf() Patch by Dong-hee Na +Add C fastpath for statistics.NormalDist.inv_cdf() Patch by Donghee Na .. @@ -2210,7 +2210,7 @@ Add C fastpath for statistics.NormalDist.inv_cdf() Patch by Dong-hee Na .. nonce: Ene6L- .. section: Library -Remove the deprecated method `threading.Thread.isAlive()`. Patch by Dong-hee +Remove the deprecated method `threading.Thread.isAlive()`. Patch by Donghee Na. .. @@ -4089,7 +4089,7 @@ Increase code coverage for multiprocessing.shared_memory. .. nonce: Kl1sti .. section: Tests -Add tests for json.dump(..., skipkeys=True). Patch by Dong-hee Na. +Add tests for json.dump(..., skipkeys=True). Patch by Donghee Na. .. @@ -4118,7 +4118,7 @@ Add tests for ROT-13 codec. .. nonce: Zoe9ek .. section: Tests -Added tests for PyDateTime_xxx_GET_xxx() macros of the C API of the +Added tests for :samp:`PyDateTime_{xxx}_GET_{xxx}()` macros of the C API of the :mod:`datetime` module. Patch by Joannah Nanjekye. .. @@ -4576,7 +4576,7 @@ distutils bdist_wininst: bdist_wininst only works on Windows. .. nonce: j5ebdT .. section: Build -Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were no longer +Many :samp:`PyRun_{XXX}()` functions like :c:func:`PyRun_String` were no longer exported in ``libpython38.dll`` by mistake. Export them again to fix the ABI compatibility. @@ -4983,7 +4983,7 @@ set to CP_UTF7 or CP_UTF8. .. nonce: -0g2O3 .. section: Windows -Make :data:`winreg.REG_MULTI_SZ` support zero-length strings. +Make :const:`winreg.REG_MULTI_SZ` support zero-length strings. .. @@ -5535,7 +5535,7 @@ Tyler Kieft. .. nonce: d0bhEA .. section: C API -:c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full +: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`). @@ -5546,8 +5546,8 @@ path (:c:func:`Py_GetProgramFullPath`) rather than to the program name .. 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 +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. .. @@ -5686,7 +5686,7 @@ positional argument. .. nonce: zrmgki .. section: C API -Add :func:`PyConfig_SetWideStringList` function. +Add :c:func:`PyConfig_SetWideStringList` function. .. @@ -5706,7 +5706,7 @@ and :c:func:`_PyObject_CallMethodOneArg`. .. nonce: qZC0N_ .. section: C API -The :const:`METH_FASTCALL` calling convention has been documented. +The :c:macro:`METH_FASTCALL` calling convention has been documented. .. diff --git a/Misc/NEWS.d/3.9.0a3.rst b/Misc/NEWS.d/3.9.0a3.rst index 8b7ff49668e1c0..8a94848427382b 100644 --- a/Misc/NEWS.d/3.9.0a3.rst +++ b/Misc/NEWS.d/3.9.0a3.rst @@ -149,7 +149,7 @@ argument - by Anthony Sottile. .. section: Core and Builtins Correct the error message when calling the :func:`min` or :func:`max` with -no arguments. Patch by Dong-hee Na. +no arguments. Patch by Donghee Na. .. @@ -392,7 +392,7 @@ Remove ``fractions.gcd()`` function, deprecated since Python 3.5 .. section: Library :class:`~smtplib.LMTP` constructor now has an optional *timeout* parameter. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -414,7 +414,7 @@ Taskaya. :class:`~ftplib.FTP_TLS` and :class:`~ftplib.FTP_TLS` now raise a :class:`ValueError` if the given timeout for their constructor is zero to -prevent the creation of a non-blocking socket. Patch by Dong-hee Na. +prevent the creation of a non-blocking socket. Patch by Donghee Na. .. @@ -425,7 +425,7 @@ prevent the creation of a non-blocking socket. Patch by Dong-hee Na. :class:`~smtplib.SMTP` and :class:`~smtplib.SMTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to -prevent the creation of a non-blocking socket. Patch by Dong-hee Na. +prevent the creation of a non-blocking socket. Patch by Donghee Na. .. @@ -456,7 +456,7 @@ resilients to inaccessible sys.path entries (importlib_metadata v1.4.0). :class:`~!nntplib.NNTP` and :class:`~!nntplib.NNTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to -prevent the creation of a non-blocking socket. Patch by Dong-hee Na. +prevent the creation of a non-blocking socket. Patch by Donghee Na. .. @@ -488,7 +488,7 @@ towards *y*. :class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to -prevent the creation of a non-blocking socket. Patch by Dong-hee Na. +prevent the creation of a non-blocking socket. Patch by Donghee Na. .. @@ -571,7 +571,7 @@ new task spawning before exception raising. .. section: Library Correctly parenthesize filter-based statements that contain lambda -expressions in mod:`!lib2to3`. Patch by Dong-hee Na. +expressions in mod:`!lib2to3`. Patch by Donghee Na. .. @@ -699,7 +699,7 @@ upon inheritance. Patch by Bar Harel. :meth:`~imaplib.IMAP4.open` method now has an optional *timeout* parameter with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and :class:`~imaplib.IMAP4_stream` were applied to this change. Patch by -Dong-hee Na. +Donghee Na. .. diff --git a/Misc/NEWS.d/3.9.0a4.rst b/Misc/NEWS.d/3.9.0a4.rst index 019b34c4082d10..e59435b5509acf 100644 --- a/Misc/NEWS.d/3.9.0a4.rst +++ b/Misc/NEWS.d/3.9.0a4.rst @@ -43,7 +43,7 @@ first item. Patch by Yonatan Goldschmidt. .. nonce: BIIX2M .. section: Core and Builtins -Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by Dong-hee Na. +Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by Donghee Na. .. @@ -141,7 +141,7 @@ collection of deleted, pickled objects. .. section: Core and Builtins Fixed a possible crash in :meth:`list.__contains__` when a list is changed -during comparing items. Patch by Dong-hee Na. +during comparing items. Patch by Donghee Na. .. @@ -152,7 +152,7 @@ during comparing items. Patch by Dong-hee Na. :term:`floor division` of float operation now has a better performance. Also the message of :exc:`ZeroDivisionError` for this operation is updated. Patch -by Dong-hee Na. +by Donghee Na. .. diff --git a/Misc/NEWS.d/3.9.0a5.rst b/Misc/NEWS.d/3.9.0a5.rst index 25342d21d8f0b1..6ff05788214723 100644 --- a/Misc/NEWS.d/3.9.0a5.rst +++ b/Misc/NEWS.d/3.9.0a5.rst @@ -96,7 +96,7 @@ Port itertools module to multiphase initialization (:pep:`489`). .. section: Core and Builtins Speed up calls to ``frozenset()`` by using the :pep:`590` ``vectorcall`` -calling convention. Patch by Dong-hee Na. +calling convention. Patch by Donghee Na. .. @@ -117,7 +117,7 @@ own variable. .. section: Core and Builtins Speed up calls to ``set()`` by using the :pep:`590` ``vectorcall`` calling -convention. Patch by Dong-hee Na. +convention. Patch by Donghee Na. .. @@ -166,7 +166,7 @@ Allow executing asynchronous comprehensions on the top level when the .. section: Core and Builtins Speed up calls to ``tuple()`` by using the :pep:`590` ``vectorcall`` calling -convention. Patch by Dong-hee Na. +convention. Patch by Donghee Na. .. @@ -571,7 +571,7 @@ Fixed :func:`ast.unparse` for extended slices containing a single element .. nonce: yWq9NJ .. section: Library -Fix :mod:`json.tool` to catch :exc:`BrokenPipeError`. Patch by Dong-hee Na. +Fix :mod:`json.tool` to catch :exc:`BrokenPipeError`. Patch by Donghee Na. .. @@ -582,7 +582,7 @@ Fix :mod:`json.tool` to catch :exc:`BrokenPipeError`. Patch by Dong-hee Na. Avoid a possible *"RuntimeError: dictionary changed size during iteration"* from :func:`inspect.getmodule` when it tried to loop through -:attr:`sys.modules`. +:data:`sys.modules`. .. @@ -783,7 +783,7 @@ when the optional ``qop`` parameter is not present. .. section: Library HTTP status codes ``103 EARLY_HINTS`` and ``425 TOO_EARLY`` are added to -:class:`http.HTTPStatus`. Patch by Dong-hee Na. +:class:`http.HTTPStatus`. Patch by Donghee Na. .. @@ -989,7 +989,7 @@ modules are built. Add ``--with-platlibdir`` option to the configure script: name of the platform-specific library directory, stored in the new -:attr:`sys.platlibdir` attribute. It is used to build the path of +:data:`sys.platlibdir` attribute. It is used to build the path of platform-specific extension modules and the path of the standard library. It is equal to ``"lib"`` on most platforms. On Fedora and SuSE, it is equal to ``"lib64"`` on 64-bit platforms. Patch by Jan MatÄ›jek, MatÄ›j Cepl, @@ -1133,7 +1133,7 @@ module. Patch by José Roberto Meza Cabrera. .. section: C API Add :c:func:`PyModule_AddType` helper function: add a type to a module. -Patch by Dong-hee Na. +Patch by Donghee Na. .. @@ -1163,7 +1163,7 @@ Python thread state. .. nonce: R3jaTy .. section: C API -Add _PyArg_NoKwnames helper function. Patch by Dong-hee Na. +Add _PyArg_NoKwnames helper function. Patch by Donghee Na. .. @@ -1234,8 +1234,8 @@ method name in the SystemError "bad call flags" error message to ease debug. .. nonce: GOYtIm .. section: C API -Deprecated :c:func:`PyEval_InitThreads` and -:c:func:`PyEval_ThreadsInitialized`. Calling :c:func:`PyEval_InitThreads` +Deprecated :c:func:`!PyEval_InitThreads` and +:c:func:`!PyEval_ThreadsInitialized`. Calling :c:func:`!PyEval_InitThreads` now does nothing. .. diff --git a/Misc/NEWS.d/3.9.0a6.rst b/Misc/NEWS.d/3.9.0a6.rst index 9594964917f390..519c7f833ebcb8 100644 --- a/Misc/NEWS.d/3.9.0a6.rst +++ b/Misc/NEWS.d/3.9.0a6.rst @@ -680,7 +680,7 @@ child process, reset the lock to the unlocked state. Rename also the private .. nonce: kIjVge .. section: Library -Expose :data:`~socket.CAN_RAW_JOIN_FILTERS` in the :mod:`socket` module. +Expose :const:`~socket.CAN_RAW_JOIN_FILTERS` in the :mod:`socket` module. .. @@ -735,7 +735,7 @@ number of groups. For other implementations, double the group list size. .. nonce: HFpHZS .. section: Library -Add :data:`time.CLOCK_TAI` constant if the operating system support it. +Add :const:`time.CLOCK_TAI` constant if the operating system support it. .. diff --git a/Misc/NEWS.d/3.9.0b1.rst b/Misc/NEWS.d/3.9.0b1.rst index 15790bc425c13f..ee87315ad334e9 100644 --- a/Misc/NEWS.d/3.9.0b1.rst +++ b/Misc/NEWS.d/3.9.0b1.rst @@ -490,7 +490,7 @@ The first argument of :func:`pickle.loads` is now positional-only. .. section: Library Update :mod:`!nntplib` to merge :class:`!nntplib.NNTP` and -:class:`!nntplib._NNTPBase`. Patch by Dong-hee Na. +:class:`!nntplib._NNTPBase`. Patch by Donghee Na. .. @@ -500,7 +500,7 @@ Update :mod:`!nntplib` to merge :class:`!nntplib.NNTP` and .. section: Library Update :mod:`dbm.gnu` to use gdbm_count if possible when calling -:func:`len`. Patch by Dong-hee Na. +:func:`len`. Patch by Donghee Na. .. @@ -592,7 +592,7 @@ subdirectories in package data, matching backport in importlib_resources .. nonce: 5GuK2A .. section: Library -:meth:`imaplib.IMAP4.unselect` is added. Patch by Dong-hee Na. +:meth:`imaplib.IMAP4.unselect` is added. Patch by Donghee Na. .. diff --git a/Misc/NEWS.d/next/Build/2023-02-03-21-36-42.gh-issue-101538.sF5F6S.rst b/Misc/NEWS.d/next/Build/2023-02-03-21-36-42.gh-issue-101538.sF5F6S.rst deleted file mode 100644 index 4b83c303b3d2c5..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-02-03-21-36-42.gh-issue-101538.sF5F6S.rst +++ /dev/null @@ -1 +0,0 @@ -Add experimental wasi-threads support. Patch by Takashi Yamamoto. diff --git a/Misc/NEWS.d/next/Build/2023-05-20-23-49-30.gh-issue-104692.s5UIu5.rst b/Misc/NEWS.d/next/Build/2023-05-20-23-49-30.gh-issue-104692.s5UIu5.rst deleted file mode 100644 index 2936990999e1aa..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-05-20-23-49-30.gh-issue-104692.s5UIu5.rst +++ /dev/null @@ -1,6 +0,0 @@ -Include ``commoninstall`` as a prerequisite for ``bininstall`` - -This ensures that ``commoninstall`` is completed before ``bininstall`` -is started when parallel builds are used (``make -j install``), and so -the ``python3`` symlink is only installed after all standard library -modules are installed. diff --git a/Misc/NEWS.d/next/Build/2023-05-26-15-44-20.gh-issue-89886._iSW-p.rst b/Misc/NEWS.d/next/Build/2023-05-26-15-44-20.gh-issue-89886._iSW-p.rst deleted file mode 100644 index 83559545e86141..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-05-26-15-44-20.gh-issue-89886._iSW-p.rst +++ /dev/null @@ -1,2 +0,0 @@ -Autoconf 2.71 and aclocal 1.16.4 is now required to regenerate -:file:`!configure`. diff --git a/Misc/NEWS.d/next/Build/2023-06-02-19-12-45.gh-issue-102404.Ry9piA.rst b/Misc/NEWS.d/next/Build/2023-06-02-19-12-45.gh-issue-102404.Ry9piA.rst deleted file mode 100644 index 7fe593d77cb762..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-06-02-19-12-45.gh-issue-102404.Ry9piA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document how to perform a WASI build on Linux. Also add -Tools/wasm/build_wasi.sh as a reference implementation of the docs. diff --git a/Misc/NEWS.d/next/Build/2023-06-06-09-08-10.gh-issue-90005.8mmeJQ.rst b/Misc/NEWS.d/next/Build/2023-06-06-09-08-10.gh-issue-90005.8mmeJQ.rst deleted file mode 100644 index 0a23fbf0c0fbdd..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-06-06-09-08-10.gh-issue-90005.8mmeJQ.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a regression in :file:`configure` where we could end up unintentionally linking with ``libbsd``. diff --git a/Misc/NEWS.d/next/Build/2023-06-16-23-40-49.gh-issue-105875.naj8v5.rst b/Misc/NEWS.d/next/Build/2023-06-16-23-40-49.gh-issue-105875.naj8v5.rst deleted file mode 100644 index 5f60e65a2f6ae8..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-06-16-23-40-49.gh-issue-105875.naj8v5.rst +++ /dev/null @@ -1,2 +0,0 @@ -SQLite 3.15.2 or newer is required to build the :mod:`sqlite3` extension -module. Patch by Erlend Aasland. diff --git a/Misc/NEWS.d/next/Build/2023-06-26-21-56-29.gh-issue-106118.0cCfhl.rst b/Misc/NEWS.d/next/Build/2023-06-26-21-56-29.gh-issue-106118.0cCfhl.rst deleted file mode 100644 index f93cae5d03b539..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-06-26-21-56-29.gh-issue-106118.0cCfhl.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix compilation for platforms without :data:`!O_CLOEXEC`. The issue was -introduced with Python 3.12b1 in :gh:`103295`. Patch by Erlend Aasland. diff --git a/Misc/NEWS.d/next/C API/2020-11-11-22-36-29.bpo-42327.ODSZBM.rst b/Misc/NEWS.d/next/C API/2020-11-11-22-36-29.bpo-42327.ODSZBM.rst deleted file mode 100644 index 3d935aceb57a79..00000000000000 --- a/Misc/NEWS.d/next/C API/2020-11-11-22-36-29.bpo-42327.ODSZBM.rst +++ /dev/null @@ -1 +0,0 @@ -Add :func:`PyModule_Add` function: similar to :c:func:`PyModule_AddObjectRef` and :c:func:`PyModule_AddObject`, but always steals a reference to the value. diff --git a/Misc/NEWS.d/next/C API/2023-05-19-10-22-34.gh-issue-104668.MLX1g9.rst b/Misc/NEWS.d/next/C API/2023-05-19-10-22-34.gh-issue-104668.MLX1g9.rst deleted file mode 100644 index 7b882afd7f81a0..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-19-10-22-34.gh-issue-104668.MLX1g9.rst +++ /dev/null @@ -1,5 +0,0 @@ -Don't call :c:var:`PyOS_InputHook` or :c:var:`PyOS_ReadlineFunctionPointer` -in subinterpreters, since it's generally difficult to avoid using global -state in their registered callbacks. This also avoids situations where -extensions may find themselves running in a subinterpreter they don't -support (or haven't yet been loaded in). diff --git a/Misc/NEWS.d/next/C API/2023-05-25-15-44-48.gh-issue-104584.cSAoRh.rst b/Misc/NEWS.d/next/C API/2023-05-25-15-44-48.gh-issue-104584.cSAoRh.rst deleted file mode 100644 index 9ce0373e8ac9d4..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-25-15-44-48.gh-issue-104584.cSAoRh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add an unstable C API for hooking in an optimizer. This is mainly internal, -but marked "unstable" to allow third-party experimentation. diff --git a/Misc/NEWS.d/next/C API/2023-05-29-16-09-27.gh-issue-104922.L23qaU.rst b/Misc/NEWS.d/next/C API/2023-05-29-16-09-27.gh-issue-104922.L23qaU.rst deleted file mode 100644 index ca56d0b4403b8c..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-29-16-09-27.gh-issue-104922.L23qaU.rst +++ /dev/null @@ -1,3 +0,0 @@ -``PY_SSIZE_T_CLEAN`` is no longer required to use ``'#'`` formats in APIs -like :c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue`. They uses -``Py_ssize_t`` for ``'#'`` regardless ``PY_SSIZE_T_CLEAN``. diff --git a/Misc/NEWS.d/next/C API/2023-05-30-10-15-13.gh-issue-105071.dPtp7c.rst b/Misc/NEWS.d/next/C API/2023-05-30-10-15-13.gh-issue-105071.dPtp7c.rst deleted file mode 100644 index 3d916fcb961f62..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-30-10-15-13.gh-issue-105071.dPtp7c.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``PyUnstable_Exc_PrepReraiseStar`` to the unstable C api to expose the implementation of :keyword:`except* `. diff --git a/Misc/NEWS.d/next/C API/2023-05-30-17-45-32.gh-issue-105115.iRho1K.rst b/Misc/NEWS.d/next/C API/2023-05-30-17-45-32.gh-issue-105115.iRho1K.rst deleted file mode 100644 index 595cc0e2013d96..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-30-17-45-32.gh-issue-105115.iRho1K.rst +++ /dev/null @@ -1,3 +0,0 @@ -``PyTypeObject.tp_bases`` (and ``tp_mro``) for builtin static types are now -shared by all interpreters, whereas in 3.12-beta1 they were stored on -``PyInterpreterState``. Also note that now the tuples are immortal objects. diff --git a/Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst b/Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst deleted file mode 100644 index 6cc758cb83962b..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst +++ /dev/null @@ -1,10 +0,0 @@ -Remove functions deprecated in Python 3.9. - -* ``PyEval_CallObject()``, ``PyEval_CallObjectWithKeywords()``: use - :c:func:`PyObject_CallNoArgs` and :c:func:`PyObject_Call` (positional - arguments must not be *NULL*) instead. -* ``PyEval_CallFunction()``: use :c:func:`PyObject_CallFunction` instead. -* ``PyEval_CallMethod()``: use :c:func:`PyObject_CallMethod` instead. -* ``PyCFunction_Call()``: use :c:func:`PyObject_Call` instead. - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-05-31-16-51-18.gh-issue-105145.b3B6lJ.rst b/Misc/NEWS.d/next/C API/2023-05-31-16-51-18.gh-issue-105145.b3B6lJ.rst deleted file mode 100644 index a3ad765b696230..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-31-16-51-18.gh-issue-105145.b3B6lJ.rst +++ /dev/null @@ -1,17 +0,0 @@ -Remove the following old functions to configure the Python initialization, -deprecated in Python 3.11: - -* ``PySys_AddWarnOptionUnicode()`` -* ``PySys_AddWarnOption()`` -* ``PySys_AddXOption()`` -* ``PySys_HasWarnOptions()`` -* ``PySys_SetArgvEx()`` -* ``PySys_SetArgv()`` -* ``PySys_SetPath()`` -* ``Py_SetPath()`` -* ``Py_SetProgramName()`` -* ``Py_SetPythonHome()`` -* ``Py_SetStandardStreamEncoding()`` -* ``_Py_SetProgramFullPath()`` - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-05-31-18-37-57.gh-issue-105156.R4El5V.rst b/Misc/NEWS.d/next/C API/2023-05-31-18-37-57.gh-issue-105156.R4El5V.rst deleted file mode 100644 index cbdb8379f24ccd..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-31-18-37-57.gh-issue-105156.R4El5V.rst +++ /dev/null @@ -1,4 +0,0 @@ -Deprecate the old ``Py_UNICODE`` and ``PY_UNICODE_TYPE`` types: use directly -the ``wchar_t`` type instead. Since Python 3.3, ``Py_UNICODE`` and -``PY_UNICODE_TYPE`` are just aliases to ``wchar_t``. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-05-31-19-38-45.gh-issue-85275.doojgE.rst b/Misc/NEWS.d/next/C API/2023-05-31-19-38-45.gh-issue-85275.doojgE.rst deleted file mode 100644 index 082b77b9035cbe..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-05-31-19-38-45.gh-issue-85275.doojgE.rst +++ /dev/null @@ -1,4 +0,0 @@ -``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``, -``PyObject_CheckReadBuffer()``, and ``PyObject_AsWriteBuffer()`` are -removed. Please migrate to new buffer protocol; :c:func:`PyObject_GetBuffer` -and :c:func:`PyBuffer_Release`. diff --git a/Misc/NEWS.d/next/C API/2023-06-01-09-40-30.gh-issue-105145.WOOE-w.rst b/Misc/NEWS.d/next/C API/2023-06-01-09-40-30.gh-issue-105145.WOOE-w.rst deleted file mode 100644 index 13dff769908792..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-01-09-40-30.gh-issue-105145.WOOE-w.rst +++ /dev/null @@ -1,11 +0,0 @@ -Deprecate old Python initialization functions: - -* :c:func:`PySys_ResetWarnOptions` -* :c:func:`Py_GetExecPrefix` -* :c:func:`Py_GetPath` -* :c:func:`Py_GetPrefix` -* :c:func:`Py_GetProgramFullPath` -* :c:func:`Py_GetProgramName` -* :c:func:`Py_GetPythonHome` - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-01-11-23-28.gh-issue-105182.kLEHl-.rst b/Misc/NEWS.d/next/C API/2023-06-01-11-23-28.gh-issue-105182.kLEHl-.rst deleted file mode 100644 index ad9c9e51baa58b..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-01-11-23-28.gh-issue-105182.kLEHl-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove ``PyEval_InitThreads()`` and ``PyEval_ThreadsInitialized()`` -functions, deprecated in Python 3.9. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-01-11-24-03.gh-issue-105182.l5sCw4.rst b/Misc/NEWS.d/next/C API/2023-06-01-11-24-03.gh-issue-105182.l5sCw4.rst deleted file mode 100644 index 0fe5487c3e2181..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-01-11-24-03.gh-issue-105182.l5sCw4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove ``PyEval_AcquireLock()`` and ``PyEval_ReleaseLock()`` functions, -deprecated in Python 3.2. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-06-10-57-18.gh-issue-105268.OTJUko.rst b/Misc/NEWS.d/next/C API/2023-06-06-10-57-18.gh-issue-105268.OTJUko.rst deleted file mode 100644 index bdabfc8c203f6e..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-06-10-57-18.gh-issue-105268.OTJUko.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the old private, undocumented and untested ``_PyGC_FINALIZED()`` macro -which was kept for backward compatibility with Python 3.8 and older. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-06-14-14-41.gh-issue-103968.BTO6II.rst b/Misc/NEWS.d/next/C API/2023-06-06-14-14-41.gh-issue-103968.BTO6II.rst deleted file mode 100644 index b73103c4e0ad9e..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-06-14-14-41.gh-issue-103968.BTO6II.rst +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`PyType_FromMetaclass` now allows metaclasses with ``tp_new`` -set to ``NULL``. diff --git a/Misc/NEWS.d/next/C API/2023-06-06-17-43-28.gh-issue-105396.FQJG5B.rst b/Misc/NEWS.d/next/C API/2023-06-06-17-43-28.gh-issue-105396.FQJG5B.rst deleted file mode 100644 index cf82f6202df17b..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-06-17-43-28.gh-issue-105396.FQJG5B.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecate the :c:func:`PyImport_ImportModuleNoBlock` function which is just -an alias to :c:func:`PyImport_ImportModule` since Python 3.3. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-09-12-35-55.gh-issue-105387.wM_oL-.rst b/Misc/NEWS.d/next/C API/2023-06-09-12-35-55.gh-issue-105387.wM_oL-.rst deleted file mode 100644 index d7ee7d2eb9d908..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-09-12-35-55.gh-issue-105387.wM_oL-.rst +++ /dev/null @@ -1,3 +0,0 @@ -In the limited C API version 3.12, :c:func:`Py_INCREF` and -:c:func:`Py_DECREF` functions are now implemented as opaque function calls -to hide implementation details. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst b/Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst deleted file mode 100644 index cd3d9bcdd4e285..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst +++ /dev/null @@ -1,5 +0,0 @@ -We've renamed the new (in 3.12) ``PyInterpreterConfig.own_gil`` to -``PyInterpreterConfig.gil`` and changed the meaning of the value from "bool" -to an integer with supported values of ``PyInterpreterConfig_DEFAULT_GIL``, -``PyInterpreterConfig_SHARED_GIL``, and ``PyInterpreterConfig_OWN_GIL``. The -default is "shared". diff --git a/Misc/NEWS.d/next/C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst b/Misc/NEWS.d/next/C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst deleted file mode 100644 index b9f95496f938ec..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in :c:func:`PyErr_WarnExplicit` where an exception could end up -being overwritten if the API failed internally. diff --git a/Misc/NEWS.d/next/C API/2023-06-13-14-24-55.gh-issue-105227.HDL9aF.rst b/Misc/NEWS.d/next/C API/2023-06-13-14-24-55.gh-issue-105227.HDL9aF.rst deleted file mode 100644 index 846663621e8689..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-13-14-24-55.gh-issue-105227.HDL9aF.rst +++ /dev/null @@ -1,5 +0,0 @@ -The new :c:func:`PyType_GetDict` provides the dictionary for the given type -object that is normally exposed by ``cls.__dict__``. Normally it's -sufficient to use :c:member:`~PyTypeObject.tp_dict`, but for the static -builtin types :c:member:`!tp_dict` is now always ``NULL``. :c:func:`!PyType_GetDict()` -provides the correct dict object instead. diff --git a/Misc/NEWS.d/next/C API/2023-06-19-20-02-16.gh-issue-105922.o4T6wO.rst b/Misc/NEWS.d/next/C API/2023-06-19-20-02-16.gh-issue-105922.o4T6wO.rst deleted file mode 100644 index 7515d684184e17..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-19-20-02-16.gh-issue-105922.o4T6wO.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :c:func:`PyImport_AddModuleRef`: similar to :c:func:`PyImport_AddModule`, -but return a :term:`strong reference` instead of a :term:`borrowed reference`. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-20-08-59-05.gh-issue-105927.DfGeEA.rst b/Misc/NEWS.d/next/C API/2023-06-20-08-59-05.gh-issue-105927.DfGeEA.rst deleted file mode 100644 index afa40c8ef5d686..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-20-08-59-05.gh-issue-105927.DfGeEA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :c:func:`PyWeakref_GetRef` function: similar to -:c:func:`PyWeakref_GetObject` but returns a :term:`strong reference`, or -``NULL`` if the referent is no longer live. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst b/Misc/NEWS.d/next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst deleted file mode 100644 index 57982dc75e004a..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecate the :c:func:`PyWeakref_GetObject` and -:c:func:`PyWeakref_GET_OBJECT` functions: use the new -:c:func:`PyWeakref_GetRef` function instead. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-25-18-01-27.gh-issue-106084.PEzqU3.rst b/Misc/NEWS.d/next/C API/2023-06-25-18-01-27.gh-issue-106084.PEzqU3.rst deleted file mode 100644 index b430f5f7ae0116..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-25-18-01-27.gh-issue-106084.PEzqU3.rst +++ /dev/null @@ -1,13 +0,0 @@ -Remove the old aliases to functions calling functions which were kept for -backward compatibility with Python 3.8 provisional API: - -* ``_PyObject_CallMethodNoArgs()``: use ``PyObject_CallMethodNoArgs()`` -* ``_PyObject_CallMethodOneArg()``: use ``PyObject_CallMethodOneArg()`` -* ``_PyObject_CallOneArg()``: use ``PyObject_CallOneArg()`` -* ``_PyObject_FastCallDict()``: use ``PyObject_VectorcallDict()`` -* ``_PyObject_Vectorcall()``: use ``PyObject_Vectorcall()`` -* ``_PyObject_VectorcallMethod()``: use ``PyObject_VectorcallMethod()`` -* ``_PyVectorcall_Function()``: use ``PyVectorcall_Function()`` - -Just remove the underscore prefix to update your code. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-28-02-30-50.gh-issue-106168.NFOZPv.rst b/Misc/NEWS.d/next/C API/2023-06-28-02-30-50.gh-issue-106168.NFOZPv.rst deleted file mode 100644 index 741d709bf824b8..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-28-02-30-50.gh-issue-106168.NFOZPv.rst +++ /dev/null @@ -1,5 +0,0 @@ -If Python is built in :ref:`debug mode ` or :option:`with -assertions <--with-assertions>`, :c:func:`PyTuple_SET_ITEM` and -:c:func:`PyList_SET_ITEM` now check the index argument with an assertion. If -the assertion fails, make sure that the size is set before. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-06-30-09-33-25.gh-issue-106023.YvYiE4.rst b/Misc/NEWS.d/next/C API/2023-06-30-09-33-25.gh-issue-106023.YvYiE4.rst deleted file mode 100644 index 3130febf61120b..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-30-09-33-25.gh-issue-106023.YvYiE4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove private ``_PyObject_FastCall()`` function: use ``PyObject_Vectorcall()`` -which is available since Python 3.8 (:pep:`590`). Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-07-01-21-23-33.gh-issue-106316.hp2Ijw.rst b/Misc/NEWS.d/next/C API/2023-07-01-21-23-33.gh-issue-106316.hp2Ijw.rst deleted file mode 100644 index 733954eb8614f2..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-01-21-23-33.gh-issue-106316.hp2Ijw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove ``cpython/pytime.h`` header file: it only contained private -functions. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-07-02-00-00-20.gh-issue-106320.tZWcvG.rst b/Misc/NEWS.d/next/C API/2023-07-02-00-00-20.gh-issue-106320.tZWcvG.rst deleted file mode 100644 index 145d2ce7b0ceb1..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-02-00-00-20.gh-issue-106320.tZWcvG.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove ``_PyInterpreterState_Get()`` alias to -:c:func:`PyInterpreterState_Get()` which was kept for backward compatibility -with Python 3.8. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-07-07-19-14-00.gh-issue-106521.Veh9f3.rst b/Misc/NEWS.d/next/C API/2023-07-07-19-14-00.gh-issue-106521.Veh9f3.rst deleted file mode 100644 index f38fd271e8a440..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-07-19-14-00.gh-issue-106521.Veh9f3.rst +++ /dev/null @@ -1 +0,0 @@ -Add :c:func:`PyObject_GetOptionalAttr` and :c:func:`PyObject_GetOptionalAttrString` functions. diff --git a/Misc/NEWS.d/next/C API/2023-07-08-12-24-17.gh-issue-106307.FVnkBw.rst b/Misc/NEWS.d/next/C API/2023-07-08-12-24-17.gh-issue-106307.FVnkBw.rst deleted file mode 100644 index dc1ab8d3e3fb83..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-08-12-24-17.gh-issue-106307.FVnkBw.rst +++ /dev/null @@ -1 +0,0 @@ -Add :c:func:`PyMapping_GetOptionalItem` function. diff --git a/Misc/NEWS.d/next/C API/2023-07-11-01-07-39.gh-issue-106572.y1b35X.rst b/Misc/NEWS.d/next/C API/2023-07-11-01-07-39.gh-issue-106572.y1b35X.rst deleted file mode 100644 index 140e9fe7b9abf6..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-11-01-07-39.gh-issue-106572.y1b35X.rst +++ /dev/null @@ -1,2 +0,0 @@ -Convert :c:func:`PyObject_DelAttr` and :c:func:`PyObject_DelAttrString` -macros to functions. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-11-10-13-04-35.gh-issue-91095.4E3Pwn.rst b/Misc/NEWS.d/next/Core and Builtins/2022-11-10-13-04-35.gh-issue-91095.4E3Pwn.rst deleted file mode 100644 index 5633097f4a3fdd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-11-10-13-04-35.gh-issue-91095.4E3Pwn.rst +++ /dev/null @@ -1,11 +0,0 @@ -Specializes calls to most Python classes. Specifically, any class that -inherits from ``object``, or another Python class, and does not override -``__new__``. - -The specialized instruction does the following: - -1. Creates the object (by calling ``object.__new__``) -2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) -3. Pushes the frame for ``__init__`` to the frame stack - -Speeds up the instantiation of most Python classes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-13-11-37-41.gh-issue-101006.fuLvn2.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-13-11-37-41.gh-issue-101006.fuLvn2.rst deleted file mode 100644 index c98670d8c4963d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-01-13-11-37-41.gh-issue-101006.fuLvn2.rst +++ /dev/null @@ -1 +0,0 @@ -Improve error handling when read :mod:`marshal` data. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-18-12-48-39.gh-issue-89091.FDzRcW.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-18-12-48-39.gh-issue-89091.FDzRcW.rst deleted file mode 100644 index 084ea708997ef3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-18-12-48-39.gh-issue-89091.FDzRcW.rst +++ /dev/null @@ -1 +0,0 @@ -Raise :exc:`RuntimeWarning` for unawaited async generator methods like :meth:`~agen.asend`, :meth:`~agen.athrow` and :meth:`~agen.aclose`. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-23-00-36-02.gh-issue-104770.poSkyY.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-23-00-36-02.gh-issue-104770.poSkyY.rst deleted file mode 100644 index 2103fb7d61c21a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-23-00-36-02.gh-issue-104770.poSkyY.rst +++ /dev/null @@ -1,2 +0,0 @@ -If a generator returns a value upon being closed, the value is now returned -by :meth:`generator.close`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-24-09-59-56.gh-issue-104825.mQesie.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-24-09-59-56.gh-issue-104825.mQesie.rst deleted file mode 100644 index caf5d3527085f3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-24-09-59-56.gh-issue-104825.mQesie.rst +++ /dev/null @@ -1,2 +0,0 @@ -Tokens emitted by the :mod:`tokenize` module do not include an implicit -``\n`` character in the ``line`` attribute anymore. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-24-10-19-35.gh-issue-104879.v-29NL.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-24-10-19-35.gh-issue-104879.v-29NL.rst deleted file mode 100644 index 235f4180642be6..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-24-10-19-35.gh-issue-104879.v-29NL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash when accessing the ``__module__`` attribute of type aliases -defined outside a module. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-24-12-10-54.gh-issue-104690.HX3Jou.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-24-12-10-54.gh-issue-104690.HX3Jou.rst deleted file mode 100644 index 7934dd23b10691..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-24-12-10-54.gh-issue-104690.HX3Jou.rst +++ /dev/null @@ -1,6 +0,0 @@ -Starting new threads and process creation through :func:`os.fork` during interpreter -shutdown (such as from :mod:`atexit` handlers) is no longer supported. It can lead -to race condition between the main Python runtime thread freeing thread states while -internal :mod:`threading` routines are trying to allocate and use the state of just -created threads. Or forked children trying to use the mid-shutdown runtime and thread -state in the child process. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-25-21-40-39.gh-issue-104955.LZx7jf.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-25-21-40-39.gh-issue-104955.LZx7jf.rst deleted file mode 100644 index 9fccf2a41ffb6f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-25-21-40-39.gh-issue-104955.LZx7jf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix signature for the new :meth:`~object.__release_buffer__` slot. Patch by Jelle -Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-26-14-09-47.gh-issue-104972.El2UjE.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-26-14-09-47.gh-issue-104972.El2UjE.rst deleted file mode 100644 index 05d50c108c7b77..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-26-14-09-47.gh-issue-104972.El2UjE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure that the ``line`` attribute in :class:`tokenize.TokenInfo` objects in -the :mod:`tokenize` module are always correct. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-26-15-16-11.gh-issue-104976.6dLitD.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-26-15-16-11.gh-issue-104976.6dLitD.rst deleted file mode 100644 index 377e8e76362687..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-26-15-16-11.gh-issue-104976.6dLitD.rst +++ /dev/null @@ -1,3 +0,0 @@ -Ensure that trailing ``DEDENT`` :class:`tokenize.TokenInfo` objects emitted -by the :mod:`tokenize` module are reported as in Python 3.11. Patch by Pablo -Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-23-16.gh-issue-105017.KQrsC0.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-23-16.gh-issue-105017.KQrsC0.rst deleted file mode 100644 index d41a2169ccb3de..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-23-16.gh-issue-105017.KQrsC0.rst +++ /dev/null @@ -1 +0,0 @@ -Do not include an additional final ``NL`` token when parsing files having CRLF lines. Patch by Marta Gómez. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst deleted file mode 100644 index a9917c2849982a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix handling of multiline parenthesized lambdas in -:func:`inspect.getsource`. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-27-21-50-48.gh-issue-105017.4sDyDV.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-27-21-50-48.gh-issue-105017.4sDyDV.rst deleted file mode 100644 index 02d653c2d658eb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-27-21-50-48.gh-issue-105017.4sDyDV.rst +++ /dev/null @@ -1 +0,0 @@ -Show CRLF lines in the tokenize string attribute in both NL and NEWLINE tokens. Patch by Marta Gómez. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-30-08-09-43.gh-issue-105035.OWUlHy.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-30-08-09-43.gh-issue-105035.OWUlHy.rst deleted file mode 100644 index c0ee2da9d45037..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-30-08-09-43.gh-issue-105035.OWUlHy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`super` calls on types with custom :attr:`tp_getattro` -implementation (e.g. meta-types.) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-30-20-30-57.gh-issue-105111.atn0_6.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-30-20-30-57.gh-issue-105111.atn0_6.rst deleted file mode 100644 index 7f9c5cc95680d8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-30-20-30-57.gh-issue-105111.atn0_6.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the old trashcan macros -``Py_TRASHCAN_SAFE_BEGIN`` and ``Py_TRASHCAN_SAFE_END``. They should be -replaced by the new macros ``Py_TRASHCAN_BEGIN`` and ``Py_TRASHCAN_END``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-31-08-10-59.gh-issue-104799.8kDWti.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-31-08-10-59.gh-issue-104799.8kDWti.rst deleted file mode 100644 index e1fe47f862529c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-31-08-10-59.gh-issue-104799.8kDWti.rst +++ /dev/null @@ -1,4 +0,0 @@ -Attributes of :mod:`ast` nodes that are lists now default to the empty list -if omitted. This means that some code that previously raised -:exc:`TypeError` when the AST node was used will now proceed with the empty -list instead. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-31-16-22-29.gh-issue-105148.MOlb1d.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-31-16-22-29.gh-issue-105148.MOlb1d.rst deleted file mode 100644 index 4dcdcdfd4287d7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-31-16-22-29.gh-issue-105148.MOlb1d.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make ``_PyASTOptimizeState`` internal to ast_opt.c. Make ``_PyAST_Optimize`` -take two integers instead of a pointer to this struct. This avoids the need -to include pycore_compile.h in ast_opt.c. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-31-19-35-22.gh-issue-105164.6Wajph.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-31-19-35-22.gh-issue-105164.6Wajph.rst deleted file mode 100644 index 7d3486c3b6e98a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-05-31-19-35-22.gh-issue-105164.6Wajph.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure annotations are set up correctly if the only annotation in a block is -within a :keyword:`match` block. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-01-11-37-03.gh-issue-105162.r8VCXk.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-01-11-37-03.gh-issue-105162.r8VCXk.rst deleted file mode 100644 index adb4e8478d9c55..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-01-11-37-03.gh-issue-105162.r8VCXk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed bug in generator.close()/throw() where an inner iterator would be -ignored when the outer iterator was instrumented. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-01-27-35.gh-issue-105229.U05x4G.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-02-01-27-35.gh-issue-105229.U05x4G.rst deleted file mode 100644 index df0c54691afb11..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-01-27-35.gh-issue-105229.U05x4G.rst +++ /dev/null @@ -1 +0,0 @@ -Replace some dynamic superinstructions with single instruction equivalents. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-11-37-12.gh-issue-105194.4eu56B.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-02-11-37-12.gh-issue-105194.4eu56B.rst deleted file mode 100644 index adee74f5894b54..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-11-37-12.gh-issue-105194.4eu56B.rst +++ /dev/null @@ -1,2 +0,0 @@ -Do not escape with backslashes f-string format specifiers. Patch by Pablo -Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-15-15-41.gh-issue-104812.dfZiG5.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-02-15-15-41.gh-issue-104812.dfZiG5.rst deleted file mode 100644 index da29a8cae61839..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-15-15-41.gh-issue-104812.dfZiG5.rst +++ /dev/null @@ -1,9 +0,0 @@ -The "pending call" machinery now works for all interpreters, not just the -main interpreter, and runs in all threads, not just the main thread. Some -calls are still only done in the main thread, ergo in the main interpreter. -This change does not affect signal handling nor the existing public C-API -(``Py_AddPendingCall()``), which both still only target the main thread. -The new functionality is meant strictly for internal use for now, since -consequences of its use are not well understood yet outside some very -restricted cases. This change brings the capability in line with the -intention when the state was made per-interpreter several years ago. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-17-39-19.gh-issue-98963.J4wJgk.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-02-17-39-19.gh-issue-98963.J4wJgk.rst deleted file mode 100644 index 4caadb0875a188..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-17-39-19.gh-issue-98963.J4wJgk.rst +++ /dev/null @@ -1,4 +0,0 @@ -Restore the ability for a subclass of :class:`property` to define ``__slots__`` -or otherwise be dict-less by ignoring failures to set a docstring on such a -class. This behavior had regressed in 3.12beta1. An :exc:`AttributeError` -where there had not previously been one was disruptive to existing code. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-19-37-29.gh-issue-105235.fgFGTi.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-02-19-37-29.gh-issue-105235.fgFGTi.rst deleted file mode 100644 index c28d0101cd4bad..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-02-19-37-29.gh-issue-105235.fgFGTi.rst +++ /dev/null @@ -1 +0,0 @@ -Prevent out-of-bounds memory access during ``mmap.find()`` calls. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-03-04-28-28.gh-issue-105229.stEmfp.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-03-04-28-28.gh-issue-105229.stEmfp.rst deleted file mode 100644 index 34fad1d4bc34d8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-03-04-28-28.gh-issue-105229.stEmfp.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove remaining two-codeunit superinstructions. All remaining -superinstructions only take a single codeunit, simplifying instrumentation -and quickening. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-05-08-30-49.gh-issue-33092.hZ0xSI.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-05-08-30-49.gh-issue-33092.hZ0xSI.rst deleted file mode 100644 index 736fbac1a86500..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-05-08-30-49.gh-issue-33092.hZ0xSI.rst +++ /dev/null @@ -1,3 +0,0 @@ -Simplify and speed up interpreter for f-strings. Removes ``FORMAT_VALUE`` -opcode. Add ``CONVERT_VALUE``, ``FORMAT_SIMPLE`` and ``FORMAT_WITH_SPEC`` -opcode. Compiler emits more efficient sequence for each format expression. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-05-17-35-50.gh-issue-105324.BqhiJJ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-05-17-35-50.gh-issue-105324.BqhiJJ.rst deleted file mode 100644 index 17275aed338d0d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-05-17-35-50.gh-issue-105324.BqhiJJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the main function of the :mod:`tokenize` module when reading from -``sys.stdin``. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-05-23-38-43.gh-issue-104635.VYZhVh.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-05-23-38-43.gh-issue-104635.VYZhVh.rst deleted file mode 100644 index f20ddb56d171c3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-05-23-38-43.gh-issue-104635.VYZhVh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Eliminate redundant :opcode:`STORE_FAST` instructions in the compiler. Patch -by Dong-hee Na and Carl Meyer. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-06-11-37-53.gh-issue-105259.E2BGKL.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-06-11-37-53.gh-issue-105259.E2BGKL.rst deleted file mode 100644 index 75a63033750826..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-06-11-37-53.gh-issue-105259.E2BGKL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Don't include newline character for trailing ``NEWLINE`` tokens emitted in -the :mod:`tokenize` module. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-06-17-10-42.gh-issue-105390.DvqI-e.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-06-17-10-42.gh-issue-105390.DvqI-e.rst deleted file mode 100644 index de59b54d8f6053..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-06-17-10-42.gh-issue-105390.DvqI-e.rst +++ /dev/null @@ -1,3 +0,0 @@ -Correctly raise :exc:`tokenize.TokenError` exceptions instead of -:exc:`SyntaxError` for tokenize errors such as incomplete input. Patch by -Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-07-12-20-59.gh-issue-105435.6VllI0.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-07-12-20-59.gh-issue-105435.6VllI0.rst deleted file mode 100644 index 9e4d7e1851ccb5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-07-12-20-59.gh-issue-105435.6VllI0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix spurious newline character if file ends on a comment without a newline. -Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-07-21-27-55.gh-issue-105678.wKOr7F.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-07-21-27-55.gh-issue-105678.wKOr7F.rst deleted file mode 100644 index fd38c14c140414..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-07-21-27-55.gh-issue-105678.wKOr7F.rst +++ /dev/null @@ -1,4 +0,0 @@ -Break the ``MAKE_FUNCTION`` instruction into two parts, ``MAKE_FUNCTION`` -which makes the function and ``SET_FUNCTION_ATTRIBUTE`` which sets the -attributes on the function. This makes the stack effect of ``MAKE_FUNCTION`` -regular to ease optimization and code generation. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-10-15.gh-issue-105486.dev-WS.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-10-15.gh-issue-105486.dev-WS.rst deleted file mode 100644 index 9f735db3dc89c3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-10-15.gh-issue-105486.dev-WS.rst +++ /dev/null @@ -1 +0,0 @@ -Change the repr of ``ParamSpec`` list of args in ``types.GenericAlias``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-25-52.gh-issue-105375.ocB7fT.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-25-52.gh-issue-105375.ocB7fT.rst deleted file mode 100644 index 24fac2df4d0955..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-25-52.gh-issue-105375.ocB7fT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve error handling in :c:func:`PyUnicode_BuildEncodingMap` where an -exception could end up being overwritten. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-54-37.gh-issue-105375.kqKT3E.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-54-37.gh-issue-105375.kqKT3E.rst deleted file mode 100644 index b4d3a1a5a3cedb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-54-37.gh-issue-105375.kqKT3E.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug in the compiler where an exception could end up being overwritten. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-10-10-07.gh-issue-105375.35VGDd.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-08-10-10-07.gh-issue-105375.35VGDd.rst deleted file mode 100644 index 3ab85538f3fc43..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-10-10-07.gh-issue-105375.35VGDd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bugs in the :mod:`builtins` module where exceptions could end up being -overwritten. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-10-48-17.gh-issue-100987.mK-xny.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-09-10-48-17.gh-issue-100987.mK-xny.rst deleted file mode 100644 index e25789e711c35d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-10-48-17.gh-issue-100987.mK-xny.rst +++ /dev/null @@ -1,4 +0,0 @@ -Allow objects other than code objects as the "executable" in internal -frames. In the long term, this can help tools like Cython and PySpy interact -more efficiently. In the shorter term, it allows us to perform some -optimizations more simply. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-11-19-51.gh-issue-105588.Y5ovpY.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-09-11-19-51.gh-issue-105588.Y5ovpY.rst deleted file mode 100644 index 3981dad7a49dfb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-11-19-51.gh-issue-105588.Y5ovpY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an issue that could result in crashes when compiling malformed -:mod:`ast` nodes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-12-59-18.gh-issue-105549.PYfTNp.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-09-12-59-18.gh-issue-105549.PYfTNp.rst deleted file mode 100644 index 7cb177b9353373..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-12-59-18.gh-issue-105549.PYfTNp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Tokenize separately ``NUMBER`` and ``NAME`` tokens that are not ambiguous. Patch -by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-15-25-12.gh-issue-105564.sFdUu4.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-09-15-25-12.gh-issue-105564.sFdUu4.rst deleted file mode 100644 index 9809fac49164f5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-09-15-25-12.gh-issue-105564.sFdUu4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Don't include artificil newlines in the ``line`` attribute of tokens in the -APIs of the :mod:`tokenize` module. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-10-21-38-49.gh-issue-105587.rL3rzv.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-10-21-38-49.gh-issue-105587.rL3rzv.rst deleted file mode 100644 index 488f82c3fb574c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-10-21-38-49.gh-issue-105587.rL3rzv.rst +++ /dev/null @@ -1,3 +0,0 @@ -The runtime can't guarantee that immortal objects will not be mutated by -Extensions. Thus, this modifies _PyStaticObject_CheckRefcnt to warn -instead of asserting. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-11-09-14-30.gh-issue-105331.nlZvoW.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-11-09-14-30.gh-issue-105331.nlZvoW.rst deleted file mode 100644 index 4a3fee0dd64ae0..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-11-09-14-30.gh-issue-105331.nlZvoW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise :exc:`ValueError` if the ``delay`` argument to :func:`asyncio.sleep` is a NaN (matching :func:`time.sleep`). - diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-12-16-38-31.gh-issue-105340._jRHXe.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-12-16-38-31.gh-issue-105340._jRHXe.rst deleted file mode 100644 index f6d4fa8fc4d74e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-12-16-38-31.gh-issue-105340._jRHXe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Include the comprehension iteration variable in ``locals()`` inside a -module- or class-scope comprehension. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-14-22-52-06.gh-issue-105800.hdpPzZ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-14-22-52-06.gh-issue-105800.hdpPzZ.rst deleted file mode 100644 index d6ef7b68b833c6..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-14-22-52-06.gh-issue-105800.hdpPzZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correctly issue :exc:`SyntaxWarning` in f-strings if invalid sequences are -used. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-15-15-54-47.gh-issue-105831.-MC9Zs.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-15-15-54-47.gh-issue-105831.-MC9Zs.rst deleted file mode 100644 index 407940add56752..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-15-15-54-47.gh-issue-105831.-MC9Zs.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix an f-string bug, where using a debug expression (the ``=`` sign) that -appears in the last line of a file results to the debug buffer that holds the -expression text being one character too small. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-15-22-11-43.gh-issue-105840.Fum_g_.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-15-22-11-43.gh-issue-105840.Fum_g_.rst deleted file mode 100644 index 5225031292e6c7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-15-22-11-43.gh-issue-105840.Fum_g_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible crashes when specializing function calls with too many -``__defaults__``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-19-11-04-01.gh-issue-105908.7oanny.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-19-11-04-01.gh-issue-105908.7oanny.rst deleted file mode 100644 index 03db3f064f503f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-19-11-04-01.gh-issue-105908.7oanny.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed bug where :gh:`99111` breaks future import ``barry_as_FLUFL`` in the Python REPL. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-22-14-19-17.gh-issue-98931.PPgvSF.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-22-14-19-17.gh-issue-98931.PPgvSF.rst deleted file mode 100644 index 611660d6286263..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-22-14-19-17.gh-issue-98931.PPgvSF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure custom :exc:`SyntaxError` error messages are raised for invalid -imports with multiple targets. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-22-17-37-35.gh-issue-106003.2Vc_Tw.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-22-17-37-35.gh-issue-106003.2Vc_Tw.rst deleted file mode 100644 index 47143f7eb8f383..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-22-17-37-35.gh-issue-106003.2Vc_Tw.rst +++ /dev/null @@ -1,5 +0,0 @@ -Add a new :opcode:`TO_BOOL` instruction, which performs boolean conversions -for :opcode:`POP_JUMP_IF_TRUE`, :opcode:`POP_JUMP_IF_FALSE`, and -:opcode:`UNARY_NOT` (which all expect exact :class:`bool` values now). Also, -modify the oparg of :opcode:`COMPARE_OP` to include an optional "boolean -conversion" flag. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-22-19-16-24.gh-issue-105979.TDP2CU.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-22-19-16-24.gh-issue-105979.TDP2CU.rst deleted file mode 100644 index be6962afd0c78f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-22-19-16-24.gh-issue-105979.TDP2CU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash in :func:`!_imp.get_frozen_object` due to improper exception handling. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-23-16-51-02.gh-issue-105730.16haMe.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-23-16-51-02.gh-issue-105730.16haMe.rst deleted file mode 100644 index fa70ee09ce27a1..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-23-16-51-02.gh-issue-105730.16haMe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow any callable other than type objects as the condition predicate in -:meth:`BaseExceptionGroup.split` and :meth:`BaseExceptionGroup.subgroup`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-24-10-34-27.gh-issue-105775.OqjoGV.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-24-10-34-27.gh-issue-105775.OqjoGV.rst deleted file mode 100644 index 27d0e9929794f4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-24-10-34-27.gh-issue-105775.OqjoGV.rst +++ /dev/null @@ -1 +0,0 @@ -:opcode:`LOAD_CLOSURE` is now a pseudo-op. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-27-00-58-26.gh-issue-104584.Wu-uXy.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-27-00-58-26.gh-issue-104584.Wu-uXy.rst deleted file mode 100644 index a36490104ba3aa..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-27-00-58-26.gh-issue-104584.Wu-uXy.rst +++ /dev/null @@ -1 +0,0 @@ -Added a new, experimental, tracing optimizer and interpreter (a.k.a. "tier 2"). This currently pessimizes, so don't use yet -- this is infrastructure so we can experiment with optimizing passes. To enable it, pass ``-Xuops`` or set ``PYTHONUOPS=1``. To get debug output, set ``PYTHONUOPSDEBUG=N`` where ``N`` is a debug level (0-4, where 0 is no debug output and 4 is excessively verbose). diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-28-13-19-20.gh-issue-106210.oE7VMn.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-28-13-19-20.gh-issue-106210.oE7VMn.rst deleted file mode 100644 index fde549d21e440a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-28-13-19-20.gh-issue-106210.oE7VMn.rst +++ /dev/null @@ -1 +0,0 @@ -Removed Emscripten import trampoline as it was no longer necessary for Pyodide. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-28-15-19-59.gh-issue-106182.cDSFi0.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-28-15-19-59.gh-issue-106182.cDSFi0.rst deleted file mode 100644 index ca2116b00a6659..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-28-15-19-59.gh-issue-106182.cDSFi0.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`sys.getfilesystemencoding` and :mod:`sys.getfilesystemencodeerrors` -now return interned Unicode object. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-29-09-46-41.gh-issue-106145.QC6-Kq.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-29-09-46-41.gh-issue-106145.QC6-Kq.rst deleted file mode 100644 index 4f9445bbcbe550..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-29-09-46-41.gh-issue-106145.QC6-Kq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make ``end_lineno`` and ``end_col_offset`` required on ``type_param`` ast -nodes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-03-11-38-43.gh-issue-106008.HDf1zd.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-03-11-38-43.gh-issue-106008.HDf1zd.rst deleted file mode 100644 index a57b892fd53242..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-03-11-38-43.gh-issue-106008.HDf1zd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible reference leaks when failing to optimize comparisons with -:const:`None` in the bytecode compiler. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-04-50-14.gh-issue-100288.yNQ1ez.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-04-04-50-14.gh-issue-100288.yNQ1ez.rst deleted file mode 100644 index faf43bd0c2f48e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-04-50-14.gh-issue-100288.yNQ1ez.rst +++ /dev/null @@ -1,3 +0,0 @@ -Specialize :opcode:`LOAD_ATTR` for non-descriptors on the class. Adds -:opcode:`LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES` and :opcode -`LOAD_ATTR_NONDESCRIPTOR_NO_DICT`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-09-51-45.gh-issue-106396.DmYp7x.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-04-09-51-45.gh-issue-106396.DmYp7x.rst deleted file mode 100644 index c5767e97271d9d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-09-51-45.gh-issue-106396.DmYp7x.rst +++ /dev/null @@ -1,3 +0,0 @@ -When the format specification of an f-string expression is empty, the parser now -generates an empty :class:`ast.JoinedStr` node for it instead of an one-element -:class:`ast.JoinedStr` with an empty string :class:`ast.Constant`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-20-42-54.gh-issue-81283.hfh_MD.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-04-20-42-54.gh-issue-81283.hfh_MD.rst deleted file mode 100644 index f673c665fe3277..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-20-42-54.gh-issue-81283.hfh_MD.rst +++ /dev/null @@ -1,3 +0,0 @@ -Compiler now strips indents from docstrings. It reduces ``pyc`` file size 5% -when the module is heavily documented. This change affects to ``__doc__`` so -tools like doctest will be affected. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-06-00-35-44.gh-issue-96844.kwvoS-.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-06-00-35-44.gh-issue-96844.kwvoS-.rst deleted file mode 100644 index 55334173bc002d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-06-00-35-44.gh-issue-96844.kwvoS-.rst +++ /dev/null @@ -1 +0,0 @@ -Improve error message of :meth:`list.remove`. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-06-22-46-05.gh-issue-106487.u3KfAD.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-06-22-46-05.gh-issue-106487.u3KfAD.rst deleted file mode 100644 index 9e8100022bbd23..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-06-22-46-05.gh-issue-106487.u3KfAD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow the *count* argument of :meth:`str.replace` to be a keyword. Patch by -Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-10-15-30-45.gh-issue-106597.WAZ14y.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-10-15-30-45.gh-issue-106597.WAZ14y.rst deleted file mode 100644 index bbe455d652f50e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-10-15-30-45.gh-issue-106597.WAZ14y.rst +++ /dev/null @@ -1,5 +0,0 @@ -A new debug structure of offsets has been added to the ``_PyRuntimeState`` -that will help out-of-process debuggers and profilers to obtain the offsets -to relevant interpreter structures in a way that is agnostic of how Python -was compiled and that doesn't require copying the headers. Patch by Pablo -Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-12-10-48-08.gh-issue-104909.sWjcr2.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-12-10-48-08.gh-issue-104909.sWjcr2.rst deleted file mode 100644 index f20226e5c54d16..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-12-10-48-08.gh-issue-104909.sWjcr2.rst +++ /dev/null @@ -1 +0,0 @@ -Split :opcode:`LOAD_GLOBAL` specializations into micro-ops. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-12-11-18-55.gh-issue-104909.DRUsuh.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-12-11-18-55.gh-issue-104909.DRUsuh.rst deleted file mode 100644 index e0c1e67515a62c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-12-11-18-55.gh-issue-104909.DRUsuh.rst +++ /dev/null @@ -1 +0,0 @@ -Split :opcode:`LOAD_ATTR_INSTANCE_VALUE` into micro-ops. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-13-15-59-07.gh-issue-106719.jmVrsv.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-13-15-59-07.gh-issue-106719.jmVrsv.rst deleted file mode 100644 index dc4bef193a3220..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-13-15-59-07.gh-issue-106719.jmVrsv.rst +++ /dev/null @@ -1,2 +0,0 @@ -No longer suppress arbitrary errors in the ``__annotations__`` getter and -setter in the type and module types. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-13-09-21-29.gh-issue-110805.vhU7A7.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-13-09-21-29.gh-issue-110805.vhU7A7.rst new file mode 100644 index 00000000000000..be90bb3564fd54 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-10-13-09-21-29.gh-issue-110805.vhU7A7.rst @@ -0,0 +1,2 @@ +Allow the repl to show source code and complete tracebacks. Patch by Pablo +Galindo diff --git a/Misc/NEWS.d/next/Documentation/2023-05-25-22-34-31.gh-issue-104943.J2v1Pc.rst b/Misc/NEWS.d/next/Documentation/2023-05-25-22-34-31.gh-issue-104943.J2v1Pc.rst deleted file mode 100644 index bc4d03b8e95f86..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-05-25-22-34-31.gh-issue-104943.J2v1Pc.rst +++ /dev/null @@ -1 +0,0 @@ -Remove mentions of old Python versions in :class:`typing.NamedTuple`. diff --git a/Misc/NEWS.d/next/Documentation/2023-05-28-19-08-42.gh-issue-89412.j4cg7K.rst b/Misc/NEWS.d/next/Documentation/2023-05-28-19-08-42.gh-issue-89412.j4cg7K.rst deleted file mode 100644 index 00937e58c98595..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-05-28-19-08-42.gh-issue-89412.j4cg7K.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add missing documentation for the ``end_lineno`` and ``end_offset`` attributes -of the :class:`traceback.TracebackException` class. diff --git a/Misc/NEWS.d/next/Documentation/2023-05-28-21-01-00.gh-issue-89455.qAKRrA.rst b/Misc/NEWS.d/next/Documentation/2023-05-28-21-01-00.gh-issue-89455.qAKRrA.rst deleted file mode 100644 index fdfa4357f001b5..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-05-28-21-01-00.gh-issue-89455.qAKRrA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add missing documentation for the ``max_group_depth`` and ``max_group_width`` -parameters and the ``exceptions`` attribute of the -:class:`traceback.TracebackException` class. diff --git a/Misc/NEWS.d/next/Documentation/2023-05-31-23-05-51.gh-issue-105172.SVfvkD.rst b/Misc/NEWS.d/next/Documentation/2023-05-31-23-05-51.gh-issue-105172.SVfvkD.rst deleted file mode 100644 index 96cf7220e53079..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-05-31-23-05-51.gh-issue-105172.SVfvkD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed :func:`functools.lru_cache` docstring accounting for ``typed`` -argument's different handling of str and int. Patch by Bar Harel. diff --git a/Misc/NEWS.d/next/Documentation/2023-06-30-19-28-59.gh-issue-106232.hQ4-tz.rst b/Misc/NEWS.d/next/Documentation/2023-06-30-19-28-59.gh-issue-106232.hQ4-tz.rst deleted file mode 100644 index bc16f92b7d6478..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-06-30-19-28-59.gh-issue-106232.hQ4-tz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make timeit doc command lines compatible with Windows by using double quotes -for arguments. This works on linux and macOS also. diff --git a/Misc/NEWS.d/next/IDLE/2023-05-23-17-19-49.gh-issue-104719.rvYXH-.rst b/Misc/NEWS.d/next/IDLE/2023-05-23-17-19-49.gh-issue-104719.rvYXH-.rst deleted file mode 100644 index 3fbe04ba4f6844..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2023-05-23-17-19-49.gh-issue-104719.rvYXH-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove IDLE's modification of tokenize.tabsize and test other uses of -tokenize data and methods. diff --git a/Misc/NEWS.d/next/Library/2019-09-13-13-28-10.bpo-17013.NWcgE3.rst b/Misc/NEWS.d/next/Library/2019-09-13-13-28-10.bpo-17013.NWcgE3.rst deleted file mode 100644 index ac746c45fa9ea8..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-13-13-28-10.bpo-17013.NWcgE3.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add ``ThreadingMock`` to :mod:`unittest.mock` that can be used to create -Mock objects that can wait until they are called. Patch by Karthikeyan -Singaravelan and Mario Corchero. diff --git a/Misc/NEWS.d/next/Library/2020-09-16-16-53-06.bpo-41768.8_fWkC.rst b/Misc/NEWS.d/next/Library/2020-09-16-16-53-06.bpo-41768.8_fWkC.rst deleted file mode 100644 index bfd3a294d44efa..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-16-16-53-06.bpo-41768.8_fWkC.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`unittest.mock` speccing no longer calls class properties. -Patch by Melanie Witt. diff --git a/Misc/NEWS.d/next/Library/2021-06-24-20-45-03.bpo-44185.ZHb8yJ.rst b/Misc/NEWS.d/next/Library/2021-06-24-20-45-03.bpo-44185.ZHb8yJ.rst deleted file mode 100644 index 056ab8d93515fb..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-06-24-20-45-03.bpo-44185.ZHb8yJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`unittest.mock.mock_open` will call the :func:`close` method of the file -handle mock when it is exiting from the context manager. -Patch by Samet Yaslan. diff --git a/Misc/NEWS.d/next/Library/2022-05-17-10-46-44.gh-issue-92871.GVogrT.rst b/Misc/NEWS.d/next/Library/2022-05-17-10-46-44.gh-issue-92871.GVogrT.rst deleted file mode 100644 index 992f8afadbe912..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-17-10-46-44.gh-issue-92871.GVogrT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the ``typing.io`` and ``typing.re`` namespaces, deprecated since Python -3.8. All items are still available from the main :mod:`typing` module. diff --git a/Misc/NEWS.d/next/Library/2022-07-12-18-45-13.gh-issue-94777.mOybx7.rst b/Misc/NEWS.d/next/Library/2022-07-12-18-45-13.gh-issue-94777.mOybx7.rst deleted file mode 100644 index 2c04a35fbfce13..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-12-18-45-13.gh-issue-94777.mOybx7.rst +++ /dev/null @@ -1 +0,0 @@ -Fix hanging :mod:`multiprocessing` ``ProcessPoolExecutor`` when a child process crashes while data is being written in the call queue. diff --git a/Misc/NEWS.d/next/Library/2022-07-18-14-20-56.gh-issue-94924.X0buz2.rst b/Misc/NEWS.d/next/Library/2022-07-18-14-20-56.gh-issue-94924.X0buz2.rst deleted file mode 100644 index 7882f224e75ad5..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-18-14-20-56.gh-issue-94924.X0buz2.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`unittest.mock.create_autospec` now properly returns coroutine functions compatible with :func:`inspect.iscoroutinefunction` diff --git a/Misc/NEWS.d/next/Library/2022-08-07-11-10-26.gh-issue-80480.IFccj3.rst b/Misc/NEWS.d/next/Library/2022-08-07-11-10-26.gh-issue-80480.IFccj3.rst deleted file mode 100644 index 2d4956ffa08035..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-08-07-11-10-26.gh-issue-80480.IFccj3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Emit :exc:`DeprecationWarning` for :mod:`array`'s ``'u'`` type code, -deprecated in docs since Python 3.3. diff --git a/Misc/NEWS.d/next/Library/2023-02-17-18-56-46.gh-issue-73435.7sTJHk.rst b/Misc/NEWS.d/next/Library/2023-02-17-18-56-46.gh-issue-73435.7sTJHk.rst deleted file mode 100644 index d5a2ae07700b34..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-02-17-18-56-46.gh-issue-73435.7sTJHk.rst +++ /dev/null @@ -1 +0,0 @@ -Add support for recursive wildcards in :meth:`pathlib.PurePath.match`. diff --git a/Misc/NEWS.d/next/Library/2023-02-18-22-55-48.gh-issue-102024.RUmg_D.rst b/Misc/NEWS.d/next/Library/2023-02-18-22-55-48.gh-issue-102024.RUmg_D.rst deleted file mode 100644 index bb9e28e06c5554..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-02-18-22-55-48.gh-issue-102024.RUmg_D.rst +++ /dev/null @@ -1 +0,0 @@ -Reduce calls of ``_idle_semaphore.release()`` in :func:`concurrent.futures.thread._worker`. diff --git a/Misc/NEWS.d/next/Library/2023-03-08-19-30-53.gh-issue-102120.xkQ5Wr.rst b/Misc/NEWS.d/next/Library/2023-03-08-19-30-53.gh-issue-102120.xkQ5Wr.rst deleted file mode 100644 index ca50242fdbe293..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-03-08-19-30-53.gh-issue-102120.xkQ5Wr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added a stream mode to ``tarfile`` that allows for reading -archives without caching info about the inner files. diff --git a/Misc/NEWS.d/next/Library/2023-03-12-01-17-15.gh-issue-102541.LK1adc.rst b/Misc/NEWS.d/next/Library/2023-03-12-01-17-15.gh-issue-102541.LK1adc.rst deleted file mode 100644 index 45b10679e19e2d..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-03-12-01-17-15.gh-issue-102541.LK1adc.rst +++ /dev/null @@ -1 +0,0 @@ -Hide traceback in :func:`help` prompt, when import failed. diff --git a/Misc/NEWS.d/next/Library/2023-03-12-03-37-03.gh-issue-77609.aOQttm.rst b/Misc/NEWS.d/next/Library/2023-03-12-03-37-03.gh-issue-77609.aOQttm.rst deleted file mode 100644 index 35e61088de58a6..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-03-12-03-37-03.gh-issue-77609.aOQttm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add *follow_symlinks* argument to :meth:`pathlib.Path.glob` and -:meth:`~pathlib.Path.rglob`, defaulting to false. diff --git a/Misc/NEWS.d/next/Library/2023-04-03-08-09-40.gh-issue-103200.lq1Etz.rst b/Misc/NEWS.d/next/Library/2023-04-03-08-09-40.gh-issue-103200.lq1Etz.rst deleted file mode 100644 index e264e0c81d3d90..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-03-08-09-40.gh-issue-103200.lq1Etz.rst +++ /dev/null @@ -1 +0,0 @@ -Fix cache repopulation semantics of zipimport.invalidate_caches(). The cache is now repopulated upon retrieving files with an invalid cache, not when the cache is invalidated. diff --git a/Misc/NEWS.d/next/Library/2023-04-09-03-53-02.gh-issue-103124.JspiNN.rst b/Misc/NEWS.d/next/Library/2023-04-09-03-53-02.gh-issue-103124.JspiNN.rst deleted file mode 100644 index 022524b369aa10..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-09-03-53-02.gh-issue-103124.JspiNN.rst +++ /dev/null @@ -1 +0,0 @@ -Added multiline statement support for :mod:`pdb` diff --git a/Misc/NEWS.d/next/Library/2023-04-12-03-03-27.gh-issue-103464.Oa_8IW.rst b/Misc/NEWS.d/next/Library/2023-04-12-03-03-27.gh-issue-103464.Oa_8IW.rst deleted file mode 100644 index 6afaeb6485ee40..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-12-03-03-27.gh-issue-103464.Oa_8IW.rst +++ /dev/null @@ -1 +0,0 @@ -Provide helpful usage messages when parsing incorrect :mod:`pdb` commands. diff --git a/Misc/NEWS.d/next/Library/2023-04-15-23-26-16.gh-issue-103558.w9OzK4.rst b/Misc/NEWS.d/next/Library/2023-04-15-23-26-16.gh-issue-103558.w9OzK4.rst deleted file mode 100644 index e62af647fcc96a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-15-23-26-16.gh-issue-103558.w9OzK4.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed ``parent`` argument validation mechanism of :mod:`argparse`. Improved test coverage. diff --git a/Misc/NEWS.d/next/Library/2023-04-28-09-31-21.gh-issue-102676.J8qDRa.rst b/Misc/NEWS.d/next/Library/2023-04-28-09-31-21.gh-issue-102676.J8qDRa.rst deleted file mode 100644 index eef89645aa533f..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-28-09-31-21.gh-issue-102676.J8qDRa.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add fields ``start_offset``, ``cache_offset``, ``end_offset``, -``baseopname``, ``baseopcode``, ``jump_target`` and ``oparg`` to -:class:`dis.Instruction`. diff --git a/Misc/NEWS.d/next/Library/2023-05-11-23-03-00.gh-issue-104399.MMatTP.rst b/Misc/NEWS.d/next/Library/2023-05-11-23-03-00.gh-issue-104399.MMatTP.rst deleted file mode 100644 index 84cc888635b415..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-11-23-03-00.gh-issue-104399.MMatTP.rst +++ /dev/null @@ -1,4 +0,0 @@ -Prepare the ``_tkinter`` module for building with Tcl 9.0 and future -libtommath by replacing usage of deprecated functions -:c:func:`mp_to_unsigned_bin_n` and :c:func:`mp_unsigned_bin_size` -when necessary. diff --git a/Misc/NEWS.d/next/Library/2023-05-15-18-57-42.gh-issue-102613.YD9yx-.rst b/Misc/NEWS.d/next/Library/2023-05-15-18-57-42.gh-issue-102613.YD9yx-.rst deleted file mode 100644 index 841a9e1e26d317..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-15-18-57-42.gh-issue-102613.YD9yx-.rst +++ /dev/null @@ -1,4 +0,0 @@ -Improve performance of :meth:`pathlib.Path.glob` when expanding a pattern with -a non-terminal "``**``" component by filtering walked paths through a regular -expression, rather than calling :func:`os.scandir` more than once on each -directory. diff --git a/Misc/NEWS.d/next/Library/2023-05-19-19-46-22.gh-issue-99108.wqCg0t.rst b/Misc/NEWS.d/next/Library/2023-05-19-19-46-22.gh-issue-99108.wqCg0t.rst deleted file mode 100644 index b595f1893609cc..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-19-19-46-22.gh-issue-99108.wqCg0t.rst +++ /dev/null @@ -1,3 +0,0 @@ -We now release the GIL around built-in :mod:`hashlib` computations of -reasonable size for the SHA families and MD5 hash functions, matching -what our OpenSSL backed hash computations already does. diff --git a/Misc/NEWS.d/next/Library/2023-05-22-18-39-53.gh-issue-104372.7tDRaK.rst b/Misc/NEWS.d/next/Library/2023-05-22-18-39-53.gh-issue-104372.7tDRaK.rst deleted file mode 100644 index ea13ec85543ca2..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-22-18-39-53.gh-issue-104372.7tDRaK.rst +++ /dev/null @@ -1,5 +0,0 @@ -On Linux where :mod:`subprocess` can use the ``vfork()`` syscall for faster -spawning, prevent the parent process from blocking other threads by dropping -the GIL while it waits for the vfork'ed child process ``exec()`` outcome. -This prevents spawning a binary from a slow filesystem from blocking the -rest of the application. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-01-37-40.gh-issue-104773.8c-GsG.rst b/Misc/NEWS.d/next/Library/2023-05-23-01-37-40.gh-issue-104773.8c-GsG.rst deleted file mode 100644 index 228916158534b2..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-01-37-40.gh-issue-104773.8c-GsG.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!sndhdr` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-01-47-57.gh-issue-104773.I6MQhb.rst b/Misc/NEWS.d/next/Library/2023-05-23-01-47-57.gh-issue-104773.I6MQhb.rst deleted file mode 100644 index 42f7a5286867cd..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-01-47-57.gh-issue-104773.I6MQhb.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!cgi`` and :mod:`!cgitb` modules, deprecated in -Python 3.11. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst b/Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst deleted file mode 100644 index 213b6f5b764258..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!imghdr` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-02-20-13.gh-issue-104773.7K59zr.rst b/Misc/NEWS.d/next/Library/2023-05-23-02-20-13.gh-issue-104773.7K59zr.rst deleted file mode 100644 index 0f3162ef509a82..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-02-20-13.gh-issue-104773.7K59zr.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!telnetlib` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-03-36-47.gh-issue-104780.P4e3Yf.rst b/Misc/NEWS.d/next/Library/2023-05-23-03-36-47.gh-issue-104780.P4e3Yf.rst deleted file mode 100644 index acdca53b4bb7d4..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-03-36-47.gh-issue-104780.P4e3Yf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the ``2to3`` program and the :mod:`!lib2to3` module, deprecated in -Python 3.11. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-04-01-27.gh-issue-104783.QyhIoq.rst b/Misc/NEWS.d/next/Library/2023-05-23-04-01-27.gh-issue-104783.QyhIoq.rst deleted file mode 100644 index 23670e8fe14d3d..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-04-01-27.gh-issue-104783.QyhIoq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove ``locale.resetlocale()`` function deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-17-43-52.gh-issue-104797.NR7KzF.rst b/Misc/NEWS.d/next/Library/2023-05-23-17-43-52.gh-issue-104797.NR7KzF.rst deleted file mode 100644 index 60c9a0601cdc9a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-17-43-52.gh-issue-104797.NR7KzF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow :class:`typing.Protocol` classes to inherit from -:class:`collections.abc.Buffer`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-18-31-49.gh-issue-104799.MJYOw6.rst b/Misc/NEWS.d/next/Library/2023-05-23-18-31-49.gh-issue-104799.MJYOw6.rst deleted file mode 100644 index 614918d7572969..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-18-31-49.gh-issue-104799.MJYOw6.rst +++ /dev/null @@ -1,4 +0,0 @@ -Adjust the location of the (see :pep:`695`) ``type_params`` field on -:class:`ast.ClassDef`, :class:`ast.AsyncFunctionDef`, and -:class:`ast.FunctionDef` to better preserve backward compatibility. Patch by -Jelle Zijlstra diff --git a/Misc/NEWS.d/next/Library/2023-05-23-19-53-18.gh-issue-83863.eRI5JG.rst b/Misc/NEWS.d/next/Library/2023-05-23-19-53-18.gh-issue-83863.eRI5JG.rst deleted file mode 100644 index 7a073aa37dd6ae..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-19-53-18.gh-issue-83863.eRI5JG.rst +++ /dev/null @@ -1,4 +0,0 @@ -Support for using :class:`pathlib.Path` objects as context managers has been -removed. Before Python 3.9, exiting the context manager marked a path as -"closed", which caused some (but not all!) methods to raise when called. -Since Python 3.9, using a path as a context manager does nothing. diff --git a/Misc/NEWS.d/next/Library/2023-05-23-21-25-54.gh-issue-104804.78fiE6.rst b/Misc/NEWS.d/next/Library/2023-05-23-21-25-54.gh-issue-104804.78fiE6.rst deleted file mode 100644 index 78409cf7cbc9dd..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-23-21-25-54.gh-issue-104804.78fiE6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the untested and undocumented :mod:`webbrowser` :class:`!MacOSX` class, deprecated in Python 3.11. -Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-08-45-04.gh-issue-104835.bN_B-B.rst b/Misc/NEWS.d/next/Library/2023-05-24-08-45-04.gh-issue-104835.bN_B-B.rst deleted file mode 100644 index f8e979b47392f4..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-08-45-04.gh-issue-104835.bN_B-B.rst +++ /dev/null @@ -1,13 +0,0 @@ -Removed the following :mod:`unittest` functions, deprecated in Python 3.11: - -* :func:`!unittest.findTestCases` -* :func:`!unittest.makeSuite` -* :func:`!unittest.getTestCaseNames` - -Use :class:`~unittest.TestLoader` methods instead: - -* :meth:`unittest.TestLoader.loadTestsFromModule` -* :meth:`unittest.TestLoader.loadTestsFromTestCase` -* :meth:`unittest.TestLoader.getTestCaseNames` - -Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-09-34-23.gh-issue-104874.oqyJSy.rst b/Misc/NEWS.d/next/Library/2023-05-24-09-34-23.gh-issue-104874.oqyJSy.rst deleted file mode 100644 index 9d5904bc146421..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-09-34-23.gh-issue-104874.oqyJSy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document the ``__name__`` and ``__supertype__`` attributes of -:class:`typing.NewType`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-09-55-33.gh-issue-104873.BKQ54y.rst b/Misc/NEWS.d/next/Library/2023-05-24-09-55-33.gh-issue-104873.BKQ54y.rst deleted file mode 100644 index c901d83812f176..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-09-55-33.gh-issue-104873.BKQ54y.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :func:`typing.get_protocol_members` to return the set of members -defining a :class:`typing.Protocol`. Add :func:`typing.is_protocol` to -check whether a class is a :class:`typing.Protocol`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-11-45-22.gh-issue-104773.R0Br4-.rst b/Misc/NEWS.d/next/Library/2023-05-24-11-45-22.gh-issue-104773.R0Br4-.rst deleted file mode 100644 index 31da29ec2a5928..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-11-45-22.gh-issue-104773.R0Br4-.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!pipes` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-14-30-14.gh-issue-104780.nXGIJt.rst b/Misc/NEWS.d/next/Library/2023-05-24-14-30-14.gh-issue-104780.nXGIJt.rst deleted file mode 100644 index 62d63a6fb7605b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-14-30-14.gh-issue-104780.nXGIJt.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!ossaudiodev` module, deprecated in Python 3.11. -Patch Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-14-58-13.gh-issue-104773.sQaXrY.rst b/Misc/NEWS.d/next/Library/2023-05-24-14-58-13.gh-issue-104773.sQaXrY.rst deleted file mode 100644 index fc103cd9aa3982..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-14-58-13.gh-issue-104773.sQaXrY.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!sunau` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-15-17-05.gh-issue-104773.EmFIQ5.rst b/Misc/NEWS.d/next/Library/2023-05-24-15-17-05.gh-issue-104773.EmFIQ5.rst deleted file mode 100644 index 95a99a20930c5a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-15-17-05.gh-issue-104773.EmFIQ5.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!mailcap` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-15-57-34.gh-issue-104773.IHWRgg.rst b/Misc/NEWS.d/next/Library/2023-05-24-15-57-34.gh-issue-104773.IHWRgg.rst deleted file mode 100644 index a2b2604f26d650..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-15-57-34.gh-issue-104773.IHWRgg.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!chunk` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-17-22-56.gh-issue-75552._QlrpQ.rst b/Misc/NEWS.d/next/Library/2023-05-24-17-22-56.gh-issue-75552._QlrpQ.rst deleted file mode 100644 index e70712af97944f..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-17-22-56.gh-issue-75552._QlrpQ.rst +++ /dev/null @@ -1 +0,0 @@ -Removed the ``tkinter.tix`` module, deprecated since Python 3.6. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst b/Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst deleted file mode 100644 index 22194895705664..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst +++ /dev/null @@ -1,3 +0,0 @@ -:pep:`594`: Remove the :mod:`!spwd` module, deprecated in Python 3.11: the -`python-pam project `_ can be used -instead. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-18-48-10.gh-issue-104773.TrgUeO.rst b/Misc/NEWS.d/next/Library/2023-05-24-18-48-10.gh-issue-104773.TrgUeO.rst deleted file mode 100644 index 34f46d951abb89..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-18-48-10.gh-issue-104773.TrgUeO.rst +++ /dev/null @@ -1 +0,0 @@ -:pep:`594`: Removed the :mod:`!msilib` package, deprecated in Python 3.11. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-19-48-16.gh-issue-104876.Z00Qnk.rst b/Misc/NEWS.d/next/Library/2023-05-24-19-48-16.gh-issue-104876.Z00Qnk.rst deleted file mode 100644 index ce1f5606415085..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-19-48-16.gh-issue-104876.Z00Qnk.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the :meth:`!turtle.RawTurtle.settiltangle` method, deprecated in docs -since Python 3.1 and with a deprecation warning since Python 3.11. Patch by -Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-20-21-27.gh-issue-104786.SmgT5_.rst b/Misc/NEWS.d/next/Library/2023-05-24-20-21-27.gh-issue-104786.SmgT5_.rst deleted file mode 100644 index aac669434ec266..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-20-21-27.gh-issue-104786.SmgT5_.rst +++ /dev/null @@ -1 +0,0 @@ -Remove kwargs-based :class:`typing.TypedDict` creation diff --git a/Misc/NEWS.d/next/Library/2023-05-24-21-30-40.gh-issue-104886.8TuV-_.rst b/Misc/NEWS.d/next/Library/2023-05-24-21-30-40.gh-issue-104886.8TuV-_.rst deleted file mode 100644 index 2f6796bed7b17c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-21-30-40.gh-issue-104886.8TuV-_.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the undocumented :class:`!configparser.LegacyInterpolation` class, -deprecated in the docstring since Python 3.2, and with a deprecation warning -since Python 3.11. Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-22-22-03.gh-issue-104773.NwpjhZ.rst b/Misc/NEWS.d/next/Library/2023-05-24-22-22-03.gh-issue-104773.NwpjhZ.rst deleted file mode 100644 index f995375e0735f8..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-22-22-03.gh-issue-104773.NwpjhZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!nntplib` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-22-47-13.gh-issue-104773.itOIf3.rst b/Misc/NEWS.d/next/Library/2023-05-24-22-47-13.gh-issue-104773.itOIf3.rst deleted file mode 100644 index 92ee9bf4f2baf0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-22-47-13.gh-issue-104773.itOIf3.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!xdrlib` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-22-50-21.gh-issue-104898.UbT2S4.rst b/Misc/NEWS.d/next/Library/2023-05-24-22-50-21.gh-issue-104898.UbT2S4.rst deleted file mode 100644 index e596ab36f5c729..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-22-50-21.gh-issue-104898.UbT2S4.rst +++ /dev/null @@ -1 +0,0 @@ -Add missing :attr:`~object.__slots__` to :class:`os.PathLike`. diff --git a/Misc/NEWS.d/next/Library/2023-05-24-23-40-22.gh-issue-104773.FHA99J.rst b/Misc/NEWS.d/next/Library/2023-05-24-23-40-22.gh-issue-104773.FHA99J.rst deleted file mode 100644 index 96c315dda79e74..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-24-23-40-22.gh-issue-104773.FHA99J.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!nis` module, deprecated in Python 3.11. Patch -by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst b/Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst deleted file mode 100644 index d5443aef80d488..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!crypt` module and its private :mod:`!_crypt` -extension, deprecated in Python 3.11. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-25-08-50-47.gh-issue-104935.-rm1BR.rst b/Misc/NEWS.d/next/Library/2023-05-25-08-50-47.gh-issue-104935.-rm1BR.rst deleted file mode 100644 index 7af52bce2c9185..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-25-08-50-47.gh-issue-104935.-rm1BR.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix bugs with the interaction between :func:`typing.runtime_checkable` and -:class:`typing.Generic` that were introduced by the :pep:`695` -implementation. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2023-05-25-15-54-02.gh-issue-104773.nW-5MI.rst b/Misc/NEWS.d/next/Library/2023-05-25-15-54-02.gh-issue-104773.nW-5MI.rst deleted file mode 100644 index 522e259992de27..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-25-15-54-02.gh-issue-104773.nW-5MI.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!uu` module, deprecated in Python 3.11. Patch -by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-25-16-50-43.gh-issue-104773.pmg0Fr.rst b/Misc/NEWS.d/next/Library/2023-05-25-16-50-43.gh-issue-104773.pmg0Fr.rst deleted file mode 100644 index 162afb6f2727a8..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-25-16-50-43.gh-issue-104773.pmg0Fr.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!aifc` module, deprecated in Python 3.11. Patch -by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-25-17-25-16.gh-issue-104773.O6TOMc.rst b/Misc/NEWS.d/next/Library/2023-05-25-17-25-16.gh-issue-104773.O6TOMc.rst deleted file mode 100644 index e668e75896043e..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-25-17-25-16.gh-issue-104773.O6TOMc.rst +++ /dev/null @@ -1,2 +0,0 @@ -:pep:`594`: Remove the :mod:`!audioop` module, deprecated in Python 3.11. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-25-22-54-20.gh-issue-104947.hi6TUr.rst b/Misc/NEWS.d/next/Library/2023-05-25-22-54-20.gh-issue-104947.hi6TUr.rst deleted file mode 100644 index 4af73d73d2a717..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-25-22-54-20.gh-issue-104947.hi6TUr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make comparisons between :class:`pathlib.PureWindowsPath` objects consistent -across Windows and Posix to match 3.11 behavior. diff --git a/Misc/NEWS.d/next/Library/2023-05-25-23-34-54.gh-issue-103631.x5Urye.rst b/Misc/NEWS.d/next/Library/2023-05-25-23-34-54.gh-issue-103631.x5Urye.rst deleted file mode 100644 index d1eb2d3ed6191f..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-25-23-34-54.gh-issue-103631.x5Urye.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``pathlib.PurePosixPath(pathlib.PureWindowsPath(...))`` not converting -path separators to restore 3.11 compatible behavior. diff --git a/Misc/NEWS.d/next/Library/2023-05-26-01-31-30.gh-issue-101588.RaqxFy.rst b/Misc/NEWS.d/next/Library/2023-05-26-01-31-30.gh-issue-101588.RaqxFy.rst deleted file mode 100644 index 07e3dc468f7d9a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-26-01-31-30.gh-issue-101588.RaqxFy.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate undocumented copy/deepcopy/pickle support for itertools. diff --git a/Misc/NEWS.d/next/Library/2023-05-26-21-24-06.gh-issue-104996.aaW78g.rst b/Misc/NEWS.d/next/Library/2023-05-26-21-24-06.gh-issue-104996.aaW78g.rst deleted file mode 100644 index 8b81b681af94aa..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-26-21-24-06.gh-issue-104996.aaW78g.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve performance of :class:`pathlib.PurePath` initialisation by -deferring joining of paths when multiple arguments are given. diff --git a/Misc/NEWS.d/next/Library/2023-05-26-21-33-24.gh-issue-104992.dbq9WK.rst b/Misc/NEWS.d/next/Library/2023-05-26-21-33-24.gh-issue-104992.dbq9WK.rst deleted file mode 100644 index d72646a6541f19..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-26-21-33-24.gh-issue-104992.dbq9WK.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the untested and undocumented :meth:`!unittest.TestProgram.usageExit` -method, deprecated in Python 3.11. Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2023-05-30-17-39-03.gh-issue-105096.pw00FW.rst b/Misc/NEWS.d/next/Library/2023-05-30-17-39-03.gh-issue-105096.pw00FW.rst deleted file mode 100644 index bc82c13081f140..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-30-17-39-03.gh-issue-105096.pw00FW.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`wave`: Deprecate the ``getmark()``, ``setmark()`` and ``getmarkers()`` -methods of the :class:`wave.Wave_read` and :class:`wave.Wave_write` classes. -They will be removed in Python 3.15. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-30-18-45-02.gh-issue-62948.1-5wMR.rst b/Misc/NEWS.d/next/Library/2023-05-30-18-45-02.gh-issue-62948.1-5wMR.rst deleted file mode 100644 index d6ba989329bce0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-30-18-45-02.gh-issue-62948.1-5wMR.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :class:`io.IOBase` finalizer now logs the ``close()`` method errors with -:data:`sys.unraisablehook`. Previously, errors were ignored silently by default, -and only logged in :ref:`Python Development Mode ` or on -:ref:`Python built on debug mode `. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-05-31-16-58-42.gh-issue-105144.Oqfn0V.rst b/Misc/NEWS.d/next/Library/2023-05-31-16-58-42.gh-issue-105144.Oqfn0V.rst deleted file mode 100644 index 7e4d6fbc4911ba..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-05-31-16-58-42.gh-issue-105144.Oqfn0V.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a recent regression in the :mod:`typing` module. The regression meant -that doing ``class Foo(X, typing.Protocol)``, where ``X`` was a class that -had :class:`abc.ABCMeta` as its metaclass, would then cause subsequent -``isinstance(1, X)`` calls to erroneously raise :exc:`TypeError`. Patch by -Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-06-02-02-38-26.gh-issue-105080.2imGMg.rst b/Misc/NEWS.d/next/Library/2023-06-02-02-38-26.gh-issue-105080.2imGMg.rst deleted file mode 100644 index efe8365a7644be..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-02-02-38-26.gh-issue-105080.2imGMg.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed inconsistent signature on derived classes for :func:`inspect.signature` diff --git a/Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst b/Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst deleted file mode 100644 index 461a3a25fe1b43..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst +++ /dev/null @@ -1,7 +0,0 @@ -In the beta 1 release we added a utility function for extension module -authors, to use when testing their module for support in multiple -interpreters or under a per-interpreter GIL. The name of that function has -changed from ``allowing_all_extensions`` to -``_incompatible_extension_module_restrictions``. The default for the -"disable_check" argument has change from ``True`` to ``False``, to better -match the new function name. diff --git a/Misc/NEWS.d/next/Library/2023-06-02-14-57-11.gh-issue-105239.SAmuuj.rst b/Misc/NEWS.d/next/Library/2023-06-02-14-57-11.gh-issue-105239.SAmuuj.rst deleted file mode 100644 index 35e1b1a217b3a4..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-02-14-57-11.gh-issue-105239.SAmuuj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix longstanding bug where ``issubclass(object, typing.Protocol)`` would -evaluate to ``True`` in some edge cases. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-06-02-23-32-17.gh-issue-80480.savBw9.rst b/Misc/NEWS.d/next/Library/2023-06-02-23-32-17.gh-issue-80480.savBw9.rst deleted file mode 100644 index fd87efe9bde0c3..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-02-23-32-17.gh-issue-80480.savBw9.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`array`: Add ``'w'`` typecode that represents ``Py_UCS4``. diff --git a/Misc/NEWS.d/next/Library/2023-06-04-12-16-47.gh-issue-105280.srRbCe.rst b/Misc/NEWS.d/next/Library/2023-06-04-12-16-47.gh-issue-105280.srRbCe.rst deleted file mode 100644 index 8e469646604316..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-04-12-16-47.gh-issue-105280.srRbCe.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix bug where ``isinstance([], collections.abc.Mapping)`` could evaluate to -``True`` if garbage collection happened at the wrong time. The bug was -caused by changes to the implementation of :class:`typing.Protocol` in -Python 3.12. diff --git a/Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst b/Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst deleted file mode 100644 index c23e1ffd3538e3..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-04-23-20-56.gh-issue-105292.ns6XQR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add option to :func:`traceback.format_exception_only` to recurse into the -nested exception of a :exc:`BaseExceptionGroup`. diff --git a/Misc/NEWS.d/next/Library/2023-06-05-14-43-56.gh-issue-104554.pwfKIo.rst b/Misc/NEWS.d/next/Library/2023-06-05-14-43-56.gh-issue-104554.pwfKIo.rst deleted file mode 100644 index 9ef8c67459c406..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-05-14-43-56.gh-issue-104554.pwfKIo.rst +++ /dev/null @@ -1 +0,0 @@ -Add RTSPS scheme support in urllib.parse diff --git a/Misc/NEWS.d/next/Library/2023-06-06-11-50-33.gh-issue-105332.tmpgRA.rst b/Misc/NEWS.d/next/Library/2023-06-06-11-50-33.gh-issue-105332.tmpgRA.rst deleted file mode 100644 index 31b6855a6ebfad..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-06-11-50-33.gh-issue-105332.tmpgRA.rst +++ /dev/null @@ -1 +0,0 @@ -Revert pickling method from by-name back to by-value. diff --git a/Misc/NEWS.d/next/Library/2023-06-06-15-32-44.gh-issue-105376.W4oDQp.rst b/Misc/NEWS.d/next/Library/2023-06-06-15-32-44.gh-issue-105376.W4oDQp.rst deleted file mode 100644 index 2ed6b5e0a7ac0a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-06-15-32-44.gh-issue-105376.W4oDQp.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`logging`: Remove undocumented and untested ``Logger.warn()`` and -``LoggerAdapter.warn()`` methods and ``logging.warn()`` function. Deprecated -since Python 3.3, they were aliases to the :meth:`logging.Logger.warning` -method, :meth:`!logging.LoggerAdapter.warning` method and -:func:`logging.warning` function. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-06-06-16-00-03.gh-issue-105382.A1LgzA.rst b/Misc/NEWS.d/next/Library/2023-06-06-16-00-03.gh-issue-105382.A1LgzA.rst deleted file mode 100644 index 4e6d72745ff025..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-06-16-00-03.gh-issue-105382.A1LgzA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove *cafile*, *capath* and *cadefault* parameters of the -:func:`urllib.request.urlopen` function, deprecated in Python 3.6. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-06-07-00-09-52.gh-issue-105375.Y_9D4n.rst b/Misc/NEWS.d/next/Library/2023-06-07-00-09-52.gh-issue-105375.Y_9D4n.rst deleted file mode 100644 index ec10d63822c203..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-07-00-09-52.gh-issue-105375.Y_9D4n.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in :mod:`sqlite3` where an exception could be overwritten in the -:meth:`collation ` callback. diff --git a/Misc/NEWS.d/next/Library/2023-06-08-08-58-36.gh-issue-105375.bTcqS9.rst b/Misc/NEWS.d/next/Library/2023-06-08-08-58-36.gh-issue-105375.bTcqS9.rst deleted file mode 100644 index 3030477c8245b5..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-08-08-58-36.gh-issue-105375.bTcqS9.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bugs in :mod:`pickle` where exceptions could be overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-08-17-49-46.gh-issue-105497.K6Q8nU.rst b/Misc/NEWS.d/next/Library/2023-06-08-17-49-46.gh-issue-105497.K6Q8nU.rst deleted file mode 100644 index 2d4e2091b50714..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-08-17-49-46.gh-issue-105497.K6Q8nU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix flag inversion when alias/mask members exist. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-08-38-30.gh-issue-105545.2q3ysu.rst b/Misc/NEWS.d/next/Library/2023-06-09-08-38-30.gh-issue-105545.2q3ysu.rst deleted file mode 100644 index f27692126a7ec4..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-08-38-30.gh-issue-105545.2q3ysu.rst +++ /dev/null @@ -1 +0,0 @@ -Remove deprecated in 3.11 ``webbrowser.MacOSXOSAScript._name`` attribute. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-20-34-23.gh-issue-105566.YxlGg1.rst b/Misc/NEWS.d/next/Library/2023-06-09-20-34-23.gh-issue-105566.YxlGg1.rst deleted file mode 100644 index c2c497aee513d3..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-20-34-23.gh-issue-105566.YxlGg1.rst +++ /dev/null @@ -1,10 +0,0 @@ -Deprecate creating a :class:`typing.NamedTuple` class using keyword -arguments to denote the fields (``NT = NamedTuple("NT", x=int, y=str)``). -This will be disallowed in Python 3.15. -Use the class-based syntax or the functional syntax instead. - -Two methods of creating ``NamedTuple`` classes with 0 fields using the -functional syntax are also deprecated, and will be disallowed in Python 3.15: -``NT = NamedTuple("NT")`` and ``NT = NamedTuple("NT", None)``. To create a -``NamedTuple`` class with 0 fields, either use ``class NT(NamedTuple): pass`` or -``NT = NamedTuple("NT", [])``. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-04-39.gh-issue-105375.bTcqS9.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-04-39.gh-issue-105375.bTcqS9.rst deleted file mode 100644 index 3030477c8245b5..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-21-04-39.gh-issue-105375.bTcqS9.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bugs in :mod:`pickle` where exceptions could be overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst deleted file mode 100644 index 4202b758d1db56..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bugs in :mod:`zoneinfo` where exceptions could be overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-25-14.gh-issue-105375.95g1eI.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-25-14.gh-issue-105375.95g1eI.rst deleted file mode 100644 index 1894b2b94bb334..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-21-25-14.gh-issue-105375.95g1eI.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bugs in :mod:`!_elementtree` where exceptions could be overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-30-59.gh-issue-105375.eewafp.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-30-59.gh-issue-105375.eewafp.rst deleted file mode 100644 index e000f98828a211..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-21-30-59.gh-issue-105375.eewafp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in the :mod:`posix` module where an exception could be -overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-40-45.gh-issue-105375._sZilh.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-40-45.gh-issue-105375._sZilh.rst deleted file mode 100644 index 87db4c2b4e22e3..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-21-40-45.gh-issue-105375._sZilh.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bugs in :mod:`_ctypes` where exceptions could end up being overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-46-52.gh-issue-105375.yrJelV.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-46-52.gh-issue-105375.yrJelV.rst deleted file mode 100644 index 21aea1b0b4082c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-21-46-52.gh-issue-105375.yrJelV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in :class:`array.array` where an exception could end up being -overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-22-16-46.gh-issue-105375.EgVJOP.rst b/Misc/NEWS.d/next/Library/2023-06-09-22-16-46.gh-issue-105375.EgVJOP.rst deleted file mode 100644 index 49f7df68e927cb..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-22-16-46.gh-issue-105375.EgVJOP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bugs in :mod:`!_ssl` initialisation which could lead to leaked -references and overwritten exceptions. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-22-45-26.gh-issue-105375.9rp6tG.rst b/Misc/NEWS.d/next/Library/2023-06-09-22-45-26.gh-issue-105375.9rp6tG.rst deleted file mode 100644 index 352d7b83a71632..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-22-45-26.gh-issue-105375.9rp6tG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bugs in :mod:`!_datetime` where exceptions could be overwritten in case -of module initialisation failure. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-22-52-45.gh-issue-105375.6igkhn.rst b/Misc/NEWS.d/next/Library/2023-06-09-22-52-45.gh-issue-105375.6igkhn.rst deleted file mode 100644 index 05e78fdc9b4076..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-22-52-45.gh-issue-105375.6igkhn.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug in :mod:`decimal` where an exception could end up being overwritten. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-23-00-13.gh-issue-105605.YuwqxY.rst b/Misc/NEWS.d/next/Library/2023-06-09-23-00-13.gh-issue-105605.YuwqxY.rst deleted file mode 100644 index 5fba6d293a785e..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-23-00-13.gh-issue-105605.YuwqxY.rst +++ /dev/null @@ -1,3 +0,0 @@ -Harden :mod:`pyexpat` error handling during module initialisation to prevent -exceptions from possibly being overwritten, and objects from being -dereferenced twice. diff --git a/Misc/NEWS.d/next/Library/2023-06-09-23-46-23.gh-issue-105375.9KaioS.rst b/Misc/NEWS.d/next/Library/2023-06-09-23-46-23.gh-issue-105375.9KaioS.rst deleted file mode 100644 index b12d7c864e7b86..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-09-23-46-23.gh-issue-105375.9KaioS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bugs in :mod:`sys` where exceptions could end up being overwritten -because of deferred error handling. diff --git a/Misc/NEWS.d/next/Library/2023-06-10-12-20-17.gh-issue-105626.XyZein.rst b/Misc/NEWS.d/next/Library/2023-06-10-12-20-17.gh-issue-105626.XyZein.rst deleted file mode 100644 index 2a48361fa596c9..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-10-12-20-17.gh-issue-105626.XyZein.rst +++ /dev/null @@ -1,3 +0,0 @@ -Change the default return value of -:meth:`http.client.HTTPConnection.get_proxy_response_headers` to be ``None`` -and not ``{}``. diff --git a/Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst b/Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst deleted file mode 100644 index dda8f428760ba1..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in :c:func:`!_Unpickler_SetInputStream` where an exception could -end up being overwritten in case of failure. diff --git a/Misc/NEWS.d/next/Library/2023-06-12-10-40-38.gh-issue-105684.yiHkFD.rst b/Misc/NEWS.d/next/Library/2023-06-12-10-40-38.gh-issue-105684.yiHkFD.rst deleted file mode 100644 index b0d4eb328a7b34..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-12-10-40-38.gh-issue-105684.yiHkFD.rst +++ /dev/null @@ -1,3 +0,0 @@ -Supporting :meth:`asyncio.Task.set_name` is now mandatory for third party task implementations. -The undocumented :func:`!_set_task_name` function (deprecated since 3.8) has been removed. -Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2023-06-12-15-17-34.gh-issue-105687.ZUonKm.rst b/Misc/NEWS.d/next/Library/2023-06-12-15-17-34.gh-issue-105687.ZUonKm.rst deleted file mode 100644 index 7966d3a566414e..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-12-15-17-34.gh-issue-105687.ZUonKm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove deprecated ``re.template``, ``re.T``, ``re.TEMPLATE``, -``sre_constans.SRE_FLAG_TEMPLATE``. diff --git a/Misc/NEWS.d/next/Library/2023-06-13-19-38-12.gh-issue-105733.WOp0mG.rst b/Misc/NEWS.d/next/Library/2023-06-13-19-38-12.gh-issue-105733.WOp0mG.rst deleted file mode 100644 index 20f2ba2bcc5cb1..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-13-19-38-12.gh-issue-105733.WOp0mG.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`ctypes`: Deprecate undocumented :func:`!ctypes.SetPointerType` and -:func:`!ctypes.ARRAY` functions. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2023-06-14-10-27-34.gh-issue-105745.l1ttOQ.rst b/Misc/NEWS.d/next/Library/2023-06-14-10-27-34.gh-issue-105745.l1ttOQ.rst deleted file mode 100644 index 7df7c5a79ec6eb..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-14-10-27-34.gh-issue-105745.l1ttOQ.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``webbrowser.Konqueror.open`` method. diff --git a/Misc/NEWS.d/next/Library/2023-06-14-14-32-31.gh-issue-105570.sFTtQU.rst b/Misc/NEWS.d/next/Library/2023-06-14-14-32-31.gh-issue-105570.sFTtQU.rst deleted file mode 100644 index e31a8ee256d697..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-14-14-32-31.gh-issue-105570.sFTtQU.rst +++ /dev/null @@ -1,5 +0,0 @@ -Deprecate two methods of creating :class:`typing.TypedDict` classes with 0 -fields using the functional syntax: ``TD = TypedDict("TD")`` and -``TD = TypedDict("TD", None)``. Both will be disallowed in Python 3.15. To create a -``TypedDict`` class with 0 fields, either use ``class TD(TypedDict): pass`` -or ``TD = TypedDict("TD", {})``. diff --git a/Misc/NEWS.d/next/Library/2023-06-14-18-41-18.gh-issue-105793.YSoykM.rst b/Misc/NEWS.d/next/Library/2023-06-14-18-41-18.gh-issue-105793.YSoykM.rst deleted file mode 100644 index 0e4090ea7eabb9..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-14-18-41-18.gh-issue-105793.YSoykM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add *follow_symlinks* keyword-only argument to :meth:`pathlib.Path.is_dir` and -:meth:`~pathlib.Path.is_file`, defaulting to ``True``. diff --git a/Misc/NEWS.d/next/Library/2023-06-15-18-11-47.gh-issue-104799.BcLzbP.rst b/Misc/NEWS.d/next/Library/2023-06-15-18-11-47.gh-issue-104799.BcLzbP.rst deleted file mode 100644 index d0dbff4f1553e2..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-15-18-11-47.gh-issue-104799.BcLzbP.rst +++ /dev/null @@ -1,3 +0,0 @@ -Enable :func:`ast.unparse` to unparse function and class definitions created -without the new ``type_params`` field from :pep:`695`. Patch by Jelle -Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2023-06-17-12-13-57.gh-issue-105481.KgBH5w.rst b/Misc/NEWS.d/next/Library/2023-06-17-12-13-57.gh-issue-105481.KgBH5w.rst deleted file mode 100644 index 11084ef956dcf3..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-17-12-13-57.gh-issue-105481.KgBH5w.rst +++ /dev/null @@ -1,4 +0,0 @@ -:func:`~dis.stack_effect` no longer raises an exception if an ``oparg`` is -provided for an ``opcode`` that doesn't use its arg, or when it is not -provided for an ``opcode`` that does use it. In the latter case, the stack -effect is returned for ``oparg=0``. diff --git a/Misc/NEWS.d/next/Library/2023-06-19-11-31-55.gh-issue-105808.NL-quu.rst b/Misc/NEWS.d/next/Library/2023-06-19-11-31-55.gh-issue-105808.NL-quu.rst deleted file mode 100644 index 8e69fd627c28e8..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-19-11-31-55.gh-issue-105808.NL-quu.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a regression introduced in GH-101251 for 3.12, causing :meth:`gzip.GzipFile.flush` to not flush the compressor (nor pass along the ``zip_mode`` argument). diff --git a/Misc/NEWS.d/next/Library/2023-06-19-22-20-41.gh-issue-89812.z2l_e8.rst b/Misc/NEWS.d/next/Library/2023-06-19-22-20-41.gh-issue-89812.z2l_e8.rst deleted file mode 100644 index f1ef11e26bc5fc..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-19-22-20-41.gh-issue-89812.z2l_e8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :exc:`pathlib.UnsupportedOperation`, which is raised instead of -:exc:`NotImplementedError` when a path operation isn't supported. diff --git a/Misc/NEWS.d/next/Library/2023-06-20-23-18-45.gh-issue-96145.o5dTRM.rst b/Misc/NEWS.d/next/Library/2023-06-20-23-18-45.gh-issue-96145.o5dTRM.rst deleted file mode 100644 index f4fb0e46ce5e57..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-20-23-18-45.gh-issue-96145.o5dTRM.rst +++ /dev/null @@ -1 +0,0 @@ -Reverted addition of ``json.AttrDict``. diff --git a/Misc/NEWS.d/next/Library/2023-06-21-19-04-27.gh-issue-105974.M47n3t.rst b/Misc/NEWS.d/next/Library/2023-06-21-19-04-27.gh-issue-105974.M47n3t.rst deleted file mode 100644 index 982192e59e3a50..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-21-19-04-27.gh-issue-105974.M47n3t.rst +++ /dev/null @@ -1,6 +0,0 @@ -Fix bug where a :class:`typing.Protocol` class that had one or more -non-callable members would raise :exc:`TypeError` when :func:`issubclass` -was called against it, even if it defined a custom ``__subclasshook__`` -method. The behaviour in Python 3.11 and lower -- which has now been -restored -- was not to raise :exc:`TypeError` in these situations if a -custom ``__subclasshook__`` method was defined. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-06-22-15-21-11.gh-issue-105987.T7Kzrb.rst b/Misc/NEWS.d/next/Library/2023-06-22-15-21-11.gh-issue-105987.T7Kzrb.rst deleted file mode 100644 index 0bc97da4edf0f9..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-22-15-21-11.gh-issue-105987.T7Kzrb.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash due to improper reference counting in :mod:`asyncio` eager task factory internal routines. diff --git a/Misc/NEWS.d/next/Library/2023-06-23-22-52-24.gh-issue-106046.OdLiLJ.rst b/Misc/NEWS.d/next/Library/2023-06-23-22-52-24.gh-issue-106046.OdLiLJ.rst deleted file mode 100644 index ce10a9d81dc64c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-23-22-52-24.gh-issue-106046.OdLiLJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the error message from :func:`os.fspath` if called on an object -where ``__fspath__`` is set to ``None``. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-06-25-06-57-24.gh-issue-104527.TJEUkd.rst b/Misc/NEWS.d/next/Library/2023-06-25-06-57-24.gh-issue-104527.TJEUkd.rst deleted file mode 100644 index 50b845bcde9bbe..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-25-06-57-24.gh-issue-104527.TJEUkd.rst +++ /dev/null @@ -1 +0,0 @@ -Zipapp will now skip over apending an archive to itself. diff --git a/Misc/NEWS.d/next/Library/2023-06-25-12-28-55.gh-issue-106075.W7tMRb.rst b/Misc/NEWS.d/next/Library/2023-06-25-12-28-55.gh-issue-106075.W7tMRb.rst deleted file mode 100644 index d2687154a58594..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-25-12-28-55.gh-issue-106075.W7tMRb.rst +++ /dev/null @@ -1 +0,0 @@ -Added `asyncio.taskgroups.__all__` to `asyncio.__all__` for export in star imports. diff --git a/Misc/NEWS.d/next/Library/2023-06-27-23-22-37.gh-issue-106152.ya5jBT.rst b/Misc/NEWS.d/next/Library/2023-06-27-23-22-37.gh-issue-106152.ya5jBT.rst deleted file mode 100644 index da9d2605f46294..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-27-23-22-37.gh-issue-106152.ya5jBT.rst +++ /dev/null @@ -1 +0,0 @@ -Added PY_THROW event hook for :mod:`cProfile` for generators diff --git a/Misc/NEWS.d/next/Library/2023-06-29-12-40-52.gh-issue-106238.VulKb9.rst b/Misc/NEWS.d/next/Library/2023-06-29-12-40-52.gh-issue-106238.VulKb9.rst deleted file mode 100644 index 52e78382fd618e..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-29-12-40-52.gh-issue-106238.VulKb9.rst +++ /dev/null @@ -1 +0,0 @@ -Fix rare concurrency bug in lock acquisition by the logging package. diff --git a/Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst b/Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst deleted file mode 100644 index 036bdb6ef59f6c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst +++ /dev/null @@ -1,2 +0,0 @@ -Replace ``assert`` statements with ``raise RuntimeError`` in -:mod:`threading`, so that ``_DummyThread`` cannot be joined even with ``-OO``. diff --git a/Misc/NEWS.d/next/Library/2023-07-01-16-40-54.gh-issue-102541.C1ahtk.rst b/Misc/NEWS.d/next/Library/2023-07-01-16-40-54.gh-issue-102541.C1ahtk.rst deleted file mode 100644 index efaf5db10f3e1c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-01-16-40-54.gh-issue-102541.C1ahtk.rst +++ /dev/null @@ -1 +0,0 @@ -Make pydoc.doc catch bad module ImportError when output stream is not None. diff --git a/Misc/NEWS.d/next/Library/2023-07-01-16-51-55.gh-issue-106309.hSlB17.rst b/Misc/NEWS.d/next/Library/2023-07-01-16-51-55.gh-issue-106309.hSlB17.rst deleted file mode 100644 index 5bd3880520871f..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-01-16-51-55.gh-issue-106309.hSlB17.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecate :func:`typing.no_type_check_decorator`. No major type checker ever -added support for this decorator. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-07-02-10-56-41.gh-issue-106330.QSkIUH.rst b/Misc/NEWS.d/next/Library/2023-07-02-10-56-41.gh-issue-106330.QSkIUH.rst deleted file mode 100644 index c1f55ab658b517..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-02-10-56-41.gh-issue-106330.QSkIUH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix incorrect matching of empty paths in :meth:`pathlib.PurePath.match`. -This bug was introduced in Python 3.12.0 beta 1. diff --git a/Misc/NEWS.d/next/Library/2023-07-03-15-09-44.gh-issue-106292.3npldV.rst b/Misc/NEWS.d/next/Library/2023-07-03-15-09-44.gh-issue-106292.3npldV.rst deleted file mode 100644 index 233509344d509b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-03-15-09-44.gh-issue-106292.3npldV.rst +++ /dev/null @@ -1,4 +0,0 @@ -Check for an instance-dict cached value in the :meth:`__get__` method of -:func:`functools.cached_property`. This better matches the pre-3.12 behavior -and improves compatibility for users subclassing -:func:`functools.cached_property` and adding a :meth:`__set__` method. diff --git a/Misc/NEWS.d/next/Library/2023-07-04-07-25-30.gh-issue-106403.GmefbV.rst b/Misc/NEWS.d/next/Library/2023-07-04-07-25-30.gh-issue-106403.GmefbV.rst deleted file mode 100644 index 4fea45f16c4f8e..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-04-07-25-30.gh-issue-106403.GmefbV.rst +++ /dev/null @@ -1,4 +0,0 @@ -Instances of :class:`typing.TypeVar`, :class:`typing.ParamSpec`, -:class:`typing.ParamSpecArgs`, :class:`typing.ParamSpecKwargs`, and -:class:`typing.TypeVarTuple` once again support weak references, fixing a -regression introduced in Python 3.12.0 beta 1. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2023-07-05-13-08-23.gh-issue-90876.Qvlkfl.rst b/Misc/NEWS.d/next/Library/2023-07-05-13-08-23.gh-issue-90876.Qvlkfl.rst deleted file mode 100644 index 3e062b5add6d89..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-05-13-08-23.gh-issue-90876.Qvlkfl.rst +++ /dev/null @@ -1,3 +0,0 @@ -Prevent :mod:`multiprocessing.spawn` from failing to *import* in environments -where ``sys.executable`` is ``None``. This regressed in 3.11 with the addition -of support for path-like objects in multiprocessing. diff --git a/Misc/NEWS.d/next/Library/2023-07-05-14-34-10.gh-issue-105497.HU5u89.rst b/Misc/NEWS.d/next/Library/2023-07-05-14-34-10.gh-issue-105497.HU5u89.rst deleted file mode 100644 index f4f2db08f73f50..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-05-14-34-10.gh-issue-105497.HU5u89.rst +++ /dev/null @@ -1 +0,0 @@ -Fix flag mask inversion when unnamed flags exist. diff --git a/Misc/NEWS.d/next/Library/2023-07-07-03-05-58.gh-issue-106503.ltfeiH.rst b/Misc/NEWS.d/next/Library/2023-07-07-03-05-58.gh-issue-106503.ltfeiH.rst deleted file mode 100644 index b8dd850386e86c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-07-03-05-58.gh-issue-106503.ltfeiH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ref cycle in :class:`!asyncio._SelectorSocketTransport` by removing -``_write_ready`` in ``close``. diff --git a/Misc/NEWS.d/next/Library/2023-07-07-13-47-28.gh-issue-106510.9n5BdC.rst b/Misc/NEWS.d/next/Library/2023-07-07-13-47-28.gh-issue-106510.9n5BdC.rst deleted file mode 100644 index e0646fa9bc0211..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-07-13-47-28.gh-issue-106510.9n5BdC.rst +++ /dev/null @@ -1 +0,0 @@ -Improve debug output for atomic groups in regular expressions. diff --git a/Misc/NEWS.d/next/Library/2023-07-07-16-19-59.gh-issue-106531.eMfNm8.rst b/Misc/NEWS.d/next/Library/2023-07-07-16-19-59.gh-issue-106531.eMfNm8.rst deleted file mode 100644 index a52107103c4576..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-07-16-19-59.gh-issue-106531.eMfNm8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed ``_legacy`` and the names it provided from ``importlib.resources``: -``Resource``, ``contents``, ``is_resource``, ``open_binary``, ``open_text``, -``path``, ``read_binary``, and ``read_text``. diff --git a/Misc/NEWS.d/next/Library/2023-07-07-17-44-03.gh-issue-106524.XkBV8h.rst b/Misc/NEWS.d/next/Library/2023-07-07-17-44-03.gh-issue-106524.XkBV8h.rst deleted file mode 100644 index f3fd070e391a66..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-07-17-44-03.gh-issue-106524.XkBV8h.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash in :func:`!_sre.template` with templates containing invalid group indices. diff --git a/Misc/NEWS.d/next/Library/2023-07-07-21-15-17.gh-issue-100502.Iici1B.rst b/Misc/NEWS.d/next/Library/2023-07-07-21-15-17.gh-issue-100502.Iici1B.rst deleted file mode 100644 index eea9564118df9c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-07-21-15-17.gh-issue-100502.Iici1B.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :attr:`pathlib.PurePath.pathmod` class attribute that stores the -implementation of :mod:`os.path` used for low-level path operations: either -``posixpath`` or ``ntpath``. diff --git a/Misc/NEWS.d/next/Library/2023-07-09-01-59-24.gh-issue-106554.37c53J.rst b/Misc/NEWS.d/next/Library/2023-07-09-01-59-24.gh-issue-106554.37c53J.rst deleted file mode 100644 index 2136f3aa5a8eb0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-09-01-59-24.gh-issue-106554.37c53J.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`selectors`: Reduce Selector overhead by using a ``dict.get()`` to lookup file descriptors. diff --git a/Misc/NEWS.d/next/Library/2023-07-11-09-25-40.gh-issue-106530.VgXrMx.rst b/Misc/NEWS.d/next/Library/2023-07-11-09-25-40.gh-issue-106530.VgXrMx.rst deleted file mode 100644 index 09fc647cc01d21..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-11-09-25-40.gh-issue-106530.VgXrMx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Revert a change to :func:`colorsys.rgb_to_hls` that caused division by zero -for certain almost-white inputs. Patch by Terry Jan Reedy. diff --git a/Misc/NEWS.d/next/Library/2023-07-11-12-34-04.gh-issue-89427.GOkCp9.rst b/Misc/NEWS.d/next/Library/2023-07-11-12-34-04.gh-issue-89427.GOkCp9.rst deleted file mode 100644 index 1605920cb8138b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-11-12-34-04.gh-issue-89427.GOkCp9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Set the environment variable ``VIRTUAL_ENV_PROMPT`` at :mod:`venv` -activation, even when ``VIRTUAL_ENV_DISABLE_PROMPT`` is set. diff --git a/Misc/NEWS.d/next/Library/2023-07-11-16-36-22.gh-issue-106628.Kx8Zvc.rst b/Misc/NEWS.d/next/Library/2023-07-11-16-36-22.gh-issue-106628.Kx8Zvc.rst deleted file mode 100644 index 6fa276e901f648..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-11-16-36-22.gh-issue-106628.Kx8Zvc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Speed up parsing of emails by about 20% by not compiling a new regular -expression for every single email. diff --git a/Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst b/Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst deleted file mode 100644 index c278cad74bd049..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-12-03-04-45.gh-issue-106664.ZeUG78.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`selectors`: Add ``_SelectorMapping.get()`` method and optimize ``_SelectorMapping.__getitem__()``. diff --git a/Misc/NEWS.d/next/Library/2023-07-12-04-58-45.gh-issue-106602.dGCcXe.rst b/Misc/NEWS.d/next/Library/2023-07-12-04-58-45.gh-issue-106602.dGCcXe.rst deleted file mode 100644 index d9c122f1d3c723..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-12-04-58-45.gh-issue-106602.dGCcXe.rst +++ /dev/null @@ -1 +0,0 @@ -Add __copy__ and __deepcopy__ in :mod:`enum` diff --git a/Misc/NEWS.d/next/Library/2023-07-13-16-04-15.gh-issue-105481.pYSwMj.rst b/Misc/NEWS.d/next/Library/2023-07-13-16-04-15.gh-issue-105481.pYSwMj.rst deleted file mode 100644 index bc2ba51d31aa9c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-13-16-04-15.gh-issue-105481.pYSwMj.rst +++ /dev/null @@ -1 +0,0 @@ -Expose opcode metadata through :mod:`_opcode`. diff --git a/Misc/NEWS.d/next/Library/2023-07-14-14-53-58.gh-issue-105293.kimf_i.rst b/Misc/NEWS.d/next/Library/2023-07-14-14-53-58.gh-issue-105293.kimf_i.rst deleted file mode 100644 index c263c8524aa962..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-14-14-53-58.gh-issue-105293.kimf_i.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove call to ``SSL_CTX_set_session_id_context`` during client side context -creation in the :mod:`ssl` module. diff --git a/Misc/NEWS.d/next/Library/2023-07-14-16-54-13.gh-issue-106752.BT1Yxw.rst b/Misc/NEWS.d/next/Library/2023-07-14-16-54-13.gh-issue-106752.BT1Yxw.rst deleted file mode 100644 index bbc53d76decbc3..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-14-16-54-13.gh-issue-106752.BT1Yxw.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fixed several bugs in zipfile.Path, including: in ``Path.match`, Windows -separators are no longer honored (and never were meant to be); Fixed -``name``/``suffix``/``suffixes``/``stem`` operations when no filename is -present and the Path is not at the root of the zipfile; Reworked glob for -performance and more correct matching behavior. diff --git a/Misc/NEWS.d/next/Library/2023-07-14-20-31-09.gh-issue-106751.52F6yQ.rst b/Misc/NEWS.d/next/Library/2023-07-14-20-31-09.gh-issue-106751.52F6yQ.rst deleted file mode 100644 index 486b1f9bbd0a97..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-14-20-31-09.gh-issue-106751.52F6yQ.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`selectors`: Optimize ``EpollSelector.select()`` code by moving some code outside of the loop. diff --git a/Misc/NEWS.d/next/Library/2023-07-15-12-52-50.gh-issue-105726.NGthO8.rst b/Misc/NEWS.d/next/Library/2023-07-15-12-52-50.gh-issue-105726.NGthO8.rst deleted file mode 100644 index 434f93240eccdf..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-15-12-52-50.gh-issue-105726.NGthO8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added ``__slots__`` to :class:`contextlib.AbstractContextManager` and :class:`contextlib.AbstractAsyncContextManager` -so that child classes can use ``__slots__``. - diff --git a/Misc/NEWS.d/next/Library/2023-07-16-10-40-34.gh-issue-106789.NvyE3C.rst b/Misc/NEWS.d/next/Library/2023-07-16-10-40-34.gh-issue-106789.NvyE3C.rst deleted file mode 100644 index 532f8059740daf..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-16-10-40-34.gh-issue-106789.NvyE3C.rst +++ /dev/null @@ -1 +0,0 @@ -Remove import of :mod:``pprint`` from :mod:``sysconfig``. diff --git a/Misc/NEWS.d/next/Library/2023-07-16-23-59-33.gh-issue-106727.bk3uCu.rst b/Misc/NEWS.d/next/Library/2023-07-16-23-59-33.gh-issue-106727.bk3uCu.rst deleted file mode 100644 index e4ea0ce1890d2f..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-16-23-59-33.gh-issue-106727.bk3uCu.rst +++ /dev/null @@ -1 +0,0 @@ -Make :func:`inspect.getsource` smarter for class for same name definitions diff --git a/Misc/NEWS.d/next/Library/2023-07-17-16-46-00.gh-issue-105481.fek_Nn.rst b/Misc/NEWS.d/next/Library/2023-07-17-16-46-00.gh-issue-105481.fek_Nn.rst deleted file mode 100644 index d82eb987c83e96..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-17-16-46-00.gh-issue-105481.fek_Nn.rst +++ /dev/null @@ -1 +0,0 @@ -The various opcode lists in the :mod:`dis` module are now generated from bytecodes.c instead of explicitly constructed in opcode.py. diff --git a/Misc/NEWS.d/next/Library/2023-07-17-21-45-15.gh-issue-106831.RqVq9X.rst b/Misc/NEWS.d/next/Library/2023-07-17-21-45-15.gh-issue-106831.RqVq9X.rst deleted file mode 100644 index d3b98626845392..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-17-21-45-15.gh-issue-106831.RqVq9X.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix potential missing ``NULL`` check of ``d2i_SSL_SESSION`` result in -``_ssl.c``. diff --git a/Misc/NEWS.d/next/Library/2023-07-18-23-05-12.gh-issue-106751.tVvzN_.rst b/Misc/NEWS.d/next/Library/2023-07-18-23-05-12.gh-issue-106751.tVvzN_.rst deleted file mode 100644 index 1cb8424b6221ee..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-18-23-05-12.gh-issue-106751.tVvzN_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize :meth:`KqueueSelector.select` for many iteration case. Patch By -Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2023-07-19-10-45-24.gh-issue-106751.3HJ1of.rst b/Misc/NEWS.d/next/Library/2023-07-19-10-45-24.gh-issue-106751.3HJ1of.rst deleted file mode 100644 index 2696b560371d13..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-19-10-45-24.gh-issue-106751.3HJ1of.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize :meth:`SelectSelector.select` for many iteration case. Patch By -Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2023-10-13-06-47-20.gh-issue-110771.opwdlc.rst b/Misc/NEWS.d/next/Library/2023-10-13-06-47-20.gh-issue-110771.opwdlc.rst new file mode 100644 index 00000000000000..a22f8a0d5e56c3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-13-06-47-20.gh-issue-110771.opwdlc.rst @@ -0,0 +1 @@ +Expose the setup and cleanup portions of ``asyncio.run_forever()`` as the standalone methods ``asyncio.run_forever_setup()`` and ``asyncio.run_forever_cleanup()``. This allows for tighter integration with GUI event loops. diff --git a/Misc/NEWS.d/next/Security/2023-05-24-09-29-08.gh-issue-99108.hwS2cr.rst b/Misc/NEWS.d/next/Security/2023-05-24-09-29-08.gh-issue-99108.hwS2cr.rst deleted file mode 100644 index 312ba89454b5b8..00000000000000 --- a/Misc/NEWS.d/next/Security/2023-05-24-09-29-08.gh-issue-99108.hwS2cr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Refresh our new HACL* built-in :mod:`hashlib` code from upstream. Built-in -SHA2 should be faster and an issue with SHA3 on 32-bit platforms is fixed. diff --git a/Misc/NEWS.d/next/Security/2023-06-01-03-24-58.gh-issue-103142.GLWDMX.rst b/Misc/NEWS.d/next/Security/2023-06-01-03-24-58.gh-issue-103142.GLWDMX.rst deleted file mode 100644 index 7e0836879e4f81..00000000000000 --- a/Misc/NEWS.d/next/Security/2023-06-01-03-24-58.gh-issue-103142.GLWDMX.rst +++ /dev/null @@ -1,2 +0,0 @@ -The version of OpenSSL used in our binary builds has been upgraded to 1.1.1u -to address several CVEs. diff --git a/Misc/NEWS.d/next/Security/2023-06-13-20-52-24.gh-issue-102988.Kei7Vf.rst b/Misc/NEWS.d/next/Security/2023-06-13-20-52-24.gh-issue-102988.Kei7Vf.rst deleted file mode 100644 index e0434ccd2ccab5..00000000000000 --- a/Misc/NEWS.d/next/Security/2023-06-13-20-52-24.gh-issue-102988.Kei7Vf.rst +++ /dev/null @@ -1,4 +0,0 @@ -CVE-2023-27043: Prevent :func:`email.utils.parseaddr` -and :func:`email.utils.getaddresses` from returning the realname portion of an -invalid RFC2822 email header in the email address portion of the 2-tuple -returned after being parsed by :class:`email._parseaddr.AddressList`. diff --git a/Misc/NEWS.d/next/Tests/2023-05-19-08-06-06.gh-issue-81005.-q7m9W.rst b/Misc/NEWS.d/next/Tests/2023-05-19-08-06-06.gh-issue-81005.-q7m9W.rst deleted file mode 100644 index dfb653241e2607..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-05-19-08-06-06.gh-issue-81005.-q7m9W.rst +++ /dev/null @@ -1,2 +0,0 @@ -String tests are modified to reflect that ``str`` and ``unicode`` are merged -in Python 3. Patch by Daniel Fortunov. diff --git a/Misc/NEWS.d/next/Tests/2023-05-29-14-49-46.gh-issue-105084.lvVvoj.rst b/Misc/NEWS.d/next/Tests/2023-05-29-14-49-46.gh-issue-105084.lvVvoj.rst deleted file mode 100644 index 5f80d507147347..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-05-29-14-49-46.gh-issue-105084.lvVvoj.rst +++ /dev/null @@ -1,3 +0,0 @@ -When the Python build is configured ``--with-wheel-pkg-dir``, tests -requiring the ``setuptools`` and ``wheel`` wheels will search for the wheels -in ``WHEEL_PKG_DIR``. diff --git a/Misc/NEWS.d/next/Tests/2023-06-28-02-51-08.gh-issue-101634.Rayczr.rst b/Misc/NEWS.d/next/Tests/2023-06-28-02-51-08.gh-issue-101634.Rayczr.rst deleted file mode 100644 index 6fbfc84c19e1b8..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-06-28-02-51-08.gh-issue-101634.Rayczr.rst +++ /dev/null @@ -1,3 +0,0 @@ -When running the Python test suite with ``-jN`` option, if a worker stdout -cannot be decoded from the locale encoding report a failed testn so the -exitcode is non-zero. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-07-12-14-07-07.gh-issue-106690.NDz-oG.rst b/Misc/NEWS.d/next/Tests/2023-07-12-14-07-07.gh-issue-106690.NDz-oG.rst deleted file mode 100644 index e7dc0ac2220502..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-07-12-14-07-07.gh-issue-106690.NDz-oG.rst +++ /dev/null @@ -1 +0,0 @@ -Add .coveragerc to cpython repository for use with coverage package. diff --git a/Misc/NEWS.d/next/Tests/2023-07-14-16-20-06.gh-issue-106752.gd1i6D.rst b/Misc/NEWS.d/next/Tests/2023-07-14-16-20-06.gh-issue-106752.gd1i6D.rst deleted file mode 100644 index ba7257e3610808..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-07-14-16-20-06.gh-issue-106752.gd1i6D.rst +++ /dev/null @@ -1,2 +0,0 @@ -Moved tests for ``zipfile.Path`` into ``Lib/test/test_zipfile/_path``. Made -``zipfile._path`` a package. diff --git a/Misc/NEWS.d/next/Tests/2023-07-16-02-57-08.gh-issue-104090.cKtK7g.rst b/Misc/NEWS.d/next/Tests/2023-07-16-02-57-08.gh-issue-104090.cKtK7g.rst deleted file mode 100644 index 5cc6c5bbe15446..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-07-16-02-57-08.gh-issue-104090.cKtK7g.rst +++ /dev/null @@ -1 +0,0 @@ -Avoid creating a reference to the test object in :meth:`~unittest.TestResult.collectedDurations`. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-04-05-07-19-36.gh-issue-103186.yEozgK.rst b/Misc/NEWS.d/next/Tools-Demos/2023-04-05-07-19-36.gh-issue-103186.yEozgK.rst deleted file mode 100644 index 7e28ba6963216a..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-04-05-07-19-36.gh-issue-103186.yEozgK.rst +++ /dev/null @@ -1,2 +0,0 @@ -``freeze`` now fetches ``CONFIG_ARGS`` from the original CPython instance -the Makefile uses to call utility scripts. Patch by Ijtaba Hussain. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-07-03-14-06-19.gh-issue-106359.RfJuR0.rst b/Misc/NEWS.d/next/Tools-Demos/2023-07-03-14-06-19.gh-issue-106359.RfJuR0.rst deleted file mode 100644 index 600c265391ec5b..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-07-03-14-06-19.gh-issue-106359.RfJuR0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Argument Clinic now explicitly forbids "kwarg splats" in function calls used as -annotations. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-07-13-12-08-35.gh-issue-106706.29zp8E.rst b/Misc/NEWS.d/next/Tools-Demos/2023-07-13-12-08-35.gh-issue-106706.29zp8E.rst deleted file mode 100644 index bbd8e8eddda607..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-07-13-12-08-35.gh-issue-106706.29zp8E.rst +++ /dev/null @@ -1,3 +0,0 @@ -Change bytecode syntax for families -to remove redundant name matching -pseudo syntax. diff --git a/Misc/NEWS.d/next/Windows/2023-05-23-19-26-28.gh-issue-104803.gqxYml.rst b/Misc/NEWS.d/next/Windows/2023-05-23-19-26-28.gh-issue-104803.gqxYml.rst deleted file mode 100644 index d2242c76189970..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-05-23-19-26-28.gh-issue-104803.gqxYml.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :func:`os.path.isdevdrive` to detect whether a path is on a Windows Dev -Drive. Returns ``False`` on platforms that do not support Dev Drive, and is -absent on non-Windows platforms. diff --git a/Misc/NEWS.d/next/Windows/2023-05-24-21-00-57.gh-issue-104820.ibyrpp.rst b/Misc/NEWS.d/next/Windows/2023-05-24-21-00-57.gh-issue-104820.ibyrpp.rst deleted file mode 100644 index 5bdfbabfaf28e1..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-05-24-21-00-57.gh-issue-104820.ibyrpp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes :func:`~os.stat` and related functions on file systems that do not -support file ID requests. This includes FAT32 and exFAT. diff --git a/Misc/NEWS.d/next/Windows/2023-05-29-11-38-53.gh-issue-88745.cldf9G.rst b/Misc/NEWS.d/next/Windows/2023-05-29-11-38-53.gh-issue-88745.cldf9G.rst deleted file mode 100644 index 258eb89d50d9f5..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-05-29-11-38-53.gh-issue-88745.cldf9G.rst +++ /dev/null @@ -1,3 +0,0 @@ -Improve performance of :func:`shutil.copy2` by using the operating system's -``CopyFile2`` function. This may result in subtle changes to metadata copied -along with some files, bringing them in line with normal OS behavior. diff --git a/Misc/NEWS.d/next/Windows/2023-05-29-17-09-31.gh-issue-103646.U8oGQx.rst b/Misc/NEWS.d/next/Windows/2023-05-29-17-09-31.gh-issue-103646.U8oGQx.rst deleted file mode 100644 index 71c1e7c6594cbf..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-05-29-17-09-31.gh-issue-103646.U8oGQx.rst +++ /dev/null @@ -1,5 +0,0 @@ -When installed from the Microsoft Store, ``pip`` no longer defaults to -per-user installs. However, as the install directory is unwritable, it -should automatically decide to do a per-user install anyway. This should -resolve issues when ``pip`` is passed an option that conflicts with -``--user``. diff --git a/Misc/NEWS.d/next/Windows/2023-05-31-16-14-31.gh-issue-105146.gNjqq8.rst b/Misc/NEWS.d/next/Windows/2023-05-31-16-14-31.gh-issue-105146.gNjqq8.rst deleted file mode 100644 index 1a5208bc898207..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-05-31-16-14-31.gh-issue-105146.gNjqq8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Updated the links at the end of the installer to point to Discourse rather -than the mailing lists. diff --git a/Misc/NEWS.d/next/Windows/2023-06-08-11-30-17.gh-issue-105436.1qlDxw.rst b/Misc/NEWS.d/next/Windows/2023-06-08-11-30-17.gh-issue-105436.1qlDxw.rst deleted file mode 100644 index 1e3f298096cdd6..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-06-08-11-30-17.gh-issue-105436.1qlDxw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure that an empty environment block is terminated by two null characters, -as is required by Windows. diff --git a/Misc/NEWS.d/next/Windows/2023-07-11-20-48-17.gh-issue-99079.CIMftz.rst b/Misc/NEWS.d/next/Windows/2023-07-11-20-48-17.gh-issue-99079.CIMftz.rst deleted file mode 100644 index 11f411be0f17c5..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-07-11-20-48-17.gh-issue-99079.CIMftz.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows build to use OpenSSL 3.0.9 diff --git a/Misc/NEWS.d/next/macOS/2023-05-30-23-30-46.gh-issue-103142.55lMXQ.rst b/Misc/NEWS.d/next/macOS/2023-05-30-23-30-46.gh-issue-103142.55lMXQ.rst deleted file mode 100644 index 1afd949d6a9f03..00000000000000 --- a/Misc/NEWS.d/next/macOS/2023-05-30-23-30-46.gh-issue-103142.55lMXQ.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use OpenSSL 1.1.1u. diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt index 5609928284d448..78201bfbd6741d 100644 --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -43,13 +43,9 @@ Py_TRACE_REFS Build option: ``./configure --with-trace-refs``. -Turn on heavy reference debugging. This is major surgery. Every PyObject grows -two more pointers, to maintain a doubly-linked list of all live heap-allocated -objects. Most built-in type objects are not in this list, as they're statically -allocated. - -Note that because the fundamental PyObject layout changes, Python modules -compiled with Py_TRACE_REFS are incompatible with modules compiled without it. +Turn on heavy reference debugging. This is major surgery. All live +heap-allocated objects are traced in a hash table. Most built-in type objects +are not in this list, as they're statically allocated. Special gimmicks: diff --git a/Misc/platform_triplet.c b/Misc/platform_triplet.c new file mode 100644 index 00000000000000..3307260544e8a6 --- /dev/null +++ b/Misc/platform_triplet.c @@ -0,0 +1,261 @@ +/* Detect platform triplet from builtin defines + * cc -E Misc/platform_triplet.c | grep '^PLATFORM_TRIPLET=' | tr -d ' ' + */ +#undef bfin +#undef cris +#undef fr30 +#undef linux +#undef hppa +#undef hpux +#undef i386 +#undef mips +#undef powerpc +#undef sparc +#undef unix +#if defined(__ANDROID__) + # Android is not a multiarch system. +#elif defined(__linux__) +/* + * BEGIN of Linux block + */ +// Detect libc (based on config.guess) +# include +# if defined(__UCLIBC__) +# error uclibc not supported +# elif defined(__dietlibc__) +# error dietlibc not supported +# elif defined(__GLIBC__) +# define LIBC gnu +# define LIBC_X32 gnux32 +# if defined(__ARM_PCS_VFP) +# define LIBC_ARM gnueabihf +# else +# define LIBC_ARM gnueabi +# endif +# if defined(__loongarch__) +# if defined(__loongarch_soft_float) +# define LIBC_LA gnusf +# elif defined(__loongarch_single_float) +# define LIBC_LA gnuf32 +# elif defined(__loongarch_double_float) +# define LIBC_LA gnu +# else +# error unknown loongarch floating-point base abi +# endif +# endif +# if defined(_MIPS_SIM) +# if defined(__mips_hard_float) +# if _MIPS_SIM == _ABIO32 +# define LIBC_MIPS gnu +# elif _MIPS_SIM == _ABIN32 +# define LIBC_MIPS gnuabin32 +# elif _MIPS_SIM == _ABI64 +# define LIBC_MIPS gnuabi64 +# else +# error unknown mips sim value +# endif +# else +# if _MIPS_SIM == _ABIO32 +# define LIBC_MIPS gnusf +# elif _MIPS_SIM == _ABIN32 +# define LIBC_MIPS gnuabin32sf +# elif _MIPS_SIM == _ABI64 +# define LIBC_MIPS gnuabi64sf +# else +# error unknown mips sim value +# endif +# endif +# endif +# if defined(__SPE__) +# define LIBC_PPC gnuspe +# else +# define LIBC_PPC gnu +# endif +# else +// Heuristic to detect musl libc +# include +# ifdef __DEFINED_va_list +# define LIBC musl +# define LIBC_X32 muslx32 +# if defined(__ARM_PCS_VFP) +# define LIBC_ARM musleabihf +# else +# define LIBC_ARM musleabi +# endif +# if defined(__loongarch__) +# if defined(__loongarch_soft_float) +# define LIBC_LA muslsf +# elif defined(__loongarch_single_float) +# define LIBC_LA muslf32 +# elif defined(__loongarch_double_float) +# define LIBC_LA musl +# else +# error unknown loongarch floating-point base abi +# endif +# endif +# if defined(_MIPS_SIM) +# if defined(__mips_hard_float) +# if _MIPS_SIM == _ABIO32 +# define LIBC_MIPS musl +# elif _MIPS_SIM == _ABIN32 +# define LIBC_MIPS musln32 +# elif _MIPS_SIM == _ABI64 +# define LIBC_MIPS musl +# else +# error unknown mips sim value +# endif +# else +# if _MIPS_SIM == _ABIO32 +# define LIBC_MIPS muslsf +# elif _MIPS_SIM == _ABIN32 +# define LIBC_MIPS musln32sf +# elif _MIPS_SIM == _ABI64 +# define LIBC_MIPS muslsf +# else +# error unknown mips sim value +# endif +# endif +# endif +# if defined(_SOFT_FLOAT) || defined(__NO_FPRS__) +# define LIBC_PPC muslsf +# else +# define LIBC_PPC musl +# endif +# else +# error unknown libc +# endif +# endif + +# if defined(__x86_64__) && defined(__LP64__) +PLATFORM_TRIPLET=x86_64-linux-LIBC +# elif defined(__x86_64__) && defined(__ILP32__) +PLATFORM_TRIPLET=x86_64-linux-LIBC_X32 +# elif defined(__i386__) +PLATFORM_TRIPLET=i386-linux-LIBC +# elif defined(__aarch64__) && defined(__AARCH64EL__) +# if defined(__ILP32__) +PLATFORM_TRIPLET=aarch64_ilp32-linux-LIBC +# else +PLATFORM_TRIPLET=aarch64-linux-LIBC +# endif +# elif defined(__aarch64__) && defined(__AARCH64EB__) +# if defined(__ILP32__) +PLATFORM_TRIPLET=aarch64_be_ilp32-linux-LIBC +# else +PLATFORM_TRIPLET=aarch64_be-linux-LIBC +# endif +# elif defined(__alpha__) +PLATFORM_TRIPLET=alpha-linux-LIBC +# elif defined(__ARM_EABI__) +# if defined(__ARMEL__) +PLATFORM_TRIPLET=arm-linux-LIBC_ARM +# else +PLATFORM_TRIPLET=armeb-linux-LIBC_ARM +# endif +# elif defined(__hppa__) +PLATFORM_TRIPLET=hppa-linux-LIBC +# elif defined(__ia64__) +PLATFORM_TRIPLET=ia64-linux-LIBC +# elif defined(__loongarch__) && defined(__loongarch_lp64) +PLATFORM_TRIPLET=loongarch64-linux-LIBC_LA +# elif defined(__m68k__) && !defined(__mcoldfire__) +PLATFORM_TRIPLET=m68k-linux-LIBC +# elif defined(__mips__) +# if defined(__mips_isa_rev) && (__mips_isa_rev >=6) +# if defined(_MIPSEL) && defined(__mips64) +PLATFORM_TRIPLET=mipsisa64r6el-linux-LIBC_MIPS +# elif defined(_MIPSEL) +PLATFORM_TRIPLET=mipsisa32r6el-linux-LIBC_MIPS +# elif defined(__mips64) +PLATFORM_TRIPLET=mipsisa64r6-linux-LIBC_MIPS +# else +PLATFORM_TRIPLET=mipsisa32r6-linux-LIBC_MIPS +# endif +# else +# if defined(_MIPSEL) && defined(__mips64) +PLATFORM_TRIPLET=mips64el-linux-LIBC_MIPS +# elif defined(_MIPSEL) +PLATFORM_TRIPLET=mipsel-linux-LIBC_MIPS +# elif defined(__mips64) +PLATFORM_TRIPLET=mips64-linux-LIBC_MIPS +# else +PLATFORM_TRIPLET=mips-linux-LIBC_MIPS +# endif +# endif +# elif defined(__or1k__) +PLATFORM_TRIPLET=or1k-linux-LIBC +# elif defined(__powerpc64__) +# if defined(__LITTLE_ENDIAN__) +PLATFORM_TRIPLET=powerpc64le-linux-LIBC +# else +PLATFORM_TRIPLET=powerpc64-linux-LIBC +# endif +# elif defined(__powerpc__) +PLATFORM_TRIPLET=powerpc-linux-LIBC_PPC +# elif defined(__s390x__) +PLATFORM_TRIPLET=s390x-linux-LIBC +# elif defined(__s390__) +PLATFORM_TRIPLET=s390-linux-LIBC +# elif defined(__sh__) && defined(__LITTLE_ENDIAN__) +PLATFORM_TRIPLET=sh4-linux-LIBC +# elif defined(__sparc__) && defined(__arch64__) +PLATFORM_TRIPLET=sparc64-linux-LIBC +# elif defined(__sparc__) +PLATFORM_TRIPLET=sparc-linux-LIBC +# elif defined(__riscv) +# if __riscv_xlen == 32 +PLATFORM_TRIPLET=riscv32-linux-LIBC +# elif __riscv_xlen == 64 +PLATFORM_TRIPLET=riscv64-linux-LIBC +# else +# error unknown platform triplet +# endif +# else +# error unknown platform triplet +# endif +/* + * END of Linux block + */ +#elif defined(__FreeBSD_kernel__) +# if defined(__LP64__) +PLATFORM_TRIPLET=x86_64-kfreebsd-gnu +# elif defined(__i386__) +PLATFORM_TRIPLET=i386-kfreebsd-gnu +# else +# error unknown platform triplet +# endif +#elif defined(__gnu_hurd__) +# if defined(__x86_64__) && defined(__LP64__) +PLATFORM_TRIPLET=x86_64-gnu +# elif defined(__i386__) +PLATFORM_TRIPLET=i386-gnu +# else +# error unknown platform triplet +# endif +#elif defined(__APPLE__) +PLATFORM_TRIPLET=darwin +#elif defined(__VXWORKS__) +PLATFORM_TRIPLET=vxworks +#elif defined(__wasm32__) +# if defined(__EMSCRIPTEN__) +PLATFORM_TRIPLET=wasm32-emscripten +# elif defined(__wasi__) +# if defined(_REENTRANT) +PLATFORM_TRIPLET=wasm32-wasi-threads +# else +PLATFORM_TRIPLET=wasm32-wasi +# endif +# else +# error unknown wasm32 platform +# endif +#elif defined(__wasm64__) +# if defined(__EMSCRIPTEN__) +PLATFORM_TRIPLET=wasm64-emscripten +# elif defined(__wasi__) +PLATFORM_TRIPLET=wasm64-wasi +# else +# error unknown wasm64 platform +# endif +#else +# error unknown platform triplet +#endif diff --git a/Misc/python.man b/Misc/python.man index bf7cf767d164a6..9f89c94adf5028 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -592,8 +592,8 @@ works on Mac OS X. .IP PYTHONUSERBASE Defines the user base directory, which is used to compute the path of the user .IR site-packages -directory and Distutils installation paths for -.IR "python setup\.py install \-\-user" . +directory and installation paths for +.IR "python \-m pip install \-\-user" . .IP PYTHONPROFILEIMPORTTIME If this environment variable is set to a non-empty string, Python will show how long each import takes. This is exactly equivalent to setting diff --git a/Misc/requirements-test.txt b/Misc/requirements-test.txt deleted file mode 100644 index 60e7ed20a3d510..00000000000000 --- a/Misc/requirements-test.txt +++ /dev/null @@ -1 +0,0 @@ -tzdata==2020.3 diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index dd2c9910b83ccb..9d66b92eb8edf0 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2446,3 +2446,23 @@ added = '3.13' [function.PyModule_Add] added = '3.13' +[function.PyDict_GetItemRef] + added = '3.13' +[function.PyDict_GetItemStringRef] + added = '3.13' +[function.PyLong_AsInt] + added = '3.13' +[function.PyObject_HasAttrWithError] + added = '3.13' +[function.PyObject_HasAttrStringWithError] + added = '3.13' +[function.PyMapping_HasKeyWithError] + added = '3.13' +[function.PyMapping_HasKeyStringWithError] + added = '3.13' +[function.Py_IsFinalizing] + added = '3.13' +[function.PyUnicode_EqualToUTF8] + added = '3.13' +[function.PyUnicode_EqualToUTF8AndSize] + added = '3.13' diff --git a/Modules/Setup b/Modules/Setup index 8676f9ddce4841..1367f0ef4fa54a 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -155,6 +155,7 @@ PYTHONPATH=$(COREPYTHONPATH) #math mathmodule.c #mmap mmapmodule.c #select selectmodule.c +#_sysconfig _sysconfig.c # XML #_elementtree _elementtree.c diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in index 8ef0f203a82a8e..cd12c1bd0df8f9 100644 --- a/Modules/Setup.bootstrap.in +++ b/Modules/Setup.bootstrap.in @@ -19,6 +19,7 @@ errno errnomodule.c _io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c itertools itertoolsmodule.c _sre _sre/sre.c +_sysconfig _sysconfig.c _thread _threadmodule.c time timemodule.c _typing _typingmodule.c diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 11a022e3d2044e..647f44280b9ea1 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -158,9 +158,10 @@ @MODULE_XXSUBTYPE_TRUE@xxsubtype xxsubtype.c @MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c -@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c -@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyos.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c +@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c +@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/pyos.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c @MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c +@MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c # Some testing modules MUST be built as shared libraries. *shared* diff --git a/Modules/_abc.c b/Modules/_abc.c index 8a3aa9cb88880f..9473905243d438 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -7,6 +7,7 @@ #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyType_GetSubclasses() #include "pycore_runtime.h" // _Py_ID() +#include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_typeobject.h" // _PyType_GetMRO() #include "pycore_weakref.h" // _PyWeakref_GET_REF() #include "clinic/_abc.c.h" diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index ef9f7f8902e09e..e911286660b56e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3,12 +3,13 @@ #endif #include "Python.h" +#include "pycore_dict.h" // _PyDict_GetItem_KnownHash() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_runtime_init.h" // _Py_ID() -#include "structmember.h" // PyMemberDef + #include // offsetof() @@ -529,7 +530,7 @@ future_init(FutureObj *fut, PyObject *loop) } if (is_true && !_Py_IsInterpreterFinalizing(_PyInterpreterState_GET())) { /* Only try to capture the traceback if the interpreter is not being - finalized. The original motivation to add a `_Py_IsFinalizing()` + finalized. The original motivation to add a `Py_IsFinalizing()` call was to prevent SIGSEGV when a Future is created in a __del__ method, which is called during the interpreter shutdown and the traceback module is already unloaded. @@ -815,7 +816,7 @@ FutureObj_clear(FutureObj *fut) Py_CLEAR(fut->fut_source_tb); Py_CLEAR(fut->fut_cancel_msg); Py_CLEAR(fut->fut_cancelled_exc); - _PyObject_ClearManagedDict((PyObject *)fut); + PyObject_ClearManagedDict((PyObject *)fut); return 0; } @@ -833,7 +834,7 @@ FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) Py_VISIT(fut->fut_source_tb); Py_VISIT(fut->fut_cancel_msg); Py_VISIT(fut->fut_cancelled_exc); - _PyObject_VisitManagedDict((PyObject *)fut, visit, arg); + PyObject_VisitManagedDict((PyObject *)fut, visit, arg); return 0; } @@ -1398,7 +1399,8 @@ FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored)) default: assert (0); } - return Py_XNewRef(ret); + assert(_Py_IsImmortal(ret)); + return ret; } static PyObject * @@ -2179,7 +2181,7 @@ TaskObj_traverse(TaskObj *task, visitproc visit, void *arg) Py_VISIT(fut->fut_source_tb); Py_VISIT(fut->fut_cancel_msg); Py_VISIT(fut->fut_cancelled_exc); - _PyObject_VisitManagedDict((PyObject *)fut, visit, arg); + PyObject_VisitManagedDict((PyObject *)fut, visit, arg); return 0; } diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 99b0f098cc2b27..869cbea78dd267 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_long.h" // _PyLong_UnsignedLong_Converter() PyDoc_STRVAR(py_blake2b_new__doc__, "blake2b(data=b\'\', /, *, digest_size=_blake2.blake2b.MAX_DIGEST_SIZE,\n" @@ -85,7 +85,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto skip_optional_kwonly; } if (fastargs[1]) { - digest_size = _PyLong_AsInt(fastargs[1]); + digest_size = PyLong_AsInt(fastargs[1]); if (digest_size == -1 && PyErr_Occurred()) { goto exit; } @@ -130,7 +130,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[5]) { - fanout = _PyLong_AsInt(fastargs[5]); + fanout = PyLong_AsInt(fastargs[5]); if (fanout == -1 && PyErr_Occurred()) { goto exit; } @@ -139,7 +139,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[6]) { - depth = _PyLong_AsInt(fastargs[6]); + depth = PyLong_AsInt(fastargs[6]); if (depth == -1 && PyErr_Occurred()) { goto exit; } @@ -164,7 +164,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[9]) { - node_depth = _PyLong_AsInt(fastargs[9]); + node_depth = PyLong_AsInt(fastargs[9]); if (node_depth == -1 && PyErr_Occurred()) { goto exit; } @@ -173,7 +173,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[10]) { - inner_size = _PyLong_AsInt(fastargs[10]); + inner_size = PyLong_AsInt(fastargs[10]); if (inner_size == -1 && PyErr_Occurred()) { goto exit; } @@ -276,4 +276,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=996b4fe396824797 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2ad807e0c83d8c25 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h index 9b821fbcd62cdb..affc203486b174 100644 --- a/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_long.h" // _PyLong_UnsignedLong_Converter() PyDoc_STRVAR(py_blake2s_new__doc__, "blake2s(data=b\'\', /, *, digest_size=_blake2.blake2s.MAX_DIGEST_SIZE,\n" @@ -85,7 +85,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto skip_optional_kwonly; } if (fastargs[1]) { - digest_size = _PyLong_AsInt(fastargs[1]); + digest_size = PyLong_AsInt(fastargs[1]); if (digest_size == -1 && PyErr_Occurred()) { goto exit; } @@ -130,7 +130,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[5]) { - fanout = _PyLong_AsInt(fastargs[5]); + fanout = PyLong_AsInt(fastargs[5]); if (fanout == -1 && PyErr_Occurred()) { goto exit; } @@ -139,7 +139,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[6]) { - depth = _PyLong_AsInt(fastargs[6]); + depth = PyLong_AsInt(fastargs[6]); if (depth == -1 && PyErr_Occurred()) { goto exit; } @@ -164,7 +164,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[9]) { - node_depth = _PyLong_AsInt(fastargs[9]); + node_depth = PyLong_AsInt(fastargs[9]); if (node_depth == -1 && PyErr_Occurred()) { goto exit; } @@ -173,7 +173,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } } if (fastargs[10]) { - inner_size = _PyLong_AsInt(fastargs[10]); + inner_size = PyLong_AsInt(fastargs[10]); if (inner_size == -1 && PyErr_Occurred()) { goto exit; } @@ -276,4 +276,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=bd0fb7639e450618 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=90ca2b52b8c40785 input=a9049054013a1b77]*/ diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index eeefe6034998c8..3d0d4ee5e79c2b 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -1,10 +1,14 @@ /* _bz2 - Low-level Python interface to libbzip2. */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" -#include "structmember.h" // PyMemberDef #include #include +#include // offsetof() // Blocks output buffer wrappers #include "pycore_blocks_output_buffer.h" @@ -112,7 +116,7 @@ typedef struct { typedef struct { PyObject_HEAD bz_stream bzs; - char eof; /* T_BOOL expects a char */ + char eof; /* Py_T_BOOL expects a char */ PyObject *unused_data; char needs_input; char *input_buffer; @@ -714,11 +718,11 @@ PyDoc_STRVAR(BZ2Decompressor_needs_input_doc, "True if more input is needed before more decompressed data can be produced."); static PyMemberDef BZ2Decompressor_members[] = { - {"eof", T_BOOL, offsetof(BZ2Decompressor, eof), - READONLY, BZ2Decompressor_eof__doc__}, - {"unused_data", T_OBJECT_EX, offsetof(BZ2Decompressor, unused_data), - READONLY, BZ2Decompressor_unused_data__doc__}, - {"needs_input", T_BOOL, offsetof(BZ2Decompressor, needs_input), READONLY, + {"eof", Py_T_BOOL, offsetof(BZ2Decompressor, eof), + Py_READONLY, BZ2Decompressor_eof__doc__}, + {"unused_data", Py_T_OBJECT_EX, offsetof(BZ2Decompressor, unused_data), + Py_READONLY, BZ2Decompressor_unused_data__doc__}, + {"needs_input", Py_T_BOOL, offsetof(BZ2Decompressor, needs_input), Py_READONLY, BZ2Decompressor_needs_input_doc}, {NULL} }; diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 9a81531bdffb16..c8cd53de5e2262 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1,9 +1,10 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_dict.h" // _PyDict_GetItem_KnownHash() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_typeobject.h" // _PyType_GetModuleState() -#include "structmember.h" // PyMemberDef + #include typedef struct { @@ -1630,7 +1631,7 @@ static PyMethodDef deque_methods[] = { }; static PyMemberDef deque_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(dequeobject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(dequeobject, weakreflist), Py_READONLY}, {NULL}, }; @@ -2054,7 +2055,7 @@ static PyMethodDef defdict_methods[] = { }; static PyMemberDef defdict_members[] = { - {"default_factory", T_OBJECT, + {"default_factory", _Py_T_OBJECT, offsetof(defdictobject, default_factory), 0, PyDoc_STR("Factory for default value called by __missing__().")}, {NULL} @@ -2466,7 +2467,7 @@ tuplegetter_repr(_tuplegetterobject *self) static PyMemberDef tuplegetter_members[] = { - {"__doc__", T_OBJECT, offsetof(_tuplegetterobject, doc), 0}, + {"__doc__", _Py_T_OBJECT, offsetof(_tuplegetterobject, doc), 0}, {0} }; diff --git a/Modules/_csv.c b/Modules/_csv.c index c36d9805a12841..9568334b8069c8 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -11,7 +11,8 @@ module instead. #define MODULE_VERSION "1.0" #include "Python.h" -#include "structmember.h" // PyMemberDef + +#include // offsetof() #include /*[clinic input] @@ -232,7 +233,7 @@ _set_int(const char *name, int *target, PyObject *src, int dflt) "\"%s\" must be an integer", name); return -1; } - value = _PyLong_AsInt(src); + value = PyLong_AsInt(src); if (value == -1 && PyErr_Occurred()) { return -1; } @@ -336,9 +337,9 @@ dialect_check_quoting(int quoting) #define D_OFF(x) offsetof(DialectObj, x) static struct PyMemberDef Dialect_memberlist[] = { - { "skipinitialspace", T_BOOL, D_OFF(skipinitialspace), READONLY }, - { "doublequote", T_BOOL, D_OFF(doublequote), READONLY }, - { "strict", T_BOOL, D_OFF(strict), READONLY }, + { "skipinitialspace", Py_T_BOOL, D_OFF(skipinitialspace), Py_READONLY }, + { "doublequote", Py_T_BOOL, D_OFF(doublequote), Py_READONLY }, + { "strict", Py_T_BOOL, D_OFF(strict), Py_READONLY }, { NULL } }; @@ -970,8 +971,8 @@ static struct PyMethodDef Reader_methods[] = { #define R_OFF(x) offsetof(ReaderObj, x) static struct PyMemberDef Reader_memberlist[] = { - { "dialect", T_OBJECT, R_OFF(dialect), READONLY }, - { "line_num", T_ULONG, R_OFF(line_num), READONLY }, + { "dialect", _Py_T_OBJECT, R_OFF(dialect), Py_READONLY }, + { "line_num", Py_T_ULONG, R_OFF(line_num), Py_READONLY }, { NULL } }; @@ -1364,7 +1365,7 @@ static struct PyMethodDef Writer_methods[] = { #define W_OFF(x) offsetof(WriterObj, x) static struct PyMemberDef Writer_memberlist[] = { - { "dialect", T_OBJECT, W_OFF(dialect), READONLY }, + { "dialect", _Py_T_OBJECT, W_OFF(dialect), Py_READONLY }, { NULL } }; diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 200fd36748c403..184af2132c2707 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -110,7 +110,8 @@ bytes(cdata) #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _Py_EnterRecursiveCall() -#include "structmember.h" // PyMemberDef +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() + #include #ifdef MS_WIN32 @@ -1728,9 +1729,9 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) Py_DECREF(as_parameter); return value; } - /* XXX better message */ - PyErr_SetString(PyExc_TypeError, - "wrong type"); + PyErr_Format(PyExc_TypeError, + "'%.200s' object cannot be interpreted " + "as ctypes.c_wchar_p", Py_TYPE(value)->tp_name); return NULL; } @@ -1792,9 +1793,9 @@ c_char_p_from_param(PyObject *type, PyObject *value) Py_DECREF(as_parameter); return value; } - /* XXX better message */ - PyErr_SetString(PyExc_TypeError, - "wrong type"); + PyErr_Format(PyExc_TypeError, + "'%.200s' object cannot be interpreted " + "as ctypes.c_char_p", Py_TYPE(value)->tp_name); return NULL; } @@ -1927,9 +1928,9 @@ c_void_p_from_param(PyObject *type, PyObject *value) Py_DECREF(as_parameter); return value; } - /* XXX better message */ - PyErr_SetString(PyExc_TypeError, - "wrong type"); + PyErr_Format(PyExc_TypeError, + "'%.200s' object cannot be interpreted " + "as ctypes.c_void_p", Py_TYPE(value)->tp_name); return NULL; } @@ -2759,14 +2760,14 @@ PyCData_dealloc(PyObject *self) } static PyMemberDef PyCData_members[] = { - { "_b_base_", T_OBJECT, - offsetof(CDataObject, b_base), READONLY, + { "_b_base_", _Py_T_OBJECT, + offsetof(CDataObject, b_base), Py_READONLY, "the base object" }, - { "_b_needsfree_", T_INT, - offsetof(CDataObject, b_needsfree), READONLY, + { "_b_needsfree_", Py_T_INT, + offsetof(CDataObject, b_needsfree), Py_READONLY, "whether the object owns the memory or not" }, - { "_objects", T_OBJECT, - offsetof(CDataObject, b_objects), READONLY, + { "_objects", _Py_T_OBJECT, + offsetof(CDataObject, b_objects), Py_READONLY, "internal objects tree (NEVER CHANGE THIS OBJECT!)"}, { NULL }, }; @@ -4793,6 +4794,16 @@ static PyMappingMethods Array_as_mapping = { Array_ass_subscript, }; +PyDoc_STRVAR(array_doc, +"Abstract base class for arrays.\n" +"\n" +"The recommended way to create concrete array types is by multiplying any\n" +"ctypes data type with a non-negative integer. Alternatively, you can subclass\n" +"this type and define _length_ and _type_ class variables. Array elements can\n" +"be read and written using standard subscript and slice accesses for slice\n" +"reads, the resulting object is not itself an Array." +); + PyTypeObject PyCArray_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes.Array", @@ -4813,8 +4824,8 @@ PyTypeObject PyCArray_Type = { 0, /* tp_getattro */ 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("XXX to be provided"), /* tp_doc */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + array_doc, /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 0d8ecce009a67a..1bd8fec97179e9 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -8,9 +8,9 @@ # include #endif -#include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_runtime.h" // _PyRuntime -#include "pycore_global_objects.h" // _Py_ID() +#include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() +#include "pycore_runtime.h" // _Py_ID() #include diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index b3831ae7119a56..fc08c42bd3574a 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -54,12 +54,17 @@ */ +/*[clinic input] +module _ctypes +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=476a19c49b31a75c]*/ + #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif #include "Python.h" -#include "structmember.h" // PyMemberDef + #include @@ -96,8 +101,11 @@ #define DONT_USE_SEH #endif -#include "pycore_runtime.h" // _PyRuntime -#include "pycore_global_objects.h" // _Py_ID() +#include "pycore_runtime.h" // _PyRuntime +#include "pycore_global_objects.h"// _Py_ID() +#include "pycore_traceback.h" // _PyTraceback_Add() + +#include "clinic/callproc.c.h" #define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem" @@ -581,8 +589,8 @@ PyCArg_repr(PyCArgObject *self) } static PyMemberDef PyCArgType_members[] = { - { "_obj", T_OBJECT, - offsetof(PyCArgObject, obj), READONLY, + { "_obj", _Py_T_OBJECT, + offsetof(PyCArgObject, obj), Py_READONLY, "the wrapped object" }, { NULL }, }; @@ -1893,8 +1901,22 @@ unpickle(PyObject *self, PyObject *args) return NULL; } +/*[clinic input] +_ctypes.POINTER as create_pointer_type + + type as cls: object + A ctypes type. + / + +Create and return a new ctypes pointer type. + +Pointer types are cached and reused internally, +so calling this function repeatedly is cheap. +[clinic start generated code]*/ + static PyObject * -POINTER(PyObject *self, PyObject *cls) +create_pointer_type(PyObject *module, PyObject *cls) +/*[clinic end generated code: output=98c3547ab6f4f40b input=3b81cff5ff9b9d5b]*/ { PyObject *result; PyTypeObject *typ; @@ -1944,8 +1966,22 @@ POINTER(PyObject *self, PyObject *cls) return result; } +/*[clinic input] +_ctypes.pointer as create_pointer_inst + + obj as arg: object + / + +Create a new pointer instance, pointing to 'obj'. + +The returned object is of the type POINTER(type(obj)). Note that if you +just want to pass a pointer to an object to a foreign function call, you +should use byref(obj) which is much faster. +[clinic start generated code]*/ + static PyObject * -pointer(PyObject *self, PyObject *arg) +create_pointer_inst(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=3b543bc9f0de2180 input=713685fdb4d9bc27]*/ { PyObject *result; PyObject *typ; @@ -1957,7 +1993,7 @@ pointer(PyObject *self, PyObject *arg) else if (PyErr_Occurred()) { return NULL; } - typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); + typ = create_pointer_type(NULL, (PyObject *)Py_TYPE(arg)); if (typ == NULL) return NULL; result = PyObject_CallOneArg(typ, arg); @@ -1997,8 +2033,8 @@ buffer_info(PyObject *self, PyObject *arg) PyMethodDef _ctypes_module_methods[] = { {"get_errno", get_errno, METH_NOARGS}, {"set_errno", set_errno, METH_VARARGS}, - {"POINTER", POINTER, METH_O }, - {"pointer", pointer, METH_O }, + CREATE_POINTER_TYPE_METHODDEF + CREATE_POINTER_INST_METHODDEF {"_unpickle", unpickle, METH_VARARGS }, {"buffer_info", buffer_info, METH_O, "Return buffer interface information"}, {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"}, diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 128506a9eed920..bfb40e5c5393fc 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -250,8 +250,8 @@ PyCField_get_size(PyObject *self, void *data) } static PyGetSetDef PyCField_getset[] = { - { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" }, - { "size", PyCField_get_size, NULL, "size in bytes of this field" }, + { "offset", PyCField_get_offset, NULL, PyDoc_STR("offset in bytes of this field") }, + { "size", PyCField_get_size, NULL, PyDoc_STR("size in bytes of this field") }, { NULL, NULL, NULL, NULL }, }; diff --git a/Modules/_ctypes/clinic/callproc.c.h b/Modules/_ctypes/clinic/callproc.c.h new file mode 100644 index 00000000000000..a787693ae67cd8 --- /dev/null +++ b/Modules/_ctypes/clinic/callproc.c.h @@ -0,0 +1,32 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(create_pointer_type__doc__, +"POINTER($module, type, /)\n" +"--\n" +"\n" +"Create and return a new ctypes pointer type.\n" +"\n" +" type\n" +" A ctypes type.\n" +"\n" +"Pointer types are cached and reused internally,\n" +"so calling this function repeatedly is cheap."); + +#define CREATE_POINTER_TYPE_METHODDEF \ + {"POINTER", (PyCFunction)create_pointer_type, METH_O, create_pointer_type__doc__}, + +PyDoc_STRVAR(create_pointer_inst__doc__, +"pointer($module, obj, /)\n" +"--\n" +"\n" +"Create a new pointer instance, pointing to \'obj\'.\n" +"\n" +"The returned object is of the type POINTER(type(obj)). Note that if you\n" +"just want to pass a pointer to an object to a foreign function call, you\n" +"should use byref(obj) which is much faster."); + +#define CREATE_POINTER_INST_METHODDEF \ + {"pointer", (PyCFunction)create_pointer_inst, METH_O, create_pointer_inst__doc__}, +/*[clinic end generated code: output=51b311ea369e5adf input=a9049054013a1b77]*/ diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 3a859322772ba7..bb4f8f21bd3f77 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -1,16 +1,17 @@ #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif + #include #include #ifdef MS_WIN32 -#include +# include #else -#include -#include -# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -# define MAP_ANONYMOUS MAP_ANON -# endif +# include +# include // sysconf() +# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif #endif #include "ctypes.h" diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 3348ebd6593d2f..6fbcf77a115371 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -9,6 +9,7 @@ #endif #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_dict.h" // _PyDict_SizeOf() #include #ifdef MS_WIN32 # include @@ -385,11 +386,11 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (fields == NULL) return 0; - if (PyObject_GetOptionalAttr(type, &_Py_ID(_swappedbytes_), &tmp) < 0) { + int rc = PyObject_HasAttrWithError(type, &_Py_ID(_swappedbytes_)); + if (rc < 0) { return -1; } - if (tmp) { - Py_DECREF(tmp); + if (rc) { big_endian = !PY_BIG_ENDIAN; } else { @@ -400,7 +401,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct return -1; } if (tmp) { - pack = _PyLong_AsInt(tmp); + pack = PyLong_AsInt(tmp); Py_DECREF(tmp); if (pack < 0) { if (!PyErr_Occurred() || diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 1f5afa6fcd898d..d339a8aa798361 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -3069,8 +3069,8 @@ _curses_getwin(PyObject *module, PyObject *file) } datalen = PyBytes_GET_SIZE(data); if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) { - Py_DECREF(data); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(data); goto error; } Py_DECREF(data); diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index b8cb0c012fd537..684a628806fbb5 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -15,7 +15,7 @@ #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_object.h" // _PyObject_Init() #include "datetime.h" -#include "structmember.h" // PyMemberDef + #include @@ -40,6 +40,27 @@ #define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType) +typedef struct { + /* Conversion factors. */ + PyObject *us_per_ms; // 1_000 + PyObject *us_per_second; // 1_000_000 + PyObject *us_per_minute; // 1e6 * 60 as Python int + PyObject *us_per_hour; // 1e6 * 3600 as Python int + PyObject *us_per_day; // 1e6 * 3600 * 24 as Python int + PyObject *us_per_week; // 1e6 * 3600 * 24 * 7 as Python int + PyObject *seconds_per_day; // 3600 * 24 as Python int + + /* The interned UTC timezone instance */ + PyObject *utc; + + /* The interned Unix epoch datetime instance */ + PyObject *epoch; +} datetime_state; + +static datetime_state _datetime_global_state; + +#define STATIC_STATE() (&_datetime_global_state) + /*[clinic input] module datetime class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" @@ -1139,11 +1160,6 @@ typedef struct PyObject *name; } PyDateTime_TimeZone; -/* The interned UTC timezone instance */ -static PyObject *PyDateTime_TimeZone_UTC; -/* The interned Epoch datetime instance */ -static PyObject *PyDateTime_Epoch; - /* Create new timezone instance checking offset range. This function does not check the name argument. Caller must assure that offset is a timedelta instance and name is either NULL @@ -1177,7 +1193,8 @@ new_timezone(PyObject *offset, PyObject *name) assert(name == NULL || PyUnicode_Check(name)); if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) { - return Py_NewRef(PyDateTime_TimeZone_UTC); + datetime_state *st = STATIC_STATE(); + return Py_NewRef(st->utc); } if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0 && @@ -1390,7 +1407,8 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) if (rv == 1) { // Create a timezone from offset in seconds (0 returns UTC) if (tzoffset == 0) { - return Py_NewRef(PyDateTime_TimeZone_UTC); + datetime_state *st = STATIC_STATE(); + return Py_NewRef(st->utc); } PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1); @@ -1807,19 +1825,6 @@ cmperror(PyObject *a, PyObject *b) return NULL; } -/* --------------------------------------------------------------------------- - * Cached Python objects; these are set by the module init function. - */ - -/* Conversion factors. */ -static PyObject *us_per_ms = NULL; /* 1000 */ -static PyObject *us_per_second = NULL; /* 1000000 */ -static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */ -static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */ -static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */ -static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */ -static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */ - /* --------------------------------------------------------------------------- * Class implementations. */ @@ -1845,7 +1850,8 @@ delta_to_microseconds(PyDateTime_Delta *self) x1 = PyLong_FromLong(GET_TD_DAYS(self)); if (x1 == NULL) goto Done; - x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */ + datetime_state *st = STATIC_STATE(); + x2 = PyNumber_Multiply(x1, st->seconds_per_day); /* days in seconds */ if (x2 == NULL) goto Done; Py_SETREF(x1, NULL); @@ -1862,7 +1868,7 @@ delta_to_microseconds(PyDateTime_Delta *self) /* x1 = */ x2 = NULL; /* x3 has days+seconds in seconds */ - x1 = PyNumber_Multiply(x3, us_per_second); /* us */ + x1 = PyNumber_Multiply(x3, st->us_per_second); /* us */ if (x1 == NULL) goto Done; Py_SETREF(x3, NULL); @@ -1917,13 +1923,14 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) PyObject *num = NULL; PyObject *result = NULL; - tuple = checked_divmod(pyus, us_per_second); + datetime_state *st = STATIC_STATE(); + tuple = checked_divmod(pyus, st->us_per_second); if (tuple == NULL) { goto Done; } num = PyTuple_GET_ITEM(tuple, 1); /* us */ - us = _PyLong_AsInt(num); + us = PyLong_AsInt(num); num = NULL; if (us == -1 && PyErr_Occurred()) { goto Done; @@ -1935,13 +1942,13 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0)); /* leftover seconds */ Py_DECREF(tuple); - tuple = checked_divmod(num, seconds_per_day); + tuple = checked_divmod(num, st->seconds_per_day); if (tuple == NULL) goto Done; Py_DECREF(num); num = PyTuple_GET_ITEM(tuple, 1); /* seconds */ - s = _PyLong_AsInt(num); + s = PyLong_AsInt(num); num = NULL; if (s == -1 && PyErr_Occurred()) { goto Done; @@ -1951,7 +1958,7 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) } num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0)); /* leftover days */ - d = _PyLong_AsInt(num); + d = PyLong_AsInt(num); if (d == -1 && PyErr_Occurred()) { goto Done; } @@ -2535,28 +2542,29 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us); CLEANUP; } + datetime_state *st = STATIC_STATE(); if (ms) { - y = accum("milliseconds", x, ms, us_per_ms, &leftover_us); + y = accum("milliseconds", x, ms, st->us_per_ms, &leftover_us); CLEANUP; } if (second) { - y = accum("seconds", x, second, us_per_second, &leftover_us); + y = accum("seconds", x, second, st->us_per_second, &leftover_us); CLEANUP; } if (minute) { - y = accum("minutes", x, minute, us_per_minute, &leftover_us); + y = accum("minutes", x, minute, st->us_per_minute, &leftover_us); CLEANUP; } if (hour) { - y = accum("hours", x, hour, us_per_hour, &leftover_us); + y = accum("hours", x, hour, st->us_per_hour, &leftover_us); CLEANUP; } if (day) { - y = accum("days", x, day, us_per_day, &leftover_us); + y = accum("days", x, day, st->us_per_day, &leftover_us); CLEANUP; } if (week) { - y = accum("weeks", x, week, us_per_week, &leftover_us); + y = accum("weeks", x, week, st->us_per_week, &leftover_us); CLEANUP; } if (leftover_us) { @@ -2711,7 +2719,8 @@ delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored)) if (total_microseconds == NULL) return NULL; - total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second); + datetime_state *st = STATIC_STATE(); + total_seconds = PyNumber_TrueDivide(total_microseconds, st->us_per_second); Py_DECREF(total_microseconds); return total_seconds; @@ -2727,13 +2736,13 @@ delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored)) static PyMemberDef delta_members[] = { - {"days", T_INT, OFFSET(days), READONLY, + {"days", Py_T_INT, OFFSET(days), Py_READONLY, PyDoc_STR("Number of days.")}, - {"seconds", T_INT, OFFSET(seconds), READONLY, + {"seconds", Py_T_INT, OFFSET(seconds), Py_READONLY, PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")}, - {"microseconds", T_INT, OFFSET(microseconds), READONLY, + {"microseconds", Py_T_INT, OFFSET(microseconds), Py_READONLY, PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")}, {NULL} }; @@ -3590,6 +3599,8 @@ static PyMethodDef date_methods[] = { {"replace", _PyCFunction_CAST(date_replace), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return date with new specified fields.")}, + {"__replace__", _PyCFunction_CAST(date_replace), METH_VARARGS | METH_KEYWORDS}, + {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, @@ -3941,8 +3952,10 @@ timezone_repr(PyDateTime_TimeZone *self) to use Py_TYPE(self)->tp_name here. */ const char *type_name = Py_TYPE(self)->tp_name; - if (((PyObject *)self) == PyDateTime_TimeZone_UTC) + datetime_state *st = STATIC_STATE(); + if (((PyObject *)self) == st->utc) { return PyUnicode_FromFormat("%s.utc", type_name); + } if (self->name == NULL) return PyUnicode_FromFormat("%s(%R)", type_name, self->offset); @@ -3962,11 +3975,14 @@ timezone_str(PyDateTime_TimeZone *self) if (self->name != NULL) { return Py_NewRef(self->name); } - if ((PyObject *)self == PyDateTime_TimeZone_UTC || + datetime_state *st = STATIC_STATE(); + if ((PyObject *)self == st->utc || (GET_TD_DAYS(self->offset) == 0 && GET_TD_SECONDS(self->offset) == 0 && GET_TD_MICROSECONDS(self->offset) == 0)) + { return PyUnicode_FromString("UTC"); + } /* Offset is normalized, so it is negative if days < 0 */ if (GET_TD_DAYS(self->offset) < 0) { sign = '-'; @@ -4719,6 +4735,8 @@ static PyMethodDef time_methods[] = { {"replace", _PyCFunction_CAST(time_replace), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return time with new specified fields.")}, + {"__replace__", _PyCFunction_CAST(time_replace), METH_VARARGS | METH_KEYWORDS}, + {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS, PyDoc_STR("string -> time from a string in ISO 8601 format")}, @@ -5136,9 +5154,9 @@ static PyObject * datetime_utcnow(PyObject *cls, PyObject *dummy) { if (PyErr_WarnEx(PyExc_DeprecationWarning, - "datetime.utcnow() is deprecated and scheduled for removal in a " + "datetime.datetime.utcnow() is deprecated and scheduled for removal in a " "future version. Use timezone-aware objects to represent datetimes " - "in UTC: datetime.now(datetime.UTC).", 1)) + "in UTC: datetime.datetime.now(datetime.UTC).", 1)) { return NULL; } @@ -5179,9 +5197,9 @@ static PyObject * datetime_utcfromtimestamp(PyObject *cls, PyObject *args) { if (PyErr_WarnEx(PyExc_DeprecationWarning, - "datetime.utcfromtimestamp() is deprecated and scheduled for removal " + "datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal " "in a future version. Use timezone-aware objects to represent " - "datetimes in UTC: datetime.fromtimestamp(timestamp, datetime.UTC).", 1)) + "datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).", 1)) { return NULL; } @@ -6130,7 +6148,8 @@ local_timezone(PyDateTime_DateTime *utc_time) PyObject *one_second; PyObject *seconds; - delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch); + datetime_state *st = STATIC_STATE(); + delta = datetime_subtract((PyObject *)utc_time, st->epoch); if (delta == NULL) return NULL; one_second = new_delta(0, 1, 0, 0); @@ -6242,6 +6261,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) if (result == NULL) return NULL; + datetime_state *st = STATIC_STATE(); /* Make sure result is aware and UTC. */ if (!HASTZINFO(result)) { temp = (PyObject *)result; @@ -6253,7 +6273,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) DATE_GET_MINUTE(result), DATE_GET_SECOND(result), DATE_GET_MICROSECOND(result), - PyDateTime_TimeZone_UTC, + st->utc, DATE_GET_FOLD(result), Py_TYPE(result)); Py_DECREF(temp); @@ -6262,7 +6282,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } else { /* Result is already aware - just replace tzinfo. */ - Py_SETREF(result->tzinfo, Py_NewRef(PyDateTime_TimeZone_UTC)); + Py_SETREF(result->tzinfo, Py_NewRef(st->utc)); } /* Attach new tzinfo and let fromutc() do the rest. */ @@ -6366,8 +6386,9 @@ datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) PyObject *result; if (HASTZINFO(self) && self->tzinfo != Py_None) { + datetime_state *st = STATIC_STATE(); PyObject *delta; - delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch); + delta = datetime_subtract((PyObject *)self, st->epoch); if (delta == NULL) return NULL; result = delta_total_seconds(delta, NULL); @@ -6579,6 +6600,8 @@ static PyMethodDef datetime_methods[] = { {"replace", _PyCFunction_CAST(datetime_replace), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return datetime with new specified fields.")}, + {"__replace__", _PyCFunction_CAST(datetime_replace), METH_VARARGS | METH_KEYWORDS}, + {"astimezone", _PyCFunction_CAST(datetime_astimezone), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, @@ -6686,10 +6709,11 @@ get_datetime_capi(void) capi->Date_FromTimestamp = datetime_date_fromtimestamp_capi; capi->DateTime_FromDateAndTimeAndFold = new_datetime_ex2; capi->Time_FromTimeAndFold = new_time_ex2; - // Make sure this function is called after PyDateTime_TimeZone_UTC has + // Make sure this function is called after utc has // been initialized. - assert(PyDateTime_TimeZone_UTC != NULL); - capi->TimeZone_UTC = PyDateTime_TimeZone_UTC; // borrowed ref + datetime_state *st = STATIC_STATE(); + assert(st->utc != NULL); + capi->TimeZone_UTC = st->utc; // borrowed ref return capi; } @@ -6700,6 +6724,85 @@ datetime_destructor(PyObject *op) PyMem_Free(ptr); } +static int +datetime_clear(PyObject *module) +{ + datetime_state *st = STATIC_STATE(); + + Py_CLEAR(st->us_per_ms); + Py_CLEAR(st->us_per_second); + Py_CLEAR(st->us_per_minute); + Py_CLEAR(st->us_per_hour); + Py_CLEAR(st->us_per_day); + Py_CLEAR(st->us_per_week); + Py_CLEAR(st->seconds_per_day); + Py_CLEAR(st->utc); + Py_CLEAR(st->epoch); + return 0; +} + +static PyObject * +create_timezone_from_delta(int days, int sec, int ms, int normalize) +{ + PyObject *delta = new_delta(days, sec, ms, normalize); + if (delta == NULL) { + return NULL; + } + PyObject *tz = create_timezone(delta, NULL); + Py_DECREF(delta); + return tz; +} + +static int +init_state(datetime_state *st) +{ + st->us_per_ms = PyLong_FromLong(1000); + if (st->us_per_ms == NULL) { + return -1; + } + st->us_per_second = PyLong_FromLong(1000000); + if (st->us_per_second == NULL) { + return -1; + } + st->us_per_minute = PyLong_FromLong(60000000); + if (st->us_per_minute == NULL) { + return -1; + } + st->seconds_per_day = PyLong_FromLong(24 * 3600); + if (st->seconds_per_day == NULL) { + return -1; + } + + /* The rest are too big for 32-bit ints, but even + * us_per_week fits in 40 bits, so doubles should be exact. + */ + st->us_per_hour = PyLong_FromDouble(3600000000.0); + if (st->us_per_hour == NULL) { + return -1; + } + st->us_per_day = PyLong_FromDouble(86400000000.0); + if (st->us_per_day == NULL) { + return -1; + } + st->us_per_week = PyLong_FromDouble(604800000000.0); + if (st->us_per_week == NULL) { + return -1; + } + + /* Init UTC timezone */ + st->utc = create_timezone_from_delta(0, 0, 0, 0); + if (st->utc == NULL) { + return -1; + } + + /* Init Unix epoch */ + st->epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, st->utc, 0); + if (st->epoch == NULL) { + return -1; + } + return 0; +} + static int _datetime_exec(PyObject *module) { @@ -6721,23 +6824,23 @@ _datetime_exec(PyObject *module) for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { if (PyModule_AddType(module, types[i]) < 0) { - return -1; + goto error; } } if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) { - return -1; + goto error; } #define DATETIME_ADD_MACRO(dict, c, value_expr) \ do { \ PyObject *value = (value_expr); \ if (value == NULL) { \ - return -1; \ + goto error; \ } \ if (PyDict_SetItemString(dict, c, value) < 0) { \ Py_DECREF(value); \ - return -1; \ + goto error; \ } \ Py_DECREF(value); \ } while(0) @@ -6769,78 +6872,54 @@ _datetime_exec(PyObject *module) 999999, Py_None, 0)); DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); - /* timezone values */ - d = PyDateTime_TimeZoneType.tp_dict; - PyObject *delta = new_delta(0, 0, 0, 0); - if (delta == NULL) { - return -1; + datetime_state *st = STATIC_STATE(); + if (init_state(st) < 0) { + goto error; } - PyObject *x = create_timezone(delta, NULL); - Py_DECREF(delta); - if (x == NULL) { - return -1; - } - if (PyDict_SetItemString(d, "utc", x) < 0) { - Py_DECREF(x); - return -1; + /* timezone values */ + d = PyDateTime_TimeZoneType.tp_dict; + if (PyDict_SetItemString(d, "utc", st->utc) < 0) { + goto error; } - PyDateTime_TimeZone_UTC = x; - /* 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 -1; - } - - x = create_timezone(delta, NULL); - Py_DECREF(delta); - DATETIME_ADD_MACRO(d, "min", x); - - delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */ - if (delta == NULL) { - return -1; - } - x = create_timezone(delta, NULL); - Py_DECREF(delta); - DATETIME_ADD_MACRO(d, "max", x); + /* -23:59 */ + PyObject *min = create_timezone_from_delta(-1, 60, 0, 1); + DATETIME_ADD_MACRO(d, "min", min); - /* Epoch */ - PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, - PyDateTime_TimeZone_UTC, 0); - if (PyDateTime_Epoch == NULL) { - return -1; - } + /* +23:59 */ + PyObject *max = create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0); + DATETIME_ADD_MACRO(d, "max", max); - /* module initialization */ + /* Add module level attributes */ if (PyModule_AddIntMacro(module, MINYEAR) < 0) { - return -1; + goto error; } if (PyModule_AddIntMacro(module, MAXYEAR) < 0) { - return -1; + goto error; + } + if (PyModule_AddObjectRef(module, "UTC", st->utc) < 0) { + goto error; } + /* At last, set up and add the encapsulated C API */ PyDateTime_CAPI *capi = get_datetime_capi(); if (capi == NULL) { - return -1; + goto error; } - x = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, datetime_destructor); - if (x == NULL) { + PyObject *capsule = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, + datetime_destructor); + if (capsule == NULL) { PyMem_Free(capi); - return -1; - } - - if (PyModule_AddObject(module, "datetime_CAPI", x) < 0) { - Py_DECREF(x); - return -1; + goto error; } - - if (PyModule_AddObjectRef(module, "UTC", PyDateTime_TimeZone_UTC) < 0) { - return -1; + if (PyModule_Add(module, "datetime_CAPI", capsule) < 0) { + PyMem_Free(capi); + goto error; } /* A 4-year cycle has an extra leap day over what we'd get from @@ -6861,54 +6940,16 @@ _datetime_exec(PyObject *module) static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y"); assert(DI100Y == days_before_year(100+1)); - us_per_ms = PyLong_FromLong(1000); - if (us_per_ms == NULL) { - goto error; - } - us_per_second = PyLong_FromLong(1000000); - if (us_per_second == NULL) { - goto error; - } - us_per_minute = PyLong_FromLong(60000000); - if (us_per_minute == NULL) { - goto error; - } - seconds_per_day = PyLong_FromLong(24 * 3600); - if (seconds_per_day == NULL) { - goto error; - } - - /* The rest are too big for 32-bit ints, but even - * us_per_week fits in 40 bits, so doubles should be exact. - */ - us_per_hour = PyLong_FromDouble(3600000000.0); - if (us_per_hour == NULL) { - goto error; - } - us_per_day = PyLong_FromDouble(86400000000.0); - if (us_per_day == NULL) { - goto error; - } - us_per_week = PyLong_FromDouble(604800000000.0); - if (us_per_week == NULL) { - goto error; - } - return 0; error: - Py_XDECREF(us_per_ms); - Py_XDECREF(us_per_second); - Py_XDECREF(us_per_minute); - Py_XDECREF(us_per_hour); - Py_XDECREF(us_per_day); - Py_XDECREF(us_per_week); - Py_XDECREF(seconds_per_day); + datetime_clear(module); return -1; } +#undef DATETIME_ADD_MACRO static struct PyModuleDef datetimemodule = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "_datetime", .m_doc = "Fast implementation of the datetime type.", .m_size = -1, diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 5be444d53e8da3..bd807698927e86 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -414,6 +414,38 @@ _dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key, return default_value; } +/*[clinic input] +_dbm.dbm.clear + cls: defining_class + / +Remove all items from the database. + +[clinic start generated code]*/ + +static PyObject * +_dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=8d126b9e1d01a434 input=43aa6ca1acb7f5f5]*/ +{ + _dbm_state *state = PyType_GetModuleState(cls); + assert(state != NULL); + check_dbmobject_open(self, state->dbm_error); + datum key; + // Invalidate cache + self->di_size = -1; + while (1) { + key = dbm_firstkey(self->di_dbm); + if (key.dptr == NULL) { + break; + } + if (dbm_delete(self->di_dbm, key) < 0) { + dbm_clearerr(self->di_dbm); + PyErr_SetString(state->dbm_error, "cannot delete item from database"); + return NULL; + } + } + Py_RETURN_NONE; +} + static PyObject * dbm__enter__(PyObject *self, PyObject *args) { @@ -431,6 +463,7 @@ static PyMethodDef dbm_methods[] = { _DBM_DBM_KEYS_METHODDEF _DBM_DBM_GET_METHODDEF _DBM_DBM_SETDEFAULT_METHODDEF + _DBM_DBM_CLEAR_METHODDEF {"__enter__", dbm__enter__, METH_NOARGS, NULL}, {"__exit__", dbm__exit__, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index f9dc6e875fa5fc..8b93f8e2cbcf0b 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -35,6 +35,7 @@ #include "complexobject.h" #include "mpdecimal.h" +#include // isascii() #include #include "docstrings.h" @@ -46,6 +47,7 @@ #endif struct PyDecContextObject; +struct DecCondMap; typedef struct { PyTypeObject *PyDecContextManager_Type; @@ -82,6 +84,9 @@ typedef struct { PyObject *SignalTuple; + struct DecCondMap *signal_map; + struct DecCondMap *cond_map; + /* External C-API functions */ binaryfunc _py_long_multiply; binaryfunc _py_long_floor_divide; @@ -91,9 +96,36 @@ typedef struct { PyCFunction _py_float_as_integer_ratio; } decimal_state; -static decimal_state global_state; +static inline decimal_state * +get_module_state(PyObject *mod) +{ + decimal_state *state = _PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static struct PyModuleDef _decimal_module; + +static inline decimal_state * +get_module_state_by_def(PyTypeObject *tp) +{ + PyObject *mod = PyType_GetModuleByDef(tp, &_decimal_module); + assert(mod != NULL); + return get_module_state(mod); +} + +static inline decimal_state * +find_state_left_or_right(PyObject *left, PyObject *right) +{ + PyObject *mod = PyType_GetModuleByDef(Py_TYPE(left), &_decimal_module); + if (mod == NULL) { + PyErr_Clear(); + mod = PyType_GetModuleByDef(Py_TYPE(right), &_decimal_module); + } + assert(mod != NULL); + return get_module_state(mod); +} -#define GLOBAL_STATE() (&global_state) #if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02050000 #error "libmpdec version >= 2.5.0 required" @@ -181,7 +213,7 @@ incr_false(void) #define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1) #define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED) -typedef struct { +typedef struct DecCondMap { const char *name; /* condition or signal name */ const char *fqname; /* fully qualified name */ uint32_t flag; /* libmpdec flag */ @@ -193,7 +225,7 @@ typedef struct { #define INEXACT 6 #define ROUNDED 7 #define SIGNAL_MAP_LEN 9 -static DecCondMap signal_map[] = { +static DecCondMap signal_map_template[] = { {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL}, {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL}, {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL}, @@ -207,7 +239,7 @@ static DecCondMap signal_map[] = { }; /* Exceptions that inherit from InvalidOperation */ -static DecCondMap cond_map[] = { +static DecCondMap cond_map_template[] = { {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL}, {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL}, {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL}, @@ -219,6 +251,21 @@ static DecCondMap cond_map[] = { {NULL} }; +/* Return a duplicate of DecCondMap template */ +static inline DecCondMap * +dec_cond_map_init(DecCondMap *template, Py_ssize_t size) +{ + DecCondMap *cm; + cm = PyMem_Malloc(size); + if (cm == NULL) { + PyErr_NoMemory(); + return NULL; + } + + memcpy(cm, template, size); + return cm; +} + static const char *dec_signal_string[MPD_NUM_FLAGS] = { "Clamped", "InvalidOperation", @@ -268,14 +315,12 @@ value_error_int(const char *mesg) return -1; } -#ifdef CONFIG_32 static PyObject * value_error_ptr(const char *mesg) { PyErr_SetString(PyExc_ValueError, mesg); return NULL; } -#endif static int type_error_int(const char *mesg) @@ -309,11 +354,11 @@ dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */ } static PyObject * -flags_as_exception(uint32_t flags) +flags_as_exception(decimal_state *state, uint32_t flags) { DecCondMap *cm; - for (cm = signal_map; cm->name != NULL; cm++) { + for (cm = state->signal_map; cm->name != NULL; cm++) { if (flags&cm->flag) { return cm->ex; } @@ -323,11 +368,11 @@ flags_as_exception(uint32_t flags) } Py_LOCAL_INLINE(uint32_t) -exception_as_flag(PyObject *ex) +exception_as_flag(decimal_state *state, PyObject *ex) { DecCondMap *cm; - for (cm = signal_map; cm->name != NULL; cm++) { + for (cm = state->signal_map; cm->name != NULL; cm++) { if (cm->ex == ex) { return cm->flag; } @@ -338,7 +383,7 @@ exception_as_flag(PyObject *ex) } static PyObject * -flags_as_list(uint32_t flags) +flags_as_list(decimal_state *state, uint32_t flags) { PyObject *list; DecCondMap *cm; @@ -348,14 +393,14 @@ flags_as_list(uint32_t flags) return NULL; } - for (cm = cond_map; cm->name != NULL; cm++) { + for (cm = state->cond_map; cm->name != NULL; cm++) { if (flags&cm->flag) { if (PyList_Append(list, cm->ex) < 0) { goto error; } } } - for (cm = signal_map+1; cm->name != NULL; cm++) { + for (cm = state->signal_map+1; cm->name != NULL; cm++) { if (flags&cm->flag) { if (PyList_Append(list, cm->ex) < 0) { goto error; @@ -371,7 +416,7 @@ flags_as_list(uint32_t flags) } static PyObject * -signals_as_list(uint32_t flags) +signals_as_list(decimal_state *state, uint32_t flags) { PyObject *list; DecCondMap *cm; @@ -381,7 +426,7 @@ signals_as_list(uint32_t flags) return NULL; } - for (cm = signal_map; cm->name != NULL; cm++) { + for (cm = state->signal_map; cm->name != NULL; cm++) { if (flags&cm->flag) { if (PyList_Append(list, cm->ex) < 0) { Py_DECREF(list); @@ -394,7 +439,7 @@ signals_as_list(uint32_t flags) } static uint32_t -list_as_flags(PyObject *list) +list_as_flags(decimal_state *state, PyObject *list) { PyObject *item; uint32_t flags, x; @@ -406,7 +451,7 @@ list_as_flags(PyObject *list) flags = 0; for (j = 0; j < n; j++) { item = PyList_GetItem(list, j); - x = exception_as_flag(item); + x = exception_as_flag(state, item); if (x & DEC_ERRORS) { return x; } @@ -417,7 +462,7 @@ list_as_flags(PyObject *list) } static PyObject * -flags_as_dict(uint32_t flags) +flags_as_dict(decimal_state *state, uint32_t flags) { DecCondMap *cm; PyObject *dict; @@ -427,7 +472,7 @@ flags_as_dict(uint32_t flags) return NULL; } - for (cm = signal_map; cm->name != NULL; cm++) { + for (cm = state->signal_map; cm->name != NULL; cm++) { PyObject *b = flags&cm->flag ? Py_True : Py_False; if (PyDict_SetItem(dict, cm->ex, b) < 0) { Py_DECREF(dict); @@ -439,7 +484,7 @@ flags_as_dict(uint32_t flags) } static uint32_t -dict_as_flags(PyObject *val) +dict_as_flags(decimal_state *state, PyObject *val) { PyObject *b; DecCondMap *cm; @@ -458,7 +503,7 @@ dict_as_flags(PyObject *val) return DEC_INVALID_SIGNALS; } - for (cm = signal_map; cm->name != NULL; cm++) { + for (cm = state->signal_map; cm->name != NULL; cm++) { b = PyDict_GetItemWithError(val, cm->ex); if (b == NULL) { if (PyErr_Occurred()) { @@ -504,6 +549,7 @@ static int dec_addstatus(PyObject *context, uint32_t status) { mpd_context_t *ctx = CTX(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); ctx->status |= status; if (status & (ctx->traps|MPD_Malloc_error)) { @@ -514,11 +560,11 @@ dec_addstatus(PyObject *context, uint32_t status) return 1; } - ex = flags_as_exception(ctx->traps&status); + ex = flags_as_exception(state, ctx->traps&status); if (ex == NULL) { return 1; /* GCOV_NOT_REACHED */ } - siglist = flags_as_list(ctx->traps&status); + siglist = flags_as_list(state, ctx->traps&status); if (siglist == NULL) { return 1; } @@ -531,11 +577,9 @@ dec_addstatus(PyObject *context, uint32_t status) } static int -getround(PyObject *v) +getround(decimal_state *state, PyObject *v) { int i; - decimal_state *state = GLOBAL_STATE(); - if (PyUnicode_Check(v)) { for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { if (v == state->round_map[i]) { @@ -563,6 +607,8 @@ getround(PyObject *v) initialized to new SignalDicts. Once a SignalDict is tied to a context, it cannot be deleted. */ +static const char *INVALID_SIGNALDICT_ERROR_MSG = "invalid signal dict"; + static int signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) { @@ -571,15 +617,21 @@ signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) } static Py_ssize_t -signaldict_len(PyObject *self UNUSED) +signaldict_len(PyObject *self) { + if (SdFlagAddr(self) == NULL) { + return value_error_int(INVALID_SIGNALDICT_ERROR_MSG); + } return SIGNAL_MAP_LEN; } static PyObject * -signaldict_iter(PyObject *self UNUSED) +signaldict_iter(PyObject *self) { - decimal_state *state = GLOBAL_STATE(); + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); return PyTuple_Type.tp_iter(state->SignalTuple); } @@ -587,8 +639,12 @@ static PyObject * signaldict_getitem(PyObject *self, PyObject *key) { uint32_t flag; + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); - flag = exception_as_flag(key); + flag = exception_as_flag(state, key); if (flag & DEC_ERRORS) { return NULL; } @@ -602,11 +658,16 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value) uint32_t flag; int x; + if (SdFlagAddr(self) == NULL) { + return value_error_int(INVALID_SIGNALDICT_ERROR_MSG); + } + if (value == NULL) { return value_error_int("signal keys cannot be deleted"); } - flag = exception_as_flag(key); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + flag = exception_as_flag(state, key); if (flag & DEC_ERRORS) { return -1; } @@ -650,9 +711,14 @@ signaldict_repr(PyObject *self) const char *b[SIGNAL_MAP_LEN]; /* bool */ int i; + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + assert(SIGNAL_MAP_LEN == 9); - for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) { + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + for (cm=state->signal_map, i=0; cm->name != NULL; cm++, i++) { n[i] = cm->fqname; b[i] = SdFlags(self)&cm->flag ? "True" : "False"; } @@ -670,15 +736,19 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) { PyObject *res = Py_NotImplemented; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = find_state_left_or_right(v, w); assert(PyDecSignalDict_Check(state, v)); + if ((SdFlagAddr(v) == NULL) || (SdFlagAddr(w) == NULL)) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + if (op == Py_EQ || op == Py_NE) { if (PyDecSignalDict_Check(state, w)) { res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False; } else if (PyDict_Check(w)) { - uint32_t flags = dict_as_flags(w); + uint32_t flags = dict_as_flags(state, w); if (flags & DEC_ERRORS) { if (flags & DEC_INVALID_SIGNALS) { /* non-comparable: Py_NotImplemented */ @@ -700,7 +770,11 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) static PyObject * signaldict_copy(PyObject *self, PyObject *args UNUSED) { - return flags_as_dict(SdFlags(self)); + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + return flags_as_dict(state, SdFlags(self)); } @@ -769,7 +843,7 @@ static PyObject * context_getround(PyObject *self, void *closure UNUSED) { int i = mpd_getround(CTX(self)); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); return Py_NewRef(state->round_map[i]); } @@ -928,7 +1002,8 @@ context_setround(PyObject *self, PyObject *value, void *closure UNUSED) mpd_context_t *ctx; int x; - x = getround(value); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + x = getround(state, value); if (x == -1) { return -1; } @@ -986,8 +1061,8 @@ context_settraps_list(PyObject *self, PyObject *value) { mpd_context_t *ctx; uint32_t flags; - - flags = list_as_flags(value); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + flags = list_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1006,12 +1081,12 @@ context_settraps_dict(PyObject *self, PyObject *value) mpd_context_t *ctx; uint32_t flags; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if (PyDecSignalDict_Check(state, value)) { flags = SdFlags(value); } else { - flags = dict_as_flags(value); + flags = dict_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1051,8 +1126,9 @@ context_setstatus_list(PyObject *self, PyObject *value) { mpd_context_t *ctx; uint32_t flags; + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); - flags = list_as_flags(value); + flags = list_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1071,12 +1147,12 @@ context_setstatus_dict(PyObject *self, PyObject *value) mpd_context_t *ctx; uint32_t flags; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if (PyDecSignalDict_Check(state, value)) { flags = SdFlags(value); } else { - flags = dict_as_flags(value); + flags = dict_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1262,7 +1338,7 @@ context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED) PyDecContextObject *self = NULL; mpd_context_t *ctx; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (type == state->PyDecContext_Type) { self = PyObject_GC_New(PyDecContextObject, state->PyDecContext_Type); } @@ -1327,7 +1403,7 @@ context_dealloc(PyDecContextObject *self) PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); #ifndef WITH_DECIMAL_CONTEXTVAR - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if (self == state->cached_context) { state->cached_context = NULL; } @@ -1379,7 +1455,7 @@ context_repr(PyDecContextObject *self) int n, mem; #ifdef Py_DEBUG - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); assert(PyDecContext_Check(state, self)); #endif ctx = CTX(self); @@ -1447,7 +1523,7 @@ ieee_context(PyObject *dummy UNUSED, PyObject *v) goto error; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(v)); context = PyObject_CallObject((PyObject *)state->PyDecContext_Type, NULL); if (context == NULL) { return NULL; @@ -1470,7 +1546,7 @@ context_copy(PyObject *self, PyObject *args UNUSED) { PyObject *copy; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); copy = PyObject_CallObject((PyObject *)state->PyDecContext_Type, NULL); if (copy == NULL) { return NULL; @@ -1490,14 +1566,15 @@ context_reduce(PyObject *self, PyObject *args UNUSED) PyObject *traps; PyObject *ret; mpd_context_t *ctx; + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); ctx = CTX(self); - flags = signals_as_list(ctx->status); + flags = signals_as_list(state, ctx->status); if (flags == NULL) { return NULL; } - traps = signals_as_list(ctx->traps); + traps = signals_as_list(state, ctx->traps); if (traps == NULL) { Py_DECREF(flags); return NULL; @@ -1542,7 +1619,7 @@ static PyGetSetDef context_getsets [] = #define CONTEXT_CHECK_VA(state, obj) \ if (obj == Py_None) { \ - CURRENT_CONTEXT(obj); \ + CURRENT_CONTEXT(state, obj); \ } \ else if (!PyDecContext_Check(state, obj)) { \ PyErr_SetString(PyExc_TypeError, \ @@ -1565,10 +1642,9 @@ static PyGetSetDef context_getsets [] = #ifndef WITH_DECIMAL_CONTEXTVAR /* Get the context from the thread state dictionary. */ static PyObject * -current_context_from_dict(void) +current_context_from_dict(decimal_state *modstate) { PyThreadState *tstate = _PyThreadState_GET(); - decimal_state *modstate = GLOBAL_STATE(); #ifdef Py_DEBUG // The caller must hold the GIL _Py_EnsureTstateNotNULL(tstate); @@ -1617,45 +1693,41 @@ current_context_from_dict(void) /* Return borrowed reference to thread local context. */ static PyObject * -current_context(void) +current_context(decimal_state *modstate) { PyThreadState *tstate = _PyThreadState_GET(); - decimal_state *modstate = GLOBAL_STATE(); if (modstate->cached_context && modstate->cached_context->tstate == tstate) { return (PyObject *)(modstate->cached_context); } - return current_context_from_dict(); + return current_context_from_dict(modstate); } /* ctxobj := borrowed reference to the current context */ -#define CURRENT_CONTEXT(ctxobj) \ - ctxobj = current_context(); \ +#define CURRENT_CONTEXT(state, ctxobj) \ + ctxobj = current_context(state); \ if (ctxobj == NULL) { \ return NULL; \ } /* Return a new reference to the current context */ static PyObject * -PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +PyDec_GetCurrentContext(PyObject *self, PyObject *args UNUSED) { PyObject *context; + decimal_state *state = get_module_state(self); - context = current_context(); - if (context == NULL) { - return NULL; - } - + CURRENT_CONTEXT(state, context); return Py_NewRef(context); } /* Set the thread local context to a new context, decrement old reference */ static PyObject * -PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +PyDec_SetCurrentContext(PyObject *self, PyObject *v) { PyObject *dict; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state(self); CONTEXT_CHECK(state, v); dict = PyThreadState_GetDict(); @@ -1691,9 +1763,8 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) } #else static PyObject * -init_current_context(void) +init_current_context(decimal_state *state) { - decimal_state *state = GLOBAL_STATE(); PyObject *tl_context = context_copy(state->default_context_template, NULL); if (tl_context == NULL) { return NULL; @@ -1711,10 +1782,9 @@ init_current_context(void) } static inline PyObject * -current_context(void) +current_context(decimal_state *state) { PyObject *tl_context; - decimal_state *state = GLOBAL_STATE(); if (PyContextVar_Get(state->current_context_var, NULL, &tl_context) < 0) { return NULL; } @@ -1723,12 +1793,12 @@ current_context(void) return tl_context; } - return init_current_context(); + return init_current_context(state); } /* ctxobj := borrowed reference to the current context */ -#define CURRENT_CONTEXT(ctxobj) \ - ctxobj = current_context(); \ +#define CURRENT_CONTEXT(state, ctxobj) \ + ctxobj = current_context(state); \ if (ctxobj == NULL) { \ return NULL; \ } \ @@ -1736,16 +1806,17 @@ current_context(void) /* Return a new reference to the current context */ static PyObject * -PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +PyDec_GetCurrentContext(PyObject *self, PyObject *args UNUSED) { - return current_context(); + decimal_state *state = get_module_state(self); + return current_context(state); } /* Set the thread local context to a new context, decrement old reference */ static PyObject * -PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +PyDec_SetCurrentContext(PyObject *self, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state(self); CONTEXT_CHECK(state, v); /* If the new context is one of the templates, make a copy. @@ -1778,7 +1849,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) * owns one reference to the global (outer) context and one * to the local (inner) context. */ static PyObject * -ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) +ctxmanager_new(PyObject *m, PyObject *args, PyObject *kwds) { static char *kwlist[] = { "ctx", "prec", "rounding", @@ -1798,8 +1869,8 @@ ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) PyObject *flags = Py_None; PyObject *traps = Py_None; - decimal_state *state = GLOBAL_STATE(); - CURRENT_CONTEXT(global); + decimal_state *state = get_module_state(m); + CURRENT_CONTEXT(state, global); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOOOO", kwlist, &local, &prec, &rounding, &Emin, &Emax, &capitals, &clamp, &flags, &traps)) { return NULL; @@ -1876,7 +1947,7 @@ ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED) { PyObject *ret; - ret = PyDec_SetCurrentContext(NULL, self->local); + ret = PyDec_SetCurrentContext(PyType_GetModule(Py_TYPE(self)), self->local); if (ret == NULL) { return NULL; } @@ -1891,7 +1962,7 @@ ctxmanager_restore_global(PyDecContextManagerObject *self, { PyObject *ret; - ret = PyDec_SetCurrentContext(NULL, self->global); + ret = PyDec_SetCurrentContext(PyType_GetModule(Py_TYPE(self)), self->global); if (ret == NULL) { return NULL; } @@ -1934,7 +2005,7 @@ PyDecType_New(PyTypeObject *type) { PyDecObject *dec; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (type == state->PyDec_Type) { dec = PyObject_GC_New(PyDecObject, state->PyDec_Type); } @@ -2321,8 +2392,8 @@ PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v, mpd_t *d1, *d2; uint32_t status = 0; mpd_context_t maxctx; + decimal_state *state = get_module_state_by_def(type); - decimal_state *state = GLOBAL_STATE(); #ifdef Py_DEBUG assert(PyType_IsSubtype(type, state->PyDec_Type)); #endif @@ -2459,7 +2530,7 @@ PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context) PyObject *dec; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (type == state->PyDec_Type && PyDec_CheckExact(state, v)) { return Py_NewRef(v); } @@ -2734,8 +2805,8 @@ dec_from_float(PyObject *type, PyObject *pyfloat) PyObject *context; PyObject *result; - CURRENT_CONTEXT(context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def((PyTypeObject *)type); + CURRENT_CONTEXT(state, context); result = PyDecType_FromFloatExact(state->PyDec_Type, pyfloat, context); if (type != (PyObject *)state->PyDec_Type && result != NULL) { Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL)); @@ -2748,7 +2819,7 @@ dec_from_float(PyObject *type, PyObject *pyfloat) static PyObject * ctx_from_float(PyObject *context, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); return PyDec_FromFloat(state, v, context); } @@ -2759,7 +2830,7 @@ dec_apply(PyObject *v, PyObject *context) PyObject *result; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -2786,7 +2857,7 @@ dec_apply(PyObject *v, PyObject *context) static PyObject * PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (v == NULL) { return PyDecType_FromSsizeExact(type, 0, context); } @@ -2821,7 +2892,7 @@ PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) static PyObject * PyDec_FromObject(PyObject *v, PyObject *context) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (v == NULL) { return PyDec_FromSsize(state, 0, context); } @@ -2877,7 +2948,7 @@ dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds) &v, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); CONTEXT_CHECK_VA(state, context); return PyDecType_FromObjectExact(type, v, context); @@ -2908,7 +2979,7 @@ ctx_create_decimal(PyObject *context, PyObject *args) Py_LOCAL_INLINE(int) convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (PyDec_Check(state, v)) { *conv = Py_NewRef(v); return 1; @@ -3011,7 +3082,7 @@ multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context) if (tmp == NULL) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); denom = PyDec_FromLongExact(state, tmp, context); Py_DECREF(tmp); if (denom == NULL) { @@ -3066,7 +3137,7 @@ numerator_as_decimal(PyObject *r, PyObject *context) return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); num = PyDec_FromLongExact(state, tmp, context); Py_DECREF(tmp); return num; @@ -3085,7 +3156,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, *vcmp = v; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (PyDec_Check(state, w)) { *wcmp = Py_NewRef(w); } @@ -3183,7 +3254,8 @@ dec_str(PyObject *dec) mpd_ssize_t size; char *cp; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context)); if (size < 0) { PyErr_NoMemory(); @@ -3201,8 +3273,8 @@ dec_repr(PyObject *dec) { PyObject *res, *context; char *cp; - - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); cp = mpd_to_sci(MPD(dec), CtxCaps(context)); if (cp == NULL) { PyErr_NoMemory(); @@ -3363,7 +3435,8 @@ dec_format(PyObject *dec, PyObject *args) mpd_t tmp = {MPD_STATIC|MPD_STATIC_DATA,0,0,0,MPD_MINALLOC_MAX,dt}; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { return NULL; } @@ -3520,6 +3593,12 @@ dec_format(PyObject *dec, PyObject *args) if (replace_fillchar) { dec_replace_fillchar(decstring); } + if (strchr(fmt, 'N') != NULL) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Format specifier 'N' is deprecated", 1) < 0) { + goto finish; + } + } result = PyUnicode_DecodeUTF8(decstring, size, NULL); @@ -3626,9 +3705,9 @@ dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) return NULL; } - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); - decimal_state *state = GLOBAL_STATE(); tmp = dec_alloc(state); if (tmp == NULL) { return NULL; @@ -3719,12 +3798,12 @@ PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds) &rounding, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); CONTEXT_CHECK_VA(state, context); workctx = *CTX(context); if (rounding != Py_None) { - int round = getround(rounding); + int round = getround(state, rounding); if (round < 0) { return NULL; } @@ -3761,12 +3840,12 @@ PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds) &rounding, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); CONTEXT_CHECK_VA(state, context); workctx = *CTX(context); if (rounding != Py_None) { - int round = getround(rounding); + int round = getround(state, rounding); if (round < 0) { return NULL; } @@ -3829,7 +3908,8 @@ PyDec_Round(PyObject *dec, PyObject *args) uint32_t status = 0; PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); if (!PyArg_ParseTuple(args, "|O", &x)) { return NULL; } @@ -3849,7 +3929,6 @@ PyDec_Round(PyObject *dec, PyObject *args) if (y == -1 && PyErr_Occurred()) { return NULL; } - decimal_state *state = GLOBAL_STATE(); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -3951,7 +4030,7 @@ PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) } } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); result = PyObject_CallFunctionObjArgs((PyObject *)state->DecimalTuple, sign, coeff, expt, NULL); @@ -3978,8 +4057,8 @@ nm_##MPDFUNC(PyObject *self) \ PyObject *context; \ uint32_t status = 0; \ \ - decimal_state *state = GLOBAL_STATE(); \ - CURRENT_CONTEXT(context); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ + CURRENT_CONTEXT(state, context); \ if ((result = dec_alloc(state)) == NULL) { \ return NULL; \ } \ @@ -4003,8 +4082,8 @@ nm_##MPDFUNC(PyObject *self, PyObject *other) \ PyObject *context; \ uint32_t status = 0; \ \ - decimal_state *state = GLOBAL_STATE(); \ - CURRENT_CONTEXT(context) ; \ + decimal_state *state = find_state_left_or_right(self, other); \ + CURRENT_CONTEXT(state, context) ; \ CONVERT_BINOP(&a, &b, self, other, context); \ \ if ((result = dec_alloc(state)) == NULL) { \ @@ -4044,7 +4123,7 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ \ return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \ @@ -4064,7 +4143,8 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ \ if ((result = dec_alloc(state)) == NULL) { \ @@ -4096,7 +4176,8 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &other, &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ \ @@ -4134,7 +4215,8 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &other, &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ \ @@ -4167,7 +4249,7 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &other, &third, &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context); \ \ @@ -4210,8 +4292,8 @@ static PyObject * nm_dec_as_long(PyObject *dec) { PyObject *context; - - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); return dec_as_long(dec, context, MPD_ROUND_DOWN); } @@ -4230,10 +4312,10 @@ nm_mpd_qdivmod(PyObject *v, PyObject *w) uint32_t status = 0; PyObject *ret; - CURRENT_CONTEXT(context); + decimal_state *state = find_state_left_or_right(v, w); + CURRENT_CONTEXT(state, context); CONVERT_BINOP(&a, &b, v, w, context); - decimal_state *state = GLOBAL_STATE(); q = dec_alloc(state); if (q == NULL) { Py_DECREF(a); @@ -4271,7 +4353,8 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) PyObject *context; uint32_t status = 0; - CURRENT_CONTEXT(context); + decimal_state *state = find_state_left_or_right(base, exp); + CURRENT_CONTEXT(state, context); CONVERT_BINOP(&a, &b, base, exp, context); if (mod != Py_None) { @@ -4282,7 +4365,6 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) } } - decimal_state *state = GLOBAL_STATE(); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -4380,11 +4462,11 @@ dec_conjugate(PyObject *self, PyObject *dummy UNUSED) } static PyObject * -dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED) +dec_mpd_radix(PyObject *self, PyObject *dummy UNUSED) { PyObject *result; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -4400,7 +4482,7 @@ dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED) PyObject *result; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if ((result = dec_alloc(state)) == NULL) { return NULL; } @@ -4421,7 +4503,7 @@ dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED) PyObject *result; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if ((result = dec_alloc(state)) == NULL) { return NULL; } @@ -4451,7 +4533,7 @@ dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds) &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); cp = mpd_class(MPD(self), CTX(context)); @@ -4471,7 +4553,7 @@ dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds) &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context)); @@ -4504,7 +4586,7 @@ dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds) &other, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); CONVERT_BINOP_RAISE(&a, &b, self, other, context); @@ -4539,7 +4621,7 @@ dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds) &other, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); CONVERT_BINOP_RAISE(&a, &b, self, other, context); @@ -4574,12 +4656,12 @@ dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds) &w, &rounding, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(v)); CONTEXT_CHECK_VA(state, context); workctx = *CTX(context); if (rounding != Py_None) { - int round = getround(rounding); + int round = getround(state, rounding); if (round < 0) { return NULL; } @@ -4618,12 +4700,12 @@ dec_richcompare(PyObject *v, PyObject *w, int op) uint32_t status = 0; int a_issnan, b_issnan; int r; + decimal_state *state = find_state_left_or_right(v, w); #ifdef Py_DEBUG - decimal_state *state = GLOBAL_STATE(); assert(PyDec_Check(state, v)); #endif - CURRENT_CONTEXT(context); + CURRENT_CONTEXT(state, context); CONVERT_BINOP_CMP(&a, &b, v, w, op, context); a_issnan = mpd_issnan(MPD(a)); @@ -4674,7 +4756,8 @@ dec_ceil(PyObject *self, PyObject *dummy UNUSED) { PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); return dec_as_long(self, context, MPD_ROUND_CEILING); } @@ -4712,7 +4795,8 @@ dec_floor(PyObject *self, PyObject *dummy UNUSED) { PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); return dec_as_long(self, context, MPD_ROUND_FLOOR); } @@ -4876,7 +4960,8 @@ dec_trunc(PyObject *self, PyObject *dummy UNUSED) { PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); return dec_as_long(self, context, MPD_ROUND_DOWN); } @@ -4892,7 +4977,7 @@ dec_imag(PyObject *self UNUSED, void *closure UNUSED) { PyObject *result; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -5091,7 +5176,8 @@ ctx_##MPDFUNC(PyObject *context, PyObject *v) \ uint32_t status = 0; \ \ CONVERT_OP_RAISE(&a, v, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ return NULL; \ @@ -5122,7 +5208,8 @@ ctx_##MPDFUNC(PyObject *context, PyObject *args) \ } \ \ CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ Py_DECREF(b); \ @@ -5157,7 +5244,8 @@ ctx_##MPDFUNC(PyObject *context, PyObject *args) \ } \ \ CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ Py_DECREF(b); \ @@ -5186,7 +5274,7 @@ ctx_##MPDFUNC(PyObject *context, PyObject *args) \ } \ \ CONVERT_TERNOP_RAISE(&a, &b, &c, v, w, x, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ Py_DECREF(b); \ @@ -5252,7 +5340,7 @@ ctx_mpd_qdivmod(PyObject *context, PyObject *args) } CONVERT_BINOP_RAISE(&a, &b, v, w, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); q = dec_alloc(state); if (q == NULL) { Py_DECREF(a); @@ -5307,7 +5395,7 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds) } } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5357,9 +5445,9 @@ DecCtx_BoolFunc_NO_CTX(mpd_issnan) DecCtx_BoolFunc_NO_CTX(mpd_iszero) static PyObject * -ctx_iscanonical(PyObject *context UNUSED, PyObject *v) +ctx_iscanonical(PyObject *context, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (!PyDec_Check(state, v)) { PyErr_SetString(PyExc_TypeError, "argument must be a Decimal"); @@ -5383,9 +5471,9 @@ PyDecContext_Apply(PyObject *context, PyObject *v) } static PyObject * -ctx_canonical(PyObject *context UNUSED, PyObject *v) +ctx_canonical(PyObject *context, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (!PyDec_Check(state, v)) { PyErr_SetString(PyExc_TypeError, "argument must be a Decimal"); @@ -5402,7 +5490,7 @@ ctx_mpd_qcopy_abs(PyObject *context, PyObject *v) uint32_t status = 0; CONVERT_OP_RAISE(&a, v, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5435,7 +5523,7 @@ ctx_mpd_qcopy_negate(PyObject *context, PyObject *v) uint32_t status = 0; CONVERT_OP_RAISE(&a, v, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5532,7 +5620,7 @@ ctx_mpd_qcopy_sign(PyObject *context, PyObject *args) } CONVERT_BINOP_RAISE(&a, &b, v, w, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5721,17 +5809,6 @@ static PyMethodDef _decimal_methods [] = { NULL, NULL, 1, NULL } }; -static struct PyModuleDef _decimal_module = { - PyModuleDef_HEAD_INIT, - "decimal", - doc__decimal, - -1, - _decimal_methods, - NULL, - NULL, - NULL, - NULL -}; struct ssize_constmap { const char *name; mpd_ssize_t val; }; static struct ssize_constmap ssize_constants [] = { @@ -5806,11 +5883,11 @@ cfunc_noargs(PyTypeObject *t, const char *name) return NULL; } +static int minalloc_is_set = 0; -PyMODINIT_FUNC -PyInit__decimal(void) +static int +_decimal_exec(PyObject *m) { - PyObject *m = NULL; PyObject *numbers = NULL; PyObject *Number = NULL; PyObject *collections = NULL; @@ -5829,9 +5906,14 @@ PyInit__decimal(void) mpd_reallocfunc = PyMem_Realloc; mpd_callocfunc = mpd_callocfunc_em; mpd_free = PyMem_Free; - mpd_setminalloc(_Py_DEC_MINALLOC); - decimal_state *state = GLOBAL_STATE(); + /* Suppress the warning caused by multi-phase initialization */ + if (!minalloc_is_set) { + mpd_setminalloc(_Py_DEC_MINALLOC); + minalloc_is_set = 1; + } + + decimal_state *state = get_module_state(m); /* Init external C-API functions */ state->_py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; @@ -5903,10 +5985,6 @@ PyInit__decimal(void) Py_CLEAR(collections_abc); Py_CLEAR(MutableMapping); - - /* Create the module */ - ASSIGN_PTR(m, PyModule_Create(&_decimal_module)); - /* Add types to the module */ CHECK_INT(PyModule_AddType(m, state->PyDec_Type)); CHECK_INT(PyModule_AddType(m, state->PyDecContext_Type)); @@ -5922,10 +6000,12 @@ PyInit__decimal(void) ASSIGN_PTR(state->SignalTuple, PyTuple_New(SIGNAL_MAP_LEN)); /* Add exceptions that correspond to IEEE signals */ + ASSIGN_PTR(state->signal_map, dec_cond_map_init(signal_map_template, + sizeof(signal_map_template))); for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) { PyObject *base; - cm = signal_map + i; + cm = state->signal_map + i; switch (cm->flag) { case MPD_Float_operation: @@ -5936,13 +6016,13 @@ PyInit__decimal(void) PyExc_ZeroDivisionError); break; case MPD_Overflow: - base = PyTuple_Pack(2, signal_map[INEXACT].ex, - signal_map[ROUNDED].ex); + base = PyTuple_Pack(2, state->signal_map[INEXACT].ex, + state->signal_map[ROUNDED].ex); break; case MPD_Underflow: - base = PyTuple_Pack(3, signal_map[INEXACT].ex, - signal_map[ROUNDED].ex, - signal_map[SUBNORMAL].ex); + base = PyTuple_Pack(3, state->signal_map[INEXACT].ex, + state->signal_map[ROUNDED].ex, + state->signal_map[SUBNORMAL].ex); break; default: base = PyTuple_Pack(1, state->DecimalException); @@ -5968,16 +6048,18 @@ PyInit__decimal(void) * several conditions, including InvalidOperation! Naming the * signal IEEEInvalidOperation would prevent the confusion. */ - cond_map[0].ex = signal_map[0].ex; + ASSIGN_PTR(state->cond_map, dec_cond_map_init(cond_map_template, + sizeof(cond_map_template))); + state->cond_map[0].ex = state->signal_map[0].ex; /* Add remaining exceptions, inherit from InvalidOperation */ - for (cm = cond_map+1; cm->name != NULL; cm++) { + for (cm = state->cond_map+1; cm->name != NULL; cm++) { PyObject *base; if (cm->flag == MPD_Division_undefined) { - base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError); + base = PyTuple_Pack(2, state->signal_map[0].ex, PyExc_ZeroDivisionError); } else { - base = PyTuple_Pack(1, signal_map[0].ex); + base = PyTuple_Pack(1, state->signal_map[0].ex); } if (base == NULL) { goto error; /* GCOV_NOT_REACHED */ @@ -6023,9 +6105,8 @@ PyInit__decimal(void) /* Init mpd_ssize_t constants */ for (ssize_cm = ssize_constants; ssize_cm->name != NULL; ssize_cm++) { - ASSIGN_PTR(obj, PyLong_FromSsize_t(ssize_cm->val)); - CHECK_INT(PyModule_AddObject(m, ssize_cm->name, obj)); - obj = NULL; + CHECK_INT(PyModule_Add(m, ssize_cm->name, + PyLong_FromSsize_t(ssize_cm->val))); } /* Init int constants */ @@ -6044,29 +6125,103 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70")); CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version())); - - return m; - + return 0; error: Py_CLEAR(obj); /* GCOV_NOT_REACHED */ Py_CLEAR(numbers); /* GCOV_NOT_REACHED */ Py_CLEAR(Number); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->Rational); /* GCOV_NOT_REACHED */ Py_CLEAR(collections); /* GCOV_NOT_REACHED */ Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */ Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->SignalTuple); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->DecimalTuple); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->default_context_template); /* GCOV_NOT_REACHED */ + + return -1; +} + +static int +decimal_traverse(PyObject *module, visitproc visit, void *arg) +{ + decimal_state *state = get_module_state(module); + Py_VISIT(state->PyDecContextManager_Type); + Py_VISIT(state->PyDecContext_Type); + Py_VISIT(state->PyDecSignalDictMixin_Type); + Py_VISIT(state->PyDec_Type); + Py_VISIT(state->PyDecSignalDict_Type); + Py_VISIT(state->DecimalTuple); + Py_VISIT(state->DecimalException); + +#ifndef WITH_DECIMAL_CONTEXTVAR + Py_VISIT(state->tls_context_key); + Py_VISIT(state->cached_context); +#else + Py_VISIT(state->current_context_var); +#endif + + Py_VISIT(state->default_context_template); + Py_VISIT(state->basic_context_template); + Py_VISIT(state->extended_context_template); + Py_VISIT(state->Rational); + Py_VISIT(state->SignalTuple); + + return 0; +} + +static int +decimal_clear(PyObject *module) +{ + decimal_state *state = get_module_state(module); + Py_CLEAR(state->PyDecContextManager_Type); + Py_CLEAR(state->PyDecContext_Type); + Py_CLEAR(state->PyDecSignalDictMixin_Type); + Py_CLEAR(state->PyDec_Type); + Py_CLEAR(state->PyDecSignalDict_Type); + Py_CLEAR(state->DecimalTuple); + Py_CLEAR(state->DecimalException); + #ifndef WITH_DECIMAL_CONTEXTVAR - Py_CLEAR(state->tls_context_key); /* GCOV_NOT_REACHED */ + Py_CLEAR(state->tls_context_key); + Py_CLEAR(state->cached_context); #else - Py_CLEAR(state->current_context_var); /* GCOV_NOT_REACHED */ + Py_CLEAR(state->current_context_var); #endif - Py_CLEAR(state->basic_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->extended_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(m); /* GCOV_NOT_REACHED */ - return NULL; /* GCOV_NOT_REACHED */ + Py_CLEAR(state->default_context_template); + Py_CLEAR(state->basic_context_template); + Py_CLEAR(state->extended_context_template); + Py_CLEAR(state->Rational); + Py_CLEAR(state->SignalTuple); + + PyMem_Free(state->signal_map); + PyMem_Free(state->cond_map); + return 0; +} + +static void +decimal_free(void *module) +{ + (void)decimal_clear((PyObject *)module); +} + +static struct PyModuleDef_Slot _decimal_slots[] = { + {Py_mod_exec, _decimal_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static struct PyModuleDef _decimal_module = { + PyModuleDef_HEAD_INIT, + .m_name = "decimal", + .m_doc = doc__decimal, + .m_size = sizeof(decimal_state), + .m_methods = _decimal_methods, + .m_slots = _decimal_slots, + .m_traverse = decimal_traverse, + .m_clear = decimal_clear, + .m_free = decimal_free, +}; + +PyMODINIT_FUNC +PyInit__decimal(void) +{ + return PyModuleDef_Init(&_decimal_module); } diff --git a/Modules/_decimal/tests/bench.py b/Modules/_decimal/tests/bench.py index 24e091b6887ccd..640290f2ec7962 100644 --- a/Modules/_decimal/tests/bench.py +++ b/Modules/_decimal/tests/bench.py @@ -7,6 +7,8 @@ import time +import sys +from functools import wraps from test.support.import_helper import import_fresh_module C = import_fresh_module('decimal', fresh=['_decimal']) @@ -64,66 +66,85 @@ def factorial(n, m): else: return factorial(n, (n+m)//2) * factorial((n+m)//2 + 1, m) +# Fix failed test cases caused by CVE-2020-10735 patch. +# See gh-95778 for details. +def increase_int_max_str_digits(maxdigits): + def _increase_int_max_str_digits(func, maxdigits=maxdigits): + @wraps(func) + def wrapper(*args, **kwargs): + previous_int_limit = sys.get_int_max_str_digits() + sys.set_int_max_str_digits(maxdigits) + ans = func(*args, **kwargs) + sys.set_int_max_str_digits(previous_int_limit) + return ans + return wrapper + return _increase_int_max_str_digits + +def test_calc_pi(): + print("\n# ======================================================================") + print("# Calculating pi, 10000 iterations") + print("# ======================================================================\n") + + to_benchmark = [pi_float, pi_decimal] + if C is not None: + to_benchmark.insert(1, pi_cdecimal) + + for prec in [9, 19]: + print("\nPrecision: %d decimal digits\n" % prec) + for func in to_benchmark: + start = time.time() + if C is not None: + C.getcontext().prec = prec + P.getcontext().prec = prec + for i in range(10000): + x = func() + print("%s:" % func.__name__.replace("pi_", "")) + print("result: %s" % str(x)) + print("time: %fs\n" % (time.time()-start)) + +@increase_int_max_str_digits(maxdigits=10000000) +def test_factorial(): + print("\n# ======================================================================") + print("# Factorial") + print("# ======================================================================\n") -print("\n# ======================================================================") -print("# Calculating pi, 10000 iterations") -print("# ======================================================================\n") - -to_benchmark = [pi_float, pi_decimal] -if C is not None: - to_benchmark.insert(1, pi_cdecimal) - -for prec in [9, 19]: - print("\nPrecision: %d decimal digits\n" % prec) - for func in to_benchmark: - start = time.time() - if C is not None: - C.getcontext().prec = prec - P.getcontext().prec = prec - for i in range(10000): - x = func() - print("%s:" % func.__name__.replace("pi_", "")) - print("result: %s" % str(x)) - print("time: %fs\n" % (time.time()-start)) - - -print("\n# ======================================================================") -print("# Factorial") -print("# ======================================================================\n") - -if C is not None: - c = C.getcontext() - c.prec = C.MAX_PREC - c.Emax = C.MAX_EMAX - c.Emin = C.MIN_EMIN + if C is not None: + c = C.getcontext() + c.prec = C.MAX_PREC + c.Emax = C.MAX_EMAX + c.Emin = C.MIN_EMIN -for n in [100000, 1000000]: + for n in [100000, 1000000]: - print("n = %d\n" % n) + print("n = %d\n" % n) - if C is not None: - # C version of decimal + if C is not None: + # C version of decimal + start_calc = time.time() + x = factorial(C.Decimal(n), 0) + end_calc = time.time() + start_conv = time.time() + sx = str(x) + end_conv = time.time() + print("cdecimal:") + print("calculation time: %fs" % (end_calc-start_calc)) + print("conversion time: %fs\n" % (end_conv-start_conv)) + + # Python integers start_calc = time.time() - x = factorial(C.Decimal(n), 0) + y = factorial(n, 0) end_calc = time.time() start_conv = time.time() - sx = str(x) - end_conv = time.time() - print("cdecimal:") - print("calculation time: %fs" % (end_calc-start_calc)) - print("conversion time: %fs\n" % (end_conv-start_conv)) + sy = str(y) + end_conv = time.time() - # Python integers - start_calc = time.time() - y = factorial(n, 0) - end_calc = time.time() - start_conv = time.time() - sy = str(y) - end_conv = time.time() + print("int:") + print("calculation time: %fs" % (end_calc-start_calc)) + print("conversion time: %fs\n\n" % (end_conv-start_conv)) - print("int:") - print("calculation time: %fs" % (end_calc-start_calc)) - print("conversion time: %fs\n\n" % (end_conv-start_conv)) + if C is not None: + assert(sx == sy) - if C is not None: - assert(sx == sy) +if __name__ == "__main__": + test_calc_pi() + test_factorial() diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index edf753f3704a18..bf277dd6879ffe 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -1301,7 +1301,7 @@ def tfunc(): out, _ = p.communicate() write_output(out, p.returncode) - N = os.cpu_count() + N = os.process_cpu_count() t = N * [None] for i in range(N): diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index a8d68d68420d36..f9d5793f9b6497 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -17,7 +17,9 @@ #include "Python.h" #include "pycore_import.h" // _PyImport_GetModuleAttrString() -#include "structmember.h" // PyMemberDef +#include "pycore_pyhash.h" // _Py_HashSecret + +#include // offsetof() #include "expat.h" #include "pyexpat.h" @@ -3530,12 +3532,11 @@ expat_start_doctype_handler(XMLParserObject *self, sysid_obj, NULL); Py_XDECREF(res); } - else if (PyObject_GetOptionalAttr((PyObject *)self, st->str_doctype, &res) > 0) { + else if (PyObject_HasAttrWithError((PyObject *)self, st->str_doctype) > 0) { (void)PyErr_WarnEx(PyExc_RuntimeWarning, "The doctype() method of XMLParser is ignored. " "Define doctype() method on the TreeBuilder target.", 1); - Py_DECREF(res); } Py_DECREF(doctype_name_obj); @@ -4133,8 +4134,8 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, } static PyMemberDef xmlparser_members[] = { - {"entity", T_OBJECT, offsetof(XMLParserObject, entity), READONLY, NULL}, - {"target", T_OBJECT, offsetof(XMLParserObject, target), READONLY, NULL}, + {"entity", _Py_T_OBJECT, offsetof(XMLParserObject, entity), Py_READONLY, NULL}, + {"target", _Py_T_OBJECT, offsetof(XMLParserObject, target), Py_READONLY, NULL}, {NULL} }; @@ -4190,7 +4191,7 @@ static PyMethodDef element_methods[] = { }; static struct PyMemberDef element_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(ElementObject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(ElementObject, weakreflist), Py_READONLY}, {NULL}, }; diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index c987485e66a48a..8ea493ad9ab278 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -6,7 +6,7 @@ #include "pycore_object.h" // _PyObject_GC_TRACK #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "structmember.h" // PyMemberDef + #include "clinic/_functoolsmodule.c.h" /*[clinic input] @@ -340,18 +340,18 @@ PyDoc_STRVAR(partial_doc, #define OFF(x) offsetof(partialobject, x) static PyMemberDef partial_memberlist[] = { - {"func", T_OBJECT, OFF(fn), READONLY, + {"func", _Py_T_OBJECT, OFF(fn), Py_READONLY, "function object to use in future partial calls"}, - {"args", T_OBJECT, OFF(args), READONLY, + {"args", _Py_T_OBJECT, OFF(args), Py_READONLY, "tuple of arguments to future partial calls"}, - {"keywords", T_OBJECT, OFF(kw), READONLY, + {"keywords", _Py_T_OBJECT, OFF(kw), Py_READONLY, "dictionary of keyword arguments to future partial calls"}, - {"__weaklistoffset__", T_PYSSIZET, - offsetof(partialobject, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, - offsetof(partialobject, dict), READONLY}, - {"__vectorcalloffset__", T_PYSSIZET, - offsetof(partialobject, vectorcall), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, + offsetof(partialobject, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, + offsetof(partialobject, dict), Py_READONLY}, + {"__vectorcalloffset__", Py_T_PYSSIZET, + offsetof(partialobject, vectorcall), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -540,7 +540,7 @@ keyobject_traverse(keyobject *ko, visitproc visit, void *arg) } static PyMemberDef keyobject_members[] = { - {"obj", T_OBJECT, + {"obj", _Py_T_OBJECT, offsetof(keyobject, object), 0, PyDoc_STR("Value wrapped by a key function.")}, {NULL} @@ -725,7 +725,7 @@ functools_reduce(PyObject *self, PyObject *args) } PyDoc_STRVAR(functools_reduce_doc, -"reduce(function, iterable[, initial]) -> value\n\ +"reduce(function, iterable[, initial], /) -> value\n\ \n\ Apply a function of two arguments cumulatively to the items of a sequence\n\ or iterable, from left to right, so as to reduce the iterable to a single\n\ @@ -1394,10 +1394,10 @@ static PyGetSetDef lru_cache_getsetlist[] = { }; static PyMemberDef lru_cache_memberlist[] = { - {"__dictoffset__", T_PYSSIZET, - offsetof(lru_cache_object, dict), READONLY}, - {"__weaklistoffset__", T_PYSSIZET, - offsetof(lru_cache_object, weakreflist), READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, + offsetof(lru_cache_object, dict), Py_READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, + offsetof(lru_cache_object, weakreflist), Py_READONLY}, {NULL} /* Sentinel */ }; diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index bedbdc081425c2..eff36fd7fb669b 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -561,6 +561,37 @@ _gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls) Py_RETURN_NONE; } +/*[clinic input] +_gdbm.gdbm.clear + cls: defining_class + / +Remove all items from the database. + +[clinic start generated code]*/ + +static PyObject * +_gdbm_gdbm_clear_impl(gdbmobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=673577c573318661 input=34136d52fcdd4210]*/ +{ + _gdbm_state *state = PyType_GetModuleState(cls); + assert(state != NULL); + check_gdbmobject_open(self, state->gdbm_error); + datum key; + // Invalidate cache + self->di_size = -1; + while (1) { + key = gdbm_firstkey(self->di_dbm); + if (key.dptr == NULL) { + break; + } + if (gdbm_delete(self->di_dbm, key) < 0) { + PyErr_SetString(state->gdbm_error, "cannot delete item from database"); + return NULL; + } + } + Py_RETURN_NONE; +} + static PyObject * gdbm__enter__(PyObject *self, PyObject *args) { @@ -582,6 +613,7 @@ static PyMethodDef gdbm_methods[] = { _GDBM_GDBM_SYNC_METHODDEF _GDBM_GDBM_GET_METHODDEF _GDBM_GDBM_SETDEFAULT_METHODDEF + _GDBM_GDBM_CLEAR_METHODDEF {"__enter__", gdbm__enter__, METH_NOARGS, NULL}, {"__exit__", gdbm__exit__, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ @@ -755,11 +787,7 @@ _gdbm_exec(PyObject *module) defined(GDBM_VERSION_PATCH) PyObject *obj = Py_BuildValue("iii", GDBM_VERSION_MAJOR, GDBM_VERSION_MINOR, GDBM_VERSION_PATCH); - if (obj == NULL) { - return -1; - } - if (PyModule_AddObject(module, "_GDBM_VERSION", obj) < 0) { - Py_DECREF(obj); + if (PyModule_Add(module, "_GDBM_VERSION", obj) < 0) { return -1; } #endif diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 246eea74098820..ee6fb8b4b03643 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -24,8 +24,9 @@ #include "Python.h" #include "pycore_hashtable.h" -#include "hashlib.h" +#include "pycore_pyhash.h" // _Py_HashBytes() #include "pycore_strhex.h" // _Py_strhex() +#include "hashlib.h" /* EVP is the preferred interface to hashing in OpenSSL */ #include @@ -1888,12 +1889,7 @@ hashlib_md_meth_names(PyObject *module) return -1; } - if (PyModule_AddObject(module, "openssl_md_meth_names", state.set) < 0) { - Py_DECREF(state.set); - return -1; - } - - return 0; + return PyModule_Add(module, "openssl_md_meth_names", state.set); } /*[clinic input] diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index 00285ae01f8574..9d4ec256ee9e3e 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -672,9 +672,7 @@ From all times, sorting has always been a Great Art! :-)\n"); static int heapq_exec(PyObject *m) { - PyObject *about = PyUnicode_FromString(__about__); - if (PyModule_AddObject(m, "__about__", about) < 0) { - Py_DECREF(about); + if (PyModule_Add(m, "__about__", PyUnicode_FromString(__about__)) < 0) { return -1; } return 0; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 1a7920eebe0b61..173f5b55e5f732 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -8,9 +8,13 @@ */ #include "Python.h" -#include "_iomodule.h" -#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_long.h" // _PyLong_Sign() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() +#include "pycore_pystate.h" // _PyInterpreterState_GET() + +#include "_iomodule.h" #ifdef HAVE_SYS_TYPES_H #include diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index bfc3d2558c9e36..e8caf9f0df6dbf 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -8,11 +8,12 @@ */ #include "Python.h" +#include "pycore_bytesobject.h" // _PyBytes_Join() #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_object.h" +#include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _Py_FatalErrorFormat() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() -#include "structmember.h" // PyMemberDef + #include "_iomodule.h" /*[clinic input] @@ -552,17 +553,14 @@ _io__Buffered_close_impl(buffered *self) } /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); + r = _PyFile_Flush((PyObject *)self); if (!ENTER_BUFFERED(self)) { return NULL; } PyObject *exc = NULL; - if (res == NULL) { + if (r < 0) { exc = PyErr_GetRaisedException(); } - else { - Py_DECREF(res); - } res = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(close)); @@ -592,12 +590,11 @@ static PyObject * _io__Buffered_detach_impl(buffered *self) /*[clinic end generated code: output=dd0fc057b8b779f7 input=482762a345cc9f44]*/ { - PyObject *raw, *res; + PyObject *raw; CHECK_INITIALIZED(self) - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) + if (_PyFile_Flush((PyObject *)self) < 0) { return NULL; - Py_DECREF(res); + } raw = self->raw; self->raw = NULL; self->detached = 1; @@ -2477,10 +2474,10 @@ static PyMethodDef bufferedreader_methods[] = { }; static PyMemberDef bufferedreader_members[] = { - {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, - {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY}, + {"raw", _Py_T_OBJECT, offsetof(buffered, raw), Py_READONLY}, + {"_finalizing", Py_T_BOOL, offsetof(buffered, finalizing), 0}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(buffered, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(buffered, dict), Py_READONLY}, {NULL} }; @@ -2537,10 +2534,10 @@ static PyMethodDef bufferedwriter_methods[] = { }; static PyMemberDef bufferedwriter_members[] = { - {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, - {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY}, + {"raw", _Py_T_OBJECT, offsetof(buffered, raw), Py_READONLY}, + {"_finalizing", Py_T_BOOL, offsetof(buffered, finalizing), 0}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(buffered, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(buffered, dict), Py_READONLY}, {NULL} }; @@ -2593,8 +2590,8 @@ static PyMethodDef bufferedrwpair_methods[] = { }; static PyMemberDef bufferedrwpair_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(rwpair, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(rwpair, dict), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(rwpair, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(rwpair, dict), Py_READONLY}, {NULL} }; @@ -2655,10 +2652,10 @@ static PyMethodDef bufferedrandom_methods[] = { }; static PyMemberDef bufferedrandom_members[] = { - {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, - {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY}, + {"raw", _Py_T_OBJECT, offsetof(buffered, raw), Py_READONLY}, + {"_finalizing", Py_T_BOOL, offsetof(buffered, finalizing), 0}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(buffered, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(buffered, dict), Py_READONLY}, {NULL} }; diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 80773058693259..f3074203f54ea2 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -1,5 +1,7 @@ #include "Python.h" #include "pycore_object.h" +#include "pycore_sysmodule.h" // _PySys_GetSizeOf() + #include // offsetof() #include "_iomodule.h" @@ -1028,8 +1030,8 @@ static struct PyMethodDef bytesio_methods[] = { }; static PyMemberDef bytesio_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(bytesio, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(bytesio, dict), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(bytesio, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(bytesio, dict), Py_READONLY}, {NULL} }; diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 6bb2f7f212a44d..49a3573ab97473 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_io_open__doc__, "open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" " errors=None, newline=None, closefd=True, opener=None)\n" @@ -202,7 +201,7 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } if (args[2]) { - buffering = _PyLong_AsInt(args[2]); + buffering = PyLong_AsInt(args[2]); if (buffering == -1 && PyErr_Occurred()) { goto exit; } @@ -332,7 +331,7 @@ _io_text_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - stacklevel = _PyLong_AsInt(args[1]); + stacklevel = PyLong_AsInt(args[1]); if (stacklevel == -1 && PyErr_Occurred()) { goto exit; } @@ -404,4 +403,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=6800c35366b1a5f3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aaf96c8d9bd20abc input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 4f40fdadf8ec85..7577bdec5c3b20 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_io__BufferedIOBase_readinto__doc__, "readinto($self, buffer, /)\n" @@ -26,7 +26,6 @@ _io__BufferedIOBase_readinto(PyObject *self, PyObject *arg) Py_buffer buffer = {NULL, NULL}; if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } @@ -63,7 +62,6 @@ _io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) Py_buffer buffer = {NULL, NULL}; if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); goto exit; } @@ -162,7 +160,7 @@ _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *arg if (nargs < 1) { goto skip_optional_posonly; } - size = _PyLong_AsInt(args[0]); + size = PyLong_AsInt(args[0]); if (size == -1 && PyErr_Occurred()) { goto exit; } @@ -216,7 +214,7 @@ _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *ar if (nargs < 1) { goto skip_optional_posonly; } - size = _PyLong_AsInt(args[0]); + size = PyLong_AsInt(args[0]); if (size == -1 && PyErr_Occurred()) { goto exit; } @@ -590,7 +588,6 @@ _io__Buffered_readinto(buffered *self, PyObject *arg) Py_buffer buffer = {NULL, NULL}; if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } @@ -627,7 +624,6 @@ _io__Buffered_readinto1(buffered *self, PyObject *arg) Py_buffer buffer = {NULL, NULL}; if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); goto exit; } @@ -721,7 +717,7 @@ _io__Buffered_seek(buffered *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - whence = _PyLong_AsInt(args[1]); + whence = PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; } @@ -1098,4 +1094,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=b7ddf84a5bc2bf34 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f940cea085f0bf91 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 9550c8728c251e..d42ab48cef2859 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() PyDoc_STRVAR(_io_BytesIO_readable__doc__, "readable($self, /)\n" @@ -328,7 +328,6 @@ _io_BytesIO_readinto(bytesio *self, PyObject *arg) Py_buffer buffer = {NULL, NULL}; if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } @@ -427,7 +426,7 @@ _io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - whence = _PyLong_AsInt(args[1]); + whence = PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; } @@ -538,4 +537,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=098584d485420b65 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b753fdf1ba36c461 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index 33a37a389d223d..deb99fa9d99bd0 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() PyDoc_STRVAR(_io_FileIO_close__doc__, "close($self, /)\n" @@ -245,7 +245,6 @@ _io_FileIO_readinto(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_s goto exit; } if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); goto exit; } @@ -430,7 +429,7 @@ _io_FileIO_seek(fileio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - whence = _PyLong_AsInt(args[1]); + whence = PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; } @@ -536,4 +535,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=bef47b31b644996a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2ce6ce923ccef86e input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index 773e0010477053..9ac80b687925a4 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -2,11 +2,7 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() PyDoc_STRVAR(_io__IOBase_seek__doc__, "seek($self, offset, whence=os.SEEK_SET, /)\n" @@ -14,6 +10,11 @@ PyDoc_STRVAR(_io__IOBase_seek__doc__, "\n" "Change the stream position to the given byte offset.\n" "\n" +" offset\n" +" The stream position, relative to \'whence\'.\n" +" whence\n" +" The relative position to seek from.\n" +"\n" "The offset is interpreted relative to the position indicated by whence.\n" "Values for whence are:\n" "\n" @@ -55,14 +56,14 @@ _io__IOBase_seek(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ss if (!args) { goto exit; } - offset = _PyLong_AsInt(args[0]); + offset = PyLong_AsInt(args[0]); if (offset == -1 && PyErr_Occurred()) { goto exit; } if (nargs < 2) { goto skip_optional_posonly; } - whence = _PyLong_AsInt(args[1]); + whence = PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; } @@ -436,4 +437,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=301b22f8f75ce3dc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=95e1633805d10294 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index d495dd10c16330..ccdae18d2af24a 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() PyDoc_STRVAR(_io_StringIO_getvalue__doc__, "getvalue($self, /)\n" @@ -198,7 +198,7 @@ _io_StringIO_seek(stringio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - whence = _PyLong_AsInt(args[1]); + whence = PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; } @@ -367,4 +367,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { return _io_StringIO_seekable_impl(self); } -/*[clinic end generated code: output=533f20ae9b773126 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=57e86cd679344ee7 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 5c2162529ff2dd..bc14327388fb2f 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() PyDoc_STRVAR(_io__TextIOBase_detach__doc__, "detach($self, /)\n" @@ -75,7 +75,7 @@ _io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, P if (nargs < 1) { goto skip_optional_posonly; } - size = _PyLong_AsInt(args[0]); + size = PyLong_AsInt(args[0]); if (size == -1 && PyErr_Occurred()) { goto exit; } @@ -129,7 +129,7 @@ _io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *arg if (nargs < 1) { goto skip_optional_posonly; } - size = _PyLong_AsInt(args[0]); + size = PyLong_AsInt(args[0]); if (size == -1 && PyErr_Occurred()) { goto exit; } @@ -756,9 +756,27 @@ _io_TextIOWrapper_readline(textio *self, PyObject *const *args, Py_ssize_t nargs } PyDoc_STRVAR(_io_TextIOWrapper_seek__doc__, -"seek($self, cookie, whence=0, /)\n" +"seek($self, cookie, whence=os.SEEK_SET, /)\n" "--\n" -"\n"); +"\n" +"Set the stream position, and return the new stream position.\n" +"\n" +" cookie\n" +" Zero or an opaque number returned by tell().\n" +" whence\n" +" The relative position to seek from.\n" +"\n" +"Four operations are supported, given by the following argument\n" +"combinations:\n" +"\n" +"- seek(0, SEEK_SET): Rewind to the start of the stream.\n" +"- seek(cookie, SEEK_SET): Restore a previous position;\n" +" \'cookie\' must be a number returned by tell().\n" +"- seek(0, SEEK_END): Fast-forward to the end of the stream.\n" +"- seek(0, SEEK_CUR): Leave the current stream position unchanged.\n" +"\n" +"Any other argument combinations are invalid,\n" +"and may raise exceptions."); #define _IO_TEXTIOWRAPPER_SEEK_METHODDEF \ {"seek", _PyCFunction_CAST(_io_TextIOWrapper_seek), METH_FASTCALL, _io_TextIOWrapper_seek__doc__}, @@ -780,7 +798,7 @@ _io_TextIOWrapper_seek(textio *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - whence = _PyLong_AsInt(args[1]); + whence = PyLong_AsInt(args[1]); if (whence == -1 && PyErr_Occurred()) { goto exit; } @@ -794,7 +812,11 @@ _io_TextIOWrapper_seek(textio *self, PyObject *const *args, Py_ssize_t nargs) PyDoc_STRVAR(_io_TextIOWrapper_tell__doc__, "tell($self, /)\n" "--\n" -"\n"); +"\n" +"Return the stream position as an opaque number.\n" +"\n" +"The return value of tell() can be given as input to seek(), to restore a\n" +"previous stream position."); #define _IO_TEXTIOWRAPPER_TELL_METHODDEF \ {"tell", (PyCFunction)_io_TextIOWrapper_tell, METH_NOARGS, _io_TextIOWrapper_tell__doc__}, @@ -957,4 +979,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=e1060638b65e8a63 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=175e1723a462a722 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index cd3348dc1227cd..ecc71e552c23f4 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() #if defined(HAVE_WINDOWS_CONSOLE_IO) @@ -243,7 +243,6 @@ _io__WindowsConsoleIO_readinto(winconsoleio *self, PyTypeObject *cls, PyObject * goto exit; } if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); goto exit; } @@ -465,4 +464,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=235393758365c229 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=37febc4c96732b3b input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 39709fd2931315..8a73ea0365b7a3 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -3,21 +3,25 @@ #include "Python.h" #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH #include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "structmember.h" // PyMemberDef -#include +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() + +#include // bool +#ifdef HAVE_UNISTD_H +# include // lseek() +#endif #ifdef HAVE_SYS_TYPES_H -#include +# include #endif #ifdef HAVE_SYS_STAT_H -#include +# include #endif #ifdef HAVE_IO_H -#include +# include #endif #ifdef HAVE_FCNTL_H -#include +# include // open() #endif -#include /* For offsetof */ + #include "_iomodule.h" /* @@ -34,22 +38,23 @@ */ #ifdef MS_WINDOWS -/* can simulate truncate with Win32 API functions; see file_truncate */ -#define HAVE_FTRUNCATE -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include + // can simulate truncate with Win32 API functions; see file_truncate +# define HAVE_FTRUNCATE +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include #endif #if BUFSIZ < (8*1024) -#define SMALLCHUNK (8*1024) +# define SMALLCHUNK (8*1024) #elif (BUFSIZ >= (2 << 25)) -#error "unreasonable BUFSIZ > 64 MiB defined" +# error "unreasonable BUFSIZ > 64 MiB defined" #else -#define SMALLCHUNK BUFSIZ +# define SMALLCHUNK BUFSIZ #endif + /*[clinic input] module _io class _io.FileIO "fileio *" "clinic_state()->PyFileIO_Type" @@ -264,7 +269,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, self->fd = -1; } - fd = _PyLong_AsInt(nameobj); + fd = PyLong_AsInt(nameobj); if (fd < 0) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, @@ -393,6 +398,11 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, if (async_err) goto error; + + if (self->fd < 0) { + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + goto error; + } } else { PyObject *fdobj; @@ -412,7 +422,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, goto error; } - self->fd = _PyLong_AsInt(fdobj); + self->fd = PyLong_AsInt(fdobj); Py_DECREF(fdobj); if (self->fd < 0) { if (!PyErr_Occurred()) { @@ -424,12 +434,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, goto error; } } - fd_is_own = 1; - if (self->fd < 0) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); - goto error; - } #ifndef MS_WINDOWS if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0) @@ -1057,8 +1062,8 @@ _io_FileIO_truncate_impl(fileio *self, PyTypeObject *cls, PyObject *posobj) Py_END_ALLOW_THREADS if (ret != 0) { - Py_DECREF(posobj); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(posobj); return NULL; } @@ -1199,10 +1204,10 @@ static PyGetSetDef fileio_getsetlist[] = { }; static PyMemberDef fileio_members[] = { - {"_blksize", T_UINT, offsetof(fileio, blksize), 0}, - {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(fileio, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(fileio, dict), READONLY}, + {"_blksize", Py_T_UINT, offsetof(fileio, blksize), 0}, + {"_finalizing", Py_T_BOOL, offsetof(fileio, finalizing), 0}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(fileio, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(fileio, dict), Py_READONLY}, {NULL} }; diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index e2e8ef46adf901..4da8e5bd572d74 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -12,6 +12,8 @@ #include "pycore_call.h" // _PyObject_CallMethod() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_object.h" // _PyType_HasFeature() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() + #include // offsetof() #include "_iomodule.h" @@ -83,7 +85,9 @@ iobase_unsupported(_PyIO_State *state, const char *message) _io._IOBase.seek cls: defining_class offset: int(unused=True) + The stream position, relative to 'whence'. whence: int(unused=True, c_default='0') = os.SEEK_SET + The relative position to seek from. / Change the stream position to the given byte offset. @@ -101,7 +105,7 @@ Return the new absolute position. static PyObject * _io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, int Py_UNUSED(offset), int Py_UNUSED(whence)) -/*[clinic end generated code: output=8bd74ea6538ded53 input=8d4e6adcd08292f2]*/ +/*[clinic end generated code: output=8bd74ea6538ded53 input=74211232b363363e]*/ { _PyIO_State *state = get_io_state_by_cls(cls); return iobase_unsupported(state, "seek"); @@ -144,13 +148,9 @@ _io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, static int iobase_is_closed(PyObject *self) { - PyObject *res; - int ret; /* This gets the derived attribute, which is *not* __IOBase_closed in most cases! */ - ret = PyObject_GetOptionalAttr(self, &_Py_ID(__IOBase_closed), &res); - Py_XDECREF(res); - return ret; + return PyObject_HasAttrWithError(self, &_Py_ID(__IOBase_closed)); } /* Flush and close methods */ @@ -265,7 +265,7 @@ static PyObject * _io__IOBase_close_impl(PyObject *self) /*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ { - int rc, closed = iobase_is_closed(self); + int rc1, rc2, closed = iobase_is_closed(self); if (closed < 0) { return NULL; @@ -274,19 +274,14 @@ _io__IOBase_close_impl(PyObject *self) Py_RETURN_NONE; } - PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush)); - + rc1 = _PyFile_Flush(self); PyObject *exc = PyErr_GetRaisedException(); - rc = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True); + rc2 = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True); _PyErr_ChainExceptions1(exc); - if (rc < 0) { - Py_CLEAR(res); - } - - if (res == NULL) + if (rc1 < 0 || rc2 < 0) { return NULL; + } - Py_DECREF(res); Py_RETURN_NONE; } @@ -863,8 +858,8 @@ static PyGetSetDef iobase_getset[] = { }; static struct PyMemberDef iobase_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(iobase, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(iobase, dict), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(iobase, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(iobase, dict), Py_READONLY}, {NULL}, }; diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 1960002d405edf..1856b07108bab6 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -1002,8 +1002,8 @@ static PyGetSetDef stringio_getset[] = { }; static struct PyMemberDef stringio_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(stringio, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(stringio, dict), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(stringio, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(stringio, dict), Py_READONLY}, {NULL}, }; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index a5cf9fc397f5fe..10ef8a803c50fd 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -9,12 +9,13 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallMethod() #include "pycore_codecs.h" // _PyCodecInfo_GetIncrementalDecoder() +#include "pycore_fileutils.h" // _Py_GetLocaleEncoding() #include "pycore_interp.h" // PyInterpreterState.fs_codec #include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_fileutils.h" // _Py_GetLocaleEncoding() #include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "structmember.h" // PyMemberDef + #include "_iomodule.h" /*[clinic input] @@ -234,7 +235,7 @@ _io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, { if (errors == NULL) { - errors = Py_NewRef(&_Py_ID(strict)); + errors = &_Py_ID(strict); } else { errors = Py_NewRef(errors); @@ -1138,7 +1139,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, if (encoding == NULL && _PyRuntime.preconfig.utf8_mode) { _Py_DECLARE_STR(utf_8, "utf-8"); - self->encoding = Py_NewRef(&_Py_STR(utf_8)); + self->encoding = &_Py_STR(utf_8); } else if (encoding == NULL || (strcmp(encoding, "locale") == 0)) { self->encoding = _Py_GetLocaleEncodingObject(); @@ -1222,11 +1223,10 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, goto error; self->seekable = self->telling = r; - r = PyObject_GetOptionalAttr(buffer, &_Py_ID(read1), &res); + r = PyObject_HasAttrWithError(buffer, &_Py_ID(read1)); if (r < 0) { goto error; } - Py_XDECREF(res); self->has_read1 = r; self->encoding_start_of_stream = 0; @@ -1368,11 +1368,9 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, return NULL; } - PyObject *res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) { + if (_PyFile_Flush((PyObject *)self) < 0) { return NULL; } - Py_DECREF(res); self->b2cratio = 0; if (newline_obj != NULL && set_newline(self, newline) < 0) { @@ -1508,12 +1506,11 @@ static PyObject * _io_TextIOWrapper_detach_impl(textio *self) /*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/ { - PyObject *buffer, *res; + PyObject *buffer; CHECK_ATTACHED(self); - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) + if (_PyFile_Flush((PyObject *)self) < 0) { return NULL; - Py_DECREF(res); + } buffer = self->buffer; self->buffer = NULL; self->detached = 1; @@ -1713,10 +1710,9 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) } if (needflush) { - ret = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(flush)); - if (ret == NULL) + if (_PyFile_Flush(self->buffer) < 0) { return NULL; - Py_DECREF(ret); + } } textiowrapper_set_decoded_chars(self, NULL); @@ -2267,7 +2263,7 @@ _textiowrapper_readline(textio *self, Py_ssize_t limit) Py_CLEAR(chunks); } if (line == NULL) { - line = Py_NewRef(&_Py_STR(empty)); + line = &_Py_STR(empty); } return line; @@ -2428,13 +2424,29 @@ _textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) /*[clinic input] _io.TextIOWrapper.seek cookie as cookieObj: object - whence: int = 0 + Zero or an opaque number returned by tell(). + whence: int(c_default='0') = os.SEEK_SET + The relative position to seek from. / + +Set the stream position, and return the new stream position. + +Four operations are supported, given by the following argument +combinations: + +- seek(0, SEEK_SET): Rewind to the start of the stream. +- seek(cookie, SEEK_SET): Restore a previous position; + 'cookie' must be a number returned by tell(). +- seek(0, SEEK_END): Fast-forward to the end of the stream. +- seek(0, SEEK_CUR): Leave the current stream position unchanged. + +Any other argument combinations are invalid, +and may raise exceptions. [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) -/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/ +/*[clinic end generated code: output=0a15679764e2d04d input=0f68adcb02cf2823]*/ { PyObject *posobj; cookie_type cookie; @@ -2486,10 +2498,9 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) + if (_PyFile_Flush((PyObject *)self) < 0) { goto fail; - Py_DECREF(res); + } textiowrapper_set_decoded_chars(self, NULL); Py_CLEAR(self->snapshot); @@ -2534,10 +2545,9 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) + if (_PyFile_Flush((PyObject *)self) < 0) { goto fail; - Py_DECREF(res); + } /* The strategy of seek() is to go back to the safe start point * and replay the effect of read(chars_to_skip) from there. @@ -2624,11 +2634,16 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) /*[clinic input] _io.TextIOWrapper.tell + +Return the stream position as an opaque number. + +The return value of tell() can be given as input to seek(), to restore a +previous stream position. [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_tell_impl(textio *self) -/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/ +/*[clinic end generated code: output=4f168c08bf34ad5f input=0852d627d76fb520]*/ { PyObject *res; PyObject *posobj = NULL; @@ -2656,10 +2671,9 @@ _io_TextIOWrapper_tell_impl(textio *self) if (_textiowrapper_writeflush(self) < 0) return NULL; - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) + if (_PyFile_Flush((PyObject *)self) < 0) { goto fail; - Py_DECREF(res); + } posobj = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(tell)); if (posobj == NULL) @@ -2864,14 +2878,11 @@ static PyObject * _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) /*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/ { - PyObject *res; - CHECK_ATTACHED(self) - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) + if (_PyFile_Flush((PyObject *)self) < 0) { return NULL; - Py_DECREF(res); + } return PyObject_CallMethodOneArg(self->buffer, &_Py_ID(truncate), pos); } @@ -3055,13 +3066,9 @@ _io_TextIOWrapper_close_impl(textio *self) PyErr_Clear(); } } - res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) { + if (_PyFile_Flush((PyObject *)self) < 0) { exc = PyErr_GetRaisedException(); } - else { - Py_DECREF(res); - } res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(close)); if (exc != NULL) { @@ -3230,13 +3237,13 @@ static PyMethodDef textiowrapper_methods[] = { }; static PyMemberDef textiowrapper_members[] = { - {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY}, - {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY}, - {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY}, - {"write_through", T_BOOL, offsetof(textio, write_through), READONLY}, - {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(textio, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(textio, dict), READONLY}, + {"encoding", _Py_T_OBJECT, offsetof(textio, encoding), Py_READONLY}, + {"buffer", _Py_T_OBJECT, offsetof(textio, buffer), Py_READONLY}, + {"line_buffering", Py_T_BOOL, offsetof(textio, line_buffering), Py_READONLY}, + {"write_through", Py_T_BOOL, offsetof(textio, write_through), Py_READONLY}, + {"_finalizing", Py_T_BOOL, offsetof(textio, finalizing), 0}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(textio, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(textio, dict), Py_READONLY}, {NULL} }; diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 452b12c138fa8b..50b8818aad410b 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -9,10 +9,11 @@ #include "Python.h" #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH #include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #ifdef HAVE_WINDOWS_CONSOLE_IO -#include "structmember.h" // PyMemberDef + #ifdef HAVE_SYS_TYPES_H #include #endif @@ -280,7 +281,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, self->fd = -1; } - fd = _PyLong_AsInt(nameobj); + fd = PyLong_AsInt(nameobj); if (fd < 0) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, @@ -377,8 +378,8 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, else self->fd = _Py_open_osfhandle_noraise(handle, _O_RDONLY | _O_BINARY); if (self->fd < 0) { - CloseHandle(handle); PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + CloseHandle(handle); goto error; } } @@ -1141,10 +1142,10 @@ static PyGetSetDef winconsoleio_getsetlist[] = { }; static PyMemberDef winconsoleio_members[] = { - {"_blksize", T_UINT, offsetof(winconsoleio, blksize), 0}, - {"_finalizing", T_BOOL, offsetof(winconsoleio, finalizing), 0}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(winconsoleio, weakreflist), READONLY}, - {"__dictoffset__", T_PYSSIZET, offsetof(winconsoleio, dict), READONLY}, + {"_blksize", Py_T_UINT, offsetof(winconsoleio, blksize), 0}, + {"_finalizing", Py_T_BOOL, offsetof(winconsoleio, finalizing), 0}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(winconsoleio, weakreflist), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(winconsoleio, dict), Py_READONLY}, {NULL} }; diff --git a/Modules/_json.c b/Modules/_json.c index 2d0e30d70932bd..41495e2012f152 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -11,8 +11,8 @@ #include "Python.h" #include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "pycore_runtime.h" // _PyRuntime -#include "structmember.h" // PyMemberDef -#include "pycore_global_objects.h" // _Py_ID() + +#include "pycore_global_strings.h" // _Py_ID() #include // bool @@ -28,12 +28,12 @@ typedef struct _PyScannerObject { } PyScannerObject; static PyMemberDef scanner_members[] = { - {"strict", T_BOOL, offsetof(PyScannerObject, strict), READONLY, "strict"}, - {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"}, - {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), READONLY}, - {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"}, - {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"}, - {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"}, + {"strict", Py_T_BOOL, offsetof(PyScannerObject, strict), Py_READONLY, "strict"}, + {"object_hook", _Py_T_OBJECT, offsetof(PyScannerObject, object_hook), Py_READONLY, "object_hook"}, + {"object_pairs_hook", _Py_T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), Py_READONLY}, + {"parse_float", _Py_T_OBJECT, offsetof(PyScannerObject, parse_float), Py_READONLY, "parse_float"}, + {"parse_int", _Py_T_OBJECT, offsetof(PyScannerObject, parse_int), Py_READONLY, "parse_int"}, + {"parse_constant", _Py_T_OBJECT, offsetof(PyScannerObject, parse_constant), Py_READONLY, "parse_constant"}, {NULL} }; @@ -52,14 +52,14 @@ typedef struct _PyEncoderObject { } PyEncoderObject; static PyMemberDef encoder_members[] = { - {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"}, - {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"}, - {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"}, - {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"}, - {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"}, - {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"}, - {"sort_keys", T_BOOL, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"}, - {"skipkeys", T_BOOL, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"}, + {"markers", _Py_T_OBJECT, offsetof(PyEncoderObject, markers), Py_READONLY, "markers"}, + {"default", _Py_T_OBJECT, offsetof(PyEncoderObject, defaultfn), Py_READONLY, "default"}, + {"encoder", _Py_T_OBJECT, offsetof(PyEncoderObject, encoder), Py_READONLY, "encoder"}, + {"indent", _Py_T_OBJECT, offsetof(PyEncoderObject, indent), Py_READONLY, "indent"}, + {"key_separator", _Py_T_OBJECT, offsetof(PyEncoderObject, key_separator), Py_READONLY, "key_separator"}, + {"item_separator", _Py_T_OBJECT, offsetof(PyEncoderObject, item_separator), Py_READONLY, "item_separator"}, + {"sort_keys", Py_T_BOOL, offsetof(PyEncoderObject, sort_keys), Py_READONLY, "sort_keys"}, + {"skipkeys", Py_T_BOOL, offsetof(PyEncoderObject, skipkeys), Py_READONLY, "skipkeys"}, {NULL} }; @@ -1277,13 +1277,13 @@ _encoded_const(PyObject *obj) { /* Return the JSON string representation of None, True, False */ if (obj == Py_None) { - return Py_NewRef(&_Py_ID(null)); + return &_Py_ID(null); } else if (obj == Py_True) { - return Py_NewRef(&_Py_ID(true)); + return &_Py_ID(true); } else if (obj == Py_False) { - return Py_NewRef(&_Py_ID(false)); + return &_Py_ID(false); } else { PyErr_SetString(PyExc_ValueError, "not a const"); diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 970530facd01b0..fe8e4c5e30035b 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -10,34 +10,25 @@ This software comes with no warranty. Use at your own risk. ******************************************************************/ #include "Python.h" -#include "pycore_fileutils.h" - -#include -#include -#include -#include +#include "pycore_fileutils.h" // _Py_GetLocaleconvNumeric() +#include "pycore_pymem.h" // _PyMem_Strdup() +#include // setlocale() +#include // strlen() #ifdef HAVE_ERRNO_H -#include +# include // errno #endif - #ifdef HAVE_LANGINFO_H -#include +# include // nl_langinfo() #endif - #ifdef HAVE_LIBINTL_H -#include +# include #endif - -#ifdef HAVE_WCHAR_H -#include -#endif - -#if defined(MS_WINDOWS) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include +#ifdef MS_WINDOWS +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include #endif PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); @@ -736,8 +727,8 @@ _locale_bindtextdomain_impl(PyObject *module, const char *domain, } current_dirname = bindtextdomain(domain, dirname); if (current_dirname == NULL) { - Py_XDECREF(dirname_bytes); PyErr_SetFromErrno(PyExc_OSError); + Py_XDECREF(dirname_bytes); return NULL; } result = PyUnicode_DecodeLocale(current_dirname, NULL); @@ -844,12 +835,7 @@ _locale_exec(PyObject *module) _locale_state *state = get_locale_state(module); state->Error = PyErr_NewException("locale.Error", NULL, NULL); - if (state->Error == NULL) { - return -1; - } - Py_INCREF(get_locale_state(module)->Error); - if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) { - Py_DECREF(get_locale_state(module)->Error); + if (PyModule_AddObjectRef(module, "Error", state->Error) < 0) { return -1; } diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 257de4387c0ab9..d23a756ace887d 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -4,7 +4,10 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_ceval.h" // _PyEval_SetProfile() +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() #include "pycore_pystate.h" // _PyThreadState_GET() + #include "rotatingtree.h" /************************************************************/ diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 02a32ddccb3ed7..eb90c308d16d19 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -5,8 +5,12 @@ */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" -#include "structmember.h" // PyMemberDef + #include // free() #include @@ -1338,13 +1342,13 @@ PyDoc_STRVAR(Decompressor_unused_data_doc, "Data found after the end of the compressed stream."); static PyMemberDef Decompressor_members[] = { - {"check", T_INT, offsetof(Decompressor, check), READONLY, + {"check", Py_T_INT, offsetof(Decompressor, check), Py_READONLY, Decompressor_check_doc}, - {"eof", T_BOOL, offsetof(Decompressor, eof), READONLY, + {"eof", Py_T_BOOL, offsetof(Decompressor, eof), Py_READONLY, Decompressor_eof_doc}, - {"needs_input", T_BOOL, offsetof(Decompressor, needs_input), READONLY, + {"needs_input", Py_T_BOOL, offsetof(Decompressor, needs_input), Py_READONLY, Decompressor_needs_input_doc}, - {"unused_data", T_OBJECT_EX, offsetof(Decompressor, unused_data), READONLY, + {"unused_data", Py_T_OBJECT_EX, offsetof(Decompressor, unused_data), Py_READONLY, Decompressor_unused_data_doc}, {NULL} }; @@ -1498,15 +1502,7 @@ _lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, static int module_add_int_constant(PyObject *m, const char *name, long long value) { - PyObject *o = PyLong_FromLongLong(value); - if (o == NULL) { - return -1; - } - if (PyModule_AddObject(m, name, o) == 0) { - return 0; - } - Py_DECREF(o); - return -1; + return PyModule_Add(m, name, PyLong_FromLongLong(value)); } static int diff --git a/Modules/_multiprocessing/clinic/multiprocessing.c.h b/Modules/_multiprocessing/clinic/multiprocessing.c.h index 885cd5c2fff8ea..0ae0039a666061 100644 --- a/Modules/_multiprocessing/clinic/multiprocessing.c.h +++ b/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - #if defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_closesocket__doc__, @@ -66,7 +60,7 @@ _multiprocessing_recv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!handle && PyErr_Occurred()) { goto exit; } - size = _PyLong_AsInt(args[1]); + size = PyLong_AsInt(args[1]); if (size == -1 && PyErr_Occurred()) { goto exit; } @@ -172,4 +166,4 @@ _multiprocessing_sem_unlink(PyObject *module, PyObject *arg) #ifndef _MULTIPROCESSING_SEND_METHODDEF #define _MULTIPROCESSING_SEND_METHODDEF #endif /* !defined(_MULTIPROCESSING_SEND_METHODDEF) */ -/*[clinic end generated code: output=4a6afc67c1f5ec85 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8b91c020d4353cc5 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h index dd40662ce9902d..09dfa11da23b86 100644 --- a/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - #if defined(HAVE_SHM_OPEN) PyDoc_STRVAR(_posixshmem_shm_open__doc__, @@ -68,14 +67,14 @@ _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, goto exit; } path = args[0]; - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } if (!noptargs) { goto skip_optional_pos; } - mode = _PyLong_AsInt(args[2]); + mode = PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -166,4 +165,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=9b67f98885757bc4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f356903a281d857 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/semaphore.c.h b/Modules/_multiprocessing/clinic/semaphore.c.h index 35347169bc1591..a4357376ee1292 100644 --- a/Modules/_multiprocessing/clinic/semaphore.c.h +++ b/Modules/_multiprocessing/clinic/semaphore.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - #if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, @@ -250,15 +249,15 @@ _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!fastargs) { goto exit; } - kind = _PyLong_AsInt(fastargs[0]); + kind = PyLong_AsInt(fastargs[0]); if (kind == -1 && PyErr_Occurred()) { goto exit; } - value = _PyLong_AsInt(fastargs[1]); + value = PyLong_AsInt(fastargs[1]); if (value == -1 && PyErr_Occurred()) { goto exit; } - maxvalue = _PyLong_AsInt(fastargs[2]); + maxvalue = PyLong_AsInt(fastargs[2]); if (maxvalue == -1 && PyErr_Occurred()) { goto exit; } @@ -542,4 +541,4 @@ _multiprocessing_SemLock___exit__(SemLockObject *self, PyObject *const *args, Py #ifndef _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #endif /* !defined(_MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF) */ -/*[clinic end generated code: output=dae57a702cc01512 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e8ea65f8cba8e173 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index 8f9daa5c3de0cc..2e6d8eb68c0243 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -14,16 +14,17 @@ class HANDLE_converter(CConverter): type = "HANDLE" format_unit = '"F_HANDLE"' - def parse_arg(self, argname, displayname): - return """ + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" {paramname} = PyLong_AsVoidPtr({argname}); if (!{paramname} && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3cf0318efc6a8772]*/ /*[clinic input] module _multiprocessing @@ -266,8 +267,7 @@ multiprocessing_exec(PyObject *module) ADD_FLAG(HAVE_BROKEN_SEM_UNLINK); #endif - if (PyModule_AddObject(module, "flags", flags) < 0) { - Py_DECREF(flags); + if (PyModule_Add(module, "flags", flags) < 0) { return -1; } diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h index 47257fd5d9fb26..099004b437828e 100644 --- a/Modules/_multiprocessing/multiprocessing.h +++ b/Modules/_multiprocessing/multiprocessing.h @@ -1,9 +1,18 @@ #ifndef MULTIPROCESSING_H #define MULTIPROCESSING_H +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "structmember.h" #include "pythread.h" +#include "pycore_signal.h" // _PyOS_IsMainThread() + +#ifndef MS_WINDOWS +# include // sysconf() +#endif /* * Platform includes and definitions diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index 897b8db7110a41..f8f2afda28d06d 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -9,6 +9,10 @@ #include "multiprocessing.h" +#ifdef HAVE_SYS_TIME_H +# include // gettimeofday() +#endif + #ifdef HAVE_MP_SEMAPHORE enum { RECURSIVE_MUTEX, SEMAPHORE }; @@ -516,12 +520,12 @@ _multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, return result; failure: - if (handle != SEM_FAILED) - SEM_CLOSE(handle); - PyMem_Free(name_copy); if (!PyErr_Occurred()) { _PyMp_SetError(NULL, MP_STANDARD_ERROR); } + if (handle != SEM_FAILED) + SEM_CLOSE(handle); + PyMem_Free(name_copy); return NULL; } @@ -556,8 +560,9 @@ _multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, if (name != NULL) { handle = sem_open(name, 0); if (handle == SEM_FAILED) { + PyErr_SetFromErrno(PyExc_OSError); PyMem_Free(name_copy); - return PyErr_SetFromErrno(PyExc_OSError); + return NULL; } } #endif @@ -734,13 +739,13 @@ static PyMethodDef semlock_methods[] = { */ static PyMemberDef semlock_members[] = { - {"handle", T_SEM_HANDLE, offsetof(SemLockObject, handle), READONLY, + {"handle", T_SEM_HANDLE, offsetof(SemLockObject, handle), Py_READONLY, ""}, - {"kind", T_INT, offsetof(SemLockObject, kind), READONLY, + {"kind", Py_T_INT, offsetof(SemLockObject, kind), Py_READONLY, ""}, - {"maxvalue", T_INT, offsetof(SemLockObject, maxvalue), READONLY, + {"maxvalue", Py_T_INT, offsetof(SemLockObject, maxvalue), Py_READONLY, ""}, - {"name", T_STRING, offsetof(SemLockObject, name), READONLY, + {"name", Py_T_STRING, offsetof(SemLockObject, name), Py_READONLY, ""}, {NULL} }; diff --git a/Modules/_opcode.c b/Modules/_opcode.c index daabdce1655777..dac9c019b249e9 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -1,7 +1,12 @@ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "compile.h" #include "opcode.h" #include "internal/pycore_code.h" +#include "internal/pycore_intrinsics.h" /*[clinic input] module _opcode @@ -220,6 +225,129 @@ _opcode_get_specialization_stats_impl(PyObject *module) #endif } +/*[clinic input] + +_opcode.get_nb_ops + +Return array of symbols of binary ops. + +Indexed by the BINARY_OP oparg value. +[clinic start generated code]*/ + +static PyObject * +_opcode_get_nb_ops_impl(PyObject *module) +/*[clinic end generated code: output=d997d306cc15426f input=9462fc544c823176]*/ +{ + PyObject *list = PyList_New(NB_OPARG_LAST + 1); + if (list == NULL) { + return NULL; + } +#define ADD_NB_OP(NUM, STR) \ + do { \ + PyObject *pair = Py_BuildValue( \ + "NN", PyUnicode_FromString(#NUM), PyUnicode_FromString(STR)); \ + if (pair == NULL) { \ + Py_DECREF(list); \ + return NULL; \ + } \ + PyList_SET_ITEM(list, (NUM), pair); \ + } while(0); + + ADD_NB_OP(NB_ADD, "+"); + ADD_NB_OP(NB_AND, "&"); + ADD_NB_OP(NB_FLOOR_DIVIDE, "//"); + ADD_NB_OP(NB_LSHIFT, "<<"); + ADD_NB_OP(NB_MATRIX_MULTIPLY, "@"); + ADD_NB_OP(NB_MULTIPLY, "*"); + ADD_NB_OP(NB_REMAINDER, "%"); + ADD_NB_OP(NB_OR, "|"); + ADD_NB_OP(NB_POWER, "**"); + ADD_NB_OP(NB_RSHIFT, ">>"); + ADD_NB_OP(NB_SUBTRACT, "-"); + ADD_NB_OP(NB_TRUE_DIVIDE, "/"); + ADD_NB_OP(NB_XOR, "^"); + ADD_NB_OP(NB_INPLACE_ADD, "+="); + ADD_NB_OP(NB_INPLACE_AND, "&="); + ADD_NB_OP(NB_INPLACE_FLOOR_DIVIDE, "//="); + ADD_NB_OP(NB_INPLACE_LSHIFT, "<<="); + ADD_NB_OP(NB_INPLACE_MATRIX_MULTIPLY, "@="); + ADD_NB_OP(NB_INPLACE_MULTIPLY, "*="); + ADD_NB_OP(NB_INPLACE_REMAINDER, "%="); + ADD_NB_OP(NB_INPLACE_OR, "|="); + ADD_NB_OP(NB_INPLACE_POWER, "**="); + ADD_NB_OP(NB_INPLACE_RSHIFT, ">>="); + ADD_NB_OP(NB_INPLACE_SUBTRACT, "-="); + ADD_NB_OP(NB_INPLACE_TRUE_DIVIDE, "/="); + ADD_NB_OP(NB_INPLACE_XOR, "^="); + +#undef ADD_NB_OP + + for(int i = 0; i <= NB_OPARG_LAST; i++) { + if (PyList_GET_ITEM(list, i) == NULL) { + Py_DECREF(list); + PyErr_Format(PyExc_ValueError, + "Missing initialization for NB_OP %d", + i); + return NULL; + } + } + return list; +} + +/*[clinic input] + +_opcode.get_intrinsic1_descs + +Return a list of names of the unary intrinsics. +[clinic start generated code]*/ + +static PyObject * +_opcode_get_intrinsic1_descs_impl(PyObject *module) +/*[clinic end generated code: output=bd1ddb6b4447d18b input=13b51c712618459b]*/ +{ + PyObject *list = PyList_New(MAX_INTRINSIC_1 + 1); + if (list == NULL) { + return NULL; + } + for (int i=0; i <= MAX_INTRINSIC_1; i++) { + PyObject *name = PyUnstable_GetUnaryIntrinsicName(i); + if (name == NULL) { + Py_DECREF(list); + return NULL; + } + PyList_SET_ITEM(list, i, name); + } + return list; +} + + +/*[clinic input] + +_opcode.get_intrinsic2_descs + +Return a list of names of the binary intrinsics. +[clinic start generated code]*/ + +static PyObject * +_opcode_get_intrinsic2_descs_impl(PyObject *module) +/*[clinic end generated code: output=40e62bc27584c8a0 input=e83068f249f5471b]*/ +{ + PyObject *list = PyList_New(MAX_INTRINSIC_2 + 1); + if (list == NULL) { + return NULL; + } + for (int i=0; i <= MAX_INTRINSIC_2; i++) { + PyObject *name = PyUnstable_GetBinaryIntrinsicName(i); + if (name == NULL) { + Py_DECREF(list); + return NULL; + } + PyList_SET_ITEM(list, i, name); + } + return list; +} + + static PyMethodDef opcode_functions[] = { _OPCODE_STACK_EFFECT_METHODDEF @@ -232,10 +360,22 @@ opcode_functions[] = { _OPCODE_HAS_LOCAL_METHODDEF _OPCODE_HAS_EXC_METHODDEF _OPCODE_GET_SPECIALIZATION_STATS_METHODDEF + _OPCODE_GET_NB_OPS_METHODDEF + _OPCODE_GET_INTRINSIC1_DESCS_METHODDEF + _OPCODE_GET_INTRINSIC2_DESCS_METHODDEF {NULL, NULL, 0, NULL} }; +int +_opcode_exec(PyObject *m) { + if (PyModule_AddIntMacro(m, ENABLE_SPECIALIZATION) < 0) { + return -1; + } + return 0; +} + static PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, _opcode_exec}, {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_operator.c b/Modules/_operator.c index 108f45fb6dad93..1f6496d381adac 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -3,7 +3,7 @@ #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_runtime.h" // _Py_ID() -#include "structmember.h" // PyMemberDef + #include "clinic/_operator.c.h" typedef struct { @@ -1153,7 +1153,7 @@ static PyMethodDef itemgetter_methods[] = { }; static PyMemberDef itemgetter_members[] = { - {"__vectorcalloffset__", T_PYSSIZET, offsetof(itemgetterobject, vectorcall), READONLY}, + {"__vectorcalloffset__", Py_T_PYSSIZET, offsetof(itemgetterobject, vectorcall), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -1508,7 +1508,7 @@ static PyMethodDef attrgetter_methods[] = { }; static PyMemberDef attrgetter_members[] = { - {"__vectorcalloffset__", T_PYSSIZET, offsetof(attrgetterobject, vectorcall), READONLY}, + {"__vectorcalloffset__", Py_T_PYSSIZET, offsetof(attrgetterobject, vectorcall), Py_READONLY}, {NULL} /* Sentinel*/ }; @@ -1549,10 +1549,77 @@ static PyType_Spec attrgetter_type_spec = { typedef struct { PyObject_HEAD PyObject *name; - PyObject *args; + PyObject *xargs; // reference to arguments passed in constructor PyObject *kwds; + PyObject **vectorcall_args; /* Borrowed references */ + PyObject *vectorcall_kwnames; + vectorcallfunc vectorcall; } methodcallerobject; +static int _methodcaller_initialize_vectorcall(methodcallerobject* mc) +{ + PyObject* args = mc->xargs; + PyObject* kwds = mc->kwds; + + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + assert(nargs > 0); + mc->vectorcall_args = PyMem_Calloc( + nargs + (kwds ? PyDict_Size(kwds) : 0), + sizeof(PyObject*)); + if (!mc->vectorcall_args) { + PyErr_NoMemory(); + return -1; + } + /* The first item of vectorcall_args will be filled with obj later */ + if (nargs > 1) { + memcpy(mc->vectorcall_args, PySequence_Fast_ITEMS(args), + nargs * sizeof(PyObject*)); + } + if (kwds) { + const Py_ssize_t nkwds = PyDict_Size(kwds); + + mc->vectorcall_kwnames = PyTuple_New(nkwds); + if (!mc->vectorcall_kwnames) { + return -1; + } + Py_ssize_t i = 0, ppos = 0; + PyObject* key, * value; + while (PyDict_Next(kwds, &ppos, &key, &value)) { + PyTuple_SET_ITEM(mc->vectorcall_kwnames, i, Py_NewRef(key)); + mc->vectorcall_args[nargs + i] = value; // borrowed reference + ++i; + } + } + else { + mc->vectorcall_kwnames = NULL; + } + return 1; +} + + +static PyObject * +methodcaller_vectorcall( + methodcallerobject *mc, PyObject *const *args, size_t nargsf, PyObject* kwnames) +{ + if (!_PyArg_CheckPositional("methodcaller", PyVectorcall_NARGS(nargsf), 1, 1) + || !_PyArg_NoKwnames("methodcaller", kwnames)) { + return NULL; + } + if (mc->vectorcall_args == NULL) { + if (_methodcaller_initialize_vectorcall(mc) < 0) { + return NULL; + } + } + + assert(mc->vectorcall_args != 0); + mc->vectorcall_args[0] = args[0]; + return PyObject_VectorcallMethod( + mc->name, mc->vectorcall_args, + (PyTuple_GET_SIZE(mc->xargs)) | PY_VECTORCALL_ARGUMENTS_OFFSET, + mc->vectorcall_kwnames); +} + + /* AC 3.5: variable number of arguments, not currently support by AC */ static PyObject * methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1580,30 +1647,32 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - name = PyTuple_GET_ITEM(args, 0); Py_INCREF(name); PyUnicode_InternInPlace(&name); mc->name = name; + mc->xargs = Py_XNewRef(args); // allows us to use borrowed references mc->kwds = Py_XNewRef(kwds); + mc->vectorcall_args = 0; - mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); - if (mc->args == NULL) { - Py_DECREF(mc); - return NULL; - } + + mc->vectorcall = (vectorcallfunc)methodcaller_vectorcall; PyObject_GC_Track(mc); return (PyObject *)mc; } -static int +static void methodcaller_clear(methodcallerobject *mc) { Py_CLEAR(mc->name); - Py_CLEAR(mc->args); + Py_CLEAR(mc->xargs); Py_CLEAR(mc->kwds); - return 0; + if (mc->vectorcall_args != NULL) { + PyMem_Free(mc->vectorcall_args); + mc->vectorcall_args = 0; + Py_CLEAR(mc->vectorcall_kwnames); + } } static void @@ -1611,7 +1680,7 @@ methodcaller_dealloc(methodcallerobject *mc) { PyTypeObject *tp = Py_TYPE(mc); PyObject_GC_UnTrack(mc); - (void)methodcaller_clear(mc); + methodcaller_clear(mc); tp->tp_free(mc); Py_DECREF(tp); } @@ -1620,7 +1689,7 @@ static int methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg) { Py_VISIT(mc->name); - Py_VISIT(mc->args); + Py_VISIT(mc->xargs); Py_VISIT(mc->kwds); Py_VISIT(Py_TYPE(mc)); return 0; @@ -1639,7 +1708,16 @@ methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw) method = PyObject_GetAttr(obj, mc->name); if (method == NULL) return NULL; - result = PyObject_Call(method, mc->args, mc->kwds); + + + PyObject *cargs = PyTuple_GetSlice(mc->xargs, 1, PyTuple_GET_SIZE(mc->xargs)); + if (cargs == NULL) { + Py_DECREF(method); + return NULL; + } + + result = PyObject_Call(method, cargs, mc->kwds); + Py_DECREF(cargs); Py_DECREF(method); return result; } @@ -1657,7 +1735,7 @@ methodcaller_repr(methodcallerobject *mc) } numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0; - numposargs = PyTuple_GET_SIZE(mc->args); + numposargs = PyTuple_GET_SIZE(mc->xargs) - 1; numtotalargs = numposargs + numkwdargs; if (numtotalargs == 0) { @@ -1673,7 +1751,7 @@ methodcaller_repr(methodcallerobject *mc) } for (i = 0; i < numposargs; ++i) { - PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i)); + PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->xargs, i+1)); if (onerepr == NULL) goto done; PyTuple_SET_ITEM(argreprs, i, onerepr); @@ -1723,17 +1801,16 @@ methodcaller_repr(methodcallerobject *mc) static PyObject * methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) { - PyObject *newargs; if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) { Py_ssize_t i; - Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args); - newargs = PyTuple_New(1 + callargcount); + Py_ssize_t newarg_size = PyTuple_GET_SIZE(mc->xargs); + PyObject *newargs = PyTuple_New(newarg_size); if (newargs == NULL) return NULL; PyTuple_SET_ITEM(newargs, 0, Py_NewRef(mc->name)); - for (i = 0; i < callargcount; ++i) { - PyObject *arg = PyTuple_GET_ITEM(mc->args, i); - PyTuple_SET_ITEM(newargs, i + 1, Py_NewRef(arg)); + for (i = 1; i < newarg_size; ++i) { + PyObject *arg = PyTuple_GET_ITEM(mc->xargs, i); + PyTuple_SET_ITEM(newargs, i, Py_NewRef(arg)); } return Py_BuildValue("ON", Py_TYPE(mc), newargs); } @@ -1751,7 +1828,12 @@ methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds); Py_DECREF(partial); - return Py_BuildValue("NO", constructor, mc->args); + PyObject *args = PyTuple_GetSlice(mc->xargs, 1, PyTuple_GET_SIZE(mc->xargs)); + if (!args) { + Py_DECREF(constructor); + return NULL; + } + return Py_BuildValue("NO", constructor, args); } } @@ -1760,6 +1842,12 @@ static PyMethodDef methodcaller_methods[] = { reduce_doc}, {NULL} }; + +static PyMemberDef methodcaller_members[] = { + {"__vectorcalloffset__", Py_T_PYSSIZET, offsetof(methodcallerobject, vectorcall), Py_READONLY}, + {NULL} +}; + PyDoc_STRVAR(methodcaller_doc, "methodcaller(name, /, *args, **kwargs)\n--\n\n\ Return a callable object that calls the given method on its operand.\n\ @@ -1774,6 +1862,7 @@ static PyType_Slot methodcaller_type_slots[] = { {Py_tp_traverse, methodcaller_traverse}, {Py_tp_clear, methodcaller_clear}, {Py_tp_methods, methodcaller_methods}, + {Py_tp_members, methodcaller_members}, {Py_tp_new, methodcaller_new}, {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_repr, methodcaller_repr}, @@ -1785,7 +1874,7 @@ static PyType_Spec methodcaller_type_spec = { .basicsize = sizeof(methodcallerobject), .itemsize = 0, .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_IMMUTABLETYPE), .slots = methodcaller_type_slots, }; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index ea44b494cdd7cd..a3cf34699ba509 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -11,13 +11,17 @@ #include "Python.h" #include "pycore_bytesobject.h" // _PyBytesWriter #include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_long.h" // _PyLong_AsByteArray() #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyNone_Type #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_runtime.h" // _Py_ID() -#include "structmember.h" // PyMemberDef +#include "pycore_setobject.h" // _PySet_NextEntry() +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include // strtol() + PyDoc_STRVAR(pickle_module_doc, "Optimized C implementation for the Python pickle module."); @@ -2027,8 +2031,7 @@ whichmodule(PyObject *global, PyObject *dotted_path) } /* If no module is found, use __main__. */ - module_name = &_Py_ID(__main__); - return Py_NewRef(module_name); + return &_Py_ID(__main__); } /* fast_save_enter() and fast_save_leave() are guards against recursive @@ -5072,9 +5075,9 @@ Pickler_set_persid(PicklerObject *self, PyObject *value, void *Py_UNUSED(ignored } static PyMemberDef Pickler_members[] = { - {"bin", T_INT, offsetof(PicklerObject, bin)}, - {"fast", T_INT, offsetof(PicklerObject, fast)}, - {"dispatch_table", T_OBJECT_EX, offsetof(PicklerObject, dispatch_table)}, + {"bin", Py_T_INT, offsetof(PicklerObject, bin)}, + {"fast", Py_T_INT, offsetof(PicklerObject, fast)}, + {"dispatch_table", Py_T_OBJECT_EX, offsetof(PicklerObject, dispatch_table)}, {NULL} }; @@ -5796,14 +5799,13 @@ instantiate(PyObject *cls, PyObject *args) into a newly created tuple. */ assert(PyTuple_Check(args)); if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) { - PyObject *func; - if (PyObject_GetOptionalAttr(cls, &_Py_ID(__getinitargs__), &func) < 0) { + int rc = PyObject_HasAttrWithError(cls, &_Py_ID(__getinitargs__)); + if (rc < 0) { return NULL; } - if (func == NULL) { + if (!rc) { return PyObject_CallMethodOneArg(cls, &_Py_ID(__new__), cls); } - Py_DECREF(func); } return PyObject_CallObject(cls, args); } diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index ac2b0d4f55468c..2898eedc3e3a8f 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -8,28 +8,28 @@ #include "pycore_pystate.h" #include "pycore_signal.h" // _Py_RestoreSignals() #if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE +# define _GNU_SOURCE #endif -#include -#include +#include // close() +#include // fcntl() #ifdef HAVE_SYS_TYPES_H -#include +# include #endif #if defined(HAVE_SYS_STAT_H) -#include +# include // stat() #endif #ifdef HAVE_SYS_SYSCALL_H -#include +# include #endif #if defined(HAVE_SYS_RESOURCE_H) -#include +# include #endif #ifdef HAVE_DIRENT_H -#include +# include // opendir() +#endif +#if defined(HAVE_SETGROUPS) +# include // setgroups() #endif -#ifdef HAVE_GRP_H -#include -#endif /* HAVE_GRP_H */ #include "posixmodule.h" @@ -87,15 +87,16 @@ class pid_t_converter(CConverter): type = 'pid_t' format_unit = '" _Py_PARSE_PID "' - def parse_arg(self, argname, displayname): - return """ + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" {paramname} = PyLong_AsPid({argname}); if ({paramname} == -1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=c94349aa1aad151d]*/ #include "clinic/_posixsubprocess.c.h" diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 69cc05135c2a72..b4bafb375c999d 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -3,9 +3,10 @@ #endif #include "Python.h" +#include "pycore_ceval.h" // _PyEval_MakePendingCalls() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_time.h" // _PyTime_t -#include "structmember.h" // PyMemberDef + #include // offsetof() typedef struct { @@ -373,7 +374,7 @@ static PyMethodDef simplequeue_methods[] = { }; static struct PyMemberDef simplequeue_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(simplequeueobject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(simplequeueobject, weakreflist), Py_READONLY}, {NULL}, }; diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 7daa1f9327966f..d41093c8806476 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -71,15 +71,18 @@ #endif #include "Python.h" +#include "pycore_long.h" // _PyLong_AsByteArray() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pylifecycle.h" // _PyOS_URandomNonblock() -#include "pycore_runtime.h" + +#ifdef HAVE_UNISTD_H +# include // getpid() +#endif #ifdef HAVE_PROCESS_H # include // getpid() #endif - #ifdef MS_WINDOWS -# include +# include // GetCurrentProcessId() #endif /* Period parameters -- These are all magic. Don't change. */ diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index 0df0324df55f7d..6cc09088bdc869 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -249,16 +249,8 @@ static struct PyModuleDef _scproxy_module = { .m_slots = _scproxy_slots, }; -#ifdef __cplusplus -extern "C" { -#endif - PyMODINIT_FUNC PyInit__scproxy(void) { return PyModuleDef_Init(&_scproxy_module); } - -#ifdef __cplusplus -} -#endif diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c index 989d9a83b590ca..f099020c5f4e6f 100644 --- a/Modules/_sqlite/blob.c +++ b/Modules/_sqlite/blob.c @@ -577,7 +577,7 @@ static PyMethodDef blob_methods[] = { }; static struct PyMemberDef blob_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Blob, in_weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(pysqlite_Blob, in_weakreflist), Py_READONLY}, {NULL}, }; diff --git a/Modules/_sqlite/clinic/_sqlite3.connect.c.h b/Modules/_sqlite/clinic/_sqlite3.connect.c.h new file mode 100644 index 00000000000000..eceb5a7bf23673 --- /dev/null +++ b/Modules/_sqlite/clinic/_sqlite3.connect.c.h @@ -0,0 +1,30 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + +PyDoc_STRVAR(pysqlite_connect__doc__, +"connect($module, /, database, timeout=5.0, detect_types=0,\n" +" isolation_level=\'\', check_same_thread=True,\n" +" factory=ConnectionType, cached_statements=128, uri=False, *,\n" +" autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL)\n" +"--\n" +"\n" +"Open a connection to the SQLite database file \'database\'.\n" +"\n" +"You can use \":memory:\" to open a database connection to a database that\n" +"resides in RAM instead of on disk.\n" +"\n" +"Note: Passing more than 1 positional argument to _sqlite3.connect() is\n" +"deprecated. Parameters \'timeout\', \'detect_types\', \'isolation_level\',\n" +"\'check_same_thread\', \'factory\', \'cached_statements\' and \'uri\' will\n" +"become keyword-only parameters in Python 3.15.\n" +""); + +#define PYSQLITE_CONNECT_METHODDEF \ + {"connect", _PyCFunction_CAST(pysqlite_connect), METH_FASTCALL|METH_KEYWORDS, pysqlite_connect__doc__}, +/*[clinic end generated code: output=03bd99542e3aec9d input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/blob.c.h b/Modules/_sqlite/clinic/blob.c.h index f3d8a35be46138..e7c60264722f7b 100644 --- a/Modules/_sqlite/clinic/blob.c.h +++ b/Modules/_sqlite/clinic/blob.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(blob_close__doc__, "close($self, /)\n" "--\n" @@ -57,7 +51,7 @@ blob_read(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - length = _PyLong_AsInt(args[0]); + length = PyLong_AsInt(args[0]); if (length == -1 && PyErr_Occurred()) { goto exit; } @@ -133,14 +127,14 @@ blob_seek(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { goto exit; } - offset = _PyLong_AsInt(args[0]); + offset = PyLong_AsInt(args[0]); if (offset == -1 && PyErr_Occurred()) { goto exit; } if (nargs < 2) { goto skip_optional; } - origin = _PyLong_AsInt(args[1]); + origin = PyLong_AsInt(args[1]); if (origin == -1 && PyErr_Occurred()) { goto exit; } @@ -219,4 +213,4 @@ blob_exit(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=ad6a402f70e85977 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8bfd79ab12ac5385 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index e869d7d9e9384c..fcc657799dfaf0 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - static int pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, double timeout, int detect_types, @@ -16,6 +15,17 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, int cache_size, int uri, enum autocommit_mode autocommit); +// Emit compiler warnings when we get to Python 3.15. +#if PY_VERSION_HEX >= 0x030f00C0 +# error "Update the clinic input of '_sqlite3.Connection.__init__'." +#elif PY_VERSION_HEX >= 0x030f00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_sqlite3.Connection.__init__'.") +# else +# warning "Update the clinic input of '_sqlite3.Connection.__init__'." +# endif +#endif + static int pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -59,6 +69,17 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) int uri = 0; enum autocommit_mode autocommit = LEGACY_TRANSACTION_CONTROL; + if (nargs > 1 && nargs <= 8) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to _sqlite3.Connection()" + " is deprecated. Parameters 'timeout', 'detect_types', " + "'isolation_level', 'check_same_thread', 'factory', " + "'cached_statements' and 'uri' will become keyword-only " + "parameters in Python 3.15.", 1)) + { + goto exit; + } + } fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 8, 0, argsbuf); if (!fastargs) { goto exit; @@ -83,7 +104,7 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - detect_types = _PyLong_AsInt(fastargs[2]); + detect_types = PyLong_AsInt(fastargs[2]); if (detect_types == -1 && PyErr_Occurred()) { goto exit; } @@ -115,7 +136,7 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[6]) { - cache_size = _PyLong_AsInt(fastargs[6]); + cache_size = PyLong_AsInt(fastargs[6]); if (cache_size == -1 && PyErr_Occurred()) { goto exit; } @@ -396,7 +417,12 @@ PyDoc_STRVAR(pysqlite_connection_create_function__doc__, "create_function($self, /, name, narg, func, *, deterministic=False)\n" "--\n" "\n" -"Creates a new function."); +"Creates a new function.\n" +"\n" +"Note: Passing keyword arguments \'name\', \'narg\' and \'func\' to\n" +"_sqlite3.Connection.create_function() is deprecated. Parameters\n" +"\'name\', \'narg\' and \'func\' will become positional-only in Python 3.15.\n" +""); #define PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF \ {"create_function", _PyCFunction_CAST(pysqlite_connection_create_function), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_function__doc__}, @@ -407,6 +433,17 @@ pysqlite_connection_create_function_impl(pysqlite_Connection *self, int narg, PyObject *func, int deterministic); +// Emit compiler warnings when we get to Python 3.15. +#if PY_VERSION_HEX >= 0x030f00C0 +# error "Update the clinic input of '_sqlite3.Connection.create_function'." +#elif PY_VERSION_HEX >= 0x030f00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_sqlite3.Connection.create_function'.") +# else +# warning "Update the clinic input of '_sqlite3.Connection.create_function'." +# endif +#endif + static PyObject * pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { @@ -447,6 +484,16 @@ pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls if (!args) { goto exit; } + if (nargs < 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'name', 'narg' and 'func' to " + "_sqlite3.Connection.create_function() is deprecated. Parameters " + "'name', 'narg' and 'func' will become positional-only in Python " + "3.15.", 1)) + { + goto exit; + } + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("create_function", "argument 'name'", "str", args[0]); goto exit; @@ -460,7 +507,7 @@ pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - narg = _PyLong_AsInt(args[1]); + narg = PyLong_AsInt(args[1]); if (narg == -1 && PyErr_Occurred()) { goto exit; } @@ -543,7 +590,7 @@ create_window_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *c PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - num_params = _PyLong_AsInt(args[1]); + num_params = PyLong_AsInt(args[1]); if (num_params == -1 && PyErr_Occurred()) { goto exit; } @@ -560,7 +607,13 @@ PyDoc_STRVAR(pysqlite_connection_create_aggregate__doc__, "create_aggregate($self, /, name, n_arg, aggregate_class)\n" "--\n" "\n" -"Creates a new aggregate."); +"Creates a new aggregate.\n" +"\n" +"Note: Passing keyword arguments \'name\', \'n_arg\' and \'aggregate_class\'\n" +"to _sqlite3.Connection.create_aggregate() is deprecated. Parameters\n" +"\'name\', \'n_arg\' and \'aggregate_class\' will become positional-only in\n" +"Python 3.15.\n" +""); #define PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF \ {"create_aggregate", _PyCFunction_CAST(pysqlite_connection_create_aggregate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_aggregate__doc__}, @@ -571,6 +624,17 @@ pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, const char *name, int n_arg, PyObject *aggregate_class); +// Emit compiler warnings when we get to Python 3.15. +#if PY_VERSION_HEX >= 0x030f00C0 +# error "Update the clinic input of '_sqlite3.Connection.create_aggregate'." +#elif PY_VERSION_HEX >= 0x030f00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_sqlite3.Connection.create_aggregate'.") +# else +# warning "Update the clinic input of '_sqlite3.Connection.create_aggregate'." +# endif +#endif + static PyObject * pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { @@ -609,6 +673,16 @@ pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cl if (!args) { goto exit; } + if (nargs < 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'name', 'n_arg' and 'aggregate_class' " + "to _sqlite3.Connection.create_aggregate() is deprecated. " + "Parameters 'name', 'n_arg' and 'aggregate_class' will become " + "positional-only in Python 3.15.", 1)) + { + goto exit; + } + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("create_aggregate", "argument 'name'", "str", args[0]); goto exit; @@ -622,7 +696,7 @@ pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cl PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - n_arg = _PyLong_AsInt(args[1]); + n_arg = PyLong_AsInt(args[1]); if (n_arg == -1 && PyErr_Occurred()) { goto exit; } @@ -637,7 +711,12 @@ PyDoc_STRVAR(pysqlite_connection_set_authorizer__doc__, "set_authorizer($self, /, authorizer_callback)\n" "--\n" "\n" -"Sets authorizer callback."); +"Set authorizer callback.\n" +"\n" +"Note: Passing keyword argument \'authorizer_callback\' to\n" +"_sqlite3.Connection.set_authorizer() is deprecated. Parameter\n" +"\'authorizer_callback\' will become positional-only in Python 3.15.\n" +""); #define PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF \ {"set_authorizer", _PyCFunction_CAST(pysqlite_connection_set_authorizer), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_authorizer__doc__}, @@ -647,13 +726,24 @@ pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable); +// Emit compiler warnings when we get to Python 3.15. +#if PY_VERSION_HEX >= 0x030f00C0 +# error "Update the clinic input of '_sqlite3.Connection.set_authorizer'." +#elif PY_VERSION_HEX >= 0x030f00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_sqlite3.Connection.set_authorizer'.") +# else +# warning "Update the clinic input of '_sqlite3.Connection.set_authorizer'." +# endif +#endif + static PyObject * pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 1 + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -683,6 +773,16 @@ pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyTypeObject *cls, if (!args) { goto exit; } + if (nargs < 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'authorizer_callback' to " + "_sqlite3.Connection.set_authorizer() is deprecated. Parameter " + "'authorizer_callback' will become positional-only in Python " + "3.15.", 1)) + { + goto exit; + } + } callable = args[0]; return_value = pysqlite_connection_set_authorizer_impl(self, cls, callable); @@ -694,7 +794,22 @@ PyDoc_STRVAR(pysqlite_connection_set_progress_handler__doc__, "set_progress_handler($self, /, progress_handler, n)\n" "--\n" "\n" -"Sets progress handler callback."); +"Set progress handler callback.\n" +"\n" +" progress_handler\n" +" A callable that takes no arguments.\n" +" If the callable returns non-zero, the current query is terminated,\n" +" and an exception is raised.\n" +" n\n" +" The number of SQLite virtual machine instructions that are\n" +" executed between invocations of \'progress_handler\'.\n" +"\n" +"If \'progress_handler\' is None or \'n\' is 0, the progress handler is disabled.\n" +"\n" +"Note: Passing keyword argument \'progress_handler\' to\n" +"_sqlite3.Connection.set_progress_handler() is deprecated. Parameter\n" +"\'progress_handler\' will become positional-only in Python 3.15.\n" +""); #define PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF \ {"set_progress_handler", _PyCFunction_CAST(pysqlite_connection_set_progress_handler), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__}, @@ -704,13 +819,24 @@ pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable, int n); +// Emit compiler warnings when we get to Python 3.15. +#if PY_VERSION_HEX >= 0x030f00C0 +# error "Update the clinic input of '_sqlite3.Connection.set_progress_handler'." +#elif PY_VERSION_HEX >= 0x030f00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_sqlite3.Connection.set_progress_handler'.") +# else +# warning "Update the clinic input of '_sqlite3.Connection.set_progress_handler'." +# endif +#endif + static PyObject * pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 2 + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -741,8 +867,18 @@ pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyTypeObject if (!args) { goto exit; } + if (nargs < 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'progress_handler' to " + "_sqlite3.Connection.set_progress_handler() is deprecated. " + "Parameter 'progress_handler' will become positional-only in " + "Python 3.15.", 1)) + { + goto exit; + } + } callable = args[0]; - n = _PyLong_AsInt(args[1]); + n = PyLong_AsInt(args[1]); if (n == -1 && PyErr_Occurred()) { goto exit; } @@ -756,7 +892,12 @@ PyDoc_STRVAR(pysqlite_connection_set_trace_callback__doc__, "set_trace_callback($self, /, trace_callback)\n" "--\n" "\n" -"Sets a trace callback called for each SQL statement (passed as unicode)."); +"Set a trace callback called for each SQL statement (passed as unicode).\n" +"\n" +"Note: Passing keyword argument \'trace_callback\' to\n" +"_sqlite3.Connection.set_trace_callback() is deprecated. Parameter\n" +"\'trace_callback\' will become positional-only in Python 3.15.\n" +""); #define PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF \ {"set_trace_callback", _PyCFunction_CAST(pysqlite_connection_set_trace_callback), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_trace_callback__doc__}, @@ -766,13 +907,24 @@ pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable); +// Emit compiler warnings when we get to Python 3.15. +#if PY_VERSION_HEX >= 0x030f00C0 +# error "Update the clinic input of '_sqlite3.Connection.set_trace_callback'." +#elif PY_VERSION_HEX >= 0x030f00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_sqlite3.Connection.set_trace_callback'.") +# else +# warning "Update the clinic input of '_sqlite3.Connection.set_trace_callback'." +# endif +#endif + static PyObject * pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 1 + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -802,6 +954,16 @@ pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyTypeObject * if (!args) { goto exit; } + if (nargs < 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'trace_callback' to " + "_sqlite3.Connection.set_trace_callback() is deprecated. " + "Parameter 'trace_callback' will become positional-only in Python" + " 3.15.", 1)) + { + goto exit; + } + } callable = args[0]; return_value = pysqlite_connection_set_trace_callback_impl(self, cls, callable); @@ -1124,7 +1286,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ goto skip_optional_kwonly; } if (args[1]) { - pages = _PyLong_AsInt(args[1]); + pages = PyLong_AsInt(args[1]); if (pages == -1 && PyErr_Occurred()) { goto exit; } @@ -1516,11 +1678,11 @@ setlimit(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setlimit", nargs, 2, 2)) { goto exit; } - category = _PyLong_AsInt(args[0]); + category = PyLong_AsInt(args[0]); if (category == -1 && PyErr_Occurred()) { goto exit; } - limit = _PyLong_AsInt(args[1]); + limit = PyLong_AsInt(args[1]); if (limit == -1 && PyErr_Occurred()) { goto exit; } @@ -1551,7 +1713,7 @@ getlimit(pysqlite_Connection *self, PyObject *arg) PyObject *return_value = NULL; int category; - category = _PyLong_AsInt(arg); + category = PyLong_AsInt(arg); if (category == -1 && PyErr_Occurred()) { goto exit; } @@ -1586,7 +1748,7 @@ setconfig(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setconfig", nargs, 1, 2)) { goto exit; } - op = _PyLong_AsInt(args[0]); + op = PyLong_AsInt(args[0]); if (op == -1 && PyErr_Occurred()) { goto exit; } @@ -1626,7 +1788,7 @@ getconfig(pysqlite_Connection *self, PyObject *arg) int op; int _return_value; - op = _PyLong_AsInt(arg); + op = PyLong_AsInt(arg); if (op == -1 && PyErr_Occurred()) { goto exit; } @@ -1659,4 +1821,4 @@ getconfig(pysqlite_Connection *self, PyObject *arg) #ifndef DESERIALIZE_METHODDEF #define DESERIALIZE_METHODDEF #endif /* !defined(DESERIALIZE_METHODDEF) */ -/*[clinic end generated code: output=d3c6cb9326736ea5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=166bf41ad5ca1655 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 08b6a732b7bac5..3cb637bde4ff6c 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - static int pysqlite_cursor_init_impl(pysqlite_Cursor *self, pysqlite_Connection *connection); @@ -223,7 +222,7 @@ pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize if (!noptargs) { goto skip_optional_pos; } - maxrows = _PyLong_AsInt(args[0]); + maxrows = PyLong_AsInt(args[0]); if (maxrows == -1 && PyErr_Occurred()) { goto exit; } @@ -313,4 +312,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=831f7bc5256526d3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0c52a9cf54d00543 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index 94002b015fc779..49ba7a341ed587 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, /, statement)\n" "--\n" @@ -159,7 +158,7 @@ pysqlite_enable_callback_trace(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int enable; - enable = _PyLong_AsInt(arg); + enable = PyLong_AsInt(arg); if (enable == -1 && PyErr_Occurred()) { goto exit; } @@ -208,4 +207,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=e08e6856ae546e7b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a14893a7c2eead5e input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/row.c.h b/Modules/_sqlite/clinic/row.c.h index 89a48fd52da226..cdf850d01e01a3 100644 --- a/Modules/_sqlite/clinic/row.c.h +++ b/Modules/_sqlite/clinic/row.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - static PyObject * pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, PyObject *data); @@ -60,4 +54,4 @@ pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_row_keys_impl(self); } -/*[clinic end generated code: output=157b31ac3f6af1ba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=972487d535d2e7d5 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index bab743674b666d..21bdbc12814698 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -26,14 +26,16 @@ #endif #include "module.h" -#include "structmember.h" // PyMemberDef + #include "connection.h" #include "statement.h" #include "cursor.h" #include "blob.h" #include "prepare_protocol.h" #include "util.h" + #include "pycore_import.h" // _PyImport_GetModuleAttrString() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_weakref.h" // _PyWeakref_IS_DEAD() @@ -149,7 +151,7 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); static void free_callback_context(callback_context *ctx); static void set_callback_context(callback_context **ctx_pp, callback_context *ctx); -static void connection_close(pysqlite_Connection *self); +static int connection_close(pysqlite_Connection *self); PyObject *_pysqlite_query_execute(pysqlite_Cursor *, int, PyObject *, PyObject *); static PyObject * @@ -212,11 +214,11 @@ class sqlite3_int64_converter(CConverter): [python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=dff8760fb1eba6a1]*/ -// NB: This needs to be in sync with the sqlite3.connect docstring /*[clinic input] _sqlite3.Connection.__init__ as pysqlite_connection_init database: object + * [from 3.15] timeout: double = 5.0 detect_types: int = 0 isolation_level: IsolationLevel = "" @@ -235,7 +237,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, int check_same_thread, PyObject *factory, int cache_size, int uri, enum autocommit_mode autocommit) -/*[clinic end generated code: output=cba057313ea7712f input=9b0ab6c12f674fa3]*/ +/*[clinic end generated code: output=cba057313ea7712f input=219c3dbecbae7d99]*/ { if (PySys_Audit("sqlite3.connect", "O", database) < 0) { return -1; @@ -247,10 +249,13 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, } if (self->initialized) { + self->initialized = 0; + PyTypeObject *tp = Py_TYPE(self); tp->tp_clear((PyObject *)self); - connection_close(self); - self->initialized = 0; + if (connection_close(self) < 0) { + return -1; + } } // Create and configure SQLite database object. @@ -334,7 +339,9 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, self->initialized = 1; if (autocommit == AUTOCOMMIT_DISABLED) { - (void)connection_exec_stmt(self, "BEGIN"); + if (connection_exec_stmt(self, "BEGIN") < 0) { + return -1; + } } return 0; @@ -346,6 +353,34 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, return -1; } +/*[clinic input] +# Create a new destination 'connect' for the docstring and methoddef only. +# This makes it possible to keep the signatures for Connection.__init__ and +# sqlite3.connect() synchronised. +output push +destination connect new file '{dirname}/clinic/_sqlite3.connect.c.h' + +# Only output the docstring and the PyMethodDef entry. +output everything suppress +output docstring_definition connect +output methoddef_define connect + +# Define the sqlite3.connect function by cloning Connection.__init__. +_sqlite3.connect as pysqlite_connect = _sqlite3.Connection.__init__ + +Open a connection to the SQLite database file 'database'. + +You can use ":memory:" to open a database connection to a database that +resides in RAM instead of on disk. +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92260edff95d1720]*/ + +/*[clinic input] +# Restore normal Argument Clinic operation for the rest of this file. +output pop +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b899ba9273edcce7]*/ + #define VISIT_CALLBACK_CONTEXT(ctx) \ do { \ if (ctx) { \ @@ -404,48 +439,91 @@ free_callback_contexts(pysqlite_Connection *self) static void remove_callbacks(sqlite3 *db) { - sqlite3_trace_v2(db, SQLITE_TRACE_STMT, 0, 0); + /* None of these APIs can fail, as long as they are given a valid + * database pointer. */ + assert(db != NULL); + int rc = sqlite3_trace_v2(db, SQLITE_TRACE_STMT, 0, 0); + assert(rc == SQLITE_OK), (void)rc; + sqlite3_progress_handler(db, 0, 0, (void *)0); - (void)sqlite3_set_authorizer(db, NULL, NULL); + + rc = sqlite3_set_authorizer(db, NULL, NULL); + assert(rc == SQLITE_OK), (void)rc; } -static void +static int connection_close(pysqlite_Connection *self) { - if (self->db) { - if (self->autocommit == AUTOCOMMIT_DISABLED && - !sqlite3_get_autocommit(self->db)) - { - /* If close is implicitly called as a result of interpreter - * tear-down, we must not call back into Python. */ - if (_Py_IsInterpreterFinalizing(PyInterpreterState_Get())) { - remove_callbacks(self->db); - } - (void)connection_exec_stmt(self, "ROLLBACK"); + if (self->db == NULL) { + return 0; + } + + int rc = 0; + if (self->autocommit == AUTOCOMMIT_DISABLED && + !sqlite3_get_autocommit(self->db)) + { + if (connection_exec_stmt(self, "ROLLBACK") < 0) { + rc = -1; } + } - free_callback_contexts(self); + sqlite3 *db = self->db; + self->db = NULL; - sqlite3 *db = self->db; - self->db = NULL; + Py_BEGIN_ALLOW_THREADS + /* The v2 close call always returns SQLITE_OK if given a valid database + * pointer (which we do), so we can safely ignore the return value */ + (void)sqlite3_close_v2(db); + Py_END_ALLOW_THREADS - Py_BEGIN_ALLOW_THREADS - int rc = sqlite3_close_v2(db); - assert(rc == SQLITE_OK), (void)rc; - Py_END_ALLOW_THREADS - } + free_callback_contexts(self); + return rc; } static void -connection_dealloc(pysqlite_Connection *self) +connection_finalize(PyObject *self) { - PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - tp->tp_clear((PyObject *)self); + pysqlite_Connection *con = (pysqlite_Connection *)self; + PyObject *exc = PyErr_GetRaisedException(); + + /* If close is implicitly called as a result of interpreter + * tear-down, we must not call back into Python. */ + PyInterpreterState *interp = PyInterpreterState_Get(); + int teardown = _Py_IsInterpreterFinalizing(interp); + if (teardown && con->db) { + remove_callbacks(con->db); + } /* Clean up if user has not called .close() explicitly. */ - connection_close(self); + if (con->db) { + if (PyErr_ResourceWarning(self, 1, "unclosed database in %R", self)) { + /* Spurious errors can appear at shutdown */ + if (PyErr_ExceptionMatches(PyExc_Warning)) { + PyErr_WriteUnraisable(self); + } + } + } + if (connection_close(con) < 0) { + if (teardown) { + PyErr_Clear(); + } + else { + PyErr_WriteUnraisable((PyObject *)self); + } + } + + PyErr_SetRaisedException(exc); +} +static void +connection_dealloc(PyObject *self) +{ + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + return; + } + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear(self); tp->tp_free(self); Py_DECREF(tp); } @@ -593,7 +671,9 @@ pysqlite_connection_close_impl(pysqlite_Connection *self) pysqlite_close_all_blobs(self); Py_CLEAR(self->statement_cache); - connection_close(self); + if (connection_close(self) < 0) { + return NULL; + } Py_RETURN_NONE; } @@ -1061,6 +1141,7 @@ _sqlite3.Connection.create_function as pysqlite_connection_create_function name: str narg: int func: object + / [from 3.15] * deterministic: bool = False @@ -1072,7 +1153,7 @@ pysqlite_connection_create_function_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, int narg, PyObject *func, int deterministic) -/*[clinic end generated code: output=8a811529287ad240 input=b3e8e1d8ddaffbef]*/ +/*[clinic end generated code: output=8a811529287ad240 input=c7c313b0ca8b519e]*/ { int rc; int flags = SQLITE_UTF8; @@ -1263,6 +1344,7 @@ _sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate name: str n_arg: int aggregate_class: object + / [from 3.15] Creates a new aggregate. [clinic start generated code]*/ @@ -1272,7 +1354,7 @@ pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, int n_arg, PyObject *aggregate_class) -/*[clinic end generated code: output=1b02d0f0aec7ff96 input=68a2a26366d4c686]*/ +/*[clinic end generated code: output=1b02d0f0aec7ff96 input=8087056db6eae1cf]*/ { int rc; @@ -1318,7 +1400,7 @@ authorizer_callback(void *ctx, int action, const char *arg1, } else { if (PyLong_Check(ret)) { - rc = _PyLong_AsInt(ret); + rc = PyLong_AsInt(ret); if (rc == -1 && PyErr_Occurred()) { print_or_clear_traceback(ctx); rc = SQLITE_DENY; @@ -1419,17 +1501,17 @@ trace_callback(unsigned int type, void *ctx, void *stmt, void *sql) _sqlite3.Connection.set_authorizer as pysqlite_connection_set_authorizer cls: defining_class - / authorizer_callback as callable: object + / [from 3.15] -Sets authorizer callback. +Set authorizer callback. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable) -/*[clinic end generated code: output=75fa60114fc971c3 input=605d32ba92dd3eca]*/ +/*[clinic end generated code: output=75fa60114fc971c3 input=a52bd4937c588752]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1461,18 +1543,25 @@ pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, _sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_handler cls: defining_class - / progress_handler as callable: object + A callable that takes no arguments. + If the callable returns non-zero, the current query is terminated, + and an exception is raised. + / [from 3.15] n: int + The number of SQLite virtual machine instructions that are + executed between invocations of 'progress_handler'. + +Set progress handler callback. -Sets progress handler callback. +If 'progress_handler' is None or 'n' is 0, the progress handler is disabled. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable, int n) -/*[clinic end generated code: output=0739957fd8034a50 input=f7c1837984bd86db]*/ +/*[clinic end generated code: output=0739957fd8034a50 input=b4d6e2ef8b4d32f9]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1498,17 +1587,17 @@ pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, _sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback cls: defining_class - / trace_callback as callable: object + / [from 3.15] -Sets a trace callback called for each SQL statement (passed as unicode). +Set a trace callback called for each SQL statement (passed as unicode). [clinic start generated code]*/ static PyObject * pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable) -/*[clinic end generated code: output=d91048c03bfcee05 input=351a94210c5f81bb]*/ +/*[clinic end generated code: output=d91048c03bfcee05 input=d705d592ec03cf28]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -2511,22 +2600,23 @@ static PyMethodDef connection_methods[] = { static struct PyMemberDef connection_members[] = { - {"Warning", T_OBJECT, offsetof(pysqlite_Connection, Warning), READONLY}, - {"Error", T_OBJECT, offsetof(pysqlite_Connection, Error), READONLY}, - {"InterfaceError", T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), READONLY}, - {"DatabaseError", T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), READONLY}, - {"DataError", T_OBJECT, offsetof(pysqlite_Connection, DataError), READONLY}, - {"OperationalError", T_OBJECT, offsetof(pysqlite_Connection, OperationalError), READONLY}, - {"IntegrityError", T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), READONLY}, - {"InternalError", T_OBJECT, offsetof(pysqlite_Connection, InternalError), READONLY}, - {"ProgrammingError", T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), READONLY}, - {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, - {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, - {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, + {"Warning", _Py_T_OBJECT, offsetof(pysqlite_Connection, Warning), Py_READONLY}, + {"Error", _Py_T_OBJECT, offsetof(pysqlite_Connection, Error), Py_READONLY}, + {"InterfaceError", _Py_T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), Py_READONLY}, + {"DatabaseError", _Py_T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), Py_READONLY}, + {"DataError", _Py_T_OBJECT, offsetof(pysqlite_Connection, DataError), Py_READONLY}, + {"OperationalError", _Py_T_OBJECT, offsetof(pysqlite_Connection, OperationalError), Py_READONLY}, + {"IntegrityError", _Py_T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), Py_READONLY}, + {"InternalError", _Py_T_OBJECT, offsetof(pysqlite_Connection, InternalError), Py_READONLY}, + {"ProgrammingError", _Py_T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), Py_READONLY}, + {"NotSupportedError", _Py_T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), Py_READONLY}, + {"row_factory", _Py_T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, + {"text_factory", _Py_T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, {NULL} }; static PyType_Slot connection_slots[] = { + {Py_tp_finalize, connection_finalize}, {Py_tp_dealloc, connection_dealloc}, {Py_tp_doc, (void *)connection_doc}, {Py_tp_methods, connection_methods}, diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index dba8ab61e41e70..618ce532b2518d 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -1325,13 +1325,13 @@ static PyMethodDef cursor_methods[] = { static struct PyMemberDef cursor_members[] = { - {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), READONLY}, - {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), READONLY}, - {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0}, - {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY}, - {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY}, - {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Cursor, in_weakreflist), READONLY}, + {"connection", _Py_T_OBJECT, offsetof(pysqlite_Cursor, connection), Py_READONLY}, + {"description", _Py_T_OBJECT, offsetof(pysqlite_Cursor, description), Py_READONLY}, + {"arraysize", Py_T_INT, offsetof(pysqlite_Cursor, arraysize), 0}, + {"lastrowid", _Py_T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), Py_READONLY}, + {"rowcount", Py_T_LONG, offsetof(pysqlite_Cursor, rowcount), Py_READONLY}, + {"row_factory", _Py_T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(pysqlite_Cursor, in_weakreflist), Py_READONLY}, {NULL} }; diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 368e581b4f3355..46fed9f13281f3 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -48,31 +48,33 @@ module _sqlite3 [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ -// NB: This needs to be in sync with the Connection.__init__ docstring. -PyDoc_STRVAR(module_connect_doc, -"connect($module, /, database, timeout=5.0, detect_types=0,\n" -" isolation_level='', check_same_thread=True,\n" -" factory=ConnectionType, cached_statements=128, uri=False, *,\n" -" autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL)\n" -"--\n" -"\n" -"Opens a connection to the SQLite database file database.\n" -"\n" -"You can use \":memory:\" to open a database connection to a database that resides\n" -"in RAM instead of on disk."); - -#define PYSQLITE_CONNECT_METHODDEF \ - {"connect", _PyCFunction_CAST(module_connect), METH_FASTCALL|METH_KEYWORDS, module_connect_doc}, +/* + * We create 'clinic/_sqlite3.connect.c.h' in connection.c, in order to + * keep the signatures of sqlite3.Connection.__init__ and + * sqlite3.connect() synchronised. + */ +#include "clinic/_sqlite3.connect.c.h" static PyObject * -module_connect(PyObject *module, PyObject *const *args, Py_ssize_t nargsf, - PyObject *kwnames) +pysqlite_connect(PyObject *module, PyObject *const *args, Py_ssize_t nargsf, + PyObject *kwnames) { pysqlite_state *state = pysqlite_get_state(module); PyObject *factory = (PyObject *)state->ConnectionType; static const int FACTORY_POS = 5; Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs > 1 && nargs <= 8) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to sqlite3.connect()" + " is deprecated. Parameters 'timeout', 'detect_types', " + "'isolation_level', 'check_same_thread', 'factory', " + "'cached_statements' and 'uri' will become keyword-only " + "parameters in Python 3.15.", 1)) + { + return NULL; + } + } if (nargs > FACTORY_POS) { factory = args[FACTORY_POS]; } @@ -242,7 +244,7 @@ load_functools_lru_cache(PyObject *module) static PyMethodDef module_methods[] = { PYSQLITE_ADAPT_METHODDEF PYSQLITE_COMPLETE_STATEMENT_METHODDEF - PYSQLITE_CONNECT_METHODDEF + {"connect", _PyCFunction_CAST(pysqlite_connect), METH_FASTCALL|METH_KEYWORDS, pysqlite_connect__doc__}, PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF PYSQLITE_REGISTER_ADAPTER_METHODDEF PYSQLITE_REGISTER_CONVERTER_METHODDEF diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index 2b3bbfefa3cf5f..833a666301d8ff 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -21,7 +21,12 @@ * 3. This notice may not be removed or altered from any source distribution. */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "module.h" +#include "pycore_long.h" // _PyLong_AsByteArray() #include "connection.h" // Returns non-NULL if a new exception should be raised diff --git a/Modules/_sre/clinic/sre.c.h b/Modules/_sre/clinic/sre.c.h index da641081ce9e3c..1b5e1a710af9db 100644 --- a/Modules/_sre/clinic/sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_sre_getcodesize__doc__, "getcodesize($module, /)\n" @@ -53,7 +53,7 @@ _sre_ascii_iscased(PyObject *module, PyObject *arg) int character; int _return_value; - character = _PyLong_AsInt(arg); + character = PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } @@ -85,7 +85,7 @@ _sre_unicode_iscased(PyObject *module, PyObject *arg) int character; int _return_value; - character = _PyLong_AsInt(arg); + character = PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } @@ -117,7 +117,7 @@ _sre_ascii_tolower(PyObject *module, PyObject *arg) int character; int _return_value; - character = _PyLong_AsInt(arg); + character = PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } @@ -149,7 +149,7 @@ _sre_unicode_tolower(PyObject *module, PyObject *arg) int character; int _return_value; - character = _PyLong_AsInt(arg); + character = PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } @@ -1031,7 +1031,7 @@ _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } pattern = args[0]; - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -1460,4 +1460,4 @@ _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const } return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=e3ba72156dd71572 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=46d83927cbafa93a input=a9049054013a1b77]*/ diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index ddbdc9f478aab3..798732ccddc99a 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -39,15 +39,44 @@ static const char copyright[] = " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB "; #include "Python.h" +#include "pycore_dict.h" // _PyDict_Next() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() -#include "structmember.h" // PyMemberDef -#include "sre.h" +#include "sre.h" // SRE_CODE + +#include // tolower(), toupper(), isalnum() #define SRE_CODE_BITS (8 * sizeof(SRE_CODE)) -#include +// On macOS, use the wide character ctype API using btowc() +#if defined(__APPLE__) +# define USE_CTYPE_WINT_T +#endif + +static int sre_isalnum(unsigned int ch) { +#ifdef USE_CTYPE_WINT_T + return (unsigned int)iswalnum(btowc((int)ch)); +#else + return (unsigned int)isalnum((int)ch); +#endif +} + +static unsigned int sre_tolower(unsigned int ch) { +#ifdef USE_CTYPE_WINT_T + return (unsigned int)towlower(btowc((int)ch)); +#else + return (unsigned int)tolower((int)ch); +#endif +} + +static unsigned int sre_toupper(unsigned int ch) { +#ifdef USE_CTYPE_WINT_T + return (unsigned int)towupper(btowc((int)ch)); +#else + return (unsigned int)toupper((int)ch); +#endif +} /* Defining this one controls tracing: * 0 -- disabled @@ -113,17 +142,17 @@ static unsigned int sre_lower_ascii(unsigned int ch) /* locale-specific character predicates */ /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids * warnings when c's type supports only numbers < N+1 */ -#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0) +#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? sre_isalnum((ch)) : 0) #define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_') static unsigned int sre_lower_locale(unsigned int ch) { - return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch); + return ((ch) < 256 ? (unsigned int)sre_tolower((ch)) : ch); } static unsigned int sre_upper_locale(unsigned int ch) { - return ((ch) < 256 ? (unsigned int)toupper((ch)) : ch); + return ((ch) < 256 ? (unsigned int)sre_toupper((ch)) : ch); } /* unicode-specific character predicates */ @@ -1479,6 +1508,9 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, for (i = 0; i < n; i++) { PyObject *o = PyList_GET_ITEM(code, i); unsigned long value = PyLong_AsUnsignedLong(o); + if (value == (unsigned long)-1 && PyErr_Occurred()) { + break; + } self->code[i] = (SRE_CODE) value; if ((unsigned long) self->code[i] != value) { PyErr_SetString(PyExc_OverflowError, @@ -2994,13 +3026,13 @@ static PyGetSetDef pattern_getset[] = { #define PAT_OFF(x) offsetof(PatternObject, x) static PyMemberDef pattern_members[] = { - {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY, + {"pattern", _Py_T_OBJECT, PAT_OFF(pattern), Py_READONLY, "The pattern string from which the RE object was compiled."}, - {"flags", T_INT, PAT_OFF(flags), READONLY, + {"flags", Py_T_INT, PAT_OFF(flags), Py_READONLY, "The regex matching flags."}, - {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY, + {"groups", Py_T_PYSSIZET, PAT_OFF(groups), Py_READONLY, "The number of capturing groups in the pattern."}, - {"__weaklistoffset__", T_PYSSIZET, offsetof(PatternObject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(PatternObject, weakreflist), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -3053,13 +3085,13 @@ static PyGetSetDef match_getset[] = { #define MATCH_OFF(x) offsetof(MatchObject, x) static PyMemberDef match_members[] = { - {"string", T_OBJECT, MATCH_OFF(string), READONLY, + {"string", _Py_T_OBJECT, MATCH_OFF(string), Py_READONLY, "The string passed to match() or search()."}, - {"re", T_OBJECT, MATCH_OFF(pattern), READONLY, + {"re", _Py_T_OBJECT, MATCH_OFF(pattern), Py_READONLY, "The regular expression object."}, - {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY, + {"pos", Py_T_PYSSIZET, MATCH_OFF(pos), Py_READONLY, "The index into the string at which the RE engine started looking for a match."}, - {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY, + {"endpos", Py_T_PYSSIZET, MATCH_OFF(endpos), Py_READONLY, "The index into the string beyond which the RE engine will not go."}, {NULL} }; @@ -3103,7 +3135,7 @@ static PyMethodDef scanner_methods[] = { #define SCAN_OFF(x) offsetof(ScannerObject, x) static PyMemberDef scanner_members[] = { - {"pattern", T_OBJECT, SCAN_OFF(pattern), READONLY}, + {"pattern", _Py_T_OBJECT, SCAN_OFF(pattern), Py_READONLY}, {NULL} /* Sentinel */ }; diff --git a/Modules/_sre/sre.h b/Modules/_sre/sre.h index f60078d6bb999b..83d89d57b11199 100644 --- a/Modules/_sre/sre.h +++ b/Modules/_sre/sre.h @@ -95,6 +95,7 @@ typedef struct { size_t data_stack_base; /* current repeat context */ SRE_REPEAT *repeat; + unsigned int sigcount; } SRE_STATE; typedef struct { diff --git a/Modules/_sre/sre_lib.h b/Modules/_sre/sre_lib.h index c1a774f69090b3..3c805aeeca0974 100644 --- a/Modules/_sre/sre_lib.h +++ b/Modules/_sre/sre_lib.h @@ -564,7 +564,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) Py_ssize_t alloc_pos, ctx_pos = -1; Py_ssize_t ret = 0; int jump; - unsigned int sigcount=0; + unsigned int sigcount = state->sigcount; SRE(match_context)* ctx; SRE(match_context)* nextctx; @@ -1336,6 +1336,10 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) MARK_POP(ctx->lastmark); LASTMARK_RESTORE(); + /* Restore the global Input Stream pointer + since it can change after jumps. */ + state->ptr = ptr; + /* We have sufficient matches, so exit loop. */ break; } @@ -1563,8 +1567,10 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) ctx_pos = ctx->last_ctx_pos; jump = ctx->jump; DATA_POP_DISCARD(ctx); - if (ctx_pos == -1) + if (ctx_pos == -1) { + state->sigcount = sigcount; return ret; + } DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); switch (jump) { diff --git a/Modules/_ssl.c b/Modules/_ssl.c index ed720b4295f8ec..cecc3785c7661c 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -26,6 +26,8 @@ #define OPENSSL_NO_DEPRECATED 1 #include "Python.h" +#include "pycore_fileutils.h" // _PyIsSelectable_fd() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_weakref.h" // _PyWeakref_GET_REF() /* Include symbols from _socket module */ @@ -666,6 +668,10 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) errstr = "Some I/O error occurred"; } } else { + if (ERR_GET_LIB(e) == ERR_LIB_SSL && + ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) { + type = state->PySSLCertVerificationErrorObject; + } p = PY_SSL_ERROR_SYSCALL; } break; @@ -3909,8 +3915,8 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, /* the password callback has already set the error information */ } else if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrno(PyExc_OSError); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -3930,8 +3936,8 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, /* the password callback has already set the error information */ } else if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrno(PyExc_OSError); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -4160,8 +4166,8 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, PySSL_END_ALLOW_THREADS if (r != 1) { if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrno(PyExc_OSError); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -4208,8 +4214,8 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) PySSL_END_ALLOW_THREADS if (dh == NULL) { if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, filepath); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -5985,7 +5991,7 @@ sslmodule_init_constants(PyObject *m) #define addbool(m, key, value) \ do { \ PyObject *bool_obj = (value) ? Py_True : Py_False; \ - PyModule_AddObject((m), (key), Py_NewRef(bool_obj)); \ + PyModule_AddObjectRef((m), (key), bool_obj); \ } while (0) addbool(m, "HAS_SNI", 1); diff --git a/Modules/_ssl/clinic/cert.c.h b/Modules/_ssl/clinic/cert.c.h index a052ab2086fd96..db43c88e411139 100644 --- a/Modules/_ssl/clinic/cert.c.h +++ b/Modules/_ssl/clinic/cert.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_ssl_Certificate_public_bytes__doc__, "public_bytes($self, /, format=Encoding.PEM)\n" "--\n" @@ -59,7 +58,7 @@ _ssl_Certificate_public_bytes(PySSLCertificate *self, PyObject *const *args, Py_ if (!noptargs) { goto skip_optional_pos; } - format = _PyLong_AsInt(args[0]); + format = PyLong_AsInt(args[0]); if (format == -1 && PyErr_Occurred()) { goto exit; } @@ -86,4 +85,4 @@ _ssl_Certificate_get_info(PySSLCertificate *self, PyObject *Py_UNUSED(ignored)) { return _ssl_Certificate_get_info_impl(self); } -/*[clinic end generated code: output=82efada014f9b7fe input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8e438b54fbebd53e input=a9049054013a1b77]*/ diff --git a/Modules/_stat.c b/Modules/_stat.c index 6cea26175dee5e..402fbbaecf8dd8 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -11,11 +11,10 @@ * */ -#include "Python.h" +// Need limited C API version 3.13 for PyModule_Add() on Windows +#define Py_LIMITED_API 0x030d0000 -#ifdef __cplusplus -extern "C" { -#endif +#include "Python.h" #ifdef HAVE_SYS_TYPES_H #include @@ -631,7 +630,3 @@ PyInit__stat(void) { return PyModuleDef_Init(&statmodule); } - -#ifdef __cplusplus -} -#endif diff --git a/Modules/_struct.c b/Modules/_struct.c index 31c94927e91d68..ff1bf4e96c5f21 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -9,9 +9,10 @@ #include "Python.h" #include "pycore_bytesobject.h" // _PyBytesWriter +#include "pycore_long.h" // _PyLong_AsByteArray() #include "pycore_moduleobject.h" // _PyModule_GetState() -#include "structmember.h" // PyMemberDef -#include + +#include // offsetof() /*[clinic input] class Struct "PyStructObject *" "&PyStructType" @@ -106,19 +107,22 @@ class cache_struct_converter(CConverter): type = 'PyStructObject *' converter = 'cache_struct_converter' c_default = "NULL" + broken_limited_capi = True - def parse_arg(self, argname, displayname): - return """ + def parse_arg(self, argname, displayname, *, limited_capi): + assert not limited_capi + return self.format_code(""" if (!{converter}(module, {argname}, &{paramname})) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.name, - converter=self.converter) + """, + argname=argname, + converter=self.converter) def cleanup(self): return "Py_XDECREF(%s);\n" % self.name [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=d6746621c2fb1a7d]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=c33b27d6b06006c6]*/ static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **); @@ -2163,6 +2167,19 @@ s_sizeof(PyStructObject *self, void *unused) return PyLong_FromSize_t(size); } +static PyObject * +s_repr(PyStructObject *self) +{ + PyObject* fmt = PyUnicode_FromStringAndSize( + PyBytes_AS_STRING(self->s_format), PyBytes_GET_SIZE(self->s_format)); + if (fmt == NULL) { + return NULL; + } + PyObject* s = PyUnicode_FromFormat("%s(%R)", _PyType_Name(Py_TYPE(self)), fmt); + Py_DECREF(fmt); + return s; +} + /* List of functions */ static struct PyMethodDef s_methods[] = { @@ -2176,13 +2193,13 @@ static struct PyMethodDef s_methods[] = { }; static PyMemberDef s_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(PyStructObject, weakreflist), Py_READONLY}, {NULL} /* sentinel */ }; static PyGetSetDef s_getsetlist[] = { - {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL}, - {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL}, + {"format", (getter)s_get_format, (setter)NULL, PyDoc_STR("struct format string"), NULL}, + {"size", (getter)s_get_size, (setter)NULL, PyDoc_STR("struct size in bytes"), NULL}, {NULL} /* sentinel */ }; @@ -2195,6 +2212,7 @@ static PyType_Slot PyStructType_slots[] = { {Py_tp_dealloc, s_dealloc}, {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_setattro, PyObject_GenericSetAttr}, + {Py_tp_repr, s_repr}, {Py_tp_doc, (void*)s__doc__}, {Py_tp_traverse, s_traverse}, {Py_tp_clear, s_clear}, diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c new file mode 100644 index 00000000000000..6f1cc16b58467d --- /dev/null +++ b/Modules/_sysconfig.c @@ -0,0 +1,98 @@ +// _sysconfig provides data for the Python sysconfig module + +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +#include "Python.h" + +#include "pycore_importdl.h" // _PyImport_DynLoadFiletab +#include "pycore_long.h" // _PyLong_GetZero, _PyLong_GetOne + + +/*[clinic input] +module _sysconfig +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0a7c02d3e212ac97]*/ + +#include "clinic/_sysconfig.c.h" + +#ifdef MS_WINDOWS +static int +add_string_value(PyObject *dict, const char *key, const char *str_value) +{ + PyObject *value = PyUnicode_FromString(str_value); + if (value == NULL) { + return -1; + } + int err = PyDict_SetItemString(dict, key, value); + Py_DECREF(value); + return err; +} +#endif + +/*[clinic input] +_sysconfig.config_vars + +Returns a dictionary containing build variables intended to be exposed by sysconfig. +[clinic start generated code]*/ + +static PyObject * +_sysconfig_config_vars_impl(PyObject *module) +/*[clinic end generated code: output=9c41cdee63ea9487 input=391ff42f3af57d01]*/ +{ + PyObject *config = PyDict_New(); + if (config == NULL) { + return NULL; + } + +#ifdef MS_WINDOWS + if (add_string_value(config, "EXT_SUFFIX", PYD_TAGGED_SUFFIX) < 0) { + Py_DECREF(config); + return NULL; + } + if (add_string_value(config, "SOABI", PYD_SOABI) < 0) { + Py_DECREF(config); + return NULL; + } +#endif + +#ifdef Py_NOGIL + PyObject *py_nogil = _PyLong_GetOne(); +#else + PyObject *py_nogil = _PyLong_GetZero(); +#endif + if (PyDict_SetItemString(config, "Py_NOGIL", py_nogil) < 0) { + Py_DECREF(config); + return NULL; + } + + return config; +} + +PyDoc_STRVAR(sysconfig__doc__, +"A helper for the sysconfig module."); + +static struct PyMethodDef sysconfig_methods[] = { + _SYSCONFIG_CONFIG_VARS_METHODDEF + {NULL, NULL} +}; + +static PyModuleDef_Slot sysconfig_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + +static PyModuleDef sysconfig_module = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_sysconfig", + .m_doc = sysconfig__doc__, + .m_methods = sysconfig_methods, + .m_slots = sysconfig_slots, +}; + +PyMODINIT_FUNC +PyInit__sysconfig(void) +{ + return PyModuleDef_Init(&sysconfig_module); +} diff --git a/Modules/_testcapi/abstract.c b/Modules/_testcapi/abstract.c new file mode 100644 index 00000000000000..a93477a7090422 --- /dev/null +++ b/Modules/_testcapi/abstract.c @@ -0,0 +1,675 @@ +#include "parts.h" +#include "util.h" + + +static PyObject * +object_getattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + return PyObject_GetAttr(obj, attr_name); +} + +static PyObject * +object_getattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + return PyObject_GetAttrString(obj, attr_name); +} + +static PyObject * +object_getoptionalattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + + switch (PyObject_GetOptionalAttr(obj, attr_name, &value)) { + case -1: + assert(value == NULL); + return NULL; + case 0: + assert(value == NULL); + return Py_NewRef(PyExc_AttributeError); + case 1: + return value; + default: + Py_FatalError("PyObject_GetOptionalAttr() returned invalid code"); + Py_UNREACHABLE(); + } +} + +static PyObject * +object_getoptionalattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj, *value = UNINITIALIZED_PTR; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + + switch (PyObject_GetOptionalAttrString(obj, attr_name, &value)) { + case -1: + assert(value == NULL); + return NULL; + case 0: + assert(value == NULL); + return Py_NewRef(PyExc_AttributeError); + case 1: + return value; + default: + Py_FatalError("PyObject_GetOptionalAttrString() returned invalid code"); + Py_UNREACHABLE(); + } +} + +static PyObject * +object_hasattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + return PyLong_FromLong(PyObject_HasAttr(obj, attr_name)); +} + +static PyObject * +object_hasattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + return PyLong_FromLong(PyObject_HasAttrString(obj, attr_name)); +} + +static PyObject * +object_hasattrwitherror(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + RETURN_INT(PyObject_HasAttrWithError(obj, attr_name)); +} + +static PyObject * +object_hasattrstringwitherror(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + RETURN_INT(PyObject_HasAttrStringWithError(obj, attr_name)); +} + +static PyObject * +object_setattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name, *value; + if (!PyArg_ParseTuple(args, "OOO", &obj, &attr_name, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + NULLABLE(value); + RETURN_INT(PyObject_SetAttr(obj, attr_name, value)); +} + +static PyObject * +object_setattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj, *value; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#O", &obj, &attr_name, &size, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(value); + RETURN_INT(PyObject_SetAttrString(obj, attr_name, value)); +} + +static PyObject * +object_delattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; +if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + RETURN_INT(PyObject_DelAttr(obj, attr_name)); +} + +static PyObject * +object_delattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + RETURN_INT(PyObject_DelAttrString(obj, attr_name)); +} + + +static PyObject * +mapping_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyMapping_Check(obj)); +} + +static PyObject * +mapping_size(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyMapping_Size(obj)); +} + +static PyObject * +mapping_length(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyMapping_Length(obj)); +} + +static PyObject * +object_getitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + return PyObject_GetItem(mapping, key); +} + +static PyObject * +mapping_getitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + return PyMapping_GetItemString(mapping, key); +} + +static PyObject * +mapping_getoptionalitem(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + + switch (PyMapping_GetOptionalItem(obj, attr_name, &value)) { + case -1: + assert(value == NULL); + return NULL; + case 0: + assert(value == NULL); + return Py_NewRef(PyExc_KeyError); + case 1: + return value; + default: + Py_FatalError("PyMapping_GetOptionalItem() returned invalid code"); + Py_UNREACHABLE(); + } +} + +static PyObject * +mapping_getoptionalitemstring(PyObject *self, PyObject *args) +{ + PyObject *obj, *value = UNINITIALIZED_PTR; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + + switch (PyMapping_GetOptionalItemString(obj, attr_name, &value)) { + case -1: + assert(value == NULL); + return NULL; + case 0: + assert(value == NULL); + return Py_NewRef(PyExc_KeyError); + case 1: + return value; + default: + Py_FatalError("PyMapping_GetOptionalItemString() returned invalid code"); + Py_UNREACHABLE(); + } +} + +static PyObject * +mapping_haskey(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + return PyLong_FromLong(PyMapping_HasKey(mapping, key)); +} + +static PyObject * +mapping_haskeystring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + return PyLong_FromLong(PyMapping_HasKeyString(mapping, key)); +} + +static PyObject * +mapping_haskeywitherror(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyMapping_HasKeyWithError(mapping, key)); +} + +static PyObject * +mapping_haskeystringwitherror(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + RETURN_INT(PyMapping_HasKeyStringWithError(mapping, key)); +} + +static PyObject * +object_setitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key, *value; + if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + NULLABLE(value); + RETURN_INT(PyObject_SetItem(mapping, key, value)); +} + +static PyObject * +mapping_setitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping, *value; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#O", &mapping, &key, &size, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(value); + RETURN_INT(PyMapping_SetItemString(mapping, key, value)); +} + +static PyObject * +object_delitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyObject_DelItem(mapping, key)); +} + +static PyObject * +mapping_delitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyMapping_DelItem(mapping, key)); +} + +static PyObject * +mapping_delitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + RETURN_INT(PyMapping_DelItemString(mapping, key)); +} + +static PyObject * +mapping_keys(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyMapping_Keys(obj); +} + +static PyObject * +mapping_values(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyMapping_Values(obj); +} + +static PyObject * +mapping_items(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyMapping_Items(obj); +} + + +static PyObject * +sequence_check(PyObject* self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PySequence_Check(obj)); +} + +static PyObject * +sequence_size(PyObject* self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PySequence_Size(obj)); +} + +static PyObject * +sequence_length(PyObject* self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PySequence_Length(obj)); +} + +static PyObject * +sequence_concat(PyObject *self, PyObject *args) +{ + PyObject *seq1, *seq2; + if (!PyArg_ParseTuple(args, "OO", &seq1, &seq2)) { + return NULL; + } + NULLABLE(seq1); + NULLABLE(seq2); + + return PySequence_Concat(seq1, seq2); +} + +static PyObject * +sequence_repeat(PyObject *self, PyObject *args) +{ + PyObject *seq; + Py_ssize_t count; + if (!PyArg_ParseTuple(args, "On", &seq, &count)) { + return NULL; + } + NULLABLE(seq); + + return PySequence_Repeat(seq, count); +} + +static PyObject * +sequence_inplaceconcat(PyObject *self, PyObject *args) +{ + PyObject *seq1, *seq2; + if (!PyArg_ParseTuple(args, "OO", &seq1, &seq2)) { + return NULL; + } + NULLABLE(seq1); + NULLABLE(seq2); + + return PySequence_InPlaceConcat(seq1, seq2); +} + +static PyObject * +sequence_inplacerepeat(PyObject *self, PyObject *args) +{ + PyObject *seq; + Py_ssize_t count; + if (!PyArg_ParseTuple(args, "On", &seq, &count)) { + return NULL; + } + NULLABLE(seq); + + return PySequence_InPlaceRepeat(seq, count); +} + +static PyObject * +sequence_getitem(PyObject *self, PyObject *args) +{ + PyObject *seq; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "On", &seq, &i)) { + return NULL; + } + NULLABLE(seq); + + return PySequence_GetItem(seq, i); +} + +static PyObject * +sequence_setitem(PyObject *self, PyObject *args) +{ + Py_ssize_t i; + PyObject *seq, *val; + if (!PyArg_ParseTuple(args, "OnO", &seq, &i, &val)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(val); + + RETURN_INT(PySequence_SetItem(seq, i, val)); +} + + +static PyObject * +sequence_delitem(PyObject *self, PyObject *args) +{ + Py_ssize_t i; + PyObject *seq; + if (!PyArg_ParseTuple(args, "On", &seq, &i)) { + return NULL; + } + NULLABLE(seq); + + RETURN_INT(PySequence_DelItem(seq, i)); +} + +static PyObject * +sequence_setslice(PyObject* self, PyObject *args) +{ + PyObject *sequence, *obj; + Py_ssize_t i1, i2; + if (!PyArg_ParseTuple(args, "OnnO", &sequence, &i1, &i2, &obj)) { + return NULL; + } + NULLABLE(sequence); + NULLABLE(obj); + + RETURN_INT(PySequence_SetSlice(sequence, i1, i2, obj)); +} + +static PyObject * +sequence_delslice(PyObject *self, PyObject *args) +{ + PyObject *sequence; + Py_ssize_t i1, i2; + if (!PyArg_ParseTuple(args, "Onn", &sequence, &i1, &i2)) { + return NULL; + } + NULLABLE(sequence); + + RETURN_INT(PySequence_DelSlice(sequence, i1, i2)); +} + +static PyObject * +sequence_count(PyObject *self, PyObject *args) +{ + PyObject *seq, *value; + if (!PyArg_ParseTuple(args, "OO", &seq, &value)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(value); + + RETURN_SIZE(PySequence_Count(seq, value)); +} + +static PyObject * +sequence_contains(PyObject *self, PyObject *args) +{ + PyObject *seq, *value; + if (!PyArg_ParseTuple(args, "OO", &seq, &value)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(value); + + RETURN_INT(PySequence_Contains(seq, value)); +} + +static PyObject * +sequence_index(PyObject *self, PyObject *args) +{ + PyObject *seq, *value; + if (!PyArg_ParseTuple(args, "OO", &seq, &value)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(value); + + RETURN_SIZE(PySequence_Index(seq, value)); +} + +static PyObject * +sequence_list(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PySequence_List(obj); +} + +static PyObject * +sequence_tuple(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PySequence_Tuple(obj); +} + + +static PyMethodDef test_methods[] = { + {"object_getattr", object_getattr, METH_VARARGS}, + {"object_getattrstring", object_getattrstring, METH_VARARGS}, + {"object_getoptionalattr", object_getoptionalattr, METH_VARARGS}, + {"object_getoptionalattrstring", object_getoptionalattrstring, METH_VARARGS}, + {"object_hasattr", object_hasattr, METH_VARARGS}, + {"object_hasattrstring", object_hasattrstring, METH_VARARGS}, + {"object_hasattrwitherror", object_hasattrwitherror, METH_VARARGS}, + {"object_hasattrstringwitherror", object_hasattrstringwitherror, METH_VARARGS}, + {"object_setattr", object_setattr, METH_VARARGS}, + {"object_setattrstring", object_setattrstring, METH_VARARGS}, + {"object_delattr", object_delattr, METH_VARARGS}, + {"object_delattrstring", object_delattrstring, METH_VARARGS}, + + {"mapping_check", mapping_check, METH_O}, + {"mapping_size", mapping_size, METH_O}, + {"mapping_length", mapping_length, METH_O}, + {"object_getitem", object_getitem, METH_VARARGS}, + {"mapping_getitemstring", mapping_getitemstring, METH_VARARGS}, + {"mapping_getoptionalitem", mapping_getoptionalitem, METH_VARARGS}, + {"mapping_getoptionalitemstring", mapping_getoptionalitemstring, METH_VARARGS}, + {"mapping_haskey", mapping_haskey, METH_VARARGS}, + {"mapping_haskeystring", mapping_haskeystring, METH_VARARGS}, + {"mapping_haskeywitherror", mapping_haskeywitherror, METH_VARARGS}, + {"mapping_haskeystringwitherror", mapping_haskeystringwitherror, METH_VARARGS}, + {"object_setitem", object_setitem, METH_VARARGS}, + {"mapping_setitemstring", mapping_setitemstring, METH_VARARGS}, + {"object_delitem", object_delitem, METH_VARARGS}, + {"mapping_delitem", mapping_delitem, METH_VARARGS}, + {"mapping_delitemstring", mapping_delitemstring, METH_VARARGS}, + {"mapping_keys", mapping_keys, METH_O}, + {"mapping_values", mapping_values, METH_O}, + {"mapping_items", mapping_items, METH_O}, + + {"sequence_check", sequence_check, METH_O}, + {"sequence_size", sequence_size, METH_O}, + {"sequence_length", sequence_length, METH_O}, + {"sequence_concat", sequence_concat, METH_VARARGS}, + {"sequence_repeat", sequence_repeat, METH_VARARGS}, + {"sequence_inplaceconcat", sequence_inplaceconcat, METH_VARARGS}, + {"sequence_inplacerepeat", sequence_inplacerepeat, METH_VARARGS}, + {"sequence_getitem", sequence_getitem, METH_VARARGS}, + {"sequence_setitem", sequence_setitem, METH_VARARGS}, + {"sequence_delitem", sequence_delitem, METH_VARARGS}, + {"sequence_setslice", sequence_setslice, METH_VARARGS}, + {"sequence_delslice", sequence_delslice, METH_VARARGS}, + {"sequence_count", sequence_count, METH_VARARGS}, + {"sequence_contains", sequence_contains, METH_VARARGS}, + {"sequence_index", sequence_index, METH_VARARGS}, + {"sequence_list", sequence_list, METH_O}, + {"sequence_tuple", sequence_tuple, METH_O}, + + {NULL}, +}; + +int +_PyTestCapi_Init_Abstract(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/buffer.c b/Modules/_testcapi/buffer.c index aff9a477eff57e..942774156c6c47 100644 --- a/Modules/_testcapi/buffer.c +++ b/Modules/_testcapi/buffer.c @@ -2,7 +2,7 @@ #include "parts.h" -#include "structmember.h" // PyMemberDef + #include // offsetof typedef struct { @@ -72,7 +72,7 @@ static PyBufferProcs testbuf_as_buffer = { }; static struct PyMemberDef testbuf_members[] = { - {"references", T_PYSSIZET, offsetof(testBufObject, references), READONLY}, + {"references", Py_T_PYSSIZET, offsetof(testBufObject, references), Py_READONLY}, {NULL}, }; diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h index 01730ffa2ed036..39b5f8b91a00db 100644 --- a/Modules/_testcapi/clinic/exceptions.c.h +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_testcapi_err_set_raised__doc__, "err_set_raised($module, exception, /)\n" "--\n" @@ -215,6 +214,68 @@ _testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize return return_value; } +PyDoc_STRVAR(_testcapi_err_setstring__doc__, +"err_setstring($module, exc, value, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_ERR_SETSTRING_METHODDEF \ + {"err_setstring", _PyCFunction_CAST(_testcapi_err_setstring), METH_FASTCALL, _testcapi_err_setstring__doc__}, + +static PyObject * +_testcapi_err_setstring_impl(PyObject *module, PyObject *exc, + const char *value, Py_ssize_t value_length); + +static PyObject * +_testcapi_err_setstring(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + const char *value; + Py_ssize_t value_length; + + if (!_PyArg_ParseStack(args, nargs, "Oz#:err_setstring", + &exc, &value, &value_length)) { + goto exit; + } + return_value = _testcapi_err_setstring_impl(module, exc, value, value_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_err_setfromerrnowithfilename__doc__, +"err_setfromerrnowithfilename($module, error, exc, value, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_ERR_SETFROMERRNOWITHFILENAME_METHODDEF \ + {"err_setfromerrnowithfilename", _PyCFunction_CAST(_testcapi_err_setfromerrnowithfilename), METH_FASTCALL, _testcapi_err_setfromerrnowithfilename__doc__}, + +static PyObject * +_testcapi_err_setfromerrnowithfilename_impl(PyObject *module, int error, + PyObject *exc, const char *value, + Py_ssize_t value_length); + +static PyObject * +_testcapi_err_setfromerrnowithfilename(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int error; + PyObject *exc; + const char *value; + Py_ssize_t value_length; + + if (!_PyArg_ParseStack(args, nargs, "iOz#:err_setfromerrnowithfilename", + &error, &exc, &value, &value_length)) { + goto exit; + } + return_value = _testcapi_err_setfromerrnowithfilename_impl(module, error, exc, value, value_length); + +exit: + return return_value; +} + PyDoc_STRVAR(_testcapi_raise_exception__doc__, "raise_exception($module, exception, num_args, /)\n" "--\n" @@ -237,7 +298,7 @@ _testcapi_raise_exception(PyObject *module, PyObject *const *args, Py_ssize_t na goto exit; } exc = args[0]; - num_args = _PyLong_AsInt(args[1]); + num_args = PyLong_AsInt(args[1]); if (num_args == -1 && PyErr_Occurred()) { goto exit; } @@ -333,38 +394,6 @@ PyDoc_STRVAR(_testcapi_set_exception__doc__, #define _TESTCAPI_SET_EXCEPTION_METHODDEF \ {"set_exception", (PyCFunction)_testcapi_set_exception, METH_O, _testcapi_set_exception__doc__}, -PyDoc_STRVAR(_testcapi_write_unraisable_exc__doc__, -"write_unraisable_exc($module, exception, err_msg, obj, /)\n" -"--\n" -"\n"); - -#define _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF \ - {"write_unraisable_exc", _PyCFunction_CAST(_testcapi_write_unraisable_exc), METH_FASTCALL, _testcapi_write_unraisable_exc__doc__}, - -static PyObject * -_testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, - PyObject *err_msg, PyObject *obj); - -static PyObject * -_testcapi_write_unraisable_exc(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *exc; - PyObject *err_msg; - PyObject *obj; - - if (!_PyArg_CheckPositional("write_unraisable_exc", nargs, 3, 3)) { - goto exit; - } - exc = args[0]; - err_msg = args[1]; - obj = args[2]; - return_value = _testcapi_write_unraisable_exc_impl(module, exc, err_msg, obj); - -exit: - return return_value; -} - PyDoc_STRVAR(_testcapi_traceback_print__doc__, "traceback_print($module, traceback, file, /)\n" "--\n" @@ -426,4 +455,4 @@ _testcapi_unstable_exc_prep_reraise_star(PyObject *module, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=fd6aef54f195c77b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ff19512450b3bbdb input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/float.c.h b/Modules/_testcapi/clinic/float.c.h index c1dff2a9ac5789..fb0931a0703e11 100644 --- a/Modules/_testcapi/clinic/float.c.h +++ b/Modules/_testcapi/clinic/float.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_testcapi_float_pack__doc__, "float_pack($module, size, d, le, /)\n" "--\n" @@ -31,7 +25,7 @@ _testcapi_float_pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("float_pack", nargs, 3, 3)) { goto exit; } - size = _PyLong_AsInt(args[0]); + size = PyLong_AsInt(args[0]); if (size == -1 && PyErr_Occurred()) { goto exit; } @@ -45,7 +39,7 @@ _testcapi_float_pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - le = _PyLong_AsInt(args[2]); + le = PyLong_AsInt(args[2]); if (le == -1 && PyErr_Occurred()) { goto exit; } @@ -85,4 +79,4 @@ _testcapi_float_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=083e5df26cd5fbeb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=50146051f1341cce input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/long.c.h b/Modules/_testcapi/clinic/long.c.h index 95885e0ae17a6c..e2f7042be12c48 100644 --- a/Modules/_testcapi/clinic/long.c.h +++ b/Modules/_testcapi/clinic/long.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_testcapi_test_long_api__doc__, "test_long_api($module, /)\n" "--\n" @@ -139,23 +133,6 @@ _testcapi_test_long_as_double(PyObject *module, PyObject *Py_UNUSED(ignored)) return _testcapi_test_long_as_double_impl(module); } -PyDoc_STRVAR(_testcapi_test_long_numbits__doc__, -"test_long_numbits($module, /)\n" -"--\n" -"\n"); - -#define _TESTCAPI_TEST_LONG_NUMBITS_METHODDEF \ - {"test_long_numbits", (PyCFunction)_testcapi_test_long_numbits, METH_NOARGS, _testcapi_test_long_numbits__doc__}, - -static PyObject * -_testcapi_test_long_numbits_impl(PyObject *module); - -static PyObject * -_testcapi_test_long_numbits(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _testcapi_test_long_numbits_impl(module); -} - PyDoc_STRVAR(_testcapi_call_long_compact_api__doc__, "call_long_compact_api($module, arg, /)\n" "--\n" @@ -163,4 +140,12 @@ PyDoc_STRVAR(_testcapi_call_long_compact_api__doc__, #define _TESTCAPI_CALL_LONG_COMPACT_API_METHODDEF \ {"call_long_compact_api", (PyCFunction)_testcapi_call_long_compact_api, METH_O, _testcapi_call_long_compact_api__doc__}, -/*[clinic end generated code: output=d000a1b58fa81eab input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_testcapi_PyLong_AsInt__doc__, +"PyLong_AsInt($module, arg, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_PYLONG_ASINT_METHODDEF \ + {"PyLong_AsInt", (PyCFunction)_testcapi_PyLong_AsInt, METH_O, _testcapi_PyLong_AsInt__doc__}, +/*[clinic end generated code: output=de762870526e241d input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/vectorcall.c.h b/Modules/_testcapi/clinic/vectorcall.c.h index 728c0d382565a7..48688e9ade050a 100644 --- a/Modules/_testcapi/clinic/vectorcall.c.h +++ b/Modules/_testcapi/clinic/vectorcall.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_testcapi_pyobject_fastcalldict__doc__, "pyobject_fastcalldict($module, func, func_args, kwargs, /)\n" "--\n" @@ -210,4 +204,4 @@ _testcapi_has_vectorcall_flag(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=beaf6beac3d13c25 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0667266b825ec9ec input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/vectorcall_limited.c.h b/Modules/_testcapi/clinic/vectorcall_limited.c.h new file mode 100644 index 00000000000000..a233aefec79ecd --- /dev/null +++ b/Modules/_testcapi/clinic/vectorcall_limited.c.h @@ -0,0 +1,20 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_testcapi_call_vectorcall__doc__, +"call_vectorcall($module, callable, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_CALL_VECTORCALL_METHODDEF \ + {"call_vectorcall", (PyCFunction)_testcapi_call_vectorcall, METH_O, _testcapi_call_vectorcall__doc__}, + +PyDoc_STRVAR(_testcapi_call_vectorcall_method__doc__, +"call_vectorcall_method($module, callable, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_CALL_VECTORCALL_METHOD_METHODDEF \ + {"call_vectorcall_method", (PyCFunction)_testcapi_call_vectorcall_method, METH_O, _testcapi_call_vectorcall_method__doc__}, +/*[clinic end generated code: output=e980906a39602528 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/watchers.c.h b/Modules/_testcapi/clinic/watchers.c.h index 975244bd59a36b..fd2ef608334049 100644 --- a/Modules/_testcapi/clinic/watchers.c.h +++ b/Modules/_testcapi/clinic/watchers.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_testcapi_watch_dict__doc__, "watch_dict($module, watcher_id, dict, /)\n" "--\n" @@ -29,7 +23,7 @@ _testcapi_watch_dict(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("watch_dict", nargs, 2, 2)) { goto exit; } - watcher_id = _PyLong_AsInt(args[0]); + watcher_id = PyLong_AsInt(args[0]); if (watcher_id == -1 && PyErr_Occurred()) { goto exit; } @@ -61,7 +55,7 @@ _testcapi_unwatch_dict(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (!_PyArg_CheckPositional("unwatch_dict", nargs, 2, 2)) { goto exit; } - watcher_id = _PyLong_AsInt(args[0]); + watcher_id = PyLong_AsInt(args[0]); if (watcher_id == -1 && PyErr_Occurred()) { goto exit; } @@ -93,7 +87,7 @@ _testcapi_watch_type(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("watch_type", nargs, 2, 2)) { goto exit; } - watcher_id = _PyLong_AsInt(args[0]); + watcher_id = PyLong_AsInt(args[0]); if (watcher_id == -1 && PyErr_Occurred()) { goto exit; } @@ -125,7 +119,7 @@ _testcapi_unwatch_type(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (!_PyArg_CheckPositional("unwatch_type", nargs, 2, 2)) { goto exit; } - watcher_id = _PyLong_AsInt(args[0]); + watcher_id = PyLong_AsInt(args[0]); if (watcher_id == -1 && PyErr_Occurred()) { goto exit; } @@ -195,4 +189,4 @@ _testcapi_set_func_kwdefaults_via_capi(PyObject *module, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=12c375089125d165 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5ad5771d6b29dfb9 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/code.c b/Modules/_testcapi/code.c index cadaf5eb94692e..c0193489b6f340 100644 --- a/Modules/_testcapi/code.c +++ b/Modules/_testcapi/code.c @@ -1,4 +1,5 @@ #include "parts.h" +#include "util.h" static Py_ssize_t get_code_extra_index(PyInterpreterState* interp) { @@ -9,12 +10,12 @@ get_code_extra_index(PyInterpreterState* interp) { PyObject *interp_dict = PyInterpreterState_GetDict(interp); // borrowed assert(interp_dict); // real users would handle missing dict... somehow - PyObject *index_obj = _PyDict_GetItemStringWithError(interp_dict, key); // borrowed + PyObject *index_obj; + if (PyDict_GetItemStringRef(interp_dict, key, &index_obj) < 0) { + goto finally; + } Py_ssize_t index = 0; if (!index_obj) { - if (PyErr_Occurred()) { - goto finally; - } index = PyUnstable_Eval_RequestCodeExtraIndex(NULL); if (index < 0 || PyErr_Occurred()) { goto finally; @@ -31,6 +32,7 @@ get_code_extra_index(PyInterpreterState* interp) { } else { index = PyLong_AsSsize_t(index_obj); + Py_DECREF(index_obj); if (index == -1 && PyErr_Occurred()) { goto finally; } @@ -74,7 +76,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable)) } // Check the value is initially NULL - void *extra; + void *extra = UNINITIALIZED_PTR; int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); if (res < 0) { goto finally; @@ -87,6 +89,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable)) goto finally; } // Assert it was set correctly + extra = UNINITIALIZED_PTR; res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); if (res < 0) { goto finally; diff --git a/Modules/_testcapi/dict.c b/Modules/_testcapi/dict.c new file mode 100644 index 00000000000000..5f6a1a037dcba2 --- /dev/null +++ b/Modules/_testcapi/dict.c @@ -0,0 +1,373 @@ +#include "parts.h" +#include "util.h" + + +static PyObject * +dict_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyDict_Check(obj)); +} + +static PyObject * +dict_checkexact(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyDict_CheckExact(obj)); +} + +static PyObject * +dict_new(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return PyDict_New(); +} + +static PyObject * +dictproxy_new(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDictProxy_New(obj); +} + +static PyObject * +dict_clear(PyObject *self, PyObject *obj) +{ + PyDict_Clear(obj); + Py_RETURN_NONE; +} + +static PyObject * +dict_copy(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Copy(obj); +} + +static PyObject * +dict_contains(PyObject *self, PyObject *args) +{ + PyObject *obj, *key; + if (!PyArg_ParseTuple(args, "OO", &obj, &key)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(key); + RETURN_INT(PyDict_Contains(obj, key)); +} + +static PyObject * +dict_containsstring(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &key, &size)) { + return NULL; + } + NULLABLE(obj); + RETURN_INT(PyDict_ContainsString(obj, key)); +} + +static PyObject * +dict_size(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyDict_Size(obj)); +} + +static PyObject * +dict_getitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + PyObject *value = PyDict_GetItem(mapping, key); + if (value == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return Py_NewRef(PyExc_KeyError); + } + return Py_NewRef(value); +} + +static PyObject * +dict_getitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + PyObject *value = PyDict_GetItemString(mapping, key); + if (value == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return Py_NewRef(PyExc_KeyError); + } + return Py_NewRef(value); +} + +static PyObject * +dict_getitemwitherror(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + PyObject *value = PyDict_GetItemWithError(mapping, key); + if (value == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return Py_NewRef(PyExc_KeyError); + } + return Py_NewRef(value); +} + + +static PyObject * +dict_getitemref(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + + switch (PyDict_GetItemRef(obj, attr_name, &value)) { + case -1: + assert(value == NULL); + return NULL; + case 0: + assert(value == NULL); + return Py_NewRef(PyExc_KeyError); + case 1: + return value; + default: + Py_FatalError("PyMapping_GetItemRef() returned invalid code"); + Py_UNREACHABLE(); + } +} + +static PyObject * +dict_getitemstringref(PyObject *self, PyObject *args) +{ + PyObject *obj, *value = UNINITIALIZED_PTR; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + + switch (PyDict_GetItemStringRef(obj, attr_name, &value)) { + case -1: + assert(value == NULL); + return NULL; + case 0: + assert(value == NULL); + return Py_NewRef(PyExc_KeyError); + case 1: + return value; + default: + Py_FatalError("PyDict_GetItemStringRef() returned invalid code"); + Py_UNREACHABLE(); + } +} + +static PyObject * +dict_setitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key, *value; + if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + NULLABLE(value); + RETURN_INT(PyDict_SetItem(mapping, key, value)); +} + +static PyObject * +dict_setitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping, *value; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#O", &mapping, &key, &size, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(value); + RETURN_INT(PyDict_SetItemString(mapping, key, value)); +} + +static PyObject * +dict_setdefault(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key, *defaultobj; + if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &defaultobj)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + NULLABLE(defaultobj); + return PyDict_SetDefault(mapping, key, defaultobj); +} + +static PyObject * +dict_delitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyDict_DelItem(mapping, key)); +} + +static PyObject * +dict_delitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + RETURN_INT(PyDict_DelItemString(mapping, key)); +} + +static PyObject * +dict_keys(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Keys(obj); +} + +static PyObject * +dict_values(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Values(obj); +} + +static PyObject * +dict_items(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Items(obj); +} + +static PyObject * +dict_next(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR; + Py_ssize_t pos; + if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) { + return NULL; + } + NULLABLE(mapping); + int rc = PyDict_Next(mapping, &pos, &key, &value); + if (rc != 0) { + return Py_BuildValue("inOO", rc, pos, key, value); + } + assert(key == UNINITIALIZED_PTR); + assert(value == UNINITIALIZED_PTR); + if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +dict_merge(PyObject *self, PyObject *args) +{ + PyObject *mapping, *mapping2; + int override; + if (!PyArg_ParseTuple(args, "OOi", &mapping, &mapping2, &override)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(mapping2); + RETURN_INT(PyDict_Merge(mapping, mapping2, override)); +} + +static PyObject * +dict_update(PyObject *self, PyObject *args) +{ + PyObject *mapping, *mapping2; + if (!PyArg_ParseTuple(args, "OO", &mapping, &mapping2)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(mapping2); + RETURN_INT(PyDict_Update(mapping, mapping2)); +} + +static PyObject * +dict_mergefromseq2(PyObject *self, PyObject *args) +{ + PyObject *mapping, *seq; + int override; + if (!PyArg_ParseTuple(args, "OOi", &mapping, &seq, &override)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(seq); + RETURN_INT(PyDict_MergeFromSeq2(mapping, seq, override)); +} + + +static PyMethodDef test_methods[] = { + {"dict_check", dict_check, METH_O}, + {"dict_checkexact", dict_checkexact, METH_O}, + {"dict_new", dict_new, METH_NOARGS}, + {"dictproxy_new", dictproxy_new, METH_O}, + {"dict_clear", dict_clear, METH_O}, + {"dict_copy", dict_copy, METH_O}, + {"dict_size", dict_size, METH_O}, + {"dict_getitem", dict_getitem, METH_VARARGS}, + {"dict_getitemwitherror", dict_getitemwitherror, METH_VARARGS}, + {"dict_getitemstring", dict_getitemstring, METH_VARARGS}, + {"dict_getitemref", dict_getitemref, METH_VARARGS}, + {"dict_getitemstringref", dict_getitemstringref, METH_VARARGS}, + {"dict_contains", dict_contains, METH_VARARGS}, + {"dict_containsstring", dict_containsstring, METH_VARARGS}, + {"dict_setitem", dict_setitem, METH_VARARGS}, + {"dict_setitemstring", dict_setitemstring, METH_VARARGS}, + {"dict_delitem", dict_delitem, METH_VARARGS}, + {"dict_delitemstring", dict_delitemstring, METH_VARARGS}, + {"dict_setdefault", dict_setdefault, METH_VARARGS}, + {"dict_keys", dict_keys, METH_O}, + {"dict_values", dict_values, METH_O}, + {"dict_items", dict_items, METH_O}, + {"dict_next", dict_next, METH_VARARGS}, + {"dict_merge", dict_merge, METH_VARARGS}, + {"dict_update", dict_update, METH_VARARGS}, + {"dict_mergefromseq2", dict_mergefromseq2, METH_VARARGS}, + + {NULL}, +}; + +int +_PyTestCapi_Init_Dict(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/docstring.c b/Modules/_testcapi/docstring.c index a997c54a8a69c4..d99fbdd904b594 100644 --- a/Modules/_testcapi/docstring.c +++ b/Modules/_testcapi/docstring.c @@ -66,42 +66,132 @@ test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) static PyMethodDef test_methods[] = { {"docstring_empty", - (PyCFunction)test_with_docstring, METH_NOARGS, + (PyCFunction)test_with_docstring, METH_VARARGS, docstring_empty}, {"docstring_no_signature", + (PyCFunction)test_with_docstring, METH_VARARGS, + docstring_no_signature}, + {"docstring_no_signature_noargs", (PyCFunction)test_with_docstring, METH_NOARGS, docstring_no_signature}, + {"docstring_no_signature_o", + (PyCFunction)test_with_docstring, METH_O, + docstring_no_signature}, {"docstring_with_invalid_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, + (PyCFunction)test_with_docstring, METH_VARARGS, docstring_with_invalid_signature}, {"docstring_with_invalid_signature2", - (PyCFunction)test_with_docstring, METH_NOARGS, + (PyCFunction)test_with_docstring, METH_VARARGS, docstring_with_invalid_signature2}, {"docstring_with_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, + (PyCFunction)test_with_docstring, METH_VARARGS, docstring_with_signature}, {"docstring_with_signature_and_extra_newlines", - (PyCFunction)test_with_docstring, METH_NOARGS, + (PyCFunction)test_with_docstring, METH_VARARGS, docstring_with_signature_and_extra_newlines}, {"docstring_with_signature_but_no_doc", - (PyCFunction)test_with_docstring, METH_NOARGS, + (PyCFunction)test_with_docstring, METH_VARARGS, docstring_with_signature_but_no_doc}, {"docstring_with_signature_with_defaults", - (PyCFunction)test_with_docstring, METH_NOARGS, + (PyCFunction)test_with_docstring, METH_VARARGS, docstring_with_signature_with_defaults}, {"no_docstring", - (PyCFunction)test_with_docstring, METH_NOARGS}, + (PyCFunction)test_with_docstring, METH_VARARGS}, {"test_with_docstring", - test_with_docstring, METH_NOARGS, + test_with_docstring, METH_VARARGS, PyDoc_STR("This is a pretty normal docstring.")}, + {"func_with_unrepresentable_signature", + (PyCFunction)test_with_docstring, METH_VARARGS, + PyDoc_STR( + "func_with_unrepresentable_signature($module, /, a, b=)\n" + "--\n\n" + "This docstring has a signature with unrepresentable default." + )}, + {NULL}, +}; + +static PyMethodDef DocStringNoSignatureTest_methods[] = { + {"meth_noargs", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_no_signature}, + {"meth_o", + (PyCFunction)test_with_docstring, METH_O, + docstring_no_signature}, + {"meth_noargs_class", + (PyCFunction)test_with_docstring, METH_NOARGS|METH_CLASS, + docstring_no_signature}, + {"meth_o_class", + (PyCFunction)test_with_docstring, METH_O|METH_CLASS, + docstring_no_signature}, + {"meth_noargs_static", + (PyCFunction)test_with_docstring, METH_NOARGS|METH_STATIC, + docstring_no_signature}, + {"meth_o_static", + (PyCFunction)test_with_docstring, METH_O|METH_STATIC, + docstring_no_signature}, + {"meth_noargs_coexist", + (PyCFunction)test_with_docstring, METH_NOARGS|METH_COEXIST, + docstring_no_signature}, + {"meth_o_coexist", + (PyCFunction)test_with_docstring, METH_O|METH_COEXIST, + docstring_no_signature}, + {NULL}, +}; + +static PyTypeObject DocStringNoSignatureTest = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testcapi.DocStringNoSignatureTest", + .tp_basicsize = sizeof(PyObject), + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = DocStringNoSignatureTest_methods, + .tp_new = PyType_GenericNew, +}; + +static PyMethodDef DocStringUnrepresentableSignatureTest_methods[] = { + {"meth", + (PyCFunction)test_with_docstring, METH_VARARGS, + PyDoc_STR( + "meth($self, /, a, b=)\n" + "--\n\n" + "This docstring has a signature with unrepresentable default." + )}, + {"classmeth", + (PyCFunction)test_with_docstring, METH_VARARGS|METH_CLASS, + PyDoc_STR( + "classmeth($type, /, a, b=)\n" + "--\n\n" + "This docstring has a signature with unrepresentable default." + )}, + {"staticmeth", + (PyCFunction)test_with_docstring, METH_VARARGS|METH_STATIC, + PyDoc_STR( + "staticmeth(a, b=)\n" + "--\n\n" + "This docstring has a signature with unrepresentable default." + )}, {NULL}, }; +static PyTypeObject DocStringUnrepresentableSignatureTest = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testcapi.DocStringUnrepresentableSignatureTest", + .tp_basicsize = sizeof(PyObject), + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = DocStringUnrepresentableSignatureTest_methods, + .tp_new = PyType_GenericNew, +}; + int _PyTestCapi_Init_Docstring(PyObject *mod) { if (PyModule_AddFunctions(mod, test_methods) < 0) { return -1; } + if (PyModule_AddType(mod, &DocStringNoSignatureTest) < 0) { + return -1; + } + if (PyModule_AddType(mod, &DocStringUnrepresentableSignatureTest) < 0) { + return -1; + } return 0; } diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index a627bf1717fe0c..b54ce0cbb0dd20 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -1,6 +1,8 @@ #include "parts.h" +#include "util.h" #include "clinic/exceptions.c.h" + /*[clinic input] module _testcapi [clinic start generated code]*/ @@ -118,17 +120,57 @@ _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, PyObject *obj) /*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/ { - PyObject *type; - PyObject *value; - PyObject *tb; + PyObject *type = UNINITIALIZED_PTR; + PyObject *value = UNINITIALIZED_PTR; + PyObject *tb = UNINITIALIZED_PTR; PyErr_SetObject(exc, obj); PyErr_Fetch(&type, &value, &tb); + assert(type != UNINITIALIZED_PTR); + assert(value != UNINITIALIZED_PTR); + assert(tb != UNINITIALIZED_PTR); Py_XDECREF(type); Py_XDECREF(tb); return value; } +/*[clinic input] +_testcapi.err_setstring + exc: object + value: str(zeroes=True, accept={robuffer, str, NoneType}) + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_err_setstring_impl(PyObject *module, PyObject *exc, + const char *value, Py_ssize_t value_length) +/*[clinic end generated code: output=fba8705e5703dd3f input=e8a95fad66d9004b]*/ +{ + NULLABLE(exc); + PyErr_SetString(exc, value); + return NULL; +} + +/*[clinic input] +_testcapi.err_setfromerrnowithfilename + error: int + exc: object + value: str(zeroes=True, accept={robuffer, str, NoneType}) + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_err_setfromerrnowithfilename_impl(PyObject *module, int error, + PyObject *exc, const char *value, + Py_ssize_t value_length) +/*[clinic end generated code: output=d02df5749a01850e input=ff7c384234bf097f]*/ +{ + NULLABLE(exc); + errno = error; + PyErr_SetFromErrnoWithFilename(exc, value); + return NULL; +} + /*[clinic input] _testcapi.raise_exception exception as exc: object @@ -205,7 +247,7 @@ _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, PyObject *new_value, PyObject *new_tb) /*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/ { - PyObject *type, *value, *tb; + PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR; PyErr_GetExcInfo(&type, &value, &tb); Py_INCREF(new_type); @@ -239,36 +281,6 @@ _testcapi_set_exception(PyObject *module, PyObject *new_exc) return exc; } -/*[clinic input] -_testcapi.write_unraisable_exc - exception as exc: object - err_msg: object - obj: object - / -[clinic start generated code]*/ - -static PyObject * -_testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, - PyObject *err_msg, PyObject *obj) -/*[clinic end generated code: output=39827c5e0a8c2092 input=582498da5b2ee6cf]*/ -{ - - const char *err_msg_utf8; - if (err_msg != Py_None) { - err_msg_utf8 = PyUnicode_AsUTF8(err_msg); - if (err_msg_utf8 == NULL) { - return NULL; - } - } - else { - err_msg_utf8 = NULL; - } - - PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); - _PyErr_WriteUnraisableMsg(err_msg_utf8, obj); - Py_RETURN_NONE; -} - /*[clinic input] _testcapi.traceback_print traceback: object @@ -338,12 +350,13 @@ static PyMethodDef test_methods[] = { _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF _TESTCAPI_EXC_SET_OBJECT_METHODDEF _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF + _TESTCAPI_ERR_SETSTRING_METHODDEF + _TESTCAPI_ERR_SETFROMERRNOWITHFILENAME_METHODDEF _TESTCAPI_RAISE_EXCEPTION_METHODDEF _TESTCAPI_RAISE_MEMORYERROR_METHODDEF _TESTCAPI_SET_EXC_INFO_METHODDEF _TESTCAPI_SET_EXCEPTION_METHODDEF _TESTCAPI_TRACEBACK_PRINT_METHODDEF - _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF _TESTCAPI_UNSTABLE_EXC_PREP_RERAISE_STAR_METHODDEF {NULL}, }; diff --git a/Modules/_testcapi/getargs.c b/Modules/_testcapi/getargs.c index 10a1c1dd05253d..86d8f5984dd3e5 100644 --- a/Modules/_testcapi/getargs.c +++ b/Modules/_testcapi/getargs.c @@ -13,9 +13,9 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) const char *sub_format; PyObject *sub_keywords; - double buffers[8][4]; /* double ensures alignment where necessary */ - PyObject *converted[8]; - char *keywords[8 + 1]; /* space for NULL at end */ +#define MAX_PARAMS 8 + double buffers[MAX_PARAMS][4]; /* double ensures alignment where necessary */ + char *keywords[MAX_PARAMS + 1]; /* space for NULL at end */ PyObject *return_value = NULL; @@ -35,11 +35,10 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) } memset(buffers, 0, sizeof(buffers)); - memset(converted, 0, sizeof(converted)); memset(keywords, 0, sizeof(keywords)); Py_ssize_t size = PySequence_Fast_GET_SIZE(sub_keywords); - if (size > 8) { + if (size > MAX_PARAMS) { PyErr_SetString(PyExc_ValueError, "parse_tuple_and_keywords: too many keywords in sub_keywords"); goto exit; @@ -47,29 +46,56 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) for (Py_ssize_t i = 0; i < size; i++) { PyObject *o = PySequence_Fast_GET_ITEM(sub_keywords, i); - if (!PyUnicode_FSConverter(o, (void *)(converted + i))) { + if (PyUnicode_Check(o)) { + keywords[i] = (char *)PyUnicode_AsUTF8(o); + if (keywords[i] == NULL) { + goto exit; + } + } + else if (PyBytes_Check(o)) { + keywords[i] = PyBytes_AS_STRING(o); + } + else { PyErr_Format(PyExc_ValueError, "parse_tuple_and_keywords: " - "could not convert keywords[%zd] to narrow string", i); + "keywords must be str or bytes", i); goto exit; } - keywords[i] = PyBytes_AS_STRING(converted[i]); } + assert(MAX_PARAMS == 8); int result = PyArg_ParseTupleAndKeywords(sub_args, sub_kwargs, sub_format, keywords, buffers + 0, buffers + 1, buffers + 2, buffers + 3, buffers + 4, buffers + 5, buffers + 6, buffers + 7); if (result) { - return_value = Py_NewRef(Py_None); + int objects_only = 1; + for (const char *f = sub_format; *f; f++) { + if (Py_ISALNUM(*f) && strchr("OSUY", *f) == NULL) { + objects_only = 0; + break; + } + } + if (objects_only) { + return_value = PyTuple_New(size); + if (return_value == NULL) { + goto exit; + } + for (Py_ssize_t i = 0; i < size; i++) { + PyObject *arg = *(PyObject **)(buffers + i); + if (arg == NULL) { + arg = Py_None; + } + PyTuple_SET_ITEM(return_value, i, Py_NewRef(arg)); + } + } + else { + return_value = Py_NewRef(Py_None); + } } exit: - size = sizeof(converted) / sizeof(converted[0]); - for (Py_ssize_t i = 0; i < size; i++) { - Py_XDECREF(converted[i]); - } return return_value; } @@ -589,54 +615,6 @@ getargs_y_hash(PyObject *self, PyObject *args) return PyBytes_FromStringAndSize(str, size); } -static PyObject * -getargs_u(PyObject *self, PyObject *args) -{ - wchar_t *str; - if (!PyArg_ParseTuple(args, "u", &str)) { - return NULL; - } - return PyUnicode_FromWideChar(str, -1); -} - -static PyObject * -getargs_u_hash(PyObject *self, PyObject *args) -{ - wchar_t *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "u#", &str, &size)) { - return NULL; - } - return PyUnicode_FromWideChar(str, size); -} - -static PyObject * -getargs_Z(PyObject *self, PyObject *args) -{ - wchar_t *str; - if (!PyArg_ParseTuple(args, "Z", &str)) { - return NULL; - } - if (str != NULL) { - return PyUnicode_FromWideChar(str, -1); - } - Py_RETURN_NONE; -} - -static PyObject * -getargs_Z_hash(PyObject *self, PyObject *args) -{ - wchar_t *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "Z#", &str, &size)) { - return NULL; - } - if (str != NULL) { - return PyUnicode_FromWideChar(str, size); - } - Py_RETURN_NONE; -} - static PyObject * getargs_es(PyObject *self, PyObject *args) { @@ -845,8 +823,6 @@ static PyMethodDef test_methods[] = { {"getargs_S", getargs_S, METH_VARARGS}, {"getargs_U", getargs_U, METH_VARARGS}, {"getargs_Y", getargs_Y, METH_VARARGS}, - {"getargs_Z", getargs_Z, METH_VARARGS}, - {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, {"getargs_b", getargs_b, METH_VARARGS}, {"getargs_c", getargs_c, METH_VARARGS}, {"getargs_d", getargs_d, METH_VARARGS}, @@ -868,8 +844,6 @@ static PyMethodDef test_methods[] = { {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, {"getargs_s_star", getargs_s_star, METH_VARARGS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, - {"getargs_u", getargs_u, METH_VARARGS}, - {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, {"getargs_w_star", getargs_w_star, METH_VARARGS}, {"getargs_y", getargs_y, METH_VARARGS}, {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index c124871e433431..4526583a8059d9 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -1,5 +1,6 @@ #include "parts.h" -#include "structmember.h" // PyMemberDef +#include // offsetof() + static struct PyModuleDef *_testcapimodule = NULL; // set at initialization @@ -332,7 +333,7 @@ typedef struct { static struct PyMemberDef members_to_repeat[] = { - {"T_INT", T_INT, offsetof(HeapCTypeWithDataObject, data), 0, NULL}, + {"Py_T_INT", Py_T_INT, offsetof(HeapCTypeWithDataObject, data), 0, NULL}, {NULL} }; @@ -477,7 +478,7 @@ typedef struct { } HeapCTypeObject; static struct PyMemberDef heapctype_members[] = { - {"value", T_INT, offsetof(HeapCTypeObject, value)}, + {"value", Py_T_INT, offsetof(HeapCTypeObject, value)}, {NULL} /* Sentinel */ }; @@ -571,7 +572,7 @@ heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) } static struct PyMemberDef heapctypesubclass_members[] = { - {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, + {"value2", Py_T_INT, offsetof(HeapCTypeSubclassObject, value2)}, {NULL} /* Sentinel */ }; @@ -772,8 +773,8 @@ static PyGetSetDef heapctypewithdict_getsetlist[] = { }; static struct PyMemberDef heapctypewithdict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY}, + {"dictobj", _Py_T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -804,13 +805,13 @@ static int heapmanaged_traverse(HeapCTypeObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); - return _PyObject_VisitManagedDict((PyObject *)self, visit, arg); + return PyObject_VisitManagedDict((PyObject *)self, visit, arg); } static int heapmanaged_clear(HeapCTypeObject *self) { - _PyObject_ClearManagedDict((PyObject *)self); + PyObject_ClearManagedDict((PyObject *)self); return 0; } @@ -818,7 +819,7 @@ static void heapmanaged_dealloc(HeapCTypeObject *self) { PyTypeObject *tp = Py_TYPE(self); - _PyObject_ClearManagedDict((PyObject *)self); + PyObject_ClearManagedDict((PyObject *)self); PyObject_GC_UnTrack(self); PyObject_GC_Del(self); Py_DECREF(tp); @@ -867,8 +868,8 @@ static PyType_Spec HeapCTypeWithManagedWeakref_spec = { }; static struct PyMemberDef heapctypewithnegativedict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, + {"dictobj", _Py_T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", Py_T_PYSSIZET, -(Py_ssize_t)sizeof(void*), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -893,9 +894,9 @@ typedef struct { } HeapCTypeWithWeakrefObject; static struct PyMemberDef heapctypewithweakref_members[] = { - {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, - {"__weaklistoffset__", T_PYSSIZET, - offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY}, + {"weakreflist", _Py_T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, + {"__weaklistoffset__", Py_T_PYSSIZET, + offsetof(HeapCTypeWithWeakrefObject, weakreflist), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -943,7 +944,7 @@ typedef struct { } HeapCTypeSetattrObject; static struct PyMemberDef heapctypesetattr_members[] = { - {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, + {"pvalue", Py_T_LONG, offsetof(HeapCTypeSetattrObject, value)}, {NULL} /* Sentinel */ }; @@ -1122,94 +1123,62 @@ _PyTestCapi_Init_Heaptype(PyObject *m) { return -1; } +#define ADD(name, value) do { \ + if (PyModule_Add(m, name, value) < 0) { \ + return -1; \ + } \ + } while (0) + PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); - if (HeapDocCType == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapDocCType", HeapDocCType); + ADD("HeapDocCType", HeapDocCType); /* bpo-41832: Add a new type to test PyType_FromSpec() now can accept a NULL tp_doc slot. */ PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec); - if (NullTpDocType == NULL) { - return -1; - } - PyModule_AddObject(m, "NullTpDocType", NullTpDocType); + ADD("NullTpDocType", NullTpDocType); PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); - if (HeapGcCType == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapGcCType", HeapGcCType); + ADD("HeapGcCType", HeapGcCType); PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); if (HeapCType == NULL) { return -1; } PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); + Py_DECREF(HeapCType); if (subclass_bases == NULL) { return -1; } PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); - if (HeapCTypeSubclass == NULL) { - return -1; - } Py_DECREF(subclass_bases); - PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); + ADD("HeapCTypeSubclass", HeapCTypeSubclass); PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec); - if (HeapCTypeWithDict == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); + ADD("HeapCTypeWithDict", HeapCTypeWithDict); PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec); - if (HeapCTypeWithDict2 == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2); + ADD("HeapCTypeWithDict2", HeapCTypeWithDict2); PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); - if (HeapCTypeWithNegativeDict == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); + ADD("HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); PyObject *HeapCTypeWithManagedDict = PyType_FromSpec(&HeapCTypeWithManagedDict_spec); - if (HeapCTypeWithManagedDict == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithManagedDict", HeapCTypeWithManagedDict); + ADD("HeapCTypeWithManagedDict", HeapCTypeWithManagedDict); PyObject *HeapCTypeWithManagedWeakref = PyType_FromSpec(&HeapCTypeWithManagedWeakref_spec); - if (HeapCTypeWithManagedWeakref == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithManagedWeakref", HeapCTypeWithManagedWeakref); + ADD("HeapCTypeWithManagedWeakref", HeapCTypeWithManagedWeakref); PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); - if (HeapCTypeWithWeakref == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); + ADD("HeapCTypeWithWeakref", HeapCTypeWithWeakref); PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec); - if (HeapCTypeWithWeakref2 == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); + ADD("HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); - if (HeapCTypeWithBuffer == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); + ADD("HeapCTypeWithBuffer", HeapCTypeWithBuffer); PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); - if (HeapCTypeSetattr == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); + ADD("HeapCTypeSetattr", HeapCTypeSetattr); PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); if (subclass_with_finalizer_bases == NULL) { @@ -1217,32 +1186,20 @@ _PyTestCapi_Init_Heaptype(PyObject *m) { } PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); - if (HeapCTypeSubclassWithFinalizer == NULL) { - return -1; - } Py_DECREF(subclass_with_finalizer_bases); - PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); + ADD("HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); PyObject *HeapCTypeMetaclass = PyType_FromMetaclass( &PyType_Type, m, &HeapCTypeMetaclass_spec, (PyObject *) &PyType_Type); - if (HeapCTypeMetaclass == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeMetaclass", HeapCTypeMetaclass); + ADD("HeapCTypeMetaclass", HeapCTypeMetaclass); PyObject *HeapCTypeMetaclassCustomNew = PyType_FromMetaclass( &PyType_Type, m, &HeapCTypeMetaclassCustomNew_spec, (PyObject *) &PyType_Type); - if (HeapCTypeMetaclassCustomNew == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeMetaclassCustomNew", HeapCTypeMetaclassCustomNew); + ADD("HeapCTypeMetaclassCustomNew", HeapCTypeMetaclassCustomNew); PyObject *HeapCTypeMetaclassNullNew = PyType_FromMetaclass( &PyType_Type, m, &HeapCTypeMetaclassNullNew_spec, (PyObject *) &PyType_Type); - if (HeapCTypeMetaclassNullNew == NULL) { - return -1; - } - PyModule_AddObject(m, "HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew); + ADD("HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew); PyObject *HeapCCollection = PyType_FromMetaclass( NULL, m, &HeapCCollection_spec, NULL); diff --git a/Modules/_testcapi/heaptype_relative.c b/Modules/_testcapi/heaptype_relative.c index c247ca33b33708..53dd01d1ed4f80 100644 --- a/Modules/_testcapi/heaptype_relative.c +++ b/Modules/_testcapi/heaptype_relative.c @@ -3,8 +3,6 @@ #include // max_align_t #include // memset -#ifdef LIMITED_API_AVAILABLE - static PyType_Slot empty_slots[] = { {0, NULL}, }; @@ -339,5 +337,3 @@ _PyTestCapi_Init_HeaptypeRelative(PyObject *m) { return 0; } - -#endif // LIMITED_API_AVAILABLE diff --git a/Modules/_testcapi/long.c b/Modules/_testcapi/long.c index ede43f60d06f95..4362f431fc3f4d 100644 --- a/Modules/_testcapi/long.c +++ b/Modules/_testcapi/long.c @@ -1,3 +1,7 @@ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "parts.h" #include "clinic/long.c.h" @@ -37,6 +41,9 @@ raise_test_long_error(const char* msg) return raiseTestError("test_long_api", msg); } +// Test PyLong_FromLong()/PyLong_AsLong() +// and PyLong_FromUnsignedLong()/PyLong_AsUnsignedLong(). + #define TESTNAME test_long_api_inner #define TYPENAME long #define F_S_TO_PY PyLong_FromLong @@ -64,6 +71,9 @@ _testcapi_test_long_api_impl(PyObject *module) #undef F_U_TO_PY #undef F_PY_TO_U +// Test PyLong_FromLongLong()/PyLong_AsLongLong() +// and PyLong_FromUnsignedLongLong()/PyLong_AsUnsignedLongLong(). + static PyObject * raise_test_longlong_error(const char* msg) { @@ -524,57 +534,6 @@ _testcapi_test_long_as_double_impl(PyObject *module) return Py_None; } -/*[clinic input] -_testcapi.test_long_numbits -[clinic start generated code]*/ - -static PyObject * -_testcapi_test_long_numbits_impl(PyObject *module) -/*[clinic end generated code: output=9eaf8458cb15d7f7 input=265c02d48a13059e]*/ -{ - struct triple { - long input; - size_t nbits; - int sign; - } testcases[] = {{0, 0, 0}, - {1L, 1, 1}, - {-1L, 1, -1}, - {2L, 2, 1}, - {-2L, 2, -1}, - {3L, 2, 1}, - {-3L, 2, -1}, - {4L, 3, 1}, - {-4L, 3, -1}, - {0x7fffL, 15, 1}, /* one Python int digit */ - {-0x7fffL, 15, -1}, - {0xffffL, 16, 1}, - {-0xffffL, 16, -1}, - {0xfffffffL, 28, 1}, - {-0xfffffffL, 28, -1}}; - size_t i; - - for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { - size_t nbits; - int sign; - PyObject *plong; - - plong = PyLong_FromLong(testcases[i].input); - if (plong == NULL) - return NULL; - nbits = _PyLong_NumBits(plong); - sign = _PyLong_Sign(plong); - - Py_DECREF(plong); - if (nbits != testcases[i].nbits) - return raiseTestError("test_long_numbits", - "wrong result for _PyLong_NumBits"); - if (sign != testcases[i].sign) - return raiseTestError("test_long_numbits", - "wrong result for _PyLong_Sign"); - } - Py_RETURN_NONE; -} - /*[clinic input] _testcapi.call_long_compact_api arg: object @@ -595,6 +554,24 @@ _testcapi_call_long_compact_api(PyObject *module, PyObject *arg) return Py_BuildValue("in", is_compact, value); } +/*[clinic input] +_testcapi.PyLong_AsInt + arg: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_PyLong_AsInt(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=0df9f19de5fa575b input=9561b97105493a67]*/ +{ + assert(!PyErr_Occurred()); + int value = PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(value); +} + static PyMethodDef test_methods[] = { _TESTCAPI_TEST_LONG_AND_OVERFLOW_METHODDEF _TESTCAPI_TEST_LONG_API_METHODDEF @@ -602,9 +579,9 @@ static PyMethodDef test_methods[] = { _TESTCAPI_TEST_LONG_AS_SIZE_T_METHODDEF _TESTCAPI_TEST_LONG_AS_UNSIGNED_LONG_LONG_MASK_METHODDEF _TESTCAPI_TEST_LONG_LONG_AND_OVERFLOW_METHODDEF - _TESTCAPI_TEST_LONG_NUMBITS_METHODDEF _TESTCAPI_TEST_LONGLONG_API_METHODDEF _TESTCAPI_CALL_LONG_COMPACT_API_METHODDEF + _TESTCAPI_PYLONG_ASINT_METHODDEF {NULL}, }; diff --git a/Modules/_testcapi/mem.c b/Modules/_testcapi/mem.c index 979b3a4b2b1af6..ef9234d7f8955f 100644 --- a/Modules/_testcapi/mem.c +++ b/Modules/_testcapi/mem.c @@ -440,17 +440,6 @@ test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -static PyObject * -test_pymem_getallocatorsname(PyObject *self, PyObject *args) -{ - const char *name = _PyMem_GetCurrentAllocatorName(); - if (name == NULL) { - PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name"); - return NULL; - } - return PyUnicode_FromString(name); -} - static PyObject * test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -526,75 +515,6 @@ pymem_malloc_without_gil(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * -test_pyobject_is_freed(const char *test_name, PyObject *op) -{ - if (!_PyObject_IsFreed(op)) { - PyErr_SetString(PyExc_AssertionError, - "object is not seen as freed"); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject * -check_pyobject_null_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *op = NULL; - return test_pyobject_is_freed("check_pyobject_null_is_freed", op); -} - - -static PyObject * -check_pyobject_uninitialized_is_freed(PyObject *self, - PyObject *Py_UNUSED(args)) -{ - PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); - if (op == NULL) { - return NULL; - } - /* Initialize reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* object fields like ob_type are uninitialized! */ - return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); -} - - -static PyObject * -check_pyobject_forbidden_bytes_is_freed(PyObject *self, - PyObject *Py_UNUSED(args)) -{ - /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ - PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); - if (op == NULL) { - return NULL; - } - /* Initialize reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* ob_type field is after the memory block: part of "forbidden bytes" - when using debug hooks on memory allocators! */ - return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); -} - - -static PyObject * -check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - /* This test would fail if run with the address sanitizer */ -#ifdef _Py_ADDRESS_SANITIZER - Py_RETURN_NONE; -#else - PyObject *op = PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); - if (op == NULL) { - return NULL; - } - Py_TYPE(op)->tp_dealloc(op); - /* Reset reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* object memory is freed! */ - return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); -#endif -} // Tracemalloc tests static PyObject * @@ -656,15 +576,8 @@ tracemalloc_untrack(PyObject *self, PyObject *args) } static PyMethodDef test_methods[] = { - {"check_pyobject_forbidden_bytes_is_freed", - check_pyobject_forbidden_bytes_is_freed, METH_NOARGS}, - {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS}, - {"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS}, - {"check_pyobject_uninitialized_is_freed", - check_pyobject_uninitialized_is_freed, METH_NOARGS}, {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS}, - {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, {"remove_mem_hooks", remove_mem_hooks, METH_NOARGS, diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index aaec0a61916948..acdba86504f58e 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -1,31 +1,30 @@ #ifndef Py_TESTCAPI_PARTS_H #define Py_TESTCAPI_PARTS_H -#include "pyconfig.h" // for Py_TRACE_REFS - -// Figure out if Limited API is available for this build. If it isn't we won't -// build tests for it. -// Currently, only Py_TRACE_REFS disables Limited API. -#ifdef Py_TRACE_REFS -#undef LIMITED_API_AVAILABLE -#else -#define LIMITED_API_AVAILABLE 1 -#endif - // Always enable assertions #undef NDEBUG -#if !defined(LIMITED_API_AVAILABLE) && defined(Py_LIMITED_API) -// Limited API being unavailable means that with Py_LIMITED_API defined -// we can't even include Python.h. -// Do nothing; the .c file that defined Py_LIMITED_API should also do nothing. - -#else +// The _testcapi extension tests the public C API: header files in Include/ and +// Include/cpython/ directories. The internal C API must not be tested by +// _testcapi: use _testinternalcapi for that. +// +// _testcapi C files can built with the Py_BUILD_CORE_BUILTIN macro defined if +// one of the Modules/Setup files asks to build _testcapi as "static" +// (gh-109723). +// +// The Visual Studio projects builds _testcapi with Py_BUILD_CORE_MODULE. +#undef Py_BUILD_CORE_MODULE +#undef Py_BUILD_CORE_BUILTIN #include "Python.h" +#ifdef Py_BUILD_CORE +# error "_testcapi must test the public Python C API, not the internal C API" +#endif + int _PyTestCapi_Init_Vectorcall(PyObject *module); int _PyTestCapi_Init_Heaptype(PyObject *module); +int _PyTestCapi_Init_Abstract(PyObject *module); int _PyTestCapi_Init_Unicode(PyObject *module); int _PyTestCapi_Init_GetArgs(PyObject *module); int _PyTestCapi_Init_DateTime(PyObject *module); @@ -34,18 +33,18 @@ int _PyTestCapi_Init_Mem(PyObject *module); int _PyTestCapi_Init_Watchers(PyObject *module); int _PyTestCapi_Init_Long(PyObject *module); int _PyTestCapi_Init_Float(PyObject *module); +int _PyTestCapi_Init_Dict(PyObject *module); +int _PyTestCapi_Init_Set(PyObject *module); int _PyTestCapi_Init_Structmember(PyObject *module); int _PyTestCapi_Init_Exceptions(PyObject *module); int _PyTestCapi_Init_Code(PyObject *module); int _PyTestCapi_Init_Buffer(PyObject *module); +int _PyTestCapi_Init_PyAtomic(PyObject *module); int _PyTestCapi_Init_PyOS(PyObject *module); int _PyTestCapi_Init_Immortal(PyObject *module); int _PyTestCapi_Init_GC(PyObject *mod); -#ifdef LIMITED_API_AVAILABLE int _PyTestCapi_Init_VectorcallLimited(PyObject *module); int _PyTestCapi_Init_HeaptypeRelative(PyObject *module); -#endif // LIMITED_API_AVAILABLE -#endif #endif // Py_TESTCAPI_PARTS_H diff --git a/Modules/_testcapi/pyatomic.c b/Modules/_testcapi/pyatomic.c new file mode 100644 index 00000000000000..5aedf687705707 --- /dev/null +++ b/Modules/_testcapi/pyatomic.c @@ -0,0 +1,175 @@ +/* + * C Extension module to smoke test pyatomic.h API. + * + * This only tests basic functionality, not any synchronizing ordering. + */ + +#include "parts.h" + +// We define atomic bitwise operations on these types +#define FOR_BITWISE_TYPES(V) \ + V(uint8, uint8_t) \ + V(uint16, uint16_t) \ + V(uint32, uint32_t) \ + V(uint64, uint64_t) \ + V(uintptr, uintptr_t) + +// We define atomic addition on these types +#define FOR_ARITHMETIC_TYPES(V) \ + FOR_BITWISE_TYPES(V) \ + V(int, int) \ + V(uint, unsigned int) \ + V(int8, int8_t) \ + V(int16, int16_t) \ + V(int32, int32_t) \ + V(int64, int64_t) \ + V(intptr, intptr_t) \ + V(ssize, Py_ssize_t) + +// We define atomic load, store, exchange, and compare_exchange on these types +#define FOR_ALL_TYPES(V) \ + FOR_ARITHMETIC_TYPES(V) \ + V(ptr, void*) + +#define IMPL_TEST_ADD(suffix, dtype) \ +static PyObject * \ +test_atomic_add_##suffix(PyObject *self, PyObject *obj) { \ + dtype x = 0; \ + assert(_Py_atomic_add_##suffix(&x, 1) == 0); \ + assert(x == 1); \ + assert(_Py_atomic_add_##suffix(&x, 2) == 1); \ + assert(x == 3); \ + assert(_Py_atomic_add_##suffix(&x, -2) == 3); \ + assert(x == 1); \ + assert(_Py_atomic_add_##suffix(&x, -1) == 1); \ + assert(x == 0); \ + assert(_Py_atomic_add_##suffix(&x, -1) == 0); \ + assert(x == (dtype)-1); \ + assert(_Py_atomic_add_##suffix(&x, -2) == (dtype)-1); \ + assert(x == (dtype)-3); \ + assert(_Py_atomic_add_##suffix(&x, 2) == (dtype)-3); \ + assert(x == (dtype)-1); \ + Py_RETURN_NONE; \ +} +FOR_ARITHMETIC_TYPES(IMPL_TEST_ADD) + +#define IMPL_TEST_COMPARE_EXCHANGE(suffix, dtype) \ +static PyObject * \ +test_atomic_compare_exchange_##suffix(PyObject *self, PyObject *obj) { \ + dtype x = (dtype)0; \ + dtype y = (dtype)1; \ + dtype z = (dtype)2; \ + assert(_Py_atomic_compare_exchange_##suffix(&x, &y, z) == 0); \ + assert(x == 0); \ + assert(y == 0); \ + assert(_Py_atomic_compare_exchange_##suffix(&x, &y, z) == 1); \ + assert(x == z); \ + assert(y == 0); \ + assert(_Py_atomic_compare_exchange_##suffix(&x, &y, z) == 0); \ + assert(x == z); \ + assert(y == z); \ + Py_RETURN_NONE; \ +} +FOR_ALL_TYPES(IMPL_TEST_COMPARE_EXCHANGE) + +#define IMPL_TEST_EXCHANGE(suffix, dtype) \ +static PyObject * \ +test_atomic_exchange_##suffix(PyObject *self, PyObject *obj) { \ + dtype x = (dtype)0; \ + dtype y = (dtype)1; \ + dtype z = (dtype)2; \ + assert(_Py_atomic_exchange_##suffix(&x, y) == (dtype)0); \ + assert(x == (dtype)1); \ + assert(_Py_atomic_exchange_##suffix(&x, z) == (dtype)1); \ + assert(x == (dtype)2); \ + assert(_Py_atomic_exchange_##suffix(&x, y) == (dtype)2); \ + assert(x == (dtype)1); \ + Py_RETURN_NONE; \ +} +FOR_ALL_TYPES(IMPL_TEST_EXCHANGE) + +#define IMPL_TEST_LOAD_STORE(suffix, dtype) \ +static PyObject * \ +test_atomic_load_store_##suffix(PyObject *self, PyObject *obj) { \ + dtype x = (dtype)0; \ + dtype y = (dtype)1; \ + dtype z = (dtype)2; \ + assert(_Py_atomic_load_##suffix(&x) == (dtype)0); \ + assert(x == (dtype)0); \ + _Py_atomic_store_##suffix(&x, y); \ + assert(_Py_atomic_load_##suffix(&x) == (dtype)1); \ + assert(x == (dtype)1); \ + _Py_atomic_store_##suffix##_relaxed(&x, z); \ + assert(_Py_atomic_load_##suffix##_relaxed(&x) == (dtype)2); \ + assert(x == (dtype)2); \ + Py_RETURN_NONE; \ +} +FOR_ALL_TYPES(IMPL_TEST_LOAD_STORE) + +#define IMPL_TEST_AND_OR(suffix, dtype) \ +static PyObject * \ +test_atomic_and_or_##suffix(PyObject *self, PyObject *obj) { \ + dtype x = (dtype)0; \ + dtype y = (dtype)1; \ + dtype z = (dtype)3; \ + assert(_Py_atomic_or_##suffix(&x, z) == (dtype)0); \ + assert(x == (dtype)3); \ + assert(_Py_atomic_and_##suffix(&x, y) == (dtype)3); \ + assert(x == (dtype)1); \ + Py_RETURN_NONE; \ +} +FOR_BITWISE_TYPES(IMPL_TEST_AND_OR) + +static PyObject * +test_atomic_fences(PyObject *self, PyObject *obj) { + // Just make sure that the fences compile. We are not + // testing any synchronizing ordering. + _Py_atomic_fence_seq_cst(); + _Py_atomic_fence_release(); + Py_RETURN_NONE; +} + +static PyObject * +test_atomic_release_acquire(PyObject *self, PyObject *obj) { + void *x = NULL; + void *y = &y; + assert(_Py_atomic_load_ptr_acquire(&x) == NULL); + _Py_atomic_store_ptr_release(&x, y); + assert(x == y); + assert(_Py_atomic_load_ptr_acquire(&x) == y); + Py_RETURN_NONE; +} + +// NOTE: all tests should start with "test_atomic_" to be included +// in test_pyatomic.py + +#define BIND_TEST_ADD(suffix, dtype) \ + {"test_atomic_add_" #suffix, test_atomic_add_##suffix, METH_NOARGS}, +#define BIND_TEST_COMPARE_EXCHANGE(suffix, dtype) \ + {"test_atomic_compare_exchange_" #suffix, test_atomic_compare_exchange_##suffix, METH_NOARGS}, +#define BIND_TEST_EXCHANGE(suffix, dtype) \ + {"test_atomic_exchange_" #suffix, test_atomic_exchange_##suffix, METH_NOARGS}, +#define BIND_TEST_LOAD_STORE(suffix, dtype) \ + {"test_atomic_load_store_" #suffix, test_atomic_load_store_##suffix, METH_NOARGS}, +#define BIND_TEST_AND_OR(suffix, dtype) \ + {"test_atomic_and_or_" #suffix, test_atomic_and_or_##suffix, METH_NOARGS}, + +static PyMethodDef test_methods[] = { + FOR_ARITHMETIC_TYPES(BIND_TEST_ADD) + FOR_ALL_TYPES(BIND_TEST_COMPARE_EXCHANGE) + FOR_ALL_TYPES(BIND_TEST_EXCHANGE) + FOR_ALL_TYPES(BIND_TEST_LOAD_STORE) + FOR_BITWISE_TYPES(BIND_TEST_AND_OR) + {"test_atomic_fences", test_atomic_fences, METH_NOARGS}, + {"test_atomic_release_acquire", test_atomic_release_acquire, METH_NOARGS}, + {NULL, NULL} /* sentinel */ +}; + +int +_PyTestCapi_Init_PyAtomic(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/set.c b/Modules/_testcapi/set.c new file mode 100644 index 00000000000000..2fbd0aeffcd9f9 --- /dev/null +++ b/Modules/_testcapi/set.c @@ -0,0 +1,197 @@ +#include "parts.h" +#include "util.h" + +static PyObject * +set_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PySet_Check(obj)); +} + +static PyObject * +set_checkexact(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PySet_CheckExact(obj)); +} + +static PyObject * +frozenset_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PyFrozenSet_Check(obj)); +} + +static PyObject * +frozenset_checkexact(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PyFrozenSet_CheckExact(obj)); +} + +static PyObject * +anyset_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PyAnySet_Check(obj)); +} + +static PyObject * +anyset_checkexact(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PyAnySet_CheckExact(obj)); +} + +static PyObject * +set_new(PyObject *self, PyObject *args) +{ + PyObject *iterable = NULL; + if (!PyArg_ParseTuple(args, "|O", &iterable)) { + return NULL; + } + return PySet_New(iterable); +} + +static PyObject * +frozenset_new(PyObject *self, PyObject *args) +{ + PyObject *iterable = NULL; + if (!PyArg_ParseTuple(args, "|O", &iterable)) { + return NULL; + } + return PyFrozenSet_New(iterable); +} + +static PyObject * +set_size(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PySet_Size(obj)); +} + +static PyObject * +set_get_size(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PySet_GET_SIZE(obj)); +} + +static PyObject * +set_contains(PyObject *self, PyObject *args) +{ + PyObject *obj, *item; + if (!PyArg_ParseTuple(args, "OO", &obj, &item)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(item); + RETURN_INT(PySet_Contains(obj, item)); +} + +static PyObject * +set_add(PyObject *self, PyObject *args) +{ + PyObject *obj, *item; + if (!PyArg_ParseTuple(args, "OO", &obj, &item)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(item); + RETURN_INT(PySet_Add(obj, item)); +} + +static PyObject * +set_discard(PyObject *self, PyObject *args) +{ + PyObject *obj, *item; + if (!PyArg_ParseTuple(args, "OO", &obj, &item)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(item); + RETURN_INT(PySet_Discard(obj, item)); +} + +static PyObject * +set_pop(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PySet_Pop(obj); +} + +static PyObject * +set_clear(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PySet_Clear(obj)); +} + +static PyObject * +test_frozenset_add_in_capi(PyObject *self, PyObject *Py_UNUSED(obj)) +{ + // Test that `frozenset` can be used with `PySet_Add`, + // when frozenset is just created in CAPI. + PyObject *fs = PyFrozenSet_New(NULL); + if (fs == NULL) { + return NULL; + } + PyObject *num = PyLong_FromLong(1); + if (num == NULL) { + goto error; + } + if (PySet_Add(fs, num) < 0) { + goto error; + } + int contains = PySet_Contains(fs, num); + if (contains < 0) { + goto error; + } + else if (contains == 0) { + goto unexpected; + } + Py_DECREF(fs); + Py_DECREF(num); + Py_RETURN_NONE; + +unexpected: + PyErr_SetString(PyExc_ValueError, "set does not contain expected value"); +error: + Py_DECREF(fs); + Py_XDECREF(num); + return NULL; +} + +static PyMethodDef test_methods[] = { + {"set_check", set_check, METH_O}, + {"set_checkexact", set_checkexact, METH_O}, + {"frozenset_check", frozenset_check, METH_O}, + {"frozenset_checkexact", frozenset_checkexact, METH_O}, + {"anyset_check", anyset_check, METH_O}, + {"anyset_checkexact", anyset_checkexact, METH_O}, + + {"set_new", set_new, METH_VARARGS}, + {"frozenset_new", frozenset_new, METH_VARARGS}, + + {"set_size", set_size, METH_O}, + {"set_get_size", set_get_size, METH_O}, + {"set_contains", set_contains, METH_VARARGS}, + {"set_add", set_add, METH_VARARGS}, + {"set_discard", set_discard, METH_VARARGS}, + {"set_pop", set_pop, METH_O}, + {"set_clear", set_clear, METH_O}, + + {"test_frozenset_add_in_capi", test_frozenset_add_in_capi, METH_NOARGS}, + + {NULL}, +}; + +int +_PyTestCapi_Init_Set(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/structmember.c b/Modules/_testcapi/structmember.c index 8522dc962efa40..096eaecd40855f 100644 --- a/Modules/_testcapi/structmember.c +++ b/Modules/_testcapi/structmember.c @@ -193,7 +193,7 @@ _PyTestCapi_Init_Structmember(PyObject *m) if (res < 0) { return -1; } - res = PyModule_AddObject( + res = PyModule_AddObjectRef( m, "_test_structmembersType_OldAPI", (PyObject *)&test_structmembersType_OldAPI); diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c index b4c6c4b5e3ce1a..d52d88a65d86fc 100644 --- a/Modules/_testcapi/unicode.c +++ b/Modules/_testcapi/unicode.c @@ -1,6 +1,7 @@ #include // ptrdiff_t #include "parts.h" +#include "util.h" static struct PyModuleDef *_testcapimodule = NULL; // set at initialization @@ -101,7 +102,6 @@ test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -#define NULLABLE(x) do { if (x == Py_None) x = NULL; } while (0); static PyObject * unicode_copy(PyObject *unicode) @@ -347,13 +347,8 @@ unicode_substring(PyObject *self, PyObject *args) static PyObject * unicode_getlength(PyObject *self, PyObject *arg) { - Py_ssize_t result; - NULLABLE(arg); - result = PyUnicode_GetLength(arg); - if (result == -1) - return NULL; - return PyLong_FromSsize_t(result); + RETURN_SIZE(PyUnicode_GetLength(arg)); } /* Test PyUnicode_ReadChar() */ @@ -482,16 +477,12 @@ static PyObject * unicode_aswidechar_null(PyObject *self, PyObject *args) { PyObject *unicode; - Py_ssize_t buflen, size; + Py_ssize_t buflen; if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) return NULL; NULLABLE(unicode); - size = PyUnicode_AsWideChar(unicode, NULL, buflen); - if (size == -1) { - return NULL; - } - return PyLong_FromSsize_t(size); + RETURN_SIZE(PyUnicode_AsWideChar(unicode, NULL, buflen)); } /* Test PyUnicode_AsWideCharString() */ @@ -499,7 +490,7 @@ static PyObject * unicode_aswidecharstring(PyObject *self, PyObject *args) { PyObject *unicode, *result; - Py_ssize_t size = 100; + Py_ssize_t size = UNINITIALIZED_SIZE; wchar_t *buffer; if (!PyArg_ParseTuple(args, "O", &unicode)) @@ -507,8 +498,10 @@ unicode_aswidecharstring(PyObject *self, PyObject *args) NULLABLE(unicode); buffer = PyUnicode_AsWideCharString(unicode, &size); - if (buffer == NULL) + if (buffer == NULL) { + assert(size == UNINITIALIZED_SIZE); return NULL; + } result = PyUnicode_FromWideChar(buffer, size + 1); PyMem_Free(buffer); @@ -633,15 +626,17 @@ unicode_asutf8andsize(PyObject *self, PyObject *args) PyObject *unicode; Py_ssize_t buflen; const char *s; - Py_ssize_t size = -100; + Py_ssize_t size = UNINITIALIZED_SIZE; if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) return NULL; NULLABLE(unicode); s = PyUnicode_AsUTF8AndSize(unicode, &size); - if (s == NULL) + if (s == NULL) { + assert(size == UNINITIALIZED_SIZE); return NULL; + } return Py_BuildValue("(y#n)", s, buflen, size); } @@ -735,7 +730,7 @@ unicode_decodeutf7stateful(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) @@ -743,6 +738,7 @@ unicode_decodeutf7stateful(PyObject *self, PyObject *args) result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); @@ -769,7 +765,7 @@ unicode_decodeutf8stateful(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed = 123456789; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) @@ -777,6 +773,7 @@ unicode_decodeutf8stateful(PyObject *self, PyObject *args) result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); @@ -797,7 +794,7 @@ unicode_decodeutf32(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder; + int byteorder = UNINITIALIZED_INT; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -817,8 +814,8 @@ unicode_decodeutf32stateful(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder; - Py_ssize_t consumed; + int byteorder = UNINITIALIZED_INT; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -826,6 +823,7 @@ unicode_decodeutf32stateful(PyObject *self, PyObject *args) result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(iNn)", byteorder, result, consumed); @@ -846,7 +844,7 @@ unicode_decodeutf16(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder = 0; + int byteorder = UNINITIALIZED_INT; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -866,8 +864,8 @@ unicode_decodeutf16stateful(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - int byteorder; - Py_ssize_t consumed; + int byteorder = UNINITIALIZED_INT; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) @@ -875,6 +873,7 @@ unicode_decodeutf16stateful(PyObject *self, PyObject *args) result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(iNn)", byteorder, result, consumed); @@ -1028,7 +1027,7 @@ unicode_decodembcsstateful(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) @@ -1036,6 +1035,7 @@ unicode_decodembcsstateful(PyObject *self, PyObject *args) result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); @@ -1049,7 +1049,7 @@ unicode_decodecodepagestateful(PyObject *self, PyObject *args) const char *data; Py_ssize_t size; const char *errors = NULL; - Py_ssize_t consumed; + Py_ssize_t consumed = UNINITIALIZED_SIZE; PyObject *result; if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors)) @@ -1057,6 +1057,7 @@ unicode_decodecodepagestateful(PyObject *self, PyObject *args) result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed); if (!result) { + assert(consumed == UNINITIALIZED_SIZE); return NULL; } return Py_BuildValue("(Nn)", result, consumed); @@ -1293,17 +1294,13 @@ unicode_count(PyObject *self, PyObject *args) PyObject *substr; Py_ssize_t start; Py_ssize_t end; - Py_ssize_t result; if (!PyArg_ParseTuple(args, "OOnn", &str, &substr, &start, &end)) return NULL; NULLABLE(str); NULLABLE(substr); - result = PyUnicode_Count(str, substr, start, end); - if (result == -1) - return NULL; - return PyLong_FromSsize_t(result); + RETURN_SIZE(PyUnicode_Count(str, substr, start, end)); } /* Test PyUnicode_Find() */ @@ -1323,8 +1320,11 @@ unicode_find(PyObject *self, PyObject *args) NULLABLE(str); NULLABLE(substr); result = PyUnicode_Find(str, substr, start, end, direction); - if (result == -2) + if (result == -2) { + assert(PyErr_Occurred()); return NULL; + } + assert(!PyErr_Occurred()); return PyLong_FromSsize_t(result); } @@ -1337,17 +1337,13 @@ unicode_tailmatch(PyObject *self, PyObject *args) Py_ssize_t start; Py_ssize_t end; int direction; - Py_ssize_t result; if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction)) return NULL; NULLABLE(str); NULLABLE(substr); - result = PyUnicode_Tailmatch(str, substr, start, end, direction); - if (result == -1) - return NULL; - return PyLong_FromSsize_t(result); + RETURN_SIZE(PyUnicode_Tailmatch(str, substr, start, end, direction)); } /* Test PyUnicode_FindChar() */ @@ -1366,10 +1362,12 @@ unicode_findchar(PyObject *self, PyObject *args) } NULLABLE(str); result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); - if (result == -2) + if (result == -2) { + assert(PyErr_Occurred()); return NULL; - else - return PyLong_FromSsize_t(result); + } + assert(!PyErr_Occurred()); + return PyLong_FromSsize_t(result); } /* Test PyUnicode_Replace() */ @@ -1407,6 +1405,7 @@ unicode_compare(PyObject *self, PyObject *args) if (result == -1 && PyErr_Occurred()) { return NULL; } + assert(!PyErr_Occurred()); return PyLong_FromLong(result); } @@ -1430,6 +1429,48 @@ unicode_comparewithasciistring(PyObject *self, PyObject *args) return PyLong_FromLong(result); } +/* Test PyUnicode_EqualToUTF8() */ +static PyObject * +unicode_equaltoutf8(PyObject *self, PyObject *args) +{ + PyObject *left; + const char *right = NULL; + Py_ssize_t right_len; + int result; + + if (!PyArg_ParseTuple(args, "Oz#", &left, &right, &right_len)) { + return NULL; + } + + NULLABLE(left); + result = PyUnicode_EqualToUTF8(left, right); + assert(!PyErr_Occurred()); + return PyLong_FromLong(result); +} + +/* Test PyUnicode_EqualToUTF8AndSize() */ +static PyObject * +unicode_equaltoutf8andsize(PyObject *self, PyObject *args) +{ + PyObject *left; + const char *right = NULL; + Py_ssize_t right_len; + Py_ssize_t size = -100; + int result; + + if (!PyArg_ParseTuple(args, "Oz#|n", &left, &right, &right_len, &size)) { + return NULL; + } + + NULLABLE(left); + if (size == -100) { + size = right_len; + } + result = PyUnicode_EqualToUTF8AndSize(left, right, size); + assert(!PyErr_Occurred()); + return PyLong_FromLong(result); +} + /* Test PyUnicode_RichCompare() */ static PyObject * unicode_richcompare(PyObject *self, PyObject *args) @@ -1467,32 +1508,21 @@ unicode_contains(PyObject *self, PyObject *args) { PyObject *container; PyObject *element; - int result; if (!PyArg_ParseTuple(args, "OO", &container, &element)) return NULL; NULLABLE(container); NULLABLE(element); - result = PyUnicode_Contains(container, element); - if (result == -1 && PyErr_Occurred()) { - return NULL; - } - return PyLong_FromLong(result); + RETURN_INT(PyUnicode_Contains(container, element)); } /* Test PyUnicode_IsIdentifier() */ static PyObject * unicode_isidentifier(PyObject *self, PyObject *arg) { - int result; - NULLABLE(arg); - result = PyUnicode_IsIdentifier(arg); - if (result == -1 && PyErr_Occurred()) { - return NULL; - } - return PyLong_FromLong(result); + RETURN_INT(PyUnicode_IsIdentifier(arg)); } /* Test PyUnicode_CopyCharacters() */ @@ -2056,6 +2086,8 @@ static PyMethodDef TestMethods[] = { {"unicode_replace", unicode_replace, METH_VARARGS}, {"unicode_compare", unicode_compare, METH_VARARGS}, {"unicode_comparewithasciistring",unicode_comparewithasciistring,METH_VARARGS}, + {"unicode_equaltoutf8", unicode_equaltoutf8, METH_VARARGS}, + {"unicode_equaltoutf8andsize",unicode_equaltoutf8andsize, METH_VARARGS}, {"unicode_richcompare", unicode_richcompare, METH_VARARGS}, {"unicode_format", unicode_format, METH_VARARGS}, {"unicode_contains", unicode_contains, METH_VARARGS}, diff --git a/Modules/_testcapi/util.h b/Modules/_testcapi/util.h new file mode 100644 index 00000000000000..f26d7656a10138 --- /dev/null +++ b/Modules/_testcapi/util.h @@ -0,0 +1,33 @@ +#define NULLABLE(x) do { \ + if (x == Py_None) { \ + x = NULL; \ + } \ + } while (0); + +#define RETURN_INT(value) do { \ + int _ret = (value); \ + if (_ret == -1) { \ + assert(PyErr_Occurred()); \ + return NULL; \ + } \ + assert(!PyErr_Occurred()); \ + return PyLong_FromLong(_ret); \ + } while (0) + +#define RETURN_SIZE(value) do { \ + Py_ssize_t _ret = (value); \ + if (_ret == -1) { \ + assert(PyErr_Occurred()); \ + return NULL; \ + } \ + assert(!PyErr_Occurred()); \ + return PyLong_FromSsize_t(_ret); \ + } while (0) + +/* Marker to check that pointer value was set. */ +static const char uninitialized[] = "uninitialized"; +#define UNINITIALIZED_PTR ((void *)uninitialized) +/* Marker to check that Py_ssize_t value was set. */ +#define UNINITIALIZED_SIZE ((Py_ssize_t)236892191) +/* Marker to check that integer value was set. */ +#define UNINITIALIZED_INT (63256717) diff --git a/Modules/_testcapi/vectorcall.c b/Modules/_testcapi/vectorcall.c index 5ee468bd28c853..2b5110fcba2c91 100644 --- a/Modules/_testcapi/vectorcall.c +++ b/Modules/_testcapi/vectorcall.c @@ -1,7 +1,7 @@ #include "parts.h" #include "clinic/vectorcall.c.h" -#include "structmember.h" // PyMemberDef + #include // offsetof /*[clinic input] @@ -155,10 +155,9 @@ VectorCallClass_vectorcall(PyObject *callable, } /*[clinic input] -module _testcapi class _testcapi.VectorCallClass "PyObject *" "&PyType_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8423a8e919f2f0df]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=95c63c1a47f9a995]*/ /*[clinic input] _testcapi.VectorCallClass.set_vectorcall @@ -197,7 +196,7 @@ PyMethodDef VectorCallClass_methods[] = { }; PyMemberDef VectorCallClass_members[] = { - {"__vectorcalloffset__", T_PYSSIZET, 0/* set later */, READONLY}, + {"__vectorcalloffset__", Py_T_PYSSIZET, 0/* set later */, Py_READONLY}, {NULL} }; diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c index a69f1d3f2a79b5..3e81903098f954 100644 --- a/Modules/_testcapi/vectorcall_limited.c +++ b/Modules/_testcapi/vectorcall_limited.c @@ -1,11 +1,13 @@ +/* Test Vectorcall in the limited API */ + #define Py_LIMITED_API 0x030c0000 // 3.12 #include "parts.h" +#include "clinic/vectorcall_limited.c.h" -#ifdef LIMITED_API_AVAILABLE - -#include "structmember.h" // PyMemberDef - -/* Test Vectorcall in the limited API */ +/*[clinic input] +module _testcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ static PyObject * LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -32,8 +34,16 @@ LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw) return self; } +/*[clinic input] +_testcapi.call_vectorcall + + callable: object + / +[clinic start generated code]*/ + static PyObject * -call_vectorcall(PyObject* self, PyObject *callable) +_testcapi_call_vectorcall(PyObject *module, PyObject *callable) +/*[clinic end generated code: output=bae81eec97fcaad7 input=55d88f92240957ee]*/ { PyObject *args[3] = { NULL, NULL, NULL }; PyObject *kwname = NULL, *kwnames = NULL, *result = NULL; @@ -77,8 +87,16 @@ call_vectorcall(PyObject* self, PyObject *callable) return result; } +/*[clinic input] +_testcapi.call_vectorcall_method + + callable: object + / +[clinic start generated code]*/ + static PyObject * -call_vectorcall_method(PyObject* self, PyObject *callable) +_testcapi_call_vectorcall_method(PyObject *module, PyObject *callable) +/*[clinic end generated code: output=e661f48dda08b6fb input=5ba81c27511395b6]*/ { PyObject *args[3] = { NULL, NULL, NULL }; PyObject *name = NULL, *kwname = NULL, @@ -132,7 +150,7 @@ call_vectorcall_method(PyObject* self, PyObject *callable) } static PyMemberDef LimitedVectorCallClass_members[] = { - {"__vectorcalloffset__", T_PYSSIZET, sizeof(PyObject), READONLY}, + {"__vectorcalloffset__", Py_T_PYSSIZET, sizeof(PyObject), Py_READONLY}, {NULL} }; @@ -153,8 +171,8 @@ static PyType_Spec LimitedVectorCallClass_spec = { }; static PyMethodDef TestMethods[] = { - {"call_vectorcall", call_vectorcall, METH_O}, - {"call_vectorcall_method", call_vectorcall_method, METH_O}, + _TESTCAPI_CALL_VECTORCALL_METHODDEF + _TESTCAPI_CALL_VECTORCALL_METHOD_METHODDEF {NULL}, }; @@ -175,5 +193,3 @@ _PyTestCapi_Init_VectorcallLimited(PyObject *m) { return 0; } - -#endif // LIMITED_API_AVAILABLE diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c index 4cf567b3314980..8a264bba4ed6ed 100644 --- a/Modules/_testcapi/watchers.c +++ b/Modules/_testcapi/watchers.c @@ -295,6 +295,7 @@ _testcapi_unwatch_type_impl(PyObject *module, int watcher_id, PyObject *type) // Test code object watching #define NUM_CODE_WATCHERS 2 +static int code_watcher_ids[NUM_CODE_WATCHERS] = {-1, -1}; static int num_code_object_created_events[NUM_CODE_WATCHERS] = {0, 0}; static int num_code_object_destroyed_events[NUM_CODE_WATCHERS] = {0, 0}; @@ -345,11 +346,13 @@ add_code_watcher(PyObject *self, PyObject *which_watcher) long which_l = PyLong_AsLong(which_watcher); if (which_l == 0) { watcher_id = PyCode_AddWatcher(first_code_object_callback); + code_watcher_ids[0] = watcher_id; num_code_object_created_events[0] = 0; num_code_object_destroyed_events[0] = 0; } else if (which_l == 1) { watcher_id = PyCode_AddWatcher(second_code_object_callback); + code_watcher_ids[1] = watcher_id; num_code_object_created_events[1] = 0; num_code_object_destroyed_events[1] = 0; } @@ -375,9 +378,14 @@ clear_code_watcher(PyObject *self, PyObject *watcher_id) return NULL; } // reset static events counters - if (watcher_id_l >= 0 && watcher_id_l < NUM_CODE_WATCHERS) { - num_code_object_created_events[watcher_id_l] = 0; - num_code_object_destroyed_events[watcher_id_l] = 0; + if (watcher_id_l >= 0) { + for (int i = 0; i < NUM_CODE_WATCHERS; i++) { + if (watcher_id_l == code_watcher_ids[i]) { + code_watcher_ids[i] = -1; + num_code_object_created_events[i] = 0; + num_code_object_destroyed_events[i] = 0; + } + } } Py_RETURN_NONE; } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index dd2c9c72e53787..2b9b2321c81e7b 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5,43 +5,30 @@ * standard Python regression test, via Lib/test/test_capi.py. */ -/* This module tests the public (Include/ and Include/cpython/) C API. - The internal C API must not be used here: use _testinternalcapi for that. - - The Visual Studio projects builds _testcapi with Py_BUILD_CORE_MODULE - macro defined, but only the public C API must be tested here. */ - -#undef Py_BUILD_CORE_MODULE -#undef Py_BUILD_CORE_BUILTIN +// Include parts.h first since it takes care of NDEBUG and Py_BUILD_CORE macros +// and including Python.h. +// +// Several parts of this module are broken out into files in _testcapi/. +// Include definitions from there. +#include "_testcapi/parts.h" -/* Always enable assertions */ -#undef NDEBUG +#include "frameobject.h" // PyFrame_New() +#include "marshal.h" // PyMarshal_WriteLongToFile() -#include "Python.h" -#include "frameobject.h" // PyFrame_New -#include "marshal.h" // PyMarshal_WriteLongToFile -#include "structmember.h" // for offsetof(), T_OBJECT #include // FLT_MAX #include -#ifndef MS_WINDOWS -#include -#endif +#include // offsetof() #ifdef HAVE_SYS_WAIT_H -#include // W_STOPCODE -#endif - -#ifdef Py_BUILD_CORE -# error "_testcapi must test the public Python C API, not CPython internal C API" +# include // W_STOPCODE #endif #ifdef bool -# error "The public headers should not include , see bpo-46748" +# error "The public headers should not include , see gh-48924" #endif -// Several parts of this module are broken out into files in _testcapi/. -// Include definitions from there. -#include "_testcapi/parts.h" +#include "_testcapi/util.h" + // Forward declarations static struct PyModuleDef _testcapimodule; @@ -217,10 +204,13 @@ test_dict_inner(int count) Py_DECREF(v); } + k = v = UNINITIALIZED_PTR; while (PyDict_Next(dict, &pos, &k, &v)) { PyObject *o; iterations++; + assert(k != UNINITIALIZED_PTR); + assert(v != UNINITIALIZED_PTR); i = PyLong_AS_LONG(v) + 1; o = PyLong_FromLong(i); if (o == NULL) @@ -230,7 +220,10 @@ test_dict_inner(int count) return -1; } Py_DECREF(o); + k = v = UNINITIALIZED_PTR; } + assert(k == UNINITIALIZED_PTR); + assert(v == UNINITIALIZED_PTR); Py_DECREF(dict); @@ -260,26 +253,6 @@ test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -static PyObject* -dict_getitem_knownhash(PyObject *self, PyObject *args) -{ - PyObject *mp, *key, *result; - Py_ssize_t hash; - - if (!PyArg_ParseTuple(args, "OOn:dict_getitem_knownhash", - &mp, &key, &hash)) { - return NULL; - } - - result = _PyDict_GetItem_KnownHash(mp, key, (Py_hash_t)hash); - if (result == NULL && !PyErr_Occurred()) { - _PyErr_SetKeyError(key); - return NULL; - } - - return Py_XNewRef(result); -} - /* Issue #4701: Check that PyObject_Hash implicitly calls * PyType_Ready if it hasn't already been called */ @@ -413,6 +386,41 @@ raise_error(void *unused) return NULL; } +static PyObject * +py_buildvalue(PyObject *self, PyObject *args) +{ + const char *fmt; + PyObject *objs[10] = {NULL}; + if (!PyArg_ParseTuple(args, "s|OOOOOOOOOO", &fmt, + &objs[0], &objs[1], &objs[2], &objs[3], &objs[4], + &objs[5], &objs[6], &objs[7], &objs[8], &objs[9])) + { + return NULL; + } + for(int i = 0; i < 10; i++) { + NULLABLE(objs[i]); + } + return Py_BuildValue(fmt, + objs[0], objs[1], objs[2], objs[3], objs[4], + objs[5], objs[6], objs[7], objs[8], objs[9]); +} + +static PyObject * +py_buildvalue_ints(PyObject *self, PyObject *args) +{ + const char *fmt; + unsigned int values[10] = {0}; + if (!PyArg_ParseTuple(args, "s|IIIIIIIIII", &fmt, + &values[0], &values[1], &values[2], &values[3], &values[4], + &values[5], &values[6], &values[7], &values[8], &values[9])) + { + return NULL; + } + return Py_BuildValue(fmt, + values[0], values[1], values[2], values[3], values[4], + values[5], values[6], values[7], values[8], values[9]); +} + static int test_buildvalue_N_error(const char *fmt) { @@ -1342,19 +1350,13 @@ static PyObject * test_PyBuffer_SizeFromFormat(PyObject *self, PyObject *args) { const char *format; - Py_ssize_t result; if (!PyArg_ParseTuple(args, "s:test_PyBuffer_SizeFromFormat", &format)) { return NULL; } - result = PyBuffer_SizeFromFormat(format); - if (result == -1) { - return NULL; - } - - return PyLong_FromSsize_t(result); + RETURN_SIZE(PyBuffer_SizeFromFormat(format)); } /* Test that the fatal error from not having a current thread doesn't @@ -1443,104 +1445,6 @@ run_in_subinterp(PyObject *self, PyObject *args) return PyLong_FromLong(r); } -/* To run some code in a sub-interpreter. */ -static PyObject * -run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) -{ - const char *code; - int use_main_obmalloc = -1; - int allow_fork = -1; - int allow_exec = -1; - int allow_threads = -1; - int allow_daemon_threads = -1; - int check_multi_interp_extensions = -1; - int gil = -1; - int r; - PyThreadState *substate, *mainstate; - /* only initialise 'cflags.cf_flags' to test backwards compatibility */ - PyCompilerFlags cflags = {0}; - - static char *kwlist[] = {"code", - "use_main_obmalloc", - "allow_fork", - "allow_exec", - "allow_threads", - "allow_daemon_threads", - "check_multi_interp_extensions", - "gil", - NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "s$ppppppi:run_in_subinterp_with_config", kwlist, - &code, &use_main_obmalloc, - &allow_fork, &allow_exec, - &allow_threads, &allow_daemon_threads, - &check_multi_interp_extensions, - &gil)) { - return NULL; - } - if (use_main_obmalloc < 0) { - PyErr_SetString(PyExc_ValueError, "missing use_main_obmalloc"); - return NULL; - } - if (allow_fork < 0) { - PyErr_SetString(PyExc_ValueError, "missing allow_fork"); - return NULL; - } - if (allow_exec < 0) { - PyErr_SetString(PyExc_ValueError, "missing allow_exec"); - return NULL; - } - if (allow_threads < 0) { - PyErr_SetString(PyExc_ValueError, "missing allow_threads"); - return NULL; - } - if (gil < 0) { - PyErr_SetString(PyExc_ValueError, "missing gil"); - return NULL; - } - if (allow_daemon_threads < 0) { - PyErr_SetString(PyExc_ValueError, "missing allow_daemon_threads"); - return NULL; - } - if (check_multi_interp_extensions < 0) { - PyErr_SetString(PyExc_ValueError, "missing check_multi_interp_extensions"); - return NULL; - } - - mainstate = PyThreadState_Get(); - - PyThreadState_Swap(NULL); - - const PyInterpreterConfig config = { - .use_main_obmalloc = use_main_obmalloc, - .allow_fork = allow_fork, - .allow_exec = allow_exec, - .allow_threads = allow_threads, - .allow_daemon_threads = allow_daemon_threads, - .check_multi_interp_extensions = check_multi_interp_extensions, - .gil = gil, - }; - PyStatus status = Py_NewInterpreterFromConfig(&substate, &config); - if (PyStatus_Exception(status)) { - /* Since no new thread state was created, there is no exception to - propagate; raise a fresh one after swapping in the old thread - state. */ - PyThreadState_Swap(mainstate); - _PyErr_SetFromPyStatus(status); - PyObject *exc = PyErr_GetRaisedException(); - PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed"); - _PyErr_ChainExceptions1(exc); - return NULL; - } - assert(substate != NULL); - r = PyRun_SimpleStringFlags(code, &cflags); - Py_EndInterpreter(substate); - - PyThreadState_Swap(mainstate); - - return PyLong_FromLong(r); -} - static void _xid_capsule_destructor(PyObject *capsule) { @@ -1982,7 +1886,7 @@ return_result_with_error(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject* +static PyObject * getitem_with_error(PyObject *self, PyObject *args) { PyObject *map, *key; @@ -2059,90 +1963,6 @@ py_w_stopcode(PyObject *self, PyObject *args) #endif -static PyObject * -get_mapping_keys(PyObject* self, PyObject *obj) -{ - return PyMapping_Keys(obj); -} - -static PyObject * -get_mapping_values(PyObject* self, PyObject *obj) -{ - return PyMapping_Values(obj); -} - -static PyObject * -get_mapping_items(PyObject* self, PyObject *obj) -{ - return PyMapping_Items(obj); -} - -static PyObject * -test_mapping_has_key_string(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *context = PyDict_New(); - PyObject *val = PyLong_FromLong(1); - - // Since this uses `const char*` it is easier to test this in C: - PyDict_SetItemString(context, "a", val); - if (!PyMapping_HasKeyString(context, "a")) { - PyErr_SetString(PyExc_RuntimeError, - "Existing mapping key does not exist"); - return NULL; - } - if (PyMapping_HasKeyString(context, "b")) { - PyErr_SetString(PyExc_RuntimeError, - "Missing mapping key exists"); - return NULL; - } - - Py_DECREF(val); - Py_DECREF(context); - Py_RETURN_NONE; -} - -static PyObject * -mapping_has_key(PyObject* self, PyObject *args) -{ - PyObject *context, *key; - if (!PyArg_ParseTuple(args, "OO", &context, &key)) { - return NULL; - } - return PyLong_FromLong(PyMapping_HasKey(context, key)); -} - -static PyObject * -sequence_set_slice(PyObject* self, PyObject *args) -{ - PyObject *sequence, *obj; - Py_ssize_t i1, i2; - if (!PyArg_ParseTuple(args, "OnnO", &sequence, &i1, &i2, &obj)) { - return NULL; - } - - int res = PySequence_SetSlice(sequence, i1, i2, obj); - if (res == -1) { - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject * -sequence_del_slice(PyObject* self, PyObject *args) -{ - PyObject *sequence; - Py_ssize_t i1, i2; - if (!PyArg_ParseTuple(args, "Onn", &sequence, &i1, &i2)) { - return NULL; - } - - int res = PySequence_DelSlice(sequence, i1, i2); - if (res == -1) { - return NULL; - } - Py_RETURN_NONE; -} - static PyObject * test_pythread_tss_key_state(PyObject *self, PyObject *args) { @@ -2198,13 +2018,6 @@ test_pythread_tss_key_state(PyObject *self, PyObject *args) } -static PyObject* -new_hamt(PyObject *self, PyObject *args) -{ - return _PyContext_NewHamtForTests(); -} - - /* def bad_get(self, obj, cls): cls() return repr(self) @@ -2243,73 +2056,27 @@ negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) Py_RETURN_NONE; } -#endif - static PyObject * -sequence_getitem(PyObject *self, PyObject *args) +decref_freed_object(PyObject *self, PyObject *Py_UNUSED(args)) { - PyObject *seq; - Py_ssize_t i; - if (!PyArg_ParseTuple(args, "On", &seq, &i)) { + PyObject *obj = PyUnicode_FromString("decref_freed_object"); + if (obj == NULL) { return NULL; } - return PySequence_GetItem(seq, i); -} - + assert(Py_REFCNT(obj) == 1); -static PyObject * -sequence_setitem(PyObject *self, PyObject *args) -{ - Py_ssize_t i; - PyObject *seq, *val; - if (!PyArg_ParseTuple(args, "OnO", &seq, &i, &val)) { - return NULL; - } - if (PySequence_SetItem(seq, i, val)) { - return NULL; - } - Py_RETURN_NONE; -} + // Deallocate the memory + Py_DECREF(obj); + // obj is a now a dangling pointer + // gh-109496: If Python is built in debug mode, Py_DECREF() must call + // _Py_NegativeRefcount() and abort Python. + Py_DECREF(obj); -static PyObject * -sequence_delitem(PyObject *self, PyObject *args) -{ - Py_ssize_t i; - PyObject *seq; - if (!PyArg_ParseTuple(args, "On", &seq, &i)) { - return NULL; - } - if (PySequence_DelItem(seq, i)) { - return NULL; - } Py_RETURN_NONE; } - -static PyObject * -hasattr_string(PyObject *self, PyObject* args) -{ - PyObject* obj; - PyObject* attr_name; - - if (!PyArg_UnpackTuple(args, "hasattr_string", 2, 2, &obj, &attr_name)) { - return NULL; - } - - if (!PyUnicode_Check(attr_name)) { - PyErr_SetString(PyExc_TypeError, "attribute name must a be string"); - return PyErr_Occurred(); - } - - const char *name_str = PyUnicode_AsUTF8(attr_name); - if (PyObject_HasAttrString(obj, name_str)) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} +#endif /* Functions for testing C calling conventions (METH_*) are named meth_*, @@ -2726,8 +2493,8 @@ test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) PyThreadState *tstate2 = PyThreadState_Get(); assert(tstate2 == tstate); - // private _PyThreadState_UncheckedGet() - PyThreadState *tstate3 = _PyThreadState_UncheckedGet(); + // PyThreadState_GetUnchecked() + PyThreadState *tstate3 = PyThreadState_GetUnchecked(); assert(tstate3 == tstate); // PyThreadState_EnterTracing(), PyThreadState_LeaveTracing() @@ -3191,7 +2958,7 @@ settrace_to_error(PyObject *self, PyObject *list) static PyObject * clear_managed_dict(PyObject *self, PyObject *obj) { - _PyObject_ClearManagedDict(obj); + PyObject_ClearManagedDict(obj); Py_RETURN_NONE; } @@ -3399,7 +3166,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) assert(Py_REFCNT(obj) == refcnt); // test PyWeakref_GetRef(), reference is alive - PyObject *ref = Py_True; // marker to check that value was set + PyObject *ref = UNINITIALIZED_PTR; assert(PyWeakref_GetRef(weakref, &ref) == 1); assert(ref == obj); assert(Py_REFCNT(obj) == (refcnt + 1)); @@ -3421,7 +3188,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) assert(PyWeakref_GET_OBJECT(weakref) == Py_None); // test PyWeakref_GetRef(), reference is dead - ref = Py_True; + ref = UNINITIALIZED_PTR; assert(PyWeakref_GetRef(weakref, &ref) == 0); assert(ref == NULL); @@ -3433,7 +3200,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) // test PyWeakref_GetRef(), invalid type assert(!PyErr_Occurred()); - ref = Py_True; + ref = UNINITIALIZED_PTR; assert(PyWeakref_GetRef(invalid_weakref, &ref) == -1); assert(PyErr_ExceptionMatches(PyExc_TypeError)); PyErr_Clear(); @@ -3445,7 +3212,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) PyErr_Clear(); // test PyWeakref_GetRef(NULL) - ref = Py_True; // marker to check that value was set + ref = UNINITIALIZED_PTR; assert(PyWeakref_GetRef(NULL, &ref) == -1); assert(PyErr_ExceptionMatches(PyExc_SystemError)); assert(ref == NULL); @@ -3464,13 +3231,41 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) } +static PyObject * +sys_getobject(PyObject *Py_UNUSED(module), PyObject *arg) +{ + const char *name; + Py_ssize_t size; + if (!PyArg_Parse(arg, "z#", &name, &size)) { + return NULL; + } + PyObject *result = PySys_GetObject(name); + if (result == NULL) { + result = PyExc_AttributeError; + } + return Py_NewRef(result); +} + +static PyObject * +sys_setobject(PyObject *Py_UNUSED(module), PyObject *args) +{ + const char *name; + Py_ssize_t size; + PyObject *value; + if (!PyArg_ParseTuple(args, "z#O", &name, &size, &value)) { + return NULL; + } + NULLABLE(value); + RETURN_INT(PySys_SetObject(name, value)); +} + + static PyMethodDef TestMethods[] = { {"set_errno", set_errno, METH_VARARGS}, {"test_config", test_config, METH_NOARGS}, {"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS}, {"test_list_api", test_list_api, METH_NOARGS}, {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, - {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, {"test_lazy_hash_inheritance", test_lazy_hash_inheritance,METH_NOARGS}, {"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS}, {"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS}, @@ -3492,6 +3287,8 @@ static PyMethodDef TestMethods[] = { #endif {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, + {"py_buildvalue", py_buildvalue, METH_VARARGS}, + {"py_buildvalue_ints", py_buildvalue_ints, METH_VARARGS}, {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, {"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS}, {"test_get_type_name", test_get_type_name, METH_NOARGS}, @@ -3514,9 +3311,6 @@ static PyMethodDef TestMethods[] = { {"crash_no_current_thread", crash_no_current_thread, METH_NOARGS}, {"test_current_tstate_matches", test_current_tstate_matches, METH_NOARGS}, {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, - {"run_in_subinterp_with_config", - _PyCFunction_CAST(run_in_subinterp_with_config), - METH_VARARGS | METH_KEYWORDS}, {"get_crossinterp_data", get_crossinterp_data, METH_VARARGS}, {"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS}, {"create_cfunction", create_cfunction, METH_NOARGS}, @@ -3545,23 +3339,12 @@ static PyMethodDef TestMethods[] = { #ifdef W_STOPCODE {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, #endif - {"get_mapping_keys", get_mapping_keys, METH_O}, - {"get_mapping_values", get_mapping_values, METH_O}, - {"get_mapping_items", get_mapping_items, METH_O}, - {"test_mapping_has_key_string", test_mapping_has_key_string, METH_NOARGS}, - {"mapping_has_key", mapping_has_key, METH_VARARGS}, - {"sequence_set_slice", sequence_set_slice, METH_VARARGS}, - {"sequence_del_slice", sequence_del_slice, METH_VARARGS}, {"test_pythread_tss_key_state", test_pythread_tss_key_state, METH_VARARGS}, - {"hamt", new_hamt, METH_NOARGS}, {"bad_get", _PyCFunction_CAST(bad_get), METH_FASTCALL}, #ifdef Py_REF_DEBUG {"negative_refcount", negative_refcount, METH_NOARGS}, + {"decref_freed_object", decref_freed_object, METH_NOARGS}, #endif - {"sequence_getitem", sequence_getitem, METH_VARARGS}, - {"sequence_setitem", sequence_setitem, METH_VARARGS}, - {"sequence_delitem", sequence_delitem, METH_VARARGS}, - {"hasattr_string", hasattr_string, METH_VARARGS}, {"meth_varargs", meth_varargs, METH_VARARGS}, {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, {"meth_o", meth_o, METH_O}, @@ -3609,6 +3392,8 @@ static PyMethodDef TestMethods[] = { {"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL}, {"check_pyimport_addmodule", check_pyimport_addmodule, METH_VARARGS}, {"test_weakref_capi", test_weakref_capi, METH_NOARGS}, + {"sys_getobject", sys_getobject, METH_O}, + {"sys_setobject", sys_setobject, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; @@ -4066,7 +3851,7 @@ ContainerNoGC_dealloc(ContainerNoGCobject *self) } static PyMemberDef ContainerNoGC_members[] = { - {"value", T_OBJECT, offsetof(ContainerNoGCobject, value), READONLY, + {"value", _Py_T_OBJECT, offsetof(ContainerNoGCobject, value), Py_READONLY, PyDoc_STR("a container value for test purposes")}, {0} }; @@ -4182,6 +3967,7 @@ PyInit__testcapi(void) PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); + PyModule_AddIntMacro(m, Py_C_RECURSION_LIMIT); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); @@ -4202,6 +3988,9 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Heaptype(m) < 0) { return NULL; } + if (_PyTestCapi_Init_Abstract(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_Unicode(m) < 0) { return NULL; } @@ -4226,6 +4015,12 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Float(m) < 0) { return NULL; } + if (_PyTestCapi_Init_Dict(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Set(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_Structmember(m) < 0) { return NULL; } @@ -4247,18 +4042,15 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_GC(m) < 0) { return NULL; } - -#ifndef LIMITED_API_AVAILABLE - PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False); -#else - PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_True); + if (_PyTestCapi_Init_PyAtomic(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_VectorcallLimited(m) < 0) { return NULL; } if (_PyTestCapi_Init_HeaptypeRelative(m) < 0) { return NULL; } -#endif PyState_AddModule(m, &_testcapimodule); return m; diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index 26cdb4371ca24c..2e0535d52641e0 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -6,6 +6,7 @@ #undef NDEBUG #include "Python.h" +#include "pycore_object.h" // _PyObject_IsFreed() // Used for clone_with_conv_f1 and clone_with_conv_v2 @@ -1192,6 +1193,605 @@ clone_with_conv_f2_impl(PyObject *module, custom_t path) } +/*[clinic input] +output push +destination deprstar new file '{dirname}/clinic/_testclinic_depr.c.h' +output everything deprstar +#output methoddef_ifndef buffer 1 +output docstring_prototype suppress +output parser_prototype suppress +output impl_definition block +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=32116eac48a42d34]*/ + + +// Mock Python version 3.8 +#define _SAVED_PY_VERSION PY_VERSION_HEX +#undef PY_VERSION_HEX +#define PY_VERSION_HEX 0x03080000 + + +#include "clinic/_testclinic_depr.c.h" + + +/*[clinic input] +class _testclinic.DeprStarNew "PyObject *" "PyObject" +@classmethod +_testclinic.DeprStarNew.__new__ as depr_star_new + * [from 3.14] + a: object = None +The deprecation message should use the class name instead of __new__. +[clinic start generated code]*/ + +static PyObject * +depr_star_new_impl(PyTypeObject *type, PyObject *a) +/*[clinic end generated code: output=bdbb36244f90cf46 input=fdd640db964b4dc1]*/ +{ + return type->tp_alloc(type, 0); +} + +/*[clinic input] +_testclinic.DeprStarNew.cloned as depr_star_new_clone = _testclinic.DeprStarNew.__new__ +[clinic start generated code]*/ + +static PyObject * +depr_star_new_clone_impl(PyObject *type, PyObject *a) +/*[clinic end generated code: output=3b17bf885fa736bc input=ea659285d5dbec6c]*/ +{ + Py_RETURN_NONE; +} + +static struct PyMethodDef depr_star_new_methods[] = { + DEPR_STAR_NEW_CLONE_METHODDEF + {NULL, NULL} +}; + +static PyTypeObject DeprStarNew = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprStarNew", + .tp_basicsize = sizeof(PyObject), + .tp_new = depr_star_new, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = depr_star_new_methods, +}; + + +/*[clinic input] +class _testclinic.DeprStarInit "PyObject *" "PyObject" +_testclinic.DeprStarInit.__init__ as depr_star_init + * [from 3.14] + a: object = None +The deprecation message should use the class name instead of __init__. +[clinic start generated code]*/ + +static int +depr_star_init_impl(PyObject *self, PyObject *a) +/*[clinic end generated code: output=8d27b43c286d3ecc input=5575b77229d5e2be]*/ +{ + return 0; +} + +/*[clinic input] +_testclinic.DeprStarInit.cloned as depr_star_init_clone = _testclinic.DeprStarInit.__init__ +[clinic start generated code]*/ + +static PyObject * +depr_star_init_clone_impl(PyObject *self, PyObject *a) +/*[clinic end generated code: output=ddfe8a1b5531e7cc input=561e103fe7f8e94f]*/ +{ + Py_RETURN_NONE; +} + +static struct PyMethodDef depr_star_init_methods[] = { + DEPR_STAR_INIT_CLONE_METHODDEF + {NULL, NULL} +}; + +static PyTypeObject DeprStarInit = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprStarInit", + .tp_basicsize = sizeof(PyObject), + .tp_new = PyType_GenericNew, + .tp_init = depr_star_init, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = depr_star_init_methods, +}; + + +/*[clinic input] +class _testclinic.DeprStarInitNoInline "PyObject *" "PyObject" +_testclinic.DeprStarInitNoInline.__init__ as depr_star_init_noinline + a: object + * [from 3.14] + b: object + c: object = None + * + # Force to use _PyArg_ParseTupleAndKeywordsFast. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static int +depr_star_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=9b31fc167f1bf9f7 input=5a887543122bca48]*/ +{ + return 0; +} + +static PyTypeObject DeprStarInitNoInline = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprStarInitNoInline", + .tp_basicsize = sizeof(PyObject), + .tp_new = PyType_GenericNew, + .tp_init = depr_star_init_noinline, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/*[clinic input] +class _testclinic.DeprKwdNew "PyObject *" "PyObject" +@classmethod +_testclinic.DeprKwdNew.__new__ as depr_kwd_new + a: object = None + / [from 3.14] +The deprecation message should use the class name instead of __new__. +[clinic start generated code]*/ + +static PyObject * +depr_kwd_new_impl(PyTypeObject *type, PyObject *a) +/*[clinic end generated code: output=618d07afc5616149 input=6c7d13c471013c10]*/ +{ + return type->tp_alloc(type, 0); +} + +static PyTypeObject DeprKwdNew = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprKwdNew", + .tp_basicsize = sizeof(PyObject), + .tp_new = depr_kwd_new, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/*[clinic input] +class _testclinic.DeprKwdInit "PyObject *" "PyObject" +_testclinic.DeprKwdInit.__init__ as depr_kwd_init + a: object = None + / [from 3.14] +The deprecation message should use the class name instead of __init__. +[clinic start generated code]*/ + +static int +depr_kwd_init_impl(PyObject *self, PyObject *a) +/*[clinic end generated code: output=6e02eb724a85d840 input=b9bf3c20f012d539]*/ +{ + return 0; +} + +static PyTypeObject DeprKwdInit = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprKwdInit", + .tp_basicsize = sizeof(PyObject), + .tp_new = PyType_GenericNew, + .tp_init = depr_kwd_init, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/*[clinic input] +class _testclinic.DeprKwdInitNoInline "PyObject *" "PyObject" +_testclinic.DeprKwdInitNoInline.__init__ as depr_kwd_init_noinline + a: object + / + b: object + c: object = None + / [from 3.14] + # Force to use _PyArg_ParseTupleAndKeywordsFast. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static int +depr_kwd_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=27759d70ddd25873 input=c19d982c8c70a930]*/ +{ + return 0; +} + +static PyTypeObject DeprKwdInitNoInline = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprKwdInitNoInline", + .tp_basicsize = sizeof(PyObject), + .tp_new = PyType_GenericNew, + .tp_init = depr_kwd_init_noinline, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/*[clinic input] +depr_star_pos0_len1 + * [from 3.14] + a: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos0_len1_impl(PyObject *module, PyObject *a) +/*[clinic end generated code: output=e1c6c2b423129499 input=089b9aee25381b69]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos0_len2 + * [from 3.14] + a: object + b: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos0_len2_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=96df9be39859c7e4 input=65c83a32e01495c6]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos0_len3_with_kwd + * [from 3.14] + a: object + b: object + c: object + * + d: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos0_len3_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=7f2531eda837052f input=b33f620f57d9270f]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos1_len1_opt + a: object + * [from 3.14] + b: object = None +[clinic start generated code]*/ + +static PyObject * +depr_star_pos1_len1_opt_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=b5b4e326ee3b216f input=4a4b8ff72eae9ff7]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos1_len1 + a: object + * [from 3.14] + b: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos1_len1_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=eab92e37d5b0a480 input=1e7787a9fe5f62a0]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos1_len2_with_kwd + a: object + * [from 3.14] + b: object + c: object + * + d: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos1_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=3bccab672b7cfbb8 input=6bc7bd742fa8be15]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos2_len1 + a: object + b: object + * [from 3.14] + c: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos2_len1_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=20f5b230e9beeb70 input=5fc3e1790dec00d5]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos2_len2 + a: object + b: object + * [from 3.14] + c: object + d: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos2_len2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=9f90ed8fbce27d7a input=9cc8003b89d38779]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_pos2_len2_with_kwd + a: object + b: object + * [from 3.14] + c: object + d: object + * + e: object +[clinic start generated code]*/ + +static PyObject * +depr_star_pos2_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d, PyObject *e) +/*[clinic end generated code: output=05432c4f20527215 input=831832d90534da91]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_noinline + a: object + * [from 3.14] + b: object + c: object = None + * + # Force to use _PyArg_ParseStackAndKeywords. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static PyObject * +depr_star_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=cc27dacf5c2754af input=d36cc862a2daef98]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_star_multi + a: object + * [from 3.16] + b: object + * [from 3.15] + c: object + d: object + * [from 3.14] + e: object + f: object + g: object + * + h: object +[clinic start generated code]*/ + +static PyObject * +depr_star_multi_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyObject *d, PyObject *e, PyObject *f, PyObject *g, + PyObject *h) +/*[clinic end generated code: output=77681653f4202068 input=3ebd05d888a957ea]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_required_1 + a: object + / + b: object + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_required_1_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=1d8ab19ea78418af input=53f2c398b828462d]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_required_2 + a: object + / + b: object + c: object + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_required_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=44a89cb82509ddde input=a2b0ef37de8a01a7]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_optional_1 + a: object + / + b: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_optional_1_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=a8a3d67efcc7b058 input=e416981eb78c3053]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_optional_2 + a: object + / + b: object = None + c: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_optional_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=aa2d967f26fdb9f6 input=cae3afb783bfc855]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_optional_3 + a: object = None + b: object = None + c: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_optional_3_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=a26025bf6118fd07 input=c9183b2f9ccaf992]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_required_optional + a: object + / + b: object + c: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_required_optional_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=e53a8b7a250d8ffc input=23237a046f8388f5]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_noinline + a: object + / + b: object + c: object = None + / [from 3.14] + # Force to use _PyArg_ParseStackAndKeywords. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static PyObject * +depr_kwd_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=f59da8113f2bad7c input=1d6db65bebb069d7]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_multi + a: object + / + b: object + / [from 3.14] + c: object + d: object + / [from 3.15] + e: object + f: object + g: object + / [from 3.16] + h: object +[clinic start generated code]*/ + +static PyObject * +depr_kwd_multi_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyObject *d, PyObject *e, PyObject *f, PyObject *g, + PyObject *h) +/*[clinic end generated code: output=ddfbde80fe1942e1 input=7a074e621c79efd7]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_multi + a: object + / + b: object + / [from 3.14] + c: object + / [from 3.15] + d: object + * [from 3.15] + e: object + * [from 3.14] + f: object + * + g: object +[clinic start generated code]*/ + +static PyObject * +depr_multi_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyObject *d, PyObject *e, PyObject *f, PyObject *g) +/*[clinic end generated code: output=f81c92852ca2d4ee input=5b847c5e44bedd02]*/ +{ + Py_RETURN_NONE; +} + + +// Reset PY_VERSION_HEX +#undef PY_VERSION_HEX +#define PY_VERSION_HEX _SAVED_PY_VERSION +#undef _SAVED_PY_VERSION + + +/*[clinic input] +output pop +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e7c7c42daced52b0]*/ + static PyMethodDef tester_methods[] = { TEST_EMPTY_FUNCTION_METHODDEF OBJECTS_CONVERTER_METHODDEF @@ -1247,6 +1847,27 @@ static PyMethodDef tester_methods[] = { CLONE_F2_METHODDEF CLONE_WITH_CONV_F1_METHODDEF CLONE_WITH_CONV_F2_METHODDEF + + DEPR_STAR_POS0_LEN1_METHODDEF + DEPR_STAR_POS0_LEN2_METHODDEF + DEPR_STAR_POS0_LEN3_WITH_KWD_METHODDEF + DEPR_STAR_POS1_LEN1_OPT_METHODDEF + DEPR_STAR_POS1_LEN1_METHODDEF + DEPR_STAR_POS1_LEN2_WITH_KWD_METHODDEF + DEPR_STAR_POS2_LEN1_METHODDEF + DEPR_STAR_POS2_LEN2_METHODDEF + DEPR_STAR_POS2_LEN2_WITH_KWD_METHODDEF + DEPR_STAR_NOINLINE_METHODDEF + DEPR_STAR_MULTI_METHODDEF + DEPR_KWD_REQUIRED_1_METHODDEF + DEPR_KWD_REQUIRED_2_METHODDEF + DEPR_KWD_OPTIONAL_1_METHODDEF + DEPR_KWD_OPTIONAL_2_METHODDEF + DEPR_KWD_OPTIONAL_3_METHODDEF + DEPR_KWD_REQUIRED_OPTIONAL_METHODDEF + DEPR_KWD_NOINLINE_METHODDEF + DEPR_KWD_MULTI_METHODDEF + DEPR_MULTI_METHODDEF {NULL, NULL} }; @@ -1260,7 +1881,33 @@ static struct PyModuleDef _testclinic_module = { PyMODINIT_FUNC PyInit__testclinic(void) { - return PyModule_Create(&_testclinic_module); + PyObject *m = PyModule_Create(&_testclinic_module); + if (m == NULL) { + return NULL; + } + if (PyModule_AddType(m, &DeprStarNew) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprStarInit) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprStarInitNoInline) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprKwdNew) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprKwdInit) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprKwdInitNoInline) < 0) { + goto error; + } + return m; + +error: + Py_DECREF(m); + return NULL; } #undef RETURN_PACKED_ARGS diff --git a/Modules/_testclinic_limited.c b/Modules/_testclinic_limited.c new file mode 100644 index 00000000000000..4273383816a0dd --- /dev/null +++ b/Modules/_testclinic_limited.c @@ -0,0 +1,93 @@ +// _testclinic_limited can built with the Py_BUILD_CORE_BUILTIN macro defined +// if one of the Modules/Setup files asks to build it as "static" (gh-109723). +#undef Py_BUILD_CORE +#undef Py_BUILD_CORE_MODULE +#undef Py_BUILD_CORE_BUILTIN + +// For now, only limited C API 3.13 is supported +#define Py_LIMITED_API 0x030d0000 + +/* Always enable assertions */ +#undef NDEBUG + +#include "Python.h" + + +#include "clinic/_testclinic_limited.c.h" + + +/*[clinic input] +module _testclinic_limited +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd408149a4fc0dbb]*/ + + +/*[clinic input] +test_empty_function + +[clinic start generated code]*/ + +static PyObject * +test_empty_function_impl(PyObject *module) +/*[clinic end generated code: output=0f8aeb3ddced55cb input=0dd7048651ad4ae4]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +my_int_func -> int + + arg: int + / + +[clinic start generated code]*/ + +static int +my_int_func_impl(PyObject *module, int arg) +/*[clinic end generated code: output=761cd54582f10e4f input=16eb8bba71d82740]*/ +{ + return arg; +} + + +/*[clinic input] +my_int_sum -> int + + x: int + y: int + / + +[clinic start generated code]*/ + +static int +my_int_sum_impl(PyObject *module, int x, int y) +/*[clinic end generated code: output=3e52db9ab5f37e2f input=0edb6796813bf2d3]*/ +{ + return x + y; +} + + +static PyMethodDef tester_methods[] = { + TEST_EMPTY_FUNCTION_METHODDEF + MY_INT_FUNC_METHODDEF + MY_INT_SUM_METHODDEF + {NULL, NULL} +}; + +static struct PyModuleDef _testclinic_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_testclinic_limited", + .m_size = 0, + .m_methods = tester_methods, +}; + +PyMODINIT_FUNC +PyInit__testclinic_limited(void) +{ + PyObject *m = PyModule_Create(&_testclinic_module); + if (m == NULL) { + return NULL; + } + return m; +} diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 74c932fa921cd0..ddeb38938a331f 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -10,29 +10,30 @@ #undef NDEBUG #include "Python.h" -#include "frameobject.h" -#include "interpreteridobject.h" // _PyInterpreterID_LookUp() -#include "pycore_atomic_funcs.h" // _Py_atomic_int_get() -#include "pycore_bitutils.h" // _Py_bswap32() -#include "pycore_bytesobject.h" // _PyBytes_Find() -#include "pycore_compile.h" // _PyCompile_CodeGen, _PyCompile_OptimizeCfg, _PyCompile_Assemble, _PyCompile_CleanDoc -#include "pycore_ceval.h" // _PyEval_AddPendingCall -#include "pycore_fileutils.h" // _Py_normpath -#include "pycore_frame.h" // _PyInterpreterFrame -#include "pycore_gc.h" // PyGC_Head -#include "pycore_hashtable.h" // _Py_hashtable_new() -#include "pycore_initconfig.h" // _Py_GetConfigsAsDict() -#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy() -#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() -#include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost() -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "osdefs.h" // MAXPATHLEN +#include "pycore_bitutils.h" // _Py_bswap32() +#include "pycore_bytesobject.h" // _PyBytes_Find() +#include "pycore_ceval.h" // _PyEval_AddPendingCall() +#include "pycore_compile.h" // _PyCompile_CodeGen() +#include "pycore_context.h" // _PyContext_NewHamtForTests() +#include "pycore_dict.h" // _PyDictOrValues_GetValues() +#include "pycore_fileutils.h" // _Py_normpath() +#include "pycore_frame.h" // _PyInterpreterFrame +#include "pycore_gc.h" // PyGC_Head +#include "pycore_hashtable.h" // _Py_hashtable_new() +#include "pycore_initconfig.h" // _Py_GetConfigsAsDict() +#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy() +#include "pycore_long.h" // _PyLong_Sign() +#include "pycore_object.h" // _PyObject_IsFreed() +#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() +#include "pycore_pystate.h" // _PyThreadState_GET() + +#include "interpreteridobject.h" // PyInterpreterID_LookUp() #include "clinic/_testinternalcapi.c.h" -#ifdef MS_WINDOWS -# include // struct timeval -#endif +// Include test definitions from _testinternalcapi/ +#include "_testinternalcapi/parts.h" #define MODULE_NAME "_testinternalcapi" @@ -348,17 +349,6 @@ test_reset_path_config(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(arg)) } -static PyObject* -test_atomic_funcs(PyObject *self, PyObject *Py_UNUSED(args)) -{ - // Test _Py_atomic_size_get() and _Py_atomic_size_set() - Py_ssize_t var = 1; - _Py_atomic_size_set(&var, 2); - assert(_Py_atomic_size_get(&var) == 2); - Py_RETURN_NONE; -} - - static int check_edit_cost(const char *a, const char *b, Py_ssize_t expected) { @@ -685,7 +675,11 @@ record_eval(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc) assert(module != NULL); module_state *state = get_module_state(module); Py_DECREF(module); - PyList_Append(state->record_list, ((PyFunctionObject *)f->f_funcobj)->func_name); + int res = PyList_Append(state->record_list, + ((PyFunctionObject *)f->f_funcobj)->func_name); + if (res < 0) { + return NULL; + } } return _PyEval_EvalFrameDefault(tstate, f, exc); } @@ -1081,7 +1075,7 @@ pending_identify(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O:pending_identify", &interpid)) { return NULL; } - PyInterpreterState *interp = _PyInterpreterID_LookUp(interpid); + PyInterpreterState *interp = PyInterpreterID_LookUp(interpid); if (interp == NULL) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "interpreter not found"); @@ -1120,327 +1114,418 @@ pending_identify(PyObject *self, PyObject *args) return res; } - static PyObject * -test_pytime_fromseconds(PyObject *self, PyObject *args) +tracemalloc_get_traceback(PyObject *self, PyObject *args) { - int seconds; - if (!PyArg_ParseTuple(args, "i", &seconds)) { + unsigned int domain; + PyObject *ptr_obj; + + if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) { return NULL; } - _PyTime_t ts = _PyTime_FromSeconds(seconds); - return _PyTime_AsNanosecondsObject(ts); + void *ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) { + return NULL; + } + + return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); } -static int -check_time_rounding(int round) + +// Test PyThreadState C API +static PyObject * +test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) { - if (round != _PyTime_ROUND_FLOOR - && round != _PyTime_ROUND_CEILING - && round != _PyTime_ROUND_HALF_EVEN - && round != _PyTime_ROUND_UP) - { - PyErr_SetString(PyExc_ValueError, "invalid rounding"); - return -1; - } - return 0; + // PyThreadState_Get() + PyThreadState *tstate = PyThreadState_Get(); + assert(tstate != NULL); + + // test _PyThreadState_GetDict() + PyObject *dict = PyThreadState_GetDict(); + assert(dict != NULL); + // dict is a borrowed reference + + PyObject *dict2 = _PyThreadState_GetDict(tstate); + assert(dict2 == dict); + // dict2 is a borrowed reference + + Py_RETURN_NONE; } + +/* Test _PyUnicode_TransformDecimalAndSpaceToASCII() */ static PyObject * -test_pytime_fromsecondsobject(PyObject *self, PyObject *args) +unicode_transformdecimalandspacetoascii(PyObject *self, PyObject *arg) { - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t ts; - if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) { - return NULL; + if (arg == Py_None) { + arg = NULL; } - return _PyTime_AsNanosecondsObject(ts); + return _PyUnicode_TransformDecimalAndSpaceToASCII(arg); +} + + +struct atexit_data { + int called; +}; + +static void +callback(void *data) +{ + ((struct atexit_data *)data)->called += 1; } static PyObject * -test_pytime_assecondsdouble(PyObject *self, PyObject *args) +test_atexit(PyObject *self, PyObject *Py_UNUSED(args)) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { + PyThreadState *oldts = PyThreadState_Swap(NULL); + PyThreadState *tstate = Py_NewInterpreter(); + + struct atexit_data data = {0}; + int res = PyUnstable_AtExit(tstate->interp, callback, (void *)&data); + Py_EndInterpreter(tstate); + PyThreadState_Swap(oldts); + if (res < 0) { return NULL; } - _PyTime_t ts; - if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { + + if (data.called == 0) { + PyErr_SetString(PyExc_RuntimeError, "atexit callback not called"); return NULL; } - double d = _PyTime_AsSecondsDouble(ts); - return PyFloat_FromDouble(d); + Py_RETURN_NONE; } + static PyObject * -test_PyTime_AsTimeval(PyObject *self, PyObject *args) +test_pyobject_is_freed(const char *test_name, PyObject *op) { - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timeval tv; - if (_PyTime_AsTimeval(t, &tv, round) < 0) { + if (!_PyObject_IsFreed(op)) { + PyErr_SetString(PyExc_AssertionError, + "object is not seen as freed"); return NULL; } + Py_RETURN_NONE; +} - PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); - if (seconds == NULL) { - return NULL; - } - return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +static PyObject * +check_pyobject_null_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *op = NULL; + return test_pyobject_is_freed("check_pyobject_null_is_freed", op); } + static PyObject * -test_PyTime_AsTimeval_clamp(PyObject *self, PyObject *args) +check_pyobject_uninitialized_is_freed(PyObject *self, + PyObject *Py_UNUSED(args)) { - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); + if (op == NULL) { return NULL; } - struct timeval tv; - _PyTime_AsTimeval_clamp(t, &tv, round); + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* object fields like ob_type are uninitialized! */ + return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); +} - PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); - if (seconds == NULL) { + +static PyObject * +check_pyobject_forbidden_bytes_is_freed(PyObject *self, + PyObject *Py_UNUSED(args)) +{ + /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ + PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); + if (op == NULL) { return NULL; } - return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* ob_type field is after the memory block: part of "forbidden bytes" + when using debug hooks on memory allocators! */ + return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); } -#ifdef HAVE_CLOCK_GETTIME + static PyObject * -test_PyTime_AsTimespec(PyObject *self, PyObject *args) +check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timespec ts; - if (_PyTime_AsTimespec(t, &ts) == -1) { + /* This test would fail if run with the address sanitizer */ +#ifdef _Py_ADDRESS_SANITIZER + Py_RETURN_NONE; +#else + PyObject *op = PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); + if (op == NULL) { return NULL; } - return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); + Py_TYPE(op)->tp_dealloc(op); + /* Reset reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* object memory is freed! */ + return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); +#endif } + static PyObject * -test_PyTime_AsTimespec_clamp(PyObject *self, PyObject *args) +test_pymem_getallocatorsname(PyObject *self, PyObject *args) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + const char *name = _PyMem_GetCurrentAllocatorName(); + if (name == NULL) { + PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name"); return NULL; } - struct timespec ts; - _PyTime_AsTimespec_clamp(t, &ts); - return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); + return PyUnicode_FromString(name); } -#endif static PyObject * -test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) +get_object_dict_values(PyObject *self, PyObject *obj) { - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; + PyTypeObject *type = Py_TYPE(obj); + if (!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { + Py_RETURN_NONE; } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (!_PyDictOrValues_IsValues(dorv)) { + Py_RETURN_NONE; } - if (check_time_rounding(round) < 0) { + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; + assert(keys != NULL); + int size = (int)keys->dk_nentries; + assert(size >= 0); + PyObject *res = PyTuple_New(size); + if (res == NULL) { return NULL; } - _PyTime_t ms = _PyTime_AsMilliseconds(t, round); - _PyTime_t ns = _PyTime_FromNanoseconds(ms); - return _PyTime_AsNanosecondsObject(ns); + _Py_DECLARE_STR(anon_null, ""); + for(int i = 0; i < size; i++) { + PyObject *item = values->values[i]; + if (item == NULL) { + item = &_Py_STR(anon_null); + } + else { + Py_INCREF(item); + } + PyTuple_SET_ITEM(res, i, item); + } + return res; } -static PyObject * -test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) + +static PyObject* +new_hamt(PyObject *self, PyObject *args) { - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return _PyContext_NewHamtForTests(); +} + + +static PyObject* +dict_getitem_knownhash(PyObject *self, PyObject *args) +{ + PyObject *mp, *key, *result; + Py_ssize_t hash; + + if (!PyArg_ParseTuple(args, "OOn:dict_getitem_knownhash", + &mp, &key, &hash)) { return NULL; } - if (check_time_rounding(round) < 0) { + + result = _PyDict_GetItem_KnownHash(mp, key, (Py_hash_t)hash); + if (result == NULL && !PyErr_Occurred()) { + _PyErr_SetKeyError(key); return NULL; } - _PyTime_t us = _PyTime_AsMicroseconds(t, round); - _PyTime_t ns = _PyTime_FromNanoseconds(us); - return _PyTime_AsNanosecondsObject(ns); + + return Py_XNewRef(result); } + +/* To run some code in a sub-interpreter. */ static PyObject * -test_pytime_object_to_time_t(PyObject *self, PyObject *args) -{ - PyObject *obj; - time_t sec; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { +run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *code; + int use_main_obmalloc = -1; + int allow_fork = -1; + int allow_exec = -1; + int allow_threads = -1; + int allow_daemon_threads = -1; + int check_multi_interp_extensions = -1; + int gil = -1; + int r; + PyThreadState *substate, *mainstate; + /* only initialise 'cflags.cf_flags' to test backwards compatibility */ + PyCompilerFlags cflags = {0}; + + static char *kwlist[] = {"code", + "use_main_obmalloc", + "allow_fork", + "allow_exec", + "allow_threads", + "allow_daemon_threads", + "check_multi_interp_extensions", + "gil", + NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s$ppppppi:run_in_subinterp_with_config", kwlist, + &code, &use_main_obmalloc, + &allow_fork, &allow_exec, + &allow_threads, &allow_daemon_threads, + &check_multi_interp_extensions, + &gil)) { return NULL; } - if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) { + if (use_main_obmalloc < 0) { + PyErr_SetString(PyExc_ValueError, "missing use_main_obmalloc"); return NULL; } - return _PyLong_FromTime_t(sec); -} - -static PyObject * -test_pytime_object_to_timeval(PyObject *self, PyObject *args) -{ - PyObject *obj; - time_t sec; - long usec; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + if (allow_fork < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_fork"); return NULL; } - if (check_time_rounding(round) < 0) { + if (allow_exec < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_exec"); return NULL; } - if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) { + if (allow_threads < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_threads"); return NULL; } - return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); -} - -static PyObject * -test_pytime_object_to_timespec(PyObject *self, PyObject *args) -{ - PyObject *obj; - time_t sec; - long nsec; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + if (gil < 0) { + PyErr_SetString(PyExc_ValueError, "missing gil"); return NULL; } - if (check_time_rounding(round) < 0) { + if (allow_daemon_threads < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_daemon_threads"); return NULL; } - if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) { + if (check_multi_interp_extensions < 0) { + PyErr_SetString(PyExc_ValueError, "missing check_multi_interp_extensions"); return NULL; } - return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); -} + mainstate = PyThreadState_Get(); -static PyObject * -tracemalloc_get_traceback(PyObject *self, PyObject *args) -{ - unsigned int domain; - PyObject *ptr_obj; + PyThreadState_Swap(NULL); - if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) { - return NULL; - } - void *ptr = PyLong_AsVoidPtr(ptr_obj); - if (PyErr_Occurred()) { + const PyInterpreterConfig config = { + .use_main_obmalloc = use_main_obmalloc, + .allow_fork = allow_fork, + .allow_exec = allow_exec, + .allow_threads = allow_threads, + .allow_daemon_threads = allow_daemon_threads, + .check_multi_interp_extensions = check_multi_interp_extensions, + .gil = gil, + }; + PyStatus status = Py_NewInterpreterFromConfig(&substate, &config); + if (PyStatus_Exception(status)) { + /* Since no new thread state was created, there is no exception to + propagate; raise a fresh one after swapping in the old thread + state. */ + PyThreadState_Swap(mainstate); + _PyErr_SetFromPyStatus(status); + PyObject *exc = PyErr_GetRaisedException(); + PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed"); + _PyErr_ChainExceptions1(exc); return NULL; } + assert(substate != NULL); + r = PyRun_SimpleStringFlags(code, &cflags); + Py_EndInterpreter(substate); - return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); + PyThreadState_Swap(mainstate); + + return PyLong_FromLong(r); } -// Test PyThreadState C API +/*[clinic input] +_testinternalcapi.write_unraisable_exc + exception as exc: object + err_msg: object + obj: object + / +[clinic start generated code]*/ + static PyObject * -test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) +_testinternalcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, + PyObject *err_msg, PyObject *obj) +/*[clinic end generated code: output=a0f063cdd04aad83 input=274381b1a3fa5cd6]*/ { - // PyThreadState_Get() - PyThreadState *tstate = PyThreadState_Get(); - assert(tstate != NULL); - - // test _PyThreadState_GetDict() - PyObject *dict = PyThreadState_GetDict(); - assert(dict != NULL); - // dict is a borrowed reference - PyObject *dict2 = _PyThreadState_GetDict(tstate); - assert(dict2 == dict); - // dict2 is a borrowed reference + const char *err_msg_utf8; + if (err_msg != Py_None) { + err_msg_utf8 = PyUnicode_AsUTF8(err_msg); + if (err_msg_utf8 == NULL) { + return NULL; + } + } + else { + err_msg_utf8 = NULL; + } + PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); + _PyErr_WriteUnraisableMsg(err_msg_utf8, obj); Py_RETURN_NONE; } -/* Test _PyUnicode_TransformDecimalAndSpaceToASCII() */ static PyObject * -unicode_transformdecimalandspacetoascii(PyObject *self, PyObject *arg) +raiseTestError(const char* test_name, const char* msg) { - if (arg == Py_None) { - arg = NULL; - } - return _PyUnicode_TransformDecimalAndSpaceToASCII(arg); + PyErr_Format(PyExc_AssertionError, "%s: %s", test_name, msg); + return NULL; } -struct atexit_data { - int called; -}; - -static void -callback(void *data) -{ - ((struct atexit_data *)data)->called += 1; -} +/*[clinic input] +_testinternalcapi.test_long_numbits +[clinic start generated code]*/ static PyObject * -test_atexit(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyThreadState *oldts = PyThreadState_Swap(NULL); - PyThreadState *tstate = Py_NewInterpreter(); - - struct atexit_data data = {0}; - int res = _Py_AtExit(tstate->interp, callback, (void *)&data); - Py_EndInterpreter(tstate); - PyThreadState_Swap(oldts); - if (res < 0) { - return NULL; - } - - if (data.called == 0) { - PyErr_SetString(PyExc_RuntimeError, "atexit callback not called"); - return NULL; +_testinternalcapi_test_long_numbits_impl(PyObject *module) +/*[clinic end generated code: output=745d62d120359434 input=f14ca6f638e44dad]*/ +{ + struct triple { + long input; + size_t nbits; + int sign; + } testcases[] = {{0, 0, 0}, + {1L, 1, 1}, + {-1L, 1, -1}, + {2L, 2, 1}, + {-2L, 2, -1}, + {3L, 2, 1}, + {-3L, 2, -1}, + {4L, 3, 1}, + {-4L, 3, -1}, + {0x7fffL, 15, 1}, /* one Python int digit */ + {-0x7fffL, 15, -1}, + {0xffffL, 16, 1}, + {-0xffffL, 16, -1}, + {0xfffffffL, 28, 1}, + {-0xfffffffL, 28, -1}}; + size_t i; + + for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { + size_t nbits; + int sign; + PyObject *plong; + + plong = PyLong_FromLong(testcases[i].input); + if (plong == NULL) + return NULL; + nbits = _PyLong_NumBits(plong); + sign = _PyLong_Sign(plong); + + Py_DECREF(plong); + if (nbits != testcases[i].nbits) + return raiseTestError("test_long_numbits", + "wrong result for _PyLong_NumBits"); + if (sign != testcases[i].sign) + return raiseTestError("test_long_numbits", + "wrong result for _PyLong_Sign"); } Py_RETURN_NONE; } @@ -1456,7 +1541,6 @@ static PyMethodDef module_functions[] = { {"get_config", test_get_config, METH_NOARGS}, {"set_config", test_set_config, METH_O}, {"reset_path_config", test_reset_path_config, METH_NOARGS}, - {"test_atomic_funcs", test_atomic_funcs, METH_NOARGS}, {"test_edit_cost", test_edit_cost, METH_NOARGS}, {"test_bytes_find", test_bytes_find, METH_NOARGS}, {"normalize_path", normalize_path, METH_O, NULL}, @@ -1484,24 +1568,25 @@ static PyMethodDef module_functions[] = { {"pending_threadfunc", _PyCFunction_CAST(pending_threadfunc), METH_VARARGS | METH_KEYWORDS}, {"pending_identify", pending_identify, METH_VARARGS, NULL}, - {"_PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, - {"_PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, - {"_PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, -#ifdef HAVE_CLOCK_GETTIME - {"_PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, - {"_PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, -#endif - {"_PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, - {"_PyTime_AsTimeval_clamp", test_PyTime_AsTimeval_clamp, METH_VARARGS}, - {"_PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS}, - {"_PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, - {"_PyTime_ObjectToTime_t", test_pytime_object_to_time_t, METH_VARARGS}, - {"_PyTime_ObjectToTimespec", test_pytime_object_to_timespec, METH_VARARGS}, - {"_PyTime_ObjectToTimeval", test_pytime_object_to_timeval, METH_VARARGS}, {"_PyTraceMalloc_GetTraceback", tracemalloc_get_traceback, METH_VARARGS}, {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, {"_PyUnicode_TransformDecimalAndSpaceToASCII", unicode_transformdecimalandspacetoascii, METH_O}, {"test_atexit", test_atexit, 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}, + {"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS}, + {"check_pyobject_uninitialized_is_freed", + check_pyobject_uninitialized_is_freed, METH_NOARGS}, + {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, + {"get_object_dict_values", get_object_dict_values, METH_O}, + {"hamt", new_hamt, METH_NOARGS}, + {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, + {"run_in_subinterp_with_config", + _PyCFunction_CAST(run_in_subinterp_with_config), + METH_VARARGS | METH_KEYWORDS}, + _TESTINTERNALCAPI_WRITE_UNRAISABLE_EXC_METHODDEF + _TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -1511,11 +1596,26 @@ static PyMethodDef module_functions[] = { static int module_exec(PyObject *module) { + if (_PyTestInternalCapi_Init_Lock(module) < 0) { + return 1; + } + if (_PyTestInternalCapi_Init_PyTime(module) < 0) { + return 1; + } + if (_PyTestInternalCapi_Init_Set(module) < 0) { + return 1; + } + if (PyModule_Add(module, "SIZEOF_PYGC_HEAD", PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { return 1; } + if (PyModule_Add(module, "SIZEOF_PYOBJECT", + PyLong_FromSsize_t(sizeof(PyObject))) < 0) { + return 1; + } + if (PyModule_Add(module, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t))) < 0) { return 1; diff --git a/Modules/_testinternalcapi/README.txt b/Modules/_testinternalcapi/README.txt new file mode 100644 index 00000000000000..eb071135e4c592 --- /dev/null +++ b/Modules/_testinternalcapi/README.txt @@ -0,0 +1,5 @@ +Tests in this directory are compiled into the _testinternalcapi extension. +The main file for the extension is Modules/_testinternalcapimodule.c, which +calls `_PyTestInternalCapi_Init_*` from these functions. + +See Modules/_testcapi/README.txt for guideline when writing C test code. \ No newline at end of file diff --git a/Modules/_testinternalcapi/clinic/test_lock.c.h b/Modules/_testinternalcapi/clinic/test_lock.c.h new file mode 100644 index 00000000000000..3cbe5ef12c5fa6 --- /dev/null +++ b/Modules/_testinternalcapi/clinic/test_lock.c.h @@ -0,0 +1,74 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#include "pycore_abstract.h" // _PyNumber_Index() + +PyDoc_STRVAR(_testinternalcapi_benchmark_locks__doc__, +"benchmark_locks($module, num_threads, use_pymutex=True,\n" +" critical_section_length=1, time_ms=1000, /)\n" +"--\n" +"\n"); + +#define _TESTINTERNALCAPI_BENCHMARK_LOCKS_METHODDEF \ + {"benchmark_locks", _PyCFunction_CAST(_testinternalcapi_benchmark_locks), METH_FASTCALL, _testinternalcapi_benchmark_locks__doc__}, + +static PyObject * +_testinternalcapi_benchmark_locks_impl(PyObject *module, + Py_ssize_t num_threads, + int use_pymutex, + int critical_section_length, + int time_ms); + +static PyObject * +_testinternalcapi_benchmark_locks(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t num_threads; + int use_pymutex = 1; + int critical_section_length = 1; + int time_ms = 1000; + + if (!_PyArg_CheckPositional("benchmark_locks", nargs, 1, 4)) { + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + num_threads = ival; + } + if (nargs < 2) { + goto skip_optional; + } + use_pymutex = PyObject_IsTrue(args[1]); + if (use_pymutex < 0) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + critical_section_length = PyLong_AsInt(args[2]); + if (critical_section_length == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + time_ms = PyLong_AsInt(args[3]); + if (time_ms == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _testinternalcapi_benchmark_locks_impl(module, num_threads, use_pymutex, critical_section_length, time_ms); + +exit: + return return_value; +} +/*[clinic end generated code: output=97c85dff601fed4b input=a9049054013a1b77]*/ diff --git a/Modules/_testinternalcapi/parts.h b/Modules/_testinternalcapi/parts.h new file mode 100644 index 00000000000000..3d2774e3f1b404 --- /dev/null +++ b/Modules/_testinternalcapi/parts.h @@ -0,0 +1,17 @@ +#ifndef Py_TESTINTERNALCAPI_PARTS_H +#define Py_TESTINTERNALCAPI_PARTS_H + +// Always enable assertions +#undef NDEBUG + +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +#include "Python.h" + +int _PyTestInternalCapi_Init_Lock(PyObject *module); +int _PyTestInternalCapi_Init_PyTime(PyObject *module); +int _PyTestInternalCapi_Init_Set(PyObject *module); + +#endif // Py_TESTINTERNALCAPI_PARTS_H diff --git a/Modules/_testinternalcapi/pytime.c b/Modules/_testinternalcapi/pytime.c new file mode 100644 index 00000000000000..2b5f9eb0ef2851 --- /dev/null +++ b/Modules/_testinternalcapi/pytime.c @@ -0,0 +1,279 @@ +/* Test pycore_time.h */ + +#include "parts.h" + +#include "pycore_time.h" + +#ifdef MS_WINDOWS +# include // struct timeval +#endif + + +static PyObject * +test_pytime_fromseconds(PyObject *self, PyObject *args) +{ + int seconds; + if (!PyArg_ParseTuple(args, "i", &seconds)) { + return NULL; + } + _PyTime_t ts = _PyTime_FromSeconds(seconds); + return _PyTime_AsNanosecondsObject(ts); +} + +static int +check_time_rounding(int round) +{ + if (round != _PyTime_ROUND_FLOOR + && round != _PyTime_ROUND_CEILING + && round != _PyTime_ROUND_HALF_EVEN + && round != _PyTime_ROUND_UP) + { + PyErr_SetString(PyExc_ValueError, "invalid rounding"); + return -1; + } + return 0; +} + +static PyObject * +test_pytime_fromsecondsobject(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t ts; + if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) { + return NULL; + } + return _PyTime_AsNanosecondsObject(ts); +} + +static PyObject * +test_pytime_assecondsdouble(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t ts; + if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { + return NULL; + } + double d = _PyTime_AsSecondsDouble(ts); + return PyFloat_FromDouble(d); +} + +static PyObject * +test_PyTime_AsTimeval(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timeval tv; + if (_PyTime_AsTimeval(t, &tv, round) < 0) { + return NULL; + } + + PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); + if (seconds == NULL) { + return NULL; + } + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +} + +static PyObject * +test_PyTime_AsTimeval_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timeval tv; + _PyTime_AsTimeval_clamp(t, &tv, round); + + PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); + if (seconds == NULL) { + return NULL; + } + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +} + +#ifdef HAVE_CLOCK_GETTIME +static PyObject * +test_PyTime_AsTimespec(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timespec ts; + if (_PyTime_AsTimespec(t, &ts) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +} + +static PyObject * +test_PyTime_AsTimespec_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timespec ts; + _PyTime_AsTimespec_clamp(t, &ts); + return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +} +#endif + +static PyObject * +test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t ms = _PyTime_AsMilliseconds(t, round); + _PyTime_t ns = _PyTime_FromNanoseconds(ms); + return _PyTime_AsNanosecondsObject(ns); +} + +static PyObject * +test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t us = _PyTime_AsMicroseconds(t, round); + _PyTime_t ns = _PyTime_FromNanoseconds(us); + return _PyTime_AsNanosecondsObject(ns); +} + +static PyObject * +test_pytime_object_to_time_t(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) { + return NULL; + } + return _PyLong_FromTime_t(sec); +} + +static PyObject * +test_pytime_object_to_timeval(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + long usec; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); +} + +static PyObject * +test_pytime_object_to_timespec(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + long nsec; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); +} + +static PyMethodDef TestMethods[] = { + {"_PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, + {"_PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, + {"_PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, +#ifdef HAVE_CLOCK_GETTIME + {"_PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, + {"_PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, +#endif + {"_PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, + {"_PyTime_AsTimeval_clamp", test_PyTime_AsTimeval_clamp, METH_VARARGS}, + {"_PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS}, + {"_PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, + {"_PyTime_ObjectToTime_t", test_pytime_object_to_time_t, METH_VARARGS}, + {"_PyTime_ObjectToTimespec", test_pytime_object_to_timespec, METH_VARARGS}, + {"_PyTime_ObjectToTimeval", test_pytime_object_to_timeval, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + +int +_PyTestInternalCapi_Init_PyTime(PyObject *m) +{ + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testinternalcapi/set.c b/Modules/_testinternalcapi/set.c new file mode 100644 index 00000000000000..0305a7885d217c --- /dev/null +++ b/Modules/_testinternalcapi/set.c @@ -0,0 +1,59 @@ +#include "parts.h" +#include "../_testcapi/util.h" // NULLABLE, RETURN_INT + +#include "pycore_setobject.h" + + +static PyObject * +set_update(PyObject *self, PyObject *args) +{ + PyObject *set, *iterable; + if (!PyArg_ParseTuple(args, "OO", &set, &iterable)) { + return NULL; + } + NULLABLE(set); + NULLABLE(iterable); + RETURN_INT(_PySet_Update(set, iterable)); +} + +static PyObject * +set_next_entry(PyObject *self, PyObject *args) +{ + int rc; + Py_ssize_t pos; + Py_hash_t hash = (Py_hash_t)UNINITIALIZED_SIZE; + PyObject *set, *item = UNINITIALIZED_PTR; + if (!PyArg_ParseTuple(args, "On", &set, &pos)) { + return NULL; + } + NULLABLE(set); + + rc = _PySet_NextEntry(set, &pos, &item, &hash); + if (rc == 1) { + return Py_BuildValue("innO", rc, pos, hash, item); + } + assert(item == UNINITIALIZED_PTR); + assert(hash == (Py_hash_t)UNINITIALIZED_SIZE); + if (rc == -1) { + return NULL; + } + assert(rc == 0); + Py_RETURN_NONE; +} + + +static PyMethodDef TestMethods[] = { + {"set_update", set_update, METH_VARARGS}, + {"set_next_entry", set_next_entry, METH_VARARGS}, + + {NULL}, +}; + +int +_PyTestInternalCapi_Init_Set(PyObject *m) +{ + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testinternalcapi/test_lock.c b/Modules/_testinternalcapi/test_lock.c new file mode 100644 index 00000000000000..33b49dacaa946e --- /dev/null +++ b/Modules/_testinternalcapi/test_lock.c @@ -0,0 +1,353 @@ +// C Extension module to test pycore_lock.h API + +#include "parts.h" + +#include "pycore_lock.h" +#include "clinic/test_lock.c.h" + +#ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#else +#include // usleep() +#endif + +/*[clinic input] +module _testinternalcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7bb583d8c9eb9a78]*/ + + +static void +pysleep(int ms) +{ +#ifdef MS_WINDOWS + Sleep(ms); +#else + usleep(ms * 1000); +#endif +} + +static PyObject * +test_lock_basic(PyObject *self, PyObject *obj) +{ + PyMutex m = (PyMutex){0}; + + // uncontended lock and unlock + PyMutex_Lock(&m); + assert(m.v == 1); + PyMutex_Unlock(&m); + assert(m.v == 0); + + Py_RETURN_NONE; +} + +struct test_lock2_data { + PyMutex m; + PyEvent done; + int started; +}; + +static void +lock_thread(void *arg) +{ + struct test_lock2_data *test_data = arg; + PyMutex *m = &test_data->m; + _Py_atomic_store_int(&test_data->started, 1); + + PyMutex_Lock(m); + assert(m->v == 1); + + PyMutex_Unlock(m); + assert(m->v == 0); + + _PyEvent_Notify(&test_data->done); +} + +static PyObject * +test_lock_two_threads(PyObject *self, PyObject *obj) +{ + // lock attempt by two threads + struct test_lock2_data test_data; + memset(&test_data, 0, sizeof(test_data)); + + PyMutex_Lock(&test_data.m); + assert(test_data.m.v == 1); + + PyThread_start_new_thread(lock_thread, &test_data); + while (!_Py_atomic_load_int(&test_data.started)) { + pysleep(10); + } + pysleep(10); // allow some time for the other thread to try to lock + assert(test_data.m.v == 3); + + PyMutex_Unlock(&test_data.m); + PyEvent_Wait(&test_data.done); + assert(test_data.m.v == 0); + + Py_RETURN_NONE; +} + +#define COUNTER_THREADS 5 +#define COUNTER_ITERS 10000 + +struct test_data_counter { + PyMutex m; + Py_ssize_t counter; +}; + +struct thread_data_counter { + struct test_data_counter *test_data; + PyEvent done_event; +}; + +static void +counter_thread(void *arg) +{ + struct thread_data_counter *thread_data = arg; + struct test_data_counter *test_data = thread_data->test_data; + + for (Py_ssize_t i = 0; i < COUNTER_ITERS; i++) { + PyMutex_Lock(&test_data->m); + test_data->counter++; + PyMutex_Unlock(&test_data->m); + } + _PyEvent_Notify(&thread_data->done_event); +} + +static PyObject * +test_lock_counter(PyObject *self, PyObject *obj) +{ + // Test with rapidly locking and unlocking mutex + struct test_data_counter test_data; + memset(&test_data, 0, sizeof(test_data)); + + struct thread_data_counter thread_data[COUNTER_THREADS]; + memset(&thread_data, 0, sizeof(thread_data)); + + for (Py_ssize_t i = 0; i < COUNTER_THREADS; i++) { + thread_data[i].test_data = &test_data; + PyThread_start_new_thread(counter_thread, &thread_data[i]); + } + + for (Py_ssize_t i = 0; i < COUNTER_THREADS; i++) { + PyEvent_Wait(&thread_data[i].done_event); + } + + assert(test_data.counter == COUNTER_THREADS * COUNTER_ITERS); + Py_RETURN_NONE; +} + +#define SLOW_COUNTER_ITERS 100 + +static void +slow_counter_thread(void *arg) +{ + struct thread_data_counter *thread_data = arg; + struct test_data_counter *test_data = thread_data->test_data; + + for (Py_ssize_t i = 0; i < SLOW_COUNTER_ITERS; i++) { + PyMutex_Lock(&test_data->m); + if (i % 7 == 0) { + pysleep(2); + } + test_data->counter++; + PyMutex_Unlock(&test_data->m); + } + _PyEvent_Notify(&thread_data->done_event); +} + +static PyObject * +test_lock_counter_slow(PyObject *self, PyObject *obj) +{ + // Test lock/unlock with occasional "long" critical section, which will + // trigger handoff of the lock. + struct test_data_counter test_data; + memset(&test_data, 0, sizeof(test_data)); + + struct thread_data_counter thread_data[COUNTER_THREADS]; + memset(&thread_data, 0, sizeof(thread_data)); + + for (Py_ssize_t i = 0; i < COUNTER_THREADS; i++) { + thread_data[i].test_data = &test_data; + PyThread_start_new_thread(slow_counter_thread, &thread_data[i]); + } + + for (Py_ssize_t i = 0; i < COUNTER_THREADS; i++) { + PyEvent_Wait(&thread_data[i].done_event); + } + + assert(test_data.counter == COUNTER_THREADS * SLOW_COUNTER_ITERS); + Py_RETURN_NONE; +} + +struct bench_data_locks { + int stop; + int use_pymutex; + int critical_section_length; + char padding[200]; + PyThread_type_lock lock; + PyMutex m; + double value; + Py_ssize_t total_iters; +}; + +struct bench_thread_data { + struct bench_data_locks *bench_data; + Py_ssize_t iters; + PyEvent done; +}; + +static void +thread_benchmark_locks(void *arg) +{ + struct bench_thread_data *thread_data = arg; + struct bench_data_locks *bench_data = thread_data->bench_data; + int use_pymutex = bench_data->use_pymutex; + int critical_section_length = bench_data->critical_section_length; + + double my_value = 1.0; + Py_ssize_t iters = 0; + while (!_Py_atomic_load_int_relaxed(&bench_data->stop)) { + if (use_pymutex) { + PyMutex_Lock(&bench_data->m); + for (int i = 0; i < critical_section_length; i++) { + bench_data->value += my_value; + my_value = bench_data->value; + } + PyMutex_Unlock(&bench_data->m); + } + else { + PyThread_acquire_lock(bench_data->lock, 1); + for (int i = 0; i < critical_section_length; i++) { + bench_data->value += my_value; + my_value = bench_data->value; + } + PyThread_release_lock(bench_data->lock); + } + iters++; + } + + thread_data->iters = iters; + _Py_atomic_add_ssize(&bench_data->total_iters, iters); + _PyEvent_Notify(&thread_data->done); +} + +/*[clinic input] +_testinternalcapi.benchmark_locks + + num_threads: Py_ssize_t + use_pymutex: bool = True + critical_section_length: int = 1 + time_ms: int = 1000 + / + +[clinic start generated code]*/ + +static PyObject * +_testinternalcapi_benchmark_locks_impl(PyObject *module, + Py_ssize_t num_threads, + int use_pymutex, + int critical_section_length, + int time_ms) +/*[clinic end generated code: output=381df8d7e9a74f18 input=f3aeaf688738c121]*/ +{ + // Run from Tools/lockbench/lockbench.py + // Based on the WebKit lock benchmarks: + // https://github.com/WebKit/WebKit/blob/main/Source/WTF/benchmarks/LockSpeedTest.cpp + // See also https://webkit.org/blog/6161/locking-in-webkit/ + PyObject *thread_iters = NULL; + PyObject *res = NULL; + + struct bench_data_locks bench_data; + memset(&bench_data, 0, sizeof(bench_data)); + bench_data.use_pymutex = use_pymutex; + bench_data.critical_section_length = critical_section_length; + + bench_data.lock = PyThread_allocate_lock(); + if (bench_data.lock == NULL) { + return PyErr_NoMemory(); + } + + struct bench_thread_data *thread_data = NULL; + thread_data = PyMem_Calloc(num_threads, sizeof(*thread_data)); + if (thread_data == NULL) { + PyErr_NoMemory(); + goto exit; + } + + thread_iters = PyList_New(num_threads); + if (thread_iters == NULL) { + goto exit; + } + + _PyTime_t start = _PyTime_GetMonotonicClock(); + + for (Py_ssize_t i = 0; i < num_threads; i++) { + thread_data[i].bench_data = &bench_data; + PyThread_start_new_thread(thread_benchmark_locks, &thread_data[i]); + } + + // Let the threads run for `time_ms` milliseconds + pysleep(time_ms); + _Py_atomic_store_int(&bench_data.stop, 1); + + // Wait for the threads to finish + for (Py_ssize_t i = 0; i < num_threads; i++) { + PyEvent_Wait(&thread_data[i].done); + } + + Py_ssize_t total_iters = bench_data.total_iters; + _PyTime_t end = _PyTime_GetMonotonicClock(); + + // Return the total number of acquisitions and the number of acquisitions + // for each thread. + for (Py_ssize_t i = 0; i < num_threads; i++) { + PyObject *iter = PyLong_FromSsize_t(thread_data[i].iters); + if (iter == NULL) { + goto exit; + } + PyList_SET_ITEM(thread_iters, i, iter); + } + + double rate = total_iters * 1000000000.0 / (end - start); + res = Py_BuildValue("(dO)", rate, thread_iters); + +exit: + PyThread_free_lock(bench_data.lock); + PyMem_Free(thread_data); + Py_XDECREF(thread_iters); + return res; +} + +static PyObject * +test_lock_benchmark(PyObject *module, PyObject *obj) +{ + // Just make sure the benchmark runs without crashing + PyObject *res = _testinternalcapi_benchmark_locks_impl( + module, 1, 1, 1, 100); + if (res == NULL) { + return NULL; + } + Py_DECREF(res); + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"test_lock_basic", test_lock_basic, METH_NOARGS}, + {"test_lock_two_threads", test_lock_two_threads, METH_NOARGS}, + {"test_lock_counter", test_lock_counter, METH_NOARGS}, + {"test_lock_counter_slow", test_lock_counter_slow, METH_NOARGS}, + _TESTINTERNALCAPI_BENCHMARK_LOCKS_METHODDEF + {"test_lock_benchmark", test_lock_benchmark, METH_NOARGS}, + {NULL, NULL} /* sentinel */ +}; + +int +_PyTestInternalCapi_Init_Lock(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index ca71b6156b005d..fdef06168bfc86 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -383,32 +383,20 @@ static int execfunc(PyObject *m) /* Add a custom type */ temp = PyType_FromSpec(&Example_Type_spec); - if (temp == NULL) { - goto fail; - } - if (PyModule_AddObject(m, "Example", temp) != 0) { - Py_DECREF(temp); + if (PyModule_Add(m, "Example", temp) != 0) { goto fail; } /* Add an exception type */ temp = PyErr_NewException("_testimportexec.error", NULL, NULL); - if (temp == NULL) { - goto fail; - } - if (PyModule_AddObject(m, "error", temp) != 0) { - Py_DECREF(temp); + if (PyModule_Add(m, "error", temp) != 0) { goto fail; } /* Add Str */ temp = PyType_FromSpec(&Str_Type_spec); - if (temp == NULL) { - goto fail; - } - if (PyModule_AddObject(m, "Str", temp) != 0) { - Py_DECREF(temp); + if (PyModule_Add(m, "Str", temp) != 0) { goto fail; } @@ -857,11 +845,7 @@ meth_state_access_exec(PyObject *m) } temp = PyType_FromModuleAndSpec(m, &StateAccessType_spec, NULL); - if (temp == NULL) { - return -1; - } - if (PyModule_AddObject(m, "StateAccessType", temp) != 0) { - Py_DECREF(temp); + if (PyModule_Add(m, "StateAccessType", temp) != 0) { return -1; } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index d8a797f34dbc4b..86bd560b92ba6b 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -3,14 +3,17 @@ /* Interface to Sjoerd's portable C thread library */ #include "Python.h" +#include "pycore_ceval.h" // _PyEval_MakePendingCalls() +#include "pycore_dict.h" // _PyDict_Pop() #include "pycore_interp.h" // _PyInterpreterState.threads.count #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() #include "pycore_pylifecycle.h" #include "pycore_pystate.h" // _PyThreadState_SetCurrent() +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_weakref.h" // _PyWeakref_GET_REF() -#include // offsetof() -#include "structmember.h" // PyMemberDef +#include // offsetof() #ifdef HAVE_SIGNAL_H # include // SIGINT #endif @@ -293,7 +296,7 @@ unlock it. A thread attempting to lock a lock that it has already locked\n\ will block until another thread unlocks it. Deadlocks may ensue."); static PyMemberDef lock_type_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(lockobject, in_weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(lockobject, in_weakreflist), Py_READONLY}, {NULL}, }; @@ -487,6 +490,18 @@ PyDoc_STRVAR(rlock_release_save_doc, \n\ For internal use by `threading.Condition`."); +static PyObject * +rlock_recursion_count(rlockobject *self, PyObject *Py_UNUSED(ignored)) +{ + unsigned long tid = PyThread_get_thread_ident(); + return PyLong_FromUnsignedLong( + self->rlock_owner == tid ? self->rlock_count : 0UL); +} + +PyDoc_STRVAR(rlock_recursion_count_doc, +"_recursion_count() -> int\n\ +\n\ +For internal use by reentrancy checks."); static PyObject * rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored)) @@ -562,6 +577,8 @@ static PyMethodDef rlock_methods[] = { METH_VARARGS, rlock_acquire_restore_doc}, {"_release_save", (PyCFunction)rlock_release_save, METH_NOARGS, rlock_release_save_doc}, + {"_recursion_count", (PyCFunction)rlock_recursion_count, + METH_NOARGS, rlock_recursion_count_doc}, {"__enter__", _PyCFunction_CAST(rlock_acquire), METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, {"__exit__", (PyCFunction)rlock_release, @@ -575,7 +592,7 @@ static PyMethodDef rlock_methods[] = { static PyMemberDef rlock_type_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(rlockobject, in_weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(rlockobject, in_weakreflist), Py_READONLY}, {NULL}, }; @@ -679,7 +696,7 @@ localdummy_dealloc(localdummyobject *self) } static PyMemberDef local_dummy_type_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(localdummyobject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(localdummyobject, weakreflist), Py_READONLY}, {NULL}, }; @@ -959,7 +976,7 @@ local_setattro(localobject *self, PyObject *name, PyObject *v) static PyObject *local_getattro(localobject *, PyObject *); static PyMemberDef local_type_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(localobject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(localobject, weakreflist), Py_READONLY}, {NULL}, }; @@ -1048,22 +1065,22 @@ _localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref) /* Module functions */ struct bootstate { - PyInterpreterState *interp; + PyThreadState *tstate; PyObject *func; PyObject *args; PyObject *kwargs; - PyThreadState *tstate; - _PyRuntimeState *runtime; }; static void -thread_bootstate_free(struct bootstate *boot) +thread_bootstate_free(struct bootstate *boot, int decref) { - Py_DECREF(boot->func); - Py_DECREF(boot->args); - Py_XDECREF(boot->kwargs); - PyMem_Free(boot); + if (decref) { + Py_DECREF(boot->func); + Py_DECREF(boot->args); + Py_XDECREF(boot->kwargs); + } + PyMem_RawFree(boot); } @@ -1071,9 +1088,27 @@ static void thread_run(void *boot_raw) { struct bootstate *boot = (struct bootstate *) boot_raw; - PyThreadState *tstate; + PyThreadState *tstate = boot->tstate; + + // gh-108987: If _thread.start_new_thread() is called before or while + // Python is being finalized, thread_run() can called *after*. + // _PyRuntimeState_SetFinalizing() is called. At this point, all Python + // threads must exit, except of the thread calling Py_Finalize() whch holds + // the GIL and must not exit. + // + // At this stage, tstate can be a dangling pointer (point to freed memory), + // it's ok to call _PyThreadState_MustExit() with a dangling pointer. + if (_PyThreadState_MustExit(tstate)) { + // Don't call PyThreadState_Clear() nor _PyThreadState_DeleteCurrent(). + // These functions are called on tstate indirectly by Py_Finalize() + // which calls _PyInterpreterState_Clear(). + // + // Py_DECREF() cannot be called because the GIL is not held: leak + // references on purpose. Python is being finalized anyway. + thread_bootstate_free(boot, 0); + goto exit; + } - tstate = boot->tstate; _PyThreadState_Bind(tstate); PyEval_AcquireThread(tstate); tstate->interp->threads.count++; @@ -1091,14 +1126,17 @@ thread_run(void *boot_raw) Py_DECREF(res); } - thread_bootstate_free(boot); + thread_bootstate_free(boot, 1); + tstate->interp->threads.count--; PyThreadState_Clear(tstate); _PyThreadState_DeleteCurrent(tstate); +exit: // bpo-44434: Don't call explicitly PyThread_exit_thread(). On Linux with // the glibc, pthread_exit() can abort the whole process if dlopen() fails // to open the libgcc_s.so library (ex: EMFILE error). + return; } static PyObject * @@ -1122,7 +1160,6 @@ and False otherwise.\n"); static PyObject * thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) { - _PyRuntimeState *runtime = &_PyRuntime; PyObject *func, *args, *kwargs = NULL; if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, @@ -1161,20 +1198,21 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) return NULL; } - struct bootstate *boot = PyMem_NEW(struct bootstate, 1); + // gh-109795: Use PyMem_RawMalloc() instead of PyMem_Malloc(), + // because it should be possible to call thread_bootstate_free() + // without holding the GIL. + struct bootstate *boot = PyMem_RawMalloc(sizeof(struct bootstate)); if (boot == NULL) { return PyErr_NoMemory(); } - boot->interp = _PyInterpreterState_GET(); - boot->tstate = _PyThreadState_New(boot->interp); + boot->tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_THREADING); if (boot->tstate == NULL) { - PyMem_Free(boot); + PyMem_RawFree(boot); if (!PyErr_Occurred()) { return PyErr_NoMemory(); } return NULL; } - boot->runtime = runtime; boot->func = Py_NewRef(func); boot->args = Py_NewRef(args); boot->kwargs = Py_XNewRef(kwargs); @@ -1183,7 +1221,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) if (ident == PYTHREAD_INVALID_THREAD_ID) { PyErr_SetString(ThreadError, "can't start new thread"); PyThreadState_Clear(boot->tstate); - thread_bootstate_free(boot); + thread_bootstate_free(boot, 1); return NULL; } return PyLong_FromUnsignedLong(ident); @@ -1476,11 +1514,9 @@ thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, _PyErr_Display(file, exc_type, exc_value, exc_traceback); /* Call file.flush() */ - PyObject *res = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); - if (!res) { + if (_PyFile_Flush(file) < 0) { return -1; } - Py_DECREF(res); return 0; } @@ -1569,6 +1605,18 @@ PyDoc_STRVAR(excepthook_doc, \n\ Handle uncaught Thread.run() exception."); +static PyObject * +thread__is_main_interpreter(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return PyBool_FromLong(_Py_IsMainInterpreter(interp)); +} + +PyDoc_STRVAR(thread__is_main_interpreter_doc, +"_is_main_interpreter()\n\ +\n\ +Return True if the current interpreter is the main Python interpreter."); + static PyMethodDef thread_methods[] = { {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread, METH_VARARGS, start_new_doc}, @@ -1598,8 +1646,10 @@ static PyMethodDef thread_methods[] = { METH_VARARGS, stack_size_doc}, {"_set_sentinel", thread__set_sentinel, METH_NOARGS, _set_sentinel_doc}, - {"_excepthook", thread_excepthook, + {"_excepthook", thread_excepthook, METH_O, excepthook_doc}, + {"_is_main_interpreter", thread__is_main_interpreter, + METH_NOARGS, thread__is_main_interpreter_doc}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 76af803bd6eefb..f9a18644945c65 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -26,15 +26,14 @@ Copyright (C) 1994 Steen Lumholt. #endif #include "Python.h" -#include #ifdef MS_WINDOWS # include "pycore_fileutils.h" // _Py_stat() #endif -#include "pycore_long.h" +#include "pycore_long.h" // _PyLong_IsNegative() #ifdef MS_WINDOWS -#include +# include #endif #define CHECK_SIZE(size, elemsize) \ @@ -46,11 +45,11 @@ Copyright (C) 1994 Steen Lumholt. #define TCL_THREADS #ifdef TK_FRAMEWORK -#include -#include +# include +# include #else -#include -#include +# include +# include #endif #include "tkinter.h" @@ -317,7 +316,6 @@ typedef struct { const Tcl_ObjType *WideIntType; const Tcl_ObjType *BignumType; const Tcl_ObjType *ListType; - const Tcl_ObjType *ProcBodyType; const Tcl_ObjType *StringType; } TkappObject; @@ -595,7 +593,6 @@ Tkapp_New(const char *screenName, const char *className, v->WideIntType = Tcl_GetObjType("wideInt"); v->BignumType = Tcl_GetObjType("bignum"); v->ListType = Tcl_GetObjType("list"); - v->ProcBodyType = Tcl_GetObjType("procbody"); v->StringType = Tcl_GetObjType("string"); /* Delete the 'exit' command, which can screw things up */ @@ -874,8 +871,9 @@ asBignumObj(PyObject *value) return NULL; } hexchars += neg + 2; /* skip sign and "0x" */ - mp_init(&bigValue); - if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) { + if (mp_init(&bigValue) != MP_OKAY || + mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) + { mp_clear(&bigValue); Py_DECREF(hexstr); PyErr_NoMemory(); @@ -912,16 +910,13 @@ AsObj(PyObject *value) if (PyLong_CheckExact(value)) { int overflow; long longValue; -#ifdef TCL_WIDE_INT_TYPE Tcl_WideInt wideValue; -#endif longValue = PyLong_AsLongAndOverflow(value, &overflow); if (!overflow) { return Tcl_NewLongObj(longValue); } /* If there is an overflow in the long conversion, fall through to wideInt handling. */ -#ifdef TCL_WIDE_INT_TYPE if (_PyLong_AsByteArray((PyLongObject *)value, (unsigned char *)(void *)&wideValue, sizeof(wideValue), @@ -930,7 +925,6 @@ AsObj(PyObject *value) return Tcl_NewWideIntObj(wideValue); } PyErr_Clear(); -#endif /* If there is an overflow in the wideInt conversion, fall through to bignum handling. */ return asBignumObj(value); @@ -1174,10 +1168,6 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value) return result; } - if (value->typePtr == tkapp->ProcBodyType) { - /* fall through: return tcl object. */ - } - if (value->typePtr == tkapp->StringType) { return unicodeFromTclObj(value); } @@ -3197,7 +3187,7 @@ static struct PyModuleDef _tkintermodule = { PyMODINIT_FUNC PyInit__tkinter(void) { - PyObject *m, *uexe, *cexe, *o; + PyObject *m, *uexe, *cexe; tcl_lock = PyThread_allocate_lock(); if (tcl_lock == NULL) @@ -3207,17 +3197,11 @@ PyInit__tkinter(void) if (m == NULL) return NULL; - o = PyErr_NewException("_tkinter.TclError", NULL, NULL); - if (o == NULL) { + Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL); + if (PyModule_AddObjectRef(m, "TclError", Tkinter_TclError)) { Py_DECREF(m); return NULL; } - if (PyModule_AddObject(m, "TclError", Py_NewRef(o))) { - Py_DECREF(o); - Py_DECREF(m); - return NULL; - } - Tkinter_TclError = o; if (PyModule_AddIntConstant(m, "READABLE", TCL_READABLE)) { Py_DECREF(m); @@ -3264,41 +3248,23 @@ PyInit__tkinter(void) return NULL; } - o = PyType_FromSpec(&Tkapp_Type_spec); - if (o == NULL) { + Tkapp_Type = PyType_FromSpec(&Tkapp_Type_spec); + if (PyModule_AddObjectRef(m, "TkappType", Tkapp_Type)) { Py_DECREF(m); return NULL; } - if (PyModule_AddObject(m, "TkappType", o)) { - Py_DECREF(o); - Py_DECREF(m); - return NULL; - } - Tkapp_Type = o; - o = PyType_FromSpec(&Tktt_Type_spec); - if (o == NULL) { - Py_DECREF(m); - return NULL; - } - if (PyModule_AddObject(m, "TkttType", o)) { - Py_DECREF(o); + Tktt_Type = PyType_FromSpec(&Tktt_Type_spec); + if (PyModule_AddObjectRef(m, "TkttType", Tktt_Type)) { Py_DECREF(m); return NULL; } - Tktt_Type = o; - o = PyType_FromSpec(&PyTclObject_Type_spec); - if (o == NULL) { - Py_DECREF(m); - return NULL; - } - if (PyModule_AddObject(m, "Tcl_Obj", o)) { - Py_DECREF(o); + PyTclObject_Type = PyType_FromSpec(&PyTclObject_Type_spec); + if (PyModule_AddObjectRef(m, "Tcl_Obj", PyTclObject_Type)) { Py_DECREF(m); return NULL; } - PyTclObject_Type = o; /* This helps the dynamic loader; in Unicode aware Tcl versions diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index f3f4af9aba08c1..6dba3cac01c1c8 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_tracemalloc.h" // _PyTraceMalloc_IsTracing #include "clinic/_tracemalloc.c.h" diff --git a/Modules/_typingmodule.c b/Modules/_typingmodule.c index 59d3a80a9305db..9ea72bf89ce0b2 100644 --- a/Modules/_typingmodule.c +++ b/Modules/_typingmodule.c @@ -40,7 +40,7 @@ static PyMethodDef typing_methods[] = { }; PyDoc_STRVAR(typing_doc, -"Accelerators for the typing module.\n"); +"Primitives and accelerators for the typing module.\n"); static int _typing_exec(PyObject *m) diff --git a/Modules/_weakref.c b/Modules/_weakref.c index b5d80cbd731a28..4e2862e7467c3d 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_dict.h" // _PyDict_DelItemIf() #include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR #include "pycore_weakref.h" // _PyWeakref_IS_DEAD() @@ -143,27 +144,19 @@ weakref_functions[] = { static int weakref_exec(PyObject *module) { - Py_INCREF(&_PyWeakref_RefType); - if (PyModule_AddObject(module, "ref", (PyObject *) &_PyWeakref_RefType) < 0) { - Py_DECREF(&_PyWeakref_RefType); + if (PyModule_AddObjectRef(module, "ref", (PyObject *) &_PyWeakref_RefType) < 0) { return -1; } - Py_INCREF(&_PyWeakref_RefType); - if (PyModule_AddObject(module, "ReferenceType", + if (PyModule_AddObjectRef(module, "ReferenceType", (PyObject *) &_PyWeakref_RefType) < 0) { - Py_DECREF(&_PyWeakref_RefType); return -1; } - Py_INCREF(&_PyWeakref_ProxyType); - if (PyModule_AddObject(module, "ProxyType", + if (PyModule_AddObjectRef(module, "ProxyType", (PyObject *) &_PyWeakref_ProxyType) < 0) { - Py_DECREF(&_PyWeakref_ProxyType); return -1; } - Py_INCREF(&_PyWeakref_CallableProxyType); - if (PyModule_AddObject(module, "CallableProxyType", + if (PyModule_AddObjectRef(module, "CallableProxyType", (PyObject *) &_PyWeakref_CallableProxyType) < 0) { - Py_DECREF(&_PyWeakref_CallableProxyType); return -1; } diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 313c12a34c6725..eec33499b983fe 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -38,7 +38,7 @@ #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_pystate.h" // _PyInterpreterState_GET -#include "structmember.h" // PyMemberDef + #ifndef WINDOWS_LEAN_AND_MEAN @@ -54,13 +54,13 @@ PyLong_FromUnsignedLong((unsigned long) handle) #define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLong(obj)) #define F_POINTER "k" -#define T_POINTER T_ULONG +#define T_POINTER Py_T_ULONG #else #define HANDLE_TO_PYNUM(handle) \ PyLong_FromUnsignedLongLong((unsigned long long) handle) #define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLongLong(obj)) #define F_POINTER "K" -#define T_POINTER T_ULONGLONG +#define T_POINTER Py_T_ULONGLONG #endif #define F_HANDLE F_POINTER @@ -322,7 +322,7 @@ static PyMethodDef overlapped_methods[] = { static PyMemberDef overlapped_members[] = { {"event", T_HANDLE, offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent), - READONLY, "overlapped event handle"}, + Py_READONLY, "overlapped event handle"}, {NULL} }; @@ -1539,40 +1539,56 @@ _winapi.LCMapStringEx locale: LPCWSTR flags: DWORD - src: LPCWSTR + src: unicode [clinic start generated code]*/ static PyObject * _winapi_LCMapStringEx_impl(PyObject *module, LPCWSTR locale, DWORD flags, - LPCWSTR src) -/*[clinic end generated code: output=cf4713d80e2b47c9 input=9fe26f95d5ab0001]*/ + PyObject *src) +/*[clinic end generated code: output=b90e6b26e028ff0a input=3e3dcd9b8164012f]*/ { if (flags & (LCMAP_SORTHANDLE | LCMAP_HASH | LCMAP_BYTEREV | LCMAP_SORTKEY)) { return PyErr_Format(PyExc_ValueError, "unsupported flags"); } - int dest_size = LCMapStringEx(locale, flags, src, -1, NULL, 0, + Py_ssize_t src_size; + wchar_t *src_ = PyUnicode_AsWideCharString(src, &src_size); + if (!src_) { + return NULL; + } + if (src_size > INT_MAX) { + PyMem_Free(src_); + PyErr_SetString(PyExc_OverflowError, "input string is too long"); + return NULL; + } + + int dest_size = LCMapStringEx(locale, flags, src_, (int)src_size, NULL, 0, NULL, NULL, 0); - if (dest_size == 0) { - return PyErr_SetFromWindowsErr(0); + if (dest_size <= 0) { + DWORD error = GetLastError(); + PyMem_Free(src_); + return PyErr_SetFromWindowsErr(error); } wchar_t* dest = PyMem_NEW(wchar_t, dest_size); if (dest == NULL) { + PyMem_Free(src_); return PyErr_NoMemory(); } - int nmapped = LCMapStringEx(locale, flags, src, -1, dest, dest_size, + int nmapped = LCMapStringEx(locale, flags, src_, (int)src_size, dest, dest_size, NULL, NULL, 0); - if (nmapped == 0) { + if (nmapped <= 0) { DWORD error = GetLastError(); + PyMem_Free(src_); PyMem_DEL(dest); return PyErr_SetFromWindowsErr(error); } - PyObject *ret = PyUnicode_FromWideChar(dest, dest_size - 1); + PyMem_Free(src_); + PyObject *ret = PyUnicode_FromWideChar(dest, nmapped); PyMem_DEL(dest); return ret; diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index 82472555ec7d62..bc8cd0e2cff4c1 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -7,7 +7,8 @@ #include "Python.h" #include "interpreteridobject.h" -#include "pycore_atexit.h" // _Py_AtExit() +#include "pycore_pybuffer.h" // _PyBuffer_ReleaseInInterpreterAndRawFree() +#include "pycore_interp.h" // _PyInterpreterState_LookUpID() /* @@ -81,6 +82,73 @@ API.. The module does not create any objects that are shared globally. PyMem_RawFree(VAR) +struct xid_class_registry { + size_t count; +#define MAX_XID_CLASSES 5 + struct { + PyTypeObject *cls; + } added[MAX_XID_CLASSES]; +}; + +static int +register_xid_class(PyTypeObject *cls, crossinterpdatafunc shared, + struct xid_class_registry *classes) +{ + int res = _PyCrossInterpreterData_RegisterClass(cls, shared); + if (res == 0) { + assert(classes->count < MAX_XID_CLASSES); + // The class has refs elsewhere, so we need to incref here. + classes->added[classes->count].cls = cls; + classes->count += 1; + } + return res; +} + +static void +clear_xid_class_registry(struct xid_class_registry *classes) +{ + while (classes->count > 0) { + classes->count -= 1; + PyTypeObject *cls = classes->added[classes->count].cls; + _PyCrossInterpreterData_UnregisterClass(cls); + } +} + +#define XID_IGNORE_EXC 1 +#define XID_FREE 2 + +static int +_release_xid_data(_PyCrossInterpreterData *data, int flags) +{ + int ignoreexc = flags & XID_IGNORE_EXC; + PyObject *exc; + if (ignoreexc) { + exc = PyErr_GetRaisedException(); + } + int res; + if (flags & XID_FREE) { + res = _PyCrossInterpreterData_ReleaseAndRawFree(data); + } + else { + res = _PyCrossInterpreterData_Release(data); + } + if (res < 0) { + /* The owning interpreter is already destroyed. */ + if (ignoreexc) { + // XXX Emit a warning? + PyErr_Clear(); + } + } + if (flags & XID_FREE) { + /* Either way, we free the data. */ + } + if (ignoreexc) { + PyErr_SetRaisedException(exc); + } + return res; +} + + static PyInterpreterState * _get_current_interp(void) { @@ -128,7 +196,7 @@ get_module_from_type(PyTypeObject *cls) static PyObject * add_new_exception(PyObject *mod, const char *name, PyObject *base) { - assert(!PyObject_HasAttrString(mod, name)); + assert(!PyObject_HasAttrStringWithError(mod, name)); PyObject *exctype = PyErr_NewException(name, base, NULL); if (exctype == NULL) { return NULL; @@ -145,7 +213,8 @@ add_new_exception(PyObject *mod, const char *name, PyObject *base) add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE) static PyTypeObject * -add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared) +add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared, + struct xid_class_registry *classes) { PyTypeObject *cls = (PyTypeObject *)PyType_FromMetaclass( NULL, mod, spec, NULL); @@ -157,7 +226,7 @@ add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared) return NULL; } if (shared != NULL) { - if (_PyCrossInterpreterData_RegisterClass(cls, shared)) { + if (register_xid_class(cls, shared, classes)) { Py_DECREF(cls); return NULL; } @@ -165,33 +234,160 @@ add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared) return cls; } +static void +wait_for_lock(PyThread_type_lock mutex) +{ + Py_BEGIN_ALLOW_THREADS + // XXX Handle eintr, etc. + PyThread_acquire_lock(mutex, WAIT_LOCK); + Py_END_ALLOW_THREADS + + PyThread_release_lock(mutex); +} + + +/* Cross-interpreter Buffer Views *******************************************/ + +// XXX Release when the original interpreter is destroyed. + +typedef struct { + PyObject_HEAD + Py_buffer *view; + int64_t interp; +} XIBufferViewObject; + +static PyObject * +xibufferview_from_xid(PyTypeObject *cls, _PyCrossInterpreterData *data) +{ + assert(data->data != NULL); + assert(data->obj == NULL); + assert(data->interp >= 0); + XIBufferViewObject *self = PyObject_Malloc(sizeof(XIBufferViewObject)); + if (self == NULL) { + return NULL; + } + PyObject_Init((PyObject *)self, cls); + self->view = (Py_buffer *)data->data; + self->interp = data->interp; + return (PyObject *)self; +} + +static void +xibufferview_dealloc(XIBufferViewObject *self) +{ + PyInterpreterState *interp = _PyInterpreterState_LookUpID(self->interp); + /* If the interpreter is no longer alive then we have problems, + since other objects may be using the buffer still. */ + assert(interp != NULL); + + if (_PyBuffer_ReleaseInInterpreterAndRawFree(interp, self->view) < 0) { + // XXX Emit a warning? + PyErr_Clear(); + } + + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + /* "Instances of heap-allocated types hold a reference to their type." + * See: https://docs.python.org/3.11/howto/isolating-extensions.html#garbage-collection-protocol + * See: https://docs.python.org/3.11/c-api/typeobj.html#c.PyTypeObject.tp_traverse + */ + // XXX Why don't we implement Py_TPFLAGS_HAVE_GC, e.g. Py_tp_traverse, + // like we do for _abc._abc_data? + Py_DECREF(tp); +} + static int -_release_xid_data(_PyCrossInterpreterData *data, int ignoreexc) +xibufferview_getbuf(XIBufferViewObject *self, Py_buffer *view, int flags) +{ + /* Only PyMemoryView_FromObject() should ever call this, + via _memoryview_from_xid() below. */ + *view = *self->view; + view->obj = (PyObject *)self; + // XXX Should we leave it alone? + view->internal = NULL; + return 0; +} + +static PyType_Slot XIBufferViewType_slots[] = { + {Py_tp_dealloc, (destructor)xibufferview_dealloc}, + {Py_bf_getbuffer, (getbufferproc)xibufferview_getbuf}, + // We don't bother with Py_bf_releasebuffer since we don't need it. + {0, NULL}, +}; + +static PyType_Spec XIBufferViewType_spec = { + .name = MODULE_NAME ".CrossInterpreterBufferView", + .basicsize = sizeof(XIBufferViewObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = XIBufferViewType_slots, +}; + + +/* extra XID types **********************************************************/ + +static PyTypeObject * _get_current_xibufferview_type(void); + +static PyObject * +_memoryview_from_xid(_PyCrossInterpreterData *data) { - PyObject *exc; - if (ignoreexc) { - exc = PyErr_GetRaisedException(); + PyTypeObject *cls = _get_current_xibufferview_type(); + if (cls == NULL) { + return NULL; } - int res = _PyCrossInterpreterData_Release(data); - if (res < 0) { - /* The owning interpreter is already destroyed. */ - if (ignoreexc) { - // XXX Emit a warning? - PyErr_Clear(); - } + PyObject *obj = xibufferview_from_xid(cls, data); + if (obj == NULL) { + return NULL; } - if (ignoreexc) { - PyErr_SetRaisedException(exc); + return PyMemoryView_FromObject(obj); +} + +static int +_memoryview_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + Py_buffer *view = PyMem_RawMalloc(sizeof(Py_buffer)); + if (view == NULL) { + return -1; } - return res; + if (PyObject_GetBuffer(obj, view, PyBUF_FULL_RO) < 0) { + PyMem_RawFree(view); + return -1; + } + _PyCrossInterpreterData_Init(data, tstate->interp, view, NULL, + _memoryview_from_xid); + return 0; +} + +static int +register_builtin_xid_types(struct xid_class_registry *classes) +{ + PyTypeObject *cls; + crossinterpdatafunc func; + + // builtin memoryview + cls = &PyMemoryView_Type; + func = _memoryview_shared; + if (register_xid_class(cls, func, classes)) { + return -1; + } + + return 0; } /* module state *************************************************************/ typedef struct { + struct xid_class_registry xid_classes; + + /* Added at runtime by interpreters module. */ + PyTypeObject *send_channel_type; + PyTypeObject *recv_channel_type; + /* heap types */ PyTypeObject *ChannelIDType; + PyTypeObject *XIBufferViewType; /* exceptions */ PyObject *ChannelError; @@ -210,11 +406,27 @@ get_module_state(PyObject *mod) return state; } +static module_state * +_get_current_module_state(void) +{ + PyObject *mod = _get_current_module(); + if (mod == NULL) { + // XXX import it? + PyErr_SetString(PyExc_RuntimeError, + MODULE_NAME " module not imported yet"); + return NULL; + } + module_state *state = get_module_state(mod); + Py_DECREF(mod); + return state; +} + static int traverse_module_state(module_state *state, visitproc visit, void *arg) { /* heap types */ Py_VISIT(state->ChannelIDType); + Py_VISIT(state->XIBufferViewType); /* exceptions */ Py_VISIT(state->ChannelError); @@ -229,11 +441,15 @@ traverse_module_state(module_state *state, visitproc visit, void *arg) static int clear_module_state(module_state *state) { + Py_CLEAR(state->send_channel_type); + Py_CLEAR(state->recv_channel_type); + /* heap types */ if (state->ChannelIDType != NULL) { (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType); } Py_CLEAR(state->ChannelIDType); + Py_CLEAR(state->XIBufferViewType); /* exceptions */ Py_CLEAR(state->ChannelError); @@ -246,6 +462,17 @@ clear_module_state(module_state *state) } +static PyTypeObject * +_get_current_xibufferview_type(void) +{ + module_state *state = _get_current_module_state(); + if (state == NULL) { + return NULL; + } + return state->XIBufferViewType; +} + + /* channel-specific code ****************************************************/ #define CHANNEL_SEND 1 @@ -351,6 +578,7 @@ struct _channelitem; typedef struct _channelitem { _PyCrossInterpreterData *data; + PyThread_type_lock recv_mutex; struct _channelitem *next; } _channelitem; @@ -371,9 +599,8 @@ static void _channelitem_clear(_channelitem *item) { if (item->data != NULL) { - (void)_release_xid_data(item->data, 1); // It was allocated in _channel_send(). - GLOBAL_FREE(item->data); + (void)_release_xid_data(item->data, XID_IGNORE_EXC & XID_FREE); item->data = NULL; } item->next = NULL; @@ -397,10 +624,11 @@ _channelitem_free_all(_channelitem *item) } static _PyCrossInterpreterData * -_channelitem_popped(_channelitem *item) +_channelitem_popped(_channelitem *item, PyThread_type_lock *recv_mutex) { _PyCrossInterpreterData *data = item->data; item->data = NULL; + *recv_mutex = item->recv_mutex; _channelitem_free(item); return data; } @@ -442,13 +670,15 @@ _channelqueue_free(_channelqueue *queue) } static int -_channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data) +_channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data, + PyThread_type_lock recv_mutex) { _channelitem *item = _channelitem_new(); if (item == NULL) { return -1; } item->data = data; + item->recv_mutex = recv_mutex; queue->count += 1; if (queue->first == NULL) { @@ -462,7 +692,7 @@ _channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data) } static _PyCrossInterpreterData * -_channelqueue_get(_channelqueue *queue) +_channelqueue_get(_channelqueue *queue, PyThread_type_lock *recv_mutex) { _channelitem *item = queue->first; if (item == NULL) { @@ -474,7 +704,7 @@ _channelqueue_get(_channelqueue *queue) } queue->count -= 1; - return _channelitem_popped(item); + return _channelitem_popped(item, recv_mutex); } static void @@ -791,7 +1021,7 @@ _channel_free(_PyChannelState *chan) static int _channel_add(_PyChannelState *chan, int64_t interp, - _PyCrossInterpreterData *data) + _PyCrossInterpreterData *data, PyThread_type_lock recv_mutex) { int res = -1; PyThread_acquire_lock(chan->mutex, WAIT_LOCK); @@ -805,7 +1035,7 @@ _channel_add(_PyChannelState *chan, int64_t interp, goto done; } - if (_channelqueue_put(chan->queue, data) != 0) { + if (_channelqueue_put(chan->queue, data, recv_mutex) != 0) { goto done; } @@ -831,12 +1061,17 @@ _channel_next(_PyChannelState *chan, int64_t interp, goto done; } - _PyCrossInterpreterData *data = _channelqueue_get(chan->queue); + PyThread_type_lock recv_mutex = NULL; + _PyCrossInterpreterData *data = _channelqueue_get(chan->queue, &recv_mutex); if (data == NULL && !PyErr_Occurred() && chan->closing != NULL) { chan->open = 0; } *res = data; + if (recv_mutex != NULL) { + PyThread_release_lock(recv_mutex); + } + done: PyThread_release_lock(chan->mutex); if (chan->queue->count == 0) { @@ -1356,7 +1591,8 @@ _channel_destroy(_channels *channels, int64_t id) } static int -_channel_send(_channels *channels, int64_t id, PyObject *obj) +_channel_send(_channels *channels, int64_t id, PyObject *obj, + PyThread_type_lock recv_mutex) { PyInterpreterState *interp = _get_current_interp(); if (interp == NULL) { @@ -1391,7 +1627,8 @@ _channel_send(_channels *channels, int64_t id, PyObject *obj) } // Add the data to the channel. - int res = _channel_add(chan, PyInterpreterState_GetID(interp), data); + int res = _channel_add(chan, PyInterpreterState_GetID(interp), data, + recv_mutex); PyThread_release_lock(mutex); if (res != 0) { // We may chain an exception here: @@ -1444,14 +1681,12 @@ _channel_recv(_channels *channels, int64_t id, PyObject **res) PyObject *obj = _PyCrossInterpreterData_NewObject(data); if (obj == NULL) { assert(PyErr_Occurred()); - (void)_release_xid_data(data, 1); - // It was allocated in _channel_send(). - GLOBAL_FREE(data); + // It was allocated in _channel_send(), so we free it. + (void)_release_xid_data(data, XID_IGNORE_EXC | XID_FREE); return -1; } - int release_res = _release_xid_data(data, 0); - // It was allocated in _channel_send(). - GLOBAL_FREE(data); + // It was allocated in _channel_send(), so we free it. + int release_res = _release_xid_data(data, XID_FREE); if (release_res < 0) { // The source interpreter has been destroyed already. assert(PyErr_Occurred()); @@ -1524,17 +1759,20 @@ typedef struct channelid { struct channel_id_converter_data { PyObject *module; int64_t cid; + int end; }; static int channel_id_converter(PyObject *arg, void *ptr) { int64_t cid; + int end = 0; struct channel_id_converter_data *data = ptr; module_state *state = get_module_state(data->module); assert(state != NULL); if (PyObject_TypeCheck(arg, state->ChannelIDType)) { cid = ((channelid *)arg)->id; + end = ((channelid *)arg)->end; } else if (PyIndex_Check(arg)) { cid = PyLong_AsLongLong(arg); @@ -1554,6 +1792,7 @@ channel_id_converter(PyObject *arg, void *ptr) return 0; } data->cid = cid; + data->end = end; return 1; } @@ -1595,6 +1834,7 @@ _channelid_new(PyObject *mod, PyTypeObject *cls, { static char *kwlist[] = {"id", "send", "recv", "force", "_resolve", NULL}; int64_t cid; + int end; struct channel_id_converter_data cid_data = { .module = mod, }; @@ -1609,6 +1849,7 @@ _channelid_new(PyObject *mod, PyTypeObject *cls, return NULL; } cid = cid_data.cid; + end = cid_data.end; // Handle "send" and "recv". if (send == 0 && recv == 0) { @@ -1616,14 +1857,17 @@ _channelid_new(PyObject *mod, PyTypeObject *cls, "'send' and 'recv' cannot both be False"); return NULL; } - - int end = 0; - if (send == 1) { + else if (send == 1) { if (recv == 0 || recv == -1) { end = CHANNEL_SEND; } + else { + assert(recv == 1); + end = 0; + } } else if (recv == 1) { + assert(send == 0 || send == -1); end = CHANNEL_RECV; } @@ -1768,21 +2012,12 @@ channelid_richcompare(PyObject *self, PyObject *other, int op) return res; } +static PyTypeObject * _get_current_channel_end_type(int end); + static PyObject * _channel_from_cid(PyObject *cid, int end) { - PyObject *highlevel = PyImport_ImportModule("interpreters"); - if (highlevel == NULL) { - PyErr_Clear(); - highlevel = PyImport_ImportModule("test.support.interpreters"); - if (highlevel == NULL) { - return NULL; - } - } - const char *clsname = (end == CHANNEL_RECV) ? "RecvChannel" : - "SendChannel"; - PyObject *cls = PyObject_GetAttrString(highlevel, clsname); - Py_DECREF(highlevel); + PyObject *cls = (PyObject *)_get_current_channel_end_type(end); if (cls == NULL) { return NULL; } @@ -1938,6 +2173,108 @@ static PyType_Spec ChannelIDType_spec = { }; +/* SendChannel and RecvChannel classes */ + +// XXX Use a new __xid__ protocol instead? + +static PyTypeObject * +_get_current_channel_end_type(int end) +{ + module_state *state = _get_current_module_state(); + if (state == NULL) { + return NULL; + } + PyTypeObject *cls; + if (end == CHANNEL_SEND) { + cls = state->send_channel_type; + } + else { + assert(end == CHANNEL_RECV); + cls = state->recv_channel_type; + } + if (cls == NULL) { + PyObject *highlevel = PyImport_ImportModule("interpreters"); + if (highlevel == NULL) { + PyErr_Clear(); + highlevel = PyImport_ImportModule("test.support.interpreters"); + if (highlevel == NULL) { + return NULL; + } + } + Py_DECREF(highlevel); + if (end == CHANNEL_SEND) { + cls = state->send_channel_type; + } + else { + cls = state->recv_channel_type; + } + assert(cls != NULL); + } + return cls; +} + +static PyObject * +_channel_end_from_xid(_PyCrossInterpreterData *data) +{ + channelid *cid = (channelid *)_channelid_from_xid(data); + if (cid == NULL) { + return NULL; + } + PyTypeObject *cls = _get_current_channel_end_type(cid->end); + if (cls == NULL) { + Py_DECREF(cid); + return NULL; + } + PyObject *obj = PyObject_CallOneArg((PyObject *)cls, (PyObject *)cid); + Py_DECREF(cid); + return obj; +} + +static int +_channel_end_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + PyObject *cidobj = PyObject_GetAttrString(obj, "_id"); + if (cidobj == NULL) { + return -1; + } + int res = _channelid_shared(tstate, cidobj, data); + Py_DECREF(cidobj); + if (res < 0) { + return -1; + } + data->new_object = _channel_end_from_xid; + return 0; +} + +static int +set_channel_end_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv) +{ + module_state *state = get_module_state(mod); + if (state == NULL) { + return -1; + } + struct xid_class_registry *xid_classes = &state->xid_classes; + + if (state->send_channel_type != NULL + || state->recv_channel_type != NULL) + { + PyErr_SetString(PyExc_TypeError, "already registered"); + return -1; + } + state->send_channel_type = (PyTypeObject *)Py_NewRef(send); + state->recv_channel_type = (PyTypeObject *)Py_NewRef(recv); + + if (register_xid_class(send, _channel_end_shared, xid_classes)) { + return -1; + } + if (register_xid_class(recv, _channel_end_shared, xid_classes)) { + return -1; + } + + return 0; +} + /* module level code ********************************************************/ /* globals is the process-global state for the module. It holds all @@ -2140,7 +2477,7 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) goto except; } if (res) { - id_obj = _PyInterpreterState_GetIDObject(interp); + id_obj = PyInterpreterState_GetIDObject(interp); if (id_obj == NULL) { goto except; } @@ -2174,29 +2511,116 @@ receive end."); static PyObject * channel_send(PyObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"cid", "obj", NULL}; + // XXX Add a timeout arg. + static char *kwlist[] = {"cid", "obj", "blocking", NULL}; int64_t cid; struct channel_id_converter_data cid_data = { .module = self, }; PyObject *obj; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O:channel_send", kwlist, - channel_id_converter, &cid_data, &obj)) { + int blocking = 1; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|$p:channel_send", kwlist, + channel_id_converter, &cid_data, &obj, + &blocking)) { return NULL; } cid = cid_data.cid; - int err = _channel_send(&_globals.channels, cid, obj); - if (handle_channel_error(err, self, cid)) { - return NULL; + if (blocking) { + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + PyErr_NoMemory(); + return NULL; + } + PyThread_acquire_lock(mutex, WAIT_LOCK); + + /* Queue up the object. */ + int err = _channel_send(&_globals.channels, cid, obj, mutex); + if (handle_channel_error(err, self, cid)) { + PyThread_release_lock(mutex); + return NULL; + } + + /* Wait until the object is received. */ + wait_for_lock(mutex); + } + else { + /* Queue up the object. */ + int err = _channel_send(&_globals.channels, cid, obj, NULL); + if (handle_channel_error(err, self, cid)) { + return NULL; + } } + Py_RETURN_NONE; } PyDoc_STRVAR(channel_send_doc, -"channel_send(cid, obj)\n\ +"channel_send(cid, obj, blocking=True)\n\ \n\ -Add the object's data to the channel's queue."); +Add the object's data to the channel's queue.\n\ +By default this waits for the object to be received."); + +static PyObject * +channel_send_buffer(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "obj", "blocking", NULL}; + int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; + PyObject *obj; + int blocking = 1; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&O|$p:channel_send_buffer", kwlist, + channel_id_converter, &cid_data, &obj, + &blocking)) { + return NULL; + } + cid = cid_data.cid; + + PyObject *tempobj = PyMemoryView_FromObject(obj); + if (tempobj == NULL) { + return NULL; + } + + if (blocking) { + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + Py_DECREF(tempobj); + PyErr_NoMemory(); + return NULL; + } + PyThread_acquire_lock(mutex, WAIT_LOCK); + + /* Queue up the buffer. */ + int err = _channel_send(&_globals.channels, cid, tempobj, mutex); + Py_DECREF(tempobj); + if (handle_channel_error(err, self, cid)) { + PyThread_acquire_lock(mutex, WAIT_LOCK); + return NULL; + } + + /* Wait until the buffer is received. */ + wait_for_lock(mutex); + } + else { + /* Queue up the buffer. */ + int err = _channel_send(&_globals.channels, cid, tempobj, NULL); + Py_DECREF(tempobj); + if (handle_channel_error(err, self, cid)) { + return NULL; + } + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_send_buffer_doc, +"channel_send_buffer(cid, obj, blocking=True)\n\ +\n\ +Add the object's buffer to the channel's queue.\n\ +By default this waits for the object to be received."); static PyObject * channel_recv(PyObject *self, PyObject *args, PyObject *kwds) @@ -2341,13 +2765,41 @@ channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } PyTypeObject *cls = state->ChannelIDType; + PyObject *mod = get_module_from_owned_type(cls); - if (mod == NULL) { + assert(mod == self); + Py_DECREF(mod); + + return _channelid_new(self, cls, args, kwds); +} + +static PyObject * +channel__register_end_types(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"send", "recv", NULL}; + PyObject *send; + PyObject *recv; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "OO:_register_end_types", kwlist, + &send, &recv)) { return NULL; } - PyObject *cid = _channelid_new(mod, cls, args, kwds); - Py_DECREF(mod); - return cid; + if (!PyType_Check(send)) { + PyErr_SetString(PyExc_TypeError, "expected a type for 'send'"); + return NULL; + } + if (!PyType_Check(recv)) { + PyErr_SetString(PyExc_TypeError, "expected a type for 'recv'"); + return NULL; + } + PyTypeObject *cls_send = (PyTypeObject *)send; + PyTypeObject *cls_recv = (PyTypeObject *)recv; + + if (set_channel_end_types(self, cls_send, cls_recv) < 0) { + return NULL; + } + + Py_RETURN_NONE; } static PyMethodDef module_functions[] = { @@ -2361,6 +2813,8 @@ static PyMethodDef module_functions[] = { METH_VARARGS | METH_KEYWORDS, channel_list_interpreters_doc}, {"send", _PyCFunction_CAST(channel_send), METH_VARARGS | METH_KEYWORDS, channel_send_doc}, + {"send_buffer", _PyCFunction_CAST(channel_send_buffer), + METH_VARARGS | METH_KEYWORDS, channel_send_buffer_doc}, {"recv", _PyCFunction_CAST(channel_recv), METH_VARARGS | METH_KEYWORDS, channel_recv_doc}, {"close", _PyCFunction_CAST(channel_close), @@ -2369,6 +2823,8 @@ static PyMethodDef module_functions[] = { METH_VARARGS | METH_KEYWORDS, channel_release_doc}, {"_channel_id", _PyCFunction_CAST(channel__channel_id), METH_VARARGS | METH_KEYWORDS, NULL}, + {"_register_end_types", _PyCFunction_CAST(channel__register_end_types), + METH_VARARGS | METH_KEYWORDS, NULL}, {NULL, NULL} /* sentinel */ }; @@ -2386,6 +2842,13 @@ module_exec(PyObject *mod) if (_globals_init() != 0) { return -1; } + struct xid_class_registry *xid_classes = NULL; + + module_state *state = get_module_state(mod); + if (state == NULL) { + goto error; + } + xid_classes = &state->xid_classes; /* Add exception types */ if (exceptions_init(mod) != 0) { @@ -2393,25 +2856,34 @@ module_exec(PyObject *mod) } /* Add other types */ - module_state *state = get_module_state(mod); - if (state == NULL) { - goto error; - } // ChannelID state->ChannelIDType = add_new_type( - mod, &ChannelIDType_spec, _channelid_shared); + mod, &ChannelIDType_spec, _channelid_shared, xid_classes); if (state->ChannelIDType == NULL) { goto error; } - // Make sure chnnels drop objects owned by this interpreter + state->XIBufferViewType = add_new_type(mod, &XIBufferViewType_spec, NULL, + xid_classes); + if (state->XIBufferViewType == NULL) { + goto error; + } + + if (register_builtin_xid_types(xid_classes) < 0) { + goto error; + } + + /* Make sure chnnels drop objects owned by this interpreter. */ PyInterpreterState *interp = _get_current_interp(); - _Py_AtExit(interp, clear_interpreter, (void *)interp); + PyUnstable_AtExit(interp, clear_interpreter, (void *)interp); return 0; error: + if (xid_classes != NULL) { + clear_xid_class_registry(xid_classes); + } _globals_fini(); return -1; } @@ -2436,6 +2908,11 @@ module_clear(PyObject *mod) { module_state *state = get_module_state(mod); assert(state != NULL); + + // Before clearing anything, we unregister the various XID types. */ + clear_xid_class_registry(&state->xid_classes); + + // Now we clear the module state. clear_module_state(state); return 0; } @@ -2445,7 +2922,13 @@ module_free(void *mod) { module_state *state = get_module_state(mod); assert(state != NULL); + + // Before clearing anything, we unregister the various XID types. */ + clear_xid_class_registry(&state->xid_classes); + + // Now we clear the module state. clear_module_state(state); + _globals_fini(); } diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index d2e0593872c5f0..12c98ea61fb7ac 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -6,8 +6,11 @@ #endif #include "Python.h" -#include "pycore_interp.h" // _PyInterpreterState_GetMainModule() +#include "pycore_initconfig.h" // _PyErr_SetFromPyStatus() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() +#include "pycore_pystate.h" // _PyInterpreterState_SetRunningMain() #include "interpreteridobject.h" +#include "marshal.h" // PyMarshal_ReadObjectFromString() #define MODULE_NAME "_xxsubinterpreters" @@ -40,7 +43,7 @@ _get_current_interp(void) static PyObject * add_new_exception(PyObject *mod, const char *name, PyObject *base) { - assert(!PyObject_HasAttrString(mod, name)); + assert(!PyObject_HasAttrStringWithError(mod, name)); PyObject *exctype = PyErr_NewException(name, base, NULL); if (exctype == NULL) { return NULL; @@ -57,24 +60,17 @@ add_new_exception(PyObject *mod, const char *name, PyObject *base) add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE) static int -_release_xid_data(_PyCrossInterpreterData *data, int ignoreexc) +_release_xid_data(_PyCrossInterpreterData *data) { - PyObject *exc; - if (ignoreexc) { - exc = PyErr_GetRaisedException(); - } + PyObject *exc = PyErr_GetRaisedException(); int res = _PyCrossInterpreterData_Release(data); if (res < 0) { /* The owning interpreter is already destroyed. */ _PyCrossInterpreterData_Clear(NULL, data); - if (ignoreexc) { - // XXX Emit a warning? - PyErr_Clear(); - } - } - if (ignoreexc) { - PyErr_SetRaisedException(exc); + // XXX Emit a warning? + PyErr_Clear(); } + PyErr_SetRaisedException(exc); return res; } @@ -144,7 +140,7 @@ _sharednsitem_clear(struct _sharednsitem *item) PyMem_RawFree((void *)item->name); item->name = NULL; } - (void)_release_xid_data(&item->data, 1); + (void)_release_xid_data(&item->data); } static int @@ -173,16 +169,16 @@ typedef struct _sharedns { static _sharedns * _sharedns_new(Py_ssize_t len) { - _sharedns *shared = PyMem_NEW(_sharedns, 1); + _sharedns *shared = PyMem_RawCalloc(sizeof(_sharedns), 1); if (shared == NULL) { PyErr_NoMemory(); return NULL; } shared->len = len; - shared->items = PyMem_NEW(struct _sharednsitem, len); + shared->items = PyMem_RawCalloc(sizeof(struct _sharednsitem), len); if (shared->items == NULL) { PyErr_NoMemory(); - PyMem_Free(shared); + PyMem_RawFree(shared); return NULL; } return shared; @@ -194,8 +190,8 @@ _sharedns_free(_sharedns *shared) for (Py_ssize_t i=0; i < shared->len; i++) { _sharednsitem_clear(&shared->items[i]); } - PyMem_Free(shared->items); - PyMem_Free(shared); + PyMem_RawFree(shared->items); + PyMem_RawFree(shared); } static _sharedns * @@ -247,6 +243,11 @@ _sharedns_apply(_sharedns *shared, PyObject *ns) // of the exception in the calling interpreter. typedef struct _sharedexception { + PyInterpreterState *interp; +#define ERR_NOT_SET 0 +#define ERR_NO_MEMORY 1 +#define ERR_ALREADY_RUNNING 2 + int code; const char *name; const char *msg; } _sharedexception; @@ -268,14 +269,26 @@ _sharedexception_clear(_sharedexception *exc) } static const char * -_sharedexception_bind(PyObject *exc, _sharedexception *sharedexc) +_sharedexception_bind(PyObject *exc, int code, _sharedexception *sharedexc) { + if (sharedexc->interp == NULL) { + sharedexc->interp = PyInterpreterState_Get(); + } + + if (code != ERR_NOT_SET) { + assert(exc == NULL); + assert(code > 0); + sharedexc->code = code; + return NULL; + } + assert(exc != NULL); const char *failure = NULL; PyObject *nameobj = PyUnicode_FromString(Py_TYPE(exc)->tp_name); if (nameobj == NULL) { failure = "unable to format exception type name"; + code = ERR_NO_MEMORY; goto error; } sharedexc->name = _copy_raw_string(nameobj); @@ -286,6 +299,7 @@ _sharedexception_bind(PyObject *exc, _sharedexception *sharedexc) } else { failure = "unable to encode and copy exception type name"; } + code = ERR_NO_MEMORY; goto error; } @@ -293,6 +307,7 @@ _sharedexception_bind(PyObject *exc, _sharedexception *sharedexc) PyObject *msgobj = PyUnicode_FromFormat("%S", exc); if (msgobj == NULL) { failure = "unable to format exception message"; + code = ERR_NO_MEMORY; goto error; } sharedexc->msg = _copy_raw_string(msgobj); @@ -303,6 +318,7 @@ _sharedexception_bind(PyObject *exc, _sharedexception *sharedexc) } else { failure = "unable to encode and copy exception message"; } + code = ERR_NO_MEMORY; goto error; } } @@ -313,7 +329,10 @@ _sharedexception_bind(PyObject *exc, _sharedexception *sharedexc) assert(failure != NULL); PyErr_Clear(); _sharedexception_clear(sharedexc); - *sharedexc = no_exception; + *sharedexc = (_sharedexception){ + .interp = sharedexc->interp, + .code = code, + }; return failure; } @@ -321,6 +340,7 @@ static void _sharedexception_apply(_sharedexception *exc, PyObject *wrapperclass) { if (exc->name != NULL) { + assert(exc->code == ERR_NOT_SET); if (exc->msg != NULL) { PyErr_Format(wrapperclass, "%s: %s", exc->name, exc->msg); } @@ -329,14 +349,116 @@ _sharedexception_apply(_sharedexception *exc, PyObject *wrapperclass) } } else if (exc->msg != NULL) { + assert(exc->code == ERR_NOT_SET); PyErr_SetString(wrapperclass, exc->msg); } + else if (exc->code == ERR_NO_MEMORY) { + PyErr_NoMemory(); + } + else if (exc->code == ERR_ALREADY_RUNNING) { + assert(exc->interp != NULL); + assert(_PyInterpreterState_IsRunningMain(exc->interp)); + _PyInterpreterState_FailIfRunningMain(exc->interp); + } else { + assert(exc->code == ERR_NOT_SET); PyErr_SetNone(wrapperclass); } } +/* Python code **************************************************************/ + +static const char * +check_code_str(PyUnicodeObject *text) +{ + assert(text != NULL); + if (PyUnicode_GET_LENGTH(text) == 0) { + return "too short"; + } + + // XXX Verify that it parses? + + return NULL; +} + +static const char * +check_code_object(PyCodeObject *code) +{ + assert(code != NULL); + if (code->co_argcount > 0 + || code->co_posonlyargcount > 0 + || code->co_kwonlyargcount > 0 + || code->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) + { + return "arguments not supported"; + } + if (code->co_ncellvars > 0) { + return "closures not supported"; + } + // We trust that no code objects under co_consts have unbound cell vars. + + if (code->co_executors != NULL + || code->_co_instrumentation_version > 0) + { + return "only basic functions are supported"; + } + if (code->_co_monitoring != NULL) { + return "only basic functions are supported"; + } + if (code->co_extra != NULL) { + return "only basic functions are supported"; + } + + return NULL; +} + +#define RUN_TEXT 1 +#define RUN_CODE 2 + +static const char * +get_code_str(PyObject *arg, Py_ssize_t *len_p, PyObject **bytes_p, int *flags_p) +{ + const char *codestr = NULL; + Py_ssize_t len = -1; + PyObject *bytes_obj = NULL; + int flags = 0; + + if (PyUnicode_Check(arg)) { + assert(PyUnicode_CheckExact(arg) + && (check_code_str((PyUnicodeObject *)arg) == NULL)); + codestr = PyUnicode_AsUTF8AndSize(arg, &len); + if (codestr == NULL) { + return NULL; + } + if (strlen(codestr) != (size_t)len) { + PyErr_SetString(PyExc_ValueError, + "source code string cannot contain null bytes"); + return NULL; + } + flags = RUN_TEXT; + } + else { + assert(PyCode_Check(arg) + && (check_code_object((PyCodeObject *)arg) == NULL)); + flags = RUN_CODE; + + // Serialize the code object. + bytes_obj = PyMarshal_WriteObjectToString(arg, Py_MARSHAL_VERSION); + if (bytes_obj == NULL) { + return NULL; + } + codestr = PyBytes_AS_STRING(bytes_obj); + len = PyBytes_GET_SIZE(bytes_obj); + } + + *flags_p = flags; + *bytes_p = bytes_obj; + *len_p = len; + return codestr; +} + + /* interpreter-specific code ************************************************/ static int @@ -364,43 +486,24 @@ exceptions_init(PyObject *mod) } static int -_is_running(PyInterpreterState *interp) +_run_script(PyInterpreterState *interp, + const char *codestr, Py_ssize_t codestrlen, + _sharedns *shared, _sharedexception *sharedexc, int flags) { - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - if (PyThreadState_Next(tstate) != NULL) { - PyErr_SetString(PyExc_RuntimeError, - "interpreter has more than one thread"); - return -1; - } - - assert(!PyErr_Occurred()); - struct _PyInterpreterFrame *frame = tstate->cframe->current_frame; - if (frame == NULL) { - return 0; - } - return 1; -} + int errcode = ERR_NOT_SET; -static int -_ensure_not_running(PyInterpreterState *interp) -{ - int is_running = _is_running(interp); - if (is_running < 0) { - return -1; - } - if (is_running) { - PyErr_Format(PyExc_RuntimeError, "interpreter already running"); - return -1; + if (_PyInterpreterState_SetRunningMain(interp) < 0) { + assert(PyErr_Occurred()); + // In the case where we didn't switch interpreters, it would + // be more efficient to leave the exception in place and return + // immediately. However, life is simpler if we don't. + PyErr_Clear(); + errcode = ERR_ALREADY_RUNNING; + goto error; } - return 0; -} -static int -_run_script(PyInterpreterState *interp, const char *codestr, - _sharedns *shared, _sharedexception *sharedexc) -{ PyObject *excval = NULL; - PyObject *main_mod = _PyInterpreterState_GetMainModule(interp); + PyObject *main_mod = PyUnstable_InterpreterState_GetMainModule(interp); if (main_mod == NULL) { goto error; } @@ -419,8 +522,21 @@ _run_script(PyInterpreterState *interp, const char *codestr, } } - // Run the string (see PyRun_SimpleStringFlags). - PyObject *result = PyRun_StringFlags(codestr, Py_file_input, ns, ns, NULL); + // Run the script/code/etc. + PyObject *result = NULL; + if (flags & RUN_TEXT) { + result = PyRun_StringFlags(codestr, Py_file_input, ns, ns, NULL); + } + else if (flags & RUN_CODE) { + PyObject *code = PyMarshal_ReadObjectFromString(codestr, codestrlen); + if (code != NULL) { + result = PyEval_EvalCode(code, ns, ns); + Py_DECREF(code); + } + } + else { + Py_UNREACHABLE(); + } Py_DECREF(ns); if (result == NULL) { goto error; @@ -428,32 +544,40 @@ _run_script(PyInterpreterState *interp, const char *codestr, else { Py_DECREF(result); // We throw away the result. } + _PyInterpreterState_SetNotRunningMain(interp); *sharedexc = no_exception; return 0; error: excval = PyErr_GetRaisedException(); - const char *failure = _sharedexception_bind(excval, sharedexc); + const char *failure = _sharedexception_bind(excval, errcode, sharedexc); if (failure != NULL) { fprintf(stderr, "RunFailedError: script raised an uncaught exception (%s)", failure); - PyErr_Clear(); } - Py_XDECREF(excval); + if (excval != NULL) { + // XXX Instead, store the rendered traceback on sharedexc, + // attach it to the exception when applied, + // and teach PyErr_Display() to print it. + PyErr_Display(NULL, excval, NULL); + Py_DECREF(excval); + } + if (errcode != ERR_ALREADY_RUNNING) { + _PyInterpreterState_SetNotRunningMain(interp); + } assert(!PyErr_Occurred()); return -1; } static int -_run_script_in_interpreter(PyObject *mod, PyInterpreterState *interp, - const char *codestr, PyObject *shareables) +_run_in_interpreter(PyObject *mod, PyInterpreterState *interp, + const char *codestr, Py_ssize_t codestrlen, + PyObject *shareables, int flags) { - if (_ensure_not_running(interp) < 0) { - return -1; - } module_state *state = get_module_state(mod); + assert(state != NULL); _sharedns *shared = _get_shared_ns(shareables); if (shared == NULL && PyErr_Occurred()) { @@ -462,30 +586,30 @@ _run_script_in_interpreter(PyObject *mod, PyInterpreterState *interp, // Switch to interpreter. PyThreadState *save_tstate = NULL; + PyThreadState *tstate = NULL; if (interp != PyInterpreterState_Get()) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + tstate = PyThreadState_New(interp); + tstate->_whence = _PyThreadState_WHENCE_EXEC; // XXX Possible GILState issues? save_tstate = PyThreadState_Swap(tstate); } // Run the script. - _sharedexception exc = {NULL, NULL}; - int result = _run_script(interp, codestr, shared, &exc); + _sharedexception exc = (_sharedexception){ .interp = interp }; + int result = _run_script(interp, codestr, codestrlen, shared, &exc, flags); // Switch back. if (save_tstate != NULL) { + PyThreadState_Clear(tstate); PyThreadState_Swap(save_tstate); + PyThreadState_Delete(tstate); } // Propagate any exception out to the caller. - if (exc.name != NULL) { - assert(state != NULL); + if (result < 0) { + assert(!PyErr_Occurred()); _sharedexception_apply(&exc, state->RunFailedError); - } - else if (result != 0) { - // We were unable to allocate a shared exception. - PyErr_NoMemory(); + assert(PyErr_Occurred()); } if (shared != NULL) { @@ -515,6 +639,7 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds) const PyInterpreterConfig config = isolated ? (PyInterpreterConfig)_PyInterpreterConfig_INIT : (PyInterpreterConfig)_PyInterpreterConfig_LEGACY_INIT; + // XXX Possible GILState issues? PyThreadState *tstate = NULL; PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); @@ -530,8 +655,9 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } assert(tstate != NULL); + PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate); - PyObject *idobj = _PyInterpreterState_GetIDObject(interp); + PyObject *idobj = PyInterpreterState_GetIDObject(interp); if (idobj == NULL) { // XXX Possible GILState issues? save_tstate = PyThreadState_Swap(tstate); @@ -539,6 +665,10 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds) PyThreadState_Swap(save_tstate); return NULL; } + + PyThreadState_Clear(tstate); + PyThreadState_Delete(tstate); + _PyInterpreterState_RequireIDRef(interp, 1); return idobj; } @@ -561,7 +691,7 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) } // Look up the interpreter. - PyInterpreterState *interp = _PyInterpreterID_LookUp(id); + PyInterpreterState *interp = PyInterpreterID_LookUp(id); if (interp == NULL) { return NULL; } @@ -580,12 +710,14 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) // Ensure the interpreter isn't running. /* XXX We *could* support destroying a running interpreter but aren't going to worry about it for now. */ - if (_ensure_not_running(interp) < 0) { + if (_PyInterpreterState_IsRunningMain(interp)) { + PyErr_Format(PyExc_RuntimeError, "interpreter running"); return NULL; } // Destroy the interpreter. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + PyThreadState *tstate = PyThreadState_New(interp); + tstate->_whence = _PyThreadState_WHENCE_INTERP; // XXX Possible GILState issues? PyThreadState *save_tstate = PyThreadState_Swap(tstate); Py_EndInterpreter(tstate); @@ -616,7 +748,7 @@ interp_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) interp = PyInterpreterState_Head(); while (interp != NULL) { - id = _PyInterpreterState_GetIDObject(interp); + id = PyInterpreterState_GetIDObject(interp); if (id == NULL) { Py_DECREF(ids); return NULL; @@ -648,7 +780,7 @@ interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored)) if (interp == NULL) { return NULL; } - return _PyInterpreterState_GetIDObject(interp); + return PyInterpreterState_GetIDObject(interp); } PyDoc_STRVAR(get_current_doc, @@ -662,7 +794,7 @@ interp_get_main(PyObject *self, PyObject *Py_UNUSED(ignored)) { // Currently, 0 is always the main interpreter. int64_t id = 0; - return _PyInterpreterID_New(id); + return PyInterpreterID_New(id); } PyDoc_STRVAR(get_main_doc, @@ -671,49 +803,231 @@ PyDoc_STRVAR(get_main_doc, Return the ID of main interpreter."); +static PyUnicodeObject * +convert_script_arg(PyObject *arg, const char *fname, const char *displayname, + const char *expected) +{ + PyUnicodeObject *str = NULL; + if (PyUnicode_CheckExact(arg)) { + str = (PyUnicodeObject *)Py_NewRef(arg); + } + else if (PyUnicode_Check(arg)) { + // XXX str = PyUnicode_FromObject(arg); + str = (PyUnicodeObject *)Py_NewRef(arg); + } + else { + _PyArg_BadArgument(fname, displayname, expected, arg); + return NULL; + } + + const char *err = check_code_str(str); + if (err != NULL) { + Py_DECREF(str); + PyErr_Format(PyExc_ValueError, + "%.200s(): bad script text (%s)", fname, err); + return NULL; + } + + return str; +} + +static PyCodeObject * +convert_code_arg(PyObject *arg, const char *fname, const char *displayname, + const char *expected) +{ + const char *kind = NULL; + PyCodeObject *code = NULL; + if (PyFunction_Check(arg)) { + if (PyFunction_GetClosure(arg) != NULL) { + PyErr_Format(PyExc_ValueError, + "%.200s(): closures not supported", fname); + return NULL; + } + code = (PyCodeObject *)PyFunction_GetCode(arg); + if (code == NULL) { + if (PyErr_Occurred()) { + // This chains. + PyErr_Format(PyExc_ValueError, + "%.200s(): bad func", fname); + } + else { + PyErr_Format(PyExc_ValueError, + "%.200s(): func.__code__ missing", fname); + } + return NULL; + } + Py_INCREF(code); + kind = "func"; + } + else if (PyCode_Check(arg)) { + code = (PyCodeObject *)Py_NewRef(arg); + kind = "code object"; + } + else { + _PyArg_BadArgument(fname, displayname, expected, arg); + return NULL; + } + + const char *err = check_code_object(code); + if (err != NULL) { + Py_DECREF(code); + PyErr_Format(PyExc_ValueError, + "%.200s(): bad %s (%s)", fname, kind, err); + return NULL; + } + + return code; +} + +static int +_interp_exec(PyObject *self, + PyObject *id_arg, PyObject *code_arg, PyObject *shared_arg) +{ + // Look up the interpreter. + PyInterpreterState *interp = PyInterpreterID_LookUp(id_arg); + if (interp == NULL) { + return -1; + } + + // Extract code. + Py_ssize_t codestrlen = -1; + PyObject *bytes_obj = NULL; + int flags = 0; + const char *codestr = get_code_str(code_arg, + &codestrlen, &bytes_obj, &flags); + if (codestr == NULL) { + return -1; + } + + // Run the code in the interpreter. + int res = _run_in_interpreter(self, interp, codestr, codestrlen, + shared_arg, flags); + Py_XDECREF(bytes_obj); + if (res != 0) { + return -1; + } + + return 0; +} + static PyObject * -interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) +interp_exec(PyObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"id", "script", "shared", NULL}; + static char *kwlist[] = {"id", "code", "shared", NULL}; PyObject *id, *code; PyObject *shared = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "OU|O:run_string", kwlist, + "OO|O:" MODULE_NAME ".exec", kwlist, &id, &code, &shared)) { return NULL; } - // Look up the interpreter. - PyInterpreterState *interp = _PyInterpreterID_LookUp(id); - if (interp == NULL) { + const char *expected = "a string, a function, or a code object"; + if (PyUnicode_Check(code)) { + code = (PyObject *)convert_script_arg(code, MODULE_NAME ".exec", + "argument 2", expected); + } + else { + code = (PyObject *)convert_code_arg(code, MODULE_NAME ".exec", + "argument 2", expected); + } + if (code == NULL) { return NULL; } - // Extract code. - Py_ssize_t size; - const char *codestr = PyUnicode_AsUTF8AndSize(code, &size); - if (codestr == NULL) { + int res = _interp_exec(self, id, code, shared); + Py_DECREF(code); + if (res < 0) { return NULL; } - if (strlen(codestr) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, - "source code string cannot contain null bytes"); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(exec_doc, +"exec(id, code, shared=None)\n\ +\n\ +Execute the provided code in the identified interpreter.\n\ +This is equivalent to running the builtin exec() under the target\n\ +interpreter, using the __dict__ of its __main__ module as both\n\ +globals and locals.\n\ +\n\ +\"code\" may be a string containing the text of a Python script.\n\ +\n\ +Functions (and code objects) are also supported, with some restrictions.\n\ +The code/function must not take any arguments or be a closure\n\ +(i.e. have cell vars). Methods and other callables are not supported.\n\ +\n\ +If a function is provided, its code object is used and all its state\n\ +is ignored, including its __globals__ dict."); + +static PyObject * +interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", "script", "shared", NULL}; + PyObject *id, *script; + PyObject *shared = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "OU|O:" MODULE_NAME ".run_string", kwlist, + &id, &script, &shared)) { return NULL; } - // Run the code in the interpreter. - if (_run_script_in_interpreter(self, interp, codestr, shared) != 0) { + script = (PyObject *)convert_script_arg(script, MODULE_NAME ".exec", + "argument 2", "a string"); + if (script == NULL) { + return NULL; + } + + int res = _interp_exec(self, id, (PyObject *)script, shared); + Py_DECREF(script); + if (res < 0) { return NULL; } Py_RETURN_NONE; } PyDoc_STRVAR(run_string_doc, -"run_string(id, script, shared)\n\ +"run_string(id, script, shared=None)\n\ \n\ Execute the provided string in the identified interpreter.\n\ \n\ -See PyRun_SimpleStrings."); +(See " MODULE_NAME ".exec()."); + +static PyObject * +interp_run_func(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", "func", "shared", NULL}; + PyObject *id, *func; + PyObject *shared = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "OO|O:" MODULE_NAME ".run_func", kwlist, + &id, &func, &shared)) { + return NULL; + } + + PyCodeObject *code = convert_code_arg(func, MODULE_NAME ".exec", + "argument 2", + "a function or a code object"); + if (code == NULL) { + return NULL; + } + + int res = _interp_exec(self, id, (PyObject *)code, shared); + Py_DECREF(code); + if (res < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(run_func_doc, +"run_func(id, func, shared=None)\n\ +\n\ +Execute the body of the provided function in the identified interpreter.\n\ +Code objects are also supported. In both cases, closures and args\n\ +are not supported. Methods and other callables are not supported either.\n\ +\n\ +(See " MODULE_NAME ".exec()."); static PyObject * @@ -750,15 +1064,11 @@ interp_is_running(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - PyInterpreterState *interp = _PyInterpreterID_LookUp(id); + PyInterpreterState *interp = PyInterpreterID_LookUp(id); if (interp == NULL) { return NULL; } - int is_running = _is_running(interp); - if (is_running < 0) { - return NULL; - } - if (is_running) { + if (_PyInterpreterState_IsRunningMain(interp)) { Py_RETURN_TRUE; } Py_RETURN_FALSE; @@ -769,6 +1079,7 @@ PyDoc_STRVAR(is_running_doc, \n\ Return whether or not the identified interpreter is running."); + static PyMethodDef module_functions[] = { {"create", _PyCFunction_CAST(interp_create), METH_VARARGS | METH_KEYWORDS, create_doc}, @@ -783,8 +1094,12 @@ static PyMethodDef module_functions[] = { {"is_running", _PyCFunction_CAST(interp_is_running), METH_VARARGS | METH_KEYWORDS, is_running_doc}, + {"exec", _PyCFunction_CAST(interp_exec), + METH_VARARGS | METH_KEYWORDS, exec_doc}, {"run_string", _PyCFunction_CAST(interp_run_string), METH_VARARGS | METH_KEYWORDS, run_string_doc}, + {"run_func", _PyCFunction_CAST(interp_run_func), + METH_VARARGS | METH_KEYWORDS, run_func_doc}, {"is_shareable", _PyCFunction_CAST(object_is_shareable), METH_VARARGS | METH_KEYWORDS, is_shareable_doc}, @@ -808,7 +1123,7 @@ module_exec(PyObject *mod) } // PyInterpreterID - if (PyModule_AddType(mod, &_PyInterpreterID_Type) < 0) { + if (PyModule_AddType(mod, &PyInterpreterID_Type) < 0) { goto error; } diff --git a/Modules/_xxtestfuzz/README.rst b/Modules/_xxtestfuzz/README.rst index 42bd02a03cbedd..b951858458c82f 100644 --- a/Modules/_xxtestfuzz/README.rst +++ b/Modules/_xxtestfuzz/README.rst @@ -13,6 +13,9 @@ oss-fuzz will regularly pull from CPython, discover all the tests in automatically be run in oss-fuzz, while also being smoke-tested as part of CPython's test suite. +In addition, the tests are run on GitHub Actions using CIFuzz for PRs to the +main branch changing relevant files. + Adding a new fuzz test ---------------------- diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 37d402824853f0..816ba09c8fd7de 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -10,7 +10,12 @@ See the source code for LLVMFuzzerTestOneInput for details. */ +#ifndef Py_BUILD_CORE +# define Py_BUILD_CORE 1 +#endif + #include +#include "pycore_pyhash.h" // _Py_HashBytes() #include #include @@ -188,37 +193,33 @@ static int fuzz_json_loads(const char* data, size_t size) { #define MAX_RE_TEST_SIZE 0x10000 -PyObject* sre_compile_method = NULL; -PyObject* sre_error_exception = NULL; -int SRE_FLAG_DEBUG = 0; +PyObject* re_compile_method = NULL; +PyObject* re_error_exception = NULL; +int RE_FLAG_DEBUG = 0; /* Called by LLVMFuzzerTestOneInput for initialization */ static int init_sre_compile(void) { /* Import sre_compile.compile and sre.error */ - PyObject* sre_compile_module = PyImport_ImportModule("sre_compile"); - if (sre_compile_module == NULL) { + PyObject* re_module = PyImport_ImportModule("re"); + if (re_module == NULL) { return 0; } - sre_compile_method = PyObject_GetAttrString(sre_compile_module, "compile"); - if (sre_compile_method == NULL) { + re_compile_method = PyObject_GetAttrString(re_module, "compile"); + if (re_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) { + re_error_exception = PyObject_GetAttrString(re_module, "error"); + if (re_error_exception == NULL) { return 0; } - PyObject* debug_flag = PyObject_GetAttrString(sre_constants, "SRE_FLAG_DEBUG"); + PyObject* debug_flag = PyObject_GetAttrString(re_module, "DEBUG"); if (debug_flag == NULL) { return 0; } - SRE_FLAG_DEBUG = PyLong_AsLong(debug_flag); + RE_FLAG_DEBUG = PyLong_AsLong(debug_flag); return 1; } -/* Fuzz _sre.compile(x) */ +/* Fuzz re.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) { @@ -231,7 +232,7 @@ static int fuzz_sre_compile(const char* data, size_t size) { 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; + flags &= ~RE_FLAG_DEBUG; /* Pull the pattern from the remaining bytes */ PyObject* pattern_bytes = PyBytes_FromStringAndSize(data + 2, size - 2); @@ -244,9 +245,9 @@ static int fuzz_sre_compile(const char* data, size_t size) { return 0; } - /* compiled = _sre.compile(data[2:], data[0:2] */ + /* compiled = re.compile(data[2:], data[0:2] */ PyObject* compiled = PyObject_CallFunctionObjArgs( - sre_compile_method, pattern_bytes, flags_obj, NULL); + re_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)) { @@ -262,7 +263,7 @@ static int fuzz_sre_compile(const char* data, size_t size) { PyErr_Clear(); } /* Ignore re.error */ - if (compiled == NULL && PyErr_ExceptionMatches(sre_error_exception)) { + if (compiled == NULL && PyErr_ExceptionMatches(re_error_exception)) { PyErr_Clear(); } @@ -526,13 +527,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_sre_compile) static int SRE_COMPILE_INITIALIZED = 0; if (!SRE_COMPILE_INITIALIZED && !init_sre_compile()) { - if (!PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { - PyErr_Print(); - abort(); - } - else { - PyErr_Clear(); - } + PyErr_Print(); + abort(); } else { SRE_COMPILE_INITIALIZED = 1; } diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 0ced9d08b9eb75..eb4e522465181f 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -4,13 +4,12 @@ #include "Python.h" #include "pycore_long.h" // _PyLong_GetOne() -#include "structmember.h" +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() -#include -#include -#include +#include "datetime.h" // PyDateTime_TZInfo -#include "datetime.h" +#include // offsetof() +#include #include "clinic/_zoneinfo.c.h" /*[clinic input] @@ -1701,7 +1700,7 @@ parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out) static int parse_uint(const char *const p, uint8_t *value) { - if (!isdigit(*p)) { + if (!Py_ISDIGIT(*p)) { return -1; } @@ -1732,7 +1731,7 @@ parse_abbr(const char *const p, PyObject **abbr) // '+' ) character, or the minus-sign ( '-' ) character. The std // and dst fields in this case shall not include the quoting // characters. - if (!isalpha(buff) && !isdigit(buff) && buff != '+' && + if (!Py_ISALPHA(buff) && !Py_ISDIGIT(buff) && buff != '+' && buff != '-') { return -1; } @@ -1748,7 +1747,7 @@ parse_abbr(const char *const p, PyObject **abbr) // In the unquoted form, all characters in these fields shall be // alphabetic characters from the portable character set in the // current locale. - while (isalpha(*ptr)) { + while (Py_ISALPHA(*ptr)) { ptr++; } str_end = ptr; @@ -1802,7 +1801,7 @@ parse_tz_delta(const char *const p, long *total_seconds) // The hour can be 1 or 2 numeric characters for (size_t i = 0; i < 2; ++i) { buff = *ptr; - if (!isdigit(buff)) { + if (!Py_ISDIGIT(buff)) { if (i == 0) { return -1; } @@ -1830,7 +1829,7 @@ parse_tz_delta(const char *const p, long *total_seconds) for (size_t j = 0; j < 2; ++j) { buff = *ptr; - if (!isdigit(buff)) { + if (!Py_ISDIGIT(buff)) { return -1; } *(outputs[i]) *= 10; @@ -1932,7 +1931,7 @@ parse_transition_rule(const char *const p, TransitionRuleType **out) } for (size_t i = 0; i < 3; ++i) { - if (!isdigit(*ptr)) { + if (!Py_ISDIGIT(*ptr)) { if (i == 0) { return -1; } @@ -2007,7 +2006,7 @@ parse_transition_time(const char *const p, int8_t *hour, int8_t *minute, uint8_t buff = 0; for (size_t j = 0; j < 2; j++) { - if (!isdigit(*ptr)) { + if (!Py_ISDIGIT(*ptr)) { if (i == 0 && j > 0) { break; } @@ -2692,13 +2691,13 @@ static PyMethodDef zoneinfo_methods[] = { static PyMemberDef zoneinfo_members[] = { {.name = "key", .offset = offsetof(PyZoneInfo_ZoneInfo, key), - .type = T_OBJECT_EX, - .flags = READONLY, + .type = Py_T_OBJECT_EX, + .flags = Py_READONLY, .doc = NULL}, {.name = "__weaklistoffset__", .offset = offsetof(PyZoneInfo_ZoneInfo, weakreflist), - .type = T_PYSSIZET, - .flags = READONLY}, + .type = Py_T_PYSSIZET, + .flags = Py_READONLY}, {NULL}, /* Sentinel */ }; diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 0000a8d637eb56..309a36919f3465 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -8,10 +8,12 @@ #endif #include "Python.h" +#include "pycore_bytesobject.h" // _PyBytes_Repeat #include "pycore_call.h" // _PyObject_CallMethod() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() +#include "pycore_long.h" // _PyLong_FromByteArray() #include "pycore_moduleobject.h" // _PyModule_GetState() -#include "pycore_bytesobject.h" // _PyBytes_Repeat -#include "structmember.h" // PyMemberDef + #include // offsetof() #include @@ -2895,7 +2897,7 @@ itemsize -- the length in bytes of one array item\n\ static PyObject *array_iter(arrayobject *ao); static struct PyMemberDef array_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(arrayobject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(arrayobject, weakreflist), Py_READONLY}, {NULL}, }; @@ -3163,9 +3165,8 @@ array_modexec(PyObject *m) CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec); Py_SET_TYPE(state->ArrayIterType, &PyType_Type); - if (PyModule_AddObject(m, "ArrayType", - Py_NewRef((PyObject *)state->ArrayType)) < 0) { - Py_DECREF((PyObject *)state->ArrayType); + if (PyModule_AddObjectRef(m, "ArrayType", + (PyObject *)state->ArrayType) < 0) { return -1; } @@ -3193,8 +3194,7 @@ array_modexec(PyObject *m) *p++ = (char)descr->typecode; } typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL); - if (PyModule_AddObject(m, "typecodes", typecodes) < 0) { - Py_XDECREF(typecodes); + if (PyModule_Add(m, "typecodes", typecodes) < 0) { return -1; } diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index 5882d405636400..57e2ea67450453 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -7,9 +7,10 @@ */ #include "Python.h" -#include "pycore_atexit.h" +#include "pycore_atexit.h" // export _Py_AtExit() #include "pycore_initconfig.h" // _PyStatus_NO_MEMORY #include "pycore_interp.h" // PyInterpreterState.atexit +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() #include "pycore_pystate.h" // _PyInterpreterState_GET /* ===================================================================== */ @@ -24,8 +25,8 @@ get_atexit_state(void) int -_Py_AtExit(PyInterpreterState *interp, - atexit_datacallbackfunc func, void *data) +PyUnstable_AtExit(PyInterpreterState *interp, + atexit_datacallbackfunc func, void *data) { assert(interp == _PyInterpreterState_GET()); atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback)); diff --git a/Modules/binascii.c b/Modules/binascii.c index cf9328795c2bcc..a87a2ef2e89927 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1253,32 +1253,20 @@ static struct PyMethodDef binascii_module_methods[] = { PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII"); static int -binascii_exec(PyObject *module) { - int result; +binascii_exec(PyObject *module) +{ binascii_state *state = PyModule_GetState(module); if (state == NULL) { return -1; } state->Error = PyErr_NewException("binascii.Error", PyExc_ValueError, NULL); - if (state->Error == NULL) { - return -1; - } - Py_INCREF(state->Error); - result = PyModule_AddObject(module, "Error", state->Error); - if (result == -1) { - Py_DECREF(state->Error); + if (PyModule_AddObjectRef(module, "Error", state->Error) < 0) { return -1; } state->Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL); - if (state->Incomplete == NULL) { - return -1; - } - Py_INCREF(state->Incomplete); - result = PyModule_AddObject(module, "Incomplete", state->Incomplete); - if (result == -1) { - Py_DECREF(state->Incomplete); + if (PyModule_AddObjectRef(module, "Incomplete", state->Incomplete) < 0) { return -1; } diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index ee588785e7403f..766f82983025e4 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -398,11 +398,7 @@ register_maps(PyObject *module) strcpy(mhname + sizeof("__map_") - 1, h->charset); PyObject *capsule = PyCapsule_New((void *)h, MAP_CAPSULE, NULL); - if (capsule == NULL) { - return -1; - } - if (PyModule_AddObject(module, mhname, capsule) < 0) { - Py_DECREF(capsule); + if (PyModule_Add(module, mhname, capsule) < 0) { return -1; } } diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 1b41c231eac5d8..0b73a7059eb584 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, "encode($self, /, input, errors=None)\n" "--\n" @@ -690,4 +689,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=5f0e8dacddb0ac76 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1ee928e7a85e9d34 input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 3febd1a832f9cc..7c1da9004549a6 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -9,10 +9,13 @@ #endif #include "Python.h" -#include "structmember.h" // PyMemberDef +#include "pycore_long.h" // _PyLong_FromByteArray() + #include "multibytecodec.h" #include "clinic/multibytecodec.c.h" +#include // offsetof() + #define MODULE_NAME "_multibytecodec" typedef struct { @@ -1611,9 +1614,9 @@ static struct PyMethodDef mbstreamreader_methods[] = { }; static PyMemberDef mbstreamreader_members[] = { - {"stream", T_OBJECT, + {"stream", _Py_T_OBJECT, offsetof(MultibyteStreamReaderObject, stream), - READONLY, NULL}, + Py_READONLY, NULL}, {NULL,} }; @@ -1919,9 +1922,9 @@ static struct PyMethodDef mbstreamwriter_methods[] = { }; static PyMemberDef mbstreamwriter_members[] = { - {"stream", T_OBJECT, + {"stream", _Py_T_OBJECT, offsetof(MultibyteStreamWriterObject, stream), - READONLY, NULL}, + Py_READONLY, NULL}, {NULL,} }; diff --git a/Modules/clinic/_abc.c.h b/Modules/clinic/_abc.c.h index 2adec818c91311..8d3832e1b83d2d 100644 --- a/Modules/clinic/_abc.c.h +++ b/Modules/clinic/_abc.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_abc__reset_registry__doc__, "_reset_registry($module, self, /)\n" "--\n" @@ -165,4 +159,4 @@ _abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _abc_get_cache_token_impl(module); } -/*[clinic end generated code: output=c2e69611a495c98d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=babb3ce445fa9b21 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 6a780a80cd0bc4..74dd06461e6e27 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_asyncio_Future___init____doc__, "Future(*, loop=None)\n" "--\n" @@ -1487,4 +1486,4 @@ _asyncio_current_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=6b0e283177b07639 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1b7658bfab7024f3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bisectmodule.c.h b/Modules/clinic/_bisectmodule.c.h index 7944f5219b02a3..5553b05acbf521 100644 --- a/Modules/clinic/_bisectmodule.c.h +++ b/Modules/clinic/_bisectmodule.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_bisect_bisect_right__doc__, "bisect_right($module, /, a, x, lo=0, hi=None, *, key=None)\n" @@ -433,4 +433,4 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=5a7fa64bf9b262f3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=43ece163c3e972df input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index d7797d639ae32e..29f5d3a68e06ae 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, "compress($self, data, /)\n" @@ -102,7 +102,7 @@ _bz2_BZ2Compressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (PyTuple_GET_SIZE(args) < 1) { goto skip_optional; } - compresslevel = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + compresslevel = PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); if (compresslevel == -1 && PyErr_Occurred()) { goto exit; } @@ -241,4 +241,4 @@ _bz2_BZ2Decompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=805400e4805098ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3dfc8436fa8eaefb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index 2275b6b9685276..bf9bd4a61f5ce4 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_codecs_register__doc__, "register($module, search_function, /)\n" "--\n" @@ -802,7 +801,7 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - byteorder = _PyLong_AsInt(args[2]); + byteorder = PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; } @@ -1091,7 +1090,7 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - byteorder = _PyLong_AsInt(args[2]); + byteorder = PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; } @@ -1639,7 +1638,7 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("code_page_decode", nargs, 2, 4)) { goto exit; } - codepage = _PyLong_AsInt(args[0]); + codepage = PyLong_AsInt(args[0]); if (codepage == -1 && PyErr_Occurred()) { goto exit; } @@ -1926,7 +1925,7 @@ _codecs_utf_16_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - byteorder = _PyLong_AsInt(args[2]); + byteorder = PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; } @@ -2099,7 +2098,7 @@ _codecs_utf_32_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - byteorder = _PyLong_AsInt(args[2]); + byteorder = PyLong_AsInt(args[2]); if (byteorder == -1 && PyErr_Occurred()) { goto exit; } @@ -2669,7 +2668,7 @@ _codecs_code_page_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("code_page_encode", nargs, 2, 3)) { goto exit; } - code_page = _PyLong_AsInt(args[0]); + code_page = PyLong_AsInt(args[0]); if (code_page == -1 && PyErr_Occurred()) { goto exit; } @@ -2818,4 +2817,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=0f52053d31533376 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3473564544f10403 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_collectionsmodule.c.h b/Modules/clinic/_collectionsmodule.c.h index 3882d069216e28..a375b87261ce2d 100644 --- a/Modules/clinic/_collectionsmodule.c.h +++ b/Modules/clinic/_collectionsmodule.c.h @@ -2,11 +2,7 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_collections__count_elements__doc__, "_count_elements($module, mapping, iterable, /)\n" @@ -75,4 +71,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=00e516317d2b8bed input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b01ddb9fdecc4a2d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_contextvarsmodule.c.h b/Modules/clinic/_contextvarsmodule.c.h index 461d4845635ef0..b1885e41c355d2 100644 --- a/Modules/clinic/_contextvarsmodule.c.h +++ b/Modules/clinic/_contextvarsmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_contextvars_copy_context__doc__, "copy_context($module, /)\n" "--\n" @@ -24,4 +18,4 @@ _contextvars_copy_context(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _contextvars_copy_context_impl(module); } -/*[clinic end generated code: output=1736c27450823e70 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=26e07024451baf52 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_csv.c.h b/Modules/clinic/_csv.c.h index 8900946350a524..86ed0efd79028e 100644 --- a/Modules/clinic/_csv.c.h +++ b/Modules/clinic/_csv.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_csv_list_dialects__doc__, "list_dialects($module, /)\n" "--\n" @@ -206,4 +205,4 @@ _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=94374e41eb2806ee input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4704d708f5745e91 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index bb6cc90f0438c0..a8c32c6aa3fc10 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "bottom($self, /)\n" "--\n" @@ -190,11 +184,11 @@ _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject if (!args) { goto exit; } - y = _PyLong_AsInt(args[0]); + y = PyLong_AsInt(args[0]); if (y == -1 && PyErr_Occurred()) { goto exit; } - x = _PyLong_AsInt(args[1]); + x = PyLong_AsInt(args[1]); if (x == -1 && PyErr_Occurred()) { goto exit; } @@ -422,4 +416,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=8d0533681891523c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd302cb9afc42f40 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 9d99d41af5d2d9..ecc3c059d03c90 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_curses_window_addch__doc__, "addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" "Paint the character.\n" @@ -708,11 +707,11 @@ _curses_window_enclose(PyCursesWindowObject *self, PyObject *const *args, Py_ssi if (!_PyArg_CheckPositional("enclose", nargs, 2, 2)) { goto exit; } - y = _PyLong_AsInt(args[0]); + y = PyLong_AsInt(args[0]); if (y == -1 && PyErr_Occurred()) { goto exit; } - x = _PyLong_AsInt(args[1]); + x = PyLong_AsInt(args[1]); if (x == -1 && PyErr_Occurred()) { goto exit; } @@ -1264,7 +1263,7 @@ _curses_window_is_linetouched(PyCursesWindowObject *self, PyObject *arg) PyObject *return_value = NULL; int line; - line = _PyLong_AsInt(arg); + line = PyLong_AsInt(arg); if (line == -1 && PyErr_Occurred()) { goto exit; } @@ -1508,11 +1507,11 @@ _curses_window_redrawln(PyCursesWindowObject *self, PyObject *const *args, Py_ss if (!_PyArg_CheckPositional("redrawln", nargs, 2, 2)) { goto exit; } - beg = _PyLong_AsInt(args[0]); + beg = PyLong_AsInt(args[0]); if (beg == -1 && PyErr_Occurred()) { goto exit; } - num = _PyLong_AsInt(args[1]); + num = PyLong_AsInt(args[1]); if (num == -1 && PyErr_Occurred()) { goto exit; } @@ -1607,11 +1606,11 @@ _curses_window_setscrreg(PyCursesWindowObject *self, PyObject *const *args, Py_s if (!_PyArg_CheckPositional("setscrreg", nargs, 2, 2)) { goto exit; } - top = _PyLong_AsInt(args[0]); + top = PyLong_AsInt(args[0]); if (top == -1 && PyErr_Occurred()) { goto exit; } - bottom = _PyLong_AsInt(args[1]); + bottom = PyLong_AsInt(args[1]); if (bottom == -1 && PyErr_Occurred()) { goto exit; } @@ -2009,7 +2008,7 @@ _curses_color_pair(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int pair_number; - pair_number = _PyLong_AsInt(arg); + pair_number = PyLong_AsInt(arg); if (pair_number == -1 && PyErr_Occurred()) { goto exit; } @@ -2045,7 +2044,7 @@ _curses_curs_set(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int visibility; - visibility = _PyLong_AsInt(arg); + visibility = PyLong_AsInt(arg); if (visibility == -1 && PyErr_Occurred()) { goto exit; } @@ -2120,7 +2119,7 @@ _curses_delay_output(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int ms; - ms = _PyLong_AsInt(arg); + ms = PyLong_AsInt(arg); if (ms == -1 && PyErr_Occurred()) { goto exit; } @@ -2363,15 +2362,15 @@ _curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) id = (short) ival; } } - x = _PyLong_AsInt(args[1]); + x = PyLong_AsInt(args[1]); if (x == -1 && PyErr_Occurred()) { goto exit; } - y = _PyLong_AsInt(args[2]); + y = PyLong_AsInt(args[2]); if (y == -1 && PyErr_Occurred()) { goto exit; } - z = _PyLong_AsInt(args[3]); + z = PyLong_AsInt(args[3]); if (z == -1 && PyErr_Occurred()) { goto exit; } @@ -2525,7 +2524,7 @@ _curses_has_key(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int key; - key = _PyLong_AsInt(arg); + key = PyLong_AsInt(arg); if (key == -1 && PyErr_Occurred()) { goto exit; } @@ -2744,7 +2743,7 @@ _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO goto skip_optional_pos; } } - fd = _PyLong_AsInt(args[1]); + fd = PyLong_AsInt(args[1]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -2808,7 +2807,7 @@ _curses_set_escdelay(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int ms; - ms = _PyLong_AsInt(arg); + ms = PyLong_AsInt(arg); if (ms == -1 && PyErr_Occurred()) { goto exit; } @@ -2871,7 +2870,7 @@ _curses_set_tabsize(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int size; - size = _PyLong_AsInt(arg); + size = PyLong_AsInt(arg); if (size == -1 && PyErr_Occurred()) { goto exit; } @@ -2957,11 +2956,11 @@ _curses_is_term_resized(PyObject *module, PyObject *const *args, Py_ssize_t narg if (!_PyArg_CheckPositional("is_term_resized", nargs, 2, 2)) { goto exit; } - nlines = _PyLong_AsInt(args[0]); + nlines = PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - ncols = _PyLong_AsInt(args[1]); + ncols = PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; } @@ -2994,7 +2993,7 @@ _curses_keyname(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int key; - key = _PyLong_AsInt(arg); + key = PyLong_AsInt(arg); if (key == -1 && PyErr_Occurred()) { goto exit; } @@ -3101,7 +3100,7 @@ _curses_mouseinterval(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int interval; - interval = _PyLong_AsInt(arg); + interval = PyLong_AsInt(arg); if (interval == -1 && PyErr_Occurred()) { goto exit; } @@ -3172,7 +3171,7 @@ _curses_napms(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int ms; - ms = _PyLong_AsInt(arg); + ms = PyLong_AsInt(arg); if (ms == -1 && PyErr_Occurred()) { goto exit; } @@ -3209,11 +3208,11 @@ _curses_newpad(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("newpad", nargs, 2, 2)) { goto exit; } - nlines = _PyLong_AsInt(args[0]); + nlines = PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - ncols = _PyLong_AsInt(args[1]); + ncols = PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; } @@ -3471,7 +3470,7 @@ _curses_pair_number(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int attr; - attr = _PyLong_AsInt(arg); + attr = PyLong_AsInt(arg); if (attr == -1 && PyErr_Occurred()) { goto exit; } @@ -3700,11 +3699,11 @@ _curses_resizeterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("resizeterm", nargs, 2, 2)) { goto exit; } - nlines = _PyLong_AsInt(args[0]); + nlines = PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - ncols = _PyLong_AsInt(args[1]); + ncols = PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; } @@ -3751,11 +3750,11 @@ _curses_resize_term(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("resize_term", nargs, 2, 2)) { goto exit; } - nlines = _PyLong_AsInt(args[0]); + nlines = PyLong_AsInt(args[0]); if (nlines == -1 && PyErr_Occurred()) { goto exit; } - ncols = _PyLong_AsInt(args[1]); + ncols = PyLong_AsInt(args[1]); if (ncols == -1 && PyErr_Occurred()) { goto exit; } @@ -3816,11 +3815,11 @@ _curses_setsyx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setsyx", nargs, 2, 2)) { goto exit; } - y = _PyLong_AsInt(args[0]); + y = PyLong_AsInt(args[0]); if (y == -1 && PyErr_Occurred()) { goto exit; } - x = _PyLong_AsInt(args[1]); + x = PyLong_AsInt(args[1]); if (x == -1 && PyErr_Occurred()) { goto exit; } @@ -4089,7 +4088,7 @@ _curses_typeahead(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -4313,4 +4312,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored #ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF #define _CURSES_USE_DEFAULT_COLORS_METHODDEF #endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ -/*[clinic end generated code: output=27a2364193b503c1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=839faafb638935ea input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h index 51e51e3791cc24..177a37e486e24d 100644 --- a/Modules/clinic/_datetimemodule.c.h +++ b/Modules/clinic/_datetimemodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(datetime_date_fromtimestamp__doc__, "fromtimestamp($type, timestamp, /)\n" "--\n" @@ -64,15 +63,15 @@ iso_calendar_date_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!fastargs) { goto exit; } - year = _PyLong_AsInt(fastargs[0]); + year = PyLong_AsInt(fastargs[0]); if (year == -1 && PyErr_Occurred()) { goto exit; } - week = _PyLong_AsInt(fastargs[1]); + week = PyLong_AsInt(fastargs[1]); if (week == -1 && PyErr_Occurred()) { goto exit; } - weekday = _PyLong_AsInt(fastargs[2]); + weekday = PyLong_AsInt(fastargs[2]); if (weekday == -1 && PyErr_Occurred()) { goto exit; } @@ -146,4 +145,4 @@ datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t narg exit: return return_value; } -/*[clinic end generated code: output=42654669940e0e3a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e422c25b1c28f38b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index 172dc4b9d5793e..a76b8b30eded39 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_dbm_dbm_close__doc__, "close($self, /)\n" "--\n" @@ -138,6 +132,28 @@ _dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, P return return_value; } +PyDoc_STRVAR(_dbm_dbm_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from the database."); + +#define _DBM_DBM_CLEAR_METHODDEF \ + {"clear", _PyCFunction_CAST(_dbm_dbm_clear), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_clear__doc__}, + +static PyObject * +_dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls); + +static PyObject * +_dbm_dbm_clear(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "clear() takes no arguments"); + return NULL; + } + return _dbm_dbm_clear_impl(self, cls); +} + PyDoc_STRVAR(dbmopen__doc__, "open($module, filename, flags=\'r\', mode=0o666, /)\n" "--\n" @@ -190,7 +206,7 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - mode = _PyLong_AsInt(args[2]); + mode = PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -200,4 +216,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=28dcf736654137c2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=972d221f9da819d3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index a0bc751ca21ee8..3477257f9d2cf2 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_elementtree_Element_append__doc__, "append($self, subelement, /)\n" @@ -1218,4 +1218,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=40767b1a98e54b60 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=20d1869da79a43d7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_functoolsmodule.c.h b/Modules/clinic/_functoolsmodule.c.h index 9c79e6430413bf..25a3e5b0da60a8 100644 --- a/Modules/clinic/_functoolsmodule.c.h +++ b/Modules/clinic/_functoolsmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_functools_cmp_to_key__doc__, "cmp_to_key($module, /, mycmp)\n" "--\n" @@ -101,4 +100,4 @@ _functools__lru_cache_wrapper_cache_clear(PyObject *self, PyObject *Py_UNUSED(ig { return _functools__lru_cache_wrapper_cache_clear_impl(self); } -/*[clinic end generated code: output=7e7f3bcf9ed61f23 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=de9cf85e85167f43 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index 5c6aeeee7789f7..e9138bbf0430c5 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_gdbm_gdbm_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -247,6 +241,28 @@ _gdbm_gdbm_sync(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_s return _gdbm_gdbm_sync_impl(self, cls); } +PyDoc_STRVAR(_gdbm_gdbm_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from the database."); + +#define _GDBM_GDBM_CLEAR_METHODDEF \ + {"clear", _PyCFunction_CAST(_gdbm_gdbm_clear), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_clear__doc__}, + +static PyObject * +_gdbm_gdbm_clear_impl(gdbmobject *self, PyTypeObject *cls); + +static PyObject * +_gdbm_gdbm_clear(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "clear() takes no arguments"); + return NULL; + } + return _gdbm_gdbm_clear_impl(self, cls); +} + PyDoc_STRVAR(dbmopen__doc__, "open($module, filename, flags=\'r\', mode=0o666, /)\n" "--\n" @@ -312,7 +328,7 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - mode = _PyLong_AsInt(args[2]); + mode = PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -322,4 +338,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=c6e721d82335adb3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=84f30c7fff0eadac input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index fb61a444018dbb..e41f608bde5011 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(EVP_copy__doc__, "copy($self, /)\n" @@ -1851,4 +1851,4 @@ _hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t narg #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=b339e255db698147 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=75413752099f2dec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_heapqmodule.c.h b/Modules/clinic/_heapqmodule.c.h index 3ee3f51702fa30..8d73b5b48d6a0e 100644 --- a/Modules/clinic/_heapqmodule.c.h +++ b/Modules/clinic/_heapqmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_heapq_heappush__doc__, "heappush($module, heap, item, /)\n" "--\n" @@ -271,4 +265,4 @@ _heapq__heapify_max(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=29e99a48c57f82bb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a22715a8bf0c91d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_localemodule.c.h b/Modules/clinic/_localemodule.c.h index 9d65c0876a1a33..efbb9f709958cd 100644 --- a/Modules/clinic/_localemodule.c.h +++ b/Modules/clinic/_localemodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_locale_setlocale__doc__, "setlocale($module, category, locale=, /)\n" "--\n" @@ -30,7 +24,7 @@ _locale_setlocale(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setlocale", nargs, 1, 2)) { goto exit; } - category = _PyLong_AsInt(args[0]); + category = PyLong_AsInt(args[0]); if (category == -1 && PyErr_Occurred()) { goto exit; } @@ -196,7 +190,7 @@ _locale_nl_langinfo(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int item; - item = _PyLong_AsInt(arg); + item = PyLong_AsInt(arg); if (item == -1 && PyErr_Occurred()) { goto exit; } @@ -373,7 +367,7 @@ _locale_dcgettext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - category = _PyLong_AsInt(args[2]); + category = PyLong_AsInt(args[2]); if (category == -1 && PyErr_Occurred()) { goto exit; } @@ -599,4 +593,4 @@ _locale_getencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #endif /* !defined(_LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF) */ -/*[clinic end generated code: output=9dbd0b4bf5767edd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3abe7fade999eff6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index 5fcc7ae02e3b00..dfc003eb54774c 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, "getstats($self, /)\n" "--\n" @@ -51,4 +45,4 @@ _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *con } return _lsprof_Profiler_getstats_impl(self, cls); } -/*[clinic end generated code: output=7425d3481349629a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0615a53cce828f06 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index 9b396a56683921..528b48384f0bcb 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, "compress($self, data, /)\n" @@ -241,7 +241,7 @@ _lzma_LZMADecompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } if (fastargs[0]) { - format = _PyLong_AsInt(fastargs[0]); + format = PyLong_AsInt(fastargs[0]); if (format == -1 && PyErr_Occurred()) { goto exit; } @@ -283,7 +283,7 @@ _lzma_is_check_supported(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int check_id; - check_id = _PyLong_AsInt(arg); + check_id = PyLong_AsInt(arg); if (check_id == -1 && PyErr_Occurred()) { goto exit; } @@ -338,4 +338,4 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz return return_value; } -/*[clinic end generated code: output=96c1fbdada1ef232 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eadc9ee7a11a06f5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h index e6381fa73a5506..4b9a70d2ba9852 100644 --- a/Modules/clinic/_opcode.c.h +++ b/Modules/clinic/_opcode.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_opcode_stack_effect__doc__, "stack_effect($module, opcode, oparg=None, /, *, jump=None)\n" "--\n" @@ -61,7 +60,7 @@ _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -135,7 +134,7 @@ _opcode_is_valid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -198,7 +197,7 @@ _opcode_has_arg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -261,7 +260,7 @@ _opcode_has_const(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -324,7 +323,7 @@ _opcode_has_name(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -387,7 +386,7 @@ _opcode_has_jump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -455,7 +454,7 @@ _opcode_has_free(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -518,7 +517,7 @@ _opcode_has_local(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -581,7 +580,7 @@ _opcode_has_exc(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!args) { goto exit; } - opcode = _PyLong_AsInt(args[0]); + opcode = PyLong_AsInt(args[0]); if (opcode == -1 && PyErr_Occurred()) { goto exit; } @@ -612,4 +611,60 @@ _opcode_get_specialization_stats(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _opcode_get_specialization_stats_impl(module); } -/*[clinic end generated code: output=e507bf14fb2796f8 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_opcode_get_nb_ops__doc__, +"get_nb_ops($module, /)\n" +"--\n" +"\n" +"Return array of symbols of binary ops.\n" +"\n" +"Indexed by the BINARY_OP oparg value."); + +#define _OPCODE_GET_NB_OPS_METHODDEF \ + {"get_nb_ops", (PyCFunction)_opcode_get_nb_ops, METH_NOARGS, _opcode_get_nb_ops__doc__}, + +static PyObject * +_opcode_get_nb_ops_impl(PyObject *module); + +static PyObject * +_opcode_get_nb_ops(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _opcode_get_nb_ops_impl(module); +} + +PyDoc_STRVAR(_opcode_get_intrinsic1_descs__doc__, +"get_intrinsic1_descs($module, /)\n" +"--\n" +"\n" +"Return a list of names of the unary intrinsics."); + +#define _OPCODE_GET_INTRINSIC1_DESCS_METHODDEF \ + {"get_intrinsic1_descs", (PyCFunction)_opcode_get_intrinsic1_descs, METH_NOARGS, _opcode_get_intrinsic1_descs__doc__}, + +static PyObject * +_opcode_get_intrinsic1_descs_impl(PyObject *module); + +static PyObject * +_opcode_get_intrinsic1_descs(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _opcode_get_intrinsic1_descs_impl(module); +} + +PyDoc_STRVAR(_opcode_get_intrinsic2_descs__doc__, +"get_intrinsic2_descs($module, /)\n" +"--\n" +"\n" +"Return a list of names of the binary intrinsics."); + +#define _OPCODE_GET_INTRINSIC2_DESCS_METHODDEF \ + {"get_intrinsic2_descs", (PyCFunction)_opcode_get_intrinsic2_descs, METH_NOARGS, _opcode_get_intrinsic2_descs__doc__}, + +static PyObject * +_opcode_get_intrinsic2_descs_impl(PyObject *module); + +static PyObject * +_opcode_get_intrinsic2_descs(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _opcode_get_intrinsic2_descs_impl(module); +} +/*[clinic end generated code: output=d608239a4c7a05a1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_operator.c.h b/Modules/clinic/_operator.c.h index b68e6e0144a586..06bde243b4e85b 100644 --- a/Modules/clinic/_operator.c.h +++ b/Modules/clinic/_operator.c.h @@ -2,11 +2,7 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_operator_truth__doc__, "truth($module, a, /)\n" @@ -1492,4 +1488,4 @@ _operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=227cbcfed44f736e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9658aca50a9ad991 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 539acc34a05cc1..5df40d62827754 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, "clear_memo($self, /)\n" "--\n" @@ -1034,4 +1033,4 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=a0e04b85e7bae626 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=57c209a12264146d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_posixsubprocess.c.h b/Modules/clinic/_posixsubprocess.c.h index f08878cf668908..83048a385d319c 100644 --- a/Modules/clinic/_posixsubprocess.c.h +++ b/Modules/clinic/_posixsubprocess.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(subprocess_fork_exec__doc__, "fork_exec($module, args, executable_list, close_fds, pass_fds, cwd,\n" " env, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite,\n" @@ -98,35 +92,35 @@ subprocess_fork_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) py_fds_to_keep = args[3]; cwd_obj = args[4]; env_list = args[5]; - p2cread = _PyLong_AsInt(args[6]); + p2cread = PyLong_AsInt(args[6]); if (p2cread == -1 && PyErr_Occurred()) { goto exit; } - p2cwrite = _PyLong_AsInt(args[7]); + p2cwrite = PyLong_AsInt(args[7]); if (p2cwrite == -1 && PyErr_Occurred()) { goto exit; } - c2pread = _PyLong_AsInt(args[8]); + c2pread = PyLong_AsInt(args[8]); if (c2pread == -1 && PyErr_Occurred()) { goto exit; } - c2pwrite = _PyLong_AsInt(args[9]); + c2pwrite = PyLong_AsInt(args[9]); if (c2pwrite == -1 && PyErr_Occurred()) { goto exit; } - errread = _PyLong_AsInt(args[10]); + errread = PyLong_AsInt(args[10]); if (errread == -1 && PyErr_Occurred()) { goto exit; } - errwrite = _PyLong_AsInt(args[11]); + errwrite = PyLong_AsInt(args[11]); if (errwrite == -1 && PyErr_Occurred()) { goto exit; } - errpipe_read = _PyLong_AsInt(args[12]); + errpipe_read = PyLong_AsInt(args[12]); if (errpipe_read == -1 && PyErr_Occurred()) { goto exit; } - errpipe_write = _PyLong_AsInt(args[13]); + errpipe_write = PyLong_AsInt(args[13]); if (errpipe_write == -1 && PyErr_Occurred()) { goto exit; } @@ -145,7 +139,7 @@ subprocess_fork_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) gid_object = args[17]; extra_groups_packed = args[18]; uid_object = args[19]; - child_umask = _PyLong_AsInt(args[20]); + child_umask = PyLong_AsInt(args[20]); if (child_umask == -1 && PyErr_Occurred()) { goto exit; } @@ -159,4 +153,4 @@ subprocess_fork_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=46d71e86845c93d7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a83b11467169b97b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 94fb59a5b17a49..8d4df14ae3b009 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(simplequeue_new__doc__, "SimpleQueue()\n" "--\n" @@ -331,4 +330,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=9a72a8d1b5767f6a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c326e4c1f2a1ad7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_randommodule.c.h b/Modules/clinic/_randommodule.c.h index ec8531ce006649..008b531d832c5a 100644 --- a/Modules/clinic/_randommodule.c.h +++ b/Modules/clinic/_randommodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_random_Random_random__doc__, "random($self, /)\n" "--\n" @@ -106,7 +100,7 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) PyObject *return_value = NULL; int k; - k = _PyLong_AsInt(arg); + k = PyLong_AsInt(arg); if (k == -1 && PyErr_Occurred()) { goto exit; } @@ -115,4 +109,4 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=bc17406a886824fc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5e7e05d756a7e1c7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 9f967ddc8e3061..5f8ae29180a4fa 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, "do_handshake($self, /)\n" @@ -445,7 +445,7 @@ _ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!_PyArg_CheckPositional("_SSLContext", PyTuple_GET_SIZE(args), 1, 1)) { goto exit; } - proto_version = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + proto_version = PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); if (proto_version == -1 && PyErr_Occurred()) { goto exit; } @@ -1073,7 +1073,7 @@ _ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *const *args, Py_ssize_t narg if (nargs < 1) { goto skip_optional; } - len = _PyLong_AsInt(args[0]); + len = PyLong_AsInt(args[0]); if (len == -1 && PyErr_Occurred()) { goto exit; } @@ -1223,7 +1223,7 @@ _ssl_RAND_bytes(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int n; - n = _PyLong_AsInt(arg); + n = PyLong_AsInt(arg); if (n == -1 && PyErr_Occurred()) { goto exit; } @@ -1372,7 +1372,7 @@ _ssl_nid2obj(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int nid; - nid = _PyLong_AsInt(arg); + nid = PyLong_AsInt(arg); if (nid == -1 && PyErr_Occurred()) { goto exit; } @@ -1542,4 +1542,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=4d9b81fa81f520f0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a47d575abe0aceb6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_statisticsmodule.c.h b/Modules/clinic/_statisticsmodule.c.h index 4dedadd2939ad6..03543e41af7f5a 100644 --- a/Modules/clinic/_statisticsmodule.c.h +++ b/Modules/clinic/_statisticsmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_statistics__normal_dist_inv_cdf__doc__, "_normal_dist_inv_cdf($module, p, mu, sigma, /)\n" "--\n" @@ -71,4 +65,4 @@ _statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssi exit: return return_value; } -/*[clinic end generated code: output=6899dc752cc6b457 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b807a8243e7801e6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index c3cf179ed4c040..8c468e6e7205e6 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(Struct__doc__, "Struct(format)\n" @@ -451,4 +451,4 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=f3d6e06f80368998 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c1bc384ff87df1f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_sysconfig.c.h b/Modules/clinic/_sysconfig.c.h new file mode 100644 index 00000000000000..eb3d396298bb21 --- /dev/null +++ b/Modules/clinic/_sysconfig.c.h @@ -0,0 +1,22 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_sysconfig_config_vars__doc__, +"config_vars($module, /)\n" +"--\n" +"\n" +"Returns a dictionary containing build variables intended to be exposed by sysconfig."); + +#define _SYSCONFIG_CONFIG_VARS_METHODDEF \ + {"config_vars", (PyCFunction)_sysconfig_config_vars, METH_NOARGS, _sysconfig_config_vars__doc__}, + +static PyObject * +_sysconfig_config_vars_impl(PyObject *module); + +static PyObject * +_sysconfig_config_vars(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _sysconfig_config_vars_impl(module); +} +/*[clinic end generated code: output=25d395cf02eced1f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index 51c3a7824dbebd..ba3aeca49e26eb 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -3,10 +3,11 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head #endif - +#include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_long.h" // _PyLong_UnsignedShort_Converter() +#include "pycore_runtime.h" // _Py_ID() PyDoc_STRVAR(test_empty_function__doc__, "test_empty_function($module, /)\n" @@ -181,7 +182,7 @@ bool_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - c = _PyLong_AsInt(args[2]); + c = PyLong_AsInt(args[2]); if (c == -1 && PyErr_Occurred()) { goto exit; } @@ -627,14 +628,14 @@ int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - a = _PyLong_AsInt(args[0]); + a = PyLong_AsInt(args[0]); if (a == -1 && PyErr_Occurred()) { goto exit; } if (nargs < 2) { goto skip_optional; } - b = _PyLong_AsInt(args[1]); + b = PyLong_AsInt(args[1]); if (b == -1 && PyErr_Occurred()) { goto exit; } @@ -3069,4 +3070,4 @@ clone_with_conv_f2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py exit: return return_value; } -/*[clinic end generated code: output=0de394419fefe7cf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c2a69a08ffdfc466 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic_depr.c.h b/Modules/clinic/_testclinic_depr.c.h new file mode 100644 index 00000000000000..36ff55bc002939 --- /dev/null +++ b/Modules/clinic/_testclinic_depr.c.h @@ -0,0 +1,2395 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +#endif +#include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_long.h" // _PyLong_UnsignedShort_Converter() +#include "pycore_runtime.h" // _Py_ID() + +PyDoc_STRVAR(depr_star_new__doc__, +"DeprStarNew(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __new__.\n" +"\n" +"Note: Passing positional arguments to _testclinic.DeprStarNew() is\n" +"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +static PyObject * +depr_star_new_impl(PyTypeObject *type, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarNew.__new__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarNew.__new__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarNew.__new__'." +# endif +#endif + +static PyObject * +depr_star_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "DeprStarNew", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to _testclinic.DeprStarNew() is " + "deprecated. Parameter 'a' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_star_new_impl(type, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_new_clone__doc__, +"cloned($self, /, a=None)\n" +"--\n" +"\n" +"Note: Passing positional arguments to _testclinic.DeprStarNew.cloned()\n" +"is deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_NEW_CLONE_METHODDEF \ + {"cloned", _PyCFunction_CAST(depr_star_new_clone), METH_FASTCALL|METH_KEYWORDS, depr_star_new_clone__doc__}, + +static PyObject * +depr_star_new_clone_impl(PyObject *type, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarNew.cloned'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarNew.cloned'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarNew.cloned'." +# endif +#endif + +static PyObject * +depr_star_new_clone(PyObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cloned", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to _testclinic.DeprStarNew.cloned()" + " is deprecated. Parameter 'a' will become a keyword-only " + "parameter in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = args[0]; +skip_optional_pos: + return_value = depr_star_new_clone_impl(type, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_init__doc__, +"DeprStarInit(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __init__.\n" +"\n" +"Note: Passing positional arguments to _testclinic.DeprStarInit() is\n" +"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +static int +depr_star_init_impl(PyObject *self, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarInit.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarInit.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarInit.__init__'." +# endif +#endif + +static int +depr_star_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "DeprStarInit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to _testclinic.DeprStarInit() is " + "deprecated. Parameter 'a' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_star_init_impl(self, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_init_clone__doc__, +"cloned($self, /, a=None)\n" +"--\n" +"\n" +"Note: Passing positional arguments to\n" +"_testclinic.DeprStarInit.cloned() is deprecated. Parameter \'a\' will\n" +"become a keyword-only parameter in Python 3.14.\n" +""); + +#define DEPR_STAR_INIT_CLONE_METHODDEF \ + {"cloned", _PyCFunction_CAST(depr_star_init_clone), METH_FASTCALL|METH_KEYWORDS, depr_star_init_clone__doc__}, + +static PyObject * +depr_star_init_clone_impl(PyObject *self, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarInit.cloned'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarInit.cloned'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarInit.cloned'." +# endif +#endif + +static PyObject * +depr_star_init_clone(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cloned", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to " + "_testclinic.DeprStarInit.cloned() is deprecated. Parameter 'a' " + "will become a keyword-only parameter in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = args[0]; +skip_optional_pos: + return_value = depr_star_init_clone_impl(self, a); + +exit: + return return_value; +} + +static int +depr_star_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarInitNoInline.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarInitNoInline.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarInitNoInline.__init__'." +# endif +#endif + +static int +depr_star_init_noinline(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|O$s#:DeprStarInitNoInline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (nargs > 1 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to " + "_testclinic.DeprStarInitNoInline() is deprecated. Parameters 'b'" + " and 'c' will become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + return_value = depr_star_init_noinline_impl(self, a, b, c, d, d_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_new__doc__, +"DeprKwdNew(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __new__.\n" +"\n" +"Note: Passing keyword argument \'a\' to _testclinic.DeprKwdNew() is\n" +"deprecated. Parameter \'a\' will become positional-only in Python 3.14.\n" +""); + +static PyObject * +depr_kwd_new_impl(PyTypeObject *type, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprKwdNew.__new__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprKwdNew.__new__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprKwdNew.__new__'." +# endif +#endif + +static PyObject * +depr_kwd_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "DeprKwdNew", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (kwargs && PyDict_GET_SIZE(kwargs) && nargs < 1 && fastargs[0]) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'a' to _testclinic.DeprKwdNew() is " + "deprecated. Parameter 'a' will become positional-only in Python " + "3.14.", 1)) + { + goto exit; + } + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_kwd_new_impl(type, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_init__doc__, +"DeprKwdInit(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __init__.\n" +"\n" +"Note: Passing keyword argument \'a\' to _testclinic.DeprKwdInit() is\n" +"deprecated. Parameter \'a\' will become positional-only in Python 3.14.\n" +""); + +static int +depr_kwd_init_impl(PyObject *self, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprKwdInit.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprKwdInit.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprKwdInit.__init__'." +# endif +#endif + +static int +depr_kwd_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "DeprKwdInit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (kwargs && PyDict_GET_SIZE(kwargs) && nargs < 1 && fastargs[0]) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'a' to _testclinic.DeprKwdInit() is " + "deprecated. Parameter 'a' will become positional-only in Python " + "3.14.", 1)) + { + goto exit; + } + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_kwd_init_impl(self, a); + +exit: + return return_value; +} + +static int +depr_kwd_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprKwdInitNoInline.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprKwdInitNoInline.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprKwdInitNoInline.__init__'." +# endif +#endif + +static int +depr_kwd_init_noinline(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|Os#:DeprKwdInitNoInline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + if (kwargs && PyDict_GET_SIZE(kwargs) && ((nargs < 2) || (nargs < 3 && PyDict_Contains(kwargs, &_Py_ID(c))))) { + if (PyErr_Occurred()) { // PyDict_Contains() above can fail + goto exit; + } + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to " + "_testclinic.DeprKwdInitNoInline() is deprecated. Parameters 'b' " + "and 'c' will become positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + return_value = depr_kwd_init_noinline_impl(self, a, b, c, d, d_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos0_len1__doc__, +"depr_star_pos0_len1($module, /, a)\n" +"--\n" +"\n" +"Note: Passing positional arguments to depr_star_pos0_len1() is\n" +"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS0_LEN1_METHODDEF \ + {"depr_star_pos0_len1", _PyCFunction_CAST(depr_star_pos0_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len1__doc__}, + +static PyObject * +depr_star_pos0_len1_impl(PyObject *module, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos0_len1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos0_len1'.") +# else +# warning "Update the clinic input of 'depr_star_pos0_len1'." +# endif +#endif + +static PyObject * +depr_star_pos0_len1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos0_len1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *a; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to depr_star_pos0_len1() is " + "deprecated. Parameter 'a' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + return_value = depr_star_pos0_len1_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos0_len2__doc__, +"depr_star_pos0_len2($module, /, a, b)\n" +"--\n" +"\n" +"Note: Passing positional arguments to depr_star_pos0_len2() is\n" +"deprecated. Parameters \'a\' and \'b\' will become keyword-only parameters\n" +"in Python 3.14.\n" +""); + +#define DEPR_STAR_POS0_LEN2_METHODDEF \ + {"depr_star_pos0_len2", _PyCFunction_CAST(depr_star_pos0_len2), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len2__doc__}, + +static PyObject * +depr_star_pos0_len2_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos0_len2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos0_len2'.") +# else +# warning "Update the clinic input of 'depr_star_pos0_len2'." +# endif +#endif + +static PyObject * +depr_star_pos0_len2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos0_len2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + if (nargs > 0 && nargs <= 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to depr_star_pos0_len2() is " + "deprecated. Parameters 'a' and 'b' will become keyword-only " + "parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = depr_star_pos0_len2_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos0_len3_with_kwd__doc__, +"depr_star_pos0_len3_with_kwd($module, /, a, b, c, *, d)\n" +"--\n" +"\n" +"Note: Passing positional arguments to depr_star_pos0_len3_with_kwd()\n" +"is deprecated. Parameters \'a\', \'b\' and \'c\' will become keyword-only\n" +"parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS0_LEN3_WITH_KWD_METHODDEF \ + {"depr_star_pos0_len3_with_kwd", _PyCFunction_CAST(depr_star_pos0_len3_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len3_with_kwd__doc__}, + +static PyObject * +depr_star_pos0_len3_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos0_len3_with_kwd'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos0_len3_with_kwd'.") +# else +# warning "Update the clinic input of 'depr_star_pos0_len3_with_kwd'." +# endif +#endif + +static PyObject * +depr_star_pos0_len3_with_kwd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos0_len3_with_kwd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + + if (nargs > 0 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to depr_star_pos0_len3_with_kwd() " + "is deprecated. Parameters 'a', 'b' and 'c' will become " + "keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + return_value = depr_star_pos0_len3_with_kwd_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos1_len1_opt__doc__, +"depr_star_pos1_len1_opt($module, /, a, b=None)\n" +"--\n" +"\n" +"Note: Passing 2 positional arguments to depr_star_pos1_len1_opt() is\n" +"deprecated. Parameter \'b\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS1_LEN1_OPT_METHODDEF \ + {"depr_star_pos1_len1_opt", _PyCFunction_CAST(depr_star_pos1_len1_opt), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len1_opt__doc__}, + +static PyObject * +depr_star_pos1_len1_opt_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos1_len1_opt'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos1_len1_opt'.") +# else +# warning "Update the clinic input of 'depr_star_pos1_len1_opt'." +# endif +#endif + +static PyObject * +depr_star_pos1_len1_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos1_len1_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + + if (nargs == 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 2 positional arguments to depr_star_pos1_len1_opt() is " + "deprecated. Parameter 'b' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + b = args[1]; +skip_optional_pos: + return_value = depr_star_pos1_len1_opt_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos1_len1__doc__, +"depr_star_pos1_len1($module, /, a, b)\n" +"--\n" +"\n" +"Note: Passing 2 positional arguments to depr_star_pos1_len1() is\n" +"deprecated. Parameter \'b\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS1_LEN1_METHODDEF \ + {"depr_star_pos1_len1", _PyCFunction_CAST(depr_star_pos1_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len1__doc__}, + +static PyObject * +depr_star_pos1_len1_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos1_len1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos1_len1'.") +# else +# warning "Update the clinic input of 'depr_star_pos1_len1'." +# endif +#endif + +static PyObject * +depr_star_pos1_len1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos1_len1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + if (nargs == 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 2 positional arguments to depr_star_pos1_len1() is " + "deprecated. Parameter 'b' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = depr_star_pos1_len1_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos1_len2_with_kwd__doc__, +"depr_star_pos1_len2_with_kwd($module, /, a, b, c, *, d)\n" +"--\n" +"\n" +"Note: Passing more than 1 positional argument to\n" +"depr_star_pos1_len2_with_kwd() is deprecated. Parameters \'b\' and \'c\'\n" +"will become keyword-only parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS1_LEN2_WITH_KWD_METHODDEF \ + {"depr_star_pos1_len2_with_kwd", _PyCFunction_CAST(depr_star_pos1_len2_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len2_with_kwd__doc__}, + +static PyObject * +depr_star_pos1_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos1_len2_with_kwd'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos1_len2_with_kwd'.") +# else +# warning "Update the clinic input of 'depr_star_pos1_len2_with_kwd'." +# endif +#endif + +static PyObject * +depr_star_pos1_len2_with_kwd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos1_len2_with_kwd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + + if (nargs > 1 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to " + "depr_star_pos1_len2_with_kwd() is deprecated. Parameters 'b' and" + " 'c' will become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + return_value = depr_star_pos1_len2_with_kwd_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos2_len1__doc__, +"depr_star_pos2_len1($module, /, a, b, c)\n" +"--\n" +"\n" +"Note: Passing 3 positional arguments to depr_star_pos2_len1() is\n" +"deprecated. Parameter \'c\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS2_LEN1_METHODDEF \ + {"depr_star_pos2_len1", _PyCFunction_CAST(depr_star_pos2_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len1__doc__}, + +static PyObject * +depr_star_pos2_len1_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos2_len1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos2_len1'.") +# else +# warning "Update the clinic input of 'depr_star_pos2_len1'." +# endif +#endif + +static PyObject * +depr_star_pos2_len1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos2_len1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *a; + PyObject *b; + PyObject *c; + + if (nargs == 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 3 positional arguments to depr_star_pos2_len1() is " + "deprecated. Parameter 'c' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + return_value = depr_star_pos2_len1_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos2_len2__doc__, +"depr_star_pos2_len2($module, /, a, b, c, d)\n" +"--\n" +"\n" +"Note: Passing more than 2 positional arguments to\n" +"depr_star_pos2_len2() is deprecated. Parameters \'c\' and \'d\' will\n" +"become keyword-only parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS2_LEN2_METHODDEF \ + {"depr_star_pos2_len2", _PyCFunction_CAST(depr_star_pos2_len2), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len2__doc__}, + +static PyObject * +depr_star_pos2_len2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos2_len2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos2_len2'.") +# else +# warning "Update the clinic input of 'depr_star_pos2_len2'." +# endif +#endif + +static PyObject * +depr_star_pos2_len2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos2_len2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + + if (nargs > 2 && nargs <= 4) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 2 positional arguments to " + "depr_star_pos2_len2() is deprecated. Parameters 'c' and 'd' will" + " become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + return_value = depr_star_pos2_len2_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos2_len2_with_kwd__doc__, +"depr_star_pos2_len2_with_kwd($module, /, a, b, c, d, *, e)\n" +"--\n" +"\n" +"Note: Passing more than 2 positional arguments to\n" +"depr_star_pos2_len2_with_kwd() is deprecated. Parameters \'c\' and \'d\'\n" +"will become keyword-only parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS2_LEN2_WITH_KWD_METHODDEF \ + {"depr_star_pos2_len2_with_kwd", _PyCFunction_CAST(depr_star_pos2_len2_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len2_with_kwd__doc__}, + +static PyObject * +depr_star_pos2_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d, PyObject *e); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos2_len2_with_kwd'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos2_len2_with_kwd'.") +# else +# warning "Update the clinic input of 'depr_star_pos2_len2_with_kwd'." +# endif +#endif + +static PyObject * +depr_star_pos2_len2_with_kwd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", "e", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos2_len2_with_kwd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + PyObject *e; + + if (nargs > 2 && nargs <= 4) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 2 positional arguments to " + "depr_star_pos2_len2_with_kwd() is deprecated. Parameters 'c' and" + " 'd' will become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + e = args[4]; + return_value = depr_star_pos2_len2_with_kwd_impl(module, a, b, c, d, e); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_noinline__doc__, +"depr_star_noinline($module, /, a, b, c=None, *, d=\'\')\n" +"--\n" +"\n" +"Note: Passing more than 1 positional argument to depr_star_noinline()\n" +"is deprecated. Parameters \'b\' and \'c\' will become keyword-only\n" +"parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_NOINLINE_METHODDEF \ + {"depr_star_noinline", _PyCFunction_CAST(depr_star_noinline), METH_FASTCALL|METH_KEYWORDS, depr_star_noinline__doc__}, + +static PyObject * +depr_star_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_noinline'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_noinline'.") +# else +# warning "Update the clinic input of 'depr_star_noinline'." +# endif +#endif + +static PyObject * +depr_star_noinline(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|O$s#:depr_star_noinline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (nargs > 1 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to depr_star_noinline() " + "is deprecated. Parameters 'b' and 'c' will become keyword-only " + "parameters in Python 3.14.", 1)) + { + goto exit; + } + } + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + return_value = depr_star_noinline_impl(module, a, b, c, d, d_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_multi__doc__, +"depr_star_multi($module, /, a, b, c, d, e, f, g, *, h)\n" +"--\n" +"\n" +"Note: Passing more than 1 positional argument to depr_star_multi() is\n" +"deprecated. Parameter \'b\' will become a keyword-only parameter in\n" +"Python 3.16. Parameters \'c\' and \'d\' will become keyword-only\n" +"parameters in Python 3.15. Parameters \'e\', \'f\' and \'g\' will become\n" +"keyword-only parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_MULTI_METHODDEF \ + {"depr_star_multi", _PyCFunction_CAST(depr_star_multi), METH_FASTCALL|METH_KEYWORDS, depr_star_multi__doc__}, + +static PyObject * +depr_star_multi_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyObject *d, PyObject *e, PyObject *f, PyObject *g, + PyObject *h); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_multi'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_multi'.") +# else +# warning "Update the clinic input of 'depr_star_multi'." +# endif +#endif + +static PyObject * +depr_star_multi(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 8 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), &_Py_ID(f), &_Py_ID(g), &_Py_ID(h), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", "e", "f", "g", "h", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_multi", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[8]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + PyObject *e; + PyObject *f; + PyObject *g; + PyObject *h; + + if (nargs > 1 && nargs <= 7) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to depr_star_multi() is " + "deprecated. Parameter 'b' will become a keyword-only parameter " + "in Python 3.16. Parameters 'c' and 'd' will become keyword-only " + "parameters in Python 3.15. Parameters 'e', 'f' and 'g' will " + "become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 7, 7, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + e = args[4]; + f = args[5]; + g = args[6]; + h = args[7]; + return_value = depr_star_multi_impl(module, a, b, c, d, e, f, g, h); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_required_1__doc__, +"depr_kwd_required_1($module, a, /, b)\n" +"--\n" +"\n" +"Note: Passing keyword argument \'b\' to depr_kwd_required_1() is\n" +"deprecated. Parameter \'b\' will become positional-only in Python 3.14.\n" +""); + +#define DEPR_KWD_REQUIRED_1_METHODDEF \ + {"depr_kwd_required_1", _PyCFunction_CAST(depr_kwd_required_1), METH_FASTCALL|METH_KEYWORDS, depr_kwd_required_1__doc__}, + +static PyObject * +depr_kwd_required_1_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_required_1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_required_1'.") +# else +# warning "Update the clinic input of 'depr_kwd_required_1'." +# endif +#endif + +static PyObject * +depr_kwd_required_1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_required_1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'b' to depr_kwd_required_1() is " + "deprecated. Parameter 'b' will become positional-only in Python " + "3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + return_value = depr_kwd_required_1_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_required_2__doc__, +"depr_kwd_required_2($module, a, /, b, c)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to depr_kwd_required_2()\n" +"is deprecated. Parameters \'b\' and \'c\' will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_REQUIRED_2_METHODDEF \ + {"depr_kwd_required_2", _PyCFunction_CAST(depr_kwd_required_2), METH_FASTCALL|METH_KEYWORDS, depr_kwd_required_2__doc__}, + +static PyObject * +depr_kwd_required_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_required_2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_required_2'.") +# else +# warning "Update the clinic input of 'depr_kwd_required_2'." +# endif +#endif + +static PyObject * +depr_kwd_required_2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_required_2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *a; + PyObject *b; + PyObject *c; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to depr_kwd_required_2() " + "is deprecated. Parameters 'b' and 'c' will become " + "positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + c = args[2]; + return_value = depr_kwd_required_2_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_optional_1__doc__, +"depr_kwd_optional_1($module, a, /, b=None)\n" +"--\n" +"\n" +"Note: Passing keyword argument \'b\' to depr_kwd_optional_1() is\n" +"deprecated. Parameter \'b\' will become positional-only in Python 3.14.\n" +""); + +#define DEPR_KWD_OPTIONAL_1_METHODDEF \ + {"depr_kwd_optional_1", _PyCFunction_CAST(depr_kwd_optional_1), METH_FASTCALL|METH_KEYWORDS, depr_kwd_optional_1__doc__}, + +static PyObject * +depr_kwd_optional_1_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_optional_1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_optional_1'.") +# else +# warning "Update the clinic input of 'depr_kwd_optional_1'." +# endif +#endif + +static PyObject * +depr_kwd_optional_1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_optional_1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && nargs < 2 && args[1]) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'b' to depr_kwd_optional_1() is " + "deprecated. Parameter 'b' will become positional-only in Python " + "3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + b = args[1]; +skip_optional_pos: + return_value = depr_kwd_optional_1_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_optional_2__doc__, +"depr_kwd_optional_2($module, a, /, b=None, c=None)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to depr_kwd_optional_2()\n" +"is deprecated. Parameters \'b\' and \'c\' will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_OPTIONAL_2_METHODDEF \ + {"depr_kwd_optional_2", _PyCFunction_CAST(depr_kwd_optional_2), METH_FASTCALL|METH_KEYWORDS, depr_kwd_optional_2__doc__}, + +static PyObject * +depr_kwd_optional_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_optional_2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_optional_2'.") +# else +# warning "Update the clinic input of 'depr_kwd_optional_2'." +# endif +#endif + +static PyObject * +depr_kwd_optional_2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_optional_2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 2 && args[1]) || (nargs < 3 && args[2]))) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to depr_kwd_optional_2() " + "is deprecated. Parameters 'b' and 'c' will become " + "positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + b = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + c = args[2]; +skip_optional_pos: + return_value = depr_kwd_optional_2_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_optional_3__doc__, +"depr_kwd_optional_3($module, /, a=None, b=None, c=None)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'a\', \'b\' and \'c\' to\n" +"depr_kwd_optional_3() is deprecated. Parameters \'a\', \'b\' and \'c\' will\n" +"become positional-only in Python 3.14.\n" +""); + +#define DEPR_KWD_OPTIONAL_3_METHODDEF \ + {"depr_kwd_optional_3", _PyCFunction_CAST(depr_kwd_optional_3), METH_FASTCALL|METH_KEYWORDS, depr_kwd_optional_3__doc__}, + +static PyObject * +depr_kwd_optional_3_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_optional_3'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_optional_3'.") +# else +# warning "Update the clinic input of 'depr_kwd_optional_3'." +# endif +#endif + +static PyObject * +depr_kwd_optional_3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_optional_3", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *a = Py_None; + PyObject *b = Py_None; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 1 && args[0]) || (nargs < 2 && args[1]) || (nargs < 3 && args[2]))) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'a', 'b' and 'c' to " + "depr_kwd_optional_3() is deprecated. Parameters 'a', 'b' and 'c'" + " will become positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + a = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[1]) { + b = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + c = args[2]; +skip_optional_pos: + return_value = depr_kwd_optional_3_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_required_optional__doc__, +"depr_kwd_required_optional($module, a, /, b, c=None)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to\n" +"depr_kwd_required_optional() is deprecated. Parameters \'b\' and \'c\'\n" +"will become positional-only in Python 3.14.\n" +""); + +#define DEPR_KWD_REQUIRED_OPTIONAL_METHODDEF \ + {"depr_kwd_required_optional", _PyCFunction_CAST(depr_kwd_required_optional), METH_FASTCALL|METH_KEYWORDS, depr_kwd_required_optional__doc__}, + +static PyObject * +depr_kwd_required_optional_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_required_optional'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_required_optional'.") +# else +# warning "Update the clinic input of 'depr_kwd_required_optional'." +# endif +#endif + +static PyObject * +depr_kwd_required_optional(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_required_optional", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 2) || (nargs < 3 && args[2]))) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to " + "depr_kwd_required_optional() is deprecated. Parameters 'b' and " + "'c' will become positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + c = args[2]; +skip_optional_pos: + return_value = depr_kwd_required_optional_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_noinline__doc__, +"depr_kwd_noinline($module, a, /, b, c=None, d=\'\')\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to depr_kwd_noinline() is\n" +"deprecated. Parameters \'b\' and \'c\' will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_NOINLINE_METHODDEF \ + {"depr_kwd_noinline", _PyCFunction_CAST(depr_kwd_noinline), METH_FASTCALL|METH_KEYWORDS, depr_kwd_noinline__doc__}, + +static PyObject * +depr_kwd_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_noinline'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_noinline'.") +# else +# warning "Update the clinic input of 'depr_kwd_noinline'." +# endif +#endif + +static PyObject * +depr_kwd_noinline(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|Os#:depr_kwd_noinline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 2) || (nargs < 3 && PySequence_Contains(kwnames, &_Py_ID(c))))) { + if (PyErr_Occurred()) { // PySequence_Contains() above can fail + goto exit; + } + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to depr_kwd_noinline() is " + "deprecated. Parameters 'b' and 'c' will become positional-only " + "in Python 3.14.", 1)) + { + goto exit; + } + } + return_value = depr_kwd_noinline_impl(module, a, b, c, d, d_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_multi__doc__, +"depr_kwd_multi($module, a, /, b, c, d, e, f, g, h)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\', \'c\', \'d\', \'e\', \'f\' and \'g\' to\n" +"depr_kwd_multi() is deprecated. Parameter \'b\' will become positional-\n" +"only in Python 3.14. Parameters \'c\' and \'d\' will become positional-\n" +"only in Python 3.15. Parameters \'e\', \'f\' and \'g\' will become\n" +"positional-only in Python 3.16.\n" +""); + +#define DEPR_KWD_MULTI_METHODDEF \ + {"depr_kwd_multi", _PyCFunction_CAST(depr_kwd_multi), METH_FASTCALL|METH_KEYWORDS, depr_kwd_multi__doc__}, + +static PyObject * +depr_kwd_multi_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyObject *d, PyObject *e, PyObject *f, PyObject *g, + PyObject *h); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_multi'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_multi'.") +# else +# warning "Update the clinic input of 'depr_kwd_multi'." +# endif +#endif + +static PyObject * +depr_kwd_multi(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), &_Py_ID(f), &_Py_ID(g), &_Py_ID(h), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", "e", "f", "g", "h", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_multi", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[8]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + PyObject *e; + PyObject *f; + PyObject *g; + PyObject *h; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 8, 8, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 7) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b', 'c', 'd', 'e', 'f' and 'g' to " + "depr_kwd_multi() is deprecated. Parameter 'b' will become " + "positional-only in Python 3.14. Parameters 'c' and 'd' will " + "become positional-only in Python 3.15. Parameters 'e', 'f' and " + "'g' will become positional-only in Python 3.16.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + e = args[4]; + f = args[5]; + g = args[6]; + h = args[7]; + return_value = depr_kwd_multi_impl(module, a, b, c, d, e, f, g, h); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_multi__doc__, +"depr_multi($module, a, /, b, c, d, e, f, *, g)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to depr_multi() is\n" +"deprecated. Parameter \'b\' will become positional-only in Python 3.14.\n" +"Parameter \'c\' will become positional-only in Python 3.15.\n" +"\n" +"\n" +"Note: Passing more than 4 positional arguments to depr_multi() is\n" +"deprecated. Parameter \'e\' will become a keyword-only parameter in\n" +"Python 3.15. Parameter \'f\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_MULTI_METHODDEF \ + {"depr_multi", _PyCFunction_CAST(depr_multi), METH_FASTCALL|METH_KEYWORDS, depr_multi__doc__}, + +static PyObject * +depr_multi_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyObject *d, PyObject *e, PyObject *f, PyObject *g); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_multi'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_multi'.") +# else +# warning "Update the clinic input of 'depr_multi'." +# endif +#endif + +static PyObject * +depr_multi(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), &_Py_ID(f), &_Py_ID(g), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", "e", "f", "g", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_multi", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[7]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + PyObject *e; + PyObject *f; + PyObject *g; + + if (nargs > 4 && nargs <= 6) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 4 positional arguments to depr_multi() is " + "deprecated. Parameter 'e' will become a keyword-only parameter " + "in Python 3.15. Parameter 'f' will become a keyword-only " + "parameter in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 6, 6, 1, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to depr_multi() is " + "deprecated. Parameter 'b' will become positional-only in Python " + "3.14. Parameter 'c' will become positional-only in Python 3.15.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + e = args[4]; + f = args[5]; + g = args[6]; + return_value = depr_multi_impl(module, a, b, c, d, e, f, g); + +exit: + return return_value; +} +/*[clinic end generated code: output=689b1e2d0872e413 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic_limited.c.h b/Modules/clinic/_testclinic_limited.c.h new file mode 100644 index 00000000000000..eff72cee24975c --- /dev/null +++ b/Modules/clinic/_testclinic_limited.c.h @@ -0,0 +1,94 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(test_empty_function__doc__, +"test_empty_function($module, /)\n" +"--\n" +"\n"); + +#define TEST_EMPTY_FUNCTION_METHODDEF \ + {"test_empty_function", (PyCFunction)test_empty_function, METH_NOARGS, test_empty_function__doc__}, + +static PyObject * +test_empty_function_impl(PyObject *module); + +static PyObject * +test_empty_function(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return test_empty_function_impl(module); +} + +PyDoc_STRVAR(my_int_func__doc__, +"my_int_func($module, arg, /)\n" +"--\n" +"\n"); + +#define MY_INT_FUNC_METHODDEF \ + {"my_int_func", (PyCFunction)my_int_func, METH_O, my_int_func__doc__}, + +static int +my_int_func_impl(PyObject *module, int arg); + +static PyObject * +my_int_func(PyObject *module, PyObject *arg_) +{ + PyObject *return_value = NULL; + int arg; + int _return_value; + + arg = PyLong_AsInt(arg_); + if (arg == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = my_int_func_impl(module, arg); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(my_int_sum__doc__, +"my_int_sum($module, x, y, /)\n" +"--\n" +"\n"); + +#define MY_INT_SUM_METHODDEF \ + {"my_int_sum", (PyCFunction)(void(*)(void))my_int_sum, METH_FASTCALL, my_int_sum__doc__}, + +static int +my_int_sum_impl(PyObject *module, int x, int y); + +static PyObject * +my_int_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int x; + int y; + int _return_value; + + if (nargs != 2) { + PyErr_Format(PyExc_TypeError, "my_int_sum expected 2 arguments, got %zd", nargs); + goto exit; + } + x = PyLong_AsInt(args[0]); + if (x == -1 && PyErr_Occurred()) { + goto exit; + } + y = PyLong_AsInt(args[1]); + if (y == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = my_int_sum_impl(module, x, y); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=5cf64baf978d2288 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testinternalcapi.c.h b/Modules/clinic/_testinternalcapi.c.h index 9419dcd751a0e9..c1b42672e13d53 100644 --- a/Modules/clinic/_testinternalcapi.c.h +++ b/Modules/clinic/_testinternalcapi.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_testinternalcapi_compiler_cleandoc__doc__, "compiler_cleandoc($module, /, doc)\n" "--\n" @@ -123,14 +122,14 @@ _testinternalcapi_compiler_codegen(PyObject *module, PyObject *const *args, Py_s } ast = args[0]; filename = args[1]; - optimize = _PyLong_AsInt(args[2]); + optimize = PyLong_AsInt(args[2]); if (optimize == -1 && PyErr_Occurred()) { goto exit; } if (!noptargs) { goto skip_optional_pos; } - compile_mode = _PyLong_AsInt(args[3]); + compile_mode = PyLong_AsInt(args[3]); if (compile_mode == -1 && PyErr_Occurred()) { goto exit; } @@ -194,7 +193,7 @@ _testinternalcapi_optimize_cfg(PyObject *module, PyObject *const *args, Py_ssize } instructions = args[0]; consts = args[1]; - nlocals = _PyLong_AsInt(args[2]); + nlocals = PyLong_AsInt(args[2]); if (nlocals == -1 && PyErr_Occurred()) { goto exit; } @@ -265,4 +264,53 @@ _testinternalcapi_assemble_code_object(PyObject *module, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=811d50772c8f285a input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_testinternalcapi_write_unraisable_exc__doc__, +"write_unraisable_exc($module, exception, err_msg, obj, /)\n" +"--\n" +"\n"); + +#define _TESTINTERNALCAPI_WRITE_UNRAISABLE_EXC_METHODDEF \ + {"write_unraisable_exc", _PyCFunction_CAST(_testinternalcapi_write_unraisable_exc), METH_FASTCALL, _testinternalcapi_write_unraisable_exc__doc__}, + +static PyObject * +_testinternalcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, + PyObject *err_msg, PyObject *obj); + +static PyObject * +_testinternalcapi_write_unraisable_exc(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + PyObject *err_msg; + PyObject *obj; + + if (!_PyArg_CheckPositional("write_unraisable_exc", nargs, 3, 3)) { + goto exit; + } + exc = args[0]; + err_msg = args[1]; + obj = args[2]; + return_value = _testinternalcapi_write_unraisable_exc_impl(module, exc, err_msg, obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testinternalcapi_test_long_numbits__doc__, +"test_long_numbits($module, /)\n" +"--\n" +"\n"); + +#define _TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF \ + {"test_long_numbits", (PyCFunction)_testinternalcapi_test_long_numbits, METH_NOARGS, _testinternalcapi_test_long_numbits__doc__}, + +static PyObject * +_testinternalcapi_test_long_numbits_impl(PyObject *module); + +static PyObject * +_testinternalcapi_test_long_numbits(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _testinternalcapi_test_long_numbits_impl(module); +} +/*[clinic end generated code: output=59144f59957627bd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index 42ec7475e5e4be..a96d20bf33ea03 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_testmultiphase_StateAccessType_get_defining_module__doc__, "get_defining_module($self, /)\n" "--\n" @@ -117,7 +116,7 @@ _testmultiphase_StateAccessType_increment_count_clinic(StateAccessTypeObject *se goto skip_optional_pos; } if (args[0]) { - n = _PyLong_AsInt(args[0]); + n = PyLong_AsInt(args[0]); if (n == -1 && PyErr_Occurred()) { goto exit; } @@ -162,4 +161,4 @@ _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObj } return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=52ea97ab2f03bb6d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=db1fdd15244ee59c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 96c6ee26f426c3..fcfc406238808b 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_tkinter_tkapp_eval__doc__, "eval($self, script, /)\n" "--\n" @@ -432,7 +426,7 @@ _tkinter_tkapp_createfilehandler(TkappObject *self, PyObject *const *args, Py_ss goto exit; } file = args[0]; - mask = _PyLong_AsInt(args[1]); + mask = PyLong_AsInt(args[1]); if (mask == -1 && PyErr_Occurred()) { goto exit; } @@ -496,7 +490,7 @@ _tkinter_tkapp_createtimerhandler(TkappObject *self, PyObject *const *args, Py_s if (!_PyArg_CheckPositional("createtimerhandler", nargs, 2, 2)) { goto exit; } - milliseconds = _PyLong_AsInt(args[0]); + milliseconds = PyLong_AsInt(args[0]); if (milliseconds == -1 && PyErr_Occurred()) { goto exit; } @@ -530,7 +524,7 @@ _tkinter_tkapp_mainloop(TkappObject *self, PyObject *const *args, Py_ssize_t nar if (nargs < 1) { goto skip_optional; } - threshold = _PyLong_AsInt(args[0]); + threshold = PyLong_AsInt(args[0]); if (threshold == -1 && PyErr_Occurred()) { goto exit; } @@ -564,7 +558,7 @@ _tkinter_tkapp_dooneevent(TkappObject *self, PyObject *const *args, Py_ssize_t n if (nargs < 1) { goto skip_optional; } - flags = _PyLong_AsInt(args[0]); + flags = PyLong_AsInt(args[0]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -820,7 +814,7 @@ _tkinter_setbusywaitinterval(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int new_val; - new_val = _PyLong_AsInt(arg); + new_val = PyLong_AsInt(arg); if (new_val == -1 && PyErr_Occurred()) { goto exit; } @@ -865,4 +859,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=2a4e3bf8448604b5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bcd9cdc8f6bdcfae input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tracemalloc.c.h b/Modules/clinic/_tracemalloc.c.h index a89cd9aabca8d6..c07ad797d6295b 100644 --- a/Modules/clinic/_tracemalloc.c.h +++ b/Modules/clinic/_tracemalloc.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, "is_tracing($module, /)\n" "--\n" @@ -107,7 +101,7 @@ _tracemalloc_start(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - nframe = _PyLong_AsInt(args[0]); + nframe = PyLong_AsInt(args[0]); if (nframe == -1 && PyErr_Occurred()) { goto exit; } @@ -218,4 +212,4 @@ _tracemalloc_reset_peak(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _tracemalloc_reset_peak_impl(module); } -/*[clinic end generated code: output=44e3f8553aae2535 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ad7d1fae89f2bdaa input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_typingmodule.c.h b/Modules/clinic/_typingmodule.c.h index f980aa0d0844da..ea415e67153ed8 100644 --- a/Modules/clinic/_typingmodule.c.h +++ b/Modules/clinic/_typingmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_typing__idfunc__doc__, "_idfunc($module, x, /)\n" "--\n" @@ -15,4 +9,4 @@ PyDoc_STRVAR(_typing__idfunc__doc__, #define _TYPING__IDFUNC_METHODDEF \ {"_idfunc", (PyCFunction)_typing__idfunc, METH_O, _typing__idfunc__doc__}, -/*[clinic end generated code: output=97457fda45072c7d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e7ea2a3cb7ab301a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index 48feb042cac039..541cba75e6813c 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_weakref_getweakrefcount__doc__, "getweakrefcount($module, object, /)\n" "--\n" @@ -116,4 +110,4 @@ _weakref_proxy(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=28265e89d583273d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f4be6b8177fbceb8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 8f46b8f1095e98..7fef127bef8606 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_long.h" // _PyLong_Size_t_Converter() PyDoc_STRVAR(_winapi_Overlapped_GetOverlappedResult__doc__, "GetOverlappedResult($self, wait, /)\n" @@ -884,7 +884,7 @@ PyDoc_STRVAR(_winapi_LCMapStringEx__doc__, static PyObject * _winapi_LCMapStringEx_impl(PyObject *module, LPCWSTR locale, DWORD flags, - LPCWSTR src); + PyObject *src); static PyObject * _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -911,16 +911,16 @@ _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, static const char * const _keywords[] = {"locale", "flags", "src", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .format = "O&kO&:LCMapStringEx", + .format = "O&kU:LCMapStringEx", .kwtuple = KWTUPLE, }; #undef KWTUPLE LPCWSTR locale = NULL; DWORD flags; - LPCWSTR src = NULL; + PyObject *src; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - _PyUnicode_WideCharString_Converter, &locale, &flags, _PyUnicode_WideCharString_Converter, &src)) { + _PyUnicode_WideCharString_Converter, &locale, &flags, &src)) { goto exit; } return_value = _winapi_LCMapStringEx_impl(module, locale, flags, src); @@ -928,8 +928,6 @@ _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: /* Cleanup for locale */ PyMem_Free((void *)locale); - /* Cleanup for src */ - PyMem_Free((void *)src); return return_value; } @@ -1480,4 +1478,4 @@ _winapi_CopyFile2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO return return_value; } -/*[clinic end generated code: output=f32fe6ecdbffd74d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6df38b5eb93f2e5a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_zoneinfo.c.h b/Modules/clinic/_zoneinfo.c.h index ae62865e0f67df..6691d39deb7c24 100644 --- a/Modules/clinic/_zoneinfo.c.h +++ b/Modules/clinic/_zoneinfo.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(zoneinfo_ZoneInfo_from_file__doc__, "from_file($type, file_obj, /, key=None)\n" "--\n" @@ -372,4 +371,4 @@ zoneinfo_ZoneInfo__unpickle(PyTypeObject *type, PyTypeObject *cls, PyObject *con exit: return return_value; } -/*[clinic end generated code: output=54051388dfc408af input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a5384f79d49a593b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 600931835ecac1..2a874b8c830609 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -2,11 +2,7 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(array_array___copy____doc__, "__copy__($self, /)\n" @@ -589,7 +585,7 @@ array__array_reconstructor(PyObject *module, PyObject *const *args, Py_ssize_t n goto exit; } typecode = PyUnicode_READ_CHAR(args[1], 0); - mformat_code = _PyLong_AsInt(args[2]); + mformat_code = PyLong_AsInt(args[2]); if (mformat_code == -1 && PyErr_Occurred()) { goto exit; } @@ -674,4 +670,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=11595e9f38d6d500 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8595b1906b5a6552 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index 63566dfb10e74f..d80decf145bfdc 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(binascii_a2b_uu__doc__, "a2b_uu($module, data, /)\n" "--\n" @@ -448,7 +447,7 @@ binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } } - bytes_per_sep = _PyLong_AsInt(args[2]); + bytes_per_sep = PyLong_AsInt(args[2]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; } @@ -541,7 +540,7 @@ binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } } - bytes_per_sep = _PyLong_AsInt(args[2]); + bytes_per_sep = PyLong_AsInt(args[2]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; } @@ -795,4 +794,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -/*[clinic end generated code: output=ab156917c9db79d2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=acc9419209dfd568 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index 941448e76e80de..a665ac3c1c4994 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(cmath_acos__doc__, "acos($module, z, /)\n" "--\n" @@ -982,4 +981,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=87f609786ef270cd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=96a5c4ae198dd5bf input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index 20eb50b0e76b38..83e882bbbaf184 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -2,11 +2,7 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - +#include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() PyDoc_STRVAR(fcntl_fcntl__doc__, "fcntl($module, fd, cmd, arg=0, /)\n" @@ -44,7 +40,7 @@ fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } - code = _PyLong_AsInt(args[1]); + code = PyLong_AsInt(args[1]); if (code == -1 && PyErr_Occurred()) { goto exit; } @@ -164,7 +160,7 @@ fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } - code = _PyLong_AsInt(args[1]); + code = PyLong_AsInt(args[1]); if (code == -1 && PyErr_Occurred()) { goto exit; } @@ -224,7 +220,7 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } - code = _PyLong_AsInt(args[1]); + code = PyLong_AsInt(args[1]); if (code == -1 && PyErr_Occurred()) { goto exit; } @@ -239,7 +235,7 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 5) { goto skip_optional; } - whence = _PyLong_AsInt(args[4]); + whence = PyLong_AsInt(args[4]); if (whence == -1 && PyErr_Occurred()) { goto exit; } @@ -249,4 +245,4 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=1db859412172dd53 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4d4fac195494faec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index 2d18e2ee0978e0..40448404877e3e 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() PyDoc_STRVAR(gc_enable__doc__, "enable($module, /)\n" @@ -131,7 +131,7 @@ gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * if (!noptargs) { goto skip_optional_pos; } - generation = _PyLong_AsInt(args[0]); + generation = PyLong_AsInt(args[0]); if (generation == -1 && PyErr_Occurred()) { goto exit; } @@ -175,7 +175,7 @@ gc_set_debug(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flags; - flags = _PyLong_AsInt(arg); + flags = PyLong_AsInt(arg); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -424,4 +424,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=66432ac0e17fd04f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=63093e7724b94a37 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index 38de3ce68ceb7f..e6c9cccfce4a76 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(grp_getgrgid__doc__, "getgrgid($module, /, id)\n" "--\n" @@ -146,4 +145,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=e685227ed5d9be9f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d4bdad9b26fb8558 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index 32278bf715aa98..74cd3ddc3c9a86 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(batched_new__doc__, "batched(iterable, n)\n" @@ -913,4 +913,4 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=111cbd102c2a23c9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=95bb863274717bd9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index c16c1b083985f2..bfce397be77c8b 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(math_ceil__doc__, "ceil($module, x, /)\n" "--\n" @@ -950,4 +949,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=91a0357265a2a553 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=da62cea7eb3dc8bc input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index b4602104f18042..6087a0f9c25c1a 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(MD5Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -148,4 +147,4 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=b4924c9905cc9f34 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=943d42b9d17d9a5b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 89928312211b60..9a71e25aa557a4 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_long.h" // _PyLong_UnsignedLong_Converter() PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, "CreateIoCompletionPort($module, handle, port, key, concurrency, /)\n" @@ -288,11 +288,11 @@ _overlapped_CreateEvent(PyObject *module, PyObject *const *args, Py_ssize_t narg goto exit; } EventAttributes = args[0]; - ManualReset = _PyLong_AsInt(args[1]); + ManualReset = PyLong_AsInt(args[1]); if (ManualReset == -1 && PyErr_Occurred()) { goto exit; } - InitialState = _PyLong_AsInt(args[2]); + InitialState = PyLong_AsInt(args[2]); if (InitialState == -1 && PyErr_Occurred()) { goto exit; } @@ -402,7 +402,7 @@ _overlapped_BindLocal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!Socket && PyErr_Occurred()) { goto exit; } - Family = _PyLong_AsInt(args[1]); + Family = PyLong_AsInt(args[1]); if (Family == -1 && PyErr_Occurred()) { goto exit; } @@ -546,7 +546,7 @@ _overlapped_Overlapped_getresult(OverlappedObject *self, PyObject *const *args, if (nargs < 1) { goto skip_optional; } - wait = _PyLong_AsInt(args[0]); + wait = PyLong_AsInt(args[0]); if (wait == -1 && PyErr_Occurred()) { goto exit; } @@ -1262,4 +1262,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=05fd038b8a81272d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=31bcc780209593a2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index a8f6ce026a331b..179132754f9aeb 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -3,10 +3,12 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() +#include "pycore_long.h" // _PyLong_UnsignedInt_Converter() PyDoc_STRVAR(os_stat__doc__, "stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" @@ -262,7 +264,7 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!path_converter(args[0], &path)) { goto exit; } - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -327,7 +329,7 @@ os_ttyname(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -568,7 +570,7 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!path_converter(args[0], &path)) { goto exit; } - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -658,11 +660,11 @@ os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!args) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -731,7 +733,7 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!path_converter(args[0], &path)) { goto exit; } - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -1284,7 +1286,7 @@ os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!args) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -1846,6 +1848,40 @@ os__getfinalpathname(PyObject *module, PyObject *arg) #if defined(MS_WINDOWS) +PyDoc_STRVAR(os__findfirstfile__doc__, +"_findfirstfile($module, path, /)\n" +"--\n" +"\n" +"A function to get the real file name without accessing the file in Windows."); + +#define OS__FINDFIRSTFILE_METHODDEF \ + {"_findfirstfile", (PyCFunction)os__findfirstfile, METH_O, os__findfirstfile__doc__}, + +static PyObject * +os__findfirstfile_impl(PyObject *module, path_t *path); + +static PyObject * +os__findfirstfile(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0); + + if (!path_converter(arg, &path)) { + goto exit; + } + return_value = os__findfirstfile_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + PyDoc_STRVAR(os__getvolumepathname__doc__, "_getvolumepathname($module, /, path)\n" "--\n" @@ -1975,7 +2011,7 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py #if defined(MS_WINDOWS) PyDoc_STRVAR(os__path_isdir__doc__, -"_path_isdir($module, /, path)\n" +"_path_isdir($module, /, s)\n" "--\n" "\n" "Return true if the pathname refers to an existing directory."); @@ -1984,7 +2020,7 @@ PyDoc_STRVAR(os__path_isdir__doc__, {"_path_isdir", _PyCFunction_CAST(os__path_isdir), METH_FASTCALL|METH_KEYWORDS, os__path_isdir__doc__}, static PyObject * -os__path_isdir_impl(PyObject *module, PyObject *path); +os__path_isdir_impl(PyObject *module, PyObject *s); static PyObject * os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -1999,7 +2035,7 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *ob_item[NUM_KEYWORDS]; } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(path), }, + .ob_item = { &_Py_ID(s), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -2008,7 +2044,7 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"path", NULL}; + static const char * const _keywords[] = {"s", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "_path_isdir", @@ -2016,14 +2052,14 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + PyObject *s; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_isdir_impl(module, path); + s = args[0]; + return_value = os__path_isdir_impl(module, s); exit: return return_value; @@ -2329,7 +2365,7 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto skip_optional_pos; } if (args[1]) { - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -2374,7 +2410,7 @@ os_nice(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int increment; - increment = _PyLong_AsInt(arg); + increment = PyLong_AsInt(arg); if (increment == -1 && PyErr_Occurred()) { goto exit; } @@ -2437,11 +2473,11 @@ os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - which = _PyLong_AsInt(args[0]); + which = PyLong_AsInt(args[0]); if (which == -1 && PyErr_Occurred()) { goto exit; } - who = _PyLong_AsInt(args[1]); + who = PyLong_AsInt(args[1]); if (who == -1 && PyErr_Occurred()) { goto exit; } @@ -2505,15 +2541,15 @@ os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - which = _PyLong_AsInt(args[0]); + which = PyLong_AsInt(args[0]); if (which == -1 && PyErr_Occurred()) { goto exit; } - who = _PyLong_AsInt(args[1]); + who = PyLong_AsInt(args[1]); if (who == -1 && PyErr_Occurred()) { goto exit; } - priority = _PyLong_AsInt(args[2]); + priority = PyLong_AsInt(args[2]); if (priority == -1 && PyErr_Occurred()) { goto exit; } @@ -2944,7 +2980,7 @@ os_umask(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int mask; - mask = _PyLong_AsInt(arg); + mask = PyLong_AsInt(arg); if (mask == -1 && PyErr_Occurred()) { goto exit; } @@ -3298,7 +3334,7 @@ os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -3759,7 +3795,7 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { goto exit; } - mode = _PyLong_AsInt(args[0]); + mode = PyLong_AsInt(args[0]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -3814,7 +3850,7 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("spawnve", nargs, 4, 4)) { goto exit; } - mode = _PyLong_AsInt(args[0]); + mode = PyLong_AsInt(args[0]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -4023,7 +4059,7 @@ os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t na if (!args) { goto exit; } - policy = _PyLong_AsInt(args[0]); + policy = PyLong_AsInt(args[0]); if (policy == -1 && PyErr_Occurred()) { goto exit; } @@ -4085,7 +4121,7 @@ os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t na if (!args) { goto exit; } - policy = _PyLong_AsInt(args[0]); + policy = PyLong_AsInt(args[0]); if (policy == -1 && PyErr_Occurred()) { goto exit; } @@ -4644,7 +4680,7 @@ os_getgrouplist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - basegid = _PyLong_AsInt(args[1]); + basegid = PyLong_AsInt(args[1]); if (basegid == -1 && PyErr_Occurred()) { goto exit; } @@ -4762,7 +4798,7 @@ os_initgroups(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!PyUnicode_FSConverter(args[0], &oname)) { goto exit; } - gid = _PyLong_AsInt(args[1]); + gid = PyLong_AsInt(args[1]); if (gid == -1 && PyErr_Occurred()) { goto exit; } @@ -5078,7 +5114,7 @@ os_plock(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int op; - op = _PyLong_AsInt(arg); + op = PyLong_AsInt(arg); if (op == -1 && PyErr_Occurred()) { goto exit; } @@ -5356,7 +5392,7 @@ os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - options = _PyLong_AsInt(args[0]); + options = PyLong_AsInt(args[0]); if (options == -1 && PyErr_Occurred()) { goto exit; } @@ -5699,7 +5735,7 @@ os_setns(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!noptargs) { goto skip_optional_pos; } - nstype = _PyLong_AsInt(args[1]); + nstype = PyLong_AsInt(args[1]); if (nstype == -1 && PyErr_Occurred()) { goto exit; } @@ -5765,7 +5801,7 @@ os_unshare(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * if (!args) { goto exit; } - flags = _PyLong_AsInt(args[0]); + flags = PyLong_AsInt(args[0]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -5986,6 +6022,376 @@ os_times(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(HAVE_TIMES) */ +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_create__doc__, +"timerfd_create($module, clockid, /, *, flags=0)\n" +"--\n" +"\n" +"Create and return a timer file descriptor.\n" +"\n" +" clockid\n" +" A valid clock ID constant as timer file descriptor.\n" +"\n" +" time.CLOCK_REALTIME\n" +" time.CLOCK_MONOTONIC\n" +" time.CLOCK_BOOTTIME\n" +" flags\n" +" 0 or a bit mask of os.TFD_NONBLOCK or os.TFD_CLOEXEC.\n" +"\n" +" os.TFD_NONBLOCK\n" +" If *TFD_NONBLOCK* is set as a flag, read doesn\'t blocks.\n" +" If *TFD_NONBLOCK* is not set as a flag, read block until the timer fires.\n" +"\n" +" os.TFD_CLOEXEC\n" +" If *TFD_CLOEXEC* is set as a flag, enable the close-on-exec flag"); + +#define OS_TIMERFD_CREATE_METHODDEF \ + {"timerfd_create", _PyCFunction_CAST(os_timerfd_create), METH_FASTCALL|METH_KEYWORDS, os_timerfd_create__doc__}, + +static PyObject * +os_timerfd_create_impl(PyObject *module, int clockid, int flags); + +static PyObject * +os_timerfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "timerfd_create", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int clockid; + int flags = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + clockid = PyLong_AsInt(args[0]); + if (clockid == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_kwonly: + return_value = os_timerfd_create_impl(module, clockid, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_settime__doc__, +"timerfd_settime($module, fd, /, *, flags=0, initial=0.0, interval=0.0)\n" +"--\n" +"\n" +"Alter a timer file descriptor\'s internal timer in seconds.\n" +"\n" +" fd\n" +" A timer file descriptor.\n" +" flags\n" +" 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET.\n" +" initial\n" +" The initial expiration time, in seconds.\n" +" interval\n" +" The timer\'s interval, in seconds."); + +#define OS_TIMERFD_SETTIME_METHODDEF \ + {"timerfd_settime", _PyCFunction_CAST(os_timerfd_settime), METH_FASTCALL|METH_KEYWORDS, os_timerfd_settime__doc__}, + +static PyObject * +os_timerfd_settime_impl(PyObject *module, int fd, int flags, double initial, + double interval); + +static PyObject * +os_timerfd_settime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), &_Py_ID(initial), &_Py_ID(interval), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "flags", "initial", "interval", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "timerfd_settime", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int fd; + int flags = 0; + double initial = 0.0; + double interval = 0.0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (PyFloat_CheckExact(args[2])) { + initial = PyFloat_AS_DOUBLE(args[2]); + } + else + { + initial = PyFloat_AsDouble(args[2]); + if (initial == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyFloat_CheckExact(args[3])) { + interval = PyFloat_AS_DOUBLE(args[3]); + } + else + { + interval = PyFloat_AsDouble(args[3]); + if (interval == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +skip_optional_kwonly: + return_value = os_timerfd_settime_impl(module, fd, flags, initial, interval); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_settime_ns__doc__, +"timerfd_settime_ns($module, fd, /, *, flags=0, initial=0, interval=0)\n" +"--\n" +"\n" +"Alter a timer file descriptor\'s internal timer in nanoseconds.\n" +"\n" +" fd\n" +" A timer file descriptor.\n" +" flags\n" +" 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET.\n" +" initial\n" +" initial expiration timing in seconds.\n" +" interval\n" +" interval for the timer in seconds."); + +#define OS_TIMERFD_SETTIME_NS_METHODDEF \ + {"timerfd_settime_ns", _PyCFunction_CAST(os_timerfd_settime_ns), METH_FASTCALL|METH_KEYWORDS, os_timerfd_settime_ns__doc__}, + +static PyObject * +os_timerfd_settime_ns_impl(PyObject *module, int fd, int flags, + long long initial, long long interval); + +static PyObject * +os_timerfd_settime_ns(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), &_Py_ID(initial), &_Py_ID(interval), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "flags", "initial", "interval", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "timerfd_settime_ns", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int fd; + int flags = 0; + long long initial = 0; + long long interval = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + initial = PyLong_AsLongLong(args[2]); + if (initial == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + interval = PyLong_AsLongLong(args[3]); + if (interval == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_kwonly: + return_value = os_timerfd_settime_ns_impl(module, fd, flags, initial, interval); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_gettime__doc__, +"timerfd_gettime($module, fd, /)\n" +"--\n" +"\n" +"Return a tuple of a timer file descriptor\'s (interval, next expiration) in float seconds.\n" +"\n" +" fd\n" +" A timer file descriptor."); + +#define OS_TIMERFD_GETTIME_METHODDEF \ + {"timerfd_gettime", (PyCFunction)os_timerfd_gettime, METH_O, os_timerfd_gettime__doc__}, + +static PyObject * +os_timerfd_gettime_impl(PyObject *module, int fd); + +static PyObject * +os_timerfd_gettime(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = os_timerfd_gettime_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_gettime_ns__doc__, +"timerfd_gettime_ns($module, fd, /)\n" +"--\n" +"\n" +"Return a tuple of a timer file descriptor\'s (interval, next expiration) in nanoseconds.\n" +"\n" +" fd\n" +" A timer file descriptor."); + +#define OS_TIMERFD_GETTIME_NS_METHODDEF \ + {"timerfd_gettime_ns", (PyCFunction)os_timerfd_gettime_ns, METH_O, os_timerfd_gettime_ns__doc__}, + +static PyObject * +os_timerfd_gettime_ns_impl(PyObject *module, int fd); + +static PyObject * +os_timerfd_gettime_ns(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = os_timerfd_gettime_ns_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + #if defined(HAVE_GETSID) PyDoc_STRVAR(os_getsid__doc__, @@ -6092,7 +6498,7 @@ os_tcgetpgrp(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6198,7 +6604,7 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn if (!path_converter(args[0], &path)) { goto exit; } - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -6206,7 +6612,7 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn goto skip_optional_pos; } if (args[2]) { - mode = _PyLong_AsInt(args[2]); + mode = PyLong_AsInt(args[2]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -6283,7 +6689,7 @@ os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6315,11 +6721,11 @@ os_closerange(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("closerange", nargs, 2, 2)) { goto exit; } - fd_low = _PyLong_AsInt(args[0]); + fd_low = PyLong_AsInt(args[0]); if (fd_low == -1 && PyErr_Occurred()) { goto exit; } - fd_high = _PyLong_AsInt(args[1]); + fd_high = PyLong_AsInt(args[1]); if (fd_high == -1 && PyErr_Occurred()) { goto exit; } @@ -6348,7 +6754,7 @@ os_dup(PyObject *module, PyObject *arg) int fd; int _return_value; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6416,11 +6822,11 @@ os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn if (!args) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - fd2 = _PyLong_AsInt(args[1]); + fd2 = PyLong_AsInt(args[1]); if (fd2 == -1 && PyErr_Occurred()) { goto exit; } @@ -6476,11 +6882,11 @@ os_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("lockf", nargs, 3, 3)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - command = _PyLong_AsInt(args[1]); + command = PyLong_AsInt(args[1]); if (command == -1 && PyErr_Occurred()) { goto exit; } @@ -6496,13 +6902,22 @@ os_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #endif /* defined(HAVE_LOCKF) */ PyDoc_STRVAR(os_lseek__doc__, -"lseek($module, fd, position, how, /)\n" +"lseek($module, fd, position, whence, /)\n" "--\n" "\n" "Set the position of a file descriptor. Return the new position.\n" "\n" -"Return the new cursor position in number of bytes\n" -"relative to the beginning of the file."); +" fd\n" +" An open file descriptor, as returned by os.open().\n" +" position\n" +" Position, interpreted relative to \'whence\'.\n" +" whence\n" +" The relative position to seek from. Valid values are:\n" +" - SEEK_SET: seek from the start of the file.\n" +" - SEEK_CUR: seek from the current file position.\n" +" - SEEK_END: seek from the end of the file.\n" +"\n" +"The return value is the number of bytes relative to the beginning of the file."); #define OS_LSEEK_METHODDEF \ {"lseek", _PyCFunction_CAST(os_lseek), METH_FASTCALL, os_lseek__doc__}, @@ -6522,14 +6937,14 @@ os_lseek(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("lseek", nargs, 3, 3)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } if (!Py_off_t_converter(args[1], &position)) { goto exit; } - how = _PyLong_AsInt(args[2]); + how = PyLong_AsInt(args[2]); if (how == -1 && PyErr_Occurred()) { goto exit; } @@ -6565,7 +6980,7 @@ os_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("read", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6620,7 +7035,7 @@ os_readv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("readv", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6665,7 +7080,7 @@ os_pread(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("pread", nargs, 3, 3)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6734,7 +7149,7 @@ os_preadv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("preadv", nargs, 3, 4)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6745,7 +7160,7 @@ os_preadv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - flags = _PyLong_AsInt(args[3]); + flags = PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -6785,7 +7200,7 @@ os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("write", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6871,11 +7286,11 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - out_fd = _PyLong_AsInt(args[0]); + out_fd = PyLong_AsInt(args[0]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - in_fd = _PyLong_AsInt(args[1]); + in_fd = PyLong_AsInt(args[1]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; } @@ -6900,7 +7315,7 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - flags = _PyLong_AsInt(args[6]); + flags = PyLong_AsInt(args[6]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -6973,11 +7388,11 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - out_fd = _PyLong_AsInt(args[0]); + out_fd = PyLong_AsInt(args[0]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - in_fd = _PyLong_AsInt(args[1]); + in_fd = PyLong_AsInt(args[1]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; } @@ -7011,7 +7426,7 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - flags = _PyLong_AsInt(args[6]); + flags = PyLong_AsInt(args[6]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -7078,11 +7493,11 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - out_fd = _PyLong_AsInt(args[0]); + out_fd = PyLong_AsInt(args[0]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - in_fd = _PyLong_AsInt(args[1]); + in_fd = PyLong_AsInt(args[1]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; } @@ -7132,15 +7547,15 @@ os__fcopyfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("_fcopyfile", nargs, 3, 3)) { goto exit; } - in_fd = _PyLong_AsInt(args[0]); + in_fd = PyLong_AsInt(args[0]); if (in_fd == -1 && PyErr_Occurred()) { goto exit; } - out_fd = _PyLong_AsInt(args[1]); + out_fd = PyLong_AsInt(args[1]); if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - flags = _PyLong_AsInt(args[2]); + flags = PyLong_AsInt(args[2]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -7203,7 +7618,7 @@ os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -7235,7 +7650,7 @@ os_isatty(PyObject *module, PyObject *arg) int fd; int _return_value; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -7300,7 +7715,7 @@ os_pipe2(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flags; - flags = _PyLong_AsInt(arg); + flags = PyLong_AsInt(arg); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -7340,7 +7755,7 @@ os_writev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("writev", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -7366,7 +7781,7 @@ PyDoc_STRVAR(os_pwrite__doc__, "Write bytes to a file descriptor starting at a particular offset.\n" "\n" "Write buffer to fd, starting at offset bytes from the beginning of\n" -"the file. Returns the number of bytes writte. Does not change the\n" +"the file. Returns the number of bytes written. Does not change the\n" "current file offset."); #define OS_PWRITE_METHODDEF \ @@ -7387,7 +7802,7 @@ os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("pwrite", nargs, 3, 3)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -7461,7 +7876,7 @@ os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("pwritev", nargs, 3, 4)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -7472,7 +7887,7 @@ os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - flags = _PyLong_AsInt(args[3]); + flags = PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -7560,11 +7975,11 @@ os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - src = _PyLong_AsInt(args[0]); + src = PyLong_AsInt(args[0]); if (src == -1 && PyErr_Occurred()) { goto exit; } - dst = _PyLong_AsInt(args[1]); + dst = PyLong_AsInt(args[1]); if (dst == -1 && PyErr_Occurred()) { goto exit; } @@ -7675,11 +8090,11 @@ os_splice(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!args) { goto exit; } - src = _PyLong_AsInt(args[0]); + src = PyLong_AsInt(args[0]); if (src == -1 && PyErr_Occurred()) { goto exit; } - dst = _PyLong_AsInt(args[1]); + dst = PyLong_AsInt(args[1]); if (dst == -1 && PyErr_Occurred()) { goto exit; } @@ -7787,7 +8202,7 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k goto skip_optional_pos; } if (args[1]) { - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -7888,7 +8303,7 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto skip_optional_pos; } if (args[1]) { - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -8020,11 +8435,11 @@ os_makedev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("makedev", nargs, 2, 2)) { goto exit; } - major = _PyLong_AsInt(args[0]); + major = PyLong_AsInt(args[0]); if (major == -1 && PyErr_Occurred()) { goto exit; } - minor = _PyLong_AsInt(args[1]); + minor = PyLong_AsInt(args[1]); if (minor == -1 && PyErr_Occurred()) { goto exit; } @@ -8064,7 +8479,7 @@ os_ftruncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ftruncate", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -8179,7 +8594,7 @@ os_posix_fallocate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("posix_fallocate", nargs, 3, 3)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -8232,7 +8647,7 @@ os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("posix_fadvise", nargs, 4, 4)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -8242,7 +8657,7 @@ os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!Py_off_t_converter(args[2], &length)) { goto exit; } - advice = _PyLong_AsInt(args[3]); + advice = PyLong_AsInt(args[3]); if (advice == -1 && PyErr_Occurred()) { goto exit; } @@ -8424,7 +8839,7 @@ os_strerror(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int code; - code = _PyLong_AsInt(arg); + code = PyLong_AsInt(arg); if (code == -1 && PyErr_Occurred()) { goto exit; } @@ -8455,7 +8870,7 @@ os_WCOREDUMP(PyObject *module, PyObject *arg) int status; int _return_value; - status = _PyLong_AsInt(arg); + status = PyLong_AsInt(arg); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8525,7 +8940,7 @@ os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8592,7 +9007,7 @@ os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8659,7 +9074,7 @@ os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8726,7 +9141,7 @@ os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8793,7 +9208,7 @@ os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8860,7 +9275,7 @@ os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8927,7 +9342,7 @@ os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - status = _PyLong_AsInt(args[0]); + status = PyLong_AsInt(args[0]); if (status == -1 && PyErr_Occurred()) { goto exit; } @@ -8965,7 +9380,7 @@ os_fstatvfs(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -9442,7 +9857,7 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - show_cmd = _PyLong_AsInt(args[4]); + show_cmd = PyLong_AsInt(args[4]); if (show_cmd == -1 && PyErr_Occurred()) { goto exit; } @@ -9541,7 +9956,7 @@ os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -9844,7 +10259,7 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } if (args[3]) { - flags = _PyLong_AsInt(args[3]); + flags = PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -10220,7 +10635,7 @@ os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * if (!noptargs) { goto skip_optional_pos; } - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -10397,7 +10812,7 @@ os_get_terminal_size(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -10414,11 +10829,9 @@ PyDoc_STRVAR(os_cpu_count__doc__, "cpu_count($module, /)\n" "--\n" "\n" -"Return the number of CPUs in the system; return None if indeterminable.\n" +"Return the number of logical CPUs in the system.\n" "\n" -"This number is not equivalent to the number of CPUs the current process can\n" -"use. The number of usable CPUs can be obtained with\n" -"``len(os.sched_getaffinity(0))``"); +"Return None if indeterminable."); #define OS_CPU_COUNT_METHODDEF \ {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, @@ -10451,7 +10864,7 @@ os_get_inheritable(PyObject *module, PyObject *arg) int fd; int _return_value; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -10487,11 +10900,11 @@ os_set_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("set_inheritable", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - inheritable = _PyLong_AsInt(args[1]); + inheritable = PyLong_AsInt(args[1]); if (inheritable == -1 && PyErr_Occurred()) { goto exit; } @@ -10592,7 +11005,7 @@ os_get_blocking(PyObject *module, PyObject *arg) int fd; int _return_value; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -10631,7 +11044,7 @@ os_set_blocking(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("set_blocking", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -10684,22 +11097,18 @@ PyDoc_STRVAR(os_DirEntry_is_junction__doc__, "Return True if the entry is a junction; cached per entry."); #define OS_DIRENTRY_IS_JUNCTION_METHODDEF \ - {"is_junction", _PyCFunction_CAST(os_DirEntry_is_junction), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_junction__doc__}, + {"is_junction", (PyCFunction)os_DirEntry_is_junction, METH_NOARGS, os_DirEntry_is_junction__doc__}, static int -os_DirEntry_is_junction_impl(DirEntry *self, PyTypeObject *defining_class); +os_DirEntry_is_junction_impl(DirEntry *self); static PyObject * -os_DirEntry_is_junction(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +os_DirEntry_is_junction(DirEntry *self, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; int _return_value; - if (nargs) { - PyErr_SetString(PyExc_TypeError, "is_junction() takes no arguments"); - goto exit; - } - _return_value = os_DirEntry_is_junction_impl(self, defining_class); + _return_value = os_DirEntry_is_junction_impl(self); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } @@ -11144,7 +11553,7 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!noptargs) { goto skip_optional_pos; } - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -11446,6 +11855,10 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #define OS__GETFINALPATHNAME_METHODDEF #endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */ +#ifndef OS__FINDFIRSTFILE_METHODDEF + #define OS__FINDFIRSTFILE_METHODDEF +#endif /* !defined(OS__FINDFIRSTFILE_METHODDEF) */ + #ifndef OS__GETVOLUMEPATHNAME_METHODDEF #define OS__GETVOLUMEPATHNAME_METHODDEF #endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */ @@ -11718,6 +12131,26 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #define OS_TIMES_METHODDEF #endif /* !defined(OS_TIMES_METHODDEF) */ +#ifndef OS_TIMERFD_CREATE_METHODDEF + #define OS_TIMERFD_CREATE_METHODDEF +#endif /* !defined(OS_TIMERFD_CREATE_METHODDEF) */ + +#ifndef OS_TIMERFD_SETTIME_METHODDEF + #define OS_TIMERFD_SETTIME_METHODDEF +#endif /* !defined(OS_TIMERFD_SETTIME_METHODDEF) */ + +#ifndef OS_TIMERFD_SETTIME_NS_METHODDEF + #define OS_TIMERFD_SETTIME_NS_METHODDEF +#endif /* !defined(OS_TIMERFD_SETTIME_NS_METHODDEF) */ + +#ifndef OS_TIMERFD_GETTIME_METHODDEF + #define OS_TIMERFD_GETTIME_METHODDEF +#endif /* !defined(OS_TIMERFD_GETTIME_METHODDEF) */ + +#ifndef OS_TIMERFD_GETTIME_NS_METHODDEF + #define OS_TIMERFD_GETTIME_NS_METHODDEF +#endif /* !defined(OS_TIMERFD_GETTIME_NS_METHODDEF) */ + #ifndef OS_GETSID_METHODDEF #define OS_GETSID_METHODDEF #endif /* !defined(OS_GETSID_METHODDEF) */ @@ -11981,4 +12414,4 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=a7e8c3df2db09717 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7c3058135ed49d20 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h index 748c873b1c8a45..0e8aa5e6a9f470 100644 --- a/Modules/clinic/pwdmodule.c.h +++ b/Modules/clinic/pwdmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(pwd_getpwuid__doc__, "getpwuid($module, uidobj, /)\n" "--\n" @@ -77,4 +71,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=1edf1e26cd2762db input=a9049054013a1b77]*/ +/*[clinic end generated code: output=211c7a2516899b91 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index 34937c5d594f5c..21b09110d00853 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, "Parse($self, data, isfinal=False, /)\n" "--\n" @@ -288,7 +287,7 @@ pyexpat_xmlparser_SetParamEntityParsing(xmlparseobject *self, PyObject *arg) PyObject *return_value = NULL; int flag; - flag = _PyLong_AsInt(arg); + flag = PyLong_AsInt(arg); if (flag == -1 && PyErr_Occurred()) { goto exit; } @@ -498,4 +497,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=63efc62e24a7b5a7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ac398d94833e802d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/readline.c.h b/Modules/clinic/readline.c.h index 83d93ef7e7b4f1..e5a784a5f79e5a 100644 --- a/Modules/clinic/readline.c.h +++ b/Modules/clinic/readline.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(readline_parse_and_bind__doc__, "parse_and_bind($module, string, /)\n" "--\n" @@ -146,7 +140,7 @@ readline_append_history_file(PyObject *module, PyObject *const *args, Py_ssize_t if (!_PyArg_CheckPositional("append_history_file", nargs, 1, 2)) { goto exit; } - nelements = _PyLong_AsInt(args[0]); + nelements = PyLong_AsInt(args[0]); if (nelements == -1 && PyErr_Occurred()) { goto exit; } @@ -183,7 +177,7 @@ readline_set_history_length(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int length; - length = _PyLong_AsInt(arg); + length = PyLong_AsInt(arg); if (length == -1 && PyErr_Occurred()) { goto exit; } @@ -404,7 +398,7 @@ readline_remove_history_item(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int entry_number; - entry_number = _PyLong_AsInt(arg); + entry_number = PyLong_AsInt(arg); if (entry_number == -1 && PyErr_Occurred()) { goto exit; } @@ -439,7 +433,7 @@ readline_replace_history_item(PyObject *module, PyObject *const *args, Py_ssize_ if (!_PyArg_CheckPositional("replace_history_item", nargs, 2, 2)) { goto exit; } - entry_number = _PyLong_AsInt(args[0]); + entry_number = PyLong_AsInt(args[0]); if (entry_number == -1 && PyErr_Occurred()) { goto exit; } @@ -582,7 +576,7 @@ readline_get_history_item(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int idx; - idx = _PyLong_AsInt(arg); + idx = PyLong_AsInt(arg); if (idx == -1 && PyErr_Occurred()) { goto exit; } @@ -688,4 +682,4 @@ readline_redisplay(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef READLINE_CLEAR_HISTORY_METHODDEF #define READLINE_CLEAR_HISTORY_METHODDEF #endif /* !defined(READLINE_CLEAR_HISTORY_METHODDEF) */ -/*[clinic end generated code: output=d66c3df7e72f93c4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=790ed2ba01babb60 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/resource.c.h b/Modules/clinic/resource.c.h index d0ca8e7150fa86..0ac272af25d154 100644 --- a/Modules/clinic/resource.c.h +++ b/Modules/clinic/resource.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - #if defined(HAVE_GETRUSAGE) PyDoc_STRVAR(resource_getrusage__doc__, @@ -27,7 +21,7 @@ resource_getrusage(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int who; - who = _PyLong_AsInt(arg); + who = PyLong_AsInt(arg); if (who == -1 && PyErr_Occurred()) { goto exit; } @@ -56,7 +50,7 @@ resource_getrlimit(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int resource; - resource = _PyLong_AsInt(arg); + resource = PyLong_AsInt(arg); if (resource == -1 && PyErr_Occurred()) { goto exit; } @@ -87,7 +81,7 @@ resource_setrlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setrlimit", nargs, 2, 2)) { goto exit; } - resource = _PyLong_AsInt(args[0]); + resource = PyLong_AsInt(args[0]); if (resource == -1 && PyErr_Occurred()) { goto exit; } @@ -127,7 +121,7 @@ resource_prlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (pid == -1 && PyErr_Occurred()) { goto exit; } - resource = _PyLong_AsInt(args[1]); + resource = PyLong_AsInt(args[1]); if (resource == -1 && PyErr_Occurred()) { goto exit; } @@ -178,4 +172,4 @@ resource_getpagesize(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef RESOURCE_PRLIMIT_METHODDEF #define RESOURCE_PRLIMIT_METHODDEF #endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */ -/*[clinic end generated code: output=2fbec74335a57230 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2376b9a3f03777aa input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index f44ca1d70a1e86..282196b8f88973 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -3,10 +3,11 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() +#include "pycore_long.h" // _PyLong_UnsignedShort_Converter() PyDoc_STRVAR(select_select__doc__, "select($module, rlist, wlist, xlist, timeout=None, /)\n" @@ -568,7 +569,7 @@ select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } if (fastargs[0]) { - sizehint = _PyLong_AsInt(fastargs[0]); + sizehint = PyLong_AsInt(fastargs[0]); if (sizehint == -1 && PyErr_Occurred()) { goto exit; } @@ -576,7 +577,7 @@ select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } } - flags = _PyLong_AsInt(fastargs[1]); + flags = PyLong_AsInt(fastargs[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -655,7 +656,7 @@ select_epoll_fromfd(PyTypeObject *type, PyObject *arg) PyObject *return_value = NULL; int fd; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -954,7 +955,7 @@ select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } } - maxevents = _PyLong_AsInt(args[1]); + maxevents = PyLong_AsInt(args[1]); if (maxevents == -1 && PyErr_Occurred()) { goto exit; } @@ -1145,7 +1146,7 @@ select_kqueue_fromfd(PyTypeObject *type, PyObject *arg) PyObject *return_value = NULL; int fd; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -1193,7 +1194,7 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize goto exit; } changelist = args[0]; - maxevents = _PyLong_AsInt(args[1]); + maxevents = PyLong_AsInt(args[1]); if (maxevents == -1 && PyErr_Occurred()) { goto exit; } @@ -1309,4 +1310,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=64516114287e894d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=35cd4aa7b6802838 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index ad15ddaadfc86c..fa4ec8bb51e787 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(SHA1Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -148,4 +147,4 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=4d1293ca3472acdb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7efbe42154a7a7f8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha2module.c.h b/Modules/clinic/sha2module.c.h index 8f855ca345e47a..9fb8bf7de876fa 100644 --- a/Modules/clinic/sha2module.c.h +++ b/Modules/clinic/sha2module.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(SHA256Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -437,4 +436,4 @@ _sha2_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject exit: return return_value; } -/*[clinic end generated code: output=f81dacb48f3fee72 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1242ccc50bcefe98 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha3module.c.h b/Modules/clinic/sha3module.c.h index 299803a3420bf6..fd65462d62c195 100644 --- a/Modules/clinic/sha3module.c.h +++ b/Modules/clinic/sha3module.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_long.h" // _PyLong_UnsignedLong_Converter() PyDoc_STRVAR(py_sha3_new__doc__, "sha3_224(data=b\'\', /, *, usedforsecurity=True)\n" @@ -193,4 +193,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=907cb475f3dc9ee0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0888aed37ef39984 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 3b3c6ba150a1ad..5e8957a4be780d 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(signal_default_int_handler__doc__, "default_int_handler($module, signalnum, frame, /)\n" "--\n" @@ -33,7 +27,7 @@ signal_default_int_handler(PyObject *module, PyObject *const *args, Py_ssize_t n if (!_PyArg_CheckPositional("default_int_handler", nargs, 2, 2)) { goto exit; } - signalnum = _PyLong_AsInt(args[0]); + signalnum = PyLong_AsInt(args[0]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } @@ -65,7 +59,7 @@ signal_alarm(PyObject *module, PyObject *arg) int seconds; long _return_value; - seconds = _PyLong_AsInt(arg); + seconds = PyLong_AsInt(arg); if (seconds == -1 && PyErr_Occurred()) { goto exit; } @@ -121,7 +115,7 @@ signal_raise_signal(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int signalnum; - signalnum = _PyLong_AsInt(arg); + signalnum = PyLong_AsInt(arg); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } @@ -160,7 +154,7 @@ signal_signal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("signal", nargs, 2, 2)) { goto exit; } - signalnum = _PyLong_AsInt(args[0]); + signalnum = PyLong_AsInt(args[0]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } @@ -195,7 +189,7 @@ signal_getsignal(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int signalnum; - signalnum = _PyLong_AsInt(arg); + signalnum = PyLong_AsInt(arg); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } @@ -227,7 +221,7 @@ signal_strsignal(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int signalnum; - signalnum = _PyLong_AsInt(arg); + signalnum = PyLong_AsInt(arg); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } @@ -264,11 +258,11 @@ signal_siginterrupt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("siginterrupt", nargs, 2, 2)) { goto exit; } - signalnum = _PyLong_AsInt(args[0]); + signalnum = PyLong_AsInt(args[0]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } - flag = _PyLong_AsInt(args[1]); + flag = PyLong_AsInt(args[1]); if (flag == -1 && PyErr_Occurred()) { goto exit; } @@ -311,7 +305,7 @@ signal_setitimer(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setitimer", nargs, 2, 3)) { goto exit; } - which = _PyLong_AsInt(args[0]); + which = PyLong_AsInt(args[0]); if (which == -1 && PyErr_Occurred()) { goto exit; } @@ -349,7 +343,7 @@ signal_getitimer(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int which; - which = _PyLong_AsInt(arg); + which = PyLong_AsInt(arg); if (which == -1 && PyErr_Occurred()) { goto exit; } @@ -385,7 +379,7 @@ signal_pthread_sigmask(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (!_PyArg_CheckPositional("pthread_sigmask", nargs, 2, 2)) { goto exit; } - how = _PyLong_AsInt(args[0]); + how = PyLong_AsInt(args[0]); if (how == -1 && PyErr_Occurred()) { goto exit; } @@ -587,7 +581,7 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } thread_id = PyLong_AsUnsignedLongMask(args[0]); - signalnum = _PyLong_AsInt(args[1]); + signalnum = PyLong_AsInt(args[1]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } @@ -626,11 +620,11 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("pidfd_send_signal", nargs, 2, 4)) { goto exit; } - pidfd = _PyLong_AsInt(args[0]); + pidfd = PyLong_AsInt(args[0]); if (pidfd == -1 && PyErr_Occurred()) { goto exit; } - signalnum = _PyLong_AsInt(args[1]); + signalnum = PyLong_AsInt(args[1]); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } @@ -641,7 +635,7 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - flags = _PyLong_AsInt(args[3]); + flags = PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -705,4 +699,4 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */ -/*[clinic end generated code: output=2b54dc607f6e3146 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ef4c2ad1a2443063 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h index 8ff1044d013b0f..c62050160f1117 100644 --- a/Modules/clinic/socketmodule.c.h +++ b/Modules/clinic/socketmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - static int sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, PyObject *fdobj); @@ -58,7 +57,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } if (fastargs[0]) { - family = _PyLong_AsInt(fastargs[0]); + family = PyLong_AsInt(fastargs[0]); if (family == -1 && PyErr_Occurred()) { goto exit; } @@ -67,7 +66,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[1]) { - type = _PyLong_AsInt(fastargs[1]); + type = PyLong_AsInt(fastargs[1]); if (type == -1 && PyErr_Occurred()) { goto exit; } @@ -76,7 +75,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - proto = _PyLong_AsInt(fastargs[2]); + proto = PyLong_AsInt(fastargs[2]); if (proto == -1 && PyErr_Occurred()) { goto exit; } @@ -91,4 +90,4 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=987155ac4b48a198 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1b68ae94d6cbeeb1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/symtablemodule.c.h b/Modules/clinic/symtablemodule.c.h index 04fdb9f2d9b776..2cd08f81782007 100644 --- a/Modules/clinic/symtablemodule.c.h +++ b/Modules/clinic/symtablemodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_symtable_symtable__doc__, "symtable($module, source, filename, startstr, /)\n" "--\n" @@ -54,4 +48,4 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=07716ddbd6c7efe1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3f7ccf535d750238 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/syslogmodule.c.h b/Modules/clinic/syslogmodule.c.h index 3e0792b88060c0..f0c6f2a871d042 100644 --- a/Modules/clinic/syslogmodule.c.h +++ b/Modules/clinic/syslogmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(syslog_openlog__doc__, "openlog($module, /, ident=, logoption=0,\n" " facility=LOG_USER)\n" @@ -251,4 +250,4 @@ syslog_LOG_UPTO(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=b8124c0977ed6177 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=68942dad7fb3872e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/termios.c.h b/Modules/clinic/termios.c.h index 78863e53c42ffb..78828e57d73077 100644 --- a/Modules/clinic/termios.c.h +++ b/Modules/clinic/termios.c.h @@ -2,11 +2,7 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - +#include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() PyDoc_STRVAR(termios_tcgetattr__doc__, "tcgetattr($module, fd, /)\n" @@ -75,7 +71,7 @@ termios_tcsetattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } - when = _PyLong_AsInt(args[1]); + when = PyLong_AsInt(args[1]); if (when == -1 && PyErr_Occurred()) { goto exit; } @@ -114,7 +110,7 @@ termios_tcsendbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } - duration = _PyLong_AsInt(args[1]); + duration = PyLong_AsInt(args[1]); if (duration == -1 && PyErr_Occurred()) { goto exit; } @@ -180,7 +176,7 @@ termios_tcflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } - queue = _PyLong_AsInt(args[1]); + queue = PyLong_AsInt(args[1]); if (queue == -1 && PyErr_Occurred()) { goto exit; } @@ -219,7 +215,7 @@ termios_tcflow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } - action = _PyLong_AsInt(args[1]); + action = PyLong_AsInt(args[1]); if (action == -1 && PyErr_Occurred()) { goto exit; } @@ -292,4 +288,4 @@ termios_tcsetwinsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=d286a3906a051869 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=daecc8ebc8fe29f5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index ec30f9017e3702..74362c6a6857b7 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, "decimal($self, chr, default=, /)\n" "--\n" @@ -523,4 +517,4 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=43e551ecaa985a40 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ca10ded25747d182 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index 65412b2435ade1..895215307974f7 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(zlib_compress__doc__, "compress($module, data, /, level=Z_DEFAULT_COMPRESSION, wbits=MAX_WBITS)\n" @@ -77,7 +77,7 @@ zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto skip_optional_pos; } if (args[1]) { - level = _PyLong_AsInt(args[1]); + level = PyLong_AsInt(args[1]); if (level == -1 && PyErr_Occurred()) { goto exit; } @@ -85,7 +85,7 @@ zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto skip_optional_pos; } } - wbits = _PyLong_AsInt(args[2]); + wbits = PyLong_AsInt(args[2]); if (wbits == -1 && PyErr_Occurred()) { goto exit; } @@ -171,7 +171,7 @@ zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } if (args[1]) { - wbits = _PyLong_AsInt(args[1]); + wbits = PyLong_AsInt(args[1]); if (wbits == -1 && PyErr_Occurred()) { goto exit; } @@ -286,7 +286,7 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } if (args[0]) { - level = _PyLong_AsInt(args[0]); + level = PyLong_AsInt(args[0]); if (level == -1 && PyErr_Occurred()) { goto exit; } @@ -295,7 +295,7 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[1]) { - method = _PyLong_AsInt(args[1]); + method = PyLong_AsInt(args[1]); if (method == -1 && PyErr_Occurred()) { goto exit; } @@ -304,7 +304,7 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[2]) { - wbits = _PyLong_AsInt(args[2]); + wbits = PyLong_AsInt(args[2]); if (wbits == -1 && PyErr_Occurred()) { goto exit; } @@ -313,7 +313,7 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[3]) { - memLevel = _PyLong_AsInt(args[3]); + memLevel = PyLong_AsInt(args[3]); if (memLevel == -1 && PyErr_Occurred()) { goto exit; } @@ -322,7 +322,7 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } } if (args[4]) { - strategy = _PyLong_AsInt(args[4]); + strategy = PyLong_AsInt(args[4]); if (strategy == -1 && PyErr_Occurred()) { goto exit; } @@ -409,7 +409,7 @@ zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto skip_optional_pos; } if (args[0]) { - wbits = _PyLong_AsInt(args[0]); + wbits = PyLong_AsInt(args[0]); if (wbits == -1 && PyErr_Occurred()) { goto exit; } @@ -628,7 +628,7 @@ zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, if (nargs < 1) { goto skip_optional_posonly; } - mode = _PyLong_AsInt(args[0]); + mode = PyLong_AsInt(args[0]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -1129,4 +1129,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=57ff7b511ab23132 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6d90c72ba2dd04c5 input=a9049054013a1b77]*/ diff --git a/Modules/config.c.in b/Modules/config.c.in index 6081f95759538f..53b4fb285498d0 100644 --- a/Modules/config.c.in +++ b/Modules/config.c.in @@ -45,7 +45,7 @@ struct _inittab _PyImport_Inittab[] = { /* This lives in Python/Python-ast.c */ {"_ast", PyInit__ast}, - /* This lives in Python/Python-tokenizer.c */ + /* This lives in Python/Python-tokenize.c */ {"_tokenize", PyInit__tokenize}, /* These entries are here for sys.builtin_module_names */ diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 428b090193f093..a2e3c2300b3ce8 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -3,10 +3,13 @@ #include "pycore_pyerrors.h" // _Py_DumpExtensionModules #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_signal.h" // Py_NSIG +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_traceback.h" // _Py_DumpTracebackThreads -#include -#include +#ifdef HAVE_UNISTD_H +# include // _exit() +#endif +#include // sigaction() #include // abort() #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H) # include @@ -15,7 +18,7 @@ # include #endif #ifdef HAVE_SYS_RESOURCE_H -# include +# include // setrlimit() #endif #if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H) @@ -23,10 +26,11 @@ # include // getauxval() #endif + /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) -#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) +#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, strlen(str)) // clang uses __attribute__((no_sanitize("undefined"))) @@ -115,7 +119,7 @@ faulthandler_get_fileno(PyObject **file_ptr) } } else if (PyLong_Check(file)) { - fd = _PyLong_AsInt(file); + fd = PyLong_AsInt(file); if (fd == -1 && PyErr_Occurred()) return -1; if (fd < 0) { @@ -145,10 +149,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return -1; } - result = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); - if (result != NULL) - Py_DECREF(result); - else { + if (_PyFile_Flush(file) < 0) { /* ignore flush() error */ PyErr_Clear(); } @@ -176,7 +177,6 @@ faulthandler_dump_traceback(int fd, int all_threads, PyInterpreterState *interp) { static volatile int reentrant = 0; - PyThreadState *tstate; if (reentrant) return; @@ -191,7 +191,7 @@ faulthandler_dump_traceback(int fd, int all_threads, fault if the thread released the GIL, and so this function cannot be used. Read the thread specific storage (TSS) instead: call PyGILState_GetThisThreadState(). */ - tstate = PyGILState_GetThisThreadState(); + PyThreadState *tstate = PyGILState_GetThisThreadState(); if (all_threads) { (void)_Py_DumpTracebackThreads(fd, NULL, tstate); @@ -414,11 +414,10 @@ faulthandler_allocate_stack(void) int err = sigaltstack(&stack, &old_stack); if (err) { + PyErr_SetFromErrno(PyExc_OSError); /* Release the stack to retry sigaltstack() next time */ PyMem_Free(stack.ss_sp); stack.ss_sp = NULL; - - PyErr_SetFromErrno(PyExc_OSError); return -1; } return 0; @@ -576,7 +575,7 @@ faulthandler_thread(void *unused) /* Timeout => dump traceback */ assert(st == PY_LOCK_FAILURE); - _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len); + (void)_Py_write_noraise(thread.fd, thread.header, (int)thread.header_len); errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL); ok = (errmsg == NULL); diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index e530621fd269a1..fd03abf0561da6 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -1,5 +1,9 @@ /* fcntl module */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #ifdef HAVE_SYS_FILE_H @@ -208,11 +212,12 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, if (mutate_arg && (len <= IOCTL_BUFSZ)) { memcpy(str, buf, len); } - PyBuffer_Release(&pstr); /* No further access to str below this point */ if (ret < 0) { PyErr_SetFromErrno(PyExc_OSError); + PyBuffer_Release(&pstr); return NULL; } + PyBuffer_Release(&pstr); if (mutate_arg) { return PyLong_FromLong(ret); } @@ -237,8 +242,8 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, ret = ioctl(fd, code, buf); Py_END_ALLOW_THREADS if (ret < 0) { - PyBuffer_Release(&pstr); PyErr_SetFromErrno(PyExc_OSError); + PyBuffer_Release(&pstr); return NULL; } PyBuffer_Release(&pstr); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 97644a7cee774f..592d527f0bd6a2 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -24,13 +24,15 @@ */ #include "Python.h" +#include "pycore_ceval.h" // _Py_set_eval_breaker_bit() #include "pycore_context.h" +#include "pycore_dict.h" // _PyDict_MaybeUntrack() #include "pycore_initconfig.h" -#include "pycore_interp.h" // PyInterpreterState.gc +#include "pycore_interp.h" // PyInterpreterState.gc #include "pycore_object.h" #include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_weakref.h" // _PyWeakref_ClearRef() +#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_weakref.h" // _PyWeakref_ClearRef() #include "pydtrace.h" typedef struct _gc_runtime_state GCState; @@ -459,6 +461,7 @@ update_refs(PyGC_Head *containers) static int visit_decref(PyObject *op, void *parent) { + OBJECT_STAT_INC(object_visits); _PyObject_ASSERT(_PyObject_CAST(parent), !_PyObject_IsFreed(op)); if (_PyObject_IS_GC(op)) { @@ -497,6 +500,7 @@ subtract_refs(PyGC_Head *containers) static int visit_reachable(PyObject *op, PyGC_Head *reachable) { + OBJECT_STAT_INC(object_visits); if (!_PyObject_IS_GC(op)) { return 0; } @@ -724,6 +728,7 @@ clear_unreachable_mask(PyGC_Head *unreachable) static int visit_move(PyObject *op, PyGC_Head *tolist) { + OBJECT_STAT_INC(object_visits); if (_PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); if (gc_is_collecting(gc)) { @@ -1194,6 +1199,12 @@ gc_collect_main(PyThreadState *tstate, int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail) { + GC_STAT_ADD(generation, collections, 1); +#ifdef Py_STATS + if (_Py_stats) { + _Py_stats->object_stats.object_visits = 0; + } +#endif int i; Py_ssize_t m = 0; /* # objects collected */ Py_ssize_t n = 0; /* # unreachable objects that couldn't be collected */ @@ -1350,6 +1361,15 @@ gc_collect_main(PyThreadState *tstate, int generation, stats->collected += m; stats->uncollectable += n; + GC_STAT_ADD(generation, objects_collected, m); +#ifdef Py_STATS + if (_Py_stats) { + GC_STAT_ADD(generation, object_visits, + _Py_stats->object_stats.object_visits); + _Py_stats->object_stats.object_visits = 0; + } +#endif + if (PyDTrace_GC_DONE_ENABLED()) { PyDTrace_GC_DONE(n + m); } @@ -2255,11 +2275,7 @@ _Py_ScheduleGC(PyInterpreterState *interp) if (gcstate->collecting == 1) { return; } - struct _ceval_state *ceval = &interp->ceval; - if (!_Py_atomic_load_relaxed(&ceval->gc_scheduled)) { - _Py_atomic_store_relaxed(&ceval->gc_scheduled, 1); - _Py_atomic_store_relaxed(&ceval->eval_breaker, 1); - } + _Py_set_eval_breaker_bit(interp, _PY_GC_SCHEDULED_BIT, 1); } void diff --git a/Modules/getaddrinfo.c b/Modules/getaddrinfo.c index f1c28d7d9312ac..6fb6062a6520d9 100644 --- a/Modules/getaddrinfo.c +++ b/Modules/getaddrinfo.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include "addrinfo.h" @@ -228,8 +227,9 @@ str_isnumber(const char *p) { unsigned char *q = (unsigned char *)p; while (*q) { - if (! isdigit(*q)) + if (!Py_ISDIGIT(*q)) { return NO; + } q++; } return YES; diff --git a/Modules/getpath.c b/Modules/getpath.c index abe7c3c3c30a9a..6f76a84e78bf62 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -1,11 +1,15 @@ /* Return the initial module search path. */ #include "Python.h" +#include "pycore_fileutils.h" // _Py_abspath() +#include "pycore_initconfig.h" // _PyStatus_EXCEPTION() +#include "pycore_pathconfig.h" // _PyPathConfig_ReadGlobal() +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() +#include "pycore_pymem.h" // _PyMem_RawWcsdup() +#include "pycore_pystate.h" // _PyThreadState_GET() + #include "marshal.h" // PyMarshal_ReadObjectFromString #include "osdefs.h" // DELIM -#include "pycore_initconfig.h" -#include "pycore_fileutils.h" -#include "pycore_pathconfig.h" #include #ifdef MS_WINDOWS @@ -340,11 +344,12 @@ getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args) return NULL; } FILE *fp = _Py_wfopen(path, L"rb"); - PyMem_Free((void *)path); if (!fp) { PyErr_SetFromErrno(PyExc_OSError); + PyMem_Free((void *)path); return NULL; } + PyMem_Free((void *)path); r = PyList_New(0); if (!r) { @@ -817,7 +822,7 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) return status; } - if (!_PyThreadState_UncheckedGet()) { + if (!_PyThreadState_GET()) { return PyStatus_Error("cannot calculate path configuration without GIL"); } @@ -920,23 +925,6 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) } Py_DECREF(r); -#if 0 - PyObject *it = PyObject_GetIter(configDict); - for (PyObject *k = PyIter_Next(it); k; k = PyIter_Next(it)) { - if (!strcmp("__builtins__", PyUnicode_AsUTF8(k))) { - Py_DECREF(k); - continue; - } - fprintf(stderr, "%s = ", PyUnicode_AsUTF8(k)); - PyObject *o = PyDict_GetItem(configDict, k); - o = PyObject_Repr(o); - fprintf(stderr, "%s\n", PyUnicode_AsUTF8(o)); - Py_DECREF(o); - Py_DECREF(k); - } - Py_DECREF(it); -#endif - if (_PyConfig_FromDict(config, configDict) < 0) { _PyErr_WriteUnraisableMsg("reading getpath results", NULL); Py_DECREF(dict); @@ -947,4 +935,3 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) return _PyStatus_OK(); } - diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 57cdde6064c24e..20e83de84e8340 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -4,7 +4,8 @@ #include "Python.h" #include "posixmodule.h" -#include +#include // getgrgid_r() +#include // sysconf() #include "clinic/grpmodule.c.h" /*[clinic input] @@ -65,8 +66,14 @@ mkgrent(PyObject *module, struct group *p) Py_DECREF(v); return NULL; } - for (member = p->gr_mem; *member != NULL; member++) { - PyObject *x = PyUnicode_DecodeFSDefault(*member); + for (member = p->gr_mem; ; member++) { + char *group_member; + // member can be misaligned + memcpy(&group_member, member, sizeof(group_member)); + if (group_member == NULL) { + break; + } + PyObject *x = PyUnicode_DecodeFSDefault(group_member); if (x == NULL || PyList_Append(w, x) != 0) { Py_XDECREF(x); Py_DECREF(w); diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index f5f7bf33bf8f4b..4ed34aa5bde827 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1,11 +1,12 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_typeobject.h" // _PyType_GetModuleState() #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "structmember.h" // PyMemberDef + #include // offsetof() /* Itertools module written and maintained @@ -1090,7 +1091,7 @@ static PyMethodDef tee_methods[] = { }; static PyMemberDef tee_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(teeobject, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(teeobject, weakreflist), Py_READONLY}, {NULL}, }; diff --git a/Modules/main.c b/Modules/main.c index a5c009321d607f..b5ee34d0141daf 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -7,6 +7,7 @@ #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() #include "pycore_pylifecycle.h" // _Py_PreInitializeFromPyArgv() #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_pythonrun.h" // _PyRun_AnyFileObject() /* Includes for exit_sigint() */ #include // perror() @@ -25,10 +26,6 @@ "Type \"help\", \"copyright\", \"credits\" or \"license\" " \ "for more information." -#ifdef __cplusplus -extern "C" { -#endif - /* --- pymain_init() ---------------------------------------------- */ static PyStatus @@ -559,6 +556,11 @@ pymain_run_python(int *exitcode) goto error; } + // XXX Calculate config->sys_path_0 in getpath.py. + // The tricky part is that we can't check the path importers yet + // at that point. + assert(config->sys_path_0 == NULL); + if (config->run_filename != NULL) { /* If filename is a package (ex: directory or ZIP file) which contains __main__.py, main_importer_path is set to filename and will be @@ -574,29 +576,45 @@ pymain_run_python(int *exitcode) // import readline and rlcompleter before script dir is added to sys.path pymain_import_readline(config); + PyObject *path0 = NULL; if (main_importer_path != NULL) { - if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) { - goto error; - } + path0 = Py_NewRef(main_importer_path); } else if (!config->safe_path) { - PyObject *path0 = NULL; int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0); if (res < 0) { goto error; } - - if (res > 0) { - if (pymain_sys_path_add_path0(interp, path0) < 0) { - Py_DECREF(path0); - goto error; - } + else if (res == 0) { + Py_CLEAR(path0); + } + } + // XXX Apply config->sys_path_0 in init_interp_main(). We have + // to be sure to get readline/rlcompleter imported at the correct time. + if (path0 != NULL) { + wchar_t *wstr = PyUnicode_AsWideCharString(path0, NULL); + if (wstr == NULL) { + Py_DECREF(path0); + goto error; + } + config->sys_path_0 = _PyMem_RawWcsdup(wstr); + PyMem_Free(wstr); + if (config->sys_path_0 == NULL) { Py_DECREF(path0); + goto error; + } + int res = pymain_sys_path_add_path0(interp, path0); + Py_DECREF(path0); + if (res < 0) { + goto error; } } pymain_header(config); + _PyInterpreterState_SetRunningMain(interp); + assert(!PyErr_Occurred()); + if (config->run_command) { *exitcode = pymain_run_command(config->run_command); } @@ -620,6 +638,7 @@ pymain_run_python(int *exitcode) *exitcode = pymain_exit_err_print(); done: + _PyInterpreterState_SetNotRunningMain(interp); Py_XDECREF(main_importer_path); } @@ -741,7 +760,3 @@ Py_BytesMain(int argc, char **argv) .wchar_argv = NULL}; return pymain_main(&args); } - -#ifdef __cplusplus -} -#endif diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 0d238c086ac78f..a4d94665592351 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -57,6 +57,7 @@ raised for division by zero and mod by zero. #endif #include "Python.h" +#include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_bitutils.h" // _Py_bit_length() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_long.h" // _PyLong_GetZero() @@ -1124,8 +1125,12 @@ static PyObject * math_ceil(PyObject *module, PyObject *number) /*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ { + double x; - if (!PyFloat_CheckExact(number)) { + if (PyFloat_CheckExact(number)) { + x = PyFloat_AS_DOUBLE(number); + } + else { math_module_state *state = get_math_module_state(module); PyObject *method = _PyObject_LookupSpecial(number, state->str___ceil__); if (method != NULL) { @@ -1135,11 +1140,10 @@ math_ceil(PyObject *module, PyObject *number) } if (PyErr_Occurred()) return NULL; + x = PyFloat_AsDouble(number); + if (x == -1.0 && PyErr_Occurred()) + return NULL; } - double x = PyFloat_AsDouble(number); - if (x == -1.0 && PyErr_Occurred()) - return NULL; - return PyLong_FromDouble(ceil(x)); } @@ -1195,8 +1199,7 @@ math_floor(PyObject *module, PyObject *number) if (PyFloat_CheckExact(number)) { x = PyFloat_AS_DOUBLE(number); } - else - { + else { math_module_state *state = get_math_module_state(module); PyObject *method = _PyObject_LookupSpecial(number, state->str___floor__); if (method != NULL) { @@ -2194,12 +2197,10 @@ math_modf_impl(PyObject *module, double x) double y; /* some platforms don't do the right thing for NaNs and infinities, so we take care of special cases directly. */ - if (!Py_IS_FINITE(x)) { - if (Py_IS_INFINITY(x)) - return Py_BuildValue("(dd)", copysign(0., x), x); - else if (Py_IS_NAN(x)) - return Py_BuildValue("(dd)", x, x); - } + if (Py_IS_INFINITY(x)) + return Py_BuildValue("(dd)", copysign(0., x), x); + else if (Py_IS_NAN(x)) + return Py_BuildValue("(dd)", x, x); errno = 0; x = modf(x, &y); @@ -2949,7 +2950,8 @@ math_pow_impl(PyObject *module, double x, double y) else /* y < 0. */ r = odd_y ? copysign(0., x) : 0.; } - else if (Py_IS_INFINITY(y)) { + else { + assert(Py_IS_INFINITY(y)); if (fabs(x) == 1.0) r = 1.; else if (y > 0. && fabs(x) > 1.0) @@ -3479,9 +3481,7 @@ static const uint8_t factorial_trailing_zeros[] = { static PyObject * perm_comb_small(unsigned long long n, unsigned long long k, int iscomb) { - if (k == 0) { - return PyLong_FromLong(1); - } + assert(k != 0); /* For small enough n and k the result fits in the 64-bit range and can * be calculated without allocating intermediate PyLong objects. */ diff --git a/Modules/md5module.c b/Modules/md5module.c index 2122f8b18baf6e..5463effb507de6 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -356,13 +356,7 @@ md5_exec(PyObject *m) st->md5_type = (PyTypeObject *)PyType_FromModuleAndSpec( m, &md5_type_spec, NULL); - if (st->md5_type == NULL) { - return -1; - } - - Py_INCREF((PyObject *)st->md5_type); - if (PyModule_AddObject(m, "MD5Type", (PyObject *)st->md5_type) < 0) { - Py_DECREF(st->md5_type); + if (PyModule_AddObjectRef(m, "MD5Type", (PyObject *)st->md5_type) < 0) { return -1; } diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index c1cd5b0efaa3d2..d11200a4042551 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -23,10 +23,14 @@ #endif #include +#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() #include "pycore_bytesobject.h" // _PyBytes_Find() #include "pycore_fileutils.h" // _Py_stat_struct -#include "structmember.h" // PyMemberDef + #include // offsetof() +#ifndef MS_WINDOWS +# include // close() +#endif // to support MS_WINDOWS_SYSTEM OpenFileMappingA / CreateFileMappingA // need to be replaced with OpenFileMappingW / CreateFileMappingW @@ -883,7 +887,7 @@ mmap_madvise_method(mmap_object *self, PyObject *args) #endif // HAVE_MADVISE static struct PyMemberDef mmap_object_members[] = { - {"__weaklistoffset__", T_PYSSIZET, offsetof(mmap_object, weakreflist), READONLY}, + {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(mmap_object, weakreflist), Py_READONLY}, {NULL}, }; @@ -1355,6 +1359,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) m_obj->data = mmap(NULL, map_size, prot, flags, fd, offset); Py_END_ALLOW_THREADS + int saved_errno = errno; if (devzero != -1) { close(devzero); } @@ -1362,6 +1367,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) if (m_obj->data == (char *)-1) { m_obj->data = NULL; Py_DECREF(m_obj); + errno = saved_errno; PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -1579,9 +1585,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) static int mmap_exec(PyObject *module) { - Py_INCREF(PyExc_OSError); - if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { - Py_DECREF(PyExc_OSError); + if (PyModule_AddObjectRef(module, "error", PyExc_OSError) < 0) { return -1; } diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 18899509c87712..e23db22dadb18b 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -7,8 +7,11 @@ /* XXX check overflow and DWORD <-> Py_ssize_t conversions Check itemsize */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" -#include "structmember.h" // PyMemberDef #define WINDOWS_LEAN_AND_MEAN #include @@ -17,10 +20,10 @@ #if defined(MS_WIN32) && !defined(MS_WIN64) # define F_POINTER "k" -# define T_POINTER T_ULONG +# define T_POINTER Py_T_ULONG #else # define F_POINTER "K" -# define T_POINTER T_ULONGLONG +# define T_POINTER Py_T_ULONGLONG #endif #define F_HANDLE F_POINTER @@ -35,13 +38,14 @@ class pointer_converter(CConverter): format_unit = '"F_POINTER"' - def parse_arg(self, argname, displayname): - return """ + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" {paramname} = PyLong_AsVoidPtr({argname}); if (!{paramname} && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) class OVERLAPPED_converter(pointer_converter): type = 'OVERLAPPED *' @@ -52,13 +56,14 @@ class HANDLE_converter(pointer_converter): class ULONG_PTR_converter(pointer_converter): type = 'ULONG_PTR' - def parse_arg(self, argname, displayname): - return """ + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" {paramname} = (uintptr_t)PyLong_AsVoidPtr({argname}); if (!{paramname} && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) class DWORD_converter(unsigned_long_converter): type = 'DWORD' @@ -66,7 +71,7 @@ class DWORD_converter(unsigned_long_converter): class BOOL_converter(int_converter): type = 'BOOL' [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=8a07ea3018f4cec8]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=436f4440630a304c]*/ /*[clinic input] module _overlapped @@ -367,8 +372,9 @@ _overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { + SetFromWindowsErr(0); PyMem_RawFree(pdata); - return SetFromWindowsErr(0); + return NULL; } return Py_BuildValue(F_HANDLE, NewWaitObject); @@ -1942,12 +1948,12 @@ static PyMethodDef Overlapped_methods[] = { }; static PyMemberDef Overlapped_members[] = { - {"error", T_ULONG, + {"error", Py_T_ULONG, offsetof(OverlappedObject, error), - READONLY, "Error from last operation"}, + Py_READONLY, "Error from last operation"}, {"event", T_HANDLE, offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent), - READONLY, "Overlapped event handle"}, + Py_READONLY, "Overlapped event handle"}, {NULL} }; @@ -1996,12 +2002,7 @@ static PyMethodDef overlapped_functions[] = { #define WINAPI_CONSTANT(fmt, con) \ do { \ - PyObject *value = Py_BuildValue(fmt, con); \ - if (value == NULL) { \ - return -1; \ - } \ - if (PyModule_AddObject(module, #con, value) < 0 ) { \ - Py_DECREF(value); \ + if (PyModule_Add(module, #con, Py_BuildValue(fmt, con)) < 0 ) { \ return -1; \ } \ } while (0) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 23bf978d0cdbf1..650ae4bbd68656 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12,6 +12,7 @@ #ifdef __VXWORKS__ # include "pycore_bitutils.h" // _Py_popcount32() #endif +#include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_ReInitThreads() #include "pycore_fileutils.h" // _Py_closerange() @@ -23,6 +24,10 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_signal.h" // Py_NSIG +#ifdef HAVE_UNISTD_H +# include // symlink() +#endif + #ifdef MS_WINDOWS # include # if !defined(MS_WINDOWS_GAMES) || defined(MS_WINDOWS_DESKTOP) @@ -36,7 +41,6 @@ # endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */ #endif -#include "structmember.h" // PyMemberDef #ifndef MS_WINDOWS # include "posixmodule.h" #else @@ -56,6 +60,17 @@ #include // ctermid() #include // system() +#ifdef HAVE_SYS_TIME_H +# include // futimes() +#endif + + +// SGI apparently needs this forward declaration +#ifdef HAVE__GETPTY +# include // mode_t + extern char * _getpty(int *, int, mode_t, int); +#endif + /* * A number of APIs are available on macOS from a certain macOS version. @@ -210,10 +225,6 @@ #endif -#ifdef __cplusplus -extern "C" { -#endif - PyDoc_STRVAR(posix__doc__, "This module provides access to operating system functionality that is\n\ standardized by the C Standard and the POSIX standard (a thinly\n\ @@ -277,15 +288,11 @@ corresponding Unix manual entries for more information on calls."); # include #endif -#ifdef HAVE_COPY_FILE_RANGE -# include -#endif - #if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) # undef HAVE_SCHED_SETAFFINITY #endif -#if defined(HAVE_SYS_XATTR_H) && defined(__linux__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) +#if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LINUX_LIMITS_H) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) # define USE_XATTRS # include // Needed for XATTR_SIZE_MAX on musl libc. #endif @@ -543,6 +550,11 @@ extern char *ctermid_r(char *); # include #endif +/* timerfd_create() */ +#ifdef HAVE_SYS_TIMERFD_H +# include +#endif + #ifdef _Py_MEMORY_SANITIZER # include #endif @@ -2384,21 +2396,26 @@ _posix_free(void *module) _posix_clear((PyObject *)module); } -static void +static int fill_time(PyObject *module, PyObject *v, int s_index, int f_index, int ns_index, time_t sec, unsigned long nsec) { - PyObject *s = _PyLong_FromTime_t(sec); - PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec); + assert(!PyErr_Occurred()); + + int res = -1; PyObject *s_in_ns = NULL; PyObject *ns_total = NULL; PyObject *float_s = NULL; - if (!(s && ns_fractional)) + PyObject *s = _PyLong_FromTime_t(sec); + PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec); + if (!(s && ns_fractional)) { goto exit; + } s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion); - if (!s_in_ns) + if (!s_in_ns) { goto exit; + } ns_total = PyNumber_Add(s_in_ns, ns_fractional); if (!ns_total) @@ -2421,12 +2438,17 @@ fill_time(PyObject *module, PyObject *v, int s_index, int f_index, int ns_index, PyStructSequence_SET_ITEM(v, ns_index, ns_total); ns_total = NULL; } + + assert(!PyErr_Occurred()); + res = 0; + exit: Py_XDECREF(s); Py_XDECREF(ns_fractional); Py_XDECREF(s_in_ns); Py_XDECREF(ns_total); Py_XDECREF(float_s); + return res; } #ifdef MS_WINDOWS @@ -2461,34 +2483,47 @@ _pystat_l128_from_l64_l64(uint64_t low, uint64_t high) static PyObject* _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) { - unsigned long ansec, mnsec, cnsec; + assert(!PyErr_Occurred()); + PyObject *StatResultType = get_posix_state(module)->StatResultType; PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType); - if (v == NULL) + if (v == NULL) { return NULL; + } - PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); +#define SET_ITEM(pos, expr) \ + do { \ + PyObject *obj = (expr); \ + if (obj == NULL) { \ + goto error; \ + } \ + PyStructSequence_SET_ITEM(v, (pos), obj); \ + } while (0) + + SET_ITEM(0, PyLong_FromLong((long)st->st_mode)); #ifdef MS_WINDOWS - PyStructSequence_SET_ITEM(v, 1, _pystat_l128_from_l64_l64(st->st_ino, st->st_ino_high)); - PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLongLong(st->st_dev)); + SET_ITEM(1, _pystat_l128_from_l64_l64(st->st_ino, st->st_ino_high)); + SET_ITEM(2, PyLong_FromUnsignedLongLong(st->st_dev)); #else static_assert(sizeof(unsigned long long) >= sizeof(st->st_ino), "stat.st_ino is larger than unsigned long long"); - PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino)); - PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); + SET_ITEM(1, PyLong_FromUnsignedLongLong(st->st_ino)); + SET_ITEM(2, _PyLong_FromDev(st->st_dev)); #endif - PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); + SET_ITEM(3, PyLong_FromLong((long)st->st_nlink)); #if defined(MS_WINDOWS) - PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0)); - PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0)); + SET_ITEM(4, PyLong_FromLong(0)); + SET_ITEM(5, PyLong_FromLong(0)); #else - PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid)); - PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid)); + SET_ITEM(4, _PyLong_FromUid(st->st_uid)); + SET_ITEM(5, _PyLong_FromGid(st->st_gid)); #endif static_assert(sizeof(long long) >= sizeof(st->st_size), "stat.st_size is larger than long long"); - PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size)); + SET_ITEM(6, PyLong_FromLongLong(st->st_size)); + // Set st_atime, st_mtime and st_ctime + unsigned long ansec, mnsec, cnsec; #if defined(HAVE_STAT_TV_NSEC) ansec = st->st_atim.tv_nsec; mnsec = st->st_mtim.tv_nsec; @@ -2504,67 +2539,67 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) #else ansec = mnsec = cnsec = 0; #endif - fill_time(module, v, 7, 10, 13, st->st_atime, ansec); - fill_time(module, v, 8, 11, 14, st->st_mtime, mnsec); - fill_time(module, v, 9, 12, 15, st->st_ctime, cnsec); + if (fill_time(module, v, 7, 10, 13, st->st_atime, ansec) < 0) { + goto error; + } + if (fill_time(module, v, 8, 11, 14, st->st_mtime, mnsec) < 0) { + goto error; + } + if (fill_time(module, v, 9, 12, 15, st->st_ctime, cnsec) < 0) { + goto error; + } #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, - PyLong_FromLong((long)st->st_blksize)); + SET_ITEM(ST_BLKSIZE_IDX, PyLong_FromLong((long)st->st_blksize)); #endif #ifdef HAVE_STRUCT_STAT_ST_BLOCKS - PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, - PyLong_FromLong((long)st->st_blocks)); + SET_ITEM(ST_BLOCKS_IDX, PyLong_FromLong((long)st->st_blocks)); #endif #ifdef HAVE_STRUCT_STAT_ST_RDEV - PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, - PyLong_FromLong((long)st->st_rdev)); + SET_ITEM(ST_RDEV_IDX, PyLong_FromLong((long)st->st_rdev)); #endif #ifdef HAVE_STRUCT_STAT_ST_GEN - PyStructSequence_SET_ITEM(v, ST_GEN_IDX, - PyLong_FromLong((long)st->st_gen)); + SET_ITEM(ST_GEN_IDX, PyLong_FromLong((long)st->st_gen)); #endif #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) { - PyObject *val; - unsigned long bsec,bnsec; + unsigned long bsec, bnsec; bsec = (long)st->st_birthtime; #ifdef HAVE_STAT_TV_NSEC2 bnsec = st->st_birthtimespec.tv_nsec; #else bnsec = 0; #endif - val = PyFloat_FromDouble(bsec + 1e-9*bnsec); - PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, - val); + SET_ITEM(ST_BIRTHTIME_IDX, PyFloat_FromDouble(bsec + bnsec * 1e-9)); } #elif defined(MS_WINDOWS) - fill_time(module, v, -1, ST_BIRTHTIME_IDX, ST_BIRTHTIME_NS_IDX, - st->st_birthtime, st->st_birthtime_nsec); + if (fill_time(module, v, -1, ST_BIRTHTIME_IDX, ST_BIRTHTIME_NS_IDX, + st->st_birthtime, st->st_birthtime_nsec) < 0) { + goto error; + } #endif #ifdef HAVE_STRUCT_STAT_ST_FLAGS - PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, - PyLong_FromLong((long)st->st_flags)); + SET_ITEM(ST_FLAGS_IDX, PyLong_FromLong((long)st->st_flags)); #endif #ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES - PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX, - PyLong_FromUnsignedLong(st->st_file_attributes)); + SET_ITEM(ST_FILE_ATTRIBUTES_IDX, + PyLong_FromUnsignedLong(st->st_file_attributes)); #endif #ifdef HAVE_STRUCT_STAT_ST_FSTYPE - PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX, - PyUnicode_FromString(st->st_fstype)); + SET_ITEM(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)); + SET_ITEM(ST_REPARSE_TAG_IDX, PyLong_FromUnsignedLong(st->st_reparse_tag)); #endif - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; - } - + assert(!PyErr_Occurred()); return v; + +error: + Py_DECREF(v); + return NULL; + +#undef SET_ITEM } /* POSIX methods */ @@ -3876,9 +3911,10 @@ posix_getcwd(int use_bytes) return NULL; } if (!len) { + PyErr_SetFromWindowsErr(0); if (wbuf2 != wbuf) PyMem_RawFree(wbuf2); - return PyErr_SetFromWindowsErr(0); + return NULL; } PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); @@ -3926,8 +3962,9 @@ posix_getcwd(int use_bytes) return PyErr_NoMemory(); } if (cwd == NULL) { + posix_error(); PyMem_RawFree(buf); - return posix_error(); + return NULL; } PyObject *obj; @@ -4139,8 +4176,8 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) int error = GetLastError(); if (error == ERROR_FILE_NOT_FOUND) goto exit; - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); goto exit; } do { @@ -4153,12 +4190,12 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); } if (v == NULL) { - Py_SETREF(list, NULL); + Py_CLEAR(list); break; } if (PyList_Append(list, v) != 0) { Py_DECREF(v); - Py_SETREF(list, NULL); + Py_CLEAR(list); break; } Py_DECREF(v); @@ -4169,8 +4206,8 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) /* FindNextFile sets error to ERROR_NO_MORE_FILES if it got to the end of the directory. */ if (!result && GetLastError() != ERROR_NO_MORE_FILES) { - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); goto exit; } } while (result == TRUE); @@ -4179,8 +4216,8 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) if (hFindFile != INVALID_HANDLE_VALUE) { if (FindClose(hFindFile) == FALSE) { if (list != NULL) { - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); } } } @@ -4242,7 +4279,8 @@ _posix_listdir(path_t *path, PyObject *list) } if (dirp == NULL) { - list = path_error(path); + path_error(path); + list = NULL; #ifdef HAVE_FDOPENDIR if (fd != -1) { Py_BEGIN_ALLOW_THREADS @@ -4264,8 +4302,8 @@ _posix_listdir(path_t *path, PyObject *list) if (errno == 0) { break; } else { - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); goto exit; } } @@ -4776,6 +4814,37 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) return result; } +/*[clinic input] +os._findfirstfile + path: path_t + / +A function to get the real file name without accessing the file in Windows. +[clinic start generated code]*/ + +static PyObject * +os__findfirstfile_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=106dd3f0779c83dd input=0734dff70f60e1a8]*/ +{ + PyObject *result; + HANDLE hFindFile; + WIN32_FIND_DATAW wFileData; + WCHAR *wRealFileName; + + Py_BEGIN_ALLOW_THREADS + hFindFile = FindFirstFileW(path->wide, &wFileData); + Py_END_ALLOW_THREADS + + if (hFindFile == INVALID_HANDLE_VALUE) { + path_error(path); + return NULL; + } + + wRealFileName = wFileData.cFileName; + result = PyUnicode_FromWideChar(wRealFileName, wcslen(wRealFileName)); + FindClose(hFindFile); + return result; +} + /*[clinic input] os._getvolumepathname @@ -4874,25 +4943,25 @@ os__path_splitroot_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isdir - path: 'O' + s: 'O' Return true if the pathname refers to an existing directory. [clinic start generated code]*/ static PyObject * -os__path_isdir_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=00faea0af309669d input=b1d2571cf7291aaf]*/ +os__path_isdir_impl(PyObject *module, PyObject *s) +/*[clinic end generated code: output=9d87ab3c8b8a4e61 input=c17f7ef21d22d64e]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; - path_t _path = PATH_T_INITIALIZE("isdir", "path", 0, 1); + path_t _path = PATH_T_INITIALIZE("isdir", "s", 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(path, &_path)) { + if (!path_converter(s, &_path)) { path_cleanup(&_path); if (PyErr_ExceptionMatches(PyExc_ValueError)) { PyErr_Clear(); @@ -5274,7 +5343,9 @@ os__path_normpath_impl(PyObject *module, PyObject *path) if (!buffer) { return NULL; } - PyObject *result = PyUnicode_FromWideChar(_Py_normpath(buffer, len), -1); + Py_ssize_t norm_len; + wchar_t *norm_path = _Py_normpath_and_size(buffer, len, &norm_len); + PyObject *result = PyUnicode_FromWideChar(norm_path, norm_len); PyMem_Free(buffer); return result; } @@ -6290,11 +6361,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); } if (!SetFileTime(hFile, NULL, &atime, &mtime)) { - /* Avoid putting the file name into the error here, - as that may confuse the user into believing that - something is wrong with the file, when it also - could be the time stamp that gives a problem. */ - PyErr_SetFromWindowsErr(0); + path_error(path); CloseHandle(hFile); return NULL; } @@ -6334,8 +6401,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, #endif if (result < 0) { - /* see previous comment about not putting filename in error here */ - posix_error(); + path_error(path); return NULL; } @@ -6606,8 +6672,9 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) /* If we get here it's definitely an error */ + posix_error(); free_string_array(argvlist, argc); - return posix_error(); + return NULL; } @@ -6819,7 +6886,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg goto fail; } if (py_schedpolicy != Py_None) { - int schedpolicy = _PyLong_AsInt(py_schedpolicy); + int schedpolicy = PyLong_AsInt(py_schedpolicy); if (schedpolicy == -1 && PyErr_Occurred()) { goto fail; @@ -6911,11 +6978,12 @@ parse_file_actions(PyObject *file_actions, } errno = posix_spawn_file_actions_addopen(file_actionsp, fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); - Py_DECREF(path); if (errno) { posix_error(); + Py_DECREF(path); goto fail; } + Py_DECREF(path); break; } case POSIX_SPAWN_CLOSE: { @@ -7312,12 +7380,15 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS + int saved_errno = errno; free_string_array(argvlist, argc); - if (spawnval == -1) - return posix_error(); - else - return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); + if (spawnval == -1) { + errno = saved_errno; + posix_error(); + return NULL; + } + return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); } /*[clinic input] @@ -7635,6 +7706,7 @@ os_fork1_impl(PyObject *module) } PyOS_BeforeFork(); pid = fork1(); + int saved_errno = errno; if (pid == 0) { /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); @@ -7643,8 +7715,10 @@ os_fork1_impl(PyObject *module) /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } - if (pid == -1) + if (pid == -1) { + errno = saved_errno; return posix_error(); + } return PyLong_FromPid(pid); } #endif /* HAVE_FORK1 */ @@ -7680,6 +7754,7 @@ os_fork_impl(PyObject *module) } PyOS_BeforeFork(); pid = fork(); + int saved_errno = errno; if (pid == 0) { /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); @@ -7688,8 +7763,10 @@ os_fork_impl(PyObject *module) /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } - if (pid == -1) + if (pid == -1) { + errno = saved_errno; return posix_error(); + } return PyLong_FromPid(pid); } #endif /* HAVE_FORK */ @@ -8092,39 +8169,45 @@ static PyObject * os_sched_getaffinity_impl(PyObject *module, pid_t pid) /*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/ { - int cpu, ncpus, count; + int ncpus = NCPUS_START; size_t setsize; - cpu_set_t *mask = NULL; - PyObject *res = NULL; + cpu_set_t *mask; - ncpus = NCPUS_START; while (1) { setsize = CPU_ALLOC_SIZE(ncpus); mask = CPU_ALLOC(ncpus); - if (mask == NULL) + if (mask == NULL) { return PyErr_NoMemory(); - if (sched_getaffinity(pid, setsize, mask) == 0) + } + if (sched_getaffinity(pid, setsize, mask) == 0) { break; + } CPU_FREE(mask); - if (errno != EINVAL) + if (errno != EINVAL) { return posix_error(); + } if (ncpus > INT_MAX / 2) { - PyErr_SetString(PyExc_OverflowError, "could not allocate " - "a large enough CPU set"); + PyErr_SetString(PyExc_OverflowError, + "could not allocate a large enough CPU set"); return NULL; } - ncpus = ncpus * 2; + ncpus *= 2; } - res = PySet_New(NULL); - if (res == NULL) + PyObject *res = PySet_New(NULL); + if (res == NULL) { goto error; - for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) { + } + + int cpu = 0; + int count = CPU_COUNT_S(setsize, mask); + for (; count; cpu++) { if (CPU_ISSET_S(cpu, setsize, mask)) { PyObject *cpu_num = PyLong_FromLong(cpu); --count; - if (cpu_num == NULL) + if (cpu_num == NULL) { goto error; + } if (PySet_Add(res, cpu_num)) { Py_DECREF(cpu_num); goto error; @@ -8136,12 +8219,12 @@ os_sched_getaffinity_impl(PyObject *module, pid_t pid) return res; error: - if (mask) + if (mask) { CPU_FREE(mask); + } Py_XDECREF(res); return NULL; } - #endif /* HAVE_SCHED_SETAFFINITY */ #endif /* HAVE_SCHED_H */ @@ -8226,13 +8309,17 @@ os_openpty_impl(PyObject *module) /* change permission of slave */ if (grantpt(master_fd) < 0) { + int saved_errno = errno; PyOS_setsig(SIGCHLD, sig_saved); + errno = saved_errno; goto posix_error; } /* unlock slave */ if (unlockpt(master_fd) < 0) { + int saved_errno = errno; PyOS_setsig(SIGCHLD, sig_saved); + errno = saved_errno; goto posix_error; } @@ -8596,8 +8683,9 @@ os_getgroups_impl(PyObject *module) n = getgroups(n, grouplist); if (n == -1) { + posix_error(); PyMem_Free(grouplist); - return posix_error(); + return NULL; } PyObject *result = PyList_New(n); @@ -9164,8 +9252,9 @@ os_setgroups(PyObject *module, PyObject *groups) } if (setgroups(len, grouplist) < 0) { + posix_error(); PyMem_Free(grouplist); - return posix_error(); + return NULL; } PyMem_Free(grouplist); Py_RETURN_NONE; @@ -10012,6 +10101,227 @@ os_times_impl(PyObject *module) #endif /* HAVE_TIMES */ +#if defined(HAVE_TIMERFD_CREATE) +#define ONE_SECOND_IN_NS (1000 * 1000 * 1000) +#define EXTRACT_NSEC(value) (long)( ( (double)(value) - (time_t)(value) ) * 1e9) +#define CONVERT_SEC_AND_NSEC_TO_DOUBLE(sec, nsec) ( (double)(sec) + (double)(nsec) * 1e-9 ) + +static PyObject * +build_itimerspec(const struct itimerspec* curr_value) +{ + double _value = CONVERT_SEC_AND_NSEC_TO_DOUBLE(curr_value->it_value.tv_sec, + curr_value->it_value.tv_nsec); + PyObject *value = PyFloat_FromDouble(_value); + if (value == NULL) { + return NULL; + } + double _interval = CONVERT_SEC_AND_NSEC_TO_DOUBLE(curr_value->it_interval.tv_sec, + curr_value->it_interval.tv_nsec); + PyObject *interval = PyFloat_FromDouble(_interval); + if (interval == NULL) { + Py_DECREF(value); + return NULL; + } + PyObject *tuple = PyTuple_Pack(2, value, interval); + Py_DECREF(interval); + Py_DECREF(value); + return tuple; +} + +static PyObject * +build_itimerspec_ns(const struct itimerspec* curr_value) +{ + _PyTime_t value, interval; + if (_PyTime_FromTimespec(&value, &curr_value->it_value) < 0) { + return NULL; + } + if (_PyTime_FromTimespec(&interval, &curr_value->it_interval) < 0) { + return NULL; + } + return Py_BuildValue("LL", value, interval); +} + +/*[clinic input] +os.timerfd_create + + clockid: int + A valid clock ID constant as timer file descriptor. + + time.CLOCK_REALTIME + time.CLOCK_MONOTONIC + time.CLOCK_BOOTTIME + / + * + flags: int = 0 + 0 or a bit mask of os.TFD_NONBLOCK or os.TFD_CLOEXEC. + + os.TFD_NONBLOCK + If *TFD_NONBLOCK* is set as a flag, read doesn't blocks. + If *TFD_NONBLOCK* is not set as a flag, read block until the timer fires. + + os.TFD_CLOEXEC + If *TFD_CLOEXEC* is set as a flag, enable the close-on-exec flag + +Create and return a timer file descriptor. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_create_impl(PyObject *module, int clockid, int flags) +/*[clinic end generated code: output=1caae80fb168004a input=64b7020c5ac0b8f4]*/ + +{ + int fd; + Py_BEGIN_ALLOW_THREADS + flags |= TFD_CLOEXEC; // PEP 446: always create non-inheritable FD + fd = timerfd_create(clockid, flags); + Py_END_ALLOW_THREADS + if (fd == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return PyLong_FromLong(fd); +} + +/*[clinic input] +os.timerfd_settime + + fd: fildes + A timer file descriptor. + / + * + flags: int = 0 + 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET. + initial: double = 0.0 + The initial expiration time, in seconds. + interval: double = 0.0 + The timer's interval, in seconds. + +Alter a timer file descriptor's internal timer in seconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_settime_impl(PyObject *module, int fd, int flags, double initial, + double interval) +/*[clinic end generated code: output=0dda31115317adb9 input=6c24e47e7a4d799e]*/ +{ + struct itimerspec new_value; + struct itimerspec old_value; + int result; + if (_PyTime_AsTimespec(_PyTime_FromSecondsDouble(initial, _PyTime_ROUND_FLOOR), &new_value.it_value) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid initial value"); + return NULL; + } + if (_PyTime_AsTimespec(_PyTime_FromSecondsDouble(interval, _PyTime_ROUND_FLOOR), &new_value.it_interval) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid interval value"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + result = timerfd_settime(fd, flags, &new_value, &old_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec(&old_value); +} + + +/*[clinic input] +os.timerfd_settime_ns + + fd: fildes + A timer file descriptor. + / + * + flags: int = 0 + 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET. + initial: long_long = 0 + initial expiration timing in seconds. + interval: long_long = 0 + interval for the timer in seconds. + +Alter a timer file descriptor's internal timer in nanoseconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_settime_ns_impl(PyObject *module, int fd, int flags, + long long initial, long long interval) +/*[clinic end generated code: output=6273ec7d7b4cc0b3 input=261e105d6e42f5bc]*/ +{ + struct itimerspec new_value; + struct itimerspec old_value; + int result; + if (_PyTime_AsTimespec(initial, &new_value.it_value) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid initial value"); + return NULL; + } + if (_PyTime_AsTimespec(interval, &new_value.it_interval) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid interval value"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + result = timerfd_settime(fd, flags, &new_value, &old_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec_ns(&old_value); +} + +/*[clinic input] +os.timerfd_gettime + + fd: fildes + A timer file descriptor. + / + +Return a tuple of a timer file descriptor's (interval, next expiration) in float seconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_gettime_impl(PyObject *module, int fd) +/*[clinic end generated code: output=ec5a94a66cfe6ab4 input=8148e3430870da1c]*/ +{ + struct itimerspec curr_value; + int result; + Py_BEGIN_ALLOW_THREADS + result = timerfd_gettime(fd, &curr_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec(&curr_value); +} + + +/*[clinic input] +os.timerfd_gettime_ns + + fd: fildes + A timer file descriptor. + / + +Return a tuple of a timer file descriptor's (interval, next expiration) in nanoseconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_gettime_ns_impl(PyObject *module, int fd) +/*[clinic end generated code: output=580633a4465f39fe input=a825443e4c6b40ac]*/ +{ + struct itimerspec curr_value; + int result; + Py_BEGIN_ALLOW_THREADS + result = timerfd_gettime(fd, &curr_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec_ns(&curr_value); +} + +#undef ONE_SECOND_IN_NS +#undef EXTRACT_NSEC + +#endif /* HAVE_TIMERFD_CREATE */ + #ifdef HAVE_GETSID /*[clinic input] os.getsid @@ -10422,19 +10732,24 @@ os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length) os.lseek -> Py_off_t fd: int + An open file descriptor, as returned by os.open(). position: Py_off_t - how: int + Position, interpreted relative to 'whence'. + whence as how: int + The relative position to seek from. Valid values are: + - SEEK_SET: seek from the start of the file. + - SEEK_CUR: seek from the current file position. + - SEEK_END: seek from the end of the file. / Set the position of a file descriptor. Return the new position. -Return the new cursor position in number of bytes -relative to the beginning of the file. +The return value is the number of bytes relative to the beginning of the file. [clinic start generated code]*/ static Py_off_t os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) -/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/ +/*[clinic end generated code: output=971e1efb6b30bd2f input=f096e754c5367504]*/ { Py_off_t result; @@ -10607,10 +10922,13 @@ os_readv_impl(PyObject *module, int fd, PyObject *buffers) Py_END_ALLOW_THREADS } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + int saved_errno = errno; iov_cleanup(iov, buf, cnt); if (n < 0) { - if (!async_err) + if (!async_err) { + errno = saved_errno; posix_error(); + } return -1; } @@ -10659,8 +10977,11 @@ os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset) } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (n < 0) { + if (!async_err) { + posix_error(); + } Py_DECREF(buffer); - return (!async_err) ? posix_error() : NULL; + return NULL; } if (n != length) _PyBytes_Resize(&buffer, n); @@ -10757,9 +11078,11 @@ os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, #endif + int saved_errno = errno; iov_cleanup(iov, buf, cnt); if (n < 0) { if (!async_err) { + errno = saved_errno; posix_error(); } return -1; @@ -10928,24 +11251,26 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); _Py_END_SUPPRESS_IPH + int saved_errno = errno; if (sf.headers != NULL) iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); if (sf.trailers != NULL) iov_cleanup(sf.trailers, tbuf, sf.trl_cnt); if (ret < 0) { - if ((errno == EAGAIN) || (errno == EBUSY)) { + if ((saved_errno == EAGAIN) || (saved_errno == EBUSY)) { if (sbytes != 0) { // some data has been sent goto done; } - else { - // no data has been sent; upper application is supposed - // to retry on EAGAIN or EBUSY - return posix_error(); - } + // no data has been sent; upper application is supposed + // to retry on EAGAIN or EBUSY } - return (!async_err) ? posix_error() : NULL; + if (!async_err) { + errno = saved_errno; + posix_error(); + } + return NULL; } goto done; @@ -11262,10 +11587,10 @@ os_writev_impl(PyObject *module, int fd, PyObject *buffers) Py_END_ALLOW_THREADS } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - iov_cleanup(iov, buf, cnt); if (result < 0 && !async_err) posix_error(); + iov_cleanup(iov, buf, cnt); return result; } #endif /* HAVE_WRITEV */ @@ -11283,13 +11608,13 @@ os.pwrite -> Py_ssize_t Write bytes to a file descriptor starting at a particular offset. Write buffer to fd, starting at offset bytes from the beginning of -the file. Returns the number of bytes writte. Does not change the +the file. Returns the number of bytes written. Does not change the current file offset. [clinic start generated code]*/ static Py_ssize_t os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset) -/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/ +/*[clinic end generated code: output=c74da630758ee925 input=614acbc7e5a0339a]*/ { Py_ssize_t size; int async_err = 0; @@ -11400,13 +11725,13 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, #endif - iov_cleanup(iov, buf, cnt); if (result < 0) { if (!async_err) { posix_error(); } - return -1; + result = -1; } + iov_cleanup(iov, buf, cnt); return result; } @@ -11968,12 +12293,13 @@ win32_putenv(PyObject *name, PyObject *value) Prefer _wputenv() to be compatible with C libraries using CRT variables and CRT functions using these variables (ex: getenv()). */ int err = _wputenv(env); - PyMem_Free(env); if (err) { posix_error(); + PyMem_Free(env); return NULL; } + PyMem_Free(env); Py_RETURN_NONE; } @@ -12477,7 +12803,7 @@ conv_confname(PyObject *arg, int *valuep, struct constdef *table, size_t tablesize) { if (PyLong_Check(arg)) { - int value = _PyLong_AsInt(arg); + int value = PyLong_AsInt(arg); if (value == -1 && PyErr_Occurred()) return 0; *valuep = value; @@ -13815,10 +14141,12 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, Py_END_ALLOW_THREADS; if (result < 0) { - Py_DECREF(buffer); - if (errno == ERANGE) + if (errno == ERANGE) { + Py_DECREF(buffer); continue; + } path_error(path); + Py_DECREF(buffer); return NULL; } @@ -14264,48 +14592,57 @@ os_get_terminal_size_impl(PyObject *module, int fd) } #endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ - /*[clinic input] os.cpu_count -Return the number of CPUs in the system; return None if indeterminable. +Return the number of logical CPUs in the system. -This number is not equivalent to the number of CPUs the current process can -use. The number of usable CPUs can be obtained with -``len(os.sched_getaffinity(0))`` +Return None if indeterminable. [clinic start generated code]*/ static PyObject * os_cpu_count_impl(PyObject *module) -/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/ +/*[clinic end generated code: output=5fc29463c3936a9c input=ba2f6f8980a0e2eb]*/ { + const PyConfig *config = _Py_GetConfig(); + if (config->cpu_count > 0) { + return PyLong_FromLong(config->cpu_count); + } + int ncpu = 0; #ifdef MS_WINDOWS -#ifdef MS_WINDOWS_DESKTOP +# ifdef MS_WINDOWS_DESKTOP ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); -#endif +# else + ncpu = 0; +# endif + #elif defined(__hpux) ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); + #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) ncpu = sysconf(_SC_NPROCESSORS_ONLN); + #elif defined(__VXWORKS__) ncpu = _Py_popcount32(vxCpuEnabledGet()); + #elif defined(__DragonFly__) || \ defined(__OpenBSD__) || \ defined(__FreeBSD__) || \ defined(__NetBSD__) || \ defined(__APPLE__) - int mib[2]; + ncpu = 0; size_t len = sizeof(ncpu); - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) + int mib[2] = {CTL_HW, HW_NCPU}; + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) { ncpu = 0; + } #endif - if (ncpu >= 1) - return PyLong_FromLong(ncpu); - else + + if (ncpu < 1) { Py_RETURN_NONE; + } + return PyLong_FromLong(ncpu); } @@ -14524,15 +14861,13 @@ os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class) /*[clinic input] os.DirEntry.is_junction -> bool - defining_class: defining_class - / Return True if the entry is a junction; cached per entry. [clinic start generated code]*/ static int -os_DirEntry_is_junction_impl(DirEntry *self, PyTypeObject *defining_class) -/*[clinic end generated code: output=7061a07b0ef2cd1f input=475cd36fb7d4723f]*/ +os_DirEntry_is_junction_impl(DirEntry *self) +/*[clinic end generated code: output=97f64d5d99eeccb5 input=4fc8e701eea118a1]*/ { #ifdef MS_WINDOWS return self->win32_lstat.st_reparse_tag == IO_REPARSE_TAG_MOUNT_POINT; @@ -14585,14 +14920,19 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) } Py_END_ALLOW_THREADS } + + int saved_errno = errno; #if defined(MS_WINDOWS) PyMem_Free(path); #else Py_DECREF(ub); #endif - if (result != 0) - return path_object_error(self->path); + if (result != 0) { + errno = saved_errno; + path_object_error(self->path); + return NULL; + } return _pystat_fromstructstat(module, &st); } @@ -14784,10 +15124,14 @@ os_DirEntry_inode_impl(DirEntry *self) wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL); Py_DECREF(unicode); result = LSTAT(path, &stat); + + int saved_errno = errno; PyMem_Free(path); - if (result != 0) + if (result != 0) { + errno = saved_errno; return path_object_error(self->path); + } self->win32_file_index = stat.st_ino; self->got_file_index = 1; @@ -14822,9 +15166,9 @@ os_DirEntry___fspath___impl(DirEntry *self) } static PyMemberDef DirEntry_members[] = { - {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY, + {"name", Py_T_OBJECT_EX, offsetof(DirEntry, name), Py_READONLY, "the entry's base filename, relative to scandir() \"path\" argument"}, - {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY, + {"path", Py_T_OBJECT_EX, offsetof(DirEntry, path), Py_READONLY, "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"}, {NULL} }; @@ -15351,12 +15695,12 @@ os_scandir_impl(PyObject *module, path_t *path) iterator->handle = FindFirstFileW(path_strW, &iterator->file_data); Py_END_ALLOW_THREADS - PyMem_Free(path_strW); - if (iterator->handle == INVALID_HANDLE_VALUE) { path_error(&iterator->path); + PyMem_Free(path_strW); goto error; } + PyMem_Free(path_strW); #else /* POSIX */ errno = 0; #ifdef HAVE_FDOPENDIR @@ -15661,7 +16005,7 @@ os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj) /*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/ { #ifndef MS_WINDOWS - int status = _PyLong_AsInt(status_obj); + int status = PyLong_AsInt(status_obj); if (status == -1 && PyErr_Occurred()) { return NULL; } @@ -15878,6 +16222,7 @@ static PyMethodDef posix_methods[] = { OS__GETFULLPATHNAME_METHODDEF OS__GETDISKUSAGE_METHODDEF OS__GETFINALPATHNAME_METHODDEF + OS__FINDFIRSTFILE_METHODDEF OS__GETVOLUMEPATHNAME_METHODDEF OS__PATH_SPLITROOT_METHODDEF OS__PATH_NORMPATH_METHODDEF @@ -15913,6 +16258,11 @@ static PyMethodDef posix_methods[] = { OS_WAITSTATUS_TO_EXITCODE_METHODDEF OS_SETNS_METHODDEF OS_UNSHARE_METHODDEF + OS_TIMERFD_CREATE_METHODDEF + OS_TIMERFD_SETTIME_METHODDEF + OS_TIMERFD_SETTIME_NS_METHODDEF + OS_TIMERFD_GETTIME_METHODDEF + OS_TIMERFD_GETTIME_NS_METHODDEF OS__PATH_ISDEVDRIVE_METHODDEF OS__PATH_ISDIR_METHODDEF @@ -16228,6 +16578,19 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, SF_NOCACHE)) return -1; #endif +#ifdef TFD_NONBLOCK + if (PyModule_AddIntMacro(m, TFD_NONBLOCK)) return -1; +#endif +#ifdef TFD_CLOEXEC + if (PyModule_AddIntMacro(m, TFD_CLOEXEC)) return -1; +#endif +#ifdef TFD_TIMER_ABSTIME + if (PyModule_AddIntMacro(m, TFD_TIMER_ABSTIME)) return -1; +#endif +#ifdef TFD_TIMER_CANCEL_ON_SET + if (PyModule_AddIntMacro(m, TFD_TIMER_CANCEL_ON_SET)) return -1; +#endif + /* constants for posix_fadvise */ #ifdef POSIX_FADV_NORMAL if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1; @@ -16626,6 +16989,10 @@ static const struct have_function { {"HAVE_EVENTFD", NULL}, #endif +#ifdef HAVE_TIMERFD_CREATE + {"HAVE_TIMERFD_CREATE", NULL}, +#endif + #ifdef HAVE_FACCESSAT { "HAVE_FACCESSAT", probe_faccessat }, #endif @@ -16925,7 +17292,3 @@ INITFUNC(void) { return PyModuleDef_Init(&posixmodule); } - -#ifdef __cplusplus -} -#endif diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h index 5452ffbf17acfc..8827ce153fed8c 100644 --- a/Modules/posixmodule.h +++ b/Modules/posixmodule.h @@ -2,31 +2,37 @@ #ifndef Py_POSIXMODULE_H #define Py_POSIXMODULE_H +#ifndef Py_LIMITED_API #ifdef __cplusplus extern "C" { #endif #ifdef HAVE_SYS_TYPES_H -#include +# include // uid_t #endif -#ifndef Py_LIMITED_API #ifndef MS_WINDOWS -PyAPI_FUNC(PyObject *) _PyLong_FromUid(uid_t); -PyAPI_FUNC(PyObject *) _PyLong_FromGid(gid_t); +extern PyObject* _PyLong_FromUid(uid_t); + +// Export for 'grp' shared extension +PyAPI_FUNC(PyObject*) _PyLong_FromGid(gid_t); + +// Export for '_posixsubprocess' shared extension PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, uid_t *); + +// Export for 'grp' shared extension PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, gid_t *); -#endif /* MS_WINDOWS */ +#endif // !MS_WINDOWS -#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ - defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) -# define HAVE_SIGSET_T +#if (defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) \ + || defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)) +# define HAVE_SIGSET_T #endif -PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); -#endif /* Py_LIMITED_API */ +extern int _Py_Sigset_Converter(PyObject *, void *); #ifdef __cplusplus } #endif -#endif /* !Py_POSIXMODULE_H */ +#endif // !Py_LIMITED_API +#endif // !Py_POSIXMODULE_H diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index cc2e2a43893971..b7034369c4731e 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -4,7 +4,8 @@ #include "Python.h" #include "posixmodule.h" -#include +#include // getpwuid() +#include // sysconf() #include "clinic/pwdmodule.c.h" /*[clinic input] diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index bd8a98a46579a3..bd24523eac830b 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -4,11 +4,11 @@ #include "Python.h" #include "pycore_import.h" // _PyImport_SetModule() -#include +#include "pycore_pyhash.h" // _Py_HashSecret +#include "pycore_traceback.h" // _PyTraceback_Add() -#include "structmember.h" // PyMemberDef +#include // offsetof() #include "expat.h" - #include "pyexpat.h" /* Do not emit Clinic output to a file as that wreaks havoc with conditionally @@ -1470,7 +1470,7 @@ xmlparse_specified_attributes_setter(xmlparseobject *self, PyObject *v, void *cl } static PyMemberDef xmlparse_members[] = { - {"intern", T_OBJECT, offsetof(xmlparseobject, intern), READONLY, NULL}, + {"intern", _Py_T_OBJECT, offsetof(xmlparseobject, intern), Py_READONLY, NULL}, {NULL} }; @@ -1655,8 +1655,7 @@ add_submodule(PyObject *mod, const char *fullname) Py_DECREF(mod_name); /* gives away the reference to the submodule */ - if (PyModule_AddObject(mod, name, submodule) < 0) { - Py_DECREF(submodule); + if (PyModule_Add(mod, name, submodule) < 0) { return NULL; } @@ -1886,10 +1885,7 @@ add_features(PyObject *mod) goto error; } } - if (PyModule_AddObject(mod, "features", list) < 0) { - goto error; - } - return 0; + return PyModule_Add(mod, "features", list); error: Py_DECREF(list); @@ -1958,8 +1954,7 @@ pyexpat_exec(PyObject *mod) info.major, info.minor, info.micro); - if (PyModule_AddObject(mod, "version_info", versionInfo) < 0) { - Py_DECREF(versionInfo); + if (PyModule_Add(mod, "version_info", versionInfo) < 0) { return -1; } } @@ -2039,8 +2034,7 @@ pyexpat_exec(PyObject *mod) return -1; } - if (PyModule_AddObject(mod, "expat_CAPI", capi_object) < 0) { - Py_DECREF(capi_object); + if (PyModule_Add(mod, "expat_CAPI", capi_object) < 0) { return -1; } diff --git a/Modules/readline.c b/Modules/readline.c index a592919692cb83..fde552d124bc77 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -12,14 +12,13 @@ #include "Python.h" #include "pycore_pylifecycle.h" // _Py_SetLocaleFromEnv() -#include -#include -#include +#include // errno +#include // SIGWINCH #include // free() -#ifdef HAVE_SYS_TIME_H -#include +#include // strdup() +#ifdef HAVE_SYS_SELECT_H +# include // select() #endif -#include #if defined(HAVE_SETLOCALE) /* GNU readline() mistakenly sets the LC_CTYPE locale. @@ -27,7 +26,7 @@ * We must save and restore the locale around the rl_initialize() call. */ #define SAVE_LOCALE -#include +# include // setlocale() #endif #ifdef SAVE_LOCALE @@ -447,7 +446,7 @@ readline_set_completion_display_matches_hook_impl(PyObject *module, default completion display. */ rl_completion_display_matches_hook = readlinestate_global->completion_display_matches_hook ? -#if defined(_RL_FUNCTION_TYPEDEF) +#if defined(HAVE_RL_COMPDISP_FUNC_T) (rl_compdisp_func_t *)on_completion_display_matches_hook : 0; #else (VFunction *)on_completion_display_matches_hook : 0; @@ -1001,7 +1000,7 @@ on_hook(PyObject *func) if (r == Py_None) result = 0; else { - result = _PyLong_AsInt(r); + result = PyLong_AsInt(r); if (result == -1 && PyErr_Occurred()) goto error; } @@ -1019,6 +1018,8 @@ on_hook(PyObject *func) static int #if defined(_RL_FUNCTION_TYPEDEF) on_startup_hook(void) +#elif defined(WITH_APPLE_EDITLINE) +on_startup_hook(const char *Py_UNUSED(text), int Py_UNUSED(state)) #else on_startup_hook(void) #endif @@ -1034,6 +1035,8 @@ on_startup_hook(void) static int #if defined(_RL_FUNCTION_TYPEDEF) on_pre_input_hook(void) +#elif defined(WITH_APPLE_EDITLINE) +on_pre_input_hook(const char *Py_UNUSED(text), int Py_UNUSED(state)) #else on_pre_input_hook(void) #endif @@ -1313,6 +1316,9 @@ rlhandler(char *text) static char * readline_until_enter_or_signal(const char *prompt, int *signal) { + // Defined in Parser/myreadline.c + extern PyThreadState *_PyOS_ReadlineTState; + char * not_done_reading = ""; fd_set selectset; @@ -1330,7 +1336,8 @@ readline_until_enter_or_signal(const char *prompt, int *signal) int has_input = 0, err = 0; while (!has_input) - { struct timeval timeout = {0, 100000}; /* 0.1 seconds */ + { + struct timeval timeout = {0, 100000}; // 100 ms (0.1 seconds) /* [Bug #1552726] Only limit the pause if an input hook has been defined. */ diff --git a/Modules/resource.c b/Modules/resource.c index 3c89468c48c56e..d65509ec3436a2 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -1,13 +1,8 @@ - #include "Python.h" -#include -#ifdef HAVE_SYS_TIME_H -#include -#endif -#include +#include // errno #include -#include -#include +#include // getrusage() +#include // getpagesize() /* On some systems, these aren't in any header file. On others they are, with inconsistent prototypes. @@ -28,15 +23,16 @@ class pid_t_converter(CConverter): type = 'pid_t' format_unit = '" _Py_PARSE_PID "' - def parse_arg(self, argname, displayname): - return """ + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" {paramname} = PyLong_AsPid({argname}); if ({paramname} == -1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=c94349aa1aad151d]*/ #include "clinic/resource.c.h" @@ -372,9 +368,7 @@ resource_exec(PyObject *module) } while (0) /* Add some symbolic constants to the module */ - Py_INCREF(PyExc_OSError); - if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { - Py_DECREF(PyExc_OSError); + if (PyModule_AddObjectRef(module, "error", PyExc_OSError) < 0) { return -1; } @@ -502,12 +496,7 @@ resource_exec(PyObject *module) { v = PyLong_FromLong((long) RLIM_INFINITY); } - if (!v) { - return -1; - } - - if (PyModule_AddObject(module, "RLIM_INFINITY", v) < 0) { - Py_DECREF(v); + if (PyModule_Add(module, "RLIM_INFINITY", v) < 0) { return -1; } return 0; diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 7ab0804ad27233..c56e682b21e2a1 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -15,7 +15,11 @@ #include "Python.h" #include "pycore_fileutils.h" // _Py_set_inheritable() #include "pycore_time.h" // _PyTime_t -#include "structmember.h" // PyMemberDef + +#include // offsetof() +#ifndef MS_WINDOWS +# include // close() +#endif #ifdef HAVE_SYS_DEVPOLL_H #include @@ -1293,8 +1297,8 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) self->epfd = fd; } if (self->epfd < 0) { - Py_DECREF(self); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(self); return NULL; } @@ -1758,18 +1762,18 @@ typedef struct { #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) # error uintptr_t does not match void *! #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) -# define T_UINTPTRT T_ULONGLONG -# define T_INTPTRT T_LONGLONG +# define T_UINTPTRT Py_T_ULONGLONG +# define T_INTPTRT Py_T_LONGLONG # define UINTPTRT_FMT_UNIT "K" # define INTPTRT_FMT_UNIT "L" #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) -# define T_UINTPTRT T_ULONG -# define T_INTPTRT T_LONG +# define T_UINTPTRT Py_T_ULONG +# define T_INTPTRT Py_T_LONG # define UINTPTRT_FMT_UNIT "k" # define INTPTRT_FMT_UNIT "l" #elif (SIZEOF_UINTPTR_T == SIZEOF_INT) -# define T_UINTPTRT T_UINT -# define T_INTPTRT T_INT +# define T_UINTPTRT Py_T_UINT +# define T_INTPTRT Py_T_INT # define UINTPTRT_FMT_UNIT "I" # define INTPTRT_FMT_UNIT "i" #else @@ -1777,26 +1781,26 @@ typedef struct { #endif #if SIZEOF_LONG_LONG == 8 -# define T_INT64 T_LONGLONG +# define T_INT64 Py_T_LONGLONG # define INT64_FMT_UNIT "L" #elif SIZEOF_LONG == 8 -# define T_INT64 T_LONG +# define T_INT64 Py_T_LONG # define INT64_FMT_UNIT "l" #elif SIZEOF_INT == 8 -# define T_INT64 T_INT +# define T_INT64 Py_T_INT # define INT64_FMT_UNIT "i" #else # define INT64_FMT_UNIT "_" #endif #if SIZEOF_LONG_LONG == 4 -# define T_UINT32 T_ULONGLONG +# define T_UINT32 Py_T_ULONGLONG # define UINT32_FMT_UNIT "K" #elif SIZEOF_LONG == 4 -# define T_UINT32 T_ULONG +# define T_UINT32 Py_T_ULONG # define UINT32_FMT_UNIT "k" #elif SIZEOF_INT == 4 -# define T_UINT32 T_UINT +# define T_UINT32 Py_T_UINT # define UINT32_FMT_UNIT "I" #else # define UINT32_FMT_UNIT "_" @@ -1813,11 +1817,11 @@ typedef struct { # define FFLAGS_TYPE T_UINT32 # define FFLAGS_FMT_UNIT UINT32_FMT_UNIT #else -# define FILTER_TYPE T_SHORT +# define FILTER_TYPE Py_T_SHORT # define FILTER_FMT_UNIT "h" -# define FLAGS_TYPE T_USHORT +# define FLAGS_TYPE Py_T_USHORT # define FLAGS_FMT_UNIT "H" -# define FFLAGS_TYPE T_UINT +# define FFLAGS_TYPE Py_T_UINT # define FFLAGS_FMT_UNIT "I" #endif @@ -1839,7 +1843,7 @@ static struct PyMemberDef kqueue_event_members[] = { {"ident", T_UINTPTRT, KQ_OFF(e.ident)}, {"filter", FILTER_TYPE, KQ_OFF(e.filter)}, {"flags", FLAGS_TYPE, KQ_OFF(e.flags)}, - {"fflags", T_UINT, KQ_OFF(e.fflags)}, + {"fflags", Py_T_UINT, KQ_OFF(e.fflags)}, {"data", DATA_TYPE, KQ_OFF(e.data)}, {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, {NULL} /* Sentinel */ @@ -1972,8 +1976,8 @@ newKqueue_Object(PyTypeObject *type, SOCKET fd) self->kqfd = fd; } if (self->kqfd < 0) { - Py_DECREF(self); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(self); return NULL; } diff --git a/Modules/sha1module.c b/Modules/sha1module.c index ef8e067dd337b3..3fd53123229ac4 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -357,16 +357,9 @@ _sha1_exec(PyObject *module) st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec( module, &sha1_type_spec, NULL); - - if (st->sha1_type == NULL) { - return -1; - } - - Py_INCREF(st->sha1_type); - if (PyModule_AddObject(module, + if (PyModule_AddObjectRef(module, "SHA1Type", (PyObject *)st->sha1_type) < 0) { - Py_DECREF(st->sha1_type); return -1; } diff --git a/Modules/sha2module.c b/Modules/sha2module.c index db3774c81e2d92..6ad1ff2e05bfd8 100644 --- a/Modules/sha2module.c +++ b/Modules/sha2module.c @@ -25,7 +25,7 @@ #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_typeobject.h" // _PyType_GetModuleState() #include "pycore_strhex.h" // _Py_strhex() -#include "structmember.h" // PyMemberDef + #include "hashlib.h" /*[clinic input] diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 3adb2e8dfe58d8..bc5cdf0ab6b5f2 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -4,7 +4,6 @@ /* XXX Signals should be recorded per thread, now we have thread state. */ #include "Python.h" -#include "pycore_atomic.h" // _Py_atomic_int #include "pycore_call.h" // _PyObject_Call() #include "pycore_ceval.h" // _PyEval_SignalReceived() #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS @@ -16,10 +15,10 @@ #include "pycore_signal.h" // _Py_RestoreSignals() #ifndef MS_WINDOWS -# include "posixmodule.h" +# include "posixmodule.h" // _PyLong_FromUid() #endif #ifdef MS_WINDOWS -# include "socketmodule.h" /* needed for SOCKET_T */ +# include "socketmodule.h" // SOCKET_T #endif #ifdef MS_WINDOWS @@ -29,16 +28,16 @@ #endif #ifdef HAVE_SIGNAL_H -# include +# include // sigaction() #endif #ifdef HAVE_SYS_SYSCALL_H -# include +# include // __NR_pidfd_send_signal #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_SYS_TIME_H -# include +# include // setitimer() #endif #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) @@ -124,13 +123,15 @@ typedef struct { Py_LOCAL_INLINE(PyObject *) get_handler(int i) { - return (PyObject *)_Py_atomic_load(&Handlers[i].func); + return (PyObject *)_Py_atomic_load_ptr(&Handlers[i].func); } Py_LOCAL_INLINE(void) set_handler(int i, PyObject* func) { - _Py_atomic_store(&Handlers[i].func, (uintptr_t)func); + /* Store func with atomic operation to ensure + that PyErr_SetInterrupt is async-signal-safe. */ + _Py_atomic_store_ptr(&Handlers[i].func, func); } @@ -267,11 +268,11 @@ report_wakeup_send_error(void* data) static void trip_signal(int sig_num) { - _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1); + _Py_atomic_store_int(&Handlers[sig_num].tripped, 1); /* Set is_tripped after setting .tripped, as it gets cleared in PyErr_CheckSignals() before .tripped. */ - _Py_atomic_store(&is_tripped, 1); + _Py_atomic_store_int(&is_tripped, 1); /* Signals are always handled by the main interpreter */ PyInterpreterState *interp = _PyInterpreterState_Main(); @@ -315,7 +316,7 @@ trip_signal(int sig_num) _PyEval_AddPendingCall(interp, report_wakeup_send_error, (void *)(intptr_t) last_error, - 1); + _Py_PENDING_MAINTHREADONLY); } } } @@ -335,7 +336,7 @@ trip_signal(int sig_num) _PyEval_AddPendingCall(interp, report_wakeup_write_error, (void *)(intptr_t)errno, - 1); + _Py_PENDING_MAINTHREADONLY); } } } @@ -1731,7 +1732,7 @@ _PySignal_Fini(void) // Restore default signals and clear handlers for (int signum = 1; signum < Py_NSIG; signum++) { PyObject *func = get_handler(signum); - _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0); + _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0); set_handler(signum, NULL); if (func != NULL && func != Py_None @@ -1767,9 +1768,8 @@ PyErr_CheckSignals(void) Python code to ensure signals are handled. Checking for the GC here allows long running native code to clean cycles created using the C-API even if it doesn't run the evaluation loop */ - struct _ceval_state *interp_ceval_state = &tstate->interp->ceval; - if (_Py_atomic_load_relaxed(&interp_ceval_state->gc_scheduled)) { - _Py_atomic_store_relaxed(&interp_ceval_state->gc_scheduled, 0); + if (_Py_eval_breaker_bit_is_set(tstate->interp, _PY_GC_SCHEDULED_BIT)) { + _Py_set_eval_breaker_bit(tstate->interp, _PY_GC_SCHEDULED_BIT, 0); _Py_RunGC(tstate); } @@ -1786,7 +1786,7 @@ int _PyErr_CheckSignalsTstate(PyThreadState *tstate) { _Py_CHECK_EMSCRIPTEN_SIGNALS(); - if (!_Py_atomic_load(&is_tripped)) { + if (!_Py_atomic_load_int(&is_tripped)) { return 0; } @@ -1804,15 +1804,15 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) * we receive a signal i after we zero is_tripped and before we * check Handlers[i].tripped. */ - _Py_atomic_store(&is_tripped, 0); + _Py_atomic_store_int(&is_tripped, 0); _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); signal_state_t *state = &signal_global_state; for (int i = 1; i < Py_NSIG; i++) { - if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) { + if (!_Py_atomic_load_int_relaxed(&Handlers[i].tripped)) { continue; } - _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); + _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0); /* Signal handlers can be modified while a signal is received, * and therefore the fact that trip_signal() or PyErr_SetInterrupt() @@ -1858,7 +1858,7 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) } if (!result) { /* On error, re-schedule a call to _PyErr_CheckSignalsTstate() */ - _Py_atomic_store(&is_tripped, 1); + _Py_atomic_store_int(&is_tripped, 1); return -1; } @@ -1976,7 +1976,7 @@ _PySignal_Init(int install_signal_handlers) #endif for (int signum = 1; signum < Py_NSIG; signum++) { - _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0); + _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0); } if (install_signal_handlers) { @@ -1998,11 +1998,11 @@ _PyOS_InterruptOccurred(PyThreadState *tstate) return 0; } - if (!_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) { + if (!_Py_atomic_load_int_relaxed(&Handlers[SIGINT].tripped)) { return 0; } - _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0); + _Py_atomic_store_int_relaxed(&Handlers[SIGINT].tripped, 0); return 1; } @@ -2020,13 +2020,13 @@ PyOS_InterruptOccurred(void) static void _clear_pending_signals(void) { - if (!_Py_atomic_load(&is_tripped)) { + if (!_Py_atomic_load_int(&is_tripped)) { return; } - _Py_atomic_store(&is_tripped, 0); + _Py_atomic_store_int(&is_tripped, 0); for (int i = 1; i < Py_NSIG; ++i) { - _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); + _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0); } } diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 39bbc911712376..3d099d41d1e761 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -106,12 +106,13 @@ Local naming conventions: #endif #include "Python.h" +#include "pycore_capsule.h" // _PyCapsule_SetTraverse() +#include "pycore_dict.h" // _PyDict_Pop() #include "pycore_fileutils.h" // _Py_set_inheritable() #include "pycore_moduleobject.h" // _PyModule_GetState -#include "structmember.h" // PyMemberDef #ifdef _Py_MEMORY_SANITIZER -# include +# include #endif /* Socket object documentation */ @@ -263,7 +264,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\ #ifdef HAVE_NETDB_H # include #endif -# include +#include // close() /* Headers needed for inet_ntoa() and inet_addr() */ # include @@ -4878,17 +4879,17 @@ sock_sendmsg_afalg(PySocketSockObject *self, PyObject *args, PyObject *kwds) /* op is a required, keyword-only argument >= 0 */ if (opobj != NULL) { - op = _PyLong_AsInt(opobj); + op = PyLong_AsInt(opobj); } if (op < 0) { - /* override exception from _PyLong_AsInt() */ + /* override exception from PyLong_AsInt() */ PyErr_SetString(PyExc_TypeError, "Invalid or missing argument 'op'"); goto finally; } /* assoclen is optional but must be >= 0 */ if (assoclenobj != NULL) { - assoclen = _PyLong_AsInt(assoclenobj); + assoclen = PyLong_AsInt(assoclenobj); if (assoclen == -1 && PyErr_Occurred()) { goto finally; } @@ -5006,7 +5007,7 @@ sock_shutdown(PySocketSockObject *s, PyObject *arg) int how; int res; - how = _PyLong_AsInt(arg); + how = PyLong_AsInt(arg); if (how == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS @@ -5205,9 +5206,9 @@ static PyMethodDef sock_methods[] = { /* SockObject members */ static PyMemberDef sock_memberlist[] = { - {"family", T_INT, offsetof(PySocketSockObject, sock_family), READONLY, "the socket family"}, - {"type", T_INT, offsetof(PySocketSockObject, sock_type), READONLY, "the socket type"}, - {"proto", T_INT, offsetof(PySocketSockObject, sock_proto), READONLY, "the socket protocol"}, + {"family", Py_T_INT, offsetof(PySocketSockObject, sock_family), Py_READONLY, "the socket family"}, + {"type", Py_T_INT, offsetof(PySocketSockObject, sock_type), Py_READONLY, "the socket type"}, + {"proto", Py_T_INT, offsetof(PySocketSockObject, sock_proto), Py_READONLY, "the socket protocol"}, {0}, }; @@ -5397,8 +5398,8 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, } if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0)) { - closesocket(fd); PyErr_SetFromWindowsErr(0); + closesocket(fd); return -1; } @@ -5612,8 +5613,9 @@ socket_gethostname(PyObject *self, PyObject *unused) name, &size)) { + PyErr_SetFromWindowsErr(0); PyMem_Free(name); - return PyErr_SetFromWindowsErr(0); + return NULL; } result = PyUnicode_FromWideChar(name, size); @@ -5650,8 +5652,9 @@ socket_sethostname(PyObject *self, PyObject *args) Py_buffer buf; int res, flag = 0; -#ifdef _AIX -/* issue #18259, not declared in any useful header file */ +#if defined(_AIX) || (defined(__sun) && defined(__SVR4) && Py_SUNOS_VERSION <= 510) +/* issue #18259, sethostname is not declared in any useful header file on AIX + * the same is true for Solaris 10 */ extern int sethostname(const char *, size_t); #endif @@ -5779,9 +5782,15 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr, /* SF #1511317: h_aliases can be NULL */ if (h->h_aliases) { - for (pch = h->h_aliases; *pch != NULL; pch++) { + for (pch = h->h_aliases; ; pch++) { int status; - tmp = PyUnicode_FromString(*pch); + char *host_alias; + // pch can be misaligned + memcpy(&host_alias, pch, sizeof(host_alias)); + if (host_alias == NULL) { + break; + } + tmp = PyUnicode_FromString(host_alias); if (tmp == NULL) goto err; @@ -5793,8 +5802,14 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr, } } - for (pch = h->h_addr_list; *pch != NULL; pch++) { + for (pch = h->h_addr_list; ; pch++) { int status; + char *host_address; + // pch can be misaligned + memcpy(&host_address, pch, sizeof(host_address)); + if (host_address == NULL) { + break; + } switch (af) { @@ -5806,7 +5821,7 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr, #ifdef HAVE_SOCKADDR_SA_LEN sin.sin_len = sizeof(sin); #endif - memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr)); + memcpy(&sin.sin_addr, host_address, sizeof(sin.sin_addr)); tmp = make_ipv4_addr(&sin); if (pch == h->h_addr_list && alen >= sizeof(sin)) @@ -5823,7 +5838,7 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr, #ifdef HAVE_SOCKADDR_SA_LEN sin6.sin6_len = sizeof(sin6); #endif - memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr)); + memcpy(&sin6.sin6_addr, host_address, sizeof(sin6.sin6_addr)); tmp = make_ipv6_addr(&sin6); if (pch == h->h_addr_list && alen >= sizeof(sin6)) @@ -6199,8 +6214,8 @@ socket_dup(PyObject *self, PyObject *fdobj) } if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { - closesocket(newfd); PyErr_SetFromWindowsErr(0); + closesocket(newfd); return NULL; } #else @@ -6647,11 +6662,12 @@ socket_inet_ntop(PyObject *self, PyObject *args) /* inet_ntop guarantee NUL-termination of resulting string. */ retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip)); - PyBuffer_Release(&packed_ip); if (!retval) { PyErr_SetFromErrno(PyExc_OSError); + PyBuffer_Release(&packed_ip); return NULL; } else { + PyBuffer_Release(&packed_ip); return PyUnicode_FromString(retval); } } @@ -6990,8 +7006,8 @@ socket_if_nameindex(PyObject *self, PyObject *arg) ni = if_nameindex(); if (ni == NULL) { - Py_DECREF(list); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(list); return NULL; } @@ -7302,20 +7318,39 @@ os_init(void) } #endif +static int +sock_capi_traverse(PyObject *capsule, visitproc visit, void *arg) +{ + PySocketModule_APIObject *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME); + assert(capi != NULL); + Py_VISIT(capi->Sock_Type); + return 0; +} + +static int +sock_capi_clear(PyObject *capsule) +{ + PySocketModule_APIObject *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME); + assert(capi != NULL); + Py_CLEAR(capi->Sock_Type); + return 0; +} + static void -sock_free_api(PySocketModule_APIObject *capi) +sock_capi_free(PySocketModule_APIObject *capi) { - Py_DECREF(capi->Sock_Type); + Py_XDECREF(capi->Sock_Type); // sock_capi_free() can clear it Py_DECREF(capi->error); Py_DECREF(capi->timeout_error); PyMem_Free(capi); } static void -sock_destroy_api(PyObject *capsule) +sock_capi_destroy(PyObject *capsule) { void *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME); - sock_free_api(capi); + assert(capi != NULL); + sock_capi_free(capi); } static PySocketModule_APIObject * @@ -7420,11 +7455,17 @@ socket_exec(PyObject *m) } PyObject *capsule = PyCapsule_New(capi, PySocket_CAPSULE_NAME, - sock_destroy_api); + sock_capi_destroy); if (capsule == NULL) { - sock_free_api(capi); + sock_capi_free(capi); goto error; } + if (_PyCapsule_SetTraverse(capsule, + sock_capi_traverse, sock_capi_clear) < 0) { + sock_capi_free(capi); + goto error; + } + if (PyModule_Add(m, PySocket_CAPI_NAME, capsule) < 0) { goto error; } diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 663ae3d6e0dd6c..47146a28e02c8f 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -100,6 +100,8 @@ typedef int socklen_t; # include # endif # include +#elif defined(HAVE_NETLINK_NETLINK_H) +# include #else # undef AF_NETLINK #endif diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index 1cc319cc3410d8..ddc9ac3324356d 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_pythonrun.h" // _Py_SourceAsString() #include "pycore_symtable.h" // struct symtable #include "clinic/symtablemodule.c.h" @@ -85,6 +86,14 @@ symtable_init_constants(PyObject *m) if (PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock) < 0) return -1; if (PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock) < 0) return -1; + if (PyModule_AddIntConstant(m, "TYPE_ANNOTATION", AnnotationBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_VAR_BOUND", TypeVarBoundBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_ALIAS", TypeAliasBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_PARAM", TypeParamBlock) < 0) + return -1; if (PyModule_AddIntMacro(m, LOCAL) < 0) return -1; if (PyModule_AddIntMacro(m, GLOBAL_EXPLICIT) < 0) return -1; diff --git a/Modules/termios.c b/Modules/termios.c index 6dc8200572bc0c..9fc2673ce0e788 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -1,11 +1,22 @@ /* termios.c -- POSIX terminal I/O module implementation. */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" -/* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE - is defined, so we define it here. */ +// On QNX 6, struct termio must be declared by including sys/termio.h +// if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must +// be included before termios.h or it will generate an error. +#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux) +# include +#endif + +// Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE +// is defined, so we define it here. #if defined(__sgi) -#define CTRL(c) ((c)&037) +# define CTRL(c) ((c)&037) #endif #if defined(__sun) @@ -16,6 +27,9 @@ #include #include +#if defined(__sun) && defined(__SVR4) +# include // ioctl() +#endif /* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR, * MDTR, MRI, and MRTS (apparently used internally by some things @@ -106,7 +120,7 @@ termios_tcgetattr_impl(PyObject *module, int fd) v = PyBytes_FromStringAndSize(&ch, 1); if (v == NULL) goto err; - PyList_SetItem(cc, i, v); + PyList_SET_ITEM(cc, i, v); } /* Convert the MIN and TIME slots to integer. On some systems, the @@ -114,29 +128,44 @@ termios_tcgetattr_impl(PyObject *module, int fd) only do this in noncanonical input mode. */ if ((mode.c_lflag & ICANON) == 0) { v = PyLong_FromLong((long)mode.c_cc[VMIN]); - if (v == NULL) + if (v == NULL) { goto err; - PyList_SetItem(cc, VMIN, v); + } + if (PyList_SetItem(cc, VMIN, v) < 0) { + goto err; + } v = PyLong_FromLong((long)mode.c_cc[VTIME]); - if (v == NULL) + if (v == NULL) { goto err; - PyList_SetItem(cc, VTIME, v); + } + if (PyList_SetItem(cc, VTIME, v) < 0) { + goto err; + } } - if (!(v = PyList_New(7))) - goto err; - - PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag)); - PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag)); - PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag)); - PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag)); - PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed)); - PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed)); - if (PyErr_Occurred()) { - Py_DECREF(v); + if (!(v = PyList_New(7))) { goto err; } - PyList_SetItem(v, 6, cc); + +#define ADD_LONG_ITEM(index, val) \ + do { \ + PyObject *l = PyLong_FromLong((long)val); \ + if (l == NULL) { \ + Py_DECREF(v); \ + goto err; \ + } \ + PyList_SET_ITEM(v, index, l); \ + } while (0) + + ADD_LONG_ITEM(0, mode.c_iflag); + ADD_LONG_ITEM(1, mode.c_oflag); + ADD_LONG_ITEM(2, mode.c_cflag); + ADD_LONG_ITEM(3, mode.c_lflag); + ADD_LONG_ITEM(4, ispeed); + ADD_LONG_ITEM(5, ospeed); +#undef ADD_LONG_ITEM + + PyList_SET_ITEM(v, 6, cc); return v; err: Py_DECREF(cc); @@ -183,17 +212,25 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term) return PyErr_SetFromErrno(state->TermiosError); } - mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0)); - mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1)); - mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2)); - mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3)); - speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); - speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); - PyObject *cc = PyList_GetItem(term, 6); - if (PyErr_Occurred()) { - return NULL; - } - + speed_t ispeed, ospeed; +#define SET_FROM_LIST(TYPE, VAR, LIST, N) do { \ + PyObject *item = PyList_GET_ITEM(LIST, N); \ + long num = PyLong_AsLong(item); \ + if (num == -1 && PyErr_Occurred()) { \ + return NULL; \ + } \ + VAR = (TYPE)num; \ +} while (0) + + SET_FROM_LIST(tcflag_t, mode.c_iflag, term, 0); + SET_FROM_LIST(tcflag_t, mode.c_oflag, term, 1); + SET_FROM_LIST(tcflag_t, mode.c_cflag, term, 2); + SET_FROM_LIST(tcflag_t, mode.c_lflag, term, 3); + SET_FROM_LIST(speed_t, ispeed, term, 4); + SET_FROM_LIST(speed_t, ospeed, term, 5); +#undef SET_FROM_LIST + + PyObject *cc = PyList_GET_ITEM(term, 6); if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { PyErr_Format(PyExc_TypeError, "tcsetattr: attributes[6] must be %d element list", @@ -208,8 +245,13 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term) if (PyBytes_Check(v) && PyBytes_Size(v) == 1) mode.c_cc[i] = (cc_t) * PyBytes_AsString(v); - else if (PyLong_Check(v)) - mode.c_cc[i] = (cc_t) PyLong_AsLong(v); + else if (PyLong_Check(v)) { + long num = PyLong_AsLong(v); + if (num == -1 && PyErr_Occurred()) { + return NULL; + } + mode.c_cc[i] = (cc_t)num; + } else { PyErr_SetString(PyExc_TypeError, "tcsetattr: elements of attributes must be characters or integers"); @@ -1232,12 +1274,7 @@ termios_exec(PyObject *mod) struct constant *constant = termios_constants; termiosmodulestate *state = get_termios_state(mod); state->TermiosError = PyErr_NewException("termios.error", NULL, NULL); - if (state->TermiosError == NULL) { - return -1; - } - Py_INCREF(state->TermiosError); - if (PyModule_AddObject(mod, "error", state->TermiosError) < 0) { - Py_DECREF(state->TermiosError); + if (PyModule_AddObjectRef(mod, "error", state->TermiosError) < 0) { return -1; } diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 912710219bd014..6a872a285d289b 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -6,22 +6,21 @@ #include "pycore_namespace.h" // _PyNamespace_New() #include "pycore_runtime.h" // _Py_ID() -#include - +#include // clock() #ifdef HAVE_SYS_TIMES_H -# include +# include // times() #endif #ifdef HAVE_SYS_TYPES_H # include #endif #if defined(HAVE_SYS_RESOURCE_H) -# include +# include // getrusage(RUSAGE_SELF) #endif #ifdef QUICKWIN # include #endif #if defined(HAVE_PTHREAD_H) -# include +# include // pthread_getcpuclockid() #endif #if defined(_AIX) # include @@ -414,6 +413,10 @@ Return the clk_id of a thread's CPU time clock."); static PyObject * time_sleep(PyObject *self, PyObject *timeout_obj) { + if (PySys_Audit("time.sleep", "O", timeout_obj) < 0) { + return NULL; + } + _PyTime_t timeout; if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) return NULL; diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 966123f4624c08..875a9c18c4e340 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -18,9 +18,9 @@ #include "Python.h" #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI -#include "structmember.h" // PyMemberDef #include +#include // offsetof() /*[clinic input] module unicodedata @@ -82,7 +82,7 @@ typedef struct previous_version { #define get_old_record(self, v) ((((PreviousDBVersion*)self)->getrecord)(v)) static PyMemberDef DB_members[] = { - {"unidata_version", T_STRING, offsetof(PreviousDBVersion, name), READONLY}, + {"unidata_version", Py_T_STRING, offsetof(PreviousDBVersion, name), Py_READONLY}, {NULL} }; @@ -1035,6 +1035,7 @@ is_unified_ideograph(Py_UCS4 code) (0x2B740 <= code && code <= 0x2B81D) || /* CJK Ideograph Extension D */ (0x2B820 <= code && code <= 0x2CEA1) || /* CJK Ideograph Extension E */ (0x2CEB0 <= code && code <= 0x2EBE0) || /* CJK Ideograph Extension F */ + (0x2EBF0 <= code && code <= 0x2EE5D) || /* CJK Ideograph Extension I */ (0x30000 <= code && code <= 0x3134A) || /* CJK Ideograph Extension G */ (0x31350 <= code && code <= 0x323AF); /* CJK Ideograph Extension H */ } @@ -1487,11 +1488,7 @@ unicodedata_exec(PyObject *module) v = new_previous_version(ucd_type, "3.2.0", get_change_3_2_0, normalization_3_2_0); Py_DECREF(ucd_type); - if (v == NULL) { - return -1; - } - if (PyModule_AddObject(module, "ucd_3_2_0", v) < 0) { - Py_DECREF(v); + if (PyModule_Add(module, "ucd_3_2_0", v) < 0) { return -1; } diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index 4c4b2f589c50bf..ed4b0eea9a6c59 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -1,6 +1,6 @@ /* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ -#define UNIDATA_VERSION "15.0.0" +#define UNIDATA_VERSION "15.1.0" /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {0, 0, 0, 0, 0, 0}, @@ -810,46 +810,46 @@ static const unsigned short index1[] = { 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 121, 121, 121, 121, 273, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 274, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 271, 101, 101, 101, 101, 272, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 121, 121, 121, 121, 274, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 275, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 275, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 276, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 276, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 137, 137, 137, 137, + 101, 101, 101, 277, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 275, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1215,7 +1215,7 @@ static const unsigned short index1[] = { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 277, 137, 278, 279, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 278, 137, 279, 280, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1288,7 +1288,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 280, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 281, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, @@ -1325,7 +1325,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 280, + 120, 281, }; static const unsigned short index2[] = { @@ -2016,58 +2016,57 @@ static const unsigned short index2[] = { 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 0, 0, 0, 0, 252, 253, 253, 253, 243, 254, 172, 255, 256, 257, 256, - 257, 256, 257, 256, 257, 256, 257, 243, 243, 256, 257, 256, 257, 256, - 257, 256, 257, 258, 259, 260, 260, 243, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 261, 262, 263, 264, 265, 265, 258, 254, 254, 254, 254, - 254, 251, 243, 266, 266, 266, 254, 172, 253, 243, 26, 0, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 267, 172, 267, 172, 267, 172, + 243, 243, 243, 243, 243, 252, 253, 253, 253, 243, 254, 172, 255, 256, + 257, 256, 257, 256, 257, 256, 257, 256, 257, 243, 243, 256, 257, 256, + 257, 256, 257, 256, 257, 258, 259, 260, 260, 243, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 261, 262, 263, 264, 265, 265, 258, 254, 254, + 254, 254, 254, 251, 243, 266, 266, 266, 254, 172, 253, 243, 26, 0, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, - 267, 172, 267, 172, 172, 267, 172, 267, 172, 267, 172, 172, 172, 172, - 172, 172, 267, 267, 172, 267, 267, 172, 267, 267, 172, 267, 267, 172, - 267, 267, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 267, 172, 172, 0, 0, - 268, 268, 269, 269, 254, 270, 271, 258, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, + 267, 172, 267, 172, 267, 172, 172, 267, 172, 267, 172, 267, 172, 172, + 172, 172, 172, 172, 267, 267, 172, 267, 267, 172, 267, 267, 172, 267, + 267, 172, 267, 267, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 267, 172, + 172, 0, 0, 268, 268, 269, 269, 254, 270, 271, 258, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, 172, 267, - 172, 172, 267, 172, 267, 172, 267, 172, 172, 172, 172, 172, 172, 267, - 267, 172, 267, 267, 172, 267, 267, 172, 267, 267, 172, 267, 267, 172, + 172, 267, 172, 172, 267, 172, 267, 172, 267, 172, 172, 172, 172, 172, + 172, 267, 267, 172, 267, 267, 172, 267, 267, 172, 267, 267, 172, 267, + 267, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 267, 172, 172, 267, 267, + 267, 267, 253, 254, 254, 270, 271, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 267, 172, 172, 267, 267, 267, 267, - 253, 254, 254, 270, 271, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 271, 271, 271, 271, 271, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 271, 0, 272, 272, 273, 273, 273, 273, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 172, 172, 172, 172, 172, 172, 172, + 271, 271, 271, 271, 271, 271, 271, 0, 272, 272, 273, 273, 273, 273, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 243, 243, 243, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, + 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 251, 251, 0, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 251, 251, 0, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 275, 275, 275, 275, 275, 275, 275, 275, 251, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 251, 251, 251, - 272, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, + 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 251, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 251, + 251, 251, 272, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 251, 251, 251, 251, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 251, 251, 251, 251, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, @@ -2078,17 +2077,18 @@ static const unsigned short index2[] = { 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 251, 251, 251, 251, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 251, 251, + 251, 251, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 251, 251, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 251, 251, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 251, 172, 172, 172, 172, 172, 172, 172, + 274, 274, 274, 274, 274, 274, 274, 274, 251, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -2102,12 +2102,12 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 172, 172, 172, 172, 172, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 172, 172, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 254, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 254, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -2115,12 +2115,12 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 243, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 53, 53, 53, 53, 53, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 138, 138, 138, 48, 48, 48, @@ -3339,6 +3339,15 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, @@ -3350,9 +3359,9 @@ static const unsigned short index2[] = { 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 281, 281, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, @@ -3368,33 +3377,33 @@ static const unsigned short index2[] = { 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, + 281, 281, 281, 281, 281, 281, 281, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, - 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, + 281, 281, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 0, 177, 0, 0, 0, 0, 0, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 0, 0, 0, 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 71, 71, 71, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, @@ -3408,7 +3417,7 @@ static const unsigned short index2[] = { 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 279, + 71, 71, 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, @@ -3417,7 +3426,7 @@ static const unsigned short index2[] = { 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 0, 0, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 0, 0, }; /* decomposition data */ @@ -6027,385 +6036,199 @@ static const change_record change_records_3_2_0[] = { { 9, 255, 255, 255, 255, 0 }, { 255, 255, 255, 1, 255, 0 }, { 255, 20, 255, 255, 255, 0 }, - { 255, 255, 255, 255, 255, 1e+16 }, + { 255, 255, 255, 255, 255, 1000000000000.0 }, { 255, 255, 255, 255, 255, 1e+20 }, { 255, 19, 255, 255, 255, -1 }, { 1, 255, 255, 0, 255, 0 }, }; static const unsigned char changes_3_2_0_index[] = { - 0, 1, 2, 2, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 2, 2, 2, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 52, 2, 53, 2, 2, 54, 55, 56, 57, 58, 2, 59, 60, 61, 62, 2, 63, 64, - 65, 66, 67, 68, 68, 2, 69, 2, 2, 70, 71, 52, 72, 73, 74, 75, 2, 2, 2, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 2, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, - 87, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 2, 89, 2, 2, 2, 2, 2, 2, 2, 2, - 90, 91, 2, 2, 2, 2, 2, 2, 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 93, - 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 98, 99, 2, 2, 2, 2, 2, 2, 2, 2, 100, 52, - 52, 101, 102, 52, 103, 104, 105, 106, 107, 108, 109, 110, 111, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 113, 114, 115, 116, 117, 118, 2, 2, 119, 120, 121, - 2, 122, 123, 124, 125, 126, 127, 2, 128, 129, 130, 131, 132, 133, 134, - 52, 52, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 2, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 2, 159, 160, 2, - 161, 162, 163, 164, 2, 165, 166, 167, 168, 169, 170, 171, 2, 172, 173, - 174, 175, 2, 176, 177, 178, 52, 52, 52, 52, 52, 52, 52, 179, 180, 52, - 181, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 182, 52, - 52, 52, 52, 52, 52, 52, 52, 183, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, - 184, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, - 52, 185, 186, 187, 188, 2, 2, 2, 2, 189, 190, 191, 192, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 102, 52, 52, 52, 52, 52, 52, 52, 52, 52, 183, - 193, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 194, 52, - 52, 195, 52, 52, 196, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 197, 198, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 199, 181, 2, 2, 200, 201, - 202, 203, 204, 2, 2, 205, 2, 2, 2, 206, 207, 208, 52, 52, 52, 52, 52, - 209, 2, 2, 2, 2, 2, 2, 2, 2, 210, 2, 211, 212, 213, 2, 2, 214, 2, 2, 2, - 215, 2, 2, 2, 2, 2, 216, 52, 217, 218, 2, 2, 2, 2, 2, 219, 220, 221, 2, - 222, 223, 2, 2, 224, 225, 52, 226, 227, 2, 52, 52, 52, 52, 52, 52, 52, - 228, 229, 230, 231, 232, 52, 52, 233, 234, 52, 235, 2, 2, 2, 2, 2, 2, 2, - 2, 236, 237, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 238, 2, - 239, 240, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 241, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 242, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 243, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 244, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 245, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 246, - 52, 247, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 248, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 249, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 241, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 250, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 251, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 52, 252, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 1, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 1, 1, 1, 50, 1, 1, 51, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 52, 53, 54, 55, 56, 1, + 57, 1, 1, 1, 58, 1, 1, 1, 1, 1, 1, 59, 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 61, 1, 55, 1, 1, 1, 1, 1, 1, 62, 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 65, 1, 66, 1, 67, 1, + 1, 1, 1, 1, 1, 1, 1, 68, 69, 1, 1, 1, 70, 28, 71, 72, 73, 74, 75, 76, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 77, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 78, 79, 80, 1, 81, 82, 83, 84, 85, 86, 87, 88, 89, 28, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 28, 28, 28, 115, 116, 117, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 118, 28, 28, 28, 28, 119, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 28, 28, 120, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 121, + 122, 1, 1, 123, 124, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 125, 28, 28, 28, 28, 126, 127, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 128, 28, 129, 130, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 131, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 132, 1, 133, + 134, 135, 136, 1, 137, 138, 28, 28, 139, 1, 1, 1, 1, 140, 141, 142, 143, + 1, 144, 1, 1, 145, 146, 147, 1, 1, 148, 149, 150, 1, 151, 152, 153, 28, + 28, 28, 154, 155, 156, 28, 157, 158, 1, 1, 1, 1, 159, 67, 1, 1, 1, 1, 1, + 1, 1, 160, 161, 162, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 163, 1, 1, 1, 1, 1, 164, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 165, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 166, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 167, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 168, 169, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 170, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 171, 28, 28, 43, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 163, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 172, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 173, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 174, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, }; static const unsigned char changes_3_2_0_data[] = { @@ -6426,153 +6249,169 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 10, 0, 9, 9, 0, 0, 0, 9, 9, - 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 10, 0, 9, 9, 0, 0, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, 0, 0, 9, - 9, 9, 9, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, 0, 0, 9, 9, 9, 9, 0, 0, 9, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 20, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 0, 20, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 9, 0, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 9, 9, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6618,82 +6457,98 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 33, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6726,74 +6581,97 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 0, 0, 0, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, + 0, 0, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 0, 0, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -6802,26 +6680,31 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 9, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6829,526 +6712,984 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 0, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 49, 50, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 21, 21, 21, 21, 21, 0, 0, 0, 1, 1, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 0, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, + 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, - 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 50, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, - 21, 21, 0, 0, 0, 1, 1, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, - 14, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, - 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7356,94 +7697,66 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7453,317 +7766,346 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 57, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 9, 9, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 0, 9, 0, 9, 0, 9, 9, + 9, 0, 9, 9, 0, 9, 0, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 9, 0, 9, 0, 0, + 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 0, 9, 0, - 9, 0, 9, 9, 9, 0, 9, 9, 0, 9, 0, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 9, - 0, 9, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 9, - 9, 9, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const change_record* get_change_3_2_0(Py_UCS4 n) @@ -7771,8 +8113,8 @@ static const change_record* get_change_3_2_0(Py_UCS4 n) int index; if (n >= 0x110000) index = 0; else { - index = changes_3_2_0_index[n>>7]; - index = changes_3_2_0_data[(index<<7)+(n & 127)]; + index = changes_3_2_0_index[n>>8]; + index = changes_3_2_0_data[(index<<8)+(n & 255)]; } return change_records_3_2_0+index; } diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index f6320c43e53f77..1116905308177d 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -53,240 +53,240 @@ static const unsigned char lexicon[] = { 200, 84, 72, 82, 69, 69, 128, 79, 86, 69, 210, 72, 65, 128, 73, 78, 68, 69, 216, 77, 65, 76, 65, 89, 65, 76, 65, 205, 83, 73, 89, 65, 209, 68, 79, 87, 206, 80, 65, 72, 65, 87, 200, 67, 72, 79, 83, 69, 79, 78, 199, - 66, 65, 76, 73, 78, 69, 83, 197, 70, 73, 86, 69, 128, 72, 65, 76, 70, 87, - 73, 68, 84, 200, 72, 65, 78, 68, 45, 70, 73, 83, 212, 77, 69, 82, 79, 73, - 84, 73, 195, 84, 85, 82, 78, 69, 196, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 73, 195, 75, 65, 128, 76, 73, 71, 72, 212, 73, 68, 69, 79, 71, 82, 65, - 205, 80, 72, 65, 83, 69, 45, 196, 84, 79, 128, 65, 76, 67, 72, 69, 77, - 73, 67, 65, 204, 78, 69, 85, 77, 197, 66, 82, 65, 72, 77, 201, 84, 79, - 78, 197, 66, 65, 82, 128, 82, 65, 128, 83, 73, 78, 72, 65, 76, 193, 78, - 85, 77, 69, 82, 73, 195, 80, 65, 128, 83, 73, 88, 128, 89, 65, 128, 69, - 73, 71, 72, 84, 128, 76, 65, 128, 77, 65, 128, 83, 69, 86, 69, 78, 128, - 84, 72, 85, 77, 194, 72, 85, 78, 71, 65, 82, 73, 65, 206, 78, 73, 78, 69, - 128, 76, 79, 78, 199, 78, 65, 128, 66, 65, 82, 194, 72, 65, 200, 82, 73, - 71, 72, 84, 128, 66, 76, 79, 67, 203, 68, 79, 84, 211, 78, 79, 82, 84, - 200, 83, 65, 128, 84, 72, 79, 85, 83, 65, 78, 68, 128, 84, 65, 128, 90, - 90, 89, 88, 128, 90, 90, 89, 84, 128, 90, 90, 89, 82, 88, 128, 90, 90, - 89, 82, 128, 90, 90, 89, 80, 128, 90, 90, 89, 65, 128, 90, 90, 89, 128, - 90, 90, 85, 88, 128, 90, 90, 85, 82, 88, 128, 90, 90, 85, 82, 128, 90, - 90, 85, 80, 128, 90, 90, 85, 128, 90, 90, 83, 89, 65, 128, 90, 90, 83, - 65, 128, 90, 90, 79, 88, 128, 90, 90, 79, 80, 128, 90, 90, 79, 128, 90, - 90, 73, 88, 128, 90, 90, 73, 84, 128, 90, 90, 73, 80, 128, 90, 90, 73, - 69, 88, 128, 90, 90, 73, 69, 84, 128, 90, 90, 73, 69, 80, 128, 90, 90, - 73, 69, 128, 90, 90, 73, 128, 90, 90, 69, 88, 128, 90, 90, 69, 80, 128, - 90, 90, 69, 69, 128, 90, 90, 69, 128, 90, 90, 65, 88, 128, 90, 90, 65, - 84, 128, 90, 90, 65, 80, 128, 90, 90, 65, 65, 128, 90, 90, 65, 128, 90, - 89, 71, 79, 83, 128, 90, 87, 83, 80, 128, 90, 87, 78, 74, 128, 90, 87, - 78, 66, 83, 80, 128, 90, 87, 74, 128, 90, 87, 202, 90, 87, 65, 82, 65, - 75, 65, 89, 128, 90, 87, 65, 128, 90, 85, 84, 128, 90, 85, 79, 88, 128, - 90, 85, 79, 80, 128, 90, 85, 79, 128, 90, 85, 77, 128, 90, 85, 66, 85, - 82, 128, 90, 85, 53, 128, 90, 85, 181, 90, 213, 90, 83, 72, 65, 128, 90, - 82, 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, 84, 128, 90, 79, 79, 128, - 90, 79, 77, 66, 73, 69, 128, 90, 79, 65, 128, 90, 77, 69, 89, 84, 83, 65, - 128, 90, 76, 65, 77, 193, 90, 76, 65, 128, 90, 76, 193, 90, 74, 69, 128, - 90, 73, 90, 50, 128, 90, 73, 81, 65, 65, 128, 90, 73, 80, 80, 69, 82, 45, - 77, 79, 85, 84, 200, 90, 73, 78, 79, 82, 128, 90, 73, 76, 68, 69, 128, - 90, 73, 71, 90, 65, 199, 90, 73, 71, 128, 90, 73, 68, 193, 90, 73, 66, - 128, 90, 73, 194, 90, 73, 51, 128, 90, 201, 90, 72, 89, 88, 128, 90, 72, - 89, 84, 128, 90, 72, 89, 82, 88, 128, 90, 72, 89, 82, 128, 90, 72, 89, - 80, 128, 90, 72, 89, 128, 90, 72, 87, 69, 128, 90, 72, 87, 65, 128, 90, - 72, 85, 88, 128, 90, 72, 85, 84, 128, 90, 72, 85, 82, 88, 128, 90, 72, - 85, 82, 128, 90, 72, 85, 80, 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, - 79, 80, 128, 90, 72, 85, 79, 128, 90, 72, 85, 128, 90, 72, 79, 88, 128, - 90, 72, 79, 84, 128, 90, 72, 79, 80, 128, 90, 72, 79, 79, 128, 90, 72, - 79, 73, 128, 90, 72, 79, 128, 90, 72, 73, 86, 69, 84, 69, 128, 90, 72, - 73, 76, 128, 90, 72, 73, 128, 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, - 90, 72, 69, 80, 128, 90, 72, 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, - 90, 72, 65, 89, 73, 78, 128, 90, 72, 65, 88, 128, 90, 72, 65, 84, 128, - 90, 72, 65, 82, 128, 90, 72, 65, 80, 128, 90, 72, 65, 73, 78, 128, 90, - 72, 65, 65, 128, 90, 72, 65, 128, 90, 72, 128, 90, 69, 86, 79, 75, 128, - 90, 69, 85, 83, 128, 90, 69, 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, - 82, 207, 90, 69, 78, 128, 90, 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, - 74, 65, 128, 90, 69, 76, 79, 128, 90, 69, 66, 82, 193, 90, 69, 50, 128, - 90, 197, 90, 65, 89, 78, 128, 90, 65, 89, 73, 78, 45, 89, 79, 68, 72, - 128, 90, 65, 89, 73, 78, 128, 90, 65, 89, 73, 206, 90, 65, 86, 73, 89, - 65, 78, 73, 128, 90, 65, 84, 65, 128, 90, 65, 82, 81, 65, 128, 90, 65, - 82, 76, 128, 90, 65, 81, 69, 198, 90, 65, 80, 89, 65, 84, 89, 77, 73, - 128, 90, 65, 80, 89, 65, 84, 79, 89, 128, 90, 65, 80, 89, 65, 84, 79, - 217, 90, 65, 80, 89, 65, 84, 65, 89, 65, 128, 90, 65, 78, 79, 90, 72, 69, - 75, 128, 90, 65, 78, 65, 66, 65, 90, 65, 210, 90, 65, 77, 88, 128, 90, - 65, 76, 128, 90, 65, 204, 90, 65, 75, 82, 89, 84, 79, 69, 128, 90, 65, - 75, 82, 89, 84, 65, 89, 65, 128, 90, 65, 75, 82, 89, 84, 65, 89, 193, 90, - 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, 73, 128, 90, 65, 72, 128, 90, - 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, 128, 90, 65, 68, 69, 82, 90, - 72, 75, 65, 128, 90, 65, 55, 128, 90, 193, 90, 48, 49, 54, 72, 128, 90, - 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, 128, 90, 48, 49, 54, 69, 128, - 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, 67, 128, 90, 48, 49, 54, 66, - 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, 54, 128, 90, 48, 49, 53, 73, - 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, 53, 71, 128, 90, 48, 49, 53, - 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, 49, 53, 68, 128, 90, 48, 49, - 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, 48, 49, 53, 65, 128, 90, 48, - 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, 49, 51, 128, 90, 48, 49, 50, - 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, 128, 90, 48, 48, 57, 128, 90, - 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, 48, 48, 54, 128, 90, 48, 48, - 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, 48, 52, 65, 128, 90, 48, 48, - 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, 48, 51, 65, 128, 90, 48, 48, - 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, 48, 50, 67, 128, 90, 48, 48, - 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, 48, 48, 50, 128, 90, 48, 48, - 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, 89, 84, 128, 89, 89, 82, 88, - 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, 89, 69, 128, 89, 89, 65, 65, - 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, 79, 79, 128, 89, 87, 79, 128, - 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, 87, 69, 128, 89, 87, 65, 65, - 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, 88, 128, 89, 85, 87, 79, 81, - 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 78, 84, 85, 128, 89, 85, 85, - 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, 85, 211, 89, 85, 82, 88, 128, - 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, 209, 89, 85, 80, 128, 89, 85, - 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, 79, 80, 128, 89, 85, 79, 77, - 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, 85, 77, 128, 89, 85, 74, 128, - 89, 85, 73, 128, 89, 85, 69, 81, 128, 89, 85, 69, 128, 89, 85, 68, 72, - 128, 89, 85, 68, 200, 89, 85, 65, 78, 128, 89, 85, 65, 69, 78, 128, 89, - 85, 45, 89, 69, 79, 128, 89, 85, 45, 89, 69, 128, 89, 85, 45, 85, 128, - 89, 85, 45, 79, 128, 89, 85, 45, 73, 128, 89, 85, 45, 69, 79, 128, 89, - 85, 45, 69, 128, 89, 85, 45, 65, 69, 128, 89, 85, 45, 65, 128, 89, 85, - 45, 52, 128, 89, 85, 45, 51, 128, 89, 85, 45, 50, 128, 89, 85, 45, 49, - 128, 89, 85, 128, 89, 213, 89, 82, 89, 128, 89, 80, 83, 73, 76, 73, 128, - 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, 75, 82, 73, 83, 73, 83, 128, - 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, 79, 71, 69, 71, 82, 65, 77, - 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, 88, 128, 89, 79, 87, 68, - 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 89, 79, 85, 84, - 72, 70, 85, 204, 89, 79, 213, 89, 79, 84, 128, 89, 79, 212, 89, 79, 82, - 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, 128, 89, 79, 79, 128, - 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, 68, 128, 89, 79, 196, - 89, 79, 65, 128, 89, 79, 45, 89, 79, 128, 89, 79, 45, 89, 69, 79, 128, - 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, 128, 89, 79, 45, 79, - 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, 89, 79, 45, 65, 69, - 128, 89, 79, 45, 65, 128, 89, 79, 45, 54, 128, 89, 79, 45, 53, 128, 89, - 79, 45, 52, 128, 89, 79, 45, 51, 128, 89, 79, 45, 50, 128, 89, 79, 45, - 49, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, 88, 128, 89, 73, 87, - 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, 78, 71, 128, 89, 73, - 73, 128, 89, 73, 72, 128, 89, 73, 199, 89, 73, 69, 88, 128, 89, 73, 69, - 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, 128, 89, 73, 69, 128, 89, - 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, 89, 73, 128, 89, 72, 69, - 128, 89, 72, 65, 128, 89, 70, 69, 83, 73, 83, 128, 89, 70, 69, 83, 73, - 211, 89, 70, 69, 206, 89, 69, 90, 73, 68, 201, 89, 69, 89, 128, 89, 69, - 87, 128, 89, 69, 85, 88, 128, 89, 69, 85, 82, 65, 69, 128, 89, 69, 85, - 81, 128, 89, 69, 85, 77, 128, 89, 69, 85, 65, 69, 84, 128, 89, 69, 85, - 65, 69, 128, 89, 69, 84, 73, 86, 128, 89, 69, 83, 84, 85, 128, 89, 69, - 83, 73, 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, 75, - 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, 83, 128, 89, 69, 83, - 73, 69, 85, 78, 71, 45, 80, 65, 78, 83, 73, 79, 83, 128, 89, 69, 83, 73, - 69, 85, 78, 71, 45, 77, 73, 69, 85, 77, 128, 89, 69, 83, 73, 69, 85, 78, - 71, 45, 75, 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, - 75, 72, 73, 69, 85, 75, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 72, - 73, 69, 85, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 128, 89, 69, 82, 85, - 128, 89, 69, 82, 213, 89, 69, 82, 73, 128, 89, 69, 82, 65, 200, 89, 69, - 82, 128, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 89, 69, 79, 45, - 89, 65, 128, 89, 69, 79, 45, 85, 128, 89, 69, 79, 45, 79, 128, 89, 69, - 78, 73, 83, 69, 201, 89, 69, 78, 65, 80, 128, 89, 69, 78, 128, 89, 69, - 206, 89, 69, 76, 76, 79, 87, 128, 89, 69, 76, 76, 79, 215, 89, 69, 73, - 78, 128, 89, 69, 72, 128, 89, 69, 69, 71, 128, 89, 69, 69, 128, 89, 69, - 65, 210, 89, 69, 65, 128, 89, 65, 90, 90, 128, 89, 65, 90, 72, 128, 89, - 65, 90, 128, 89, 65, 89, 68, 128, 89, 65, 89, 65, 78, 78, 65, 128, 89, - 65, 89, 128, 89, 65, 87, 78, 73, 78, 199, 89, 65, 87, 78, 128, 89, 65, - 87, 128, 89, 65, 86, 128, 89, 65, 85, 128, 89, 65, 84, 84, 128, 89, 65, - 84, 73, 128, 89, 65, 84, 72, 128, 89, 65, 84, 128, 89, 65, 83, 83, 128, - 89, 65, 83, 72, 128, 89, 65, 83, 128, 89, 65, 82, 82, 128, 89, 65, 82, - 78, 128, 89, 65, 82, 128, 89, 65, 210, 89, 65, 81, 128, 89, 65, 80, 128, - 89, 65, 78, 83, 65, 89, 65, 128, 89, 65, 78, 71, 128, 89, 65, 78, 199, - 89, 65, 78, 128, 89, 65, 77, 79, 75, 128, 89, 65, 77, 65, 75, 75, 65, 78, - 128, 89, 65, 77, 128, 89, 65, 76, 128, 89, 65, 75, 72, 72, 128, 89, 65, - 75, 72, 128, 89, 65, 75, 65, 83, 72, 128, 89, 65, 75, 128, 89, 65, 74, - 85, 82, 86, 69, 68, 73, 195, 89, 65, 74, 128, 89, 65, 73, 128, 89, 65, - 72, 72, 128, 89, 65, 72, 128, 89, 65, 71, 78, 128, 89, 65, 71, 72, 72, - 128, 89, 65, 71, 72, 128, 89, 65, 71, 128, 89, 65, 70, 213, 89, 65, 70, - 128, 89, 65, 69, 77, 77, 65, 69, 128, 89, 65, 68, 72, 128, 89, 65, 68, - 68, 72, 128, 89, 65, 68, 68, 128, 89, 65, 68, 128, 89, 65, 67, 72, 128, - 89, 65, 66, 72, 128, 89, 65, 66, 128, 89, 65, 65, 82, 85, 128, 89, 65, - 65, 73, 128, 89, 65, 65, 68, 79, 128, 89, 65, 45, 89, 79, 128, 89, 65, - 45, 85, 128, 89, 65, 45, 79, 128, 89, 65, 45, 53, 128, 89, 65, 45, 52, - 128, 89, 65, 45, 51, 128, 89, 65, 45, 50, 128, 89, 65, 45, 49, 128, 89, - 48, 48, 56, 128, 89, 48, 48, 55, 128, 89, 48, 48, 54, 128, 89, 48, 48, - 53, 128, 89, 48, 48, 52, 128, 89, 48, 48, 51, 128, 89, 48, 48, 50, 128, - 89, 48, 48, 49, 65, 128, 89, 48, 48, 49, 128, 89, 45, 67, 82, 69, 197, - 88, 89, 88, 128, 88, 89, 85, 128, 88, 89, 84, 128, 88, 89, 82, 88, 128, - 88, 89, 82, 128, 88, 89, 80, 128, 88, 89, 79, 79, 74, 128, 88, 89, 79, - 79, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, 89, 69, 69, 205, 88, 89, - 69, 69, 128, 88, 89, 69, 128, 88, 89, 65, 65, 128, 88, 89, 65, 128, 88, - 89, 128, 88, 87, 73, 128, 88, 87, 69, 69, 128, 88, 87, 69, 128, 88, 87, - 65, 65, 128, 88, 87, 65, 128, 88, 87, 128, 88, 215, 88, 86, 69, 128, 88, - 86, 65, 128, 88, 85, 79, 88, 128, 88, 85, 79, 128, 88, 85, 128, 88, 83, - 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, 88, 79, 88, 128, 88, 79, 84, - 128, 88, 79, 82, 128, 88, 79, 80, 72, 128, 88, 79, 80, 128, 88, 79, 65, - 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, 84, 128, 88, 73, 82, 79, 206, - 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, 73, 69, 84, 128, 88, 73, 69, - 80, 128, 88, 73, 69, 128, 88, 73, 65, 78, 71, 81, 201, 88, 73, 65, 66, - 128, 88, 73, 128, 88, 72, 69, 89, 78, 128, 88, 71, 128, 88, 69, 89, 78, - 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, 69, 128, 88, 69, - 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, 88, 65, 80, 72, 128, 88, 65, - 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, 48, 48, 56, 65, 128, 88, 48, - 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, 48, 54, 65, 128, 88, 48, 48, - 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, 52, 66, 128, 88, 48, 48, 52, - 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, 51, 128, 88, 48, 48, 50, 128, - 88, 48, 48, 49, 128, 88, 45, 216, 88, 45, 82, 65, 89, 128, 87, 90, 128, - 87, 89, 78, 78, 128, 87, 89, 78, 206, 87, 86, 73, 128, 87, 86, 69, 128, - 87, 86, 65, 128, 87, 86, 128, 87, 85, 80, 128, 87, 85, 79, 88, 128, 87, - 85, 79, 80, 128, 87, 85, 79, 128, 87, 85, 78, 74, 207, 87, 85, 78, 128, - 87, 85, 76, 85, 128, 87, 85, 76, 213, 87, 85, 73, 128, 87, 85, 69, 128, - 87, 85, 65, 69, 84, 128, 87, 85, 65, 69, 78, 128, 87, 85, 128, 87, 82, - 217, 87, 82, 79, 78, 71, 128, 87, 82, 73, 83, 212, 87, 82, 73, 78, 75, - 76, 69, 83, 128, 87, 82, 73, 78, 75, 76, 69, 211, 87, 82, 73, 78, 75, 76, - 69, 68, 128, 87, 82, 69, 83, 84, 76, 69, 82, 83, 128, 87, 82, 69, 78, 67, - 72, 128, 87, 82, 69, 65, 84, 200, 87, 82, 65, 80, 80, 69, 196, 87, 82, - 65, 80, 128, 87, 79, 88, 128, 87, 79, 87, 128, 87, 79, 82, 83, 72, 73, - 80, 128, 87, 79, 82, 82, 73, 69, 196, 87, 79, 82, 77, 128, 87, 79, 82, - 76, 196, 87, 79, 82, 75, 69, 82, 128, 87, 79, 82, 75, 128, 87, 79, 82, - 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, 128, 87, 79, 82, 196, 87, 79, - 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, 76, 128, 87, 79, 79, 68, 83, - 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, 87, 79, 78, 128, 87, 79, 206, - 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, 206, 87, 79, 77, 65, 78, 211, - 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, 206, 87, 79, 76, 79, 83, 79, - 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, 79, 65, 128, 87, 79, 45, 55, - 128, 87, 79, 45, 54, 128, 87, 79, 45, 53, 128, 87, 79, 45, 52, 128, 87, - 79, 45, 51, 128, 87, 79, 45, 50, 128, 87, 79, 45, 49, 128, 87, 73, 84, - 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, 128, 87, 73, 84, 72, 73, 206, - 87, 73, 82, 69, 76, 69, 83, 83, 128, 87, 73, 82, 69, 196, 87, 73, 78, 84, - 69, 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 75, 128, 87, 73, - 78, 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, 78, 71, 128, 87, 73, - 78, 69, 128, 87, 73, 78, 197, 87, 73, 78, 68, 85, 128, 87, 73, 78, 68, - 79, 87, 128, 87, 73, 78, 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, - 73, 76, 84, 69, 196, 87, 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, - 217, 87, 73, 71, 71, 76, 69, 83, 128, 87, 73, 68, 84, 72, 128, 87, 73, - 68, 69, 78, 73, 78, 199, 87, 73, 68, 69, 45, 72, 69, 65, 68, 69, 196, 87, - 73, 68, 197, 87, 73, 65, 78, 71, 87, 65, 65, 75, 128, 87, 73, 65, 78, 71, - 128, 87, 73, 45, 53, 128, 87, 73, 45, 52, 128, 87, 73, 45, 51, 128, 87, - 73, 45, 50, 128, 87, 73, 45, 49, 128, 87, 72, 79, 76, 197, 87, 72, 73, - 84, 69, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 87, 72, 73, 84, 69, 128, - 87, 72, 69, 69, 76, 69, 196, 87, 72, 69, 69, 76, 67, 72, 65, 73, 82, 128, - 87, 72, 69, 69, 76, 67, 72, 65, 73, 210, 87, 72, 69, 69, 76, 128, 87, 72, - 69, 69, 204, 87, 72, 69, 65, 84, 128, 87, 72, 65, 76, 69, 128, 87, 72, - 128, 87, 71, 128, 87, 69, 88, 128, 87, 69, 85, 88, 128, 87, 69, 212, 87, - 69, 83, 84, 69, 82, 206, 87, 69, 83, 84, 45, 67, 82, 69, 197, 87, 69, 83, - 84, 128, 87, 69, 83, 212, 87, 69, 80, 128, 87, 69, 79, 128, 87, 69, 78, - 128, 87, 69, 76, 76, 128, 87, 69, 73, 71, 72, 212, 87, 69, 73, 69, 82, - 83, 84, 82, 65, 83, 211, 87, 69, 73, 128, 87, 69, 69, 78, 128, 87, 69, - 68, 71, 69, 45, 84, 65, 73, 76, 69, 196, 87, 69, 68, 71, 69, 128, 87, 69, - 68, 68, 73, 78, 71, 128, 87, 69, 66, 128, 87, 69, 65, 82, 217, 87, 69, - 65, 80, 79, 78, 128, 87, 69, 45, 52, 128, 87, 69, 45, 51, 128, 87, 69, - 45, 50, 128, 87, 69, 45, 49, 128, 87, 67, 128, 87, 66, 128, 87, 65, 89, - 128, 87, 65, 217, 87, 65, 88, 73, 78, 199, 87, 65, 88, 128, 87, 65, 87, - 45, 65, 89, 73, 78, 45, 82, 69, 83, 72, 128, 87, 65, 87, 128, 87, 65, - 215, 87, 65, 86, 217, 87, 65, 86, 73, 78, 199, 87, 65, 86, 69, 83, 128, - 87, 65, 86, 69, 128, 87, 65, 86, 197, 87, 65, 85, 128, 87, 65, 84, 84, - 79, 128, 87, 65, 84, 69, 82, 77, 69, 76, 79, 78, 128, 87, 65, 84, 69, 82, - 128, 87, 65, 84, 69, 210, 87, 65, 84, 67, 72, 128, 87, 65, 84, 128, 87, - 65, 83, 84, 73, 78, 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, 75, 69, 84, - 128, 87, 65, 83, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, 128, - 87, 65, 83, 76, 193, 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 65, - 76, 76, 65, 205, 87, 65, 83, 45, 83, 65, 76, 65, 65, 77, 128, 87, 65, 82, - 78, 73, 78, 199, 87, 65, 82, 65, 78, 199, 87, 65, 81, 70, 65, 128, 87, - 65, 80, 128, 87, 65, 78, 73, 78, 199, 87, 65, 78, 71, 75, 85, 79, 81, - 128, 87, 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 78, 68, 128, 87, 65, - 78, 67, 72, 207, 87, 65, 78, 128, 87, 65, 76, 76, 80, 76, 65, 78, 197, - 87, 65, 76, 76, 69, 196, 87, 65, 76, 76, 128, 87, 65, 76, 204, 87, 65, - 76, 75, 128, 87, 65, 76, 203, 87, 65, 73, 84, 73, 78, 71, 128, 87, 65, - 73, 83, 84, 128, 87, 65, 73, 128, 87, 65, 70, 70, 76, 69, 128, 87, 65, - 69, 78, 128, 87, 65, 69, 128, 87, 65, 68, 68, 65, 128, 87, 65, 65, 86, - 85, 128, 87, 65, 65, 74, 73, 66, 128, 87, 65, 65, 65, 76, 73, 72, 69, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 73, 195, 66, 65, 76, 73, 78, 69, 83, + 197, 70, 73, 86, 69, 128, 72, 65, 76, 70, 87, 73, 68, 84, 200, 72, 65, + 78, 68, 45, 70, 73, 83, 212, 77, 69, 82, 79, 73, 84, 73, 195, 84, 85, 82, + 78, 69, 196, 75, 65, 128, 76, 73, 71, 72, 212, 73, 68, 69, 79, 71, 82, + 65, 205, 80, 72, 65, 83, 69, 45, 196, 84, 79, 128, 65, 76, 67, 72, 69, + 77, 73, 67, 65, 204, 78, 69, 85, 77, 197, 66, 82, 65, 72, 77, 201, 84, + 79, 78, 197, 66, 65, 82, 128, 82, 65, 128, 83, 73, 78, 72, 65, 76, 193, + 78, 85, 77, 69, 82, 73, 195, 80, 65, 128, 83, 73, 88, 128, 89, 65, 128, + 69, 73, 71, 72, 84, 128, 76, 65, 128, 77, 65, 128, 83, 69, 86, 69, 78, + 128, 84, 72, 85, 77, 194, 72, 85, 78, 71, 65, 82, 73, 65, 206, 78, 73, + 78, 69, 128, 82, 73, 71, 72, 84, 128, 76, 79, 78, 199, 78, 65, 128, 66, + 65, 82, 194, 72, 65, 200, 66, 76, 79, 67, 203, 68, 79, 84, 211, 78, 79, + 82, 84, 200, 83, 65, 128, 84, 72, 79, 85, 83, 65, 78, 68, 128, 84, 65, + 128, 90, 90, 89, 88, 128, 90, 90, 89, 84, 128, 90, 90, 89, 82, 88, 128, + 90, 90, 89, 82, 128, 90, 90, 89, 80, 128, 90, 90, 89, 65, 128, 90, 90, + 89, 128, 90, 90, 85, 88, 128, 90, 90, 85, 82, 88, 128, 90, 90, 85, 82, + 128, 90, 90, 85, 80, 128, 90, 90, 85, 128, 90, 90, 83, 89, 65, 128, 90, + 90, 83, 65, 128, 90, 90, 79, 88, 128, 90, 90, 79, 80, 128, 90, 90, 79, + 128, 90, 90, 73, 88, 128, 90, 90, 73, 84, 128, 90, 90, 73, 80, 128, 90, + 90, 73, 69, 88, 128, 90, 90, 73, 69, 84, 128, 90, 90, 73, 69, 80, 128, + 90, 90, 73, 69, 128, 90, 90, 73, 128, 90, 90, 69, 88, 128, 90, 90, 69, + 80, 128, 90, 90, 69, 69, 128, 90, 90, 69, 128, 90, 90, 65, 88, 128, 90, + 90, 65, 84, 128, 90, 90, 65, 80, 128, 90, 90, 65, 65, 128, 90, 90, 65, + 128, 90, 89, 71, 79, 83, 128, 90, 87, 83, 80, 128, 90, 87, 78, 74, 128, + 90, 87, 78, 66, 83, 80, 128, 90, 87, 74, 128, 90, 87, 202, 90, 87, 65, + 82, 65, 75, 65, 89, 128, 90, 87, 65, 128, 90, 85, 84, 128, 90, 85, 79, + 88, 128, 90, 85, 79, 80, 128, 90, 85, 79, 128, 90, 85, 77, 128, 90, 85, + 66, 85, 82, 128, 90, 85, 53, 128, 90, 85, 181, 90, 213, 90, 83, 72, 65, + 128, 90, 82, 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, 84, 128, 90, 79, + 79, 128, 90, 79, 77, 66, 73, 69, 128, 90, 79, 65, 128, 90, 77, 69, 89, + 84, 83, 65, 128, 90, 76, 65, 77, 193, 90, 76, 65, 128, 90, 76, 193, 90, + 74, 69, 128, 90, 73, 90, 50, 128, 90, 73, 81, 65, 65, 128, 90, 73, 80, + 80, 69, 82, 45, 77, 79, 85, 84, 200, 90, 73, 78, 79, 82, 128, 90, 73, 76, + 68, 69, 128, 90, 73, 71, 90, 65, 199, 90, 73, 71, 128, 90, 73, 68, 193, + 90, 73, 66, 128, 90, 73, 194, 90, 73, 51, 128, 90, 201, 90, 72, 89, 88, + 128, 90, 72, 89, 84, 128, 90, 72, 89, 82, 88, 128, 90, 72, 89, 82, 128, + 90, 72, 89, 80, 128, 90, 72, 89, 128, 90, 72, 87, 69, 128, 90, 72, 87, + 65, 128, 90, 72, 85, 88, 128, 90, 72, 85, 84, 128, 90, 72, 85, 82, 88, + 128, 90, 72, 85, 82, 128, 90, 72, 85, 80, 128, 90, 72, 85, 79, 88, 128, + 90, 72, 85, 79, 80, 128, 90, 72, 85, 79, 128, 90, 72, 85, 128, 90, 72, + 79, 88, 128, 90, 72, 79, 84, 128, 90, 72, 79, 80, 128, 90, 72, 79, 79, + 128, 90, 72, 79, 73, 128, 90, 72, 79, 128, 90, 72, 73, 86, 69, 84, 69, + 128, 90, 72, 73, 76, 128, 90, 72, 73, 128, 90, 72, 69, 88, 128, 90, 72, + 69, 84, 128, 90, 72, 69, 80, 128, 90, 72, 69, 69, 128, 90, 72, 69, 128, + 90, 72, 197, 90, 72, 65, 89, 73, 78, 128, 90, 72, 65, 88, 128, 90, 72, + 65, 84, 128, 90, 72, 65, 82, 128, 90, 72, 65, 80, 128, 90, 72, 65, 73, + 78, 128, 90, 72, 65, 65, 128, 90, 72, 65, 128, 90, 72, 128, 90, 69, 86, + 79, 75, 128, 90, 69, 85, 83, 128, 90, 69, 84, 65, 128, 90, 69, 82, 79, + 128, 90, 69, 82, 207, 90, 69, 78, 128, 90, 69, 77, 76, 89, 65, 128, 90, + 69, 77, 76, 74, 65, 128, 90, 69, 76, 79, 128, 90, 69, 66, 82, 193, 90, + 69, 50, 128, 90, 197, 90, 65, 89, 78, 128, 90, 65, 89, 73, 78, 45, 89, + 79, 68, 72, 128, 90, 65, 89, 73, 78, 128, 90, 65, 89, 73, 206, 90, 65, + 86, 73, 89, 65, 78, 73, 128, 90, 65, 84, 65, 128, 90, 65, 82, 81, 65, + 128, 90, 65, 82, 76, 128, 90, 65, 81, 69, 198, 90, 65, 80, 89, 65, 84, + 89, 77, 73, 128, 90, 65, 80, 89, 65, 84, 79, 89, 128, 90, 65, 80, 89, 65, + 84, 79, 217, 90, 65, 80, 89, 65, 84, 65, 89, 65, 128, 90, 65, 78, 79, 90, + 72, 69, 75, 128, 90, 65, 78, 65, 66, 65, 90, 65, 210, 90, 65, 77, 88, + 128, 90, 65, 76, 128, 90, 65, 204, 90, 65, 75, 82, 89, 84, 79, 69, 128, + 90, 65, 75, 82, 89, 84, 65, 89, 65, 128, 90, 65, 75, 82, 89, 84, 65, 89, + 193, 90, 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, 73, 128, 90, 65, 72, + 128, 90, 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, 128, 90, 65, 68, 69, + 82, 90, 72, 75, 65, 128, 90, 65, 55, 128, 90, 193, 90, 48, 49, 54, 72, + 128, 90, 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, 128, 90, 48, 49, 54, + 69, 128, 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, 67, 128, 90, 48, 49, + 54, 66, 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, 54, 128, 90, 48, 49, + 53, 73, 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, 53, 71, 128, 90, 48, + 49, 53, 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, 49, 53, 68, 128, 90, + 48, 49, 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, 48, 49, 53, 65, 128, + 90, 48, 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, 49, 51, 128, 90, 48, + 49, 50, 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, 128, 90, 48, 48, 57, + 128, 90, 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, 48, 48, 54, 128, 90, + 48, 48, 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, 48, 52, 65, 128, 90, + 48, 48, 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, 48, 51, 65, 128, 90, + 48, 48, 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, 48, 50, 67, 128, 90, + 48, 48, 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, 48, 48, 50, 128, 90, + 48, 48, 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, 89, 84, 128, 89, 89, + 82, 88, 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, 89, 69, 128, 89, 89, + 65, 65, 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, 79, 79, 128, 89, 87, + 79, 128, 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, 87, 69, 128, 89, 87, + 65, 65, 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, 88, 128, 89, 85, 87, + 79, 81, 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 78, 84, 85, 128, 89, + 85, 85, 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, 85, 211, 89, 85, 82, + 88, 128, 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, 209, 89, 85, 80, 128, + 89, 85, 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, 79, 80, 128, 89, 85, + 79, 77, 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, 85, 77, 128, 89, 85, + 74, 128, 89, 85, 73, 128, 89, 85, 69, 81, 128, 89, 85, 69, 128, 89, 85, + 68, 72, 128, 89, 85, 68, 200, 89, 85, 65, 78, 128, 89, 85, 65, 69, 78, + 128, 89, 85, 45, 89, 69, 79, 128, 89, 85, 45, 89, 69, 128, 89, 85, 45, + 85, 128, 89, 85, 45, 79, 128, 89, 85, 45, 73, 128, 89, 85, 45, 69, 79, + 128, 89, 85, 45, 69, 128, 89, 85, 45, 65, 69, 128, 89, 85, 45, 65, 128, + 89, 85, 45, 52, 128, 89, 85, 45, 51, 128, 89, 85, 45, 50, 128, 89, 85, + 45, 49, 128, 89, 85, 128, 89, 213, 89, 82, 89, 128, 89, 80, 83, 73, 76, + 73, 128, 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, 75, 82, 73, 83, 73, + 83, 128, 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, 79, 71, 69, 71, 82, + 65, 77, 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, 88, 128, 89, 79, + 87, 68, 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 89, 79, + 85, 84, 72, 70, 85, 204, 89, 79, 213, 89, 79, 84, 128, 89, 79, 212, 89, + 79, 82, 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, 128, 89, 79, + 79, 128, 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, 68, 128, 89, + 79, 196, 89, 79, 65, 128, 89, 79, 45, 89, 79, 128, 89, 79, 45, 89, 69, + 79, 128, 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, 128, 89, 79, + 45, 79, 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, 89, 79, 45, + 65, 69, 128, 89, 79, 45, 65, 128, 89, 79, 45, 54, 128, 89, 79, 45, 53, + 128, 89, 79, 45, 52, 128, 89, 79, 45, 51, 128, 89, 79, 45, 50, 128, 89, + 79, 45, 49, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, 88, 128, 89, + 73, 87, 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, 78, 71, 128, + 89, 73, 73, 128, 89, 73, 72, 128, 89, 73, 199, 89, 73, 69, 88, 128, 89, + 73, 69, 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, 128, 89, 73, 69, + 128, 89, 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, 89, 73, 128, 89, + 72, 69, 128, 89, 72, 65, 128, 89, 70, 69, 83, 73, 83, 128, 89, 70, 69, + 83, 73, 211, 89, 70, 69, 206, 89, 69, 90, 73, 68, 201, 89, 69, 89, 128, + 89, 69, 87, 128, 89, 69, 85, 88, 128, 89, 69, 85, 82, 65, 69, 128, 89, + 69, 85, 81, 128, 89, 69, 85, 77, 128, 89, 69, 85, 65, 69, 84, 128, 89, + 69, 85, 65, 69, 128, 89, 69, 84, 73, 86, 128, 89, 69, 83, 84, 85, 128, + 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, + 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, 83, 128, 89, + 69, 83, 73, 69, 85, 78, 71, 45, 80, 65, 78, 83, 73, 79, 83, 128, 89, 69, + 83, 73, 69, 85, 78, 71, 45, 77, 73, 69, 85, 77, 128, 89, 69, 83, 73, 69, + 85, 78, 71, 45, 75, 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, + 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, + 45, 72, 73, 69, 85, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 128, 89, 69, + 82, 85, 128, 89, 69, 82, 213, 89, 69, 82, 73, 128, 89, 69, 82, 65, 200, + 89, 69, 82, 128, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 89, 69, + 79, 45, 89, 65, 128, 89, 69, 79, 45, 85, 128, 89, 69, 79, 45, 79, 128, + 89, 69, 78, 73, 83, 69, 201, 89, 69, 78, 65, 80, 128, 89, 69, 78, 128, + 89, 69, 206, 89, 69, 76, 76, 79, 87, 128, 89, 69, 76, 76, 79, 215, 89, + 69, 73, 78, 128, 89, 69, 72, 128, 89, 69, 69, 71, 128, 89, 69, 69, 128, + 89, 69, 65, 210, 89, 69, 65, 128, 89, 65, 90, 90, 128, 89, 65, 90, 72, + 128, 89, 65, 90, 128, 89, 65, 89, 68, 128, 89, 65, 89, 65, 78, 78, 65, + 128, 89, 65, 89, 128, 89, 65, 87, 78, 73, 78, 199, 89, 65, 87, 78, 128, + 89, 65, 87, 128, 89, 65, 86, 128, 89, 65, 85, 128, 89, 65, 84, 84, 128, + 89, 65, 84, 73, 128, 89, 65, 84, 72, 128, 89, 65, 84, 128, 89, 65, 83, + 83, 128, 89, 65, 83, 72, 128, 89, 65, 83, 128, 89, 65, 82, 82, 128, 89, + 65, 82, 78, 128, 89, 65, 82, 128, 89, 65, 210, 89, 65, 81, 128, 89, 65, + 80, 128, 89, 65, 78, 83, 65, 89, 65, 128, 89, 65, 78, 71, 128, 89, 65, + 78, 199, 89, 65, 78, 128, 89, 65, 77, 79, 75, 128, 89, 65, 77, 65, 75, + 75, 65, 78, 128, 89, 65, 77, 128, 89, 65, 76, 128, 89, 65, 75, 72, 72, + 128, 89, 65, 75, 72, 128, 89, 65, 75, 65, 83, 72, 128, 89, 65, 75, 128, + 89, 65, 74, 85, 82, 86, 69, 68, 73, 195, 89, 65, 74, 128, 89, 65, 73, + 128, 89, 65, 72, 72, 128, 89, 65, 72, 128, 89, 65, 71, 78, 128, 89, 65, + 71, 72, 72, 128, 89, 65, 71, 72, 128, 89, 65, 71, 128, 89, 65, 70, 213, + 89, 65, 70, 128, 89, 65, 69, 77, 77, 65, 69, 128, 89, 65, 68, 72, 128, + 89, 65, 68, 68, 72, 128, 89, 65, 68, 68, 128, 89, 65, 68, 128, 89, 65, + 67, 72, 128, 89, 65, 66, 72, 128, 89, 65, 66, 128, 89, 65, 65, 82, 85, + 128, 89, 65, 65, 73, 128, 89, 65, 65, 68, 79, 128, 89, 65, 45, 89, 79, + 128, 89, 65, 45, 85, 128, 89, 65, 45, 79, 128, 89, 65, 45, 53, 128, 89, + 65, 45, 52, 128, 89, 65, 45, 51, 128, 89, 65, 45, 50, 128, 89, 65, 45, + 49, 128, 89, 48, 48, 56, 128, 89, 48, 48, 55, 128, 89, 48, 48, 54, 128, + 89, 48, 48, 53, 128, 89, 48, 48, 52, 128, 89, 48, 48, 51, 128, 89, 48, + 48, 50, 128, 89, 48, 48, 49, 65, 128, 89, 48, 48, 49, 128, 89, 45, 67, + 82, 69, 197, 88, 89, 88, 128, 88, 89, 85, 128, 88, 89, 84, 128, 88, 89, + 82, 88, 128, 88, 89, 82, 128, 88, 89, 80, 128, 88, 89, 79, 79, 74, 128, + 88, 89, 79, 79, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, 89, 69, 69, + 205, 88, 89, 69, 69, 128, 88, 89, 69, 128, 88, 89, 65, 65, 128, 88, 89, + 65, 128, 88, 89, 128, 88, 87, 73, 128, 88, 87, 69, 69, 128, 88, 87, 69, + 128, 88, 87, 65, 65, 128, 88, 87, 65, 128, 88, 87, 128, 88, 215, 88, 86, + 69, 128, 88, 86, 65, 128, 88, 85, 79, 88, 128, 88, 85, 79, 128, 88, 85, + 128, 88, 83, 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, 88, 79, 88, + 128, 88, 79, 84, 128, 88, 79, 82, 128, 88, 79, 80, 72, 128, 88, 79, 80, + 128, 88, 79, 65, 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, 84, 128, 88, + 73, 82, 79, 206, 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, 73, 69, 84, + 128, 88, 73, 69, 80, 128, 88, 73, 69, 128, 88, 73, 65, 78, 71, 81, 201, + 88, 73, 65, 66, 128, 88, 73, 128, 88, 72, 69, 89, 78, 128, 88, 71, 128, + 88, 69, 89, 78, 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, + 69, 128, 88, 69, 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, 88, 65, 80, + 72, 128, 88, 65, 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, 48, 48, 56, + 65, 128, 88, 48, 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, 48, 54, 65, + 128, 88, 48, 48, 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, 52, 66, 128, + 88, 48, 48, 52, 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, 51, 128, 88, + 48, 48, 50, 128, 88, 48, 48, 49, 128, 88, 45, 216, 88, 45, 82, 65, 89, + 128, 87, 90, 128, 87, 89, 78, 78, 128, 87, 89, 78, 206, 87, 86, 73, 128, + 87, 86, 69, 128, 87, 86, 65, 128, 87, 86, 128, 87, 85, 80, 128, 87, 85, + 79, 88, 128, 87, 85, 79, 80, 128, 87, 85, 79, 128, 87, 85, 78, 74, 207, + 87, 85, 78, 128, 87, 85, 76, 85, 128, 87, 85, 76, 213, 87, 85, 73, 128, + 87, 85, 69, 128, 87, 85, 65, 69, 84, 128, 87, 85, 65, 69, 78, 128, 87, + 85, 128, 87, 82, 217, 87, 82, 79, 78, 71, 128, 87, 82, 73, 83, 212, 87, + 82, 73, 78, 75, 76, 69, 83, 128, 87, 82, 73, 78, 75, 76, 69, 211, 87, 82, + 73, 78, 75, 76, 69, 68, 128, 87, 82, 69, 83, 84, 76, 69, 82, 83, 128, 87, + 82, 69, 78, 67, 72, 128, 87, 82, 69, 65, 84, 200, 87, 82, 65, 80, 80, 69, + 196, 87, 82, 65, 80, 128, 87, 79, 88, 128, 87, 79, 87, 128, 87, 79, 82, + 83, 72, 73, 80, 128, 87, 79, 82, 82, 73, 69, 196, 87, 79, 82, 77, 128, + 87, 79, 82, 76, 196, 87, 79, 82, 75, 69, 82, 128, 87, 79, 82, 75, 128, + 87, 79, 82, 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, 128, 87, 79, 82, + 196, 87, 79, 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, 76, 128, 87, 79, + 79, 68, 83, 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, 87, 79, 78, 128, + 87, 79, 206, 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, 206, 87, 79, 77, + 65, 78, 211, 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, 206, 87, 79, 76, + 79, 83, 79, 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, 79, 65, 128, 87, + 79, 45, 55, 128, 87, 79, 45, 54, 128, 87, 79, 45, 53, 128, 87, 79, 45, + 52, 128, 87, 79, 45, 51, 128, 87, 79, 45, 50, 128, 87, 79, 45, 49, 128, + 87, 73, 84, 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, 128, 87, 73, 84, 72, + 73, 206, 87, 73, 82, 69, 76, 69, 83, 83, 128, 87, 73, 82, 69, 196, 87, + 73, 78, 84, 69, 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 75, + 128, 87, 73, 78, 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, 78, 71, + 128, 87, 73, 78, 69, 128, 87, 73, 78, 197, 87, 73, 78, 68, 85, 128, 87, + 73, 78, 68, 79, 87, 128, 87, 73, 78, 68, 128, 87, 73, 78, 196, 87, 73, + 78, 128, 87, 73, 76, 84, 69, 196, 87, 73, 71, 78, 89, 65, 78, 128, 87, + 73, 71, 71, 76, 217, 87, 73, 71, 71, 76, 69, 83, 128, 87, 73, 68, 84, 72, + 128, 87, 73, 68, 69, 78, 73, 78, 199, 87, 73, 68, 69, 45, 72, 69, 65, 68, + 69, 196, 87, 73, 68, 197, 87, 73, 65, 78, 71, 87, 65, 65, 75, 128, 87, + 73, 65, 78, 71, 128, 87, 73, 45, 53, 128, 87, 73, 45, 52, 128, 87, 73, + 45, 51, 128, 87, 73, 45, 50, 128, 87, 73, 45, 49, 128, 87, 72, 79, 76, + 197, 87, 72, 73, 84, 69, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 87, 72, + 73, 84, 69, 128, 87, 72, 69, 69, 76, 69, 196, 87, 72, 69, 69, 76, 67, 72, + 65, 73, 82, 128, 87, 72, 69, 69, 76, 67, 72, 65, 73, 210, 87, 72, 69, 69, + 76, 128, 87, 72, 69, 69, 204, 87, 72, 69, 65, 84, 128, 87, 72, 65, 76, + 69, 128, 87, 72, 128, 87, 71, 128, 87, 69, 88, 128, 87, 69, 85, 88, 128, + 87, 69, 212, 87, 69, 83, 84, 69, 82, 206, 87, 69, 83, 84, 45, 67, 82, 69, + 197, 87, 69, 83, 84, 128, 87, 69, 83, 212, 87, 69, 80, 128, 87, 69, 79, + 128, 87, 69, 78, 128, 87, 69, 76, 76, 128, 87, 69, 73, 71, 72, 212, 87, + 69, 73, 69, 82, 83, 84, 82, 65, 83, 211, 87, 69, 73, 128, 87, 69, 69, 78, + 128, 87, 69, 68, 71, 69, 45, 84, 65, 73, 76, 69, 196, 87, 69, 68, 71, 69, + 128, 87, 69, 68, 68, 73, 78, 71, 128, 87, 69, 66, 128, 87, 69, 65, 82, + 217, 87, 69, 65, 80, 79, 78, 128, 87, 69, 45, 52, 128, 87, 69, 45, 51, + 128, 87, 69, 45, 50, 128, 87, 69, 45, 49, 128, 87, 67, 128, 87, 66, 128, + 87, 65, 89, 128, 87, 65, 217, 87, 65, 88, 73, 78, 199, 87, 65, 88, 128, + 87, 65, 87, 45, 65, 89, 73, 78, 45, 82, 69, 83, 72, 128, 87, 65, 87, 128, + 87, 65, 215, 87, 65, 86, 217, 87, 65, 86, 73, 78, 199, 87, 65, 86, 69, + 83, 128, 87, 65, 86, 69, 128, 87, 65, 86, 197, 87, 65, 85, 128, 87, 65, + 84, 84, 79, 128, 87, 65, 84, 69, 82, 77, 69, 76, 79, 78, 128, 87, 65, 84, + 69, 82, 128, 87, 65, 84, 69, 210, 87, 65, 84, 67, 72, 128, 87, 65, 84, + 128, 87, 65, 83, 84, 73, 78, 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, 75, + 69, 84, 128, 87, 65, 83, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, + 128, 87, 65, 83, 76, 193, 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, + 83, 65, 76, 76, 65, 205, 87, 65, 83, 45, 83, 65, 76, 65, 65, 77, 128, 87, + 65, 82, 78, 73, 78, 199, 87, 65, 82, 65, 78, 199, 87, 65, 81, 70, 65, + 128, 87, 65, 80, 128, 87, 65, 78, 73, 78, 199, 87, 65, 78, 71, 75, 85, + 79, 81, 128, 87, 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 78, 68, 128, + 87, 65, 78, 67, 72, 207, 87, 65, 78, 128, 87, 65, 76, 76, 80, 76, 65, 78, + 197, 87, 65, 76, 76, 69, 196, 87, 65, 76, 76, 128, 87, 65, 76, 204, 87, + 65, 76, 75, 128, 87, 65, 76, 203, 87, 65, 73, 84, 73, 78, 71, 128, 87, + 65, 73, 83, 84, 128, 87, 65, 73, 128, 87, 65, 70, 70, 76, 69, 128, 87, + 65, 69, 78, 128, 87, 65, 69, 128, 87, 65, 68, 68, 65, 128, 87, 65, 65, + 86, 85, 128, 87, 65, 65, 74, 73, 66, 128, 87, 65, 65, 65, 76, 73, 72, 69, 197, 87, 65, 45, 84, 65, 65, 65, 76, 65, 65, 128, 87, 65, 45, 83, 65, 76, 76, 65, 77, 128, 87, 65, 45, 65, 65, 76, 73, 72, 128, 87, 65, 45, 53, 128, 87, 65, 45, 52, 128, 87, 65, 45, 51, 128, 87, 65, 45, 50, 128, 87, @@ -937,249 +937,250 @@ static const unsigned char lexicon[] = { 75, 73, 78, 199, 83, 85, 67, 75, 69, 68, 128, 83, 85, 67, 203, 83, 85, 67, 67, 69, 69, 68, 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, 67, 69, 69, 68, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, - 84, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, - 84, 73, 84, 85, 84, 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, - 85, 66, 83, 69, 84, 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, - 73, 80, 212, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, - 73, 78, 69, 65, 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, - 85, 66, 76, 73, 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, - 84, 69, 45, 50, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, - 76, 73, 77, 65, 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 82, 128, 83, 85, - 66, 74, 79, 73, 78, 69, 196, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, - 73, 84, 79, 128, 83, 85, 66, 72, 65, 65, 78, 65, 72, 213, 83, 85, 66, 71, - 82, 79, 85, 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, 128, - 83, 85, 65, 77, 128, 83, 85, 65, 69, 84, 128, 83, 85, 65, 69, 78, 128, - 83, 85, 65, 69, 128, 83, 85, 65, 66, 128, 83, 85, 65, 128, 83, 85, 45, - 56, 128, 83, 85, 45, 55, 128, 83, 85, 45, 54, 128, 83, 85, 45, 53, 128, - 83, 85, 45, 52, 128, 83, 85, 45, 51, 128, 83, 85, 45, 50, 128, 83, 85, - 45, 49, 128, 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, - 80, 65, 128, 83, 84, 85, 70, 70, 69, 196, 83, 84, 85, 68, 89, 128, 83, - 84, 85, 68, 73, 207, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, - 128, 83, 84, 82, 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, - 82, 79, 75, 69, 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, - 75, 69, 45, 56, 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, - 75, 69, 45, 54, 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, - 75, 69, 45, 52, 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, - 75, 69, 45, 50, 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, - 79, 75, 69, 45, 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, - 82, 79, 75, 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, - 128, 83, 84, 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, - 71, 72, 128, 83, 84, 82, 73, 75, 197, 83, 84, 82, 73, 68, 69, 128, 83, - 84, 82, 73, 67, 84, 76, 217, 83, 84, 82, 69, 84, 67, 72, 69, 196, 83, 84, - 82, 69, 84, 67, 72, 128, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, 78, 71, - 84, 72, 128, 83, 84, 82, 69, 76, 193, 83, 84, 82, 69, 65, 77, 69, 82, - 128, 83, 84, 82, 65, 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 87, - 128, 83, 84, 82, 65, 84, 85, 77, 45, 50, 128, 83, 84, 82, 65, 84, 85, 77, - 128, 83, 84, 82, 65, 84, 85, 205, 83, 84, 82, 65, 84, 73, 65, 206, 83, - 84, 82, 65, 78, 78, 79, 128, 83, 84, 82, 65, 78, 78, 207, 83, 84, 82, 65, - 73, 78, 69, 82, 128, 83, 84, 82, 65, 73, 71, 72, 84, 78, 69, 83, 83, 128, - 83, 84, 82, 65, 73, 71, 72, 84, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, - 84, 82, 65, 73, 70, 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, - 128, 83, 84, 79, 86, 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, - 87, 65, 84, 67, 72, 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, - 80, 80, 65, 71, 69, 128, 83, 84, 79, 80, 73, 84, 83, 65, 128, 83, 84, 79, - 80, 73, 84, 83, 193, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, - 78, 69, 128, 83, 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, 73, - 82, 82, 85, 208, 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, 83, - 84, 73, 76, 197, 83, 84, 73, 71, 77, 65, 128, 83, 84, 73, 67, 75, 73, 78, - 199, 83, 84, 73, 67, 203, 83, 84, 69, 84, 72, 79, 83, 67, 79, 80, 69, - 128, 83, 84, 69, 82, 69, 79, 128, 83, 84, 69, 80, 128, 83, 84, 69, 78, - 79, 71, 82, 65, 80, 72, 73, 195, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, - 217, 83, 84, 69, 65, 77, 73, 78, 199, 83, 84, 69, 65, 77, 128, 83, 84, - 69, 65, 205, 83, 84, 65, 86, 82, 79, 85, 128, 83, 84, 65, 86, 82, 79, 83, - 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 65, 85, 82, 79, 83, 128, 83, - 84, 65, 84, 89, 65, 128, 83, 84, 65, 84, 89, 193, 83, 84, 65, 84, 85, - 197, 83, 84, 65, 84, 73, 79, 78, 128, 83, 84, 65, 84, 69, 82, 83, 128, - 83, 84, 65, 84, 69, 128, 83, 84, 65, 82, 84, 73, 78, 199, 83, 84, 65, 82, - 84, 128, 83, 84, 65, 82, 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, - 82, 69, 196, 83, 84, 65, 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, - 210, 83, 84, 65, 78, 68, 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 73, - 78, 199, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, 68, 128, 83, - 84, 65, 78, 128, 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, 76, 76, 73, 79, - 78, 128, 83, 84, 65, 70, 70, 128, 83, 84, 65, 70, 198, 83, 84, 65, 68, - 73, 85, 77, 128, 83, 84, 65, 67, 75, 69, 196, 83, 84, 65, 67, 67, 65, 84, - 79, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, 83, 84, - 50, 128, 83, 83, 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, 82, 88, - 128, 83, 83, 89, 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, 83, 83, - 85, 88, 128, 83, 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, 85, 80, - 128, 83, 83, 79, 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, 128, 83, - 83, 79, 79, 128, 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, 73, 84, - 128, 83, 83, 73, 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, 88, 128, - 83, 83, 73, 69, 80, 128, 83, 83, 73, 69, 128, 83, 83, 72, 73, 78, 128, - 83, 83, 72, 69, 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, 83, - 69, 69, 128, 83, 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, 84, - 128, 83, 83, 65, 80, 128, 83, 83, 65, 78, 71, 89, 69, 83, 73, 69, 85, 78, - 71, 128, 83, 83, 65, 78, 71, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, - 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, - 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, - 84, 72, 73, 69, 85, 84, 72, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, - 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 80, - 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 75, 73, 89, - 69, 79, 75, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 83, 65, 78, - 71, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 83, 65, - 78, 71, 82, 73, 69, 85, 76, 128, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, - 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 83, 83, 65, 78, 71, 77, - 73, 69, 85, 77, 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, - 65, 78, 71, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, - 67, 45, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, - 128, 83, 83, 65, 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, - 83, 83, 65, 65, 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 69, 68, - 78, 197, 83, 82, 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, - 69, 204, 83, 81, 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, - 81, 85, 69, 69, 90, 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, - 65, 212, 83, 81, 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, - 128, 83, 81, 85, 65, 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, - 83, 80, 85, 78, 71, 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, - 71, 83, 128, 83, 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, - 83, 65, 78, 199, 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, - 83, 80, 79, 85, 84, 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, - 211, 83, 80, 79, 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, - 69, 128, 83, 80, 79, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, - 76, 73, 84, 128, 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, - 83, 80, 76, 65, 83, 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, - 80, 73, 82, 73, 84, 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, - 84, 128, 83, 80, 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, - 73, 78, 69, 128, 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, - 128, 83, 80, 73, 68, 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 73, 128, - 83, 80, 72, 69, 82, 73, 67, 65, 204, 83, 80, 69, 83, 77, 73, 76, 207, 83, - 80, 69, 78, 212, 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, 69, - 67, 72, 128, 83, 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, 128, - 83, 80, 69, 65, 82, 128, 83, 80, 69, 65, 75, 73, 78, 199, 83, 80, 69, 65, - 75, 69, 82, 128, 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, - 79, 45, 69, 86, 73, 204, 83, 80, 69, 128, 83, 80, 65, 84, 72, 73, 128, - 83, 80, 65, 82, 75, 76, 73, 78, 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, - 83, 80, 65, 82, 75, 76, 69, 82, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, - 80, 65, 71, 72, 69, 84, 84, 73, 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, - 65, 68, 197, 83, 80, 65, 67, 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, - 65, 128, 83, 79, 89, 79, 77, 66, 207, 83, 79, 89, 128, 83, 79, 87, 73, - 76, 207, 83, 79, 87, 128, 83, 79, 85, 84, 72, 69, 82, 206, 83, 79, 85, - 84, 72, 45, 83, 76, 65, 86, 69, 217, 83, 79, 85, 84, 200, 83, 79, 85, 82, - 67, 69, 128, 83, 79, 85, 78, 68, 128, 83, 79, 85, 78, 196, 83, 79, 85, - 78, 65, 80, 128, 83, 79, 85, 128, 83, 79, 83, 128, 83, 79, 82, 79, 67, - 72, 89, 193, 83, 79, 82, 73, 128, 83, 79, 82, 193, 83, 79, 81, 128, 83, - 79, 79, 206, 83, 79, 78, 74, 65, 77, 128, 83, 79, 78, 71, 128, 83, 79, - 78, 128, 83, 79, 77, 80, 69, 78, 199, 83, 79, 77, 128, 83, 79, 205, 83, - 79, 76, 73, 68, 85, 83, 128, 83, 79, 76, 73, 68, 85, 211, 83, 79, 76, 73, - 196, 83, 79, 76, 68, 73, 69, 82, 128, 83, 79, 72, 128, 83, 79, 71, 68, - 73, 65, 206, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, - 79, 206, 83, 79, 70, 84, 78, 69, 83, 83, 128, 83, 79, 70, 84, 66, 65, 76, - 76, 128, 83, 79, 70, 212, 83, 79, 198, 83, 79, 67, 75, 83, 128, 83, 79, - 67, 73, 69, 84, 89, 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, - 83, 79, 65, 128, 83, 79, 45, 55, 128, 83, 79, 45, 54, 128, 83, 79, 45, - 53, 128, 83, 79, 45, 52, 128, 83, 79, 45, 51, 128, 83, 79, 45, 50, 128, - 83, 79, 45, 49, 128, 83, 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, - 79, 87, 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, - 87, 66, 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, - 215, 83, 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, 83, 78, 69, 69, 90, - 73, 78, 199, 83, 78, 65, 208, 83, 78, 65, 75, 69, 128, 83, 78, 65, 75, - 197, 83, 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, 79, 75, 73, 78, 199, - 83, 77, 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, 78, 199, 83, 77, 73, - 76, 69, 128, 83, 77, 73, 76, 197, 83, 77, 69, 65, 82, 128, 83, 77, 65, - 83, 200, 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, 76, 76, 128, 83, 76, - 85, 82, 128, 83, 76, 79, 90, 72, 73, 84, 73, 69, 128, 83, 76, 79, 90, 72, - 73, 84, 73, 197, 83, 76, 79, 87, 76, 89, 128, 83, 76, 79, 87, 128, 83, - 76, 79, 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 84, 72, 128, 83, 76, - 79, 212, 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, - 79, 65, 206, 83, 76, 73, 78, 71, 128, 83, 76, 73, 71, 72, 84, 76, 217, - 83, 76, 73, 68, 73, 78, 71, 128, 83, 76, 73, 68, 69, 82, 128, 83, 76, 73, - 68, 69, 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, 197, 83, 76, 69, - 85, 84, 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, 199, - 83, 76, 69, 69, 208, 83, 76, 69, 68, 128, 83, 76, 65, 86, 79, 78, 73, - 195, 83, 76, 65, 86, 69, 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, - 200, 83, 76, 65, 78, 84, 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, - 83, 75, 85, 78, 75, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, 76, 204, - 83, 75, 79, 66, 65, 128, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, - 128, 83, 75, 73, 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, - 75, 65, 84, 69, 66, 79, 65, 82, 68, 128, 83, 75, 65, 84, 69, 128, 83, 75, - 65, 77, 69, 89, 84, 83, 193, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, - 197, 83, 73, 88, 84, 89, 45, 70, 79, 85, 82, 84, 72, 83, 128, 83, 73, 88, - 84, 89, 45, 70, 79, 85, 82, 84, 72, 128, 83, 73, 88, 84, 89, 45, 70, 79, - 85, 82, 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, - 88, 84, 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, - 83, 73, 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, - 84, 72, 45, 50, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 45, 49, 128, 83, - 73, 88, 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, - 83, 73, 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, - 45, 84, 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, - 83, 73, 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, - 83, 73, 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 82, - 65, 72, 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, - 73, 69, 85, 84, 72, 128, 83, 73, 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, - 79, 83, 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, - 45, 80, 73, 69, 85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, - 45, 80, 72, 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, - 73, 79, 83, 128, 83, 73, 79, 83, 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, - 83, 45, 77, 73, 69, 85, 77, 128, 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, - 75, 72, 128, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, - 69, 85, 80, 128, 83, 73, 79, 83, 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, - 83, 45, 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, - 128, 83, 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73, 79, - 211, 83, 73, 78, 85, 83, 79, 73, 196, 83, 73, 78, 79, 76, 79, 71, 73, 67, - 65, 204, 83, 73, 78, 78, 89, 73, 73, 89, 72, 69, 128, 83, 73, 78, 75, 73, - 78, 71, 128, 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, - 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, - 71, 76, 69, 45, 76, 73, 78, 197, 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, - 71, 76, 197, 83, 73, 78, 71, 65, 65, 84, 128, 83, 73, 78, 197, 83, 73, - 78, 68, 72, 201, 83, 73, 78, 128, 83, 73, 206, 83, 73, 77, 85, 76, 84, - 65, 78, 69, 79, 85, 83, 128, 83, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, - 211, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, - 128, 83, 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, - 73, 77, 65, 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, - 69, 82, 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, - 76, 72, 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, - 197, 83, 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, - 83, 73, 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, 71, 77, 79, 73, 196, - 83, 73, 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, - 73, 71, 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, - 83, 73, 68, 69, 87, 65, 89, 211, 83, 73, 68, 69, 128, 83, 73, 68, 197, - 83, 73, 68, 68, 72, 73, 128, 83, 73, 68, 68, 72, 65, 77, 128, 83, 73, 68, - 68, 72, 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, - 69, 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, 73, 45, 54, 128, 83, 73, - 45, 53, 128, 83, 73, 45, 52, 128, 83, 73, 45, 51, 128, 83, 73, 45, 50, - 128, 83, 73, 45, 49, 128, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, - 128, 83, 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, - 83, 72, 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, - 79, 89, 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, - 73, 73, 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, - 83, 72, 87, 65, 65, 128, 83, 72, 87, 65, 128, 83, 72, 86, 128, 83, 72, - 85, 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, 84, 84, 76, 69, 67, 79, 67, - 75, 128, 83, 72, 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, - 128, 83, 72, 85, 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, - 128, 83, 72, 85, 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, - 72, 85, 70, 70, 76, 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, - 72, 85, 69, 84, 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 65, 78, 71, - 88, 73, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, - 72, 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 85, 71, - 128, 83, 72, 82, 79, 79, 128, 83, 72, 82, 79, 128, 83, 72, 82, 73, 78, - 69, 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 73, 128, 83, 72, - 82, 73, 128, 83, 72, 82, 65, 65, 128, 83, 72, 82, 65, 128, 83, 72, 79, - 89, 128, 83, 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, - 85, 76, 68, 69, 82, 69, 196, 83, 72, 79, 85, 76, 68, 69, 210, 83, 72, 79, - 85, 128, 83, 72, 79, 84, 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 79, - 82, 84, 211, 83, 72, 79, 82, 84, 72, 65, 78, 196, 83, 72, 79, 82, 84, 69, - 78, 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, - 84, 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, - 73, 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, - 79, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, - 79, 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, - 45, 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, - 73, 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, 72, - 79, 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 80, 73, 78, 199, 83, 72, - 79, 80, 128, 83, 72, 79, 79, 84, 73, 78, 199, 83, 72, 79, 79, 84, 128, - 83, 72, 79, 79, 73, 128, 83, 72, 79, 79, 128, 83, 72, 79, 71, 201, 83, - 72, 79, 199, 83, 72, 79, 69, 83, 128, 83, 72, 79, 69, 128, 83, 72, 79, - 197, 83, 72, 79, 67, 75, 69, 196, 83, 72, 79, 65, 128, 83, 72, 79, 128, - 83, 72, 73, 89, 89, 65, 65, 76, 65, 65, 128, 83, 72, 73, 84, 65, 128, 83, - 72, 73, 84, 193, 83, 72, 73, 82, 212, 83, 72, 73, 82, 65, 69, 128, 83, - 72, 73, 82, 128, 83, 72, 73, 210, 83, 72, 73, 81, 128, 83, 72, 73, 78, - 84, 207, 83, 72, 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, - 73, 206, 83, 72, 73, 77, 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, 77, - 128, 83, 72, 73, 205, 83, 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, 83, - 72, 73, 70, 212, 83, 72, 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, 83, - 72, 73, 196, 83, 72, 72, 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, 128, - 83, 72, 69, 86, 65, 128, 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, 79, 81, + 84, 128, 83, 85, 66, 84, 82, 65, 67, 84, 73, 79, 78, 128, 83, 85, 66, 83, + 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, 84, 73, 84, 85, 84, 69, + 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, 85, 66, 83, 69, 84, + 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, 73, 80, 212, 83, + 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, 73, 78, 69, 65, + 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, 85, 66, 76, 73, + 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 45, 50, + 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, 76, 73, 77, 65, + 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 82, 128, 83, 85, 66, 74, 79, 73, + 78, 69, 196, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, 73, 84, 79, + 128, 83, 85, 66, 72, 65, 65, 78, 65, 72, 213, 83, 85, 66, 71, 82, 79, 85, + 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, 128, 83, 85, 65, + 77, 128, 83, 85, 65, 69, 84, 128, 83, 85, 65, 69, 78, 128, 83, 85, 65, + 69, 128, 83, 85, 65, 66, 128, 83, 85, 65, 128, 83, 85, 45, 56, 128, 83, + 85, 45, 55, 128, 83, 85, 45, 54, 128, 83, 85, 45, 53, 128, 83, 85, 45, + 52, 128, 83, 85, 45, 51, 128, 83, 85, 45, 50, 128, 83, 85, 45, 49, 128, + 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, 80, 65, 128, + 83, 84, 85, 70, 70, 69, 196, 83, 84, 85, 68, 89, 128, 83, 84, 85, 68, 73, + 207, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, 128, 83, 84, 82, + 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, 82, 79, 75, 69, + 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, 75, 69, 45, 56, + 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, 75, 69, 45, 54, + 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, 75, 69, 45, 52, + 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, 75, 69, 45, 50, + 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, 79, 75, 69, 45, + 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, 82, 79, 75, + 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, 128, 83, 84, + 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, 71, 72, 128, + 83, 84, 82, 73, 75, 197, 83, 84, 82, 73, 68, 69, 128, 83, 84, 82, 73, 67, + 84, 76, 217, 83, 84, 82, 69, 84, 67, 72, 69, 196, 83, 84, 82, 69, 84, 67, + 72, 128, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, 78, 71, 84, 72, 128, + 83, 84, 82, 69, 76, 193, 83, 84, 82, 69, 65, 77, 69, 82, 128, 83, 84, 82, + 65, 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 87, 128, 83, 84, 82, 65, + 84, 85, 77, 45, 50, 128, 83, 84, 82, 65, 84, 85, 77, 128, 83, 84, 82, 65, + 84, 85, 205, 83, 84, 82, 65, 84, 73, 65, 206, 83, 84, 82, 65, 78, 78, 79, + 128, 83, 84, 82, 65, 78, 78, 207, 83, 84, 82, 65, 73, 78, 69, 82, 128, + 83, 84, 82, 65, 73, 71, 72, 84, 78, 69, 83, 83, 128, 83, 84, 82, 65, 73, + 71, 72, 84, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, 84, 82, 65, 73, 70, + 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, 128, 83, 84, 79, 86, + 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, 87, 65, 84, 67, 72, + 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, 80, 80, 65, 71, 69, + 128, 83, 84, 79, 80, 73, 84, 83, 65, 128, 83, 84, 79, 80, 73, 84, 83, + 193, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, 78, 69, 128, 83, + 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, 73, 82, 82, 85, 208, + 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, 83, 84, 73, 76, 197, + 83, 84, 73, 71, 77, 65, 128, 83, 84, 73, 67, 75, 73, 78, 199, 83, 84, 73, + 67, 203, 83, 84, 69, 84, 72, 79, 83, 67, 79, 80, 69, 128, 83, 84, 69, 82, + 69, 79, 128, 83, 84, 69, 80, 128, 83, 84, 69, 78, 79, 71, 82, 65, 80, 72, + 73, 195, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, 217, 83, 84, 69, 65, + 77, 73, 78, 199, 83, 84, 69, 65, 77, 128, 83, 84, 69, 65, 205, 83, 84, + 65, 86, 82, 79, 85, 128, 83, 84, 65, 86, 82, 79, 83, 128, 83, 84, 65, 86, + 82, 79, 211, 83, 84, 65, 85, 82, 79, 83, 128, 83, 84, 65, 84, 89, 65, + 128, 83, 84, 65, 84, 89, 193, 83, 84, 65, 84, 85, 197, 83, 84, 65, 84, + 73, 79, 78, 128, 83, 84, 65, 84, 69, 82, 83, 128, 83, 84, 65, 84, 69, + 128, 83, 84, 65, 82, 84, 73, 78, 199, 83, 84, 65, 82, 84, 128, 83, 84, + 65, 82, 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, 82, 69, 196, 83, + 84, 65, 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, 210, 83, 84, 65, + 78, 68, 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 73, 78, 199, 83, 84, + 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, 68, 128, 83, 84, 65, 78, 128, + 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, 76, 76, 73, 79, 78, 128, 83, 84, + 65, 70, 70, 128, 83, 84, 65, 70, 198, 83, 84, 65, 68, 73, 85, 77, 128, + 83, 84, 65, 67, 75, 69, 196, 83, 84, 65, 67, 67, 65, 84, 79, 128, 83, 84, + 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, 83, 84, 50, 128, 83, 83, + 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, 82, 88, 128, 83, 83, 89, + 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, 83, 83, 85, 88, 128, 83, + 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, 85, 80, 128, 83, 83, 79, + 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, 128, 83, 83, 79, 79, 128, + 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, 73, 84, 128, 83, 83, 73, + 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, 88, 128, 83, 83, 73, 69, + 80, 128, 83, 83, 73, 69, 128, 83, 83, 72, 73, 78, 128, 83, 83, 72, 69, + 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, 83, 69, 69, 128, 83, + 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, 84, 128, 83, 83, 65, + 80, 128, 83, 83, 65, 78, 71, 89, 69, 83, 73, 69, 85, 78, 71, 128, 83, 83, + 65, 78, 71, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 83, 83, 65, + 78, 71, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, + 78, 71, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 84, 72, 73, 69, + 85, 84, 72, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 84, 73, 75, 69, + 85, 84, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, + 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, + 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 83, 65, 78, 71, 82, 73, 69, + 85, 76, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 83, 65, 78, 71, 82, 73, + 69, 85, 76, 128, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 83, 83, 65, + 78, 71, 78, 73, 69, 85, 78, 128, 83, 83, 65, 78, 71, 77, 73, 69, 85, 77, + 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, 65, 78, 71, 72, + 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 45, 72, 73, + 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 83, 83, 65, + 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, 83, 83, 65, 65, + 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 69, 68, 78, 197, 83, 82, + 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, 69, 204, 83, 81, + 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, 81, 85, 69, 69, 90, + 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, 65, 212, 83, 81, + 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, 128, 83, 81, 85, 65, + 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, 83, 80, 85, 78, 71, + 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, 71, 83, 128, 83, + 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, 83, 65, 78, 199, + 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, 83, 80, 79, 85, 84, + 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, 211, 83, 80, 79, + 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, 69, 128, 83, 80, + 79, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, 76, 73, 84, 128, + 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, 83, 80, 76, 65, 83, + 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, 80, 73, 82, 73, 84, + 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, 84, 128, 83, 80, + 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, 73, 78, 69, 128, + 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, 128, 83, 80, 73, 68, + 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 73, 128, 83, 80, 72, 69, 82, + 73, 67, 65, 204, 83, 80, 69, 83, 77, 73, 76, 207, 83, 80, 69, 78, 212, + 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, 69, 67, 72, 128, 83, + 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, 128, 83, 80, 69, 65, 82, + 128, 83, 80, 69, 65, 75, 73, 78, 199, 83, 80, 69, 65, 75, 69, 82, 128, + 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, 79, 45, 69, 86, + 73, 204, 83, 80, 69, 128, 83, 80, 65, 84, 72, 73, 128, 83, 80, 65, 82, + 75, 76, 73, 78, 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, 83, 80, 65, 82, + 75, 76, 69, 82, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, 80, 65, 71, 72, + 69, 84, 84, 73, 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, 65, 68, 197, + 83, 80, 65, 67, 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, 65, 128, 83, + 79, 89, 79, 77, 66, 207, 83, 79, 89, 128, 83, 79, 87, 73, 76, 207, 83, + 79, 87, 128, 83, 79, 85, 84, 72, 69, 82, 206, 83, 79, 85, 84, 72, 45, 83, + 76, 65, 86, 69, 217, 83, 79, 85, 84, 200, 83, 79, 85, 82, 67, 69, 128, + 83, 79, 85, 78, 68, 128, 83, 79, 85, 78, 196, 83, 79, 85, 78, 65, 80, + 128, 83, 79, 85, 128, 83, 79, 83, 128, 83, 79, 82, 79, 67, 72, 89, 193, + 83, 79, 82, 73, 128, 83, 79, 82, 193, 83, 79, 81, 128, 83, 79, 79, 206, + 83, 79, 78, 74, 65, 77, 128, 83, 79, 78, 71, 128, 83, 79, 78, 128, 83, + 79, 77, 80, 69, 78, 199, 83, 79, 77, 128, 83, 79, 205, 83, 79, 76, 73, + 68, 85, 83, 128, 83, 79, 76, 73, 68, 85, 211, 83, 79, 76, 73, 196, 83, + 79, 76, 68, 73, 69, 82, 128, 83, 79, 72, 128, 83, 79, 71, 68, 73, 65, + 206, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, 79, 206, + 83, 79, 70, 84, 78, 69, 83, 83, 128, 83, 79, 70, 84, 66, 65, 76, 76, 128, + 83, 79, 70, 212, 83, 79, 198, 83, 79, 67, 75, 83, 128, 83, 79, 67, 73, + 69, 84, 89, 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, 83, 79, + 65, 128, 83, 79, 45, 55, 128, 83, 79, 45, 54, 128, 83, 79, 45, 53, 128, + 83, 79, 45, 52, 128, 83, 79, 45, 51, 128, 83, 79, 45, 50, 128, 83, 79, + 45, 49, 128, 83, 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, 79, 87, + 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, 87, 66, + 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, 215, 83, + 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, 83, 78, 69, 69, 90, 73, 78, + 199, 83, 78, 65, 208, 83, 78, 65, 75, 69, 128, 83, 78, 65, 75, 197, 83, + 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, 79, 75, 73, 78, 199, 83, 77, + 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, 78, 199, 83, 77, 73, 76, 69, + 128, 83, 77, 73, 76, 197, 83, 77, 69, 65, 82, 128, 83, 77, 65, 83, 200, + 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, 76, 76, 128, 83, 76, 85, 82, + 128, 83, 76, 79, 90, 72, 73, 84, 73, 69, 128, 83, 76, 79, 90, 72, 73, 84, + 73, 197, 83, 76, 79, 87, 76, 89, 128, 83, 76, 79, 87, 128, 83, 76, 79, + 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 84, 72, 128, 83, 76, 79, 212, + 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, 79, 65, + 206, 83, 76, 73, 78, 71, 128, 83, 76, 73, 71, 72, 84, 76, 217, 83, 76, + 73, 68, 73, 78, 71, 128, 83, 76, 73, 68, 69, 82, 128, 83, 76, 73, 68, 69, + 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, 197, 83, 76, 69, 85, 84, + 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, 199, 83, 76, + 69, 69, 208, 83, 76, 69, 68, 128, 83, 76, 65, 86, 79, 78, 73, 195, 83, + 76, 65, 86, 69, 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, 200, 83, + 76, 65, 78, 84, 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, 83, 75, + 85, 78, 75, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, 76, 204, 83, 75, + 79, 66, 65, 128, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, 128, 83, + 75, 73, 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, 75, 65, + 84, 69, 66, 79, 65, 82, 68, 128, 83, 75, 65, 84, 69, 128, 83, 75, 65, 77, + 69, 89, 84, 83, 193, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, 197, 83, + 73, 88, 84, 89, 45, 70, 79, 85, 82, 84, 72, 83, 128, 83, 73, 88, 84, 89, + 45, 70, 79, 85, 82, 84, 72, 128, 83, 73, 88, 84, 89, 45, 70, 79, 85, 82, + 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, 88, 84, + 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, 83, 73, + 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, + 45, 50, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 45, 49, 128, 83, 73, 88, + 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, 83, 73, + 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, 45, 84, + 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, 83, 73, + 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, 83, 73, + 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 82, 65, 72, + 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, 73, 69, + 85, 84, 72, 128, 83, 73, 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, + 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, 45, 80, + 73, 69, 85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, 45, 80, + 72, 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, 73, 79, + 83, 128, 83, 73, 79, 83, 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, 83, 45, + 77, 73, 69, 85, 77, 128, 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, 75, 72, + 128, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, + 80, 128, 83, 73, 79, 83, 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, 83, 45, + 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 83, + 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73, 79, 211, 83, 73, + 78, 85, 83, 79, 73, 196, 83, 73, 78, 79, 76, 79, 71, 73, 67, 65, 204, 83, + 73, 78, 78, 89, 73, 73, 89, 72, 69, 128, 83, 73, 78, 75, 73, 78, 71, 128, + 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, 83, 73, 78, + 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, 71, 76, 69, + 45, 76, 73, 78, 197, 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, 71, 76, + 197, 83, 73, 78, 71, 65, 65, 84, 128, 83, 73, 78, 197, 83, 73, 78, 68, + 72, 201, 83, 73, 78, 128, 83, 73, 206, 83, 73, 77, 85, 76, 84, 65, 78, + 69, 79, 85, 83, 128, 83, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, 211, 83, + 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, 128, 83, + 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, 73, 77, 65, + 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, 69, 82, + 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, 76, 72, + 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, 197, 83, + 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, 83, 73, + 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, 71, 77, 79, 73, 196, 83, 73, + 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, 73, 71, + 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, 83, 73, + 68, 69, 87, 65, 89, 211, 83, 73, 68, 69, 128, 83, 73, 68, 197, 83, 73, + 68, 68, 72, 73, 128, 83, 73, 68, 68, 72, 65, 77, 128, 83, 73, 68, 68, 72, + 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, 69, + 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, 73, 45, 54, 128, 83, 73, 45, + 53, 128, 83, 73, 45, 52, 128, 83, 73, 45, 51, 128, 83, 73, 45, 50, 128, + 83, 73, 45, 49, 128, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, 128, + 83, 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, 83, + 72, 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, 79, + 89, 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, 73, + 73, 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, 83, + 72, 87, 65, 65, 128, 83, 72, 87, 65, 128, 83, 72, 86, 128, 83, 72, 85, + 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, 84, 84, 76, 69, 67, 79, 67, 75, + 128, 83, 72, 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, 128, + 83, 72, 85, 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, 128, + 83, 72, 85, 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, 72, + 85, 70, 70, 76, 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, 72, + 85, 69, 84, 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 65, 78, 71, 88, + 73, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, 72, + 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 85, 71, 128, + 83, 72, 82, 79, 79, 128, 83, 72, 82, 79, 128, 83, 72, 82, 73, 78, 69, + 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 73, 128, 83, 72, 82, + 73, 128, 83, 72, 82, 65, 65, 128, 83, 72, 82, 65, 128, 83, 72, 79, 89, + 128, 83, 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, 85, + 76, 68, 69, 82, 69, 196, 83, 72, 79, 85, 76, 68, 69, 210, 83, 72, 79, 85, + 128, 83, 72, 79, 84, 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 79, 82, + 84, 211, 83, 72, 79, 82, 84, 72, 65, 78, 196, 83, 72, 79, 82, 84, 69, 78, + 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, 84, + 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, + 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, 79, + 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, 79, + 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, 45, + 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, + 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, + 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, + 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, 72, 79, + 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 80, 73, 78, 199, 83, 72, 79, + 80, 128, 83, 72, 79, 79, 84, 73, 78, 199, 83, 72, 79, 79, 84, 128, 83, + 72, 79, 79, 73, 128, 83, 72, 79, 79, 128, 83, 72, 79, 71, 201, 83, 72, + 79, 199, 83, 72, 79, 69, 83, 128, 83, 72, 79, 69, 128, 83, 72, 79, 197, + 83, 72, 79, 67, 75, 69, 196, 83, 72, 79, 65, 128, 83, 72, 79, 128, 83, + 72, 73, 89, 89, 65, 65, 76, 65, 65, 128, 83, 72, 73, 84, 65, 128, 83, 72, + 73, 84, 193, 83, 72, 73, 82, 212, 83, 72, 73, 82, 65, 69, 128, 83, 72, + 73, 82, 128, 83, 72, 73, 210, 83, 72, 73, 81, 128, 83, 72, 73, 78, 84, + 207, 83, 72, 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, 73, + 206, 83, 72, 73, 77, 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, 77, 128, + 83, 72, 73, 205, 83, 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, 83, 72, + 73, 70, 212, 83, 72, 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, 83, 72, + 73, 196, 83, 72, 72, 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, 128, 83, + 72, 69, 86, 65, 128, 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, 79, 81, 128, 83, 72, 69, 85, 65, 69, 81, 84, 85, 128, 83, 72, 69, 85, 65, 69, 81, 128, 83, 72, 69, 85, 65, 69, 128, 83, 72, 69, 84, 128, 83, 72, 69, 212, 83, 72, 69, 83, 72, 76, 65, 77, 128, 83, 72, 69, 83, 72, 73, 71, 128, 83, @@ -1655,239 +1656,240 @@ static const unsigned char lexicon[] = { 76, 85, 83, 128, 82, 69, 71, 85, 76, 85, 211, 82, 69, 71, 73, 83, 84, 69, 82, 69, 196, 82, 69, 71, 73, 79, 78, 65, 204, 82, 69, 71, 73, 65, 45, 50, 128, 82, 69, 71, 73, 65, 128, 82, 69, 70, 79, 82, 77, 69, 196, 82, 69, - 70, 69, 82, 69, 78, 67, 197, 82, 69, 68, 85, 80, 76, 73, 67, 65, 84, 73, - 79, 78, 128, 82, 69, 67, 89, 67, 76, 73, 78, 199, 82, 69, 67, 89, 67, 76, - 69, 196, 82, 69, 67, 84, 73, 76, 73, 78, 69, 65, 210, 82, 69, 67, 84, 65, - 78, 71, 85, 76, 65, 210, 82, 69, 67, 84, 65, 78, 71, 76, 69, 128, 82, 69, - 67, 84, 65, 78, 71, 76, 197, 82, 69, 67, 82, 69, 65, 84, 73, 79, 78, 65, - 204, 82, 69, 67, 79, 82, 68, 73, 78, 199, 82, 69, 67, 79, 82, 68, 69, 82, - 128, 82, 69, 67, 79, 82, 68, 128, 82, 69, 67, 79, 82, 196, 82, 69, 67, - 73, 84, 65, 84, 73, 86, 197, 82, 69, 67, 69, 80, 84, 73, 86, 197, 82, 69, - 67, 69, 73, 86, 69, 82, 128, 82, 69, 67, 69, 73, 86, 69, 210, 82, 69, 67, - 69, 73, 80, 84, 128, 82, 69, 65, 76, 71, 65, 82, 45, 50, 128, 82, 69, 65, - 76, 71, 65, 82, 128, 82, 69, 65, 72, 77, 85, 75, 128, 82, 69, 65, 68, 73, - 78, 199, 82, 69, 65, 67, 72, 128, 82, 69, 45, 52, 128, 82, 69, 45, 51, - 128, 82, 69, 45, 50, 128, 82, 69, 45, 49, 128, 82, 68, 207, 82, 68, 69, - 204, 82, 66, 65, 83, 193, 82, 65, 90, 83, 69, 75, 65, 128, 82, 65, 90, - 79, 82, 128, 82, 65, 89, 83, 128, 82, 65, 89, 211, 82, 65, 89, 65, 78, - 78, 65, 128, 82, 65, 86, 78, 79, 128, 82, 65, 84, 73, 79, 128, 82, 65, - 84, 72, 65, 128, 82, 65, 84, 72, 193, 82, 65, 84, 65, 128, 82, 65, 84, - 128, 82, 65, 83, 87, 65, 68, 73, 128, 82, 65, 83, 79, 85, 204, 82, 65, - 83, 72, 65, 128, 82, 65, 81, 128, 82, 65, 80, 73, 83, 77, 65, 128, 82, - 65, 78, 71, 197, 82, 65, 78, 65, 128, 82, 65, 78, 128, 82, 65, 77, 211, - 82, 65, 77, 66, 65, 84, 128, 82, 65, 75, 72, 65, 78, 71, 128, 82, 65, 75, - 65, 65, 82, 65, 65, 78, 83, 65, 89, 65, 128, 82, 65, 73, 83, 73, 78, 199, - 82, 65, 73, 83, 69, 68, 128, 82, 65, 73, 83, 69, 196, 82, 65, 73, 78, 66, - 79, 87, 128, 82, 65, 73, 76, 87, 65, 89, 128, 82, 65, 73, 76, 87, 65, - 217, 82, 65, 73, 76, 128, 82, 65, 73, 68, 207, 82, 65, 73, 68, 65, 128, - 82, 65, 72, 77, 65, 84, 85, 76, 76, 65, 200, 82, 65, 72, 73, 77, 65, 72, - 85, 205, 82, 65, 72, 73, 77, 65, 72, 213, 82, 65, 70, 69, 128, 82, 65, - 69, 77, 128, 82, 65, 68, 73, 79, 65, 67, 84, 73, 86, 197, 82, 65, 68, 73, - 79, 128, 82, 65, 68, 73, 207, 82, 65, 68, 201, 82, 65, 68, 128, 82, 65, - 196, 82, 65, 67, 81, 85, 69, 212, 82, 65, 67, 73, 78, 71, 128, 82, 65, - 67, 73, 78, 199, 82, 65, 67, 67, 79, 79, 78, 128, 82, 65, 66, 66, 73, 84, - 128, 82, 65, 66, 66, 73, 212, 82, 65, 66, 128, 82, 65, 65, 73, 128, 82, - 65, 51, 128, 82, 65, 50, 128, 82, 65, 45, 75, 65, 82, 65, 128, 82, 65, - 45, 52, 128, 82, 65, 45, 51, 128, 82, 65, 45, 50, 128, 82, 65, 45, 49, - 128, 82, 48, 50, 57, 128, 82, 48, 50, 56, 128, 82, 48, 50, 55, 128, 82, - 48, 50, 54, 128, 82, 48, 50, 53, 128, 82, 48, 50, 52, 128, 82, 48, 50, - 51, 128, 82, 48, 50, 50, 128, 82, 48, 50, 49, 128, 82, 48, 50, 48, 128, - 82, 48, 49, 57, 128, 82, 48, 49, 56, 128, 82, 48, 49, 55, 128, 82, 48, - 49, 54, 65, 128, 82, 48, 49, 54, 128, 82, 48, 49, 53, 128, 82, 48, 49, - 52, 128, 82, 48, 49, 51, 128, 82, 48, 49, 50, 128, 82, 48, 49, 49, 128, - 82, 48, 49, 48, 65, 128, 82, 48, 49, 48, 128, 82, 48, 48, 57, 128, 82, - 48, 48, 56, 128, 82, 48, 48, 55, 128, 82, 48, 48, 54, 128, 82, 48, 48, - 53, 128, 82, 48, 48, 52, 128, 82, 48, 48, 51, 66, 128, 82, 48, 48, 51, - 65, 128, 82, 48, 48, 51, 128, 82, 48, 48, 50, 65, 128, 82, 48, 48, 50, - 128, 82, 48, 48, 49, 128, 82, 45, 67, 82, 69, 197, 81, 89, 88, 128, 81, - 89, 85, 128, 81, 89, 84, 128, 81, 89, 82, 88, 128, 81, 89, 82, 128, 81, - 89, 80, 128, 81, 89, 79, 128, 81, 89, 73, 128, 81, 89, 69, 69, 128, 81, - 89, 69, 128, 81, 89, 65, 65, 128, 81, 89, 65, 128, 81, 89, 128, 81, 87, - 73, 128, 81, 87, 69, 69, 128, 81, 87, 69, 128, 81, 87, 65, 65, 128, 81, - 87, 65, 128, 81, 85, 88, 128, 81, 85, 86, 128, 81, 85, 85, 86, 128, 81, - 85, 85, 128, 81, 85, 84, 128, 81, 85, 83, 72, 83, 72, 65, 89, 65, 128, - 81, 85, 82, 88, 128, 81, 85, 82, 128, 81, 85, 80, 128, 81, 85, 79, 88, - 128, 81, 85, 79, 84, 197, 81, 85, 79, 84, 65, 84, 73, 79, 206, 81, 85, - 79, 84, 128, 81, 85, 79, 80, 128, 81, 85, 79, 128, 81, 85, 75, 128, 81, - 85, 73, 78, 84, 73, 76, 69, 128, 81, 85, 73, 78, 84, 69, 83, 83, 69, 78, - 67, 69, 128, 81, 85, 73, 78, 68, 73, 67, 69, 83, 73, 77, 193, 81, 85, 73, - 78, 67, 85, 78, 88, 128, 81, 85, 73, 78, 65, 82, 73, 85, 211, 81, 85, 73, - 76, 212, 81, 85, 73, 76, 76, 128, 81, 85, 73, 67, 203, 81, 85, 73, 128, - 81, 85, 70, 128, 81, 85, 69, 83, 84, 73, 79, 78, 69, 196, 81, 85, 69, 83, - 84, 73, 79, 78, 128, 81, 85, 69, 83, 84, 73, 79, 206, 81, 85, 69, 69, 78, - 128, 81, 85, 69, 69, 206, 81, 85, 69, 128, 81, 85, 68, 68, 73, 83, 193, - 81, 85, 66, 85, 84, 83, 128, 81, 85, 65, 84, 69, 82, 78, 73, 79, 206, 81, - 85, 65, 82, 84, 69, 82, 83, 128, 81, 85, 65, 82, 84, 69, 82, 211, 81, 85, - 65, 82, 84, 69, 82, 128, 81, 85, 65, 79, 65, 82, 128, 81, 85, 65, 78, 84, - 73, 84, 217, 81, 85, 65, 68, 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, - 78, 84, 128, 81, 85, 65, 68, 82, 65, 78, 212, 81, 85, 65, 68, 67, 79, 76, - 79, 78, 128, 81, 85, 65, 68, 128, 81, 85, 65, 196, 81, 85, 65, 128, 81, - 85, 128, 81, 208, 81, 79, 88, 128, 81, 79, 84, 128, 81, 79, 80, 72, 128, - 81, 79, 80, 65, 128, 81, 79, 80, 128, 81, 79, 79, 128, 81, 79, 207, 81, - 79, 70, 128, 81, 79, 198, 81, 79, 65, 128, 81, 79, 128, 81, 78, 128, 81, - 73, 88, 128, 81, 73, 84, 83, 65, 128, 81, 73, 84, 128, 81, 73, 80, 128, - 81, 73, 73, 128, 81, 73, 70, 128, 81, 73, 69, 88, 128, 81, 73, 69, 84, - 128, 81, 73, 69, 80, 128, 81, 73, 69, 128, 81, 73, 128, 81, 72, 87, 73, - 128, 81, 72, 87, 69, 69, 128, 81, 72, 87, 69, 128, 81, 72, 87, 65, 65, - 128, 81, 72, 87, 65, 128, 81, 72, 85, 128, 81, 72, 79, 80, 72, 128, 81, - 72, 79, 128, 81, 72, 73, 128, 81, 72, 69, 69, 128, 81, 72, 69, 128, 81, - 72, 65, 85, 128, 81, 72, 65, 65, 128, 81, 72, 65, 128, 81, 71, 65, 128, - 81, 69, 84, 65, 78, 65, 128, 81, 69, 69, 128, 81, 69, 128, 81, 65, 89, - 128, 81, 65, 85, 128, 81, 65, 84, 65, 78, 128, 81, 65, 83, 82, 128, 81, - 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, 128, 81, 65, 80, 72, - 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, 84, 211, 81, 65, 76, - 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, 73, 128, 81, 65, 70, - 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, 65, 73, 128, 81, 65, - 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, 55, 128, 81, 48, 48, - 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, 81, 48, 48, 51, 128, - 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, 128, 80, 89, 88, 128, - 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, 128, 80, 89, 80, 128, - 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, 79, 128, 80, 87, 207, - 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, 69, 128, 80, 87, 69, - 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, 80, 85, 90, 90, 76, - 197, 80, 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, 85, 128, 80, 85, 84, - 82, 69, 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, 78, 65, 89, 65, 128, - 80, 85, 84, 128, 80, 85, 212, 80, 85, 83, 72, 80, 73, 78, 128, 80, 85, - 83, 72, 80, 73, 75, 65, 128, 80, 85, 83, 72, 73, 78, 199, 80, 85, 82, 88, - 128, 80, 85, 82, 83, 69, 128, 80, 85, 82, 80, 76, 197, 80, 85, 82, 78, - 65, 77, 65, 128, 80, 85, 82, 73, 84, 89, 128, 80, 85, 82, 73, 70, 89, - 128, 80, 85, 82, 128, 80, 85, 81, 128, 80, 85, 80, 128, 80, 85, 79, 88, - 128, 80, 85, 79, 80, 128, 80, 85, 79, 128, 80, 85, 78, 71, 65, 65, 77, - 128, 80, 85, 78, 71, 128, 80, 85, 78, 67, 84, 85, 211, 80, 85, 78, 67, - 84, 85, 65, 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, - 206, 80, 85, 77, 80, 128, 80, 85, 77, 128, 80, 85, 70, 70, 69, 68, 128, - 80, 85, 69, 128, 80, 85, 67, 75, 128, 80, 85, 66, 76, 73, 195, 80, 85, - 194, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 80, 85, 65, 67, 72, 85, - 197, 80, 85, 50, 128, 80, 85, 49, 128, 80, 85, 128, 80, 84, 72, 65, 72, - 193, 80, 84, 69, 128, 80, 83, 73, 76, 201, 80, 83, 73, 70, 73, 83, 84, - 79, 83, 89, 78, 65, 71, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 80, - 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, - 79, 206, 80, 83, 73, 70, 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 128, - 80, 83, 73, 128, 80, 83, 65, 76, 84, 69, 210, 80, 83, 128, 80, 82, 79, - 86, 69, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, 211, 80, 82, 79, 84, 79, - 211, 80, 82, 79, 84, 69, 67, 84, 69, 196, 80, 82, 79, 83, 84, 65, 89, 65, - 128, 80, 82, 79, 83, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 80, 82, - 79, 83, 69, 82, 80, 73, 78, 65, 128, 80, 82, 79, 80, 79, 82, 84, 73, 79, - 78, 65, 204, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 128, 80, 82, 79, 80, - 69, 82, 84, 217, 80, 82, 79, 80, 69, 76, 76, 69, 210, 80, 82, 79, 79, 70, - 128, 80, 82, 79, 76, 79, 78, 71, 69, 196, 80, 82, 79, 76, 65, 84, 73, 79, - 78, 197, 80, 82, 79, 74, 69, 67, 84, 79, 82, 128, 80, 82, 79, 74, 69, 67, - 84, 73, 86, 69, 128, 80, 82, 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, - 79, 72, 73, 66, 73, 84, 69, 196, 80, 82, 79, 71, 82, 69, 83, 83, 128, 80, - 82, 79, 71, 82, 65, 205, 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, 79, - 68, 85, 67, 84, 128, 80, 82, 79, 68, 85, 67, 212, 80, 82, 79, 66, 73, 78, - 199, 80, 82, 73, 90, 78, 65, 203, 80, 82, 73, 86, 65, 84, 69, 128, 80, - 82, 73, 86, 65, 84, 197, 80, 82, 73, 86, 65, 67, 217, 80, 82, 73, 83, 72, - 84, 72, 65, 77, 65, 84, 82, 193, 80, 82, 73, 78, 84, 83, 128, 80, 82, 73, - 78, 84, 69, 82, 128, 80, 82, 73, 78, 84, 69, 210, 80, 82, 73, 78, 84, - 128, 80, 82, 73, 78, 212, 80, 82, 73, 78, 67, 69, 83, 83, 128, 80, 82, - 73, 78, 67, 69, 128, 80, 82, 73, 77, 69, 128, 80, 82, 73, 77, 197, 80, - 82, 69, 86, 73, 79, 85, 211, 80, 82, 69, 84, 90, 69, 76, 128, 80, 82, 69, - 83, 83, 69, 196, 80, 82, 69, 83, 69, 84, 128, 80, 82, 69, 83, 69, 78, 84, - 65, 84, 73, 79, 206, 80, 82, 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 80, - 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, 67, 69, 128, 80, 82, 69, 78, 75, - 72, 65, 128, 80, 82, 69, 71, 78, 65, 78, 212, 80, 82, 69, 70, 73, 88, 69, - 196, 80, 82, 69, 70, 65, 67, 197, 80, 82, 69, 67, 73, 80, 73, 84, 65, 84, - 69, 128, 80, 82, 69, 67, 69, 68, 73, 78, 199, 80, 82, 69, 67, 69, 68, 69, - 83, 128, 80, 82, 69, 67, 69, 68, 69, 211, 80, 82, 69, 67, 69, 68, 69, - 196, 80, 82, 69, 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, 68, 197, 80, - 82, 65, 89, 69, 210, 80, 82, 65, 77, 45, 80, 73, 73, 128, 80, 82, 65, 77, - 45, 80, 73, 201, 80, 82, 65, 77, 45, 77, 85, 79, 89, 128, 80, 82, 65, 77, - 45, 77, 85, 79, 217, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, - 77, 45, 66, 85, 79, 206, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, - 77, 45, 66, 69, 201, 80, 82, 65, 77, 128, 80, 82, 65, 205, 80, 82, 128, - 80, 80, 86, 128, 80, 80, 77, 128, 80, 80, 65, 128, 80, 79, 89, 128, 80, - 79, 88, 128, 80, 79, 87, 69, 82, 211, 80, 79, 87, 69, 82, 128, 80, 79, - 87, 69, 210, 80, 79, 87, 68, 69, 82, 69, 196, 80, 79, 87, 68, 69, 82, - 128, 80, 79, 86, 89, 83, 72, 69, 128, 80, 79, 86, 89, 83, 72, 197, 80, - 79, 86, 79, 68, 78, 89, 128, 80, 79, 85, 82, 73, 78, 199, 80, 79, 85, 78, - 196, 80, 79, 85, 76, 84, 82, 217, 80, 79, 85, 67, 72, 128, 80, 79, 84, - 84, 69, 196, 80, 79, 84, 65, 84, 79, 128, 80, 79, 84, 65, 66, 76, 197, - 80, 79, 212, 80, 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 79, 83, - 84, 66, 79, 88, 128, 80, 79, 83, 84, 65, 204, 80, 79, 83, 84, 128, 80, - 79, 83, 212, 80, 79, 83, 83, 69, 83, 83, 73, 79, 78, 128, 80, 79, 83, 83, - 69, 83, 83, 73, 79, 206, 80, 79, 83, 73, 84, 73, 79, 78, 83, 128, 80, 79, - 83, 73, 84, 73, 79, 78, 128, 80, 79, 83, 69, 73, 68, 79, 78, 128, 80, 79, - 82, 84, 65, 66, 76, 197, 80, 79, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, - 82, 82, 69, 67, 84, 85, 211, 80, 79, 80, 80, 73, 78, 199, 80, 79, 80, 80, - 69, 82, 128, 80, 79, 80, 67, 79, 82, 78, 128, 80, 79, 80, 128, 80, 79, - 208, 80, 79, 79, 68, 76, 69, 128, 80, 79, 79, 128, 80, 79, 78, 68, 79, - 128, 80, 79, 206, 80, 79, 77, 77, 69, 69, 128, 80, 79, 77, 77, 69, 197, - 80, 79, 76, 85, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 80, 79, 76, 79, - 128, 80, 79, 76, 78, 65, 89, 65, 128, 80, 79, 76, 76, 85, 128, 80, 79, - 76, 75, 85, 76, 73, 90, 77, 89, 128, 80, 79, 76, 73, 83, 72, 128, 80, 79, - 76, 73, 83, 200, 80, 79, 76, 73, 67, 197, 80, 79, 76, 201, 80, 79, 76, - 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, 89, 84, 73, 69, 128, 80, 79, - 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, 211, 80, 79, 73, 78, 84, 79, - 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, 79, 73, 78, 84, 69, 196, 80, - 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, 80, 79, 69, 84, 82, 217, 80, - 79, 69, 84, 73, 195, 80, 79, 68, 86, 69, 82, 84, 75, 65, 128, 80, 79, 68, - 67, 72, 65, 83, 72, 73, 69, 77, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, - 69, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, 197, 80, 79, 68, 65, 84, 85, - 83, 128, 80, 79, 67, 75, 69, 212, 80, 79, 65, 128, 80, 207, 80, 78, 69, - 85, 77, 65, 84, 65, 128, 80, 76, 85, 84, 207, 80, 76, 85, 84, 65, 128, - 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 76, 85, 83, 128, 80, 76, 85, - 82, 65, 76, 128, 80, 76, 85, 78, 71, 69, 82, 128, 80, 76, 85, 77, 69, - 196, 80, 76, 85, 77, 128, 80, 76, 85, 75, 128, 80, 76, 85, 71, 128, 80, - 76, 85, 128, 80, 76, 79, 87, 128, 80, 76, 79, 80, 72, 85, 128, 80, 76, - 72, 65, 85, 128, 80, 76, 69, 84, 72, 82, 79, 78, 128, 80, 76, 69, 65, 68, - 73, 78, 199, 80, 76, 68, 128, 80, 76, 65, 89, 73, 78, 199, 80, 76, 65, - 89, 71, 82, 79, 85, 78, 196, 80, 76, 65, 84, 69, 128, 80, 76, 65, 83, 84, - 73, 67, 83, 128, 80, 76, 65, 78, 84, 128, 80, 76, 65, 78, 69, 84, 128, - 80, 76, 65, 78, 69, 128, 80, 76, 65, 78, 67, 203, 80, 76, 65, 75, 128, - 80, 76, 65, 71, 73, 79, 211, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 82, - 128, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 210, 80, 76, 65, 67, 197, - 80, 76, 65, 67, 65, 82, 68, 128, 80, 76, 65, 128, 80, 73, 90, 90, 73, 67, - 65, 84, 79, 128, 80, 73, 90, 90, 65, 128, 80, 73, 88, 128, 80, 73, 87, - 82, 128, 80, 73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 84, 67, 72, 70, - 79, 82, 203, 80, 73, 84, 128, 80, 73, 83, 84, 79, 76, 128, 80, 73, 83, - 69, 76, 69, 72, 128, 80, 73, 83, 67, 69, 83, 128, 80, 73, 82, 73, 71, - 128, 80, 73, 82, 73, 199, 80, 73, 82, 73, 69, 69, 78, 128, 80, 73, 82, - 65, 67, 89, 128, 80, 73, 82, 50, 128, 80, 73, 80, 73, 78, 71, 128, 80, - 73, 80, 65, 69, 77, 71, 66, 73, 69, 69, 128, 80, 73, 80, 65, 69, 77, 66, - 65, 128, 80, 73, 80, 128, 80, 73, 78, 87, 72, 69, 69, 204, 80, 73, 78, - 203, 80, 73, 78, 69, 65, 80, 80, 76, 69, 128, 80, 73, 78, 197, 80, 73, - 78, 67, 72, 73, 78, 199, 80, 73, 78, 67, 72, 69, 196, 80, 73, 78, 65, 84, - 65, 128, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, 73, 76, 76, - 128, 80, 73, 76, 197, 80, 73, 76, 67, 82, 79, 215, 80, 73, 75, 85, 82, - 85, 128, 80, 73, 75, 79, 128, 80, 73, 71, 128, 80, 73, 199, 80, 73, 69, - 88, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, - 69, 85, 80, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 80, 73, 69, 85, - 80, 45, 83, 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 80, 73, 69, 85, - 80, 45, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, 69, - 85, 80, 45, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, 73, 69, 85, - 80, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 80, 73, 69, 85, - 80, 45, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 80, 73, 69, 85, 80, - 45, 82, 73, 69, 85, 76, 45, 80, 72, 73, 69, 85, 80, 72, 128, 80, 73, 69, - 85, 80, 45, 82, 73, 69, 85, 76, 128, 80, 73, 69, 85, 80, 45, 78, 73, 69, - 85, 78, 128, 80, 73, 69, 85, 80, 45, 77, 73, 69, 85, 77, 128, 80, 73, 69, - 85, 80, 45, 75, 72, 73, 69, 85, 75, 72, 128, 80, 73, 69, 85, 80, 45, 67, - 73, 69, 85, 67, 128, 80, 73, 69, 85, 80, 45, 67, 72, 73, 69, 85, 67, 72, - 128, 80, 73, 69, 85, 208, 80, 73, 69, 84, 128, 80, 73, 69, 80, 128, 80, - 73, 69, 69, 84, 128, 80, 73, 69, 69, 81, 128, 80, 73, 69, 67, 69, 128, - 80, 73, 69, 128, 80, 73, 67, 84, 85, 82, 69, 128, 80, 73, 67, 75, 85, - 208, 80, 73, 67, 75, 69, 84, 128, 80, 73, 67, 75, 128, 80, 73, 65, 83, - 85, 84, 79, 82, 85, 128, 80, 73, 65, 83, 84, 82, 197, 80, 73, 65, 83, 77, - 193, 80, 73, 65, 78, 79, 128, 80, 201, 80, 72, 87, 65, 128, 80, 72, 85, - 84, 72, 65, 79, 128, 80, 72, 85, 210, 80, 72, 85, 78, 71, 128, 80, 72, - 82, 65, 83, 69, 128, 80, 72, 79, 78, 69, 83, 128, 80, 72, 79, 76, 85, 83, - 128, 80, 72, 79, 69, 78, 73, 67, 73, 65, 206, 80, 72, 79, 65, 128, 80, - 72, 79, 128, 80, 72, 207, 80, 72, 78, 65, 69, 203, 80, 72, 73, 78, 84, - 72, 85, 128, 80, 72, 73, 76, 79, 83, 79, 80, 72, 69, 82, 211, 80, 72, 73, - 76, 73, 80, 80, 73, 78, 197, 80, 72, 73, 69, 85, 80, 72, 45, 84, 72, 73, - 69, 85, 84, 72, 128, 80, 72, 73, 69, 85, 80, 72, 45, 83, 73, 79, 83, 128, - 80, 72, 73, 69, 85, 80, 72, 45, 80, 73, 69, 85, 80, 128, 80, 72, 73, 69, - 85, 80, 72, 45, 72, 73, 69, 85, 72, 128, 80, 72, 73, 69, 85, 80, 200, 80, - 72, 73, 128, 80, 72, 201, 80, 72, 69, 69, 128, 80, 72, 69, 128, 80, 72, - 65, 83, 69, 45, 198, 80, 72, 65, 83, 69, 45, 195, 80, 72, 65, 83, 69, 45, - 194, 80, 72, 65, 83, 69, 45, 193, 80, 72, 65, 82, 89, 78, 71, 69, 65, - 204, 80, 72, 65, 82, 128, 80, 72, 65, 78, 128, 80, 72, 65, 77, 128, 80, - 72, 65, 73, 83, 84, 79, 211, 80, 72, 65, 71, 83, 45, 80, 193, 80, 72, 65, - 66, 128, 80, 72, 65, 65, 82, 75, 65, 65, 128, 80, 72, 65, 65, 128, 80, - 71, 128, 80, 70, 128, 80, 69, 85, 88, 128, 80, 69, 85, 84, 65, 69, 128, - 80, 69, 85, 84, 128, 80, 69, 84, 82, 201, 80, 69, 84, 65, 83, 84, 79, 75, - 79, 85, 70, 73, 83, 77, 65, 128, 80, 69, 84, 65, 83, 84, 73, 128, 80, 69, - 84, 65, 83, 77, 65, 128, 80, 69, 84, 65, 76, 76, 69, 196, 80, 69, 83, 79, + 70, 76, 69, 67, 84, 73, 79, 78, 128, 82, 69, 70, 69, 82, 69, 78, 67, 197, + 82, 69, 68, 85, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 82, 69, 67, 89, + 67, 76, 73, 78, 199, 82, 69, 67, 89, 67, 76, 69, 196, 82, 69, 67, 84, 73, + 76, 73, 78, 69, 65, 210, 82, 69, 67, 84, 65, 78, 71, 85, 76, 65, 210, 82, + 69, 67, 84, 65, 78, 71, 76, 69, 128, 82, 69, 67, 84, 65, 78, 71, 76, 197, + 82, 69, 67, 82, 69, 65, 84, 73, 79, 78, 65, 204, 82, 69, 67, 79, 82, 68, + 73, 78, 199, 82, 69, 67, 79, 82, 68, 69, 82, 128, 82, 69, 67, 79, 82, 68, + 128, 82, 69, 67, 79, 82, 196, 82, 69, 67, 73, 84, 65, 84, 73, 86, 197, + 82, 69, 67, 69, 80, 84, 73, 86, 197, 82, 69, 67, 69, 73, 86, 69, 82, 128, + 82, 69, 67, 69, 73, 86, 69, 210, 82, 69, 67, 69, 73, 80, 84, 128, 82, 69, + 65, 76, 71, 65, 82, 45, 50, 128, 82, 69, 65, 76, 71, 65, 82, 128, 82, 69, + 65, 72, 77, 85, 75, 128, 82, 69, 65, 68, 73, 78, 199, 82, 69, 65, 67, 72, + 128, 82, 69, 45, 52, 128, 82, 69, 45, 51, 128, 82, 69, 45, 50, 128, 82, + 69, 45, 49, 128, 82, 68, 207, 82, 68, 69, 204, 82, 66, 65, 83, 193, 82, + 65, 90, 83, 69, 75, 65, 128, 82, 65, 90, 79, 82, 128, 82, 65, 89, 83, + 128, 82, 65, 89, 211, 82, 65, 89, 65, 78, 78, 65, 128, 82, 65, 86, 78, + 79, 128, 82, 65, 84, 73, 79, 128, 82, 65, 84, 72, 65, 128, 82, 65, 84, + 72, 193, 82, 65, 84, 65, 128, 82, 65, 84, 128, 82, 65, 83, 87, 65, 68, + 73, 128, 82, 65, 83, 79, 85, 204, 82, 65, 83, 72, 65, 128, 82, 65, 81, + 128, 82, 65, 80, 73, 83, 77, 65, 128, 82, 65, 78, 71, 197, 82, 65, 78, + 65, 128, 82, 65, 78, 128, 82, 65, 77, 211, 82, 65, 77, 66, 65, 84, 128, + 82, 65, 75, 72, 65, 78, 71, 128, 82, 65, 75, 65, 65, 82, 65, 65, 78, 83, + 65, 89, 65, 128, 82, 65, 73, 83, 73, 78, 199, 82, 65, 73, 83, 69, 68, + 128, 82, 65, 73, 83, 69, 196, 82, 65, 73, 78, 66, 79, 87, 128, 82, 65, + 73, 76, 87, 65, 89, 128, 82, 65, 73, 76, 87, 65, 217, 82, 65, 73, 76, + 128, 82, 65, 73, 68, 207, 82, 65, 73, 68, 65, 128, 82, 65, 72, 77, 65, + 84, 85, 76, 76, 65, 200, 82, 65, 72, 73, 77, 65, 72, 85, 205, 82, 65, 72, + 73, 77, 65, 72, 213, 82, 65, 70, 69, 128, 82, 65, 69, 77, 128, 82, 65, + 68, 73, 79, 65, 67, 84, 73, 86, 197, 82, 65, 68, 73, 79, 128, 82, 65, 68, + 73, 207, 82, 65, 68, 201, 82, 65, 68, 128, 82, 65, 196, 82, 65, 67, 81, + 85, 69, 212, 82, 65, 67, 73, 78, 71, 128, 82, 65, 67, 73, 78, 199, 82, + 65, 67, 67, 79, 79, 78, 128, 82, 65, 66, 66, 73, 84, 128, 82, 65, 66, 66, + 73, 212, 82, 65, 66, 128, 82, 65, 65, 73, 128, 82, 65, 51, 128, 82, 65, + 50, 128, 82, 65, 45, 75, 65, 82, 65, 128, 82, 65, 45, 52, 128, 82, 65, + 45, 51, 128, 82, 65, 45, 50, 128, 82, 65, 45, 49, 128, 82, 48, 50, 57, + 128, 82, 48, 50, 56, 128, 82, 48, 50, 55, 128, 82, 48, 50, 54, 128, 82, + 48, 50, 53, 128, 82, 48, 50, 52, 128, 82, 48, 50, 51, 128, 82, 48, 50, + 50, 128, 82, 48, 50, 49, 128, 82, 48, 50, 48, 128, 82, 48, 49, 57, 128, + 82, 48, 49, 56, 128, 82, 48, 49, 55, 128, 82, 48, 49, 54, 65, 128, 82, + 48, 49, 54, 128, 82, 48, 49, 53, 128, 82, 48, 49, 52, 128, 82, 48, 49, + 51, 128, 82, 48, 49, 50, 128, 82, 48, 49, 49, 128, 82, 48, 49, 48, 65, + 128, 82, 48, 49, 48, 128, 82, 48, 48, 57, 128, 82, 48, 48, 56, 128, 82, + 48, 48, 55, 128, 82, 48, 48, 54, 128, 82, 48, 48, 53, 128, 82, 48, 48, + 52, 128, 82, 48, 48, 51, 66, 128, 82, 48, 48, 51, 65, 128, 82, 48, 48, + 51, 128, 82, 48, 48, 50, 65, 128, 82, 48, 48, 50, 128, 82, 48, 48, 49, + 128, 82, 45, 67, 82, 69, 197, 81, 89, 88, 128, 81, 89, 85, 128, 81, 89, + 84, 128, 81, 89, 82, 88, 128, 81, 89, 82, 128, 81, 89, 80, 128, 81, 89, + 79, 128, 81, 89, 73, 128, 81, 89, 69, 69, 128, 81, 89, 69, 128, 81, 89, + 65, 65, 128, 81, 89, 65, 128, 81, 89, 128, 81, 87, 73, 128, 81, 87, 69, + 69, 128, 81, 87, 69, 128, 81, 87, 65, 65, 128, 81, 87, 65, 128, 81, 85, + 88, 128, 81, 85, 86, 128, 81, 85, 85, 86, 128, 81, 85, 85, 128, 81, 85, + 84, 128, 81, 85, 83, 72, 83, 72, 65, 89, 65, 128, 81, 85, 82, 88, 128, + 81, 85, 82, 128, 81, 85, 80, 128, 81, 85, 79, 88, 128, 81, 85, 79, 84, + 197, 81, 85, 79, 84, 65, 84, 73, 79, 206, 81, 85, 79, 84, 128, 81, 85, + 79, 80, 128, 81, 85, 79, 128, 81, 85, 75, 128, 81, 85, 73, 78, 84, 73, + 76, 69, 128, 81, 85, 73, 78, 84, 69, 83, 83, 69, 78, 67, 69, 128, 81, 85, + 73, 78, 68, 73, 67, 69, 83, 73, 77, 193, 81, 85, 73, 78, 67, 85, 78, 88, + 128, 81, 85, 73, 78, 65, 82, 73, 85, 211, 81, 85, 73, 76, 212, 81, 85, + 73, 76, 76, 128, 81, 85, 73, 67, 203, 81, 85, 73, 128, 81, 85, 70, 128, + 81, 85, 69, 83, 84, 73, 79, 78, 69, 196, 81, 85, 69, 83, 84, 73, 79, 78, + 128, 81, 85, 69, 83, 84, 73, 79, 206, 81, 85, 69, 69, 78, 128, 81, 85, + 69, 69, 206, 81, 85, 69, 128, 81, 85, 68, 68, 73, 83, 193, 81, 85, 66, + 85, 84, 83, 128, 81, 85, 65, 84, 69, 82, 78, 73, 79, 206, 81, 85, 65, 82, + 84, 69, 82, 83, 128, 81, 85, 65, 82, 84, 69, 82, 211, 81, 85, 65, 82, 84, + 69, 82, 128, 81, 85, 65, 79, 65, 82, 128, 81, 85, 65, 78, 84, 73, 84, + 217, 81, 85, 65, 68, 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, 78, 84, + 128, 81, 85, 65, 68, 82, 65, 78, 212, 81, 85, 65, 68, 67, 79, 76, 79, 78, + 128, 81, 85, 65, 68, 128, 81, 85, 65, 196, 81, 85, 65, 128, 81, 85, 128, + 81, 208, 81, 79, 88, 128, 81, 79, 84, 128, 81, 79, 80, 72, 128, 81, 79, + 80, 65, 128, 81, 79, 80, 128, 81, 79, 79, 128, 81, 79, 207, 81, 79, 70, + 128, 81, 79, 198, 81, 79, 65, 128, 81, 79, 128, 81, 78, 128, 81, 73, 88, + 128, 81, 73, 84, 83, 65, 128, 81, 73, 84, 128, 81, 73, 80, 128, 81, 73, + 73, 128, 81, 73, 70, 128, 81, 73, 69, 88, 128, 81, 73, 69, 84, 128, 81, + 73, 69, 80, 128, 81, 73, 69, 128, 81, 73, 128, 81, 72, 87, 73, 128, 81, + 72, 87, 69, 69, 128, 81, 72, 87, 69, 128, 81, 72, 87, 65, 65, 128, 81, + 72, 87, 65, 128, 81, 72, 85, 128, 81, 72, 79, 80, 72, 128, 81, 72, 79, + 128, 81, 72, 73, 128, 81, 72, 69, 69, 128, 81, 72, 69, 128, 81, 72, 65, + 85, 128, 81, 72, 65, 65, 128, 81, 72, 65, 128, 81, 71, 65, 128, 81, 69, + 84, 65, 78, 65, 128, 81, 69, 69, 128, 81, 69, 128, 81, 65, 89, 128, 81, + 65, 85, 128, 81, 65, 84, 65, 78, 128, 81, 65, 83, 82, 128, 81, 65, 82, + 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, 128, 81, 65, 80, 72, 128, 81, + 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, 84, 211, 81, 65, 76, 193, 81, + 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, 73, 128, 81, 65, 70, 128, 81, + 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, 65, 73, 128, 81, 65, 65, 70, + 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, 55, 128, 81, 48, 48, 54, 128, + 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, 81, 48, 48, 51, 128, 81, 48, + 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, 128, 80, 89, 88, 128, 80, 89, + 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, 128, 80, 89, 80, 128, 80, 87, + 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, 79, 128, 80, 87, 207, 80, 87, + 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, 69, 128, 80, 87, 69, 128, 80, + 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, 80, 85, 90, 90, 76, 197, 80, + 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, 85, 128, 80, 85, 84, 82, 69, + 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, 78, 65, 89, 65, 128, 80, 85, + 84, 128, 80, 85, 212, 80, 85, 83, 72, 80, 73, 78, 128, 80, 85, 83, 72, + 80, 73, 75, 65, 128, 80, 85, 83, 72, 73, 78, 199, 80, 85, 82, 88, 128, + 80, 85, 82, 83, 69, 128, 80, 85, 82, 80, 76, 197, 80, 85, 82, 78, 65, 77, + 65, 128, 80, 85, 82, 73, 84, 89, 128, 80, 85, 82, 73, 70, 89, 128, 80, + 85, 82, 128, 80, 85, 81, 128, 80, 85, 80, 128, 80, 85, 79, 88, 128, 80, + 85, 79, 80, 128, 80, 85, 79, 128, 80, 85, 78, 71, 65, 65, 77, 128, 80, + 85, 78, 71, 128, 80, 85, 78, 67, 84, 85, 211, 80, 85, 78, 67, 84, 85, 65, + 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 206, 80, 85, + 77, 80, 128, 80, 85, 77, 128, 80, 85, 70, 70, 69, 68, 128, 80, 85, 69, + 128, 80, 85, 67, 75, 128, 80, 85, 66, 76, 73, 195, 80, 85, 194, 80, 85, + 65, 81, 128, 80, 85, 65, 69, 128, 80, 85, 65, 67, 72, 85, 197, 80, 85, + 50, 128, 80, 85, 49, 128, 80, 85, 128, 80, 84, 72, 65, 72, 193, 80, 84, + 69, 128, 80, 83, 73, 76, 201, 80, 83, 73, 70, 73, 83, 84, 79, 83, 89, 78, + 65, 71, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 80, 65, 82, 65, 75, + 65, 76, 69, 83, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 206, 80, 83, + 73, 70, 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 128, 80, 83, 73, 128, + 80, 83, 65, 76, 84, 69, 210, 80, 83, 128, 80, 82, 79, 86, 69, 128, 80, + 82, 79, 84, 79, 86, 65, 82, 89, 211, 80, 82, 79, 84, 79, 211, 80, 82, 79, + 84, 69, 67, 84, 69, 196, 80, 82, 79, 83, 84, 65, 89, 65, 128, 80, 82, 79, + 83, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 80, 82, 79, 83, 69, 82, + 80, 73, 78, 65, 128, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 65, 204, 80, + 82, 79, 80, 79, 82, 84, 73, 79, 78, 128, 80, 82, 79, 80, 69, 82, 84, 217, + 80, 82, 79, 80, 69, 76, 76, 69, 210, 80, 82, 79, 79, 70, 128, 80, 82, 79, + 76, 79, 78, 71, 69, 196, 80, 82, 79, 76, 65, 84, 73, 79, 78, 197, 80, 82, + 79, 74, 69, 67, 84, 79, 82, 128, 80, 82, 79, 74, 69, 67, 84, 73, 86, 69, + 128, 80, 82, 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, 79, 72, 73, 66, + 73, 84, 69, 196, 80, 82, 79, 71, 82, 69, 83, 83, 128, 80, 82, 79, 71, 82, + 65, 205, 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, 79, 68, 85, 67, 84, + 128, 80, 82, 79, 68, 85, 67, 212, 80, 82, 79, 66, 73, 78, 199, 80, 82, + 73, 90, 78, 65, 203, 80, 82, 73, 86, 65, 84, 69, 128, 80, 82, 73, 86, 65, + 84, 197, 80, 82, 73, 86, 65, 67, 217, 80, 82, 73, 83, 72, 84, 72, 65, 77, + 65, 84, 82, 193, 80, 82, 73, 78, 84, 83, 128, 80, 82, 73, 78, 84, 69, 82, + 128, 80, 82, 73, 78, 84, 69, 210, 80, 82, 73, 78, 84, 128, 80, 82, 73, + 78, 212, 80, 82, 73, 78, 67, 69, 83, 83, 128, 80, 82, 73, 78, 67, 69, + 128, 80, 82, 73, 77, 69, 128, 80, 82, 73, 77, 197, 80, 82, 69, 86, 73, + 79, 85, 211, 80, 82, 69, 84, 90, 69, 76, 128, 80, 82, 69, 83, 83, 69, + 196, 80, 82, 69, 83, 69, 84, 128, 80, 82, 69, 83, 69, 78, 84, 65, 84, 73, + 79, 206, 80, 82, 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 80, 82, 69, 80, + 79, 78, 68, 69, 82, 65, 78, 67, 69, 128, 80, 82, 69, 78, 75, 72, 65, 128, + 80, 82, 69, 71, 78, 65, 78, 212, 80, 82, 69, 70, 73, 88, 69, 196, 80, 82, + 69, 70, 65, 67, 197, 80, 82, 69, 67, 73, 80, 73, 84, 65, 84, 69, 128, 80, + 82, 69, 67, 69, 68, 73, 78, 199, 80, 82, 69, 67, 69, 68, 69, 83, 128, 80, + 82, 69, 67, 69, 68, 69, 211, 80, 82, 69, 67, 69, 68, 69, 196, 80, 82, 69, + 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, 68, 197, 80, 82, 65, 89, 69, + 210, 80, 82, 65, 77, 45, 80, 73, 73, 128, 80, 82, 65, 77, 45, 80, 73, + 201, 80, 82, 65, 77, 45, 77, 85, 79, 89, 128, 80, 82, 65, 77, 45, 77, 85, + 79, 217, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, 77, 45, 66, + 85, 79, 206, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, 77, 45, 66, + 69, 201, 80, 82, 65, 77, 128, 80, 82, 65, 205, 80, 82, 128, 80, 80, 86, + 128, 80, 80, 77, 128, 80, 80, 65, 128, 80, 79, 89, 128, 80, 79, 88, 128, + 80, 79, 87, 69, 82, 211, 80, 79, 87, 69, 82, 128, 80, 79, 87, 69, 210, + 80, 79, 87, 68, 69, 82, 69, 196, 80, 79, 87, 68, 69, 82, 128, 80, 79, 86, + 89, 83, 72, 69, 128, 80, 79, 86, 89, 83, 72, 197, 80, 79, 86, 79, 68, 78, + 89, 128, 80, 79, 85, 82, 73, 78, 199, 80, 79, 85, 78, 196, 80, 79, 85, + 76, 84, 82, 217, 80, 79, 85, 67, 72, 128, 80, 79, 84, 84, 69, 196, 80, + 79, 84, 65, 84, 79, 128, 80, 79, 84, 65, 66, 76, 197, 80, 79, 212, 80, + 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 79, 83, 84, 66, 79, 88, + 128, 80, 79, 83, 84, 65, 204, 80, 79, 83, 84, 128, 80, 79, 83, 212, 80, + 79, 83, 83, 69, 83, 83, 73, 79, 78, 128, 80, 79, 83, 83, 69, 83, 83, 73, + 79, 206, 80, 79, 83, 73, 84, 73, 79, 78, 83, 128, 80, 79, 83, 73, 84, 73, + 79, 78, 128, 80, 79, 83, 69, 73, 68, 79, 78, 128, 80, 79, 82, 84, 65, 66, + 76, 197, 80, 79, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, 82, 82, 69, 67, + 84, 85, 211, 80, 79, 80, 80, 73, 78, 199, 80, 79, 80, 80, 69, 82, 128, + 80, 79, 80, 67, 79, 82, 78, 128, 80, 79, 80, 128, 80, 79, 208, 80, 79, + 79, 68, 76, 69, 128, 80, 79, 79, 128, 80, 79, 78, 68, 79, 128, 80, 79, + 206, 80, 79, 77, 77, 69, 69, 128, 80, 79, 77, 77, 69, 197, 80, 79, 76, + 85, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 80, 79, 76, 79, 128, 80, 79, + 76, 78, 65, 89, 65, 128, 80, 79, 76, 76, 85, 128, 80, 79, 76, 75, 85, 76, + 73, 90, 77, 89, 128, 80, 79, 76, 73, 83, 72, 128, 80, 79, 76, 73, 83, + 200, 80, 79, 76, 73, 67, 197, 80, 79, 76, 201, 80, 79, 76, 69, 128, 80, + 79, 76, 197, 80, 79, 75, 82, 89, 84, 73, 69, 128, 80, 79, 75, 79, 74, 73, + 128, 80, 79, 73, 78, 84, 211, 80, 79, 73, 78, 84, 79, 128, 80, 79, 73, + 78, 84, 69, 82, 128, 80, 79, 73, 78, 84, 69, 196, 80, 79, 73, 78, 84, + 128, 80, 79, 73, 78, 212, 80, 79, 69, 84, 82, 217, 80, 79, 69, 84, 73, + 195, 80, 79, 68, 86, 69, 82, 84, 75, 65, 128, 80, 79, 68, 67, 72, 65, 83, + 72, 73, 69, 77, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, 69, 128, 80, 79, + 68, 67, 72, 65, 83, 72, 73, 197, 80, 79, 68, 65, 84, 85, 83, 128, 80, 79, + 67, 75, 69, 212, 80, 79, 65, 128, 80, 207, 80, 78, 69, 85, 77, 65, 84, + 65, 128, 80, 76, 85, 84, 207, 80, 76, 85, 84, 65, 128, 80, 76, 85, 83, + 45, 77, 73, 78, 85, 211, 80, 76, 85, 83, 128, 80, 76, 85, 82, 65, 76, + 128, 80, 76, 85, 78, 71, 69, 82, 128, 80, 76, 85, 77, 69, 196, 80, 76, + 85, 77, 128, 80, 76, 85, 75, 128, 80, 76, 85, 71, 128, 80, 76, 85, 128, + 80, 76, 79, 87, 128, 80, 76, 79, 80, 72, 85, 128, 80, 76, 72, 65, 85, + 128, 80, 76, 69, 84, 72, 82, 79, 78, 128, 80, 76, 69, 65, 68, 73, 78, + 199, 80, 76, 68, 128, 80, 76, 65, 89, 73, 78, 199, 80, 76, 65, 89, 71, + 82, 79, 85, 78, 196, 80, 76, 65, 84, 69, 128, 80, 76, 65, 83, 84, 73, 67, + 83, 128, 80, 76, 65, 78, 84, 128, 80, 76, 65, 78, 69, 84, 128, 80, 76, + 65, 78, 69, 128, 80, 76, 65, 78, 67, 203, 80, 76, 65, 75, 128, 80, 76, + 65, 71, 73, 79, 211, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 82, 128, 80, + 76, 65, 67, 69, 72, 79, 76, 68, 69, 210, 80, 76, 65, 67, 197, 80, 76, 65, + 67, 65, 82, 68, 128, 80, 76, 65, 128, 80, 73, 90, 90, 73, 67, 65, 84, 79, + 128, 80, 73, 90, 90, 65, 128, 80, 73, 88, 128, 80, 73, 87, 82, 128, 80, + 73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 84, 67, 72, 70, 79, 82, 203, + 80, 73, 84, 128, 80, 73, 83, 84, 79, 76, 128, 80, 73, 83, 69, 76, 69, 72, + 128, 80, 73, 83, 67, 69, 83, 128, 80, 73, 82, 73, 71, 128, 80, 73, 82, + 73, 199, 80, 73, 82, 73, 69, 69, 78, 128, 80, 73, 82, 65, 67, 89, 128, + 80, 73, 82, 50, 128, 80, 73, 80, 73, 78, 71, 128, 80, 73, 80, 65, 69, 77, + 71, 66, 73, 69, 69, 128, 80, 73, 80, 65, 69, 77, 66, 65, 128, 80, 73, 80, + 128, 80, 73, 78, 87, 72, 69, 69, 204, 80, 73, 78, 203, 80, 73, 78, 69, + 65, 80, 80, 76, 69, 128, 80, 73, 78, 197, 80, 73, 78, 67, 72, 73, 78, + 199, 80, 73, 78, 67, 72, 69, 196, 80, 73, 78, 65, 84, 65, 128, 80, 73, + 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, 73, 76, 76, 128, 80, 73, 76, + 197, 80, 73, 76, 67, 82, 79, 215, 80, 73, 75, 85, 82, 85, 128, 80, 73, + 75, 79, 128, 80, 73, 71, 128, 80, 73, 199, 80, 73, 69, 88, 128, 80, 73, + 69, 85, 80, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, 69, 85, 80, 45, + 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 80, 73, 69, 85, 80, 45, 83, 73, + 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 80, 73, 69, 85, 80, 45, 83, 73, + 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, 69, 85, 80, 45, 83, + 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, 73, 69, 85, 80, 45, 83, 73, + 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 80, 73, 69, 85, 80, 45, 83, 73, + 79, 83, 45, 67, 73, 69, 85, 67, 128, 80, 73, 69, 85, 80, 45, 82, 73, 69, + 85, 76, 45, 80, 72, 73, 69, 85, 80, 72, 128, 80, 73, 69, 85, 80, 45, 82, + 73, 69, 85, 76, 128, 80, 73, 69, 85, 80, 45, 78, 73, 69, 85, 78, 128, 80, + 73, 69, 85, 80, 45, 77, 73, 69, 85, 77, 128, 80, 73, 69, 85, 80, 45, 75, + 72, 73, 69, 85, 75, 72, 128, 80, 73, 69, 85, 80, 45, 67, 73, 69, 85, 67, + 128, 80, 73, 69, 85, 80, 45, 67, 72, 73, 69, 85, 67, 72, 128, 80, 73, 69, + 85, 208, 80, 73, 69, 84, 128, 80, 73, 69, 80, 128, 80, 73, 69, 69, 84, + 128, 80, 73, 69, 69, 81, 128, 80, 73, 69, 67, 69, 128, 80, 73, 69, 128, + 80, 73, 67, 84, 85, 82, 69, 128, 80, 73, 67, 75, 85, 208, 80, 73, 67, 75, + 69, 84, 128, 80, 73, 67, 75, 128, 80, 73, 65, 83, 85, 84, 79, 82, 85, + 128, 80, 73, 65, 83, 84, 82, 197, 80, 73, 65, 83, 77, 193, 80, 73, 65, + 78, 79, 128, 80, 201, 80, 72, 87, 65, 128, 80, 72, 85, 84, 72, 65, 79, + 128, 80, 72, 85, 210, 80, 72, 85, 78, 71, 128, 80, 72, 82, 65, 83, 69, + 128, 80, 72, 79, 78, 69, 83, 128, 80, 72, 79, 76, 85, 83, 128, 80, 72, + 79, 69, 78, 73, 67, 73, 65, 206, 80, 72, 79, 65, 128, 80, 72, 79, 128, + 80, 72, 207, 80, 72, 78, 65, 69, 203, 80, 72, 73, 78, 84, 72, 85, 128, + 80, 72, 73, 76, 79, 83, 79, 80, 72, 69, 82, 211, 80, 72, 73, 76, 73, 80, + 80, 73, 78, 197, 80, 72, 73, 69, 85, 80, 72, 45, 84, 72, 73, 69, 85, 84, + 72, 128, 80, 72, 73, 69, 85, 80, 72, 45, 83, 73, 79, 83, 128, 80, 72, 73, + 69, 85, 80, 72, 45, 80, 73, 69, 85, 80, 128, 80, 72, 73, 69, 85, 80, 72, + 45, 72, 73, 69, 85, 72, 128, 80, 72, 73, 69, 85, 80, 200, 80, 72, 73, + 128, 80, 72, 201, 80, 72, 69, 69, 128, 80, 72, 69, 128, 80, 72, 65, 83, + 69, 45, 198, 80, 72, 65, 83, 69, 45, 195, 80, 72, 65, 83, 69, 45, 194, + 80, 72, 65, 83, 69, 45, 193, 80, 72, 65, 82, 89, 78, 71, 69, 65, 204, 80, + 72, 65, 82, 128, 80, 72, 65, 78, 128, 80, 72, 65, 77, 128, 80, 72, 65, + 73, 83, 84, 79, 211, 80, 72, 65, 71, 83, 45, 80, 193, 80, 72, 65, 66, + 128, 80, 72, 65, 65, 82, 75, 65, 65, 128, 80, 72, 65, 65, 128, 80, 71, + 128, 80, 70, 128, 80, 69, 85, 88, 128, 80, 69, 85, 84, 65, 69, 128, 80, + 69, 85, 84, 128, 80, 69, 84, 82, 201, 80, 69, 84, 65, 83, 84, 79, 75, 79, + 85, 70, 73, 83, 77, 65, 128, 80, 69, 84, 65, 83, 84, 73, 128, 80, 69, 84, + 65, 83, 77, 65, 128, 80, 69, 84, 65, 76, 76, 69, 196, 80, 69, 83, 79, 128, 80, 69, 83, 207, 80, 69, 83, 72, 50, 128, 80, 69, 83, 72, 178, 80, 69, 83, 69, 84, 193, 80, 69, 211, 80, 69, 82, 84, 72, 207, 80, 69, 82, 83, 80, 69, 67, 84, 73, 86, 69, 128, 80, 69, 82, 83, 79, 78, 65, 204, 80, @@ -7120,9 +7122,9 @@ static const unsigned int lexicon_offset[] = { 593, 598, 606, 615, 618, 625, 629, 633, 637, 642, 645, 652, 659, 666, 671, 676, 683, 692, 694, 703, 707, 715, 719, 727, 281, 736, 749, 753, 758, 761, 765, 769, 771, 776, 786, 792, 796, 802, 806, 809, 814, 823, - 828, 832, 774, 838, 846, 854, 859, 868, 877, 885, 891, 902, 905, 910, + 828, 832, 774, 838, 846, 857, 865, 870, 879, 888, 896, 902, 905, 910, 918, 925, 928, 938, 943, 949, 953, 957, 960, 967, 974, 977, 981, 984, - 657, 990, 993, 996, 1002, 1007, 1016, 1021, 1025, 1028, 1032, 1035, 1041, + 657, 990, 993, 996, 1002, 1007, 1016, 1021, 1027, 1031, 1034, 1038, 1041, 1046, 1050, 617, 1055, 1058, 1067, 1070, 1075, 1080, 1086, 1091, 1096, 1101, 1105, 1110, 1116, 1121, 1126, 1130, 1136, 1141, 1146, 1151, 1155, 1160, 1165, 1170, 1176, 1182, 1188, 1193, 1197, 1202, 1207, 1212, 1216, @@ -7177,7 +7179,7 @@ static const unsigned int lexicon_offset[] = { 2172, 4008, 4012, 4015, 4021, 4026, 4032, 4038, 4043, 4050, 4054, 4058, 4062, 4067, 4072, 4077, 4082, 4087, 4092, 634, 616, 1264, 4097, 4104, 4111, 4117, 4126, 4131, 4138, 4145, 4150, 4156, 4162, 4167, 4172, 4176, - 4182, 4189, 4194, 4198, 4202, 2181, 4208, 4216, 4222, 4230, 863, 4236, + 4182, 4189, 4194, 4198, 4202, 2181, 4208, 4216, 4222, 4230, 874, 4236, 4244, 4255, 4259, 4269, 4275, 4280, 4285, 4290, 4295, 2186, 4300, 4305, 4320, 4326, 4333, 4344, 4354, 4360, 4365, 4371, 4377, 4380, 4383, 4387, 4392, 4395, 4402, 4411, 4416, 4420, 4424, 4428, 4432, 4437, 4443, 4454, @@ -7355,9505 +7357,9508 @@ static const unsigned int lexicon_offset[] = { 15923, 15931, 15938, 15949, 15954, 15964, 15973, 15977, 15980, 15987, 15997, 16006, 16013, 16017, 16024, 16030, 16035, 16040, 16044, 15590, 16053, 16057, 16063, 16067, 16072, 16076, 16083, 16090, 16094, 16103, - 16111, 16119, 16126, 16134, 16146, 16157, 16167, 16174, 16180, 16189, - 16200, 16209, 16221, 16233, 16245, 16255, 16264, 16274, 16283, 16291, - 16298, 16308, 16317, 16325, 16329, 16334, 16340, 16346, 16351, 16356, - 16360, 16365, 16370, 16375, 16380, 16385, 16390, 16395, 8738, 16400, - 16402, 16406, 16411, 16417, 16424, 16430, 16436, 16445, 16449, 16455, - 16463, 16470, 16479, 16488, 16497, 16506, 16515, 16524, 16533, 16542, - 16552, 16562, 16571, 16577, 16584, 16591, 16597, 16611, 16617, 16624, - 16632, 16641, 16649, 16655, 16664, 16670, 16679, 16690, 16696, 16706, - 16714, 16721, 16729, 16737, 16744, 16753, 16766, 16775, 16783, 16790, - 16803, 16809, 16815, 16825, 16834, 16843, 16852, 16860, 16865, 16869, - 16875, 16881, 16886, 16893, 16900, 10242, 16905, 16910, 16917, 16925, - 16930, 16942, 16949, 16954, 16966, 14943, 16971, 16977, 16985, 16991, - 16996, 17004, 17012, 17019, 17027, 17034, 17040, 17046, 17054, 17062, - 17068, 17076, 17082, 17087, 17093, 17100, 17106, 17111, 17115, 17126, - 17134, 17142, 17148, 17153, 17160, 17169, 17175, 17180, 17188, 17195, - 17204, 17218, 4413, 17222, 17227, 17232, 17238, 17243, 17248, 17252, - 17257, 17262, 17267, 8737, 17272, 17277, 17282, 17287, 17292, 17296, - 17301, 17306, 17311, 17316, 17322, 17328, 14216, 17333, 17339, 17344, - 17349, 17354, 10643, 17359, 17364, 17369, 17374, 17379, 17393, 17410, - 17428, 17440, 17453, 17470, 17486, 17503, 17513, 17532, 17543, 17554, - 17565, 2803, 17576, 17587, 17598, 17615, 17626, 17637, 17642, 10648, - 17647, 17651, 2483, 17655, 17661, 17664, 17670, 17678, 17686, 17692, - 17701, 17708, 17713, 17721, 17729, 17736, 17740, 17745, 17751, 17758, - 17766, 17773, 17785, 17792, 17798, 17806, 17811, 17817, 17823, 17828, - 13971, 17835, 17839, 17848, 17854, 17859, 17867, 17876, 17884, 17891, - 17897, 17905, 17912, 17918, 17924, 17931, 17938, 17944, 17950, 17954, - 17963, 17971, 17976, 17986, 17993, 17999, 18007, 18013, 18021, 18029, - 18036, 18049, 18053, 18060, 18069, 18078, 18087, 18095, 18105, 18112, - 18117, 3969, 18124, 18129, 1248, 18133, 18140, 17273, 18144, 18150, - 18154, 18162, 18174, 18179, 18186, 18192, 18197, 18204, 17278, 18208, - 18212, 18220, 18225, 18229, 17283, 18233, 17288, 18237, 18244, 18249, - 18253, 18260, 18264, 18267, 18275, 18282, 18287, 18295, 18299, 18306, - 18323, 18332, 18341, 18345, 18348, 18354, 18362, 18368, 18373, 18377, - 18382, 18387, 18392, 18397, 18402, 18407, 4047, 18412, 18414, 18422, - 18429, 18439, 18451, 18456, 18460, 18466, 18471, 18479, 18483, 18489, - 18494, 18500, 18503, 18510, 18518, 18525, 18531, 18536, 18542, 18547, - 18554, 18560, 18565, 18575, 18584, 18591, 18596, 18600, 18606, 18612, - 18616, 18623, 18629, 18634, 18640, 18648, 18656, 18663, 18669, 18675, - 18680, 18686, 18692, 18700, 18705, 18710, 18718, 18724, 18730, 18735, - 18742, 18747, 18751, 18757, 18763, 18768, 18774, 18781, 18786, 18792, - 18795, 18801, 18812, 18818, 18827, 18830, 18834, 18838, 18852, 18865, - 18877, 18883, 18888, 18895, 18901, 18907, 18918, 18930, 18942, 18952, - 18961, 18969, 18976, 18987, 18997, 19007, 19015, 19018, 17302, 19023, - 19028, 19035, 17307, 17458, 19043, 19056, 19071, 19082, 17475, 19100, - 19113, 19126, 19137, 12546, 19148, 19161, 19180, 19191, 19202, 19213, - 2824, 19226, 19230, 19238, 19249, 19260, 19268, 19283, 19298, 19309, - 19316, 19322, 19330, 19334, 19340, 19344, 19347, 19360, 19372, 19382, - 19390, 19397, 19405, 19415, 19420, 19427, 19432, 19439, 19450, 19460, - 19466, 19471, 19476, 17312, 19480, 19486, 19493, 19499, 19504, 19509, - 19514, 19518, 17317, 17323, 19522, 17329, 19527, 19535, 19540, 19544, - 19551, 19559, 19566, 19575, 19582, 19586, 19590, 19595, 19600, 19605, - 19610, 19615, 10487, 19620, 19622, 19627, 19632, 19638, 19643, 19648, - 19653, 19658, 19662, 19668, 19674, 19679, 19685, 19690, 19695, 19699, - 19705, 19710, 19714, 19719, 19724, 19736, 19741, 19747, 19752, 19757, - 19763, 19769, 19774, 19779, 19784, 19791, 19797, 19808, 19815, 19824, - 19829, 19833, 279, 19837, 19845, 19850, 19856, 19862, 19867, 19874, - 19881, 19887, 19892, 19898, 19903, 19908, 19913, 19920, 19930, 19938, - 19943, 19948, 19955, 19961, 19970, 19980, 19990, 20004, 20018, 20032, - 20046, 20061, 20076, 20093, 20111, 20124, 20130, 20135, 20140, 20144, - 20152, 20157, 20165, 20171, 20177, 20182, 20187, 20191, 20197, 20202, - 20206, 20213, 20218, 20222, 20233, 20239, 20244, 20249, 20256, 20261, - 20265, 3927, 20270, 20276, 20283, 17334, 20289, 20293, 20299, 20304, - 20309, 20313, 20319, 20324, 20329, 20336, 20341, 15730, 20345, 20350, - 20354, 20359, 20365, 20371, 20378, 20388, 20396, 20403, 20408, 20412, - 20421, 20429, 20436, 20443, 20449, 20454, 20460, 20465, 20470, 20476, - 20481, 20487, 20492, 20498, 20504, 20511, 20517, 20522, 20527, 10713, - 20536, 20539, 20547, 20553, 20558, 20563, 20573, 20580, 20586, 20591, - 20596, 20602, 20607, 20613, 20618, 20624, 20631, 20637, 20643, 20648, - 20656, 20663, 20668, 20673, 20679, 20684, 20688, 20697, 20708, 20715, - 20722, 20730, 20737, 20744, 20749, 20754, 20760, 20765, 20773, 20779, - 20785, 20790, 20797, 20803, 20808, 20812, 20818, 20823, 20828, 20832, - 20837, 1321, 8762, 3112, 20841, 20845, 20849, 20853, 20857, 20861, 20864, - 20869, 20876, 20884, 20894, 20905, 20915, 20926, 20938, 20949, 20959, - 20970, 20982, 20993, 21005, 21018, 21030, 21041, 21051, 21062, 21074, - 21085, 21098, 21110, 21121, 21133, 21146, 21158, 21171, 21185, 21198, - 21210, 21221, 21231, 21242, 21254, 21265, 21277, 21290, 21302, 21313, - 21325, 21338, 21351, 21365, 21378, 21390, 21401, 21413, 21426, 21438, - 21451, 21465, 21478, 21490, 21503, 21517, 21530, 21544, 21558, 21571, - 21583, 21594, 21604, 17345, 21611, 21617, 21627, 21635, 21642, 21650, - 21660, 21669, 21682, 21687, 21692, 21700, 21707, 15839, 15848, 21714, - 21724, 21739, 21745, 21752, 21759, 21766, 21772, 21778, 21789, 21797, - 21805, 21815, 21825, 21834, 17350, 21843, 21849, 21855, 21864, 21872, - 21880, 21885, 21894, 21902, 21914, 21924, 21934, 21944, 21953, 21965, - 21975, 21985, 21996, 22003, 22008, 22015, 22027, 22039, 22051, 22063, - 22075, 22087, 22099, 22111, 22123, 22135, 22146, 22158, 22170, 22182, - 22194, 22206, 22218, 22230, 22242, 22254, 22266, 22277, 22289, 22301, - 22313, 22325, 22337, 22349, 22361, 22373, 22385, 22397, 22408, 22420, - 22432, 22444, 22456, 22468, 22480, 22492, 22504, 22516, 22528, 22539, + 16111, 16119, 16126, 16134, 16146, 16158, 16169, 16179, 16186, 16192, + 16201, 16212, 16221, 16233, 16245, 16257, 16267, 16276, 16286, 16295, + 16303, 16310, 16320, 16329, 16337, 16341, 16346, 16352, 16358, 16363, + 16368, 16372, 16377, 16382, 16387, 16392, 16397, 16402, 16407, 8738, + 16412, 16414, 16418, 16423, 16429, 16436, 16442, 16448, 16457, 16461, + 16467, 16475, 16482, 16491, 16500, 16509, 16518, 16527, 16536, 16545, + 16554, 16564, 16574, 16583, 16589, 16596, 16603, 16609, 16623, 16629, + 16636, 16644, 16653, 16661, 16667, 16676, 16682, 16691, 16702, 16708, + 16718, 16726, 16733, 16741, 16749, 16756, 16765, 16778, 16787, 16795, + 16802, 16815, 16821, 16827, 16837, 16846, 16855, 16864, 16872, 16877, + 16881, 16887, 16893, 16898, 16905, 16912, 10242, 16917, 16922, 16929, + 16937, 16942, 16954, 16961, 16966, 16978, 14943, 16983, 16989, 16997, + 17003, 17008, 17016, 17024, 17031, 17039, 17046, 17052, 17058, 17066, + 17074, 17080, 17088, 17094, 17099, 17105, 17112, 17118, 17123, 17127, + 17138, 17146, 17154, 17160, 17165, 17172, 17181, 17187, 17192, 17200, + 17207, 17216, 17230, 4413, 17234, 17239, 17244, 17250, 17255, 17260, + 17264, 17269, 17274, 17279, 8737, 17284, 17289, 17294, 17299, 17304, + 17308, 17313, 17318, 17323, 17328, 17334, 17340, 14216, 17345, 17351, + 17356, 17361, 17366, 10643, 17371, 17376, 17381, 17386, 17391, 17405, + 17422, 17440, 17452, 17465, 17482, 17498, 17515, 17525, 17544, 17555, + 17566, 17577, 2803, 17588, 17599, 17610, 17627, 17638, 17649, 17654, + 10648, 17659, 17663, 2483, 17667, 17673, 17676, 17682, 17690, 17698, + 17704, 17713, 17720, 17725, 17733, 17741, 17748, 17752, 17757, 17763, + 17770, 17778, 17785, 17797, 17804, 17810, 17818, 17823, 17829, 17835, + 17840, 13971, 17847, 17851, 17860, 17866, 17871, 17879, 17888, 17896, + 17903, 17909, 17917, 17924, 17930, 17936, 17943, 17950, 17956, 17962, + 17966, 17975, 17983, 17988, 17998, 18005, 18011, 18019, 18025, 18033, + 18041, 18048, 18061, 18065, 18072, 18081, 18090, 18099, 18107, 18117, + 18124, 18129, 3969, 18136, 18141, 1248, 18145, 18152, 17285, 18156, + 18162, 18166, 18174, 18186, 18191, 18198, 18204, 18209, 18216, 17290, + 18220, 18224, 18232, 18237, 18241, 17295, 18245, 17300, 18249, 18256, + 18261, 18265, 18272, 18276, 18279, 18287, 18294, 18299, 18307, 18311, + 18318, 18335, 18344, 18353, 18357, 18360, 18366, 18374, 18380, 18385, + 18389, 18394, 18399, 18404, 18409, 18414, 18419, 4047, 18424, 18426, + 18434, 18441, 18451, 18463, 18468, 18472, 18478, 18483, 18491, 18495, + 18501, 18506, 18512, 18515, 18522, 18530, 18537, 18543, 18548, 18554, + 18559, 18566, 18572, 18577, 18587, 18596, 18603, 18608, 18612, 18618, + 18624, 18628, 18635, 18641, 18646, 18652, 18660, 18668, 18675, 18681, + 18687, 18692, 18698, 18704, 18712, 18717, 18722, 18730, 18736, 18742, + 18747, 18754, 18759, 18763, 18769, 18775, 18780, 18786, 18793, 18798, + 18804, 18807, 18813, 18824, 18830, 18839, 18842, 18846, 18850, 18864, + 18877, 18889, 18895, 18900, 18907, 18913, 18919, 18930, 18942, 18954, + 18964, 18973, 18981, 18988, 18999, 19009, 19019, 19027, 19030, 17314, + 19035, 19040, 19047, 17319, 17470, 19055, 19068, 19083, 19094, 17487, + 19112, 19125, 19138, 19149, 12546, 19160, 19173, 19192, 19203, 19214, + 19225, 2824, 19238, 19242, 19250, 19261, 19272, 19280, 19295, 19310, + 19321, 19328, 19334, 19342, 19346, 19352, 19356, 19359, 19372, 19384, + 19394, 19402, 19409, 19417, 19427, 19432, 19439, 19444, 19451, 19462, + 19472, 19478, 19483, 19488, 17324, 19492, 19498, 19505, 19511, 19516, + 19521, 19526, 19530, 17329, 17335, 19534, 17341, 19539, 19547, 19552, + 19556, 19563, 19571, 19578, 19587, 19594, 19598, 19602, 19607, 19612, + 19617, 19622, 19627, 10487, 19632, 19634, 19639, 19644, 19650, 19655, + 19660, 19665, 19670, 19674, 19680, 19686, 19691, 19697, 19702, 19707, + 19711, 19717, 19722, 19726, 19731, 19736, 19748, 19753, 19759, 19764, + 19769, 19775, 19781, 19786, 19791, 19796, 19803, 19809, 19820, 19827, + 19836, 19841, 19845, 279, 19849, 19857, 19862, 19868, 19874, 19879, + 19886, 19893, 19899, 19904, 19910, 19915, 19920, 19925, 19932, 19942, + 19950, 19955, 19960, 19967, 19973, 19982, 19992, 20002, 20016, 20030, + 20044, 20058, 20073, 20088, 20105, 20123, 20136, 20142, 20147, 20152, + 20156, 20164, 20169, 20177, 20183, 20189, 20194, 20199, 20203, 20209, + 20214, 20218, 20225, 20230, 20234, 20245, 20251, 20256, 20261, 20268, + 20273, 20277, 3927, 20282, 20288, 20295, 17346, 20301, 20305, 20311, + 20316, 20321, 20325, 20331, 20336, 20341, 20348, 20353, 15730, 20357, + 20362, 20366, 20371, 20377, 20383, 20390, 20400, 20408, 20415, 20420, + 20424, 20433, 20441, 20448, 20455, 20461, 20466, 20472, 20477, 20482, + 20488, 20493, 20499, 20504, 20510, 20516, 20523, 20529, 20534, 20539, + 10713, 20548, 20551, 20559, 20565, 20570, 20575, 20585, 20592, 20598, + 20603, 20608, 20614, 20619, 20625, 20630, 20636, 20643, 20649, 20655, + 20660, 20668, 20675, 20680, 20685, 20691, 20696, 20700, 20709, 20720, + 20727, 20734, 20742, 20749, 20756, 20761, 20766, 20772, 20777, 20785, + 20791, 20797, 20802, 20809, 20815, 20820, 20824, 20830, 20835, 20840, + 20844, 20849, 1321, 8762, 3112, 20853, 20857, 20861, 20865, 20869, 20873, + 20876, 20881, 20888, 20896, 20906, 20917, 20927, 20938, 20950, 20961, + 20971, 20982, 20994, 21005, 21017, 21030, 21042, 21053, 21063, 21074, + 21086, 21097, 21110, 21122, 21133, 21145, 21158, 21170, 21183, 21197, + 21210, 21222, 21233, 21243, 21254, 21266, 21277, 21289, 21302, 21314, + 21325, 21337, 21350, 21363, 21377, 21390, 21402, 21413, 21425, 21438, + 21450, 21463, 21477, 21490, 21502, 21515, 21529, 21542, 21556, 21570, + 21583, 21595, 21606, 21616, 17357, 21623, 21629, 21639, 21647, 21654, + 21662, 21672, 21681, 21694, 21699, 21704, 21712, 21719, 15839, 15848, + 21726, 21736, 21751, 21757, 21764, 21771, 21778, 21784, 21790, 21801, + 21809, 21817, 21827, 21837, 21846, 17362, 21855, 21861, 21867, 21876, + 21884, 21892, 21897, 21906, 21914, 21926, 21936, 21946, 21956, 21965, + 21977, 21987, 21997, 22008, 22015, 22020, 22027, 22039, 22051, 22063, + 22075, 22087, 22099, 22111, 22123, 22135, 22147, 22158, 22170, 22182, + 22194, 22206, 22218, 22230, 22242, 22254, 22266, 22278, 22289, 22301, + 22313, 22325, 22337, 22349, 22361, 22373, 22385, 22397, 22409, 22420, + 22432, 22444, 22456, 22468, 22480, 22492, 22504, 22516, 22528, 22540, 22551, 22563, 22575, 22587, 22599, 22611, 22623, 22635, 22647, 22659, - 22670, 22682, 22694, 22706, 22718, 22730, 22742, 22754, 22766, 22778, - 22790, 22801, 22813, 22825, 22837, 22849, 22861, 22873, 22885, 22897, - 22909, 22921, 22932, 22944, 22956, 22968, 22980, 22993, 23006, 23019, - 23032, 23045, 23058, 23071, 23083, 23096, 23109, 23122, 23135, 23148, - 23161, 23174, 23187, 23200, 23213, 23225, 23238, 23251, 23264, 23277, - 23290, 23303, 23316, 23329, 23342, 23355, 23367, 23380, 23393, 23406, - 23419, 23432, 23445, 23458, 23471, 23484, 23497, 23509, 23522, 23535, - 23548, 23561, 23574, 23587, 23600, 23613, 23626, 23639, 23651, 23664, - 23677, 23690, 23703, 23716, 23729, 23742, 23755, 23768, 23781, 23793, - 23804, 23817, 23830, 23843, 23856, 23869, 23882, 23895, 23908, 23921, - 23934, 23946, 23959, 23972, 23985, 23998, 24011, 24024, 24037, 24050, - 24063, 24076, 24088, 24101, 24114, 24127, 24140, 24153, 24166, 24179, - 24192, 24205, 24218, 24230, 24243, 24256, 24269, 24282, 24295, 24308, - 24321, 24334, 24347, 24360, 24372, 24385, 24398, 24411, 24424, 24437, - 24450, 24463, 24476, 24489, 24502, 24514, 24527, 24540, 24553, 24566, - 24579, 24592, 24605, 24618, 24631, 24644, 24656, 24669, 24682, 24695, - 24708, 24721, 24734, 24747, 24760, 24773, 24786, 24798, 24811, 24824, - 24837, 24850, 24863, 24876, 24889, 24902, 24915, 24928, 24940, 24953, - 24966, 24979, 24992, 25005, 25018, 25031, 25044, 25057, 25070, 25082, - 25095, 25108, 25121, 25134, 25147, 25160, 25173, 25186, 25199, 25212, - 25224, 25235, 25244, 25252, 25260, 25267, 25273, 25277, 25283, 25289, - 25298, 25306, 25311, 25317, 25322, 25326, 25335, 10492, 25346, 25352, - 25359, 25367, 25374, 13145, 13159, 25381, 25388, 25397, 25402, 25407, - 25414, 25419, 25424, 8778, 8784, 8790, 25429, 25434, 25437, 25442, 25450, - 25457, 25464, 25476, 25483, 25489, 25498, 25503, 25512, 25521, 25527, - 25535, 25544, 25548, 25554, 25559, 25569, 25576, 25582, 25590, 25596, - 25603, 25609, 25619, 25628, 25632, 25639, 25643, 25648, 25654, 25662, - 25666, 25676, 17360, 25685, 25691, 25695, 25704, 25713, 25723, 25729, - 17365, 25736, 25743, 25754, 25762, 25772, 25781, 25789, 10207, 25797, - 25802, 25808, 25813, 25817, 25821, 25825, 11301, 25830, 25838, 25845, - 25854, 25862, 25869, 25876, 25885, 25891, 1062, 25898, 25904, 25908, - 25914, 25921, 25927, 25935, 25941, 25948, 25954, 25960, 25969, 25973, - 25981, 25989, 25996, 26005, 26012, 26017, 26021, 26031, 26042, 26053, - 26058, 26063, 26069, 26078, 26083, 26096, 9000, 26100, 26106, 26112, - 26118, 26123, 26131, 26135, 26142, 26151, 26156, 17638, 26164, 26168, - 26180, 26185, 26189, 26192, 26198, 26204, 26210, 26215, 26220, 26224, - 26227, 26238, 26243, 10769, 26250, 26255, 26260, 26265, 26270, 26275, - 26280, 26285, 26290, 10774, 26295, 26300, 26305, 26310, 26315, 26320, - 26325, 26330, 26335, 26340, 26345, 26350, 26356, 26361, 26366, 26371, - 26376, 26381, 26386, 26391, 26396, 26401, 26407, 26413, 26418, 26423, - 26428, 26433, 26438, 26443, 26448, 26453, 26458, 26464, 26469, 26474, - 26479, 26485, 26491, 26496, 26501, 26506, 26511, 26516, 26521, 26526, - 26531, 26537, 26542, 26547, 26552, 26557, 26563, 26568, 26573, 26577, - 1244, 145, 26585, 26589, 26593, 26597, 26602, 26606, 15736, 2409, 26610, - 26615, 26619, 26624, 26628, 26633, 26637, 26643, 26648, 26652, 26656, - 26664, 26668, 26672, 26679, 26684, 26689, 26693, 26699, 26704, 26708, - 26713, 26718, 26722, 26729, 26736, 26743, 26748, 26752, 26756, 26761, - 26765, 26768, 26774, 26787, 26792, 26798, 26807, 26812, 11049, 26817, - 26826, 26831, 26834, 26838, 26843, 26848, 26853, 26858, 26863, 2920, - 2925, 26868, 26874, 26878, 26884, 3888, 26889, 26894, 26899, 26905, - 26910, 16686, 26915, 26920, 26925, 26930, 26936, 26941, 26946, 26952, - 26957, 26961, 26966, 26971, 26976, 26981, 26986, 26990, 26995, 26999, - 27004, 27009, 27014, 27019, 27023, 27028, 27032, 27037, 27042, 27047, - 26962, 3121, 26967, 27052, 27060, 27067, 11395, 27079, 27087, 27097, - 27115, 27134, 27143, 27151, 26972, 27158, 27163, 27171, 26977, 27176, - 27181, 27189, 27194, 27199, 27203, 19858, 27208, 27216, 27221, 27225, - 27232, 27238, 27247, 27251, 27259, 27265, 27269, 27272, 20692, 27279, - 27283, 27287, 27292, 27298, 27305, 27310, 10234, 27314, 27319, 27324, - 27329, 27334, 27339, 1663, 1668, 27344, 27350, 27356, 27361, 27365, - 27369, 27373, 27377, 27381, 27385, 27389, 27393, 25470, 27396, 27403, - 27411, 27417, 27423, 27428, 27433, 27439, 27443, 27448, 27455, 16586, - 16593, 27461, 27473, 27476, 27483, 27487, 19883, 27494, 27502, 27513, - 27522, 27535, 27545, 27559, 27571, 27585, 27598, 27610, 27620, 27632, - 27638, 27653, 27677, 27695, 27714, 27727, 27741, 27759, 27775, 27792, - 27810, 27821, 27840, 27857, 27877, 27895, 27907, 27921, 27935, 27947, - 27964, 27983, 28001, 28013, 28031, 28050, 17518, 28063, 28083, 28095, - 12577, 28107, 28112, 28117, 28122, 28131, 28137, 28142, 28146, 28153, - 28159, 28163, 28168, 28173, 28178, 28183, 28188, 28193, 2506, 28198, - 28204, 28208, 28211, 28222, 28226, 28229, 28237, 28243, 14882, 28247, - 28256, 28267, 28273, 28279, 28294, 28303, 28311, 28318, 28323, 28327, - 28334, 28340, 28349, 28357, 28364, 28374, 28383, 28393, 28398, 28407, - 28416, 28427, 28438, 28448, 28465, 4557, 28475, 28479, 28489, 28497, - 28507, 28518, 28524, 28529, 28539, 28547, 28554, 28560, 28567, 28572, - 27010, 28576, 28585, 28589, 28592, 28597, 28605, 28612, 28621, 28629, - 28637, 28645, 28655, 28664, 28670, 28676, 28682, 28686, 27015, 27020, - 28690, 28700, 28710, 28720, 28728, 28735, 28745, 28753, 28761, 28767, - 28775, 798, 28784, 17725, 649, 28798, 28807, 28815, 28826, 28837, 28847, - 28856, 28868, 28877, 28886, 28893, 28899, 28909, 28918, 28927, 28935, - 28943, 28953, 28961, 28969, 28976, 28982, 28987, 28992, 28997, 8156, - 29002, 29005, 29009, 29014, 29022, 29028, 29033, 29037, 3751, 27033, - 29045, 27038, 29051, 29057, 29063, 29068, 29073, 29077, 29085, 29091, - 29097, 29101, 3912, 29109, 29114, 29119, 29123, 29127, 11681, 29134, - 29142, 29156, 29163, 29170, 29176, 11690, 11696, 29184, 29192, 29199, - 29204, 29209, 27043, 29215, 29226, 29235, 19031, 29243, 29248, 2755, - 29253, 29264, 29270, 29275, 29279, 29283, 29286, 29293, 29300, 29306, - 29314, 29321, 29327, 29331, 8196, 29336, 29340, 29344, 29352, 29357, - 29362, 29367, 1696, 29372, 29377, 29382, 29387, 29392, 29397, 29402, - 29407, 29412, 29417, 29422, 29427, 29432, 29437, 29443, 29448, 29453, - 29458, 29463, 29468, 29473, 29479, 29484, 29489, 29494, 29499, 29504, - 29509, 29514, 29520, 29526, 29531, 29537, 29542, 29547, 5, 29553, 29557, - 29561, 29565, 29570, 29574, 29578, 29582, 29586, 29591, 29595, 29600, - 29604, 29607, 29611, 29616, 29620, 29625, 29629, 29633, 29637, 29642, - 29646, 29650, 29660, 29665, 29669, 29673, 29678, 29683, 29692, 29697, - 29702, 29706, 29710, 29719, 29732, 29744, 29753, 29762, 29767, 29773, - 29778, 29782, 29786, 29796, 29805, 29813, 29819, 29824, 29828, 29835, - 29842, 29852, 29861, 29869, 12934, 29877, 29884, 29892, 29901, 29910, - 29918, 29928, 29933, 29937, 29941, 29944, 29946, 29950, 29954, 29959, - 29964, 29968, 29972, 29975, 29979, 29982, 29986, 29989, 29992, 29996, - 30002, 30006, 30010, 30014, 30018, 30023, 30028, 30033, 30037, 30040, - 30045, 30051, 30056, 30062, 30067, 30071, 30077, 30081, 30085, 30090, - 30094, 30099, 30104, 30108, 30112, 30119, 30123, 30126, 30130, 30134, - 30140, 30145, 30151, 30155, 30159, 30164, 30171, 30177, 30181, 30190, - 30194, 30198, 30201, 30207, 30212, 30218, 1385, 1748, 30223, 30228, - 30233, 30238, 30243, 30248, 30253, 2213, 827, 30258, 30261, 30265, 30269, - 30274, 30278, 17737, 30282, 30287, 30292, 30296, 30299, 30304, 30308, - 30313, 30317, 17741, 30322, 30325, 30328, 30334, 30338, 30343, 30347, - 30360, 30368, 30372, 30375, 30383, 30392, 30399, 30404, 30410, 30416, - 30424, 30431, 30438, 30442, 30446, 30450, 30455, 30460, 30464, 30472, - 30477, 30484, 30496, 30507, 30512, 30516, 30523, 30527, 30532, 30538, - 30541, 30546, 30551, 30558, 30562, 30566, 30569, 30575, 8900, 2413, - 30579, 30584, 30600, 11100, 30620, 30629, 30645, 30649, 30656, 30659, - 30665, 30675, 30681, 30690, 30699, 30714, 30725, 30737, 30748, 30756, - 30765, 30771, 30780, 30790, 30800, 30811, 30822, 30832, 30841, 30848, - 30857, 30865, 30872, 30879, 30886, 30894, 30901, 30908, 30921, 30928, - 30936, 30943, 30949, 30954, 30963, 30970, 30976, 30981, 30989, 30997, - 31004, 31011, 28499, 31023, 31035, 31049, 31057, 31065, 31073, 31080, - 31092, 31101, 31110, 31118, 31126, 31134, 31141, 31147, 31156, 31164, - 31174, 31183, 31193, 31202, 31211, 31219, 31224, 31228, 31231, 31235, - 31239, 31243, 31247, 31251, 31257, 31263, 31268, 31276, 31283, 31291, - 31298, 10806, 17799, 31306, 31313, 31318, 31325, 31331, 31337, 31344, - 14024, 31351, 31354, 31366, 31374, 31380, 31385, 31389, 31400, 31410, - 31420, 11620, 31429, 31438, 31446, 31456, 31465, 31472, 31479, 31487, - 31491, 17818, 31494, 31501, 31505, 4501, 31511, 31514, 31521, 31527, - 31541, 31546, 31554, 31560, 31571, 31578, 31584, 31590, 31594, 31599, - 31603, 31612, 31619, 31625, 8953, 31632, 31640, 31647, 31653, 31658, - 31664, 31670, 31680, 31692, 31703, 31713, 11252, 31721, 31727, 17836, - 31731, 31733, 31236, 11633, 31742, 31747, 31753, 31763, 31768, 31775, - 31783, 31789, 31794, 31799, 31804, 31808, 31813, 31820, 31826, 31835, - 31843, 31847, 31854, 31864, 31870, 31879, 31885, 31892, 4771, 31898, - 31904, 31909, 31916, 31928, 31939, 31944, 31952, 31956, 31966, 31972, - 31976, 31981, 31991, 32000, 32004, 32011, 32019, 32026, 32032, 32037, - 32045, 32052, 32057, 32064, 32076, 32085, 32089, 32097, 15656, 32101, - 32111, 32115, 32123, 32130, 32137, 30379, 32148, 32153, 32157, 32164, - 32171, 26695, 31161, 32176, 32180, 32183, 27827, 32188, 32202, 32218, - 32236, 32255, 32272, 32290, 27846, 32307, 32327, 27863, 32339, 32351, - 19087, 32363, 27883, 32377, 32389, 12590, 32403, 32408, 32413, 32418, - 32424, 32430, 32436, 32440, 32448, 32454, 32461, 32466, 32476, 32483, - 32489, 12128, 32495, 32497, 32502, 32510, 32514, 31816, 32520, 32527, - 13866, 13876, 32534, 32541, 32551, 32556, 32560, 32563, 32569, 32577, - 32589, 32599, 32615, 32628, 32642, 19105, 32656, 32663, 32667, 32670, - 32675, 32679, 32686, 32693, 32700, 32707, 32717, 32722, 32727, 32732, - 32740, 32748, 32753, 32762, 28520, 3561, 32767, 32770, 32773, 32778, - 32785, 32790, 32795, 32811, 32819, 32827, 10864, 32835, 32840, 32844, - 32850, 32855, 32861, 32864, 32870, 32882, 32890, 32897, 32903, 32910, - 32921, 32935, 32948, 32954, 32963, 32969, 32978, 32990, 33001, 33011, - 33020, 33029, 33037, 33047, 33056, 33067, 673, 33074, 33081, 33087, - 33092, 33098, 33105, 33111, 33122, 33132, 33142, 33151, 33157, 33164, - 33169, 33177, 33184, 33192, 33200, 33212, 7142, 33219, 33222, 33231, - 33239, 33245, 33251, 33256, 33260, 33263, 33269, 33276, 33281, 33286, - 33293, 33298, 33302, 33314, 33325, 33334, 33342, 18008, 33347, 33355, - 33360, 33368, 33374, 33380, 33385, 13859, 9802, 33388, 33392, 33396, - 33399, 33402, 33408, 33416, 33424, 33428, 33432, 33437, 33441, 33444, - 33453, 33458, 33463, 33467, 33470, 33475, 33483, 33494, 33503, 33507, - 33513, 33519, 33523, 33529, 33537, 33559, 33583, 33594, 33603, 33609, - 33616, 33623, 33629, 33637, 33643, 33648, 33659, 33677, 33684, 33692, - 33696, 33703, 33708, 33717, 33730, 33738, 33750, 33761, 33772, 33782, - 33796, 33805, 33813, 33825, 33836, 11117, 33845, 33856, 33867, 33879, - 33889, 33898, 33908, 33913, 33917, 33925, 33936, 33946, 33952, 33957, - 33961, 33964, 33967, 33975, 33983, 33992, 34002, 34011, 34017, 34022, - 34036, 2838, 34058, 34069, 34078, 34088, 34100, 34109, 34118, 34128, - 34136, 34144, 34153, 34158, 34169, 34174, 34183, 34189, 34200, 34204, - 34207, 34217, 34226, 34234, 34244, 34254, 34262, 34271, 34278, 34284, - 34292, 34299, 34308, 34317, 34322, 34327, 34331, 34339, 34346, 34352, - 34356, 34364, 34371, 34382, 34397, 34404, 34410, 34420, 34429, 34435, - 34446, 34450, 34457, 34461, 34468, 34474, 16838, 34480, 34484, 34489, - 34495, 34502, 34506, 34510, 34518, 34526, 34532, 34541, 34548, 34555, - 34560, 34565, 34575, 28574, 34579, 34582, 34587, 34592, 34597, 34602, - 34607, 34612, 34617, 34622, 34628, 34633, 34638, 34644, 1094, 770, 34649, - 34652, 34659, 34668, 1777, 34675, 34680, 34684, 34690, 1143, 643, 34695, - 347, 34699, 34709, 34718, 34726, 34735, 34743, 34750, 34761, 34769, - 34778, 34786, 34796, 34804, 34809, 11794, 34813, 34821, 34829, 34834, - 17754, 4101, 34840, 34846, 34852, 6669, 34857, 34861, 34868, 34874, - 34880, 34884, 34893, 34899, 34904, 34911, 1336, 34917, 34923, 34928, - 34935, 34939, 1243, 6677, 34944, 34954, 34962, 34968, 34978, 34987, - 34995, 35001, 35006, 35014, 35021, 13376, 35027, 35034, 35039, 35045, - 35052, 35062, 1404, 253, 2212, 35068, 35074, 35081, 35092, 35103, 35111, - 35118, 35128, 35137, 35145, 35154, 35161, 35168, 35181, 35188, 35194, - 35205, 35224, 35229, 1148, 35233, 35238, 35246, 3984, 35250, 35255, - 35259, 35263, 1340, 29973, 35273, 35277, 35282, 35286, 35292, 3846, - 35298, 35306, 35313, 35324, 35333, 35341, 35366, 35374, 35379, 3985, 401, - 35385, 35393, 35401, 35408, 35413, 35419, 35424, 2281, 12792, 35431, - 35437, 31595, 31934, 35443, 656, 106, 35447, 35451, 35457, 595, 10679, - 35462, 35467, 35474, 35480, 35484, 35488, 1549, 35491, 35495, 18296, - 35498, 35503, 35510, 35516, 8966, 35521, 35529, 35536, 35542, 27205, - 35546, 35550, 35554, 35558, 1834, 20204, 35562, 35567, 35571, 35574, - 35582, 35590, 35595, 35604, 35612, 35615, 35622, 35629, 35641, 27284, - 35651, 35663, 35671, 35676, 35680, 35688, 35695, 35702, 35711, 35717, - 35724, 35731, 35734, 35738, 35742, 1351, 35752, 35754, 35759, 35765, - 35771, 35776, 35781, 35786, 35791, 35796, 35801, 35806, 35811, 35816, - 35821, 35826, 35831, 35836, 35841, 35847, 35853, 35859, 35865, 35870, - 35875, 35880, 35886, 35891, 35896, 35901, 35907, 35912, 35918, 35923, - 35928, 35933, 35938, 35944, 35949, 35955, 35960, 35965, 35970, 35975, - 35981, 35986, 35992, 35997, 36002, 36007, 36012, 36017, 36022, 36027, - 36032, 36037, 36043, 36049, 36055, 36060, 36065, 36070, 36075, 36081, - 36087, 36093, 36099, 36105, 36111, 36116, 36122, 36127, 36132, 36137, - 36142, 36148, 2552, 36153, 2559, 2566, 2962, 36158, 2572, 2582, 36164, - 2614, 2619, 2624, 36168, 36173, 36178, 36184, 36189, 36194, 36198, 36203, - 36209, 36214, 36219, 36224, 36230, 36235, 36239, 36243, 36248, 36253, - 36258, 36263, 36268, 36274, 36280, 36285, 36289, 36294, 36300, 36304, - 36309, 36314, 36319, 36324, 36328, 36331, 36336, 36341, 36346, 36351, - 36356, 36362, 36368, 36373, 36378, 36383, 36387, 36392, 36397, 36402, - 36407, 36412, 36417, 36421, 36426, 36431, 36436, 36440, 36444, 36448, - 36453, 36461, 36466, 36471, 36477, 36483, 36489, 36494, 36502, 36506, - 36509, 36514, 36519, 36523, 36528, 36533, 36537, 36542, 36546, 36549, - 36554, 4211, 21695, 36559, 36564, 36569, 36574, 36582, 25865, 34932, - 10318, 36587, 36592, 36596, 36601, 36605, 36609, 36614, 36618, 36621, - 36624, 36628, 36633, 36637, 36645, 36649, 36652, 36657, 36661, 36665, - 36670, 36675, 36679, 36685, 36690, 36695, 36702, 36709, 36713, 36716, - 36722, 36731, 36738, 36746, 36753, 36757, 36762, 36766, 36770, 36776, - 36781, 36787, 36791, 36797, 36802, 36807, 36811, 36818, 36824, 36830, - 36836, 36842, 36849, 36855, 36861, 36867, 36873, 36879, 36885, 36891, - 36898, 36904, 36911, 36917, 36923, 36929, 36935, 36941, 36947, 36953, - 36959, 36965, 36971, 36976, 36981, 13731, 36986, 36992, 36997, 37002, - 37007, 37012, 37015, 37021, 37026, 37034, 37039, 37043, 37048, 37054, - 37063, 37069, 37074, 37079, 37084, 37088, 37093, 37097, 37102, 37107, - 37112, 37117, 37124, 37131, 37137, 37143, 37148, 19801, 37155, 37161, - 37168, 37174, 37180, 37185, 37193, 37198, 11288, 37202, 37207, 37212, - 37218, 37223, 37228, 37232, 37237, 37242, 37248, 37253, 37258, 37263, - 37267, 37272, 37277, 37281, 37286, 37291, 37295, 37300, 37304, 37309, - 37314, 37319, 37323, 37328, 37332, 37337, 37341, 37348, 37352, 37356, - 18452, 37361, 37368, 37377, 37383, 37389, 37398, 37406, 37415, 37423, - 37428, 37432, 37439, 37445, 37453, 37457, 37460, 37465, 37469, 37478, - 37486, 37504, 37510, 1403, 37516, 37519, 37523, 27351, 27357, 37529, - 37533, 37544, 37555, 37566, 37578, 37582, 37589, 37596, 37603, 37608, - 37612, 37620, 37625, 37630, 37635, 37640, 6734, 16742, 25864, 37645, - 37650, 37654, 16733, 37659, 37665, 37670, 37676, 37681, 37687, 37692, - 37698, 37703, 37709, 37715, 37721, 37726, 37682, 37688, 37730, 37735, - 37741, 37746, 37752, 37757, 37763, 37768, 37693, 12422, 37772, 37704, - 37710, 37716, 3054, 3760, 37778, 37781, 37786, 37792, 37798, 37804, - 37811, 37817, 37823, 37829, 37835, 37841, 37847, 37853, 37859, 37865, - 37871, 37877, 37883, 37890, 37896, 37902, 37908, 37914, 37920, 37923, - 37928, 37931, 37938, 37943, 37951, 37955, 37960, 37965, 37971, 37976, - 37981, 37985, 37990, 37996, 38001, 38007, 38012, 38018, 38023, 38029, - 38035, 38039, 38044, 38049, 38054, 38059, 38063, 38068, 38073, 38078, - 38084, 38090, 38096, 38102, 38107, 38111, 38114, 38120, 38126, 38135, - 38143, 38150, 38155, 38159, 38163, 38168, 18239, 38173, 38181, 38187, - 4152, 1253, 38192, 38197, 38201, 9016, 38207, 38213, 38220, 9025, 38224, - 38230, 38236, 38243, 38249, 38258, 38266, 38278, 38287, 38291, 38298, - 38304, 38309, 38313, 38317, 38320, 38330, 38339, 38347, 37683, 38352, - 38362, 38372, 38382, 38388, 38393, 38403, 38408, 38421, 38435, 38446, - 38458, 38470, 38484, 38497, 38509, 38521, 17559, 38535, 38540, 38545, - 38549, 38553, 38557, 38561, 38567, 38572, 38577, 38582, 38587, 38592, - 38597, 1737, 32999, 38602, 38607, 38612, 37731, 38617, 38620, 38625, - 38630, 38635, 38641, 38647, 19411, 11994, 38652, 38658, 38665, 19039, - 38671, 38676, 38681, 38685, 38690, 38695, 37736, 38700, 38705, 38710, - 38716, 37742, 38721, 38724, 38731, 38739, 38745, 38751, 38757, 38768, - 38773, 38780, 38787, 38794, 38802, 38811, 38820, 38826, 38832, 38840, - 37747, 38845, 38851, 38857, 37753, 38862, 38867, 38875, 38883, 38889, - 38896, 38902, 38909, 38916, 38922, 38930, 38940, 38947, 38953, 38958, - 38964, 38969, 38974, 38981, 38990, 38998, 39003, 39009, 39016, 39024, - 39030, 39035, 39041, 39050, 39057, 33997, 39063, 39067, 39072, 39081, - 39086, 39091, 39096, 14972, 39104, 39109, 39114, 39119, 39123, 39128, - 39133, 39140, 39145, 39150, 39155, 37758, 25793, 39161, 2655, 158, 39164, - 39167, 39171, 39175, 39185, 39193, 39200, 39204, 39208, 39211, 39219, - 39226, 39233, 31888, 39242, 39245, 39252, 39258, 39263, 39267, 39274, - 39278, 39286, 39294, 39301, 39316, 39320, 39324, 39327, 39333, 39340, - 39344, 39350, 39354, 39361, 39369, 39377, 39384, 37694, 39391, 39399, - 39404, 39416, 12075, 12082, 12089, 12096, 12103, 12110, 626, 434, 39422, - 39427, 39432, 39438, 39443, 39448, 4178, 39453, 39456, 39461, 39466, - 39471, 39476, 39481, 39488, 27469, 39493, 39498, 39503, 39508, 39513, - 39519, 39524, 39530, 37934, 39536, 39541, 39547, 39553, 39563, 39568, - 39573, 39577, 39582, 39587, 39592, 39597, 39610, 39615, 27083, 20286, - 1064, 39619, 39625, 39629, 39634, 39639, 39645, 39650, 39655, 39659, - 39664, 39669, 39675, 39680, 39685, 1258, 39689, 39694, 39699, 39704, - 39708, 39713, 39718, 39723, 39729, 39735, 39740, 39744, 39748, 39753, - 39758, 39763, 39767, 39772, 39780, 39784, 39790, 39794, 39801, 39810, - 20057, 37705, 39816, 39823, 39831, 39839, 39846, 39852, 39861, 39874, - 39886, 39891, 39897, 39901, 2981, 39905, 39909, 39335, 39918, 39929, - 39940, 39945, 34065, 39950, 39955, 39959, 34185, 27362, 39964, 39971, - 39975, 39980, 37711, 25900, 39984, 39989, 39995, 40000, 40004, 40008, - 40011, 40015, 40021, 40030, 40041, 40053, 37717, 40058, 40061, 40065, - 40069, 40074, 40079, 40084, 40089, 40094, 40099, 40104, 40109, 373, - 40114, 40119, 40124, 40129, 40134, 40139, 40145, 40150, 40155, 40161, - 40166, 40172, 40177, 40183, 40188, 40193, 40198, 40203, 40208, 40213, - 40218, 40223, 40229, 40234, 40239, 40244, 40249, 40254, 40259, 40264, - 40270, 40276, 40281, 40286, 40291, 40296, 40301, 40306, 40311, 40316, - 40321, 40326, 40331, 40336, 40341, 40346, 40351, 40356, 40361, 40366, - 40376, 40386, 40392, 342, 14, 40397, 40400, 40404, 40408, 40416, 40420, - 40424, 31568, 16975, 1818, 40427, 40432, 40436, 40441, 40445, 40450, - 40454, 40459, 40463, 40466, 40468, 40472, 40477, 40481, 40492, 40495, - 40497, 40501, 40513, 40525, 40534, 40538, 40548, 40552, 40558, 40563, - 40572, 40578, 40583, 40588, 40592, 40596, 40601, 40608, 40613, 40619, - 40624, 40628, 40635, 31169, 31179, 40639, 40644, 40649, 40654, 40661, - 40665, 40672, 40679, 40685, 9171, 40689, 40698, 40706, 40721, 40735, - 40744, 40752, 40763, 40772, 40777, 40784, 40794, 8165, 40804, 40809, - 40815, 40820, 40824, 40827, 40832, 40836, 40841, 40845, 40852, 40857, - 40862, 40867, 40877, 40882, 40887, 40892, 10188, 40897, 40899, 40907, - 40910, 40913, 40921, 40936, 40944, 40954, 40956, 40959, 40963, 40969, - 40973, 40978, 40983, 41001, 41015, 41034, 41051, 41060, 41068, 41073, - 41078, 1396, 41084, 41090, 41095, 41105, 41114, 41122, 41127, 41133, - 41138, 41147, 41156, 41167, 41172, 41179, 41185, 41189, 41198, 41205, - 41213, 41220, 41233, 41241, 41245, 41255, 41261, 41266, 41270, 41278, - 41286, 41291, 41295, 41299, 41308, 41314, 41319, 41327, 41337, 41346, - 41355, 41364, 41375, 41383, 41394, 41403, 41411, 41418, 41424, 41429, - 41440, 41451, 41456, 41460, 41463, 41467, 41477, 41485, 41491, 41502, - 41513, 41524, 41535, 41546, 41557, 41568, 41579, 41591, 41603, 41615, - 41627, 41639, 41651, 41663, 41672, 41676, 41684, 41690, 41696, 41703, - 41709, 41714, 41720, 41724, 41729, 41734, 41739, 40371, 40381, 2526, - 41744, 41746, 41751, 41756, 41761, 41764, 41766, 41770, 41773, 41780, - 41784, 11644, 41788, 41794, 41801, 41807, 41817, 41822, 41828, 41832, - 41837, 41850, 31758, 41856, 41862, 41871, 41880, 21918, 41887, 41896, - 41904, 38368, 41910, 41915, 41919, 41928, 41936, 41943, 41948, 41952, - 41957, 41962, 41970, 41974, 41982, 41988, 41994, 41999, 42004, 42008, - 42011, 42016, 42029, 42045, 27953, 42062, 42074, 42091, 42103, 42117, - 27970, 27989, 42129, 42141, 2855, 42155, 42160, 42165, 42170, 42174, - 42181, 42193, 42200, 42209, 42219, 42222, 42233, 42244, 42252, 42257, - 42261, 42266, 42271, 42276, 42281, 42286, 42291, 1768, 947, 42296, 42300, - 42304, 42307, 42312, 42317, 42323, 42328, 42333, 42339, 42345, 42350, - 42354, 42359, 42364, 42369, 42373, 42376, 42382, 42387, 42392, 42397, - 42401, 42406, 42412, 42420, 32069, 42425, 42430, 42437, 42443, 42449, - 42454, 42462, 27478, 42469, 42474, 42479, 42484, 42488, 42491, 42496, - 42500, 42504, 42511, 42517, 42523, 42529, 42536, 42541, 42547, 41281, - 42551, 42555, 42560, 42573, 42578, 42584, 42592, 42599, 42607, 42617, - 42623, 42629, 42635, 42639, 42648, 42656, 42663, 42668, 42673, 12445, - 42678, 42688, 42695, 42701, 42711, 42716, 42722, 42730, 4017, 42737, - 42744, 42750, 42757, 4023, 42761, 42766, 42777, 42784, 42790, 42799, - 42803, 42806, 4609, 42813, 42820, 42826, 42832, 42840, 42850, 35414, - 42857, 42865, 42871, 42876, 42882, 42887, 42891, 31517, 42897, 42904, - 42910, 42918, 42927, 42934, 42940, 42951, 28772, 42957, 42964, 42970, - 42980, 42985, 42989, 42997, 43005, 43012, 43018, 43023, 11246, 941, - 43028, 43032, 43034, 43038, 43043, 43046, 43048, 43053, 43059, 43064, - 43069, 43076, 39484, 43082, 43087, 43091, 43096, 43100, 43109, 43113, - 43119, 43126, 43132, 43139, 43144, 43153, 43158, 43162, 43167, 43174, - 43182, 43190, 43195, 25956, 43199, 43202, 43206, 43210, 12889, 1005, - 43214, 43219, 43227, 43232, 43236, 43245, 43252, 43256, 43260, 43268, - 43275, 16260, 43285, 43289, 43293, 43301, 43309, 43315, 43320, 43324, - 43333, 16008, 43339, 43348, 43355, 43360, 43367, 43374, 43382, 43389, - 43397, 43405, 43414, 43419, 43426, 43433, 43440, 43447, 43454, 43459, - 43466, 43472, 43489, 43497, 43507, 43515, 43522, 43530, 461, 43534, - 43540, 43544, 43549, 40768, 43555, 43558, 43562, 43568, 43579, 43587, - 4028, 43595, 43601, 43607, 43617, 43623, 43632, 43641, 43651, 43658, - 43664, 43669, 4034, 4040, 43678, 43686, 43693, 43697, 14356, 43705, - 43709, 43716, 43724, 43731, 43740, 43747, 43753, 43762, 43772, 43778, - 43786, 43795, 43802, 43810, 43817, 26758, 43821, 43828, 43834, 43844, - 43853, 43861, 43872, 43876, 43886, 43893, 43898, 43903, 43909, 43916, - 43924, 43933, 43942, 43952, 43963, 43970, 43975, 43982, 3269, 43990, - 43996, 44001, 44008, 44014, 44020, 44025, 44038, 44051, 44064, 44071, - 44077, 44085, 44093, 44098, 44102, 44106, 44111, 44116, 44121, 44126, - 44131, 44136, 1365, 44141, 44145, 44149, 44153, 44157, 44161, 44165, - 44169, 44173, 44177, 44181, 44185, 44189, 44193, 44197, 44201, 44205, - 44209, 44213, 44217, 44221, 44225, 44229, 44233, 44237, 44241, 44245, - 44249, 44253, 44257, 44261, 44265, 44269, 44273, 44277, 44281, 44285, - 44289, 44293, 44297, 44301, 44305, 44309, 44313, 44317, 44321, 44325, - 44329, 44333, 44337, 44341, 44345, 44349, 44353, 44357, 44361, 44365, - 44369, 44373, 44377, 44381, 44385, 44389, 44393, 44397, 44401, 44405, - 44409, 44413, 44417, 44421, 44425, 44429, 44433, 44437, 44441, 44445, - 44449, 44453, 44457, 44461, 44465, 44469, 44473, 44477, 44481, 44485, - 44489, 44493, 44497, 44501, 44505, 44509, 44513, 44517, 44521, 44525, - 44529, 44533, 44537, 44541, 44545, 44549, 44553, 44557, 44561, 44565, - 44569, 44573, 44577, 44581, 44585, 44589, 44593, 44597, 44601, 44605, - 44609, 44613, 44617, 44621, 44625, 44629, 44633, 44637, 44641, 44645, - 44649, 44653, 44657, 44661, 44665, 44669, 44673, 44677, 44681, 44685, - 44689, 44693, 44697, 44701, 44705, 44709, 44713, 44717, 44721, 44725, - 44729, 44733, 44737, 44741, 44745, 44749, 44753, 44758, 44762, 44767, - 44771, 44776, 44780, 44785, 44789, 44795, 44800, 44804, 44809, 44813, - 44818, 44822, 44827, 44831, 44836, 44840, 44845, 44849, 44854, 44858, - 44864, 44870, 44875, 44879, 44884, 44888, 44894, 44899, 44903, 44908, - 44912, 44917, 44921, 44927, 44932, 44936, 44941, 44945, 44950, 44954, - 44959, 44963, 44969, 44974, 44978, 44983, 44987, 44993, 44998, 45002, - 45007, 45011, 45016, 45020, 45025, 45029, 45034, 45038, 45044, 45049, - 45053, 45059, 45064, 45068, 45074, 45079, 45083, 45088, 45092, 45097, - 45101, 45107, 45113, 45119, 45125, 45131, 45137, 45143, 45149, 45154, - 45158, 45163, 45167, 45173, 45178, 45182, 45187, 45191, 45196, 45200, - 45205, 45209, 45214, 45218, 45223, 45227, 45232, 45236, 45242, 45247, - 45251, 45256, 45260, 45266, 45272, 45277, 127, 63, 45281, 45283, 45287, - 45291, 45295, 45300, 45304, 45308, 45313, 11153, 45318, 45324, 1677, - 7181, 45330, 45333, 45338, 45342, 45347, 45351, 45355, 45360, 12233, - 45364, 45368, 45372, 630, 45376, 18561, 45381, 45385, 45390, 45395, - 45400, 45404, 45411, 45417, 45423, 31790, 45428, 45431, 45435, 45440, - 45446, 45450, 45453, 45461, 45467, 45472, 45476, 45479, 45483, 45489, - 45493, 45497, 3811, 3816, 15084, 45500, 45504, 45508, 45512, 45516, - 45524, 45531, 45535, 15958, 45542, 45556, 45563, 45574, 361, 45579, - 45583, 45589, 45601, 45607, 45613, 45618, 45624, 18613, 45628, 45632, - 35727, 45641, 45647, 45656, 45660, 45664, 45669, 45675, 45680, 45684, - 45689, 45693, 45697, 45704, 45710, 45715, 45726, 45741, 45756, 45771, - 45787, 45805, 12140, 45819, 45826, 45832, 45836, 45839, 45848, 45853, - 45857, 45865, 19242, 45873, 45877, 45887, 45898, 35617, 1042, 45911, - 45920, 45938, 45957, 45966, 45974, 45982, 1690, 12342, 45986, 27374, - 45989, 31556, 45994, 11478, 45999, 46005, 46010, 46016, 46021, 46027, - 46032, 46038, 46043, 46049, 46055, 46061, 46066, 46022, 46028, 46070, - 46033, 46039, 46044, 46075, 46050, 46056, 9184, 4434, 46081, 46089, - 46093, 46096, 46103, 46107, 46112, 46117, 46124, 46130, 46136, 46141, - 17850, 46145, 31573, 46149, 46153, 46157, 46164, 46170, 46174, 33931, - 46183, 10351, 46187, 10780, 46190, 46197, 46203, 46207, 14381, 46214, - 46220, 46225, 46232, 46239, 46246, 34730, 9081, 46253, 46260, 46267, - 46273, 46278, 46285, 46296, 46302, 46307, 46312, 46317, 46321, 46326, - 46333, 46023, 46337, 46347, 46356, 46367, 46373, 46381, 46388, 46393, - 46398, 46403, 46408, 46413, 46417, 46421, 46428, 46434, 46442, 2416, - 30582, 12245, 12257, 12262, 12268, 46451, 12273, 12278, 12284, 46456, - 46466, 46470, 12289, 46475, 20484, 46478, 46483, 46487, 46491, 46502, - 46510, 42204, 46518, 46523, 46530, 46537, 46541, 46544, 46552, 12153, - 46559, 46562, 46568, 46578, 6767, 46587, 46592, 46598, 46602, 46610, - 46614, 46624, 46630, 46635, 46646, 46655, 46664, 46673, 46682, 46691, - 46700, 46709, 46715, 46721, 46726, 46732, 46738, 46744, 46749, 46752, - 46759, 46765, 46769, 46774, 46781, 46788, 46792, 46795, 46805, 46818, - 46827, 46836, 46847, 46860, 46872, 46883, 46892, 46903, 46908, 46917, - 46922, 12294, 46928, 46935, 46943, 46950, 46955, 46960, 31836, 46964, - 46971, 4374, 25, 46975, 46980, 20333, 46984, 46987, 46990, 34122, 46994, - 34739, 47002, 47006, 47010, 47013, 47019, 47025, 47030, 37782, 47039, - 47047, 47053, 47060, 34105, 47064, 34342, 47068, 47077, 47081, 47089, - 47095, 47101, 47106, 47110, 34765, 47116, 47119, 47127, 47135, 47143, - 4772, 47149, 47153, 47157, 47162, 47169, 47175, 47180, 47185, 47189, - 47195, 47200, 47206, 4662, 820, 47213, 47217, 47220, 47232, 47239, 47244, - 18434, 47248, 47256, 47264, 47272, 47280, 47287, 47295, 47303, 47310, - 47318, 47326, 47334, 47342, 47350, 47358, 47366, 47374, 47382, 47390, - 47398, 47405, 47413, 47421, 47429, 47437, 47445, 47453, 47461, 47469, - 47477, 47485, 47493, 47501, 47509, 47517, 47525, 47533, 47541, 47549, - 47557, 47564, 47572, 47579, 47587, 47595, 47603, 47611, 47619, 47627, - 47635, 47643, 47654, 26794, 47659, 47662, 47669, 47673, 47679, 47683, - 47689, 47694, 47700, 47705, 47710, 47714, 47718, 47725, 47733, 47738, - 47743, 47753, 47759, 47772, 47778, 47784, 47790, 47793, 47800, 47805, - 4700, 47811, 4869, 965, 47816, 47819, 47822, 47825, 37866, 37872, 47828, - 37878, 37891, 37897, 37903, 47834, 37909, 37915, 47840, 47846, 10, 47854, - 47861, 47865, 47869, 47877, 38726, 47881, 47885, 47892, 47897, 47901, - 47906, 47912, 47917, 47923, 47928, 47932, 47936, 47940, 47945, 47949, - 47954, 47958, 47962, 47969, 47974, 47978, 47982, 47987, 47991, 47996, - 48000, 48004, 48009, 48015, 18743, 18748, 48020, 48024, 48027, 48033, - 48037, 48041, 25750, 48046, 48050, 48056, 48063, 48069, 48074, 40797, - 48084, 48089, 48097, 48101, 48104, 48108, 38741, 48116, 4738, 48121, - 48126, 48130, 48135, 48139, 48144, 16026, 48155, 48159, 48162, 48166, - 48174, 48179, 48183, 48188, 48193, 48197, 48201, 48205, 48208, 48212, - 48215, 48220, 48225, 48230, 48235, 48240, 48245, 8664, 16042, 48250, - 48253, 48259, 48264, 48270, 48275, 48281, 48286, 48292, 48297, 48303, - 48309, 48315, 48320, 48324, 48328, 48339, 48347, 48354, 48360, 48365, - 48376, 48386, 48392, 48397, 48404, 48413, 48429, 48445, 48455, 34007, - 48462, 48466, 48471, 48476, 48480, 48484, 43937, 48490, 48495, 48499, - 48506, 48511, 48516, 48520, 48523, 48527, 48533, 32802, 48537, 26108, - 48542, 48549, 48557, 48563, 48569, 48576, 48584, 48590, 48594, 48599, - 48605, 48613, 48618, 48622, 48631, 11134, 48639, 48643, 48651, 48658, - 48663, 48668, 48673, 48677, 48680, 48686, 48690, 48693, 48697, 48704, - 48709, 48716, 48720, 48726, 48730, 48736, 48741, 48746, 5107, 5114, - 48751, 48760, 48768, 48773, 48779, 48791, 48804, 48818, 48825, 48831, - 48837, 48842, 48850, 48853, 48855, 48866, 48878, 48889, 48904, 48921, - 48941, 48963, 48970, 48977, 48984, 48990, 48994, 8663, 48997, 49001, - 49005, 49010, 49014, 49018, 49021, 49025, 49039, 28019, 49058, 49071, - 49084, 49097, 28037, 49112, 2808, 49127, 49133, 49137, 49147, 49151, - 49155, 49160, 49164, 49171, 49176, 49180, 49187, 49193, 49198, 49204, - 49214, 49226, 49237, 49242, 49249, 49253, 49257, 49260, 49268, 19263, - 4141, 49273, 18782, 49286, 49293, 49300, 49306, 49310, 49314, 49319, - 49325, 49330, 49336, 49340, 49344, 49347, 49352, 49356, 49361, 49366, - 49371, 49376, 49381, 49386, 49391, 49396, 49401, 8727, 18793, 49406, - 49410, 49416, 49425, 49430, 49439, 49446, 43768, 49452, 49457, 49461, - 49468, 49473, 49480, 49488, 49494, 49498, 49501, 49505, 49510, 2886, - 49517, 49524, 49528, 49531, 49536, 49541, 49547, 49552, 49557, 49561, - 49566, 49576, 49581, 49587, 49592, 49599, 47234, 49605, 49611, 49619, - 49629, 49634, 49639, 49643, 49648, 49653, 8167, 8179, 49658, 49661, - 49668, 49674, 49683, 10268, 41421, 49691, 49695, 49699, 38789, 49707, - 49718, 49726, 43985, 49733, 49738, 49743, 49754, 49761, 49772, 38813, - 26125, 49780, 4652, 49785, 16459, 49791, 34096, 49797, 49802, 49812, - 49821, 49828, 49834, 49838, 49841, 49848, 49854, 49861, 49867, 49877, - 49885, 49891, 49897, 49902, 49906, 49913, 49918, 49924, 49931, 49937, - 49006, 49942, 49946, 16501, 16510, 16519, 16528, 16537, 16566, 622, - 16575, 49952, 49957, 49960, 49966, 49974, 1275, 49979, 49983, 49988, - 49993, 49997, 50002, 50009, 50015, 50019, 50024, 50030, 50034, 37939, - 50039, 50044, 50053, 50060, 50070, 50076, 34140, 50093, 50102, 50110, - 50116, 50121, 50128, 50134, 50142, 50151, 50159, 50167, 50173, 50177, - 50182, 50190, 35288, 38822, 50196, 50215, 19166, 50229, 50245, 50259, - 50265, 50270, 50275, 50280, 50286, 38828, 50291, 50294, 50301, 50308, - 50317, 50322, 50326, 423, 3176, 50333, 50338, 50343, 33196, 50131, 50347, - 50355, 50360, 50368, 50372, 50375, 50380, 50386, 50392, 50397, 50401, - 34213, 50404, 50409, 50413, 50416, 50421, 50425, 50430, 50435, 50439, - 50444, 50448, 50455, 50459, 50463, 25746, 25757, 50468, 50473, 50479, - 50484, 50490, 50496, 32758, 50501, 50505, 50508, 50514, 50519, 50524, - 50529, 50534, 50539, 50544, 50549, 50554, 50560, 50566, 14569, 19473, - 50571, 50576, 50581, 50586, 50591, 50596, 50601, 50606, 452, 68, 37956, - 37961, 37966, 37972, 37977, 37982, 50611, 37986, 50615, 50619, 50623, - 37991, 37997, 50637, 38008, 38013, 50645, 50650, 38019, 50655, 50660, - 50669, 50674, 50679, 50688, 50694, 50700, 50706, 38036, 50719, 50728, - 50734, 38040, 50738, 38045, 50743, 38050, 38055, 50746, 50751, 50755, - 50761, 16267, 50768, 16277, 50775, 50780, 38060, 50784, 50789, 50794, - 50799, 50804, 50808, 50813, 50818, 50824, 50829, 50834, 50840, 50846, - 50851, 50855, 50860, 50865, 50870, 50874, 50879, 50884, 50889, 50895, - 50901, 50907, 50912, 50916, 50921, 50925, 38064, 38069, 38074, 50929, - 50933, 50938, 50942, 50954, 38079, 38085, 38091, 38103, 50960, 31616, - 50964, 50969, 50973, 50978, 50985, 50990, 50995, 51000, 51004, 51008, - 51018, 51023, 51028, 51032, 51042, 51046, 51049, 51057, 51062, 38151, - 51066, 1375, 51072, 51077, 51083, 51091, 51095, 51104, 51112, 51116, - 51120, 51128, 51134, 51142, 51158, 51163, 51167, 51171, 51175, 51180, - 51186, 51201, 38188, 1685, 14601, 51205, 1254, 1269, 51217, 51225, 51232, - 51237, 9230, 51244, 51249, 10765, 978, 2641, 12321, 51256, 10658, 51261, - 51264, 51273, 1162, 51278, 49177, 51285, 51294, 51299, 51303, 51311, - 51318, 27424, 2697, 51326, 12842, 51336, 51342, 2434, 2444, 51351, 51360, - 51370, 51381, 3584, 41818, 51386, 4341, 4352, 9258, 1167, 51390, 51398, - 51405, 51410, 51414, 51418, 51423, 29054, 49512, 12412, 51431, 51440, - 51449, 51457, 51470, 51477, 51488, 51493, 51506, 51519, 51531, 51543, - 51555, 51566, 51579, 51590, 51601, 51611, 51619, 51627, 51639, 51651, - 51662, 51671, 51679, 51686, 51698, 51705, 51711, 51720, 51726, 51733, - 51746, 51751, 51761, 51766, 51772, 51777, 32098, 51781, 48682, 51788, - 51795, 51803, 51810, 2654, 51817, 51828, 51838, 51847, 51855, 51865, - 51873, 51882, 51892, 51901, 51906, 51912, 51918, 4190, 51929, 51939, - 51948, 51957, 51965, 51975, 51983, 51992, 51997, 52002, 52007, 1604, 47, - 52015, 52023, 52034, 52045, 19877, 52055, 52059, 52066, 52072, 52077, - 52081, 52092, 52102, 52111, 52122, 52127, 20306, 20311, 52134, 52143, - 52148, 52158, 52163, 52171, 52179, 52186, 52192, 1566, 271, 52196, 52201, - 52207, 46085, 52212, 52215, 2182, 2663, 52223, 52227, 52230, 1420, 52236, - 16787, 1172, 52241, 52254, 2797, 2818, 52268, 52280, 52292, 2832, 2849, - 2864, 2880, 2897, 52306, 52318, 2912, 52332, 1178, 1184, 1190, 12713, - 52337, 52342, 52347, 52351, 52366, 52381, 52396, 52411, 52426, 52441, - 52456, 52471, 52486, 52501, 52516, 52531, 52546, 52561, 52576, 52591, - 52606, 52621, 52636, 52651, 52666, 52681, 52696, 52711, 52726, 52741, - 52756, 52771, 52786, 52801, 52816, 52831, 52846, 52861, 52876, 52891, - 52906, 52921, 52936, 52951, 52966, 52981, 52996, 53011, 53026, 53041, - 53056, 53071, 53086, 53101, 53116, 53131, 53146, 53161, 53176, 53191, - 53206, 53221, 53236, 53251, 53266, 53281, 53296, 53311, 53326, 53341, - 53356, 53371, 53386, 53401, 53416, 53431, 53446, 53461, 53476, 53491, - 53506, 53521, 53536, 53551, 53566, 53581, 53596, 53611, 53626, 53641, - 53656, 53671, 53686, 53701, 53716, 53731, 53746, 53761, 53776, 53791, - 53806, 53821, 53836, 53851, 53866, 53881, 53896, 53911, 53926, 53941, - 53956, 53971, 53986, 54001, 54016, 54031, 54046, 54061, 54076, 54091, - 54106, 54121, 54136, 54151, 54166, 54181, 54196, 54211, 54226, 54241, - 54256, 54271, 54286, 54301, 54316, 54331, 54346, 54361, 54376, 54391, - 54406, 54421, 54436, 54451, 54466, 54481, 54496, 54511, 54526, 54541, - 54556, 54571, 54586, 54601, 54616, 54631, 54646, 54661, 54676, 54691, - 54706, 54721, 54736, 54751, 54766, 54781, 54796, 54811, 54826, 54841, - 54856, 54871, 54886, 54901, 54916, 54931, 54946, 54961, 54976, 54991, - 55006, 55021, 55036, 55051, 55066, 55081, 55096, 55111, 55126, 55141, - 55156, 55171, 55186, 55201, 55216, 55231, 55246, 55261, 55276, 55291, - 55306, 55321, 55336, 55351, 55366, 55381, 55396, 55411, 55426, 55441, - 55456, 55471, 55486, 55501, 55516, 55531, 55546, 55561, 55576, 55591, - 55606, 55621, 55636, 55651, 55666, 55681, 55696, 55711, 55726, 55741, - 55756, 55771, 55786, 55801, 55816, 55831, 55846, 55861, 55876, 55891, - 55906, 55921, 55936, 55951, 55966, 55981, 55996, 56011, 56026, 56041, - 56056, 56071, 56086, 56101, 56116, 56131, 56146, 56161, 56176, 56191, - 56206, 56221, 56236, 56251, 56266, 56281, 56296, 56311, 56326, 56341, - 56356, 56371, 56386, 56401, 56416, 56431, 56446, 56461, 56476, 56491, - 56506, 56521, 56536, 56551, 56566, 56581, 56596, 56611, 56626, 56641, - 56656, 56671, 56686, 56701, 56716, 56731, 56746, 56761, 56776, 56791, - 56806, 56821, 56836, 56851, 56866, 56881, 56896, 56911, 56926, 56941, - 56956, 56971, 56986, 57001, 57016, 57031, 57046, 57061, 57076, 57091, - 57106, 57121, 57136, 57151, 57166, 57181, 57196, 57211, 57226, 57241, - 57256, 57271, 57286, 57301, 57316, 57331, 57346, 57361, 57376, 57391, - 57406, 57421, 57436, 57451, 57466, 57481, 57496, 57511, 57526, 57541, - 57556, 57571, 57586, 57601, 57616, 57631, 57646, 57661, 57676, 57691, - 57706, 57721, 57736, 57751, 57766, 57781, 57796, 57811, 57826, 57841, - 57856, 57871, 57886, 57901, 57916, 57931, 57946, 57961, 57976, 57991, - 58006, 58021, 58036, 58051, 58066, 58081, 58096, 58111, 58126, 58141, - 58156, 58171, 58186, 58201, 58216, 58231, 58246, 58261, 58276, 58291, - 58306, 58321, 58336, 58351, 58366, 58381, 58396, 58411, 58426, 58441, - 58456, 58471, 58486, 58501, 58516, 58531, 58546, 58561, 58576, 58591, - 58606, 58621, 58636, 58651, 58666, 58681, 58696, 58711, 58726, 58741, - 58756, 58771, 58786, 58801, 58816, 58831, 58846, 58861, 58876, 58891, - 58906, 58921, 58936, 58951, 58966, 58981, 58996, 59011, 59026, 59041, - 59056, 59071, 59086, 59101, 59116, 59131, 59146, 59161, 59176, 59191, - 59206, 59221, 59236, 59251, 59266, 59281, 59296, 59311, 59326, 59341, - 59356, 59371, 59386, 59401, 59416, 59431, 59446, 59461, 59476, 59491, - 59506, 59521, 59536, 59551, 59566, 59581, 59596, 59611, 59626, 59641, - 59656, 59671, 59686, 59701, 59716, 59731, 59746, 59761, 59776, 59791, - 59806, 59821, 59836, 59851, 59866, 59881, 59896, 59911, 59926, 59941, - 59956, 59971, 59986, 60001, 60016, 60031, 60046, 60061, 60076, 60091, - 60106, 60121, 60136, 60151, 60166, 60182, 60198, 60214, 60230, 60246, - 60262, 60278, 60294, 60310, 60326, 60342, 60358, 60374, 60390, 60406, - 60422, 60438, 60454, 60470, 60486, 60502, 60518, 60534, 60550, 60566, - 60582, 60598, 60614, 60630, 60646, 60662, 60678, 60694, 60710, 60726, - 60742, 60758, 60774, 60790, 60806, 60822, 60838, 60854, 60870, 60886, - 60902, 60918, 60934, 60950, 60966, 60982, 60998, 61014, 61030, 61046, - 61062, 61078, 61094, 61110, 61126, 61142, 61158, 61174, 61190, 61206, - 61222, 61238, 61254, 61270, 61286, 61302, 61318, 61334, 61350, 61366, - 61382, 61398, 61414, 61430, 61446, 61462, 61478, 61494, 61510, 61526, - 61542, 61558, 61574, 61590, 61606, 61622, 61638, 61654, 61670, 61686, - 61702, 61718, 61734, 61750, 61766, 61782, 61798, 61814, 61830, 61846, - 61862, 61878, 61894, 61910, 61926, 61942, 61958, 61974, 61990, 62006, - 62022, 62038, 62054, 62070, 62086, 62102, 62118, 62134, 62150, 62166, - 62182, 62198, 62214, 62230, 62246, 62262, 62278, 62294, 62310, 62326, - 62342, 62358, 62374, 62390, 62406, 62422, 62438, 62454, 62470, 62486, - 62502, 62518, 62534, 62550, 62566, 62582, 62598, 62614, 62630, 62646, - 62662, 62678, 62694, 62710, 62726, 62742, 62758, 62774, 62790, 62806, - 62822, 62838, 62854, 62870, 62886, 62902, 62918, 62934, 62950, 62966, - 62982, 62998, 63014, 63030, 63046, 63062, 63078, 63094, 63110, 63126, - 63142, 63158, 63174, 63190, 63206, 63222, 63238, 63254, 63270, 63286, - 63302, 63318, 63334, 63350, 63366, 63382, 63398, 63414, 63430, 63446, - 63462, 63478, 63494, 63510, 63526, 63542, 63558, 63574, 63590, 63606, - 63622, 63638, 63654, 63670, 63686, 63702, 63718, 63734, 63750, 63766, - 63782, 63798, 63814, 63830, 63846, 63862, 63878, 63894, 63910, 63926, - 63942, 63958, 63974, 63990, 64006, 64022, 64038, 64054, 64070, 64086, - 64102, 64118, 64134, 64150, 64166, 64182, 64198, 64214, 64230, 64246, - 64262, 64278, 64294, 64310, 64326, 64342, 64358, 64374, 64390, 64406, - 64422, 64438, 64454, 64470, 64486, 64502, 64518, 64534, 64550, 64566, - 64582, 64598, 64614, 64630, 64646, 64662, 64678, 64694, 64710, 64726, - 64742, 64758, 64774, 64790, 64806, 64822, 64838, 64854, 64870, 64886, - 64902, 64918, 64934, 64950, 64966, 64982, 64998, 65014, 65030, 65046, - 65062, 65078, 65094, 65110, 65126, 65142, 65158, 65174, 65190, 65206, - 65222, 65238, 65254, 65270, 65286, 65302, 65318, 65334, 65350, 65366, - 65382, 65398, 65414, 65430, 65446, 65462, 65478, 65494, 65510, 65526, - 65542, 65558, 65574, 65590, 65606, 65622, 65638, 65654, 65670, 65686, - 65702, 65718, 65734, 65750, 65766, 65782, 65798, 65814, 65830, 65846, - 65862, 65878, 65894, 65910, 65926, 65942, 65958, 65974, 65990, 66006, - 66022, 66038, 66054, 66070, 66086, 66102, 66118, 66134, 66150, 66166, - 66182, 66198, 66214, 66230, 66246, 66262, 66278, 66294, 66310, 66326, - 66342, 66358, 66374, 66390, 66406, 66422, 66438, 66454, 66470, 66486, - 66502, 66518, 66534, 66550, 66566, 66582, 66598, 66614, 66630, 66646, - 66662, 66678, 66694, 66710, 66726, 66742, 66758, 66774, 66790, 66806, - 66822, 66838, 66854, 66870, 66886, 66902, 66918, 66934, 66950, 66966, - 66982, 66998, 67014, 67030, 67046, 67062, 67078, 67094, 67110, 67126, - 67142, 67158, 67174, 67190, 67206, 67222, 67238, 67254, 67270, 67286, - 67302, 67318, 67334, 67350, 67366, 67382, 67398, 67414, 67430, 67446, - 67462, 67478, 67494, 67510, 67526, 67542, 67558, 67574, 67590, 67606, - 67622, 67638, 67654, 67670, 67686, 67702, 67718, 67734, 67750, 67766, - 67782, 67798, 67814, 67830, 67846, 67862, 67878, 67894, 67910, 67926, - 67942, 67958, 67974, 67990, 68006, 68022, 68038, 68054, 68070, 68086, - 68102, 68118, 68134, 68150, 68166, 68182, 68198, 68214, 68230, 68246, - 68262, 68278, 68294, 68310, 68326, 68342, 68358, 68374, 68390, 68406, - 68422, 68438, 68454, 68470, 68486, 68502, 68518, 68534, 68550, 68566, - 68582, 68598, 68614, 68630, 68646, 68662, 68678, 68694, 68710, 68726, - 68742, 68758, 68774, 68790, 68806, 68822, 68838, 68847, 68862, 68876, - 68885, 17689, 68889, 68894, 68900, 68906, 68916, 68924, 17946, 18677, - 9277, 68937, 1428, 1432, 68945, 4270, 33321, 8104, 68951, 68956, 68961, - 68966, 68971, 68977, 68982, 68988, 68993, 68999, 69004, 69009, 69014, - 69019, 69025, 69030, 69035, 69040, 69045, 69050, 69055, 69060, 69066, - 69071, 69077, 69084, 2701, 69089, 69095, 9652, 69099, 69104, 69111, - 69119, 4281, 4286, 4291, 4296, 65, 69123, 69129, 69134, 69139, 69143, - 69148, 69152, 69156, 12785, 69160, 69170, 69183, 69194, 69207, 69214, - 69220, 69228, 69235, 12246, 69244, 69249, 69255, 69261, 69267, 69272, - 69277, 69282, 69287, 69291, 69296, 69301, 69306, 69312, 69318, 69324, - 69329, 69333, 69338, 69343, 69347, 69352, 69357, 69362, 69366, 12801, - 12812, 12817, 1471, 69370, 69376, 1476, 19711, 69381, 19720, 1486, 69386, - 69392, 69397, 1507, 69403, 1513, 1519, 12847, 69408, 69417, 69425, 69433, - 69440, 69444, 69448, 69454, 69459, 37599, 69464, 69471, 69479, 69486, - 69491, 69495, 69499, 69508, 69513, 69518, 69523, 1524, 280, 69528, 69533, - 69537, 19846, 987, 69541, 69548, 69553, 69557, 19904, 1528, 46361, 69560, - 69565, 69575, 69584, 69589, 69593, 69599, 1533, 49458, 69604, 69613, - 69619, 69624, 69629, 13086, 13092, 69635, 69648, 69660, 69677, 69694, - 69711, 69728, 69745, 69762, 69779, 69796, 69813, 69830, 69847, 69864, - 69881, 69898, 69915, 69932, 69949, 69966, 69983, 70000, 70017, 70034, - 70051, 70068, 70085, 70102, 70119, 70136, 70153, 70170, 70187, 70204, - 70221, 70238, 70255, 70272, 70289, 70306, 70323, 70340, 70357, 70374, - 70391, 70408, 70425, 70442, 70459, 70476, 70493, 70504, 70514, 70519, - 1538, 70523, 70528, 70534, 70539, 70544, 70551, 10677, 1543, 70557, - 70566, 33713, 70571, 70582, 13108, 70592, 70597, 70603, 70608, 70615, - 70621, 70626, 1548, 20198, 70631, 70637, 13118, 70643, 70648, 70653, - 70658, 70663, 70668, 70673, 70678, 1553, 4761, 70683, 70688, 70694, - 70699, 70704, 70709, 70714, 70719, 70724, 70729, 70734, 70740, 70746, - 70752, 70757, 70761, 70766, 70771, 70775, 70780, 70785, 70790, 70795, - 70799, 70804, 70810, 70815, 70820, 70824, 70829, 70834, 70840, 70845, - 70850, 70856, 70862, 70867, 70871, 70876, 70881, 70886, 70890, 70895, - 70900, 70905, 70911, 70917, 70922, 70926, 70930, 70935, 70940, 70945, - 35492, 70949, 70954, 70959, 70965, 70970, 70975, 70979, 70984, 70989, - 70995, 71000, 71005, 71011, 71017, 71022, 71026, 71031, 71036, 71040, - 71045, 71050, 71055, 71061, 71067, 71072, 71076, 71081, 71086, 71090, - 71095, 71100, 71105, 71110, 71114, 71117, 71120, 71125, 71130, 38335, - 71137, 71145, 50085, 71151, 3928, 33656, 71164, 71171, 71177, 71183, - 4107, 71188, 13260, 71194, 71204, 71219, 71227, 13265, 71238, 71243, - 71254, 71266, 71278, 71290, 2903, 71302, 71307, 31699, 71319, 71325, - 71331, 71336, 71345, 71352, 71357, 71362, 71367, 71372, 71377, 71382, - 1570, 19338, 71387, 71392, 71397, 71402, 71408, 71413, 71419, 71424, - 71429, 71435, 71440, 71445, 49532, 71449, 71453, 71458, 71462, 20346, - 71467, 71470, 71475, 71483, 71491, 1574, 13301, 13307, 1579, 71499, - 71506, 71511, 71520, 71530, 71537, 71542, 71547, 1584, 71554, 71559, - 20466, 71563, 71568, 71575, 71581, 71585, 71598, 71604, 71615, 71625, - 71632, 20488, 10571, 10578, 4355, 4361, 71639, 1589, 71644, 71653, 71659, - 71667, 71674, 71680, 71687, 71699, 71705, 71710, 71717, 71729, 71740, - 71750, 71759, 71769, 71779, 4249, 71787, 37393, 37402, 20528, 71800, - 71805, 71810, 71815, 71820, 71825, 71830, 1594, 1598, 71835, 71839, - 71842, 71853, 71858, 20554, 1608, 71866, 71871, 71876, 71888, 20587, - 71895, 71898, 71904, 71910, 71915, 71923, 1613, 71928, 71933, 71941, - 71949, 71956, 71965, 71973, 71982, 71986, 1618, 71995, 1623, 25931, - 72000, 72007, 72013, 20674, 72021, 72031, 72037, 72042, 72050, 72057, - 72066, 72074, 72084, 72093, 72103, 72112, 72123, 72133, 72143, 72152, - 72162, 72176, 72189, 72198, 72206, 72216, 72225, 72237, 72248, 72259, - 72269, 19966, 72274, 13453, 72283, 72289, 72294, 72301, 72307, 72314, - 72320, 19555, 72330, 72336, 72341, 72352, 72359, 72366, 72371, 72379, - 13470, 13475, 72387, 72393, 72397, 4339, 4350, 20750, 49635, 72405, - 72411, 72416, 72424, 72431, 14582, 72436, 72442, 72448, 1634, 72453, - 72456, 72462, 72467, 72472, 72477, 72482, 72487, 72492, 72497, 72502, - 72508, 72514, 1333, 72519, 72524, 72529, 72535, 72540, 72545, 72550, - 72555, 72560, 72565, 1643, 18, 72571, 72575, 72580, 72584, 72588, 72592, - 38621, 72597, 28238, 72602, 72607, 72611, 72614, 72618, 72622, 72627, - 72631, 72636, 72640, 72643, 72649, 42308, 42313, 42318, 72652, 72659, - 72665, 72673, 49230, 72683, 72689, 42324, 38885, 38636, 38642, 42340, - 38648, 72694, 72699, 72703, 38918, 72710, 72713, 72717, 72725, 72732, - 72737, 72740, 72745, 72750, 72754, 72758, 72761, 72771, 72783, 72790, - 72796, 38653, 72803, 40604, 72806, 9669, 13815, 72809, 72813, 72818, - 4159, 72822, 72825, 16320, 72832, 72839, 72852, 72867, 72881, 72897, - 72912, 72921, 72929, 72937, 72946, 72950, 72959, 72965, 72970, 72980, - 72993, 73005, 73012, 73017, 73026, 73039, 44032, 73057, 73062, 73069, - 73075, 73080, 895, 73085, 73093, 73100, 73107, 33137, 914, 73113, 73119, - 73124, 73134, 73142, 73148, 73153, 38672, 6858, 38686, 73157, 73167, - 73172, 73180, 73190, 73205, 73211, 73217, 73224, 38696, 73229, 73235, - 37737, 73239, 73243, 73248, 73257, 73264, 73269, 73273, 73278, 73286, - 20531, 73293, 73298, 73302, 6899, 38722, 73306, 73312, 341, 73322, 73329, - 73336, 73342, 73349, 73354, 73363, 15941, 69569, 69579, 73369, 73377, - 73381, 73385, 73389, 73393, 73398, 73402, 73408, 73416, 73421, 73426, - 73433, 73438, 73442, 73447, 73451, 73455, 73461, 73467, 73478, 73484, - 73489, 73493, 73498, 73502, 38846, 73506, 38852, 38858, 73511, 73517, - 73524, 73529, 73533, 37754, 20185, 73536, 73540, 73545, 73552, 73558, - 73562, 73567, 48699, 73573, 73577, 73584, 73588, 73593, 73599, 73605, - 73611, 73623, 73632, 73642, 73648, 73655, 73660, 73665, 73669, 73672, - 73678, 73685, 73690, 73695, 73702, 73709, 73716, 73722, 73727, 73732, - 73740, 38863, 2531, 73745, 73750, 73756, 73761, 73767, 73772, 73777, - 73782, 73788, 38884, 73793, 73799, 73805, 73811, 38954, 73816, 73821, - 73826, 38965, 73831, 73836, 73841, 73847, 73853, 38970, 73858, 73863, - 73868, 39025, 39031, 73873, 73878, 39036, 39058, 33998, 39064, 39068, - 73883, 14258, 73887, 73895, 73901, 73909, 73916, 73922, 73932, 73938, - 73945, 12685, 39082, 73951, 73964, 73973, 73979, 73988, 73994, 74000, - 74007, 28581, 74015, 74022, 74032, 74040, 74043, 39026, 74048, 74055, - 74060, 74064, 74068, 74073, 74077, 4478, 74082, 74087, 74092, 42402, - 42407, 74096, 42421, 74101, 42426, 74106, 74112, 42438, 42444, 42450, - 74117, 74123, 27479, 74134, 74137, 74149, 74157, 39105, 74161, 74170, - 74180, 74189, 39115, 74194, 74201, 74210, 74216, 74224, 74231, 74238, - 6950, 5174, 74243, 39037, 74249, 74252, 74258, 74265, 74270, 74275, - 28485, 74279, 74285, 74291, 74296, 74301, 74305, 74311, 74317, 40488, - 74322, 43626, 45463, 45469, 39146, 39151, 74326, 74330, 74334, 74337, - 74350, 74356, 74360, 74363, 74368, 40870, 74372, 37759, 25872, 74378, - 6879, 6887, 10377, 74381, 74386, 74391, 74396, 74401, 74406, 74411, - 74416, 74421, 74426, 74432, 74437, 74442, 74448, 74453, 74458, 74463, - 74468, 74473, 74478, 74484, 74489, 74495, 74500, 74505, 74510, 74515, - 74520, 74525, 74530, 74535, 74540, 74545, 74551, 74556, 74561, 74566, - 74571, 74576, 74581, 74587, 74592, 74597, 74602, 74607, 74612, 74617, - 74622, 74627, 74632, 74638, 74643, 74648, 74653, 74658, 74664, 74670, - 74675, 74681, 74686, 74691, 74696, 74701, 74706, 1421, 159, 74711, 74715, - 74719, 74723, 30435, 74727, 74731, 74736, 74740, 74745, 74749, 74754, - 74759, 74764, 74769, 74773, 74777, 74782, 74786, 16020, 74791, 74795, - 74802, 74812, 18315, 74821, 74830, 74839, 74843, 74848, 74853, 74857, - 74861, 30215, 3259, 74865, 74871, 21763, 74875, 74884, 74892, 74898, - 74903, 74915, 74927, 74932, 74936, 74941, 74945, 74951, 74957, 74962, - 74972, 74982, 74988, 74996, 75001, 75005, 75011, 75016, 75023, 75029, - 75034, 75041, 75050, 75059, 75067, 75071, 18871, 75074, 75083, 75091, - 75103, 75114, 75125, 75134, 75138, 75147, 75155, 75165, 75173, 75180, - 75190, 75196, 75201, 75209, 75216, 75225, 75231, 75236, 75243, 75249, - 75260, 60, 37536, 75266, 31986, 31996, 75272, 75280, 75287, 75293, 75297, - 75307, 75318, 75326, 75335, 75340, 75345, 75350, 75354, 75358, 75366, - 21710, 75373, 75377, 75383, 75393, 75400, 75407, 75413, 75419, 42501, - 75423, 75425, 75428, 75434, 75438, 75449, 75459, 75465, 75472, 75479, - 15957, 75487, 75493, 75502, 75511, 75517, 11579, 75523, 75529, 75534, - 75539, 75546, 75551, 75558, 75564, 75569, 75577, 75590, 75599, 75608, - 72138, 72148, 75618, 75624, 75633, 75639, 75645, 75652, 75659, 75666, - 75673, 75680, 75685, 75689, 75693, 75696, 75706, 75710, 75722, 75731, - 10038, 75740, 75751, 75756, 75760, 72157, 75766, 75773, 75782, 75790, - 51037, 75798, 75802, 75807, 75812, 75822, 75830, 75842, 75847, 75851, - 75855, 75861, 75869, 75876, 75888, 75896, 75907, 75914, 75920, 75930, - 75936, 75940, 75949, 75958, 75965, 75971, 75976, 75980, 75984, 75988, - 75997, 76006, 76015, 76022, 76028, 76034, 76040, 76045, 76052, 76058, - 76066, 76073, 76079, 15046, 76084, 76090, 76094, 17172, 76098, 76103, - 76113, 76118, 76127, 76133, 76139, 76147, 76154, 76158, 76162, 76169, - 76175, 76183, 76190, 76196, 76207, 76211, 76215, 76219, 76222, 76228, - 76233, 76238, 76242, 76246, 76255, 76263, 76270, 76276, 76283, 29245, - 48840, 76288, 76296, 76300, 76304, 76307, 76315, 76322, 76328, 76337, - 76345, 76351, 76356, 76360, 76365, 76370, 76374, 76378, 76382, 76387, - 76396, 76400, 76407, 45567, 76411, 76417, 76425, 76429, 76435, 76443, - 76449, 76454, 76465, 76473, 76479, 76488, 27626, 76496, 76503, 76510, - 76517, 76524, 76531, 52526, 15772, 76538, 76545, 76550, 42537, 4721, - 76556, 76561, 76566, 76572, 76578, 76584, 76589, 76594, 76599, 76604, - 76610, 76615, 76621, 76626, 76632, 76637, 76642, 76647, 76652, 76657, - 76662, 76667, 76673, 76678, 76684, 76689, 76694, 76699, 76704, 76709, - 76714, 76720, 76725, 76730, 76735, 76740, 76745, 76750, 76755, 76760, - 76765, 76770, 76776, 76781, 76786, 76791, 76796, 76801, 76806, 76811, - 76816, 76822, 76827, 76832, 76837, 76842, 76847, 76852, 76857, 76862, - 76867, 76872, 76877, 76882, 76888, 1883, 305, 76893, 46479, 46484, 76897, - 76902, 9293, 76906, 3628, 76911, 76916, 76920, 76929, 76940, 76957, - 76975, 76983, 75794, 76990, 76993, 77003, 77010, 77019, 77035, 77044, - 77054, 77059, 77072, 77082, 77091, 77099, 77113, 77121, 77130, 77134, - 77137, 77144, 77150, 77161, 77168, 77180, 77191, 77202, 77211, 77218, - 1173, 812, 77228, 2744, 77232, 77237, 77246, 997, 9059, 25308, 77254, - 77262, 77276, 77289, 77293, 77298, 77303, 77308, 77314, 77320, 77325, - 9661, 18358, 77330, 77334, 77338, 77346, 10098, 77351, 77357, 77366, - 77374, 1657, 13314, 1179, 4393, 77378, 77382, 77391, 77401, 2482, 32836, - 77410, 77416, 20438, 32851, 77422, 4558, 13696, 77428, 77435, 71848, - 77439, 77443, 77449, 77454, 77459, 3861, 163, 3887, 77464, 77476, 77480, - 77484, 77490, 77495, 33733, 77499, 13684, 2938, 4, 77504, 77514, 77525, - 77536, 77546, 77552, 77563, 77570, 77576, 77582, 2306, 77587, 77595, - 77602, 77608, 77618, 77628, 77638, 77647, 28568, 1185, 77652, 77656, - 77660, 77666, 77670, 2961, 2967, 9658, 2337, 77674, 77678, 77687, 77695, - 77706, 77714, 77722, 77728, 77733, 77744, 77755, 77763, 77769, 77774, - 11356, 77784, 77792, 77796, 77800, 77805, 77809, 77821, 34196, 18257, - 77828, 77838, 77844, 77850, 7977, 11490, 77860, 77871, 77882, 77892, - 77901, 77905, 77912, 999, 2731, 77922, 77927, 77935, 71564, 77943, 77948, - 77959, 77966, 77980, 16968, 529, 77990, 77997, 78001, 78005, 78013, - 78022, 4433, 78030, 78036, 20483, 78041, 78055, 78062, 78068, 78076, - 78085, 78094, 78101, 78113, 78123, 78131, 78138, 78146, 78153, 4357, 116, - 78161, 78172, 78176, 78188, 78194, 1804, 227, 78199, 10709, 78204, 3006, - 78208, 78215, 78221, 78232, 78242, 78250, 78257, 10049, 78264, 78273, - 78281, 4438, 78294, 4455, 78298, 78303, 78309, 78314, 78319, 78324, 3011, - 573, 78330, 78343, 78347, 78352, 78357, 3016, 1882, 763, 78361, 4459, - 78369, 78375, 78379, 799, 78389, 78398, 78403, 3878, 78407, 78411, 17989, - 17996, 9317, 78419, 4490, 4367, 15644, 78427, 78434, 78439, 28632, 78443, - 78450, 78456, 13952, 78461, 14017, 204, 78466, 78478, 78484, 78492, 3028, - 1699, 78500, 78502, 78507, 78512, 78517, 78523, 78528, 78533, 78538, - 78543, 78548, 78553, 78559, 78564, 78569, 78574, 78579, 78584, 78589, - 78594, 78599, 78605, 78610, 78615, 78620, 78626, 78631, 78637, 78642, - 78647, 78652, 78657, 78662, 78667, 78672, 78678, 78683, 78689, 78694, - 78699, 78704, 78709, 78714, 78719, 78724, 78729, 9730, 9743, 4506, 4511, - 4516, 4521, 26, 78735, 78741, 78746, 78751, 78756, 78762, 78767, 78771, - 78775, 78780, 78786, 78790, 78796, 78801, 78806, 78812, 78817, 78821, - 78826, 78831, 78835, 78838, 78840, 78844, 78847, 78854, 78859, 78863, - 78868, 78872, 78876, 78880, 78886, 78897, 78917, 78936, 78957, 78970, - 78982, 78991, 78995, 78998, 39423, 79001, 39428, 79008, 79013, 39433, - 79022, 79031, 39439, 79036, 39444, 79045, 79050, 13941, 79054, 79059, - 79064, 39449, 79068, 79077, 50696, 79081, 79084, 79088, 9325, 79094, - 79097, 79102, 79107, 79112, 79116, 4179, 39454, 79119, 79123, 79126, - 79137, 79142, 79146, 79152, 79160, 79173, 79177, 79185, 79194, 79200, - 79205, 79211, 79215, 79221, 79227, 79235, 79240, 79244, 79251, 79257, - 79265, 79274, 79282, 39457, 79289, 79299, 79308, 79316, 79327, 79340, - 79345, 79350, 79354, 79363, 79369, 79376, 79389, 79401, 79412, 79424, - 79431, 79440, 79449, 79458, 79465, 79471, 79478, 79486, 79493, 79501, - 79510, 79518, 79525, 79533, 79542, 79550, 79559, 79569, 79578, 79586, - 79593, 79601, 79610, 79618, 79627, 79637, 79646, 79654, 79663, 79673, - 79682, 79692, 79703, 79713, 79722, 79730, 79737, 79745, 79754, 79762, - 79771, 79781, 79790, 79798, 79807, 79817, 79826, 79836, 79847, 79857, - 79866, 79874, 79883, 79893, 79902, 79912, 79923, 79933, 79942, 79952, - 79963, 79973, 79984, 79996, 80007, 80017, 80026, 80034, 80041, 80049, - 80058, 80066, 80075, 80085, 80094, 80102, 80111, 80121, 80130, 80140, - 80151, 80161, 80170, 80178, 80187, 80197, 80206, 80216, 80227, 80237, - 80246, 80256, 80267, 80277, 80288, 80300, 80311, 80321, 80330, 80338, - 80347, 80357, 80366, 80376, 80387, 80397, 80406, 80416, 80427, 80437, - 80448, 80460, 80471, 80481, 80490, 80500, 80511, 80521, 80532, 80544, - 80555, 80565, 80576, 80588, 80599, 80611, 80624, 80636, 80647, 80657, - 80666, 80674, 80681, 80689, 80698, 80706, 80715, 80725, 80734, 80742, - 80751, 80761, 80770, 80780, 80791, 80801, 80810, 80818, 80827, 80837, - 80846, 80856, 80867, 80877, 80886, 80896, 80907, 80917, 80928, 80940, - 80951, 80961, 80970, 80978, 80987, 80997, 81006, 81016, 81027, 81037, - 81046, 81056, 81067, 81077, 81088, 81100, 81111, 81121, 81130, 81140, - 81151, 81161, 81172, 81184, 81195, 81205, 81216, 81228, 81239, 81251, - 81264, 81276, 81287, 81297, 81306, 81314, 81323, 81333, 81342, 81352, - 81363, 81373, 81382, 81392, 81403, 81413, 81424, 81436, 81447, 81457, - 81466, 81476, 81487, 81497, 81508, 81520, 81531, 81541, 81552, 81564, - 81575, 81587, 81600, 81612, 81623, 81633, 81642, 81652, 81663, 81673, - 81684, 81696, 81707, 81717, 81728, 81740, 81751, 81763, 81776, 81788, - 81799, 81809, 81820, 81832, 81843, 81855, 81868, 81880, 81891, 81903, - 81916, 81928, 81941, 81955, 81968, 81980, 81991, 82001, 82010, 82018, - 82025, 82030, 9090, 82037, 82042, 39467, 82048, 82053, 39472, 82059, - 82066, 25430, 31434, 82071, 82077, 82083, 82091, 82097, 82103, 82110, - 82117, 82122, 82127, 82131, 82136, 82140, 82143, 82147, 82152, 82161, - 82170, 82178, 82184, 82196, 82207, 82211, 3321, 9065, 82216, 82219, - 82222, 82224, 82228, 82232, 82236, 82242, 82247, 31497, 82252, 82256, - 82259, 82264, 82268, 82275, 82281, 82285, 7060, 82289, 82294, 39494, - 82298, 82305, 82314, 82322, 82328, 82339, 82347, 82356, 82364, 82371, - 82378, 82384, 82389, 82400, 39499, 82405, 82416, 82428, 82436, 82447, - 82456, 82464, 82475, 82480, 82488, 2696, 82493, 82502, 41891, 82515, - 82519, 82531, 82539, 82544, 82552, 82563, 21928, 82572, 82578, 82585, - 82593, 82599, 39509, 82604, 4484, 68920, 82611, 82614, 82622, 82635, - 82648, 82661, 82674, 82681, 82692, 82701, 82706, 52343, 52348, 82710, - 82714, 82722, 82729, 82738, 82746, 82752, 82761, 82769, 82776, 82784, - 82788, 82797, 82806, 82816, 82829, 82842, 82852, 39514, 82858, 82865, - 82871, 82877, 39520, 82882, 82885, 82889, 82897, 82906, 52114, 82914, - 82923, 82931, 82938, 82946, 82956, 82965, 82974, 41043, 82983, 82994, - 83009, 83019, 10747, 26246, 83028, 83033, 83038, 83042, 19547, 83047, - 83052, 83058, 83063, 83068, 83074, 83079, 83084, 26206, 83089, 83096, - 83104, 83112, 83120, 83125, 83132, 83139, 83144, 1717, 83148, 83152, - 83160, 83168, 39537, 83174, 83180, 83192, 83198, 83205, 83209, 83216, - 83221, 83228, 83234, 83241, 83252, 83262, 83272, 83284, 83290, 83298, - 83307, 83313, 83323, 83333, 39564, 83342, 83351, 83357, 83369, 83380, - 83387, 83392, 83396, 83404, 83415, 83421, 83426, 83431, 83438, 83446, - 83458, 83468, 83477, 83486, 83494, 83501, 41705, 29006, 83507, 83512, - 83516, 83520, 83525, 83533, 83539, 83550, 83563, 83568, 83575, 39569, - 83580, 83592, 83601, 83609, 83619, 83630, 83643, 83650, 83659, 83668, - 83676, 83681, 83687, 83691, 1410, 83696, 83701, 83706, 83711, 83717, - 83722, 83727, 83733, 83739, 83744, 83748, 83753, 83758, 83763, 69504, - 83768, 83773, 83778, 83783, 83789, 83795, 83800, 83804, 83809, 19546, - 83814, 83820, 83825, 83831, 83836, 83841, 83846, 83851, 83855, 83861, - 83866, 83875, 83880, 83885, 83890, 83895, 83899, 83906, 83912, 4836, - 20800, 3286, 83917, 83921, 83926, 83930, 83934, 83938, 56143, 83942, - 83867, 83944, 83954, 39578, 83957, 83962, 83971, 83977, 7019, 39583, - 83981, 83987, 83992, 83998, 84003, 84007, 84014, 84019, 84029, 84038, - 84042, 84048, 84054, 84060, 84064, 84072, 84079, 84087, 84095, 39588, - 84102, 84105, 84116, 84123, 84129, 84134, 84138, 84144, 84152, 84159, - 84164, 84168, 84177, 84185, 84191, 84196, 84203, 84211, 39593, 84218, - 28458, 84230, 84236, 84241, 84247, 84254, 84260, 25894, 33344, 84266, - 84271, 84277, 84281, 84293, 83900, 83907, 26138, 84303, 84308, 84315, - 84321, 84328, 84334, 84345, 84350, 84358, 10447, 84363, 84366, 84372, - 84376, 84380, 84383, 84389, 84395, 39282, 4837, 1425, 16069, 84402, - 84408, 84414, 84420, 84426, 84432, 84438, 84444, 84450, 84455, 84460, - 84465, 84470, 84475, 84480, 84485, 84490, 84495, 84500, 84505, 84510, - 84515, 84521, 84526, 84531, 84537, 84542, 84547, 84553, 84559, 84565, - 84571, 84577, 84583, 84589, 84595, 84601, 84606, 84611, 84617, 84622, - 84627, 84633, 84638, 84643, 84648, 84653, 84658, 84663, 84668, 84673, - 84678, 84683, 84688, 84693, 84699, 84704, 84709, 84714, 84720, 84725, - 84730, 84735, 84740, 84746, 84751, 84756, 84761, 84766, 84771, 84776, - 84781, 84786, 84791, 84796, 84801, 84806, 84811, 84816, 84821, 84826, - 84831, 84836, 84841, 84847, 84852, 84857, 84862, 84867, 84872, 84877, - 84882, 1065, 148, 84887, 84891, 84895, 84900, 84908, 84912, 84924, 84931, - 84939, 84943, 84956, 84964, 84969, 84974, 32049, 84978, 84983, 84987, - 84992, 84996, 85004, 85008, 25438, 85013, 85017, 72401, 85021, 85024, - 85032, 85040, 85048, 85053, 85058, 85065, 85072, 85078, 85084, 85089, - 85096, 85101, 85109, 77281, 85116, 85121, 72167, 85128, 85134, 85139, - 85143, 85150, 85156, 85163, 72194, 14031, 85171, 85176, 85181, 85185, - 85188, 85199, 85208, 85214, 85219, 85223, 85233, 85242, 50487, 85246, - 85250, 85257, 85270, 85276, 85284, 85291, 85300, 85311, 85322, 85333, - 85344, 85353, 85359, 85368, 85376, 85386, 85399, 85407, 85414, 85425, - 85434, 85440, 85445, 85450, 85456, 85466, 85472, 85482, 85490, 85497, - 85507, 85516, 83582, 85524, 85530, 85538, 85544, 75834, 85551, 85556, - 85559, 85563, 85569, 85573, 85576, 85584, 85590, 85596, 85604, 85616, - 85628, 85635, 85640, 85644, 85655, 85663, 85670, 85682, 85690, 85697, - 85705, 85712, 85718, 85723, 85729, 85739, 85748, 85756, 85761, 85771, - 85780, 51375, 85787, 85791, 85796, 85804, 85811, 85817, 85821, 85831, - 85842, 85850, 85857, 85869, 85881, 85890, 82505, 85897, 85907, 85919, - 85930, 85944, 85952, 85962, 85969, 85977, 85990, 86002, 86011, 86019, - 86029, 86040, 86052, 86061, 86071, 86081, 86091, 86100, 86107, 86116, - 86131, 86139, 86149, 86158, 86166, 86179, 68890, 86194, 86204, 86213, - 86225, 86235, 86247, 86258, 86272, 86286, 86300, 86314, 86328, 86342, - 86356, 86370, 86384, 86398, 86412, 86426, 86440, 86454, 86468, 86482, - 86496, 86510, 86524, 86538, 86552, 86566, 86580, 86594, 86608, 86622, - 86636, 86650, 86664, 86678, 86692, 86706, 86720, 86734, 86748, 86762, - 86776, 86790, 86804, 86818, 86832, 86846, 86860, 86874, 86888, 86902, - 86916, 86930, 86944, 86958, 86972, 86986, 87000, 87014, 87028, 87042, - 87056, 87070, 87084, 87098, 87112, 87126, 87140, 87154, 87168, 87182, - 87196, 87210, 87224, 87238, 87252, 87266, 87280, 87294, 87308, 87322, - 87336, 87350, 87364, 87378, 87392, 87406, 87420, 87434, 87448, 87462, - 87476, 87490, 87504, 87518, 87532, 87546, 87560, 87574, 87588, 87602, - 87616, 87630, 87644, 87658, 87672, 87686, 87700, 87714, 87728, 87742, - 87756, 87770, 87784, 87798, 87812, 87826, 87840, 87854, 87868, 87882, - 87896, 87910, 87924, 87938, 87952, 87966, 87980, 87994, 88008, 88022, - 88036, 88050, 88064, 88078, 88092, 88106, 88120, 88134, 88148, 88162, - 88176, 88190, 88204, 88218, 88232, 88246, 88260, 88274, 88288, 88302, - 88316, 88330, 88344, 88358, 88372, 88386, 88400, 88414, 88428, 88442, - 88456, 88470, 88484, 88498, 88512, 88526, 88540, 88554, 88568, 88582, - 88596, 88610, 88624, 88638, 88652, 88666, 88680, 88694, 88708, 88722, - 88736, 88750, 88764, 88778, 88792, 88806, 88820, 88834, 88848, 88862, - 88876, 88890, 88904, 88918, 88932, 88946, 88960, 88974, 88988, 89002, - 89016, 89030, 89044, 89058, 89072, 89086, 89100, 89114, 89128, 89142, - 89156, 89170, 89184, 89198, 89212, 89226, 89240, 89254, 89268, 89282, - 89296, 89310, 89324, 89338, 89352, 89366, 89380, 89394, 89408, 89422, - 89436, 89450, 89464, 89478, 89492, 89506, 89520, 89534, 89548, 89562, - 89576, 89590, 89604, 89618, 89632, 89646, 89660, 89674, 89688, 89702, - 89716, 89730, 89744, 89758, 89772, 89786, 89800, 89814, 89828, 89842, - 89856, 89870, 89884, 89898, 89912, 89926, 89940, 89954, 89968, 89982, - 89996, 90010, 90024, 90038, 90052, 90066, 90080, 90094, 90108, 90122, - 90136, 90150, 90164, 90178, 90192, 90206, 90220, 90234, 90248, 90262, - 90276, 90290, 90304, 90318, 90332, 90346, 90360, 90374, 90388, 90402, - 90416, 90430, 90444, 90458, 90472, 90486, 90500, 90514, 90528, 90542, - 90556, 90570, 90584, 90598, 90612, 90626, 90640, 90654, 90668, 90682, - 90696, 90710, 90724, 90738, 90752, 90766, 90780, 90794, 90808, 90822, - 90836, 90850, 90864, 90878, 90892, 90906, 90920, 90934, 90948, 90962, - 90976, 90990, 91004, 91018, 91032, 91046, 91060, 91074, 91088, 91102, - 91116, 91130, 91144, 91158, 91172, 91186, 91200, 91214, 91228, 91242, - 91256, 91270, 91284, 91298, 91312, 91326, 91340, 91354, 91368, 91382, - 91396, 91410, 91424, 91438, 91452, 91466, 91480, 91494, 91508, 91522, - 91536, 91550, 91564, 91578, 91592, 91606, 91620, 91634, 91648, 91662, - 91676, 91690, 91704, 91718, 91732, 91746, 91760, 91774, 91788, 91802, - 91816, 91830, 91844, 91858, 91872, 91886, 91900, 91914, 91928, 91942, - 91956, 91970, 91984, 91998, 92012, 92026, 92040, 92054, 92068, 92082, - 92096, 92110, 92124, 92138, 92152, 92166, 92180, 92194, 92208, 92222, - 92236, 92250, 92264, 92278, 92292, 92306, 92320, 92334, 92348, 92362, - 92376, 92390, 92404, 92418, 92432, 92446, 92460, 92474, 92488, 92502, - 92516, 92530, 92544, 92558, 92572, 92586, 92600, 92614, 92628, 92642, - 92656, 92670, 92684, 92698, 92712, 92726, 92740, 92754, 92768, 92782, - 92796, 92810, 92824, 92838, 92852, 92866, 92880, 92894, 92908, 92922, - 92936, 92950, 92964, 92978, 92992, 93006, 93020, 93034, 93048, 93062, - 93076, 93090, 93104, 93118, 93132, 93146, 93160, 93174, 93188, 93202, - 93216, 93230, 93244, 93258, 93272, 93286, 93300, 93314, 93328, 93342, - 93356, 93370, 93384, 93398, 93412, 93426, 93440, 93454, 93468, 93482, - 93496, 93510, 93524, 93538, 93552, 93566, 93580, 93594, 93608, 93622, - 93636, 93650, 93664, 93678, 93692, 93706, 93720, 93734, 93748, 93762, - 93776, 93790, 93804, 93818, 93832, 93846, 93860, 93874, 93888, 93902, - 93916, 93930, 93944, 93958, 93972, 93986, 94000, 94014, 94028, 94042, - 94056, 94070, 94084, 94098, 94112, 94126, 94140, 94154, 94168, 94182, - 94196, 94210, 94224, 94238, 94252, 94266, 94280, 94294, 94308, 94322, - 94336, 94350, 94364, 94378, 94392, 94406, 94420, 94434, 94448, 94462, - 94476, 94490, 94504, 94518, 94532, 94546, 94560, 94574, 94588, 94602, - 94616, 94630, 94644, 94658, 94672, 94686, 94700, 94714, 94728, 94742, - 94756, 94770, 94784, 94798, 94812, 94826, 94840, 94854, 94868, 94882, - 94896, 94910, 94924, 94938, 94952, 94966, 94980, 94994, 95008, 95022, - 95036, 95050, 95064, 95078, 95092, 95106, 95120, 95134, 95148, 95162, - 95176, 95190, 95204, 95218, 95232, 95246, 95260, 95274, 95288, 95302, - 95316, 95330, 95344, 95358, 95372, 95386, 95400, 95414, 95428, 95442, - 95456, 95470, 95484, 95498, 95512, 95526, 95540, 95554, 95568, 95582, - 95596, 95610, 95624, 95638, 95652, 95666, 95680, 95694, 95708, 95722, - 95736, 95750, 95764, 95778, 95792, 95806, 95820, 95834, 95848, 95862, - 95876, 95890, 95904, 95918, 95932, 95946, 95960, 95974, 95988, 96002, - 96016, 96030, 96044, 96058, 96072, 96086, 96100, 96114, 96128, 96142, - 96156, 96170, 96184, 96198, 96212, 96226, 96240, 96254, 96268, 96282, - 96296, 96310, 96324, 96338, 96352, 96366, 96380, 96394, 96408, 96422, - 96436, 96450, 96464, 96478, 96492, 96506, 96520, 96534, 96548, 96562, - 96576, 96590, 96604, 96618, 96632, 96646, 96660, 96674, 96688, 96702, - 96716, 96730, 96744, 96758, 96772, 96786, 96800, 96814, 96828, 96842, - 96856, 96870, 96884, 96898, 96912, 96926, 96940, 96954, 96968, 96982, - 96996, 97010, 97019, 97030, 97041, 97051, 97062, 97070, 97078, 97084, - 97094, 97102, 97108, 35368, 97113, 97119, 97128, 97140, 97145, 97152, - 11370, 21948, 97158, 97167, 97172, 97176, 97181, 97188, 97194, 97199, - 97204, 97212, 97220, 97230, 97235, 97243, 14513, 97247, 97253, 97259, - 97265, 97271, 97277, 97283, 97289, 97295, 97301, 97307, 97313, 97319, - 97325, 97331, 97337, 97343, 97349, 97355, 97361, 97367, 97373, 97379, - 97385, 97391, 97397, 97403, 97409, 97415, 97421, 97427, 97433, 97439, - 97445, 97451, 97457, 97463, 97470, 97476, 97482, 97488, 97494, 97500, - 97506, 97512, 97518, 97524, 97530, 97536, 97542, 97548, 97554, 97560, - 97566, 97572, 97578, 97584, 97590, 97596, 97602, 97608, 97614, 97620, - 97626, 97632, 97638, 97644, 97650, 97656, 97662, 97668, 97674, 97680, - 97686, 97692, 97698, 97704, 97710, 97716, 97722, 97728, 97734, 97740, - 97746, 97752, 97758, 97764, 97770, 97777, 97783, 97789, 97795, 97801, - 97807, 97813, 97819, 97825, 97831, 97837, 97843, 97846, 97848, 97863, - 97876, 97883, 97889, 97900, 97905, 97909, 97914, 97921, 97927, 97932, - 97940, 77884, 77894, 97946, 97953, 97963, 12672, 97970, 97975, 35616, - 97984, 97989, 97996, 98006, 98014, 98022, 98031, 98040, 98046, 98052, - 98057, 98064, 98071, 98076, 98080, 98088, 72211, 98093, 98102, 98110, - 98117, 98122, 98126, 98135, 98141, 98144, 98148, 98157, 98167, 84951, - 98176, 98180, 98188, 98192, 98198, 98209, 98219, 21957, 98230, 98239, - 98247, 98255, 98262, 72230, 9895, 98270, 98274, 98283, 98290, 98293, - 98297, 33215, 98300, 98304, 98309, 98326, 98338, 12630, 98350, 98355, - 98360, 98365, 25545, 98369, 98374, 98379, 98385, 98390, 6640, 98395, - 25549, 98400, 98405, 98411, 98418, 98423, 98428, 98434, 98440, 98446, - 98451, 98457, 98461, 98475, 98483, 98491, 98497, 98502, 98509, 98519, - 98528, 98533, 98538, 98543, 98551, 98561, 98572, 98577, 98583, 98588, - 98597, 70639, 4760, 98602, 98620, 98639, 98652, 98666, 98682, 98689, - 98696, 98705, 98712, 98718, 98725, 98730, 98736, 98741, 98747, 98755, - 98761, 98766, 98771, 98787, 12643, 98801, 98808, 98816, 98822, 98826, - 98829, 98835, 98840, 98845, 98853, 98860, 98865, 98874, 98880, 98885, - 98891, 98897, 98906, 98915, 43462, 98920, 98931, 98938, 98946, 98955, - 14104, 98964, 98970, 98978, 98984, 98990, 98996, 99001, 99008, 99014, - 14115, 99019, 99022, 99027, 39620, 99037, 99046, 99051, 99059, 99066, - 99072, 99077, 99085, 99092, 99103, 99119, 99135, 99151, 99167, 99183, - 99199, 99215, 99231, 99247, 99263, 99279, 99295, 99311, 99327, 99343, - 99359, 99375, 99391, 99407, 99423, 99439, 99455, 99471, 99487, 99503, - 99519, 99535, 99551, 99567, 99583, 99599, 99615, 99631, 99647, 99663, - 99679, 99695, 99711, 99727, 99743, 99759, 99775, 99791, 99807, 99823, - 99839, 99855, 99871, 99887, 99903, 99919, 99935, 99951, 99967, 99983, - 99999, 100015, 100031, 100047, 100063, 100079, 100095, 100111, 100127, - 100143, 100159, 100175, 100191, 100207, 100223, 100239, 100255, 100271, - 100287, 100303, 100319, 100335, 100351, 100367, 100383, 100399, 100415, - 100431, 100447, 100463, 100479, 100495, 100511, 100527, 100543, 100559, - 100575, 100591, 100607, 100623, 100639, 100655, 100671, 100687, 100703, - 100719, 100735, 100751, 100767, 100783, 100799, 100815, 100831, 100847, - 100863, 100879, 100895, 100911, 100927, 100943, 100959, 100975, 100991, - 101007, 101023, 101039, 101055, 101071, 101087, 101103, 101119, 101135, - 101151, 101167, 101183, 101199, 101215, 101231, 101247, 101263, 101279, - 101295, 101311, 101327, 101343, 101359, 101375, 101391, 101407, 101423, - 101439, 101455, 101471, 101487, 101503, 101519, 101535, 101551, 101567, - 101583, 101599, 101615, 101631, 101647, 101663, 101679, 101695, 101711, - 101727, 101743, 101759, 101775, 101791, 101807, 101823, 101839, 101855, - 101871, 101887, 101903, 101919, 101935, 101951, 101967, 101983, 101999, - 102015, 102031, 102047, 102063, 102079, 102095, 102111, 102127, 102143, - 102159, 102175, 102191, 102207, 102223, 102239, 102255, 102271, 102287, - 102303, 102319, 102335, 102351, 102367, 102383, 102399, 102415, 102431, - 102447, 102463, 102479, 102495, 102511, 102527, 102543, 102559, 102575, - 102591, 102607, 102623, 102639, 102655, 102671, 102687, 102703, 102719, - 102735, 102751, 102767, 102783, 102799, 102815, 102831, 102847, 102863, - 102879, 102895, 102911, 102927, 102943, 102959, 102975, 102991, 103007, - 103023, 103039, 103055, 103071, 103087, 103103, 103119, 103135, 103151, - 103167, 103183, 103199, 103215, 103231, 103247, 103263, 103279, 103295, - 103311, 103327, 103343, 103359, 103375, 103391, 103407, 103423, 103439, - 103455, 103471, 103487, 103503, 103519, 103535, 103551, 103567, 103583, - 103599, 103615, 103631, 103647, 103663, 103679, 103695, 103711, 103727, - 103743, 103759, 103775, 103791, 103807, 103823, 103839, 103855, 103871, - 103887, 103903, 103919, 103935, 103951, 103967, 103983, 103999, 104015, - 104031, 104047, 104063, 104079, 104095, 104111, 104127, 104143, 104159, - 104175, 104191, 104207, 104223, 104239, 104255, 104271, 104287, 104303, - 104319, 104335, 104351, 104367, 104383, 104399, 104415, 104431, 104447, - 104463, 104479, 104495, 104511, 104527, 104543, 104559, 104575, 104591, - 104607, 104623, 104639, 104655, 104671, 104687, 104703, 104719, 104735, - 104751, 104767, 104783, 104799, 104815, 104831, 104847, 104863, 104879, - 104895, 104911, 104927, 104943, 104959, 104975, 104991, 105007, 105023, - 105039, 105055, 105071, 105087, 105103, 105119, 105135, 105151, 105167, - 105183, 105199, 105215, 105231, 105247, 105263, 105279, 105295, 105311, - 105327, 105343, 105359, 105375, 105391, 105407, 105423, 105439, 105455, - 105471, 105487, 105503, 105519, 105535, 105551, 105567, 105583, 105599, - 105615, 105631, 105647, 105663, 105679, 105695, 105711, 105727, 105743, - 105759, 105775, 105791, 105807, 105823, 105839, 105855, 105871, 105887, - 105903, 105919, 105935, 105951, 105967, 105983, 105999, 106015, 106031, - 106047, 106063, 106079, 106095, 106111, 106127, 106143, 106159, 106175, - 106191, 106207, 106223, 106239, 106255, 106271, 106287, 106303, 106319, - 106335, 106351, 106367, 106383, 106399, 106415, 106431, 106447, 106463, - 106479, 106495, 106511, 106527, 106543, 106559, 106575, 106591, 106607, - 106623, 106639, 106655, 106671, 106687, 106703, 106719, 106735, 106751, - 106767, 106783, 106799, 106815, 106831, 106847, 106863, 106879, 106895, - 106911, 106927, 106943, 106959, 106975, 106991, 107007, 107023, 107039, - 107055, 107071, 107087, 107103, 107119, 107135, 107151, 107167, 107183, - 107199, 107215, 107231, 107247, 107263, 107279, 107295, 107311, 107327, - 107343, 107359, 107375, 107391, 107407, 107423, 107439, 107455, 107471, - 107487, 107503, 107519, 107535, 107551, 107567, 107583, 107599, 107615, - 107631, 107647, 107663, 107679, 107695, 107711, 107727, 107743, 107759, - 107775, 107791, 107807, 107823, 107839, 107855, 107871, 107887, 107903, - 107919, 107935, 107951, 107967, 107983, 107999, 108015, 108031, 108047, - 108063, 108079, 108095, 108111, 108127, 108143, 108159, 108175, 108191, - 108207, 108223, 108239, 108255, 108271, 108287, 108303, 108319, 108335, - 108351, 108367, 108383, 108399, 108415, 108431, 108447, 108463, 108479, - 108495, 108511, 108527, 108543, 108559, 108575, 108591, 108607, 108623, - 108639, 108655, 108671, 108687, 108703, 108719, 108735, 108751, 108767, - 108783, 108799, 108815, 108831, 108847, 108863, 108879, 108895, 108911, - 108927, 108943, 108959, 108975, 108991, 109007, 109023, 109039, 109055, - 109071, 109087, 109103, 109119, 109135, 109151, 109167, 109183, 109199, - 109215, 109231, 109247, 109263, 109279, 109295, 109311, 109327, 109343, - 109359, 109375, 109391, 109407, 109423, 109439, 109455, 109471, 109487, - 109503, 109519, 109535, 109551, 109567, 109583, 109599, 109615, 109631, - 109647, 109663, 109679, 109695, 109711, 109727, 109743, 109759, 109775, - 109791, 109807, 109823, 109839, 109855, 109871, 109887, 109903, 109919, - 109935, 109951, 109967, 109983, 109999, 110015, 110031, 110047, 110063, - 110079, 110095, 110111, 110127, 110143, 110159, 110175, 110191, 110207, - 110223, 110239, 110255, 110271, 110287, 110303, 110319, 110335, 110351, - 110367, 110383, 110399, 110415, 110431, 110447, 110463, 110479, 110495, - 110511, 110527, 110543, 110559, 110575, 110591, 110607, 110623, 110639, - 110655, 110671, 110687, 110703, 110719, 110735, 110751, 110767, 110783, - 110799, 110815, 110831, 110847, 110863, 110879, 110895, 110911, 110927, - 110943, 110959, 110975, 110991, 111007, 111023, 111039, 111055, 111071, - 111087, 111103, 111119, 111135, 111151, 111167, 111183, 111199, 111215, - 111231, 111247, 111263, 111279, 111295, 111311, 111327, 111343, 111359, - 111375, 111391, 111407, 111423, 111439, 111455, 111471, 111487, 111503, - 111519, 111535, 111551, 111567, 111583, 111599, 111615, 111631, 111647, - 111663, 111679, 111695, 111711, 111727, 111743, 111759, 111775, 111791, - 111807, 111823, 111839, 111855, 111871, 111887, 111903, 111919, 111935, - 111951, 111967, 111983, 111999, 112015, 112031, 112047, 112063, 112079, - 112095, 112111, 112127, 112143, 112159, 112175, 112191, 112207, 112223, - 112239, 112255, 112271, 112287, 112303, 112319, 112335, 112351, 112367, - 112383, 112399, 112415, 112431, 112447, 112463, 112479, 112495, 112511, - 112527, 112543, 112559, 112575, 112591, 112607, 112623, 112639, 112655, - 112671, 112687, 112703, 112719, 112735, 112751, 112767, 112783, 112799, - 112815, 112831, 112847, 112863, 112879, 112895, 112911, 112927, 112943, - 112959, 112969, 112978, 112983, 112991, 77204, 112996, 113002, 113007, - 113014, 113023, 113031, 113035, 4338, 113041, 113048, 113054, 113058, - 20549, 46595, 3295, 113063, 113067, 113071, 113078, 113084, 113093, - 113099, 113106, 113110, 113131, 113153, 113169, 113186, 113205, 113214, - 113224, 113232, 113239, 113246, 113252, 33070, 113266, 113270, 113276, - 113284, 113296, 113302, 113310, 113317, 113322, 113327, 113331, 113339, - 113346, 113350, 113356, 113362, 113367, 3972, 52543, 113373, 113377, - 113381, 113385, 113390, 113395, 113400, 113406, 113412, 113418, 113425, - 113431, 113438, 113444, 113450, 113455, 113461, 113466, 113470, 105563, - 113475, 105627, 52558, 113480, 113485, 113493, 113497, 113502, 113509, - 113518, 113525, 113531, 113540, 113544, 113551, 113555, 113558, 113565, - 113571, 113580, 113590, 113600, 113605, 113609, 113616, 113624, 113633, - 113637, 113645, 113651, 113656, 113661, 113667, 113673, 113678, 113682, - 31947, 113688, 113692, 113696, 113699, 113704, 113712, 113722, 113728, - 113733, 113743, 49664, 113751, 113763, 113769, 113776, 113782, 113786, - 113791, 113797, 113809, 113820, 113827, 113833, 113840, 113847, 113859, - 113866, 113872, 25629, 113876, 113884, 113890, 113897, 113903, 113909, - 113915, 113920, 113925, 113930, 113934, 113943, 113951, 113962, 7934, - 113967, 19985, 113973, 113977, 113981, 113985, 113993, 114002, 114006, - 114013, 114022, 114030, 114043, 114049, 106139, 36551, 114054, 114056, - 114061, 114066, 114071, 114076, 114081, 114086, 114091, 114096, 114101, - 114106, 114111, 114116, 114121, 114126, 114132, 114137, 114142, 114147, - 114152, 114157, 114162, 114167, 114172, 114178, 114184, 114190, 114195, - 114200, 114212, 114217, 1935, 54, 114222, 114227, 39630, 114231, 39635, - 39640, 39646, 39651, 114235, 39656, 26815, 114257, 114261, 114265, - 114270, 114274, 39660, 114278, 114286, 114293, 114299, 114309, 39665, - 114316, 114319, 114324, 114328, 114337, 11168, 114345, 39670, 26659, - 114348, 114352, 114360, 1307, 114365, 39681, 114368, 114373, 114378, - 31188, 31198, 43060, 114383, 114388, 114393, 114398, 114404, 114409, - 114418, 114423, 114432, 114440, 114447, 114453, 114458, 114463, 114468, - 114478, 114487, 114495, 114500, 114508, 114512, 114520, 114524, 114531, - 114538, 114546, 114553, 39485, 46310, 114559, 114565, 114570, 114575, - 14548, 11961, 114580, 114585, 114590, 114596, 114603, 114609, 114618, - 114623, 114631, 114641, 114648, 114658, 114664, 114669, 114675, 114679, - 21979, 114686, 44045, 114699, 114704, 114711, 114717, 114732, 37615, - 75612, 114745, 114749, 114758, 114767, 114774, 114780, 114788, 114794, - 114802, 114811, 114819, 114826, 46430, 114832, 114835, 114839, 114843, - 114847, 11982, 114853, 114860, 114866, 114874, 114879, 114883, 29180, - 114889, 114892, 114900, 114907, 114915, 114928, 114942, 114949, 114955, - 114962, 114968, 39695, 114972, 114978, 114986, 114993, 115001, 115009, - 115015, 39700, 115023, 115029, 115034, 115044, 115050, 115059, 37410, - 42408, 115067, 115072, 115077, 115081, 115086, 115090, 115098, 115103, - 17981, 18806, 49686, 115107, 115112, 39705, 18138, 115116, 115128, - 115133, 115137, 115144, 115153, 115157, 115165, 115171, 115176, 115184, - 115192, 115200, 115208, 115216, 115224, 115235, 115241, 9132, 115246, - 115252, 115257, 115262, 115273, 115282, 115294, 115309, 40017, 115315, - 20104, 39709, 115319, 115326, 115332, 115336, 29317, 115343, 115349, - 115356, 48811, 115365, 115371, 115380, 115386, 115391, 115399, 115405, - 115410, 39719, 115415, 115424, 115433, 113815, 115442, 115449, 115455, - 115461, 115470, 115480, 115486, 115494, 115501, 115505, 39724, 115508, - 39730, 1346, 115513, 115521, 115529, 115539, 115548, 115556, 115563, - 115573, 39741, 115577, 115579, 115583, 115588, 115592, 115596, 115602, - 115607, 115611, 115622, 115627, 115633, 115638, 115647, 115652, 3300, - 115656, 115663, 115667, 115676, 115684, 115692, 115699, 115704, 115709, - 74113, 115713, 115716, 115722, 115730, 115736, 115740, 115745, 115752, - 115757, 115762, 115766, 115773, 115779, 115784, 42439, 115788, 115791, - 115796, 115800, 115805, 115812, 115817, 115821, 47780, 115829, 31207, - 31216, 115835, 115841, 115847, 115852, 115856, 115859, 115869, 115878, - 115883, 115889, 115896, 115902, 115906, 115914, 115919, 42445, 85210, - 115923, 115931, 115938, 115944, 115951, 115956, 115963, 115968, 115972, - 115978, 115983, 69106, 115989, 115995, 10386, 116000, 116005, 116009, - 116014, 116019, 116024, 116028, 116033, 116038, 116044, 116049, 116054, - 116060, 116066, 116071, 116075, 116080, 116085, 116090, 116094, 29316, - 116099, 116104, 116110, 116116, 116122, 116127, 116131, 116136, 116141, - 109915, 116146, 116151, 116156, 116161, 109979, 52813, 116166, 39749, - 116174, 116178, 116186, 116194, 116205, 116210, 116214, 27294, 82608, - 116219, 116225, 116230, 4649, 116240, 116247, 116252, 116260, 116269, - 116274, 116278, 116283, 116287, 116295, 116303, 116310, 77470, 116316, - 116324, 116331, 116342, 116348, 116354, 39759, 116357, 116364, 116372, - 116377, 116381, 33589, 71792, 116387, 116392, 116399, 116404, 10275, - 116408, 116416, 116423, 116430, 116439, 116446, 116452, 116466, 116474, - 6724, 116236, 116480, 116485, 116491, 116495, 116498, 116506, 116513, - 116518, 116531, 116538, 116544, 116548, 116556, 116561, 116568, 116574, - 116579, 72070, 116584, 116587, 116596, 116603, 110187, 116609, 116612, - 116620, 116626, 116635, 116645, 116655, 116664, 116675, 116683, 116694, - 116699, 116703, 116708, 116712, 43191, 116720, 18771, 43200, 116725, - 101706, 101722, 101738, 101754, 101770, 116730, 101802, 101818, 101834, - 101850, 101962, 101978, 116734, 102010, 102026, 116738, 116742, 116746, - 116750, 102266, 102298, 116754, 102330, 116758, 116762, 102474, 102490, - 102506, 102522, 116766, 102586, 102602, 116770, 102730, 102746, 102762, - 102778, 102794, 102810, 102826, 102842, 102858, 102874, 102986, 103002, - 103018, 103034, 103050, 103066, 103082, 103098, 103114, 103130, 116774, - 104922, 105034, 105098, 105114, 105130, 105146, 105162, 105178, 105290, - 105306, 105322, 116778, 105370, 116782, 105402, 105418, 105434, 116786, - 116791, 116796, 116801, 116806, 116811, 116816, 116820, 116824, 116829, - 116834, 116838, 116843, 116848, 116852, 116857, 116862, 116867, 116872, - 116876, 116881, 116886, 116890, 116895, 116899, 116903, 116907, 116911, - 116916, 116920, 116924, 116928, 116932, 116936, 116940, 116944, 116948, - 116952, 116957, 116962, 116967, 116972, 116977, 116982, 116987, 116992, - 116997, 117002, 117006, 117010, 117014, 117018, 117022, 117026, 117031, - 117035, 117040, 117044, 117049, 117054, 117058, 117062, 117067, 117071, - 117075, 117079, 117083, 117087, 117091, 117095, 117099, 117103, 117107, - 117111, 117115, 117119, 117123, 117128, 117133, 117137, 117141, 117145, - 117149, 117153, 117157, 117162, 117166, 117170, 117174, 117178, 117182, - 117186, 117191, 117195, 117200, 117204, 117208, 117212, 117216, 117220, - 117224, 117228, 117232, 117236, 117240, 117244, 117249, 117253, 117257, - 117261, 117265, 117269, 117273, 117277, 117281, 117285, 117289, 117293, - 117298, 117302, 117306, 117311, 117316, 117320, 117324, 117328, 117332, - 117336, 117340, 117344, 117348, 117353, 117357, 117362, 117366, 117371, - 117375, 117380, 117384, 117390, 117395, 117399, 117404, 117408, 117413, - 117417, 117422, 117426, 117431, 1429, 117435, 117439, 3042, 1705, 28453, - 1602, 31143, 117443, 3051, 117447, 1276, 117452, 1218, 117456, 117460, - 117464, 117468, 117472, 117476, 3075, 117480, 117488, 117495, 117502, - 117516, 3079, 8044, 117525, 117533, 117540, 117551, 117560, 117564, - 117571, 117583, 117596, 117609, 117620, 117625, 117632, 117644, 117648, - 3083, 14185, 117658, 117663, 117672, 117682, 117687, 117696, 3087, - 117704, 117708, 117713, 117720, 117726, 117731, 117740, 117748, 117760, - 117770, 1223, 15645, 117783, 117787, 117793, 117807, 117819, 117831, - 117839, 117849, 117858, 117867, 117876, 117884, 117895, 117903, 4657, - 117913, 117924, 117933, 117939, 117954, 117961, 117967, 117972, 43334, - 117977, 3111, 15649, 117981, 117986, 117993, 10206, 118002, 118008, 4695, - 118018, 3116, 39121, 118027, 71682, 118034, 118038, 118044, 118055, - 118061, 118066, 118073, 118079, 118087, 118094, 118100, 118111, 118127, - 118137, 118146, 118157, 118166, 118173, 118179, 118189, 118197, 118203, - 118218, 118224, 118229, 118233, 118240, 118248, 118252, 118255, 118261, - 118268, 118274, 118282, 118291, 118299, 118305, 118314, 52116, 118328, - 118333, 118339, 17732, 118344, 118357, 118369, 118378, 118386, 118393, - 118397, 118401, 118404, 118411, 118418, 118426, 118434, 118443, 118451, - 17631, 118459, 118464, 118468, 118480, 118487, 118494, 118503, 954, - 118513, 118522, 118533, 3137, 118537, 118541, 118547, 118560, 118572, - 118582, 118591, 118603, 32105, 118614, 118622, 118631, 118642, 118653, - 118663, 118673, 118681, 118690, 118698, 13604, 118705, 118709, 118712, - 118717, 118722, 118726, 118732, 1228, 118739, 118743, 14281, 118747, - 118751, 118762, 118771, 118779, 118788, 118796, 118812, 118823, 118832, - 118840, 118852, 118863, 118879, 118889, 118910, 118924, 118937, 118945, - 118952, 8090, 118965, 118970, 118976, 6733, 118982, 118985, 118992, - 119002, 9266, 119009, 119014, 119019, 119026, 119034, 119042, 119048, - 119053, 119059, 119063, 119071, 119080, 119088, 119093, 119102, 119109, - 11418, 11427, 119115, 119126, 119132, 119137, 119143, 3153, 3158, 119149, - 1063, 119155, 119162, 119169, 119182, 119192, 119197, 2324, 87, 119205, - 119212, 119217, 119225, 119235, 119244, 119250, 119259, 119267, 119277, - 119281, 119285, 119290, 119294, 119306, 3181, 119314, 119322, 119327, - 119338, 119349, 119361, 119372, 119382, 119391, 26013, 119396, 119402, - 119407, 119417, 119427, 119432, 34323, 119438, 119443, 119452, 26035, - 119456, 26046, 119461, 4783, 8, 119468, 119477, 119484, 119491, 119497, - 119502, 119506, 119512, 34353, 119517, 119522, 72367, 119527, 119532, - 119538, 119544, 119552, 119557, 119565, 119573, 119582, 119589, 119595, - 119602, 119608, 119615, 119620, 47649, 52010, 119626, 119636, 1822, 32, - 119643, 119648, 119661, 119666, 119674, 119679, 119685, 3207, 30884, - 3221, 119690, 119698, 119705, 119710, 119715, 119724, 4340, 4351, 73711, - 119732, 119736, 1629, 1862, 119741, 119746, 119753, 34774, 1866, 331, - 119760, 119766, 119771, 3229, 119775, 119780, 119787, 1870, 119792, - 119798, 119803, 119815, 6978, 119825, 119832, 1877, 119838, 119843, - 119850, 119857, 119872, 119879, 119890, 119895, 119903, 2772, 119907, - 119919, 119924, 119928, 119934, 34195, 2329, 119938, 119949, 119953, - 119957, 119963, 119967, 119976, 119980, 119991, 119995, 2375, 38938, - 119999, 120009, 120017, 3320, 120023, 120032, 120040, 10752, 120045, - 120053, 120058, 120062, 120071, 120078, 120084, 3290, 17796, 120088, - 120101, 44058, 120119, 120124, 120132, 120140, 120150, 11759, 15773, - 120162, 120175, 120182, 120192, 120206, 120213, 120229, 120236, 120242, - 26093, 14980, 120249, 120256, 120266, 120275, 52812, 120287, 120295, - 52947, 120302, 120305, 120311, 120317, 120323, 120329, 120335, 120342, - 120349, 120355, 120361, 120367, 120373, 120379, 120385, 120391, 120397, - 120403, 120409, 120415, 120421, 120427, 120433, 120439, 120445, 120451, - 120457, 120463, 120469, 120475, 120481, 120487, 120493, 120499, 120505, - 120511, 120517, 120523, 120529, 120535, 120541, 120547, 120553, 120559, - 120565, 120571, 120577, 120583, 120589, 120595, 120601, 120607, 120613, - 120619, 120625, 120631, 120637, 120643, 120649, 120655, 120662, 120668, - 120675, 120682, 120688, 120695, 120702, 120708, 120714, 120720, 120726, - 120732, 120738, 120744, 120750, 120756, 120762, 120768, 120774, 120780, - 120786, 120792, 3304, 10720, 120798, 120808, 120814, 120822, 120826, - 117716, 3308, 120830, 114044, 25758, 4701, 4265, 120834, 3314, 120838, - 120848, 120854, 120860, 120866, 120872, 120878, 120884, 120890, 120896, - 120902, 120908, 120914, 120920, 120926, 120932, 120938, 120944, 120950, - 120956, 120962, 120968, 120974, 120980, 120986, 120992, 120998, 121005, - 121012, 121018, 121024, 121030, 121036, 121042, 121048, 1233, 121054, - 121059, 121064, 121069, 121074, 121079, 121084, 121089, 121094, 121098, - 121102, 121106, 121110, 121114, 121118, 121122, 121126, 121130, 121136, - 121142, 121148, 121154, 121158, 121162, 121166, 121170, 121174, 121178, - 121182, 121186, 121190, 121195, 121200, 121205, 121210, 121215, 121220, - 121225, 121230, 121235, 121240, 121245, 121250, 121255, 121260, 121265, - 121270, 121275, 121280, 121285, 121290, 121295, 121300, 121305, 121310, - 121315, 121320, 121325, 121330, 121335, 121340, 121345, 121350, 121355, - 121360, 121365, 121370, 121375, 121380, 121385, 121390, 121395, 121400, - 121405, 121410, 121415, 121420, 121425, 121430, 121435, 121440, 121445, - 121450, 121455, 121460, 121465, 121470, 121475, 121480, 121485, 121490, - 121495, 121500, 121505, 121510, 121515, 121520, 121525, 121530, 121535, - 121540, 121545, 121550, 121555, 121560, 121565, 121570, 121575, 121580, - 121585, 121590, 121595, 121600, 121605, 121610, 121615, 121620, 121625, - 121630, 121635, 121640, 121645, 121650, 121655, 121660, 121665, 121670, - 121675, 121680, 121685, 121690, 121695, 121700, 121705, 121710, 121715, - 121720, 121725, 121730, 121735, 121740, 121745, 121750, 121755, 121760, - 121765, 121770, 121775, 121780, 121785, 121790, 121795, 121800, 121805, - 121810, 121815, 121820, 121825, 121830, 121835, 121840, 121845, 121850, - 121855, 121860, 121865, 121870, 121875, 121880, 121885, 121890, 121895, - 121900, 121905, 121910, 121915, 121920, 121925, 121930, 121935, 121940, - 121945, 121950, 121955, 121960, 121965, 121970, 121975, 121980, 121985, - 121990, 121995, 122000, 122005, 122010, 122015, 122020, 122025, 122030, - 122035, 122040, 122045, 122050, 122055, 122060, 122065, 122070, 122075, - 122080, 122086, 122091, 122096, 122101, 122106, 122111, 122116, 122121, - 122127, 122132, 122137, 122142, 122147, 122152, 122157, 122162, 122167, - 122172, 122177, 122182, 122187, 122192, 122197, 122202, 122207, 122212, - 122217, 122222, 122227, 122232, 122237, 122242, 122247, 122252, 122257, - 122262, 122267, 122272, 122277, 122282, 122287, 122296, 122301, 122310, - 122315, 122324, 122329, 122338, 122343, 122352, 122357, 122366, 122371, - 122380, 122385, 122394, 122399, 122404, 122413, 122417, 122426, 122431, - 122440, 122445, 122454, 122459, 122468, 122473, 122482, 122487, 122496, - 122501, 122510, 122515, 122524, 122529, 122538, 122543, 122552, 122557, - 122562, 122567, 122572, 122577, 122582, 122587, 122591, 122596, 122601, - 122606, 122611, 122616, 122621, 122627, 122632, 122637, 122642, 122648, - 122652, 122657, 122663, 122668, 122673, 122678, 122683, 122688, 122693, - 122698, 122703, 122708, 122713, 122719, 122724, 122729, 122734, 122740, - 122745, 122750, 122755, 122760, 122766, 122771, 122776, 122781, 122786, - 122791, 122797, 122802, 122807, 122812, 122817, 122822, 122827, 122832, - 122837, 122842, 122847, 122852, 122857, 122862, 122867, 122872, 122877, - 122882, 122887, 122892, 122897, 122902, 122907, 122912, 122918, 122924, - 122930, 122935, 122940, 122945, 122950, 122956, 122962, 122968, 122973, - 122978, 122983, 122989, 122994, 122999, 123004, 123009, 123014, 123019, - 123024, 123029, 123034, 123039, 123044, 123049, 123054, 123059, 123064, - 123069, 123075, 123081, 123087, 123092, 123097, 123102, 123107, 123113, - 123119, 123125, 123130, 123135, 123140, 123145, 123150, 123155, 123160, - 123165, 123170, 19463, 123175, 123181, 123186, 123191, 123196, 123201, - 123206, 123212, 123217, 123222, 123227, 123232, 123237, 123243, 123248, - 123253, 123258, 123263, 123268, 123273, 123278, 123283, 123288, 123293, - 123298, 123303, 123308, 123313, 123318, 123323, 123328, 123333, 123338, - 123343, 123348, 123353, 123359, 123364, 123369, 123374, 123379, 123384, - 123389, 123394, 123399, 123404, 123409, 123414, 123419, 123424, 123429, - 123434, 123439, 123444, 123449, 123454, 123459, 123464, 123469, 123474, - 123479, 123484, 123489, 123494, 123499, 123504, 123509, 123514, 123519, - 123524, 123529, 123534, 123539, 123544, 123549, 123554, 123559, 123565, - 123570, 123575, 123580, 123585, 123590, 123595, 123600, 123605, 123610, - 123615, 123620, 123626, 123631, 123637, 123642, 123647, 123652, 123657, - 123662, 123667, 123673, 123678, 123683, 123689, 123694, 123699, 123704, - 123709, 123714, 123720, 123726, 123731, 123736, 14614, 123741, 123746, - 123751, 123756, 123761, 123766, 123771, 123776, 123781, 123786, 123791, - 123796, 123801, 123806, 123811, 123816, 123821, 123826, 123831, 123836, - 123841, 123846, 123851, 123856, 123861, 123866, 123871, 123876, 123881, - 123886, 123891, 123896, 123901, 123906, 123911, 123916, 123921, 123926, - 123931, 123936, 123941, 123946, 123951, 123956, 123961, 123966, 123971, - 123976, 123981, 123986, 123991, 123996, 124001, 124006, 124011, 124016, - 124021, 124026, 124031, 124036, 124041, 124046, 124051, 124056, 124061, - 124067, 124072, 124077, 124082, 124087, 124093, 124098, 124103, 124108, - 124113, 124118, 124123, 124129, 124134, 124139, 124144, 124149, 124154, - 124160, 124165, 124170, 124175, 124180, 124185, 124191, 124196, 124201, - 124206, 124211, 124216, 124222, 124228, 124233, 124238, 124243, 124249, - 124255, 124261, 124266, 124271, 124277, 124283, 124288, 124294, 124300, - 124306, 124311, 124316, 124322, 124327, 124333, 124338, 124344, 124353, - 124358, 124363, 124369, 124374, 124380, 124385, 124390, 124395, 124400, - 124405, 124410, 124415, 124420, 124425, 124430, 124435, 124440, 124445, - 124450, 124455, 124460, 124465, 124470, 124475, 124480, 124485, 124490, - 124495, 124500, 124505, 124510, 124515, 124520, 124525, 124530, 124535, - 124541, 124547, 124553, 124558, 124563, 124568, 124573, 124578, 124583, - 124588, 124593, 124598, 124603, 124608, 124613, 124618, 124623, 124628, - 124633, 124638, 124643, 124648, 124653, 124659, 124665, 124670, 124676, - 124681, 124686, 124692, 124697, 124703, 124708, 124714, 124719, 124725, - 124730, 124736, 124741, 124746, 124751, 124756, 124761, 124766, 124771, - 120849, 120855, 120861, 120867, 124777, 120873, 120879, 124783, 120885, - 120891, 120897, 120903, 120909, 120915, 120921, 120927, 120933, 124789, - 120939, 120945, 120951, 124795, 120957, 120963, 120969, 120975, 124801, - 120981, 120987, 120993, 121013, 124807, 124813, 121019, 124819, 121025, - 121031, 121037, 121043, 121049, 124825, 3331, 3336, 124830, 3351, 3356, - 3361, 124835, 124838, 124844, 124850, 124857, 124862, 124867, 2380, + 22671, 22682, 22694, 22706, 22718, 22730, 22742, 22754, 22766, 22778, + 22790, 22802, 22813, 22825, 22837, 22849, 22861, 22873, 22885, 22897, + 22909, 22921, 22933, 22944, 22956, 22968, 22980, 22992, 23005, 23018, + 23031, 23044, 23057, 23070, 23083, 23095, 23108, 23121, 23134, 23147, + 23160, 23173, 23186, 23199, 23212, 23225, 23237, 23250, 23263, 23276, + 23289, 23302, 23315, 23328, 23341, 23354, 23367, 23379, 23392, 23405, + 23418, 23431, 23444, 23457, 23470, 23483, 23496, 23509, 23521, 23534, + 23547, 23560, 23573, 23586, 23599, 23612, 23625, 23638, 23651, 23663, + 23676, 23689, 23702, 23715, 23728, 23741, 23754, 23767, 23780, 23793, + 23805, 23816, 23829, 23842, 23855, 23868, 23881, 23894, 23907, 23920, + 23933, 23946, 23958, 23971, 23984, 23997, 24010, 24023, 24036, 24049, + 24062, 24075, 24088, 24100, 24113, 24126, 24139, 24152, 24165, 24178, + 24191, 24204, 24217, 24230, 24242, 24255, 24268, 24281, 24294, 24307, + 24320, 24333, 24346, 24359, 24372, 24384, 24397, 24410, 24423, 24436, + 24449, 24462, 24475, 24488, 24501, 24514, 24526, 24539, 24552, 24565, + 24578, 24591, 24604, 24617, 24630, 24643, 24656, 24668, 24681, 24694, + 24707, 24720, 24733, 24746, 24759, 24772, 24785, 24798, 24810, 24823, + 24836, 24849, 24862, 24875, 24888, 24901, 24914, 24927, 24940, 24952, + 24965, 24978, 24991, 25004, 25017, 25030, 25043, 25056, 25069, 25082, + 25094, 25107, 25120, 25133, 25146, 25159, 25172, 25185, 25198, 25211, + 25224, 25236, 25247, 25256, 25264, 25272, 25279, 25285, 25289, 25295, + 25301, 25310, 25318, 25323, 25329, 25334, 25338, 25347, 10492, 25358, + 25364, 25371, 25379, 25386, 13145, 13159, 25393, 25400, 25409, 25414, + 25419, 25426, 25431, 25436, 8778, 8784, 8790, 25441, 25446, 25449, 25454, + 25462, 25469, 25476, 25488, 25495, 25501, 25510, 25515, 25524, 25533, + 25539, 25547, 25556, 25560, 25566, 25571, 25581, 25588, 25594, 25602, + 25608, 25615, 25621, 25631, 25640, 25644, 25651, 25655, 25660, 25666, + 25674, 25678, 25688, 17372, 25697, 25703, 25707, 25716, 25725, 25735, + 25741, 17377, 25748, 25755, 25766, 25774, 25784, 25793, 25801, 10207, + 25809, 25814, 25820, 25825, 25829, 25833, 25837, 11301, 25842, 25850, + 25857, 25866, 25874, 25881, 25888, 25897, 25903, 1062, 25910, 25916, + 25920, 25926, 25933, 25939, 25947, 25953, 25960, 25966, 25972, 25981, + 25985, 25993, 26001, 26008, 26017, 26024, 26029, 26033, 26043, 26054, + 26065, 26070, 26075, 26081, 26090, 26095, 26108, 9000, 26112, 26118, + 26124, 26130, 26135, 26143, 26147, 26154, 26163, 26168, 17650, 26176, + 26180, 26192, 26197, 26201, 26204, 26210, 26216, 26222, 26227, 26232, + 26236, 26239, 26250, 26255, 10769, 26262, 26267, 26272, 26277, 26282, + 26287, 26292, 26297, 26302, 10774, 26307, 26312, 26317, 26322, 26327, + 26332, 26337, 26342, 26347, 26352, 26357, 26362, 26368, 26373, 26378, + 26383, 26388, 26393, 26398, 26403, 26408, 26413, 26419, 26425, 26430, + 26435, 26440, 26445, 26450, 26455, 26460, 26465, 26470, 26476, 26481, + 26486, 26491, 26497, 26503, 26508, 26513, 26518, 26523, 26528, 26533, + 26538, 26543, 26549, 26554, 26559, 26564, 26569, 26575, 26580, 26585, + 26589, 1244, 145, 26597, 26601, 26605, 26609, 26614, 26618, 15736, 2409, + 26622, 26627, 26631, 26636, 26640, 26645, 26649, 26655, 26660, 26664, + 26668, 26676, 26680, 26684, 26691, 26696, 26701, 26705, 26711, 26716, + 26720, 26725, 26730, 26734, 26741, 26748, 26755, 26760, 26764, 26768, + 26773, 26777, 26780, 26786, 26799, 26804, 26810, 26819, 26824, 11049, + 26829, 26838, 26843, 26846, 26850, 26855, 26860, 26865, 26870, 26875, + 2920, 2925, 26880, 26886, 26890, 26896, 3888, 26901, 26906, 26911, 26917, + 26922, 16698, 26927, 26932, 26937, 26942, 26948, 26953, 26958, 26964, + 26969, 26973, 26978, 26983, 26988, 26993, 26998, 27002, 27007, 27011, + 27016, 27021, 27026, 27031, 27035, 27040, 27044, 27049, 27054, 27059, + 26974, 3121, 26979, 27064, 27072, 27079, 11395, 27091, 27099, 27109, + 27127, 27146, 27155, 27163, 26984, 27170, 27175, 27183, 26989, 27188, + 27193, 27201, 27206, 27211, 27215, 19870, 27220, 27228, 27233, 27237, + 27244, 27250, 27259, 27263, 27271, 27277, 27281, 27284, 20704, 27291, + 27295, 27299, 27304, 27310, 27317, 27322, 10234, 27326, 27331, 27336, + 27341, 27346, 27351, 1663, 1668, 27356, 27362, 27368, 27373, 27377, + 27381, 27385, 27389, 27393, 27397, 27401, 27405, 25482, 27408, 27415, + 27423, 27429, 27435, 27440, 27445, 27451, 27455, 27460, 27467, 16598, + 16605, 27473, 27485, 27488, 27495, 27499, 19895, 27506, 27514, 27525, + 27534, 27547, 27557, 27571, 27583, 27597, 27610, 27622, 27632, 27644, + 27650, 27665, 27689, 27707, 27726, 27739, 27753, 27771, 27787, 27804, + 27822, 27833, 27852, 27869, 27889, 27907, 27919, 27933, 27947, 27959, + 27976, 27995, 28013, 28025, 28043, 28062, 17530, 28075, 28095, 28107, + 12577, 28119, 28124, 28129, 28134, 28143, 28149, 28154, 28158, 28165, + 28171, 28175, 28180, 28185, 28190, 28195, 28200, 28205, 2506, 28210, + 28216, 28220, 28223, 28234, 28238, 28241, 28249, 28255, 14882, 28259, + 28268, 28279, 28285, 28291, 28306, 28315, 28323, 28330, 28335, 28339, + 28346, 28352, 28361, 28369, 28376, 28386, 28395, 28405, 28410, 28419, + 28428, 28439, 28450, 28460, 28477, 4557, 28487, 28491, 28501, 28509, + 28519, 28530, 28536, 28541, 28551, 28559, 28566, 28572, 28579, 28584, + 27022, 28588, 28597, 28601, 28604, 28609, 28617, 28624, 28633, 28641, + 28649, 28657, 28667, 28676, 28682, 28688, 28694, 28698, 27027, 27032, + 28702, 28712, 28722, 28732, 28740, 28747, 28757, 28765, 28773, 28779, + 28787, 28798, 798, 28807, 17737, 649, 28821, 28830, 28838, 28849, 28860, + 28870, 28879, 28891, 28900, 28909, 28916, 28922, 28932, 28941, 28950, + 28958, 28966, 28976, 28984, 28992, 28999, 29005, 29010, 29015, 29020, + 8156, 29025, 29028, 29032, 29037, 29045, 29051, 29056, 29060, 3751, + 27045, 29068, 27050, 29074, 29080, 29086, 29091, 29096, 29100, 29108, + 29114, 29120, 29124, 3912, 29132, 29137, 29142, 29146, 29150, 11681, + 29157, 29165, 29179, 29186, 29193, 29199, 11690, 11696, 29207, 29215, + 29222, 29227, 29232, 27055, 29238, 29249, 29258, 19043, 29266, 29271, + 2755, 29276, 29287, 29293, 29298, 29302, 29306, 29309, 29316, 29323, + 29329, 29337, 29344, 29350, 29354, 8196, 29359, 29363, 29367, 29375, + 29380, 29385, 29390, 1696, 29395, 29400, 29405, 29410, 29415, 29420, + 29425, 29430, 29435, 29440, 29445, 29450, 29455, 29460, 29466, 29471, + 29476, 29481, 29486, 29491, 29496, 29502, 29507, 29512, 29517, 29522, + 29527, 29532, 29537, 29543, 29549, 29554, 29560, 29565, 29570, 5, 29576, + 29580, 29584, 29588, 29593, 29597, 29601, 29605, 29609, 29614, 29618, + 29623, 29627, 29630, 29634, 29639, 29643, 29648, 29652, 29656, 29660, + 29665, 29669, 29673, 29683, 29688, 29692, 29696, 29701, 29706, 29715, + 29720, 29725, 29729, 29733, 29742, 29755, 29767, 29776, 29785, 29790, + 29796, 29801, 29805, 29809, 29819, 29828, 29836, 29842, 29847, 29851, + 29858, 29865, 29875, 29884, 29892, 12934, 29900, 29907, 29915, 29924, + 29933, 29941, 29951, 29956, 29960, 29964, 29967, 29969, 29973, 29977, + 29982, 29987, 29991, 29995, 29998, 30002, 30005, 30009, 30012, 30015, + 30019, 30025, 30029, 30033, 30037, 30041, 30046, 30051, 30056, 30060, + 30063, 30068, 30074, 30079, 30085, 30090, 30094, 30100, 30104, 30108, + 30113, 30117, 30122, 30127, 30131, 30135, 30142, 30146, 30149, 30153, + 30157, 30163, 30168, 30174, 30178, 30182, 30187, 30194, 30200, 30204, + 30213, 30217, 30221, 30224, 30230, 30235, 30241, 1385, 1748, 30246, + 30251, 30256, 30261, 30266, 30271, 30276, 2213, 827, 30281, 30284, 30288, + 30292, 30297, 30301, 17749, 30305, 30310, 30315, 30319, 30322, 30327, + 30331, 30336, 30340, 17753, 30345, 30348, 30351, 30357, 30361, 30366, + 30370, 30383, 30391, 30395, 30398, 30406, 30415, 30422, 30427, 30433, + 30439, 30447, 30454, 30461, 30465, 30469, 30473, 30478, 30483, 30487, + 30495, 30500, 30507, 30519, 30530, 30535, 30539, 30546, 30550, 30555, + 30561, 30564, 30569, 30574, 30581, 30585, 30589, 30592, 30598, 8900, + 2413, 30602, 30607, 30623, 11100, 30643, 30652, 30668, 30672, 30679, + 30682, 30688, 30698, 30704, 30713, 30722, 30737, 30748, 30760, 30771, + 30779, 30788, 30794, 30803, 30813, 30823, 30834, 30845, 30855, 30864, + 30871, 30880, 30888, 30895, 30902, 30909, 30917, 30924, 30931, 30944, + 30951, 30959, 30966, 30972, 30977, 30986, 30993, 30999, 31004, 31012, + 31020, 31027, 31034, 28511, 31046, 31058, 31072, 31080, 31088, 31096, + 31103, 31115, 31124, 31133, 31141, 31149, 31157, 31164, 31170, 31179, + 31187, 31197, 31206, 31216, 31225, 31234, 31242, 31247, 31251, 31254, + 31258, 31262, 31266, 31270, 31274, 31280, 31286, 31291, 31299, 31306, + 31314, 31321, 10806, 17811, 31329, 31336, 31341, 31348, 31354, 31360, + 31367, 14024, 31374, 31377, 31389, 31397, 31403, 31408, 31412, 31423, + 31433, 31443, 11620, 31452, 31461, 31469, 31479, 31488, 31495, 31502, + 31510, 31514, 17830, 31517, 31524, 31528, 4501, 31534, 31537, 31544, + 31550, 31564, 31569, 31577, 31583, 31594, 31601, 31607, 31613, 31617, + 31622, 31626, 31635, 31642, 31648, 8953, 31655, 31663, 31670, 31676, + 31681, 31687, 31693, 31703, 31715, 31726, 31736, 11252, 31744, 31750, + 17848, 31754, 31756, 31259, 11633, 31765, 31770, 31776, 31786, 31791, + 31798, 31806, 31812, 31817, 31822, 31827, 31831, 31836, 31843, 31849, + 31858, 31866, 31870, 31877, 31887, 31893, 31902, 31908, 31915, 4771, + 31921, 31927, 31932, 31939, 31951, 31962, 31967, 31975, 31979, 31989, + 31995, 31999, 32004, 32014, 32023, 32027, 32034, 32042, 32049, 32055, + 32060, 32068, 32075, 32080, 32087, 32099, 32108, 32112, 32120, 15656, + 32124, 32134, 32138, 32146, 32153, 32160, 30402, 32171, 32176, 32180, + 32187, 32194, 26707, 31184, 32199, 32203, 32206, 27839, 32211, 32225, + 32241, 32259, 32278, 32295, 32313, 27858, 32330, 32350, 27875, 32362, + 32374, 19099, 32386, 27895, 32400, 32412, 12590, 32426, 32431, 32436, + 32441, 32447, 32453, 32459, 32463, 32471, 32477, 32484, 32489, 32499, + 32506, 32512, 12128, 32518, 32520, 32525, 32533, 32537, 31839, 32543, + 32550, 13866, 13876, 32557, 32564, 32574, 32579, 32583, 32586, 32592, + 32600, 32612, 32622, 32638, 32651, 32665, 19117, 32679, 32686, 32690, + 32693, 32698, 32702, 32709, 32716, 32723, 32730, 32740, 32745, 32750, + 32755, 32763, 32771, 32776, 32785, 28532, 3561, 32790, 32793, 32796, + 32801, 32808, 32813, 32818, 32834, 32842, 32850, 10864, 32858, 32863, + 32867, 32873, 32878, 32884, 32887, 32893, 32905, 32913, 32920, 32926, + 32933, 32944, 32958, 32971, 32977, 32986, 32992, 33001, 33013, 33024, + 33034, 33043, 33052, 33060, 33070, 33079, 33090, 673, 33097, 33104, + 33110, 33115, 33121, 33128, 33134, 33145, 33155, 33165, 33174, 33180, + 33187, 33192, 33200, 33207, 33215, 33223, 33235, 7142, 33242, 33245, + 33254, 33262, 33268, 33274, 33279, 33283, 33286, 33292, 33299, 33304, + 33309, 33316, 33321, 33325, 33337, 33348, 33357, 33365, 18020, 33370, + 33378, 33383, 33391, 33397, 33403, 33408, 13859, 9802, 33411, 33415, + 33419, 33422, 33425, 33431, 33439, 33447, 33451, 33455, 33460, 33464, + 33467, 33476, 33481, 33486, 33490, 33493, 33498, 33506, 33517, 33526, + 33530, 33536, 33542, 33546, 33552, 33560, 33582, 33606, 33617, 33626, + 33632, 33639, 33646, 33652, 33660, 33666, 33671, 33682, 33700, 33707, + 33715, 33719, 33726, 33731, 33740, 33753, 33761, 33773, 33784, 33795, + 33805, 33819, 33828, 33836, 33848, 33859, 11117, 33868, 33879, 33890, + 33902, 33912, 33921, 33931, 33936, 33940, 33948, 33959, 33969, 33975, + 33980, 33984, 33987, 33990, 33998, 34006, 34015, 34025, 34034, 34040, + 34045, 34059, 2838, 34081, 34092, 34101, 34111, 34123, 34132, 34141, + 34151, 34159, 34167, 34176, 34181, 34192, 34197, 34206, 34212, 34223, + 34227, 34230, 34240, 34249, 34257, 34267, 34277, 34285, 34294, 34301, + 34307, 34315, 34322, 34331, 34340, 34345, 34350, 34354, 34362, 34369, + 34375, 34379, 34387, 34394, 34405, 34420, 34427, 34433, 34443, 34452, + 34458, 34469, 34473, 34480, 34484, 34491, 34497, 16850, 34503, 34507, + 34512, 34518, 34525, 34529, 34533, 34541, 34549, 34555, 34564, 34571, + 34578, 34583, 34588, 34598, 28586, 34602, 34605, 34610, 34615, 34620, + 34625, 34630, 34635, 34640, 34645, 34651, 34656, 34661, 34667, 1094, 770, + 34672, 34675, 34682, 34691, 1777, 34698, 34703, 34707, 34713, 1143, 643, + 34718, 347, 34722, 34732, 34741, 34749, 34758, 34766, 34773, 34784, + 34792, 34801, 34809, 34819, 34827, 34832, 11794, 34836, 34844, 34852, + 34857, 17766, 4101, 34863, 34869, 34875, 6669, 34880, 34884, 34891, + 34897, 34903, 34907, 34916, 34922, 34927, 34934, 1336, 34940, 34946, + 34951, 34958, 34962, 1243, 6677, 34967, 34977, 34985, 34991, 35001, + 35010, 35018, 35024, 35029, 35037, 35044, 13376, 35050, 35057, 35062, + 35068, 35075, 35085, 1404, 253, 2212, 35091, 35097, 35104, 35115, 35126, + 35134, 35141, 35151, 35160, 35168, 35177, 35184, 35191, 35204, 35211, + 35217, 35228, 35247, 35252, 1148, 35256, 35261, 35269, 3984, 35273, + 35278, 35282, 35286, 1340, 29996, 35296, 35300, 35305, 35309, 35315, + 3846, 35321, 35329, 35336, 35347, 35356, 35364, 35389, 35397, 35402, + 3985, 401, 35408, 35416, 35424, 35431, 35436, 35442, 35447, 2281, 12792, + 35454, 35460, 31618, 31957, 35466, 656, 106, 35470, 35474, 35480, 595, + 10679, 35485, 35490, 35497, 35503, 35507, 35511, 1549, 35514, 35518, + 18308, 35521, 35526, 35533, 35539, 8966, 35544, 35552, 35559, 35565, + 27217, 35569, 35573, 35577, 35581, 1834, 20216, 35585, 35590, 35594, + 35597, 35605, 35613, 35618, 35627, 35635, 35638, 35645, 35652, 35664, + 27296, 35674, 35686, 35694, 35699, 35703, 35711, 35718, 35725, 35734, + 35740, 35747, 35754, 35757, 35761, 35765, 1351, 35775, 35777, 35782, + 35788, 35794, 35799, 35804, 35809, 35814, 35819, 35824, 35829, 35834, + 35839, 35844, 35849, 35854, 35859, 35864, 35870, 35876, 35882, 35888, + 35893, 35898, 35903, 35909, 35914, 35919, 35924, 35930, 35935, 35941, + 35946, 35951, 35956, 35961, 35967, 35972, 35978, 35983, 35988, 35993, + 35998, 36004, 36009, 36015, 36020, 36025, 36030, 36035, 36040, 36045, + 36050, 36055, 36060, 36066, 36072, 36078, 36083, 36088, 36093, 36098, + 36104, 36110, 36116, 36122, 36128, 36134, 36139, 36145, 36150, 36155, + 36160, 36165, 36171, 2552, 36176, 2559, 2566, 2962, 36181, 2572, 2582, + 36187, 2614, 2619, 2624, 36191, 36196, 36201, 36207, 36212, 36217, 36221, + 36226, 36232, 36237, 36242, 36247, 36253, 36258, 36262, 36266, 36271, + 36276, 36281, 36286, 36291, 36297, 36303, 36308, 36312, 36317, 36323, + 36327, 36332, 36337, 36342, 36347, 36351, 36354, 36359, 36364, 36369, + 36374, 36379, 36385, 36391, 36396, 36401, 36406, 36410, 36415, 36420, + 36425, 36430, 36435, 36440, 36444, 36449, 36454, 36459, 36463, 36467, + 36471, 36476, 36484, 36489, 36494, 36500, 36506, 36512, 36517, 36525, + 36529, 36532, 36537, 36542, 36546, 36551, 36556, 36560, 36565, 36569, + 36572, 36577, 4211, 21707, 36582, 36587, 36592, 36597, 36605, 25877, + 34955, 10318, 36610, 36615, 36619, 36624, 36628, 36632, 36637, 36641, + 36644, 36647, 36651, 36656, 36660, 36668, 36672, 36675, 36680, 36684, + 36688, 36693, 36698, 36702, 36708, 36713, 36718, 36725, 36732, 36736, + 36739, 36745, 36754, 36761, 36769, 36776, 36780, 36785, 36789, 36793, + 36799, 36804, 36810, 36814, 36820, 36825, 36830, 36834, 36841, 36847, + 36853, 36859, 36865, 36872, 36878, 36884, 36890, 36896, 36902, 36908, + 36914, 36921, 36927, 36934, 36940, 36946, 36952, 36958, 36964, 36970, + 36976, 36982, 36988, 36994, 36999, 37004, 13731, 37009, 37015, 37020, + 37025, 37030, 37035, 37038, 37044, 37049, 37057, 37062, 37066, 37071, + 37077, 37086, 37092, 37097, 37102, 37107, 37111, 37116, 37120, 37125, + 37130, 37135, 37140, 37147, 37154, 37160, 37166, 37171, 19813, 37178, + 37184, 37191, 37197, 37203, 37208, 37216, 37221, 11288, 37225, 37230, + 37235, 37241, 37246, 37251, 37255, 37260, 37265, 37271, 37276, 37281, + 37286, 37290, 37295, 37300, 37304, 37309, 37314, 37318, 37323, 37327, + 37332, 37337, 37342, 37346, 37351, 37355, 37360, 37364, 37371, 37375, + 37379, 18464, 37384, 37391, 37400, 37406, 37412, 37421, 37429, 37438, + 37446, 37451, 37455, 37462, 37468, 37476, 37480, 37483, 37488, 37492, + 37501, 37509, 37527, 37533, 1403, 37539, 37542, 37546, 27363, 27369, + 37552, 37556, 37567, 37578, 37589, 37601, 37605, 37612, 37619, 37626, + 37631, 37635, 37643, 37648, 37653, 37658, 37663, 6734, 16754, 25876, + 37668, 37673, 37677, 16745, 37682, 37688, 37693, 37699, 37704, 37710, + 37715, 37721, 37726, 37732, 37738, 37744, 37749, 37705, 37711, 37753, + 37758, 37764, 37769, 37775, 37780, 37786, 37791, 37716, 12422, 37795, + 37727, 37733, 37739, 3054, 3760, 37801, 37804, 37809, 37815, 37821, + 37827, 37834, 37840, 37846, 37852, 37858, 37864, 37870, 37876, 37882, + 37888, 37894, 37900, 37906, 37913, 37919, 37925, 37931, 37937, 37943, + 37946, 37951, 37954, 37961, 37966, 37974, 37978, 37983, 37988, 37994, + 37999, 38004, 38008, 38013, 38019, 38024, 38030, 38035, 38041, 38046, + 38052, 38058, 38062, 38067, 38072, 38077, 38082, 38086, 38091, 38096, + 38101, 38107, 38113, 38119, 38125, 38130, 38134, 38137, 38143, 38149, + 38158, 38166, 38173, 38178, 38182, 38186, 38191, 18251, 38196, 38204, + 38210, 4152, 1253, 38215, 38220, 38224, 9016, 38230, 38236, 38243, 9025, + 38247, 38253, 38259, 38266, 38272, 38281, 38289, 38301, 38310, 38314, + 38321, 38327, 38332, 38336, 38340, 38343, 38353, 38362, 38370, 37706, + 38375, 38385, 38395, 38405, 38411, 38416, 38426, 38431, 38444, 38458, + 38469, 38481, 38493, 38507, 38520, 38532, 38544, 17571, 38558, 38563, + 38568, 38572, 38576, 38580, 38584, 38590, 38595, 38600, 38605, 38610, + 38615, 38620, 1737, 33022, 38625, 38630, 38635, 37754, 38640, 38643, + 38648, 38653, 38658, 38664, 38670, 19423, 11994, 38675, 38681, 38688, + 19051, 38694, 38699, 38704, 38708, 38713, 38718, 37759, 38723, 38728, + 38733, 38739, 37765, 38744, 38747, 38754, 38762, 38768, 38774, 38780, + 38791, 38796, 38803, 38810, 38817, 38825, 38834, 38843, 38849, 38855, + 38863, 37770, 38868, 38874, 38880, 37776, 38885, 38890, 38898, 38906, + 38912, 38919, 38925, 38932, 38939, 38945, 38953, 38963, 38970, 38976, + 38981, 38987, 38992, 38997, 39004, 39013, 39021, 39026, 39032, 39039, + 39047, 39053, 39058, 39064, 39073, 39080, 34020, 39086, 39090, 39095, + 39104, 39109, 39114, 39119, 14972, 39127, 39132, 39137, 39142, 39146, + 39151, 39156, 39163, 39168, 39173, 39178, 37781, 25805, 39184, 2655, 158, + 39187, 39190, 39194, 39198, 39208, 39216, 39223, 39227, 39231, 39234, + 39242, 39249, 39256, 31911, 39265, 39268, 39275, 39281, 39286, 39290, + 39297, 39301, 39309, 39317, 39324, 39339, 39343, 39347, 39350, 39356, + 39363, 39367, 39373, 39377, 39384, 39392, 39400, 39407, 37717, 39414, + 39422, 39427, 39439, 12075, 12082, 12089, 12096, 12103, 12110, 626, 434, + 39445, 39450, 39455, 39461, 39466, 39471, 4178, 39476, 39479, 39484, + 39489, 39494, 39499, 39504, 39511, 27481, 39516, 39521, 39526, 39531, + 39536, 39542, 39547, 39553, 37957, 39559, 39564, 39570, 39576, 39586, + 39591, 39596, 39600, 39605, 39610, 39615, 39620, 39633, 39638, 27095, + 20298, 1064, 39642, 39648, 39652, 39657, 39662, 39668, 39673, 39678, + 39682, 39687, 39692, 39698, 39703, 39708, 1258, 39712, 39717, 39722, + 39727, 39731, 39736, 39741, 39746, 39752, 39758, 39763, 39767, 39771, + 39776, 39781, 39786, 39790, 39795, 39803, 39807, 39813, 39817, 39824, + 39833, 20069, 37728, 39839, 39846, 39854, 39862, 39869, 39875, 39884, + 39897, 39909, 39914, 39920, 39924, 2981, 39928, 39932, 39358, 39941, + 39952, 39963, 39968, 34088, 39973, 39978, 39982, 34208, 27374, 39987, + 39994, 39998, 40003, 37734, 25912, 40007, 40012, 40018, 40023, 40027, + 40031, 40034, 40038, 40044, 40053, 40064, 40076, 37740, 40081, 40084, + 40088, 40092, 40097, 40102, 40107, 40112, 40117, 40122, 40127, 40132, + 373, 40137, 40142, 40147, 40152, 40157, 40162, 40168, 40173, 40178, + 40184, 40189, 40195, 40200, 40206, 40211, 40216, 40221, 40226, 40231, + 40236, 40241, 40246, 40252, 40257, 40262, 40267, 40272, 40277, 40282, + 40287, 40293, 40299, 40304, 40309, 40314, 40319, 40324, 40329, 40334, + 40339, 40344, 40349, 40354, 40359, 40364, 40369, 40374, 40379, 40384, + 40389, 40399, 40409, 40415, 342, 14, 40420, 40423, 40427, 40431, 40439, + 40443, 40447, 31591, 16987, 1818, 40450, 40455, 40459, 40464, 40468, + 40473, 40477, 40482, 40486, 40489, 40491, 40495, 40500, 40504, 40515, + 40518, 40520, 40524, 40536, 40548, 40557, 40561, 40571, 40575, 40581, + 40586, 40595, 40601, 40606, 40611, 40615, 40619, 40624, 40631, 40636, + 40642, 40647, 40651, 40658, 31192, 31202, 40662, 40667, 40672, 40677, + 40684, 40688, 40695, 40702, 40708, 9171, 40712, 40721, 40729, 40744, + 40758, 40767, 40775, 40786, 40795, 40800, 40807, 40817, 8165, 40827, + 40832, 40838, 40843, 40847, 40850, 40855, 40859, 40864, 40868, 40875, + 40880, 40885, 40890, 40900, 40905, 40910, 40915, 10188, 40920, 40922, + 40930, 40933, 40936, 40944, 40959, 40967, 40977, 40979, 40982, 40986, + 40992, 40996, 41001, 41006, 41024, 41038, 41057, 41074, 41083, 41091, + 41096, 41101, 1396, 41107, 41113, 41118, 41128, 41137, 41145, 41150, + 41156, 41161, 41170, 41179, 41190, 41195, 41202, 41208, 41212, 41221, + 41228, 41236, 41243, 41256, 41264, 41268, 41278, 41284, 41289, 41293, + 41301, 41309, 41314, 41318, 41322, 41331, 41337, 41342, 41350, 41360, + 41369, 41378, 41387, 41398, 41406, 41417, 41426, 41434, 41441, 41447, + 41452, 41463, 41474, 41479, 41483, 41486, 41490, 41500, 41508, 41514, + 41525, 41536, 41547, 41558, 41569, 41580, 41591, 41602, 41614, 41626, + 41638, 41650, 41662, 41674, 41686, 41695, 41699, 41707, 41713, 41719, + 41726, 41732, 41737, 41743, 41747, 41752, 41757, 41762, 40394, 40404, + 2526, 41767, 41769, 41774, 41779, 41784, 41787, 41789, 41793, 41796, + 41803, 41807, 11644, 41811, 41817, 41824, 41830, 41840, 41845, 41851, + 41855, 41860, 41873, 31781, 41879, 41885, 41894, 41903, 21930, 41910, + 41919, 41927, 38391, 41933, 41938, 41942, 41951, 41959, 41966, 41971, + 41975, 41980, 41985, 41993, 41997, 42005, 42011, 42017, 42022, 42027, + 42031, 42034, 42039, 42052, 42068, 27965, 42085, 42097, 42114, 42126, + 42140, 27982, 28001, 42152, 42164, 2855, 42178, 42183, 42188, 42193, + 42197, 42204, 42216, 42223, 42232, 42242, 42245, 42256, 42267, 42275, + 42280, 42284, 42289, 42294, 42299, 42304, 42309, 42314, 1768, 947, 42319, + 42323, 42327, 42330, 42335, 42340, 42346, 42351, 42356, 42362, 42368, + 42373, 42377, 42382, 42387, 42392, 42396, 42399, 42405, 42410, 42415, + 42420, 42424, 42429, 42435, 42443, 32092, 42448, 42453, 42460, 42466, + 42472, 42477, 42485, 27490, 42492, 42497, 42502, 42507, 42511, 42514, + 42519, 42523, 42527, 42534, 42540, 42546, 42552, 42559, 42564, 42570, + 41304, 42574, 42578, 42583, 42596, 42601, 42607, 42615, 42622, 42630, + 42640, 42646, 42652, 42658, 42662, 42671, 42679, 42686, 42691, 42696, + 12445, 42701, 42711, 42718, 42724, 42734, 42739, 42745, 42753, 4017, + 42760, 42767, 42773, 42780, 4023, 42784, 42789, 42800, 42807, 42813, + 42822, 42826, 42829, 4609, 42836, 42843, 42849, 42855, 42863, 42873, + 35437, 42880, 42888, 42894, 42899, 42905, 42910, 42914, 31540, 42920, + 42927, 42933, 42941, 42950, 42957, 42963, 42974, 28784, 42980, 42987, + 42993, 43003, 43008, 43012, 43020, 43028, 43035, 43041, 43046, 11246, + 941, 43051, 43055, 43057, 43061, 43066, 43069, 43071, 43076, 43082, + 43087, 43092, 43099, 39507, 43105, 43110, 43114, 43119, 43123, 43132, + 43136, 43142, 43149, 43155, 43162, 43167, 43176, 43181, 43185, 43190, + 43197, 43205, 43213, 43218, 25968, 43222, 43225, 43229, 43233, 12889, + 1005, 43237, 43242, 43250, 43255, 43259, 43268, 43275, 43279, 43283, + 43291, 43298, 16272, 43308, 43312, 43316, 43324, 43332, 43338, 43343, + 43347, 43356, 16008, 43362, 43371, 43378, 43383, 43390, 43397, 43405, + 43412, 43420, 43428, 43437, 43442, 43449, 43456, 43463, 43470, 43477, + 43482, 43489, 43495, 43512, 43520, 43530, 43538, 43545, 43553, 461, + 43557, 43563, 43567, 43572, 40791, 43578, 43581, 43585, 43591, 43602, + 43610, 4028, 43618, 43624, 43630, 43640, 43646, 43655, 43664, 43674, + 43681, 43687, 43692, 4034, 4040, 43701, 43709, 43716, 43720, 14356, + 43728, 43732, 43739, 43747, 43754, 43763, 43770, 43776, 43785, 43795, + 43801, 43809, 43818, 43825, 43833, 43840, 26770, 43844, 43851, 43857, + 43867, 43876, 43884, 43895, 43899, 43909, 43916, 43921, 43926, 43932, + 43939, 43947, 43956, 43965, 43975, 43986, 43993, 43998, 44005, 3269, + 44013, 44019, 44024, 44031, 44037, 44043, 44048, 44061, 44074, 44087, + 44094, 44100, 44108, 44116, 44121, 44125, 44129, 44134, 44139, 44144, + 44149, 44154, 44159, 1365, 44164, 44168, 44172, 44176, 44180, 44184, + 44188, 44192, 44196, 44200, 44204, 44208, 44212, 44216, 44220, 44224, + 44228, 44232, 44236, 44240, 44244, 44248, 44252, 44256, 44260, 44264, + 44268, 44272, 44276, 44280, 44284, 44288, 44292, 44296, 44300, 44304, + 44308, 44312, 44316, 44320, 44324, 44328, 44332, 44336, 44340, 44344, + 44348, 44352, 44356, 44360, 44364, 44368, 44372, 44376, 44380, 44384, + 44388, 44392, 44396, 44400, 44404, 44408, 44412, 44416, 44420, 44424, + 44428, 44432, 44436, 44440, 44444, 44448, 44452, 44456, 44460, 44464, + 44468, 44472, 44476, 44480, 44484, 44488, 44492, 44496, 44500, 44504, + 44508, 44512, 44516, 44520, 44524, 44528, 44532, 44536, 44540, 44544, + 44548, 44552, 44556, 44560, 44564, 44568, 44572, 44576, 44580, 44584, + 44588, 44592, 44596, 44600, 44604, 44608, 44612, 44616, 44620, 44624, + 44628, 44632, 44636, 44640, 44644, 44648, 44652, 44656, 44660, 44664, + 44668, 44672, 44676, 44680, 44684, 44688, 44692, 44696, 44700, 44704, + 44708, 44712, 44716, 44720, 44724, 44728, 44732, 44736, 44740, 44744, + 44748, 44752, 44756, 44760, 44764, 44768, 44772, 44776, 44781, 44785, + 44790, 44794, 44799, 44803, 44808, 44812, 44818, 44823, 44827, 44832, + 44836, 44841, 44845, 44850, 44854, 44859, 44863, 44868, 44872, 44877, + 44881, 44887, 44893, 44898, 44902, 44907, 44911, 44917, 44922, 44926, + 44931, 44935, 44940, 44944, 44950, 44955, 44959, 44964, 44968, 44973, + 44977, 44982, 44986, 44992, 44997, 45001, 45006, 45010, 45016, 45021, + 45025, 45030, 45034, 45039, 45043, 45048, 45052, 45057, 45061, 45067, + 45072, 45076, 45082, 45087, 45091, 45097, 45102, 45106, 45111, 45115, + 45120, 45124, 45130, 45136, 45142, 45148, 45154, 45160, 45166, 45172, + 45177, 45181, 45186, 45190, 45196, 45201, 45205, 45210, 45214, 45219, + 45223, 45228, 45232, 45237, 45241, 45246, 45250, 45255, 45259, 45265, + 45270, 45274, 45279, 45283, 45289, 45295, 45300, 127, 63, 45304, 45306, + 45310, 45314, 45318, 45323, 45327, 45331, 45336, 11153, 45341, 45347, + 1677, 7181, 45353, 45356, 45361, 45365, 45370, 45374, 45378, 45383, + 12233, 45387, 45391, 45395, 630, 45399, 18573, 45404, 45408, 45413, + 45418, 45423, 45427, 45434, 45440, 45446, 31813, 45451, 45454, 45458, + 45463, 45469, 45473, 45476, 45484, 45490, 45495, 45499, 45502, 45506, + 45512, 45516, 45520, 3811, 3816, 15084, 45523, 45527, 45531, 45535, + 45539, 45547, 45554, 45558, 15958, 45565, 45579, 45586, 45597, 361, + 45602, 45606, 45612, 45624, 45630, 45636, 45641, 45647, 18625, 45651, + 45655, 35750, 45664, 45670, 45679, 45683, 45687, 45692, 45698, 45703, + 45707, 45712, 45716, 45720, 45727, 45733, 45738, 45749, 45764, 45779, + 45794, 45810, 45828, 12140, 45842, 45849, 45855, 45859, 45862, 45871, + 45876, 45880, 45888, 19254, 45896, 45900, 45910, 45921, 35640, 1042, + 45934, 45943, 45961, 45980, 45989, 45997, 46005, 1690, 12342, 46009, + 27386, 46012, 31579, 46017, 11478, 46022, 46028, 46033, 46039, 46044, + 46050, 46055, 46061, 46066, 46072, 46078, 46084, 46089, 46045, 46051, + 46093, 46056, 46062, 46067, 46098, 46073, 46079, 9184, 4434, 46104, + 46112, 46116, 46119, 46126, 46130, 46135, 46140, 46147, 46153, 46159, + 46164, 17862, 46168, 31596, 46172, 46176, 46180, 46187, 46193, 46197, + 33954, 46206, 10351, 46210, 10780, 46213, 46220, 46226, 46230, 14381, + 46237, 46243, 46248, 46255, 46262, 46269, 34753, 9081, 46276, 46283, + 46290, 46296, 46301, 46308, 46319, 46325, 46330, 46335, 46340, 46344, + 46349, 46356, 46046, 46360, 46370, 46379, 46390, 46396, 46404, 46411, + 46416, 46421, 46426, 46431, 46436, 46440, 46444, 46451, 46457, 46465, + 2416, 30605, 12245, 12257, 12262, 12268, 46474, 12273, 12278, 12284, + 46479, 46489, 46493, 12289, 46498, 20496, 46501, 46506, 46510, 46514, + 46525, 46533, 42227, 46541, 46546, 46553, 46560, 46564, 46567, 46575, + 12153, 46582, 46585, 46591, 46601, 6767, 46610, 46615, 46621, 46625, + 46633, 46637, 46647, 46653, 46658, 46669, 46678, 46687, 46696, 46705, + 46714, 46723, 46732, 46738, 46744, 46749, 46755, 46761, 46767, 46772, + 46775, 46782, 46788, 46792, 46797, 46804, 46811, 46815, 46818, 46828, + 46841, 46850, 46859, 46870, 46883, 46895, 46906, 46915, 46926, 46931, + 46940, 46945, 12294, 46951, 46958, 46966, 46973, 46978, 46983, 31859, + 46987, 46994, 4374, 25, 46998, 47003, 20345, 47007, 47010, 47013, 34145, + 47017, 34762, 47025, 47029, 47033, 47036, 47042, 47048, 47053, 37805, + 47062, 47070, 47076, 47083, 34128, 47087, 34365, 47091, 47100, 47104, + 47112, 47118, 47124, 47129, 47133, 34788, 47139, 47142, 47150, 47158, + 47166, 4772, 47172, 47176, 47180, 47185, 47192, 47198, 47203, 47208, + 47212, 47218, 47223, 47229, 4662, 820, 47236, 47240, 47243, 47255, 47262, + 47267, 18446, 47271, 47279, 47287, 47295, 47303, 47310, 47318, 47326, + 47333, 47341, 47349, 47357, 47365, 47373, 47381, 47389, 47397, 47405, + 47413, 47421, 47428, 47436, 47444, 47452, 47460, 47468, 47476, 47484, + 47492, 47500, 47508, 47516, 47524, 47532, 47540, 47548, 47556, 47564, + 47572, 47580, 47587, 47595, 47602, 47610, 47618, 47626, 47634, 47642, + 47650, 47658, 47666, 47677, 26806, 47682, 47685, 47692, 47696, 47702, + 47706, 47712, 47717, 47723, 47728, 47733, 47737, 47741, 47748, 47756, + 47761, 47766, 47776, 47782, 47795, 47801, 47807, 47813, 47816, 47823, + 47828, 4700, 47834, 4869, 965, 47839, 47842, 47845, 47848, 37889, 37895, + 47851, 37901, 37914, 37920, 37926, 47857, 37932, 37938, 47863, 47869, 10, + 47877, 47884, 47888, 47892, 47900, 38749, 47904, 47908, 47915, 47920, + 47924, 47929, 47935, 47940, 47946, 47951, 47955, 47959, 47963, 47968, + 47972, 47977, 47981, 47985, 47992, 47997, 48001, 48005, 48010, 48014, + 48019, 48023, 48027, 48032, 48038, 18755, 18760, 48043, 48047, 48050, + 48056, 48060, 48064, 25762, 48069, 48073, 48079, 48086, 48092, 48097, + 40820, 48107, 48112, 48120, 48124, 48127, 48131, 38764, 48139, 4738, + 48144, 48149, 48153, 48158, 48162, 48167, 16026, 48178, 48182, 48185, + 48189, 48197, 48202, 48206, 48211, 48216, 48220, 48224, 48228, 48231, + 48235, 48238, 48243, 48248, 48253, 48258, 48263, 48268, 8664, 16042, + 48273, 48276, 48282, 48287, 48293, 48298, 48304, 48309, 48315, 48320, + 48326, 48332, 48338, 48343, 48347, 48351, 48362, 48370, 48377, 48383, + 48388, 48399, 48409, 48415, 48420, 48427, 48436, 48452, 48468, 48478, + 34030, 48485, 48489, 48494, 48499, 48503, 48507, 43960, 48513, 48518, + 48522, 48529, 48534, 48539, 48543, 48546, 48550, 48556, 32825, 48560, + 26120, 48565, 48572, 48580, 48586, 48592, 48599, 48607, 48613, 48617, + 48622, 48628, 48636, 48641, 48645, 48654, 11134, 48662, 48666, 48674, + 48681, 48686, 48691, 48696, 48700, 48703, 48709, 48713, 48716, 48720, + 48727, 48732, 48739, 48743, 48749, 48753, 48759, 48764, 48769, 5107, + 5114, 48774, 48783, 48791, 48796, 48802, 48814, 48827, 48841, 48848, + 48854, 48860, 48865, 48873, 48876, 48878, 48889, 48901, 48912, 48927, + 48944, 48964, 48986, 48993, 49000, 49007, 49013, 49017, 8663, 49020, + 49024, 49028, 49033, 49037, 49041, 49044, 49048, 49062, 28031, 49081, + 49094, 49107, 49120, 28049, 49135, 2808, 49150, 49156, 49160, 49170, + 49174, 49178, 49183, 49187, 49194, 49199, 49203, 49210, 49216, 49221, + 49227, 49237, 49249, 49260, 49265, 49272, 49276, 49280, 49283, 49291, + 19275, 4141, 49296, 18794, 49309, 49316, 49323, 49329, 49333, 49337, + 49342, 49348, 49353, 49359, 49363, 49367, 49370, 49375, 49379, 49384, + 49389, 49394, 49399, 49404, 49409, 49414, 49419, 49424, 8727, 18805, + 49429, 49433, 49439, 49448, 49453, 49462, 49469, 43791, 49475, 49480, + 49484, 49491, 49496, 49503, 49511, 49517, 49521, 49524, 49528, 49533, + 2886, 49540, 49547, 49551, 49554, 49559, 49564, 49570, 49575, 49580, + 49584, 49589, 49599, 49604, 49610, 49615, 49622, 47257, 49628, 49634, + 49642, 49652, 49657, 49662, 49666, 49671, 49676, 8167, 8179, 49681, + 49684, 49691, 49697, 49706, 10268, 41444, 49714, 49718, 49722, 38812, + 49730, 49741, 49749, 44008, 49756, 49761, 49766, 49777, 49784, 49795, + 38836, 26137, 49803, 4652, 49808, 16471, 49814, 34119, 49820, 49825, + 49835, 49844, 49851, 49857, 49861, 49864, 49871, 49877, 49884, 49890, + 49900, 49908, 49914, 49920, 49925, 49929, 49936, 49941, 49947, 49954, + 49960, 49029, 49965, 49969, 16513, 16522, 16531, 16540, 16549, 16578, + 622, 16587, 49975, 49980, 49983, 49989, 49997, 1275, 50002, 50006, 50011, + 50016, 50020, 50025, 50032, 50038, 50042, 50047, 50053, 50057, 37962, + 50062, 50067, 50076, 50083, 50093, 50099, 34163, 50116, 50125, 50133, + 50139, 50144, 50151, 50157, 50165, 50174, 50182, 50190, 50196, 50200, + 50205, 50213, 35311, 38845, 50219, 50238, 19178, 50252, 50268, 50282, + 50288, 50293, 50298, 50303, 50309, 38851, 50314, 50317, 50324, 50331, + 50340, 50345, 50349, 423, 3176, 50356, 50361, 50366, 33219, 50154, 50370, + 50378, 50383, 50391, 50395, 50398, 50403, 50409, 50415, 50420, 50424, + 34236, 50427, 50432, 50436, 50439, 50444, 50448, 50453, 50458, 50462, + 50467, 50471, 50478, 50482, 50486, 25758, 25769, 50491, 50496, 50502, + 50507, 50513, 50519, 32781, 50524, 50528, 50531, 50537, 50542, 50547, + 50552, 50557, 50562, 50567, 50572, 50577, 50583, 50589, 14569, 19485, + 50594, 50599, 50604, 50609, 50614, 50619, 50624, 50629, 452, 68, 37979, + 37984, 37989, 37995, 38000, 38005, 50634, 38009, 50638, 50642, 50646, + 38014, 38020, 50660, 38031, 38036, 50668, 50673, 38042, 50678, 50683, + 50692, 50697, 50702, 50711, 50717, 50723, 50729, 38059, 50742, 50751, + 50757, 38063, 50761, 38068, 50766, 38073, 38078, 50769, 50774, 50778, + 50784, 16279, 50791, 16289, 50798, 50803, 38083, 50807, 50812, 50817, + 50822, 50827, 50831, 50836, 50841, 50847, 50852, 50857, 50863, 50869, + 50874, 50878, 50883, 50888, 50893, 50897, 50902, 50907, 50912, 50918, + 50924, 50930, 50935, 50939, 50944, 50948, 38087, 38092, 38097, 50952, + 50956, 50961, 50965, 50977, 38102, 38108, 38114, 38126, 50983, 31639, + 50987, 50992, 50996, 51001, 51008, 51013, 51018, 51023, 51027, 51031, + 51041, 51046, 51051, 51055, 51065, 51069, 51072, 51080, 51085, 38174, + 51089, 1375, 51095, 51100, 51106, 51114, 51118, 51127, 51135, 51139, + 51143, 51151, 51157, 51165, 51181, 51186, 51190, 51194, 51198, 51203, + 51209, 51224, 38211, 1685, 14601, 51228, 1254, 1269, 51240, 51248, 51255, + 51260, 9230, 51267, 51272, 10765, 978, 2641, 12321, 51279, 10658, 51284, + 51287, 51296, 1162, 51301, 49200, 51308, 51317, 51322, 51326, 51334, + 51341, 27436, 2697, 51349, 12842, 51359, 51365, 2434, 2444, 51374, 51383, + 51393, 51404, 3584, 41841, 51409, 4341, 4352, 9258, 1167, 51413, 51421, + 51428, 51433, 51437, 51441, 51446, 29077, 49535, 12412, 51454, 51463, + 51472, 51480, 51493, 51500, 51511, 51516, 51529, 51542, 51554, 51566, + 51578, 51589, 51602, 51613, 51624, 51634, 51642, 51650, 51662, 51674, + 51685, 51694, 51702, 51709, 51721, 51728, 51734, 51743, 51749, 51756, + 51769, 51774, 51784, 51789, 51795, 51800, 32121, 51804, 48705, 51811, + 51818, 51826, 51833, 2654, 51840, 51851, 51861, 51870, 51878, 51888, + 51896, 51905, 51915, 51924, 51929, 51935, 51941, 4190, 51952, 51962, + 51971, 51980, 51988, 51998, 52006, 52015, 52020, 52025, 52030, 1604, 47, + 52038, 52046, 52057, 52068, 19889, 52078, 52082, 52089, 52095, 52100, + 52104, 52115, 52125, 52134, 52145, 52150, 20318, 20323, 52157, 52166, + 52171, 52181, 52186, 52194, 52202, 52209, 52215, 1566, 271, 52219, 52224, + 52230, 46108, 52235, 52238, 2182, 2663, 52246, 52250, 52253, 1420, 52259, + 16799, 1172, 52264, 52277, 2797, 2818, 52291, 52303, 52315, 2832, 2849, + 2864, 2880, 2897, 52329, 52341, 2912, 52355, 1178, 1184, 1190, 12713, + 52360, 52365, 52370, 52374, 52389, 52404, 52419, 52434, 52449, 52464, + 52479, 52494, 52509, 52524, 52539, 52554, 52569, 52584, 52599, 52614, + 52629, 52644, 52659, 52674, 52689, 52704, 52719, 52734, 52749, 52764, + 52779, 52794, 52809, 52824, 52839, 52854, 52869, 52884, 52899, 52914, + 52929, 52944, 52959, 52974, 52989, 53004, 53019, 53034, 53049, 53064, + 53079, 53094, 53109, 53124, 53139, 53154, 53169, 53184, 53199, 53214, + 53229, 53244, 53259, 53274, 53289, 53304, 53319, 53334, 53349, 53364, + 53379, 53394, 53409, 53424, 53439, 53454, 53469, 53484, 53499, 53514, + 53529, 53544, 53559, 53574, 53589, 53604, 53619, 53634, 53649, 53664, + 53679, 53694, 53709, 53724, 53739, 53754, 53769, 53784, 53799, 53814, + 53829, 53844, 53859, 53874, 53889, 53904, 53919, 53934, 53949, 53964, + 53979, 53994, 54009, 54024, 54039, 54054, 54069, 54084, 54099, 54114, + 54129, 54144, 54159, 54174, 54189, 54204, 54219, 54234, 54249, 54264, + 54279, 54294, 54309, 54324, 54339, 54354, 54369, 54384, 54399, 54414, + 54429, 54444, 54459, 54474, 54489, 54504, 54519, 54534, 54549, 54564, + 54579, 54594, 54609, 54624, 54639, 54654, 54669, 54684, 54699, 54714, + 54729, 54744, 54759, 54774, 54789, 54804, 54819, 54834, 54849, 54864, + 54879, 54894, 54909, 54924, 54939, 54954, 54969, 54984, 54999, 55014, + 55029, 55044, 55059, 55074, 55089, 55104, 55119, 55134, 55149, 55164, + 55179, 55194, 55209, 55224, 55239, 55254, 55269, 55284, 55299, 55314, + 55329, 55344, 55359, 55374, 55389, 55404, 55419, 55434, 55449, 55464, + 55479, 55494, 55509, 55524, 55539, 55554, 55569, 55584, 55599, 55614, + 55629, 55644, 55659, 55674, 55689, 55704, 55719, 55734, 55749, 55764, + 55779, 55794, 55809, 55824, 55839, 55854, 55869, 55884, 55899, 55914, + 55929, 55944, 55959, 55974, 55989, 56004, 56019, 56034, 56049, 56064, + 56079, 56094, 56109, 56124, 56139, 56154, 56169, 56184, 56199, 56214, + 56229, 56244, 56259, 56274, 56289, 56304, 56319, 56334, 56349, 56364, + 56379, 56394, 56409, 56424, 56439, 56454, 56469, 56484, 56499, 56514, + 56529, 56544, 56559, 56574, 56589, 56604, 56619, 56634, 56649, 56664, + 56679, 56694, 56709, 56724, 56739, 56754, 56769, 56784, 56799, 56814, + 56829, 56844, 56859, 56874, 56889, 56904, 56919, 56934, 56949, 56964, + 56979, 56994, 57009, 57024, 57039, 57054, 57069, 57084, 57099, 57114, + 57129, 57144, 57159, 57174, 57189, 57204, 57219, 57234, 57249, 57264, + 57279, 57294, 57309, 57324, 57339, 57354, 57369, 57384, 57399, 57414, + 57429, 57444, 57459, 57474, 57489, 57504, 57519, 57534, 57549, 57564, + 57579, 57594, 57609, 57624, 57639, 57654, 57669, 57684, 57699, 57714, + 57729, 57744, 57759, 57774, 57789, 57804, 57819, 57834, 57849, 57864, + 57879, 57894, 57909, 57924, 57939, 57954, 57969, 57984, 57999, 58014, + 58029, 58044, 58059, 58074, 58089, 58104, 58119, 58134, 58149, 58164, + 58179, 58194, 58209, 58224, 58239, 58254, 58269, 58284, 58299, 58314, + 58329, 58344, 58359, 58374, 58389, 58404, 58419, 58434, 58449, 58464, + 58479, 58494, 58509, 58524, 58539, 58554, 58569, 58584, 58599, 58614, + 58629, 58644, 58659, 58674, 58689, 58704, 58719, 58734, 58749, 58764, + 58779, 58794, 58809, 58824, 58839, 58854, 58869, 58884, 58899, 58914, + 58929, 58944, 58959, 58974, 58989, 59004, 59019, 59034, 59049, 59064, + 59079, 59094, 59109, 59124, 59139, 59154, 59169, 59184, 59199, 59214, + 59229, 59244, 59259, 59274, 59289, 59304, 59319, 59334, 59349, 59364, + 59379, 59394, 59409, 59424, 59439, 59454, 59469, 59484, 59499, 59514, + 59529, 59544, 59559, 59574, 59589, 59604, 59619, 59634, 59649, 59664, + 59679, 59694, 59709, 59724, 59739, 59754, 59769, 59784, 59799, 59814, + 59829, 59844, 59859, 59874, 59889, 59904, 59919, 59934, 59949, 59964, + 59979, 59994, 60009, 60024, 60039, 60054, 60069, 60084, 60099, 60114, + 60129, 60144, 60159, 60174, 60189, 60205, 60221, 60237, 60253, 60269, + 60285, 60301, 60317, 60333, 60349, 60365, 60381, 60397, 60413, 60429, + 60445, 60461, 60477, 60493, 60509, 60525, 60541, 60557, 60573, 60589, + 60605, 60621, 60637, 60653, 60669, 60685, 60701, 60717, 60733, 60749, + 60765, 60781, 60797, 60813, 60829, 60845, 60861, 60877, 60893, 60909, + 60925, 60941, 60957, 60973, 60989, 61005, 61021, 61037, 61053, 61069, + 61085, 61101, 61117, 61133, 61149, 61165, 61181, 61197, 61213, 61229, + 61245, 61261, 61277, 61293, 61309, 61325, 61341, 61357, 61373, 61389, + 61405, 61421, 61437, 61453, 61469, 61485, 61501, 61517, 61533, 61549, + 61565, 61581, 61597, 61613, 61629, 61645, 61661, 61677, 61693, 61709, + 61725, 61741, 61757, 61773, 61789, 61805, 61821, 61837, 61853, 61869, + 61885, 61901, 61917, 61933, 61949, 61965, 61981, 61997, 62013, 62029, + 62045, 62061, 62077, 62093, 62109, 62125, 62141, 62157, 62173, 62189, + 62205, 62221, 62237, 62253, 62269, 62285, 62301, 62317, 62333, 62349, + 62365, 62381, 62397, 62413, 62429, 62445, 62461, 62477, 62493, 62509, + 62525, 62541, 62557, 62573, 62589, 62605, 62621, 62637, 62653, 62669, + 62685, 62701, 62717, 62733, 62749, 62765, 62781, 62797, 62813, 62829, + 62845, 62861, 62877, 62893, 62909, 62925, 62941, 62957, 62973, 62989, + 63005, 63021, 63037, 63053, 63069, 63085, 63101, 63117, 63133, 63149, + 63165, 63181, 63197, 63213, 63229, 63245, 63261, 63277, 63293, 63309, + 63325, 63341, 63357, 63373, 63389, 63405, 63421, 63437, 63453, 63469, + 63485, 63501, 63517, 63533, 63549, 63565, 63581, 63597, 63613, 63629, + 63645, 63661, 63677, 63693, 63709, 63725, 63741, 63757, 63773, 63789, + 63805, 63821, 63837, 63853, 63869, 63885, 63901, 63917, 63933, 63949, + 63965, 63981, 63997, 64013, 64029, 64045, 64061, 64077, 64093, 64109, + 64125, 64141, 64157, 64173, 64189, 64205, 64221, 64237, 64253, 64269, + 64285, 64301, 64317, 64333, 64349, 64365, 64381, 64397, 64413, 64429, + 64445, 64461, 64477, 64493, 64509, 64525, 64541, 64557, 64573, 64589, + 64605, 64621, 64637, 64653, 64669, 64685, 64701, 64717, 64733, 64749, + 64765, 64781, 64797, 64813, 64829, 64845, 64861, 64877, 64893, 64909, + 64925, 64941, 64957, 64973, 64989, 65005, 65021, 65037, 65053, 65069, + 65085, 65101, 65117, 65133, 65149, 65165, 65181, 65197, 65213, 65229, + 65245, 65261, 65277, 65293, 65309, 65325, 65341, 65357, 65373, 65389, + 65405, 65421, 65437, 65453, 65469, 65485, 65501, 65517, 65533, 65549, + 65565, 65581, 65597, 65613, 65629, 65645, 65661, 65677, 65693, 65709, + 65725, 65741, 65757, 65773, 65789, 65805, 65821, 65837, 65853, 65869, + 65885, 65901, 65917, 65933, 65949, 65965, 65981, 65997, 66013, 66029, + 66045, 66061, 66077, 66093, 66109, 66125, 66141, 66157, 66173, 66189, + 66205, 66221, 66237, 66253, 66269, 66285, 66301, 66317, 66333, 66349, + 66365, 66381, 66397, 66413, 66429, 66445, 66461, 66477, 66493, 66509, + 66525, 66541, 66557, 66573, 66589, 66605, 66621, 66637, 66653, 66669, + 66685, 66701, 66717, 66733, 66749, 66765, 66781, 66797, 66813, 66829, + 66845, 66861, 66877, 66893, 66909, 66925, 66941, 66957, 66973, 66989, + 67005, 67021, 67037, 67053, 67069, 67085, 67101, 67117, 67133, 67149, + 67165, 67181, 67197, 67213, 67229, 67245, 67261, 67277, 67293, 67309, + 67325, 67341, 67357, 67373, 67389, 67405, 67421, 67437, 67453, 67469, + 67485, 67501, 67517, 67533, 67549, 67565, 67581, 67597, 67613, 67629, + 67645, 67661, 67677, 67693, 67709, 67725, 67741, 67757, 67773, 67789, + 67805, 67821, 67837, 67853, 67869, 67885, 67901, 67917, 67933, 67949, + 67965, 67981, 67997, 68013, 68029, 68045, 68061, 68077, 68093, 68109, + 68125, 68141, 68157, 68173, 68189, 68205, 68221, 68237, 68253, 68269, + 68285, 68301, 68317, 68333, 68349, 68365, 68381, 68397, 68413, 68429, + 68445, 68461, 68477, 68493, 68509, 68525, 68541, 68557, 68573, 68589, + 68605, 68621, 68637, 68653, 68669, 68685, 68701, 68717, 68733, 68749, + 68765, 68781, 68797, 68813, 68829, 68845, 68861, 68870, 68885, 68899, + 68908, 17701, 68912, 68917, 68923, 68929, 68939, 68947, 17958, 18689, + 9277, 68960, 1428, 1432, 68968, 4270, 33344, 8104, 68974, 68979, 68984, + 68989, 68994, 69000, 69005, 69011, 69016, 69022, 69027, 69032, 69037, + 69042, 69048, 69053, 69058, 69063, 69068, 69073, 69078, 69083, 69089, + 69094, 69100, 69107, 2701, 69112, 69118, 9652, 69122, 69127, 69134, + 69142, 4281, 4286, 4291, 4296, 65, 69146, 69152, 69157, 69162, 69166, + 69171, 69175, 69179, 12785, 69183, 69193, 69206, 69217, 69230, 69237, + 69243, 69251, 69258, 12246, 69267, 69272, 69278, 69284, 69290, 69295, + 69300, 69305, 69310, 69314, 69319, 69324, 69329, 69335, 69341, 69347, + 69352, 69356, 69361, 69366, 69370, 69375, 69380, 69385, 69389, 12801, + 12812, 12817, 1471, 69393, 69399, 1476, 19723, 69404, 19732, 1486, 69409, + 69415, 69420, 1507, 69426, 1513, 1519, 12847, 69431, 69440, 69448, 69456, + 69463, 69467, 69471, 69477, 69482, 37622, 69487, 69494, 69502, 69509, + 69514, 69518, 69522, 69531, 69536, 69541, 69546, 1524, 280, 69551, 69556, + 69560, 19858, 987, 69564, 69571, 69576, 69580, 19916, 1528, 46384, 69583, + 69588, 69598, 69607, 69612, 69616, 69622, 1533, 49481, 69627, 69636, + 69642, 69647, 69652, 13086, 13092, 69658, 69671, 69683, 69700, 69717, + 69734, 69751, 69768, 69785, 69802, 69819, 69836, 69853, 69870, 69887, + 69904, 69921, 69938, 69955, 69972, 69989, 70006, 70023, 70040, 70057, + 70074, 70091, 70108, 70125, 70142, 70159, 70176, 70193, 70210, 70227, + 70244, 70261, 70278, 70295, 70312, 70329, 70346, 70363, 70380, 70397, + 70414, 70431, 70448, 70465, 70482, 70499, 70516, 70527, 70537, 70542, + 1538, 70546, 70551, 70557, 70562, 70567, 70574, 10677, 1543, 70580, + 70589, 33736, 70594, 70605, 13108, 70615, 70620, 70626, 70631, 70638, + 70644, 70649, 1548, 20210, 70654, 70660, 13118, 70666, 70671, 70676, + 70681, 70686, 70691, 70696, 70701, 1553, 4761, 70706, 70711, 70717, + 70722, 70727, 70732, 70737, 70742, 70747, 70752, 70757, 70763, 70769, + 70775, 70780, 70784, 70789, 70794, 70798, 70803, 70808, 70813, 70818, + 70822, 70827, 70833, 70838, 70843, 70847, 70852, 70857, 70863, 70868, + 70873, 70879, 70885, 70890, 70894, 70899, 70904, 70909, 70913, 70918, + 70923, 70928, 70934, 70940, 70945, 70949, 70953, 70958, 70963, 70968, + 35515, 70972, 70977, 70982, 70988, 70993, 70998, 71002, 71007, 71012, + 71018, 71023, 71028, 71034, 71040, 71045, 71049, 71054, 71059, 71063, + 71068, 71073, 71078, 71084, 71090, 71095, 71099, 71104, 71109, 71113, + 71118, 71123, 71128, 71133, 71137, 71140, 71143, 71148, 71153, 38358, + 71160, 71168, 50108, 71174, 3928, 33679, 71187, 71194, 71200, 71206, + 4107, 71211, 13260, 71217, 71227, 71242, 71250, 13265, 71261, 71266, + 71277, 71289, 71301, 71313, 2903, 71325, 71330, 31722, 71342, 71348, + 71354, 71359, 71368, 71375, 71380, 71385, 71390, 71395, 71400, 71405, + 1570, 19350, 71410, 71415, 71420, 71425, 71431, 71436, 71442, 71447, + 71452, 71458, 71463, 71468, 49555, 71472, 71476, 71481, 71485, 20358, + 71490, 71493, 71498, 71506, 71514, 1574, 13301, 13307, 1579, 71522, + 71529, 71534, 71543, 71553, 71560, 71565, 71570, 1584, 71577, 71582, + 20478, 71586, 71591, 71598, 71604, 71608, 71621, 71627, 71638, 71648, + 71655, 20500, 10571, 10578, 4355, 4361, 71662, 1589, 71667, 71676, 71682, + 71690, 71697, 71703, 71710, 71722, 71728, 71733, 71740, 71752, 71763, + 71773, 71782, 71792, 71802, 4249, 71810, 37416, 37425, 20540, 71823, + 71828, 71833, 71838, 71843, 71848, 71853, 1594, 1598, 71858, 71862, + 71865, 71876, 71881, 20566, 1608, 71889, 71894, 71899, 71911, 20599, + 71918, 71921, 71927, 71933, 71938, 71946, 1613, 71951, 71956, 71964, + 71972, 71979, 71988, 71996, 72005, 72009, 1618, 72018, 1623, 25943, + 72023, 72030, 72036, 20686, 72044, 72054, 72060, 72065, 72073, 72080, + 72089, 72097, 72107, 72116, 72126, 72135, 72146, 72156, 72166, 72175, + 72185, 72199, 72212, 72221, 72229, 72239, 72248, 72260, 72271, 72282, + 72292, 19978, 72297, 13453, 72306, 72312, 72317, 72324, 72330, 72337, + 72343, 19567, 72353, 72359, 72364, 72375, 72382, 72389, 72394, 72402, + 13470, 13475, 72410, 72416, 72420, 4339, 4350, 20762, 49658, 72428, + 72434, 72439, 72447, 72454, 14582, 72459, 72465, 72471, 1634, 72476, + 72479, 72485, 72490, 72495, 72500, 72505, 72510, 72515, 72520, 72525, + 72531, 72537, 1333, 72542, 72547, 72552, 72558, 72563, 72568, 72573, + 72578, 72583, 72588, 1643, 18, 72594, 72598, 72603, 72607, 72611, 72615, + 38644, 72620, 28250, 72625, 72630, 72634, 72637, 72641, 72645, 72650, + 72654, 72659, 72663, 72666, 72672, 42331, 42336, 42341, 72675, 72682, + 72688, 72696, 49253, 72706, 72712, 42347, 38908, 38659, 38665, 42363, + 38671, 72717, 72722, 72726, 38941, 72733, 72736, 72740, 72748, 72755, + 72760, 72763, 72768, 72773, 72777, 72781, 72784, 72794, 72806, 72813, + 72819, 38676, 72826, 40627, 72829, 9669, 13815, 72832, 72836, 72841, + 4159, 72845, 72848, 16332, 72855, 72862, 72875, 72890, 72904, 72920, + 72935, 72944, 72952, 72960, 72969, 72973, 72982, 72988, 72993, 73003, + 73016, 73028, 73035, 73040, 73049, 73062, 44055, 73080, 73085, 73092, + 73098, 73103, 850, 73108, 73116, 73123, 73130, 33160, 914, 73136, 73142, + 73147, 73157, 73165, 73171, 73176, 38695, 6858, 38709, 73180, 73190, + 73195, 73203, 73213, 73228, 73234, 73240, 73247, 38719, 73252, 73258, + 37760, 73262, 73266, 73271, 73280, 73287, 73292, 73296, 73301, 73309, + 20543, 73316, 73321, 73325, 6899, 38745, 73329, 73335, 341, 73345, 73352, + 73359, 73365, 73372, 73377, 73386, 15941, 69592, 69602, 73392, 73400, + 73404, 73408, 73412, 73416, 73421, 73425, 73431, 73439, 73444, 73449, + 73456, 73461, 73465, 73470, 73474, 73478, 73484, 73490, 73501, 73507, + 73512, 73516, 73521, 73525, 38869, 73529, 38875, 38881, 73534, 73540, + 73547, 73552, 73556, 37777, 20197, 73559, 73563, 73568, 73575, 73581, + 73585, 73590, 48722, 73596, 73600, 73607, 73611, 73616, 73622, 73628, + 73634, 73646, 73655, 73665, 73671, 73678, 73683, 73688, 73692, 73695, + 73701, 73708, 73713, 73718, 73725, 73732, 73739, 73745, 73750, 73755, + 73763, 38886, 2531, 73768, 73773, 73779, 73784, 73790, 73795, 73800, + 73805, 73811, 38907, 73816, 73822, 73828, 73834, 38977, 73839, 73844, + 73849, 38988, 73854, 73859, 73864, 73870, 73876, 38993, 73881, 73886, + 73891, 39048, 39054, 73896, 73901, 39059, 39081, 34021, 39087, 39091, + 73906, 14258, 73910, 73918, 73924, 73932, 73939, 73945, 73955, 73961, + 73968, 12685, 39105, 73974, 73987, 73996, 74002, 74011, 74017, 74023, + 74030, 28593, 74038, 74045, 74055, 74063, 74066, 39049, 74071, 74078, + 74083, 74087, 74091, 74096, 74100, 4478, 74105, 74110, 74115, 42425, + 42430, 74119, 42444, 74124, 42449, 74129, 74135, 42461, 42467, 42473, + 74140, 74146, 27491, 74157, 74160, 74172, 74180, 39128, 74184, 74193, + 74203, 74212, 39138, 74217, 74224, 74233, 74239, 74247, 74254, 74261, + 6950, 5174, 74266, 39060, 74272, 74275, 74281, 74288, 74293, 74298, + 28497, 74302, 74308, 74314, 74319, 74324, 74328, 74334, 74340, 40511, + 74345, 43649, 45486, 45492, 39169, 39174, 74349, 74353, 74357, 74360, + 74373, 74379, 74383, 74386, 74391, 40893, 74395, 37782, 25884, 74401, + 6879, 6887, 10377, 74404, 74409, 74414, 74419, 74424, 74429, 74434, + 74439, 74444, 74449, 74455, 74460, 74465, 74471, 74476, 74481, 74486, + 74491, 74496, 74501, 74507, 74512, 74518, 74523, 74528, 74533, 74538, + 74543, 74548, 74553, 74558, 74563, 74568, 74574, 74579, 74584, 74589, + 74594, 74599, 74604, 74610, 74615, 74620, 74625, 74630, 74635, 74640, + 74645, 74650, 74655, 74661, 74666, 74671, 74676, 74681, 74687, 74693, + 74698, 74704, 74709, 74714, 74719, 74724, 74729, 1421, 159, 74734, 74738, + 74742, 74746, 30458, 74750, 74754, 74759, 74763, 74768, 74772, 74777, + 74782, 74787, 74792, 74796, 74800, 74805, 74809, 16020, 74814, 74818, + 74825, 74835, 18327, 74844, 74853, 74862, 74866, 74871, 74876, 74880, + 74884, 30238, 3259, 74888, 74894, 21775, 74898, 74907, 74915, 74921, + 74926, 74938, 74950, 74955, 74959, 74964, 74968, 74974, 74980, 74985, + 74995, 75005, 75011, 75019, 75024, 75028, 75034, 75039, 75046, 75052, + 75057, 75064, 75073, 75082, 75090, 75094, 18883, 75097, 75106, 75114, + 75126, 75137, 75148, 75157, 75161, 75170, 75178, 75188, 75196, 75203, + 75213, 75219, 75224, 75232, 75239, 75248, 75254, 75259, 75266, 75272, + 75283, 60, 37559, 75289, 32009, 32019, 75295, 75303, 75310, 75316, 75320, + 75330, 75341, 75349, 75358, 75363, 75368, 75373, 75377, 75381, 75389, + 21722, 75396, 75400, 75406, 75416, 75423, 75430, 75436, 75442, 42524, + 75446, 75448, 75451, 75457, 75461, 75472, 75482, 75488, 75495, 75502, + 15957, 75510, 75516, 75525, 75534, 75540, 11579, 75546, 75552, 75557, + 75562, 75569, 75574, 75581, 75587, 75592, 75600, 75613, 75622, 75631, + 72161, 72171, 75641, 75647, 75656, 75662, 75668, 75675, 75682, 75689, + 75696, 75703, 75708, 75712, 75716, 75719, 75729, 75733, 75745, 75754, + 10038, 75763, 75774, 75779, 75783, 72180, 75789, 75796, 75805, 75813, + 51060, 75821, 75825, 75830, 75835, 75845, 75853, 75865, 75870, 75874, + 75878, 75884, 75892, 75899, 75911, 75919, 75930, 75937, 75943, 75953, + 75959, 75963, 75972, 75981, 75988, 75994, 75999, 76003, 76007, 76011, + 76020, 76029, 76038, 76045, 76051, 76057, 76063, 76068, 76075, 76081, + 76089, 76096, 76102, 15046, 76107, 76113, 76117, 17184, 76121, 76126, + 76136, 76141, 76150, 76156, 76162, 76170, 76177, 76181, 76185, 76192, + 76198, 76206, 76213, 76219, 76230, 76234, 76238, 76242, 76245, 76251, + 76256, 76261, 76265, 76269, 76278, 76286, 76293, 76299, 76306, 29268, + 48863, 76311, 76319, 76323, 76327, 76330, 76338, 76345, 76351, 76360, + 76368, 76374, 76379, 76383, 76388, 76393, 76397, 76401, 76405, 76410, + 76419, 76423, 76430, 45590, 76434, 76440, 76448, 76452, 76458, 76466, + 76472, 76477, 76488, 76496, 76502, 76511, 27638, 76519, 76526, 76533, + 76540, 76547, 76554, 52549, 15772, 76561, 76568, 76573, 42560, 4721, + 76579, 76584, 76589, 76595, 76601, 76607, 76612, 76617, 76622, 76627, + 76633, 76638, 76644, 76649, 76655, 76660, 76665, 76670, 76675, 76680, + 76685, 76690, 76696, 76701, 76707, 76712, 76717, 76722, 76727, 76732, + 76737, 76743, 76748, 76753, 76758, 76763, 76768, 76773, 76778, 76783, + 76788, 76793, 76799, 76804, 76809, 76814, 76819, 76824, 76829, 76834, + 76839, 76845, 76850, 76855, 76860, 76865, 76870, 76875, 76880, 76885, + 76890, 76895, 76900, 76905, 76911, 1883, 305, 76916, 46502, 46507, 76920, + 76925, 9293, 76929, 3628, 76934, 76939, 76943, 76952, 76963, 76980, + 76998, 77006, 75817, 77013, 77016, 77026, 77033, 77042, 77058, 77067, + 77077, 77082, 77095, 77105, 77114, 77122, 77136, 77144, 77153, 77157, + 77160, 77167, 77173, 77184, 77191, 77203, 77214, 77225, 77234, 77241, + 1173, 812, 77251, 2744, 77255, 77260, 77269, 997, 9059, 25320, 77277, + 77285, 77299, 77312, 77316, 77321, 77326, 77331, 77337, 77343, 77348, + 9661, 18370, 77353, 77357, 77361, 77369, 10098, 77374, 77380, 77389, + 77397, 1657, 13314, 1179, 4393, 77401, 77405, 77414, 77424, 2482, 32859, + 77433, 77439, 20450, 32874, 77445, 4558, 13696, 77451, 77458, 71871, + 77462, 77466, 77472, 77477, 77482, 3861, 163, 3887, 77487, 77499, 77503, + 77507, 77513, 77518, 33756, 77522, 13684, 2938, 4, 77527, 77537, 77548, + 77559, 77569, 77575, 77586, 77593, 77599, 77605, 2306, 77610, 77618, + 77625, 77631, 77641, 77651, 77661, 77670, 28580, 1185, 77675, 77679, + 77683, 77689, 77693, 2961, 2967, 9658, 2337, 77697, 77701, 77710, 77718, + 77729, 77737, 77745, 77751, 77756, 77767, 77778, 77786, 77792, 77797, + 11356, 77807, 77815, 77819, 77823, 77828, 77832, 77844, 34219, 18269, + 77851, 77861, 77867, 77873, 7977, 11490, 77883, 77894, 77905, 77915, + 77924, 77928, 77935, 999, 2731, 77945, 77950, 77958, 71587, 77966, 77971, + 77982, 77989, 78003, 16980, 529, 78013, 78020, 78024, 78028, 78036, + 78045, 4433, 78053, 78059, 20495, 78064, 78078, 78085, 78091, 78099, + 78108, 78117, 78124, 78136, 78146, 78154, 78161, 78169, 78176, 4357, 116, + 78184, 78195, 78199, 78211, 78217, 1804, 227, 78222, 10709, 78227, 3006, + 78231, 78238, 78244, 78255, 78265, 78273, 78280, 10049, 78287, 78296, + 78304, 4438, 78317, 4455, 78321, 78326, 78332, 78337, 78342, 78347, 3011, + 573, 78353, 78366, 78370, 78375, 78380, 3016, 1882, 763, 78384, 4459, + 78392, 78398, 78402, 799, 78412, 78421, 78426, 3878, 78430, 78434, 18001, + 18008, 9317, 78442, 4490, 4367, 15644, 78450, 78457, 78462, 28644, 78466, + 78473, 78479, 13952, 78484, 14017, 204, 78489, 78501, 78507, 78515, 3028, + 1699, 78523, 78525, 78530, 78535, 78540, 78546, 78551, 78556, 78561, + 78566, 78571, 78576, 78582, 78587, 78592, 78597, 78602, 78607, 78612, + 78617, 78622, 78628, 78633, 78638, 78643, 78649, 78654, 78660, 78665, + 78670, 78675, 78680, 78685, 78690, 78695, 78701, 78706, 78712, 78717, + 78722, 78727, 78732, 78737, 78742, 78747, 78752, 9730, 9743, 4506, 4511, + 4516, 4521, 26, 78758, 78764, 78769, 78774, 78779, 78785, 78790, 78794, + 78798, 78803, 78809, 78813, 78819, 78824, 78829, 78835, 78840, 78844, + 78849, 78854, 78858, 78861, 78863, 78867, 78870, 78877, 78882, 78886, + 78891, 78895, 78899, 78903, 78909, 78920, 78940, 78959, 78980, 78993, + 79005, 79014, 79018, 79021, 39446, 79024, 39451, 79031, 79036, 39456, + 79045, 79054, 39462, 79059, 39467, 79068, 79073, 13941, 79077, 79082, + 79087, 39472, 79091, 79100, 50719, 79104, 79107, 79111, 9325, 79117, + 79120, 79125, 79130, 79135, 79139, 4179, 39477, 79142, 79146, 79149, + 79160, 79165, 79169, 79175, 79183, 79196, 79200, 79208, 79217, 79223, + 79228, 79234, 79238, 79244, 79250, 79258, 79263, 79267, 79274, 79280, + 79288, 79297, 79305, 39480, 79312, 79322, 79331, 79339, 79350, 79363, + 79368, 79373, 79377, 79386, 79392, 79399, 79412, 79424, 79435, 79447, + 79454, 79463, 79472, 79481, 79488, 79494, 79501, 79509, 79516, 79524, + 79533, 79541, 79548, 79556, 79565, 79573, 79582, 79592, 79601, 79609, + 79616, 79624, 79633, 79641, 79650, 79660, 79669, 79677, 79686, 79696, + 79705, 79715, 79726, 79736, 79745, 79753, 79760, 79768, 79777, 79785, + 79794, 79804, 79813, 79821, 79830, 79840, 79849, 79859, 79870, 79880, + 79889, 79897, 79906, 79916, 79925, 79935, 79946, 79956, 79965, 79975, + 79986, 79996, 80007, 80019, 80030, 80040, 80049, 80057, 80064, 80072, + 80081, 80089, 80098, 80108, 80117, 80125, 80134, 80144, 80153, 80163, + 80174, 80184, 80193, 80201, 80210, 80220, 80229, 80239, 80250, 80260, + 80269, 80279, 80290, 80300, 80311, 80323, 80334, 80344, 80353, 80361, + 80370, 80380, 80389, 80399, 80410, 80420, 80429, 80439, 80450, 80460, + 80471, 80483, 80494, 80504, 80513, 80523, 80534, 80544, 80555, 80567, + 80578, 80588, 80599, 80611, 80622, 80634, 80647, 80659, 80670, 80680, + 80689, 80697, 80704, 80712, 80721, 80729, 80738, 80748, 80757, 80765, + 80774, 80784, 80793, 80803, 80814, 80824, 80833, 80841, 80850, 80860, + 80869, 80879, 80890, 80900, 80909, 80919, 80930, 80940, 80951, 80963, + 80974, 80984, 80993, 81001, 81010, 81020, 81029, 81039, 81050, 81060, + 81069, 81079, 81090, 81100, 81111, 81123, 81134, 81144, 81153, 81163, + 81174, 81184, 81195, 81207, 81218, 81228, 81239, 81251, 81262, 81274, + 81287, 81299, 81310, 81320, 81329, 81337, 81346, 81356, 81365, 81375, + 81386, 81396, 81405, 81415, 81426, 81436, 81447, 81459, 81470, 81480, + 81489, 81499, 81510, 81520, 81531, 81543, 81554, 81564, 81575, 81587, + 81598, 81610, 81623, 81635, 81646, 81656, 81665, 81675, 81686, 81696, + 81707, 81719, 81730, 81740, 81751, 81763, 81774, 81786, 81799, 81811, + 81822, 81832, 81843, 81855, 81866, 81878, 81891, 81903, 81914, 81926, + 81939, 81951, 81964, 81978, 81991, 82003, 82014, 82024, 82033, 82041, + 82048, 82053, 9090, 82060, 82065, 39490, 82071, 82076, 39495, 82082, + 82089, 25442, 31457, 82094, 82100, 82106, 82114, 82120, 82126, 82133, + 82140, 82145, 82150, 82154, 82159, 82163, 82166, 82170, 82175, 82184, + 82193, 82201, 82207, 82219, 82230, 82234, 3321, 9065, 82239, 82242, + 82245, 82247, 82251, 82255, 82259, 82265, 82270, 31520, 82275, 82279, + 82282, 82287, 82291, 82298, 82304, 82308, 7060, 82312, 82317, 39517, + 82321, 82328, 82337, 82345, 82351, 82362, 82370, 82379, 82387, 82394, + 82401, 82407, 82412, 82423, 39522, 82428, 82439, 82451, 82459, 82470, + 82479, 82487, 82498, 82503, 82511, 2696, 82516, 82525, 41914, 82538, + 82542, 82554, 82562, 82567, 82575, 82586, 21940, 82595, 82601, 82608, + 82616, 82622, 39532, 82627, 4484, 68943, 82634, 82637, 82645, 82658, + 82671, 82684, 82697, 82704, 82715, 82724, 82729, 52366, 52371, 82733, + 82737, 82745, 82752, 82761, 82769, 82775, 82784, 82792, 82799, 82807, + 82811, 82820, 82829, 82839, 82852, 82865, 82875, 39537, 82881, 82888, + 82894, 82900, 39543, 82905, 82908, 82912, 82920, 82929, 52137, 82937, + 82946, 82954, 82961, 82969, 82979, 82988, 82997, 41066, 83006, 83017, + 83032, 83042, 10747, 26258, 83051, 83056, 83061, 83065, 19559, 83070, + 83075, 83081, 83086, 83091, 83097, 83102, 83107, 26218, 83112, 83119, + 83127, 83135, 83143, 83148, 83155, 83162, 83167, 1717, 83171, 83175, + 83183, 83191, 39560, 83197, 83203, 83215, 83221, 83228, 83232, 83239, + 83244, 83251, 83257, 83264, 83275, 83285, 83295, 83307, 83313, 83321, + 83330, 83336, 83346, 83356, 39587, 83365, 83374, 83380, 83392, 83403, + 83410, 83415, 83419, 83427, 83438, 83444, 83449, 83454, 83461, 83469, + 83481, 83491, 83500, 83509, 83517, 83524, 41728, 29029, 83530, 83535, + 83539, 83543, 83548, 83556, 83562, 83573, 83586, 83591, 83598, 39592, + 83603, 83615, 83624, 83632, 83642, 83653, 83666, 83673, 83682, 83691, + 83699, 83704, 83710, 83714, 1410, 83719, 83724, 83729, 83734, 83740, + 83745, 83750, 83756, 83762, 83767, 83771, 83776, 83781, 83786, 69527, + 83791, 83796, 83801, 83806, 83812, 83818, 83823, 83827, 83832, 19558, + 83837, 83843, 83848, 83854, 83859, 83864, 83869, 83874, 83878, 83884, + 83889, 83898, 83903, 83908, 83913, 83918, 83922, 83929, 83935, 4836, + 20812, 3286, 83940, 83944, 83949, 83953, 83957, 83961, 56166, 83965, + 83890, 83967, 83977, 39601, 83980, 83985, 83994, 84000, 7019, 39606, + 84004, 84010, 84015, 84021, 84026, 84030, 84037, 84042, 84052, 84061, + 84065, 84071, 84077, 84083, 84087, 84095, 84102, 84110, 84118, 39611, + 84125, 84128, 84139, 84146, 84152, 84157, 84161, 84167, 84175, 84182, + 84187, 84191, 84200, 84208, 84214, 84219, 84226, 84234, 39616, 84241, + 28470, 84253, 84259, 84264, 84270, 84277, 84283, 25906, 33367, 84289, + 84294, 84300, 84304, 84316, 83923, 83930, 26150, 84326, 84331, 84338, + 84344, 84351, 84357, 84368, 84373, 84381, 10447, 84386, 84389, 84395, + 84399, 84403, 84406, 84412, 84418, 39305, 4837, 1425, 16069, 84425, + 84431, 84437, 84443, 84449, 84455, 84461, 84467, 84473, 84478, 84483, + 84488, 84493, 84498, 84503, 84508, 84513, 84518, 84523, 84528, 84533, + 84538, 84544, 84549, 84554, 84560, 84565, 84570, 84576, 84582, 84588, + 84594, 84600, 84606, 84612, 84618, 84624, 84629, 84634, 84640, 84645, + 84650, 84656, 84661, 84666, 84671, 84676, 84681, 84686, 84691, 84696, + 84701, 84706, 84711, 84716, 84722, 84727, 84732, 84737, 84743, 84748, + 84753, 84758, 84763, 84769, 84774, 84779, 84784, 84789, 84794, 84799, + 84804, 84809, 84814, 84819, 84824, 84829, 84834, 84839, 84844, 84849, + 84854, 84859, 84864, 84870, 84875, 84880, 84885, 84890, 84895, 84900, + 84905, 1065, 148, 84910, 84914, 84918, 84923, 84931, 84935, 84947, 84954, + 84962, 84966, 84979, 84987, 84992, 84997, 32072, 85001, 85006, 85010, + 85015, 85019, 85027, 85031, 25450, 85036, 85040, 72424, 85044, 85047, + 85055, 85063, 85071, 85076, 85081, 85088, 85095, 85101, 85107, 85112, + 85119, 85124, 85132, 77304, 85139, 85144, 72190, 85151, 85157, 85162, + 85166, 85173, 85179, 85186, 72217, 14031, 85194, 85199, 85204, 85208, + 85211, 85222, 85231, 85237, 85242, 85246, 85256, 85265, 50510, 85269, + 85273, 85280, 85293, 85299, 85307, 85314, 85323, 85334, 85345, 85356, + 85367, 85376, 85382, 85391, 85399, 85409, 85422, 85430, 85437, 85448, + 85457, 85463, 85468, 85473, 85479, 85489, 85495, 85505, 85513, 85520, + 85530, 85539, 83605, 85547, 85553, 85561, 85567, 75857, 85574, 85579, + 85582, 85586, 85592, 85596, 85599, 85607, 85613, 85619, 85627, 85639, + 85651, 85658, 85663, 85667, 85678, 85686, 85693, 85705, 85713, 85720, + 85728, 85735, 85741, 85746, 85752, 85762, 85771, 85779, 85784, 85794, + 85803, 51398, 85810, 85814, 85819, 85827, 85834, 85840, 85844, 85854, + 85865, 85873, 85880, 85892, 85904, 85913, 82528, 85920, 85930, 85942, + 85953, 85967, 85975, 85985, 85992, 86000, 86013, 86025, 86034, 86042, + 86052, 86063, 86075, 86084, 86094, 86104, 86114, 86123, 86130, 86139, + 86154, 86162, 86172, 86181, 86189, 86202, 68913, 86217, 86227, 86236, + 86248, 86258, 86270, 86281, 86295, 86309, 86323, 86337, 86351, 86365, + 86379, 86393, 86407, 86421, 86435, 86449, 86463, 86477, 86491, 86505, + 86519, 86533, 86547, 86561, 86575, 86589, 86603, 86617, 86631, 86645, + 86659, 86673, 86687, 86701, 86715, 86729, 86743, 86757, 86771, 86785, + 86799, 86813, 86827, 86841, 86855, 86869, 86883, 86897, 86911, 86925, + 86939, 86953, 86967, 86981, 86995, 87009, 87023, 87037, 87051, 87065, + 87079, 87093, 87107, 87121, 87135, 87149, 87163, 87177, 87191, 87205, + 87219, 87233, 87247, 87261, 87275, 87289, 87303, 87317, 87331, 87345, + 87359, 87373, 87387, 87401, 87415, 87429, 87443, 87457, 87471, 87485, + 87499, 87513, 87527, 87541, 87555, 87569, 87583, 87597, 87611, 87625, + 87639, 87653, 87667, 87681, 87695, 87709, 87723, 87737, 87751, 87765, + 87779, 87793, 87807, 87821, 87835, 87849, 87863, 87877, 87891, 87905, + 87919, 87933, 87947, 87961, 87975, 87989, 88003, 88017, 88031, 88045, + 88059, 88073, 88087, 88101, 88115, 88129, 88143, 88157, 88171, 88185, + 88199, 88213, 88227, 88241, 88255, 88269, 88283, 88297, 88311, 88325, + 88339, 88353, 88367, 88381, 88395, 88409, 88423, 88437, 88451, 88465, + 88479, 88493, 88507, 88521, 88535, 88549, 88563, 88577, 88591, 88605, + 88619, 88633, 88647, 88661, 88675, 88689, 88703, 88717, 88731, 88745, + 88759, 88773, 88787, 88801, 88815, 88829, 88843, 88857, 88871, 88885, + 88899, 88913, 88927, 88941, 88955, 88969, 88983, 88997, 89011, 89025, + 89039, 89053, 89067, 89081, 89095, 89109, 89123, 89137, 89151, 89165, + 89179, 89193, 89207, 89221, 89235, 89249, 89263, 89277, 89291, 89305, + 89319, 89333, 89347, 89361, 89375, 89389, 89403, 89417, 89431, 89445, + 89459, 89473, 89487, 89501, 89515, 89529, 89543, 89557, 89571, 89585, + 89599, 89613, 89627, 89641, 89655, 89669, 89683, 89697, 89711, 89725, + 89739, 89753, 89767, 89781, 89795, 89809, 89823, 89837, 89851, 89865, + 89879, 89893, 89907, 89921, 89935, 89949, 89963, 89977, 89991, 90005, + 90019, 90033, 90047, 90061, 90075, 90089, 90103, 90117, 90131, 90145, + 90159, 90173, 90187, 90201, 90215, 90229, 90243, 90257, 90271, 90285, + 90299, 90313, 90327, 90341, 90355, 90369, 90383, 90397, 90411, 90425, + 90439, 90453, 90467, 90481, 90495, 90509, 90523, 90537, 90551, 90565, + 90579, 90593, 90607, 90621, 90635, 90649, 90663, 90677, 90691, 90705, + 90719, 90733, 90747, 90761, 90775, 90789, 90803, 90817, 90831, 90845, + 90859, 90873, 90887, 90901, 90915, 90929, 90943, 90957, 90971, 90985, + 90999, 91013, 91027, 91041, 91055, 91069, 91083, 91097, 91111, 91125, + 91139, 91153, 91167, 91181, 91195, 91209, 91223, 91237, 91251, 91265, + 91279, 91293, 91307, 91321, 91335, 91349, 91363, 91377, 91391, 91405, + 91419, 91433, 91447, 91461, 91475, 91489, 91503, 91517, 91531, 91545, + 91559, 91573, 91587, 91601, 91615, 91629, 91643, 91657, 91671, 91685, + 91699, 91713, 91727, 91741, 91755, 91769, 91783, 91797, 91811, 91825, + 91839, 91853, 91867, 91881, 91895, 91909, 91923, 91937, 91951, 91965, + 91979, 91993, 92007, 92021, 92035, 92049, 92063, 92077, 92091, 92105, + 92119, 92133, 92147, 92161, 92175, 92189, 92203, 92217, 92231, 92245, + 92259, 92273, 92287, 92301, 92315, 92329, 92343, 92357, 92371, 92385, + 92399, 92413, 92427, 92441, 92455, 92469, 92483, 92497, 92511, 92525, + 92539, 92553, 92567, 92581, 92595, 92609, 92623, 92637, 92651, 92665, + 92679, 92693, 92707, 92721, 92735, 92749, 92763, 92777, 92791, 92805, + 92819, 92833, 92847, 92861, 92875, 92889, 92903, 92917, 92931, 92945, + 92959, 92973, 92987, 93001, 93015, 93029, 93043, 93057, 93071, 93085, + 93099, 93113, 93127, 93141, 93155, 93169, 93183, 93197, 93211, 93225, + 93239, 93253, 93267, 93281, 93295, 93309, 93323, 93337, 93351, 93365, + 93379, 93393, 93407, 93421, 93435, 93449, 93463, 93477, 93491, 93505, + 93519, 93533, 93547, 93561, 93575, 93589, 93603, 93617, 93631, 93645, + 93659, 93673, 93687, 93701, 93715, 93729, 93743, 93757, 93771, 93785, + 93799, 93813, 93827, 93841, 93855, 93869, 93883, 93897, 93911, 93925, + 93939, 93953, 93967, 93981, 93995, 94009, 94023, 94037, 94051, 94065, + 94079, 94093, 94107, 94121, 94135, 94149, 94163, 94177, 94191, 94205, + 94219, 94233, 94247, 94261, 94275, 94289, 94303, 94317, 94331, 94345, + 94359, 94373, 94387, 94401, 94415, 94429, 94443, 94457, 94471, 94485, + 94499, 94513, 94527, 94541, 94555, 94569, 94583, 94597, 94611, 94625, + 94639, 94653, 94667, 94681, 94695, 94709, 94723, 94737, 94751, 94765, + 94779, 94793, 94807, 94821, 94835, 94849, 94863, 94877, 94891, 94905, + 94919, 94933, 94947, 94961, 94975, 94989, 95003, 95017, 95031, 95045, + 95059, 95073, 95087, 95101, 95115, 95129, 95143, 95157, 95171, 95185, + 95199, 95213, 95227, 95241, 95255, 95269, 95283, 95297, 95311, 95325, + 95339, 95353, 95367, 95381, 95395, 95409, 95423, 95437, 95451, 95465, + 95479, 95493, 95507, 95521, 95535, 95549, 95563, 95577, 95591, 95605, + 95619, 95633, 95647, 95661, 95675, 95689, 95703, 95717, 95731, 95745, + 95759, 95773, 95787, 95801, 95815, 95829, 95843, 95857, 95871, 95885, + 95899, 95913, 95927, 95941, 95955, 95969, 95983, 95997, 96011, 96025, + 96039, 96053, 96067, 96081, 96095, 96109, 96123, 96137, 96151, 96165, + 96179, 96193, 96207, 96221, 96235, 96249, 96263, 96277, 96291, 96305, + 96319, 96333, 96347, 96361, 96375, 96389, 96403, 96417, 96431, 96445, + 96459, 96473, 96487, 96501, 96515, 96529, 96543, 96557, 96571, 96585, + 96599, 96613, 96627, 96641, 96655, 96669, 96683, 96697, 96711, 96725, + 96739, 96753, 96767, 96781, 96795, 96809, 96823, 96837, 96851, 96865, + 96879, 96893, 96907, 96921, 96935, 96949, 96963, 96977, 96991, 97005, + 97019, 97033, 97042, 97053, 97064, 97074, 97085, 97093, 97101, 97107, + 97117, 97125, 97131, 35391, 97136, 97142, 97151, 97163, 97168, 97175, + 11370, 21960, 97181, 97190, 97195, 97199, 97204, 97211, 97217, 97222, + 97227, 97235, 97243, 97253, 97258, 97266, 14513, 97270, 97276, 97282, + 97288, 97294, 97300, 97306, 97312, 97318, 97324, 97330, 97336, 97342, + 97348, 97354, 97360, 97366, 97372, 97378, 97384, 97390, 97396, 97402, + 97408, 97414, 97420, 97426, 97432, 97438, 97444, 97450, 97456, 97462, + 97468, 97474, 97480, 97486, 97493, 97499, 97505, 97511, 97517, 97523, + 97529, 97535, 97541, 97547, 97553, 97559, 97565, 97571, 97577, 97583, + 97589, 97595, 97601, 97607, 97613, 97619, 97625, 97631, 97637, 97643, + 97649, 97655, 97661, 97667, 97673, 97679, 97685, 97691, 97697, 97703, + 97709, 97715, 97721, 97727, 97733, 97739, 97745, 97751, 97757, 97763, + 97769, 97775, 97781, 97787, 97793, 97800, 97806, 97812, 97818, 97824, + 97830, 97836, 97842, 97848, 97854, 97860, 97866, 97869, 97871, 97886, + 97899, 97906, 97912, 97923, 97928, 97932, 97937, 97944, 97950, 97955, + 97963, 77907, 77917, 97969, 97976, 97986, 12672, 97993, 97998, 35639, + 98007, 98012, 98019, 98029, 98037, 98045, 98054, 98063, 98069, 98075, + 98080, 98087, 98094, 98099, 98103, 98111, 72234, 98116, 98125, 98133, + 98140, 98145, 98149, 98158, 98164, 98167, 98171, 98180, 98190, 84974, + 98199, 98203, 98211, 98215, 98221, 98232, 98242, 21969, 98253, 98262, + 98270, 98278, 98285, 72253, 9895, 98293, 98297, 98306, 98313, 98316, + 98320, 33238, 98323, 98327, 98332, 98349, 98361, 12630, 98373, 98378, + 98383, 98388, 25557, 98392, 98397, 98402, 98408, 98413, 6640, 98418, + 25561, 98423, 98428, 98434, 98441, 98446, 98451, 98457, 98463, 98469, + 98474, 98480, 98484, 98498, 98506, 98514, 98520, 98525, 98532, 98542, + 98551, 98556, 98561, 98566, 98574, 98584, 98595, 98600, 98606, 98611, + 98620, 70662, 4760, 98625, 98643, 98662, 98675, 98689, 98705, 98712, + 98719, 98728, 98735, 98741, 98748, 98753, 98759, 98764, 98770, 98778, + 98784, 98789, 98794, 98810, 12643, 98824, 98831, 98839, 98845, 98849, + 98852, 98858, 98863, 98868, 98876, 98883, 98888, 98897, 98903, 98908, + 98914, 98920, 98929, 98938, 43485, 98943, 98954, 98961, 98969, 98978, + 14104, 98987, 98993, 99001, 99007, 99013, 99019, 99024, 99031, 99037, + 14115, 99042, 99045, 99050, 39643, 99060, 99069, 99074, 99082, 99089, + 99095, 99100, 99108, 99115, 99126, 99142, 99158, 99174, 99190, 99206, + 99222, 99238, 99254, 99270, 99286, 99302, 99318, 99334, 99350, 99366, + 99382, 99398, 99414, 99430, 99446, 99462, 99478, 99494, 99510, 99526, + 99542, 99558, 99574, 99590, 99606, 99622, 99638, 99654, 99670, 99686, + 99702, 99718, 99734, 99750, 99766, 99782, 99798, 99814, 99830, 99846, + 99862, 99878, 99894, 99910, 99926, 99942, 99958, 99974, 99990, 100006, + 100022, 100038, 100054, 100070, 100086, 100102, 100118, 100134, 100150, + 100166, 100182, 100198, 100214, 100230, 100246, 100262, 100278, 100294, + 100310, 100326, 100342, 100358, 100374, 100390, 100406, 100422, 100438, + 100454, 100470, 100486, 100502, 100518, 100534, 100550, 100566, 100582, + 100598, 100614, 100630, 100646, 100662, 100678, 100694, 100710, 100726, + 100742, 100758, 100774, 100790, 100806, 100822, 100838, 100854, 100870, + 100886, 100902, 100918, 100934, 100950, 100966, 100982, 100998, 101014, + 101030, 101046, 101062, 101078, 101094, 101110, 101126, 101142, 101158, + 101174, 101190, 101206, 101222, 101238, 101254, 101270, 101286, 101302, + 101318, 101334, 101350, 101366, 101382, 101398, 101414, 101430, 101446, + 101462, 101478, 101494, 101510, 101526, 101542, 101558, 101574, 101590, + 101606, 101622, 101638, 101654, 101670, 101686, 101702, 101718, 101734, + 101750, 101766, 101782, 101798, 101814, 101830, 101846, 101862, 101878, + 101894, 101910, 101926, 101942, 101958, 101974, 101990, 102006, 102022, + 102038, 102054, 102070, 102086, 102102, 102118, 102134, 102150, 102166, + 102182, 102198, 102214, 102230, 102246, 102262, 102278, 102294, 102310, + 102326, 102342, 102358, 102374, 102390, 102406, 102422, 102438, 102454, + 102470, 102486, 102502, 102518, 102534, 102550, 102566, 102582, 102598, + 102614, 102630, 102646, 102662, 102678, 102694, 102710, 102726, 102742, + 102758, 102774, 102790, 102806, 102822, 102838, 102854, 102870, 102886, + 102902, 102918, 102934, 102950, 102966, 102982, 102998, 103014, 103030, + 103046, 103062, 103078, 103094, 103110, 103126, 103142, 103158, 103174, + 103190, 103206, 103222, 103238, 103254, 103270, 103286, 103302, 103318, + 103334, 103350, 103366, 103382, 103398, 103414, 103430, 103446, 103462, + 103478, 103494, 103510, 103526, 103542, 103558, 103574, 103590, 103606, + 103622, 103638, 103654, 103670, 103686, 103702, 103718, 103734, 103750, + 103766, 103782, 103798, 103814, 103830, 103846, 103862, 103878, 103894, + 103910, 103926, 103942, 103958, 103974, 103990, 104006, 104022, 104038, + 104054, 104070, 104086, 104102, 104118, 104134, 104150, 104166, 104182, + 104198, 104214, 104230, 104246, 104262, 104278, 104294, 104310, 104326, + 104342, 104358, 104374, 104390, 104406, 104422, 104438, 104454, 104470, + 104486, 104502, 104518, 104534, 104550, 104566, 104582, 104598, 104614, + 104630, 104646, 104662, 104678, 104694, 104710, 104726, 104742, 104758, + 104774, 104790, 104806, 104822, 104838, 104854, 104870, 104886, 104902, + 104918, 104934, 104950, 104966, 104982, 104998, 105014, 105030, 105046, + 105062, 105078, 105094, 105110, 105126, 105142, 105158, 105174, 105190, + 105206, 105222, 105238, 105254, 105270, 105286, 105302, 105318, 105334, + 105350, 105366, 105382, 105398, 105414, 105430, 105446, 105462, 105478, + 105494, 105510, 105526, 105542, 105558, 105574, 105590, 105606, 105622, + 105638, 105654, 105670, 105686, 105702, 105718, 105734, 105750, 105766, + 105782, 105798, 105814, 105830, 105846, 105862, 105878, 105894, 105910, + 105926, 105942, 105958, 105974, 105990, 106006, 106022, 106038, 106054, + 106070, 106086, 106102, 106118, 106134, 106150, 106166, 106182, 106198, + 106214, 106230, 106246, 106262, 106278, 106294, 106310, 106326, 106342, + 106358, 106374, 106390, 106406, 106422, 106438, 106454, 106470, 106486, + 106502, 106518, 106534, 106550, 106566, 106582, 106598, 106614, 106630, + 106646, 106662, 106678, 106694, 106710, 106726, 106742, 106758, 106774, + 106790, 106806, 106822, 106838, 106854, 106870, 106886, 106902, 106918, + 106934, 106950, 106966, 106982, 106998, 107014, 107030, 107046, 107062, + 107078, 107094, 107110, 107126, 107142, 107158, 107174, 107190, 107206, + 107222, 107238, 107254, 107270, 107286, 107302, 107318, 107334, 107350, + 107366, 107382, 107398, 107414, 107430, 107446, 107462, 107478, 107494, + 107510, 107526, 107542, 107558, 107574, 107590, 107606, 107622, 107638, + 107654, 107670, 107686, 107702, 107718, 107734, 107750, 107766, 107782, + 107798, 107814, 107830, 107846, 107862, 107878, 107894, 107910, 107926, + 107942, 107958, 107974, 107990, 108006, 108022, 108038, 108054, 108070, + 108086, 108102, 108118, 108134, 108150, 108166, 108182, 108198, 108214, + 108230, 108246, 108262, 108278, 108294, 108310, 108326, 108342, 108358, + 108374, 108390, 108406, 108422, 108438, 108454, 108470, 108486, 108502, + 108518, 108534, 108550, 108566, 108582, 108598, 108614, 108630, 108646, + 108662, 108678, 108694, 108710, 108726, 108742, 108758, 108774, 108790, + 108806, 108822, 108838, 108854, 108870, 108886, 108902, 108918, 108934, + 108950, 108966, 108982, 108998, 109014, 109030, 109046, 109062, 109078, + 109094, 109110, 109126, 109142, 109158, 109174, 109190, 109206, 109222, + 109238, 109254, 109270, 109286, 109302, 109318, 109334, 109350, 109366, + 109382, 109398, 109414, 109430, 109446, 109462, 109478, 109494, 109510, + 109526, 109542, 109558, 109574, 109590, 109606, 109622, 109638, 109654, + 109670, 109686, 109702, 109718, 109734, 109750, 109766, 109782, 109798, + 109814, 109830, 109846, 109862, 109878, 109894, 109910, 109926, 109942, + 109958, 109974, 109990, 110006, 110022, 110038, 110054, 110070, 110086, + 110102, 110118, 110134, 110150, 110166, 110182, 110198, 110214, 110230, + 110246, 110262, 110278, 110294, 110310, 110326, 110342, 110358, 110374, + 110390, 110406, 110422, 110438, 110454, 110470, 110486, 110502, 110518, + 110534, 110550, 110566, 110582, 110598, 110614, 110630, 110646, 110662, + 110678, 110694, 110710, 110726, 110742, 110758, 110774, 110790, 110806, + 110822, 110838, 110854, 110870, 110886, 110902, 110918, 110934, 110950, + 110966, 110982, 110998, 111014, 111030, 111046, 111062, 111078, 111094, + 111110, 111126, 111142, 111158, 111174, 111190, 111206, 111222, 111238, + 111254, 111270, 111286, 111302, 111318, 111334, 111350, 111366, 111382, + 111398, 111414, 111430, 111446, 111462, 111478, 111494, 111510, 111526, + 111542, 111558, 111574, 111590, 111606, 111622, 111638, 111654, 111670, + 111686, 111702, 111718, 111734, 111750, 111766, 111782, 111798, 111814, + 111830, 111846, 111862, 111878, 111894, 111910, 111926, 111942, 111958, + 111974, 111990, 112006, 112022, 112038, 112054, 112070, 112086, 112102, + 112118, 112134, 112150, 112166, 112182, 112198, 112214, 112230, 112246, + 112262, 112278, 112294, 112310, 112326, 112342, 112358, 112374, 112390, + 112406, 112422, 112438, 112454, 112470, 112486, 112502, 112518, 112534, + 112550, 112566, 112582, 112598, 112614, 112630, 112646, 112662, 112678, + 112694, 112710, 112726, 112742, 112758, 112774, 112790, 112806, 112822, + 112838, 112854, 112870, 112886, 112902, 112918, 112934, 112950, 112966, + 112982, 112992, 113001, 113006, 113014, 77227, 113019, 113025, 113030, + 113037, 113046, 113054, 113058, 4338, 113064, 113071, 113077, 113081, + 20561, 46618, 3295, 113086, 113090, 113094, 113101, 113107, 113116, + 113122, 113129, 113133, 113154, 113176, 113192, 113209, 113228, 113237, + 113247, 113255, 113262, 113269, 113275, 33093, 113289, 113293, 113299, + 113307, 113319, 113325, 113333, 113340, 113345, 113350, 113354, 113362, + 113369, 113373, 113379, 113385, 113390, 3972, 52566, 113396, 113400, + 113404, 113408, 113413, 113418, 113423, 113429, 113435, 113441, 113448, + 113454, 113461, 113467, 113473, 113478, 113484, 113489, 113493, 105586, + 113498, 105650, 52581, 113503, 113508, 113516, 113520, 113525, 113532, + 113541, 113548, 113554, 113563, 113567, 113574, 113578, 113581, 113588, + 113594, 113603, 113613, 113623, 113628, 113632, 113639, 113647, 113656, + 113660, 113668, 113674, 113679, 113684, 113690, 113696, 113701, 113705, + 31970, 113711, 113715, 113719, 113722, 113727, 113735, 113745, 113751, + 113756, 113766, 49687, 113774, 113786, 113792, 113799, 113805, 113809, + 113814, 113820, 113832, 113843, 113850, 113856, 113863, 113870, 113882, + 113889, 113895, 25641, 113899, 113907, 113913, 113920, 113926, 113932, + 113938, 113943, 113948, 113953, 113957, 113966, 113974, 113985, 7934, + 113990, 19997, 113996, 114000, 114004, 114008, 114016, 114025, 114029, + 114036, 114045, 114053, 114066, 114072, 106162, 36574, 114077, 114079, + 114084, 114089, 114094, 114099, 114104, 114109, 114114, 114119, 114124, + 114129, 114134, 114139, 114144, 114149, 114155, 114160, 114165, 114170, + 114175, 114180, 114185, 114190, 114195, 114201, 114207, 114213, 114218, + 114223, 114235, 114240, 1935, 54, 114245, 114250, 39653, 114254, 39658, + 39663, 39669, 39674, 114258, 39679, 26827, 114280, 114284, 114288, + 114293, 114297, 39683, 114301, 114309, 114316, 114322, 114332, 39688, + 114339, 114342, 114347, 114351, 114360, 11168, 114368, 39693, 26671, + 114371, 114375, 114383, 1307, 114388, 39704, 114391, 114396, 114401, + 31211, 31221, 43083, 114406, 114411, 114416, 114421, 114427, 114432, + 114441, 114446, 114455, 114463, 114470, 114476, 114481, 114486, 114491, + 114501, 114510, 114518, 114523, 114531, 114535, 114543, 114547, 114554, + 114561, 114569, 114576, 39508, 46333, 114582, 114588, 114593, 114598, + 14548, 11961, 114603, 114608, 114613, 114619, 114626, 114632, 114641, + 114646, 114654, 114664, 114671, 114681, 114687, 114692, 114698, 114702, + 21991, 114709, 44068, 114722, 114727, 114734, 114740, 114755, 37638, + 75635, 114768, 114772, 114781, 114790, 114797, 114803, 114811, 114817, + 114825, 114834, 114842, 114849, 46453, 114855, 114858, 114862, 114866, + 114870, 11982, 114876, 114883, 114889, 114897, 114902, 114906, 29203, + 114912, 114915, 114923, 114930, 114938, 114951, 114965, 114972, 114978, + 114985, 114991, 39718, 114995, 115001, 115009, 115016, 115024, 115032, + 115038, 39723, 115046, 115052, 115057, 115067, 115073, 115082, 37433, + 42431, 115090, 115095, 115100, 115104, 115109, 115113, 115121, 115126, + 17993, 18818, 49709, 115130, 115135, 39728, 18150, 115139, 115151, + 115156, 115160, 115167, 115176, 115180, 115188, 115194, 115199, 115207, + 115215, 115223, 115231, 115239, 115247, 115258, 115264, 9132, 115269, + 115275, 115280, 115285, 115296, 115305, 115317, 115332, 40040, 115338, + 20116, 39732, 115342, 115349, 115355, 115359, 29340, 115366, 115372, + 115379, 48834, 115388, 115394, 115403, 115409, 115414, 115422, 115428, + 115433, 39742, 115438, 115447, 115456, 113838, 115465, 115472, 115478, + 115484, 115493, 115503, 115509, 115517, 115524, 115528, 39747, 115531, + 39753, 1346, 115536, 115544, 115552, 115562, 115571, 115579, 115586, + 115596, 39764, 115600, 115602, 115606, 115611, 115615, 115619, 115625, + 115630, 115634, 115645, 115650, 115656, 115661, 115670, 115675, 3300, + 115679, 115686, 115690, 115699, 115707, 115715, 115722, 115727, 115732, + 74136, 115736, 115739, 115745, 115753, 115759, 115763, 115768, 115775, + 115780, 115785, 115789, 115796, 115802, 115807, 42462, 115811, 115814, + 115819, 115823, 115828, 115835, 115840, 115844, 47803, 115852, 31230, + 31239, 115858, 115864, 115870, 115875, 115879, 115882, 115892, 115901, + 115906, 115912, 115919, 115925, 115929, 115937, 115942, 42468, 85233, + 115946, 115954, 115961, 115967, 115974, 115979, 115986, 115991, 115995, + 116001, 116006, 69129, 116012, 116018, 10386, 116023, 116028, 116032, + 116037, 116042, 116047, 116051, 116056, 116061, 116067, 116072, 116077, + 116083, 116089, 116094, 116098, 116103, 116108, 116113, 116117, 29339, + 116122, 116127, 116133, 116139, 116145, 116150, 116154, 116159, 116164, + 109938, 116169, 116174, 116179, 116184, 110002, 52836, 116189, 39772, + 116197, 116201, 116209, 116217, 116228, 116233, 116237, 27306, 82631, + 116242, 116248, 116253, 4649, 116263, 116270, 116275, 116283, 116292, + 116297, 116301, 116306, 116310, 116318, 116326, 116333, 77493, 116339, + 116347, 116354, 116365, 116371, 116377, 39782, 116380, 116387, 116395, + 116400, 116404, 33612, 71815, 116410, 116415, 116422, 116427, 10275, + 116431, 116439, 116446, 116453, 116462, 116469, 116475, 116489, 116497, + 6724, 116259, 116503, 116508, 116514, 116518, 116521, 116529, 116536, + 116541, 116554, 116561, 116567, 116571, 116579, 116584, 116591, 116597, + 116602, 72093, 116607, 116610, 116619, 116626, 110210, 116632, 116635, + 116643, 116649, 116658, 116668, 116678, 116687, 116698, 116706, 116717, + 116722, 116726, 116731, 116735, 43214, 116743, 18783, 43223, 116748, + 101729, 101745, 101761, 101777, 101793, 116753, 101825, 101841, 101857, + 101873, 101985, 102001, 116757, 102033, 102049, 116761, 116765, 116769, + 116773, 102289, 102321, 116777, 102353, 116781, 116785, 102497, 102513, + 102529, 102545, 116789, 102609, 102625, 116793, 102753, 102769, 102785, + 102801, 102817, 102833, 102849, 102865, 102881, 102897, 103009, 103025, + 103041, 103057, 103073, 103089, 103105, 103121, 103137, 103153, 116797, + 104945, 105057, 105121, 105137, 105153, 105169, 105185, 105201, 105313, + 105329, 105345, 116801, 105393, 116805, 105425, 105441, 105457, 116809, + 116814, 116819, 116824, 116829, 116834, 116839, 116843, 116847, 116852, + 116857, 116861, 116866, 116871, 116875, 116880, 116885, 116890, 116895, + 116899, 116904, 116909, 116913, 116918, 116922, 116926, 116930, 116934, + 116939, 116943, 116947, 116951, 116955, 116959, 116963, 116967, 116971, + 116975, 116980, 116985, 116990, 116995, 117000, 117005, 117010, 117015, + 117020, 117025, 117029, 117033, 117037, 117041, 117045, 117049, 117054, + 117058, 117063, 117067, 117072, 117077, 117081, 117085, 117090, 117094, + 117098, 117102, 117106, 117110, 117114, 117118, 117122, 117126, 117130, + 117134, 117138, 117142, 117146, 117151, 117156, 117160, 117164, 117168, + 117172, 117176, 117180, 117185, 117189, 117193, 117197, 117201, 117205, + 117209, 117214, 117218, 117223, 117227, 117231, 117235, 117239, 117243, + 117247, 117251, 117255, 117259, 117263, 117267, 117272, 117276, 117280, + 117284, 117288, 117292, 117296, 117300, 117304, 117308, 117312, 117316, + 117321, 117325, 117329, 117334, 117339, 117343, 117347, 117351, 117355, + 117359, 117363, 117367, 117371, 117376, 117380, 117385, 117389, 117394, + 117398, 117403, 117407, 117413, 117418, 117422, 117427, 117431, 117436, + 117440, 117445, 117449, 117454, 1429, 117458, 117462, 3042, 1705, 28465, + 1602, 31166, 117466, 3051, 117470, 1276, 117475, 1218, 117479, 117483, + 117487, 117491, 117495, 117499, 3075, 117503, 117511, 117518, 117525, + 117539, 3079, 8044, 117548, 117556, 117563, 117574, 117583, 117587, + 117594, 117606, 117619, 117632, 117643, 117648, 117655, 117667, 117671, + 3083, 14185, 117681, 117686, 117695, 117705, 117710, 117719, 3087, + 117727, 117731, 117736, 117743, 117749, 117754, 117763, 117771, 117783, + 117793, 1223, 15645, 117806, 117810, 117816, 117830, 117842, 117854, + 117862, 117872, 117881, 117890, 117899, 117907, 117918, 117926, 4657, + 117936, 117947, 117956, 117962, 117977, 117984, 117990, 117995, 43357, + 118000, 3111, 15649, 118004, 118009, 118016, 10206, 118025, 118031, 4695, + 118041, 3116, 39144, 118050, 71705, 118057, 118061, 118067, 118078, + 118084, 118089, 118096, 118102, 118110, 118117, 118123, 118134, 118150, + 118160, 118169, 118180, 118189, 118196, 118202, 118212, 118220, 118226, + 118241, 118247, 118252, 118256, 118263, 118271, 118275, 118278, 118284, + 118291, 118297, 118305, 118314, 118322, 118328, 118337, 52139, 118351, + 118356, 118362, 17744, 118367, 118380, 118392, 118401, 118409, 118416, + 118420, 118424, 118427, 118434, 118441, 118449, 118457, 118466, 118474, + 17643, 118482, 118487, 118491, 118503, 118510, 118517, 118526, 954, + 118536, 118545, 118556, 3137, 118560, 118564, 118570, 118583, 118595, + 118605, 118614, 118626, 32128, 118637, 118645, 118654, 118665, 118676, + 118686, 118696, 118704, 118713, 118721, 13604, 118728, 118732, 118735, + 118740, 118745, 118749, 118755, 1228, 118762, 118766, 14281, 118770, + 118774, 118785, 118794, 118802, 118811, 118819, 118835, 118846, 118855, + 118863, 118875, 118886, 118902, 118912, 118933, 118947, 118960, 118968, + 118975, 8090, 118988, 118993, 118999, 6733, 119005, 119008, 119015, + 119025, 9266, 119032, 119037, 119042, 119049, 119057, 119065, 119071, + 119076, 119082, 119086, 119094, 119103, 119111, 119116, 119125, 119132, + 11418, 11427, 119138, 119149, 119155, 119160, 119166, 3153, 3158, 119172, + 1063, 119178, 119185, 119192, 119205, 119215, 119220, 2324, 87, 119228, + 119235, 119240, 119248, 119258, 119267, 119273, 119282, 119290, 119300, + 119304, 119308, 119313, 119317, 119329, 3181, 119337, 119345, 119350, + 119361, 119372, 119384, 119395, 119405, 119414, 26025, 119419, 119425, + 119430, 119440, 119450, 119455, 34346, 119461, 119466, 119475, 26047, + 119479, 26058, 119484, 4783, 8, 119491, 119500, 119507, 119514, 119520, + 119525, 119529, 119535, 34376, 119540, 119545, 72390, 119550, 119555, + 119561, 119567, 119575, 119580, 119588, 119596, 119605, 119612, 119618, + 119625, 119631, 119638, 119643, 47672, 52033, 119649, 119659, 1822, 32, + 119666, 119671, 119684, 119689, 119697, 119702, 119708, 3207, 30907, + 3221, 119713, 119721, 119728, 119733, 119738, 119747, 4340, 4351, 73734, + 119755, 119759, 1629, 1862, 119764, 119769, 119776, 34797, 1866, 331, + 119783, 119789, 119794, 3229, 119798, 119803, 119810, 1870, 119815, + 119821, 119826, 119838, 6978, 119848, 119855, 1877, 119861, 119866, + 119873, 119880, 119895, 119902, 119913, 119918, 119926, 2772, 119930, + 119942, 119947, 119951, 119957, 34218, 2329, 119961, 119972, 119976, + 119980, 119986, 119990, 119999, 120003, 120014, 120018, 2375, 38961, + 120022, 120032, 120040, 3320, 120046, 120055, 120063, 10752, 120068, + 120076, 120081, 120085, 120094, 120101, 120107, 3290, 17808, 120111, + 120124, 44081, 120142, 120147, 120155, 120163, 120173, 11759, 15773, + 120185, 120198, 120205, 120215, 120229, 120236, 120252, 120259, 120265, + 26105, 14980, 120272, 120279, 120289, 120298, 52835, 120310, 120318, + 52970, 120325, 120328, 120334, 120340, 120346, 120352, 120358, 120365, + 120372, 120378, 120384, 120390, 120396, 120402, 120408, 120414, 120420, + 120426, 120432, 120438, 120444, 120450, 120456, 120462, 120468, 120474, + 120480, 120486, 120492, 120498, 120504, 120510, 120516, 120522, 120528, + 120534, 120540, 120546, 120552, 120558, 120564, 120570, 120576, 120582, + 120588, 120594, 120600, 120606, 120612, 120618, 120624, 120630, 120636, + 120642, 120648, 120654, 120660, 120666, 120672, 120678, 120685, 120691, + 120698, 120705, 120711, 120718, 120725, 120731, 120737, 120743, 120749, + 120755, 120761, 120767, 120773, 120779, 120785, 120791, 120797, 120803, + 120809, 120815, 3304, 10720, 120821, 120831, 120837, 120845, 120849, + 117739, 3308, 120853, 114067, 25770, 4701, 4265, 120857, 3314, 120861, + 120871, 120877, 120883, 120889, 120895, 120901, 120907, 120913, 120919, + 120925, 120931, 120937, 120943, 120949, 120955, 120961, 120967, 120973, + 120979, 120985, 120991, 120997, 121003, 121009, 121015, 121021, 121028, + 121035, 121041, 121047, 121053, 121059, 121065, 121071, 1233, 121077, + 121082, 121087, 121092, 121097, 121102, 121107, 121112, 121117, 121121, + 121125, 121129, 121133, 121137, 121141, 121145, 121149, 121153, 121159, + 121165, 121171, 121177, 121181, 121185, 121189, 121193, 121197, 121201, + 121205, 121209, 121213, 121218, 121223, 121228, 121233, 121238, 121243, + 121248, 121253, 121258, 121263, 121268, 121273, 121278, 121283, 121288, + 121293, 121298, 121303, 121308, 121313, 121318, 121323, 121328, 121333, + 121338, 121343, 121348, 121353, 121358, 121363, 121368, 121373, 121378, + 121383, 121388, 121393, 121398, 121403, 121408, 121413, 121418, 121423, + 121428, 121433, 121438, 121443, 121448, 121453, 121458, 121463, 121468, + 121473, 121478, 121483, 121488, 121493, 121498, 121503, 121508, 121513, + 121518, 121523, 121528, 121533, 121538, 121543, 121548, 121553, 121558, + 121563, 121568, 121573, 121578, 121583, 121588, 121593, 121598, 121603, + 121608, 121613, 121618, 121623, 121628, 121633, 121638, 121643, 121648, + 121653, 121658, 121663, 121668, 121673, 121678, 121683, 121688, 121693, + 121698, 121703, 121708, 121713, 121718, 121723, 121728, 121733, 121738, + 121743, 121748, 121753, 121758, 121763, 121768, 121773, 121778, 121783, + 121788, 121793, 121798, 121803, 121808, 121813, 121818, 121823, 121828, + 121833, 121838, 121843, 121848, 121853, 121858, 121863, 121868, 121873, + 121878, 121883, 121888, 121893, 121898, 121903, 121908, 121913, 121918, + 121923, 121928, 121933, 121938, 121943, 121948, 121953, 121958, 121963, + 121968, 121973, 121978, 121983, 121988, 121993, 121998, 122003, 122008, + 122013, 122018, 122023, 122028, 122033, 122038, 122043, 122048, 122053, + 122058, 122063, 122068, 122073, 122078, 122083, 122088, 122093, 122098, + 122103, 122109, 122114, 122119, 122124, 122129, 122134, 122139, 122144, + 122150, 122155, 122160, 122165, 122170, 122175, 122180, 122185, 122190, + 122195, 122200, 122205, 122210, 122215, 122220, 122225, 122230, 122235, + 122240, 122245, 122250, 122255, 122260, 122265, 122270, 122275, 122280, + 122285, 122290, 122295, 122300, 122305, 122310, 122319, 122324, 122333, + 122338, 122347, 122352, 122361, 122366, 122375, 122380, 122389, 122394, + 122403, 122408, 122417, 122422, 122427, 122436, 122440, 122449, 122454, + 122463, 122468, 122477, 122482, 122491, 122496, 122505, 122510, 122519, + 122524, 122533, 122538, 122547, 122552, 122561, 122566, 122575, 122580, + 122585, 122590, 122595, 122600, 122605, 122610, 122614, 122619, 122624, + 122629, 122634, 122639, 122644, 122650, 122655, 122660, 122665, 122671, + 122675, 122680, 122686, 122691, 122696, 122701, 122706, 122711, 122716, + 122721, 122726, 122731, 122736, 122742, 122747, 122752, 122757, 122763, + 122768, 122773, 122778, 122783, 122789, 122794, 122799, 122804, 122809, + 122814, 122820, 122825, 122830, 122835, 122840, 122845, 122850, 122855, + 122860, 122865, 122870, 122875, 122880, 122885, 122890, 122895, 122900, + 122905, 122910, 122915, 122920, 122925, 122930, 122935, 122941, 122947, + 122953, 122958, 122963, 122968, 122973, 122979, 122985, 122991, 122996, + 123001, 123006, 123012, 123017, 123022, 123027, 123032, 123037, 123042, + 123047, 123052, 123057, 123062, 123067, 123072, 123077, 123082, 123087, + 123092, 123098, 123104, 123110, 123115, 123120, 123125, 123130, 123136, + 123142, 123148, 123153, 123158, 123163, 123168, 123173, 123178, 123183, + 123188, 123193, 19475, 123198, 123204, 123209, 123214, 123219, 123224, + 123229, 123235, 123240, 123245, 123250, 123255, 123260, 123266, 123271, + 123276, 123281, 123286, 123291, 123296, 123301, 123306, 123311, 123316, + 123321, 123326, 123331, 123336, 123341, 123346, 123351, 123356, 123361, + 123366, 123371, 123376, 123382, 123387, 123392, 123397, 123402, 123407, + 123412, 123417, 123422, 123427, 123432, 123437, 123442, 123447, 123452, + 123457, 123462, 123467, 123472, 123477, 123482, 123487, 123492, 123497, + 123502, 123507, 123512, 123517, 123522, 123527, 123532, 123537, 123542, + 123547, 123552, 123557, 123562, 123567, 123572, 123577, 123582, 123588, + 123593, 123598, 123603, 123608, 123613, 123618, 123623, 123628, 123633, + 123638, 123643, 123649, 123654, 123660, 123665, 123670, 123675, 123680, + 123685, 123690, 123696, 123701, 123706, 123712, 123717, 123722, 123727, + 123732, 123737, 123743, 123749, 123754, 123759, 14614, 123764, 123769, + 123774, 123779, 123784, 123789, 123794, 123799, 123804, 123809, 123814, + 123819, 123824, 123829, 123834, 123839, 123844, 123849, 123854, 123859, + 123864, 123869, 123874, 123879, 123884, 123889, 123894, 123899, 123904, + 123909, 123914, 123919, 123924, 123929, 123934, 123939, 123944, 123949, + 123954, 123959, 123964, 123969, 123974, 123979, 123984, 123989, 123994, + 123999, 124004, 124009, 124014, 124019, 124024, 124029, 124034, 124039, + 124044, 124049, 124054, 124059, 124064, 124069, 124074, 124079, 124084, + 124090, 124095, 124100, 124105, 124110, 124116, 124121, 124126, 124131, + 124136, 124141, 124146, 124152, 124157, 124162, 124167, 124172, 124177, + 124183, 124188, 124193, 124198, 124203, 124208, 124214, 124219, 124224, + 124229, 124234, 124239, 124245, 124251, 124256, 124261, 124266, 124272, + 124278, 124284, 124289, 124294, 124300, 124306, 124311, 124317, 124323, + 124329, 124334, 124339, 124345, 124350, 124356, 124361, 124367, 124376, + 124381, 124386, 124392, 124397, 124403, 124408, 124413, 124418, 124423, + 124428, 124433, 124438, 124443, 124448, 124453, 124458, 124463, 124468, + 124473, 124478, 124483, 124488, 124493, 124498, 124503, 124508, 124513, + 124518, 124523, 124528, 124533, 124538, 124543, 124548, 124553, 124558, + 124564, 124570, 124576, 124581, 124586, 124591, 124596, 124601, 124606, + 124611, 124616, 124621, 124626, 124631, 124636, 124641, 124646, 124651, + 124656, 124661, 124666, 124671, 124676, 124682, 124688, 124693, 124699, + 124704, 124709, 124715, 124720, 124726, 124731, 124737, 124742, 124748, + 124753, 124759, 124764, 124769, 124774, 124779, 124784, 124789, 124794, + 120872, 120878, 120884, 120890, 124800, 120896, 120902, 124806, 120908, + 120914, 120920, 120926, 120932, 120938, 120944, 120950, 120956, 124812, + 120962, 120968, 120974, 124818, 120980, 120986, 120992, 120998, 124824, + 121004, 121010, 121016, 121036, 124830, 124836, 121042, 124842, 121048, + 121054, 121060, 121066, 121072, 124848, 3331, 3336, 124853, 3351, 3356, + 3361, 124858, 124861, 124867, 124873, 124880, 124885, 124890, 2380, }; /* code->name phrasebook */ #define phrasebook_shift 7 #define phrasebook_short 190 static const unsigned char phrasebook[] = { - 0, 201, 247, 233, 216, 77, 207, 252, 77, 31, 56, 236, 155, 56, 210, 13, - 56, 251, 137, 251, 49, 45, 210, 113, 50, 210, 113, 250, 193, 108, 56, - 242, 74, 228, 87, 232, 80, 201, 63, 202, 23, 17, 191, 77, 17, 107, 17, - 109, 17, 138, 17, 134, 17, 149, 17, 169, 17, 175, 17, 171, 17, 178, 242, - 83, 204, 25, 219, 180, 56, 234, 43, 56, 230, 204, 56, 208, 13, 77, 242, - 72, 250, 182, 8, 6, 1, 65, 8, 6, 1, 250, 120, 8, 6, 1, 247, 193, 8, 6, 1, - 238, 127, 8, 6, 1, 71, 8, 6, 1, 233, 175, 8, 6, 1, 232, 51, 8, 6, 1, 230, - 116, 8, 6, 1, 68, 8, 6, 1, 223, 35, 8, 6, 1, 222, 152, 8, 6, 1, 172, 8, - 6, 1, 218, 168, 8, 6, 1, 215, 61, 8, 6, 1, 74, 8, 6, 1, 210, 236, 8, 6, - 1, 208, 104, 8, 6, 1, 146, 8, 6, 1, 206, 8, 8, 6, 1, 200, 43, 8, 6, 1, + 0, 201, 248, 233, 218, 77, 207, 254, 77, 31, 56, 236, 157, 56, 210, 15, + 56, 251, 139, 251, 51, 45, 210, 115, 50, 210, 115, 250, 195, 108, 56, + 242, 76, 228, 89, 232, 82, 201, 64, 202, 24, 17, 191, 77, 17, 107, 17, + 109, 17, 138, 17, 134, 17, 150, 17, 169, 17, 175, 17, 171, 17, 178, 242, + 85, 204, 26, 219, 182, 56, 234, 45, 56, 230, 206, 56, 208, 15, 77, 242, + 74, 250, 184, 8, 6, 1, 65, 8, 6, 1, 250, 122, 8, 6, 1, 247, 195, 8, 6, 1, + 238, 129, 8, 6, 1, 71, 8, 6, 1, 233, 177, 8, 6, 1, 232, 53, 8, 6, 1, 230, + 118, 8, 6, 1, 68, 8, 6, 1, 223, 37, 8, 6, 1, 222, 154, 8, 6, 1, 172, 8, + 6, 1, 218, 170, 8, 6, 1, 215, 63, 8, 6, 1, 74, 8, 6, 1, 210, 238, 8, 6, + 1, 208, 106, 8, 6, 1, 146, 8, 6, 1, 206, 9, 8, 6, 1, 200, 43, 8, 6, 1, 66, 8, 6, 1, 196, 12, 8, 6, 1, 193, 224, 8, 6, 1, 192, 235, 8, 6, 1, 192, - 159, 8, 6, 1, 191, 166, 45, 51, 248, 53, 207, 19, 202, 23, 50, 51, 248, - 53, 243, 2, 252, 60, 130, 219, 112, 230, 211, 252, 60, 8, 2, 1, 65, 8, 2, - 1, 250, 120, 8, 2, 1, 247, 193, 8, 2, 1, 238, 127, 8, 2, 1, 71, 8, 2, 1, - 233, 175, 8, 2, 1, 232, 51, 8, 2, 1, 230, 116, 8, 2, 1, 68, 8, 2, 1, 223, - 35, 8, 2, 1, 222, 152, 8, 2, 1, 172, 8, 2, 1, 218, 168, 8, 2, 1, 215, 61, - 8, 2, 1, 74, 8, 2, 1, 210, 236, 8, 2, 1, 208, 104, 8, 2, 1, 146, 8, 2, 1, - 206, 8, 8, 2, 1, 200, 43, 8, 2, 1, 66, 8, 2, 1, 196, 12, 8, 2, 1, 193, + 159, 8, 6, 1, 191, 166, 45, 51, 248, 55, 207, 20, 202, 24, 50, 51, 248, + 55, 243, 4, 252, 62, 130, 219, 114, 230, 213, 252, 62, 8, 2, 1, 65, 8, 2, + 1, 250, 122, 8, 2, 1, 247, 195, 8, 2, 1, 238, 129, 8, 2, 1, 71, 8, 2, 1, + 233, 177, 8, 2, 1, 232, 53, 8, 2, 1, 230, 118, 8, 2, 1, 68, 8, 2, 1, 223, + 37, 8, 2, 1, 222, 154, 8, 2, 1, 172, 8, 2, 1, 218, 170, 8, 2, 1, 215, 63, + 8, 2, 1, 74, 8, 2, 1, 210, 238, 8, 2, 1, 208, 106, 8, 2, 1, 146, 8, 2, 1, + 206, 9, 8, 2, 1, 200, 43, 8, 2, 1, 66, 8, 2, 1, 196, 12, 8, 2, 1, 193, 224, 8, 2, 1, 192, 235, 8, 2, 1, 192, 159, 8, 2, 1, 191, 166, 45, 238, - 171, 248, 53, 81, 219, 112, 50, 238, 171, 248, 53, 198, 152, 213, 37, - 201, 247, 223, 93, 233, 216, 77, 247, 24, 56, 209, 8, 56, 238, 170, 56, - 192, 71, 56, 248, 22, 164, 205, 54, 56, 237, 42, 239, 6, 56, 233, 40, - 211, 50, 223, 144, 219, 219, 55, 251, 116, 207, 252, 77, 213, 12, 56, - 202, 32, 228, 88, 207, 78, 56, 217, 146, 237, 125, 56, 209, 80, 56, 200, - 182, 109, 200, 182, 138, 252, 47, 252, 60, 216, 91, 56, 209, 142, 56, 82, - 236, 140, 247, 35, 200, 182, 107, 217, 40, 211, 50, 223, 144, 206, 203, - 55, 251, 116, 207, 252, 77, 193, 246, 232, 118, 91, 208, 22, 193, 246, - 232, 118, 91, 230, 70, 193, 246, 232, 118, 115, 208, 20, 223, 93, 208, - 13, 77, 8, 6, 1, 42, 4, 230, 210, 8, 6, 1, 42, 4, 252, 46, 8, 6, 1, 42, - 4, 243, 1, 8, 6, 1, 42, 4, 198, 152, 8, 6, 1, 42, 4, 237, 42, 8, 6, 1, - 42, 4, 206, 189, 58, 8, 6, 1, 252, 25, 8, 6, 1, 247, 194, 4, 247, 35, 8, - 6, 1, 235, 15, 4, 230, 210, 8, 6, 1, 235, 15, 4, 252, 46, 8, 6, 1, 235, - 15, 4, 243, 1, 8, 6, 1, 235, 15, 4, 237, 42, 8, 6, 1, 228, 74, 4, 230, - 210, 8, 6, 1, 228, 74, 4, 252, 46, 8, 6, 1, 228, 74, 4, 243, 1, 8, 6, 1, - 228, 74, 4, 237, 42, 8, 6, 1, 233, 248, 8, 6, 1, 215, 62, 4, 198, 152, 8, - 6, 1, 187, 4, 230, 210, 8, 6, 1, 187, 4, 252, 46, 8, 6, 1, 187, 4, 243, - 1, 8, 6, 1, 187, 4, 198, 152, 8, 6, 1, 187, 4, 237, 42, 215, 127, 56, 8, - 6, 1, 187, 4, 106, 8, 6, 1, 126, 4, 230, 210, 8, 6, 1, 126, 4, 252, 46, - 8, 6, 1, 126, 4, 243, 1, 8, 6, 1, 126, 4, 237, 42, 8, 6, 1, 192, 160, 4, - 252, 46, 8, 6, 1, 198, 233, 8, 2, 1, 203, 127, 206, 8, 8, 2, 1, 42, 4, - 230, 210, 8, 2, 1, 42, 4, 252, 46, 8, 2, 1, 42, 4, 243, 1, 8, 2, 1, 42, - 4, 198, 152, 8, 2, 1, 42, 4, 237, 42, 8, 2, 1, 42, 4, 206, 189, 58, 8, 2, - 1, 252, 25, 8, 2, 1, 247, 194, 4, 247, 35, 8, 2, 1, 235, 15, 4, 230, 210, - 8, 2, 1, 235, 15, 4, 252, 46, 8, 2, 1, 235, 15, 4, 243, 1, 8, 2, 1, 235, - 15, 4, 237, 42, 8, 2, 1, 228, 74, 4, 230, 210, 8, 2, 1, 228, 74, 4, 252, - 46, 8, 2, 1, 228, 74, 4, 243, 1, 8, 2, 1, 228, 74, 4, 237, 42, 8, 2, 1, - 233, 248, 8, 2, 1, 215, 62, 4, 198, 152, 8, 2, 1, 187, 4, 230, 210, 8, 2, - 1, 187, 4, 252, 46, 8, 2, 1, 187, 4, 243, 1, 8, 2, 1, 187, 4, 198, 152, - 8, 2, 1, 187, 4, 237, 42, 236, 200, 56, 8, 2, 1, 187, 4, 106, 8, 2, 1, - 126, 4, 230, 210, 8, 2, 1, 126, 4, 252, 46, 8, 2, 1, 126, 4, 243, 1, 8, - 2, 1, 126, 4, 237, 42, 8, 2, 1, 192, 160, 4, 252, 46, 8, 2, 1, 198, 233, - 8, 2, 1, 192, 160, 4, 237, 42, 8, 6, 1, 42, 4, 217, 146, 8, 2, 1, 42, 4, - 217, 146, 8, 6, 1, 42, 4, 248, 36, 8, 2, 1, 42, 4, 248, 36, 8, 6, 1, 42, - 4, 211, 138, 8, 2, 1, 42, 4, 211, 138, 8, 6, 1, 247, 194, 4, 252, 46, 8, - 2, 1, 247, 194, 4, 252, 46, 8, 6, 1, 247, 194, 4, 243, 1, 8, 2, 1, 247, - 194, 4, 243, 1, 8, 6, 1, 247, 194, 4, 75, 58, 8, 2, 1, 247, 194, 4, 75, - 58, 8, 6, 1, 247, 194, 4, 247, 92, 8, 2, 1, 247, 194, 4, 247, 92, 8, 6, - 1, 238, 128, 4, 247, 92, 8, 2, 1, 238, 128, 4, 247, 92, 8, 6, 1, 238, - 128, 4, 106, 8, 2, 1, 238, 128, 4, 106, 8, 6, 1, 235, 15, 4, 217, 146, 8, - 2, 1, 235, 15, 4, 217, 146, 8, 6, 1, 235, 15, 4, 248, 36, 8, 2, 1, 235, - 15, 4, 248, 36, 8, 6, 1, 235, 15, 4, 75, 58, 8, 2, 1, 235, 15, 4, 75, 58, - 8, 6, 1, 235, 15, 4, 211, 138, 8, 2, 1, 235, 15, 4, 211, 138, 8, 6, 1, - 235, 15, 4, 247, 92, 8, 2, 1, 235, 15, 4, 247, 92, 8, 6, 1, 232, 52, 4, - 243, 1, 8, 2, 1, 232, 52, 4, 243, 1, 8, 6, 1, 232, 52, 4, 248, 36, 8, 2, - 1, 232, 52, 4, 248, 36, 8, 6, 1, 232, 52, 4, 75, 58, 8, 2, 1, 232, 52, 4, - 75, 58, 8, 6, 1, 232, 52, 4, 247, 35, 8, 2, 1, 232, 52, 4, 247, 35, 8, 6, - 1, 230, 117, 4, 243, 1, 8, 2, 1, 230, 117, 4, 243, 1, 8, 6, 1, 230, 117, - 4, 106, 8, 2, 1, 230, 117, 4, 106, 8, 6, 1, 228, 74, 4, 198, 152, 8, 2, - 1, 228, 74, 4, 198, 152, 8, 6, 1, 228, 74, 4, 217, 146, 8, 2, 1, 228, 74, - 4, 217, 146, 8, 6, 1, 228, 74, 4, 248, 36, 8, 2, 1, 228, 74, 4, 248, 36, - 8, 6, 1, 228, 74, 4, 211, 138, 8, 2, 1, 228, 74, 4, 211, 138, 8, 6, 1, - 228, 74, 4, 75, 58, 8, 2, 1, 236, 139, 68, 8, 6, 34, 223, 197, 8, 2, 34, - 223, 197, 8, 6, 1, 223, 36, 4, 243, 1, 8, 2, 1, 223, 36, 4, 243, 1, 8, 6, - 1, 222, 153, 4, 247, 35, 8, 2, 1, 222, 153, 4, 247, 35, 8, 2, 1, 221, 8, - 8, 6, 1, 220, 143, 4, 252, 46, 8, 2, 1, 220, 143, 4, 252, 46, 8, 6, 1, - 220, 143, 4, 247, 35, 8, 2, 1, 220, 143, 4, 247, 35, 8, 6, 1, 220, 143, - 4, 247, 92, 8, 2, 1, 220, 143, 4, 247, 92, 8, 6, 1, 220, 143, 4, 82, 236, - 140, 8, 2, 1, 220, 143, 4, 82, 236, 140, 8, 6, 1, 220, 143, 4, 106, 8, 2, - 1, 220, 143, 4, 106, 8, 6, 1, 215, 62, 4, 252, 46, 8, 2, 1, 215, 62, 4, - 252, 46, 8, 6, 1, 215, 62, 4, 247, 35, 8, 2, 1, 215, 62, 4, 247, 35, 8, - 6, 1, 215, 62, 4, 247, 92, 8, 2, 1, 215, 62, 4, 247, 92, 8, 2, 1, 215, - 62, 208, 233, 247, 205, 251, 49, 8, 6, 1, 234, 88, 8, 2, 1, 234, 88, 8, - 6, 1, 187, 4, 217, 146, 8, 2, 1, 187, 4, 217, 146, 8, 6, 1, 187, 4, 248, - 36, 8, 2, 1, 187, 4, 248, 36, 8, 6, 1, 187, 4, 55, 252, 46, 8, 2, 1, 187, - 4, 55, 252, 46, 8, 6, 34, 211, 151, 8, 2, 34, 211, 151, 8, 6, 1, 207, - 222, 4, 252, 46, 8, 2, 1, 207, 222, 4, 252, 46, 8, 6, 1, 207, 222, 4, - 247, 35, 8, 2, 1, 207, 222, 4, 247, 35, 8, 6, 1, 207, 222, 4, 247, 92, 8, - 2, 1, 207, 222, 4, 247, 92, 8, 6, 1, 206, 9, 4, 252, 46, 8, 2, 1, 206, 9, - 4, 252, 46, 8, 6, 1, 206, 9, 4, 243, 1, 8, 2, 1, 206, 9, 4, 243, 1, 8, 6, - 1, 206, 9, 4, 247, 35, 8, 2, 1, 206, 9, 4, 247, 35, 8, 6, 1, 206, 9, 4, - 247, 92, 8, 2, 1, 206, 9, 4, 247, 92, 8, 6, 1, 200, 44, 4, 247, 35, 8, 2, - 1, 200, 44, 4, 247, 35, 8, 6, 1, 200, 44, 4, 247, 92, 8, 2, 1, 200, 44, - 4, 247, 92, 8, 6, 1, 200, 44, 4, 106, 8, 2, 1, 200, 44, 4, 106, 8, 6, 1, - 126, 4, 198, 152, 8, 2, 1, 126, 4, 198, 152, 8, 6, 1, 126, 4, 217, 146, - 8, 2, 1, 126, 4, 217, 146, 8, 6, 1, 126, 4, 248, 36, 8, 2, 1, 126, 4, - 248, 36, 8, 6, 1, 126, 4, 206, 189, 58, 8, 2, 1, 126, 4, 206, 189, 58, 8, - 6, 1, 126, 4, 55, 252, 46, 8, 2, 1, 126, 4, 55, 252, 46, 8, 6, 1, 126, 4, - 211, 138, 8, 2, 1, 126, 4, 211, 138, 8, 6, 1, 193, 225, 4, 243, 1, 8, 2, - 1, 193, 225, 4, 243, 1, 8, 6, 1, 192, 160, 4, 243, 1, 8, 2, 1, 192, 160, - 4, 243, 1, 8, 6, 1, 192, 160, 4, 237, 42, 8, 6, 1, 191, 167, 4, 252, 46, - 8, 2, 1, 191, 167, 4, 252, 46, 8, 6, 1, 191, 167, 4, 75, 58, 8, 2, 1, - 191, 167, 4, 75, 58, 8, 6, 1, 191, 167, 4, 247, 92, 8, 2, 1, 191, 167, 4, - 247, 92, 8, 2, 1, 179, 206, 8, 8, 2, 1, 78, 4, 106, 8, 6, 1, 78, 4, 102, - 8, 6, 1, 78, 4, 198, 51, 8, 2, 1, 78, 4, 198, 51, 8, 6, 1, 163, 169, 8, - 2, 1, 163, 169, 8, 6, 1, 211, 77, 74, 8, 6, 1, 247, 194, 4, 102, 8, 2, 1, - 247, 194, 4, 102, 8, 6, 1, 252, 0, 238, 127, 8, 6, 1, 238, 128, 4, 102, - 8, 6, 1, 238, 128, 4, 198, 51, 8, 2, 1, 238, 128, 4, 198, 51, 8, 2, 1, - 153, 237, 106, 8, 6, 1, 207, 18, 71, 8, 6, 1, 205, 86, 8, 6, 1, 211, 77, - 71, 8, 6, 1, 233, 176, 4, 102, 8, 2, 1, 233, 176, 4, 102, 8, 6, 1, 232, - 52, 4, 102, 8, 6, 1, 231, 211, 8, 2, 1, 228, 126, 8, 6, 1, 223, 83, 8, 6, - 1, 228, 74, 4, 106, 8, 6, 1, 222, 153, 4, 102, 8, 2, 1, 222, 153, 4, 102, - 8, 2, 1, 220, 143, 4, 164, 8, 2, 1, 220, 33, 4, 106, 8, 6, 1, 153, 218, - 168, 8, 6, 1, 215, 62, 4, 45, 102, 8, 2, 1, 215, 62, 4, 179, 50, 219, - 212, 8, 6, 1, 187, 4, 82, 198, 152, 8, 6, 1, 187, 4, 228, 187, 8, 2, 1, - 187, 4, 228, 187, 8, 6, 1, 211, 133, 8, 2, 1, 211, 133, 8, 6, 1, 210, - 237, 4, 102, 8, 2, 1, 210, 237, 4, 102, 8, 1, 191, 228, 8, 6, 1, 163, - 109, 8, 2, 1, 163, 109, 8, 6, 1, 234, 12, 8, 1, 207, 18, 234, 13, 219, 4, - 8, 2, 1, 200, 44, 4, 210, 192, 102, 8, 6, 1, 200, 44, 4, 102, 8, 2, 1, - 200, 44, 4, 102, 8, 6, 1, 200, 44, 4, 207, 24, 102, 8, 6, 1, 126, 4, 228, - 187, 8, 2, 1, 126, 4, 228, 187, 8, 6, 1, 196, 70, 8, 6, 1, 196, 13, 4, - 102, 8, 6, 1, 192, 160, 4, 102, 8, 2, 1, 192, 160, 4, 102, 8, 6, 1, 191, - 167, 4, 106, 8, 2, 1, 191, 167, 4, 106, 8, 6, 1, 233, 178, 8, 6, 1, 233, - 179, 207, 17, 8, 2, 1, 233, 179, 207, 17, 8, 2, 1, 233, 179, 4, 199, 215, - 8, 1, 105, 4, 106, 8, 6, 1, 163, 149, 8, 2, 1, 163, 149, 8, 1, 223, 93, - 231, 11, 201, 64, 4, 106, 8, 1, 192, 238, 8, 1, 237, 98, 242, 231, 8, 1, - 220, 3, 242, 231, 8, 1, 251, 150, 242, 231, 8, 1, 207, 24, 242, 231, 8, - 6, 1, 235, 37, 4, 247, 92, 8, 6, 1, 238, 128, 4, 2, 1, 191, 167, 4, 247, - 92, 8, 2, 1, 235, 37, 4, 247, 92, 8, 6, 1, 219, 77, 8, 6, 1, 220, 143, 4, - 2, 1, 223, 35, 8, 2, 1, 219, 77, 8, 6, 1, 213, 158, 8, 6, 1, 215, 62, 4, - 2, 1, 223, 35, 8, 2, 1, 213, 158, 8, 6, 1, 42, 4, 247, 92, 8, 2, 1, 42, - 4, 247, 92, 8, 6, 1, 228, 74, 4, 247, 92, 8, 2, 1, 228, 74, 4, 247, 92, - 8, 6, 1, 187, 4, 247, 92, 8, 2, 1, 187, 4, 247, 92, 8, 6, 1, 126, 4, 247, - 92, 8, 2, 1, 126, 4, 247, 92, 8, 6, 1, 126, 4, 237, 43, 23, 217, 146, 8, - 2, 1, 126, 4, 237, 43, 23, 217, 146, 8, 6, 1, 126, 4, 237, 43, 23, 252, - 46, 8, 2, 1, 126, 4, 237, 43, 23, 252, 46, 8, 6, 1, 126, 4, 237, 43, 23, - 247, 92, 8, 2, 1, 126, 4, 237, 43, 23, 247, 92, 8, 6, 1, 126, 4, 237, 43, - 23, 230, 210, 8, 2, 1, 126, 4, 237, 43, 23, 230, 210, 8, 2, 1, 153, 71, - 8, 6, 1, 42, 4, 237, 43, 23, 217, 146, 8, 2, 1, 42, 4, 237, 43, 23, 217, - 146, 8, 6, 1, 42, 4, 75, 93, 23, 217, 146, 8, 2, 1, 42, 4, 75, 93, 23, - 217, 146, 8, 6, 1, 252, 26, 4, 217, 146, 8, 2, 1, 252, 26, 4, 217, 146, - 8, 6, 1, 232, 52, 4, 106, 8, 2, 1, 232, 52, 4, 106, 8, 6, 1, 232, 52, 4, - 247, 92, 8, 2, 1, 232, 52, 4, 247, 92, 8, 6, 1, 222, 153, 4, 247, 92, 8, - 2, 1, 222, 153, 4, 247, 92, 8, 6, 1, 187, 4, 211, 138, 8, 2, 1, 187, 4, - 211, 138, 8, 6, 1, 187, 4, 211, 139, 23, 217, 146, 8, 2, 1, 187, 4, 211, - 139, 23, 217, 146, 8, 6, 1, 233, 179, 4, 247, 92, 8, 2, 1, 233, 179, 4, - 247, 92, 8, 2, 1, 223, 36, 4, 247, 92, 8, 6, 1, 235, 36, 8, 6, 1, 238, - 128, 4, 2, 1, 191, 166, 8, 2, 1, 235, 36, 8, 6, 1, 232, 52, 4, 252, 46, - 8, 2, 1, 232, 52, 4, 252, 46, 8, 6, 1, 228, 123, 8, 6, 1, 192, 238, 8, 6, - 1, 215, 62, 4, 230, 210, 8, 2, 1, 215, 62, 4, 230, 210, 8, 6, 1, 42, 4, - 206, 189, 93, 23, 252, 46, 8, 2, 1, 42, 4, 206, 189, 93, 23, 252, 46, 8, - 6, 1, 252, 26, 4, 252, 46, 8, 2, 1, 252, 26, 4, 252, 46, 8, 6, 1, 187, 4, - 201, 28, 23, 252, 46, 8, 2, 1, 187, 4, 201, 28, 23, 252, 46, 8, 6, 1, 42, - 4, 55, 230, 210, 8, 2, 1, 42, 4, 55, 230, 210, 8, 6, 1, 42, 4, 223, 93, - 248, 36, 8, 2, 1, 42, 4, 223, 93, 248, 36, 8, 6, 1, 235, 15, 4, 55, 230, - 210, 8, 2, 1, 235, 15, 4, 55, 230, 210, 8, 6, 1, 235, 15, 4, 223, 93, - 248, 36, 8, 2, 1, 235, 15, 4, 223, 93, 248, 36, 8, 6, 1, 228, 74, 4, 55, - 230, 210, 8, 2, 1, 228, 74, 4, 55, 230, 210, 8, 6, 1, 228, 74, 4, 223, - 93, 248, 36, 8, 2, 1, 228, 74, 4, 223, 93, 248, 36, 8, 6, 1, 187, 4, 55, - 230, 210, 8, 2, 1, 187, 4, 55, 230, 210, 8, 6, 1, 187, 4, 223, 93, 248, - 36, 8, 2, 1, 187, 4, 223, 93, 248, 36, 8, 6, 1, 207, 222, 4, 55, 230, - 210, 8, 2, 1, 207, 222, 4, 55, 230, 210, 8, 6, 1, 207, 222, 4, 223, 93, - 248, 36, 8, 2, 1, 207, 222, 4, 223, 93, 248, 36, 8, 6, 1, 126, 4, 55, - 230, 210, 8, 2, 1, 126, 4, 55, 230, 210, 8, 6, 1, 126, 4, 223, 93, 248, - 36, 8, 2, 1, 126, 4, 223, 93, 248, 36, 8, 6, 1, 206, 9, 4, 242, 75, 60, - 8, 2, 1, 206, 9, 4, 242, 75, 60, 8, 6, 1, 200, 44, 4, 242, 75, 60, 8, 2, - 1, 200, 44, 4, 242, 75, 60, 8, 6, 1, 191, 248, 8, 2, 1, 191, 248, 8, 6, - 1, 230, 117, 4, 247, 92, 8, 2, 1, 230, 117, 4, 247, 92, 8, 6, 1, 215, 62, - 4, 179, 50, 219, 212, 8, 2, 1, 238, 128, 4, 238, 175, 8, 6, 1, 211, 19, - 8, 2, 1, 211, 19, 8, 6, 1, 191, 167, 4, 102, 8, 2, 1, 191, 167, 4, 102, - 8, 6, 1, 42, 4, 75, 58, 8, 2, 1, 42, 4, 75, 58, 8, 6, 1, 235, 15, 4, 247, - 35, 8, 2, 1, 235, 15, 4, 247, 35, 8, 6, 1, 187, 4, 237, 43, 23, 217, 146, - 8, 2, 1, 187, 4, 237, 43, 23, 217, 146, 8, 6, 1, 187, 4, 198, 153, 23, - 217, 146, 8, 2, 1, 187, 4, 198, 153, 23, 217, 146, 8, 6, 1, 187, 4, 75, - 58, 8, 2, 1, 187, 4, 75, 58, 8, 6, 1, 187, 4, 75, 93, 23, 217, 146, 8, 2, - 1, 187, 4, 75, 93, 23, 217, 146, 8, 6, 1, 192, 160, 4, 217, 146, 8, 2, 1, - 192, 160, 4, 217, 146, 8, 2, 1, 220, 143, 4, 238, 175, 8, 2, 1, 215, 62, - 4, 238, 175, 8, 2, 1, 200, 44, 4, 238, 175, 8, 2, 1, 236, 139, 223, 35, - 8, 2, 1, 237, 201, 237, 2, 8, 2, 1, 208, 34, 237, 2, 8, 6, 1, 42, 4, 106, - 8, 6, 1, 247, 194, 4, 106, 8, 2, 1, 247, 194, 4, 106, 8, 6, 1, 220, 143, - 4, 164, 8, 6, 1, 200, 44, 4, 237, 39, 106, 8, 2, 1, 206, 9, 4, 200, 146, - 199, 215, 8, 2, 1, 191, 167, 4, 200, 146, 199, 215, 8, 6, 1, 231, 11, - 201, 63, 8, 2, 1, 231, 11, 201, 63, 8, 6, 1, 78, 4, 106, 8, 6, 1, 126, - 164, 8, 6, 1, 153, 196, 12, 8, 6, 1, 235, 15, 4, 106, 8, 2, 1, 235, 15, - 4, 106, 8, 6, 1, 223, 36, 4, 106, 8, 2, 1, 223, 36, 4, 106, 8, 6, 1, 2, - 208, 105, 4, 228, 251, 199, 215, 8, 2, 1, 208, 105, 4, 228, 251, 199, - 215, 8, 6, 1, 207, 222, 4, 106, 8, 2, 1, 207, 222, 4, 106, 8, 6, 1, 192, - 160, 4, 106, 8, 2, 1, 192, 160, 4, 106, 8, 2, 1, 153, 65, 8, 2, 1, 251, - 160, 8, 2, 1, 153, 251, 160, 8, 2, 1, 78, 4, 102, 8, 2, 1, 211, 77, 74, - 8, 2, 1, 247, 194, 4, 238, 175, 8, 2, 1, 238, 128, 4, 199, 215, 8, 2, 1, - 238, 128, 4, 102, 8, 2, 1, 207, 18, 71, 8, 2, 1, 205, 86, 8, 2, 1, 205, - 87, 4, 102, 8, 2, 1, 211, 77, 71, 8, 2, 1, 207, 18, 211, 77, 71, 8, 2, 1, - 207, 18, 211, 77, 235, 15, 4, 102, 8, 2, 1, 242, 219, 207, 18, 211, 77, - 71, 8, 2, 1, 236, 139, 223, 36, 4, 106, 8, 2, 1, 232, 52, 4, 102, 8, 2, - 1, 27, 232, 51, 8, 1, 2, 6, 232, 51, 8, 2, 1, 231, 211, 8, 2, 1, 207, - 140, 228, 187, 8, 2, 1, 153, 230, 116, 8, 2, 1, 230, 117, 4, 102, 8, 2, - 1, 229, 197, 4, 102, 8, 2, 1, 228, 74, 4, 106, 8, 2, 1, 223, 83, 8, 1, 2, - 6, 68, 8, 2, 1, 220, 143, 4, 82, 198, 152, 8, 2, 1, 220, 143, 4, 248, - 231, 8, 2, 1, 220, 143, 4, 207, 24, 102, 8, 2, 1, 219, 162, 8, 2, 1, 153, - 218, 168, 8, 2, 1, 153, 218, 169, 4, 179, 219, 212, 8, 2, 1, 218, 169, 4, - 102, 8, 2, 1, 215, 62, 4, 45, 102, 8, 2, 1, 215, 62, 4, 207, 24, 102, 8, - 1, 2, 6, 215, 61, 8, 2, 1, 249, 82, 74, 8, 1, 2, 6, 211, 151, 8, 2, 1, - 242, 219, 211, 110, 8, 2, 1, 209, 211, 8, 2, 1, 153, 146, 8, 2, 1, 153, - 207, 222, 4, 179, 219, 212, 8, 2, 1, 153, 207, 222, 4, 102, 8, 2, 1, 207, - 222, 4, 179, 219, 212, 8, 2, 1, 207, 222, 4, 199, 215, 8, 2, 1, 207, 222, - 4, 232, 233, 8, 2, 1, 207, 18, 207, 222, 4, 232, 233, 8, 1, 2, 6, 146, 8, - 1, 2, 6, 223, 93, 146, 8, 2, 1, 206, 9, 4, 102, 8, 2, 1, 234, 12, 8, 2, - 1, 236, 139, 223, 36, 4, 201, 28, 23, 102, 8, 2, 1, 201, 187, 207, 18, - 234, 12, 8, 2, 1, 234, 13, 4, 238, 175, 8, 2, 1, 153, 200, 43, 8, 2, 1, - 200, 44, 4, 207, 24, 102, 8, 2, 1, 126, 164, 8, 2, 1, 196, 70, 8, 2, 1, - 196, 13, 4, 102, 8, 2, 1, 153, 196, 12, 8, 2, 1, 153, 193, 224, 8, 2, 1, - 153, 192, 159, 8, 1, 2, 6, 192, 159, 8, 2, 1, 191, 167, 4, 207, 24, 102, - 8, 2, 1, 191, 167, 4, 238, 175, 8, 2, 1, 233, 178, 8, 2, 1, 233, 179, 4, - 238, 175, 8, 1, 231, 11, 201, 63, 8, 1, 209, 219, 195, 20, 232, 104, 8, - 1, 223, 93, 231, 11, 201, 63, 8, 1, 201, 36, 247, 193, 8, 1, 248, 172, - 242, 231, 8, 1, 2, 6, 250, 120, 8, 2, 1, 242, 219, 211, 77, 71, 8, 1, 2, - 6, 232, 52, 4, 102, 8, 1, 2, 6, 230, 116, 8, 2, 1, 223, 36, 4, 238, 212, - 8, 2, 1, 153, 222, 152, 8, 1, 2, 6, 172, 8, 2, 1, 208, 105, 4, 102, 8, 1, - 231, 11, 201, 64, 4, 106, 8, 1, 207, 18, 231, 11, 201, 64, 4, 106, 8, 2, - 1, 235, 37, 237, 2, 8, 2, 1, 237, 70, 237, 2, 8, 2, 1, 235, 37, 237, 3, - 4, 238, 175, 8, 2, 1, 197, 170, 237, 2, 8, 2, 1, 199, 79, 237, 2, 8, 2, - 1, 199, 152, 237, 3, 4, 238, 175, 8, 2, 1, 233, 37, 237, 2, 8, 2, 1, 218, - 227, 237, 2, 8, 2, 1, 218, 170, 237, 2, 8, 1, 248, 172, 210, 12, 8, 1, - 248, 180, 210, 12, 8, 2, 1, 153, 230, 117, 4, 232, 233, 8, 2, 1, 153, - 230, 117, 4, 232, 234, 23, 199, 215, 52, 1, 2, 230, 116, 52, 1, 2, 230, - 117, 4, 102, 52, 1, 2, 223, 35, 52, 1, 2, 146, 52, 1, 2, 153, 146, 52, 1, - 2, 153, 207, 222, 4, 102, 52, 1, 2, 6, 223, 93, 146, 52, 1, 2, 193, 224, - 52, 1, 2, 192, 159, 52, 1, 208, 215, 52, 1, 55, 208, 215, 52, 1, 153, - 242, 74, 52, 1, 251, 49, 52, 1, 207, 18, 242, 74, 52, 1, 50, 132, 206, - 188, 52, 1, 45, 132, 206, 188, 52, 1, 231, 11, 201, 63, 52, 1, 207, 18, - 231, 11, 201, 63, 52, 1, 45, 250, 235, 52, 1, 50, 250, 235, 52, 1, 133, - 250, 235, 52, 1, 144, 250, 235, 52, 1, 243, 2, 252, 60, 247, 92, 52, 1, - 81, 219, 112, 52, 1, 217, 146, 52, 1, 252, 47, 252, 60, 52, 1, 230, 211, - 252, 60, 52, 1, 130, 81, 219, 112, 52, 1, 130, 217, 146, 52, 1, 130, 230, - 211, 252, 60, 52, 1, 130, 252, 47, 252, 60, 52, 1, 197, 238, 242, 83, 52, - 1, 132, 197, 238, 242, 83, 52, 1, 247, 20, 50, 132, 206, 188, 52, 1, 247, - 20, 45, 132, 206, 188, 52, 1, 133, 199, 228, 52, 1, 144, 199, 228, 52, 1, - 108, 56, 52, 1, 216, 35, 56, 248, 36, 75, 58, 206, 189, 58, 211, 138, 2, - 198, 152, 55, 252, 47, 252, 60, 52, 1, 207, 2, 102, 52, 1, 238, 218, 252, - 60, 52, 1, 2, 231, 211, 52, 1, 2, 172, 52, 1, 2, 206, 8, 52, 1, 2, 192, - 235, 52, 1, 2, 207, 18, 231, 11, 201, 63, 52, 1, 233, 200, 163, 164, 52, - 1, 137, 163, 164, 52, 1, 216, 87, 163, 164, 52, 1, 130, 163, 164, 52, 1, - 233, 199, 163, 164, 52, 1, 192, 22, 237, 95, 163, 77, 52, 1, 192, 107, - 237, 95, 163, 77, 52, 1, 195, 18, 52, 1, 196, 109, 52, 1, 55, 251, 49, - 52, 1, 130, 144, 250, 235, 52, 1, 130, 133, 250, 235, 52, 1, 130, 45, - 250, 235, 52, 1, 130, 50, 250, 235, 52, 1, 130, 206, 188, 52, 1, 82, 230, - 211, 252, 60, 52, 1, 82, 55, 230, 211, 252, 60, 52, 1, 82, 55, 252, 47, - 252, 60, 52, 1, 130, 198, 152, 52, 1, 207, 147, 242, 83, 52, 1, 248, 249, - 137, 198, 79, 52, 1, 234, 95, 137, 198, 79, 52, 1, 248, 249, 130, 198, - 79, 52, 1, 234, 95, 130, 198, 79, 52, 1, 203, 104, 52, 1, 211, 77, 203, - 104, 52, 1, 130, 45, 57, 33, 230, 211, 252, 60, 33, 252, 47, 252, 60, 33, - 243, 2, 252, 60, 33, 198, 152, 33, 217, 146, 33, 210, 254, 33, 248, 36, - 33, 75, 58, 33, 237, 42, 33, 228, 251, 58, 33, 206, 189, 58, 33, 55, 252, - 47, 252, 60, 33, 247, 92, 33, 81, 219, 113, 58, 33, 55, 81, 219, 113, 58, - 33, 55, 230, 211, 252, 60, 33, 247, 119, 33, 223, 93, 248, 36, 33, 153, - 242, 75, 58, 33, 242, 75, 58, 33, 207, 18, 242, 75, 58, 33, 242, 75, 93, - 183, 33, 230, 211, 252, 61, 60, 33, 252, 47, 252, 61, 60, 33, 45, 199, - 229, 60, 33, 50, 199, 229, 60, 33, 45, 251, 116, 58, 33, 228, 187, 33, - 45, 132, 206, 189, 60, 33, 133, 199, 229, 60, 33, 144, 199, 229, 60, 33, - 108, 3, 60, 33, 216, 35, 3, 60, 33, 210, 190, 228, 251, 60, 33, 207, 24, - 228, 251, 60, 33, 75, 60, 33, 237, 43, 60, 33, 206, 189, 60, 33, 242, 75, - 60, 33, 247, 35, 33, 211, 138, 33, 81, 219, 113, 60, 33, 248, 29, 60, 33, - 223, 93, 55, 251, 15, 60, 33, 247, 93, 60, 33, 243, 2, 252, 61, 60, 33, - 248, 37, 60, 33, 223, 93, 248, 37, 60, 33, 198, 153, 60, 33, 217, 147, - 60, 33, 130, 219, 112, 33, 55, 130, 219, 112, 33, 198, 153, 210, 255, 33, - 203, 40, 201, 28, 210, 255, 33, 179, 201, 28, 210, 255, 33, 203, 40, 202, - 24, 210, 255, 33, 179, 202, 24, 210, 255, 33, 50, 132, 206, 189, 60, 33, - 223, 93, 248, 29, 60, 33, 51, 60, 33, 205, 62, 60, 33, 192, 236, 58, 33, - 81, 198, 152, 33, 55, 210, 254, 33, 230, 211, 163, 77, 33, 252, 47, 163, - 77, 33, 35, 210, 4, 33, 35, 221, 30, 33, 35, 237, 36, 198, 60, 33, 35, - 191, 233, 33, 248, 29, 58, 33, 234, 43, 3, 60, 33, 55, 81, 219, 113, 60, - 33, 45, 251, 116, 60, 33, 213, 12, 198, 153, 58, 33, 229, 1, 58, 33, 251, - 165, 234, 45, 119, 58, 33, 45, 50, 64, 60, 33, 196, 66, 64, 60, 33, 230, - 217, 222, 196, 33, 50, 250, 236, 58, 33, 45, 132, 206, 189, 58, 33, 233, - 34, 33, 192, 236, 60, 33, 45, 250, 236, 60, 33, 50, 250, 236, 60, 33, 50, - 250, 236, 23, 133, 250, 236, 60, 33, 50, 132, 206, 189, 58, 33, 75, 93, - 183, 33, 250, 194, 60, 33, 55, 206, 189, 60, 33, 191, 21, 58, 33, 55, - 248, 37, 60, 33, 55, 248, 36, 33, 55, 217, 146, 33, 55, 217, 147, 60, 33, - 55, 198, 152, 33, 55, 223, 93, 248, 36, 33, 55, 96, 64, 60, 33, 8, 2, 1, - 65, 33, 8, 2, 1, 71, 33, 8, 2, 1, 68, 33, 8, 2, 1, 74, 33, 8, 2, 1, 66, - 33, 8, 2, 1, 247, 193, 33, 8, 2, 1, 238, 127, 33, 8, 2, 1, 230, 116, 33, - 8, 2, 1, 218, 168, 33, 8, 2, 1, 146, 33, 8, 2, 1, 200, 43, 33, 8, 2, 1, - 196, 12, 33, 8, 2, 1, 192, 235, 35, 6, 1, 229, 185, 35, 2, 1, 229, 185, - 35, 6, 1, 251, 14, 205, 145, 35, 2, 1, 251, 14, 205, 145, 35, 212, 134, - 56, 35, 110, 212, 134, 56, 35, 6, 1, 210, 171, 237, 10, 35, 2, 1, 210, - 171, 237, 10, 35, 191, 233, 35, 2, 207, 18, 218, 206, 202, 197, 113, 35, - 2, 235, 138, 218, 206, 202, 197, 113, 35, 2, 207, 18, 235, 138, 218, 206, - 202, 197, 113, 35, 208, 13, 77, 35, 6, 1, 191, 240, 35, 198, 60, 35, 237, - 36, 198, 60, 35, 6, 1, 251, 161, 4, 198, 60, 35, 251, 94, 199, 108, 35, - 6, 1, 234, 48, 4, 198, 60, 35, 6, 1, 233, 254, 4, 198, 60, 35, 6, 1, 223, - 84, 4, 198, 60, 35, 6, 1, 211, 108, 4, 198, 60, 35, 6, 1, 196, 71, 4, - 198, 60, 35, 6, 1, 211, 111, 4, 198, 60, 35, 2, 1, 223, 84, 4, 237, 36, - 23, 198, 60, 35, 6, 1, 251, 160, 35, 6, 1, 248, 212, 35, 6, 1, 231, 211, - 35, 6, 1, 237, 106, 35, 6, 1, 234, 47, 35, 6, 1, 191, 76, 35, 6, 1, 233, - 253, 35, 6, 1, 199, 15, 35, 6, 1, 223, 83, 35, 6, 1, 222, 72, 35, 6, 1, - 220, 31, 35, 6, 1, 215, 155, 35, 6, 1, 212, 178, 35, 6, 1, 192, 207, 35, - 6, 1, 211, 107, 35, 6, 1, 209, 185, 35, 6, 1, 207, 3, 35, 6, 1, 202, 196, - 35, 6, 1, 199, 166, 35, 6, 1, 196, 70, 35, 6, 1, 209, 211, 35, 6, 1, 243, - 95, 35, 6, 1, 208, 176, 35, 6, 1, 211, 110, 35, 6, 1, 223, 84, 4, 237, - 35, 35, 6, 1, 196, 71, 4, 237, 35, 35, 2, 1, 251, 161, 4, 198, 60, 35, 2, - 1, 234, 48, 4, 198, 60, 35, 2, 1, 233, 254, 4, 198, 60, 35, 2, 1, 223, - 84, 4, 198, 60, 35, 2, 1, 196, 71, 4, 237, 36, 23, 198, 60, 35, 2, 1, - 251, 160, 35, 2, 1, 248, 212, 35, 2, 1, 231, 211, 35, 2, 1, 237, 106, 35, - 2, 1, 234, 47, 35, 2, 1, 191, 76, 35, 2, 1, 233, 253, 35, 2, 1, 199, 15, - 35, 2, 1, 223, 83, 35, 2, 1, 222, 72, 35, 2, 1, 220, 31, 35, 2, 1, 215, - 155, 35, 2, 1, 212, 178, 35, 2, 1, 192, 207, 35, 2, 1, 211, 107, 35, 2, - 1, 209, 185, 35, 2, 1, 207, 3, 35, 2, 1, 53, 202, 196, 35, 2, 1, 202, - 196, 35, 2, 1, 199, 166, 35, 2, 1, 196, 70, 35, 2, 1, 209, 211, 35, 2, 1, - 243, 95, 35, 2, 1, 208, 176, 35, 2, 1, 211, 110, 35, 2, 1, 223, 84, 4, - 237, 35, 35, 2, 1, 196, 71, 4, 237, 35, 35, 2, 1, 211, 108, 4, 198, 60, - 35, 2, 1, 196, 71, 4, 198, 60, 35, 2, 1, 211, 111, 4, 198, 60, 35, 6, - 222, 103, 113, 35, 248, 213, 113, 35, 199, 16, 113, 35, 196, 71, 4, 228, - 251, 113, 35, 196, 71, 4, 252, 47, 23, 228, 251, 113, 35, 196, 71, 4, - 237, 43, 23, 228, 251, 113, 35, 209, 212, 113, 35, 209, 186, 113, 35, - 222, 103, 113, 35, 1, 251, 14, 221, 35, 35, 2, 1, 251, 14, 221, 35, 35, - 1, 201, 73, 35, 2, 1, 201, 73, 35, 1, 237, 10, 35, 2, 1, 237, 10, 35, 1, - 221, 35, 35, 2, 1, 221, 35, 35, 1, 205, 145, 35, 2, 1, 205, 145, 94, 6, - 1, 203, 105, 94, 2, 1, 203, 105, 94, 6, 1, 233, 44, 94, 2, 1, 233, 44, - 94, 6, 1, 221, 195, 94, 2, 1, 221, 195, 94, 6, 1, 228, 242, 94, 2, 1, - 228, 242, 94, 6, 1, 231, 206, 94, 2, 1, 231, 206, 94, 6, 1, 203, 71, 94, - 2, 1, 203, 71, 94, 6, 1, 237, 122, 94, 2, 1, 237, 122, 35, 222, 73, 113, - 35, 207, 4, 113, 35, 218, 206, 202, 197, 113, 35, 1, 191, 240, 35, 6, - 199, 16, 113, 35, 218, 206, 234, 48, 113, 35, 207, 18, 218, 206, 234, 48, - 113, 35, 6, 1, 203, 56, 35, 2, 1, 203, 56, 35, 6, 218, 206, 202, 197, - 113, 35, 6, 1, 205, 142, 35, 2, 1, 205, 142, 35, 207, 4, 4, 201, 28, 113, - 35, 6, 207, 18, 218, 206, 202, 197, 113, 35, 6, 235, 138, 218, 206, 202, - 197, 113, 35, 6, 207, 18, 235, 138, 218, 206, 202, 197, 113, 38, 6, 1, - 223, 227, 4, 230, 210, 38, 6, 1, 223, 88, 38, 6, 1, 236, 192, 38, 6, 1, - 231, 20, 38, 6, 1, 196, 125, 223, 226, 38, 6, 1, 235, 32, 38, 6, 1, 247, - 203, 68, 38, 6, 1, 192, 33, 38, 6, 1, 223, 10, 38, 6, 1, 219, 76, 38, 6, - 1, 213, 150, 38, 6, 1, 197, 155, 38, 6, 1, 221, 103, 38, 6, 1, 228, 74, - 4, 230, 210, 38, 6, 1, 203, 40, 66, 38, 6, 1, 235, 28, 38, 6, 1, 65, 38, - 6, 1, 249, 17, 38, 6, 1, 195, 153, 38, 6, 1, 231, 77, 38, 6, 1, 237, 146, - 38, 6, 1, 223, 226, 38, 6, 1, 191, 62, 38, 6, 1, 191, 87, 38, 6, 1, 68, - 38, 6, 1, 203, 40, 68, 38, 6, 1, 155, 38, 6, 1, 234, 140, 38, 6, 1, 234, - 114, 38, 6, 1, 234, 103, 38, 6, 1, 74, 38, 6, 1, 210, 63, 38, 6, 1, 234, - 34, 38, 6, 1, 234, 22, 38, 6, 1, 199, 145, 38, 6, 1, 66, 38, 6, 1, 234, - 181, 38, 6, 1, 140, 38, 6, 1, 197, 161, 38, 6, 1, 243, 127, 38, 6, 1, - 203, 165, 38, 6, 1, 203, 116, 38, 6, 1, 230, 17, 56, 38, 6, 1, 192, 58, - 38, 6, 1, 202, 32, 56, 38, 6, 1, 71, 38, 6, 1, 191, 225, 38, 6, 1, 170, - 38, 2, 1, 65, 38, 2, 1, 249, 17, 38, 2, 1, 195, 153, 38, 2, 1, 231, 77, - 38, 2, 1, 237, 146, 38, 2, 1, 223, 226, 38, 2, 1, 191, 62, 38, 2, 1, 191, - 87, 38, 2, 1, 68, 38, 2, 1, 203, 40, 68, 38, 2, 1, 155, 38, 2, 1, 234, - 140, 38, 2, 1, 234, 114, 38, 2, 1, 234, 103, 38, 2, 1, 74, 38, 2, 1, 210, - 63, 38, 2, 1, 234, 34, 38, 2, 1, 234, 22, 38, 2, 1, 199, 145, 38, 2, 1, - 66, 38, 2, 1, 234, 181, 38, 2, 1, 140, 38, 2, 1, 197, 161, 38, 2, 1, 243, - 127, 38, 2, 1, 203, 165, 38, 2, 1, 203, 116, 38, 2, 1, 230, 17, 56, 38, - 2, 1, 192, 58, 38, 2, 1, 202, 32, 56, 38, 2, 1, 71, 38, 2, 1, 191, 225, - 38, 2, 1, 170, 38, 2, 1, 223, 227, 4, 230, 210, 38, 2, 1, 223, 88, 38, 2, - 1, 236, 192, 38, 2, 1, 231, 20, 38, 2, 1, 196, 125, 223, 226, 38, 2, 1, - 235, 32, 38, 2, 1, 247, 203, 68, 38, 2, 1, 192, 33, 38, 2, 1, 223, 10, - 38, 2, 1, 219, 76, 38, 2, 1, 213, 150, 38, 2, 1, 197, 155, 38, 2, 1, 221, - 103, 38, 2, 1, 228, 74, 4, 230, 210, 38, 2, 1, 203, 40, 66, 38, 2, 1, - 235, 28, 38, 6, 1, 211, 110, 38, 2, 1, 211, 110, 38, 6, 1, 192, 95, 38, - 2, 1, 192, 95, 38, 6, 1, 223, 81, 71, 38, 2, 1, 223, 81, 71, 38, 6, 1, - 219, 83, 191, 190, 38, 2, 1, 219, 83, 191, 190, 38, 6, 1, 223, 81, 219, - 83, 191, 190, 38, 2, 1, 223, 81, 219, 83, 191, 190, 38, 6, 1, 248, 175, - 191, 190, 38, 2, 1, 248, 175, 191, 190, 38, 6, 1, 223, 81, 248, 175, 191, - 190, 38, 2, 1, 223, 81, 248, 175, 191, 190, 38, 6, 1, 220, 248, 38, 2, 1, - 220, 248, 38, 6, 1, 208, 176, 38, 2, 1, 208, 176, 38, 6, 1, 232, 228, 38, - 2, 1, 232, 228, 38, 6, 1, 223, 37, 38, 2, 1, 223, 37, 38, 6, 1, 223, 38, - 4, 55, 230, 211, 252, 60, 38, 2, 1, 223, 38, 4, 55, 230, 211, 252, 60, - 38, 6, 1, 196, 128, 38, 2, 1, 196, 128, 38, 6, 1, 206, 115, 211, 110, 38, - 2, 1, 206, 115, 211, 110, 38, 6, 1, 211, 111, 4, 198, 122, 38, 2, 1, 211, - 111, 4, 198, 122, 38, 6, 1, 211, 30, 38, 2, 1, 211, 30, 38, 6, 1, 221, - 35, 38, 2, 1, 221, 35, 38, 198, 229, 56, 33, 38, 198, 122, 33, 38, 210, - 191, 33, 38, 237, 213, 209, 75, 33, 38, 208, 170, 209, 75, 33, 38, 209, - 54, 33, 38, 228, 141, 198, 229, 56, 33, 38, 216, 48, 56, 38, 6, 1, 203, - 40, 228, 74, 4, 199, 215, 38, 2, 1, 203, 40, 228, 74, 4, 199, 215, 38, 6, - 1, 204, 21, 56, 38, 2, 1, 204, 21, 56, 38, 6, 1, 234, 35, 4, 198, 182, - 38, 2, 1, 234, 35, 4, 198, 182, 38, 6, 1, 231, 78, 4, 196, 69, 38, 2, 1, - 231, 78, 4, 196, 69, 38, 6, 1, 231, 78, 4, 106, 38, 2, 1, 231, 78, 4, - 106, 38, 6, 1, 231, 78, 4, 82, 102, 38, 2, 1, 231, 78, 4, 82, 102, 38, 6, - 1, 191, 63, 4, 237, 87, 38, 2, 1, 191, 63, 4, 237, 87, 38, 6, 1, 191, 88, - 4, 237, 87, 38, 2, 1, 191, 88, 4, 237, 87, 38, 6, 1, 222, 142, 4, 237, - 87, 38, 2, 1, 222, 142, 4, 237, 87, 38, 6, 1, 222, 142, 4, 81, 106, 38, - 2, 1, 222, 142, 4, 81, 106, 38, 6, 1, 222, 142, 4, 106, 38, 2, 1, 222, - 142, 4, 106, 38, 6, 1, 249, 70, 155, 38, 2, 1, 249, 70, 155, 38, 6, 1, - 234, 104, 4, 237, 87, 38, 2, 1, 234, 104, 4, 237, 87, 38, 6, 34, 234, - 104, 231, 77, 38, 2, 34, 234, 104, 231, 77, 38, 6, 1, 210, 64, 4, 82, - 102, 38, 2, 1, 210, 64, 4, 82, 102, 38, 6, 1, 252, 67, 140, 38, 2, 1, - 252, 67, 140, 38, 6, 1, 234, 23, 4, 237, 87, 38, 2, 1, 234, 23, 4, 237, - 87, 38, 6, 1, 199, 146, 4, 237, 87, 38, 2, 1, 199, 146, 4, 237, 87, 38, - 6, 1, 201, 53, 66, 38, 2, 1, 201, 53, 66, 38, 6, 1, 201, 53, 126, 4, 106, - 38, 2, 1, 201, 53, 126, 4, 106, 38, 6, 1, 230, 105, 4, 237, 87, 38, 2, 1, - 230, 105, 4, 237, 87, 38, 6, 34, 199, 146, 197, 161, 38, 2, 34, 199, 146, - 197, 161, 38, 6, 1, 243, 128, 4, 237, 87, 38, 2, 1, 243, 128, 4, 237, 87, - 38, 6, 1, 243, 128, 4, 81, 106, 38, 2, 1, 243, 128, 4, 81, 106, 38, 6, 1, - 203, 82, 38, 2, 1, 203, 82, 38, 6, 1, 252, 67, 243, 127, 38, 2, 1, 252, - 67, 243, 127, 38, 6, 1, 252, 67, 243, 128, 4, 237, 87, 38, 2, 1, 252, 67, - 243, 128, 4, 237, 87, 38, 1, 210, 179, 38, 6, 1, 191, 63, 4, 248, 36, 38, - 2, 1, 191, 63, 4, 248, 36, 38, 6, 1, 222, 142, 4, 102, 38, 2, 1, 222, - 142, 4, 102, 38, 6, 1, 234, 141, 4, 199, 215, 38, 2, 1, 234, 141, 4, 199, - 215, 38, 6, 1, 234, 104, 4, 102, 38, 2, 1, 234, 104, 4, 102, 38, 6, 1, - 234, 104, 4, 199, 215, 38, 2, 1, 234, 104, 4, 199, 215, 38, 6, 1, 221, - 208, 243, 127, 38, 2, 1, 221, 208, 243, 127, 38, 6, 1, 234, 115, 4, 199, - 215, 38, 2, 1, 234, 115, 4, 199, 215, 38, 2, 1, 210, 179, 38, 6, 1, 42, - 4, 248, 36, 38, 2, 1, 42, 4, 248, 36, 38, 6, 1, 42, 4, 237, 42, 38, 2, 1, - 42, 4, 237, 42, 38, 6, 34, 42, 223, 226, 38, 2, 34, 42, 223, 226, 38, 6, - 1, 223, 227, 4, 248, 36, 38, 2, 1, 223, 227, 4, 248, 36, 38, 6, 1, 205, - 86, 38, 2, 1, 205, 86, 38, 6, 1, 205, 87, 4, 237, 42, 38, 2, 1, 205, 87, - 4, 237, 42, 38, 6, 1, 191, 63, 4, 237, 42, 38, 2, 1, 191, 63, 4, 237, 42, - 38, 6, 1, 191, 88, 4, 237, 42, 38, 2, 1, 191, 88, 4, 237, 42, 38, 6, 1, - 252, 67, 235, 32, 38, 2, 1, 252, 67, 235, 32, 38, 6, 1, 228, 74, 4, 217, - 146, 38, 2, 1, 228, 74, 4, 217, 146, 38, 6, 1, 228, 74, 4, 237, 42, 38, - 2, 1, 228, 74, 4, 237, 42, 38, 6, 1, 187, 4, 237, 42, 38, 2, 1, 187, 4, - 237, 42, 38, 6, 1, 249, 82, 74, 38, 2, 1, 249, 82, 74, 38, 6, 1, 249, 82, - 187, 4, 237, 42, 38, 2, 1, 249, 82, 187, 4, 237, 42, 38, 6, 1, 235, 15, - 4, 237, 42, 38, 2, 1, 235, 15, 4, 237, 42, 38, 6, 1, 126, 4, 217, 146, - 38, 2, 1, 126, 4, 217, 146, 38, 6, 1, 126, 4, 237, 42, 38, 2, 1, 126, 4, - 237, 42, 38, 6, 1, 126, 4, 55, 252, 46, 38, 2, 1, 126, 4, 55, 252, 46, - 38, 6, 1, 243, 128, 4, 237, 42, 38, 2, 1, 243, 128, 4, 237, 42, 38, 6, 1, - 231, 78, 4, 237, 87, 38, 2, 1, 231, 78, 4, 237, 87, 38, 6, 1, 192, 59, 4, - 237, 42, 38, 2, 1, 192, 59, 4, 237, 42, 38, 6, 1, 231, 78, 4, 201, 28, - 23, 102, 38, 2, 1, 231, 78, 4, 201, 28, 23, 102, 38, 6, 1, 230, 105, 4, - 102, 38, 2, 1, 230, 105, 4, 102, 38, 6, 1, 230, 105, 4, 106, 38, 2, 1, - 230, 105, 4, 106, 38, 6, 1, 221, 45, 237, 146, 38, 2, 1, 221, 45, 237, - 146, 38, 6, 1, 221, 45, 236, 192, 38, 2, 1, 221, 45, 236, 192, 38, 6, 1, - 221, 45, 191, 12, 38, 2, 1, 221, 45, 191, 12, 38, 6, 1, 221, 45, 235, 24, - 38, 2, 1, 221, 45, 235, 24, 38, 6, 1, 221, 45, 219, 76, 38, 2, 1, 221, - 45, 219, 76, 38, 6, 1, 221, 45, 213, 150, 38, 2, 1, 221, 45, 213, 150, - 38, 6, 1, 221, 45, 202, 115, 38, 2, 1, 221, 45, 202, 115, 38, 6, 1, 221, - 45, 198, 116, 38, 2, 1, 221, 45, 198, 116, 38, 6, 1, 207, 18, 191, 87, - 38, 2, 1, 207, 18, 191, 87, 38, 6, 1, 234, 141, 4, 102, 38, 2, 1, 234, - 141, 4, 102, 38, 6, 1, 219, 159, 38, 2, 1, 219, 159, 38, 6, 1, 207, 6, - 38, 2, 1, 207, 6, 38, 6, 1, 192, 129, 38, 2, 1, 192, 129, 38, 6, 1, 208, - 96, 38, 2, 1, 208, 96, 38, 6, 1, 193, 125, 38, 2, 1, 193, 125, 38, 6, 1, - 251, 188, 155, 38, 2, 1, 251, 188, 155, 38, 6, 1, 234, 141, 4, 82, 102, - 38, 2, 1, 234, 141, 4, 82, 102, 38, 6, 1, 234, 104, 4, 82, 102, 38, 2, 1, - 234, 104, 4, 82, 102, 38, 6, 1, 210, 64, 4, 237, 87, 38, 2, 1, 210, 64, - 4, 237, 87, 38, 6, 1, 203, 83, 4, 237, 87, 38, 2, 1, 203, 83, 4, 237, 87, - 38, 6, 1, 234, 104, 4, 45, 102, 38, 2, 1, 234, 104, 4, 45, 102, 38, 6, 1, - 235, 16, 38, 2, 1, 235, 16, 38, 6, 1, 237, 195, 38, 2, 1, 237, 195, 38, - 6, 1, 234, 141, 4, 237, 87, 38, 2, 1, 234, 141, 4, 237, 87, 250, 249, 6, - 1, 250, 128, 250, 249, 6, 1, 248, 229, 250, 249, 6, 1, 231, 40, 250, 249, - 6, 1, 238, 32, 250, 249, 6, 1, 234, 195, 250, 249, 6, 1, 191, 123, 250, - 249, 6, 1, 234, 173, 250, 249, 6, 1, 233, 255, 250, 249, 6, 1, 159, 250, - 249, 6, 1, 191, 62, 250, 249, 6, 1, 223, 131, 250, 249, 6, 1, 219, 80, - 250, 249, 6, 1, 192, 212, 250, 249, 6, 1, 247, 160, 250, 249, 6, 1, 221, - 251, 250, 249, 6, 1, 229, 23, 250, 249, 6, 1, 223, 32, 250, 249, 6, 1, - 231, 88, 250, 249, 6, 1, 243, 117, 250, 249, 6, 1, 216, 186, 250, 249, 6, - 1, 192, 33, 250, 249, 6, 1, 212, 253, 250, 249, 6, 1, 203, 165, 250, 249, - 6, 1, 195, 24, 250, 249, 6, 1, 247, 1, 250, 249, 6, 1, 210, 41, 250, 249, - 6, 1, 222, 247, 250, 249, 6, 1, 165, 250, 249, 6, 1, 205, 39, 250, 249, - 6, 1, 195, 74, 250, 249, 6, 1, 198, 119, 250, 249, 6, 1, 207, 71, 250, - 249, 6, 1, 242, 99, 250, 249, 6, 1, 192, 17, 250, 249, 6, 1, 209, 114, - 250, 249, 6, 1, 222, 6, 250, 249, 6, 1, 211, 136, 250, 249, 6, 1, 233, - 46, 250, 249, 52, 1, 45, 132, 206, 188, 250, 249, 251, 49, 250, 249, 234, - 107, 77, 250, 249, 233, 216, 77, 250, 249, 242, 74, 250, 249, 208, 13, - 77, 250, 249, 252, 68, 77, 250, 249, 2, 1, 153, 250, 128, 250, 249, 2, 1, - 250, 128, 250, 249, 2, 1, 248, 229, 250, 249, 2, 1, 231, 40, 250, 249, 2, - 1, 238, 32, 250, 249, 2, 1, 234, 195, 250, 249, 2, 1, 191, 123, 250, 249, - 2, 1, 234, 173, 250, 249, 2, 1, 233, 255, 250, 249, 2, 1, 159, 250, 249, - 2, 1, 191, 62, 250, 249, 2, 1, 223, 131, 250, 249, 2, 1, 219, 80, 250, - 249, 2, 1, 192, 212, 250, 249, 2, 1, 247, 160, 250, 249, 2, 1, 221, 251, - 250, 249, 2, 1, 229, 23, 250, 249, 2, 1, 223, 32, 250, 249, 2, 1, 231, - 88, 250, 249, 2, 1, 243, 117, 250, 249, 2, 1, 216, 186, 250, 249, 2, 1, - 192, 33, 250, 249, 2, 1, 212, 253, 250, 249, 2, 1, 203, 165, 250, 249, 2, - 1, 195, 24, 250, 249, 2, 1, 247, 1, 250, 249, 2, 1, 210, 41, 250, 249, 2, - 1, 222, 247, 250, 249, 2, 1, 165, 250, 249, 2, 1, 205, 39, 250, 249, 2, - 1, 195, 74, 250, 249, 2, 1, 198, 119, 250, 249, 2, 1, 207, 71, 250, 249, - 2, 1, 242, 99, 250, 249, 2, 1, 192, 17, 250, 249, 2, 1, 209, 114, 250, - 249, 2, 1, 222, 6, 250, 249, 2, 1, 211, 136, 250, 249, 2, 1, 233, 46, - 250, 249, 2, 34, 234, 196, 192, 17, 250, 249, 2, 1, 11, 4, 106, 250, 249, - 232, 80, 201, 63, 250, 249, 228, 88, 206, 207, 250, 249, 233, 251, 56, - 219, 223, 250, 249, 233, 251, 56, 250, 249, 235, 110, 56, 136, 252, 61, - 233, 246, 136, 252, 61, 205, 40, 136, 252, 61, 203, 141, 136, 252, 61, - 191, 99, 208, 78, 136, 252, 61, 191, 99, 231, 230, 136, 252, 61, 198, - 134, 136, 252, 61, 207, 15, 136, 252, 61, 191, 97, 136, 252, 61, 210, 97, - 136, 252, 61, 192, 48, 136, 252, 61, 199, 56, 136, 252, 61, 231, 139, - 136, 252, 61, 231, 140, 215, 110, 136, 252, 61, 231, 137, 136, 252, 61, - 208, 80, 210, 130, 136, 252, 61, 199, 103, 231, 158, 136, 252, 61, 210, - 69, 136, 252, 61, 250, 173, 230, 85, 136, 252, 61, 215, 121, 136, 252, - 61, 217, 117, 136, 252, 61, 216, 175, 136, 252, 61, 216, 176, 222, 7, - 136, 252, 61, 237, 222, 136, 252, 61, 208, 91, 136, 252, 61, 199, 103, - 208, 73, 136, 252, 61, 192, 61, 248, 230, 191, 247, 136, 252, 61, 211, - 117, 136, 252, 61, 223, 183, 136, 252, 61, 237, 123, 136, 252, 61, 191, - 19, 136, 87, 217, 34, 243, 10, 136, 209, 62, 203, 85, 136, 209, 62, 230, - 8, 205, 40, 136, 209, 62, 230, 8, 210, 88, 136, 209, 62, 230, 8, 208, 84, - 136, 209, 62, 229, 119, 136, 209, 62, 197, 158, 136, 209, 62, 205, 40, - 136, 209, 62, 210, 88, 136, 209, 62, 208, 84, 136, 209, 62, 229, 7, 136, - 209, 62, 229, 8, 230, 10, 40, 195, 158, 136, 209, 62, 208, 18, 136, 209, - 62, 238, 17, 211, 57, 217, 70, 136, 209, 62, 216, 164, 136, 208, 152, - 217, 67, 136, 209, 62, 207, 161, 136, 208, 152, 210, 99, 136, 209, 62, - 203, 70, 236, 140, 136, 209, 62, 202, 175, 236, 140, 136, 208, 152, 202, - 33, 210, 90, 136, 87, 116, 236, 140, 136, 87, 110, 236, 140, 136, 208, - 152, 212, 131, 230, 84, 136, 209, 62, 208, 85, 208, 78, 136, 1, 251, 192, - 136, 1, 248, 214, 136, 1, 231, 38, 136, 1, 237, 253, 136, 1, 229, 245, - 136, 1, 195, 158, 136, 1, 191, 91, 136, 1, 229, 186, 136, 1, 199, 73, - 136, 1, 191, 250, 136, 1, 53, 222, 106, 136, 1, 222, 106, 136, 1, 220, - 27, 136, 1, 53, 216, 193, 136, 1, 216, 193, 136, 1, 53, 212, 130, 136, 1, - 212, 130, 136, 1, 205, 148, 136, 1, 250, 126, 136, 1, 53, 210, 63, 136, - 1, 210, 63, 136, 1, 53, 197, 163, 136, 1, 197, 163, 136, 1, 208, 42, 136, - 1, 207, 38, 136, 1, 203, 69, 136, 1, 199, 162, 136, 191, 251, 197, 241, + 173, 248, 55, 81, 219, 114, 50, 238, 173, 248, 55, 198, 152, 213, 39, + 201, 248, 223, 95, 233, 218, 77, 247, 26, 56, 209, 10, 56, 238, 172, 56, + 192, 71, 56, 248, 24, 164, 205, 55, 56, 237, 44, 239, 8, 56, 233, 42, + 211, 52, 223, 146, 219, 221, 55, 251, 118, 207, 254, 77, 213, 14, 56, + 202, 33, 228, 90, 207, 79, 56, 217, 148, 237, 127, 56, 209, 82, 56, 200, + 182, 109, 200, 182, 138, 252, 49, 252, 62, 216, 93, 56, 209, 144, 56, 82, + 236, 142, 247, 37, 200, 182, 107, 217, 42, 211, 52, 223, 146, 206, 204, + 55, 251, 118, 207, 254, 77, 193, 246, 232, 120, 91, 208, 24, 193, 246, + 232, 120, 91, 230, 72, 193, 246, 232, 120, 115, 208, 22, 223, 95, 208, + 15, 77, 8, 6, 1, 42, 4, 230, 212, 8, 6, 1, 42, 4, 252, 48, 8, 6, 1, 42, + 4, 243, 3, 8, 6, 1, 42, 4, 198, 152, 8, 6, 1, 42, 4, 237, 44, 8, 6, 1, + 42, 4, 206, 190, 58, 8, 6, 1, 252, 27, 8, 6, 1, 247, 196, 4, 247, 37, 8, + 6, 1, 235, 17, 4, 230, 212, 8, 6, 1, 235, 17, 4, 252, 48, 8, 6, 1, 235, + 17, 4, 243, 3, 8, 6, 1, 235, 17, 4, 237, 44, 8, 6, 1, 228, 76, 4, 230, + 212, 8, 6, 1, 228, 76, 4, 252, 48, 8, 6, 1, 228, 76, 4, 243, 3, 8, 6, 1, + 228, 76, 4, 237, 44, 8, 6, 1, 233, 250, 8, 6, 1, 215, 64, 4, 198, 152, 8, + 6, 1, 187, 4, 230, 212, 8, 6, 1, 187, 4, 252, 48, 8, 6, 1, 187, 4, 243, + 3, 8, 6, 1, 187, 4, 198, 152, 8, 6, 1, 187, 4, 237, 44, 215, 129, 56, 8, + 6, 1, 187, 4, 106, 8, 6, 1, 126, 4, 230, 212, 8, 6, 1, 126, 4, 252, 48, + 8, 6, 1, 126, 4, 243, 3, 8, 6, 1, 126, 4, 237, 44, 8, 6, 1, 192, 160, 4, + 252, 48, 8, 6, 1, 198, 233, 8, 2, 1, 203, 128, 206, 9, 8, 2, 1, 42, 4, + 230, 212, 8, 2, 1, 42, 4, 252, 48, 8, 2, 1, 42, 4, 243, 3, 8, 2, 1, 42, + 4, 198, 152, 8, 2, 1, 42, 4, 237, 44, 8, 2, 1, 42, 4, 206, 190, 58, 8, 2, + 1, 252, 27, 8, 2, 1, 247, 196, 4, 247, 37, 8, 2, 1, 235, 17, 4, 230, 212, + 8, 2, 1, 235, 17, 4, 252, 48, 8, 2, 1, 235, 17, 4, 243, 3, 8, 2, 1, 235, + 17, 4, 237, 44, 8, 2, 1, 228, 76, 4, 230, 212, 8, 2, 1, 228, 76, 4, 252, + 48, 8, 2, 1, 228, 76, 4, 243, 3, 8, 2, 1, 228, 76, 4, 237, 44, 8, 2, 1, + 233, 250, 8, 2, 1, 215, 64, 4, 198, 152, 8, 2, 1, 187, 4, 230, 212, 8, 2, + 1, 187, 4, 252, 48, 8, 2, 1, 187, 4, 243, 3, 8, 2, 1, 187, 4, 198, 152, + 8, 2, 1, 187, 4, 237, 44, 236, 202, 56, 8, 2, 1, 187, 4, 106, 8, 2, 1, + 126, 4, 230, 212, 8, 2, 1, 126, 4, 252, 48, 8, 2, 1, 126, 4, 243, 3, 8, + 2, 1, 126, 4, 237, 44, 8, 2, 1, 192, 160, 4, 252, 48, 8, 2, 1, 198, 233, + 8, 2, 1, 192, 160, 4, 237, 44, 8, 6, 1, 42, 4, 217, 148, 8, 2, 1, 42, 4, + 217, 148, 8, 6, 1, 42, 4, 248, 38, 8, 2, 1, 42, 4, 248, 38, 8, 6, 1, 42, + 4, 211, 140, 8, 2, 1, 42, 4, 211, 140, 8, 6, 1, 247, 196, 4, 252, 48, 8, + 2, 1, 247, 196, 4, 252, 48, 8, 6, 1, 247, 196, 4, 243, 3, 8, 2, 1, 247, + 196, 4, 243, 3, 8, 6, 1, 247, 196, 4, 75, 58, 8, 2, 1, 247, 196, 4, 75, + 58, 8, 6, 1, 247, 196, 4, 247, 94, 8, 2, 1, 247, 196, 4, 247, 94, 8, 6, + 1, 238, 130, 4, 247, 94, 8, 2, 1, 238, 130, 4, 247, 94, 8, 6, 1, 238, + 130, 4, 106, 8, 2, 1, 238, 130, 4, 106, 8, 6, 1, 235, 17, 4, 217, 148, 8, + 2, 1, 235, 17, 4, 217, 148, 8, 6, 1, 235, 17, 4, 248, 38, 8, 2, 1, 235, + 17, 4, 248, 38, 8, 6, 1, 235, 17, 4, 75, 58, 8, 2, 1, 235, 17, 4, 75, 58, + 8, 6, 1, 235, 17, 4, 211, 140, 8, 2, 1, 235, 17, 4, 211, 140, 8, 6, 1, + 235, 17, 4, 247, 94, 8, 2, 1, 235, 17, 4, 247, 94, 8, 6, 1, 232, 54, 4, + 243, 3, 8, 2, 1, 232, 54, 4, 243, 3, 8, 6, 1, 232, 54, 4, 248, 38, 8, 2, + 1, 232, 54, 4, 248, 38, 8, 6, 1, 232, 54, 4, 75, 58, 8, 2, 1, 232, 54, 4, + 75, 58, 8, 6, 1, 232, 54, 4, 247, 37, 8, 2, 1, 232, 54, 4, 247, 37, 8, 6, + 1, 230, 119, 4, 243, 3, 8, 2, 1, 230, 119, 4, 243, 3, 8, 6, 1, 230, 119, + 4, 106, 8, 2, 1, 230, 119, 4, 106, 8, 6, 1, 228, 76, 4, 198, 152, 8, 2, + 1, 228, 76, 4, 198, 152, 8, 6, 1, 228, 76, 4, 217, 148, 8, 2, 1, 228, 76, + 4, 217, 148, 8, 6, 1, 228, 76, 4, 248, 38, 8, 2, 1, 228, 76, 4, 248, 38, + 8, 6, 1, 228, 76, 4, 211, 140, 8, 2, 1, 228, 76, 4, 211, 140, 8, 6, 1, + 228, 76, 4, 75, 58, 8, 2, 1, 236, 141, 68, 8, 6, 34, 223, 199, 8, 2, 34, + 223, 199, 8, 6, 1, 223, 38, 4, 243, 3, 8, 2, 1, 223, 38, 4, 243, 3, 8, 6, + 1, 222, 155, 4, 247, 37, 8, 2, 1, 222, 155, 4, 247, 37, 8, 2, 1, 221, 10, + 8, 6, 1, 220, 145, 4, 252, 48, 8, 2, 1, 220, 145, 4, 252, 48, 8, 6, 1, + 220, 145, 4, 247, 37, 8, 2, 1, 220, 145, 4, 247, 37, 8, 6, 1, 220, 145, + 4, 247, 94, 8, 2, 1, 220, 145, 4, 247, 94, 8, 6, 1, 220, 145, 4, 82, 236, + 142, 8, 2, 1, 220, 145, 4, 82, 236, 142, 8, 6, 1, 220, 145, 4, 106, 8, 2, + 1, 220, 145, 4, 106, 8, 6, 1, 215, 64, 4, 252, 48, 8, 2, 1, 215, 64, 4, + 252, 48, 8, 6, 1, 215, 64, 4, 247, 37, 8, 2, 1, 215, 64, 4, 247, 37, 8, + 6, 1, 215, 64, 4, 247, 94, 8, 2, 1, 215, 64, 4, 247, 94, 8, 2, 1, 215, + 64, 208, 235, 247, 207, 251, 51, 8, 6, 1, 234, 90, 8, 2, 1, 234, 90, 8, + 6, 1, 187, 4, 217, 148, 8, 2, 1, 187, 4, 217, 148, 8, 6, 1, 187, 4, 248, + 38, 8, 2, 1, 187, 4, 248, 38, 8, 6, 1, 187, 4, 55, 252, 48, 8, 2, 1, 187, + 4, 55, 252, 48, 8, 6, 34, 211, 153, 8, 2, 34, 211, 153, 8, 6, 1, 207, + 224, 4, 252, 48, 8, 2, 1, 207, 224, 4, 252, 48, 8, 6, 1, 207, 224, 4, + 247, 37, 8, 2, 1, 207, 224, 4, 247, 37, 8, 6, 1, 207, 224, 4, 247, 94, 8, + 2, 1, 207, 224, 4, 247, 94, 8, 6, 1, 206, 10, 4, 252, 48, 8, 2, 1, 206, + 10, 4, 252, 48, 8, 6, 1, 206, 10, 4, 243, 3, 8, 2, 1, 206, 10, 4, 243, 3, + 8, 6, 1, 206, 10, 4, 247, 37, 8, 2, 1, 206, 10, 4, 247, 37, 8, 6, 1, 206, + 10, 4, 247, 94, 8, 2, 1, 206, 10, 4, 247, 94, 8, 6, 1, 200, 44, 4, 247, + 37, 8, 2, 1, 200, 44, 4, 247, 37, 8, 6, 1, 200, 44, 4, 247, 94, 8, 2, 1, + 200, 44, 4, 247, 94, 8, 6, 1, 200, 44, 4, 106, 8, 2, 1, 200, 44, 4, 106, + 8, 6, 1, 126, 4, 198, 152, 8, 2, 1, 126, 4, 198, 152, 8, 6, 1, 126, 4, + 217, 148, 8, 2, 1, 126, 4, 217, 148, 8, 6, 1, 126, 4, 248, 38, 8, 2, 1, + 126, 4, 248, 38, 8, 6, 1, 126, 4, 206, 190, 58, 8, 2, 1, 126, 4, 206, + 190, 58, 8, 6, 1, 126, 4, 55, 252, 48, 8, 2, 1, 126, 4, 55, 252, 48, 8, + 6, 1, 126, 4, 211, 140, 8, 2, 1, 126, 4, 211, 140, 8, 6, 1, 193, 225, 4, + 243, 3, 8, 2, 1, 193, 225, 4, 243, 3, 8, 6, 1, 192, 160, 4, 243, 3, 8, 2, + 1, 192, 160, 4, 243, 3, 8, 6, 1, 192, 160, 4, 237, 44, 8, 6, 1, 191, 167, + 4, 252, 48, 8, 2, 1, 191, 167, 4, 252, 48, 8, 6, 1, 191, 167, 4, 75, 58, + 8, 2, 1, 191, 167, 4, 75, 58, 8, 6, 1, 191, 167, 4, 247, 94, 8, 2, 1, + 191, 167, 4, 247, 94, 8, 2, 1, 180, 206, 9, 8, 2, 1, 78, 4, 106, 8, 6, 1, + 78, 4, 102, 8, 6, 1, 78, 4, 198, 51, 8, 2, 1, 78, 4, 198, 51, 8, 6, 1, + 163, 169, 8, 2, 1, 163, 169, 8, 6, 1, 211, 79, 74, 8, 6, 1, 247, 196, 4, + 102, 8, 2, 1, 247, 196, 4, 102, 8, 6, 1, 252, 2, 238, 129, 8, 6, 1, 238, + 130, 4, 102, 8, 6, 1, 238, 130, 4, 198, 51, 8, 2, 1, 238, 130, 4, 198, + 51, 8, 2, 1, 154, 237, 108, 8, 6, 1, 207, 19, 71, 8, 6, 1, 205, 87, 8, 6, + 1, 211, 79, 71, 8, 6, 1, 233, 178, 4, 102, 8, 2, 1, 233, 178, 4, 102, 8, + 6, 1, 232, 54, 4, 102, 8, 6, 1, 231, 213, 8, 2, 1, 228, 128, 8, 6, 1, + 223, 85, 8, 6, 1, 228, 76, 4, 106, 8, 6, 1, 222, 155, 4, 102, 8, 2, 1, + 222, 155, 4, 102, 8, 2, 1, 220, 145, 4, 164, 8, 2, 1, 220, 35, 4, 106, 8, + 6, 1, 154, 218, 170, 8, 6, 1, 215, 64, 4, 45, 102, 8, 2, 1, 215, 64, 4, + 180, 50, 219, 214, 8, 6, 1, 187, 4, 82, 198, 152, 8, 6, 1, 187, 4, 228, + 189, 8, 2, 1, 187, 4, 228, 189, 8, 6, 1, 211, 135, 8, 2, 1, 211, 135, 8, + 6, 1, 210, 239, 4, 102, 8, 2, 1, 210, 239, 4, 102, 8, 1, 191, 228, 8, 6, + 1, 163, 109, 8, 2, 1, 163, 109, 8, 6, 1, 234, 14, 8, 1, 207, 19, 234, 15, + 219, 6, 8, 2, 1, 200, 44, 4, 210, 194, 102, 8, 6, 1, 200, 44, 4, 102, 8, + 2, 1, 200, 44, 4, 102, 8, 6, 1, 200, 44, 4, 207, 25, 102, 8, 6, 1, 126, + 4, 228, 189, 8, 2, 1, 126, 4, 228, 189, 8, 6, 1, 196, 70, 8, 6, 1, 196, + 13, 4, 102, 8, 6, 1, 192, 160, 4, 102, 8, 2, 1, 192, 160, 4, 102, 8, 6, + 1, 191, 167, 4, 106, 8, 2, 1, 191, 167, 4, 106, 8, 6, 1, 233, 180, 8, 6, + 1, 233, 181, 207, 18, 8, 2, 1, 233, 181, 207, 18, 8, 2, 1, 233, 181, 4, + 199, 215, 8, 1, 105, 4, 106, 8, 6, 1, 163, 150, 8, 2, 1, 163, 150, 8, 1, + 223, 95, 231, 13, 201, 65, 4, 106, 8, 1, 192, 238, 8, 1, 237, 100, 242, + 233, 8, 1, 220, 5, 242, 233, 8, 1, 251, 152, 242, 233, 8, 1, 207, 25, + 242, 233, 8, 6, 1, 235, 39, 4, 247, 94, 8, 6, 1, 238, 130, 4, 2, 1, 191, + 167, 4, 247, 94, 8, 2, 1, 235, 39, 4, 247, 94, 8, 6, 1, 219, 79, 8, 6, 1, + 220, 145, 4, 2, 1, 223, 37, 8, 2, 1, 219, 79, 8, 6, 1, 213, 160, 8, 6, 1, + 215, 64, 4, 2, 1, 223, 37, 8, 2, 1, 213, 160, 8, 6, 1, 42, 4, 247, 94, 8, + 2, 1, 42, 4, 247, 94, 8, 6, 1, 228, 76, 4, 247, 94, 8, 2, 1, 228, 76, 4, + 247, 94, 8, 6, 1, 187, 4, 247, 94, 8, 2, 1, 187, 4, 247, 94, 8, 6, 1, + 126, 4, 247, 94, 8, 2, 1, 126, 4, 247, 94, 8, 6, 1, 126, 4, 237, 45, 23, + 217, 148, 8, 2, 1, 126, 4, 237, 45, 23, 217, 148, 8, 6, 1, 126, 4, 237, + 45, 23, 252, 48, 8, 2, 1, 126, 4, 237, 45, 23, 252, 48, 8, 6, 1, 126, 4, + 237, 45, 23, 247, 94, 8, 2, 1, 126, 4, 237, 45, 23, 247, 94, 8, 6, 1, + 126, 4, 237, 45, 23, 230, 212, 8, 2, 1, 126, 4, 237, 45, 23, 230, 212, 8, + 2, 1, 154, 71, 8, 6, 1, 42, 4, 237, 45, 23, 217, 148, 8, 2, 1, 42, 4, + 237, 45, 23, 217, 148, 8, 6, 1, 42, 4, 75, 93, 23, 217, 148, 8, 2, 1, 42, + 4, 75, 93, 23, 217, 148, 8, 6, 1, 252, 28, 4, 217, 148, 8, 2, 1, 252, 28, + 4, 217, 148, 8, 6, 1, 232, 54, 4, 106, 8, 2, 1, 232, 54, 4, 106, 8, 6, 1, + 232, 54, 4, 247, 94, 8, 2, 1, 232, 54, 4, 247, 94, 8, 6, 1, 222, 155, 4, + 247, 94, 8, 2, 1, 222, 155, 4, 247, 94, 8, 6, 1, 187, 4, 211, 140, 8, 2, + 1, 187, 4, 211, 140, 8, 6, 1, 187, 4, 211, 141, 23, 217, 148, 8, 2, 1, + 187, 4, 211, 141, 23, 217, 148, 8, 6, 1, 233, 181, 4, 247, 94, 8, 2, 1, + 233, 181, 4, 247, 94, 8, 2, 1, 223, 38, 4, 247, 94, 8, 6, 1, 235, 38, 8, + 6, 1, 238, 130, 4, 2, 1, 191, 166, 8, 2, 1, 235, 38, 8, 6, 1, 232, 54, 4, + 252, 48, 8, 2, 1, 232, 54, 4, 252, 48, 8, 6, 1, 228, 125, 8, 6, 1, 192, + 238, 8, 6, 1, 215, 64, 4, 230, 212, 8, 2, 1, 215, 64, 4, 230, 212, 8, 6, + 1, 42, 4, 206, 190, 93, 23, 252, 48, 8, 2, 1, 42, 4, 206, 190, 93, 23, + 252, 48, 8, 6, 1, 252, 28, 4, 252, 48, 8, 2, 1, 252, 28, 4, 252, 48, 8, + 6, 1, 187, 4, 201, 29, 23, 252, 48, 8, 2, 1, 187, 4, 201, 29, 23, 252, + 48, 8, 6, 1, 42, 4, 55, 230, 212, 8, 2, 1, 42, 4, 55, 230, 212, 8, 6, 1, + 42, 4, 223, 95, 248, 38, 8, 2, 1, 42, 4, 223, 95, 248, 38, 8, 6, 1, 235, + 17, 4, 55, 230, 212, 8, 2, 1, 235, 17, 4, 55, 230, 212, 8, 6, 1, 235, 17, + 4, 223, 95, 248, 38, 8, 2, 1, 235, 17, 4, 223, 95, 248, 38, 8, 6, 1, 228, + 76, 4, 55, 230, 212, 8, 2, 1, 228, 76, 4, 55, 230, 212, 8, 6, 1, 228, 76, + 4, 223, 95, 248, 38, 8, 2, 1, 228, 76, 4, 223, 95, 248, 38, 8, 6, 1, 187, + 4, 55, 230, 212, 8, 2, 1, 187, 4, 55, 230, 212, 8, 6, 1, 187, 4, 223, 95, + 248, 38, 8, 2, 1, 187, 4, 223, 95, 248, 38, 8, 6, 1, 207, 224, 4, 55, + 230, 212, 8, 2, 1, 207, 224, 4, 55, 230, 212, 8, 6, 1, 207, 224, 4, 223, + 95, 248, 38, 8, 2, 1, 207, 224, 4, 223, 95, 248, 38, 8, 6, 1, 126, 4, 55, + 230, 212, 8, 2, 1, 126, 4, 55, 230, 212, 8, 6, 1, 126, 4, 223, 95, 248, + 38, 8, 2, 1, 126, 4, 223, 95, 248, 38, 8, 6, 1, 206, 10, 4, 242, 77, 60, + 8, 2, 1, 206, 10, 4, 242, 77, 60, 8, 6, 1, 200, 44, 4, 242, 77, 60, 8, 2, + 1, 200, 44, 4, 242, 77, 60, 8, 6, 1, 191, 248, 8, 2, 1, 191, 248, 8, 6, + 1, 230, 119, 4, 247, 94, 8, 2, 1, 230, 119, 4, 247, 94, 8, 6, 1, 215, 64, + 4, 180, 50, 219, 214, 8, 2, 1, 238, 130, 4, 238, 177, 8, 6, 1, 211, 21, + 8, 2, 1, 211, 21, 8, 6, 1, 191, 167, 4, 102, 8, 2, 1, 191, 167, 4, 102, + 8, 6, 1, 42, 4, 75, 58, 8, 2, 1, 42, 4, 75, 58, 8, 6, 1, 235, 17, 4, 247, + 37, 8, 2, 1, 235, 17, 4, 247, 37, 8, 6, 1, 187, 4, 237, 45, 23, 217, 148, + 8, 2, 1, 187, 4, 237, 45, 23, 217, 148, 8, 6, 1, 187, 4, 198, 153, 23, + 217, 148, 8, 2, 1, 187, 4, 198, 153, 23, 217, 148, 8, 6, 1, 187, 4, 75, + 58, 8, 2, 1, 187, 4, 75, 58, 8, 6, 1, 187, 4, 75, 93, 23, 217, 148, 8, 2, + 1, 187, 4, 75, 93, 23, 217, 148, 8, 6, 1, 192, 160, 4, 217, 148, 8, 2, 1, + 192, 160, 4, 217, 148, 8, 2, 1, 220, 145, 4, 238, 177, 8, 2, 1, 215, 64, + 4, 238, 177, 8, 2, 1, 200, 44, 4, 238, 177, 8, 2, 1, 236, 141, 223, 37, + 8, 2, 1, 237, 203, 237, 4, 8, 2, 1, 208, 36, 237, 4, 8, 6, 1, 42, 4, 106, + 8, 6, 1, 247, 196, 4, 106, 8, 2, 1, 247, 196, 4, 106, 8, 6, 1, 220, 145, + 4, 164, 8, 6, 1, 200, 44, 4, 237, 41, 106, 8, 2, 1, 206, 10, 4, 200, 146, + 199, 215, 8, 2, 1, 191, 167, 4, 200, 146, 199, 215, 8, 6, 1, 231, 13, + 201, 64, 8, 2, 1, 231, 13, 201, 64, 8, 6, 1, 78, 4, 106, 8, 6, 1, 126, + 164, 8, 6, 1, 154, 196, 12, 8, 6, 1, 235, 17, 4, 106, 8, 2, 1, 235, 17, + 4, 106, 8, 6, 1, 223, 38, 4, 106, 8, 2, 1, 223, 38, 4, 106, 8, 6, 1, 2, + 208, 107, 4, 228, 253, 199, 215, 8, 2, 1, 208, 107, 4, 228, 253, 199, + 215, 8, 6, 1, 207, 224, 4, 106, 8, 2, 1, 207, 224, 4, 106, 8, 6, 1, 192, + 160, 4, 106, 8, 2, 1, 192, 160, 4, 106, 8, 2, 1, 154, 65, 8, 2, 1, 251, + 162, 8, 2, 1, 154, 251, 162, 8, 2, 1, 78, 4, 102, 8, 2, 1, 211, 79, 74, + 8, 2, 1, 247, 196, 4, 238, 177, 8, 2, 1, 238, 130, 4, 199, 215, 8, 2, 1, + 238, 130, 4, 102, 8, 2, 1, 207, 19, 71, 8, 2, 1, 205, 87, 8, 2, 1, 205, + 88, 4, 102, 8, 2, 1, 211, 79, 71, 8, 2, 1, 207, 19, 211, 79, 71, 8, 2, 1, + 207, 19, 211, 79, 235, 17, 4, 102, 8, 2, 1, 242, 221, 207, 19, 211, 79, + 71, 8, 2, 1, 236, 141, 223, 38, 4, 106, 8, 2, 1, 232, 54, 4, 102, 8, 2, + 1, 27, 232, 53, 8, 1, 2, 6, 232, 53, 8, 2, 1, 231, 213, 8, 2, 1, 207, + 142, 228, 189, 8, 2, 1, 154, 230, 118, 8, 2, 1, 230, 119, 4, 102, 8, 2, + 1, 229, 199, 4, 102, 8, 2, 1, 228, 76, 4, 106, 8, 2, 1, 223, 85, 8, 1, 2, + 6, 68, 8, 2, 1, 220, 145, 4, 82, 198, 152, 8, 2, 1, 220, 145, 4, 248, + 233, 8, 2, 1, 220, 145, 4, 207, 25, 102, 8, 2, 1, 219, 164, 8, 2, 1, 154, + 218, 170, 8, 2, 1, 154, 218, 171, 4, 180, 219, 214, 8, 2, 1, 218, 171, 4, + 102, 8, 2, 1, 215, 64, 4, 45, 102, 8, 2, 1, 215, 64, 4, 207, 25, 102, 8, + 1, 2, 6, 215, 63, 8, 2, 1, 249, 84, 74, 8, 1, 2, 6, 211, 153, 8, 2, 1, + 242, 221, 211, 112, 8, 2, 1, 209, 213, 8, 2, 1, 154, 146, 8, 2, 1, 154, + 207, 224, 4, 180, 219, 214, 8, 2, 1, 154, 207, 224, 4, 102, 8, 2, 1, 207, + 224, 4, 180, 219, 214, 8, 2, 1, 207, 224, 4, 199, 215, 8, 2, 1, 207, 224, + 4, 232, 235, 8, 2, 1, 207, 19, 207, 224, 4, 232, 235, 8, 1, 2, 6, 146, 8, + 1, 2, 6, 223, 95, 146, 8, 2, 1, 206, 10, 4, 102, 8, 2, 1, 234, 14, 8, 2, + 1, 236, 141, 223, 38, 4, 201, 29, 23, 102, 8, 2, 1, 201, 188, 207, 19, + 234, 14, 8, 2, 1, 234, 15, 4, 238, 177, 8, 2, 1, 154, 200, 43, 8, 2, 1, + 200, 44, 4, 207, 25, 102, 8, 2, 1, 126, 164, 8, 2, 1, 196, 70, 8, 2, 1, + 196, 13, 4, 102, 8, 2, 1, 154, 196, 12, 8, 2, 1, 154, 193, 224, 8, 2, 1, + 154, 192, 159, 8, 1, 2, 6, 192, 159, 8, 2, 1, 191, 167, 4, 207, 25, 102, + 8, 2, 1, 191, 167, 4, 238, 177, 8, 2, 1, 233, 180, 8, 2, 1, 233, 181, 4, + 238, 177, 8, 1, 231, 13, 201, 64, 8, 1, 209, 221, 195, 20, 232, 106, 8, + 1, 223, 95, 231, 13, 201, 64, 8, 1, 201, 37, 247, 195, 8, 1, 248, 174, + 242, 233, 8, 1, 2, 6, 250, 122, 8, 2, 1, 242, 221, 211, 79, 71, 8, 1, 2, + 6, 232, 54, 4, 102, 8, 1, 2, 6, 230, 118, 8, 2, 1, 223, 38, 4, 238, 214, + 8, 2, 1, 154, 222, 154, 8, 1, 2, 6, 172, 8, 2, 1, 208, 107, 4, 102, 8, 1, + 231, 13, 201, 65, 4, 106, 8, 1, 207, 19, 231, 13, 201, 65, 4, 106, 8, 2, + 1, 235, 39, 237, 4, 8, 2, 1, 237, 72, 237, 4, 8, 2, 1, 235, 39, 237, 5, + 4, 238, 177, 8, 2, 1, 197, 170, 237, 4, 8, 2, 1, 199, 79, 237, 4, 8, 2, + 1, 199, 152, 237, 5, 4, 238, 177, 8, 2, 1, 233, 39, 237, 4, 8, 2, 1, 218, + 229, 237, 4, 8, 2, 1, 218, 172, 237, 4, 8, 1, 248, 174, 210, 14, 8, 1, + 248, 182, 210, 14, 8, 2, 1, 154, 230, 119, 4, 232, 235, 8, 2, 1, 154, + 230, 119, 4, 232, 236, 23, 199, 215, 52, 1, 2, 230, 118, 52, 1, 2, 230, + 119, 4, 102, 52, 1, 2, 223, 37, 52, 1, 2, 146, 52, 1, 2, 154, 146, 52, 1, + 2, 154, 207, 224, 4, 102, 52, 1, 2, 6, 223, 95, 146, 52, 1, 2, 193, 224, + 52, 1, 2, 192, 159, 52, 1, 208, 217, 52, 1, 55, 208, 217, 52, 1, 154, + 242, 76, 52, 1, 251, 51, 52, 1, 207, 19, 242, 76, 52, 1, 50, 132, 206, + 189, 52, 1, 45, 132, 206, 189, 52, 1, 231, 13, 201, 64, 52, 1, 207, 19, + 231, 13, 201, 64, 52, 1, 45, 250, 237, 52, 1, 50, 250, 237, 52, 1, 133, + 250, 237, 52, 1, 144, 250, 237, 52, 1, 243, 4, 252, 62, 247, 94, 52, 1, + 81, 219, 114, 52, 1, 217, 148, 52, 1, 252, 49, 252, 62, 52, 1, 230, 213, + 252, 62, 52, 1, 130, 81, 219, 114, 52, 1, 130, 217, 148, 52, 1, 130, 230, + 213, 252, 62, 52, 1, 130, 252, 49, 252, 62, 52, 1, 197, 238, 242, 85, 52, + 1, 132, 197, 238, 242, 85, 52, 1, 247, 22, 50, 132, 206, 189, 52, 1, 247, + 22, 45, 132, 206, 189, 52, 1, 133, 199, 228, 52, 1, 144, 199, 228, 52, 1, + 108, 56, 52, 1, 216, 37, 56, 248, 38, 75, 58, 206, 190, 58, 211, 140, 2, + 198, 152, 55, 252, 49, 252, 62, 52, 1, 207, 3, 102, 52, 1, 238, 220, 252, + 62, 52, 1, 2, 231, 213, 52, 1, 2, 172, 52, 1, 2, 206, 9, 52, 1, 2, 192, + 235, 52, 1, 2, 207, 19, 231, 13, 201, 64, 52, 1, 233, 202, 163, 164, 52, + 1, 137, 163, 164, 52, 1, 216, 89, 163, 164, 52, 1, 130, 163, 164, 52, 1, + 233, 201, 163, 164, 52, 1, 192, 22, 237, 97, 163, 77, 52, 1, 192, 107, + 237, 97, 163, 77, 52, 1, 195, 18, 52, 1, 196, 109, 52, 1, 55, 251, 51, + 52, 1, 130, 144, 250, 237, 52, 1, 130, 133, 250, 237, 52, 1, 130, 45, + 250, 237, 52, 1, 130, 50, 250, 237, 52, 1, 130, 206, 189, 52, 1, 82, 230, + 213, 252, 62, 52, 1, 82, 55, 230, 213, 252, 62, 52, 1, 82, 55, 252, 49, + 252, 62, 52, 1, 130, 198, 152, 52, 1, 207, 149, 242, 85, 52, 1, 248, 251, + 137, 198, 79, 52, 1, 234, 97, 137, 198, 79, 52, 1, 248, 251, 130, 198, + 79, 52, 1, 234, 97, 130, 198, 79, 52, 1, 203, 105, 52, 1, 211, 79, 203, + 105, 52, 1, 130, 45, 57, 33, 230, 213, 252, 62, 33, 252, 49, 252, 62, 33, + 243, 4, 252, 62, 33, 198, 152, 33, 217, 148, 33, 211, 0, 33, 248, 38, 33, + 75, 58, 33, 237, 44, 33, 228, 253, 58, 33, 206, 190, 58, 33, 55, 252, 49, + 252, 62, 33, 247, 94, 33, 81, 219, 115, 58, 33, 55, 81, 219, 115, 58, 33, + 55, 230, 213, 252, 62, 33, 247, 121, 33, 223, 95, 248, 38, 33, 154, 242, + 77, 58, 33, 242, 77, 58, 33, 207, 19, 242, 77, 58, 33, 242, 77, 93, 179, + 33, 230, 213, 252, 63, 60, 33, 252, 49, 252, 63, 60, 33, 45, 199, 229, + 60, 33, 50, 199, 229, 60, 33, 45, 251, 118, 58, 33, 228, 189, 33, 45, + 132, 206, 190, 60, 33, 133, 199, 229, 60, 33, 144, 199, 229, 60, 33, 108, + 3, 60, 33, 216, 37, 3, 60, 33, 210, 192, 228, 253, 60, 33, 207, 25, 228, + 253, 60, 33, 75, 60, 33, 237, 45, 60, 33, 206, 190, 60, 33, 242, 77, 60, + 33, 247, 37, 33, 211, 140, 33, 81, 219, 115, 60, 33, 248, 31, 60, 33, + 223, 95, 55, 251, 17, 60, 33, 247, 95, 60, 33, 243, 4, 252, 63, 60, 33, + 248, 39, 60, 33, 223, 95, 248, 39, 60, 33, 198, 153, 60, 33, 217, 149, + 60, 33, 130, 219, 114, 33, 55, 130, 219, 114, 33, 198, 153, 211, 1, 33, + 203, 41, 201, 29, 211, 1, 33, 180, 201, 29, 211, 1, 33, 203, 41, 202, 25, + 211, 1, 33, 180, 202, 25, 211, 1, 33, 50, 132, 206, 190, 60, 33, 223, 95, + 248, 31, 60, 33, 51, 60, 33, 205, 63, 60, 33, 192, 236, 58, 33, 81, 198, + 152, 33, 55, 211, 0, 33, 230, 213, 163, 77, 33, 252, 49, 163, 77, 33, 35, + 210, 6, 33, 35, 221, 32, 33, 35, 237, 38, 198, 60, 33, 35, 191, 233, 33, + 248, 31, 58, 33, 234, 45, 3, 60, 33, 55, 81, 219, 115, 60, 33, 45, 251, + 118, 60, 33, 213, 14, 198, 153, 58, 33, 229, 3, 58, 33, 251, 167, 234, + 47, 119, 58, 33, 45, 50, 64, 60, 33, 196, 66, 64, 60, 33, 230, 219, 222, + 198, 33, 50, 250, 238, 58, 33, 45, 132, 206, 190, 58, 33, 233, 36, 33, + 192, 236, 60, 33, 45, 250, 238, 60, 33, 50, 250, 238, 60, 33, 50, 250, + 238, 23, 133, 250, 238, 60, 33, 50, 132, 206, 190, 58, 33, 75, 93, 179, + 33, 250, 196, 60, 33, 55, 206, 190, 60, 33, 191, 21, 58, 33, 55, 248, 39, + 60, 33, 55, 248, 38, 33, 55, 217, 148, 33, 55, 217, 149, 60, 33, 55, 198, + 152, 33, 55, 223, 95, 248, 38, 33, 55, 96, 64, 60, 33, 8, 2, 1, 65, 33, + 8, 2, 1, 71, 33, 8, 2, 1, 68, 33, 8, 2, 1, 74, 33, 8, 2, 1, 66, 33, 8, 2, + 1, 247, 195, 33, 8, 2, 1, 238, 129, 33, 8, 2, 1, 230, 118, 33, 8, 2, 1, + 218, 170, 33, 8, 2, 1, 146, 33, 8, 2, 1, 200, 43, 33, 8, 2, 1, 196, 12, + 33, 8, 2, 1, 192, 235, 35, 6, 1, 229, 187, 35, 2, 1, 229, 187, 35, 6, 1, + 251, 16, 205, 146, 35, 2, 1, 251, 16, 205, 146, 35, 212, 136, 56, 35, + 110, 212, 136, 56, 35, 6, 1, 210, 173, 237, 12, 35, 2, 1, 210, 173, 237, + 12, 35, 191, 233, 35, 2, 207, 19, 218, 208, 202, 198, 113, 35, 2, 235, + 140, 218, 208, 202, 198, 113, 35, 2, 207, 19, 235, 140, 218, 208, 202, + 198, 113, 35, 208, 15, 77, 35, 6, 1, 191, 240, 35, 198, 60, 35, 237, 38, + 198, 60, 35, 6, 1, 251, 163, 4, 198, 60, 35, 251, 96, 199, 108, 35, 6, 1, + 234, 50, 4, 198, 60, 35, 6, 1, 234, 0, 4, 198, 60, 35, 6, 1, 223, 86, 4, + 198, 60, 35, 6, 1, 211, 110, 4, 198, 60, 35, 6, 1, 196, 71, 4, 198, 60, + 35, 6, 1, 211, 113, 4, 198, 60, 35, 2, 1, 223, 86, 4, 237, 38, 23, 198, + 60, 35, 6, 1, 251, 162, 35, 6, 1, 248, 214, 35, 6, 1, 231, 213, 35, 6, 1, + 237, 108, 35, 6, 1, 234, 49, 35, 6, 1, 191, 76, 35, 6, 1, 233, 255, 35, + 6, 1, 199, 15, 35, 6, 1, 223, 85, 35, 6, 1, 222, 74, 35, 6, 1, 220, 33, + 35, 6, 1, 215, 157, 35, 6, 1, 212, 180, 35, 6, 1, 192, 207, 35, 6, 1, + 211, 109, 35, 6, 1, 209, 187, 35, 6, 1, 207, 4, 35, 6, 1, 202, 197, 35, + 6, 1, 199, 166, 35, 6, 1, 196, 70, 35, 6, 1, 209, 213, 35, 6, 1, 243, 97, + 35, 6, 1, 208, 178, 35, 6, 1, 211, 112, 35, 6, 1, 223, 86, 4, 237, 37, + 35, 6, 1, 196, 71, 4, 237, 37, 35, 2, 1, 251, 163, 4, 198, 60, 35, 2, 1, + 234, 50, 4, 198, 60, 35, 2, 1, 234, 0, 4, 198, 60, 35, 2, 1, 223, 86, 4, + 198, 60, 35, 2, 1, 196, 71, 4, 237, 38, 23, 198, 60, 35, 2, 1, 251, 162, + 35, 2, 1, 248, 214, 35, 2, 1, 231, 213, 35, 2, 1, 237, 108, 35, 2, 1, + 234, 49, 35, 2, 1, 191, 76, 35, 2, 1, 233, 255, 35, 2, 1, 199, 15, 35, 2, + 1, 223, 85, 35, 2, 1, 222, 74, 35, 2, 1, 220, 33, 35, 2, 1, 215, 157, 35, + 2, 1, 212, 180, 35, 2, 1, 192, 207, 35, 2, 1, 211, 109, 35, 2, 1, 209, + 187, 35, 2, 1, 207, 4, 35, 2, 1, 53, 202, 197, 35, 2, 1, 202, 197, 35, 2, + 1, 199, 166, 35, 2, 1, 196, 70, 35, 2, 1, 209, 213, 35, 2, 1, 243, 97, + 35, 2, 1, 208, 178, 35, 2, 1, 211, 112, 35, 2, 1, 223, 86, 4, 237, 37, + 35, 2, 1, 196, 71, 4, 237, 37, 35, 2, 1, 211, 110, 4, 198, 60, 35, 2, 1, + 196, 71, 4, 198, 60, 35, 2, 1, 211, 113, 4, 198, 60, 35, 6, 222, 105, + 113, 35, 248, 215, 113, 35, 199, 16, 113, 35, 196, 71, 4, 228, 253, 113, + 35, 196, 71, 4, 252, 49, 23, 228, 253, 113, 35, 196, 71, 4, 237, 45, 23, + 228, 253, 113, 35, 209, 214, 113, 35, 209, 188, 113, 35, 222, 105, 113, + 35, 1, 251, 16, 221, 37, 35, 2, 1, 251, 16, 221, 37, 35, 1, 201, 74, 35, + 2, 1, 201, 74, 35, 1, 237, 12, 35, 2, 1, 237, 12, 35, 1, 221, 37, 35, 2, + 1, 221, 37, 35, 1, 205, 146, 35, 2, 1, 205, 146, 94, 6, 1, 203, 106, 94, + 2, 1, 203, 106, 94, 6, 1, 233, 46, 94, 2, 1, 233, 46, 94, 6, 1, 221, 197, + 94, 2, 1, 221, 197, 94, 6, 1, 228, 244, 94, 2, 1, 228, 244, 94, 6, 1, + 231, 208, 94, 2, 1, 231, 208, 94, 6, 1, 203, 72, 94, 2, 1, 203, 72, 94, + 6, 1, 237, 124, 94, 2, 1, 237, 124, 35, 222, 75, 113, 35, 207, 5, 113, + 35, 218, 208, 202, 198, 113, 35, 1, 191, 240, 35, 6, 199, 16, 113, 35, + 218, 208, 234, 50, 113, 35, 207, 19, 218, 208, 234, 50, 113, 35, 6, 1, + 203, 57, 35, 2, 1, 203, 57, 35, 6, 218, 208, 202, 198, 113, 35, 6, 1, + 205, 143, 35, 2, 1, 205, 143, 35, 207, 5, 4, 201, 29, 113, 35, 6, 207, + 19, 218, 208, 202, 198, 113, 35, 6, 235, 140, 218, 208, 202, 198, 113, + 35, 6, 207, 19, 235, 140, 218, 208, 202, 198, 113, 38, 6, 1, 223, 229, 4, + 230, 212, 38, 6, 1, 223, 90, 38, 6, 1, 236, 194, 38, 6, 1, 231, 22, 38, + 6, 1, 196, 125, 223, 228, 38, 6, 1, 235, 34, 38, 6, 1, 247, 205, 68, 38, + 6, 1, 192, 33, 38, 6, 1, 223, 12, 38, 6, 1, 219, 78, 38, 6, 1, 213, 152, + 38, 6, 1, 197, 155, 38, 6, 1, 221, 105, 38, 6, 1, 228, 76, 4, 230, 212, + 38, 6, 1, 203, 41, 66, 38, 6, 1, 235, 30, 38, 6, 1, 65, 38, 6, 1, 249, + 19, 38, 6, 1, 195, 153, 38, 6, 1, 231, 79, 38, 6, 1, 237, 148, 38, 6, 1, + 223, 228, 38, 6, 1, 191, 62, 38, 6, 1, 191, 87, 38, 6, 1, 68, 38, 6, 1, + 203, 41, 68, 38, 6, 1, 155, 38, 6, 1, 234, 142, 38, 6, 1, 234, 116, 38, + 6, 1, 234, 105, 38, 6, 1, 74, 38, 6, 1, 210, 65, 38, 6, 1, 234, 36, 38, + 6, 1, 234, 24, 38, 6, 1, 199, 145, 38, 6, 1, 66, 38, 6, 1, 234, 183, 38, + 6, 1, 140, 38, 6, 1, 197, 161, 38, 6, 1, 243, 129, 38, 6, 1, 203, 166, + 38, 6, 1, 203, 117, 38, 6, 1, 230, 19, 56, 38, 6, 1, 192, 58, 38, 6, 1, + 202, 33, 56, 38, 6, 1, 71, 38, 6, 1, 191, 225, 38, 6, 1, 170, 38, 2, 1, + 65, 38, 2, 1, 249, 19, 38, 2, 1, 195, 153, 38, 2, 1, 231, 79, 38, 2, 1, + 237, 148, 38, 2, 1, 223, 228, 38, 2, 1, 191, 62, 38, 2, 1, 191, 87, 38, + 2, 1, 68, 38, 2, 1, 203, 41, 68, 38, 2, 1, 155, 38, 2, 1, 234, 142, 38, + 2, 1, 234, 116, 38, 2, 1, 234, 105, 38, 2, 1, 74, 38, 2, 1, 210, 65, 38, + 2, 1, 234, 36, 38, 2, 1, 234, 24, 38, 2, 1, 199, 145, 38, 2, 1, 66, 38, + 2, 1, 234, 183, 38, 2, 1, 140, 38, 2, 1, 197, 161, 38, 2, 1, 243, 129, + 38, 2, 1, 203, 166, 38, 2, 1, 203, 117, 38, 2, 1, 230, 19, 56, 38, 2, 1, + 192, 58, 38, 2, 1, 202, 33, 56, 38, 2, 1, 71, 38, 2, 1, 191, 225, 38, 2, + 1, 170, 38, 2, 1, 223, 229, 4, 230, 212, 38, 2, 1, 223, 90, 38, 2, 1, + 236, 194, 38, 2, 1, 231, 22, 38, 2, 1, 196, 125, 223, 228, 38, 2, 1, 235, + 34, 38, 2, 1, 247, 205, 68, 38, 2, 1, 192, 33, 38, 2, 1, 223, 12, 38, 2, + 1, 219, 78, 38, 2, 1, 213, 152, 38, 2, 1, 197, 155, 38, 2, 1, 221, 105, + 38, 2, 1, 228, 76, 4, 230, 212, 38, 2, 1, 203, 41, 66, 38, 2, 1, 235, 30, + 38, 6, 1, 211, 112, 38, 2, 1, 211, 112, 38, 6, 1, 192, 95, 38, 2, 1, 192, + 95, 38, 6, 1, 223, 83, 71, 38, 2, 1, 223, 83, 71, 38, 6, 1, 219, 85, 191, + 190, 38, 2, 1, 219, 85, 191, 190, 38, 6, 1, 223, 83, 219, 85, 191, 190, + 38, 2, 1, 223, 83, 219, 85, 191, 190, 38, 6, 1, 248, 177, 191, 190, 38, + 2, 1, 248, 177, 191, 190, 38, 6, 1, 223, 83, 248, 177, 191, 190, 38, 2, + 1, 223, 83, 248, 177, 191, 190, 38, 6, 1, 220, 250, 38, 2, 1, 220, 250, + 38, 6, 1, 208, 178, 38, 2, 1, 208, 178, 38, 6, 1, 232, 230, 38, 2, 1, + 232, 230, 38, 6, 1, 223, 39, 38, 2, 1, 223, 39, 38, 6, 1, 223, 40, 4, 55, + 230, 213, 252, 62, 38, 2, 1, 223, 40, 4, 55, 230, 213, 252, 62, 38, 6, 1, + 196, 128, 38, 2, 1, 196, 128, 38, 6, 1, 206, 116, 211, 112, 38, 2, 1, + 206, 116, 211, 112, 38, 6, 1, 211, 113, 4, 198, 122, 38, 2, 1, 211, 113, + 4, 198, 122, 38, 6, 1, 211, 32, 38, 2, 1, 211, 32, 38, 6, 1, 221, 37, 38, + 2, 1, 221, 37, 38, 198, 229, 56, 33, 38, 198, 122, 33, 38, 210, 193, 33, + 38, 237, 215, 209, 77, 33, 38, 208, 172, 209, 77, 33, 38, 209, 56, 33, + 38, 228, 143, 198, 229, 56, 33, 38, 216, 50, 56, 38, 6, 1, 203, 41, 228, + 76, 4, 199, 215, 38, 2, 1, 203, 41, 228, 76, 4, 199, 215, 38, 6, 1, 204, + 22, 56, 38, 2, 1, 204, 22, 56, 38, 6, 1, 234, 37, 4, 198, 182, 38, 2, 1, + 234, 37, 4, 198, 182, 38, 6, 1, 231, 80, 4, 196, 69, 38, 2, 1, 231, 80, + 4, 196, 69, 38, 6, 1, 231, 80, 4, 106, 38, 2, 1, 231, 80, 4, 106, 38, 6, + 1, 231, 80, 4, 82, 102, 38, 2, 1, 231, 80, 4, 82, 102, 38, 6, 1, 191, 63, + 4, 237, 89, 38, 2, 1, 191, 63, 4, 237, 89, 38, 6, 1, 191, 88, 4, 237, 89, + 38, 2, 1, 191, 88, 4, 237, 89, 38, 6, 1, 222, 144, 4, 237, 89, 38, 2, 1, + 222, 144, 4, 237, 89, 38, 6, 1, 222, 144, 4, 81, 106, 38, 2, 1, 222, 144, + 4, 81, 106, 38, 6, 1, 222, 144, 4, 106, 38, 2, 1, 222, 144, 4, 106, 38, + 6, 1, 249, 72, 155, 38, 2, 1, 249, 72, 155, 38, 6, 1, 234, 106, 4, 237, + 89, 38, 2, 1, 234, 106, 4, 237, 89, 38, 6, 34, 234, 106, 231, 79, 38, 2, + 34, 234, 106, 231, 79, 38, 6, 1, 210, 66, 4, 82, 102, 38, 2, 1, 210, 66, + 4, 82, 102, 38, 6, 1, 252, 69, 140, 38, 2, 1, 252, 69, 140, 38, 6, 1, + 234, 25, 4, 237, 89, 38, 2, 1, 234, 25, 4, 237, 89, 38, 6, 1, 199, 146, + 4, 237, 89, 38, 2, 1, 199, 146, 4, 237, 89, 38, 6, 1, 201, 54, 66, 38, 2, + 1, 201, 54, 66, 38, 6, 1, 201, 54, 126, 4, 106, 38, 2, 1, 201, 54, 126, + 4, 106, 38, 6, 1, 230, 107, 4, 237, 89, 38, 2, 1, 230, 107, 4, 237, 89, + 38, 6, 34, 199, 146, 197, 161, 38, 2, 34, 199, 146, 197, 161, 38, 6, 1, + 243, 130, 4, 237, 89, 38, 2, 1, 243, 130, 4, 237, 89, 38, 6, 1, 243, 130, + 4, 81, 106, 38, 2, 1, 243, 130, 4, 81, 106, 38, 6, 1, 203, 83, 38, 2, 1, + 203, 83, 38, 6, 1, 252, 69, 243, 129, 38, 2, 1, 252, 69, 243, 129, 38, 6, + 1, 252, 69, 243, 130, 4, 237, 89, 38, 2, 1, 252, 69, 243, 130, 4, 237, + 89, 38, 1, 210, 181, 38, 6, 1, 191, 63, 4, 248, 38, 38, 2, 1, 191, 63, 4, + 248, 38, 38, 6, 1, 222, 144, 4, 102, 38, 2, 1, 222, 144, 4, 102, 38, 6, + 1, 234, 143, 4, 199, 215, 38, 2, 1, 234, 143, 4, 199, 215, 38, 6, 1, 234, + 106, 4, 102, 38, 2, 1, 234, 106, 4, 102, 38, 6, 1, 234, 106, 4, 199, 215, + 38, 2, 1, 234, 106, 4, 199, 215, 38, 6, 1, 221, 210, 243, 129, 38, 2, 1, + 221, 210, 243, 129, 38, 6, 1, 234, 117, 4, 199, 215, 38, 2, 1, 234, 117, + 4, 199, 215, 38, 2, 1, 210, 181, 38, 6, 1, 42, 4, 248, 38, 38, 2, 1, 42, + 4, 248, 38, 38, 6, 1, 42, 4, 237, 44, 38, 2, 1, 42, 4, 237, 44, 38, 6, + 34, 42, 223, 228, 38, 2, 34, 42, 223, 228, 38, 6, 1, 223, 229, 4, 248, + 38, 38, 2, 1, 223, 229, 4, 248, 38, 38, 6, 1, 205, 87, 38, 2, 1, 205, 87, + 38, 6, 1, 205, 88, 4, 237, 44, 38, 2, 1, 205, 88, 4, 237, 44, 38, 6, 1, + 191, 63, 4, 237, 44, 38, 2, 1, 191, 63, 4, 237, 44, 38, 6, 1, 191, 88, 4, + 237, 44, 38, 2, 1, 191, 88, 4, 237, 44, 38, 6, 1, 252, 69, 235, 34, 38, + 2, 1, 252, 69, 235, 34, 38, 6, 1, 228, 76, 4, 217, 148, 38, 2, 1, 228, + 76, 4, 217, 148, 38, 6, 1, 228, 76, 4, 237, 44, 38, 2, 1, 228, 76, 4, + 237, 44, 38, 6, 1, 187, 4, 237, 44, 38, 2, 1, 187, 4, 237, 44, 38, 6, 1, + 249, 84, 74, 38, 2, 1, 249, 84, 74, 38, 6, 1, 249, 84, 187, 4, 237, 44, + 38, 2, 1, 249, 84, 187, 4, 237, 44, 38, 6, 1, 235, 17, 4, 237, 44, 38, 2, + 1, 235, 17, 4, 237, 44, 38, 6, 1, 126, 4, 217, 148, 38, 2, 1, 126, 4, + 217, 148, 38, 6, 1, 126, 4, 237, 44, 38, 2, 1, 126, 4, 237, 44, 38, 6, 1, + 126, 4, 55, 252, 48, 38, 2, 1, 126, 4, 55, 252, 48, 38, 6, 1, 243, 130, + 4, 237, 44, 38, 2, 1, 243, 130, 4, 237, 44, 38, 6, 1, 231, 80, 4, 237, + 89, 38, 2, 1, 231, 80, 4, 237, 89, 38, 6, 1, 192, 59, 4, 237, 44, 38, 2, + 1, 192, 59, 4, 237, 44, 38, 6, 1, 231, 80, 4, 201, 29, 23, 102, 38, 2, 1, + 231, 80, 4, 201, 29, 23, 102, 38, 6, 1, 230, 107, 4, 102, 38, 2, 1, 230, + 107, 4, 102, 38, 6, 1, 230, 107, 4, 106, 38, 2, 1, 230, 107, 4, 106, 38, + 6, 1, 221, 47, 237, 148, 38, 2, 1, 221, 47, 237, 148, 38, 6, 1, 221, 47, + 236, 194, 38, 2, 1, 221, 47, 236, 194, 38, 6, 1, 221, 47, 191, 12, 38, 2, + 1, 221, 47, 191, 12, 38, 6, 1, 221, 47, 235, 26, 38, 2, 1, 221, 47, 235, + 26, 38, 6, 1, 221, 47, 219, 78, 38, 2, 1, 221, 47, 219, 78, 38, 6, 1, + 221, 47, 213, 152, 38, 2, 1, 221, 47, 213, 152, 38, 6, 1, 221, 47, 202, + 116, 38, 2, 1, 221, 47, 202, 116, 38, 6, 1, 221, 47, 198, 116, 38, 2, 1, + 221, 47, 198, 116, 38, 6, 1, 207, 19, 191, 87, 38, 2, 1, 207, 19, 191, + 87, 38, 6, 1, 234, 143, 4, 102, 38, 2, 1, 234, 143, 4, 102, 38, 6, 1, + 219, 161, 38, 2, 1, 219, 161, 38, 6, 1, 207, 7, 38, 2, 1, 207, 7, 38, 6, + 1, 192, 129, 38, 2, 1, 192, 129, 38, 6, 1, 208, 98, 38, 2, 1, 208, 98, + 38, 6, 1, 193, 125, 38, 2, 1, 193, 125, 38, 6, 1, 251, 190, 155, 38, 2, + 1, 251, 190, 155, 38, 6, 1, 234, 143, 4, 82, 102, 38, 2, 1, 234, 143, 4, + 82, 102, 38, 6, 1, 234, 106, 4, 82, 102, 38, 2, 1, 234, 106, 4, 82, 102, + 38, 6, 1, 210, 66, 4, 237, 89, 38, 2, 1, 210, 66, 4, 237, 89, 38, 6, 1, + 203, 84, 4, 237, 89, 38, 2, 1, 203, 84, 4, 237, 89, 38, 6, 1, 234, 106, + 4, 45, 102, 38, 2, 1, 234, 106, 4, 45, 102, 38, 6, 1, 235, 18, 38, 2, 1, + 235, 18, 38, 6, 1, 237, 197, 38, 2, 1, 237, 197, 38, 6, 1, 234, 143, 4, + 237, 89, 38, 2, 1, 234, 143, 4, 237, 89, 250, 251, 6, 1, 250, 130, 250, + 251, 6, 1, 248, 231, 250, 251, 6, 1, 231, 42, 250, 251, 6, 1, 238, 34, + 250, 251, 6, 1, 234, 197, 250, 251, 6, 1, 191, 123, 250, 251, 6, 1, 234, + 175, 250, 251, 6, 1, 234, 1, 250, 251, 6, 1, 159, 250, 251, 6, 1, 191, + 62, 250, 251, 6, 1, 223, 133, 250, 251, 6, 1, 219, 82, 250, 251, 6, 1, + 192, 212, 250, 251, 6, 1, 247, 162, 250, 251, 6, 1, 221, 253, 250, 251, + 6, 1, 229, 25, 250, 251, 6, 1, 223, 34, 250, 251, 6, 1, 231, 90, 250, + 251, 6, 1, 243, 119, 250, 251, 6, 1, 216, 188, 250, 251, 6, 1, 192, 33, + 250, 251, 6, 1, 212, 255, 250, 251, 6, 1, 203, 166, 250, 251, 6, 1, 195, + 24, 250, 251, 6, 1, 247, 3, 250, 251, 6, 1, 210, 43, 250, 251, 6, 1, 222, + 249, 250, 251, 6, 1, 165, 250, 251, 6, 1, 205, 40, 250, 251, 6, 1, 195, + 74, 250, 251, 6, 1, 198, 119, 250, 251, 6, 1, 207, 72, 250, 251, 6, 1, + 242, 101, 250, 251, 6, 1, 192, 17, 250, 251, 6, 1, 209, 116, 250, 251, 6, + 1, 222, 8, 250, 251, 6, 1, 211, 138, 250, 251, 6, 1, 233, 48, 250, 251, + 52, 1, 45, 132, 206, 189, 250, 251, 251, 51, 250, 251, 234, 109, 77, 250, + 251, 233, 218, 77, 250, 251, 242, 76, 250, 251, 208, 15, 77, 250, 251, + 252, 70, 77, 250, 251, 2, 1, 154, 250, 130, 250, 251, 2, 1, 250, 130, + 250, 251, 2, 1, 248, 231, 250, 251, 2, 1, 231, 42, 250, 251, 2, 1, 238, + 34, 250, 251, 2, 1, 234, 197, 250, 251, 2, 1, 191, 123, 250, 251, 2, 1, + 234, 175, 250, 251, 2, 1, 234, 1, 250, 251, 2, 1, 159, 250, 251, 2, 1, + 191, 62, 250, 251, 2, 1, 223, 133, 250, 251, 2, 1, 219, 82, 250, 251, 2, + 1, 192, 212, 250, 251, 2, 1, 247, 162, 250, 251, 2, 1, 221, 253, 250, + 251, 2, 1, 229, 25, 250, 251, 2, 1, 223, 34, 250, 251, 2, 1, 231, 90, + 250, 251, 2, 1, 243, 119, 250, 251, 2, 1, 216, 188, 250, 251, 2, 1, 192, + 33, 250, 251, 2, 1, 212, 255, 250, 251, 2, 1, 203, 166, 250, 251, 2, 1, + 195, 24, 250, 251, 2, 1, 247, 3, 250, 251, 2, 1, 210, 43, 250, 251, 2, 1, + 222, 249, 250, 251, 2, 1, 165, 250, 251, 2, 1, 205, 40, 250, 251, 2, 1, + 195, 74, 250, 251, 2, 1, 198, 119, 250, 251, 2, 1, 207, 72, 250, 251, 2, + 1, 242, 101, 250, 251, 2, 1, 192, 17, 250, 251, 2, 1, 209, 116, 250, 251, + 2, 1, 222, 8, 250, 251, 2, 1, 211, 138, 250, 251, 2, 1, 233, 48, 250, + 251, 2, 34, 234, 198, 192, 17, 250, 251, 2, 1, 11, 4, 106, 250, 251, 232, + 82, 201, 64, 250, 251, 228, 90, 206, 208, 250, 251, 233, 253, 56, 219, + 225, 250, 251, 233, 253, 56, 250, 251, 235, 112, 56, 136, 252, 63, 233, + 248, 136, 252, 63, 205, 41, 136, 252, 63, 203, 142, 136, 252, 63, 191, + 99, 208, 80, 136, 252, 63, 191, 99, 231, 232, 136, 252, 63, 198, 134, + 136, 252, 63, 207, 16, 136, 252, 63, 191, 97, 136, 252, 63, 210, 99, 136, + 252, 63, 192, 48, 136, 252, 63, 199, 56, 136, 252, 63, 231, 141, 136, + 252, 63, 231, 142, 215, 112, 136, 252, 63, 231, 139, 136, 252, 63, 208, + 82, 210, 132, 136, 252, 63, 199, 103, 231, 160, 136, 252, 63, 210, 71, + 136, 252, 63, 250, 175, 230, 87, 136, 252, 63, 215, 123, 136, 252, 63, + 217, 119, 136, 252, 63, 216, 177, 136, 252, 63, 216, 178, 222, 9, 136, + 252, 63, 237, 224, 136, 252, 63, 208, 93, 136, 252, 63, 199, 103, 208, + 75, 136, 252, 63, 192, 61, 248, 232, 191, 247, 136, 252, 63, 211, 119, + 136, 252, 63, 223, 185, 136, 252, 63, 237, 125, 136, 252, 63, 191, 19, + 136, 87, 217, 36, 243, 12, 136, 209, 64, 203, 86, 136, 209, 64, 230, 10, + 205, 41, 136, 209, 64, 230, 10, 210, 90, 136, 209, 64, 230, 10, 208, 86, + 136, 209, 64, 229, 121, 136, 209, 64, 197, 158, 136, 209, 64, 205, 41, + 136, 209, 64, 210, 90, 136, 209, 64, 208, 86, 136, 209, 64, 229, 9, 136, + 209, 64, 229, 10, 230, 12, 40, 195, 158, 136, 209, 64, 208, 20, 136, 209, + 64, 238, 19, 211, 59, 217, 72, 136, 209, 64, 216, 166, 136, 208, 154, + 217, 69, 136, 209, 64, 207, 163, 136, 208, 154, 210, 101, 136, 209, 64, + 203, 71, 236, 142, 136, 209, 64, 202, 176, 236, 142, 136, 208, 154, 202, + 34, 210, 92, 136, 87, 116, 236, 142, 136, 87, 110, 236, 142, 136, 208, + 154, 212, 133, 230, 86, 136, 209, 64, 208, 87, 208, 80, 136, 1, 251, 194, + 136, 1, 248, 216, 136, 1, 231, 40, 136, 1, 237, 255, 136, 1, 229, 247, + 136, 1, 195, 158, 136, 1, 191, 91, 136, 1, 229, 188, 136, 1, 199, 73, + 136, 1, 191, 250, 136, 1, 53, 222, 108, 136, 1, 222, 108, 136, 1, 220, + 29, 136, 1, 53, 216, 195, 136, 1, 216, 195, 136, 1, 53, 212, 132, 136, 1, + 212, 132, 136, 1, 205, 149, 136, 1, 250, 128, 136, 1, 53, 210, 65, 136, + 1, 210, 65, 136, 1, 53, 197, 163, 136, 1, 197, 163, 136, 1, 208, 44, 136, + 1, 207, 39, 136, 1, 203, 70, 136, 1, 199, 162, 136, 191, 251, 197, 241, 136, 34, 192, 31, 55, 195, 158, 136, 34, 192, 31, 195, 159, 191, 250, - 136, 34, 192, 31, 55, 191, 250, 136, 208, 152, 231, 139, 136, 208, 152, - 231, 137, 9, 31, 56, 9, 3, 205, 141, 9, 232, 157, 217, 51, 9, 3, 205, - 187, 9, 3, 205, 144, 9, 31, 87, 58, 251, 28, 238, 191, 206, 128, 251, 28, - 232, 121, 206, 128, 9, 207, 122, 251, 28, 210, 14, 216, 50, 56, 251, 28, - 210, 14, 199, 96, 198, 230, 56, 252, 2, 56, 9, 242, 74, 9, 237, 209, 204, - 10, 9, 209, 64, 195, 137, 56, 9, 3, 216, 25, 9, 3, 205, 161, 251, 199, - 193, 149, 9, 3, 251, 199, 250, 198, 9, 3, 207, 157, 251, 198, 9, 3, 207, - 167, 251, 170, 251, 105, 9, 3, 199, 206, 9, 2, 137, 199, 219, 9, 2, 137, - 34, 131, 4, 220, 36, 4, 192, 75, 9, 2, 137, 191, 113, 9, 2, 233, 70, 9, - 2, 237, 245, 9, 2, 222, 52, 9, 204, 25, 9, 1, 77, 9, 234, 95, 79, 199, - 54, 77, 9, 197, 225, 75, 208, 152, 77, 9, 208, 13, 77, 9, 1, 222, 56, - 192, 75, 9, 1, 230, 57, 9, 1, 131, 4, 217, 142, 58, 9, 1, 131, 4, 230, - 58, 58, 9, 1, 193, 134, 4, 230, 58, 58, 9, 1, 131, 4, 230, 58, 60, 9, 1, - 99, 4, 230, 58, 58, 9, 1, 251, 192, 9, 1, 248, 245, 9, 1, 199, 115, 217, - 62, 9, 1, 199, 114, 9, 1, 199, 29, 9, 1, 223, 6, 9, 1, 230, 81, 9, 1, - 221, 210, 9, 1, 238, 3, 9, 1, 199, 41, 9, 1, 207, 71, 9, 1, 191, 113, 9, - 1, 205, 46, 9, 1, 203, 109, 9, 1, 205, 192, 9, 1, 238, 26, 9, 1, 199, - 219, 9, 1, 191, 116, 9, 1, 251, 230, 9, 1, 231, 86, 9, 1, 222, 5, 4, 105, - 185, 58, 9, 1, 222, 5, 4, 115, 185, 60, 9, 1, 233, 74, 99, 4, 223, 93, - 196, 12, 9, 1, 233, 74, 99, 4, 105, 185, 58, 9, 1, 233, 74, 99, 4, 115, - 185, 58, 9, 199, 168, 9, 1, 233, 46, 9, 1, 208, 89, 9, 1, 222, 106, 9, 1, - 220, 35, 9, 1, 216, 208, 9, 1, 213, 24, 9, 1, 229, 210, 9, 1, 193, 133, - 9, 1, 131, 217, 99, 9, 1, 192, 75, 9, 233, 68, 9, 237, 243, 9, 222, 50, - 9, 233, 70, 9, 237, 245, 9, 222, 52, 9, 203, 155, 9, 200, 206, 9, 217, - 140, 58, 9, 230, 58, 58, 9, 230, 58, 60, 9, 200, 230, 251, 192, 9, 223, - 93, 237, 245, 9, 87, 213, 25, 231, 57, 9, 190, 237, 9, 18, 3, 2, 196, 13, - 58, 9, 18, 3, 223, 93, 2, 196, 13, 58, 9, 18, 3, 75, 60, 9, 207, 18, 237, - 245, 9, 233, 71, 4, 105, 236, 138, 9, 193, 135, 230, 58, 60, 251, 28, 17, - 191, 77, 251, 28, 17, 107, 251, 28, 17, 109, 251, 28, 17, 138, 251, 28, - 17, 134, 251, 28, 17, 149, 251, 28, 17, 169, 251, 28, 17, 175, 251, 28, - 17, 171, 251, 28, 17, 178, 9, 210, 13, 56, 9, 237, 138, 204, 10, 9, 198, - 229, 204, 10, 9, 232, 226, 209, 60, 201, 102, 9, 1, 236, 139, 248, 245, - 9, 1, 236, 139, 208, 89, 9, 1, 200, 182, 251, 192, 9, 1, 131, 193, 150, - 9, 1, 131, 4, 193, 135, 230, 58, 58, 9, 1, 131, 4, 193, 135, 230, 58, 60, - 9, 1, 137, 230, 57, 9, 1, 137, 230, 58, 251, 192, 9, 1, 137, 230, 58, - 193, 133, 9, 1, 126, 4, 230, 58, 58, 9, 1, 137, 230, 58, 192, 75, 9, 1, - 197, 124, 9, 1, 197, 122, 9, 1, 248, 255, 9, 1, 199, 115, 4, 206, 188, 9, - 1, 199, 115, 4, 115, 185, 93, 235, 118, 9, 1, 210, 41, 9, 1, 199, 112, 9, - 1, 248, 243, 9, 1, 182, 4, 230, 58, 58, 9, 1, 182, 4, 105, 185, 81, 58, - 9, 1, 212, 87, 9, 1, 235, 41, 9, 1, 182, 4, 115, 185, 58, 9, 1, 199, 149, - 9, 1, 199, 147, 9, 1, 237, 186, 9, 1, 238, 4, 4, 206, 188, 9, 1, 238, 4, - 4, 75, 60, 9, 1, 238, 4, 4, 75, 248, 233, 23, 2, 199, 219, 9, 1, 238, 10, - 9, 1, 237, 188, 9, 1, 235, 78, 9, 1, 238, 4, 4, 115, 185, 93, 235, 118, - 9, 1, 238, 4, 4, 232, 128, 185, 58, 9, 1, 206, 101, 9, 1, 207, 72, 4, 2, - 196, 12, 9, 1, 207, 72, 4, 206, 188, 9, 1, 207, 72, 4, 75, 60, 9, 1, 207, - 72, 4, 2, 196, 13, 60, 9, 1, 207, 72, 4, 75, 248, 233, 23, 75, 58, 9, 1, - 207, 72, 4, 105, 185, 58, 9, 1, 223, 3, 9, 1, 207, 72, 4, 232, 128, 185, - 58, 9, 1, 205, 47, 4, 75, 248, 233, 23, 75, 58, 9, 1, 205, 47, 4, 115, - 185, 60, 9, 1, 205, 47, 4, 115, 185, 248, 233, 23, 115, 185, 58, 9, 1, - 205, 193, 4, 105, 185, 60, 9, 1, 205, 193, 4, 115, 185, 58, 9, 1, 199, - 220, 4, 115, 185, 58, 9, 1, 251, 231, 4, 115, 185, 58, 9, 1, 236, 139, - 233, 46, 9, 1, 233, 47, 4, 75, 215, 177, 60, 9, 1, 233, 47, 4, 75, 60, 9, - 1, 195, 146, 9, 1, 233, 47, 4, 115, 185, 60, 9, 1, 210, 39, 9, 1, 208, - 90, 4, 75, 58, 9, 1, 208, 90, 4, 115, 185, 58, 9, 1, 222, 4, 9, 1, 200, - 146, 222, 106, 9, 1, 222, 107, 4, 206, 188, 9, 1, 222, 107, 4, 75, 58, 9, - 1, 214, 70, 9, 1, 222, 107, 4, 115, 185, 60, 9, 1, 231, 227, 9, 1, 231, - 228, 4, 206, 188, 9, 1, 213, 247, 9, 1, 231, 228, 4, 105, 185, 60, 9, 1, - 230, 166, 9, 1, 231, 228, 4, 115, 185, 58, 9, 1, 220, 36, 4, 2, 196, 12, - 9, 1, 220, 36, 4, 75, 58, 9, 1, 220, 36, 4, 115, 185, 58, 9, 1, 220, 36, - 4, 115, 185, 60, 9, 1, 213, 25, 4, 75, 60, 9, 1, 213, 25, 231, 57, 9, 1, - 206, 165, 9, 1, 213, 25, 4, 206, 188, 9, 1, 213, 25, 4, 115, 185, 58, 9, - 1, 229, 211, 236, 170, 9, 1, 199, 150, 4, 75, 58, 9, 1, 229, 211, 4, 99, - 58, 9, 1, 229, 211, 231, 0, 9, 1, 229, 211, 231, 1, 4, 230, 58, 58, 9, 1, - 199, 115, 217, 63, 231, 0, 9, 1, 193, 134, 4, 206, 188, 9, 1, 221, 132, - 211, 151, 9, 1, 211, 151, 9, 1, 66, 9, 1, 191, 225, 9, 1, 221, 132, 191, - 225, 9, 1, 193, 134, 4, 105, 185, 58, 9, 1, 195, 153, 9, 1, 233, 74, 192, + 136, 34, 192, 31, 55, 191, 250, 136, 208, 154, 231, 141, 136, 208, 154, + 231, 139, 9, 31, 56, 9, 3, 205, 142, 9, 232, 159, 217, 53, 9, 3, 205, + 188, 9, 3, 205, 145, 9, 31, 87, 58, 251, 30, 238, 193, 206, 129, 251, 30, + 232, 123, 206, 129, 9, 207, 124, 251, 30, 210, 16, 216, 52, 56, 251, 30, + 210, 16, 199, 96, 198, 230, 56, 252, 4, 56, 9, 242, 76, 9, 237, 211, 204, + 11, 9, 209, 66, 195, 137, 56, 9, 3, 216, 27, 9, 3, 205, 162, 251, 201, + 193, 149, 9, 3, 251, 201, 250, 200, 9, 3, 207, 159, 251, 200, 9, 3, 207, + 169, 251, 172, 251, 107, 9, 3, 199, 206, 9, 2, 137, 199, 219, 9, 2, 137, + 34, 131, 4, 220, 38, 4, 192, 75, 9, 2, 137, 191, 113, 9, 2, 233, 72, 9, + 2, 237, 247, 9, 2, 222, 54, 9, 204, 26, 9, 1, 77, 9, 234, 97, 79, 199, + 54, 77, 9, 197, 225, 75, 208, 154, 77, 9, 208, 15, 77, 9, 1, 222, 58, + 192, 75, 9, 1, 230, 59, 9, 1, 131, 4, 217, 144, 58, 9, 1, 131, 4, 230, + 60, 58, 9, 1, 193, 134, 4, 230, 60, 58, 9, 1, 131, 4, 230, 60, 60, 9, 1, + 99, 4, 230, 60, 58, 9, 1, 251, 194, 9, 1, 248, 247, 9, 1, 199, 115, 217, + 64, 9, 1, 199, 114, 9, 1, 199, 29, 9, 1, 223, 8, 9, 1, 230, 83, 9, 1, + 221, 212, 9, 1, 238, 5, 9, 1, 199, 41, 9, 1, 207, 72, 9, 1, 191, 113, 9, + 1, 205, 47, 9, 1, 203, 110, 9, 1, 205, 193, 9, 1, 238, 28, 9, 1, 199, + 219, 9, 1, 191, 116, 9, 1, 251, 232, 9, 1, 231, 88, 9, 1, 222, 7, 4, 105, + 185, 58, 9, 1, 222, 7, 4, 115, 185, 60, 9, 1, 233, 76, 99, 4, 223, 95, + 196, 12, 9, 1, 233, 76, 99, 4, 105, 185, 58, 9, 1, 233, 76, 99, 4, 115, + 185, 58, 9, 199, 168, 9, 1, 233, 48, 9, 1, 208, 91, 9, 1, 222, 108, 9, 1, + 220, 37, 9, 1, 216, 210, 9, 1, 213, 26, 9, 1, 229, 212, 9, 1, 193, 133, + 9, 1, 131, 217, 101, 9, 1, 192, 75, 9, 233, 70, 9, 237, 245, 9, 222, 52, + 9, 233, 72, 9, 237, 247, 9, 222, 54, 9, 203, 156, 9, 200, 206, 9, 217, + 142, 58, 9, 230, 60, 58, 9, 230, 60, 60, 9, 200, 231, 251, 194, 9, 223, + 95, 237, 247, 9, 87, 213, 27, 231, 59, 9, 190, 237, 9, 18, 3, 2, 196, 13, + 58, 9, 18, 3, 223, 95, 2, 196, 13, 58, 9, 18, 3, 75, 60, 9, 207, 19, 237, + 247, 9, 233, 73, 4, 105, 236, 140, 9, 193, 135, 230, 60, 60, 251, 30, 17, + 191, 77, 251, 30, 17, 107, 251, 30, 17, 109, 251, 30, 17, 138, 251, 30, + 17, 134, 251, 30, 17, 150, 251, 30, 17, 169, 251, 30, 17, 175, 251, 30, + 17, 171, 251, 30, 17, 178, 9, 210, 15, 56, 9, 237, 140, 204, 11, 9, 198, + 229, 204, 11, 9, 232, 228, 209, 62, 201, 103, 9, 1, 236, 141, 248, 247, + 9, 1, 236, 141, 208, 91, 9, 1, 200, 182, 251, 194, 9, 1, 131, 193, 150, + 9, 1, 131, 4, 193, 135, 230, 60, 58, 9, 1, 131, 4, 193, 135, 230, 60, 60, + 9, 1, 137, 230, 59, 9, 1, 137, 230, 60, 251, 194, 9, 1, 137, 230, 60, + 193, 133, 9, 1, 126, 4, 230, 60, 58, 9, 1, 137, 230, 60, 192, 75, 9, 1, + 197, 124, 9, 1, 197, 122, 9, 1, 249, 1, 9, 1, 199, 115, 4, 206, 189, 9, + 1, 199, 115, 4, 115, 185, 93, 235, 120, 9, 1, 210, 43, 9, 1, 199, 112, 9, + 1, 248, 245, 9, 1, 183, 4, 230, 60, 58, 9, 1, 183, 4, 105, 185, 81, 58, + 9, 1, 212, 89, 9, 1, 235, 43, 9, 1, 183, 4, 115, 185, 58, 9, 1, 199, 149, + 9, 1, 199, 147, 9, 1, 237, 188, 9, 1, 238, 6, 4, 206, 189, 9, 1, 238, 6, + 4, 75, 60, 9, 1, 238, 6, 4, 75, 248, 235, 23, 2, 199, 219, 9, 1, 238, 12, + 9, 1, 237, 190, 9, 1, 235, 80, 9, 1, 238, 6, 4, 115, 185, 93, 235, 120, + 9, 1, 238, 6, 4, 232, 130, 185, 58, 9, 1, 206, 102, 9, 1, 207, 73, 4, 2, + 196, 12, 9, 1, 207, 73, 4, 206, 189, 9, 1, 207, 73, 4, 75, 60, 9, 1, 207, + 73, 4, 2, 196, 13, 60, 9, 1, 207, 73, 4, 75, 248, 235, 23, 75, 58, 9, 1, + 207, 73, 4, 105, 185, 58, 9, 1, 223, 5, 9, 1, 207, 73, 4, 232, 130, 185, + 58, 9, 1, 205, 48, 4, 75, 248, 235, 23, 75, 58, 9, 1, 205, 48, 4, 115, + 185, 60, 9, 1, 205, 48, 4, 115, 185, 248, 235, 23, 115, 185, 58, 9, 1, + 205, 194, 4, 105, 185, 60, 9, 1, 205, 194, 4, 115, 185, 58, 9, 1, 199, + 220, 4, 115, 185, 58, 9, 1, 251, 233, 4, 115, 185, 58, 9, 1, 236, 141, + 233, 48, 9, 1, 233, 49, 4, 75, 215, 179, 60, 9, 1, 233, 49, 4, 75, 60, 9, + 1, 195, 146, 9, 1, 233, 49, 4, 115, 185, 60, 9, 1, 210, 41, 9, 1, 208, + 92, 4, 75, 58, 9, 1, 208, 92, 4, 115, 185, 58, 9, 1, 222, 6, 9, 1, 200, + 146, 222, 108, 9, 1, 222, 109, 4, 206, 189, 9, 1, 222, 109, 4, 75, 58, 9, + 1, 214, 72, 9, 1, 222, 109, 4, 115, 185, 60, 9, 1, 231, 229, 9, 1, 231, + 230, 4, 206, 189, 9, 1, 213, 249, 9, 1, 231, 230, 4, 105, 185, 60, 9, 1, + 230, 168, 9, 1, 231, 230, 4, 115, 185, 58, 9, 1, 220, 38, 4, 2, 196, 12, + 9, 1, 220, 38, 4, 75, 58, 9, 1, 220, 38, 4, 115, 185, 58, 9, 1, 220, 38, + 4, 115, 185, 60, 9, 1, 213, 27, 4, 75, 60, 9, 1, 213, 27, 231, 59, 9, 1, + 206, 166, 9, 1, 213, 27, 4, 206, 189, 9, 1, 213, 27, 4, 115, 185, 58, 9, + 1, 229, 213, 236, 172, 9, 1, 199, 150, 4, 75, 58, 9, 1, 229, 213, 4, 99, + 58, 9, 1, 229, 213, 231, 2, 9, 1, 229, 213, 231, 3, 4, 230, 60, 58, 9, 1, + 199, 115, 217, 65, 231, 2, 9, 1, 193, 134, 4, 206, 189, 9, 1, 221, 134, + 211, 153, 9, 1, 211, 153, 9, 1, 66, 9, 1, 191, 225, 9, 1, 221, 134, 191, + 225, 9, 1, 193, 134, 4, 105, 185, 58, 9, 1, 195, 153, 9, 1, 233, 76, 192, 75, 9, 1, 99, 4, 199, 215, 9, 1, 99, 4, 2, 196, 12, 9, 1, 193, 134, 4, - 75, 58, 9, 1, 71, 9, 1, 99, 4, 115, 185, 60, 9, 1, 99, 249, 80, 9, 1, 99, - 249, 81, 4, 230, 58, 58, 9, 232, 80, 201, 63, 9, 1, 252, 25, 9, 2, 137, - 34, 205, 193, 4, 220, 36, 4, 131, 217, 99, 9, 2, 137, 34, 208, 90, 4, - 220, 36, 4, 131, 217, 99, 9, 2, 137, 92, 89, 20, 9, 2, 137, 220, 36, 251, - 192, 9, 2, 137, 223, 6, 9, 2, 137, 115, 236, 138, 9, 2, 137, 205, 46, 9, - 234, 95, 79, 250, 130, 9, 201, 98, 79, 206, 60, 234, 141, 229, 114, 9, 2, - 137, 206, 113, 191, 77, 9, 2, 137, 196, 73, 207, 91, 191, 77, 9, 2, 137, - 236, 139, 229, 236, 79, 221, 210, 9, 2, 137, 92, 76, 20, 9, 2, 130, 205, - 46, 9, 2, 137, 217, 141, 9, 2, 193, 133, 9, 2, 192, 75, 9, 2, 137, 192, - 75, 9, 2, 137, 213, 24, 9, 209, 108, 79, 205, 177, 9, 234, 105, 247, 22, - 130, 201, 63, 9, 234, 105, 247, 22, 137, 201, 63, 9, 206, 113, 137, 201, - 64, 4, 233, 4, 247, 21, 9, 2, 130, 216, 208, 9, 1, 238, 4, 4, 223, 93, - 196, 12, 9, 1, 207, 72, 4, 223, 93, 196, 12, 233, 205, 251, 28, 17, 191, - 77, 233, 205, 251, 28, 17, 107, 233, 205, 251, 28, 17, 109, 233, 205, - 251, 28, 17, 138, 233, 205, 251, 28, 17, 134, 233, 205, 251, 28, 17, 149, - 233, 205, 251, 28, 17, 169, 233, 205, 251, 28, 17, 175, 233, 205, 251, - 28, 17, 171, 233, 205, 251, 28, 17, 178, 9, 1, 203, 110, 4, 75, 60, 9, 1, - 238, 27, 4, 75, 60, 9, 1, 231, 87, 4, 75, 60, 9, 3, 202, 173, 251, 137, - 9, 3, 202, 173, 209, 16, 216, 186, 9, 1, 229, 211, 4, 223, 93, 196, 12, - 200, 63, 234, 95, 79, 210, 127, 200, 63, 200, 177, 232, 80, 201, 63, 200, - 63, 200, 232, 232, 80, 201, 63, 200, 63, 200, 177, 242, 83, 200, 63, 200, - 232, 242, 83, 200, 63, 228, 241, 242, 83, 200, 63, 242, 84, 202, 110, - 219, 224, 200, 63, 242, 84, 202, 110, 183, 200, 63, 200, 177, 242, 84, - 202, 110, 219, 224, 200, 63, 200, 232, 242, 84, 202, 110, 183, 200, 63, - 239, 24, 200, 63, 230, 15, 211, 176, 200, 63, 230, 15, 216, 162, 200, 63, - 230, 15, 250, 195, 200, 63, 252, 68, 77, 200, 63, 1, 251, 202, 200, 63, - 1, 200, 182, 251, 202, 200, 63, 1, 248, 211, 200, 63, 1, 231, 217, 200, - 63, 1, 231, 218, 231, 194, 200, 63, 1, 238, 0, 200, 63, 1, 236, 139, 238, - 1, 206, 181, 200, 63, 1, 229, 245, 200, 63, 1, 193, 133, 200, 63, 1, 191, - 113, 200, 63, 1, 229, 184, 200, 63, 1, 199, 69, 200, 63, 1, 199, 70, 231, - 194, 200, 63, 1, 191, 208, 200, 63, 1, 191, 209, 229, 245, 200, 63, 1, - 222, 75, 200, 63, 1, 220, 34, 200, 63, 1, 216, 46, 200, 63, 1, 212, 130, - 200, 63, 1, 204, 18, 200, 63, 1, 53, 204, 18, 200, 63, 1, 71, 200, 63, 1, - 210, 63, 200, 63, 1, 207, 18, 210, 63, 200, 63, 1, 205, 189, 200, 63, 1, - 208, 83, 200, 63, 1, 206, 181, 200, 63, 1, 203, 69, 200, 63, 1, 199, 159, - 200, 63, 1, 209, 252, 248, 194, 200, 63, 1, 209, 252, 231, 84, 200, 63, - 1, 209, 252, 237, 63, 200, 63, 208, 166, 58, 200, 63, 208, 166, 60, 200, - 63, 208, 166, 235, 137, 200, 63, 191, 0, 58, 200, 63, 191, 0, 60, 200, - 63, 191, 0, 235, 137, 200, 63, 207, 116, 58, 200, 63, 207, 116, 60, 200, - 63, 235, 138, 191, 9, 228, 240, 200, 63, 235, 138, 191, 9, 251, 108, 200, - 63, 229, 250, 58, 200, 63, 229, 250, 60, 200, 63, 229, 249, 235, 137, - 200, 63, 234, 16, 58, 200, 63, 234, 16, 60, 200, 63, 206, 24, 200, 63, - 233, 40, 236, 140, 200, 63, 207, 246, 200, 63, 206, 54, 200, 63, 105, 81, - 185, 58, 200, 63, 105, 81, 185, 60, 200, 63, 115, 185, 58, 200, 63, 115, - 185, 60, 200, 63, 211, 172, 219, 113, 58, 200, 63, 211, 172, 219, 113, - 60, 200, 63, 215, 96, 200, 63, 249, 79, 200, 63, 1, 202, 28, 191, 69, - 200, 63, 1, 202, 28, 221, 201, 200, 63, 1, 202, 28, 233, 59, 9, 1, 248, - 246, 4, 115, 185, 228, 190, 60, 9, 1, 248, 246, 4, 75, 248, 233, 23, 115, - 185, 58, 9, 1, 248, 246, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, 248, - 246, 4, 115, 185, 209, 58, 196, 66, 248, 233, 23, 105, 185, 58, 9, 1, - 248, 246, 4, 105, 185, 248, 233, 23, 75, 58, 9, 1, 248, 246, 4, 223, 93, - 2, 196, 13, 60, 9, 1, 248, 246, 4, 2, 196, 12, 9, 1, 182, 4, 105, 185, - 58, 9, 1, 182, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, 238, 4, 4, 105, - 185, 195, 85, 248, 233, 23, 2, 199, 219, 9, 1, 238, 4, 4, 223, 93, 2, - 196, 13, 60, 9, 1, 207, 72, 4, 106, 9, 1, 205, 47, 4, 232, 128, 185, 58, - 9, 1, 251, 231, 4, 105, 185, 58, 9, 1, 251, 231, 4, 115, 185, 209, 58, - 235, 119, 58, 9, 1, 251, 231, 4, 105, 185, 195, 85, 58, 9, 1, 233, 47, 4, - 105, 185, 60, 9, 1, 233, 47, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, - 222, 5, 4, 75, 58, 9, 1, 222, 5, 4, 115, 185, 58, 9, 1, 222, 5, 4, 115, - 185, 209, 58, 196, 66, 60, 9, 1, 92, 4, 75, 58, 9, 1, 92, 4, 75, 60, 9, - 1, 213, 25, 4, 105, 185, 60, 9, 1, 213, 25, 4, 2, 199, 219, 9, 1, 213, - 25, 4, 2, 196, 12, 9, 1, 220, 36, 4, 164, 9, 1, 207, 72, 4, 105, 185, - 195, 85, 58, 9, 1, 207, 72, 4, 230, 58, 58, 9, 1, 205, 47, 4, 105, 185, - 195, 85, 58, 9, 1, 182, 4, 2, 9, 1, 199, 220, 60, 9, 1, 182, 4, 2, 9, 1, - 199, 220, 23, 105, 236, 138, 9, 1, 205, 47, 4, 2, 9, 1, 199, 220, 23, - 105, 236, 138, 9, 1, 207, 72, 4, 2, 9, 1, 199, 220, 23, 105, 236, 138, 9, - 1, 182, 4, 2, 9, 1, 199, 220, 58, 9, 1, 131, 4, 233, 205, 251, 28, 17, - 105, 58, 9, 1, 131, 4, 233, 205, 251, 28, 17, 115, 58, 9, 1, 233, 74, 99, - 4, 233, 205, 251, 28, 17, 105, 58, 9, 1, 233, 74, 99, 4, 233, 205, 251, - 28, 17, 115, 58, 9, 1, 233, 74, 99, 4, 233, 205, 251, 28, 17, 232, 128, - 60, 9, 1, 193, 134, 4, 233, 205, 251, 28, 17, 105, 58, 9, 1, 193, 134, 4, - 233, 205, 251, 28, 17, 115, 58, 9, 1, 99, 249, 81, 4, 233, 205, 251, 28, - 17, 105, 58, 9, 1, 99, 249, 81, 4, 233, 205, 251, 28, 17, 115, 58, 9, 1, - 182, 4, 233, 205, 251, 28, 17, 232, 128, 60, 9, 1, 205, 47, 4, 233, 205, - 251, 28, 17, 232, 128, 58, 9, 1, 205, 47, 4, 223, 93, 196, 12, 9, 1, 222, - 107, 4, 105, 185, 58, 199, 46, 1, 230, 91, 199, 46, 1, 203, 119, 199, 46, - 1, 213, 23, 199, 46, 1, 207, 178, 199, 46, 1, 249, 151, 199, 46, 1, 219, - 156, 199, 46, 1, 222, 122, 199, 46, 1, 251, 179, 199, 46, 1, 195, 186, - 199, 46, 1, 216, 207, 199, 46, 1, 233, 107, 199, 46, 1, 237, 66, 199, 46, - 1, 199, 48, 199, 46, 1, 220, 122, 199, 46, 1, 231, 236, 199, 46, 1, 231, - 6, 199, 46, 1, 205, 45, 199, 46, 1, 237, 207, 199, 46, 1, 191, 94, 199, - 46, 1, 199, 161, 199, 46, 1, 192, 140, 199, 46, 1, 210, 77, 199, 46, 1, - 223, 15, 199, 46, 1, 243, 130, 199, 46, 1, 197, 131, 199, 46, 1, 229, - 176, 199, 46, 1, 221, 214, 199, 46, 1, 199, 47, 199, 46, 1, 191, 121, - 199, 46, 1, 203, 108, 199, 46, 1, 205, 196, 199, 46, 1, 238, 30, 199, 46, - 1, 159, 199, 46, 1, 191, 7, 199, 46, 1, 251, 227, 199, 46, 1, 231, 85, - 199, 46, 1, 208, 93, 199, 46, 1, 193, 178, 199, 46, 252, 70, 199, 46, - 252, 171, 199, 46, 228, 29, 199, 46, 234, 187, 199, 46, 196, 161, 199, - 46, 211, 86, 199, 46, 234, 198, 199, 46, 233, 195, 199, 46, 211, 171, - 199, 46, 211, 181, 199, 46, 200, 206, 199, 46, 1, 214, 250, 213, 107, 17, - 191, 77, 213, 107, 17, 107, 213, 107, 17, 109, 213, 107, 17, 138, 213, - 107, 17, 134, 213, 107, 17, 149, 213, 107, 17, 169, 213, 107, 17, 175, - 213, 107, 17, 171, 213, 107, 17, 178, 213, 107, 1, 65, 213, 107, 1, 234, - 188, 213, 107, 1, 68, 213, 107, 1, 71, 213, 107, 1, 66, 213, 107, 1, 211, - 87, 213, 107, 1, 74, 213, 107, 1, 238, 18, 213, 107, 1, 215, 61, 213, - 107, 1, 249, 153, 213, 107, 1, 168, 213, 107, 1, 190, 190, 213, 107, 1, - 223, 32, 213, 107, 1, 247, 1, 213, 107, 1, 238, 32, 213, 107, 1, 165, - 213, 107, 1, 206, 109, 213, 107, 1, 188, 213, 107, 1, 231, 182, 213, 107, - 1, 233, 109, 213, 107, 1, 155, 213, 107, 1, 173, 213, 107, 1, 215, 7, - 193, 37, 213, 107, 1, 174, 213, 107, 1, 212, 101, 213, 107, 1, 180, 213, - 107, 1, 140, 213, 107, 1, 193, 190, 213, 107, 1, 170, 213, 107, 1, 212, - 102, 193, 37, 213, 107, 1, 222, 193, 223, 32, 213, 107, 1, 222, 193, 247, - 1, 213, 107, 1, 222, 193, 165, 213, 107, 33, 203, 40, 137, 198, 79, 213, - 107, 33, 203, 40, 130, 198, 79, 213, 107, 33, 203, 40, 206, 180, 198, 79, - 213, 107, 33, 179, 237, 86, 198, 79, 213, 107, 33, 179, 137, 198, 79, - 213, 107, 33, 179, 130, 198, 79, 213, 107, 33, 179, 206, 180, 198, 79, - 213, 107, 33, 214, 213, 77, 213, 107, 33, 55, 75, 58, 213, 107, 137, 163, - 251, 49, 213, 107, 130, 163, 251, 49, 213, 107, 16, 211, 88, 237, 101, - 213, 107, 16, 231, 181, 213, 107, 242, 74, 213, 107, 233, 216, 77, 213, - 107, 220, 94, 213, 107, 237, 233, 213, 107, 236, 142, 56, 213, 107, 199, - 195, 56, 205, 151, 1, 251, 204, 205, 151, 1, 248, 148, 205, 151, 1, 231, - 216, 205, 151, 1, 238, 2, 205, 151, 1, 223, 44, 205, 151, 1, 249, 151, - 205, 151, 1, 191, 80, 205, 151, 1, 223, 53, 205, 151, 1, 198, 125, 205, - 151, 1, 191, 189, 205, 151, 1, 222, 123, 205, 151, 1, 220, 118, 205, 151, - 1, 216, 46, 205, 151, 1, 212, 130, 205, 151, 1, 202, 171, 205, 151, 1, - 223, 162, 205, 151, 1, 233, 23, 205, 151, 1, 197, 166, 205, 151, 1, 208, - 10, 205, 151, 1, 206, 181, 205, 151, 1, 203, 138, 205, 151, 1, 199, 243, - 205, 151, 87, 223, 162, 205, 151, 87, 223, 161, 205, 151, 87, 211, 165, - 205, 151, 87, 238, 16, 205, 151, 52, 1, 234, 52, 191, 189, 205, 151, 87, - 234, 52, 191, 189, 205, 151, 18, 3, 179, 71, 205, 151, 18, 3, 71, 205, - 151, 18, 3, 210, 253, 252, 206, 205, 151, 18, 3, 179, 252, 206, 205, 151, - 18, 3, 252, 206, 205, 151, 18, 3, 210, 253, 65, 205, 151, 18, 3, 179, 65, - 205, 151, 18, 3, 65, 205, 151, 52, 1, 203, 40, 65, 205, 151, 18, 3, 203, - 40, 65, 205, 151, 18, 3, 179, 66, 205, 151, 18, 3, 66, 205, 151, 52, 1, - 68, 205, 151, 18, 3, 179, 68, 205, 151, 18, 3, 68, 205, 151, 18, 3, 74, - 205, 151, 18, 3, 200, 206, 205, 151, 87, 214, 93, 205, 151, 208, 152, - 214, 93, 205, 151, 208, 152, 251, 255, 205, 151, 208, 152, 251, 121, 205, - 151, 208, 152, 249, 57, 205, 151, 208, 152, 250, 174, 205, 151, 208, 152, - 203, 57, 205, 151, 252, 68, 77, 205, 151, 208, 152, 216, 197, 208, 48, - 205, 151, 208, 152, 191, 16, 205, 151, 208, 152, 208, 48, 205, 151, 208, - 152, 191, 119, 205, 151, 208, 152, 197, 54, 205, 151, 208, 152, 250, 255, - 205, 151, 208, 152, 202, 33, 217, 37, 205, 151, 208, 152, 251, 97, 217, - 86, 1, 230, 65, 217, 86, 1, 252, 155, 217, 86, 1, 251, 253, 217, 86, 1, - 252, 42, 217, 86, 1, 251, 245, 217, 86, 1, 196, 36, 217, 86, 1, 250, 123, - 217, 86, 1, 223, 53, 217, 86, 1, 250, 171, 217, 86, 1, 251, 211, 217, 86, - 1, 251, 216, 217, 86, 1, 251, 207, 217, 86, 1, 251, 149, 217, 86, 1, 251, - 132, 217, 86, 1, 250, 219, 217, 86, 1, 223, 162, 217, 86, 1, 251, 65, - 217, 86, 1, 250, 184, 217, 86, 1, 251, 37, 217, 86, 1, 251, 33, 217, 86, - 1, 250, 209, 217, 86, 1, 250, 182, 217, 86, 1, 235, 62, 217, 86, 1, 222, - 114, 217, 86, 1, 251, 230, 217, 86, 252, 3, 77, 217, 86, 195, 22, 77, - 217, 86, 231, 153, 77, 217, 86, 208, 151, 200, 63, 1, 142, 214, 68, 200, - 63, 1, 142, 223, 32, 200, 63, 1, 142, 212, 101, 200, 63, 1, 142, 197, - 132, 200, 63, 1, 142, 213, 79, 200, 63, 1, 142, 213, 61, 200, 63, 1, 142, - 248, 203, 200, 63, 1, 142, 165, 200, 63, 1, 142, 219, 73, 200, 63, 1, - 142, 219, 62, 200, 63, 1, 142, 201, 175, 9, 1, 131, 4, 250, 170, 233, 70, - 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, 70, 9, 1, 131, 4, 50, 82, 106, - 9, 1, 131, 4, 45, 82, 106, 9, 1, 131, 4, 250, 170, 222, 52, 9, 1, 131, 4, - 250, 170, 248, 77, 50, 222, 52, 9, 1, 131, 4, 250, 170, 206, 115, 75, 58, - 9, 1, 131, 4, 250, 170, 50, 206, 115, 236, 140, 9, 1, 131, 4, 250, 170, - 45, 206, 115, 236, 140, 9, 1, 131, 4, 250, 170, 206, 115, 75, 60, 9, 1, - 131, 4, 75, 58, 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, 71, 23, 75, 58, - 9, 1, 131, 4, 50, 82, 201, 28, 23, 75, 58, 9, 1, 131, 4, 250, 170, 248, - 77, 50, 222, 53, 23, 75, 58, 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, - 71, 23, 45, 206, 188, 9, 1, 131, 4, 50, 82, 201, 28, 23, 45, 206, 188, 9, - 1, 131, 4, 250, 170, 248, 77, 50, 222, 53, 23, 45, 206, 188, 9, 1, 131, - 4, 250, 170, 50, 230, 57, 9, 1, 131, 4, 250, 170, 45, 230, 57, 9, 199, - 169, 4, 210, 251, 230, 57, 9, 199, 169, 4, 210, 251, 193, 133, 9, 199, - 169, 4, 105, 185, 60, 9, 1, 199, 4, 192, 75, 9, 249, 72, 206, 115, 236, - 140, 9, 207, 147, 206, 115, 236, 140, 9, 1, 213, 25, 4, 223, 93, 2, 196, - 12, 9, 1, 182, 4, 223, 93, 2, 196, 13, 60, 9, 1, 199, 220, 4, 75, 60, 9, - 1, 199, 220, 4, 115, 185, 60, 9, 1, 222, 5, 4, 105, 185, 195, 85, 60, 9, - 81, 199, 215, 9, 209, 8, 87, 58, 9, 209, 182, 87, 58, 9, 2, 137, 193, 23, - 251, 206, 9, 2, 130, 193, 23, 223, 61, 9, 2, 130, 193, 23, 223, 179, 9, - 2, 130, 193, 23, 199, 173, 9, 217, 142, 193, 179, 9, 200, 182, 131, 215, - 234, 9, 235, 128, 217, 141, 9, 132, 217, 142, 139, 217, 141, 9, 1, 248, - 246, 4, 2, 196, 13, 60, 9, 1, 248, 246, 4, 230, 58, 58, 9, 1, 223, 7, 4, - 105, 185, 58, 9, 1, 199, 220, 4, 105, 185, 58, 9, 1, 233, 47, 4, 75, 248, - 233, 23, 115, 185, 58, 9, 1, 208, 90, 4, 75, 60, 9, 1, 220, 36, 4, 55, - 164, 9, 1, 92, 4, 115, 185, 58, 9, 1, 99, 4, 105, 185, 248, 233, 23, 230, - 58, 58, 9, 1, 99, 4, 105, 185, 248, 233, 23, 75, 58, 9, 1, 207, 72, 4, - 219, 4, 9, 1, 193, 134, 4, 75, 193, 52, 9, 1, 206, 142, 192, 75, 9, 1, - 130, 251, 192, 9, 1, 238, 4, 4, 115, 185, 60, 9, 1, 205, 193, 4, 115, - 185, 60, 9, 1, 231, 228, 4, 223, 93, 106, 9, 1, 201, 53, 193, 133, 9, 1, - 191, 114, 4, 223, 93, 196, 13, 58, 9, 1, 251, 231, 4, 115, 185, 60, 9, 1, - 222, 107, 4, 75, 60, 9, 1, 208, 90, 4, 75, 248, 233, 23, 213, 44, 185, - 58, 9, 1, 248, 246, 4, 2, 92, 58, 9, 1, 210, 42, 4, 2, 92, 58, 9, 1, 199, - 115, 4, 2, 199, 115, 58, 9, 1, 207, 72, 4, 2, 213, 25, 58, 9, 1, 99, 4, - 105, 185, 248, 233, 23, 2, 213, 25, 58, 9, 1, 252, 0, 233, 46, 9, 1, 252, - 0, 208, 89, 9, 1, 252, 0, 213, 24, 9, 1, 210, 42, 4, 2, 196, 12, 9, 1, - 199, 115, 4, 2, 196, 12, 9, 1, 197, 125, 4, 2, 196, 12, 9, 1, 199, 150, - 4, 2, 196, 12, 9, 1, 222, 5, 4, 2, 196, 12, 9, 1, 231, 87, 4, 115, 185, - 58, 9, 1, 252, 0, 208, 90, 4, 115, 185, 58, 9, 1, 223, 7, 4, 115, 185, - 58, 9, 1, 223, 7, 4, 115, 185, 60, 9, 1, 220, 36, 4, 2, 9, 1, 199, 220, - 58, 9, 1, 230, 224, 9, 2, 233, 74, 192, 75, 9, 2, 137, 233, 74, 192, 75, - 9, 2, 137, 99, 249, 81, 4, 105, 185, 60, 9, 2, 137, 193, 23, 205, 182, 9, - 2, 137, 191, 116, 9, 220, 13, 206, 115, 75, 58, 9, 220, 13, 206, 115, 75, - 60, 9, 200, 207, 60, 9, 220, 13, 243, 11, 60, 9, 220, 13, 206, 115, 75, - 223, 118, 243, 11, 60, 9, 2, 130, 193, 133, 9, 2, 137, 193, 23, 251, 30, - 9, 2, 137, 205, 192, 9, 2, 137, 251, 230, 9, 2, 137, 208, 89, 9, 2, 137, - 213, 25, 4, 222, 52, 9, 2, 130, 213, 25, 4, 222, 52, 9, 2, 137, 193, 23, - 250, 181, 9, 2, 137, 193, 23, 250, 218, 9, 2, 137, 193, 23, 251, 131, 9, - 2, 137, 193, 23, 205, 171, 9, 2, 137, 193, 23, 208, 52, 9, 2, 137, 193, - 23, 193, 157, 9, 2, 137, 232, 157, 217, 51, 9, 2, 137, 3, 205, 187, 9, - 236, 218, 234, 95, 79, 250, 130, 9, 153, 237, 246, 60, 9, 238, 171, 233, - 70, 9, 238, 171, 237, 245, 9, 238, 171, 222, 52, 9, 238, 171, 233, 68, 9, - 238, 171, 237, 243, 9, 238, 171, 222, 50, 9, 163, 91, 75, 58, 9, 163, - 105, 185, 58, 9, 163, 219, 5, 58, 9, 163, 91, 75, 60, 9, 163, 105, 185, - 60, 9, 163, 219, 5, 60, 9, 211, 77, 233, 68, 9, 211, 77, 237, 243, 9, - 211, 77, 222, 50, 9, 2, 137, 193, 133, 9, 233, 71, 4, 206, 188, 9, 233, - 71, 4, 75, 58, 9, 222, 53, 4, 75, 60, 9, 45, 250, 236, 58, 9, 50, 250, - 236, 58, 9, 45, 250, 236, 60, 9, 50, 250, 236, 60, 9, 55, 50, 250, 236, - 58, 9, 55, 50, 250, 236, 93, 4, 236, 140, 9, 50, 250, 236, 93, 4, 236, - 140, 9, 237, 246, 4, 236, 140, 9, 87, 202, 206, 213, 25, 231, 57, 100, 3, - 223, 93, 247, 119, 100, 3, 247, 119, 100, 3, 251, 71, 100, 3, 195, 35, - 100, 1, 203, 40, 65, 100, 1, 65, 100, 1, 252, 206, 100, 1, 68, 100, 1, - 223, 199, 100, 1, 66, 100, 1, 196, 30, 100, 1, 117, 146, 100, 1, 117, - 172, 100, 1, 247, 122, 71, 100, 1, 203, 40, 71, 100, 1, 71, 100, 1, 251, - 236, 100, 1, 247, 122, 74, 100, 1, 203, 40, 74, 100, 1, 74, 100, 1, 250, - 163, 100, 1, 155, 100, 1, 221, 215, 100, 1, 231, 240, 100, 1, 231, 91, - 100, 1, 214, 68, 100, 1, 247, 160, 100, 1, 247, 1, 100, 1, 223, 32, 100, - 1, 222, 252, 100, 1, 212, 101, 100, 1, 197, 132, 100, 1, 197, 120, 100, - 1, 237, 191, 100, 1, 237, 175, 100, 1, 213, 79, 100, 1, 190, 190, 100, 1, - 199, 49, 100, 1, 238, 32, 100, 1, 237, 68, 100, 1, 180, 100, 1, 213, 61, - 100, 1, 168, 100, 1, 209, 228, 100, 1, 249, 153, 100, 1, 248, 203, 100, - 1, 174, 100, 1, 170, 100, 1, 165, 100, 1, 206, 109, 100, 1, 173, 100, 1, - 219, 73, 100, 1, 219, 62, 100, 1, 195, 188, 100, 1, 203, 165, 100, 1, - 201, 175, 100, 1, 188, 100, 1, 140, 100, 18, 3, 211, 151, 100, 18, 3, - 211, 85, 100, 3, 212, 141, 100, 3, 250, 145, 100, 18, 3, 252, 206, 100, - 18, 3, 68, 100, 18, 3, 223, 199, 100, 18, 3, 66, 100, 18, 3, 196, 30, - 100, 18, 3, 117, 146, 100, 18, 3, 117, 206, 110, 100, 18, 3, 247, 122, - 71, 100, 18, 3, 203, 40, 71, 100, 18, 3, 71, 100, 18, 3, 251, 236, 100, - 18, 3, 247, 122, 74, 100, 18, 3, 203, 40, 74, 100, 18, 3, 74, 100, 18, 3, - 250, 163, 100, 3, 195, 40, 100, 18, 3, 208, 207, 71, 100, 18, 3, 250, - 140, 100, 211, 113, 100, 201, 38, 3, 196, 154, 100, 201, 38, 3, 251, 73, - 100, 230, 211, 252, 60, 100, 252, 47, 252, 60, 100, 18, 3, 247, 122, 179, - 71, 100, 18, 3, 196, 152, 100, 18, 3, 196, 29, 100, 1, 208, 96, 100, 1, - 221, 193, 100, 1, 231, 66, 100, 1, 191, 123, 100, 1, 237, 180, 100, 1, - 207, 6, 100, 1, 233, 109, 100, 1, 191, 175, 100, 1, 117, 206, 110, 100, - 1, 117, 219, 74, 100, 18, 3, 117, 172, 100, 18, 3, 117, 219, 74, 100, - 237, 238, 100, 55, 237, 238, 100, 17, 191, 77, 100, 17, 107, 100, 17, - 109, 100, 17, 138, 100, 17, 134, 100, 17, 149, 100, 17, 169, 100, 17, - 175, 100, 17, 171, 100, 17, 178, 100, 252, 68, 56, 100, 3, 137, 201, 246, - 236, 140, 100, 1, 247, 122, 65, 100, 1, 211, 151, 100, 1, 211, 85, 100, - 1, 250, 140, 100, 1, 196, 152, 100, 1, 196, 29, 100, 1, 217, 43, 237, - 191, 100, 1, 191, 71, 100, 1, 88, 170, 100, 1, 231, 127, 100, 1, 222, - 230, 100, 1, 231, 11, 201, 63, 100, 1, 237, 181, 100, 1, 249, 53, 248, - 225, 251, 100, 248, 225, 3, 247, 119, 248, 225, 3, 251, 71, 248, 225, 3, - 195, 35, 248, 225, 1, 65, 248, 225, 1, 252, 206, 248, 225, 1, 68, 248, - 225, 1, 223, 199, 248, 225, 1, 66, 248, 225, 1, 196, 30, 248, 225, 1, - 117, 146, 248, 225, 1, 117, 172, 248, 225, 1, 71, 248, 225, 1, 251, 236, - 248, 225, 1, 74, 248, 225, 1, 250, 163, 248, 225, 1, 155, 248, 225, 1, - 221, 215, 248, 225, 1, 231, 240, 248, 225, 1, 231, 91, 248, 225, 1, 214, - 68, 248, 225, 1, 247, 160, 248, 225, 1, 247, 1, 248, 225, 1, 223, 32, - 248, 225, 1, 222, 252, 248, 225, 1, 212, 101, 248, 225, 1, 197, 132, 248, - 225, 1, 197, 120, 248, 225, 1, 237, 191, 248, 225, 1, 237, 175, 248, 225, - 1, 213, 79, 248, 225, 1, 190, 190, 248, 225, 1, 199, 49, 248, 225, 1, - 238, 32, 248, 225, 1, 237, 68, 248, 225, 1, 180, 248, 225, 1, 168, 248, - 225, 1, 209, 228, 248, 225, 1, 249, 153, 248, 225, 1, 248, 203, 248, 225, - 1, 174, 248, 225, 1, 170, 248, 225, 1, 165, 248, 225, 1, 173, 248, 225, - 1, 203, 165, 248, 225, 1, 201, 175, 248, 225, 1, 188, 248, 225, 1, 140, - 248, 225, 3, 212, 141, 248, 225, 3, 250, 145, 248, 225, 18, 3, 252, 206, - 248, 225, 18, 3, 68, 248, 225, 18, 3, 223, 199, 248, 225, 18, 3, 66, 248, - 225, 18, 3, 196, 30, 248, 225, 18, 3, 117, 146, 248, 225, 18, 3, 117, - 206, 110, 248, 225, 18, 3, 71, 248, 225, 18, 3, 251, 236, 248, 225, 18, - 3, 74, 248, 225, 18, 3, 250, 163, 248, 225, 3, 195, 40, 248, 225, 1, 221, - 204, 190, 190, 248, 225, 250, 164, 219, 198, 77, 248, 225, 1, 206, 109, - 248, 225, 1, 207, 6, 248, 225, 1, 191, 175, 248, 225, 1, 117, 206, 110, - 248, 225, 1, 117, 219, 74, 248, 225, 18, 3, 117, 172, 248, 225, 18, 3, - 117, 219, 74, 248, 225, 17, 191, 77, 248, 225, 17, 107, 248, 225, 17, - 109, 248, 225, 17, 138, 248, 225, 17, 134, 248, 225, 17, 149, 248, 225, - 17, 169, 248, 225, 17, 175, 248, 225, 17, 171, 248, 225, 17, 178, 248, - 225, 1, 207, 186, 4, 82, 237, 38, 248, 225, 1, 207, 186, 4, 110, 237, 38, - 248, 225, 206, 36, 77, 248, 225, 206, 36, 56, 248, 225, 238, 170, 212, - 133, 107, 248, 225, 238, 170, 212, 133, 109, 248, 225, 238, 170, 212, - 133, 138, 248, 225, 238, 170, 212, 133, 134, 248, 225, 238, 170, 212, - 133, 91, 219, 181, 199, 39, 199, 34, 237, 99, 248, 225, 238, 170, 237, - 100, 202, 130, 248, 225, 223, 54, 248, 225, 231, 207, 77, 248, 225, 1, - 195, 150, 251, 71, 248, 225, 252, 68, 56, 248, 225, 205, 138, 77, 230, - 144, 3, 252, 41, 248, 167, 230, 144, 3, 248, 167, 230, 144, 3, 195, 35, - 230, 144, 1, 65, 230, 144, 1, 252, 206, 230, 144, 1, 68, 230, 144, 1, - 223, 199, 230, 144, 1, 66, 230, 144, 1, 196, 30, 230, 144, 1, 234, 188, - 230, 144, 1, 251, 236, 230, 144, 1, 211, 87, 230, 144, 1, 250, 163, 230, - 144, 1, 155, 230, 144, 1, 221, 215, 230, 144, 1, 231, 240, 230, 144, 1, - 231, 91, 230, 144, 1, 214, 68, 230, 144, 1, 247, 160, 230, 144, 1, 247, - 1, 230, 144, 1, 223, 32, 230, 144, 1, 222, 252, 230, 144, 1, 212, 101, - 230, 144, 1, 197, 132, 230, 144, 1, 197, 120, 230, 144, 1, 237, 191, 230, - 144, 1, 237, 175, 230, 144, 1, 213, 79, 230, 144, 1, 190, 190, 230, 144, - 1, 199, 49, 230, 144, 1, 238, 32, 230, 144, 1, 237, 68, 230, 144, 1, 180, - 230, 144, 1, 168, 230, 144, 1, 209, 228, 230, 144, 1, 249, 153, 230, 144, - 1, 248, 203, 230, 144, 1, 174, 230, 144, 1, 170, 230, 144, 1, 165, 230, - 144, 1, 173, 230, 144, 1, 219, 73, 230, 144, 1, 195, 188, 230, 144, 1, - 203, 165, 230, 144, 1, 188, 230, 144, 1, 140, 230, 144, 3, 212, 141, 230, - 144, 18, 3, 252, 206, 230, 144, 18, 3, 68, 230, 144, 18, 3, 223, 199, - 230, 144, 18, 3, 66, 230, 144, 18, 3, 196, 30, 230, 144, 18, 3, 234, 188, - 230, 144, 18, 3, 251, 236, 230, 144, 18, 3, 211, 87, 230, 144, 18, 3, - 250, 163, 230, 144, 3, 195, 40, 230, 144, 3, 196, 157, 230, 144, 1, 221, - 193, 230, 144, 1, 231, 66, 230, 144, 1, 191, 123, 230, 144, 1, 206, 109, - 230, 144, 1, 233, 109, 230, 144, 17, 191, 77, 230, 144, 17, 107, 230, - 144, 17, 109, 230, 144, 17, 138, 230, 144, 17, 134, 230, 144, 17, 149, - 230, 144, 17, 169, 230, 144, 17, 175, 230, 144, 17, 171, 230, 144, 17, - 178, 230, 144, 198, 133, 230, 144, 252, 40, 230, 144, 223, 75, 230, 144, - 196, 58, 230, 144, 234, 148, 211, 92, 230, 144, 3, 192, 115, 230, 144, - 252, 68, 56, 230, 161, 3, 247, 119, 230, 161, 3, 251, 71, 230, 161, 3, - 195, 35, 230, 161, 1, 65, 230, 161, 1, 252, 206, 230, 161, 1, 68, 230, - 161, 1, 223, 199, 230, 161, 1, 66, 230, 161, 1, 196, 30, 230, 161, 1, - 117, 146, 230, 161, 1, 117, 172, 230, 161, 18, 247, 122, 71, 230, 161, 1, - 71, 230, 161, 1, 251, 236, 230, 161, 18, 247, 122, 74, 230, 161, 1, 74, - 230, 161, 1, 250, 163, 230, 161, 1, 155, 230, 161, 1, 221, 215, 230, 161, - 1, 231, 240, 230, 161, 1, 231, 91, 230, 161, 1, 214, 68, 230, 161, 1, - 247, 160, 230, 161, 1, 247, 1, 230, 161, 1, 223, 32, 230, 161, 1, 222, - 252, 230, 161, 1, 212, 101, 230, 161, 1, 197, 132, 230, 161, 1, 197, 120, - 230, 161, 1, 237, 191, 230, 161, 1, 237, 175, 230, 161, 1, 213, 79, 230, - 161, 1, 190, 190, 230, 161, 1, 199, 49, 230, 161, 1, 238, 32, 230, 161, - 1, 237, 68, 230, 161, 1, 180, 230, 161, 1, 168, 230, 161, 1, 209, 228, - 230, 161, 1, 249, 153, 230, 161, 1, 248, 203, 230, 161, 1, 174, 230, 161, - 1, 170, 230, 161, 1, 165, 230, 161, 1, 173, 230, 161, 1, 219, 73, 230, - 161, 1, 195, 188, 230, 161, 1, 203, 165, 230, 161, 1, 201, 175, 230, 161, - 1, 188, 230, 161, 1, 140, 230, 161, 3, 212, 141, 230, 161, 3, 250, 145, - 230, 161, 18, 3, 252, 206, 230, 161, 18, 3, 68, 230, 161, 18, 3, 223, - 199, 230, 161, 18, 3, 66, 230, 161, 18, 3, 196, 30, 230, 161, 18, 3, 117, - 146, 230, 161, 18, 3, 117, 206, 110, 230, 161, 18, 3, 247, 122, 71, 230, - 161, 18, 3, 71, 230, 161, 18, 3, 251, 236, 230, 161, 18, 3, 247, 122, 74, - 230, 161, 18, 3, 74, 230, 161, 18, 3, 250, 163, 230, 161, 3, 195, 40, - 230, 161, 211, 113, 230, 161, 1, 117, 206, 110, 230, 161, 1, 117, 219, - 74, 230, 161, 18, 3, 117, 172, 230, 161, 18, 3, 117, 219, 74, 230, 161, - 17, 191, 77, 230, 161, 17, 107, 230, 161, 17, 109, 230, 161, 17, 138, - 230, 161, 17, 134, 230, 161, 17, 149, 230, 161, 17, 169, 230, 161, 17, - 175, 230, 161, 17, 171, 230, 161, 17, 178, 230, 161, 252, 68, 56, 230, - 161, 206, 36, 56, 230, 161, 1, 191, 71, 230, 161, 3, 200, 206, 230, 161, - 3, 203, 155, 230, 161, 3, 217, 139, 230, 161, 3, 198, 224, 212, 142, 58, - 230, 161, 3, 243, 11, 212, 142, 58, 230, 161, 3, 197, 15, 212, 142, 58, - 211, 45, 3, 247, 119, 211, 45, 3, 251, 71, 211, 45, 3, 195, 35, 211, 45, - 1, 65, 211, 45, 1, 252, 206, 211, 45, 1, 68, 211, 45, 1, 223, 199, 211, - 45, 1, 66, 211, 45, 1, 196, 30, 211, 45, 1, 117, 146, 211, 45, 1, 117, - 172, 211, 45, 1, 71, 211, 45, 1, 251, 236, 211, 45, 1, 74, 211, 45, 1, - 250, 163, 211, 45, 1, 155, 211, 45, 1, 221, 215, 211, 45, 1, 231, 240, - 211, 45, 1, 231, 91, 211, 45, 1, 214, 68, 211, 45, 1, 247, 160, 211, 45, - 1, 247, 1, 211, 45, 1, 223, 32, 211, 45, 1, 222, 252, 211, 45, 1, 212, - 101, 211, 45, 1, 197, 132, 211, 45, 1, 197, 120, 211, 45, 1, 237, 191, - 211, 45, 1, 237, 175, 211, 45, 1, 213, 79, 211, 45, 1, 190, 190, 211, 45, - 1, 199, 49, 211, 45, 1, 238, 32, 211, 45, 1, 237, 68, 211, 45, 1, 180, - 211, 45, 1, 168, 211, 45, 1, 209, 228, 211, 45, 1, 249, 153, 211, 45, 1, - 248, 203, 211, 45, 1, 174, 211, 45, 1, 170, 211, 45, 1, 165, 211, 45, 1, - 173, 211, 45, 1, 219, 73, 211, 45, 1, 195, 188, 211, 45, 1, 203, 165, - 211, 45, 1, 201, 175, 211, 45, 1, 188, 211, 45, 1, 140, 211, 45, 3, 212, - 141, 211, 45, 3, 250, 145, 211, 45, 18, 3, 252, 206, 211, 45, 18, 3, 68, - 211, 45, 18, 3, 223, 199, 211, 45, 18, 3, 66, 211, 45, 18, 3, 196, 30, - 211, 45, 18, 3, 117, 146, 211, 45, 18, 3, 117, 206, 110, 211, 45, 18, 3, - 71, 211, 45, 18, 3, 251, 236, 211, 45, 18, 3, 74, 211, 45, 18, 3, 250, - 163, 211, 45, 3, 195, 40, 211, 45, 3, 210, 254, 211, 45, 251, 237, 219, - 198, 77, 211, 45, 250, 164, 219, 198, 77, 211, 45, 1, 206, 109, 211, 45, - 1, 207, 6, 211, 45, 1, 191, 175, 211, 45, 1, 117, 206, 110, 211, 45, 1, - 117, 219, 74, 211, 45, 18, 3, 117, 172, 211, 45, 18, 3, 117, 219, 74, - 211, 45, 17, 191, 77, 211, 45, 17, 107, 211, 45, 17, 109, 211, 45, 17, - 138, 211, 45, 17, 134, 211, 45, 17, 149, 211, 45, 17, 169, 211, 45, 17, - 175, 211, 45, 17, 171, 211, 45, 17, 178, 211, 45, 223, 54, 211, 45, 1, - 193, 190, 211, 45, 232, 118, 91, 208, 22, 211, 45, 232, 118, 91, 230, 70, - 211, 45, 232, 118, 115, 208, 20, 211, 45, 232, 118, 91, 202, 128, 211, - 45, 232, 118, 91, 234, 159, 211, 45, 232, 118, 115, 202, 125, 44, 3, 251, - 71, 44, 3, 195, 35, 44, 1, 65, 44, 1, 252, 206, 44, 1, 68, 44, 1, 223, - 199, 44, 1, 66, 44, 1, 196, 30, 44, 1, 71, 44, 1, 234, 188, 44, 1, 251, - 236, 44, 1, 74, 44, 1, 211, 87, 44, 1, 250, 163, 44, 1, 155, 44, 1, 214, - 68, 44, 1, 247, 160, 44, 1, 223, 32, 44, 1, 212, 101, 44, 1, 197, 132, - 44, 1, 213, 79, 44, 1, 190, 190, 44, 1, 180, 44, 1, 213, 61, 44, 1, 168, - 44, 1, 174, 44, 1, 170, 44, 1, 165, 44, 1, 206, 109, 44, 1, 173, 44, 1, - 219, 73, 44, 1, 219, 62, 44, 1, 195, 188, 44, 1, 203, 165, 44, 1, 201, - 175, 44, 1, 188, 44, 1, 140, 44, 18, 3, 252, 206, 44, 18, 3, 68, 44, 18, - 3, 223, 199, 44, 18, 3, 66, 44, 18, 3, 196, 30, 44, 18, 3, 71, 44, 18, 3, - 234, 188, 44, 18, 3, 251, 236, 44, 18, 3, 74, 44, 18, 3, 211, 87, 44, 18, - 3, 250, 163, 44, 3, 195, 40, 44, 211, 113, 44, 250, 164, 219, 198, 77, + 75, 58, 9, 1, 71, 9, 1, 99, 4, 115, 185, 60, 9, 1, 99, 249, 82, 9, 1, 99, + 249, 83, 4, 230, 60, 58, 9, 232, 82, 201, 64, 9, 1, 252, 27, 9, 2, 137, + 34, 205, 194, 4, 220, 38, 4, 131, 217, 101, 9, 2, 137, 34, 208, 92, 4, + 220, 38, 4, 131, 217, 101, 9, 2, 137, 92, 89, 20, 9, 2, 137, 220, 38, + 251, 194, 9, 2, 137, 223, 8, 9, 2, 137, 115, 236, 140, 9, 2, 137, 205, + 47, 9, 234, 97, 79, 250, 132, 9, 201, 99, 79, 206, 61, 234, 143, 229, + 116, 9, 2, 137, 206, 114, 191, 77, 9, 2, 137, 196, 73, 207, 93, 191, 77, + 9, 2, 137, 236, 141, 229, 238, 79, 221, 212, 9, 2, 137, 92, 76, 20, 9, 2, + 130, 205, 47, 9, 2, 137, 217, 143, 9, 2, 193, 133, 9, 2, 192, 75, 9, 2, + 137, 192, 75, 9, 2, 137, 213, 26, 9, 209, 110, 79, 205, 178, 9, 234, 107, + 247, 24, 130, 201, 64, 9, 234, 107, 247, 24, 137, 201, 64, 9, 206, 114, + 137, 201, 65, 4, 233, 6, 247, 23, 9, 2, 130, 216, 210, 9, 1, 238, 6, 4, + 223, 95, 196, 12, 9, 1, 207, 73, 4, 223, 95, 196, 12, 233, 207, 251, 30, + 17, 191, 77, 233, 207, 251, 30, 17, 107, 233, 207, 251, 30, 17, 109, 233, + 207, 251, 30, 17, 138, 233, 207, 251, 30, 17, 134, 233, 207, 251, 30, 17, + 150, 233, 207, 251, 30, 17, 169, 233, 207, 251, 30, 17, 175, 233, 207, + 251, 30, 17, 171, 233, 207, 251, 30, 17, 178, 9, 1, 203, 111, 4, 75, 60, + 9, 1, 238, 29, 4, 75, 60, 9, 1, 231, 89, 4, 75, 60, 9, 3, 202, 174, 251, + 139, 9, 3, 202, 174, 209, 18, 216, 188, 9, 1, 229, 213, 4, 223, 95, 196, + 12, 200, 63, 234, 97, 79, 210, 129, 200, 63, 200, 177, 232, 82, 201, 64, + 200, 63, 200, 233, 232, 82, 201, 64, 200, 63, 200, 177, 242, 85, 200, 63, + 200, 233, 242, 85, 200, 63, 228, 243, 242, 85, 200, 63, 242, 86, 202, + 111, 219, 226, 200, 63, 242, 86, 202, 111, 179, 200, 63, 200, 177, 242, + 86, 202, 111, 219, 226, 200, 63, 200, 233, 242, 86, 202, 111, 179, 200, + 63, 239, 26, 200, 63, 230, 17, 211, 178, 200, 63, 230, 17, 216, 164, 200, + 63, 230, 17, 250, 197, 200, 63, 252, 70, 77, 200, 63, 1, 251, 204, 200, + 63, 1, 200, 182, 251, 204, 200, 63, 1, 248, 213, 200, 63, 1, 231, 219, + 200, 63, 1, 231, 220, 231, 196, 200, 63, 1, 238, 2, 200, 63, 1, 236, 141, + 238, 3, 206, 182, 200, 63, 1, 229, 247, 200, 63, 1, 193, 133, 200, 63, 1, + 191, 113, 200, 63, 1, 229, 186, 200, 63, 1, 199, 69, 200, 63, 1, 199, 70, + 231, 196, 200, 63, 1, 191, 208, 200, 63, 1, 191, 209, 229, 247, 200, 63, + 1, 222, 77, 200, 63, 1, 220, 36, 200, 63, 1, 216, 48, 200, 63, 1, 212, + 132, 200, 63, 1, 204, 19, 200, 63, 1, 53, 204, 19, 200, 63, 1, 71, 200, + 63, 1, 210, 65, 200, 63, 1, 207, 19, 210, 65, 200, 63, 1, 205, 190, 200, + 63, 1, 208, 85, 200, 63, 1, 206, 182, 200, 63, 1, 203, 70, 200, 63, 1, + 199, 159, 200, 63, 1, 209, 254, 248, 196, 200, 63, 1, 209, 254, 231, 86, + 200, 63, 1, 209, 254, 237, 65, 200, 63, 208, 168, 58, 200, 63, 208, 168, + 60, 200, 63, 208, 168, 235, 139, 200, 63, 191, 0, 58, 200, 63, 191, 0, + 60, 200, 63, 191, 0, 235, 139, 200, 63, 207, 118, 58, 200, 63, 207, 118, + 60, 200, 63, 235, 140, 191, 9, 228, 242, 200, 63, 235, 140, 191, 9, 251, + 110, 200, 63, 229, 252, 58, 200, 63, 229, 252, 60, 200, 63, 229, 251, + 235, 139, 200, 63, 234, 18, 58, 200, 63, 234, 18, 60, 200, 63, 206, 25, + 200, 63, 233, 42, 236, 142, 200, 63, 207, 248, 200, 63, 206, 55, 200, 63, + 105, 81, 185, 58, 200, 63, 105, 81, 185, 60, 200, 63, 115, 185, 58, 200, + 63, 115, 185, 60, 200, 63, 211, 174, 219, 115, 58, 200, 63, 211, 174, + 219, 115, 60, 200, 63, 215, 98, 200, 63, 249, 81, 200, 63, 1, 202, 29, + 191, 69, 200, 63, 1, 202, 29, 221, 203, 200, 63, 1, 202, 29, 233, 61, 9, + 1, 248, 248, 4, 115, 185, 228, 192, 60, 9, 1, 248, 248, 4, 75, 248, 235, + 23, 115, 185, 58, 9, 1, 248, 248, 4, 115, 185, 209, 60, 196, 66, 60, 9, + 1, 248, 248, 4, 115, 185, 209, 60, 196, 66, 248, 235, 23, 105, 185, 58, + 9, 1, 248, 248, 4, 105, 185, 248, 235, 23, 75, 58, 9, 1, 248, 248, 4, + 223, 95, 2, 196, 13, 60, 9, 1, 248, 248, 4, 2, 196, 12, 9, 1, 183, 4, + 105, 185, 58, 9, 1, 183, 4, 115, 185, 209, 60, 196, 66, 60, 9, 1, 238, 6, + 4, 105, 185, 195, 85, 248, 235, 23, 2, 199, 219, 9, 1, 238, 6, 4, 223, + 95, 2, 196, 13, 60, 9, 1, 207, 73, 4, 106, 9, 1, 205, 48, 4, 232, 130, + 185, 58, 9, 1, 251, 233, 4, 105, 185, 58, 9, 1, 251, 233, 4, 115, 185, + 209, 60, 235, 121, 58, 9, 1, 251, 233, 4, 105, 185, 195, 85, 58, 9, 1, + 233, 49, 4, 105, 185, 60, 9, 1, 233, 49, 4, 115, 185, 209, 60, 196, 66, + 60, 9, 1, 222, 7, 4, 75, 58, 9, 1, 222, 7, 4, 115, 185, 58, 9, 1, 222, 7, + 4, 115, 185, 209, 60, 196, 66, 60, 9, 1, 92, 4, 75, 58, 9, 1, 92, 4, 75, + 60, 9, 1, 213, 27, 4, 105, 185, 60, 9, 1, 213, 27, 4, 2, 199, 219, 9, 1, + 213, 27, 4, 2, 196, 12, 9, 1, 220, 38, 4, 164, 9, 1, 207, 73, 4, 105, + 185, 195, 85, 58, 9, 1, 207, 73, 4, 230, 60, 58, 9, 1, 205, 48, 4, 105, + 185, 195, 85, 58, 9, 1, 183, 4, 2, 9, 1, 199, 220, 60, 9, 1, 183, 4, 2, + 9, 1, 199, 220, 23, 105, 236, 140, 9, 1, 205, 48, 4, 2, 9, 1, 199, 220, + 23, 105, 236, 140, 9, 1, 207, 73, 4, 2, 9, 1, 199, 220, 23, 105, 236, + 140, 9, 1, 183, 4, 2, 9, 1, 199, 220, 58, 9, 1, 131, 4, 233, 207, 251, + 30, 17, 105, 58, 9, 1, 131, 4, 233, 207, 251, 30, 17, 115, 58, 9, 1, 233, + 76, 99, 4, 233, 207, 251, 30, 17, 105, 58, 9, 1, 233, 76, 99, 4, 233, + 207, 251, 30, 17, 115, 58, 9, 1, 233, 76, 99, 4, 233, 207, 251, 30, 17, + 232, 130, 60, 9, 1, 193, 134, 4, 233, 207, 251, 30, 17, 105, 58, 9, 1, + 193, 134, 4, 233, 207, 251, 30, 17, 115, 58, 9, 1, 99, 249, 83, 4, 233, + 207, 251, 30, 17, 105, 58, 9, 1, 99, 249, 83, 4, 233, 207, 251, 30, 17, + 115, 58, 9, 1, 183, 4, 233, 207, 251, 30, 17, 232, 130, 60, 9, 1, 205, + 48, 4, 233, 207, 251, 30, 17, 232, 130, 58, 9, 1, 205, 48, 4, 223, 95, + 196, 12, 9, 1, 222, 109, 4, 105, 185, 58, 199, 46, 1, 230, 93, 199, 46, + 1, 203, 120, 199, 46, 1, 213, 25, 199, 46, 1, 207, 180, 199, 46, 1, 249, + 153, 199, 46, 1, 219, 158, 199, 46, 1, 222, 124, 199, 46, 1, 251, 181, + 199, 46, 1, 195, 186, 199, 46, 1, 216, 209, 199, 46, 1, 233, 109, 199, + 46, 1, 237, 68, 199, 46, 1, 199, 48, 199, 46, 1, 220, 124, 199, 46, 1, + 231, 238, 199, 46, 1, 231, 8, 199, 46, 1, 205, 46, 199, 46, 1, 237, 209, + 199, 46, 1, 191, 94, 199, 46, 1, 199, 161, 199, 46, 1, 192, 140, 199, 46, + 1, 210, 79, 199, 46, 1, 223, 17, 199, 46, 1, 243, 132, 199, 46, 1, 197, + 131, 199, 46, 1, 229, 178, 199, 46, 1, 221, 216, 199, 46, 1, 199, 47, + 199, 46, 1, 191, 121, 199, 46, 1, 203, 109, 199, 46, 1, 205, 197, 199, + 46, 1, 238, 32, 199, 46, 1, 159, 199, 46, 1, 191, 7, 199, 46, 1, 251, + 229, 199, 46, 1, 231, 87, 199, 46, 1, 208, 95, 199, 46, 1, 193, 178, 199, + 46, 252, 72, 199, 46, 252, 173, 199, 46, 228, 31, 199, 46, 234, 189, 199, + 46, 196, 161, 199, 46, 211, 88, 199, 46, 234, 200, 199, 46, 233, 197, + 199, 46, 211, 173, 199, 46, 211, 183, 199, 46, 200, 206, 199, 46, 1, 214, + 252, 213, 109, 17, 191, 77, 213, 109, 17, 107, 213, 109, 17, 109, 213, + 109, 17, 138, 213, 109, 17, 134, 213, 109, 17, 150, 213, 109, 17, 169, + 213, 109, 17, 175, 213, 109, 17, 171, 213, 109, 17, 178, 213, 109, 1, 65, + 213, 109, 1, 234, 190, 213, 109, 1, 68, 213, 109, 1, 71, 213, 109, 1, 66, + 213, 109, 1, 211, 89, 213, 109, 1, 74, 213, 109, 1, 238, 20, 213, 109, 1, + 215, 63, 213, 109, 1, 249, 155, 213, 109, 1, 168, 213, 109, 1, 190, 190, + 213, 109, 1, 223, 34, 213, 109, 1, 247, 3, 213, 109, 1, 238, 34, 213, + 109, 1, 165, 213, 109, 1, 206, 110, 213, 109, 1, 188, 213, 109, 1, 231, + 184, 213, 109, 1, 233, 111, 213, 109, 1, 155, 213, 109, 1, 173, 213, 109, + 1, 215, 9, 193, 37, 213, 109, 1, 174, 213, 109, 1, 212, 103, 213, 109, 1, + 181, 213, 109, 1, 140, 213, 109, 1, 193, 190, 213, 109, 1, 170, 213, 109, + 1, 212, 104, 193, 37, 213, 109, 1, 222, 195, 223, 34, 213, 109, 1, 222, + 195, 247, 3, 213, 109, 1, 222, 195, 165, 213, 109, 33, 203, 41, 137, 198, + 79, 213, 109, 33, 203, 41, 130, 198, 79, 213, 109, 33, 203, 41, 206, 181, + 198, 79, 213, 109, 33, 180, 237, 88, 198, 79, 213, 109, 33, 180, 137, + 198, 79, 213, 109, 33, 180, 130, 198, 79, 213, 109, 33, 180, 206, 181, + 198, 79, 213, 109, 33, 214, 215, 77, 213, 109, 33, 55, 75, 58, 213, 109, + 137, 163, 251, 51, 213, 109, 130, 163, 251, 51, 213, 109, 16, 211, 90, + 237, 103, 213, 109, 16, 231, 183, 213, 109, 242, 76, 213, 109, 233, 218, + 77, 213, 109, 220, 96, 213, 109, 237, 235, 213, 109, 236, 144, 56, 213, + 109, 199, 195, 56, 205, 152, 1, 251, 206, 205, 152, 1, 248, 150, 205, + 152, 1, 231, 218, 205, 152, 1, 238, 4, 205, 152, 1, 223, 46, 205, 152, 1, + 249, 153, 205, 152, 1, 191, 80, 205, 152, 1, 223, 55, 205, 152, 1, 198, + 125, 205, 152, 1, 191, 189, 205, 152, 1, 222, 125, 205, 152, 1, 220, 120, + 205, 152, 1, 216, 48, 205, 152, 1, 212, 132, 205, 152, 1, 202, 172, 205, + 152, 1, 223, 164, 205, 152, 1, 233, 25, 205, 152, 1, 197, 166, 205, 152, + 1, 208, 12, 205, 152, 1, 206, 182, 205, 152, 1, 203, 139, 205, 152, 1, + 199, 243, 205, 152, 87, 223, 164, 205, 152, 87, 223, 163, 205, 152, 87, + 211, 167, 205, 152, 87, 238, 18, 205, 152, 52, 1, 234, 54, 191, 189, 205, + 152, 87, 234, 54, 191, 189, 205, 152, 18, 3, 180, 71, 205, 152, 18, 3, + 71, 205, 152, 18, 3, 210, 255, 252, 208, 205, 152, 18, 3, 180, 252, 208, + 205, 152, 18, 3, 252, 208, 205, 152, 18, 3, 210, 255, 65, 205, 152, 18, + 3, 180, 65, 205, 152, 18, 3, 65, 205, 152, 52, 1, 203, 41, 65, 205, 152, + 18, 3, 203, 41, 65, 205, 152, 18, 3, 180, 66, 205, 152, 18, 3, 66, 205, + 152, 52, 1, 68, 205, 152, 18, 3, 180, 68, 205, 152, 18, 3, 68, 205, 152, + 18, 3, 74, 205, 152, 18, 3, 200, 206, 205, 152, 87, 214, 95, 205, 152, + 208, 154, 214, 95, 205, 152, 208, 154, 252, 1, 205, 152, 208, 154, 251, + 123, 205, 152, 208, 154, 249, 59, 205, 152, 208, 154, 250, 176, 205, 152, + 208, 154, 203, 58, 205, 152, 252, 70, 77, 205, 152, 208, 154, 216, 199, + 208, 50, 205, 152, 208, 154, 191, 16, 205, 152, 208, 154, 208, 50, 205, + 152, 208, 154, 191, 119, 205, 152, 208, 154, 197, 54, 205, 152, 208, 154, + 251, 1, 205, 152, 208, 154, 202, 34, 217, 39, 205, 152, 208, 154, 251, + 99, 217, 88, 1, 230, 67, 217, 88, 1, 252, 157, 217, 88, 1, 251, 255, 217, + 88, 1, 252, 44, 217, 88, 1, 251, 247, 217, 88, 1, 196, 36, 217, 88, 1, + 250, 125, 217, 88, 1, 223, 55, 217, 88, 1, 250, 173, 217, 88, 1, 251, + 213, 217, 88, 1, 251, 218, 217, 88, 1, 251, 209, 217, 88, 1, 251, 151, + 217, 88, 1, 251, 134, 217, 88, 1, 250, 221, 217, 88, 1, 223, 164, 217, + 88, 1, 251, 67, 217, 88, 1, 250, 186, 217, 88, 1, 251, 39, 217, 88, 1, + 251, 35, 217, 88, 1, 250, 211, 217, 88, 1, 250, 184, 217, 88, 1, 235, 64, + 217, 88, 1, 222, 116, 217, 88, 1, 251, 232, 217, 88, 252, 5, 77, 217, 88, + 195, 22, 77, 217, 88, 231, 155, 77, 217, 88, 208, 153, 200, 63, 1, 142, + 214, 70, 200, 63, 1, 142, 223, 34, 200, 63, 1, 142, 212, 103, 200, 63, 1, + 142, 197, 132, 200, 63, 1, 142, 213, 81, 200, 63, 1, 142, 213, 63, 200, + 63, 1, 142, 248, 205, 200, 63, 1, 142, 165, 200, 63, 1, 142, 219, 75, + 200, 63, 1, 142, 219, 64, 200, 63, 1, 142, 201, 176, 9, 1, 131, 4, 250, + 172, 233, 72, 9, 1, 131, 4, 250, 172, 198, 54, 50, 233, 72, 9, 1, 131, 4, + 50, 82, 106, 9, 1, 131, 4, 45, 82, 106, 9, 1, 131, 4, 250, 172, 222, 54, + 9, 1, 131, 4, 250, 172, 248, 79, 50, 222, 54, 9, 1, 131, 4, 250, 172, + 206, 116, 75, 58, 9, 1, 131, 4, 250, 172, 50, 206, 116, 236, 142, 9, 1, + 131, 4, 250, 172, 45, 206, 116, 236, 142, 9, 1, 131, 4, 250, 172, 206, + 116, 75, 60, 9, 1, 131, 4, 75, 58, 9, 1, 131, 4, 250, 172, 198, 54, 50, + 233, 73, 23, 75, 58, 9, 1, 131, 4, 50, 82, 201, 29, 23, 75, 58, 9, 1, + 131, 4, 250, 172, 248, 79, 50, 222, 55, 23, 75, 58, 9, 1, 131, 4, 250, + 172, 198, 54, 50, 233, 73, 23, 45, 206, 189, 9, 1, 131, 4, 50, 82, 201, + 29, 23, 45, 206, 189, 9, 1, 131, 4, 250, 172, 248, 79, 50, 222, 55, 23, + 45, 206, 189, 9, 1, 131, 4, 250, 172, 50, 230, 59, 9, 1, 131, 4, 250, + 172, 45, 230, 59, 9, 199, 169, 4, 210, 253, 230, 59, 9, 199, 169, 4, 210, + 253, 193, 133, 9, 199, 169, 4, 105, 185, 60, 9, 1, 199, 4, 192, 75, 9, + 249, 74, 206, 116, 236, 142, 9, 207, 149, 206, 116, 236, 142, 9, 1, 213, + 27, 4, 223, 95, 2, 196, 12, 9, 1, 183, 4, 223, 95, 2, 196, 13, 60, 9, 1, + 199, 220, 4, 75, 60, 9, 1, 199, 220, 4, 115, 185, 60, 9, 1, 222, 7, 4, + 105, 185, 195, 85, 60, 9, 81, 199, 215, 9, 209, 10, 87, 58, 9, 209, 184, + 87, 58, 9, 2, 137, 193, 23, 251, 208, 9, 2, 130, 193, 23, 223, 63, 9, 2, + 130, 193, 23, 223, 181, 9, 2, 130, 193, 23, 199, 173, 9, 217, 144, 193, + 179, 9, 200, 182, 131, 215, 236, 9, 235, 130, 217, 143, 9, 132, 217, 144, + 139, 217, 143, 9, 1, 248, 248, 4, 2, 196, 13, 60, 9, 1, 248, 248, 4, 230, + 60, 58, 9, 1, 223, 9, 4, 105, 185, 58, 9, 1, 199, 220, 4, 105, 185, 58, + 9, 1, 233, 49, 4, 75, 248, 235, 23, 115, 185, 58, 9, 1, 208, 92, 4, 75, + 60, 9, 1, 220, 38, 4, 55, 164, 9, 1, 92, 4, 115, 185, 58, 9, 1, 99, 4, + 105, 185, 248, 235, 23, 230, 60, 58, 9, 1, 99, 4, 105, 185, 248, 235, 23, + 75, 58, 9, 1, 207, 73, 4, 219, 6, 9, 1, 193, 134, 4, 75, 193, 52, 9, 1, + 206, 143, 192, 75, 9, 1, 130, 251, 194, 9, 1, 238, 6, 4, 115, 185, 60, 9, + 1, 205, 194, 4, 115, 185, 60, 9, 1, 231, 230, 4, 223, 95, 106, 9, 1, 201, + 54, 193, 133, 9, 1, 191, 114, 4, 223, 95, 196, 13, 58, 9, 1, 251, 233, 4, + 115, 185, 60, 9, 1, 222, 109, 4, 75, 60, 9, 1, 208, 92, 4, 75, 248, 235, + 23, 213, 46, 185, 58, 9, 1, 248, 248, 4, 2, 92, 58, 9, 1, 210, 44, 4, 2, + 92, 58, 9, 1, 199, 115, 4, 2, 199, 115, 58, 9, 1, 207, 73, 4, 2, 213, 27, + 58, 9, 1, 99, 4, 105, 185, 248, 235, 23, 2, 213, 27, 58, 9, 1, 252, 2, + 233, 48, 9, 1, 252, 2, 208, 91, 9, 1, 252, 2, 213, 26, 9, 1, 210, 44, 4, + 2, 196, 12, 9, 1, 199, 115, 4, 2, 196, 12, 9, 1, 197, 125, 4, 2, 196, 12, + 9, 1, 199, 150, 4, 2, 196, 12, 9, 1, 222, 7, 4, 2, 196, 12, 9, 1, 231, + 89, 4, 115, 185, 58, 9, 1, 252, 2, 208, 92, 4, 115, 185, 58, 9, 1, 223, + 9, 4, 115, 185, 58, 9, 1, 223, 9, 4, 115, 185, 60, 9, 1, 220, 38, 4, 2, + 9, 1, 199, 220, 58, 9, 1, 230, 226, 9, 2, 233, 76, 192, 75, 9, 2, 137, + 233, 76, 192, 75, 9, 2, 137, 99, 249, 83, 4, 105, 185, 60, 9, 2, 137, + 193, 23, 205, 183, 9, 2, 137, 191, 116, 9, 220, 15, 206, 116, 75, 58, 9, + 220, 15, 206, 116, 75, 60, 9, 200, 207, 60, 9, 220, 15, 243, 13, 60, 9, + 220, 15, 206, 116, 75, 223, 120, 243, 13, 60, 9, 2, 130, 193, 133, 9, 2, + 137, 193, 23, 251, 32, 9, 2, 137, 205, 193, 9, 2, 137, 251, 232, 9, 2, + 137, 208, 91, 9, 2, 137, 213, 27, 4, 222, 54, 9, 2, 130, 213, 27, 4, 222, + 54, 9, 2, 137, 193, 23, 250, 183, 9, 2, 137, 193, 23, 250, 220, 9, 2, + 137, 193, 23, 251, 133, 9, 2, 137, 193, 23, 205, 172, 9, 2, 137, 193, 23, + 208, 54, 9, 2, 137, 193, 23, 193, 157, 9, 2, 137, 232, 159, 217, 53, 9, + 2, 137, 3, 205, 188, 9, 236, 220, 234, 97, 79, 250, 132, 9, 154, 237, + 248, 60, 9, 238, 173, 233, 72, 9, 238, 173, 237, 247, 9, 238, 173, 222, + 54, 9, 238, 173, 233, 70, 9, 238, 173, 237, 245, 9, 238, 173, 222, 52, 9, + 163, 91, 75, 58, 9, 163, 105, 185, 58, 9, 163, 219, 7, 58, 9, 163, 91, + 75, 60, 9, 163, 105, 185, 60, 9, 163, 219, 7, 60, 9, 211, 79, 233, 70, 9, + 211, 79, 237, 245, 9, 211, 79, 222, 52, 9, 2, 137, 193, 133, 9, 233, 73, + 4, 206, 189, 9, 233, 73, 4, 75, 58, 9, 222, 55, 4, 75, 60, 9, 45, 250, + 238, 58, 9, 50, 250, 238, 58, 9, 45, 250, 238, 60, 9, 50, 250, 238, 60, + 9, 55, 50, 250, 238, 58, 9, 55, 50, 250, 238, 93, 4, 236, 142, 9, 50, + 250, 238, 93, 4, 236, 142, 9, 237, 248, 4, 236, 142, 9, 87, 202, 207, + 213, 27, 231, 59, 100, 3, 223, 95, 247, 121, 100, 3, 247, 121, 100, 3, + 251, 73, 100, 3, 195, 35, 100, 1, 203, 41, 65, 100, 1, 65, 100, 1, 252, + 208, 100, 1, 68, 100, 1, 223, 201, 100, 1, 66, 100, 1, 196, 30, 100, 1, + 117, 146, 100, 1, 117, 172, 100, 1, 247, 124, 71, 100, 1, 203, 41, 71, + 100, 1, 71, 100, 1, 251, 238, 100, 1, 247, 124, 74, 100, 1, 203, 41, 74, + 100, 1, 74, 100, 1, 250, 165, 100, 1, 155, 100, 1, 221, 217, 100, 1, 231, + 242, 100, 1, 231, 93, 100, 1, 214, 70, 100, 1, 247, 162, 100, 1, 247, 3, + 100, 1, 223, 34, 100, 1, 222, 254, 100, 1, 212, 103, 100, 1, 197, 132, + 100, 1, 197, 120, 100, 1, 237, 193, 100, 1, 237, 177, 100, 1, 213, 81, + 100, 1, 190, 190, 100, 1, 199, 49, 100, 1, 238, 34, 100, 1, 237, 70, 100, + 1, 181, 100, 1, 213, 63, 100, 1, 168, 100, 1, 209, 230, 100, 1, 249, 155, + 100, 1, 248, 205, 100, 1, 174, 100, 1, 170, 100, 1, 165, 100, 1, 206, + 110, 100, 1, 173, 100, 1, 219, 75, 100, 1, 219, 64, 100, 1, 195, 188, + 100, 1, 203, 166, 100, 1, 201, 176, 100, 1, 188, 100, 1, 140, 100, 18, 3, + 211, 153, 100, 18, 3, 211, 87, 100, 3, 212, 143, 100, 3, 250, 147, 100, + 18, 3, 252, 208, 100, 18, 3, 68, 100, 18, 3, 223, 201, 100, 18, 3, 66, + 100, 18, 3, 196, 30, 100, 18, 3, 117, 146, 100, 18, 3, 117, 206, 111, + 100, 18, 3, 247, 124, 71, 100, 18, 3, 203, 41, 71, 100, 18, 3, 71, 100, + 18, 3, 251, 238, 100, 18, 3, 247, 124, 74, 100, 18, 3, 203, 41, 74, 100, + 18, 3, 74, 100, 18, 3, 250, 165, 100, 3, 195, 40, 100, 18, 3, 208, 209, + 71, 100, 18, 3, 250, 142, 100, 211, 115, 100, 201, 39, 3, 196, 154, 100, + 201, 39, 3, 251, 75, 100, 230, 213, 252, 62, 100, 252, 49, 252, 62, 100, + 18, 3, 247, 124, 180, 71, 100, 18, 3, 196, 152, 100, 18, 3, 196, 29, 100, + 1, 208, 98, 100, 1, 221, 195, 100, 1, 231, 68, 100, 1, 191, 123, 100, 1, + 237, 182, 100, 1, 207, 7, 100, 1, 233, 111, 100, 1, 191, 175, 100, 1, + 117, 206, 111, 100, 1, 117, 219, 76, 100, 18, 3, 117, 172, 100, 18, 3, + 117, 219, 76, 100, 237, 240, 100, 55, 237, 240, 100, 17, 191, 77, 100, + 17, 107, 100, 17, 109, 100, 17, 138, 100, 17, 134, 100, 17, 150, 100, 17, + 169, 100, 17, 175, 100, 17, 171, 100, 17, 178, 100, 252, 70, 56, 100, 3, + 137, 201, 247, 236, 142, 100, 1, 247, 124, 65, 100, 1, 211, 153, 100, 1, + 211, 87, 100, 1, 250, 142, 100, 1, 196, 152, 100, 1, 196, 29, 100, 1, + 217, 45, 237, 193, 100, 1, 191, 71, 100, 1, 88, 170, 100, 1, 231, 129, + 100, 1, 222, 232, 100, 1, 231, 13, 201, 64, 100, 1, 237, 183, 100, 1, + 249, 55, 248, 227, 251, 102, 248, 227, 3, 247, 121, 248, 227, 3, 251, 73, + 248, 227, 3, 195, 35, 248, 227, 1, 65, 248, 227, 1, 252, 208, 248, 227, + 1, 68, 248, 227, 1, 223, 201, 248, 227, 1, 66, 248, 227, 1, 196, 30, 248, + 227, 1, 117, 146, 248, 227, 1, 117, 172, 248, 227, 1, 71, 248, 227, 1, + 251, 238, 248, 227, 1, 74, 248, 227, 1, 250, 165, 248, 227, 1, 155, 248, + 227, 1, 221, 217, 248, 227, 1, 231, 242, 248, 227, 1, 231, 93, 248, 227, + 1, 214, 70, 248, 227, 1, 247, 162, 248, 227, 1, 247, 3, 248, 227, 1, 223, + 34, 248, 227, 1, 222, 254, 248, 227, 1, 212, 103, 248, 227, 1, 197, 132, + 248, 227, 1, 197, 120, 248, 227, 1, 237, 193, 248, 227, 1, 237, 177, 248, + 227, 1, 213, 81, 248, 227, 1, 190, 190, 248, 227, 1, 199, 49, 248, 227, + 1, 238, 34, 248, 227, 1, 237, 70, 248, 227, 1, 181, 248, 227, 1, 168, + 248, 227, 1, 209, 230, 248, 227, 1, 249, 155, 248, 227, 1, 248, 205, 248, + 227, 1, 174, 248, 227, 1, 170, 248, 227, 1, 165, 248, 227, 1, 173, 248, + 227, 1, 203, 166, 248, 227, 1, 201, 176, 248, 227, 1, 188, 248, 227, 1, + 140, 248, 227, 3, 212, 143, 248, 227, 3, 250, 147, 248, 227, 18, 3, 252, + 208, 248, 227, 18, 3, 68, 248, 227, 18, 3, 223, 201, 248, 227, 18, 3, 66, + 248, 227, 18, 3, 196, 30, 248, 227, 18, 3, 117, 146, 248, 227, 18, 3, + 117, 206, 111, 248, 227, 18, 3, 71, 248, 227, 18, 3, 251, 238, 248, 227, + 18, 3, 74, 248, 227, 18, 3, 250, 165, 248, 227, 3, 195, 40, 248, 227, 1, + 221, 206, 190, 190, 248, 227, 250, 166, 219, 200, 77, 248, 227, 1, 206, + 110, 248, 227, 1, 207, 7, 248, 227, 1, 191, 175, 248, 227, 1, 117, 206, + 111, 248, 227, 1, 117, 219, 76, 248, 227, 18, 3, 117, 172, 248, 227, 18, + 3, 117, 219, 76, 248, 227, 17, 191, 77, 248, 227, 17, 107, 248, 227, 17, + 109, 248, 227, 17, 138, 248, 227, 17, 134, 248, 227, 17, 150, 248, 227, + 17, 169, 248, 227, 17, 175, 248, 227, 17, 171, 248, 227, 17, 178, 248, + 227, 1, 207, 188, 4, 82, 237, 40, 248, 227, 1, 207, 188, 4, 110, 237, 40, + 248, 227, 206, 37, 77, 248, 227, 206, 37, 56, 248, 227, 238, 172, 212, + 135, 107, 248, 227, 238, 172, 212, 135, 109, 248, 227, 238, 172, 212, + 135, 138, 248, 227, 238, 172, 212, 135, 134, 248, 227, 238, 172, 212, + 135, 91, 219, 183, 199, 39, 199, 34, 237, 101, 248, 227, 238, 172, 237, + 102, 202, 131, 248, 227, 223, 56, 248, 227, 231, 209, 77, 248, 227, 1, + 195, 150, 251, 73, 248, 227, 252, 70, 56, 248, 227, 205, 139, 77, 230, + 146, 3, 252, 43, 248, 169, 230, 146, 3, 248, 169, 230, 146, 3, 195, 35, + 230, 146, 1, 65, 230, 146, 1, 252, 208, 230, 146, 1, 68, 230, 146, 1, + 223, 201, 230, 146, 1, 66, 230, 146, 1, 196, 30, 230, 146, 1, 234, 190, + 230, 146, 1, 251, 238, 230, 146, 1, 211, 89, 230, 146, 1, 250, 165, 230, + 146, 1, 155, 230, 146, 1, 221, 217, 230, 146, 1, 231, 242, 230, 146, 1, + 231, 93, 230, 146, 1, 214, 70, 230, 146, 1, 247, 162, 230, 146, 1, 247, + 3, 230, 146, 1, 223, 34, 230, 146, 1, 222, 254, 230, 146, 1, 212, 103, + 230, 146, 1, 197, 132, 230, 146, 1, 197, 120, 230, 146, 1, 237, 193, 230, + 146, 1, 237, 177, 230, 146, 1, 213, 81, 230, 146, 1, 190, 190, 230, 146, + 1, 199, 49, 230, 146, 1, 238, 34, 230, 146, 1, 237, 70, 230, 146, 1, 181, + 230, 146, 1, 168, 230, 146, 1, 209, 230, 230, 146, 1, 249, 155, 230, 146, + 1, 248, 205, 230, 146, 1, 174, 230, 146, 1, 170, 230, 146, 1, 165, 230, + 146, 1, 173, 230, 146, 1, 219, 75, 230, 146, 1, 195, 188, 230, 146, 1, + 203, 166, 230, 146, 1, 188, 230, 146, 1, 140, 230, 146, 3, 212, 143, 230, + 146, 18, 3, 252, 208, 230, 146, 18, 3, 68, 230, 146, 18, 3, 223, 201, + 230, 146, 18, 3, 66, 230, 146, 18, 3, 196, 30, 230, 146, 18, 3, 234, 190, + 230, 146, 18, 3, 251, 238, 230, 146, 18, 3, 211, 89, 230, 146, 18, 3, + 250, 165, 230, 146, 3, 195, 40, 230, 146, 3, 196, 157, 230, 146, 1, 221, + 195, 230, 146, 1, 231, 68, 230, 146, 1, 191, 123, 230, 146, 1, 206, 110, + 230, 146, 1, 233, 111, 230, 146, 17, 191, 77, 230, 146, 17, 107, 230, + 146, 17, 109, 230, 146, 17, 138, 230, 146, 17, 134, 230, 146, 17, 150, + 230, 146, 17, 169, 230, 146, 17, 175, 230, 146, 17, 171, 230, 146, 17, + 178, 230, 146, 198, 133, 230, 146, 252, 42, 230, 146, 223, 77, 230, 146, + 196, 58, 230, 146, 234, 150, 211, 94, 230, 146, 3, 192, 115, 230, 146, + 252, 70, 56, 230, 163, 3, 247, 121, 230, 163, 3, 251, 73, 230, 163, 3, + 195, 35, 230, 163, 1, 65, 230, 163, 1, 252, 208, 230, 163, 1, 68, 230, + 163, 1, 223, 201, 230, 163, 1, 66, 230, 163, 1, 196, 30, 230, 163, 1, + 117, 146, 230, 163, 1, 117, 172, 230, 163, 18, 247, 124, 71, 230, 163, 1, + 71, 230, 163, 1, 251, 238, 230, 163, 18, 247, 124, 74, 230, 163, 1, 74, + 230, 163, 1, 250, 165, 230, 163, 1, 155, 230, 163, 1, 221, 217, 230, 163, + 1, 231, 242, 230, 163, 1, 231, 93, 230, 163, 1, 214, 70, 230, 163, 1, + 247, 162, 230, 163, 1, 247, 3, 230, 163, 1, 223, 34, 230, 163, 1, 222, + 254, 230, 163, 1, 212, 103, 230, 163, 1, 197, 132, 230, 163, 1, 197, 120, + 230, 163, 1, 237, 193, 230, 163, 1, 237, 177, 230, 163, 1, 213, 81, 230, + 163, 1, 190, 190, 230, 163, 1, 199, 49, 230, 163, 1, 238, 34, 230, 163, + 1, 237, 70, 230, 163, 1, 181, 230, 163, 1, 168, 230, 163, 1, 209, 230, + 230, 163, 1, 249, 155, 230, 163, 1, 248, 205, 230, 163, 1, 174, 230, 163, + 1, 170, 230, 163, 1, 165, 230, 163, 1, 173, 230, 163, 1, 219, 75, 230, + 163, 1, 195, 188, 230, 163, 1, 203, 166, 230, 163, 1, 201, 176, 230, 163, + 1, 188, 230, 163, 1, 140, 230, 163, 3, 212, 143, 230, 163, 3, 250, 147, + 230, 163, 18, 3, 252, 208, 230, 163, 18, 3, 68, 230, 163, 18, 3, 223, + 201, 230, 163, 18, 3, 66, 230, 163, 18, 3, 196, 30, 230, 163, 18, 3, 117, + 146, 230, 163, 18, 3, 117, 206, 111, 230, 163, 18, 3, 247, 124, 71, 230, + 163, 18, 3, 71, 230, 163, 18, 3, 251, 238, 230, 163, 18, 3, 247, 124, 74, + 230, 163, 18, 3, 74, 230, 163, 18, 3, 250, 165, 230, 163, 3, 195, 40, + 230, 163, 211, 115, 230, 163, 1, 117, 206, 111, 230, 163, 1, 117, 219, + 76, 230, 163, 18, 3, 117, 172, 230, 163, 18, 3, 117, 219, 76, 230, 163, + 17, 191, 77, 230, 163, 17, 107, 230, 163, 17, 109, 230, 163, 17, 138, + 230, 163, 17, 134, 230, 163, 17, 150, 230, 163, 17, 169, 230, 163, 17, + 175, 230, 163, 17, 171, 230, 163, 17, 178, 230, 163, 252, 70, 56, 230, + 163, 206, 37, 56, 230, 163, 1, 191, 71, 230, 163, 3, 200, 206, 230, 163, + 3, 203, 156, 230, 163, 3, 217, 141, 230, 163, 3, 198, 224, 212, 144, 58, + 230, 163, 3, 243, 13, 212, 144, 58, 230, 163, 3, 197, 15, 212, 144, 58, + 211, 47, 3, 247, 121, 211, 47, 3, 251, 73, 211, 47, 3, 195, 35, 211, 47, + 1, 65, 211, 47, 1, 252, 208, 211, 47, 1, 68, 211, 47, 1, 223, 201, 211, + 47, 1, 66, 211, 47, 1, 196, 30, 211, 47, 1, 117, 146, 211, 47, 1, 117, + 172, 211, 47, 1, 71, 211, 47, 1, 251, 238, 211, 47, 1, 74, 211, 47, 1, + 250, 165, 211, 47, 1, 155, 211, 47, 1, 221, 217, 211, 47, 1, 231, 242, + 211, 47, 1, 231, 93, 211, 47, 1, 214, 70, 211, 47, 1, 247, 162, 211, 47, + 1, 247, 3, 211, 47, 1, 223, 34, 211, 47, 1, 222, 254, 211, 47, 1, 212, + 103, 211, 47, 1, 197, 132, 211, 47, 1, 197, 120, 211, 47, 1, 237, 193, + 211, 47, 1, 237, 177, 211, 47, 1, 213, 81, 211, 47, 1, 190, 190, 211, 47, + 1, 199, 49, 211, 47, 1, 238, 34, 211, 47, 1, 237, 70, 211, 47, 1, 181, + 211, 47, 1, 168, 211, 47, 1, 209, 230, 211, 47, 1, 249, 155, 211, 47, 1, + 248, 205, 211, 47, 1, 174, 211, 47, 1, 170, 211, 47, 1, 165, 211, 47, 1, + 173, 211, 47, 1, 219, 75, 211, 47, 1, 195, 188, 211, 47, 1, 203, 166, + 211, 47, 1, 201, 176, 211, 47, 1, 188, 211, 47, 1, 140, 211, 47, 3, 212, + 143, 211, 47, 3, 250, 147, 211, 47, 18, 3, 252, 208, 211, 47, 18, 3, 68, + 211, 47, 18, 3, 223, 201, 211, 47, 18, 3, 66, 211, 47, 18, 3, 196, 30, + 211, 47, 18, 3, 117, 146, 211, 47, 18, 3, 117, 206, 111, 211, 47, 18, 3, + 71, 211, 47, 18, 3, 251, 238, 211, 47, 18, 3, 74, 211, 47, 18, 3, 250, + 165, 211, 47, 3, 195, 40, 211, 47, 3, 211, 0, 211, 47, 251, 239, 219, + 200, 77, 211, 47, 250, 166, 219, 200, 77, 211, 47, 1, 206, 110, 211, 47, + 1, 207, 7, 211, 47, 1, 191, 175, 211, 47, 1, 117, 206, 111, 211, 47, 1, + 117, 219, 76, 211, 47, 18, 3, 117, 172, 211, 47, 18, 3, 117, 219, 76, + 211, 47, 17, 191, 77, 211, 47, 17, 107, 211, 47, 17, 109, 211, 47, 17, + 138, 211, 47, 17, 134, 211, 47, 17, 150, 211, 47, 17, 169, 211, 47, 17, + 175, 211, 47, 17, 171, 211, 47, 17, 178, 211, 47, 223, 56, 211, 47, 1, + 193, 190, 211, 47, 232, 120, 91, 208, 24, 211, 47, 232, 120, 91, 230, 72, + 211, 47, 232, 120, 115, 208, 22, 211, 47, 232, 120, 91, 202, 129, 211, + 47, 232, 120, 91, 234, 161, 211, 47, 232, 120, 115, 202, 126, 44, 3, 251, + 73, 44, 3, 195, 35, 44, 1, 65, 44, 1, 252, 208, 44, 1, 68, 44, 1, 223, + 201, 44, 1, 66, 44, 1, 196, 30, 44, 1, 71, 44, 1, 234, 190, 44, 1, 251, + 238, 44, 1, 74, 44, 1, 211, 89, 44, 1, 250, 165, 44, 1, 155, 44, 1, 214, + 70, 44, 1, 247, 162, 44, 1, 223, 34, 44, 1, 212, 103, 44, 1, 197, 132, + 44, 1, 213, 81, 44, 1, 190, 190, 44, 1, 181, 44, 1, 213, 63, 44, 1, 168, + 44, 1, 174, 44, 1, 170, 44, 1, 165, 44, 1, 206, 110, 44, 1, 173, 44, 1, + 219, 75, 44, 1, 219, 64, 44, 1, 195, 188, 44, 1, 203, 166, 44, 1, 201, + 176, 44, 1, 188, 44, 1, 140, 44, 18, 3, 252, 208, 44, 18, 3, 68, 44, 18, + 3, 223, 201, 44, 18, 3, 66, 44, 18, 3, 196, 30, 44, 18, 3, 71, 44, 18, 3, + 234, 190, 44, 18, 3, 251, 238, 44, 18, 3, 74, 44, 18, 3, 211, 89, 44, 18, + 3, 250, 165, 44, 3, 195, 40, 44, 211, 115, 44, 250, 166, 219, 200, 77, 44, 17, 191, 77, 44, 17, 107, 44, 17, 109, 44, 17, 138, 44, 17, 134, 44, - 17, 149, 44, 17, 169, 44, 17, 175, 44, 17, 171, 44, 17, 178, 44, 31, 199, - 95, 44, 31, 91, 228, 140, 44, 31, 91, 189, 44, 237, 204, 56, 44, 215, - 214, 56, 44, 192, 78, 56, 44, 237, 142, 56, 44, 238, 230, 56, 44, 250, - 220, 93, 56, 44, 206, 36, 56, 44, 31, 56, 199, 99, 3, 33, 247, 120, 58, - 199, 99, 3, 247, 119, 199, 99, 3, 251, 71, 199, 99, 3, 195, 35, 199, 99, - 3, 33, 251, 72, 58, 199, 99, 1, 65, 199, 99, 1, 252, 206, 199, 99, 1, 68, - 199, 99, 1, 223, 199, 199, 99, 1, 66, 199, 99, 1, 196, 30, 199, 99, 1, - 117, 146, 199, 99, 1, 117, 172, 199, 99, 1, 71, 199, 99, 1, 234, 188, - 199, 99, 1, 251, 236, 199, 99, 1, 74, 199, 99, 1, 211, 87, 199, 99, 1, - 250, 163, 199, 99, 1, 155, 199, 99, 1, 221, 215, 199, 99, 1, 231, 240, - 199, 99, 1, 231, 91, 199, 99, 1, 214, 68, 199, 99, 1, 247, 160, 199, 99, - 1, 247, 1, 199, 99, 1, 223, 32, 199, 99, 1, 222, 252, 199, 99, 1, 212, - 101, 199, 99, 1, 197, 132, 199, 99, 1, 197, 120, 199, 99, 1, 237, 191, - 199, 99, 1, 237, 175, 199, 99, 1, 213, 79, 199, 99, 1, 190, 190, 199, 99, - 1, 199, 49, 199, 99, 1, 238, 32, 199, 99, 1, 237, 68, 199, 99, 1, 180, - 199, 99, 1, 168, 199, 99, 1, 209, 228, 199, 99, 1, 249, 153, 199, 99, 1, - 248, 203, 199, 99, 1, 174, 199, 99, 1, 170, 199, 99, 1, 165, 199, 99, 1, - 206, 109, 199, 99, 1, 173, 199, 99, 1, 219, 73, 199, 99, 1, 219, 62, 199, - 99, 1, 195, 188, 199, 99, 1, 203, 165, 199, 99, 1, 201, 175, 199, 99, 1, - 188, 199, 99, 1, 140, 199, 99, 3, 212, 141, 199, 99, 3, 250, 145, 199, - 99, 18, 3, 252, 206, 199, 99, 18, 3, 68, 199, 99, 18, 3, 223, 199, 199, + 17, 150, 44, 17, 169, 44, 17, 175, 44, 17, 171, 44, 17, 178, 44, 31, 199, + 95, 44, 31, 91, 228, 142, 44, 31, 91, 189, 44, 237, 206, 56, 44, 215, + 216, 56, 44, 192, 78, 56, 44, 237, 144, 56, 44, 238, 232, 56, 44, 250, + 222, 93, 56, 44, 206, 37, 56, 44, 31, 56, 199, 99, 3, 33, 247, 122, 58, + 199, 99, 3, 247, 121, 199, 99, 3, 251, 73, 199, 99, 3, 195, 35, 199, 99, + 3, 33, 251, 74, 58, 199, 99, 1, 65, 199, 99, 1, 252, 208, 199, 99, 1, 68, + 199, 99, 1, 223, 201, 199, 99, 1, 66, 199, 99, 1, 196, 30, 199, 99, 1, + 117, 146, 199, 99, 1, 117, 172, 199, 99, 1, 71, 199, 99, 1, 234, 190, + 199, 99, 1, 251, 238, 199, 99, 1, 74, 199, 99, 1, 211, 89, 199, 99, 1, + 250, 165, 199, 99, 1, 155, 199, 99, 1, 221, 217, 199, 99, 1, 231, 242, + 199, 99, 1, 231, 93, 199, 99, 1, 214, 70, 199, 99, 1, 247, 162, 199, 99, + 1, 247, 3, 199, 99, 1, 223, 34, 199, 99, 1, 222, 254, 199, 99, 1, 212, + 103, 199, 99, 1, 197, 132, 199, 99, 1, 197, 120, 199, 99, 1, 237, 193, + 199, 99, 1, 237, 177, 199, 99, 1, 213, 81, 199, 99, 1, 190, 190, 199, 99, + 1, 199, 49, 199, 99, 1, 238, 34, 199, 99, 1, 237, 70, 199, 99, 1, 181, + 199, 99, 1, 168, 199, 99, 1, 209, 230, 199, 99, 1, 249, 155, 199, 99, 1, + 248, 205, 199, 99, 1, 174, 199, 99, 1, 170, 199, 99, 1, 165, 199, 99, 1, + 206, 110, 199, 99, 1, 173, 199, 99, 1, 219, 75, 199, 99, 1, 219, 64, 199, + 99, 1, 195, 188, 199, 99, 1, 203, 166, 199, 99, 1, 201, 176, 199, 99, 1, + 188, 199, 99, 1, 140, 199, 99, 3, 212, 143, 199, 99, 3, 250, 147, 199, + 99, 18, 3, 252, 208, 199, 99, 18, 3, 68, 199, 99, 18, 3, 223, 201, 199, 99, 18, 3, 66, 199, 99, 18, 3, 196, 30, 199, 99, 18, 3, 117, 146, 199, - 99, 18, 3, 117, 206, 110, 199, 99, 18, 3, 71, 199, 99, 18, 3, 234, 188, - 199, 99, 18, 3, 251, 236, 199, 99, 18, 3, 74, 199, 99, 18, 3, 211, 87, - 199, 99, 18, 3, 250, 163, 199, 99, 3, 195, 40, 199, 99, 219, 198, 77, - 199, 99, 251, 237, 219, 198, 77, 199, 99, 1, 197, 168, 199, 99, 1, 235, - 35, 199, 99, 1, 206, 90, 199, 99, 1, 214, 232, 209, 46, 199, 99, 1, 117, - 206, 110, 199, 99, 1, 117, 219, 74, 199, 99, 18, 3, 117, 172, 199, 99, - 18, 3, 117, 219, 74, 199, 99, 17, 191, 77, 199, 99, 17, 107, 199, 99, 17, - 109, 199, 99, 17, 138, 199, 99, 17, 134, 199, 99, 17, 149, 199, 99, 17, + 99, 18, 3, 117, 206, 111, 199, 99, 18, 3, 71, 199, 99, 18, 3, 234, 190, + 199, 99, 18, 3, 251, 238, 199, 99, 18, 3, 74, 199, 99, 18, 3, 211, 89, + 199, 99, 18, 3, 250, 165, 199, 99, 3, 195, 40, 199, 99, 219, 200, 77, + 199, 99, 251, 239, 219, 200, 77, 199, 99, 1, 197, 168, 199, 99, 1, 235, + 37, 199, 99, 1, 206, 91, 199, 99, 1, 214, 234, 209, 48, 199, 99, 1, 117, + 206, 111, 199, 99, 1, 117, 219, 76, 199, 99, 18, 3, 117, 172, 199, 99, + 18, 3, 117, 219, 76, 199, 99, 17, 191, 77, 199, 99, 17, 107, 199, 99, 17, + 109, 199, 99, 17, 138, 199, 99, 17, 134, 199, 99, 17, 150, 199, 99, 17, 169, 199, 99, 17, 175, 199, 99, 17, 171, 199, 99, 17, 178, 199, 99, 3, - 202, 210, 199, 99, 232, 118, 17, 191, 78, 40, 211, 155, 208, 253, 79, - 134, 199, 99, 232, 118, 17, 91, 40, 211, 155, 208, 253, 79, 134, 199, 99, - 232, 118, 17, 105, 40, 211, 155, 208, 253, 79, 134, 199, 99, 232, 118, - 17, 115, 40, 211, 155, 208, 253, 79, 134, 199, 99, 232, 118, 17, 91, 40, - 233, 229, 208, 253, 79, 134, 199, 99, 232, 118, 17, 105, 40, 233, 229, - 208, 253, 79, 134, 199, 99, 232, 118, 17, 115, 40, 233, 229, 208, 253, - 79, 134, 199, 99, 3, 197, 48, 222, 81, 3, 201, 246, 247, 119, 222, 81, 3, - 247, 119, 222, 81, 3, 251, 71, 222, 81, 3, 195, 35, 222, 81, 3, 202, 210, - 222, 81, 1, 65, 222, 81, 1, 252, 206, 222, 81, 1, 68, 222, 81, 1, 223, - 199, 222, 81, 1, 66, 222, 81, 1, 196, 30, 222, 81, 1, 117, 146, 222, 81, - 1, 117, 172, 222, 81, 1, 71, 222, 81, 1, 234, 188, 222, 81, 1, 251, 236, - 222, 81, 1, 74, 222, 81, 1, 211, 87, 222, 81, 1, 250, 163, 222, 81, 1, - 155, 222, 81, 1, 221, 215, 222, 81, 1, 231, 240, 222, 81, 1, 231, 91, - 222, 81, 1, 214, 68, 222, 81, 1, 247, 160, 222, 81, 1, 247, 1, 222, 81, - 1, 223, 32, 222, 81, 1, 222, 252, 222, 81, 1, 212, 101, 222, 81, 1, 197, - 132, 222, 81, 1, 197, 120, 222, 81, 1, 237, 191, 222, 81, 1, 237, 175, - 222, 81, 1, 213, 79, 222, 81, 1, 190, 190, 222, 81, 1, 199, 49, 222, 81, - 1, 238, 32, 222, 81, 1, 237, 68, 222, 81, 1, 180, 222, 81, 1, 168, 222, - 81, 1, 209, 228, 222, 81, 1, 249, 153, 222, 81, 1, 248, 203, 222, 81, 1, - 174, 222, 81, 1, 170, 222, 81, 1, 165, 222, 81, 1, 206, 109, 222, 81, 1, - 173, 222, 81, 1, 219, 73, 222, 81, 1, 195, 188, 222, 81, 1, 203, 165, - 222, 81, 1, 201, 175, 222, 81, 1, 188, 222, 81, 1, 140, 222, 81, 3, 212, - 141, 222, 81, 3, 250, 145, 222, 81, 18, 3, 252, 206, 222, 81, 18, 3, 68, - 222, 81, 18, 3, 223, 199, 222, 81, 18, 3, 66, 222, 81, 18, 3, 196, 30, - 222, 81, 18, 3, 117, 146, 222, 81, 18, 3, 117, 206, 110, 222, 81, 18, 3, - 71, 222, 81, 18, 3, 234, 188, 222, 81, 18, 3, 251, 236, 222, 81, 18, 3, - 74, 222, 81, 18, 3, 211, 87, 222, 81, 18, 3, 250, 163, 222, 81, 3, 195, - 40, 222, 81, 219, 198, 77, 222, 81, 251, 237, 219, 198, 77, 222, 81, 1, - 214, 232, 209, 46, 222, 81, 1, 233, 109, 222, 81, 1, 117, 206, 110, 222, - 81, 1, 117, 219, 74, 222, 81, 18, 3, 117, 172, 222, 81, 18, 3, 117, 219, - 74, 222, 81, 17, 191, 77, 222, 81, 17, 107, 222, 81, 17, 109, 222, 81, - 17, 138, 222, 81, 17, 134, 222, 81, 17, 149, 222, 81, 17, 169, 222, 81, - 17, 175, 222, 81, 17, 171, 222, 81, 17, 178, 222, 81, 3, 222, 237, 222, - 81, 3, 196, 75, 222, 81, 3, 33, 251, 72, 93, 183, 142, 3, 33, 251, 72, - 58, 142, 3, 247, 119, 142, 3, 251, 71, 142, 3, 195, 35, 142, 1, 195, 150, - 251, 71, 142, 1, 65, 142, 1, 252, 206, 142, 1, 68, 142, 1, 223, 199, 142, + 202, 211, 199, 99, 232, 120, 17, 191, 78, 40, 211, 157, 208, 255, 79, + 134, 199, 99, 232, 120, 17, 91, 40, 211, 157, 208, 255, 79, 134, 199, 99, + 232, 120, 17, 105, 40, 211, 157, 208, 255, 79, 134, 199, 99, 232, 120, + 17, 115, 40, 211, 157, 208, 255, 79, 134, 199, 99, 232, 120, 17, 91, 40, + 233, 231, 208, 255, 79, 134, 199, 99, 232, 120, 17, 105, 40, 233, 231, + 208, 255, 79, 134, 199, 99, 232, 120, 17, 115, 40, 233, 231, 208, 255, + 79, 134, 199, 99, 3, 197, 48, 222, 83, 3, 201, 247, 247, 121, 222, 83, 3, + 247, 121, 222, 83, 3, 251, 73, 222, 83, 3, 195, 35, 222, 83, 3, 202, 211, + 222, 83, 1, 65, 222, 83, 1, 252, 208, 222, 83, 1, 68, 222, 83, 1, 223, + 201, 222, 83, 1, 66, 222, 83, 1, 196, 30, 222, 83, 1, 117, 146, 222, 83, + 1, 117, 172, 222, 83, 1, 71, 222, 83, 1, 234, 190, 222, 83, 1, 251, 238, + 222, 83, 1, 74, 222, 83, 1, 211, 89, 222, 83, 1, 250, 165, 222, 83, 1, + 155, 222, 83, 1, 221, 217, 222, 83, 1, 231, 242, 222, 83, 1, 231, 93, + 222, 83, 1, 214, 70, 222, 83, 1, 247, 162, 222, 83, 1, 247, 3, 222, 83, + 1, 223, 34, 222, 83, 1, 222, 254, 222, 83, 1, 212, 103, 222, 83, 1, 197, + 132, 222, 83, 1, 197, 120, 222, 83, 1, 237, 193, 222, 83, 1, 237, 177, + 222, 83, 1, 213, 81, 222, 83, 1, 190, 190, 222, 83, 1, 199, 49, 222, 83, + 1, 238, 34, 222, 83, 1, 237, 70, 222, 83, 1, 181, 222, 83, 1, 168, 222, + 83, 1, 209, 230, 222, 83, 1, 249, 155, 222, 83, 1, 248, 205, 222, 83, 1, + 174, 222, 83, 1, 170, 222, 83, 1, 165, 222, 83, 1, 206, 110, 222, 83, 1, + 173, 222, 83, 1, 219, 75, 222, 83, 1, 195, 188, 222, 83, 1, 203, 166, + 222, 83, 1, 201, 176, 222, 83, 1, 188, 222, 83, 1, 140, 222, 83, 3, 212, + 143, 222, 83, 3, 250, 147, 222, 83, 18, 3, 252, 208, 222, 83, 18, 3, 68, + 222, 83, 18, 3, 223, 201, 222, 83, 18, 3, 66, 222, 83, 18, 3, 196, 30, + 222, 83, 18, 3, 117, 146, 222, 83, 18, 3, 117, 206, 111, 222, 83, 18, 3, + 71, 222, 83, 18, 3, 234, 190, 222, 83, 18, 3, 251, 238, 222, 83, 18, 3, + 74, 222, 83, 18, 3, 211, 89, 222, 83, 18, 3, 250, 165, 222, 83, 3, 195, + 40, 222, 83, 219, 200, 77, 222, 83, 251, 239, 219, 200, 77, 222, 83, 1, + 214, 234, 209, 48, 222, 83, 1, 233, 111, 222, 83, 1, 117, 206, 111, 222, + 83, 1, 117, 219, 76, 222, 83, 18, 3, 117, 172, 222, 83, 18, 3, 117, 219, + 76, 222, 83, 17, 191, 77, 222, 83, 17, 107, 222, 83, 17, 109, 222, 83, + 17, 138, 222, 83, 17, 134, 222, 83, 17, 150, 222, 83, 17, 169, 222, 83, + 17, 175, 222, 83, 17, 171, 222, 83, 17, 178, 222, 83, 3, 222, 239, 222, + 83, 3, 196, 75, 222, 83, 3, 33, 251, 74, 93, 179, 142, 3, 33, 251, 74, + 58, 142, 3, 247, 121, 142, 3, 251, 73, 142, 3, 195, 35, 142, 1, 195, 150, + 251, 73, 142, 1, 65, 142, 1, 252, 208, 142, 1, 68, 142, 1, 223, 201, 142, 1, 66, 142, 1, 196, 30, 142, 1, 117, 146, 142, 1, 117, 172, 142, 1, 71, - 142, 1, 234, 188, 142, 1, 251, 236, 142, 1, 74, 142, 1, 211, 87, 142, 1, - 250, 163, 142, 1, 155, 142, 1, 221, 215, 142, 1, 231, 240, 142, 1, 231, - 91, 142, 1, 214, 68, 142, 1, 247, 160, 142, 1, 247, 1, 142, 1, 223, 32, - 142, 1, 222, 252, 142, 1, 212, 101, 142, 1, 197, 132, 142, 1, 197, 120, - 142, 1, 237, 191, 142, 1, 237, 175, 142, 1, 213, 79, 142, 1, 190, 190, - 142, 1, 199, 49, 142, 1, 238, 32, 142, 1, 237, 68, 142, 1, 180, 142, 1, - 213, 61, 142, 1, 168, 142, 1, 209, 228, 142, 1, 249, 153, 142, 1, 248, - 203, 142, 1, 174, 142, 1, 170, 142, 1, 165, 142, 1, 206, 109, 142, 1, - 173, 142, 1, 219, 73, 142, 1, 219, 62, 142, 1, 195, 188, 142, 1, 203, - 165, 142, 1, 201, 175, 142, 1, 188, 142, 1, 140, 142, 1, 197, 101, 142, - 3, 81, 249, 88, 195, 40, 142, 3, 243, 4, 195, 40, 142, 3, 250, 145, 142, - 18, 3, 252, 206, 142, 18, 3, 68, 142, 18, 3, 223, 199, 142, 18, 3, 66, - 142, 18, 3, 196, 30, 142, 18, 3, 117, 146, 142, 18, 3, 117, 206, 110, - 142, 18, 3, 71, 142, 18, 3, 234, 188, 142, 18, 3, 251, 236, 142, 18, 3, - 74, 142, 18, 3, 211, 87, 142, 18, 3, 250, 163, 142, 3, 195, 40, 142, 1, - 75, 207, 45, 142, 3, 210, 130, 142, 1, 243, 84, 218, 168, 142, 1, 243, - 84, 192, 159, 142, 1, 243, 84, 219, 63, 142, 250, 164, 219, 198, 77, 142, - 232, 118, 91, 211, 100, 142, 232, 118, 91, 232, 139, 142, 232, 118, 115, - 234, 155, 142, 232, 118, 91, 197, 35, 142, 232, 118, 91, 199, 86, 142, - 232, 118, 115, 197, 34, 142, 232, 118, 91, 233, 18, 142, 1, 251, 14, 223, - 199, 142, 1, 117, 206, 110, 142, 1, 117, 219, 74, 142, 18, 3, 117, 172, - 142, 18, 3, 117, 219, 74, 142, 17, 191, 77, 142, 17, 107, 142, 17, 109, - 142, 17, 138, 142, 17, 134, 142, 17, 149, 142, 17, 169, 142, 17, 175, - 142, 17, 171, 142, 17, 178, 142, 31, 199, 95, 142, 31, 91, 228, 140, 142, - 31, 91, 189, 142, 232, 118, 91, 208, 22, 142, 232, 118, 91, 230, 70, 142, - 232, 118, 115, 208, 20, 142, 232, 118, 91, 202, 128, 142, 232, 118, 91, - 234, 159, 142, 232, 118, 115, 202, 125, 142, 237, 209, 77, 142, 1, 243, - 84, 213, 80, 142, 1, 243, 84, 215, 61, 142, 1, 243, 84, 206, 110, 142, 1, - 243, 84, 172, 142, 1, 243, 84, 219, 74, 142, 1, 243, 84, 222, 152, 166, - 3, 247, 119, 166, 3, 251, 70, 166, 3, 195, 34, 166, 1, 250, 129, 166, 1, - 252, 159, 166, 1, 252, 5, 166, 1, 252, 20, 166, 1, 223, 43, 166, 1, 223, - 198, 166, 1, 196, 20, 166, 1, 196, 24, 166, 1, 223, 70, 166, 1, 223, 71, - 166, 1, 223, 182, 166, 1, 223, 184, 166, 1, 233, 196, 166, 1, 234, 183, - 166, 1, 251, 219, 166, 1, 210, 241, 166, 1, 211, 80, 166, 1, 250, 148, - 166, 1, 251, 163, 222, 27, 166, 1, 217, 119, 222, 27, 166, 1, 251, 163, - 231, 185, 166, 1, 217, 119, 231, 185, 166, 1, 222, 80, 214, 247, 166, 1, - 205, 132, 231, 185, 166, 1, 251, 163, 247, 68, 166, 1, 217, 119, 247, 68, - 166, 1, 251, 163, 223, 13, 166, 1, 217, 119, 223, 13, 166, 1, 199, 241, - 214, 247, 166, 1, 199, 241, 205, 131, 214, 248, 166, 1, 205, 132, 223, - 13, 166, 1, 251, 163, 197, 128, 166, 1, 217, 119, 197, 128, 166, 1, 251, - 163, 237, 182, 166, 1, 217, 119, 237, 182, 166, 1, 215, 92, 214, 197, - 166, 1, 205, 132, 237, 182, 166, 1, 251, 163, 199, 153, 166, 1, 217, 119, - 199, 153, 166, 1, 251, 163, 237, 202, 166, 1, 217, 119, 237, 202, 166, 1, - 237, 234, 214, 197, 166, 1, 205, 132, 237, 202, 166, 1, 251, 163, 210, - 71, 166, 1, 217, 119, 210, 71, 166, 1, 251, 163, 249, 55, 166, 1, 217, - 119, 249, 55, 166, 1, 217, 19, 166, 1, 251, 143, 249, 55, 166, 1, 192, - 85, 166, 1, 207, 121, 166, 1, 237, 234, 219, 247, 166, 1, 195, 156, 166, - 1, 199, 241, 205, 102, 166, 1, 215, 92, 205, 102, 166, 1, 237, 234, 205, - 102, 166, 1, 229, 251, 166, 1, 215, 92, 219, 247, 166, 1, 233, 61, 166, - 3, 251, 205, 166, 18, 3, 252, 15, 166, 18, 3, 221, 240, 252, 22, 166, 18, - 3, 237, 11, 252, 22, 166, 18, 3, 221, 240, 223, 67, 166, 18, 3, 237, 11, - 223, 67, 166, 18, 3, 221, 240, 210, 219, 166, 18, 3, 237, 11, 210, 219, - 166, 18, 3, 231, 229, 166, 18, 3, 221, 46, 166, 18, 3, 237, 11, 221, 46, - 166, 18, 3, 221, 48, 237, 120, 166, 18, 3, 221, 47, 230, 92, 252, 15, - 166, 18, 3, 221, 47, 230, 92, 237, 11, 252, 15, 166, 18, 3, 221, 47, 230, - 92, 231, 184, 166, 18, 3, 231, 184, 166, 219, 86, 17, 191, 77, 166, 219, - 86, 17, 107, 166, 219, 86, 17, 109, 166, 219, 86, 17, 138, 166, 219, 86, - 17, 134, 166, 219, 86, 17, 149, 166, 219, 86, 17, 169, 166, 219, 86, 17, - 175, 166, 219, 86, 17, 171, 166, 219, 86, 17, 178, 166, 18, 3, 237, 11, - 231, 229, 166, 18, 3, 237, 11, 231, 184, 166, 208, 152, 220, 209, 199, - 44, 246, 240, 221, 68, 222, 102, 199, 44, 246, 240, 221, 184, 221, 209, - 199, 44, 246, 240, 221, 184, 221, 174, 199, 44, 246, 240, 221, 184, 221, - 169, 199, 44, 246, 240, 221, 184, 221, 179, 199, 44, 246, 240, 221, 184, - 207, 143, 199, 44, 246, 240, 213, 250, 213, 237, 199, 44, 246, 240, 243, - 69, 246, 246, 199, 44, 246, 240, 243, 69, 243, 79, 199, 44, 246, 240, - 243, 69, 246, 245, 199, 44, 246, 240, 202, 47, 202, 46, 199, 44, 246, - 240, 243, 69, 243, 65, 199, 44, 246, 240, 192, 13, 192, 20, 199, 44, 246, - 240, 236, 175, 246, 254, 199, 44, 246, 240, 119, 210, 87, 199, 44, 246, - 240, 198, 242, 199, 38, 199, 44, 246, 240, 198, 242, 214, 222, 199, 44, - 246, 240, 198, 242, 209, 188, 199, 44, 246, 240, 213, 44, 214, 102, 199, - 44, 246, 240, 236, 175, 237, 121, 199, 44, 246, 240, 119, 199, 184, 199, - 44, 246, 240, 198, 242, 198, 207, 199, 44, 246, 240, 198, 242, 199, 45, - 199, 44, 246, 240, 198, 242, 198, 236, 199, 44, 246, 240, 213, 44, 212, - 178, 199, 44, 246, 240, 248, 112, 249, 118, 199, 44, 246, 240, 209, 74, - 209, 110, 199, 44, 246, 240, 209, 200, 209, 190, 199, 44, 246, 240, 232, - 176, 233, 109, 199, 44, 246, 240, 209, 200, 209, 221, 199, 44, 246, 240, - 232, 176, 233, 80, 199, 44, 246, 240, 209, 200, 205, 146, 199, 44, 246, - 240, 216, 13, 174, 199, 44, 246, 240, 192, 13, 192, 116, 199, 44, 246, - 240, 206, 163, 206, 61, 199, 44, 246, 240, 206, 68, 199, 44, 246, 240, - 219, 44, 219, 105, 199, 44, 246, 240, 218, 225, 199, 44, 246, 240, 193, - 49, 193, 175, 199, 44, 246, 240, 202, 47, 205, 167, 199, 44, 246, 240, - 202, 47, 206, 32, 199, 44, 246, 240, 202, 47, 200, 251, 199, 44, 246, - 240, 229, 24, 229, 122, 199, 44, 246, 240, 219, 44, 243, 47, 199, 44, - 246, 240, 187, 251, 122, 199, 44, 246, 240, 229, 24, 213, 34, 199, 44, - 246, 240, 210, 194, 199, 44, 246, 240, 205, 126, 65, 199, 44, 246, 240, - 217, 113, 230, 55, 199, 44, 246, 240, 205, 126, 252, 206, 199, 44, 246, - 240, 205, 126, 251, 149, 199, 44, 246, 240, 205, 126, 68, 199, 44, 246, - 240, 205, 126, 223, 199, 199, 44, 246, 240, 205, 126, 196, 152, 199, 44, - 246, 240, 205, 126, 196, 149, 199, 44, 246, 240, 205, 126, 66, 199, 44, - 246, 240, 205, 126, 196, 30, 199, 44, 246, 240, 209, 202, 199, 44, 238, - 170, 16, 249, 119, 199, 44, 246, 240, 205, 126, 71, 199, 44, 246, 240, - 205, 126, 252, 25, 199, 44, 246, 240, 205, 126, 74, 199, 44, 246, 240, - 205, 126, 251, 237, 217, 107, 199, 44, 246, 240, 205, 126, 251, 237, 217, - 108, 199, 44, 246, 240, 220, 39, 199, 44, 246, 240, 217, 104, 199, 44, - 246, 240, 217, 105, 199, 44, 246, 240, 217, 113, 234, 147, 199, 44, 246, - 240, 217, 113, 198, 241, 199, 44, 246, 240, 217, 113, 197, 244, 199, 44, - 246, 240, 217, 113, 243, 132, 199, 44, 246, 240, 199, 36, 199, 44, 246, - 240, 213, 183, 199, 44, 246, 240, 192, 110, 199, 44, 246, 240, 232, 164, + 142, 1, 234, 190, 142, 1, 251, 238, 142, 1, 74, 142, 1, 211, 89, 142, 1, + 250, 165, 142, 1, 155, 142, 1, 221, 217, 142, 1, 231, 242, 142, 1, 231, + 93, 142, 1, 214, 70, 142, 1, 247, 162, 142, 1, 247, 3, 142, 1, 223, 34, + 142, 1, 222, 254, 142, 1, 212, 103, 142, 1, 197, 132, 142, 1, 197, 120, + 142, 1, 237, 193, 142, 1, 237, 177, 142, 1, 213, 81, 142, 1, 190, 190, + 142, 1, 199, 49, 142, 1, 238, 34, 142, 1, 237, 70, 142, 1, 181, 142, 1, + 213, 63, 142, 1, 168, 142, 1, 209, 230, 142, 1, 249, 155, 142, 1, 248, + 205, 142, 1, 174, 142, 1, 170, 142, 1, 165, 142, 1, 206, 110, 142, 1, + 173, 142, 1, 219, 75, 142, 1, 219, 64, 142, 1, 195, 188, 142, 1, 203, + 166, 142, 1, 201, 176, 142, 1, 188, 142, 1, 140, 142, 1, 197, 101, 142, + 3, 81, 249, 90, 195, 40, 142, 3, 243, 6, 195, 40, 142, 3, 250, 147, 142, + 18, 3, 252, 208, 142, 18, 3, 68, 142, 18, 3, 223, 201, 142, 18, 3, 66, + 142, 18, 3, 196, 30, 142, 18, 3, 117, 146, 142, 18, 3, 117, 206, 111, + 142, 18, 3, 71, 142, 18, 3, 234, 190, 142, 18, 3, 251, 238, 142, 18, 3, + 74, 142, 18, 3, 211, 89, 142, 18, 3, 250, 165, 142, 3, 195, 40, 142, 1, + 75, 207, 46, 142, 3, 210, 132, 142, 1, 243, 86, 218, 170, 142, 1, 243, + 86, 192, 159, 142, 1, 243, 86, 219, 65, 142, 250, 166, 219, 200, 77, 142, + 232, 120, 91, 211, 102, 142, 232, 120, 91, 232, 141, 142, 232, 120, 115, + 234, 157, 142, 232, 120, 91, 197, 35, 142, 232, 120, 91, 199, 86, 142, + 232, 120, 115, 197, 34, 142, 232, 120, 91, 233, 20, 142, 1, 251, 16, 223, + 201, 142, 1, 117, 206, 111, 142, 1, 117, 219, 76, 142, 18, 3, 117, 172, + 142, 18, 3, 117, 219, 76, 142, 17, 191, 77, 142, 17, 107, 142, 17, 109, + 142, 17, 138, 142, 17, 134, 142, 17, 150, 142, 17, 169, 142, 17, 175, + 142, 17, 171, 142, 17, 178, 142, 31, 199, 95, 142, 31, 91, 228, 142, 142, + 31, 91, 189, 142, 232, 120, 91, 208, 24, 142, 232, 120, 91, 230, 72, 142, + 232, 120, 115, 208, 22, 142, 232, 120, 91, 202, 129, 142, 232, 120, 91, + 234, 161, 142, 232, 120, 115, 202, 126, 142, 237, 211, 77, 142, 1, 243, + 86, 213, 82, 142, 1, 243, 86, 215, 63, 142, 1, 243, 86, 206, 111, 142, 1, + 243, 86, 172, 142, 1, 243, 86, 219, 76, 142, 1, 243, 86, 222, 154, 166, + 3, 247, 121, 166, 3, 251, 72, 166, 3, 195, 34, 166, 1, 250, 131, 166, 1, + 252, 161, 166, 1, 252, 7, 166, 1, 252, 22, 166, 1, 223, 45, 166, 1, 223, + 200, 166, 1, 196, 20, 166, 1, 196, 24, 166, 1, 223, 72, 166, 1, 223, 73, + 166, 1, 223, 184, 166, 1, 223, 186, 166, 1, 233, 198, 166, 1, 234, 185, + 166, 1, 251, 221, 166, 1, 210, 243, 166, 1, 211, 82, 166, 1, 250, 150, + 166, 1, 251, 165, 222, 29, 166, 1, 217, 121, 222, 29, 166, 1, 251, 165, + 231, 187, 166, 1, 217, 121, 231, 187, 166, 1, 222, 82, 214, 249, 166, 1, + 205, 133, 231, 187, 166, 1, 251, 165, 247, 70, 166, 1, 217, 121, 247, 70, + 166, 1, 251, 165, 223, 15, 166, 1, 217, 121, 223, 15, 166, 1, 199, 241, + 214, 249, 166, 1, 199, 241, 205, 132, 214, 250, 166, 1, 205, 133, 223, + 15, 166, 1, 251, 165, 197, 128, 166, 1, 217, 121, 197, 128, 166, 1, 251, + 165, 237, 184, 166, 1, 217, 121, 237, 184, 166, 1, 215, 94, 214, 199, + 166, 1, 205, 133, 237, 184, 166, 1, 251, 165, 199, 153, 166, 1, 217, 121, + 199, 153, 166, 1, 251, 165, 237, 204, 166, 1, 217, 121, 237, 204, 166, 1, + 237, 236, 214, 199, 166, 1, 205, 133, 237, 204, 166, 1, 251, 165, 210, + 73, 166, 1, 217, 121, 210, 73, 166, 1, 251, 165, 249, 57, 166, 1, 217, + 121, 249, 57, 166, 1, 217, 21, 166, 1, 251, 145, 249, 57, 166, 1, 192, + 85, 166, 1, 207, 123, 166, 1, 237, 236, 219, 249, 166, 1, 195, 156, 166, + 1, 199, 241, 205, 103, 166, 1, 215, 94, 205, 103, 166, 1, 237, 236, 205, + 103, 166, 1, 229, 253, 166, 1, 215, 94, 219, 249, 166, 1, 233, 63, 166, + 3, 251, 207, 166, 18, 3, 252, 17, 166, 18, 3, 221, 242, 252, 24, 166, 18, + 3, 237, 13, 252, 24, 166, 18, 3, 221, 242, 223, 69, 166, 18, 3, 237, 13, + 223, 69, 166, 18, 3, 221, 242, 210, 221, 166, 18, 3, 237, 13, 210, 221, + 166, 18, 3, 231, 231, 166, 18, 3, 221, 48, 166, 18, 3, 237, 13, 221, 48, + 166, 18, 3, 221, 50, 237, 122, 166, 18, 3, 221, 49, 230, 94, 252, 17, + 166, 18, 3, 221, 49, 230, 94, 237, 13, 252, 17, 166, 18, 3, 221, 49, 230, + 94, 231, 186, 166, 18, 3, 231, 186, 166, 219, 88, 17, 191, 77, 166, 219, + 88, 17, 107, 166, 219, 88, 17, 109, 166, 219, 88, 17, 138, 166, 219, 88, + 17, 134, 166, 219, 88, 17, 150, 166, 219, 88, 17, 169, 166, 219, 88, 17, + 175, 166, 219, 88, 17, 171, 166, 219, 88, 17, 178, 166, 18, 3, 237, 13, + 231, 231, 166, 18, 3, 237, 13, 231, 186, 166, 208, 154, 220, 211, 199, + 44, 246, 242, 221, 70, 222, 104, 199, 44, 246, 242, 221, 186, 221, 211, + 199, 44, 246, 242, 221, 186, 221, 176, 199, 44, 246, 242, 221, 186, 221, + 171, 199, 44, 246, 242, 221, 186, 221, 181, 199, 44, 246, 242, 221, 186, + 207, 145, 199, 44, 246, 242, 213, 252, 213, 239, 199, 44, 246, 242, 243, + 71, 246, 248, 199, 44, 246, 242, 243, 71, 243, 81, 199, 44, 246, 242, + 243, 71, 246, 247, 199, 44, 246, 242, 202, 48, 202, 47, 199, 44, 246, + 242, 243, 71, 243, 67, 199, 44, 246, 242, 192, 13, 192, 20, 199, 44, 246, + 242, 236, 177, 247, 0, 199, 44, 246, 242, 119, 210, 89, 199, 44, 246, + 242, 198, 242, 199, 38, 199, 44, 246, 242, 198, 242, 214, 224, 199, 44, + 246, 242, 198, 242, 209, 190, 199, 44, 246, 242, 213, 46, 214, 104, 199, + 44, 246, 242, 236, 177, 237, 123, 199, 44, 246, 242, 119, 199, 184, 199, + 44, 246, 242, 198, 242, 198, 207, 199, 44, 246, 242, 198, 242, 199, 45, + 199, 44, 246, 242, 198, 242, 198, 236, 199, 44, 246, 242, 213, 46, 212, + 180, 199, 44, 246, 242, 248, 114, 249, 120, 199, 44, 246, 242, 209, 76, + 209, 112, 199, 44, 246, 242, 209, 202, 209, 192, 199, 44, 246, 242, 232, + 178, 233, 111, 199, 44, 246, 242, 209, 202, 209, 223, 199, 44, 246, 242, + 232, 178, 233, 82, 199, 44, 246, 242, 209, 202, 205, 147, 199, 44, 246, + 242, 216, 15, 174, 199, 44, 246, 242, 192, 13, 192, 116, 199, 44, 246, + 242, 206, 164, 206, 62, 199, 44, 246, 242, 206, 69, 199, 44, 246, 242, + 219, 46, 219, 107, 199, 44, 246, 242, 218, 227, 199, 44, 246, 242, 193, + 49, 193, 175, 199, 44, 246, 242, 202, 48, 205, 168, 199, 44, 246, 242, + 202, 48, 206, 33, 199, 44, 246, 242, 202, 48, 200, 252, 199, 44, 246, + 242, 229, 26, 229, 124, 199, 44, 246, 242, 219, 46, 243, 49, 199, 44, + 246, 242, 187, 251, 124, 199, 44, 246, 242, 229, 26, 213, 36, 199, 44, + 246, 242, 210, 196, 199, 44, 246, 242, 205, 127, 65, 199, 44, 246, 242, + 217, 115, 230, 57, 199, 44, 246, 242, 205, 127, 252, 208, 199, 44, 246, + 242, 205, 127, 251, 151, 199, 44, 246, 242, 205, 127, 68, 199, 44, 246, + 242, 205, 127, 223, 201, 199, 44, 246, 242, 205, 127, 196, 152, 199, 44, + 246, 242, 205, 127, 196, 149, 199, 44, 246, 242, 205, 127, 66, 199, 44, + 246, 242, 205, 127, 196, 30, 199, 44, 246, 242, 209, 204, 199, 44, 238, + 172, 16, 249, 121, 199, 44, 246, 242, 205, 127, 71, 199, 44, 246, 242, + 205, 127, 252, 27, 199, 44, 246, 242, 205, 127, 74, 199, 44, 246, 242, + 205, 127, 251, 239, 217, 109, 199, 44, 246, 242, 205, 127, 251, 239, 217, + 110, 199, 44, 246, 242, 220, 41, 199, 44, 246, 242, 217, 106, 199, 44, + 246, 242, 217, 107, 199, 44, 246, 242, 217, 115, 234, 149, 199, 44, 246, + 242, 217, 115, 198, 241, 199, 44, 246, 242, 217, 115, 197, 244, 199, 44, + 246, 242, 217, 115, 243, 134, 199, 44, 246, 242, 199, 36, 199, 44, 246, + 242, 213, 185, 199, 44, 246, 242, 192, 110, 199, 44, 246, 242, 232, 166, 199, 44, 17, 191, 77, 199, 44, 17, 107, 199, 44, 17, 109, 199, 44, 17, - 138, 199, 44, 17, 134, 199, 44, 17, 149, 199, 44, 17, 169, 199, 44, 17, - 175, 199, 44, 17, 171, 199, 44, 17, 178, 199, 44, 246, 240, 251, 117, - 199, 44, 246, 240, 221, 180, 220, 17, 1, 221, 67, 220, 17, 1, 221, 184, - 200, 195, 220, 17, 1, 221, 184, 199, 197, 220, 17, 1, 210, 187, 231, 91, - 220, 17, 1, 213, 249, 220, 17, 1, 242, 99, 220, 17, 1, 210, 187, 247, 1, - 220, 17, 1, 202, 47, 199, 197, 220, 17, 1, 210, 187, 222, 252, 220, 17, - 1, 212, 65, 220, 17, 1, 210, 187, 212, 101, 220, 17, 1, 210, 187, 197, - 132, 220, 17, 1, 210, 187, 197, 120, 220, 17, 1, 210, 187, 237, 191, 220, - 17, 1, 210, 187, 237, 175, 220, 17, 1, 210, 187, 213, 79, 220, 17, 1, - 236, 174, 220, 17, 1, 159, 220, 17, 1, 198, 242, 200, 195, 220, 17, 1, - 198, 242, 199, 197, 220, 17, 1, 210, 187, 237, 68, 220, 17, 1, 213, 43, - 220, 17, 1, 248, 111, 220, 17, 1, 209, 73, 220, 17, 1, 209, 200, 200, - 195, 220, 17, 1, 232, 176, 199, 197, 220, 17, 1, 209, 200, 199, 197, 220, - 17, 1, 232, 176, 200, 195, 220, 17, 1, 210, 187, 248, 203, 220, 17, 1, - 216, 12, 220, 17, 1, 192, 12, 220, 17, 1, 219, 44, 219, 105, 220, 17, 1, - 219, 44, 219, 2, 220, 17, 1, 193, 48, 220, 17, 1, 205, 134, 203, 165, - 220, 17, 1, 205, 134, 201, 175, 220, 17, 1, 202, 47, 200, 195, 220, 17, - 1, 229, 24, 200, 195, 220, 17, 1, 210, 187, 219, 73, 220, 17, 1, 74, 220, - 17, 1, 229, 24, 199, 197, 220, 17, 234, 120, 220, 17, 18, 3, 65, 220, 17, - 18, 3, 217, 113, 222, 87, 220, 17, 18, 3, 252, 206, 220, 17, 18, 3, 251, - 149, 220, 17, 18, 3, 68, 220, 17, 18, 3, 223, 199, 220, 17, 18, 3, 192, - 159, 220, 17, 18, 3, 191, 176, 220, 17, 18, 3, 66, 220, 17, 18, 3, 196, - 30, 220, 17, 3, 210, 187, 195, 40, 220, 17, 18, 3, 217, 113, 221, 44, - 220, 17, 204, 20, 3, 219, 43, 220, 17, 204, 20, 3, 212, 65, 220, 17, 18, - 3, 71, 220, 17, 18, 3, 234, 166, 220, 17, 18, 3, 74, 220, 17, 18, 3, 250, - 131, 220, 17, 18, 3, 251, 236, 220, 17, 221, 68, 173, 220, 17, 163, 217, - 113, 234, 147, 220, 17, 163, 217, 113, 198, 241, 220, 17, 163, 217, 113, - 198, 193, 220, 17, 163, 217, 113, 247, 77, 220, 17, 247, 125, 77, 220, - 17, 213, 192, 220, 17, 192, 110, 220, 17, 17, 191, 77, 220, 17, 17, 107, - 220, 17, 17, 109, 220, 17, 17, 138, 220, 17, 17, 134, 220, 17, 17, 149, - 220, 17, 17, 169, 220, 17, 17, 175, 220, 17, 17, 171, 220, 17, 17, 178, - 220, 17, 229, 24, 213, 43, 220, 17, 229, 24, 216, 12, 220, 17, 1, 221, - 185, 231, 3, 220, 17, 1, 221, 185, 212, 65, 86, 5, 211, 113, 86, 87, 230, - 181, 192, 25, 216, 118, 197, 178, 65, 86, 87, 230, 181, 192, 25, 216, - 118, 255, 207, 206, 167, 249, 19, 174, 86, 87, 230, 181, 192, 25, 216, - 118, 255, 207, 230, 181, 197, 153, 174, 86, 87, 89, 192, 25, 216, 118, - 216, 234, 174, 86, 87, 242, 215, 192, 25, 216, 118, 203, 172, 174, 86, - 87, 247, 97, 192, 25, 216, 118, 209, 189, 203, 158, 174, 86, 87, 192, 25, - 216, 118, 197, 153, 203, 158, 174, 86, 87, 205, 100, 203, 157, 86, 87, - 248, 13, 192, 25, 216, 117, 86, 87, 248, 141, 203, 50, 192, 25, 216, 117, - 86, 87, 223, 98, 197, 152, 86, 87, 237, 113, 197, 153, 248, 12, 86, 87, - 203, 157, 86, 87, 212, 70, 203, 157, 86, 87, 197, 153, 203, 157, 86, 87, - 212, 70, 197, 153, 203, 157, 86, 87, 206, 191, 243, 111, 201, 193, 203, - 157, 86, 87, 207, 10, 230, 222, 203, 157, 86, 87, 247, 97, 255, 211, 206, - 73, 216, 233, 179, 247, 128, 86, 87, 230, 181, 197, 152, 86, 219, 27, 3, - 246, 255, 206, 72, 86, 219, 27, 3, 219, 157, 206, 72, 86, 250, 188, 3, - 203, 168, 231, 168, 255, 212, 206, 72, 86, 250, 188, 3, 255, 209, 168, - 86, 250, 188, 3, 205, 69, 197, 147, 86, 3, 207, 115, 236, 189, 231, 167, - 86, 3, 207, 115, 236, 189, 231, 5, 86, 3, 207, 115, 236, 189, 230, 182, - 86, 3, 207, 115, 214, 243, 231, 167, 86, 3, 207, 115, 214, 243, 231, 5, - 86, 3, 207, 115, 236, 189, 207, 115, 214, 242, 86, 17, 191, 77, 86, 17, - 107, 86, 17, 109, 86, 17, 138, 86, 17, 134, 86, 17, 149, 86, 17, 169, 86, - 17, 175, 86, 17, 171, 86, 17, 178, 86, 17, 132, 107, 86, 17, 132, 109, - 86, 17, 132, 138, 86, 17, 132, 134, 86, 17, 132, 149, 86, 17, 132, 169, - 86, 17, 132, 175, 86, 17, 132, 171, 86, 17, 132, 178, 86, 17, 132, 191, - 77, 86, 87, 248, 15, 206, 72, 86, 87, 214, 59, 247, 195, 212, 82, 191, - 10, 86, 87, 247, 97, 255, 211, 206, 73, 247, 196, 216, 62, 247, 128, 86, - 87, 214, 59, 247, 195, 203, 169, 206, 72, 86, 87, 243, 128, 216, 117, 86, - 87, 197, 169, 255, 208, 86, 87, 230, 164, 206, 73, 230, 119, 86, 87, 230, - 164, 206, 73, 230, 125, 86, 87, 251, 123, 221, 202, 230, 119, 86, 87, - 251, 123, 221, 202, 230, 125, 86, 3, 192, 102, 197, 151, 86, 3, 217, 66, - 197, 151, 86, 1, 155, 86, 1, 221, 215, 86, 1, 231, 240, 86, 1, 231, 91, - 86, 1, 214, 68, 86, 1, 247, 160, 86, 1, 247, 1, 86, 1, 223, 32, 86, 1, - 212, 101, 86, 1, 197, 132, 86, 1, 197, 120, 86, 1, 237, 191, 86, 1, 237, - 175, 86, 1, 213, 79, 86, 1, 190, 190, 86, 1, 199, 49, 86, 1, 238, 32, 86, - 1, 237, 68, 86, 1, 180, 86, 1, 168, 86, 1, 209, 228, 86, 1, 249, 153, 86, - 1, 248, 203, 86, 1, 174, 86, 1, 197, 168, 86, 1, 197, 157, 86, 1, 235, - 35, 86, 1, 235, 29, 86, 1, 193, 190, 86, 1, 191, 71, 86, 1, 191, 123, 86, - 1, 255, 214, 86, 1, 170, 86, 1, 165, 86, 1, 173, 86, 1, 203, 165, 86, 1, - 201, 175, 86, 1, 188, 86, 1, 140, 86, 1, 65, 86, 1, 220, 246, 86, 1, 232, - 221, 165, 86, 1, 221, 101, 86, 1, 206, 109, 86, 18, 3, 252, 206, 86, 18, - 3, 68, 86, 18, 3, 223, 199, 86, 18, 3, 66, 86, 18, 3, 196, 30, 86, 18, 3, - 117, 146, 86, 18, 3, 117, 206, 110, 86, 18, 3, 117, 172, 86, 18, 3, 117, - 219, 74, 86, 18, 3, 71, 86, 18, 3, 234, 188, 86, 18, 3, 74, 86, 18, 3, - 211, 87, 86, 3, 206, 173, 201, 5, 214, 69, 206, 162, 86, 3, 206, 167, - 249, 18, 86, 18, 3, 207, 18, 68, 86, 18, 3, 207, 18, 223, 199, 86, 3, - 212, 82, 191, 11, 214, 251, 238, 32, 86, 3, 202, 61, 219, 240, 86, 87, - 230, 72, 86, 87, 210, 178, 86, 3, 219, 243, 206, 72, 86, 3, 192, 107, - 206, 72, 86, 3, 219, 244, 197, 169, 247, 128, 86, 3, 216, 236, 247, 128, - 86, 3, 230, 185, 247, 129, 207, 8, 86, 3, 230, 185, 216, 220, 207, 8, 86, - 3, 223, 93, 216, 236, 247, 128, 86, 200, 239, 3, 219, 244, 197, 169, 247, - 128, 86, 200, 239, 3, 216, 236, 247, 128, 86, 200, 239, 3, 223, 93, 216, - 236, 247, 128, 86, 200, 239, 1, 155, 86, 200, 239, 1, 221, 215, 86, 200, - 239, 1, 231, 240, 86, 200, 239, 1, 231, 91, 86, 200, 239, 1, 214, 68, 86, - 200, 239, 1, 247, 160, 86, 200, 239, 1, 247, 1, 86, 200, 239, 1, 223, 32, - 86, 200, 239, 1, 212, 101, 86, 200, 239, 1, 197, 132, 86, 200, 239, 1, - 197, 120, 86, 200, 239, 1, 237, 191, 86, 200, 239, 1, 237, 175, 86, 200, - 239, 1, 213, 79, 86, 200, 239, 1, 190, 190, 86, 200, 239, 1, 199, 49, 86, - 200, 239, 1, 238, 32, 86, 200, 239, 1, 237, 68, 86, 200, 239, 1, 180, 86, - 200, 239, 1, 168, 86, 200, 239, 1, 209, 228, 86, 200, 239, 1, 249, 153, - 86, 200, 239, 1, 248, 203, 86, 200, 239, 1, 174, 86, 200, 239, 1, 197, - 168, 86, 200, 239, 1, 197, 157, 86, 200, 239, 1, 235, 35, 86, 200, 239, - 1, 235, 29, 86, 200, 239, 1, 193, 190, 86, 200, 239, 1, 191, 71, 86, 200, - 239, 1, 191, 123, 86, 200, 239, 1, 255, 214, 86, 200, 239, 1, 170, 86, - 200, 239, 1, 165, 86, 200, 239, 1, 173, 86, 200, 239, 1, 203, 165, 86, - 200, 239, 1, 201, 175, 86, 200, 239, 1, 188, 86, 200, 239, 1, 140, 86, - 200, 239, 1, 65, 86, 200, 239, 1, 220, 246, 86, 200, 239, 1, 232, 221, - 193, 190, 86, 200, 239, 1, 232, 221, 170, 86, 200, 239, 1, 232, 221, 165, - 86, 220, 233, 206, 69, 221, 215, 86, 220, 233, 206, 69, 221, 216, 247, - 196, 216, 62, 247, 128, 86, 247, 112, 3, 88, 249, 7, 86, 247, 112, 3, - 156, 249, 7, 86, 247, 112, 3, 247, 116, 199, 135, 86, 247, 112, 3, 205, - 99, 255, 213, 86, 16, 235, 105, 248, 10, 86, 16, 207, 114, 206, 174, 86, - 16, 210, 206, 231, 166, 86, 16, 207, 114, 206, 175, 207, 10, 230, 221, - 86, 16, 209, 189, 168, 86, 16, 213, 21, 248, 10, 86, 16, 213, 21, 248, - 11, 212, 70, 255, 210, 86, 16, 213, 21, 248, 11, 230, 183, 255, 210, 86, - 16, 213, 21, 248, 11, 247, 196, 255, 210, 86, 3, 207, 115, 214, 243, 207, - 115, 236, 188, 86, 3, 207, 115, 214, 243, 230, 182, 86, 87, 248, 14, 203, - 50, 231, 54, 216, 118, 207, 9, 86, 87, 216, 14, 192, 25, 231, 54, 216, - 118, 207, 9, 86, 87, 212, 70, 197, 152, 86, 87, 89, 248, 44, 206, 164, - 192, 25, 216, 118, 216, 234, 174, 86, 87, 242, 215, 248, 44, 206, 164, - 192, 25, 216, 118, 203, 172, 174, 206, 207, 200, 155, 56, 219, 223, 200, - 155, 56, 206, 207, 200, 155, 3, 4, 236, 138, 219, 223, 200, 155, 3, 4, - 236, 138, 86, 87, 219, 235, 216, 237, 206, 72, 86, 87, 198, 18, 216, 237, - 206, 72, 80, 1, 155, 80, 1, 221, 215, 80, 1, 231, 240, 80, 1, 231, 91, - 80, 1, 214, 68, 80, 1, 247, 160, 80, 1, 247, 1, 80, 1, 223, 32, 80, 1, - 222, 252, 80, 1, 212, 101, 80, 1, 213, 45, 80, 1, 197, 132, 80, 1, 197, - 120, 80, 1, 237, 191, 80, 1, 237, 175, 80, 1, 213, 79, 80, 1, 190, 190, - 80, 1, 199, 49, 80, 1, 238, 32, 80, 1, 237, 68, 80, 1, 180, 80, 1, 168, - 80, 1, 209, 228, 80, 1, 249, 153, 80, 1, 248, 203, 80, 1, 174, 80, 1, + 138, 199, 44, 17, 134, 199, 44, 17, 150, 199, 44, 17, 169, 199, 44, 17, + 175, 199, 44, 17, 171, 199, 44, 17, 178, 199, 44, 246, 242, 251, 119, + 199, 44, 246, 242, 221, 182, 220, 19, 1, 221, 69, 220, 19, 1, 221, 186, + 200, 195, 220, 19, 1, 221, 186, 199, 197, 220, 19, 1, 210, 189, 231, 93, + 220, 19, 1, 213, 251, 220, 19, 1, 242, 101, 220, 19, 1, 210, 189, 247, 3, + 220, 19, 1, 202, 48, 199, 197, 220, 19, 1, 210, 189, 222, 254, 220, 19, + 1, 212, 67, 220, 19, 1, 210, 189, 212, 103, 220, 19, 1, 210, 189, 197, + 132, 220, 19, 1, 210, 189, 197, 120, 220, 19, 1, 210, 189, 237, 193, 220, + 19, 1, 210, 189, 237, 177, 220, 19, 1, 210, 189, 213, 81, 220, 19, 1, + 236, 176, 220, 19, 1, 159, 220, 19, 1, 198, 242, 200, 195, 220, 19, 1, + 198, 242, 199, 197, 220, 19, 1, 210, 189, 237, 70, 220, 19, 1, 213, 45, + 220, 19, 1, 248, 113, 220, 19, 1, 209, 75, 220, 19, 1, 209, 202, 200, + 195, 220, 19, 1, 232, 178, 199, 197, 220, 19, 1, 209, 202, 199, 197, 220, + 19, 1, 232, 178, 200, 195, 220, 19, 1, 210, 189, 248, 205, 220, 19, 1, + 216, 14, 220, 19, 1, 192, 12, 220, 19, 1, 219, 46, 219, 107, 220, 19, 1, + 219, 46, 219, 4, 220, 19, 1, 193, 48, 220, 19, 1, 205, 135, 203, 166, + 220, 19, 1, 205, 135, 201, 176, 220, 19, 1, 202, 48, 200, 195, 220, 19, + 1, 229, 26, 200, 195, 220, 19, 1, 210, 189, 219, 75, 220, 19, 1, 74, 220, + 19, 1, 229, 26, 199, 197, 220, 19, 234, 122, 220, 19, 18, 3, 65, 220, 19, + 18, 3, 217, 115, 222, 89, 220, 19, 18, 3, 252, 208, 220, 19, 18, 3, 251, + 151, 220, 19, 18, 3, 68, 220, 19, 18, 3, 223, 201, 220, 19, 18, 3, 192, + 159, 220, 19, 18, 3, 191, 176, 220, 19, 18, 3, 66, 220, 19, 18, 3, 196, + 30, 220, 19, 3, 210, 189, 195, 40, 220, 19, 18, 3, 217, 115, 221, 46, + 220, 19, 204, 21, 3, 219, 45, 220, 19, 204, 21, 3, 212, 67, 220, 19, 18, + 3, 71, 220, 19, 18, 3, 234, 168, 220, 19, 18, 3, 74, 220, 19, 18, 3, 250, + 133, 220, 19, 18, 3, 251, 238, 220, 19, 221, 70, 173, 220, 19, 163, 217, + 115, 234, 149, 220, 19, 163, 217, 115, 198, 241, 220, 19, 163, 217, 115, + 198, 193, 220, 19, 163, 217, 115, 247, 79, 220, 19, 247, 127, 77, 220, + 19, 213, 194, 220, 19, 192, 110, 220, 19, 17, 191, 77, 220, 19, 17, 107, + 220, 19, 17, 109, 220, 19, 17, 138, 220, 19, 17, 134, 220, 19, 17, 150, + 220, 19, 17, 169, 220, 19, 17, 175, 220, 19, 17, 171, 220, 19, 17, 178, + 220, 19, 229, 26, 213, 45, 220, 19, 229, 26, 216, 14, 220, 19, 1, 221, + 187, 231, 5, 220, 19, 1, 221, 187, 212, 67, 86, 5, 211, 115, 86, 87, 230, + 183, 192, 25, 216, 120, 197, 178, 65, 86, 87, 230, 183, 192, 25, 216, + 120, 255, 209, 206, 168, 249, 21, 174, 86, 87, 230, 183, 192, 25, 216, + 120, 255, 209, 230, 183, 197, 153, 174, 86, 87, 89, 192, 25, 216, 120, + 216, 236, 174, 86, 87, 242, 217, 192, 25, 216, 120, 203, 173, 174, 86, + 87, 247, 99, 192, 25, 216, 120, 209, 191, 203, 159, 174, 86, 87, 192, 25, + 216, 120, 197, 153, 203, 159, 174, 86, 87, 205, 101, 203, 158, 86, 87, + 248, 15, 192, 25, 216, 119, 86, 87, 248, 143, 203, 51, 192, 25, 216, 119, + 86, 87, 223, 100, 197, 152, 86, 87, 237, 115, 197, 153, 248, 14, 86, 87, + 203, 158, 86, 87, 212, 72, 203, 158, 86, 87, 197, 153, 203, 158, 86, 87, + 212, 72, 197, 153, 203, 158, 86, 87, 206, 192, 243, 113, 201, 194, 203, + 158, 86, 87, 207, 11, 230, 224, 203, 158, 86, 87, 247, 99, 255, 213, 206, + 74, 216, 235, 180, 247, 130, 86, 87, 230, 183, 197, 152, 86, 219, 29, 3, + 247, 1, 206, 73, 86, 219, 29, 3, 219, 159, 206, 73, 86, 250, 190, 3, 203, + 169, 231, 170, 255, 214, 206, 73, 86, 250, 190, 3, 255, 211, 168, 86, + 250, 190, 3, 205, 70, 197, 147, 86, 3, 207, 117, 236, 191, 231, 169, 86, + 3, 207, 117, 236, 191, 231, 7, 86, 3, 207, 117, 236, 191, 230, 184, 86, + 3, 207, 117, 214, 245, 231, 169, 86, 3, 207, 117, 214, 245, 231, 7, 86, + 3, 207, 117, 236, 191, 207, 117, 214, 244, 86, 17, 191, 77, 86, 17, 107, + 86, 17, 109, 86, 17, 138, 86, 17, 134, 86, 17, 150, 86, 17, 169, 86, 17, + 175, 86, 17, 171, 86, 17, 178, 86, 17, 132, 107, 86, 17, 132, 109, 86, + 17, 132, 138, 86, 17, 132, 134, 86, 17, 132, 150, 86, 17, 132, 169, 86, + 17, 132, 175, 86, 17, 132, 171, 86, 17, 132, 178, 86, 17, 132, 191, 77, + 86, 87, 248, 17, 206, 73, 86, 87, 214, 61, 247, 197, 212, 84, 191, 10, + 86, 87, 247, 99, 255, 213, 206, 74, 247, 198, 216, 64, 247, 130, 86, 87, + 214, 61, 247, 197, 203, 170, 206, 73, 86, 87, 243, 130, 216, 119, 86, 87, + 197, 169, 255, 210, 86, 87, 230, 166, 206, 74, 230, 121, 86, 87, 230, + 166, 206, 74, 230, 127, 86, 87, 251, 125, 221, 204, 230, 121, 86, 87, + 251, 125, 221, 204, 230, 127, 86, 3, 192, 102, 197, 151, 86, 3, 217, 68, + 197, 151, 86, 1, 155, 86, 1, 221, 217, 86, 1, 231, 242, 86, 1, 231, 93, + 86, 1, 214, 70, 86, 1, 247, 162, 86, 1, 247, 3, 86, 1, 223, 34, 86, 1, + 212, 103, 86, 1, 197, 132, 86, 1, 197, 120, 86, 1, 237, 193, 86, 1, 237, + 177, 86, 1, 213, 81, 86, 1, 190, 190, 86, 1, 199, 49, 86, 1, 238, 34, 86, + 1, 237, 70, 86, 1, 181, 86, 1, 168, 86, 1, 209, 230, 86, 1, 249, 155, 86, + 1, 248, 205, 86, 1, 174, 86, 1, 197, 168, 86, 1, 197, 157, 86, 1, 235, + 37, 86, 1, 235, 31, 86, 1, 193, 190, 86, 1, 191, 71, 86, 1, 191, 123, 86, + 1, 255, 216, 86, 1, 170, 86, 1, 165, 86, 1, 173, 86, 1, 203, 166, 86, 1, + 201, 176, 86, 1, 188, 86, 1, 140, 86, 1, 65, 86, 1, 220, 248, 86, 1, 232, + 223, 165, 86, 1, 221, 103, 86, 1, 206, 110, 86, 18, 3, 252, 208, 86, 18, + 3, 68, 86, 18, 3, 223, 201, 86, 18, 3, 66, 86, 18, 3, 196, 30, 86, 18, 3, + 117, 146, 86, 18, 3, 117, 206, 111, 86, 18, 3, 117, 172, 86, 18, 3, 117, + 219, 76, 86, 18, 3, 71, 86, 18, 3, 234, 190, 86, 18, 3, 74, 86, 18, 3, + 211, 89, 86, 3, 206, 174, 201, 6, 214, 71, 206, 163, 86, 3, 206, 168, + 249, 20, 86, 18, 3, 207, 19, 68, 86, 18, 3, 207, 19, 223, 201, 86, 3, + 212, 84, 191, 11, 214, 253, 238, 34, 86, 3, 202, 62, 219, 242, 86, 87, + 230, 74, 86, 87, 210, 180, 86, 3, 219, 245, 206, 73, 86, 3, 192, 107, + 206, 73, 86, 3, 219, 246, 197, 169, 247, 130, 86, 3, 216, 238, 247, 130, + 86, 3, 230, 187, 247, 131, 207, 9, 86, 3, 230, 187, 216, 222, 207, 9, 86, + 3, 223, 95, 216, 238, 247, 130, 86, 200, 240, 3, 219, 246, 197, 169, 247, + 130, 86, 200, 240, 3, 216, 238, 247, 130, 86, 200, 240, 3, 223, 95, 216, + 238, 247, 130, 86, 200, 240, 1, 155, 86, 200, 240, 1, 221, 217, 86, 200, + 240, 1, 231, 242, 86, 200, 240, 1, 231, 93, 86, 200, 240, 1, 214, 70, 86, + 200, 240, 1, 247, 162, 86, 200, 240, 1, 247, 3, 86, 200, 240, 1, 223, 34, + 86, 200, 240, 1, 212, 103, 86, 200, 240, 1, 197, 132, 86, 200, 240, 1, + 197, 120, 86, 200, 240, 1, 237, 193, 86, 200, 240, 1, 237, 177, 86, 200, + 240, 1, 213, 81, 86, 200, 240, 1, 190, 190, 86, 200, 240, 1, 199, 49, 86, + 200, 240, 1, 238, 34, 86, 200, 240, 1, 237, 70, 86, 200, 240, 1, 181, 86, + 200, 240, 1, 168, 86, 200, 240, 1, 209, 230, 86, 200, 240, 1, 249, 155, + 86, 200, 240, 1, 248, 205, 86, 200, 240, 1, 174, 86, 200, 240, 1, 197, + 168, 86, 200, 240, 1, 197, 157, 86, 200, 240, 1, 235, 37, 86, 200, 240, + 1, 235, 31, 86, 200, 240, 1, 193, 190, 86, 200, 240, 1, 191, 71, 86, 200, + 240, 1, 191, 123, 86, 200, 240, 1, 255, 216, 86, 200, 240, 1, 170, 86, + 200, 240, 1, 165, 86, 200, 240, 1, 173, 86, 200, 240, 1, 203, 166, 86, + 200, 240, 1, 201, 176, 86, 200, 240, 1, 188, 86, 200, 240, 1, 140, 86, + 200, 240, 1, 65, 86, 200, 240, 1, 220, 248, 86, 200, 240, 1, 232, 223, + 193, 190, 86, 200, 240, 1, 232, 223, 170, 86, 200, 240, 1, 232, 223, 165, + 86, 220, 235, 206, 70, 221, 217, 86, 220, 235, 206, 70, 221, 218, 247, + 198, 216, 64, 247, 130, 86, 247, 114, 3, 88, 249, 9, 86, 247, 114, 3, + 156, 249, 9, 86, 247, 114, 3, 247, 118, 199, 135, 86, 247, 114, 3, 205, + 100, 255, 215, 86, 16, 235, 107, 248, 12, 86, 16, 207, 116, 206, 175, 86, + 16, 210, 208, 231, 168, 86, 16, 207, 116, 206, 176, 207, 11, 230, 223, + 86, 16, 209, 191, 168, 86, 16, 213, 23, 248, 12, 86, 16, 213, 23, 248, + 13, 212, 72, 255, 212, 86, 16, 213, 23, 248, 13, 230, 185, 255, 212, 86, + 16, 213, 23, 248, 13, 247, 198, 255, 212, 86, 3, 207, 117, 214, 245, 207, + 117, 236, 190, 86, 3, 207, 117, 214, 245, 230, 184, 86, 87, 248, 16, 203, + 51, 231, 56, 216, 120, 207, 10, 86, 87, 216, 16, 192, 25, 231, 56, 216, + 120, 207, 10, 86, 87, 212, 72, 197, 152, 86, 87, 89, 248, 46, 206, 165, + 192, 25, 216, 120, 216, 236, 174, 86, 87, 242, 217, 248, 46, 206, 165, + 192, 25, 216, 120, 203, 173, 174, 206, 208, 200, 155, 56, 219, 225, 200, + 155, 56, 206, 208, 200, 155, 3, 4, 236, 140, 219, 225, 200, 155, 3, 4, + 236, 140, 86, 87, 219, 237, 216, 239, 206, 73, 86, 87, 198, 18, 216, 239, + 206, 73, 80, 1, 155, 80, 1, 221, 217, 80, 1, 231, 242, 80, 1, 231, 93, + 80, 1, 214, 70, 80, 1, 247, 162, 80, 1, 247, 3, 80, 1, 223, 34, 80, 1, + 222, 254, 80, 1, 212, 103, 80, 1, 213, 47, 80, 1, 197, 132, 80, 1, 197, + 120, 80, 1, 237, 193, 80, 1, 237, 177, 80, 1, 213, 81, 80, 1, 190, 190, + 80, 1, 199, 49, 80, 1, 238, 34, 80, 1, 237, 70, 80, 1, 181, 80, 1, 168, + 80, 1, 209, 230, 80, 1, 249, 155, 80, 1, 248, 205, 80, 1, 174, 80, 1, 170, 80, 1, 165, 80, 1, 173, 80, 1, 193, 190, 80, 1, 188, 80, 1, 140, 80, - 1, 219, 73, 80, 1, 65, 80, 1, 203, 139, 65, 80, 1, 68, 80, 1, 223, 199, - 80, 1, 66, 80, 1, 196, 30, 80, 1, 71, 80, 1, 215, 232, 71, 80, 1, 74, 80, - 1, 250, 163, 80, 18, 3, 199, 200, 252, 206, 80, 18, 3, 252, 206, 80, 18, - 3, 68, 80, 18, 3, 223, 199, 80, 18, 3, 66, 80, 18, 3, 196, 30, 80, 18, 3, - 71, 80, 18, 3, 251, 236, 80, 18, 3, 215, 232, 223, 199, 80, 18, 3, 215, - 232, 74, 80, 18, 3, 235, 15, 58, 80, 3, 251, 71, 80, 3, 75, 60, 80, 3, - 195, 35, 80, 3, 195, 40, 80, 3, 250, 214, 80, 120, 3, 216, 217, 170, 80, - 120, 3, 216, 217, 165, 80, 120, 3, 216, 217, 193, 190, 80, 120, 3, 216, - 217, 140, 80, 1, 230, 206, 188, 80, 17, 191, 77, 80, 17, 107, 80, 17, - 109, 80, 17, 138, 80, 17, 134, 80, 17, 149, 80, 17, 169, 80, 17, 175, 80, - 17, 171, 80, 17, 178, 80, 3, 219, 83, 205, 53, 80, 3, 205, 53, 80, 16, - 219, 36, 80, 16, 242, 67, 80, 16, 252, 1, 80, 16, 231, 146, 80, 1, 203, - 165, 80, 1, 201, 175, 80, 1, 117, 146, 80, 1, 117, 206, 110, 80, 1, 117, - 172, 80, 1, 117, 219, 74, 80, 18, 3, 117, 146, 80, 18, 3, 117, 206, 110, - 80, 18, 3, 117, 172, 80, 18, 3, 117, 219, 74, 80, 1, 215, 232, 214, 68, - 80, 1, 215, 232, 222, 252, 80, 1, 215, 232, 249, 53, 80, 1, 215, 232, - 249, 48, 80, 120, 3, 215, 232, 216, 217, 180, 80, 120, 3, 215, 232, 216, - 217, 174, 80, 120, 3, 215, 232, 216, 217, 173, 80, 1, 203, 171, 222, 62, - 203, 165, 80, 18, 3, 203, 171, 222, 62, 233, 242, 80, 163, 87, 203, 171, - 222, 62, 230, 5, 80, 163, 87, 203, 171, 222, 62, 222, 23, 209, 199, 80, - 1, 193, 102, 208, 116, 222, 62, 199, 49, 80, 1, 193, 102, 208, 116, 222, - 62, 208, 122, 80, 18, 3, 193, 102, 208, 116, 222, 62, 233, 242, 80, 18, - 3, 193, 102, 208, 116, 222, 62, 196, 152, 80, 3, 193, 102, 208, 116, 222, - 62, 198, 78, 80, 3, 193, 102, 208, 116, 222, 62, 198, 77, 80, 3, 193, - 102, 208, 116, 222, 62, 198, 76, 80, 3, 193, 102, 208, 116, 222, 62, 198, - 75, 80, 3, 193, 102, 208, 116, 222, 62, 198, 74, 80, 1, 234, 202, 208, - 116, 222, 62, 213, 79, 80, 1, 234, 202, 208, 116, 222, 62, 191, 183, 80, - 1, 234, 202, 208, 116, 222, 62, 231, 56, 80, 18, 3, 231, 161, 222, 62, - 68, 80, 18, 3, 222, 28, 211, 151, 80, 18, 3, 222, 28, 66, 80, 18, 3, 222, - 28, 234, 188, 80, 1, 203, 139, 155, 80, 1, 203, 139, 221, 215, 80, 1, - 203, 139, 231, 240, 80, 1, 203, 139, 247, 160, 80, 1, 203, 139, 191, 123, - 80, 1, 203, 139, 212, 101, 80, 1, 203, 139, 238, 32, 80, 1, 203, 139, - 180, 80, 1, 203, 139, 209, 228, 80, 1, 203, 139, 233, 109, 80, 1, 203, - 139, 249, 153, 80, 1, 203, 139, 199, 49, 80, 1, 203, 139, 140, 80, 120, - 3, 203, 139, 216, 217, 193, 190, 80, 18, 3, 203, 139, 252, 206, 80, 18, - 3, 203, 139, 71, 80, 18, 3, 203, 139, 235, 15, 58, 80, 18, 3, 203, 139, - 53, 192, 159, 80, 3, 203, 139, 198, 77, 80, 3, 203, 139, 198, 76, 80, 3, - 203, 139, 198, 74, 80, 3, 203, 139, 198, 73, 80, 3, 203, 139, 238, 247, - 198, 77, 80, 3, 203, 139, 238, 247, 198, 76, 80, 3, 203, 139, 238, 247, - 234, 106, 198, 79, 80, 1, 206, 47, 210, 189, 233, 109, 80, 3, 206, 47, - 210, 189, 198, 74, 80, 203, 139, 17, 191, 77, 80, 203, 139, 17, 107, 80, - 203, 139, 17, 109, 80, 203, 139, 17, 138, 80, 203, 139, 17, 134, 80, 203, - 139, 17, 149, 80, 203, 139, 17, 169, 80, 203, 139, 17, 175, 80, 203, 139, - 17, 171, 80, 203, 139, 17, 178, 80, 3, 221, 206, 198, 78, 80, 3, 221, - 206, 198, 76, 80, 18, 3, 251, 222, 65, 80, 18, 3, 251, 222, 251, 236, 80, - 16, 203, 139, 107, 80, 16, 203, 139, 233, 215, 101, 6, 1, 251, 132, 101, - 6, 1, 249, 101, 101, 6, 1, 231, 210, 101, 6, 1, 236, 150, 101, 6, 1, 234, - 103, 101, 6, 1, 195, 49, 101, 6, 1, 191, 80, 101, 6, 1, 199, 193, 101, 6, - 1, 223, 162, 101, 6, 1, 222, 87, 101, 6, 1, 220, 7, 101, 6, 1, 217, 90, - 101, 6, 1, 214, 216, 101, 6, 1, 211, 104, 101, 6, 1, 210, 131, 101, 6, 1, - 191, 67, 101, 6, 1, 207, 163, 101, 6, 1, 205, 142, 101, 6, 1, 199, 179, - 101, 6, 1, 196, 113, 101, 6, 1, 209, 220, 101, 6, 1, 221, 200, 101, 6, 1, - 231, 82, 101, 6, 1, 208, 81, 101, 6, 1, 203, 69, 101, 6, 1, 243, 81, 101, - 6, 1, 247, 128, 101, 6, 1, 222, 234, 101, 6, 1, 243, 18, 101, 6, 1, 246, - 241, 101, 6, 1, 192, 218, 101, 6, 1, 222, 249, 101, 6, 1, 230, 87, 101, - 6, 1, 229, 245, 101, 6, 1, 229, 145, 101, 6, 1, 193, 125, 101, 6, 1, 230, - 19, 101, 6, 1, 229, 11, 101, 6, 1, 192, 14, 101, 6, 1, 252, 14, 101, 1, - 251, 132, 101, 1, 249, 101, 101, 1, 231, 210, 101, 1, 236, 150, 101, 1, - 234, 103, 101, 1, 195, 49, 101, 1, 191, 80, 101, 1, 199, 193, 101, 1, - 223, 162, 101, 1, 222, 87, 101, 1, 220, 7, 101, 1, 217, 90, 101, 1, 214, - 216, 101, 1, 211, 104, 101, 1, 210, 131, 101, 1, 191, 67, 101, 1, 207, - 163, 101, 1, 205, 142, 101, 1, 199, 179, 101, 1, 196, 113, 101, 1, 209, - 220, 101, 1, 221, 200, 101, 1, 231, 82, 101, 1, 208, 81, 101, 1, 203, 69, - 101, 1, 243, 81, 101, 1, 247, 128, 101, 1, 222, 234, 101, 1, 243, 18, - 101, 1, 246, 241, 101, 1, 192, 218, 101, 1, 222, 249, 101, 1, 230, 87, - 101, 1, 229, 245, 101, 1, 229, 145, 101, 1, 193, 125, 101, 1, 230, 19, - 101, 1, 229, 11, 101, 1, 233, 23, 101, 1, 192, 14, 101, 1, 234, 123, 101, - 1, 153, 231, 210, 101, 1, 251, 230, 101, 210, 128, 204, 10, 52, 1, 101, - 214, 216, 101, 1, 252, 14, 101, 1, 230, 17, 56, 101, 1, 220, 116, 56, 30, - 147, 221, 113, 30, 147, 201, 167, 30, 147, 213, 204, 30, 147, 198, 168, - 30, 147, 201, 156, 30, 147, 206, 239, 30, 147, 216, 77, 30, 147, 209, - 169, 30, 147, 201, 164, 30, 147, 202, 160, 30, 147, 201, 161, 30, 147, - 223, 222, 30, 147, 243, 24, 30, 147, 201, 171, 30, 147, 243, 91, 30, 147, - 221, 188, 30, 147, 199, 7, 30, 147, 209, 209, 30, 147, 229, 142, 30, 147, - 213, 200, 30, 147, 201, 165, 30, 147, 213, 194, 30, 147, 213, 198, 30, - 147, 198, 165, 30, 147, 206, 227, 30, 147, 201, 163, 30, 147, 206, 237, - 30, 147, 222, 68, 30, 147, 216, 70, 30, 147, 222, 71, 30, 147, 209, 164, - 30, 147, 209, 162, 30, 147, 209, 150, 30, 147, 209, 158, 30, 147, 209, - 156, 30, 147, 209, 153, 30, 147, 209, 155, 30, 147, 209, 152, 30, 147, - 209, 157, 30, 147, 209, 167, 30, 147, 209, 168, 30, 147, 209, 151, 30, - 147, 209, 161, 30, 147, 222, 69, 30, 147, 222, 67, 30, 147, 202, 153, 30, - 147, 202, 151, 30, 147, 202, 143, 30, 147, 202, 146, 30, 147, 202, 152, - 30, 147, 202, 148, 30, 147, 202, 147, 30, 147, 202, 145, 30, 147, 202, - 156, 30, 147, 202, 158, 30, 147, 202, 159, 30, 147, 202, 154, 30, 147, - 202, 144, 30, 147, 202, 149, 30, 147, 202, 157, 30, 147, 243, 72, 30, - 147, 243, 70, 30, 147, 247, 14, 30, 147, 247, 12, 30, 147, 210, 149, 30, - 147, 223, 217, 30, 147, 223, 208, 30, 147, 223, 216, 30, 147, 223, 213, - 30, 147, 223, 211, 30, 147, 223, 215, 30, 147, 201, 168, 30, 147, 223, - 220, 30, 147, 223, 221, 30, 147, 223, 209, 30, 147, 223, 214, 30, 147, - 192, 57, 30, 147, 243, 23, 30, 147, 243, 73, 30, 147, 243, 71, 30, 147, - 247, 15, 30, 147, 247, 13, 30, 147, 243, 89, 30, 147, 243, 90, 30, 147, - 243, 74, 30, 147, 247, 16, 30, 147, 209, 207, 30, 147, 222, 70, 30, 147, - 201, 169, 30, 147, 192, 63, 30, 147, 221, 104, 30, 147, 213, 196, 30, - 147, 213, 202, 30, 147, 213, 201, 30, 147, 198, 162, 30, 147, 233, 3, 30, - 222, 174, 233, 3, 30, 222, 174, 65, 30, 222, 174, 252, 25, 30, 222, 174, - 170, 30, 222, 174, 192, 129, 30, 222, 174, 234, 65, 30, 222, 174, 71, 30, - 222, 174, 192, 67, 30, 222, 174, 192, 80, 30, 222, 174, 74, 30, 222, 174, - 193, 190, 30, 222, 174, 193, 176, 30, 222, 174, 211, 151, 30, 222, 174, - 192, 12, 30, 222, 174, 66, 30, 222, 174, 193, 107, 30, 222, 174, 193, - 125, 30, 222, 174, 193, 86, 30, 222, 174, 191, 225, 30, 222, 174, 233, - 242, 30, 222, 174, 192, 33, 30, 222, 174, 68, 30, 222, 174, 255, 202, 30, - 222, 174, 255, 201, 30, 222, 174, 192, 143, 30, 222, 174, 192, 141, 30, - 222, 174, 234, 63, 30, 222, 174, 234, 62, 30, 222, 174, 234, 64, 30, 222, - 174, 192, 66, 30, 222, 174, 192, 65, 30, 222, 174, 212, 10, 30, 222, 174, - 212, 11, 30, 222, 174, 212, 4, 30, 222, 174, 212, 9, 30, 222, 174, 212, - 7, 30, 222, 174, 192, 0, 30, 222, 174, 191, 255, 30, 222, 174, 191, 254, - 30, 222, 174, 192, 1, 30, 222, 174, 192, 2, 30, 222, 174, 196, 226, 30, - 222, 174, 196, 225, 30, 222, 174, 196, 223, 30, 222, 174, 196, 219, 30, - 222, 174, 196, 220, 30, 222, 174, 191, 220, 30, 222, 174, 191, 217, 30, - 222, 174, 191, 218, 30, 222, 174, 191, 212, 30, 222, 174, 191, 213, 30, - 222, 174, 191, 214, 30, 222, 174, 191, 216, 30, 222, 174, 233, 236, 30, - 222, 174, 233, 238, 30, 222, 174, 192, 32, 30, 222, 174, 228, 69, 30, - 222, 174, 228, 61, 30, 222, 174, 228, 64, 30, 222, 174, 228, 62, 30, 222, - 174, 228, 66, 30, 222, 174, 228, 68, 30, 222, 174, 251, 25, 30, 222, 174, - 251, 22, 30, 222, 174, 251, 20, 30, 222, 174, 251, 21, 30, 222, 174, 201, - 172, 30, 222, 174, 255, 203, 30, 222, 174, 192, 142, 30, 222, 174, 192, - 64, 30, 222, 174, 212, 6, 30, 222, 174, 212, 5, 30, 125, 221, 113, 30, - 125, 201, 167, 30, 125, 221, 106, 30, 125, 213, 204, 30, 125, 213, 202, - 30, 125, 213, 201, 30, 125, 198, 168, 30, 125, 206, 239, 30, 125, 206, - 234, 30, 125, 206, 231, 30, 125, 206, 224, 30, 125, 206, 219, 30, 125, - 206, 214, 30, 125, 206, 225, 30, 125, 206, 237, 30, 125, 216, 77, 30, - 125, 209, 169, 30, 125, 209, 158, 30, 125, 202, 160, 30, 125, 201, 161, - 30, 125, 223, 222, 30, 125, 243, 24, 30, 125, 243, 91, 30, 125, 221, 188, - 30, 125, 199, 7, 30, 125, 209, 209, 30, 125, 229, 142, 30, 125, 221, 107, - 30, 125, 221, 105, 30, 125, 213, 200, 30, 125, 213, 194, 30, 125, 213, - 196, 30, 125, 213, 199, 30, 125, 213, 195, 30, 125, 198, 165, 30, 125, - 198, 162, 30, 125, 206, 232, 30, 125, 206, 227, 30, 125, 206, 213, 30, - 125, 206, 212, 30, 125, 201, 163, 30, 125, 206, 229, 30, 125, 206, 228, - 30, 125, 206, 221, 30, 125, 206, 223, 30, 125, 206, 236, 30, 125, 206, - 216, 30, 125, 206, 226, 30, 125, 206, 235, 30, 125, 206, 211, 30, 125, - 216, 73, 30, 125, 216, 68, 30, 125, 216, 70, 30, 125, 216, 67, 30, 125, - 216, 65, 30, 125, 216, 71, 30, 125, 216, 76, 30, 125, 216, 74, 30, 125, - 222, 71, 30, 125, 209, 160, 30, 125, 209, 161, 30, 125, 209, 166, 30, - 125, 222, 69, 30, 125, 202, 153, 30, 125, 202, 143, 30, 125, 202, 146, - 30, 125, 202, 148, 30, 125, 210, 149, 30, 125, 223, 217, 30, 125, 223, - 210, 30, 125, 201, 168, 30, 125, 223, 218, 30, 125, 192, 57, 30, 125, - 192, 51, 30, 125, 192, 52, 30, 125, 209, 207, 30, 125, 222, 70, 30, 125, - 229, 140, 30, 125, 229, 138, 30, 125, 229, 141, 30, 125, 229, 139, 30, - 125, 192, 63, 30, 125, 221, 109, 30, 125, 221, 108, 30, 125, 221, 112, - 30, 125, 221, 110, 30, 125, 221, 111, 30, 125, 201, 165, 36, 5, 140, 36, - 5, 228, 159, 36, 5, 229, 158, 36, 5, 230, 91, 36, 5, 229, 215, 36, 5, - 229, 245, 36, 5, 229, 23, 36, 5, 229, 14, 36, 5, 173, 36, 5, 218, 225, - 36, 5, 219, 146, 36, 5, 220, 125, 36, 5, 219, 228, 36, 5, 219, 238, 36, - 5, 219, 43, 36, 5, 218, 191, 36, 5, 229, 177, 36, 5, 229, 171, 36, 5, - 229, 173, 36, 5, 229, 176, 36, 5, 229, 174, 36, 5, 229, 175, 36, 5, 229, - 172, 36, 5, 229, 170, 36, 5, 174, 36, 5, 215, 155, 36, 5, 216, 100, 36, - 5, 217, 151, 36, 5, 216, 211, 36, 5, 216, 232, 36, 5, 216, 12, 36, 5, - 215, 80, 36, 5, 200, 54, 36, 5, 200, 48, 36, 5, 200, 50, 36, 5, 200, 53, + 1, 219, 75, 80, 1, 65, 80, 1, 203, 140, 65, 80, 1, 68, 80, 1, 223, 201, + 80, 1, 66, 80, 1, 196, 30, 80, 1, 71, 80, 1, 215, 234, 71, 80, 1, 74, 80, + 1, 250, 165, 80, 18, 3, 199, 200, 252, 208, 80, 18, 3, 252, 208, 80, 18, + 3, 68, 80, 18, 3, 223, 201, 80, 18, 3, 66, 80, 18, 3, 196, 30, 80, 18, 3, + 71, 80, 18, 3, 251, 238, 80, 18, 3, 215, 234, 223, 201, 80, 18, 3, 215, + 234, 74, 80, 18, 3, 235, 17, 58, 80, 3, 251, 73, 80, 3, 75, 60, 80, 3, + 195, 35, 80, 3, 195, 40, 80, 3, 250, 216, 80, 120, 3, 216, 219, 170, 80, + 120, 3, 216, 219, 165, 80, 120, 3, 216, 219, 193, 190, 80, 120, 3, 216, + 219, 140, 80, 1, 230, 208, 188, 80, 17, 191, 77, 80, 17, 107, 80, 17, + 109, 80, 17, 138, 80, 17, 134, 80, 17, 150, 80, 17, 169, 80, 17, 175, 80, + 17, 171, 80, 17, 178, 80, 3, 219, 85, 205, 54, 80, 3, 205, 54, 80, 16, + 219, 38, 80, 16, 242, 69, 80, 16, 252, 3, 80, 16, 231, 148, 80, 1, 203, + 166, 80, 1, 201, 176, 80, 1, 117, 146, 80, 1, 117, 206, 111, 80, 1, 117, + 172, 80, 1, 117, 219, 76, 80, 18, 3, 117, 146, 80, 18, 3, 117, 206, 111, + 80, 18, 3, 117, 172, 80, 18, 3, 117, 219, 76, 80, 1, 215, 234, 214, 70, + 80, 1, 215, 234, 222, 254, 80, 1, 215, 234, 249, 55, 80, 1, 215, 234, + 249, 50, 80, 120, 3, 215, 234, 216, 219, 181, 80, 120, 3, 215, 234, 216, + 219, 174, 80, 120, 3, 215, 234, 216, 219, 173, 80, 1, 203, 172, 222, 64, + 203, 166, 80, 18, 3, 203, 172, 222, 64, 233, 244, 80, 163, 87, 203, 172, + 222, 64, 230, 7, 80, 163, 87, 203, 172, 222, 64, 222, 25, 209, 201, 80, + 1, 193, 102, 208, 118, 222, 64, 199, 49, 80, 1, 193, 102, 208, 118, 222, + 64, 208, 124, 80, 18, 3, 193, 102, 208, 118, 222, 64, 233, 244, 80, 18, + 3, 193, 102, 208, 118, 222, 64, 196, 152, 80, 3, 193, 102, 208, 118, 222, + 64, 198, 78, 80, 3, 193, 102, 208, 118, 222, 64, 198, 77, 80, 3, 193, + 102, 208, 118, 222, 64, 198, 76, 80, 3, 193, 102, 208, 118, 222, 64, 198, + 75, 80, 3, 193, 102, 208, 118, 222, 64, 198, 74, 80, 1, 234, 204, 208, + 118, 222, 64, 213, 81, 80, 1, 234, 204, 208, 118, 222, 64, 191, 183, 80, + 1, 234, 204, 208, 118, 222, 64, 231, 58, 80, 18, 3, 231, 163, 222, 64, + 68, 80, 18, 3, 222, 30, 211, 153, 80, 18, 3, 222, 30, 66, 80, 18, 3, 222, + 30, 234, 190, 80, 1, 203, 140, 155, 80, 1, 203, 140, 221, 217, 80, 1, + 203, 140, 231, 242, 80, 1, 203, 140, 247, 162, 80, 1, 203, 140, 191, 123, + 80, 1, 203, 140, 212, 103, 80, 1, 203, 140, 238, 34, 80, 1, 203, 140, + 181, 80, 1, 203, 140, 209, 230, 80, 1, 203, 140, 233, 111, 80, 1, 203, + 140, 249, 155, 80, 1, 203, 140, 199, 49, 80, 1, 203, 140, 140, 80, 120, + 3, 203, 140, 216, 219, 193, 190, 80, 18, 3, 203, 140, 252, 208, 80, 18, + 3, 203, 140, 71, 80, 18, 3, 203, 140, 235, 17, 58, 80, 18, 3, 203, 140, + 53, 192, 159, 80, 3, 203, 140, 198, 77, 80, 3, 203, 140, 198, 76, 80, 3, + 203, 140, 198, 74, 80, 3, 203, 140, 198, 73, 80, 3, 203, 140, 238, 249, + 198, 77, 80, 3, 203, 140, 238, 249, 198, 76, 80, 3, 203, 140, 238, 249, + 234, 108, 198, 79, 80, 1, 206, 48, 210, 191, 233, 111, 80, 3, 206, 48, + 210, 191, 198, 74, 80, 203, 140, 17, 191, 77, 80, 203, 140, 17, 107, 80, + 203, 140, 17, 109, 80, 203, 140, 17, 138, 80, 203, 140, 17, 134, 80, 203, + 140, 17, 150, 80, 203, 140, 17, 169, 80, 203, 140, 17, 175, 80, 203, 140, + 17, 171, 80, 203, 140, 17, 178, 80, 3, 221, 208, 198, 78, 80, 3, 221, + 208, 198, 76, 80, 18, 3, 251, 224, 65, 80, 18, 3, 251, 224, 251, 238, 80, + 16, 203, 140, 107, 80, 16, 203, 140, 233, 217, 101, 6, 1, 251, 134, 101, + 6, 1, 249, 103, 101, 6, 1, 231, 212, 101, 6, 1, 236, 152, 101, 6, 1, 234, + 105, 101, 6, 1, 195, 49, 101, 6, 1, 191, 80, 101, 6, 1, 199, 193, 101, 6, + 1, 223, 164, 101, 6, 1, 222, 89, 101, 6, 1, 220, 9, 101, 6, 1, 217, 92, + 101, 6, 1, 214, 218, 101, 6, 1, 211, 106, 101, 6, 1, 210, 133, 101, 6, 1, + 191, 67, 101, 6, 1, 207, 165, 101, 6, 1, 205, 143, 101, 6, 1, 199, 179, + 101, 6, 1, 196, 113, 101, 6, 1, 209, 222, 101, 6, 1, 221, 202, 101, 6, 1, + 231, 84, 101, 6, 1, 208, 83, 101, 6, 1, 203, 70, 101, 6, 1, 243, 83, 101, + 6, 1, 247, 130, 101, 6, 1, 222, 236, 101, 6, 1, 243, 20, 101, 6, 1, 246, + 243, 101, 6, 1, 192, 218, 101, 6, 1, 222, 251, 101, 6, 1, 230, 89, 101, + 6, 1, 229, 247, 101, 6, 1, 229, 147, 101, 6, 1, 193, 125, 101, 6, 1, 230, + 21, 101, 6, 1, 229, 13, 101, 6, 1, 192, 14, 101, 6, 1, 252, 16, 101, 1, + 251, 134, 101, 1, 249, 103, 101, 1, 231, 212, 101, 1, 236, 152, 101, 1, + 234, 105, 101, 1, 195, 49, 101, 1, 191, 80, 101, 1, 199, 193, 101, 1, + 223, 164, 101, 1, 222, 89, 101, 1, 220, 9, 101, 1, 217, 92, 101, 1, 214, + 218, 101, 1, 211, 106, 101, 1, 210, 133, 101, 1, 191, 67, 101, 1, 207, + 165, 101, 1, 205, 143, 101, 1, 199, 179, 101, 1, 196, 113, 101, 1, 209, + 222, 101, 1, 221, 202, 101, 1, 231, 84, 101, 1, 208, 83, 101, 1, 203, 70, + 101, 1, 243, 83, 101, 1, 247, 130, 101, 1, 222, 236, 101, 1, 243, 20, + 101, 1, 246, 243, 101, 1, 192, 218, 101, 1, 222, 251, 101, 1, 230, 89, + 101, 1, 229, 247, 101, 1, 229, 147, 101, 1, 193, 125, 101, 1, 230, 21, + 101, 1, 229, 13, 101, 1, 233, 25, 101, 1, 192, 14, 101, 1, 234, 125, 101, + 1, 154, 231, 212, 101, 1, 251, 232, 101, 210, 130, 204, 11, 52, 1, 101, + 214, 218, 101, 1, 252, 16, 101, 1, 230, 19, 56, 101, 1, 220, 118, 56, 30, + 147, 221, 115, 30, 147, 201, 168, 30, 147, 213, 206, 30, 147, 198, 168, + 30, 147, 201, 157, 30, 147, 206, 240, 30, 147, 216, 79, 30, 147, 209, + 171, 30, 147, 201, 165, 30, 147, 202, 161, 30, 147, 201, 162, 30, 147, + 223, 224, 30, 147, 243, 26, 30, 147, 201, 172, 30, 147, 243, 93, 30, 147, + 221, 190, 30, 147, 199, 7, 30, 147, 209, 211, 30, 147, 229, 144, 30, 147, + 213, 202, 30, 147, 201, 166, 30, 147, 213, 196, 30, 147, 213, 200, 30, + 147, 198, 165, 30, 147, 206, 228, 30, 147, 201, 164, 30, 147, 206, 238, + 30, 147, 222, 70, 30, 147, 216, 72, 30, 147, 222, 73, 30, 147, 209, 166, + 30, 147, 209, 164, 30, 147, 209, 152, 30, 147, 209, 160, 30, 147, 209, + 158, 30, 147, 209, 155, 30, 147, 209, 157, 30, 147, 209, 154, 30, 147, + 209, 159, 30, 147, 209, 169, 30, 147, 209, 170, 30, 147, 209, 153, 30, + 147, 209, 163, 30, 147, 222, 71, 30, 147, 222, 69, 30, 147, 202, 154, 30, + 147, 202, 152, 30, 147, 202, 144, 30, 147, 202, 147, 30, 147, 202, 153, + 30, 147, 202, 149, 30, 147, 202, 148, 30, 147, 202, 146, 30, 147, 202, + 157, 30, 147, 202, 159, 30, 147, 202, 160, 30, 147, 202, 155, 30, 147, + 202, 145, 30, 147, 202, 150, 30, 147, 202, 158, 30, 147, 243, 74, 30, + 147, 243, 72, 30, 147, 247, 16, 30, 147, 247, 14, 30, 147, 210, 151, 30, + 147, 223, 219, 30, 147, 223, 210, 30, 147, 223, 218, 30, 147, 223, 215, + 30, 147, 223, 213, 30, 147, 223, 217, 30, 147, 201, 169, 30, 147, 223, + 222, 30, 147, 223, 223, 30, 147, 223, 211, 30, 147, 223, 216, 30, 147, + 192, 57, 30, 147, 243, 25, 30, 147, 243, 75, 30, 147, 243, 73, 30, 147, + 247, 17, 30, 147, 247, 15, 30, 147, 243, 91, 30, 147, 243, 92, 30, 147, + 243, 76, 30, 147, 247, 18, 30, 147, 209, 209, 30, 147, 222, 72, 30, 147, + 201, 170, 30, 147, 192, 63, 30, 147, 221, 106, 30, 147, 213, 198, 30, + 147, 213, 204, 30, 147, 213, 203, 30, 147, 198, 162, 30, 147, 233, 5, 30, + 222, 176, 233, 5, 30, 222, 176, 65, 30, 222, 176, 252, 27, 30, 222, 176, + 170, 30, 222, 176, 192, 129, 30, 222, 176, 234, 67, 30, 222, 176, 71, 30, + 222, 176, 192, 67, 30, 222, 176, 192, 80, 30, 222, 176, 74, 30, 222, 176, + 193, 190, 30, 222, 176, 193, 176, 30, 222, 176, 211, 153, 30, 222, 176, + 192, 12, 30, 222, 176, 66, 30, 222, 176, 193, 107, 30, 222, 176, 193, + 125, 30, 222, 176, 193, 86, 30, 222, 176, 191, 225, 30, 222, 176, 233, + 244, 30, 222, 176, 192, 33, 30, 222, 176, 68, 30, 222, 176, 255, 204, 30, + 222, 176, 255, 203, 30, 222, 176, 192, 143, 30, 222, 176, 192, 141, 30, + 222, 176, 234, 65, 30, 222, 176, 234, 64, 30, 222, 176, 234, 66, 30, 222, + 176, 192, 66, 30, 222, 176, 192, 65, 30, 222, 176, 212, 12, 30, 222, 176, + 212, 13, 30, 222, 176, 212, 6, 30, 222, 176, 212, 11, 30, 222, 176, 212, + 9, 30, 222, 176, 192, 0, 30, 222, 176, 191, 255, 30, 222, 176, 191, 254, + 30, 222, 176, 192, 1, 30, 222, 176, 192, 2, 30, 222, 176, 196, 226, 30, + 222, 176, 196, 225, 30, 222, 176, 196, 223, 30, 222, 176, 196, 219, 30, + 222, 176, 196, 220, 30, 222, 176, 191, 220, 30, 222, 176, 191, 217, 30, + 222, 176, 191, 218, 30, 222, 176, 191, 212, 30, 222, 176, 191, 213, 30, + 222, 176, 191, 214, 30, 222, 176, 191, 216, 30, 222, 176, 233, 238, 30, + 222, 176, 233, 240, 30, 222, 176, 192, 32, 30, 222, 176, 228, 71, 30, + 222, 176, 228, 63, 30, 222, 176, 228, 66, 30, 222, 176, 228, 64, 30, 222, + 176, 228, 68, 30, 222, 176, 228, 70, 30, 222, 176, 251, 27, 30, 222, 176, + 251, 24, 30, 222, 176, 251, 22, 30, 222, 176, 251, 23, 30, 222, 176, 201, + 173, 30, 222, 176, 255, 205, 30, 222, 176, 192, 142, 30, 222, 176, 192, + 64, 30, 222, 176, 212, 8, 30, 222, 176, 212, 7, 30, 125, 221, 115, 30, + 125, 201, 168, 30, 125, 221, 108, 30, 125, 213, 206, 30, 125, 213, 204, + 30, 125, 213, 203, 30, 125, 198, 168, 30, 125, 206, 240, 30, 125, 206, + 235, 30, 125, 206, 232, 30, 125, 206, 225, 30, 125, 206, 220, 30, 125, + 206, 215, 30, 125, 206, 226, 30, 125, 206, 238, 30, 125, 216, 79, 30, + 125, 209, 171, 30, 125, 209, 160, 30, 125, 202, 161, 30, 125, 201, 162, + 30, 125, 223, 224, 30, 125, 243, 26, 30, 125, 243, 93, 30, 125, 221, 190, + 30, 125, 199, 7, 30, 125, 209, 211, 30, 125, 229, 144, 30, 125, 221, 109, + 30, 125, 221, 107, 30, 125, 213, 202, 30, 125, 213, 196, 30, 125, 213, + 198, 30, 125, 213, 201, 30, 125, 213, 197, 30, 125, 198, 165, 30, 125, + 198, 162, 30, 125, 206, 233, 30, 125, 206, 228, 30, 125, 206, 214, 30, + 125, 206, 213, 30, 125, 201, 164, 30, 125, 206, 230, 30, 125, 206, 229, + 30, 125, 206, 222, 30, 125, 206, 224, 30, 125, 206, 237, 30, 125, 206, + 217, 30, 125, 206, 227, 30, 125, 206, 236, 30, 125, 206, 212, 30, 125, + 216, 75, 30, 125, 216, 70, 30, 125, 216, 72, 30, 125, 216, 69, 30, 125, + 216, 67, 30, 125, 216, 73, 30, 125, 216, 78, 30, 125, 216, 76, 30, 125, + 222, 73, 30, 125, 209, 162, 30, 125, 209, 163, 30, 125, 209, 168, 30, + 125, 222, 71, 30, 125, 202, 154, 30, 125, 202, 144, 30, 125, 202, 147, + 30, 125, 202, 149, 30, 125, 210, 151, 30, 125, 223, 219, 30, 125, 223, + 212, 30, 125, 201, 169, 30, 125, 223, 220, 30, 125, 192, 57, 30, 125, + 192, 51, 30, 125, 192, 52, 30, 125, 209, 209, 30, 125, 222, 72, 30, 125, + 229, 142, 30, 125, 229, 140, 30, 125, 229, 143, 30, 125, 229, 141, 30, + 125, 192, 63, 30, 125, 221, 111, 30, 125, 221, 110, 30, 125, 221, 114, + 30, 125, 221, 112, 30, 125, 221, 113, 30, 125, 201, 166, 36, 5, 140, 36, + 5, 228, 161, 36, 5, 229, 160, 36, 5, 230, 93, 36, 5, 229, 217, 36, 5, + 229, 247, 36, 5, 229, 25, 36, 5, 229, 16, 36, 5, 173, 36, 5, 218, 227, + 36, 5, 219, 148, 36, 5, 220, 127, 36, 5, 219, 230, 36, 5, 219, 240, 36, + 5, 219, 45, 36, 5, 218, 193, 36, 5, 229, 179, 36, 5, 229, 173, 36, 5, + 229, 175, 36, 5, 229, 178, 36, 5, 229, 176, 36, 5, 229, 177, 36, 5, 229, + 174, 36, 5, 229, 172, 36, 5, 174, 36, 5, 215, 157, 36, 5, 216, 102, 36, + 5, 217, 153, 36, 5, 216, 213, 36, 5, 216, 234, 36, 5, 216, 14, 36, 5, + 215, 82, 36, 5, 200, 54, 36, 5, 200, 48, 36, 5, 200, 50, 36, 5, 200, 53, 36, 5, 200, 51, 36, 5, 200, 52, 36, 5, 200, 49, 36, 5, 200, 47, 36, 5, - 165, 36, 5, 206, 68, 36, 5, 207, 1, 36, 5, 207, 178, 36, 5, 207, 84, 36, - 5, 207, 113, 36, 5, 206, 162, 36, 5, 206, 26, 36, 5, 188, 36, 5, 201, 4, - 36, 5, 202, 222, 36, 5, 205, 197, 36, 5, 205, 50, 36, 5, 205, 68, 36, 5, - 202, 46, 36, 5, 200, 150, 36, 5, 203, 165, 36, 5, 203, 5, 36, 5, 203, 81, - 36, 5, 203, 160, 36, 5, 203, 111, 36, 5, 203, 113, 36, 5, 203, 56, 36, 5, - 202, 240, 36, 5, 208, 96, 36, 5, 208, 33, 36, 5, 208, 57, 36, 5, 208, 95, - 36, 5, 208, 74, 36, 5, 208, 75, 36, 5, 208, 45, 36, 5, 208, 44, 36, 5, - 207, 240, 36, 5, 207, 236, 36, 5, 207, 239, 36, 5, 207, 237, 36, 5, 207, - 238, 36, 5, 208, 71, 36, 5, 208, 63, 36, 5, 208, 66, 36, 5, 208, 70, 36, - 5, 208, 67, 36, 5, 208, 68, 36, 5, 208, 65, 36, 5, 208, 62, 36, 5, 208, - 58, 36, 5, 208, 61, 36, 5, 208, 59, 36, 5, 208, 60, 36, 5, 249, 153, 36, - 5, 248, 10, 36, 5, 248, 188, 36, 5, 249, 151, 36, 5, 249, 1, 36, 5, 249, - 17, 36, 5, 248, 111, 36, 5, 247, 210, 36, 5, 195, 188, 36, 5, 193, 249, + 165, 36, 5, 206, 69, 36, 5, 207, 2, 36, 5, 207, 180, 36, 5, 207, 86, 36, + 5, 207, 115, 36, 5, 206, 163, 36, 5, 206, 27, 36, 5, 188, 36, 5, 201, 5, + 36, 5, 202, 223, 36, 5, 205, 198, 36, 5, 205, 51, 36, 5, 205, 69, 36, 5, + 202, 47, 36, 5, 200, 150, 36, 5, 203, 166, 36, 5, 203, 6, 36, 5, 203, 82, + 36, 5, 203, 161, 36, 5, 203, 112, 36, 5, 203, 114, 36, 5, 203, 57, 36, 5, + 202, 241, 36, 5, 208, 98, 36, 5, 208, 35, 36, 5, 208, 59, 36, 5, 208, 97, + 36, 5, 208, 76, 36, 5, 208, 77, 36, 5, 208, 47, 36, 5, 208, 46, 36, 5, + 207, 242, 36, 5, 207, 238, 36, 5, 207, 241, 36, 5, 207, 239, 36, 5, 207, + 240, 36, 5, 208, 73, 36, 5, 208, 65, 36, 5, 208, 68, 36, 5, 208, 72, 36, + 5, 208, 69, 36, 5, 208, 70, 36, 5, 208, 67, 36, 5, 208, 64, 36, 5, 208, + 60, 36, 5, 208, 63, 36, 5, 208, 61, 36, 5, 208, 62, 36, 5, 249, 155, 36, + 5, 248, 12, 36, 5, 248, 190, 36, 5, 249, 153, 36, 5, 249, 3, 36, 5, 249, + 19, 36, 5, 248, 113, 36, 5, 247, 212, 36, 5, 195, 188, 36, 5, 193, 249, 36, 5, 195, 69, 36, 5, 195, 187, 36, 5, 195, 148, 36, 5, 195, 153, 36, 5, 195, 24, 36, 5, 193, 238, 36, 5, 190, 190, 36, 5, 197, 94, 36, 5, 198, 193, 36, 5, 199, 245, 36, 5, 199, 121, 36, 5, 199, 145, 36, 5, 159, 36, - 5, 197, 43, 36, 5, 247, 160, 36, 5, 238, 195, 36, 5, 243, 29, 36, 5, 247, - 159, 36, 5, 247, 34, 36, 5, 247, 42, 36, 5, 242, 99, 36, 5, 238, 151, 36, - 5, 192, 220, 36, 5, 192, 188, 36, 5, 192, 207, 36, 5, 192, 219, 36, 5, - 192, 213, 36, 5, 192, 214, 36, 5, 192, 196, 36, 5, 192, 195, 36, 5, 192, - 181, 36, 5, 192, 177, 36, 5, 192, 180, 36, 5, 192, 178, 36, 5, 192, 179, - 36, 5, 180, 36, 5, 212, 178, 36, 5, 213, 219, 36, 5, 214, 250, 36, 5, - 214, 110, 36, 5, 214, 121, 36, 5, 213, 43, 36, 5, 212, 110, 36, 5, 212, - 101, 36, 5, 212, 58, 36, 5, 212, 81, 36, 5, 212, 100, 36, 5, 212, 89, 36, - 5, 212, 90, 36, 5, 212, 65, 36, 5, 212, 48, 36, 5, 231, 11, 65, 36, 5, - 231, 11, 66, 36, 5, 231, 11, 68, 36, 5, 231, 11, 252, 206, 36, 5, 231, - 11, 234, 188, 36, 5, 231, 11, 71, 36, 5, 231, 11, 74, 36, 5, 231, 11, - 193, 190, 36, 5, 155, 36, 5, 220, 232, 36, 5, 221, 166, 36, 5, 222, 127, - 36, 5, 222, 13, 36, 5, 222, 22, 36, 5, 221, 67, 36, 5, 221, 62, 36, 5, - 220, 179, 36, 5, 220, 172, 36, 5, 220, 178, 36, 5, 220, 173, 36, 5, 220, - 174, 36, 5, 220, 165, 36, 5, 220, 159, 36, 5, 220, 161, 36, 5, 220, 164, - 36, 5, 220, 162, 36, 5, 220, 163, 36, 5, 220, 160, 36, 5, 220, 158, 36, - 5, 220, 154, 36, 5, 220, 157, 36, 5, 220, 155, 36, 5, 220, 156, 36, 5, - 193, 190, 36, 5, 193, 0, 36, 5, 193, 86, 36, 5, 193, 181, 36, 5, 193, - 114, 36, 5, 193, 125, 36, 5, 193, 48, 36, 5, 193, 40, 36, 5, 209, 219, - 65, 36, 5, 209, 219, 66, 36, 5, 209, 219, 68, 36, 5, 209, 219, 252, 206, - 36, 5, 209, 219, 234, 188, 36, 5, 209, 219, 71, 36, 5, 209, 219, 74, 36, + 5, 197, 43, 36, 5, 247, 162, 36, 5, 238, 197, 36, 5, 243, 31, 36, 5, 247, + 161, 36, 5, 247, 36, 36, 5, 247, 44, 36, 5, 242, 101, 36, 5, 238, 153, + 36, 5, 192, 220, 36, 5, 192, 188, 36, 5, 192, 207, 36, 5, 192, 219, 36, + 5, 192, 213, 36, 5, 192, 214, 36, 5, 192, 196, 36, 5, 192, 195, 36, 5, + 192, 181, 36, 5, 192, 177, 36, 5, 192, 180, 36, 5, 192, 178, 36, 5, 192, + 179, 36, 5, 181, 36, 5, 212, 180, 36, 5, 213, 221, 36, 5, 214, 252, 36, + 5, 214, 112, 36, 5, 214, 123, 36, 5, 213, 45, 36, 5, 212, 112, 36, 5, + 212, 103, 36, 5, 212, 60, 36, 5, 212, 83, 36, 5, 212, 102, 36, 5, 212, + 91, 36, 5, 212, 92, 36, 5, 212, 67, 36, 5, 212, 50, 36, 5, 231, 13, 65, + 36, 5, 231, 13, 66, 36, 5, 231, 13, 68, 36, 5, 231, 13, 252, 208, 36, 5, + 231, 13, 234, 190, 36, 5, 231, 13, 71, 36, 5, 231, 13, 74, 36, 5, 231, + 13, 193, 190, 36, 5, 155, 36, 5, 220, 234, 36, 5, 221, 168, 36, 5, 222, + 129, 36, 5, 222, 15, 36, 5, 222, 24, 36, 5, 221, 69, 36, 5, 221, 64, 36, + 5, 220, 181, 36, 5, 220, 174, 36, 5, 220, 180, 36, 5, 220, 175, 36, 5, + 220, 176, 36, 5, 220, 167, 36, 5, 220, 161, 36, 5, 220, 163, 36, 5, 220, + 166, 36, 5, 220, 164, 36, 5, 220, 165, 36, 5, 220, 162, 36, 5, 220, 160, + 36, 5, 220, 156, 36, 5, 220, 159, 36, 5, 220, 157, 36, 5, 220, 158, 36, + 5, 193, 190, 36, 5, 193, 0, 36, 5, 193, 86, 36, 5, 193, 181, 36, 5, 193, + 114, 36, 5, 193, 125, 36, 5, 193, 48, 36, 5, 193, 40, 36, 5, 209, 221, + 65, 36, 5, 209, 221, 66, 36, 5, 209, 221, 68, 36, 5, 209, 221, 252, 208, + 36, 5, 209, 221, 234, 190, 36, 5, 209, 221, 71, 36, 5, 209, 221, 74, 36, 5, 191, 123, 36, 5, 190, 251, 36, 5, 191, 30, 36, 5, 191, 121, 36, 5, 191, 84, 36, 5, 191, 87, 36, 5, 191, 7, 36, 5, 190, 238, 36, 5, 191, 71, 36, 5, 191, 48, 36, 5, 191, 57, 36, 5, 191, 70, 36, 5, 191, 61, 36, 5, 191, 62, 36, 5, 191, 54, 36, 5, 191, 39, 36, 5, 170, 36, 5, 191, 225, 36, 5, 192, 33, 36, 5, 192, 140, 36, 5, 192, 77, 36, 5, 192, 80, 36, 5, 192, - 12, 36, 5, 191, 252, 36, 5, 238, 32, 36, 5, 235, 89, 36, 5, 237, 44, 36, - 5, 238, 31, 36, 5, 237, 131, 36, 5, 237, 146, 36, 5, 236, 174, 36, 5, - 235, 46, 36, 5, 237, 191, 36, 5, 237, 156, 36, 5, 237, 168, 36, 5, 237, - 190, 36, 5, 237, 178, 36, 5, 237, 179, 36, 5, 237, 161, 36, 5, 237, 147, - 36, 5, 223, 32, 36, 5, 222, 182, 36, 5, 222, 244, 36, 5, 223, 31, 36, 5, - 223, 8, 36, 5, 223, 10, 36, 5, 222, 201, 36, 5, 222, 160, 36, 5, 231, - 240, 36, 5, 230, 179, 36, 5, 231, 53, 36, 5, 231, 237, 36, 5, 231, 157, - 36, 5, 231, 165, 36, 5, 231, 3, 36, 5, 231, 2, 36, 5, 230, 135, 36, 5, - 230, 131, 36, 5, 230, 134, 36, 5, 230, 132, 36, 5, 230, 133, 36, 5, 231, - 127, 36, 5, 231, 107, 36, 5, 231, 117, 36, 5, 231, 126, 36, 5, 231, 121, - 36, 5, 231, 122, 36, 5, 231, 111, 36, 5, 231, 96, 36, 5, 199, 49, 36, 5, + 12, 36, 5, 191, 252, 36, 5, 238, 34, 36, 5, 235, 91, 36, 5, 237, 46, 36, + 5, 238, 33, 36, 5, 237, 133, 36, 5, 237, 148, 36, 5, 236, 176, 36, 5, + 235, 48, 36, 5, 237, 193, 36, 5, 237, 158, 36, 5, 237, 170, 36, 5, 237, + 192, 36, 5, 237, 180, 36, 5, 237, 181, 36, 5, 237, 163, 36, 5, 237, 149, + 36, 5, 223, 34, 36, 5, 222, 184, 36, 5, 222, 246, 36, 5, 223, 33, 36, 5, + 223, 10, 36, 5, 223, 12, 36, 5, 222, 203, 36, 5, 222, 162, 36, 5, 231, + 242, 36, 5, 230, 181, 36, 5, 231, 55, 36, 5, 231, 239, 36, 5, 231, 159, + 36, 5, 231, 167, 36, 5, 231, 5, 36, 5, 231, 4, 36, 5, 230, 137, 36, 5, + 230, 133, 36, 5, 230, 136, 36, 5, 230, 134, 36, 5, 230, 135, 36, 5, 231, + 129, 36, 5, 231, 109, 36, 5, 231, 119, 36, 5, 231, 128, 36, 5, 231, 123, + 36, 5, 231, 124, 36, 5, 231, 113, 36, 5, 231, 98, 36, 5, 199, 49, 36, 5, 198, 213, 36, 5, 199, 11, 36, 5, 199, 48, 36, 5, 199, 31, 36, 5, 199, 33, - 36, 5, 198, 241, 36, 5, 198, 204, 36, 5, 247, 1, 36, 5, 243, 48, 36, 5, - 243, 95, 36, 5, 247, 0, 36, 5, 243, 123, 36, 5, 243, 127, 36, 5, 243, 68, - 36, 5, 243, 37, 36, 5, 209, 228, 36, 5, 209, 191, 36, 5, 209, 211, 36, 5, - 209, 227, 36, 5, 209, 213, 36, 5, 209, 214, 36, 5, 209, 199, 36, 5, 209, - 187, 36, 5, 197, 168, 36, 5, 197, 140, 36, 5, 197, 146, 36, 5, 197, 167, + 36, 5, 198, 241, 36, 5, 198, 204, 36, 5, 247, 3, 36, 5, 243, 50, 36, 5, + 243, 97, 36, 5, 247, 2, 36, 5, 243, 125, 36, 5, 243, 129, 36, 5, 243, 70, + 36, 5, 243, 39, 36, 5, 209, 230, 36, 5, 209, 193, 36, 5, 209, 213, 36, 5, + 209, 229, 36, 5, 209, 215, 36, 5, 209, 216, 36, 5, 209, 201, 36, 5, 209, + 189, 36, 5, 197, 168, 36, 5, 197, 140, 36, 5, 197, 146, 36, 5, 197, 167, 36, 5, 197, 160, 36, 5, 197, 161, 36, 5, 197, 144, 36, 5, 197, 138, 36, 5, 196, 240, 36, 5, 196, 232, 36, 5, 196, 236, 36, 5, 196, 239, 36, 5, 196, 237, 36, 5, 196, 238, 36, 5, 196, 234, 36, 5, 196, 233, 36, 5, 233, - 109, 36, 5, 232, 86, 36, 5, 233, 23, 36, 5, 233, 108, 36, 5, 233, 52, 36, - 5, 233, 59, 36, 5, 232, 175, 36, 5, 232, 62, 36, 5, 168, 36, 5, 208, 165, - 36, 5, 209, 185, 36, 5, 210, 220, 36, 5, 210, 49, 36, 5, 210, 63, 36, 5, - 209, 73, 36, 5, 208, 122, 36, 5, 206, 16, 36, 5, 215, 68, 36, 5, 232, 56, - 36, 33, 231, 153, 23, 18, 219, 198, 77, 36, 33, 18, 219, 198, 77, 36, 33, - 231, 153, 77, 36, 205, 54, 77, 36, 193, 22, 36, 232, 80, 201, 63, 36, - 242, 74, 36, 204, 25, 36, 242, 83, 36, 208, 228, 242, 83, 36, 208, 13, - 77, 36, 210, 128, 204, 10, 36, 17, 107, 36, 17, 109, 36, 17, 138, 36, 17, - 134, 36, 17, 149, 36, 17, 169, 36, 17, 175, 36, 17, 171, 36, 17, 178, 36, - 31, 199, 95, 36, 31, 197, 32, 36, 31, 198, 249, 36, 31, 232, 135, 36, 31, - 233, 15, 36, 31, 202, 120, 36, 31, 203, 241, 36, 31, 234, 153, 36, 31, - 213, 169, 36, 31, 228, 140, 36, 31, 199, 96, 189, 36, 5, 205, 59, 215, - 80, 36, 5, 215, 76, 36, 5, 215, 77, 36, 5, 215, 78, 36, 5, 205, 59, 247, - 210, 36, 5, 247, 207, 36, 5, 247, 208, 36, 5, 247, 209, 36, 5, 205, 59, - 232, 62, 36, 5, 232, 58, 36, 5, 232, 59, 36, 5, 232, 60, 36, 5, 205, 59, - 208, 122, 36, 5, 208, 118, 36, 5, 208, 119, 36, 5, 208, 120, 36, 198, 80, - 87, 192, 15, 36, 198, 80, 87, 237, 89, 36, 198, 80, 87, 206, 194, 36, - 198, 80, 87, 203, 40, 206, 194, 36, 198, 80, 87, 237, 18, 36, 198, 80, - 87, 221, 250, 36, 198, 80, 87, 243, 76, 36, 198, 80, 87, 229, 147, 36, - 198, 80, 87, 237, 88, 36, 198, 80, 87, 220, 195, 103, 1, 65, 103, 1, 71, - 103, 1, 68, 103, 1, 74, 103, 1, 66, 103, 1, 196, 12, 103, 1, 231, 240, - 103, 1, 155, 103, 1, 231, 165, 103, 1, 231, 53, 103, 1, 231, 3, 103, 1, - 230, 179, 103, 1, 230, 138, 103, 1, 140, 103, 1, 229, 245, 103, 1, 229, - 158, 103, 1, 229, 23, 103, 1, 228, 159, 103, 1, 228, 126, 103, 1, 173, - 103, 1, 219, 238, 103, 1, 219, 146, 103, 1, 219, 43, 103, 1, 218, 225, - 103, 1, 218, 192, 103, 1, 174, 103, 1, 216, 232, 103, 1, 216, 100, 103, - 1, 216, 12, 103, 1, 215, 155, 103, 1, 180, 103, 1, 229, 47, 103, 1, 214, - 237, 103, 1, 214, 121, 103, 1, 213, 219, 103, 1, 213, 43, 103, 1, 212, - 178, 103, 1, 212, 112, 103, 1, 208, 32, 103, 1, 208, 16, 103, 1, 208, 9, - 103, 1, 207, 255, 103, 1, 207, 244, 103, 1, 207, 242, 103, 1, 188, 103, - 1, 206, 8, 103, 1, 205, 68, 103, 1, 202, 222, 103, 1, 202, 46, 103, 1, - 201, 4, 103, 1, 200, 158, 103, 1, 238, 32, 103, 1, 190, 190, 103, 1, 237, - 146, 103, 1, 199, 145, 103, 1, 237, 44, 103, 1, 198, 193, 103, 1, 236, - 174, 103, 1, 235, 89, 103, 1, 235, 57, 103, 1, 236, 186, 103, 1, 198, - 115, 103, 1, 198, 114, 103, 1, 198, 103, 103, 1, 198, 102, 103, 1, 198, - 101, 103, 1, 198, 100, 103, 1, 197, 168, 103, 1, 197, 161, 103, 1, 197, - 146, 103, 1, 197, 144, 103, 1, 197, 140, 103, 1, 197, 139, 103, 1, 193, - 190, 103, 1, 193, 125, 103, 1, 193, 86, 103, 1, 193, 48, 103, 1, 193, 0, - 103, 1, 192, 243, 103, 1, 170, 103, 1, 192, 80, 103, 1, 192, 33, 103, 1, - 192, 12, 103, 1, 191, 225, 103, 1, 191, 184, 103, 1, 215, 87, 103, 2, 1, - 192, 80, 103, 2, 1, 192, 33, 103, 2, 1, 192, 12, 103, 2, 1, 191, 225, - 103, 2, 1, 191, 184, 103, 2, 1, 215, 87, 21, 22, 228, 88, 21, 22, 71, 21, - 22, 252, 170, 21, 22, 68, 21, 22, 223, 199, 21, 22, 74, 21, 22, 211, 87, - 21, 22, 192, 158, 211, 87, 21, 22, 98, 234, 188, 21, 22, 98, 68, 21, 22, - 65, 21, 22, 252, 206, 21, 22, 193, 125, 21, 22, 193, 103, 193, 125, 21, - 22, 193, 86, 21, 22, 193, 103, 193, 86, 21, 22, 193, 70, 21, 22, 193, - 103, 193, 70, 21, 22, 193, 48, 21, 22, 193, 103, 193, 48, 21, 22, 193, - 29, 21, 22, 193, 103, 193, 29, 21, 22, 214, 209, 193, 29, 21, 22, 193, - 190, 21, 22, 193, 103, 193, 190, 21, 22, 193, 181, 21, 22, 193, 103, 193, - 181, 21, 22, 214, 209, 193, 181, 21, 22, 251, 236, 21, 22, 192, 158, 193, - 224, 21, 22, 231, 11, 201, 63, 21, 22, 53, 252, 46, 21, 22, 53, 230, 210, - 21, 22, 53, 248, 77, 132, 206, 188, 21, 22, 53, 198, 54, 132, 206, 188, - 21, 22, 53, 50, 132, 206, 188, 21, 22, 53, 206, 188, 21, 22, 53, 55, 252, - 46, 21, 22, 53, 55, 203, 40, 81, 201, 15, 21, 22, 53, 82, 236, 140, 21, - 22, 53, 203, 40, 228, 241, 106, 21, 22, 53, 209, 81, 21, 22, 53, 144, - 199, 228, 21, 22, 234, 103, 21, 22, 223, 162, 21, 22, 211, 104, 21, 22, - 251, 132, 21, 22, 210, 63, 21, 22, 210, 218, 21, 22, 209, 185, 21, 22, - 209, 145, 21, 22, 209, 73, 21, 22, 209, 37, 21, 22, 192, 158, 209, 37, - 21, 22, 98, 229, 215, 21, 22, 98, 229, 158, 21, 22, 168, 21, 22, 210, - 220, 21, 22, 208, 120, 21, 22, 193, 103, 208, 120, 21, 22, 208, 118, 21, - 22, 193, 103, 208, 118, 21, 22, 208, 117, 21, 22, 193, 103, 208, 117, 21, - 22, 208, 115, 21, 22, 193, 103, 208, 115, 21, 22, 208, 114, 21, 22, 193, - 103, 208, 114, 21, 22, 208, 122, 21, 22, 193, 103, 208, 122, 21, 22, 208, - 121, 21, 22, 193, 103, 208, 121, 21, 22, 192, 158, 208, 121, 21, 22, 210, - 236, 21, 22, 193, 103, 210, 236, 21, 22, 98, 230, 116, 21, 22, 199, 145, - 21, 22, 199, 242, 21, 22, 198, 193, 21, 22, 198, 170, 21, 22, 159, 21, - 22, 198, 59, 21, 22, 192, 158, 198, 59, 21, 22, 98, 237, 131, 21, 22, 98, - 237, 44, 21, 22, 190, 190, 21, 22, 199, 245, 21, 22, 197, 41, 21, 22, - 193, 103, 197, 41, 21, 22, 197, 19, 21, 22, 193, 103, 197, 19, 21, 22, - 197, 18, 21, 22, 193, 103, 197, 18, 21, 22, 109, 21, 22, 193, 103, 109, - 21, 22, 197, 9, 21, 22, 193, 103, 197, 9, 21, 22, 197, 43, 21, 22, 193, - 103, 197, 43, 21, 22, 197, 42, 21, 22, 193, 103, 197, 42, 21, 22, 214, - 209, 197, 42, 21, 22, 200, 43, 21, 22, 197, 127, 21, 22, 197, 111, 21, - 22, 197, 109, 21, 22, 197, 132, 21, 22, 222, 22, 21, 22, 222, 121, 21, - 22, 221, 166, 21, 22, 221, 145, 21, 22, 221, 67, 21, 22, 221, 41, 21, 22, - 192, 158, 221, 41, 21, 22, 155, 21, 22, 222, 127, 21, 22, 220, 174, 21, - 22, 193, 103, 220, 174, 21, 22, 220, 172, 21, 22, 193, 103, 220, 172, 21, - 22, 220, 171, 21, 22, 193, 103, 220, 171, 21, 22, 220, 169, 21, 22, 193, - 103, 220, 169, 21, 22, 220, 168, 21, 22, 193, 103, 220, 168, 21, 22, 220, - 179, 21, 22, 193, 103, 220, 179, 21, 22, 220, 178, 21, 22, 193, 103, 220, - 178, 21, 22, 214, 209, 220, 178, 21, 22, 222, 152, 21, 22, 220, 180, 21, - 22, 202, 1, 222, 6, 21, 22, 202, 1, 221, 146, 21, 22, 202, 1, 221, 56, - 21, 22, 202, 1, 222, 104, 21, 22, 247, 42, 21, 22, 247, 158, 21, 22, 243, - 29, 21, 22, 243, 19, 21, 22, 242, 99, 21, 22, 239, 18, 21, 22, 192, 158, - 239, 18, 21, 22, 247, 160, 21, 22, 247, 159, 21, 22, 238, 149, 21, 22, - 193, 103, 238, 149, 21, 22, 238, 147, 21, 22, 193, 103, 238, 147, 21, 22, - 238, 146, 21, 22, 193, 103, 238, 146, 21, 22, 238, 145, 21, 22, 193, 103, - 238, 145, 21, 22, 238, 144, 21, 22, 193, 103, 238, 144, 21, 22, 238, 151, - 21, 22, 193, 103, 238, 151, 21, 22, 238, 150, 21, 22, 193, 103, 238, 150, - 21, 22, 214, 209, 238, 150, 21, 22, 247, 193, 21, 22, 205, 101, 199, 51, - 21, 22, 216, 232, 21, 22, 217, 150, 21, 22, 216, 100, 21, 22, 216, 61, - 21, 22, 216, 12, 21, 22, 215, 211, 21, 22, 192, 158, 215, 211, 21, 22, - 174, 21, 22, 217, 151, 21, 22, 215, 78, 21, 22, 193, 103, 215, 78, 21, - 22, 215, 76, 21, 22, 193, 103, 215, 76, 21, 22, 215, 75, 21, 22, 193, - 103, 215, 75, 21, 22, 215, 74, 21, 22, 193, 103, 215, 74, 21, 22, 215, - 73, 21, 22, 193, 103, 215, 73, 21, 22, 215, 80, 21, 22, 193, 103, 215, - 80, 21, 22, 215, 79, 21, 22, 193, 103, 215, 79, 21, 22, 214, 209, 215, - 79, 21, 22, 218, 168, 21, 22, 193, 103, 218, 168, 21, 22, 216, 104, 21, - 22, 250, 180, 218, 168, 21, 22, 205, 101, 218, 168, 21, 22, 214, 121, 21, - 22, 214, 249, 21, 22, 213, 219, 21, 22, 213, 186, 21, 22, 213, 43, 21, - 22, 213, 26, 21, 22, 192, 158, 213, 26, 21, 22, 180, 21, 22, 214, 250, - 21, 22, 212, 108, 21, 22, 193, 103, 212, 108, 21, 22, 212, 110, 21, 22, - 193, 103, 212, 110, 21, 22, 212, 109, 21, 22, 193, 103, 212, 109, 21, 22, - 214, 209, 212, 109, 21, 22, 215, 61, 21, 22, 98, 214, 70, 21, 22, 213, - 225, 21, 22, 219, 238, 21, 22, 220, 124, 21, 22, 219, 146, 21, 22, 219, - 128, 21, 22, 219, 43, 21, 22, 219, 8, 21, 22, 192, 158, 219, 8, 21, 22, - 173, 21, 22, 220, 125, 21, 22, 218, 189, 21, 22, 193, 103, 218, 189, 21, + 111, 36, 5, 232, 88, 36, 5, 233, 25, 36, 5, 233, 110, 36, 5, 233, 54, 36, + 5, 233, 61, 36, 5, 232, 177, 36, 5, 232, 64, 36, 5, 168, 36, 5, 208, 167, + 36, 5, 209, 187, 36, 5, 210, 222, 36, 5, 210, 51, 36, 5, 210, 65, 36, 5, + 209, 75, 36, 5, 208, 124, 36, 5, 206, 17, 36, 5, 215, 70, 36, 5, 232, 58, + 36, 33, 231, 155, 23, 18, 219, 200, 77, 36, 33, 18, 219, 200, 77, 36, 33, + 231, 155, 77, 36, 205, 55, 77, 36, 193, 22, 36, 232, 82, 201, 64, 36, + 242, 76, 36, 204, 26, 36, 242, 85, 36, 208, 230, 242, 85, 36, 208, 15, + 77, 36, 210, 130, 204, 11, 36, 17, 107, 36, 17, 109, 36, 17, 138, 36, 17, + 134, 36, 17, 150, 36, 17, 169, 36, 17, 175, 36, 17, 171, 36, 17, 178, 36, + 31, 199, 95, 36, 31, 197, 32, 36, 31, 198, 249, 36, 31, 232, 137, 36, 31, + 233, 17, 36, 31, 202, 121, 36, 31, 203, 242, 36, 31, 234, 155, 36, 31, + 213, 171, 36, 31, 228, 142, 36, 31, 199, 96, 189, 36, 5, 205, 60, 215, + 82, 36, 5, 215, 78, 36, 5, 215, 79, 36, 5, 215, 80, 36, 5, 205, 60, 247, + 212, 36, 5, 247, 209, 36, 5, 247, 210, 36, 5, 247, 211, 36, 5, 205, 60, + 232, 64, 36, 5, 232, 60, 36, 5, 232, 61, 36, 5, 232, 62, 36, 5, 205, 60, + 208, 124, 36, 5, 208, 120, 36, 5, 208, 121, 36, 5, 208, 122, 36, 198, 80, + 87, 192, 15, 36, 198, 80, 87, 237, 91, 36, 198, 80, 87, 206, 195, 36, + 198, 80, 87, 203, 41, 206, 195, 36, 198, 80, 87, 237, 20, 36, 198, 80, + 87, 221, 252, 36, 198, 80, 87, 243, 78, 36, 198, 80, 87, 229, 149, 36, + 198, 80, 87, 237, 90, 36, 198, 80, 87, 220, 197, 103, 1, 65, 103, 1, 71, + 103, 1, 68, 103, 1, 74, 103, 1, 66, 103, 1, 196, 12, 103, 1, 231, 242, + 103, 1, 155, 103, 1, 231, 167, 103, 1, 231, 55, 103, 1, 231, 5, 103, 1, + 230, 181, 103, 1, 230, 140, 103, 1, 140, 103, 1, 229, 247, 103, 1, 229, + 160, 103, 1, 229, 25, 103, 1, 228, 161, 103, 1, 228, 128, 103, 1, 173, + 103, 1, 219, 240, 103, 1, 219, 148, 103, 1, 219, 45, 103, 1, 218, 227, + 103, 1, 218, 194, 103, 1, 174, 103, 1, 216, 234, 103, 1, 216, 102, 103, + 1, 216, 14, 103, 1, 215, 157, 103, 1, 181, 103, 1, 229, 49, 103, 1, 214, + 239, 103, 1, 214, 123, 103, 1, 213, 221, 103, 1, 213, 45, 103, 1, 212, + 180, 103, 1, 212, 114, 103, 1, 208, 34, 103, 1, 208, 18, 103, 1, 208, 11, + 103, 1, 208, 1, 103, 1, 207, 246, 103, 1, 207, 244, 103, 1, 188, 103, 1, + 206, 9, 103, 1, 205, 69, 103, 1, 202, 223, 103, 1, 202, 47, 103, 1, 201, + 5, 103, 1, 200, 158, 103, 1, 238, 34, 103, 1, 190, 190, 103, 1, 237, 148, + 103, 1, 199, 145, 103, 1, 237, 46, 103, 1, 198, 193, 103, 1, 236, 176, + 103, 1, 235, 91, 103, 1, 235, 59, 103, 1, 236, 188, 103, 1, 198, 115, + 103, 1, 198, 114, 103, 1, 198, 103, 103, 1, 198, 102, 103, 1, 198, 101, + 103, 1, 198, 100, 103, 1, 197, 168, 103, 1, 197, 161, 103, 1, 197, 146, + 103, 1, 197, 144, 103, 1, 197, 140, 103, 1, 197, 139, 103, 1, 193, 190, + 103, 1, 193, 125, 103, 1, 193, 86, 103, 1, 193, 48, 103, 1, 193, 0, 103, + 1, 192, 243, 103, 1, 170, 103, 1, 192, 80, 103, 1, 192, 33, 103, 1, 192, + 12, 103, 1, 191, 225, 103, 1, 191, 184, 103, 1, 215, 89, 103, 2, 1, 192, + 80, 103, 2, 1, 192, 33, 103, 2, 1, 192, 12, 103, 2, 1, 191, 225, 103, 2, + 1, 191, 184, 103, 2, 1, 215, 89, 21, 22, 228, 90, 21, 22, 71, 21, 22, + 252, 172, 21, 22, 68, 21, 22, 223, 201, 21, 22, 74, 21, 22, 211, 89, 21, + 22, 192, 158, 211, 89, 21, 22, 98, 234, 190, 21, 22, 98, 68, 21, 22, 65, + 21, 22, 252, 208, 21, 22, 193, 125, 21, 22, 193, 103, 193, 125, 21, 22, + 193, 86, 21, 22, 193, 103, 193, 86, 21, 22, 193, 70, 21, 22, 193, 103, + 193, 70, 21, 22, 193, 48, 21, 22, 193, 103, 193, 48, 21, 22, 193, 29, 21, + 22, 193, 103, 193, 29, 21, 22, 214, 211, 193, 29, 21, 22, 193, 190, 21, + 22, 193, 103, 193, 190, 21, 22, 193, 181, 21, 22, 193, 103, 193, 181, 21, + 22, 214, 211, 193, 181, 21, 22, 251, 238, 21, 22, 192, 158, 193, 224, 21, + 22, 231, 13, 201, 64, 21, 22, 53, 252, 48, 21, 22, 53, 230, 212, 21, 22, + 53, 248, 79, 132, 206, 189, 21, 22, 53, 198, 54, 132, 206, 189, 21, 22, + 53, 50, 132, 206, 189, 21, 22, 53, 206, 189, 21, 22, 53, 55, 252, 48, 21, + 22, 53, 55, 203, 41, 81, 201, 16, 21, 22, 53, 82, 236, 142, 21, 22, 53, + 203, 41, 228, 243, 106, 21, 22, 53, 209, 83, 21, 22, 53, 144, 199, 228, + 21, 22, 234, 105, 21, 22, 223, 164, 21, 22, 211, 106, 21, 22, 251, 134, + 21, 22, 210, 65, 21, 22, 210, 220, 21, 22, 209, 187, 21, 22, 209, 147, + 21, 22, 209, 75, 21, 22, 209, 39, 21, 22, 192, 158, 209, 39, 21, 22, 98, + 229, 217, 21, 22, 98, 229, 160, 21, 22, 168, 21, 22, 210, 222, 21, 22, + 208, 122, 21, 22, 193, 103, 208, 122, 21, 22, 208, 120, 21, 22, 193, 103, + 208, 120, 21, 22, 208, 119, 21, 22, 193, 103, 208, 119, 21, 22, 208, 117, + 21, 22, 193, 103, 208, 117, 21, 22, 208, 116, 21, 22, 193, 103, 208, 116, + 21, 22, 208, 124, 21, 22, 193, 103, 208, 124, 21, 22, 208, 123, 21, 22, + 193, 103, 208, 123, 21, 22, 192, 158, 208, 123, 21, 22, 210, 238, 21, 22, + 193, 103, 210, 238, 21, 22, 98, 230, 118, 21, 22, 199, 145, 21, 22, 199, + 242, 21, 22, 198, 193, 21, 22, 198, 170, 21, 22, 159, 21, 22, 198, 59, + 21, 22, 192, 158, 198, 59, 21, 22, 98, 237, 133, 21, 22, 98, 237, 46, 21, + 22, 190, 190, 21, 22, 199, 245, 21, 22, 197, 41, 21, 22, 193, 103, 197, + 41, 21, 22, 197, 19, 21, 22, 193, 103, 197, 19, 21, 22, 197, 18, 21, 22, + 193, 103, 197, 18, 21, 22, 109, 21, 22, 193, 103, 109, 21, 22, 197, 9, + 21, 22, 193, 103, 197, 9, 21, 22, 197, 43, 21, 22, 193, 103, 197, 43, 21, + 22, 197, 42, 21, 22, 193, 103, 197, 42, 21, 22, 214, 211, 197, 42, 21, + 22, 200, 43, 21, 22, 197, 127, 21, 22, 197, 111, 21, 22, 197, 109, 21, + 22, 197, 132, 21, 22, 222, 24, 21, 22, 222, 123, 21, 22, 221, 168, 21, + 22, 221, 147, 21, 22, 221, 69, 21, 22, 221, 43, 21, 22, 192, 158, 221, + 43, 21, 22, 155, 21, 22, 222, 129, 21, 22, 220, 176, 21, 22, 193, 103, + 220, 176, 21, 22, 220, 174, 21, 22, 193, 103, 220, 174, 21, 22, 220, 173, + 21, 22, 193, 103, 220, 173, 21, 22, 220, 171, 21, 22, 193, 103, 220, 171, + 21, 22, 220, 170, 21, 22, 193, 103, 220, 170, 21, 22, 220, 181, 21, 22, + 193, 103, 220, 181, 21, 22, 220, 180, 21, 22, 193, 103, 220, 180, 21, 22, + 214, 211, 220, 180, 21, 22, 222, 154, 21, 22, 220, 182, 21, 22, 202, 2, + 222, 8, 21, 22, 202, 2, 221, 148, 21, 22, 202, 2, 221, 58, 21, 22, 202, + 2, 222, 106, 21, 22, 247, 44, 21, 22, 247, 160, 21, 22, 243, 31, 21, 22, + 243, 21, 21, 22, 242, 101, 21, 22, 239, 20, 21, 22, 192, 158, 239, 20, + 21, 22, 247, 162, 21, 22, 247, 161, 21, 22, 238, 151, 21, 22, 193, 103, + 238, 151, 21, 22, 238, 149, 21, 22, 193, 103, 238, 149, 21, 22, 238, 148, + 21, 22, 193, 103, 238, 148, 21, 22, 238, 147, 21, 22, 193, 103, 238, 147, + 21, 22, 238, 146, 21, 22, 193, 103, 238, 146, 21, 22, 238, 153, 21, 22, + 193, 103, 238, 153, 21, 22, 238, 152, 21, 22, 193, 103, 238, 152, 21, 22, + 214, 211, 238, 152, 21, 22, 247, 195, 21, 22, 205, 102, 199, 51, 21, 22, + 216, 234, 21, 22, 217, 152, 21, 22, 216, 102, 21, 22, 216, 63, 21, 22, + 216, 14, 21, 22, 215, 213, 21, 22, 192, 158, 215, 213, 21, 22, 174, 21, + 22, 217, 153, 21, 22, 215, 80, 21, 22, 193, 103, 215, 80, 21, 22, 215, + 78, 21, 22, 193, 103, 215, 78, 21, 22, 215, 77, 21, 22, 193, 103, 215, + 77, 21, 22, 215, 76, 21, 22, 193, 103, 215, 76, 21, 22, 215, 75, 21, 22, + 193, 103, 215, 75, 21, 22, 215, 82, 21, 22, 193, 103, 215, 82, 21, 22, + 215, 81, 21, 22, 193, 103, 215, 81, 21, 22, 214, 211, 215, 81, 21, 22, + 218, 170, 21, 22, 193, 103, 218, 170, 21, 22, 216, 106, 21, 22, 250, 182, + 218, 170, 21, 22, 205, 102, 218, 170, 21, 22, 214, 123, 21, 22, 214, 251, + 21, 22, 213, 221, 21, 22, 213, 188, 21, 22, 213, 45, 21, 22, 213, 28, 21, + 22, 192, 158, 213, 28, 21, 22, 181, 21, 22, 214, 252, 21, 22, 212, 110, + 21, 22, 193, 103, 212, 110, 21, 22, 212, 112, 21, 22, 193, 103, 212, 112, + 21, 22, 212, 111, 21, 22, 193, 103, 212, 111, 21, 22, 214, 211, 212, 111, + 21, 22, 215, 63, 21, 22, 98, 214, 72, 21, 22, 213, 227, 21, 22, 219, 240, + 21, 22, 220, 126, 21, 22, 219, 148, 21, 22, 219, 130, 21, 22, 219, 45, + 21, 22, 219, 10, 21, 22, 192, 158, 219, 10, 21, 22, 173, 21, 22, 220, + 127, 21, 22, 218, 191, 21, 22, 193, 103, 218, 191, 21, 22, 218, 190, 21, + 22, 193, 103, 218, 190, 21, 22, 218, 189, 21, 22, 193, 103, 218, 189, 21, 22, 218, 188, 21, 22, 193, 103, 218, 188, 21, 22, 218, 187, 21, 22, 193, - 103, 218, 187, 21, 22, 218, 186, 21, 22, 193, 103, 218, 186, 21, 22, 218, - 185, 21, 22, 193, 103, 218, 185, 21, 22, 218, 191, 21, 22, 193, 103, 218, - 191, 21, 22, 218, 190, 21, 22, 193, 103, 218, 190, 21, 22, 172, 21, 22, - 193, 103, 172, 21, 22, 216, 217, 172, 21, 22, 205, 68, 21, 22, 205, 195, - 21, 22, 202, 222, 21, 22, 202, 193, 21, 22, 202, 46, 21, 22, 202, 16, 21, - 22, 192, 158, 202, 16, 21, 22, 188, 21, 22, 205, 197, 21, 22, 200, 145, - 21, 22, 193, 103, 200, 145, 21, 22, 200, 139, 21, 22, 193, 103, 200, 139, - 21, 22, 200, 138, 21, 22, 193, 103, 200, 138, 21, 22, 200, 133, 21, 22, - 193, 103, 200, 133, 21, 22, 200, 132, 21, 22, 193, 103, 200, 132, 21, 22, - 200, 150, 21, 22, 193, 103, 200, 150, 21, 22, 200, 149, 21, 22, 193, 103, - 200, 149, 21, 22, 214, 209, 200, 149, 21, 22, 206, 8, 21, 22, 250, 180, - 206, 8, 21, 22, 200, 151, 21, 22, 248, 136, 206, 8, 21, 22, 215, 203, - 202, 114, 21, 22, 214, 209, 202, 101, 21, 22, 214, 209, 206, 6, 21, 22, - 214, 209, 201, 192, 21, 22, 214, 209, 201, 7, 21, 22, 214, 209, 202, 100, - 21, 22, 214, 209, 205, 71, 21, 22, 203, 113, 21, 22, 203, 81, 21, 22, - 203, 76, 21, 22, 203, 56, 21, 22, 203, 48, 21, 22, 203, 165, 21, 22, 203, - 160, 21, 22, 202, 237, 21, 22, 193, 103, 202, 237, 21, 22, 202, 236, 21, - 22, 193, 103, 202, 236, 21, 22, 202, 235, 21, 22, 193, 103, 202, 235, 21, - 22, 202, 234, 21, 22, 193, 103, 202, 234, 21, 22, 202, 233, 21, 22, 193, - 103, 202, 233, 21, 22, 202, 240, 21, 22, 193, 103, 202, 240, 21, 22, 202, - 239, 21, 22, 193, 103, 202, 239, 21, 22, 203, 167, 21, 22, 192, 80, 21, - 22, 192, 138, 21, 22, 192, 33, 21, 22, 192, 23, 21, 22, 192, 12, 21, 22, - 191, 246, 21, 22, 192, 158, 191, 246, 21, 22, 170, 21, 22, 192, 140, 21, - 22, 191, 181, 21, 22, 193, 103, 191, 181, 21, 22, 191, 180, 21, 22, 193, - 103, 191, 180, 21, 22, 191, 179, 21, 22, 193, 103, 191, 179, 21, 22, 191, - 178, 21, 22, 193, 103, 191, 178, 21, 22, 191, 177, 21, 22, 193, 103, 191, - 177, 21, 22, 191, 183, 21, 22, 193, 103, 191, 183, 21, 22, 191, 182, 21, - 22, 193, 103, 191, 182, 21, 22, 214, 209, 191, 182, 21, 22, 192, 159, 21, - 22, 248, 186, 192, 159, 21, 22, 193, 103, 192, 159, 21, 22, 205, 101, - 192, 33, 21, 22, 207, 113, 21, 22, 207, 221, 207, 113, 21, 22, 193, 103, - 219, 238, 21, 22, 207, 177, 21, 22, 207, 1, 21, 22, 206, 195, 21, 22, - 206, 162, 21, 22, 206, 134, 21, 22, 193, 103, 219, 43, 21, 22, 165, 21, - 22, 207, 178, 21, 22, 193, 103, 173, 21, 22, 206, 25, 21, 22, 193, 103, - 206, 25, 21, 22, 146, 21, 22, 193, 103, 146, 21, 22, 216, 217, 146, 21, - 22, 233, 59, 21, 22, 233, 106, 21, 22, 233, 23, 21, 22, 233, 8, 21, 22, - 232, 175, 21, 22, 232, 162, 21, 22, 233, 109, 21, 22, 233, 108, 21, 22, - 232, 61, 21, 22, 193, 103, 232, 61, 21, 22, 233, 175, 21, 22, 199, 33, - 21, 22, 215, 59, 199, 33, 21, 22, 199, 11, 21, 22, 215, 59, 199, 11, 21, - 22, 199, 5, 21, 22, 215, 59, 199, 5, 21, 22, 198, 241, 21, 22, 198, 235, - 21, 22, 199, 49, 21, 22, 199, 48, 21, 22, 198, 203, 21, 22, 193, 103, - 198, 203, 21, 22, 199, 51, 21, 22, 197, 118, 21, 22, 197, 116, 21, 22, - 197, 115, 21, 22, 197, 120, 21, 22, 197, 121, 21, 22, 197, 2, 21, 22, - 197, 1, 21, 22, 197, 0, 21, 22, 197, 4, 21, 22, 212, 129, 229, 245, 21, - 22, 212, 129, 229, 158, 21, 22, 212, 129, 229, 130, 21, 22, 212, 129, - 229, 23, 21, 22, 212, 129, 228, 252, 21, 22, 212, 129, 140, 21, 22, 212, - 129, 230, 91, 21, 22, 212, 129, 230, 116, 21, 22, 212, 128, 230, 116, 21, - 22, 229, 113, 21, 22, 208, 92, 21, 22, 208, 57, 21, 22, 208, 51, 21, 22, - 208, 45, 21, 22, 208, 40, 21, 22, 208, 96, 21, 22, 208, 95, 21, 22, 208, - 104, 21, 22, 198, 111, 21, 22, 198, 109, 21, 22, 198, 108, 21, 22, 198, - 112, 21, 22, 193, 103, 207, 113, 21, 22, 193, 103, 207, 1, 21, 22, 193, - 103, 206, 162, 21, 22, 193, 103, 165, 21, 22, 214, 66, 21, 22, 214, 16, - 21, 22, 214, 12, 21, 22, 213, 249, 21, 22, 213, 244, 21, 22, 214, 68, 21, - 22, 214, 67, 21, 22, 214, 70, 21, 22, 213, 72, 21, 22, 205, 101, 203, - 113, 21, 22, 205, 101, 203, 81, 21, 22, 205, 101, 203, 56, 21, 22, 205, - 101, 203, 165, 21, 22, 193, 27, 199, 33, 21, 22, 193, 27, 199, 11, 21, - 22, 193, 27, 198, 241, 21, 22, 193, 27, 199, 49, 21, 22, 193, 27, 199, - 51, 21, 22, 219, 153, 21, 22, 219, 152, 21, 22, 219, 151, 21, 22, 219, - 150, 21, 22, 219, 159, 21, 22, 219, 158, 21, 22, 219, 160, 21, 22, 199, - 50, 199, 33, 21, 22, 199, 50, 199, 11, 21, 22, 199, 50, 199, 5, 21, 22, - 199, 50, 198, 241, 21, 22, 199, 50, 198, 235, 21, 22, 199, 50, 199, 49, - 21, 22, 199, 50, 199, 48, 21, 22, 199, 50, 199, 51, 21, 22, 251, 220, - 250, 120, 21, 22, 248, 136, 71, 21, 22, 248, 136, 68, 21, 22, 248, 136, - 74, 21, 22, 248, 136, 65, 21, 22, 248, 136, 193, 125, 21, 22, 248, 136, - 193, 86, 21, 22, 248, 136, 193, 48, 21, 22, 248, 136, 193, 190, 21, 22, - 248, 136, 214, 121, 21, 22, 248, 136, 213, 219, 21, 22, 248, 136, 213, - 43, 21, 22, 248, 136, 180, 21, 22, 248, 136, 222, 22, 21, 22, 248, 136, - 221, 166, 21, 22, 248, 136, 221, 67, 21, 22, 248, 136, 155, 21, 22, 205, - 101, 229, 245, 21, 22, 205, 101, 229, 158, 21, 22, 205, 101, 229, 23, 21, - 22, 205, 101, 140, 21, 22, 98, 231, 59, 21, 22, 98, 231, 63, 21, 22, 98, - 231, 77, 21, 22, 98, 231, 76, 21, 22, 98, 231, 65, 21, 22, 98, 231, 91, - 21, 22, 98, 206, 68, 21, 22, 98, 206, 162, 21, 22, 98, 207, 113, 21, 22, - 98, 207, 84, 21, 22, 98, 207, 1, 21, 22, 98, 165, 21, 22, 98, 193, 0, 21, - 22, 98, 193, 48, 21, 22, 98, 193, 125, 21, 22, 98, 193, 114, 21, 22, 98, - 193, 86, 21, 22, 98, 193, 190, 21, 22, 98, 228, 118, 21, 22, 98, 228, - 119, 21, 22, 98, 228, 122, 21, 22, 98, 228, 121, 21, 22, 98, 228, 120, - 21, 22, 98, 228, 125, 21, 22, 98, 198, 213, 21, 22, 98, 198, 241, 21, 22, - 98, 199, 33, 21, 22, 98, 199, 31, 21, 22, 98, 199, 11, 21, 22, 98, 199, - 49, 21, 22, 98, 197, 99, 21, 22, 98, 197, 109, 21, 22, 98, 197, 127, 21, - 22, 98, 197, 126, 21, 22, 98, 197, 111, 21, 22, 98, 197, 132, 21, 22, 98, - 208, 165, 21, 22, 98, 209, 73, 21, 22, 98, 210, 63, 21, 22, 98, 210, 49, - 21, 22, 98, 209, 185, 21, 22, 98, 168, 21, 22, 98, 210, 236, 21, 22, 98, - 230, 179, 21, 22, 98, 231, 3, 21, 22, 98, 231, 165, 21, 22, 98, 231, 157, - 21, 22, 98, 231, 53, 21, 22, 98, 231, 240, 21, 22, 98, 221, 175, 21, 22, - 98, 221, 183, 21, 22, 98, 221, 197, 21, 22, 98, 221, 196, 21, 22, 98, - 221, 190, 21, 22, 98, 221, 215, 21, 22, 98, 221, 96, 21, 22, 98, 221, 97, - 21, 22, 98, 221, 100, 21, 22, 98, 221, 99, 21, 22, 98, 221, 98, 21, 22, - 98, 221, 101, 21, 22, 98, 221, 102, 21, 22, 98, 212, 178, 21, 22, 98, - 213, 43, 21, 22, 98, 214, 121, 21, 22, 98, 214, 110, 21, 22, 98, 213, - 219, 21, 22, 98, 180, 21, 22, 98, 215, 155, 21, 22, 98, 216, 12, 21, 22, - 98, 216, 232, 21, 22, 98, 216, 211, 21, 22, 98, 216, 100, 21, 22, 98, - 174, 21, 22, 98, 191, 225, 21, 22, 98, 192, 12, 21, 22, 98, 192, 80, 21, - 22, 98, 192, 77, 21, 22, 98, 192, 33, 21, 22, 98, 170, 21, 22, 98, 222, - 182, 21, 22, 205, 101, 222, 182, 21, 22, 98, 222, 201, 21, 22, 98, 223, - 10, 21, 22, 98, 223, 8, 21, 22, 98, 222, 244, 21, 22, 205, 101, 222, 244, - 21, 22, 98, 223, 32, 21, 22, 98, 222, 215, 21, 22, 98, 222, 219, 21, 22, - 98, 222, 229, 21, 22, 98, 222, 228, 21, 22, 98, 222, 227, 21, 22, 98, - 222, 230, 21, 22, 98, 218, 225, 21, 22, 98, 219, 43, 21, 22, 98, 219, - 238, 21, 22, 98, 219, 228, 21, 22, 98, 219, 146, 21, 22, 98, 173, 21, 22, - 98, 236, 179, 21, 22, 98, 236, 180, 21, 22, 98, 236, 185, 21, 22, 98, - 236, 184, 21, 22, 98, 236, 181, 21, 22, 98, 236, 186, 21, 22, 98, 219, - 149, 21, 22, 98, 219, 151, 21, 22, 98, 219, 155, 21, 22, 98, 219, 154, - 21, 22, 98, 219, 153, 21, 22, 98, 219, 159, 21, 22, 98, 198, 106, 21, 22, - 98, 198, 108, 21, 22, 98, 198, 111, 21, 22, 98, 198, 110, 21, 22, 98, - 198, 109, 21, 22, 98, 198, 112, 21, 22, 98, 198, 101, 21, 22, 98, 198, - 102, 21, 22, 98, 198, 114, 21, 22, 98, 198, 113, 21, 22, 98, 198, 103, - 21, 22, 98, 198, 115, 21, 22, 98, 190, 251, 21, 22, 98, 191, 7, 21, 22, - 98, 191, 87, 21, 22, 98, 191, 84, 21, 22, 98, 191, 30, 21, 22, 98, 191, - 123, 21, 22, 98, 191, 166, 21, 22, 98, 89, 191, 166, 21, 22, 98, 235, 22, - 21, 22, 98, 235, 23, 21, 22, 98, 235, 32, 21, 22, 98, 235, 31, 21, 22, - 98, 235, 26, 21, 22, 98, 235, 35, 21, 22, 98, 201, 4, 21, 22, 98, 202, - 46, 21, 22, 98, 205, 68, 21, 22, 98, 205, 50, 21, 22, 98, 202, 222, 21, - 22, 98, 188, 21, 22, 98, 203, 5, 21, 22, 98, 203, 56, 21, 22, 98, 203, - 113, 21, 22, 98, 203, 111, 21, 22, 98, 203, 81, 21, 22, 98, 203, 165, 21, - 22, 98, 203, 167, 21, 22, 98, 197, 140, 21, 22, 98, 197, 144, 21, 22, 98, - 197, 161, 21, 22, 98, 197, 160, 21, 22, 98, 197, 146, 21, 22, 98, 197, - 168, 21, 22, 98, 243, 48, 21, 22, 98, 243, 68, 21, 22, 98, 243, 127, 21, - 22, 98, 243, 123, 21, 22, 98, 243, 95, 21, 22, 98, 247, 1, 21, 22, 98, - 197, 102, 21, 22, 98, 197, 103, 21, 22, 98, 197, 106, 21, 22, 98, 197, - 105, 21, 22, 98, 197, 104, 21, 22, 98, 197, 107, 21, 22, 243, 96, 56, 21, - 22, 232, 80, 201, 63, 21, 22, 208, 88, 21, 22, 214, 64, 21, 22, 213, 69, - 21, 22, 213, 68, 21, 22, 213, 67, 21, 22, 213, 66, 21, 22, 213, 71, 21, - 22, 213, 70, 21, 22, 193, 27, 198, 201, 21, 22, 193, 27, 198, 200, 21, - 22, 193, 27, 198, 199, 21, 22, 193, 27, 198, 198, 21, 22, 193, 27, 198, - 197, 21, 22, 193, 27, 198, 204, 21, 22, 193, 27, 198, 203, 21, 22, 193, - 27, 53, 199, 51, 21, 22, 248, 136, 193, 224, 211, 140, 201, 248, 77, 211, - 140, 1, 248, 239, 211, 140, 1, 218, 211, 211, 140, 1, 233, 56, 211, 140, - 1, 205, 179, 211, 140, 1, 213, 166, 211, 140, 1, 196, 165, 211, 140, 1, - 238, 5, 211, 140, 1, 198, 139, 211, 140, 1, 242, 86, 211, 140, 1, 247, - 29, 211, 140, 1, 215, 137, 211, 140, 1, 230, 234, 211, 140, 1, 214, 54, - 211, 140, 1, 201, 54, 211, 140, 1, 206, 55, 211, 140, 1, 251, 232, 211, - 140, 1, 211, 91, 211, 140, 1, 196, 62, 211, 140, 1, 234, 215, 211, 140, - 1, 223, 87, 211, 140, 1, 234, 216, 211, 140, 1, 211, 56, 211, 140, 1, - 196, 136, 211, 140, 1, 223, 205, 211, 140, 1, 234, 213, 211, 140, 1, 210, - 38, 211, 140, 233, 55, 77, 211, 140, 207, 18, 233, 55, 77, 206, 44, 1, - 233, 45, 233, 36, 233, 60, 233, 175, 206, 44, 1, 196, 12, 206, 44, 1, - 196, 47, 196, 63, 66, 206, 44, 1, 191, 228, 206, 44, 1, 192, 159, 206, - 44, 1, 193, 224, 206, 44, 1, 198, 206, 198, 205, 198, 233, 206, 44, 1, - 233, 248, 206, 44, 1, 251, 90, 65, 206, 44, 1, 211, 37, 74, 206, 44, 1, - 252, 64, 65, 206, 44, 1, 252, 9, 206, 44, 1, 219, 15, 74, 206, 44, 1, - 203, 33, 74, 206, 44, 1, 74, 206, 44, 1, 211, 151, 206, 44, 1, 211, 104, - 206, 44, 1, 207, 154, 207, 169, 207, 69, 146, 206, 44, 1, 222, 39, 206, - 44, 1, 247, 25, 206, 44, 1, 222, 40, 222, 152, 206, 44, 1, 232, 51, 206, - 44, 1, 234, 88, 206, 44, 1, 231, 160, 230, 122, 232, 51, 206, 44, 1, 231, - 200, 206, 44, 1, 192, 248, 192, 239, 193, 224, 206, 44, 1, 230, 82, 230, - 116, 206, 44, 1, 230, 86, 230, 116, 206, 44, 1, 219, 17, 230, 116, 206, - 44, 1, 203, 36, 230, 116, 206, 44, 1, 214, 203, 212, 91, 214, 204, 215, - 61, 206, 44, 1, 203, 34, 215, 61, 206, 44, 1, 235, 135, 206, 44, 1, 223, - 65, 223, 69, 223, 55, 68, 206, 44, 1, 71, 206, 44, 1, 222, 255, 223, 35, - 206, 44, 1, 231, 141, 206, 44, 1, 219, 18, 252, 25, 206, 44, 1, 203, 38, - 65, 206, 44, 1, 223, 47, 234, 61, 206, 44, 1, 209, 247, 210, 18, 210, - 236, 206, 44, 1, 251, 185, 234, 59, 206, 44, 1, 201, 254, 206, 8, 206, - 44, 1, 202, 198, 219, 14, 206, 8, 206, 44, 1, 203, 32, 206, 8, 206, 44, - 1, 247, 193, 206, 44, 1, 191, 166, 206, 44, 1, 198, 120, 198, 132, 196, - 242, 200, 43, 206, 44, 1, 203, 31, 200, 43, 206, 44, 1, 238, 127, 206, - 44, 1, 248, 217, 248, 220, 248, 142, 250, 120, 206, 44, 1, 203, 37, 250, - 120, 206, 44, 1, 235, 134, 206, 44, 1, 211, 70, 206, 44, 1, 234, 167, - 234, 174, 71, 206, 44, 1, 217, 79, 217, 91, 218, 168, 206, 44, 1, 219, - 16, 218, 168, 206, 44, 1, 203, 35, 218, 168, 206, 44, 1, 219, 253, 220, - 101, 219, 26, 172, 206, 44, 1, 235, 136, 206, 44, 1, 223, 135, 206, 44, - 1, 223, 136, 206, 44, 1, 238, 19, 238, 25, 238, 127, 206, 44, 1, 211, 28, - 233, 247, 74, 206, 44, 1, 234, 211, 206, 44, 1, 223, 85, 206, 44, 1, 238, - 148, 206, 44, 1, 247, 143, 206, 44, 1, 247, 41, 206, 44, 1, 201, 108, - 206, 44, 1, 219, 13, 206, 44, 1, 203, 30, 206, 44, 1, 228, 25, 206, 44, - 1, 208, 104, 206, 44, 1, 192, 235, 206, 44, 202, 170, 208, 151, 206, 44, - 215, 129, 208, 151, 206, 44, 238, 218, 208, 151, 206, 44, 250, 252, 113, - 206, 44, 197, 45, 113, 206, 44, 248, 237, 113, 206, 44, 1, 222, 152, 206, - 44, 1, 203, 167, 206, 44, 1, 211, 87, 206, 44, 1, 232, 110, 247, 81, 211, - 36, 206, 44, 1, 232, 110, 247, 81, 223, 68, 206, 44, 1, 232, 110, 247, - 81, 234, 173, 206, 44, 1, 232, 110, 247, 81, 252, 63, 206, 44, 1, 232, - 110, 247, 81, 252, 9, 199, 222, 1, 65, 199, 222, 1, 68, 199, 222, 1, 66, - 199, 222, 1, 155, 199, 222, 1, 231, 240, 199, 222, 1, 214, 68, 199, 222, - 1, 190, 190, 199, 222, 1, 238, 32, 199, 222, 1, 180, 199, 222, 1, 168, - 199, 222, 1, 249, 153, 199, 222, 1, 174, 199, 222, 1, 170, 199, 222, 1, - 165, 199, 222, 1, 173, 199, 222, 1, 193, 190, 199, 222, 1, 188, 199, 222, - 1, 140, 199, 222, 18, 3, 68, 199, 222, 18, 3, 66, 199, 222, 3, 195, 40, - 199, 222, 3, 210, 169, 199, 222, 1, 251, 14, 165, 230, 23, 1, 65, 230, - 23, 1, 68, 230, 23, 1, 66, 230, 23, 1, 155, 230, 23, 1, 231, 240, 230, - 23, 1, 214, 68, 230, 23, 1, 190, 190, 230, 23, 1, 238, 32, 230, 23, 1, - 180, 230, 23, 1, 168, 230, 23, 1, 249, 153, 230, 23, 1, 174, 230, 23, 1, - 170, 230, 23, 1, 165, 230, 23, 1, 173, 230, 23, 1, 193, 190, 230, 23, 1, - 188, 230, 23, 1, 140, 230, 23, 18, 3, 68, 230, 23, 18, 3, 66, 230, 23, 3, - 210, 169, 209, 204, 202, 170, 208, 151, 209, 204, 55, 208, 151, 248, 0, - 1, 65, 248, 0, 1, 68, 248, 0, 1, 66, 248, 0, 1, 155, 248, 0, 1, 231, 240, - 248, 0, 1, 214, 68, 248, 0, 1, 190, 190, 248, 0, 1, 238, 32, 248, 0, 1, - 180, 248, 0, 1, 168, 248, 0, 1, 249, 153, 248, 0, 1, 174, 248, 0, 1, 170, - 248, 0, 1, 165, 248, 0, 1, 173, 248, 0, 1, 193, 190, 248, 0, 1, 188, 248, - 0, 1, 140, 248, 0, 18, 3, 68, 248, 0, 18, 3, 66, 199, 221, 1, 65, 199, - 221, 1, 68, 199, 221, 1, 66, 199, 221, 1, 155, 199, 221, 1, 231, 240, - 199, 221, 1, 214, 68, 199, 221, 1, 190, 190, 199, 221, 1, 238, 32, 199, - 221, 1, 180, 199, 221, 1, 168, 199, 221, 1, 249, 153, 199, 221, 1, 174, - 199, 221, 1, 170, 199, 221, 1, 173, 199, 221, 1, 193, 190, 199, 221, 1, - 188, 199, 221, 18, 3, 68, 199, 221, 18, 3, 66, 95, 1, 155, 95, 1, 221, - 215, 95, 1, 221, 67, 95, 1, 221, 183, 95, 1, 213, 249, 95, 1, 247, 160, - 95, 1, 247, 1, 95, 1, 242, 99, 95, 1, 243, 68, 95, 1, 212, 65, 95, 1, - 238, 32, 95, 1, 197, 120, 95, 1, 236, 174, 95, 1, 197, 115, 95, 1, 213, - 49, 95, 1, 190, 190, 95, 1, 199, 49, 95, 1, 159, 95, 1, 198, 241, 95, 1, - 213, 43, 95, 1, 249, 153, 95, 1, 209, 228, 95, 1, 209, 73, 95, 1, 209, - 199, 95, 1, 216, 12, 95, 1, 192, 12, 95, 1, 206, 162, 95, 1, 219, 43, 95, - 1, 195, 24, 95, 1, 203, 165, 95, 1, 201, 134, 95, 1, 188, 95, 1, 140, 95, - 1, 173, 95, 1, 208, 96, 95, 223, 149, 18, 208, 82, 95, 223, 149, 18, 208, - 95, 95, 223, 149, 18, 208, 57, 95, 223, 149, 18, 208, 51, 95, 223, 149, - 18, 208, 33, 95, 223, 149, 18, 208, 0, 95, 223, 149, 18, 207, 244, 95, - 223, 149, 18, 207, 243, 95, 223, 149, 18, 206, 17, 95, 223, 149, 18, 206, - 10, 95, 223, 149, 18, 218, 183, 95, 223, 149, 18, 218, 171, 95, 223, 149, - 18, 208, 75, 95, 223, 149, 18, 208, 88, 95, 223, 149, 18, 208, 41, 196, - 255, 107, 95, 223, 149, 18, 208, 41, 196, 255, 109, 95, 223, 149, 18, - 208, 77, 95, 18, 223, 133, 251, 37, 95, 18, 223, 133, 252, 206, 95, 18, - 3, 252, 206, 95, 18, 3, 68, 95, 18, 3, 223, 199, 95, 18, 3, 192, 159, 95, - 18, 3, 191, 176, 95, 18, 3, 66, 95, 18, 3, 196, 30, 95, 18, 3, 196, 168, - 95, 18, 3, 211, 151, 95, 18, 3, 170, 95, 18, 3, 223, 226, 95, 18, 3, 71, - 95, 18, 3, 252, 25, 95, 18, 3, 251, 236, 95, 18, 3, 211, 87, 95, 18, 3, - 250, 163, 95, 3, 213, 184, 95, 3, 207, 106, 95, 3, 191, 187, 95, 3, 215, - 91, 95, 3, 197, 229, 95, 3, 249, 90, 95, 3, 206, 151, 95, 3, 198, 90, 95, - 3, 222, 95, 95, 3, 251, 238, 95, 3, 205, 143, 205, 135, 95, 3, 195, 37, - 95, 3, 242, 90, 95, 3, 249, 60, 95, 3, 221, 205, 95, 3, 249, 85, 95, 3, - 247, 131, 209, 146, 220, 186, 95, 3, 219, 205, 198, 59, 95, 3, 248, 205, - 95, 3, 209, 201, 215, 148, 95, 3, 221, 39, 95, 238, 170, 16, 206, 241, - 95, 3, 250, 144, 95, 3, 250, 166, 95, 17, 191, 77, 95, 17, 107, 95, 17, - 109, 95, 17, 138, 95, 17, 134, 95, 17, 149, 95, 17, 169, 95, 17, 175, 95, - 17, 171, 95, 17, 178, 95, 16, 219, 205, 250, 168, 202, 19, 95, 16, 219, - 205, 250, 168, 215, 112, 95, 16, 219, 205, 250, 168, 209, 145, 95, 16, - 219, 205, 250, 168, 248, 240, 95, 16, 219, 205, 250, 168, 247, 236, 95, - 16, 219, 205, 250, 168, 208, 245, 95, 16, 219, 205, 250, 168, 208, 239, - 95, 16, 219, 205, 250, 168, 208, 237, 95, 16, 219, 205, 250, 168, 208, - 243, 95, 16, 219, 205, 250, 168, 208, 241, 104, 248, 158, 104, 234, 120, - 104, 242, 74, 104, 232, 80, 201, 63, 104, 242, 83, 104, 232, 128, 236, - 138, 104, 198, 88, 202, 32, 228, 88, 104, 202, 214, 5, 248, 73, 217, 51, - 104, 217, 87, 242, 74, 104, 217, 87, 232, 80, 201, 63, 104, 213, 164, - 104, 232, 109, 67, 205, 35, 107, 104, 232, 109, 67, 205, 35, 109, 104, - 232, 109, 67, 205, 35, 138, 104, 18, 204, 10, 104, 232, 109, 67, 205, 35, - 134, 104, 17, 191, 77, 104, 17, 107, 104, 17, 109, 104, 17, 138, 104, 17, - 134, 104, 17, 149, 104, 17, 169, 104, 17, 175, 104, 17, 171, 104, 17, - 178, 104, 1, 65, 104, 1, 71, 104, 1, 68, 104, 1, 74, 104, 1, 66, 104, 1, - 211, 151, 104, 1, 196, 152, 104, 1, 234, 188, 104, 1, 180, 104, 1, 251, - 122, 104, 1, 249, 153, 104, 1, 168, 104, 1, 208, 96, 104, 1, 231, 240, - 104, 1, 174, 104, 1, 173, 104, 1, 188, 104, 1, 203, 165, 104, 1, 190, - 190, 104, 1, 238, 32, 104, 1, 247, 1, 104, 1, 223, 32, 104, 1, 170, 104, - 1, 165, 104, 1, 193, 190, 104, 1, 233, 109, 104, 1, 155, 104, 1, 221, - 215, 104, 1, 197, 168, 104, 1, 191, 123, 104, 1, 230, 91, 104, 1, 190, - 255, 104, 1, 219, 159, 104, 1, 191, 57, 104, 1, 243, 95, 104, 1, 198, 88, - 179, 18, 56, 104, 1, 198, 88, 71, 104, 1, 198, 88, 68, 104, 1, 198, 88, - 74, 104, 1, 198, 88, 66, 104, 1, 198, 88, 211, 151, 104, 1, 198, 88, 196, - 152, 104, 1, 198, 88, 251, 122, 104, 1, 198, 88, 249, 153, 104, 1, 198, - 88, 168, 104, 1, 198, 88, 208, 96, 104, 1, 198, 88, 231, 240, 104, 1, - 198, 88, 174, 104, 1, 198, 88, 190, 190, 104, 1, 198, 88, 238, 32, 104, - 1, 198, 88, 247, 1, 104, 1, 198, 88, 223, 32, 104, 1, 198, 88, 197, 168, - 104, 1, 198, 88, 170, 104, 1, 198, 88, 193, 190, 104, 1, 198, 88, 155, - 104, 1, 198, 88, 231, 237, 104, 1, 198, 88, 230, 91, 104, 1, 198, 88, - 222, 243, 104, 1, 198, 88, 213, 209, 104, 1, 198, 88, 235, 35, 104, 1, - 202, 214, 71, 104, 1, 202, 214, 68, 104, 1, 202, 214, 223, 44, 104, 1, - 202, 214, 196, 152, 104, 1, 202, 214, 66, 104, 1, 202, 214, 251, 122, - 104, 1, 202, 214, 155, 104, 1, 202, 214, 231, 240, 104, 1, 202, 214, 140, - 104, 1, 202, 214, 168, 104, 1, 202, 214, 203, 165, 104, 1, 202, 214, 190, - 190, 104, 1, 202, 214, 238, 32, 104, 1, 202, 214, 223, 32, 104, 1, 202, - 214, 233, 109, 104, 1, 202, 214, 231, 237, 104, 1, 202, 214, 230, 91, - 104, 1, 202, 214, 197, 168, 104, 1, 202, 214, 191, 123, 104, 1, 202, 214, - 207, 178, 104, 1, 202, 214, 247, 1, 104, 1, 202, 214, 191, 71, 104, 1, - 217, 87, 68, 104, 1, 217, 87, 155, 104, 1, 217, 87, 165, 104, 1, 217, 87, - 233, 109, 104, 1, 217, 87, 191, 71, 104, 1, 247, 2, 4, 105, 236, 138, - 104, 1, 251, 184, 231, 220, 251, 72, 107, 104, 1, 251, 184, 231, 220, - 195, 36, 107, 104, 1, 251, 184, 231, 220, 237, 247, 104, 1, 251, 184, - 231, 220, 196, 163, 104, 1, 251, 184, 231, 220, 223, 93, 196, 163, 104, - 1, 251, 184, 231, 220, 249, 104, 104, 1, 251, 184, 231, 220, 115, 249, - 104, 104, 1, 251, 184, 231, 220, 65, 104, 1, 251, 184, 231, 220, 68, 104, - 1, 251, 184, 231, 220, 155, 104, 1, 251, 184, 231, 220, 214, 68, 104, 1, - 251, 184, 231, 220, 247, 160, 104, 1, 251, 184, 231, 220, 197, 132, 104, - 1, 251, 184, 231, 220, 197, 120, 104, 1, 251, 184, 231, 220, 237, 191, - 104, 1, 251, 184, 231, 220, 213, 79, 104, 1, 251, 184, 231, 220, 190, - 190, 104, 1, 251, 184, 231, 220, 238, 32, 104, 1, 251, 184, 231, 220, - 168, 104, 1, 251, 184, 231, 220, 209, 228, 104, 1, 251, 184, 231, 220, - 201, 175, 104, 1, 251, 184, 231, 220, 191, 71, 104, 1, 251, 184, 231, - 220, 191, 123, 104, 1, 251, 184, 231, 220, 251, 245, 104, 1, 198, 88, - 251, 184, 231, 220, 190, 190, 104, 1, 198, 88, 251, 184, 231, 220, 191, - 71, 104, 1, 217, 87, 251, 184, 231, 220, 231, 91, 104, 1, 217, 87, 251, - 184, 231, 220, 214, 68, 104, 1, 217, 87, 251, 184, 231, 220, 247, 160, - 104, 1, 217, 87, 251, 184, 231, 220, 222, 252, 104, 1, 217, 87, 251, 184, - 231, 220, 197, 132, 104, 1, 217, 87, 251, 184, 231, 220, 237, 175, 104, - 1, 217, 87, 251, 184, 231, 220, 190, 190, 104, 1, 217, 87, 251, 184, 231, - 220, 237, 68, 104, 1, 217, 87, 251, 184, 231, 220, 201, 175, 104, 1, 217, - 87, 251, 184, 231, 220, 238, 142, 104, 1, 217, 87, 251, 184, 231, 220, - 191, 71, 104, 1, 217, 87, 251, 184, 231, 220, 191, 123, 104, 1, 251, 184, - 231, 220, 132, 66, 104, 1, 251, 184, 231, 220, 132, 170, 104, 1, 217, 87, - 251, 184, 231, 220, 248, 203, 104, 1, 251, 184, 231, 220, 238, 20, 104, - 1, 217, 87, 251, 184, 231, 220, 219, 159, 21, 22, 210, 242, 21, 22, 250, - 131, 21, 22, 252, 160, 21, 22, 193, 128, 21, 22, 208, 251, 21, 22, 210, - 72, 21, 22, 208, 113, 21, 22, 199, 154, 21, 22, 222, 29, 21, 22, 220, - 176, 21, 22, 217, 21, 21, 22, 212, 250, 21, 22, 214, 198, 21, 22, 219, - 248, 21, 22, 201, 252, 21, 22, 205, 103, 21, 22, 203, 18, 21, 22, 203, - 117, 21, 22, 202, 232, 21, 22, 191, 234, 21, 22, 192, 86, 21, 22, 207, - 122, 21, 22, 212, 107, 21, 22, 211, 128, 212, 107, 21, 22, 212, 106, 21, - 22, 211, 128, 212, 106, 21, 22, 212, 105, 21, 22, 211, 128, 212, 105, 21, - 22, 212, 104, 21, 22, 211, 128, 212, 104, 21, 22, 206, 22, 21, 22, 206, - 21, 21, 22, 206, 20, 21, 22, 206, 19, 21, 22, 206, 18, 21, 22, 206, 26, - 21, 22, 211, 128, 210, 236, 21, 22, 211, 128, 200, 43, 21, 22, 211, 128, - 222, 152, 21, 22, 211, 128, 247, 193, 21, 22, 211, 128, 218, 168, 21, 22, - 211, 128, 215, 61, 21, 22, 211, 128, 206, 8, 21, 22, 211, 128, 203, 167, - 21, 22, 234, 202, 193, 224, 21, 22, 193, 102, 193, 224, 21, 22, 53, 2, - 206, 188, 21, 22, 53, 207, 147, 236, 140, 21, 22, 207, 221, 206, 23, 21, - 22, 193, 103, 219, 8, 21, 22, 193, 103, 220, 125, 21, 22, 198, 202, 21, + 103, 218, 187, 21, 22, 218, 193, 21, 22, 193, 103, 218, 193, 21, 22, 218, + 192, 21, 22, 193, 103, 218, 192, 21, 22, 172, 21, 22, 193, 103, 172, 21, + 22, 216, 219, 172, 21, 22, 205, 69, 21, 22, 205, 196, 21, 22, 202, 223, + 21, 22, 202, 194, 21, 22, 202, 47, 21, 22, 202, 17, 21, 22, 192, 158, + 202, 17, 21, 22, 188, 21, 22, 205, 198, 21, 22, 200, 145, 21, 22, 193, + 103, 200, 145, 21, 22, 200, 139, 21, 22, 193, 103, 200, 139, 21, 22, 200, + 138, 21, 22, 193, 103, 200, 138, 21, 22, 200, 133, 21, 22, 193, 103, 200, + 133, 21, 22, 200, 132, 21, 22, 193, 103, 200, 132, 21, 22, 200, 150, 21, + 22, 193, 103, 200, 150, 21, 22, 200, 149, 21, 22, 193, 103, 200, 149, 21, + 22, 214, 211, 200, 149, 21, 22, 206, 9, 21, 22, 250, 182, 206, 9, 21, 22, + 200, 151, 21, 22, 248, 138, 206, 9, 21, 22, 215, 205, 202, 115, 21, 22, + 214, 211, 202, 102, 21, 22, 214, 211, 206, 7, 21, 22, 214, 211, 201, 193, + 21, 22, 214, 211, 201, 8, 21, 22, 214, 211, 202, 101, 21, 22, 214, 211, + 205, 72, 21, 22, 203, 114, 21, 22, 203, 82, 21, 22, 203, 77, 21, 22, 203, + 57, 21, 22, 203, 49, 21, 22, 203, 166, 21, 22, 203, 161, 21, 22, 202, + 238, 21, 22, 193, 103, 202, 238, 21, 22, 202, 237, 21, 22, 193, 103, 202, + 237, 21, 22, 202, 236, 21, 22, 193, 103, 202, 236, 21, 22, 202, 235, 21, + 22, 193, 103, 202, 235, 21, 22, 202, 234, 21, 22, 193, 103, 202, 234, 21, + 22, 202, 241, 21, 22, 193, 103, 202, 241, 21, 22, 202, 240, 21, 22, 193, + 103, 202, 240, 21, 22, 203, 168, 21, 22, 192, 80, 21, 22, 192, 138, 21, + 22, 192, 33, 21, 22, 192, 23, 21, 22, 192, 12, 21, 22, 191, 246, 21, 22, + 192, 158, 191, 246, 21, 22, 170, 21, 22, 192, 140, 21, 22, 191, 181, 21, + 22, 193, 103, 191, 181, 21, 22, 191, 180, 21, 22, 193, 103, 191, 180, 21, + 22, 191, 179, 21, 22, 193, 103, 191, 179, 21, 22, 191, 178, 21, 22, 193, + 103, 191, 178, 21, 22, 191, 177, 21, 22, 193, 103, 191, 177, 21, 22, 191, + 183, 21, 22, 193, 103, 191, 183, 21, 22, 191, 182, 21, 22, 193, 103, 191, + 182, 21, 22, 214, 211, 191, 182, 21, 22, 192, 159, 21, 22, 248, 188, 192, + 159, 21, 22, 193, 103, 192, 159, 21, 22, 205, 102, 192, 33, 21, 22, 207, + 115, 21, 22, 207, 223, 207, 115, 21, 22, 193, 103, 219, 240, 21, 22, 207, + 179, 21, 22, 207, 2, 21, 22, 206, 196, 21, 22, 206, 163, 21, 22, 206, + 135, 21, 22, 193, 103, 219, 45, 21, 22, 165, 21, 22, 207, 180, 21, 22, + 193, 103, 173, 21, 22, 206, 26, 21, 22, 193, 103, 206, 26, 21, 22, 146, + 21, 22, 193, 103, 146, 21, 22, 216, 219, 146, 21, 22, 233, 61, 21, 22, + 233, 108, 21, 22, 233, 25, 21, 22, 233, 10, 21, 22, 232, 177, 21, 22, + 232, 164, 21, 22, 233, 111, 21, 22, 233, 110, 21, 22, 232, 63, 21, 22, + 193, 103, 232, 63, 21, 22, 233, 177, 21, 22, 199, 33, 21, 22, 215, 61, + 199, 33, 21, 22, 199, 11, 21, 22, 215, 61, 199, 11, 21, 22, 199, 5, 21, + 22, 215, 61, 199, 5, 21, 22, 198, 241, 21, 22, 198, 235, 21, 22, 199, 49, + 21, 22, 199, 48, 21, 22, 198, 203, 21, 22, 193, 103, 198, 203, 21, 22, + 199, 51, 21, 22, 197, 118, 21, 22, 197, 116, 21, 22, 197, 115, 21, 22, + 197, 120, 21, 22, 197, 121, 21, 22, 197, 2, 21, 22, 197, 1, 21, 22, 197, + 0, 21, 22, 197, 4, 21, 22, 212, 131, 229, 247, 21, 22, 212, 131, 229, + 160, 21, 22, 212, 131, 229, 132, 21, 22, 212, 131, 229, 25, 21, 22, 212, + 131, 228, 254, 21, 22, 212, 131, 140, 21, 22, 212, 131, 230, 93, 21, 22, + 212, 131, 230, 118, 21, 22, 212, 130, 230, 118, 21, 22, 229, 115, 21, 22, + 208, 94, 21, 22, 208, 59, 21, 22, 208, 53, 21, 22, 208, 47, 21, 22, 208, + 42, 21, 22, 208, 98, 21, 22, 208, 97, 21, 22, 208, 106, 21, 22, 198, 111, + 21, 22, 198, 109, 21, 22, 198, 108, 21, 22, 198, 112, 21, 22, 193, 103, + 207, 115, 21, 22, 193, 103, 207, 2, 21, 22, 193, 103, 206, 163, 21, 22, + 193, 103, 165, 21, 22, 214, 68, 21, 22, 214, 18, 21, 22, 214, 14, 21, 22, + 213, 251, 21, 22, 213, 246, 21, 22, 214, 70, 21, 22, 214, 69, 21, 22, + 214, 72, 21, 22, 213, 74, 21, 22, 205, 102, 203, 114, 21, 22, 205, 102, + 203, 82, 21, 22, 205, 102, 203, 57, 21, 22, 205, 102, 203, 166, 21, 22, + 193, 27, 199, 33, 21, 22, 193, 27, 199, 11, 21, 22, 193, 27, 198, 241, + 21, 22, 193, 27, 199, 49, 21, 22, 193, 27, 199, 51, 21, 22, 219, 155, 21, + 22, 219, 154, 21, 22, 219, 153, 21, 22, 219, 152, 21, 22, 219, 161, 21, + 22, 219, 160, 21, 22, 219, 162, 21, 22, 199, 50, 199, 33, 21, 22, 199, + 50, 199, 11, 21, 22, 199, 50, 199, 5, 21, 22, 199, 50, 198, 241, 21, 22, + 199, 50, 198, 235, 21, 22, 199, 50, 199, 49, 21, 22, 199, 50, 199, 48, + 21, 22, 199, 50, 199, 51, 21, 22, 251, 222, 250, 122, 21, 22, 248, 138, + 71, 21, 22, 248, 138, 68, 21, 22, 248, 138, 74, 21, 22, 248, 138, 65, 21, + 22, 248, 138, 193, 125, 21, 22, 248, 138, 193, 86, 21, 22, 248, 138, 193, + 48, 21, 22, 248, 138, 193, 190, 21, 22, 248, 138, 214, 123, 21, 22, 248, + 138, 213, 221, 21, 22, 248, 138, 213, 45, 21, 22, 248, 138, 181, 21, 22, + 248, 138, 222, 24, 21, 22, 248, 138, 221, 168, 21, 22, 248, 138, 221, 69, + 21, 22, 248, 138, 155, 21, 22, 205, 102, 229, 247, 21, 22, 205, 102, 229, + 160, 21, 22, 205, 102, 229, 25, 21, 22, 205, 102, 140, 21, 22, 98, 231, + 61, 21, 22, 98, 231, 65, 21, 22, 98, 231, 79, 21, 22, 98, 231, 78, 21, + 22, 98, 231, 67, 21, 22, 98, 231, 93, 21, 22, 98, 206, 69, 21, 22, 98, + 206, 163, 21, 22, 98, 207, 115, 21, 22, 98, 207, 86, 21, 22, 98, 207, 2, + 21, 22, 98, 165, 21, 22, 98, 193, 0, 21, 22, 98, 193, 48, 21, 22, 98, + 193, 125, 21, 22, 98, 193, 114, 21, 22, 98, 193, 86, 21, 22, 98, 193, + 190, 21, 22, 98, 228, 120, 21, 22, 98, 228, 121, 21, 22, 98, 228, 124, + 21, 22, 98, 228, 123, 21, 22, 98, 228, 122, 21, 22, 98, 228, 127, 21, 22, + 98, 198, 213, 21, 22, 98, 198, 241, 21, 22, 98, 199, 33, 21, 22, 98, 199, + 31, 21, 22, 98, 199, 11, 21, 22, 98, 199, 49, 21, 22, 98, 197, 99, 21, + 22, 98, 197, 109, 21, 22, 98, 197, 127, 21, 22, 98, 197, 126, 21, 22, 98, + 197, 111, 21, 22, 98, 197, 132, 21, 22, 98, 208, 167, 21, 22, 98, 209, + 75, 21, 22, 98, 210, 65, 21, 22, 98, 210, 51, 21, 22, 98, 209, 187, 21, + 22, 98, 168, 21, 22, 98, 210, 238, 21, 22, 98, 230, 181, 21, 22, 98, 231, + 5, 21, 22, 98, 231, 167, 21, 22, 98, 231, 159, 21, 22, 98, 231, 55, 21, + 22, 98, 231, 242, 21, 22, 98, 221, 177, 21, 22, 98, 221, 185, 21, 22, 98, + 221, 199, 21, 22, 98, 221, 198, 21, 22, 98, 221, 192, 21, 22, 98, 221, + 217, 21, 22, 98, 221, 98, 21, 22, 98, 221, 99, 21, 22, 98, 221, 102, 21, + 22, 98, 221, 101, 21, 22, 98, 221, 100, 21, 22, 98, 221, 103, 21, 22, 98, + 221, 104, 21, 22, 98, 212, 180, 21, 22, 98, 213, 45, 21, 22, 98, 214, + 123, 21, 22, 98, 214, 112, 21, 22, 98, 213, 221, 21, 22, 98, 181, 21, 22, + 98, 215, 157, 21, 22, 98, 216, 14, 21, 22, 98, 216, 234, 21, 22, 98, 216, + 213, 21, 22, 98, 216, 102, 21, 22, 98, 174, 21, 22, 98, 191, 225, 21, 22, + 98, 192, 12, 21, 22, 98, 192, 80, 21, 22, 98, 192, 77, 21, 22, 98, 192, + 33, 21, 22, 98, 170, 21, 22, 98, 222, 184, 21, 22, 205, 102, 222, 184, + 21, 22, 98, 222, 203, 21, 22, 98, 223, 12, 21, 22, 98, 223, 10, 21, 22, + 98, 222, 246, 21, 22, 205, 102, 222, 246, 21, 22, 98, 223, 34, 21, 22, + 98, 222, 217, 21, 22, 98, 222, 221, 21, 22, 98, 222, 231, 21, 22, 98, + 222, 230, 21, 22, 98, 222, 229, 21, 22, 98, 222, 232, 21, 22, 98, 218, + 227, 21, 22, 98, 219, 45, 21, 22, 98, 219, 240, 21, 22, 98, 219, 230, 21, + 22, 98, 219, 148, 21, 22, 98, 173, 21, 22, 98, 236, 181, 21, 22, 98, 236, + 182, 21, 22, 98, 236, 187, 21, 22, 98, 236, 186, 21, 22, 98, 236, 183, + 21, 22, 98, 236, 188, 21, 22, 98, 219, 151, 21, 22, 98, 219, 153, 21, 22, + 98, 219, 157, 21, 22, 98, 219, 156, 21, 22, 98, 219, 155, 21, 22, 98, + 219, 161, 21, 22, 98, 198, 106, 21, 22, 98, 198, 108, 21, 22, 98, 198, + 111, 21, 22, 98, 198, 110, 21, 22, 98, 198, 109, 21, 22, 98, 198, 112, + 21, 22, 98, 198, 101, 21, 22, 98, 198, 102, 21, 22, 98, 198, 114, 21, 22, + 98, 198, 113, 21, 22, 98, 198, 103, 21, 22, 98, 198, 115, 21, 22, 98, + 190, 251, 21, 22, 98, 191, 7, 21, 22, 98, 191, 87, 21, 22, 98, 191, 84, + 21, 22, 98, 191, 30, 21, 22, 98, 191, 123, 21, 22, 98, 191, 166, 21, 22, + 98, 89, 191, 166, 21, 22, 98, 235, 24, 21, 22, 98, 235, 25, 21, 22, 98, + 235, 34, 21, 22, 98, 235, 33, 21, 22, 98, 235, 28, 21, 22, 98, 235, 37, + 21, 22, 98, 201, 5, 21, 22, 98, 202, 47, 21, 22, 98, 205, 69, 21, 22, 98, + 205, 51, 21, 22, 98, 202, 223, 21, 22, 98, 188, 21, 22, 98, 203, 6, 21, + 22, 98, 203, 57, 21, 22, 98, 203, 114, 21, 22, 98, 203, 112, 21, 22, 98, + 203, 82, 21, 22, 98, 203, 166, 21, 22, 98, 203, 168, 21, 22, 98, 197, + 140, 21, 22, 98, 197, 144, 21, 22, 98, 197, 161, 21, 22, 98, 197, 160, + 21, 22, 98, 197, 146, 21, 22, 98, 197, 168, 21, 22, 98, 243, 50, 21, 22, + 98, 243, 70, 21, 22, 98, 243, 129, 21, 22, 98, 243, 125, 21, 22, 98, 243, + 97, 21, 22, 98, 247, 3, 21, 22, 98, 197, 102, 21, 22, 98, 197, 103, 21, + 22, 98, 197, 106, 21, 22, 98, 197, 105, 21, 22, 98, 197, 104, 21, 22, 98, + 197, 107, 21, 22, 243, 98, 56, 21, 22, 232, 82, 201, 64, 21, 22, 208, 90, + 21, 22, 214, 66, 21, 22, 213, 71, 21, 22, 213, 70, 21, 22, 213, 69, 21, + 22, 213, 68, 21, 22, 213, 73, 21, 22, 213, 72, 21, 22, 193, 27, 198, 201, + 21, 22, 193, 27, 198, 200, 21, 22, 193, 27, 198, 199, 21, 22, 193, 27, + 198, 198, 21, 22, 193, 27, 198, 197, 21, 22, 193, 27, 198, 204, 21, 22, + 193, 27, 198, 203, 21, 22, 193, 27, 53, 199, 51, 21, 22, 248, 138, 193, + 224, 211, 142, 201, 249, 77, 211, 142, 1, 248, 241, 211, 142, 1, 218, + 213, 211, 142, 1, 233, 58, 211, 142, 1, 205, 180, 211, 142, 1, 213, 168, + 211, 142, 1, 196, 165, 211, 142, 1, 238, 7, 211, 142, 1, 198, 139, 211, + 142, 1, 242, 88, 211, 142, 1, 247, 31, 211, 142, 1, 215, 139, 211, 142, + 1, 230, 236, 211, 142, 1, 214, 56, 211, 142, 1, 201, 55, 211, 142, 1, + 206, 56, 211, 142, 1, 251, 234, 211, 142, 1, 211, 93, 211, 142, 1, 196, + 62, 211, 142, 1, 234, 217, 211, 142, 1, 223, 89, 211, 142, 1, 234, 218, + 211, 142, 1, 211, 58, 211, 142, 1, 196, 136, 211, 142, 1, 223, 207, 211, + 142, 1, 234, 215, 211, 142, 1, 210, 40, 211, 142, 233, 57, 77, 211, 142, + 207, 19, 233, 57, 77, 206, 45, 1, 233, 47, 233, 38, 233, 62, 233, 177, + 206, 45, 1, 196, 12, 206, 45, 1, 196, 47, 196, 63, 66, 206, 45, 1, 191, + 228, 206, 45, 1, 192, 159, 206, 45, 1, 193, 224, 206, 45, 1, 198, 206, + 198, 205, 198, 233, 206, 45, 1, 233, 250, 206, 45, 1, 251, 92, 65, 206, + 45, 1, 211, 39, 74, 206, 45, 1, 252, 66, 65, 206, 45, 1, 252, 11, 206, + 45, 1, 219, 17, 74, 206, 45, 1, 203, 34, 74, 206, 45, 1, 74, 206, 45, 1, + 211, 153, 206, 45, 1, 211, 106, 206, 45, 1, 207, 156, 207, 171, 207, 70, + 146, 206, 45, 1, 222, 41, 206, 45, 1, 247, 27, 206, 45, 1, 222, 42, 222, + 154, 206, 45, 1, 232, 53, 206, 45, 1, 234, 90, 206, 45, 1, 231, 162, 230, + 124, 232, 53, 206, 45, 1, 231, 202, 206, 45, 1, 192, 248, 192, 239, 193, + 224, 206, 45, 1, 230, 84, 230, 118, 206, 45, 1, 230, 88, 230, 118, 206, + 45, 1, 219, 19, 230, 118, 206, 45, 1, 203, 37, 230, 118, 206, 45, 1, 214, + 205, 212, 93, 214, 206, 215, 63, 206, 45, 1, 203, 35, 215, 63, 206, 45, + 1, 235, 137, 206, 45, 1, 223, 67, 223, 71, 223, 57, 68, 206, 45, 1, 71, + 206, 45, 1, 223, 1, 223, 37, 206, 45, 1, 231, 143, 206, 45, 1, 219, 20, + 252, 27, 206, 45, 1, 203, 39, 65, 206, 45, 1, 223, 49, 234, 63, 206, 45, + 1, 209, 249, 210, 20, 210, 238, 206, 45, 1, 251, 187, 234, 61, 206, 45, + 1, 201, 255, 206, 9, 206, 45, 1, 202, 199, 219, 16, 206, 9, 206, 45, 1, + 203, 33, 206, 9, 206, 45, 1, 247, 195, 206, 45, 1, 191, 166, 206, 45, 1, + 198, 120, 198, 132, 196, 242, 200, 43, 206, 45, 1, 203, 32, 200, 43, 206, + 45, 1, 238, 129, 206, 45, 1, 248, 219, 248, 222, 248, 144, 250, 122, 206, + 45, 1, 203, 38, 250, 122, 206, 45, 1, 235, 136, 206, 45, 1, 211, 72, 206, + 45, 1, 234, 169, 234, 176, 71, 206, 45, 1, 217, 81, 217, 93, 218, 170, + 206, 45, 1, 219, 18, 218, 170, 206, 45, 1, 203, 36, 218, 170, 206, 45, 1, + 219, 255, 220, 103, 219, 28, 172, 206, 45, 1, 235, 138, 206, 45, 1, 223, + 137, 206, 45, 1, 223, 138, 206, 45, 1, 238, 21, 238, 27, 238, 129, 206, + 45, 1, 211, 30, 233, 249, 74, 206, 45, 1, 234, 213, 206, 45, 1, 223, 87, + 206, 45, 1, 238, 150, 206, 45, 1, 247, 145, 206, 45, 1, 247, 43, 206, 45, + 1, 201, 109, 206, 45, 1, 219, 15, 206, 45, 1, 203, 31, 206, 45, 1, 228, + 27, 206, 45, 1, 208, 106, 206, 45, 1, 192, 235, 206, 45, 202, 171, 208, + 153, 206, 45, 215, 131, 208, 153, 206, 45, 238, 220, 208, 153, 206, 45, + 250, 254, 113, 206, 45, 197, 45, 113, 206, 45, 248, 239, 113, 206, 45, 1, + 222, 154, 206, 45, 1, 203, 168, 206, 45, 1, 211, 89, 206, 45, 1, 232, + 112, 247, 83, 211, 38, 206, 45, 1, 232, 112, 247, 83, 223, 70, 206, 45, + 1, 232, 112, 247, 83, 234, 175, 206, 45, 1, 232, 112, 247, 83, 252, 65, + 206, 45, 1, 232, 112, 247, 83, 252, 11, 199, 222, 1, 65, 199, 222, 1, 68, + 199, 222, 1, 66, 199, 222, 1, 155, 199, 222, 1, 231, 242, 199, 222, 1, + 214, 70, 199, 222, 1, 190, 190, 199, 222, 1, 238, 34, 199, 222, 1, 181, + 199, 222, 1, 168, 199, 222, 1, 249, 155, 199, 222, 1, 174, 199, 222, 1, + 170, 199, 222, 1, 165, 199, 222, 1, 173, 199, 222, 1, 193, 190, 199, 222, + 1, 188, 199, 222, 1, 140, 199, 222, 18, 3, 68, 199, 222, 18, 3, 66, 199, + 222, 3, 195, 40, 199, 222, 3, 210, 171, 199, 222, 1, 251, 16, 165, 230, + 25, 1, 65, 230, 25, 1, 68, 230, 25, 1, 66, 230, 25, 1, 155, 230, 25, 1, + 231, 242, 230, 25, 1, 214, 70, 230, 25, 1, 190, 190, 230, 25, 1, 238, 34, + 230, 25, 1, 181, 230, 25, 1, 168, 230, 25, 1, 249, 155, 230, 25, 1, 174, + 230, 25, 1, 170, 230, 25, 1, 165, 230, 25, 1, 173, 230, 25, 1, 193, 190, + 230, 25, 1, 188, 230, 25, 1, 140, 230, 25, 18, 3, 68, 230, 25, 18, 3, 66, + 230, 25, 3, 210, 171, 209, 206, 202, 171, 208, 153, 209, 206, 55, 208, + 153, 248, 2, 1, 65, 248, 2, 1, 68, 248, 2, 1, 66, 248, 2, 1, 155, 248, 2, + 1, 231, 242, 248, 2, 1, 214, 70, 248, 2, 1, 190, 190, 248, 2, 1, 238, 34, + 248, 2, 1, 181, 248, 2, 1, 168, 248, 2, 1, 249, 155, 248, 2, 1, 174, 248, + 2, 1, 170, 248, 2, 1, 165, 248, 2, 1, 173, 248, 2, 1, 193, 190, 248, 2, + 1, 188, 248, 2, 1, 140, 248, 2, 18, 3, 68, 248, 2, 18, 3, 66, 199, 221, + 1, 65, 199, 221, 1, 68, 199, 221, 1, 66, 199, 221, 1, 155, 199, 221, 1, + 231, 242, 199, 221, 1, 214, 70, 199, 221, 1, 190, 190, 199, 221, 1, 238, + 34, 199, 221, 1, 181, 199, 221, 1, 168, 199, 221, 1, 249, 155, 199, 221, + 1, 174, 199, 221, 1, 170, 199, 221, 1, 173, 199, 221, 1, 193, 190, 199, + 221, 1, 188, 199, 221, 18, 3, 68, 199, 221, 18, 3, 66, 95, 1, 155, 95, 1, + 221, 217, 95, 1, 221, 69, 95, 1, 221, 185, 95, 1, 213, 251, 95, 1, 247, + 162, 95, 1, 247, 3, 95, 1, 242, 101, 95, 1, 243, 70, 95, 1, 212, 67, 95, + 1, 238, 34, 95, 1, 197, 120, 95, 1, 236, 176, 95, 1, 197, 115, 95, 1, + 213, 51, 95, 1, 190, 190, 95, 1, 199, 49, 95, 1, 159, 95, 1, 198, 241, + 95, 1, 213, 45, 95, 1, 249, 155, 95, 1, 209, 230, 95, 1, 209, 75, 95, 1, + 209, 201, 95, 1, 216, 14, 95, 1, 192, 12, 95, 1, 206, 163, 95, 1, 219, + 45, 95, 1, 195, 24, 95, 1, 203, 166, 95, 1, 201, 135, 95, 1, 188, 95, 1, + 140, 95, 1, 173, 95, 1, 208, 98, 95, 223, 151, 18, 208, 84, 95, 223, 151, + 18, 208, 97, 95, 223, 151, 18, 208, 59, 95, 223, 151, 18, 208, 53, 95, + 223, 151, 18, 208, 35, 95, 223, 151, 18, 208, 2, 95, 223, 151, 18, 207, + 246, 95, 223, 151, 18, 207, 245, 95, 223, 151, 18, 206, 18, 95, 223, 151, + 18, 206, 11, 95, 223, 151, 18, 218, 185, 95, 223, 151, 18, 218, 173, 95, + 223, 151, 18, 208, 77, 95, 223, 151, 18, 208, 90, 95, 223, 151, 18, 208, + 43, 196, 255, 107, 95, 223, 151, 18, 208, 43, 196, 255, 109, 95, 223, + 151, 18, 208, 79, 95, 18, 223, 135, 251, 39, 95, 18, 223, 135, 252, 208, + 95, 18, 3, 252, 208, 95, 18, 3, 68, 95, 18, 3, 223, 201, 95, 18, 3, 192, + 159, 95, 18, 3, 191, 176, 95, 18, 3, 66, 95, 18, 3, 196, 30, 95, 18, 3, + 196, 168, 95, 18, 3, 211, 153, 95, 18, 3, 170, 95, 18, 3, 223, 228, 95, + 18, 3, 71, 95, 18, 3, 252, 27, 95, 18, 3, 251, 238, 95, 18, 3, 211, 89, + 95, 18, 3, 250, 165, 95, 3, 213, 186, 95, 3, 207, 108, 95, 3, 191, 187, + 95, 3, 215, 93, 95, 3, 197, 229, 95, 3, 249, 92, 95, 3, 206, 152, 95, 3, + 198, 90, 95, 3, 222, 97, 95, 3, 251, 240, 95, 3, 205, 144, 205, 136, 95, + 3, 195, 37, 95, 3, 242, 92, 95, 3, 249, 62, 95, 3, 221, 207, 95, 3, 249, + 87, 95, 3, 247, 133, 209, 148, 220, 188, 95, 3, 219, 207, 198, 59, 95, 3, + 248, 207, 95, 3, 209, 203, 215, 150, 95, 3, 221, 41, 95, 238, 172, 16, + 206, 242, 95, 3, 250, 146, 95, 3, 250, 168, 95, 17, 191, 77, 95, 17, 107, + 95, 17, 109, 95, 17, 138, 95, 17, 134, 95, 17, 150, 95, 17, 169, 95, 17, + 175, 95, 17, 171, 95, 17, 178, 95, 16, 219, 207, 250, 170, 202, 20, 95, + 16, 219, 207, 250, 170, 215, 114, 95, 16, 219, 207, 250, 170, 209, 147, + 95, 16, 219, 207, 250, 170, 248, 242, 95, 16, 219, 207, 250, 170, 247, + 238, 95, 16, 219, 207, 250, 170, 208, 247, 95, 16, 219, 207, 250, 170, + 208, 241, 95, 16, 219, 207, 250, 170, 208, 239, 95, 16, 219, 207, 250, + 170, 208, 245, 95, 16, 219, 207, 250, 170, 208, 243, 104, 248, 160, 104, + 234, 122, 104, 242, 76, 104, 232, 82, 201, 64, 104, 242, 85, 104, 232, + 130, 236, 140, 104, 198, 88, 202, 33, 228, 90, 104, 202, 215, 5, 248, 75, + 217, 53, 104, 217, 89, 242, 76, 104, 217, 89, 232, 82, 201, 64, 104, 213, + 166, 104, 232, 111, 67, 205, 36, 107, 104, 232, 111, 67, 205, 36, 109, + 104, 232, 111, 67, 205, 36, 138, 104, 18, 204, 11, 104, 232, 111, 67, + 205, 36, 134, 104, 17, 191, 77, 104, 17, 107, 104, 17, 109, 104, 17, 138, + 104, 17, 134, 104, 17, 150, 104, 17, 169, 104, 17, 175, 104, 17, 171, + 104, 17, 178, 104, 1, 65, 104, 1, 71, 104, 1, 68, 104, 1, 74, 104, 1, 66, + 104, 1, 211, 153, 104, 1, 196, 152, 104, 1, 234, 190, 104, 1, 181, 104, + 1, 251, 124, 104, 1, 249, 155, 104, 1, 168, 104, 1, 208, 98, 104, 1, 231, + 242, 104, 1, 174, 104, 1, 173, 104, 1, 188, 104, 1, 203, 166, 104, 1, + 190, 190, 104, 1, 238, 34, 104, 1, 247, 3, 104, 1, 223, 34, 104, 1, 170, + 104, 1, 165, 104, 1, 193, 190, 104, 1, 233, 111, 104, 1, 155, 104, 1, + 221, 217, 104, 1, 197, 168, 104, 1, 191, 123, 104, 1, 230, 93, 104, 1, + 190, 255, 104, 1, 219, 161, 104, 1, 191, 57, 104, 1, 243, 97, 104, 1, + 198, 88, 180, 18, 56, 104, 1, 198, 88, 71, 104, 1, 198, 88, 68, 104, 1, + 198, 88, 74, 104, 1, 198, 88, 66, 104, 1, 198, 88, 211, 153, 104, 1, 198, + 88, 196, 152, 104, 1, 198, 88, 251, 124, 104, 1, 198, 88, 249, 155, 104, + 1, 198, 88, 168, 104, 1, 198, 88, 208, 98, 104, 1, 198, 88, 231, 242, + 104, 1, 198, 88, 174, 104, 1, 198, 88, 190, 190, 104, 1, 198, 88, 238, + 34, 104, 1, 198, 88, 247, 3, 104, 1, 198, 88, 223, 34, 104, 1, 198, 88, + 197, 168, 104, 1, 198, 88, 170, 104, 1, 198, 88, 193, 190, 104, 1, 198, + 88, 155, 104, 1, 198, 88, 231, 239, 104, 1, 198, 88, 230, 93, 104, 1, + 198, 88, 222, 245, 104, 1, 198, 88, 213, 211, 104, 1, 198, 88, 235, 37, + 104, 1, 202, 215, 71, 104, 1, 202, 215, 68, 104, 1, 202, 215, 223, 46, + 104, 1, 202, 215, 196, 152, 104, 1, 202, 215, 66, 104, 1, 202, 215, 251, + 124, 104, 1, 202, 215, 155, 104, 1, 202, 215, 231, 242, 104, 1, 202, 215, + 140, 104, 1, 202, 215, 168, 104, 1, 202, 215, 203, 166, 104, 1, 202, 215, + 190, 190, 104, 1, 202, 215, 238, 34, 104, 1, 202, 215, 223, 34, 104, 1, + 202, 215, 233, 111, 104, 1, 202, 215, 231, 239, 104, 1, 202, 215, 230, + 93, 104, 1, 202, 215, 197, 168, 104, 1, 202, 215, 191, 123, 104, 1, 202, + 215, 207, 180, 104, 1, 202, 215, 247, 3, 104, 1, 202, 215, 191, 71, 104, + 1, 217, 89, 68, 104, 1, 217, 89, 155, 104, 1, 217, 89, 165, 104, 1, 217, + 89, 233, 111, 104, 1, 217, 89, 191, 71, 104, 1, 247, 4, 4, 105, 236, 140, + 104, 1, 251, 186, 231, 222, 251, 74, 107, 104, 1, 251, 186, 231, 222, + 195, 36, 107, 104, 1, 251, 186, 231, 222, 237, 249, 104, 1, 251, 186, + 231, 222, 196, 163, 104, 1, 251, 186, 231, 222, 223, 95, 196, 163, 104, + 1, 251, 186, 231, 222, 249, 106, 104, 1, 251, 186, 231, 222, 115, 249, + 106, 104, 1, 251, 186, 231, 222, 65, 104, 1, 251, 186, 231, 222, 68, 104, + 1, 251, 186, 231, 222, 155, 104, 1, 251, 186, 231, 222, 214, 70, 104, 1, + 251, 186, 231, 222, 247, 162, 104, 1, 251, 186, 231, 222, 197, 132, 104, + 1, 251, 186, 231, 222, 197, 120, 104, 1, 251, 186, 231, 222, 237, 193, + 104, 1, 251, 186, 231, 222, 213, 81, 104, 1, 251, 186, 231, 222, 190, + 190, 104, 1, 251, 186, 231, 222, 238, 34, 104, 1, 251, 186, 231, 222, + 168, 104, 1, 251, 186, 231, 222, 209, 230, 104, 1, 251, 186, 231, 222, + 201, 176, 104, 1, 251, 186, 231, 222, 191, 71, 104, 1, 251, 186, 231, + 222, 191, 123, 104, 1, 251, 186, 231, 222, 251, 247, 104, 1, 198, 88, + 251, 186, 231, 222, 190, 190, 104, 1, 198, 88, 251, 186, 231, 222, 191, + 71, 104, 1, 217, 89, 251, 186, 231, 222, 231, 93, 104, 1, 217, 89, 251, + 186, 231, 222, 214, 70, 104, 1, 217, 89, 251, 186, 231, 222, 247, 162, + 104, 1, 217, 89, 251, 186, 231, 222, 222, 254, 104, 1, 217, 89, 251, 186, + 231, 222, 197, 132, 104, 1, 217, 89, 251, 186, 231, 222, 237, 177, 104, + 1, 217, 89, 251, 186, 231, 222, 190, 190, 104, 1, 217, 89, 251, 186, 231, + 222, 237, 70, 104, 1, 217, 89, 251, 186, 231, 222, 201, 176, 104, 1, 217, + 89, 251, 186, 231, 222, 238, 144, 104, 1, 217, 89, 251, 186, 231, 222, + 191, 71, 104, 1, 217, 89, 251, 186, 231, 222, 191, 123, 104, 1, 251, 186, + 231, 222, 132, 66, 104, 1, 251, 186, 231, 222, 132, 170, 104, 1, 217, 89, + 251, 186, 231, 222, 248, 205, 104, 1, 251, 186, 231, 222, 238, 22, 104, + 1, 217, 89, 251, 186, 231, 222, 219, 161, 21, 22, 210, 244, 21, 22, 250, + 133, 21, 22, 252, 162, 21, 22, 193, 128, 21, 22, 208, 253, 21, 22, 210, + 74, 21, 22, 208, 115, 21, 22, 199, 154, 21, 22, 222, 31, 21, 22, 220, + 178, 21, 22, 217, 23, 21, 22, 212, 252, 21, 22, 214, 200, 21, 22, 219, + 250, 21, 22, 201, 253, 21, 22, 205, 104, 21, 22, 203, 19, 21, 22, 203, + 118, 21, 22, 202, 233, 21, 22, 191, 234, 21, 22, 192, 86, 21, 22, 207, + 124, 21, 22, 212, 109, 21, 22, 211, 130, 212, 109, 21, 22, 212, 108, 21, + 22, 211, 130, 212, 108, 21, 22, 212, 107, 21, 22, 211, 130, 212, 107, 21, + 22, 212, 106, 21, 22, 211, 130, 212, 106, 21, 22, 206, 23, 21, 22, 206, + 22, 21, 22, 206, 21, 21, 22, 206, 20, 21, 22, 206, 19, 21, 22, 206, 27, + 21, 22, 211, 130, 210, 238, 21, 22, 211, 130, 200, 43, 21, 22, 211, 130, + 222, 154, 21, 22, 211, 130, 247, 195, 21, 22, 211, 130, 218, 170, 21, 22, + 211, 130, 215, 63, 21, 22, 211, 130, 206, 9, 21, 22, 211, 130, 203, 168, + 21, 22, 234, 204, 193, 224, 21, 22, 193, 102, 193, 224, 21, 22, 53, 2, + 206, 189, 21, 22, 53, 207, 149, 236, 142, 21, 22, 207, 223, 206, 24, 21, + 22, 193, 103, 219, 10, 21, 22, 193, 103, 220, 127, 21, 22, 198, 202, 21, 22, 198, 204, 21, 22, 197, 112, 21, 22, 197, 114, 21, 22, 197, 119, 21, - 22, 198, 105, 21, 22, 198, 107, 21, 22, 205, 101, 202, 237, 21, 22, 205, - 101, 203, 48, 21, 22, 205, 101, 228, 252, 21, 22, 98, 230, 130, 21, 22, - 98, 237, 103, 231, 157, 21, 22, 98, 231, 237, 21, 22, 98, 230, 135, 21, - 22, 205, 101, 222, 162, 21, 22, 98, 222, 160, 21, 22, 249, 5, 237, 103, - 172, 21, 22, 249, 5, 237, 103, 146, 21, 22, 98, 237, 98, 206, 8, 219, - 122, 195, 1, 219, 175, 219, 122, 1, 155, 219, 122, 1, 221, 215, 219, 122, - 1, 231, 240, 219, 122, 1, 231, 91, 219, 122, 1, 214, 68, 219, 122, 1, - 247, 160, 219, 122, 1, 247, 1, 219, 122, 1, 223, 32, 219, 122, 1, 222, - 252, 219, 122, 1, 192, 108, 219, 122, 1, 190, 190, 219, 122, 1, 199, 49, - 219, 122, 1, 238, 32, 219, 122, 1, 237, 68, 219, 122, 1, 180, 219, 122, - 1, 168, 219, 122, 1, 209, 228, 219, 122, 1, 249, 153, 219, 122, 1, 248, - 203, 219, 122, 1, 174, 219, 122, 1, 170, 219, 122, 1, 165, 219, 122, 1, - 173, 219, 122, 1, 193, 190, 219, 122, 1, 203, 165, 219, 122, 1, 201, 175, - 219, 122, 1, 188, 219, 122, 1, 140, 219, 122, 1, 230, 126, 219, 122, 1, - 198, 26, 219, 122, 18, 3, 65, 219, 122, 18, 3, 68, 219, 122, 18, 3, 66, - 219, 122, 18, 3, 234, 188, 219, 122, 18, 3, 251, 236, 219, 122, 18, 3, - 211, 87, 219, 122, 18, 3, 250, 163, 219, 122, 18, 3, 71, 219, 122, 18, 3, - 74, 219, 122, 200, 239, 1, 170, 219, 122, 200, 239, 1, 165, 219, 122, - 200, 239, 1, 193, 190, 219, 122, 2, 1, 155, 219, 122, 2, 1, 214, 68, 219, - 122, 2, 1, 251, 71, 219, 122, 2, 1, 190, 190, 219, 122, 2, 1, 180, 219, - 122, 2, 1, 168, 219, 122, 2, 1, 174, 219, 122, 2, 1, 165, 219, 122, 2, 1, - 173, 219, 122, 3, 215, 134, 219, 122, 3, 222, 1, 219, 122, 3, 205, 198, - 219, 122, 3, 219, 8, 219, 122, 233, 216, 77, 219, 122, 208, 13, 77, 219, - 122, 17, 191, 77, 219, 122, 17, 107, 219, 122, 17, 109, 219, 122, 17, - 138, 219, 122, 17, 134, 219, 122, 17, 149, 219, 122, 17, 169, 219, 122, - 17, 175, 219, 122, 17, 171, 219, 122, 17, 178, 54, 219, 239, 1, 155, 54, - 219, 239, 1, 192, 220, 54, 219, 239, 1, 214, 68, 54, 219, 239, 1, 197, - 168, 54, 219, 239, 1, 188, 54, 219, 239, 1, 170, 54, 219, 239, 1, 190, - 190, 54, 219, 239, 1, 199, 49, 54, 219, 239, 1, 173, 54, 219, 239, 1, - 168, 54, 219, 239, 1, 209, 228, 54, 219, 239, 1, 174, 54, 219, 239, 1, - 233, 109, 54, 219, 239, 1, 195, 188, 54, 219, 239, 1, 140, 54, 219, 239, - 1, 208, 96, 54, 219, 239, 1, 221, 215, 54, 219, 239, 1, 197, 157, 54, - 219, 239, 1, 180, 54, 219, 239, 1, 65, 54, 219, 239, 1, 68, 54, 219, 239, - 1, 234, 188, 54, 219, 239, 1, 234, 173, 54, 219, 239, 1, 66, 54, 219, - 239, 1, 211, 87, 54, 219, 239, 1, 74, 54, 219, 239, 1, 196, 152, 54, 219, - 239, 1, 71, 54, 219, 239, 1, 250, 161, 54, 219, 239, 1, 251, 236, 54, - 219, 239, 1, 198, 77, 54, 219, 239, 1, 198, 76, 54, 219, 239, 1, 198, 75, - 54, 219, 239, 1, 198, 74, 54, 219, 239, 1, 198, 73, 214, 80, 54, 218, - 219, 1, 137, 208, 96, 214, 80, 54, 218, 219, 1, 130, 208, 96, 214, 80, - 54, 218, 219, 1, 137, 155, 214, 80, 54, 218, 219, 1, 137, 192, 220, 214, - 80, 54, 218, 219, 1, 137, 214, 68, 214, 80, 54, 218, 219, 1, 130, 155, - 214, 80, 54, 218, 219, 1, 130, 192, 220, 214, 80, 54, 218, 219, 1, 130, - 214, 68, 214, 80, 54, 218, 219, 1, 137, 197, 168, 214, 80, 54, 218, 219, - 1, 137, 188, 214, 80, 54, 218, 219, 1, 137, 170, 214, 80, 54, 218, 219, - 1, 130, 197, 168, 214, 80, 54, 218, 219, 1, 130, 188, 214, 80, 54, 218, - 219, 1, 130, 170, 214, 80, 54, 218, 219, 1, 137, 190, 190, 214, 80, 54, - 218, 219, 1, 137, 199, 49, 214, 80, 54, 218, 219, 1, 137, 180, 214, 80, - 54, 218, 219, 1, 130, 190, 190, 214, 80, 54, 218, 219, 1, 130, 199, 49, - 214, 80, 54, 218, 219, 1, 130, 180, 214, 80, 54, 218, 219, 1, 137, 168, - 214, 80, 54, 218, 219, 1, 137, 209, 228, 214, 80, 54, 218, 219, 1, 137, - 174, 214, 80, 54, 218, 219, 1, 130, 168, 214, 80, 54, 218, 219, 1, 130, - 209, 228, 214, 80, 54, 218, 219, 1, 130, 174, 214, 80, 54, 218, 219, 1, - 137, 233, 109, 214, 80, 54, 218, 219, 1, 137, 195, 188, 214, 80, 54, 218, - 219, 1, 137, 173, 214, 80, 54, 218, 219, 1, 130, 233, 109, 214, 80, 54, - 218, 219, 1, 130, 195, 188, 214, 80, 54, 218, 219, 1, 130, 173, 214, 80, - 54, 218, 219, 1, 137, 140, 214, 80, 54, 218, 219, 1, 137, 238, 32, 214, - 80, 54, 218, 219, 1, 137, 249, 153, 214, 80, 54, 218, 219, 1, 130, 140, - 214, 80, 54, 218, 219, 1, 130, 238, 32, 214, 80, 54, 218, 219, 1, 130, - 249, 153, 214, 80, 54, 218, 219, 1, 137, 220, 181, 214, 80, 54, 218, 219, - 1, 137, 192, 185, 214, 80, 54, 218, 219, 1, 130, 220, 181, 214, 80, 54, - 218, 219, 1, 130, 192, 185, 214, 80, 54, 218, 219, 1, 137, 200, 251, 214, - 80, 54, 218, 219, 1, 130, 200, 251, 214, 80, 54, 218, 219, 18, 3, 18, - 203, 28, 214, 80, 54, 218, 219, 18, 3, 252, 206, 214, 80, 54, 218, 219, - 18, 3, 223, 199, 214, 80, 54, 218, 219, 18, 3, 66, 214, 80, 54, 218, 219, - 18, 3, 196, 30, 214, 80, 54, 218, 219, 18, 3, 71, 214, 80, 54, 218, 219, - 18, 3, 252, 25, 214, 80, 54, 218, 219, 18, 3, 74, 214, 80, 54, 218, 219, - 18, 3, 211, 182, 214, 80, 54, 218, 219, 18, 3, 196, 152, 214, 80, 54, - 218, 219, 18, 3, 250, 131, 214, 80, 54, 218, 219, 18, 3, 252, 160, 214, - 80, 54, 218, 219, 18, 3, 196, 21, 214, 80, 54, 218, 219, 18, 3, 210, 242, - 214, 80, 54, 218, 219, 18, 3, 211, 179, 214, 80, 54, 218, 219, 18, 3, - 196, 144, 214, 80, 54, 218, 219, 18, 3, 223, 44, 214, 80, 54, 218, 219, - 1, 53, 196, 12, 214, 80, 54, 218, 219, 1, 53, 214, 70, 214, 80, 54, 218, - 219, 1, 53, 215, 61, 214, 80, 54, 218, 219, 1, 53, 218, 168, 214, 80, 54, - 218, 219, 1, 53, 222, 152, 214, 80, 54, 218, 219, 1, 53, 238, 127, 214, - 80, 54, 218, 219, 1, 53, 250, 120, 214, 80, 54, 218, 219, 163, 217, 55, - 214, 80, 54, 218, 219, 163, 217, 54, 214, 80, 54, 218, 219, 17, 191, 77, - 214, 80, 54, 218, 219, 17, 107, 214, 80, 54, 218, 219, 17, 109, 214, 80, - 54, 218, 219, 17, 138, 214, 80, 54, 218, 219, 17, 134, 214, 80, 54, 218, - 219, 17, 149, 214, 80, 54, 218, 219, 17, 169, 214, 80, 54, 218, 219, 17, - 175, 214, 80, 54, 218, 219, 17, 171, 214, 80, 54, 218, 219, 17, 178, 214, - 80, 54, 218, 219, 128, 17, 107, 214, 80, 54, 218, 219, 3, 220, 107, 214, - 80, 54, 218, 219, 3, 220, 106, 95, 16, 210, 84, 95, 16, 215, 113, 221, - 58, 95, 16, 209, 146, 221, 58, 95, 16, 248, 241, 221, 58, 95, 16, 247, - 237, 221, 58, 95, 16, 208, 246, 221, 58, 95, 16, 208, 240, 221, 58, 95, - 16, 208, 238, 221, 58, 95, 16, 208, 244, 221, 58, 95, 16, 208, 242, 221, - 58, 95, 16, 237, 232, 221, 58, 95, 16, 237, 228, 221, 58, 95, 16, 237, - 227, 221, 58, 95, 16, 237, 230, 221, 58, 95, 16, 237, 229, 221, 58, 95, - 16, 237, 226, 221, 58, 95, 16, 197, 51, 95, 16, 215, 113, 206, 149, 95, - 16, 209, 146, 206, 149, 95, 16, 248, 241, 206, 149, 95, 16, 247, 237, - 206, 149, 95, 16, 208, 246, 206, 149, 95, 16, 208, 240, 206, 149, 95, 16, - 208, 238, 206, 149, 95, 16, 208, 244, 206, 149, 95, 16, 208, 242, 206, - 149, 95, 16, 237, 232, 206, 149, 95, 16, 237, 228, 206, 149, 95, 16, 237, - 227, 206, 149, 95, 16, 237, 230, 206, 149, 95, 16, 237, 229, 206, 149, - 95, 16, 237, 226, 206, 149, 248, 1, 1, 155, 248, 1, 1, 231, 240, 248, 1, - 1, 214, 68, 248, 1, 1, 214, 11, 248, 1, 1, 168, 248, 1, 1, 249, 153, 248, - 1, 1, 174, 248, 1, 1, 215, 166, 248, 1, 1, 190, 190, 248, 1, 1, 238, 32, - 248, 1, 1, 180, 248, 1, 1, 212, 244, 248, 1, 1, 247, 160, 248, 1, 1, 223, - 32, 248, 1, 1, 212, 101, 248, 1, 1, 212, 92, 248, 1, 1, 170, 248, 1, 1, - 165, 248, 1, 1, 173, 248, 1, 1, 195, 188, 248, 1, 1, 188, 248, 1, 1, 65, - 248, 1, 1, 140, 248, 1, 18, 3, 68, 248, 1, 18, 3, 66, 248, 1, 18, 3, 71, - 248, 1, 18, 3, 74, 248, 1, 18, 3, 252, 25, 248, 1, 210, 184, 248, 1, 234, - 95, 79, 205, 53, 54, 128, 1, 137, 155, 54, 128, 1, 137, 221, 215, 54, - 128, 1, 137, 220, 165, 54, 128, 1, 130, 155, 54, 128, 1, 130, 220, 165, - 54, 128, 1, 130, 221, 215, 54, 128, 1, 214, 68, 54, 128, 1, 137, 247, - 160, 54, 128, 1, 137, 247, 1, 54, 128, 1, 130, 247, 160, 54, 128, 1, 130, - 188, 54, 128, 1, 130, 247, 1, 54, 128, 1, 212, 101, 54, 128, 1, 207, 129, - 54, 128, 1, 137, 207, 127, 54, 128, 1, 238, 32, 54, 128, 1, 130, 207, - 127, 54, 128, 1, 207, 138, 54, 128, 1, 137, 190, 190, 54, 128, 1, 137, + 22, 198, 105, 21, 22, 198, 107, 21, 22, 205, 102, 202, 238, 21, 22, 205, + 102, 203, 49, 21, 22, 205, 102, 228, 254, 21, 22, 98, 230, 132, 21, 22, + 98, 237, 105, 231, 159, 21, 22, 98, 231, 239, 21, 22, 98, 230, 137, 21, + 22, 205, 102, 222, 164, 21, 22, 98, 222, 162, 21, 22, 249, 7, 237, 105, + 172, 21, 22, 249, 7, 237, 105, 146, 21, 22, 98, 237, 100, 206, 9, 219, + 124, 195, 1, 219, 177, 219, 124, 1, 155, 219, 124, 1, 221, 217, 219, 124, + 1, 231, 242, 219, 124, 1, 231, 93, 219, 124, 1, 214, 70, 219, 124, 1, + 247, 162, 219, 124, 1, 247, 3, 219, 124, 1, 223, 34, 219, 124, 1, 222, + 254, 219, 124, 1, 192, 108, 219, 124, 1, 190, 190, 219, 124, 1, 199, 49, + 219, 124, 1, 238, 34, 219, 124, 1, 237, 70, 219, 124, 1, 181, 219, 124, + 1, 168, 219, 124, 1, 209, 230, 219, 124, 1, 249, 155, 219, 124, 1, 248, + 205, 219, 124, 1, 174, 219, 124, 1, 170, 219, 124, 1, 165, 219, 124, 1, + 173, 219, 124, 1, 193, 190, 219, 124, 1, 203, 166, 219, 124, 1, 201, 176, + 219, 124, 1, 188, 219, 124, 1, 140, 219, 124, 1, 230, 128, 219, 124, 1, + 198, 26, 219, 124, 18, 3, 65, 219, 124, 18, 3, 68, 219, 124, 18, 3, 66, + 219, 124, 18, 3, 234, 190, 219, 124, 18, 3, 251, 238, 219, 124, 18, 3, + 211, 89, 219, 124, 18, 3, 250, 165, 219, 124, 18, 3, 71, 219, 124, 18, 3, + 74, 219, 124, 200, 240, 1, 170, 219, 124, 200, 240, 1, 165, 219, 124, + 200, 240, 1, 193, 190, 219, 124, 2, 1, 155, 219, 124, 2, 1, 214, 70, 219, + 124, 2, 1, 251, 73, 219, 124, 2, 1, 190, 190, 219, 124, 2, 1, 181, 219, + 124, 2, 1, 168, 219, 124, 2, 1, 174, 219, 124, 2, 1, 165, 219, 124, 2, 1, + 173, 219, 124, 3, 215, 136, 219, 124, 3, 222, 3, 219, 124, 3, 205, 199, + 219, 124, 3, 219, 10, 219, 124, 233, 218, 77, 219, 124, 208, 15, 77, 219, + 124, 17, 191, 77, 219, 124, 17, 107, 219, 124, 17, 109, 219, 124, 17, + 138, 219, 124, 17, 134, 219, 124, 17, 150, 219, 124, 17, 169, 219, 124, + 17, 175, 219, 124, 17, 171, 219, 124, 17, 178, 54, 219, 241, 1, 155, 54, + 219, 241, 1, 192, 220, 54, 219, 241, 1, 214, 70, 54, 219, 241, 1, 197, + 168, 54, 219, 241, 1, 188, 54, 219, 241, 1, 170, 54, 219, 241, 1, 190, + 190, 54, 219, 241, 1, 199, 49, 54, 219, 241, 1, 173, 54, 219, 241, 1, + 168, 54, 219, 241, 1, 209, 230, 54, 219, 241, 1, 174, 54, 219, 241, 1, + 233, 111, 54, 219, 241, 1, 195, 188, 54, 219, 241, 1, 140, 54, 219, 241, + 1, 208, 98, 54, 219, 241, 1, 221, 217, 54, 219, 241, 1, 197, 157, 54, + 219, 241, 1, 181, 54, 219, 241, 1, 65, 54, 219, 241, 1, 68, 54, 219, 241, + 1, 234, 190, 54, 219, 241, 1, 234, 175, 54, 219, 241, 1, 66, 54, 219, + 241, 1, 211, 89, 54, 219, 241, 1, 74, 54, 219, 241, 1, 196, 152, 54, 219, + 241, 1, 71, 54, 219, 241, 1, 250, 163, 54, 219, 241, 1, 251, 238, 54, + 219, 241, 1, 198, 77, 54, 219, 241, 1, 198, 76, 54, 219, 241, 1, 198, 75, + 54, 219, 241, 1, 198, 74, 54, 219, 241, 1, 198, 73, 214, 82, 54, 218, + 221, 1, 137, 208, 98, 214, 82, 54, 218, 221, 1, 130, 208, 98, 214, 82, + 54, 218, 221, 1, 137, 155, 214, 82, 54, 218, 221, 1, 137, 192, 220, 214, + 82, 54, 218, 221, 1, 137, 214, 70, 214, 82, 54, 218, 221, 1, 130, 155, + 214, 82, 54, 218, 221, 1, 130, 192, 220, 214, 82, 54, 218, 221, 1, 130, + 214, 70, 214, 82, 54, 218, 221, 1, 137, 197, 168, 214, 82, 54, 218, 221, + 1, 137, 188, 214, 82, 54, 218, 221, 1, 137, 170, 214, 82, 54, 218, 221, + 1, 130, 197, 168, 214, 82, 54, 218, 221, 1, 130, 188, 214, 82, 54, 218, + 221, 1, 130, 170, 214, 82, 54, 218, 221, 1, 137, 190, 190, 214, 82, 54, + 218, 221, 1, 137, 199, 49, 214, 82, 54, 218, 221, 1, 137, 181, 214, 82, + 54, 218, 221, 1, 130, 190, 190, 214, 82, 54, 218, 221, 1, 130, 199, 49, + 214, 82, 54, 218, 221, 1, 130, 181, 214, 82, 54, 218, 221, 1, 137, 168, + 214, 82, 54, 218, 221, 1, 137, 209, 230, 214, 82, 54, 218, 221, 1, 137, + 174, 214, 82, 54, 218, 221, 1, 130, 168, 214, 82, 54, 218, 221, 1, 130, + 209, 230, 214, 82, 54, 218, 221, 1, 130, 174, 214, 82, 54, 218, 221, 1, + 137, 233, 111, 214, 82, 54, 218, 221, 1, 137, 195, 188, 214, 82, 54, 218, + 221, 1, 137, 173, 214, 82, 54, 218, 221, 1, 130, 233, 111, 214, 82, 54, + 218, 221, 1, 130, 195, 188, 214, 82, 54, 218, 221, 1, 130, 173, 214, 82, + 54, 218, 221, 1, 137, 140, 214, 82, 54, 218, 221, 1, 137, 238, 34, 214, + 82, 54, 218, 221, 1, 137, 249, 155, 214, 82, 54, 218, 221, 1, 130, 140, + 214, 82, 54, 218, 221, 1, 130, 238, 34, 214, 82, 54, 218, 221, 1, 130, + 249, 155, 214, 82, 54, 218, 221, 1, 137, 220, 183, 214, 82, 54, 218, 221, + 1, 137, 192, 185, 214, 82, 54, 218, 221, 1, 130, 220, 183, 214, 82, 54, + 218, 221, 1, 130, 192, 185, 214, 82, 54, 218, 221, 1, 137, 200, 252, 214, + 82, 54, 218, 221, 1, 130, 200, 252, 214, 82, 54, 218, 221, 18, 3, 18, + 203, 29, 214, 82, 54, 218, 221, 18, 3, 252, 208, 214, 82, 54, 218, 221, + 18, 3, 223, 201, 214, 82, 54, 218, 221, 18, 3, 66, 214, 82, 54, 218, 221, + 18, 3, 196, 30, 214, 82, 54, 218, 221, 18, 3, 71, 214, 82, 54, 218, 221, + 18, 3, 252, 27, 214, 82, 54, 218, 221, 18, 3, 74, 214, 82, 54, 218, 221, + 18, 3, 211, 184, 214, 82, 54, 218, 221, 18, 3, 196, 152, 214, 82, 54, + 218, 221, 18, 3, 250, 133, 214, 82, 54, 218, 221, 18, 3, 252, 162, 214, + 82, 54, 218, 221, 18, 3, 196, 21, 214, 82, 54, 218, 221, 18, 3, 210, 244, + 214, 82, 54, 218, 221, 18, 3, 211, 181, 214, 82, 54, 218, 221, 18, 3, + 196, 144, 214, 82, 54, 218, 221, 18, 3, 223, 46, 214, 82, 54, 218, 221, + 1, 53, 196, 12, 214, 82, 54, 218, 221, 1, 53, 214, 72, 214, 82, 54, 218, + 221, 1, 53, 215, 63, 214, 82, 54, 218, 221, 1, 53, 218, 170, 214, 82, 54, + 218, 221, 1, 53, 222, 154, 214, 82, 54, 218, 221, 1, 53, 238, 129, 214, + 82, 54, 218, 221, 1, 53, 250, 122, 214, 82, 54, 218, 221, 163, 217, 57, + 214, 82, 54, 218, 221, 163, 217, 56, 214, 82, 54, 218, 221, 17, 191, 77, + 214, 82, 54, 218, 221, 17, 107, 214, 82, 54, 218, 221, 17, 109, 214, 82, + 54, 218, 221, 17, 138, 214, 82, 54, 218, 221, 17, 134, 214, 82, 54, 218, + 221, 17, 150, 214, 82, 54, 218, 221, 17, 169, 214, 82, 54, 218, 221, 17, + 175, 214, 82, 54, 218, 221, 17, 171, 214, 82, 54, 218, 221, 17, 178, 214, + 82, 54, 218, 221, 128, 17, 107, 214, 82, 54, 218, 221, 3, 220, 109, 214, + 82, 54, 218, 221, 3, 220, 108, 95, 16, 210, 86, 95, 16, 215, 115, 221, + 60, 95, 16, 209, 148, 221, 60, 95, 16, 248, 243, 221, 60, 95, 16, 247, + 239, 221, 60, 95, 16, 208, 248, 221, 60, 95, 16, 208, 242, 221, 60, 95, + 16, 208, 240, 221, 60, 95, 16, 208, 246, 221, 60, 95, 16, 208, 244, 221, + 60, 95, 16, 237, 234, 221, 60, 95, 16, 237, 230, 221, 60, 95, 16, 237, + 229, 221, 60, 95, 16, 237, 232, 221, 60, 95, 16, 237, 231, 221, 60, 95, + 16, 237, 228, 221, 60, 95, 16, 197, 51, 95, 16, 215, 115, 206, 150, 95, + 16, 209, 148, 206, 150, 95, 16, 248, 243, 206, 150, 95, 16, 247, 239, + 206, 150, 95, 16, 208, 248, 206, 150, 95, 16, 208, 242, 206, 150, 95, 16, + 208, 240, 206, 150, 95, 16, 208, 246, 206, 150, 95, 16, 208, 244, 206, + 150, 95, 16, 237, 234, 206, 150, 95, 16, 237, 230, 206, 150, 95, 16, 237, + 229, 206, 150, 95, 16, 237, 232, 206, 150, 95, 16, 237, 231, 206, 150, + 95, 16, 237, 228, 206, 150, 248, 3, 1, 155, 248, 3, 1, 231, 242, 248, 3, + 1, 214, 70, 248, 3, 1, 214, 13, 248, 3, 1, 168, 248, 3, 1, 249, 155, 248, + 3, 1, 174, 248, 3, 1, 215, 168, 248, 3, 1, 190, 190, 248, 3, 1, 238, 34, + 248, 3, 1, 181, 248, 3, 1, 212, 246, 248, 3, 1, 247, 162, 248, 3, 1, 223, + 34, 248, 3, 1, 212, 103, 248, 3, 1, 212, 94, 248, 3, 1, 170, 248, 3, 1, + 165, 248, 3, 1, 173, 248, 3, 1, 195, 188, 248, 3, 1, 188, 248, 3, 1, 65, + 248, 3, 1, 140, 248, 3, 18, 3, 68, 248, 3, 18, 3, 66, 248, 3, 18, 3, 71, + 248, 3, 18, 3, 74, 248, 3, 18, 3, 252, 27, 248, 3, 210, 186, 248, 3, 234, + 97, 79, 205, 54, 54, 128, 1, 137, 155, 54, 128, 1, 137, 221, 217, 54, + 128, 1, 137, 220, 167, 54, 128, 1, 130, 155, 54, 128, 1, 130, 220, 167, + 54, 128, 1, 130, 221, 217, 54, 128, 1, 214, 70, 54, 128, 1, 137, 247, + 162, 54, 128, 1, 137, 247, 3, 54, 128, 1, 130, 247, 162, 54, 128, 1, 130, + 188, 54, 128, 1, 130, 247, 3, 54, 128, 1, 212, 103, 54, 128, 1, 207, 131, + 54, 128, 1, 137, 207, 129, 54, 128, 1, 238, 34, 54, 128, 1, 130, 207, + 129, 54, 128, 1, 207, 140, 54, 128, 1, 137, 190, 190, 54, 128, 1, 137, 199, 49, 54, 128, 1, 130, 190, 190, 54, 128, 1, 130, 199, 49, 54, 128, 1, - 180, 54, 128, 1, 249, 153, 54, 128, 1, 137, 168, 54, 128, 1, 137, 209, - 228, 54, 128, 1, 137, 233, 109, 54, 128, 1, 130, 168, 54, 128, 1, 130, - 233, 109, 54, 128, 1, 130, 209, 228, 54, 128, 1, 174, 54, 128, 1, 130, - 170, 54, 128, 1, 137, 170, 54, 128, 1, 165, 54, 128, 1, 206, 57, 54, 128, - 1, 173, 54, 128, 1, 218, 218, 54, 128, 1, 193, 190, 54, 128, 1, 137, 203, - 165, 54, 128, 1, 137, 201, 175, 54, 128, 1, 137, 188, 54, 128, 1, 137, - 140, 54, 128, 1, 219, 73, 54, 128, 1, 65, 54, 128, 1, 130, 140, 54, 128, - 1, 68, 54, 128, 1, 223, 199, 54, 128, 1, 66, 54, 128, 1, 196, 30, 54, - 128, 1, 234, 188, 54, 128, 1, 211, 87, 54, 128, 1, 220, 107, 54, 128, 1, - 230, 206, 188, 54, 128, 120, 3, 216, 217, 165, 54, 128, 120, 3, 216, 217, - 173, 54, 128, 120, 3, 220, 126, 199, 190, 220, 96, 54, 128, 3, 217, 113, - 222, 84, 220, 96, 54, 128, 120, 3, 53, 214, 68, 54, 128, 120, 3, 130, - 168, 54, 128, 120, 3, 137, 207, 128, 211, 57, 130, 168, 54, 128, 120, 3, - 174, 54, 128, 120, 3, 249, 153, 54, 128, 120, 3, 188, 54, 128, 3, 205, - 172, 54, 128, 18, 3, 65, 54, 128, 18, 3, 217, 113, 205, 122, 54, 128, 18, - 3, 252, 206, 54, 128, 18, 3, 199, 200, 252, 206, 54, 128, 18, 3, 68, 54, - 128, 18, 3, 223, 199, 54, 128, 18, 3, 196, 152, 54, 128, 18, 3, 196, 29, + 181, 54, 128, 1, 249, 155, 54, 128, 1, 137, 168, 54, 128, 1, 137, 209, + 230, 54, 128, 1, 137, 233, 111, 54, 128, 1, 130, 168, 54, 128, 1, 130, + 233, 111, 54, 128, 1, 130, 209, 230, 54, 128, 1, 174, 54, 128, 1, 130, + 170, 54, 128, 1, 137, 170, 54, 128, 1, 165, 54, 128, 1, 206, 58, 54, 128, + 1, 173, 54, 128, 1, 218, 220, 54, 128, 1, 193, 190, 54, 128, 1, 137, 203, + 166, 54, 128, 1, 137, 201, 176, 54, 128, 1, 137, 188, 54, 128, 1, 137, + 140, 54, 128, 1, 219, 75, 54, 128, 1, 65, 54, 128, 1, 130, 140, 54, 128, + 1, 68, 54, 128, 1, 223, 201, 54, 128, 1, 66, 54, 128, 1, 196, 30, 54, + 128, 1, 234, 190, 54, 128, 1, 211, 89, 54, 128, 1, 220, 109, 54, 128, 1, + 230, 208, 188, 54, 128, 120, 3, 216, 219, 165, 54, 128, 120, 3, 216, 219, + 173, 54, 128, 120, 3, 220, 128, 199, 190, 220, 98, 54, 128, 3, 217, 115, + 222, 86, 220, 98, 54, 128, 120, 3, 53, 214, 70, 54, 128, 120, 3, 130, + 168, 54, 128, 120, 3, 137, 207, 130, 211, 59, 130, 168, 54, 128, 120, 3, + 174, 54, 128, 120, 3, 249, 155, 54, 128, 120, 3, 188, 54, 128, 3, 205, + 173, 54, 128, 18, 3, 65, 54, 128, 18, 3, 217, 115, 205, 123, 54, 128, 18, + 3, 252, 208, 54, 128, 18, 3, 199, 200, 252, 208, 54, 128, 18, 3, 68, 54, + 128, 18, 3, 223, 201, 54, 128, 18, 3, 196, 152, 54, 128, 18, 3, 196, 29, 54, 128, 18, 3, 66, 54, 128, 18, 3, 196, 30, 54, 128, 18, 3, 74, 54, 128, - 18, 3, 211, 183, 60, 54, 128, 18, 3, 210, 242, 54, 128, 18, 3, 71, 54, - 128, 18, 3, 252, 25, 54, 128, 18, 3, 211, 87, 54, 128, 18, 3, 251, 236, - 54, 128, 18, 3, 128, 251, 236, 54, 128, 18, 3, 211, 183, 58, 54, 128, 3, - 217, 113, 222, 83, 54, 128, 3, 198, 78, 54, 128, 3, 198, 77, 54, 128, 3, - 221, 171, 198, 76, 54, 128, 3, 221, 171, 198, 75, 54, 128, 3, 221, 171, - 198, 74, 54, 128, 3, 207, 186, 230, 90, 54, 128, 3, 217, 113, 205, 152, - 54, 128, 3, 221, 170, 222, 64, 54, 128, 33, 238, 198, 236, 140, 54, 128, - 228, 243, 17, 191, 77, 54, 128, 228, 243, 17, 107, 54, 128, 228, 243, 17, - 109, 54, 128, 228, 243, 17, 138, 54, 128, 228, 243, 17, 134, 54, 128, - 228, 243, 17, 149, 54, 128, 228, 243, 17, 169, 54, 128, 228, 243, 17, - 175, 54, 128, 228, 243, 17, 171, 54, 128, 228, 243, 17, 178, 54, 128, + 18, 3, 211, 185, 60, 54, 128, 18, 3, 210, 244, 54, 128, 18, 3, 71, 54, + 128, 18, 3, 252, 27, 54, 128, 18, 3, 211, 89, 54, 128, 18, 3, 251, 238, + 54, 128, 18, 3, 128, 251, 238, 54, 128, 18, 3, 211, 185, 58, 54, 128, 3, + 217, 115, 222, 85, 54, 128, 3, 198, 78, 54, 128, 3, 198, 77, 54, 128, 3, + 221, 173, 198, 76, 54, 128, 3, 221, 173, 198, 75, 54, 128, 3, 221, 173, + 198, 74, 54, 128, 3, 207, 188, 230, 92, 54, 128, 3, 217, 115, 205, 153, + 54, 128, 3, 221, 172, 222, 66, 54, 128, 33, 238, 200, 236, 142, 54, 128, + 228, 245, 17, 191, 77, 54, 128, 228, 245, 17, 107, 54, 128, 228, 245, 17, + 109, 54, 128, 228, 245, 17, 138, 54, 128, 228, 245, 17, 134, 54, 128, + 228, 245, 17, 150, 54, 128, 228, 245, 17, 169, 54, 128, 228, 245, 17, + 175, 54, 128, 228, 245, 17, 171, 54, 128, 228, 245, 17, 178, 54, 128, 128, 17, 191, 77, 54, 128, 128, 17, 107, 54, 128, 128, 17, 109, 54, 128, - 128, 17, 138, 54, 128, 128, 17, 134, 54, 128, 128, 17, 149, 54, 128, 128, + 128, 17, 138, 54, 128, 128, 17, 134, 54, 128, 128, 17, 150, 54, 128, 128, 17, 169, 54, 128, 128, 17, 175, 54, 128, 128, 17, 171, 54, 128, 128, 17, - 178, 54, 128, 3, 193, 80, 54, 128, 3, 193, 79, 54, 128, 3, 205, 107, 54, - 128, 3, 221, 246, 54, 128, 3, 228, 170, 54, 128, 3, 236, 157, 54, 128, 3, - 207, 18, 206, 122, 207, 138, 54, 128, 3, 217, 113, 192, 109, 54, 128, 3, - 222, 120, 54, 128, 3, 222, 119, 54, 128, 3, 205, 117, 54, 128, 3, 205, - 116, 54, 128, 3, 230, 26, 54, 128, 3, 247, 157, 33, 235, 128, 243, 2, - 252, 60, 33, 237, 41, 33, 223, 139, 33, 235, 119, 57, 33, 197, 225, 236, - 140, 33, 192, 233, 60, 33, 193, 72, 219, 113, 60, 33, 211, 77, 87, 60, - 33, 55, 211, 77, 87, 60, 33, 156, 247, 23, 201, 28, 60, 33, 201, 14, 247, - 23, 201, 28, 60, 33, 210, 115, 58, 33, 55, 210, 115, 58, 33, 210, 115, - 60, 33, 210, 115, 210, 255, 33, 8, 2, 1, 193, 225, 60, 33, 8, 2, 1, 153, - 193, 225, 60, 33, 45, 210, 114, 93, 219, 224, 33, 50, 210, 114, 93, 183, - 33, 45, 210, 114, 248, 233, 219, 224, 33, 50, 210, 114, 248, 233, 183, - 33, 51, 248, 51, 58, 33, 31, 3, 58, 33, 223, 93, 55, 251, 15, 58, 33, + 178, 54, 128, 3, 193, 80, 54, 128, 3, 193, 79, 54, 128, 3, 205, 108, 54, + 128, 3, 221, 248, 54, 128, 3, 228, 172, 54, 128, 3, 236, 159, 54, 128, 3, + 207, 19, 206, 123, 207, 140, 54, 128, 3, 217, 115, 192, 109, 54, 128, 3, + 222, 122, 54, 128, 3, 222, 121, 54, 128, 3, 205, 118, 54, 128, 3, 205, + 117, 54, 128, 3, 230, 28, 54, 128, 3, 247, 159, 33, 235, 130, 243, 4, + 252, 62, 33, 237, 43, 33, 223, 141, 33, 235, 121, 57, 33, 197, 225, 236, + 142, 33, 192, 233, 60, 33, 193, 72, 219, 115, 60, 33, 211, 79, 87, 60, + 33, 55, 211, 79, 87, 60, 33, 156, 247, 25, 201, 29, 60, 33, 201, 15, 247, + 25, 201, 29, 60, 33, 210, 117, 58, 33, 55, 210, 117, 58, 33, 210, 117, + 60, 33, 210, 117, 211, 1, 33, 8, 2, 1, 193, 225, 60, 33, 8, 2, 1, 154, + 193, 225, 60, 33, 45, 210, 116, 93, 219, 226, 33, 50, 210, 116, 93, 179, + 33, 45, 210, 116, 248, 235, 219, 226, 33, 50, 210, 116, 248, 235, 179, + 33, 51, 248, 53, 58, 33, 31, 3, 58, 33, 223, 95, 55, 251, 17, 58, 33, 108, 3, 58, 33, 55, 108, 3, 58, 33, 55, 108, 3, 60, 33, 197, 225, 252, - 47, 252, 60, 33, 8, 2, 1, 223, 115, 232, 51, 33, 8, 2, 1, 223, 115, 146, - 33, 8, 2, 1, 223, 115, 200, 43, 148, 3, 196, 123, 206, 244, 148, 3, 196, - 123, 247, 121, 148, 3, 247, 38, 148, 3, 200, 173, 148, 3, 248, 155, 148, - 1, 251, 214, 148, 1, 251, 215, 199, 123, 148, 1, 223, 194, 148, 1, 223, - 195, 199, 123, 148, 1, 196, 126, 148, 1, 196, 127, 199, 123, 148, 1, 207, - 186, 207, 51, 148, 1, 207, 186, 207, 52, 199, 123, 148, 1, 220, 126, 219, - 199, 148, 1, 220, 126, 219, 200, 199, 123, 148, 1, 234, 145, 148, 1, 251, - 233, 148, 1, 211, 123, 148, 1, 211, 124, 199, 123, 148, 1, 155, 148, 1, - 222, 142, 217, 116, 148, 1, 231, 240, 148, 1, 231, 241, 230, 241, 148, 1, - 214, 68, 148, 1, 247, 160, 148, 1, 247, 161, 220, 112, 148, 1, 223, 32, - 148, 1, 223, 33, 223, 0, 148, 1, 212, 101, 148, 1, 199, 252, 220, 2, 148, - 1, 199, 252, 215, 108, 217, 116, 148, 1, 238, 33, 215, 108, 251, 162, - 148, 1, 238, 33, 215, 108, 217, 116, 148, 1, 215, 7, 207, 141, 148, 1, - 190, 190, 148, 1, 199, 252, 199, 158, 148, 1, 238, 32, 148, 1, 238, 33, - 217, 138, 148, 1, 180, 148, 1, 168, 148, 1, 210, 221, 222, 76, 148, 1, - 249, 153, 148, 1, 249, 154, 222, 2, 148, 1, 174, 148, 1, 170, 148, 1, - 165, 148, 1, 173, 148, 1, 193, 190, 148, 1, 205, 207, 205, 184, 148, 1, - 205, 207, 205, 129, 148, 1, 188, 148, 1, 140, 148, 3, 207, 41, 148, 18, - 3, 199, 123, 148, 18, 3, 196, 122, 148, 18, 3, 196, 123, 205, 125, 148, - 18, 3, 200, 208, 148, 18, 3, 200, 209, 223, 185, 148, 18, 3, 207, 186, - 207, 51, 148, 18, 3, 207, 186, 207, 52, 199, 123, 148, 18, 3, 220, 126, - 219, 199, 148, 18, 3, 220, 126, 219, 200, 199, 123, 148, 18, 3, 199, 201, - 148, 18, 3, 199, 202, 207, 51, 148, 18, 3, 199, 202, 199, 123, 148, 18, - 3, 199, 202, 207, 52, 199, 123, 148, 18, 3, 210, 16, 148, 18, 3, 210, 17, - 199, 123, 148, 252, 37, 252, 36, 148, 1, 222, 107, 205, 124, 148, 1, 221, - 177, 205, 124, 148, 1, 196, 235, 205, 124, 148, 1, 234, 182, 205, 124, - 148, 1, 195, 154, 205, 124, 148, 1, 191, 109, 205, 124, 148, 1, 250, 185, - 205, 124, 148, 1, 251, 14, 222, 202, 148, 17, 191, 77, 148, 17, 107, 148, - 17, 109, 148, 17, 138, 148, 17, 134, 148, 17, 149, 148, 17, 169, 148, 17, - 175, 148, 17, 171, 148, 17, 178, 148, 210, 145, 148, 210, 175, 148, 193, - 64, 148, 247, 94, 210, 168, 148, 247, 94, 202, 190, 148, 247, 94, 210, - 112, 148, 210, 174, 148, 37, 16, 236, 148, 148, 37, 16, 237, 102, 148, - 37, 16, 235, 71, 148, 37, 16, 237, 236, 148, 37, 16, 237, 237, 200, 173, - 148, 37, 16, 236, 242, 148, 37, 16, 238, 24, 148, 37, 16, 237, 77, 148, - 37, 16, 238, 6, 148, 37, 16, 237, 237, 231, 159, 148, 37, 16, 33, 199, - 116, 148, 37, 16, 33, 234, 92, 148, 37, 16, 33, 221, 253, 148, 37, 16, - 33, 221, 255, 148, 37, 16, 33, 223, 5, 148, 37, 16, 33, 221, 254, 4, 223, - 5, 148, 37, 16, 33, 222, 0, 4, 223, 5, 148, 37, 16, 33, 248, 226, 148, - 37, 16, 33, 230, 247, 148, 37, 16, 206, 206, 211, 77, 235, 82, 148, 37, - 16, 206, 206, 211, 77, 238, 22, 148, 37, 16, 206, 206, 242, 219, 197, 80, - 148, 37, 16, 206, 206, 242, 219, 199, 211, 148, 37, 16, 219, 222, 211, - 77, 210, 160, 148, 37, 16, 219, 222, 211, 77, 208, 149, 148, 37, 16, 219, - 222, 242, 219, 209, 104, 148, 37, 16, 219, 222, 242, 219, 209, 86, 148, - 37, 16, 219, 222, 211, 77, 209, 132, 148, 210, 146, 220, 19, 148, 210, - 176, 220, 19, 200, 197, 3, 210, 142, 200, 197, 3, 210, 156, 200, 197, 3, - 210, 152, 200, 197, 1, 65, 200, 197, 1, 68, 200, 197, 1, 66, 200, 197, 1, - 252, 25, 200, 197, 1, 74, 200, 197, 1, 71, 200, 197, 1, 233, 242, 200, - 197, 1, 155, 200, 197, 1, 208, 96, 200, 197, 1, 231, 240, 200, 197, 1, - 214, 68, 200, 197, 1, 247, 160, 200, 197, 1, 223, 32, 200, 197, 1, 191, - 123, 200, 197, 1, 212, 101, 200, 197, 1, 190, 190, 200, 197, 1, 238, 32, - 200, 197, 1, 180, 200, 197, 1, 168, 200, 197, 1, 233, 109, 200, 197, 1, - 195, 188, 200, 197, 1, 249, 153, 200, 197, 1, 174, 200, 197, 1, 170, 200, + 49, 252, 62, 33, 8, 2, 1, 223, 117, 232, 53, 33, 8, 2, 1, 223, 117, 146, + 33, 8, 2, 1, 223, 117, 200, 43, 149, 3, 196, 123, 206, 245, 149, 3, 196, + 123, 247, 123, 149, 3, 247, 40, 149, 3, 200, 173, 149, 3, 248, 157, 149, + 1, 251, 216, 149, 1, 251, 217, 199, 123, 149, 1, 223, 196, 149, 1, 223, + 197, 199, 123, 149, 1, 196, 126, 149, 1, 196, 127, 199, 123, 149, 1, 207, + 188, 207, 52, 149, 1, 207, 188, 207, 53, 199, 123, 149, 1, 220, 128, 219, + 201, 149, 1, 220, 128, 219, 202, 199, 123, 149, 1, 234, 147, 149, 1, 251, + 235, 149, 1, 211, 125, 149, 1, 211, 126, 199, 123, 149, 1, 155, 149, 1, + 222, 144, 217, 118, 149, 1, 231, 242, 149, 1, 231, 243, 230, 243, 149, 1, + 214, 70, 149, 1, 247, 162, 149, 1, 247, 163, 220, 114, 149, 1, 223, 34, + 149, 1, 223, 35, 223, 2, 149, 1, 212, 103, 149, 1, 199, 252, 220, 4, 149, + 1, 199, 252, 215, 110, 217, 118, 149, 1, 238, 35, 215, 110, 251, 164, + 149, 1, 238, 35, 215, 110, 217, 118, 149, 1, 215, 9, 207, 143, 149, 1, + 190, 190, 149, 1, 199, 252, 199, 158, 149, 1, 238, 34, 149, 1, 238, 35, + 217, 140, 149, 1, 181, 149, 1, 168, 149, 1, 210, 223, 222, 78, 149, 1, + 249, 155, 149, 1, 249, 156, 222, 4, 149, 1, 174, 149, 1, 170, 149, 1, + 165, 149, 1, 173, 149, 1, 193, 190, 149, 1, 205, 208, 205, 185, 149, 1, + 205, 208, 205, 130, 149, 1, 188, 149, 1, 140, 149, 3, 207, 42, 149, 18, + 3, 199, 123, 149, 18, 3, 196, 122, 149, 18, 3, 196, 123, 205, 126, 149, + 18, 3, 200, 208, 149, 18, 3, 200, 209, 223, 187, 149, 18, 3, 207, 188, + 207, 52, 149, 18, 3, 207, 188, 207, 53, 199, 123, 149, 18, 3, 220, 128, + 219, 201, 149, 18, 3, 220, 128, 219, 202, 199, 123, 149, 18, 3, 199, 201, + 149, 18, 3, 199, 202, 207, 52, 149, 18, 3, 199, 202, 199, 123, 149, 18, + 3, 199, 202, 207, 53, 199, 123, 149, 18, 3, 210, 18, 149, 18, 3, 210, 19, + 199, 123, 149, 252, 39, 252, 38, 149, 1, 222, 109, 205, 125, 149, 1, 221, + 179, 205, 125, 149, 1, 196, 235, 205, 125, 149, 1, 234, 184, 205, 125, + 149, 1, 195, 154, 205, 125, 149, 1, 191, 109, 205, 125, 149, 1, 250, 187, + 205, 125, 149, 1, 251, 16, 222, 204, 149, 17, 191, 77, 149, 17, 107, 149, + 17, 109, 149, 17, 138, 149, 17, 134, 149, 17, 150, 149, 17, 169, 149, 17, + 175, 149, 17, 171, 149, 17, 178, 149, 210, 147, 149, 210, 177, 149, 193, + 64, 149, 247, 96, 210, 170, 149, 247, 96, 202, 191, 149, 247, 96, 210, + 114, 149, 210, 176, 149, 37, 16, 236, 150, 149, 37, 16, 237, 104, 149, + 37, 16, 235, 73, 149, 37, 16, 237, 238, 149, 37, 16, 237, 239, 200, 173, + 149, 37, 16, 236, 244, 149, 37, 16, 238, 26, 149, 37, 16, 237, 79, 149, + 37, 16, 238, 8, 149, 37, 16, 237, 239, 231, 161, 149, 37, 16, 33, 199, + 116, 149, 37, 16, 33, 234, 94, 149, 37, 16, 33, 221, 255, 149, 37, 16, + 33, 222, 1, 149, 37, 16, 33, 223, 7, 149, 37, 16, 33, 222, 0, 4, 223, 7, + 149, 37, 16, 33, 222, 2, 4, 223, 7, 149, 37, 16, 33, 248, 228, 149, 37, + 16, 33, 230, 249, 149, 37, 16, 206, 207, 211, 79, 235, 84, 149, 37, 16, + 206, 207, 211, 79, 238, 24, 149, 37, 16, 206, 207, 242, 221, 197, 80, + 149, 37, 16, 206, 207, 242, 221, 199, 211, 149, 37, 16, 219, 224, 211, + 79, 210, 162, 149, 37, 16, 219, 224, 211, 79, 208, 151, 149, 37, 16, 219, + 224, 242, 221, 209, 106, 149, 37, 16, 219, 224, 242, 221, 209, 88, 149, + 37, 16, 219, 224, 211, 79, 209, 134, 149, 210, 148, 220, 21, 149, 210, + 178, 220, 21, 200, 197, 3, 210, 144, 200, 197, 3, 210, 158, 200, 197, 3, + 210, 154, 200, 197, 1, 65, 200, 197, 1, 68, 200, 197, 1, 66, 200, 197, 1, + 252, 27, 200, 197, 1, 74, 200, 197, 1, 71, 200, 197, 1, 233, 244, 200, + 197, 1, 155, 200, 197, 1, 208, 98, 200, 197, 1, 231, 242, 200, 197, 1, + 214, 70, 200, 197, 1, 247, 162, 200, 197, 1, 223, 34, 200, 197, 1, 191, + 123, 200, 197, 1, 212, 103, 200, 197, 1, 190, 190, 200, 197, 1, 238, 34, + 200, 197, 1, 181, 200, 197, 1, 168, 200, 197, 1, 233, 111, 200, 197, 1, + 195, 188, 200, 197, 1, 249, 155, 200, 197, 1, 174, 200, 197, 1, 170, 200, 197, 1, 165, 200, 197, 1, 173, 200, 197, 1, 193, 190, 200, 197, 1, 188, - 200, 197, 1, 192, 220, 200, 197, 1, 140, 200, 197, 120, 3, 210, 172, 200, - 197, 120, 3, 210, 144, 200, 197, 120, 3, 210, 141, 200, 197, 18, 3, 210, - 159, 200, 197, 18, 3, 210, 140, 200, 197, 18, 3, 210, 165, 200, 197, 18, - 3, 210, 151, 200, 197, 18, 3, 210, 173, 200, 197, 18, 3, 210, 161, 200, - 197, 3, 210, 177, 200, 197, 3, 195, 40, 200, 197, 120, 3, 210, 100, 174, - 200, 197, 120, 3, 210, 100, 193, 190, 200, 197, 1, 221, 215, 200, 197, 1, + 200, 197, 1, 192, 220, 200, 197, 1, 140, 200, 197, 120, 3, 210, 174, 200, + 197, 120, 3, 210, 146, 200, 197, 120, 3, 210, 143, 200, 197, 18, 3, 210, + 161, 200, 197, 18, 3, 210, 142, 200, 197, 18, 3, 210, 167, 200, 197, 18, + 3, 210, 153, 200, 197, 18, 3, 210, 175, 200, 197, 18, 3, 210, 163, 200, + 197, 3, 210, 179, 200, 197, 3, 195, 40, 200, 197, 120, 3, 210, 102, 174, + 200, 197, 120, 3, 210, 102, 193, 190, 200, 197, 1, 221, 217, 200, 197, 1, 200, 126, 200, 197, 17, 191, 77, 200, 197, 17, 107, 200, 197, 17, 109, - 200, 197, 17, 138, 200, 197, 17, 134, 200, 197, 17, 149, 200, 197, 17, + 200, 197, 17, 138, 200, 197, 17, 134, 200, 197, 17, 150, 200, 197, 17, 169, 200, 197, 17, 175, 200, 197, 17, 171, 200, 197, 17, 178, 200, 197, - 250, 145, 200, 197, 1, 207, 21, 200, 197, 1, 219, 172, 200, 197, 1, 248, - 203, 200, 197, 1, 53, 222, 152, 200, 197, 1, 53, 218, 168, 249, 63, 1, - 65, 249, 63, 1, 202, 182, 65, 249, 63, 1, 140, 249, 63, 1, 202, 182, 140, - 249, 63, 1, 217, 85, 140, 249, 63, 1, 249, 153, 249, 63, 1, 222, 61, 249, - 153, 249, 63, 1, 168, 249, 63, 1, 202, 182, 168, 249, 63, 1, 180, 249, - 63, 1, 217, 85, 180, 249, 63, 1, 193, 190, 249, 63, 1, 202, 182, 193, - 190, 249, 63, 1, 210, 193, 193, 190, 249, 63, 1, 231, 240, 249, 63, 1, - 202, 182, 231, 240, 249, 63, 1, 223, 32, 249, 63, 1, 238, 32, 249, 63, 1, - 165, 249, 63, 1, 202, 182, 165, 249, 63, 1, 174, 249, 63, 1, 202, 182, - 174, 249, 63, 1, 202, 0, 190, 190, 249, 63, 1, 213, 16, 190, 190, 249, - 63, 1, 188, 249, 63, 1, 202, 182, 188, 249, 63, 1, 217, 85, 188, 249, 63, - 1, 170, 249, 63, 1, 202, 182, 170, 249, 63, 1, 214, 68, 249, 63, 1, 173, - 249, 63, 1, 202, 182, 173, 249, 63, 1, 212, 101, 249, 63, 1, 247, 160, - 249, 63, 1, 214, 162, 249, 63, 1, 217, 11, 249, 63, 1, 68, 249, 63, 1, - 66, 249, 63, 3, 198, 82, 249, 63, 18, 3, 71, 249, 63, 18, 3, 210, 193, - 71, 249, 63, 18, 3, 234, 188, 249, 63, 18, 3, 68, 249, 63, 18, 3, 222, - 61, 68, 249, 63, 18, 3, 74, 249, 63, 18, 3, 222, 61, 74, 249, 63, 18, 3, - 66, 249, 63, 18, 3, 126, 40, 202, 182, 188, 249, 63, 120, 3, 214, 70, - 249, 63, 120, 3, 230, 116, 249, 63, 210, 154, 249, 63, 210, 150, 249, 63, - 16, 248, 165, 215, 7, 216, 163, 249, 63, 16, 248, 165, 209, 138, 249, 63, - 16, 248, 165, 222, 179, 249, 63, 16, 248, 165, 210, 154, 219, 183, 1, - 155, 219, 183, 1, 221, 94, 219, 183, 1, 221, 215, 219, 183, 1, 231, 240, - 219, 183, 1, 231, 19, 219, 183, 1, 214, 68, 219, 183, 1, 247, 160, 219, - 183, 1, 247, 1, 219, 183, 1, 223, 32, 219, 183, 1, 212, 101, 219, 183, 1, - 190, 190, 219, 183, 1, 199, 49, 219, 183, 1, 238, 32, 219, 183, 1, 180, - 219, 183, 1, 168, 219, 183, 1, 209, 110, 219, 183, 1, 209, 228, 219, 183, - 1, 233, 109, 219, 183, 1, 232, 219, 219, 183, 1, 249, 153, 219, 183, 1, - 248, 140, 219, 183, 1, 174, 219, 183, 1, 216, 19, 219, 183, 1, 197, 168, - 219, 183, 1, 197, 157, 219, 183, 1, 235, 35, 219, 183, 1, 170, 219, 183, - 1, 165, 219, 183, 1, 173, 219, 183, 1, 140, 219, 183, 1, 229, 111, 219, - 183, 1, 195, 188, 219, 183, 1, 188, 219, 183, 1, 203, 165, 219, 183, 1, - 193, 190, 219, 183, 1, 65, 219, 183, 200, 239, 1, 170, 219, 183, 200, - 239, 1, 165, 219, 183, 18, 3, 252, 206, 219, 183, 18, 3, 68, 219, 183, - 18, 3, 74, 219, 183, 18, 3, 211, 87, 219, 183, 18, 3, 66, 219, 183, 18, - 3, 196, 30, 219, 183, 18, 3, 71, 219, 183, 120, 3, 222, 152, 219, 183, - 120, 3, 218, 168, 219, 183, 120, 3, 172, 219, 183, 120, 3, 215, 61, 219, - 183, 120, 3, 210, 236, 219, 183, 120, 3, 146, 219, 183, 120, 3, 200, 43, - 219, 183, 120, 3, 212, 73, 219, 183, 120, 3, 222, 83, 219, 183, 3, 207, - 139, 219, 183, 3, 212, 141, 219, 183, 208, 152, 199, 247, 219, 183, 208, - 152, 212, 85, 198, 196, 199, 247, 219, 183, 208, 152, 247, 10, 219, 183, - 208, 152, 197, 149, 247, 10, 219, 183, 208, 152, 197, 148, 219, 183, 17, - 191, 77, 219, 183, 17, 107, 219, 183, 17, 109, 219, 183, 17, 138, 219, - 183, 17, 134, 219, 183, 17, 149, 219, 183, 17, 169, 219, 183, 17, 175, - 219, 183, 17, 171, 219, 183, 17, 178, 219, 183, 1, 197, 132, 219, 183, 1, - 197, 120, 219, 183, 1, 237, 191, 211, 121, 243, 88, 17, 191, 77, 211, - 121, 243, 88, 17, 107, 211, 121, 243, 88, 17, 109, 211, 121, 243, 88, 17, - 138, 211, 121, 243, 88, 17, 134, 211, 121, 243, 88, 17, 149, 211, 121, - 243, 88, 17, 169, 211, 121, 243, 88, 17, 175, 211, 121, 243, 88, 17, 171, - 211, 121, 243, 88, 17, 178, 211, 121, 243, 88, 1, 173, 211, 121, 243, 88, - 1, 250, 182, 211, 121, 243, 88, 1, 251, 253, 211, 121, 243, 88, 1, 251, - 122, 211, 121, 243, 88, 1, 251, 207, 211, 121, 243, 88, 1, 220, 125, 211, - 121, 243, 88, 1, 252, 168, 211, 121, 243, 88, 1, 252, 169, 211, 121, 243, - 88, 1, 252, 167, 211, 121, 243, 88, 1, 252, 161, 211, 121, 243, 88, 1, - 219, 146, 211, 121, 243, 88, 1, 223, 68, 211, 121, 243, 88, 1, 223, 200, - 211, 121, 243, 88, 1, 223, 90, 211, 121, 243, 88, 1, 223, 77, 211, 121, - 243, 88, 1, 218, 225, 211, 121, 243, 88, 1, 196, 160, 211, 121, 243, 88, - 1, 196, 158, 211, 121, 243, 88, 1, 196, 83, 211, 121, 243, 88, 1, 196, - 21, 211, 121, 243, 88, 1, 219, 238, 211, 121, 243, 88, 1, 234, 56, 211, - 121, 243, 88, 1, 234, 191, 211, 121, 243, 88, 1, 234, 103, 211, 121, 243, - 88, 1, 234, 26, 211, 121, 243, 88, 1, 219, 43, 211, 121, 243, 88, 1, 211, - 24, 211, 121, 243, 88, 1, 211, 178, 211, 121, 243, 88, 1, 211, 9, 211, - 121, 243, 88, 1, 211, 136, 211, 121, 243, 88, 215, 156, 197, 97, 211, - 121, 243, 88, 231, 235, 197, 98, 211, 121, 243, 88, 215, 150, 197, 98, - 211, 121, 243, 88, 207, 66, 211, 121, 243, 88, 209, 226, 211, 121, 243, - 88, 251, 244, 211, 121, 243, 88, 208, 152, 215, 146, 211, 121, 243, 88, - 208, 152, 55, 215, 146, 38, 2, 1, 206, 113, 195, 153, 38, 2, 1, 219, 12, - 237, 146, 38, 2, 1, 214, 215, 74, 38, 2, 1, 193, 78, 234, 22, 38, 2, 1, + 250, 147, 200, 197, 1, 207, 22, 200, 197, 1, 219, 174, 200, 197, 1, 248, + 205, 200, 197, 1, 53, 222, 154, 200, 197, 1, 53, 218, 170, 249, 65, 1, + 65, 249, 65, 1, 202, 183, 65, 249, 65, 1, 140, 249, 65, 1, 202, 183, 140, + 249, 65, 1, 217, 87, 140, 249, 65, 1, 249, 155, 249, 65, 1, 222, 63, 249, + 155, 249, 65, 1, 168, 249, 65, 1, 202, 183, 168, 249, 65, 1, 181, 249, + 65, 1, 217, 87, 181, 249, 65, 1, 193, 190, 249, 65, 1, 202, 183, 193, + 190, 249, 65, 1, 210, 195, 193, 190, 249, 65, 1, 231, 242, 249, 65, 1, + 202, 183, 231, 242, 249, 65, 1, 223, 34, 249, 65, 1, 238, 34, 249, 65, 1, + 165, 249, 65, 1, 202, 183, 165, 249, 65, 1, 174, 249, 65, 1, 202, 183, + 174, 249, 65, 1, 202, 1, 190, 190, 249, 65, 1, 213, 18, 190, 190, 249, + 65, 1, 188, 249, 65, 1, 202, 183, 188, 249, 65, 1, 217, 87, 188, 249, 65, + 1, 170, 249, 65, 1, 202, 183, 170, 249, 65, 1, 214, 70, 249, 65, 1, 173, + 249, 65, 1, 202, 183, 173, 249, 65, 1, 212, 103, 249, 65, 1, 247, 162, + 249, 65, 1, 214, 164, 249, 65, 1, 217, 13, 249, 65, 1, 68, 249, 65, 1, + 66, 249, 65, 3, 198, 82, 249, 65, 18, 3, 71, 249, 65, 18, 3, 210, 195, + 71, 249, 65, 18, 3, 234, 190, 249, 65, 18, 3, 68, 249, 65, 18, 3, 222, + 63, 68, 249, 65, 18, 3, 74, 249, 65, 18, 3, 222, 63, 74, 249, 65, 18, 3, + 66, 249, 65, 18, 3, 126, 40, 202, 183, 188, 249, 65, 120, 3, 214, 72, + 249, 65, 120, 3, 230, 118, 249, 65, 210, 156, 249, 65, 210, 152, 249, 65, + 16, 248, 167, 215, 9, 216, 165, 249, 65, 16, 248, 167, 209, 140, 249, 65, + 16, 248, 167, 222, 181, 249, 65, 16, 248, 167, 210, 156, 219, 185, 1, + 155, 219, 185, 1, 221, 96, 219, 185, 1, 221, 217, 219, 185, 1, 231, 242, + 219, 185, 1, 231, 21, 219, 185, 1, 214, 70, 219, 185, 1, 247, 162, 219, + 185, 1, 247, 3, 219, 185, 1, 223, 34, 219, 185, 1, 212, 103, 219, 185, 1, + 190, 190, 219, 185, 1, 199, 49, 219, 185, 1, 238, 34, 219, 185, 1, 181, + 219, 185, 1, 168, 219, 185, 1, 209, 112, 219, 185, 1, 209, 230, 219, 185, + 1, 233, 111, 219, 185, 1, 232, 221, 219, 185, 1, 249, 155, 219, 185, 1, + 248, 142, 219, 185, 1, 174, 219, 185, 1, 216, 21, 219, 185, 1, 197, 168, + 219, 185, 1, 197, 157, 219, 185, 1, 235, 37, 219, 185, 1, 170, 219, 185, + 1, 165, 219, 185, 1, 173, 219, 185, 1, 140, 219, 185, 1, 229, 113, 219, + 185, 1, 195, 188, 219, 185, 1, 188, 219, 185, 1, 203, 166, 219, 185, 1, + 193, 190, 219, 185, 1, 65, 219, 185, 200, 240, 1, 170, 219, 185, 200, + 240, 1, 165, 219, 185, 18, 3, 252, 208, 219, 185, 18, 3, 68, 219, 185, + 18, 3, 74, 219, 185, 18, 3, 211, 89, 219, 185, 18, 3, 66, 219, 185, 18, + 3, 196, 30, 219, 185, 18, 3, 71, 219, 185, 120, 3, 222, 154, 219, 185, + 120, 3, 218, 170, 219, 185, 120, 3, 172, 219, 185, 120, 3, 215, 63, 219, + 185, 120, 3, 210, 238, 219, 185, 120, 3, 146, 219, 185, 120, 3, 200, 43, + 219, 185, 120, 3, 212, 75, 219, 185, 120, 3, 222, 85, 219, 185, 3, 207, + 141, 219, 185, 3, 212, 143, 219, 185, 208, 154, 199, 247, 219, 185, 208, + 154, 212, 87, 198, 196, 199, 247, 219, 185, 208, 154, 247, 12, 219, 185, + 208, 154, 197, 149, 247, 12, 219, 185, 208, 154, 197, 148, 219, 185, 17, + 191, 77, 219, 185, 17, 107, 219, 185, 17, 109, 219, 185, 17, 138, 219, + 185, 17, 134, 219, 185, 17, 150, 219, 185, 17, 169, 219, 185, 17, 175, + 219, 185, 17, 171, 219, 185, 17, 178, 219, 185, 1, 197, 132, 219, 185, 1, + 197, 120, 219, 185, 1, 237, 193, 211, 123, 243, 90, 17, 191, 77, 211, + 123, 243, 90, 17, 107, 211, 123, 243, 90, 17, 109, 211, 123, 243, 90, 17, + 138, 211, 123, 243, 90, 17, 134, 211, 123, 243, 90, 17, 150, 211, 123, + 243, 90, 17, 169, 211, 123, 243, 90, 17, 175, 211, 123, 243, 90, 17, 171, + 211, 123, 243, 90, 17, 178, 211, 123, 243, 90, 1, 173, 211, 123, 243, 90, + 1, 250, 184, 211, 123, 243, 90, 1, 251, 255, 211, 123, 243, 90, 1, 251, + 124, 211, 123, 243, 90, 1, 251, 209, 211, 123, 243, 90, 1, 220, 127, 211, + 123, 243, 90, 1, 252, 170, 211, 123, 243, 90, 1, 252, 171, 211, 123, 243, + 90, 1, 252, 169, 211, 123, 243, 90, 1, 252, 163, 211, 123, 243, 90, 1, + 219, 148, 211, 123, 243, 90, 1, 223, 70, 211, 123, 243, 90, 1, 223, 202, + 211, 123, 243, 90, 1, 223, 92, 211, 123, 243, 90, 1, 223, 79, 211, 123, + 243, 90, 1, 218, 227, 211, 123, 243, 90, 1, 196, 160, 211, 123, 243, 90, + 1, 196, 158, 211, 123, 243, 90, 1, 196, 83, 211, 123, 243, 90, 1, 196, + 21, 211, 123, 243, 90, 1, 219, 240, 211, 123, 243, 90, 1, 234, 58, 211, + 123, 243, 90, 1, 234, 193, 211, 123, 243, 90, 1, 234, 105, 211, 123, 243, + 90, 1, 234, 28, 211, 123, 243, 90, 1, 219, 45, 211, 123, 243, 90, 1, 211, + 26, 211, 123, 243, 90, 1, 211, 180, 211, 123, 243, 90, 1, 211, 11, 211, + 123, 243, 90, 1, 211, 138, 211, 123, 243, 90, 215, 158, 197, 97, 211, + 123, 243, 90, 231, 237, 197, 98, 211, 123, 243, 90, 215, 152, 197, 98, + 211, 123, 243, 90, 207, 67, 211, 123, 243, 90, 209, 228, 211, 123, 243, + 90, 251, 246, 211, 123, 243, 90, 208, 154, 215, 148, 211, 123, 243, 90, + 208, 154, 55, 215, 148, 38, 2, 1, 206, 114, 195, 153, 38, 2, 1, 219, 14, + 237, 148, 38, 2, 1, 214, 217, 74, 38, 2, 1, 193, 78, 234, 24, 38, 2, 1, 199, 200, 199, 145, 38, 2, 1, 198, 221, 199, 145, 38, 2, 1, 199, 200, - 230, 17, 56, 38, 2, 1, 199, 200, 192, 95, 38, 2, 1, 196, 108, 196, 128, - 101, 215, 157, 6, 1, 251, 132, 101, 215, 157, 6, 1, 249, 101, 101, 215, - 157, 6, 1, 231, 210, 101, 215, 157, 6, 1, 236, 150, 101, 215, 157, 6, 1, - 234, 103, 101, 215, 157, 6, 1, 195, 49, 101, 215, 157, 6, 1, 191, 80, - 101, 215, 157, 6, 1, 199, 193, 101, 215, 157, 6, 1, 223, 162, 101, 215, - 157, 6, 1, 222, 87, 101, 215, 157, 6, 1, 220, 7, 101, 215, 157, 6, 1, - 217, 90, 101, 215, 157, 6, 1, 214, 216, 101, 215, 157, 6, 1, 211, 104, - 101, 215, 157, 6, 1, 210, 131, 101, 215, 157, 6, 1, 191, 67, 101, 215, - 157, 6, 1, 207, 163, 101, 215, 157, 6, 1, 205, 142, 101, 215, 157, 6, 1, - 199, 179, 101, 215, 157, 6, 1, 196, 113, 101, 215, 157, 6, 1, 209, 220, - 101, 215, 157, 6, 1, 221, 200, 101, 215, 157, 6, 1, 231, 82, 101, 215, - 157, 6, 1, 208, 81, 101, 215, 157, 6, 1, 203, 69, 101, 215, 157, 6, 1, - 243, 81, 101, 215, 157, 6, 1, 247, 128, 101, 215, 157, 6, 1, 222, 234, - 101, 215, 157, 6, 1, 243, 18, 101, 215, 157, 6, 1, 246, 241, 101, 215, - 157, 6, 1, 192, 218, 101, 215, 157, 6, 1, 222, 249, 101, 215, 157, 6, 1, - 230, 87, 101, 215, 157, 6, 1, 229, 245, 101, 215, 157, 6, 1, 229, 145, - 101, 215, 157, 6, 1, 193, 125, 101, 215, 157, 6, 1, 230, 19, 101, 215, - 157, 6, 1, 229, 11, 101, 215, 157, 6, 1, 233, 23, 101, 215, 157, 6, 1, - 192, 14, 101, 215, 157, 6, 1, 234, 123, 101, 215, 157, 6, 1, 153, 231, - 210, 101, 215, 157, 6, 1, 251, 230, 101, 215, 157, 6, 1, 252, 14, 101, - 215, 157, 6, 1, 230, 17, 56, 101, 215, 157, 6, 1, 220, 116, 56, 200, 197, - 208, 152, 248, 165, 200, 166, 200, 197, 208, 152, 248, 165, 210, 155, - 200, 197, 208, 152, 248, 165, 208, 139, 200, 197, 208, 152, 248, 165, - 247, 145, 200, 197, 208, 152, 248, 165, 219, 173, 205, 121, 200, 197, - 208, 152, 248, 165, 222, 142, 205, 121, 200, 197, 208, 152, 248, 165, - 238, 33, 205, 121, 200, 197, 208, 152, 248, 165, 249, 154, 205, 121, 195, - 150, 163, 222, 57, 195, 150, 163, 203, 130, 195, 150, 163, 208, 225, 195, - 150, 3, 213, 187, 195, 150, 3, 192, 117, 216, 82, 200, 156, 195, 150, - 163, 192, 117, 251, 249, 223, 149, 200, 156, 195, 150, 163, 192, 117, - 223, 149, 200, 156, 195, 150, 163, 192, 117, 222, 45, 223, 149, 200, 156, - 195, 150, 163, 247, 122, 60, 195, 150, 163, 192, 117, 222, 45, 223, 149, - 200, 157, 205, 88, 195, 150, 163, 55, 200, 156, 195, 150, 163, 197, 225, - 200, 156, 195, 150, 163, 222, 45, 251, 73, 195, 150, 163, 75, 60, 195, + 230, 19, 56, 38, 2, 1, 199, 200, 192, 95, 38, 2, 1, 196, 108, 196, 128, + 101, 215, 159, 6, 1, 251, 134, 101, 215, 159, 6, 1, 249, 103, 101, 215, + 159, 6, 1, 231, 212, 101, 215, 159, 6, 1, 236, 152, 101, 215, 159, 6, 1, + 234, 105, 101, 215, 159, 6, 1, 195, 49, 101, 215, 159, 6, 1, 191, 80, + 101, 215, 159, 6, 1, 199, 193, 101, 215, 159, 6, 1, 223, 164, 101, 215, + 159, 6, 1, 222, 89, 101, 215, 159, 6, 1, 220, 9, 101, 215, 159, 6, 1, + 217, 92, 101, 215, 159, 6, 1, 214, 218, 101, 215, 159, 6, 1, 211, 106, + 101, 215, 159, 6, 1, 210, 133, 101, 215, 159, 6, 1, 191, 67, 101, 215, + 159, 6, 1, 207, 165, 101, 215, 159, 6, 1, 205, 143, 101, 215, 159, 6, 1, + 199, 179, 101, 215, 159, 6, 1, 196, 113, 101, 215, 159, 6, 1, 209, 222, + 101, 215, 159, 6, 1, 221, 202, 101, 215, 159, 6, 1, 231, 84, 101, 215, + 159, 6, 1, 208, 83, 101, 215, 159, 6, 1, 203, 70, 101, 215, 159, 6, 1, + 243, 83, 101, 215, 159, 6, 1, 247, 130, 101, 215, 159, 6, 1, 222, 236, + 101, 215, 159, 6, 1, 243, 20, 101, 215, 159, 6, 1, 246, 243, 101, 215, + 159, 6, 1, 192, 218, 101, 215, 159, 6, 1, 222, 251, 101, 215, 159, 6, 1, + 230, 89, 101, 215, 159, 6, 1, 229, 247, 101, 215, 159, 6, 1, 229, 147, + 101, 215, 159, 6, 1, 193, 125, 101, 215, 159, 6, 1, 230, 21, 101, 215, + 159, 6, 1, 229, 13, 101, 215, 159, 6, 1, 233, 25, 101, 215, 159, 6, 1, + 192, 14, 101, 215, 159, 6, 1, 234, 125, 101, 215, 159, 6, 1, 154, 231, + 212, 101, 215, 159, 6, 1, 251, 232, 101, 215, 159, 6, 1, 252, 16, 101, + 215, 159, 6, 1, 230, 19, 56, 101, 215, 159, 6, 1, 220, 118, 56, 200, 197, + 208, 154, 248, 167, 200, 166, 200, 197, 208, 154, 248, 167, 210, 157, + 200, 197, 208, 154, 248, 167, 208, 141, 200, 197, 208, 154, 248, 167, + 247, 147, 200, 197, 208, 154, 248, 167, 219, 175, 205, 122, 200, 197, + 208, 154, 248, 167, 222, 144, 205, 122, 200, 197, 208, 154, 248, 167, + 238, 35, 205, 122, 200, 197, 208, 154, 248, 167, 249, 156, 205, 122, 195, + 150, 163, 222, 59, 195, 150, 163, 203, 131, 195, 150, 163, 208, 227, 195, + 150, 3, 213, 189, 195, 150, 3, 192, 117, 216, 84, 200, 156, 195, 150, + 163, 192, 117, 251, 251, 223, 151, 200, 156, 195, 150, 163, 192, 117, + 223, 151, 200, 156, 195, 150, 163, 192, 117, 222, 47, 223, 151, 200, 156, + 195, 150, 163, 247, 124, 60, 195, 150, 163, 192, 117, 222, 47, 223, 151, + 200, 157, 205, 89, 195, 150, 163, 55, 200, 156, 195, 150, 163, 197, 225, + 200, 156, 195, 150, 163, 222, 47, 251, 75, 195, 150, 163, 75, 60, 195, 150, 163, 105, 185, 60, 195, 150, 163, 115, 185, 60, 195, 150, 163, 206, - 196, 222, 56, 223, 149, 200, 156, 195, 150, 163, 250, 179, 223, 149, 200, + 197, 222, 58, 223, 151, 200, 156, 195, 150, 163, 250, 181, 223, 151, 200, 156, 195, 150, 3, 195, 36, 200, 156, 195, 150, 3, 195, 36, 196, 154, 195, - 150, 3, 207, 18, 195, 36, 196, 154, 195, 150, 3, 195, 36, 251, 73, 195, - 150, 3, 207, 18, 195, 36, 251, 73, 195, 150, 3, 195, 36, 196, 155, 4, - 199, 215, 195, 150, 3, 195, 36, 251, 74, 4, 199, 215, 195, 150, 3, 251, - 72, 251, 88, 195, 150, 3, 251, 72, 249, 120, 195, 150, 3, 251, 72, 195, - 178, 195, 150, 3, 251, 72, 195, 179, 4, 199, 215, 195, 150, 3, 198, 126, - 195, 150, 3, 229, 180, 179, 251, 71, 195, 150, 3, 179, 251, 71, 195, 150, - 3, 206, 70, 179, 251, 71, 195, 150, 3, 251, 72, 196, 162, 215, 136, 195, - 150, 3, 251, 10, 195, 150, 3, 206, 122, 251, 10, 195, 150, 163, 247, 122, - 58, 195, 150, 3, 222, 237, 195, 150, 3, 196, 75, 195, 150, 3, 250, 177, - 195, 150, 163, 206, 189, 58, 195, 150, 163, 55, 206, 189, 58, 195, 150, - 3, 55, 251, 72, 251, 88, 8, 1, 2, 6, 65, 8, 1, 2, 6, 252, 25, 8, 2, 1, - 153, 252, 25, 8, 1, 2, 6, 249, 82, 250, 120, 8, 1, 2, 6, 247, 193, 8, 1, - 2, 6, 238, 127, 8, 1, 2, 6, 233, 248, 8, 1, 2, 6, 71, 8, 2, 1, 153, 211, - 77, 71, 8, 2, 1, 153, 68, 8, 1, 2, 6, 223, 35, 8, 1, 2, 6, 222, 152, 8, - 1, 2, 6, 220, 143, 4, 106, 8, 1, 2, 6, 218, 168, 8, 1, 2, 6, 207, 18, - 215, 61, 8, 1, 2, 6, 74, 8, 1, 2, 6, 211, 77, 74, 8, 2, 1, 202, 206, 74, - 8, 2, 1, 202, 206, 211, 77, 74, 8, 2, 1, 202, 206, 187, 4, 106, 8, 2, 1, - 153, 211, 151, 8, 1, 2, 6, 211, 19, 8, 2, 1, 198, 54, 132, 74, 8, 2, 1, - 248, 77, 132, 74, 8, 1, 2, 6, 210, 236, 8, 1, 2, 6, 207, 18, 146, 8, 1, - 2, 6, 153, 146, 8, 1, 2, 6, 200, 43, 8, 1, 2, 6, 66, 8, 2, 1, 202, 206, - 66, 8, 2, 1, 202, 206, 237, 40, 66, 8, 2, 1, 202, 206, 153, 218, 168, 8, + 150, 3, 207, 19, 195, 36, 196, 154, 195, 150, 3, 195, 36, 251, 75, 195, + 150, 3, 207, 19, 195, 36, 251, 75, 195, 150, 3, 195, 36, 196, 155, 4, + 199, 215, 195, 150, 3, 195, 36, 251, 76, 4, 199, 215, 195, 150, 3, 251, + 74, 251, 90, 195, 150, 3, 251, 74, 249, 122, 195, 150, 3, 251, 74, 195, + 178, 195, 150, 3, 251, 74, 195, 179, 4, 199, 215, 195, 150, 3, 198, 126, + 195, 150, 3, 229, 182, 180, 251, 73, 195, 150, 3, 180, 251, 73, 195, 150, + 3, 206, 71, 180, 251, 73, 195, 150, 3, 251, 74, 196, 162, 215, 138, 195, + 150, 3, 251, 12, 195, 150, 3, 206, 123, 251, 12, 195, 150, 163, 247, 124, + 58, 195, 150, 3, 222, 239, 195, 150, 3, 196, 75, 195, 150, 3, 250, 179, + 195, 150, 163, 206, 190, 58, 195, 150, 163, 55, 206, 190, 58, 195, 150, + 3, 55, 251, 74, 251, 90, 8, 1, 2, 6, 65, 8, 1, 2, 6, 252, 27, 8, 2, 1, + 154, 252, 27, 8, 1, 2, 6, 249, 84, 250, 122, 8, 1, 2, 6, 247, 195, 8, 1, + 2, 6, 238, 129, 8, 1, 2, 6, 233, 250, 8, 1, 2, 6, 71, 8, 2, 1, 154, 211, + 79, 71, 8, 2, 1, 154, 68, 8, 1, 2, 6, 223, 37, 8, 1, 2, 6, 222, 154, 8, + 1, 2, 6, 220, 145, 4, 106, 8, 1, 2, 6, 218, 170, 8, 1, 2, 6, 207, 19, + 215, 63, 8, 1, 2, 6, 74, 8, 1, 2, 6, 211, 79, 74, 8, 2, 1, 202, 207, 74, + 8, 2, 1, 202, 207, 211, 79, 74, 8, 2, 1, 202, 207, 187, 4, 106, 8, 2, 1, + 154, 211, 153, 8, 1, 2, 6, 211, 21, 8, 2, 1, 198, 54, 132, 74, 8, 2, 1, + 248, 79, 132, 74, 8, 1, 2, 6, 210, 238, 8, 1, 2, 6, 207, 19, 146, 8, 1, + 2, 6, 154, 146, 8, 1, 2, 6, 200, 43, 8, 1, 2, 6, 66, 8, 2, 1, 202, 207, + 66, 8, 2, 1, 202, 207, 237, 42, 66, 8, 2, 1, 202, 207, 154, 218, 170, 8, 1, 2, 6, 196, 12, 8, 1, 2, 6, 193, 224, 8, 1, 2, 6, 191, 166, 8, 1, 2, 6, - 233, 178, 8, 1, 195, 20, 220, 8, 201, 216, 8, 1, 251, 230, 35, 1, 2, 6, - 231, 211, 35, 1, 2, 6, 220, 31, 35, 1, 2, 6, 209, 185, 35, 1, 2, 6, 207, - 3, 35, 1, 2, 6, 208, 176, 38, 1, 2, 6, 234, 140, 52, 1, 6, 65, 52, 1, 6, - 252, 25, 52, 1, 6, 250, 120, 52, 1, 6, 249, 82, 250, 120, 52, 1, 6, 238, - 127, 52, 1, 6, 71, 52, 1, 6, 207, 18, 71, 52, 1, 6, 232, 51, 52, 1, 6, - 230, 116, 52, 1, 6, 68, 52, 1, 6, 223, 35, 52, 1, 6, 222, 152, 52, 1, 6, - 172, 52, 1, 6, 218, 168, 52, 1, 6, 215, 61, 52, 1, 6, 207, 18, 215, 61, - 52, 1, 6, 74, 52, 1, 6, 211, 19, 52, 1, 6, 210, 236, 52, 1, 6, 146, 52, + 233, 180, 8, 1, 195, 20, 220, 10, 201, 217, 8, 1, 251, 232, 35, 1, 2, 6, + 231, 213, 35, 1, 2, 6, 220, 33, 35, 1, 2, 6, 209, 187, 35, 1, 2, 6, 207, + 4, 35, 1, 2, 6, 208, 178, 38, 1, 2, 6, 234, 142, 52, 1, 6, 65, 52, 1, 6, + 252, 27, 52, 1, 6, 250, 122, 52, 1, 6, 249, 84, 250, 122, 52, 1, 6, 238, + 129, 52, 1, 6, 71, 52, 1, 6, 207, 19, 71, 52, 1, 6, 232, 53, 52, 1, 6, + 230, 118, 52, 1, 6, 68, 52, 1, 6, 223, 37, 52, 1, 6, 222, 154, 52, 1, 6, + 172, 52, 1, 6, 218, 170, 52, 1, 6, 215, 63, 52, 1, 6, 207, 19, 215, 63, + 52, 1, 6, 74, 52, 1, 6, 211, 21, 52, 1, 6, 210, 238, 52, 1, 6, 146, 52, 1, 6, 200, 43, 52, 1, 6, 66, 52, 1, 6, 193, 224, 52, 1, 2, 65, 52, 1, 2, - 153, 65, 52, 1, 2, 251, 160, 52, 1, 2, 153, 252, 25, 52, 1, 2, 250, 120, - 52, 1, 2, 238, 127, 52, 1, 2, 71, 52, 1, 2, 205, 86, 52, 1, 2, 211, 77, - 71, 52, 1, 2, 153, 211, 77, 71, 52, 1, 2, 232, 51, 52, 1, 2, 153, 68, 52, - 1, 2, 222, 152, 52, 1, 2, 218, 168, 52, 1, 2, 234, 88, 52, 1, 2, 74, 52, - 1, 2, 211, 77, 74, 52, 1, 2, 198, 54, 132, 74, 52, 1, 2, 248, 77, 132, - 74, 52, 1, 2, 210, 236, 52, 1, 2, 200, 43, 52, 1, 2, 66, 52, 1, 2, 202, - 206, 66, 52, 1, 2, 153, 218, 168, 52, 1, 2, 196, 12, 52, 1, 2, 251, 230, - 52, 1, 2, 248, 212, 52, 1, 2, 35, 231, 211, 52, 1, 2, 237, 106, 52, 1, 2, - 35, 209, 211, 52, 1, 2, 243, 95, 8, 200, 230, 2, 1, 68, 8, 200, 230, 2, - 1, 146, 8, 200, 230, 2, 1, 66, 8, 200, 230, 2, 1, 196, 12, 35, 200, 230, - 2, 1, 248, 212, 35, 200, 230, 2, 1, 231, 211, 35, 200, 230, 2, 1, 207, 3, - 35, 200, 230, 2, 1, 209, 211, 35, 200, 230, 2, 1, 243, 95, 8, 2, 1, 196, - 152, 8, 2, 1, 78, 4, 82, 198, 152, 8, 2, 1, 238, 128, 4, 82, 198, 152, 8, - 2, 1, 233, 176, 4, 82, 198, 152, 8, 2, 1, 218, 169, 4, 82, 198, 152, 8, - 2, 1, 215, 62, 4, 82, 198, 152, 8, 2, 1, 210, 237, 4, 82, 198, 152, 8, 2, - 1, 207, 222, 4, 82, 198, 152, 8, 2, 1, 207, 222, 4, 232, 234, 23, 82, - 198, 152, 8, 2, 1, 206, 9, 4, 82, 198, 152, 8, 2, 1, 200, 44, 4, 82, 198, - 152, 8, 2, 1, 191, 167, 4, 82, 198, 152, 8, 2, 1, 153, 232, 51, 52, 1, - 38, 234, 103, 8, 2, 1, 223, 115, 232, 51, 8, 2, 1, 199, 52, 4, 201, 32, - 8, 2, 6, 1, 228, 74, 4, 106, 8, 2, 1, 223, 84, 4, 106, 8, 2, 1, 210, 237, - 4, 106, 8, 2, 6, 1, 126, 4, 106, 8, 2, 1, 196, 71, 4, 106, 8, 2, 1, 78, - 4, 210, 192, 102, 8, 2, 1, 238, 128, 4, 210, 192, 102, 8, 2, 1, 233, 176, - 4, 210, 192, 102, 8, 2, 1, 232, 52, 4, 210, 192, 102, 8, 2, 1, 222, 153, - 4, 210, 192, 102, 8, 2, 1, 220, 143, 4, 210, 192, 102, 8, 2, 1, 218, 169, - 4, 210, 192, 102, 8, 2, 1, 215, 62, 4, 210, 192, 102, 8, 2, 1, 210, 237, - 4, 210, 192, 102, 8, 2, 1, 207, 222, 4, 210, 192, 102, 8, 2, 1, 206, 9, - 4, 210, 192, 102, 8, 2, 1, 234, 13, 4, 210, 192, 102, 8, 2, 1, 196, 13, - 4, 210, 192, 102, 8, 2, 1, 192, 236, 4, 210, 192, 102, 8, 2, 1, 191, 167, - 4, 210, 192, 102, 8, 2, 1, 42, 4, 207, 24, 102, 8, 2, 1, 251, 161, 4, - 207, 24, 102, 8, 2, 1, 238, 128, 4, 228, 251, 23, 199, 215, 8, 2, 1, 235, - 15, 4, 207, 24, 102, 8, 2, 1, 211, 77, 235, 15, 4, 207, 24, 102, 8, 2, 1, - 207, 18, 211, 77, 235, 15, 4, 207, 24, 102, 8, 2, 1, 205, 87, 4, 207, 24, - 102, 8, 2, 1, 228, 74, 4, 207, 24, 102, 8, 2, 1, 211, 77, 187, 4, 207, - 24, 102, 8, 2, 1, 234, 13, 4, 207, 24, 102, 8, 2, 1, 126, 4, 207, 24, - 102, 8, 2, 1, 233, 179, 4, 207, 24, 102, 52, 1, 2, 153, 251, 160, 52, 1, - 2, 247, 193, 52, 1, 2, 247, 194, 4, 238, 175, 52, 1, 2, 233, 248, 52, 1, - 2, 207, 18, 211, 77, 71, 52, 1, 2, 233, 175, 52, 1, 2, 236, 139, 223, 36, - 4, 106, 52, 1, 2, 27, 232, 51, 52, 1, 2, 153, 230, 116, 52, 1, 2, 228, - 74, 4, 106, 52, 1, 2, 223, 83, 52, 1, 2, 6, 68, 52, 1, 2, 6, 228, 74, 4, - 106, 52, 1, 2, 223, 36, 4, 238, 212, 52, 1, 2, 220, 143, 4, 207, 24, 102, - 52, 1, 2, 220, 143, 4, 210, 192, 102, 52, 1, 2, 6, 172, 52, 1, 2, 218, - 169, 4, 102, 52, 1, 2, 153, 218, 169, 4, 179, 219, 212, 52, 1, 2, 215, - 62, 4, 45, 102, 52, 1, 2, 215, 62, 4, 207, 24, 102, 52, 1, 2, 6, 215, 61, - 52, 1, 2, 249, 82, 74, 52, 1, 2, 209, 211, 52, 1, 2, 206, 9, 4, 102, 52, - 1, 2, 234, 12, 52, 1, 2, 200, 44, 4, 210, 192, 102, 52, 1, 2, 126, 164, - 52, 1, 2, 196, 70, 52, 1, 2, 6, 66, 52, 1, 2, 196, 13, 4, 102, 52, 1, 2, - 153, 196, 12, 52, 1, 2, 191, 166, 52, 1, 2, 191, 167, 4, 207, 24, 102, - 52, 1, 2, 191, 167, 4, 238, 175, 52, 1, 2, 233, 178, 52, 1, 2, 199, 15, - 33, 235, 138, 230, 211, 252, 60, 33, 235, 138, 252, 47, 252, 60, 33, 202, - 59, 60, 33, 200, 164, 77, 33, 217, 145, 33, 230, 208, 33, 217, 143, 33, - 252, 44, 33, 230, 209, 33, 252, 45, 33, 8, 2, 1, 207, 222, 60, 33, 248, - 35, 33, 217, 144, 33, 55, 243, 2, 58, 33, 211, 139, 58, 33, 191, 21, 60, - 33, 223, 69, 60, 33, 196, 63, 58, 33, 196, 46, 58, 33, 8, 2, 1, 232, 203, - 211, 77, 42, 58, 33, 8, 2, 1, 252, 25, 33, 8, 2, 1, 251, 68, 33, 8, 2, 1, - 250, 146, 33, 8, 2, 1, 247, 194, 247, 35, 33, 8, 2, 1, 223, 115, 238, - 127, 33, 8, 2, 1, 233, 248, 33, 8, 2, 1, 232, 51, 33, 8, 1, 2, 6, 232, - 51, 33, 8, 2, 1, 222, 152, 33, 8, 2, 1, 172, 33, 8, 1, 2, 6, 172, 33, 8, - 1, 2, 6, 218, 168, 33, 8, 2, 1, 215, 61, 33, 8, 1, 2, 6, 215, 61, 33, 8, - 1, 2, 6, 146, 33, 8, 2, 1, 207, 222, 206, 116, 33, 8, 2, 1, 206, 8, 33, - 8, 2, 1, 179, 206, 8, 33, 8, 2, 1, 191, 166, 33, 8, 2, 1, 251, 160, 33, - 8, 2, 1, 250, 120, 33, 8, 2, 1, 248, 212, 33, 8, 2, 1, 205, 86, 33, 8, 2, - 1, 233, 175, 33, 8, 2, 1, 220, 143, 4, 55, 82, 198, 152, 33, 8, 2, 1, - 187, 4, 156, 247, 23, 106, 33, 8, 2, 1, 210, 236, 33, 8, 2, 1, 234, 12, - 33, 8, 2, 1, 126, 4, 156, 247, 23, 106, 33, 8, 2, 1, 193, 224, 33, 8, 2, - 1, 42, 4, 237, 42, 33, 8, 2, 1, 187, 4, 237, 42, 33, 8, 2, 1, 126, 4, - 237, 42, 33, 133, 199, 229, 58, 33, 222, 36, 93, 183, 33, 222, 36, 93, - 219, 224, 33, 75, 93, 219, 224, 33, 193, 78, 223, 93, 248, 29, 60, 33, - 75, 248, 233, 219, 224, 33, 237, 115, 77, 33, 55, 223, 93, 248, 37, 60, - 33, 251, 165, 234, 45, 119, 60, 33, 45, 250, 236, 58, 33, 50, 250, 236, - 23, 144, 250, 236, 60, 8, 6, 1, 42, 4, 206, 189, 60, 8, 2, 1, 42, 4, 206, - 189, 60, 8, 6, 1, 78, 4, 75, 58, 8, 2, 1, 78, 4, 75, 58, 8, 6, 1, 78, 4, - 75, 60, 8, 2, 1, 78, 4, 75, 60, 8, 6, 1, 78, 4, 219, 113, 60, 8, 2, 1, - 78, 4, 219, 113, 60, 8, 6, 1, 247, 194, 4, 247, 36, 23, 252, 46, 8, 2, 1, - 247, 194, 4, 247, 36, 23, 252, 46, 8, 6, 1, 238, 128, 4, 75, 58, 8, 2, 1, - 238, 128, 4, 75, 58, 8, 6, 1, 238, 128, 4, 75, 60, 8, 2, 1, 238, 128, 4, - 75, 60, 8, 6, 1, 238, 128, 4, 219, 113, 60, 8, 2, 1, 238, 128, 4, 219, - 113, 60, 8, 6, 1, 238, 128, 4, 247, 35, 8, 2, 1, 238, 128, 4, 247, 35, 8, - 6, 1, 238, 128, 4, 243, 2, 60, 8, 2, 1, 238, 128, 4, 243, 2, 60, 8, 6, 1, - 235, 15, 4, 217, 147, 23, 230, 210, 8, 2, 1, 235, 15, 4, 217, 147, 23, - 230, 210, 8, 6, 1, 235, 15, 4, 217, 147, 23, 252, 46, 8, 2, 1, 235, 15, - 4, 217, 147, 23, 252, 46, 8, 6, 1, 235, 15, 4, 243, 2, 60, 8, 2, 1, 235, - 15, 4, 243, 2, 60, 8, 6, 1, 235, 15, 4, 198, 153, 60, 8, 2, 1, 235, 15, - 4, 198, 153, 60, 8, 6, 1, 235, 15, 4, 247, 36, 23, 248, 36, 8, 2, 1, 235, - 15, 4, 247, 36, 23, 248, 36, 8, 6, 1, 233, 176, 4, 75, 58, 8, 2, 1, 233, - 176, 4, 75, 58, 8, 6, 1, 232, 52, 4, 217, 146, 8, 2, 1, 232, 52, 4, 217, - 146, 8, 6, 1, 230, 117, 4, 75, 58, 8, 2, 1, 230, 117, 4, 75, 58, 8, 6, 1, - 230, 117, 4, 75, 60, 8, 2, 1, 230, 117, 4, 75, 60, 8, 6, 1, 230, 117, 4, - 237, 42, 8, 2, 1, 230, 117, 4, 237, 42, 8, 6, 1, 230, 117, 4, 247, 35, 8, - 2, 1, 230, 117, 4, 247, 35, 8, 6, 1, 230, 117, 4, 248, 37, 60, 8, 2, 1, - 230, 117, 4, 248, 37, 60, 8, 6, 1, 228, 74, 4, 198, 153, 60, 8, 2, 1, - 228, 74, 4, 198, 153, 60, 8, 6, 1, 228, 74, 4, 237, 43, 23, 252, 46, 8, - 2, 1, 228, 74, 4, 237, 43, 23, 252, 46, 8, 6, 1, 222, 153, 4, 252, 46, 8, - 2, 1, 222, 153, 4, 252, 46, 8, 6, 1, 222, 153, 4, 75, 60, 8, 2, 1, 222, - 153, 4, 75, 60, 8, 6, 1, 222, 153, 4, 219, 113, 60, 8, 2, 1, 222, 153, 4, - 219, 113, 60, 8, 6, 1, 220, 143, 4, 75, 60, 8, 2, 1, 220, 143, 4, 75, 60, - 8, 6, 1, 220, 143, 4, 75, 248, 233, 23, 217, 146, 8, 2, 1, 220, 143, 4, - 75, 248, 233, 23, 217, 146, 8, 6, 1, 220, 143, 4, 219, 113, 60, 8, 2, 1, - 220, 143, 4, 219, 113, 60, 8, 6, 1, 220, 143, 4, 243, 2, 60, 8, 2, 1, - 220, 143, 4, 243, 2, 60, 8, 6, 1, 218, 169, 4, 252, 46, 8, 2, 1, 218, - 169, 4, 252, 46, 8, 6, 1, 218, 169, 4, 75, 58, 8, 2, 1, 218, 169, 4, 75, - 58, 8, 6, 1, 218, 169, 4, 75, 60, 8, 2, 1, 218, 169, 4, 75, 60, 8, 6, 1, - 215, 62, 4, 75, 58, 8, 2, 1, 215, 62, 4, 75, 58, 8, 6, 1, 215, 62, 4, 75, - 60, 8, 2, 1, 215, 62, 4, 75, 60, 8, 6, 1, 215, 62, 4, 219, 113, 60, 8, 2, - 1, 215, 62, 4, 219, 113, 60, 8, 6, 1, 215, 62, 4, 243, 2, 60, 8, 2, 1, - 215, 62, 4, 243, 2, 60, 8, 6, 1, 187, 4, 198, 153, 23, 252, 46, 8, 2, 1, - 187, 4, 198, 153, 23, 252, 46, 8, 6, 1, 187, 4, 198, 153, 23, 237, 42, 8, - 2, 1, 187, 4, 198, 153, 23, 237, 42, 8, 6, 1, 187, 4, 217, 147, 23, 230, - 210, 8, 2, 1, 187, 4, 217, 147, 23, 230, 210, 8, 6, 1, 187, 4, 217, 147, - 23, 252, 46, 8, 2, 1, 187, 4, 217, 147, 23, 252, 46, 8, 6, 1, 210, 237, - 4, 252, 46, 8, 2, 1, 210, 237, 4, 252, 46, 8, 6, 1, 210, 237, 4, 75, 58, - 8, 2, 1, 210, 237, 4, 75, 58, 8, 6, 1, 207, 222, 4, 75, 58, 8, 2, 1, 207, - 222, 4, 75, 58, 8, 6, 1, 207, 222, 4, 75, 60, 8, 2, 1, 207, 222, 4, 75, - 60, 8, 6, 1, 207, 222, 4, 75, 248, 233, 23, 217, 146, 8, 2, 1, 207, 222, - 4, 75, 248, 233, 23, 217, 146, 8, 6, 1, 207, 222, 4, 219, 113, 60, 8, 2, - 1, 207, 222, 4, 219, 113, 60, 8, 6, 1, 206, 9, 4, 75, 58, 8, 2, 1, 206, - 9, 4, 75, 58, 8, 6, 1, 206, 9, 4, 75, 60, 8, 2, 1, 206, 9, 4, 75, 60, 8, - 6, 1, 206, 9, 4, 252, 47, 23, 75, 58, 8, 2, 1, 206, 9, 4, 252, 47, 23, - 75, 58, 8, 6, 1, 206, 9, 4, 247, 93, 23, 75, 58, 8, 2, 1, 206, 9, 4, 247, - 93, 23, 75, 58, 8, 6, 1, 206, 9, 4, 75, 248, 233, 23, 75, 58, 8, 2, 1, - 206, 9, 4, 75, 248, 233, 23, 75, 58, 8, 6, 1, 200, 44, 4, 75, 58, 8, 2, - 1, 200, 44, 4, 75, 58, 8, 6, 1, 200, 44, 4, 75, 60, 8, 2, 1, 200, 44, 4, - 75, 60, 8, 6, 1, 200, 44, 4, 219, 113, 60, 8, 2, 1, 200, 44, 4, 219, 113, - 60, 8, 6, 1, 200, 44, 4, 243, 2, 60, 8, 2, 1, 200, 44, 4, 243, 2, 60, 8, - 6, 1, 126, 4, 237, 43, 60, 8, 2, 1, 126, 4, 237, 43, 60, 8, 6, 1, 126, 4, - 198, 153, 60, 8, 2, 1, 126, 4, 198, 153, 60, 8, 6, 1, 126, 4, 243, 2, 60, - 8, 2, 1, 126, 4, 243, 2, 60, 8, 6, 1, 126, 4, 198, 153, 23, 252, 46, 8, - 2, 1, 126, 4, 198, 153, 23, 252, 46, 8, 6, 1, 126, 4, 217, 147, 23, 237, - 42, 8, 2, 1, 126, 4, 217, 147, 23, 237, 42, 8, 6, 1, 196, 13, 4, 198, - 152, 8, 2, 1, 196, 13, 4, 198, 152, 8, 6, 1, 196, 13, 4, 75, 60, 8, 2, 1, - 196, 13, 4, 75, 60, 8, 6, 1, 193, 225, 4, 230, 210, 8, 2, 1, 193, 225, 4, - 230, 210, 8, 6, 1, 193, 225, 4, 252, 46, 8, 2, 1, 193, 225, 4, 252, 46, - 8, 6, 1, 193, 225, 4, 237, 42, 8, 2, 1, 193, 225, 4, 237, 42, 8, 6, 1, - 193, 225, 4, 75, 58, 8, 2, 1, 193, 225, 4, 75, 58, 8, 6, 1, 193, 225, 4, - 75, 60, 8, 2, 1, 193, 225, 4, 75, 60, 8, 6, 1, 192, 236, 4, 75, 58, 8, 2, - 1, 192, 236, 4, 75, 58, 8, 6, 1, 192, 236, 4, 237, 42, 8, 2, 1, 192, 236, - 4, 237, 42, 8, 6, 1, 192, 160, 4, 75, 58, 8, 2, 1, 192, 160, 4, 75, 58, - 8, 6, 1, 191, 167, 4, 243, 1, 8, 2, 1, 191, 167, 4, 243, 1, 8, 6, 1, 191, - 167, 4, 75, 60, 8, 2, 1, 191, 167, 4, 75, 60, 8, 6, 1, 191, 167, 4, 219, - 113, 60, 8, 2, 1, 191, 167, 4, 219, 113, 60, 8, 2, 1, 230, 117, 4, 219, - 113, 60, 8, 2, 1, 200, 44, 4, 237, 42, 8, 2, 1, 193, 225, 4, 206, 189, - 58, 8, 2, 1, 192, 160, 4, 206, 189, 58, 8, 2, 1, 42, 4, 50, 132, 206, - 188, 8, 2, 1, 179, 206, 9, 4, 75, 58, 8, 2, 1, 179, 206, 9, 4, 237, 39, - 106, 8, 2, 1, 179, 206, 9, 4, 137, 106, 8, 6, 1, 203, 127, 206, 8, 8, 2, - 1, 237, 106, 8, 6, 1, 42, 4, 75, 60, 8, 2, 1, 42, 4, 75, 60, 8, 6, 1, 42, - 4, 228, 251, 58, 8, 2, 1, 42, 4, 228, 251, 58, 8, 6, 1, 42, 4, 243, 2, - 23, 252, 46, 8, 2, 1, 42, 4, 243, 2, 23, 252, 46, 8, 6, 1, 42, 4, 243, 2, - 23, 230, 210, 8, 2, 1, 42, 4, 243, 2, 23, 230, 210, 8, 6, 1, 42, 4, 243, - 2, 23, 228, 251, 58, 8, 2, 1, 42, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, - 42, 4, 243, 2, 23, 198, 152, 8, 2, 1, 42, 4, 243, 2, 23, 198, 152, 8, 6, - 1, 42, 4, 243, 2, 23, 75, 60, 8, 2, 1, 42, 4, 243, 2, 23, 75, 60, 8, 6, - 1, 42, 4, 248, 37, 23, 252, 46, 8, 2, 1, 42, 4, 248, 37, 23, 252, 46, 8, - 6, 1, 42, 4, 248, 37, 23, 230, 210, 8, 2, 1, 42, 4, 248, 37, 23, 230, - 210, 8, 6, 1, 42, 4, 248, 37, 23, 228, 251, 58, 8, 2, 1, 42, 4, 248, 37, - 23, 228, 251, 58, 8, 6, 1, 42, 4, 248, 37, 23, 198, 152, 8, 2, 1, 42, 4, - 248, 37, 23, 198, 152, 8, 6, 1, 42, 4, 248, 37, 23, 75, 60, 8, 2, 1, 42, - 4, 248, 37, 23, 75, 60, 8, 6, 1, 235, 15, 4, 75, 60, 8, 2, 1, 235, 15, 4, - 75, 60, 8, 6, 1, 235, 15, 4, 228, 251, 58, 8, 2, 1, 235, 15, 4, 228, 251, - 58, 8, 6, 1, 235, 15, 4, 198, 152, 8, 2, 1, 235, 15, 4, 198, 152, 8, 6, - 1, 235, 15, 4, 243, 2, 23, 252, 46, 8, 2, 1, 235, 15, 4, 243, 2, 23, 252, - 46, 8, 6, 1, 235, 15, 4, 243, 2, 23, 230, 210, 8, 2, 1, 235, 15, 4, 243, - 2, 23, 230, 210, 8, 6, 1, 235, 15, 4, 243, 2, 23, 228, 251, 58, 8, 2, 1, - 235, 15, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, 235, 15, 4, 243, 2, 23, - 198, 152, 8, 2, 1, 235, 15, 4, 243, 2, 23, 198, 152, 8, 6, 1, 235, 15, 4, - 243, 2, 23, 75, 60, 8, 2, 1, 235, 15, 4, 243, 2, 23, 75, 60, 8, 6, 1, - 228, 74, 4, 228, 251, 58, 8, 2, 1, 228, 74, 4, 228, 251, 58, 8, 6, 1, - 228, 74, 4, 75, 60, 8, 2, 1, 228, 74, 4, 75, 60, 8, 6, 1, 187, 4, 75, 60, - 8, 2, 1, 187, 4, 75, 60, 8, 6, 1, 187, 4, 228, 251, 58, 8, 2, 1, 187, 4, - 228, 251, 58, 8, 6, 1, 187, 4, 243, 2, 23, 252, 46, 8, 2, 1, 187, 4, 243, - 2, 23, 252, 46, 8, 6, 1, 187, 4, 243, 2, 23, 230, 210, 8, 2, 1, 187, 4, - 243, 2, 23, 230, 210, 8, 6, 1, 187, 4, 243, 2, 23, 228, 251, 58, 8, 2, 1, - 187, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, 187, 4, 243, 2, 23, 198, 152, - 8, 2, 1, 187, 4, 243, 2, 23, 198, 152, 8, 6, 1, 187, 4, 243, 2, 23, 75, - 60, 8, 2, 1, 187, 4, 243, 2, 23, 75, 60, 8, 6, 1, 187, 4, 228, 188, 23, - 252, 46, 8, 2, 1, 187, 4, 228, 188, 23, 252, 46, 8, 6, 1, 187, 4, 228, - 188, 23, 230, 210, 8, 2, 1, 187, 4, 228, 188, 23, 230, 210, 8, 6, 1, 187, - 4, 228, 188, 23, 228, 251, 58, 8, 2, 1, 187, 4, 228, 188, 23, 228, 251, - 58, 8, 6, 1, 187, 4, 228, 188, 23, 198, 152, 8, 2, 1, 187, 4, 228, 188, - 23, 198, 152, 8, 6, 1, 187, 4, 228, 188, 23, 75, 60, 8, 2, 1, 187, 4, - 228, 188, 23, 75, 60, 8, 6, 1, 126, 4, 75, 60, 8, 2, 1, 126, 4, 75, 60, - 8, 6, 1, 126, 4, 228, 251, 58, 8, 2, 1, 126, 4, 228, 251, 58, 8, 6, 1, - 126, 4, 228, 188, 23, 252, 46, 8, 2, 1, 126, 4, 228, 188, 23, 252, 46, 8, - 6, 1, 126, 4, 228, 188, 23, 230, 210, 8, 2, 1, 126, 4, 228, 188, 23, 230, - 210, 8, 6, 1, 126, 4, 228, 188, 23, 228, 251, 58, 8, 2, 1, 126, 4, 228, - 188, 23, 228, 251, 58, 8, 6, 1, 126, 4, 228, 188, 23, 198, 152, 8, 2, 1, - 126, 4, 228, 188, 23, 198, 152, 8, 6, 1, 126, 4, 228, 188, 23, 75, 60, 8, - 2, 1, 126, 4, 228, 188, 23, 75, 60, 8, 6, 1, 192, 160, 4, 230, 210, 8, 2, - 1, 192, 160, 4, 230, 210, 8, 6, 1, 192, 160, 4, 75, 60, 8, 2, 1, 192, - 160, 4, 75, 60, 8, 6, 1, 192, 160, 4, 228, 251, 58, 8, 2, 1, 192, 160, 4, - 228, 251, 58, 8, 6, 1, 192, 160, 4, 198, 152, 8, 2, 1, 192, 160, 4, 198, - 152, 8, 6, 1, 216, 83, 219, 74, 8, 2, 1, 216, 83, 219, 74, 8, 6, 1, 216, - 83, 196, 12, 8, 2, 1, 216, 83, 196, 12, 8, 6, 1, 192, 160, 4, 219, 4, 8, - 2, 1, 192, 160, 4, 219, 4, 35, 2, 1, 251, 161, 4, 208, 169, 35, 2, 1, - 251, 161, 4, 237, 212, 35, 2, 1, 251, 161, 4, 208, 170, 23, 195, 169, 35, - 2, 1, 251, 161, 4, 237, 213, 23, 195, 169, 35, 2, 1, 251, 161, 4, 208, - 170, 23, 210, 243, 35, 2, 1, 251, 161, 4, 237, 213, 23, 210, 243, 35, 2, - 1, 251, 161, 4, 208, 170, 23, 210, 4, 35, 2, 1, 251, 161, 4, 237, 213, - 23, 210, 4, 35, 6, 1, 251, 161, 4, 208, 169, 35, 6, 1, 251, 161, 4, 237, - 212, 35, 6, 1, 251, 161, 4, 208, 170, 23, 195, 169, 35, 6, 1, 251, 161, - 4, 237, 213, 23, 195, 169, 35, 6, 1, 251, 161, 4, 208, 170, 23, 210, 243, - 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 243, 35, 6, 1, 251, 161, 4, - 208, 170, 23, 210, 4, 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 4, 35, 2, - 1, 234, 48, 4, 208, 169, 35, 2, 1, 234, 48, 4, 237, 212, 35, 2, 1, 234, - 48, 4, 208, 170, 23, 195, 169, 35, 2, 1, 234, 48, 4, 237, 213, 23, 195, - 169, 35, 2, 1, 234, 48, 4, 208, 170, 23, 210, 243, 35, 2, 1, 234, 48, 4, - 237, 213, 23, 210, 243, 35, 6, 1, 234, 48, 4, 208, 169, 35, 6, 1, 234, - 48, 4, 237, 212, 35, 6, 1, 234, 48, 4, 208, 170, 23, 195, 169, 35, 6, 1, - 234, 48, 4, 237, 213, 23, 195, 169, 35, 6, 1, 234, 48, 4, 208, 170, 23, - 210, 243, 35, 6, 1, 234, 48, 4, 237, 213, 23, 210, 243, 35, 2, 1, 233, - 254, 4, 208, 169, 35, 2, 1, 233, 254, 4, 237, 212, 35, 2, 1, 233, 254, 4, - 208, 170, 23, 195, 169, 35, 2, 1, 233, 254, 4, 237, 213, 23, 195, 169, - 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 243, 35, 2, 1, 233, 254, 4, - 237, 213, 23, 210, 243, 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 4, 35, - 2, 1, 233, 254, 4, 237, 213, 23, 210, 4, 35, 6, 1, 233, 254, 4, 208, 169, - 35, 6, 1, 233, 254, 4, 237, 212, 35, 6, 1, 233, 254, 4, 208, 170, 23, - 195, 169, 35, 6, 1, 233, 254, 4, 237, 213, 23, 195, 169, 35, 6, 1, 233, - 254, 4, 208, 170, 23, 210, 243, 35, 6, 1, 233, 254, 4, 237, 213, 23, 210, - 243, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, 4, 35, 6, 1, 233, 254, 4, - 237, 213, 23, 210, 4, 35, 2, 1, 223, 84, 4, 208, 169, 35, 2, 1, 223, 84, - 4, 237, 212, 35, 2, 1, 223, 84, 4, 208, 170, 23, 195, 169, 35, 2, 1, 223, - 84, 4, 237, 213, 23, 195, 169, 35, 2, 1, 223, 84, 4, 208, 170, 23, 210, - 243, 35, 2, 1, 223, 84, 4, 237, 213, 23, 210, 243, 35, 2, 1, 223, 84, 4, - 208, 170, 23, 210, 4, 35, 2, 1, 223, 84, 4, 237, 213, 23, 210, 4, 35, 6, - 1, 223, 84, 4, 208, 169, 35, 6, 1, 223, 84, 4, 237, 212, 35, 6, 1, 223, - 84, 4, 208, 170, 23, 195, 169, 35, 6, 1, 223, 84, 4, 237, 213, 23, 195, - 169, 35, 6, 1, 223, 84, 4, 208, 170, 23, 210, 243, 35, 6, 1, 223, 84, 4, - 237, 213, 23, 210, 243, 35, 6, 1, 223, 84, 4, 208, 170, 23, 210, 4, 35, - 6, 1, 223, 84, 4, 237, 213, 23, 210, 4, 35, 2, 1, 211, 108, 4, 208, 169, - 35, 2, 1, 211, 108, 4, 237, 212, 35, 2, 1, 211, 108, 4, 208, 170, 23, - 195, 169, 35, 2, 1, 211, 108, 4, 237, 213, 23, 195, 169, 35, 2, 1, 211, - 108, 4, 208, 170, 23, 210, 243, 35, 2, 1, 211, 108, 4, 237, 213, 23, 210, - 243, 35, 6, 1, 211, 108, 4, 208, 169, 35, 6, 1, 211, 108, 4, 237, 212, - 35, 6, 1, 211, 108, 4, 208, 170, 23, 195, 169, 35, 6, 1, 211, 108, 4, - 237, 213, 23, 195, 169, 35, 6, 1, 211, 108, 4, 208, 170, 23, 210, 243, - 35, 6, 1, 211, 108, 4, 237, 213, 23, 210, 243, 35, 2, 1, 196, 71, 4, 208, - 169, 35, 2, 1, 196, 71, 4, 237, 212, 35, 2, 1, 196, 71, 4, 208, 170, 23, - 195, 169, 35, 2, 1, 196, 71, 4, 237, 213, 23, 195, 169, 35, 2, 1, 196, - 71, 4, 208, 170, 23, 210, 243, 35, 2, 1, 196, 71, 4, 237, 213, 23, 210, - 243, 35, 2, 1, 196, 71, 4, 208, 170, 23, 210, 4, 35, 2, 1, 196, 71, 4, - 237, 213, 23, 210, 4, 35, 6, 1, 196, 71, 4, 237, 212, 35, 6, 1, 196, 71, - 4, 237, 213, 23, 195, 169, 35, 6, 1, 196, 71, 4, 237, 213, 23, 210, 243, - 35, 6, 1, 196, 71, 4, 237, 213, 23, 210, 4, 35, 2, 1, 211, 111, 4, 208, - 169, 35, 2, 1, 211, 111, 4, 237, 212, 35, 2, 1, 211, 111, 4, 208, 170, - 23, 195, 169, 35, 2, 1, 211, 111, 4, 237, 213, 23, 195, 169, 35, 2, 1, - 211, 111, 4, 208, 170, 23, 210, 243, 35, 2, 1, 211, 111, 4, 237, 213, 23, - 210, 243, 35, 2, 1, 211, 111, 4, 208, 170, 23, 210, 4, 35, 2, 1, 211, - 111, 4, 237, 213, 23, 210, 4, 35, 6, 1, 211, 111, 4, 208, 169, 35, 6, 1, - 211, 111, 4, 237, 212, 35, 6, 1, 211, 111, 4, 208, 170, 23, 195, 169, 35, - 6, 1, 211, 111, 4, 237, 213, 23, 195, 169, 35, 6, 1, 211, 111, 4, 208, - 170, 23, 210, 243, 35, 6, 1, 211, 111, 4, 237, 213, 23, 210, 243, 35, 6, - 1, 211, 111, 4, 208, 170, 23, 210, 4, 35, 6, 1, 211, 111, 4, 237, 213, - 23, 210, 4, 35, 2, 1, 251, 161, 4, 195, 169, 35, 2, 1, 251, 161, 4, 210, - 243, 35, 2, 1, 234, 48, 4, 195, 169, 35, 2, 1, 234, 48, 4, 210, 243, 35, - 2, 1, 233, 254, 4, 195, 169, 35, 2, 1, 233, 254, 4, 210, 243, 35, 2, 1, - 223, 84, 4, 195, 169, 35, 2, 1, 223, 84, 4, 210, 243, 35, 2, 1, 211, 108, - 4, 195, 169, 35, 2, 1, 211, 108, 4, 210, 243, 35, 2, 1, 196, 71, 4, 195, - 169, 35, 2, 1, 196, 71, 4, 210, 243, 35, 2, 1, 211, 111, 4, 195, 169, 35, - 2, 1, 211, 111, 4, 210, 243, 35, 2, 1, 251, 161, 4, 208, 170, 23, 191, - 233, 35, 2, 1, 251, 161, 4, 237, 213, 23, 191, 233, 35, 2, 1, 251, 161, - 4, 208, 170, 23, 195, 170, 23, 191, 233, 35, 2, 1, 251, 161, 4, 237, 213, - 23, 195, 170, 23, 191, 233, 35, 2, 1, 251, 161, 4, 208, 170, 23, 210, - 244, 23, 191, 233, 35, 2, 1, 251, 161, 4, 237, 213, 23, 210, 244, 23, - 191, 233, 35, 2, 1, 251, 161, 4, 208, 170, 23, 210, 5, 23, 191, 233, 35, - 2, 1, 251, 161, 4, 237, 213, 23, 210, 5, 23, 191, 233, 35, 6, 1, 251, - 161, 4, 208, 170, 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, 23, 208, - 184, 35, 6, 1, 251, 161, 4, 208, 170, 23, 195, 170, 23, 208, 184, 35, 6, - 1, 251, 161, 4, 237, 213, 23, 195, 170, 23, 208, 184, 35, 6, 1, 251, 161, - 4, 208, 170, 23, 210, 244, 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, - 23, 210, 244, 23, 208, 184, 35, 6, 1, 251, 161, 4, 208, 170, 23, 210, 5, - 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 5, 23, 208, 184, - 35, 2, 1, 233, 254, 4, 208, 170, 23, 191, 233, 35, 2, 1, 233, 254, 4, - 237, 213, 23, 191, 233, 35, 2, 1, 233, 254, 4, 208, 170, 23, 195, 170, - 23, 191, 233, 35, 2, 1, 233, 254, 4, 237, 213, 23, 195, 170, 23, 191, - 233, 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 244, 23, 191, 233, 35, 2, - 1, 233, 254, 4, 237, 213, 23, 210, 244, 23, 191, 233, 35, 2, 1, 233, 254, - 4, 208, 170, 23, 210, 5, 23, 191, 233, 35, 2, 1, 233, 254, 4, 237, 213, - 23, 210, 5, 23, 191, 233, 35, 6, 1, 233, 254, 4, 208, 170, 23, 208, 184, - 35, 6, 1, 233, 254, 4, 237, 213, 23, 208, 184, 35, 6, 1, 233, 254, 4, - 208, 170, 23, 195, 170, 23, 208, 184, 35, 6, 1, 233, 254, 4, 237, 213, - 23, 195, 170, 23, 208, 184, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, - 244, 23, 208, 184, 35, 6, 1, 233, 254, 4, 237, 213, 23, 210, 244, 23, - 208, 184, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, 5, 23, 208, 184, 35, - 6, 1, 233, 254, 4, 237, 213, 23, 210, 5, 23, 208, 184, 35, 2, 1, 211, - 111, 4, 208, 170, 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, 23, 191, - 233, 35, 2, 1, 211, 111, 4, 208, 170, 23, 195, 170, 23, 191, 233, 35, 2, - 1, 211, 111, 4, 237, 213, 23, 195, 170, 23, 191, 233, 35, 2, 1, 211, 111, - 4, 208, 170, 23, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, - 23, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 208, 170, 23, 210, 5, - 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, 23, 210, 5, 23, 191, 233, - 35, 6, 1, 211, 111, 4, 208, 170, 23, 208, 184, 35, 6, 1, 211, 111, 4, - 237, 213, 23, 208, 184, 35, 6, 1, 211, 111, 4, 208, 170, 23, 195, 170, - 23, 208, 184, 35, 6, 1, 211, 111, 4, 237, 213, 23, 195, 170, 23, 208, - 184, 35, 6, 1, 211, 111, 4, 208, 170, 23, 210, 244, 23, 208, 184, 35, 6, - 1, 211, 111, 4, 237, 213, 23, 210, 244, 23, 208, 184, 35, 6, 1, 211, 111, - 4, 208, 170, 23, 210, 5, 23, 208, 184, 35, 6, 1, 211, 111, 4, 237, 213, - 23, 210, 5, 23, 208, 184, 35, 2, 1, 251, 161, 4, 194, 254, 35, 2, 1, 251, - 161, 4, 217, 146, 35, 2, 1, 251, 161, 4, 195, 170, 23, 191, 233, 35, 2, - 1, 251, 161, 4, 191, 233, 35, 2, 1, 251, 161, 4, 210, 244, 23, 191, 233, - 35, 2, 1, 251, 161, 4, 210, 4, 35, 2, 1, 251, 161, 4, 210, 5, 23, 191, - 233, 35, 6, 1, 251, 161, 4, 194, 254, 35, 6, 1, 251, 161, 4, 217, 146, - 35, 6, 1, 251, 161, 4, 195, 169, 35, 6, 1, 251, 161, 4, 210, 243, 35, 6, - 1, 251, 161, 4, 208, 184, 35, 221, 30, 35, 208, 184, 35, 208, 169, 35, - 210, 4, 35, 237, 36, 23, 210, 4, 35, 2, 1, 233, 254, 4, 195, 170, 23, - 191, 233, 35, 2, 1, 233, 254, 4, 191, 233, 35, 2, 1, 233, 254, 4, 210, - 244, 23, 191, 233, 35, 2, 1, 233, 254, 4, 210, 4, 35, 2, 1, 233, 254, 4, - 210, 5, 23, 191, 233, 35, 6, 1, 234, 48, 4, 195, 169, 35, 6, 1, 234, 48, - 4, 210, 243, 35, 6, 1, 233, 254, 4, 195, 169, 35, 6, 1, 233, 254, 4, 210, - 243, 35, 6, 1, 233, 254, 4, 208, 184, 35, 208, 170, 23, 195, 169, 35, - 208, 170, 23, 210, 243, 35, 208, 170, 23, 210, 4, 35, 2, 1, 223, 84, 4, - 194, 254, 35, 2, 1, 223, 84, 4, 217, 146, 35, 2, 1, 223, 84, 4, 237, 36, - 23, 195, 169, 35, 2, 1, 223, 84, 4, 237, 36, 23, 210, 243, 35, 2, 1, 223, - 84, 4, 210, 4, 35, 2, 1, 223, 84, 4, 237, 36, 23, 210, 4, 35, 6, 1, 223, - 84, 4, 194, 254, 35, 6, 1, 223, 84, 4, 217, 146, 35, 6, 1, 223, 84, 4, - 195, 169, 35, 6, 1, 223, 84, 4, 210, 243, 35, 237, 213, 23, 195, 169, 35, - 237, 213, 23, 210, 243, 35, 237, 213, 23, 210, 4, 35, 2, 1, 196, 71, 4, - 194, 254, 35, 2, 1, 196, 71, 4, 217, 146, 35, 2, 1, 196, 71, 4, 237, 36, - 23, 195, 169, 35, 2, 1, 196, 71, 4, 237, 36, 23, 210, 243, 35, 2, 1, 207, - 4, 4, 208, 169, 35, 2, 1, 207, 4, 4, 237, 212, 35, 2, 1, 196, 71, 4, 210, - 4, 35, 2, 1, 196, 71, 4, 237, 36, 23, 210, 4, 35, 6, 1, 196, 71, 4, 194, - 254, 35, 6, 1, 196, 71, 4, 217, 146, 35, 6, 1, 196, 71, 4, 195, 169, 35, - 6, 1, 196, 71, 4, 210, 243, 35, 6, 1, 207, 4, 4, 237, 212, 35, 237, 36, - 23, 195, 169, 35, 237, 36, 23, 210, 243, 35, 195, 169, 35, 2, 1, 211, - 111, 4, 195, 170, 23, 191, 233, 35, 2, 1, 211, 111, 4, 191, 233, 35, 2, - 1, 211, 111, 4, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 210, 4, - 35, 2, 1, 211, 111, 4, 210, 5, 23, 191, 233, 35, 6, 1, 211, 108, 4, 195, - 169, 35, 6, 1, 211, 108, 4, 210, 243, 35, 6, 1, 211, 111, 4, 195, 169, - 35, 6, 1, 211, 111, 4, 210, 243, 35, 6, 1, 211, 111, 4, 208, 184, 35, - 210, 243, 35, 237, 212, 234, 104, 208, 30, 234, 115, 208, 30, 234, 104, - 201, 247, 234, 115, 201, 247, 198, 219, 201, 247, 232, 126, 201, 247, - 202, 134, 201, 247, 233, 13, 201, 247, 208, 152, 201, 247, 199, 4, 201, - 247, 230, 79, 201, 247, 191, 78, 193, 75, 201, 247, 191, 78, 193, 75, - 213, 29, 191, 78, 193, 75, 222, 196, 219, 215, 77, 206, 199, 77, 228, 88, - 213, 30, 228, 88, 233, 13, 237, 215, 234, 104, 237, 215, 234, 115, 237, - 215, 228, 241, 164, 55, 81, 219, 112, 55, 130, 219, 112, 45, 202, 170, - 207, 252, 77, 50, 202, 170, 207, 252, 77, 202, 170, 218, 240, 207, 252, - 77, 202, 170, 229, 132, 207, 252, 77, 45, 55, 207, 252, 77, 50, 55, 207, - 252, 77, 55, 218, 240, 207, 252, 77, 55, 229, 132, 207, 252, 77, 238, 14, - 55, 238, 14, 247, 248, 197, 238, 247, 248, 91, 75, 219, 236, 105, 75, - 219, 236, 228, 241, 234, 120, 228, 86, 209, 61, 219, 113, 204, 10, 210, - 128, 204, 10, 219, 215, 234, 113, 206, 199, 234, 113, 209, 34, 236, 232, - 232, 144, 219, 215, 210, 252, 206, 199, 210, 252, 214, 215, 213, 37, 201, - 247, 210, 14, 216, 50, 56, 210, 14, 199, 96, 198, 230, 56, 208, 215, 55, - 208, 215, 197, 225, 208, 215, 207, 18, 208, 215, 207, 18, 55, 208, 215, - 207, 18, 197, 225, 208, 215, 247, 96, 202, 170, 219, 219, 251, 116, 207, - 252, 77, 202, 170, 206, 203, 251, 116, 207, 252, 77, 207, 83, 77, 55, - 233, 216, 77, 223, 102, 210, 254, 196, 100, 246, 240, 198, 178, 247, 97, - 223, 119, 209, 61, 250, 191, 228, 89, 247, 248, 232, 118, 202, 97, 45, - 51, 248, 54, 4, 208, 7, 50, 51, 248, 54, 4, 208, 7, 55, 208, 13, 77, 208, - 13, 233, 216, 77, 233, 216, 208, 13, 77, 198, 128, 3, 233, 255, 207, 18, - 209, 142, 56, 62, 118, 247, 248, 62, 96, 247, 248, 130, 250, 193, 207, - 18, 204, 25, 242, 220, 196, 77, 105, 250, 192, 251, 178, 195, 84, 242, - 72, 216, 35, 56, 200, 129, 237, 215, 223, 93, 196, 100, 232, 187, 208, - 152, 77, 115, 75, 208, 151, 208, 26, 208, 215, 232, 128, 75, 208, 151, - 232, 226, 75, 208, 151, 105, 75, 208, 151, 232, 128, 75, 77, 235, 138, - 238, 217, 197, 237, 81, 232, 128, 236, 138, 216, 213, 13, 201, 247, 193, - 23, 222, 196, 232, 77, 251, 44, 223, 91, 198, 144, 223, 91, 204, 10, 223, - 91, 209, 81, 219, 215, 223, 59, 206, 199, 223, 59, 232, 238, 201, 14, - 223, 59, 209, 34, 236, 232, 223, 59, 223, 132, 200, 75, 200, 147, 252, - 49, 200, 75, 200, 147, 223, 132, 9, 232, 146, 203, 133, 252, 49, 9, 232, - 146, 203, 133, 214, 208, 17, 203, 134, 213, 33, 17, 203, 134, 200, 182, - 191, 77, 200, 182, 8, 2, 1, 68, 200, 182, 134, 200, 182, 149, 200, 182, - 169, 200, 182, 175, 200, 182, 171, 200, 182, 178, 200, 182, 108, 56, 200, - 182, 216, 34, 200, 182, 234, 43, 56, 200, 182, 45, 210, 113, 200, 182, - 50, 210, 113, 200, 182, 8, 2, 1, 215, 61, 200, 230, 191, 77, 200, 230, - 107, 200, 230, 109, 200, 230, 138, 200, 230, 134, 200, 230, 149, 200, - 230, 169, 200, 230, 175, 200, 230, 171, 200, 230, 178, 200, 230, 108, 56, - 200, 230, 216, 34, 200, 230, 234, 43, 56, 200, 230, 45, 210, 113, 200, - 230, 50, 210, 113, 8, 200, 230, 2, 1, 65, 8, 200, 230, 2, 1, 71, 8, 200, - 230, 2, 1, 74, 8, 200, 230, 2, 1, 192, 235, 8, 200, 230, 2, 1, 205, 86, - 8, 200, 230, 2, 1, 230, 116, 8, 200, 230, 2, 1, 222, 152, 8, 200, 230, 2, - 1, 172, 8, 200, 230, 2, 1, 218, 168, 8, 200, 230, 2, 1, 215, 61, 8, 200, - 230, 2, 1, 210, 236, 8, 200, 230, 2, 1, 206, 8, 8, 200, 230, 2, 1, 200, - 43, 233, 233, 56, 242, 84, 56, 238, 200, 56, 232, 106, 232, 111, 56, 219, - 91, 56, 216, 51, 56, 214, 234, 56, 209, 245, 56, 206, 36, 56, 193, 31, - 56, 214, 80, 203, 99, 56, 236, 149, 56, 233, 234, 56, 221, 135, 56, 197, - 81, 56, 235, 116, 56, 231, 138, 210, 27, 56, 209, 242, 56, 230, 174, 56, - 250, 153, 56, 228, 166, 56, 247, 37, 56, 219, 81, 198, 33, 56, 201, 226, - 56, 199, 93, 56, 223, 147, 206, 36, 56, 197, 60, 219, 91, 56, 213, 19, - 87, 56, 217, 88, 56, 206, 59, 56, 220, 9, 56, 248, 147, 56, 202, 22, 56, - 33, 45, 230, 13, 58, 33, 50, 230, 13, 58, 33, 179, 81, 219, 113, 210, - 255, 33, 203, 40, 81, 219, 113, 210, 255, 33, 251, 85, 64, 58, 33, 242, - 221, 64, 58, 33, 45, 64, 58, 33, 50, 64, 58, 33, 206, 189, 210, 255, 33, - 242, 221, 206, 189, 210, 255, 33, 251, 85, 206, 189, 210, 255, 33, 115, - 185, 58, 33, 232, 128, 185, 58, 33, 234, 99, 243, 10, 33, 234, 99, 201, - 190, 33, 234, 99, 237, 32, 33, 234, 99, 243, 11, 249, 141, 33, 45, 50, - 64, 58, 33, 234, 99, 205, 76, 33, 234, 99, 221, 218, 33, 234, 99, 196, - 68, 209, 58, 197, 241, 33, 207, 19, 202, 24, 210, 255, 33, 55, 81, 201, - 28, 210, 255, 33, 251, 95, 113, 33, 197, 225, 196, 102, 33, 193, 78, 248, - 29, 58, 33, 118, 64, 210, 255, 33, 179, 55, 202, 24, 210, 255, 33, 96, - 230, 13, 4, 181, 235, 118, 33, 118, 230, 13, 4, 181, 235, 118, 33, 45, - 64, 60, 33, 50, 64, 60, 33, 250, 194, 58, 252, 55, 211, 146, 252, 38, - 119, 199, 34, 200, 240, 235, 129, 6, 247, 193, 237, 125, 247, 27, 247, - 22, 219, 113, 113, 247, 98, 211, 146, 247, 152, 196, 112, 233, 235, 239, - 38, 205, 72, 237, 125, 233, 91, 27, 2, 232, 51, 27, 6, 230, 116, 248, - 137, 6, 230, 116, 235, 129, 6, 230, 116, 209, 103, 239, 38, 209, 103, - 239, 39, 139, 105, 209, 185, 27, 6, 68, 248, 137, 6, 68, 27, 6, 172, 27, - 2, 172, 220, 143, 78, 249, 88, 113, 235, 129, 6, 215, 61, 212, 132, 56, - 202, 5, 207, 95, 239, 5, 27, 6, 210, 236, 235, 129, 6, 210, 236, 235, - 129, 6, 208, 104, 27, 6, 146, 248, 137, 6, 146, 235, 129, 6, 146, 208, - 223, 199, 208, 207, 31, 204, 1, 77, 199, 107, 56, 198, 22, 87, 56, 195, - 136, 235, 129, 6, 191, 166, 211, 18, 56, 211, 135, 56, 223, 93, 211, 135, - 56, 248, 137, 6, 191, 166, 153, 35, 2, 1, 223, 83, 222, 3, 56, 251, 110, - 56, 27, 6, 250, 120, 248, 137, 6, 247, 193, 234, 4, 113, 27, 2, 71, 27, - 6, 71, 27, 6, 233, 175, 153, 6, 233, 175, 27, 6, 218, 168, 27, 2, 74, - 131, 113, 248, 215, 113, 231, 39, 113, 237, 254, 113, 223, 137, 202, 3, - 206, 122, 6, 208, 104, 233, 94, 56, 235, 129, 2, 209, 185, 235, 129, 2, - 231, 211, 235, 129, 6, 231, 211, 235, 129, 6, 209, 185, 235, 129, 215, - 60, 200, 201, 153, 49, 6, 232, 51, 153, 49, 6, 172, 207, 18, 49, 6, 172, - 153, 49, 6, 192, 159, 235, 129, 43, 6, 238, 127, 235, 129, 43, 2, 238, - 127, 235, 129, 43, 2, 71, 235, 129, 43, 2, 68, 235, 129, 43, 2, 223, 35, - 208, 188, 219, 112, 153, 251, 137, 210, 14, 56, 251, 210, 153, 2, 233, - 175, 16, 40, 205, 151, 202, 3, 193, 246, 232, 118, 91, 203, 243, 193, - 246, 232, 118, 91, 213, 167, 193, 246, 232, 118, 91, 199, 86, 193, 246, - 232, 118, 91, 199, 0, 193, 246, 232, 118, 105, 198, 253, 193, 246, 232, - 118, 91, 233, 18, 193, 246, 232, 118, 105, 233, 17, 193, 246, 232, 118, - 115, 233, 17, 193, 246, 232, 118, 232, 128, 233, 17, 193, 246, 232, 118, - 91, 202, 124, 193, 246, 232, 118, 232, 226, 202, 122, 193, 246, 232, 118, - 91, 234, 159, 193, 246, 232, 118, 115, 234, 157, 193, 246, 232, 118, 232, - 226, 234, 157, 193, 246, 232, 118, 203, 247, 234, 157, 232, 118, 212, - 133, 107, 206, 136, 212, 134, 107, 206, 136, 212, 134, 109, 206, 136, - 212, 134, 138, 206, 136, 212, 134, 134, 206, 136, 212, 134, 149, 206, - 136, 212, 134, 169, 206, 136, 212, 134, 175, 206, 136, 212, 134, 171, - 206, 136, 212, 134, 178, 206, 136, 212, 134, 199, 95, 206, 136, 212, 134, - 234, 127, 206, 136, 212, 134, 197, 37, 206, 136, 212, 134, 233, 15, 206, - 136, 212, 134, 91, 228, 140, 206, 136, 212, 134, 232, 226, 228, 140, 206, - 136, 212, 134, 91, 189, 2, 206, 136, 212, 134, 107, 2, 206, 136, 212, - 134, 109, 2, 206, 136, 212, 134, 138, 2, 206, 136, 212, 134, 134, 2, 206, - 136, 212, 134, 149, 2, 206, 136, 212, 134, 169, 2, 206, 136, 212, 134, - 175, 2, 206, 136, 212, 134, 171, 2, 206, 136, 212, 134, 178, 2, 206, 136, - 212, 134, 199, 95, 2, 206, 136, 212, 134, 234, 127, 2, 206, 136, 212, - 134, 197, 37, 2, 206, 136, 212, 134, 233, 15, 2, 206, 136, 212, 134, 91, - 228, 140, 2, 206, 136, 212, 134, 232, 226, 228, 140, 2, 206, 136, 212, - 134, 91, 189, 206, 136, 212, 134, 91, 198, 230, 247, 194, 238, 127, 206, - 136, 212, 134, 232, 226, 189, 206, 136, 212, 134, 199, 96, 189, 206, 136, - 212, 134, 207, 18, 91, 228, 140, 8, 2, 1, 207, 18, 247, 193, 206, 136, - 212, 134, 202, 136, 220, 4, 20, 206, 136, 212, 134, 233, 16, 234, 210, - 20, 206, 136, 212, 134, 233, 16, 189, 206, 136, 212, 134, 91, 228, 141, - 189, 193, 246, 232, 118, 191, 78, 198, 253, 153, 17, 109, 153, 17, 138, - 118, 57, 196, 66, 57, 96, 57, 235, 119, 57, 45, 50, 57, 133, 144, 57, - 186, 193, 105, 57, 186, 234, 204, 57, 202, 2, 234, 204, 57, 202, 2, 193, + 154, 65, 52, 1, 2, 251, 162, 52, 1, 2, 154, 252, 27, 52, 1, 2, 250, 122, + 52, 1, 2, 238, 129, 52, 1, 2, 71, 52, 1, 2, 205, 87, 52, 1, 2, 211, 79, + 71, 52, 1, 2, 154, 211, 79, 71, 52, 1, 2, 232, 53, 52, 1, 2, 154, 68, 52, + 1, 2, 222, 154, 52, 1, 2, 218, 170, 52, 1, 2, 234, 90, 52, 1, 2, 74, 52, + 1, 2, 211, 79, 74, 52, 1, 2, 198, 54, 132, 74, 52, 1, 2, 248, 79, 132, + 74, 52, 1, 2, 210, 238, 52, 1, 2, 200, 43, 52, 1, 2, 66, 52, 1, 2, 202, + 207, 66, 52, 1, 2, 154, 218, 170, 52, 1, 2, 196, 12, 52, 1, 2, 251, 232, + 52, 1, 2, 248, 214, 52, 1, 2, 35, 231, 213, 52, 1, 2, 237, 108, 52, 1, 2, + 35, 209, 213, 52, 1, 2, 243, 97, 8, 200, 231, 2, 1, 68, 8, 200, 231, 2, + 1, 146, 8, 200, 231, 2, 1, 66, 8, 200, 231, 2, 1, 196, 12, 35, 200, 231, + 2, 1, 248, 214, 35, 200, 231, 2, 1, 231, 213, 35, 200, 231, 2, 1, 207, 4, + 35, 200, 231, 2, 1, 209, 213, 35, 200, 231, 2, 1, 243, 97, 8, 2, 1, 196, + 152, 8, 2, 1, 78, 4, 82, 198, 152, 8, 2, 1, 238, 130, 4, 82, 198, 152, 8, + 2, 1, 233, 178, 4, 82, 198, 152, 8, 2, 1, 218, 171, 4, 82, 198, 152, 8, + 2, 1, 215, 64, 4, 82, 198, 152, 8, 2, 1, 210, 239, 4, 82, 198, 152, 8, 2, + 1, 207, 224, 4, 82, 198, 152, 8, 2, 1, 207, 224, 4, 232, 236, 23, 82, + 198, 152, 8, 2, 1, 206, 10, 4, 82, 198, 152, 8, 2, 1, 200, 44, 4, 82, + 198, 152, 8, 2, 1, 191, 167, 4, 82, 198, 152, 8, 2, 1, 154, 232, 53, 52, + 1, 38, 234, 105, 8, 2, 1, 223, 117, 232, 53, 8, 2, 1, 199, 52, 4, 201, + 33, 8, 2, 6, 1, 228, 76, 4, 106, 8, 2, 1, 223, 86, 4, 106, 8, 2, 1, 210, + 239, 4, 106, 8, 2, 6, 1, 126, 4, 106, 8, 2, 1, 196, 71, 4, 106, 8, 2, 1, + 78, 4, 210, 194, 102, 8, 2, 1, 238, 130, 4, 210, 194, 102, 8, 2, 1, 233, + 178, 4, 210, 194, 102, 8, 2, 1, 232, 54, 4, 210, 194, 102, 8, 2, 1, 222, + 155, 4, 210, 194, 102, 8, 2, 1, 220, 145, 4, 210, 194, 102, 8, 2, 1, 218, + 171, 4, 210, 194, 102, 8, 2, 1, 215, 64, 4, 210, 194, 102, 8, 2, 1, 210, + 239, 4, 210, 194, 102, 8, 2, 1, 207, 224, 4, 210, 194, 102, 8, 2, 1, 206, + 10, 4, 210, 194, 102, 8, 2, 1, 234, 15, 4, 210, 194, 102, 8, 2, 1, 196, + 13, 4, 210, 194, 102, 8, 2, 1, 192, 236, 4, 210, 194, 102, 8, 2, 1, 191, + 167, 4, 210, 194, 102, 8, 2, 1, 42, 4, 207, 25, 102, 8, 2, 1, 251, 163, + 4, 207, 25, 102, 8, 2, 1, 238, 130, 4, 228, 253, 23, 199, 215, 8, 2, 1, + 235, 17, 4, 207, 25, 102, 8, 2, 1, 211, 79, 235, 17, 4, 207, 25, 102, 8, + 2, 1, 207, 19, 211, 79, 235, 17, 4, 207, 25, 102, 8, 2, 1, 205, 88, 4, + 207, 25, 102, 8, 2, 1, 228, 76, 4, 207, 25, 102, 8, 2, 1, 211, 79, 187, + 4, 207, 25, 102, 8, 2, 1, 234, 15, 4, 207, 25, 102, 8, 2, 1, 126, 4, 207, + 25, 102, 8, 2, 1, 233, 181, 4, 207, 25, 102, 52, 1, 2, 154, 251, 162, 52, + 1, 2, 247, 195, 52, 1, 2, 247, 196, 4, 238, 177, 52, 1, 2, 233, 250, 52, + 1, 2, 207, 19, 211, 79, 71, 52, 1, 2, 233, 177, 52, 1, 2, 236, 141, 223, + 38, 4, 106, 52, 1, 2, 27, 232, 53, 52, 1, 2, 154, 230, 118, 52, 1, 2, + 228, 76, 4, 106, 52, 1, 2, 223, 85, 52, 1, 2, 6, 68, 52, 1, 2, 6, 228, + 76, 4, 106, 52, 1, 2, 223, 38, 4, 238, 214, 52, 1, 2, 220, 145, 4, 207, + 25, 102, 52, 1, 2, 220, 145, 4, 210, 194, 102, 52, 1, 2, 6, 172, 52, 1, + 2, 218, 171, 4, 102, 52, 1, 2, 154, 218, 171, 4, 180, 219, 214, 52, 1, 2, + 215, 64, 4, 45, 102, 52, 1, 2, 215, 64, 4, 207, 25, 102, 52, 1, 2, 6, + 215, 63, 52, 1, 2, 249, 84, 74, 52, 1, 2, 209, 213, 52, 1, 2, 206, 10, 4, + 102, 52, 1, 2, 234, 14, 52, 1, 2, 200, 44, 4, 210, 194, 102, 52, 1, 2, + 126, 164, 52, 1, 2, 196, 70, 52, 1, 2, 6, 66, 52, 1, 2, 196, 13, 4, 102, + 52, 1, 2, 154, 196, 12, 52, 1, 2, 191, 166, 52, 1, 2, 191, 167, 4, 207, + 25, 102, 52, 1, 2, 191, 167, 4, 238, 177, 52, 1, 2, 233, 180, 52, 1, 2, + 199, 15, 33, 235, 140, 230, 213, 252, 62, 33, 235, 140, 252, 49, 252, 62, + 33, 202, 60, 60, 33, 200, 164, 77, 33, 217, 147, 33, 230, 210, 33, 217, + 145, 33, 252, 46, 33, 230, 211, 33, 252, 47, 33, 8, 2, 1, 207, 224, 60, + 33, 248, 37, 33, 217, 146, 33, 55, 243, 4, 58, 33, 211, 141, 58, 33, 191, + 21, 60, 33, 223, 71, 60, 33, 196, 63, 58, 33, 196, 46, 58, 33, 8, 2, 1, + 232, 205, 211, 79, 42, 58, 33, 8, 2, 1, 252, 27, 33, 8, 2, 1, 251, 70, + 33, 8, 2, 1, 250, 148, 33, 8, 2, 1, 247, 196, 247, 37, 33, 8, 2, 1, 223, + 117, 238, 129, 33, 8, 2, 1, 233, 250, 33, 8, 2, 1, 232, 53, 33, 8, 1, 2, + 6, 232, 53, 33, 8, 2, 1, 222, 154, 33, 8, 2, 1, 172, 33, 8, 1, 2, 6, 172, + 33, 8, 1, 2, 6, 218, 170, 33, 8, 2, 1, 215, 63, 33, 8, 1, 2, 6, 215, 63, + 33, 8, 1, 2, 6, 146, 33, 8, 2, 1, 207, 224, 206, 117, 33, 8, 2, 1, 206, + 9, 33, 8, 2, 1, 180, 206, 9, 33, 8, 2, 1, 191, 166, 33, 8, 2, 1, 251, + 162, 33, 8, 2, 1, 250, 122, 33, 8, 2, 1, 248, 214, 33, 8, 2, 1, 205, 87, + 33, 8, 2, 1, 233, 177, 33, 8, 2, 1, 220, 145, 4, 55, 82, 198, 152, 33, 8, + 2, 1, 187, 4, 156, 247, 25, 106, 33, 8, 2, 1, 210, 238, 33, 8, 2, 1, 234, + 14, 33, 8, 2, 1, 126, 4, 156, 247, 25, 106, 33, 8, 2, 1, 193, 224, 33, 8, + 2, 1, 42, 4, 237, 44, 33, 8, 2, 1, 187, 4, 237, 44, 33, 8, 2, 1, 126, 4, + 237, 44, 33, 133, 199, 229, 58, 33, 222, 38, 93, 179, 33, 222, 38, 93, + 219, 226, 33, 75, 93, 219, 226, 33, 193, 78, 223, 95, 248, 31, 60, 33, + 75, 248, 235, 219, 226, 33, 237, 117, 77, 33, 55, 223, 95, 248, 39, 60, + 33, 251, 167, 234, 47, 119, 60, 33, 45, 250, 238, 58, 33, 50, 250, 238, + 23, 144, 250, 238, 60, 8, 6, 1, 42, 4, 206, 190, 60, 8, 2, 1, 42, 4, 206, + 190, 60, 8, 6, 1, 78, 4, 75, 58, 8, 2, 1, 78, 4, 75, 58, 8, 6, 1, 78, 4, + 75, 60, 8, 2, 1, 78, 4, 75, 60, 8, 6, 1, 78, 4, 219, 115, 60, 8, 2, 1, + 78, 4, 219, 115, 60, 8, 6, 1, 247, 196, 4, 247, 38, 23, 252, 48, 8, 2, 1, + 247, 196, 4, 247, 38, 23, 252, 48, 8, 6, 1, 238, 130, 4, 75, 58, 8, 2, 1, + 238, 130, 4, 75, 58, 8, 6, 1, 238, 130, 4, 75, 60, 8, 2, 1, 238, 130, 4, + 75, 60, 8, 6, 1, 238, 130, 4, 219, 115, 60, 8, 2, 1, 238, 130, 4, 219, + 115, 60, 8, 6, 1, 238, 130, 4, 247, 37, 8, 2, 1, 238, 130, 4, 247, 37, 8, + 6, 1, 238, 130, 4, 243, 4, 60, 8, 2, 1, 238, 130, 4, 243, 4, 60, 8, 6, 1, + 235, 17, 4, 217, 149, 23, 230, 212, 8, 2, 1, 235, 17, 4, 217, 149, 23, + 230, 212, 8, 6, 1, 235, 17, 4, 217, 149, 23, 252, 48, 8, 2, 1, 235, 17, + 4, 217, 149, 23, 252, 48, 8, 6, 1, 235, 17, 4, 243, 4, 60, 8, 2, 1, 235, + 17, 4, 243, 4, 60, 8, 6, 1, 235, 17, 4, 198, 153, 60, 8, 2, 1, 235, 17, + 4, 198, 153, 60, 8, 6, 1, 235, 17, 4, 247, 38, 23, 248, 38, 8, 2, 1, 235, + 17, 4, 247, 38, 23, 248, 38, 8, 6, 1, 233, 178, 4, 75, 58, 8, 2, 1, 233, + 178, 4, 75, 58, 8, 6, 1, 232, 54, 4, 217, 148, 8, 2, 1, 232, 54, 4, 217, + 148, 8, 6, 1, 230, 119, 4, 75, 58, 8, 2, 1, 230, 119, 4, 75, 58, 8, 6, 1, + 230, 119, 4, 75, 60, 8, 2, 1, 230, 119, 4, 75, 60, 8, 6, 1, 230, 119, 4, + 237, 44, 8, 2, 1, 230, 119, 4, 237, 44, 8, 6, 1, 230, 119, 4, 247, 37, 8, + 2, 1, 230, 119, 4, 247, 37, 8, 6, 1, 230, 119, 4, 248, 39, 60, 8, 2, 1, + 230, 119, 4, 248, 39, 60, 8, 6, 1, 228, 76, 4, 198, 153, 60, 8, 2, 1, + 228, 76, 4, 198, 153, 60, 8, 6, 1, 228, 76, 4, 237, 45, 23, 252, 48, 8, + 2, 1, 228, 76, 4, 237, 45, 23, 252, 48, 8, 6, 1, 222, 155, 4, 252, 48, 8, + 2, 1, 222, 155, 4, 252, 48, 8, 6, 1, 222, 155, 4, 75, 60, 8, 2, 1, 222, + 155, 4, 75, 60, 8, 6, 1, 222, 155, 4, 219, 115, 60, 8, 2, 1, 222, 155, 4, + 219, 115, 60, 8, 6, 1, 220, 145, 4, 75, 60, 8, 2, 1, 220, 145, 4, 75, 60, + 8, 6, 1, 220, 145, 4, 75, 248, 235, 23, 217, 148, 8, 2, 1, 220, 145, 4, + 75, 248, 235, 23, 217, 148, 8, 6, 1, 220, 145, 4, 219, 115, 60, 8, 2, 1, + 220, 145, 4, 219, 115, 60, 8, 6, 1, 220, 145, 4, 243, 4, 60, 8, 2, 1, + 220, 145, 4, 243, 4, 60, 8, 6, 1, 218, 171, 4, 252, 48, 8, 2, 1, 218, + 171, 4, 252, 48, 8, 6, 1, 218, 171, 4, 75, 58, 8, 2, 1, 218, 171, 4, 75, + 58, 8, 6, 1, 218, 171, 4, 75, 60, 8, 2, 1, 218, 171, 4, 75, 60, 8, 6, 1, + 215, 64, 4, 75, 58, 8, 2, 1, 215, 64, 4, 75, 58, 8, 6, 1, 215, 64, 4, 75, + 60, 8, 2, 1, 215, 64, 4, 75, 60, 8, 6, 1, 215, 64, 4, 219, 115, 60, 8, 2, + 1, 215, 64, 4, 219, 115, 60, 8, 6, 1, 215, 64, 4, 243, 4, 60, 8, 2, 1, + 215, 64, 4, 243, 4, 60, 8, 6, 1, 187, 4, 198, 153, 23, 252, 48, 8, 2, 1, + 187, 4, 198, 153, 23, 252, 48, 8, 6, 1, 187, 4, 198, 153, 23, 237, 44, 8, + 2, 1, 187, 4, 198, 153, 23, 237, 44, 8, 6, 1, 187, 4, 217, 149, 23, 230, + 212, 8, 2, 1, 187, 4, 217, 149, 23, 230, 212, 8, 6, 1, 187, 4, 217, 149, + 23, 252, 48, 8, 2, 1, 187, 4, 217, 149, 23, 252, 48, 8, 6, 1, 210, 239, + 4, 252, 48, 8, 2, 1, 210, 239, 4, 252, 48, 8, 6, 1, 210, 239, 4, 75, 58, + 8, 2, 1, 210, 239, 4, 75, 58, 8, 6, 1, 207, 224, 4, 75, 58, 8, 2, 1, 207, + 224, 4, 75, 58, 8, 6, 1, 207, 224, 4, 75, 60, 8, 2, 1, 207, 224, 4, 75, + 60, 8, 6, 1, 207, 224, 4, 75, 248, 235, 23, 217, 148, 8, 2, 1, 207, 224, + 4, 75, 248, 235, 23, 217, 148, 8, 6, 1, 207, 224, 4, 219, 115, 60, 8, 2, + 1, 207, 224, 4, 219, 115, 60, 8, 6, 1, 206, 10, 4, 75, 58, 8, 2, 1, 206, + 10, 4, 75, 58, 8, 6, 1, 206, 10, 4, 75, 60, 8, 2, 1, 206, 10, 4, 75, 60, + 8, 6, 1, 206, 10, 4, 252, 49, 23, 75, 58, 8, 2, 1, 206, 10, 4, 252, 49, + 23, 75, 58, 8, 6, 1, 206, 10, 4, 247, 95, 23, 75, 58, 8, 2, 1, 206, 10, + 4, 247, 95, 23, 75, 58, 8, 6, 1, 206, 10, 4, 75, 248, 235, 23, 75, 58, 8, + 2, 1, 206, 10, 4, 75, 248, 235, 23, 75, 58, 8, 6, 1, 200, 44, 4, 75, 58, + 8, 2, 1, 200, 44, 4, 75, 58, 8, 6, 1, 200, 44, 4, 75, 60, 8, 2, 1, 200, + 44, 4, 75, 60, 8, 6, 1, 200, 44, 4, 219, 115, 60, 8, 2, 1, 200, 44, 4, + 219, 115, 60, 8, 6, 1, 200, 44, 4, 243, 4, 60, 8, 2, 1, 200, 44, 4, 243, + 4, 60, 8, 6, 1, 126, 4, 237, 45, 60, 8, 2, 1, 126, 4, 237, 45, 60, 8, 6, + 1, 126, 4, 198, 153, 60, 8, 2, 1, 126, 4, 198, 153, 60, 8, 6, 1, 126, 4, + 243, 4, 60, 8, 2, 1, 126, 4, 243, 4, 60, 8, 6, 1, 126, 4, 198, 153, 23, + 252, 48, 8, 2, 1, 126, 4, 198, 153, 23, 252, 48, 8, 6, 1, 126, 4, 217, + 149, 23, 237, 44, 8, 2, 1, 126, 4, 217, 149, 23, 237, 44, 8, 6, 1, 196, + 13, 4, 198, 152, 8, 2, 1, 196, 13, 4, 198, 152, 8, 6, 1, 196, 13, 4, 75, + 60, 8, 2, 1, 196, 13, 4, 75, 60, 8, 6, 1, 193, 225, 4, 230, 212, 8, 2, 1, + 193, 225, 4, 230, 212, 8, 6, 1, 193, 225, 4, 252, 48, 8, 2, 1, 193, 225, + 4, 252, 48, 8, 6, 1, 193, 225, 4, 237, 44, 8, 2, 1, 193, 225, 4, 237, 44, + 8, 6, 1, 193, 225, 4, 75, 58, 8, 2, 1, 193, 225, 4, 75, 58, 8, 6, 1, 193, + 225, 4, 75, 60, 8, 2, 1, 193, 225, 4, 75, 60, 8, 6, 1, 192, 236, 4, 75, + 58, 8, 2, 1, 192, 236, 4, 75, 58, 8, 6, 1, 192, 236, 4, 237, 44, 8, 2, 1, + 192, 236, 4, 237, 44, 8, 6, 1, 192, 160, 4, 75, 58, 8, 2, 1, 192, 160, 4, + 75, 58, 8, 6, 1, 191, 167, 4, 243, 3, 8, 2, 1, 191, 167, 4, 243, 3, 8, 6, + 1, 191, 167, 4, 75, 60, 8, 2, 1, 191, 167, 4, 75, 60, 8, 6, 1, 191, 167, + 4, 219, 115, 60, 8, 2, 1, 191, 167, 4, 219, 115, 60, 8, 2, 1, 230, 119, + 4, 219, 115, 60, 8, 2, 1, 200, 44, 4, 237, 44, 8, 2, 1, 193, 225, 4, 206, + 190, 58, 8, 2, 1, 192, 160, 4, 206, 190, 58, 8, 2, 1, 42, 4, 50, 132, + 206, 189, 8, 2, 1, 180, 206, 10, 4, 75, 58, 8, 2, 1, 180, 206, 10, 4, + 237, 41, 106, 8, 2, 1, 180, 206, 10, 4, 137, 106, 8, 6, 1, 203, 128, 206, + 9, 8, 2, 1, 237, 108, 8, 6, 1, 42, 4, 75, 60, 8, 2, 1, 42, 4, 75, 60, 8, + 6, 1, 42, 4, 228, 253, 58, 8, 2, 1, 42, 4, 228, 253, 58, 8, 6, 1, 42, 4, + 243, 4, 23, 252, 48, 8, 2, 1, 42, 4, 243, 4, 23, 252, 48, 8, 6, 1, 42, 4, + 243, 4, 23, 230, 212, 8, 2, 1, 42, 4, 243, 4, 23, 230, 212, 8, 6, 1, 42, + 4, 243, 4, 23, 228, 253, 58, 8, 2, 1, 42, 4, 243, 4, 23, 228, 253, 58, 8, + 6, 1, 42, 4, 243, 4, 23, 198, 152, 8, 2, 1, 42, 4, 243, 4, 23, 198, 152, + 8, 6, 1, 42, 4, 243, 4, 23, 75, 60, 8, 2, 1, 42, 4, 243, 4, 23, 75, 60, + 8, 6, 1, 42, 4, 248, 39, 23, 252, 48, 8, 2, 1, 42, 4, 248, 39, 23, 252, + 48, 8, 6, 1, 42, 4, 248, 39, 23, 230, 212, 8, 2, 1, 42, 4, 248, 39, 23, + 230, 212, 8, 6, 1, 42, 4, 248, 39, 23, 228, 253, 58, 8, 2, 1, 42, 4, 248, + 39, 23, 228, 253, 58, 8, 6, 1, 42, 4, 248, 39, 23, 198, 152, 8, 2, 1, 42, + 4, 248, 39, 23, 198, 152, 8, 6, 1, 42, 4, 248, 39, 23, 75, 60, 8, 2, 1, + 42, 4, 248, 39, 23, 75, 60, 8, 6, 1, 235, 17, 4, 75, 60, 8, 2, 1, 235, + 17, 4, 75, 60, 8, 6, 1, 235, 17, 4, 228, 253, 58, 8, 2, 1, 235, 17, 4, + 228, 253, 58, 8, 6, 1, 235, 17, 4, 198, 152, 8, 2, 1, 235, 17, 4, 198, + 152, 8, 6, 1, 235, 17, 4, 243, 4, 23, 252, 48, 8, 2, 1, 235, 17, 4, 243, + 4, 23, 252, 48, 8, 6, 1, 235, 17, 4, 243, 4, 23, 230, 212, 8, 2, 1, 235, + 17, 4, 243, 4, 23, 230, 212, 8, 6, 1, 235, 17, 4, 243, 4, 23, 228, 253, + 58, 8, 2, 1, 235, 17, 4, 243, 4, 23, 228, 253, 58, 8, 6, 1, 235, 17, 4, + 243, 4, 23, 198, 152, 8, 2, 1, 235, 17, 4, 243, 4, 23, 198, 152, 8, 6, 1, + 235, 17, 4, 243, 4, 23, 75, 60, 8, 2, 1, 235, 17, 4, 243, 4, 23, 75, 60, + 8, 6, 1, 228, 76, 4, 228, 253, 58, 8, 2, 1, 228, 76, 4, 228, 253, 58, 8, + 6, 1, 228, 76, 4, 75, 60, 8, 2, 1, 228, 76, 4, 75, 60, 8, 6, 1, 187, 4, + 75, 60, 8, 2, 1, 187, 4, 75, 60, 8, 6, 1, 187, 4, 228, 253, 58, 8, 2, 1, + 187, 4, 228, 253, 58, 8, 6, 1, 187, 4, 243, 4, 23, 252, 48, 8, 2, 1, 187, + 4, 243, 4, 23, 252, 48, 8, 6, 1, 187, 4, 243, 4, 23, 230, 212, 8, 2, 1, + 187, 4, 243, 4, 23, 230, 212, 8, 6, 1, 187, 4, 243, 4, 23, 228, 253, 58, + 8, 2, 1, 187, 4, 243, 4, 23, 228, 253, 58, 8, 6, 1, 187, 4, 243, 4, 23, + 198, 152, 8, 2, 1, 187, 4, 243, 4, 23, 198, 152, 8, 6, 1, 187, 4, 243, 4, + 23, 75, 60, 8, 2, 1, 187, 4, 243, 4, 23, 75, 60, 8, 6, 1, 187, 4, 228, + 190, 23, 252, 48, 8, 2, 1, 187, 4, 228, 190, 23, 252, 48, 8, 6, 1, 187, + 4, 228, 190, 23, 230, 212, 8, 2, 1, 187, 4, 228, 190, 23, 230, 212, 8, 6, + 1, 187, 4, 228, 190, 23, 228, 253, 58, 8, 2, 1, 187, 4, 228, 190, 23, + 228, 253, 58, 8, 6, 1, 187, 4, 228, 190, 23, 198, 152, 8, 2, 1, 187, 4, + 228, 190, 23, 198, 152, 8, 6, 1, 187, 4, 228, 190, 23, 75, 60, 8, 2, 1, + 187, 4, 228, 190, 23, 75, 60, 8, 6, 1, 126, 4, 75, 60, 8, 2, 1, 126, 4, + 75, 60, 8, 6, 1, 126, 4, 228, 253, 58, 8, 2, 1, 126, 4, 228, 253, 58, 8, + 6, 1, 126, 4, 228, 190, 23, 252, 48, 8, 2, 1, 126, 4, 228, 190, 23, 252, + 48, 8, 6, 1, 126, 4, 228, 190, 23, 230, 212, 8, 2, 1, 126, 4, 228, 190, + 23, 230, 212, 8, 6, 1, 126, 4, 228, 190, 23, 228, 253, 58, 8, 2, 1, 126, + 4, 228, 190, 23, 228, 253, 58, 8, 6, 1, 126, 4, 228, 190, 23, 198, 152, + 8, 2, 1, 126, 4, 228, 190, 23, 198, 152, 8, 6, 1, 126, 4, 228, 190, 23, + 75, 60, 8, 2, 1, 126, 4, 228, 190, 23, 75, 60, 8, 6, 1, 192, 160, 4, 230, + 212, 8, 2, 1, 192, 160, 4, 230, 212, 8, 6, 1, 192, 160, 4, 75, 60, 8, 2, + 1, 192, 160, 4, 75, 60, 8, 6, 1, 192, 160, 4, 228, 253, 58, 8, 2, 1, 192, + 160, 4, 228, 253, 58, 8, 6, 1, 192, 160, 4, 198, 152, 8, 2, 1, 192, 160, + 4, 198, 152, 8, 6, 1, 216, 85, 219, 76, 8, 2, 1, 216, 85, 219, 76, 8, 6, + 1, 216, 85, 196, 12, 8, 2, 1, 216, 85, 196, 12, 8, 6, 1, 192, 160, 4, + 219, 6, 8, 2, 1, 192, 160, 4, 219, 6, 35, 2, 1, 251, 163, 4, 208, 171, + 35, 2, 1, 251, 163, 4, 237, 214, 35, 2, 1, 251, 163, 4, 208, 172, 23, + 195, 169, 35, 2, 1, 251, 163, 4, 237, 215, 23, 195, 169, 35, 2, 1, 251, + 163, 4, 208, 172, 23, 210, 245, 35, 2, 1, 251, 163, 4, 237, 215, 23, 210, + 245, 35, 2, 1, 251, 163, 4, 208, 172, 23, 210, 6, 35, 2, 1, 251, 163, 4, + 237, 215, 23, 210, 6, 35, 6, 1, 251, 163, 4, 208, 171, 35, 6, 1, 251, + 163, 4, 237, 214, 35, 6, 1, 251, 163, 4, 208, 172, 23, 195, 169, 35, 6, + 1, 251, 163, 4, 237, 215, 23, 195, 169, 35, 6, 1, 251, 163, 4, 208, 172, + 23, 210, 245, 35, 6, 1, 251, 163, 4, 237, 215, 23, 210, 245, 35, 6, 1, + 251, 163, 4, 208, 172, 23, 210, 6, 35, 6, 1, 251, 163, 4, 237, 215, 23, + 210, 6, 35, 2, 1, 234, 50, 4, 208, 171, 35, 2, 1, 234, 50, 4, 237, 214, + 35, 2, 1, 234, 50, 4, 208, 172, 23, 195, 169, 35, 2, 1, 234, 50, 4, 237, + 215, 23, 195, 169, 35, 2, 1, 234, 50, 4, 208, 172, 23, 210, 245, 35, 2, + 1, 234, 50, 4, 237, 215, 23, 210, 245, 35, 6, 1, 234, 50, 4, 208, 171, + 35, 6, 1, 234, 50, 4, 237, 214, 35, 6, 1, 234, 50, 4, 208, 172, 23, 195, + 169, 35, 6, 1, 234, 50, 4, 237, 215, 23, 195, 169, 35, 6, 1, 234, 50, 4, + 208, 172, 23, 210, 245, 35, 6, 1, 234, 50, 4, 237, 215, 23, 210, 245, 35, + 2, 1, 234, 0, 4, 208, 171, 35, 2, 1, 234, 0, 4, 237, 214, 35, 2, 1, 234, + 0, 4, 208, 172, 23, 195, 169, 35, 2, 1, 234, 0, 4, 237, 215, 23, 195, + 169, 35, 2, 1, 234, 0, 4, 208, 172, 23, 210, 245, 35, 2, 1, 234, 0, 4, + 237, 215, 23, 210, 245, 35, 2, 1, 234, 0, 4, 208, 172, 23, 210, 6, 35, 2, + 1, 234, 0, 4, 237, 215, 23, 210, 6, 35, 6, 1, 234, 0, 4, 208, 171, 35, 6, + 1, 234, 0, 4, 237, 214, 35, 6, 1, 234, 0, 4, 208, 172, 23, 195, 169, 35, + 6, 1, 234, 0, 4, 237, 215, 23, 195, 169, 35, 6, 1, 234, 0, 4, 208, 172, + 23, 210, 245, 35, 6, 1, 234, 0, 4, 237, 215, 23, 210, 245, 35, 6, 1, 234, + 0, 4, 208, 172, 23, 210, 6, 35, 6, 1, 234, 0, 4, 237, 215, 23, 210, 6, + 35, 2, 1, 223, 86, 4, 208, 171, 35, 2, 1, 223, 86, 4, 237, 214, 35, 2, 1, + 223, 86, 4, 208, 172, 23, 195, 169, 35, 2, 1, 223, 86, 4, 237, 215, 23, + 195, 169, 35, 2, 1, 223, 86, 4, 208, 172, 23, 210, 245, 35, 2, 1, 223, + 86, 4, 237, 215, 23, 210, 245, 35, 2, 1, 223, 86, 4, 208, 172, 23, 210, + 6, 35, 2, 1, 223, 86, 4, 237, 215, 23, 210, 6, 35, 6, 1, 223, 86, 4, 208, + 171, 35, 6, 1, 223, 86, 4, 237, 214, 35, 6, 1, 223, 86, 4, 208, 172, 23, + 195, 169, 35, 6, 1, 223, 86, 4, 237, 215, 23, 195, 169, 35, 6, 1, 223, + 86, 4, 208, 172, 23, 210, 245, 35, 6, 1, 223, 86, 4, 237, 215, 23, 210, + 245, 35, 6, 1, 223, 86, 4, 208, 172, 23, 210, 6, 35, 6, 1, 223, 86, 4, + 237, 215, 23, 210, 6, 35, 2, 1, 211, 110, 4, 208, 171, 35, 2, 1, 211, + 110, 4, 237, 214, 35, 2, 1, 211, 110, 4, 208, 172, 23, 195, 169, 35, 2, + 1, 211, 110, 4, 237, 215, 23, 195, 169, 35, 2, 1, 211, 110, 4, 208, 172, + 23, 210, 245, 35, 2, 1, 211, 110, 4, 237, 215, 23, 210, 245, 35, 6, 1, + 211, 110, 4, 208, 171, 35, 6, 1, 211, 110, 4, 237, 214, 35, 6, 1, 211, + 110, 4, 208, 172, 23, 195, 169, 35, 6, 1, 211, 110, 4, 237, 215, 23, 195, + 169, 35, 6, 1, 211, 110, 4, 208, 172, 23, 210, 245, 35, 6, 1, 211, 110, + 4, 237, 215, 23, 210, 245, 35, 2, 1, 196, 71, 4, 208, 171, 35, 2, 1, 196, + 71, 4, 237, 214, 35, 2, 1, 196, 71, 4, 208, 172, 23, 195, 169, 35, 2, 1, + 196, 71, 4, 237, 215, 23, 195, 169, 35, 2, 1, 196, 71, 4, 208, 172, 23, + 210, 245, 35, 2, 1, 196, 71, 4, 237, 215, 23, 210, 245, 35, 2, 1, 196, + 71, 4, 208, 172, 23, 210, 6, 35, 2, 1, 196, 71, 4, 237, 215, 23, 210, 6, + 35, 6, 1, 196, 71, 4, 237, 214, 35, 6, 1, 196, 71, 4, 237, 215, 23, 195, + 169, 35, 6, 1, 196, 71, 4, 237, 215, 23, 210, 245, 35, 6, 1, 196, 71, 4, + 237, 215, 23, 210, 6, 35, 2, 1, 211, 113, 4, 208, 171, 35, 2, 1, 211, + 113, 4, 237, 214, 35, 2, 1, 211, 113, 4, 208, 172, 23, 195, 169, 35, 2, + 1, 211, 113, 4, 237, 215, 23, 195, 169, 35, 2, 1, 211, 113, 4, 208, 172, + 23, 210, 245, 35, 2, 1, 211, 113, 4, 237, 215, 23, 210, 245, 35, 2, 1, + 211, 113, 4, 208, 172, 23, 210, 6, 35, 2, 1, 211, 113, 4, 237, 215, 23, + 210, 6, 35, 6, 1, 211, 113, 4, 208, 171, 35, 6, 1, 211, 113, 4, 237, 214, + 35, 6, 1, 211, 113, 4, 208, 172, 23, 195, 169, 35, 6, 1, 211, 113, 4, + 237, 215, 23, 195, 169, 35, 6, 1, 211, 113, 4, 208, 172, 23, 210, 245, + 35, 6, 1, 211, 113, 4, 237, 215, 23, 210, 245, 35, 6, 1, 211, 113, 4, + 208, 172, 23, 210, 6, 35, 6, 1, 211, 113, 4, 237, 215, 23, 210, 6, 35, 2, + 1, 251, 163, 4, 195, 169, 35, 2, 1, 251, 163, 4, 210, 245, 35, 2, 1, 234, + 50, 4, 195, 169, 35, 2, 1, 234, 50, 4, 210, 245, 35, 2, 1, 234, 0, 4, + 195, 169, 35, 2, 1, 234, 0, 4, 210, 245, 35, 2, 1, 223, 86, 4, 195, 169, + 35, 2, 1, 223, 86, 4, 210, 245, 35, 2, 1, 211, 110, 4, 195, 169, 35, 2, + 1, 211, 110, 4, 210, 245, 35, 2, 1, 196, 71, 4, 195, 169, 35, 2, 1, 196, + 71, 4, 210, 245, 35, 2, 1, 211, 113, 4, 195, 169, 35, 2, 1, 211, 113, 4, + 210, 245, 35, 2, 1, 251, 163, 4, 208, 172, 23, 191, 233, 35, 2, 1, 251, + 163, 4, 237, 215, 23, 191, 233, 35, 2, 1, 251, 163, 4, 208, 172, 23, 195, + 170, 23, 191, 233, 35, 2, 1, 251, 163, 4, 237, 215, 23, 195, 170, 23, + 191, 233, 35, 2, 1, 251, 163, 4, 208, 172, 23, 210, 246, 23, 191, 233, + 35, 2, 1, 251, 163, 4, 237, 215, 23, 210, 246, 23, 191, 233, 35, 2, 1, + 251, 163, 4, 208, 172, 23, 210, 7, 23, 191, 233, 35, 2, 1, 251, 163, 4, + 237, 215, 23, 210, 7, 23, 191, 233, 35, 6, 1, 251, 163, 4, 208, 172, 23, + 208, 186, 35, 6, 1, 251, 163, 4, 237, 215, 23, 208, 186, 35, 6, 1, 251, + 163, 4, 208, 172, 23, 195, 170, 23, 208, 186, 35, 6, 1, 251, 163, 4, 237, + 215, 23, 195, 170, 23, 208, 186, 35, 6, 1, 251, 163, 4, 208, 172, 23, + 210, 246, 23, 208, 186, 35, 6, 1, 251, 163, 4, 237, 215, 23, 210, 246, + 23, 208, 186, 35, 6, 1, 251, 163, 4, 208, 172, 23, 210, 7, 23, 208, 186, + 35, 6, 1, 251, 163, 4, 237, 215, 23, 210, 7, 23, 208, 186, 35, 2, 1, 234, + 0, 4, 208, 172, 23, 191, 233, 35, 2, 1, 234, 0, 4, 237, 215, 23, 191, + 233, 35, 2, 1, 234, 0, 4, 208, 172, 23, 195, 170, 23, 191, 233, 35, 2, 1, + 234, 0, 4, 237, 215, 23, 195, 170, 23, 191, 233, 35, 2, 1, 234, 0, 4, + 208, 172, 23, 210, 246, 23, 191, 233, 35, 2, 1, 234, 0, 4, 237, 215, 23, + 210, 246, 23, 191, 233, 35, 2, 1, 234, 0, 4, 208, 172, 23, 210, 7, 23, + 191, 233, 35, 2, 1, 234, 0, 4, 237, 215, 23, 210, 7, 23, 191, 233, 35, 6, + 1, 234, 0, 4, 208, 172, 23, 208, 186, 35, 6, 1, 234, 0, 4, 237, 215, 23, + 208, 186, 35, 6, 1, 234, 0, 4, 208, 172, 23, 195, 170, 23, 208, 186, 35, + 6, 1, 234, 0, 4, 237, 215, 23, 195, 170, 23, 208, 186, 35, 6, 1, 234, 0, + 4, 208, 172, 23, 210, 246, 23, 208, 186, 35, 6, 1, 234, 0, 4, 237, 215, + 23, 210, 246, 23, 208, 186, 35, 6, 1, 234, 0, 4, 208, 172, 23, 210, 7, + 23, 208, 186, 35, 6, 1, 234, 0, 4, 237, 215, 23, 210, 7, 23, 208, 186, + 35, 2, 1, 211, 113, 4, 208, 172, 23, 191, 233, 35, 2, 1, 211, 113, 4, + 237, 215, 23, 191, 233, 35, 2, 1, 211, 113, 4, 208, 172, 23, 195, 170, + 23, 191, 233, 35, 2, 1, 211, 113, 4, 237, 215, 23, 195, 170, 23, 191, + 233, 35, 2, 1, 211, 113, 4, 208, 172, 23, 210, 246, 23, 191, 233, 35, 2, + 1, 211, 113, 4, 237, 215, 23, 210, 246, 23, 191, 233, 35, 2, 1, 211, 113, + 4, 208, 172, 23, 210, 7, 23, 191, 233, 35, 2, 1, 211, 113, 4, 237, 215, + 23, 210, 7, 23, 191, 233, 35, 6, 1, 211, 113, 4, 208, 172, 23, 208, 186, + 35, 6, 1, 211, 113, 4, 237, 215, 23, 208, 186, 35, 6, 1, 211, 113, 4, + 208, 172, 23, 195, 170, 23, 208, 186, 35, 6, 1, 211, 113, 4, 237, 215, + 23, 195, 170, 23, 208, 186, 35, 6, 1, 211, 113, 4, 208, 172, 23, 210, + 246, 23, 208, 186, 35, 6, 1, 211, 113, 4, 237, 215, 23, 210, 246, 23, + 208, 186, 35, 6, 1, 211, 113, 4, 208, 172, 23, 210, 7, 23, 208, 186, 35, + 6, 1, 211, 113, 4, 237, 215, 23, 210, 7, 23, 208, 186, 35, 2, 1, 251, + 163, 4, 194, 254, 35, 2, 1, 251, 163, 4, 217, 148, 35, 2, 1, 251, 163, 4, + 195, 170, 23, 191, 233, 35, 2, 1, 251, 163, 4, 191, 233, 35, 2, 1, 251, + 163, 4, 210, 246, 23, 191, 233, 35, 2, 1, 251, 163, 4, 210, 6, 35, 2, 1, + 251, 163, 4, 210, 7, 23, 191, 233, 35, 6, 1, 251, 163, 4, 194, 254, 35, + 6, 1, 251, 163, 4, 217, 148, 35, 6, 1, 251, 163, 4, 195, 169, 35, 6, 1, + 251, 163, 4, 210, 245, 35, 6, 1, 251, 163, 4, 208, 186, 35, 221, 32, 35, + 208, 186, 35, 208, 171, 35, 210, 6, 35, 237, 38, 23, 210, 6, 35, 2, 1, + 234, 0, 4, 195, 170, 23, 191, 233, 35, 2, 1, 234, 0, 4, 191, 233, 35, 2, + 1, 234, 0, 4, 210, 246, 23, 191, 233, 35, 2, 1, 234, 0, 4, 210, 6, 35, 2, + 1, 234, 0, 4, 210, 7, 23, 191, 233, 35, 6, 1, 234, 50, 4, 195, 169, 35, + 6, 1, 234, 50, 4, 210, 245, 35, 6, 1, 234, 0, 4, 195, 169, 35, 6, 1, 234, + 0, 4, 210, 245, 35, 6, 1, 234, 0, 4, 208, 186, 35, 208, 172, 23, 195, + 169, 35, 208, 172, 23, 210, 245, 35, 208, 172, 23, 210, 6, 35, 2, 1, 223, + 86, 4, 194, 254, 35, 2, 1, 223, 86, 4, 217, 148, 35, 2, 1, 223, 86, 4, + 237, 38, 23, 195, 169, 35, 2, 1, 223, 86, 4, 237, 38, 23, 210, 245, 35, + 2, 1, 223, 86, 4, 210, 6, 35, 2, 1, 223, 86, 4, 237, 38, 23, 210, 6, 35, + 6, 1, 223, 86, 4, 194, 254, 35, 6, 1, 223, 86, 4, 217, 148, 35, 6, 1, + 223, 86, 4, 195, 169, 35, 6, 1, 223, 86, 4, 210, 245, 35, 237, 215, 23, + 195, 169, 35, 237, 215, 23, 210, 245, 35, 237, 215, 23, 210, 6, 35, 2, 1, + 196, 71, 4, 194, 254, 35, 2, 1, 196, 71, 4, 217, 148, 35, 2, 1, 196, 71, + 4, 237, 38, 23, 195, 169, 35, 2, 1, 196, 71, 4, 237, 38, 23, 210, 245, + 35, 2, 1, 207, 5, 4, 208, 171, 35, 2, 1, 207, 5, 4, 237, 214, 35, 2, 1, + 196, 71, 4, 210, 6, 35, 2, 1, 196, 71, 4, 237, 38, 23, 210, 6, 35, 6, 1, + 196, 71, 4, 194, 254, 35, 6, 1, 196, 71, 4, 217, 148, 35, 6, 1, 196, 71, + 4, 195, 169, 35, 6, 1, 196, 71, 4, 210, 245, 35, 6, 1, 207, 5, 4, 237, + 214, 35, 237, 38, 23, 195, 169, 35, 237, 38, 23, 210, 245, 35, 195, 169, + 35, 2, 1, 211, 113, 4, 195, 170, 23, 191, 233, 35, 2, 1, 211, 113, 4, + 191, 233, 35, 2, 1, 211, 113, 4, 210, 246, 23, 191, 233, 35, 2, 1, 211, + 113, 4, 210, 6, 35, 2, 1, 211, 113, 4, 210, 7, 23, 191, 233, 35, 6, 1, + 211, 110, 4, 195, 169, 35, 6, 1, 211, 110, 4, 210, 245, 35, 6, 1, 211, + 113, 4, 195, 169, 35, 6, 1, 211, 113, 4, 210, 245, 35, 6, 1, 211, 113, 4, + 208, 186, 35, 210, 245, 35, 237, 214, 234, 106, 208, 32, 234, 117, 208, + 32, 234, 106, 201, 248, 234, 117, 201, 248, 198, 219, 201, 248, 232, 128, + 201, 248, 202, 135, 201, 248, 233, 15, 201, 248, 208, 154, 201, 248, 199, + 4, 201, 248, 230, 81, 201, 248, 191, 78, 193, 75, 201, 248, 191, 78, 193, + 75, 213, 31, 191, 78, 193, 75, 222, 198, 219, 217, 77, 206, 200, 77, 228, + 90, 213, 32, 228, 90, 233, 15, 237, 217, 234, 106, 237, 217, 234, 117, + 237, 217, 228, 243, 164, 55, 81, 219, 114, 55, 130, 219, 114, 45, 202, + 171, 207, 254, 77, 50, 202, 171, 207, 254, 77, 202, 171, 218, 242, 207, + 254, 77, 202, 171, 229, 134, 207, 254, 77, 45, 55, 207, 254, 77, 50, 55, + 207, 254, 77, 55, 218, 242, 207, 254, 77, 55, 229, 134, 207, 254, 77, + 238, 16, 55, 238, 16, 247, 250, 197, 238, 247, 250, 91, 75, 219, 238, + 105, 75, 219, 238, 228, 243, 234, 122, 228, 88, 209, 63, 219, 115, 204, + 11, 210, 130, 204, 11, 219, 217, 234, 115, 206, 200, 234, 115, 209, 36, + 236, 234, 232, 146, 219, 217, 210, 254, 206, 200, 210, 254, 214, 217, + 213, 39, 201, 248, 210, 16, 216, 52, 56, 210, 16, 199, 96, 198, 230, 56, + 208, 217, 55, 208, 217, 197, 225, 208, 217, 207, 19, 208, 217, 207, 19, + 55, 208, 217, 207, 19, 197, 225, 208, 217, 247, 98, 202, 171, 219, 221, + 251, 118, 207, 254, 77, 202, 171, 206, 204, 251, 118, 207, 254, 77, 207, + 85, 77, 55, 233, 218, 77, 223, 104, 211, 0, 196, 100, 246, 242, 198, 178, + 247, 99, 223, 121, 209, 63, 250, 193, 228, 91, 247, 250, 232, 120, 202, + 98, 45, 51, 248, 56, 4, 208, 9, 50, 51, 248, 56, 4, 208, 9, 55, 208, 15, + 77, 208, 15, 233, 218, 77, 233, 218, 208, 15, 77, 198, 128, 3, 234, 1, + 207, 19, 209, 144, 56, 62, 118, 247, 250, 62, 96, 247, 250, 130, 250, + 195, 207, 19, 204, 26, 242, 222, 196, 77, 105, 250, 194, 251, 180, 195, + 84, 242, 74, 216, 37, 56, 200, 129, 237, 217, 223, 95, 196, 100, 232, + 189, 208, 154, 77, 115, 75, 208, 153, 208, 28, 208, 217, 232, 130, 75, + 208, 153, 232, 228, 75, 208, 153, 105, 75, 208, 153, 232, 130, 75, 77, + 235, 140, 238, 219, 197, 237, 81, 232, 130, 236, 140, 216, 215, 13, 201, + 248, 193, 23, 222, 198, 232, 79, 251, 46, 223, 93, 198, 144, 223, 93, + 204, 11, 223, 93, 209, 83, 219, 217, 223, 61, 206, 200, 223, 61, 232, + 240, 201, 15, 223, 61, 209, 36, 236, 234, 223, 61, 223, 134, 200, 75, + 200, 147, 252, 51, 200, 75, 200, 147, 223, 134, 9, 232, 148, 203, 134, + 252, 51, 9, 232, 148, 203, 134, 214, 210, 17, 203, 135, 213, 35, 17, 203, + 135, 200, 182, 191, 77, 200, 182, 8, 2, 1, 68, 200, 182, 134, 200, 182, + 150, 200, 182, 169, 200, 182, 175, 200, 182, 171, 200, 182, 178, 200, + 182, 108, 56, 200, 182, 216, 36, 200, 182, 234, 45, 56, 200, 182, 45, + 210, 115, 200, 182, 50, 210, 115, 200, 182, 8, 2, 1, 215, 63, 200, 231, + 191, 77, 200, 231, 107, 200, 231, 109, 200, 231, 138, 200, 231, 134, 200, + 231, 150, 200, 231, 169, 200, 231, 175, 200, 231, 171, 200, 231, 178, + 200, 231, 108, 56, 200, 231, 216, 36, 200, 231, 234, 45, 56, 200, 231, + 45, 210, 115, 200, 231, 50, 210, 115, 8, 200, 231, 2, 1, 65, 8, 200, 231, + 2, 1, 71, 8, 200, 231, 2, 1, 74, 8, 200, 231, 2, 1, 192, 235, 8, 200, + 231, 2, 1, 205, 87, 8, 200, 231, 2, 1, 230, 118, 8, 200, 231, 2, 1, 222, + 154, 8, 200, 231, 2, 1, 172, 8, 200, 231, 2, 1, 218, 170, 8, 200, 231, 2, + 1, 215, 63, 8, 200, 231, 2, 1, 210, 238, 8, 200, 231, 2, 1, 206, 9, 8, + 200, 231, 2, 1, 200, 43, 233, 235, 56, 242, 86, 56, 238, 202, 56, 232, + 108, 232, 113, 56, 219, 93, 56, 216, 53, 56, 214, 236, 56, 209, 247, 56, + 206, 37, 56, 193, 31, 56, 214, 82, 203, 100, 56, 236, 151, 56, 233, 236, + 56, 221, 137, 56, 197, 81, 56, 235, 118, 56, 231, 140, 210, 29, 56, 209, + 244, 56, 230, 176, 56, 250, 155, 56, 228, 168, 56, 247, 39, 56, 219, 83, + 198, 33, 56, 201, 227, 56, 199, 93, 56, 223, 149, 206, 37, 56, 197, 60, + 219, 93, 56, 213, 21, 87, 56, 217, 90, 56, 206, 60, 56, 220, 11, 56, 248, + 149, 56, 202, 23, 56, 33, 45, 230, 15, 58, 33, 50, 230, 15, 58, 33, 180, + 81, 219, 115, 211, 1, 33, 203, 41, 81, 219, 115, 211, 1, 33, 251, 87, 64, + 58, 33, 242, 223, 64, 58, 33, 45, 64, 58, 33, 50, 64, 58, 33, 206, 190, + 211, 1, 33, 242, 223, 206, 190, 211, 1, 33, 251, 87, 206, 190, 211, 1, + 33, 115, 185, 58, 33, 232, 130, 185, 58, 33, 234, 101, 243, 12, 33, 234, + 101, 201, 191, 33, 234, 101, 237, 34, 33, 234, 101, 243, 13, 249, 143, + 33, 45, 50, 64, 58, 33, 234, 101, 205, 77, 33, 234, 101, 221, 220, 33, + 234, 101, 196, 68, 209, 60, 197, 241, 33, 207, 20, 202, 25, 211, 1, 33, + 55, 81, 201, 29, 211, 1, 33, 251, 97, 113, 33, 197, 225, 196, 102, 33, + 193, 78, 248, 31, 58, 33, 118, 64, 211, 1, 33, 180, 55, 202, 25, 211, 1, + 33, 96, 230, 15, 4, 182, 235, 120, 33, 118, 230, 15, 4, 182, 235, 120, + 33, 45, 64, 60, 33, 50, 64, 60, 33, 250, 196, 58, 252, 57, 211, 148, 252, + 40, 119, 199, 34, 200, 241, 235, 131, 6, 247, 195, 237, 127, 247, 29, + 247, 24, 219, 115, 113, 247, 100, 211, 148, 247, 154, 196, 112, 233, 237, + 239, 40, 205, 73, 237, 127, 233, 93, 27, 2, 232, 53, 27, 6, 230, 118, + 248, 139, 6, 230, 118, 235, 131, 6, 230, 118, 209, 105, 239, 40, 209, + 105, 239, 41, 139, 105, 209, 187, 27, 6, 68, 248, 139, 6, 68, 27, 6, 172, + 27, 2, 172, 220, 145, 78, 249, 90, 113, 235, 131, 6, 215, 63, 212, 134, + 56, 202, 6, 207, 97, 239, 7, 27, 6, 210, 238, 235, 131, 6, 210, 238, 235, + 131, 6, 208, 106, 27, 6, 146, 248, 139, 6, 146, 235, 131, 6, 146, 208, + 225, 199, 208, 207, 32, 204, 2, 77, 199, 107, 56, 198, 22, 87, 56, 195, + 136, 235, 131, 6, 191, 166, 211, 20, 56, 211, 137, 56, 223, 95, 211, 137, + 56, 248, 139, 6, 191, 166, 154, 35, 2, 1, 223, 85, 222, 5, 56, 251, 112, + 56, 27, 6, 250, 122, 248, 139, 6, 247, 195, 234, 6, 113, 27, 2, 71, 27, + 6, 71, 27, 6, 233, 177, 154, 6, 233, 177, 27, 6, 218, 170, 27, 2, 74, + 131, 113, 248, 217, 113, 231, 41, 113, 238, 0, 113, 223, 139, 202, 4, + 206, 123, 6, 208, 106, 233, 96, 56, 235, 131, 2, 209, 187, 235, 131, 2, + 231, 213, 235, 131, 6, 231, 213, 235, 131, 6, 209, 187, 235, 131, 215, + 62, 200, 201, 154, 49, 6, 232, 53, 154, 49, 6, 172, 207, 19, 49, 6, 172, + 154, 49, 6, 192, 159, 235, 131, 43, 6, 238, 129, 235, 131, 43, 2, 238, + 129, 235, 131, 43, 2, 71, 235, 131, 43, 2, 68, 235, 131, 43, 2, 223, 37, + 208, 190, 219, 114, 154, 251, 139, 210, 16, 56, 251, 212, 154, 2, 233, + 177, 16, 40, 205, 152, 202, 4, 193, 246, 232, 120, 91, 203, 244, 193, + 246, 232, 120, 91, 213, 169, 193, 246, 232, 120, 91, 199, 86, 193, 246, + 232, 120, 91, 199, 0, 193, 246, 232, 120, 105, 198, 253, 193, 246, 232, + 120, 91, 233, 20, 193, 246, 232, 120, 105, 233, 19, 193, 246, 232, 120, + 115, 233, 19, 193, 246, 232, 120, 232, 130, 233, 19, 193, 246, 232, 120, + 91, 202, 125, 193, 246, 232, 120, 232, 228, 202, 123, 193, 246, 232, 120, + 91, 234, 161, 193, 246, 232, 120, 115, 234, 159, 193, 246, 232, 120, 232, + 228, 234, 159, 193, 246, 232, 120, 203, 248, 234, 159, 232, 120, 212, + 135, 107, 206, 137, 212, 136, 107, 206, 137, 212, 136, 109, 206, 137, + 212, 136, 138, 206, 137, 212, 136, 134, 206, 137, 212, 136, 150, 206, + 137, 212, 136, 169, 206, 137, 212, 136, 175, 206, 137, 212, 136, 171, + 206, 137, 212, 136, 178, 206, 137, 212, 136, 199, 95, 206, 137, 212, 136, + 234, 129, 206, 137, 212, 136, 197, 37, 206, 137, 212, 136, 233, 17, 206, + 137, 212, 136, 91, 228, 142, 206, 137, 212, 136, 232, 228, 228, 142, 206, + 137, 212, 136, 91, 189, 2, 206, 137, 212, 136, 107, 2, 206, 137, 212, + 136, 109, 2, 206, 137, 212, 136, 138, 2, 206, 137, 212, 136, 134, 2, 206, + 137, 212, 136, 150, 2, 206, 137, 212, 136, 169, 2, 206, 137, 212, 136, + 175, 2, 206, 137, 212, 136, 171, 2, 206, 137, 212, 136, 178, 2, 206, 137, + 212, 136, 199, 95, 2, 206, 137, 212, 136, 234, 129, 2, 206, 137, 212, + 136, 197, 37, 2, 206, 137, 212, 136, 233, 17, 2, 206, 137, 212, 136, 91, + 228, 142, 2, 206, 137, 212, 136, 232, 228, 228, 142, 2, 206, 137, 212, + 136, 91, 189, 206, 137, 212, 136, 91, 198, 230, 247, 196, 238, 129, 206, + 137, 212, 136, 232, 228, 189, 206, 137, 212, 136, 199, 96, 189, 206, 137, + 212, 136, 207, 19, 91, 228, 142, 8, 2, 1, 207, 19, 247, 195, 206, 137, + 212, 136, 202, 137, 220, 6, 20, 206, 137, 212, 136, 233, 18, 234, 212, + 20, 206, 137, 212, 136, 233, 18, 189, 206, 137, 212, 136, 91, 228, 143, + 189, 193, 246, 232, 120, 191, 78, 198, 253, 154, 17, 109, 154, 17, 138, + 118, 57, 196, 66, 57, 96, 57, 235, 121, 57, 45, 50, 57, 133, 144, 57, + 186, 193, 105, 57, 186, 234, 206, 57, 202, 3, 234, 206, 57, 202, 3, 193, 105, 57, 118, 64, 4, 106, 96, 64, 4, 106, 118, 193, 139, 57, 96, 193, - 139, 57, 118, 105, 229, 233, 57, 196, 66, 105, 229, 233, 57, 96, 105, - 229, 233, 57, 235, 119, 105, 229, 233, 57, 118, 64, 4, 199, 215, 96, 64, - 4, 199, 215, 118, 64, 232, 98, 164, 196, 66, 64, 232, 98, 164, 96, 64, - 232, 98, 164, 235, 119, 64, 232, 98, 164, 133, 144, 64, 4, 249, 74, 118, - 64, 4, 102, 96, 64, 4, 102, 118, 64, 4, 219, 4, 96, 64, 4, 219, 4, 45, - 50, 193, 139, 57, 45, 50, 64, 4, 106, 235, 119, 191, 21, 57, 196, 66, 64, - 4, 198, 136, 219, 214, 196, 66, 64, 4, 198, 136, 206, 197, 235, 119, 64, - 4, 198, 136, 219, 214, 235, 119, 64, 4, 198, 136, 206, 197, 96, 64, 4, - 239, 2, 235, 118, 235, 119, 64, 4, 239, 2, 219, 214, 251, 85, 198, 54, - 204, 28, 57, 242, 221, 198, 54, 204, 28, 57, 186, 193, 105, 64, 119, 179, - 164, 118, 64, 119, 249, 88, 139, 96, 64, 119, 164, 251, 85, 211, 77, 243, - 11, 57, 242, 221, 211, 77, 243, 11, 57, 118, 230, 13, 4, 181, 196, 65, - 118, 230, 13, 4, 181, 235, 118, 196, 66, 230, 13, 4, 181, 206, 197, 196, - 66, 230, 13, 4, 181, 219, 214, 96, 230, 13, 4, 181, 196, 65, 96, 230, 13, - 4, 181, 235, 118, 235, 119, 230, 13, 4, 181, 206, 197, 235, 119, 230, 13, - 4, 181, 219, 214, 96, 64, 139, 118, 57, 196, 66, 64, 118, 79, 235, 119, - 57, 118, 64, 139, 96, 57, 118, 210, 196, 250, 231, 196, 66, 210, 196, - 250, 231, 96, 210, 196, 250, 231, 235, 119, 210, 196, 250, 231, 118, 230, - 13, 139, 96, 230, 12, 96, 230, 13, 139, 118, 230, 12, 118, 55, 64, 4, + 139, 57, 118, 105, 229, 235, 57, 196, 66, 105, 229, 235, 57, 96, 105, + 229, 235, 57, 235, 121, 105, 229, 235, 57, 118, 64, 4, 199, 215, 96, 64, + 4, 199, 215, 118, 64, 232, 100, 164, 196, 66, 64, 232, 100, 164, 96, 64, + 232, 100, 164, 235, 121, 64, 232, 100, 164, 133, 144, 64, 4, 249, 76, + 118, 64, 4, 102, 96, 64, 4, 102, 118, 64, 4, 219, 6, 96, 64, 4, 219, 6, + 45, 50, 193, 139, 57, 45, 50, 64, 4, 106, 235, 121, 191, 21, 57, 196, 66, + 64, 4, 198, 136, 219, 216, 196, 66, 64, 4, 198, 136, 206, 198, 235, 121, + 64, 4, 198, 136, 219, 216, 235, 121, 64, 4, 198, 136, 206, 198, 96, 64, + 4, 239, 4, 235, 120, 235, 121, 64, 4, 239, 4, 219, 216, 251, 87, 198, 54, + 204, 29, 57, 242, 223, 198, 54, 204, 29, 57, 186, 193, 105, 64, 119, 180, + 164, 118, 64, 119, 249, 90, 139, 96, 64, 119, 164, 251, 87, 211, 79, 243, + 13, 57, 242, 223, 211, 79, 243, 13, 57, 118, 230, 15, 4, 182, 196, 65, + 118, 230, 15, 4, 182, 235, 120, 196, 66, 230, 15, 4, 182, 206, 198, 196, + 66, 230, 15, 4, 182, 219, 216, 96, 230, 15, 4, 182, 196, 65, 96, 230, 15, + 4, 182, 235, 120, 235, 121, 230, 15, 4, 182, 206, 198, 235, 121, 230, 15, + 4, 182, 219, 216, 96, 64, 139, 118, 57, 196, 66, 64, 118, 79, 235, 121, + 57, 118, 64, 139, 96, 57, 118, 210, 198, 250, 233, 196, 66, 210, 198, + 250, 233, 96, 210, 198, 250, 233, 235, 121, 210, 198, 250, 233, 118, 230, + 15, 139, 96, 230, 14, 96, 230, 15, 139, 118, 230, 14, 118, 55, 64, 4, 106, 45, 50, 55, 64, 4, 106, 96, 55, 64, 4, 106, 118, 55, 57, 196, 66, - 55, 57, 96, 55, 57, 235, 119, 55, 57, 45, 50, 55, 57, 133, 144, 55, 57, - 186, 193, 105, 55, 57, 186, 234, 204, 55, 57, 202, 2, 234, 204, 55, 57, - 202, 2, 193, 105, 55, 57, 118, 197, 225, 57, 96, 197, 225, 57, 118, 201, - 183, 57, 96, 201, 183, 57, 196, 66, 64, 4, 55, 106, 235, 119, 64, 4, 55, - 106, 118, 237, 214, 57, 196, 66, 237, 214, 57, 96, 237, 214, 57, 235, - 119, 237, 214, 57, 118, 64, 119, 164, 96, 64, 119, 164, 118, 63, 57, 196, - 66, 63, 57, 96, 63, 57, 235, 119, 63, 57, 196, 66, 63, 64, 232, 98, 164, - 196, 66, 63, 64, 211, 105, 210, 52, 196, 66, 63, 64, 211, 105, 210, 53, - 4, 228, 241, 164, 196, 66, 63, 64, 211, 105, 210, 53, 4, 81, 164, 196, - 66, 63, 55, 57, 196, 66, 63, 55, 64, 211, 105, 210, 52, 96, 63, 64, 232, - 98, 193, 167, 186, 193, 105, 64, 119, 239, 1, 202, 2, 234, 204, 64, 119, - 239, 1, 133, 144, 63, 57, 50, 64, 4, 2, 243, 10, 235, 119, 64, 118, 79, - 196, 66, 57, 115, 96, 250, 231, 118, 64, 4, 81, 106, 96, 64, 4, 81, 106, + 55, 57, 96, 55, 57, 235, 121, 55, 57, 45, 50, 55, 57, 133, 144, 55, 57, + 186, 193, 105, 55, 57, 186, 234, 206, 55, 57, 202, 3, 234, 206, 55, 57, + 202, 3, 193, 105, 55, 57, 118, 197, 225, 57, 96, 197, 225, 57, 118, 201, + 184, 57, 96, 201, 184, 57, 196, 66, 64, 4, 55, 106, 235, 121, 64, 4, 55, + 106, 118, 237, 216, 57, 196, 66, 237, 216, 57, 96, 237, 216, 57, 235, + 121, 237, 216, 57, 118, 64, 119, 164, 96, 64, 119, 164, 118, 63, 57, 196, + 66, 63, 57, 96, 63, 57, 235, 121, 63, 57, 196, 66, 63, 64, 232, 100, 164, + 196, 66, 63, 64, 211, 107, 210, 54, 196, 66, 63, 64, 211, 107, 210, 55, + 4, 228, 243, 164, 196, 66, 63, 64, 211, 107, 210, 55, 4, 81, 164, 196, + 66, 63, 55, 57, 196, 66, 63, 55, 64, 211, 107, 210, 54, 96, 63, 64, 232, + 100, 193, 167, 186, 193, 105, 64, 119, 239, 3, 202, 3, 234, 206, 64, 119, + 239, 3, 133, 144, 63, 57, 50, 64, 4, 2, 243, 12, 235, 121, 64, 118, 79, + 196, 66, 57, 115, 96, 250, 233, 118, 64, 4, 81, 106, 96, 64, 4, 81, 106, 45, 50, 64, 4, 81, 106, 118, 64, 4, 55, 81, 106, 96, 64, 4, 55, 81, 106, - 45, 50, 64, 4, 55, 81, 106, 118, 211, 74, 57, 96, 211, 74, 57, 45, 50, - 211, 74, 57, 40, 251, 174, 242, 68, 210, 105, 237, 16, 199, 24, 233, 211, - 199, 24, 236, 164, 213, 12, 233, 212, 234, 105, 203, 252, 223, 151, 214, - 245, 234, 132, 211, 146, 213, 12, 251, 133, 234, 132, 211, 146, 2, 234, - 132, 211, 146, 239, 32, 250, 220, 216, 190, 236, 164, 213, 12, 239, 34, - 250, 220, 216, 190, 2, 239, 32, 250, 220, 216, 190, 234, 95, 79, 208, - 190, 215, 60, 208, 200, 215, 60, 239, 9, 215, 60, 200, 201, 216, 35, 56, - 216, 33, 56, 75, 209, 81, 236, 200, 202, 97, 203, 253, 216, 34, 250, 194, - 211, 66, 206, 189, 211, 66, 247, 249, 211, 66, 51, 206, 128, 238, 191, - 206, 128, 232, 121, 206, 128, 208, 186, 159, 223, 139, 50, 251, 115, 251, - 115, 216, 226, 251, 115, 201, 225, 251, 115, 236, 203, 236, 164, 213, 12, - 236, 207, 210, 119, 159, 213, 12, 210, 119, 159, 219, 29, 251, 125, 219, - 29, 211, 56, 223, 99, 196, 92, 223, 113, 55, 223, 113, 197, 225, 223, - 113, 239, 26, 223, 113, 200, 171, 223, 113, 195, 11, 223, 113, 242, 221, - 223, 113, 242, 221, 239, 26, 223, 113, 251, 85, 239, 26, 223, 113, 199, - 23, 249, 3, 207, 126, 208, 187, 75, 216, 34, 233, 219, 231, 144, 208, - 187, 229, 0, 198, 153, 211, 66, 207, 18, 198, 152, 223, 93, 219, 245, - 206, 8, 202, 172, 193, 138, 193, 10, 208, 200, 213, 12, 198, 152, 216, - 35, 198, 152, 250, 186, 234, 45, 159, 213, 12, 250, 186, 234, 45, 159, - 251, 40, 234, 45, 159, 251, 40, 247, 218, 213, 12, 252, 48, 234, 45, 159, - 214, 105, 251, 40, 213, 21, 252, 48, 234, 45, 159, 251, 165, 234, 45, - 159, 213, 12, 251, 165, 234, 45, 159, 251, 165, 234, 45, 211, 57, 234, - 45, 159, 197, 225, 198, 152, 251, 175, 234, 45, 159, 234, 36, 159, 231, - 143, 234, 36, 159, 237, 17, 248, 209, 251, 42, 199, 34, 219, 120, 231, - 143, 234, 45, 159, 251, 40, 234, 45, 119, 211, 57, 199, 34, 223, 178, - 211, 146, 223, 178, 79, 211, 57, 251, 40, 234, 45, 159, 242, 84, 234, 42, - 234, 43, 242, 83, 206, 189, 223, 163, 234, 45, 159, 206, 189, 234, 45, - 159, 238, 250, 159, 234, 3, 234, 41, 159, 201, 103, 234, 42, 237, 107, - 234, 45, 159, 234, 45, 119, 247, 205, 237, 126, 216, 226, 247, 204, 208, - 11, 234, 45, 159, 213, 12, 234, 45, 159, 228, 17, 159, 213, 12, 228, 17, - 159, 201, 35, 234, 36, 159, 219, 180, 211, 57, 234, 45, 159, 230, 204, - 211, 57, 234, 45, 159, 219, 180, 139, 234, 45, 159, 230, 204, 139, 234, - 45, 159, 219, 180, 247, 218, 213, 12, 234, 45, 159, 230, 204, 247, 218, - 213, 12, 234, 45, 159, 215, 145, 219, 179, 215, 145, 230, 203, 248, 209, - 213, 12, 234, 36, 159, 213, 12, 219, 179, 213, 12, 230, 203, 214, 105, - 219, 180, 213, 21, 234, 45, 159, 214, 105, 230, 204, 213, 21, 234, 45, - 159, 219, 180, 211, 57, 234, 36, 159, 230, 204, 211, 57, 234, 36, 159, - 214, 105, 219, 180, 213, 21, 234, 36, 159, 214, 105, 230, 204, 213, 21, - 234, 36, 159, 219, 180, 211, 57, 230, 203, 230, 204, 211, 57, 219, 179, - 214, 105, 219, 180, 213, 21, 230, 203, 214, 105, 230, 204, 213, 21, 219, - 179, 208, 231, 200, 220, 208, 232, 211, 57, 234, 45, 159, 200, 221, 211, - 57, 234, 45, 159, 208, 232, 211, 57, 234, 36, 159, 200, 221, 211, 57, - 234, 36, 159, 236, 164, 213, 12, 208, 234, 236, 164, 213, 12, 200, 222, - 200, 229, 211, 146, 200, 181, 211, 146, 213, 12, 42, 200, 229, 211, 146, - 213, 12, 42, 200, 181, 211, 146, 200, 229, 79, 211, 57, 234, 45, 159, - 200, 181, 79, 211, 57, 234, 45, 159, 214, 105, 42, 200, 229, 79, 213, 21, - 234, 45, 159, 214, 105, 42, 200, 181, 79, 213, 21, 234, 45, 159, 200, - 229, 79, 4, 213, 12, 234, 45, 159, 200, 181, 79, 4, 213, 12, 234, 45, - 159, 215, 124, 215, 125, 215, 126, 215, 125, 196, 92, 51, 223, 178, 211, - 146, 51, 211, 46, 211, 146, 51, 223, 178, 79, 211, 57, 234, 45, 159, 51, - 211, 46, 79, 211, 57, 234, 45, 159, 51, 247, 111, 51, 238, 181, 47, 209, - 81, 47, 216, 34, 47, 198, 144, 47, 236, 200, 202, 97, 47, 75, 211, 66, - 47, 206, 189, 211, 66, 47, 250, 194, 211, 66, 47, 234, 42, 47, 237, 215, - 112, 209, 81, 112, 216, 34, 112, 198, 144, 112, 75, 211, 66, 50, 199, - 228, 45, 199, 228, 144, 199, 228, 133, 199, 228, 250, 197, 216, 1, 197, - 201, 232, 152, 197, 225, 81, 249, 88, 50, 197, 57, 55, 81, 249, 88, 55, - 50, 197, 57, 236, 164, 213, 12, 208, 179, 213, 12, 197, 201, 236, 164, - 213, 12, 232, 153, 214, 108, 55, 81, 249, 88, 55, 50, 197, 57, 208, 232, - 196, 105, 207, 65, 200, 221, 196, 105, 207, 65, 213, 18, 200, 244, 211, - 146, 239, 32, 250, 220, 213, 18, 200, 243, 213, 18, 200, 244, 79, 211, - 57, 234, 45, 159, 239, 32, 250, 220, 213, 18, 200, 244, 211, 57, 234, 45, - 159, 211, 46, 211, 146, 223, 178, 211, 146, 215, 131, 229, 189, 239, 43, - 217, 27, 223, 110, 192, 192, 214, 224, 213, 20, 50, 251, 116, 4, 251, 16, - 50, 197, 241, 215, 60, 219, 29, 251, 125, 215, 60, 219, 29, 211, 56, 215, - 60, 223, 99, 215, 60, 196, 92, 237, 33, 211, 66, 75, 211, 66, 201, 103, - 211, 66, 236, 200, 198, 144, 248, 63, 45, 213, 18, 233, 93, 204, 24, 208, - 200, 50, 213, 18, 233, 93, 204, 24, 208, 200, 45, 204, 24, 208, 200, 50, - 204, 24, 208, 200, 207, 18, 198, 153, 234, 42, 238, 171, 219, 29, 211, - 56, 238, 171, 219, 29, 251, 125, 55, 200, 228, 55, 200, 180, 55, 223, 99, - 55, 196, 92, 209, 115, 234, 45, 23, 210, 119, 159, 219, 180, 4, 236, 140, - 230, 204, 4, 236, 140, 195, 83, 215, 145, 219, 179, 195, 83, 215, 145, - 230, 203, 219, 180, 234, 45, 119, 211, 57, 230, 203, 230, 204, 234, 45, - 119, 211, 57, 219, 179, 234, 45, 119, 211, 57, 219, 179, 234, 45, 119, - 211, 57, 230, 203, 234, 45, 119, 211, 57, 208, 231, 234, 45, 119, 211, - 57, 200, 220, 236, 164, 213, 12, 208, 235, 211, 57, 234, 44, 236, 164, - 213, 12, 200, 223, 211, 57, 234, 44, 213, 12, 51, 223, 178, 79, 211, 57, - 234, 45, 159, 213, 12, 51, 211, 46, 79, 211, 57, 234, 45, 159, 51, 223, - 178, 79, 211, 57, 213, 12, 234, 45, 159, 51, 211, 46, 79, 211, 57, 213, - 12, 234, 45, 159, 219, 180, 247, 218, 213, 12, 234, 36, 159, 230, 204, - 247, 218, 213, 12, 234, 36, 159, 208, 232, 247, 218, 213, 12, 234, 36, - 159, 200, 221, 247, 218, 213, 12, 234, 36, 159, 213, 12, 213, 18, 200, - 244, 211, 146, 236, 164, 213, 12, 239, 34, 250, 220, 213, 18, 200, 243, - 213, 12, 213, 18, 200, 244, 79, 211, 57, 234, 45, 159, 236, 164, 213, 12, - 239, 34, 250, 220, 213, 18, 200, 244, 211, 57, 234, 44, 81, 234, 120, - 216, 82, 228, 241, 234, 120, 133, 50, 237, 39, 234, 120, 144, 50, 237, - 39, 234, 120, 234, 132, 79, 4, 179, 228, 241, 106, 234, 132, 79, 4, 81, - 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 2, 234, 132, 79, 4, 81, - 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 234, 132, 79, 4, 75, 58, - 234, 132, 79, 4, 211, 6, 2, 234, 132, 79, 4, 211, 6, 234, 132, 79, 4, - 196, 103, 234, 132, 79, 4, 105, 228, 241, 201, 15, 239, 32, 4, 179, 228, - 241, 106, 239, 32, 4, 81, 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, - 2, 239, 32, 4, 81, 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 239, - 32, 4, 211, 6, 2, 239, 32, 4, 211, 6, 191, 167, 213, 10, 249, 131, 216, - 189, 237, 34, 56, 234, 135, 57, 228, 172, 133, 250, 235, 144, 250, 235, - 208, 194, 209, 248, 193, 135, 219, 112, 45, 247, 30, 50, 247, 30, 45, - 232, 193, 50, 232, 193, 248, 77, 50, 238, 219, 248, 77, 45, 238, 219, - 198, 54, 50, 238, 219, 198, 54, 45, 238, 219, 207, 18, 213, 12, 56, 51, - 218, 232, 251, 16, 205, 43, 205, 52, 199, 107, 207, 96, 209, 25, 223, - 144, 195, 56, 201, 190, 209, 108, 79, 223, 109, 56, 153, 213, 12, 56, - 193, 145, 228, 174, 198, 54, 45, 239, 1, 198, 54, 50, 239, 1, 248, 77, - 45, 239, 1, 248, 77, 50, 239, 1, 198, 54, 132, 223, 113, 248, 77, 132, - 223, 113, 232, 93, 202, 65, 133, 250, 236, 248, 210, 105, 228, 241, 249, - 76, 211, 59, 221, 222, 234, 32, 119, 199, 34, 183, 192, 236, 223, 163, - 42, 207, 93, 248, 62, 221, 220, 219, 219, 251, 116, 248, 53, 206, 203, - 251, 116, 248, 53, 234, 32, 119, 199, 34, 219, 224, 248, 221, 206, 188, - 238, 138, 251, 175, 250, 244, 200, 74, 198, 39, 206, 41, 236, 252, 211, - 47, 239, 48, 199, 181, 202, 81, 238, 246, 238, 245, 251, 59, 232, 75, 16, - 228, 67, 251, 59, 232, 75, 16, 201, 181, 208, 30, 251, 59, 232, 75, 16, - 208, 31, 234, 44, 251, 59, 232, 75, 16, 208, 31, 236, 207, 251, 59, 232, - 75, 16, 208, 31, 237, 32, 251, 59, 232, 75, 16, 208, 31, 222, 188, 251, - 59, 232, 75, 16, 208, 31, 243, 10, 251, 59, 232, 75, 16, 243, 11, 201, - 71, 251, 59, 232, 75, 16, 243, 11, 222, 188, 251, 59, 232, 75, 16, 202, - 98, 164, 251, 59, 232, 75, 16, 249, 142, 164, 251, 59, 232, 75, 16, 208, - 31, 202, 97, 251, 59, 232, 75, 16, 208, 31, 249, 141, 251, 59, 232, 75, - 16, 208, 31, 219, 179, 251, 59, 232, 75, 16, 208, 31, 230, 203, 251, 59, - 232, 75, 16, 118, 195, 176, 251, 59, 232, 75, 16, 96, 195, 176, 251, 59, - 232, 75, 16, 208, 31, 118, 57, 251, 59, 232, 75, 16, 208, 31, 96, 57, - 251, 59, 232, 75, 16, 243, 11, 249, 141, 251, 59, 232, 75, 16, 144, 199, - 229, 196, 103, 251, 59, 232, 75, 16, 237, 107, 201, 71, 251, 59, 232, 75, - 16, 208, 31, 144, 247, 96, 251, 59, 232, 75, 16, 208, 31, 237, 106, 251, - 59, 232, 75, 16, 144, 199, 229, 222, 188, 251, 59, 232, 75, 16, 196, 66, - 195, 176, 251, 59, 232, 75, 16, 208, 31, 196, 66, 57, 251, 59, 232, 75, - 16, 133, 199, 229, 211, 6, 251, 59, 232, 75, 16, 237, 119, 201, 71, 251, - 59, 232, 75, 16, 208, 31, 133, 247, 96, 251, 59, 232, 75, 16, 208, 31, - 237, 118, 251, 59, 232, 75, 16, 133, 199, 229, 222, 188, 251, 59, 232, - 75, 16, 235, 119, 195, 176, 251, 59, 232, 75, 16, 208, 31, 235, 119, 57, - 251, 59, 232, 75, 16, 207, 251, 196, 103, 251, 59, 232, 75, 16, 237, 107, - 196, 103, 251, 59, 232, 75, 16, 237, 33, 196, 103, 251, 59, 232, 75, 16, - 222, 189, 196, 103, 251, 59, 232, 75, 16, 243, 11, 196, 103, 251, 59, - 232, 75, 16, 133, 203, 53, 222, 188, 251, 59, 232, 75, 16, 207, 251, 208, - 30, 251, 59, 232, 75, 16, 243, 11, 201, 102, 251, 59, 232, 75, 16, 208, - 31, 242, 83, 251, 59, 232, 75, 16, 133, 199, 229, 237, 42, 251, 59, 232, - 75, 16, 237, 119, 237, 42, 251, 59, 232, 75, 16, 201, 103, 237, 42, 251, - 59, 232, 75, 16, 222, 189, 237, 42, 251, 59, 232, 75, 16, 243, 11, 237, - 42, 251, 59, 232, 75, 16, 144, 203, 53, 201, 71, 251, 59, 232, 75, 16, - 45, 203, 53, 201, 71, 251, 59, 232, 75, 16, 198, 153, 237, 42, 251, 59, - 232, 75, 16, 230, 204, 237, 42, 251, 59, 232, 75, 16, 242, 75, 164, 251, - 59, 232, 75, 16, 237, 119, 198, 152, 251, 59, 232, 75, 16, 191, 20, 251, - 59, 232, 75, 16, 201, 72, 198, 152, 251, 59, 232, 75, 16, 204, 26, 196, - 103, 251, 59, 232, 75, 16, 208, 31, 213, 12, 234, 44, 251, 59, 232, 75, - 16, 208, 31, 208, 12, 251, 59, 232, 75, 16, 144, 247, 97, 198, 152, 251, - 59, 232, 75, 16, 133, 247, 97, 198, 152, 251, 59, 232, 75, 16, 223, 83, - 251, 59, 232, 75, 16, 207, 3, 251, 59, 232, 75, 16, 211, 110, 251, 59, - 232, 75, 16, 251, 161, 196, 103, 251, 59, 232, 75, 16, 234, 48, 196, 103, - 251, 59, 232, 75, 16, 223, 84, 196, 103, 251, 59, 232, 75, 16, 211, 111, - 196, 103, 251, 59, 232, 75, 16, 251, 160, 213, 12, 243, 126, 77, 50, 251, - 116, 4, 235, 119, 191, 21, 57, 203, 21, 211, 77, 248, 62, 248, 236, 113, - 81, 219, 113, 4, 82, 236, 140, 223, 119, 113, 239, 27, 196, 101, 113, - 236, 225, 196, 101, 113, 234, 107, 113, 239, 63, 113, 63, 51, 4, 247, 22, - 81, 219, 112, 234, 78, 113, 251, 152, 221, 223, 113, 229, 202, 113, 47, - 228, 241, 249, 88, 4, 213, 9, 47, 197, 242, 235, 123, 248, 22, 243, 11, - 4, 213, 15, 57, 196, 99, 113, 215, 216, 113, 228, 84, 113, 211, 75, 230, - 115, 113, 211, 75, 220, 141, 113, 210, 93, 113, 210, 92, 113, 236, 234, - 238, 169, 16, 232, 146, 109, 202, 29, 113, 251, 59, 232, 75, 16, 208, 30, - 237, 138, 204, 11, 221, 223, 113, 208, 217, 210, 204, 214, 73, 210, 204, - 208, 212, 205, 77, 113, 242, 238, 205, 77, 113, 45, 210, 114, 116, 102, - 45, 210, 114, 233, 203, 45, 210, 114, 110, 102, 50, 210, 114, 116, 102, - 50, 210, 114, 233, 203, 50, 210, 114, 110, 102, 45, 51, 248, 54, 116, - 239, 1, 45, 51, 248, 54, 233, 203, 45, 51, 248, 54, 110, 239, 1, 50, 51, - 248, 54, 116, 239, 1, 50, 51, 248, 54, 233, 203, 50, 51, 248, 54, 110, - 239, 1, 45, 238, 171, 248, 54, 116, 102, 45, 238, 171, 248, 54, 82, 209, - 175, 45, 238, 171, 248, 54, 110, 102, 238, 171, 248, 54, 233, 203, 50, - 238, 171, 248, 54, 116, 102, 50, 238, 171, 248, 54, 82, 209, 175, 50, - 238, 171, 248, 54, 110, 102, 223, 114, 233, 203, 228, 241, 219, 113, 233, - 203, 116, 45, 211, 57, 110, 50, 238, 171, 248, 54, 205, 53, 116, 50, 211, - 57, 110, 45, 238, 171, 248, 54, 205, 53, 200, 202, 198, 53, 200, 202, - 248, 76, 198, 54, 51, 248, 53, 248, 77, 51, 248, 53, 248, 77, 51, 248, - 54, 139, 198, 54, 51, 248, 53, 48, 16, 248, 76, 45, 81, 111, 219, 112, - 50, 81, 111, 219, 112, 228, 241, 205, 97, 219, 111, 228, 241, 205, 97, - 219, 110, 228, 241, 205, 97, 219, 109, 228, 241, 205, 97, 219, 108, 237, - 97, 16, 156, 81, 23, 198, 54, 183, 237, 97, 16, 156, 81, 23, 248, 77, - 183, 237, 97, 16, 156, 81, 4, 243, 10, 237, 97, 16, 156, 144, 23, 228, - 241, 4, 243, 10, 237, 97, 16, 156, 133, 23, 228, 241, 4, 243, 10, 237, - 97, 16, 156, 81, 4, 197, 241, 237, 97, 16, 156, 144, 23, 228, 241, 4, - 197, 241, 237, 97, 16, 156, 133, 23, 228, 241, 4, 197, 241, 237, 97, 16, - 156, 81, 23, 193, 138, 237, 97, 16, 156, 144, 23, 228, 241, 4, 193, 138, - 237, 97, 16, 156, 133, 23, 228, 241, 4, 193, 138, 237, 97, 16, 156, 144, - 23, 228, 240, 237, 97, 16, 156, 133, 23, 228, 240, 237, 97, 16, 156, 81, - 23, 198, 54, 219, 224, 237, 97, 16, 156, 81, 23, 248, 77, 219, 224, 51, - 232, 159, 207, 23, 113, 234, 149, 113, 81, 219, 113, 233, 203, 216, 159, - 248, 36, 216, 159, 179, 139, 203, 39, 216, 159, 203, 40, 139, 219, 19, - 216, 159, 179, 139, 105, 203, 25, 216, 159, 105, 203, 26, 139, 219, 19, - 216, 159, 105, 203, 26, 222, 197, 216, 159, 197, 221, 216, 159, 199, 65, - 216, 159, 210, 22, 234, 208, 230, 188, 232, 69, 198, 54, 210, 113, 248, - 77, 210, 113, 198, 54, 238, 171, 248, 53, 248, 77, 238, 171, 248, 53, - 198, 54, 198, 42, 203, 103, 248, 53, 248, 77, 198, 42, 203, 103, 248, 53, - 63, 198, 5, 248, 221, 206, 189, 4, 243, 10, 201, 51, 232, 204, 252, 64, - 238, 168, 234, 134, 223, 99, 237, 138, 233, 207, 113, 62, 206, 203, 55, - 197, 241, 62, 219, 219, 55, 197, 241, 62, 196, 76, 55, 197, 241, 62, 235, - 122, 55, 197, 241, 62, 206, 203, 55, 197, 242, 4, 81, 164, 62, 219, 219, - 55, 197, 242, 4, 81, 164, 62, 206, 203, 197, 242, 4, 55, 81, 164, 251, - 201, 242, 222, 201, 58, 198, 145, 242, 222, 228, 175, 4, 232, 184, 205, - 140, 62, 216, 213, 219, 219, 197, 241, 62, 216, 213, 206, 203, 197, 241, - 62, 216, 213, 196, 76, 197, 241, 62, 216, 213, 235, 122, 197, 241, 55, - 81, 164, 62, 51, 40, 201, 63, 62, 243, 11, 40, 207, 97, 208, 255, 113, - 208, 255, 211, 103, 113, 208, 255, 211, 105, 113, 208, 255, 202, 93, 113, - 211, 168, 233, 194, 113, 16, 40, 212, 138, 16, 40, 201, 98, 79, 229, 232, - 16, 40, 201, 98, 79, 199, 53, 16, 40, 234, 95, 79, 199, 53, 16, 40, 234, - 95, 79, 198, 11, 16, 40, 234, 81, 16, 40, 252, 51, 16, 40, 248, 235, 16, - 40, 249, 140, 16, 40, 228, 241, 199, 230, 16, 40, 219, 113, 233, 50, 16, - 40, 81, 199, 230, 16, 40, 232, 146, 233, 50, 16, 40, 247, 88, 207, 22, - 16, 40, 203, 77, 211, 14, 16, 40, 203, 77, 223, 162, 16, 40, 237, 210, - 219, 103, 234, 14, 16, 40, 237, 75, 239, 22, 107, 16, 40, 237, 75, 239, - 22, 109, 16, 40, 237, 75, 239, 22, 138, 16, 40, 237, 75, 239, 22, 134, - 16, 40, 214, 106, 252, 51, 16, 40, 200, 69, 223, 228, 16, 40, 234, 95, - 79, 198, 12, 248, 129, 16, 40, 247, 126, 16, 40, 234, 95, 79, 216, 212, - 16, 40, 200, 226, 16, 40, 234, 14, 16, 40, 233, 7, 204, 10, 16, 40, 230, - 187, 204, 10, 16, 40, 207, 98, 204, 10, 16, 40, 196, 91, 204, 10, 16, 40, - 201, 247, 16, 40, 237, 116, 248, 133, 113, 211, 77, 248, 62, 16, 40, 214, - 76, 16, 40, 237, 117, 232, 146, 109, 16, 40, 200, 227, 232, 146, 109, - 211, 161, 102, 211, 161, 246, 252, 211, 161, 232, 149, 211, 161, 223, 93, - 232, 149, 211, 161, 248, 232, 248, 5, 211, 161, 248, 70, 198, 178, 211, - 161, 248, 48, 249, 93, 228, 15, 211, 161, 251, 139, 79, 243, 125, 211, - 161, 237, 215, 211, 161, 238, 157, 252, 55, 212, 136, 211, 161, 55, 249, - 141, 47, 17, 107, 47, 17, 109, 47, 17, 138, 47, 17, 134, 47, 17, 149, 47, + 45, 50, 64, 4, 55, 81, 106, 118, 211, 76, 57, 96, 211, 76, 57, 45, 50, + 211, 76, 57, 40, 251, 176, 242, 70, 210, 107, 237, 18, 199, 24, 233, 213, + 199, 24, 236, 166, 213, 14, 233, 214, 234, 107, 203, 253, 223, 153, 214, + 247, 234, 134, 211, 148, 213, 14, 251, 135, 234, 134, 211, 148, 2, 234, + 134, 211, 148, 239, 34, 250, 222, 216, 192, 236, 166, 213, 14, 239, 36, + 250, 222, 216, 192, 2, 239, 34, 250, 222, 216, 192, 234, 97, 79, 208, + 192, 215, 62, 208, 202, 215, 62, 239, 11, 215, 62, 200, 201, 216, 37, 56, + 216, 35, 56, 75, 209, 83, 236, 202, 202, 98, 203, 254, 216, 36, 250, 196, + 211, 68, 206, 190, 211, 68, 247, 251, 211, 68, 51, 206, 129, 238, 193, + 206, 129, 232, 123, 206, 129, 208, 188, 159, 223, 141, 50, 251, 117, 251, + 117, 216, 228, 251, 117, 201, 226, 251, 117, 236, 205, 236, 166, 213, 14, + 236, 209, 210, 121, 159, 213, 14, 210, 121, 159, 219, 31, 251, 127, 219, + 31, 211, 58, 223, 101, 196, 92, 223, 115, 55, 223, 115, 197, 225, 223, + 115, 239, 28, 223, 115, 200, 171, 223, 115, 195, 11, 223, 115, 242, 223, + 223, 115, 242, 223, 239, 28, 223, 115, 251, 87, 239, 28, 223, 115, 199, + 23, 249, 5, 207, 128, 208, 189, 75, 216, 36, 233, 221, 231, 146, 208, + 189, 229, 2, 198, 153, 211, 68, 207, 19, 198, 152, 223, 95, 219, 247, + 206, 9, 202, 173, 193, 138, 193, 10, 208, 202, 213, 14, 198, 152, 216, + 37, 198, 152, 250, 188, 234, 47, 159, 213, 14, 250, 188, 234, 47, 159, + 251, 42, 234, 47, 159, 251, 42, 247, 220, 213, 14, 252, 50, 234, 47, 159, + 214, 107, 251, 42, 213, 23, 252, 50, 234, 47, 159, 251, 167, 234, 47, + 159, 213, 14, 251, 167, 234, 47, 159, 251, 167, 234, 47, 211, 59, 234, + 47, 159, 197, 225, 198, 152, 251, 177, 234, 47, 159, 234, 38, 159, 231, + 145, 234, 38, 159, 237, 19, 248, 211, 251, 44, 199, 34, 219, 122, 231, + 145, 234, 47, 159, 251, 42, 234, 47, 119, 211, 59, 199, 34, 223, 180, + 211, 148, 223, 180, 79, 211, 59, 251, 42, 234, 47, 159, 242, 86, 234, 44, + 234, 45, 242, 85, 206, 190, 223, 165, 234, 47, 159, 206, 190, 234, 47, + 159, 238, 252, 159, 234, 5, 234, 43, 159, 201, 104, 234, 44, 237, 109, + 234, 47, 159, 234, 47, 119, 247, 207, 237, 128, 216, 228, 247, 206, 208, + 13, 234, 47, 159, 213, 14, 234, 47, 159, 228, 19, 159, 213, 14, 228, 19, + 159, 201, 36, 234, 38, 159, 219, 182, 211, 59, 234, 47, 159, 230, 206, + 211, 59, 234, 47, 159, 219, 182, 139, 234, 47, 159, 230, 206, 139, 234, + 47, 159, 219, 182, 247, 220, 213, 14, 234, 47, 159, 230, 206, 247, 220, + 213, 14, 234, 47, 159, 215, 147, 219, 181, 215, 147, 230, 205, 248, 211, + 213, 14, 234, 38, 159, 213, 14, 219, 181, 213, 14, 230, 205, 214, 107, + 219, 182, 213, 23, 234, 47, 159, 214, 107, 230, 206, 213, 23, 234, 47, + 159, 219, 182, 211, 59, 234, 38, 159, 230, 206, 211, 59, 234, 38, 159, + 214, 107, 219, 182, 213, 23, 234, 38, 159, 214, 107, 230, 206, 213, 23, + 234, 38, 159, 219, 182, 211, 59, 230, 205, 230, 206, 211, 59, 219, 181, + 214, 107, 219, 182, 213, 23, 230, 205, 214, 107, 230, 206, 213, 23, 219, + 181, 208, 233, 200, 220, 208, 234, 211, 59, 234, 47, 159, 200, 221, 211, + 59, 234, 47, 159, 208, 234, 211, 59, 234, 38, 159, 200, 221, 211, 59, + 234, 38, 159, 236, 166, 213, 14, 208, 236, 236, 166, 213, 14, 200, 222, + 200, 230, 211, 148, 200, 181, 211, 148, 213, 14, 42, 200, 230, 211, 148, + 213, 14, 42, 200, 181, 211, 148, 200, 230, 79, 211, 59, 234, 47, 159, + 200, 181, 79, 211, 59, 234, 47, 159, 214, 107, 42, 200, 230, 79, 213, 23, + 234, 47, 159, 214, 107, 42, 200, 181, 79, 213, 23, 234, 47, 159, 200, + 230, 79, 4, 213, 14, 234, 47, 159, 200, 181, 79, 4, 213, 14, 234, 47, + 159, 215, 126, 215, 127, 215, 128, 215, 127, 196, 92, 51, 223, 180, 211, + 148, 51, 211, 48, 211, 148, 51, 223, 180, 79, 211, 59, 234, 47, 159, 51, + 211, 48, 79, 211, 59, 234, 47, 159, 51, 247, 113, 51, 238, 183, 47, 209, + 83, 47, 216, 36, 47, 198, 144, 47, 236, 202, 202, 98, 47, 75, 211, 68, + 47, 206, 190, 211, 68, 47, 250, 196, 211, 68, 47, 234, 44, 47, 237, 217, + 112, 209, 83, 112, 216, 36, 112, 198, 144, 112, 75, 211, 68, 50, 199, + 228, 45, 199, 228, 144, 199, 228, 133, 199, 228, 250, 199, 216, 3, 197, + 201, 232, 154, 197, 225, 81, 249, 90, 50, 197, 57, 55, 81, 249, 90, 55, + 50, 197, 57, 236, 166, 213, 14, 208, 181, 213, 14, 197, 201, 236, 166, + 213, 14, 232, 155, 214, 110, 55, 81, 249, 90, 55, 50, 197, 57, 208, 234, + 196, 105, 207, 66, 200, 221, 196, 105, 207, 66, 213, 20, 200, 245, 211, + 148, 239, 34, 250, 222, 213, 20, 200, 244, 213, 20, 200, 245, 79, 211, + 59, 234, 47, 159, 239, 34, 250, 222, 213, 20, 200, 245, 211, 59, 234, 47, + 159, 211, 48, 211, 148, 223, 180, 211, 148, 215, 133, 229, 191, 239, 45, + 217, 29, 223, 112, 192, 192, 214, 226, 213, 22, 50, 251, 118, 4, 251, 18, + 50, 197, 241, 215, 62, 219, 31, 251, 127, 215, 62, 219, 31, 211, 58, 215, + 62, 223, 101, 215, 62, 196, 92, 237, 35, 211, 68, 75, 211, 68, 201, 104, + 211, 68, 236, 202, 198, 144, 248, 65, 45, 213, 20, 233, 95, 204, 25, 208, + 202, 50, 213, 20, 233, 95, 204, 25, 208, 202, 45, 204, 25, 208, 202, 50, + 204, 25, 208, 202, 207, 19, 198, 153, 234, 44, 238, 173, 219, 31, 211, + 58, 238, 173, 219, 31, 251, 127, 55, 200, 229, 55, 200, 180, 55, 223, + 101, 55, 196, 92, 209, 117, 234, 47, 23, 210, 121, 159, 219, 182, 4, 236, + 142, 230, 206, 4, 236, 142, 195, 83, 215, 147, 219, 181, 195, 83, 215, + 147, 230, 205, 219, 182, 234, 47, 119, 211, 59, 230, 205, 230, 206, 234, + 47, 119, 211, 59, 219, 181, 234, 47, 119, 211, 59, 219, 181, 234, 47, + 119, 211, 59, 230, 205, 234, 47, 119, 211, 59, 208, 233, 234, 47, 119, + 211, 59, 200, 220, 236, 166, 213, 14, 208, 237, 211, 59, 234, 46, 236, + 166, 213, 14, 200, 223, 211, 59, 234, 46, 213, 14, 51, 223, 180, 79, 211, + 59, 234, 47, 159, 213, 14, 51, 211, 48, 79, 211, 59, 234, 47, 159, 51, + 223, 180, 79, 211, 59, 213, 14, 234, 47, 159, 51, 211, 48, 79, 211, 59, + 213, 14, 234, 47, 159, 219, 182, 247, 220, 213, 14, 234, 38, 159, 230, + 206, 247, 220, 213, 14, 234, 38, 159, 208, 234, 247, 220, 213, 14, 234, + 38, 159, 200, 221, 247, 220, 213, 14, 234, 38, 159, 213, 14, 213, 20, + 200, 245, 211, 148, 236, 166, 213, 14, 239, 36, 250, 222, 213, 20, 200, + 244, 213, 14, 213, 20, 200, 245, 79, 211, 59, 234, 47, 159, 236, 166, + 213, 14, 239, 36, 250, 222, 213, 20, 200, 245, 211, 59, 234, 46, 81, 234, + 122, 216, 84, 228, 243, 234, 122, 133, 50, 237, 41, 234, 122, 144, 50, + 237, 41, 234, 122, 234, 134, 79, 4, 180, 228, 243, 106, 234, 134, 79, 4, + 81, 249, 90, 250, 185, 234, 97, 79, 228, 243, 106, 2, 234, 134, 79, 4, + 81, 249, 90, 250, 185, 234, 97, 79, 228, 243, 106, 234, 134, 79, 4, 75, + 58, 234, 134, 79, 4, 211, 8, 2, 234, 134, 79, 4, 211, 8, 234, 134, 79, 4, + 196, 103, 234, 134, 79, 4, 105, 228, 243, 201, 16, 239, 34, 4, 180, 228, + 243, 106, 239, 34, 4, 81, 249, 90, 250, 185, 234, 97, 79, 228, 243, 106, + 2, 239, 34, 4, 81, 249, 90, 250, 185, 234, 97, 79, 228, 243, 106, 239, + 34, 4, 211, 8, 2, 239, 34, 4, 211, 8, 191, 167, 213, 12, 249, 133, 216, + 191, 237, 36, 56, 234, 137, 57, 228, 174, 133, 250, 237, 144, 250, 237, + 208, 196, 209, 250, 193, 135, 219, 114, 45, 247, 32, 50, 247, 32, 45, + 232, 195, 50, 232, 195, 248, 79, 50, 238, 221, 248, 79, 45, 238, 221, + 198, 54, 50, 238, 221, 198, 54, 45, 238, 221, 207, 19, 213, 14, 56, 51, + 218, 234, 251, 18, 205, 44, 205, 53, 199, 107, 207, 98, 209, 27, 223, + 146, 195, 56, 201, 191, 209, 110, 79, 223, 111, 56, 154, 213, 14, 56, + 193, 145, 228, 176, 198, 54, 45, 239, 3, 198, 54, 50, 239, 3, 248, 79, + 45, 239, 3, 248, 79, 50, 239, 3, 198, 54, 132, 223, 115, 248, 79, 132, + 223, 115, 232, 95, 202, 66, 133, 250, 238, 248, 212, 105, 228, 243, 249, + 78, 211, 61, 221, 224, 234, 34, 119, 199, 34, 179, 192, 236, 223, 165, + 42, 207, 95, 248, 64, 221, 222, 219, 221, 251, 118, 248, 55, 206, 204, + 251, 118, 248, 55, 234, 34, 119, 199, 34, 219, 226, 248, 223, 206, 189, + 238, 140, 251, 177, 250, 246, 200, 74, 198, 39, 206, 42, 236, 254, 211, + 49, 239, 50, 199, 181, 202, 82, 238, 248, 238, 247, 251, 61, 232, 77, 16, + 228, 69, 251, 61, 232, 77, 16, 201, 182, 208, 32, 251, 61, 232, 77, 16, + 208, 33, 234, 46, 251, 61, 232, 77, 16, 208, 33, 236, 209, 251, 61, 232, + 77, 16, 208, 33, 237, 34, 251, 61, 232, 77, 16, 208, 33, 222, 190, 251, + 61, 232, 77, 16, 208, 33, 243, 12, 251, 61, 232, 77, 16, 243, 13, 201, + 72, 251, 61, 232, 77, 16, 243, 13, 222, 190, 251, 61, 232, 77, 16, 202, + 99, 164, 251, 61, 232, 77, 16, 249, 144, 164, 251, 61, 232, 77, 16, 208, + 33, 202, 98, 251, 61, 232, 77, 16, 208, 33, 249, 143, 251, 61, 232, 77, + 16, 208, 33, 219, 181, 251, 61, 232, 77, 16, 208, 33, 230, 205, 251, 61, + 232, 77, 16, 118, 195, 176, 251, 61, 232, 77, 16, 96, 195, 176, 251, 61, + 232, 77, 16, 208, 33, 118, 57, 251, 61, 232, 77, 16, 208, 33, 96, 57, + 251, 61, 232, 77, 16, 243, 13, 249, 143, 251, 61, 232, 77, 16, 144, 199, + 229, 196, 103, 251, 61, 232, 77, 16, 237, 109, 201, 72, 251, 61, 232, 77, + 16, 208, 33, 144, 247, 98, 251, 61, 232, 77, 16, 208, 33, 237, 108, 251, + 61, 232, 77, 16, 144, 199, 229, 222, 190, 251, 61, 232, 77, 16, 196, 66, + 195, 176, 251, 61, 232, 77, 16, 208, 33, 196, 66, 57, 251, 61, 232, 77, + 16, 133, 199, 229, 211, 8, 251, 61, 232, 77, 16, 237, 121, 201, 72, 251, + 61, 232, 77, 16, 208, 33, 133, 247, 98, 251, 61, 232, 77, 16, 208, 33, + 237, 120, 251, 61, 232, 77, 16, 133, 199, 229, 222, 190, 251, 61, 232, + 77, 16, 235, 121, 195, 176, 251, 61, 232, 77, 16, 208, 33, 235, 121, 57, + 251, 61, 232, 77, 16, 207, 253, 196, 103, 251, 61, 232, 77, 16, 237, 109, + 196, 103, 251, 61, 232, 77, 16, 237, 35, 196, 103, 251, 61, 232, 77, 16, + 222, 191, 196, 103, 251, 61, 232, 77, 16, 243, 13, 196, 103, 251, 61, + 232, 77, 16, 133, 203, 54, 222, 190, 251, 61, 232, 77, 16, 207, 253, 208, + 32, 251, 61, 232, 77, 16, 243, 13, 201, 103, 251, 61, 232, 77, 16, 208, + 33, 242, 85, 251, 61, 232, 77, 16, 133, 199, 229, 237, 44, 251, 61, 232, + 77, 16, 237, 121, 237, 44, 251, 61, 232, 77, 16, 201, 104, 237, 44, 251, + 61, 232, 77, 16, 222, 191, 237, 44, 251, 61, 232, 77, 16, 243, 13, 237, + 44, 251, 61, 232, 77, 16, 144, 203, 54, 201, 72, 251, 61, 232, 77, 16, + 45, 203, 54, 201, 72, 251, 61, 232, 77, 16, 198, 153, 237, 44, 251, 61, + 232, 77, 16, 230, 206, 237, 44, 251, 61, 232, 77, 16, 242, 77, 164, 251, + 61, 232, 77, 16, 237, 121, 198, 152, 251, 61, 232, 77, 16, 191, 20, 251, + 61, 232, 77, 16, 201, 73, 198, 152, 251, 61, 232, 77, 16, 204, 27, 196, + 103, 251, 61, 232, 77, 16, 208, 33, 213, 14, 234, 46, 251, 61, 232, 77, + 16, 208, 33, 208, 14, 251, 61, 232, 77, 16, 144, 247, 99, 198, 152, 251, + 61, 232, 77, 16, 133, 247, 99, 198, 152, 251, 61, 232, 77, 16, 223, 85, + 251, 61, 232, 77, 16, 207, 4, 251, 61, 232, 77, 16, 211, 112, 251, 61, + 232, 77, 16, 251, 163, 196, 103, 251, 61, 232, 77, 16, 234, 50, 196, 103, + 251, 61, 232, 77, 16, 223, 86, 196, 103, 251, 61, 232, 77, 16, 211, 113, + 196, 103, 251, 61, 232, 77, 16, 251, 162, 213, 14, 243, 128, 77, 50, 251, + 118, 4, 235, 121, 191, 21, 57, 203, 22, 211, 79, 248, 64, 248, 238, 113, + 81, 219, 115, 4, 82, 236, 142, 223, 121, 113, 239, 29, 196, 101, 113, + 236, 227, 196, 101, 113, 234, 109, 113, 239, 65, 113, 63, 51, 4, 247, 24, + 81, 219, 114, 234, 80, 113, 251, 154, 221, 225, 113, 229, 204, 113, 47, + 228, 243, 249, 90, 4, 213, 11, 47, 197, 242, 235, 125, 248, 24, 243, 13, + 4, 213, 17, 57, 196, 99, 113, 215, 218, 113, 228, 86, 113, 211, 77, 230, + 117, 113, 211, 77, 220, 143, 113, 210, 95, 113, 210, 94, 113, 236, 236, + 238, 171, 16, 232, 148, 109, 202, 30, 113, 251, 61, 232, 77, 16, 208, 32, + 237, 140, 204, 12, 221, 225, 113, 208, 219, 210, 206, 214, 75, 210, 206, + 208, 214, 205, 78, 113, 242, 240, 205, 78, 113, 45, 210, 116, 116, 102, + 45, 210, 116, 233, 205, 45, 210, 116, 110, 102, 50, 210, 116, 116, 102, + 50, 210, 116, 233, 205, 50, 210, 116, 110, 102, 45, 51, 248, 56, 116, + 239, 3, 45, 51, 248, 56, 233, 205, 45, 51, 248, 56, 110, 239, 3, 50, 51, + 248, 56, 116, 239, 3, 50, 51, 248, 56, 233, 205, 50, 51, 248, 56, 110, + 239, 3, 45, 238, 173, 248, 56, 116, 102, 45, 238, 173, 248, 56, 82, 209, + 177, 45, 238, 173, 248, 56, 110, 102, 238, 173, 248, 56, 233, 205, 50, + 238, 173, 248, 56, 116, 102, 50, 238, 173, 248, 56, 82, 209, 177, 50, + 238, 173, 248, 56, 110, 102, 223, 116, 233, 205, 228, 243, 219, 115, 233, + 205, 116, 45, 211, 59, 110, 50, 238, 173, 248, 56, 205, 54, 116, 50, 211, + 59, 110, 45, 238, 173, 248, 56, 205, 54, 200, 202, 198, 53, 200, 202, + 248, 78, 198, 54, 51, 248, 55, 248, 79, 51, 248, 55, 248, 79, 51, 248, + 56, 139, 198, 54, 51, 248, 55, 48, 16, 248, 78, 45, 81, 111, 219, 114, + 50, 81, 111, 219, 114, 228, 243, 205, 98, 219, 113, 228, 243, 205, 98, + 219, 112, 228, 243, 205, 98, 219, 111, 228, 243, 205, 98, 219, 110, 237, + 99, 16, 156, 81, 23, 198, 54, 179, 237, 99, 16, 156, 81, 23, 248, 79, + 179, 237, 99, 16, 156, 81, 4, 243, 12, 237, 99, 16, 156, 144, 23, 228, + 243, 4, 243, 12, 237, 99, 16, 156, 133, 23, 228, 243, 4, 243, 12, 237, + 99, 16, 156, 81, 4, 197, 241, 237, 99, 16, 156, 144, 23, 228, 243, 4, + 197, 241, 237, 99, 16, 156, 133, 23, 228, 243, 4, 197, 241, 237, 99, 16, + 156, 81, 23, 193, 138, 237, 99, 16, 156, 144, 23, 228, 243, 4, 193, 138, + 237, 99, 16, 156, 133, 23, 228, 243, 4, 193, 138, 237, 99, 16, 156, 144, + 23, 228, 242, 237, 99, 16, 156, 133, 23, 228, 242, 237, 99, 16, 156, 81, + 23, 198, 54, 219, 226, 237, 99, 16, 156, 81, 23, 248, 79, 219, 226, 51, + 232, 161, 207, 24, 113, 234, 151, 113, 81, 219, 115, 233, 205, 216, 161, + 248, 38, 216, 161, 180, 139, 203, 40, 216, 161, 203, 41, 139, 219, 21, + 216, 161, 180, 139, 105, 203, 26, 216, 161, 105, 203, 27, 139, 219, 21, + 216, 161, 105, 203, 27, 222, 199, 216, 161, 197, 221, 216, 161, 199, 65, + 216, 161, 210, 24, 234, 210, 230, 190, 232, 71, 198, 54, 210, 115, 248, + 79, 210, 115, 198, 54, 238, 173, 248, 55, 248, 79, 238, 173, 248, 55, + 198, 54, 198, 42, 203, 104, 248, 55, 248, 79, 198, 42, 203, 104, 248, 55, + 63, 198, 5, 248, 223, 206, 190, 4, 243, 12, 201, 52, 232, 206, 252, 66, + 238, 170, 234, 136, 223, 101, 237, 140, 233, 209, 113, 62, 206, 204, 55, + 197, 241, 62, 219, 221, 55, 197, 241, 62, 196, 76, 55, 197, 241, 62, 235, + 124, 55, 197, 241, 62, 206, 204, 55, 197, 242, 4, 81, 164, 62, 219, 221, + 55, 197, 242, 4, 81, 164, 62, 206, 204, 197, 242, 4, 55, 81, 164, 251, + 203, 242, 224, 201, 59, 198, 145, 242, 224, 228, 177, 4, 232, 186, 205, + 141, 62, 216, 215, 219, 221, 197, 241, 62, 216, 215, 206, 204, 197, 241, + 62, 216, 215, 196, 76, 197, 241, 62, 216, 215, 235, 124, 197, 241, 55, + 81, 164, 62, 51, 40, 201, 64, 62, 243, 13, 40, 207, 99, 209, 1, 113, 209, + 1, 211, 105, 113, 209, 1, 211, 107, 113, 209, 1, 202, 94, 113, 211, 170, + 233, 196, 113, 16, 40, 212, 140, 16, 40, 201, 99, 79, 229, 234, 16, 40, + 201, 99, 79, 199, 53, 16, 40, 234, 97, 79, 199, 53, 16, 40, 234, 97, 79, + 198, 11, 16, 40, 234, 83, 16, 40, 252, 53, 16, 40, 248, 237, 16, 40, 249, + 142, 16, 40, 228, 243, 199, 230, 16, 40, 219, 115, 233, 52, 16, 40, 81, + 199, 230, 16, 40, 232, 148, 233, 52, 16, 40, 247, 90, 207, 23, 16, 40, + 203, 78, 211, 16, 16, 40, 203, 78, 223, 164, 16, 40, 237, 212, 219, 105, + 234, 16, 16, 40, 237, 77, 239, 24, 107, 16, 40, 237, 77, 239, 24, 109, + 16, 40, 237, 77, 239, 24, 138, 16, 40, 237, 77, 239, 24, 134, 16, 40, + 214, 108, 252, 53, 16, 40, 200, 69, 223, 230, 16, 40, 234, 97, 79, 198, + 12, 248, 131, 16, 40, 247, 128, 16, 40, 234, 97, 79, 216, 214, 16, 40, + 200, 227, 16, 40, 234, 16, 16, 40, 233, 9, 204, 11, 16, 40, 230, 189, + 204, 11, 16, 40, 207, 100, 204, 11, 16, 40, 196, 91, 204, 11, 16, 40, + 201, 248, 16, 40, 237, 118, 248, 135, 113, 211, 79, 248, 64, 16, 40, 214, + 78, 16, 40, 237, 119, 232, 148, 109, 16, 40, 200, 228, 232, 148, 109, + 211, 163, 102, 211, 163, 246, 254, 211, 163, 232, 151, 211, 163, 223, 95, + 232, 151, 211, 163, 248, 234, 248, 7, 211, 163, 248, 72, 198, 178, 211, + 163, 248, 50, 249, 95, 228, 17, 211, 163, 251, 141, 79, 243, 127, 211, + 163, 237, 217, 211, 163, 238, 159, 252, 57, 212, 138, 211, 163, 55, 249, + 143, 47, 17, 107, 47, 17, 109, 47, 17, 138, 47, 17, 134, 47, 17, 150, 47, 17, 169, 47, 17, 175, 47, 17, 171, 47, 17, 178, 47, 31, 199, 95, 47, 31, - 234, 127, 47, 31, 197, 37, 47, 31, 198, 251, 47, 31, 232, 122, 47, 31, - 233, 19, 47, 31, 202, 130, 47, 31, 203, 244, 47, 31, 234, 161, 47, 31, - 213, 171, 47, 31, 197, 32, 127, 17, 107, 127, 17, 109, 127, 17, 138, 127, - 17, 134, 127, 17, 149, 127, 17, 169, 127, 17, 175, 127, 17, 171, 127, 17, - 178, 127, 31, 199, 95, 127, 31, 234, 127, 127, 31, 197, 37, 127, 31, 198, - 251, 127, 31, 232, 122, 127, 31, 233, 19, 127, 31, 202, 130, 127, 31, - 203, 244, 127, 31, 234, 161, 127, 31, 213, 171, 127, 31, 197, 32, 17, 91, - 232, 80, 201, 63, 17, 105, 232, 80, 201, 63, 17, 115, 232, 80, 201, 63, - 17, 232, 128, 232, 80, 201, 63, 17, 232, 226, 232, 80, 201, 63, 17, 202, - 136, 232, 80, 201, 63, 17, 203, 247, 232, 80, 201, 63, 17, 234, 164, 232, - 80, 201, 63, 17, 213, 175, 232, 80, 201, 63, 31, 199, 96, 232, 80, 201, - 63, 31, 234, 128, 232, 80, 201, 63, 31, 197, 38, 232, 80, 201, 63, 31, - 198, 252, 232, 80, 201, 63, 31, 232, 123, 232, 80, 201, 63, 31, 233, 20, - 232, 80, 201, 63, 31, 202, 131, 232, 80, 201, 63, 31, 203, 245, 232, 80, - 201, 63, 31, 234, 162, 232, 80, 201, 63, 31, 213, 172, 232, 80, 201, 63, - 31, 197, 33, 232, 80, 201, 63, 127, 8, 2, 1, 65, 127, 8, 2, 1, 250, 120, - 127, 8, 2, 1, 247, 193, 127, 8, 2, 1, 238, 127, 127, 8, 2, 1, 71, 127, 8, - 2, 1, 233, 175, 127, 8, 2, 1, 232, 51, 127, 8, 2, 1, 230, 116, 127, 8, 2, - 1, 68, 127, 8, 2, 1, 223, 35, 127, 8, 2, 1, 222, 152, 127, 8, 2, 1, 172, - 127, 8, 2, 1, 218, 168, 127, 8, 2, 1, 215, 61, 127, 8, 2, 1, 74, 127, 8, - 2, 1, 210, 236, 127, 8, 2, 1, 208, 104, 127, 8, 2, 1, 146, 127, 8, 2, 1, - 206, 8, 127, 8, 2, 1, 200, 43, 127, 8, 2, 1, 66, 127, 8, 2, 1, 196, 12, + 234, 129, 47, 31, 197, 37, 47, 31, 198, 251, 47, 31, 232, 124, 47, 31, + 233, 21, 47, 31, 202, 131, 47, 31, 203, 245, 47, 31, 234, 163, 47, 31, + 213, 173, 47, 31, 197, 32, 127, 17, 107, 127, 17, 109, 127, 17, 138, 127, + 17, 134, 127, 17, 150, 127, 17, 169, 127, 17, 175, 127, 17, 171, 127, 17, + 178, 127, 31, 199, 95, 127, 31, 234, 129, 127, 31, 197, 37, 127, 31, 198, + 251, 127, 31, 232, 124, 127, 31, 233, 21, 127, 31, 202, 131, 127, 31, + 203, 245, 127, 31, 234, 163, 127, 31, 213, 173, 127, 31, 197, 32, 17, 91, + 232, 82, 201, 64, 17, 105, 232, 82, 201, 64, 17, 115, 232, 82, 201, 64, + 17, 232, 130, 232, 82, 201, 64, 17, 232, 228, 232, 82, 201, 64, 17, 202, + 137, 232, 82, 201, 64, 17, 203, 248, 232, 82, 201, 64, 17, 234, 166, 232, + 82, 201, 64, 17, 213, 177, 232, 82, 201, 64, 31, 199, 96, 232, 82, 201, + 64, 31, 234, 130, 232, 82, 201, 64, 31, 197, 38, 232, 82, 201, 64, 31, + 198, 252, 232, 82, 201, 64, 31, 232, 125, 232, 82, 201, 64, 31, 233, 22, + 232, 82, 201, 64, 31, 202, 132, 232, 82, 201, 64, 31, 203, 246, 232, 82, + 201, 64, 31, 234, 164, 232, 82, 201, 64, 31, 213, 174, 232, 82, 201, 64, + 31, 197, 33, 232, 82, 201, 64, 127, 8, 2, 1, 65, 127, 8, 2, 1, 250, 122, + 127, 8, 2, 1, 247, 195, 127, 8, 2, 1, 238, 129, 127, 8, 2, 1, 71, 127, 8, + 2, 1, 233, 177, 127, 8, 2, 1, 232, 53, 127, 8, 2, 1, 230, 118, 127, 8, 2, + 1, 68, 127, 8, 2, 1, 223, 37, 127, 8, 2, 1, 222, 154, 127, 8, 2, 1, 172, + 127, 8, 2, 1, 218, 170, 127, 8, 2, 1, 215, 63, 127, 8, 2, 1, 74, 127, 8, + 2, 1, 210, 238, 127, 8, 2, 1, 208, 106, 127, 8, 2, 1, 146, 127, 8, 2, 1, + 206, 9, 127, 8, 2, 1, 200, 43, 127, 8, 2, 1, 66, 127, 8, 2, 1, 196, 12, 127, 8, 2, 1, 193, 224, 127, 8, 2, 1, 192, 235, 127, 8, 2, 1, 192, 159, - 127, 8, 2, 1, 191, 166, 47, 8, 6, 1, 65, 47, 8, 6, 1, 250, 120, 47, 8, 6, - 1, 247, 193, 47, 8, 6, 1, 238, 127, 47, 8, 6, 1, 71, 47, 8, 6, 1, 233, - 175, 47, 8, 6, 1, 232, 51, 47, 8, 6, 1, 230, 116, 47, 8, 6, 1, 68, 47, 8, - 6, 1, 223, 35, 47, 8, 6, 1, 222, 152, 47, 8, 6, 1, 172, 47, 8, 6, 1, 218, - 168, 47, 8, 6, 1, 215, 61, 47, 8, 6, 1, 74, 47, 8, 6, 1, 210, 236, 47, 8, - 6, 1, 208, 104, 47, 8, 6, 1, 146, 47, 8, 6, 1, 206, 8, 47, 8, 6, 1, 200, + 127, 8, 2, 1, 191, 166, 47, 8, 6, 1, 65, 47, 8, 6, 1, 250, 122, 47, 8, 6, + 1, 247, 195, 47, 8, 6, 1, 238, 129, 47, 8, 6, 1, 71, 47, 8, 6, 1, 233, + 177, 47, 8, 6, 1, 232, 53, 47, 8, 6, 1, 230, 118, 47, 8, 6, 1, 68, 47, 8, + 6, 1, 223, 37, 47, 8, 6, 1, 222, 154, 47, 8, 6, 1, 172, 47, 8, 6, 1, 218, + 170, 47, 8, 6, 1, 215, 63, 47, 8, 6, 1, 74, 47, 8, 6, 1, 210, 238, 47, 8, + 6, 1, 208, 106, 47, 8, 6, 1, 146, 47, 8, 6, 1, 206, 9, 47, 8, 6, 1, 200, 43, 47, 8, 6, 1, 66, 47, 8, 6, 1, 196, 12, 47, 8, 6, 1, 193, 224, 47, 8, 6, 1, 192, 235, 47, 8, 6, 1, 192, 159, 47, 8, 6, 1, 191, 166, 47, 8, 2, - 1, 65, 47, 8, 2, 1, 250, 120, 47, 8, 2, 1, 247, 193, 47, 8, 2, 1, 238, - 127, 47, 8, 2, 1, 71, 47, 8, 2, 1, 233, 175, 47, 8, 2, 1, 232, 51, 47, 8, - 2, 1, 230, 116, 47, 8, 2, 1, 68, 47, 8, 2, 1, 223, 35, 47, 8, 2, 1, 222, - 152, 47, 8, 2, 1, 172, 47, 8, 2, 1, 218, 168, 47, 8, 2, 1, 215, 61, 47, - 8, 2, 1, 74, 47, 8, 2, 1, 210, 236, 47, 8, 2, 1, 208, 104, 47, 8, 2, 1, - 146, 47, 8, 2, 1, 206, 8, 47, 8, 2, 1, 200, 43, 47, 8, 2, 1, 66, 47, 8, + 1, 65, 47, 8, 2, 1, 250, 122, 47, 8, 2, 1, 247, 195, 47, 8, 2, 1, 238, + 129, 47, 8, 2, 1, 71, 47, 8, 2, 1, 233, 177, 47, 8, 2, 1, 232, 53, 47, 8, + 2, 1, 230, 118, 47, 8, 2, 1, 68, 47, 8, 2, 1, 223, 37, 47, 8, 2, 1, 222, + 154, 47, 8, 2, 1, 172, 47, 8, 2, 1, 218, 170, 47, 8, 2, 1, 215, 63, 47, + 8, 2, 1, 74, 47, 8, 2, 1, 210, 238, 47, 8, 2, 1, 208, 106, 47, 8, 2, 1, + 146, 47, 8, 2, 1, 206, 9, 47, 8, 2, 1, 200, 43, 47, 8, 2, 1, 66, 47, 8, 2, 1, 196, 12, 47, 8, 2, 1, 193, 224, 47, 8, 2, 1, 192, 235, 47, 8, 2, 1, - 192, 159, 47, 8, 2, 1, 191, 166, 47, 17, 191, 77, 214, 106, 47, 31, 234, - 127, 214, 106, 47, 31, 197, 37, 214, 106, 47, 31, 198, 251, 214, 106, 47, - 31, 232, 122, 214, 106, 47, 31, 233, 19, 214, 106, 47, 31, 202, 130, 214, - 106, 47, 31, 203, 244, 214, 106, 47, 31, 234, 161, 214, 106, 47, 31, 213, - 171, 214, 106, 47, 31, 197, 32, 55, 47, 17, 107, 55, 47, 17, 109, 55, 47, - 17, 138, 55, 47, 17, 134, 55, 47, 17, 149, 55, 47, 17, 169, 55, 47, 17, - 175, 55, 47, 17, 171, 55, 47, 17, 178, 55, 47, 31, 199, 95, 214, 106, 47, - 17, 191, 77, 111, 122, 156, 228, 240, 111, 122, 88, 228, 240, 111, 122, - 156, 195, 135, 111, 122, 88, 195, 135, 111, 122, 156, 197, 225, 237, 216, - 228, 240, 111, 122, 88, 197, 225, 237, 216, 228, 240, 111, 122, 156, 197, - 225, 237, 216, 195, 135, 111, 122, 88, 197, 225, 237, 216, 195, 135, 111, - 122, 156, 208, 26, 237, 216, 228, 240, 111, 122, 88, 208, 26, 237, 216, - 228, 240, 111, 122, 156, 208, 26, 237, 216, 195, 135, 111, 122, 88, 208, - 26, 237, 216, 195, 135, 111, 122, 156, 144, 23, 183, 111, 122, 144, 156, - 23, 50, 229, 217, 111, 122, 144, 88, 23, 50, 219, 132, 111, 122, 88, 144, - 23, 183, 111, 122, 156, 144, 23, 219, 224, 111, 122, 144, 156, 23, 45, - 229, 217, 111, 122, 144, 88, 23, 45, 219, 132, 111, 122, 88, 144, 23, - 219, 224, 111, 122, 156, 133, 23, 183, 111, 122, 133, 156, 23, 50, 229, - 217, 111, 122, 133, 88, 23, 50, 219, 132, 111, 122, 88, 133, 23, 183, - 111, 122, 156, 133, 23, 219, 224, 111, 122, 133, 156, 23, 45, 229, 217, - 111, 122, 133, 88, 23, 45, 219, 132, 111, 122, 88, 133, 23, 219, 224, - 111, 122, 156, 81, 23, 183, 111, 122, 81, 156, 23, 50, 229, 217, 111, - 122, 133, 88, 23, 50, 144, 219, 132, 111, 122, 144, 88, 23, 50, 133, 219, - 132, 111, 122, 81, 88, 23, 50, 219, 132, 111, 122, 144, 156, 23, 50, 133, - 229, 217, 111, 122, 133, 156, 23, 50, 144, 229, 217, 111, 122, 88, 81, - 23, 183, 111, 122, 156, 81, 23, 219, 224, 111, 122, 81, 156, 23, 45, 229, - 217, 111, 122, 133, 88, 23, 45, 144, 219, 132, 111, 122, 144, 88, 23, 45, - 133, 219, 132, 111, 122, 81, 88, 23, 45, 219, 132, 111, 122, 144, 156, - 23, 45, 133, 229, 217, 111, 122, 133, 156, 23, 45, 144, 229, 217, 111, - 122, 88, 81, 23, 219, 224, 111, 122, 156, 144, 23, 228, 240, 111, 122, - 45, 88, 23, 50, 144, 219, 132, 111, 122, 50, 88, 23, 45, 144, 219, 132, - 111, 122, 144, 156, 23, 228, 241, 229, 217, 111, 122, 144, 88, 23, 228, - 241, 219, 132, 111, 122, 50, 156, 23, 45, 144, 229, 217, 111, 122, 45, - 156, 23, 50, 144, 229, 217, 111, 122, 88, 144, 23, 228, 240, 111, 122, - 156, 133, 23, 228, 240, 111, 122, 45, 88, 23, 50, 133, 219, 132, 111, - 122, 50, 88, 23, 45, 133, 219, 132, 111, 122, 133, 156, 23, 228, 241, - 229, 217, 111, 122, 133, 88, 23, 228, 241, 219, 132, 111, 122, 50, 156, - 23, 45, 133, 229, 217, 111, 122, 45, 156, 23, 50, 133, 229, 217, 111, - 122, 88, 133, 23, 228, 240, 111, 122, 156, 81, 23, 228, 240, 111, 122, - 45, 88, 23, 50, 81, 219, 132, 111, 122, 50, 88, 23, 45, 81, 219, 132, - 111, 122, 81, 156, 23, 228, 241, 229, 217, 111, 122, 133, 88, 23, 144, - 228, 241, 219, 132, 111, 122, 144, 88, 23, 133, 228, 241, 219, 132, 111, - 122, 81, 88, 23, 228, 241, 219, 132, 111, 122, 45, 133, 88, 23, 50, 144, - 219, 132, 111, 122, 50, 133, 88, 23, 45, 144, 219, 132, 111, 122, 45, - 144, 88, 23, 50, 133, 219, 132, 111, 122, 50, 144, 88, 23, 45, 133, 219, - 132, 111, 122, 144, 156, 23, 133, 228, 241, 229, 217, 111, 122, 133, 156, - 23, 144, 228, 241, 229, 217, 111, 122, 50, 156, 23, 45, 81, 229, 217, - 111, 122, 45, 156, 23, 50, 81, 229, 217, 111, 122, 88, 81, 23, 228, 240, - 111, 122, 156, 55, 237, 216, 228, 240, 111, 122, 88, 55, 237, 216, 228, - 240, 111, 122, 156, 55, 237, 216, 195, 135, 111, 122, 88, 55, 237, 216, - 195, 135, 111, 122, 55, 228, 240, 111, 122, 55, 195, 135, 111, 122, 144, - 202, 170, 23, 50, 235, 133, 111, 122, 144, 55, 23, 50, 202, 169, 111, - 122, 55, 144, 23, 183, 111, 122, 144, 202, 170, 23, 45, 235, 133, 111, - 122, 144, 55, 23, 45, 202, 169, 111, 122, 55, 144, 23, 219, 224, 111, - 122, 133, 202, 170, 23, 50, 235, 133, 111, 122, 133, 55, 23, 50, 202, - 169, 111, 122, 55, 133, 23, 183, 111, 122, 133, 202, 170, 23, 45, 235, - 133, 111, 122, 133, 55, 23, 45, 202, 169, 111, 122, 55, 133, 23, 219, - 224, 111, 122, 81, 202, 170, 23, 50, 235, 133, 111, 122, 81, 55, 23, 50, - 202, 169, 111, 122, 55, 81, 23, 183, 111, 122, 81, 202, 170, 23, 45, 235, - 133, 111, 122, 81, 55, 23, 45, 202, 169, 111, 122, 55, 81, 23, 219, 224, - 111, 122, 144, 202, 170, 23, 228, 241, 235, 133, 111, 122, 144, 55, 23, - 228, 241, 202, 169, 111, 122, 55, 144, 23, 228, 240, 111, 122, 133, 202, - 170, 23, 228, 241, 235, 133, 111, 122, 133, 55, 23, 228, 241, 202, 169, - 111, 122, 55, 133, 23, 228, 240, 111, 122, 81, 202, 170, 23, 228, 241, - 235, 133, 111, 122, 81, 55, 23, 228, 241, 202, 169, 111, 122, 55, 81, 23, - 228, 240, 111, 122, 156, 251, 17, 144, 23, 183, 111, 122, 156, 251, 17, - 144, 23, 219, 224, 111, 122, 156, 251, 17, 133, 23, 219, 224, 111, 122, - 156, 251, 17, 133, 23, 183, 111, 122, 156, 237, 39, 116, 50, 119, 110, - 219, 224, 111, 122, 156, 237, 39, 116, 45, 119, 110, 183, 111, 122, 156, - 237, 39, 238, 217, 111, 122, 156, 219, 224, 111, 122, 156, 196, 77, 111, - 122, 156, 183, 111, 122, 156, 235, 123, 111, 122, 88, 219, 224, 111, 122, - 88, 196, 77, 111, 122, 88, 183, 111, 122, 88, 235, 123, 111, 122, 156, - 45, 23, 88, 183, 111, 122, 156, 133, 23, 88, 235, 123, 111, 122, 88, 45, - 23, 156, 183, 111, 122, 88, 133, 23, 156, 235, 123, 116, 132, 248, 129, - 110, 91, 234, 160, 248, 129, 110, 91, 208, 23, 248, 129, 110, 115, 234, - 158, 248, 129, 110, 132, 248, 129, 110, 232, 226, 234, 158, 248, 129, - 110, 115, 208, 21, 248, 129, 110, 203, 247, 234, 158, 248, 129, 232, 80, - 248, 129, 45, 203, 247, 234, 158, 248, 129, 45, 115, 208, 21, 248, 129, - 45, 232, 226, 234, 158, 248, 129, 45, 132, 248, 129, 45, 115, 234, 158, - 248, 129, 45, 91, 208, 23, 248, 129, 45, 91, 234, 160, 248, 129, 50, 132, - 248, 129, 156, 203, 153, 216, 213, 203, 153, 237, 221, 203, 153, 116, 91, - 234, 160, 248, 129, 50, 91, 234, 160, 248, 129, 208, 28, 110, 219, 224, - 208, 28, 110, 183, 208, 28, 116, 219, 224, 208, 28, 116, 45, 23, 110, 45, - 23, 110, 183, 208, 28, 116, 45, 23, 110, 183, 208, 28, 116, 45, 23, 116, - 50, 23, 110, 219, 224, 208, 28, 116, 45, 23, 116, 50, 23, 110, 183, 208, - 28, 116, 183, 208, 28, 116, 50, 23, 110, 219, 224, 208, 28, 116, 50, 23, - 110, 45, 23, 110, 183, 62, 201, 190, 63, 201, 190, 63, 51, 4, 206, 113, - 239, 0, 63, 51, 239, 33, 62, 2, 201, 190, 51, 4, 228, 241, 233, 5, 51, 4, - 81, 233, 5, 51, 4, 211, 38, 238, 211, 233, 5, 51, 4, 116, 45, 119, 110, - 50, 233, 5, 51, 4, 116, 50, 119, 110, 45, 233, 5, 51, 4, 237, 39, 238, - 211, 233, 5, 62, 2, 201, 190, 63, 2, 201, 190, 62, 207, 92, 63, 207, 92, - 62, 81, 207, 92, 63, 81, 207, 92, 62, 210, 117, 63, 210, 117, 62, 196, + 192, 159, 47, 8, 2, 1, 191, 166, 47, 17, 191, 77, 214, 108, 47, 31, 234, + 129, 214, 108, 47, 31, 197, 37, 214, 108, 47, 31, 198, 251, 214, 108, 47, + 31, 232, 124, 214, 108, 47, 31, 233, 21, 214, 108, 47, 31, 202, 131, 214, + 108, 47, 31, 203, 245, 214, 108, 47, 31, 234, 163, 214, 108, 47, 31, 213, + 173, 214, 108, 47, 31, 197, 32, 55, 47, 17, 107, 55, 47, 17, 109, 55, 47, + 17, 138, 55, 47, 17, 134, 55, 47, 17, 150, 55, 47, 17, 169, 55, 47, 17, + 175, 55, 47, 17, 171, 55, 47, 17, 178, 55, 47, 31, 199, 95, 214, 108, 47, + 17, 191, 77, 111, 122, 156, 228, 242, 111, 122, 88, 228, 242, 111, 122, + 156, 195, 135, 111, 122, 88, 195, 135, 111, 122, 156, 197, 225, 237, 218, + 228, 242, 111, 122, 88, 197, 225, 237, 218, 228, 242, 111, 122, 156, 197, + 225, 237, 218, 195, 135, 111, 122, 88, 197, 225, 237, 218, 195, 135, 111, + 122, 156, 208, 28, 237, 218, 228, 242, 111, 122, 88, 208, 28, 237, 218, + 228, 242, 111, 122, 156, 208, 28, 237, 218, 195, 135, 111, 122, 88, 208, + 28, 237, 218, 195, 135, 111, 122, 156, 144, 23, 179, 111, 122, 144, 156, + 23, 50, 229, 219, 111, 122, 144, 88, 23, 50, 219, 134, 111, 122, 88, 144, + 23, 179, 111, 122, 156, 144, 23, 219, 226, 111, 122, 144, 156, 23, 45, + 229, 219, 111, 122, 144, 88, 23, 45, 219, 134, 111, 122, 88, 144, 23, + 219, 226, 111, 122, 156, 133, 23, 179, 111, 122, 133, 156, 23, 50, 229, + 219, 111, 122, 133, 88, 23, 50, 219, 134, 111, 122, 88, 133, 23, 179, + 111, 122, 156, 133, 23, 219, 226, 111, 122, 133, 156, 23, 45, 229, 219, + 111, 122, 133, 88, 23, 45, 219, 134, 111, 122, 88, 133, 23, 219, 226, + 111, 122, 156, 81, 23, 179, 111, 122, 81, 156, 23, 50, 229, 219, 111, + 122, 133, 88, 23, 50, 144, 219, 134, 111, 122, 144, 88, 23, 50, 133, 219, + 134, 111, 122, 81, 88, 23, 50, 219, 134, 111, 122, 144, 156, 23, 50, 133, + 229, 219, 111, 122, 133, 156, 23, 50, 144, 229, 219, 111, 122, 88, 81, + 23, 179, 111, 122, 156, 81, 23, 219, 226, 111, 122, 81, 156, 23, 45, 229, + 219, 111, 122, 133, 88, 23, 45, 144, 219, 134, 111, 122, 144, 88, 23, 45, + 133, 219, 134, 111, 122, 81, 88, 23, 45, 219, 134, 111, 122, 144, 156, + 23, 45, 133, 229, 219, 111, 122, 133, 156, 23, 45, 144, 229, 219, 111, + 122, 88, 81, 23, 219, 226, 111, 122, 156, 144, 23, 228, 242, 111, 122, + 45, 88, 23, 50, 144, 219, 134, 111, 122, 50, 88, 23, 45, 144, 219, 134, + 111, 122, 144, 156, 23, 228, 243, 229, 219, 111, 122, 144, 88, 23, 228, + 243, 219, 134, 111, 122, 50, 156, 23, 45, 144, 229, 219, 111, 122, 45, + 156, 23, 50, 144, 229, 219, 111, 122, 88, 144, 23, 228, 242, 111, 122, + 156, 133, 23, 228, 242, 111, 122, 45, 88, 23, 50, 133, 219, 134, 111, + 122, 50, 88, 23, 45, 133, 219, 134, 111, 122, 133, 156, 23, 228, 243, + 229, 219, 111, 122, 133, 88, 23, 228, 243, 219, 134, 111, 122, 50, 156, + 23, 45, 133, 229, 219, 111, 122, 45, 156, 23, 50, 133, 229, 219, 111, + 122, 88, 133, 23, 228, 242, 111, 122, 156, 81, 23, 228, 242, 111, 122, + 45, 88, 23, 50, 81, 219, 134, 111, 122, 50, 88, 23, 45, 81, 219, 134, + 111, 122, 81, 156, 23, 228, 243, 229, 219, 111, 122, 133, 88, 23, 144, + 228, 243, 219, 134, 111, 122, 144, 88, 23, 133, 228, 243, 219, 134, 111, + 122, 81, 88, 23, 228, 243, 219, 134, 111, 122, 45, 133, 88, 23, 50, 144, + 219, 134, 111, 122, 50, 133, 88, 23, 45, 144, 219, 134, 111, 122, 45, + 144, 88, 23, 50, 133, 219, 134, 111, 122, 50, 144, 88, 23, 45, 133, 219, + 134, 111, 122, 144, 156, 23, 133, 228, 243, 229, 219, 111, 122, 133, 156, + 23, 144, 228, 243, 229, 219, 111, 122, 50, 156, 23, 45, 81, 229, 219, + 111, 122, 45, 156, 23, 50, 81, 229, 219, 111, 122, 88, 81, 23, 228, 242, + 111, 122, 156, 55, 237, 218, 228, 242, 111, 122, 88, 55, 237, 218, 228, + 242, 111, 122, 156, 55, 237, 218, 195, 135, 111, 122, 88, 55, 237, 218, + 195, 135, 111, 122, 55, 228, 242, 111, 122, 55, 195, 135, 111, 122, 144, + 202, 171, 23, 50, 235, 135, 111, 122, 144, 55, 23, 50, 202, 170, 111, + 122, 55, 144, 23, 179, 111, 122, 144, 202, 171, 23, 45, 235, 135, 111, + 122, 144, 55, 23, 45, 202, 170, 111, 122, 55, 144, 23, 219, 226, 111, + 122, 133, 202, 171, 23, 50, 235, 135, 111, 122, 133, 55, 23, 50, 202, + 170, 111, 122, 55, 133, 23, 179, 111, 122, 133, 202, 171, 23, 45, 235, + 135, 111, 122, 133, 55, 23, 45, 202, 170, 111, 122, 55, 133, 23, 219, + 226, 111, 122, 81, 202, 171, 23, 50, 235, 135, 111, 122, 81, 55, 23, 50, + 202, 170, 111, 122, 55, 81, 23, 179, 111, 122, 81, 202, 171, 23, 45, 235, + 135, 111, 122, 81, 55, 23, 45, 202, 170, 111, 122, 55, 81, 23, 219, 226, + 111, 122, 144, 202, 171, 23, 228, 243, 235, 135, 111, 122, 144, 55, 23, + 228, 243, 202, 170, 111, 122, 55, 144, 23, 228, 242, 111, 122, 133, 202, + 171, 23, 228, 243, 235, 135, 111, 122, 133, 55, 23, 228, 243, 202, 170, + 111, 122, 55, 133, 23, 228, 242, 111, 122, 81, 202, 171, 23, 228, 243, + 235, 135, 111, 122, 81, 55, 23, 228, 243, 202, 170, 111, 122, 55, 81, 23, + 228, 242, 111, 122, 156, 251, 19, 144, 23, 179, 111, 122, 156, 251, 19, + 144, 23, 219, 226, 111, 122, 156, 251, 19, 133, 23, 219, 226, 111, 122, + 156, 251, 19, 133, 23, 179, 111, 122, 156, 237, 41, 116, 50, 119, 110, + 219, 226, 111, 122, 156, 237, 41, 116, 45, 119, 110, 179, 111, 122, 156, + 237, 41, 238, 219, 111, 122, 156, 219, 226, 111, 122, 156, 196, 77, 111, + 122, 156, 179, 111, 122, 156, 235, 125, 111, 122, 88, 219, 226, 111, 122, + 88, 196, 77, 111, 122, 88, 179, 111, 122, 88, 235, 125, 111, 122, 156, + 45, 23, 88, 179, 111, 122, 156, 133, 23, 88, 235, 125, 111, 122, 88, 45, + 23, 156, 179, 111, 122, 88, 133, 23, 156, 235, 125, 116, 132, 248, 131, + 110, 91, 234, 162, 248, 131, 110, 91, 208, 25, 248, 131, 110, 115, 234, + 160, 248, 131, 110, 132, 248, 131, 110, 232, 228, 234, 160, 248, 131, + 110, 115, 208, 23, 248, 131, 110, 203, 248, 234, 160, 248, 131, 232, 82, + 248, 131, 45, 203, 248, 234, 160, 248, 131, 45, 115, 208, 23, 248, 131, + 45, 232, 228, 234, 160, 248, 131, 45, 132, 248, 131, 45, 115, 234, 160, + 248, 131, 45, 91, 208, 25, 248, 131, 45, 91, 234, 162, 248, 131, 50, 132, + 248, 131, 156, 203, 154, 216, 215, 203, 154, 237, 223, 203, 154, 116, 91, + 234, 162, 248, 131, 50, 91, 234, 162, 248, 131, 208, 30, 110, 219, 226, + 208, 30, 110, 179, 208, 30, 116, 219, 226, 208, 30, 116, 45, 23, 110, 45, + 23, 110, 179, 208, 30, 116, 45, 23, 110, 179, 208, 30, 116, 45, 23, 116, + 50, 23, 110, 219, 226, 208, 30, 116, 45, 23, 116, 50, 23, 110, 179, 208, + 30, 116, 179, 208, 30, 116, 50, 23, 110, 219, 226, 208, 30, 116, 50, 23, + 110, 45, 23, 110, 179, 62, 201, 191, 63, 201, 191, 63, 51, 4, 206, 114, + 239, 2, 63, 51, 239, 35, 62, 2, 201, 191, 51, 4, 228, 243, 233, 7, 51, 4, + 81, 233, 7, 51, 4, 211, 40, 238, 213, 233, 7, 51, 4, 116, 45, 119, 110, + 50, 233, 7, 51, 4, 116, 50, 119, 110, 45, 233, 7, 51, 4, 237, 41, 238, + 213, 233, 7, 62, 2, 201, 191, 63, 2, 201, 191, 62, 207, 94, 63, 207, 94, + 62, 81, 207, 94, 63, 81, 207, 94, 62, 210, 119, 63, 210, 119, 62, 196, 76, 197, 241, 63, 196, 76, 197, 241, 62, 196, 76, 2, 197, 241, 63, 196, - 76, 2, 197, 241, 62, 206, 203, 197, 241, 63, 206, 203, 197, 241, 62, 206, - 203, 2, 197, 241, 63, 206, 203, 2, 197, 241, 62, 206, 203, 209, 59, 63, - 206, 203, 209, 59, 62, 235, 122, 197, 241, 63, 235, 122, 197, 241, 62, - 235, 122, 2, 197, 241, 63, 235, 122, 2, 197, 241, 62, 219, 219, 197, 241, - 63, 219, 219, 197, 241, 62, 219, 219, 2, 197, 241, 63, 219, 219, 2, 197, - 241, 62, 219, 219, 209, 59, 63, 219, 219, 209, 59, 62, 237, 32, 63, 237, - 32, 63, 237, 33, 239, 33, 62, 2, 237, 32, 232, 235, 218, 232, 63, 243, - 10, 235, 138, 243, 10, 243, 11, 4, 81, 233, 5, 247, 244, 62, 243, 10, - 243, 11, 4, 45, 132, 248, 139, 243, 11, 4, 50, 132, 248, 139, 243, 11, 4, - 110, 132, 248, 139, 243, 11, 4, 116, 132, 248, 139, 243, 11, 4, 116, 50, - 208, 28, 248, 139, 243, 11, 4, 251, 175, 247, 218, 116, 45, 208, 28, 248, - 139, 45, 132, 62, 243, 10, 50, 132, 62, 243, 10, 223, 95, 247, 248, 223, - 95, 63, 243, 10, 116, 132, 223, 95, 63, 243, 10, 110, 132, 223, 95, 63, - 243, 10, 116, 45, 208, 28, 243, 4, 251, 16, 116, 50, 208, 28, 243, 4, - 251, 16, 110, 50, 208, 28, 243, 4, 251, 16, 110, 45, 208, 28, 243, 4, - 251, 16, 116, 132, 243, 10, 110, 132, 243, 10, 62, 110, 50, 197, 241, 62, + 76, 2, 197, 241, 62, 206, 204, 197, 241, 63, 206, 204, 197, 241, 62, 206, + 204, 2, 197, 241, 63, 206, 204, 2, 197, 241, 62, 206, 204, 209, 61, 63, + 206, 204, 209, 61, 62, 235, 124, 197, 241, 63, 235, 124, 197, 241, 62, + 235, 124, 2, 197, 241, 63, 235, 124, 2, 197, 241, 62, 219, 221, 197, 241, + 63, 219, 221, 197, 241, 62, 219, 221, 2, 197, 241, 63, 219, 221, 2, 197, + 241, 62, 219, 221, 209, 61, 63, 219, 221, 209, 61, 62, 237, 34, 63, 237, + 34, 63, 237, 35, 239, 35, 62, 2, 237, 34, 232, 237, 218, 234, 63, 243, + 12, 235, 140, 243, 12, 243, 13, 4, 81, 233, 7, 247, 246, 62, 243, 12, + 243, 13, 4, 45, 132, 248, 141, 243, 13, 4, 50, 132, 248, 141, 243, 13, 4, + 110, 132, 248, 141, 243, 13, 4, 116, 132, 248, 141, 243, 13, 4, 116, 50, + 208, 30, 248, 141, 243, 13, 4, 251, 177, 247, 220, 116, 45, 208, 30, 248, + 141, 45, 132, 62, 243, 12, 50, 132, 62, 243, 12, 223, 97, 247, 250, 223, + 97, 63, 243, 12, 116, 132, 223, 97, 63, 243, 12, 110, 132, 223, 97, 63, + 243, 12, 116, 45, 208, 30, 243, 6, 251, 18, 116, 50, 208, 30, 243, 6, + 251, 18, 110, 50, 208, 30, 243, 6, 251, 18, 110, 45, 208, 30, 243, 6, + 251, 18, 116, 132, 243, 12, 110, 132, 243, 12, 62, 110, 50, 197, 241, 62, 110, 45, 197, 241, 62, 116, 45, 197, 241, 62, 116, 50, 197, 241, 63, 247, - 248, 51, 4, 45, 132, 248, 139, 51, 4, 50, 132, 248, 139, 51, 4, 116, 45, - 237, 39, 132, 248, 139, 51, 4, 110, 50, 237, 39, 132, 248, 139, 63, 51, - 4, 81, 248, 154, 219, 112, 63, 196, 76, 197, 242, 4, 236, 140, 196, 76, - 197, 242, 4, 45, 132, 248, 139, 196, 76, 197, 242, 4, 50, 132, 248, 139, - 220, 13, 243, 10, 63, 51, 4, 116, 45, 208, 27, 63, 51, 4, 110, 45, 208, - 27, 63, 51, 4, 110, 50, 208, 27, 63, 51, 4, 116, 50, 208, 27, 63, 243, - 11, 4, 116, 45, 208, 27, 63, 243, 11, 4, 110, 45, 208, 27, 63, 243, 11, - 4, 110, 50, 208, 27, 63, 243, 11, 4, 116, 50, 208, 27, 116, 45, 197, 241, - 116, 50, 197, 241, 110, 45, 197, 241, 63, 216, 213, 201, 190, 62, 216, - 213, 201, 190, 63, 216, 213, 2, 201, 190, 62, 216, 213, 2, 201, 190, 110, - 50, 197, 241, 62, 200, 199, 4, 207, 119, 242, 210, 196, 117, 202, 48, - 242, 77, 62, 201, 102, 63, 201, 102, 219, 129, 198, 208, 200, 198, 250, - 213, 213, 35, 237, 86, 213, 35, 239, 42, 211, 62, 62, 199, 106, 63, 199, - 106, 249, 107, 248, 62, 249, 107, 111, 4, 243, 125, 249, 107, 111, 4, - 192, 235, 205, 154, 196, 118, 4, 207, 150, 235, 96, 228, 181, 248, 207, - 63, 203, 49, 209, 175, 62, 203, 49, 209, 175, 203, 140, 207, 18, 206, - 122, 232, 190, 229, 224, 247, 248, 62, 45, 209, 58, 223, 148, 62, 50, - 209, 58, 223, 148, 63, 45, 209, 58, 223, 148, 63, 133, 209, 58, 223, 148, - 63, 50, 209, 58, 223, 148, 63, 144, 209, 58, 223, 148, 202, 104, 23, 238, - 215, 247, 71, 56, 207, 164, 56, 248, 162, 56, 247, 151, 251, 99, 211, 39, - 238, 217, 243, 96, 207, 3, 238, 218, 79, 218, 255, 238, 218, 79, 222, - 254, 201, 103, 23, 238, 227, 233, 74, 113, 252, 34, 203, 143, 230, 62, - 23, 202, 213, 210, 61, 113, 192, 22, 192, 106, 197, 231, 40, 229, 219, - 197, 231, 40, 220, 43, 197, 231, 40, 232, 243, 197, 231, 40, 198, 209, - 197, 231, 40, 193, 66, 197, 231, 40, 193, 143, 197, 231, 40, 215, 184, - 197, 231, 40, 234, 207, 193, 94, 79, 237, 60, 63, 232, 92, 233, 103, 63, - 202, 64, 233, 103, 62, 202, 64, 233, 103, 63, 200, 199, 4, 207, 119, 232, - 238, 208, 23, 215, 205, 220, 6, 208, 23, 215, 205, 216, 180, 233, 42, 56, - 234, 207, 217, 97, 56, 222, 167, 205, 115, 196, 57, 214, 94, 209, 77, - 251, 2, 199, 164, 231, 152, 247, 124, 219, 186, 195, 38, 219, 143, 205, - 80, 205, 183, 247, 106, 251, 34, 209, 120, 63, 243, 105, 221, 138, 63, - 243, 105, 208, 14, 63, 243, 105, 206, 131, 63, 243, 105, 248, 152, 63, - 243, 105, 221, 76, 63, 243, 105, 210, 74, 62, 243, 105, 221, 138, 62, - 243, 105, 208, 14, 62, 243, 105, 206, 131, 62, 243, 105, 248, 152, 62, - 243, 105, 221, 76, 62, 243, 105, 210, 74, 62, 201, 245, 200, 211, 63, - 229, 224, 200, 211, 63, 237, 33, 200, 211, 62, 242, 207, 200, 211, 63, - 201, 245, 200, 211, 62, 229, 224, 200, 211, 62, 237, 33, 200, 211, 63, - 242, 207, 200, 211, 228, 181, 201, 195, 208, 23, 213, 6, 234, 160, 213, - 6, 249, 13, 234, 160, 213, 1, 249, 13, 202, 129, 213, 1, 215, 97, 232, - 207, 56, 215, 97, 214, 206, 56, 215, 97, 203, 127, 56, 193, 105, 200, 63, - 238, 217, 234, 204, 200, 63, 238, 217, 196, 87, 207, 88, 113, 207, 88, - 16, 40, 196, 254, 209, 98, 207, 88, 16, 40, 196, 252, 209, 98, 207, 88, - 16, 40, 196, 251, 209, 98, 207, 88, 16, 40, 196, 249, 209, 98, 207, 88, - 16, 40, 196, 247, 209, 98, 207, 88, 16, 40, 196, 245, 209, 98, 207, 88, - 16, 40, 196, 243, 209, 98, 207, 88, 16, 40, 231, 149, 217, 28, 62, 196, - 87, 207, 88, 113, 207, 89, 210, 136, 113, 210, 104, 210, 136, 113, 210, - 3, 210, 136, 56, 193, 92, 113, 237, 25, 233, 102, 237, 25, 233, 101, 237, - 25, 233, 100, 237, 25, 233, 99, 237, 25, 233, 98, 237, 25, 233, 97, 63, - 243, 11, 4, 75, 183, 63, 243, 11, 4, 105, 236, 138, 62, 243, 11, 4, 63, - 75, 183, 62, 243, 11, 4, 105, 63, 236, 138, 215, 221, 40, 192, 106, 215, - 221, 40, 192, 21, 237, 6, 40, 230, 205, 192, 106, 237, 6, 40, 219, 178, - 192, 21, 237, 6, 40, 219, 178, 192, 106, 237, 6, 40, 230, 205, 192, 21, - 63, 232, 217, 62, 232, 217, 230, 62, 23, 209, 180, 251, 127, 238, 214, - 200, 130, 201, 112, 79, 252, 8, 205, 98, 251, 191, 232, 186, 231, 162, - 201, 112, 79, 229, 191, 250, 172, 113, 232, 202, 211, 10, 63, 201, 102, - 115, 219, 107, 239, 19, 183, 115, 219, 107, 239, 19, 219, 224, 193, 155, - 56, 137, 195, 12, 56, 235, 128, 233, 42, 56, 235, 128, 217, 97, 56, 223, - 105, 233, 42, 23, 217, 97, 56, 217, 97, 23, 233, 42, 56, 217, 97, 4, 201, - 28, 56, 217, 97, 4, 201, 28, 23, 217, 97, 23, 233, 42, 56, 81, 217, 97, - 4, 201, 28, 56, 228, 241, 217, 97, 4, 201, 28, 56, 216, 213, 63, 243, 10, - 216, 213, 62, 243, 10, 216, 213, 2, 63, 243, 10, 217, 48, 113, 236, 198, - 113, 196, 84, 210, 103, 113, 242, 89, 232, 74, 196, 53, 214, 83, 247, 7, - 210, 185, 222, 173, 195, 80, 243, 75, 62, 215, 206, 219, 126, 203, 176, - 204, 22, 208, 4, 203, 255, 202, 36, 249, 111, 249, 73, 112, 221, 222, 63, - 235, 108, 217, 90, 63, 235, 108, 221, 138, 62, 235, 108, 217, 90, 62, - 235, 108, 221, 138, 202, 49, 193, 51, 202, 52, 200, 199, 248, 242, 242, - 210, 207, 149, 62, 202, 48, 198, 210, 242, 211, 23, 207, 149, 153, 63, - 203, 49, 209, 175, 153, 62, 203, 49, 209, 175, 63, 237, 33, 223, 163, - 201, 190, 238, 210, 220, 21, 236, 229, 247, 102, 211, 65, 209, 180, 247, - 103, 202, 85, 229, 201, 4, 63, 238, 217, 47, 238, 210, 220, 21, 246, 253, - 213, 44, 234, 72, 251, 157, 211, 96, 45, 193, 129, 198, 19, 62, 197, 10, - 45, 193, 129, 198, 19, 63, 197, 10, 45, 193, 129, 198, 19, 62, 45, 220, - 22, 216, 179, 63, 45, 220, 22, 216, 179, 235, 103, 202, 76, 56, 88, 63, - 235, 122, 197, 241, 45, 242, 219, 234, 72, 112, 205, 154, 233, 83, 237, - 39, 223, 163, 63, 243, 11, 223, 163, 62, 201, 190, 62, 197, 203, 207, 29, - 45, 234, 71, 207, 29, 45, 234, 70, 250, 187, 16, 40, 196, 57, 88, 243, - 11, 4, 201, 28, 23, 105, 185, 58, 210, 23, 206, 205, 223, 107, 210, 23, - 219, 221, 223, 107, 210, 23, 223, 93, 210, 23, 62, 238, 218, 211, 105, - 203, 78, 203, 66, 203, 12, 243, 40, 247, 80, 229, 118, 202, 137, 231, - 163, 193, 51, 228, 153, 231, 163, 4, 230, 30, 217, 72, 16, 40, 219, 131, - 215, 184, 196, 118, 211, 105, 230, 188, 232, 129, 232, 218, 223, 163, - 229, 5, 233, 32, 205, 178, 51, 232, 128, 239, 0, 202, 108, 228, 27, 202, - 112, 209, 251, 4, 249, 111, 199, 87, 223, 19, 249, 93, 113, 229, 229, - 230, 207, 113, 232, 83, 208, 153, 238, 182, 211, 105, 62, 201, 190, 63, - 232, 218, 4, 228, 241, 82, 62, 201, 29, 62, 205, 188, 205, 84, 116, 248, - 134, 205, 84, 62, 205, 84, 110, 248, 134, 205, 84, 63, 205, 84, 63, 88, - 243, 126, 77, 199, 107, 219, 40, 56, 199, 182, 235, 102, 251, 223, 234, - 67, 207, 147, 232, 231, 207, 147, 230, 53, 195, 67, 230, 53, 193, 3, 230, - 53, 110, 50, 210, 33, 210, 33, 116, 50, 210, 33, 63, 213, 208, 62, 213, - 208, 243, 126, 77, 88, 243, 126, 77, 215, 127, 192, 235, 88, 215, 127, - 192, 235, 249, 107, 192, 235, 88, 249, 107, 192, 235, 211, 10, 35, 238, - 217, 88, 35, 238, 217, 211, 77, 247, 22, 238, 217, 88, 211, 77, 247, 22, - 238, 217, 8, 238, 217, 203, 151, 63, 8, 238, 217, 211, 10, 8, 238, 217, - 217, 93, 238, 217, 201, 103, 79, 237, 208, 232, 128, 199, 127, 250, 193, - 232, 128, 249, 108, 250, 193, 88, 232, 128, 249, 108, 250, 193, 232, 128, - 242, 205, 250, 193, 62, 232, 128, 209, 60, 201, 102, 63, 232, 128, 209, - 60, 201, 102, 201, 240, 201, 38, 211, 10, 63, 201, 102, 47, 63, 201, 102, - 211, 77, 247, 22, 62, 201, 102, 62, 247, 22, 63, 201, 102, 211, 10, 62, - 201, 102, 88, 211, 10, 62, 201, 102, 209, 130, 201, 102, 203, 151, 63, - 201, 102, 88, 250, 193, 211, 77, 247, 22, 250, 193, 234, 164, 201, 206, - 250, 193, 234, 164, 209, 60, 62, 201, 102, 234, 164, 209, 60, 209, 130, - 201, 102, 202, 136, 209, 60, 62, 201, 102, 234, 164, 209, 60, 207, 90, - 62, 201, 102, 88, 234, 164, 209, 60, 207, 90, 62, 201, 102, 197, 38, 209, - 60, 62, 201, 102, 202, 131, 209, 60, 250, 193, 199, 127, 250, 193, 211, - 77, 247, 22, 199, 127, 250, 193, 88, 199, 127, 250, 193, 202, 136, 209, - 239, 62, 23, 63, 232, 189, 62, 232, 189, 63, 232, 189, 234, 164, 209, - 239, 211, 10, 62, 232, 189, 47, 211, 77, 247, 22, 234, 164, 209, 60, 201, - 102, 88, 199, 127, 209, 130, 250, 193, 202, 50, 198, 172, 197, 234, 202, - 50, 88, 243, 101, 202, 50, 201, 242, 88, 201, 242, 249, 108, 250, 193, - 234, 164, 199, 127, 208, 189, 250, 193, 88, 234, 164, 199, 127, 208, 189, - 250, 193, 238, 218, 77, 203, 151, 63, 243, 10, 214, 106, 112, 238, 218, - 77, 110, 50, 235, 98, 63, 201, 190, 116, 50, 235, 98, 63, 201, 190, 110, - 50, 203, 151, 63, 201, 190, 116, 50, 203, 151, 63, 201, 190, 62, 208, 13, - 87, 211, 42, 63, 208, 13, 87, 211, 42, 63, 233, 216, 87, 211, 42, 62, - 237, 33, 216, 35, 63, 192, 235, 88, 233, 216, 87, 113, 156, 81, 164, 216, - 213, 81, 164, 88, 81, 164, 88, 202, 170, 153, 242, 75, 207, 252, 87, 211, - 42, 88, 202, 170, 242, 75, 207, 252, 87, 211, 42, 88, 55, 153, 242, 75, - 207, 252, 87, 211, 42, 88, 55, 242, 75, 207, 252, 87, 211, 42, 88, 130, - 202, 170, 242, 75, 207, 252, 87, 211, 42, 88, 130, 55, 242, 75, 207, 252, - 87, 211, 42, 238, 163, 201, 81, 210, 128, 3, 211, 42, 88, 233, 216, 87, - 211, 42, 88, 229, 224, 233, 216, 87, 211, 42, 88, 62, 229, 223, 206, 122, - 88, 62, 229, 224, 247, 248, 232, 190, 229, 223, 206, 122, 232, 190, 229, - 224, 247, 248, 216, 213, 45, 210, 114, 211, 42, 216, 213, 50, 210, 114, - 211, 42, 216, 213, 232, 203, 45, 210, 114, 211, 42, 216, 213, 232, 203, - 50, 210, 114, 211, 42, 216, 213, 219, 219, 251, 116, 248, 54, 211, 42, - 216, 213, 206, 203, 251, 116, 248, 54, 211, 42, 88, 219, 219, 251, 116, - 207, 252, 87, 211, 42, 88, 206, 203, 251, 116, 207, 252, 87, 211, 42, 88, - 219, 219, 251, 116, 248, 54, 211, 42, 88, 206, 203, 251, 116, 248, 54, - 211, 42, 156, 45, 198, 42, 203, 103, 248, 54, 211, 42, 156, 50, 198, 42, - 203, 103, 248, 54, 211, 42, 216, 213, 45, 238, 171, 248, 54, 211, 42, - 216, 213, 50, 238, 171, 248, 54, 211, 42, 236, 241, 214, 106, 47, 17, - 107, 236, 241, 214, 106, 47, 17, 109, 236, 241, 214, 106, 47, 17, 138, - 236, 241, 214, 106, 47, 17, 134, 236, 241, 214, 106, 47, 17, 149, 236, - 241, 214, 106, 47, 17, 169, 236, 241, 214, 106, 47, 17, 175, 236, 241, - 214, 106, 47, 17, 171, 236, 241, 214, 106, 47, 17, 178, 236, 241, 214, - 106, 47, 31, 199, 95, 236, 241, 47, 49, 17, 107, 236, 241, 47, 49, 17, - 109, 236, 241, 47, 49, 17, 138, 236, 241, 47, 49, 17, 134, 236, 241, 47, - 49, 17, 149, 236, 241, 47, 49, 17, 169, 236, 241, 47, 49, 17, 175, 236, - 241, 47, 49, 17, 171, 236, 241, 47, 49, 17, 178, 236, 241, 47, 49, 31, - 199, 95, 236, 241, 214, 106, 47, 49, 17, 107, 236, 241, 214, 106, 47, 49, - 17, 109, 236, 241, 214, 106, 47, 49, 17, 138, 236, 241, 214, 106, 47, 49, - 17, 134, 236, 241, 214, 106, 47, 49, 17, 149, 236, 241, 214, 106, 47, 49, - 17, 169, 236, 241, 214, 106, 47, 49, 17, 175, 236, 241, 214, 106, 47, 49, - 17, 171, 236, 241, 214, 106, 47, 49, 17, 178, 236, 241, 214, 106, 47, 49, - 31, 199, 95, 88, 193, 77, 96, 57, 88, 108, 56, 88, 216, 35, 56, 88, 236, - 200, 56, 88, 202, 2, 234, 204, 57, 88, 96, 57, 88, 186, 234, 204, 57, - 235, 113, 209, 62, 96, 57, 88, 206, 114, 96, 57, 197, 240, 96, 57, 88, - 197, 240, 96, 57, 237, 214, 197, 240, 96, 57, 88, 237, 214, 197, 240, 96, - 57, 62, 96, 57, 198, 225, 198, 52, 96, 250, 235, 198, 225, 248, 75, 96, - 250, 235, 62, 96, 250, 235, 88, 62, 238, 163, 235, 119, 23, 96, 57, 88, - 62, 238, 163, 196, 66, 23, 96, 57, 201, 187, 62, 96, 57, 88, 239, 56, 62, - 96, 57, 206, 202, 63, 96, 57, 219, 218, 63, 96, 57, 249, 145, 203, 151, - 63, 96, 57, 232, 95, 203, 151, 63, 96, 57, 88, 110, 206, 201, 63, 96, 57, - 88, 116, 206, 201, 63, 96, 57, 213, 8, 110, 206, 201, 63, 96, 57, 238, - 171, 219, 4, 213, 8, 116, 206, 201, 63, 96, 57, 47, 88, 63, 96, 57, 193, - 88, 96, 57, 248, 138, 202, 2, 234, 204, 57, 248, 138, 96, 57, 248, 138, - 186, 234, 204, 57, 88, 248, 138, 202, 2, 234, 204, 57, 88, 248, 138, 96, - 57, 88, 248, 138, 186, 234, 204, 57, 199, 129, 96, 57, 88, 199, 128, 96, - 57, 193, 115, 96, 57, 88, 193, 115, 96, 57, 211, 71, 96, 57, 55, 238, - 171, 219, 4, 115, 236, 251, 251, 115, 63, 197, 242, 239, 33, 2, 63, 197, - 241, 209, 254, 211, 77, 200, 228, 211, 77, 200, 180, 45, 206, 7, 249, - 131, 237, 112, 50, 206, 7, 249, 131, 237, 112, 211, 57, 4, 75, 223, 117, - 207, 19, 202, 24, 208, 230, 200, 228, 200, 181, 208, 230, 202, 23, 81, - 249, 88, 4, 228, 241, 106, 13, 206, 180, 237, 38, 179, 236, 199, 13, 233, - 83, 237, 38, 112, 219, 29, 251, 125, 112, 219, 29, 211, 56, 63, 237, 33, - 4, 247, 20, 236, 140, 23, 4, 236, 140, 234, 132, 79, 211, 69, 196, 65, - 110, 50, 239, 2, 4, 236, 140, 116, 45, 239, 2, 4, 236, 140, 45, 211, 12, - 222, 199, 50, 211, 12, 222, 199, 232, 80, 211, 12, 222, 199, 220, 13, - 133, 199, 228, 220, 13, 144, 199, 228, 45, 23, 50, 55, 197, 57, 45, 23, - 50, 199, 228, 45, 215, 131, 179, 50, 199, 228, 179, 45, 199, 228, 133, - 199, 229, 4, 243, 11, 58, 218, 233, 236, 206, 247, 205, 228, 241, 206, - 52, 63, 239, 55, 237, 32, 63, 239, 55, 237, 33, 4, 118, 198, 182, 63, - 239, 55, 237, 33, 4, 96, 198, 182, 63, 51, 4, 118, 198, 182, 63, 51, 4, - 96, 198, 182, 13, 45, 63, 51, 248, 53, 13, 50, 63, 51, 248, 53, 13, 45, - 251, 116, 248, 53, 13, 50, 251, 116, 248, 53, 13, 45, 55, 251, 116, 248, - 53, 13, 50, 55, 251, 116, 248, 53, 13, 45, 63, 198, 42, 203, 103, 248, - 53, 13, 50, 63, 198, 42, 203, 103, 248, 53, 13, 45, 232, 203, 210, 113, - 13, 50, 232, 203, 210, 113, 196, 66, 208, 26, 57, 235, 119, 208, 26, 57, - 251, 85, 231, 202, 243, 11, 57, 242, 221, 231, 202, 243, 11, 57, 50, 64, - 4, 47, 209, 81, 179, 118, 57, 179, 96, 57, 179, 45, 50, 57, 179, 118, 55, - 57, 179, 96, 55, 57, 179, 45, 50, 55, 57, 179, 118, 64, 232, 98, 164, - 179, 96, 64, 232, 98, 164, 179, 118, 55, 64, 232, 98, 164, 179, 96, 55, - 64, 232, 98, 164, 179, 96, 201, 183, 57, 69, 70, 248, 132, 69, 70, 236, - 137, 69, 70, 236, 9, 69, 70, 236, 136, 69, 70, 235, 201, 69, 70, 236, 72, - 69, 70, 236, 8, 69, 70, 236, 135, 69, 70, 235, 169, 69, 70, 236, 40, 69, - 70, 235, 232, 69, 70, 236, 103, 69, 70, 235, 200, 69, 70, 236, 71, 69, - 70, 236, 7, 69, 70, 236, 134, 69, 70, 235, 153, 69, 70, 236, 24, 69, 70, - 235, 216, 69, 70, 236, 87, 69, 70, 235, 184, 69, 70, 236, 55, 69, 70, - 235, 247, 69, 70, 236, 118, 69, 70, 235, 168, 69, 70, 236, 39, 69, 70, - 235, 231, 69, 70, 236, 102, 69, 70, 235, 199, 69, 70, 236, 70, 69, 70, - 236, 6, 69, 70, 236, 133, 69, 70, 235, 145, 69, 70, 236, 16, 69, 70, 235, - 208, 69, 70, 236, 79, 69, 70, 235, 176, 69, 70, 236, 47, 69, 70, 235, - 239, 69, 70, 236, 110, 69, 70, 235, 160, 69, 70, 236, 31, 69, 70, 235, - 223, 69, 70, 236, 94, 69, 70, 235, 191, 69, 70, 236, 62, 69, 70, 235, - 254, 69, 70, 236, 125, 69, 70, 235, 152, 69, 70, 236, 23, 69, 70, 235, - 215, 69, 70, 236, 86, 69, 70, 235, 183, 69, 70, 236, 54, 69, 70, 235, - 246, 69, 70, 236, 117, 69, 70, 235, 167, 69, 70, 236, 38, 69, 70, 235, - 230, 69, 70, 236, 101, 69, 70, 235, 198, 69, 70, 236, 69, 69, 70, 236, 5, - 69, 70, 236, 132, 69, 70, 235, 141, 69, 70, 236, 12, 69, 70, 235, 204, - 69, 70, 236, 75, 69, 70, 235, 172, 69, 70, 236, 43, 69, 70, 235, 235, 69, - 70, 236, 106, 69, 70, 235, 156, 69, 70, 236, 27, 69, 70, 235, 219, 69, - 70, 236, 90, 69, 70, 235, 187, 69, 70, 236, 58, 69, 70, 235, 250, 69, 70, - 236, 121, 69, 70, 235, 148, 69, 70, 236, 19, 69, 70, 235, 211, 69, 70, - 236, 82, 69, 70, 235, 179, 69, 70, 236, 50, 69, 70, 235, 242, 69, 70, - 236, 113, 69, 70, 235, 163, 69, 70, 236, 34, 69, 70, 235, 226, 69, 70, - 236, 97, 69, 70, 235, 194, 69, 70, 236, 65, 69, 70, 236, 1, 69, 70, 236, - 128, 69, 70, 235, 144, 69, 70, 236, 15, 69, 70, 235, 207, 69, 70, 236, - 78, 69, 70, 235, 175, 69, 70, 236, 46, 69, 70, 235, 238, 69, 70, 236, - 109, 69, 70, 235, 159, 69, 70, 236, 30, 69, 70, 235, 222, 69, 70, 236, - 93, 69, 70, 235, 190, 69, 70, 236, 61, 69, 70, 235, 253, 69, 70, 236, - 124, 69, 70, 235, 151, 69, 70, 236, 22, 69, 70, 235, 214, 69, 70, 236, - 85, 69, 70, 235, 182, 69, 70, 236, 53, 69, 70, 235, 245, 69, 70, 236, - 116, 69, 70, 235, 166, 69, 70, 236, 37, 69, 70, 235, 229, 69, 70, 236, - 100, 69, 70, 235, 197, 69, 70, 236, 68, 69, 70, 236, 4, 69, 70, 236, 131, - 69, 70, 235, 139, 69, 70, 236, 10, 69, 70, 235, 202, 69, 70, 236, 73, 69, - 70, 235, 170, 69, 70, 236, 41, 69, 70, 235, 233, 69, 70, 236, 104, 69, - 70, 235, 154, 69, 70, 236, 25, 69, 70, 235, 217, 69, 70, 236, 88, 69, 70, - 235, 185, 69, 70, 236, 56, 69, 70, 235, 248, 69, 70, 236, 119, 69, 70, - 235, 146, 69, 70, 236, 17, 69, 70, 235, 209, 69, 70, 236, 80, 69, 70, - 235, 177, 69, 70, 236, 48, 69, 70, 235, 240, 69, 70, 236, 111, 69, 70, - 235, 161, 69, 70, 236, 32, 69, 70, 235, 224, 69, 70, 236, 95, 69, 70, - 235, 192, 69, 70, 236, 63, 69, 70, 235, 255, 69, 70, 236, 126, 69, 70, - 235, 142, 69, 70, 236, 13, 69, 70, 235, 205, 69, 70, 236, 76, 69, 70, - 235, 173, 69, 70, 236, 44, 69, 70, 235, 236, 69, 70, 236, 107, 69, 70, - 235, 157, 69, 70, 236, 28, 69, 70, 235, 220, 69, 70, 236, 91, 69, 70, - 235, 188, 69, 70, 236, 59, 69, 70, 235, 251, 69, 70, 236, 122, 69, 70, - 235, 149, 69, 70, 236, 20, 69, 70, 235, 212, 69, 70, 236, 83, 69, 70, - 235, 180, 69, 70, 236, 51, 69, 70, 235, 243, 69, 70, 236, 114, 69, 70, - 235, 164, 69, 70, 236, 35, 69, 70, 235, 227, 69, 70, 236, 98, 69, 70, - 235, 195, 69, 70, 236, 66, 69, 70, 236, 2, 69, 70, 236, 129, 69, 70, 235, - 140, 69, 70, 236, 11, 69, 70, 235, 203, 69, 70, 236, 74, 69, 70, 235, - 171, 69, 70, 236, 42, 69, 70, 235, 234, 69, 70, 236, 105, 69, 70, 235, - 155, 69, 70, 236, 26, 69, 70, 235, 218, 69, 70, 236, 89, 69, 70, 235, - 186, 69, 70, 236, 57, 69, 70, 235, 249, 69, 70, 236, 120, 69, 70, 235, - 147, 69, 70, 236, 18, 69, 70, 235, 210, 69, 70, 236, 81, 69, 70, 235, - 178, 69, 70, 236, 49, 69, 70, 235, 241, 69, 70, 236, 112, 69, 70, 235, - 162, 69, 70, 236, 33, 69, 70, 235, 225, 69, 70, 236, 96, 69, 70, 235, - 193, 69, 70, 236, 64, 69, 70, 236, 0, 69, 70, 236, 127, 69, 70, 235, 143, - 69, 70, 236, 14, 69, 70, 235, 206, 69, 70, 236, 77, 69, 70, 235, 174, 69, - 70, 236, 45, 69, 70, 235, 237, 69, 70, 236, 108, 69, 70, 235, 158, 69, - 70, 236, 29, 69, 70, 235, 221, 69, 70, 236, 92, 69, 70, 235, 189, 69, 70, - 236, 60, 69, 70, 235, 252, 69, 70, 236, 123, 69, 70, 235, 150, 69, 70, - 236, 21, 69, 70, 235, 213, 69, 70, 236, 84, 69, 70, 235, 181, 69, 70, - 236, 52, 69, 70, 235, 244, 69, 70, 236, 115, 69, 70, 235, 165, 69, 70, - 236, 36, 69, 70, 235, 228, 69, 70, 236, 99, 69, 70, 235, 196, 69, 70, - 236, 67, 69, 70, 236, 3, 69, 70, 236, 130, 96, 197, 13, 64, 4, 81, 106, - 96, 197, 13, 64, 4, 55, 81, 106, 118, 55, 64, 4, 81, 106, 96, 55, 64, 4, - 81, 106, 45, 50, 55, 64, 4, 81, 106, 96, 197, 13, 64, 232, 98, 164, 118, - 55, 64, 232, 98, 164, 96, 55, 64, 232, 98, 164, 235, 119, 64, 4, 228, - 241, 106, 196, 66, 64, 4, 228, 241, 106, 196, 66, 197, 225, 57, 235, 119, - 197, 225, 57, 118, 55, 237, 216, 57, 96, 55, 237, 216, 57, 118, 197, 225, - 237, 216, 57, 96, 197, 225, 237, 216, 57, 96, 197, 13, 197, 225, 237, - 216, 57, 96, 64, 4, 235, 138, 201, 80, 196, 66, 64, 119, 164, 235, 119, - 64, 119, 164, 96, 64, 4, 199, 216, 4, 81, 106, 96, 64, 4, 199, 216, 4, - 55, 81, 106, 96, 197, 13, 64, 4, 199, 215, 96, 197, 13, 64, 4, 199, 216, - 4, 81, 106, 96, 197, 13, 64, 4, 199, 216, 4, 55, 81, 106, 118, 250, 237, - 96, 250, 237, 118, 55, 250, 237, 96, 55, 250, 237, 118, 64, 119, 62, 237, - 32, 96, 64, 119, 62, 237, 32, 118, 64, 232, 98, 249, 88, 119, 62, 237, - 32, 96, 64, 232, 98, 249, 88, 119, 62, 237, 32, 186, 193, 105, 23, 202, - 2, 234, 204, 57, 186, 234, 204, 23, 202, 2, 193, 105, 57, 186, 193, 105, - 64, 4, 102, 186, 234, 204, 64, 4, 102, 202, 2, 234, 204, 64, 4, 102, 202, - 2, 193, 105, 64, 4, 102, 186, 193, 105, 64, 23, 186, 234, 204, 57, 186, - 234, 204, 64, 23, 202, 2, 234, 204, 57, 202, 2, 234, 204, 64, 23, 202, 2, - 193, 105, 57, 202, 2, 193, 105, 64, 23, 186, 193, 105, 57, 206, 180, 237, - 39, 238, 210, 233, 83, 237, 38, 233, 83, 237, 39, 238, 210, 206, 180, - 237, 38, 202, 2, 234, 204, 64, 238, 210, 186, 234, 204, 57, 186, 234, - 204, 64, 238, 210, 202, 2, 234, 204, 57, 233, 83, 237, 39, 238, 210, 186, - 234, 204, 57, 206, 180, 237, 39, 238, 210, 202, 2, 234, 204, 57, 186, - 234, 204, 64, 238, 210, 186, 193, 105, 57, 186, 193, 105, 64, 238, 210, - 186, 234, 204, 57, 193, 139, 64, 209, 58, 236, 231, 183, 64, 209, 58, 96, - 199, 25, 238, 161, 196, 65, 64, 209, 58, 96, 199, 25, 238, 161, 235, 118, - 64, 209, 58, 235, 119, 199, 25, 238, 161, 219, 214, 64, 209, 58, 235, - 119, 199, 25, 238, 161, 206, 197, 206, 200, 251, 17, 242, 221, 57, 219, - 217, 251, 17, 251, 85, 57, 198, 54, 251, 17, 251, 85, 57, 248, 77, 251, - 17, 251, 85, 57, 198, 54, 251, 17, 242, 221, 64, 4, 216, 34, 198, 54, - 251, 17, 251, 85, 64, 4, 209, 81, 110, 50, 204, 27, 242, 221, 57, 110, - 45, 204, 27, 251, 85, 57, 251, 85, 242, 219, 243, 11, 57, 242, 221, 242, - 219, 243, 11, 57, 96, 64, 93, 203, 40, 118, 57, 118, 64, 93, 203, 40, 96, - 57, 203, 40, 96, 64, 93, 118, 57, 96, 64, 4, 108, 60, 118, 64, 4, 108, - 60, 96, 64, 198, 216, 192, 235, 45, 50, 64, 198, 216, 2, 243, 10, 196, - 66, 197, 13, 64, 232, 98, 2, 243, 10, 45, 181, 133, 50, 181, 144, 230, - 12, 45, 181, 144, 50, 181, 133, 230, 12, 133, 181, 50, 144, 181, 45, 230, - 12, 133, 181, 45, 144, 181, 50, 230, 12, 45, 181, 133, 50, 181, 133, 230, - 12, 133, 181, 50, 144, 181, 50, 230, 12, 45, 181, 144, 50, 181, 144, 230, - 12, 133, 181, 45, 144, 181, 45, 230, 12, 118, 230, 13, 4, 181, 133, 119, - 164, 96, 230, 13, 4, 181, 133, 119, 164, 196, 66, 230, 13, 4, 181, 50, - 119, 164, 235, 119, 230, 13, 4, 181, 50, 119, 164, 118, 230, 13, 4, 181, - 144, 119, 164, 96, 230, 13, 4, 181, 144, 119, 164, 196, 66, 230, 13, 4, - 181, 45, 119, 164, 235, 119, 230, 13, 4, 181, 45, 119, 164, 118, 230, 13, - 4, 181, 133, 232, 98, 164, 96, 230, 13, 4, 181, 133, 232, 98, 164, 196, - 66, 230, 13, 4, 181, 50, 232, 98, 164, 235, 119, 230, 13, 4, 181, 50, - 232, 98, 164, 118, 230, 13, 4, 181, 144, 232, 98, 164, 96, 230, 13, 4, - 181, 144, 232, 98, 164, 196, 66, 230, 13, 4, 181, 45, 232, 98, 164, 235, - 119, 230, 13, 4, 181, 45, 232, 98, 164, 118, 230, 13, 4, 181, 133, 93, - 118, 230, 13, 4, 181, 235, 123, 196, 66, 230, 13, 4, 181, 45, 248, 216, - 196, 66, 230, 13, 4, 181, 183, 96, 230, 13, 4, 181, 133, 93, 96, 230, 13, - 4, 181, 235, 123, 235, 119, 230, 13, 4, 181, 45, 248, 216, 235, 119, 230, - 13, 4, 181, 183, 118, 230, 13, 4, 181, 133, 93, 96, 230, 13, 4, 181, 196, - 77, 118, 230, 13, 4, 181, 144, 93, 96, 230, 13, 4, 181, 235, 123, 96, - 230, 13, 4, 181, 133, 93, 118, 230, 13, 4, 181, 196, 77, 96, 230, 13, 4, - 181, 144, 93, 118, 230, 13, 4, 181, 235, 123, 118, 230, 13, 4, 181, 133, - 93, 179, 237, 215, 118, 230, 13, 4, 181, 144, 248, 233, 179, 237, 215, - 96, 230, 13, 4, 181, 133, 93, 179, 237, 215, 96, 230, 13, 4, 181, 144, - 248, 233, 179, 237, 215, 196, 66, 230, 13, 4, 181, 45, 248, 216, 235, - 119, 230, 13, 4, 181, 183, 235, 119, 230, 13, 4, 181, 45, 248, 216, 196, - 66, 230, 13, 4, 181, 183, 50, 55, 64, 4, 206, 113, 229, 235, 234, 43, 3, - 93, 96, 57, 198, 153, 211, 67, 93, 96, 57, 118, 64, 93, 198, 153, 211, - 66, 96, 64, 93, 198, 153, 211, 66, 96, 64, 93, 251, 165, 234, 45, 159, - 219, 180, 93, 118, 57, 118, 64, 198, 216, 219, 179, 230, 204, 93, 96, 57, - 200, 229, 93, 96, 57, 118, 64, 198, 216, 200, 228, 200, 181, 93, 118, 57, - 45, 232, 237, 199, 215, 50, 232, 237, 199, 215, 133, 232, 237, 199, 215, - 144, 232, 237, 199, 215, 197, 225, 81, 249, 88, 237, 112, 191, 167, 213, - 10, 201, 201, 191, 167, 213, 10, 196, 255, 242, 83, 45, 63, 238, 171, - 248, 53, 50, 63, 238, 171, 248, 53, 45, 63, 210, 113, 50, 63, 210, 113, - 191, 167, 213, 10, 45, 223, 178, 248, 53, 191, 167, 213, 10, 50, 223, - 178, 248, 53, 191, 167, 213, 10, 45, 248, 166, 248, 53, 191, 167, 213, - 10, 50, 248, 166, 248, 53, 45, 51, 248, 54, 4, 196, 103, 50, 51, 248, 54, - 4, 196, 103, 45, 51, 248, 54, 4, 198, 183, 223, 163, 198, 54, 239, 1, 50, - 51, 248, 54, 4, 198, 183, 223, 163, 248, 77, 239, 1, 45, 51, 248, 54, 4, - 198, 183, 223, 163, 248, 77, 239, 1, 50, 51, 248, 54, 4, 198, 183, 223, - 163, 198, 54, 239, 1, 45, 251, 116, 248, 54, 4, 236, 140, 50, 251, 116, - 248, 54, 4, 236, 140, 45, 251, 17, 219, 180, 248, 53, 50, 251, 17, 230, - 204, 248, 53, 55, 45, 251, 17, 230, 204, 248, 53, 55, 50, 251, 17, 219, - 180, 248, 53, 45, 62, 198, 42, 203, 103, 248, 53, 50, 62, 198, 42, 203, - 103, 248, 53, 235, 138, 233, 39, 81, 191, 21, 219, 112, 216, 226, 251, - 116, 211, 69, 219, 224, 50, 251, 116, 195, 168, 4, 201, 190, 216, 226, - 50, 251, 116, 4, 236, 140, 251, 116, 4, 206, 9, 223, 117, 252, 47, 251, - 115, 201, 225, 251, 116, 211, 69, 219, 224, 201, 225, 251, 116, 211, 69, - 196, 77, 153, 251, 115, 207, 18, 251, 115, 251, 116, 4, 196, 103, 207, - 18, 251, 116, 4, 196, 103, 211, 172, 251, 116, 211, 69, 196, 77, 211, - 172, 251, 116, 211, 69, 235, 123, 216, 226, 251, 116, 4, 211, 77, 250, - 251, 234, 91, 223, 163, 64, 209, 58, 133, 23, 183, 216, 226, 251, 116, 4, - 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, 133, 23, 219, 224, - 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, - 144, 23, 183, 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, - 163, 64, 209, 58, 144, 23, 219, 224, 216, 226, 251, 116, 4, 211, 77, 250, - 251, 234, 91, 223, 163, 64, 209, 58, 50, 23, 196, 77, 216, 226, 251, 116, - 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, 45, 23, 196, 77, - 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, - 50, 23, 235, 123, 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, - 163, 64, 209, 58, 45, 23, 235, 123, 207, 18, 234, 105, 203, 252, 234, - 105, 203, 253, 4, 211, 6, 234, 105, 203, 253, 4, 2, 243, 11, 58, 234, - 105, 203, 253, 4, 50, 64, 58, 234, 105, 203, 253, 4, 45, 64, 58, 243, 11, - 4, 228, 241, 164, 47, 81, 164, 47, 210, 118, 47, 207, 19, 202, 23, 47, - 209, 254, 243, 11, 236, 206, 247, 205, 228, 241, 249, 88, 23, 198, 54, - 132, 236, 206, 247, 205, 81, 164, 243, 11, 4, 200, 183, 192, 235, 47, - 251, 83, 236, 200, 56, 133, 64, 198, 216, 243, 10, 47, 63, 247, 248, 47, - 247, 248, 47, 219, 179, 47, 230, 203, 243, 11, 4, 2, 243, 11, 119, 199, - 34, 183, 243, 11, 4, 105, 228, 241, 201, 16, 119, 199, 34, 183, 112, 206, - 180, 237, 39, 202, 97, 112, 233, 83, 237, 39, 202, 97, 112, 250, 193, - 112, 2, 243, 10, 112, 201, 190, 105, 222, 198, 201, 188, 197, 242, 4, 75, - 58, 197, 242, 4, 196, 103, 206, 9, 223, 163, 197, 241, 197, 242, 4, 204, - 4, 250, 183, 248, 76, 50, 197, 242, 93, 45, 197, 241, 45, 197, 242, 248, - 216, 81, 164, 81, 249, 88, 248, 216, 50, 197, 241, 248, 64, 4, 45, 132, - 248, 139, 248, 64, 4, 50, 132, 248, 139, 62, 248, 63, 25, 4, 45, 132, - 248, 139, 25, 4, 50, 132, 248, 139, 63, 228, 174, 62, 228, 174, 45, 193, - 72, 233, 39, 50, 193, 72, 233, 39, 45, 55, 193, 72, 233, 39, 50, 55, 193, - 72, 233, 39, 223, 155, 223, 139, 198, 179, 139, 223, 139, 223, 140, 214, - 108, 4, 81, 164, 235, 132, 215, 131, 51, 4, 239, 25, 211, 11, 223, 152, - 250, 219, 202, 254, 208, 200, 234, 43, 3, 23, 202, 99, 210, 118, 234, 43, - 3, 23, 202, 99, 210, 119, 4, 198, 153, 58, 228, 17, 119, 23, 202, 99, - 210, 118, 231, 14, 201, 101, 199, 22, 235, 122, 197, 242, 4, 45, 132, - 248, 139, 235, 122, 197, 242, 4, 50, 132, 248, 139, 62, 237, 33, 4, 144, - 57, 62, 218, 232, 63, 243, 11, 4, 144, 57, 62, 243, 11, 4, 144, 57, 234, - 25, 63, 201, 190, 234, 25, 62, 201, 190, 234, 25, 63, 237, 32, 234, 25, - 62, 237, 32, 234, 25, 63, 243, 10, 234, 25, 62, 243, 10, 206, 51, 207, - 19, 202, 24, 211, 66, 202, 24, 4, 211, 6, 207, 19, 202, 24, 4, 228, 241, - 106, 248, 175, 202, 23, 248, 175, 207, 19, 202, 23, 55, 209, 81, 197, - 225, 209, 81, 219, 219, 238, 163, 251, 116, 248, 53, 206, 203, 238, 163, - 251, 116, 248, 53, 198, 137, 216, 32, 215, 60, 47, 75, 211, 66, 215, 60, - 47, 108, 211, 66, 215, 60, 47, 25, 211, 66, 215, 60, 196, 93, 211, 67, 4, - 236, 140, 215, 60, 196, 93, 211, 67, 4, 209, 81, 215, 60, 51, 223, 100, - 211, 66, 215, 60, 51, 196, 93, 211, 66, 105, 219, 29, 23, 211, 66, 105, - 219, 29, 211, 57, 211, 66, 215, 60, 25, 211, 66, 215, 236, 105, 200, 204, - 200, 202, 4, 223, 113, 208, 26, 223, 114, 211, 66, 232, 246, 210, 107, - 223, 113, 223, 114, 4, 55, 106, 223, 114, 250, 143, 4, 202, 97, 243, 3, - 232, 76, 251, 85, 223, 111, 219, 113, 223, 112, 4, 207, 91, 210, 86, 250, - 245, 209, 52, 219, 113, 223, 112, 4, 204, 27, 210, 86, 250, 245, 209, 52, - 219, 113, 223, 112, 213, 12, 223, 157, 199, 34, 209, 52, 223, 114, 250, - 245, 42, 209, 62, 211, 66, 208, 19, 223, 114, 211, 66, 223, 114, 4, 118, - 64, 4, 102, 223, 114, 4, 25, 56, 223, 114, 4, 223, 99, 223, 114, 4, 196, - 92, 223, 114, 4, 211, 6, 223, 114, 4, 196, 103, 222, 199, 220, 13, 45, - 197, 242, 211, 66, 191, 167, 213, 10, 205, 92, 239, 62, 191, 167, 213, - 10, 205, 92, 209, 126, 191, 167, 213, 10, 205, 92, 208, 195, 108, 3, 4, - 2, 243, 11, 58, 108, 3, 4, 243, 2, 252, 61, 58, 108, 3, 4, 198, 153, 58, - 108, 3, 4, 75, 60, 108, 3, 4, 198, 153, 60, 108, 3, 4, 200, 230, 109, - 108, 3, 4, 62, 197, 241, 216, 35, 3, 4, 242, 75, 58, 216, 35, 3, 4, 75, - 60, 216, 35, 3, 4, 233, 83, 236, 138, 216, 35, 3, 4, 206, 180, 236, 138, - 108, 3, 223, 163, 45, 132, 243, 10, 108, 3, 223, 163, 50, 132, 243, 10, - 195, 152, 211, 57, 238, 218, 208, 200, 215, 127, 3, 4, 75, 58, 215, 127, - 3, 4, 196, 103, 204, 24, 208, 201, 4, 248, 77, 242, 218, 202, 68, 208, - 200, 215, 127, 3, 223, 163, 45, 132, 243, 10, 215, 127, 3, 223, 163, 50, - 132, 243, 10, 47, 215, 127, 3, 4, 243, 2, 252, 60, 215, 127, 3, 223, 163, - 55, 243, 10, 47, 236, 200, 56, 108, 3, 223, 163, 197, 241, 216, 35, 3, - 223, 163, 197, 241, 215, 127, 3, 223, 163, 197, 241, 223, 108, 208, 200, - 206, 198, 223, 108, 208, 200, 191, 167, 213, 10, 207, 64, 239, 62, 251, - 147, 211, 57, 239, 9, 223, 100, 4, 236, 140, 196, 93, 4, 216, 35, 56, - 196, 93, 4, 211, 6, 223, 100, 4, 211, 6, 223, 100, 4, 219, 29, 251, 125, - 196, 93, 4, 219, 29, 211, 56, 196, 93, 93, 223, 99, 223, 100, 93, 196, - 92, 196, 93, 93, 249, 88, 93, 223, 99, 223, 100, 93, 249, 88, 93, 196, - 92, 196, 93, 248, 216, 23, 222, 198, 4, 196, 92, 223, 100, 248, 216, 23, - 222, 198, 4, 223, 99, 242, 219, 196, 93, 4, 204, 3, 242, 219, 223, 100, - 4, 204, 3, 55, 51, 223, 99, 55, 51, 196, 92, 242, 219, 196, 93, 4, 204, - 4, 23, 202, 68, 208, 200, 219, 29, 23, 4, 75, 58, 219, 29, 211, 57, 4, - 75, 58, 55, 219, 29, 251, 125, 55, 219, 29, 211, 56, 105, 223, 101, 219, - 29, 251, 125, 105, 223, 101, 219, 29, 211, 56, 202, 80, 220, 13, 211, 56, - 202, 80, 220, 13, 251, 125, 219, 29, 211, 57, 211, 1, 219, 29, 251, 125, - 219, 29, 23, 4, 82, 201, 80, 219, 29, 211, 57, 4, 82, 201, 80, 219, 29, - 23, 4, 228, 241, 237, 215, 219, 29, 211, 57, 4, 228, 241, 237, 215, 219, - 29, 23, 4, 55, 211, 6, 219, 29, 23, 4, 196, 103, 219, 29, 23, 4, 55, 196, - 103, 2, 195, 149, 4, 196, 103, 219, 29, 211, 57, 4, 55, 211, 6, 219, 29, - 211, 57, 4, 55, 196, 103, 191, 167, 213, 10, 236, 152, 251, 75, 191, 167, - 213, 10, 207, 137, 251, 75, 234, 43, 3, 4, 75, 60, 228, 17, 4, 75, 58, - 197, 225, 228, 241, 249, 88, 4, 55, 81, 106, 197, 225, 228, 241, 249, 88, - 4, 197, 225, 81, 106, 198, 153, 211, 67, 4, 75, 58, 198, 153, 211, 67, 4, - 206, 180, 236, 138, 202, 180, 216, 35, 202, 179, 239, 49, 4, 75, 58, 234, - 43, 4, 250, 193, 251, 165, 234, 45, 119, 4, 243, 2, 252, 60, 251, 40, - 234, 45, 211, 57, 234, 45, 159, 234, 43, 3, 93, 108, 56, 108, 3, 93, 234, - 43, 56, 234, 43, 3, 93, 198, 153, 211, 66, 55, 242, 84, 234, 44, 105, - 239, 41, 234, 43, 202, 194, 115, 239, 41, 234, 43, 202, 194, 234, 43, 3, - 4, 105, 185, 93, 23, 105, 185, 60, 234, 36, 4, 232, 128, 185, 58, 219, - 180, 4, 243, 11, 223, 117, 230, 204, 4, 243, 11, 223, 117, 219, 180, 4, - 208, 13, 87, 58, 230, 204, 4, 208, 13, 87, 58, 219, 180, 211, 57, 202, - 99, 234, 45, 159, 230, 204, 211, 57, 202, 99, 234, 45, 159, 219, 180, - 211, 57, 202, 99, 234, 45, 119, 4, 75, 223, 117, 230, 204, 211, 57, 202, - 99, 234, 45, 119, 4, 75, 223, 117, 219, 180, 211, 57, 202, 99, 234, 45, - 119, 4, 75, 58, 230, 204, 211, 57, 202, 99, 234, 45, 119, 4, 75, 58, 219, - 180, 211, 57, 202, 99, 234, 45, 119, 4, 75, 93, 183, 230, 204, 211, 57, - 202, 99, 234, 45, 119, 4, 75, 93, 219, 224, 219, 180, 211, 57, 251, 41, - 230, 204, 211, 57, 251, 41, 219, 180, 23, 202, 168, 213, 12, 234, 45, - 159, 230, 204, 23, 202, 168, 213, 12, 234, 45, 159, 219, 180, 23, 213, - 12, 251, 41, 230, 204, 23, 213, 12, 251, 41, 219, 180, 93, 235, 131, 234, - 45, 93, 230, 203, 230, 204, 93, 235, 131, 234, 45, 93, 219, 179, 219, - 180, 93, 202, 180, 211, 57, 234, 44, 230, 204, 93, 202, 180, 211, 57, - 234, 44, 219, 180, 93, 202, 180, 93, 230, 203, 230, 204, 93, 202, 180, - 93, 219, 179, 219, 180, 93, 230, 204, 93, 235, 131, 234, 44, 230, 204, - 93, 219, 180, 93, 235, 131, 234, 44, 219, 180, 93, 202, 99, 234, 45, 93, - 230, 204, 93, 202, 99, 234, 44, 230, 204, 93, 202, 99, 234, 45, 93, 219, - 180, 93, 202, 99, 234, 44, 202, 99, 234, 45, 119, 211, 57, 219, 179, 202, - 99, 234, 45, 119, 211, 57, 230, 203, 202, 99, 234, 45, 119, 211, 57, 219, - 180, 4, 75, 223, 117, 202, 99, 234, 45, 119, 211, 57, 230, 204, 4, 75, - 223, 117, 235, 131, 234, 45, 119, 211, 57, 219, 179, 235, 131, 234, 45, - 119, 211, 57, 230, 203, 235, 131, 202, 99, 234, 45, 119, 211, 57, 219, - 179, 235, 131, 202, 99, 234, 45, 119, 211, 57, 230, 203, 202, 180, 211, - 57, 219, 179, 202, 180, 211, 57, 230, 203, 202, 180, 93, 219, 180, 93, - 234, 43, 56, 202, 180, 93, 230, 204, 93, 234, 43, 56, 55, 214, 88, 219, - 179, 55, 214, 88, 230, 203, 55, 214, 88, 219, 180, 4, 196, 103, 230, 204, - 211, 1, 219, 179, 230, 204, 248, 216, 219, 179, 219, 180, 242, 219, 247, - 205, 238, 164, 230, 204, 242, 219, 247, 205, 238, 164, 219, 180, 242, - 219, 247, 205, 238, 165, 93, 202, 99, 234, 44, 230, 204, 242, 219, 247, - 205, 238, 165, 93, 202, 99, 234, 44, 202, 69, 199, 38, 220, 11, 199, 38, - 202, 69, 199, 39, 211, 57, 234, 45, 159, 220, 11, 199, 39, 211, 57, 234, - 45, 159, 234, 43, 3, 4, 247, 241, 58, 208, 232, 93, 202, 168, 234, 43, - 56, 200, 221, 93, 202, 168, 234, 43, 56, 208, 232, 93, 202, 168, 213, 12, - 234, 45, 159, 200, 221, 93, 202, 168, 213, 12, 234, 45, 159, 208, 232, - 93, 234, 43, 56, 200, 221, 93, 234, 43, 56, 208, 232, 93, 213, 12, 234, - 45, 159, 200, 221, 93, 213, 12, 234, 45, 159, 208, 232, 93, 251, 165, - 234, 45, 159, 200, 221, 93, 251, 165, 234, 45, 159, 208, 232, 93, 213, - 12, 251, 165, 234, 45, 159, 200, 221, 93, 213, 12, 251, 165, 234, 45, - 159, 55, 208, 231, 55, 200, 220, 200, 229, 4, 236, 140, 200, 181, 4, 236, - 140, 200, 229, 4, 108, 3, 60, 200, 181, 4, 108, 3, 60, 200, 229, 4, 215, - 127, 3, 60, 200, 181, 4, 215, 127, 3, 60, 200, 229, 79, 211, 57, 234, 45, - 119, 4, 75, 58, 200, 181, 79, 211, 57, 234, 45, 119, 4, 75, 58, 200, 229, - 79, 93, 234, 43, 56, 200, 181, 79, 93, 234, 43, 56, 200, 229, 79, 93, - 198, 153, 211, 66, 200, 181, 79, 93, 198, 153, 211, 66, 200, 229, 79, 93, - 251, 165, 234, 45, 159, 200, 181, 79, 93, 251, 165, 234, 45, 159, 200, - 229, 79, 93, 213, 12, 234, 45, 159, 200, 181, 79, 93, 213, 12, 234, 45, - 159, 51, 45, 211, 77, 111, 211, 66, 51, 50, 211, 77, 111, 211, 66, 242, - 219, 200, 228, 242, 219, 200, 180, 242, 219, 200, 229, 211, 57, 234, 45, - 159, 242, 219, 200, 181, 211, 57, 234, 45, 159, 200, 229, 93, 200, 180, - 200, 181, 93, 200, 228, 200, 229, 93, 200, 228, 200, 181, 93, 200, 180, - 200, 181, 248, 216, 200, 228, 200, 181, 248, 216, 23, 222, 198, 247, 205, - 237, 216, 4, 200, 228, 234, 132, 79, 211, 69, 235, 118, 209, 116, 4, 199, - 122, 198, 53, 198, 7, 223, 99, 232, 147, 213, 27, 203, 40, 45, 199, 228, - 203, 40, 144, 199, 228, 203, 40, 133, 199, 228, 209, 255, 4, 206, 8, 81, - 249, 88, 197, 225, 50, 197, 57, 55, 81, 249, 88, 45, 197, 57, 81, 249, - 88, 55, 45, 197, 57, 55, 81, 249, 88, 55, 45, 197, 57, 179, 237, 216, - 232, 98, 45, 216, 191, 79, 55, 195, 135, 203, 40, 144, 199, 229, 4, 211, - 6, 203, 40, 133, 199, 229, 4, 196, 103, 203, 40, 133, 199, 229, 93, 203, - 40, 144, 199, 228, 55, 144, 199, 228, 55, 133, 199, 228, 55, 201, 28, - 213, 12, 56, 207, 18, 55, 201, 28, 213, 12, 56, 236, 164, 213, 12, 236, - 208, 4, 207, 18, 214, 107, 202, 97, 81, 219, 113, 4, 243, 11, 58, 81, - 219, 113, 4, 243, 11, 60, 144, 199, 229, 4, 243, 11, 60, 210, 119, 4, - 228, 241, 106, 210, 119, 4, 198, 153, 211, 66, 197, 225, 81, 249, 88, - 248, 168, 207, 65, 197, 225, 81, 249, 88, 4, 228, 241, 106, 197, 225, - 242, 84, 211, 66, 197, 225, 214, 88, 219, 179, 197, 225, 214, 88, 230, - 203, 235, 131, 202, 99, 219, 180, 211, 57, 234, 45, 159, 235, 131, 202, - 99, 230, 204, 211, 57, 234, 45, 159, 197, 225, 202, 24, 248, 168, 207, - 65, 220, 13, 197, 225, 81, 249, 88, 211, 66, 55, 202, 24, 211, 66, 63, - 81, 164, 215, 60, 63, 81, 164, 186, 234, 204, 63, 57, 186, 193, 105, 63, - 57, 202, 2, 234, 204, 63, 57, 202, 2, 193, 105, 63, 57, 45, 50, 63, 57, - 118, 62, 57, 196, 66, 62, 57, 235, 119, 62, 57, 186, 234, 204, 62, 57, - 186, 193, 105, 62, 57, 202, 2, 234, 204, 62, 57, 202, 2, 193, 105, 62, - 57, 45, 50, 62, 57, 133, 144, 62, 57, 96, 64, 4, 198, 136, 235, 118, 96, - 64, 4, 198, 136, 196, 65, 118, 64, 4, 198, 136, 235, 118, 118, 64, 4, - 198, 136, 196, 65, 51, 4, 198, 54, 132, 248, 139, 51, 4, 248, 77, 132, - 248, 139, 51, 4, 116, 50, 237, 39, 132, 248, 139, 51, 4, 110, 45, 237, - 39, 132, 248, 139, 237, 33, 4, 45, 132, 248, 139, 237, 33, 4, 50, 132, - 248, 139, 237, 33, 4, 198, 54, 132, 248, 139, 237, 33, 4, 248, 77, 132, - 248, 139, 235, 138, 201, 190, 62, 220, 13, 201, 190, 63, 220, 13, 201, - 190, 62, 195, 83, 2, 201, 190, 63, 195, 83, 2, 201, 190, 62, 210, 24, 63, - 210, 24, 63, 229, 182, 62, 229, 182, 228, 241, 62, 229, 182, 62, 220, 13, - 243, 10, 62, 216, 213, 237, 32, 63, 216, 213, 237, 32, 62, 216, 213, 218, - 232, 63, 216, 213, 218, 232, 62, 2, 237, 32, 62, 2, 218, 232, 63, 2, 218, - 232, 62, 228, 241, 234, 121, 63, 228, 241, 234, 121, 62, 81, 234, 121, - 63, 81, 234, 121, 45, 64, 4, 2, 243, 10, 115, 118, 250, 231, 45, 64, 4, - 47, 209, 81, 179, 118, 201, 183, 57, 118, 197, 13, 64, 4, 81, 106, 118, - 197, 13, 64, 4, 55, 81, 106, 118, 197, 13, 64, 232, 98, 164, 118, 197, - 13, 197, 225, 237, 216, 57, 118, 64, 4, 235, 138, 201, 80, 118, 64, 4, - 199, 216, 4, 81, 106, 118, 64, 4, 199, 216, 4, 55, 81, 106, 118, 197, 13, - 64, 4, 199, 215, 118, 197, 13, 64, 4, 199, 216, 4, 81, 106, 118, 197, 13, - 64, 4, 199, 216, 4, 55, 81, 106, 118, 64, 198, 216, 192, 235, 193, 139, - 64, 209, 58, 236, 231, 219, 224, 234, 43, 3, 93, 118, 57, 207, 19, 198, - 153, 211, 67, 93, 118, 57, 118, 64, 93, 207, 19, 251, 165, 234, 45, 159, - 96, 64, 198, 216, 230, 203, 96, 64, 198, 216, 200, 180, 118, 208, 26, 57, - 96, 208, 26, 57, 207, 19, 198, 153, 211, 67, 93, 96, 57, 96, 64, 93, 207, - 19, 251, 165, 234, 45, 159, 198, 153, 211, 67, 93, 118, 57, 118, 64, 93, - 251, 165, 234, 45, 159, 118, 64, 93, 207, 19, 198, 153, 211, 66, 96, 64, - 93, 207, 19, 198, 153, 211, 66, 235, 119, 197, 240, 191, 21, 57, 203, 40, - 202, 99, 186, 57, 203, 40, 249, 143, 202, 2, 57, 63, 216, 213, 201, 102, - 62, 2, 201, 102, 63, 2, 201, 102, 62, 206, 203, 210, 24, 63, 206, 203, - 210, 24, 88, 220, 13, 243, 10, 88, 211, 8, 4, 211, 8, 223, 117, 88, 243, - 11, 4, 243, 11, 223, 117, 88, 243, 10, 88, 47, 205, 154, 202, 99, 186, - 64, 4, 228, 250, 229, 235, 249, 143, 202, 2, 64, 4, 228, 250, 199, 215, - 202, 99, 186, 64, 4, 228, 241, 199, 215, 249, 143, 202, 2, 64, 4, 228, - 241, 199, 215, 248, 224, 64, 209, 58, 235, 119, 199, 25, 186, 234, 203, - 203, 40, 248, 224, 64, 209, 58, 235, 119, 199, 25, 186, 234, 203, 118, - 197, 240, 57, 196, 66, 197, 240, 57, 96, 197, 240, 57, 235, 119, 197, - 240, 57, 45, 50, 197, 240, 57, 133, 144, 197, 240, 57, 186, 193, 105, - 197, 240, 57, 186, 234, 204, 197, 240, 57, 202, 2, 234, 204, 197, 240, - 57, 202, 2, 193, 105, 197, 240, 57, 118, 197, 240, 237, 214, 57, 196, 66, - 197, 240, 237, 214, 57, 96, 197, 240, 237, 214, 57, 235, 119, 197, 240, - 237, 214, 57, 242, 221, 197, 240, 211, 77, 243, 11, 57, 251, 85, 197, - 240, 211, 77, 243, 11, 57, 118, 197, 240, 64, 119, 164, 196, 66, 197, - 240, 64, 119, 164, 96, 197, 240, 64, 119, 164, 235, 119, 197, 240, 64, - 119, 164, 186, 193, 105, 197, 240, 64, 119, 164, 186, 234, 204, 197, 240, - 64, 119, 164, 202, 2, 234, 204, 197, 240, 64, 119, 164, 202, 2, 193, 105, - 197, 240, 64, 119, 164, 118, 197, 240, 64, 4, 55, 228, 241, 106, 196, 66, - 197, 240, 64, 4, 55, 228, 241, 106, 96, 197, 240, 64, 4, 55, 228, 241, - 106, 235, 119, 197, 240, 64, 4, 55, 228, 241, 106, 228, 241, 199, 237, - 221, 222, 81, 199, 237, 221, 222, 118, 197, 240, 64, 139, 96, 197, 240, - 57, 196, 66, 197, 240, 64, 118, 79, 235, 119, 197, 240, 57, 96, 197, 240, - 64, 139, 118, 197, 240, 57, 235, 119, 197, 240, 64, 118, 79, 196, 66, - 197, 240, 57, 118, 197, 240, 210, 196, 250, 231, 196, 66, 197, 240, 210, - 196, 250, 231, 96, 197, 240, 210, 196, 250, 231, 235, 119, 197, 240, 210, - 196, 250, 231, 118, 62, 47, 63, 57, 196, 66, 62, 47, 63, 57, 96, 62, 47, - 63, 57, 235, 119, 62, 47, 63, 57, 251, 85, 197, 240, 50, 196, 221, 57, - 251, 85, 197, 240, 248, 77, 196, 221, 57, 251, 85, 197, 240, 45, 196, - 221, 57, 251, 85, 197, 240, 198, 54, 196, 221, 57, 207, 23, 219, 224, - 207, 23, 183, 214, 77, 219, 224, 214, 77, 183, 232, 128, 239, 2, 250, - 232, 243, 6, 251, 84, 96, 62, 57, 16, 40, 196, 255, 42, 234, 133, 198, - 225, 198, 52, 118, 234, 37, 250, 235, 198, 225, 206, 204, 196, 66, 234, - 37, 250, 235, 198, 225, 198, 52, 96, 234, 37, 250, 235, 198, 225, 219, - 220, 235, 119, 234, 37, 250, 235, 62, 118, 234, 37, 250, 235, 62, 196, - 66, 234, 37, 250, 235, 62, 96, 234, 37, 250, 235, 62, 235, 119, 234, 37, - 250, 235, 235, 119, 197, 240, 64, 4, 179, 198, 136, 219, 214, 235, 119, - 197, 240, 64, 4, 179, 198, 136, 206, 197, 196, 66, 197, 240, 64, 4, 179, - 198, 136, 219, 214, 196, 66, 197, 240, 64, 4, 179, 198, 136, 206, 197, - 118, 197, 240, 64, 4, 179, 198, 136, 196, 65, 96, 197, 240, 64, 4, 179, - 198, 136, 196, 65, 118, 197, 240, 64, 4, 179, 198, 136, 235, 118, 96, - 197, 240, 64, 4, 179, 198, 136, 235, 118, 62, 238, 163, 235, 119, 23, - 118, 57, 62, 238, 163, 235, 119, 23, 96, 57, 62, 238, 163, 196, 66, 23, - 118, 57, 62, 238, 163, 196, 66, 23, 96, 57, 62, 238, 163, 118, 23, 196, - 66, 57, 62, 238, 163, 96, 23, 196, 66, 57, 62, 238, 163, 118, 23, 235, - 119, 57, 62, 238, 163, 96, 23, 235, 119, 57, 206, 248, 64, 144, 219, 224, - 206, 248, 64, 144, 183, 206, 248, 64, 133, 219, 224, 206, 248, 64, 133, - 183, 206, 248, 64, 45, 196, 77, 206, 248, 64, 50, 196, 77, 206, 248, 64, - 45, 235, 123, 206, 248, 64, 50, 235, 123, 196, 66, 63, 64, 232, 98, 249, - 88, 4, 228, 241, 164, 133, 250, 236, 223, 163, 42, 207, 93, 248, 62, 211, - 1, 63, 201, 188, 211, 1, 63, 23, 62, 201, 188, 211, 1, 62, 201, 188, 249, - 107, 111, 4, 156, 192, 235, 47, 192, 235, 47, 28, 192, 235, 62, 51, 247, - 19, 62, 237, 33, 247, 19, 153, 62, 210, 24, 228, 241, 62, 211, 160, 62, - 211, 160, 62, 216, 213, 196, 76, 197, 242, 247, 19, 62, 216, 213, 235, - 122, 197, 242, 247, 19, 62, 216, 213, 219, 219, 197, 242, 247, 19, 62, - 216, 213, 206, 203, 197, 242, 247, 19, 214, 95, 232, 146, 109, 198, 54, - 132, 62, 243, 10, 248, 77, 132, 62, 243, 10, 156, 232, 128, 209, 60, 62, - 238, 159, 206, 122, 156, 232, 128, 209, 60, 62, 238, 159, 63, 232, 128, - 209, 60, 238, 159, 206, 122, 63, 232, 128, 209, 60, 238, 159, 51, 209, - 25, 223, 144, 196, 107, 56, 230, 187, 77, 209, 78, 232, 146, 109, 209, - 78, 232, 146, 138, 209, 78, 232, 146, 134, 209, 78, 232, 146, 149, 198, - 9, 208, 185, 250, 189, 228, 91, 209, 196, 214, 91, 63, 215, 206, 204, 33, - 62, 237, 33, 211, 105, 238, 217, 197, 202, 156, 215, 206, 250, 227, 238, - 179, 230, 88, 191, 75, 221, 2, 251, 53, 252, 32, 193, 247, 209, 26, 45, - 132, 62, 201, 102, 50, 132, 62, 201, 102, 201, 103, 4, 45, 132, 248, 139, - 201, 103, 4, 50, 132, 248, 139, 118, 197, 13, 64, 4, 197, 242, 250, 233, - 196, 66, 197, 13, 64, 4, 197, 242, 250, 233, 96, 197, 13, 64, 4, 197, - 242, 250, 233, 235, 119, 197, 13, 64, 4, 197, 242, 250, 233, 234, 27, - 232, 146, 107, 234, 27, 232, 146, 109, 205, 51, 206, 31, 250, 188, 16, - 195, 52, 206, 31, 250, 188, 16, 212, 254, 206, 31, 250, 188, 16, 208, 1, - 206, 31, 250, 188, 16, 248, 163, 206, 31, 250, 188, 16, 204, 16, 206, 31, - 250, 188, 16, 198, 0, 234, 43, 3, 4, 223, 140, 60, 196, 89, 113, 204, 12, - 113, 235, 128, 113, 210, 96, 113, 207, 18, 50, 251, 115, 229, 203, 210, - 78, 113, 135, 6, 1, 250, 122, 135, 6, 1, 247, 252, 135, 6, 1, 195, 151, - 135, 6, 1, 231, 18, 135, 6, 1, 236, 169, 135, 6, 1, 192, 49, 135, 6, 1, - 191, 55, 135, 6, 1, 235, 30, 135, 6, 1, 191, 82, 135, 6, 1, 223, 39, 135, - 6, 1, 89, 223, 39, 135, 6, 1, 68, 135, 6, 1, 236, 190, 135, 6, 1, 222, - 94, 135, 6, 1, 219, 75, 135, 6, 1, 215, 66, 135, 6, 1, 214, 210, 135, 6, - 1, 211, 89, 135, 6, 1, 209, 55, 135, 6, 1, 206, 179, 135, 6, 1, 202, 77, - 135, 6, 1, 197, 44, 135, 6, 1, 196, 124, 135, 6, 1, 232, 101, 135, 6, 1, - 229, 188, 135, 6, 1, 211, 20, 135, 6, 1, 210, 63, 135, 6, 1, 203, 8, 135, - 6, 1, 197, 146, 135, 6, 1, 243, 54, 135, 6, 1, 203, 165, 135, 6, 1, 192, - 58, 135, 6, 1, 192, 60, 135, 6, 1, 192, 93, 135, 6, 1, 201, 220, 140, - 135, 6, 1, 191, 225, 135, 6, 1, 2, 191, 190, 135, 6, 1, 2, 191, 191, 4, - 199, 215, 135, 6, 1, 192, 12, 135, 6, 1, 223, 82, 2, 191, 190, 135, 6, 1, - 248, 175, 191, 190, 135, 6, 1, 223, 82, 248, 175, 191, 190, 135, 6, 1, - 232, 228, 135, 6, 1, 223, 37, 135, 6, 1, 203, 7, 135, 6, 1, 197, 215, 65, - 135, 6, 1, 220, 1, 215, 66, 135, 6, 1, 247, 73, 243, 54, 135, 2, 1, 250, - 122, 135, 2, 1, 247, 252, 135, 2, 1, 195, 151, 135, 2, 1, 231, 18, 135, - 2, 1, 236, 169, 135, 2, 1, 192, 49, 135, 2, 1, 191, 55, 135, 2, 1, 235, - 30, 135, 2, 1, 191, 82, 135, 2, 1, 223, 39, 135, 2, 1, 89, 223, 39, 135, - 2, 1, 68, 135, 2, 1, 236, 190, 135, 2, 1, 222, 94, 135, 2, 1, 219, 75, - 135, 2, 1, 215, 66, 135, 2, 1, 214, 210, 135, 2, 1, 211, 89, 135, 2, 1, - 209, 55, 135, 2, 1, 206, 179, 135, 2, 1, 202, 77, 135, 2, 1, 197, 44, - 135, 2, 1, 196, 124, 135, 2, 1, 232, 101, 135, 2, 1, 229, 188, 135, 2, 1, - 211, 20, 135, 2, 1, 210, 63, 135, 2, 1, 203, 8, 135, 2, 1, 197, 146, 135, - 2, 1, 243, 54, 135, 2, 1, 203, 165, 135, 2, 1, 192, 58, 135, 2, 1, 192, - 60, 135, 2, 1, 192, 93, 135, 2, 1, 201, 220, 140, 135, 2, 1, 191, 225, - 135, 2, 1, 2, 191, 190, 135, 2, 1, 2, 191, 191, 4, 199, 215, 135, 2, 1, - 192, 12, 135, 2, 1, 223, 82, 2, 191, 190, 135, 2, 1, 248, 175, 191, 190, - 135, 2, 1, 223, 82, 248, 175, 191, 190, 135, 2, 1, 232, 228, 135, 2, 1, - 223, 37, 135, 2, 1, 203, 7, 135, 2, 1, 197, 215, 65, 135, 2, 1, 220, 1, - 215, 66, 135, 2, 1, 247, 73, 243, 54, 8, 6, 1, 220, 143, 4, 55, 164, 8, - 2, 1, 220, 143, 4, 55, 164, 8, 6, 1, 220, 143, 4, 82, 198, 152, 8, 6, 1, - 210, 237, 4, 106, 8, 6, 1, 207, 222, 4, 199, 215, 8, 2, 1, 42, 4, 106, 8, - 2, 1, 200, 44, 4, 237, 39, 106, 8, 6, 1, 230, 117, 4, 237, 87, 8, 2, 1, - 230, 117, 4, 237, 87, 8, 6, 1, 222, 153, 4, 237, 87, 8, 2, 1, 222, 153, - 4, 237, 87, 8, 6, 1, 191, 167, 4, 237, 87, 8, 2, 1, 191, 167, 4, 237, 87, - 8, 6, 1, 251, 160, 8, 6, 1, 218, 169, 4, 102, 8, 6, 1, 153, 65, 8, 6, 1, - 153, 251, 160, 8, 2, 1, 196, 13, 4, 50, 102, 8, 6, 1, 193, 225, 4, 102, - 8, 2, 1, 193, 225, 4, 102, 8, 2, 1, 196, 13, 4, 238, 175, 8, 6, 1, 132, - 230, 116, 8, 2, 1, 132, 230, 116, 8, 2, 1, 199, 213, 209, 211, 8, 2, 1, - 235, 15, 4, 213, 9, 8, 2, 1, 153, 207, 222, 4, 199, 215, 8, 2, 1, 187, 4, - 130, 206, 189, 223, 117, 8, 1, 2, 6, 153, 71, 8, 200, 230, 2, 1, 223, 35, - 52, 1, 6, 196, 12, 8, 6, 1, 206, 9, 4, 200, 146, 199, 215, 8, 6, 1, 191, - 167, 4, 200, 146, 199, 215, 94, 6, 1, 251, 186, 94, 2, 1, 251, 186, 94, - 6, 1, 195, 66, 94, 2, 1, 195, 66, 94, 6, 1, 231, 211, 94, 2, 1, 231, 211, - 94, 6, 1, 237, 255, 94, 2, 1, 237, 255, 94, 6, 1, 234, 165, 94, 2, 1, - 234, 165, 94, 6, 1, 202, 7, 94, 2, 1, 202, 7, 94, 6, 1, 191, 95, 94, 2, - 1, 191, 95, 94, 6, 1, 230, 6, 94, 2, 1, 230, 6, 94, 6, 1, 199, 13, 94, 2, - 1, 199, 13, 94, 6, 1, 228, 32, 94, 2, 1, 228, 32, 94, 6, 1, 222, 77, 94, - 2, 1, 222, 77, 94, 6, 1, 219, 252, 94, 2, 1, 219, 252, 94, 6, 1, 216, - 100, 94, 2, 1, 216, 100, 94, 6, 1, 213, 219, 94, 2, 1, 213, 219, 94, 6, - 1, 220, 248, 94, 2, 1, 220, 248, 94, 6, 1, 74, 94, 2, 1, 74, 94, 6, 1, - 209, 185, 94, 2, 1, 209, 185, 94, 6, 1, 206, 162, 94, 2, 1, 206, 162, 94, - 6, 1, 202, 183, 94, 2, 1, 202, 183, 94, 6, 1, 199, 166, 94, 2, 1, 199, - 166, 94, 6, 1, 196, 168, 94, 2, 1, 196, 168, 94, 6, 1, 233, 23, 94, 2, 1, - 233, 23, 94, 6, 1, 221, 190, 94, 2, 1, 221, 190, 94, 6, 1, 208, 176, 94, - 2, 1, 208, 176, 94, 6, 1, 211, 81, 94, 2, 1, 211, 81, 94, 6, 1, 237, 37, - 251, 192, 94, 2, 1, 237, 37, 251, 192, 94, 6, 1, 39, 94, 251, 230, 94, 2, - 1, 39, 94, 251, 230, 94, 6, 1, 238, 198, 234, 165, 94, 2, 1, 238, 198, - 234, 165, 94, 6, 1, 237, 37, 222, 77, 94, 2, 1, 237, 37, 222, 77, 94, 6, - 1, 237, 37, 213, 219, 94, 2, 1, 237, 37, 213, 219, 94, 6, 1, 238, 198, - 213, 219, 94, 2, 1, 238, 198, 213, 219, 94, 6, 1, 39, 94, 211, 81, 94, 2, - 1, 39, 94, 211, 81, 94, 6, 1, 205, 145, 94, 2, 1, 205, 145, 94, 6, 1, - 238, 214, 203, 105, 94, 2, 1, 238, 214, 203, 105, 94, 6, 1, 39, 94, 203, - 105, 94, 2, 1, 39, 94, 203, 105, 94, 6, 1, 39, 94, 234, 12, 94, 2, 1, 39, - 94, 234, 12, 94, 6, 1, 251, 212, 221, 195, 94, 2, 1, 251, 212, 221, 195, - 94, 6, 1, 237, 37, 228, 242, 94, 2, 1, 237, 37, 228, 242, 94, 6, 1, 39, - 94, 228, 242, 94, 2, 1, 39, 94, 228, 242, 94, 6, 1, 39, 94, 140, 94, 2, - 1, 39, 94, 140, 94, 6, 1, 220, 142, 140, 94, 2, 1, 220, 142, 140, 94, 6, - 1, 39, 94, 229, 209, 94, 2, 1, 39, 94, 229, 209, 94, 6, 1, 39, 94, 230, - 9, 94, 2, 1, 39, 94, 230, 9, 94, 6, 1, 39, 94, 231, 206, 94, 2, 1, 39, - 94, 231, 206, 94, 6, 1, 39, 94, 236, 193, 94, 2, 1, 39, 94, 236, 193, 94, - 6, 1, 39, 94, 203, 71, 94, 2, 1, 39, 94, 203, 71, 94, 6, 1, 39, 212, 145, - 203, 71, 94, 2, 1, 39, 212, 145, 203, 71, 94, 6, 1, 39, 212, 145, 214, - 16, 94, 2, 1, 39, 212, 145, 214, 16, 94, 6, 1, 39, 212, 145, 212, 81, 94, - 2, 1, 39, 212, 145, 212, 81, 94, 6, 1, 39, 212, 145, 193, 140, 94, 2, 1, - 39, 212, 145, 193, 140, 94, 16, 222, 102, 94, 16, 216, 101, 206, 162, 94, - 16, 209, 186, 206, 162, 94, 16, 201, 89, 94, 16, 199, 167, 206, 162, 94, - 16, 221, 191, 206, 162, 94, 16, 203, 72, 202, 183, 94, 6, 1, 238, 198, - 203, 105, 94, 2, 1, 238, 198, 203, 105, 94, 6, 1, 238, 198, 231, 206, 94, - 2, 1, 238, 198, 231, 206, 94, 33, 213, 220, 58, 94, 33, 201, 213, 250, - 201, 94, 33, 201, 213, 219, 188, 94, 6, 1, 248, 103, 221, 195, 94, 2, 1, - 248, 103, 221, 195, 94, 39, 212, 145, 232, 80, 201, 63, 94, 39, 212, 145, - 236, 234, 208, 13, 77, 94, 39, 212, 145, 223, 142, 208, 13, 77, 94, 39, - 212, 145, 195, 137, 236, 205, 94, 232, 118, 91, 230, 70, 94, 232, 80, - 201, 63, 94, 215, 200, 236, 205, 101, 2, 1, 251, 132, 101, 2, 1, 249, - 101, 101, 2, 1, 231, 210, 101, 2, 1, 236, 150, 101, 2, 1, 234, 103, 101, - 2, 1, 195, 49, 101, 2, 1, 191, 80, 101, 2, 1, 199, 193, 101, 2, 1, 223, - 162, 101, 2, 1, 222, 87, 101, 2, 1, 220, 7, 101, 2, 1, 217, 90, 101, 2, - 1, 214, 216, 101, 2, 1, 211, 104, 101, 2, 1, 210, 131, 101, 2, 1, 191, - 67, 101, 2, 1, 207, 163, 101, 2, 1, 205, 142, 101, 2, 1, 199, 179, 101, - 2, 1, 196, 113, 101, 2, 1, 209, 220, 101, 2, 1, 221, 200, 101, 2, 1, 231, - 82, 101, 2, 1, 208, 81, 101, 2, 1, 203, 69, 101, 2, 1, 243, 81, 101, 2, - 1, 247, 128, 101, 2, 1, 222, 234, 101, 2, 1, 243, 18, 101, 2, 1, 246, - 241, 101, 2, 1, 192, 218, 101, 2, 1, 222, 249, 101, 2, 1, 230, 87, 101, - 2, 1, 229, 245, 101, 2, 1, 229, 145, 101, 2, 1, 193, 125, 101, 2, 1, 230, - 19, 101, 2, 1, 229, 11, 101, 2, 1, 192, 14, 101, 2, 1, 252, 14, 198, 175, - 1, 170, 198, 175, 1, 192, 136, 198, 175, 1, 192, 135, 198, 175, 1, 192, - 125, 198, 175, 1, 192, 123, 198, 175, 1, 248, 218, 252, 62, 192, 118, - 198, 175, 1, 192, 118, 198, 175, 1, 192, 133, 198, 175, 1, 192, 130, 198, - 175, 1, 192, 132, 198, 175, 1, 192, 131, 198, 175, 1, 192, 40, 198, 175, - 1, 192, 127, 198, 175, 1, 192, 116, 198, 175, 1, 197, 86, 192, 116, 198, - 175, 1, 192, 113, 198, 175, 1, 192, 121, 198, 175, 1, 248, 218, 252, 62, - 192, 121, 198, 175, 1, 197, 86, 192, 121, 198, 175, 1, 192, 120, 198, - 175, 1, 192, 140, 198, 175, 1, 192, 114, 198, 175, 1, 197, 86, 192, 114, - 198, 175, 1, 192, 103, 198, 175, 1, 197, 86, 192, 103, 198, 175, 1, 192, - 33, 198, 175, 1, 192, 82, 198, 175, 1, 251, 243, 192, 82, 198, 175, 1, - 197, 86, 192, 82, 198, 175, 1, 192, 112, 198, 175, 1, 192, 111, 198, 175, - 1, 192, 108, 198, 175, 1, 197, 86, 192, 122, 198, 175, 1, 197, 86, 192, - 106, 198, 175, 1, 192, 104, 198, 175, 1, 191, 225, 198, 175, 1, 192, 101, - 198, 175, 1, 192, 99, 198, 175, 1, 192, 124, 198, 175, 1, 197, 86, 192, - 124, 198, 175, 1, 250, 127, 192, 124, 198, 175, 1, 192, 98, 198, 175, 1, - 192, 96, 198, 175, 1, 192, 97, 198, 175, 1, 192, 95, 198, 175, 1, 192, - 94, 198, 175, 1, 192, 134, 198, 175, 1, 192, 92, 198, 175, 1, 192, 90, - 198, 175, 1, 192, 89, 198, 175, 1, 192, 86, 198, 175, 1, 192, 83, 198, - 175, 1, 199, 157, 192, 83, 198, 175, 1, 192, 81, 198, 175, 1, 192, 80, - 198, 175, 1, 192, 12, 198, 175, 52, 1, 220, 115, 77, 198, 175, 204, 11, - 77, 198, 175, 120, 222, 196, 36, 5, 219, 42, 36, 5, 216, 5, 36, 5, 206, - 154, 36, 5, 202, 38, 36, 5, 203, 55, 36, 5, 248, 110, 36, 5, 198, 91, 36, - 5, 242, 98, 36, 5, 213, 36, 36, 5, 212, 64, 36, 5, 231, 11, 211, 182, 36, - 5, 191, 6, 36, 5, 236, 172, 36, 5, 237, 160, 36, 5, 222, 200, 36, 5, 198, - 240, 36, 5, 243, 67, 36, 5, 209, 198, 36, 5, 209, 72, 36, 5, 231, 97, 36, - 5, 231, 93, 36, 5, 231, 94, 36, 5, 231, 95, 36, 5, 201, 175, 36, 5, 201, - 129, 36, 5, 201, 142, 36, 5, 201, 174, 36, 5, 201, 147, 36, 5, 201, 148, - 36, 5, 201, 134, 36, 5, 247, 65, 36, 5, 247, 44, 36, 5, 247, 46, 36, 5, - 247, 64, 36, 5, 247, 62, 36, 5, 247, 63, 36, 5, 247, 45, 36, 5, 190, 224, - 36, 5, 190, 202, 36, 5, 190, 215, 36, 5, 190, 223, 36, 5, 190, 218, 36, - 5, 190, 219, 36, 5, 190, 207, 36, 5, 247, 60, 36, 5, 247, 47, 36, 5, 247, - 49, 36, 5, 247, 59, 36, 5, 247, 57, 36, 5, 247, 58, 36, 5, 247, 48, 36, - 5, 207, 234, 36, 5, 207, 224, 36, 5, 207, 230, 36, 5, 207, 233, 36, 5, - 207, 231, 36, 5, 207, 232, 36, 5, 207, 229, 36, 5, 220, 153, 36, 5, 220, - 145, 36, 5, 220, 148, 36, 5, 220, 152, 36, 5, 220, 149, 36, 5, 220, 150, - 36, 5, 220, 146, 36, 5, 192, 175, 36, 5, 192, 162, 36, 5, 192, 170, 36, - 5, 192, 174, 36, 5, 192, 172, 36, 5, 192, 173, 36, 5, 192, 169, 36, 5, - 230, 128, 36, 5, 230, 118, 36, 5, 230, 121, 36, 5, 230, 127, 36, 5, 230, - 123, 36, 5, 230, 124, 36, 5, 230, 120, 33, 38, 1, 249, 17, 33, 38, 1, - 195, 153, 33, 38, 1, 231, 77, 33, 38, 1, 237, 146, 33, 38, 1, 191, 62, - 33, 38, 1, 191, 87, 33, 38, 1, 155, 33, 38, 1, 234, 140, 33, 38, 1, 234, - 114, 33, 38, 1, 234, 103, 33, 38, 1, 74, 33, 38, 1, 210, 63, 33, 38, 1, - 234, 34, 33, 38, 1, 234, 22, 33, 38, 1, 199, 145, 33, 38, 1, 140, 33, 38, - 1, 197, 161, 33, 38, 1, 243, 127, 33, 38, 1, 203, 165, 33, 38, 1, 203, - 116, 33, 38, 1, 232, 228, 33, 38, 1, 234, 18, 33, 38, 1, 65, 33, 38, 1, - 223, 226, 33, 38, 1, 236, 191, 33, 38, 1, 215, 219, 196, 128, 33, 38, 1, - 192, 95, 33, 38, 1, 191, 225, 33, 38, 1, 223, 81, 65, 33, 38, 1, 219, 83, - 191, 190, 33, 38, 1, 248, 175, 191, 190, 33, 38, 1, 223, 81, 248, 175, - 191, 190, 50, 251, 116, 200, 225, 217, 51, 50, 251, 116, 235, 138, 200, - 225, 217, 51, 45, 200, 225, 248, 53, 50, 200, 225, 248, 53, 45, 235, 138, - 200, 225, 248, 53, 50, 235, 138, 200, 225, 248, 53, 207, 147, 223, 104, - 217, 51, 207, 147, 235, 138, 223, 104, 217, 51, 235, 138, 198, 8, 217, - 51, 45, 198, 8, 248, 53, 50, 198, 8, 248, 53, 207, 147, 201, 190, 45, - 207, 147, 211, 106, 248, 53, 50, 207, 147, 211, 106, 248, 53, 234, 189, - 238, 254, 210, 126, 232, 148, 210, 126, 207, 18, 232, 148, 210, 126, 228, - 85, 235, 138, 211, 177, 235, 119, 251, 126, 196, 66, 251, 126, 235, 138, - 206, 203, 251, 115, 55, 211, 172, 228, 88, 223, 93, 223, 102, 210, 183, - 248, 47, 228, 89, 4, 237, 42, 198, 153, 4, 206, 189, 58, 45, 130, 210, - 116, 248, 53, 50, 130, 210, 116, 248, 53, 198, 153, 4, 75, 58, 198, 153, - 4, 75, 60, 45, 81, 249, 88, 4, 208, 7, 50, 81, 249, 88, 4, 208, 7, 198, - 54, 45, 132, 248, 53, 198, 54, 50, 132, 248, 53, 248, 77, 45, 132, 248, - 53, 248, 77, 50, 132, 248, 53, 45, 202, 206, 126, 248, 53, 50, 202, 206, - 126, 248, 53, 45, 55, 210, 113, 50, 55, 210, 113, 105, 185, 139, 91, 75, - 208, 151, 91, 75, 139, 105, 185, 208, 151, 112, 232, 128, 75, 208, 151, - 232, 226, 75, 77, 207, 18, 208, 13, 77, 81, 198, 152, 206, 189, 209, 61, - 193, 23, 204, 11, 82, 236, 140, 153, 242, 74, 207, 147, 236, 140, 207, - 147, 242, 74, 153, 204, 25, 238, 15, 4, 45, 230, 173, 238, 15, 4, 50, - 230, 173, 153, 238, 14, 198, 54, 132, 205, 54, 56, 197, 14, 237, 215, - 198, 223, 237, 215, 201, 79, 232, 80, 201, 63, 81, 202, 136, 236, 138, - 193, 72, 81, 219, 112, 247, 109, 55, 228, 88, 207, 18, 242, 74, 55, 218, - 237, 207, 252, 77, 237, 216, 4, 45, 196, 69, 55, 200, 164, 77, 223, 93, - 130, 222, 35, 223, 93, 130, 222, 36, 4, 222, 36, 58, 130, 222, 35, 130, - 222, 36, 4, 236, 140, 55, 201, 114, 242, 74, 235, 138, 202, 23, 197, 225, - 238, 14, 216, 214, 242, 74, 210, 125, 77, 208, 150, 234, 129, 77, 238, - 255, 195, 137, 236, 205, 238, 218, 210, 82, 4, 50, 238, 216, 238, 218, - 210, 82, 4, 45, 238, 216, 198, 128, 3, 6, 233, 255, 216, 214, 233, 216, - 77, 216, 214, 208, 13, 77, 45, 51, 248, 54, 4, 106, 50, 51, 248, 54, 4, - 106, 45, 51, 248, 54, 4, 55, 106, 50, 51, 248, 54, 4, 55, 106, 198, 54, - 132, 45, 210, 113, 198, 54, 132, 50, 210, 113, 248, 77, 132, 45, 210, - 113, 248, 77, 132, 50, 210, 113, 211, 172, 228, 88, 12, 48, 207, 48, 12, - 48, 242, 230, 12, 48, 205, 57, 107, 12, 48, 205, 57, 109, 12, 48, 205, - 57, 138, 12, 48, 209, 250, 12, 48, 248, 62, 12, 48, 199, 233, 12, 48, - 221, 79, 107, 12, 48, 221, 79, 109, 12, 48, 236, 202, 12, 48, 205, 61, - 12, 48, 2, 107, 12, 48, 2, 109, 12, 48, 220, 30, 107, 12, 48, 220, 30, - 109, 12, 48, 220, 30, 138, 12, 48, 220, 30, 134, 12, 48, 202, 58, 12, 48, - 198, 227, 12, 48, 202, 55, 107, 12, 48, 202, 55, 109, 12, 48, 229, 224, - 107, 12, 48, 229, 224, 109, 12, 48, 230, 53, 12, 48, 207, 136, 12, 48, - 243, 64, 12, 48, 200, 198, 12, 48, 215, 205, 12, 48, 237, 143, 12, 48, - 215, 193, 12, 48, 242, 249, 12, 48, 193, 144, 107, 12, 48, 193, 144, 109, - 12, 48, 232, 243, 12, 48, 210, 76, 107, 12, 48, 210, 76, 109, 12, 48, - 202, 178, 132, 197, 255, 197, 177, 12, 48, 238, 239, 12, 48, 236, 162, - 12, 48, 223, 27, 12, 48, 248, 102, 79, 242, 213, 12, 48, 233, 193, 12, - 48, 201, 215, 107, 12, 48, 201, 215, 109, 12, 48, 249, 103, 12, 48, 202, - 185, 12, 48, 247, 190, 202, 185, 12, 48, 214, 86, 107, 12, 48, 214, 86, - 109, 12, 48, 214, 86, 138, 12, 48, 214, 86, 134, 12, 48, 216, 172, 12, - 48, 203, 107, 12, 48, 207, 142, 12, 48, 233, 223, 12, 48, 211, 119, 12, - 48, 248, 18, 107, 12, 48, 248, 18, 109, 12, 48, 216, 224, 12, 48, 215, - 199, 12, 48, 230, 214, 107, 12, 48, 230, 214, 109, 12, 48, 230, 214, 138, - 12, 48, 198, 173, 12, 48, 242, 212, 12, 48, 193, 105, 107, 12, 48, 193, - 105, 109, 12, 48, 247, 190, 205, 50, 12, 48, 202, 178, 228, 187, 12, 48, - 228, 187, 12, 48, 247, 190, 201, 229, 12, 48, 247, 190, 203, 102, 12, 48, - 232, 159, 12, 48, 247, 190, 247, 85, 12, 48, 202, 178, 193, 169, 12, 48, - 193, 170, 107, 12, 48, 193, 170, 109, 12, 48, 242, 252, 12, 48, 247, 190, - 230, 250, 12, 48, 179, 107, 12, 48, 179, 109, 12, 48, 247, 190, 219, 19, - 12, 48, 247, 190, 231, 191, 12, 48, 215, 188, 107, 12, 48, 215, 188, 109, - 12, 48, 207, 149, 12, 48, 248, 114, 12, 48, 247, 190, 199, 185, 219, 230, - 12, 48, 247, 190, 219, 233, 12, 48, 247, 190, 193, 66, 12, 48, 247, 190, - 232, 179, 12, 48, 234, 201, 107, 12, 48, 234, 201, 109, 12, 48, 234, 201, - 138, 12, 48, 247, 190, 234, 200, 12, 48, 229, 235, 12, 48, 247, 190, 228, - 183, 12, 48, 248, 98, 12, 48, 231, 61, 12, 48, 247, 190, 232, 236, 12, - 48, 247, 190, 248, 160, 12, 48, 247, 190, 205, 158, 12, 48, 202, 178, - 193, 95, 12, 48, 202, 178, 192, 72, 12, 48, 247, 190, 232, 99, 12, 48, - 223, 34, 233, 228, 12, 48, 247, 190, 233, 228, 12, 48, 223, 34, 198, 56, - 12, 48, 247, 190, 198, 56, 12, 48, 223, 34, 235, 111, 12, 48, 247, 190, - 235, 111, 12, 48, 197, 55, 12, 48, 223, 34, 197, 55, 12, 48, 247, 190, - 197, 55, 83, 48, 107, 83, 48, 219, 112, 83, 48, 236, 140, 83, 48, 202, - 97, 83, 48, 205, 56, 83, 48, 102, 83, 48, 109, 83, 48, 219, 141, 83, 48, - 217, 90, 83, 48, 219, 209, 83, 48, 234, 77, 83, 48, 171, 83, 48, 144, - 248, 62, 83, 48, 238, 242, 83, 48, 228, 26, 83, 48, 199, 233, 83, 48, - 211, 77, 248, 62, 83, 48, 221, 78, 83, 48, 208, 254, 83, 48, 193, 12, 83, - 48, 201, 203, 83, 48, 50, 211, 77, 248, 62, 83, 48, 229, 146, 234, 98, - 83, 48, 199, 95, 83, 48, 236, 202, 83, 48, 205, 61, 83, 48, 242, 230, 83, - 48, 208, 204, 83, 48, 251, 252, 83, 48, 215, 179, 83, 48, 234, 98, 83, - 48, 234, 207, 83, 48, 205, 91, 83, 48, 231, 3, 83, 48, 231, 4, 202, 74, - 83, 48, 233, 227, 83, 48, 248, 174, 83, 48, 193, 35, 83, 48, 243, 86, 83, - 48, 206, 133, 83, 48, 223, 158, 83, 48, 202, 70, 83, 48, 220, 29, 83, 48, - 238, 252, 83, 48, 201, 194, 83, 48, 215, 184, 83, 48, 206, 176, 83, 48, - 193, 20, 83, 48, 211, 95, 83, 48, 197, 63, 83, 48, 235, 91, 83, 48, 203, - 40, 198, 227, 83, 48, 235, 138, 242, 230, 83, 48, 179, 201, 34, 83, 48, - 105, 230, 28, 83, 48, 203, 46, 83, 48, 248, 69, 83, 48, 202, 54, 83, 48, - 248, 25, 83, 48, 201, 78, 83, 48, 229, 223, 83, 48, 230, 71, 83, 48, 236, - 144, 83, 48, 230, 53, 83, 48, 248, 47, 83, 48, 207, 136, 83, 48, 205, 74, - 83, 48, 236, 236, 83, 48, 250, 132, 83, 48, 201, 190, 83, 48, 213, 11, - 83, 48, 200, 198, 83, 48, 205, 103, 83, 48, 215, 205, 83, 48, 197, 254, - 83, 48, 220, 111, 83, 48, 201, 63, 83, 48, 237, 143, 83, 48, 193, 120, - 83, 48, 236, 175, 213, 11, 83, 48, 242, 70, 83, 48, 232, 72, 83, 48, 242, - 243, 83, 48, 201, 84, 83, 48, 193, 143, 83, 48, 232, 243, 83, 48, 242, - 239, 83, 48, 233, 66, 83, 48, 55, 192, 235, 83, 48, 132, 197, 255, 197, - 177, 83, 48, 202, 88, 83, 48, 233, 78, 83, 48, 238, 239, 83, 48, 236, - 162, 83, 48, 208, 199, 83, 48, 223, 27, 83, 48, 216, 196, 83, 48, 198, - 151, 83, 48, 200, 141, 83, 48, 219, 135, 83, 48, 196, 43, 83, 48, 233, - 21, 83, 48, 248, 102, 79, 242, 213, 83, 48, 202, 212, 83, 48, 235, 138, - 199, 87, 83, 48, 193, 89, 83, 48, 202, 107, 83, 48, 236, 222, 83, 48, - 233, 193, 83, 48, 201, 232, 83, 48, 57, 83, 48, 201, 65, 83, 48, 201, - 214, 83, 48, 198, 25, 83, 48, 230, 223, 83, 48, 247, 70, 83, 48, 201, - 107, 83, 48, 249, 103, 83, 48, 206, 245, 83, 48, 202, 185, 83, 48, 223, - 18, 83, 48, 214, 85, 83, 48, 203, 107, 83, 48, 233, 54, 83, 48, 211, 119, - 83, 48, 251, 125, 83, 48, 209, 89, 83, 48, 234, 211, 83, 48, 248, 17, 83, - 48, 216, 224, 83, 48, 216, 37, 83, 48, 204, 32, 83, 48, 250, 239, 83, 48, - 215, 199, 83, 48, 198, 61, 83, 48, 211, 64, 83, 48, 248, 106, 83, 48, - 201, 59, 83, 48, 242, 82, 83, 48, 230, 213, 83, 48, 198, 173, 83, 48, - 223, 121, 83, 48, 248, 120, 83, 48, 193, 170, 234, 98, 83, 48, 242, 212, - 83, 48, 193, 104, 83, 48, 205, 50, 83, 48, 228, 187, 83, 48, 201, 229, - 83, 48, 195, 180, 83, 48, 249, 12, 83, 48, 209, 147, 83, 48, 249, 133, - 83, 48, 203, 102, 83, 48, 207, 86, 83, 48, 206, 45, 83, 48, 232, 159, 83, - 48, 248, 104, 83, 48, 247, 85, 83, 48, 248, 144, 83, 48, 215, 201, 83, - 48, 193, 169, 83, 48, 242, 252, 83, 48, 193, 62, 83, 48, 236, 214, 83, - 48, 195, 50, 83, 48, 230, 250, 83, 48, 219, 19, 83, 48, 231, 191, 83, 48, - 215, 187, 83, 48, 202, 96, 83, 48, 203, 40, 199, 214, 248, 160, 83, 48, - 207, 149, 83, 48, 248, 114, 83, 48, 193, 2, 83, 48, 233, 103, 83, 48, - 219, 230, 83, 48, 199, 185, 219, 230, 83, 48, 219, 226, 83, 48, 202, 4, - 83, 48, 219, 233, 83, 48, 193, 66, 83, 48, 232, 179, 83, 48, 234, 200, - 83, 48, 229, 235, 83, 48, 232, 116, 83, 48, 228, 183, 83, 48, 248, 98, - 83, 48, 199, 199, 83, 48, 230, 78, 83, 48, 233, 14, 83, 48, 205, 194, - 193, 62, 83, 48, 247, 72, 83, 48, 231, 61, 83, 48, 232, 236, 83, 48, 248, - 160, 83, 48, 205, 158, 83, 48, 237, 128, 83, 48, 193, 95, 83, 48, 229, - 199, 83, 48, 192, 72, 83, 48, 216, 49, 83, 48, 248, 139, 83, 48, 234, - 110, 83, 48, 232, 99, 83, 48, 197, 222, 83, 48, 235, 94, 83, 48, 207, - 130, 83, 48, 213, 13, 83, 48, 233, 228, 83, 48, 198, 56, 83, 48, 235, - 111, 83, 48, 197, 55, 83, 48, 232, 182, 154, 237, 85, 246, 240, 45, 119, - 183, 154, 237, 85, 246, 240, 93, 119, 60, 154, 237, 85, 246, 240, 45, - 119, 82, 23, 183, 154, 237, 85, 246, 240, 93, 119, 82, 23, 60, 154, 237, - 85, 246, 240, 232, 80, 200, 168, 154, 237, 85, 246, 240, 200, 169, 232, - 98, 58, 154, 237, 85, 246, 240, 200, 169, 232, 98, 60, 154, 237, 85, 246, - 240, 200, 169, 232, 98, 219, 224, 154, 237, 85, 246, 240, 200, 169, 232, - 98, 116, 219, 224, 154, 237, 85, 246, 240, 200, 169, 232, 98, 116, 183, - 154, 237, 85, 246, 240, 200, 169, 232, 98, 110, 219, 224, 154, 237, 85, - 246, 240, 211, 3, 154, 201, 247, 154, 242, 74, 154, 232, 80, 201, 63, - 236, 211, 77, 223, 19, 223, 141, 201, 106, 113, 154, 223, 51, 77, 154, - 242, 215, 77, 154, 31, 191, 77, 45, 251, 116, 248, 53, 50, 251, 116, 248, - 53, 45, 55, 251, 116, 248, 53, 50, 55, 251, 116, 248, 53, 45, 239, 2, - 248, 53, 50, 239, 2, 248, 53, 45, 63, 239, 2, 248, 53, 50, 63, 239, 2, - 248, 53, 45, 62, 219, 187, 248, 53, 50, 62, 219, 187, 248, 53, 209, 18, - 77, 231, 130, 77, 45, 198, 42, 203, 103, 248, 53, 50, 198, 42, 203, 103, - 248, 53, 45, 63, 219, 187, 248, 53, 50, 63, 219, 187, 248, 53, 45, 63, - 198, 42, 203, 103, 248, 53, 50, 63, 198, 42, 203, 103, 248, 53, 45, 63, - 51, 248, 53, 50, 63, 51, 248, 53, 193, 139, 237, 215, 207, 18, 55, 208, - 216, 207, 252, 77, 55, 208, 216, 207, 252, 77, 130, 55, 208, 216, 207, - 252, 77, 209, 18, 87, 233, 103, 230, 25, 212, 134, 107, 230, 25, 212, - 134, 109, 230, 25, 212, 134, 138, 230, 25, 212, 134, 134, 230, 25, 212, - 134, 149, 230, 25, 212, 134, 169, 230, 25, 212, 134, 175, 230, 25, 212, - 134, 171, 230, 25, 212, 134, 178, 154, 219, 168, 163, 77, 154, 206, 180, - 163, 77, 154, 237, 95, 163, 77, 154, 234, 76, 163, 77, 30, 202, 170, 75, - 163, 77, 30, 55, 75, 163, 77, 193, 135, 237, 215, 81, 222, 86, 207, 49, - 77, 81, 222, 86, 207, 49, 4, 195, 20, 202, 5, 77, 81, 222, 86, 207, 49, - 87, 116, 230, 70, 81, 222, 86, 207, 49, 4, 195, 20, 202, 5, 87, 116, 230, - 70, 81, 222, 86, 207, 49, 87, 110, 230, 70, 47, 209, 18, 77, 154, 199, - 109, 219, 113, 233, 51, 204, 11, 113, 230, 25, 212, 134, 199, 95, 230, - 25, 212, 134, 197, 32, 230, 25, 212, 134, 198, 249, 81, 154, 223, 51, 77, - 217, 31, 77, 210, 107, 251, 153, 77, 154, 67, 223, 144, 154, 132, 233, 6, - 201, 247, 229, 120, 1, 2, 65, 229, 120, 1, 65, 229, 120, 1, 2, 68, 229, - 120, 1, 68, 229, 120, 1, 2, 66, 229, 120, 1, 66, 229, 120, 1, 2, 71, 229, - 120, 1, 71, 229, 120, 1, 2, 74, 229, 120, 1, 74, 229, 120, 1, 155, 229, - 120, 1, 231, 240, 229, 120, 1, 221, 166, 229, 120, 1, 231, 53, 229, 120, - 1, 220, 232, 229, 120, 1, 230, 179, 229, 120, 1, 222, 22, 229, 120, 1, - 231, 165, 229, 120, 1, 221, 67, 229, 120, 1, 231, 3, 229, 120, 1, 188, - 229, 120, 1, 191, 123, 229, 120, 1, 202, 222, 229, 120, 1, 191, 30, 229, - 120, 1, 201, 4, 229, 120, 1, 190, 251, 229, 120, 1, 205, 68, 229, 120, 1, - 191, 87, 229, 120, 1, 202, 46, 229, 120, 1, 191, 7, 229, 120, 1, 190, - 190, 229, 120, 1, 238, 32, 229, 120, 1, 198, 193, 229, 120, 1, 237, 44, - 229, 120, 1, 2, 197, 94, 229, 120, 1, 197, 94, 229, 120, 1, 235, 89, 229, - 120, 1, 199, 145, 229, 120, 1, 237, 146, 229, 120, 1, 159, 229, 120, 1, - 236, 174, 229, 120, 1, 180, 229, 120, 1, 213, 219, 229, 120, 1, 212, 178, - 229, 120, 1, 214, 121, 229, 120, 1, 213, 43, 229, 120, 1, 140, 229, 120, - 1, 249, 153, 229, 120, 1, 168, 229, 120, 1, 229, 158, 229, 120, 1, 248, - 188, 229, 120, 1, 209, 185, 229, 120, 1, 228, 159, 229, 120, 1, 248, 10, - 229, 120, 1, 208, 165, 229, 120, 1, 229, 245, 229, 120, 1, 249, 17, 229, - 120, 1, 210, 63, 229, 120, 1, 229, 23, 229, 120, 1, 248, 111, 229, 120, - 1, 209, 73, 229, 120, 1, 174, 229, 120, 1, 216, 100, 229, 120, 1, 215, - 155, 229, 120, 1, 216, 232, 229, 120, 1, 216, 12, 229, 120, 1, 2, 170, - 229, 120, 1, 170, 229, 120, 1, 2, 191, 225, 229, 120, 1, 191, 225, 229, - 120, 1, 2, 192, 12, 229, 120, 1, 192, 12, 229, 120, 1, 165, 229, 120, 1, - 207, 1, 229, 120, 1, 206, 68, 229, 120, 1, 207, 113, 229, 120, 1, 206, - 162, 229, 120, 1, 2, 193, 190, 229, 120, 1, 193, 190, 229, 120, 1, 193, - 86, 229, 120, 1, 193, 125, 229, 120, 1, 193, 48, 229, 120, 1, 215, 61, - 229, 120, 1, 193, 249, 229, 120, 1, 2, 155, 229, 120, 1, 2, 222, 22, 33, - 222, 48, 195, 20, 202, 5, 77, 33, 222, 48, 204, 30, 202, 5, 77, 222, 48, - 195, 20, 202, 5, 77, 222, 48, 204, 30, 202, 5, 77, 229, 120, 223, 51, 77, - 229, 120, 195, 20, 223, 51, 77, 229, 120, 237, 3, 191, 242, 222, 48, 55, - 228, 88, 72, 1, 2, 65, 72, 1, 65, 72, 1, 2, 68, 72, 1, 68, 72, 1, 2, 66, - 72, 1, 66, 72, 1, 2, 71, 72, 1, 71, 72, 1, 2, 74, 72, 1, 74, 72, 1, 155, - 72, 1, 231, 240, 72, 1, 221, 166, 72, 1, 231, 53, 72, 1, 220, 232, 72, 1, - 230, 179, 72, 1, 222, 22, 72, 1, 231, 165, 72, 1, 221, 67, 72, 1, 231, 3, - 72, 1, 188, 72, 1, 191, 123, 72, 1, 202, 222, 72, 1, 191, 30, 72, 1, 201, - 4, 72, 1, 190, 251, 72, 1, 205, 68, 72, 1, 191, 87, 72, 1, 202, 46, 72, - 1, 191, 7, 72, 1, 190, 190, 72, 1, 238, 32, 72, 1, 198, 193, 72, 1, 237, - 44, 72, 1, 2, 197, 94, 72, 1, 197, 94, 72, 1, 235, 89, 72, 1, 199, 145, - 72, 1, 237, 146, 72, 1, 159, 72, 1, 236, 174, 72, 1, 180, 72, 1, 213, - 219, 72, 1, 212, 178, 72, 1, 214, 121, 72, 1, 213, 43, 72, 1, 140, 72, 1, - 249, 153, 72, 1, 168, 72, 1, 229, 158, 72, 1, 248, 188, 72, 1, 209, 185, - 72, 1, 228, 159, 72, 1, 248, 10, 72, 1, 208, 165, 72, 1, 229, 245, 72, 1, - 249, 17, 72, 1, 210, 63, 72, 1, 229, 23, 72, 1, 248, 111, 72, 1, 209, 73, - 72, 1, 174, 72, 1, 216, 100, 72, 1, 215, 155, 72, 1, 216, 232, 72, 1, - 216, 12, 72, 1, 2, 170, 72, 1, 170, 72, 1, 2, 191, 225, 72, 1, 191, 225, - 72, 1, 2, 192, 12, 72, 1, 192, 12, 72, 1, 165, 72, 1, 207, 1, 72, 1, 206, - 68, 72, 1, 207, 113, 72, 1, 206, 162, 72, 1, 2, 193, 190, 72, 1, 193, - 190, 72, 1, 193, 86, 72, 1, 193, 125, 72, 1, 193, 48, 72, 1, 215, 61, 72, - 1, 193, 249, 72, 1, 2, 155, 72, 1, 2, 222, 22, 72, 1, 195, 188, 72, 1, - 195, 69, 72, 1, 195, 153, 72, 1, 195, 24, 72, 82, 236, 140, 222, 48, 208, - 191, 202, 5, 77, 72, 223, 51, 77, 72, 195, 20, 223, 51, 77, 72, 237, 3, - 221, 27, 248, 88, 1, 250, 120, 248, 88, 1, 210, 236, 248, 88, 1, 218, - 168, 248, 88, 1, 233, 175, 248, 88, 1, 238, 127, 248, 88, 1, 200, 43, - 248, 88, 1, 215, 61, 248, 88, 1, 172, 248, 88, 1, 232, 51, 248, 88, 1, - 222, 152, 248, 88, 1, 230, 116, 248, 88, 1, 223, 35, 248, 88, 1, 208, - 104, 248, 88, 1, 192, 235, 248, 88, 1, 191, 72, 248, 88, 1, 247, 3, 248, - 88, 1, 203, 167, 248, 88, 1, 146, 248, 88, 1, 191, 166, 248, 88, 1, 247, - 193, 248, 88, 1, 206, 8, 248, 88, 1, 65, 248, 88, 1, 74, 248, 88, 1, 71, - 248, 88, 1, 234, 173, 248, 88, 1, 251, 236, 248, 88, 1, 234, 166, 248, - 88, 1, 250, 163, 248, 88, 1, 211, 19, 248, 88, 1, 251, 132, 248, 88, 1, - 234, 103, 248, 88, 1, 251, 122, 248, 88, 1, 234, 88, 248, 88, 1, 234, 34, - 248, 88, 1, 68, 248, 88, 1, 66, 248, 88, 1, 223, 49, 248, 88, 1, 196, 12, - 248, 88, 1, 214, 70, 248, 88, 1, 231, 7, 248, 88, 1, 223, 200, 248, 88, - 1, 187, 4, 75, 58, 248, 88, 1, 213, 80, 30, 1, 221, 113, 30, 1, 201, 167, - 30, 1, 221, 106, 30, 1, 213, 204, 30, 1, 213, 202, 30, 1, 213, 201, 30, - 1, 198, 168, 30, 1, 201, 156, 30, 1, 206, 239, 30, 1, 206, 234, 30, 1, - 206, 231, 30, 1, 206, 224, 30, 1, 206, 219, 30, 1, 206, 214, 30, 1, 206, - 225, 30, 1, 206, 237, 30, 1, 216, 77, 30, 1, 209, 169, 30, 1, 201, 164, - 30, 1, 209, 158, 30, 1, 202, 160, 30, 1, 201, 161, 30, 1, 223, 222, 30, - 1, 243, 24, 30, 1, 201, 171, 30, 1, 243, 91, 30, 1, 221, 188, 30, 1, 199, - 7, 30, 1, 209, 209, 30, 1, 229, 142, 30, 1, 65, 30, 1, 252, 25, 30, 1, - 170, 30, 1, 192, 129, 30, 1, 234, 65, 30, 1, 71, 30, 1, 192, 67, 30, 1, - 192, 80, 30, 1, 74, 30, 1, 193, 190, 30, 1, 193, 176, 30, 1, 211, 151, - 30, 1, 192, 12, 30, 1, 66, 30, 1, 193, 107, 30, 1, 193, 125, 30, 1, 193, - 86, 30, 1, 191, 225, 30, 1, 233, 242, 30, 1, 192, 33, 30, 1, 68, 30, 233, - 3, 30, 1, 201, 165, 30, 1, 213, 194, 30, 1, 213, 196, 30, 1, 213, 199, - 30, 1, 206, 232, 30, 1, 206, 213, 30, 1, 206, 221, 30, 1, 206, 226, 30, - 1, 206, 211, 30, 1, 216, 70, 30, 1, 216, 67, 30, 1, 216, 71, 30, 1, 222, - 71, 30, 1, 209, 164, 30, 1, 209, 150, 30, 1, 209, 156, 30, 1, 209, 153, - 30, 1, 209, 167, 30, 1, 209, 151, 30, 1, 222, 69, 30, 1, 222, 67, 30, 1, - 202, 153, 30, 1, 202, 151, 30, 1, 202, 143, 30, 1, 202, 148, 30, 1, 202, - 158, 30, 1, 210, 149, 30, 1, 201, 168, 30, 1, 192, 57, 30, 1, 192, 51, - 30, 1, 192, 52, 30, 1, 222, 70, 30, 1, 201, 169, 30, 1, 192, 63, 30, 1, - 192, 0, 30, 1, 191, 255, 30, 1, 192, 2, 30, 1, 191, 212, 30, 1, 191, 213, - 30, 1, 191, 216, 30, 1, 251, 25, 30, 1, 251, 19, 154, 251, 96, 219, 101, - 77, 154, 251, 96, 207, 19, 77, 154, 251, 96, 91, 77, 154, 251, 96, 105, - 77, 154, 251, 96, 115, 77, 154, 251, 96, 232, 128, 77, 154, 251, 96, 198, - 54, 77, 154, 251, 96, 82, 77, 154, 251, 96, 248, 77, 77, 154, 251, 96, - 232, 238, 77, 154, 251, 96, 205, 57, 77, 154, 251, 96, 199, 1, 77, 154, - 251, 96, 232, 121, 77, 154, 251, 96, 229, 220, 77, 154, 251, 96, 234, - 208, 77, 154, 251, 96, 217, 91, 77, 248, 88, 1, 248, 10, 248, 88, 1, 191, - 30, 248, 88, 1, 222, 244, 248, 88, 1, 230, 179, 248, 88, 1, 234, 188, - 248, 88, 1, 234, 85, 248, 88, 1, 211, 87, 248, 88, 1, 211, 91, 248, 88, - 1, 223, 77, 248, 88, 1, 251, 98, 248, 88, 1, 223, 128, 248, 88, 1, 196, - 83, 248, 88, 1, 223, 180, 248, 88, 1, 214, 48, 248, 88, 1, 251, 229, 248, - 88, 1, 250, 158, 248, 88, 1, 251, 149, 248, 88, 1, 211, 113, 248, 88, 1, - 211, 94, 248, 88, 1, 223, 125, 248, 88, 53, 1, 210, 236, 248, 88, 53, 1, - 200, 43, 248, 88, 53, 1, 222, 152, 248, 88, 53, 1, 230, 116, 248, 88, 1, - 231, 92, 248, 88, 1, 219, 160, 248, 88, 1, 190, 231, 248, 88, 53, 1, 232, - 51, 248, 88, 1, 230, 136, 248, 88, 1, 220, 180, 248, 88, 1, 211, 151, - 248, 88, 1, 251, 245, 12, 201, 28, 200, 43, 12, 201, 28, 193, 98, 12, - 201, 28, 192, 209, 12, 201, 28, 247, 206, 12, 201, 28, 200, 151, 12, 201, - 28, 228, 78, 12, 201, 28, 228, 82, 12, 201, 28, 228, 169, 12, 201, 28, - 228, 79, 12, 201, 28, 200, 46, 12, 201, 28, 228, 81, 12, 201, 28, 228, - 77, 12, 201, 28, 228, 167, 12, 201, 28, 228, 80, 12, 201, 28, 228, 76, - 12, 201, 28, 215, 61, 12, 201, 28, 230, 116, 12, 201, 28, 206, 8, 12, - 201, 28, 210, 236, 12, 201, 28, 201, 250, 12, 201, 28, 238, 127, 12, 201, - 28, 228, 83, 12, 201, 28, 229, 178, 12, 201, 28, 200, 55, 12, 201, 28, - 200, 128, 12, 201, 28, 201, 118, 12, 201, 28, 203, 173, 12, 201, 28, 210, - 67, 12, 201, 28, 208, 106, 12, 201, 28, 198, 99, 12, 201, 28, 200, 45, - 12, 201, 28, 200, 140, 12, 201, 28, 228, 94, 12, 201, 28, 228, 75, 12, - 201, 28, 209, 230, 12, 201, 28, 208, 104, 72, 1, 2, 220, 232, 72, 1, 2, - 202, 222, 72, 1, 2, 201, 4, 72, 1, 2, 159, 72, 1, 2, 212, 178, 72, 1, 2, - 140, 72, 1, 2, 229, 158, 72, 1, 2, 228, 159, 72, 1, 2, 229, 245, 72, 1, - 2, 229, 23, 72, 1, 2, 215, 155, 72, 1, 2, 165, 72, 1, 2, 207, 1, 72, 1, - 2, 206, 68, 72, 1, 2, 207, 113, 72, 1, 2, 206, 162, 127, 30, 221, 113, - 127, 30, 213, 204, 127, 30, 198, 168, 127, 30, 206, 239, 127, 30, 216, - 77, 127, 30, 209, 169, 127, 30, 202, 160, 127, 30, 223, 222, 127, 30, - 243, 24, 127, 30, 243, 91, 127, 30, 221, 188, 127, 30, 199, 7, 127, 30, - 209, 209, 127, 30, 229, 142, 127, 30, 221, 114, 65, 127, 30, 213, 205, - 65, 127, 30, 198, 169, 65, 127, 30, 206, 240, 65, 127, 30, 216, 78, 65, - 127, 30, 209, 170, 65, 127, 30, 202, 161, 65, 127, 30, 223, 223, 65, 127, - 30, 243, 25, 65, 127, 30, 243, 92, 65, 127, 30, 221, 189, 65, 127, 30, - 199, 8, 65, 127, 30, 209, 210, 65, 127, 30, 229, 143, 65, 127, 30, 243, - 25, 66, 127, 221, 32, 246, 240, 211, 129, 127, 221, 32, 246, 240, 187, - 228, 159, 127, 228, 14, 107, 127, 228, 14, 109, 127, 228, 14, 138, 127, - 228, 14, 134, 127, 228, 14, 149, 127, 228, 14, 169, 127, 228, 14, 175, - 127, 228, 14, 171, 127, 228, 14, 178, 127, 228, 14, 199, 95, 127, 228, - 14, 215, 205, 127, 228, 14, 232, 243, 127, 228, 14, 193, 143, 127, 228, - 14, 193, 28, 127, 228, 14, 216, 165, 127, 228, 14, 234, 207, 127, 228, - 14, 200, 198, 127, 228, 14, 201, 66, 127, 228, 14, 229, 255, 127, 228, - 14, 202, 35, 127, 228, 14, 214, 227, 127, 228, 14, 201, 231, 127, 228, - 14, 232, 254, 127, 228, 14, 239, 50, 127, 228, 14, 220, 114, 127, 228, - 14, 207, 42, 127, 228, 14, 247, 138, 127, 228, 14, 201, 10, 127, 228, 14, - 200, 178, 127, 228, 14, 234, 75, 127, 228, 14, 207, 32, 127, 228, 14, - 251, 168, 127, 228, 14, 233, 31, 127, 228, 14, 207, 30, 127, 228, 14, - 204, 32, 127, 228, 14, 207, 108, 47, 228, 14, 208, 12, 47, 228, 14, 221, - 140, 47, 228, 14, 205, 89, 47, 228, 14, 221, 27, 47, 31, 199, 96, 211, - 105, 62, 201, 190, 47, 31, 197, 33, 211, 105, 62, 201, 190, 47, 31, 198, - 250, 211, 105, 62, 201, 190, 47, 31, 232, 136, 211, 105, 62, 201, 190, - 47, 31, 233, 16, 211, 105, 62, 201, 190, 47, 31, 202, 121, 211, 105, 62, - 201, 190, 47, 31, 203, 242, 211, 105, 62, 201, 190, 47, 31, 234, 154, - 211, 105, 62, 201, 190, 210, 103, 56, 47, 31, 197, 33, 107, 47, 31, 197, - 33, 109, 47, 31, 197, 33, 138, 47, 31, 197, 33, 134, 47, 31, 197, 33, - 149, 47, 31, 197, 33, 169, 47, 31, 197, 33, 175, 47, 31, 197, 33, 171, - 47, 31, 197, 33, 178, 47, 31, 198, 249, 47, 31, 198, 250, 107, 47, 31, - 198, 250, 109, 47, 31, 198, 250, 138, 47, 31, 198, 250, 134, 47, 31, 198, - 250, 149, 47, 30, 221, 113, 47, 30, 213, 204, 47, 30, 198, 168, 47, 30, - 206, 239, 47, 30, 216, 77, 47, 30, 209, 169, 47, 30, 202, 160, 47, 30, - 223, 222, 47, 30, 243, 24, 47, 30, 243, 91, 47, 30, 221, 188, 47, 30, - 199, 7, 47, 30, 209, 209, 47, 30, 229, 142, 47, 30, 221, 114, 65, 47, 30, - 213, 205, 65, 47, 30, 198, 169, 65, 47, 30, 206, 240, 65, 47, 30, 216, - 78, 65, 47, 30, 209, 170, 65, 47, 30, 202, 161, 65, 47, 30, 223, 223, 65, - 47, 30, 243, 25, 65, 47, 30, 243, 92, 65, 47, 30, 221, 189, 65, 47, 30, - 199, 8, 65, 47, 30, 209, 210, 65, 47, 30, 229, 143, 65, 47, 221, 32, 246, - 240, 246, 247, 47, 221, 32, 246, 240, 222, 178, 47, 30, 223, 223, 66, - 221, 32, 201, 106, 113, 47, 228, 14, 107, 47, 228, 14, 109, 47, 228, 14, - 138, 47, 228, 14, 134, 47, 228, 14, 149, 47, 228, 14, 169, 47, 228, 14, - 175, 47, 228, 14, 171, 47, 228, 14, 178, 47, 228, 14, 199, 95, 47, 228, - 14, 215, 205, 47, 228, 14, 232, 243, 47, 228, 14, 193, 143, 47, 228, 14, - 193, 28, 47, 228, 14, 216, 165, 47, 228, 14, 234, 207, 47, 228, 14, 200, - 198, 47, 228, 14, 201, 66, 47, 228, 14, 229, 255, 47, 228, 14, 202, 35, - 47, 228, 14, 214, 227, 47, 228, 14, 201, 231, 47, 228, 14, 232, 254, 47, - 228, 14, 239, 50, 47, 228, 14, 220, 114, 47, 228, 14, 205, 55, 47, 228, - 14, 217, 96, 47, 228, 14, 233, 41, 47, 228, 14, 200, 210, 47, 228, 14, - 233, 220, 47, 228, 14, 208, 211, 47, 228, 14, 250, 167, 47, 228, 14, 223, - 52, 47, 228, 14, 207, 30, 47, 228, 14, 239, 8, 47, 228, 14, 238, 251, 47, - 228, 14, 229, 135, 47, 228, 14, 247, 21, 47, 228, 14, 218, 241, 47, 228, - 14, 219, 224, 47, 228, 14, 183, 47, 228, 14, 216, 215, 47, 228, 14, 207, - 60, 47, 228, 14, 201, 10, 47, 228, 14, 200, 178, 47, 228, 14, 234, 75, - 47, 228, 14, 207, 32, 47, 228, 14, 251, 168, 47, 228, 14, 213, 190, 47, + 250, 51, 4, 45, 132, 248, 141, 51, 4, 50, 132, 248, 141, 51, 4, 116, 45, + 237, 41, 132, 248, 141, 51, 4, 110, 50, 237, 41, 132, 248, 141, 63, 51, + 4, 81, 248, 156, 219, 114, 63, 196, 76, 197, 242, 4, 236, 142, 196, 76, + 197, 242, 4, 45, 132, 248, 141, 196, 76, 197, 242, 4, 50, 132, 248, 141, + 220, 15, 243, 12, 63, 51, 4, 116, 45, 208, 29, 63, 51, 4, 110, 45, 208, + 29, 63, 51, 4, 110, 50, 208, 29, 63, 51, 4, 116, 50, 208, 29, 63, 243, + 13, 4, 116, 45, 208, 29, 63, 243, 13, 4, 110, 45, 208, 29, 63, 243, 13, + 4, 110, 50, 208, 29, 63, 243, 13, 4, 116, 50, 208, 29, 116, 45, 197, 241, + 116, 50, 197, 241, 110, 45, 197, 241, 63, 216, 215, 201, 191, 62, 216, + 215, 201, 191, 63, 216, 215, 2, 201, 191, 62, 216, 215, 2, 201, 191, 110, + 50, 197, 241, 62, 200, 199, 4, 207, 121, 242, 212, 196, 117, 202, 49, + 242, 79, 62, 201, 103, 63, 201, 103, 219, 131, 198, 208, 200, 198, 250, + 215, 213, 37, 237, 88, 213, 37, 239, 44, 211, 64, 62, 199, 106, 63, 199, + 106, 249, 109, 248, 64, 249, 109, 111, 4, 243, 127, 249, 109, 111, 4, + 192, 235, 205, 155, 196, 118, 4, 207, 152, 235, 98, 228, 183, 248, 209, + 63, 203, 50, 209, 177, 62, 203, 50, 209, 177, 203, 141, 207, 19, 206, + 123, 232, 192, 229, 226, 247, 250, 62, 45, 209, 60, 223, 150, 62, 50, + 209, 60, 223, 150, 63, 45, 209, 60, 223, 150, 63, 133, 209, 60, 223, 150, + 63, 50, 209, 60, 223, 150, 63, 144, 209, 60, 223, 150, 202, 105, 23, 238, + 217, 247, 73, 56, 207, 166, 56, 248, 164, 56, 247, 153, 251, 101, 211, + 41, 238, 219, 243, 98, 207, 4, 238, 220, 79, 219, 1, 238, 220, 79, 223, + 0, 201, 104, 23, 238, 229, 233, 76, 113, 252, 36, 203, 144, 230, 64, 23, + 202, 214, 210, 63, 113, 192, 22, 192, 106, 197, 231, 40, 229, 221, 197, + 231, 40, 220, 45, 197, 231, 40, 232, 245, 197, 231, 40, 198, 209, 197, + 231, 40, 193, 66, 197, 231, 40, 193, 143, 197, 231, 40, 215, 186, 197, + 231, 40, 234, 209, 193, 94, 79, 237, 62, 63, 232, 94, 233, 105, 63, 202, + 65, 233, 105, 62, 202, 65, 233, 105, 63, 200, 199, 4, 207, 121, 232, 240, + 208, 25, 215, 207, 220, 8, 208, 25, 215, 207, 216, 182, 233, 44, 56, 234, + 209, 217, 99, 56, 222, 169, 205, 116, 196, 57, 214, 96, 209, 79, 251, 4, + 199, 164, 231, 154, 247, 126, 219, 188, 195, 38, 219, 145, 205, 81, 205, + 184, 247, 108, 251, 36, 209, 122, 63, 243, 107, 221, 140, 63, 243, 107, + 208, 16, 63, 243, 107, 206, 132, 63, 243, 107, 248, 154, 63, 243, 107, + 221, 78, 63, 243, 107, 210, 76, 62, 243, 107, 221, 140, 62, 243, 107, + 208, 16, 62, 243, 107, 206, 132, 62, 243, 107, 248, 154, 62, 243, 107, + 221, 78, 62, 243, 107, 210, 76, 62, 201, 246, 200, 211, 63, 229, 226, + 200, 211, 63, 237, 35, 200, 211, 62, 242, 209, 200, 211, 63, 201, 246, + 200, 211, 62, 229, 226, 200, 211, 62, 237, 35, 200, 211, 63, 242, 209, + 200, 211, 228, 183, 201, 196, 208, 25, 213, 8, 234, 162, 213, 8, 249, 15, + 234, 162, 213, 3, 249, 15, 202, 130, 213, 3, 215, 99, 232, 209, 56, 215, + 99, 214, 208, 56, 215, 99, 203, 128, 56, 193, 105, 200, 63, 238, 219, + 234, 206, 200, 63, 238, 219, 196, 87, 207, 90, 113, 207, 90, 16, 40, 196, + 254, 209, 100, 207, 90, 16, 40, 196, 252, 209, 100, 207, 90, 16, 40, 196, + 251, 209, 100, 207, 90, 16, 40, 196, 249, 209, 100, 207, 90, 16, 40, 196, + 247, 209, 100, 207, 90, 16, 40, 196, 245, 209, 100, 207, 90, 16, 40, 196, + 243, 209, 100, 207, 90, 16, 40, 231, 151, 217, 30, 62, 196, 87, 207, 90, + 113, 207, 91, 210, 138, 113, 210, 106, 210, 138, 113, 210, 5, 210, 138, + 56, 193, 92, 113, 237, 27, 233, 104, 237, 27, 233, 103, 237, 27, 233, + 102, 237, 27, 233, 101, 237, 27, 233, 100, 237, 27, 233, 99, 63, 243, 13, + 4, 75, 179, 63, 243, 13, 4, 105, 236, 140, 62, 243, 13, 4, 63, 75, 179, + 62, 243, 13, 4, 105, 63, 236, 140, 215, 223, 40, 192, 106, 215, 223, 40, + 192, 21, 237, 8, 40, 230, 207, 192, 106, 237, 8, 40, 219, 180, 192, 21, + 237, 8, 40, 219, 180, 192, 106, 237, 8, 40, 230, 207, 192, 21, 63, 232, + 219, 62, 232, 219, 230, 64, 23, 209, 182, 251, 129, 238, 216, 200, 130, + 201, 113, 79, 252, 10, 205, 99, 251, 193, 232, 188, 231, 164, 201, 113, + 79, 229, 193, 250, 174, 113, 232, 204, 211, 12, 63, 201, 103, 115, 219, + 109, 239, 21, 179, 115, 219, 109, 239, 21, 219, 226, 193, 155, 56, 137, + 195, 12, 56, 235, 130, 233, 44, 56, 235, 130, 217, 99, 56, 223, 107, 233, + 44, 23, 217, 99, 56, 217, 99, 23, 233, 44, 56, 217, 99, 4, 201, 29, 56, + 217, 99, 4, 201, 29, 23, 217, 99, 23, 233, 44, 56, 81, 217, 99, 4, 201, + 29, 56, 228, 243, 217, 99, 4, 201, 29, 56, 216, 215, 63, 243, 12, 216, + 215, 62, 243, 12, 216, 215, 2, 63, 243, 12, 217, 50, 113, 236, 200, 113, + 196, 84, 210, 105, 113, 242, 91, 232, 76, 196, 53, 214, 85, 247, 9, 210, + 187, 222, 175, 195, 80, 243, 77, 62, 215, 208, 219, 128, 203, 177, 204, + 23, 208, 6, 204, 0, 202, 37, 249, 113, 249, 75, 112, 221, 224, 63, 235, + 110, 217, 92, 63, 235, 110, 221, 140, 62, 235, 110, 217, 92, 62, 235, + 110, 221, 140, 202, 50, 193, 51, 202, 53, 200, 199, 248, 244, 242, 212, + 207, 151, 62, 202, 49, 198, 210, 242, 213, 23, 207, 151, 154, 63, 203, + 50, 209, 177, 154, 62, 203, 50, 209, 177, 63, 237, 35, 223, 165, 201, + 191, 238, 212, 220, 23, 236, 231, 247, 104, 211, 67, 209, 182, 247, 105, + 202, 86, 229, 203, 4, 63, 238, 219, 47, 238, 212, 220, 23, 246, 255, 213, + 46, 234, 74, 251, 159, 211, 98, 45, 193, 129, 198, 19, 62, 197, 10, 45, + 193, 129, 198, 19, 63, 197, 10, 45, 193, 129, 198, 19, 62, 45, 220, 24, + 216, 181, 63, 45, 220, 24, 216, 181, 235, 105, 202, 77, 56, 88, 63, 235, + 124, 197, 241, 45, 242, 221, 234, 74, 112, 205, 155, 233, 85, 237, 41, + 223, 165, 63, 243, 13, 223, 165, 62, 201, 191, 62, 197, 203, 207, 30, 45, + 234, 73, 207, 30, 45, 234, 72, 250, 189, 16, 40, 196, 57, 88, 243, 13, 4, + 201, 29, 23, 105, 185, 58, 210, 25, 206, 206, 223, 109, 210, 25, 219, + 223, 223, 109, 210, 25, 223, 95, 210, 25, 62, 238, 220, 211, 107, 203, + 79, 203, 67, 203, 13, 243, 42, 247, 82, 229, 120, 202, 138, 231, 165, + 193, 51, 228, 155, 231, 165, 4, 230, 32, 217, 74, 16, 40, 219, 133, 215, + 186, 196, 118, 211, 107, 230, 190, 232, 131, 232, 220, 223, 165, 229, 7, + 233, 34, 205, 179, 51, 232, 130, 239, 2, 202, 109, 228, 29, 202, 113, + 209, 253, 4, 249, 113, 199, 87, 223, 21, 249, 95, 113, 229, 231, 230, + 209, 113, 232, 85, 208, 155, 238, 184, 211, 107, 62, 201, 191, 63, 232, + 220, 4, 228, 243, 82, 62, 201, 30, 62, 205, 189, 205, 85, 116, 248, 136, + 205, 85, 62, 205, 85, 110, 248, 136, 205, 85, 63, 205, 85, 63, 88, 243, + 128, 77, 199, 107, 219, 42, 56, 199, 182, 235, 104, 251, 225, 234, 69, + 207, 149, 232, 233, 207, 149, 230, 55, 195, 67, 230, 55, 193, 3, 230, 55, + 110, 50, 210, 35, 210, 35, 116, 50, 210, 35, 63, 213, 210, 62, 213, 210, + 243, 128, 77, 88, 243, 128, 77, 215, 129, 192, 235, 88, 215, 129, 192, + 235, 249, 109, 192, 235, 88, 249, 109, 192, 235, 211, 12, 35, 238, 219, + 88, 35, 238, 219, 211, 79, 247, 24, 238, 219, 88, 211, 79, 247, 24, 238, + 219, 8, 238, 219, 203, 152, 63, 8, 238, 219, 211, 12, 8, 238, 219, 217, + 95, 238, 219, 201, 104, 79, 237, 210, 232, 130, 199, 127, 250, 195, 232, + 130, 249, 110, 250, 195, 88, 232, 130, 249, 110, 250, 195, 232, 130, 242, + 207, 250, 195, 62, 232, 130, 209, 62, 201, 103, 63, 232, 130, 209, 62, + 201, 103, 201, 241, 201, 39, 211, 12, 63, 201, 103, 47, 63, 201, 103, + 211, 79, 247, 24, 62, 201, 103, 62, 247, 24, 63, 201, 103, 211, 12, 62, + 201, 103, 88, 211, 12, 62, 201, 103, 209, 132, 201, 103, 203, 152, 63, + 201, 103, 88, 250, 195, 211, 79, 247, 24, 250, 195, 234, 166, 201, 207, + 250, 195, 234, 166, 209, 62, 62, 201, 103, 234, 166, 209, 62, 209, 132, + 201, 103, 202, 137, 209, 62, 62, 201, 103, 234, 166, 209, 62, 207, 92, + 62, 201, 103, 88, 234, 166, 209, 62, 207, 92, 62, 201, 103, 197, 38, 209, + 62, 62, 201, 103, 202, 132, 209, 62, 250, 195, 199, 127, 250, 195, 211, + 79, 247, 24, 199, 127, 250, 195, 88, 199, 127, 250, 195, 202, 137, 209, + 241, 62, 23, 63, 232, 191, 62, 232, 191, 63, 232, 191, 234, 166, 209, + 241, 211, 12, 62, 232, 191, 47, 211, 79, 247, 24, 234, 166, 209, 62, 201, + 103, 88, 199, 127, 209, 132, 250, 195, 202, 51, 198, 172, 197, 234, 202, + 51, 88, 243, 103, 202, 51, 201, 243, 88, 201, 243, 249, 110, 250, 195, + 234, 166, 199, 127, 208, 191, 250, 195, 88, 234, 166, 199, 127, 208, 191, + 250, 195, 238, 220, 77, 203, 152, 63, 243, 12, 214, 108, 112, 238, 220, + 77, 110, 50, 235, 100, 63, 201, 191, 116, 50, 235, 100, 63, 201, 191, + 110, 50, 203, 152, 63, 201, 191, 116, 50, 203, 152, 63, 201, 191, 62, + 208, 15, 87, 211, 44, 63, 208, 15, 87, 211, 44, 63, 233, 218, 87, 211, + 44, 62, 237, 35, 216, 37, 63, 192, 235, 88, 233, 218, 87, 113, 156, 81, + 164, 216, 215, 81, 164, 88, 81, 164, 88, 202, 171, 154, 242, 77, 207, + 254, 87, 211, 44, 88, 202, 171, 242, 77, 207, 254, 87, 211, 44, 88, 55, + 154, 242, 77, 207, 254, 87, 211, 44, 88, 55, 242, 77, 207, 254, 87, 211, + 44, 88, 130, 202, 171, 242, 77, 207, 254, 87, 211, 44, 88, 130, 55, 242, + 77, 207, 254, 87, 211, 44, 238, 165, 201, 82, 210, 130, 3, 211, 44, 88, + 233, 218, 87, 211, 44, 88, 229, 226, 233, 218, 87, 211, 44, 88, 62, 229, + 225, 206, 123, 88, 62, 229, 226, 247, 250, 232, 192, 229, 225, 206, 123, + 232, 192, 229, 226, 247, 250, 216, 215, 45, 210, 116, 211, 44, 216, 215, + 50, 210, 116, 211, 44, 216, 215, 232, 205, 45, 210, 116, 211, 44, 216, + 215, 232, 205, 50, 210, 116, 211, 44, 216, 215, 219, 221, 251, 118, 248, + 56, 211, 44, 216, 215, 206, 204, 251, 118, 248, 56, 211, 44, 88, 219, + 221, 251, 118, 207, 254, 87, 211, 44, 88, 206, 204, 251, 118, 207, 254, + 87, 211, 44, 88, 219, 221, 251, 118, 248, 56, 211, 44, 88, 206, 204, 251, + 118, 248, 56, 211, 44, 156, 45, 198, 42, 203, 104, 248, 56, 211, 44, 156, + 50, 198, 42, 203, 104, 248, 56, 211, 44, 216, 215, 45, 238, 173, 248, 56, + 211, 44, 216, 215, 50, 238, 173, 248, 56, 211, 44, 236, 243, 214, 108, + 47, 17, 107, 236, 243, 214, 108, 47, 17, 109, 236, 243, 214, 108, 47, 17, + 138, 236, 243, 214, 108, 47, 17, 134, 236, 243, 214, 108, 47, 17, 150, + 236, 243, 214, 108, 47, 17, 169, 236, 243, 214, 108, 47, 17, 175, 236, + 243, 214, 108, 47, 17, 171, 236, 243, 214, 108, 47, 17, 178, 236, 243, + 214, 108, 47, 31, 199, 95, 236, 243, 47, 49, 17, 107, 236, 243, 47, 49, + 17, 109, 236, 243, 47, 49, 17, 138, 236, 243, 47, 49, 17, 134, 236, 243, + 47, 49, 17, 150, 236, 243, 47, 49, 17, 169, 236, 243, 47, 49, 17, 175, + 236, 243, 47, 49, 17, 171, 236, 243, 47, 49, 17, 178, 236, 243, 47, 49, + 31, 199, 95, 236, 243, 214, 108, 47, 49, 17, 107, 236, 243, 214, 108, 47, + 49, 17, 109, 236, 243, 214, 108, 47, 49, 17, 138, 236, 243, 214, 108, 47, + 49, 17, 134, 236, 243, 214, 108, 47, 49, 17, 150, 236, 243, 214, 108, 47, + 49, 17, 169, 236, 243, 214, 108, 47, 49, 17, 175, 236, 243, 214, 108, 47, + 49, 17, 171, 236, 243, 214, 108, 47, 49, 17, 178, 236, 243, 214, 108, 47, + 49, 31, 199, 95, 88, 193, 77, 96, 57, 88, 108, 56, 88, 216, 37, 56, 88, + 236, 202, 56, 88, 202, 3, 234, 206, 57, 88, 96, 57, 88, 186, 234, 206, + 57, 235, 115, 209, 64, 96, 57, 88, 206, 115, 96, 57, 197, 240, 96, 57, + 88, 197, 240, 96, 57, 237, 216, 197, 240, 96, 57, 88, 237, 216, 197, 240, + 96, 57, 62, 96, 57, 198, 225, 198, 52, 96, 250, 237, 198, 225, 248, 77, + 96, 250, 237, 62, 96, 250, 237, 88, 62, 238, 165, 235, 121, 23, 96, 57, + 88, 62, 238, 165, 196, 66, 23, 96, 57, 201, 188, 62, 96, 57, 88, 239, 58, + 62, 96, 57, 206, 203, 63, 96, 57, 219, 220, 63, 96, 57, 249, 147, 203, + 152, 63, 96, 57, 232, 97, 203, 152, 63, 96, 57, 88, 110, 206, 202, 63, + 96, 57, 88, 116, 206, 202, 63, 96, 57, 213, 10, 110, 206, 202, 63, 96, + 57, 238, 173, 219, 6, 213, 10, 116, 206, 202, 63, 96, 57, 47, 88, 63, 96, + 57, 193, 88, 96, 57, 248, 140, 202, 3, 234, 206, 57, 248, 140, 96, 57, + 248, 140, 186, 234, 206, 57, 88, 248, 140, 202, 3, 234, 206, 57, 88, 248, + 140, 96, 57, 88, 248, 140, 186, 234, 206, 57, 199, 129, 96, 57, 88, 199, + 128, 96, 57, 193, 115, 96, 57, 88, 193, 115, 96, 57, 211, 73, 96, 57, 55, + 238, 173, 219, 6, 115, 236, 253, 251, 117, 63, 197, 242, 239, 35, 2, 63, + 197, 241, 210, 0, 211, 79, 200, 229, 211, 79, 200, 180, 45, 206, 8, 249, + 133, 237, 114, 50, 206, 8, 249, 133, 237, 114, 211, 59, 4, 75, 223, 119, + 207, 20, 202, 25, 208, 232, 200, 229, 200, 181, 208, 232, 202, 24, 81, + 249, 90, 4, 228, 243, 106, 13, 206, 181, 237, 40, 180, 236, 201, 13, 233, + 85, 237, 40, 112, 219, 31, 251, 127, 112, 219, 31, 211, 58, 63, 237, 35, + 4, 247, 22, 236, 142, 23, 4, 236, 142, 234, 134, 79, 211, 71, 196, 65, + 110, 50, 239, 4, 4, 236, 142, 116, 45, 239, 4, 4, 236, 142, 45, 211, 14, + 222, 201, 50, 211, 14, 222, 201, 232, 82, 211, 14, 222, 201, 220, 15, + 133, 199, 228, 220, 15, 144, 199, 228, 45, 23, 50, 55, 197, 57, 45, 23, + 50, 199, 228, 45, 215, 133, 180, 50, 199, 228, 180, 45, 199, 228, 133, + 199, 229, 4, 243, 13, 58, 218, 235, 236, 208, 247, 207, 228, 243, 206, + 53, 63, 239, 57, 237, 34, 63, 239, 57, 237, 35, 4, 118, 198, 182, 63, + 239, 57, 237, 35, 4, 96, 198, 182, 63, 51, 4, 118, 198, 182, 63, 51, 4, + 96, 198, 182, 13, 45, 63, 51, 248, 55, 13, 50, 63, 51, 248, 55, 13, 45, + 251, 118, 248, 55, 13, 50, 251, 118, 248, 55, 13, 45, 55, 251, 118, 248, + 55, 13, 50, 55, 251, 118, 248, 55, 13, 45, 63, 198, 42, 203, 104, 248, + 55, 13, 50, 63, 198, 42, 203, 104, 248, 55, 13, 45, 232, 205, 210, 115, + 13, 50, 232, 205, 210, 115, 196, 66, 208, 28, 57, 235, 121, 208, 28, 57, + 251, 87, 231, 204, 243, 13, 57, 242, 223, 231, 204, 243, 13, 57, 50, 64, + 4, 47, 209, 83, 180, 118, 57, 180, 96, 57, 180, 45, 50, 57, 180, 118, 55, + 57, 180, 96, 55, 57, 180, 45, 50, 55, 57, 180, 118, 64, 232, 100, 164, + 180, 96, 64, 232, 100, 164, 180, 118, 55, 64, 232, 100, 164, 180, 96, 55, + 64, 232, 100, 164, 180, 96, 201, 184, 57, 69, 70, 248, 134, 69, 70, 236, + 139, 69, 70, 236, 11, 69, 70, 236, 138, 69, 70, 235, 203, 69, 70, 236, + 74, 69, 70, 236, 10, 69, 70, 236, 137, 69, 70, 235, 171, 69, 70, 236, 42, + 69, 70, 235, 234, 69, 70, 236, 105, 69, 70, 235, 202, 69, 70, 236, 73, + 69, 70, 236, 9, 69, 70, 236, 136, 69, 70, 235, 155, 69, 70, 236, 26, 69, + 70, 235, 218, 69, 70, 236, 89, 69, 70, 235, 186, 69, 70, 236, 57, 69, 70, + 235, 249, 69, 70, 236, 120, 69, 70, 235, 170, 69, 70, 236, 41, 69, 70, + 235, 233, 69, 70, 236, 104, 69, 70, 235, 201, 69, 70, 236, 72, 69, 70, + 236, 8, 69, 70, 236, 135, 69, 70, 235, 147, 69, 70, 236, 18, 69, 70, 235, + 210, 69, 70, 236, 81, 69, 70, 235, 178, 69, 70, 236, 49, 69, 70, 235, + 241, 69, 70, 236, 112, 69, 70, 235, 162, 69, 70, 236, 33, 69, 70, 235, + 225, 69, 70, 236, 96, 69, 70, 235, 193, 69, 70, 236, 64, 69, 70, 236, 0, + 69, 70, 236, 127, 69, 70, 235, 154, 69, 70, 236, 25, 69, 70, 235, 217, + 69, 70, 236, 88, 69, 70, 235, 185, 69, 70, 236, 56, 69, 70, 235, 248, 69, + 70, 236, 119, 69, 70, 235, 169, 69, 70, 236, 40, 69, 70, 235, 232, 69, + 70, 236, 103, 69, 70, 235, 200, 69, 70, 236, 71, 69, 70, 236, 7, 69, 70, + 236, 134, 69, 70, 235, 143, 69, 70, 236, 14, 69, 70, 235, 206, 69, 70, + 236, 77, 69, 70, 235, 174, 69, 70, 236, 45, 69, 70, 235, 237, 69, 70, + 236, 108, 69, 70, 235, 158, 69, 70, 236, 29, 69, 70, 235, 221, 69, 70, + 236, 92, 69, 70, 235, 189, 69, 70, 236, 60, 69, 70, 235, 252, 69, 70, + 236, 123, 69, 70, 235, 150, 69, 70, 236, 21, 69, 70, 235, 213, 69, 70, + 236, 84, 69, 70, 235, 181, 69, 70, 236, 52, 69, 70, 235, 244, 69, 70, + 236, 115, 69, 70, 235, 165, 69, 70, 236, 36, 69, 70, 235, 228, 69, 70, + 236, 99, 69, 70, 235, 196, 69, 70, 236, 67, 69, 70, 236, 3, 69, 70, 236, + 130, 69, 70, 235, 146, 69, 70, 236, 17, 69, 70, 235, 209, 69, 70, 236, + 80, 69, 70, 235, 177, 69, 70, 236, 48, 69, 70, 235, 240, 69, 70, 236, + 111, 69, 70, 235, 161, 69, 70, 236, 32, 69, 70, 235, 224, 69, 70, 236, + 95, 69, 70, 235, 192, 69, 70, 236, 63, 69, 70, 235, 255, 69, 70, 236, + 126, 69, 70, 235, 153, 69, 70, 236, 24, 69, 70, 235, 216, 69, 70, 236, + 87, 69, 70, 235, 184, 69, 70, 236, 55, 69, 70, 235, 247, 69, 70, 236, + 118, 69, 70, 235, 168, 69, 70, 236, 39, 69, 70, 235, 231, 69, 70, 236, + 102, 69, 70, 235, 199, 69, 70, 236, 70, 69, 70, 236, 6, 69, 70, 236, 133, + 69, 70, 235, 141, 69, 70, 236, 12, 69, 70, 235, 204, 69, 70, 236, 75, 69, + 70, 235, 172, 69, 70, 236, 43, 69, 70, 235, 235, 69, 70, 236, 106, 69, + 70, 235, 156, 69, 70, 236, 27, 69, 70, 235, 219, 69, 70, 236, 90, 69, 70, + 235, 187, 69, 70, 236, 58, 69, 70, 235, 250, 69, 70, 236, 121, 69, 70, + 235, 148, 69, 70, 236, 19, 69, 70, 235, 211, 69, 70, 236, 82, 69, 70, + 235, 179, 69, 70, 236, 50, 69, 70, 235, 242, 69, 70, 236, 113, 69, 70, + 235, 163, 69, 70, 236, 34, 69, 70, 235, 226, 69, 70, 236, 97, 69, 70, + 235, 194, 69, 70, 236, 65, 69, 70, 236, 1, 69, 70, 236, 128, 69, 70, 235, + 144, 69, 70, 236, 15, 69, 70, 235, 207, 69, 70, 236, 78, 69, 70, 235, + 175, 69, 70, 236, 46, 69, 70, 235, 238, 69, 70, 236, 109, 69, 70, 235, + 159, 69, 70, 236, 30, 69, 70, 235, 222, 69, 70, 236, 93, 69, 70, 235, + 190, 69, 70, 236, 61, 69, 70, 235, 253, 69, 70, 236, 124, 69, 70, 235, + 151, 69, 70, 236, 22, 69, 70, 235, 214, 69, 70, 236, 85, 69, 70, 235, + 182, 69, 70, 236, 53, 69, 70, 235, 245, 69, 70, 236, 116, 69, 70, 235, + 166, 69, 70, 236, 37, 69, 70, 235, 229, 69, 70, 236, 100, 69, 70, 235, + 197, 69, 70, 236, 68, 69, 70, 236, 4, 69, 70, 236, 131, 69, 70, 235, 142, + 69, 70, 236, 13, 69, 70, 235, 205, 69, 70, 236, 76, 69, 70, 235, 173, 69, + 70, 236, 44, 69, 70, 235, 236, 69, 70, 236, 107, 69, 70, 235, 157, 69, + 70, 236, 28, 69, 70, 235, 220, 69, 70, 236, 91, 69, 70, 235, 188, 69, 70, + 236, 59, 69, 70, 235, 251, 69, 70, 236, 122, 69, 70, 235, 149, 69, 70, + 236, 20, 69, 70, 235, 212, 69, 70, 236, 83, 69, 70, 235, 180, 69, 70, + 236, 51, 69, 70, 235, 243, 69, 70, 236, 114, 69, 70, 235, 164, 69, 70, + 236, 35, 69, 70, 235, 227, 69, 70, 236, 98, 69, 70, 235, 195, 69, 70, + 236, 66, 69, 70, 236, 2, 69, 70, 236, 129, 69, 70, 235, 145, 69, 70, 236, + 16, 69, 70, 235, 208, 69, 70, 236, 79, 69, 70, 235, 176, 69, 70, 236, 47, + 69, 70, 235, 239, 69, 70, 236, 110, 69, 70, 235, 160, 69, 70, 236, 31, + 69, 70, 235, 223, 69, 70, 236, 94, 69, 70, 235, 191, 69, 70, 236, 62, 69, + 70, 235, 254, 69, 70, 236, 125, 69, 70, 235, 152, 69, 70, 236, 23, 69, + 70, 235, 215, 69, 70, 236, 86, 69, 70, 235, 183, 69, 70, 236, 54, 69, 70, + 235, 246, 69, 70, 236, 117, 69, 70, 235, 167, 69, 70, 236, 38, 69, 70, + 235, 230, 69, 70, 236, 101, 69, 70, 235, 198, 69, 70, 236, 69, 69, 70, + 236, 5, 69, 70, 236, 132, 96, 197, 13, 64, 4, 81, 106, 96, 197, 13, 64, + 4, 55, 81, 106, 118, 55, 64, 4, 81, 106, 96, 55, 64, 4, 81, 106, 45, 50, + 55, 64, 4, 81, 106, 96, 197, 13, 64, 232, 100, 164, 118, 55, 64, 232, + 100, 164, 96, 55, 64, 232, 100, 164, 235, 121, 64, 4, 228, 243, 106, 196, + 66, 64, 4, 228, 243, 106, 196, 66, 197, 225, 57, 235, 121, 197, 225, 57, + 118, 55, 237, 218, 57, 96, 55, 237, 218, 57, 118, 197, 225, 237, 218, 57, + 96, 197, 225, 237, 218, 57, 96, 197, 13, 197, 225, 237, 218, 57, 96, 64, + 4, 235, 140, 201, 81, 196, 66, 64, 119, 164, 235, 121, 64, 119, 164, 96, + 64, 4, 199, 216, 4, 81, 106, 96, 64, 4, 199, 216, 4, 55, 81, 106, 96, + 197, 13, 64, 4, 199, 215, 96, 197, 13, 64, 4, 199, 216, 4, 81, 106, 96, + 197, 13, 64, 4, 199, 216, 4, 55, 81, 106, 118, 250, 239, 96, 250, 239, + 118, 55, 250, 239, 96, 55, 250, 239, 118, 64, 119, 62, 237, 34, 96, 64, + 119, 62, 237, 34, 118, 64, 232, 100, 249, 90, 119, 62, 237, 34, 96, 64, + 232, 100, 249, 90, 119, 62, 237, 34, 186, 193, 105, 23, 202, 3, 234, 206, + 57, 186, 234, 206, 23, 202, 3, 193, 105, 57, 186, 193, 105, 64, 4, 102, + 186, 234, 206, 64, 4, 102, 202, 3, 234, 206, 64, 4, 102, 202, 3, 193, + 105, 64, 4, 102, 186, 193, 105, 64, 23, 186, 234, 206, 57, 186, 234, 206, + 64, 23, 202, 3, 234, 206, 57, 202, 3, 234, 206, 64, 23, 202, 3, 193, 105, + 57, 202, 3, 193, 105, 64, 23, 186, 193, 105, 57, 206, 181, 237, 41, 238, + 212, 233, 85, 237, 40, 233, 85, 237, 41, 238, 212, 206, 181, 237, 40, + 202, 3, 234, 206, 64, 238, 212, 186, 234, 206, 57, 186, 234, 206, 64, + 238, 212, 202, 3, 234, 206, 57, 233, 85, 237, 41, 238, 212, 186, 234, + 206, 57, 206, 181, 237, 41, 238, 212, 202, 3, 234, 206, 57, 186, 234, + 206, 64, 238, 212, 186, 193, 105, 57, 186, 193, 105, 64, 238, 212, 186, + 234, 206, 57, 193, 139, 64, 209, 60, 236, 233, 179, 64, 209, 60, 96, 199, + 25, 238, 163, 196, 65, 64, 209, 60, 96, 199, 25, 238, 163, 235, 120, 64, + 209, 60, 235, 121, 199, 25, 238, 163, 219, 216, 64, 209, 60, 235, 121, + 199, 25, 238, 163, 206, 198, 206, 201, 251, 19, 242, 223, 57, 219, 219, + 251, 19, 251, 87, 57, 198, 54, 251, 19, 251, 87, 57, 248, 79, 251, 19, + 251, 87, 57, 198, 54, 251, 19, 242, 223, 64, 4, 216, 36, 198, 54, 251, + 19, 251, 87, 64, 4, 209, 83, 110, 50, 204, 28, 242, 223, 57, 110, 45, + 204, 28, 251, 87, 57, 251, 87, 242, 221, 243, 13, 57, 242, 223, 242, 221, + 243, 13, 57, 96, 64, 93, 203, 41, 118, 57, 118, 64, 93, 203, 41, 96, 57, + 203, 41, 96, 64, 93, 118, 57, 96, 64, 4, 108, 60, 118, 64, 4, 108, 60, + 96, 64, 198, 216, 192, 235, 45, 50, 64, 198, 216, 2, 243, 12, 196, 66, + 197, 13, 64, 232, 100, 2, 243, 12, 45, 182, 133, 50, 182, 144, 230, 14, + 45, 182, 144, 50, 182, 133, 230, 14, 133, 182, 50, 144, 182, 45, 230, 14, + 133, 182, 45, 144, 182, 50, 230, 14, 45, 182, 133, 50, 182, 133, 230, 14, + 133, 182, 50, 144, 182, 50, 230, 14, 45, 182, 144, 50, 182, 144, 230, 14, + 133, 182, 45, 144, 182, 45, 230, 14, 118, 230, 15, 4, 182, 133, 119, 164, + 96, 230, 15, 4, 182, 133, 119, 164, 196, 66, 230, 15, 4, 182, 50, 119, + 164, 235, 121, 230, 15, 4, 182, 50, 119, 164, 118, 230, 15, 4, 182, 144, + 119, 164, 96, 230, 15, 4, 182, 144, 119, 164, 196, 66, 230, 15, 4, 182, + 45, 119, 164, 235, 121, 230, 15, 4, 182, 45, 119, 164, 118, 230, 15, 4, + 182, 133, 232, 100, 164, 96, 230, 15, 4, 182, 133, 232, 100, 164, 196, + 66, 230, 15, 4, 182, 50, 232, 100, 164, 235, 121, 230, 15, 4, 182, 50, + 232, 100, 164, 118, 230, 15, 4, 182, 144, 232, 100, 164, 96, 230, 15, 4, + 182, 144, 232, 100, 164, 196, 66, 230, 15, 4, 182, 45, 232, 100, 164, + 235, 121, 230, 15, 4, 182, 45, 232, 100, 164, 118, 230, 15, 4, 182, 133, + 93, 118, 230, 15, 4, 182, 235, 125, 196, 66, 230, 15, 4, 182, 45, 248, + 218, 196, 66, 230, 15, 4, 182, 179, 96, 230, 15, 4, 182, 133, 93, 96, + 230, 15, 4, 182, 235, 125, 235, 121, 230, 15, 4, 182, 45, 248, 218, 235, + 121, 230, 15, 4, 182, 179, 118, 230, 15, 4, 182, 133, 93, 96, 230, 15, 4, + 182, 196, 77, 118, 230, 15, 4, 182, 144, 93, 96, 230, 15, 4, 182, 235, + 125, 96, 230, 15, 4, 182, 133, 93, 118, 230, 15, 4, 182, 196, 77, 96, + 230, 15, 4, 182, 144, 93, 118, 230, 15, 4, 182, 235, 125, 118, 230, 15, + 4, 182, 133, 93, 180, 237, 217, 118, 230, 15, 4, 182, 144, 248, 235, 180, + 237, 217, 96, 230, 15, 4, 182, 133, 93, 180, 237, 217, 96, 230, 15, 4, + 182, 144, 248, 235, 180, 237, 217, 196, 66, 230, 15, 4, 182, 45, 248, + 218, 235, 121, 230, 15, 4, 182, 179, 235, 121, 230, 15, 4, 182, 45, 248, + 218, 196, 66, 230, 15, 4, 182, 179, 50, 55, 64, 4, 206, 114, 229, 237, + 234, 45, 3, 93, 96, 57, 198, 153, 211, 69, 93, 96, 57, 118, 64, 93, 198, + 153, 211, 68, 96, 64, 93, 198, 153, 211, 68, 96, 64, 93, 251, 167, 234, + 47, 159, 219, 182, 93, 118, 57, 118, 64, 198, 216, 219, 181, 230, 206, + 93, 96, 57, 200, 230, 93, 96, 57, 118, 64, 198, 216, 200, 229, 200, 181, + 93, 118, 57, 45, 232, 239, 199, 215, 50, 232, 239, 199, 215, 133, 232, + 239, 199, 215, 144, 232, 239, 199, 215, 197, 225, 81, 249, 90, 237, 114, + 191, 167, 213, 12, 201, 202, 191, 167, 213, 12, 196, 255, 242, 85, 45, + 63, 238, 173, 248, 55, 50, 63, 238, 173, 248, 55, 45, 63, 210, 115, 50, + 63, 210, 115, 191, 167, 213, 12, 45, 223, 180, 248, 55, 191, 167, 213, + 12, 50, 223, 180, 248, 55, 191, 167, 213, 12, 45, 248, 168, 248, 55, 191, + 167, 213, 12, 50, 248, 168, 248, 55, 45, 51, 248, 56, 4, 196, 103, 50, + 51, 248, 56, 4, 196, 103, 45, 51, 248, 56, 4, 198, 183, 223, 165, 198, + 54, 239, 3, 50, 51, 248, 56, 4, 198, 183, 223, 165, 248, 79, 239, 3, 45, + 51, 248, 56, 4, 198, 183, 223, 165, 248, 79, 239, 3, 50, 51, 248, 56, 4, + 198, 183, 223, 165, 198, 54, 239, 3, 45, 251, 118, 248, 56, 4, 236, 142, + 50, 251, 118, 248, 56, 4, 236, 142, 45, 251, 19, 219, 182, 248, 55, 50, + 251, 19, 230, 206, 248, 55, 55, 45, 251, 19, 230, 206, 248, 55, 55, 50, + 251, 19, 219, 182, 248, 55, 45, 62, 198, 42, 203, 104, 248, 55, 50, 62, + 198, 42, 203, 104, 248, 55, 235, 140, 233, 41, 81, 191, 21, 219, 114, + 216, 228, 251, 118, 211, 71, 219, 226, 50, 251, 118, 195, 168, 4, 201, + 191, 216, 228, 50, 251, 118, 4, 236, 142, 251, 118, 4, 206, 10, 223, 119, + 252, 49, 251, 117, 201, 226, 251, 118, 211, 71, 219, 226, 201, 226, 251, + 118, 211, 71, 196, 77, 154, 251, 117, 207, 19, 251, 117, 251, 118, 4, + 196, 103, 207, 19, 251, 118, 4, 196, 103, 211, 174, 251, 118, 211, 71, + 196, 77, 211, 174, 251, 118, 211, 71, 235, 125, 216, 228, 251, 118, 4, + 211, 79, 250, 253, 234, 93, 223, 165, 64, 209, 60, 133, 23, 179, 216, + 228, 251, 118, 4, 211, 79, 250, 253, 234, 93, 223, 165, 64, 209, 60, 133, + 23, 219, 226, 216, 228, 251, 118, 4, 211, 79, 250, 253, 234, 93, 223, + 165, 64, 209, 60, 144, 23, 179, 216, 228, 251, 118, 4, 211, 79, 250, 253, + 234, 93, 223, 165, 64, 209, 60, 144, 23, 219, 226, 216, 228, 251, 118, 4, + 211, 79, 250, 253, 234, 93, 223, 165, 64, 209, 60, 50, 23, 196, 77, 216, + 228, 251, 118, 4, 211, 79, 250, 253, 234, 93, 223, 165, 64, 209, 60, 45, + 23, 196, 77, 216, 228, 251, 118, 4, 211, 79, 250, 253, 234, 93, 223, 165, + 64, 209, 60, 50, 23, 235, 125, 216, 228, 251, 118, 4, 211, 79, 250, 253, + 234, 93, 223, 165, 64, 209, 60, 45, 23, 235, 125, 207, 19, 234, 107, 203, + 253, 234, 107, 203, 254, 4, 211, 8, 234, 107, 203, 254, 4, 2, 243, 13, + 58, 234, 107, 203, 254, 4, 50, 64, 58, 234, 107, 203, 254, 4, 45, 64, 58, + 243, 13, 4, 228, 243, 164, 47, 81, 164, 47, 210, 120, 47, 207, 20, 202, + 24, 47, 210, 0, 243, 13, 236, 208, 247, 207, 228, 243, 249, 90, 23, 198, + 54, 132, 236, 208, 247, 207, 81, 164, 243, 13, 4, 200, 183, 192, 235, 47, + 251, 85, 236, 202, 56, 133, 64, 198, 216, 243, 12, 47, 63, 247, 250, 47, + 247, 250, 47, 219, 181, 47, 230, 205, 243, 13, 4, 2, 243, 13, 119, 199, + 34, 179, 243, 13, 4, 105, 228, 243, 201, 17, 119, 199, 34, 179, 112, 206, + 181, 237, 41, 202, 98, 112, 233, 85, 237, 41, 202, 98, 112, 250, 195, + 112, 2, 243, 12, 112, 201, 191, 105, 222, 200, 201, 189, 197, 242, 4, 75, + 58, 197, 242, 4, 196, 103, 206, 10, 223, 165, 197, 241, 197, 242, 4, 204, + 5, 250, 185, 248, 78, 50, 197, 242, 93, 45, 197, 241, 45, 197, 242, 248, + 218, 81, 164, 81, 249, 90, 248, 218, 50, 197, 241, 248, 66, 4, 45, 132, + 248, 141, 248, 66, 4, 50, 132, 248, 141, 62, 248, 65, 25, 4, 45, 132, + 248, 141, 25, 4, 50, 132, 248, 141, 63, 228, 176, 62, 228, 176, 45, 193, + 72, 233, 41, 50, 193, 72, 233, 41, 45, 55, 193, 72, 233, 41, 50, 55, 193, + 72, 233, 41, 223, 157, 223, 141, 198, 179, 139, 223, 141, 223, 142, 214, + 110, 4, 81, 164, 235, 134, 215, 133, 51, 4, 239, 27, 211, 13, 223, 154, + 250, 221, 202, 255, 208, 202, 234, 45, 3, 23, 202, 100, 210, 120, 234, + 45, 3, 23, 202, 100, 210, 121, 4, 198, 153, 58, 228, 19, 119, 23, 202, + 100, 210, 120, 231, 16, 201, 102, 199, 22, 235, 124, 197, 242, 4, 45, + 132, 248, 141, 235, 124, 197, 242, 4, 50, 132, 248, 141, 62, 237, 35, 4, + 144, 57, 62, 218, 234, 63, 243, 13, 4, 144, 57, 62, 243, 13, 4, 144, 57, + 234, 27, 63, 201, 191, 234, 27, 62, 201, 191, 234, 27, 63, 237, 34, 234, + 27, 62, 237, 34, 234, 27, 63, 243, 12, 234, 27, 62, 243, 12, 206, 52, + 207, 20, 202, 25, 211, 68, 202, 25, 4, 211, 8, 207, 20, 202, 25, 4, 228, + 243, 106, 248, 177, 202, 24, 248, 177, 207, 20, 202, 24, 55, 209, 83, + 197, 225, 209, 83, 219, 221, 238, 165, 251, 118, 248, 55, 206, 204, 238, + 165, 251, 118, 248, 55, 198, 137, 216, 34, 215, 62, 47, 75, 211, 68, 215, + 62, 47, 108, 211, 68, 215, 62, 47, 25, 211, 68, 215, 62, 196, 93, 211, + 69, 4, 236, 142, 215, 62, 196, 93, 211, 69, 4, 209, 83, 215, 62, 51, 223, + 102, 211, 68, 215, 62, 51, 196, 93, 211, 68, 105, 219, 31, 23, 211, 68, + 105, 219, 31, 211, 59, 211, 68, 215, 62, 25, 211, 68, 215, 238, 105, 200, + 204, 200, 202, 4, 223, 115, 208, 28, 223, 116, 211, 68, 232, 248, 210, + 109, 223, 115, 223, 116, 4, 55, 106, 223, 116, 250, 145, 4, 202, 98, 243, + 5, 232, 78, 251, 87, 223, 113, 219, 115, 223, 114, 4, 207, 93, 210, 88, + 250, 247, 209, 54, 219, 115, 223, 114, 4, 204, 28, 210, 88, 250, 247, + 209, 54, 219, 115, 223, 114, 213, 14, 223, 159, 199, 34, 209, 54, 223, + 116, 250, 247, 42, 209, 64, 211, 68, 208, 21, 223, 116, 211, 68, 223, + 116, 4, 118, 64, 4, 102, 223, 116, 4, 25, 56, 223, 116, 4, 223, 101, 223, + 116, 4, 196, 92, 223, 116, 4, 211, 8, 223, 116, 4, 196, 103, 222, 201, + 220, 15, 45, 197, 242, 211, 68, 191, 167, 213, 12, 205, 93, 239, 64, 191, + 167, 213, 12, 205, 93, 209, 128, 191, 167, 213, 12, 205, 93, 208, 197, + 108, 3, 4, 2, 243, 13, 58, 108, 3, 4, 243, 4, 252, 63, 58, 108, 3, 4, + 198, 153, 58, 108, 3, 4, 75, 60, 108, 3, 4, 198, 153, 60, 108, 3, 4, 200, + 231, 109, 108, 3, 4, 62, 197, 241, 216, 37, 3, 4, 242, 77, 58, 216, 37, + 3, 4, 75, 60, 216, 37, 3, 4, 233, 85, 236, 140, 216, 37, 3, 4, 206, 181, + 236, 140, 108, 3, 223, 165, 45, 132, 243, 12, 108, 3, 223, 165, 50, 132, + 243, 12, 195, 152, 211, 59, 238, 220, 208, 202, 215, 129, 3, 4, 75, 58, + 215, 129, 3, 4, 196, 103, 204, 25, 208, 203, 4, 248, 79, 242, 220, 202, + 69, 208, 202, 215, 129, 3, 223, 165, 45, 132, 243, 12, 215, 129, 3, 223, + 165, 50, 132, 243, 12, 47, 215, 129, 3, 4, 243, 4, 252, 62, 215, 129, 3, + 223, 165, 55, 243, 12, 47, 236, 202, 56, 108, 3, 223, 165, 197, 241, 216, + 37, 3, 223, 165, 197, 241, 215, 129, 3, 223, 165, 197, 241, 223, 110, + 208, 202, 206, 199, 223, 110, 208, 202, 191, 167, 213, 12, 207, 65, 239, + 64, 251, 149, 211, 59, 239, 11, 223, 102, 4, 236, 142, 196, 93, 4, 216, + 37, 56, 196, 93, 4, 211, 8, 223, 102, 4, 211, 8, 223, 102, 4, 219, 31, + 251, 127, 196, 93, 4, 219, 31, 211, 58, 196, 93, 93, 223, 101, 223, 102, + 93, 196, 92, 196, 93, 93, 249, 90, 93, 223, 101, 223, 102, 93, 249, 90, + 93, 196, 92, 196, 93, 248, 218, 23, 222, 200, 4, 196, 92, 223, 102, 248, + 218, 23, 222, 200, 4, 223, 101, 242, 221, 196, 93, 4, 204, 4, 242, 221, + 223, 102, 4, 204, 4, 55, 51, 223, 101, 55, 51, 196, 92, 242, 221, 196, + 93, 4, 204, 5, 23, 202, 69, 208, 202, 219, 31, 23, 4, 75, 58, 219, 31, + 211, 59, 4, 75, 58, 55, 219, 31, 251, 127, 55, 219, 31, 211, 58, 105, + 223, 103, 219, 31, 251, 127, 105, 223, 103, 219, 31, 211, 58, 202, 81, + 220, 15, 211, 58, 202, 81, 220, 15, 251, 127, 219, 31, 211, 59, 211, 3, + 219, 31, 251, 127, 219, 31, 23, 4, 82, 201, 81, 219, 31, 211, 59, 4, 82, + 201, 81, 219, 31, 23, 4, 228, 243, 237, 217, 219, 31, 211, 59, 4, 228, + 243, 237, 217, 219, 31, 23, 4, 55, 211, 8, 219, 31, 23, 4, 196, 103, 219, + 31, 23, 4, 55, 196, 103, 2, 195, 149, 4, 196, 103, 219, 31, 211, 59, 4, + 55, 211, 8, 219, 31, 211, 59, 4, 55, 196, 103, 191, 167, 213, 12, 236, + 154, 251, 77, 191, 167, 213, 12, 207, 139, 251, 77, 234, 45, 3, 4, 75, + 60, 228, 19, 4, 75, 58, 197, 225, 228, 243, 249, 90, 4, 55, 81, 106, 197, + 225, 228, 243, 249, 90, 4, 197, 225, 81, 106, 198, 153, 211, 69, 4, 75, + 58, 198, 153, 211, 69, 4, 206, 181, 236, 140, 202, 181, 216, 37, 202, + 180, 239, 51, 4, 75, 58, 234, 45, 4, 250, 195, 251, 167, 234, 47, 119, 4, + 243, 4, 252, 62, 251, 42, 234, 47, 211, 59, 234, 47, 159, 234, 45, 3, 93, + 108, 56, 108, 3, 93, 234, 45, 56, 234, 45, 3, 93, 198, 153, 211, 68, 55, + 242, 86, 234, 46, 105, 239, 43, 234, 45, 202, 195, 115, 239, 43, 234, 45, + 202, 195, 234, 45, 3, 4, 105, 185, 93, 23, 105, 185, 60, 234, 38, 4, 232, + 130, 185, 58, 219, 182, 4, 243, 13, 223, 119, 230, 206, 4, 243, 13, 223, + 119, 219, 182, 4, 208, 15, 87, 58, 230, 206, 4, 208, 15, 87, 58, 219, + 182, 211, 59, 202, 100, 234, 47, 159, 230, 206, 211, 59, 202, 100, 234, + 47, 159, 219, 182, 211, 59, 202, 100, 234, 47, 119, 4, 75, 223, 119, 230, + 206, 211, 59, 202, 100, 234, 47, 119, 4, 75, 223, 119, 219, 182, 211, 59, + 202, 100, 234, 47, 119, 4, 75, 58, 230, 206, 211, 59, 202, 100, 234, 47, + 119, 4, 75, 58, 219, 182, 211, 59, 202, 100, 234, 47, 119, 4, 75, 93, + 179, 230, 206, 211, 59, 202, 100, 234, 47, 119, 4, 75, 93, 219, 226, 219, + 182, 211, 59, 251, 43, 230, 206, 211, 59, 251, 43, 219, 182, 23, 202, + 169, 213, 14, 234, 47, 159, 230, 206, 23, 202, 169, 213, 14, 234, 47, + 159, 219, 182, 23, 213, 14, 251, 43, 230, 206, 23, 213, 14, 251, 43, 219, + 182, 93, 235, 133, 234, 47, 93, 230, 205, 230, 206, 93, 235, 133, 234, + 47, 93, 219, 181, 219, 182, 93, 202, 181, 211, 59, 234, 46, 230, 206, 93, + 202, 181, 211, 59, 234, 46, 219, 182, 93, 202, 181, 93, 230, 205, 230, + 206, 93, 202, 181, 93, 219, 181, 219, 182, 93, 230, 206, 93, 235, 133, + 234, 46, 230, 206, 93, 219, 182, 93, 235, 133, 234, 46, 219, 182, 93, + 202, 100, 234, 47, 93, 230, 206, 93, 202, 100, 234, 46, 230, 206, 93, + 202, 100, 234, 47, 93, 219, 182, 93, 202, 100, 234, 46, 202, 100, 234, + 47, 119, 211, 59, 219, 181, 202, 100, 234, 47, 119, 211, 59, 230, 205, + 202, 100, 234, 47, 119, 211, 59, 219, 182, 4, 75, 223, 119, 202, 100, + 234, 47, 119, 211, 59, 230, 206, 4, 75, 223, 119, 235, 133, 234, 47, 119, + 211, 59, 219, 181, 235, 133, 234, 47, 119, 211, 59, 230, 205, 235, 133, + 202, 100, 234, 47, 119, 211, 59, 219, 181, 235, 133, 202, 100, 234, 47, + 119, 211, 59, 230, 205, 202, 181, 211, 59, 219, 181, 202, 181, 211, 59, + 230, 205, 202, 181, 93, 219, 182, 93, 234, 45, 56, 202, 181, 93, 230, + 206, 93, 234, 45, 56, 55, 214, 90, 219, 181, 55, 214, 90, 230, 205, 55, + 214, 90, 219, 182, 4, 196, 103, 230, 206, 211, 3, 219, 181, 230, 206, + 248, 218, 219, 181, 219, 182, 242, 221, 247, 207, 238, 166, 230, 206, + 242, 221, 247, 207, 238, 166, 219, 182, 242, 221, 247, 207, 238, 167, 93, + 202, 100, 234, 46, 230, 206, 242, 221, 247, 207, 238, 167, 93, 202, 100, + 234, 46, 202, 70, 199, 38, 220, 13, 199, 38, 202, 70, 199, 39, 211, 59, + 234, 47, 159, 220, 13, 199, 39, 211, 59, 234, 47, 159, 234, 45, 3, 4, + 247, 243, 58, 208, 234, 93, 202, 169, 234, 45, 56, 200, 221, 93, 202, + 169, 234, 45, 56, 208, 234, 93, 202, 169, 213, 14, 234, 47, 159, 200, + 221, 93, 202, 169, 213, 14, 234, 47, 159, 208, 234, 93, 234, 45, 56, 200, + 221, 93, 234, 45, 56, 208, 234, 93, 213, 14, 234, 47, 159, 200, 221, 93, + 213, 14, 234, 47, 159, 208, 234, 93, 251, 167, 234, 47, 159, 200, 221, + 93, 251, 167, 234, 47, 159, 208, 234, 93, 213, 14, 251, 167, 234, 47, + 159, 200, 221, 93, 213, 14, 251, 167, 234, 47, 159, 55, 208, 233, 55, + 200, 220, 200, 230, 4, 236, 142, 200, 181, 4, 236, 142, 200, 230, 4, 108, + 3, 60, 200, 181, 4, 108, 3, 60, 200, 230, 4, 215, 129, 3, 60, 200, 181, + 4, 215, 129, 3, 60, 200, 230, 79, 211, 59, 234, 47, 119, 4, 75, 58, 200, + 181, 79, 211, 59, 234, 47, 119, 4, 75, 58, 200, 230, 79, 93, 234, 45, 56, + 200, 181, 79, 93, 234, 45, 56, 200, 230, 79, 93, 198, 153, 211, 68, 200, + 181, 79, 93, 198, 153, 211, 68, 200, 230, 79, 93, 251, 167, 234, 47, 159, + 200, 181, 79, 93, 251, 167, 234, 47, 159, 200, 230, 79, 93, 213, 14, 234, + 47, 159, 200, 181, 79, 93, 213, 14, 234, 47, 159, 51, 45, 211, 79, 111, + 211, 68, 51, 50, 211, 79, 111, 211, 68, 242, 221, 200, 229, 242, 221, + 200, 180, 242, 221, 200, 230, 211, 59, 234, 47, 159, 242, 221, 200, 181, + 211, 59, 234, 47, 159, 200, 230, 93, 200, 180, 200, 181, 93, 200, 229, + 200, 230, 93, 200, 229, 200, 181, 93, 200, 180, 200, 181, 248, 218, 200, + 229, 200, 181, 248, 218, 23, 222, 200, 247, 207, 237, 218, 4, 200, 229, + 234, 134, 79, 211, 71, 235, 120, 209, 118, 4, 199, 122, 198, 53, 198, 7, + 223, 101, 232, 149, 213, 29, 203, 41, 45, 199, 228, 203, 41, 144, 199, + 228, 203, 41, 133, 199, 228, 210, 1, 4, 206, 9, 81, 249, 90, 197, 225, + 50, 197, 57, 55, 81, 249, 90, 45, 197, 57, 81, 249, 90, 55, 45, 197, 57, + 55, 81, 249, 90, 55, 45, 197, 57, 180, 237, 218, 232, 100, 45, 216, 193, + 79, 55, 195, 135, 203, 41, 144, 199, 229, 4, 211, 8, 203, 41, 133, 199, + 229, 4, 196, 103, 203, 41, 133, 199, 229, 93, 203, 41, 144, 199, 228, 55, + 144, 199, 228, 55, 133, 199, 228, 55, 201, 29, 213, 14, 56, 207, 19, 55, + 201, 29, 213, 14, 56, 236, 166, 213, 14, 236, 210, 4, 207, 19, 214, 109, + 202, 98, 81, 219, 115, 4, 243, 13, 58, 81, 219, 115, 4, 243, 13, 60, 144, + 199, 229, 4, 243, 13, 60, 210, 121, 4, 228, 243, 106, 210, 121, 4, 198, + 153, 211, 68, 197, 225, 81, 249, 90, 248, 170, 207, 66, 197, 225, 81, + 249, 90, 4, 228, 243, 106, 197, 225, 242, 86, 211, 68, 197, 225, 214, 90, + 219, 181, 197, 225, 214, 90, 230, 205, 235, 133, 202, 100, 219, 182, 211, + 59, 234, 47, 159, 235, 133, 202, 100, 230, 206, 211, 59, 234, 47, 159, + 197, 225, 202, 25, 248, 170, 207, 66, 220, 15, 197, 225, 81, 249, 90, + 211, 68, 55, 202, 25, 211, 68, 63, 81, 164, 215, 62, 63, 81, 164, 186, + 234, 206, 63, 57, 186, 193, 105, 63, 57, 202, 3, 234, 206, 63, 57, 202, + 3, 193, 105, 63, 57, 45, 50, 63, 57, 118, 62, 57, 196, 66, 62, 57, 235, + 121, 62, 57, 186, 234, 206, 62, 57, 186, 193, 105, 62, 57, 202, 3, 234, + 206, 62, 57, 202, 3, 193, 105, 62, 57, 45, 50, 62, 57, 133, 144, 62, 57, + 96, 64, 4, 198, 136, 235, 120, 96, 64, 4, 198, 136, 196, 65, 118, 64, 4, + 198, 136, 235, 120, 118, 64, 4, 198, 136, 196, 65, 51, 4, 198, 54, 132, + 248, 141, 51, 4, 248, 79, 132, 248, 141, 51, 4, 116, 50, 237, 41, 132, + 248, 141, 51, 4, 110, 45, 237, 41, 132, 248, 141, 237, 35, 4, 45, 132, + 248, 141, 237, 35, 4, 50, 132, 248, 141, 237, 35, 4, 198, 54, 132, 248, + 141, 237, 35, 4, 248, 79, 132, 248, 141, 235, 140, 201, 191, 62, 220, 15, + 201, 191, 63, 220, 15, 201, 191, 62, 195, 83, 2, 201, 191, 63, 195, 83, + 2, 201, 191, 62, 210, 26, 63, 210, 26, 63, 229, 184, 62, 229, 184, 228, + 243, 62, 229, 184, 62, 220, 15, 243, 12, 62, 216, 215, 237, 34, 63, 216, + 215, 237, 34, 62, 216, 215, 218, 234, 63, 216, 215, 218, 234, 62, 2, 237, + 34, 62, 2, 218, 234, 63, 2, 218, 234, 62, 228, 243, 234, 123, 63, 228, + 243, 234, 123, 62, 81, 234, 123, 63, 81, 234, 123, 45, 64, 4, 2, 243, 12, + 115, 118, 250, 233, 45, 64, 4, 47, 209, 83, 180, 118, 201, 184, 57, 118, + 197, 13, 64, 4, 81, 106, 118, 197, 13, 64, 4, 55, 81, 106, 118, 197, 13, + 64, 232, 100, 164, 118, 197, 13, 197, 225, 237, 218, 57, 118, 64, 4, 235, + 140, 201, 81, 118, 64, 4, 199, 216, 4, 81, 106, 118, 64, 4, 199, 216, 4, + 55, 81, 106, 118, 197, 13, 64, 4, 199, 215, 118, 197, 13, 64, 4, 199, + 216, 4, 81, 106, 118, 197, 13, 64, 4, 199, 216, 4, 55, 81, 106, 118, 64, + 198, 216, 192, 235, 193, 139, 64, 209, 60, 236, 233, 219, 226, 234, 45, + 3, 93, 118, 57, 207, 20, 198, 153, 211, 69, 93, 118, 57, 118, 64, 93, + 207, 20, 251, 167, 234, 47, 159, 96, 64, 198, 216, 230, 205, 96, 64, 198, + 216, 200, 180, 118, 208, 28, 57, 96, 208, 28, 57, 207, 20, 198, 153, 211, + 69, 93, 96, 57, 96, 64, 93, 207, 20, 251, 167, 234, 47, 159, 198, 153, + 211, 69, 93, 118, 57, 118, 64, 93, 251, 167, 234, 47, 159, 118, 64, 93, + 207, 20, 198, 153, 211, 68, 96, 64, 93, 207, 20, 198, 153, 211, 68, 235, + 121, 197, 240, 191, 21, 57, 203, 41, 202, 100, 186, 57, 203, 41, 249, + 145, 202, 3, 57, 63, 216, 215, 201, 103, 62, 2, 201, 103, 63, 2, 201, + 103, 62, 206, 204, 210, 26, 63, 206, 204, 210, 26, 88, 220, 15, 243, 12, + 88, 211, 10, 4, 211, 10, 223, 119, 88, 243, 13, 4, 243, 13, 223, 119, 88, + 243, 12, 88, 47, 205, 155, 202, 100, 186, 64, 4, 228, 252, 229, 237, 249, + 145, 202, 3, 64, 4, 228, 252, 199, 215, 202, 100, 186, 64, 4, 228, 243, + 199, 215, 249, 145, 202, 3, 64, 4, 228, 243, 199, 215, 248, 226, 64, 209, + 60, 235, 121, 199, 25, 186, 234, 205, 203, 41, 248, 226, 64, 209, 60, + 235, 121, 199, 25, 186, 234, 205, 118, 197, 240, 57, 196, 66, 197, 240, + 57, 96, 197, 240, 57, 235, 121, 197, 240, 57, 45, 50, 197, 240, 57, 133, + 144, 197, 240, 57, 186, 193, 105, 197, 240, 57, 186, 234, 206, 197, 240, + 57, 202, 3, 234, 206, 197, 240, 57, 202, 3, 193, 105, 197, 240, 57, 118, + 197, 240, 237, 216, 57, 196, 66, 197, 240, 237, 216, 57, 96, 197, 240, + 237, 216, 57, 235, 121, 197, 240, 237, 216, 57, 242, 223, 197, 240, 211, + 79, 243, 13, 57, 251, 87, 197, 240, 211, 79, 243, 13, 57, 118, 197, 240, + 64, 119, 164, 196, 66, 197, 240, 64, 119, 164, 96, 197, 240, 64, 119, + 164, 235, 121, 197, 240, 64, 119, 164, 186, 193, 105, 197, 240, 64, 119, + 164, 186, 234, 206, 197, 240, 64, 119, 164, 202, 3, 234, 206, 197, 240, + 64, 119, 164, 202, 3, 193, 105, 197, 240, 64, 119, 164, 118, 197, 240, + 64, 4, 55, 228, 243, 106, 196, 66, 197, 240, 64, 4, 55, 228, 243, 106, + 96, 197, 240, 64, 4, 55, 228, 243, 106, 235, 121, 197, 240, 64, 4, 55, + 228, 243, 106, 228, 243, 199, 237, 221, 224, 81, 199, 237, 221, 224, 118, + 197, 240, 64, 139, 96, 197, 240, 57, 196, 66, 197, 240, 64, 118, 79, 235, + 121, 197, 240, 57, 96, 197, 240, 64, 139, 118, 197, 240, 57, 235, 121, + 197, 240, 64, 118, 79, 196, 66, 197, 240, 57, 118, 197, 240, 210, 198, + 250, 233, 196, 66, 197, 240, 210, 198, 250, 233, 96, 197, 240, 210, 198, + 250, 233, 235, 121, 197, 240, 210, 198, 250, 233, 118, 62, 47, 63, 57, + 196, 66, 62, 47, 63, 57, 96, 62, 47, 63, 57, 235, 121, 62, 47, 63, 57, + 251, 87, 197, 240, 50, 196, 221, 57, 251, 87, 197, 240, 248, 79, 196, + 221, 57, 251, 87, 197, 240, 45, 196, 221, 57, 251, 87, 197, 240, 198, 54, + 196, 221, 57, 207, 24, 219, 226, 207, 24, 179, 214, 79, 219, 226, 214, + 79, 179, 232, 130, 239, 4, 250, 234, 243, 8, 251, 86, 96, 62, 57, 16, 40, + 196, 255, 42, 234, 135, 198, 225, 198, 52, 118, 234, 39, 250, 237, 198, + 225, 206, 205, 196, 66, 234, 39, 250, 237, 198, 225, 198, 52, 96, 234, + 39, 250, 237, 198, 225, 219, 222, 235, 121, 234, 39, 250, 237, 62, 118, + 234, 39, 250, 237, 62, 196, 66, 234, 39, 250, 237, 62, 96, 234, 39, 250, + 237, 62, 235, 121, 234, 39, 250, 237, 235, 121, 197, 240, 64, 4, 180, + 198, 136, 219, 216, 235, 121, 197, 240, 64, 4, 180, 198, 136, 206, 198, + 196, 66, 197, 240, 64, 4, 180, 198, 136, 219, 216, 196, 66, 197, 240, 64, + 4, 180, 198, 136, 206, 198, 118, 197, 240, 64, 4, 180, 198, 136, 196, 65, + 96, 197, 240, 64, 4, 180, 198, 136, 196, 65, 118, 197, 240, 64, 4, 180, + 198, 136, 235, 120, 96, 197, 240, 64, 4, 180, 198, 136, 235, 120, 62, + 238, 165, 235, 121, 23, 118, 57, 62, 238, 165, 235, 121, 23, 96, 57, 62, + 238, 165, 196, 66, 23, 118, 57, 62, 238, 165, 196, 66, 23, 96, 57, 62, + 238, 165, 118, 23, 196, 66, 57, 62, 238, 165, 96, 23, 196, 66, 57, 62, + 238, 165, 118, 23, 235, 121, 57, 62, 238, 165, 96, 23, 235, 121, 57, 206, + 249, 64, 144, 219, 226, 206, 249, 64, 144, 179, 206, 249, 64, 133, 219, + 226, 206, 249, 64, 133, 179, 206, 249, 64, 45, 196, 77, 206, 249, 64, 50, + 196, 77, 206, 249, 64, 45, 235, 125, 206, 249, 64, 50, 235, 125, 196, 66, + 63, 64, 232, 100, 249, 90, 4, 228, 243, 164, 133, 250, 238, 223, 165, 42, + 207, 95, 248, 64, 211, 3, 63, 201, 189, 211, 3, 63, 23, 62, 201, 189, + 211, 3, 62, 201, 189, 249, 109, 111, 4, 156, 192, 235, 47, 192, 235, 47, + 28, 192, 235, 62, 51, 247, 21, 62, 237, 35, 247, 21, 154, 62, 210, 26, + 228, 243, 62, 211, 162, 62, 211, 162, 62, 216, 215, 196, 76, 197, 242, + 247, 21, 62, 216, 215, 235, 124, 197, 242, 247, 21, 62, 216, 215, 219, + 221, 197, 242, 247, 21, 62, 216, 215, 206, 204, 197, 242, 247, 21, 214, + 97, 232, 148, 109, 198, 54, 132, 62, 243, 12, 248, 79, 132, 62, 243, 12, + 156, 232, 130, 209, 62, 62, 238, 161, 206, 123, 156, 232, 130, 209, 62, + 62, 238, 161, 63, 232, 130, 209, 62, 238, 161, 206, 123, 63, 232, 130, + 209, 62, 238, 161, 51, 209, 27, 223, 146, 196, 107, 56, 230, 189, 77, + 209, 80, 232, 148, 109, 209, 80, 232, 148, 138, 209, 80, 232, 148, 134, + 209, 80, 232, 148, 150, 198, 9, 208, 187, 250, 191, 228, 93, 209, 198, + 214, 93, 63, 215, 208, 204, 34, 62, 237, 35, 211, 107, 238, 219, 197, + 202, 156, 215, 208, 250, 229, 238, 181, 230, 90, 191, 75, 221, 4, 251, + 55, 252, 34, 193, 247, 209, 28, 45, 132, 62, 201, 103, 50, 132, 62, 201, + 103, 201, 104, 4, 45, 132, 248, 141, 201, 104, 4, 50, 132, 248, 141, 118, + 197, 13, 64, 4, 197, 242, 250, 235, 196, 66, 197, 13, 64, 4, 197, 242, + 250, 235, 96, 197, 13, 64, 4, 197, 242, 250, 235, 235, 121, 197, 13, 64, + 4, 197, 242, 250, 235, 234, 29, 232, 148, 107, 234, 29, 232, 148, 109, + 205, 52, 206, 32, 250, 190, 16, 195, 52, 206, 32, 250, 190, 16, 213, 0, + 206, 32, 250, 190, 16, 208, 3, 206, 32, 250, 190, 16, 248, 165, 206, 32, + 250, 190, 16, 204, 17, 206, 32, 250, 190, 16, 198, 0, 234, 45, 3, 4, 223, + 142, 60, 196, 89, 113, 204, 13, 113, 235, 130, 113, 210, 98, 113, 207, + 19, 50, 251, 117, 229, 205, 210, 80, 113, 135, 6, 1, 250, 124, 135, 6, 1, + 247, 254, 135, 6, 1, 195, 151, 135, 6, 1, 231, 20, 135, 6, 1, 236, 171, + 135, 6, 1, 192, 49, 135, 6, 1, 191, 55, 135, 6, 1, 235, 32, 135, 6, 1, + 191, 82, 135, 6, 1, 223, 41, 135, 6, 1, 89, 223, 41, 135, 6, 1, 68, 135, + 6, 1, 236, 192, 135, 6, 1, 222, 96, 135, 6, 1, 219, 77, 135, 6, 1, 215, + 68, 135, 6, 1, 214, 212, 135, 6, 1, 211, 91, 135, 6, 1, 209, 57, 135, 6, + 1, 206, 180, 135, 6, 1, 202, 78, 135, 6, 1, 197, 44, 135, 6, 1, 196, 124, + 135, 6, 1, 232, 103, 135, 6, 1, 229, 190, 135, 6, 1, 211, 22, 135, 6, 1, + 210, 65, 135, 6, 1, 203, 9, 135, 6, 1, 197, 146, 135, 6, 1, 243, 56, 135, + 6, 1, 203, 166, 135, 6, 1, 192, 58, 135, 6, 1, 192, 60, 135, 6, 1, 192, + 93, 135, 6, 1, 201, 221, 140, 135, 6, 1, 191, 225, 135, 6, 1, 2, 191, + 190, 135, 6, 1, 2, 191, 191, 4, 199, 215, 135, 6, 1, 192, 12, 135, 6, 1, + 223, 84, 2, 191, 190, 135, 6, 1, 248, 177, 191, 190, 135, 6, 1, 223, 84, + 248, 177, 191, 190, 135, 6, 1, 232, 230, 135, 6, 1, 223, 39, 135, 6, 1, + 203, 8, 135, 6, 1, 197, 215, 65, 135, 6, 1, 220, 3, 215, 68, 135, 6, 1, + 247, 75, 243, 56, 135, 2, 1, 250, 124, 135, 2, 1, 247, 254, 135, 2, 1, + 195, 151, 135, 2, 1, 231, 20, 135, 2, 1, 236, 171, 135, 2, 1, 192, 49, + 135, 2, 1, 191, 55, 135, 2, 1, 235, 32, 135, 2, 1, 191, 82, 135, 2, 1, + 223, 41, 135, 2, 1, 89, 223, 41, 135, 2, 1, 68, 135, 2, 1, 236, 192, 135, + 2, 1, 222, 96, 135, 2, 1, 219, 77, 135, 2, 1, 215, 68, 135, 2, 1, 214, + 212, 135, 2, 1, 211, 91, 135, 2, 1, 209, 57, 135, 2, 1, 206, 180, 135, 2, + 1, 202, 78, 135, 2, 1, 197, 44, 135, 2, 1, 196, 124, 135, 2, 1, 232, 103, + 135, 2, 1, 229, 190, 135, 2, 1, 211, 22, 135, 2, 1, 210, 65, 135, 2, 1, + 203, 9, 135, 2, 1, 197, 146, 135, 2, 1, 243, 56, 135, 2, 1, 203, 166, + 135, 2, 1, 192, 58, 135, 2, 1, 192, 60, 135, 2, 1, 192, 93, 135, 2, 1, + 201, 221, 140, 135, 2, 1, 191, 225, 135, 2, 1, 2, 191, 190, 135, 2, 1, 2, + 191, 191, 4, 199, 215, 135, 2, 1, 192, 12, 135, 2, 1, 223, 84, 2, 191, + 190, 135, 2, 1, 248, 177, 191, 190, 135, 2, 1, 223, 84, 248, 177, 191, + 190, 135, 2, 1, 232, 230, 135, 2, 1, 223, 39, 135, 2, 1, 203, 8, 135, 2, + 1, 197, 215, 65, 135, 2, 1, 220, 3, 215, 68, 135, 2, 1, 247, 75, 243, 56, + 8, 6, 1, 220, 145, 4, 55, 164, 8, 2, 1, 220, 145, 4, 55, 164, 8, 6, 1, + 220, 145, 4, 82, 198, 152, 8, 6, 1, 210, 239, 4, 106, 8, 6, 1, 207, 224, + 4, 199, 215, 8, 2, 1, 42, 4, 106, 8, 2, 1, 200, 44, 4, 237, 41, 106, 8, + 6, 1, 230, 119, 4, 237, 89, 8, 2, 1, 230, 119, 4, 237, 89, 8, 6, 1, 222, + 155, 4, 237, 89, 8, 2, 1, 222, 155, 4, 237, 89, 8, 6, 1, 191, 167, 4, + 237, 89, 8, 2, 1, 191, 167, 4, 237, 89, 8, 6, 1, 251, 162, 8, 6, 1, 218, + 171, 4, 102, 8, 6, 1, 154, 65, 8, 6, 1, 154, 251, 162, 8, 2, 1, 196, 13, + 4, 50, 102, 8, 6, 1, 193, 225, 4, 102, 8, 2, 1, 193, 225, 4, 102, 8, 2, + 1, 196, 13, 4, 238, 177, 8, 6, 1, 132, 230, 118, 8, 2, 1, 132, 230, 118, + 8, 2, 1, 199, 213, 209, 213, 8, 2, 1, 235, 17, 4, 213, 11, 8, 2, 1, 154, + 207, 224, 4, 199, 215, 8, 2, 1, 187, 4, 130, 206, 190, 223, 119, 8, 1, 2, + 6, 154, 71, 8, 200, 231, 2, 1, 223, 37, 52, 1, 6, 196, 12, 8, 6, 1, 206, + 10, 4, 200, 146, 199, 215, 8, 6, 1, 191, 167, 4, 200, 146, 199, 215, 94, + 6, 1, 251, 188, 94, 2, 1, 251, 188, 94, 6, 1, 195, 66, 94, 2, 1, 195, 66, + 94, 6, 1, 231, 213, 94, 2, 1, 231, 213, 94, 6, 1, 238, 1, 94, 2, 1, 238, + 1, 94, 6, 1, 234, 167, 94, 2, 1, 234, 167, 94, 6, 1, 202, 8, 94, 2, 1, + 202, 8, 94, 6, 1, 191, 95, 94, 2, 1, 191, 95, 94, 6, 1, 230, 8, 94, 2, 1, + 230, 8, 94, 6, 1, 199, 13, 94, 2, 1, 199, 13, 94, 6, 1, 228, 34, 94, 2, + 1, 228, 34, 94, 6, 1, 222, 79, 94, 2, 1, 222, 79, 94, 6, 1, 219, 254, 94, + 2, 1, 219, 254, 94, 6, 1, 216, 102, 94, 2, 1, 216, 102, 94, 6, 1, 213, + 221, 94, 2, 1, 213, 221, 94, 6, 1, 220, 250, 94, 2, 1, 220, 250, 94, 6, + 1, 74, 94, 2, 1, 74, 94, 6, 1, 209, 187, 94, 2, 1, 209, 187, 94, 6, 1, + 206, 163, 94, 2, 1, 206, 163, 94, 6, 1, 202, 184, 94, 2, 1, 202, 184, 94, + 6, 1, 199, 166, 94, 2, 1, 199, 166, 94, 6, 1, 196, 168, 94, 2, 1, 196, + 168, 94, 6, 1, 233, 25, 94, 2, 1, 233, 25, 94, 6, 1, 221, 192, 94, 2, 1, + 221, 192, 94, 6, 1, 208, 178, 94, 2, 1, 208, 178, 94, 6, 1, 211, 83, 94, + 2, 1, 211, 83, 94, 6, 1, 237, 39, 251, 194, 94, 2, 1, 237, 39, 251, 194, + 94, 6, 1, 39, 94, 251, 232, 94, 2, 1, 39, 94, 251, 232, 94, 6, 1, 238, + 200, 234, 167, 94, 2, 1, 238, 200, 234, 167, 94, 6, 1, 237, 39, 222, 79, + 94, 2, 1, 237, 39, 222, 79, 94, 6, 1, 237, 39, 213, 221, 94, 2, 1, 237, + 39, 213, 221, 94, 6, 1, 238, 200, 213, 221, 94, 2, 1, 238, 200, 213, 221, + 94, 6, 1, 39, 94, 211, 83, 94, 2, 1, 39, 94, 211, 83, 94, 6, 1, 205, 146, + 94, 2, 1, 205, 146, 94, 6, 1, 238, 216, 203, 106, 94, 2, 1, 238, 216, + 203, 106, 94, 6, 1, 39, 94, 203, 106, 94, 2, 1, 39, 94, 203, 106, 94, 6, + 1, 39, 94, 234, 14, 94, 2, 1, 39, 94, 234, 14, 94, 6, 1, 251, 214, 221, + 197, 94, 2, 1, 251, 214, 221, 197, 94, 6, 1, 237, 39, 228, 244, 94, 2, 1, + 237, 39, 228, 244, 94, 6, 1, 39, 94, 228, 244, 94, 2, 1, 39, 94, 228, + 244, 94, 6, 1, 39, 94, 140, 94, 2, 1, 39, 94, 140, 94, 6, 1, 220, 144, + 140, 94, 2, 1, 220, 144, 140, 94, 6, 1, 39, 94, 229, 211, 94, 2, 1, 39, + 94, 229, 211, 94, 6, 1, 39, 94, 230, 11, 94, 2, 1, 39, 94, 230, 11, 94, + 6, 1, 39, 94, 231, 208, 94, 2, 1, 39, 94, 231, 208, 94, 6, 1, 39, 94, + 236, 195, 94, 2, 1, 39, 94, 236, 195, 94, 6, 1, 39, 94, 203, 72, 94, 2, + 1, 39, 94, 203, 72, 94, 6, 1, 39, 212, 147, 203, 72, 94, 2, 1, 39, 212, + 147, 203, 72, 94, 6, 1, 39, 212, 147, 214, 18, 94, 2, 1, 39, 212, 147, + 214, 18, 94, 6, 1, 39, 212, 147, 212, 83, 94, 2, 1, 39, 212, 147, 212, + 83, 94, 6, 1, 39, 212, 147, 193, 140, 94, 2, 1, 39, 212, 147, 193, 140, + 94, 16, 222, 104, 94, 16, 216, 103, 206, 163, 94, 16, 209, 188, 206, 163, + 94, 16, 201, 90, 94, 16, 199, 167, 206, 163, 94, 16, 221, 193, 206, 163, + 94, 16, 203, 73, 202, 184, 94, 6, 1, 238, 200, 203, 106, 94, 2, 1, 238, + 200, 203, 106, 94, 6, 1, 238, 200, 231, 208, 94, 2, 1, 238, 200, 231, + 208, 94, 33, 213, 222, 58, 94, 33, 201, 214, 250, 203, 94, 33, 201, 214, + 219, 190, 94, 6, 1, 248, 105, 221, 197, 94, 2, 1, 248, 105, 221, 197, 94, + 39, 212, 147, 232, 82, 201, 64, 94, 39, 212, 147, 236, 236, 208, 15, 77, + 94, 39, 212, 147, 223, 144, 208, 15, 77, 94, 39, 212, 147, 195, 137, 236, + 207, 94, 232, 120, 91, 230, 72, 94, 232, 82, 201, 64, 94, 215, 202, 236, + 207, 101, 2, 1, 251, 134, 101, 2, 1, 249, 103, 101, 2, 1, 231, 212, 101, + 2, 1, 236, 152, 101, 2, 1, 234, 105, 101, 2, 1, 195, 49, 101, 2, 1, 191, + 80, 101, 2, 1, 199, 193, 101, 2, 1, 223, 164, 101, 2, 1, 222, 89, 101, 2, + 1, 220, 9, 101, 2, 1, 217, 92, 101, 2, 1, 214, 218, 101, 2, 1, 211, 106, + 101, 2, 1, 210, 133, 101, 2, 1, 191, 67, 101, 2, 1, 207, 165, 101, 2, 1, + 205, 143, 101, 2, 1, 199, 179, 101, 2, 1, 196, 113, 101, 2, 1, 209, 222, + 101, 2, 1, 221, 202, 101, 2, 1, 231, 84, 101, 2, 1, 208, 83, 101, 2, 1, + 203, 70, 101, 2, 1, 243, 83, 101, 2, 1, 247, 130, 101, 2, 1, 222, 236, + 101, 2, 1, 243, 20, 101, 2, 1, 246, 243, 101, 2, 1, 192, 218, 101, 2, 1, + 222, 251, 101, 2, 1, 230, 89, 101, 2, 1, 229, 247, 101, 2, 1, 229, 147, + 101, 2, 1, 193, 125, 101, 2, 1, 230, 21, 101, 2, 1, 229, 13, 101, 2, 1, + 192, 14, 101, 2, 1, 252, 16, 198, 175, 1, 170, 198, 175, 1, 192, 136, + 198, 175, 1, 192, 135, 198, 175, 1, 192, 125, 198, 175, 1, 192, 123, 198, + 175, 1, 248, 220, 252, 64, 192, 118, 198, 175, 1, 192, 118, 198, 175, 1, + 192, 133, 198, 175, 1, 192, 130, 198, 175, 1, 192, 132, 198, 175, 1, 192, + 131, 198, 175, 1, 192, 40, 198, 175, 1, 192, 127, 198, 175, 1, 192, 116, + 198, 175, 1, 197, 86, 192, 116, 198, 175, 1, 192, 113, 198, 175, 1, 192, + 121, 198, 175, 1, 248, 220, 252, 64, 192, 121, 198, 175, 1, 197, 86, 192, + 121, 198, 175, 1, 192, 120, 198, 175, 1, 192, 140, 198, 175, 1, 192, 114, + 198, 175, 1, 197, 86, 192, 114, 198, 175, 1, 192, 103, 198, 175, 1, 197, + 86, 192, 103, 198, 175, 1, 192, 33, 198, 175, 1, 192, 82, 198, 175, 1, + 251, 245, 192, 82, 198, 175, 1, 197, 86, 192, 82, 198, 175, 1, 192, 112, + 198, 175, 1, 192, 111, 198, 175, 1, 192, 108, 198, 175, 1, 197, 86, 192, + 122, 198, 175, 1, 197, 86, 192, 106, 198, 175, 1, 192, 104, 198, 175, 1, + 191, 225, 198, 175, 1, 192, 101, 198, 175, 1, 192, 99, 198, 175, 1, 192, + 124, 198, 175, 1, 197, 86, 192, 124, 198, 175, 1, 250, 129, 192, 124, + 198, 175, 1, 192, 98, 198, 175, 1, 192, 96, 198, 175, 1, 192, 97, 198, + 175, 1, 192, 95, 198, 175, 1, 192, 94, 198, 175, 1, 192, 134, 198, 175, + 1, 192, 92, 198, 175, 1, 192, 90, 198, 175, 1, 192, 89, 198, 175, 1, 192, + 86, 198, 175, 1, 192, 83, 198, 175, 1, 199, 157, 192, 83, 198, 175, 1, + 192, 81, 198, 175, 1, 192, 80, 198, 175, 1, 192, 12, 198, 175, 52, 1, + 220, 117, 77, 198, 175, 204, 12, 77, 198, 175, 120, 222, 198, 36, 5, 219, + 44, 36, 5, 216, 7, 36, 5, 206, 155, 36, 5, 202, 39, 36, 5, 203, 56, 36, + 5, 248, 112, 36, 5, 198, 91, 36, 5, 242, 100, 36, 5, 213, 38, 36, 5, 212, + 66, 36, 5, 231, 13, 211, 184, 36, 5, 191, 6, 36, 5, 236, 174, 36, 5, 237, + 162, 36, 5, 222, 202, 36, 5, 198, 240, 36, 5, 243, 69, 36, 5, 209, 200, + 36, 5, 209, 74, 36, 5, 231, 99, 36, 5, 231, 95, 36, 5, 231, 96, 36, 5, + 231, 97, 36, 5, 201, 176, 36, 5, 201, 130, 36, 5, 201, 143, 36, 5, 201, + 175, 36, 5, 201, 148, 36, 5, 201, 149, 36, 5, 201, 135, 36, 5, 247, 67, + 36, 5, 247, 46, 36, 5, 247, 48, 36, 5, 247, 66, 36, 5, 247, 64, 36, 5, + 247, 65, 36, 5, 247, 47, 36, 5, 190, 224, 36, 5, 190, 202, 36, 5, 190, + 215, 36, 5, 190, 223, 36, 5, 190, 218, 36, 5, 190, 219, 36, 5, 190, 207, + 36, 5, 247, 62, 36, 5, 247, 49, 36, 5, 247, 51, 36, 5, 247, 61, 36, 5, + 247, 59, 36, 5, 247, 60, 36, 5, 247, 50, 36, 5, 207, 236, 36, 5, 207, + 226, 36, 5, 207, 232, 36, 5, 207, 235, 36, 5, 207, 233, 36, 5, 207, 234, + 36, 5, 207, 231, 36, 5, 220, 155, 36, 5, 220, 147, 36, 5, 220, 150, 36, + 5, 220, 154, 36, 5, 220, 151, 36, 5, 220, 152, 36, 5, 220, 148, 36, 5, + 192, 175, 36, 5, 192, 162, 36, 5, 192, 170, 36, 5, 192, 174, 36, 5, 192, + 172, 36, 5, 192, 173, 36, 5, 192, 169, 36, 5, 230, 130, 36, 5, 230, 120, + 36, 5, 230, 123, 36, 5, 230, 129, 36, 5, 230, 125, 36, 5, 230, 126, 36, + 5, 230, 122, 33, 38, 1, 249, 19, 33, 38, 1, 195, 153, 33, 38, 1, 231, 79, + 33, 38, 1, 237, 148, 33, 38, 1, 191, 62, 33, 38, 1, 191, 87, 33, 38, 1, + 155, 33, 38, 1, 234, 142, 33, 38, 1, 234, 116, 33, 38, 1, 234, 105, 33, + 38, 1, 74, 33, 38, 1, 210, 65, 33, 38, 1, 234, 36, 33, 38, 1, 234, 24, + 33, 38, 1, 199, 145, 33, 38, 1, 140, 33, 38, 1, 197, 161, 33, 38, 1, 243, + 129, 33, 38, 1, 203, 166, 33, 38, 1, 203, 117, 33, 38, 1, 232, 230, 33, + 38, 1, 234, 20, 33, 38, 1, 65, 33, 38, 1, 223, 228, 33, 38, 1, 236, 193, + 33, 38, 1, 215, 221, 196, 128, 33, 38, 1, 192, 95, 33, 38, 1, 191, 225, + 33, 38, 1, 223, 83, 65, 33, 38, 1, 219, 85, 191, 190, 33, 38, 1, 248, + 177, 191, 190, 33, 38, 1, 223, 83, 248, 177, 191, 190, 50, 251, 118, 200, + 226, 217, 53, 50, 251, 118, 235, 140, 200, 226, 217, 53, 45, 200, 226, + 248, 55, 50, 200, 226, 248, 55, 45, 235, 140, 200, 226, 248, 55, 50, 235, + 140, 200, 226, 248, 55, 207, 149, 223, 106, 217, 53, 207, 149, 235, 140, + 223, 106, 217, 53, 235, 140, 198, 8, 217, 53, 45, 198, 8, 248, 55, 50, + 198, 8, 248, 55, 207, 149, 201, 191, 45, 207, 149, 211, 108, 248, 55, 50, + 207, 149, 211, 108, 248, 55, 234, 191, 239, 0, 210, 128, 232, 150, 210, + 128, 207, 19, 232, 150, 210, 128, 228, 87, 235, 140, 211, 179, 235, 121, + 251, 128, 196, 66, 251, 128, 235, 140, 206, 204, 251, 117, 55, 211, 174, + 228, 90, 223, 95, 223, 104, 210, 185, 248, 49, 228, 91, 4, 237, 44, 198, + 153, 4, 206, 190, 58, 45, 130, 210, 118, 248, 55, 50, 130, 210, 118, 248, + 55, 198, 153, 4, 75, 58, 198, 153, 4, 75, 60, 45, 81, 249, 90, 4, 208, 9, + 50, 81, 249, 90, 4, 208, 9, 198, 54, 45, 132, 248, 55, 198, 54, 50, 132, + 248, 55, 248, 79, 45, 132, 248, 55, 248, 79, 50, 132, 248, 55, 45, 202, + 207, 126, 248, 55, 50, 202, 207, 126, 248, 55, 45, 55, 210, 115, 50, 55, + 210, 115, 105, 185, 139, 91, 75, 208, 153, 91, 75, 139, 105, 185, 208, + 153, 112, 232, 130, 75, 208, 153, 232, 228, 75, 77, 207, 19, 208, 15, 77, + 81, 198, 152, 206, 190, 209, 63, 193, 23, 204, 12, 82, 236, 142, 154, + 242, 76, 207, 149, 236, 142, 207, 149, 242, 76, 154, 204, 26, 238, 17, 4, + 45, 230, 175, 238, 17, 4, 50, 230, 175, 154, 238, 16, 198, 54, 132, 205, + 55, 56, 197, 14, 237, 217, 198, 223, 237, 217, 201, 80, 232, 82, 201, 64, + 81, 202, 137, 236, 140, 193, 72, 81, 219, 114, 247, 111, 55, 228, 90, + 207, 19, 242, 76, 55, 218, 239, 207, 254, 77, 237, 218, 4, 45, 196, 69, + 55, 200, 164, 77, 223, 95, 130, 222, 37, 223, 95, 130, 222, 38, 4, 222, + 38, 58, 130, 222, 37, 130, 222, 38, 4, 236, 142, 55, 201, 115, 242, 76, + 235, 140, 202, 24, 197, 225, 238, 16, 216, 216, 242, 76, 210, 127, 77, + 208, 152, 234, 131, 77, 239, 1, 195, 137, 236, 207, 238, 220, 210, 84, 4, + 50, 238, 218, 238, 220, 210, 84, 4, 45, 238, 218, 198, 128, 3, 6, 234, 1, + 216, 216, 233, 218, 77, 216, 216, 208, 15, 77, 45, 51, 248, 56, 4, 106, + 50, 51, 248, 56, 4, 106, 45, 51, 248, 56, 4, 55, 106, 50, 51, 248, 56, 4, + 55, 106, 198, 54, 132, 45, 210, 115, 198, 54, 132, 50, 210, 115, 248, 79, + 132, 45, 210, 115, 248, 79, 132, 50, 210, 115, 211, 174, 228, 90, 12, 48, + 207, 49, 12, 48, 242, 232, 12, 48, 205, 58, 107, 12, 48, 205, 58, 109, + 12, 48, 205, 58, 138, 12, 48, 209, 252, 12, 48, 248, 64, 12, 48, 199, + 233, 12, 48, 221, 81, 107, 12, 48, 221, 81, 109, 12, 48, 236, 204, 12, + 48, 205, 62, 12, 48, 2, 107, 12, 48, 2, 109, 12, 48, 220, 32, 107, 12, + 48, 220, 32, 109, 12, 48, 220, 32, 138, 12, 48, 220, 32, 134, 12, 48, + 202, 59, 12, 48, 198, 227, 12, 48, 202, 56, 107, 12, 48, 202, 56, 109, + 12, 48, 229, 226, 107, 12, 48, 229, 226, 109, 12, 48, 230, 55, 12, 48, + 207, 138, 12, 48, 243, 66, 12, 48, 200, 198, 12, 48, 215, 207, 12, 48, + 237, 145, 12, 48, 215, 195, 12, 48, 242, 251, 12, 48, 193, 144, 107, 12, + 48, 193, 144, 109, 12, 48, 232, 245, 12, 48, 210, 78, 107, 12, 48, 210, + 78, 109, 12, 48, 202, 179, 132, 197, 255, 197, 177, 12, 48, 238, 241, 12, + 48, 236, 164, 12, 48, 223, 29, 12, 48, 248, 104, 79, 242, 215, 12, 48, + 233, 195, 12, 48, 201, 216, 107, 12, 48, 201, 216, 109, 12, 48, 249, 105, + 12, 48, 202, 186, 12, 48, 247, 192, 202, 186, 12, 48, 214, 88, 107, 12, + 48, 214, 88, 109, 12, 48, 214, 88, 138, 12, 48, 214, 88, 134, 12, 48, + 216, 174, 12, 48, 203, 108, 12, 48, 207, 144, 12, 48, 233, 225, 12, 48, + 211, 121, 12, 48, 248, 20, 107, 12, 48, 248, 20, 109, 12, 48, 216, 226, + 12, 48, 215, 201, 12, 48, 230, 216, 107, 12, 48, 230, 216, 109, 12, 48, + 230, 216, 138, 12, 48, 198, 173, 12, 48, 242, 214, 12, 48, 193, 105, 107, + 12, 48, 193, 105, 109, 12, 48, 247, 192, 205, 51, 12, 48, 202, 179, 228, + 189, 12, 48, 228, 189, 12, 48, 247, 192, 201, 230, 12, 48, 247, 192, 203, + 103, 12, 48, 232, 161, 12, 48, 247, 192, 247, 87, 12, 48, 202, 179, 193, + 169, 12, 48, 193, 170, 107, 12, 48, 193, 170, 109, 12, 48, 242, 254, 12, + 48, 247, 192, 230, 252, 12, 48, 180, 107, 12, 48, 180, 109, 12, 48, 247, + 192, 219, 21, 12, 48, 247, 192, 231, 193, 12, 48, 215, 190, 107, 12, 48, + 215, 190, 109, 12, 48, 207, 151, 12, 48, 248, 116, 12, 48, 247, 192, 199, + 185, 219, 232, 12, 48, 247, 192, 219, 235, 12, 48, 247, 192, 193, 66, 12, + 48, 247, 192, 232, 181, 12, 48, 234, 203, 107, 12, 48, 234, 203, 109, 12, + 48, 234, 203, 138, 12, 48, 247, 192, 234, 202, 12, 48, 229, 237, 12, 48, + 247, 192, 228, 185, 12, 48, 248, 100, 12, 48, 231, 63, 12, 48, 247, 192, + 232, 238, 12, 48, 247, 192, 248, 162, 12, 48, 247, 192, 205, 159, 12, 48, + 202, 179, 193, 95, 12, 48, 202, 179, 192, 72, 12, 48, 247, 192, 232, 101, + 12, 48, 223, 36, 233, 230, 12, 48, 247, 192, 233, 230, 12, 48, 223, 36, + 198, 56, 12, 48, 247, 192, 198, 56, 12, 48, 223, 36, 235, 113, 12, 48, + 247, 192, 235, 113, 12, 48, 197, 55, 12, 48, 223, 36, 197, 55, 12, 48, + 247, 192, 197, 55, 83, 48, 107, 83, 48, 219, 114, 83, 48, 236, 142, 83, + 48, 202, 98, 83, 48, 205, 57, 83, 48, 102, 83, 48, 109, 83, 48, 219, 143, + 83, 48, 217, 92, 83, 48, 219, 211, 83, 48, 234, 79, 83, 48, 171, 83, 48, + 144, 248, 64, 83, 48, 238, 244, 83, 48, 228, 28, 83, 48, 199, 233, 83, + 48, 211, 79, 248, 64, 83, 48, 221, 80, 83, 48, 209, 0, 83, 48, 193, 12, + 83, 48, 201, 204, 83, 48, 50, 211, 79, 248, 64, 83, 48, 229, 148, 234, + 100, 83, 48, 199, 95, 83, 48, 236, 204, 83, 48, 205, 62, 83, 48, 242, + 232, 83, 48, 208, 206, 83, 48, 251, 254, 83, 48, 215, 181, 83, 48, 234, + 100, 83, 48, 234, 209, 83, 48, 205, 92, 83, 48, 231, 5, 83, 48, 231, 6, + 202, 75, 83, 48, 233, 229, 83, 48, 248, 176, 83, 48, 193, 35, 83, 48, + 243, 88, 83, 48, 206, 134, 83, 48, 223, 160, 83, 48, 202, 71, 83, 48, + 220, 31, 83, 48, 238, 254, 83, 48, 201, 195, 83, 48, 215, 186, 83, 48, + 206, 177, 83, 48, 193, 20, 83, 48, 211, 97, 83, 48, 197, 63, 83, 48, 235, + 93, 83, 48, 203, 41, 198, 227, 83, 48, 235, 140, 242, 232, 83, 48, 180, + 201, 35, 83, 48, 105, 230, 30, 83, 48, 203, 47, 83, 48, 248, 71, 83, 48, + 202, 55, 83, 48, 248, 27, 83, 48, 201, 79, 83, 48, 229, 225, 83, 48, 230, + 73, 83, 48, 236, 146, 83, 48, 230, 55, 83, 48, 248, 49, 83, 48, 207, 138, + 83, 48, 205, 75, 83, 48, 236, 238, 83, 48, 250, 134, 83, 48, 201, 191, + 83, 48, 213, 13, 83, 48, 200, 198, 83, 48, 205, 104, 83, 48, 215, 207, + 83, 48, 197, 254, 83, 48, 220, 113, 83, 48, 201, 64, 83, 48, 237, 145, + 83, 48, 193, 120, 83, 48, 236, 177, 213, 13, 83, 48, 242, 72, 83, 48, + 232, 74, 83, 48, 242, 245, 83, 48, 201, 85, 83, 48, 193, 143, 83, 48, + 232, 245, 83, 48, 242, 241, 83, 48, 233, 68, 83, 48, 55, 192, 235, 83, + 48, 132, 197, 255, 197, 177, 83, 48, 202, 89, 83, 48, 233, 80, 83, 48, + 238, 241, 83, 48, 236, 164, 83, 48, 208, 201, 83, 48, 223, 29, 83, 48, + 216, 198, 83, 48, 198, 151, 83, 48, 200, 141, 83, 48, 219, 137, 83, 48, + 196, 43, 83, 48, 233, 23, 83, 48, 248, 104, 79, 242, 215, 83, 48, 202, + 213, 83, 48, 235, 140, 199, 87, 83, 48, 193, 89, 83, 48, 202, 108, 83, + 48, 236, 224, 83, 48, 233, 195, 83, 48, 201, 233, 83, 48, 57, 83, 48, + 201, 66, 83, 48, 201, 215, 83, 48, 198, 25, 83, 48, 230, 225, 83, 48, + 247, 72, 83, 48, 201, 108, 83, 48, 249, 105, 83, 48, 206, 246, 83, 48, + 202, 186, 83, 48, 223, 20, 83, 48, 214, 87, 83, 48, 203, 108, 83, 48, + 233, 56, 83, 48, 211, 121, 83, 48, 251, 127, 83, 48, 209, 91, 83, 48, + 234, 213, 83, 48, 248, 19, 83, 48, 216, 226, 83, 48, 216, 39, 83, 48, + 204, 33, 83, 48, 250, 241, 83, 48, 215, 201, 83, 48, 198, 61, 83, 48, + 211, 66, 83, 48, 248, 108, 83, 48, 201, 60, 83, 48, 242, 84, 83, 48, 230, + 215, 83, 48, 198, 173, 83, 48, 223, 123, 83, 48, 248, 122, 83, 48, 193, + 170, 234, 100, 83, 48, 242, 214, 83, 48, 193, 104, 83, 48, 205, 51, 83, + 48, 228, 189, 83, 48, 201, 230, 83, 48, 195, 180, 83, 48, 249, 14, 83, + 48, 209, 149, 83, 48, 249, 135, 83, 48, 203, 103, 83, 48, 207, 88, 83, + 48, 206, 46, 83, 48, 232, 161, 83, 48, 248, 106, 83, 48, 247, 87, 83, 48, + 248, 146, 83, 48, 215, 203, 83, 48, 193, 169, 83, 48, 242, 254, 83, 48, + 193, 62, 83, 48, 236, 216, 83, 48, 195, 50, 83, 48, 230, 252, 83, 48, + 219, 21, 83, 48, 231, 193, 83, 48, 215, 189, 83, 48, 202, 97, 83, 48, + 203, 41, 199, 214, 248, 162, 83, 48, 207, 151, 83, 48, 248, 116, 83, 48, + 193, 2, 83, 48, 233, 105, 83, 48, 219, 232, 83, 48, 199, 185, 219, 232, + 83, 48, 219, 228, 83, 48, 202, 5, 83, 48, 219, 235, 83, 48, 193, 66, 83, + 48, 232, 181, 83, 48, 234, 202, 83, 48, 229, 237, 83, 48, 232, 118, 83, + 48, 228, 185, 83, 48, 248, 100, 83, 48, 199, 199, 83, 48, 230, 80, 83, + 48, 233, 16, 83, 48, 205, 195, 193, 62, 83, 48, 247, 74, 83, 48, 231, 63, + 83, 48, 232, 238, 83, 48, 248, 162, 83, 48, 205, 159, 83, 48, 237, 130, + 83, 48, 193, 95, 83, 48, 229, 201, 83, 48, 192, 72, 83, 48, 216, 51, 83, + 48, 248, 141, 83, 48, 234, 112, 83, 48, 232, 101, 83, 48, 197, 222, 83, + 48, 235, 96, 83, 48, 207, 132, 83, 48, 213, 15, 83, 48, 233, 230, 83, 48, + 198, 56, 83, 48, 235, 113, 83, 48, 197, 55, 83, 48, 232, 184, 148, 237, + 87, 246, 242, 45, 119, 179, 148, 237, 87, 246, 242, 93, 119, 60, 148, + 237, 87, 246, 242, 45, 119, 82, 23, 179, 148, 237, 87, 246, 242, 93, 119, + 82, 23, 60, 148, 237, 87, 246, 242, 232, 82, 200, 168, 148, 237, 87, 246, + 242, 200, 169, 232, 100, 58, 148, 237, 87, 246, 242, 200, 169, 232, 100, + 60, 148, 237, 87, 246, 242, 200, 169, 232, 100, 219, 226, 148, 237, 87, + 246, 242, 200, 169, 232, 100, 116, 219, 226, 148, 237, 87, 246, 242, 200, + 169, 232, 100, 116, 179, 148, 237, 87, 246, 242, 200, 169, 232, 100, 110, + 219, 226, 148, 237, 87, 246, 242, 211, 5, 148, 237, 87, 246, 242, 200, + 169, 232, 100, 179, 148, 237, 87, 246, 242, 200, 169, 232, 100, 110, 179, + 148, 237, 87, 246, 242, 228, 243, 207, 84, 148, 237, 87, 246, 242, 206, + 121, 148, 201, 248, 148, 242, 76, 148, 232, 82, 201, 64, 236, 213, 77, + 223, 21, 223, 143, 201, 107, 113, 148, 223, 53, 77, 148, 242, 217, 77, + 148, 31, 191, 77, 45, 251, 118, 248, 55, 50, 251, 118, 248, 55, 45, 55, + 251, 118, 248, 55, 50, 55, 251, 118, 248, 55, 45, 239, 4, 248, 55, 50, + 239, 4, 248, 55, 45, 63, 239, 4, 248, 55, 50, 63, 239, 4, 248, 55, 45, + 62, 219, 189, 248, 55, 50, 62, 219, 189, 248, 55, 209, 20, 77, 231, 132, + 77, 45, 198, 42, 203, 104, 248, 55, 50, 198, 42, 203, 104, 248, 55, 45, + 63, 219, 189, 248, 55, 50, 63, 219, 189, 248, 55, 45, 63, 198, 42, 203, + 104, 248, 55, 50, 63, 198, 42, 203, 104, 248, 55, 45, 63, 51, 248, 55, + 50, 63, 51, 248, 55, 193, 139, 237, 217, 207, 19, 55, 208, 218, 207, 254, + 77, 55, 208, 218, 207, 254, 77, 130, 55, 208, 218, 207, 254, 77, 209, 20, + 87, 233, 105, 230, 27, 212, 136, 107, 230, 27, 212, 136, 109, 230, 27, + 212, 136, 138, 230, 27, 212, 136, 134, 230, 27, 212, 136, 150, 230, 27, + 212, 136, 169, 230, 27, 212, 136, 175, 230, 27, 212, 136, 171, 230, 27, + 212, 136, 178, 148, 219, 170, 163, 77, 148, 206, 181, 163, 77, 148, 237, + 97, 163, 77, 148, 234, 78, 163, 77, 30, 202, 171, 75, 163, 77, 30, 55, + 75, 163, 77, 193, 135, 237, 217, 81, 222, 88, 207, 50, 77, 81, 222, 88, + 207, 50, 4, 195, 20, 202, 6, 77, 81, 222, 88, 207, 50, 87, 116, 230, 72, + 81, 222, 88, 207, 50, 4, 195, 20, 202, 6, 87, 116, 230, 72, 81, 222, 88, + 207, 50, 87, 110, 230, 72, 47, 209, 20, 77, 148, 199, 109, 219, 115, 233, + 53, 204, 12, 113, 230, 27, 212, 136, 199, 95, 230, 27, 212, 136, 197, 32, + 230, 27, 212, 136, 198, 249, 81, 148, 223, 53, 77, 217, 33, 77, 210, 109, + 251, 155, 77, 148, 67, 223, 146, 148, 132, 233, 8, 201, 248, 229, 122, 1, + 2, 65, 229, 122, 1, 65, 229, 122, 1, 2, 68, 229, 122, 1, 68, 229, 122, 1, + 2, 66, 229, 122, 1, 66, 229, 122, 1, 2, 71, 229, 122, 1, 71, 229, 122, 1, + 2, 74, 229, 122, 1, 74, 229, 122, 1, 155, 229, 122, 1, 231, 242, 229, + 122, 1, 221, 168, 229, 122, 1, 231, 55, 229, 122, 1, 220, 234, 229, 122, + 1, 230, 181, 229, 122, 1, 222, 24, 229, 122, 1, 231, 167, 229, 122, 1, + 221, 69, 229, 122, 1, 231, 5, 229, 122, 1, 188, 229, 122, 1, 191, 123, + 229, 122, 1, 202, 223, 229, 122, 1, 191, 30, 229, 122, 1, 201, 5, 229, + 122, 1, 190, 251, 229, 122, 1, 205, 69, 229, 122, 1, 191, 87, 229, 122, + 1, 202, 47, 229, 122, 1, 191, 7, 229, 122, 1, 190, 190, 229, 122, 1, 238, + 34, 229, 122, 1, 198, 193, 229, 122, 1, 237, 46, 229, 122, 1, 2, 197, 94, + 229, 122, 1, 197, 94, 229, 122, 1, 235, 91, 229, 122, 1, 199, 145, 229, + 122, 1, 237, 148, 229, 122, 1, 159, 229, 122, 1, 236, 176, 229, 122, 1, + 181, 229, 122, 1, 213, 221, 229, 122, 1, 212, 180, 229, 122, 1, 214, 123, + 229, 122, 1, 213, 45, 229, 122, 1, 140, 229, 122, 1, 249, 155, 229, 122, + 1, 168, 229, 122, 1, 229, 160, 229, 122, 1, 248, 190, 229, 122, 1, 209, + 187, 229, 122, 1, 228, 161, 229, 122, 1, 248, 12, 229, 122, 1, 208, 167, + 229, 122, 1, 229, 247, 229, 122, 1, 249, 19, 229, 122, 1, 210, 65, 229, + 122, 1, 229, 25, 229, 122, 1, 248, 113, 229, 122, 1, 209, 75, 229, 122, + 1, 174, 229, 122, 1, 216, 102, 229, 122, 1, 215, 157, 229, 122, 1, 216, + 234, 229, 122, 1, 216, 14, 229, 122, 1, 2, 170, 229, 122, 1, 170, 229, + 122, 1, 2, 191, 225, 229, 122, 1, 191, 225, 229, 122, 1, 2, 192, 12, 229, + 122, 1, 192, 12, 229, 122, 1, 165, 229, 122, 1, 207, 2, 229, 122, 1, 206, + 69, 229, 122, 1, 207, 115, 229, 122, 1, 206, 163, 229, 122, 1, 2, 193, + 190, 229, 122, 1, 193, 190, 229, 122, 1, 193, 86, 229, 122, 1, 193, 125, + 229, 122, 1, 193, 48, 229, 122, 1, 215, 63, 229, 122, 1, 193, 249, 229, + 122, 1, 2, 155, 229, 122, 1, 2, 222, 24, 33, 222, 50, 195, 20, 202, 6, + 77, 33, 222, 50, 204, 31, 202, 6, 77, 222, 50, 195, 20, 202, 6, 77, 222, + 50, 204, 31, 202, 6, 77, 229, 122, 223, 53, 77, 229, 122, 195, 20, 223, + 53, 77, 229, 122, 237, 5, 191, 242, 222, 50, 55, 228, 90, 72, 1, 2, 65, + 72, 1, 65, 72, 1, 2, 68, 72, 1, 68, 72, 1, 2, 66, 72, 1, 66, 72, 1, 2, + 71, 72, 1, 71, 72, 1, 2, 74, 72, 1, 74, 72, 1, 155, 72, 1, 231, 242, 72, + 1, 221, 168, 72, 1, 231, 55, 72, 1, 220, 234, 72, 1, 230, 181, 72, 1, + 222, 24, 72, 1, 231, 167, 72, 1, 221, 69, 72, 1, 231, 5, 72, 1, 188, 72, + 1, 191, 123, 72, 1, 202, 223, 72, 1, 191, 30, 72, 1, 201, 5, 72, 1, 190, + 251, 72, 1, 205, 69, 72, 1, 191, 87, 72, 1, 202, 47, 72, 1, 191, 7, 72, + 1, 190, 190, 72, 1, 238, 34, 72, 1, 198, 193, 72, 1, 237, 46, 72, 1, 2, + 197, 94, 72, 1, 197, 94, 72, 1, 235, 91, 72, 1, 199, 145, 72, 1, 237, + 148, 72, 1, 159, 72, 1, 236, 176, 72, 1, 181, 72, 1, 213, 221, 72, 1, + 212, 180, 72, 1, 214, 123, 72, 1, 213, 45, 72, 1, 140, 72, 1, 249, 155, + 72, 1, 168, 72, 1, 229, 160, 72, 1, 248, 190, 72, 1, 209, 187, 72, 1, + 228, 161, 72, 1, 248, 12, 72, 1, 208, 167, 72, 1, 229, 247, 72, 1, 249, + 19, 72, 1, 210, 65, 72, 1, 229, 25, 72, 1, 248, 113, 72, 1, 209, 75, 72, + 1, 174, 72, 1, 216, 102, 72, 1, 215, 157, 72, 1, 216, 234, 72, 1, 216, + 14, 72, 1, 2, 170, 72, 1, 170, 72, 1, 2, 191, 225, 72, 1, 191, 225, 72, + 1, 2, 192, 12, 72, 1, 192, 12, 72, 1, 165, 72, 1, 207, 2, 72, 1, 206, 69, + 72, 1, 207, 115, 72, 1, 206, 163, 72, 1, 2, 193, 190, 72, 1, 193, 190, + 72, 1, 193, 86, 72, 1, 193, 125, 72, 1, 193, 48, 72, 1, 215, 63, 72, 1, + 193, 249, 72, 1, 2, 155, 72, 1, 2, 222, 24, 72, 1, 195, 188, 72, 1, 195, + 69, 72, 1, 195, 153, 72, 1, 195, 24, 72, 82, 236, 142, 222, 50, 208, 193, + 202, 6, 77, 72, 223, 53, 77, 72, 195, 20, 223, 53, 77, 72, 237, 5, 221, + 29, 248, 90, 1, 250, 122, 248, 90, 1, 210, 238, 248, 90, 1, 218, 170, + 248, 90, 1, 233, 177, 248, 90, 1, 238, 129, 248, 90, 1, 200, 43, 248, 90, + 1, 215, 63, 248, 90, 1, 172, 248, 90, 1, 232, 53, 248, 90, 1, 222, 154, + 248, 90, 1, 230, 118, 248, 90, 1, 223, 37, 248, 90, 1, 208, 106, 248, 90, + 1, 192, 235, 248, 90, 1, 191, 72, 248, 90, 1, 247, 5, 248, 90, 1, 203, + 168, 248, 90, 1, 146, 248, 90, 1, 191, 166, 248, 90, 1, 247, 195, 248, + 90, 1, 206, 9, 248, 90, 1, 65, 248, 90, 1, 74, 248, 90, 1, 71, 248, 90, + 1, 234, 175, 248, 90, 1, 251, 238, 248, 90, 1, 234, 168, 248, 90, 1, 250, + 165, 248, 90, 1, 211, 21, 248, 90, 1, 251, 134, 248, 90, 1, 234, 105, + 248, 90, 1, 251, 124, 248, 90, 1, 234, 90, 248, 90, 1, 234, 36, 248, 90, + 1, 68, 248, 90, 1, 66, 248, 90, 1, 223, 51, 248, 90, 1, 196, 12, 248, 90, + 1, 214, 72, 248, 90, 1, 231, 9, 248, 90, 1, 223, 202, 248, 90, 1, 187, 4, + 75, 58, 248, 90, 1, 213, 82, 30, 1, 221, 115, 30, 1, 201, 168, 30, 1, + 221, 108, 30, 1, 213, 206, 30, 1, 213, 204, 30, 1, 213, 203, 30, 1, 198, + 168, 30, 1, 201, 157, 30, 1, 206, 240, 30, 1, 206, 235, 30, 1, 206, 232, + 30, 1, 206, 225, 30, 1, 206, 220, 30, 1, 206, 215, 30, 1, 206, 226, 30, + 1, 206, 238, 30, 1, 216, 79, 30, 1, 209, 171, 30, 1, 201, 165, 30, 1, + 209, 160, 30, 1, 202, 161, 30, 1, 201, 162, 30, 1, 223, 224, 30, 1, 243, + 26, 30, 1, 201, 172, 30, 1, 243, 93, 30, 1, 221, 190, 30, 1, 199, 7, 30, + 1, 209, 211, 30, 1, 229, 144, 30, 1, 65, 30, 1, 252, 27, 30, 1, 170, 30, + 1, 192, 129, 30, 1, 234, 67, 30, 1, 71, 30, 1, 192, 67, 30, 1, 192, 80, + 30, 1, 74, 30, 1, 193, 190, 30, 1, 193, 176, 30, 1, 211, 153, 30, 1, 192, + 12, 30, 1, 66, 30, 1, 193, 107, 30, 1, 193, 125, 30, 1, 193, 86, 30, 1, + 191, 225, 30, 1, 233, 244, 30, 1, 192, 33, 30, 1, 68, 30, 233, 5, 30, 1, + 201, 166, 30, 1, 213, 196, 30, 1, 213, 198, 30, 1, 213, 201, 30, 1, 206, + 233, 30, 1, 206, 214, 30, 1, 206, 222, 30, 1, 206, 227, 30, 1, 206, 212, + 30, 1, 216, 72, 30, 1, 216, 69, 30, 1, 216, 73, 30, 1, 222, 73, 30, 1, + 209, 166, 30, 1, 209, 152, 30, 1, 209, 158, 30, 1, 209, 155, 30, 1, 209, + 169, 30, 1, 209, 153, 30, 1, 222, 71, 30, 1, 222, 69, 30, 1, 202, 154, + 30, 1, 202, 152, 30, 1, 202, 144, 30, 1, 202, 149, 30, 1, 202, 159, 30, + 1, 210, 151, 30, 1, 201, 169, 30, 1, 192, 57, 30, 1, 192, 51, 30, 1, 192, + 52, 30, 1, 222, 72, 30, 1, 201, 170, 30, 1, 192, 63, 30, 1, 192, 0, 30, + 1, 191, 255, 30, 1, 192, 2, 30, 1, 191, 212, 30, 1, 191, 213, 30, 1, 191, + 216, 30, 1, 251, 27, 30, 1, 251, 21, 148, 251, 98, 219, 103, 77, 148, + 251, 98, 207, 20, 77, 148, 251, 98, 91, 77, 148, 251, 98, 105, 77, 148, + 251, 98, 115, 77, 148, 251, 98, 232, 130, 77, 148, 251, 98, 198, 54, 77, + 148, 251, 98, 82, 77, 148, 251, 98, 248, 79, 77, 148, 251, 98, 232, 240, + 77, 148, 251, 98, 205, 58, 77, 148, 251, 98, 199, 1, 77, 148, 251, 98, + 232, 123, 77, 148, 251, 98, 229, 222, 77, 148, 251, 98, 234, 210, 77, + 148, 251, 98, 217, 93, 77, 248, 90, 1, 248, 12, 248, 90, 1, 191, 30, 248, + 90, 1, 222, 246, 248, 90, 1, 230, 181, 248, 90, 1, 234, 190, 248, 90, 1, + 234, 87, 248, 90, 1, 211, 89, 248, 90, 1, 211, 93, 248, 90, 1, 223, 79, + 248, 90, 1, 251, 100, 248, 90, 1, 223, 130, 248, 90, 1, 196, 83, 248, 90, + 1, 223, 182, 248, 90, 1, 214, 50, 248, 90, 1, 251, 231, 248, 90, 1, 250, + 160, 248, 90, 1, 251, 151, 248, 90, 1, 211, 115, 248, 90, 1, 211, 96, + 248, 90, 1, 223, 127, 248, 90, 53, 1, 210, 238, 248, 90, 53, 1, 200, 43, + 248, 90, 53, 1, 222, 154, 248, 90, 53, 1, 230, 118, 248, 90, 1, 231, 94, + 248, 90, 1, 219, 162, 248, 90, 1, 190, 231, 248, 90, 53, 1, 232, 53, 248, + 90, 1, 230, 138, 248, 90, 1, 220, 182, 248, 90, 1, 211, 153, 248, 90, 1, + 251, 247, 12, 201, 29, 200, 43, 12, 201, 29, 193, 98, 12, 201, 29, 192, + 209, 12, 201, 29, 247, 208, 12, 201, 29, 200, 151, 12, 201, 29, 228, 80, + 12, 201, 29, 228, 84, 12, 201, 29, 228, 171, 12, 201, 29, 228, 81, 12, + 201, 29, 200, 46, 12, 201, 29, 228, 83, 12, 201, 29, 228, 79, 12, 201, + 29, 228, 169, 12, 201, 29, 228, 82, 12, 201, 29, 228, 78, 12, 201, 29, + 215, 63, 12, 201, 29, 230, 118, 12, 201, 29, 206, 9, 12, 201, 29, 210, + 238, 12, 201, 29, 201, 251, 12, 201, 29, 238, 129, 12, 201, 29, 228, 85, + 12, 201, 29, 229, 180, 12, 201, 29, 200, 55, 12, 201, 29, 200, 128, 12, + 201, 29, 201, 119, 12, 201, 29, 203, 174, 12, 201, 29, 210, 69, 12, 201, + 29, 208, 108, 12, 201, 29, 198, 99, 12, 201, 29, 200, 45, 12, 201, 29, + 200, 140, 12, 201, 29, 228, 96, 12, 201, 29, 228, 77, 12, 201, 29, 209, + 232, 12, 201, 29, 208, 106, 148, 237, 87, 246, 242, 200, 225, 72, 1, 2, + 220, 234, 72, 1, 2, 202, 223, 72, 1, 2, 201, 5, 72, 1, 2, 159, 72, 1, 2, + 212, 180, 72, 1, 2, 140, 72, 1, 2, 229, 160, 72, 1, 2, 228, 161, 72, 1, + 2, 229, 247, 72, 1, 2, 229, 25, 72, 1, 2, 215, 157, 72, 1, 2, 165, 72, 1, + 2, 207, 2, 72, 1, 2, 206, 69, 72, 1, 2, 207, 115, 72, 1, 2, 206, 163, + 127, 30, 221, 115, 127, 30, 213, 206, 127, 30, 198, 168, 127, 30, 206, + 240, 127, 30, 216, 79, 127, 30, 209, 171, 127, 30, 202, 161, 127, 30, + 223, 224, 127, 30, 243, 26, 127, 30, 243, 93, 127, 30, 221, 190, 127, 30, + 199, 7, 127, 30, 209, 211, 127, 30, 229, 144, 127, 30, 221, 116, 65, 127, + 30, 213, 207, 65, 127, 30, 198, 169, 65, 127, 30, 206, 241, 65, 127, 30, + 216, 80, 65, 127, 30, 209, 172, 65, 127, 30, 202, 162, 65, 127, 30, 223, + 225, 65, 127, 30, 243, 27, 65, 127, 30, 243, 94, 65, 127, 30, 221, 191, + 65, 127, 30, 199, 8, 65, 127, 30, 209, 212, 65, 127, 30, 229, 145, 65, + 127, 30, 243, 27, 66, 127, 221, 34, 246, 242, 211, 131, 127, 221, 34, + 246, 242, 187, 228, 161, 127, 228, 16, 107, 127, 228, 16, 109, 127, 228, + 16, 138, 127, 228, 16, 134, 127, 228, 16, 150, 127, 228, 16, 169, 127, + 228, 16, 175, 127, 228, 16, 171, 127, 228, 16, 178, 127, 228, 16, 199, + 95, 127, 228, 16, 215, 207, 127, 228, 16, 232, 245, 127, 228, 16, 193, + 143, 127, 228, 16, 193, 28, 127, 228, 16, 216, 167, 127, 228, 16, 234, + 209, 127, 228, 16, 200, 198, 127, 228, 16, 201, 67, 127, 228, 16, 230, 1, + 127, 228, 16, 202, 36, 127, 228, 16, 214, 229, 127, 228, 16, 201, 232, + 127, 228, 16, 233, 0, 127, 228, 16, 239, 52, 127, 228, 16, 220, 116, 127, + 228, 16, 207, 43, 127, 228, 16, 247, 140, 127, 228, 16, 201, 11, 127, + 228, 16, 200, 178, 127, 228, 16, 234, 77, 127, 228, 16, 207, 33, 127, + 228, 16, 251, 170, 127, 228, 16, 233, 33, 127, 228, 16, 207, 31, 127, + 228, 16, 204, 33, 127, 228, 16, 207, 110, 47, 228, 16, 208, 14, 47, 228, + 16, 221, 142, 47, 228, 16, 205, 90, 47, 228, 16, 221, 29, 47, 31, 199, + 96, 211, 107, 62, 201, 191, 47, 31, 197, 33, 211, 107, 62, 201, 191, 47, + 31, 198, 250, 211, 107, 62, 201, 191, 47, 31, 232, 138, 211, 107, 62, + 201, 191, 47, 31, 233, 18, 211, 107, 62, 201, 191, 47, 31, 202, 122, 211, + 107, 62, 201, 191, 47, 31, 203, 243, 211, 107, 62, 201, 191, 47, 31, 234, + 156, 211, 107, 62, 201, 191, 210, 105, 56, 47, 31, 197, 33, 107, 47, 31, + 197, 33, 109, 47, 31, 197, 33, 138, 47, 31, 197, 33, 134, 47, 31, 197, + 33, 150, 47, 31, 197, 33, 169, 47, 31, 197, 33, 175, 47, 31, 197, 33, + 171, 47, 31, 197, 33, 178, 47, 31, 198, 249, 47, 31, 198, 250, 107, 47, + 31, 198, 250, 109, 47, 31, 198, 250, 138, 47, 31, 198, 250, 134, 47, 31, + 198, 250, 150, 47, 30, 221, 115, 47, 30, 213, 206, 47, 30, 198, 168, 47, + 30, 206, 240, 47, 30, 216, 79, 47, 30, 209, 171, 47, 30, 202, 161, 47, + 30, 223, 224, 47, 30, 243, 26, 47, 30, 243, 93, 47, 30, 221, 190, 47, 30, + 199, 7, 47, 30, 209, 211, 47, 30, 229, 144, 47, 30, 221, 116, 65, 47, 30, + 213, 207, 65, 47, 30, 198, 169, 65, 47, 30, 206, 241, 65, 47, 30, 216, + 80, 65, 47, 30, 209, 172, 65, 47, 30, 202, 162, 65, 47, 30, 223, 225, 65, + 47, 30, 243, 27, 65, 47, 30, 243, 94, 65, 47, 30, 221, 191, 65, 47, 30, + 199, 8, 65, 47, 30, 209, 212, 65, 47, 30, 229, 145, 65, 47, 221, 34, 246, + 242, 246, 249, 47, 221, 34, 246, 242, 222, 180, 47, 30, 223, 225, 66, + 221, 34, 201, 107, 113, 47, 228, 16, 107, 47, 228, 16, 109, 47, 228, 16, + 138, 47, 228, 16, 134, 47, 228, 16, 150, 47, 228, 16, 169, 47, 228, 16, + 175, 47, 228, 16, 171, 47, 228, 16, 178, 47, 228, 16, 199, 95, 47, 228, + 16, 215, 207, 47, 228, 16, 232, 245, 47, 228, 16, 193, 143, 47, 228, 16, + 193, 28, 47, 228, 16, 216, 167, 47, 228, 16, 234, 209, 47, 228, 16, 200, + 198, 47, 228, 16, 201, 67, 47, 228, 16, 230, 1, 47, 228, 16, 202, 36, 47, + 228, 16, 214, 229, 47, 228, 16, 201, 232, 47, 228, 16, 233, 0, 47, 228, + 16, 239, 52, 47, 228, 16, 220, 116, 47, 228, 16, 205, 56, 47, 228, 16, + 217, 98, 47, 228, 16, 233, 43, 47, 228, 16, 200, 210, 47, 228, 16, 233, + 222, 47, 228, 16, 208, 213, 47, 228, 16, 250, 169, 47, 228, 16, 223, 54, + 47, 228, 16, 207, 31, 47, 228, 16, 239, 10, 47, 228, 16, 238, 253, 47, + 228, 16, 229, 137, 47, 228, 16, 247, 23, 47, 228, 16, 218, 243, 47, 228, + 16, 219, 226, 47, 228, 16, 179, 47, 228, 16, 216, 217, 47, 228, 16, 207, + 61, 47, 228, 16, 201, 11, 47, 228, 16, 200, 178, 47, 228, 16, 234, 77, + 47, 228, 16, 207, 33, 47, 228, 16, 251, 170, 47, 228, 16, 213, 192, 47, 31, 198, 250, 169, 47, 31, 198, 250, 175, 47, 31, 198, 250, 171, 47, 31, - 198, 250, 178, 47, 31, 232, 135, 47, 31, 232, 136, 107, 47, 31, 232, 136, - 109, 47, 31, 232, 136, 138, 47, 31, 232, 136, 134, 47, 31, 232, 136, 149, - 47, 31, 232, 136, 169, 47, 31, 232, 136, 175, 47, 31, 232, 136, 171, 47, - 31, 232, 136, 178, 47, 31, 233, 15, 154, 199, 109, 16, 40, 223, 21, 154, - 199, 109, 16, 40, 233, 53, 154, 199, 109, 16, 40, 217, 58, 154, 199, 109, - 16, 40, 251, 39, 154, 199, 109, 16, 40, 217, 21, 154, 199, 109, 16, 40, - 222, 175, 154, 199, 109, 16, 40, 222, 176, 154, 199, 109, 16, 40, 250, - 159, 154, 199, 109, 16, 40, 204, 9, 154, 199, 109, 16, 40, 211, 157, 154, - 199, 109, 16, 40, 212, 255, 154, 199, 109, 16, 40, 237, 140, 51, 229, - 178, 51, 234, 30, 51, 233, 230, 219, 118, 219, 145, 56, 47, 72, 65, 47, + 198, 250, 178, 47, 31, 232, 137, 47, 31, 232, 138, 107, 47, 31, 232, 138, + 109, 47, 31, 232, 138, 138, 47, 31, 232, 138, 134, 47, 31, 232, 138, 150, + 47, 31, 232, 138, 169, 47, 31, 232, 138, 175, 47, 31, 232, 138, 171, 47, + 31, 232, 138, 178, 47, 31, 233, 17, 148, 199, 109, 16, 40, 223, 23, 148, + 199, 109, 16, 40, 233, 55, 148, 199, 109, 16, 40, 217, 60, 148, 199, 109, + 16, 40, 251, 41, 148, 199, 109, 16, 40, 217, 23, 148, 199, 109, 16, 40, + 222, 177, 148, 199, 109, 16, 40, 222, 178, 148, 199, 109, 16, 40, 250, + 161, 148, 199, 109, 16, 40, 204, 10, 148, 199, 109, 16, 40, 211, 159, + 148, 199, 109, 16, 40, 213, 1, 148, 199, 109, 16, 40, 237, 142, 51, 229, + 180, 51, 234, 32, 51, 233, 232, 219, 120, 219, 147, 56, 47, 72, 65, 47, 72, 68, 47, 72, 66, 47, 72, 71, 47, 72, 74, 47, 72, 155, 47, 72, 221, - 166, 47, 72, 220, 232, 47, 72, 222, 22, 47, 72, 221, 67, 47, 72, 188, 47, - 72, 202, 222, 47, 72, 201, 4, 47, 72, 205, 68, 47, 72, 202, 46, 47, 72, + 168, 47, 72, 220, 234, 47, 72, 222, 24, 47, 72, 221, 69, 47, 72, 188, 47, + 72, 202, 223, 47, 72, 201, 5, 47, 72, 205, 69, 47, 72, 202, 47, 47, 72, 190, 190, 47, 72, 198, 193, 47, 72, 197, 94, 47, 72, 199, 145, 47, 72, - 159, 47, 72, 180, 47, 72, 213, 219, 47, 72, 212, 178, 47, 72, 214, 121, - 47, 72, 213, 43, 47, 72, 140, 47, 72, 229, 158, 47, 72, 228, 159, 47, 72, - 229, 245, 47, 72, 229, 23, 47, 72, 174, 47, 72, 216, 100, 47, 72, 215, - 155, 47, 72, 216, 232, 47, 72, 216, 12, 47, 72, 170, 47, 72, 191, 225, - 47, 72, 192, 12, 47, 72, 165, 47, 72, 207, 1, 47, 72, 206, 68, 47, 72, - 207, 113, 47, 72, 206, 162, 47, 72, 193, 190, 47, 72, 193, 86, 47, 72, - 193, 125, 47, 72, 193, 48, 51, 234, 33, 214, 228, 207, 68, 51, 251, 64, - 51, 250, 221, 51, 251, 92, 51, 252, 163, 51, 223, 130, 51, 223, 97, 51, - 196, 80, 51, 234, 2, 51, 234, 185, 51, 211, 90, 51, 211, 83, 51, 222, - 100, 51, 222, 63, 51, 222, 58, 51, 231, 195, 51, 231, 205, 51, 231, 41, - 51, 231, 35, 51, 220, 144, 51, 231, 26, 51, 221, 131, 51, 221, 130, 51, - 221, 129, 51, 221, 128, 51, 230, 146, 51, 230, 145, 51, 220, 193, 51, - 220, 196, 51, 222, 9, 51, 221, 29, 51, 221, 38, 51, 205, 180, 51, 205, - 133, 51, 202, 141, 51, 204, 15, 51, 204, 14, 51, 238, 28, 51, 237, 81, - 51, 236, 141, 51, 198, 81, 51, 214, 221, 51, 213, 0, 51, 230, 75, 51, - 210, 214, 51, 210, 213, 51, 249, 150, 51, 209, 181, 51, 209, 143, 51, - 209, 144, 51, 248, 156, 51, 228, 154, 51, 228, 148, 51, 247, 221, 51, - 228, 132, 51, 229, 206, 51, 209, 241, 51, 210, 29, 51, 229, 187, 51, 210, - 25, 51, 210, 43, 51, 248, 252, 51, 209, 57, 51, 248, 84, 51, 228, 255, - 51, 209, 38, 51, 228, 246, 51, 228, 248, 51, 217, 110, 51, 217, 106, 51, - 217, 115, 51, 217, 44, 51, 217, 76, 51, 216, 56, 51, 216, 29, 51, 216, - 28, 51, 216, 203, 51, 216, 200, 51, 216, 204, 51, 192, 139, 51, 192, 137, - 51, 191, 210, 51, 206, 178, 51, 206, 182, 51, 206, 35, 51, 206, 28, 51, - 207, 57, 51, 207, 54, 51, 193, 141, 154, 199, 109, 16, 40, 228, 177, 191, - 77, 154, 199, 109, 16, 40, 228, 177, 107, 154, 199, 109, 16, 40, 228, - 177, 109, 154, 199, 109, 16, 40, 228, 177, 138, 154, 199, 109, 16, 40, - 228, 177, 134, 154, 199, 109, 16, 40, 228, 177, 149, 154, 199, 109, 16, - 40, 228, 177, 169, 154, 199, 109, 16, 40, 228, 177, 175, 154, 199, 109, - 16, 40, 228, 177, 171, 154, 199, 109, 16, 40, 228, 177, 178, 154, 199, - 109, 16, 40, 228, 177, 199, 95, 154, 199, 109, 16, 40, 228, 177, 234, - 127, 154, 199, 109, 16, 40, 228, 177, 197, 37, 154, 199, 109, 16, 40, - 228, 177, 198, 251, 154, 199, 109, 16, 40, 228, 177, 232, 122, 154, 199, - 109, 16, 40, 228, 177, 233, 19, 154, 199, 109, 16, 40, 228, 177, 202, - 130, 154, 199, 109, 16, 40, 228, 177, 203, 244, 154, 199, 109, 16, 40, - 228, 177, 234, 161, 154, 199, 109, 16, 40, 228, 177, 213, 171, 154, 199, - 109, 16, 40, 228, 177, 197, 32, 154, 199, 109, 16, 40, 228, 177, 197, 25, - 154, 199, 109, 16, 40, 228, 177, 197, 20, 154, 199, 109, 16, 40, 228, - 177, 197, 22, 154, 199, 109, 16, 40, 228, 177, 197, 27, 51, 228, 168, 51, - 238, 32, 51, 250, 163, 51, 164, 51, 211, 9, 51, 210, 68, 51, 236, 177, - 51, 236, 178, 201, 189, 51, 236, 178, 238, 189, 51, 223, 49, 51, 234, 33, - 214, 228, 229, 207, 51, 234, 33, 214, 228, 200, 66, 51, 234, 33, 214, - 228, 199, 212, 51, 234, 33, 214, 228, 216, 199, 51, 238, 253, 51, 210, - 221, 251, 135, 51, 180, 51, 215, 156, 65, 51, 174, 51, 155, 51, 222, 25, - 51, 217, 16, 51, 231, 183, 51, 247, 144, 51, 222, 24, 51, 209, 231, 51, - 214, 72, 51, 215, 156, 233, 175, 51, 215, 156, 232, 51, 51, 216, 141, 51, - 221, 217, 51, 228, 83, 51, 221, 168, 51, 216, 102, 51, 231, 55, 51, 198, - 195, 51, 215, 156, 172, 51, 216, 20, 51, 236, 187, 51, 221, 95, 51, 232, - 177, 51, 213, 81, 51, 215, 156, 218, 168, 51, 216, 17, 51, 242, 199, 51, - 221, 81, 51, 216, 18, 201, 189, 51, 242, 200, 201, 189, 51, 218, 169, - 201, 189, 51, 221, 82, 201, 189, 51, 216, 18, 238, 189, 51, 242, 200, - 238, 189, 51, 218, 169, 238, 189, 51, 221, 82, 238, 189, 51, 218, 169, - 139, 206, 8, 51, 218, 169, 139, 206, 9, 201, 189, 51, 168, 51, 221, 21, - 51, 215, 166, 51, 230, 229, 51, 207, 168, 51, 207, 169, 139, 206, 8, 51, - 207, 169, 139, 206, 9, 201, 189, 51, 208, 178, 51, 212, 219, 51, 215, - 156, 206, 8, 51, 215, 158, 51, 208, 124, 51, 212, 112, 51, 215, 156, 196, - 12, 51, 215, 87, 51, 220, 182, 51, 215, 88, 216, 203, 51, 208, 123, 51, - 212, 111, 51, 215, 156, 193, 224, 51, 215, 81, 51, 220, 180, 51, 215, 82, - 216, 203, 51, 222, 153, 211, 134, 51, 218, 169, 211, 134, 51, 251, 149, - 51, 248, 57, 51, 247, 66, 51, 247, 43, 51, 247, 194, 139, 221, 217, 51, - 242, 99, 51, 237, 200, 51, 230, 129, 51, 140, 51, 228, 169, 51, 223, 162, - 51, 221, 102, 51, 221, 82, 247, 110, 51, 220, 234, 51, 219, 46, 51, 219, - 45, 51, 219, 30, 51, 218, 184, 51, 217, 17, 202, 70, 51, 216, 55, 51, - 215, 233, 51, 209, 229, 51, 209, 76, 51, 208, 249, 51, 208, 247, 51, 201, - 180, 51, 200, 158, 51, 193, 127, 51, 196, 13, 139, 218, 168, 51, 42, 139, - 218, 168, 154, 199, 109, 16, 40, 237, 204, 107, 154, 199, 109, 16, 40, - 237, 204, 109, 154, 199, 109, 16, 40, 237, 204, 138, 154, 199, 109, 16, - 40, 237, 204, 134, 154, 199, 109, 16, 40, 237, 204, 149, 154, 199, 109, - 16, 40, 237, 204, 169, 154, 199, 109, 16, 40, 237, 204, 175, 154, 199, - 109, 16, 40, 237, 204, 171, 154, 199, 109, 16, 40, 237, 204, 178, 154, - 199, 109, 16, 40, 237, 204, 199, 95, 154, 199, 109, 16, 40, 237, 204, - 234, 127, 154, 199, 109, 16, 40, 237, 204, 197, 37, 154, 199, 109, 16, - 40, 237, 204, 198, 251, 154, 199, 109, 16, 40, 237, 204, 232, 122, 154, - 199, 109, 16, 40, 237, 204, 233, 19, 154, 199, 109, 16, 40, 237, 204, - 202, 130, 154, 199, 109, 16, 40, 237, 204, 203, 244, 154, 199, 109, 16, - 40, 237, 204, 234, 161, 154, 199, 109, 16, 40, 237, 204, 213, 171, 154, - 199, 109, 16, 40, 237, 204, 197, 32, 154, 199, 109, 16, 40, 237, 204, - 197, 25, 154, 199, 109, 16, 40, 237, 204, 197, 20, 154, 199, 109, 16, 40, - 237, 204, 197, 22, 154, 199, 109, 16, 40, 237, 204, 197, 27, 154, 199, - 109, 16, 40, 237, 204, 197, 28, 154, 199, 109, 16, 40, 237, 204, 197, 23, - 154, 199, 109, 16, 40, 237, 204, 197, 24, 154, 199, 109, 16, 40, 237, - 204, 197, 31, 154, 199, 109, 16, 40, 237, 204, 197, 26, 154, 199, 109, - 16, 40, 237, 204, 198, 249, 154, 199, 109, 16, 40, 237, 204, 198, 247, - 51, 231, 222, 229, 181, 40, 199, 34, 238, 231, 229, 219, 229, 181, 40, - 199, 34, 207, 100, 234, 207, 229, 181, 40, 237, 14, 250, 183, 199, 34, - 248, 247, 229, 181, 40, 191, 238, 232, 168, 229, 181, 40, 193, 171, 229, - 181, 40, 239, 53, 229, 181, 40, 199, 34, 250, 246, 229, 181, 40, 229, 6, - 198, 87, 229, 181, 40, 2, 199, 194, 229, 181, 40, 198, 1, 229, 181, 40, - 210, 60, 229, 181, 40, 201, 104, 229, 181, 40, 233, 43, 229, 181, 40, - 230, 206, 209, 21, 229, 181, 40, 215, 254, 229, 181, 40, 234, 74, 229, - 181, 40, 232, 169, 229, 181, 40, 193, 21, 211, 105, 199, 34, 237, 141, - 229, 181, 40, 251, 43, 229, 181, 40, 239, 31, 229, 181, 40, 248, 145, - 198, 215, 229, 181, 40, 230, 227, 229, 181, 40, 201, 208, 251, 63, 229, - 181, 40, 207, 22, 229, 181, 40, 223, 124, 229, 181, 40, 230, 206, 199, - 194, 229, 181, 40, 215, 180, 239, 0, 229, 181, 40, 230, 206, 208, 224, - 229, 181, 40, 199, 34, 252, 65, 193, 143, 229, 181, 40, 199, 34, 242, - 227, 232, 243, 229, 181, 40, 223, 138, 229, 181, 40, 235, 64, 229, 181, - 40, 207, 25, 229, 181, 40, 230, 206, 208, 254, 229, 181, 40, 208, 197, - 229, 181, 40, 237, 220, 79, 199, 34, 219, 132, 229, 181, 40, 199, 34, - 233, 81, 229, 181, 40, 211, 62, 229, 181, 40, 211, 167, 229, 181, 40, - 237, 111, 229, 181, 40, 237, 133, 229, 181, 40, 223, 153, 229, 181, 40, - 248, 41, 229, 181, 40, 242, 76, 119, 216, 206, 229, 181, 40, 231, 190, - 198, 87, 229, 181, 40, 208, 135, 196, 67, 229, 181, 40, 211, 61, 229, - 181, 40, 199, 34, 193, 109, 229, 181, 40, 207, 13, 229, 181, 40, 199, 34, - 247, 72, 229, 181, 40, 199, 34, 250, 242, 198, 209, 229, 181, 40, 199, - 34, 222, 10, 201, 70, 215, 184, 229, 181, 40, 237, 76, 229, 181, 40, 199, - 34, 217, 47, 217, 111, 229, 181, 40, 252, 66, 229, 181, 40, 199, 34, 193, - 161, 229, 181, 40, 199, 34, 231, 145, 193, 66, 229, 181, 40, 199, 34, - 222, 184, 220, 43, 229, 181, 40, 236, 219, 229, 181, 40, 219, 119, 229, - 181, 40, 223, 127, 197, 176, 229, 181, 40, 2, 208, 224, 229, 181, 40, - 251, 254, 242, 66, 229, 181, 40, 248, 250, 242, 66, 11, 5, 223, 53, 11, - 5, 223, 45, 11, 5, 68, 11, 5, 223, 80, 11, 5, 223, 224, 11, 5, 223, 207, - 11, 5, 223, 226, 11, 5, 223, 225, 11, 5, 250, 182, 11, 5, 250, 133, 11, - 5, 65, 11, 5, 251, 65, 11, 5, 196, 78, 11, 5, 196, 82, 11, 5, 196, 79, - 11, 5, 211, 30, 11, 5, 210, 247, 11, 5, 74, 11, 5, 211, 78, 11, 5, 233, - 221, 11, 5, 71, 11, 5, 193, 0, 11, 5, 248, 148, 11, 5, 248, 143, 11, 5, - 248, 188, 11, 5, 248, 161, 11, 5, 248, 177, 11, 5, 248, 176, 11, 5, 248, - 179, 11, 5, 248, 178, 11, 5, 249, 64, 11, 5, 249, 56, 11, 5, 249, 153, - 11, 5, 249, 89, 11, 5, 247, 234, 11, 5, 247, 238, 11, 5, 247, 235, 11, 5, - 248, 81, 11, 5, 248, 62, 11, 5, 248, 111, 11, 5, 248, 89, 11, 5, 248, - 206, 11, 5, 249, 17, 11, 5, 248, 219, 11, 5, 247, 217, 11, 5, 247, 211, - 11, 5, 248, 10, 11, 5, 247, 232, 11, 5, 247, 225, 11, 5, 247, 230, 11, 5, - 247, 199, 11, 5, 247, 197, 11, 5, 247, 204, 11, 5, 247, 202, 11, 5, 247, - 200, 11, 5, 247, 201, 11, 5, 209, 117, 11, 5, 209, 113, 11, 5, 209, 185, - 11, 5, 209, 129, 11, 5, 209, 149, 11, 5, 209, 176, 11, 5, 209, 172, 11, - 5, 210, 89, 11, 5, 210, 73, 11, 5, 168, 11, 5, 210, 137, 11, 5, 208, 145, - 11, 5, 208, 147, 11, 5, 208, 146, 11, 5, 209, 14, 11, 5, 208, 252, 11, 5, - 209, 73, 11, 5, 209, 33, 11, 5, 208, 131, 11, 5, 208, 126, 11, 5, 208, - 165, 11, 5, 208, 144, 11, 5, 208, 136, 11, 5, 208, 142, 11, 5, 208, 108, - 11, 5, 208, 107, 11, 5, 208, 112, 11, 5, 208, 111, 11, 5, 208, 109, 11, - 5, 208, 110, 11, 5, 249, 38, 11, 5, 249, 37, 11, 5, 249, 44, 11, 5, 249, - 39, 11, 5, 249, 41, 11, 5, 249, 40, 11, 5, 249, 43, 11, 5, 249, 42, 11, - 5, 249, 50, 11, 5, 249, 49, 11, 5, 249, 53, 11, 5, 249, 51, 11, 5, 249, - 29, 11, 5, 249, 31, 11, 5, 249, 30, 11, 5, 249, 34, 11, 5, 249, 33, 11, - 5, 249, 36, 11, 5, 249, 35, 11, 5, 249, 45, 11, 5, 249, 48, 11, 5, 249, - 46, 11, 5, 249, 25, 11, 5, 249, 24, 11, 5, 249, 32, 11, 5, 249, 28, 11, - 5, 249, 26, 11, 5, 249, 27, 11, 5, 249, 21, 11, 5, 249, 20, 11, 5, 249, - 23, 11, 5, 249, 22, 11, 5, 214, 185, 11, 5, 214, 184, 11, 5, 214, 190, - 11, 5, 214, 186, 11, 5, 214, 187, 11, 5, 214, 189, 11, 5, 214, 188, 11, - 5, 214, 193, 11, 5, 214, 192, 11, 5, 214, 195, 11, 5, 214, 194, 11, 5, - 214, 181, 11, 5, 214, 180, 11, 5, 214, 183, 11, 5, 214, 182, 11, 5, 214, - 174, 11, 5, 214, 173, 11, 5, 214, 178, 11, 5, 214, 177, 11, 5, 214, 175, - 11, 5, 214, 176, 11, 5, 214, 168, 11, 5, 214, 167, 11, 5, 214, 172, 11, - 5, 214, 171, 11, 5, 214, 169, 11, 5, 214, 170, 11, 5, 229, 67, 11, 5, - 229, 66, 11, 5, 229, 72, 11, 5, 229, 68, 11, 5, 229, 69, 11, 5, 229, 71, - 11, 5, 229, 70, 11, 5, 229, 75, 11, 5, 229, 74, 11, 5, 229, 77, 11, 5, - 229, 76, 11, 5, 229, 58, 11, 5, 229, 60, 11, 5, 229, 59, 11, 5, 229, 63, - 11, 5, 229, 62, 11, 5, 229, 65, 11, 5, 229, 64, 11, 5, 229, 54, 11, 5, - 229, 53, 11, 5, 229, 61, 11, 5, 229, 57, 11, 5, 229, 55, 11, 5, 229, 56, - 11, 5, 229, 48, 11, 5, 229, 52, 11, 5, 229, 51, 11, 5, 229, 49, 11, 5, - 229, 50, 11, 5, 216, 23, 11, 5, 216, 22, 11, 5, 216, 100, 11, 5, 216, 31, - 11, 5, 216, 63, 11, 5, 216, 81, 11, 5, 216, 79, 11, 5, 217, 30, 11, 5, - 217, 24, 11, 5, 174, 11, 5, 217, 71, 11, 5, 215, 115, 11, 5, 215, 114, - 11, 5, 215, 118, 11, 5, 215, 116, 11, 5, 215, 195, 11, 5, 215, 168, 11, - 5, 216, 12, 11, 5, 215, 202, 11, 5, 216, 152, 11, 5, 216, 232, 11, 5, - 215, 95, 11, 5, 215, 89, 11, 5, 215, 155, 11, 5, 215, 111, 11, 5, 215, - 104, 11, 5, 215, 109, 11, 5, 215, 65, 11, 5, 215, 64, 11, 5, 215, 70, 11, - 5, 215, 67, 11, 5, 232, 229, 11, 5, 232, 222, 11, 5, 233, 23, 11, 5, 232, - 245, 11, 5, 233, 72, 11, 5, 233, 63, 11, 5, 233, 109, 11, 5, 233, 77, 11, - 5, 232, 119, 11, 5, 232, 175, 11, 5, 232, 154, 11, 5, 232, 68, 11, 5, - 232, 67, 11, 5, 232, 86, 11, 5, 232, 73, 11, 5, 232, 71, 11, 5, 232, 72, - 11, 5, 232, 54, 11, 5, 232, 53, 11, 5, 232, 57, 11, 5, 232, 55, 11, 5, + 159, 47, 72, 181, 47, 72, 213, 221, 47, 72, 212, 180, 47, 72, 214, 123, + 47, 72, 213, 45, 47, 72, 140, 47, 72, 229, 160, 47, 72, 228, 161, 47, 72, + 229, 247, 47, 72, 229, 25, 47, 72, 174, 47, 72, 216, 102, 47, 72, 215, + 157, 47, 72, 216, 234, 47, 72, 216, 14, 47, 72, 170, 47, 72, 191, 225, + 47, 72, 192, 12, 47, 72, 165, 47, 72, 207, 2, 47, 72, 206, 69, 47, 72, + 207, 115, 47, 72, 206, 163, 47, 72, 193, 190, 47, 72, 193, 86, 47, 72, + 193, 125, 47, 72, 193, 48, 51, 234, 35, 214, 230, 207, 69, 51, 251, 66, + 51, 250, 223, 51, 251, 94, 51, 252, 165, 51, 223, 132, 51, 223, 99, 51, + 196, 80, 51, 234, 4, 51, 234, 187, 51, 211, 92, 51, 211, 85, 51, 222, + 102, 51, 222, 65, 51, 222, 60, 51, 231, 197, 51, 231, 207, 51, 231, 43, + 51, 231, 37, 51, 220, 146, 51, 231, 28, 51, 221, 133, 51, 221, 132, 51, + 221, 131, 51, 221, 130, 51, 230, 148, 51, 230, 147, 51, 220, 195, 51, + 220, 198, 51, 222, 11, 51, 221, 31, 51, 221, 40, 51, 205, 181, 51, 205, + 134, 51, 202, 142, 51, 204, 16, 51, 204, 15, 51, 238, 30, 51, 237, 83, + 51, 236, 143, 51, 198, 81, 51, 214, 223, 51, 213, 2, 51, 230, 77, 51, + 210, 216, 51, 210, 215, 51, 249, 152, 51, 209, 183, 51, 209, 145, 51, + 209, 146, 51, 248, 158, 51, 228, 156, 51, 228, 150, 51, 247, 223, 51, + 228, 134, 51, 229, 208, 51, 209, 243, 51, 210, 31, 51, 229, 189, 51, 210, + 27, 51, 210, 45, 51, 248, 254, 51, 209, 59, 51, 248, 86, 51, 229, 1, 51, + 209, 40, 51, 228, 248, 51, 228, 250, 51, 217, 112, 51, 217, 108, 51, 217, + 117, 51, 217, 46, 51, 217, 78, 51, 216, 58, 51, 216, 31, 51, 216, 30, 51, + 216, 205, 51, 216, 202, 51, 216, 206, 51, 192, 139, 51, 192, 137, 51, + 191, 210, 51, 206, 179, 51, 206, 183, 51, 206, 36, 51, 206, 29, 51, 207, + 58, 51, 207, 55, 51, 193, 141, 148, 199, 109, 16, 40, 228, 179, 191, 77, + 148, 199, 109, 16, 40, 228, 179, 107, 148, 199, 109, 16, 40, 228, 179, + 109, 148, 199, 109, 16, 40, 228, 179, 138, 148, 199, 109, 16, 40, 228, + 179, 134, 148, 199, 109, 16, 40, 228, 179, 150, 148, 199, 109, 16, 40, + 228, 179, 169, 148, 199, 109, 16, 40, 228, 179, 175, 148, 199, 109, 16, + 40, 228, 179, 171, 148, 199, 109, 16, 40, 228, 179, 178, 148, 199, 109, + 16, 40, 228, 179, 199, 95, 148, 199, 109, 16, 40, 228, 179, 234, 129, + 148, 199, 109, 16, 40, 228, 179, 197, 37, 148, 199, 109, 16, 40, 228, + 179, 198, 251, 148, 199, 109, 16, 40, 228, 179, 232, 124, 148, 199, 109, + 16, 40, 228, 179, 233, 21, 148, 199, 109, 16, 40, 228, 179, 202, 131, + 148, 199, 109, 16, 40, 228, 179, 203, 245, 148, 199, 109, 16, 40, 228, + 179, 234, 163, 148, 199, 109, 16, 40, 228, 179, 213, 173, 148, 199, 109, + 16, 40, 228, 179, 197, 32, 148, 199, 109, 16, 40, 228, 179, 197, 25, 148, + 199, 109, 16, 40, 228, 179, 197, 20, 148, 199, 109, 16, 40, 228, 179, + 197, 22, 148, 199, 109, 16, 40, 228, 179, 197, 27, 51, 228, 170, 51, 238, + 34, 51, 250, 165, 51, 164, 51, 211, 11, 51, 210, 70, 51, 236, 179, 51, + 236, 180, 201, 190, 51, 236, 180, 238, 191, 51, 223, 51, 51, 234, 35, + 214, 230, 229, 209, 51, 234, 35, 214, 230, 200, 66, 51, 234, 35, 214, + 230, 199, 212, 51, 234, 35, 214, 230, 216, 201, 51, 238, 255, 51, 210, + 223, 251, 137, 51, 181, 51, 215, 158, 65, 51, 174, 51, 155, 51, 222, 27, + 51, 217, 18, 51, 231, 185, 51, 247, 146, 51, 222, 26, 51, 209, 233, 51, + 214, 74, 51, 215, 158, 233, 177, 51, 215, 158, 232, 53, 51, 216, 143, 51, + 221, 219, 51, 228, 85, 51, 221, 170, 51, 216, 104, 51, 231, 57, 51, 198, + 195, 51, 215, 158, 172, 51, 216, 22, 51, 236, 189, 51, 221, 97, 51, 232, + 179, 51, 213, 83, 51, 215, 158, 218, 170, 51, 216, 19, 51, 242, 201, 51, + 221, 83, 51, 216, 20, 201, 190, 51, 242, 202, 201, 190, 51, 218, 171, + 201, 190, 51, 221, 84, 201, 190, 51, 216, 20, 238, 191, 51, 242, 202, + 238, 191, 51, 218, 171, 238, 191, 51, 221, 84, 238, 191, 51, 218, 171, + 139, 206, 9, 51, 218, 171, 139, 206, 10, 201, 190, 51, 168, 51, 221, 23, + 51, 215, 168, 51, 230, 231, 51, 207, 170, 51, 207, 171, 139, 206, 9, 51, + 207, 171, 139, 206, 10, 201, 190, 51, 208, 180, 51, 212, 221, 51, 215, + 158, 206, 9, 51, 215, 160, 51, 208, 126, 51, 212, 114, 51, 215, 158, 196, + 12, 51, 215, 89, 51, 220, 184, 51, 215, 90, 216, 205, 51, 208, 125, 51, + 212, 113, 51, 215, 158, 193, 224, 51, 215, 83, 51, 220, 182, 51, 215, 84, + 216, 205, 51, 222, 155, 211, 136, 51, 218, 171, 211, 136, 51, 251, 151, + 51, 248, 59, 51, 247, 68, 51, 247, 45, 51, 247, 196, 139, 221, 219, 51, + 242, 101, 51, 237, 202, 51, 230, 131, 51, 140, 51, 228, 171, 51, 223, + 164, 51, 221, 104, 51, 221, 84, 247, 112, 51, 220, 236, 51, 219, 48, 51, + 219, 47, 51, 219, 32, 51, 218, 186, 51, 217, 19, 202, 71, 51, 216, 57, + 51, 215, 235, 51, 209, 231, 51, 209, 78, 51, 208, 251, 51, 208, 249, 51, + 201, 181, 51, 200, 158, 51, 193, 127, 51, 196, 13, 139, 218, 170, 51, 42, + 139, 218, 170, 148, 199, 109, 16, 40, 237, 206, 107, 148, 199, 109, 16, + 40, 237, 206, 109, 148, 199, 109, 16, 40, 237, 206, 138, 148, 199, 109, + 16, 40, 237, 206, 134, 148, 199, 109, 16, 40, 237, 206, 150, 148, 199, + 109, 16, 40, 237, 206, 169, 148, 199, 109, 16, 40, 237, 206, 175, 148, + 199, 109, 16, 40, 237, 206, 171, 148, 199, 109, 16, 40, 237, 206, 178, + 148, 199, 109, 16, 40, 237, 206, 199, 95, 148, 199, 109, 16, 40, 237, + 206, 234, 129, 148, 199, 109, 16, 40, 237, 206, 197, 37, 148, 199, 109, + 16, 40, 237, 206, 198, 251, 148, 199, 109, 16, 40, 237, 206, 232, 124, + 148, 199, 109, 16, 40, 237, 206, 233, 21, 148, 199, 109, 16, 40, 237, + 206, 202, 131, 148, 199, 109, 16, 40, 237, 206, 203, 245, 148, 199, 109, + 16, 40, 237, 206, 234, 163, 148, 199, 109, 16, 40, 237, 206, 213, 173, + 148, 199, 109, 16, 40, 237, 206, 197, 32, 148, 199, 109, 16, 40, 237, + 206, 197, 25, 148, 199, 109, 16, 40, 237, 206, 197, 20, 148, 199, 109, + 16, 40, 237, 206, 197, 22, 148, 199, 109, 16, 40, 237, 206, 197, 27, 148, + 199, 109, 16, 40, 237, 206, 197, 28, 148, 199, 109, 16, 40, 237, 206, + 197, 23, 148, 199, 109, 16, 40, 237, 206, 197, 24, 148, 199, 109, 16, 40, + 237, 206, 197, 31, 148, 199, 109, 16, 40, 237, 206, 197, 26, 148, 199, + 109, 16, 40, 237, 206, 198, 249, 148, 199, 109, 16, 40, 237, 206, 198, + 247, 51, 231, 224, 229, 183, 40, 199, 34, 238, 233, 229, 221, 229, 183, + 40, 199, 34, 207, 102, 234, 209, 229, 183, 40, 237, 16, 250, 185, 199, + 34, 248, 249, 229, 183, 40, 191, 238, 232, 170, 229, 183, 40, 193, 171, + 229, 183, 40, 239, 55, 229, 183, 40, 199, 34, 250, 248, 229, 183, 40, + 229, 8, 198, 87, 229, 183, 40, 2, 199, 194, 229, 183, 40, 198, 1, 229, + 183, 40, 210, 62, 229, 183, 40, 201, 105, 229, 183, 40, 233, 45, 229, + 183, 40, 230, 208, 209, 23, 229, 183, 40, 216, 0, 229, 183, 40, 234, 76, + 229, 183, 40, 232, 171, 229, 183, 40, 193, 21, 211, 107, 199, 34, 237, + 143, 229, 183, 40, 251, 45, 229, 183, 40, 239, 33, 229, 183, 40, 248, + 147, 198, 215, 229, 183, 40, 230, 229, 229, 183, 40, 201, 209, 251, 65, + 229, 183, 40, 207, 23, 229, 183, 40, 223, 126, 229, 183, 40, 230, 208, + 199, 194, 229, 183, 40, 215, 182, 239, 2, 229, 183, 40, 230, 208, 208, + 226, 229, 183, 40, 199, 34, 252, 67, 193, 143, 229, 183, 40, 199, 34, + 242, 229, 232, 245, 229, 183, 40, 223, 140, 229, 183, 40, 235, 66, 229, + 183, 40, 207, 26, 229, 183, 40, 230, 208, 209, 0, 229, 183, 40, 208, 199, + 229, 183, 40, 237, 222, 79, 199, 34, 219, 134, 229, 183, 40, 199, 34, + 233, 83, 229, 183, 40, 211, 64, 229, 183, 40, 211, 169, 229, 183, 40, + 237, 113, 229, 183, 40, 237, 135, 229, 183, 40, 223, 155, 229, 183, 40, + 248, 43, 229, 183, 40, 242, 78, 119, 216, 208, 229, 183, 40, 231, 192, + 198, 87, 229, 183, 40, 208, 137, 196, 67, 229, 183, 40, 211, 63, 229, + 183, 40, 199, 34, 193, 109, 229, 183, 40, 207, 14, 229, 183, 40, 199, 34, + 247, 74, 229, 183, 40, 199, 34, 250, 244, 198, 209, 229, 183, 40, 199, + 34, 222, 12, 201, 71, 215, 186, 229, 183, 40, 237, 78, 229, 183, 40, 199, + 34, 217, 49, 217, 113, 229, 183, 40, 252, 68, 229, 183, 40, 199, 34, 193, + 161, 229, 183, 40, 199, 34, 231, 147, 193, 66, 229, 183, 40, 199, 34, + 222, 186, 220, 45, 229, 183, 40, 236, 221, 229, 183, 40, 219, 121, 229, + 183, 40, 223, 129, 197, 176, 229, 183, 40, 2, 208, 226, 229, 183, 40, + 252, 0, 242, 68, 229, 183, 40, 248, 252, 242, 68, 11, 5, 223, 55, 11, 5, + 223, 47, 11, 5, 68, 11, 5, 223, 82, 11, 5, 223, 226, 11, 5, 223, 209, 11, + 5, 223, 228, 11, 5, 223, 227, 11, 5, 250, 184, 11, 5, 250, 135, 11, 5, + 65, 11, 5, 251, 67, 11, 5, 196, 78, 11, 5, 196, 82, 11, 5, 196, 79, 11, + 5, 211, 32, 11, 5, 210, 249, 11, 5, 74, 11, 5, 211, 80, 11, 5, 233, 223, + 11, 5, 71, 11, 5, 193, 0, 11, 5, 248, 150, 11, 5, 248, 145, 11, 5, 248, + 190, 11, 5, 248, 163, 11, 5, 248, 179, 11, 5, 248, 178, 11, 5, 248, 181, + 11, 5, 248, 180, 11, 5, 249, 66, 11, 5, 249, 58, 11, 5, 249, 155, 11, 5, + 249, 91, 11, 5, 247, 236, 11, 5, 247, 240, 11, 5, 247, 237, 11, 5, 248, + 83, 11, 5, 248, 64, 11, 5, 248, 113, 11, 5, 248, 91, 11, 5, 248, 208, 11, + 5, 249, 19, 11, 5, 248, 221, 11, 5, 247, 219, 11, 5, 247, 213, 11, 5, + 248, 12, 11, 5, 247, 234, 11, 5, 247, 227, 11, 5, 247, 232, 11, 5, 247, + 201, 11, 5, 247, 199, 11, 5, 247, 206, 11, 5, 247, 204, 11, 5, 247, 202, + 11, 5, 247, 203, 11, 5, 209, 119, 11, 5, 209, 115, 11, 5, 209, 187, 11, + 5, 209, 131, 11, 5, 209, 151, 11, 5, 209, 178, 11, 5, 209, 174, 11, 5, + 210, 91, 11, 5, 210, 75, 11, 5, 168, 11, 5, 210, 139, 11, 5, 208, 147, + 11, 5, 208, 149, 11, 5, 208, 148, 11, 5, 209, 16, 11, 5, 208, 254, 11, 5, + 209, 75, 11, 5, 209, 35, 11, 5, 208, 133, 11, 5, 208, 128, 11, 5, 208, + 167, 11, 5, 208, 146, 11, 5, 208, 138, 11, 5, 208, 144, 11, 5, 208, 110, + 11, 5, 208, 109, 11, 5, 208, 114, 11, 5, 208, 113, 11, 5, 208, 111, 11, + 5, 208, 112, 11, 5, 249, 40, 11, 5, 249, 39, 11, 5, 249, 46, 11, 5, 249, + 41, 11, 5, 249, 43, 11, 5, 249, 42, 11, 5, 249, 45, 11, 5, 249, 44, 11, + 5, 249, 52, 11, 5, 249, 51, 11, 5, 249, 55, 11, 5, 249, 53, 11, 5, 249, + 31, 11, 5, 249, 33, 11, 5, 249, 32, 11, 5, 249, 36, 11, 5, 249, 35, 11, + 5, 249, 38, 11, 5, 249, 37, 11, 5, 249, 47, 11, 5, 249, 50, 11, 5, 249, + 48, 11, 5, 249, 27, 11, 5, 249, 26, 11, 5, 249, 34, 11, 5, 249, 30, 11, + 5, 249, 28, 11, 5, 249, 29, 11, 5, 249, 23, 11, 5, 249, 22, 11, 5, 249, + 25, 11, 5, 249, 24, 11, 5, 214, 187, 11, 5, 214, 186, 11, 5, 214, 192, + 11, 5, 214, 188, 11, 5, 214, 189, 11, 5, 214, 191, 11, 5, 214, 190, 11, + 5, 214, 195, 11, 5, 214, 194, 11, 5, 214, 197, 11, 5, 214, 196, 11, 5, + 214, 183, 11, 5, 214, 182, 11, 5, 214, 185, 11, 5, 214, 184, 11, 5, 214, + 176, 11, 5, 214, 175, 11, 5, 214, 180, 11, 5, 214, 179, 11, 5, 214, 177, + 11, 5, 214, 178, 11, 5, 214, 170, 11, 5, 214, 169, 11, 5, 214, 174, 11, + 5, 214, 173, 11, 5, 214, 171, 11, 5, 214, 172, 11, 5, 229, 69, 11, 5, + 229, 68, 11, 5, 229, 74, 11, 5, 229, 70, 11, 5, 229, 71, 11, 5, 229, 73, + 11, 5, 229, 72, 11, 5, 229, 77, 11, 5, 229, 76, 11, 5, 229, 79, 11, 5, + 229, 78, 11, 5, 229, 60, 11, 5, 229, 62, 11, 5, 229, 61, 11, 5, 229, 65, + 11, 5, 229, 64, 11, 5, 229, 67, 11, 5, 229, 66, 11, 5, 229, 56, 11, 5, + 229, 55, 11, 5, 229, 63, 11, 5, 229, 59, 11, 5, 229, 57, 11, 5, 229, 58, + 11, 5, 229, 50, 11, 5, 229, 54, 11, 5, 229, 53, 11, 5, 229, 51, 11, 5, + 229, 52, 11, 5, 216, 25, 11, 5, 216, 24, 11, 5, 216, 102, 11, 5, 216, 33, + 11, 5, 216, 65, 11, 5, 216, 83, 11, 5, 216, 81, 11, 5, 217, 32, 11, 5, + 217, 26, 11, 5, 174, 11, 5, 217, 73, 11, 5, 215, 117, 11, 5, 215, 116, + 11, 5, 215, 120, 11, 5, 215, 118, 11, 5, 215, 197, 11, 5, 215, 170, 11, + 5, 216, 14, 11, 5, 215, 204, 11, 5, 216, 154, 11, 5, 216, 234, 11, 5, + 215, 97, 11, 5, 215, 91, 11, 5, 215, 157, 11, 5, 215, 113, 11, 5, 215, + 106, 11, 5, 215, 111, 11, 5, 215, 67, 11, 5, 215, 66, 11, 5, 215, 72, 11, + 5, 215, 69, 11, 5, 232, 231, 11, 5, 232, 224, 11, 5, 233, 25, 11, 5, 232, + 247, 11, 5, 233, 74, 11, 5, 233, 65, 11, 5, 233, 111, 11, 5, 233, 79, 11, + 5, 232, 121, 11, 5, 232, 177, 11, 5, 232, 156, 11, 5, 232, 70, 11, 5, + 232, 69, 11, 5, 232, 88, 11, 5, 232, 75, 11, 5, 232, 73, 11, 5, 232, 74, + 11, 5, 232, 56, 11, 5, 232, 55, 11, 5, 232, 59, 11, 5, 232, 57, 11, 5, 195, 32, 11, 5, 195, 26, 11, 5, 195, 69, 11, 5, 195, 41, 11, 5, 195, 58, 11, 5, 195, 53, 11, 5, 195, 61, 11, 5, 195, 60, 11, 5, 195, 162, 11, 5, 195, 157, 11, 5, 195, 188, 11, 5, 195, 175, 11, 5, 195, 4, 11, 5, 195, 0, 11, 5, 195, 24, 11, 5, 195, 6, 11, 5, 195, 73, 11, 5, 195, 141, 11, 5, 193, 242, 11, 5, 193, 240, 11, 5, 193, 249, 11, 5, 193, 245, 11, 5, 193, 243, 11, 5, 193, 244, 11, 5, 193, 229, 11, 5, 193, 228, 11, 5, 193, 235, - 11, 5, 193, 234, 11, 5, 193, 232, 11, 5, 193, 233, 11, 5, 236, 212, 11, - 5, 236, 197, 11, 5, 237, 44, 11, 5, 236, 240, 11, 5, 237, 19, 11, 5, 237, - 24, 11, 5, 237, 23, 11, 5, 237, 211, 11, 5, 237, 205, 11, 5, 238, 32, 11, - 5, 237, 231, 11, 5, 235, 69, 11, 5, 235, 70, 11, 5, 236, 140, 11, 5, 235, - 117, 11, 5, 236, 174, 11, 5, 236, 143, 11, 5, 237, 74, 11, 5, 237, 146, - 11, 5, 237, 96, 11, 5, 235, 60, 11, 5, 235, 58, 11, 5, 235, 89, 11, 5, - 235, 68, 11, 5, 235, 63, 11, 5, 235, 66, 11, 5, 198, 125, 11, 5, 198, + 11, 5, 193, 234, 11, 5, 193, 232, 11, 5, 193, 233, 11, 5, 236, 214, 11, + 5, 236, 199, 11, 5, 237, 46, 11, 5, 236, 242, 11, 5, 237, 21, 11, 5, 237, + 26, 11, 5, 237, 25, 11, 5, 237, 213, 11, 5, 237, 207, 11, 5, 238, 34, 11, + 5, 237, 233, 11, 5, 235, 71, 11, 5, 235, 72, 11, 5, 236, 142, 11, 5, 235, + 119, 11, 5, 236, 176, 11, 5, 236, 145, 11, 5, 237, 76, 11, 5, 237, 148, + 11, 5, 237, 98, 11, 5, 235, 62, 11, 5, 235, 60, 11, 5, 235, 91, 11, 5, + 235, 70, 11, 5, 235, 65, 11, 5, 235, 68, 11, 5, 198, 125, 11, 5, 198, 117, 11, 5, 198, 193, 11, 5, 198, 135, 11, 5, 198, 176, 11, 5, 198, 178, 11, 5, 198, 177, 11, 5, 199, 171, 11, 5, 199, 156, 11, 5, 190, 190, 11, 5, 199, 183, 11, 5, 197, 69, 11, 5, 197, 68, 11, 5, 197, 71, 11, 5, 197, 70, 11, 5, 198, 40, 11, 5, 198, 29, 11, 5, 159, 11, 5, 198, 53, 11, 5, 199, 55, 11, 5, 199, 145, 11, 5, 199, 82, 11, 5, 197, 52, 11, 5, 197, 47, 11, 5, 197, 94, 11, 5, 197, 67, 11, 5, 197, 53, 11, 5, 197, 64, 11, 5, - 237, 163, 11, 5, 237, 162, 11, 5, 237, 168, 11, 5, 237, 164, 11, 5, 237, - 165, 11, 5, 237, 167, 11, 5, 237, 166, 11, 5, 237, 184, 11, 5, 237, 183, - 11, 5, 237, 191, 11, 5, 237, 185, 11, 5, 237, 153, 11, 5, 237, 155, 11, - 5, 237, 154, 11, 5, 237, 158, 11, 5, 237, 157, 11, 5, 237, 161, 11, 5, - 237, 159, 11, 5, 237, 176, 11, 5, 237, 179, 11, 5, 237, 177, 11, 5, 237, - 149, 11, 5, 237, 148, 11, 5, 237, 156, 11, 5, 237, 152, 11, 5, 237, 150, - 11, 5, 237, 151, 11, 5, 214, 140, 11, 5, 214, 139, 11, 5, 214, 147, 11, - 5, 214, 142, 11, 5, 214, 143, 11, 5, 214, 144, 11, 5, 214, 156, 11, 5, - 214, 155, 11, 5, 214, 162, 11, 5, 214, 157, 11, 5, 214, 132, 11, 5, 214, - 131, 11, 5, 214, 138, 11, 5, 214, 133, 11, 5, 214, 148, 11, 5, 214, 154, - 11, 5, 214, 152, 11, 5, 214, 124, 11, 5, 214, 123, 11, 5, 214, 129, 11, - 5, 214, 127, 11, 5, 214, 125, 11, 5, 214, 126, 11, 5, 229, 33, 11, 5, - 229, 32, 11, 5, 229, 39, 11, 5, 229, 34, 11, 5, 229, 36, 11, 5, 229, 35, - 11, 5, 229, 38, 11, 5, 229, 37, 11, 5, 229, 45, 11, 5, 229, 43, 11, 5, - 229, 47, 11, 5, 229, 46, 11, 5, 229, 26, 11, 5, 229, 27, 11, 5, 229, 30, - 11, 5, 229, 29, 11, 5, 229, 31, 11, 5, 229, 40, 11, 5, 229, 42, 11, 5, - 229, 41, 11, 5, 229, 25, 11, 5, 213, 162, 11, 5, 213, 160, 11, 5, 213, - 219, 11, 5, 213, 165, 11, 5, 213, 193, 11, 5, 213, 207, 11, 5, 213, 206, - 11, 5, 214, 200, 11, 5, 180, 11, 5, 214, 218, 11, 5, 212, 122, 11, 5, - 212, 124, 11, 5, 212, 123, 11, 5, 213, 11, 11, 5, 212, 251, 11, 5, 213, - 43, 11, 5, 213, 22, 11, 5, 214, 74, 11, 5, 214, 121, 11, 5, 214, 97, 11, - 5, 212, 117, 11, 5, 212, 113, 11, 5, 212, 178, 11, 5, 212, 121, 11, 5, - 212, 119, 11, 5, 212, 120, 11, 5, 229, 98, 11, 5, 229, 97, 11, 5, 229, - 103, 11, 5, 229, 99, 11, 5, 229, 100, 11, 5, 229, 102, 11, 5, 229, 101, - 11, 5, 229, 109, 11, 5, 229, 107, 11, 5, 229, 111, 11, 5, 229, 110, 11, - 5, 229, 90, 11, 5, 229, 92, 11, 5, 229, 91, 11, 5, 229, 94, 11, 5, 229, - 96, 11, 5, 229, 95, 11, 5, 229, 104, 11, 5, 229, 106, 11, 5, 229, 105, - 11, 5, 229, 86, 11, 5, 229, 85, 11, 5, 229, 93, 11, 5, 229, 89, 11, 5, - 229, 87, 11, 5, 229, 88, 11, 5, 229, 80, 11, 5, 229, 79, 11, 5, 229, 84, - 11, 5, 229, 83, 11, 5, 229, 81, 11, 5, 229, 82, 11, 5, 219, 87, 11, 5, - 219, 79, 11, 5, 219, 146, 11, 5, 219, 98, 11, 5, 219, 137, 11, 5, 219, - 136, 11, 5, 219, 140, 11, 5, 219, 138, 11, 5, 220, 5, 11, 5, 219, 249, - 11, 5, 173, 11, 5, 220, 16, 11, 5, 218, 201, 11, 5, 218, 200, 11, 5, 218, - 203, 11, 5, 218, 202, 11, 5, 218, 249, 11, 5, 218, 234, 11, 5, 219, 43, - 11, 5, 219, 1, 11, 5, 219, 164, 11, 5, 219, 238, 11, 5, 219, 184, 11, 5, - 218, 195, 11, 5, 218, 193, 11, 5, 218, 225, 11, 5, 218, 199, 11, 5, 218, - 197, 11, 5, 218, 198, 11, 5, 218, 173, 11, 5, 218, 172, 11, 5, 218, 183, - 11, 5, 218, 176, 11, 5, 218, 174, 11, 5, 218, 175, 11, 5, 231, 22, 11, 5, - 231, 21, 11, 5, 231, 53, 11, 5, 231, 34, 11, 5, 231, 45, 11, 5, 231, 44, - 11, 5, 231, 47, 11, 5, 231, 46, 11, 5, 231, 192, 11, 5, 231, 187, 11, 5, - 231, 240, 11, 5, 231, 203, 11, 5, 230, 152, 11, 5, 230, 151, 11, 5, 230, - 154, 11, 5, 230, 153, 11, 5, 230, 232, 11, 5, 230, 230, 11, 5, 231, 3, - 11, 5, 230, 242, 11, 5, 231, 131, 11, 5, 231, 129, 11, 5, 231, 165, 11, - 5, 231, 142, 11, 5, 230, 140, 11, 5, 230, 139, 11, 5, 230, 179, 11, 5, - 230, 150, 11, 5, 230, 141, 11, 5, 230, 149, 11, 5, 221, 120, 11, 5, 221, - 115, 11, 5, 221, 166, 11, 5, 221, 134, 11, 5, 221, 147, 11, 5, 221, 151, - 11, 5, 221, 149, 11, 5, 222, 49, 11, 5, 222, 30, 11, 5, 155, 11, 5, 222, - 78, 11, 5, 220, 202, 11, 5, 220, 207, 11, 5, 220, 204, 11, 5, 221, 28, - 11, 5, 221, 23, 11, 5, 221, 67, 11, 5, 221, 36, 11, 5, 221, 241, 11, 5, - 221, 224, 11, 5, 222, 22, 11, 5, 221, 245, 11, 5, 220, 188, 11, 5, 220, - 184, 11, 5, 220, 232, 11, 5, 220, 201, 11, 5, 220, 192, 11, 5, 220, 197, - 11, 5, 231, 113, 11, 5, 231, 112, 11, 5, 231, 117, 11, 5, 231, 114, 11, - 5, 231, 116, 11, 5, 231, 115, 11, 5, 231, 124, 11, 5, 231, 123, 11, 5, - 231, 127, 11, 5, 231, 125, 11, 5, 231, 104, 11, 5, 231, 103, 11, 5, 231, - 106, 11, 5, 231, 105, 11, 5, 231, 109, 11, 5, 231, 108, 11, 5, 231, 111, - 11, 5, 231, 110, 11, 5, 231, 119, 11, 5, 231, 118, 11, 5, 231, 122, 11, - 5, 231, 120, 11, 5, 231, 99, 11, 5, 231, 98, 11, 5, 231, 107, 11, 5, 231, - 102, 11, 5, 231, 100, 11, 5, 231, 101, 11, 5, 216, 119, 11, 5, 216, 120, - 11, 5, 216, 138, 11, 5, 216, 137, 11, 5, 216, 140, 11, 5, 216, 139, 11, - 5, 216, 110, 11, 5, 216, 112, 11, 5, 216, 111, 11, 5, 216, 115, 11, 5, - 216, 114, 11, 5, 216, 117, 11, 5, 216, 116, 11, 5, 216, 121, 11, 5, 216, - 123, 11, 5, 216, 122, 11, 5, 216, 106, 11, 5, 216, 105, 11, 5, 216, 113, - 11, 5, 216, 109, 11, 5, 216, 107, 11, 5, 216, 108, 11, 5, 228, 104, 11, - 5, 228, 103, 11, 5, 228, 110, 11, 5, 228, 105, 11, 5, 228, 107, 11, 5, - 228, 106, 11, 5, 228, 109, 11, 5, 228, 108, 11, 5, 228, 115, 11, 5, 228, - 114, 11, 5, 228, 117, 11, 5, 228, 116, 11, 5, 228, 96, 11, 5, 228, 95, - 11, 5, 228, 98, 11, 5, 228, 97, 11, 5, 228, 100, 11, 5, 228, 99, 11, 5, - 228, 102, 11, 5, 228, 101, 11, 5, 228, 111, 11, 5, 228, 113, 11, 5, 228, - 112, 11, 5, 214, 13, 11, 5, 214, 15, 11, 5, 214, 14, 11, 5, 214, 58, 11, - 5, 214, 56, 11, 5, 214, 68, 11, 5, 214, 61, 11, 5, 213, 230, 11, 5, 213, - 229, 11, 5, 213, 231, 11, 5, 213, 241, 11, 5, 213, 238, 11, 5, 213, 249, - 11, 5, 213, 243, 11, 5, 214, 49, 11, 5, 214, 55, 11, 5, 214, 51, 11, 5, - 229, 117, 11, 5, 229, 136, 11, 5, 229, 145, 11, 5, 230, 9, 11, 5, 229, - 253, 11, 5, 140, 11, 5, 230, 21, 11, 5, 228, 134, 11, 5, 228, 133, 11, 5, - 228, 136, 11, 5, 228, 135, 11, 5, 228, 180, 11, 5, 228, 171, 11, 5, 229, - 23, 11, 5, 228, 244, 11, 5, 229, 183, 11, 5, 229, 245, 11, 5, 229, 195, - 11, 5, 193, 146, 11, 5, 193, 131, 11, 5, 193, 190, 11, 5, 193, 158, 11, - 5, 192, 245, 11, 5, 192, 247, 11, 5, 192, 246, 11, 5, 193, 13, 11, 5, - 193, 48, 11, 5, 193, 24, 11, 5, 193, 99, 11, 5, 193, 125, 11, 5, 193, - 106, 11, 5, 191, 15, 11, 5, 191, 14, 11, 5, 191, 30, 11, 5, 191, 18, 11, - 5, 191, 23, 11, 5, 191, 25, 11, 5, 191, 24, 11, 5, 191, 96, 11, 5, 191, - 93, 11, 5, 191, 123, 11, 5, 191, 104, 11, 5, 190, 244, 11, 5, 190, 246, - 11, 5, 190, 245, 11, 5, 191, 2, 11, 5, 191, 1, 11, 5, 191, 7, 11, 5, 191, - 3, 11, 5, 191, 73, 11, 5, 191, 87, 11, 5, 191, 79, 11, 5, 190, 240, 11, - 5, 190, 239, 11, 5, 190, 251, 11, 5, 190, 243, 11, 5, 190, 241, 11, 5, - 190, 242, 11, 5, 190, 226, 11, 5, 190, 225, 11, 5, 190, 231, 11, 5, 190, - 229, 11, 5, 190, 227, 11, 5, 190, 228, 11, 5, 242, 255, 11, 5, 242, 248, - 11, 5, 243, 29, 11, 5, 243, 12, 11, 5, 243, 26, 11, 5, 243, 20, 11, 5, - 243, 28, 11, 5, 243, 27, 11, 5, 247, 78, 11, 5, 247, 69, 11, 5, 247, 160, - 11, 5, 247, 111, 11, 5, 238, 183, 11, 5, 238, 185, 11, 5, 238, 184, 11, - 5, 238, 249, 11, 5, 238, 237, 11, 5, 242, 99, 11, 5, 239, 13, 11, 5, 247, - 5, 11, 5, 247, 42, 11, 5, 247, 11, 11, 5, 238, 154, 11, 5, 238, 152, 11, - 5, 238, 195, 11, 5, 238, 181, 11, 5, 238, 160, 11, 5, 238, 176, 11, 5, - 238, 130, 11, 5, 238, 129, 11, 5, 238, 143, 11, 5, 238, 137, 11, 5, 238, - 131, 11, 5, 238, 133, 11, 5, 190, 209, 11, 5, 190, 208, 11, 5, 190, 215, - 11, 5, 190, 210, 11, 5, 190, 212, 11, 5, 190, 211, 11, 5, 190, 214, 11, - 5, 190, 213, 11, 5, 190, 221, 11, 5, 190, 220, 11, 5, 190, 224, 11, 5, - 190, 222, 11, 5, 190, 205, 11, 5, 190, 207, 11, 5, 190, 206, 11, 5, 190, - 216, 11, 5, 190, 219, 11, 5, 190, 217, 11, 5, 190, 198, 11, 5, 190, 202, - 11, 5, 190, 201, 11, 5, 190, 199, 11, 5, 190, 200, 11, 5, 190, 192, 11, - 5, 190, 191, 11, 5, 190, 197, 11, 5, 190, 195, 11, 5, 190, 193, 11, 5, - 190, 194, 11, 5, 212, 33, 11, 5, 212, 32, 11, 5, 212, 38, 11, 5, 212, 34, - 11, 5, 212, 35, 11, 5, 212, 37, 11, 5, 212, 36, 11, 5, 212, 43, 11, 5, - 212, 42, 11, 5, 212, 46, 11, 5, 212, 45, 11, 5, 212, 26, 11, 5, 212, 27, - 11, 5, 212, 30, 11, 5, 212, 31, 11, 5, 212, 39, 11, 5, 212, 41, 11, 5, - 212, 21, 11, 5, 212, 29, 11, 5, 212, 25, 11, 5, 212, 22, 11, 5, 212, 23, - 11, 5, 212, 16, 11, 5, 212, 15, 11, 5, 212, 20, 11, 5, 212, 19, 11, 5, - 212, 17, 11, 5, 212, 18, 11, 5, 202, 138, 11, 5, 169, 11, 5, 202, 222, - 11, 5, 202, 142, 11, 5, 202, 202, 11, 5, 202, 205, 11, 5, 202, 203, 11, - 5, 205, 122, 11, 5, 205, 106, 11, 5, 188, 11, 5, 205, 130, 11, 5, 200, - 188, 11, 5, 200, 190, 11, 5, 200, 189, 11, 5, 202, 8, 11, 5, 201, 253, - 11, 5, 202, 46, 11, 5, 202, 14, 11, 5, 203, 238, 11, 5, 205, 68, 11, 5, - 204, 13, 11, 5, 200, 163, 11, 5, 200, 159, 11, 5, 201, 4, 11, 5, 200, + 237, 165, 11, 5, 237, 164, 11, 5, 237, 170, 11, 5, 237, 166, 11, 5, 237, + 167, 11, 5, 237, 169, 11, 5, 237, 168, 11, 5, 237, 186, 11, 5, 237, 185, + 11, 5, 237, 193, 11, 5, 237, 187, 11, 5, 237, 155, 11, 5, 237, 157, 11, + 5, 237, 156, 11, 5, 237, 160, 11, 5, 237, 159, 11, 5, 237, 163, 11, 5, + 237, 161, 11, 5, 237, 178, 11, 5, 237, 181, 11, 5, 237, 179, 11, 5, 237, + 151, 11, 5, 237, 150, 11, 5, 237, 158, 11, 5, 237, 154, 11, 5, 237, 152, + 11, 5, 237, 153, 11, 5, 214, 142, 11, 5, 214, 141, 11, 5, 214, 149, 11, + 5, 214, 144, 11, 5, 214, 145, 11, 5, 214, 146, 11, 5, 214, 158, 11, 5, + 214, 157, 11, 5, 214, 164, 11, 5, 214, 159, 11, 5, 214, 134, 11, 5, 214, + 133, 11, 5, 214, 140, 11, 5, 214, 135, 11, 5, 214, 150, 11, 5, 214, 156, + 11, 5, 214, 154, 11, 5, 214, 126, 11, 5, 214, 125, 11, 5, 214, 131, 11, + 5, 214, 129, 11, 5, 214, 127, 11, 5, 214, 128, 11, 5, 229, 35, 11, 5, + 229, 34, 11, 5, 229, 41, 11, 5, 229, 36, 11, 5, 229, 38, 11, 5, 229, 37, + 11, 5, 229, 40, 11, 5, 229, 39, 11, 5, 229, 47, 11, 5, 229, 45, 11, 5, + 229, 49, 11, 5, 229, 48, 11, 5, 229, 28, 11, 5, 229, 29, 11, 5, 229, 32, + 11, 5, 229, 31, 11, 5, 229, 33, 11, 5, 229, 42, 11, 5, 229, 44, 11, 5, + 229, 43, 11, 5, 229, 27, 11, 5, 213, 164, 11, 5, 213, 162, 11, 5, 213, + 221, 11, 5, 213, 167, 11, 5, 213, 195, 11, 5, 213, 209, 11, 5, 213, 208, + 11, 5, 214, 202, 11, 5, 181, 11, 5, 214, 220, 11, 5, 212, 124, 11, 5, + 212, 126, 11, 5, 212, 125, 11, 5, 213, 13, 11, 5, 212, 253, 11, 5, 213, + 45, 11, 5, 213, 24, 11, 5, 214, 76, 11, 5, 214, 123, 11, 5, 214, 99, 11, + 5, 212, 119, 11, 5, 212, 115, 11, 5, 212, 180, 11, 5, 212, 123, 11, 5, + 212, 121, 11, 5, 212, 122, 11, 5, 229, 100, 11, 5, 229, 99, 11, 5, 229, + 105, 11, 5, 229, 101, 11, 5, 229, 102, 11, 5, 229, 104, 11, 5, 229, 103, + 11, 5, 229, 111, 11, 5, 229, 109, 11, 5, 229, 113, 11, 5, 229, 112, 11, + 5, 229, 92, 11, 5, 229, 94, 11, 5, 229, 93, 11, 5, 229, 96, 11, 5, 229, + 98, 11, 5, 229, 97, 11, 5, 229, 106, 11, 5, 229, 108, 11, 5, 229, 107, + 11, 5, 229, 88, 11, 5, 229, 87, 11, 5, 229, 95, 11, 5, 229, 91, 11, 5, + 229, 89, 11, 5, 229, 90, 11, 5, 229, 82, 11, 5, 229, 81, 11, 5, 229, 86, + 11, 5, 229, 85, 11, 5, 229, 83, 11, 5, 229, 84, 11, 5, 219, 89, 11, 5, + 219, 81, 11, 5, 219, 148, 11, 5, 219, 100, 11, 5, 219, 139, 11, 5, 219, + 138, 11, 5, 219, 142, 11, 5, 219, 140, 11, 5, 220, 7, 11, 5, 219, 251, + 11, 5, 173, 11, 5, 220, 18, 11, 5, 218, 203, 11, 5, 218, 202, 11, 5, 218, + 205, 11, 5, 218, 204, 11, 5, 218, 251, 11, 5, 218, 236, 11, 5, 219, 45, + 11, 5, 219, 3, 11, 5, 219, 166, 11, 5, 219, 240, 11, 5, 219, 186, 11, 5, + 218, 197, 11, 5, 218, 195, 11, 5, 218, 227, 11, 5, 218, 201, 11, 5, 218, + 199, 11, 5, 218, 200, 11, 5, 218, 175, 11, 5, 218, 174, 11, 5, 218, 185, + 11, 5, 218, 178, 11, 5, 218, 176, 11, 5, 218, 177, 11, 5, 231, 24, 11, 5, + 231, 23, 11, 5, 231, 55, 11, 5, 231, 36, 11, 5, 231, 47, 11, 5, 231, 46, + 11, 5, 231, 49, 11, 5, 231, 48, 11, 5, 231, 194, 11, 5, 231, 189, 11, 5, + 231, 242, 11, 5, 231, 205, 11, 5, 230, 154, 11, 5, 230, 153, 11, 5, 230, + 156, 11, 5, 230, 155, 11, 5, 230, 234, 11, 5, 230, 232, 11, 5, 231, 5, + 11, 5, 230, 244, 11, 5, 231, 133, 11, 5, 231, 131, 11, 5, 231, 167, 11, + 5, 231, 144, 11, 5, 230, 142, 11, 5, 230, 141, 11, 5, 230, 181, 11, 5, + 230, 152, 11, 5, 230, 143, 11, 5, 230, 151, 11, 5, 221, 122, 11, 5, 221, + 117, 11, 5, 221, 168, 11, 5, 221, 136, 11, 5, 221, 149, 11, 5, 221, 153, + 11, 5, 221, 151, 11, 5, 222, 51, 11, 5, 222, 32, 11, 5, 155, 11, 5, 222, + 80, 11, 5, 220, 204, 11, 5, 220, 209, 11, 5, 220, 206, 11, 5, 221, 30, + 11, 5, 221, 25, 11, 5, 221, 69, 11, 5, 221, 38, 11, 5, 221, 243, 11, 5, + 221, 226, 11, 5, 222, 24, 11, 5, 221, 247, 11, 5, 220, 190, 11, 5, 220, + 186, 11, 5, 220, 234, 11, 5, 220, 203, 11, 5, 220, 194, 11, 5, 220, 199, + 11, 5, 231, 115, 11, 5, 231, 114, 11, 5, 231, 119, 11, 5, 231, 116, 11, + 5, 231, 118, 11, 5, 231, 117, 11, 5, 231, 126, 11, 5, 231, 125, 11, 5, + 231, 129, 11, 5, 231, 127, 11, 5, 231, 106, 11, 5, 231, 105, 11, 5, 231, + 108, 11, 5, 231, 107, 11, 5, 231, 111, 11, 5, 231, 110, 11, 5, 231, 113, + 11, 5, 231, 112, 11, 5, 231, 121, 11, 5, 231, 120, 11, 5, 231, 124, 11, + 5, 231, 122, 11, 5, 231, 101, 11, 5, 231, 100, 11, 5, 231, 109, 11, 5, + 231, 104, 11, 5, 231, 102, 11, 5, 231, 103, 11, 5, 216, 121, 11, 5, 216, + 122, 11, 5, 216, 140, 11, 5, 216, 139, 11, 5, 216, 142, 11, 5, 216, 141, + 11, 5, 216, 112, 11, 5, 216, 114, 11, 5, 216, 113, 11, 5, 216, 117, 11, + 5, 216, 116, 11, 5, 216, 119, 11, 5, 216, 118, 11, 5, 216, 123, 11, 5, + 216, 125, 11, 5, 216, 124, 11, 5, 216, 108, 11, 5, 216, 107, 11, 5, 216, + 115, 11, 5, 216, 111, 11, 5, 216, 109, 11, 5, 216, 110, 11, 5, 228, 106, + 11, 5, 228, 105, 11, 5, 228, 112, 11, 5, 228, 107, 11, 5, 228, 109, 11, + 5, 228, 108, 11, 5, 228, 111, 11, 5, 228, 110, 11, 5, 228, 117, 11, 5, + 228, 116, 11, 5, 228, 119, 11, 5, 228, 118, 11, 5, 228, 98, 11, 5, 228, + 97, 11, 5, 228, 100, 11, 5, 228, 99, 11, 5, 228, 102, 11, 5, 228, 101, + 11, 5, 228, 104, 11, 5, 228, 103, 11, 5, 228, 113, 11, 5, 228, 115, 11, + 5, 228, 114, 11, 5, 214, 15, 11, 5, 214, 17, 11, 5, 214, 16, 11, 5, 214, + 60, 11, 5, 214, 58, 11, 5, 214, 70, 11, 5, 214, 63, 11, 5, 213, 232, 11, + 5, 213, 231, 11, 5, 213, 233, 11, 5, 213, 243, 11, 5, 213, 240, 11, 5, + 213, 251, 11, 5, 213, 245, 11, 5, 214, 51, 11, 5, 214, 57, 11, 5, 214, + 53, 11, 5, 229, 119, 11, 5, 229, 138, 11, 5, 229, 147, 11, 5, 230, 11, + 11, 5, 229, 255, 11, 5, 140, 11, 5, 230, 23, 11, 5, 228, 136, 11, 5, 228, + 135, 11, 5, 228, 138, 11, 5, 228, 137, 11, 5, 228, 182, 11, 5, 228, 173, + 11, 5, 229, 25, 11, 5, 228, 246, 11, 5, 229, 185, 11, 5, 229, 247, 11, 5, + 229, 197, 11, 5, 193, 146, 11, 5, 193, 131, 11, 5, 193, 190, 11, 5, 193, + 158, 11, 5, 192, 245, 11, 5, 192, 247, 11, 5, 192, 246, 11, 5, 193, 13, + 11, 5, 193, 48, 11, 5, 193, 24, 11, 5, 193, 99, 11, 5, 193, 125, 11, 5, + 193, 106, 11, 5, 191, 15, 11, 5, 191, 14, 11, 5, 191, 30, 11, 5, 191, 18, + 11, 5, 191, 23, 11, 5, 191, 25, 11, 5, 191, 24, 11, 5, 191, 96, 11, 5, + 191, 93, 11, 5, 191, 123, 11, 5, 191, 104, 11, 5, 190, 244, 11, 5, 190, + 246, 11, 5, 190, 245, 11, 5, 191, 2, 11, 5, 191, 1, 11, 5, 191, 7, 11, 5, + 191, 3, 11, 5, 191, 73, 11, 5, 191, 87, 11, 5, 191, 79, 11, 5, 190, 240, + 11, 5, 190, 239, 11, 5, 190, 251, 11, 5, 190, 243, 11, 5, 190, 241, 11, + 5, 190, 242, 11, 5, 190, 226, 11, 5, 190, 225, 11, 5, 190, 231, 11, 5, + 190, 229, 11, 5, 190, 227, 11, 5, 190, 228, 11, 5, 243, 1, 11, 5, 242, + 250, 11, 5, 243, 31, 11, 5, 243, 14, 11, 5, 243, 28, 11, 5, 243, 22, 11, + 5, 243, 30, 11, 5, 243, 29, 11, 5, 247, 80, 11, 5, 247, 71, 11, 5, 247, + 162, 11, 5, 247, 113, 11, 5, 238, 185, 11, 5, 238, 187, 11, 5, 238, 186, + 11, 5, 238, 251, 11, 5, 238, 239, 11, 5, 242, 101, 11, 5, 239, 15, 11, 5, + 247, 7, 11, 5, 247, 44, 11, 5, 247, 13, 11, 5, 238, 156, 11, 5, 238, 154, + 11, 5, 238, 197, 11, 5, 238, 183, 11, 5, 238, 162, 11, 5, 238, 178, 11, + 5, 238, 132, 11, 5, 238, 131, 11, 5, 238, 145, 11, 5, 238, 139, 11, 5, + 238, 133, 11, 5, 238, 135, 11, 5, 190, 209, 11, 5, 190, 208, 11, 5, 190, + 215, 11, 5, 190, 210, 11, 5, 190, 212, 11, 5, 190, 211, 11, 5, 190, 214, + 11, 5, 190, 213, 11, 5, 190, 221, 11, 5, 190, 220, 11, 5, 190, 224, 11, + 5, 190, 222, 11, 5, 190, 205, 11, 5, 190, 207, 11, 5, 190, 206, 11, 5, + 190, 216, 11, 5, 190, 219, 11, 5, 190, 217, 11, 5, 190, 198, 11, 5, 190, + 202, 11, 5, 190, 201, 11, 5, 190, 199, 11, 5, 190, 200, 11, 5, 190, 192, + 11, 5, 190, 191, 11, 5, 190, 197, 11, 5, 190, 195, 11, 5, 190, 193, 11, + 5, 190, 194, 11, 5, 212, 35, 11, 5, 212, 34, 11, 5, 212, 40, 11, 5, 212, + 36, 11, 5, 212, 37, 11, 5, 212, 39, 11, 5, 212, 38, 11, 5, 212, 45, 11, + 5, 212, 44, 11, 5, 212, 48, 11, 5, 212, 47, 11, 5, 212, 28, 11, 5, 212, + 29, 11, 5, 212, 32, 11, 5, 212, 33, 11, 5, 212, 41, 11, 5, 212, 43, 11, + 5, 212, 23, 11, 5, 212, 31, 11, 5, 212, 27, 11, 5, 212, 24, 11, 5, 212, + 25, 11, 5, 212, 18, 11, 5, 212, 17, 11, 5, 212, 22, 11, 5, 212, 21, 11, + 5, 212, 19, 11, 5, 212, 20, 11, 5, 202, 139, 11, 5, 169, 11, 5, 202, 223, + 11, 5, 202, 143, 11, 5, 202, 203, 11, 5, 202, 206, 11, 5, 202, 204, 11, + 5, 205, 123, 11, 5, 205, 107, 11, 5, 188, 11, 5, 205, 131, 11, 5, 200, + 188, 11, 5, 200, 190, 11, 5, 200, 189, 11, 5, 202, 9, 11, 5, 201, 254, + 11, 5, 202, 47, 11, 5, 202, 15, 11, 5, 203, 239, 11, 5, 205, 69, 11, 5, + 204, 14, 11, 5, 200, 163, 11, 5, 200, 159, 11, 5, 201, 5, 11, 5, 200, 187, 11, 5, 200, 167, 11, 5, 200, 175, 11, 5, 200, 57, 11, 5, 200, 56, 11, 5, 200, 127, 11, 5, 200, 65, 11, 5, 200, 59, 11, 5, 200, 64, 11, 5, - 201, 136, 11, 5, 201, 135, 11, 5, 201, 142, 11, 5, 201, 137, 11, 5, 201, - 139, 11, 5, 201, 141, 11, 5, 201, 140, 11, 5, 201, 151, 11, 5, 201, 149, - 11, 5, 201, 175, 11, 5, 201, 152, 11, 5, 201, 131, 11, 5, 201, 130, 11, - 5, 201, 134, 11, 5, 201, 132, 11, 5, 201, 145, 11, 5, 201, 148, 11, 5, - 201, 146, 11, 5, 201, 127, 11, 5, 201, 125, 11, 5, 201, 129, 11, 5, 201, - 128, 11, 5, 201, 120, 11, 5, 201, 119, 11, 5, 201, 124, 11, 5, 201, 123, - 11, 5, 201, 121, 11, 5, 201, 122, 11, 5, 191, 66, 11, 5, 191, 65, 11, 5, + 201, 137, 11, 5, 201, 136, 11, 5, 201, 143, 11, 5, 201, 138, 11, 5, 201, + 140, 11, 5, 201, 142, 11, 5, 201, 141, 11, 5, 201, 152, 11, 5, 201, 150, + 11, 5, 201, 176, 11, 5, 201, 153, 11, 5, 201, 132, 11, 5, 201, 131, 11, + 5, 201, 135, 11, 5, 201, 133, 11, 5, 201, 146, 11, 5, 201, 149, 11, 5, + 201, 147, 11, 5, 201, 128, 11, 5, 201, 126, 11, 5, 201, 130, 11, 5, 201, + 129, 11, 5, 201, 121, 11, 5, 201, 120, 11, 5, 201, 125, 11, 5, 201, 124, + 11, 5, 201, 122, 11, 5, 201, 123, 11, 5, 191, 66, 11, 5, 191, 65, 11, 5, 191, 71, 11, 5, 191, 68, 11, 5, 191, 45, 11, 5, 191, 47, 11, 5, 191, 46, 11, 5, 191, 50, 11, 5, 191, 49, 11, 5, 191, 54, 11, 5, 191, 51, 11, 5, 191, 59, 11, 5, 191, 58, 11, 5, 191, 62, 11, 5, 191, 60, 11, 5, 191, 41, 11, 5, 191, 40, 11, 5, 191, 48, 11, 5, 191, 44, 11, 5, 191, 42, 11, 5, 191, 43, 11, 5, 191, 33, 11, 5, 191, 32, 11, 5, 191, 37, 11, 5, 191, 36, - 11, 5, 191, 34, 11, 5, 191, 35, 11, 5, 243, 133, 11, 5, 243, 129, 11, 5, - 247, 1, 11, 5, 246, 243, 11, 5, 243, 44, 11, 5, 243, 43, 11, 5, 243, 46, - 11, 5, 243, 45, 11, 5, 243, 59, 11, 5, 243, 58, 11, 5, 243, 68, 11, 5, - 243, 63, 11, 5, 243, 102, 11, 5, 243, 99, 11, 5, 243, 127, 11, 5, 243, - 110, 11, 5, 243, 38, 11, 5, 243, 48, 11, 5, 243, 42, 11, 5, 243, 39, 11, - 5, 243, 41, 11, 5, 243, 31, 11, 5, 243, 30, 11, 5, 243, 35, 11, 5, 243, - 34, 11, 5, 243, 32, 11, 5, 243, 33, 11, 5, 206, 105, 11, 5, 206, 109, 11, - 5, 206, 87, 11, 5, 206, 88, 11, 5, 206, 92, 11, 5, 206, 91, 11, 5, 206, - 95, 11, 5, 206, 93, 11, 5, 206, 99, 11, 5, 206, 98, 11, 5, 206, 104, 11, - 5, 206, 100, 11, 5, 206, 83, 11, 5, 206, 81, 11, 5, 206, 89, 11, 5, 206, - 86, 11, 5, 206, 84, 11, 5, 206, 85, 11, 5, 206, 76, 11, 5, 206, 75, 11, - 5, 206, 80, 11, 5, 206, 79, 11, 5, 206, 77, 11, 5, 206, 78, 11, 5, 212, - 242, 11, 5, 212, 241, 11, 5, 212, 244, 11, 5, 212, 243, 11, 5, 212, 233, - 11, 5, 212, 235, 11, 5, 212, 234, 11, 5, 212, 237, 11, 5, 212, 236, 11, - 5, 212, 240, 11, 5, 212, 239, 11, 5, 212, 227, 11, 5, 212, 226, 11, 5, - 212, 232, 11, 5, 212, 230, 11, 5, 212, 228, 11, 5, 212, 229, 11, 5, 212, - 221, 11, 5, 212, 220, 11, 5, 212, 225, 11, 5, 212, 224, 11, 5, 212, 222, - 11, 5, 212, 223, 11, 5, 203, 123, 11, 5, 203, 118, 11, 5, 203, 165, 11, - 5, 203, 136, 11, 5, 202, 249, 11, 5, 202, 251, 11, 5, 202, 250, 11, 5, - 203, 24, 11, 5, 203, 19, 11, 5, 203, 56, 11, 5, 203, 44, 11, 5, 203, 91, - 11, 5, 203, 84, 11, 5, 203, 113, 11, 5, 203, 100, 11, 5, 202, 245, 11, 5, - 202, 242, 11, 5, 203, 5, 11, 5, 202, 248, 11, 5, 202, 246, 11, 5, 202, - 247, 11, 5, 202, 225, 11, 5, 202, 224, 11, 5, 202, 231, 11, 5, 202, 228, - 11, 5, 202, 226, 11, 5, 202, 227, 11, 5, 207, 130, 11, 5, 207, 123, 11, - 5, 165, 11, 5, 207, 136, 11, 5, 206, 38, 11, 5, 206, 40, 11, 5, 206, 39, - 11, 5, 206, 123, 11, 5, 206, 111, 11, 5, 206, 162, 11, 5, 206, 127, 11, - 5, 207, 11, 11, 5, 207, 113, 11, 5, 207, 53, 11, 5, 206, 30, 11, 5, 206, - 27, 11, 5, 206, 68, 11, 5, 206, 37, 11, 5, 206, 33, 11, 5, 206, 34, 11, - 5, 206, 12, 11, 5, 206, 11, 11, 5, 206, 17, 11, 5, 206, 15, 11, 5, 206, - 13, 11, 5, 206, 14, 11, 5, 222, 232, 11, 5, 222, 231, 11, 5, 222, 244, - 11, 5, 222, 233, 11, 5, 222, 240, 11, 5, 222, 239, 11, 5, 222, 242, 11, - 5, 222, 241, 11, 5, 222, 170, 11, 5, 222, 169, 11, 5, 222, 172, 11, 5, - 222, 171, 11, 5, 222, 188, 11, 5, 222, 186, 11, 5, 222, 201, 11, 5, 222, - 190, 11, 5, 222, 163, 11, 5, 222, 161, 11, 5, 222, 182, 11, 5, 222, 168, - 11, 5, 222, 165, 11, 5, 222, 166, 11, 5, 222, 155, 11, 5, 222, 154, 11, - 5, 222, 159, 11, 5, 222, 158, 11, 5, 222, 156, 11, 5, 222, 157, 11, 5, - 208, 49, 11, 5, 208, 47, 11, 5, 208, 57, 11, 5, 208, 50, 11, 5, 208, 54, - 11, 5, 208, 53, 11, 5, 208, 56, 11, 5, 208, 55, 11, 5, 207, 253, 11, 5, - 207, 250, 11, 5, 207, 255, 11, 5, 207, 254, 11, 5, 208, 36, 11, 5, 208, - 35, 11, 5, 208, 45, 11, 5, 208, 39, 11, 5, 207, 245, 11, 5, 207, 241, 11, - 5, 208, 33, 11, 5, 207, 249, 11, 5, 207, 247, 11, 5, 207, 248, 11, 5, - 207, 225, 11, 5, 207, 223, 11, 5, 207, 235, 11, 5, 207, 228, 11, 5, 207, - 226, 11, 5, 207, 227, 11, 5, 222, 221, 11, 5, 222, 220, 11, 5, 222, 227, - 11, 5, 222, 222, 11, 5, 222, 224, 11, 5, 222, 223, 11, 5, 222, 226, 11, - 5, 222, 225, 11, 5, 222, 212, 11, 5, 222, 214, 11, 5, 222, 213, 11, 5, - 222, 217, 11, 5, 222, 216, 11, 5, 222, 219, 11, 5, 222, 218, 11, 5, 222, - 208, 11, 5, 222, 207, 11, 5, 222, 215, 11, 5, 222, 211, 11, 5, 222, 209, - 11, 5, 222, 210, 11, 5, 222, 204, 11, 5, 222, 203, 11, 5, 222, 206, 11, - 5, 222, 205, 11, 5, 213, 134, 11, 5, 213, 133, 11, 5, 213, 141, 11, 5, - 213, 135, 11, 5, 213, 137, 11, 5, 213, 136, 11, 5, 213, 140, 11, 5, 213, - 138, 11, 5, 213, 123, 11, 5, 213, 124, 11, 5, 213, 129, 11, 5, 213, 128, - 11, 5, 213, 132, 11, 5, 213, 130, 11, 5, 213, 118, 11, 5, 213, 127, 11, - 5, 213, 122, 11, 5, 213, 119, 11, 5, 213, 120, 11, 5, 213, 113, 11, 5, - 213, 112, 11, 5, 213, 117, 11, 5, 213, 116, 11, 5, 213, 114, 11, 5, 213, - 115, 11, 5, 212, 68, 11, 5, 212, 67, 11, 5, 212, 81, 11, 5, 212, 72, 11, - 5, 212, 77, 11, 5, 212, 76, 11, 5, 212, 79, 11, 5, 212, 78, 11, 5, 212, - 53, 11, 5, 212, 55, 11, 5, 212, 54, 11, 5, 212, 60, 11, 5, 212, 59, 11, - 5, 212, 65, 11, 5, 212, 61, 11, 5, 212, 51, 11, 5, 212, 49, 11, 5, 212, - 58, 11, 5, 212, 52, 11, 5, 192, 198, 11, 5, 192, 197, 11, 5, 192, 207, - 11, 5, 192, 200, 11, 5, 192, 202, 11, 5, 192, 201, 11, 5, 192, 204, 11, - 5, 192, 203, 11, 5, 192, 186, 11, 5, 192, 187, 11, 5, 192, 191, 11, 5, - 192, 190, 11, 5, 192, 196, 11, 5, 192, 194, 11, 5, 192, 163, 11, 5, 192, - 161, 11, 5, 192, 176, 11, 5, 192, 166, 11, 5, 192, 164, 11, 5, 192, 165, - 11, 5, 192, 18, 11, 5, 192, 16, 11, 5, 192, 33, 11, 5, 192, 19, 11, 5, - 192, 27, 11, 5, 192, 26, 11, 5, 192, 30, 11, 5, 192, 28, 11, 5, 191, 198, - 11, 5, 191, 197, 11, 5, 191, 201, 11, 5, 191, 199, 11, 5, 191, 240, 11, - 5, 191, 235, 11, 5, 192, 12, 11, 5, 191, 245, 11, 5, 191, 189, 11, 5, - 191, 185, 11, 5, 191, 225, 11, 5, 191, 196, 11, 5, 191, 192, 11, 5, 191, - 193, 11, 5, 191, 169, 11, 5, 191, 168, 11, 5, 191, 176, 11, 5, 191, 172, - 11, 5, 191, 170, 11, 5, 191, 171, 11, 48, 208, 36, 11, 48, 219, 146, 11, - 48, 221, 120, 11, 48, 212, 72, 11, 48, 238, 137, 11, 48, 201, 142, 11, - 48, 231, 110, 11, 48, 231, 142, 11, 48, 216, 100, 11, 48, 228, 104, 11, - 48, 218, 175, 11, 48, 249, 25, 11, 48, 215, 202, 11, 48, 192, 12, 11, 48, - 208, 131, 11, 48, 228, 98, 11, 48, 199, 171, 11, 48, 231, 240, 11, 48, - 190, 243, 11, 48, 238, 130, 11, 48, 237, 151, 11, 48, 247, 230, 11, 48, - 231, 106, 11, 48, 212, 61, 11, 48, 197, 94, 11, 48, 211, 78, 11, 48, 222, - 208, 11, 48, 191, 2, 11, 48, 208, 108, 11, 48, 229, 65, 11, 48, 192, 18, - 11, 48, 193, 244, 11, 48, 202, 231, 11, 48, 195, 141, 11, 48, 191, 123, - 11, 48, 222, 201, 11, 48, 212, 25, 11, 48, 222, 206, 11, 48, 230, 232, - 11, 48, 222, 226, 11, 48, 193, 48, 11, 48, 235, 89, 11, 48, 202, 247, 11, - 48, 219, 140, 11, 48, 238, 143, 11, 48, 238, 184, 11, 48, 243, 12, 11, - 48, 228, 101, 11, 48, 203, 123, 11, 48, 190, 242, 11, 48, 203, 44, 11, - 48, 243, 127, 11, 48, 190, 212, 11, 48, 214, 189, 11, 48, 222, 22, 219, - 88, 1, 249, 153, 219, 88, 1, 168, 219, 88, 1, 209, 228, 219, 88, 1, 238, - 32, 219, 88, 1, 190, 190, 219, 88, 1, 199, 49, 219, 88, 1, 231, 240, 219, - 88, 1, 155, 219, 88, 1, 221, 215, 219, 88, 1, 223, 32, 219, 88, 1, 247, - 160, 219, 88, 1, 247, 1, 219, 88, 1, 235, 35, 219, 88, 1, 197, 168, 219, - 88, 1, 197, 157, 219, 88, 1, 174, 219, 88, 1, 180, 219, 88, 1, 173, 219, - 88, 1, 188, 219, 88, 1, 191, 71, 219, 88, 1, 191, 123, 219, 88, 1, 214, - 68, 219, 88, 1, 140, 219, 88, 1, 192, 220, 219, 88, 1, 229, 177, 219, 88, - 1, 233, 109, 219, 88, 1, 193, 190, 219, 88, 1, 203, 165, 219, 88, 1, 170, - 219, 88, 1, 231, 91, 219, 88, 1, 65, 219, 88, 1, 252, 25, 219, 88, 1, 71, - 219, 88, 1, 233, 242, 219, 88, 1, 68, 219, 88, 1, 74, 219, 88, 1, 66, - 219, 88, 1, 196, 152, 219, 88, 1, 196, 141, 219, 88, 1, 211, 151, 219, - 88, 1, 163, 215, 69, 198, 193, 219, 88, 1, 163, 215, 7, 209, 73, 219, 88, - 1, 163, 215, 69, 238, 142, 219, 88, 1, 163, 215, 69, 248, 111, 219, 88, - 1, 163, 215, 69, 180, 219, 88, 1, 163, 215, 69, 222, 253, 219, 88, 208, - 152, 242, 74, 219, 88, 208, 152, 232, 80, 201, 63, 59, 5, 234, 188, 59, - 5, 234, 184, 59, 5, 229, 215, 59, 5, 193, 114, 59, 5, 193, 113, 59, 5, - 210, 49, 59, 5, 248, 195, 59, 5, 249, 1, 59, 5, 217, 3, 59, 5, 221, 16, - 59, 5, 216, 132, 59, 5, 231, 178, 59, 5, 233, 52, 59, 5, 195, 148, 59, 5, - 199, 121, 59, 5, 199, 31, 59, 5, 237, 58, 59, 5, 237, 55, 59, 5, 219, - 228, 59, 5, 207, 84, 59, 5, 237, 131, 59, 5, 214, 153, 59, 5, 205, 50, - 59, 5, 203, 111, 59, 5, 191, 84, 59, 5, 191, 61, 59, 5, 247, 34, 59, 5, - 223, 8, 59, 5, 213, 148, 59, 5, 192, 77, 59, 5, 222, 13, 59, 5, 214, 41, - 59, 5, 231, 157, 59, 5, 216, 211, 59, 5, 214, 110, 59, 5, 212, 89, 59, 5, - 68, 59, 5, 223, 162, 59, 5, 229, 158, 59, 5, 229, 128, 59, 5, 193, 86, - 59, 5, 193, 68, 59, 5, 209, 185, 59, 5, 248, 193, 59, 5, 248, 188, 59, 5, - 216, 252, 59, 5, 221, 13, 59, 5, 216, 129, 59, 5, 231, 174, 59, 5, 233, - 23, 59, 5, 195, 69, 59, 5, 198, 193, 59, 5, 199, 11, 59, 5, 237, 50, 59, - 5, 237, 54, 59, 5, 219, 146, 59, 5, 207, 1, 59, 5, 237, 44, 59, 5, 214, - 147, 59, 5, 202, 222, 59, 5, 203, 81, 59, 5, 191, 30, 59, 5, 191, 57, 59, - 5, 243, 29, 59, 5, 222, 244, 59, 5, 213, 141, 59, 5, 192, 33, 59, 5, 221, - 166, 59, 5, 214, 33, 59, 5, 231, 53, 59, 5, 216, 100, 59, 5, 213, 219, - 59, 5, 212, 81, 59, 5, 65, 59, 5, 251, 132, 59, 5, 214, 63, 59, 5, 140, - 59, 5, 230, 56, 59, 5, 193, 190, 59, 5, 193, 164, 59, 5, 168, 59, 5, 248, - 203, 59, 5, 249, 153, 59, 5, 217, 11, 59, 5, 221, 21, 59, 5, 221, 19, 59, - 5, 216, 136, 59, 5, 231, 182, 59, 5, 233, 109, 59, 5, 195, 188, 59, 5, - 190, 190, 59, 5, 199, 49, 59, 5, 237, 68, 59, 5, 237, 57, 59, 5, 173, 59, - 5, 165, 59, 5, 238, 32, 59, 5, 214, 162, 59, 5, 188, 59, 5, 203, 165, 59, - 5, 191, 123, 59, 5, 191, 71, 59, 5, 247, 160, 59, 5, 223, 32, 59, 5, 213, - 157, 59, 5, 170, 59, 5, 155, 59, 5, 222, 87, 59, 5, 214, 47, 59, 5, 231, - 240, 59, 5, 174, 59, 5, 180, 59, 5, 212, 101, 59, 5, 211, 87, 59, 5, 211, - 82, 59, 5, 228, 252, 59, 5, 193, 29, 59, 5, 193, 25, 59, 5, 209, 37, 59, - 5, 248, 191, 59, 5, 248, 97, 59, 5, 216, 247, 59, 5, 221, 11, 59, 5, 216, - 125, 59, 5, 231, 170, 59, 5, 232, 162, 59, 5, 195, 8, 59, 5, 198, 59, 59, - 5, 198, 235, 59, 5, 237, 47, 59, 5, 237, 52, 59, 5, 219, 8, 59, 5, 206, - 134, 59, 5, 236, 146, 59, 5, 214, 134, 59, 5, 202, 16, 59, 5, 203, 48, - 59, 5, 191, 4, 59, 5, 191, 52, 59, 5, 239, 18, 59, 5, 222, 191, 59, 5, - 213, 131, 59, 5, 191, 246, 59, 5, 221, 41, 59, 5, 214, 31, 59, 5, 230, - 245, 59, 5, 215, 211, 59, 5, 213, 26, 59, 5, 212, 62, 59, 5, 66, 59, 5, - 196, 113, 59, 5, 228, 159, 59, 5, 228, 142, 59, 5, 193, 0, 59, 5, 192, - 249, 59, 5, 208, 165, 59, 5, 248, 190, 59, 5, 248, 10, 59, 5, 216, 246, - 59, 5, 221, 9, 59, 5, 216, 124, 59, 5, 231, 169, 59, 5, 232, 86, 59, 5, - 193, 249, 59, 5, 197, 94, 59, 5, 198, 213, 59, 5, 237, 45, 59, 5, 237, - 51, 59, 5, 218, 225, 59, 5, 206, 68, 59, 5, 235, 89, 59, 5, 214, 129, 59, - 5, 201, 4, 59, 5, 203, 5, 59, 5, 190, 251, 59, 5, 191, 48, 59, 5, 238, - 195, 59, 5, 222, 182, 59, 5, 213, 127, 59, 5, 191, 225, 59, 5, 220, 232, - 59, 5, 214, 30, 59, 5, 230, 179, 59, 5, 215, 155, 59, 5, 212, 178, 59, 5, - 212, 58, 59, 5, 74, 59, 5, 211, 104, 59, 5, 213, 245, 59, 5, 229, 23, 59, - 5, 228, 255, 59, 5, 193, 48, 59, 5, 193, 30, 59, 5, 209, 73, 59, 5, 248, - 192, 59, 5, 248, 111, 59, 5, 216, 248, 59, 5, 221, 12, 59, 5, 216, 127, - 59, 5, 231, 172, 59, 5, 231, 171, 59, 5, 232, 175, 59, 5, 195, 24, 59, 5, - 159, 59, 5, 198, 241, 59, 5, 237, 48, 59, 5, 237, 53, 59, 5, 219, 43, 59, - 5, 206, 162, 59, 5, 236, 174, 59, 5, 214, 138, 59, 5, 202, 46, 59, 5, - 203, 56, 59, 5, 191, 7, 59, 5, 191, 54, 59, 5, 242, 99, 59, 5, 222, 201, - 59, 5, 213, 132, 59, 5, 192, 12, 59, 5, 221, 67, 59, 5, 214, 32, 59, 5, - 231, 3, 59, 5, 216, 12, 59, 5, 213, 43, 59, 5, 212, 65, 59, 5, 71, 59, 5, - 234, 103, 59, 5, 214, 52, 59, 5, 229, 245, 59, 5, 229, 198, 59, 5, 193, - 125, 59, 5, 193, 108, 59, 5, 210, 63, 59, 5, 248, 196, 59, 5, 249, 17, - 59, 5, 217, 4, 59, 5, 221, 17, 59, 5, 221, 15, 59, 5, 216, 133, 59, 5, - 231, 179, 59, 5, 231, 177, 59, 5, 233, 59, 59, 5, 195, 153, 59, 5, 199, - 145, 59, 5, 199, 33, 59, 5, 237, 59, 59, 5, 237, 56, 59, 5, 219, 238, 59, - 5, 207, 113, 59, 5, 237, 146, 59, 5, 214, 154, 59, 5, 205, 68, 59, 5, - 203, 113, 59, 5, 191, 87, 59, 5, 191, 62, 59, 5, 247, 42, 59, 5, 223, 10, - 59, 5, 213, 150, 59, 5, 192, 80, 59, 5, 222, 22, 59, 5, 214, 42, 59, 5, - 214, 38, 59, 5, 231, 165, 59, 5, 231, 151, 59, 5, 216, 232, 59, 5, 214, - 121, 59, 5, 212, 90, 59, 5, 214, 70, 59, 5, 219, 190, 59, 242, 74, 59, - 232, 80, 201, 63, 59, 208, 13, 77, 59, 5, 214, 137, 233, 109, 59, 5, 214, - 137, 155, 59, 5, 214, 137, 202, 16, 59, 16, 233, 48, 59, 16, 222, 11, 59, - 16, 198, 140, 59, 16, 213, 186, 59, 16, 249, 95, 59, 16, 233, 108, 59, - 16, 199, 245, 59, 16, 237, 236, 59, 16, 236, 145, 59, 16, 220, 208, 59, - 16, 198, 63, 59, 16, 236, 173, 59, 16, 222, 192, 59, 17, 191, 77, 59, 17, - 107, 59, 17, 109, 59, 17, 138, 59, 17, 134, 59, 17, 149, 59, 17, 169, 59, - 17, 175, 59, 17, 171, 59, 17, 178, 59, 5, 214, 137, 174, 59, 5, 214, 137, - 236, 174, 38, 6, 1, 191, 81, 38, 2, 1, 191, 81, 38, 6, 1, 235, 30, 38, 2, - 1, 235, 30, 38, 6, 1, 207, 18, 235, 32, 38, 2, 1, 207, 18, 235, 32, 38, - 6, 1, 223, 83, 38, 2, 1, 223, 83, 38, 6, 1, 236, 191, 38, 2, 1, 236, 191, - 38, 6, 1, 215, 219, 196, 128, 38, 2, 1, 215, 219, 196, 128, 38, 6, 1, - 248, 24, 211, 110, 38, 2, 1, 248, 24, 211, 110, 38, 6, 1, 214, 82, 192, - 62, 38, 2, 1, 214, 82, 192, 62, 38, 6, 1, 192, 59, 4, 249, 147, 192, 62, - 38, 2, 1, 192, 59, 4, 249, 147, 192, 62, 38, 6, 1, 223, 81, 192, 95, 38, - 2, 1, 223, 81, 192, 95, 38, 6, 1, 207, 18, 191, 225, 38, 2, 1, 207, 18, - 191, 225, 38, 6, 1, 223, 81, 65, 38, 2, 1, 223, 81, 65, 38, 6, 1, 242, - 219, 219, 83, 191, 190, 38, 2, 1, 242, 219, 219, 83, 191, 190, 38, 6, 1, - 248, 131, 191, 190, 38, 2, 1, 248, 131, 191, 190, 38, 6, 1, 223, 81, 242, - 219, 219, 83, 191, 190, 38, 2, 1, 223, 81, 242, 219, 219, 83, 191, 190, - 38, 6, 1, 192, 14, 38, 2, 1, 192, 14, 38, 6, 1, 207, 18, 197, 161, 38, 2, - 1, 207, 18, 197, 161, 38, 6, 1, 202, 32, 237, 146, 38, 2, 1, 202, 32, - 237, 146, 38, 6, 1, 202, 32, 234, 140, 38, 2, 1, 202, 32, 234, 140, 38, - 6, 1, 202, 32, 234, 114, 38, 2, 1, 202, 32, 234, 114, 38, 6, 1, 215, 223, - 74, 38, 2, 1, 215, 223, 74, 38, 6, 1, 248, 164, 74, 38, 2, 1, 248, 164, - 74, 38, 6, 1, 55, 215, 223, 74, 38, 2, 1, 55, 215, 223, 74, 38, 1, 215, - 130, 74, 33, 38, 193, 226, 33, 38, 199, 96, 216, 48, 56, 33, 38, 228, - 141, 216, 48, 56, 33, 38, 198, 230, 216, 48, 56, 202, 95, 250, 193, 33, - 38, 1, 196, 125, 223, 226, 33, 38, 1, 68, 33, 38, 1, 192, 33, 33, 38, 1, - 66, 33, 38, 1, 230, 17, 56, 33, 38, 1, 192, 58, 33, 38, 1, 202, 32, 56, - 33, 38, 1, 211, 110, 33, 38, 222, 35, 33, 38, 210, 70, 38, 222, 35, 38, - 210, 70, 38, 6, 1, 235, 45, 38, 2, 1, 235, 45, 38, 6, 1, 235, 21, 38, 2, - 1, 235, 21, 38, 6, 1, 191, 38, 38, 2, 1, 191, 38, 38, 6, 1, 247, 58, 38, - 2, 1, 247, 58, 38, 6, 1, 235, 17, 38, 2, 1, 235, 17, 38, 6, 1, 199, 146, + 11, 5, 191, 34, 11, 5, 191, 35, 11, 5, 243, 135, 11, 5, 243, 131, 11, 5, + 247, 3, 11, 5, 246, 245, 11, 5, 243, 46, 11, 5, 243, 45, 11, 5, 243, 48, + 11, 5, 243, 47, 11, 5, 243, 61, 11, 5, 243, 60, 11, 5, 243, 70, 11, 5, + 243, 65, 11, 5, 243, 104, 11, 5, 243, 101, 11, 5, 243, 129, 11, 5, 243, + 112, 11, 5, 243, 40, 11, 5, 243, 50, 11, 5, 243, 44, 11, 5, 243, 41, 11, + 5, 243, 43, 11, 5, 243, 33, 11, 5, 243, 32, 11, 5, 243, 37, 11, 5, 243, + 36, 11, 5, 243, 34, 11, 5, 243, 35, 11, 5, 206, 106, 11, 5, 206, 110, 11, + 5, 206, 88, 11, 5, 206, 89, 11, 5, 206, 93, 11, 5, 206, 92, 11, 5, 206, + 96, 11, 5, 206, 94, 11, 5, 206, 100, 11, 5, 206, 99, 11, 5, 206, 105, 11, + 5, 206, 101, 11, 5, 206, 84, 11, 5, 206, 82, 11, 5, 206, 90, 11, 5, 206, + 87, 11, 5, 206, 85, 11, 5, 206, 86, 11, 5, 206, 77, 11, 5, 206, 76, 11, + 5, 206, 81, 11, 5, 206, 80, 11, 5, 206, 78, 11, 5, 206, 79, 11, 5, 212, + 244, 11, 5, 212, 243, 11, 5, 212, 246, 11, 5, 212, 245, 11, 5, 212, 235, + 11, 5, 212, 237, 11, 5, 212, 236, 11, 5, 212, 239, 11, 5, 212, 238, 11, + 5, 212, 242, 11, 5, 212, 241, 11, 5, 212, 229, 11, 5, 212, 228, 11, 5, + 212, 234, 11, 5, 212, 232, 11, 5, 212, 230, 11, 5, 212, 231, 11, 5, 212, + 223, 11, 5, 212, 222, 11, 5, 212, 227, 11, 5, 212, 226, 11, 5, 212, 224, + 11, 5, 212, 225, 11, 5, 203, 124, 11, 5, 203, 119, 11, 5, 203, 166, 11, + 5, 203, 137, 11, 5, 202, 250, 11, 5, 202, 252, 11, 5, 202, 251, 11, 5, + 203, 25, 11, 5, 203, 20, 11, 5, 203, 57, 11, 5, 203, 45, 11, 5, 203, 92, + 11, 5, 203, 85, 11, 5, 203, 114, 11, 5, 203, 101, 11, 5, 202, 246, 11, 5, + 202, 243, 11, 5, 203, 6, 11, 5, 202, 249, 11, 5, 202, 247, 11, 5, 202, + 248, 11, 5, 202, 226, 11, 5, 202, 225, 11, 5, 202, 232, 11, 5, 202, 229, + 11, 5, 202, 227, 11, 5, 202, 228, 11, 5, 207, 132, 11, 5, 207, 125, 11, + 5, 165, 11, 5, 207, 138, 11, 5, 206, 39, 11, 5, 206, 41, 11, 5, 206, 40, + 11, 5, 206, 124, 11, 5, 206, 112, 11, 5, 206, 163, 11, 5, 206, 128, 11, + 5, 207, 12, 11, 5, 207, 115, 11, 5, 207, 54, 11, 5, 206, 31, 11, 5, 206, + 28, 11, 5, 206, 69, 11, 5, 206, 38, 11, 5, 206, 34, 11, 5, 206, 35, 11, + 5, 206, 13, 11, 5, 206, 12, 11, 5, 206, 18, 11, 5, 206, 16, 11, 5, 206, + 14, 11, 5, 206, 15, 11, 5, 222, 234, 11, 5, 222, 233, 11, 5, 222, 246, + 11, 5, 222, 235, 11, 5, 222, 242, 11, 5, 222, 241, 11, 5, 222, 244, 11, + 5, 222, 243, 11, 5, 222, 172, 11, 5, 222, 171, 11, 5, 222, 174, 11, 5, + 222, 173, 11, 5, 222, 190, 11, 5, 222, 188, 11, 5, 222, 203, 11, 5, 222, + 192, 11, 5, 222, 165, 11, 5, 222, 163, 11, 5, 222, 184, 11, 5, 222, 170, + 11, 5, 222, 167, 11, 5, 222, 168, 11, 5, 222, 157, 11, 5, 222, 156, 11, + 5, 222, 161, 11, 5, 222, 160, 11, 5, 222, 158, 11, 5, 222, 159, 11, 5, + 208, 51, 11, 5, 208, 49, 11, 5, 208, 59, 11, 5, 208, 52, 11, 5, 208, 56, + 11, 5, 208, 55, 11, 5, 208, 58, 11, 5, 208, 57, 11, 5, 207, 255, 11, 5, + 207, 252, 11, 5, 208, 1, 11, 5, 208, 0, 11, 5, 208, 38, 11, 5, 208, 37, + 11, 5, 208, 47, 11, 5, 208, 41, 11, 5, 207, 247, 11, 5, 207, 243, 11, 5, + 208, 35, 11, 5, 207, 251, 11, 5, 207, 249, 11, 5, 207, 250, 11, 5, 207, + 227, 11, 5, 207, 225, 11, 5, 207, 237, 11, 5, 207, 230, 11, 5, 207, 228, + 11, 5, 207, 229, 11, 5, 222, 223, 11, 5, 222, 222, 11, 5, 222, 229, 11, + 5, 222, 224, 11, 5, 222, 226, 11, 5, 222, 225, 11, 5, 222, 228, 11, 5, + 222, 227, 11, 5, 222, 214, 11, 5, 222, 216, 11, 5, 222, 215, 11, 5, 222, + 219, 11, 5, 222, 218, 11, 5, 222, 221, 11, 5, 222, 220, 11, 5, 222, 210, + 11, 5, 222, 209, 11, 5, 222, 217, 11, 5, 222, 213, 11, 5, 222, 211, 11, + 5, 222, 212, 11, 5, 222, 206, 11, 5, 222, 205, 11, 5, 222, 208, 11, 5, + 222, 207, 11, 5, 213, 136, 11, 5, 213, 135, 11, 5, 213, 143, 11, 5, 213, + 137, 11, 5, 213, 139, 11, 5, 213, 138, 11, 5, 213, 142, 11, 5, 213, 140, + 11, 5, 213, 125, 11, 5, 213, 126, 11, 5, 213, 131, 11, 5, 213, 130, 11, + 5, 213, 134, 11, 5, 213, 132, 11, 5, 213, 120, 11, 5, 213, 129, 11, 5, + 213, 124, 11, 5, 213, 121, 11, 5, 213, 122, 11, 5, 213, 115, 11, 5, 213, + 114, 11, 5, 213, 119, 11, 5, 213, 118, 11, 5, 213, 116, 11, 5, 213, 117, + 11, 5, 212, 70, 11, 5, 212, 69, 11, 5, 212, 83, 11, 5, 212, 74, 11, 5, + 212, 79, 11, 5, 212, 78, 11, 5, 212, 81, 11, 5, 212, 80, 11, 5, 212, 55, + 11, 5, 212, 57, 11, 5, 212, 56, 11, 5, 212, 62, 11, 5, 212, 61, 11, 5, + 212, 67, 11, 5, 212, 63, 11, 5, 212, 53, 11, 5, 212, 51, 11, 5, 212, 60, + 11, 5, 212, 54, 11, 5, 192, 198, 11, 5, 192, 197, 11, 5, 192, 207, 11, 5, + 192, 200, 11, 5, 192, 202, 11, 5, 192, 201, 11, 5, 192, 204, 11, 5, 192, + 203, 11, 5, 192, 186, 11, 5, 192, 187, 11, 5, 192, 191, 11, 5, 192, 190, + 11, 5, 192, 196, 11, 5, 192, 194, 11, 5, 192, 163, 11, 5, 192, 161, 11, + 5, 192, 176, 11, 5, 192, 166, 11, 5, 192, 164, 11, 5, 192, 165, 11, 5, + 192, 18, 11, 5, 192, 16, 11, 5, 192, 33, 11, 5, 192, 19, 11, 5, 192, 27, + 11, 5, 192, 26, 11, 5, 192, 30, 11, 5, 192, 28, 11, 5, 191, 198, 11, 5, + 191, 197, 11, 5, 191, 201, 11, 5, 191, 199, 11, 5, 191, 240, 11, 5, 191, + 235, 11, 5, 192, 12, 11, 5, 191, 245, 11, 5, 191, 189, 11, 5, 191, 185, + 11, 5, 191, 225, 11, 5, 191, 196, 11, 5, 191, 192, 11, 5, 191, 193, 11, + 5, 191, 169, 11, 5, 191, 168, 11, 5, 191, 176, 11, 5, 191, 172, 11, 5, + 191, 170, 11, 5, 191, 171, 11, 48, 208, 38, 11, 48, 219, 148, 11, 48, + 221, 122, 11, 48, 212, 74, 11, 48, 238, 139, 11, 48, 201, 143, 11, 48, + 231, 112, 11, 48, 231, 144, 11, 48, 216, 102, 11, 48, 228, 106, 11, 48, + 218, 177, 11, 48, 249, 27, 11, 48, 215, 204, 11, 48, 192, 12, 11, 48, + 208, 133, 11, 48, 228, 100, 11, 48, 199, 171, 11, 48, 231, 242, 11, 48, + 190, 243, 11, 48, 238, 132, 11, 48, 237, 153, 11, 48, 247, 232, 11, 48, + 231, 108, 11, 48, 212, 63, 11, 48, 197, 94, 11, 48, 211, 80, 11, 48, 222, + 210, 11, 48, 191, 2, 11, 48, 208, 110, 11, 48, 229, 67, 11, 48, 192, 18, + 11, 48, 193, 244, 11, 48, 202, 232, 11, 48, 195, 141, 11, 48, 191, 123, + 11, 48, 222, 203, 11, 48, 212, 27, 11, 48, 222, 208, 11, 48, 230, 234, + 11, 48, 222, 228, 11, 48, 193, 48, 11, 48, 235, 91, 11, 48, 202, 248, 11, + 48, 219, 142, 11, 48, 238, 145, 11, 48, 238, 186, 11, 48, 243, 14, 11, + 48, 228, 103, 11, 48, 203, 124, 11, 48, 190, 242, 11, 48, 203, 45, 11, + 48, 243, 129, 11, 48, 190, 212, 11, 48, 214, 191, 11, 48, 222, 24, 219, + 90, 1, 249, 155, 219, 90, 1, 168, 219, 90, 1, 209, 230, 219, 90, 1, 238, + 34, 219, 90, 1, 190, 190, 219, 90, 1, 199, 49, 219, 90, 1, 231, 242, 219, + 90, 1, 155, 219, 90, 1, 221, 217, 219, 90, 1, 223, 34, 219, 90, 1, 247, + 162, 219, 90, 1, 247, 3, 219, 90, 1, 235, 37, 219, 90, 1, 197, 168, 219, + 90, 1, 197, 157, 219, 90, 1, 174, 219, 90, 1, 181, 219, 90, 1, 173, 219, + 90, 1, 188, 219, 90, 1, 191, 71, 219, 90, 1, 191, 123, 219, 90, 1, 214, + 70, 219, 90, 1, 140, 219, 90, 1, 192, 220, 219, 90, 1, 229, 179, 219, 90, + 1, 233, 111, 219, 90, 1, 193, 190, 219, 90, 1, 203, 166, 219, 90, 1, 170, + 219, 90, 1, 231, 93, 219, 90, 1, 65, 219, 90, 1, 252, 27, 219, 90, 1, 71, + 219, 90, 1, 233, 244, 219, 90, 1, 68, 219, 90, 1, 74, 219, 90, 1, 66, + 219, 90, 1, 196, 152, 219, 90, 1, 196, 141, 219, 90, 1, 211, 153, 219, + 90, 1, 163, 215, 71, 198, 193, 219, 90, 1, 163, 215, 9, 209, 75, 219, 90, + 1, 163, 215, 71, 238, 144, 219, 90, 1, 163, 215, 71, 248, 113, 219, 90, + 1, 163, 215, 71, 181, 219, 90, 1, 163, 215, 71, 222, 255, 219, 90, 208, + 154, 242, 76, 219, 90, 208, 154, 232, 82, 201, 64, 59, 5, 234, 190, 59, + 5, 234, 186, 59, 5, 229, 217, 59, 5, 193, 114, 59, 5, 193, 113, 59, 5, + 210, 51, 59, 5, 248, 197, 59, 5, 249, 3, 59, 5, 217, 5, 59, 5, 221, 18, + 59, 5, 216, 134, 59, 5, 231, 180, 59, 5, 233, 54, 59, 5, 195, 148, 59, 5, + 199, 121, 59, 5, 199, 31, 59, 5, 237, 60, 59, 5, 237, 57, 59, 5, 219, + 230, 59, 5, 207, 86, 59, 5, 237, 133, 59, 5, 214, 155, 59, 5, 205, 51, + 59, 5, 203, 112, 59, 5, 191, 84, 59, 5, 191, 61, 59, 5, 247, 36, 59, 5, + 223, 10, 59, 5, 213, 150, 59, 5, 192, 77, 59, 5, 222, 15, 59, 5, 214, 43, + 59, 5, 231, 159, 59, 5, 216, 213, 59, 5, 214, 112, 59, 5, 212, 91, 59, 5, + 68, 59, 5, 223, 164, 59, 5, 229, 160, 59, 5, 229, 130, 59, 5, 193, 86, + 59, 5, 193, 68, 59, 5, 209, 187, 59, 5, 248, 195, 59, 5, 248, 190, 59, 5, + 216, 254, 59, 5, 221, 15, 59, 5, 216, 131, 59, 5, 231, 176, 59, 5, 233, + 25, 59, 5, 195, 69, 59, 5, 198, 193, 59, 5, 199, 11, 59, 5, 237, 52, 59, + 5, 237, 56, 59, 5, 219, 148, 59, 5, 207, 2, 59, 5, 237, 46, 59, 5, 214, + 149, 59, 5, 202, 223, 59, 5, 203, 82, 59, 5, 191, 30, 59, 5, 191, 57, 59, + 5, 243, 31, 59, 5, 222, 246, 59, 5, 213, 143, 59, 5, 192, 33, 59, 5, 221, + 168, 59, 5, 214, 35, 59, 5, 231, 55, 59, 5, 216, 102, 59, 5, 213, 221, + 59, 5, 212, 83, 59, 5, 65, 59, 5, 251, 134, 59, 5, 214, 65, 59, 5, 140, + 59, 5, 230, 58, 59, 5, 193, 190, 59, 5, 193, 164, 59, 5, 168, 59, 5, 248, + 205, 59, 5, 249, 155, 59, 5, 217, 13, 59, 5, 221, 23, 59, 5, 221, 21, 59, + 5, 216, 138, 59, 5, 231, 184, 59, 5, 233, 111, 59, 5, 195, 188, 59, 5, + 190, 190, 59, 5, 199, 49, 59, 5, 237, 70, 59, 5, 237, 59, 59, 5, 173, 59, + 5, 165, 59, 5, 238, 34, 59, 5, 214, 164, 59, 5, 188, 59, 5, 203, 166, 59, + 5, 191, 123, 59, 5, 191, 71, 59, 5, 247, 162, 59, 5, 223, 34, 59, 5, 213, + 159, 59, 5, 170, 59, 5, 155, 59, 5, 222, 89, 59, 5, 214, 49, 59, 5, 231, + 242, 59, 5, 174, 59, 5, 181, 59, 5, 212, 103, 59, 5, 211, 89, 59, 5, 211, + 84, 59, 5, 228, 254, 59, 5, 193, 29, 59, 5, 193, 25, 59, 5, 209, 39, 59, + 5, 248, 193, 59, 5, 248, 99, 59, 5, 216, 249, 59, 5, 221, 13, 59, 5, 216, + 127, 59, 5, 231, 172, 59, 5, 232, 164, 59, 5, 195, 8, 59, 5, 198, 59, 59, + 5, 198, 235, 59, 5, 237, 49, 59, 5, 237, 54, 59, 5, 219, 10, 59, 5, 206, + 135, 59, 5, 236, 148, 59, 5, 214, 136, 59, 5, 202, 17, 59, 5, 203, 49, + 59, 5, 191, 4, 59, 5, 191, 52, 59, 5, 239, 20, 59, 5, 222, 193, 59, 5, + 213, 133, 59, 5, 191, 246, 59, 5, 221, 43, 59, 5, 214, 33, 59, 5, 230, + 247, 59, 5, 215, 213, 59, 5, 213, 28, 59, 5, 212, 64, 59, 5, 66, 59, 5, + 196, 113, 59, 5, 228, 161, 59, 5, 228, 144, 59, 5, 193, 0, 59, 5, 192, + 249, 59, 5, 208, 167, 59, 5, 248, 192, 59, 5, 248, 12, 59, 5, 216, 248, + 59, 5, 221, 11, 59, 5, 216, 126, 59, 5, 231, 171, 59, 5, 232, 88, 59, 5, + 193, 249, 59, 5, 197, 94, 59, 5, 198, 213, 59, 5, 237, 47, 59, 5, 237, + 53, 59, 5, 218, 227, 59, 5, 206, 69, 59, 5, 235, 91, 59, 5, 214, 131, 59, + 5, 201, 5, 59, 5, 203, 6, 59, 5, 190, 251, 59, 5, 191, 48, 59, 5, 238, + 197, 59, 5, 222, 184, 59, 5, 213, 129, 59, 5, 191, 225, 59, 5, 220, 234, + 59, 5, 214, 32, 59, 5, 230, 181, 59, 5, 215, 157, 59, 5, 212, 180, 59, 5, + 212, 60, 59, 5, 74, 59, 5, 211, 106, 59, 5, 213, 247, 59, 5, 229, 25, 59, + 5, 229, 1, 59, 5, 193, 48, 59, 5, 193, 30, 59, 5, 209, 75, 59, 5, 248, + 194, 59, 5, 248, 113, 59, 5, 216, 250, 59, 5, 221, 14, 59, 5, 216, 129, + 59, 5, 231, 174, 59, 5, 231, 173, 59, 5, 232, 177, 59, 5, 195, 24, 59, 5, + 159, 59, 5, 198, 241, 59, 5, 237, 50, 59, 5, 237, 55, 59, 5, 219, 45, 59, + 5, 206, 163, 59, 5, 236, 176, 59, 5, 214, 140, 59, 5, 202, 47, 59, 5, + 203, 57, 59, 5, 191, 7, 59, 5, 191, 54, 59, 5, 242, 101, 59, 5, 222, 203, + 59, 5, 213, 134, 59, 5, 192, 12, 59, 5, 221, 69, 59, 5, 214, 34, 59, 5, + 231, 5, 59, 5, 216, 14, 59, 5, 213, 45, 59, 5, 212, 67, 59, 5, 71, 59, 5, + 234, 105, 59, 5, 214, 54, 59, 5, 229, 247, 59, 5, 229, 200, 59, 5, 193, + 125, 59, 5, 193, 108, 59, 5, 210, 65, 59, 5, 248, 198, 59, 5, 249, 19, + 59, 5, 217, 6, 59, 5, 221, 19, 59, 5, 221, 17, 59, 5, 216, 135, 59, 5, + 231, 181, 59, 5, 231, 179, 59, 5, 233, 61, 59, 5, 195, 153, 59, 5, 199, + 145, 59, 5, 199, 33, 59, 5, 237, 61, 59, 5, 237, 58, 59, 5, 219, 240, 59, + 5, 207, 115, 59, 5, 237, 148, 59, 5, 214, 156, 59, 5, 205, 69, 59, 5, + 203, 114, 59, 5, 191, 87, 59, 5, 191, 62, 59, 5, 247, 44, 59, 5, 223, 12, + 59, 5, 213, 152, 59, 5, 192, 80, 59, 5, 222, 24, 59, 5, 214, 44, 59, 5, + 214, 40, 59, 5, 231, 167, 59, 5, 231, 153, 59, 5, 216, 234, 59, 5, 214, + 123, 59, 5, 212, 92, 59, 5, 214, 72, 59, 5, 219, 192, 59, 242, 76, 59, + 232, 82, 201, 64, 59, 208, 15, 77, 59, 5, 214, 139, 233, 111, 59, 5, 214, + 139, 155, 59, 5, 214, 139, 202, 17, 59, 16, 233, 50, 59, 16, 222, 13, 59, + 16, 198, 140, 59, 16, 213, 188, 59, 16, 249, 97, 59, 16, 233, 110, 59, + 16, 199, 245, 59, 16, 237, 238, 59, 16, 236, 147, 59, 16, 220, 210, 59, + 16, 198, 63, 59, 16, 236, 175, 59, 16, 222, 194, 59, 17, 191, 77, 59, 17, + 107, 59, 17, 109, 59, 17, 138, 59, 17, 134, 59, 17, 150, 59, 17, 169, 59, + 17, 175, 59, 17, 171, 59, 17, 178, 59, 5, 214, 139, 174, 59, 5, 214, 139, + 236, 176, 38, 6, 1, 191, 81, 38, 2, 1, 191, 81, 38, 6, 1, 235, 32, 38, 2, + 1, 235, 32, 38, 6, 1, 207, 19, 235, 34, 38, 2, 1, 207, 19, 235, 34, 38, + 6, 1, 223, 85, 38, 2, 1, 223, 85, 38, 6, 1, 236, 193, 38, 2, 1, 236, 193, + 38, 6, 1, 215, 221, 196, 128, 38, 2, 1, 215, 221, 196, 128, 38, 6, 1, + 248, 26, 211, 112, 38, 2, 1, 248, 26, 211, 112, 38, 6, 1, 214, 84, 192, + 62, 38, 2, 1, 214, 84, 192, 62, 38, 6, 1, 192, 59, 4, 249, 149, 192, 62, + 38, 2, 1, 192, 59, 4, 249, 149, 192, 62, 38, 6, 1, 223, 83, 192, 95, 38, + 2, 1, 223, 83, 192, 95, 38, 6, 1, 207, 19, 191, 225, 38, 2, 1, 207, 19, + 191, 225, 38, 6, 1, 223, 83, 65, 38, 2, 1, 223, 83, 65, 38, 6, 1, 242, + 221, 219, 85, 191, 190, 38, 2, 1, 242, 221, 219, 85, 191, 190, 38, 6, 1, + 248, 133, 191, 190, 38, 2, 1, 248, 133, 191, 190, 38, 6, 1, 223, 83, 242, + 221, 219, 85, 191, 190, 38, 2, 1, 223, 83, 242, 221, 219, 85, 191, 190, + 38, 6, 1, 192, 14, 38, 2, 1, 192, 14, 38, 6, 1, 207, 19, 197, 161, 38, 2, + 1, 207, 19, 197, 161, 38, 6, 1, 202, 33, 237, 148, 38, 2, 1, 202, 33, + 237, 148, 38, 6, 1, 202, 33, 234, 142, 38, 2, 1, 202, 33, 234, 142, 38, + 6, 1, 202, 33, 234, 116, 38, 2, 1, 202, 33, 234, 116, 38, 6, 1, 215, 225, + 74, 38, 2, 1, 215, 225, 74, 38, 6, 1, 248, 166, 74, 38, 2, 1, 248, 166, + 74, 38, 6, 1, 55, 215, 225, 74, 38, 2, 1, 55, 215, 225, 74, 38, 1, 215, + 132, 74, 33, 38, 193, 226, 33, 38, 199, 96, 216, 50, 56, 33, 38, 228, + 143, 216, 50, 56, 33, 38, 198, 230, 216, 50, 56, 202, 96, 250, 195, 33, + 38, 1, 196, 125, 223, 228, 33, 38, 1, 68, 33, 38, 1, 192, 33, 33, 38, 1, + 66, 33, 38, 1, 230, 19, 56, 33, 38, 1, 192, 58, 33, 38, 1, 202, 33, 56, + 33, 38, 1, 211, 112, 33, 38, 222, 37, 33, 38, 210, 72, 38, 222, 37, 38, + 210, 72, 38, 6, 1, 235, 47, 38, 2, 1, 235, 47, 38, 6, 1, 235, 23, 38, 2, + 1, 235, 23, 38, 6, 1, 191, 38, 38, 2, 1, 191, 38, 38, 6, 1, 247, 60, 38, + 2, 1, 247, 60, 38, 6, 1, 235, 19, 38, 2, 1, 235, 19, 38, 6, 1, 199, 146, 4, 82, 102, 38, 2, 1, 199, 146, 4, 82, 102, 38, 6, 1, 197, 41, 38, 2, 1, 197, 41, 38, 6, 1, 197, 136, 38, 2, 1, 197, 136, 38, 6, 1, 197, 141, 38, 2, 1, 197, 141, 38, 6, 1, 199, 151, 38, 2, 1, 199, 151, 38, 6, 1, 228, - 122, 38, 2, 1, 228, 122, 38, 6, 1, 202, 237, 38, 2, 1, 202, 237, 38, 6, - 1, 55, 74, 38, 2, 1, 55, 74, 38, 6, 1, 238, 214, 74, 38, 2, 1, 238, 214, - 74, 52, 1, 38, 230, 17, 56, 52, 1, 38, 202, 32, 56, 33, 38, 1, 234, 181, - 33, 38, 1, 223, 81, 71, 26, 1, 65, 26, 1, 155, 26, 1, 66, 26, 1, 220, - 232, 26, 1, 234, 188, 26, 1, 207, 84, 26, 1, 199, 226, 26, 1, 74, 26, 1, - 212, 81, 26, 1, 68, 26, 1, 173, 26, 1, 168, 26, 1, 206, 195, 26, 1, 206, - 242, 26, 1, 219, 227, 26, 1, 216, 210, 26, 1, 199, 245, 26, 1, 214, 160, - 26, 1, 213, 155, 26, 1, 218, 168, 26, 1, 200, 160, 26, 1, 215, 155, 26, - 1, 203, 76, 26, 1, 202, 222, 26, 1, 203, 86, 26, 1, 203, 248, 26, 1, 220, - 149, 26, 1, 221, 241, 26, 1, 212, 146, 26, 1, 212, 178, 26, 1, 213, 126, - 26, 1, 191, 243, 26, 1, 203, 5, 26, 1, 191, 194, 26, 1, 170, 26, 1, 212, - 215, 26, 1, 221, 227, 26, 1, 209, 232, 26, 1, 213, 148, 26, 1, 212, 195, - 26, 1, 208, 156, 26, 1, 192, 253, 26, 1, 210, 49, 26, 1, 233, 52, 26, 1, - 206, 68, 26, 1, 218, 225, 26, 1, 216, 100, 26, 1, 213, 219, 26, 1, 207, - 20, 26, 1, 207, 163, 26, 1, 221, 251, 26, 1, 213, 252, 26, 1, 214, 47, - 26, 1, 214, 68, 26, 1, 203, 56, 26, 1, 208, 161, 26, 1, 232, 86, 26, 1, - 232, 167, 26, 1, 193, 190, 26, 1, 180, 26, 1, 219, 146, 26, 1, 209, 185, - 26, 1, 219, 0, 26, 1, 221, 67, 26, 1, 217, 1, 26, 1, 207, 55, 26, 1, 216, - 186, 26, 1, 174, 26, 1, 198, 193, 26, 1, 221, 166, 26, 1, 216, 12, 26, 1, - 217, 9, 26, 1, 199, 73, 26, 1, 221, 21, 26, 1, 199, 95, 26, 1, 212, 181, - 26, 1, 205, 150, 26, 1, 233, 105, 26, 1, 221, 24, 26, 1, 221, 57, 26, 33, - 87, 221, 34, 26, 33, 87, 197, 79, 26, 213, 154, 26, 232, 80, 201, 63, 26, - 242, 83, 26, 242, 74, 26, 204, 25, 26, 208, 13, 77, 52, 1, 243, 80, 163, - 192, 22, 209, 132, 52, 1, 243, 80, 163, 192, 107, 209, 132, 52, 1, 243, - 80, 163, 192, 22, 203, 137, 52, 1, 243, 80, 163, 192, 107, 203, 137, 52, - 1, 243, 80, 163, 192, 22, 208, 33, 52, 1, 243, 80, 163, 192, 107, 208, - 33, 52, 1, 243, 80, 163, 192, 22, 206, 68, 52, 1, 243, 80, 163, 192, 107, - 206, 68, 52, 1, 233, 200, 235, 138, 163, 164, 52, 1, 137, 235, 138, 163, - 164, 52, 1, 216, 87, 235, 138, 163, 164, 52, 1, 130, 235, 138, 163, 164, - 52, 1, 233, 199, 235, 138, 163, 164, 52, 1, 233, 200, 235, 138, 219, 216, - 163, 164, 52, 1, 137, 235, 138, 219, 216, 163, 164, 52, 1, 216, 87, 235, - 138, 219, 216, 163, 164, 52, 1, 130, 235, 138, 219, 216, 163, 164, 52, 1, - 233, 199, 235, 138, 219, 216, 163, 164, 52, 1, 233, 200, 219, 216, 163, - 164, 52, 1, 137, 219, 216, 163, 164, 52, 1, 216, 87, 219, 216, 163, 164, - 52, 1, 130, 219, 216, 163, 164, 52, 1, 233, 199, 219, 216, 163, 164, 52, - 1, 75, 81, 164, 52, 1, 75, 202, 97, 52, 1, 75, 228, 241, 164, 52, 1, 110, - 50, 239, 2, 251, 115, 52, 1, 207, 147, 133, 57, 52, 1, 207, 147, 144, 57, - 52, 1, 207, 147, 233, 216, 77, 52, 1, 207, 147, 223, 93, 233, 216, 77, - 52, 1, 130, 223, 93, 233, 216, 77, 52, 1, 201, 38, 23, 137, 198, 79, 52, - 1, 201, 38, 23, 130, 198, 79, 8, 6, 1, 234, 175, 251, 192, 8, 2, 1, 234, - 175, 251, 192, 8, 6, 1, 234, 175, 251, 230, 8, 2, 1, 234, 175, 251, 230, - 8, 6, 1, 229, 196, 8, 2, 1, 229, 196, 8, 6, 1, 196, 241, 8, 2, 1, 196, - 241, 8, 6, 1, 197, 248, 8, 2, 1, 197, 248, 8, 6, 1, 238, 192, 8, 2, 1, - 238, 192, 8, 6, 1, 238, 193, 4, 242, 74, 8, 2, 1, 238, 193, 4, 242, 74, - 8, 1, 2, 6, 233, 175, 8, 1, 2, 6, 206, 8, 8, 6, 1, 252, 206, 8, 2, 1, - 252, 206, 8, 6, 1, 251, 68, 8, 2, 1, 251, 68, 8, 6, 1, 250, 163, 8, 2, 1, - 250, 163, 8, 6, 1, 250, 146, 8, 2, 1, 250, 146, 8, 6, 1, 250, 147, 4, - 228, 241, 164, 8, 2, 1, 250, 147, 4, 228, 241, 164, 8, 6, 1, 250, 131, 8, - 2, 1, 250, 131, 8, 6, 1, 207, 18, 247, 194, 4, 236, 140, 8, 2, 1, 207, - 18, 247, 194, 4, 236, 140, 8, 6, 1, 222, 153, 4, 106, 8, 2, 1, 222, 153, - 4, 106, 8, 6, 1, 222, 153, 4, 237, 39, 106, 8, 2, 1, 222, 153, 4, 237, - 39, 106, 8, 6, 1, 222, 153, 4, 201, 28, 23, 237, 39, 106, 8, 2, 1, 222, - 153, 4, 201, 28, 23, 237, 39, 106, 8, 6, 1, 248, 22, 172, 8, 2, 1, 248, - 22, 172, 8, 6, 1, 220, 143, 4, 137, 106, 8, 2, 1, 220, 143, 4, 137, 106, - 8, 6, 1, 187, 4, 179, 201, 28, 210, 255, 8, 2, 1, 187, 4, 179, 201, 28, - 210, 255, 8, 6, 1, 187, 4, 219, 4, 8, 2, 1, 187, 4, 219, 4, 8, 6, 1, 211, - 87, 8, 2, 1, 211, 87, 8, 6, 1, 210, 237, 4, 201, 28, 198, 216, 237, 87, - 8, 2, 1, 210, 237, 4, 201, 28, 198, 216, 237, 87, 8, 6, 1, 210, 237, 4, - 232, 188, 8, 2, 1, 210, 237, 4, 232, 188, 8, 6, 1, 210, 237, 4, 201, 182, - 199, 215, 8, 2, 1, 210, 237, 4, 201, 182, 199, 215, 8, 6, 1, 208, 105, 4, - 201, 28, 198, 216, 237, 87, 8, 2, 1, 208, 105, 4, 201, 28, 198, 216, 237, - 87, 8, 6, 1, 208, 105, 4, 237, 39, 106, 8, 2, 1, 208, 105, 4, 237, 39, - 106, 8, 6, 1, 207, 222, 206, 116, 8, 2, 1, 207, 222, 206, 116, 8, 6, 1, - 206, 49, 206, 116, 8, 2, 1, 206, 49, 206, 116, 8, 6, 1, 196, 13, 4, 237, - 39, 106, 8, 2, 1, 196, 13, 4, 237, 39, 106, 8, 6, 1, 193, 235, 8, 2, 1, + 124, 38, 2, 1, 228, 124, 38, 6, 1, 202, 238, 38, 2, 1, 202, 238, 38, 6, + 1, 55, 74, 38, 2, 1, 55, 74, 38, 6, 1, 238, 216, 74, 38, 2, 1, 238, 216, + 74, 52, 1, 38, 230, 19, 56, 52, 1, 38, 202, 33, 56, 33, 38, 1, 234, 183, + 33, 38, 1, 223, 83, 71, 26, 1, 65, 26, 1, 155, 26, 1, 66, 26, 1, 220, + 234, 26, 1, 234, 190, 26, 1, 207, 86, 26, 1, 199, 226, 26, 1, 74, 26, 1, + 212, 83, 26, 1, 68, 26, 1, 173, 26, 1, 168, 26, 1, 206, 196, 26, 1, 206, + 243, 26, 1, 219, 229, 26, 1, 216, 212, 26, 1, 199, 245, 26, 1, 214, 162, + 26, 1, 213, 157, 26, 1, 218, 170, 26, 1, 200, 160, 26, 1, 215, 157, 26, + 1, 203, 77, 26, 1, 202, 223, 26, 1, 203, 87, 26, 1, 203, 249, 26, 1, 220, + 151, 26, 1, 221, 243, 26, 1, 212, 148, 26, 1, 212, 180, 26, 1, 213, 128, + 26, 1, 191, 243, 26, 1, 203, 6, 26, 1, 191, 194, 26, 1, 170, 26, 1, 212, + 217, 26, 1, 221, 229, 26, 1, 209, 234, 26, 1, 213, 150, 26, 1, 212, 197, + 26, 1, 208, 158, 26, 1, 192, 253, 26, 1, 210, 51, 26, 1, 233, 54, 26, 1, + 206, 69, 26, 1, 218, 227, 26, 1, 216, 102, 26, 1, 213, 221, 26, 1, 207, + 21, 26, 1, 207, 165, 26, 1, 221, 253, 26, 1, 213, 254, 26, 1, 214, 49, + 26, 1, 214, 70, 26, 1, 203, 57, 26, 1, 208, 163, 26, 1, 232, 88, 26, 1, + 232, 169, 26, 1, 193, 190, 26, 1, 181, 26, 1, 219, 148, 26, 1, 209, 187, + 26, 1, 219, 2, 26, 1, 221, 69, 26, 1, 217, 3, 26, 1, 207, 56, 26, 1, 216, + 188, 26, 1, 174, 26, 1, 198, 193, 26, 1, 221, 168, 26, 1, 216, 14, 26, 1, + 217, 11, 26, 1, 199, 73, 26, 1, 221, 23, 26, 1, 199, 95, 26, 1, 212, 183, + 26, 1, 205, 151, 26, 1, 233, 107, 26, 1, 221, 26, 26, 1, 221, 59, 26, 33, + 87, 221, 36, 26, 33, 87, 197, 79, 26, 213, 156, 26, 232, 82, 201, 64, 26, + 242, 85, 26, 242, 76, 26, 204, 26, 26, 208, 15, 77, 52, 1, 243, 82, 163, + 192, 22, 209, 134, 52, 1, 243, 82, 163, 192, 107, 209, 134, 52, 1, 243, + 82, 163, 192, 22, 203, 138, 52, 1, 243, 82, 163, 192, 107, 203, 138, 52, + 1, 243, 82, 163, 192, 22, 208, 35, 52, 1, 243, 82, 163, 192, 107, 208, + 35, 52, 1, 243, 82, 163, 192, 22, 206, 69, 52, 1, 243, 82, 163, 192, 107, + 206, 69, 52, 1, 233, 202, 235, 140, 163, 164, 52, 1, 137, 235, 140, 163, + 164, 52, 1, 216, 89, 235, 140, 163, 164, 52, 1, 130, 235, 140, 163, 164, + 52, 1, 233, 201, 235, 140, 163, 164, 52, 1, 233, 202, 235, 140, 219, 218, + 163, 164, 52, 1, 137, 235, 140, 219, 218, 163, 164, 52, 1, 216, 89, 235, + 140, 219, 218, 163, 164, 52, 1, 130, 235, 140, 219, 218, 163, 164, 52, 1, + 233, 201, 235, 140, 219, 218, 163, 164, 52, 1, 233, 202, 219, 218, 163, + 164, 52, 1, 137, 219, 218, 163, 164, 52, 1, 216, 89, 219, 218, 163, 164, + 52, 1, 130, 219, 218, 163, 164, 52, 1, 233, 201, 219, 218, 163, 164, 52, + 1, 75, 81, 164, 52, 1, 75, 202, 98, 52, 1, 75, 228, 243, 164, 52, 1, 110, + 50, 239, 4, 251, 117, 52, 1, 207, 149, 133, 57, 52, 1, 207, 149, 144, 57, + 52, 1, 207, 149, 233, 218, 77, 52, 1, 207, 149, 223, 95, 233, 218, 77, + 52, 1, 130, 223, 95, 233, 218, 77, 52, 1, 201, 39, 23, 137, 198, 79, 52, + 1, 201, 39, 23, 130, 198, 79, 8, 6, 1, 234, 177, 251, 194, 8, 2, 1, 234, + 177, 251, 194, 8, 6, 1, 234, 177, 251, 232, 8, 2, 1, 234, 177, 251, 232, + 8, 6, 1, 229, 198, 8, 2, 1, 229, 198, 8, 6, 1, 196, 241, 8, 2, 1, 196, + 241, 8, 6, 1, 197, 248, 8, 2, 1, 197, 248, 8, 6, 1, 238, 194, 8, 2, 1, + 238, 194, 8, 6, 1, 238, 195, 4, 242, 76, 8, 2, 1, 238, 195, 4, 242, 76, + 8, 1, 2, 6, 233, 177, 8, 1, 2, 6, 206, 9, 8, 6, 1, 252, 208, 8, 2, 1, + 252, 208, 8, 6, 1, 251, 70, 8, 2, 1, 251, 70, 8, 6, 1, 250, 165, 8, 2, 1, + 250, 165, 8, 6, 1, 250, 148, 8, 2, 1, 250, 148, 8, 6, 1, 250, 149, 4, + 228, 243, 164, 8, 2, 1, 250, 149, 4, 228, 243, 164, 8, 6, 1, 250, 133, 8, + 2, 1, 250, 133, 8, 6, 1, 207, 19, 247, 196, 4, 236, 142, 8, 2, 1, 207, + 19, 247, 196, 4, 236, 142, 8, 6, 1, 222, 155, 4, 106, 8, 2, 1, 222, 155, + 4, 106, 8, 6, 1, 222, 155, 4, 237, 41, 106, 8, 2, 1, 222, 155, 4, 237, + 41, 106, 8, 6, 1, 222, 155, 4, 201, 29, 23, 237, 41, 106, 8, 2, 1, 222, + 155, 4, 201, 29, 23, 237, 41, 106, 8, 6, 1, 248, 24, 172, 8, 2, 1, 248, + 24, 172, 8, 6, 1, 220, 145, 4, 137, 106, 8, 2, 1, 220, 145, 4, 137, 106, + 8, 6, 1, 187, 4, 180, 201, 29, 211, 1, 8, 2, 1, 187, 4, 180, 201, 29, + 211, 1, 8, 6, 1, 187, 4, 219, 6, 8, 2, 1, 187, 4, 219, 6, 8, 6, 1, 211, + 89, 8, 2, 1, 211, 89, 8, 6, 1, 210, 239, 4, 201, 29, 198, 216, 237, 89, + 8, 2, 1, 210, 239, 4, 201, 29, 198, 216, 237, 89, 8, 6, 1, 210, 239, 4, + 232, 190, 8, 2, 1, 210, 239, 4, 232, 190, 8, 6, 1, 210, 239, 4, 201, 183, + 199, 215, 8, 2, 1, 210, 239, 4, 201, 183, 199, 215, 8, 6, 1, 208, 107, 4, + 201, 29, 198, 216, 237, 89, 8, 2, 1, 208, 107, 4, 201, 29, 198, 216, 237, + 89, 8, 6, 1, 208, 107, 4, 237, 41, 106, 8, 2, 1, 208, 107, 4, 237, 41, + 106, 8, 6, 1, 207, 224, 206, 117, 8, 2, 1, 207, 224, 206, 117, 8, 6, 1, + 206, 50, 206, 117, 8, 2, 1, 206, 50, 206, 117, 8, 6, 1, 196, 13, 4, 237, + 41, 106, 8, 2, 1, 196, 13, 4, 237, 41, 106, 8, 6, 1, 193, 235, 8, 2, 1, 193, 235, 8, 6, 1, 195, 33, 191, 166, 8, 2, 1, 195, 33, 191, 166, 8, 6, 1, 198, 234, 4, 106, 8, 2, 1, 198, 234, 4, 106, 8, 6, 1, 198, 234, 4, - 201, 28, 198, 216, 237, 87, 8, 2, 1, 198, 234, 4, 201, 28, 198, 216, 237, - 87, 8, 6, 1, 195, 142, 8, 2, 1, 195, 142, 8, 6, 1, 233, 255, 8, 2, 1, - 233, 255, 8, 6, 1, 223, 68, 8, 2, 1, 223, 68, 8, 6, 1, 239, 57, 8, 2, 1, - 239, 57, 52, 1, 196, 45, 8, 2, 1, 235, 77, 8, 2, 1, 218, 208, 8, 2, 1, - 215, 123, 8, 2, 1, 212, 137, 8, 2, 1, 206, 48, 8, 1, 2, 6, 206, 48, 8, 2, - 1, 197, 76, 8, 2, 1, 196, 120, 8, 6, 1, 223, 115, 238, 127, 8, 2, 1, 223, - 115, 238, 127, 8, 6, 1, 223, 115, 233, 175, 8, 2, 1, 223, 115, 233, 175, - 8, 6, 1, 223, 115, 232, 51, 8, 6, 1, 153, 223, 115, 232, 51, 8, 2, 1, - 153, 223, 115, 232, 51, 8, 6, 1, 153, 172, 8, 2, 1, 153, 172, 8, 6, 1, - 223, 115, 146, 8, 2, 1, 223, 115, 146, 8, 6, 1, 223, 115, 206, 8, 8, 2, - 1, 223, 115, 206, 8, 8, 6, 1, 223, 115, 200, 43, 8, 2, 1, 223, 115, 200, - 43, 52, 1, 130, 243, 2, 252, 60, 52, 1, 242, 83, 52, 1, 203, 40, 234, 43, - 56, 8, 6, 1, 205, 156, 8, 2, 1, 205, 156, 8, 6, 1, 153, 230, 116, 8, 2, - 1, 220, 143, 4, 207, 24, 228, 251, 23, 248, 231, 8, 1, 202, 163, 236, - 140, 8, 6, 1, 215, 62, 4, 237, 87, 8, 2, 1, 215, 62, 4, 237, 87, 8, 6, 1, - 247, 194, 4, 164, 8, 2, 1, 247, 194, 4, 164, 8, 2, 1, 247, 194, 4, 210, - 192, 102, 8, 2, 1, 230, 117, 4, 210, 192, 102, 8, 6, 1, 78, 4, 232, 188, - 8, 2, 1, 78, 4, 232, 188, 8, 6, 1, 233, 176, 4, 106, 8, 2, 1, 233, 176, - 4, 106, 8, 6, 1, 195, 15, 252, 25, 8, 2, 1, 195, 15, 252, 25, 8, 6, 1, - 195, 15, 211, 151, 8, 2, 1, 195, 15, 211, 151, 8, 6, 1, 195, 15, 196, - 152, 8, 2, 1, 195, 15, 196, 152, 8, 6, 1, 232, 52, 4, 211, 172, 106, 8, - 2, 1, 232, 52, 4, 211, 172, 106, 8, 6, 1, 222, 153, 4, 211, 172, 106, 8, - 2, 1, 222, 153, 4, 211, 172, 106, 8, 6, 1, 215, 62, 4, 211, 172, 106, 8, - 2, 1, 215, 62, 4, 211, 172, 106, 8, 6, 1, 207, 222, 4, 211, 172, 106, 8, - 2, 1, 207, 222, 4, 211, 172, 106, 8, 6, 1, 206, 9, 4, 211, 172, 106, 8, - 2, 1, 206, 9, 4, 211, 172, 106, 8, 6, 1, 230, 117, 4, 102, 8, 6, 1, 207, - 18, 211, 77, 71, 8, 6, 1, 27, 232, 51, 8, 6, 1, 220, 143, 4, 248, 231, 8, - 6, 1, 2, 6, 68, 8, 1, 2, 6, 208, 104, 8, 6, 1, 153, 222, 152, 8, 6, 1, - 153, 200, 43, 8, 6, 1, 223, 36, 4, 238, 212, 8, 6, 1, 243, 95, 8, 6, 1, - 248, 212, 8, 2, 1, 248, 212, 8, 6, 1, 211, 110, 8, 2, 1, 211, 110, 8, 6, - 1, 126, 4, 106, 8, 2, 1, 126, 4, 106, 8, 6, 1, 231, 11, 65, 8, 2, 1, 231, - 11, 65, 8, 6, 1, 231, 11, 68, 8, 2, 1, 231, 11, 68, 8, 6, 1, 231, 11, 66, - 8, 2, 1, 231, 11, 66, 8, 6, 1, 39, 209, 49, 74, 8, 2, 1, 39, 209, 49, 74, - 8, 6, 1, 251, 112, 193, 224, 8, 2, 1, 251, 112, 193, 224, 8, 6, 1, 247, - 194, 4, 210, 192, 102, 8, 6, 1, 206, 9, 4, 102, 8, 6, 1, 191, 167, 4, - 210, 192, 102, 8, 6, 1, 238, 128, 4, 203, 40, 201, 28, 210, 255, 8, 2, 1, - 238, 128, 4, 203, 40, 201, 28, 210, 255, 8, 6, 1, 206, 9, 4, 203, 40, - 201, 28, 210, 255, 8, 2, 1, 206, 9, 4, 203, 40, 201, 28, 210, 255, 8, 6, - 1, 242, 219, 223, 115, 232, 51, 8, 2, 1, 242, 219, 223, 115, 232, 51, 8, - 2, 1, 55, 198, 233, 8, 2, 1, 55, 192, 238, 8, 6, 1, 82, 205, 79, 206, 8, - 8, 2, 1, 82, 205, 79, 206, 8, 8, 6, 1, 202, 195, 206, 8, 8, 2, 1, 202, - 195, 206, 8, 52, 1, 6, 247, 193, 52, 1, 6, 233, 175, 52, 1, 6, 208, 104, - 8, 6, 1, 207, 18, 132, 230, 116, 8, 2, 1, 207, 18, 132, 230, 116, 8, 234, - 50, 1, 202, 206, 68, 52, 1, 6, 230, 117, 4, 106, 52, 1, 2, 34, 211, 151, - 8, 1, 2, 6, 153, 218, 168, 8, 234, 50, 1, 207, 18, 233, 175, 8, 234, 50, - 1, 207, 18, 210, 236, 8, 234, 50, 1, 223, 93, 218, 168, 8, 234, 50, 1, - 228, 74, 219, 10, 8, 234, 50, 1, 251, 14, 218, 168, 200, 124, 214, 238, - 1, 65, 200, 124, 214, 238, 1, 68, 200, 124, 214, 238, 3, 235, 54, 200, - 124, 214, 238, 1, 66, 200, 124, 214, 238, 1, 71, 200, 124, 214, 238, 1, - 74, 200, 124, 214, 238, 3, 230, 11, 200, 124, 214, 238, 1, 221, 67, 200, - 124, 214, 238, 1, 221, 183, 200, 124, 214, 238, 1, 231, 3, 200, 124, 214, - 238, 1, 231, 63, 200, 124, 214, 238, 3, 251, 71, 200, 124, 214, 238, 1, - 242, 99, 200, 124, 214, 238, 1, 243, 68, 200, 124, 214, 238, 1, 222, 201, - 200, 124, 214, 238, 1, 222, 246, 200, 124, 214, 238, 1, 197, 109, 200, - 124, 214, 238, 1, 197, 115, 200, 124, 214, 238, 1, 237, 161, 200, 124, - 214, 238, 1, 237, 170, 200, 124, 214, 238, 1, 159, 200, 124, 214, 238, 1, - 198, 241, 200, 124, 214, 238, 1, 236, 174, 200, 124, 214, 238, 1, 237, - 48, 200, 124, 214, 238, 1, 213, 43, 200, 124, 214, 238, 1, 209, 73, 200, - 124, 214, 238, 1, 209, 199, 200, 124, 214, 238, 1, 248, 111, 200, 124, - 214, 238, 1, 248, 192, 200, 124, 214, 238, 1, 216, 12, 200, 124, 214, - 238, 1, 206, 162, 200, 124, 214, 238, 1, 219, 43, 200, 124, 214, 238, 1, - 206, 95, 200, 124, 214, 238, 1, 202, 46, 200, 124, 214, 238, 1, 229, 23, - 200, 124, 214, 238, 18, 3, 65, 200, 124, 214, 238, 18, 3, 68, 200, 124, - 214, 238, 18, 3, 66, 200, 124, 214, 238, 18, 3, 71, 200, 124, 214, 238, - 18, 3, 211, 87, 200, 124, 214, 238, 209, 63, 217, 55, 200, 124, 214, 238, - 209, 63, 217, 54, 200, 124, 214, 238, 209, 63, 217, 53, 200, 124, 214, - 238, 209, 63, 217, 52, 200, 124, 214, 238, 3, 251, 157, 230, 11, 186, - 223, 146, 232, 118, 91, 208, 22, 186, 223, 146, 232, 118, 91, 230, 70, - 186, 223, 146, 232, 118, 115, 208, 20, 186, 223, 146, 232, 118, 91, 202, - 128, 186, 223, 146, 232, 118, 91, 234, 159, 186, 223, 146, 232, 118, 115, - 202, 125, 186, 223, 146, 208, 23, 77, 186, 223, 146, 209, 107, 77, 186, - 223, 146, 206, 36, 77, 186, 223, 146, 208, 25, 77, 209, 224, 1, 155, 209, - 224, 1, 221, 215, 209, 224, 1, 231, 240, 209, 224, 1, 214, 68, 209, 224, - 1, 247, 160, 209, 224, 1, 247, 1, 209, 224, 1, 223, 32, 209, 224, 1, 212, - 101, 209, 224, 1, 190, 190, 209, 224, 1, 199, 49, 209, 224, 1, 238, 32, - 209, 224, 1, 180, 209, 224, 1, 168, 209, 224, 1, 209, 228, 209, 224, 1, - 249, 153, 209, 224, 1, 174, 209, 224, 1, 197, 168, 209, 224, 1, 197, 157, - 209, 224, 1, 235, 35, 209, 224, 1, 193, 190, 209, 224, 1, 191, 71, 209, - 224, 1, 191, 123, 209, 224, 1, 2, 65, 209, 224, 1, 170, 209, 224, 1, 165, - 209, 224, 1, 173, 209, 224, 1, 203, 165, 209, 224, 1, 188, 209, 224, 1, - 140, 209, 224, 1, 65, 209, 224, 1, 68, 209, 224, 1, 66, 209, 224, 1, 71, - 209, 224, 1, 74, 209, 224, 1, 208, 96, 209, 224, 1, 192, 220, 209, 224, - 1, 233, 109, 209, 224, 1, 231, 127, 209, 224, 1, 234, 188, 209, 224, 200, - 239, 1, 193, 190, 209, 224, 200, 239, 1, 170, 209, 224, 1, 197, 132, 209, - 224, 1, 197, 120, 209, 224, 1, 237, 191, 209, 224, 1, 213, 79, 209, 224, - 1, 251, 157, 170, 209, 224, 1, 195, 19, 203, 165, 209, 224, 1, 195, 20, - 140, 209, 224, 1, 250, 200, 233, 109, 209, 224, 200, 239, 1, 165, 209, - 224, 200, 185, 1, 165, 209, 224, 1, 247, 119, 209, 224, 202, 170, 229, - 236, 77, 209, 224, 55, 229, 236, 77, 209, 224, 87, 203, 157, 209, 224, - 87, 55, 203, 157, 205, 111, 3, 251, 71, 205, 111, 3, 195, 35, 205, 111, - 1, 65, 205, 111, 1, 252, 206, 205, 111, 1, 68, 205, 111, 1, 223, 199, - 205, 111, 1, 66, 205, 111, 1, 196, 30, 205, 111, 1, 117, 146, 205, 111, - 1, 117, 206, 110, 205, 111, 1, 117, 172, 205, 111, 1, 117, 219, 74, 205, - 111, 1, 71, 205, 111, 1, 234, 188, 205, 111, 1, 251, 236, 205, 111, 1, - 74, 205, 111, 1, 211, 87, 205, 111, 1, 250, 163, 205, 111, 1, 155, 205, - 111, 1, 221, 215, 205, 111, 1, 231, 240, 205, 111, 1, 231, 91, 205, 111, - 1, 214, 68, 205, 111, 1, 247, 160, 205, 111, 1, 247, 1, 205, 111, 1, 223, - 32, 205, 111, 1, 222, 252, 205, 111, 1, 212, 101, 205, 111, 1, 197, 132, - 205, 111, 1, 197, 120, 205, 111, 1, 237, 191, 205, 111, 1, 237, 175, 205, - 111, 1, 213, 79, 205, 111, 1, 190, 190, 205, 111, 1, 199, 49, 205, 111, - 1, 238, 32, 205, 111, 1, 237, 68, 205, 111, 1, 180, 205, 111, 1, 168, - 205, 111, 1, 209, 228, 205, 111, 1, 249, 153, 205, 111, 1, 248, 203, 205, - 111, 1, 174, 205, 111, 1, 170, 205, 111, 1, 165, 205, 111, 1, 173, 205, - 111, 1, 195, 188, 205, 111, 1, 203, 165, 205, 111, 1, 201, 175, 205, 111, - 1, 188, 205, 111, 1, 140, 205, 111, 1, 219, 73, 205, 111, 120, 3, 230, - 89, 205, 111, 18, 3, 252, 206, 205, 111, 18, 3, 68, 205, 111, 18, 3, 223, - 199, 205, 111, 18, 3, 66, 205, 111, 18, 3, 196, 30, 205, 111, 18, 3, 117, - 146, 205, 111, 18, 3, 117, 206, 110, 205, 111, 18, 3, 117, 172, 205, 111, - 18, 3, 117, 219, 74, 205, 111, 18, 3, 71, 205, 111, 18, 3, 234, 188, 205, - 111, 18, 3, 251, 236, 205, 111, 18, 3, 74, 205, 111, 18, 3, 211, 87, 205, - 111, 18, 3, 250, 163, 205, 111, 3, 195, 40, 205, 111, 3, 247, 119, 205, - 111, 237, 238, 205, 111, 55, 237, 238, 205, 111, 17, 191, 77, 205, 111, - 17, 107, 205, 111, 17, 109, 205, 111, 17, 138, 205, 111, 17, 134, 205, - 111, 17, 149, 205, 111, 17, 169, 205, 111, 17, 175, 205, 111, 17, 171, - 205, 111, 17, 178, 33, 100, 17, 191, 77, 33, 100, 17, 107, 33, 100, 17, - 109, 33, 100, 17, 138, 33, 100, 17, 134, 33, 100, 17, 149, 33, 100, 17, + 201, 29, 198, 216, 237, 89, 8, 2, 1, 198, 234, 4, 201, 29, 198, 216, 237, + 89, 8, 6, 1, 195, 142, 8, 2, 1, 195, 142, 8, 6, 1, 234, 1, 8, 2, 1, 234, + 1, 8, 6, 1, 223, 70, 8, 2, 1, 223, 70, 8, 6, 1, 239, 59, 8, 2, 1, 239, + 59, 52, 1, 196, 45, 8, 2, 1, 235, 79, 8, 2, 1, 218, 210, 8, 2, 1, 215, + 125, 8, 2, 1, 212, 139, 8, 2, 1, 206, 49, 8, 1, 2, 6, 206, 49, 8, 2, 1, + 197, 76, 8, 2, 1, 196, 120, 8, 6, 1, 223, 117, 238, 129, 8, 2, 1, 223, + 117, 238, 129, 8, 6, 1, 223, 117, 233, 177, 8, 2, 1, 223, 117, 233, 177, + 8, 6, 1, 223, 117, 232, 53, 8, 6, 1, 154, 223, 117, 232, 53, 8, 2, 1, + 154, 223, 117, 232, 53, 8, 6, 1, 154, 172, 8, 2, 1, 154, 172, 8, 6, 1, + 223, 117, 146, 8, 2, 1, 223, 117, 146, 8, 6, 1, 223, 117, 206, 9, 8, 2, + 1, 223, 117, 206, 9, 8, 6, 1, 223, 117, 200, 43, 8, 2, 1, 223, 117, 200, + 43, 52, 1, 130, 243, 4, 252, 62, 52, 1, 242, 85, 52, 1, 203, 41, 234, 45, + 56, 8, 6, 1, 205, 157, 8, 2, 1, 205, 157, 8, 6, 1, 154, 230, 118, 8, 2, + 1, 220, 145, 4, 207, 25, 228, 253, 23, 248, 233, 8, 1, 202, 164, 236, + 142, 8, 6, 1, 215, 64, 4, 237, 89, 8, 2, 1, 215, 64, 4, 237, 89, 8, 6, 1, + 247, 196, 4, 164, 8, 2, 1, 247, 196, 4, 164, 8, 2, 1, 247, 196, 4, 210, + 194, 102, 8, 2, 1, 230, 119, 4, 210, 194, 102, 8, 6, 1, 78, 4, 232, 190, + 8, 2, 1, 78, 4, 232, 190, 8, 6, 1, 233, 178, 4, 106, 8, 2, 1, 233, 178, + 4, 106, 8, 6, 1, 195, 15, 252, 27, 8, 2, 1, 195, 15, 252, 27, 8, 6, 1, + 195, 15, 211, 153, 8, 2, 1, 195, 15, 211, 153, 8, 6, 1, 195, 15, 196, + 152, 8, 2, 1, 195, 15, 196, 152, 8, 6, 1, 232, 54, 4, 211, 174, 106, 8, + 2, 1, 232, 54, 4, 211, 174, 106, 8, 6, 1, 222, 155, 4, 211, 174, 106, 8, + 2, 1, 222, 155, 4, 211, 174, 106, 8, 6, 1, 215, 64, 4, 211, 174, 106, 8, + 2, 1, 215, 64, 4, 211, 174, 106, 8, 6, 1, 207, 224, 4, 211, 174, 106, 8, + 2, 1, 207, 224, 4, 211, 174, 106, 8, 6, 1, 206, 10, 4, 211, 174, 106, 8, + 2, 1, 206, 10, 4, 211, 174, 106, 8, 6, 1, 230, 119, 4, 102, 8, 6, 1, 207, + 19, 211, 79, 71, 8, 6, 1, 27, 232, 53, 8, 6, 1, 220, 145, 4, 248, 233, 8, + 6, 1, 2, 6, 68, 8, 1, 2, 6, 208, 106, 8, 6, 1, 154, 222, 154, 8, 6, 1, + 154, 200, 43, 8, 6, 1, 223, 38, 4, 238, 214, 8, 6, 1, 243, 97, 8, 6, 1, + 248, 214, 8, 2, 1, 248, 214, 8, 6, 1, 211, 112, 8, 2, 1, 211, 112, 8, 6, + 1, 126, 4, 106, 8, 2, 1, 126, 4, 106, 8, 6, 1, 231, 13, 65, 8, 2, 1, 231, + 13, 65, 8, 6, 1, 231, 13, 68, 8, 2, 1, 231, 13, 68, 8, 6, 1, 231, 13, 66, + 8, 2, 1, 231, 13, 66, 8, 6, 1, 39, 209, 51, 74, 8, 2, 1, 39, 209, 51, 74, + 8, 6, 1, 251, 114, 193, 224, 8, 2, 1, 251, 114, 193, 224, 8, 6, 1, 247, + 196, 4, 210, 194, 102, 8, 6, 1, 206, 10, 4, 102, 8, 6, 1, 191, 167, 4, + 210, 194, 102, 8, 6, 1, 238, 130, 4, 203, 41, 201, 29, 211, 1, 8, 2, 1, + 238, 130, 4, 203, 41, 201, 29, 211, 1, 8, 6, 1, 206, 10, 4, 203, 41, 201, + 29, 211, 1, 8, 2, 1, 206, 10, 4, 203, 41, 201, 29, 211, 1, 8, 6, 1, 242, + 221, 223, 117, 232, 53, 8, 2, 1, 242, 221, 223, 117, 232, 53, 8, 2, 1, + 55, 198, 233, 8, 2, 1, 55, 192, 238, 8, 6, 1, 82, 205, 80, 206, 9, 8, 2, + 1, 82, 205, 80, 206, 9, 8, 6, 1, 202, 196, 206, 9, 8, 2, 1, 202, 196, + 206, 9, 52, 1, 6, 247, 195, 52, 1, 6, 233, 177, 52, 1, 6, 208, 106, 8, 6, + 1, 207, 19, 132, 230, 118, 8, 2, 1, 207, 19, 132, 230, 118, 8, 234, 52, + 1, 202, 207, 68, 52, 1, 6, 230, 119, 4, 106, 52, 1, 2, 34, 211, 153, 8, + 1, 2, 6, 154, 218, 170, 8, 234, 52, 1, 207, 19, 233, 177, 8, 234, 52, 1, + 207, 19, 210, 238, 8, 234, 52, 1, 223, 95, 218, 170, 8, 234, 52, 1, 228, + 76, 219, 12, 8, 234, 52, 1, 251, 16, 218, 170, 200, 124, 214, 240, 1, 65, + 200, 124, 214, 240, 1, 68, 200, 124, 214, 240, 3, 235, 56, 200, 124, 214, + 240, 1, 66, 200, 124, 214, 240, 1, 71, 200, 124, 214, 240, 1, 74, 200, + 124, 214, 240, 3, 230, 13, 200, 124, 214, 240, 1, 221, 69, 200, 124, 214, + 240, 1, 221, 185, 200, 124, 214, 240, 1, 231, 5, 200, 124, 214, 240, 1, + 231, 65, 200, 124, 214, 240, 3, 251, 73, 200, 124, 214, 240, 1, 242, 101, + 200, 124, 214, 240, 1, 243, 70, 200, 124, 214, 240, 1, 222, 203, 200, + 124, 214, 240, 1, 222, 248, 200, 124, 214, 240, 1, 197, 109, 200, 124, + 214, 240, 1, 197, 115, 200, 124, 214, 240, 1, 237, 163, 200, 124, 214, + 240, 1, 237, 172, 200, 124, 214, 240, 1, 159, 200, 124, 214, 240, 1, 198, + 241, 200, 124, 214, 240, 1, 236, 176, 200, 124, 214, 240, 1, 237, 50, + 200, 124, 214, 240, 1, 213, 45, 200, 124, 214, 240, 1, 209, 75, 200, 124, + 214, 240, 1, 209, 201, 200, 124, 214, 240, 1, 248, 113, 200, 124, 214, + 240, 1, 248, 194, 200, 124, 214, 240, 1, 216, 14, 200, 124, 214, 240, 1, + 206, 163, 200, 124, 214, 240, 1, 219, 45, 200, 124, 214, 240, 1, 206, 96, + 200, 124, 214, 240, 1, 202, 47, 200, 124, 214, 240, 1, 229, 25, 200, 124, + 214, 240, 18, 3, 65, 200, 124, 214, 240, 18, 3, 68, 200, 124, 214, 240, + 18, 3, 66, 200, 124, 214, 240, 18, 3, 71, 200, 124, 214, 240, 18, 3, 211, + 89, 200, 124, 214, 240, 209, 65, 217, 57, 200, 124, 214, 240, 209, 65, + 217, 56, 200, 124, 214, 240, 209, 65, 217, 55, 200, 124, 214, 240, 209, + 65, 217, 54, 200, 124, 214, 240, 3, 251, 159, 230, 13, 186, 223, 148, + 232, 120, 91, 208, 24, 186, 223, 148, 232, 120, 91, 230, 72, 186, 223, + 148, 232, 120, 115, 208, 22, 186, 223, 148, 232, 120, 91, 202, 129, 186, + 223, 148, 232, 120, 91, 234, 161, 186, 223, 148, 232, 120, 115, 202, 126, + 186, 223, 148, 208, 25, 77, 186, 223, 148, 209, 109, 77, 186, 223, 148, + 206, 37, 77, 186, 223, 148, 208, 27, 77, 209, 226, 1, 155, 209, 226, 1, + 221, 217, 209, 226, 1, 231, 242, 209, 226, 1, 214, 70, 209, 226, 1, 247, + 162, 209, 226, 1, 247, 3, 209, 226, 1, 223, 34, 209, 226, 1, 212, 103, + 209, 226, 1, 190, 190, 209, 226, 1, 199, 49, 209, 226, 1, 238, 34, 209, + 226, 1, 181, 209, 226, 1, 168, 209, 226, 1, 209, 230, 209, 226, 1, 249, + 155, 209, 226, 1, 174, 209, 226, 1, 197, 168, 209, 226, 1, 197, 157, 209, + 226, 1, 235, 37, 209, 226, 1, 193, 190, 209, 226, 1, 191, 71, 209, 226, + 1, 191, 123, 209, 226, 1, 2, 65, 209, 226, 1, 170, 209, 226, 1, 165, 209, + 226, 1, 173, 209, 226, 1, 203, 166, 209, 226, 1, 188, 209, 226, 1, 140, + 209, 226, 1, 65, 209, 226, 1, 68, 209, 226, 1, 66, 209, 226, 1, 71, 209, + 226, 1, 74, 209, 226, 1, 208, 98, 209, 226, 1, 192, 220, 209, 226, 1, + 233, 111, 209, 226, 1, 231, 129, 209, 226, 1, 234, 190, 209, 226, 200, + 240, 1, 193, 190, 209, 226, 200, 240, 1, 170, 209, 226, 1, 197, 132, 209, + 226, 1, 197, 120, 209, 226, 1, 237, 193, 209, 226, 1, 213, 81, 209, 226, + 1, 251, 159, 170, 209, 226, 1, 195, 19, 203, 166, 209, 226, 1, 195, 20, + 140, 209, 226, 1, 250, 202, 233, 111, 209, 226, 200, 240, 1, 165, 209, + 226, 200, 185, 1, 165, 209, 226, 1, 247, 121, 209, 226, 202, 171, 229, + 238, 77, 209, 226, 55, 229, 238, 77, 209, 226, 87, 203, 158, 209, 226, + 87, 55, 203, 158, 205, 112, 3, 251, 73, 205, 112, 3, 195, 35, 205, 112, + 1, 65, 205, 112, 1, 252, 208, 205, 112, 1, 68, 205, 112, 1, 223, 201, + 205, 112, 1, 66, 205, 112, 1, 196, 30, 205, 112, 1, 117, 146, 205, 112, + 1, 117, 206, 111, 205, 112, 1, 117, 172, 205, 112, 1, 117, 219, 76, 205, + 112, 1, 71, 205, 112, 1, 234, 190, 205, 112, 1, 251, 238, 205, 112, 1, + 74, 205, 112, 1, 211, 89, 205, 112, 1, 250, 165, 205, 112, 1, 155, 205, + 112, 1, 221, 217, 205, 112, 1, 231, 242, 205, 112, 1, 231, 93, 205, 112, + 1, 214, 70, 205, 112, 1, 247, 162, 205, 112, 1, 247, 3, 205, 112, 1, 223, + 34, 205, 112, 1, 222, 254, 205, 112, 1, 212, 103, 205, 112, 1, 197, 132, + 205, 112, 1, 197, 120, 205, 112, 1, 237, 193, 205, 112, 1, 237, 177, 205, + 112, 1, 213, 81, 205, 112, 1, 190, 190, 205, 112, 1, 199, 49, 205, 112, + 1, 238, 34, 205, 112, 1, 237, 70, 205, 112, 1, 181, 205, 112, 1, 168, + 205, 112, 1, 209, 230, 205, 112, 1, 249, 155, 205, 112, 1, 248, 205, 205, + 112, 1, 174, 205, 112, 1, 170, 205, 112, 1, 165, 205, 112, 1, 173, 205, + 112, 1, 195, 188, 205, 112, 1, 203, 166, 205, 112, 1, 201, 176, 205, 112, + 1, 188, 205, 112, 1, 140, 205, 112, 1, 219, 75, 205, 112, 120, 3, 230, + 91, 205, 112, 18, 3, 252, 208, 205, 112, 18, 3, 68, 205, 112, 18, 3, 223, + 201, 205, 112, 18, 3, 66, 205, 112, 18, 3, 196, 30, 205, 112, 18, 3, 117, + 146, 205, 112, 18, 3, 117, 206, 111, 205, 112, 18, 3, 117, 172, 205, 112, + 18, 3, 117, 219, 76, 205, 112, 18, 3, 71, 205, 112, 18, 3, 234, 190, 205, + 112, 18, 3, 251, 238, 205, 112, 18, 3, 74, 205, 112, 18, 3, 211, 89, 205, + 112, 18, 3, 250, 165, 205, 112, 3, 195, 40, 205, 112, 3, 247, 121, 205, + 112, 237, 240, 205, 112, 55, 237, 240, 205, 112, 17, 191, 77, 205, 112, + 17, 107, 205, 112, 17, 109, 205, 112, 17, 138, 205, 112, 17, 134, 205, + 112, 17, 150, 205, 112, 17, 169, 205, 112, 17, 175, 205, 112, 17, 171, + 205, 112, 17, 178, 33, 100, 17, 191, 77, 33, 100, 17, 107, 33, 100, 17, + 109, 33, 100, 17, 138, 33, 100, 17, 134, 33, 100, 17, 150, 33, 100, 17, 169, 33, 100, 17, 175, 33, 100, 17, 171, 33, 100, 17, 178, 33, 100, 1, - 65, 33, 100, 1, 66, 33, 100, 1, 155, 33, 100, 1, 180, 33, 100, 1, 168, - 33, 100, 1, 165, 33, 100, 1, 195, 69, 33, 100, 3, 250, 145, 100, 3, 201, - 246, 247, 119, 100, 3, 247, 120, 195, 40, 100, 3, 55, 247, 120, 195, 40, - 100, 3, 247, 120, 109, 100, 3, 247, 120, 138, 100, 3, 247, 120, 250, 145, - 100, 3, 208, 134, 100, 231, 204, 233, 3, 100, 247, 96, 100, 229, 227, - 100, 3, 202, 210, 100, 223, 24, 211, 113, 100, 1, 250, 131, 100, 18, 3, - 250, 131, 222, 28, 219, 147, 17, 191, 77, 222, 28, 219, 147, 17, 107, - 222, 28, 219, 147, 17, 109, 222, 28, 219, 147, 17, 138, 222, 28, 219, - 147, 17, 134, 222, 28, 219, 147, 17, 149, 222, 28, 219, 147, 17, 169, - 222, 28, 219, 147, 17, 175, 222, 28, 219, 147, 17, 171, 222, 28, 219, - 147, 17, 178, 222, 28, 219, 147, 1, 155, 222, 28, 219, 147, 1, 221, 215, - 222, 28, 219, 147, 1, 231, 240, 222, 28, 219, 147, 1, 214, 68, 222, 28, - 219, 147, 1, 188, 222, 28, 219, 147, 1, 203, 165, 222, 28, 219, 147, 1, - 191, 123, 222, 28, 219, 147, 1, 212, 101, 222, 28, 219, 147, 1, 190, 190, - 222, 28, 219, 147, 1, 228, 164, 222, 28, 219, 147, 1, 180, 222, 28, 219, - 147, 1, 168, 222, 28, 219, 147, 1, 209, 228, 222, 28, 219, 147, 1, 174, - 222, 28, 219, 147, 1, 238, 32, 222, 28, 219, 147, 1, 249, 153, 222, 28, - 219, 147, 1, 165, 222, 28, 219, 147, 1, 170, 222, 28, 219, 147, 1, 173, - 222, 28, 219, 147, 1, 193, 190, 222, 28, 219, 147, 1, 199, 49, 222, 28, - 219, 147, 1, 140, 222, 28, 219, 147, 1, 195, 188, 222, 28, 219, 147, 1, - 247, 160, 222, 28, 219, 147, 1, 65, 222, 28, 219, 147, 1, 211, 151, 222, - 28, 219, 147, 1, 68, 222, 28, 219, 147, 1, 211, 87, 222, 28, 219, 147, - 18, 196, 152, 222, 28, 219, 147, 18, 71, 222, 28, 219, 147, 18, 66, 222, - 28, 219, 147, 18, 234, 188, 222, 28, 219, 147, 18, 74, 222, 28, 219, 147, - 163, 209, 90, 222, 28, 219, 147, 163, 247, 135, 222, 28, 219, 147, 163, - 247, 136, 209, 90, 222, 28, 219, 147, 3, 238, 147, 222, 28, 219, 147, 3, - 202, 230, 207, 67, 1, 155, 207, 67, 1, 231, 240, 207, 67, 1, 214, 68, - 207, 67, 1, 190, 190, 207, 67, 1, 238, 32, 207, 67, 1, 180, 207, 67, 1, - 168, 207, 67, 1, 249, 153, 207, 67, 1, 174, 207, 67, 1, 247, 160, 207, - 67, 1, 223, 32, 207, 67, 1, 212, 101, 207, 67, 1, 188, 207, 67, 1, 165, - 207, 67, 1, 173, 207, 67, 1, 170, 207, 67, 1, 193, 190, 207, 67, 1, 140, - 207, 67, 1, 217, 11, 207, 67, 1, 214, 47, 207, 67, 1, 214, 162, 207, 67, - 1, 212, 66, 207, 67, 1, 65, 207, 67, 18, 3, 68, 207, 67, 18, 3, 66, 207, - 67, 18, 3, 71, 207, 67, 18, 3, 251, 236, 207, 67, 18, 3, 74, 207, 67, 18, - 3, 250, 163, 207, 67, 18, 3, 233, 242, 207, 67, 18, 3, 234, 217, 207, 67, - 120, 3, 214, 70, 207, 67, 120, 3, 215, 61, 207, 67, 120, 3, 146, 207, 67, - 120, 3, 230, 116, 207, 67, 195, 40, 207, 67, 205, 54, 77, 30, 147, 198, + 65, 33, 100, 1, 66, 33, 100, 1, 155, 33, 100, 1, 181, 33, 100, 1, 168, + 33, 100, 1, 165, 33, 100, 1, 195, 69, 33, 100, 3, 250, 147, 100, 3, 201, + 247, 247, 121, 100, 3, 247, 122, 195, 40, 100, 3, 55, 247, 122, 195, 40, + 100, 3, 247, 122, 109, 100, 3, 247, 122, 138, 100, 3, 247, 122, 250, 147, + 100, 3, 208, 136, 100, 231, 206, 233, 5, 100, 247, 98, 100, 229, 229, + 100, 3, 202, 211, 100, 223, 26, 211, 115, 100, 1, 250, 133, 100, 18, 3, + 250, 133, 222, 30, 219, 149, 17, 191, 77, 222, 30, 219, 149, 17, 107, + 222, 30, 219, 149, 17, 109, 222, 30, 219, 149, 17, 138, 222, 30, 219, + 149, 17, 134, 222, 30, 219, 149, 17, 150, 222, 30, 219, 149, 17, 169, + 222, 30, 219, 149, 17, 175, 222, 30, 219, 149, 17, 171, 222, 30, 219, + 149, 17, 178, 222, 30, 219, 149, 1, 155, 222, 30, 219, 149, 1, 221, 217, + 222, 30, 219, 149, 1, 231, 242, 222, 30, 219, 149, 1, 214, 70, 222, 30, + 219, 149, 1, 188, 222, 30, 219, 149, 1, 203, 166, 222, 30, 219, 149, 1, + 191, 123, 222, 30, 219, 149, 1, 212, 103, 222, 30, 219, 149, 1, 190, 190, + 222, 30, 219, 149, 1, 228, 166, 222, 30, 219, 149, 1, 181, 222, 30, 219, + 149, 1, 168, 222, 30, 219, 149, 1, 209, 230, 222, 30, 219, 149, 1, 174, + 222, 30, 219, 149, 1, 238, 34, 222, 30, 219, 149, 1, 249, 155, 222, 30, + 219, 149, 1, 165, 222, 30, 219, 149, 1, 170, 222, 30, 219, 149, 1, 173, + 222, 30, 219, 149, 1, 193, 190, 222, 30, 219, 149, 1, 199, 49, 222, 30, + 219, 149, 1, 140, 222, 30, 219, 149, 1, 195, 188, 222, 30, 219, 149, 1, + 247, 162, 222, 30, 219, 149, 1, 65, 222, 30, 219, 149, 1, 211, 153, 222, + 30, 219, 149, 1, 68, 222, 30, 219, 149, 1, 211, 89, 222, 30, 219, 149, + 18, 196, 152, 222, 30, 219, 149, 18, 71, 222, 30, 219, 149, 18, 66, 222, + 30, 219, 149, 18, 234, 190, 222, 30, 219, 149, 18, 74, 222, 30, 219, 149, + 163, 209, 92, 222, 30, 219, 149, 163, 247, 137, 222, 30, 219, 149, 163, + 247, 138, 209, 92, 222, 30, 219, 149, 3, 238, 149, 222, 30, 219, 149, 3, + 202, 231, 207, 68, 1, 155, 207, 68, 1, 231, 242, 207, 68, 1, 214, 70, + 207, 68, 1, 190, 190, 207, 68, 1, 238, 34, 207, 68, 1, 181, 207, 68, 1, + 168, 207, 68, 1, 249, 155, 207, 68, 1, 174, 207, 68, 1, 247, 162, 207, + 68, 1, 223, 34, 207, 68, 1, 212, 103, 207, 68, 1, 188, 207, 68, 1, 165, + 207, 68, 1, 173, 207, 68, 1, 170, 207, 68, 1, 193, 190, 207, 68, 1, 140, + 207, 68, 1, 217, 13, 207, 68, 1, 214, 49, 207, 68, 1, 214, 164, 207, 68, + 1, 212, 68, 207, 68, 1, 65, 207, 68, 18, 3, 68, 207, 68, 18, 3, 66, 207, + 68, 18, 3, 71, 207, 68, 18, 3, 251, 238, 207, 68, 18, 3, 74, 207, 68, 18, + 3, 250, 165, 207, 68, 18, 3, 233, 244, 207, 68, 18, 3, 234, 219, 207, 68, + 120, 3, 214, 72, 207, 68, 120, 3, 215, 63, 207, 68, 120, 3, 146, 207, 68, + 120, 3, 230, 118, 207, 68, 195, 40, 207, 68, 205, 55, 77, 30, 147, 198, 164, 30, 147, 198, 163, 30, 147, 198, 161, 30, 147, 198, 166, 30, 147, - 206, 234, 30, 147, 206, 218, 30, 147, 206, 213, 30, 147, 206, 215, 30, - 147, 206, 231, 30, 147, 206, 224, 30, 147, 206, 217, 30, 147, 206, 236, - 30, 147, 206, 219, 30, 147, 206, 238, 30, 147, 206, 235, 30, 147, 216, - 73, 30, 147, 216, 64, 30, 147, 216, 67, 30, 147, 209, 154, 30, 147, 209, - 165, 30, 147, 209, 166, 30, 147, 201, 159, 30, 147, 223, 212, 30, 147, - 223, 219, 30, 147, 201, 170, 30, 147, 201, 157, 30, 147, 209, 208, 30, - 147, 229, 137, 30, 147, 201, 154, 223, 16, 3, 210, 143, 223, 16, 3, 247, - 39, 223, 16, 3, 219, 246, 223, 16, 3, 193, 71, 223, 16, 1, 65, 223, 16, - 1, 228, 74, 222, 32, 223, 16, 1, 68, 223, 16, 1, 223, 199, 223, 16, 1, - 66, 223, 16, 1, 210, 221, 247, 9, 223, 16, 1, 214, 69, 219, 203, 223, 16, - 1, 214, 69, 219, 204, 207, 131, 223, 16, 1, 71, 223, 16, 1, 251, 236, - 223, 16, 1, 74, 223, 16, 1, 155, 223, 16, 1, 222, 142, 205, 124, 223, 16, - 1, 222, 142, 215, 107, 223, 16, 1, 231, 240, 223, 16, 1, 231, 241, 215, - 107, 223, 16, 1, 214, 68, 223, 16, 1, 247, 160, 223, 16, 1, 247, 161, - 215, 107, 223, 16, 1, 223, 32, 223, 16, 1, 212, 102, 215, 107, 223, 16, - 1, 223, 33, 217, 116, 223, 16, 1, 212, 101, 223, 16, 1, 197, 132, 223, - 16, 1, 197, 133, 217, 116, 223, 16, 1, 237, 191, 223, 16, 1, 237, 192, - 217, 116, 223, 16, 1, 215, 7, 215, 107, 223, 16, 1, 190, 190, 223, 16, 1, - 199, 252, 215, 107, 223, 16, 1, 238, 32, 223, 16, 1, 238, 33, 217, 116, - 223, 16, 1, 180, 223, 16, 1, 168, 223, 16, 1, 210, 221, 215, 107, 223, - 16, 1, 249, 153, 223, 16, 1, 249, 154, 215, 107, 223, 16, 1, 174, 223, - 16, 1, 170, 223, 16, 1, 165, 223, 16, 1, 207, 186, 251, 246, 223, 16, 1, - 173, 223, 16, 1, 193, 190, 223, 16, 1, 205, 207, 215, 107, 223, 16, 1, - 205, 207, 217, 116, 223, 16, 1, 188, 223, 16, 1, 140, 223, 16, 3, 247, - 40, 199, 100, 223, 16, 18, 3, 199, 175, 223, 16, 18, 3, 198, 84, 223, 16, - 18, 3, 192, 250, 223, 16, 18, 3, 192, 251, 216, 198, 223, 16, 18, 3, 200, - 208, 223, 16, 18, 3, 200, 209, 216, 185, 223, 16, 18, 3, 199, 201, 223, - 16, 18, 3, 236, 230, 215, 106, 223, 16, 18, 3, 210, 16, 223, 16, 120, 3, - 221, 244, 223, 16, 120, 3, 210, 31, 223, 16, 120, 3, 247, 145, 223, 16, - 210, 157, 223, 16, 45, 207, 40, 223, 16, 50, 207, 40, 223, 16, 210, 209, - 251, 124, 223, 16, 210, 209, 217, 137, 223, 16, 210, 209, 218, 212, 223, - 16, 210, 209, 193, 64, 223, 16, 210, 209, 210, 158, 223, 16, 210, 209, - 219, 104, 223, 16, 210, 209, 218, 204, 223, 16, 210, 209, 252, 36, 223, - 16, 210, 209, 252, 37, 252, 36, 223, 16, 210, 209, 209, 119, 223, 16, - 153, 210, 209, 209, 119, 223, 16, 210, 153, 223, 16, 17, 191, 77, 223, - 16, 17, 107, 223, 16, 17, 109, 223, 16, 17, 138, 223, 16, 17, 134, 223, - 16, 17, 149, 223, 16, 17, 169, 223, 16, 17, 175, 223, 16, 17, 171, 223, - 16, 17, 178, 223, 16, 210, 209, 198, 127, 197, 73, 223, 16, 210, 209, - 223, 64, 80, 1, 203, 139, 231, 91, 80, 1, 203, 139, 247, 1, 80, 1, 203, - 139, 222, 252, 80, 1, 203, 139, 213, 79, 80, 1, 203, 139, 248, 203, 80, - 3, 203, 139, 205, 108, 80, 52, 1, 203, 139, 207, 85, 80, 1, 54, 220, 95, - 212, 101, 80, 1, 54, 220, 95, 233, 109, 80, 1, 54, 220, 95, 231, 240, 80, - 1, 54, 220, 95, 231, 91, 80, 1, 54, 220, 95, 223, 32, 80, 1, 54, 220, 95, - 222, 252, 80, 1, 54, 220, 95, 237, 191, 80, 1, 54, 220, 95, 237, 175, 80, - 1, 54, 220, 95, 213, 79, 80, 54, 220, 95, 17, 191, 77, 80, 54, 220, 95, - 17, 107, 80, 54, 220, 95, 17, 109, 80, 54, 220, 95, 17, 138, 80, 54, 220, - 95, 17, 134, 80, 54, 220, 95, 17, 149, 80, 54, 220, 95, 17, 169, 80, 54, - 220, 95, 17, 175, 80, 54, 220, 95, 17, 171, 80, 54, 220, 95, 17, 178, 80, - 1, 54, 220, 95, 219, 73, 80, 1, 54, 220, 95, 238, 32, 80, 1, 54, 220, 95, - 237, 68, 80, 1, 54, 220, 95, 249, 153, 80, 1, 54, 220, 95, 248, 203, 246, - 250, 1, 65, 246, 250, 1, 68, 246, 250, 1, 66, 246, 250, 1, 71, 246, 250, - 1, 251, 236, 246, 250, 1, 74, 246, 250, 1, 155, 246, 250, 1, 221, 215, - 246, 250, 1, 231, 240, 246, 250, 1, 231, 91, 246, 250, 1, 213, 233, 246, - 250, 1, 214, 68, 246, 250, 1, 247, 1, 246, 250, 1, 243, 98, 246, 250, 1, - 223, 32, 246, 250, 1, 222, 252, 246, 250, 1, 213, 221, 246, 250, 1, 213, - 224, 246, 250, 1, 213, 222, 246, 250, 1, 190, 190, 246, 250, 1, 199, 49, - 246, 250, 1, 238, 32, 246, 250, 1, 237, 68, 246, 250, 1, 212, 144, 246, - 250, 1, 180, 246, 250, 1, 237, 191, 246, 250, 1, 168, 246, 250, 1, 208, - 250, 246, 250, 1, 209, 228, 246, 250, 1, 249, 153, 246, 250, 1, 248, 203, - 246, 250, 1, 215, 143, 246, 250, 1, 174, 246, 250, 1, 249, 53, 246, 250, - 1, 170, 246, 250, 1, 165, 246, 250, 1, 173, 246, 250, 1, 195, 188, 246, - 250, 1, 201, 175, 246, 250, 1, 188, 246, 250, 1, 140, 246, 250, 18, 3, - 252, 206, 246, 250, 18, 3, 68, 246, 250, 18, 3, 223, 199, 246, 250, 18, - 3, 234, 166, 246, 250, 18, 3, 66, 246, 250, 18, 3, 211, 151, 246, 250, - 18, 3, 74, 246, 250, 18, 3, 251, 236, 246, 250, 18, 3, 250, 163, 246, - 250, 18, 3, 196, 152, 246, 250, 120, 3, 170, 246, 250, 120, 3, 165, 246, - 250, 120, 3, 173, 246, 250, 120, 3, 193, 190, 246, 250, 1, 53, 222, 152, - 246, 250, 1, 53, 232, 51, 246, 250, 1, 53, 214, 70, 246, 250, 120, 3, 53, - 214, 70, 246, 250, 1, 53, 247, 3, 246, 250, 1, 53, 200, 43, 246, 250, 1, - 53, 215, 61, 246, 250, 1, 53, 210, 236, 246, 250, 1, 53, 192, 159, 246, - 250, 1, 53, 146, 246, 250, 1, 53, 172, 246, 250, 1, 53, 201, 178, 246, - 250, 120, 3, 53, 218, 168, 246, 250, 120, 3, 53, 230, 116, 246, 250, 17, - 191, 77, 246, 250, 17, 107, 246, 250, 17, 109, 246, 250, 17, 138, 246, - 250, 17, 134, 246, 250, 17, 149, 246, 250, 17, 169, 246, 250, 17, 175, - 246, 250, 17, 171, 246, 250, 17, 178, 246, 250, 208, 152, 201, 217, 246, - 250, 208, 152, 237, 238, 246, 250, 208, 152, 55, 237, 238, 246, 250, 208, - 152, 197, 225, 237, 238, 80, 1, 221, 206, 231, 240, 80, 1, 221, 206, 247, - 160, 80, 1, 221, 206, 247, 1, 80, 1, 221, 206, 223, 32, 80, 1, 221, 206, - 222, 252, 80, 1, 221, 206, 212, 101, 80, 1, 221, 206, 197, 132, 80, 1, - 221, 206, 197, 120, 80, 1, 221, 206, 237, 191, 80, 1, 221, 206, 237, 175, - 80, 1, 221, 206, 237, 68, 80, 1, 221, 206, 180, 80, 1, 221, 206, 188, 80, - 1, 221, 206, 140, 80, 1, 221, 206, 229, 177, 80, 1, 221, 206, 233, 109, - 80, 52, 1, 221, 206, 207, 85, 80, 1, 221, 206, 192, 220, 80, 1, 221, 206, - 191, 123, 80, 1, 221, 206, 165, 80, 219, 28, 221, 206, 211, 179, 80, 219, - 28, 221, 206, 208, 46, 80, 219, 28, 221, 206, 229, 78, 80, 16, 251, 222, - 233, 215, 80, 16, 251, 222, 107, 80, 16, 251, 222, 109, 80, 1, 251, 222, - 165, 80, 3, 210, 139, 222, 62, 198, 79, 80, 3, 54, 220, 95, 198, 77, 80, - 3, 54, 220, 95, 198, 74, 80, 1, 202, 238, 210, 189, 247, 1, 80, 1, 202, - 238, 210, 189, 203, 165, 54, 195, 59, 1, 130, 221, 67, 54, 195, 59, 1, - 137, 221, 67, 54, 195, 59, 1, 130, 221, 183, 54, 195, 59, 1, 137, 221, - 183, 54, 195, 59, 1, 130, 221, 192, 54, 195, 59, 1, 137, 221, 192, 54, - 195, 59, 1, 130, 231, 3, 54, 195, 59, 1, 137, 231, 3, 54, 195, 59, 1, - 130, 213, 249, 54, 195, 59, 1, 137, 213, 249, 54, 195, 59, 1, 130, 242, - 99, 54, 195, 59, 1, 137, 242, 99, 54, 195, 59, 1, 130, 243, 68, 54, 195, - 59, 1, 137, 243, 68, 54, 195, 59, 1, 130, 202, 46, 54, 195, 59, 1, 137, - 202, 46, 54, 195, 59, 1, 130, 212, 65, 54, 195, 59, 1, 137, 212, 65, 54, - 195, 59, 1, 130, 236, 174, 54, 195, 59, 1, 137, 236, 174, 54, 195, 59, 1, - 130, 159, 54, 195, 59, 1, 137, 159, 54, 195, 59, 1, 130, 198, 241, 54, - 195, 59, 1, 137, 198, 241, 54, 195, 59, 1, 130, 213, 43, 54, 195, 59, 1, - 137, 213, 43, 54, 195, 59, 1, 130, 248, 111, 54, 195, 59, 1, 137, 248, - 111, 54, 195, 59, 1, 130, 209, 73, 54, 195, 59, 1, 137, 209, 73, 54, 195, - 59, 1, 130, 209, 199, 54, 195, 59, 1, 137, 209, 199, 54, 195, 59, 1, 130, - 232, 175, 54, 195, 59, 1, 137, 232, 175, 54, 195, 59, 1, 130, 216, 12, - 54, 195, 59, 1, 137, 216, 12, 54, 195, 59, 1, 130, 192, 12, 54, 195, 59, - 1, 137, 192, 12, 54, 195, 59, 1, 130, 206, 162, 54, 195, 59, 1, 137, 206, - 162, 54, 195, 59, 1, 130, 219, 43, 54, 195, 59, 1, 137, 219, 43, 54, 195, + 206, 235, 30, 147, 206, 219, 30, 147, 206, 214, 30, 147, 206, 216, 30, + 147, 206, 232, 30, 147, 206, 225, 30, 147, 206, 218, 30, 147, 206, 237, + 30, 147, 206, 220, 30, 147, 206, 239, 30, 147, 206, 236, 30, 147, 216, + 75, 30, 147, 216, 66, 30, 147, 216, 69, 30, 147, 209, 156, 30, 147, 209, + 167, 30, 147, 209, 168, 30, 147, 201, 160, 30, 147, 223, 214, 30, 147, + 223, 221, 30, 147, 201, 171, 30, 147, 201, 158, 30, 147, 209, 210, 30, + 147, 229, 139, 30, 147, 201, 155, 223, 18, 3, 210, 145, 223, 18, 3, 247, + 41, 223, 18, 3, 219, 248, 223, 18, 3, 193, 71, 223, 18, 1, 65, 223, 18, + 1, 228, 76, 222, 34, 223, 18, 1, 68, 223, 18, 1, 223, 201, 223, 18, 1, + 66, 223, 18, 1, 210, 223, 247, 11, 223, 18, 1, 214, 71, 219, 205, 223, + 18, 1, 214, 71, 219, 206, 207, 133, 223, 18, 1, 71, 223, 18, 1, 251, 238, + 223, 18, 1, 74, 223, 18, 1, 155, 223, 18, 1, 222, 144, 205, 125, 223, 18, + 1, 222, 144, 215, 109, 223, 18, 1, 231, 242, 223, 18, 1, 231, 243, 215, + 109, 223, 18, 1, 214, 70, 223, 18, 1, 247, 162, 223, 18, 1, 247, 163, + 215, 109, 223, 18, 1, 223, 34, 223, 18, 1, 212, 104, 215, 109, 223, 18, + 1, 223, 35, 217, 118, 223, 18, 1, 212, 103, 223, 18, 1, 197, 132, 223, + 18, 1, 197, 133, 217, 118, 223, 18, 1, 237, 193, 223, 18, 1, 237, 194, + 217, 118, 223, 18, 1, 215, 9, 215, 109, 223, 18, 1, 190, 190, 223, 18, 1, + 199, 252, 215, 109, 223, 18, 1, 238, 34, 223, 18, 1, 238, 35, 217, 118, + 223, 18, 1, 181, 223, 18, 1, 168, 223, 18, 1, 210, 223, 215, 109, 223, + 18, 1, 249, 155, 223, 18, 1, 249, 156, 215, 109, 223, 18, 1, 174, 223, + 18, 1, 170, 223, 18, 1, 165, 223, 18, 1, 207, 188, 251, 248, 223, 18, 1, + 173, 223, 18, 1, 193, 190, 223, 18, 1, 205, 208, 215, 109, 223, 18, 1, + 205, 208, 217, 118, 223, 18, 1, 188, 223, 18, 1, 140, 223, 18, 3, 247, + 42, 199, 100, 223, 18, 18, 3, 199, 175, 223, 18, 18, 3, 198, 84, 223, 18, + 18, 3, 192, 250, 223, 18, 18, 3, 192, 251, 216, 200, 223, 18, 18, 3, 200, + 208, 223, 18, 18, 3, 200, 209, 216, 187, 223, 18, 18, 3, 199, 201, 223, + 18, 18, 3, 236, 232, 215, 108, 223, 18, 18, 3, 210, 18, 223, 18, 120, 3, + 221, 246, 223, 18, 120, 3, 210, 33, 223, 18, 120, 3, 247, 147, 223, 18, + 210, 159, 223, 18, 45, 207, 41, 223, 18, 50, 207, 41, 223, 18, 210, 211, + 251, 126, 223, 18, 210, 211, 217, 139, 223, 18, 210, 211, 218, 214, 223, + 18, 210, 211, 193, 64, 223, 18, 210, 211, 210, 160, 223, 18, 210, 211, + 219, 106, 223, 18, 210, 211, 218, 206, 223, 18, 210, 211, 252, 38, 223, + 18, 210, 211, 252, 39, 252, 38, 223, 18, 210, 211, 209, 121, 223, 18, + 154, 210, 211, 209, 121, 223, 18, 210, 155, 223, 18, 17, 191, 77, 223, + 18, 17, 107, 223, 18, 17, 109, 223, 18, 17, 138, 223, 18, 17, 134, 223, + 18, 17, 150, 223, 18, 17, 169, 223, 18, 17, 175, 223, 18, 17, 171, 223, + 18, 17, 178, 223, 18, 210, 211, 198, 127, 197, 73, 223, 18, 210, 211, + 223, 66, 80, 1, 203, 140, 231, 93, 80, 1, 203, 140, 247, 3, 80, 1, 203, + 140, 222, 254, 80, 1, 203, 140, 213, 81, 80, 1, 203, 140, 248, 205, 80, + 3, 203, 140, 205, 109, 80, 52, 1, 203, 140, 207, 87, 80, 1, 54, 220, 97, + 212, 103, 80, 1, 54, 220, 97, 233, 111, 80, 1, 54, 220, 97, 231, 242, 80, + 1, 54, 220, 97, 231, 93, 80, 1, 54, 220, 97, 223, 34, 80, 1, 54, 220, 97, + 222, 254, 80, 1, 54, 220, 97, 237, 193, 80, 1, 54, 220, 97, 237, 177, 80, + 1, 54, 220, 97, 213, 81, 80, 54, 220, 97, 17, 191, 77, 80, 54, 220, 97, + 17, 107, 80, 54, 220, 97, 17, 109, 80, 54, 220, 97, 17, 138, 80, 54, 220, + 97, 17, 134, 80, 54, 220, 97, 17, 150, 80, 54, 220, 97, 17, 169, 80, 54, + 220, 97, 17, 175, 80, 54, 220, 97, 17, 171, 80, 54, 220, 97, 17, 178, 80, + 1, 54, 220, 97, 219, 75, 80, 1, 54, 220, 97, 238, 34, 80, 1, 54, 220, 97, + 237, 70, 80, 1, 54, 220, 97, 249, 155, 80, 1, 54, 220, 97, 248, 205, 246, + 252, 1, 65, 246, 252, 1, 68, 246, 252, 1, 66, 246, 252, 1, 71, 246, 252, + 1, 251, 238, 246, 252, 1, 74, 246, 252, 1, 155, 246, 252, 1, 221, 217, + 246, 252, 1, 231, 242, 246, 252, 1, 231, 93, 246, 252, 1, 213, 235, 246, + 252, 1, 214, 70, 246, 252, 1, 247, 3, 246, 252, 1, 243, 100, 246, 252, 1, + 223, 34, 246, 252, 1, 222, 254, 246, 252, 1, 213, 223, 246, 252, 1, 213, + 226, 246, 252, 1, 213, 224, 246, 252, 1, 190, 190, 246, 252, 1, 199, 49, + 246, 252, 1, 238, 34, 246, 252, 1, 237, 70, 246, 252, 1, 212, 146, 246, + 252, 1, 181, 246, 252, 1, 237, 193, 246, 252, 1, 168, 246, 252, 1, 208, + 252, 246, 252, 1, 209, 230, 246, 252, 1, 249, 155, 246, 252, 1, 248, 205, + 246, 252, 1, 215, 145, 246, 252, 1, 174, 246, 252, 1, 249, 55, 246, 252, + 1, 170, 246, 252, 1, 165, 246, 252, 1, 173, 246, 252, 1, 195, 188, 246, + 252, 1, 201, 176, 246, 252, 1, 188, 246, 252, 1, 140, 246, 252, 18, 3, + 252, 208, 246, 252, 18, 3, 68, 246, 252, 18, 3, 223, 201, 246, 252, 18, + 3, 234, 168, 246, 252, 18, 3, 66, 246, 252, 18, 3, 211, 153, 246, 252, + 18, 3, 74, 246, 252, 18, 3, 251, 238, 246, 252, 18, 3, 250, 165, 246, + 252, 18, 3, 196, 152, 246, 252, 120, 3, 170, 246, 252, 120, 3, 165, 246, + 252, 120, 3, 173, 246, 252, 120, 3, 193, 190, 246, 252, 1, 53, 222, 154, + 246, 252, 1, 53, 232, 53, 246, 252, 1, 53, 214, 72, 246, 252, 120, 3, 53, + 214, 72, 246, 252, 1, 53, 247, 5, 246, 252, 1, 53, 200, 43, 246, 252, 1, + 53, 215, 63, 246, 252, 1, 53, 210, 238, 246, 252, 1, 53, 192, 159, 246, + 252, 1, 53, 146, 246, 252, 1, 53, 172, 246, 252, 1, 53, 201, 179, 246, + 252, 120, 3, 53, 218, 170, 246, 252, 120, 3, 53, 230, 118, 246, 252, 17, + 191, 77, 246, 252, 17, 107, 246, 252, 17, 109, 246, 252, 17, 138, 246, + 252, 17, 134, 246, 252, 17, 150, 246, 252, 17, 169, 246, 252, 17, 175, + 246, 252, 17, 171, 246, 252, 17, 178, 246, 252, 208, 154, 201, 218, 246, + 252, 208, 154, 237, 240, 246, 252, 208, 154, 55, 237, 240, 246, 252, 208, + 154, 197, 225, 237, 240, 80, 1, 221, 208, 231, 242, 80, 1, 221, 208, 247, + 162, 80, 1, 221, 208, 247, 3, 80, 1, 221, 208, 223, 34, 80, 1, 221, 208, + 222, 254, 80, 1, 221, 208, 212, 103, 80, 1, 221, 208, 197, 132, 80, 1, + 221, 208, 197, 120, 80, 1, 221, 208, 237, 193, 80, 1, 221, 208, 237, 177, + 80, 1, 221, 208, 237, 70, 80, 1, 221, 208, 181, 80, 1, 221, 208, 188, 80, + 1, 221, 208, 140, 80, 1, 221, 208, 229, 179, 80, 1, 221, 208, 233, 111, + 80, 52, 1, 221, 208, 207, 87, 80, 1, 221, 208, 192, 220, 80, 1, 221, 208, + 191, 123, 80, 1, 221, 208, 165, 80, 219, 30, 221, 208, 211, 181, 80, 219, + 30, 221, 208, 208, 48, 80, 219, 30, 221, 208, 229, 80, 80, 16, 251, 224, + 233, 217, 80, 16, 251, 224, 107, 80, 16, 251, 224, 109, 80, 1, 251, 224, + 165, 80, 3, 210, 141, 222, 64, 198, 79, 80, 3, 54, 220, 97, 198, 77, 80, + 3, 54, 220, 97, 198, 74, 80, 1, 202, 239, 210, 191, 247, 3, 80, 1, 202, + 239, 210, 191, 203, 166, 54, 195, 59, 1, 130, 221, 69, 54, 195, 59, 1, + 137, 221, 69, 54, 195, 59, 1, 130, 221, 185, 54, 195, 59, 1, 137, 221, + 185, 54, 195, 59, 1, 130, 221, 194, 54, 195, 59, 1, 137, 221, 194, 54, + 195, 59, 1, 130, 231, 5, 54, 195, 59, 1, 137, 231, 5, 54, 195, 59, 1, + 130, 213, 251, 54, 195, 59, 1, 137, 213, 251, 54, 195, 59, 1, 130, 242, + 101, 54, 195, 59, 1, 137, 242, 101, 54, 195, 59, 1, 130, 243, 70, 54, + 195, 59, 1, 137, 243, 70, 54, 195, 59, 1, 130, 202, 47, 54, 195, 59, 1, + 137, 202, 47, 54, 195, 59, 1, 130, 212, 67, 54, 195, 59, 1, 137, 212, 67, + 54, 195, 59, 1, 130, 236, 176, 54, 195, 59, 1, 137, 236, 176, 54, 195, + 59, 1, 130, 159, 54, 195, 59, 1, 137, 159, 54, 195, 59, 1, 130, 198, 241, + 54, 195, 59, 1, 137, 198, 241, 54, 195, 59, 1, 130, 213, 45, 54, 195, 59, + 1, 137, 213, 45, 54, 195, 59, 1, 130, 248, 113, 54, 195, 59, 1, 137, 248, + 113, 54, 195, 59, 1, 130, 209, 75, 54, 195, 59, 1, 137, 209, 75, 54, 195, + 59, 1, 130, 209, 201, 54, 195, 59, 1, 137, 209, 201, 54, 195, 59, 1, 130, + 232, 177, 54, 195, 59, 1, 137, 232, 177, 54, 195, 59, 1, 130, 216, 14, + 54, 195, 59, 1, 137, 216, 14, 54, 195, 59, 1, 130, 192, 12, 54, 195, 59, + 1, 137, 192, 12, 54, 195, 59, 1, 130, 206, 163, 54, 195, 59, 1, 137, 206, + 163, 54, 195, 59, 1, 130, 219, 45, 54, 195, 59, 1, 137, 219, 45, 54, 195, 59, 1, 130, 195, 24, 54, 195, 59, 1, 137, 195, 24, 54, 195, 59, 1, 130, - 229, 23, 54, 195, 59, 1, 137, 229, 23, 54, 195, 59, 1, 130, 74, 54, 195, - 59, 1, 137, 74, 54, 195, 59, 217, 113, 222, 83, 54, 195, 59, 18, 252, - 206, 54, 195, 59, 18, 68, 54, 195, 59, 18, 196, 152, 54, 195, 59, 18, 66, - 54, 195, 59, 18, 71, 54, 195, 59, 18, 74, 54, 195, 59, 217, 113, 221, - 186, 54, 195, 59, 18, 228, 35, 54, 195, 59, 18, 196, 151, 54, 195, 59, - 18, 196, 168, 54, 195, 59, 18, 250, 161, 54, 195, 59, 18, 250, 131, 54, - 195, 59, 18, 251, 132, 54, 195, 59, 18, 251, 149, 54, 195, 59, 163, 217, - 113, 234, 147, 54, 195, 59, 163, 217, 113, 212, 143, 54, 195, 59, 163, - 217, 113, 198, 241, 54, 195, 59, 163, 217, 113, 202, 18, 54, 195, 59, 16, - 221, 44, 54, 195, 59, 16, 212, 143, 54, 195, 59, 16, 205, 152, 54, 195, - 59, 16, 229, 24, 229, 10, 54, 195, 59, 16, 221, 55, 221, 54, 216, 205, - 217, 18, 1, 71, 216, 205, 217, 18, 1, 74, 216, 205, 217, 18, 1, 247, 1, - 216, 205, 217, 18, 1, 212, 101, 216, 205, 217, 18, 1, 197, 132, 216, 205, - 217, 18, 1, 197, 120, 216, 205, 217, 18, 1, 237, 191, 216, 205, 217, 18, - 1, 237, 175, 216, 205, 217, 18, 1, 213, 79, 216, 205, 217, 18, 1, 203, - 165, 216, 205, 217, 18, 1, 201, 175, 216, 205, 217, 18, 18, 3, 223, 199, - 216, 205, 217, 18, 18, 3, 196, 30, 216, 205, 217, 18, 18, 3, 252, 170, - 216, 205, 217, 18, 18, 3, 250, 163, 216, 205, 217, 18, 18, 3, 252, 162, - 216, 205, 217, 18, 243, 116, 216, 205, 217, 18, 251, 242, 221, 173, 216, - 205, 217, 18, 251, 100, 216, 205, 217, 18, 5, 207, 46, 77, 216, 205, 217, - 18, 193, 23, 207, 46, 77, 216, 205, 217, 18, 18, 3, 195, 35, 216, 205, - 217, 18, 195, 40, 36, 5, 197, 113, 36, 5, 197, 116, 36, 5, 197, 119, 36, - 5, 197, 117, 36, 5, 197, 118, 36, 5, 197, 115, 36, 5, 237, 169, 36, 5, - 237, 171, 36, 5, 237, 174, 36, 5, 237, 172, 36, 5, 237, 173, 36, 5, 237, - 170, 36, 5, 235, 22, 36, 5, 235, 26, 36, 5, 235, 34, 36, 5, 235, 31, 36, - 5, 235, 32, 36, 5, 235, 23, 36, 5, 247, 56, 36, 5, 247, 50, 36, 5, 247, - 52, 36, 5, 247, 55, 36, 5, 247, 53, 36, 5, 247, 54, 36, 5, 247, 51, 36, - 5, 249, 53, 36, 5, 249, 32, 36, 5, 249, 44, 36, 5, 249, 52, 36, 5, 249, - 47, 36, 5, 249, 48, 36, 5, 249, 36, 8, 2, 1, 249, 82, 251, 160, 8, 2, 1, - 42, 207, 16, 8, 2, 1, 248, 135, 71, 8, 2, 1, 249, 82, 71, 8, 2, 1, 235, - 15, 4, 232, 188, 8, 2, 1, 219, 189, 233, 175, 8, 2, 1, 27, 232, 52, 4, - 238, 212, 8, 2, 1, 220, 143, 4, 223, 93, 219, 245, 206, 8, 8, 2, 1, 220, - 143, 4, 55, 82, 198, 152, 8, 2, 1, 220, 143, 4, 82, 206, 188, 8, 2, 1, - 218, 169, 4, 238, 212, 8, 2, 1, 215, 62, 4, 238, 212, 8, 2, 1, 234, 89, - 4, 238, 212, 8, 2, 1, 248, 135, 74, 8, 2, 1, 248, 135, 187, 4, 106, 8, 2, - 1, 211, 77, 187, 4, 106, 8, 2, 1, 223, 93, 211, 151, 8, 2, 1, 153, 211, - 152, 4, 106, 8, 2, 1, 153, 211, 152, 4, 228, 241, 106, 8, 2, 1, 153, 187, - 211, 72, 8, 2, 1, 153, 187, 211, 73, 4, 106, 8, 2, 1, 201, 68, 146, 8, 1, - 2, 6, 207, 222, 4, 50, 219, 212, 8, 2, 1, 207, 222, 193, 51, 230, 31, 8, - 2, 1, 55, 146, 8, 2, 1, 207, 222, 4, 238, 212, 8, 2, 1, 55, 207, 222, 4, - 238, 212, 8, 2, 1, 27, 146, 8, 2, 1, 27, 207, 222, 4, 206, 188, 8, 2, 1, - 249, 72, 234, 12, 8, 2, 1, 126, 4, 203, 40, 50, 219, 212, 8, 2, 1, 126, - 249, 88, 4, 203, 40, 50, 219, 212, 8, 2, 1, 196, 139, 8, 2, 1, 153, 196, - 139, 8, 2, 1, 126, 4, 45, 102, 8, 2, 1, 243, 95, 8, 2, 1, 243, 96, 4, - 130, 50, 206, 188, 8, 2, 1, 243, 96, 4, 130, 45, 204, 5, 8, 2, 1, 192, - 236, 4, 130, 50, 206, 188, 8, 2, 1, 192, 236, 4, 179, 45, 219, 212, 8, 2, - 1, 192, 236, 4, 179, 45, 219, 213, 23, 130, 50, 206, 188, 8, 2, 1, 192, - 236, 4, 179, 45, 219, 213, 4, 204, 5, 8, 2, 1, 192, 160, 4, 203, 40, 50, - 219, 212, 52, 248, 37, 4, 223, 93, 248, 36, 52, 1, 2, 229, 196, 52, 1, 2, - 220, 143, 4, 223, 93, 219, 245, 206, 8, 52, 1, 2, 220, 143, 4, 82, 198, - 152, 52, 1, 2, 126, 4, 45, 102, 8, 2, 1, 205, 174, 192, 95, 8, 2, 1, 223, - 81, 71, 8, 2, 1, 211, 77, 211, 151, 8, 2, 1, 196, 82, 8, 2, 1, 223, 93, - 251, 160, 35, 1, 2, 6, 211, 110, 8, 2, 1, 235, 37, 237, 3, 4, 207, 24, - 102, 8, 2, 1, 197, 170, 237, 3, 4, 207, 24, 102, 8, 2, 1, 153, 207, 222, - 4, 82, 198, 152, 52, 1, 2, 153, 193, 224, 52, 1, 45, 199, 228, 52, 1, 50, + 229, 25, 54, 195, 59, 1, 137, 229, 25, 54, 195, 59, 1, 130, 74, 54, 195, + 59, 1, 137, 74, 54, 195, 59, 217, 115, 222, 85, 54, 195, 59, 18, 252, + 208, 54, 195, 59, 18, 68, 54, 195, 59, 18, 196, 152, 54, 195, 59, 18, 66, + 54, 195, 59, 18, 71, 54, 195, 59, 18, 74, 54, 195, 59, 217, 115, 221, + 188, 54, 195, 59, 18, 228, 37, 54, 195, 59, 18, 196, 151, 54, 195, 59, + 18, 196, 168, 54, 195, 59, 18, 250, 163, 54, 195, 59, 18, 250, 133, 54, + 195, 59, 18, 251, 134, 54, 195, 59, 18, 251, 151, 54, 195, 59, 163, 217, + 115, 234, 149, 54, 195, 59, 163, 217, 115, 212, 145, 54, 195, 59, 163, + 217, 115, 198, 241, 54, 195, 59, 163, 217, 115, 202, 19, 54, 195, 59, 16, + 221, 46, 54, 195, 59, 16, 212, 145, 54, 195, 59, 16, 205, 153, 54, 195, + 59, 16, 229, 26, 229, 12, 54, 195, 59, 16, 221, 57, 221, 56, 216, 207, + 217, 20, 1, 71, 216, 207, 217, 20, 1, 74, 216, 207, 217, 20, 1, 247, 3, + 216, 207, 217, 20, 1, 212, 103, 216, 207, 217, 20, 1, 197, 132, 216, 207, + 217, 20, 1, 197, 120, 216, 207, 217, 20, 1, 237, 193, 216, 207, 217, 20, + 1, 237, 177, 216, 207, 217, 20, 1, 213, 81, 216, 207, 217, 20, 1, 203, + 166, 216, 207, 217, 20, 1, 201, 176, 216, 207, 217, 20, 18, 3, 223, 201, + 216, 207, 217, 20, 18, 3, 196, 30, 216, 207, 217, 20, 18, 3, 252, 172, + 216, 207, 217, 20, 18, 3, 250, 165, 216, 207, 217, 20, 18, 3, 252, 164, + 216, 207, 217, 20, 243, 118, 216, 207, 217, 20, 251, 244, 221, 175, 216, + 207, 217, 20, 251, 102, 216, 207, 217, 20, 5, 207, 47, 77, 216, 207, 217, + 20, 193, 23, 207, 47, 77, 216, 207, 217, 20, 18, 3, 195, 35, 216, 207, + 217, 20, 195, 40, 36, 5, 197, 113, 36, 5, 197, 116, 36, 5, 197, 119, 36, + 5, 197, 117, 36, 5, 197, 118, 36, 5, 197, 115, 36, 5, 237, 171, 36, 5, + 237, 173, 36, 5, 237, 176, 36, 5, 237, 174, 36, 5, 237, 175, 36, 5, 237, + 172, 36, 5, 235, 24, 36, 5, 235, 28, 36, 5, 235, 36, 36, 5, 235, 33, 36, + 5, 235, 34, 36, 5, 235, 25, 36, 5, 247, 58, 36, 5, 247, 52, 36, 5, 247, + 54, 36, 5, 247, 57, 36, 5, 247, 55, 36, 5, 247, 56, 36, 5, 247, 53, 36, + 5, 249, 55, 36, 5, 249, 34, 36, 5, 249, 46, 36, 5, 249, 54, 36, 5, 249, + 49, 36, 5, 249, 50, 36, 5, 249, 38, 8, 2, 1, 249, 84, 251, 162, 8, 2, 1, + 42, 207, 17, 8, 2, 1, 248, 137, 71, 8, 2, 1, 249, 84, 71, 8, 2, 1, 235, + 17, 4, 232, 190, 8, 2, 1, 219, 191, 233, 177, 8, 2, 1, 27, 232, 54, 4, + 238, 214, 8, 2, 1, 220, 145, 4, 223, 95, 219, 247, 206, 9, 8, 2, 1, 220, + 145, 4, 55, 82, 198, 152, 8, 2, 1, 220, 145, 4, 82, 206, 189, 8, 2, 1, + 218, 171, 4, 238, 214, 8, 2, 1, 215, 64, 4, 238, 214, 8, 2, 1, 234, 91, + 4, 238, 214, 8, 2, 1, 248, 137, 74, 8, 2, 1, 248, 137, 187, 4, 106, 8, 2, + 1, 211, 79, 187, 4, 106, 8, 2, 1, 223, 95, 211, 153, 8, 2, 1, 154, 211, + 154, 4, 106, 8, 2, 1, 154, 211, 154, 4, 228, 243, 106, 8, 2, 1, 154, 187, + 211, 74, 8, 2, 1, 154, 187, 211, 75, 4, 106, 8, 2, 1, 201, 69, 146, 8, 1, + 2, 6, 207, 224, 4, 50, 219, 214, 8, 2, 1, 207, 224, 193, 51, 230, 33, 8, + 2, 1, 55, 146, 8, 2, 1, 207, 224, 4, 238, 214, 8, 2, 1, 55, 207, 224, 4, + 238, 214, 8, 2, 1, 27, 146, 8, 2, 1, 27, 207, 224, 4, 206, 189, 8, 2, 1, + 249, 74, 234, 14, 8, 2, 1, 126, 4, 203, 41, 50, 219, 214, 8, 2, 1, 126, + 249, 90, 4, 203, 41, 50, 219, 214, 8, 2, 1, 196, 139, 8, 2, 1, 154, 196, + 139, 8, 2, 1, 126, 4, 45, 102, 8, 2, 1, 243, 97, 8, 2, 1, 243, 98, 4, + 130, 50, 206, 189, 8, 2, 1, 243, 98, 4, 130, 45, 204, 6, 8, 2, 1, 192, + 236, 4, 130, 50, 206, 189, 8, 2, 1, 192, 236, 4, 180, 45, 219, 214, 8, 2, + 1, 192, 236, 4, 180, 45, 219, 215, 23, 130, 50, 206, 189, 8, 2, 1, 192, + 236, 4, 180, 45, 219, 215, 4, 204, 6, 8, 2, 1, 192, 160, 4, 203, 41, 50, + 219, 214, 52, 248, 39, 4, 223, 95, 248, 38, 52, 1, 2, 229, 198, 52, 1, 2, + 220, 145, 4, 223, 95, 219, 247, 206, 9, 52, 1, 2, 220, 145, 4, 82, 198, + 152, 52, 1, 2, 126, 4, 45, 102, 8, 2, 1, 205, 175, 192, 95, 8, 2, 1, 223, + 83, 71, 8, 2, 1, 211, 79, 211, 153, 8, 2, 1, 196, 82, 8, 2, 1, 223, 95, + 251, 162, 35, 1, 2, 6, 211, 112, 8, 2, 1, 235, 39, 237, 5, 4, 207, 25, + 102, 8, 2, 1, 197, 170, 237, 5, 4, 207, 25, 102, 8, 2, 1, 154, 207, 224, + 4, 82, 198, 152, 52, 1, 2, 154, 193, 224, 52, 1, 45, 199, 228, 52, 1, 50, 199, 228, 103, 2, 1, 65, 103, 2, 1, 71, 103, 2, 1, 68, 103, 2, 1, 74, - 103, 2, 1, 66, 103, 2, 1, 196, 12, 103, 2, 1, 231, 240, 103, 2, 1, 155, - 103, 2, 1, 231, 165, 103, 2, 1, 231, 53, 103, 2, 1, 231, 3, 103, 2, 1, - 230, 179, 103, 2, 1, 230, 138, 103, 2, 1, 140, 103, 2, 1, 229, 245, 103, - 2, 1, 229, 158, 103, 2, 1, 229, 23, 103, 2, 1, 228, 159, 103, 2, 1, 228, - 126, 103, 2, 1, 173, 103, 2, 1, 219, 238, 103, 2, 1, 219, 146, 103, 2, 1, - 219, 43, 103, 2, 1, 218, 225, 103, 2, 1, 218, 192, 103, 2, 1, 174, 103, - 2, 1, 216, 232, 103, 2, 1, 216, 100, 103, 2, 1, 216, 12, 103, 2, 1, 215, - 155, 103, 2, 1, 180, 103, 2, 1, 229, 47, 103, 2, 1, 214, 237, 103, 2, 1, - 214, 121, 103, 2, 1, 213, 219, 103, 2, 1, 213, 43, 103, 2, 1, 212, 178, - 103, 2, 1, 212, 112, 103, 2, 1, 208, 32, 103, 2, 1, 208, 16, 103, 2, 1, - 208, 9, 103, 2, 1, 207, 255, 103, 2, 1, 207, 244, 103, 2, 1, 207, 242, - 103, 2, 1, 188, 103, 2, 1, 206, 8, 103, 2, 1, 205, 68, 103, 2, 1, 202, - 222, 103, 2, 1, 202, 46, 103, 2, 1, 201, 4, 103, 2, 1, 200, 158, 103, 2, - 1, 238, 32, 103, 2, 1, 190, 190, 103, 2, 1, 237, 146, 103, 2, 1, 199, - 145, 103, 2, 1, 237, 44, 103, 2, 1, 198, 193, 103, 2, 1, 236, 174, 103, - 2, 1, 235, 89, 103, 2, 1, 235, 57, 103, 2, 1, 236, 186, 103, 2, 1, 198, + 103, 2, 1, 66, 103, 2, 1, 196, 12, 103, 2, 1, 231, 242, 103, 2, 1, 155, + 103, 2, 1, 231, 167, 103, 2, 1, 231, 55, 103, 2, 1, 231, 5, 103, 2, 1, + 230, 181, 103, 2, 1, 230, 140, 103, 2, 1, 140, 103, 2, 1, 229, 247, 103, + 2, 1, 229, 160, 103, 2, 1, 229, 25, 103, 2, 1, 228, 161, 103, 2, 1, 228, + 128, 103, 2, 1, 173, 103, 2, 1, 219, 240, 103, 2, 1, 219, 148, 103, 2, 1, + 219, 45, 103, 2, 1, 218, 227, 103, 2, 1, 218, 194, 103, 2, 1, 174, 103, + 2, 1, 216, 234, 103, 2, 1, 216, 102, 103, 2, 1, 216, 14, 103, 2, 1, 215, + 157, 103, 2, 1, 181, 103, 2, 1, 229, 49, 103, 2, 1, 214, 239, 103, 2, 1, + 214, 123, 103, 2, 1, 213, 221, 103, 2, 1, 213, 45, 103, 2, 1, 212, 180, + 103, 2, 1, 212, 114, 103, 2, 1, 208, 34, 103, 2, 1, 208, 18, 103, 2, 1, + 208, 11, 103, 2, 1, 208, 1, 103, 2, 1, 207, 246, 103, 2, 1, 207, 244, + 103, 2, 1, 188, 103, 2, 1, 206, 9, 103, 2, 1, 205, 69, 103, 2, 1, 202, + 223, 103, 2, 1, 202, 47, 103, 2, 1, 201, 5, 103, 2, 1, 200, 158, 103, 2, + 1, 238, 34, 103, 2, 1, 190, 190, 103, 2, 1, 237, 148, 103, 2, 1, 199, + 145, 103, 2, 1, 237, 46, 103, 2, 1, 198, 193, 103, 2, 1, 236, 176, 103, + 2, 1, 235, 91, 103, 2, 1, 235, 59, 103, 2, 1, 236, 188, 103, 2, 1, 198, 115, 103, 2, 1, 198, 114, 103, 2, 1, 198, 103, 103, 2, 1, 198, 102, 103, 2, 1, 198, 101, 103, 2, 1, 198, 100, 103, 2, 1, 197, 168, 103, 2, 1, 197, 161, 103, 2, 1, 197, 146, 103, 2, 1, 197, 144, 103, 2, 1, 197, 140, 103, 2, 1, 197, 139, 103, 2, 1, 193, 190, 103, 2, 1, 193, 125, 103, 2, 1, 193, 86, 103, 2, 1, 193, 48, 103, 2, 1, 193, 0, 103, 2, 1, 192, 243, 103, 2, - 1, 170, 216, 205, 217, 18, 1, 221, 51, 216, 205, 217, 18, 1, 205, 152, - 216, 205, 217, 18, 1, 220, 96, 216, 205, 217, 18, 1, 216, 23, 216, 205, - 217, 18, 1, 168, 216, 205, 217, 18, 1, 180, 216, 205, 217, 18, 1, 243, - 87, 216, 205, 217, 18, 1, 198, 154, 216, 205, 217, 18, 1, 221, 176, 216, - 205, 217, 18, 1, 213, 239, 216, 205, 217, 18, 1, 198, 232, 216, 205, 217, - 18, 1, 193, 173, 216, 205, 217, 18, 1, 192, 106, 216, 205, 217, 18, 1, - 228, 147, 216, 205, 217, 18, 1, 196, 113, 216, 205, 217, 18, 1, 68, 216, - 205, 217, 18, 1, 209, 222, 216, 205, 217, 18, 1, 250, 175, 216, 205, 217, - 18, 1, 230, 251, 216, 205, 217, 18, 1, 222, 250, 216, 205, 217, 18, 1, - 207, 156, 216, 205, 217, 18, 1, 249, 153, 216, 205, 217, 18, 1, 222, 234, - 216, 205, 217, 18, 1, 237, 1, 216, 205, 217, 18, 1, 231, 60, 216, 205, - 217, 18, 1, 237, 46, 216, 205, 217, 18, 1, 248, 198, 216, 205, 217, 18, - 1, 221, 52, 219, 9, 216, 205, 217, 18, 1, 220, 97, 219, 9, 216, 205, 217, - 18, 1, 216, 24, 219, 9, 216, 205, 217, 18, 1, 210, 221, 219, 9, 216, 205, - 217, 18, 1, 215, 7, 219, 9, 216, 205, 217, 18, 1, 198, 155, 219, 9, 216, - 205, 217, 18, 1, 213, 240, 219, 9, 216, 205, 217, 18, 1, 228, 74, 219, 9, - 216, 205, 217, 18, 18, 3, 211, 102, 216, 205, 217, 18, 18, 3, 223, 160, - 216, 205, 217, 18, 18, 3, 251, 130, 216, 205, 217, 18, 18, 3, 192, 69, - 216, 205, 217, 18, 18, 3, 202, 6, 216, 205, 217, 18, 18, 3, 196, 110, - 216, 205, 217, 18, 18, 3, 243, 114, 216, 205, 217, 18, 18, 3, 212, 127, - 216, 205, 217, 18, 243, 115, 216, 205, 217, 18, 218, 209, 223, 42, 216, - 205, 217, 18, 251, 38, 223, 42, 216, 205, 217, 18, 17, 191, 77, 216, 205, - 217, 18, 17, 107, 216, 205, 217, 18, 17, 109, 216, 205, 217, 18, 17, 138, - 216, 205, 217, 18, 17, 134, 216, 205, 217, 18, 17, 149, 216, 205, 217, - 18, 17, 169, 216, 205, 217, 18, 17, 175, 216, 205, 217, 18, 17, 171, 216, - 205, 217, 18, 17, 178, 30, 222, 174, 212, 3, 30, 222, 174, 212, 8, 30, - 222, 174, 192, 5, 30, 222, 174, 192, 4, 30, 222, 174, 192, 3, 30, 222, - 174, 196, 218, 30, 222, 174, 196, 222, 30, 222, 174, 191, 219, 30, 222, - 174, 191, 215, 30, 222, 174, 233, 241, 30, 222, 174, 233, 239, 30, 222, - 174, 233, 240, 30, 222, 174, 233, 237, 30, 222, 174, 228, 60, 30, 222, - 174, 228, 59, 30, 222, 174, 228, 57, 30, 222, 174, 228, 58, 30, 222, 174, - 228, 63, 30, 222, 174, 228, 56, 30, 222, 174, 228, 55, 30, 222, 174, 228, - 65, 30, 222, 174, 251, 24, 30, 222, 174, 251, 23, 30, 125, 213, 197, 30, - 125, 213, 203, 30, 125, 201, 156, 30, 125, 201, 155, 30, 125, 198, 163, - 30, 125, 198, 161, 30, 125, 198, 160, 30, 125, 198, 166, 30, 125, 198, - 167, 30, 125, 198, 159, 30, 125, 206, 218, 30, 125, 206, 233, 30, 125, - 201, 162, 30, 125, 206, 230, 30, 125, 206, 220, 30, 125, 206, 222, 30, - 125, 206, 209, 30, 125, 206, 210, 30, 125, 222, 68, 30, 125, 216, 72, 30, - 125, 216, 66, 30, 125, 201, 166, 30, 125, 216, 69, 30, 125, 216, 75, 30, - 125, 209, 150, 30, 125, 209, 159, 30, 125, 209, 163, 30, 125, 201, 164, - 30, 125, 209, 153, 30, 125, 209, 167, 30, 125, 209, 168, 30, 125, 202, - 152, 30, 125, 202, 155, 30, 125, 201, 160, 30, 125, 201, 158, 30, 125, - 202, 150, 30, 125, 202, 158, 30, 125, 202, 159, 30, 125, 202, 144, 30, - 125, 202, 157, 30, 125, 210, 147, 30, 125, 210, 148, 30, 125, 192, 53, - 30, 125, 192, 56, 30, 125, 243, 22, 30, 125, 243, 21, 30, 125, 201, 171, - 30, 125, 209, 206, 30, 125, 209, 205, 12, 15, 225, 190, 12, 15, 225, 189, - 12, 15, 225, 188, 12, 15, 225, 187, 12, 15, 225, 186, 12, 15, 225, 185, - 12, 15, 225, 184, 12, 15, 225, 183, 12, 15, 225, 182, 12, 15, 225, 181, - 12, 15, 225, 180, 12, 15, 225, 179, 12, 15, 225, 178, 12, 15, 225, 177, - 12, 15, 225, 176, 12, 15, 225, 175, 12, 15, 225, 174, 12, 15, 225, 173, - 12, 15, 225, 172, 12, 15, 225, 171, 12, 15, 225, 170, 12, 15, 225, 169, - 12, 15, 225, 168, 12, 15, 225, 167, 12, 15, 225, 166, 12, 15, 225, 165, - 12, 15, 225, 164, 12, 15, 225, 163, 12, 15, 225, 162, 12, 15, 225, 161, - 12, 15, 225, 160, 12, 15, 225, 159, 12, 15, 225, 158, 12, 15, 225, 157, - 12, 15, 225, 156, 12, 15, 225, 155, 12, 15, 225, 154, 12, 15, 225, 153, - 12, 15, 225, 152, 12, 15, 225, 151, 12, 15, 225, 150, 12, 15, 225, 149, - 12, 15, 225, 148, 12, 15, 225, 147, 12, 15, 225, 146, 12, 15, 225, 145, - 12, 15, 225, 144, 12, 15, 225, 143, 12, 15, 225, 142, 12, 15, 225, 141, - 12, 15, 225, 140, 12, 15, 225, 139, 12, 15, 225, 138, 12, 15, 225, 137, - 12, 15, 225, 136, 12, 15, 225, 135, 12, 15, 225, 134, 12, 15, 225, 133, - 12, 15, 225, 132, 12, 15, 225, 131, 12, 15, 225, 130, 12, 15, 225, 129, - 12, 15, 225, 128, 12, 15, 225, 127, 12, 15, 225, 126, 12, 15, 225, 125, - 12, 15, 225, 124, 12, 15, 225, 123, 12, 15, 225, 122, 12, 15, 225, 121, - 12, 15, 225, 120, 12, 15, 225, 119, 12, 15, 225, 118, 12, 15, 225, 117, - 12, 15, 225, 116, 12, 15, 225, 115, 12, 15, 225, 114, 12, 15, 225, 113, - 12, 15, 225, 112, 12, 15, 225, 111, 12, 15, 225, 110, 12, 15, 225, 109, - 12, 15, 225, 108, 12, 15, 225, 107, 12, 15, 225, 106, 12, 15, 225, 105, - 12, 15, 225, 104, 12, 15, 225, 103, 12, 15, 225, 102, 12, 15, 225, 101, - 12, 15, 225, 100, 12, 15, 225, 99, 12, 15, 225, 98, 12, 15, 225, 97, 12, - 15, 225, 96, 12, 15, 225, 95, 12, 15, 225, 94, 12, 15, 225, 93, 12, 15, - 225, 92, 12, 15, 225, 91, 12, 15, 225, 90, 12, 15, 225, 89, 12, 15, 225, - 88, 12, 15, 225, 87, 12, 15, 225, 86, 12, 15, 225, 85, 12, 15, 225, 84, - 12, 15, 225, 83, 12, 15, 225, 82, 12, 15, 225, 81, 12, 15, 225, 80, 12, - 15, 225, 79, 12, 15, 225, 78, 12, 15, 225, 77, 12, 15, 225, 76, 12, 15, - 225, 75, 12, 15, 225, 74, 12, 15, 225, 73, 12, 15, 225, 72, 12, 15, 225, - 71, 12, 15, 225, 70, 12, 15, 225, 69, 12, 15, 225, 68, 12, 15, 225, 67, - 12, 15, 225, 66, 12, 15, 225, 65, 12, 15, 225, 64, 12, 15, 225, 63, 12, - 15, 225, 62, 12, 15, 225, 61, 12, 15, 225, 60, 12, 15, 225, 59, 12, 15, - 225, 58, 12, 15, 225, 57, 12, 15, 225, 56, 12, 15, 225, 55, 12, 15, 225, - 54, 12, 15, 225, 53, 12, 15, 225, 52, 12, 15, 225, 51, 12, 15, 225, 50, - 12, 15, 225, 49, 12, 15, 225, 48, 12, 15, 225, 47, 12, 15, 225, 46, 12, - 15, 225, 45, 12, 15, 225, 44, 12, 15, 225, 43, 12, 15, 225, 42, 12, 15, - 225, 41, 12, 15, 225, 40, 12, 15, 225, 39, 12, 15, 225, 38, 12, 15, 225, - 37, 12, 15, 225, 36, 12, 15, 225, 35, 12, 15, 225, 34, 12, 15, 225, 33, - 12, 15, 225, 32, 12, 15, 225, 31, 12, 15, 225, 30, 12, 15, 225, 29, 12, - 15, 225, 28, 12, 15, 225, 27, 12, 15, 225, 26, 12, 15, 225, 25, 12, 15, - 225, 24, 12, 15, 225, 23, 12, 15, 225, 22, 12, 15, 225, 21, 12, 15, 225, - 20, 12, 15, 225, 19, 12, 15, 225, 18, 12, 15, 225, 17, 12, 15, 225, 16, - 12, 15, 225, 15, 12, 15, 225, 14, 12, 15, 225, 13, 12, 15, 225, 12, 12, - 15, 225, 11, 12, 15, 225, 10, 12, 15, 225, 9, 12, 15, 225, 8, 12, 15, - 225, 7, 12, 15, 225, 6, 12, 15, 225, 5, 12, 15, 225, 4, 12, 15, 225, 3, - 12, 15, 225, 2, 12, 15, 225, 1, 12, 15, 225, 0, 12, 15, 224, 255, 12, 15, - 224, 254, 12, 15, 224, 253, 12, 15, 224, 252, 12, 15, 224, 251, 12, 15, - 224, 250, 12, 15, 224, 249, 12, 15, 224, 248, 12, 15, 224, 247, 12, 15, - 224, 246, 12, 15, 224, 245, 12, 15, 224, 244, 12, 15, 224, 243, 12, 15, - 224, 242, 12, 15, 224, 241, 12, 15, 224, 240, 12, 15, 224, 239, 12, 15, - 224, 238, 12, 15, 224, 237, 12, 15, 224, 236, 12, 15, 224, 235, 12, 15, - 224, 234, 12, 15, 224, 233, 12, 15, 224, 232, 12, 15, 224, 231, 12, 15, - 224, 230, 12, 15, 224, 229, 12, 15, 224, 228, 12, 15, 224, 227, 12, 15, - 224, 226, 12, 15, 224, 225, 12, 15, 224, 224, 12, 15, 224, 223, 12, 15, - 224, 222, 12, 15, 224, 221, 12, 15, 224, 220, 12, 15, 224, 219, 12, 15, - 224, 218, 12, 15, 224, 217, 12, 15, 224, 216, 12, 15, 224, 215, 12, 15, - 224, 214, 12, 15, 224, 213, 12, 15, 224, 212, 12, 15, 224, 211, 12, 15, - 224, 210, 12, 15, 224, 209, 12, 15, 224, 208, 12, 15, 224, 207, 12, 15, - 224, 206, 12, 15, 224, 205, 12, 15, 224, 204, 12, 15, 224, 203, 12, 15, - 224, 202, 12, 15, 224, 201, 12, 15, 224, 200, 12, 15, 224, 199, 12, 15, - 224, 198, 12, 15, 224, 197, 12, 15, 224, 196, 12, 15, 224, 195, 12, 15, - 224, 194, 12, 15, 224, 193, 12, 15, 224, 192, 12, 15, 224, 191, 12, 15, - 224, 190, 12, 15, 224, 189, 12, 15, 224, 188, 12, 15, 224, 187, 12, 15, - 224, 186, 12, 15, 224, 185, 12, 15, 224, 184, 12, 15, 224, 183, 12, 15, - 224, 182, 12, 15, 224, 181, 12, 15, 224, 180, 12, 15, 224, 179, 12, 15, - 224, 178, 12, 15, 224, 177, 12, 15, 224, 176, 12, 15, 224, 175, 12, 15, - 224, 174, 12, 15, 224, 173, 12, 15, 224, 172, 12, 15, 224, 171, 12, 15, - 224, 170, 12, 15, 224, 169, 12, 15, 224, 168, 12, 15, 224, 167, 12, 15, - 224, 166, 12, 15, 224, 165, 12, 15, 224, 164, 12, 15, 224, 163, 12, 15, - 224, 162, 12, 15, 224, 161, 12, 15, 224, 160, 12, 15, 224, 159, 12, 15, - 224, 158, 12, 15, 224, 157, 12, 15, 224, 156, 12, 15, 224, 155, 12, 15, - 224, 154, 12, 15, 224, 153, 12, 15, 224, 152, 12, 15, 224, 151, 12, 15, - 224, 150, 12, 15, 224, 149, 12, 15, 224, 148, 12, 15, 224, 147, 12, 15, - 224, 146, 12, 15, 224, 145, 12, 15, 224, 144, 12, 15, 224, 143, 12, 15, - 224, 142, 12, 15, 224, 141, 12, 15, 224, 140, 12, 15, 224, 139, 12, 15, - 224, 138, 12, 15, 224, 137, 12, 15, 224, 136, 12, 15, 224, 135, 12, 15, - 224, 134, 12, 15, 224, 133, 12, 15, 224, 132, 12, 15, 224, 131, 12, 15, - 224, 130, 12, 15, 224, 129, 12, 15, 224, 128, 12, 15, 224, 127, 12, 15, - 224, 126, 12, 15, 224, 125, 12, 15, 224, 124, 12, 15, 224, 123, 12, 15, - 224, 122, 12, 15, 224, 121, 12, 15, 224, 120, 12, 15, 224, 119, 12, 15, - 224, 118, 12, 15, 224, 117, 12, 15, 224, 116, 12, 15, 224, 115, 12, 15, - 224, 114, 12, 15, 224, 113, 12, 15, 224, 112, 12, 15, 224, 111, 12, 15, - 224, 110, 12, 15, 224, 109, 12, 15, 224, 108, 12, 15, 224, 107, 12, 15, - 224, 106, 12, 15, 224, 105, 12, 15, 224, 104, 12, 15, 224, 103, 12, 15, - 224, 102, 12, 15, 224, 101, 12, 15, 224, 100, 12, 15, 224, 99, 12, 15, - 224, 98, 12, 15, 224, 97, 12, 15, 224, 96, 12, 15, 224, 95, 12, 15, 224, - 94, 12, 15, 224, 93, 12, 15, 224, 92, 12, 15, 224, 91, 12, 15, 224, 90, - 12, 15, 224, 89, 12, 15, 224, 88, 12, 15, 224, 87, 12, 15, 224, 86, 12, - 15, 224, 85, 12, 15, 224, 84, 12, 15, 224, 83, 12, 15, 224, 82, 12, 15, - 224, 81, 12, 15, 224, 80, 12, 15, 224, 79, 12, 15, 224, 78, 12, 15, 224, - 77, 12, 15, 224, 76, 12, 15, 224, 75, 12, 15, 224, 74, 12, 15, 224, 73, - 12, 15, 224, 72, 12, 15, 224, 71, 12, 15, 224, 70, 12, 15, 224, 69, 12, - 15, 224, 68, 12, 15, 224, 67, 12, 15, 224, 66, 12, 15, 224, 65, 12, 15, - 224, 64, 12, 15, 224, 63, 12, 15, 224, 62, 12, 15, 224, 61, 12, 15, 224, - 60, 12, 15, 224, 59, 12, 15, 224, 58, 12, 15, 224, 57, 12, 15, 224, 56, - 12, 15, 224, 55, 12, 15, 224, 54, 12, 15, 224, 53, 12, 15, 224, 52, 12, - 15, 224, 51, 12, 15, 224, 50, 12, 15, 224, 49, 12, 15, 224, 48, 12, 15, - 224, 47, 12, 15, 224, 46, 12, 15, 224, 45, 12, 15, 224, 44, 12, 15, 224, - 43, 12, 15, 224, 42, 12, 15, 224, 41, 12, 15, 224, 40, 12, 15, 224, 39, - 12, 15, 224, 38, 12, 15, 224, 37, 12, 15, 224, 36, 12, 15, 224, 35, 12, - 15, 224, 34, 12, 15, 224, 33, 12, 15, 224, 32, 12, 15, 224, 31, 12, 15, - 224, 30, 12, 15, 224, 29, 12, 15, 224, 28, 12, 15, 224, 27, 12, 15, 224, - 26, 12, 15, 224, 25, 12, 15, 224, 24, 12, 15, 224, 23, 12, 15, 224, 22, - 12, 15, 224, 21, 12, 15, 224, 20, 12, 15, 224, 19, 12, 15, 224, 18, 12, - 15, 224, 17, 12, 15, 224, 16, 12, 15, 224, 15, 12, 15, 224, 14, 12, 15, - 224, 13, 12, 15, 224, 12, 12, 15, 224, 11, 12, 15, 224, 10, 12, 15, 224, - 9, 12, 15, 224, 8, 12, 15, 224, 7, 12, 15, 224, 6, 12, 15, 224, 5, 12, - 15, 224, 4, 12, 15, 224, 3, 12, 15, 224, 2, 12, 15, 224, 1, 12, 15, 224, - 0, 12, 15, 223, 255, 12, 15, 223, 254, 12, 15, 223, 253, 12, 15, 223, - 252, 12, 15, 223, 251, 12, 15, 223, 250, 12, 15, 223, 249, 12, 15, 223, - 248, 12, 15, 223, 247, 12, 15, 223, 246, 12, 15, 223, 245, 12, 15, 223, - 244, 12, 15, 223, 243, 12, 15, 223, 242, 12, 15, 223, 241, 12, 15, 223, - 240, 12, 15, 223, 239, 12, 15, 223, 238, 12, 15, 223, 237, 12, 15, 223, - 236, 12, 15, 223, 235, 12, 15, 223, 234, 12, 15, 223, 233, 12, 15, 223, - 232, 12, 15, 223, 231, 8, 2, 34, 233, 27, 8, 2, 34, 233, 23, 8, 2, 34, - 232, 220, 8, 2, 34, 233, 26, 8, 2, 34, 233, 25, 8, 2, 34, 179, 206, 9, - 200, 43, 8, 2, 34, 201, 118, 250, 249, 2, 34, 216, 187, 212, 253, 250, - 249, 2, 34, 216, 187, 234, 195, 250, 249, 2, 34, 216, 187, 223, 131, 250, - 249, 2, 34, 195, 75, 212, 253, 250, 249, 2, 34, 216, 187, 192, 212, 136, - 1, 191, 251, 4, 229, 119, 136, 209, 62, 222, 181, 195, 166, 136, 34, 192, - 31, 191, 251, 191, 251, 210, 88, 136, 1, 251, 152, 250, 126, 136, 1, 193, - 78, 251, 192, 136, 1, 193, 78, 237, 253, 136, 1, 193, 78, 229, 245, 136, - 1, 193, 78, 222, 106, 136, 1, 193, 78, 220, 27, 136, 1, 193, 78, 53, 216, - 193, 136, 1, 193, 78, 207, 38, 136, 1, 193, 78, 199, 162, 136, 1, 251, - 152, 108, 56, 136, 1, 203, 70, 4, 203, 70, 236, 140, 136, 1, 203, 70, 4, - 202, 175, 236, 140, 136, 1, 203, 70, 4, 238, 17, 23, 203, 70, 236, 140, - 136, 1, 203, 70, 4, 238, 17, 23, 202, 175, 236, 140, 136, 1, 131, 4, 210, - 88, 136, 1, 131, 4, 208, 84, 136, 1, 131, 4, 217, 70, 136, 1, 248, 215, - 4, 238, 16, 136, 1, 231, 39, 4, 238, 16, 136, 1, 237, 254, 4, 238, 16, - 136, 1, 229, 246, 4, 217, 70, 136, 1, 195, 159, 4, 238, 16, 136, 1, 191, - 92, 4, 238, 16, 136, 1, 199, 74, 4, 238, 16, 136, 1, 191, 251, 4, 238, - 16, 136, 1, 53, 222, 107, 4, 238, 16, 136, 1, 222, 107, 4, 238, 16, 136, - 1, 220, 28, 4, 238, 16, 136, 1, 216, 194, 4, 238, 16, 136, 1, 212, 131, - 4, 238, 16, 136, 1, 205, 149, 4, 238, 16, 136, 1, 53, 210, 64, 4, 238, - 16, 136, 1, 210, 64, 4, 238, 16, 136, 1, 197, 164, 4, 238, 16, 136, 1, - 208, 43, 4, 238, 16, 136, 1, 207, 39, 4, 238, 16, 136, 1, 203, 70, 4, - 238, 16, 136, 1, 199, 163, 4, 238, 16, 136, 1, 195, 159, 4, 229, 7, 136, - 1, 248, 215, 4, 207, 161, 136, 1, 222, 107, 4, 207, 161, 136, 1, 210, 64, - 4, 207, 161, 136, 34, 131, 220, 27, 9, 1, 131, 193, 151, 76, 20, 9, 1, - 131, 193, 151, 53, 20, 9, 1, 249, 0, 76, 20, 9, 1, 249, 0, 53, 20, 9, 1, - 249, 0, 89, 20, 9, 1, 249, 0, 216, 217, 20, 9, 1, 210, 42, 76, 20, 9, 1, - 210, 42, 53, 20, 9, 1, 210, 42, 89, 20, 9, 1, 210, 42, 216, 217, 20, 9, - 1, 248, 244, 76, 20, 9, 1, 248, 244, 53, 20, 9, 1, 248, 244, 89, 20, 9, - 1, 248, 244, 216, 217, 20, 9, 1, 197, 123, 76, 20, 9, 1, 197, 123, 53, - 20, 9, 1, 197, 123, 89, 20, 9, 1, 197, 123, 216, 217, 20, 9, 1, 199, 113, - 76, 20, 9, 1, 199, 113, 53, 20, 9, 1, 199, 113, 89, 20, 9, 1, 199, 113, - 216, 217, 20, 9, 1, 197, 125, 76, 20, 9, 1, 197, 125, 53, 20, 9, 1, 197, - 125, 89, 20, 9, 1, 197, 125, 216, 217, 20, 9, 1, 195, 147, 76, 20, 9, 1, - 195, 147, 53, 20, 9, 1, 195, 147, 89, 20, 9, 1, 195, 147, 216, 217, 20, - 9, 1, 210, 40, 76, 20, 9, 1, 210, 40, 53, 20, 9, 1, 210, 40, 89, 20, 9, - 1, 210, 40, 216, 217, 20, 9, 1, 235, 42, 76, 20, 9, 1, 235, 42, 53, 20, - 9, 1, 235, 42, 89, 20, 9, 1, 235, 42, 216, 217, 20, 9, 1, 212, 88, 76, - 20, 9, 1, 212, 88, 53, 20, 9, 1, 212, 88, 89, 20, 9, 1, 212, 88, 216, - 217, 20, 9, 1, 199, 150, 76, 20, 9, 1, 199, 150, 53, 20, 9, 1, 199, 150, - 89, 20, 9, 1, 199, 150, 216, 217, 20, 9, 1, 199, 148, 76, 20, 9, 1, 199, - 148, 53, 20, 9, 1, 199, 148, 89, 20, 9, 1, 199, 148, 216, 217, 20, 9, 1, - 237, 189, 76, 20, 9, 1, 237, 189, 53, 20, 9, 1, 238, 11, 76, 20, 9, 1, - 238, 11, 53, 20, 9, 1, 235, 79, 76, 20, 9, 1, 235, 79, 53, 20, 9, 1, 237, - 187, 76, 20, 9, 1, 237, 187, 53, 20, 9, 1, 223, 4, 76, 20, 9, 1, 223, 4, - 53, 20, 9, 1, 206, 102, 76, 20, 9, 1, 206, 102, 53, 20, 9, 1, 222, 5, 76, - 20, 9, 1, 222, 5, 53, 20, 9, 1, 222, 5, 89, 20, 9, 1, 222, 5, 216, 217, - 20, 9, 1, 231, 228, 76, 20, 9, 1, 231, 228, 53, 20, 9, 1, 231, 228, 89, - 20, 9, 1, 231, 228, 216, 217, 20, 9, 1, 230, 167, 76, 20, 9, 1, 230, 167, - 53, 20, 9, 1, 230, 167, 89, 20, 9, 1, 230, 167, 216, 217, 20, 9, 1, 213, - 248, 76, 20, 9, 1, 213, 248, 53, 20, 9, 1, 213, 248, 89, 20, 9, 1, 213, - 248, 216, 217, 20, 9, 1, 213, 25, 231, 58, 76, 20, 9, 1, 213, 25, 231, - 58, 53, 20, 9, 1, 206, 166, 76, 20, 9, 1, 206, 166, 53, 20, 9, 1, 206, - 166, 89, 20, 9, 1, 206, 166, 216, 217, 20, 9, 1, 229, 211, 4, 99, 93, 76, - 20, 9, 1, 229, 211, 4, 99, 93, 53, 20, 9, 1, 229, 211, 231, 1, 76, 20, 9, - 1, 229, 211, 231, 1, 53, 20, 9, 1, 229, 211, 231, 1, 89, 20, 9, 1, 229, - 211, 231, 1, 216, 217, 20, 9, 1, 229, 211, 236, 171, 76, 20, 9, 1, 229, - 211, 236, 171, 53, 20, 9, 1, 229, 211, 236, 171, 89, 20, 9, 1, 229, 211, - 236, 171, 216, 217, 20, 9, 1, 99, 249, 81, 76, 20, 9, 1, 99, 249, 81, 53, - 20, 9, 1, 99, 249, 81, 4, 230, 58, 93, 76, 20, 9, 1, 99, 249, 81, 4, 230, - 58, 93, 53, 20, 9, 16, 75, 58, 9, 16, 75, 60, 9, 16, 105, 185, 58, 9, 16, - 105, 185, 60, 9, 16, 115, 185, 58, 9, 16, 115, 185, 60, 9, 16, 115, 185, - 209, 58, 235, 119, 58, 9, 16, 115, 185, 209, 58, 235, 119, 60, 9, 16, - 232, 128, 185, 58, 9, 16, 232, 128, 185, 60, 9, 16, 55, 81, 249, 88, 60, - 9, 16, 105, 185, 195, 85, 58, 9, 16, 105, 185, 195, 85, 60, 9, 16, 206, - 188, 9, 16, 2, 199, 220, 58, 9, 16, 2, 199, 220, 60, 9, 16, 193, 151, 58, - 9, 1, 214, 71, 76, 20, 9, 1, 214, 71, 53, 20, 9, 1, 214, 71, 89, 20, 9, - 1, 214, 71, 216, 217, 20, 9, 1, 126, 76, 20, 9, 1, 126, 53, 20, 9, 1, - 211, 152, 76, 20, 9, 1, 211, 152, 53, 20, 9, 1, 191, 226, 76, 20, 9, 1, - 191, 226, 53, 20, 9, 1, 126, 4, 230, 58, 93, 76, 20, 9, 1, 195, 154, 76, - 20, 9, 1, 195, 154, 53, 20, 9, 1, 221, 132, 211, 152, 76, 20, 9, 1, 221, - 132, 211, 152, 53, 20, 9, 1, 221, 132, 191, 226, 76, 20, 9, 1, 221, 132, - 191, 226, 53, 20, 9, 1, 235, 15, 76, 20, 9, 1, 235, 15, 53, 20, 9, 1, - 235, 15, 89, 20, 9, 1, 235, 15, 216, 217, 20, 9, 1, 196, 137, 222, 26, - 221, 132, 131, 217, 100, 89, 20, 9, 1, 196, 137, 222, 26, 221, 132, 131, - 217, 100, 216, 217, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 76, 20, 9, 34, - 99, 4, 230, 58, 93, 4, 131, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 252, - 26, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 252, 26, 53, 20, 9, 34, 99, 4, - 230, 58, 93, 4, 193, 134, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 193, 134, - 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 126, 76, 20, 9, 34, 99, 4, 230, 58, - 93, 4, 126, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 211, 152, 76, 20, 9, - 34, 99, 4, 230, 58, 93, 4, 211, 152, 53, 20, 9, 34, 99, 4, 230, 58, 93, - 4, 191, 226, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 191, 226, 53, 20, 9, - 34, 99, 4, 230, 58, 93, 4, 235, 15, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, - 235, 15, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 235, 15, 89, 20, 9, 34, - 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 76, 20, 9, 34, - 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 53, 20, 9, 34, - 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 89, 20, 9, 1, - 233, 74, 99, 76, 20, 9, 1, 233, 74, 99, 53, 20, 9, 1, 233, 74, 99, 89, - 20, 9, 1, 233, 74, 99, 216, 217, 20, 9, 34, 99, 4, 230, 58, 93, 4, 223, - 7, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 182, 76, 20, 9, 34, 99, 4, 230, - 58, 93, 4, 92, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 217, 100, 76, - 20, 9, 34, 99, 4, 230, 58, 93, 4, 99, 76, 20, 9, 34, 248, 246, 4, 223, 7, - 76, 20, 9, 34, 248, 246, 4, 182, 76, 20, 9, 34, 248, 246, 4, 221, 211, - 76, 20, 9, 34, 248, 246, 4, 92, 76, 20, 9, 34, 248, 246, 4, 131, 217, - 100, 76, 20, 9, 34, 248, 246, 4, 99, 76, 20, 9, 34, 199, 115, 4, 223, 7, - 76, 20, 9, 34, 199, 115, 4, 182, 76, 20, 9, 34, 199, 115, 4, 221, 211, - 76, 20, 9, 34, 199, 115, 4, 92, 76, 20, 9, 34, 199, 115, 4, 131, 217, - 100, 76, 20, 9, 34, 199, 115, 4, 99, 76, 20, 9, 34, 199, 30, 4, 223, 7, - 76, 20, 9, 34, 199, 30, 4, 92, 76, 20, 9, 34, 199, 30, 4, 131, 217, 100, - 76, 20, 9, 34, 199, 30, 4, 99, 76, 20, 9, 34, 223, 7, 4, 182, 76, 20, 9, - 34, 223, 7, 4, 92, 76, 20, 9, 34, 182, 4, 223, 7, 76, 20, 9, 34, 182, 4, - 92, 76, 20, 9, 34, 221, 211, 4, 223, 7, 76, 20, 9, 34, 221, 211, 4, 182, - 76, 20, 9, 34, 221, 211, 4, 92, 76, 20, 9, 34, 205, 47, 4, 223, 7, 76, - 20, 9, 34, 205, 47, 4, 182, 76, 20, 9, 34, 205, 47, 4, 221, 211, 76, 20, - 9, 34, 205, 47, 4, 92, 76, 20, 9, 34, 205, 193, 4, 182, 76, 20, 9, 34, - 205, 193, 4, 92, 76, 20, 9, 34, 238, 27, 4, 223, 7, 76, 20, 9, 34, 238, - 27, 4, 182, 76, 20, 9, 34, 238, 27, 4, 221, 211, 76, 20, 9, 34, 238, 27, - 4, 92, 76, 20, 9, 34, 199, 220, 4, 182, 76, 20, 9, 34, 199, 220, 4, 92, - 76, 20, 9, 34, 191, 117, 4, 92, 76, 20, 9, 34, 251, 231, 4, 223, 7, 76, - 20, 9, 34, 251, 231, 4, 92, 76, 20, 9, 34, 231, 87, 4, 223, 7, 76, 20, 9, - 34, 231, 87, 4, 92, 76, 20, 9, 34, 233, 47, 4, 223, 7, 76, 20, 9, 34, - 233, 47, 4, 182, 76, 20, 9, 34, 233, 47, 4, 221, 211, 76, 20, 9, 34, 233, - 47, 4, 92, 76, 20, 9, 34, 233, 47, 4, 131, 217, 100, 76, 20, 9, 34, 233, - 47, 4, 99, 76, 20, 9, 34, 208, 90, 4, 182, 76, 20, 9, 34, 208, 90, 4, 92, - 76, 20, 9, 34, 208, 90, 4, 131, 217, 100, 76, 20, 9, 34, 208, 90, 4, 99, - 76, 20, 9, 34, 222, 107, 4, 131, 76, 20, 9, 34, 222, 107, 4, 223, 7, 76, - 20, 9, 34, 222, 107, 4, 182, 76, 20, 9, 34, 222, 107, 4, 221, 211, 76, - 20, 9, 34, 222, 107, 4, 220, 36, 76, 20, 9, 34, 222, 107, 4, 92, 76, 20, - 9, 34, 222, 107, 4, 131, 217, 100, 76, 20, 9, 34, 222, 107, 4, 99, 76, - 20, 9, 34, 220, 36, 4, 223, 7, 76, 20, 9, 34, 220, 36, 4, 182, 76, 20, 9, - 34, 220, 36, 4, 221, 211, 76, 20, 9, 34, 220, 36, 4, 92, 76, 20, 9, 34, - 220, 36, 4, 131, 217, 100, 76, 20, 9, 34, 220, 36, 4, 99, 76, 20, 9, 34, - 92, 4, 223, 7, 76, 20, 9, 34, 92, 4, 182, 76, 20, 9, 34, 92, 4, 221, 211, - 76, 20, 9, 34, 92, 4, 92, 76, 20, 9, 34, 92, 4, 131, 217, 100, 76, 20, 9, - 34, 92, 4, 99, 76, 20, 9, 34, 213, 25, 4, 223, 7, 76, 20, 9, 34, 213, 25, - 4, 182, 76, 20, 9, 34, 213, 25, 4, 221, 211, 76, 20, 9, 34, 213, 25, 4, - 92, 76, 20, 9, 34, 213, 25, 4, 131, 217, 100, 76, 20, 9, 34, 213, 25, 4, - 99, 76, 20, 9, 34, 229, 211, 4, 223, 7, 76, 20, 9, 34, 229, 211, 4, 92, - 76, 20, 9, 34, 229, 211, 4, 131, 217, 100, 76, 20, 9, 34, 229, 211, 4, - 99, 76, 20, 9, 34, 99, 4, 223, 7, 76, 20, 9, 34, 99, 4, 182, 76, 20, 9, - 34, 99, 4, 221, 211, 76, 20, 9, 34, 99, 4, 92, 76, 20, 9, 34, 99, 4, 131, - 217, 100, 76, 20, 9, 34, 99, 4, 99, 76, 20, 9, 34, 199, 42, 4, 200, 182, - 131, 76, 20, 9, 34, 207, 72, 4, 200, 182, 131, 76, 20, 9, 34, 131, 217, - 100, 4, 200, 182, 131, 76, 20, 9, 34, 203, 156, 4, 237, 244, 76, 20, 9, - 34, 203, 156, 4, 222, 51, 76, 20, 9, 34, 203, 156, 4, 233, 71, 76, 20, 9, - 34, 203, 156, 4, 237, 246, 76, 20, 9, 34, 203, 156, 4, 222, 53, 76, 20, - 9, 34, 203, 156, 4, 200, 182, 131, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, - 207, 72, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 191, 114, 53, 20, 9, 34, - 99, 4, 230, 58, 93, 4, 92, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 213, 25, - 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 217, 100, 53, 20, 9, 34, 99, - 4, 230, 58, 93, 4, 99, 53, 20, 9, 34, 248, 246, 4, 207, 72, 53, 20, 9, - 34, 248, 246, 4, 191, 114, 53, 20, 9, 34, 248, 246, 4, 92, 53, 20, 9, 34, - 248, 246, 4, 213, 25, 53, 20, 9, 34, 248, 246, 4, 131, 217, 100, 53, 20, - 9, 34, 248, 246, 4, 99, 53, 20, 9, 34, 199, 115, 4, 207, 72, 53, 20, 9, - 34, 199, 115, 4, 191, 114, 53, 20, 9, 34, 199, 115, 4, 92, 53, 20, 9, 34, - 199, 115, 4, 213, 25, 53, 20, 9, 34, 199, 115, 4, 131, 217, 100, 53, 20, - 9, 34, 199, 115, 4, 99, 53, 20, 9, 34, 199, 30, 4, 207, 72, 53, 20, 9, - 34, 199, 30, 4, 191, 114, 53, 20, 9, 34, 199, 30, 4, 92, 53, 20, 9, 34, - 199, 30, 4, 213, 25, 53, 20, 9, 34, 199, 30, 4, 131, 217, 100, 53, 20, 9, - 34, 199, 30, 4, 99, 53, 20, 9, 34, 233, 47, 4, 131, 217, 100, 53, 20, 9, - 34, 233, 47, 4, 99, 53, 20, 9, 34, 208, 90, 4, 131, 217, 100, 53, 20, 9, - 34, 208, 90, 4, 99, 53, 20, 9, 34, 222, 107, 4, 131, 53, 20, 9, 34, 222, - 107, 4, 220, 36, 53, 20, 9, 34, 222, 107, 4, 92, 53, 20, 9, 34, 222, 107, - 4, 131, 217, 100, 53, 20, 9, 34, 222, 107, 4, 99, 53, 20, 9, 34, 220, 36, - 4, 92, 53, 20, 9, 34, 220, 36, 4, 131, 217, 100, 53, 20, 9, 34, 220, 36, - 4, 99, 53, 20, 9, 34, 92, 4, 131, 53, 20, 9, 34, 92, 4, 92, 53, 20, 9, - 34, 213, 25, 4, 207, 72, 53, 20, 9, 34, 213, 25, 4, 191, 114, 53, 20, 9, - 34, 213, 25, 4, 92, 53, 20, 9, 34, 213, 25, 4, 213, 25, 53, 20, 9, 34, - 213, 25, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 99, 53, 20, 9, 34, - 131, 217, 100, 4, 200, 182, 131, 53, 20, 9, 34, 99, 4, 207, 72, 53, 20, - 9, 34, 99, 4, 191, 114, 53, 20, 9, 34, 99, 4, 92, 53, 20, 9, 34, 99, 4, - 213, 25, 53, 20, 9, 34, 99, 4, 131, 217, 100, 53, 20, 9, 34, 99, 4, 99, - 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 223, 7, 89, 20, 9, 34, 99, 4, 230, - 58, 93, 4, 182, 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, 221, 211, 89, 20, - 9, 34, 99, 4, 230, 58, 93, 4, 92, 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, - 229, 211, 89, 20, 9, 34, 248, 246, 4, 223, 7, 89, 20, 9, 34, 248, 246, 4, - 182, 89, 20, 9, 34, 248, 246, 4, 221, 211, 89, 20, 9, 34, 248, 246, 4, - 92, 89, 20, 9, 34, 248, 246, 4, 229, 211, 89, 20, 9, 34, 199, 115, 4, - 223, 7, 89, 20, 9, 34, 199, 115, 4, 182, 89, 20, 9, 34, 199, 115, 4, 221, - 211, 89, 20, 9, 34, 199, 115, 4, 92, 89, 20, 9, 34, 199, 115, 4, 229, - 211, 89, 20, 9, 34, 199, 30, 4, 92, 89, 20, 9, 34, 223, 7, 4, 182, 89, - 20, 9, 34, 223, 7, 4, 92, 89, 20, 9, 34, 182, 4, 223, 7, 89, 20, 9, 34, - 182, 4, 92, 89, 20, 9, 34, 221, 211, 4, 223, 7, 89, 20, 9, 34, 221, 211, - 4, 92, 89, 20, 9, 34, 205, 47, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 182, - 89, 20, 9, 34, 205, 47, 4, 221, 211, 89, 20, 9, 34, 205, 47, 4, 92, 89, - 20, 9, 34, 205, 193, 4, 182, 89, 20, 9, 34, 205, 193, 4, 221, 211, 89, - 20, 9, 34, 205, 193, 4, 92, 89, 20, 9, 34, 238, 27, 4, 223, 7, 89, 20, 9, - 34, 238, 27, 4, 182, 89, 20, 9, 34, 238, 27, 4, 221, 211, 89, 20, 9, 34, - 238, 27, 4, 92, 89, 20, 9, 34, 199, 220, 4, 182, 89, 20, 9, 34, 191, 117, - 4, 92, 89, 20, 9, 34, 251, 231, 4, 223, 7, 89, 20, 9, 34, 251, 231, 4, - 92, 89, 20, 9, 34, 231, 87, 4, 223, 7, 89, 20, 9, 34, 231, 87, 4, 92, 89, - 20, 9, 34, 233, 47, 4, 223, 7, 89, 20, 9, 34, 233, 47, 4, 182, 89, 20, 9, - 34, 233, 47, 4, 221, 211, 89, 20, 9, 34, 233, 47, 4, 92, 89, 20, 9, 34, - 208, 90, 4, 182, 89, 20, 9, 34, 208, 90, 4, 92, 89, 20, 9, 34, 222, 107, - 4, 223, 7, 89, 20, 9, 34, 222, 107, 4, 182, 89, 20, 9, 34, 222, 107, 4, - 221, 211, 89, 20, 9, 34, 222, 107, 4, 220, 36, 89, 20, 9, 34, 222, 107, - 4, 92, 89, 20, 9, 34, 220, 36, 4, 223, 7, 89, 20, 9, 34, 220, 36, 4, 182, - 89, 20, 9, 34, 220, 36, 4, 221, 211, 89, 20, 9, 34, 220, 36, 4, 92, 89, - 20, 9, 34, 220, 36, 4, 229, 211, 89, 20, 9, 34, 92, 4, 223, 7, 89, 20, 9, - 34, 92, 4, 182, 89, 20, 9, 34, 92, 4, 221, 211, 89, 20, 9, 34, 92, 4, 92, - 89, 20, 9, 34, 213, 25, 4, 223, 7, 89, 20, 9, 34, 213, 25, 4, 182, 89, - 20, 9, 34, 213, 25, 4, 221, 211, 89, 20, 9, 34, 213, 25, 4, 92, 89, 20, - 9, 34, 213, 25, 4, 229, 211, 89, 20, 9, 34, 229, 211, 4, 223, 7, 89, 20, - 9, 34, 229, 211, 4, 92, 89, 20, 9, 34, 229, 211, 4, 200, 182, 131, 89, - 20, 9, 34, 99, 4, 223, 7, 89, 20, 9, 34, 99, 4, 182, 89, 20, 9, 34, 99, - 4, 221, 211, 89, 20, 9, 34, 99, 4, 92, 89, 20, 9, 34, 99, 4, 229, 211, - 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, 92, 216, 217, 20, 9, 34, 99, 4, - 230, 58, 93, 4, 229, 211, 216, 217, 20, 9, 34, 248, 246, 4, 92, 216, 217, - 20, 9, 34, 248, 246, 4, 229, 211, 216, 217, 20, 9, 34, 199, 115, 4, 92, - 216, 217, 20, 9, 34, 199, 115, 4, 229, 211, 216, 217, 20, 9, 34, 199, 30, - 4, 92, 216, 217, 20, 9, 34, 199, 30, 4, 229, 211, 216, 217, 20, 9, 34, - 205, 47, 4, 92, 216, 217, 20, 9, 34, 205, 47, 4, 229, 211, 216, 217, 20, - 9, 34, 203, 110, 4, 92, 216, 217, 20, 9, 34, 203, 110, 4, 229, 211, 216, - 217, 20, 9, 34, 222, 107, 4, 220, 36, 216, 217, 20, 9, 34, 222, 107, 4, - 92, 216, 217, 20, 9, 34, 220, 36, 4, 92, 216, 217, 20, 9, 34, 213, 25, 4, - 92, 216, 217, 20, 9, 34, 213, 25, 4, 229, 211, 216, 217, 20, 9, 34, 99, - 4, 92, 216, 217, 20, 9, 34, 99, 4, 229, 211, 216, 217, 20, 9, 34, 203, - 156, 4, 233, 71, 216, 217, 20, 9, 34, 203, 156, 4, 237, 246, 216, 217, - 20, 9, 34, 203, 156, 4, 222, 53, 216, 217, 20, 9, 34, 199, 220, 4, 131, - 217, 100, 76, 20, 9, 34, 199, 220, 4, 99, 76, 20, 9, 34, 251, 231, 4, - 131, 217, 100, 76, 20, 9, 34, 251, 231, 4, 99, 76, 20, 9, 34, 231, 87, 4, - 131, 217, 100, 76, 20, 9, 34, 231, 87, 4, 99, 76, 20, 9, 34, 205, 47, 4, - 131, 217, 100, 76, 20, 9, 34, 205, 47, 4, 99, 76, 20, 9, 34, 203, 110, 4, - 131, 217, 100, 76, 20, 9, 34, 203, 110, 4, 99, 76, 20, 9, 34, 182, 4, - 131, 217, 100, 76, 20, 9, 34, 182, 4, 99, 76, 20, 9, 34, 223, 7, 4, 131, - 217, 100, 76, 20, 9, 34, 223, 7, 4, 99, 76, 20, 9, 34, 221, 211, 4, 131, - 217, 100, 76, 20, 9, 34, 221, 211, 4, 99, 76, 20, 9, 34, 205, 193, 4, - 131, 217, 100, 76, 20, 9, 34, 205, 193, 4, 99, 76, 20, 9, 34, 238, 27, 4, - 131, 217, 100, 76, 20, 9, 34, 238, 27, 4, 99, 76, 20, 9, 34, 203, 110, 4, - 223, 7, 76, 20, 9, 34, 203, 110, 4, 182, 76, 20, 9, 34, 203, 110, 4, 221, - 211, 76, 20, 9, 34, 203, 110, 4, 92, 76, 20, 9, 34, 203, 110, 4, 207, 72, - 76, 20, 9, 34, 205, 47, 4, 207, 72, 76, 20, 9, 34, 205, 193, 4, 207, 72, - 76, 20, 9, 34, 238, 27, 4, 207, 72, 76, 20, 9, 34, 199, 220, 4, 131, 217, - 100, 53, 20, 9, 34, 199, 220, 4, 99, 53, 20, 9, 34, 251, 231, 4, 131, - 217, 100, 53, 20, 9, 34, 251, 231, 4, 99, 53, 20, 9, 34, 231, 87, 4, 131, - 217, 100, 53, 20, 9, 34, 231, 87, 4, 99, 53, 20, 9, 34, 205, 47, 4, 131, - 217, 100, 53, 20, 9, 34, 205, 47, 4, 99, 53, 20, 9, 34, 203, 110, 4, 131, - 217, 100, 53, 20, 9, 34, 203, 110, 4, 99, 53, 20, 9, 34, 182, 4, 131, - 217, 100, 53, 20, 9, 34, 182, 4, 99, 53, 20, 9, 34, 223, 7, 4, 131, 217, - 100, 53, 20, 9, 34, 223, 7, 4, 99, 53, 20, 9, 34, 221, 211, 4, 131, 217, - 100, 53, 20, 9, 34, 221, 211, 4, 99, 53, 20, 9, 34, 205, 193, 4, 131, - 217, 100, 53, 20, 9, 34, 205, 193, 4, 99, 53, 20, 9, 34, 238, 27, 4, 131, - 217, 100, 53, 20, 9, 34, 238, 27, 4, 99, 53, 20, 9, 34, 203, 110, 4, 223, - 7, 53, 20, 9, 34, 203, 110, 4, 182, 53, 20, 9, 34, 203, 110, 4, 221, 211, - 53, 20, 9, 34, 203, 110, 4, 92, 53, 20, 9, 34, 203, 110, 4, 207, 72, 53, - 20, 9, 34, 205, 47, 4, 207, 72, 53, 20, 9, 34, 205, 193, 4, 207, 72, 53, - 20, 9, 34, 238, 27, 4, 207, 72, 53, 20, 9, 34, 203, 110, 4, 223, 7, 89, - 20, 9, 34, 203, 110, 4, 182, 89, 20, 9, 34, 203, 110, 4, 221, 211, 89, - 20, 9, 34, 203, 110, 4, 92, 89, 20, 9, 34, 205, 47, 4, 229, 211, 89, 20, - 9, 34, 203, 110, 4, 229, 211, 89, 20, 9, 34, 199, 220, 4, 92, 89, 20, 9, - 34, 205, 47, 4, 223, 7, 216, 217, 20, 9, 34, 205, 47, 4, 182, 216, 217, - 20, 9, 34, 205, 47, 4, 221, 211, 216, 217, 20, 9, 34, 203, 110, 4, 223, - 7, 216, 217, 20, 9, 34, 203, 110, 4, 182, 216, 217, 20, 9, 34, 203, 110, - 4, 221, 211, 216, 217, 20, 9, 34, 199, 220, 4, 92, 216, 217, 20, 9, 34, - 191, 117, 4, 92, 216, 217, 20, 9, 34, 131, 4, 233, 69, 53, 20, 9, 34, - 131, 4, 233, 69, 76, 20, 211, 40, 45, 210, 113, 211, 40, 50, 210, 113, 9, - 34, 207, 159, 251, 173, 9, 34, 207, 167, 251, 172, 251, 107, 9, 34, 207, - 167, 251, 172, 251, 106, 9, 34, 207, 167, 251, 172, 251, 104, 9, 34, 207, - 167, 251, 172, 251, 103, 9, 34, 207, 167, 251, 172, 251, 102, 9, 34, 205, - 162, 251, 197, 193, 184, 9, 34, 251, 197, 250, 217, 9, 34, 251, 196, 250, - 217, 9, 34, 251, 195, 250, 217, 9, 34, 251, 197, 250, 216, 193, 154, 9, - 34, 208, 17, 202, 140, 9, 34, 205, 160, 251, 197, 193, 180, 193, 183, 9, - 34, 251, 200, 250, 217, 9, 34, 199, 235, 193, 182, 9, 34, 207, 158, 251, - 173, 9, 34, 199, 115, 4, 223, 7, 4, 92, 89, 20, 9, 34, 199, 115, 4, 182, - 4, 223, 7, 53, 20, 9, 34, 199, 115, 4, 182, 4, 223, 7, 89, 20, 9, 34, - 199, 115, 4, 182, 4, 92, 89, 20, 9, 34, 199, 115, 4, 221, 211, 4, 92, 89, - 20, 9, 34, 199, 115, 4, 92, 4, 223, 7, 89, 20, 9, 34, 199, 115, 4, 92, 4, - 182, 89, 20, 9, 34, 199, 115, 4, 92, 4, 221, 211, 89, 20, 9, 34, 223, 7, - 4, 92, 4, 182, 53, 20, 9, 34, 223, 7, 4, 92, 4, 182, 89, 20, 9, 34, 182, - 4, 92, 4, 99, 53, 20, 9, 34, 182, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, - 205, 47, 4, 182, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 223, 7, 4, 182, - 89, 20, 9, 34, 205, 47, 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 205, - 47, 4, 92, 4, 182, 53, 20, 9, 34, 205, 47, 4, 92, 4, 182, 89, 20, 9, 34, - 205, 47, 4, 92, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 92, 4, 92, 53, 20, - 9, 34, 205, 47, 4, 92, 4, 92, 89, 20, 9, 34, 205, 193, 4, 182, 4, 182, - 53, 20, 9, 34, 205, 193, 4, 182, 4, 182, 89, 20, 9, 34, 205, 193, 4, 92, - 4, 92, 53, 20, 9, 34, 203, 110, 4, 182, 4, 92, 53, 20, 9, 34, 203, 110, - 4, 182, 4, 92, 89, 20, 9, 34, 203, 110, 4, 223, 7, 4, 99, 53, 20, 9, 34, - 203, 110, 4, 92, 4, 221, 211, 53, 20, 9, 34, 203, 110, 4, 92, 4, 221, - 211, 89, 20, 9, 34, 203, 110, 4, 92, 4, 92, 53, 20, 9, 34, 203, 110, 4, - 92, 4, 92, 89, 20, 9, 34, 238, 27, 4, 182, 4, 131, 217, 100, 53, 20, 9, - 34, 238, 27, 4, 221, 211, 4, 92, 53, 20, 9, 34, 238, 27, 4, 221, 211, 4, - 92, 89, 20, 9, 34, 199, 220, 4, 92, 4, 182, 53, 20, 9, 34, 199, 220, 4, - 92, 4, 182, 89, 20, 9, 34, 199, 220, 4, 92, 4, 92, 89, 20, 9, 34, 199, - 220, 4, 92, 4, 99, 53, 20, 9, 34, 251, 231, 4, 223, 7, 4, 92, 53, 20, 9, - 34, 251, 231, 4, 92, 4, 92, 53, 20, 9, 34, 251, 231, 4, 92, 4, 92, 89, - 20, 9, 34, 251, 231, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 231, 87, 4, - 92, 4, 92, 53, 20, 9, 34, 231, 87, 4, 92, 4, 99, 53, 20, 9, 34, 231, 87, - 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 233, 47, 4, 221, 211, 4, 92, 53, - 20, 9, 34, 233, 47, 4, 221, 211, 4, 92, 89, 20, 9, 34, 208, 90, 4, 92, 4, - 182, 53, 20, 9, 34, 208, 90, 4, 92, 4, 92, 53, 20, 9, 34, 220, 36, 4, - 182, 4, 92, 53, 20, 9, 34, 220, 36, 4, 182, 4, 99, 53, 20, 9, 34, 220, - 36, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 220, 36, 4, 223, 7, 4, 223, - 7, 89, 20, 9, 34, 220, 36, 4, 223, 7, 4, 223, 7, 53, 20, 9, 34, 220, 36, - 4, 221, 211, 4, 92, 53, 20, 9, 34, 220, 36, 4, 221, 211, 4, 92, 89, 20, - 9, 34, 220, 36, 4, 92, 4, 182, 53, 20, 9, 34, 220, 36, 4, 92, 4, 182, 89, - 20, 9, 34, 92, 4, 182, 4, 223, 7, 89, 20, 9, 34, 92, 4, 182, 4, 92, 89, - 20, 9, 34, 92, 4, 182, 4, 99, 53, 20, 9, 34, 92, 4, 223, 7, 4, 182, 89, - 20, 9, 34, 92, 4, 223, 7, 4, 92, 89, 20, 9, 34, 92, 4, 221, 211, 4, 223, - 7, 89, 20, 9, 34, 92, 4, 221, 211, 4, 92, 89, 20, 9, 34, 92, 4, 223, 7, - 4, 221, 211, 89, 20, 9, 34, 229, 211, 4, 92, 4, 223, 7, 89, 20, 9, 34, - 229, 211, 4, 92, 4, 92, 89, 20, 9, 34, 213, 25, 4, 182, 4, 92, 89, 20, 9, - 34, 213, 25, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 223, 7, - 4, 92, 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, 92, 89, 20, 9, 34, 213, 25, - 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 92, 4, 99, 53, - 20, 9, 34, 213, 25, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 99, 4, 92, 4, - 92, 53, 20, 9, 34, 99, 4, 92, 4, 92, 89, 20, 9, 34, 248, 246, 4, 221, - 211, 4, 99, 53, 20, 9, 34, 199, 115, 4, 223, 7, 4, 99, 53, 20, 9, 34, - 199, 115, 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 199, 115, 4, 221, - 211, 4, 99, 53, 20, 9, 34, 199, 115, 4, 221, 211, 4, 131, 217, 100, 53, - 20, 9, 34, 199, 115, 4, 92, 4, 99, 53, 20, 9, 34, 199, 115, 4, 92, 4, - 131, 217, 100, 53, 20, 9, 34, 223, 7, 4, 92, 4, 99, 53, 20, 9, 34, 223, - 7, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 223, 7, 4, 92, 4, 131, 217, - 100, 53, 20, 9, 34, 205, 47, 4, 221, 211, 4, 131, 217, 100, 53, 20, 9, - 34, 205, 193, 4, 182, 4, 99, 53, 20, 9, 34, 203, 110, 4, 182, 4, 99, 53, - 20, 9, 34, 238, 27, 4, 182, 4, 99, 53, 20, 9, 34, 220, 36, 4, 223, 7, 4, - 99, 53, 20, 9, 34, 220, 36, 4, 92, 4, 99, 53, 20, 9, 34, 99, 4, 182, 4, - 99, 53, 20, 9, 34, 99, 4, 223, 7, 4, 99, 53, 20, 9, 34, 99, 4, 92, 4, 99, - 53, 20, 9, 34, 92, 4, 92, 4, 99, 53, 20, 9, 34, 208, 90, 4, 92, 4, 99, - 53, 20, 9, 34, 213, 25, 4, 182, 4, 99, 53, 20, 9, 34, 208, 90, 4, 92, 4, - 182, 89, 20, 9, 34, 220, 36, 4, 182, 4, 92, 89, 20, 9, 34, 251, 231, 4, - 92, 4, 99, 53, 20, 9, 34, 222, 107, 4, 92, 4, 99, 53, 20, 9, 34, 213, 25, - 4, 223, 7, 4, 182, 89, 20, 9, 34, 92, 4, 221, 211, 4, 99, 53, 20, 9, 34, - 220, 36, 4, 223, 7, 4, 92, 89, 20, 9, 34, 222, 107, 4, 92, 4, 92, 53, 20, - 9, 34, 220, 36, 4, 223, 7, 4, 92, 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, - 182, 53, 20, 9, 34, 223, 7, 4, 182, 4, 99, 53, 20, 9, 34, 182, 4, 223, 7, - 4, 99, 53, 20, 9, 34, 92, 4, 223, 7, 4, 99, 53, 20, 9, 34, 233, 47, 4, - 92, 4, 99, 53, 20, 9, 34, 248, 246, 4, 182, 4, 99, 53, 20, 9, 34, 222, - 107, 4, 92, 4, 92, 89, 20, 9, 34, 251, 231, 4, 223, 7, 4, 92, 89, 20, 9, - 34, 205, 193, 4, 92, 4, 92, 89, 20, 9, 34, 205, 47, 4, 221, 211, 4, 99, - 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, 99, 53, 20, 9, 34, 205, 166, 251, - 194, 9, 34, 205, 163, 196, 40, 250, 220, 221, 33, 201, 64, 3, 76, 20, 9, - 34, 208, 86, 196, 40, 250, 220, 221, 33, 201, 64, 3, 76, 20, 9, 34, 251, - 171, 76, 20, 9, 34, 251, 213, 76, 20, 9, 34, 215, 235, 76, 20, 9, 34, - 205, 164, 76, 20, 9, 34, 207, 132, 76, 20, 9, 34, 251, 199, 76, 20, 9, - 34, 193, 153, 76, 20, 9, 34, 205, 163, 76, 20, 9, 34, 205, 161, 251, 199, - 193, 152, 9, 34, 223, 22, 206, 249, 56, 9, 34, 248, 151, 251, 31, 251, - 32, 9, 34, 200, 242, 193, 191, 199, 244, 9, 34, 250, 121, 193, 191, 223, - 23, 67, 205, 33, 67, 204, 178, 67, 204, 110, 67, 204, 99, 67, 204, 88, - 67, 204, 77, 67, 204, 66, 67, 204, 55, 67, 204, 44, 67, 205, 32, 67, 205, - 21, 67, 205, 10, 67, 204, 255, 67, 204, 244, 67, 204, 233, 67, 204, 222, - 208, 221, 232, 146, 40, 81, 242, 74, 208, 221, 232, 146, 40, 81, 154, - 242, 74, 208, 221, 232, 146, 40, 81, 154, 232, 80, 201, 63, 208, 221, - 232, 146, 40, 81, 242, 83, 208, 221, 232, 146, 40, 81, 204, 25, 208, 221, - 232, 146, 40, 81, 233, 216, 77, 208, 221, 232, 146, 40, 81, 208, 13, 77, - 208, 221, 232, 146, 40, 81, 45, 63, 219, 187, 248, 53, 208, 221, 232, - 146, 40, 81, 50, 63, 219, 187, 248, 49, 208, 221, 232, 146, 40, 81, 228, - 241, 234, 120, 33, 34, 45, 230, 70, 33, 34, 50, 230, 70, 33, 55, 198, - 153, 45, 230, 70, 33, 55, 198, 153, 50, 230, 70, 33, 217, 147, 45, 230, - 70, 33, 217, 147, 50, 230, 70, 33, 239, 44, 217, 146, 33, 34, 45, 132, - 60, 33, 34, 50, 132, 60, 33, 198, 153, 45, 132, 60, 33, 198, 153, 50, - 132, 60, 33, 217, 147, 45, 132, 60, 33, 217, 147, 50, 132, 60, 33, 239, - 44, 217, 147, 60, 33, 38, 198, 123, 45, 230, 70, 33, 38, 198, 123, 50, - 230, 70, 208, 221, 232, 146, 40, 81, 105, 75, 219, 236, 208, 221, 232, - 146, 40, 81, 234, 115, 237, 215, 208, 221, 232, 146, 40, 81, 234, 104, - 237, 215, 208, 221, 232, 146, 40, 81, 130, 219, 112, 208, 221, 232, 146, - 40, 81, 193, 135, 130, 219, 112, 208, 221, 232, 146, 40, 81, 45, 210, - 113, 208, 221, 232, 146, 40, 81, 50, 210, 113, 208, 221, 232, 146, 40, - 81, 45, 238, 171, 248, 53, 208, 221, 232, 146, 40, 81, 50, 238, 171, 248, - 53, 208, 221, 232, 146, 40, 81, 45, 198, 42, 203, 103, 248, 53, 208, 221, - 232, 146, 40, 81, 50, 198, 42, 203, 103, 248, 53, 208, 221, 232, 146, 40, - 81, 45, 62, 219, 187, 248, 53, 208, 221, 232, 146, 40, 81, 50, 62, 219, - 187, 248, 53, 208, 221, 232, 146, 40, 81, 45, 55, 251, 116, 248, 53, 208, - 221, 232, 146, 40, 81, 50, 55, 251, 116, 248, 53, 208, 221, 232, 146, 40, - 81, 45, 251, 116, 248, 53, 208, 221, 232, 146, 40, 81, 50, 251, 116, 248, - 53, 208, 221, 232, 146, 40, 81, 45, 239, 2, 248, 53, 208, 221, 232, 146, - 40, 81, 50, 239, 2, 248, 53, 208, 221, 232, 146, 40, 81, 45, 63, 239, 2, - 248, 53, 208, 221, 232, 146, 40, 81, 50, 63, 239, 2, 248, 53, 204, 0, - 236, 140, 63, 204, 0, 236, 140, 208, 221, 232, 146, 40, 81, 45, 51, 248, - 53, 208, 221, 232, 146, 40, 81, 50, 51, 248, 53, 237, 214, 210, 254, 247, - 18, 210, 254, 193, 135, 210, 254, 55, 193, 135, 210, 254, 237, 214, 130, - 219, 112, 247, 18, 130, 219, 112, 193, 135, 130, 219, 112, 2, 242, 74, 2, - 154, 242, 74, 2, 232, 80, 201, 63, 2, 204, 25, 2, 242, 83, 2, 208, 13, - 77, 2, 233, 216, 77, 2, 234, 115, 237, 215, 2, 45, 210, 113, 2, 50, 210, - 113, 2, 45, 238, 171, 248, 53, 2, 50, 238, 171, 248, 53, 2, 45, 198, 42, - 203, 103, 248, 53, 2, 50, 198, 42, 203, 103, 248, 53, 2, 31, 56, 2, 251, - 137, 2, 250, 193, 2, 108, 56, 2, 228, 87, 2, 219, 180, 56, 2, 230, 204, - 56, 2, 234, 43, 56, 2, 207, 19, 202, 23, 2, 236, 155, 56, 2, 210, 13, 56, - 2, 242, 72, 250, 182, 9, 233, 69, 76, 20, 9, 199, 169, 4, 233, 69, 58, 9, - 237, 244, 76, 20, 9, 199, 216, 232, 117, 9, 222, 51, 76, 20, 9, 233, 71, - 76, 20, 9, 233, 71, 216, 217, 20, 9, 237, 246, 76, 20, 9, 237, 246, 216, - 217, 20, 9, 222, 53, 76, 20, 9, 222, 53, 216, 217, 20, 9, 203, 156, 76, - 20, 9, 203, 156, 216, 217, 20, 9, 200, 207, 76, 20, 9, 200, 207, 216, - 217, 20, 9, 1, 230, 58, 76, 20, 9, 1, 131, 4, 217, 142, 93, 76, 20, 9, 1, - 131, 4, 217, 142, 93, 53, 20, 9, 1, 131, 4, 230, 58, 93, 76, 20, 9, 1, - 131, 4, 230, 58, 93, 53, 20, 9, 1, 193, 134, 4, 230, 58, 93, 76, 20, 9, - 1, 193, 134, 4, 230, 58, 93, 53, 20, 9, 1, 131, 4, 230, 58, 248, 233, 76, - 20, 9, 1, 131, 4, 230, 58, 248, 233, 53, 20, 9, 1, 99, 4, 230, 58, 93, - 76, 20, 9, 1, 99, 4, 230, 58, 93, 53, 20, 9, 1, 99, 4, 230, 58, 93, 89, - 20, 9, 1, 99, 4, 230, 58, 93, 216, 217, 20, 9, 1, 131, 76, 20, 9, 1, 131, - 53, 20, 9, 1, 248, 246, 76, 20, 9, 1, 248, 246, 53, 20, 9, 1, 248, 246, - 89, 20, 9, 1, 248, 246, 216, 217, 20, 9, 1, 199, 115, 217, 63, 76, 20, 9, - 1, 199, 115, 217, 63, 53, 20, 9, 1, 199, 115, 76, 20, 9, 1, 199, 115, 53, - 20, 9, 1, 199, 115, 89, 20, 9, 1, 199, 115, 216, 217, 20, 9, 1, 199, 30, - 76, 20, 9, 1, 199, 30, 53, 20, 9, 1, 199, 30, 89, 20, 9, 1, 199, 30, 216, - 217, 20, 9, 1, 223, 7, 76, 20, 9, 1, 223, 7, 53, 20, 9, 1, 223, 7, 89, - 20, 9, 1, 223, 7, 216, 217, 20, 9, 1, 182, 76, 20, 9, 1, 182, 53, 20, 9, - 1, 182, 89, 20, 9, 1, 182, 216, 217, 20, 9, 1, 221, 211, 76, 20, 9, 1, - 221, 211, 53, 20, 9, 1, 221, 211, 89, 20, 9, 1, 221, 211, 216, 217, 20, - 9, 1, 238, 4, 76, 20, 9, 1, 238, 4, 53, 20, 9, 1, 199, 42, 76, 20, 9, 1, - 199, 42, 53, 20, 9, 1, 207, 72, 76, 20, 9, 1, 207, 72, 53, 20, 9, 1, 191, - 114, 76, 20, 9, 1, 191, 114, 53, 20, 9, 1, 205, 47, 76, 20, 9, 1, 205, - 47, 53, 20, 9, 1, 205, 47, 89, 20, 9, 1, 205, 47, 216, 217, 20, 9, 1, - 203, 110, 76, 20, 9, 1, 203, 110, 53, 20, 9, 1, 203, 110, 89, 20, 9, 1, - 203, 110, 216, 217, 20, 9, 1, 205, 193, 76, 20, 9, 1, 205, 193, 53, 20, - 9, 1, 205, 193, 89, 20, 9, 1, 205, 193, 216, 217, 20, 9, 1, 238, 27, 76, - 20, 9, 1, 238, 27, 53, 20, 9, 1, 238, 27, 89, 20, 9, 1, 238, 27, 216, - 217, 20, 9, 1, 199, 220, 76, 20, 9, 1, 199, 220, 53, 20, 9, 1, 199, 220, - 89, 20, 9, 1, 199, 220, 216, 217, 20, 9, 1, 191, 117, 76, 20, 9, 1, 191, - 117, 53, 20, 9, 1, 191, 117, 89, 20, 9, 1, 191, 117, 216, 217, 20, 9, 1, - 251, 231, 76, 20, 9, 1, 251, 231, 53, 20, 9, 1, 251, 231, 89, 20, 9, 1, - 251, 231, 216, 217, 20, 9, 1, 231, 87, 76, 20, 9, 1, 231, 87, 53, 20, 9, - 1, 231, 87, 89, 20, 9, 1, 231, 87, 216, 217, 20, 9, 1, 233, 47, 76, 20, - 9, 1, 233, 47, 53, 20, 9, 1, 233, 47, 89, 20, 9, 1, 233, 47, 216, 217, - 20, 9, 1, 208, 90, 76, 20, 9, 1, 208, 90, 53, 20, 9, 1, 208, 90, 89, 20, - 9, 1, 208, 90, 216, 217, 20, 9, 1, 222, 107, 76, 20, 9, 1, 222, 107, 53, - 20, 9, 1, 222, 107, 89, 20, 9, 1, 222, 107, 216, 217, 20, 9, 1, 220, 36, - 76, 20, 9, 1, 220, 36, 53, 20, 9, 1, 220, 36, 89, 20, 9, 1, 220, 36, 216, - 217, 20, 9, 1, 92, 76, 20, 9, 1, 92, 53, 20, 9, 1, 92, 89, 20, 9, 1, 92, - 216, 217, 20, 9, 1, 213, 25, 76, 20, 9, 1, 213, 25, 53, 20, 9, 1, 213, - 25, 89, 20, 9, 1, 213, 25, 216, 217, 20, 9, 1, 229, 211, 76, 20, 9, 1, - 229, 211, 53, 20, 9, 1, 229, 211, 89, 20, 9, 1, 229, 211, 216, 217, 20, - 9, 1, 193, 134, 76, 20, 9, 1, 193, 134, 53, 20, 9, 1, 131, 217, 100, 76, - 20, 9, 1, 131, 217, 100, 53, 20, 9, 1, 99, 76, 20, 9, 1, 99, 53, 20, 9, - 1, 99, 89, 20, 9, 1, 99, 216, 217, 20, 9, 34, 220, 36, 4, 131, 4, 217, - 142, 93, 76, 20, 9, 34, 220, 36, 4, 131, 4, 217, 142, 93, 53, 20, 9, 34, - 220, 36, 4, 131, 4, 230, 58, 93, 76, 20, 9, 34, 220, 36, 4, 131, 4, 230, - 58, 93, 53, 20, 9, 34, 220, 36, 4, 131, 4, 230, 58, 248, 233, 76, 20, 9, - 34, 220, 36, 4, 131, 4, 230, 58, 248, 233, 53, 20, 9, 34, 220, 36, 4, - 131, 76, 20, 9, 34, 220, 36, 4, 131, 53, 20, 191, 78, 193, 75, 213, 37, - 201, 247, 232, 78, 233, 216, 77, 232, 78, 207, 252, 77, 232, 78, 31, 56, - 232, 78, 236, 155, 56, 232, 78, 210, 13, 56, 232, 78, 251, 137, 232, 78, - 251, 49, 232, 78, 45, 210, 113, 232, 78, 50, 210, 113, 232, 78, 250, 193, - 232, 78, 108, 56, 232, 78, 242, 74, 232, 78, 228, 87, 232, 78, 232, 80, - 201, 63, 232, 78, 202, 23, 232, 78, 17, 191, 77, 232, 78, 17, 107, 232, - 78, 17, 109, 232, 78, 17, 138, 232, 78, 17, 134, 232, 78, 17, 149, 232, - 78, 17, 169, 232, 78, 17, 175, 232, 78, 17, 171, 232, 78, 17, 178, 232, - 78, 242, 83, 232, 78, 204, 25, 232, 78, 219, 180, 56, 232, 78, 234, 43, - 56, 232, 78, 230, 204, 56, 232, 78, 208, 13, 77, 232, 78, 242, 72, 250, - 182, 232, 78, 8, 6, 1, 65, 232, 78, 8, 6, 1, 250, 120, 232, 78, 8, 6, 1, - 247, 193, 232, 78, 8, 6, 1, 238, 127, 232, 78, 8, 6, 1, 71, 232, 78, 8, - 6, 1, 233, 175, 232, 78, 8, 6, 1, 232, 51, 232, 78, 8, 6, 1, 230, 116, - 232, 78, 8, 6, 1, 68, 232, 78, 8, 6, 1, 223, 35, 232, 78, 8, 6, 1, 222, - 152, 232, 78, 8, 6, 1, 172, 232, 78, 8, 6, 1, 218, 168, 232, 78, 8, 6, 1, - 215, 61, 232, 78, 8, 6, 1, 74, 232, 78, 8, 6, 1, 210, 236, 232, 78, 8, 6, - 1, 208, 104, 232, 78, 8, 6, 1, 146, 232, 78, 8, 6, 1, 206, 8, 232, 78, 8, - 6, 1, 200, 43, 232, 78, 8, 6, 1, 66, 232, 78, 8, 6, 1, 196, 12, 232, 78, - 8, 6, 1, 193, 224, 232, 78, 8, 6, 1, 192, 235, 232, 78, 8, 6, 1, 192, - 159, 232, 78, 8, 6, 1, 191, 166, 232, 78, 45, 51, 248, 53, 232, 78, 207, - 19, 202, 23, 232, 78, 50, 51, 248, 53, 232, 78, 243, 2, 252, 60, 232, 78, - 130, 219, 112, 232, 78, 230, 211, 252, 60, 232, 78, 8, 2, 1, 65, 232, 78, - 8, 2, 1, 250, 120, 232, 78, 8, 2, 1, 247, 193, 232, 78, 8, 2, 1, 238, - 127, 232, 78, 8, 2, 1, 71, 232, 78, 8, 2, 1, 233, 175, 232, 78, 8, 2, 1, - 232, 51, 232, 78, 8, 2, 1, 230, 116, 232, 78, 8, 2, 1, 68, 232, 78, 8, 2, - 1, 223, 35, 232, 78, 8, 2, 1, 222, 152, 232, 78, 8, 2, 1, 172, 232, 78, - 8, 2, 1, 218, 168, 232, 78, 8, 2, 1, 215, 61, 232, 78, 8, 2, 1, 74, 232, - 78, 8, 2, 1, 210, 236, 232, 78, 8, 2, 1, 208, 104, 232, 78, 8, 2, 1, 146, - 232, 78, 8, 2, 1, 206, 8, 232, 78, 8, 2, 1, 200, 43, 232, 78, 8, 2, 1, - 66, 232, 78, 8, 2, 1, 196, 12, 232, 78, 8, 2, 1, 193, 224, 232, 78, 8, 2, - 1, 192, 235, 232, 78, 8, 2, 1, 192, 159, 232, 78, 8, 2, 1, 191, 166, 232, - 78, 45, 238, 171, 248, 53, 232, 78, 81, 219, 112, 232, 78, 50, 238, 171, - 248, 53, 232, 78, 198, 152, 232, 78, 45, 63, 210, 113, 232, 78, 50, 63, - 210, 113, 150, 154, 232, 80, 201, 63, 150, 45, 239, 2, 248, 53, 150, 50, - 239, 2, 248, 53, 150, 154, 242, 74, 150, 72, 82, 236, 140, 150, 72, 1, - 193, 48, 150, 72, 1, 2, 65, 150, 72, 1, 2, 68, 150, 72, 1, 2, 66, 150, - 72, 1, 2, 71, 150, 72, 1, 2, 74, 150, 72, 1, 2, 170, 150, 72, 1, 2, 191, - 225, 150, 72, 1, 2, 192, 12, 150, 72, 1, 2, 197, 94, 150, 222, 48, 208, - 191, 202, 5, 77, 150, 72, 1, 65, 150, 72, 1, 68, 150, 72, 1, 66, 150, 72, - 1, 71, 150, 72, 1, 74, 150, 72, 1, 155, 150, 72, 1, 221, 166, 150, 72, 1, - 220, 232, 150, 72, 1, 222, 22, 150, 72, 1, 221, 67, 150, 72, 1, 188, 150, - 72, 1, 202, 222, 150, 72, 1, 201, 4, 150, 72, 1, 205, 68, 150, 72, 1, - 202, 46, 150, 72, 1, 190, 190, 150, 72, 1, 198, 193, 150, 72, 1, 197, 94, - 150, 72, 1, 199, 145, 150, 72, 1, 159, 150, 72, 1, 180, 150, 72, 1, 213, - 219, 150, 72, 1, 212, 178, 150, 72, 1, 214, 121, 150, 72, 1, 213, 43, - 150, 72, 1, 140, 150, 72, 1, 229, 158, 150, 72, 1, 228, 159, 150, 72, 1, - 229, 245, 150, 72, 1, 229, 23, 150, 72, 1, 174, 150, 72, 1, 216, 100, - 150, 72, 1, 215, 155, 150, 72, 1, 216, 232, 150, 72, 1, 216, 12, 150, 72, - 1, 170, 150, 72, 1, 191, 225, 150, 72, 1, 192, 12, 150, 72, 1, 165, 150, - 72, 1, 207, 1, 150, 72, 1, 206, 68, 150, 72, 1, 207, 113, 150, 72, 1, - 206, 162, 150, 72, 1, 193, 190, 150, 72, 1, 215, 61, 150, 72, 195, 20, - 202, 5, 77, 150, 72, 204, 30, 202, 5, 77, 150, 30, 233, 3, 150, 30, 1, - 221, 113, 150, 30, 1, 201, 167, 150, 30, 1, 221, 106, 150, 30, 1, 213, - 204, 150, 30, 1, 213, 202, 150, 30, 1, 213, 201, 150, 30, 1, 198, 168, - 150, 30, 1, 201, 156, 150, 30, 1, 206, 239, 150, 30, 1, 206, 234, 150, - 30, 1, 206, 231, 150, 30, 1, 206, 224, 150, 30, 1, 206, 219, 150, 30, 1, - 206, 214, 150, 30, 1, 206, 225, 150, 30, 1, 206, 237, 150, 30, 1, 216, - 77, 150, 30, 1, 209, 169, 150, 30, 1, 201, 164, 150, 30, 1, 209, 158, - 150, 30, 1, 202, 160, 150, 30, 1, 201, 161, 150, 30, 1, 223, 222, 150, - 30, 1, 243, 24, 150, 30, 1, 201, 171, 150, 30, 1, 243, 91, 150, 30, 1, - 221, 188, 150, 30, 1, 199, 7, 150, 30, 1, 209, 209, 150, 30, 1, 229, 142, - 150, 30, 1, 65, 150, 30, 1, 252, 25, 150, 30, 1, 170, 150, 30, 1, 192, - 129, 150, 30, 1, 234, 65, 150, 30, 1, 71, 150, 30, 1, 192, 67, 150, 30, - 1, 192, 80, 150, 30, 1, 74, 150, 30, 1, 193, 190, 150, 30, 1, 193, 176, - 150, 30, 1, 211, 151, 150, 30, 1, 192, 12, 150, 30, 1, 66, 150, 30, 1, - 193, 107, 150, 30, 1, 193, 125, 150, 30, 1, 193, 86, 150, 30, 1, 191, - 225, 150, 30, 1, 233, 242, 150, 30, 1, 192, 33, 150, 30, 1, 68, 232, 78, - 247, 24, 56, 232, 78, 209, 8, 56, 232, 78, 213, 12, 56, 232, 78, 217, - 146, 232, 78, 248, 22, 164, 232, 78, 192, 71, 56, 232, 78, 193, 31, 56, - 150, 232, 141, 156, 195, 135, 150, 118, 57, 150, 196, 66, 57, 150, 96, - 57, 150, 235, 119, 57, 150, 62, 201, 190, 150, 63, 243, 10, 223, 106, - 251, 96, 251, 127, 223, 106, 251, 96, 204, 10, 223, 106, 251, 96, 199, - 80, 211, 175, 207, 43, 246, 239, 207, 43, 246, 239, 32, 78, 5, 250, 104, - 65, 32, 78, 5, 250, 73, 71, 32, 78, 5, 250, 82, 68, 32, 78, 5, 250, 50, - 74, 32, 78, 5, 250, 100, 66, 32, 78, 5, 250, 119, 238, 32, 32, 78, 5, - 250, 66, 237, 146, 32, 78, 5, 250, 106, 237, 44, 32, 78, 5, 250, 96, 236, - 174, 32, 78, 5, 250, 60, 235, 89, 32, 78, 5, 250, 54, 223, 32, 32, 78, 5, - 250, 65, 223, 10, 32, 78, 5, 250, 75, 222, 201, 32, 78, 5, 250, 46, 222, - 182, 32, 78, 5, 250, 34, 155, 32, 78, 5, 250, 67, 222, 22, 32, 78, 5, - 250, 44, 221, 166, 32, 78, 5, 250, 41, 221, 67, 32, 78, 5, 250, 30, 220, - 232, 32, 78, 5, 250, 31, 174, 32, 78, 5, 250, 97, 216, 232, 32, 78, 5, - 250, 38, 216, 100, 32, 78, 5, 250, 95, 216, 12, 32, 78, 5, 250, 87, 215, - 155, 32, 78, 5, 250, 108, 180, 32, 78, 5, 250, 86, 214, 121, 32, 78, 5, - 250, 80, 213, 219, 32, 78, 5, 250, 59, 213, 43, 32, 78, 5, 250, 56, 212, - 178, 32, 78, 5, 250, 115, 168, 32, 78, 5, 250, 39, 210, 63, 32, 78, 5, - 250, 72, 209, 185, 32, 78, 5, 250, 99, 209, 73, 32, 78, 5, 250, 61, 208, - 165, 32, 78, 5, 250, 94, 208, 96, 32, 78, 5, 250, 33, 208, 75, 32, 78, 5, - 250, 89, 208, 57, 32, 78, 5, 250, 78, 208, 45, 32, 78, 5, 250, 51, 165, - 32, 78, 5, 250, 83, 207, 113, 32, 78, 5, 250, 58, 207, 1, 32, 78, 5, 250, - 117, 206, 162, 32, 78, 5, 250, 84, 206, 68, 32, 78, 5, 250, 79, 188, 32, - 78, 5, 250, 102, 205, 68, 32, 78, 5, 250, 70, 202, 222, 32, 78, 5, 250, - 98, 202, 46, 32, 78, 5, 250, 53, 201, 4, 32, 78, 5, 250, 52, 190, 190, - 32, 78, 5, 250, 113, 199, 145, 32, 78, 5, 250, 74, 198, 193, 32, 78, 5, - 250, 111, 159, 32, 78, 5, 250, 42, 197, 94, 32, 78, 5, 250, 57, 193, 190, - 32, 78, 5, 250, 36, 193, 125, 32, 78, 5, 250, 71, 193, 86, 32, 78, 5, - 250, 69, 193, 48, 32, 78, 5, 250, 93, 191, 123, 32, 78, 5, 250, 37, 191, - 87, 32, 78, 5, 250, 90, 191, 7, 32, 78, 5, 250, 85, 254, 215, 32, 78, 5, - 250, 68, 254, 103, 32, 78, 5, 250, 27, 250, 163, 32, 78, 5, 250, 40, 235, - 45, 32, 78, 5, 250, 23, 235, 44, 32, 78, 5, 250, 63, 212, 110, 32, 78, 5, - 250, 81, 208, 163, 32, 78, 5, 250, 49, 208, 167, 32, 78, 5, 250, 35, 207, - 180, 32, 78, 5, 250, 77, 207, 179, 32, 78, 5, 250, 43, 206, 155, 32, 78, - 5, 250, 45, 199, 246, 32, 78, 5, 250, 25, 197, 41, 32, 78, 5, 250, 22, - 109, 32, 78, 16, 250, 92, 32, 78, 16, 250, 91, 32, 78, 16, 250, 88, 32, - 78, 16, 250, 76, 32, 78, 16, 250, 64, 32, 78, 16, 250, 62, 32, 78, 16, - 250, 55, 32, 78, 16, 250, 48, 32, 78, 16, 250, 47, 32, 78, 16, 250, 32, - 32, 78, 16, 250, 29, 32, 78, 16, 250, 28, 32, 78, 16, 250, 26, 32, 78, - 16, 250, 24, 32, 78, 157, 250, 21, 217, 90, 32, 78, 157, 250, 20, 193, - 35, 32, 78, 157, 250, 19, 237, 128, 32, 78, 157, 250, 18, 234, 40, 32, - 78, 157, 250, 17, 217, 56, 32, 78, 157, 250, 16, 201, 110, 32, 78, 157, - 250, 15, 233, 223, 32, 78, 157, 250, 14, 207, 142, 32, 78, 157, 250, 13, - 203, 112, 32, 78, 157, 250, 12, 229, 237, 32, 78, 157, 250, 11, 201, 255, - 32, 78, 157, 250, 10, 248, 109, 32, 78, 157, 250, 9, 238, 239, 32, 78, - 157, 250, 8, 247, 250, 32, 78, 157, 250, 7, 193, 95, 32, 78, 157, 250, 6, - 249, 84, 32, 78, 157, 250, 5, 211, 115, 32, 78, 157, 250, 4, 201, 223, - 32, 78, 157, 250, 3, 238, 136, 32, 78, 215, 221, 250, 2, 222, 74, 32, 78, - 215, 221, 250, 1, 222, 85, 32, 78, 157, 250, 0, 211, 131, 32, 78, 157, - 249, 255, 193, 62, 32, 78, 157, 249, 254, 32, 78, 215, 221, 249, 253, - 251, 7, 32, 78, 215, 221, 249, 252, 216, 178, 32, 78, 157, 249, 251, 248, - 21, 32, 78, 157, 249, 250, 230, 250, 32, 78, 157, 249, 249, 32, 78, 157, - 249, 248, 193, 26, 32, 78, 157, 249, 247, 32, 78, 157, 249, 246, 32, 78, - 157, 249, 245, 228, 187, 32, 78, 157, 249, 244, 32, 78, 157, 249, 243, - 32, 78, 157, 249, 242, 32, 78, 215, 221, 249, 240, 197, 56, 32, 78, 157, - 249, 239, 32, 78, 157, 249, 238, 32, 78, 157, 249, 237, 242, 213, 32, 78, - 157, 249, 236, 32, 78, 157, 249, 235, 32, 78, 157, 249, 234, 231, 196, - 32, 78, 157, 249, 233, 250, 248, 32, 78, 157, 249, 232, 32, 78, 157, 249, - 231, 32, 78, 157, 249, 230, 32, 78, 157, 249, 229, 32, 78, 157, 249, 228, - 32, 78, 157, 249, 227, 32, 78, 157, 249, 226, 32, 78, 157, 249, 225, 32, - 78, 157, 249, 224, 32, 78, 157, 249, 223, 215, 213, 32, 78, 157, 249, - 222, 32, 78, 157, 249, 221, 197, 254, 32, 78, 157, 249, 220, 32, 78, 157, - 249, 219, 32, 78, 157, 249, 218, 32, 78, 157, 249, 217, 32, 78, 157, 249, - 216, 32, 78, 157, 249, 215, 32, 78, 157, 249, 214, 32, 78, 157, 249, 213, - 32, 78, 157, 249, 212, 32, 78, 157, 249, 211, 32, 78, 157, 249, 210, 32, - 78, 157, 249, 209, 229, 200, 32, 78, 157, 249, 188, 232, 155, 32, 78, - 157, 249, 185, 249, 59, 32, 78, 157, 249, 180, 201, 232, 32, 78, 157, - 249, 179, 57, 32, 78, 157, 249, 178, 32, 78, 157, 249, 177, 200, 131, 32, - 78, 157, 249, 176, 32, 78, 157, 249, 175, 32, 78, 157, 249, 174, 193, 90, - 243, 138, 32, 78, 157, 249, 173, 243, 138, 32, 78, 157, 249, 172, 243, - 139, 232, 113, 32, 78, 157, 249, 171, 193, 93, 32, 78, 157, 249, 170, 32, - 78, 157, 249, 169, 32, 78, 215, 221, 249, 168, 236, 235, 32, 78, 157, - 249, 167, 32, 78, 157, 249, 166, 32, 78, 157, 249, 164, 32, 78, 157, 249, - 163, 32, 78, 157, 249, 162, 32, 78, 157, 249, 161, 237, 218, 32, 78, 157, - 249, 160, 32, 78, 157, 249, 159, 32, 78, 157, 249, 158, 32, 78, 157, 249, - 157, 32, 78, 157, 249, 156, 32, 78, 157, 195, 82, 249, 241, 32, 78, 157, - 195, 82, 249, 208, 32, 78, 157, 195, 82, 249, 207, 32, 78, 157, 195, 82, - 249, 206, 32, 78, 157, 195, 82, 249, 205, 32, 78, 157, 195, 82, 249, 204, - 32, 78, 157, 195, 82, 249, 203, 32, 78, 157, 195, 82, 249, 202, 32, 78, - 157, 195, 82, 249, 201, 32, 78, 157, 195, 82, 249, 200, 32, 78, 157, 195, - 82, 249, 199, 32, 78, 157, 195, 82, 249, 198, 32, 78, 157, 195, 82, 249, - 197, 32, 78, 157, 195, 82, 249, 196, 32, 78, 157, 195, 82, 249, 195, 32, - 78, 157, 195, 82, 249, 194, 32, 78, 157, 195, 82, 249, 193, 32, 78, 157, - 195, 82, 249, 192, 32, 78, 157, 195, 82, 249, 191, 32, 78, 157, 195, 82, - 249, 190, 32, 78, 157, 195, 82, 249, 189, 32, 78, 157, 195, 82, 249, 187, - 32, 78, 157, 195, 82, 249, 186, 32, 78, 157, 195, 82, 249, 184, 32, 78, - 157, 195, 82, 249, 183, 32, 78, 157, 195, 82, 249, 182, 32, 78, 157, 195, - 82, 249, 181, 32, 78, 157, 195, 82, 249, 165, 32, 78, 157, 195, 82, 249, - 155, 252, 18, 193, 23, 204, 11, 219, 112, 252, 18, 193, 23, 204, 11, 236, - 140, 252, 18, 243, 126, 77, 252, 18, 31, 107, 252, 18, 31, 109, 252, 18, - 31, 138, 252, 18, 31, 134, 252, 18, 31, 149, 252, 18, 31, 169, 252, 18, - 31, 175, 252, 18, 31, 171, 252, 18, 31, 178, 252, 18, 31, 199, 95, 252, - 18, 31, 197, 32, 252, 18, 31, 198, 249, 252, 18, 31, 232, 135, 252, 18, - 31, 233, 15, 252, 18, 31, 202, 120, 252, 18, 31, 203, 241, 252, 18, 31, - 234, 153, 252, 18, 31, 213, 169, 252, 18, 31, 91, 228, 140, 252, 18, 31, - 105, 228, 140, 252, 18, 31, 115, 228, 140, 252, 18, 31, 232, 128, 228, - 140, 252, 18, 31, 232, 226, 228, 140, 252, 18, 31, 202, 136, 228, 140, - 252, 18, 31, 203, 247, 228, 140, 252, 18, 31, 234, 164, 228, 140, 252, - 18, 31, 213, 175, 228, 140, 252, 18, 31, 91, 189, 252, 18, 31, 105, 189, - 252, 18, 31, 115, 189, 252, 18, 31, 232, 128, 189, 252, 18, 31, 232, 226, - 189, 252, 18, 31, 202, 136, 189, 252, 18, 31, 203, 247, 189, 252, 18, 31, - 234, 164, 189, 252, 18, 31, 213, 175, 189, 252, 18, 31, 199, 96, 189, - 252, 18, 31, 197, 33, 189, 252, 18, 31, 198, 250, 189, 252, 18, 31, 232, - 136, 189, 252, 18, 31, 233, 16, 189, 252, 18, 31, 202, 121, 189, 252, 18, - 31, 203, 242, 189, 252, 18, 31, 234, 154, 189, 252, 18, 31, 213, 170, - 189, 252, 18, 193, 110, 249, 75, 196, 90, 252, 18, 193, 110, 232, 238, - 200, 224, 252, 18, 193, 110, 205, 57, 200, 224, 252, 18, 193, 110, 199, - 1, 200, 224, 252, 18, 193, 110, 232, 121, 200, 224, 252, 18, 235, 92, - 216, 228, 232, 238, 200, 224, 252, 18, 219, 93, 216, 228, 232, 238, 200, - 224, 252, 18, 216, 228, 205, 57, 200, 224, 252, 18, 216, 228, 199, 1, - 200, 224, 35, 252, 50, 250, 165, 91, 208, 22, 35, 252, 50, 250, 165, 91, - 230, 70, 35, 252, 50, 250, 165, 91, 235, 115, 35, 252, 50, 250, 165, 149, - 35, 252, 50, 250, 165, 233, 15, 35, 252, 50, 250, 165, 232, 226, 228, - 140, 35, 252, 50, 250, 165, 232, 226, 189, 35, 252, 50, 250, 165, 233, - 16, 189, 35, 252, 50, 250, 165, 232, 226, 199, 203, 35, 252, 50, 250, - 165, 199, 96, 199, 203, 35, 252, 50, 250, 165, 233, 16, 199, 203, 35, - 252, 50, 250, 165, 91, 228, 141, 199, 203, 35, 252, 50, 250, 165, 232, - 226, 228, 141, 199, 203, 35, 252, 50, 250, 165, 91, 198, 230, 199, 203, - 35, 252, 50, 250, 165, 232, 226, 198, 230, 199, 203, 35, 252, 50, 250, - 165, 232, 226, 201, 94, 35, 252, 50, 250, 165, 199, 96, 201, 94, 35, 252, - 50, 250, 165, 233, 16, 201, 94, 35, 252, 50, 250, 165, 91, 228, 141, 201, - 94, 35, 252, 50, 250, 165, 232, 226, 228, 141, 201, 94, 35, 252, 50, 250, - 165, 91, 198, 230, 201, 94, 35, 252, 50, 250, 165, 199, 96, 198, 230, - 201, 94, 35, 252, 50, 250, 165, 233, 16, 198, 230, 201, 94, 35, 252, 50, - 250, 165, 199, 96, 216, 15, 35, 252, 50, 229, 194, 91, 209, 92, 35, 252, - 50, 199, 17, 107, 35, 252, 50, 229, 190, 107, 35, 252, 50, 234, 51, 109, - 35, 252, 50, 199, 17, 109, 35, 252, 50, 238, 132, 105, 235, 114, 35, 252, - 50, 234, 51, 105, 235, 114, 35, 252, 50, 197, 216, 149, 35, 252, 50, 197, - 216, 199, 95, 35, 252, 50, 197, 216, 199, 96, 251, 157, 20, 35, 252, 50, - 229, 190, 199, 95, 35, 252, 50, 216, 167, 199, 95, 35, 252, 50, 199, 17, - 199, 95, 35, 252, 50, 199, 17, 198, 249, 35, 252, 50, 197, 216, 233, 15, - 35, 252, 50, 197, 216, 233, 16, 251, 157, 20, 35, 252, 50, 229, 190, 233, - 15, 35, 252, 50, 199, 17, 233, 15, 35, 252, 50, 199, 17, 91, 228, 140, - 35, 252, 50, 199, 17, 115, 228, 140, 35, 252, 50, 234, 51, 232, 226, 228, - 140, 35, 252, 50, 197, 216, 232, 226, 228, 140, 35, 252, 50, 199, 17, - 232, 226, 228, 140, 35, 252, 50, 247, 82, 232, 226, 228, 140, 35, 252, - 50, 214, 199, 232, 226, 228, 140, 35, 252, 50, 199, 17, 91, 189, 35, 252, - 50, 199, 17, 232, 226, 189, 35, 252, 50, 237, 109, 232, 226, 216, 15, 35, - 252, 50, 201, 47, 233, 16, 216, 15, 35, 91, 132, 56, 35, 91, 132, 3, 251, - 157, 20, 35, 105, 198, 254, 56, 35, 115, 208, 21, 56, 35, 192, 78, 56, - 35, 199, 204, 56, 35, 235, 116, 56, 35, 211, 170, 56, 35, 105, 211, 169, - 56, 35, 115, 211, 169, 56, 35, 232, 128, 211, 169, 56, 35, 232, 226, 211, - 169, 56, 35, 216, 161, 56, 35, 220, 151, 249, 75, 56, 35, 219, 85, 56, - 35, 211, 16, 56, 35, 192, 211, 56, 35, 250, 226, 56, 35, 250, 243, 56, - 35, 230, 220, 56, 35, 197, 171, 249, 75, 56, 35, 191, 78, 56, 35, 91, - 208, 23, 56, 35, 202, 162, 56, 35, 223, 143, 56, 213, 32, 56, 206, 136, - 203, 237, 56, 206, 136, 196, 106, 56, 206, 136, 204, 17, 56, 206, 136, - 203, 175, 56, 206, 136, 236, 250, 203, 175, 56, 206, 136, 202, 186, 56, - 206, 136, 237, 104, 56, 206, 136, 208, 5, 56, 206, 136, 203, 254, 56, - 206, 136, 235, 67, 56, 206, 136, 250, 220, 56, 206, 136, 247, 17, 56, - 250, 211, 113, 35, 16, 199, 167, 207, 3, 209, 223, 236, 227, 3, 210, 51, - 209, 223, 236, 227, 3, 209, 84, 229, 235, 209, 223, 236, 227, 3, 199, - 170, 229, 235, 209, 223, 236, 227, 3, 247, 105, 209, 223, 236, 227, 3, - 243, 86, 209, 223, 236, 227, 3, 193, 35, 209, 223, 236, 227, 3, 229, 200, - 209, 223, 236, 227, 3, 231, 188, 209, 223, 236, 227, 3, 198, 184, 209, - 223, 236, 227, 3, 57, 209, 223, 236, 227, 3, 248, 69, 209, 223, 236, 227, - 3, 203, 78, 209, 223, 236, 227, 3, 242, 206, 209, 223, 236, 227, 3, 217, - 89, 209, 223, 236, 227, 3, 217, 26, 209, 223, 236, 227, 3, 205, 108, 209, - 223, 236, 227, 3, 219, 141, 209, 223, 236, 227, 3, 248, 92, 209, 223, - 236, 227, 3, 247, 89, 209, 101, 209, 223, 236, 227, 3, 236, 156, 209, - 223, 236, 227, 3, 242, 80, 209, 223, 236, 227, 3, 202, 83, 209, 223, 236, - 227, 3, 242, 81, 209, 223, 236, 227, 3, 248, 254, 209, 223, 236, 227, 3, - 203, 65, 209, 223, 236, 227, 3, 228, 187, 209, 223, 236, 227, 3, 229, - 148, 209, 223, 236, 227, 3, 247, 245, 219, 212, 209, 223, 236, 227, 3, - 247, 78, 209, 223, 236, 227, 3, 207, 142, 209, 223, 236, 227, 3, 234, - 214, 209, 223, 236, 227, 3, 235, 124, 209, 223, 236, 227, 3, 197, 72, - 209, 223, 236, 227, 3, 249, 1, 209, 223, 236, 227, 3, 209, 102, 197, 254, - 209, 223, 236, 227, 3, 195, 47, 209, 223, 236, 227, 3, 210, 132, 209, - 223, 236, 227, 3, 206, 125, 209, 223, 236, 227, 3, 219, 125, 209, 223, - 236, 227, 3, 210, 248, 249, 146, 209, 223, 236, 227, 3, 232, 182, 209, - 223, 236, 227, 3, 230, 212, 209, 223, 236, 227, 3, 201, 50, 209, 223, - 236, 227, 3, 2, 250, 132, 209, 223, 236, 227, 3, 193, 135, 249, 97, 209, - 223, 236, 227, 3, 33, 211, 172, 106, 218, 181, 1, 65, 218, 181, 1, 71, - 218, 181, 1, 250, 120, 218, 181, 1, 248, 204, 218, 181, 1, 232, 51, 218, - 181, 1, 238, 127, 218, 181, 1, 68, 218, 181, 1, 193, 224, 218, 181, 1, - 191, 166, 218, 181, 1, 199, 51, 218, 181, 1, 223, 35, 218, 181, 1, 222, - 152, 218, 181, 1, 208, 104, 218, 181, 1, 172, 218, 181, 1, 218, 168, 218, - 181, 1, 215, 61, 218, 181, 1, 216, 17, 218, 181, 1, 213, 80, 218, 181, 1, - 66, 218, 181, 1, 210, 236, 218, 181, 1, 221, 102, 218, 181, 1, 146, 218, - 181, 1, 206, 8, 218, 181, 1, 200, 43, 218, 181, 1, 197, 135, 218, 181, 1, - 251, 132, 218, 181, 1, 234, 103, 218, 181, 1, 230, 116, 218, 181, 1, 192, - 235, 247, 95, 1, 65, 247, 95, 1, 210, 222, 247, 95, 1, 238, 127, 247, 95, - 1, 172, 247, 95, 1, 196, 28, 247, 95, 1, 146, 247, 95, 1, 219, 242, 247, - 95, 1, 254, 215, 247, 95, 1, 208, 104, 247, 95, 1, 250, 120, 247, 95, 1, - 218, 168, 247, 95, 1, 74, 247, 95, 1, 238, 34, 247, 95, 1, 200, 43, 247, - 95, 1, 203, 167, 247, 95, 1, 203, 166, 247, 95, 1, 206, 8, 247, 95, 1, - 247, 192, 247, 95, 1, 66, 247, 95, 1, 213, 80, 247, 95, 1, 192, 235, 247, - 95, 1, 215, 61, 247, 95, 1, 197, 134, 247, 95, 1, 210, 236, 247, 95, 1, - 201, 178, 247, 95, 1, 68, 247, 95, 1, 71, 247, 95, 1, 196, 25, 247, 95, - 1, 222, 152, 247, 95, 1, 222, 143, 247, 95, 1, 214, 164, 247, 95, 1, 196, - 30, 247, 95, 1, 232, 51, 247, 95, 1, 231, 242, 247, 95, 1, 201, 118, 247, - 95, 1, 201, 117, 247, 95, 1, 214, 70, 247, 95, 1, 223, 199, 247, 95, 1, - 247, 191, 247, 95, 1, 197, 135, 247, 95, 1, 196, 27, 247, 95, 1, 206, - 110, 247, 95, 1, 217, 16, 247, 95, 1, 217, 15, 247, 95, 1, 217, 14, 247, - 95, 1, 217, 13, 247, 95, 1, 219, 241, 247, 95, 1, 234, 218, 247, 95, 1, - 196, 26, 94, 234, 54, 198, 229, 77, 94, 234, 54, 17, 107, 94, 234, 54, - 17, 109, 94, 234, 54, 17, 138, 94, 234, 54, 17, 134, 94, 234, 54, 17, - 149, 94, 234, 54, 17, 169, 94, 234, 54, 17, 175, 94, 234, 54, 17, 171, - 94, 234, 54, 17, 178, 94, 234, 54, 31, 199, 95, 94, 234, 54, 31, 197, 32, - 94, 234, 54, 31, 198, 249, 94, 234, 54, 31, 232, 135, 94, 234, 54, 31, - 233, 15, 94, 234, 54, 31, 202, 120, 94, 234, 54, 31, 203, 241, 94, 234, - 54, 31, 234, 153, 94, 234, 54, 31, 213, 169, 94, 234, 54, 31, 91, 228, - 140, 94, 234, 54, 31, 105, 228, 140, 94, 234, 54, 31, 115, 228, 140, 94, - 234, 54, 31, 232, 128, 228, 140, 94, 234, 54, 31, 232, 226, 228, 140, 94, - 234, 54, 31, 202, 136, 228, 140, 94, 234, 54, 31, 203, 247, 228, 140, 94, - 234, 54, 31, 234, 164, 228, 140, 94, 234, 54, 31, 213, 175, 228, 140, 39, - 43, 1, 65, 39, 43, 1, 249, 17, 39, 43, 1, 222, 22, 39, 43, 1, 237, 146, - 39, 43, 1, 71, 39, 43, 1, 195, 153, 39, 43, 1, 191, 87, 39, 43, 1, 229, - 245, 39, 43, 1, 199, 33, 39, 43, 1, 68, 39, 43, 1, 155, 39, 43, 1, 234, - 140, 39, 43, 1, 234, 114, 39, 43, 1, 234, 103, 39, 43, 1, 234, 12, 39, - 43, 1, 74, 39, 43, 1, 210, 63, 39, 43, 1, 203, 113, 39, 43, 1, 220, 232, - 39, 43, 1, 234, 34, 39, 43, 1, 234, 22, 39, 43, 1, 199, 145, 39, 43, 1, - 66, 39, 43, 1, 234, 143, 39, 43, 1, 209, 214, 39, 43, 1, 221, 197, 39, - 43, 1, 234, 181, 39, 43, 1, 234, 24, 39, 43, 1, 243, 127, 39, 43, 1, 223, - 199, 39, 43, 1, 196, 30, 39, 43, 1, 234, 5, 39, 43, 212, 134, 107, 39, - 43, 212, 134, 149, 39, 43, 212, 134, 199, 95, 39, 43, 212, 134, 233, 15, - 39, 43, 1, 192, 80, 39, 43, 1, 213, 16, 197, 161, 39, 43, 1, 202, 0, 197, - 161, 230, 231, 1, 251, 239, 230, 231, 1, 249, 117, 230, 231, 1, 231, 50, - 230, 231, 1, 238, 13, 230, 231, 1, 251, 234, 230, 231, 1, 208, 87, 230, - 231, 1, 223, 48, 230, 231, 1, 230, 83, 230, 231, 1, 198, 243, 230, 231, - 1, 234, 151, 230, 231, 1, 220, 189, 230, 231, 1, 220, 100, 230, 231, 1, - 217, 80, 230, 231, 1, 214, 201, 230, 231, 1, 223, 1, 230, 231, 1, 196, - 48, 230, 231, 1, 210, 195, 230, 231, 1, 213, 169, 230, 231, 1, 207, 155, - 230, 231, 1, 205, 112, 230, 231, 1, 199, 111, 230, 231, 1, 193, 59, 230, - 231, 1, 233, 89, 230, 231, 1, 223, 203, 230, 231, 1, 228, 123, 230, 231, - 1, 211, 29, 230, 231, 1, 213, 175, 228, 140, 39, 210, 2, 1, 251, 132, 39, - 210, 2, 1, 247, 230, 39, 210, 2, 1, 231, 224, 39, 210, 2, 1, 236, 160, - 39, 210, 2, 1, 71, 39, 210, 2, 1, 191, 53, 39, 210, 2, 1, 235, 27, 39, - 210, 2, 1, 191, 95, 39, 210, 2, 1, 235, 25, 39, 210, 2, 1, 68, 39, 210, - 2, 1, 221, 50, 39, 210, 2, 1, 219, 208, 39, 210, 2, 1, 216, 184, 39, 210, - 2, 1, 214, 100, 39, 210, 2, 1, 195, 7, 39, 210, 2, 1, 210, 48, 39, 210, - 2, 1, 207, 70, 39, 210, 2, 1, 202, 193, 39, 210, 2, 1, 199, 217, 39, 210, - 2, 1, 66, 39, 210, 2, 1, 243, 106, 39, 210, 2, 1, 203, 47, 39, 210, 2, 1, - 203, 115, 39, 210, 2, 1, 191, 227, 39, 210, 2, 1, 192, 58, 39, 210, 2, 1, - 74, 39, 210, 2, 1, 211, 87, 39, 210, 2, 1, 234, 181, 39, 210, 2, 1, 140, - 39, 210, 2, 1, 197, 145, 39, 210, 2, 1, 195, 140, 39, 210, 2, 1, 192, 62, - 39, 210, 2, 1, 192, 60, 39, 210, 2, 1, 192, 95, 39, 210, 2, 1, 223, 226, - 39, 210, 2, 1, 191, 225, 39, 210, 2, 1, 170, 39, 210, 2, 1, 228, 35, 33, - 39, 210, 2, 1, 251, 132, 33, 39, 210, 2, 1, 236, 160, 33, 39, 210, 2, 1, - 191, 95, 33, 39, 210, 2, 1, 214, 100, 33, 39, 210, 2, 1, 202, 193, 196, - 142, 1, 251, 164, 196, 142, 1, 248, 212, 196, 142, 1, 231, 212, 196, 142, - 1, 221, 215, 196, 142, 1, 237, 106, 196, 142, 1, 229, 23, 196, 142, 1, - 193, 48, 196, 142, 1, 191, 76, 196, 142, 1, 228, 179, 196, 142, 1, 199, - 73, 196, 142, 1, 191, 250, 196, 142, 1, 222, 106, 196, 142, 1, 203, 69, - 196, 142, 1, 220, 31, 196, 142, 1, 216, 193, 196, 142, 1, 237, 64, 196, - 142, 1, 212, 130, 196, 142, 1, 190, 251, 196, 142, 1, 205, 147, 196, 142, - 1, 251, 230, 196, 142, 1, 208, 165, 196, 142, 1, 205, 191, 196, 142, 1, - 208, 38, 196, 142, 1, 207, 133, 196, 142, 1, 199, 37, 196, 142, 1, 231, - 86, 196, 142, 1, 159, 196, 142, 1, 68, 196, 142, 1, 66, 196, 142, 1, 201, - 129, 196, 142, 193, 23, 236, 205, 39, 209, 252, 3, 65, 39, 209, 252, 3, - 68, 39, 209, 252, 3, 66, 39, 209, 252, 3, 155, 39, 209, 252, 3, 220, 232, - 39, 209, 252, 3, 231, 240, 39, 209, 252, 3, 230, 179, 39, 209, 252, 3, - 192, 220, 39, 209, 252, 3, 247, 160, 39, 209, 252, 3, 223, 32, 39, 209, - 252, 3, 222, 244, 39, 209, 252, 3, 190, 190, 39, 209, 252, 3, 197, 94, - 39, 209, 252, 3, 238, 32, 39, 209, 252, 3, 237, 44, 39, 209, 252, 3, 235, - 89, 39, 209, 252, 3, 199, 49, 39, 209, 252, 3, 168, 39, 209, 252, 3, 249, - 153, 39, 209, 252, 3, 233, 109, 39, 209, 252, 3, 180, 39, 209, 252, 3, - 212, 178, 39, 209, 252, 3, 174, 39, 209, 252, 3, 216, 100, 39, 209, 252, - 3, 215, 155, 39, 209, 252, 3, 170, 39, 209, 252, 3, 195, 188, 39, 209, - 252, 3, 195, 69, 39, 209, 252, 3, 165, 39, 209, 252, 3, 206, 68, 39, 209, - 252, 3, 173, 39, 209, 252, 3, 188, 39, 209, 252, 3, 191, 123, 39, 209, - 252, 3, 203, 165, 39, 209, 252, 3, 201, 175, 39, 209, 252, 3, 140, 39, - 209, 252, 3, 250, 157, 39, 209, 252, 3, 250, 156, 39, 209, 252, 3, 250, - 155, 39, 209, 252, 3, 192, 189, 39, 209, 252, 3, 238, 9, 39, 209, 252, 3, - 238, 8, 39, 209, 252, 3, 249, 128, 39, 209, 252, 3, 247, 212, 39, 209, - 252, 193, 23, 236, 205, 39, 209, 252, 31, 107, 39, 209, 252, 31, 109, 39, - 209, 252, 31, 199, 95, 39, 209, 252, 31, 197, 32, 39, 209, 252, 31, 228, - 140, 237, 84, 6, 1, 179, 68, 237, 84, 6, 1, 179, 71, 237, 84, 6, 1, 179, - 65, 237, 84, 6, 1, 179, 251, 245, 237, 84, 6, 1, 179, 74, 237, 84, 6, 1, - 179, 211, 87, 237, 84, 6, 1, 203, 40, 68, 237, 84, 6, 1, 203, 40, 71, - 237, 84, 6, 1, 203, 40, 65, 237, 84, 6, 1, 203, 40, 251, 245, 237, 84, 6, - 1, 203, 40, 74, 237, 84, 6, 1, 203, 40, 211, 87, 237, 84, 6, 1, 250, 131, - 237, 84, 6, 1, 210, 250, 237, 84, 6, 1, 193, 0, 237, 84, 6, 1, 192, 77, - 237, 84, 6, 1, 230, 116, 237, 84, 6, 1, 210, 49, 237, 84, 6, 1, 249, 1, - 237, 84, 6, 1, 199, 121, 237, 84, 6, 1, 237, 131, 237, 84, 6, 1, 243, - 123, 237, 84, 6, 1, 223, 8, 237, 84, 6, 1, 222, 29, 237, 84, 6, 1, 231, - 186, 237, 84, 6, 1, 234, 181, 237, 84, 6, 1, 195, 148, 237, 84, 6, 1, - 233, 248, 237, 84, 6, 1, 199, 31, 237, 84, 6, 1, 234, 22, 237, 84, 6, 1, - 191, 84, 237, 84, 6, 1, 234, 12, 237, 84, 6, 1, 191, 61, 237, 84, 6, 1, - 234, 34, 237, 84, 6, 1, 234, 140, 237, 84, 6, 1, 234, 114, 237, 84, 6, 1, - 234, 103, 237, 84, 6, 1, 234, 88, 237, 84, 6, 1, 211, 133, 237, 84, 6, 1, - 233, 224, 237, 84, 2, 1, 179, 68, 237, 84, 2, 1, 179, 71, 237, 84, 2, 1, - 179, 65, 237, 84, 2, 1, 179, 251, 245, 237, 84, 2, 1, 179, 74, 237, 84, - 2, 1, 179, 211, 87, 237, 84, 2, 1, 203, 40, 68, 237, 84, 2, 1, 203, 40, - 71, 237, 84, 2, 1, 203, 40, 65, 237, 84, 2, 1, 203, 40, 251, 245, 237, - 84, 2, 1, 203, 40, 74, 237, 84, 2, 1, 203, 40, 211, 87, 237, 84, 2, 1, - 250, 131, 237, 84, 2, 1, 210, 250, 237, 84, 2, 1, 193, 0, 237, 84, 2, 1, - 192, 77, 237, 84, 2, 1, 230, 116, 237, 84, 2, 1, 210, 49, 237, 84, 2, 1, - 249, 1, 237, 84, 2, 1, 199, 121, 237, 84, 2, 1, 237, 131, 237, 84, 2, 1, - 243, 123, 237, 84, 2, 1, 223, 8, 237, 84, 2, 1, 222, 29, 237, 84, 2, 1, - 231, 186, 237, 84, 2, 1, 234, 181, 237, 84, 2, 1, 195, 148, 237, 84, 2, - 1, 233, 248, 237, 84, 2, 1, 199, 31, 237, 84, 2, 1, 234, 22, 237, 84, 2, - 1, 191, 84, 237, 84, 2, 1, 234, 12, 237, 84, 2, 1, 191, 61, 237, 84, 2, - 1, 234, 34, 237, 84, 2, 1, 234, 140, 237, 84, 2, 1, 234, 114, 237, 84, 2, - 1, 234, 103, 237, 84, 2, 1, 234, 88, 237, 84, 2, 1, 211, 133, 237, 84, 2, - 1, 233, 224, 203, 120, 1, 210, 45, 203, 120, 1, 198, 40, 203, 120, 1, - 221, 154, 203, 120, 1, 233, 52, 203, 120, 1, 199, 6, 203, 120, 1, 202, - 46, 203, 120, 1, 200, 172, 203, 120, 1, 243, 40, 203, 120, 1, 192, 79, - 203, 120, 1, 228, 137, 203, 120, 1, 248, 187, 203, 120, 1, 237, 145, 203, - 120, 1, 231, 226, 203, 120, 1, 195, 2, 203, 120, 1, 199, 12, 203, 120, 1, - 191, 4, 203, 120, 1, 216, 227, 203, 120, 1, 222, 180, 203, 120, 1, 193, - 39, 203, 120, 1, 230, 93, 203, 120, 1, 219, 25, 203, 120, 1, 216, 45, - 203, 120, 1, 223, 206, 203, 120, 1, 234, 179, 203, 120, 1, 250, 209, 203, - 120, 1, 252, 30, 203, 120, 1, 211, 104, 203, 120, 1, 193, 26, 203, 120, - 1, 211, 14, 203, 120, 1, 251, 245, 203, 120, 1, 206, 153, 203, 120, 1, - 212, 130, 203, 120, 1, 234, 200, 203, 120, 1, 251, 250, 203, 120, 1, 228, - 26, 203, 120, 1, 196, 77, 203, 120, 1, 211, 180, 203, 120, 1, 211, 79, - 203, 120, 1, 211, 131, 203, 120, 1, 250, 137, 203, 120, 1, 251, 9, 203, - 120, 1, 211, 56, 203, 120, 1, 251, 225, 203, 120, 1, 234, 26, 203, 120, - 1, 250, 240, 203, 120, 1, 234, 211, 203, 120, 1, 228, 34, 203, 120, 1, - 192, 41, 211, 33, 1, 251, 192, 211, 33, 1, 249, 153, 211, 33, 1, 190, - 190, 211, 33, 1, 223, 32, 211, 33, 1, 192, 220, 211, 33, 1, 221, 215, - 211, 33, 1, 237, 130, 211, 33, 1, 165, 211, 33, 1, 188, 211, 33, 1, 203, - 75, 211, 33, 1, 237, 68, 211, 33, 1, 247, 67, 211, 33, 1, 231, 240, 211, - 33, 1, 233, 109, 211, 33, 1, 208, 94, 211, 33, 1, 222, 123, 211, 33, 1, - 220, 121, 211, 33, 1, 216, 59, 211, 33, 1, 212, 114, 211, 33, 1, 193, - 133, 211, 33, 1, 140, 211, 33, 1, 170, 211, 33, 1, 65, 211, 33, 1, 71, - 211, 33, 1, 68, 211, 33, 1, 74, 211, 33, 1, 66, 211, 33, 1, 252, 206, - 211, 33, 1, 234, 188, 211, 33, 1, 211, 87, 211, 33, 17, 191, 77, 211, 33, - 17, 107, 211, 33, 17, 109, 211, 33, 17, 138, 211, 33, 17, 134, 211, 33, - 17, 149, 211, 33, 17, 169, 211, 33, 17, 175, 211, 33, 17, 171, 211, 33, - 17, 178, 211, 35, 6, 1, 65, 211, 35, 6, 1, 251, 236, 211, 35, 6, 1, 251, - 230, 211, 35, 6, 1, 251, 245, 211, 35, 6, 1, 248, 56, 211, 35, 6, 1, 247, - 1, 211, 35, 6, 1, 234, 172, 211, 35, 6, 1, 71, 211, 35, 6, 1, 234, 152, - 211, 35, 6, 1, 140, 211, 35, 6, 1, 228, 93, 211, 35, 6, 1, 68, 211, 35, - 6, 1, 155, 211, 35, 6, 1, 234, 171, 211, 35, 6, 1, 220, 153, 211, 35, 6, - 1, 173, 211, 35, 6, 1, 174, 211, 35, 6, 1, 180, 211, 35, 6, 1, 74, 211, - 35, 6, 1, 211, 130, 211, 35, 6, 1, 168, 211, 35, 6, 1, 234, 170, 211, 35, - 6, 1, 188, 211, 35, 6, 1, 203, 165, 211, 35, 6, 1, 190, 190, 211, 35, 6, - 1, 234, 169, 211, 35, 6, 1, 197, 168, 211, 35, 6, 1, 234, 168, 211, 35, - 6, 1, 197, 157, 211, 35, 6, 1, 237, 68, 211, 35, 6, 1, 66, 211, 35, 6, 1, - 193, 190, 211, 35, 6, 1, 221, 215, 211, 35, 6, 1, 231, 91, 211, 35, 6, 1, - 191, 123, 211, 35, 6, 1, 191, 71, 211, 35, 2, 1, 65, 211, 35, 2, 1, 251, - 236, 211, 35, 2, 1, 251, 230, 211, 35, 2, 1, 251, 245, 211, 35, 2, 1, - 248, 56, 211, 35, 2, 1, 247, 1, 211, 35, 2, 1, 234, 172, 211, 35, 2, 1, - 71, 211, 35, 2, 1, 234, 152, 211, 35, 2, 1, 140, 211, 35, 2, 1, 228, 93, - 211, 35, 2, 1, 68, 211, 35, 2, 1, 155, 211, 35, 2, 1, 234, 171, 211, 35, - 2, 1, 220, 153, 211, 35, 2, 1, 173, 211, 35, 2, 1, 174, 211, 35, 2, 1, - 180, 211, 35, 2, 1, 74, 211, 35, 2, 1, 211, 130, 211, 35, 2, 1, 168, 211, - 35, 2, 1, 234, 170, 211, 35, 2, 1, 188, 211, 35, 2, 1, 203, 165, 211, 35, - 2, 1, 190, 190, 211, 35, 2, 1, 234, 169, 211, 35, 2, 1, 197, 168, 211, - 35, 2, 1, 234, 168, 211, 35, 2, 1, 197, 157, 211, 35, 2, 1, 237, 68, 211, - 35, 2, 1, 66, 211, 35, 2, 1, 193, 190, 211, 35, 2, 1, 221, 215, 211, 35, - 2, 1, 231, 91, 211, 35, 2, 1, 191, 123, 211, 35, 2, 1, 191, 71, 234, 136, - 1, 65, 234, 136, 1, 249, 17, 234, 136, 1, 247, 42, 234, 136, 1, 243, 127, - 234, 136, 1, 237, 146, 234, 136, 1, 214, 154, 234, 136, 1, 237, 59, 234, - 136, 1, 234, 166, 234, 136, 1, 71, 234, 136, 1, 233, 59, 234, 136, 1, - 231, 165, 234, 136, 1, 231, 20, 234, 136, 1, 229, 245, 234, 136, 1, 68, - 234, 136, 1, 223, 10, 234, 136, 1, 222, 22, 234, 136, 1, 219, 238, 234, - 136, 1, 219, 68, 234, 136, 1, 216, 232, 234, 136, 1, 214, 121, 234, 136, - 1, 180, 234, 136, 1, 213, 150, 234, 136, 1, 74, 234, 136, 1, 210, 63, - 234, 136, 1, 208, 75, 234, 136, 1, 207, 113, 234, 136, 1, 206, 104, 234, - 136, 1, 205, 68, 234, 136, 1, 203, 113, 234, 136, 1, 199, 145, 234, 136, - 1, 199, 33, 234, 136, 1, 66, 234, 136, 1, 195, 153, 234, 136, 1, 192, - 214, 234, 136, 1, 192, 159, 234, 136, 1, 191, 87, 234, 136, 1, 191, 62, - 234, 136, 1, 231, 77, 234, 136, 1, 231, 83, 234, 136, 1, 221, 197, 247, - 75, 251, 193, 1, 251, 159, 247, 75, 251, 193, 1, 248, 214, 247, 75, 251, - 193, 1, 231, 40, 247, 75, 251, 193, 1, 237, 211, 247, 75, 251, 193, 1, - 234, 199, 247, 75, 251, 193, 1, 191, 98, 247, 75, 251, 193, 1, 233, 184, - 247, 75, 251, 193, 1, 191, 56, 247, 75, 251, 193, 1, 199, 174, 247, 75, - 251, 193, 1, 247, 1, 247, 75, 251, 193, 1, 191, 236, 247, 75, 251, 193, - 1, 191, 71, 247, 75, 251, 193, 1, 223, 76, 247, 75, 251, 193, 1, 203, - 165, 247, 75, 251, 193, 1, 220, 24, 247, 75, 251, 193, 1, 223, 89, 247, - 75, 251, 193, 1, 192, 210, 247, 75, 251, 193, 1, 235, 43, 247, 75, 251, - 193, 1, 247, 102, 247, 75, 251, 193, 1, 222, 245, 247, 75, 251, 193, 1, - 222, 65, 247, 75, 251, 193, 1, 218, 177, 247, 75, 251, 193, 1, 229, 179, - 247, 75, 251, 193, 1, 208, 76, 247, 75, 251, 193, 1, 251, 67, 247, 75, - 251, 193, 1, 243, 57, 247, 75, 251, 193, 1, 243, 95, 247, 75, 251, 193, - 1, 238, 140, 247, 75, 251, 193, 1, 217, 68, 247, 75, 251, 193, 1, 208, - 81, 247, 75, 251, 193, 1, 212, 252, 247, 75, 251, 193, 1, 235, 20, 247, - 75, 251, 193, 1, 203, 147, 247, 75, 251, 193, 1, 223, 11, 247, 75, 251, - 193, 1, 211, 104, 247, 75, 251, 193, 1, 197, 3, 247, 75, 251, 193, 1, - 233, 82, 247, 75, 251, 193, 1, 235, 33, 247, 75, 251, 193, 1, 243, 133, - 247, 75, 251, 193, 1, 210, 34, 247, 75, 251, 193, 1, 231, 67, 247, 75, - 251, 193, 1, 207, 130, 247, 75, 251, 193, 1, 203, 174, 247, 75, 251, 193, - 1, 195, 72, 247, 75, 251, 193, 1, 198, 118, 247, 75, 251, 193, 1, 203, - 18, 247, 75, 251, 193, 1, 223, 46, 247, 75, 251, 193, 1, 238, 141, 247, - 75, 251, 193, 1, 247, 67, 247, 75, 251, 193, 1, 192, 84, 247, 75, 251, - 193, 1, 209, 114, 247, 75, 251, 193, 1, 221, 117, 247, 75, 251, 193, 242, - 254, 77, 195, 29, 6, 1, 65, 195, 29, 6, 1, 249, 48, 195, 29, 6, 1, 249, - 17, 195, 29, 6, 1, 247, 42, 195, 29, 6, 1, 243, 127, 195, 29, 6, 1, 237, - 146, 195, 29, 6, 1, 237, 59, 195, 29, 6, 1, 234, 166, 195, 29, 6, 1, 71, - 195, 29, 6, 1, 233, 59, 195, 29, 6, 1, 231, 240, 195, 29, 6, 1, 140, 195, - 29, 6, 1, 229, 177, 195, 29, 6, 1, 68, 195, 29, 6, 1, 223, 196, 195, 29, - 6, 1, 223, 10, 195, 29, 6, 1, 155, 195, 29, 6, 1, 173, 195, 29, 6, 1, - 219, 73, 195, 29, 6, 1, 216, 232, 195, 29, 6, 1, 214, 121, 195, 29, 6, 1, - 213, 150, 195, 29, 6, 1, 74, 195, 29, 6, 1, 210, 63, 195, 29, 6, 1, 208, - 96, 195, 29, 6, 1, 207, 113, 195, 29, 6, 1, 205, 68, 195, 29, 6, 1, 203, - 113, 195, 29, 6, 1, 199, 145, 195, 29, 6, 1, 199, 33, 195, 29, 6, 1, 66, - 195, 29, 6, 1, 195, 153, 195, 29, 6, 1, 192, 214, 195, 29, 6, 1, 192, - 159, 195, 29, 6, 1, 191, 87, 195, 29, 2, 1, 65, 195, 29, 2, 1, 249, 48, - 195, 29, 2, 1, 249, 17, 195, 29, 2, 1, 247, 42, 195, 29, 2, 1, 243, 127, - 195, 29, 2, 1, 237, 146, 195, 29, 2, 1, 237, 59, 195, 29, 2, 1, 234, 166, - 195, 29, 2, 1, 71, 195, 29, 2, 1, 233, 59, 195, 29, 2, 1, 231, 240, 195, - 29, 2, 1, 140, 195, 29, 2, 1, 229, 177, 195, 29, 2, 1, 68, 195, 29, 2, 1, - 223, 196, 195, 29, 2, 1, 223, 10, 195, 29, 2, 1, 155, 195, 29, 2, 1, 173, - 195, 29, 2, 1, 219, 73, 195, 29, 2, 1, 216, 232, 195, 29, 2, 1, 214, 121, - 195, 29, 2, 1, 213, 150, 195, 29, 2, 1, 74, 195, 29, 2, 1, 210, 63, 195, - 29, 2, 1, 208, 96, 195, 29, 2, 1, 207, 113, 195, 29, 2, 1, 205, 68, 195, - 29, 2, 1, 203, 113, 195, 29, 2, 1, 199, 145, 195, 29, 2, 1, 199, 33, 195, - 29, 2, 1, 66, 195, 29, 2, 1, 195, 153, 195, 29, 2, 1, 192, 214, 195, 29, - 2, 1, 192, 159, 195, 29, 2, 1, 191, 87, 32, 42, 3, 252, 154, 32, 42, 3, - 252, 153, 32, 42, 3, 252, 152, 32, 42, 3, 252, 151, 32, 42, 3, 252, 150, - 32, 42, 3, 252, 149, 32, 42, 3, 252, 148, 32, 42, 3, 252, 147, 32, 42, 3, - 252, 146, 32, 42, 3, 252, 145, 32, 42, 3, 252, 144, 32, 42, 3, 252, 143, - 32, 42, 3, 252, 142, 32, 42, 3, 252, 141, 32, 42, 3, 252, 140, 32, 42, 3, - 252, 139, 32, 42, 3, 252, 138, 32, 42, 3, 252, 137, 32, 42, 3, 252, 136, - 32, 42, 3, 252, 135, 32, 42, 3, 252, 134, 32, 42, 3, 252, 133, 32, 42, 3, - 252, 132, 32, 42, 3, 252, 131, 32, 42, 3, 252, 130, 32, 42, 3, 252, 129, - 32, 42, 3, 252, 128, 32, 42, 3, 255, 164, 32, 42, 3, 252, 127, 32, 42, 3, - 252, 126, 32, 42, 3, 252, 125, 32, 42, 3, 252, 124, 32, 42, 3, 252, 123, - 32, 42, 3, 252, 122, 32, 42, 3, 252, 121, 32, 42, 3, 252, 120, 32, 42, 3, - 252, 119, 32, 42, 3, 252, 118, 32, 42, 3, 252, 117, 32, 42, 3, 252, 116, - 32, 42, 3, 252, 115, 32, 42, 3, 252, 114, 32, 42, 3, 252, 113, 32, 42, 3, - 252, 112, 32, 42, 3, 252, 111, 32, 42, 3, 252, 110, 32, 42, 3, 252, 109, - 32, 42, 3, 252, 108, 32, 42, 3, 252, 107, 32, 42, 3, 252, 106, 32, 42, 3, - 252, 105, 32, 42, 3, 252, 104, 32, 42, 3, 252, 103, 32, 42, 3, 252, 102, - 32, 42, 3, 252, 101, 32, 42, 3, 252, 100, 32, 42, 3, 252, 99, 32, 42, 3, - 252, 98, 32, 42, 3, 252, 97, 32, 42, 3, 252, 96, 32, 42, 3, 252, 95, 32, - 42, 3, 252, 94, 32, 42, 3, 252, 93, 32, 42, 3, 252, 92, 32, 42, 3, 252, - 91, 32, 42, 3, 252, 90, 32, 42, 3, 252, 89, 32, 42, 3, 252, 88, 32, 42, - 3, 252, 87, 32, 42, 3, 252, 86, 32, 42, 3, 252, 85, 32, 42, 3, 255, 77, - 32, 42, 3, 252, 84, 32, 42, 3, 252, 83, 32, 42, 3, 255, 42, 32, 42, 3, - 252, 82, 32, 42, 3, 252, 81, 32, 42, 3, 252, 80, 32, 42, 3, 252, 79, 32, - 42, 3, 255, 29, 32, 42, 3, 252, 78, 32, 42, 3, 252, 77, 32, 42, 3, 252, - 76, 32, 42, 3, 252, 75, 32, 42, 3, 252, 74, 32, 42, 3, 254, 101, 32, 42, - 3, 254, 100, 32, 42, 3, 254, 99, 32, 42, 3, 254, 98, 32, 42, 3, 254, 97, - 32, 42, 3, 254, 96, 32, 42, 3, 254, 95, 32, 42, 3, 254, 94, 32, 42, 3, - 254, 92, 32, 42, 3, 254, 91, 32, 42, 3, 254, 90, 32, 42, 3, 254, 89, 32, - 42, 3, 254, 88, 32, 42, 3, 254, 87, 32, 42, 3, 254, 85, 32, 42, 3, 254, - 84, 32, 42, 3, 254, 83, 32, 42, 3, 254, 82, 32, 42, 3, 254, 81, 32, 42, - 3, 254, 80, 32, 42, 3, 254, 79, 32, 42, 3, 254, 78, 32, 42, 3, 254, 77, - 32, 42, 3, 254, 76, 32, 42, 3, 254, 75, 32, 42, 3, 254, 74, 32, 42, 3, - 254, 73, 32, 42, 3, 254, 72, 32, 42, 3, 254, 71, 32, 42, 3, 254, 70, 32, - 42, 3, 254, 69, 32, 42, 3, 254, 68, 32, 42, 3, 254, 67, 32, 42, 3, 254, - 65, 32, 42, 3, 254, 64, 32, 42, 3, 254, 63, 32, 42, 3, 254, 59, 32, 42, - 3, 254, 58, 32, 42, 3, 254, 57, 32, 42, 3, 254, 56, 32, 42, 3, 254, 52, - 32, 42, 3, 254, 51, 32, 42, 3, 254, 50, 32, 42, 3, 254, 49, 32, 42, 3, - 254, 48, 32, 42, 3, 254, 47, 32, 42, 3, 254, 46, 32, 42, 3, 254, 45, 32, - 42, 3, 254, 44, 32, 42, 3, 254, 43, 32, 42, 3, 254, 42, 32, 42, 3, 254, - 41, 32, 42, 3, 254, 40, 32, 42, 3, 254, 39, 32, 42, 3, 254, 38, 32, 42, - 3, 254, 37, 32, 42, 3, 254, 36, 32, 42, 3, 254, 35, 32, 42, 3, 254, 34, - 32, 42, 3, 254, 33, 32, 42, 3, 254, 32, 32, 42, 3, 254, 31, 32, 42, 3, - 254, 30, 32, 42, 3, 254, 28, 32, 42, 3, 254, 27, 32, 42, 3, 254, 26, 32, - 42, 3, 254, 25, 32, 42, 3, 254, 24, 32, 42, 3, 254, 22, 32, 42, 3, 254, - 21, 32, 42, 3, 254, 20, 32, 42, 3, 254, 19, 32, 42, 3, 254, 17, 32, 42, - 3, 254, 16, 32, 42, 3, 254, 15, 32, 42, 3, 253, 237, 32, 42, 3, 253, 235, - 32, 42, 3, 253, 233, 32, 42, 3, 253, 231, 32, 42, 3, 253, 229, 32, 42, 3, - 253, 227, 32, 42, 3, 253, 225, 32, 42, 3, 253, 223, 32, 42, 3, 253, 221, - 32, 42, 3, 253, 219, 32, 42, 3, 253, 217, 32, 42, 3, 253, 214, 32, 42, 3, - 253, 212, 32, 42, 3, 253, 210, 32, 42, 3, 253, 208, 32, 42, 3, 253, 206, - 32, 42, 3, 253, 204, 32, 42, 3, 253, 202, 32, 42, 3, 253, 200, 32, 42, 3, - 253, 118, 32, 42, 3, 253, 117, 32, 42, 3, 253, 116, 32, 42, 3, 253, 115, - 32, 42, 3, 253, 114, 32, 42, 3, 253, 113, 32, 42, 3, 253, 111, 32, 42, 3, - 253, 110, 32, 42, 3, 253, 109, 32, 42, 3, 253, 108, 32, 42, 3, 253, 107, - 32, 42, 3, 253, 106, 32, 42, 3, 253, 104, 32, 42, 3, 253, 103, 32, 42, 3, - 253, 99, 32, 42, 3, 253, 98, 32, 42, 3, 253, 96, 32, 42, 3, 253, 95, 32, - 42, 3, 253, 94, 32, 42, 3, 253, 93, 32, 42, 3, 253, 92, 32, 42, 3, 253, - 91, 32, 42, 3, 253, 90, 32, 42, 3, 253, 89, 32, 42, 3, 253, 88, 32, 42, - 3, 253, 87, 32, 42, 3, 253, 86, 32, 42, 3, 253, 85, 32, 42, 3, 253, 84, - 32, 42, 3, 253, 83, 32, 42, 3, 253, 82, 32, 42, 3, 253, 81, 32, 42, 3, - 253, 80, 32, 42, 3, 253, 79, 32, 42, 3, 253, 78, 32, 42, 3, 253, 77, 32, - 42, 3, 253, 76, 32, 42, 3, 253, 75, 32, 42, 3, 253, 74, 32, 42, 3, 253, - 73, 32, 42, 3, 253, 72, 32, 42, 3, 253, 71, 32, 42, 3, 253, 70, 32, 42, - 3, 253, 69, 32, 42, 3, 253, 68, 32, 42, 3, 253, 67, 32, 42, 3, 253, 66, - 32, 42, 3, 253, 65, 32, 42, 3, 253, 64, 32, 42, 3, 253, 63, 32, 42, 3, - 253, 62, 32, 42, 3, 253, 61, 32, 42, 3, 253, 60, 32, 42, 3, 253, 59, 32, - 42, 3, 253, 58, 32, 42, 3, 253, 57, 32, 42, 3, 253, 56, 32, 42, 3, 253, - 55, 32, 42, 3, 253, 54, 32, 42, 3, 253, 53, 32, 42, 3, 253, 52, 32, 42, - 3, 253, 51, 32, 42, 3, 253, 50, 32, 42, 3, 253, 49, 32, 42, 3, 253, 48, - 32, 42, 3, 253, 47, 32, 42, 3, 253, 46, 32, 42, 3, 253, 45, 32, 42, 3, - 253, 44, 32, 42, 3, 253, 43, 32, 42, 3, 253, 42, 32, 42, 3, 253, 41, 32, - 42, 3, 253, 40, 32, 42, 3, 253, 39, 32, 42, 3, 253, 38, 32, 42, 3, 253, - 37, 32, 42, 3, 253, 36, 32, 42, 3, 253, 35, 32, 42, 3, 253, 34, 32, 42, - 3, 253, 33, 32, 42, 3, 253, 32, 32, 42, 3, 253, 31, 32, 42, 3, 253, 30, - 32, 42, 3, 253, 29, 32, 42, 3, 253, 28, 32, 42, 3, 253, 27, 32, 42, 3, - 253, 26, 32, 42, 3, 253, 25, 32, 42, 3, 253, 24, 32, 42, 3, 253, 23, 32, - 42, 3, 253, 22, 32, 42, 3, 253, 21, 32, 42, 3, 253, 20, 32, 42, 3, 253, - 19, 32, 42, 3, 253, 18, 32, 42, 3, 253, 17, 32, 42, 3, 253, 16, 32, 42, - 3, 253, 15, 32, 42, 3, 253, 14, 32, 42, 3, 253, 13, 32, 42, 3, 253, 12, - 32, 42, 3, 253, 11, 32, 42, 3, 253, 10, 32, 42, 3, 253, 9, 32, 42, 3, - 253, 8, 32, 42, 3, 253, 7, 32, 42, 3, 253, 6, 32, 42, 3, 253, 5, 32, 42, - 3, 253, 4, 32, 42, 3, 253, 3, 32, 42, 3, 253, 2, 32, 42, 3, 253, 1, 32, - 42, 3, 253, 0, 32, 42, 3, 252, 255, 32, 42, 3, 252, 254, 32, 42, 3, 252, - 253, 32, 42, 3, 252, 252, 32, 42, 3, 252, 251, 32, 42, 3, 252, 250, 32, - 42, 3, 252, 249, 32, 42, 3, 252, 248, 32, 42, 3, 252, 247, 32, 42, 3, - 252, 246, 32, 42, 3, 252, 245, 32, 42, 3, 252, 244, 32, 42, 3, 252, 243, - 32, 42, 3, 252, 242, 32, 42, 3, 252, 241, 32, 42, 3, 252, 240, 32, 42, 3, - 252, 239, 32, 42, 3, 252, 238, 32, 42, 3, 252, 237, 32, 42, 3, 252, 236, - 65, 32, 42, 3, 252, 235, 250, 120, 32, 42, 3, 252, 234, 238, 127, 32, 42, - 3, 252, 233, 71, 32, 42, 3, 252, 232, 233, 175, 32, 42, 3, 252, 231, 230, - 116, 32, 42, 3, 252, 230, 223, 35, 32, 42, 3, 252, 229, 222, 152, 32, 42, - 3, 252, 228, 172, 32, 42, 3, 252, 227, 220, 130, 32, 42, 3, 252, 226, - 220, 129, 32, 42, 3, 252, 225, 220, 128, 32, 42, 3, 252, 224, 220, 127, - 32, 42, 3, 252, 223, 193, 224, 32, 42, 3, 252, 222, 192, 235, 32, 42, 3, - 252, 221, 192, 159, 32, 42, 3, 252, 220, 211, 110, 32, 42, 3, 252, 219, - 252, 69, 32, 42, 3, 252, 218, 249, 54, 32, 42, 3, 252, 217, 237, 193, 32, - 42, 3, 252, 216, 233, 183, 32, 42, 3, 252, 215, 223, 10, 32, 42, 3, 252, - 214, 32, 42, 3, 252, 213, 32, 42, 3, 252, 212, 32, 42, 3, 252, 211, 32, - 42, 3, 252, 210, 32, 42, 3, 252, 209, 32, 42, 3, 252, 208, 32, 42, 3, - 252, 207, 52, 1, 2, 6, 252, 206, 52, 1, 200, 182, 197, 238, 242, 83, 52, - 1, 200, 182, 132, 197, 238, 242, 83, 52, 1, 2, 252, 25, 52, 1, 2, 6, 250, - 120, 52, 1, 2, 78, 4, 102, 52, 1, 2, 235, 37, 237, 2, 52, 1, 2, 235, 37, - 237, 3, 4, 207, 24, 102, 52, 1, 2, 235, 37, 237, 3, 4, 238, 175, 52, 1, - 2, 237, 70, 237, 2, 52, 1, 2, 238, 128, 4, 199, 215, 52, 1, 2, 238, 128, - 4, 102, 52, 1, 2, 238, 128, 4, 228, 251, 23, 199, 215, 52, 1, 2, 207, 18, - 71, 52, 1, 2, 242, 219, 207, 18, 211, 77, 71, 52, 1, 2, 233, 37, 237, 2, - 52, 1, 2, 207, 140, 228, 187, 52, 1, 2, 6, 232, 51, 52, 1, 2, 232, 52, 4, - 102, 52, 1, 2, 6, 232, 52, 4, 102, 52, 1, 2, 230, 117, 4, 106, 52, 1, 2, - 6, 230, 116, 52, 1, 2, 229, 197, 4, 102, 52, 1, 2, 236, 139, 223, 36, 4, - 201, 28, 23, 102, 52, 1, 2, 218, 227, 237, 2, 52, 1, 2, 218, 170, 237, 2, - 52, 1, 2, 220, 143, 4, 248, 231, 52, 1, 2, 6, 220, 143, 4, 248, 231, 52, - 1, 2, 220, 143, 4, 207, 24, 228, 251, 23, 248, 231, 52, 1, 2, 219, 162, - 52, 1, 2, 219, 163, 4, 207, 24, 102, 52, 1, 2, 153, 192, 159, 52, 1, 2, - 153, 192, 160, 4, 248, 231, 52, 1, 2, 187, 4, 106, 52, 1, 2, 6, 211, 151, - 52, 1, 2, 242, 219, 211, 110, 52, 1, 2, 208, 104, 52, 1, 2, 153, 207, - 222, 4, 179, 219, 212, 52, 1, 2, 153, 207, 222, 4, 179, 219, 213, 23, - 207, 24, 102, 52, 1, 2, 207, 222, 4, 199, 215, 52, 1, 2, 207, 222, 4, - 232, 233, 52, 1, 2, 6, 146, 52, 1, 2, 199, 152, 237, 3, 4, 238, 175, 52, - 1, 2, 197, 170, 237, 2, 52, 1, 2, 197, 170, 237, 3, 4, 207, 24, 102, 52, - 1, 2, 199, 79, 237, 2, 52, 1, 2, 200, 44, 4, 207, 24, 102, 52, 1, 2, 196, - 13, 4, 50, 102, 52, 1, 2, 6, 192, 159, 52, 1, 231, 11, 201, 64, 4, 106, - 52, 1, 207, 18, 231, 11, 201, 64, 4, 106, 52, 1, 248, 172, 242, 231, 52, - 1, 237, 98, 242, 231, 52, 1, 220, 3, 242, 231, 52, 1, 251, 150, 242, 231, - 52, 1, 207, 24, 242, 232, 4, 207, 24, 102, 52, 1, 2, 206, 9, 4, 238, 175, - 238, 135, 5, 65, 238, 135, 5, 71, 238, 135, 5, 68, 238, 135, 5, 74, 238, - 135, 5, 66, 238, 135, 5, 223, 32, 238, 135, 5, 222, 201, 238, 135, 5, - 155, 238, 135, 5, 222, 22, 238, 135, 5, 221, 166, 238, 135, 5, 221, 67, - 238, 135, 5, 220, 232, 238, 135, 5, 173, 238, 135, 5, 219, 238, 238, 135, - 5, 219, 146, 238, 135, 5, 219, 43, 238, 135, 5, 218, 225, 238, 135, 5, - 174, 238, 135, 5, 216, 232, 238, 135, 5, 216, 100, 238, 135, 5, 216, 12, - 238, 135, 5, 215, 155, 238, 135, 5, 180, 238, 135, 5, 214, 121, 238, 135, - 5, 213, 219, 238, 135, 5, 213, 43, 238, 135, 5, 212, 178, 238, 135, 5, - 168, 238, 135, 5, 210, 63, 238, 135, 5, 209, 185, 238, 135, 5, 209, 73, - 238, 135, 5, 208, 165, 238, 135, 5, 165, 238, 135, 5, 207, 113, 238, 135, - 5, 207, 1, 238, 135, 5, 206, 162, 238, 135, 5, 206, 68, 238, 135, 5, 188, - 238, 135, 5, 205, 68, 238, 135, 5, 202, 222, 238, 135, 5, 202, 46, 238, - 135, 5, 201, 4, 238, 135, 5, 190, 190, 238, 135, 5, 199, 145, 238, 135, - 5, 198, 193, 238, 135, 5, 159, 238, 135, 5, 197, 94, 238, 135, 5, 193, - 190, 238, 135, 5, 193, 125, 238, 135, 5, 193, 86, 238, 135, 5, 193, 48, - 238, 135, 5, 192, 220, 238, 135, 5, 192, 214, 238, 135, 5, 191, 123, 238, - 135, 5, 191, 7, 223, 164, 251, 18, 1, 251, 190, 223, 164, 251, 18, 1, - 248, 211, 223, 164, 251, 18, 1, 231, 38, 223, 164, 251, 18, 1, 237, 252, - 223, 164, 251, 18, 1, 229, 245, 223, 164, 251, 18, 1, 193, 133, 223, 164, - 251, 18, 1, 191, 91, 223, 164, 251, 18, 1, 229, 184, 223, 164, 251, 18, - 1, 199, 69, 223, 164, 251, 18, 1, 191, 249, 223, 164, 251, 18, 1, 222, - 75, 223, 164, 251, 18, 1, 220, 26, 223, 164, 251, 18, 1, 216, 193, 223, - 164, 251, 18, 1, 212, 130, 223, 164, 251, 18, 1, 205, 148, 223, 164, 251, - 18, 1, 250, 126, 223, 164, 251, 18, 1, 210, 63, 223, 164, 251, 18, 1, - 205, 189, 223, 164, 251, 18, 1, 208, 37, 223, 164, 251, 18, 1, 207, 38, - 223, 164, 251, 18, 1, 203, 69, 223, 164, 251, 18, 1, 199, 159, 223, 164, - 251, 18, 205, 54, 56, 223, 164, 251, 18, 31, 107, 223, 164, 251, 18, 31, - 109, 223, 164, 251, 18, 31, 138, 223, 164, 251, 18, 31, 199, 95, 223, - 164, 251, 18, 31, 197, 32, 223, 164, 251, 18, 31, 91, 228, 140, 223, 164, - 251, 18, 31, 91, 189, 223, 164, 251, 18, 31, 199, 96, 189, 210, 180, 1, - 251, 190, 210, 180, 1, 248, 211, 210, 180, 1, 231, 38, 210, 180, 1, 237, - 252, 210, 180, 1, 229, 245, 210, 180, 1, 193, 133, 210, 180, 1, 191, 91, - 210, 180, 1, 229, 184, 210, 180, 1, 199, 69, 210, 180, 1, 191, 249, 210, - 180, 1, 222, 75, 210, 180, 1, 220, 26, 210, 180, 1, 216, 193, 210, 180, - 1, 53, 212, 130, 210, 180, 1, 212, 130, 210, 180, 1, 205, 148, 210, 180, - 1, 250, 126, 210, 180, 1, 210, 63, 210, 180, 1, 205, 189, 210, 180, 1, - 208, 37, 210, 180, 1, 207, 38, 210, 180, 1, 203, 69, 210, 180, 1, 199, - 159, 210, 180, 219, 219, 232, 201, 210, 180, 206, 203, 232, 201, 210, - 180, 31, 107, 210, 180, 31, 109, 210, 180, 31, 138, 210, 180, 31, 134, - 210, 180, 31, 149, 210, 180, 31, 199, 95, 210, 180, 31, 197, 32, 214, - 246, 1, 53, 251, 190, 214, 246, 1, 251, 190, 214, 246, 1, 53, 248, 211, - 214, 246, 1, 248, 211, 214, 246, 1, 231, 38, 214, 246, 1, 237, 252, 214, - 246, 1, 53, 229, 245, 214, 246, 1, 229, 245, 214, 246, 1, 193, 133, 214, - 246, 1, 191, 91, 214, 246, 1, 229, 184, 214, 246, 1, 199, 69, 214, 246, - 1, 53, 191, 249, 214, 246, 1, 191, 249, 214, 246, 1, 53, 222, 75, 214, - 246, 1, 222, 75, 214, 246, 1, 53, 220, 26, 214, 246, 1, 220, 26, 214, - 246, 1, 53, 216, 193, 214, 246, 1, 216, 193, 214, 246, 1, 53, 212, 130, - 214, 246, 1, 212, 130, 214, 246, 1, 205, 148, 214, 246, 1, 250, 126, 214, - 246, 1, 210, 63, 214, 246, 1, 205, 189, 214, 246, 1, 208, 37, 214, 246, - 1, 207, 38, 214, 246, 1, 53, 203, 69, 214, 246, 1, 203, 69, 214, 246, 1, - 199, 159, 214, 246, 31, 107, 214, 246, 31, 109, 214, 246, 31, 138, 214, - 246, 31, 134, 214, 246, 238, 202, 31, 134, 214, 246, 31, 149, 214, 246, - 31, 199, 95, 214, 246, 31, 197, 32, 214, 246, 31, 91, 228, 140, 230, 4, - 1, 251, 190, 230, 4, 1, 248, 211, 230, 4, 1, 231, 38, 230, 4, 1, 237, - 251, 230, 4, 1, 229, 245, 230, 4, 1, 193, 133, 230, 4, 1, 191, 89, 230, - 4, 1, 229, 184, 230, 4, 1, 199, 69, 230, 4, 1, 191, 249, 230, 4, 1, 222, - 75, 230, 4, 1, 220, 26, 230, 4, 1, 216, 193, 230, 4, 1, 212, 130, 230, 4, - 1, 205, 148, 230, 4, 1, 250, 124, 230, 4, 1, 210, 63, 230, 4, 1, 205, - 189, 230, 4, 1, 208, 37, 230, 4, 1, 203, 69, 230, 4, 1, 199, 159, 230, 4, - 31, 107, 230, 4, 31, 149, 230, 4, 31, 199, 95, 230, 4, 31, 197, 32, 230, - 4, 31, 91, 228, 140, 209, 197, 1, 251, 187, 209, 197, 1, 248, 214, 209, - 197, 1, 231, 213, 209, 197, 1, 237, 108, 209, 197, 1, 229, 245, 209, 197, - 1, 193, 140, 209, 197, 1, 191, 115, 209, 197, 1, 229, 186, 209, 197, 1, - 199, 73, 209, 197, 1, 191, 250, 209, 197, 1, 222, 106, 209, 197, 1, 220, - 32, 209, 197, 1, 216, 193, 209, 197, 1, 212, 130, 209, 197, 1, 204, 19, - 209, 197, 1, 251, 230, 209, 197, 1, 210, 63, 209, 197, 1, 205, 191, 209, - 197, 1, 208, 42, 209, 197, 1, 206, 124, 209, 197, 1, 203, 69, 209, 197, - 1, 199, 166, 209, 197, 31, 107, 209, 197, 31, 199, 95, 209, 197, 31, 197, - 32, 209, 197, 31, 91, 228, 140, 209, 197, 31, 109, 209, 197, 31, 138, - 209, 197, 193, 23, 204, 10, 218, 180, 1, 65, 218, 180, 1, 250, 120, 218, - 180, 1, 232, 51, 218, 180, 1, 238, 127, 218, 180, 1, 71, 218, 180, 1, - 196, 12, 218, 180, 1, 68, 218, 180, 1, 192, 159, 218, 180, 1, 222, 152, - 218, 180, 1, 172, 218, 180, 1, 218, 168, 218, 180, 1, 215, 61, 218, 180, - 1, 74, 218, 180, 1, 146, 218, 180, 1, 201, 178, 218, 180, 1, 200, 43, - 218, 180, 1, 66, 218, 180, 1, 233, 175, 218, 180, 1, 208, 104, 218, 180, - 1, 206, 8, 218, 180, 1, 197, 135, 218, 180, 1, 251, 132, 218, 180, 1, - 234, 103, 218, 180, 1, 218, 183, 218, 180, 1, 213, 80, 218, 180, 1, 247, - 193, 218, 180, 197, 238, 77, 152, 229, 144, 1, 65, 152, 229, 144, 1, 71, - 152, 229, 144, 1, 68, 152, 229, 144, 1, 74, 152, 229, 144, 1, 170, 152, - 229, 144, 1, 193, 190, 152, 229, 144, 1, 249, 153, 152, 229, 144, 1, 249, - 152, 152, 229, 144, 1, 168, 152, 229, 144, 1, 174, 152, 229, 144, 1, 180, - 152, 229, 144, 1, 215, 5, 152, 229, 144, 1, 214, 121, 152, 229, 144, 1, - 214, 119, 152, 229, 144, 1, 165, 152, 229, 144, 1, 207, 184, 152, 229, - 144, 1, 173, 152, 229, 144, 1, 221, 215, 152, 229, 144, 1, 229, 177, 152, - 229, 144, 1, 188, 152, 229, 144, 1, 205, 205, 152, 229, 144, 1, 205, 68, - 152, 229, 144, 1, 155, 152, 229, 144, 1, 208, 96, 152, 229, 144, 1, 190, - 190, 152, 229, 144, 1, 199, 250, 152, 229, 144, 1, 199, 145, 152, 229, - 144, 1, 199, 143, 152, 229, 144, 1, 159, 152, 229, 144, 1, 238, 32, 152, - 229, 144, 16, 195, 63, 152, 229, 144, 16, 195, 62, 152, 238, 166, 1, 65, - 152, 238, 166, 1, 71, 152, 238, 166, 1, 68, 152, 238, 166, 1, 74, 152, - 238, 166, 1, 170, 152, 238, 166, 1, 193, 190, 152, 238, 166, 1, 249, 153, - 152, 238, 166, 1, 168, 152, 238, 166, 1, 174, 152, 238, 166, 1, 180, 152, - 238, 166, 1, 214, 121, 152, 238, 166, 1, 165, 152, 238, 166, 1, 173, 152, - 238, 166, 1, 221, 215, 152, 238, 166, 1, 229, 177, 152, 238, 166, 1, 188, - 152, 238, 166, 1, 251, 14, 188, 152, 238, 166, 1, 205, 68, 152, 238, 166, - 1, 155, 152, 238, 166, 1, 208, 96, 152, 238, 166, 1, 190, 190, 152, 238, - 166, 1, 199, 145, 152, 238, 166, 1, 159, 152, 238, 166, 1, 238, 32, 152, - 238, 166, 232, 118, 234, 128, 197, 39, 152, 238, 166, 232, 118, 91, 230, - 70, 152, 238, 166, 219, 28, 206, 168, 152, 238, 166, 219, 28, 223, 169, - 152, 238, 166, 31, 107, 152, 238, 166, 31, 109, 152, 238, 166, 31, 138, - 152, 238, 166, 31, 134, 152, 238, 166, 31, 149, 152, 238, 166, 31, 169, - 152, 238, 166, 31, 175, 152, 238, 166, 31, 171, 152, 238, 166, 31, 178, - 152, 238, 166, 31, 199, 95, 152, 238, 166, 31, 197, 32, 152, 238, 166, - 31, 198, 249, 152, 238, 166, 31, 232, 135, 152, 238, 166, 31, 233, 15, - 152, 238, 166, 31, 202, 120, 152, 238, 166, 31, 203, 241, 152, 238, 166, - 31, 91, 228, 140, 152, 238, 166, 31, 105, 228, 140, 152, 238, 166, 31, - 115, 228, 140, 152, 238, 166, 31, 232, 128, 228, 140, 152, 238, 166, 31, - 232, 226, 228, 140, 152, 238, 166, 31, 202, 136, 228, 140, 152, 238, 166, - 31, 203, 247, 228, 140, 152, 238, 166, 31, 234, 164, 228, 140, 152, 238, - 166, 31, 213, 175, 228, 140, 152, 238, 166, 31, 91, 189, 152, 238, 166, - 31, 105, 189, 152, 238, 166, 31, 115, 189, 152, 238, 166, 31, 232, 128, - 189, 152, 238, 166, 31, 232, 226, 189, 152, 238, 166, 31, 202, 136, 189, - 152, 238, 166, 31, 203, 247, 189, 152, 238, 166, 31, 234, 164, 189, 152, - 238, 166, 31, 213, 175, 189, 152, 238, 166, 31, 199, 96, 189, 152, 238, - 166, 31, 197, 33, 189, 152, 238, 166, 31, 198, 250, 189, 152, 238, 166, - 31, 232, 136, 189, 152, 238, 166, 31, 233, 16, 189, 152, 238, 166, 31, - 202, 121, 189, 152, 238, 166, 31, 203, 242, 189, 152, 238, 166, 31, 234, - 154, 189, 152, 238, 166, 31, 213, 170, 189, 152, 238, 166, 31, 91, 228, - 141, 189, 152, 238, 166, 31, 105, 228, 141, 189, 152, 238, 166, 31, 115, - 228, 141, 189, 152, 238, 166, 31, 232, 128, 228, 141, 189, 152, 238, 166, - 31, 232, 226, 228, 141, 189, 152, 238, 166, 31, 202, 136, 228, 141, 189, - 152, 238, 166, 31, 203, 247, 228, 141, 189, 152, 238, 166, 31, 234, 164, - 228, 141, 189, 152, 238, 166, 31, 213, 175, 228, 141, 189, 152, 238, 166, - 232, 118, 91, 197, 40, 152, 238, 166, 232, 118, 105, 197, 39, 152, 238, - 166, 232, 118, 115, 197, 39, 152, 238, 166, 232, 118, 232, 128, 197, 39, - 152, 238, 166, 232, 118, 232, 226, 197, 39, 152, 238, 166, 232, 118, 202, - 136, 197, 39, 152, 238, 166, 232, 118, 203, 247, 197, 39, 152, 238, 166, - 232, 118, 234, 164, 197, 39, 152, 238, 166, 232, 118, 213, 175, 197, 39, - 152, 238, 166, 232, 118, 199, 96, 197, 39, 221, 199, 1, 65, 221, 199, 18, - 3, 68, 221, 199, 18, 3, 66, 221, 199, 18, 3, 117, 146, 221, 199, 18, 3, - 71, 221, 199, 18, 3, 74, 221, 199, 18, 219, 198, 77, 221, 199, 3, 55, - 206, 189, 60, 221, 199, 3, 251, 71, 221, 199, 3, 195, 35, 221, 199, 1, - 155, 221, 199, 1, 221, 215, 221, 199, 1, 231, 240, 221, 199, 1, 231, 91, - 221, 199, 1, 247, 160, 221, 199, 1, 247, 1, 221, 199, 1, 223, 32, 221, - 199, 1, 212, 101, 221, 199, 1, 197, 132, 221, 199, 1, 197, 120, 221, 199, - 1, 237, 191, 221, 199, 1, 237, 175, 221, 199, 1, 213, 79, 221, 199, 1, - 190, 190, 221, 199, 1, 199, 49, 221, 199, 1, 238, 32, 221, 199, 1, 237, - 68, 221, 199, 1, 180, 221, 199, 1, 168, 221, 199, 1, 209, 228, 221, 199, - 1, 249, 153, 221, 199, 1, 248, 203, 221, 199, 1, 174, 221, 199, 1, 170, - 221, 199, 1, 165, 221, 199, 1, 173, 221, 199, 1, 195, 188, 221, 199, 1, - 203, 165, 221, 199, 1, 201, 175, 221, 199, 1, 188, 221, 199, 1, 191, 123, - 221, 199, 1, 140, 221, 199, 1, 221, 101, 221, 199, 1, 197, 100, 221, 199, - 1, 197, 101, 221, 199, 1, 195, 70, 221, 199, 3, 249, 88, 58, 221, 199, 3, - 247, 74, 221, 199, 3, 75, 60, 221, 199, 195, 40, 221, 199, 17, 107, 221, - 199, 17, 109, 221, 199, 17, 138, 221, 199, 17, 134, 221, 199, 31, 199, - 95, 221, 199, 31, 197, 32, 221, 199, 31, 91, 228, 140, 221, 199, 31, 91, - 189, 221, 199, 232, 118, 91, 230, 70, 221, 199, 208, 152, 236, 140, 221, - 199, 208, 152, 2, 243, 10, 221, 199, 208, 152, 243, 10, 221, 199, 208, - 152, 238, 228, 164, 221, 199, 208, 152, 217, 83, 221, 199, 208, 152, 218, - 246, 221, 199, 208, 152, 237, 238, 221, 199, 208, 152, 55, 237, 238, 221, - 199, 208, 152, 219, 106, 39, 202, 2, 251, 29, 1, 229, 245, 39, 202, 2, - 251, 29, 1, 220, 26, 39, 202, 2, 251, 29, 1, 229, 184, 39, 202, 2, 251, - 29, 1, 216, 193, 39, 202, 2, 251, 29, 1, 208, 37, 39, 202, 2, 251, 29, 1, - 193, 133, 39, 202, 2, 251, 29, 1, 203, 69, 39, 202, 2, 251, 29, 1, 207, - 38, 39, 202, 2, 251, 29, 1, 248, 211, 39, 202, 2, 251, 29, 1, 199, 159, - 39, 202, 2, 251, 29, 1, 205, 122, 39, 202, 2, 251, 29, 1, 222, 75, 39, - 202, 2, 251, 29, 1, 212, 130, 39, 202, 2, 251, 29, 1, 221, 194, 39, 202, - 2, 251, 29, 1, 205, 189, 39, 202, 2, 251, 29, 1, 205, 148, 39, 202, 2, - 251, 29, 1, 233, 59, 39, 202, 2, 251, 29, 1, 251, 192, 39, 202, 2, 251, - 29, 1, 250, 124, 39, 202, 2, 251, 29, 1, 237, 65, 39, 202, 2, 251, 29, 1, - 231, 38, 39, 202, 2, 251, 29, 1, 237, 252, 39, 202, 2, 251, 29, 1, 231, - 79, 39, 202, 2, 251, 29, 1, 199, 69, 39, 202, 2, 251, 29, 1, 191, 89, 39, - 202, 2, 251, 29, 1, 237, 62, 39, 202, 2, 251, 29, 1, 191, 249, 39, 202, - 2, 251, 29, 1, 199, 35, 39, 202, 2, 251, 29, 1, 199, 14, 39, 202, 2, 251, - 29, 31, 107, 39, 202, 2, 251, 29, 31, 233, 15, 39, 202, 2, 251, 29, 167, - 223, 144, 39, 186, 251, 29, 1, 229, 210, 39, 186, 251, 29, 1, 220, 35, - 39, 186, 251, 29, 1, 230, 81, 39, 186, 251, 29, 1, 216, 208, 39, 186, - 251, 29, 1, 208, 89, 39, 186, 251, 29, 1, 193, 133, 39, 186, 251, 29, 1, - 234, 20, 39, 186, 251, 29, 1, 207, 71, 39, 186, 251, 29, 1, 248, 245, 39, - 186, 251, 29, 1, 199, 114, 39, 186, 251, 29, 1, 234, 21, 39, 186, 251, - 29, 1, 222, 106, 39, 186, 251, 29, 1, 213, 24, 39, 186, 251, 29, 1, 221, - 210, 39, 186, 251, 29, 1, 205, 192, 39, 186, 251, 29, 1, 234, 19, 39, - 186, 251, 29, 1, 233, 46, 39, 186, 251, 29, 1, 251, 192, 39, 186, 251, - 29, 1, 251, 230, 39, 186, 251, 29, 1, 238, 26, 39, 186, 251, 29, 1, 231, - 156, 39, 186, 251, 29, 1, 238, 3, 39, 186, 251, 29, 1, 231, 86, 39, 186, - 251, 29, 1, 199, 219, 39, 186, 251, 29, 1, 191, 113, 39, 186, 251, 29, 1, - 199, 41, 39, 186, 251, 29, 1, 192, 75, 39, 186, 251, 29, 1, 199, 29, 39, - 186, 251, 29, 1, 191, 116, 39, 186, 251, 29, 31, 107, 39, 186, 251, 29, - 31, 199, 95, 39, 186, 251, 29, 31, 197, 32, 217, 81, 1, 251, 190, 217, - 81, 1, 248, 211, 217, 81, 1, 248, 194, 217, 81, 1, 231, 38, 217, 81, 1, - 231, 64, 217, 81, 1, 237, 252, 217, 81, 1, 229, 245, 217, 81, 1, 193, - 133, 217, 81, 3, 196, 158, 217, 81, 1, 191, 91, 217, 81, 1, 191, 64, 217, - 81, 1, 223, 12, 217, 81, 1, 222, 248, 217, 81, 1, 229, 184, 217, 81, 1, - 199, 69, 217, 81, 1, 191, 249, 217, 81, 1, 222, 75, 217, 81, 1, 192, 217, - 217, 81, 1, 221, 201, 217, 81, 1, 220, 26, 217, 81, 1, 237, 61, 217, 81, - 1, 199, 40, 217, 81, 1, 216, 193, 217, 81, 1, 212, 130, 217, 81, 1, 205, - 148, 217, 81, 1, 250, 126, 217, 81, 1, 252, 158, 217, 81, 1, 210, 63, - 217, 81, 1, 233, 59, 217, 81, 1, 205, 189, 217, 81, 1, 208, 37, 217, 81, - 1, 192, 193, 217, 81, 1, 208, 64, 217, 81, 1, 207, 38, 217, 81, 1, 203, - 69, 217, 81, 1, 201, 143, 217, 81, 1, 199, 159, 217, 81, 252, 68, 87, 58, - 217, 81, 252, 68, 87, 60, 217, 81, 31, 107, 217, 81, 31, 149, 217, 81, - 31, 199, 95, 217, 81, 31, 197, 32, 217, 81, 31, 91, 228, 140, 217, 81, - 208, 152, 201, 102, 217, 81, 208, 152, 232, 201, 217, 81, 208, 152, 55, - 75, 193, 53, 236, 140, 217, 81, 208, 152, 75, 193, 53, 236, 140, 217, 81, - 208, 152, 236, 140, 217, 81, 208, 152, 105, 236, 138, 217, 81, 208, 152, - 219, 113, 233, 3, 250, 142, 1, 65, 250, 142, 1, 252, 206, 250, 142, 1, - 251, 68, 250, 142, 1, 252, 164, 250, 142, 1, 251, 132, 250, 142, 1, 252, - 166, 250, 142, 1, 252, 25, 250, 142, 1, 252, 21, 250, 142, 1, 71, 250, - 142, 1, 234, 188, 250, 142, 1, 74, 250, 142, 1, 211, 87, 250, 142, 1, 68, - 250, 142, 1, 223, 199, 250, 142, 1, 66, 250, 142, 1, 196, 30, 250, 142, - 1, 222, 22, 250, 142, 1, 192, 214, 250, 142, 1, 192, 173, 250, 142, 1, - 192, 184, 250, 142, 1, 231, 165, 250, 142, 1, 231, 122, 250, 142, 1, 231, - 77, 250, 142, 1, 247, 42, 250, 142, 1, 223, 10, 250, 142, 1, 199, 145, - 250, 142, 1, 199, 33, 250, 142, 1, 237, 146, 250, 142, 1, 237, 59, 250, - 142, 1, 197, 127, 250, 142, 1, 210, 63, 250, 142, 1, 233, 59, 250, 142, - 1, 249, 17, 250, 142, 1, 248, 196, 250, 142, 1, 214, 55, 250, 142, 1, - 213, 226, 250, 142, 1, 213, 227, 250, 142, 1, 214, 121, 250, 142, 1, 212, - 90, 250, 142, 1, 213, 74, 250, 142, 1, 216, 232, 250, 142, 1, 229, 73, - 250, 142, 1, 191, 173, 250, 142, 1, 192, 80, 250, 142, 1, 195, 153, 250, - 142, 1, 207, 113, 250, 142, 1, 219, 238, 250, 142, 1, 205, 68, 250, 142, - 1, 191, 87, 250, 142, 1, 203, 113, 250, 142, 1, 191, 62, 250, 142, 1, - 202, 229, 250, 142, 1, 201, 144, 250, 142, 1, 229, 245, 250, 142, 252, - 68, 77, 198, 138, 105, 185, 139, 91, 75, 208, 151, 2, 105, 185, 139, 91, - 75, 208, 151, 220, 13, 105, 185, 139, 91, 75, 208, 151, 220, 13, 91, 75, - 139, 105, 185, 208, 151, 220, 13, 105, 206, 185, 139, 91, 206, 189, 208, - 151, 220, 13, 91, 206, 189, 139, 105, 206, 185, 208, 151, 223, 122, 210, - 106, 1, 251, 190, 223, 122, 210, 106, 1, 248, 211, 223, 122, 210, 106, 1, - 231, 38, 223, 122, 210, 106, 1, 237, 252, 223, 122, 210, 106, 1, 229, - 245, 223, 122, 210, 106, 1, 193, 133, 223, 122, 210, 106, 1, 191, 91, - 223, 122, 210, 106, 1, 229, 184, 223, 122, 210, 106, 1, 199, 69, 223, - 122, 210, 106, 1, 191, 249, 223, 122, 210, 106, 1, 222, 75, 223, 122, - 210, 106, 1, 220, 26, 223, 122, 210, 106, 1, 216, 193, 223, 122, 210, - 106, 1, 212, 130, 223, 122, 210, 106, 1, 205, 148, 223, 122, 210, 106, 1, - 250, 126, 223, 122, 210, 106, 1, 210, 63, 223, 122, 210, 106, 1, 205, - 189, 223, 122, 210, 106, 1, 208, 37, 223, 122, 210, 106, 1, 207, 38, 223, - 122, 210, 106, 1, 203, 69, 223, 122, 210, 106, 1, 199, 159, 223, 122, - 210, 106, 31, 107, 223, 122, 210, 106, 31, 109, 223, 122, 210, 106, 31, - 138, 223, 122, 210, 106, 31, 134, 223, 122, 210, 106, 31, 199, 95, 223, - 122, 210, 106, 31, 197, 32, 223, 122, 210, 106, 31, 91, 228, 140, 223, - 122, 210, 106, 31, 91, 189, 223, 122, 210, 199, 1, 251, 190, 223, 122, - 210, 199, 1, 248, 211, 223, 122, 210, 199, 1, 231, 38, 223, 122, 210, - 199, 1, 237, 252, 223, 122, 210, 199, 1, 229, 245, 223, 122, 210, 199, 1, - 193, 132, 223, 122, 210, 199, 1, 191, 91, 223, 122, 210, 199, 1, 229, - 184, 223, 122, 210, 199, 1, 199, 69, 223, 122, 210, 199, 1, 191, 249, - 223, 122, 210, 199, 1, 222, 75, 223, 122, 210, 199, 1, 220, 26, 223, 122, - 210, 199, 1, 216, 192, 223, 122, 210, 199, 1, 212, 130, 223, 122, 210, - 199, 1, 205, 148, 223, 122, 210, 199, 1, 210, 63, 223, 122, 210, 199, 1, - 205, 189, 223, 122, 210, 199, 1, 203, 69, 223, 122, 210, 199, 1, 199, - 159, 223, 122, 210, 199, 31, 107, 223, 122, 210, 199, 31, 109, 223, 122, - 210, 199, 31, 138, 223, 122, 210, 199, 31, 134, 223, 122, 210, 199, 31, - 199, 95, 223, 122, 210, 199, 31, 197, 32, 223, 122, 210, 199, 31, 91, - 228, 140, 223, 122, 210, 199, 31, 91, 189, 208, 177, 210, 199, 1, 251, - 190, 208, 177, 210, 199, 1, 248, 211, 208, 177, 210, 199, 1, 231, 38, - 208, 177, 210, 199, 1, 237, 252, 208, 177, 210, 199, 1, 229, 245, 208, - 177, 210, 199, 1, 193, 132, 208, 177, 210, 199, 1, 191, 91, 208, 177, - 210, 199, 1, 229, 184, 208, 177, 210, 199, 1, 191, 249, 208, 177, 210, - 199, 1, 222, 75, 208, 177, 210, 199, 1, 220, 26, 208, 177, 210, 199, 1, - 216, 192, 208, 177, 210, 199, 1, 212, 130, 208, 177, 210, 199, 1, 205, - 148, 208, 177, 210, 199, 1, 210, 63, 208, 177, 210, 199, 1, 205, 189, - 208, 177, 210, 199, 1, 203, 69, 208, 177, 210, 199, 1, 199, 159, 208, - 177, 210, 199, 205, 54, 77, 208, 177, 210, 199, 153, 205, 54, 77, 208, - 177, 210, 199, 232, 128, 185, 4, 238, 217, 208, 177, 210, 199, 232, 128, - 185, 4, 236, 140, 208, 177, 210, 199, 31, 107, 208, 177, 210, 199, 31, - 109, 208, 177, 210, 199, 31, 138, 208, 177, 210, 199, 31, 134, 208, 177, - 210, 199, 31, 199, 95, 208, 177, 210, 199, 31, 197, 32, 208, 177, 210, - 199, 31, 91, 228, 140, 39, 197, 61, 1, 211, 44, 65, 39, 197, 61, 1, 192, - 68, 65, 39, 197, 61, 1, 192, 68, 252, 25, 39, 197, 61, 1, 211, 44, 68, + 1, 170, 216, 207, 217, 20, 1, 221, 53, 216, 207, 217, 20, 1, 205, 153, + 216, 207, 217, 20, 1, 220, 98, 216, 207, 217, 20, 1, 216, 25, 216, 207, + 217, 20, 1, 168, 216, 207, 217, 20, 1, 181, 216, 207, 217, 20, 1, 243, + 89, 216, 207, 217, 20, 1, 198, 154, 216, 207, 217, 20, 1, 221, 178, 216, + 207, 217, 20, 1, 213, 241, 216, 207, 217, 20, 1, 198, 232, 216, 207, 217, + 20, 1, 193, 173, 216, 207, 217, 20, 1, 192, 106, 216, 207, 217, 20, 1, + 228, 149, 216, 207, 217, 20, 1, 196, 113, 216, 207, 217, 20, 1, 68, 216, + 207, 217, 20, 1, 209, 224, 216, 207, 217, 20, 1, 250, 177, 216, 207, 217, + 20, 1, 230, 253, 216, 207, 217, 20, 1, 222, 252, 216, 207, 217, 20, 1, + 207, 158, 216, 207, 217, 20, 1, 249, 155, 216, 207, 217, 20, 1, 222, 236, + 216, 207, 217, 20, 1, 237, 3, 216, 207, 217, 20, 1, 231, 62, 216, 207, + 217, 20, 1, 237, 48, 216, 207, 217, 20, 1, 248, 200, 216, 207, 217, 20, + 1, 221, 54, 219, 11, 216, 207, 217, 20, 1, 220, 99, 219, 11, 216, 207, + 217, 20, 1, 216, 26, 219, 11, 216, 207, 217, 20, 1, 210, 223, 219, 11, + 216, 207, 217, 20, 1, 215, 9, 219, 11, 216, 207, 217, 20, 1, 198, 155, + 219, 11, 216, 207, 217, 20, 1, 213, 242, 219, 11, 216, 207, 217, 20, 1, + 228, 76, 219, 11, 216, 207, 217, 20, 18, 3, 211, 104, 216, 207, 217, 20, + 18, 3, 223, 162, 216, 207, 217, 20, 18, 3, 251, 132, 216, 207, 217, 20, + 18, 3, 192, 69, 216, 207, 217, 20, 18, 3, 202, 7, 216, 207, 217, 20, 18, + 3, 196, 110, 216, 207, 217, 20, 18, 3, 243, 116, 216, 207, 217, 20, 18, + 3, 212, 129, 216, 207, 217, 20, 243, 117, 216, 207, 217, 20, 218, 211, + 223, 44, 216, 207, 217, 20, 251, 40, 223, 44, 216, 207, 217, 20, 17, 191, + 77, 216, 207, 217, 20, 17, 107, 216, 207, 217, 20, 17, 109, 216, 207, + 217, 20, 17, 138, 216, 207, 217, 20, 17, 134, 216, 207, 217, 20, 17, 150, + 216, 207, 217, 20, 17, 169, 216, 207, 217, 20, 17, 175, 216, 207, 217, + 20, 17, 171, 216, 207, 217, 20, 17, 178, 30, 222, 176, 212, 5, 30, 222, + 176, 212, 10, 30, 222, 176, 192, 5, 30, 222, 176, 192, 4, 30, 222, 176, + 192, 3, 30, 222, 176, 196, 218, 30, 222, 176, 196, 222, 30, 222, 176, + 191, 219, 30, 222, 176, 191, 215, 30, 222, 176, 233, 243, 30, 222, 176, + 233, 241, 30, 222, 176, 233, 242, 30, 222, 176, 233, 239, 30, 222, 176, + 228, 62, 30, 222, 176, 228, 61, 30, 222, 176, 228, 59, 30, 222, 176, 228, + 60, 30, 222, 176, 228, 65, 30, 222, 176, 228, 58, 30, 222, 176, 228, 57, + 30, 222, 176, 228, 67, 30, 222, 176, 251, 26, 30, 222, 176, 251, 25, 30, + 125, 213, 199, 30, 125, 213, 205, 30, 125, 201, 157, 30, 125, 201, 156, + 30, 125, 198, 163, 30, 125, 198, 161, 30, 125, 198, 160, 30, 125, 198, + 166, 30, 125, 198, 167, 30, 125, 198, 159, 30, 125, 206, 219, 30, 125, + 206, 234, 30, 125, 201, 163, 30, 125, 206, 231, 30, 125, 206, 221, 30, + 125, 206, 223, 30, 125, 206, 210, 30, 125, 206, 211, 30, 125, 222, 70, + 30, 125, 216, 74, 30, 125, 216, 68, 30, 125, 201, 167, 30, 125, 216, 71, + 30, 125, 216, 77, 30, 125, 209, 152, 30, 125, 209, 161, 30, 125, 209, + 165, 30, 125, 201, 165, 30, 125, 209, 155, 30, 125, 209, 169, 30, 125, + 209, 170, 30, 125, 202, 153, 30, 125, 202, 156, 30, 125, 201, 161, 30, + 125, 201, 159, 30, 125, 202, 151, 30, 125, 202, 159, 30, 125, 202, 160, + 30, 125, 202, 145, 30, 125, 202, 158, 30, 125, 210, 149, 30, 125, 210, + 150, 30, 125, 192, 53, 30, 125, 192, 56, 30, 125, 243, 24, 30, 125, 243, + 23, 30, 125, 201, 172, 30, 125, 209, 208, 30, 125, 209, 207, 12, 15, 225, + 192, 12, 15, 225, 191, 12, 15, 225, 190, 12, 15, 225, 189, 12, 15, 225, + 188, 12, 15, 225, 187, 12, 15, 225, 186, 12, 15, 225, 185, 12, 15, 225, + 184, 12, 15, 225, 183, 12, 15, 225, 182, 12, 15, 225, 181, 12, 15, 225, + 180, 12, 15, 225, 179, 12, 15, 225, 178, 12, 15, 225, 177, 12, 15, 225, + 176, 12, 15, 225, 175, 12, 15, 225, 174, 12, 15, 225, 173, 12, 15, 225, + 172, 12, 15, 225, 171, 12, 15, 225, 170, 12, 15, 225, 169, 12, 15, 225, + 168, 12, 15, 225, 167, 12, 15, 225, 166, 12, 15, 225, 165, 12, 15, 225, + 164, 12, 15, 225, 163, 12, 15, 225, 162, 12, 15, 225, 161, 12, 15, 225, + 160, 12, 15, 225, 159, 12, 15, 225, 158, 12, 15, 225, 157, 12, 15, 225, + 156, 12, 15, 225, 155, 12, 15, 225, 154, 12, 15, 225, 153, 12, 15, 225, + 152, 12, 15, 225, 151, 12, 15, 225, 150, 12, 15, 225, 149, 12, 15, 225, + 148, 12, 15, 225, 147, 12, 15, 225, 146, 12, 15, 225, 145, 12, 15, 225, + 144, 12, 15, 225, 143, 12, 15, 225, 142, 12, 15, 225, 141, 12, 15, 225, + 140, 12, 15, 225, 139, 12, 15, 225, 138, 12, 15, 225, 137, 12, 15, 225, + 136, 12, 15, 225, 135, 12, 15, 225, 134, 12, 15, 225, 133, 12, 15, 225, + 132, 12, 15, 225, 131, 12, 15, 225, 130, 12, 15, 225, 129, 12, 15, 225, + 128, 12, 15, 225, 127, 12, 15, 225, 126, 12, 15, 225, 125, 12, 15, 225, + 124, 12, 15, 225, 123, 12, 15, 225, 122, 12, 15, 225, 121, 12, 15, 225, + 120, 12, 15, 225, 119, 12, 15, 225, 118, 12, 15, 225, 117, 12, 15, 225, + 116, 12, 15, 225, 115, 12, 15, 225, 114, 12, 15, 225, 113, 12, 15, 225, + 112, 12, 15, 225, 111, 12, 15, 225, 110, 12, 15, 225, 109, 12, 15, 225, + 108, 12, 15, 225, 107, 12, 15, 225, 106, 12, 15, 225, 105, 12, 15, 225, + 104, 12, 15, 225, 103, 12, 15, 225, 102, 12, 15, 225, 101, 12, 15, 225, + 100, 12, 15, 225, 99, 12, 15, 225, 98, 12, 15, 225, 97, 12, 15, 225, 96, + 12, 15, 225, 95, 12, 15, 225, 94, 12, 15, 225, 93, 12, 15, 225, 92, 12, + 15, 225, 91, 12, 15, 225, 90, 12, 15, 225, 89, 12, 15, 225, 88, 12, 15, + 225, 87, 12, 15, 225, 86, 12, 15, 225, 85, 12, 15, 225, 84, 12, 15, 225, + 83, 12, 15, 225, 82, 12, 15, 225, 81, 12, 15, 225, 80, 12, 15, 225, 79, + 12, 15, 225, 78, 12, 15, 225, 77, 12, 15, 225, 76, 12, 15, 225, 75, 12, + 15, 225, 74, 12, 15, 225, 73, 12, 15, 225, 72, 12, 15, 225, 71, 12, 15, + 225, 70, 12, 15, 225, 69, 12, 15, 225, 68, 12, 15, 225, 67, 12, 15, 225, + 66, 12, 15, 225, 65, 12, 15, 225, 64, 12, 15, 225, 63, 12, 15, 225, 62, + 12, 15, 225, 61, 12, 15, 225, 60, 12, 15, 225, 59, 12, 15, 225, 58, 12, + 15, 225, 57, 12, 15, 225, 56, 12, 15, 225, 55, 12, 15, 225, 54, 12, 15, + 225, 53, 12, 15, 225, 52, 12, 15, 225, 51, 12, 15, 225, 50, 12, 15, 225, + 49, 12, 15, 225, 48, 12, 15, 225, 47, 12, 15, 225, 46, 12, 15, 225, 45, + 12, 15, 225, 44, 12, 15, 225, 43, 12, 15, 225, 42, 12, 15, 225, 41, 12, + 15, 225, 40, 12, 15, 225, 39, 12, 15, 225, 38, 12, 15, 225, 37, 12, 15, + 225, 36, 12, 15, 225, 35, 12, 15, 225, 34, 12, 15, 225, 33, 12, 15, 225, + 32, 12, 15, 225, 31, 12, 15, 225, 30, 12, 15, 225, 29, 12, 15, 225, 28, + 12, 15, 225, 27, 12, 15, 225, 26, 12, 15, 225, 25, 12, 15, 225, 24, 12, + 15, 225, 23, 12, 15, 225, 22, 12, 15, 225, 21, 12, 15, 225, 20, 12, 15, + 225, 19, 12, 15, 225, 18, 12, 15, 225, 17, 12, 15, 225, 16, 12, 15, 225, + 15, 12, 15, 225, 14, 12, 15, 225, 13, 12, 15, 225, 12, 12, 15, 225, 11, + 12, 15, 225, 10, 12, 15, 225, 9, 12, 15, 225, 8, 12, 15, 225, 7, 12, 15, + 225, 6, 12, 15, 225, 5, 12, 15, 225, 4, 12, 15, 225, 3, 12, 15, 225, 2, + 12, 15, 225, 1, 12, 15, 225, 0, 12, 15, 224, 255, 12, 15, 224, 254, 12, + 15, 224, 253, 12, 15, 224, 252, 12, 15, 224, 251, 12, 15, 224, 250, 12, + 15, 224, 249, 12, 15, 224, 248, 12, 15, 224, 247, 12, 15, 224, 246, 12, + 15, 224, 245, 12, 15, 224, 244, 12, 15, 224, 243, 12, 15, 224, 242, 12, + 15, 224, 241, 12, 15, 224, 240, 12, 15, 224, 239, 12, 15, 224, 238, 12, + 15, 224, 237, 12, 15, 224, 236, 12, 15, 224, 235, 12, 15, 224, 234, 12, + 15, 224, 233, 12, 15, 224, 232, 12, 15, 224, 231, 12, 15, 224, 230, 12, + 15, 224, 229, 12, 15, 224, 228, 12, 15, 224, 227, 12, 15, 224, 226, 12, + 15, 224, 225, 12, 15, 224, 224, 12, 15, 224, 223, 12, 15, 224, 222, 12, + 15, 224, 221, 12, 15, 224, 220, 12, 15, 224, 219, 12, 15, 224, 218, 12, + 15, 224, 217, 12, 15, 224, 216, 12, 15, 224, 215, 12, 15, 224, 214, 12, + 15, 224, 213, 12, 15, 224, 212, 12, 15, 224, 211, 12, 15, 224, 210, 12, + 15, 224, 209, 12, 15, 224, 208, 12, 15, 224, 207, 12, 15, 224, 206, 12, + 15, 224, 205, 12, 15, 224, 204, 12, 15, 224, 203, 12, 15, 224, 202, 12, + 15, 224, 201, 12, 15, 224, 200, 12, 15, 224, 199, 12, 15, 224, 198, 12, + 15, 224, 197, 12, 15, 224, 196, 12, 15, 224, 195, 12, 15, 224, 194, 12, + 15, 224, 193, 12, 15, 224, 192, 12, 15, 224, 191, 12, 15, 224, 190, 12, + 15, 224, 189, 12, 15, 224, 188, 12, 15, 224, 187, 12, 15, 224, 186, 12, + 15, 224, 185, 12, 15, 224, 184, 12, 15, 224, 183, 12, 15, 224, 182, 12, + 15, 224, 181, 12, 15, 224, 180, 12, 15, 224, 179, 12, 15, 224, 178, 12, + 15, 224, 177, 12, 15, 224, 176, 12, 15, 224, 175, 12, 15, 224, 174, 12, + 15, 224, 173, 12, 15, 224, 172, 12, 15, 224, 171, 12, 15, 224, 170, 12, + 15, 224, 169, 12, 15, 224, 168, 12, 15, 224, 167, 12, 15, 224, 166, 12, + 15, 224, 165, 12, 15, 224, 164, 12, 15, 224, 163, 12, 15, 224, 162, 12, + 15, 224, 161, 12, 15, 224, 160, 12, 15, 224, 159, 12, 15, 224, 158, 12, + 15, 224, 157, 12, 15, 224, 156, 12, 15, 224, 155, 12, 15, 224, 154, 12, + 15, 224, 153, 12, 15, 224, 152, 12, 15, 224, 151, 12, 15, 224, 150, 12, + 15, 224, 149, 12, 15, 224, 148, 12, 15, 224, 147, 12, 15, 224, 146, 12, + 15, 224, 145, 12, 15, 224, 144, 12, 15, 224, 143, 12, 15, 224, 142, 12, + 15, 224, 141, 12, 15, 224, 140, 12, 15, 224, 139, 12, 15, 224, 138, 12, + 15, 224, 137, 12, 15, 224, 136, 12, 15, 224, 135, 12, 15, 224, 134, 12, + 15, 224, 133, 12, 15, 224, 132, 12, 15, 224, 131, 12, 15, 224, 130, 12, + 15, 224, 129, 12, 15, 224, 128, 12, 15, 224, 127, 12, 15, 224, 126, 12, + 15, 224, 125, 12, 15, 224, 124, 12, 15, 224, 123, 12, 15, 224, 122, 12, + 15, 224, 121, 12, 15, 224, 120, 12, 15, 224, 119, 12, 15, 224, 118, 12, + 15, 224, 117, 12, 15, 224, 116, 12, 15, 224, 115, 12, 15, 224, 114, 12, + 15, 224, 113, 12, 15, 224, 112, 12, 15, 224, 111, 12, 15, 224, 110, 12, + 15, 224, 109, 12, 15, 224, 108, 12, 15, 224, 107, 12, 15, 224, 106, 12, + 15, 224, 105, 12, 15, 224, 104, 12, 15, 224, 103, 12, 15, 224, 102, 12, + 15, 224, 101, 12, 15, 224, 100, 12, 15, 224, 99, 12, 15, 224, 98, 12, 15, + 224, 97, 12, 15, 224, 96, 12, 15, 224, 95, 12, 15, 224, 94, 12, 15, 224, + 93, 12, 15, 224, 92, 12, 15, 224, 91, 12, 15, 224, 90, 12, 15, 224, 89, + 12, 15, 224, 88, 12, 15, 224, 87, 12, 15, 224, 86, 12, 15, 224, 85, 12, + 15, 224, 84, 12, 15, 224, 83, 12, 15, 224, 82, 12, 15, 224, 81, 12, 15, + 224, 80, 12, 15, 224, 79, 12, 15, 224, 78, 12, 15, 224, 77, 12, 15, 224, + 76, 12, 15, 224, 75, 12, 15, 224, 74, 12, 15, 224, 73, 12, 15, 224, 72, + 12, 15, 224, 71, 12, 15, 224, 70, 12, 15, 224, 69, 12, 15, 224, 68, 12, + 15, 224, 67, 12, 15, 224, 66, 12, 15, 224, 65, 12, 15, 224, 64, 12, 15, + 224, 63, 12, 15, 224, 62, 12, 15, 224, 61, 12, 15, 224, 60, 12, 15, 224, + 59, 12, 15, 224, 58, 12, 15, 224, 57, 12, 15, 224, 56, 12, 15, 224, 55, + 12, 15, 224, 54, 12, 15, 224, 53, 12, 15, 224, 52, 12, 15, 224, 51, 12, + 15, 224, 50, 12, 15, 224, 49, 12, 15, 224, 48, 12, 15, 224, 47, 12, 15, + 224, 46, 12, 15, 224, 45, 12, 15, 224, 44, 12, 15, 224, 43, 12, 15, 224, + 42, 12, 15, 224, 41, 12, 15, 224, 40, 12, 15, 224, 39, 12, 15, 224, 38, + 12, 15, 224, 37, 12, 15, 224, 36, 12, 15, 224, 35, 12, 15, 224, 34, 12, + 15, 224, 33, 12, 15, 224, 32, 12, 15, 224, 31, 12, 15, 224, 30, 12, 15, + 224, 29, 12, 15, 224, 28, 12, 15, 224, 27, 12, 15, 224, 26, 12, 15, 224, + 25, 12, 15, 224, 24, 12, 15, 224, 23, 12, 15, 224, 22, 12, 15, 224, 21, + 12, 15, 224, 20, 12, 15, 224, 19, 12, 15, 224, 18, 12, 15, 224, 17, 12, + 15, 224, 16, 12, 15, 224, 15, 12, 15, 224, 14, 12, 15, 224, 13, 12, 15, + 224, 12, 12, 15, 224, 11, 12, 15, 224, 10, 12, 15, 224, 9, 12, 15, 224, + 8, 12, 15, 224, 7, 12, 15, 224, 6, 12, 15, 224, 5, 12, 15, 224, 4, 12, + 15, 224, 3, 12, 15, 224, 2, 12, 15, 224, 1, 12, 15, 224, 0, 12, 15, 223, + 255, 12, 15, 223, 254, 12, 15, 223, 253, 12, 15, 223, 252, 12, 15, 223, + 251, 12, 15, 223, 250, 12, 15, 223, 249, 12, 15, 223, 248, 12, 15, 223, + 247, 12, 15, 223, 246, 12, 15, 223, 245, 12, 15, 223, 244, 12, 15, 223, + 243, 12, 15, 223, 242, 12, 15, 223, 241, 12, 15, 223, 240, 12, 15, 223, + 239, 12, 15, 223, 238, 12, 15, 223, 237, 12, 15, 223, 236, 12, 15, 223, + 235, 12, 15, 223, 234, 12, 15, 223, 233, 8, 2, 34, 233, 29, 8, 2, 34, + 233, 25, 8, 2, 34, 232, 222, 8, 2, 34, 233, 28, 8, 2, 34, 233, 27, 8, 2, + 34, 180, 206, 10, 200, 43, 8, 2, 34, 201, 119, 250, 251, 2, 34, 216, 189, + 212, 255, 250, 251, 2, 34, 216, 189, 234, 197, 250, 251, 2, 34, 216, 189, + 223, 133, 250, 251, 2, 34, 195, 75, 212, 255, 250, 251, 2, 34, 216, 189, + 192, 212, 136, 1, 191, 251, 4, 229, 121, 136, 209, 64, 222, 183, 195, + 166, 136, 34, 192, 31, 191, 251, 191, 251, 210, 90, 136, 1, 251, 154, + 250, 128, 136, 1, 193, 78, 251, 194, 136, 1, 193, 78, 237, 255, 136, 1, + 193, 78, 229, 247, 136, 1, 193, 78, 222, 108, 136, 1, 193, 78, 220, 29, + 136, 1, 193, 78, 53, 216, 195, 136, 1, 193, 78, 207, 39, 136, 1, 193, 78, + 199, 162, 136, 1, 251, 154, 108, 56, 136, 1, 203, 71, 4, 203, 71, 236, + 142, 136, 1, 203, 71, 4, 202, 176, 236, 142, 136, 1, 203, 71, 4, 238, 19, + 23, 203, 71, 236, 142, 136, 1, 203, 71, 4, 238, 19, 23, 202, 176, 236, + 142, 136, 1, 131, 4, 210, 90, 136, 1, 131, 4, 208, 86, 136, 1, 131, 4, + 217, 72, 136, 1, 248, 217, 4, 238, 18, 136, 1, 231, 41, 4, 238, 18, 136, + 1, 238, 0, 4, 238, 18, 136, 1, 229, 248, 4, 217, 72, 136, 1, 195, 159, 4, + 238, 18, 136, 1, 191, 92, 4, 238, 18, 136, 1, 199, 74, 4, 238, 18, 136, + 1, 191, 251, 4, 238, 18, 136, 1, 53, 222, 109, 4, 238, 18, 136, 1, 222, + 109, 4, 238, 18, 136, 1, 220, 30, 4, 238, 18, 136, 1, 216, 196, 4, 238, + 18, 136, 1, 212, 133, 4, 238, 18, 136, 1, 205, 150, 4, 238, 18, 136, 1, + 53, 210, 66, 4, 238, 18, 136, 1, 210, 66, 4, 238, 18, 136, 1, 197, 164, + 4, 238, 18, 136, 1, 208, 45, 4, 238, 18, 136, 1, 207, 40, 4, 238, 18, + 136, 1, 203, 71, 4, 238, 18, 136, 1, 199, 163, 4, 238, 18, 136, 1, 195, + 159, 4, 229, 9, 136, 1, 248, 217, 4, 207, 163, 136, 1, 222, 109, 4, 207, + 163, 136, 1, 210, 66, 4, 207, 163, 136, 34, 131, 220, 29, 9, 1, 131, 193, + 151, 76, 20, 9, 1, 131, 193, 151, 53, 20, 9, 1, 249, 2, 76, 20, 9, 1, + 249, 2, 53, 20, 9, 1, 249, 2, 89, 20, 9, 1, 249, 2, 216, 219, 20, 9, 1, + 210, 44, 76, 20, 9, 1, 210, 44, 53, 20, 9, 1, 210, 44, 89, 20, 9, 1, 210, + 44, 216, 219, 20, 9, 1, 248, 246, 76, 20, 9, 1, 248, 246, 53, 20, 9, 1, + 248, 246, 89, 20, 9, 1, 248, 246, 216, 219, 20, 9, 1, 197, 123, 76, 20, + 9, 1, 197, 123, 53, 20, 9, 1, 197, 123, 89, 20, 9, 1, 197, 123, 216, 219, + 20, 9, 1, 199, 113, 76, 20, 9, 1, 199, 113, 53, 20, 9, 1, 199, 113, 89, + 20, 9, 1, 199, 113, 216, 219, 20, 9, 1, 197, 125, 76, 20, 9, 1, 197, 125, + 53, 20, 9, 1, 197, 125, 89, 20, 9, 1, 197, 125, 216, 219, 20, 9, 1, 195, + 147, 76, 20, 9, 1, 195, 147, 53, 20, 9, 1, 195, 147, 89, 20, 9, 1, 195, + 147, 216, 219, 20, 9, 1, 210, 42, 76, 20, 9, 1, 210, 42, 53, 20, 9, 1, + 210, 42, 89, 20, 9, 1, 210, 42, 216, 219, 20, 9, 1, 235, 44, 76, 20, 9, + 1, 235, 44, 53, 20, 9, 1, 235, 44, 89, 20, 9, 1, 235, 44, 216, 219, 20, + 9, 1, 212, 90, 76, 20, 9, 1, 212, 90, 53, 20, 9, 1, 212, 90, 89, 20, 9, + 1, 212, 90, 216, 219, 20, 9, 1, 199, 150, 76, 20, 9, 1, 199, 150, 53, 20, + 9, 1, 199, 150, 89, 20, 9, 1, 199, 150, 216, 219, 20, 9, 1, 199, 148, 76, + 20, 9, 1, 199, 148, 53, 20, 9, 1, 199, 148, 89, 20, 9, 1, 199, 148, 216, + 219, 20, 9, 1, 237, 191, 76, 20, 9, 1, 237, 191, 53, 20, 9, 1, 238, 13, + 76, 20, 9, 1, 238, 13, 53, 20, 9, 1, 235, 81, 76, 20, 9, 1, 235, 81, 53, + 20, 9, 1, 237, 189, 76, 20, 9, 1, 237, 189, 53, 20, 9, 1, 223, 6, 76, 20, + 9, 1, 223, 6, 53, 20, 9, 1, 206, 103, 76, 20, 9, 1, 206, 103, 53, 20, 9, + 1, 222, 7, 76, 20, 9, 1, 222, 7, 53, 20, 9, 1, 222, 7, 89, 20, 9, 1, 222, + 7, 216, 219, 20, 9, 1, 231, 230, 76, 20, 9, 1, 231, 230, 53, 20, 9, 1, + 231, 230, 89, 20, 9, 1, 231, 230, 216, 219, 20, 9, 1, 230, 169, 76, 20, + 9, 1, 230, 169, 53, 20, 9, 1, 230, 169, 89, 20, 9, 1, 230, 169, 216, 219, + 20, 9, 1, 213, 250, 76, 20, 9, 1, 213, 250, 53, 20, 9, 1, 213, 250, 89, + 20, 9, 1, 213, 250, 216, 219, 20, 9, 1, 213, 27, 231, 60, 76, 20, 9, 1, + 213, 27, 231, 60, 53, 20, 9, 1, 206, 167, 76, 20, 9, 1, 206, 167, 53, 20, + 9, 1, 206, 167, 89, 20, 9, 1, 206, 167, 216, 219, 20, 9, 1, 229, 213, 4, + 99, 93, 76, 20, 9, 1, 229, 213, 4, 99, 93, 53, 20, 9, 1, 229, 213, 231, + 3, 76, 20, 9, 1, 229, 213, 231, 3, 53, 20, 9, 1, 229, 213, 231, 3, 89, + 20, 9, 1, 229, 213, 231, 3, 216, 219, 20, 9, 1, 229, 213, 236, 173, 76, + 20, 9, 1, 229, 213, 236, 173, 53, 20, 9, 1, 229, 213, 236, 173, 89, 20, + 9, 1, 229, 213, 236, 173, 216, 219, 20, 9, 1, 99, 249, 83, 76, 20, 9, 1, + 99, 249, 83, 53, 20, 9, 1, 99, 249, 83, 4, 230, 60, 93, 76, 20, 9, 1, 99, + 249, 83, 4, 230, 60, 93, 53, 20, 9, 16, 75, 58, 9, 16, 75, 60, 9, 16, + 105, 185, 58, 9, 16, 105, 185, 60, 9, 16, 115, 185, 58, 9, 16, 115, 185, + 60, 9, 16, 115, 185, 209, 60, 235, 121, 58, 9, 16, 115, 185, 209, 60, + 235, 121, 60, 9, 16, 232, 130, 185, 58, 9, 16, 232, 130, 185, 60, 9, 16, + 55, 81, 249, 90, 60, 9, 16, 105, 185, 195, 85, 58, 9, 16, 105, 185, 195, + 85, 60, 9, 16, 206, 189, 9, 16, 2, 199, 220, 58, 9, 16, 2, 199, 220, 60, + 9, 16, 193, 151, 58, 9, 1, 214, 73, 76, 20, 9, 1, 214, 73, 53, 20, 9, 1, + 214, 73, 89, 20, 9, 1, 214, 73, 216, 219, 20, 9, 1, 126, 76, 20, 9, 1, + 126, 53, 20, 9, 1, 211, 154, 76, 20, 9, 1, 211, 154, 53, 20, 9, 1, 191, + 226, 76, 20, 9, 1, 191, 226, 53, 20, 9, 1, 126, 4, 230, 60, 93, 76, 20, + 9, 1, 195, 154, 76, 20, 9, 1, 195, 154, 53, 20, 9, 1, 221, 134, 211, 154, + 76, 20, 9, 1, 221, 134, 211, 154, 53, 20, 9, 1, 221, 134, 191, 226, 76, + 20, 9, 1, 221, 134, 191, 226, 53, 20, 9, 1, 235, 17, 76, 20, 9, 1, 235, + 17, 53, 20, 9, 1, 235, 17, 89, 20, 9, 1, 235, 17, 216, 219, 20, 9, 1, + 196, 137, 222, 28, 221, 134, 131, 217, 102, 89, 20, 9, 1, 196, 137, 222, + 28, 221, 134, 131, 217, 102, 216, 219, 20, 9, 34, 99, 4, 230, 60, 93, 4, + 131, 76, 20, 9, 34, 99, 4, 230, 60, 93, 4, 131, 53, 20, 9, 34, 99, 4, + 230, 60, 93, 4, 252, 28, 76, 20, 9, 34, 99, 4, 230, 60, 93, 4, 252, 28, + 53, 20, 9, 34, 99, 4, 230, 60, 93, 4, 193, 134, 76, 20, 9, 34, 99, 4, + 230, 60, 93, 4, 193, 134, 53, 20, 9, 34, 99, 4, 230, 60, 93, 4, 126, 76, + 20, 9, 34, 99, 4, 230, 60, 93, 4, 126, 53, 20, 9, 34, 99, 4, 230, 60, 93, + 4, 211, 154, 76, 20, 9, 34, 99, 4, 230, 60, 93, 4, 211, 154, 53, 20, 9, + 34, 99, 4, 230, 60, 93, 4, 191, 226, 76, 20, 9, 34, 99, 4, 230, 60, 93, + 4, 191, 226, 53, 20, 9, 34, 99, 4, 230, 60, 93, 4, 235, 17, 76, 20, 9, + 34, 99, 4, 230, 60, 93, 4, 235, 17, 53, 20, 9, 34, 99, 4, 230, 60, 93, 4, + 235, 17, 89, 20, 9, 34, 196, 137, 221, 134, 99, 4, 230, 60, 93, 4, 131, + 217, 102, 76, 20, 9, 34, 196, 137, 221, 134, 99, 4, 230, 60, 93, 4, 131, + 217, 102, 53, 20, 9, 34, 196, 137, 221, 134, 99, 4, 230, 60, 93, 4, 131, + 217, 102, 89, 20, 9, 1, 233, 76, 99, 76, 20, 9, 1, 233, 76, 99, 53, 20, + 9, 1, 233, 76, 99, 89, 20, 9, 1, 233, 76, 99, 216, 219, 20, 9, 34, 99, 4, + 230, 60, 93, 4, 223, 9, 76, 20, 9, 34, 99, 4, 230, 60, 93, 4, 183, 76, + 20, 9, 34, 99, 4, 230, 60, 93, 4, 92, 76, 20, 9, 34, 99, 4, 230, 60, 93, + 4, 131, 217, 102, 76, 20, 9, 34, 99, 4, 230, 60, 93, 4, 99, 76, 20, 9, + 34, 248, 248, 4, 223, 9, 76, 20, 9, 34, 248, 248, 4, 183, 76, 20, 9, 34, + 248, 248, 4, 221, 213, 76, 20, 9, 34, 248, 248, 4, 92, 76, 20, 9, 34, + 248, 248, 4, 131, 217, 102, 76, 20, 9, 34, 248, 248, 4, 99, 76, 20, 9, + 34, 199, 115, 4, 223, 9, 76, 20, 9, 34, 199, 115, 4, 183, 76, 20, 9, 34, + 199, 115, 4, 221, 213, 76, 20, 9, 34, 199, 115, 4, 92, 76, 20, 9, 34, + 199, 115, 4, 131, 217, 102, 76, 20, 9, 34, 199, 115, 4, 99, 76, 20, 9, + 34, 199, 30, 4, 223, 9, 76, 20, 9, 34, 199, 30, 4, 92, 76, 20, 9, 34, + 199, 30, 4, 131, 217, 102, 76, 20, 9, 34, 199, 30, 4, 99, 76, 20, 9, 34, + 223, 9, 4, 183, 76, 20, 9, 34, 223, 9, 4, 92, 76, 20, 9, 34, 183, 4, 223, + 9, 76, 20, 9, 34, 183, 4, 92, 76, 20, 9, 34, 221, 213, 4, 223, 9, 76, 20, + 9, 34, 221, 213, 4, 183, 76, 20, 9, 34, 221, 213, 4, 92, 76, 20, 9, 34, + 205, 48, 4, 223, 9, 76, 20, 9, 34, 205, 48, 4, 183, 76, 20, 9, 34, 205, + 48, 4, 221, 213, 76, 20, 9, 34, 205, 48, 4, 92, 76, 20, 9, 34, 205, 194, + 4, 183, 76, 20, 9, 34, 205, 194, 4, 92, 76, 20, 9, 34, 238, 29, 4, 223, + 9, 76, 20, 9, 34, 238, 29, 4, 183, 76, 20, 9, 34, 238, 29, 4, 221, 213, + 76, 20, 9, 34, 238, 29, 4, 92, 76, 20, 9, 34, 199, 220, 4, 183, 76, 20, + 9, 34, 199, 220, 4, 92, 76, 20, 9, 34, 191, 117, 4, 92, 76, 20, 9, 34, + 251, 233, 4, 223, 9, 76, 20, 9, 34, 251, 233, 4, 92, 76, 20, 9, 34, 231, + 89, 4, 223, 9, 76, 20, 9, 34, 231, 89, 4, 92, 76, 20, 9, 34, 233, 49, 4, + 223, 9, 76, 20, 9, 34, 233, 49, 4, 183, 76, 20, 9, 34, 233, 49, 4, 221, + 213, 76, 20, 9, 34, 233, 49, 4, 92, 76, 20, 9, 34, 233, 49, 4, 131, 217, + 102, 76, 20, 9, 34, 233, 49, 4, 99, 76, 20, 9, 34, 208, 92, 4, 183, 76, + 20, 9, 34, 208, 92, 4, 92, 76, 20, 9, 34, 208, 92, 4, 131, 217, 102, 76, + 20, 9, 34, 208, 92, 4, 99, 76, 20, 9, 34, 222, 109, 4, 131, 76, 20, 9, + 34, 222, 109, 4, 223, 9, 76, 20, 9, 34, 222, 109, 4, 183, 76, 20, 9, 34, + 222, 109, 4, 221, 213, 76, 20, 9, 34, 222, 109, 4, 220, 38, 76, 20, 9, + 34, 222, 109, 4, 92, 76, 20, 9, 34, 222, 109, 4, 131, 217, 102, 76, 20, + 9, 34, 222, 109, 4, 99, 76, 20, 9, 34, 220, 38, 4, 223, 9, 76, 20, 9, 34, + 220, 38, 4, 183, 76, 20, 9, 34, 220, 38, 4, 221, 213, 76, 20, 9, 34, 220, + 38, 4, 92, 76, 20, 9, 34, 220, 38, 4, 131, 217, 102, 76, 20, 9, 34, 220, + 38, 4, 99, 76, 20, 9, 34, 92, 4, 223, 9, 76, 20, 9, 34, 92, 4, 183, 76, + 20, 9, 34, 92, 4, 221, 213, 76, 20, 9, 34, 92, 4, 92, 76, 20, 9, 34, 92, + 4, 131, 217, 102, 76, 20, 9, 34, 92, 4, 99, 76, 20, 9, 34, 213, 27, 4, + 223, 9, 76, 20, 9, 34, 213, 27, 4, 183, 76, 20, 9, 34, 213, 27, 4, 221, + 213, 76, 20, 9, 34, 213, 27, 4, 92, 76, 20, 9, 34, 213, 27, 4, 131, 217, + 102, 76, 20, 9, 34, 213, 27, 4, 99, 76, 20, 9, 34, 229, 213, 4, 223, 9, + 76, 20, 9, 34, 229, 213, 4, 92, 76, 20, 9, 34, 229, 213, 4, 131, 217, + 102, 76, 20, 9, 34, 229, 213, 4, 99, 76, 20, 9, 34, 99, 4, 223, 9, 76, + 20, 9, 34, 99, 4, 183, 76, 20, 9, 34, 99, 4, 221, 213, 76, 20, 9, 34, 99, + 4, 92, 76, 20, 9, 34, 99, 4, 131, 217, 102, 76, 20, 9, 34, 99, 4, 99, 76, + 20, 9, 34, 199, 42, 4, 200, 182, 131, 76, 20, 9, 34, 207, 73, 4, 200, + 182, 131, 76, 20, 9, 34, 131, 217, 102, 4, 200, 182, 131, 76, 20, 9, 34, + 203, 157, 4, 237, 246, 76, 20, 9, 34, 203, 157, 4, 222, 53, 76, 20, 9, + 34, 203, 157, 4, 233, 73, 76, 20, 9, 34, 203, 157, 4, 237, 248, 76, 20, + 9, 34, 203, 157, 4, 222, 55, 76, 20, 9, 34, 203, 157, 4, 200, 182, 131, + 76, 20, 9, 34, 99, 4, 230, 60, 93, 4, 207, 73, 53, 20, 9, 34, 99, 4, 230, + 60, 93, 4, 191, 114, 53, 20, 9, 34, 99, 4, 230, 60, 93, 4, 92, 53, 20, 9, + 34, 99, 4, 230, 60, 93, 4, 213, 27, 53, 20, 9, 34, 99, 4, 230, 60, 93, 4, + 131, 217, 102, 53, 20, 9, 34, 99, 4, 230, 60, 93, 4, 99, 53, 20, 9, 34, + 248, 248, 4, 207, 73, 53, 20, 9, 34, 248, 248, 4, 191, 114, 53, 20, 9, + 34, 248, 248, 4, 92, 53, 20, 9, 34, 248, 248, 4, 213, 27, 53, 20, 9, 34, + 248, 248, 4, 131, 217, 102, 53, 20, 9, 34, 248, 248, 4, 99, 53, 20, 9, + 34, 199, 115, 4, 207, 73, 53, 20, 9, 34, 199, 115, 4, 191, 114, 53, 20, + 9, 34, 199, 115, 4, 92, 53, 20, 9, 34, 199, 115, 4, 213, 27, 53, 20, 9, + 34, 199, 115, 4, 131, 217, 102, 53, 20, 9, 34, 199, 115, 4, 99, 53, 20, + 9, 34, 199, 30, 4, 207, 73, 53, 20, 9, 34, 199, 30, 4, 191, 114, 53, 20, + 9, 34, 199, 30, 4, 92, 53, 20, 9, 34, 199, 30, 4, 213, 27, 53, 20, 9, 34, + 199, 30, 4, 131, 217, 102, 53, 20, 9, 34, 199, 30, 4, 99, 53, 20, 9, 34, + 233, 49, 4, 131, 217, 102, 53, 20, 9, 34, 233, 49, 4, 99, 53, 20, 9, 34, + 208, 92, 4, 131, 217, 102, 53, 20, 9, 34, 208, 92, 4, 99, 53, 20, 9, 34, + 222, 109, 4, 131, 53, 20, 9, 34, 222, 109, 4, 220, 38, 53, 20, 9, 34, + 222, 109, 4, 92, 53, 20, 9, 34, 222, 109, 4, 131, 217, 102, 53, 20, 9, + 34, 222, 109, 4, 99, 53, 20, 9, 34, 220, 38, 4, 92, 53, 20, 9, 34, 220, + 38, 4, 131, 217, 102, 53, 20, 9, 34, 220, 38, 4, 99, 53, 20, 9, 34, 92, + 4, 131, 53, 20, 9, 34, 92, 4, 92, 53, 20, 9, 34, 213, 27, 4, 207, 73, 53, + 20, 9, 34, 213, 27, 4, 191, 114, 53, 20, 9, 34, 213, 27, 4, 92, 53, 20, + 9, 34, 213, 27, 4, 213, 27, 53, 20, 9, 34, 213, 27, 4, 131, 217, 102, 53, + 20, 9, 34, 213, 27, 4, 99, 53, 20, 9, 34, 131, 217, 102, 4, 200, 182, + 131, 53, 20, 9, 34, 99, 4, 207, 73, 53, 20, 9, 34, 99, 4, 191, 114, 53, + 20, 9, 34, 99, 4, 92, 53, 20, 9, 34, 99, 4, 213, 27, 53, 20, 9, 34, 99, + 4, 131, 217, 102, 53, 20, 9, 34, 99, 4, 99, 53, 20, 9, 34, 99, 4, 230, + 60, 93, 4, 223, 9, 89, 20, 9, 34, 99, 4, 230, 60, 93, 4, 183, 89, 20, 9, + 34, 99, 4, 230, 60, 93, 4, 221, 213, 89, 20, 9, 34, 99, 4, 230, 60, 93, + 4, 92, 89, 20, 9, 34, 99, 4, 230, 60, 93, 4, 229, 213, 89, 20, 9, 34, + 248, 248, 4, 223, 9, 89, 20, 9, 34, 248, 248, 4, 183, 89, 20, 9, 34, 248, + 248, 4, 221, 213, 89, 20, 9, 34, 248, 248, 4, 92, 89, 20, 9, 34, 248, + 248, 4, 229, 213, 89, 20, 9, 34, 199, 115, 4, 223, 9, 89, 20, 9, 34, 199, + 115, 4, 183, 89, 20, 9, 34, 199, 115, 4, 221, 213, 89, 20, 9, 34, 199, + 115, 4, 92, 89, 20, 9, 34, 199, 115, 4, 229, 213, 89, 20, 9, 34, 199, 30, + 4, 92, 89, 20, 9, 34, 223, 9, 4, 183, 89, 20, 9, 34, 223, 9, 4, 92, 89, + 20, 9, 34, 183, 4, 223, 9, 89, 20, 9, 34, 183, 4, 92, 89, 20, 9, 34, 221, + 213, 4, 223, 9, 89, 20, 9, 34, 221, 213, 4, 92, 89, 20, 9, 34, 205, 48, + 4, 223, 9, 89, 20, 9, 34, 205, 48, 4, 183, 89, 20, 9, 34, 205, 48, 4, + 221, 213, 89, 20, 9, 34, 205, 48, 4, 92, 89, 20, 9, 34, 205, 194, 4, 183, + 89, 20, 9, 34, 205, 194, 4, 221, 213, 89, 20, 9, 34, 205, 194, 4, 92, 89, + 20, 9, 34, 238, 29, 4, 223, 9, 89, 20, 9, 34, 238, 29, 4, 183, 89, 20, 9, + 34, 238, 29, 4, 221, 213, 89, 20, 9, 34, 238, 29, 4, 92, 89, 20, 9, 34, + 199, 220, 4, 183, 89, 20, 9, 34, 191, 117, 4, 92, 89, 20, 9, 34, 251, + 233, 4, 223, 9, 89, 20, 9, 34, 251, 233, 4, 92, 89, 20, 9, 34, 231, 89, + 4, 223, 9, 89, 20, 9, 34, 231, 89, 4, 92, 89, 20, 9, 34, 233, 49, 4, 223, + 9, 89, 20, 9, 34, 233, 49, 4, 183, 89, 20, 9, 34, 233, 49, 4, 221, 213, + 89, 20, 9, 34, 233, 49, 4, 92, 89, 20, 9, 34, 208, 92, 4, 183, 89, 20, 9, + 34, 208, 92, 4, 92, 89, 20, 9, 34, 222, 109, 4, 223, 9, 89, 20, 9, 34, + 222, 109, 4, 183, 89, 20, 9, 34, 222, 109, 4, 221, 213, 89, 20, 9, 34, + 222, 109, 4, 220, 38, 89, 20, 9, 34, 222, 109, 4, 92, 89, 20, 9, 34, 220, + 38, 4, 223, 9, 89, 20, 9, 34, 220, 38, 4, 183, 89, 20, 9, 34, 220, 38, 4, + 221, 213, 89, 20, 9, 34, 220, 38, 4, 92, 89, 20, 9, 34, 220, 38, 4, 229, + 213, 89, 20, 9, 34, 92, 4, 223, 9, 89, 20, 9, 34, 92, 4, 183, 89, 20, 9, + 34, 92, 4, 221, 213, 89, 20, 9, 34, 92, 4, 92, 89, 20, 9, 34, 213, 27, 4, + 223, 9, 89, 20, 9, 34, 213, 27, 4, 183, 89, 20, 9, 34, 213, 27, 4, 221, + 213, 89, 20, 9, 34, 213, 27, 4, 92, 89, 20, 9, 34, 213, 27, 4, 229, 213, + 89, 20, 9, 34, 229, 213, 4, 223, 9, 89, 20, 9, 34, 229, 213, 4, 92, 89, + 20, 9, 34, 229, 213, 4, 200, 182, 131, 89, 20, 9, 34, 99, 4, 223, 9, 89, + 20, 9, 34, 99, 4, 183, 89, 20, 9, 34, 99, 4, 221, 213, 89, 20, 9, 34, 99, + 4, 92, 89, 20, 9, 34, 99, 4, 229, 213, 89, 20, 9, 34, 99, 4, 230, 60, 93, + 4, 92, 216, 219, 20, 9, 34, 99, 4, 230, 60, 93, 4, 229, 213, 216, 219, + 20, 9, 34, 248, 248, 4, 92, 216, 219, 20, 9, 34, 248, 248, 4, 229, 213, + 216, 219, 20, 9, 34, 199, 115, 4, 92, 216, 219, 20, 9, 34, 199, 115, 4, + 229, 213, 216, 219, 20, 9, 34, 199, 30, 4, 92, 216, 219, 20, 9, 34, 199, + 30, 4, 229, 213, 216, 219, 20, 9, 34, 205, 48, 4, 92, 216, 219, 20, 9, + 34, 205, 48, 4, 229, 213, 216, 219, 20, 9, 34, 203, 111, 4, 92, 216, 219, + 20, 9, 34, 203, 111, 4, 229, 213, 216, 219, 20, 9, 34, 222, 109, 4, 220, + 38, 216, 219, 20, 9, 34, 222, 109, 4, 92, 216, 219, 20, 9, 34, 220, 38, + 4, 92, 216, 219, 20, 9, 34, 213, 27, 4, 92, 216, 219, 20, 9, 34, 213, 27, + 4, 229, 213, 216, 219, 20, 9, 34, 99, 4, 92, 216, 219, 20, 9, 34, 99, 4, + 229, 213, 216, 219, 20, 9, 34, 203, 157, 4, 233, 73, 216, 219, 20, 9, 34, + 203, 157, 4, 237, 248, 216, 219, 20, 9, 34, 203, 157, 4, 222, 55, 216, + 219, 20, 9, 34, 199, 220, 4, 131, 217, 102, 76, 20, 9, 34, 199, 220, 4, + 99, 76, 20, 9, 34, 251, 233, 4, 131, 217, 102, 76, 20, 9, 34, 251, 233, + 4, 99, 76, 20, 9, 34, 231, 89, 4, 131, 217, 102, 76, 20, 9, 34, 231, 89, + 4, 99, 76, 20, 9, 34, 205, 48, 4, 131, 217, 102, 76, 20, 9, 34, 205, 48, + 4, 99, 76, 20, 9, 34, 203, 111, 4, 131, 217, 102, 76, 20, 9, 34, 203, + 111, 4, 99, 76, 20, 9, 34, 183, 4, 131, 217, 102, 76, 20, 9, 34, 183, 4, + 99, 76, 20, 9, 34, 223, 9, 4, 131, 217, 102, 76, 20, 9, 34, 223, 9, 4, + 99, 76, 20, 9, 34, 221, 213, 4, 131, 217, 102, 76, 20, 9, 34, 221, 213, + 4, 99, 76, 20, 9, 34, 205, 194, 4, 131, 217, 102, 76, 20, 9, 34, 205, + 194, 4, 99, 76, 20, 9, 34, 238, 29, 4, 131, 217, 102, 76, 20, 9, 34, 238, + 29, 4, 99, 76, 20, 9, 34, 203, 111, 4, 223, 9, 76, 20, 9, 34, 203, 111, + 4, 183, 76, 20, 9, 34, 203, 111, 4, 221, 213, 76, 20, 9, 34, 203, 111, 4, + 92, 76, 20, 9, 34, 203, 111, 4, 207, 73, 76, 20, 9, 34, 205, 48, 4, 207, + 73, 76, 20, 9, 34, 205, 194, 4, 207, 73, 76, 20, 9, 34, 238, 29, 4, 207, + 73, 76, 20, 9, 34, 199, 220, 4, 131, 217, 102, 53, 20, 9, 34, 199, 220, + 4, 99, 53, 20, 9, 34, 251, 233, 4, 131, 217, 102, 53, 20, 9, 34, 251, + 233, 4, 99, 53, 20, 9, 34, 231, 89, 4, 131, 217, 102, 53, 20, 9, 34, 231, + 89, 4, 99, 53, 20, 9, 34, 205, 48, 4, 131, 217, 102, 53, 20, 9, 34, 205, + 48, 4, 99, 53, 20, 9, 34, 203, 111, 4, 131, 217, 102, 53, 20, 9, 34, 203, + 111, 4, 99, 53, 20, 9, 34, 183, 4, 131, 217, 102, 53, 20, 9, 34, 183, 4, + 99, 53, 20, 9, 34, 223, 9, 4, 131, 217, 102, 53, 20, 9, 34, 223, 9, 4, + 99, 53, 20, 9, 34, 221, 213, 4, 131, 217, 102, 53, 20, 9, 34, 221, 213, + 4, 99, 53, 20, 9, 34, 205, 194, 4, 131, 217, 102, 53, 20, 9, 34, 205, + 194, 4, 99, 53, 20, 9, 34, 238, 29, 4, 131, 217, 102, 53, 20, 9, 34, 238, + 29, 4, 99, 53, 20, 9, 34, 203, 111, 4, 223, 9, 53, 20, 9, 34, 203, 111, + 4, 183, 53, 20, 9, 34, 203, 111, 4, 221, 213, 53, 20, 9, 34, 203, 111, 4, + 92, 53, 20, 9, 34, 203, 111, 4, 207, 73, 53, 20, 9, 34, 205, 48, 4, 207, + 73, 53, 20, 9, 34, 205, 194, 4, 207, 73, 53, 20, 9, 34, 238, 29, 4, 207, + 73, 53, 20, 9, 34, 203, 111, 4, 223, 9, 89, 20, 9, 34, 203, 111, 4, 183, + 89, 20, 9, 34, 203, 111, 4, 221, 213, 89, 20, 9, 34, 203, 111, 4, 92, 89, + 20, 9, 34, 205, 48, 4, 229, 213, 89, 20, 9, 34, 203, 111, 4, 229, 213, + 89, 20, 9, 34, 199, 220, 4, 92, 89, 20, 9, 34, 205, 48, 4, 223, 9, 216, + 219, 20, 9, 34, 205, 48, 4, 183, 216, 219, 20, 9, 34, 205, 48, 4, 221, + 213, 216, 219, 20, 9, 34, 203, 111, 4, 223, 9, 216, 219, 20, 9, 34, 203, + 111, 4, 183, 216, 219, 20, 9, 34, 203, 111, 4, 221, 213, 216, 219, 20, 9, + 34, 199, 220, 4, 92, 216, 219, 20, 9, 34, 191, 117, 4, 92, 216, 219, 20, + 9, 34, 131, 4, 233, 71, 53, 20, 9, 34, 131, 4, 233, 71, 76, 20, 211, 42, + 45, 210, 115, 211, 42, 50, 210, 115, 9, 34, 207, 161, 251, 175, 9, 34, + 207, 169, 251, 174, 251, 109, 9, 34, 207, 169, 251, 174, 251, 108, 9, 34, + 207, 169, 251, 174, 251, 106, 9, 34, 207, 169, 251, 174, 251, 105, 9, 34, + 207, 169, 251, 174, 251, 104, 9, 34, 205, 163, 251, 199, 193, 184, 9, 34, + 251, 199, 250, 219, 9, 34, 251, 198, 250, 219, 9, 34, 251, 197, 250, 219, + 9, 34, 251, 199, 250, 218, 193, 154, 9, 34, 208, 19, 202, 141, 9, 34, + 205, 161, 251, 199, 193, 180, 193, 183, 9, 34, 251, 202, 250, 219, 9, 34, + 199, 235, 193, 182, 9, 34, 207, 160, 251, 175, 9, 34, 199, 115, 4, 223, + 9, 4, 92, 89, 20, 9, 34, 199, 115, 4, 183, 4, 223, 9, 53, 20, 9, 34, 199, + 115, 4, 183, 4, 223, 9, 89, 20, 9, 34, 199, 115, 4, 183, 4, 92, 89, 20, + 9, 34, 199, 115, 4, 221, 213, 4, 92, 89, 20, 9, 34, 199, 115, 4, 92, 4, + 223, 9, 89, 20, 9, 34, 199, 115, 4, 92, 4, 183, 89, 20, 9, 34, 199, 115, + 4, 92, 4, 221, 213, 89, 20, 9, 34, 223, 9, 4, 92, 4, 183, 53, 20, 9, 34, + 223, 9, 4, 92, 4, 183, 89, 20, 9, 34, 183, 4, 92, 4, 99, 53, 20, 9, 34, + 183, 4, 92, 4, 131, 217, 102, 53, 20, 9, 34, 205, 48, 4, 183, 4, 223, 9, + 89, 20, 9, 34, 205, 48, 4, 223, 9, 4, 183, 89, 20, 9, 34, 205, 48, 4, + 223, 9, 4, 131, 217, 102, 53, 20, 9, 34, 205, 48, 4, 92, 4, 183, 53, 20, + 9, 34, 205, 48, 4, 92, 4, 183, 89, 20, 9, 34, 205, 48, 4, 92, 4, 223, 9, + 89, 20, 9, 34, 205, 48, 4, 92, 4, 92, 53, 20, 9, 34, 205, 48, 4, 92, 4, + 92, 89, 20, 9, 34, 205, 194, 4, 183, 4, 183, 53, 20, 9, 34, 205, 194, 4, + 183, 4, 183, 89, 20, 9, 34, 205, 194, 4, 92, 4, 92, 53, 20, 9, 34, 203, + 111, 4, 183, 4, 92, 53, 20, 9, 34, 203, 111, 4, 183, 4, 92, 89, 20, 9, + 34, 203, 111, 4, 223, 9, 4, 99, 53, 20, 9, 34, 203, 111, 4, 92, 4, 221, + 213, 53, 20, 9, 34, 203, 111, 4, 92, 4, 221, 213, 89, 20, 9, 34, 203, + 111, 4, 92, 4, 92, 53, 20, 9, 34, 203, 111, 4, 92, 4, 92, 89, 20, 9, 34, + 238, 29, 4, 183, 4, 131, 217, 102, 53, 20, 9, 34, 238, 29, 4, 221, 213, + 4, 92, 53, 20, 9, 34, 238, 29, 4, 221, 213, 4, 92, 89, 20, 9, 34, 199, + 220, 4, 92, 4, 183, 53, 20, 9, 34, 199, 220, 4, 92, 4, 183, 89, 20, 9, + 34, 199, 220, 4, 92, 4, 92, 89, 20, 9, 34, 199, 220, 4, 92, 4, 99, 53, + 20, 9, 34, 251, 233, 4, 223, 9, 4, 92, 53, 20, 9, 34, 251, 233, 4, 92, 4, + 92, 53, 20, 9, 34, 251, 233, 4, 92, 4, 92, 89, 20, 9, 34, 251, 233, 4, + 92, 4, 131, 217, 102, 53, 20, 9, 34, 231, 89, 4, 92, 4, 92, 53, 20, 9, + 34, 231, 89, 4, 92, 4, 99, 53, 20, 9, 34, 231, 89, 4, 92, 4, 131, 217, + 102, 53, 20, 9, 34, 233, 49, 4, 221, 213, 4, 92, 53, 20, 9, 34, 233, 49, + 4, 221, 213, 4, 92, 89, 20, 9, 34, 208, 92, 4, 92, 4, 183, 53, 20, 9, 34, + 208, 92, 4, 92, 4, 92, 53, 20, 9, 34, 220, 38, 4, 183, 4, 92, 53, 20, 9, + 34, 220, 38, 4, 183, 4, 99, 53, 20, 9, 34, 220, 38, 4, 183, 4, 131, 217, + 102, 53, 20, 9, 34, 220, 38, 4, 223, 9, 4, 223, 9, 89, 20, 9, 34, 220, + 38, 4, 223, 9, 4, 223, 9, 53, 20, 9, 34, 220, 38, 4, 221, 213, 4, 92, 53, + 20, 9, 34, 220, 38, 4, 221, 213, 4, 92, 89, 20, 9, 34, 220, 38, 4, 92, 4, + 183, 53, 20, 9, 34, 220, 38, 4, 92, 4, 183, 89, 20, 9, 34, 92, 4, 183, 4, + 223, 9, 89, 20, 9, 34, 92, 4, 183, 4, 92, 89, 20, 9, 34, 92, 4, 183, 4, + 99, 53, 20, 9, 34, 92, 4, 223, 9, 4, 183, 89, 20, 9, 34, 92, 4, 223, 9, + 4, 92, 89, 20, 9, 34, 92, 4, 221, 213, 4, 223, 9, 89, 20, 9, 34, 92, 4, + 221, 213, 4, 92, 89, 20, 9, 34, 92, 4, 223, 9, 4, 221, 213, 89, 20, 9, + 34, 229, 213, 4, 92, 4, 223, 9, 89, 20, 9, 34, 229, 213, 4, 92, 4, 92, + 89, 20, 9, 34, 213, 27, 4, 183, 4, 92, 89, 20, 9, 34, 213, 27, 4, 183, 4, + 131, 217, 102, 53, 20, 9, 34, 213, 27, 4, 223, 9, 4, 92, 53, 20, 9, 34, + 213, 27, 4, 223, 9, 4, 92, 89, 20, 9, 34, 213, 27, 4, 223, 9, 4, 131, + 217, 102, 53, 20, 9, 34, 213, 27, 4, 92, 4, 99, 53, 20, 9, 34, 213, 27, + 4, 92, 4, 131, 217, 102, 53, 20, 9, 34, 99, 4, 92, 4, 92, 53, 20, 9, 34, + 99, 4, 92, 4, 92, 89, 20, 9, 34, 248, 248, 4, 221, 213, 4, 99, 53, 20, 9, + 34, 199, 115, 4, 223, 9, 4, 99, 53, 20, 9, 34, 199, 115, 4, 223, 9, 4, + 131, 217, 102, 53, 20, 9, 34, 199, 115, 4, 221, 213, 4, 99, 53, 20, 9, + 34, 199, 115, 4, 221, 213, 4, 131, 217, 102, 53, 20, 9, 34, 199, 115, 4, + 92, 4, 99, 53, 20, 9, 34, 199, 115, 4, 92, 4, 131, 217, 102, 53, 20, 9, + 34, 223, 9, 4, 92, 4, 99, 53, 20, 9, 34, 223, 9, 4, 183, 4, 131, 217, + 102, 53, 20, 9, 34, 223, 9, 4, 92, 4, 131, 217, 102, 53, 20, 9, 34, 205, + 48, 4, 221, 213, 4, 131, 217, 102, 53, 20, 9, 34, 205, 194, 4, 183, 4, + 99, 53, 20, 9, 34, 203, 111, 4, 183, 4, 99, 53, 20, 9, 34, 238, 29, 4, + 183, 4, 99, 53, 20, 9, 34, 220, 38, 4, 223, 9, 4, 99, 53, 20, 9, 34, 220, + 38, 4, 92, 4, 99, 53, 20, 9, 34, 99, 4, 183, 4, 99, 53, 20, 9, 34, 99, 4, + 223, 9, 4, 99, 53, 20, 9, 34, 99, 4, 92, 4, 99, 53, 20, 9, 34, 92, 4, 92, + 4, 99, 53, 20, 9, 34, 208, 92, 4, 92, 4, 99, 53, 20, 9, 34, 213, 27, 4, + 183, 4, 99, 53, 20, 9, 34, 208, 92, 4, 92, 4, 183, 89, 20, 9, 34, 220, + 38, 4, 183, 4, 92, 89, 20, 9, 34, 251, 233, 4, 92, 4, 99, 53, 20, 9, 34, + 222, 109, 4, 92, 4, 99, 53, 20, 9, 34, 213, 27, 4, 223, 9, 4, 183, 89, + 20, 9, 34, 92, 4, 221, 213, 4, 99, 53, 20, 9, 34, 220, 38, 4, 223, 9, 4, + 92, 89, 20, 9, 34, 222, 109, 4, 92, 4, 92, 53, 20, 9, 34, 220, 38, 4, + 223, 9, 4, 92, 53, 20, 9, 34, 213, 27, 4, 223, 9, 4, 183, 53, 20, 9, 34, + 223, 9, 4, 183, 4, 99, 53, 20, 9, 34, 183, 4, 223, 9, 4, 99, 53, 20, 9, + 34, 92, 4, 223, 9, 4, 99, 53, 20, 9, 34, 233, 49, 4, 92, 4, 99, 53, 20, + 9, 34, 248, 248, 4, 183, 4, 99, 53, 20, 9, 34, 222, 109, 4, 92, 4, 92, + 89, 20, 9, 34, 251, 233, 4, 223, 9, 4, 92, 89, 20, 9, 34, 205, 194, 4, + 92, 4, 92, 89, 20, 9, 34, 205, 48, 4, 221, 213, 4, 99, 53, 20, 9, 34, + 213, 27, 4, 223, 9, 4, 99, 53, 20, 9, 34, 205, 167, 251, 196, 9, 34, 205, + 164, 196, 40, 250, 222, 221, 35, 201, 65, 3, 76, 20, 9, 34, 208, 88, 196, + 40, 250, 222, 221, 35, 201, 65, 3, 76, 20, 9, 34, 251, 173, 76, 20, 9, + 34, 251, 215, 76, 20, 9, 34, 215, 237, 76, 20, 9, 34, 205, 165, 76, 20, + 9, 34, 207, 134, 76, 20, 9, 34, 251, 201, 76, 20, 9, 34, 193, 153, 76, + 20, 9, 34, 205, 164, 76, 20, 9, 34, 205, 162, 251, 201, 193, 152, 9, 34, + 223, 24, 206, 250, 56, 9, 34, 248, 153, 251, 33, 251, 34, 9, 34, 200, + 243, 193, 191, 199, 244, 9, 34, 250, 123, 193, 191, 223, 25, 67, 205, 34, + 67, 204, 179, 67, 204, 111, 67, 204, 100, 67, 204, 89, 67, 204, 78, 67, + 204, 67, 67, 204, 56, 67, 204, 45, 67, 205, 33, 67, 205, 22, 67, 205, 11, + 67, 205, 0, 67, 204, 245, 67, 204, 234, 67, 204, 223, 208, 223, 232, 148, + 40, 81, 242, 76, 208, 223, 232, 148, 40, 81, 148, 242, 76, 208, 223, 232, + 148, 40, 81, 148, 232, 82, 201, 64, 208, 223, 232, 148, 40, 81, 242, 85, + 208, 223, 232, 148, 40, 81, 204, 26, 208, 223, 232, 148, 40, 81, 233, + 218, 77, 208, 223, 232, 148, 40, 81, 208, 15, 77, 208, 223, 232, 148, 40, + 81, 45, 63, 219, 189, 248, 55, 208, 223, 232, 148, 40, 81, 50, 63, 219, + 189, 248, 51, 208, 223, 232, 148, 40, 81, 228, 243, 234, 122, 33, 34, 45, + 230, 72, 33, 34, 50, 230, 72, 33, 55, 198, 153, 45, 230, 72, 33, 55, 198, + 153, 50, 230, 72, 33, 217, 149, 45, 230, 72, 33, 217, 149, 50, 230, 72, + 33, 239, 46, 217, 148, 33, 34, 45, 132, 60, 33, 34, 50, 132, 60, 33, 198, + 153, 45, 132, 60, 33, 198, 153, 50, 132, 60, 33, 217, 149, 45, 132, 60, + 33, 217, 149, 50, 132, 60, 33, 239, 46, 217, 149, 60, 33, 38, 198, 123, + 45, 230, 72, 33, 38, 198, 123, 50, 230, 72, 208, 223, 232, 148, 40, 81, + 105, 75, 219, 238, 208, 223, 232, 148, 40, 81, 234, 117, 237, 217, 208, + 223, 232, 148, 40, 81, 234, 106, 237, 217, 208, 223, 232, 148, 40, 81, + 130, 219, 114, 208, 223, 232, 148, 40, 81, 193, 135, 130, 219, 114, 208, + 223, 232, 148, 40, 81, 45, 210, 115, 208, 223, 232, 148, 40, 81, 50, 210, + 115, 208, 223, 232, 148, 40, 81, 45, 238, 173, 248, 55, 208, 223, 232, + 148, 40, 81, 50, 238, 173, 248, 55, 208, 223, 232, 148, 40, 81, 45, 198, + 42, 203, 104, 248, 55, 208, 223, 232, 148, 40, 81, 50, 198, 42, 203, 104, + 248, 55, 208, 223, 232, 148, 40, 81, 45, 62, 219, 189, 248, 55, 208, 223, + 232, 148, 40, 81, 50, 62, 219, 189, 248, 55, 208, 223, 232, 148, 40, 81, + 45, 55, 251, 118, 248, 55, 208, 223, 232, 148, 40, 81, 50, 55, 251, 118, + 248, 55, 208, 223, 232, 148, 40, 81, 45, 251, 118, 248, 55, 208, 223, + 232, 148, 40, 81, 50, 251, 118, 248, 55, 208, 223, 232, 148, 40, 81, 45, + 239, 4, 248, 55, 208, 223, 232, 148, 40, 81, 50, 239, 4, 248, 55, 208, + 223, 232, 148, 40, 81, 45, 63, 239, 4, 248, 55, 208, 223, 232, 148, 40, + 81, 50, 63, 239, 4, 248, 55, 204, 1, 236, 142, 63, 204, 1, 236, 142, 208, + 223, 232, 148, 40, 81, 45, 51, 248, 55, 208, 223, 232, 148, 40, 81, 50, + 51, 248, 55, 237, 216, 211, 0, 247, 20, 211, 0, 193, 135, 211, 0, 55, + 193, 135, 211, 0, 237, 216, 130, 219, 114, 247, 20, 130, 219, 114, 193, + 135, 130, 219, 114, 2, 242, 76, 2, 148, 242, 76, 2, 232, 82, 201, 64, 2, + 204, 26, 2, 242, 85, 2, 208, 15, 77, 2, 233, 218, 77, 2, 234, 117, 237, + 217, 2, 45, 210, 115, 2, 50, 210, 115, 2, 45, 238, 173, 248, 55, 2, 50, + 238, 173, 248, 55, 2, 45, 198, 42, 203, 104, 248, 55, 2, 50, 198, 42, + 203, 104, 248, 55, 2, 31, 56, 2, 251, 139, 2, 250, 195, 2, 108, 56, 2, + 228, 89, 2, 219, 182, 56, 2, 230, 206, 56, 2, 234, 45, 56, 2, 207, 20, + 202, 24, 2, 236, 157, 56, 2, 210, 15, 56, 2, 242, 74, 250, 184, 9, 233, + 71, 76, 20, 9, 199, 169, 4, 233, 71, 58, 9, 237, 246, 76, 20, 9, 199, + 216, 232, 119, 9, 222, 53, 76, 20, 9, 233, 73, 76, 20, 9, 233, 73, 216, + 219, 20, 9, 237, 248, 76, 20, 9, 237, 248, 216, 219, 20, 9, 222, 55, 76, + 20, 9, 222, 55, 216, 219, 20, 9, 203, 157, 76, 20, 9, 203, 157, 216, 219, + 20, 9, 200, 207, 76, 20, 9, 200, 207, 216, 219, 20, 9, 1, 230, 60, 76, + 20, 9, 1, 131, 4, 217, 144, 93, 76, 20, 9, 1, 131, 4, 217, 144, 93, 53, + 20, 9, 1, 131, 4, 230, 60, 93, 76, 20, 9, 1, 131, 4, 230, 60, 93, 53, 20, + 9, 1, 193, 134, 4, 230, 60, 93, 76, 20, 9, 1, 193, 134, 4, 230, 60, 93, + 53, 20, 9, 1, 131, 4, 230, 60, 248, 235, 76, 20, 9, 1, 131, 4, 230, 60, + 248, 235, 53, 20, 9, 1, 99, 4, 230, 60, 93, 76, 20, 9, 1, 99, 4, 230, 60, + 93, 53, 20, 9, 1, 99, 4, 230, 60, 93, 89, 20, 9, 1, 99, 4, 230, 60, 93, + 216, 219, 20, 9, 1, 131, 76, 20, 9, 1, 131, 53, 20, 9, 1, 248, 248, 76, + 20, 9, 1, 248, 248, 53, 20, 9, 1, 248, 248, 89, 20, 9, 1, 248, 248, 216, + 219, 20, 9, 1, 199, 115, 217, 65, 76, 20, 9, 1, 199, 115, 217, 65, 53, + 20, 9, 1, 199, 115, 76, 20, 9, 1, 199, 115, 53, 20, 9, 1, 199, 115, 89, + 20, 9, 1, 199, 115, 216, 219, 20, 9, 1, 199, 30, 76, 20, 9, 1, 199, 30, + 53, 20, 9, 1, 199, 30, 89, 20, 9, 1, 199, 30, 216, 219, 20, 9, 1, 223, 9, + 76, 20, 9, 1, 223, 9, 53, 20, 9, 1, 223, 9, 89, 20, 9, 1, 223, 9, 216, + 219, 20, 9, 1, 183, 76, 20, 9, 1, 183, 53, 20, 9, 1, 183, 89, 20, 9, 1, + 183, 216, 219, 20, 9, 1, 221, 213, 76, 20, 9, 1, 221, 213, 53, 20, 9, 1, + 221, 213, 89, 20, 9, 1, 221, 213, 216, 219, 20, 9, 1, 238, 6, 76, 20, 9, + 1, 238, 6, 53, 20, 9, 1, 199, 42, 76, 20, 9, 1, 199, 42, 53, 20, 9, 1, + 207, 73, 76, 20, 9, 1, 207, 73, 53, 20, 9, 1, 191, 114, 76, 20, 9, 1, + 191, 114, 53, 20, 9, 1, 205, 48, 76, 20, 9, 1, 205, 48, 53, 20, 9, 1, + 205, 48, 89, 20, 9, 1, 205, 48, 216, 219, 20, 9, 1, 203, 111, 76, 20, 9, + 1, 203, 111, 53, 20, 9, 1, 203, 111, 89, 20, 9, 1, 203, 111, 216, 219, + 20, 9, 1, 205, 194, 76, 20, 9, 1, 205, 194, 53, 20, 9, 1, 205, 194, 89, + 20, 9, 1, 205, 194, 216, 219, 20, 9, 1, 238, 29, 76, 20, 9, 1, 238, 29, + 53, 20, 9, 1, 238, 29, 89, 20, 9, 1, 238, 29, 216, 219, 20, 9, 1, 199, + 220, 76, 20, 9, 1, 199, 220, 53, 20, 9, 1, 199, 220, 89, 20, 9, 1, 199, + 220, 216, 219, 20, 9, 1, 191, 117, 76, 20, 9, 1, 191, 117, 53, 20, 9, 1, + 191, 117, 89, 20, 9, 1, 191, 117, 216, 219, 20, 9, 1, 251, 233, 76, 20, + 9, 1, 251, 233, 53, 20, 9, 1, 251, 233, 89, 20, 9, 1, 251, 233, 216, 219, + 20, 9, 1, 231, 89, 76, 20, 9, 1, 231, 89, 53, 20, 9, 1, 231, 89, 89, 20, + 9, 1, 231, 89, 216, 219, 20, 9, 1, 233, 49, 76, 20, 9, 1, 233, 49, 53, + 20, 9, 1, 233, 49, 89, 20, 9, 1, 233, 49, 216, 219, 20, 9, 1, 208, 92, + 76, 20, 9, 1, 208, 92, 53, 20, 9, 1, 208, 92, 89, 20, 9, 1, 208, 92, 216, + 219, 20, 9, 1, 222, 109, 76, 20, 9, 1, 222, 109, 53, 20, 9, 1, 222, 109, + 89, 20, 9, 1, 222, 109, 216, 219, 20, 9, 1, 220, 38, 76, 20, 9, 1, 220, + 38, 53, 20, 9, 1, 220, 38, 89, 20, 9, 1, 220, 38, 216, 219, 20, 9, 1, 92, + 76, 20, 9, 1, 92, 53, 20, 9, 1, 92, 89, 20, 9, 1, 92, 216, 219, 20, 9, 1, + 213, 27, 76, 20, 9, 1, 213, 27, 53, 20, 9, 1, 213, 27, 89, 20, 9, 1, 213, + 27, 216, 219, 20, 9, 1, 229, 213, 76, 20, 9, 1, 229, 213, 53, 20, 9, 1, + 229, 213, 89, 20, 9, 1, 229, 213, 216, 219, 20, 9, 1, 193, 134, 76, 20, + 9, 1, 193, 134, 53, 20, 9, 1, 131, 217, 102, 76, 20, 9, 1, 131, 217, 102, + 53, 20, 9, 1, 99, 76, 20, 9, 1, 99, 53, 20, 9, 1, 99, 89, 20, 9, 1, 99, + 216, 219, 20, 9, 34, 220, 38, 4, 131, 4, 217, 144, 93, 76, 20, 9, 34, + 220, 38, 4, 131, 4, 217, 144, 93, 53, 20, 9, 34, 220, 38, 4, 131, 4, 230, + 60, 93, 76, 20, 9, 34, 220, 38, 4, 131, 4, 230, 60, 93, 53, 20, 9, 34, + 220, 38, 4, 131, 4, 230, 60, 248, 235, 76, 20, 9, 34, 220, 38, 4, 131, 4, + 230, 60, 248, 235, 53, 20, 9, 34, 220, 38, 4, 131, 76, 20, 9, 34, 220, + 38, 4, 131, 53, 20, 191, 78, 193, 75, 213, 39, 201, 248, 232, 80, 233, + 218, 77, 232, 80, 207, 254, 77, 232, 80, 31, 56, 232, 80, 236, 157, 56, + 232, 80, 210, 15, 56, 232, 80, 251, 139, 232, 80, 251, 51, 232, 80, 45, + 210, 115, 232, 80, 50, 210, 115, 232, 80, 250, 195, 232, 80, 108, 56, + 232, 80, 242, 76, 232, 80, 228, 89, 232, 80, 232, 82, 201, 64, 232, 80, + 202, 24, 232, 80, 17, 191, 77, 232, 80, 17, 107, 232, 80, 17, 109, 232, + 80, 17, 138, 232, 80, 17, 134, 232, 80, 17, 150, 232, 80, 17, 169, 232, + 80, 17, 175, 232, 80, 17, 171, 232, 80, 17, 178, 232, 80, 242, 85, 232, + 80, 204, 26, 232, 80, 219, 182, 56, 232, 80, 234, 45, 56, 232, 80, 230, + 206, 56, 232, 80, 208, 15, 77, 232, 80, 242, 74, 250, 184, 232, 80, 8, 6, + 1, 65, 232, 80, 8, 6, 1, 250, 122, 232, 80, 8, 6, 1, 247, 195, 232, 80, + 8, 6, 1, 238, 129, 232, 80, 8, 6, 1, 71, 232, 80, 8, 6, 1, 233, 177, 232, + 80, 8, 6, 1, 232, 53, 232, 80, 8, 6, 1, 230, 118, 232, 80, 8, 6, 1, 68, + 232, 80, 8, 6, 1, 223, 37, 232, 80, 8, 6, 1, 222, 154, 232, 80, 8, 6, 1, + 172, 232, 80, 8, 6, 1, 218, 170, 232, 80, 8, 6, 1, 215, 63, 232, 80, 8, + 6, 1, 74, 232, 80, 8, 6, 1, 210, 238, 232, 80, 8, 6, 1, 208, 106, 232, + 80, 8, 6, 1, 146, 232, 80, 8, 6, 1, 206, 9, 232, 80, 8, 6, 1, 200, 43, + 232, 80, 8, 6, 1, 66, 232, 80, 8, 6, 1, 196, 12, 232, 80, 8, 6, 1, 193, + 224, 232, 80, 8, 6, 1, 192, 235, 232, 80, 8, 6, 1, 192, 159, 232, 80, 8, + 6, 1, 191, 166, 232, 80, 45, 51, 248, 55, 232, 80, 207, 20, 202, 24, 232, + 80, 50, 51, 248, 55, 232, 80, 243, 4, 252, 62, 232, 80, 130, 219, 114, + 232, 80, 230, 213, 252, 62, 232, 80, 8, 2, 1, 65, 232, 80, 8, 2, 1, 250, + 122, 232, 80, 8, 2, 1, 247, 195, 232, 80, 8, 2, 1, 238, 129, 232, 80, 8, + 2, 1, 71, 232, 80, 8, 2, 1, 233, 177, 232, 80, 8, 2, 1, 232, 53, 232, 80, + 8, 2, 1, 230, 118, 232, 80, 8, 2, 1, 68, 232, 80, 8, 2, 1, 223, 37, 232, + 80, 8, 2, 1, 222, 154, 232, 80, 8, 2, 1, 172, 232, 80, 8, 2, 1, 218, 170, + 232, 80, 8, 2, 1, 215, 63, 232, 80, 8, 2, 1, 74, 232, 80, 8, 2, 1, 210, + 238, 232, 80, 8, 2, 1, 208, 106, 232, 80, 8, 2, 1, 146, 232, 80, 8, 2, 1, + 206, 9, 232, 80, 8, 2, 1, 200, 43, 232, 80, 8, 2, 1, 66, 232, 80, 8, 2, + 1, 196, 12, 232, 80, 8, 2, 1, 193, 224, 232, 80, 8, 2, 1, 192, 235, 232, + 80, 8, 2, 1, 192, 159, 232, 80, 8, 2, 1, 191, 166, 232, 80, 45, 238, 173, + 248, 55, 232, 80, 81, 219, 114, 232, 80, 50, 238, 173, 248, 55, 232, 80, + 198, 152, 232, 80, 45, 63, 210, 115, 232, 80, 50, 63, 210, 115, 151, 148, + 232, 82, 201, 64, 151, 45, 239, 4, 248, 55, 151, 50, 239, 4, 248, 55, + 151, 148, 242, 76, 151, 72, 82, 236, 142, 151, 72, 1, 193, 48, 151, 72, + 1, 2, 65, 151, 72, 1, 2, 68, 151, 72, 1, 2, 66, 151, 72, 1, 2, 71, 151, + 72, 1, 2, 74, 151, 72, 1, 2, 170, 151, 72, 1, 2, 191, 225, 151, 72, 1, 2, + 192, 12, 151, 72, 1, 2, 197, 94, 151, 222, 50, 208, 193, 202, 6, 77, 151, + 72, 1, 65, 151, 72, 1, 68, 151, 72, 1, 66, 151, 72, 1, 71, 151, 72, 1, + 74, 151, 72, 1, 155, 151, 72, 1, 221, 168, 151, 72, 1, 220, 234, 151, 72, + 1, 222, 24, 151, 72, 1, 221, 69, 151, 72, 1, 188, 151, 72, 1, 202, 223, + 151, 72, 1, 201, 5, 151, 72, 1, 205, 69, 151, 72, 1, 202, 47, 151, 72, 1, + 190, 190, 151, 72, 1, 198, 193, 151, 72, 1, 197, 94, 151, 72, 1, 199, + 145, 151, 72, 1, 159, 151, 72, 1, 181, 151, 72, 1, 213, 221, 151, 72, 1, + 212, 180, 151, 72, 1, 214, 123, 151, 72, 1, 213, 45, 151, 72, 1, 140, + 151, 72, 1, 229, 160, 151, 72, 1, 228, 161, 151, 72, 1, 229, 247, 151, + 72, 1, 229, 25, 151, 72, 1, 174, 151, 72, 1, 216, 102, 151, 72, 1, 215, + 157, 151, 72, 1, 216, 234, 151, 72, 1, 216, 14, 151, 72, 1, 170, 151, 72, + 1, 191, 225, 151, 72, 1, 192, 12, 151, 72, 1, 165, 151, 72, 1, 207, 2, + 151, 72, 1, 206, 69, 151, 72, 1, 207, 115, 151, 72, 1, 206, 163, 151, 72, + 1, 193, 190, 151, 72, 1, 215, 63, 151, 72, 195, 20, 202, 6, 77, 151, 72, + 204, 31, 202, 6, 77, 151, 30, 233, 5, 151, 30, 1, 221, 115, 151, 30, 1, + 201, 168, 151, 30, 1, 221, 108, 151, 30, 1, 213, 206, 151, 30, 1, 213, + 204, 151, 30, 1, 213, 203, 151, 30, 1, 198, 168, 151, 30, 1, 201, 157, + 151, 30, 1, 206, 240, 151, 30, 1, 206, 235, 151, 30, 1, 206, 232, 151, + 30, 1, 206, 225, 151, 30, 1, 206, 220, 151, 30, 1, 206, 215, 151, 30, 1, + 206, 226, 151, 30, 1, 206, 238, 151, 30, 1, 216, 79, 151, 30, 1, 209, + 171, 151, 30, 1, 201, 165, 151, 30, 1, 209, 160, 151, 30, 1, 202, 161, + 151, 30, 1, 201, 162, 151, 30, 1, 223, 224, 151, 30, 1, 243, 26, 151, 30, + 1, 201, 172, 151, 30, 1, 243, 93, 151, 30, 1, 221, 190, 151, 30, 1, 199, + 7, 151, 30, 1, 209, 211, 151, 30, 1, 229, 144, 151, 30, 1, 65, 151, 30, + 1, 252, 27, 151, 30, 1, 170, 151, 30, 1, 192, 129, 151, 30, 1, 234, 67, + 151, 30, 1, 71, 151, 30, 1, 192, 67, 151, 30, 1, 192, 80, 151, 30, 1, 74, + 151, 30, 1, 193, 190, 151, 30, 1, 193, 176, 151, 30, 1, 211, 153, 151, + 30, 1, 192, 12, 151, 30, 1, 66, 151, 30, 1, 193, 107, 151, 30, 1, 193, + 125, 151, 30, 1, 193, 86, 151, 30, 1, 191, 225, 151, 30, 1, 233, 244, + 151, 30, 1, 192, 33, 151, 30, 1, 68, 232, 80, 247, 26, 56, 232, 80, 209, + 10, 56, 232, 80, 213, 14, 56, 232, 80, 217, 148, 232, 80, 248, 24, 164, + 232, 80, 192, 71, 56, 232, 80, 193, 31, 56, 151, 232, 143, 156, 195, 135, + 151, 118, 57, 151, 196, 66, 57, 151, 96, 57, 151, 235, 121, 57, 151, 62, + 201, 191, 151, 63, 243, 12, 223, 108, 251, 98, 251, 129, 223, 108, 251, + 98, 204, 11, 223, 108, 251, 98, 199, 80, 211, 177, 207, 44, 246, 241, + 207, 44, 246, 241, 32, 78, 5, 250, 106, 65, 32, 78, 5, 250, 75, 71, 32, + 78, 5, 250, 84, 68, 32, 78, 5, 250, 52, 74, 32, 78, 5, 250, 102, 66, 32, + 78, 5, 250, 121, 238, 34, 32, 78, 5, 250, 68, 237, 148, 32, 78, 5, 250, + 108, 237, 46, 32, 78, 5, 250, 98, 236, 176, 32, 78, 5, 250, 62, 235, 91, + 32, 78, 5, 250, 56, 223, 34, 32, 78, 5, 250, 67, 223, 12, 32, 78, 5, 250, + 77, 222, 203, 32, 78, 5, 250, 48, 222, 184, 32, 78, 5, 250, 36, 155, 32, + 78, 5, 250, 69, 222, 24, 32, 78, 5, 250, 46, 221, 168, 32, 78, 5, 250, + 43, 221, 69, 32, 78, 5, 250, 32, 220, 234, 32, 78, 5, 250, 33, 174, 32, + 78, 5, 250, 99, 216, 234, 32, 78, 5, 250, 40, 216, 102, 32, 78, 5, 250, + 97, 216, 14, 32, 78, 5, 250, 89, 215, 157, 32, 78, 5, 250, 110, 181, 32, + 78, 5, 250, 88, 214, 123, 32, 78, 5, 250, 82, 213, 221, 32, 78, 5, 250, + 61, 213, 45, 32, 78, 5, 250, 58, 212, 180, 32, 78, 5, 250, 117, 168, 32, + 78, 5, 250, 41, 210, 65, 32, 78, 5, 250, 74, 209, 187, 32, 78, 5, 250, + 101, 209, 75, 32, 78, 5, 250, 63, 208, 167, 32, 78, 5, 250, 96, 208, 98, + 32, 78, 5, 250, 35, 208, 77, 32, 78, 5, 250, 91, 208, 59, 32, 78, 5, 250, + 80, 208, 47, 32, 78, 5, 250, 53, 165, 32, 78, 5, 250, 85, 207, 115, 32, + 78, 5, 250, 60, 207, 2, 32, 78, 5, 250, 119, 206, 163, 32, 78, 5, 250, + 86, 206, 69, 32, 78, 5, 250, 81, 188, 32, 78, 5, 250, 104, 205, 69, 32, + 78, 5, 250, 72, 202, 223, 32, 78, 5, 250, 100, 202, 47, 32, 78, 5, 250, + 55, 201, 5, 32, 78, 5, 250, 54, 190, 190, 32, 78, 5, 250, 115, 199, 145, + 32, 78, 5, 250, 76, 198, 193, 32, 78, 5, 250, 113, 159, 32, 78, 5, 250, + 44, 197, 94, 32, 78, 5, 250, 59, 193, 190, 32, 78, 5, 250, 38, 193, 125, + 32, 78, 5, 250, 73, 193, 86, 32, 78, 5, 250, 71, 193, 48, 32, 78, 5, 250, + 95, 191, 123, 32, 78, 5, 250, 39, 191, 87, 32, 78, 5, 250, 92, 191, 7, + 32, 78, 5, 250, 87, 254, 217, 32, 78, 5, 250, 70, 254, 105, 32, 78, 5, + 250, 29, 250, 165, 32, 78, 5, 250, 42, 235, 47, 32, 78, 5, 250, 25, 235, + 46, 32, 78, 5, 250, 65, 212, 112, 32, 78, 5, 250, 83, 208, 165, 32, 78, + 5, 250, 51, 208, 169, 32, 78, 5, 250, 37, 207, 182, 32, 78, 5, 250, 79, + 207, 181, 32, 78, 5, 250, 45, 206, 156, 32, 78, 5, 250, 47, 199, 246, 32, + 78, 5, 250, 27, 197, 41, 32, 78, 5, 250, 24, 109, 32, 78, 16, 250, 94, + 32, 78, 16, 250, 93, 32, 78, 16, 250, 90, 32, 78, 16, 250, 78, 32, 78, + 16, 250, 66, 32, 78, 16, 250, 64, 32, 78, 16, 250, 57, 32, 78, 16, 250, + 50, 32, 78, 16, 250, 49, 32, 78, 16, 250, 34, 32, 78, 16, 250, 31, 32, + 78, 16, 250, 30, 32, 78, 16, 250, 28, 32, 78, 16, 250, 26, 32, 78, 157, + 250, 23, 217, 92, 32, 78, 157, 250, 22, 193, 35, 32, 78, 157, 250, 21, + 237, 130, 32, 78, 157, 250, 20, 234, 42, 32, 78, 157, 250, 19, 217, 58, + 32, 78, 157, 250, 18, 201, 111, 32, 78, 157, 250, 17, 233, 225, 32, 78, + 157, 250, 16, 207, 144, 32, 78, 157, 250, 15, 203, 113, 32, 78, 157, 250, + 14, 229, 239, 32, 78, 157, 250, 13, 202, 0, 32, 78, 157, 250, 12, 248, + 111, 32, 78, 157, 250, 11, 238, 241, 32, 78, 157, 250, 10, 247, 252, 32, + 78, 157, 250, 9, 193, 95, 32, 78, 157, 250, 8, 249, 86, 32, 78, 157, 250, + 7, 211, 117, 32, 78, 157, 250, 6, 201, 224, 32, 78, 157, 250, 5, 238, + 138, 32, 78, 215, 223, 250, 4, 222, 76, 32, 78, 215, 223, 250, 3, 222, + 87, 32, 78, 157, 250, 2, 211, 133, 32, 78, 157, 250, 1, 193, 62, 32, 78, + 157, 250, 0, 32, 78, 215, 223, 249, 255, 251, 9, 32, 78, 215, 223, 249, + 254, 216, 180, 32, 78, 157, 249, 253, 248, 23, 32, 78, 157, 249, 252, + 230, 252, 32, 78, 157, 249, 251, 32, 78, 157, 249, 250, 193, 26, 32, 78, + 157, 249, 249, 32, 78, 157, 249, 248, 32, 78, 157, 249, 247, 228, 189, + 32, 78, 157, 249, 246, 32, 78, 157, 249, 245, 32, 78, 157, 249, 244, 32, + 78, 215, 223, 249, 242, 197, 56, 32, 78, 157, 249, 241, 32, 78, 157, 249, + 240, 32, 78, 157, 249, 239, 242, 215, 32, 78, 157, 249, 238, 32, 78, 157, + 249, 237, 32, 78, 157, 249, 236, 231, 198, 32, 78, 157, 249, 235, 250, + 250, 32, 78, 157, 249, 234, 32, 78, 157, 249, 233, 32, 78, 157, 249, 232, + 32, 78, 157, 249, 231, 32, 78, 157, 249, 230, 32, 78, 157, 249, 229, 32, + 78, 157, 249, 228, 32, 78, 157, 249, 227, 32, 78, 157, 249, 226, 32, 78, + 157, 249, 225, 215, 215, 32, 78, 157, 249, 224, 32, 78, 157, 249, 223, + 197, 254, 32, 78, 157, 249, 222, 32, 78, 157, 249, 221, 32, 78, 157, 249, + 220, 32, 78, 157, 249, 219, 32, 78, 157, 249, 218, 32, 78, 157, 249, 217, + 32, 78, 157, 249, 216, 32, 78, 157, 249, 215, 32, 78, 157, 249, 214, 32, + 78, 157, 249, 213, 32, 78, 157, 249, 212, 32, 78, 157, 249, 211, 229, + 202, 32, 78, 157, 249, 190, 232, 157, 32, 78, 157, 249, 187, 249, 61, 32, + 78, 157, 249, 182, 201, 233, 32, 78, 157, 249, 181, 57, 32, 78, 157, 249, + 180, 32, 78, 157, 249, 179, 200, 131, 32, 78, 157, 249, 178, 32, 78, 157, + 249, 177, 32, 78, 157, 249, 176, 193, 90, 243, 140, 32, 78, 157, 249, + 175, 243, 140, 32, 78, 157, 249, 174, 243, 141, 232, 115, 32, 78, 157, + 249, 173, 193, 93, 32, 78, 157, 249, 172, 32, 78, 157, 249, 171, 32, 78, + 215, 223, 249, 170, 236, 237, 32, 78, 157, 249, 169, 32, 78, 157, 249, + 168, 32, 78, 157, 249, 166, 32, 78, 157, 249, 165, 32, 78, 157, 249, 164, + 32, 78, 157, 249, 163, 237, 220, 32, 78, 157, 249, 162, 32, 78, 157, 249, + 161, 32, 78, 157, 249, 160, 32, 78, 157, 249, 159, 32, 78, 157, 249, 158, + 32, 78, 157, 195, 82, 249, 243, 32, 78, 157, 195, 82, 249, 210, 32, 78, + 157, 195, 82, 249, 209, 32, 78, 157, 195, 82, 249, 208, 32, 78, 157, 195, + 82, 249, 207, 32, 78, 157, 195, 82, 249, 206, 32, 78, 157, 195, 82, 249, + 205, 32, 78, 157, 195, 82, 249, 204, 32, 78, 157, 195, 82, 249, 203, 32, + 78, 157, 195, 82, 249, 202, 32, 78, 157, 195, 82, 249, 201, 32, 78, 157, + 195, 82, 249, 200, 32, 78, 157, 195, 82, 249, 199, 32, 78, 157, 195, 82, + 249, 198, 32, 78, 157, 195, 82, 249, 197, 32, 78, 157, 195, 82, 249, 196, + 32, 78, 157, 195, 82, 249, 195, 32, 78, 157, 195, 82, 249, 194, 32, 78, + 157, 195, 82, 249, 193, 32, 78, 157, 195, 82, 249, 192, 32, 78, 157, 195, + 82, 249, 191, 32, 78, 157, 195, 82, 249, 189, 32, 78, 157, 195, 82, 249, + 188, 32, 78, 157, 195, 82, 249, 186, 32, 78, 157, 195, 82, 249, 185, 32, + 78, 157, 195, 82, 249, 184, 32, 78, 157, 195, 82, 249, 183, 32, 78, 157, + 195, 82, 249, 167, 32, 78, 157, 195, 82, 249, 157, 252, 20, 193, 23, 204, + 12, 219, 114, 252, 20, 193, 23, 204, 12, 236, 142, 252, 20, 243, 128, 77, + 252, 20, 31, 107, 252, 20, 31, 109, 252, 20, 31, 138, 252, 20, 31, 134, + 252, 20, 31, 150, 252, 20, 31, 169, 252, 20, 31, 175, 252, 20, 31, 171, + 252, 20, 31, 178, 252, 20, 31, 199, 95, 252, 20, 31, 197, 32, 252, 20, + 31, 198, 249, 252, 20, 31, 232, 137, 252, 20, 31, 233, 17, 252, 20, 31, + 202, 121, 252, 20, 31, 203, 242, 252, 20, 31, 234, 155, 252, 20, 31, 213, + 171, 252, 20, 31, 91, 228, 142, 252, 20, 31, 105, 228, 142, 252, 20, 31, + 115, 228, 142, 252, 20, 31, 232, 130, 228, 142, 252, 20, 31, 232, 228, + 228, 142, 252, 20, 31, 202, 137, 228, 142, 252, 20, 31, 203, 248, 228, + 142, 252, 20, 31, 234, 166, 228, 142, 252, 20, 31, 213, 177, 228, 142, + 252, 20, 31, 91, 189, 252, 20, 31, 105, 189, 252, 20, 31, 115, 189, 252, + 20, 31, 232, 130, 189, 252, 20, 31, 232, 228, 189, 252, 20, 31, 202, 137, + 189, 252, 20, 31, 203, 248, 189, 252, 20, 31, 234, 166, 189, 252, 20, 31, + 213, 177, 189, 252, 20, 31, 199, 96, 189, 252, 20, 31, 197, 33, 189, 252, + 20, 31, 198, 250, 189, 252, 20, 31, 232, 138, 189, 252, 20, 31, 233, 18, + 189, 252, 20, 31, 202, 122, 189, 252, 20, 31, 203, 243, 189, 252, 20, 31, + 234, 156, 189, 252, 20, 31, 213, 172, 189, 252, 20, 193, 110, 249, 77, + 196, 90, 252, 20, 193, 110, 232, 240, 200, 224, 252, 20, 193, 110, 205, + 58, 200, 224, 252, 20, 193, 110, 199, 1, 200, 224, 252, 20, 193, 110, + 232, 123, 200, 224, 252, 20, 235, 94, 216, 230, 232, 240, 200, 224, 252, + 20, 219, 95, 216, 230, 232, 240, 200, 224, 252, 20, 216, 230, 205, 58, + 200, 224, 252, 20, 216, 230, 199, 1, 200, 224, 35, 252, 52, 250, 167, 91, + 208, 24, 35, 252, 52, 250, 167, 91, 230, 72, 35, 252, 52, 250, 167, 91, + 235, 117, 35, 252, 52, 250, 167, 150, 35, 252, 52, 250, 167, 233, 17, 35, + 252, 52, 250, 167, 232, 228, 228, 142, 35, 252, 52, 250, 167, 232, 228, + 189, 35, 252, 52, 250, 167, 233, 18, 189, 35, 252, 52, 250, 167, 232, + 228, 199, 203, 35, 252, 52, 250, 167, 199, 96, 199, 203, 35, 252, 52, + 250, 167, 233, 18, 199, 203, 35, 252, 52, 250, 167, 91, 228, 143, 199, + 203, 35, 252, 52, 250, 167, 232, 228, 228, 143, 199, 203, 35, 252, 52, + 250, 167, 91, 198, 230, 199, 203, 35, 252, 52, 250, 167, 232, 228, 198, + 230, 199, 203, 35, 252, 52, 250, 167, 232, 228, 201, 95, 35, 252, 52, + 250, 167, 199, 96, 201, 95, 35, 252, 52, 250, 167, 233, 18, 201, 95, 35, + 252, 52, 250, 167, 91, 228, 143, 201, 95, 35, 252, 52, 250, 167, 232, + 228, 228, 143, 201, 95, 35, 252, 52, 250, 167, 91, 198, 230, 201, 95, 35, + 252, 52, 250, 167, 199, 96, 198, 230, 201, 95, 35, 252, 52, 250, 167, + 233, 18, 198, 230, 201, 95, 35, 252, 52, 250, 167, 199, 96, 216, 17, 35, + 252, 52, 229, 196, 91, 209, 94, 35, 252, 52, 199, 17, 107, 35, 252, 52, + 229, 192, 107, 35, 252, 52, 234, 53, 109, 35, 252, 52, 199, 17, 109, 35, + 252, 52, 238, 134, 105, 235, 116, 35, 252, 52, 234, 53, 105, 235, 116, + 35, 252, 52, 197, 216, 150, 35, 252, 52, 197, 216, 199, 95, 35, 252, 52, + 197, 216, 199, 96, 251, 159, 20, 35, 252, 52, 229, 192, 199, 95, 35, 252, + 52, 216, 169, 199, 95, 35, 252, 52, 199, 17, 199, 95, 35, 252, 52, 199, + 17, 198, 249, 35, 252, 52, 197, 216, 233, 17, 35, 252, 52, 197, 216, 233, + 18, 251, 159, 20, 35, 252, 52, 229, 192, 233, 17, 35, 252, 52, 199, 17, + 233, 17, 35, 252, 52, 199, 17, 91, 228, 142, 35, 252, 52, 199, 17, 115, + 228, 142, 35, 252, 52, 234, 53, 232, 228, 228, 142, 35, 252, 52, 197, + 216, 232, 228, 228, 142, 35, 252, 52, 199, 17, 232, 228, 228, 142, 35, + 252, 52, 247, 84, 232, 228, 228, 142, 35, 252, 52, 214, 201, 232, 228, + 228, 142, 35, 252, 52, 199, 17, 91, 189, 35, 252, 52, 199, 17, 232, 228, + 189, 35, 252, 52, 237, 111, 232, 228, 216, 17, 35, 252, 52, 201, 48, 233, + 18, 216, 17, 35, 91, 132, 56, 35, 91, 132, 3, 251, 159, 20, 35, 105, 198, + 254, 56, 35, 115, 208, 23, 56, 35, 192, 78, 56, 35, 199, 204, 56, 35, + 235, 118, 56, 35, 211, 172, 56, 35, 105, 211, 171, 56, 35, 115, 211, 171, + 56, 35, 232, 130, 211, 171, 56, 35, 232, 228, 211, 171, 56, 35, 216, 163, + 56, 35, 220, 153, 249, 77, 56, 35, 219, 87, 56, 35, 211, 18, 56, 35, 192, + 211, 56, 35, 250, 228, 56, 35, 250, 245, 56, 35, 230, 222, 56, 35, 197, + 171, 249, 77, 56, 35, 191, 78, 56, 35, 91, 208, 25, 56, 35, 202, 163, 56, + 35, 223, 145, 56, 213, 34, 56, 206, 137, 203, 238, 56, 206, 137, 196, + 106, 56, 206, 137, 204, 18, 56, 206, 137, 203, 176, 56, 206, 137, 236, + 252, 203, 176, 56, 206, 137, 202, 187, 56, 206, 137, 237, 106, 56, 206, + 137, 208, 7, 56, 206, 137, 203, 255, 56, 206, 137, 235, 69, 56, 206, 137, + 250, 222, 56, 206, 137, 247, 19, 56, 250, 213, 113, 35, 16, 199, 167, + 207, 4, 209, 225, 236, 229, 3, 210, 53, 209, 225, 236, 229, 3, 209, 86, + 229, 237, 209, 225, 236, 229, 3, 199, 170, 229, 237, 209, 225, 236, 229, + 3, 247, 107, 209, 225, 236, 229, 3, 243, 88, 209, 225, 236, 229, 3, 193, + 35, 209, 225, 236, 229, 3, 229, 202, 209, 225, 236, 229, 3, 231, 190, + 209, 225, 236, 229, 3, 198, 184, 209, 225, 236, 229, 3, 57, 209, 225, + 236, 229, 3, 248, 71, 209, 225, 236, 229, 3, 203, 79, 209, 225, 236, 229, + 3, 242, 208, 209, 225, 236, 229, 3, 217, 91, 209, 225, 236, 229, 3, 217, + 28, 209, 225, 236, 229, 3, 205, 109, 209, 225, 236, 229, 3, 219, 143, + 209, 225, 236, 229, 3, 248, 94, 209, 225, 236, 229, 3, 247, 91, 209, 103, + 209, 225, 236, 229, 3, 236, 158, 209, 225, 236, 229, 3, 242, 82, 209, + 225, 236, 229, 3, 202, 84, 209, 225, 236, 229, 3, 242, 83, 209, 225, 236, + 229, 3, 249, 0, 209, 225, 236, 229, 3, 203, 66, 209, 225, 236, 229, 3, + 228, 189, 209, 225, 236, 229, 3, 229, 150, 209, 225, 236, 229, 3, 247, + 247, 219, 214, 209, 225, 236, 229, 3, 247, 80, 209, 225, 236, 229, 3, + 207, 144, 209, 225, 236, 229, 3, 234, 216, 209, 225, 236, 229, 3, 235, + 126, 209, 225, 236, 229, 3, 197, 72, 209, 225, 236, 229, 3, 249, 3, 209, + 225, 236, 229, 3, 209, 104, 197, 254, 209, 225, 236, 229, 3, 195, 47, + 209, 225, 236, 229, 3, 210, 134, 209, 225, 236, 229, 3, 206, 126, 209, + 225, 236, 229, 3, 219, 127, 209, 225, 236, 229, 3, 210, 250, 249, 148, + 209, 225, 236, 229, 3, 232, 184, 209, 225, 236, 229, 3, 230, 214, 209, + 225, 236, 229, 3, 201, 51, 209, 225, 236, 229, 3, 2, 250, 134, 209, 225, + 236, 229, 3, 193, 135, 249, 99, 209, 225, 236, 229, 3, 33, 211, 174, 106, + 218, 183, 1, 65, 218, 183, 1, 71, 218, 183, 1, 250, 122, 218, 183, 1, + 248, 206, 218, 183, 1, 232, 53, 218, 183, 1, 238, 129, 218, 183, 1, 68, + 218, 183, 1, 193, 224, 218, 183, 1, 191, 166, 218, 183, 1, 199, 51, 218, + 183, 1, 223, 37, 218, 183, 1, 222, 154, 218, 183, 1, 208, 106, 218, 183, + 1, 172, 218, 183, 1, 218, 170, 218, 183, 1, 215, 63, 218, 183, 1, 216, + 19, 218, 183, 1, 213, 82, 218, 183, 1, 66, 218, 183, 1, 210, 238, 218, + 183, 1, 221, 104, 218, 183, 1, 146, 218, 183, 1, 206, 9, 218, 183, 1, + 200, 43, 218, 183, 1, 197, 135, 218, 183, 1, 251, 134, 218, 183, 1, 234, + 105, 218, 183, 1, 230, 118, 218, 183, 1, 192, 235, 247, 97, 1, 65, 247, + 97, 1, 210, 224, 247, 97, 1, 238, 129, 247, 97, 1, 172, 247, 97, 1, 196, + 28, 247, 97, 1, 146, 247, 97, 1, 219, 244, 247, 97, 1, 254, 217, 247, 97, + 1, 208, 106, 247, 97, 1, 250, 122, 247, 97, 1, 218, 170, 247, 97, 1, 74, + 247, 97, 1, 238, 36, 247, 97, 1, 200, 43, 247, 97, 1, 203, 168, 247, 97, + 1, 203, 167, 247, 97, 1, 206, 9, 247, 97, 1, 247, 194, 247, 97, 1, 66, + 247, 97, 1, 213, 82, 247, 97, 1, 192, 235, 247, 97, 1, 215, 63, 247, 97, + 1, 197, 134, 247, 97, 1, 210, 238, 247, 97, 1, 201, 179, 247, 97, 1, 68, + 247, 97, 1, 71, 247, 97, 1, 196, 25, 247, 97, 1, 222, 154, 247, 97, 1, + 222, 145, 247, 97, 1, 214, 166, 247, 97, 1, 196, 30, 247, 97, 1, 232, 53, + 247, 97, 1, 231, 244, 247, 97, 1, 201, 119, 247, 97, 1, 201, 118, 247, + 97, 1, 214, 72, 247, 97, 1, 223, 201, 247, 97, 1, 247, 193, 247, 97, 1, + 197, 135, 247, 97, 1, 196, 27, 247, 97, 1, 206, 111, 247, 97, 1, 217, 18, + 247, 97, 1, 217, 17, 247, 97, 1, 217, 16, 247, 97, 1, 217, 15, 247, 97, + 1, 219, 243, 247, 97, 1, 234, 220, 247, 97, 1, 196, 26, 94, 234, 56, 198, + 229, 77, 94, 234, 56, 17, 107, 94, 234, 56, 17, 109, 94, 234, 56, 17, + 138, 94, 234, 56, 17, 134, 94, 234, 56, 17, 150, 94, 234, 56, 17, 169, + 94, 234, 56, 17, 175, 94, 234, 56, 17, 171, 94, 234, 56, 17, 178, 94, + 234, 56, 31, 199, 95, 94, 234, 56, 31, 197, 32, 94, 234, 56, 31, 198, + 249, 94, 234, 56, 31, 232, 137, 94, 234, 56, 31, 233, 17, 94, 234, 56, + 31, 202, 121, 94, 234, 56, 31, 203, 242, 94, 234, 56, 31, 234, 155, 94, + 234, 56, 31, 213, 171, 94, 234, 56, 31, 91, 228, 142, 94, 234, 56, 31, + 105, 228, 142, 94, 234, 56, 31, 115, 228, 142, 94, 234, 56, 31, 232, 130, + 228, 142, 94, 234, 56, 31, 232, 228, 228, 142, 94, 234, 56, 31, 202, 137, + 228, 142, 94, 234, 56, 31, 203, 248, 228, 142, 94, 234, 56, 31, 234, 166, + 228, 142, 94, 234, 56, 31, 213, 177, 228, 142, 39, 43, 1, 65, 39, 43, 1, + 249, 19, 39, 43, 1, 222, 24, 39, 43, 1, 237, 148, 39, 43, 1, 71, 39, 43, + 1, 195, 153, 39, 43, 1, 191, 87, 39, 43, 1, 229, 247, 39, 43, 1, 199, 33, + 39, 43, 1, 68, 39, 43, 1, 155, 39, 43, 1, 234, 142, 39, 43, 1, 234, 116, + 39, 43, 1, 234, 105, 39, 43, 1, 234, 14, 39, 43, 1, 74, 39, 43, 1, 210, + 65, 39, 43, 1, 203, 114, 39, 43, 1, 220, 234, 39, 43, 1, 234, 36, 39, 43, + 1, 234, 24, 39, 43, 1, 199, 145, 39, 43, 1, 66, 39, 43, 1, 234, 145, 39, + 43, 1, 209, 216, 39, 43, 1, 221, 199, 39, 43, 1, 234, 183, 39, 43, 1, + 234, 26, 39, 43, 1, 243, 129, 39, 43, 1, 223, 201, 39, 43, 1, 196, 30, + 39, 43, 1, 234, 7, 39, 43, 212, 136, 107, 39, 43, 212, 136, 150, 39, 43, + 212, 136, 199, 95, 39, 43, 212, 136, 233, 17, 39, 43, 1, 192, 80, 39, 43, + 1, 213, 18, 197, 161, 39, 43, 1, 202, 1, 197, 161, 230, 233, 1, 251, 241, + 230, 233, 1, 249, 119, 230, 233, 1, 231, 52, 230, 233, 1, 238, 15, 230, + 233, 1, 251, 236, 230, 233, 1, 208, 89, 230, 233, 1, 223, 50, 230, 233, + 1, 230, 85, 230, 233, 1, 198, 243, 230, 233, 1, 234, 153, 230, 233, 1, + 220, 191, 230, 233, 1, 220, 102, 230, 233, 1, 217, 82, 230, 233, 1, 214, + 203, 230, 233, 1, 223, 3, 230, 233, 1, 196, 48, 230, 233, 1, 210, 197, + 230, 233, 1, 213, 171, 230, 233, 1, 207, 157, 230, 233, 1, 205, 113, 230, + 233, 1, 199, 111, 230, 233, 1, 193, 59, 230, 233, 1, 233, 91, 230, 233, + 1, 223, 205, 230, 233, 1, 228, 125, 230, 233, 1, 211, 31, 230, 233, 1, + 213, 177, 228, 142, 39, 210, 4, 1, 251, 134, 39, 210, 4, 1, 247, 232, 39, + 210, 4, 1, 231, 226, 39, 210, 4, 1, 236, 162, 39, 210, 4, 1, 71, 39, 210, + 4, 1, 191, 53, 39, 210, 4, 1, 235, 29, 39, 210, 4, 1, 191, 95, 39, 210, + 4, 1, 235, 27, 39, 210, 4, 1, 68, 39, 210, 4, 1, 221, 52, 39, 210, 4, 1, + 219, 210, 39, 210, 4, 1, 216, 186, 39, 210, 4, 1, 214, 102, 39, 210, 4, + 1, 195, 7, 39, 210, 4, 1, 210, 50, 39, 210, 4, 1, 207, 71, 39, 210, 4, 1, + 202, 194, 39, 210, 4, 1, 199, 217, 39, 210, 4, 1, 66, 39, 210, 4, 1, 243, + 108, 39, 210, 4, 1, 203, 48, 39, 210, 4, 1, 203, 116, 39, 210, 4, 1, 191, + 227, 39, 210, 4, 1, 192, 58, 39, 210, 4, 1, 74, 39, 210, 4, 1, 211, 89, + 39, 210, 4, 1, 234, 183, 39, 210, 4, 1, 140, 39, 210, 4, 1, 197, 145, 39, + 210, 4, 1, 195, 140, 39, 210, 4, 1, 192, 62, 39, 210, 4, 1, 192, 60, 39, + 210, 4, 1, 192, 95, 39, 210, 4, 1, 223, 228, 39, 210, 4, 1, 191, 225, 39, + 210, 4, 1, 170, 39, 210, 4, 1, 228, 37, 33, 39, 210, 4, 1, 251, 134, 33, + 39, 210, 4, 1, 236, 162, 33, 39, 210, 4, 1, 191, 95, 33, 39, 210, 4, 1, + 214, 102, 33, 39, 210, 4, 1, 202, 194, 196, 142, 1, 251, 166, 196, 142, + 1, 248, 214, 196, 142, 1, 231, 214, 196, 142, 1, 221, 217, 196, 142, 1, + 237, 108, 196, 142, 1, 229, 25, 196, 142, 1, 193, 48, 196, 142, 1, 191, + 76, 196, 142, 1, 228, 181, 196, 142, 1, 199, 73, 196, 142, 1, 191, 250, + 196, 142, 1, 222, 108, 196, 142, 1, 203, 70, 196, 142, 1, 220, 33, 196, + 142, 1, 216, 195, 196, 142, 1, 237, 66, 196, 142, 1, 212, 132, 196, 142, + 1, 190, 251, 196, 142, 1, 205, 148, 196, 142, 1, 251, 232, 196, 142, 1, + 208, 167, 196, 142, 1, 205, 192, 196, 142, 1, 208, 40, 196, 142, 1, 207, + 135, 196, 142, 1, 199, 37, 196, 142, 1, 231, 88, 196, 142, 1, 159, 196, + 142, 1, 68, 196, 142, 1, 66, 196, 142, 1, 201, 130, 196, 142, 193, 23, + 236, 207, 39, 209, 254, 3, 65, 39, 209, 254, 3, 68, 39, 209, 254, 3, 66, + 39, 209, 254, 3, 155, 39, 209, 254, 3, 220, 234, 39, 209, 254, 3, 231, + 242, 39, 209, 254, 3, 230, 181, 39, 209, 254, 3, 192, 220, 39, 209, 254, + 3, 247, 162, 39, 209, 254, 3, 223, 34, 39, 209, 254, 3, 222, 246, 39, + 209, 254, 3, 190, 190, 39, 209, 254, 3, 197, 94, 39, 209, 254, 3, 238, + 34, 39, 209, 254, 3, 237, 46, 39, 209, 254, 3, 235, 91, 39, 209, 254, 3, + 199, 49, 39, 209, 254, 3, 168, 39, 209, 254, 3, 249, 155, 39, 209, 254, + 3, 233, 111, 39, 209, 254, 3, 181, 39, 209, 254, 3, 212, 180, 39, 209, + 254, 3, 174, 39, 209, 254, 3, 216, 102, 39, 209, 254, 3, 215, 157, 39, + 209, 254, 3, 170, 39, 209, 254, 3, 195, 188, 39, 209, 254, 3, 195, 69, + 39, 209, 254, 3, 165, 39, 209, 254, 3, 206, 69, 39, 209, 254, 3, 173, 39, + 209, 254, 3, 188, 39, 209, 254, 3, 191, 123, 39, 209, 254, 3, 203, 166, + 39, 209, 254, 3, 201, 176, 39, 209, 254, 3, 140, 39, 209, 254, 3, 250, + 159, 39, 209, 254, 3, 250, 158, 39, 209, 254, 3, 250, 157, 39, 209, 254, + 3, 192, 189, 39, 209, 254, 3, 238, 11, 39, 209, 254, 3, 238, 10, 39, 209, + 254, 3, 249, 130, 39, 209, 254, 3, 247, 214, 39, 209, 254, 193, 23, 236, + 207, 39, 209, 254, 31, 107, 39, 209, 254, 31, 109, 39, 209, 254, 31, 199, + 95, 39, 209, 254, 31, 197, 32, 39, 209, 254, 31, 228, 142, 237, 86, 6, 1, + 180, 68, 237, 86, 6, 1, 180, 71, 237, 86, 6, 1, 180, 65, 237, 86, 6, 1, + 180, 251, 247, 237, 86, 6, 1, 180, 74, 237, 86, 6, 1, 180, 211, 89, 237, + 86, 6, 1, 203, 41, 68, 237, 86, 6, 1, 203, 41, 71, 237, 86, 6, 1, 203, + 41, 65, 237, 86, 6, 1, 203, 41, 251, 247, 237, 86, 6, 1, 203, 41, 74, + 237, 86, 6, 1, 203, 41, 211, 89, 237, 86, 6, 1, 250, 133, 237, 86, 6, 1, + 210, 252, 237, 86, 6, 1, 193, 0, 237, 86, 6, 1, 192, 77, 237, 86, 6, 1, + 230, 118, 237, 86, 6, 1, 210, 51, 237, 86, 6, 1, 249, 3, 237, 86, 6, 1, + 199, 121, 237, 86, 6, 1, 237, 133, 237, 86, 6, 1, 243, 125, 237, 86, 6, + 1, 223, 10, 237, 86, 6, 1, 222, 31, 237, 86, 6, 1, 231, 188, 237, 86, 6, + 1, 234, 183, 237, 86, 6, 1, 195, 148, 237, 86, 6, 1, 233, 250, 237, 86, + 6, 1, 199, 31, 237, 86, 6, 1, 234, 24, 237, 86, 6, 1, 191, 84, 237, 86, + 6, 1, 234, 14, 237, 86, 6, 1, 191, 61, 237, 86, 6, 1, 234, 36, 237, 86, + 6, 1, 234, 142, 237, 86, 6, 1, 234, 116, 237, 86, 6, 1, 234, 105, 237, + 86, 6, 1, 234, 90, 237, 86, 6, 1, 211, 135, 237, 86, 6, 1, 233, 226, 237, + 86, 2, 1, 180, 68, 237, 86, 2, 1, 180, 71, 237, 86, 2, 1, 180, 65, 237, + 86, 2, 1, 180, 251, 247, 237, 86, 2, 1, 180, 74, 237, 86, 2, 1, 180, 211, + 89, 237, 86, 2, 1, 203, 41, 68, 237, 86, 2, 1, 203, 41, 71, 237, 86, 2, + 1, 203, 41, 65, 237, 86, 2, 1, 203, 41, 251, 247, 237, 86, 2, 1, 203, 41, + 74, 237, 86, 2, 1, 203, 41, 211, 89, 237, 86, 2, 1, 250, 133, 237, 86, 2, + 1, 210, 252, 237, 86, 2, 1, 193, 0, 237, 86, 2, 1, 192, 77, 237, 86, 2, + 1, 230, 118, 237, 86, 2, 1, 210, 51, 237, 86, 2, 1, 249, 3, 237, 86, 2, + 1, 199, 121, 237, 86, 2, 1, 237, 133, 237, 86, 2, 1, 243, 125, 237, 86, + 2, 1, 223, 10, 237, 86, 2, 1, 222, 31, 237, 86, 2, 1, 231, 188, 237, 86, + 2, 1, 234, 183, 237, 86, 2, 1, 195, 148, 237, 86, 2, 1, 233, 250, 237, + 86, 2, 1, 199, 31, 237, 86, 2, 1, 234, 24, 237, 86, 2, 1, 191, 84, 237, + 86, 2, 1, 234, 14, 237, 86, 2, 1, 191, 61, 237, 86, 2, 1, 234, 36, 237, + 86, 2, 1, 234, 142, 237, 86, 2, 1, 234, 116, 237, 86, 2, 1, 234, 105, + 237, 86, 2, 1, 234, 90, 237, 86, 2, 1, 211, 135, 237, 86, 2, 1, 233, 226, + 203, 121, 1, 210, 47, 203, 121, 1, 198, 40, 203, 121, 1, 221, 156, 203, + 121, 1, 233, 54, 203, 121, 1, 199, 6, 203, 121, 1, 202, 47, 203, 121, 1, + 200, 172, 203, 121, 1, 243, 42, 203, 121, 1, 192, 79, 203, 121, 1, 228, + 139, 203, 121, 1, 248, 189, 203, 121, 1, 237, 147, 203, 121, 1, 231, 228, + 203, 121, 1, 195, 2, 203, 121, 1, 199, 12, 203, 121, 1, 191, 4, 203, 121, + 1, 216, 229, 203, 121, 1, 222, 182, 203, 121, 1, 193, 39, 203, 121, 1, + 230, 95, 203, 121, 1, 219, 27, 203, 121, 1, 216, 47, 203, 121, 1, 223, + 208, 203, 121, 1, 234, 181, 203, 121, 1, 250, 211, 203, 121, 1, 252, 32, + 203, 121, 1, 211, 106, 203, 121, 1, 193, 26, 203, 121, 1, 211, 16, 203, + 121, 1, 251, 247, 203, 121, 1, 206, 154, 203, 121, 1, 212, 132, 203, 121, + 1, 234, 202, 203, 121, 1, 251, 252, 203, 121, 1, 228, 28, 203, 121, 1, + 196, 77, 203, 121, 1, 211, 182, 203, 121, 1, 211, 81, 203, 121, 1, 211, + 133, 203, 121, 1, 250, 139, 203, 121, 1, 251, 11, 203, 121, 1, 211, 58, + 203, 121, 1, 251, 227, 203, 121, 1, 234, 28, 203, 121, 1, 250, 242, 203, + 121, 1, 234, 213, 203, 121, 1, 228, 36, 203, 121, 1, 192, 41, 211, 35, 1, + 251, 194, 211, 35, 1, 249, 155, 211, 35, 1, 190, 190, 211, 35, 1, 223, + 34, 211, 35, 1, 192, 220, 211, 35, 1, 221, 217, 211, 35, 1, 237, 132, + 211, 35, 1, 165, 211, 35, 1, 188, 211, 35, 1, 203, 76, 211, 35, 1, 237, + 70, 211, 35, 1, 247, 69, 211, 35, 1, 231, 242, 211, 35, 1, 233, 111, 211, + 35, 1, 208, 96, 211, 35, 1, 222, 125, 211, 35, 1, 220, 123, 211, 35, 1, + 216, 61, 211, 35, 1, 212, 116, 211, 35, 1, 193, 133, 211, 35, 1, 140, + 211, 35, 1, 170, 211, 35, 1, 65, 211, 35, 1, 71, 211, 35, 1, 68, 211, 35, + 1, 74, 211, 35, 1, 66, 211, 35, 1, 252, 208, 211, 35, 1, 234, 190, 211, + 35, 1, 211, 89, 211, 35, 17, 191, 77, 211, 35, 17, 107, 211, 35, 17, 109, + 211, 35, 17, 138, 211, 35, 17, 134, 211, 35, 17, 150, 211, 35, 17, 169, + 211, 35, 17, 175, 211, 35, 17, 171, 211, 35, 17, 178, 211, 37, 6, 1, 65, + 211, 37, 6, 1, 251, 238, 211, 37, 6, 1, 251, 232, 211, 37, 6, 1, 251, + 247, 211, 37, 6, 1, 248, 58, 211, 37, 6, 1, 247, 3, 211, 37, 6, 1, 234, + 174, 211, 37, 6, 1, 71, 211, 37, 6, 1, 234, 154, 211, 37, 6, 1, 140, 211, + 37, 6, 1, 228, 95, 211, 37, 6, 1, 68, 211, 37, 6, 1, 155, 211, 37, 6, 1, + 234, 173, 211, 37, 6, 1, 220, 155, 211, 37, 6, 1, 173, 211, 37, 6, 1, + 174, 211, 37, 6, 1, 181, 211, 37, 6, 1, 74, 211, 37, 6, 1, 211, 132, 211, + 37, 6, 1, 168, 211, 37, 6, 1, 234, 172, 211, 37, 6, 1, 188, 211, 37, 6, + 1, 203, 166, 211, 37, 6, 1, 190, 190, 211, 37, 6, 1, 234, 171, 211, 37, + 6, 1, 197, 168, 211, 37, 6, 1, 234, 170, 211, 37, 6, 1, 197, 157, 211, + 37, 6, 1, 237, 70, 211, 37, 6, 1, 66, 211, 37, 6, 1, 193, 190, 211, 37, + 6, 1, 221, 217, 211, 37, 6, 1, 231, 93, 211, 37, 6, 1, 191, 123, 211, 37, + 6, 1, 191, 71, 211, 37, 2, 1, 65, 211, 37, 2, 1, 251, 238, 211, 37, 2, 1, + 251, 232, 211, 37, 2, 1, 251, 247, 211, 37, 2, 1, 248, 58, 211, 37, 2, 1, + 247, 3, 211, 37, 2, 1, 234, 174, 211, 37, 2, 1, 71, 211, 37, 2, 1, 234, + 154, 211, 37, 2, 1, 140, 211, 37, 2, 1, 228, 95, 211, 37, 2, 1, 68, 211, + 37, 2, 1, 155, 211, 37, 2, 1, 234, 173, 211, 37, 2, 1, 220, 155, 211, 37, + 2, 1, 173, 211, 37, 2, 1, 174, 211, 37, 2, 1, 181, 211, 37, 2, 1, 74, + 211, 37, 2, 1, 211, 132, 211, 37, 2, 1, 168, 211, 37, 2, 1, 234, 172, + 211, 37, 2, 1, 188, 211, 37, 2, 1, 203, 166, 211, 37, 2, 1, 190, 190, + 211, 37, 2, 1, 234, 171, 211, 37, 2, 1, 197, 168, 211, 37, 2, 1, 234, + 170, 211, 37, 2, 1, 197, 157, 211, 37, 2, 1, 237, 70, 211, 37, 2, 1, 66, + 211, 37, 2, 1, 193, 190, 211, 37, 2, 1, 221, 217, 211, 37, 2, 1, 231, 93, + 211, 37, 2, 1, 191, 123, 211, 37, 2, 1, 191, 71, 234, 138, 1, 65, 234, + 138, 1, 249, 19, 234, 138, 1, 247, 44, 234, 138, 1, 243, 129, 234, 138, + 1, 237, 148, 234, 138, 1, 214, 156, 234, 138, 1, 237, 61, 234, 138, 1, + 234, 168, 234, 138, 1, 71, 234, 138, 1, 233, 61, 234, 138, 1, 231, 167, + 234, 138, 1, 231, 22, 234, 138, 1, 229, 247, 234, 138, 1, 68, 234, 138, + 1, 223, 12, 234, 138, 1, 222, 24, 234, 138, 1, 219, 240, 234, 138, 1, + 219, 70, 234, 138, 1, 216, 234, 234, 138, 1, 214, 123, 234, 138, 1, 181, + 234, 138, 1, 213, 152, 234, 138, 1, 74, 234, 138, 1, 210, 65, 234, 138, + 1, 208, 77, 234, 138, 1, 207, 115, 234, 138, 1, 206, 105, 234, 138, 1, + 205, 69, 234, 138, 1, 203, 114, 234, 138, 1, 199, 145, 234, 138, 1, 199, + 33, 234, 138, 1, 66, 234, 138, 1, 195, 153, 234, 138, 1, 192, 214, 234, + 138, 1, 192, 159, 234, 138, 1, 191, 87, 234, 138, 1, 191, 62, 234, 138, + 1, 231, 79, 234, 138, 1, 231, 85, 234, 138, 1, 221, 199, 247, 77, 251, + 195, 1, 251, 161, 247, 77, 251, 195, 1, 248, 216, 247, 77, 251, 195, 1, + 231, 42, 247, 77, 251, 195, 1, 237, 213, 247, 77, 251, 195, 1, 234, 201, + 247, 77, 251, 195, 1, 191, 98, 247, 77, 251, 195, 1, 233, 186, 247, 77, + 251, 195, 1, 191, 56, 247, 77, 251, 195, 1, 199, 174, 247, 77, 251, 195, + 1, 247, 3, 247, 77, 251, 195, 1, 191, 236, 247, 77, 251, 195, 1, 191, 71, + 247, 77, 251, 195, 1, 223, 78, 247, 77, 251, 195, 1, 203, 166, 247, 77, + 251, 195, 1, 220, 26, 247, 77, 251, 195, 1, 223, 91, 247, 77, 251, 195, + 1, 192, 210, 247, 77, 251, 195, 1, 235, 45, 247, 77, 251, 195, 1, 247, + 104, 247, 77, 251, 195, 1, 222, 247, 247, 77, 251, 195, 1, 222, 67, 247, + 77, 251, 195, 1, 218, 179, 247, 77, 251, 195, 1, 229, 181, 247, 77, 251, + 195, 1, 208, 78, 247, 77, 251, 195, 1, 251, 69, 247, 77, 251, 195, 1, + 243, 59, 247, 77, 251, 195, 1, 243, 97, 247, 77, 251, 195, 1, 238, 142, + 247, 77, 251, 195, 1, 217, 70, 247, 77, 251, 195, 1, 208, 83, 247, 77, + 251, 195, 1, 212, 254, 247, 77, 251, 195, 1, 235, 22, 247, 77, 251, 195, + 1, 203, 148, 247, 77, 251, 195, 1, 223, 13, 247, 77, 251, 195, 1, 211, + 106, 247, 77, 251, 195, 1, 197, 3, 247, 77, 251, 195, 1, 233, 84, 247, + 77, 251, 195, 1, 235, 35, 247, 77, 251, 195, 1, 243, 135, 247, 77, 251, + 195, 1, 210, 36, 247, 77, 251, 195, 1, 231, 69, 247, 77, 251, 195, 1, + 207, 132, 247, 77, 251, 195, 1, 203, 175, 247, 77, 251, 195, 1, 195, 72, + 247, 77, 251, 195, 1, 198, 118, 247, 77, 251, 195, 1, 203, 19, 247, 77, + 251, 195, 1, 223, 48, 247, 77, 251, 195, 1, 238, 143, 247, 77, 251, 195, + 1, 247, 69, 247, 77, 251, 195, 1, 192, 84, 247, 77, 251, 195, 1, 209, + 116, 247, 77, 251, 195, 1, 221, 119, 247, 77, 251, 195, 243, 0, 77, 195, + 29, 6, 1, 65, 195, 29, 6, 1, 249, 50, 195, 29, 6, 1, 249, 19, 195, 29, 6, + 1, 247, 44, 195, 29, 6, 1, 243, 129, 195, 29, 6, 1, 237, 148, 195, 29, 6, + 1, 237, 61, 195, 29, 6, 1, 234, 168, 195, 29, 6, 1, 71, 195, 29, 6, 1, + 233, 61, 195, 29, 6, 1, 231, 242, 195, 29, 6, 1, 140, 195, 29, 6, 1, 229, + 179, 195, 29, 6, 1, 68, 195, 29, 6, 1, 223, 198, 195, 29, 6, 1, 223, 12, + 195, 29, 6, 1, 155, 195, 29, 6, 1, 173, 195, 29, 6, 1, 219, 75, 195, 29, + 6, 1, 216, 234, 195, 29, 6, 1, 214, 123, 195, 29, 6, 1, 213, 152, 195, + 29, 6, 1, 74, 195, 29, 6, 1, 210, 65, 195, 29, 6, 1, 208, 98, 195, 29, 6, + 1, 207, 115, 195, 29, 6, 1, 205, 69, 195, 29, 6, 1, 203, 114, 195, 29, 6, + 1, 199, 145, 195, 29, 6, 1, 199, 33, 195, 29, 6, 1, 66, 195, 29, 6, 1, + 195, 153, 195, 29, 6, 1, 192, 214, 195, 29, 6, 1, 192, 159, 195, 29, 6, + 1, 191, 87, 195, 29, 2, 1, 65, 195, 29, 2, 1, 249, 50, 195, 29, 2, 1, + 249, 19, 195, 29, 2, 1, 247, 44, 195, 29, 2, 1, 243, 129, 195, 29, 2, 1, + 237, 148, 195, 29, 2, 1, 237, 61, 195, 29, 2, 1, 234, 168, 195, 29, 2, 1, + 71, 195, 29, 2, 1, 233, 61, 195, 29, 2, 1, 231, 242, 195, 29, 2, 1, 140, + 195, 29, 2, 1, 229, 179, 195, 29, 2, 1, 68, 195, 29, 2, 1, 223, 198, 195, + 29, 2, 1, 223, 12, 195, 29, 2, 1, 155, 195, 29, 2, 1, 173, 195, 29, 2, 1, + 219, 75, 195, 29, 2, 1, 216, 234, 195, 29, 2, 1, 214, 123, 195, 29, 2, 1, + 213, 152, 195, 29, 2, 1, 74, 195, 29, 2, 1, 210, 65, 195, 29, 2, 1, 208, + 98, 195, 29, 2, 1, 207, 115, 195, 29, 2, 1, 205, 69, 195, 29, 2, 1, 203, + 114, 195, 29, 2, 1, 199, 145, 195, 29, 2, 1, 199, 33, 195, 29, 2, 1, 66, + 195, 29, 2, 1, 195, 153, 195, 29, 2, 1, 192, 214, 195, 29, 2, 1, 192, + 159, 195, 29, 2, 1, 191, 87, 32, 42, 3, 252, 156, 32, 42, 3, 252, 155, + 32, 42, 3, 252, 154, 32, 42, 3, 252, 153, 32, 42, 3, 252, 152, 32, 42, 3, + 252, 151, 32, 42, 3, 252, 150, 32, 42, 3, 252, 149, 32, 42, 3, 252, 148, + 32, 42, 3, 252, 147, 32, 42, 3, 252, 146, 32, 42, 3, 252, 145, 32, 42, 3, + 252, 144, 32, 42, 3, 252, 143, 32, 42, 3, 252, 142, 32, 42, 3, 252, 141, + 32, 42, 3, 252, 140, 32, 42, 3, 252, 139, 32, 42, 3, 252, 138, 32, 42, 3, + 252, 137, 32, 42, 3, 252, 136, 32, 42, 3, 252, 135, 32, 42, 3, 252, 134, + 32, 42, 3, 252, 133, 32, 42, 3, 252, 132, 32, 42, 3, 252, 131, 32, 42, 3, + 252, 130, 32, 42, 3, 255, 166, 32, 42, 3, 252, 129, 32, 42, 3, 252, 128, + 32, 42, 3, 252, 127, 32, 42, 3, 252, 126, 32, 42, 3, 252, 125, 32, 42, 3, + 252, 124, 32, 42, 3, 252, 123, 32, 42, 3, 252, 122, 32, 42, 3, 252, 121, + 32, 42, 3, 252, 120, 32, 42, 3, 252, 119, 32, 42, 3, 252, 118, 32, 42, 3, + 252, 117, 32, 42, 3, 252, 116, 32, 42, 3, 252, 115, 32, 42, 3, 252, 114, + 32, 42, 3, 252, 113, 32, 42, 3, 252, 112, 32, 42, 3, 252, 111, 32, 42, 3, + 252, 110, 32, 42, 3, 252, 109, 32, 42, 3, 252, 108, 32, 42, 3, 252, 107, + 32, 42, 3, 252, 106, 32, 42, 3, 252, 105, 32, 42, 3, 252, 104, 32, 42, 3, + 252, 103, 32, 42, 3, 252, 102, 32, 42, 3, 252, 101, 32, 42, 3, 252, 100, + 32, 42, 3, 252, 99, 32, 42, 3, 252, 98, 32, 42, 3, 252, 97, 32, 42, 3, + 252, 96, 32, 42, 3, 252, 95, 32, 42, 3, 252, 94, 32, 42, 3, 252, 93, 32, + 42, 3, 252, 92, 32, 42, 3, 252, 91, 32, 42, 3, 252, 90, 32, 42, 3, 252, + 89, 32, 42, 3, 252, 88, 32, 42, 3, 252, 87, 32, 42, 3, 255, 79, 32, 42, + 3, 252, 86, 32, 42, 3, 252, 85, 32, 42, 3, 255, 44, 32, 42, 3, 252, 84, + 32, 42, 3, 252, 83, 32, 42, 3, 252, 82, 32, 42, 3, 252, 81, 32, 42, 3, + 255, 31, 32, 42, 3, 252, 80, 32, 42, 3, 252, 79, 32, 42, 3, 252, 78, 32, + 42, 3, 252, 77, 32, 42, 3, 252, 76, 32, 42, 3, 254, 103, 32, 42, 3, 254, + 102, 32, 42, 3, 254, 101, 32, 42, 3, 254, 100, 32, 42, 3, 254, 99, 32, + 42, 3, 254, 98, 32, 42, 3, 254, 97, 32, 42, 3, 254, 96, 32, 42, 3, 254, + 94, 32, 42, 3, 254, 93, 32, 42, 3, 254, 92, 32, 42, 3, 254, 91, 32, 42, + 3, 254, 90, 32, 42, 3, 254, 89, 32, 42, 3, 254, 87, 32, 42, 3, 254, 86, + 32, 42, 3, 254, 85, 32, 42, 3, 254, 84, 32, 42, 3, 254, 83, 32, 42, 3, + 254, 82, 32, 42, 3, 254, 81, 32, 42, 3, 254, 80, 32, 42, 3, 254, 79, 32, + 42, 3, 254, 78, 32, 42, 3, 254, 77, 32, 42, 3, 254, 76, 32, 42, 3, 254, + 75, 32, 42, 3, 254, 74, 32, 42, 3, 254, 73, 32, 42, 3, 254, 72, 32, 42, + 3, 254, 71, 32, 42, 3, 254, 70, 32, 42, 3, 254, 69, 32, 42, 3, 254, 67, + 32, 42, 3, 254, 66, 32, 42, 3, 254, 65, 32, 42, 3, 254, 61, 32, 42, 3, + 254, 60, 32, 42, 3, 254, 59, 32, 42, 3, 254, 58, 32, 42, 3, 254, 54, 32, + 42, 3, 254, 53, 32, 42, 3, 254, 52, 32, 42, 3, 254, 51, 32, 42, 3, 254, + 50, 32, 42, 3, 254, 49, 32, 42, 3, 254, 48, 32, 42, 3, 254, 47, 32, 42, + 3, 254, 46, 32, 42, 3, 254, 45, 32, 42, 3, 254, 44, 32, 42, 3, 254, 43, + 32, 42, 3, 254, 42, 32, 42, 3, 254, 41, 32, 42, 3, 254, 40, 32, 42, 3, + 254, 39, 32, 42, 3, 254, 38, 32, 42, 3, 254, 37, 32, 42, 3, 254, 36, 32, + 42, 3, 254, 35, 32, 42, 3, 254, 34, 32, 42, 3, 254, 33, 32, 42, 3, 254, + 32, 32, 42, 3, 254, 30, 32, 42, 3, 254, 29, 32, 42, 3, 254, 28, 32, 42, + 3, 254, 27, 32, 42, 3, 254, 26, 32, 42, 3, 254, 24, 32, 42, 3, 254, 23, + 32, 42, 3, 254, 22, 32, 42, 3, 254, 21, 32, 42, 3, 254, 19, 32, 42, 3, + 254, 18, 32, 42, 3, 254, 17, 32, 42, 3, 253, 239, 32, 42, 3, 253, 237, + 32, 42, 3, 253, 235, 32, 42, 3, 253, 233, 32, 42, 3, 253, 231, 32, 42, 3, + 253, 229, 32, 42, 3, 253, 227, 32, 42, 3, 253, 225, 32, 42, 3, 253, 223, + 32, 42, 3, 253, 221, 32, 42, 3, 253, 219, 32, 42, 3, 253, 216, 32, 42, 3, + 253, 214, 32, 42, 3, 253, 212, 32, 42, 3, 253, 210, 32, 42, 3, 253, 208, + 32, 42, 3, 253, 206, 32, 42, 3, 253, 204, 32, 42, 3, 253, 202, 32, 42, 3, + 253, 120, 32, 42, 3, 253, 119, 32, 42, 3, 253, 118, 32, 42, 3, 253, 117, + 32, 42, 3, 253, 116, 32, 42, 3, 253, 115, 32, 42, 3, 253, 113, 32, 42, 3, + 253, 112, 32, 42, 3, 253, 111, 32, 42, 3, 253, 110, 32, 42, 3, 253, 109, + 32, 42, 3, 253, 108, 32, 42, 3, 253, 106, 32, 42, 3, 253, 105, 32, 42, 3, + 253, 101, 32, 42, 3, 253, 100, 32, 42, 3, 253, 98, 32, 42, 3, 253, 97, + 32, 42, 3, 253, 96, 32, 42, 3, 253, 95, 32, 42, 3, 253, 94, 32, 42, 3, + 253, 93, 32, 42, 3, 253, 92, 32, 42, 3, 253, 91, 32, 42, 3, 253, 90, 32, + 42, 3, 253, 89, 32, 42, 3, 253, 88, 32, 42, 3, 253, 87, 32, 42, 3, 253, + 86, 32, 42, 3, 253, 85, 32, 42, 3, 253, 84, 32, 42, 3, 253, 83, 32, 42, + 3, 253, 82, 32, 42, 3, 253, 81, 32, 42, 3, 253, 80, 32, 42, 3, 253, 79, + 32, 42, 3, 253, 78, 32, 42, 3, 253, 77, 32, 42, 3, 253, 76, 32, 42, 3, + 253, 75, 32, 42, 3, 253, 74, 32, 42, 3, 253, 73, 32, 42, 3, 253, 72, 32, + 42, 3, 253, 71, 32, 42, 3, 253, 70, 32, 42, 3, 253, 69, 32, 42, 3, 253, + 68, 32, 42, 3, 253, 67, 32, 42, 3, 253, 66, 32, 42, 3, 253, 65, 32, 42, + 3, 253, 64, 32, 42, 3, 253, 63, 32, 42, 3, 253, 62, 32, 42, 3, 253, 61, + 32, 42, 3, 253, 60, 32, 42, 3, 253, 59, 32, 42, 3, 253, 58, 32, 42, 3, + 253, 57, 32, 42, 3, 253, 56, 32, 42, 3, 253, 55, 32, 42, 3, 253, 54, 32, + 42, 3, 253, 53, 32, 42, 3, 253, 52, 32, 42, 3, 253, 51, 32, 42, 3, 253, + 50, 32, 42, 3, 253, 49, 32, 42, 3, 253, 48, 32, 42, 3, 253, 47, 32, 42, + 3, 253, 46, 32, 42, 3, 253, 45, 32, 42, 3, 253, 44, 32, 42, 3, 253, 43, + 32, 42, 3, 253, 42, 32, 42, 3, 253, 41, 32, 42, 3, 253, 40, 32, 42, 3, + 253, 39, 32, 42, 3, 253, 38, 32, 42, 3, 253, 37, 32, 42, 3, 253, 36, 32, + 42, 3, 253, 35, 32, 42, 3, 253, 34, 32, 42, 3, 253, 33, 32, 42, 3, 253, + 32, 32, 42, 3, 253, 31, 32, 42, 3, 253, 30, 32, 42, 3, 253, 29, 32, 42, + 3, 253, 28, 32, 42, 3, 253, 27, 32, 42, 3, 253, 26, 32, 42, 3, 253, 25, + 32, 42, 3, 253, 24, 32, 42, 3, 253, 23, 32, 42, 3, 253, 22, 32, 42, 3, + 253, 21, 32, 42, 3, 253, 20, 32, 42, 3, 253, 19, 32, 42, 3, 253, 18, 32, + 42, 3, 253, 17, 32, 42, 3, 253, 16, 32, 42, 3, 253, 15, 32, 42, 3, 253, + 14, 32, 42, 3, 253, 13, 32, 42, 3, 253, 12, 32, 42, 3, 253, 11, 32, 42, + 3, 253, 10, 32, 42, 3, 253, 9, 32, 42, 3, 253, 8, 32, 42, 3, 253, 7, 32, + 42, 3, 253, 6, 32, 42, 3, 253, 5, 32, 42, 3, 253, 4, 32, 42, 3, 253, 3, + 32, 42, 3, 253, 2, 32, 42, 3, 253, 1, 32, 42, 3, 253, 0, 32, 42, 3, 252, + 255, 32, 42, 3, 252, 254, 32, 42, 3, 252, 253, 32, 42, 3, 252, 252, 32, + 42, 3, 252, 251, 32, 42, 3, 252, 250, 32, 42, 3, 252, 249, 32, 42, 3, + 252, 248, 32, 42, 3, 252, 247, 32, 42, 3, 252, 246, 32, 42, 3, 252, 245, + 32, 42, 3, 252, 244, 32, 42, 3, 252, 243, 32, 42, 3, 252, 242, 32, 42, 3, + 252, 241, 32, 42, 3, 252, 240, 32, 42, 3, 252, 239, 32, 42, 3, 252, 238, + 65, 32, 42, 3, 252, 237, 250, 122, 32, 42, 3, 252, 236, 238, 129, 32, 42, + 3, 252, 235, 71, 32, 42, 3, 252, 234, 233, 177, 32, 42, 3, 252, 233, 230, + 118, 32, 42, 3, 252, 232, 223, 37, 32, 42, 3, 252, 231, 222, 154, 32, 42, + 3, 252, 230, 172, 32, 42, 3, 252, 229, 220, 132, 32, 42, 3, 252, 228, + 220, 131, 32, 42, 3, 252, 227, 220, 130, 32, 42, 3, 252, 226, 220, 129, + 32, 42, 3, 252, 225, 193, 224, 32, 42, 3, 252, 224, 192, 235, 32, 42, 3, + 252, 223, 192, 159, 32, 42, 3, 252, 222, 211, 112, 32, 42, 3, 252, 221, + 252, 71, 32, 42, 3, 252, 220, 249, 56, 32, 42, 3, 252, 219, 237, 195, 32, + 42, 3, 252, 218, 233, 185, 32, 42, 3, 252, 217, 223, 12, 32, 42, 3, 252, + 216, 32, 42, 3, 252, 215, 32, 42, 3, 252, 214, 32, 42, 3, 252, 213, 32, + 42, 3, 252, 212, 32, 42, 3, 252, 211, 32, 42, 3, 252, 210, 32, 42, 3, + 252, 209, 52, 1, 2, 6, 252, 208, 52, 1, 200, 182, 197, 238, 242, 85, 52, + 1, 200, 182, 132, 197, 238, 242, 85, 52, 1, 2, 252, 27, 52, 1, 2, 6, 250, + 122, 52, 1, 2, 78, 4, 102, 52, 1, 2, 235, 39, 237, 4, 52, 1, 2, 235, 39, + 237, 5, 4, 207, 25, 102, 52, 1, 2, 235, 39, 237, 5, 4, 238, 177, 52, 1, + 2, 237, 72, 237, 4, 52, 1, 2, 238, 130, 4, 199, 215, 52, 1, 2, 238, 130, + 4, 102, 52, 1, 2, 238, 130, 4, 228, 253, 23, 199, 215, 52, 1, 2, 207, 19, + 71, 52, 1, 2, 242, 221, 207, 19, 211, 79, 71, 52, 1, 2, 233, 39, 237, 4, + 52, 1, 2, 207, 142, 228, 189, 52, 1, 2, 6, 232, 53, 52, 1, 2, 232, 54, 4, + 102, 52, 1, 2, 6, 232, 54, 4, 102, 52, 1, 2, 230, 119, 4, 106, 52, 1, 2, + 6, 230, 118, 52, 1, 2, 229, 199, 4, 102, 52, 1, 2, 236, 141, 223, 38, 4, + 201, 29, 23, 102, 52, 1, 2, 218, 229, 237, 4, 52, 1, 2, 218, 172, 237, 4, + 52, 1, 2, 220, 145, 4, 248, 233, 52, 1, 2, 6, 220, 145, 4, 248, 233, 52, + 1, 2, 220, 145, 4, 207, 25, 228, 253, 23, 248, 233, 52, 1, 2, 219, 164, + 52, 1, 2, 219, 165, 4, 207, 25, 102, 52, 1, 2, 154, 192, 159, 52, 1, 2, + 154, 192, 160, 4, 248, 233, 52, 1, 2, 187, 4, 106, 52, 1, 2, 6, 211, 153, + 52, 1, 2, 242, 221, 211, 112, 52, 1, 2, 208, 106, 52, 1, 2, 154, 207, + 224, 4, 180, 219, 214, 52, 1, 2, 154, 207, 224, 4, 180, 219, 215, 23, + 207, 25, 102, 52, 1, 2, 207, 224, 4, 199, 215, 52, 1, 2, 207, 224, 4, + 232, 235, 52, 1, 2, 6, 146, 52, 1, 2, 199, 152, 237, 5, 4, 238, 177, 52, + 1, 2, 197, 170, 237, 4, 52, 1, 2, 197, 170, 237, 5, 4, 207, 25, 102, 52, + 1, 2, 199, 79, 237, 4, 52, 1, 2, 200, 44, 4, 207, 25, 102, 52, 1, 2, 196, + 13, 4, 50, 102, 52, 1, 2, 6, 192, 159, 52, 1, 231, 13, 201, 65, 4, 106, + 52, 1, 207, 19, 231, 13, 201, 65, 4, 106, 52, 1, 248, 174, 242, 233, 52, + 1, 237, 100, 242, 233, 52, 1, 220, 5, 242, 233, 52, 1, 251, 152, 242, + 233, 52, 1, 207, 25, 242, 234, 4, 207, 25, 102, 52, 1, 2, 206, 10, 4, + 238, 177, 238, 137, 5, 65, 238, 137, 5, 71, 238, 137, 5, 68, 238, 137, 5, + 74, 238, 137, 5, 66, 238, 137, 5, 223, 34, 238, 137, 5, 222, 203, 238, + 137, 5, 155, 238, 137, 5, 222, 24, 238, 137, 5, 221, 168, 238, 137, 5, + 221, 69, 238, 137, 5, 220, 234, 238, 137, 5, 173, 238, 137, 5, 219, 240, + 238, 137, 5, 219, 148, 238, 137, 5, 219, 45, 238, 137, 5, 218, 227, 238, + 137, 5, 174, 238, 137, 5, 216, 234, 238, 137, 5, 216, 102, 238, 137, 5, + 216, 14, 238, 137, 5, 215, 157, 238, 137, 5, 181, 238, 137, 5, 214, 123, + 238, 137, 5, 213, 221, 238, 137, 5, 213, 45, 238, 137, 5, 212, 180, 238, + 137, 5, 168, 238, 137, 5, 210, 65, 238, 137, 5, 209, 187, 238, 137, 5, + 209, 75, 238, 137, 5, 208, 167, 238, 137, 5, 165, 238, 137, 5, 207, 115, + 238, 137, 5, 207, 2, 238, 137, 5, 206, 163, 238, 137, 5, 206, 69, 238, + 137, 5, 188, 238, 137, 5, 205, 69, 238, 137, 5, 202, 223, 238, 137, 5, + 202, 47, 238, 137, 5, 201, 5, 238, 137, 5, 190, 190, 238, 137, 5, 199, + 145, 238, 137, 5, 198, 193, 238, 137, 5, 159, 238, 137, 5, 197, 94, 238, + 137, 5, 193, 190, 238, 137, 5, 193, 125, 238, 137, 5, 193, 86, 238, 137, + 5, 193, 48, 238, 137, 5, 192, 220, 238, 137, 5, 192, 214, 238, 137, 5, + 191, 123, 238, 137, 5, 191, 7, 223, 166, 251, 20, 1, 251, 192, 223, 166, + 251, 20, 1, 248, 213, 223, 166, 251, 20, 1, 231, 40, 223, 166, 251, 20, + 1, 237, 254, 223, 166, 251, 20, 1, 229, 247, 223, 166, 251, 20, 1, 193, + 133, 223, 166, 251, 20, 1, 191, 91, 223, 166, 251, 20, 1, 229, 186, 223, + 166, 251, 20, 1, 199, 69, 223, 166, 251, 20, 1, 191, 249, 223, 166, 251, + 20, 1, 222, 77, 223, 166, 251, 20, 1, 220, 28, 223, 166, 251, 20, 1, 216, + 195, 223, 166, 251, 20, 1, 212, 132, 223, 166, 251, 20, 1, 205, 149, 223, + 166, 251, 20, 1, 250, 128, 223, 166, 251, 20, 1, 210, 65, 223, 166, 251, + 20, 1, 205, 190, 223, 166, 251, 20, 1, 208, 39, 223, 166, 251, 20, 1, + 207, 39, 223, 166, 251, 20, 1, 203, 70, 223, 166, 251, 20, 1, 199, 159, + 223, 166, 251, 20, 205, 55, 56, 223, 166, 251, 20, 31, 107, 223, 166, + 251, 20, 31, 109, 223, 166, 251, 20, 31, 138, 223, 166, 251, 20, 31, 199, + 95, 223, 166, 251, 20, 31, 197, 32, 223, 166, 251, 20, 31, 91, 228, 142, + 223, 166, 251, 20, 31, 91, 189, 223, 166, 251, 20, 31, 199, 96, 189, 210, + 182, 1, 251, 192, 210, 182, 1, 248, 213, 210, 182, 1, 231, 40, 210, 182, + 1, 237, 254, 210, 182, 1, 229, 247, 210, 182, 1, 193, 133, 210, 182, 1, + 191, 91, 210, 182, 1, 229, 186, 210, 182, 1, 199, 69, 210, 182, 1, 191, + 249, 210, 182, 1, 222, 77, 210, 182, 1, 220, 28, 210, 182, 1, 216, 195, + 210, 182, 1, 53, 212, 132, 210, 182, 1, 212, 132, 210, 182, 1, 205, 149, + 210, 182, 1, 250, 128, 210, 182, 1, 210, 65, 210, 182, 1, 205, 190, 210, + 182, 1, 208, 39, 210, 182, 1, 207, 39, 210, 182, 1, 203, 70, 210, 182, 1, + 199, 159, 210, 182, 219, 221, 232, 203, 210, 182, 206, 204, 232, 203, + 210, 182, 31, 107, 210, 182, 31, 109, 210, 182, 31, 138, 210, 182, 31, + 134, 210, 182, 31, 150, 210, 182, 31, 199, 95, 210, 182, 31, 197, 32, + 214, 248, 1, 53, 251, 192, 214, 248, 1, 251, 192, 214, 248, 1, 53, 248, + 213, 214, 248, 1, 248, 213, 214, 248, 1, 231, 40, 214, 248, 1, 237, 254, + 214, 248, 1, 53, 229, 247, 214, 248, 1, 229, 247, 214, 248, 1, 193, 133, + 214, 248, 1, 191, 91, 214, 248, 1, 229, 186, 214, 248, 1, 199, 69, 214, + 248, 1, 53, 191, 249, 214, 248, 1, 191, 249, 214, 248, 1, 53, 222, 77, + 214, 248, 1, 222, 77, 214, 248, 1, 53, 220, 28, 214, 248, 1, 220, 28, + 214, 248, 1, 53, 216, 195, 214, 248, 1, 216, 195, 214, 248, 1, 53, 212, + 132, 214, 248, 1, 212, 132, 214, 248, 1, 205, 149, 214, 248, 1, 250, 128, + 214, 248, 1, 210, 65, 214, 248, 1, 205, 190, 214, 248, 1, 208, 39, 214, + 248, 1, 207, 39, 214, 248, 1, 53, 203, 70, 214, 248, 1, 203, 70, 214, + 248, 1, 199, 159, 214, 248, 31, 107, 214, 248, 31, 109, 214, 248, 31, + 138, 214, 248, 31, 134, 214, 248, 238, 204, 31, 134, 214, 248, 31, 150, + 214, 248, 31, 199, 95, 214, 248, 31, 197, 32, 214, 248, 31, 91, 228, 142, + 230, 6, 1, 251, 192, 230, 6, 1, 248, 213, 230, 6, 1, 231, 40, 230, 6, 1, + 237, 253, 230, 6, 1, 229, 247, 230, 6, 1, 193, 133, 230, 6, 1, 191, 89, + 230, 6, 1, 229, 186, 230, 6, 1, 199, 69, 230, 6, 1, 191, 249, 230, 6, 1, + 222, 77, 230, 6, 1, 220, 28, 230, 6, 1, 216, 195, 230, 6, 1, 212, 132, + 230, 6, 1, 205, 149, 230, 6, 1, 250, 126, 230, 6, 1, 210, 65, 230, 6, 1, + 205, 190, 230, 6, 1, 208, 39, 230, 6, 1, 203, 70, 230, 6, 1, 199, 159, + 230, 6, 31, 107, 230, 6, 31, 150, 230, 6, 31, 199, 95, 230, 6, 31, 197, + 32, 230, 6, 31, 91, 228, 142, 209, 199, 1, 251, 189, 209, 199, 1, 248, + 216, 209, 199, 1, 231, 215, 209, 199, 1, 237, 110, 209, 199, 1, 229, 247, + 209, 199, 1, 193, 140, 209, 199, 1, 191, 115, 209, 199, 1, 229, 188, 209, + 199, 1, 199, 73, 209, 199, 1, 191, 250, 209, 199, 1, 222, 108, 209, 199, + 1, 220, 34, 209, 199, 1, 216, 195, 209, 199, 1, 212, 132, 209, 199, 1, + 204, 20, 209, 199, 1, 251, 232, 209, 199, 1, 210, 65, 209, 199, 1, 205, + 192, 209, 199, 1, 208, 44, 209, 199, 1, 206, 125, 209, 199, 1, 203, 70, + 209, 199, 1, 199, 166, 209, 199, 31, 107, 209, 199, 31, 199, 95, 209, + 199, 31, 197, 32, 209, 199, 31, 91, 228, 142, 209, 199, 31, 109, 209, + 199, 31, 138, 209, 199, 193, 23, 204, 11, 218, 182, 1, 65, 218, 182, 1, + 250, 122, 218, 182, 1, 232, 53, 218, 182, 1, 238, 129, 218, 182, 1, 71, + 218, 182, 1, 196, 12, 218, 182, 1, 68, 218, 182, 1, 192, 159, 218, 182, + 1, 222, 154, 218, 182, 1, 172, 218, 182, 1, 218, 170, 218, 182, 1, 215, + 63, 218, 182, 1, 74, 218, 182, 1, 146, 218, 182, 1, 201, 179, 218, 182, + 1, 200, 43, 218, 182, 1, 66, 218, 182, 1, 233, 177, 218, 182, 1, 208, + 106, 218, 182, 1, 206, 9, 218, 182, 1, 197, 135, 218, 182, 1, 251, 134, + 218, 182, 1, 234, 105, 218, 182, 1, 218, 185, 218, 182, 1, 213, 82, 218, + 182, 1, 247, 195, 218, 182, 197, 238, 77, 153, 229, 146, 1, 65, 153, 229, + 146, 1, 71, 153, 229, 146, 1, 68, 153, 229, 146, 1, 74, 153, 229, 146, 1, + 170, 153, 229, 146, 1, 193, 190, 153, 229, 146, 1, 249, 155, 153, 229, + 146, 1, 249, 154, 153, 229, 146, 1, 168, 153, 229, 146, 1, 174, 153, 229, + 146, 1, 181, 153, 229, 146, 1, 215, 7, 153, 229, 146, 1, 214, 123, 153, + 229, 146, 1, 214, 121, 153, 229, 146, 1, 165, 153, 229, 146, 1, 207, 186, + 153, 229, 146, 1, 173, 153, 229, 146, 1, 221, 217, 153, 229, 146, 1, 229, + 179, 153, 229, 146, 1, 188, 153, 229, 146, 1, 205, 206, 153, 229, 146, 1, + 205, 69, 153, 229, 146, 1, 155, 153, 229, 146, 1, 208, 98, 153, 229, 146, + 1, 190, 190, 153, 229, 146, 1, 199, 250, 153, 229, 146, 1, 199, 145, 153, + 229, 146, 1, 199, 143, 153, 229, 146, 1, 159, 153, 229, 146, 1, 238, 34, + 153, 229, 146, 16, 195, 63, 153, 229, 146, 16, 195, 62, 153, 238, 168, 1, + 65, 153, 238, 168, 1, 71, 153, 238, 168, 1, 68, 153, 238, 168, 1, 74, + 153, 238, 168, 1, 170, 153, 238, 168, 1, 193, 190, 153, 238, 168, 1, 249, + 155, 153, 238, 168, 1, 168, 153, 238, 168, 1, 174, 153, 238, 168, 1, 181, + 153, 238, 168, 1, 214, 123, 153, 238, 168, 1, 165, 153, 238, 168, 1, 173, + 153, 238, 168, 1, 221, 217, 153, 238, 168, 1, 229, 179, 153, 238, 168, 1, + 188, 153, 238, 168, 1, 251, 16, 188, 153, 238, 168, 1, 205, 69, 153, 238, + 168, 1, 155, 153, 238, 168, 1, 208, 98, 153, 238, 168, 1, 190, 190, 153, + 238, 168, 1, 199, 145, 153, 238, 168, 1, 159, 153, 238, 168, 1, 238, 34, + 153, 238, 168, 232, 120, 234, 130, 197, 39, 153, 238, 168, 232, 120, 91, + 230, 72, 153, 238, 168, 219, 30, 206, 169, 153, 238, 168, 219, 30, 223, + 171, 153, 238, 168, 31, 107, 153, 238, 168, 31, 109, 153, 238, 168, 31, + 138, 153, 238, 168, 31, 134, 153, 238, 168, 31, 150, 153, 238, 168, 31, + 169, 153, 238, 168, 31, 175, 153, 238, 168, 31, 171, 153, 238, 168, 31, + 178, 153, 238, 168, 31, 199, 95, 153, 238, 168, 31, 197, 32, 153, 238, + 168, 31, 198, 249, 153, 238, 168, 31, 232, 137, 153, 238, 168, 31, 233, + 17, 153, 238, 168, 31, 202, 121, 153, 238, 168, 31, 203, 242, 153, 238, + 168, 31, 91, 228, 142, 153, 238, 168, 31, 105, 228, 142, 153, 238, 168, + 31, 115, 228, 142, 153, 238, 168, 31, 232, 130, 228, 142, 153, 238, 168, + 31, 232, 228, 228, 142, 153, 238, 168, 31, 202, 137, 228, 142, 153, 238, + 168, 31, 203, 248, 228, 142, 153, 238, 168, 31, 234, 166, 228, 142, 153, + 238, 168, 31, 213, 177, 228, 142, 153, 238, 168, 31, 91, 189, 153, 238, + 168, 31, 105, 189, 153, 238, 168, 31, 115, 189, 153, 238, 168, 31, 232, + 130, 189, 153, 238, 168, 31, 232, 228, 189, 153, 238, 168, 31, 202, 137, + 189, 153, 238, 168, 31, 203, 248, 189, 153, 238, 168, 31, 234, 166, 189, + 153, 238, 168, 31, 213, 177, 189, 153, 238, 168, 31, 199, 96, 189, 153, + 238, 168, 31, 197, 33, 189, 153, 238, 168, 31, 198, 250, 189, 153, 238, + 168, 31, 232, 138, 189, 153, 238, 168, 31, 233, 18, 189, 153, 238, 168, + 31, 202, 122, 189, 153, 238, 168, 31, 203, 243, 189, 153, 238, 168, 31, + 234, 156, 189, 153, 238, 168, 31, 213, 172, 189, 153, 238, 168, 31, 91, + 228, 143, 189, 153, 238, 168, 31, 105, 228, 143, 189, 153, 238, 168, 31, + 115, 228, 143, 189, 153, 238, 168, 31, 232, 130, 228, 143, 189, 153, 238, + 168, 31, 232, 228, 228, 143, 189, 153, 238, 168, 31, 202, 137, 228, 143, + 189, 153, 238, 168, 31, 203, 248, 228, 143, 189, 153, 238, 168, 31, 234, + 166, 228, 143, 189, 153, 238, 168, 31, 213, 177, 228, 143, 189, 153, 238, + 168, 232, 120, 91, 197, 40, 153, 238, 168, 232, 120, 105, 197, 39, 153, + 238, 168, 232, 120, 115, 197, 39, 153, 238, 168, 232, 120, 232, 130, 197, + 39, 153, 238, 168, 232, 120, 232, 228, 197, 39, 153, 238, 168, 232, 120, + 202, 137, 197, 39, 153, 238, 168, 232, 120, 203, 248, 197, 39, 153, 238, + 168, 232, 120, 234, 166, 197, 39, 153, 238, 168, 232, 120, 213, 177, 197, + 39, 153, 238, 168, 232, 120, 199, 96, 197, 39, 221, 201, 1, 65, 221, 201, + 18, 3, 68, 221, 201, 18, 3, 66, 221, 201, 18, 3, 117, 146, 221, 201, 18, + 3, 71, 221, 201, 18, 3, 74, 221, 201, 18, 219, 200, 77, 221, 201, 3, 55, + 206, 190, 60, 221, 201, 3, 251, 73, 221, 201, 3, 195, 35, 221, 201, 1, + 155, 221, 201, 1, 221, 217, 221, 201, 1, 231, 242, 221, 201, 1, 231, 93, + 221, 201, 1, 247, 162, 221, 201, 1, 247, 3, 221, 201, 1, 223, 34, 221, + 201, 1, 212, 103, 221, 201, 1, 197, 132, 221, 201, 1, 197, 120, 221, 201, + 1, 237, 193, 221, 201, 1, 237, 177, 221, 201, 1, 213, 81, 221, 201, 1, + 190, 190, 221, 201, 1, 199, 49, 221, 201, 1, 238, 34, 221, 201, 1, 237, + 70, 221, 201, 1, 181, 221, 201, 1, 168, 221, 201, 1, 209, 230, 221, 201, + 1, 249, 155, 221, 201, 1, 248, 205, 221, 201, 1, 174, 221, 201, 1, 170, + 221, 201, 1, 165, 221, 201, 1, 173, 221, 201, 1, 195, 188, 221, 201, 1, + 203, 166, 221, 201, 1, 201, 176, 221, 201, 1, 188, 221, 201, 1, 191, 123, + 221, 201, 1, 140, 221, 201, 1, 221, 103, 221, 201, 1, 197, 100, 221, 201, + 1, 197, 101, 221, 201, 1, 195, 70, 221, 201, 3, 249, 90, 58, 221, 201, 3, + 247, 76, 221, 201, 3, 75, 60, 221, 201, 195, 40, 221, 201, 17, 107, 221, + 201, 17, 109, 221, 201, 17, 138, 221, 201, 17, 134, 221, 201, 31, 199, + 95, 221, 201, 31, 197, 32, 221, 201, 31, 91, 228, 142, 221, 201, 31, 91, + 189, 221, 201, 232, 120, 91, 230, 72, 221, 201, 208, 154, 236, 142, 221, + 201, 208, 154, 2, 243, 12, 221, 201, 208, 154, 243, 12, 221, 201, 208, + 154, 238, 230, 164, 221, 201, 208, 154, 217, 85, 221, 201, 208, 154, 218, + 248, 221, 201, 208, 154, 237, 240, 221, 201, 208, 154, 55, 237, 240, 221, + 201, 208, 154, 219, 108, 39, 202, 3, 251, 31, 1, 229, 247, 39, 202, 3, + 251, 31, 1, 220, 28, 39, 202, 3, 251, 31, 1, 229, 186, 39, 202, 3, 251, + 31, 1, 216, 195, 39, 202, 3, 251, 31, 1, 208, 39, 39, 202, 3, 251, 31, 1, + 193, 133, 39, 202, 3, 251, 31, 1, 203, 70, 39, 202, 3, 251, 31, 1, 207, + 39, 39, 202, 3, 251, 31, 1, 248, 213, 39, 202, 3, 251, 31, 1, 199, 159, + 39, 202, 3, 251, 31, 1, 205, 123, 39, 202, 3, 251, 31, 1, 222, 77, 39, + 202, 3, 251, 31, 1, 212, 132, 39, 202, 3, 251, 31, 1, 221, 196, 39, 202, + 3, 251, 31, 1, 205, 190, 39, 202, 3, 251, 31, 1, 205, 149, 39, 202, 3, + 251, 31, 1, 233, 61, 39, 202, 3, 251, 31, 1, 251, 194, 39, 202, 3, 251, + 31, 1, 250, 126, 39, 202, 3, 251, 31, 1, 237, 67, 39, 202, 3, 251, 31, 1, + 231, 40, 39, 202, 3, 251, 31, 1, 237, 254, 39, 202, 3, 251, 31, 1, 231, + 81, 39, 202, 3, 251, 31, 1, 199, 69, 39, 202, 3, 251, 31, 1, 191, 89, 39, + 202, 3, 251, 31, 1, 237, 64, 39, 202, 3, 251, 31, 1, 191, 249, 39, 202, + 3, 251, 31, 1, 199, 35, 39, 202, 3, 251, 31, 1, 199, 14, 39, 202, 3, 251, + 31, 31, 107, 39, 202, 3, 251, 31, 31, 233, 17, 39, 202, 3, 251, 31, 167, + 223, 146, 39, 186, 251, 31, 1, 229, 212, 39, 186, 251, 31, 1, 220, 37, + 39, 186, 251, 31, 1, 230, 83, 39, 186, 251, 31, 1, 216, 210, 39, 186, + 251, 31, 1, 208, 91, 39, 186, 251, 31, 1, 193, 133, 39, 186, 251, 31, 1, + 234, 22, 39, 186, 251, 31, 1, 207, 72, 39, 186, 251, 31, 1, 248, 247, 39, + 186, 251, 31, 1, 199, 114, 39, 186, 251, 31, 1, 234, 23, 39, 186, 251, + 31, 1, 222, 108, 39, 186, 251, 31, 1, 213, 26, 39, 186, 251, 31, 1, 221, + 212, 39, 186, 251, 31, 1, 205, 193, 39, 186, 251, 31, 1, 234, 21, 39, + 186, 251, 31, 1, 233, 48, 39, 186, 251, 31, 1, 251, 194, 39, 186, 251, + 31, 1, 251, 232, 39, 186, 251, 31, 1, 238, 28, 39, 186, 251, 31, 1, 231, + 158, 39, 186, 251, 31, 1, 238, 5, 39, 186, 251, 31, 1, 231, 88, 39, 186, + 251, 31, 1, 199, 219, 39, 186, 251, 31, 1, 191, 113, 39, 186, 251, 31, 1, + 199, 41, 39, 186, 251, 31, 1, 192, 75, 39, 186, 251, 31, 1, 199, 29, 39, + 186, 251, 31, 1, 191, 116, 39, 186, 251, 31, 31, 107, 39, 186, 251, 31, + 31, 199, 95, 39, 186, 251, 31, 31, 197, 32, 217, 83, 1, 251, 192, 217, + 83, 1, 248, 213, 217, 83, 1, 248, 196, 217, 83, 1, 231, 40, 217, 83, 1, + 231, 66, 217, 83, 1, 237, 254, 217, 83, 1, 229, 247, 217, 83, 1, 193, + 133, 217, 83, 3, 196, 158, 217, 83, 1, 191, 91, 217, 83, 1, 191, 64, 217, + 83, 1, 223, 14, 217, 83, 1, 222, 250, 217, 83, 1, 229, 186, 217, 83, 1, + 199, 69, 217, 83, 1, 191, 249, 217, 83, 1, 222, 77, 217, 83, 1, 192, 217, + 217, 83, 1, 221, 203, 217, 83, 1, 220, 28, 217, 83, 1, 237, 63, 217, 83, + 1, 199, 40, 217, 83, 1, 216, 195, 217, 83, 1, 212, 132, 217, 83, 1, 205, + 149, 217, 83, 1, 250, 128, 217, 83, 1, 252, 160, 217, 83, 1, 210, 65, + 217, 83, 1, 233, 61, 217, 83, 1, 205, 190, 217, 83, 1, 208, 39, 217, 83, + 1, 192, 193, 217, 83, 1, 208, 66, 217, 83, 1, 207, 39, 217, 83, 1, 203, + 70, 217, 83, 1, 201, 144, 217, 83, 1, 199, 159, 217, 83, 252, 70, 87, 58, + 217, 83, 252, 70, 87, 60, 217, 83, 31, 107, 217, 83, 31, 150, 217, 83, + 31, 199, 95, 217, 83, 31, 197, 32, 217, 83, 31, 91, 228, 142, 217, 83, + 208, 154, 201, 103, 217, 83, 208, 154, 232, 203, 217, 83, 208, 154, 55, + 75, 193, 53, 236, 142, 217, 83, 208, 154, 75, 193, 53, 236, 142, 217, 83, + 208, 154, 236, 142, 217, 83, 208, 154, 105, 236, 140, 217, 83, 208, 154, + 219, 115, 233, 5, 250, 144, 1, 65, 250, 144, 1, 252, 208, 250, 144, 1, + 251, 70, 250, 144, 1, 252, 166, 250, 144, 1, 251, 134, 250, 144, 1, 252, + 168, 250, 144, 1, 252, 27, 250, 144, 1, 252, 23, 250, 144, 1, 71, 250, + 144, 1, 234, 190, 250, 144, 1, 74, 250, 144, 1, 211, 89, 250, 144, 1, 68, + 250, 144, 1, 223, 201, 250, 144, 1, 66, 250, 144, 1, 196, 30, 250, 144, + 1, 222, 24, 250, 144, 1, 192, 214, 250, 144, 1, 192, 173, 250, 144, 1, + 192, 184, 250, 144, 1, 231, 167, 250, 144, 1, 231, 124, 250, 144, 1, 231, + 79, 250, 144, 1, 247, 44, 250, 144, 1, 223, 12, 250, 144, 1, 199, 145, + 250, 144, 1, 199, 33, 250, 144, 1, 237, 148, 250, 144, 1, 237, 61, 250, + 144, 1, 197, 127, 250, 144, 1, 210, 65, 250, 144, 1, 233, 61, 250, 144, + 1, 249, 19, 250, 144, 1, 248, 198, 250, 144, 1, 214, 57, 250, 144, 1, + 213, 228, 250, 144, 1, 213, 229, 250, 144, 1, 214, 123, 250, 144, 1, 212, + 92, 250, 144, 1, 213, 76, 250, 144, 1, 216, 234, 250, 144, 1, 229, 75, + 250, 144, 1, 191, 173, 250, 144, 1, 192, 80, 250, 144, 1, 195, 153, 250, + 144, 1, 207, 115, 250, 144, 1, 219, 240, 250, 144, 1, 205, 69, 250, 144, + 1, 191, 87, 250, 144, 1, 203, 114, 250, 144, 1, 191, 62, 250, 144, 1, + 202, 230, 250, 144, 1, 201, 145, 250, 144, 1, 229, 247, 250, 144, 252, + 70, 77, 198, 138, 105, 185, 139, 91, 75, 208, 153, 2, 105, 185, 139, 91, + 75, 208, 153, 220, 15, 105, 185, 139, 91, 75, 208, 153, 220, 15, 91, 75, + 139, 105, 185, 208, 153, 220, 15, 105, 206, 186, 139, 91, 206, 190, 208, + 153, 220, 15, 91, 206, 190, 139, 105, 206, 186, 208, 153, 223, 124, 210, + 108, 1, 251, 192, 223, 124, 210, 108, 1, 248, 213, 223, 124, 210, 108, 1, + 231, 40, 223, 124, 210, 108, 1, 237, 254, 223, 124, 210, 108, 1, 229, + 247, 223, 124, 210, 108, 1, 193, 133, 223, 124, 210, 108, 1, 191, 91, + 223, 124, 210, 108, 1, 229, 186, 223, 124, 210, 108, 1, 199, 69, 223, + 124, 210, 108, 1, 191, 249, 223, 124, 210, 108, 1, 222, 77, 223, 124, + 210, 108, 1, 220, 28, 223, 124, 210, 108, 1, 216, 195, 223, 124, 210, + 108, 1, 212, 132, 223, 124, 210, 108, 1, 205, 149, 223, 124, 210, 108, 1, + 250, 128, 223, 124, 210, 108, 1, 210, 65, 223, 124, 210, 108, 1, 205, + 190, 223, 124, 210, 108, 1, 208, 39, 223, 124, 210, 108, 1, 207, 39, 223, + 124, 210, 108, 1, 203, 70, 223, 124, 210, 108, 1, 199, 159, 223, 124, + 210, 108, 31, 107, 223, 124, 210, 108, 31, 109, 223, 124, 210, 108, 31, + 138, 223, 124, 210, 108, 31, 134, 223, 124, 210, 108, 31, 199, 95, 223, + 124, 210, 108, 31, 197, 32, 223, 124, 210, 108, 31, 91, 228, 142, 223, + 124, 210, 108, 31, 91, 189, 223, 124, 210, 201, 1, 251, 192, 223, 124, + 210, 201, 1, 248, 213, 223, 124, 210, 201, 1, 231, 40, 223, 124, 210, + 201, 1, 237, 254, 223, 124, 210, 201, 1, 229, 247, 223, 124, 210, 201, 1, + 193, 132, 223, 124, 210, 201, 1, 191, 91, 223, 124, 210, 201, 1, 229, + 186, 223, 124, 210, 201, 1, 199, 69, 223, 124, 210, 201, 1, 191, 249, + 223, 124, 210, 201, 1, 222, 77, 223, 124, 210, 201, 1, 220, 28, 223, 124, + 210, 201, 1, 216, 194, 223, 124, 210, 201, 1, 212, 132, 223, 124, 210, + 201, 1, 205, 149, 223, 124, 210, 201, 1, 210, 65, 223, 124, 210, 201, 1, + 205, 190, 223, 124, 210, 201, 1, 203, 70, 223, 124, 210, 201, 1, 199, + 159, 223, 124, 210, 201, 31, 107, 223, 124, 210, 201, 31, 109, 223, 124, + 210, 201, 31, 138, 223, 124, 210, 201, 31, 134, 223, 124, 210, 201, 31, + 199, 95, 223, 124, 210, 201, 31, 197, 32, 223, 124, 210, 201, 31, 91, + 228, 142, 223, 124, 210, 201, 31, 91, 189, 208, 179, 210, 201, 1, 251, + 192, 208, 179, 210, 201, 1, 248, 213, 208, 179, 210, 201, 1, 231, 40, + 208, 179, 210, 201, 1, 237, 254, 208, 179, 210, 201, 1, 229, 247, 208, + 179, 210, 201, 1, 193, 132, 208, 179, 210, 201, 1, 191, 91, 208, 179, + 210, 201, 1, 229, 186, 208, 179, 210, 201, 1, 191, 249, 208, 179, 210, + 201, 1, 222, 77, 208, 179, 210, 201, 1, 220, 28, 208, 179, 210, 201, 1, + 216, 194, 208, 179, 210, 201, 1, 212, 132, 208, 179, 210, 201, 1, 205, + 149, 208, 179, 210, 201, 1, 210, 65, 208, 179, 210, 201, 1, 205, 190, + 208, 179, 210, 201, 1, 203, 70, 208, 179, 210, 201, 1, 199, 159, 208, + 179, 210, 201, 205, 55, 77, 208, 179, 210, 201, 154, 205, 55, 77, 208, + 179, 210, 201, 232, 130, 185, 4, 238, 219, 208, 179, 210, 201, 232, 130, + 185, 4, 236, 142, 208, 179, 210, 201, 31, 107, 208, 179, 210, 201, 31, + 109, 208, 179, 210, 201, 31, 138, 208, 179, 210, 201, 31, 134, 208, 179, + 210, 201, 31, 199, 95, 208, 179, 210, 201, 31, 197, 32, 208, 179, 210, + 201, 31, 91, 228, 142, 39, 197, 61, 1, 211, 46, 65, 39, 197, 61, 1, 192, + 68, 65, 39, 197, 61, 1, 192, 68, 252, 27, 39, 197, 61, 1, 211, 46, 68, 39, 197, 61, 1, 192, 68, 68, 39, 197, 61, 1, 192, 68, 71, 39, 197, 61, 1, - 211, 44, 74, 39, 197, 61, 1, 211, 44, 211, 151, 39, 197, 61, 1, 192, 68, - 211, 151, 39, 197, 61, 1, 211, 44, 252, 155, 39, 197, 61, 1, 192, 68, - 252, 155, 39, 197, 61, 1, 211, 44, 252, 24, 39, 197, 61, 1, 192, 68, 252, - 24, 39, 197, 61, 1, 211, 44, 251, 253, 39, 197, 61, 1, 192, 68, 251, 253, - 39, 197, 61, 1, 211, 44, 252, 19, 39, 197, 61, 1, 192, 68, 252, 19, 39, - 197, 61, 1, 211, 44, 252, 42, 39, 197, 61, 1, 192, 68, 252, 42, 39, 197, - 61, 1, 211, 44, 252, 23, 39, 197, 61, 1, 211, 44, 233, 182, 39, 197, 61, - 1, 192, 68, 233, 182, 39, 197, 61, 1, 211, 44, 250, 131, 39, 197, 61, 1, - 192, 68, 250, 131, 39, 197, 61, 1, 211, 44, 252, 6, 39, 197, 61, 1, 192, - 68, 252, 6, 39, 197, 61, 1, 211, 44, 252, 17, 39, 197, 61, 1, 192, 68, - 252, 17, 39, 197, 61, 1, 211, 44, 211, 149, 39, 197, 61, 1, 192, 68, 211, - 149, 39, 197, 61, 1, 211, 44, 251, 207, 39, 197, 61, 1, 192, 68, 251, - 207, 39, 197, 61, 1, 211, 44, 252, 16, 39, 197, 61, 1, 211, 44, 234, 118, - 39, 197, 61, 1, 211, 44, 234, 114, 39, 197, 61, 1, 211, 44, 251, 132, 39, - 197, 61, 1, 211, 44, 252, 14, 39, 197, 61, 1, 192, 68, 252, 14, 39, 197, - 61, 1, 211, 44, 234, 80, 39, 197, 61, 1, 192, 68, 234, 80, 39, 197, 61, - 1, 211, 44, 234, 100, 39, 197, 61, 1, 192, 68, 234, 100, 39, 197, 61, 1, - 211, 44, 234, 66, 39, 197, 61, 1, 192, 68, 234, 66, 39, 197, 61, 1, 192, - 68, 251, 122, 39, 197, 61, 1, 211, 44, 234, 88, 39, 197, 61, 1, 192, 68, - 252, 13, 39, 197, 61, 1, 211, 44, 234, 56, 39, 197, 61, 1, 211, 44, 211, - 78, 39, 197, 61, 1, 211, 44, 228, 28, 39, 197, 61, 1, 211, 44, 234, 197, - 39, 197, 61, 1, 192, 68, 234, 197, 39, 197, 61, 1, 211, 44, 251, 37, 39, - 197, 61, 1, 192, 68, 251, 37, 39, 197, 61, 1, 211, 44, 223, 79, 39, 197, - 61, 1, 192, 68, 223, 79, 39, 197, 61, 1, 211, 44, 211, 58, 39, 197, 61, - 1, 192, 68, 211, 58, 39, 197, 61, 1, 211, 44, 251, 33, 39, 197, 61, 1, - 192, 68, 251, 33, 39, 197, 61, 1, 211, 44, 252, 12, 39, 197, 61, 1, 211, - 44, 250, 219, 39, 197, 61, 1, 211, 44, 252, 10, 39, 197, 61, 1, 211, 44, - 250, 209, 39, 197, 61, 1, 192, 68, 250, 209, 39, 197, 61, 1, 211, 44, - 234, 12, 39, 197, 61, 1, 192, 68, 234, 12, 39, 197, 61, 1, 211, 44, 250, - 182, 39, 197, 61, 1, 192, 68, 250, 182, 39, 197, 61, 1, 211, 44, 252, 7, - 39, 197, 61, 1, 192, 68, 252, 7, 39, 197, 61, 1, 211, 44, 211, 30, 39, - 197, 61, 1, 211, 44, 249, 71, 39, 177, 6, 1, 65, 39, 177, 6, 1, 252, 206, - 39, 177, 6, 1, 234, 199, 39, 177, 6, 1, 251, 144, 39, 177, 6, 1, 234, - 197, 39, 177, 6, 1, 234, 100, 39, 177, 6, 1, 234, 193, 39, 177, 6, 1, - 234, 192, 39, 177, 6, 1, 251, 125, 39, 177, 6, 1, 71, 39, 177, 6, 1, 242, - 220, 71, 39, 177, 6, 1, 234, 188, 39, 177, 6, 1, 234, 181, 39, 177, 6, 1, - 234, 180, 39, 177, 6, 1, 234, 176, 39, 177, 6, 1, 234, 173, 39, 177, 6, - 1, 68, 39, 177, 6, 1, 223, 199, 39, 177, 6, 1, 234, 150, 39, 177, 6, 1, - 234, 147, 39, 177, 6, 1, 251, 216, 39, 177, 6, 1, 196, 86, 39, 177, 6, 1, - 234, 140, 39, 177, 6, 1, 234, 117, 39, 177, 6, 1, 234, 114, 39, 177, 6, - 1, 234, 103, 39, 177, 6, 1, 234, 66, 39, 177, 6, 1, 74, 39, 177, 6, 1, - 211, 87, 39, 177, 6, 1, 213, 182, 211, 151, 39, 177, 6, 1, 206, 58, 211, - 151, 39, 177, 6, 1, 211, 150, 39, 177, 6, 1, 234, 56, 39, 177, 6, 1, 234, - 108, 39, 177, 6, 1, 234, 34, 39, 177, 6, 1, 203, 40, 234, 34, 39, 177, 6, - 1, 234, 22, 39, 177, 6, 1, 234, 1, 39, 177, 6, 1, 233, 255, 39, 177, 6, - 1, 234, 80, 39, 177, 6, 1, 233, 243, 39, 177, 6, 1, 234, 195, 39, 177, 6, - 1, 66, 39, 177, 6, 1, 196, 30, 39, 177, 6, 1, 213, 182, 196, 152, 39, - 177, 6, 1, 206, 58, 196, 152, 39, 177, 6, 1, 233, 230, 39, 177, 6, 1, - 233, 182, 39, 177, 6, 1, 233, 177, 39, 177, 6, 1, 234, 79, 56, 39, 177, - 6, 1, 196, 45, 39, 177, 2, 1, 65, 39, 177, 2, 1, 252, 206, 39, 177, 2, 1, - 234, 199, 39, 177, 2, 1, 251, 144, 39, 177, 2, 1, 234, 197, 39, 177, 2, - 1, 234, 100, 39, 177, 2, 1, 234, 193, 39, 177, 2, 1, 234, 192, 39, 177, - 2, 1, 251, 125, 39, 177, 2, 1, 71, 39, 177, 2, 1, 242, 220, 71, 39, 177, - 2, 1, 234, 188, 39, 177, 2, 1, 234, 181, 39, 177, 2, 1, 234, 180, 39, - 177, 2, 1, 234, 176, 39, 177, 2, 1, 234, 173, 39, 177, 2, 1, 68, 39, 177, - 2, 1, 223, 199, 39, 177, 2, 1, 234, 150, 39, 177, 2, 1, 234, 147, 39, - 177, 2, 1, 251, 216, 39, 177, 2, 1, 196, 86, 39, 177, 2, 1, 234, 140, 39, - 177, 2, 1, 234, 117, 39, 177, 2, 1, 234, 114, 39, 177, 2, 1, 234, 103, - 39, 177, 2, 1, 234, 66, 39, 177, 2, 1, 74, 39, 177, 2, 1, 211, 87, 39, - 177, 2, 1, 213, 182, 211, 151, 39, 177, 2, 1, 206, 58, 211, 151, 39, 177, - 2, 1, 211, 150, 39, 177, 2, 1, 234, 56, 39, 177, 2, 1, 234, 108, 39, 177, - 2, 1, 234, 34, 39, 177, 2, 1, 203, 40, 234, 34, 39, 177, 2, 1, 234, 22, - 39, 177, 2, 1, 234, 1, 39, 177, 2, 1, 233, 255, 39, 177, 2, 1, 234, 80, - 39, 177, 2, 1, 233, 243, 39, 177, 2, 1, 234, 195, 39, 177, 2, 1, 66, 39, - 177, 2, 1, 196, 30, 39, 177, 2, 1, 213, 182, 196, 152, 39, 177, 2, 1, - 206, 58, 196, 152, 39, 177, 2, 1, 233, 230, 39, 177, 2, 1, 233, 182, 39, - 177, 2, 1, 233, 177, 39, 177, 2, 1, 234, 79, 56, 39, 177, 2, 1, 196, 45, - 39, 177, 31, 107, 39, 177, 31, 149, 39, 177, 31, 199, 95, 39, 177, 31, - 233, 15, 39, 177, 31, 91, 228, 140, 39, 177, 31, 91, 189, 230, 24, 206, - 142, 1, 65, 230, 24, 206, 142, 1, 249, 153, 230, 24, 206, 142, 1, 168, - 230, 24, 206, 142, 1, 190, 190, 230, 24, 206, 142, 1, 197, 132, 230, 24, - 206, 142, 1, 223, 32, 230, 24, 206, 142, 1, 247, 160, 230, 24, 206, 142, - 1, 140, 230, 24, 206, 142, 1, 221, 215, 230, 24, 206, 142, 1, 233, 109, - 230, 24, 206, 142, 1, 238, 32, 230, 24, 206, 142, 1, 237, 191, 230, 24, - 206, 142, 1, 165, 230, 24, 206, 142, 1, 206, 109, 230, 24, 206, 142, 1, - 191, 123, 230, 24, 206, 142, 1, 188, 230, 24, 206, 142, 1, 203, 165, 230, - 24, 206, 142, 1, 155, 230, 24, 206, 142, 1, 231, 240, 230, 24, 206, 142, - 1, 173, 230, 24, 206, 142, 1, 174, 230, 24, 206, 142, 1, 180, 230, 24, - 206, 142, 1, 193, 190, 230, 24, 206, 142, 1, 221, 137, 193, 190, 230, 24, - 206, 142, 1, 170, 230, 24, 206, 142, 1, 221, 137, 170, 230, 24, 206, 142, - 1, 214, 68, 230, 24, 206, 142, 1, 212, 101, 230, 24, 206, 142, 1, 195, - 188, 230, 24, 206, 142, 18, 65, 230, 24, 206, 142, 18, 68, 230, 24, 206, - 142, 18, 66, 230, 24, 206, 142, 18, 71, 230, 24, 206, 142, 18, 74, 230, - 24, 206, 142, 87, 205, 173, 230, 24, 206, 142, 87, 215, 7, 221, 178, 230, - 24, 206, 142, 3, 230, 18, 230, 24, 206, 142, 3, 199, 218, 230, 24, 206, - 142, 3, 199, 192, 230, 24, 206, 142, 3, 199, 172, 230, 24, 206, 142, 17, - 191, 77, 230, 24, 206, 142, 17, 107, 230, 24, 206, 142, 17, 109, 230, 24, - 206, 142, 17, 138, 230, 24, 206, 142, 17, 134, 230, 24, 206, 142, 17, - 149, 230, 24, 206, 142, 17, 169, 230, 24, 206, 142, 17, 175, 230, 24, - 206, 142, 17, 171, 230, 24, 206, 142, 17, 178, 206, 46, 17, 107, 206, 46, - 17, 109, 206, 46, 17, 138, 206, 46, 17, 134, 206, 46, 17, 149, 206, 46, - 17, 169, 206, 46, 17, 175, 206, 46, 17, 171, 206, 46, 17, 178, 206, 46, - 31, 199, 95, 206, 46, 31, 197, 32, 206, 46, 31, 198, 249, 206, 46, 31, - 232, 135, 206, 46, 31, 233, 15, 206, 46, 31, 202, 120, 206, 46, 31, 203, - 241, 206, 46, 31, 234, 153, 206, 46, 31, 213, 169, 206, 46, 31, 91, 228, - 140, 206, 46, 31, 105, 228, 140, 206, 46, 31, 115, 228, 140, 206, 46, 31, - 232, 128, 228, 140, 206, 46, 31, 232, 226, 228, 140, 206, 46, 31, 202, - 136, 228, 140, 206, 46, 31, 203, 247, 228, 140, 206, 46, 31, 234, 164, - 228, 140, 206, 46, 31, 213, 175, 228, 140, 206, 46, 232, 118, 91, 230, - 70, 206, 46, 232, 118, 91, 208, 22, 206, 46, 232, 118, 91, 199, 0, 206, - 46, 232, 118, 105, 198, 253, 192, 39, 1, 234, 124, 192, 39, 1, 249, 17, - 192, 39, 1, 210, 63, 192, 39, 1, 209, 214, 192, 39, 1, 199, 33, 192, 39, - 1, 205, 68, 192, 39, 1, 243, 16, 192, 39, 1, 243, 83, 192, 39, 1, 243, - 97, 192, 39, 1, 229, 177, 192, 39, 1, 192, 220, 192, 39, 1, 238, 3, 192, - 39, 1, 191, 108, 192, 39, 1, 165, 192, 39, 1, 207, 6, 192, 39, 1, 191, - 123, 192, 39, 1, 223, 32, 192, 39, 1, 202, 174, 192, 39, 1, 203, 69, 192, - 39, 1, 205, 192, 192, 39, 1, 238, 26, 192, 39, 1, 190, 190, 192, 39, 1, - 191, 87, 192, 39, 1, 233, 184, 192, 39, 1, 192, 208, 192, 39, 1, 233, - 109, 192, 39, 1, 195, 188, 192, 39, 1, 195, 189, 251, 157, 20, 192, 39, - 1, 208, 89, 192, 39, 1, 222, 106, 192, 39, 1, 221, 212, 192, 39, 1, 231, - 227, 192, 39, 1, 220, 35, 192, 39, 1, 216, 46, 192, 39, 1, 212, 130, 192, - 39, 1, 196, 120, 192, 39, 1, 193, 133, 192, 39, 1, 210, 250, 192, 39, 1, - 233, 224, 192, 39, 1, 229, 252, 192, 39, 1, 191, 240, 192, 39, 1, 233, - 255, 192, 39, 33, 230, 58, 77, 192, 39, 33, 217, 142, 77, 192, 39, 228, - 86, 77, 192, 39, 1, 220, 36, 4, 75, 58, 192, 39, 1, 191, 241, 4, 243, 2, - 58, 9, 2, 130, 193, 23, 205, 171, 9, 2, 130, 193, 23, 208, 79, 9, 2, 130, - 193, 23, 217, 141, 39, 202, 28, 1, 251, 190, 39, 202, 28, 1, 53, 251, - 190, 39, 202, 28, 1, 248, 211, 39, 202, 28, 1, 53, 248, 211, 39, 202, 28, - 1, 231, 38, 39, 202, 28, 1, 229, 245, 39, 202, 28, 1, 53, 229, 245, 39, - 202, 28, 1, 193, 133, 39, 202, 28, 1, 191, 91, 39, 202, 28, 1, 229, 184, - 39, 202, 28, 1, 191, 249, 39, 202, 28, 1, 222, 75, 39, 202, 28, 1, 220, - 26, 39, 202, 28, 1, 216, 193, 39, 202, 28, 1, 212, 130, 39, 202, 28, 1, - 53, 212, 130, 39, 202, 28, 1, 53, 212, 131, 4, 81, 199, 215, 39, 202, 28, - 1, 205, 148, 39, 202, 28, 1, 250, 126, 39, 202, 28, 1, 251, 157, 250, - 126, 39, 202, 28, 1, 210, 63, 39, 202, 28, 1, 205, 189, 39, 202, 28, 1, - 53, 205, 189, 39, 202, 28, 1, 53, 205, 190, 4, 81, 199, 215, 39, 202, 28, - 1, 207, 36, 39, 202, 28, 1, 203, 69, 39, 202, 28, 1, 199, 159, 39, 202, - 28, 1, 53, 199, 159, 39, 202, 28, 1, 53, 199, 160, 4, 81, 199, 215, 39, - 202, 28, 31, 107, 39, 202, 28, 31, 109, 39, 202, 28, 31, 138, 39, 202, - 28, 31, 134, 39, 202, 28, 31, 149, 39, 202, 28, 31, 199, 95, 39, 202, 28, - 31, 197, 32, 39, 202, 28, 31, 198, 249, 39, 202, 28, 31, 91, 228, 140, - 39, 202, 28, 232, 118, 91, 230, 70, 39, 202, 28, 34, 250, 125, 202, 28, - 1, 251, 190, 202, 28, 1, 248, 211, 202, 28, 1, 231, 38, 202, 28, 1, 229, - 245, 202, 28, 1, 193, 133, 202, 28, 1, 191, 91, 202, 28, 1, 229, 184, - 202, 28, 1, 191, 249, 202, 28, 1, 222, 75, 202, 28, 1, 220, 26, 202, 28, - 1, 216, 193, 202, 28, 1, 212, 130, 202, 28, 1, 205, 148, 202, 28, 1, 250, - 126, 202, 28, 1, 210, 63, 202, 28, 1, 205, 189, 202, 28, 1, 207, 37, 202, - 28, 1, 203, 69, 202, 28, 1, 199, 159, 202, 28, 1, 233, 30, 202, 28, 1, - 219, 182, 202, 28, 223, 149, 203, 69, 202, 28, 33, 75, 60, 202, 28, 33, - 105, 185, 60, 202, 28, 33, 75, 58, 202, 28, 33, 105, 185, 58, 202, 28, - 33, 238, 165, 58, 202, 28, 33, 238, 165, 60, 202, 28, 33, 228, 251, 58, - 202, 28, 33, 228, 251, 60, 202, 28, 33, 179, 228, 251, 60, 202, 28, 33, - 207, 39, 60, 202, 28, 33, 201, 28, 60, 202, 28, 31, 107, 202, 28, 31, - 199, 95, 202, 28, 31, 197, 32, 202, 28, 31, 91, 228, 140, 202, 28, 208, - 152, 105, 81, 249, 76, 202, 28, 208, 152, 105, 81, 249, 77, 4, 236, 138, - 202, 28, 208, 152, 243, 11, 4, 236, 140, 202, 28, 208, 152, 105, 243, 8, - 4, 236, 138, 202, 28, 208, 152, 132, 243, 11, 4, 236, 140, 39, 196, 19, - 1, 251, 190, 39, 196, 19, 1, 248, 211, 39, 196, 19, 1, 231, 37, 39, 196, - 19, 1, 193, 133, 39, 196, 19, 1, 191, 91, 39, 196, 19, 1, 53, 229, 184, - 39, 196, 19, 1, 191, 249, 39, 196, 19, 1, 222, 75, 39, 196, 19, 1, 220, - 26, 39, 196, 19, 1, 216, 193, 39, 196, 19, 1, 212, 130, 39, 196, 19, 1, - 205, 148, 39, 196, 19, 1, 210, 63, 39, 196, 19, 1, 205, 189, 39, 196, 19, - 1, 207, 38, 39, 196, 19, 1, 203, 69, 39, 196, 19, 1, 199, 159, 39, 196, - 19, 1, 219, 182, 39, 196, 19, 33, 75, 58, 39, 196, 19, 33, 75, 60, 39, + 211, 46, 74, 39, 197, 61, 1, 211, 46, 211, 153, 39, 197, 61, 1, 192, 68, + 211, 153, 39, 197, 61, 1, 211, 46, 252, 157, 39, 197, 61, 1, 192, 68, + 252, 157, 39, 197, 61, 1, 211, 46, 252, 26, 39, 197, 61, 1, 192, 68, 252, + 26, 39, 197, 61, 1, 211, 46, 251, 255, 39, 197, 61, 1, 192, 68, 251, 255, + 39, 197, 61, 1, 211, 46, 252, 21, 39, 197, 61, 1, 192, 68, 252, 21, 39, + 197, 61, 1, 211, 46, 252, 44, 39, 197, 61, 1, 192, 68, 252, 44, 39, 197, + 61, 1, 211, 46, 252, 25, 39, 197, 61, 1, 211, 46, 233, 184, 39, 197, 61, + 1, 192, 68, 233, 184, 39, 197, 61, 1, 211, 46, 250, 133, 39, 197, 61, 1, + 192, 68, 250, 133, 39, 197, 61, 1, 211, 46, 252, 8, 39, 197, 61, 1, 192, + 68, 252, 8, 39, 197, 61, 1, 211, 46, 252, 19, 39, 197, 61, 1, 192, 68, + 252, 19, 39, 197, 61, 1, 211, 46, 211, 151, 39, 197, 61, 1, 192, 68, 211, + 151, 39, 197, 61, 1, 211, 46, 251, 209, 39, 197, 61, 1, 192, 68, 251, + 209, 39, 197, 61, 1, 211, 46, 252, 18, 39, 197, 61, 1, 211, 46, 234, 120, + 39, 197, 61, 1, 211, 46, 234, 116, 39, 197, 61, 1, 211, 46, 251, 134, 39, + 197, 61, 1, 211, 46, 252, 16, 39, 197, 61, 1, 192, 68, 252, 16, 39, 197, + 61, 1, 211, 46, 234, 82, 39, 197, 61, 1, 192, 68, 234, 82, 39, 197, 61, + 1, 211, 46, 234, 102, 39, 197, 61, 1, 192, 68, 234, 102, 39, 197, 61, 1, + 211, 46, 234, 68, 39, 197, 61, 1, 192, 68, 234, 68, 39, 197, 61, 1, 192, + 68, 251, 124, 39, 197, 61, 1, 211, 46, 234, 90, 39, 197, 61, 1, 192, 68, + 252, 15, 39, 197, 61, 1, 211, 46, 234, 58, 39, 197, 61, 1, 211, 46, 211, + 80, 39, 197, 61, 1, 211, 46, 228, 30, 39, 197, 61, 1, 211, 46, 234, 199, + 39, 197, 61, 1, 192, 68, 234, 199, 39, 197, 61, 1, 211, 46, 251, 39, 39, + 197, 61, 1, 192, 68, 251, 39, 39, 197, 61, 1, 211, 46, 223, 81, 39, 197, + 61, 1, 192, 68, 223, 81, 39, 197, 61, 1, 211, 46, 211, 60, 39, 197, 61, + 1, 192, 68, 211, 60, 39, 197, 61, 1, 211, 46, 251, 35, 39, 197, 61, 1, + 192, 68, 251, 35, 39, 197, 61, 1, 211, 46, 252, 14, 39, 197, 61, 1, 211, + 46, 250, 221, 39, 197, 61, 1, 211, 46, 252, 12, 39, 197, 61, 1, 211, 46, + 250, 211, 39, 197, 61, 1, 192, 68, 250, 211, 39, 197, 61, 1, 211, 46, + 234, 14, 39, 197, 61, 1, 192, 68, 234, 14, 39, 197, 61, 1, 211, 46, 250, + 184, 39, 197, 61, 1, 192, 68, 250, 184, 39, 197, 61, 1, 211, 46, 252, 9, + 39, 197, 61, 1, 192, 68, 252, 9, 39, 197, 61, 1, 211, 46, 211, 32, 39, + 197, 61, 1, 211, 46, 249, 73, 39, 177, 6, 1, 65, 39, 177, 6, 1, 252, 208, + 39, 177, 6, 1, 234, 201, 39, 177, 6, 1, 251, 146, 39, 177, 6, 1, 234, + 199, 39, 177, 6, 1, 234, 102, 39, 177, 6, 1, 234, 195, 39, 177, 6, 1, + 234, 194, 39, 177, 6, 1, 251, 127, 39, 177, 6, 1, 71, 39, 177, 6, 1, 242, + 222, 71, 39, 177, 6, 1, 234, 190, 39, 177, 6, 1, 234, 183, 39, 177, 6, 1, + 234, 182, 39, 177, 6, 1, 234, 178, 39, 177, 6, 1, 234, 175, 39, 177, 6, + 1, 68, 39, 177, 6, 1, 223, 201, 39, 177, 6, 1, 234, 152, 39, 177, 6, 1, + 234, 149, 39, 177, 6, 1, 251, 218, 39, 177, 6, 1, 196, 86, 39, 177, 6, 1, + 234, 142, 39, 177, 6, 1, 234, 119, 39, 177, 6, 1, 234, 116, 39, 177, 6, + 1, 234, 105, 39, 177, 6, 1, 234, 68, 39, 177, 6, 1, 74, 39, 177, 6, 1, + 211, 89, 39, 177, 6, 1, 213, 184, 211, 153, 39, 177, 6, 1, 206, 59, 211, + 153, 39, 177, 6, 1, 211, 152, 39, 177, 6, 1, 234, 58, 39, 177, 6, 1, 234, + 110, 39, 177, 6, 1, 234, 36, 39, 177, 6, 1, 203, 41, 234, 36, 39, 177, 6, + 1, 234, 24, 39, 177, 6, 1, 234, 3, 39, 177, 6, 1, 234, 1, 39, 177, 6, 1, + 234, 82, 39, 177, 6, 1, 233, 245, 39, 177, 6, 1, 234, 197, 39, 177, 6, 1, + 66, 39, 177, 6, 1, 196, 30, 39, 177, 6, 1, 213, 184, 196, 152, 39, 177, + 6, 1, 206, 59, 196, 152, 39, 177, 6, 1, 233, 232, 39, 177, 6, 1, 233, + 184, 39, 177, 6, 1, 233, 179, 39, 177, 6, 1, 234, 81, 56, 39, 177, 6, 1, + 196, 45, 39, 177, 2, 1, 65, 39, 177, 2, 1, 252, 208, 39, 177, 2, 1, 234, + 201, 39, 177, 2, 1, 251, 146, 39, 177, 2, 1, 234, 199, 39, 177, 2, 1, + 234, 102, 39, 177, 2, 1, 234, 195, 39, 177, 2, 1, 234, 194, 39, 177, 2, + 1, 251, 127, 39, 177, 2, 1, 71, 39, 177, 2, 1, 242, 222, 71, 39, 177, 2, + 1, 234, 190, 39, 177, 2, 1, 234, 183, 39, 177, 2, 1, 234, 182, 39, 177, + 2, 1, 234, 178, 39, 177, 2, 1, 234, 175, 39, 177, 2, 1, 68, 39, 177, 2, + 1, 223, 201, 39, 177, 2, 1, 234, 152, 39, 177, 2, 1, 234, 149, 39, 177, + 2, 1, 251, 218, 39, 177, 2, 1, 196, 86, 39, 177, 2, 1, 234, 142, 39, 177, + 2, 1, 234, 119, 39, 177, 2, 1, 234, 116, 39, 177, 2, 1, 234, 105, 39, + 177, 2, 1, 234, 68, 39, 177, 2, 1, 74, 39, 177, 2, 1, 211, 89, 39, 177, + 2, 1, 213, 184, 211, 153, 39, 177, 2, 1, 206, 59, 211, 153, 39, 177, 2, + 1, 211, 152, 39, 177, 2, 1, 234, 58, 39, 177, 2, 1, 234, 110, 39, 177, 2, + 1, 234, 36, 39, 177, 2, 1, 203, 41, 234, 36, 39, 177, 2, 1, 234, 24, 39, + 177, 2, 1, 234, 3, 39, 177, 2, 1, 234, 1, 39, 177, 2, 1, 234, 82, 39, + 177, 2, 1, 233, 245, 39, 177, 2, 1, 234, 197, 39, 177, 2, 1, 66, 39, 177, + 2, 1, 196, 30, 39, 177, 2, 1, 213, 184, 196, 152, 39, 177, 2, 1, 206, 59, + 196, 152, 39, 177, 2, 1, 233, 232, 39, 177, 2, 1, 233, 184, 39, 177, 2, + 1, 233, 179, 39, 177, 2, 1, 234, 81, 56, 39, 177, 2, 1, 196, 45, 39, 177, + 31, 107, 39, 177, 31, 150, 39, 177, 31, 199, 95, 39, 177, 31, 233, 17, + 39, 177, 31, 91, 228, 142, 39, 177, 31, 91, 189, 230, 26, 206, 143, 1, + 65, 230, 26, 206, 143, 1, 249, 155, 230, 26, 206, 143, 1, 168, 230, 26, + 206, 143, 1, 190, 190, 230, 26, 206, 143, 1, 197, 132, 230, 26, 206, 143, + 1, 223, 34, 230, 26, 206, 143, 1, 247, 162, 230, 26, 206, 143, 1, 140, + 230, 26, 206, 143, 1, 221, 217, 230, 26, 206, 143, 1, 233, 111, 230, 26, + 206, 143, 1, 238, 34, 230, 26, 206, 143, 1, 237, 193, 230, 26, 206, 143, + 1, 165, 230, 26, 206, 143, 1, 206, 110, 230, 26, 206, 143, 1, 191, 123, + 230, 26, 206, 143, 1, 188, 230, 26, 206, 143, 1, 203, 166, 230, 26, 206, + 143, 1, 155, 230, 26, 206, 143, 1, 231, 242, 230, 26, 206, 143, 1, 173, + 230, 26, 206, 143, 1, 174, 230, 26, 206, 143, 1, 181, 230, 26, 206, 143, + 1, 193, 190, 230, 26, 206, 143, 1, 221, 139, 193, 190, 230, 26, 206, 143, + 1, 170, 230, 26, 206, 143, 1, 221, 139, 170, 230, 26, 206, 143, 1, 214, + 70, 230, 26, 206, 143, 1, 212, 103, 230, 26, 206, 143, 1, 195, 188, 230, + 26, 206, 143, 18, 65, 230, 26, 206, 143, 18, 68, 230, 26, 206, 143, 18, + 66, 230, 26, 206, 143, 18, 71, 230, 26, 206, 143, 18, 74, 230, 26, 206, + 143, 87, 205, 174, 230, 26, 206, 143, 87, 215, 9, 221, 180, 230, 26, 206, + 143, 3, 230, 20, 230, 26, 206, 143, 3, 199, 218, 230, 26, 206, 143, 3, + 199, 192, 230, 26, 206, 143, 3, 199, 172, 230, 26, 206, 143, 17, 191, 77, + 230, 26, 206, 143, 17, 107, 230, 26, 206, 143, 17, 109, 230, 26, 206, + 143, 17, 138, 230, 26, 206, 143, 17, 134, 230, 26, 206, 143, 17, 150, + 230, 26, 206, 143, 17, 169, 230, 26, 206, 143, 17, 175, 230, 26, 206, + 143, 17, 171, 230, 26, 206, 143, 17, 178, 206, 47, 17, 107, 206, 47, 17, + 109, 206, 47, 17, 138, 206, 47, 17, 134, 206, 47, 17, 150, 206, 47, 17, + 169, 206, 47, 17, 175, 206, 47, 17, 171, 206, 47, 17, 178, 206, 47, 31, + 199, 95, 206, 47, 31, 197, 32, 206, 47, 31, 198, 249, 206, 47, 31, 232, + 137, 206, 47, 31, 233, 17, 206, 47, 31, 202, 121, 206, 47, 31, 203, 242, + 206, 47, 31, 234, 155, 206, 47, 31, 213, 171, 206, 47, 31, 91, 228, 142, + 206, 47, 31, 105, 228, 142, 206, 47, 31, 115, 228, 142, 206, 47, 31, 232, + 130, 228, 142, 206, 47, 31, 232, 228, 228, 142, 206, 47, 31, 202, 137, + 228, 142, 206, 47, 31, 203, 248, 228, 142, 206, 47, 31, 234, 166, 228, + 142, 206, 47, 31, 213, 177, 228, 142, 206, 47, 232, 120, 91, 230, 72, + 206, 47, 232, 120, 91, 208, 24, 206, 47, 232, 120, 91, 199, 0, 206, 47, + 232, 120, 105, 198, 253, 192, 39, 1, 234, 126, 192, 39, 1, 249, 19, 192, + 39, 1, 210, 65, 192, 39, 1, 209, 216, 192, 39, 1, 199, 33, 192, 39, 1, + 205, 69, 192, 39, 1, 243, 18, 192, 39, 1, 243, 85, 192, 39, 1, 243, 99, + 192, 39, 1, 229, 179, 192, 39, 1, 192, 220, 192, 39, 1, 238, 5, 192, 39, + 1, 191, 108, 192, 39, 1, 165, 192, 39, 1, 207, 7, 192, 39, 1, 191, 123, + 192, 39, 1, 223, 34, 192, 39, 1, 202, 175, 192, 39, 1, 203, 70, 192, 39, + 1, 205, 193, 192, 39, 1, 238, 28, 192, 39, 1, 190, 190, 192, 39, 1, 191, + 87, 192, 39, 1, 233, 186, 192, 39, 1, 192, 208, 192, 39, 1, 233, 111, + 192, 39, 1, 195, 188, 192, 39, 1, 195, 189, 251, 159, 20, 192, 39, 1, + 208, 91, 192, 39, 1, 222, 108, 192, 39, 1, 221, 214, 192, 39, 1, 231, + 229, 192, 39, 1, 220, 37, 192, 39, 1, 216, 48, 192, 39, 1, 212, 132, 192, + 39, 1, 196, 120, 192, 39, 1, 193, 133, 192, 39, 1, 210, 252, 192, 39, 1, + 233, 226, 192, 39, 1, 229, 254, 192, 39, 1, 191, 240, 192, 39, 1, 234, 1, + 192, 39, 33, 230, 60, 77, 192, 39, 33, 217, 144, 77, 192, 39, 228, 88, + 77, 192, 39, 1, 220, 38, 4, 75, 58, 192, 39, 1, 191, 241, 4, 243, 4, 58, + 9, 2, 130, 193, 23, 205, 172, 9, 2, 130, 193, 23, 208, 81, 9, 2, 130, + 193, 23, 217, 143, 39, 202, 29, 1, 251, 192, 39, 202, 29, 1, 53, 251, + 192, 39, 202, 29, 1, 248, 213, 39, 202, 29, 1, 53, 248, 213, 39, 202, 29, + 1, 231, 40, 39, 202, 29, 1, 229, 247, 39, 202, 29, 1, 53, 229, 247, 39, + 202, 29, 1, 193, 133, 39, 202, 29, 1, 191, 91, 39, 202, 29, 1, 229, 186, + 39, 202, 29, 1, 191, 249, 39, 202, 29, 1, 222, 77, 39, 202, 29, 1, 220, + 28, 39, 202, 29, 1, 216, 195, 39, 202, 29, 1, 212, 132, 39, 202, 29, 1, + 53, 212, 132, 39, 202, 29, 1, 53, 212, 133, 4, 81, 199, 215, 39, 202, 29, + 1, 205, 149, 39, 202, 29, 1, 250, 128, 39, 202, 29, 1, 251, 159, 250, + 128, 39, 202, 29, 1, 210, 65, 39, 202, 29, 1, 205, 190, 39, 202, 29, 1, + 53, 205, 190, 39, 202, 29, 1, 53, 205, 191, 4, 81, 199, 215, 39, 202, 29, + 1, 207, 37, 39, 202, 29, 1, 203, 70, 39, 202, 29, 1, 199, 159, 39, 202, + 29, 1, 53, 199, 159, 39, 202, 29, 1, 53, 199, 160, 4, 81, 199, 215, 39, + 202, 29, 31, 107, 39, 202, 29, 31, 109, 39, 202, 29, 31, 138, 39, 202, + 29, 31, 134, 39, 202, 29, 31, 150, 39, 202, 29, 31, 199, 95, 39, 202, 29, + 31, 197, 32, 39, 202, 29, 31, 198, 249, 39, 202, 29, 31, 91, 228, 142, + 39, 202, 29, 232, 120, 91, 230, 72, 39, 202, 29, 34, 250, 127, 202, 29, + 1, 251, 192, 202, 29, 1, 248, 213, 202, 29, 1, 231, 40, 202, 29, 1, 229, + 247, 202, 29, 1, 193, 133, 202, 29, 1, 191, 91, 202, 29, 1, 229, 186, + 202, 29, 1, 191, 249, 202, 29, 1, 222, 77, 202, 29, 1, 220, 28, 202, 29, + 1, 216, 195, 202, 29, 1, 212, 132, 202, 29, 1, 205, 149, 202, 29, 1, 250, + 128, 202, 29, 1, 210, 65, 202, 29, 1, 205, 190, 202, 29, 1, 207, 38, 202, + 29, 1, 203, 70, 202, 29, 1, 199, 159, 202, 29, 1, 233, 32, 202, 29, 1, + 219, 184, 202, 29, 223, 151, 203, 70, 202, 29, 33, 75, 60, 202, 29, 33, + 105, 185, 60, 202, 29, 33, 75, 58, 202, 29, 33, 105, 185, 58, 202, 29, + 33, 238, 167, 58, 202, 29, 33, 238, 167, 60, 202, 29, 33, 228, 253, 58, + 202, 29, 33, 228, 253, 60, 202, 29, 33, 180, 228, 253, 60, 202, 29, 33, + 207, 40, 60, 202, 29, 33, 201, 29, 60, 202, 29, 31, 107, 202, 29, 31, + 199, 95, 202, 29, 31, 197, 32, 202, 29, 31, 91, 228, 142, 202, 29, 208, + 154, 105, 81, 249, 78, 202, 29, 208, 154, 105, 81, 249, 79, 4, 236, 140, + 202, 29, 208, 154, 243, 13, 4, 236, 142, 202, 29, 208, 154, 105, 243, 10, + 4, 236, 140, 202, 29, 208, 154, 132, 243, 13, 4, 236, 142, 39, 196, 19, + 1, 251, 192, 39, 196, 19, 1, 248, 213, 39, 196, 19, 1, 231, 39, 39, 196, + 19, 1, 193, 133, 39, 196, 19, 1, 191, 91, 39, 196, 19, 1, 53, 229, 186, + 39, 196, 19, 1, 191, 249, 39, 196, 19, 1, 222, 77, 39, 196, 19, 1, 220, + 28, 39, 196, 19, 1, 216, 195, 39, 196, 19, 1, 212, 132, 39, 196, 19, 1, + 205, 149, 39, 196, 19, 1, 210, 65, 39, 196, 19, 1, 205, 190, 39, 196, 19, + 1, 207, 39, 39, 196, 19, 1, 203, 70, 39, 196, 19, 1, 199, 159, 39, 196, + 19, 1, 219, 184, 39, 196, 19, 33, 75, 58, 39, 196, 19, 33, 75, 60, 39, 196, 19, 33, 105, 185, 58, 39, 196, 19, 33, 105, 185, 60, 39, 196, 19, - 208, 152, 164, 39, 196, 19, 208, 152, 105, 249, 76, 39, 196, 19, 208, - 152, 105, 236, 138, 39, 196, 19, 208, 152, 232, 128, 236, 138, 243, 61, - 1, 251, 190, 243, 61, 1, 2, 251, 190, 243, 61, 1, 248, 211, 243, 61, 1, - 231, 38, 243, 61, 1, 237, 252, 243, 61, 1, 229, 245, 243, 61, 1, 193, - 133, 243, 61, 1, 238, 174, 193, 133, 243, 61, 1, 191, 91, 243, 61, 1, - 229, 184, 243, 61, 1, 191, 249, 243, 61, 1, 222, 75, 243, 61, 1, 220, 26, - 243, 61, 1, 216, 193, 243, 61, 1, 212, 130, 243, 61, 1, 205, 148, 243, - 61, 1, 250, 126, 243, 61, 1, 210, 63, 243, 61, 1, 207, 38, 243, 61, 1, - 203, 69, 243, 61, 1, 199, 159, 243, 61, 31, 107, 243, 61, 31, 109, 243, - 61, 31, 138, 243, 61, 31, 134, 243, 61, 31, 199, 95, 243, 61, 31, 197, - 32, 243, 61, 31, 91, 228, 140, 234, 116, 1, 251, 190, 234, 116, 1, 248, - 211, 234, 116, 1, 231, 38, 234, 116, 1, 237, 252, 234, 116, 1, 229, 245, - 234, 116, 1, 193, 133, 234, 116, 1, 191, 91, 234, 116, 1, 229, 184, 234, - 116, 1, 199, 69, 234, 116, 1, 191, 249, 234, 116, 1, 222, 75, 234, 116, - 1, 220, 26, 234, 116, 1, 216, 193, 234, 116, 1, 212, 130, 234, 116, 1, - 205, 148, 234, 116, 1, 250, 126, 234, 116, 1, 210, 63, 234, 116, 1, 205, - 189, 234, 116, 1, 208, 37, 234, 116, 1, 207, 38, 234, 116, 1, 203, 69, - 234, 116, 1, 199, 159, 234, 116, 34, 191, 90, 162, 3, 247, 119, 162, 3, - 251, 71, 162, 3, 195, 35, 162, 3, 222, 237, 162, 3, 196, 75, 162, 1, 65, - 162, 1, 252, 206, 162, 1, 68, 162, 1, 223, 199, 162, 1, 66, 162, 1, 196, - 30, 162, 1, 117, 146, 162, 1, 117, 206, 110, 162, 1, 117, 172, 162, 1, - 117, 219, 74, 162, 1, 71, 162, 1, 251, 236, 162, 1, 74, 162, 1, 250, 163, - 162, 1, 155, 162, 1, 221, 215, 162, 1, 231, 240, 162, 1, 231, 91, 162, 1, - 214, 68, 162, 1, 247, 160, 162, 1, 247, 1, 162, 1, 223, 32, 162, 1, 222, - 252, 162, 1, 212, 101, 162, 1, 197, 132, 162, 1, 197, 120, 162, 1, 237, - 191, 162, 1, 237, 175, 162, 1, 213, 79, 162, 1, 190, 190, 162, 1, 199, - 49, 162, 1, 238, 32, 162, 1, 237, 68, 162, 1, 180, 162, 1, 168, 162, 1, - 209, 228, 162, 1, 249, 153, 162, 1, 248, 203, 162, 1, 174, 162, 1, 170, - 162, 1, 165, 162, 1, 173, 162, 1, 195, 188, 162, 1, 203, 165, 162, 1, - 201, 175, 162, 1, 188, 162, 1, 140, 162, 1, 219, 73, 162, 1, 39, 44, 219, - 62, 162, 1, 39, 44, 206, 109, 162, 1, 39, 44, 213, 61, 162, 18, 3, 252, - 206, 162, 18, 3, 248, 197, 252, 206, 162, 18, 3, 68, 162, 18, 3, 223, - 199, 162, 18, 3, 66, 162, 18, 3, 196, 30, 162, 18, 3, 117, 146, 162, 18, - 3, 117, 206, 110, 162, 18, 3, 117, 172, 162, 18, 3, 117, 219, 74, 162, - 18, 3, 71, 162, 18, 3, 251, 236, 162, 18, 3, 74, 162, 18, 3, 250, 163, - 162, 195, 40, 162, 237, 238, 162, 55, 237, 238, 162, 208, 152, 236, 140, - 162, 208, 152, 55, 236, 140, 162, 208, 152, 219, 112, 162, 208, 152, 238, - 228, 164, 162, 208, 152, 218, 246, 162, 31, 107, 162, 31, 109, 162, 31, - 138, 162, 31, 134, 162, 31, 149, 162, 31, 169, 162, 31, 175, 162, 31, + 208, 154, 164, 39, 196, 19, 208, 154, 105, 249, 78, 39, 196, 19, 208, + 154, 105, 236, 140, 39, 196, 19, 208, 154, 232, 130, 236, 140, 243, 63, + 1, 251, 192, 243, 63, 1, 2, 251, 192, 243, 63, 1, 248, 213, 243, 63, 1, + 231, 40, 243, 63, 1, 237, 254, 243, 63, 1, 229, 247, 243, 63, 1, 193, + 133, 243, 63, 1, 238, 176, 193, 133, 243, 63, 1, 191, 91, 243, 63, 1, + 229, 186, 243, 63, 1, 191, 249, 243, 63, 1, 222, 77, 243, 63, 1, 220, 28, + 243, 63, 1, 216, 195, 243, 63, 1, 212, 132, 243, 63, 1, 205, 149, 243, + 63, 1, 250, 128, 243, 63, 1, 210, 65, 243, 63, 1, 207, 39, 243, 63, 1, + 203, 70, 243, 63, 1, 199, 159, 243, 63, 31, 107, 243, 63, 31, 109, 243, + 63, 31, 138, 243, 63, 31, 134, 243, 63, 31, 199, 95, 243, 63, 31, 197, + 32, 243, 63, 31, 91, 228, 142, 234, 118, 1, 251, 192, 234, 118, 1, 248, + 213, 234, 118, 1, 231, 40, 234, 118, 1, 237, 254, 234, 118, 1, 229, 247, + 234, 118, 1, 193, 133, 234, 118, 1, 191, 91, 234, 118, 1, 229, 186, 234, + 118, 1, 199, 69, 234, 118, 1, 191, 249, 234, 118, 1, 222, 77, 234, 118, + 1, 220, 28, 234, 118, 1, 216, 195, 234, 118, 1, 212, 132, 234, 118, 1, + 205, 149, 234, 118, 1, 250, 128, 234, 118, 1, 210, 65, 234, 118, 1, 205, + 190, 234, 118, 1, 208, 39, 234, 118, 1, 207, 39, 234, 118, 1, 203, 70, + 234, 118, 1, 199, 159, 234, 118, 34, 191, 90, 162, 3, 247, 121, 162, 3, + 251, 73, 162, 3, 195, 35, 162, 3, 222, 239, 162, 3, 196, 75, 162, 1, 65, + 162, 1, 252, 208, 162, 1, 68, 162, 1, 223, 201, 162, 1, 66, 162, 1, 196, + 30, 162, 1, 117, 146, 162, 1, 117, 206, 111, 162, 1, 117, 172, 162, 1, + 117, 219, 76, 162, 1, 71, 162, 1, 251, 238, 162, 1, 74, 162, 1, 250, 165, + 162, 1, 155, 162, 1, 221, 217, 162, 1, 231, 242, 162, 1, 231, 93, 162, 1, + 214, 70, 162, 1, 247, 162, 162, 1, 247, 3, 162, 1, 223, 34, 162, 1, 222, + 254, 162, 1, 212, 103, 162, 1, 197, 132, 162, 1, 197, 120, 162, 1, 237, + 193, 162, 1, 237, 177, 162, 1, 213, 81, 162, 1, 190, 190, 162, 1, 199, + 49, 162, 1, 238, 34, 162, 1, 237, 70, 162, 1, 181, 162, 1, 168, 162, 1, + 209, 230, 162, 1, 249, 155, 162, 1, 248, 205, 162, 1, 174, 162, 1, 170, + 162, 1, 165, 162, 1, 173, 162, 1, 195, 188, 162, 1, 203, 166, 162, 1, + 201, 176, 162, 1, 188, 162, 1, 140, 162, 1, 219, 75, 162, 1, 39, 44, 219, + 64, 162, 1, 39, 44, 206, 110, 162, 1, 39, 44, 213, 63, 162, 18, 3, 252, + 208, 162, 18, 3, 248, 199, 252, 208, 162, 18, 3, 68, 162, 18, 3, 223, + 201, 162, 18, 3, 66, 162, 18, 3, 196, 30, 162, 18, 3, 117, 146, 162, 18, + 3, 117, 206, 111, 162, 18, 3, 117, 172, 162, 18, 3, 117, 219, 76, 162, + 18, 3, 71, 162, 18, 3, 251, 238, 162, 18, 3, 74, 162, 18, 3, 250, 165, + 162, 195, 40, 162, 237, 240, 162, 55, 237, 240, 162, 208, 154, 236, 142, + 162, 208, 154, 55, 236, 142, 162, 208, 154, 219, 114, 162, 208, 154, 238, + 230, 164, 162, 208, 154, 218, 248, 162, 31, 107, 162, 31, 109, 162, 31, + 138, 162, 31, 134, 162, 31, 150, 162, 31, 169, 162, 31, 175, 162, 31, 171, 162, 31, 178, 162, 31, 199, 95, 162, 31, 197, 32, 162, 31, 198, 249, - 162, 31, 232, 135, 162, 31, 233, 15, 162, 31, 202, 120, 162, 31, 203, - 241, 162, 31, 234, 153, 162, 31, 213, 169, 162, 31, 91, 228, 140, 162, + 162, 31, 232, 137, 162, 31, 233, 17, 162, 31, 202, 121, 162, 31, 203, + 242, 162, 31, 234, 155, 162, 31, 213, 171, 162, 31, 91, 228, 142, 162, 31, 91, 189, 162, 17, 191, 77, 162, 17, 107, 162, 17, 109, 162, 17, 138, - 162, 17, 134, 162, 17, 149, 162, 17, 169, 162, 17, 175, 162, 17, 171, - 162, 17, 178, 162, 3, 39, 44, 195, 40, 162, 1, 39, 44, 203, 40, 71, 162, - 1, 39, 44, 203, 40, 74, 162, 18, 3, 39, 44, 203, 40, 71, 162, 18, 3, 39, - 44, 203, 40, 74, 162, 1, 39, 44, 219, 73, 162, 31, 222, 196, 222, 99, 3, - 247, 119, 222, 99, 3, 251, 71, 222, 99, 3, 195, 35, 222, 99, 1, 65, 222, - 99, 1, 252, 206, 222, 99, 1, 68, 222, 99, 1, 223, 199, 222, 99, 1, 66, - 222, 99, 1, 196, 30, 222, 99, 1, 71, 222, 99, 1, 251, 236, 222, 99, 1, - 74, 222, 99, 1, 250, 163, 222, 99, 1, 155, 222, 99, 1, 221, 215, 222, 99, - 1, 231, 240, 222, 99, 1, 231, 91, 222, 99, 1, 214, 68, 222, 99, 1, 247, - 160, 222, 99, 1, 247, 1, 222, 99, 1, 223, 32, 222, 99, 1, 222, 252, 222, - 99, 1, 212, 101, 222, 99, 1, 197, 132, 222, 99, 1, 197, 120, 222, 99, 1, - 237, 191, 222, 99, 1, 237, 180, 222, 99, 1, 237, 175, 222, 99, 1, 207, 6, - 222, 99, 1, 213, 79, 222, 99, 1, 190, 190, 222, 99, 1, 199, 49, 222, 99, - 1, 238, 32, 222, 99, 1, 237, 68, 222, 99, 1, 180, 222, 99, 1, 168, 222, - 99, 1, 209, 228, 222, 99, 1, 249, 153, 222, 99, 1, 248, 203, 222, 99, 1, - 174, 222, 99, 1, 170, 222, 99, 1, 165, 222, 99, 1, 173, 222, 99, 1, 195, - 188, 222, 99, 1, 203, 165, 222, 99, 1, 201, 175, 222, 99, 1, 188, 222, - 99, 1, 140, 222, 99, 18, 3, 252, 206, 222, 99, 18, 3, 68, 222, 99, 18, 3, - 223, 199, 222, 99, 18, 3, 66, 222, 99, 18, 3, 196, 30, 222, 99, 18, 3, - 71, 222, 99, 18, 3, 251, 236, 222, 99, 18, 3, 74, 222, 99, 18, 3, 250, - 163, 222, 99, 3, 195, 40, 222, 99, 3, 212, 141, 222, 99, 252, 68, 56, - 222, 99, 234, 69, 56, 222, 99, 31, 56, 222, 99, 205, 54, 77, 222, 99, 55, - 205, 54, 77, 222, 99, 237, 238, 222, 99, 55, 237, 238, 222, 99, 18, 3, - 117, 146, 222, 99, 31, 3, 58, 202, 12, 202, 20, 1, 205, 182, 202, 12, - 202, 20, 1, 199, 219, 202, 12, 202, 20, 1, 249, 123, 202, 12, 202, 20, 1, - 247, 149, 202, 12, 202, 20, 1, 238, 12, 202, 12, 202, 20, 1, 231, 225, - 202, 12, 202, 20, 1, 217, 120, 202, 12, 202, 20, 1, 214, 65, 202, 12, - 202, 20, 1, 220, 99, 202, 12, 202, 20, 1, 214, 237, 202, 12, 202, 20, 1, - 195, 184, 202, 12, 202, 20, 1, 210, 200, 202, 12, 202, 20, 1, 192, 121, - 202, 12, 202, 20, 1, 207, 160, 202, 12, 202, 20, 1, 230, 81, 202, 12, - 202, 20, 1, 222, 104, 202, 12, 202, 20, 1, 223, 26, 202, 12, 202, 20, 1, - 212, 98, 202, 12, 202, 20, 1, 251, 245, 202, 12, 202, 20, 1, 234, 186, - 202, 12, 202, 20, 1, 223, 200, 202, 12, 202, 20, 1, 196, 141, 202, 12, - 202, 20, 1, 211, 136, 202, 12, 202, 20, 1, 234, 173, 202, 12, 202, 20, 1, - 217, 136, 202, 12, 202, 20, 17, 191, 77, 202, 12, 202, 20, 17, 107, 202, - 12, 202, 20, 17, 109, 202, 12, 202, 20, 17, 138, 202, 12, 202, 20, 17, - 134, 202, 12, 202, 20, 17, 149, 202, 12, 202, 20, 17, 169, 202, 12, 202, - 20, 17, 175, 202, 12, 202, 20, 17, 171, 202, 12, 202, 20, 17, 178, 246, - 251, 3, 247, 119, 246, 251, 3, 251, 71, 246, 251, 3, 195, 35, 246, 251, - 1, 252, 206, 246, 251, 1, 68, 246, 251, 1, 66, 246, 251, 1, 71, 246, 251, - 1, 222, 127, 246, 251, 1, 221, 214, 246, 251, 1, 231, 237, 246, 251, 1, - 231, 90, 246, 251, 1, 214, 67, 246, 251, 1, 247, 159, 246, 251, 1, 247, - 0, 246, 251, 1, 223, 31, 246, 251, 1, 222, 251, 246, 251, 1, 212, 100, - 246, 251, 1, 197, 131, 246, 251, 1, 197, 119, 246, 251, 1, 237, 190, 246, - 251, 1, 237, 174, 246, 251, 1, 213, 78, 246, 251, 1, 199, 245, 246, 251, - 1, 199, 48, 246, 251, 1, 238, 31, 246, 251, 1, 237, 67, 246, 251, 1, 214, - 250, 246, 251, 1, 210, 220, 246, 251, 1, 209, 227, 246, 251, 1, 249, 151, - 246, 251, 1, 248, 202, 246, 251, 1, 217, 151, 246, 251, 1, 191, 174, 246, - 251, 1, 192, 140, 246, 251, 1, 207, 178, 246, 251, 1, 220, 125, 246, 251, - 1, 193, 181, 246, 251, 1, 205, 197, 246, 251, 1, 230, 91, 246, 251, 18, - 3, 65, 246, 251, 18, 3, 68, 246, 251, 18, 3, 223, 199, 246, 251, 18, 3, - 66, 246, 251, 18, 3, 196, 30, 246, 251, 18, 3, 71, 246, 251, 18, 3, 251, - 236, 246, 251, 18, 3, 74, 246, 251, 18, 3, 250, 163, 246, 251, 18, 3, - 211, 133, 246, 251, 187, 77, 246, 251, 250, 164, 77, 246, 251, 195, 40, - 246, 251, 217, 149, 246, 251, 17, 191, 77, 246, 251, 17, 107, 246, 251, - 17, 109, 246, 251, 17, 138, 246, 251, 17, 134, 246, 251, 17, 149, 246, - 251, 17, 169, 246, 251, 17, 175, 246, 251, 17, 171, 246, 251, 17, 178, - 246, 251, 205, 54, 77, 246, 251, 237, 238, 246, 251, 55, 237, 238, 246, - 251, 208, 13, 77, 246, 251, 1, 219, 158, 246, 251, 18, 3, 252, 206, 246, - 251, 18, 3, 234, 166, 246, 251, 1, 195, 187, 217, 118, 1, 65, 217, 118, - 1, 68, 217, 118, 1, 66, 217, 118, 1, 71, 217, 118, 1, 74, 217, 118, 1, - 155, 217, 118, 1, 221, 215, 217, 118, 1, 231, 240, 217, 118, 1, 231, 91, - 217, 118, 1, 247, 160, 217, 118, 1, 247, 1, 217, 118, 1, 223, 32, 217, - 118, 1, 222, 252, 217, 118, 1, 212, 101, 217, 118, 1, 197, 132, 217, 118, - 1, 197, 120, 217, 118, 1, 237, 191, 217, 118, 1, 237, 175, 217, 118, 1, - 213, 79, 217, 118, 1, 190, 190, 217, 118, 1, 199, 49, 217, 118, 1, 238, - 32, 217, 118, 1, 237, 68, 217, 118, 1, 180, 217, 118, 1, 168, 217, 118, - 1, 209, 228, 217, 118, 1, 249, 153, 217, 118, 1, 248, 203, 217, 118, 1, - 174, 217, 118, 1, 165, 217, 118, 1, 173, 217, 118, 1, 195, 188, 217, 118, - 1, 188, 217, 118, 1, 140, 217, 118, 1, 206, 109, 217, 118, 3, 212, 141, - 217, 118, 252, 68, 56, 217, 118, 205, 54, 77, 217, 118, 34, 203, 15, 203, - 129, 3, 247, 119, 203, 129, 3, 251, 71, 203, 129, 3, 195, 35, 203, 129, - 1, 65, 203, 129, 1, 252, 206, 203, 129, 1, 68, 203, 129, 1, 223, 199, - 203, 129, 1, 66, 203, 129, 1, 196, 30, 203, 129, 1, 117, 146, 203, 129, - 1, 117, 206, 110, 203, 129, 1, 117, 172, 203, 129, 1, 117, 219, 74, 203, - 129, 1, 71, 203, 129, 1, 251, 236, 203, 129, 1, 74, 203, 129, 1, 250, - 163, 203, 129, 1, 155, 203, 129, 1, 221, 215, 203, 129, 1, 231, 240, 203, - 129, 1, 231, 91, 203, 129, 1, 214, 68, 203, 129, 1, 247, 160, 203, 129, - 1, 247, 1, 203, 129, 1, 223, 32, 203, 129, 1, 222, 252, 203, 129, 1, 212, - 101, 203, 129, 1, 197, 132, 203, 129, 1, 197, 120, 203, 129, 1, 237, 191, - 203, 129, 1, 237, 175, 203, 129, 1, 213, 79, 203, 129, 1, 190, 190, 203, - 129, 1, 199, 49, 203, 129, 1, 238, 32, 203, 129, 1, 237, 68, 203, 129, 1, - 180, 203, 129, 1, 168, 203, 129, 1, 209, 228, 203, 129, 1, 249, 153, 203, - 129, 1, 248, 203, 203, 129, 1, 174, 203, 129, 1, 170, 203, 129, 1, 165, - 203, 129, 1, 173, 203, 129, 1, 219, 73, 203, 129, 1, 195, 188, 203, 129, - 1, 203, 165, 203, 129, 1, 201, 175, 203, 129, 1, 188, 203, 129, 1, 140, - 203, 129, 18, 3, 252, 206, 203, 129, 18, 3, 68, 203, 129, 18, 3, 223, - 199, 203, 129, 18, 3, 66, 203, 129, 18, 3, 196, 30, 203, 129, 18, 3, 117, - 146, 203, 129, 18, 3, 117, 206, 110, 203, 129, 18, 3, 117, 172, 203, 129, - 18, 3, 117, 219, 74, 203, 129, 18, 3, 71, 203, 129, 18, 3, 251, 236, 203, - 129, 18, 3, 74, 203, 129, 18, 3, 250, 163, 203, 129, 3, 195, 40, 203, - 129, 3, 250, 145, 203, 129, 3, 222, 237, 203, 129, 3, 196, 75, 203, 129, - 211, 113, 203, 129, 237, 238, 203, 129, 55, 237, 238, 203, 129, 252, 68, - 56, 203, 129, 204, 10, 203, 129, 205, 138, 77, 203, 129, 3, 212, 141, - 203, 129, 18, 52, 77, 203, 129, 233, 201, 203, 40, 18, 77, 203, 129, 200, - 162, 77, 203, 129, 18, 3, 208, 207, 71, 203, 129, 3, 223, 93, 247, 119, - 203, 129, 17, 191, 77, 203, 129, 17, 107, 203, 129, 17, 109, 203, 129, - 17, 138, 203, 129, 17, 134, 203, 129, 17, 149, 203, 129, 17, 169, 203, - 129, 17, 175, 203, 129, 17, 171, 203, 129, 17, 178, 203, 129, 234, 146, - 203, 129, 3, 202, 210, 203, 129, 229, 227, 203, 129, 239, 29, 56, 203, - 129, 205, 54, 217, 55, 203, 129, 205, 54, 217, 54, 166, 251, 14, 17, 107, - 166, 251, 14, 17, 109, 166, 251, 14, 17, 138, 166, 251, 14, 17, 134, 166, - 251, 14, 17, 149, 166, 251, 14, 17, 169, 166, 251, 14, 17, 175, 166, 251, - 14, 17, 171, 166, 251, 14, 17, 178, 166, 251, 14, 31, 199, 95, 166, 251, - 14, 31, 197, 32, 166, 251, 14, 31, 198, 249, 166, 251, 14, 31, 232, 135, - 166, 251, 14, 31, 233, 15, 166, 251, 14, 31, 202, 120, 166, 251, 14, 31, - 203, 241, 166, 251, 14, 31, 234, 153, 166, 251, 14, 31, 213, 169, 166, - 251, 14, 31, 91, 228, 140, 166, 251, 14, 31, 91, 189, 221, 182, 1, 65, - 221, 182, 1, 252, 206, 221, 182, 1, 68, 221, 182, 1, 66, 221, 182, 1, 71, - 221, 182, 1, 251, 236, 221, 182, 1, 74, 221, 182, 1, 250, 163, 221, 182, - 1, 155, 221, 182, 1, 221, 215, 221, 182, 1, 231, 240, 221, 182, 1, 231, - 127, 221, 182, 1, 231, 91, 221, 182, 1, 214, 68, 221, 182, 1, 247, 160, - 221, 182, 1, 247, 1, 221, 182, 1, 223, 32, 221, 182, 1, 222, 230, 221, - 182, 1, 212, 101, 221, 182, 1, 197, 132, 221, 182, 1, 197, 120, 221, 182, - 1, 237, 191, 221, 182, 1, 237, 175, 221, 182, 1, 213, 79, 221, 182, 1, - 190, 190, 221, 182, 1, 199, 49, 221, 182, 1, 238, 32, 221, 182, 1, 237, - 181, 221, 182, 1, 237, 68, 221, 182, 1, 180, 221, 182, 1, 168, 221, 182, - 1, 209, 228, 221, 182, 1, 249, 153, 221, 182, 1, 249, 53, 221, 182, 1, - 248, 203, 221, 182, 1, 174, 221, 182, 1, 170, 221, 182, 1, 165, 221, 182, - 1, 173, 221, 182, 1, 195, 188, 221, 182, 1, 188, 221, 182, 1, 140, 221, - 182, 1, 219, 73, 221, 182, 18, 3, 252, 206, 221, 182, 18, 3, 68, 221, - 182, 18, 3, 223, 199, 221, 182, 18, 3, 66, 221, 182, 18, 3, 71, 221, 182, - 18, 3, 251, 236, 221, 182, 18, 3, 74, 221, 182, 18, 3, 250, 163, 221, - 182, 3, 251, 71, 221, 182, 3, 195, 40, 221, 182, 3, 212, 141, 221, 182, - 3, 203, 155, 221, 182, 237, 238, 221, 182, 55, 237, 238, 221, 182, 193, - 23, 204, 10, 221, 182, 205, 54, 77, 221, 182, 55, 205, 54, 77, 221, 182, - 252, 68, 56, 221, 182, 3, 200, 206, 221, 182, 1, 208, 96, 221, 182, 1, - 203, 40, 68, 221, 182, 18, 3, 117, 146, 215, 133, 1, 65, 215, 133, 1, 68, - 215, 133, 1, 66, 215, 133, 1, 71, 215, 133, 1, 155, 215, 133, 1, 221, - 215, 215, 133, 1, 231, 240, 215, 133, 1, 231, 91, 215, 133, 1, 247, 160, - 215, 133, 1, 247, 1, 215, 133, 1, 223, 32, 215, 133, 1, 222, 230, 215, - 133, 1, 212, 101, 215, 133, 1, 197, 132, 215, 133, 1, 197, 120, 215, 133, - 1, 237, 191, 215, 133, 1, 237, 181, 215, 133, 1, 237, 175, 215, 133, 1, - 213, 79, 215, 133, 1, 190, 190, 215, 133, 1, 199, 49, 215, 133, 1, 238, - 32, 215, 133, 1, 237, 68, 215, 133, 1, 180, 215, 133, 1, 168, 215, 133, - 1, 209, 228, 215, 133, 1, 249, 153, 215, 133, 1, 248, 203, 215, 133, 1, - 174, 215, 133, 1, 170, 215, 133, 1, 165, 215, 133, 1, 173, 215, 133, 1, - 195, 188, 215, 133, 1, 188, 215, 133, 1, 140, 215, 133, 1, 206, 109, 215, - 133, 1, 207, 6, 215, 133, 205, 54, 77, 221, 172, 1, 65, 221, 172, 1, 252, - 206, 221, 172, 1, 68, 221, 172, 1, 223, 199, 221, 172, 1, 66, 221, 172, - 1, 196, 30, 221, 172, 1, 71, 221, 172, 1, 251, 236, 221, 172, 1, 74, 221, - 172, 1, 250, 163, 221, 172, 1, 155, 221, 172, 1, 221, 215, 221, 172, 1, - 231, 240, 221, 172, 1, 231, 127, 221, 172, 1, 231, 91, 221, 172, 1, 214, - 68, 221, 172, 1, 247, 160, 221, 172, 1, 247, 1, 221, 172, 1, 223, 32, - 221, 172, 1, 222, 230, 221, 172, 1, 222, 252, 221, 172, 1, 212, 101, 221, - 172, 1, 197, 132, 221, 172, 1, 197, 120, 221, 172, 1, 237, 191, 221, 172, - 1, 237, 181, 221, 172, 1, 206, 109, 221, 172, 1, 237, 175, 221, 172, 1, - 213, 79, 221, 172, 1, 190, 190, 221, 172, 1, 199, 49, 221, 172, 1, 238, - 32, 221, 172, 1, 237, 68, 221, 172, 1, 180, 221, 172, 1, 168, 221, 172, - 1, 209, 228, 221, 172, 1, 249, 153, 221, 172, 1, 249, 53, 221, 172, 1, - 248, 203, 221, 172, 1, 174, 221, 172, 1, 170, 221, 172, 1, 165, 221, 172, - 1, 173, 221, 172, 1, 195, 188, 221, 172, 1, 203, 165, 221, 172, 1, 188, - 221, 172, 1, 140, 221, 172, 3, 251, 71, 221, 172, 18, 3, 252, 206, 221, - 172, 18, 3, 68, 221, 172, 18, 3, 223, 199, 221, 172, 18, 3, 66, 221, 172, - 18, 3, 196, 30, 221, 172, 18, 3, 71, 221, 172, 18, 3, 251, 236, 221, 172, - 18, 3, 74, 221, 172, 18, 3, 250, 163, 221, 172, 3, 212, 141, 221, 172, 3, - 195, 40, 221, 172, 17, 191, 77, 221, 172, 17, 107, 221, 172, 17, 109, - 221, 172, 17, 138, 221, 172, 17, 134, 221, 172, 17, 149, 221, 172, 17, - 169, 221, 172, 17, 175, 221, 172, 17, 171, 221, 172, 17, 178, 230, 219, - 3, 33, 251, 72, 58, 230, 219, 3, 247, 119, 230, 219, 3, 251, 71, 230, - 219, 3, 195, 35, 230, 219, 1, 65, 230, 219, 1, 252, 206, 230, 219, 1, 68, - 230, 219, 1, 223, 199, 230, 219, 1, 66, 230, 219, 1, 196, 30, 230, 219, - 1, 117, 146, 230, 219, 1, 117, 172, 230, 219, 1, 234, 188, 230, 219, 1, - 251, 236, 230, 219, 1, 211, 87, 230, 219, 1, 250, 163, 230, 219, 1, 155, - 230, 219, 1, 221, 215, 230, 219, 1, 231, 240, 230, 219, 1, 231, 91, 230, - 219, 1, 214, 68, 230, 219, 1, 247, 160, 230, 219, 1, 247, 1, 230, 219, 1, - 223, 32, 230, 219, 1, 222, 252, 230, 219, 1, 212, 101, 230, 219, 1, 197, - 132, 230, 219, 1, 197, 120, 230, 219, 1, 237, 191, 230, 219, 1, 237, 175, - 230, 219, 1, 213, 79, 230, 219, 1, 190, 190, 230, 219, 1, 199, 49, 230, - 219, 1, 238, 32, 230, 219, 1, 237, 68, 230, 219, 1, 180, 230, 219, 1, - 168, 230, 219, 1, 209, 228, 230, 219, 1, 249, 153, 230, 219, 1, 248, 203, - 230, 219, 1, 174, 230, 219, 1, 170, 230, 219, 1, 165, 230, 219, 1, 173, - 230, 219, 1, 219, 73, 230, 219, 1, 195, 188, 230, 219, 1, 203, 165, 230, - 219, 1, 201, 175, 230, 219, 1, 188, 230, 219, 1, 140, 33, 248, 165, 60, - 230, 219, 3, 212, 141, 230, 219, 3, 250, 145, 230, 219, 18, 3, 252, 206, - 230, 219, 18, 3, 68, 230, 219, 18, 3, 223, 199, 230, 219, 18, 3, 66, 230, - 219, 18, 3, 196, 30, 230, 219, 18, 3, 117, 146, 230, 219, 18, 3, 117, - 206, 110, 230, 219, 18, 3, 234, 188, 230, 219, 18, 3, 251, 236, 230, 219, - 18, 3, 211, 87, 230, 219, 18, 3, 250, 163, 230, 219, 3, 195, 40, 230, - 219, 211, 113, 230, 219, 250, 164, 219, 198, 77, 230, 219, 3, 209, 79, - 230, 219, 1, 195, 150, 251, 71, 230, 219, 1, 195, 150, 55, 251, 71, 230, - 219, 1, 117, 206, 110, 230, 219, 1, 117, 219, 74, 230, 219, 18, 3, 117, - 172, 230, 219, 18, 3, 117, 219, 74, 33, 230, 219, 17, 191, 77, 33, 230, - 219, 17, 107, 33, 230, 219, 17, 109, 33, 230, 219, 17, 138, 33, 230, 219, - 17, 134, 33, 230, 219, 17, 149, 33, 230, 219, 17, 169, 33, 230, 219, 1, - 65, 33, 230, 219, 1, 155, 33, 230, 219, 1, 180, 33, 230, 219, 1, 195, 69, - 33, 230, 219, 1, 168, 214, 78, 1, 65, 214, 78, 1, 252, 206, 214, 78, 1, - 68, 214, 78, 1, 223, 199, 214, 78, 1, 66, 214, 78, 1, 196, 30, 214, 78, - 1, 117, 146, 214, 78, 1, 117, 206, 110, 214, 78, 1, 117, 172, 214, 78, 1, - 117, 219, 74, 214, 78, 1, 71, 214, 78, 1, 251, 236, 214, 78, 1, 74, 214, - 78, 1, 250, 163, 214, 78, 1, 155, 214, 78, 1, 221, 215, 214, 78, 1, 231, - 240, 214, 78, 1, 231, 91, 214, 78, 1, 214, 68, 214, 78, 1, 214, 17, 214, - 78, 1, 247, 160, 214, 78, 1, 247, 1, 214, 78, 1, 223, 32, 214, 78, 1, - 222, 252, 214, 78, 1, 212, 101, 214, 78, 1, 212, 83, 214, 78, 1, 197, - 132, 214, 78, 1, 197, 120, 214, 78, 1, 237, 191, 214, 78, 1, 237, 175, - 214, 78, 1, 213, 79, 214, 78, 1, 190, 190, 214, 78, 1, 199, 49, 214, 78, - 1, 238, 32, 214, 78, 1, 237, 68, 214, 78, 1, 180, 214, 78, 1, 213, 224, - 214, 78, 1, 168, 214, 78, 1, 209, 228, 214, 78, 1, 249, 153, 214, 78, 1, - 248, 203, 214, 78, 1, 174, 214, 78, 1, 216, 103, 214, 78, 1, 170, 214, - 78, 1, 165, 214, 78, 1, 207, 6, 214, 78, 1, 173, 214, 78, 1, 219, 159, - 214, 78, 1, 193, 190, 214, 78, 1, 203, 165, 214, 78, 1, 201, 175, 214, - 78, 1, 188, 214, 78, 1, 140, 214, 78, 18, 3, 252, 206, 214, 78, 18, 3, - 68, 214, 78, 18, 3, 223, 199, 214, 78, 18, 3, 66, 214, 78, 18, 3, 196, - 30, 214, 78, 18, 3, 117, 146, 214, 78, 18, 3, 117, 206, 110, 214, 78, 18, - 3, 117, 172, 214, 78, 18, 3, 117, 219, 74, 214, 78, 18, 3, 71, 214, 78, - 18, 3, 251, 236, 214, 78, 18, 3, 74, 214, 78, 18, 3, 250, 163, 214, 78, - 3, 195, 40, 214, 78, 3, 247, 119, 214, 78, 3, 251, 71, 214, 78, 3, 195, - 35, 214, 78, 3, 212, 141, 214, 78, 3, 250, 145, 214, 78, 3, 53, 251, 71, - 214, 78, 211, 113, 214, 78, 202, 209, 214, 78, 237, 238, 214, 78, 55, - 237, 238, 214, 78, 242, 74, 214, 78, 231, 204, 233, 3, 214, 78, 252, 68, - 56, 214, 78, 17, 191, 77, 214, 78, 17, 107, 214, 78, 17, 109, 214, 78, - 17, 138, 214, 78, 17, 134, 214, 78, 17, 149, 214, 78, 17, 169, 214, 78, - 17, 175, 214, 78, 17, 171, 214, 78, 17, 178, 214, 78, 55, 242, 74, 214, - 78, 209, 107, 77, 214, 78, 223, 119, 56, 214, 78, 205, 138, 77, 214, 78, - 1, 195, 150, 251, 71, 214, 78, 3, 222, 237, 214, 78, 3, 196, 75, 198, - 129, 251, 100, 198, 129, 1, 65, 198, 129, 1, 252, 206, 198, 129, 1, 68, - 198, 129, 1, 223, 199, 198, 129, 1, 66, 198, 129, 1, 196, 30, 198, 129, - 1, 117, 146, 198, 129, 1, 117, 206, 110, 198, 129, 1, 117, 172, 198, 129, - 1, 117, 219, 74, 198, 129, 1, 71, 198, 129, 1, 251, 236, 198, 129, 1, 74, - 198, 129, 1, 250, 163, 198, 129, 1, 155, 198, 129, 1, 221, 215, 198, 129, - 1, 231, 240, 198, 129, 1, 231, 91, 198, 129, 1, 214, 68, 198, 129, 1, - 247, 160, 198, 129, 1, 247, 1, 198, 129, 1, 223, 32, 198, 129, 1, 222, - 252, 198, 129, 1, 212, 101, 198, 129, 1, 197, 132, 198, 129, 1, 197, 120, - 198, 129, 1, 237, 191, 198, 129, 1, 237, 175, 198, 129, 1, 213, 79, 198, - 129, 1, 190, 190, 198, 129, 1, 199, 49, 198, 129, 1, 238, 32, 198, 129, - 1, 237, 68, 198, 129, 1, 180, 198, 129, 1, 168, 198, 129, 1, 209, 228, - 198, 129, 1, 249, 153, 198, 129, 1, 248, 203, 198, 129, 1, 174, 198, 129, + 162, 17, 134, 162, 17, 150, 162, 17, 169, 162, 17, 175, 162, 17, 171, + 162, 17, 178, 162, 3, 39, 44, 195, 40, 162, 1, 39, 44, 203, 41, 71, 162, + 1, 39, 44, 203, 41, 74, 162, 18, 3, 39, 44, 203, 41, 71, 162, 18, 3, 39, + 44, 203, 41, 74, 162, 1, 39, 44, 219, 75, 162, 31, 222, 198, 222, 101, 3, + 247, 121, 222, 101, 3, 251, 73, 222, 101, 3, 195, 35, 222, 101, 1, 65, + 222, 101, 1, 252, 208, 222, 101, 1, 68, 222, 101, 1, 223, 201, 222, 101, + 1, 66, 222, 101, 1, 196, 30, 222, 101, 1, 71, 222, 101, 1, 251, 238, 222, + 101, 1, 74, 222, 101, 1, 250, 165, 222, 101, 1, 155, 222, 101, 1, 221, + 217, 222, 101, 1, 231, 242, 222, 101, 1, 231, 93, 222, 101, 1, 214, 70, + 222, 101, 1, 247, 162, 222, 101, 1, 247, 3, 222, 101, 1, 223, 34, 222, + 101, 1, 222, 254, 222, 101, 1, 212, 103, 222, 101, 1, 197, 132, 222, 101, + 1, 197, 120, 222, 101, 1, 237, 193, 222, 101, 1, 237, 182, 222, 101, 1, + 237, 177, 222, 101, 1, 207, 7, 222, 101, 1, 213, 81, 222, 101, 1, 190, + 190, 222, 101, 1, 199, 49, 222, 101, 1, 238, 34, 222, 101, 1, 237, 70, + 222, 101, 1, 181, 222, 101, 1, 168, 222, 101, 1, 209, 230, 222, 101, 1, + 249, 155, 222, 101, 1, 248, 205, 222, 101, 1, 174, 222, 101, 1, 170, 222, + 101, 1, 165, 222, 101, 1, 173, 222, 101, 1, 195, 188, 222, 101, 1, 203, + 166, 222, 101, 1, 201, 176, 222, 101, 1, 188, 222, 101, 1, 140, 222, 101, + 18, 3, 252, 208, 222, 101, 18, 3, 68, 222, 101, 18, 3, 223, 201, 222, + 101, 18, 3, 66, 222, 101, 18, 3, 196, 30, 222, 101, 18, 3, 71, 222, 101, + 18, 3, 251, 238, 222, 101, 18, 3, 74, 222, 101, 18, 3, 250, 165, 222, + 101, 3, 195, 40, 222, 101, 3, 212, 143, 222, 101, 252, 70, 56, 222, 101, + 234, 71, 56, 222, 101, 31, 56, 222, 101, 205, 55, 77, 222, 101, 55, 205, + 55, 77, 222, 101, 237, 240, 222, 101, 55, 237, 240, 222, 101, 18, 3, 117, + 146, 222, 101, 31, 3, 58, 202, 13, 202, 21, 1, 205, 183, 202, 13, 202, + 21, 1, 199, 219, 202, 13, 202, 21, 1, 249, 125, 202, 13, 202, 21, 1, 247, + 151, 202, 13, 202, 21, 1, 238, 14, 202, 13, 202, 21, 1, 231, 227, 202, + 13, 202, 21, 1, 217, 122, 202, 13, 202, 21, 1, 214, 67, 202, 13, 202, 21, + 1, 220, 101, 202, 13, 202, 21, 1, 214, 239, 202, 13, 202, 21, 1, 195, + 184, 202, 13, 202, 21, 1, 210, 202, 202, 13, 202, 21, 1, 192, 121, 202, + 13, 202, 21, 1, 207, 162, 202, 13, 202, 21, 1, 230, 83, 202, 13, 202, 21, + 1, 222, 106, 202, 13, 202, 21, 1, 223, 28, 202, 13, 202, 21, 1, 212, 100, + 202, 13, 202, 21, 1, 251, 247, 202, 13, 202, 21, 1, 234, 188, 202, 13, + 202, 21, 1, 223, 202, 202, 13, 202, 21, 1, 196, 141, 202, 13, 202, 21, 1, + 211, 138, 202, 13, 202, 21, 1, 234, 175, 202, 13, 202, 21, 1, 217, 138, + 202, 13, 202, 21, 17, 191, 77, 202, 13, 202, 21, 17, 107, 202, 13, 202, + 21, 17, 109, 202, 13, 202, 21, 17, 138, 202, 13, 202, 21, 17, 134, 202, + 13, 202, 21, 17, 150, 202, 13, 202, 21, 17, 169, 202, 13, 202, 21, 17, + 175, 202, 13, 202, 21, 17, 171, 202, 13, 202, 21, 17, 178, 246, 253, 3, + 247, 121, 246, 253, 3, 251, 73, 246, 253, 3, 195, 35, 246, 253, 1, 252, + 208, 246, 253, 1, 68, 246, 253, 1, 66, 246, 253, 1, 71, 246, 253, 1, 222, + 129, 246, 253, 1, 221, 216, 246, 253, 1, 231, 239, 246, 253, 1, 231, 92, + 246, 253, 1, 214, 69, 246, 253, 1, 247, 161, 246, 253, 1, 247, 2, 246, + 253, 1, 223, 33, 246, 253, 1, 222, 253, 246, 253, 1, 212, 102, 246, 253, + 1, 197, 131, 246, 253, 1, 197, 119, 246, 253, 1, 237, 192, 246, 253, 1, + 237, 176, 246, 253, 1, 213, 80, 246, 253, 1, 199, 245, 246, 253, 1, 199, + 48, 246, 253, 1, 238, 33, 246, 253, 1, 237, 69, 246, 253, 1, 214, 252, + 246, 253, 1, 210, 222, 246, 253, 1, 209, 229, 246, 253, 1, 249, 153, 246, + 253, 1, 248, 204, 246, 253, 1, 217, 153, 246, 253, 1, 191, 174, 246, 253, + 1, 192, 140, 246, 253, 1, 207, 180, 246, 253, 1, 220, 127, 246, 253, 1, + 193, 181, 246, 253, 1, 205, 198, 246, 253, 1, 230, 93, 246, 253, 18, 3, + 65, 246, 253, 18, 3, 68, 246, 253, 18, 3, 223, 201, 246, 253, 18, 3, 66, + 246, 253, 18, 3, 196, 30, 246, 253, 18, 3, 71, 246, 253, 18, 3, 251, 238, + 246, 253, 18, 3, 74, 246, 253, 18, 3, 250, 165, 246, 253, 18, 3, 211, + 135, 246, 253, 187, 77, 246, 253, 250, 166, 77, 246, 253, 195, 40, 246, + 253, 217, 151, 246, 253, 17, 191, 77, 246, 253, 17, 107, 246, 253, 17, + 109, 246, 253, 17, 138, 246, 253, 17, 134, 246, 253, 17, 150, 246, 253, + 17, 169, 246, 253, 17, 175, 246, 253, 17, 171, 246, 253, 17, 178, 246, + 253, 205, 55, 77, 246, 253, 237, 240, 246, 253, 55, 237, 240, 246, 253, + 208, 15, 77, 246, 253, 1, 219, 160, 246, 253, 18, 3, 252, 208, 246, 253, + 18, 3, 234, 168, 246, 253, 1, 195, 187, 217, 120, 1, 65, 217, 120, 1, 68, + 217, 120, 1, 66, 217, 120, 1, 71, 217, 120, 1, 74, 217, 120, 1, 155, 217, + 120, 1, 221, 217, 217, 120, 1, 231, 242, 217, 120, 1, 231, 93, 217, 120, + 1, 247, 162, 217, 120, 1, 247, 3, 217, 120, 1, 223, 34, 217, 120, 1, 222, + 254, 217, 120, 1, 212, 103, 217, 120, 1, 197, 132, 217, 120, 1, 197, 120, + 217, 120, 1, 237, 193, 217, 120, 1, 237, 177, 217, 120, 1, 213, 81, 217, + 120, 1, 190, 190, 217, 120, 1, 199, 49, 217, 120, 1, 238, 34, 217, 120, + 1, 237, 70, 217, 120, 1, 181, 217, 120, 1, 168, 217, 120, 1, 209, 230, + 217, 120, 1, 249, 155, 217, 120, 1, 248, 205, 217, 120, 1, 174, 217, 120, + 1, 165, 217, 120, 1, 173, 217, 120, 1, 195, 188, 217, 120, 1, 188, 217, + 120, 1, 140, 217, 120, 1, 206, 110, 217, 120, 3, 212, 143, 217, 120, 252, + 70, 56, 217, 120, 205, 55, 77, 217, 120, 34, 203, 16, 203, 130, 3, 247, + 121, 203, 130, 3, 251, 73, 203, 130, 3, 195, 35, 203, 130, 1, 65, 203, + 130, 1, 252, 208, 203, 130, 1, 68, 203, 130, 1, 223, 201, 203, 130, 1, + 66, 203, 130, 1, 196, 30, 203, 130, 1, 117, 146, 203, 130, 1, 117, 206, + 111, 203, 130, 1, 117, 172, 203, 130, 1, 117, 219, 76, 203, 130, 1, 71, + 203, 130, 1, 251, 238, 203, 130, 1, 74, 203, 130, 1, 250, 165, 203, 130, + 1, 155, 203, 130, 1, 221, 217, 203, 130, 1, 231, 242, 203, 130, 1, 231, + 93, 203, 130, 1, 214, 70, 203, 130, 1, 247, 162, 203, 130, 1, 247, 3, + 203, 130, 1, 223, 34, 203, 130, 1, 222, 254, 203, 130, 1, 212, 103, 203, + 130, 1, 197, 132, 203, 130, 1, 197, 120, 203, 130, 1, 237, 193, 203, 130, + 1, 237, 177, 203, 130, 1, 213, 81, 203, 130, 1, 190, 190, 203, 130, 1, + 199, 49, 203, 130, 1, 238, 34, 203, 130, 1, 237, 70, 203, 130, 1, 181, + 203, 130, 1, 168, 203, 130, 1, 209, 230, 203, 130, 1, 249, 155, 203, 130, + 1, 248, 205, 203, 130, 1, 174, 203, 130, 1, 170, 203, 130, 1, 165, 203, + 130, 1, 173, 203, 130, 1, 219, 75, 203, 130, 1, 195, 188, 203, 130, 1, + 203, 166, 203, 130, 1, 201, 176, 203, 130, 1, 188, 203, 130, 1, 140, 203, + 130, 18, 3, 252, 208, 203, 130, 18, 3, 68, 203, 130, 18, 3, 223, 201, + 203, 130, 18, 3, 66, 203, 130, 18, 3, 196, 30, 203, 130, 18, 3, 117, 146, + 203, 130, 18, 3, 117, 206, 111, 203, 130, 18, 3, 117, 172, 203, 130, 18, + 3, 117, 219, 76, 203, 130, 18, 3, 71, 203, 130, 18, 3, 251, 238, 203, + 130, 18, 3, 74, 203, 130, 18, 3, 250, 165, 203, 130, 3, 195, 40, 203, + 130, 3, 250, 147, 203, 130, 3, 222, 239, 203, 130, 3, 196, 75, 203, 130, + 211, 115, 203, 130, 237, 240, 203, 130, 55, 237, 240, 203, 130, 252, 70, + 56, 203, 130, 204, 11, 203, 130, 205, 139, 77, 203, 130, 3, 212, 143, + 203, 130, 18, 52, 77, 203, 130, 233, 203, 203, 41, 18, 77, 203, 130, 200, + 162, 77, 203, 130, 18, 3, 208, 209, 71, 203, 130, 3, 223, 95, 247, 121, + 203, 130, 17, 191, 77, 203, 130, 17, 107, 203, 130, 17, 109, 203, 130, + 17, 138, 203, 130, 17, 134, 203, 130, 17, 150, 203, 130, 17, 169, 203, + 130, 17, 175, 203, 130, 17, 171, 203, 130, 17, 178, 203, 130, 234, 148, + 203, 130, 3, 202, 211, 203, 130, 229, 229, 203, 130, 239, 31, 56, 203, + 130, 205, 55, 217, 57, 203, 130, 205, 55, 217, 56, 166, 251, 16, 17, 107, + 166, 251, 16, 17, 109, 166, 251, 16, 17, 138, 166, 251, 16, 17, 134, 166, + 251, 16, 17, 150, 166, 251, 16, 17, 169, 166, 251, 16, 17, 175, 166, 251, + 16, 17, 171, 166, 251, 16, 17, 178, 166, 251, 16, 31, 199, 95, 166, 251, + 16, 31, 197, 32, 166, 251, 16, 31, 198, 249, 166, 251, 16, 31, 232, 137, + 166, 251, 16, 31, 233, 17, 166, 251, 16, 31, 202, 121, 166, 251, 16, 31, + 203, 242, 166, 251, 16, 31, 234, 155, 166, 251, 16, 31, 213, 171, 166, + 251, 16, 31, 91, 228, 142, 166, 251, 16, 31, 91, 189, 221, 184, 1, 65, + 221, 184, 1, 252, 208, 221, 184, 1, 68, 221, 184, 1, 66, 221, 184, 1, 71, + 221, 184, 1, 251, 238, 221, 184, 1, 74, 221, 184, 1, 250, 165, 221, 184, + 1, 155, 221, 184, 1, 221, 217, 221, 184, 1, 231, 242, 221, 184, 1, 231, + 129, 221, 184, 1, 231, 93, 221, 184, 1, 214, 70, 221, 184, 1, 247, 162, + 221, 184, 1, 247, 3, 221, 184, 1, 223, 34, 221, 184, 1, 222, 232, 221, + 184, 1, 212, 103, 221, 184, 1, 197, 132, 221, 184, 1, 197, 120, 221, 184, + 1, 237, 193, 221, 184, 1, 237, 177, 221, 184, 1, 213, 81, 221, 184, 1, + 190, 190, 221, 184, 1, 199, 49, 221, 184, 1, 238, 34, 221, 184, 1, 237, + 183, 221, 184, 1, 237, 70, 221, 184, 1, 181, 221, 184, 1, 168, 221, 184, + 1, 209, 230, 221, 184, 1, 249, 155, 221, 184, 1, 249, 55, 221, 184, 1, + 248, 205, 221, 184, 1, 174, 221, 184, 1, 170, 221, 184, 1, 165, 221, 184, + 1, 173, 221, 184, 1, 195, 188, 221, 184, 1, 188, 221, 184, 1, 140, 221, + 184, 1, 219, 75, 221, 184, 18, 3, 252, 208, 221, 184, 18, 3, 68, 221, + 184, 18, 3, 223, 201, 221, 184, 18, 3, 66, 221, 184, 18, 3, 71, 221, 184, + 18, 3, 251, 238, 221, 184, 18, 3, 74, 221, 184, 18, 3, 250, 165, 221, + 184, 3, 251, 73, 221, 184, 3, 195, 40, 221, 184, 3, 212, 143, 221, 184, + 3, 203, 156, 221, 184, 237, 240, 221, 184, 55, 237, 240, 221, 184, 193, + 23, 204, 11, 221, 184, 205, 55, 77, 221, 184, 55, 205, 55, 77, 221, 184, + 252, 70, 56, 221, 184, 3, 200, 206, 221, 184, 1, 208, 98, 221, 184, 1, + 203, 41, 68, 221, 184, 18, 3, 117, 146, 215, 135, 1, 65, 215, 135, 1, 68, + 215, 135, 1, 66, 215, 135, 1, 71, 215, 135, 1, 155, 215, 135, 1, 221, + 217, 215, 135, 1, 231, 242, 215, 135, 1, 231, 93, 215, 135, 1, 247, 162, + 215, 135, 1, 247, 3, 215, 135, 1, 223, 34, 215, 135, 1, 222, 232, 215, + 135, 1, 212, 103, 215, 135, 1, 197, 132, 215, 135, 1, 197, 120, 215, 135, + 1, 237, 193, 215, 135, 1, 237, 183, 215, 135, 1, 237, 177, 215, 135, 1, + 213, 81, 215, 135, 1, 190, 190, 215, 135, 1, 199, 49, 215, 135, 1, 238, + 34, 215, 135, 1, 237, 70, 215, 135, 1, 181, 215, 135, 1, 168, 215, 135, + 1, 209, 230, 215, 135, 1, 249, 155, 215, 135, 1, 248, 205, 215, 135, 1, + 174, 215, 135, 1, 170, 215, 135, 1, 165, 215, 135, 1, 173, 215, 135, 1, + 195, 188, 215, 135, 1, 188, 215, 135, 1, 140, 215, 135, 1, 206, 110, 215, + 135, 1, 207, 7, 215, 135, 205, 55, 77, 221, 174, 1, 65, 221, 174, 1, 252, + 208, 221, 174, 1, 68, 221, 174, 1, 223, 201, 221, 174, 1, 66, 221, 174, + 1, 196, 30, 221, 174, 1, 71, 221, 174, 1, 251, 238, 221, 174, 1, 74, 221, + 174, 1, 250, 165, 221, 174, 1, 155, 221, 174, 1, 221, 217, 221, 174, 1, + 231, 242, 221, 174, 1, 231, 129, 221, 174, 1, 231, 93, 221, 174, 1, 214, + 70, 221, 174, 1, 247, 162, 221, 174, 1, 247, 3, 221, 174, 1, 223, 34, + 221, 174, 1, 222, 232, 221, 174, 1, 222, 254, 221, 174, 1, 212, 103, 221, + 174, 1, 197, 132, 221, 174, 1, 197, 120, 221, 174, 1, 237, 193, 221, 174, + 1, 237, 183, 221, 174, 1, 206, 110, 221, 174, 1, 237, 177, 221, 174, 1, + 213, 81, 221, 174, 1, 190, 190, 221, 174, 1, 199, 49, 221, 174, 1, 238, + 34, 221, 174, 1, 237, 70, 221, 174, 1, 181, 221, 174, 1, 168, 221, 174, + 1, 209, 230, 221, 174, 1, 249, 155, 221, 174, 1, 249, 55, 221, 174, 1, + 248, 205, 221, 174, 1, 174, 221, 174, 1, 170, 221, 174, 1, 165, 221, 174, + 1, 173, 221, 174, 1, 195, 188, 221, 174, 1, 203, 166, 221, 174, 1, 188, + 221, 174, 1, 140, 221, 174, 3, 251, 73, 221, 174, 18, 3, 252, 208, 221, + 174, 18, 3, 68, 221, 174, 18, 3, 223, 201, 221, 174, 18, 3, 66, 221, 174, + 18, 3, 196, 30, 221, 174, 18, 3, 71, 221, 174, 18, 3, 251, 238, 221, 174, + 18, 3, 74, 221, 174, 18, 3, 250, 165, 221, 174, 3, 212, 143, 221, 174, 3, + 195, 40, 221, 174, 17, 191, 77, 221, 174, 17, 107, 221, 174, 17, 109, + 221, 174, 17, 138, 221, 174, 17, 134, 221, 174, 17, 150, 221, 174, 17, + 169, 221, 174, 17, 175, 221, 174, 17, 171, 221, 174, 17, 178, 230, 221, + 3, 33, 251, 74, 58, 230, 221, 3, 247, 121, 230, 221, 3, 251, 73, 230, + 221, 3, 195, 35, 230, 221, 1, 65, 230, 221, 1, 252, 208, 230, 221, 1, 68, + 230, 221, 1, 223, 201, 230, 221, 1, 66, 230, 221, 1, 196, 30, 230, 221, + 1, 117, 146, 230, 221, 1, 117, 172, 230, 221, 1, 234, 190, 230, 221, 1, + 251, 238, 230, 221, 1, 211, 89, 230, 221, 1, 250, 165, 230, 221, 1, 155, + 230, 221, 1, 221, 217, 230, 221, 1, 231, 242, 230, 221, 1, 231, 93, 230, + 221, 1, 214, 70, 230, 221, 1, 247, 162, 230, 221, 1, 247, 3, 230, 221, 1, + 223, 34, 230, 221, 1, 222, 254, 230, 221, 1, 212, 103, 230, 221, 1, 197, + 132, 230, 221, 1, 197, 120, 230, 221, 1, 237, 193, 230, 221, 1, 237, 177, + 230, 221, 1, 213, 81, 230, 221, 1, 190, 190, 230, 221, 1, 199, 49, 230, + 221, 1, 238, 34, 230, 221, 1, 237, 70, 230, 221, 1, 181, 230, 221, 1, + 168, 230, 221, 1, 209, 230, 230, 221, 1, 249, 155, 230, 221, 1, 248, 205, + 230, 221, 1, 174, 230, 221, 1, 170, 230, 221, 1, 165, 230, 221, 1, 173, + 230, 221, 1, 219, 75, 230, 221, 1, 195, 188, 230, 221, 1, 203, 166, 230, + 221, 1, 201, 176, 230, 221, 1, 188, 230, 221, 1, 140, 33, 248, 167, 60, + 230, 221, 3, 212, 143, 230, 221, 3, 250, 147, 230, 221, 18, 3, 252, 208, + 230, 221, 18, 3, 68, 230, 221, 18, 3, 223, 201, 230, 221, 18, 3, 66, 230, + 221, 18, 3, 196, 30, 230, 221, 18, 3, 117, 146, 230, 221, 18, 3, 117, + 206, 111, 230, 221, 18, 3, 234, 190, 230, 221, 18, 3, 251, 238, 230, 221, + 18, 3, 211, 89, 230, 221, 18, 3, 250, 165, 230, 221, 3, 195, 40, 230, + 221, 211, 115, 230, 221, 250, 166, 219, 200, 77, 230, 221, 3, 209, 81, + 230, 221, 1, 195, 150, 251, 73, 230, 221, 1, 195, 150, 55, 251, 73, 230, + 221, 1, 117, 206, 111, 230, 221, 1, 117, 219, 76, 230, 221, 18, 3, 117, + 172, 230, 221, 18, 3, 117, 219, 76, 33, 230, 221, 17, 191, 77, 33, 230, + 221, 17, 107, 33, 230, 221, 17, 109, 33, 230, 221, 17, 138, 33, 230, 221, + 17, 134, 33, 230, 221, 17, 150, 33, 230, 221, 17, 169, 33, 230, 221, 1, + 65, 33, 230, 221, 1, 155, 33, 230, 221, 1, 181, 33, 230, 221, 1, 195, 69, + 33, 230, 221, 1, 168, 214, 80, 1, 65, 214, 80, 1, 252, 208, 214, 80, 1, + 68, 214, 80, 1, 223, 201, 214, 80, 1, 66, 214, 80, 1, 196, 30, 214, 80, + 1, 117, 146, 214, 80, 1, 117, 206, 111, 214, 80, 1, 117, 172, 214, 80, 1, + 117, 219, 76, 214, 80, 1, 71, 214, 80, 1, 251, 238, 214, 80, 1, 74, 214, + 80, 1, 250, 165, 214, 80, 1, 155, 214, 80, 1, 221, 217, 214, 80, 1, 231, + 242, 214, 80, 1, 231, 93, 214, 80, 1, 214, 70, 214, 80, 1, 214, 19, 214, + 80, 1, 247, 162, 214, 80, 1, 247, 3, 214, 80, 1, 223, 34, 214, 80, 1, + 222, 254, 214, 80, 1, 212, 103, 214, 80, 1, 212, 85, 214, 80, 1, 197, + 132, 214, 80, 1, 197, 120, 214, 80, 1, 237, 193, 214, 80, 1, 237, 177, + 214, 80, 1, 213, 81, 214, 80, 1, 190, 190, 214, 80, 1, 199, 49, 214, 80, + 1, 238, 34, 214, 80, 1, 237, 70, 214, 80, 1, 181, 214, 80, 1, 213, 226, + 214, 80, 1, 168, 214, 80, 1, 209, 230, 214, 80, 1, 249, 155, 214, 80, 1, + 248, 205, 214, 80, 1, 174, 214, 80, 1, 216, 105, 214, 80, 1, 170, 214, + 80, 1, 165, 214, 80, 1, 207, 7, 214, 80, 1, 173, 214, 80, 1, 219, 161, + 214, 80, 1, 193, 190, 214, 80, 1, 203, 166, 214, 80, 1, 201, 176, 214, + 80, 1, 188, 214, 80, 1, 140, 214, 80, 18, 3, 252, 208, 214, 80, 18, 3, + 68, 214, 80, 18, 3, 223, 201, 214, 80, 18, 3, 66, 214, 80, 18, 3, 196, + 30, 214, 80, 18, 3, 117, 146, 214, 80, 18, 3, 117, 206, 111, 214, 80, 18, + 3, 117, 172, 214, 80, 18, 3, 117, 219, 76, 214, 80, 18, 3, 71, 214, 80, + 18, 3, 251, 238, 214, 80, 18, 3, 74, 214, 80, 18, 3, 250, 165, 214, 80, + 3, 195, 40, 214, 80, 3, 247, 121, 214, 80, 3, 251, 73, 214, 80, 3, 195, + 35, 214, 80, 3, 212, 143, 214, 80, 3, 250, 147, 214, 80, 3, 53, 251, 73, + 214, 80, 211, 115, 214, 80, 202, 210, 214, 80, 237, 240, 214, 80, 55, + 237, 240, 214, 80, 242, 76, 214, 80, 231, 206, 233, 5, 214, 80, 252, 70, + 56, 214, 80, 17, 191, 77, 214, 80, 17, 107, 214, 80, 17, 109, 214, 80, + 17, 138, 214, 80, 17, 134, 214, 80, 17, 150, 214, 80, 17, 169, 214, 80, + 17, 175, 214, 80, 17, 171, 214, 80, 17, 178, 214, 80, 55, 242, 76, 214, + 80, 209, 109, 77, 214, 80, 223, 121, 56, 214, 80, 205, 139, 77, 214, 80, + 1, 195, 150, 251, 73, 214, 80, 3, 222, 239, 214, 80, 3, 196, 75, 198, + 129, 251, 102, 198, 129, 1, 65, 198, 129, 1, 252, 208, 198, 129, 1, 68, + 198, 129, 1, 223, 201, 198, 129, 1, 66, 198, 129, 1, 196, 30, 198, 129, + 1, 117, 146, 198, 129, 1, 117, 206, 111, 198, 129, 1, 117, 172, 198, 129, + 1, 117, 219, 76, 198, 129, 1, 71, 198, 129, 1, 251, 238, 198, 129, 1, 74, + 198, 129, 1, 250, 165, 198, 129, 1, 155, 198, 129, 1, 221, 217, 198, 129, + 1, 231, 242, 198, 129, 1, 231, 93, 198, 129, 1, 214, 70, 198, 129, 1, + 247, 162, 198, 129, 1, 247, 3, 198, 129, 1, 223, 34, 198, 129, 1, 222, + 254, 198, 129, 1, 212, 103, 198, 129, 1, 197, 132, 198, 129, 1, 197, 120, + 198, 129, 1, 237, 193, 198, 129, 1, 237, 177, 198, 129, 1, 213, 81, 198, + 129, 1, 190, 190, 198, 129, 1, 199, 49, 198, 129, 1, 238, 34, 198, 129, + 1, 237, 70, 198, 129, 1, 181, 198, 129, 1, 168, 198, 129, 1, 209, 230, + 198, 129, 1, 249, 155, 198, 129, 1, 248, 205, 198, 129, 1, 174, 198, 129, 1, 170, 198, 129, 1, 165, 198, 129, 1, 173, 198, 129, 1, 195, 188, 198, - 129, 1, 203, 165, 198, 129, 1, 201, 175, 198, 129, 1, 188, 198, 129, 1, - 140, 198, 129, 18, 3, 252, 206, 198, 129, 18, 3, 68, 198, 129, 18, 3, - 223, 199, 198, 129, 18, 3, 66, 198, 129, 18, 3, 196, 30, 198, 129, 18, 3, - 117, 146, 198, 129, 18, 3, 117, 206, 110, 198, 129, 18, 3, 117, 172, 198, - 129, 18, 3, 117, 219, 74, 198, 129, 18, 3, 71, 198, 129, 18, 3, 203, 40, - 71, 198, 129, 18, 3, 251, 236, 198, 129, 18, 3, 74, 198, 129, 18, 3, 203, - 40, 74, 198, 129, 18, 3, 250, 163, 198, 129, 3, 247, 119, 198, 129, 3, - 251, 71, 198, 129, 3, 195, 35, 198, 129, 3, 195, 40, 198, 129, 3, 212, - 141, 198, 129, 3, 250, 145, 198, 129, 230, 137, 198, 129, 252, 68, 56, - 198, 129, 211, 113, 198, 129, 17, 191, 77, 198, 129, 17, 107, 198, 129, - 17, 109, 198, 129, 17, 138, 198, 129, 17, 134, 198, 129, 17, 149, 198, + 129, 1, 203, 166, 198, 129, 1, 201, 176, 198, 129, 1, 188, 198, 129, 1, + 140, 198, 129, 18, 3, 252, 208, 198, 129, 18, 3, 68, 198, 129, 18, 3, + 223, 201, 198, 129, 18, 3, 66, 198, 129, 18, 3, 196, 30, 198, 129, 18, 3, + 117, 146, 198, 129, 18, 3, 117, 206, 111, 198, 129, 18, 3, 117, 172, 198, + 129, 18, 3, 117, 219, 76, 198, 129, 18, 3, 71, 198, 129, 18, 3, 203, 41, + 71, 198, 129, 18, 3, 251, 238, 198, 129, 18, 3, 74, 198, 129, 18, 3, 203, + 41, 74, 198, 129, 18, 3, 250, 165, 198, 129, 3, 247, 121, 198, 129, 3, + 251, 73, 198, 129, 3, 195, 35, 198, 129, 3, 195, 40, 198, 129, 3, 212, + 143, 198, 129, 3, 250, 147, 198, 129, 230, 139, 198, 129, 252, 70, 56, + 198, 129, 211, 115, 198, 129, 17, 191, 77, 198, 129, 17, 107, 198, 129, + 17, 109, 198, 129, 17, 138, 198, 129, 17, 134, 198, 129, 17, 150, 198, 129, 17, 169, 198, 129, 17, 175, 198, 129, 17, 171, 198, 129, 17, 178, - 202, 211, 1, 65, 202, 211, 1, 252, 206, 202, 211, 1, 68, 202, 211, 1, - 223, 199, 202, 211, 1, 66, 202, 211, 1, 196, 30, 202, 211, 1, 117, 146, - 202, 211, 1, 117, 206, 110, 202, 211, 1, 117, 172, 202, 211, 1, 117, 219, - 74, 202, 211, 1, 71, 202, 211, 1, 251, 236, 202, 211, 1, 74, 202, 211, 1, - 250, 163, 202, 211, 1, 155, 202, 211, 1, 221, 215, 202, 211, 1, 231, 240, - 202, 211, 1, 231, 91, 202, 211, 1, 214, 68, 202, 211, 1, 247, 160, 202, - 211, 1, 247, 1, 202, 211, 1, 223, 32, 202, 211, 1, 222, 252, 202, 211, 1, - 212, 101, 202, 211, 1, 197, 132, 202, 211, 1, 197, 120, 202, 211, 1, 237, - 191, 202, 211, 1, 237, 175, 202, 211, 1, 213, 79, 202, 211, 1, 190, 190, - 202, 211, 1, 199, 49, 202, 211, 1, 238, 32, 202, 211, 1, 237, 68, 202, - 211, 1, 180, 202, 211, 1, 168, 202, 211, 1, 209, 228, 202, 211, 1, 249, - 153, 202, 211, 1, 248, 203, 202, 211, 1, 174, 202, 211, 1, 170, 202, 211, - 1, 165, 202, 211, 1, 173, 202, 211, 1, 195, 188, 202, 211, 1, 203, 165, - 202, 211, 1, 201, 175, 202, 211, 1, 188, 202, 211, 1, 140, 202, 211, 18, - 3, 252, 206, 202, 211, 18, 3, 68, 202, 211, 18, 3, 223, 199, 202, 211, - 18, 3, 66, 202, 211, 18, 3, 196, 30, 202, 211, 18, 3, 117, 146, 202, 211, - 18, 3, 117, 206, 110, 202, 211, 18, 3, 71, 202, 211, 18, 3, 251, 236, - 202, 211, 18, 3, 74, 202, 211, 18, 3, 250, 163, 202, 211, 3, 247, 119, - 202, 211, 3, 251, 71, 202, 211, 3, 195, 35, 202, 211, 3, 195, 40, 202, - 211, 3, 212, 141, 202, 211, 3, 202, 210, 202, 211, 237, 238, 202, 211, - 55, 237, 238, 202, 211, 204, 11, 236, 140, 202, 211, 204, 11, 164, 202, - 211, 207, 46, 217, 55, 202, 211, 207, 46, 217, 54, 202, 211, 207, 46, - 217, 53, 202, 211, 234, 95, 79, 199, 54, 77, 202, 211, 205, 54, 87, 4, - 197, 236, 23, 196, 221, 211, 41, 202, 211, 205, 54, 87, 4, 197, 236, 23, - 235, 138, 238, 226, 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, - 238, 226, 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, 55, 238, 226, - 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, 197, 225, 238, 226, - 202, 211, 205, 54, 87, 55, 206, 188, 202, 211, 205, 54, 87, 55, 206, 189, - 4, 207, 119, 202, 211, 205, 54, 87, 4, 55, 238, 226, 202, 211, 205, 54, - 87, 4, 197, 225, 238, 226, 202, 211, 205, 54, 87, 4, 208, 26, 238, 226, - 202, 211, 205, 54, 87, 4, 204, 8, 238, 226, 202, 211, 205, 54, 87, 4, - 243, 8, 23, 207, 119, 202, 211, 205, 54, 87, 4, 243, 8, 23, 105, 234, 97, - 202, 211, 205, 54, 87, 4, 243, 8, 23, 232, 128, 234, 97, 202, 211, 1, - 198, 226, 251, 157, 68, 202, 211, 1, 197, 15, 251, 157, 68, 202, 211, 1, - 197, 15, 251, 157, 223, 199, 202, 211, 1, 251, 157, 66, 202, 211, 18, 3, - 251, 157, 66, 202, 211, 18, 3, 251, 157, 196, 30, 215, 253, 1, 65, 215, - 253, 1, 252, 206, 215, 253, 1, 68, 215, 253, 1, 223, 199, 215, 253, 1, - 66, 215, 253, 1, 196, 30, 215, 253, 1, 117, 146, 215, 253, 1, 117, 206, - 110, 215, 253, 1, 117, 172, 215, 253, 1, 117, 219, 74, 215, 253, 1, 71, - 215, 253, 1, 251, 236, 215, 253, 1, 74, 215, 253, 1, 250, 163, 215, 253, - 1, 155, 215, 253, 1, 221, 215, 215, 253, 1, 231, 240, 215, 253, 1, 231, - 91, 215, 253, 1, 214, 68, 215, 253, 1, 247, 160, 215, 253, 1, 247, 1, - 215, 253, 1, 223, 32, 215, 253, 1, 222, 252, 215, 253, 1, 212, 101, 215, - 253, 1, 197, 132, 215, 253, 1, 197, 120, 215, 253, 1, 237, 191, 215, 253, - 1, 237, 175, 215, 253, 1, 213, 79, 215, 253, 1, 190, 190, 215, 253, 1, - 199, 49, 215, 253, 1, 238, 32, 215, 253, 1, 237, 68, 215, 253, 1, 180, - 215, 253, 1, 168, 215, 253, 1, 209, 228, 215, 253, 1, 249, 153, 215, 253, - 1, 248, 203, 215, 253, 1, 174, 215, 253, 1, 170, 215, 253, 1, 165, 215, - 253, 1, 173, 215, 253, 1, 195, 188, 215, 253, 1, 203, 165, 215, 253, 1, - 201, 175, 215, 253, 1, 188, 215, 253, 1, 140, 215, 253, 1, 219, 73, 215, - 253, 18, 3, 252, 206, 215, 253, 18, 3, 68, 215, 253, 18, 3, 223, 199, - 215, 253, 18, 3, 66, 215, 253, 18, 3, 196, 30, 215, 253, 18, 3, 117, 146, - 215, 253, 18, 3, 117, 206, 110, 215, 253, 18, 3, 117, 172, 215, 253, 18, - 3, 117, 219, 74, 215, 253, 18, 3, 71, 215, 253, 18, 3, 251, 236, 215, - 253, 18, 3, 74, 215, 253, 18, 3, 250, 163, 215, 253, 3, 251, 71, 215, - 253, 3, 195, 35, 215, 253, 3, 195, 40, 215, 253, 3, 251, 11, 215, 253, - 237, 238, 215, 253, 55, 237, 238, 215, 253, 252, 68, 56, 215, 253, 3, - 228, 127, 215, 253, 17, 191, 77, 215, 253, 17, 107, 215, 253, 17, 109, - 215, 253, 17, 138, 215, 253, 17, 134, 215, 253, 17, 149, 215, 253, 17, - 169, 215, 253, 17, 175, 215, 253, 17, 171, 215, 253, 17, 178, 104, 248, - 159, 4, 211, 42, 104, 206, 122, 248, 158, 104, 55, 248, 159, 4, 211, 42, - 104, 197, 225, 248, 159, 4, 211, 42, 104, 248, 159, 4, 55, 211, 42, 104, - 206, 122, 248, 159, 4, 211, 42, 104, 206, 122, 248, 159, 4, 55, 211, 42, - 104, 223, 93, 248, 158, 104, 223, 93, 248, 159, 4, 55, 211, 42, 104, 200, - 134, 248, 158, 104, 200, 134, 248, 159, 4, 211, 42, 104, 200, 134, 248, - 159, 4, 55, 211, 42, 104, 153, 200, 134, 248, 159, 4, 55, 211, 42, 199, - 205, 1, 65, 199, 205, 1, 252, 206, 199, 205, 1, 68, 199, 205, 1, 223, - 199, 199, 205, 1, 66, 199, 205, 1, 196, 30, 199, 205, 1, 71, 199, 205, 1, - 251, 236, 199, 205, 1, 74, 199, 205, 1, 250, 163, 199, 205, 1, 155, 199, - 205, 1, 221, 215, 199, 205, 1, 231, 240, 199, 205, 1, 231, 91, 199, 205, - 1, 214, 68, 199, 205, 1, 247, 160, 199, 205, 1, 247, 1, 199, 205, 1, 223, - 32, 199, 205, 1, 222, 252, 199, 205, 1, 212, 101, 199, 205, 1, 197, 132, - 199, 205, 1, 197, 120, 199, 205, 1, 237, 191, 199, 205, 1, 237, 175, 199, - 205, 1, 213, 79, 199, 205, 1, 190, 190, 199, 205, 1, 199, 49, 199, 205, - 1, 238, 32, 199, 205, 1, 237, 68, 199, 205, 1, 180, 199, 205, 1, 168, - 199, 205, 1, 209, 228, 199, 205, 1, 249, 153, 199, 205, 1, 248, 203, 199, + 202, 212, 1, 65, 202, 212, 1, 252, 208, 202, 212, 1, 68, 202, 212, 1, + 223, 201, 202, 212, 1, 66, 202, 212, 1, 196, 30, 202, 212, 1, 117, 146, + 202, 212, 1, 117, 206, 111, 202, 212, 1, 117, 172, 202, 212, 1, 117, 219, + 76, 202, 212, 1, 71, 202, 212, 1, 251, 238, 202, 212, 1, 74, 202, 212, 1, + 250, 165, 202, 212, 1, 155, 202, 212, 1, 221, 217, 202, 212, 1, 231, 242, + 202, 212, 1, 231, 93, 202, 212, 1, 214, 70, 202, 212, 1, 247, 162, 202, + 212, 1, 247, 3, 202, 212, 1, 223, 34, 202, 212, 1, 222, 254, 202, 212, 1, + 212, 103, 202, 212, 1, 197, 132, 202, 212, 1, 197, 120, 202, 212, 1, 237, + 193, 202, 212, 1, 237, 177, 202, 212, 1, 213, 81, 202, 212, 1, 190, 190, + 202, 212, 1, 199, 49, 202, 212, 1, 238, 34, 202, 212, 1, 237, 70, 202, + 212, 1, 181, 202, 212, 1, 168, 202, 212, 1, 209, 230, 202, 212, 1, 249, + 155, 202, 212, 1, 248, 205, 202, 212, 1, 174, 202, 212, 1, 170, 202, 212, + 1, 165, 202, 212, 1, 173, 202, 212, 1, 195, 188, 202, 212, 1, 203, 166, + 202, 212, 1, 201, 176, 202, 212, 1, 188, 202, 212, 1, 140, 202, 212, 18, + 3, 252, 208, 202, 212, 18, 3, 68, 202, 212, 18, 3, 223, 201, 202, 212, + 18, 3, 66, 202, 212, 18, 3, 196, 30, 202, 212, 18, 3, 117, 146, 202, 212, + 18, 3, 117, 206, 111, 202, 212, 18, 3, 71, 202, 212, 18, 3, 251, 238, + 202, 212, 18, 3, 74, 202, 212, 18, 3, 250, 165, 202, 212, 3, 247, 121, + 202, 212, 3, 251, 73, 202, 212, 3, 195, 35, 202, 212, 3, 195, 40, 202, + 212, 3, 212, 143, 202, 212, 3, 202, 211, 202, 212, 237, 240, 202, 212, + 55, 237, 240, 202, 212, 204, 12, 236, 142, 202, 212, 204, 12, 164, 202, + 212, 207, 47, 217, 57, 202, 212, 207, 47, 217, 56, 202, 212, 207, 47, + 217, 55, 202, 212, 234, 97, 79, 199, 54, 77, 202, 212, 205, 55, 87, 4, + 197, 236, 23, 196, 221, 211, 43, 202, 212, 205, 55, 87, 4, 197, 236, 23, + 235, 140, 238, 228, 202, 212, 205, 55, 87, 4, 207, 122, 23, 235, 140, + 238, 228, 202, 212, 205, 55, 87, 4, 207, 122, 23, 235, 140, 55, 238, 228, + 202, 212, 205, 55, 87, 4, 207, 122, 23, 235, 140, 197, 225, 238, 228, + 202, 212, 205, 55, 87, 55, 206, 189, 202, 212, 205, 55, 87, 55, 206, 190, + 4, 207, 121, 202, 212, 205, 55, 87, 4, 55, 238, 228, 202, 212, 205, 55, + 87, 4, 197, 225, 238, 228, 202, 212, 205, 55, 87, 4, 208, 28, 238, 228, + 202, 212, 205, 55, 87, 4, 204, 9, 238, 228, 202, 212, 205, 55, 87, 4, + 243, 10, 23, 207, 121, 202, 212, 205, 55, 87, 4, 243, 10, 23, 105, 234, + 99, 202, 212, 205, 55, 87, 4, 243, 10, 23, 232, 130, 234, 99, 202, 212, + 1, 198, 226, 251, 159, 68, 202, 212, 1, 197, 15, 251, 159, 68, 202, 212, + 1, 197, 15, 251, 159, 223, 201, 202, 212, 1, 251, 159, 66, 202, 212, 18, + 3, 251, 159, 66, 202, 212, 18, 3, 251, 159, 196, 30, 215, 255, 1, 65, + 215, 255, 1, 252, 208, 215, 255, 1, 68, 215, 255, 1, 223, 201, 215, 255, + 1, 66, 215, 255, 1, 196, 30, 215, 255, 1, 117, 146, 215, 255, 1, 117, + 206, 111, 215, 255, 1, 117, 172, 215, 255, 1, 117, 219, 76, 215, 255, 1, + 71, 215, 255, 1, 251, 238, 215, 255, 1, 74, 215, 255, 1, 250, 165, 215, + 255, 1, 155, 215, 255, 1, 221, 217, 215, 255, 1, 231, 242, 215, 255, 1, + 231, 93, 215, 255, 1, 214, 70, 215, 255, 1, 247, 162, 215, 255, 1, 247, + 3, 215, 255, 1, 223, 34, 215, 255, 1, 222, 254, 215, 255, 1, 212, 103, + 215, 255, 1, 197, 132, 215, 255, 1, 197, 120, 215, 255, 1, 237, 193, 215, + 255, 1, 237, 177, 215, 255, 1, 213, 81, 215, 255, 1, 190, 190, 215, 255, + 1, 199, 49, 215, 255, 1, 238, 34, 215, 255, 1, 237, 70, 215, 255, 1, 181, + 215, 255, 1, 168, 215, 255, 1, 209, 230, 215, 255, 1, 249, 155, 215, 255, + 1, 248, 205, 215, 255, 1, 174, 215, 255, 1, 170, 215, 255, 1, 165, 215, + 255, 1, 173, 215, 255, 1, 195, 188, 215, 255, 1, 203, 166, 215, 255, 1, + 201, 176, 215, 255, 1, 188, 215, 255, 1, 140, 215, 255, 1, 219, 75, 215, + 255, 18, 3, 252, 208, 215, 255, 18, 3, 68, 215, 255, 18, 3, 223, 201, + 215, 255, 18, 3, 66, 215, 255, 18, 3, 196, 30, 215, 255, 18, 3, 117, 146, + 215, 255, 18, 3, 117, 206, 111, 215, 255, 18, 3, 117, 172, 215, 255, 18, + 3, 117, 219, 76, 215, 255, 18, 3, 71, 215, 255, 18, 3, 251, 238, 215, + 255, 18, 3, 74, 215, 255, 18, 3, 250, 165, 215, 255, 3, 251, 73, 215, + 255, 3, 195, 35, 215, 255, 3, 195, 40, 215, 255, 3, 251, 13, 215, 255, + 237, 240, 215, 255, 55, 237, 240, 215, 255, 252, 70, 56, 215, 255, 3, + 228, 129, 215, 255, 17, 191, 77, 215, 255, 17, 107, 215, 255, 17, 109, + 215, 255, 17, 138, 215, 255, 17, 134, 215, 255, 17, 150, 215, 255, 17, + 169, 215, 255, 17, 175, 215, 255, 17, 171, 215, 255, 17, 178, 104, 248, + 161, 4, 211, 44, 104, 206, 123, 248, 160, 104, 55, 248, 161, 4, 211, 44, + 104, 197, 225, 248, 161, 4, 211, 44, 104, 248, 161, 4, 55, 211, 44, 104, + 206, 123, 248, 161, 4, 211, 44, 104, 206, 123, 248, 161, 4, 55, 211, 44, + 104, 223, 95, 248, 160, 104, 223, 95, 248, 161, 4, 55, 211, 44, 104, 200, + 134, 248, 160, 104, 200, 134, 248, 161, 4, 211, 44, 104, 200, 134, 248, + 161, 4, 55, 211, 44, 104, 154, 200, 134, 248, 161, 4, 55, 211, 44, 199, + 205, 1, 65, 199, 205, 1, 252, 208, 199, 205, 1, 68, 199, 205, 1, 223, + 201, 199, 205, 1, 66, 199, 205, 1, 196, 30, 199, 205, 1, 71, 199, 205, 1, + 251, 238, 199, 205, 1, 74, 199, 205, 1, 250, 165, 199, 205, 1, 155, 199, + 205, 1, 221, 217, 199, 205, 1, 231, 242, 199, 205, 1, 231, 93, 199, 205, + 1, 214, 70, 199, 205, 1, 247, 162, 199, 205, 1, 247, 3, 199, 205, 1, 223, + 34, 199, 205, 1, 222, 254, 199, 205, 1, 212, 103, 199, 205, 1, 197, 132, + 199, 205, 1, 197, 120, 199, 205, 1, 237, 193, 199, 205, 1, 237, 177, 199, + 205, 1, 213, 81, 199, 205, 1, 190, 190, 199, 205, 1, 199, 49, 199, 205, + 1, 238, 34, 199, 205, 1, 237, 70, 199, 205, 1, 181, 199, 205, 1, 168, + 199, 205, 1, 209, 230, 199, 205, 1, 249, 155, 199, 205, 1, 248, 205, 199, 205, 1, 174, 199, 205, 1, 170, 199, 205, 1, 165, 199, 205, 1, 173, 199, - 205, 1, 195, 188, 199, 205, 1, 203, 165, 199, 205, 1, 188, 199, 205, 1, - 140, 199, 205, 1, 206, 109, 199, 205, 3, 251, 71, 199, 205, 3, 195, 35, - 199, 205, 18, 3, 252, 206, 199, 205, 18, 3, 68, 199, 205, 18, 3, 223, - 199, 199, 205, 18, 3, 66, 199, 205, 18, 3, 196, 30, 199, 205, 18, 3, 71, - 199, 205, 18, 3, 251, 236, 199, 205, 18, 3, 74, 199, 205, 18, 3, 250, - 163, 199, 205, 3, 195, 40, 199, 205, 3, 212, 141, 199, 205, 1, 251, 14, - 221, 215, 199, 205, 252, 68, 56, 199, 205, 17, 191, 77, 199, 205, 17, + 205, 1, 195, 188, 199, 205, 1, 203, 166, 199, 205, 1, 188, 199, 205, 1, + 140, 199, 205, 1, 206, 110, 199, 205, 3, 251, 73, 199, 205, 3, 195, 35, + 199, 205, 18, 3, 252, 208, 199, 205, 18, 3, 68, 199, 205, 18, 3, 223, + 201, 199, 205, 18, 3, 66, 199, 205, 18, 3, 196, 30, 199, 205, 18, 3, 71, + 199, 205, 18, 3, 251, 238, 199, 205, 18, 3, 74, 199, 205, 18, 3, 250, + 165, 199, 205, 3, 195, 40, 199, 205, 3, 212, 143, 199, 205, 1, 251, 16, + 221, 217, 199, 205, 252, 70, 56, 199, 205, 17, 191, 77, 199, 205, 17, 107, 199, 205, 17, 109, 199, 205, 17, 138, 199, 205, 17, 134, 199, 205, - 17, 149, 199, 205, 17, 169, 199, 205, 17, 175, 199, 205, 17, 171, 199, - 205, 17, 178, 251, 240, 1, 155, 251, 240, 1, 221, 215, 251, 240, 1, 214, - 68, 251, 240, 1, 180, 251, 240, 1, 190, 190, 251, 240, 1, 251, 157, 190, - 190, 251, 240, 1, 168, 251, 240, 1, 209, 228, 251, 240, 1, 249, 153, 251, - 240, 1, 174, 251, 240, 1, 223, 32, 251, 240, 1, 247, 1, 251, 240, 1, 199, - 49, 251, 240, 1, 165, 251, 240, 1, 173, 251, 240, 1, 188, 251, 240, 1, - 212, 101, 251, 240, 1, 140, 251, 240, 1, 65, 251, 240, 1, 238, 32, 251, - 240, 1, 237, 68, 251, 240, 1, 231, 240, 251, 240, 1, 251, 157, 231, 240, - 251, 240, 1, 231, 91, 251, 240, 1, 248, 203, 251, 240, 1, 222, 252, 251, - 240, 1, 251, 157, 249, 153, 251, 240, 120, 3, 216, 217, 173, 251, 240, - 120, 3, 216, 217, 165, 251, 240, 120, 3, 216, 217, 219, 133, 165, 251, - 240, 18, 3, 65, 251, 240, 18, 3, 252, 206, 251, 240, 18, 3, 68, 251, 240, - 18, 3, 223, 199, 251, 240, 18, 3, 66, 251, 240, 18, 3, 196, 30, 251, 240, - 18, 3, 71, 251, 240, 18, 3, 250, 140, 251, 240, 18, 3, 74, 251, 240, 18, - 3, 251, 236, 251, 240, 18, 3, 251, 149, 251, 240, 3, 221, 143, 251, 240, - 17, 191, 77, 251, 240, 17, 107, 251, 240, 17, 109, 251, 240, 17, 138, - 251, 240, 17, 134, 251, 240, 17, 149, 251, 240, 17, 169, 251, 240, 17, - 175, 251, 240, 17, 171, 251, 240, 17, 178, 251, 240, 31, 199, 95, 251, - 240, 31, 197, 32, 251, 240, 3, 2, 205, 53, 251, 240, 3, 205, 53, 251, - 240, 3, 206, 53, 251, 240, 16, 195, 69, 251, 240, 1, 247, 160, 251, 240, - 1, 197, 132, 251, 240, 1, 197, 120, 251, 240, 1, 237, 191, 251, 240, 1, - 237, 175, 251, 240, 1, 213, 79, 251, 240, 1, 219, 73, 236, 161, 1, 65, - 236, 161, 1, 252, 206, 236, 161, 1, 68, 236, 161, 1, 223, 199, 236, 161, - 1, 66, 236, 161, 1, 196, 30, 236, 161, 1, 71, 236, 161, 1, 251, 236, 236, - 161, 1, 74, 236, 161, 1, 250, 163, 236, 161, 1, 155, 236, 161, 1, 221, - 215, 236, 161, 1, 231, 240, 236, 161, 1, 231, 91, 236, 161, 1, 214, 68, - 236, 161, 1, 247, 160, 236, 161, 1, 247, 1, 236, 161, 1, 223, 32, 236, - 161, 1, 222, 252, 236, 161, 1, 212, 101, 236, 161, 1, 197, 132, 236, 161, - 1, 197, 120, 236, 161, 1, 237, 191, 236, 161, 1, 237, 175, 236, 161, 1, - 213, 79, 236, 161, 1, 190, 190, 236, 161, 1, 199, 49, 236, 161, 1, 238, - 32, 236, 161, 1, 237, 68, 236, 161, 1, 180, 236, 161, 1, 168, 236, 161, - 1, 209, 228, 236, 161, 1, 249, 153, 236, 161, 1, 248, 203, 236, 161, 1, - 174, 236, 161, 1, 170, 236, 161, 1, 165, 236, 161, 1, 173, 236, 161, 1, - 195, 188, 236, 161, 1, 203, 165, 236, 161, 1, 201, 175, 236, 161, 1, 188, - 236, 161, 1, 140, 236, 161, 1, 206, 109, 236, 161, 18, 3, 252, 206, 236, - 161, 18, 3, 68, 236, 161, 18, 3, 223, 199, 236, 161, 18, 3, 66, 236, 161, - 18, 3, 196, 30, 236, 161, 18, 3, 117, 146, 236, 161, 18, 3, 117, 206, - 110, 236, 161, 18, 3, 71, 236, 161, 18, 3, 251, 236, 236, 161, 18, 3, 74, - 236, 161, 18, 3, 250, 163, 236, 161, 3, 251, 71, 236, 161, 3, 195, 35, - 236, 161, 3, 195, 40, 236, 161, 3, 212, 141, 236, 161, 252, 68, 56, 193, - 156, 242, 253, 6, 1, 214, 67, 193, 156, 242, 253, 6, 1, 65, 193, 156, - 242, 253, 6, 1, 193, 86, 193, 156, 242, 253, 6, 1, 191, 225, 193, 156, - 242, 253, 6, 1, 170, 193, 156, 242, 253, 6, 1, 192, 12, 193, 156, 242, - 253, 6, 1, 223, 199, 193, 156, 242, 253, 6, 1, 196, 30, 193, 156, 242, - 253, 6, 1, 71, 193, 156, 242, 253, 6, 1, 74, 193, 156, 242, 253, 6, 1, - 251, 122, 193, 156, 242, 253, 6, 1, 231, 240, 193, 156, 242, 253, 6, 1, - 221, 67, 193, 156, 242, 253, 6, 1, 234, 66, 193, 156, 242, 253, 6, 1, - 191, 204, 193, 156, 242, 253, 6, 1, 196, 160, 193, 156, 242, 253, 6, 1, - 234, 85, 193, 156, 242, 253, 6, 1, 211, 154, 193, 156, 242, 253, 6, 1, - 197, 127, 193, 156, 242, 253, 6, 1, 212, 127, 193, 156, 242, 253, 6, 1, - 238, 32, 193, 156, 242, 253, 6, 1, 250, 182, 193, 156, 242, 253, 6, 1, - 251, 149, 193, 156, 242, 253, 6, 1, 248, 10, 193, 156, 242, 253, 6, 1, - 208, 165, 193, 156, 242, 253, 6, 1, 229, 115, 193, 156, 242, 253, 6, 1, - 229, 3, 193, 156, 242, 253, 6, 1, 228, 185, 193, 156, 242, 253, 6, 1, - 230, 19, 193, 156, 242, 253, 6, 1, 201, 126, 193, 156, 242, 253, 6, 1, - 202, 193, 193, 156, 242, 253, 6, 1, 195, 25, 193, 156, 242, 253, 2, 1, - 214, 67, 193, 156, 242, 253, 2, 1, 65, 193, 156, 242, 253, 2, 1, 193, 86, - 193, 156, 242, 253, 2, 1, 191, 225, 193, 156, 242, 253, 2, 1, 170, 193, - 156, 242, 253, 2, 1, 192, 12, 193, 156, 242, 253, 2, 1, 223, 199, 193, - 156, 242, 253, 2, 1, 196, 30, 193, 156, 242, 253, 2, 1, 71, 193, 156, - 242, 253, 2, 1, 74, 193, 156, 242, 253, 2, 1, 251, 122, 193, 156, 242, - 253, 2, 1, 231, 240, 193, 156, 242, 253, 2, 1, 221, 67, 193, 156, 242, - 253, 2, 1, 234, 66, 193, 156, 242, 253, 2, 1, 191, 204, 193, 156, 242, - 253, 2, 1, 196, 160, 193, 156, 242, 253, 2, 1, 234, 85, 193, 156, 242, - 253, 2, 1, 211, 154, 193, 156, 242, 253, 2, 1, 197, 127, 193, 156, 242, - 253, 2, 1, 212, 127, 193, 156, 242, 253, 2, 1, 238, 32, 193, 156, 242, - 253, 2, 1, 250, 182, 193, 156, 242, 253, 2, 1, 251, 149, 193, 156, 242, - 253, 2, 1, 248, 10, 193, 156, 242, 253, 2, 1, 208, 165, 193, 156, 242, - 253, 2, 1, 229, 115, 193, 156, 242, 253, 2, 1, 229, 3, 193, 156, 242, - 253, 2, 1, 228, 185, 193, 156, 242, 253, 2, 1, 230, 19, 193, 156, 242, - 253, 2, 1, 201, 126, 193, 156, 242, 253, 2, 1, 202, 193, 193, 156, 242, - 253, 2, 1, 195, 25, 193, 156, 242, 253, 17, 191, 77, 193, 156, 242, 253, - 17, 107, 193, 156, 242, 253, 17, 109, 193, 156, 242, 253, 17, 138, 193, - 156, 242, 253, 17, 134, 193, 156, 242, 253, 17, 149, 193, 156, 242, 253, - 17, 169, 193, 156, 242, 253, 17, 175, 193, 156, 242, 253, 17, 171, 193, - 156, 242, 253, 17, 178, 193, 156, 242, 253, 31, 199, 95, 193, 156, 242, - 253, 31, 197, 32, 193, 156, 242, 253, 31, 198, 249, 193, 156, 242, 253, - 31, 232, 135, 193, 156, 242, 253, 31, 233, 15, 193, 156, 242, 253, 31, - 202, 120, 193, 156, 242, 253, 31, 203, 241, 193, 156, 242, 253, 31, 234, - 153, 193, 156, 242, 253, 31, 213, 169, 193, 156, 242, 253, 211, 113, 236, - 209, 251, 209, 1, 65, 236, 209, 251, 209, 1, 252, 206, 236, 209, 251, - 209, 1, 68, 236, 209, 251, 209, 1, 223, 199, 236, 209, 251, 209, 1, 66, - 236, 209, 251, 209, 1, 196, 30, 236, 209, 251, 209, 1, 71, 236, 209, 251, - 209, 1, 74, 236, 209, 251, 209, 1, 155, 236, 209, 251, 209, 1, 221, 215, - 236, 209, 251, 209, 1, 231, 240, 236, 209, 251, 209, 1, 231, 91, 236, - 209, 251, 209, 1, 214, 68, 236, 209, 251, 209, 1, 247, 160, 236, 209, - 251, 209, 1, 247, 1, 236, 209, 251, 209, 1, 223, 32, 236, 209, 251, 209, - 1, 212, 101, 236, 209, 251, 209, 1, 197, 132, 236, 209, 251, 209, 1, 237, - 191, 236, 209, 251, 209, 1, 237, 175, 236, 209, 251, 209, 1, 213, 79, - 236, 209, 251, 209, 1, 190, 190, 236, 209, 251, 209, 1, 199, 49, 236, - 209, 251, 209, 1, 238, 32, 236, 209, 251, 209, 1, 237, 68, 236, 209, 251, - 209, 1, 180, 236, 209, 251, 209, 1, 168, 236, 209, 251, 209, 1, 209, 228, - 236, 209, 251, 209, 1, 249, 153, 236, 209, 251, 209, 1, 248, 203, 236, - 209, 251, 209, 1, 174, 236, 209, 251, 209, 1, 170, 236, 209, 251, 209, 1, - 191, 175, 236, 209, 251, 209, 1, 165, 236, 209, 251, 209, 1, 173, 236, - 209, 251, 209, 1, 195, 188, 236, 209, 251, 209, 1, 203, 165, 236, 209, - 251, 209, 1, 201, 175, 236, 209, 251, 209, 1, 188, 236, 209, 251, 209, 1, - 140, 236, 209, 251, 209, 1, 219, 73, 236, 209, 251, 209, 1, 191, 123, - 236, 209, 251, 209, 18, 3, 252, 206, 236, 209, 251, 209, 18, 3, 68, 236, - 209, 251, 209, 18, 3, 223, 199, 236, 209, 251, 209, 18, 3, 66, 236, 209, - 251, 209, 18, 3, 196, 30, 236, 209, 251, 209, 18, 3, 71, 236, 209, 251, - 209, 18, 3, 251, 236, 236, 209, 251, 209, 18, 3, 74, 236, 209, 251, 209, - 3, 251, 71, 236, 209, 251, 209, 3, 247, 119, 236, 209, 251, 209, 3, 230, - 72, 236, 209, 251, 209, 195, 40, 236, 209, 251, 209, 208, 227, 214, 214, - 56, 236, 209, 251, 209, 216, 217, 170, 236, 209, 251, 209, 89, 165, 236, - 209, 251, 209, 216, 217, 165, 236, 209, 251, 209, 3, 212, 141, 236, 209, - 251, 209, 55, 237, 238, 236, 209, 251, 209, 231, 204, 233, 3, 236, 209, - 251, 209, 234, 95, 79, 199, 54, 77, 236, 209, 251, 209, 17, 191, 77, 236, - 209, 251, 209, 17, 107, 236, 209, 251, 209, 17, 109, 236, 209, 251, 209, - 17, 138, 236, 209, 251, 209, 17, 134, 236, 209, 251, 209, 17, 149, 236, - 209, 251, 209, 17, 169, 236, 209, 251, 209, 17, 175, 236, 209, 251, 209, - 17, 171, 236, 209, 251, 209, 17, 178, 214, 223, 1, 65, 214, 223, 1, 252, - 206, 214, 223, 1, 68, 214, 223, 1, 223, 199, 214, 223, 1, 66, 214, 223, - 1, 196, 30, 214, 223, 1, 117, 146, 214, 223, 1, 117, 206, 110, 214, 223, - 1, 71, 214, 223, 1, 251, 236, 214, 223, 1, 74, 214, 223, 1, 250, 163, - 214, 223, 1, 155, 214, 223, 1, 221, 215, 214, 223, 1, 231, 240, 214, 223, - 1, 231, 91, 214, 223, 1, 214, 68, 214, 223, 1, 247, 160, 214, 223, 1, - 247, 1, 214, 223, 1, 223, 32, 214, 223, 1, 222, 252, 214, 223, 1, 212, - 101, 214, 223, 1, 197, 132, 214, 223, 1, 197, 120, 214, 223, 1, 237, 191, - 214, 223, 1, 237, 175, 214, 223, 1, 213, 79, 214, 223, 1, 190, 190, 214, - 223, 1, 199, 49, 214, 223, 1, 238, 32, 214, 223, 1, 237, 68, 214, 223, 1, - 180, 214, 223, 1, 168, 214, 223, 1, 209, 228, 214, 223, 1, 249, 153, 214, - 223, 1, 248, 203, 214, 223, 1, 174, 214, 223, 1, 170, 214, 223, 1, 165, - 214, 223, 1, 173, 214, 223, 1, 195, 188, 214, 223, 1, 203, 165, 214, 223, - 1, 201, 175, 214, 223, 1, 188, 214, 223, 1, 140, 214, 223, 1, 219, 73, - 214, 223, 1, 206, 109, 214, 223, 18, 3, 252, 206, 214, 223, 18, 3, 68, - 214, 223, 18, 3, 223, 199, 214, 223, 18, 3, 66, 214, 223, 18, 3, 196, 30, - 214, 223, 18, 3, 117, 146, 214, 223, 18, 3, 117, 206, 110, 214, 223, 18, - 3, 71, 214, 223, 18, 3, 251, 236, 214, 223, 18, 3, 74, 214, 223, 18, 3, - 250, 163, 214, 223, 3, 251, 71, 214, 223, 3, 195, 35, 214, 223, 3, 195, - 40, 214, 223, 3, 250, 145, 214, 223, 3, 202, 210, 214, 223, 229, 227, - 214, 223, 18, 3, 208, 207, 71, 191, 106, 51, 1, 65, 191, 106, 51, 18, 3, + 17, 150, 199, 205, 17, 169, 199, 205, 17, 175, 199, 205, 17, 171, 199, + 205, 17, 178, 251, 242, 1, 155, 251, 242, 1, 221, 217, 251, 242, 1, 214, + 70, 251, 242, 1, 181, 251, 242, 1, 190, 190, 251, 242, 1, 251, 159, 190, + 190, 251, 242, 1, 168, 251, 242, 1, 209, 230, 251, 242, 1, 249, 155, 251, + 242, 1, 174, 251, 242, 1, 223, 34, 251, 242, 1, 247, 3, 251, 242, 1, 199, + 49, 251, 242, 1, 165, 251, 242, 1, 173, 251, 242, 1, 188, 251, 242, 1, + 212, 103, 251, 242, 1, 140, 251, 242, 1, 65, 251, 242, 1, 238, 34, 251, + 242, 1, 237, 70, 251, 242, 1, 231, 242, 251, 242, 1, 251, 159, 231, 242, + 251, 242, 1, 231, 93, 251, 242, 1, 248, 205, 251, 242, 1, 222, 254, 251, + 242, 1, 251, 159, 249, 155, 251, 242, 120, 3, 216, 219, 173, 251, 242, + 120, 3, 216, 219, 165, 251, 242, 120, 3, 216, 219, 219, 135, 165, 251, + 242, 18, 3, 65, 251, 242, 18, 3, 252, 208, 251, 242, 18, 3, 68, 251, 242, + 18, 3, 223, 201, 251, 242, 18, 3, 66, 251, 242, 18, 3, 196, 30, 251, 242, + 18, 3, 71, 251, 242, 18, 3, 250, 142, 251, 242, 18, 3, 74, 251, 242, 18, + 3, 251, 238, 251, 242, 18, 3, 251, 151, 251, 242, 3, 221, 145, 251, 242, + 17, 191, 77, 251, 242, 17, 107, 251, 242, 17, 109, 251, 242, 17, 138, + 251, 242, 17, 134, 251, 242, 17, 150, 251, 242, 17, 169, 251, 242, 17, + 175, 251, 242, 17, 171, 251, 242, 17, 178, 251, 242, 31, 199, 95, 251, + 242, 31, 197, 32, 251, 242, 3, 2, 205, 54, 251, 242, 3, 205, 54, 251, + 242, 3, 206, 54, 251, 242, 16, 195, 69, 251, 242, 1, 247, 162, 251, 242, + 1, 197, 132, 251, 242, 1, 197, 120, 251, 242, 1, 237, 193, 251, 242, 1, + 237, 177, 251, 242, 1, 213, 81, 251, 242, 1, 219, 75, 236, 163, 1, 65, + 236, 163, 1, 252, 208, 236, 163, 1, 68, 236, 163, 1, 223, 201, 236, 163, + 1, 66, 236, 163, 1, 196, 30, 236, 163, 1, 71, 236, 163, 1, 251, 238, 236, + 163, 1, 74, 236, 163, 1, 250, 165, 236, 163, 1, 155, 236, 163, 1, 221, + 217, 236, 163, 1, 231, 242, 236, 163, 1, 231, 93, 236, 163, 1, 214, 70, + 236, 163, 1, 247, 162, 236, 163, 1, 247, 3, 236, 163, 1, 223, 34, 236, + 163, 1, 222, 254, 236, 163, 1, 212, 103, 236, 163, 1, 197, 132, 236, 163, + 1, 197, 120, 236, 163, 1, 237, 193, 236, 163, 1, 237, 177, 236, 163, 1, + 213, 81, 236, 163, 1, 190, 190, 236, 163, 1, 199, 49, 236, 163, 1, 238, + 34, 236, 163, 1, 237, 70, 236, 163, 1, 181, 236, 163, 1, 168, 236, 163, + 1, 209, 230, 236, 163, 1, 249, 155, 236, 163, 1, 248, 205, 236, 163, 1, + 174, 236, 163, 1, 170, 236, 163, 1, 165, 236, 163, 1, 173, 236, 163, 1, + 195, 188, 236, 163, 1, 203, 166, 236, 163, 1, 201, 176, 236, 163, 1, 188, + 236, 163, 1, 140, 236, 163, 1, 206, 110, 236, 163, 18, 3, 252, 208, 236, + 163, 18, 3, 68, 236, 163, 18, 3, 223, 201, 236, 163, 18, 3, 66, 236, 163, + 18, 3, 196, 30, 236, 163, 18, 3, 117, 146, 236, 163, 18, 3, 117, 206, + 111, 236, 163, 18, 3, 71, 236, 163, 18, 3, 251, 238, 236, 163, 18, 3, 74, + 236, 163, 18, 3, 250, 165, 236, 163, 3, 251, 73, 236, 163, 3, 195, 35, + 236, 163, 3, 195, 40, 236, 163, 3, 212, 143, 236, 163, 252, 70, 56, 193, + 156, 242, 255, 6, 1, 214, 69, 193, 156, 242, 255, 6, 1, 65, 193, 156, + 242, 255, 6, 1, 193, 86, 193, 156, 242, 255, 6, 1, 191, 225, 193, 156, + 242, 255, 6, 1, 170, 193, 156, 242, 255, 6, 1, 192, 12, 193, 156, 242, + 255, 6, 1, 223, 201, 193, 156, 242, 255, 6, 1, 196, 30, 193, 156, 242, + 255, 6, 1, 71, 193, 156, 242, 255, 6, 1, 74, 193, 156, 242, 255, 6, 1, + 251, 124, 193, 156, 242, 255, 6, 1, 231, 242, 193, 156, 242, 255, 6, 1, + 221, 69, 193, 156, 242, 255, 6, 1, 234, 68, 193, 156, 242, 255, 6, 1, + 191, 204, 193, 156, 242, 255, 6, 1, 196, 160, 193, 156, 242, 255, 6, 1, + 234, 87, 193, 156, 242, 255, 6, 1, 211, 156, 193, 156, 242, 255, 6, 1, + 197, 127, 193, 156, 242, 255, 6, 1, 212, 129, 193, 156, 242, 255, 6, 1, + 238, 34, 193, 156, 242, 255, 6, 1, 250, 184, 193, 156, 242, 255, 6, 1, + 251, 151, 193, 156, 242, 255, 6, 1, 248, 12, 193, 156, 242, 255, 6, 1, + 208, 167, 193, 156, 242, 255, 6, 1, 229, 117, 193, 156, 242, 255, 6, 1, + 229, 5, 193, 156, 242, 255, 6, 1, 228, 187, 193, 156, 242, 255, 6, 1, + 230, 21, 193, 156, 242, 255, 6, 1, 201, 127, 193, 156, 242, 255, 6, 1, + 202, 194, 193, 156, 242, 255, 6, 1, 195, 25, 193, 156, 242, 255, 2, 1, + 214, 69, 193, 156, 242, 255, 2, 1, 65, 193, 156, 242, 255, 2, 1, 193, 86, + 193, 156, 242, 255, 2, 1, 191, 225, 193, 156, 242, 255, 2, 1, 170, 193, + 156, 242, 255, 2, 1, 192, 12, 193, 156, 242, 255, 2, 1, 223, 201, 193, + 156, 242, 255, 2, 1, 196, 30, 193, 156, 242, 255, 2, 1, 71, 193, 156, + 242, 255, 2, 1, 74, 193, 156, 242, 255, 2, 1, 251, 124, 193, 156, 242, + 255, 2, 1, 231, 242, 193, 156, 242, 255, 2, 1, 221, 69, 193, 156, 242, + 255, 2, 1, 234, 68, 193, 156, 242, 255, 2, 1, 191, 204, 193, 156, 242, + 255, 2, 1, 196, 160, 193, 156, 242, 255, 2, 1, 234, 87, 193, 156, 242, + 255, 2, 1, 211, 156, 193, 156, 242, 255, 2, 1, 197, 127, 193, 156, 242, + 255, 2, 1, 212, 129, 193, 156, 242, 255, 2, 1, 238, 34, 193, 156, 242, + 255, 2, 1, 250, 184, 193, 156, 242, 255, 2, 1, 251, 151, 193, 156, 242, + 255, 2, 1, 248, 12, 193, 156, 242, 255, 2, 1, 208, 167, 193, 156, 242, + 255, 2, 1, 229, 117, 193, 156, 242, 255, 2, 1, 229, 5, 193, 156, 242, + 255, 2, 1, 228, 187, 193, 156, 242, 255, 2, 1, 230, 21, 193, 156, 242, + 255, 2, 1, 201, 127, 193, 156, 242, 255, 2, 1, 202, 194, 193, 156, 242, + 255, 2, 1, 195, 25, 193, 156, 242, 255, 17, 191, 77, 193, 156, 242, 255, + 17, 107, 193, 156, 242, 255, 17, 109, 193, 156, 242, 255, 17, 138, 193, + 156, 242, 255, 17, 134, 193, 156, 242, 255, 17, 150, 193, 156, 242, 255, + 17, 169, 193, 156, 242, 255, 17, 175, 193, 156, 242, 255, 17, 171, 193, + 156, 242, 255, 17, 178, 193, 156, 242, 255, 31, 199, 95, 193, 156, 242, + 255, 31, 197, 32, 193, 156, 242, 255, 31, 198, 249, 193, 156, 242, 255, + 31, 232, 137, 193, 156, 242, 255, 31, 233, 17, 193, 156, 242, 255, 31, + 202, 121, 193, 156, 242, 255, 31, 203, 242, 193, 156, 242, 255, 31, 234, + 155, 193, 156, 242, 255, 31, 213, 171, 193, 156, 242, 255, 211, 115, 236, + 211, 251, 211, 1, 65, 236, 211, 251, 211, 1, 252, 208, 236, 211, 251, + 211, 1, 68, 236, 211, 251, 211, 1, 223, 201, 236, 211, 251, 211, 1, 66, + 236, 211, 251, 211, 1, 196, 30, 236, 211, 251, 211, 1, 71, 236, 211, 251, + 211, 1, 74, 236, 211, 251, 211, 1, 155, 236, 211, 251, 211, 1, 221, 217, + 236, 211, 251, 211, 1, 231, 242, 236, 211, 251, 211, 1, 231, 93, 236, + 211, 251, 211, 1, 214, 70, 236, 211, 251, 211, 1, 247, 162, 236, 211, + 251, 211, 1, 247, 3, 236, 211, 251, 211, 1, 223, 34, 236, 211, 251, 211, + 1, 212, 103, 236, 211, 251, 211, 1, 197, 132, 236, 211, 251, 211, 1, 237, + 193, 236, 211, 251, 211, 1, 237, 177, 236, 211, 251, 211, 1, 213, 81, + 236, 211, 251, 211, 1, 190, 190, 236, 211, 251, 211, 1, 199, 49, 236, + 211, 251, 211, 1, 238, 34, 236, 211, 251, 211, 1, 237, 70, 236, 211, 251, + 211, 1, 181, 236, 211, 251, 211, 1, 168, 236, 211, 251, 211, 1, 209, 230, + 236, 211, 251, 211, 1, 249, 155, 236, 211, 251, 211, 1, 248, 205, 236, + 211, 251, 211, 1, 174, 236, 211, 251, 211, 1, 170, 236, 211, 251, 211, 1, + 191, 175, 236, 211, 251, 211, 1, 165, 236, 211, 251, 211, 1, 173, 236, + 211, 251, 211, 1, 195, 188, 236, 211, 251, 211, 1, 203, 166, 236, 211, + 251, 211, 1, 201, 176, 236, 211, 251, 211, 1, 188, 236, 211, 251, 211, 1, + 140, 236, 211, 251, 211, 1, 219, 75, 236, 211, 251, 211, 1, 191, 123, + 236, 211, 251, 211, 18, 3, 252, 208, 236, 211, 251, 211, 18, 3, 68, 236, + 211, 251, 211, 18, 3, 223, 201, 236, 211, 251, 211, 18, 3, 66, 236, 211, + 251, 211, 18, 3, 196, 30, 236, 211, 251, 211, 18, 3, 71, 236, 211, 251, + 211, 18, 3, 251, 238, 236, 211, 251, 211, 18, 3, 74, 236, 211, 251, 211, + 3, 251, 73, 236, 211, 251, 211, 3, 247, 121, 236, 211, 251, 211, 3, 230, + 74, 236, 211, 251, 211, 195, 40, 236, 211, 251, 211, 208, 229, 214, 216, + 56, 236, 211, 251, 211, 216, 219, 170, 236, 211, 251, 211, 89, 165, 236, + 211, 251, 211, 216, 219, 165, 236, 211, 251, 211, 3, 212, 143, 236, 211, + 251, 211, 55, 237, 240, 236, 211, 251, 211, 231, 206, 233, 5, 236, 211, + 251, 211, 234, 97, 79, 199, 54, 77, 236, 211, 251, 211, 17, 191, 77, 236, + 211, 251, 211, 17, 107, 236, 211, 251, 211, 17, 109, 236, 211, 251, 211, + 17, 138, 236, 211, 251, 211, 17, 134, 236, 211, 251, 211, 17, 150, 236, + 211, 251, 211, 17, 169, 236, 211, 251, 211, 17, 175, 236, 211, 251, 211, + 17, 171, 236, 211, 251, 211, 17, 178, 214, 225, 1, 65, 214, 225, 1, 252, + 208, 214, 225, 1, 68, 214, 225, 1, 223, 201, 214, 225, 1, 66, 214, 225, + 1, 196, 30, 214, 225, 1, 117, 146, 214, 225, 1, 117, 206, 111, 214, 225, + 1, 71, 214, 225, 1, 251, 238, 214, 225, 1, 74, 214, 225, 1, 250, 165, + 214, 225, 1, 155, 214, 225, 1, 221, 217, 214, 225, 1, 231, 242, 214, 225, + 1, 231, 93, 214, 225, 1, 214, 70, 214, 225, 1, 247, 162, 214, 225, 1, + 247, 3, 214, 225, 1, 223, 34, 214, 225, 1, 222, 254, 214, 225, 1, 212, + 103, 214, 225, 1, 197, 132, 214, 225, 1, 197, 120, 214, 225, 1, 237, 193, + 214, 225, 1, 237, 177, 214, 225, 1, 213, 81, 214, 225, 1, 190, 190, 214, + 225, 1, 199, 49, 214, 225, 1, 238, 34, 214, 225, 1, 237, 70, 214, 225, 1, + 181, 214, 225, 1, 168, 214, 225, 1, 209, 230, 214, 225, 1, 249, 155, 214, + 225, 1, 248, 205, 214, 225, 1, 174, 214, 225, 1, 170, 214, 225, 1, 165, + 214, 225, 1, 173, 214, 225, 1, 195, 188, 214, 225, 1, 203, 166, 214, 225, + 1, 201, 176, 214, 225, 1, 188, 214, 225, 1, 140, 214, 225, 1, 219, 75, + 214, 225, 1, 206, 110, 214, 225, 18, 3, 252, 208, 214, 225, 18, 3, 68, + 214, 225, 18, 3, 223, 201, 214, 225, 18, 3, 66, 214, 225, 18, 3, 196, 30, + 214, 225, 18, 3, 117, 146, 214, 225, 18, 3, 117, 206, 111, 214, 225, 18, + 3, 71, 214, 225, 18, 3, 251, 238, 214, 225, 18, 3, 74, 214, 225, 18, 3, + 250, 165, 214, 225, 3, 251, 73, 214, 225, 3, 195, 35, 214, 225, 3, 195, + 40, 214, 225, 3, 250, 147, 214, 225, 3, 202, 211, 214, 225, 229, 229, + 214, 225, 18, 3, 208, 209, 71, 191, 106, 51, 1, 65, 191, 106, 51, 18, 3, 68, 191, 106, 51, 18, 3, 196, 152, 191, 106, 51, 18, 3, 66, 191, 106, 51, - 18, 3, 71, 191, 106, 51, 18, 3, 211, 151, 191, 106, 51, 18, 3, 74, 191, - 106, 51, 18, 3, 251, 236, 191, 106, 51, 18, 3, 250, 163, 191, 106, 51, - 18, 3, 207, 18, 68, 191, 106, 51, 18, 219, 198, 77, 191, 106, 51, 1, 155, - 191, 106, 51, 1, 221, 215, 191, 106, 51, 1, 231, 240, 191, 106, 51, 1, - 231, 91, 191, 106, 51, 1, 214, 68, 191, 106, 51, 1, 247, 160, 191, 106, - 51, 1, 247, 1, 191, 106, 51, 1, 223, 32, 191, 106, 51, 1, 212, 101, 191, + 18, 3, 71, 191, 106, 51, 18, 3, 211, 153, 191, 106, 51, 18, 3, 74, 191, + 106, 51, 18, 3, 251, 238, 191, 106, 51, 18, 3, 250, 165, 191, 106, 51, + 18, 3, 207, 19, 68, 191, 106, 51, 18, 219, 200, 77, 191, 106, 51, 1, 155, + 191, 106, 51, 1, 221, 217, 191, 106, 51, 1, 231, 242, 191, 106, 51, 1, + 231, 93, 191, 106, 51, 1, 214, 70, 191, 106, 51, 1, 247, 162, 191, 106, + 51, 1, 247, 3, 191, 106, 51, 1, 223, 34, 191, 106, 51, 1, 212, 103, 191, 106, 51, 1, 197, 132, 191, 106, 51, 1, 197, 120, 191, 106, 51, 1, 237, - 191, 191, 106, 51, 1, 237, 175, 191, 106, 51, 1, 213, 79, 191, 106, 51, - 1, 190, 190, 191, 106, 51, 1, 199, 49, 191, 106, 51, 1, 238, 32, 191, - 106, 51, 1, 237, 68, 191, 106, 51, 1, 180, 191, 106, 51, 1, 168, 191, - 106, 51, 1, 209, 228, 191, 106, 51, 1, 249, 153, 191, 106, 51, 1, 248, - 203, 191, 106, 51, 1, 174, 191, 106, 51, 1, 197, 168, 191, 106, 51, 1, - 197, 157, 191, 106, 51, 1, 235, 35, 191, 106, 51, 1, 235, 29, 191, 106, - 51, 1, 191, 71, 191, 106, 51, 1, 191, 123, 191, 106, 51, 1, 255, 214, + 193, 191, 106, 51, 1, 237, 177, 191, 106, 51, 1, 213, 81, 191, 106, 51, + 1, 190, 190, 191, 106, 51, 1, 199, 49, 191, 106, 51, 1, 238, 34, 191, + 106, 51, 1, 237, 70, 191, 106, 51, 1, 181, 191, 106, 51, 1, 168, 191, + 106, 51, 1, 209, 230, 191, 106, 51, 1, 249, 155, 191, 106, 51, 1, 248, + 205, 191, 106, 51, 1, 174, 191, 106, 51, 1, 197, 168, 191, 106, 51, 1, + 197, 157, 191, 106, 51, 1, 235, 37, 191, 106, 51, 1, 235, 31, 191, 106, + 51, 1, 191, 71, 191, 106, 51, 1, 191, 123, 191, 106, 51, 1, 255, 216, 191, 106, 51, 1, 170, 191, 106, 51, 1, 165, 191, 106, 51, 1, 173, 191, - 106, 51, 1, 195, 188, 191, 106, 51, 1, 203, 165, 191, 106, 51, 1, 201, - 175, 191, 106, 51, 1, 188, 191, 106, 51, 1, 140, 191, 106, 51, 1, 220, - 246, 191, 106, 51, 53, 120, 77, 191, 106, 51, 3, 195, 40, 191, 106, 51, - 3, 247, 119, 191, 106, 51, 3, 247, 120, 4, 211, 42, 191, 106, 51, 3, 247, - 122, 4, 211, 42, 191, 106, 51, 3, 251, 71, 191, 106, 51, 3, 195, 35, 191, - 106, 51, 242, 201, 1, 165, 191, 106, 51, 242, 202, 1, 170, 191, 106, 51, - 242, 202, 1, 165, 191, 106, 51, 242, 202, 1, 173, 191, 106, 51, 242, 202, - 1, 195, 188, 191, 106, 51, 89, 229, 236, 77, 191, 106, 51, 242, 215, 229, - 236, 77, 191, 106, 51, 87, 197, 152, 191, 106, 51, 87, 203, 157, 191, - 106, 51, 87, 55, 203, 157, 191, 106, 51, 87, 179, 197, 152, 191, 106, 51, - 89, 235, 130, 229, 236, 77, 191, 106, 51, 242, 215, 235, 130, 229, 236, - 77, 191, 106, 51, 200, 238, 201, 251, 1, 65, 201, 251, 18, 3, 68, 201, - 251, 18, 3, 196, 152, 201, 251, 18, 3, 66, 201, 251, 18, 3, 71, 201, 251, - 18, 3, 74, 201, 251, 18, 3, 211, 151, 201, 251, 18, 3, 251, 236, 201, - 251, 18, 3, 250, 163, 201, 251, 18, 3, 117, 146, 201, 251, 18, 3, 117, - 172, 201, 251, 18, 219, 198, 77, 201, 251, 1, 155, 201, 251, 1, 221, 215, - 201, 251, 1, 231, 240, 201, 251, 1, 231, 91, 201, 251, 1, 214, 68, 201, - 251, 1, 247, 160, 201, 251, 1, 247, 1, 201, 251, 1, 223, 32, 201, 251, 1, - 222, 252, 201, 251, 1, 212, 101, 201, 251, 1, 197, 132, 201, 251, 1, 197, - 120, 201, 251, 1, 237, 191, 201, 251, 1, 237, 175, 201, 251, 1, 213, 79, - 201, 251, 1, 190, 190, 201, 251, 1, 199, 49, 201, 251, 1, 238, 32, 201, - 251, 1, 237, 68, 201, 251, 1, 180, 201, 251, 1, 168, 201, 251, 1, 209, - 228, 201, 251, 1, 249, 153, 201, 251, 1, 248, 203, 201, 251, 1, 174, 201, - 251, 1, 197, 168, 201, 251, 1, 197, 157, 201, 251, 1, 235, 35, 201, 251, - 1, 191, 71, 201, 251, 1, 191, 123, 201, 251, 1, 255, 214, 201, 251, 1, - 170, 201, 251, 1, 165, 201, 251, 1, 173, 201, 251, 1, 195, 188, 201, 251, - 1, 203, 165, 201, 251, 1, 201, 175, 201, 251, 1, 188, 201, 251, 1, 140, - 201, 251, 1, 220, 246, 201, 251, 3, 222, 237, 201, 251, 3, 196, 75, 201, - 251, 242, 201, 1, 165, 201, 251, 242, 201, 1, 173, 201, 251, 242, 201, 1, - 203, 165, 201, 251, 242, 201, 1, 188, 201, 251, 53, 120, 3, 232, 51, 201, - 251, 53, 120, 3, 222, 152, 201, 251, 53, 120, 3, 214, 70, 201, 251, 53, - 120, 3, 238, 127, 201, 251, 53, 120, 3, 215, 61, 201, 251, 53, 120, 3, - 250, 120, 201, 251, 53, 120, 3, 218, 168, 201, 251, 53, 120, 3, 146, 201, - 251, 53, 120, 3, 172, 201, 251, 53, 120, 3, 203, 167, 201, 251, 53, 120, - 3, 206, 8, 201, 251, 53, 120, 3, 255, 214, 201, 251, 3, 251, 71, 201, - 251, 3, 195, 35, 201, 251, 231, 153, 77, 201, 251, 200, 238, 201, 251, - 87, 197, 152, 201, 251, 87, 203, 157, 201, 251, 87, 55, 203, 157, 201, - 251, 87, 209, 79, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 199, 23, - 197, 225, 232, 210, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 199, - 23, 232, 210, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 198, 201, - 251, 199, 81, 217, 55, 201, 251, 199, 81, 217, 54, 21, 22, 214, 207, 229, - 158, 21, 22, 214, 207, 229, 130, 21, 22, 214, 207, 229, 23, 21, 22, 214, - 207, 228, 252, 21, 22, 214, 207, 140, 21, 22, 214, 207, 230, 91, 21, 22, - 214, 207, 203, 15, 21, 22, 214, 207, 203, 14, 21, 22, 214, 207, 203, 11, - 21, 22, 214, 207, 203, 10, 21, 22, 214, 207, 203, 17, 21, 22, 214, 207, - 203, 16, 21, 22, 201, 237, 21, 22, 201, 224, 21, 22, 201, 207, 21, 22, - 201, 249, 210, 81, 243, 15, 230, 3, 1, 168, 210, 81, 243, 15, 230, 3, 1, - 155, 210, 81, 243, 15, 230, 3, 1, 173, 210, 81, 243, 15, 230, 3, 1, 174, - 210, 81, 243, 15, 230, 3, 1, 238, 32, 210, 81, 243, 15, 230, 3, 1, 191, - 123, 210, 81, 243, 15, 230, 3, 1, 195, 188, 210, 81, 243, 15, 230, 3, 1, - 214, 68, 210, 81, 243, 15, 230, 3, 1, 140, 210, 81, 243, 15, 230, 3, 1, - 231, 240, 210, 81, 243, 15, 230, 3, 1, 221, 215, 210, 81, 243, 15, 230, - 3, 1, 188, 210, 81, 243, 15, 230, 3, 1, 249, 153, 210, 81, 243, 15, 230, - 3, 1, 247, 160, 210, 81, 243, 15, 230, 3, 1, 190, 190, 210, 81, 243, 15, - 230, 3, 1, 199, 49, 210, 81, 243, 15, 230, 3, 1, 180, 210, 81, 243, 15, - 230, 3, 1, 209, 228, 210, 81, 243, 15, 230, 3, 1, 165, 210, 81, 243, 15, - 230, 3, 1, 233, 109, 210, 81, 243, 15, 230, 3, 1, 247, 1, 210, 81, 243, - 15, 230, 3, 1, 65, 210, 81, 243, 15, 230, 3, 1, 71, 210, 81, 243, 15, - 230, 3, 1, 68, 210, 81, 243, 15, 230, 3, 1, 74, 210, 81, 243, 15, 230, 3, - 1, 66, 210, 81, 243, 15, 230, 3, 1, 196, 168, 210, 81, 243, 15, 230, 3, - 1, 228, 35, 210, 81, 243, 15, 230, 3, 1, 53, 210, 236, 210, 81, 243, 15, - 230, 3, 1, 53, 222, 152, 210, 81, 243, 15, 230, 3, 1, 53, 200, 43, 210, - 81, 243, 15, 230, 3, 1, 53, 218, 168, 210, 81, 243, 15, 230, 3, 1, 53, - 215, 61, 210, 81, 243, 15, 230, 3, 1, 53, 172, 210, 81, 243, 15, 230, 3, - 1, 53, 193, 224, 210, 81, 243, 15, 230, 3, 1, 53, 214, 70, 210, 81, 243, - 15, 230, 3, 1, 53, 192, 159, 210, 81, 243, 15, 230, 3, 206, 180, 163, - 219, 19, 210, 81, 243, 15, 230, 3, 206, 180, 198, 79, 210, 81, 243, 15, - 230, 3, 205, 138, 231, 11, 201, 63, 210, 81, 243, 15, 230, 3, 206, 180, - 163, 179, 232, 255, 210, 81, 243, 15, 230, 3, 206, 180, 163, 232, 255, - 210, 81, 243, 15, 230, 3, 205, 138, 231, 11, 201, 64, 232, 255, 210, 81, - 243, 15, 230, 3, 205, 138, 163, 219, 19, 210, 81, 243, 15, 230, 3, 205, - 138, 198, 79, 210, 81, 243, 15, 230, 3, 205, 138, 163, 179, 232, 255, - 210, 81, 243, 15, 230, 3, 205, 138, 163, 232, 255, 210, 81, 243, 15, 230, - 3, 216, 85, 198, 79, 210, 81, 243, 15, 230, 3, 231, 11, 201, 64, 195, - 167, 210, 81, 243, 15, 230, 3, 216, 85, 163, 179, 232, 255, 210, 81, 243, - 15, 230, 3, 216, 85, 163, 232, 255, 210, 81, 243, 15, 230, 3, 218, 239, - 163, 219, 19, 210, 81, 243, 15, 230, 3, 218, 239, 198, 79, 210, 81, 243, - 15, 230, 3, 231, 11, 201, 63, 210, 81, 243, 15, 230, 3, 218, 239, 163, - 179, 232, 255, 210, 81, 243, 15, 230, 3, 218, 239, 163, 232, 255, 210, - 81, 243, 15, 230, 3, 231, 11, 201, 64, 232, 255, 100, 229, 236, 77, 100, - 229, 236, 87, 4, 229, 227, 100, 3, 248, 199, 100, 3, 248, 200, 4, 102, - 100, 3, 233, 205, 248, 199, 100, 3, 233, 205, 248, 200, 4, 102, 100, 3, - 193, 102, 232, 225, 248, 199, 100, 3, 193, 102, 213, 174, 248, 199, 100, - 3, 207, 18, 213, 174, 248, 199, 100, 3, 216, 43, 248, 201, 1, 65, 248, - 201, 1, 252, 206, 248, 201, 1, 68, 248, 201, 1, 223, 199, 248, 201, 1, - 66, 248, 201, 1, 196, 30, 248, 201, 1, 117, 146, 248, 201, 1, 117, 206, - 110, 248, 201, 1, 117, 172, 248, 201, 1, 71, 248, 201, 1, 251, 236, 248, - 201, 1, 74, 248, 201, 1, 250, 163, 248, 201, 1, 155, 248, 201, 1, 221, - 215, 248, 201, 1, 231, 240, 248, 201, 1, 231, 91, 248, 201, 1, 214, 68, - 248, 201, 1, 247, 160, 248, 201, 1, 247, 1, 248, 201, 1, 223, 32, 248, - 201, 1, 222, 252, 248, 201, 1, 212, 101, 248, 201, 1, 197, 132, 248, 201, - 1, 197, 120, 248, 201, 1, 237, 191, 248, 201, 1, 237, 175, 248, 201, 1, - 213, 79, 248, 201, 1, 190, 190, 248, 201, 1, 199, 49, 248, 201, 1, 238, - 32, 248, 201, 1, 237, 68, 248, 201, 1, 180, 248, 201, 1, 168, 248, 201, - 1, 209, 228, 248, 201, 1, 249, 153, 248, 201, 1, 248, 203, 248, 201, 1, - 174, 248, 201, 1, 170, 248, 201, 1, 165, 248, 201, 1, 173, 248, 201, 1, - 195, 188, 248, 201, 1, 203, 165, 248, 201, 1, 201, 175, 248, 201, 1, 188, - 248, 201, 1, 140, 248, 201, 18, 3, 252, 206, 248, 201, 18, 3, 68, 248, - 201, 18, 3, 223, 199, 248, 201, 18, 3, 66, 248, 201, 18, 3, 196, 30, 248, - 201, 18, 3, 117, 146, 248, 201, 18, 3, 117, 206, 110, 248, 201, 18, 3, - 117, 172, 248, 201, 18, 3, 71, 248, 201, 18, 3, 251, 236, 248, 201, 18, - 3, 74, 248, 201, 18, 3, 250, 163, 248, 201, 3, 247, 119, 248, 201, 3, - 251, 71, 248, 201, 3, 195, 35, 248, 201, 3, 195, 40, 248, 201, 3, 250, - 145, 248, 201, 237, 238, 248, 201, 55, 237, 238, 248, 201, 193, 23, 204, - 10, 248, 201, 231, 204, 233, 2, 248, 201, 231, 204, 233, 1, 248, 201, 17, - 191, 77, 248, 201, 17, 107, 248, 201, 17, 109, 248, 201, 17, 138, 248, - 201, 17, 134, 248, 201, 17, 149, 248, 201, 17, 169, 248, 201, 17, 175, - 248, 201, 17, 171, 248, 201, 17, 178, 248, 201, 31, 107, 248, 201, 31, - 109, 248, 201, 31, 138, 248, 201, 31, 134, 248, 201, 31, 149, 248, 201, - 31, 169, 248, 201, 31, 175, 248, 201, 31, 171, 248, 201, 31, 178, 248, - 201, 31, 199, 95, 248, 201, 31, 197, 32, 248, 201, 31, 198, 249, 248, - 201, 31, 232, 135, 248, 201, 31, 233, 15, 248, 201, 31, 202, 120, 248, - 201, 31, 203, 241, 248, 201, 31, 234, 153, 248, 201, 31, 213, 169, 248, - 201, 228, 139, 196, 91, 77, 217, 57, 229, 236, 77, 217, 57, 87, 203, 157, - 217, 57, 1, 155, 217, 57, 1, 221, 215, 217, 57, 1, 231, 240, 217, 57, 1, - 214, 68, 217, 57, 1, 247, 160, 217, 57, 1, 247, 1, 217, 57, 1, 223, 32, - 217, 57, 1, 212, 101, 217, 57, 1, 190, 190, 217, 57, 1, 199, 49, 217, 57, - 1, 238, 32, 217, 57, 1, 180, 217, 57, 1, 168, 217, 57, 1, 209, 228, 217, - 57, 1, 249, 153, 217, 57, 1, 174, 217, 57, 1, 197, 168, 217, 57, 1, 197, - 157, 217, 57, 1, 235, 35, 217, 57, 1, 193, 190, 217, 57, 1, 191, 71, 217, - 57, 1, 191, 123, 217, 57, 1, 255, 214, 217, 57, 1, 170, 217, 57, 1, 165, - 217, 57, 1, 173, 217, 57, 1, 203, 165, 217, 57, 1, 188, 217, 57, 1, 140, - 217, 57, 1, 65, 217, 57, 200, 239, 1, 155, 217, 57, 200, 239, 1, 221, - 215, 217, 57, 200, 239, 1, 231, 240, 217, 57, 200, 239, 1, 214, 68, 217, - 57, 200, 239, 1, 247, 160, 217, 57, 200, 239, 1, 247, 1, 217, 57, 200, - 239, 1, 223, 32, 217, 57, 200, 239, 1, 212, 101, 217, 57, 200, 239, 1, - 190, 190, 217, 57, 200, 239, 1, 199, 49, 217, 57, 200, 239, 1, 238, 32, - 217, 57, 200, 239, 1, 180, 217, 57, 200, 239, 1, 168, 217, 57, 200, 239, - 1, 209, 228, 217, 57, 200, 239, 1, 249, 153, 217, 57, 200, 239, 1, 174, - 217, 57, 200, 239, 1, 197, 168, 217, 57, 200, 239, 1, 197, 157, 217, 57, - 200, 239, 1, 235, 35, 217, 57, 200, 239, 1, 193, 190, 217, 57, 200, 239, - 1, 191, 71, 217, 57, 200, 239, 1, 191, 123, 217, 57, 200, 239, 1, 170, - 217, 57, 200, 239, 1, 165, 217, 57, 200, 239, 1, 173, 217, 57, 200, 239, - 1, 203, 165, 217, 57, 200, 239, 1, 188, 217, 57, 200, 239, 1, 140, 217, - 57, 200, 239, 1, 65, 217, 57, 18, 3, 252, 206, 217, 57, 18, 3, 68, 217, - 57, 18, 3, 66, 217, 57, 18, 3, 71, 217, 57, 18, 3, 74, 217, 57, 3, 251, - 71, 217, 57, 3, 247, 119, 217, 41, 129, 1, 65, 217, 41, 129, 1, 252, 206, - 217, 41, 129, 1, 68, 217, 41, 129, 1, 223, 199, 217, 41, 129, 1, 66, 217, - 41, 129, 1, 196, 30, 217, 41, 129, 1, 71, 217, 41, 129, 1, 251, 236, 217, - 41, 129, 1, 74, 217, 41, 129, 1, 250, 163, 217, 41, 129, 1, 155, 217, 41, - 129, 1, 221, 215, 217, 41, 129, 1, 231, 240, 217, 41, 129, 1, 231, 91, - 217, 41, 129, 1, 214, 68, 217, 41, 129, 1, 247, 160, 217, 41, 129, 1, - 247, 1, 217, 41, 129, 1, 223, 32, 217, 41, 129, 1, 222, 252, 217, 41, - 129, 1, 212, 101, 217, 41, 129, 1, 197, 132, 217, 41, 129, 1, 197, 120, - 217, 41, 129, 1, 237, 191, 217, 41, 129, 1, 237, 175, 217, 41, 129, 1, - 213, 79, 217, 41, 129, 1, 190, 190, 217, 41, 129, 1, 199, 49, 217, 41, - 129, 1, 238, 32, 217, 41, 129, 1, 237, 68, 217, 41, 129, 1, 180, 217, 41, - 129, 1, 168, 217, 41, 129, 1, 209, 228, 217, 41, 129, 1, 249, 153, 217, - 41, 129, 1, 248, 203, 217, 41, 129, 1, 174, 217, 41, 129, 1, 170, 217, - 41, 129, 1, 165, 217, 41, 129, 1, 173, 217, 41, 129, 1, 195, 188, 217, - 41, 129, 1, 203, 165, 217, 41, 129, 1, 201, 175, 217, 41, 129, 1, 188, - 217, 41, 129, 1, 140, 217, 41, 129, 1, 219, 73, 217, 41, 129, 1, 220, - 246, 217, 41, 129, 1, 222, 202, 217, 41, 129, 1, 198, 26, 217, 41, 129, - 18, 3, 252, 206, 217, 41, 129, 18, 3, 68, 217, 41, 129, 18, 3, 223, 199, - 217, 41, 129, 18, 3, 66, 217, 41, 129, 18, 3, 196, 30, 217, 41, 129, 18, - 3, 117, 146, 217, 41, 129, 18, 3, 71, 217, 41, 129, 18, 3, 251, 236, 217, - 41, 129, 18, 3, 74, 217, 41, 129, 18, 3, 250, 163, 217, 41, 129, 3, 251, - 71, 217, 41, 129, 3, 195, 35, 217, 41, 129, 3, 212, 141, 217, 41, 129, 3, - 247, 121, 217, 41, 129, 3, 230, 72, 217, 41, 129, 195, 40, 217, 41, 129, - 207, 44, 217, 41, 129, 207, 181, 217, 41, 129, 17, 191, 77, 217, 41, 129, - 17, 107, 217, 41, 129, 17, 109, 217, 41, 129, 17, 138, 217, 41, 129, 17, - 134, 217, 41, 129, 17, 149, 217, 41, 129, 17, 169, 217, 41, 129, 17, 175, - 217, 41, 129, 17, 171, 217, 41, 129, 17, 178, 230, 157, 129, 1, 65, 230, - 157, 129, 1, 252, 206, 230, 157, 129, 1, 68, 230, 157, 129, 1, 223, 199, - 230, 157, 129, 1, 66, 230, 157, 129, 1, 196, 30, 230, 157, 129, 1, 234, - 188, 230, 157, 129, 1, 251, 236, 230, 157, 129, 1, 211, 87, 230, 157, - 129, 1, 250, 163, 230, 157, 129, 1, 170, 230, 157, 129, 1, 195, 188, 230, - 157, 129, 1, 249, 153, 230, 157, 129, 1, 248, 203, 230, 157, 129, 1, 174, - 230, 157, 129, 1, 155, 230, 157, 129, 1, 221, 215, 230, 157, 129, 1, 190, - 190, 230, 157, 129, 1, 199, 49, 230, 157, 129, 1, 173, 230, 157, 129, 1, - 231, 240, 230, 157, 129, 1, 231, 91, 230, 157, 129, 1, 238, 32, 230, 157, - 129, 1, 237, 68, 230, 157, 129, 1, 180, 230, 157, 129, 1, 247, 160, 230, - 157, 129, 1, 247, 1, 230, 157, 129, 1, 197, 132, 230, 157, 129, 1, 197, - 120, 230, 157, 129, 1, 219, 73, 230, 157, 129, 1, 223, 32, 230, 157, 129, - 1, 222, 252, 230, 157, 129, 1, 237, 191, 230, 157, 129, 1, 237, 175, 230, - 157, 129, 1, 214, 68, 230, 157, 129, 1, 168, 230, 157, 129, 1, 209, 228, - 230, 157, 129, 1, 140, 230, 157, 129, 1, 165, 230, 157, 129, 1, 188, 230, - 157, 129, 18, 3, 252, 206, 230, 157, 129, 18, 3, 68, 230, 157, 129, 18, - 3, 223, 199, 230, 157, 129, 18, 3, 66, 230, 157, 129, 18, 3, 196, 30, - 230, 157, 129, 18, 3, 234, 188, 230, 157, 129, 18, 3, 251, 236, 230, 157, - 129, 18, 3, 211, 87, 230, 157, 129, 18, 3, 250, 163, 230, 157, 129, 3, - 251, 71, 230, 157, 129, 3, 195, 35, 230, 157, 129, 195, 40, 230, 157, - 129, 211, 113, 230, 157, 129, 17, 191, 77, 230, 157, 129, 17, 107, 230, - 157, 129, 17, 109, 230, 157, 129, 17, 138, 230, 157, 129, 17, 134, 230, - 157, 129, 17, 149, 230, 157, 129, 17, 169, 230, 157, 129, 17, 175, 230, - 157, 129, 17, 171, 230, 157, 129, 17, 178, 217, 102, 1, 155, 217, 102, 1, - 231, 240, 217, 102, 1, 214, 68, 217, 102, 1, 168, 217, 102, 1, 249, 153, - 217, 102, 1, 174, 217, 102, 1, 190, 190, 217, 102, 1, 238, 32, 217, 102, - 1, 180, 217, 102, 1, 247, 160, 217, 102, 1, 223, 32, 217, 102, 1, 212, - 101, 217, 102, 1, 170, 217, 102, 1, 165, 217, 102, 1, 173, 217, 102, 1, - 195, 188, 217, 102, 1, 188, 217, 102, 1, 65, 217, 102, 251, 118, 217, - 102, 18, 3, 68, 217, 102, 18, 3, 66, 217, 102, 18, 3, 71, 217, 102, 18, - 3, 74, 217, 102, 210, 94, 217, 102, 234, 95, 79, 205, 53, 222, 33, 3, - 247, 119, 222, 33, 3, 251, 71, 222, 33, 3, 207, 44, 222, 33, 3, 195, 35, - 222, 33, 1, 65, 222, 33, 1, 252, 206, 222, 33, 1, 68, 222, 33, 1, 223, - 199, 222, 33, 1, 66, 222, 33, 1, 196, 30, 222, 33, 1, 117, 146, 222, 33, - 1, 117, 206, 110, 222, 33, 1, 117, 172, 222, 33, 1, 117, 219, 74, 222, - 33, 1, 71, 222, 33, 1, 251, 236, 222, 33, 1, 74, 222, 33, 1, 155, 222, - 33, 1, 221, 215, 222, 33, 1, 231, 240, 222, 33, 1, 231, 91, 222, 33, 1, - 214, 68, 222, 33, 1, 247, 160, 222, 33, 1, 247, 1, 222, 33, 1, 223, 32, - 222, 33, 1, 222, 252, 222, 33, 1, 212, 101, 222, 33, 1, 197, 132, 222, - 33, 1, 197, 120, 222, 33, 1, 237, 191, 222, 33, 1, 237, 175, 222, 33, 1, - 213, 79, 222, 33, 1, 190, 190, 222, 33, 1, 199, 49, 222, 33, 1, 238, 32, - 222, 33, 1, 237, 68, 222, 33, 1, 180, 222, 33, 1, 168, 222, 33, 1, 209, - 228, 222, 33, 1, 249, 153, 222, 33, 1, 248, 203, 222, 33, 1, 174, 222, - 33, 1, 170, 222, 33, 1, 165, 222, 33, 1, 173, 222, 33, 1, 193, 190, 222, - 33, 1, 203, 165, 222, 33, 1, 201, 175, 222, 33, 1, 188, 222, 33, 1, 140, - 222, 33, 1, 222, 202, 222, 33, 18, 3, 252, 206, 222, 33, 18, 3, 251, 157, - 252, 206, 222, 33, 18, 3, 68, 222, 33, 18, 3, 223, 199, 222, 33, 18, 3, - 66, 222, 33, 18, 3, 196, 30, 222, 33, 18, 3, 117, 146, 222, 33, 18, 3, - 71, 222, 33, 18, 3, 251, 236, 222, 33, 18, 3, 233, 242, 222, 33, 3, 221, - 143, 222, 33, 239, 45, 222, 33, 237, 238, 222, 33, 55, 237, 238, 222, 33, - 208, 152, 205, 54, 217, 51, 222, 33, 208, 152, 251, 157, 205, 54, 217, - 51, 222, 33, 208, 152, 232, 186, 222, 33, 208, 152, 201, 248, 233, 3, - 222, 33, 208, 152, 236, 140, 222, 33, 208, 152, 55, 236, 140, 222, 33, - 208, 152, 197, 225, 236, 140, 222, 33, 208, 152, 243, 10, 222, 33, 208, - 152, 233, 4, 243, 10, 222, 33, 208, 152, 201, 217, 222, 33, 208, 152, - 242, 215, 201, 217, 222, 33, 17, 191, 77, 222, 33, 17, 107, 222, 33, 17, - 109, 222, 33, 17, 138, 222, 33, 17, 134, 222, 33, 17, 149, 222, 33, 17, - 169, 222, 33, 17, 175, 222, 33, 17, 171, 222, 33, 17, 178, 219, 88, 1, - 192, 35, 44, 232, 118, 91, 198, 222, 44, 232, 118, 91, 211, 100, 44, 232, - 118, 91, 234, 156, 44, 232, 118, 91, 202, 118, 44, 232, 118, 91, 232, - 139, 44, 232, 118, 91, 198, 245, 44, 232, 118, 115, 234, 155, 44, 232, - 118, 115, 202, 117, 44, 232, 118, 91, 197, 35, 44, 232, 118, 91, 202, - 127, 44, 232, 118, 91, 202, 126, 44, 232, 118, 91, 199, 86, 44, 232, 118, - 91, 234, 159, 44, 232, 118, 115, 197, 34, 44, 232, 118, 115, 202, 125, - 44, 232, 118, 91, 233, 18, 44, 232, 118, 91, 208, 22, 44, 232, 118, 91, - 230, 69, 44, 232, 118, 91, 230, 68, 44, 232, 118, 115, 208, 20, 44, 232, - 118, 235, 121, 233, 93, 221, 144, 44, 3, 214, 104, 44, 3, 247, 6, 44, 3, - 252, 157, 44, 3, 196, 15, 44, 3, 215, 90, 44, 3, 220, 194, 44, 3, 210, - 85, 44, 3, 215, 135, 44, 3, 222, 124, 44, 3, 210, 164, 44, 3, 209, 39, - 44, 3, 195, 173, 44, 3, 210, 215, 44, 3, 220, 183, 44, 3, 195, 143, 44, - 193, 101, 238, 187, 56, 44, 235, 92, 238, 187, 56, 44, 220, 23, 56, 44, - 205, 159, 210, 167, 56, 44, 198, 21, 238, 230, 56, 44, 198, 21, 31, 56, - 44, 238, 169, 56, 44, 23, 211, 155, 56, 44, 201, 227, 56, 44, 198, 39, - 56, 44, 223, 163, 209, 22, 56, 44, 201, 96, 232, 98, 56, 44, 3, 215, 94, - 44, 3, 195, 181, 44, 208, 152, 234, 95, 79, 199, 53, 10, 3, 65, 10, 3, - 42, 25, 65, 10, 3, 42, 25, 249, 135, 10, 3, 42, 25, 231, 209, 199, 84, - 10, 3, 42, 25, 140, 10, 3, 42, 25, 223, 201, 10, 3, 42, 25, 220, 103, - 230, 155, 10, 3, 42, 25, 215, 101, 10, 3, 42, 25, 205, 185, 10, 3, 254, - 215, 10, 3, 252, 155, 10, 3, 252, 156, 25, 250, 207, 10, 3, 252, 156, 25, - 235, 74, 230, 155, 10, 3, 252, 156, 25, 231, 222, 10, 3, 252, 156, 25, - 231, 209, 199, 84, 10, 3, 252, 156, 25, 140, 10, 3, 252, 156, 25, 223, - 202, 230, 155, 10, 3, 252, 156, 25, 223, 172, 10, 3, 252, 156, 25, 220, - 104, 10, 3, 252, 156, 25, 203, 97, 10, 3, 252, 156, 25, 126, 108, 126, - 108, 66, 10, 3, 252, 156, 230, 155, 10, 3, 252, 72, 10, 3, 252, 73, 25, - 249, 114, 10, 3, 252, 73, 25, 231, 209, 199, 84, 10, 3, 252, 73, 25, 216, - 233, 108, 234, 103, 10, 3, 252, 73, 25, 203, 163, 10, 3, 252, 73, 25, - 199, 209, 10, 3, 252, 42, 10, 3, 251, 216, 10, 3, 251, 217, 25, 234, 28, - 10, 3, 251, 217, 25, 203, 59, 108, 231, 23, 10, 3, 251, 207, 10, 3, 251, - 208, 25, 251, 207, 10, 3, 251, 208, 25, 236, 253, 10, 3, 251, 208, 25, - 231, 23, 10, 3, 251, 208, 25, 140, 10, 3, 251, 208, 25, 222, 111, 10, 3, - 251, 208, 25, 221, 166, 10, 3, 251, 208, 25, 203, 113, 10, 3, 251, 208, - 25, 196, 38, 10, 3, 251, 203, 10, 3, 251, 190, 10, 3, 251, 145, 10, 3, - 251, 146, 25, 203, 113, 10, 3, 251, 132, 10, 3, 251, 133, 139, 251, 132, - 10, 3, 251, 133, 115, 198, 144, 10, 3, 251, 133, 108, 214, 241, 211, 63, - 251, 133, 108, 214, 240, 10, 3, 251, 133, 108, 214, 241, 201, 189, 10, 3, - 251, 91, 10, 3, 251, 60, 10, 3, 251, 26, 10, 3, 251, 27, 25, 220, 197, - 10, 3, 250, 254, 10, 3, 250, 215, 10, 3, 250, 209, 10, 3, 250, 210, 191, - 26, 199, 84, 10, 3, 250, 210, 222, 116, 199, 84, 10, 3, 250, 210, 139, - 250, 210, 197, 83, 139, 197, 83, 197, 83, 139, 197, 83, 210, 137, 10, 3, - 250, 210, 139, 250, 210, 139, 250, 209, 10, 3, 250, 210, 139, 250, 210, - 139, 250, 210, 238, 210, 250, 210, 139, 250, 210, 139, 250, 209, 10, 3, - 250, 207, 10, 3, 250, 203, 10, 3, 249, 153, 10, 3, 249, 135, 10, 3, 249, - 129, 10, 3, 249, 121, 10, 3, 249, 115, 10, 3, 249, 116, 139, 249, 115, - 10, 3, 249, 114, 10, 3, 164, 10, 3, 249, 87, 10, 3, 248, 188, 10, 3, 248, - 189, 25, 65, 10, 3, 248, 189, 25, 231, 200, 10, 3, 248, 189, 25, 223, - 202, 230, 155, 10, 3, 248, 10, 10, 3, 248, 11, 139, 248, 11, 252, 155, - 10, 3, 248, 11, 139, 248, 11, 196, 113, 10, 3, 248, 11, 238, 210, 248, - 10, 10, 3, 247, 242, 10, 3, 247, 243, 139, 247, 242, 10, 3, 247, 230, 10, - 3, 247, 229, 10, 3, 238, 32, 10, 3, 238, 22, 10, 3, 238, 23, 221, 125, - 25, 42, 108, 217, 39, 10, 3, 238, 23, 221, 125, 25, 251, 145, 10, 3, 238, - 23, 221, 125, 25, 249, 114, 10, 3, 238, 23, 221, 125, 25, 248, 188, 10, - 3, 238, 23, 221, 125, 25, 231, 240, 10, 3, 238, 23, 221, 125, 25, 231, - 241, 108, 217, 39, 10, 3, 238, 23, 221, 125, 25, 231, 53, 10, 3, 238, 23, - 221, 125, 25, 231, 32, 10, 3, 238, 23, 221, 125, 25, 230, 168, 10, 3, - 238, 23, 221, 125, 25, 140, 10, 3, 238, 23, 221, 125, 25, 223, 77, 10, 3, - 238, 23, 221, 125, 25, 223, 78, 108, 218, 225, 10, 3, 238, 23, 221, 125, - 25, 222, 96, 10, 3, 238, 23, 221, 125, 25, 173, 10, 3, 238, 23, 221, 125, - 25, 218, 225, 10, 3, 238, 23, 221, 125, 25, 218, 226, 108, 217, 38, 10, - 3, 238, 23, 221, 125, 25, 218, 208, 10, 3, 238, 23, 221, 125, 25, 214, - 121, 10, 3, 238, 23, 221, 125, 25, 210, 138, 108, 210, 137, 10, 3, 238, - 23, 221, 125, 25, 202, 222, 10, 3, 238, 23, 221, 125, 25, 199, 209, 10, - 3, 238, 23, 221, 125, 25, 196, 170, 108, 231, 32, 10, 3, 238, 23, 221, - 125, 25, 196, 38, 10, 3, 237, 250, 10, 3, 237, 225, 10, 3, 237, 224, 10, - 3, 237, 223, 10, 3, 237, 44, 10, 3, 237, 26, 10, 3, 236, 255, 10, 3, 237, - 0, 25, 203, 113, 10, 3, 236, 253, 10, 3, 236, 243, 10, 3, 236, 244, 222, - 55, 126, 230, 156, 236, 222, 10, 3, 236, 222, 10, 3, 235, 89, 10, 3, 235, - 90, 139, 235, 89, 10, 3, 235, 90, 230, 155, 10, 3, 235, 90, 203, 94, 10, - 3, 235, 87, 10, 3, 235, 88, 25, 234, 9, 10, 3, 235, 86, 10, 3, 235, 82, - 10, 3, 235, 81, 10, 3, 235, 80, 10, 3, 235, 75, 10, 3, 235, 73, 10, 3, - 235, 74, 230, 155, 10, 3, 235, 74, 230, 156, 230, 155, 10, 3, 235, 72, - 10, 3, 235, 65, 10, 3, 71, 10, 3, 235, 15, 25, 210, 137, 10, 3, 235, 15, - 139, 235, 15, 212, 131, 139, 212, 130, 10, 3, 234, 218, 10, 3, 234, 219, - 25, 42, 108, 230, 105, 108, 238, 32, 10, 3, 234, 219, 25, 231, 200, 10, - 3, 234, 219, 25, 216, 100, 10, 3, 234, 219, 25, 205, 169, 10, 3, 234, - 219, 25, 203, 113, 10, 3, 234, 219, 25, 66, 10, 3, 234, 190, 10, 3, 234, - 177, 10, 3, 234, 140, 10, 3, 234, 103, 10, 3, 234, 104, 25, 231, 208, 10, - 3, 234, 104, 25, 231, 209, 199, 84, 10, 3, 234, 104, 25, 216, 232, 10, 3, - 234, 104, 238, 210, 234, 103, 10, 3, 234, 104, 211, 63, 234, 103, 10, 3, - 234, 104, 201, 189, 10, 3, 234, 31, 10, 3, 234, 28, 10, 3, 234, 9, 10, 3, - 233, 180, 10, 3, 233, 181, 25, 65, 10, 3, 233, 181, 25, 42, 108, 220, 37, - 10, 3, 233, 181, 25, 42, 108, 220, 38, 25, 220, 37, 10, 3, 233, 181, 25, - 251, 132, 10, 3, 233, 181, 25, 249, 135, 10, 3, 233, 181, 25, 235, 74, - 230, 155, 10, 3, 233, 181, 25, 235, 74, 230, 156, 230, 155, 10, 3, 233, - 181, 25, 140, 10, 3, 233, 181, 25, 230, 105, 230, 155, 10, 3, 233, 181, - 25, 223, 202, 230, 155, 10, 3, 233, 181, 25, 222, 54, 10, 3, 233, 181, - 25, 222, 55, 201, 189, 10, 3, 233, 181, 25, 220, 223, 10, 3, 233, 181, - 25, 173, 10, 3, 233, 181, 25, 220, 38, 25, 220, 37, 10, 3, 233, 181, 25, - 219, 146, 10, 3, 233, 181, 25, 218, 225, 10, 3, 233, 181, 25, 196, 169, - 10, 3, 233, 181, 25, 196, 158, 10, 3, 231, 240, 10, 3, 231, 241, 230, - 155, 10, 3, 231, 238, 10, 3, 231, 239, 25, 42, 108, 238, 33, 108, 140, - 10, 3, 231, 239, 25, 42, 108, 140, 10, 3, 231, 239, 25, 42, 108, 223, - 201, 10, 3, 231, 239, 25, 252, 73, 199, 85, 108, 199, 236, 10, 3, 231, - 239, 25, 251, 132, 10, 3, 231, 239, 25, 250, 209, 10, 3, 231, 239, 25, - 250, 208, 108, 231, 222, 10, 3, 231, 239, 25, 249, 135, 10, 3, 231, 239, - 25, 249, 88, 108, 165, 10, 3, 231, 239, 25, 247, 230, 10, 3, 231, 239, - 25, 247, 231, 108, 165, 10, 3, 231, 239, 25, 238, 32, 10, 3, 231, 239, - 25, 237, 44, 10, 3, 231, 239, 25, 237, 0, 25, 203, 113, 10, 3, 231, 239, - 25, 235, 87, 10, 3, 231, 239, 25, 234, 140, 10, 3, 231, 239, 25, 234, - 141, 108, 173, 10, 3, 231, 239, 25, 234, 103, 10, 3, 231, 239, 25, 234, - 104, 25, 231, 209, 199, 84, 10, 3, 231, 239, 25, 231, 209, 199, 84, 10, - 3, 231, 239, 25, 231, 200, 10, 3, 231, 239, 25, 231, 53, 10, 3, 231, 239, - 25, 231, 51, 10, 3, 231, 239, 25, 231, 52, 108, 65, 10, 3, 231, 239, 25, - 231, 33, 108, 201, 4, 10, 3, 231, 239, 25, 230, 105, 108, 218, 226, 108, - 234, 9, 10, 3, 231, 239, 25, 230, 73, 10, 3, 231, 239, 25, 230, 74, 108, - 173, 10, 3, 231, 239, 25, 229, 159, 108, 219, 146, 10, 3, 231, 239, 25, - 228, 151, 10, 3, 231, 239, 25, 223, 202, 230, 155, 10, 3, 231, 239, 25, - 223, 63, 108, 228, 160, 108, 250, 209, 10, 3, 231, 239, 25, 222, 96, 10, - 3, 231, 239, 25, 222, 54, 10, 3, 231, 239, 25, 221, 152, 10, 3, 231, 239, - 25, 221, 153, 108, 220, 37, 10, 3, 231, 239, 25, 220, 224, 108, 251, 132, - 10, 3, 231, 239, 25, 173, 10, 3, 231, 239, 25, 216, 233, 108, 234, 103, - 10, 3, 231, 239, 25, 216, 100, 10, 3, 231, 239, 25, 212, 130, 10, 3, 231, - 239, 25, 212, 131, 139, 212, 130, 10, 3, 231, 239, 25, 168, 10, 3, 231, - 239, 25, 205, 169, 10, 3, 231, 239, 25, 205, 127, 10, 3, 231, 239, 25, - 203, 113, 10, 3, 231, 239, 25, 203, 114, 108, 197, 64, 10, 3, 231, 239, - 25, 203, 79, 10, 3, 231, 239, 25, 200, 204, 10, 3, 231, 239, 25, 199, - 209, 10, 3, 231, 239, 25, 66, 10, 3, 231, 239, 25, 196, 158, 10, 3, 231, - 239, 25, 196, 159, 108, 235, 89, 10, 3, 231, 239, 139, 231, 238, 10, 3, - 231, 233, 10, 3, 231, 234, 238, 210, 231, 233, 10, 3, 231, 231, 10, 3, - 231, 232, 139, 231, 232, 231, 201, 139, 231, 200, 10, 3, 231, 222, 10, 3, - 231, 223, 231, 232, 139, 231, 232, 231, 201, 139, 231, 200, 10, 3, 231, - 221, 10, 3, 231, 219, 10, 3, 231, 210, 10, 3, 231, 208, 10, 3, 231, 209, - 199, 84, 10, 3, 231, 209, 139, 231, 208, 10, 3, 231, 209, 238, 210, 231, - 208, 10, 3, 231, 200, 10, 3, 231, 199, 10, 3, 231, 193, 10, 3, 231, 134, - 10, 3, 231, 135, 25, 220, 197, 10, 3, 231, 53, 10, 3, 231, 54, 25, 71, - 10, 3, 231, 54, 25, 66, 10, 3, 231, 54, 238, 210, 231, 53, 10, 3, 231, - 51, 10, 3, 231, 52, 139, 231, 51, 10, 3, 231, 52, 238, 210, 231, 51, 10, - 3, 231, 48, 10, 3, 231, 32, 10, 3, 231, 33, 230, 155, 10, 3, 231, 30, 10, - 3, 231, 31, 25, 42, 108, 223, 201, 10, 3, 231, 31, 25, 231, 209, 199, 84, - 10, 3, 231, 31, 25, 223, 201, 10, 3, 231, 31, 25, 218, 226, 108, 223, - 201, 10, 3, 231, 31, 25, 168, 10, 3, 231, 25, 10, 3, 231, 23, 10, 3, 231, - 24, 238, 210, 231, 23, 10, 3, 231, 24, 25, 249, 135, 10, 3, 231, 24, 25, - 199, 209, 10, 3, 231, 24, 199, 84, 10, 3, 230, 179, 10, 3, 230, 180, 238, - 210, 230, 179, 10, 3, 230, 177, 10, 3, 230, 178, 25, 222, 96, 10, 3, 230, - 178, 25, 222, 97, 25, 223, 202, 230, 155, 10, 3, 230, 178, 25, 212, 130, - 10, 3, 230, 178, 25, 205, 170, 108, 197, 82, 10, 3, 230, 178, 230, 155, - 10, 3, 230, 168, 10, 3, 230, 169, 25, 42, 108, 220, 197, 10, 3, 230, 169, - 25, 220, 197, 10, 3, 230, 169, 139, 230, 169, 218, 216, 10, 3, 230, 160, - 10, 3, 230, 158, 10, 3, 230, 159, 25, 203, 113, 10, 3, 230, 149, 10, 3, - 230, 148, 10, 3, 230, 143, 10, 3, 230, 142, 10, 3, 140, 10, 3, 230, 105, - 199, 84, 10, 3, 230, 105, 230, 155, 10, 3, 230, 73, 10, 3, 229, 158, 10, - 3, 229, 159, 25, 250, 209, 10, 3, 229, 159, 25, 250, 207, 10, 3, 229, - 159, 25, 249, 135, 10, 3, 229, 159, 25, 236, 222, 10, 3, 229, 159, 25, - 231, 231, 10, 3, 229, 159, 25, 221, 141, 10, 3, 229, 159, 25, 212, 130, - 10, 3, 229, 159, 25, 203, 113, 10, 3, 229, 159, 25, 66, 10, 3, 228, 159, - 10, 3, 228, 151, 10, 3, 228, 152, 25, 251, 132, 10, 3, 228, 152, 25, 230, - 73, 10, 3, 228, 152, 25, 222, 54, 10, 3, 228, 152, 25, 219, 89, 10, 3, - 228, 152, 25, 196, 158, 10, 3, 228, 146, 10, 3, 68, 10, 3, 228, 74, 65, - 10, 3, 228, 30, 10, 3, 223, 229, 10, 3, 223, 230, 139, 223, 230, 247, - 230, 10, 3, 223, 230, 139, 223, 230, 201, 189, 10, 3, 223, 204, 10, 3, - 223, 201, 10, 3, 223, 202, 237, 26, 10, 3, 223, 202, 207, 1, 10, 3, 223, - 202, 139, 223, 202, 203, 63, 139, 203, 63, 196, 159, 139, 196, 158, 10, - 3, 223, 202, 230, 155, 10, 3, 223, 191, 10, 3, 223, 192, 25, 231, 209, - 199, 84, 10, 3, 223, 190, 10, 3, 223, 180, 10, 3, 223, 181, 25, 199, 209, - 10, 3, 223, 181, 238, 210, 223, 180, 10, 3, 223, 181, 211, 63, 223, 180, - 10, 3, 223, 181, 201, 189, 10, 3, 223, 172, 10, 3, 223, 162, 10, 3, 223, - 77, 10, 3, 223, 62, 10, 3, 155, 10, 3, 222, 142, 25, 65, 10, 3, 222, 142, - 25, 252, 42, 10, 3, 222, 142, 25, 252, 43, 108, 220, 223, 10, 3, 222, - 142, 25, 250, 207, 10, 3, 222, 142, 25, 249, 135, 10, 3, 222, 142, 25, - 249, 114, 10, 3, 222, 142, 25, 164, 10, 3, 222, 142, 25, 248, 188, 10, 3, - 222, 142, 25, 234, 28, 10, 3, 222, 142, 25, 234, 9, 10, 3, 222, 142, 25, - 231, 240, 10, 3, 222, 142, 25, 231, 222, 10, 3, 222, 142, 25, 231, 209, - 199, 84, 10, 3, 222, 142, 25, 231, 200, 10, 3, 222, 142, 25, 231, 201, - 108, 203, 164, 108, 65, 10, 3, 222, 142, 25, 231, 53, 10, 3, 222, 142, - 25, 231, 32, 10, 3, 222, 142, 25, 231, 24, 108, 205, 127, 10, 3, 222, - 142, 25, 231, 24, 238, 210, 231, 23, 10, 3, 222, 142, 25, 230, 179, 10, - 3, 222, 142, 25, 230, 148, 10, 3, 222, 142, 25, 223, 201, 10, 3, 222, - 142, 25, 223, 180, 10, 3, 222, 142, 25, 222, 96, 10, 3, 222, 142, 25, - 221, 166, 10, 3, 222, 142, 25, 221, 152, 10, 3, 222, 142, 25, 219, 146, - 10, 3, 222, 142, 25, 218, 225, 10, 3, 222, 142, 25, 216, 232, 10, 3, 222, - 142, 25, 216, 233, 108, 235, 89, 10, 3, 222, 142, 25, 216, 233, 108, 231, - 53, 10, 3, 222, 142, 25, 216, 233, 108, 199, 145, 10, 3, 222, 142, 25, - 216, 100, 10, 3, 222, 142, 25, 216, 101, 108, 212, 125, 10, 3, 222, 142, - 25, 214, 121, 10, 3, 222, 142, 25, 212, 130, 10, 3, 222, 142, 25, 209, - 185, 10, 3, 222, 142, 25, 206, 68, 10, 3, 222, 142, 25, 188, 10, 3, 222, - 142, 25, 205, 127, 10, 3, 222, 142, 25, 203, 165, 10, 3, 222, 142, 25, - 203, 113, 10, 3, 222, 142, 25, 203, 79, 10, 3, 222, 142, 25, 203, 5, 10, - 3, 222, 142, 25, 202, 201, 10, 3, 222, 142, 25, 200, 213, 10, 3, 222, - 142, 25, 199, 179, 10, 3, 222, 142, 25, 66, 10, 3, 222, 142, 25, 196, - 169, 10, 3, 222, 142, 25, 196, 158, 10, 3, 222, 142, 25, 196, 116, 25, - 168, 10, 3, 222, 142, 25, 196, 38, 10, 3, 222, 142, 25, 191, 30, 10, 3, - 222, 128, 10, 3, 222, 129, 238, 210, 222, 128, 10, 3, 222, 117, 10, 3, - 222, 113, 10, 3, 222, 111, 10, 3, 222, 110, 10, 3, 222, 108, 10, 3, 222, - 109, 139, 222, 108, 10, 3, 222, 96, 10, 3, 222, 97, 25, 223, 202, 230, - 155, 10, 3, 222, 91, 10, 3, 222, 92, 25, 249, 135, 10, 3, 222, 92, 238, - 210, 222, 91, 10, 3, 222, 89, 10, 3, 222, 88, 10, 3, 222, 54, 10, 3, 222, - 55, 220, 105, 25, 126, 139, 220, 105, 25, 66, 10, 3, 222, 55, 139, 222, - 55, 220, 105, 25, 126, 139, 220, 105, 25, 66, 10, 3, 221, 242, 10, 3, - 221, 166, 10, 3, 221, 167, 25, 249, 135, 10, 3, 221, 167, 25, 66, 10, 3, - 221, 167, 25, 196, 158, 10, 3, 221, 152, 10, 3, 221, 141, 10, 3, 221, - 127, 10, 3, 221, 126, 10, 3, 221, 124, 10, 3, 221, 125, 139, 221, 124, - 10, 3, 220, 232, 10, 3, 220, 233, 139, 229, 159, 25, 250, 208, 220, 233, - 139, 229, 159, 25, 250, 207, 10, 3, 220, 223, 10, 3, 220, 221, 10, 3, - 220, 222, 195, 168, 20, 10, 3, 220, 220, 10, 3, 220, 211, 10, 3, 220, - 212, 230, 155, 10, 3, 220, 210, 10, 3, 220, 197, 10, 3, 220, 198, 211, - 63, 220, 197, 10, 3, 220, 190, 10, 3, 220, 167, 10, 3, 173, 10, 3, 220, - 104, 10, 3, 220, 105, 25, 65, 10, 3, 220, 105, 25, 42, 108, 238, 33, 108, - 140, 10, 3, 220, 105, 25, 42, 108, 231, 200, 10, 3, 220, 105, 25, 42, - 108, 220, 37, 10, 3, 220, 105, 25, 251, 207, 10, 3, 220, 105, 25, 251, - 132, 10, 3, 220, 105, 25, 250, 210, 191, 26, 199, 84, 10, 3, 220, 105, - 25, 249, 135, 10, 3, 220, 105, 25, 248, 188, 10, 3, 220, 105, 25, 237, - 225, 10, 3, 220, 105, 25, 234, 103, 10, 3, 220, 105, 25, 231, 240, 10, 3, - 220, 105, 25, 231, 200, 10, 3, 220, 105, 25, 230, 168, 10, 3, 220, 105, - 25, 230, 169, 108, 230, 168, 10, 3, 220, 105, 25, 140, 10, 3, 220, 105, - 25, 230, 73, 10, 3, 220, 105, 25, 229, 159, 25, 212, 130, 10, 3, 220, - 105, 25, 223, 202, 230, 155, 10, 3, 220, 105, 25, 223, 180, 10, 3, 220, - 105, 25, 223, 181, 108, 140, 10, 3, 220, 105, 25, 223, 181, 108, 218, - 225, 10, 3, 220, 105, 25, 221, 166, 10, 3, 220, 105, 25, 221, 141, 10, 3, - 220, 105, 25, 220, 223, 10, 3, 220, 105, 25, 220, 211, 10, 3, 220, 105, - 25, 220, 212, 108, 229, 159, 108, 65, 10, 3, 220, 105, 25, 220, 104, 10, - 3, 220, 105, 25, 219, 89, 10, 3, 220, 105, 25, 218, 225, 10, 3, 220, 105, - 25, 218, 210, 10, 3, 220, 105, 25, 216, 232, 10, 3, 220, 105, 25, 216, - 233, 108, 234, 103, 10, 3, 220, 105, 25, 215, 101, 10, 3, 220, 105, 25, - 214, 121, 10, 3, 220, 105, 25, 203, 114, 108, 200, 204, 10, 3, 220, 105, - 25, 203, 59, 108, 231, 24, 108, 234, 28, 10, 3, 220, 105, 25, 203, 59, - 108, 231, 24, 199, 84, 10, 3, 220, 105, 25, 203, 3, 10, 3, 220, 105, 25, - 203, 4, 108, 203, 3, 10, 3, 220, 105, 25, 200, 204, 10, 3, 220, 105, 25, - 199, 223, 10, 3, 220, 105, 25, 199, 209, 10, 3, 220, 105, 25, 199, 146, - 108, 42, 108, 201, 5, 108, 180, 10, 3, 220, 105, 25, 66, 10, 3, 220, 105, - 25, 126, 108, 65, 10, 3, 220, 105, 25, 126, 108, 126, 108, 66, 10, 3, - 220, 105, 25, 196, 170, 108, 250, 209, 10, 3, 220, 105, 25, 196, 158, 10, - 3, 220, 105, 25, 196, 38, 10, 3, 220, 105, 201, 189, 10, 3, 220, 102, 10, - 3, 220, 103, 25, 203, 113, 10, 3, 220, 103, 25, 203, 114, 108, 200, 204, - 10, 3, 220, 103, 230, 155, 10, 3, 220, 103, 230, 156, 139, 220, 103, 230, - 156, 203, 113, 10, 3, 220, 98, 10, 3, 220, 37, 10, 3, 220, 38, 25, 220, - 37, 10, 3, 220, 35, 10, 3, 220, 36, 25, 220, 197, 10, 3, 220, 36, 25, - 220, 198, 108, 206, 68, 10, 3, 219, 146, 10, 3, 219, 127, 10, 3, 219, - 115, 10, 3, 219, 89, 10, 3, 218, 225, 10, 3, 218, 226, 25, 249, 135, 10, - 3, 218, 223, 10, 3, 218, 224, 25, 251, 207, 10, 3, 218, 224, 25, 249, - 135, 10, 3, 218, 224, 25, 234, 9, 10, 3, 218, 224, 25, 234, 10, 199, 84, - 10, 3, 218, 224, 25, 231, 209, 199, 84, 10, 3, 218, 224, 25, 229, 159, - 25, 249, 135, 10, 3, 218, 224, 25, 223, 180, 10, 3, 218, 224, 25, 222, - 113, 10, 3, 218, 224, 25, 222, 111, 10, 3, 218, 224, 25, 222, 112, 108, - 250, 209, 10, 3, 218, 224, 25, 221, 166, 10, 3, 218, 224, 25, 220, 126, - 108, 250, 209, 10, 3, 218, 224, 25, 220, 104, 10, 3, 218, 224, 25, 216, - 233, 108, 234, 103, 10, 3, 218, 224, 25, 214, 121, 10, 3, 218, 224, 25, - 212, 178, 10, 3, 218, 224, 25, 202, 223, 108, 250, 209, 10, 3, 218, 224, - 25, 202, 192, 108, 248, 10, 10, 3, 218, 224, 25, 197, 82, 10, 3, 218, - 224, 199, 84, 10, 3, 218, 224, 238, 210, 218, 223, 10, 3, 218, 224, 211, - 63, 218, 223, 10, 3, 218, 224, 201, 189, 10, 3, 218, 224, 203, 94, 10, 3, - 218, 222, 10, 3, 218, 216, 10, 3, 218, 217, 139, 218, 216, 10, 3, 218, - 217, 211, 63, 218, 216, 10, 3, 218, 217, 203, 94, 10, 3, 218, 213, 10, 3, - 218, 210, 10, 3, 218, 208, 10, 3, 218, 209, 139, 218, 208, 10, 3, 218, - 209, 139, 218, 209, 231, 201, 139, 231, 200, 10, 3, 174, 10, 3, 217, 160, - 25, 199, 209, 10, 3, 217, 160, 230, 155, 10, 3, 217, 152, 10, 3, 217, - 120, 10, 3, 217, 65, 10, 3, 217, 39, 10, 3, 217, 38, 10, 3, 216, 232, 10, - 3, 216, 173, 10, 3, 216, 100, 10, 3, 216, 44, 10, 3, 215, 155, 10, 3, - 215, 156, 139, 215, 155, 10, 3, 215, 140, 10, 3, 215, 141, 230, 155, 10, - 3, 215, 119, 10, 3, 215, 105, 10, 3, 215, 101, 10, 3, 215, 102, 25, 65, - 10, 3, 215, 102, 25, 220, 197, 10, 3, 215, 102, 25, 191, 123, 10, 3, 215, - 102, 139, 215, 101, 10, 3, 215, 102, 139, 215, 102, 25, 42, 108, 180, 10, - 3, 215, 102, 238, 210, 215, 101, 10, 3, 215, 99, 10, 3, 215, 100, 25, 65, - 10, 3, 215, 100, 25, 42, 108, 237, 44, 10, 3, 215, 100, 25, 237, 44, 10, - 3, 215, 100, 230, 155, 10, 3, 180, 10, 3, 214, 253, 10, 3, 214, 240, 10, - 3, 214, 241, 223, 92, 10, 3, 214, 241, 25, 203, 6, 199, 84, 10, 3, 214, - 241, 211, 63, 214, 240, 10, 3, 214, 239, 10, 3, 214, 231, 212, 116, 10, - 3, 214, 230, 10, 3, 214, 229, 10, 3, 214, 121, 10, 3, 214, 122, 25, 65, - 10, 3, 214, 122, 25, 196, 158, 10, 3, 214, 122, 203, 94, 10, 3, 213, 219, - 10, 3, 213, 220, 25, 71, 10, 3, 213, 210, 10, 3, 213, 180, 10, 3, 213, - 181, 25, 231, 209, 199, 84, 10, 3, 213, 181, 25, 231, 201, 108, 231, 209, - 199, 84, 10, 3, 213, 176, 10, 3, 213, 177, 25, 251, 132, 10, 3, 213, 177, - 25, 250, 209, 10, 3, 213, 177, 25, 250, 210, 108, 250, 209, 10, 3, 213, - 177, 25, 230, 168, 10, 3, 213, 177, 25, 216, 233, 108, 231, 209, 199, 84, - 10, 3, 213, 177, 25, 214, 121, 10, 3, 213, 177, 25, 212, 130, 10, 3, 213, - 177, 25, 203, 113, 10, 3, 213, 177, 25, 203, 114, 108, 42, 251, 132, 10, - 3, 213, 177, 25, 203, 114, 108, 250, 209, 10, 3, 213, 177, 25, 203, 114, - 108, 250, 210, 108, 250, 209, 10, 3, 213, 177, 25, 196, 170, 108, 250, - 209, 10, 3, 213, 177, 25, 196, 38, 10, 3, 213, 163, 10, 3, 212, 178, 10, - 3, 212, 147, 10, 3, 212, 130, 10, 3, 212, 131, 220, 103, 25, 231, 200, - 10, 3, 212, 131, 220, 103, 25, 217, 39, 10, 3, 212, 131, 220, 103, 25, - 205, 169, 10, 3, 212, 131, 220, 103, 25, 205, 170, 139, 212, 131, 220, - 103, 25, 205, 169, 10, 3, 212, 131, 220, 103, 25, 196, 38, 10, 3, 212, - 131, 199, 84, 10, 3, 212, 131, 139, 212, 130, 10, 3, 212, 131, 238, 210, - 212, 130, 10, 3, 212, 131, 238, 210, 212, 131, 220, 103, 139, 220, 102, - 10, 3, 212, 125, 10, 3, 212, 126, 252, 73, 25, 250, 203, 10, 3, 212, 126, - 252, 73, 25, 248, 188, 10, 3, 212, 126, 252, 73, 25, 235, 82, 10, 3, 212, - 126, 252, 73, 25, 230, 168, 10, 3, 212, 126, 252, 73, 25, 223, 202, 230, - 155, 10, 3, 212, 126, 252, 73, 25, 222, 111, 10, 3, 212, 126, 252, 73, - 25, 173, 10, 3, 212, 126, 252, 73, 25, 214, 121, 10, 3, 212, 126, 252, - 73, 25, 202, 189, 10, 3, 212, 126, 252, 73, 25, 196, 169, 10, 3, 212, - 126, 221, 125, 25, 248, 188, 10, 3, 212, 126, 221, 125, 25, 248, 189, 66, - 10, 3, 168, 10, 3, 210, 210, 10, 3, 210, 166, 10, 3, 210, 137, 10, 3, - 209, 243, 10, 3, 209, 185, 10, 3, 209, 186, 25, 65, 10, 3, 209, 186, 25, - 252, 155, 10, 3, 209, 186, 25, 248, 188, 10, 3, 209, 186, 25, 248, 10, - 10, 3, 209, 186, 25, 71, 10, 3, 209, 186, 25, 68, 10, 3, 209, 186, 25, - 228, 30, 10, 3, 209, 186, 25, 66, 10, 3, 209, 186, 25, 196, 169, 10, 3, - 209, 186, 238, 210, 209, 185, 10, 3, 209, 121, 10, 3, 209, 122, 25, 222, - 91, 10, 3, 209, 122, 25, 196, 158, 10, 3, 209, 122, 25, 191, 123, 10, 3, - 209, 122, 211, 63, 209, 121, 10, 3, 165, 10, 3, 207, 176, 10, 3, 207, 1, - 10, 3, 206, 68, 10, 3, 188, 10, 3, 205, 186, 212, 116, 10, 3, 205, 185, - 10, 3, 205, 186, 25, 65, 10, 3, 205, 186, 25, 235, 89, 10, 3, 205, 186, - 25, 235, 87, 10, 3, 205, 186, 25, 140, 10, 3, 205, 186, 25, 222, 96, 10, - 3, 205, 186, 25, 220, 197, 10, 3, 205, 186, 25, 218, 208, 10, 3, 205, - 186, 25, 216, 100, 10, 3, 205, 186, 25, 212, 130, 10, 3, 205, 186, 25, - 205, 169, 10, 3, 205, 186, 25, 203, 79, 10, 3, 205, 186, 25, 199, 236, - 10, 3, 205, 186, 25, 196, 169, 10, 3, 205, 186, 25, 196, 164, 10, 3, 205, - 186, 25, 196, 120, 10, 3, 205, 186, 25, 196, 62, 10, 3, 205, 186, 25, - 196, 38, 10, 3, 205, 186, 139, 205, 185, 10, 3, 205, 186, 230, 155, 10, - 3, 205, 169, 10, 3, 205, 170, 220, 105, 25, 250, 207, 10, 3, 205, 136, - 10, 3, 205, 127, 10, 3, 203, 165, 10, 3, 203, 163, 10, 3, 203, 164, 25, - 65, 10, 3, 203, 164, 25, 249, 135, 10, 3, 203, 164, 25, 231, 23, 10, 3, - 203, 164, 25, 214, 121, 10, 3, 203, 164, 25, 203, 3, 10, 3, 203, 164, 25, - 197, 64, 10, 3, 203, 164, 25, 66, 10, 3, 203, 164, 25, 126, 108, 65, 10, - 3, 203, 161, 10, 3, 203, 159, 10, 3, 203, 131, 10, 3, 203, 113, 10, 3, - 203, 114, 228, 159, 10, 3, 203, 114, 139, 203, 114, 231, 232, 139, 231, - 232, 231, 201, 139, 231, 200, 10, 3, 203, 114, 139, 203, 114, 199, 237, - 139, 199, 237, 231, 201, 139, 231, 200, 10, 3, 203, 106, 10, 3, 203, 101, - 10, 3, 203, 97, 10, 3, 203, 96, 10, 3, 203, 93, 10, 3, 203, 79, 10, 3, - 203, 80, 25, 65, 10, 3, 203, 80, 25, 223, 180, 10, 3, 203, 73, 10, 3, - 203, 74, 25, 65, 10, 3, 203, 74, 25, 249, 115, 10, 3, 203, 74, 25, 247, - 242, 10, 3, 203, 74, 25, 236, 243, 10, 3, 203, 74, 25, 231, 200, 10, 3, - 203, 74, 25, 223, 201, 10, 3, 203, 74, 25, 223, 202, 230, 155, 10, 3, - 203, 74, 25, 220, 190, 10, 3, 203, 74, 25, 218, 210, 10, 3, 203, 74, 25, - 215, 140, 10, 3, 203, 74, 25, 205, 169, 10, 3, 203, 67, 10, 3, 203, 62, - 10, 3, 203, 63, 199, 84, 10, 3, 203, 63, 139, 203, 63, 247, 231, 139, - 247, 230, 10, 3, 203, 58, 10, 3, 203, 5, 10, 3, 203, 6, 139, 223, 93, - 203, 5, 10, 3, 203, 3, 10, 3, 203, 1, 10, 3, 202, 222, 10, 3, 202, 223, - 230, 155, 10, 3, 202, 201, 10, 3, 202, 199, 10, 3, 202, 200, 139, 202, - 200, 203, 3, 10, 3, 202, 191, 10, 3, 202, 189, 10, 3, 201, 4, 10, 3, 201, - 5, 139, 201, 4, 10, 3, 200, 216, 10, 3, 200, 215, 10, 3, 200, 213, 10, 3, - 200, 204, 10, 3, 200, 203, 10, 3, 200, 175, 10, 3, 200, 174, 10, 3, 190, - 190, 10, 3, 199, 252, 250, 193, 10, 3, 199, 252, 25, 229, 158, 10, 3, - 199, 252, 25, 216, 100, 10, 3, 199, 252, 230, 155, 10, 3, 199, 236, 10, - 3, 199, 237, 139, 199, 237, 213, 220, 139, 213, 220, 236, 223, 139, 236, - 222, 10, 3, 199, 237, 201, 189, 10, 3, 199, 223, 10, 3, 199, 224, 25, - 248, 188, 10, 3, 199, 224, 25, 230, 168, 10, 3, 199, 224, 25, 203, 113, - 10, 3, 199, 224, 25, 203, 5, 10, 3, 199, 224, 25, 197, 82, 10, 3, 199, - 224, 25, 196, 158, 10, 3, 199, 209, 10, 3, 199, 179, 10, 3, 199, 145, 10, - 3, 199, 146, 230, 155, 10, 3, 198, 193, 10, 3, 198, 194, 199, 84, 10, 3, - 198, 154, 10, 3, 198, 131, 10, 3, 198, 132, 25, 199, 209, 10, 3, 198, - 132, 139, 198, 131, 10, 3, 198, 132, 139, 198, 132, 231, 232, 139, 231, - 232, 231, 201, 139, 231, 200, 10, 3, 197, 94, 10, 3, 197, 82, 10, 3, 197, - 80, 10, 3, 197, 76, 10, 3, 197, 64, 10, 3, 197, 65, 139, 197, 65, 191, - 124, 139, 191, 123, 10, 3, 66, 10, 3, 126, 230, 168, 10, 3, 126, 126, 66, - 10, 3, 126, 139, 126, 210, 221, 139, 210, 221, 231, 201, 139, 231, 200, - 10, 3, 126, 139, 126, 200, 176, 139, 200, 175, 10, 3, 126, 139, 126, 126, - 207, 18, 139, 126, 207, 17, 10, 3, 196, 169, 10, 3, 196, 164, 10, 3, 196, - 158, 10, 3, 196, 159, 220, 190, 10, 3, 196, 159, 25, 249, 135, 10, 3, - 196, 159, 25, 216, 100, 10, 3, 196, 159, 25, 126, 108, 126, 108, 66, 10, - 3, 196, 159, 25, 126, 108, 126, 108, 126, 230, 155, 10, 3, 196, 159, 230, - 155, 10, 3, 196, 159, 203, 94, 10, 3, 196, 159, 203, 95, 25, 249, 135, - 10, 3, 196, 153, 10, 3, 196, 120, 10, 3, 196, 121, 25, 220, 104, 10, 3, - 196, 121, 25, 216, 233, 108, 238, 32, 10, 3, 196, 121, 25, 203, 163, 10, - 3, 196, 121, 25, 66, 10, 3, 196, 119, 10, 3, 196, 115, 10, 3, 196, 116, - 25, 222, 54, 10, 3, 196, 116, 25, 168, 10, 3, 196, 113, 10, 3, 196, 114, - 230, 155, 10, 3, 196, 62, 10, 3, 196, 63, 238, 210, 196, 62, 10, 3, 196, - 63, 203, 94, 10, 3, 196, 60, 10, 3, 196, 61, 25, 42, 108, 140, 10, 3, - 196, 61, 25, 42, 108, 180, 10, 3, 196, 61, 25, 251, 207, 10, 3, 196, 61, - 25, 140, 10, 3, 196, 61, 25, 212, 130, 10, 3, 196, 61, 25, 196, 169, 10, - 3, 196, 61, 25, 196, 170, 108, 250, 209, 10, 3, 196, 61, 25, 196, 170, - 108, 248, 188, 10, 3, 196, 59, 10, 3, 196, 56, 10, 3, 196, 55, 10, 3, - 196, 51, 10, 3, 196, 52, 25, 65, 10, 3, 196, 52, 25, 250, 203, 10, 3, - 196, 52, 25, 164, 10, 3, 196, 52, 25, 235, 75, 10, 3, 196, 52, 25, 231, - 240, 10, 3, 196, 52, 25, 231, 222, 10, 3, 196, 52, 25, 231, 209, 199, 84, - 10, 3, 196, 52, 25, 231, 200, 10, 3, 196, 52, 25, 230, 179, 10, 3, 196, - 52, 25, 140, 10, 3, 196, 52, 25, 223, 201, 10, 3, 196, 52, 25, 223, 180, - 10, 3, 196, 52, 25, 223, 62, 10, 3, 196, 52, 25, 221, 166, 10, 3, 196, - 52, 25, 218, 208, 10, 3, 196, 52, 25, 216, 44, 10, 3, 196, 52, 25, 168, - 10, 3, 196, 52, 25, 203, 113, 10, 3, 196, 52, 25, 202, 199, 10, 3, 196, - 52, 25, 197, 94, 10, 3, 196, 52, 25, 126, 108, 230, 168, 10, 3, 196, 52, - 25, 196, 158, 10, 3, 196, 52, 25, 196, 49, 10, 3, 196, 49, 10, 3, 196, - 50, 25, 66, 10, 3, 196, 38, 10, 3, 196, 39, 25, 65, 10, 3, 196, 39, 25, - 220, 232, 10, 3, 196, 39, 25, 220, 197, 10, 3, 196, 39, 25, 199, 209, 10, - 3, 196, 34, 10, 3, 196, 37, 10, 3, 196, 35, 10, 3, 196, 31, 10, 3, 196, - 16, 10, 3, 196, 17, 25, 222, 54, 10, 3, 196, 14, 10, 3, 191, 123, 10, 3, - 191, 124, 199, 84, 10, 3, 191, 124, 112, 25, 220, 197, 10, 3, 191, 118, - 10, 3, 191, 107, 10, 3, 191, 86, 10, 3, 191, 30, 10, 3, 191, 31, 139, - 191, 30, 10, 3, 191, 29, 10, 3, 191, 27, 10, 3, 191, 28, 222, 116, 199, - 84, 10, 3, 191, 22, 10, 3, 191, 13, 10, 3, 190, 251, 10, 3, 190, 249, 10, - 3, 190, 250, 25, 65, 10, 3, 190, 248, 10, 3, 190, 247, 10, 3, 222, 79, - 234, 137, 10, 3, 252, 156, 25, 212, 130, 10, 3, 252, 73, 25, 65, 10, 3, - 251, 146, 25, 220, 213, 10, 3, 238, 23, 221, 125, 25, 196, 170, 108, 217, - 39, 10, 3, 238, 21, 10, 3, 236, 223, 108, 203, 5, 10, 3, 235, 88, 25, - 203, 113, 10, 3, 233, 181, 25, 230, 168, 10, 3, 233, 181, 25, 203, 113, - 10, 3, 231, 239, 25, 251, 133, 108, 222, 97, 108, 65, 10, 3, 231, 239, - 25, 250, 207, 10, 3, 231, 164, 10, 3, 231, 42, 10, 3, 228, 131, 10, 3, - 222, 142, 25, 251, 91, 10, 3, 222, 142, 25, 250, 206, 10, 3, 222, 142, - 25, 231, 23, 10, 3, 222, 142, 25, 230, 168, 10, 3, 222, 142, 25, 229, - 159, 25, 250, 207, 10, 3, 222, 142, 25, 218, 208, 10, 3, 222, 142, 25, - 168, 10, 3, 222, 142, 25, 202, 253, 10, 3, 222, 142, 25, 197, 94, 10, 3, - 222, 142, 25, 196, 60, 10, 3, 220, 105, 25, 231, 53, 10, 3, 218, 224, - 203, 95, 25, 249, 135, 10, 3, 218, 224, 25, 234, 10, 108, 220, 37, 10, 3, - 218, 224, 25, 203, 5, 10, 3, 216, 172, 10, 3, 215, 100, 25, 191, 123, 10, - 3, 214, 252, 10, 3, 213, 179, 10, 3, 213, 178, 10, 3, 213, 177, 25, 249, - 115, 10, 3, 213, 177, 25, 231, 53, 10, 3, 212, 148, 206, 122, 213, 170, - 237, 124, 10, 3, 209, 244, 250, 193, 10, 3, 209, 125, 10, 3, 205, 186, - 25, 223, 202, 230, 155, 10, 3, 198, 185, 10, 3, 196, 121, 25, 216, 232, - 10, 3, 126, 66, 10, 167, 3, 105, 250, 209, 10, 167, 3, 115, 250, 209, 10, - 167, 3, 232, 128, 250, 209, 10, 167, 3, 232, 226, 250, 209, 10, 167, 3, - 202, 136, 250, 209, 10, 167, 3, 203, 247, 250, 209, 10, 167, 3, 234, 164, - 250, 209, 10, 167, 3, 213, 175, 250, 209, 10, 167, 3, 115, 236, 222, 10, - 167, 3, 232, 128, 236, 222, 10, 167, 3, 232, 226, 236, 222, 10, 167, 3, - 202, 136, 236, 222, 10, 167, 3, 203, 247, 236, 222, 10, 167, 3, 234, 164, - 236, 222, 10, 167, 3, 213, 175, 236, 222, 10, 167, 3, 232, 128, 66, 10, - 167, 3, 232, 226, 66, 10, 167, 3, 202, 136, 66, 10, 167, 3, 203, 247, 66, - 10, 167, 3, 234, 164, 66, 10, 167, 3, 213, 175, 66, 10, 167, 3, 91, 231, - 136, 10, 167, 3, 105, 231, 136, 10, 167, 3, 115, 231, 136, 10, 167, 3, - 232, 128, 231, 136, 10, 167, 3, 232, 226, 231, 136, 10, 167, 3, 202, 136, - 231, 136, 10, 167, 3, 203, 247, 231, 136, 10, 167, 3, 234, 164, 231, 136, - 10, 167, 3, 213, 175, 231, 136, 10, 167, 3, 91, 231, 133, 10, 167, 3, - 105, 231, 133, 10, 167, 3, 115, 231, 133, 10, 167, 3, 232, 128, 231, 133, - 10, 167, 3, 232, 226, 231, 133, 10, 167, 3, 105, 203, 131, 10, 167, 3, - 115, 203, 131, 10, 167, 3, 115, 203, 132, 195, 168, 20, 10, 167, 3, 232, - 128, 203, 131, 10, 167, 3, 232, 226, 203, 131, 10, 167, 3, 202, 136, 203, - 131, 10, 167, 3, 203, 247, 203, 131, 10, 167, 3, 234, 164, 203, 131, 10, - 167, 3, 213, 175, 203, 131, 10, 167, 3, 91, 203, 124, 10, 167, 3, 105, - 203, 124, 10, 167, 3, 115, 203, 124, 10, 167, 3, 115, 203, 125, 195, 168, - 20, 10, 167, 3, 232, 128, 203, 124, 10, 167, 3, 232, 226, 203, 124, 10, - 167, 3, 203, 132, 25, 231, 223, 108, 236, 222, 10, 167, 3, 203, 132, 25, - 231, 223, 108, 216, 44, 10, 167, 3, 91, 247, 226, 10, 167, 3, 105, 247, - 226, 10, 167, 3, 115, 247, 226, 10, 167, 3, 115, 247, 227, 195, 168, 20, - 10, 167, 3, 232, 128, 247, 226, 10, 167, 3, 232, 226, 247, 226, 10, 167, - 3, 115, 195, 168, 232, 146, 234, 11, 10, 167, 3, 115, 195, 168, 232, 146, - 234, 8, 10, 167, 3, 232, 128, 195, 168, 232, 146, 219, 116, 10, 167, 3, - 232, 128, 195, 168, 232, 146, 219, 114, 10, 167, 3, 232, 128, 195, 168, - 232, 146, 219, 117, 65, 10, 167, 3, 232, 128, 195, 168, 232, 146, 219, - 117, 250, 120, 10, 167, 3, 202, 136, 195, 168, 232, 146, 250, 205, 10, - 167, 3, 203, 247, 195, 168, 232, 146, 223, 171, 10, 167, 3, 203, 247, - 195, 168, 232, 146, 223, 173, 65, 10, 167, 3, 203, 247, 195, 168, 232, - 146, 223, 173, 250, 120, 10, 167, 3, 234, 164, 195, 168, 232, 146, 196, - 33, 10, 167, 3, 234, 164, 195, 168, 232, 146, 196, 32, 10, 167, 3, 213, - 175, 195, 168, 232, 146, 223, 188, 10, 167, 3, 213, 175, 195, 168, 232, - 146, 223, 187, 10, 167, 3, 213, 175, 195, 168, 232, 146, 223, 186, 10, - 167, 3, 213, 175, 195, 168, 232, 146, 223, 189, 65, 10, 167, 3, 105, 250, - 210, 199, 84, 10, 167, 3, 115, 250, 210, 199, 84, 10, 167, 3, 232, 128, - 250, 210, 199, 84, 10, 167, 3, 232, 226, 250, 210, 199, 84, 10, 167, 3, - 202, 136, 250, 210, 199, 84, 10, 167, 3, 91, 249, 99, 10, 167, 3, 105, - 249, 99, 10, 167, 3, 115, 249, 99, 10, 167, 3, 232, 128, 249, 99, 10, - 167, 3, 232, 128, 249, 100, 195, 168, 20, 10, 167, 3, 232, 226, 249, 99, - 10, 167, 3, 232, 226, 249, 100, 195, 168, 20, 10, 167, 3, 213, 188, 10, - 167, 3, 213, 189, 10, 167, 3, 91, 234, 7, 10, 167, 3, 105, 234, 7, 10, - 167, 3, 91, 199, 1, 236, 222, 10, 167, 3, 105, 198, 254, 236, 222, 10, - 167, 3, 232, 226, 202, 123, 236, 222, 10, 167, 3, 91, 199, 1, 195, 168, - 232, 146, 65, 10, 167, 3, 105, 198, 254, 195, 168, 232, 146, 65, 10, 167, - 3, 91, 234, 160, 250, 209, 10, 167, 3, 91, 208, 23, 250, 209, 10, 167, 3, - 39, 250, 196, 91, 202, 124, 10, 167, 3, 39, 250, 196, 91, 208, 22, 10, - 167, 3, 91, 208, 23, 230, 149, 10, 167, 3, 91, 132, 230, 149, 10, 167, 3, - 234, 138, 91, 199, 0, 10, 167, 3, 234, 138, 105, 198, 253, 10, 167, 3, - 234, 138, 232, 135, 10, 167, 3, 234, 138, 233, 15, 10, 167, 3, 232, 128, - 126, 195, 168, 20, 10, 167, 3, 232, 226, 126, 195, 168, 20, 10, 167, 3, - 202, 136, 126, 195, 168, 20, 10, 167, 3, 203, 247, 126, 195, 168, 20, 10, - 167, 3, 234, 164, 126, 195, 168, 20, 10, 167, 3, 213, 175, 126, 195, 168, - 20, 10, 208, 152, 3, 39, 250, 196, 193, 23, 236, 205, 10, 208, 152, 3, - 81, 242, 83, 10, 208, 152, 3, 237, 39, 242, 83, 10, 208, 152, 3, 237, 39, - 197, 237, 10, 208, 152, 3, 237, 39, 208, 29, 10, 3, 252, 156, 25, 212, - 131, 199, 84, 10, 3, 252, 156, 25, 203, 3, 10, 3, 252, 43, 25, 234, 9, - 10, 3, 249, 136, 25, 236, 223, 199, 84, 10, 3, 249, 122, 25, 252, 72, 10, - 3, 249, 122, 25, 213, 219, 10, 3, 249, 122, 25, 191, 123, 10, 3, 248, 11, - 139, 248, 11, 25, 214, 253, 10, 3, 238, 33, 25, 199, 209, 10, 3, 238, 23, - 25, 220, 197, 10, 3, 237, 0, 25, 223, 201, 10, 3, 237, 0, 25, 126, 126, - 66, 10, 3, 236, 254, 25, 196, 158, 10, 3, 235, 83, 25, 251, 91, 10, 3, - 235, 83, 25, 250, 209, 10, 3, 235, 83, 25, 250, 210, 250, 183, 219, 224, - 10, 3, 235, 83, 25, 236, 243, 10, 3, 235, 83, 25, 235, 75, 10, 3, 235, - 83, 25, 234, 28, 10, 3, 235, 83, 25, 231, 240, 10, 3, 235, 83, 25, 231, - 53, 10, 3, 235, 83, 25, 231, 33, 230, 155, 10, 3, 235, 83, 25, 231, 23, - 10, 3, 235, 83, 25, 140, 10, 3, 235, 83, 25, 229, 158, 10, 3, 235, 83, - 25, 223, 202, 230, 155, 10, 3, 235, 83, 25, 222, 54, 10, 3, 235, 83, 25, - 220, 197, 10, 3, 235, 83, 25, 220, 190, 10, 3, 235, 83, 25, 220, 191, - 108, 222, 54, 10, 3, 235, 83, 25, 220, 92, 10, 3, 235, 83, 25, 220, 35, - 10, 3, 235, 83, 25, 220, 36, 25, 220, 197, 10, 3, 235, 83, 25, 218, 214, - 108, 231, 23, 10, 3, 235, 83, 25, 217, 39, 10, 3, 235, 83, 25, 216, 173, - 10, 3, 235, 83, 25, 216, 100, 10, 3, 235, 83, 25, 213, 219, 10, 3, 235, - 83, 25, 209, 185, 10, 3, 235, 83, 25, 203, 113, 10, 3, 235, 83, 25, 202, - 223, 230, 155, 10, 3, 234, 219, 25, 220, 197, 10, 3, 234, 219, 25, 210, - 137, 10, 3, 234, 29, 192, 235, 10, 3, 234, 10, 238, 210, 234, 9, 10, 3, - 233, 181, 203, 95, 25, 250, 209, 10, 3, 233, 181, 203, 95, 25, 229, 158, - 10, 3, 233, 181, 203, 95, 25, 223, 202, 230, 155, 10, 3, 233, 181, 203, - 95, 25, 173, 10, 3, 233, 181, 203, 95, 25, 220, 37, 10, 3, 233, 181, 203, - 95, 25, 216, 232, 10, 3, 233, 181, 203, 95, 25, 216, 173, 10, 3, 233, - 181, 203, 95, 25, 201, 4, 10, 3, 233, 181, 25, 201, 4, 10, 3, 231, 239, - 25, 249, 121, 10, 3, 231, 239, 25, 237, 0, 230, 155, 10, 3, 231, 239, 25, - 235, 83, 25, 223, 202, 230, 155, 10, 3, 231, 239, 25, 235, 83, 25, 222, - 54, 10, 3, 231, 239, 25, 234, 31, 10, 3, 231, 239, 25, 231, 240, 10, 3, - 231, 239, 25, 231, 201, 108, 237, 44, 10, 3, 231, 239, 25, 231, 201, 108, - 214, 121, 10, 3, 231, 239, 25, 230, 105, 108, 65, 10, 3, 231, 239, 25, - 220, 191, 108, 222, 54, 10, 3, 231, 239, 25, 220, 35, 10, 3, 231, 239, - 25, 220, 36, 25, 220, 197, 10, 3, 231, 239, 25, 218, 213, 10, 3, 231, - 239, 25, 215, 101, 10, 3, 231, 239, 25, 214, 121, 10, 3, 231, 239, 25, - 214, 122, 108, 234, 218, 10, 3, 231, 239, 25, 214, 122, 108, 231, 53, 10, - 3, 231, 239, 25, 203, 73, 10, 3, 231, 239, 25, 191, 13, 10, 3, 231, 234, - 206, 122, 213, 170, 237, 124, 10, 3, 231, 135, 25, 66, 10, 3, 231, 24, - 25, 231, 24, 238, 210, 231, 23, 10, 3, 230, 178, 25, 223, 202, 230, 155, - 10, 3, 230, 169, 108, 231, 24, 25, 199, 209, 10, 3, 230, 105, 199, 85, - 230, 155, 10, 3, 229, 159, 25, 250, 210, 139, 229, 159, 25, 250, 209, 10, - 3, 222, 142, 25, 248, 10, 10, 3, 222, 142, 25, 155, 10, 3, 222, 142, 25, - 126, 126, 66, 10, 3, 222, 142, 25, 196, 62, 10, 3, 220, 105, 25, 190, - 252, 139, 190, 251, 10, 3, 220, 93, 10, 3, 220, 91, 10, 3, 220, 90, 10, - 3, 220, 89, 10, 3, 220, 88, 10, 3, 220, 87, 10, 3, 220, 86, 10, 3, 220, - 85, 139, 220, 85, 230, 155, 10, 3, 220, 84, 10, 3, 220, 83, 139, 220, 82, - 10, 3, 220, 81, 10, 3, 220, 80, 10, 3, 220, 79, 10, 3, 220, 78, 10, 3, - 220, 77, 10, 3, 220, 76, 10, 3, 220, 75, 10, 3, 220, 74, 10, 3, 220, 73, - 10, 3, 220, 72, 10, 3, 220, 71, 10, 3, 220, 70, 10, 3, 220, 69, 10, 3, - 220, 68, 10, 3, 220, 67, 10, 3, 220, 66, 10, 3, 220, 65, 10, 3, 220, 64, - 10, 3, 220, 62, 10, 3, 220, 63, 25, 230, 179, 10, 3, 220, 63, 25, 223, - 201, 10, 3, 220, 63, 25, 210, 138, 108, 218, 222, 10, 3, 220, 63, 25, - 210, 138, 108, 210, 138, 108, 218, 222, 10, 3, 220, 63, 25, 196, 170, - 108, 249, 153, 10, 3, 220, 61, 10, 3, 220, 60, 10, 3, 220, 59, 10, 3, - 220, 58, 10, 3, 220, 57, 10, 3, 220, 56, 10, 3, 220, 55, 10, 3, 220, 54, - 10, 3, 220, 53, 10, 3, 220, 52, 10, 3, 220, 50, 10, 3, 220, 51, 25, 250, - 209, 10, 3, 220, 51, 25, 249, 135, 10, 3, 220, 51, 25, 235, 74, 230, 156, - 230, 155, 10, 3, 220, 51, 25, 220, 223, 10, 3, 220, 51, 25, 173, 10, 3, - 220, 51, 25, 199, 179, 10, 3, 220, 51, 25, 199, 145, 10, 3, 220, 51, 25, - 196, 169, 10, 3, 220, 51, 25, 196, 158, 10, 3, 220, 51, 25, 196, 49, 10, - 3, 220, 49, 10, 3, 220, 47, 10, 3, 220, 48, 25, 235, 87, 10, 3, 220, 48, - 25, 231, 240, 10, 3, 220, 48, 25, 223, 201, 10, 3, 220, 48, 25, 223, 202, - 230, 155, 10, 3, 220, 48, 25, 213, 219, 10, 3, 220, 48, 25, 210, 138, - 108, 210, 138, 108, 218, 222, 10, 3, 220, 48, 25, 203, 98, 108, 221, 166, - 10, 3, 220, 48, 25, 196, 158, 10, 3, 220, 48, 25, 196, 49, 10, 3, 220, - 45, 10, 3, 220, 44, 10, 3, 218, 224, 230, 156, 25, 250, 209, 10, 3, 218, - 224, 25, 236, 222, 10, 3, 218, 224, 25, 230, 73, 10, 3, 218, 224, 25, - 210, 137, 10, 3, 218, 224, 25, 210, 138, 108, 210, 138, 108, 218, 222, - 10, 3, 218, 224, 25, 199, 209, 10, 3, 216, 101, 108, 191, 122, 10, 3, - 215, 102, 139, 215, 102, 25, 231, 240, 10, 3, 215, 102, 139, 215, 102, - 25, 222, 96, 10, 3, 213, 177, 25, 237, 0, 230, 155, 10, 3, 213, 177, 25, - 231, 23, 10, 3, 213, 177, 25, 230, 160, 10, 3, 213, 177, 25, 229, 158, - 10, 3, 213, 177, 25, 221, 242, 10, 3, 213, 177, 25, 220, 88, 10, 3, 213, - 177, 25, 217, 39, 10, 3, 213, 177, 25, 210, 138, 108, 210, 137, 10, 3, - 213, 177, 25, 66, 10, 3, 213, 177, 25, 126, 108, 66, 10, 3, 213, 177, 25, - 196, 49, 10, 3, 205, 186, 230, 156, 25, 140, 10, 3, 205, 186, 25, 234, - 103, 10, 3, 205, 186, 25, 203, 114, 250, 183, 219, 224, 10, 3, 205, 186, - 25, 199, 209, 10, 3, 203, 162, 199, 84, 10, 3, 203, 114, 139, 203, 113, - 10, 3, 203, 114, 108, 228, 151, 10, 3, 203, 114, 108, 214, 229, 10, 3, - 203, 114, 108, 205, 127, 10, 3, 203, 4, 108, 235, 83, 25, 213, 219, 10, - 3, 203, 4, 108, 234, 219, 25, 251, 132, 10, 3, 202, 223, 25, 199, 209, - 10, 3, 199, 210, 108, 205, 185, 10, 3, 197, 77, 25, 231, 209, 199, 84, - 10, 3, 197, 77, 25, 115, 236, 222, 10, 3, 196, 61, 223, 92, 10, 3, 196, - 61, 25, 196, 158, 10, 3, 196, 52, 25, 237, 224, 10, 3, 196, 52, 25, 220, - 46, 10, 3, 196, 52, 25, 218, 222, 10, 3, 191, 122, 10, 3, 190, 252, 139, - 190, 252, 108, 205, 127, 10, 3, 190, 250, 25, 115, 236, 223, 199, 84, - 238, 134, 3, 242, 198, 238, 134, 3, 242, 197, 238, 134, 3, 242, 196, 238, - 134, 3, 242, 195, 238, 134, 3, 242, 194, 238, 134, 3, 242, 193, 238, 134, - 3, 242, 192, 238, 134, 3, 242, 191, 238, 134, 3, 242, 190, 238, 134, 3, - 242, 189, 238, 134, 3, 242, 188, 238, 134, 3, 242, 187, 238, 134, 3, 242, - 186, 238, 134, 3, 242, 185, 238, 134, 3, 242, 184, 238, 134, 3, 242, 183, - 238, 134, 3, 242, 182, 238, 134, 3, 242, 181, 238, 134, 3, 242, 180, 238, - 134, 3, 242, 179, 238, 134, 3, 242, 178, 238, 134, 3, 242, 177, 238, 134, - 3, 242, 176, 238, 134, 3, 242, 175, 238, 134, 3, 242, 174, 238, 134, 3, - 242, 173, 238, 134, 3, 242, 172, 238, 134, 3, 242, 171, 238, 134, 3, 242, - 170, 238, 134, 3, 242, 169, 238, 134, 3, 242, 168, 238, 134, 3, 242, 167, - 238, 134, 3, 242, 166, 238, 134, 3, 242, 165, 238, 134, 3, 242, 164, 238, - 134, 3, 242, 163, 238, 134, 3, 242, 162, 238, 134, 3, 242, 161, 238, 134, - 3, 242, 160, 238, 134, 3, 242, 159, 238, 134, 3, 242, 158, 238, 134, 3, - 242, 157, 238, 134, 3, 242, 156, 238, 134, 3, 242, 155, 238, 134, 3, 242, - 154, 238, 134, 3, 242, 153, 238, 134, 3, 242, 152, 238, 134, 3, 242, 151, - 238, 134, 3, 242, 150, 238, 134, 3, 242, 149, 238, 134, 3, 242, 148, 238, - 134, 3, 242, 147, 238, 134, 3, 242, 146, 238, 134, 3, 242, 145, 238, 134, - 3, 242, 144, 238, 134, 3, 242, 143, 238, 134, 3, 242, 142, 238, 134, 3, - 242, 141, 238, 134, 3, 242, 140, 238, 134, 3, 242, 139, 238, 134, 3, 242, - 138, 238, 134, 3, 242, 137, 238, 134, 3, 242, 136, 238, 134, 3, 242, 135, - 238, 134, 3, 242, 134, 238, 134, 3, 242, 133, 238, 134, 3, 242, 132, 238, - 134, 3, 242, 131, 238, 134, 3, 242, 130, 238, 134, 3, 242, 129, 238, 134, - 3, 242, 128, 238, 134, 3, 242, 127, 238, 134, 3, 242, 126, 238, 134, 3, - 242, 125, 238, 134, 3, 242, 124, 238, 134, 3, 242, 123, 238, 134, 3, 242, - 122, 238, 134, 3, 242, 121, 238, 134, 3, 242, 120, 238, 134, 3, 242, 119, - 238, 134, 3, 242, 118, 238, 134, 3, 242, 117, 238, 134, 3, 242, 116, 238, - 134, 3, 242, 115, 238, 134, 3, 242, 114, 238, 134, 3, 242, 113, 238, 134, - 3, 242, 112, 238, 134, 3, 242, 111, 238, 134, 3, 242, 110, 238, 134, 3, - 242, 109, 238, 134, 3, 242, 108, 238, 134, 3, 242, 107, 238, 134, 3, 242, - 106, 238, 134, 3, 242, 105, 238, 134, 3, 242, 104, 238, 134, 3, 242, 103, - 238, 134, 3, 242, 102, 238, 134, 3, 242, 101, 238, 134, 3, 242, 100, 14, - 7, 255, 199, 14, 7, 255, 198, 14, 7, 255, 197, 14, 7, 255, 196, 14, 7, - 255, 195, 14, 7, 255, 194, 14, 7, 255, 193, 14, 7, 255, 192, 14, 7, 255, - 191, 14, 7, 255, 190, 14, 7, 255, 189, 14, 7, 255, 188, 14, 7, 255, 187, - 14, 7, 255, 185, 14, 7, 255, 184, 14, 7, 255, 183, 14, 7, 255, 182, 14, - 7, 255, 181, 14, 7, 255, 180, 14, 7, 255, 179, 14, 7, 255, 178, 14, 7, - 255, 177, 14, 7, 255, 176, 14, 7, 255, 175, 14, 7, 255, 174, 14, 7, 255, - 173, 14, 7, 255, 172, 14, 7, 255, 171, 14, 7, 255, 170, 14, 7, 255, 169, - 14, 7, 255, 168, 14, 7, 255, 166, 14, 7, 255, 165, 14, 7, 255, 163, 14, - 7, 255, 162, 14, 7, 255, 161, 14, 7, 255, 160, 14, 7, 255, 159, 14, 7, - 255, 158, 14, 7, 255, 157, 14, 7, 255, 156, 14, 7, 255, 155, 14, 7, 255, - 154, 14, 7, 255, 153, 14, 7, 255, 152, 14, 7, 255, 150, 14, 7, 255, 149, - 14, 7, 255, 148, 14, 7, 255, 146, 14, 7, 255, 145, 14, 7, 255, 144, 14, - 7, 255, 143, 14, 7, 255, 142, 14, 7, 255, 141, 14, 7, 255, 140, 14, 7, - 255, 139, 14, 7, 255, 136, 14, 7, 255, 135, 14, 7, 255, 134, 14, 7, 255, - 133, 14, 7, 255, 132, 14, 7, 255, 131, 14, 7, 255, 130, 14, 7, 255, 129, - 14, 7, 255, 128, 14, 7, 255, 127, 14, 7, 255, 126, 14, 7, 255, 125, 14, - 7, 255, 124, 14, 7, 255, 123, 14, 7, 255, 122, 14, 7, 255, 121, 14, 7, - 255, 120, 14, 7, 255, 119, 14, 7, 255, 118, 14, 7, 255, 117, 14, 7, 255, - 113, 14, 7, 255, 112, 14, 7, 255, 111, 14, 7, 255, 110, 14, 7, 250, 118, - 14, 7, 250, 116, 14, 7, 250, 114, 14, 7, 250, 112, 14, 7, 250, 110, 14, - 7, 250, 109, 14, 7, 250, 107, 14, 7, 250, 105, 14, 7, 250, 103, 14, 7, - 250, 101, 14, 7, 247, 189, 14, 7, 247, 188, 14, 7, 247, 187, 14, 7, 247, - 186, 14, 7, 247, 185, 14, 7, 247, 184, 14, 7, 247, 183, 14, 7, 247, 182, - 14, 7, 247, 181, 14, 7, 247, 180, 14, 7, 247, 179, 14, 7, 247, 178, 14, - 7, 247, 177, 14, 7, 247, 176, 14, 7, 247, 175, 14, 7, 247, 174, 14, 7, - 247, 173, 14, 7, 247, 172, 14, 7, 247, 171, 14, 7, 247, 170, 14, 7, 247, - 169, 14, 7, 247, 168, 14, 7, 247, 167, 14, 7, 247, 166, 14, 7, 247, 165, - 14, 7, 247, 164, 14, 7, 247, 163, 14, 7, 247, 162, 14, 7, 238, 126, 14, - 7, 238, 125, 14, 7, 238, 124, 14, 7, 238, 123, 14, 7, 238, 122, 14, 7, - 238, 121, 14, 7, 238, 120, 14, 7, 238, 119, 14, 7, 238, 118, 14, 7, 238, - 117, 14, 7, 238, 116, 14, 7, 238, 115, 14, 7, 238, 114, 14, 7, 238, 113, - 14, 7, 238, 112, 14, 7, 238, 111, 14, 7, 238, 110, 14, 7, 238, 109, 14, - 7, 238, 108, 14, 7, 238, 107, 14, 7, 238, 106, 14, 7, 238, 105, 14, 7, - 238, 104, 14, 7, 238, 103, 14, 7, 238, 102, 14, 7, 238, 101, 14, 7, 238, - 100, 14, 7, 238, 99, 14, 7, 238, 98, 14, 7, 238, 97, 14, 7, 238, 96, 14, - 7, 238, 95, 14, 7, 238, 94, 14, 7, 238, 93, 14, 7, 238, 92, 14, 7, 238, - 91, 14, 7, 238, 90, 14, 7, 238, 89, 14, 7, 238, 88, 14, 7, 238, 87, 14, - 7, 238, 86, 14, 7, 238, 85, 14, 7, 238, 84, 14, 7, 238, 83, 14, 7, 238, - 82, 14, 7, 238, 81, 14, 7, 238, 80, 14, 7, 238, 79, 14, 7, 238, 78, 14, - 7, 238, 77, 14, 7, 238, 76, 14, 7, 238, 75, 14, 7, 238, 74, 14, 7, 238, - 73, 14, 7, 238, 72, 14, 7, 238, 71, 14, 7, 238, 70, 14, 7, 238, 69, 14, - 7, 238, 68, 14, 7, 238, 67, 14, 7, 238, 66, 14, 7, 238, 65, 14, 7, 238, - 64, 14, 7, 238, 63, 14, 7, 238, 62, 14, 7, 238, 61, 14, 7, 238, 60, 14, - 7, 238, 59, 14, 7, 238, 58, 14, 7, 238, 57, 14, 7, 238, 56, 14, 7, 238, - 55, 14, 7, 238, 54, 14, 7, 238, 53, 14, 7, 238, 52, 14, 7, 238, 51, 14, - 7, 238, 50, 14, 7, 238, 49, 14, 7, 238, 48, 14, 7, 238, 47, 14, 7, 238, - 46, 14, 7, 238, 45, 14, 7, 238, 44, 14, 7, 238, 43, 14, 7, 238, 42, 14, - 7, 238, 41, 14, 7, 238, 40, 14, 7, 238, 39, 14, 7, 238, 38, 14, 7, 238, - 37, 14, 7, 238, 36, 14, 7, 238, 35, 14, 7, 235, 7, 14, 7, 235, 6, 14, 7, - 235, 5, 14, 7, 235, 4, 14, 7, 235, 3, 14, 7, 235, 2, 14, 7, 235, 1, 14, - 7, 235, 0, 14, 7, 234, 255, 14, 7, 234, 254, 14, 7, 234, 253, 14, 7, 234, - 252, 14, 7, 234, 251, 14, 7, 234, 250, 14, 7, 234, 249, 14, 7, 234, 248, - 14, 7, 234, 247, 14, 7, 234, 246, 14, 7, 234, 245, 14, 7, 234, 244, 14, - 7, 234, 243, 14, 7, 234, 242, 14, 7, 234, 241, 14, 7, 234, 240, 14, 7, - 234, 239, 14, 7, 234, 238, 14, 7, 234, 237, 14, 7, 234, 236, 14, 7, 234, - 235, 14, 7, 234, 234, 14, 7, 234, 233, 14, 7, 234, 232, 14, 7, 234, 231, - 14, 7, 234, 230, 14, 7, 234, 229, 14, 7, 234, 228, 14, 7, 234, 227, 14, - 7, 234, 226, 14, 7, 234, 225, 14, 7, 234, 224, 14, 7, 234, 223, 14, 7, - 234, 222, 14, 7, 234, 221, 14, 7, 234, 220, 14, 7, 233, 174, 14, 7, 233, - 173, 14, 7, 233, 172, 14, 7, 233, 171, 14, 7, 233, 170, 14, 7, 233, 169, - 14, 7, 233, 168, 14, 7, 233, 167, 14, 7, 233, 166, 14, 7, 233, 165, 14, - 7, 233, 164, 14, 7, 233, 163, 14, 7, 233, 162, 14, 7, 233, 161, 14, 7, - 233, 160, 14, 7, 233, 159, 14, 7, 233, 158, 14, 7, 233, 157, 14, 7, 233, - 156, 14, 7, 233, 155, 14, 7, 233, 154, 14, 7, 233, 153, 14, 7, 233, 152, - 14, 7, 233, 151, 14, 7, 233, 150, 14, 7, 233, 149, 14, 7, 233, 148, 14, - 7, 233, 147, 14, 7, 233, 146, 14, 7, 233, 145, 14, 7, 233, 144, 14, 7, - 233, 143, 14, 7, 233, 142, 14, 7, 233, 141, 14, 7, 233, 140, 14, 7, 233, - 139, 14, 7, 233, 138, 14, 7, 233, 137, 14, 7, 233, 136, 14, 7, 233, 135, - 14, 7, 233, 134, 14, 7, 233, 133, 14, 7, 233, 132, 14, 7, 233, 131, 14, - 7, 233, 130, 14, 7, 233, 129, 14, 7, 233, 128, 14, 7, 233, 127, 14, 7, - 233, 126, 14, 7, 233, 125, 14, 7, 233, 124, 14, 7, 233, 123, 14, 7, 233, - 122, 14, 7, 233, 121, 14, 7, 233, 120, 14, 7, 233, 119, 14, 7, 233, 118, - 14, 7, 233, 117, 14, 7, 233, 116, 14, 7, 233, 115, 14, 7, 233, 114, 14, - 7, 233, 113, 14, 7, 233, 112, 14, 7, 233, 111, 14, 7, 233, 110, 14, 7, - 232, 50, 14, 7, 232, 49, 14, 7, 232, 48, 14, 7, 232, 47, 14, 7, 232, 46, - 14, 7, 232, 45, 14, 7, 232, 44, 14, 7, 232, 43, 14, 7, 232, 42, 14, 7, - 232, 41, 14, 7, 232, 40, 14, 7, 232, 39, 14, 7, 232, 38, 14, 7, 232, 37, - 14, 7, 232, 36, 14, 7, 232, 35, 14, 7, 232, 34, 14, 7, 232, 33, 14, 7, - 232, 32, 14, 7, 232, 31, 14, 7, 232, 30, 14, 7, 232, 29, 14, 7, 232, 28, - 14, 7, 232, 27, 14, 7, 232, 26, 14, 7, 232, 25, 14, 7, 232, 24, 14, 7, - 232, 23, 14, 7, 232, 22, 14, 7, 232, 21, 14, 7, 232, 20, 14, 7, 232, 19, - 14, 7, 232, 18, 14, 7, 232, 17, 14, 7, 232, 16, 14, 7, 232, 15, 14, 7, - 232, 14, 14, 7, 232, 13, 14, 7, 232, 12, 14, 7, 232, 11, 14, 7, 232, 10, - 14, 7, 232, 9, 14, 7, 232, 8, 14, 7, 232, 7, 14, 7, 232, 6, 14, 7, 232, - 5, 14, 7, 232, 4, 14, 7, 232, 3, 14, 7, 232, 2, 14, 7, 232, 1, 14, 7, - 232, 0, 14, 7, 231, 255, 14, 7, 231, 254, 14, 7, 231, 253, 14, 7, 231, - 252, 14, 7, 231, 251, 14, 7, 231, 250, 14, 7, 231, 249, 14, 7, 231, 248, - 14, 7, 231, 247, 14, 7, 231, 246, 14, 7, 231, 245, 14, 7, 231, 244, 14, - 7, 231, 243, 14, 7, 230, 114, 14, 7, 230, 113, 14, 7, 230, 112, 14, 7, - 230, 111, 14, 7, 230, 110, 14, 7, 230, 109, 14, 7, 230, 108, 14, 7, 230, - 107, 14, 7, 230, 106, 14, 7, 228, 54, 14, 7, 228, 53, 14, 7, 228, 52, 14, - 7, 228, 51, 14, 7, 228, 50, 14, 7, 228, 49, 14, 7, 228, 48, 14, 7, 228, - 47, 14, 7, 228, 46, 14, 7, 228, 45, 14, 7, 228, 44, 14, 7, 228, 43, 14, - 7, 228, 42, 14, 7, 228, 41, 14, 7, 228, 40, 14, 7, 228, 39, 14, 7, 228, - 38, 14, 7, 228, 37, 14, 7, 228, 36, 14, 7, 222, 151, 14, 7, 222, 150, 14, - 7, 222, 149, 14, 7, 222, 148, 14, 7, 222, 147, 14, 7, 222, 146, 14, 7, - 222, 145, 14, 7, 222, 144, 14, 7, 220, 140, 14, 7, 220, 139, 14, 7, 220, - 138, 14, 7, 220, 137, 14, 7, 220, 136, 14, 7, 220, 135, 14, 7, 220, 134, - 14, 7, 220, 133, 14, 7, 220, 132, 14, 7, 220, 131, 14, 7, 218, 166, 14, - 7, 218, 165, 14, 7, 218, 164, 14, 7, 218, 162, 14, 7, 218, 160, 14, 7, - 218, 159, 14, 7, 218, 157, 14, 7, 218, 155, 14, 7, 218, 153, 14, 7, 218, - 151, 14, 7, 218, 149, 14, 7, 218, 147, 14, 7, 218, 145, 14, 7, 218, 144, - 14, 7, 218, 142, 14, 7, 218, 140, 14, 7, 218, 139, 14, 7, 218, 138, 14, - 7, 218, 137, 14, 7, 218, 136, 14, 7, 218, 135, 14, 7, 218, 134, 14, 7, - 218, 133, 14, 7, 218, 132, 14, 7, 218, 130, 14, 7, 218, 128, 14, 7, 218, - 126, 14, 7, 218, 125, 14, 7, 218, 123, 14, 7, 218, 122, 14, 7, 218, 120, - 14, 7, 218, 119, 14, 7, 218, 117, 14, 7, 218, 115, 14, 7, 218, 113, 14, - 7, 218, 111, 14, 7, 218, 109, 14, 7, 218, 108, 14, 7, 218, 106, 14, 7, - 218, 104, 14, 7, 218, 103, 14, 7, 218, 101, 14, 7, 218, 99, 14, 7, 218, - 97, 14, 7, 218, 95, 14, 7, 218, 94, 14, 7, 218, 92, 14, 7, 218, 90, 14, - 7, 218, 88, 14, 7, 218, 87, 14, 7, 218, 85, 14, 7, 218, 83, 14, 7, 218, - 82, 14, 7, 218, 81, 14, 7, 218, 79, 14, 7, 218, 77, 14, 7, 218, 75, 14, - 7, 218, 73, 14, 7, 218, 71, 14, 7, 218, 69, 14, 7, 218, 67, 14, 7, 218, - 66, 14, 7, 218, 64, 14, 7, 218, 62, 14, 7, 218, 60, 14, 7, 218, 58, 14, - 7, 215, 56, 14, 7, 215, 55, 14, 7, 215, 54, 14, 7, 215, 53, 14, 7, 215, - 52, 14, 7, 215, 51, 14, 7, 215, 50, 14, 7, 215, 49, 14, 7, 215, 48, 14, - 7, 215, 47, 14, 7, 215, 46, 14, 7, 215, 45, 14, 7, 215, 44, 14, 7, 215, - 43, 14, 7, 215, 42, 14, 7, 215, 41, 14, 7, 215, 40, 14, 7, 215, 39, 14, - 7, 215, 38, 14, 7, 215, 37, 14, 7, 215, 36, 14, 7, 215, 35, 14, 7, 215, - 34, 14, 7, 215, 33, 14, 7, 215, 32, 14, 7, 215, 31, 14, 7, 215, 30, 14, - 7, 215, 29, 14, 7, 215, 28, 14, 7, 215, 27, 14, 7, 215, 26, 14, 7, 215, - 25, 14, 7, 215, 24, 14, 7, 215, 23, 14, 7, 215, 22, 14, 7, 215, 21, 14, - 7, 215, 20, 14, 7, 215, 19, 14, 7, 215, 18, 14, 7, 215, 17, 14, 7, 215, - 16, 14, 7, 215, 15, 14, 7, 215, 14, 14, 7, 215, 13, 14, 7, 215, 12, 14, - 7, 215, 11, 14, 7, 215, 10, 14, 7, 215, 9, 14, 7, 215, 8, 14, 7, 213, - 104, 14, 7, 213, 103, 14, 7, 213, 102, 14, 7, 213, 101, 14, 7, 213, 100, - 14, 7, 213, 99, 14, 7, 213, 98, 14, 7, 213, 97, 14, 7, 213, 96, 14, 7, - 213, 95, 14, 7, 213, 94, 14, 7, 213, 93, 14, 7, 213, 92, 14, 7, 213, 91, - 14, 7, 213, 90, 14, 7, 213, 89, 14, 7, 213, 88, 14, 7, 213, 87, 14, 7, - 213, 86, 14, 7, 213, 85, 14, 7, 213, 84, 14, 7, 213, 83, 14, 7, 212, 174, - 14, 7, 212, 173, 14, 7, 212, 172, 14, 7, 212, 171, 14, 7, 212, 170, 14, - 7, 212, 169, 14, 7, 212, 168, 14, 7, 212, 167, 14, 7, 212, 166, 14, 7, - 212, 165, 14, 7, 212, 164, 14, 7, 212, 163, 14, 7, 212, 162, 14, 7, 212, - 161, 14, 7, 212, 160, 14, 7, 212, 159, 14, 7, 212, 158, 14, 7, 212, 157, - 14, 7, 212, 156, 14, 7, 212, 155, 14, 7, 212, 154, 14, 7, 212, 153, 14, - 7, 212, 152, 14, 7, 212, 151, 14, 7, 212, 150, 14, 7, 212, 149, 14, 7, - 212, 2, 14, 7, 212, 1, 14, 7, 212, 0, 14, 7, 211, 255, 14, 7, 211, 254, - 14, 7, 211, 253, 14, 7, 211, 252, 14, 7, 211, 251, 14, 7, 211, 250, 14, - 7, 211, 249, 14, 7, 211, 248, 14, 7, 211, 247, 14, 7, 211, 246, 14, 7, - 211, 245, 14, 7, 211, 244, 14, 7, 211, 243, 14, 7, 211, 242, 14, 7, 211, - 241, 14, 7, 211, 240, 14, 7, 211, 239, 14, 7, 211, 238, 14, 7, 211, 237, - 14, 7, 211, 236, 14, 7, 211, 235, 14, 7, 211, 234, 14, 7, 211, 233, 14, - 7, 211, 232, 14, 7, 211, 231, 14, 7, 211, 230, 14, 7, 211, 229, 14, 7, - 211, 228, 14, 7, 211, 227, 14, 7, 211, 226, 14, 7, 211, 225, 14, 7, 211, - 224, 14, 7, 211, 223, 14, 7, 211, 222, 14, 7, 211, 221, 14, 7, 211, 220, - 14, 7, 211, 219, 14, 7, 211, 218, 14, 7, 211, 217, 14, 7, 211, 216, 14, - 7, 211, 215, 14, 7, 211, 214, 14, 7, 211, 213, 14, 7, 211, 212, 14, 7, - 211, 211, 14, 7, 211, 210, 14, 7, 211, 209, 14, 7, 211, 208, 14, 7, 211, - 207, 14, 7, 211, 206, 14, 7, 211, 205, 14, 7, 211, 204, 14, 7, 211, 203, - 14, 7, 211, 202, 14, 7, 211, 201, 14, 7, 211, 200, 14, 7, 211, 199, 14, - 7, 211, 198, 14, 7, 211, 197, 14, 7, 211, 196, 14, 7, 211, 195, 14, 7, - 211, 194, 14, 7, 211, 193, 14, 7, 211, 192, 14, 7, 211, 191, 14, 7, 211, - 190, 14, 7, 211, 189, 14, 7, 211, 188, 14, 7, 211, 187, 14, 7, 211, 186, - 14, 7, 211, 185, 14, 7, 211, 184, 14, 7, 210, 235, 14, 7, 210, 234, 14, - 7, 210, 233, 14, 7, 210, 232, 14, 7, 210, 231, 14, 7, 210, 230, 14, 7, - 210, 229, 14, 7, 210, 228, 14, 7, 210, 227, 14, 7, 210, 226, 14, 7, 210, - 225, 14, 7, 210, 224, 14, 7, 210, 223, 14, 7, 208, 103, 14, 7, 208, 102, - 14, 7, 208, 101, 14, 7, 208, 100, 14, 7, 208, 99, 14, 7, 208, 98, 14, 7, - 208, 97, 14, 7, 207, 220, 14, 7, 207, 219, 14, 7, 207, 218, 14, 7, 207, - 217, 14, 7, 207, 216, 14, 7, 207, 215, 14, 7, 207, 214, 14, 7, 207, 213, - 14, 7, 207, 212, 14, 7, 207, 211, 14, 7, 207, 210, 14, 7, 207, 209, 14, - 7, 207, 208, 14, 7, 207, 207, 14, 7, 207, 206, 14, 7, 207, 205, 14, 7, - 207, 204, 14, 7, 207, 203, 14, 7, 207, 202, 14, 7, 207, 201, 14, 7, 207, - 200, 14, 7, 207, 199, 14, 7, 207, 198, 14, 7, 207, 197, 14, 7, 207, 196, - 14, 7, 207, 195, 14, 7, 207, 194, 14, 7, 207, 193, 14, 7, 207, 192, 14, - 7, 207, 191, 14, 7, 207, 190, 14, 7, 207, 189, 14, 7, 207, 188, 14, 7, - 207, 187, 14, 7, 206, 5, 14, 7, 206, 4, 14, 7, 206, 3, 14, 7, 206, 2, 14, - 7, 206, 1, 14, 7, 206, 0, 14, 7, 205, 255, 14, 7, 205, 254, 14, 7, 205, - 253, 14, 7, 205, 252, 14, 7, 205, 251, 14, 7, 205, 250, 14, 7, 205, 249, - 14, 7, 205, 248, 14, 7, 205, 247, 14, 7, 205, 246, 14, 7, 205, 245, 14, - 7, 205, 244, 14, 7, 205, 243, 14, 7, 205, 242, 14, 7, 205, 241, 14, 7, - 205, 240, 14, 7, 205, 239, 14, 7, 205, 238, 14, 7, 205, 237, 14, 7, 205, - 236, 14, 7, 205, 235, 14, 7, 205, 234, 14, 7, 205, 233, 14, 7, 205, 232, - 14, 7, 205, 231, 14, 7, 205, 230, 14, 7, 205, 229, 14, 7, 205, 228, 14, - 7, 205, 227, 14, 7, 205, 226, 14, 7, 205, 225, 14, 7, 205, 224, 14, 7, - 205, 223, 14, 7, 205, 222, 14, 7, 205, 221, 14, 7, 205, 220, 14, 7, 205, - 219, 14, 7, 205, 218, 14, 7, 205, 217, 14, 7, 205, 216, 14, 7, 205, 215, - 14, 7, 205, 214, 14, 7, 205, 213, 14, 7, 205, 212, 14, 7, 205, 211, 14, - 7, 205, 210, 14, 7, 205, 209, 14, 7, 205, 208, 14, 7, 200, 40, 14, 7, + 106, 51, 1, 195, 188, 191, 106, 51, 1, 203, 166, 191, 106, 51, 1, 201, + 176, 191, 106, 51, 1, 188, 191, 106, 51, 1, 140, 191, 106, 51, 1, 220, + 248, 191, 106, 51, 53, 120, 77, 191, 106, 51, 3, 195, 40, 191, 106, 51, + 3, 247, 121, 191, 106, 51, 3, 247, 122, 4, 211, 44, 191, 106, 51, 3, 247, + 124, 4, 211, 44, 191, 106, 51, 3, 251, 73, 191, 106, 51, 3, 195, 35, 191, + 106, 51, 242, 203, 1, 165, 191, 106, 51, 242, 204, 1, 170, 191, 106, 51, + 242, 204, 1, 165, 191, 106, 51, 242, 204, 1, 173, 191, 106, 51, 242, 204, + 1, 195, 188, 191, 106, 51, 89, 229, 238, 77, 191, 106, 51, 242, 217, 229, + 238, 77, 191, 106, 51, 87, 197, 152, 191, 106, 51, 87, 203, 158, 191, + 106, 51, 87, 55, 203, 158, 191, 106, 51, 87, 180, 197, 152, 191, 106, 51, + 89, 235, 132, 229, 238, 77, 191, 106, 51, 242, 217, 235, 132, 229, 238, + 77, 191, 106, 51, 200, 239, 201, 252, 1, 65, 201, 252, 18, 3, 68, 201, + 252, 18, 3, 196, 152, 201, 252, 18, 3, 66, 201, 252, 18, 3, 71, 201, 252, + 18, 3, 74, 201, 252, 18, 3, 211, 153, 201, 252, 18, 3, 251, 238, 201, + 252, 18, 3, 250, 165, 201, 252, 18, 3, 117, 146, 201, 252, 18, 3, 117, + 172, 201, 252, 18, 219, 200, 77, 201, 252, 1, 155, 201, 252, 1, 221, 217, + 201, 252, 1, 231, 242, 201, 252, 1, 231, 93, 201, 252, 1, 214, 70, 201, + 252, 1, 247, 162, 201, 252, 1, 247, 3, 201, 252, 1, 223, 34, 201, 252, 1, + 222, 254, 201, 252, 1, 212, 103, 201, 252, 1, 197, 132, 201, 252, 1, 197, + 120, 201, 252, 1, 237, 193, 201, 252, 1, 237, 177, 201, 252, 1, 213, 81, + 201, 252, 1, 190, 190, 201, 252, 1, 199, 49, 201, 252, 1, 238, 34, 201, + 252, 1, 237, 70, 201, 252, 1, 181, 201, 252, 1, 168, 201, 252, 1, 209, + 230, 201, 252, 1, 249, 155, 201, 252, 1, 248, 205, 201, 252, 1, 174, 201, + 252, 1, 197, 168, 201, 252, 1, 197, 157, 201, 252, 1, 235, 37, 201, 252, + 1, 191, 71, 201, 252, 1, 191, 123, 201, 252, 1, 255, 216, 201, 252, 1, + 170, 201, 252, 1, 165, 201, 252, 1, 173, 201, 252, 1, 195, 188, 201, 252, + 1, 203, 166, 201, 252, 1, 201, 176, 201, 252, 1, 188, 201, 252, 1, 140, + 201, 252, 1, 220, 248, 201, 252, 3, 222, 239, 201, 252, 3, 196, 75, 201, + 252, 242, 203, 1, 165, 201, 252, 242, 203, 1, 173, 201, 252, 242, 203, 1, + 203, 166, 201, 252, 242, 203, 1, 188, 201, 252, 53, 120, 3, 232, 53, 201, + 252, 53, 120, 3, 222, 154, 201, 252, 53, 120, 3, 214, 72, 201, 252, 53, + 120, 3, 238, 129, 201, 252, 53, 120, 3, 215, 63, 201, 252, 53, 120, 3, + 250, 122, 201, 252, 53, 120, 3, 218, 170, 201, 252, 53, 120, 3, 146, 201, + 252, 53, 120, 3, 172, 201, 252, 53, 120, 3, 203, 168, 201, 252, 53, 120, + 3, 206, 9, 201, 252, 53, 120, 3, 255, 216, 201, 252, 3, 251, 73, 201, + 252, 3, 195, 35, 201, 252, 231, 155, 77, 201, 252, 200, 239, 201, 252, + 87, 197, 152, 201, 252, 87, 203, 158, 201, 252, 87, 55, 203, 158, 201, + 252, 87, 209, 81, 201, 252, 229, 238, 87, 4, 215, 208, 23, 200, 199, 23, + 197, 225, 232, 212, 201, 252, 229, 238, 87, 4, 215, 208, 23, 200, 199, + 23, 232, 212, 201, 252, 229, 238, 87, 4, 215, 208, 23, 200, 198, 201, + 252, 199, 81, 217, 57, 201, 252, 199, 81, 217, 56, 21, 22, 214, 209, 229, + 160, 21, 22, 214, 209, 229, 132, 21, 22, 214, 209, 229, 25, 21, 22, 214, + 209, 228, 254, 21, 22, 214, 209, 140, 21, 22, 214, 209, 230, 93, 21, 22, + 214, 209, 203, 16, 21, 22, 214, 209, 203, 15, 21, 22, 214, 209, 203, 12, + 21, 22, 214, 209, 203, 11, 21, 22, 214, 209, 203, 18, 21, 22, 214, 209, + 203, 17, 21, 22, 201, 238, 21, 22, 201, 225, 21, 22, 201, 208, 21, 22, + 201, 250, 210, 83, 243, 17, 230, 5, 1, 168, 210, 83, 243, 17, 230, 5, 1, + 155, 210, 83, 243, 17, 230, 5, 1, 173, 210, 83, 243, 17, 230, 5, 1, 174, + 210, 83, 243, 17, 230, 5, 1, 238, 34, 210, 83, 243, 17, 230, 5, 1, 191, + 123, 210, 83, 243, 17, 230, 5, 1, 195, 188, 210, 83, 243, 17, 230, 5, 1, + 214, 70, 210, 83, 243, 17, 230, 5, 1, 140, 210, 83, 243, 17, 230, 5, 1, + 231, 242, 210, 83, 243, 17, 230, 5, 1, 221, 217, 210, 83, 243, 17, 230, + 5, 1, 188, 210, 83, 243, 17, 230, 5, 1, 249, 155, 210, 83, 243, 17, 230, + 5, 1, 247, 162, 210, 83, 243, 17, 230, 5, 1, 190, 190, 210, 83, 243, 17, + 230, 5, 1, 199, 49, 210, 83, 243, 17, 230, 5, 1, 181, 210, 83, 243, 17, + 230, 5, 1, 209, 230, 210, 83, 243, 17, 230, 5, 1, 165, 210, 83, 243, 17, + 230, 5, 1, 233, 111, 210, 83, 243, 17, 230, 5, 1, 247, 3, 210, 83, 243, + 17, 230, 5, 1, 65, 210, 83, 243, 17, 230, 5, 1, 71, 210, 83, 243, 17, + 230, 5, 1, 68, 210, 83, 243, 17, 230, 5, 1, 74, 210, 83, 243, 17, 230, 5, + 1, 66, 210, 83, 243, 17, 230, 5, 1, 196, 168, 210, 83, 243, 17, 230, 5, + 1, 228, 37, 210, 83, 243, 17, 230, 5, 1, 53, 210, 238, 210, 83, 243, 17, + 230, 5, 1, 53, 222, 154, 210, 83, 243, 17, 230, 5, 1, 53, 200, 43, 210, + 83, 243, 17, 230, 5, 1, 53, 218, 170, 210, 83, 243, 17, 230, 5, 1, 53, + 215, 63, 210, 83, 243, 17, 230, 5, 1, 53, 172, 210, 83, 243, 17, 230, 5, + 1, 53, 193, 224, 210, 83, 243, 17, 230, 5, 1, 53, 214, 72, 210, 83, 243, + 17, 230, 5, 1, 53, 192, 159, 210, 83, 243, 17, 230, 5, 206, 181, 163, + 219, 21, 210, 83, 243, 17, 230, 5, 206, 181, 198, 79, 210, 83, 243, 17, + 230, 5, 205, 139, 231, 13, 201, 64, 210, 83, 243, 17, 230, 5, 206, 181, + 163, 180, 233, 1, 210, 83, 243, 17, 230, 5, 206, 181, 163, 233, 1, 210, + 83, 243, 17, 230, 5, 205, 139, 231, 13, 201, 65, 233, 1, 210, 83, 243, + 17, 230, 5, 205, 139, 163, 219, 21, 210, 83, 243, 17, 230, 5, 205, 139, + 198, 79, 210, 83, 243, 17, 230, 5, 205, 139, 163, 180, 233, 1, 210, 83, + 243, 17, 230, 5, 205, 139, 163, 233, 1, 210, 83, 243, 17, 230, 5, 216, + 87, 198, 79, 210, 83, 243, 17, 230, 5, 231, 13, 201, 65, 195, 167, 210, + 83, 243, 17, 230, 5, 216, 87, 163, 180, 233, 1, 210, 83, 243, 17, 230, 5, + 216, 87, 163, 233, 1, 210, 83, 243, 17, 230, 5, 218, 241, 163, 219, 21, + 210, 83, 243, 17, 230, 5, 218, 241, 198, 79, 210, 83, 243, 17, 230, 5, + 231, 13, 201, 64, 210, 83, 243, 17, 230, 5, 218, 241, 163, 180, 233, 1, + 210, 83, 243, 17, 230, 5, 218, 241, 163, 233, 1, 210, 83, 243, 17, 230, + 5, 231, 13, 201, 65, 233, 1, 100, 229, 238, 77, 100, 229, 238, 87, 4, + 229, 229, 100, 3, 248, 201, 100, 3, 248, 202, 4, 102, 100, 3, 233, 207, + 248, 201, 100, 3, 233, 207, 248, 202, 4, 102, 100, 3, 193, 102, 232, 227, + 248, 201, 100, 3, 193, 102, 213, 176, 248, 201, 100, 3, 207, 19, 213, + 176, 248, 201, 100, 3, 216, 45, 248, 203, 1, 65, 248, 203, 1, 252, 208, + 248, 203, 1, 68, 248, 203, 1, 223, 201, 248, 203, 1, 66, 248, 203, 1, + 196, 30, 248, 203, 1, 117, 146, 248, 203, 1, 117, 206, 111, 248, 203, 1, + 117, 172, 248, 203, 1, 71, 248, 203, 1, 251, 238, 248, 203, 1, 74, 248, + 203, 1, 250, 165, 248, 203, 1, 155, 248, 203, 1, 221, 217, 248, 203, 1, + 231, 242, 248, 203, 1, 231, 93, 248, 203, 1, 214, 70, 248, 203, 1, 247, + 162, 248, 203, 1, 247, 3, 248, 203, 1, 223, 34, 248, 203, 1, 222, 254, + 248, 203, 1, 212, 103, 248, 203, 1, 197, 132, 248, 203, 1, 197, 120, 248, + 203, 1, 237, 193, 248, 203, 1, 237, 177, 248, 203, 1, 213, 81, 248, 203, + 1, 190, 190, 248, 203, 1, 199, 49, 248, 203, 1, 238, 34, 248, 203, 1, + 237, 70, 248, 203, 1, 181, 248, 203, 1, 168, 248, 203, 1, 209, 230, 248, + 203, 1, 249, 155, 248, 203, 1, 248, 205, 248, 203, 1, 174, 248, 203, 1, + 170, 248, 203, 1, 165, 248, 203, 1, 173, 248, 203, 1, 195, 188, 248, 203, + 1, 203, 166, 248, 203, 1, 201, 176, 248, 203, 1, 188, 248, 203, 1, 140, + 248, 203, 18, 3, 252, 208, 248, 203, 18, 3, 68, 248, 203, 18, 3, 223, + 201, 248, 203, 18, 3, 66, 248, 203, 18, 3, 196, 30, 248, 203, 18, 3, 117, + 146, 248, 203, 18, 3, 117, 206, 111, 248, 203, 18, 3, 117, 172, 248, 203, + 18, 3, 71, 248, 203, 18, 3, 251, 238, 248, 203, 18, 3, 74, 248, 203, 18, + 3, 250, 165, 248, 203, 3, 247, 121, 248, 203, 3, 251, 73, 248, 203, 3, + 195, 35, 248, 203, 3, 195, 40, 248, 203, 3, 250, 147, 248, 203, 237, 240, + 248, 203, 55, 237, 240, 248, 203, 193, 23, 204, 11, 248, 203, 231, 206, + 233, 4, 248, 203, 231, 206, 233, 3, 248, 203, 17, 191, 77, 248, 203, 17, + 107, 248, 203, 17, 109, 248, 203, 17, 138, 248, 203, 17, 134, 248, 203, + 17, 150, 248, 203, 17, 169, 248, 203, 17, 175, 248, 203, 17, 171, 248, + 203, 17, 178, 248, 203, 31, 107, 248, 203, 31, 109, 248, 203, 31, 138, + 248, 203, 31, 134, 248, 203, 31, 150, 248, 203, 31, 169, 248, 203, 31, + 175, 248, 203, 31, 171, 248, 203, 31, 178, 248, 203, 31, 199, 95, 248, + 203, 31, 197, 32, 248, 203, 31, 198, 249, 248, 203, 31, 232, 137, 248, + 203, 31, 233, 17, 248, 203, 31, 202, 121, 248, 203, 31, 203, 242, 248, + 203, 31, 234, 155, 248, 203, 31, 213, 171, 248, 203, 228, 141, 196, 91, + 77, 217, 59, 229, 238, 77, 217, 59, 87, 203, 158, 217, 59, 1, 155, 217, + 59, 1, 221, 217, 217, 59, 1, 231, 242, 217, 59, 1, 214, 70, 217, 59, 1, + 247, 162, 217, 59, 1, 247, 3, 217, 59, 1, 223, 34, 217, 59, 1, 212, 103, + 217, 59, 1, 190, 190, 217, 59, 1, 199, 49, 217, 59, 1, 238, 34, 217, 59, + 1, 181, 217, 59, 1, 168, 217, 59, 1, 209, 230, 217, 59, 1, 249, 155, 217, + 59, 1, 174, 217, 59, 1, 197, 168, 217, 59, 1, 197, 157, 217, 59, 1, 235, + 37, 217, 59, 1, 193, 190, 217, 59, 1, 191, 71, 217, 59, 1, 191, 123, 217, + 59, 1, 255, 216, 217, 59, 1, 170, 217, 59, 1, 165, 217, 59, 1, 173, 217, + 59, 1, 203, 166, 217, 59, 1, 188, 217, 59, 1, 140, 217, 59, 1, 65, 217, + 59, 200, 240, 1, 155, 217, 59, 200, 240, 1, 221, 217, 217, 59, 200, 240, + 1, 231, 242, 217, 59, 200, 240, 1, 214, 70, 217, 59, 200, 240, 1, 247, + 162, 217, 59, 200, 240, 1, 247, 3, 217, 59, 200, 240, 1, 223, 34, 217, + 59, 200, 240, 1, 212, 103, 217, 59, 200, 240, 1, 190, 190, 217, 59, 200, + 240, 1, 199, 49, 217, 59, 200, 240, 1, 238, 34, 217, 59, 200, 240, 1, + 181, 217, 59, 200, 240, 1, 168, 217, 59, 200, 240, 1, 209, 230, 217, 59, + 200, 240, 1, 249, 155, 217, 59, 200, 240, 1, 174, 217, 59, 200, 240, 1, + 197, 168, 217, 59, 200, 240, 1, 197, 157, 217, 59, 200, 240, 1, 235, 37, + 217, 59, 200, 240, 1, 193, 190, 217, 59, 200, 240, 1, 191, 71, 217, 59, + 200, 240, 1, 191, 123, 217, 59, 200, 240, 1, 170, 217, 59, 200, 240, 1, + 165, 217, 59, 200, 240, 1, 173, 217, 59, 200, 240, 1, 203, 166, 217, 59, + 200, 240, 1, 188, 217, 59, 200, 240, 1, 140, 217, 59, 200, 240, 1, 65, + 217, 59, 18, 3, 252, 208, 217, 59, 18, 3, 68, 217, 59, 18, 3, 66, 217, + 59, 18, 3, 71, 217, 59, 18, 3, 74, 217, 59, 3, 251, 73, 217, 59, 3, 247, + 121, 217, 43, 129, 1, 65, 217, 43, 129, 1, 252, 208, 217, 43, 129, 1, 68, + 217, 43, 129, 1, 223, 201, 217, 43, 129, 1, 66, 217, 43, 129, 1, 196, 30, + 217, 43, 129, 1, 71, 217, 43, 129, 1, 251, 238, 217, 43, 129, 1, 74, 217, + 43, 129, 1, 250, 165, 217, 43, 129, 1, 155, 217, 43, 129, 1, 221, 217, + 217, 43, 129, 1, 231, 242, 217, 43, 129, 1, 231, 93, 217, 43, 129, 1, + 214, 70, 217, 43, 129, 1, 247, 162, 217, 43, 129, 1, 247, 3, 217, 43, + 129, 1, 223, 34, 217, 43, 129, 1, 222, 254, 217, 43, 129, 1, 212, 103, + 217, 43, 129, 1, 197, 132, 217, 43, 129, 1, 197, 120, 217, 43, 129, 1, + 237, 193, 217, 43, 129, 1, 237, 177, 217, 43, 129, 1, 213, 81, 217, 43, + 129, 1, 190, 190, 217, 43, 129, 1, 199, 49, 217, 43, 129, 1, 238, 34, + 217, 43, 129, 1, 237, 70, 217, 43, 129, 1, 181, 217, 43, 129, 1, 168, + 217, 43, 129, 1, 209, 230, 217, 43, 129, 1, 249, 155, 217, 43, 129, 1, + 248, 205, 217, 43, 129, 1, 174, 217, 43, 129, 1, 170, 217, 43, 129, 1, + 165, 217, 43, 129, 1, 173, 217, 43, 129, 1, 195, 188, 217, 43, 129, 1, + 203, 166, 217, 43, 129, 1, 201, 176, 217, 43, 129, 1, 188, 217, 43, 129, + 1, 140, 217, 43, 129, 1, 219, 75, 217, 43, 129, 1, 220, 248, 217, 43, + 129, 1, 222, 204, 217, 43, 129, 1, 198, 26, 217, 43, 129, 18, 3, 252, + 208, 217, 43, 129, 18, 3, 68, 217, 43, 129, 18, 3, 223, 201, 217, 43, + 129, 18, 3, 66, 217, 43, 129, 18, 3, 196, 30, 217, 43, 129, 18, 3, 117, + 146, 217, 43, 129, 18, 3, 71, 217, 43, 129, 18, 3, 251, 238, 217, 43, + 129, 18, 3, 74, 217, 43, 129, 18, 3, 250, 165, 217, 43, 129, 3, 251, 73, + 217, 43, 129, 3, 195, 35, 217, 43, 129, 3, 212, 143, 217, 43, 129, 3, + 247, 123, 217, 43, 129, 3, 230, 74, 217, 43, 129, 195, 40, 217, 43, 129, + 207, 45, 217, 43, 129, 207, 183, 217, 43, 129, 17, 191, 77, 217, 43, 129, + 17, 107, 217, 43, 129, 17, 109, 217, 43, 129, 17, 138, 217, 43, 129, 17, + 134, 217, 43, 129, 17, 150, 217, 43, 129, 17, 169, 217, 43, 129, 17, 175, + 217, 43, 129, 17, 171, 217, 43, 129, 17, 178, 230, 159, 129, 1, 65, 230, + 159, 129, 1, 252, 208, 230, 159, 129, 1, 68, 230, 159, 129, 1, 223, 201, + 230, 159, 129, 1, 66, 230, 159, 129, 1, 196, 30, 230, 159, 129, 1, 234, + 190, 230, 159, 129, 1, 251, 238, 230, 159, 129, 1, 211, 89, 230, 159, + 129, 1, 250, 165, 230, 159, 129, 1, 170, 230, 159, 129, 1, 195, 188, 230, + 159, 129, 1, 249, 155, 230, 159, 129, 1, 248, 205, 230, 159, 129, 1, 174, + 230, 159, 129, 1, 155, 230, 159, 129, 1, 221, 217, 230, 159, 129, 1, 190, + 190, 230, 159, 129, 1, 199, 49, 230, 159, 129, 1, 173, 230, 159, 129, 1, + 231, 242, 230, 159, 129, 1, 231, 93, 230, 159, 129, 1, 238, 34, 230, 159, + 129, 1, 237, 70, 230, 159, 129, 1, 181, 230, 159, 129, 1, 247, 162, 230, + 159, 129, 1, 247, 3, 230, 159, 129, 1, 197, 132, 230, 159, 129, 1, 197, + 120, 230, 159, 129, 1, 219, 75, 230, 159, 129, 1, 223, 34, 230, 159, 129, + 1, 222, 254, 230, 159, 129, 1, 237, 193, 230, 159, 129, 1, 237, 177, 230, + 159, 129, 1, 214, 70, 230, 159, 129, 1, 168, 230, 159, 129, 1, 209, 230, + 230, 159, 129, 1, 140, 230, 159, 129, 1, 165, 230, 159, 129, 1, 188, 230, + 159, 129, 18, 3, 252, 208, 230, 159, 129, 18, 3, 68, 230, 159, 129, 18, + 3, 223, 201, 230, 159, 129, 18, 3, 66, 230, 159, 129, 18, 3, 196, 30, + 230, 159, 129, 18, 3, 234, 190, 230, 159, 129, 18, 3, 251, 238, 230, 159, + 129, 18, 3, 211, 89, 230, 159, 129, 18, 3, 250, 165, 230, 159, 129, 3, + 251, 73, 230, 159, 129, 3, 195, 35, 230, 159, 129, 195, 40, 230, 159, + 129, 211, 115, 230, 159, 129, 17, 191, 77, 230, 159, 129, 17, 107, 230, + 159, 129, 17, 109, 230, 159, 129, 17, 138, 230, 159, 129, 17, 134, 230, + 159, 129, 17, 150, 230, 159, 129, 17, 169, 230, 159, 129, 17, 175, 230, + 159, 129, 17, 171, 230, 159, 129, 17, 178, 217, 104, 1, 155, 217, 104, 1, + 231, 242, 217, 104, 1, 214, 70, 217, 104, 1, 168, 217, 104, 1, 249, 155, + 217, 104, 1, 174, 217, 104, 1, 190, 190, 217, 104, 1, 238, 34, 217, 104, + 1, 181, 217, 104, 1, 247, 162, 217, 104, 1, 223, 34, 217, 104, 1, 212, + 103, 217, 104, 1, 170, 217, 104, 1, 165, 217, 104, 1, 173, 217, 104, 1, + 195, 188, 217, 104, 1, 188, 217, 104, 1, 65, 217, 104, 251, 120, 217, + 104, 18, 3, 68, 217, 104, 18, 3, 66, 217, 104, 18, 3, 71, 217, 104, 18, + 3, 74, 217, 104, 210, 96, 217, 104, 234, 97, 79, 205, 54, 222, 35, 3, + 247, 121, 222, 35, 3, 251, 73, 222, 35, 3, 207, 45, 222, 35, 3, 195, 35, + 222, 35, 1, 65, 222, 35, 1, 252, 208, 222, 35, 1, 68, 222, 35, 1, 223, + 201, 222, 35, 1, 66, 222, 35, 1, 196, 30, 222, 35, 1, 117, 146, 222, 35, + 1, 117, 206, 111, 222, 35, 1, 117, 172, 222, 35, 1, 117, 219, 76, 222, + 35, 1, 71, 222, 35, 1, 251, 238, 222, 35, 1, 74, 222, 35, 1, 155, 222, + 35, 1, 221, 217, 222, 35, 1, 231, 242, 222, 35, 1, 231, 93, 222, 35, 1, + 214, 70, 222, 35, 1, 247, 162, 222, 35, 1, 247, 3, 222, 35, 1, 223, 34, + 222, 35, 1, 222, 254, 222, 35, 1, 212, 103, 222, 35, 1, 197, 132, 222, + 35, 1, 197, 120, 222, 35, 1, 237, 193, 222, 35, 1, 237, 177, 222, 35, 1, + 213, 81, 222, 35, 1, 190, 190, 222, 35, 1, 199, 49, 222, 35, 1, 238, 34, + 222, 35, 1, 237, 70, 222, 35, 1, 181, 222, 35, 1, 168, 222, 35, 1, 209, + 230, 222, 35, 1, 249, 155, 222, 35, 1, 248, 205, 222, 35, 1, 174, 222, + 35, 1, 170, 222, 35, 1, 165, 222, 35, 1, 173, 222, 35, 1, 193, 190, 222, + 35, 1, 203, 166, 222, 35, 1, 201, 176, 222, 35, 1, 188, 222, 35, 1, 140, + 222, 35, 1, 222, 204, 222, 35, 18, 3, 252, 208, 222, 35, 18, 3, 251, 159, + 252, 208, 222, 35, 18, 3, 68, 222, 35, 18, 3, 223, 201, 222, 35, 18, 3, + 66, 222, 35, 18, 3, 196, 30, 222, 35, 18, 3, 117, 146, 222, 35, 18, 3, + 71, 222, 35, 18, 3, 251, 238, 222, 35, 18, 3, 233, 244, 222, 35, 3, 221, + 145, 222, 35, 239, 47, 222, 35, 237, 240, 222, 35, 55, 237, 240, 222, 35, + 208, 154, 205, 55, 217, 53, 222, 35, 208, 154, 251, 159, 205, 55, 217, + 53, 222, 35, 208, 154, 232, 188, 222, 35, 208, 154, 201, 249, 233, 5, + 222, 35, 208, 154, 236, 142, 222, 35, 208, 154, 55, 236, 142, 222, 35, + 208, 154, 197, 225, 236, 142, 222, 35, 208, 154, 243, 12, 222, 35, 208, + 154, 233, 6, 243, 12, 222, 35, 208, 154, 201, 218, 222, 35, 208, 154, + 242, 217, 201, 218, 222, 35, 17, 191, 77, 222, 35, 17, 107, 222, 35, 17, + 109, 222, 35, 17, 138, 222, 35, 17, 134, 222, 35, 17, 150, 222, 35, 17, + 169, 222, 35, 17, 175, 222, 35, 17, 171, 222, 35, 17, 178, 219, 90, 1, + 192, 35, 44, 232, 120, 91, 198, 222, 44, 232, 120, 91, 211, 102, 44, 232, + 120, 91, 234, 158, 44, 232, 120, 91, 202, 119, 44, 232, 120, 91, 232, + 141, 44, 232, 120, 91, 198, 245, 44, 232, 120, 115, 234, 157, 44, 232, + 120, 115, 202, 118, 44, 232, 120, 91, 197, 35, 44, 232, 120, 91, 202, + 128, 44, 232, 120, 91, 202, 127, 44, 232, 120, 91, 199, 86, 44, 232, 120, + 91, 234, 161, 44, 232, 120, 115, 197, 34, 44, 232, 120, 115, 202, 126, + 44, 232, 120, 91, 233, 20, 44, 232, 120, 91, 208, 24, 44, 232, 120, 91, + 230, 71, 44, 232, 120, 91, 230, 70, 44, 232, 120, 115, 208, 22, 44, 232, + 120, 235, 123, 233, 95, 221, 146, 44, 3, 214, 106, 44, 3, 247, 8, 44, 3, + 252, 159, 44, 3, 196, 15, 44, 3, 215, 92, 44, 3, 220, 196, 44, 3, 210, + 87, 44, 3, 215, 137, 44, 3, 222, 126, 44, 3, 210, 166, 44, 3, 209, 41, + 44, 3, 195, 173, 44, 3, 210, 217, 44, 3, 220, 185, 44, 3, 195, 143, 44, + 193, 101, 238, 189, 56, 44, 235, 94, 238, 189, 56, 44, 220, 25, 56, 44, + 205, 160, 210, 169, 56, 44, 198, 21, 238, 232, 56, 44, 198, 21, 31, 56, + 44, 238, 171, 56, 44, 23, 211, 157, 56, 44, 201, 228, 56, 44, 198, 39, + 56, 44, 223, 165, 209, 24, 56, 44, 201, 97, 232, 100, 56, 44, 3, 215, 96, + 44, 3, 195, 181, 44, 208, 154, 234, 97, 79, 199, 53, 10, 3, 65, 10, 3, + 42, 25, 65, 10, 3, 42, 25, 249, 137, 10, 3, 42, 25, 231, 211, 199, 84, + 10, 3, 42, 25, 140, 10, 3, 42, 25, 223, 203, 10, 3, 42, 25, 220, 105, + 230, 157, 10, 3, 42, 25, 215, 103, 10, 3, 42, 25, 205, 186, 10, 3, 254, + 217, 10, 3, 252, 157, 10, 3, 252, 158, 25, 250, 209, 10, 3, 252, 158, 25, + 235, 76, 230, 157, 10, 3, 252, 158, 25, 231, 224, 10, 3, 252, 158, 25, + 231, 211, 199, 84, 10, 3, 252, 158, 25, 140, 10, 3, 252, 158, 25, 223, + 204, 230, 157, 10, 3, 252, 158, 25, 223, 174, 10, 3, 252, 158, 25, 220, + 106, 10, 3, 252, 158, 25, 203, 98, 10, 3, 252, 158, 25, 126, 108, 126, + 108, 66, 10, 3, 252, 158, 230, 157, 10, 3, 252, 74, 10, 3, 252, 75, 25, + 249, 116, 10, 3, 252, 75, 25, 231, 211, 199, 84, 10, 3, 252, 75, 25, 216, + 235, 108, 234, 105, 10, 3, 252, 75, 25, 203, 164, 10, 3, 252, 75, 25, + 199, 209, 10, 3, 252, 44, 10, 3, 251, 218, 10, 3, 251, 219, 25, 234, 30, + 10, 3, 251, 219, 25, 203, 60, 108, 231, 25, 10, 3, 251, 209, 10, 3, 251, + 210, 25, 251, 209, 10, 3, 251, 210, 25, 236, 255, 10, 3, 251, 210, 25, + 231, 25, 10, 3, 251, 210, 25, 140, 10, 3, 251, 210, 25, 222, 113, 10, 3, + 251, 210, 25, 221, 168, 10, 3, 251, 210, 25, 203, 114, 10, 3, 251, 210, + 25, 196, 38, 10, 3, 251, 205, 10, 3, 251, 192, 10, 3, 251, 147, 10, 3, + 251, 148, 25, 203, 114, 10, 3, 251, 134, 10, 3, 251, 135, 139, 251, 134, + 10, 3, 251, 135, 115, 198, 144, 10, 3, 251, 135, 108, 214, 243, 211, 65, + 251, 135, 108, 214, 242, 10, 3, 251, 135, 108, 214, 243, 201, 190, 10, 3, + 251, 93, 10, 3, 251, 62, 10, 3, 251, 28, 10, 3, 251, 29, 25, 220, 199, + 10, 3, 251, 0, 10, 3, 250, 217, 10, 3, 250, 211, 10, 3, 250, 212, 191, + 26, 199, 84, 10, 3, 250, 212, 222, 118, 199, 84, 10, 3, 250, 212, 139, + 250, 212, 197, 83, 139, 197, 83, 197, 83, 139, 197, 83, 210, 139, 10, 3, + 250, 212, 139, 250, 212, 139, 250, 211, 10, 3, 250, 212, 139, 250, 212, + 139, 250, 212, 238, 212, 250, 212, 139, 250, 212, 139, 250, 211, 10, 3, + 250, 209, 10, 3, 250, 205, 10, 3, 249, 155, 10, 3, 249, 137, 10, 3, 249, + 131, 10, 3, 249, 123, 10, 3, 249, 117, 10, 3, 249, 118, 139, 249, 117, + 10, 3, 249, 116, 10, 3, 164, 10, 3, 249, 89, 10, 3, 248, 190, 10, 3, 248, + 191, 25, 65, 10, 3, 248, 191, 25, 231, 202, 10, 3, 248, 191, 25, 223, + 204, 230, 157, 10, 3, 248, 12, 10, 3, 248, 13, 139, 248, 13, 252, 157, + 10, 3, 248, 13, 139, 248, 13, 196, 113, 10, 3, 248, 13, 238, 212, 248, + 12, 10, 3, 247, 244, 10, 3, 247, 245, 139, 247, 244, 10, 3, 247, 232, 10, + 3, 247, 231, 10, 3, 238, 34, 10, 3, 238, 24, 10, 3, 238, 25, 221, 127, + 25, 42, 108, 217, 41, 10, 3, 238, 25, 221, 127, 25, 251, 147, 10, 3, 238, + 25, 221, 127, 25, 249, 116, 10, 3, 238, 25, 221, 127, 25, 248, 190, 10, + 3, 238, 25, 221, 127, 25, 231, 242, 10, 3, 238, 25, 221, 127, 25, 231, + 243, 108, 217, 41, 10, 3, 238, 25, 221, 127, 25, 231, 55, 10, 3, 238, 25, + 221, 127, 25, 231, 34, 10, 3, 238, 25, 221, 127, 25, 230, 170, 10, 3, + 238, 25, 221, 127, 25, 140, 10, 3, 238, 25, 221, 127, 25, 223, 79, 10, 3, + 238, 25, 221, 127, 25, 223, 80, 108, 218, 227, 10, 3, 238, 25, 221, 127, + 25, 222, 98, 10, 3, 238, 25, 221, 127, 25, 173, 10, 3, 238, 25, 221, 127, + 25, 218, 227, 10, 3, 238, 25, 221, 127, 25, 218, 228, 108, 217, 40, 10, + 3, 238, 25, 221, 127, 25, 218, 210, 10, 3, 238, 25, 221, 127, 25, 214, + 123, 10, 3, 238, 25, 221, 127, 25, 210, 140, 108, 210, 139, 10, 3, 238, + 25, 221, 127, 25, 202, 223, 10, 3, 238, 25, 221, 127, 25, 199, 209, 10, + 3, 238, 25, 221, 127, 25, 196, 170, 108, 231, 34, 10, 3, 238, 25, 221, + 127, 25, 196, 38, 10, 3, 237, 252, 10, 3, 237, 227, 10, 3, 237, 226, 10, + 3, 237, 225, 10, 3, 237, 46, 10, 3, 237, 28, 10, 3, 237, 1, 10, 3, 237, + 2, 25, 203, 114, 10, 3, 236, 255, 10, 3, 236, 245, 10, 3, 236, 246, 222, + 57, 126, 230, 158, 236, 224, 10, 3, 236, 224, 10, 3, 235, 91, 10, 3, 235, + 92, 139, 235, 91, 10, 3, 235, 92, 230, 157, 10, 3, 235, 92, 203, 95, 10, + 3, 235, 89, 10, 3, 235, 90, 25, 234, 11, 10, 3, 235, 88, 10, 3, 235, 84, + 10, 3, 235, 83, 10, 3, 235, 82, 10, 3, 235, 77, 10, 3, 235, 75, 10, 3, + 235, 76, 230, 157, 10, 3, 235, 76, 230, 158, 230, 157, 10, 3, 235, 74, + 10, 3, 235, 67, 10, 3, 71, 10, 3, 235, 17, 25, 210, 139, 10, 3, 235, 17, + 139, 235, 17, 212, 133, 139, 212, 132, 10, 3, 234, 220, 10, 3, 234, 221, + 25, 42, 108, 230, 107, 108, 238, 34, 10, 3, 234, 221, 25, 231, 202, 10, + 3, 234, 221, 25, 216, 102, 10, 3, 234, 221, 25, 205, 170, 10, 3, 234, + 221, 25, 203, 114, 10, 3, 234, 221, 25, 66, 10, 3, 234, 192, 10, 3, 234, + 179, 10, 3, 234, 142, 10, 3, 234, 105, 10, 3, 234, 106, 25, 231, 210, 10, + 3, 234, 106, 25, 231, 211, 199, 84, 10, 3, 234, 106, 25, 216, 234, 10, 3, + 234, 106, 238, 212, 234, 105, 10, 3, 234, 106, 211, 65, 234, 105, 10, 3, + 234, 106, 201, 190, 10, 3, 234, 33, 10, 3, 234, 30, 10, 3, 234, 11, 10, + 3, 233, 182, 10, 3, 233, 183, 25, 65, 10, 3, 233, 183, 25, 42, 108, 220, + 39, 10, 3, 233, 183, 25, 42, 108, 220, 40, 25, 220, 39, 10, 3, 233, 183, + 25, 251, 134, 10, 3, 233, 183, 25, 249, 137, 10, 3, 233, 183, 25, 235, + 76, 230, 157, 10, 3, 233, 183, 25, 235, 76, 230, 158, 230, 157, 10, 3, + 233, 183, 25, 140, 10, 3, 233, 183, 25, 230, 107, 230, 157, 10, 3, 233, + 183, 25, 223, 204, 230, 157, 10, 3, 233, 183, 25, 222, 56, 10, 3, 233, + 183, 25, 222, 57, 201, 190, 10, 3, 233, 183, 25, 220, 225, 10, 3, 233, + 183, 25, 173, 10, 3, 233, 183, 25, 220, 40, 25, 220, 39, 10, 3, 233, 183, + 25, 219, 148, 10, 3, 233, 183, 25, 218, 227, 10, 3, 233, 183, 25, 196, + 169, 10, 3, 233, 183, 25, 196, 158, 10, 3, 231, 242, 10, 3, 231, 243, + 230, 157, 10, 3, 231, 240, 10, 3, 231, 241, 25, 42, 108, 238, 35, 108, + 140, 10, 3, 231, 241, 25, 42, 108, 140, 10, 3, 231, 241, 25, 42, 108, + 223, 203, 10, 3, 231, 241, 25, 252, 75, 199, 85, 108, 199, 236, 10, 3, + 231, 241, 25, 251, 134, 10, 3, 231, 241, 25, 250, 211, 10, 3, 231, 241, + 25, 250, 210, 108, 231, 224, 10, 3, 231, 241, 25, 249, 137, 10, 3, 231, + 241, 25, 249, 90, 108, 165, 10, 3, 231, 241, 25, 247, 232, 10, 3, 231, + 241, 25, 247, 233, 108, 165, 10, 3, 231, 241, 25, 238, 34, 10, 3, 231, + 241, 25, 237, 46, 10, 3, 231, 241, 25, 237, 2, 25, 203, 114, 10, 3, 231, + 241, 25, 235, 89, 10, 3, 231, 241, 25, 234, 142, 10, 3, 231, 241, 25, + 234, 143, 108, 173, 10, 3, 231, 241, 25, 234, 105, 10, 3, 231, 241, 25, + 234, 106, 25, 231, 211, 199, 84, 10, 3, 231, 241, 25, 231, 211, 199, 84, + 10, 3, 231, 241, 25, 231, 202, 10, 3, 231, 241, 25, 231, 55, 10, 3, 231, + 241, 25, 231, 53, 10, 3, 231, 241, 25, 231, 54, 108, 65, 10, 3, 231, 241, + 25, 231, 35, 108, 201, 5, 10, 3, 231, 241, 25, 230, 107, 108, 218, 228, + 108, 234, 11, 10, 3, 231, 241, 25, 230, 75, 10, 3, 231, 241, 25, 230, 76, + 108, 173, 10, 3, 231, 241, 25, 229, 161, 108, 219, 148, 10, 3, 231, 241, + 25, 228, 153, 10, 3, 231, 241, 25, 223, 204, 230, 157, 10, 3, 231, 241, + 25, 223, 65, 108, 228, 162, 108, 250, 211, 10, 3, 231, 241, 25, 222, 98, + 10, 3, 231, 241, 25, 222, 56, 10, 3, 231, 241, 25, 221, 154, 10, 3, 231, + 241, 25, 221, 155, 108, 220, 39, 10, 3, 231, 241, 25, 220, 226, 108, 251, + 134, 10, 3, 231, 241, 25, 173, 10, 3, 231, 241, 25, 216, 235, 108, 234, + 105, 10, 3, 231, 241, 25, 216, 102, 10, 3, 231, 241, 25, 212, 132, 10, 3, + 231, 241, 25, 212, 133, 139, 212, 132, 10, 3, 231, 241, 25, 168, 10, 3, + 231, 241, 25, 205, 170, 10, 3, 231, 241, 25, 205, 128, 10, 3, 231, 241, + 25, 203, 114, 10, 3, 231, 241, 25, 203, 115, 108, 197, 64, 10, 3, 231, + 241, 25, 203, 80, 10, 3, 231, 241, 25, 200, 204, 10, 3, 231, 241, 25, + 199, 209, 10, 3, 231, 241, 25, 66, 10, 3, 231, 241, 25, 196, 158, 10, 3, + 231, 241, 25, 196, 159, 108, 235, 91, 10, 3, 231, 241, 139, 231, 240, 10, + 3, 231, 235, 10, 3, 231, 236, 238, 212, 231, 235, 10, 3, 231, 233, 10, 3, + 231, 234, 139, 231, 234, 231, 203, 139, 231, 202, 10, 3, 231, 224, 10, 3, + 231, 225, 231, 234, 139, 231, 234, 231, 203, 139, 231, 202, 10, 3, 231, + 223, 10, 3, 231, 221, 10, 3, 231, 212, 10, 3, 231, 210, 10, 3, 231, 211, + 199, 84, 10, 3, 231, 211, 139, 231, 210, 10, 3, 231, 211, 238, 212, 231, + 210, 10, 3, 231, 202, 10, 3, 231, 201, 10, 3, 231, 195, 10, 3, 231, 136, + 10, 3, 231, 137, 25, 220, 199, 10, 3, 231, 55, 10, 3, 231, 56, 25, 71, + 10, 3, 231, 56, 25, 66, 10, 3, 231, 56, 238, 212, 231, 55, 10, 3, 231, + 53, 10, 3, 231, 54, 139, 231, 53, 10, 3, 231, 54, 238, 212, 231, 53, 10, + 3, 231, 50, 10, 3, 231, 34, 10, 3, 231, 35, 230, 157, 10, 3, 231, 32, 10, + 3, 231, 33, 25, 42, 108, 223, 203, 10, 3, 231, 33, 25, 231, 211, 199, 84, + 10, 3, 231, 33, 25, 223, 203, 10, 3, 231, 33, 25, 218, 228, 108, 223, + 203, 10, 3, 231, 33, 25, 168, 10, 3, 231, 27, 10, 3, 231, 25, 10, 3, 231, + 26, 238, 212, 231, 25, 10, 3, 231, 26, 25, 249, 137, 10, 3, 231, 26, 25, + 199, 209, 10, 3, 231, 26, 199, 84, 10, 3, 230, 181, 10, 3, 230, 182, 238, + 212, 230, 181, 10, 3, 230, 179, 10, 3, 230, 180, 25, 222, 98, 10, 3, 230, + 180, 25, 222, 99, 25, 223, 204, 230, 157, 10, 3, 230, 180, 25, 212, 132, + 10, 3, 230, 180, 25, 205, 171, 108, 197, 82, 10, 3, 230, 180, 230, 157, + 10, 3, 230, 170, 10, 3, 230, 171, 25, 42, 108, 220, 199, 10, 3, 230, 171, + 25, 220, 199, 10, 3, 230, 171, 139, 230, 171, 218, 218, 10, 3, 230, 162, + 10, 3, 230, 160, 10, 3, 230, 161, 25, 203, 114, 10, 3, 230, 151, 10, 3, + 230, 150, 10, 3, 230, 145, 10, 3, 230, 144, 10, 3, 140, 10, 3, 230, 107, + 199, 84, 10, 3, 230, 107, 230, 157, 10, 3, 230, 75, 10, 3, 229, 160, 10, + 3, 229, 161, 25, 250, 211, 10, 3, 229, 161, 25, 250, 209, 10, 3, 229, + 161, 25, 249, 137, 10, 3, 229, 161, 25, 236, 224, 10, 3, 229, 161, 25, + 231, 233, 10, 3, 229, 161, 25, 221, 143, 10, 3, 229, 161, 25, 212, 132, + 10, 3, 229, 161, 25, 203, 114, 10, 3, 229, 161, 25, 66, 10, 3, 228, 161, + 10, 3, 228, 153, 10, 3, 228, 154, 25, 251, 134, 10, 3, 228, 154, 25, 230, + 75, 10, 3, 228, 154, 25, 222, 56, 10, 3, 228, 154, 25, 219, 91, 10, 3, + 228, 154, 25, 196, 158, 10, 3, 228, 148, 10, 3, 68, 10, 3, 228, 76, 65, + 10, 3, 228, 32, 10, 3, 223, 231, 10, 3, 223, 232, 139, 223, 232, 247, + 232, 10, 3, 223, 232, 139, 223, 232, 201, 190, 10, 3, 223, 206, 10, 3, + 223, 203, 10, 3, 223, 204, 237, 28, 10, 3, 223, 204, 207, 2, 10, 3, 223, + 204, 139, 223, 204, 203, 64, 139, 203, 64, 196, 159, 139, 196, 158, 10, + 3, 223, 204, 230, 157, 10, 3, 223, 193, 10, 3, 223, 194, 25, 231, 211, + 199, 84, 10, 3, 223, 192, 10, 3, 223, 182, 10, 3, 223, 183, 25, 199, 209, + 10, 3, 223, 183, 238, 212, 223, 182, 10, 3, 223, 183, 211, 65, 223, 182, + 10, 3, 223, 183, 201, 190, 10, 3, 223, 174, 10, 3, 223, 164, 10, 3, 223, + 79, 10, 3, 223, 64, 10, 3, 155, 10, 3, 222, 144, 25, 65, 10, 3, 222, 144, + 25, 252, 44, 10, 3, 222, 144, 25, 252, 45, 108, 220, 225, 10, 3, 222, + 144, 25, 250, 209, 10, 3, 222, 144, 25, 249, 137, 10, 3, 222, 144, 25, + 249, 116, 10, 3, 222, 144, 25, 164, 10, 3, 222, 144, 25, 248, 190, 10, 3, + 222, 144, 25, 234, 30, 10, 3, 222, 144, 25, 234, 11, 10, 3, 222, 144, 25, + 231, 242, 10, 3, 222, 144, 25, 231, 224, 10, 3, 222, 144, 25, 231, 211, + 199, 84, 10, 3, 222, 144, 25, 231, 202, 10, 3, 222, 144, 25, 231, 203, + 108, 203, 165, 108, 65, 10, 3, 222, 144, 25, 231, 55, 10, 3, 222, 144, + 25, 231, 34, 10, 3, 222, 144, 25, 231, 26, 108, 205, 128, 10, 3, 222, + 144, 25, 231, 26, 238, 212, 231, 25, 10, 3, 222, 144, 25, 230, 181, 10, + 3, 222, 144, 25, 230, 150, 10, 3, 222, 144, 25, 223, 203, 10, 3, 222, + 144, 25, 223, 182, 10, 3, 222, 144, 25, 222, 98, 10, 3, 222, 144, 25, + 221, 168, 10, 3, 222, 144, 25, 221, 154, 10, 3, 222, 144, 25, 219, 148, + 10, 3, 222, 144, 25, 218, 227, 10, 3, 222, 144, 25, 216, 234, 10, 3, 222, + 144, 25, 216, 235, 108, 235, 91, 10, 3, 222, 144, 25, 216, 235, 108, 231, + 55, 10, 3, 222, 144, 25, 216, 235, 108, 199, 145, 10, 3, 222, 144, 25, + 216, 102, 10, 3, 222, 144, 25, 216, 103, 108, 212, 127, 10, 3, 222, 144, + 25, 214, 123, 10, 3, 222, 144, 25, 212, 132, 10, 3, 222, 144, 25, 209, + 187, 10, 3, 222, 144, 25, 206, 69, 10, 3, 222, 144, 25, 188, 10, 3, 222, + 144, 25, 205, 128, 10, 3, 222, 144, 25, 203, 166, 10, 3, 222, 144, 25, + 203, 114, 10, 3, 222, 144, 25, 203, 80, 10, 3, 222, 144, 25, 203, 6, 10, + 3, 222, 144, 25, 202, 202, 10, 3, 222, 144, 25, 200, 213, 10, 3, 222, + 144, 25, 199, 179, 10, 3, 222, 144, 25, 66, 10, 3, 222, 144, 25, 196, + 169, 10, 3, 222, 144, 25, 196, 158, 10, 3, 222, 144, 25, 196, 116, 25, + 168, 10, 3, 222, 144, 25, 196, 38, 10, 3, 222, 144, 25, 191, 30, 10, 3, + 222, 130, 10, 3, 222, 131, 238, 212, 222, 130, 10, 3, 222, 119, 10, 3, + 222, 115, 10, 3, 222, 113, 10, 3, 222, 112, 10, 3, 222, 110, 10, 3, 222, + 111, 139, 222, 110, 10, 3, 222, 98, 10, 3, 222, 99, 25, 223, 204, 230, + 157, 10, 3, 222, 93, 10, 3, 222, 94, 25, 249, 137, 10, 3, 222, 94, 238, + 212, 222, 93, 10, 3, 222, 91, 10, 3, 222, 90, 10, 3, 222, 56, 10, 3, 222, + 57, 220, 107, 25, 126, 139, 220, 107, 25, 66, 10, 3, 222, 57, 139, 222, + 57, 220, 107, 25, 126, 139, 220, 107, 25, 66, 10, 3, 221, 244, 10, 3, + 221, 168, 10, 3, 221, 169, 25, 249, 137, 10, 3, 221, 169, 25, 66, 10, 3, + 221, 169, 25, 196, 158, 10, 3, 221, 154, 10, 3, 221, 143, 10, 3, 221, + 129, 10, 3, 221, 128, 10, 3, 221, 126, 10, 3, 221, 127, 139, 221, 126, + 10, 3, 220, 234, 10, 3, 220, 235, 139, 229, 161, 25, 250, 210, 220, 235, + 139, 229, 161, 25, 250, 209, 10, 3, 220, 225, 10, 3, 220, 223, 10, 3, + 220, 224, 195, 168, 20, 10, 3, 220, 222, 10, 3, 220, 213, 10, 3, 220, + 214, 230, 157, 10, 3, 220, 212, 10, 3, 220, 199, 10, 3, 220, 200, 211, + 65, 220, 199, 10, 3, 220, 192, 10, 3, 220, 169, 10, 3, 173, 10, 3, 220, + 106, 10, 3, 220, 107, 25, 65, 10, 3, 220, 107, 25, 42, 108, 238, 35, 108, + 140, 10, 3, 220, 107, 25, 42, 108, 231, 202, 10, 3, 220, 107, 25, 42, + 108, 220, 39, 10, 3, 220, 107, 25, 251, 209, 10, 3, 220, 107, 25, 251, + 134, 10, 3, 220, 107, 25, 250, 212, 191, 26, 199, 84, 10, 3, 220, 107, + 25, 249, 137, 10, 3, 220, 107, 25, 248, 190, 10, 3, 220, 107, 25, 237, + 227, 10, 3, 220, 107, 25, 234, 105, 10, 3, 220, 107, 25, 231, 242, 10, 3, + 220, 107, 25, 231, 202, 10, 3, 220, 107, 25, 230, 170, 10, 3, 220, 107, + 25, 230, 171, 108, 230, 170, 10, 3, 220, 107, 25, 140, 10, 3, 220, 107, + 25, 230, 75, 10, 3, 220, 107, 25, 229, 161, 25, 212, 132, 10, 3, 220, + 107, 25, 223, 204, 230, 157, 10, 3, 220, 107, 25, 223, 182, 10, 3, 220, + 107, 25, 223, 183, 108, 140, 10, 3, 220, 107, 25, 223, 183, 108, 218, + 227, 10, 3, 220, 107, 25, 221, 168, 10, 3, 220, 107, 25, 221, 143, 10, 3, + 220, 107, 25, 220, 225, 10, 3, 220, 107, 25, 220, 213, 10, 3, 220, 107, + 25, 220, 214, 108, 229, 161, 108, 65, 10, 3, 220, 107, 25, 220, 106, 10, + 3, 220, 107, 25, 219, 91, 10, 3, 220, 107, 25, 218, 227, 10, 3, 220, 107, + 25, 218, 212, 10, 3, 220, 107, 25, 216, 234, 10, 3, 220, 107, 25, 216, + 235, 108, 234, 105, 10, 3, 220, 107, 25, 215, 103, 10, 3, 220, 107, 25, + 214, 123, 10, 3, 220, 107, 25, 203, 115, 108, 200, 204, 10, 3, 220, 107, + 25, 203, 60, 108, 231, 26, 108, 234, 30, 10, 3, 220, 107, 25, 203, 60, + 108, 231, 26, 199, 84, 10, 3, 220, 107, 25, 203, 4, 10, 3, 220, 107, 25, + 203, 5, 108, 203, 4, 10, 3, 220, 107, 25, 200, 204, 10, 3, 220, 107, 25, + 199, 223, 10, 3, 220, 107, 25, 199, 209, 10, 3, 220, 107, 25, 199, 146, + 108, 42, 108, 201, 6, 108, 181, 10, 3, 220, 107, 25, 66, 10, 3, 220, 107, + 25, 126, 108, 65, 10, 3, 220, 107, 25, 126, 108, 126, 108, 66, 10, 3, + 220, 107, 25, 196, 170, 108, 250, 211, 10, 3, 220, 107, 25, 196, 158, 10, + 3, 220, 107, 25, 196, 38, 10, 3, 220, 107, 201, 190, 10, 3, 220, 104, 10, + 3, 220, 105, 25, 203, 114, 10, 3, 220, 105, 25, 203, 115, 108, 200, 204, + 10, 3, 220, 105, 230, 157, 10, 3, 220, 105, 230, 158, 139, 220, 105, 230, + 158, 203, 114, 10, 3, 220, 100, 10, 3, 220, 39, 10, 3, 220, 40, 25, 220, + 39, 10, 3, 220, 37, 10, 3, 220, 38, 25, 220, 199, 10, 3, 220, 38, 25, + 220, 200, 108, 206, 69, 10, 3, 219, 148, 10, 3, 219, 129, 10, 3, 219, + 117, 10, 3, 219, 91, 10, 3, 218, 227, 10, 3, 218, 228, 25, 249, 137, 10, + 3, 218, 225, 10, 3, 218, 226, 25, 251, 209, 10, 3, 218, 226, 25, 249, + 137, 10, 3, 218, 226, 25, 234, 11, 10, 3, 218, 226, 25, 234, 12, 199, 84, + 10, 3, 218, 226, 25, 231, 211, 199, 84, 10, 3, 218, 226, 25, 229, 161, + 25, 249, 137, 10, 3, 218, 226, 25, 223, 182, 10, 3, 218, 226, 25, 222, + 115, 10, 3, 218, 226, 25, 222, 113, 10, 3, 218, 226, 25, 222, 114, 108, + 250, 211, 10, 3, 218, 226, 25, 221, 168, 10, 3, 218, 226, 25, 220, 128, + 108, 250, 211, 10, 3, 218, 226, 25, 220, 106, 10, 3, 218, 226, 25, 216, + 235, 108, 234, 105, 10, 3, 218, 226, 25, 214, 123, 10, 3, 218, 226, 25, + 212, 180, 10, 3, 218, 226, 25, 202, 224, 108, 250, 211, 10, 3, 218, 226, + 25, 202, 193, 108, 248, 12, 10, 3, 218, 226, 25, 197, 82, 10, 3, 218, + 226, 199, 84, 10, 3, 218, 226, 238, 212, 218, 225, 10, 3, 218, 226, 211, + 65, 218, 225, 10, 3, 218, 226, 201, 190, 10, 3, 218, 226, 203, 95, 10, 3, + 218, 224, 10, 3, 218, 218, 10, 3, 218, 219, 139, 218, 218, 10, 3, 218, + 219, 211, 65, 218, 218, 10, 3, 218, 219, 203, 95, 10, 3, 218, 215, 10, 3, + 218, 212, 10, 3, 218, 210, 10, 3, 218, 211, 139, 218, 210, 10, 3, 218, + 211, 139, 218, 211, 231, 203, 139, 231, 202, 10, 3, 174, 10, 3, 217, 162, + 25, 199, 209, 10, 3, 217, 162, 230, 157, 10, 3, 217, 154, 10, 3, 217, + 122, 10, 3, 217, 67, 10, 3, 217, 41, 10, 3, 217, 40, 10, 3, 216, 234, 10, + 3, 216, 175, 10, 3, 216, 102, 10, 3, 216, 46, 10, 3, 215, 157, 10, 3, + 215, 158, 139, 215, 157, 10, 3, 215, 142, 10, 3, 215, 143, 230, 157, 10, + 3, 215, 121, 10, 3, 215, 107, 10, 3, 215, 103, 10, 3, 215, 104, 25, 65, + 10, 3, 215, 104, 25, 220, 199, 10, 3, 215, 104, 25, 191, 123, 10, 3, 215, + 104, 139, 215, 103, 10, 3, 215, 104, 139, 215, 104, 25, 42, 108, 181, 10, + 3, 215, 104, 238, 212, 215, 103, 10, 3, 215, 101, 10, 3, 215, 102, 25, + 65, 10, 3, 215, 102, 25, 42, 108, 237, 46, 10, 3, 215, 102, 25, 237, 46, + 10, 3, 215, 102, 230, 157, 10, 3, 181, 10, 3, 214, 255, 10, 3, 214, 242, + 10, 3, 214, 243, 223, 94, 10, 3, 214, 243, 25, 203, 7, 199, 84, 10, 3, + 214, 243, 211, 65, 214, 242, 10, 3, 214, 241, 10, 3, 214, 233, 212, 118, + 10, 3, 214, 232, 10, 3, 214, 231, 10, 3, 214, 123, 10, 3, 214, 124, 25, + 65, 10, 3, 214, 124, 25, 196, 158, 10, 3, 214, 124, 203, 95, 10, 3, 213, + 221, 10, 3, 213, 222, 25, 71, 10, 3, 213, 212, 10, 3, 213, 182, 10, 3, + 213, 183, 25, 231, 211, 199, 84, 10, 3, 213, 183, 25, 231, 203, 108, 231, + 211, 199, 84, 10, 3, 213, 178, 10, 3, 213, 179, 25, 251, 134, 10, 3, 213, + 179, 25, 250, 211, 10, 3, 213, 179, 25, 250, 212, 108, 250, 211, 10, 3, + 213, 179, 25, 230, 170, 10, 3, 213, 179, 25, 216, 235, 108, 231, 211, + 199, 84, 10, 3, 213, 179, 25, 214, 123, 10, 3, 213, 179, 25, 212, 132, + 10, 3, 213, 179, 25, 203, 114, 10, 3, 213, 179, 25, 203, 115, 108, 42, + 251, 134, 10, 3, 213, 179, 25, 203, 115, 108, 250, 211, 10, 3, 213, 179, + 25, 203, 115, 108, 250, 212, 108, 250, 211, 10, 3, 213, 179, 25, 196, + 170, 108, 250, 211, 10, 3, 213, 179, 25, 196, 38, 10, 3, 213, 165, 10, 3, + 212, 180, 10, 3, 212, 149, 10, 3, 212, 132, 10, 3, 212, 133, 220, 105, + 25, 231, 202, 10, 3, 212, 133, 220, 105, 25, 217, 41, 10, 3, 212, 133, + 220, 105, 25, 205, 170, 10, 3, 212, 133, 220, 105, 25, 205, 171, 139, + 212, 133, 220, 105, 25, 205, 170, 10, 3, 212, 133, 220, 105, 25, 196, 38, + 10, 3, 212, 133, 199, 84, 10, 3, 212, 133, 139, 212, 132, 10, 3, 212, + 133, 238, 212, 212, 132, 10, 3, 212, 133, 238, 212, 212, 133, 220, 105, + 139, 220, 104, 10, 3, 212, 127, 10, 3, 212, 128, 252, 75, 25, 250, 205, + 10, 3, 212, 128, 252, 75, 25, 248, 190, 10, 3, 212, 128, 252, 75, 25, + 235, 84, 10, 3, 212, 128, 252, 75, 25, 230, 170, 10, 3, 212, 128, 252, + 75, 25, 223, 204, 230, 157, 10, 3, 212, 128, 252, 75, 25, 222, 113, 10, + 3, 212, 128, 252, 75, 25, 173, 10, 3, 212, 128, 252, 75, 25, 214, 123, + 10, 3, 212, 128, 252, 75, 25, 202, 190, 10, 3, 212, 128, 252, 75, 25, + 196, 169, 10, 3, 212, 128, 221, 127, 25, 248, 190, 10, 3, 212, 128, 221, + 127, 25, 248, 191, 66, 10, 3, 168, 10, 3, 210, 212, 10, 3, 210, 168, 10, + 3, 210, 139, 10, 3, 209, 245, 10, 3, 209, 187, 10, 3, 209, 188, 25, 65, + 10, 3, 209, 188, 25, 252, 157, 10, 3, 209, 188, 25, 248, 190, 10, 3, 209, + 188, 25, 248, 12, 10, 3, 209, 188, 25, 71, 10, 3, 209, 188, 25, 68, 10, + 3, 209, 188, 25, 228, 32, 10, 3, 209, 188, 25, 66, 10, 3, 209, 188, 25, + 196, 169, 10, 3, 209, 188, 238, 212, 209, 187, 10, 3, 209, 123, 10, 3, + 209, 124, 25, 222, 93, 10, 3, 209, 124, 25, 196, 158, 10, 3, 209, 124, + 25, 191, 123, 10, 3, 209, 124, 211, 65, 209, 123, 10, 3, 165, 10, 3, 207, + 178, 10, 3, 207, 2, 10, 3, 206, 69, 10, 3, 188, 10, 3, 205, 187, 212, + 118, 10, 3, 205, 186, 10, 3, 205, 187, 25, 65, 10, 3, 205, 187, 25, 235, + 91, 10, 3, 205, 187, 25, 235, 89, 10, 3, 205, 187, 25, 140, 10, 3, 205, + 187, 25, 222, 98, 10, 3, 205, 187, 25, 220, 199, 10, 3, 205, 187, 25, + 218, 210, 10, 3, 205, 187, 25, 216, 102, 10, 3, 205, 187, 25, 212, 132, + 10, 3, 205, 187, 25, 205, 170, 10, 3, 205, 187, 25, 203, 80, 10, 3, 205, + 187, 25, 199, 236, 10, 3, 205, 187, 25, 196, 169, 10, 3, 205, 187, 25, + 196, 164, 10, 3, 205, 187, 25, 196, 120, 10, 3, 205, 187, 25, 196, 62, + 10, 3, 205, 187, 25, 196, 38, 10, 3, 205, 187, 139, 205, 186, 10, 3, 205, + 187, 230, 157, 10, 3, 205, 170, 10, 3, 205, 171, 220, 107, 25, 250, 209, + 10, 3, 205, 137, 10, 3, 205, 128, 10, 3, 203, 166, 10, 3, 203, 164, 10, + 3, 203, 165, 25, 65, 10, 3, 203, 165, 25, 249, 137, 10, 3, 203, 165, 25, + 231, 25, 10, 3, 203, 165, 25, 214, 123, 10, 3, 203, 165, 25, 203, 4, 10, + 3, 203, 165, 25, 197, 64, 10, 3, 203, 165, 25, 66, 10, 3, 203, 165, 25, + 126, 108, 65, 10, 3, 203, 162, 10, 3, 203, 160, 10, 3, 203, 132, 10, 3, + 203, 114, 10, 3, 203, 115, 228, 161, 10, 3, 203, 115, 139, 203, 115, 231, + 234, 139, 231, 234, 231, 203, 139, 231, 202, 10, 3, 203, 115, 139, 203, + 115, 199, 237, 139, 199, 237, 231, 203, 139, 231, 202, 10, 3, 203, 107, + 10, 3, 203, 102, 10, 3, 203, 98, 10, 3, 203, 97, 10, 3, 203, 94, 10, 3, + 203, 80, 10, 3, 203, 81, 25, 65, 10, 3, 203, 81, 25, 223, 182, 10, 3, + 203, 74, 10, 3, 203, 75, 25, 65, 10, 3, 203, 75, 25, 249, 117, 10, 3, + 203, 75, 25, 247, 244, 10, 3, 203, 75, 25, 236, 245, 10, 3, 203, 75, 25, + 231, 202, 10, 3, 203, 75, 25, 223, 203, 10, 3, 203, 75, 25, 223, 204, + 230, 157, 10, 3, 203, 75, 25, 220, 192, 10, 3, 203, 75, 25, 218, 212, 10, + 3, 203, 75, 25, 215, 142, 10, 3, 203, 75, 25, 205, 170, 10, 3, 203, 68, + 10, 3, 203, 63, 10, 3, 203, 64, 199, 84, 10, 3, 203, 64, 139, 203, 64, + 247, 233, 139, 247, 232, 10, 3, 203, 59, 10, 3, 203, 6, 10, 3, 203, 7, + 139, 223, 95, 203, 6, 10, 3, 203, 4, 10, 3, 203, 2, 10, 3, 202, 223, 10, + 3, 202, 224, 230, 157, 10, 3, 202, 202, 10, 3, 202, 200, 10, 3, 202, 201, + 139, 202, 201, 203, 4, 10, 3, 202, 192, 10, 3, 202, 190, 10, 3, 201, 5, + 10, 3, 201, 6, 139, 201, 5, 10, 3, 200, 216, 10, 3, 200, 215, 10, 3, 200, + 213, 10, 3, 200, 204, 10, 3, 200, 203, 10, 3, 200, 175, 10, 3, 200, 174, + 10, 3, 190, 190, 10, 3, 199, 252, 250, 195, 10, 3, 199, 252, 25, 229, + 160, 10, 3, 199, 252, 25, 216, 102, 10, 3, 199, 252, 230, 157, 10, 3, + 199, 236, 10, 3, 199, 237, 139, 199, 237, 213, 222, 139, 213, 222, 236, + 225, 139, 236, 224, 10, 3, 199, 237, 201, 190, 10, 3, 199, 223, 10, 3, + 199, 224, 25, 248, 190, 10, 3, 199, 224, 25, 230, 170, 10, 3, 199, 224, + 25, 203, 114, 10, 3, 199, 224, 25, 203, 6, 10, 3, 199, 224, 25, 197, 82, + 10, 3, 199, 224, 25, 196, 158, 10, 3, 199, 209, 10, 3, 199, 179, 10, 3, + 199, 145, 10, 3, 199, 146, 230, 157, 10, 3, 198, 193, 10, 3, 198, 194, + 199, 84, 10, 3, 198, 154, 10, 3, 198, 131, 10, 3, 198, 132, 25, 199, 209, + 10, 3, 198, 132, 139, 198, 131, 10, 3, 198, 132, 139, 198, 132, 231, 234, + 139, 231, 234, 231, 203, 139, 231, 202, 10, 3, 197, 94, 10, 3, 197, 82, + 10, 3, 197, 80, 10, 3, 197, 76, 10, 3, 197, 64, 10, 3, 197, 65, 139, 197, + 65, 191, 124, 139, 191, 123, 10, 3, 66, 10, 3, 126, 230, 170, 10, 3, 126, + 126, 66, 10, 3, 126, 139, 126, 210, 223, 139, 210, 223, 231, 203, 139, + 231, 202, 10, 3, 126, 139, 126, 200, 176, 139, 200, 175, 10, 3, 126, 139, + 126, 126, 207, 19, 139, 126, 207, 18, 10, 3, 196, 169, 10, 3, 196, 164, + 10, 3, 196, 158, 10, 3, 196, 159, 220, 192, 10, 3, 196, 159, 25, 249, + 137, 10, 3, 196, 159, 25, 216, 102, 10, 3, 196, 159, 25, 126, 108, 126, + 108, 66, 10, 3, 196, 159, 25, 126, 108, 126, 108, 126, 230, 157, 10, 3, + 196, 159, 230, 157, 10, 3, 196, 159, 203, 95, 10, 3, 196, 159, 203, 96, + 25, 249, 137, 10, 3, 196, 153, 10, 3, 196, 120, 10, 3, 196, 121, 25, 220, + 106, 10, 3, 196, 121, 25, 216, 235, 108, 238, 34, 10, 3, 196, 121, 25, + 203, 164, 10, 3, 196, 121, 25, 66, 10, 3, 196, 119, 10, 3, 196, 115, 10, + 3, 196, 116, 25, 222, 56, 10, 3, 196, 116, 25, 168, 10, 3, 196, 113, 10, + 3, 196, 114, 230, 157, 10, 3, 196, 62, 10, 3, 196, 63, 238, 212, 196, 62, + 10, 3, 196, 63, 203, 95, 10, 3, 196, 60, 10, 3, 196, 61, 25, 42, 108, + 140, 10, 3, 196, 61, 25, 42, 108, 181, 10, 3, 196, 61, 25, 251, 209, 10, + 3, 196, 61, 25, 140, 10, 3, 196, 61, 25, 212, 132, 10, 3, 196, 61, 25, + 196, 169, 10, 3, 196, 61, 25, 196, 170, 108, 250, 211, 10, 3, 196, 61, + 25, 196, 170, 108, 248, 190, 10, 3, 196, 59, 10, 3, 196, 56, 10, 3, 196, + 55, 10, 3, 196, 51, 10, 3, 196, 52, 25, 65, 10, 3, 196, 52, 25, 250, 205, + 10, 3, 196, 52, 25, 164, 10, 3, 196, 52, 25, 235, 77, 10, 3, 196, 52, 25, + 231, 242, 10, 3, 196, 52, 25, 231, 224, 10, 3, 196, 52, 25, 231, 211, + 199, 84, 10, 3, 196, 52, 25, 231, 202, 10, 3, 196, 52, 25, 230, 181, 10, + 3, 196, 52, 25, 140, 10, 3, 196, 52, 25, 223, 203, 10, 3, 196, 52, 25, + 223, 182, 10, 3, 196, 52, 25, 223, 64, 10, 3, 196, 52, 25, 221, 168, 10, + 3, 196, 52, 25, 218, 210, 10, 3, 196, 52, 25, 216, 46, 10, 3, 196, 52, + 25, 168, 10, 3, 196, 52, 25, 203, 114, 10, 3, 196, 52, 25, 202, 200, 10, + 3, 196, 52, 25, 197, 94, 10, 3, 196, 52, 25, 126, 108, 230, 170, 10, 3, + 196, 52, 25, 196, 158, 10, 3, 196, 52, 25, 196, 49, 10, 3, 196, 49, 10, + 3, 196, 50, 25, 66, 10, 3, 196, 38, 10, 3, 196, 39, 25, 65, 10, 3, 196, + 39, 25, 220, 234, 10, 3, 196, 39, 25, 220, 199, 10, 3, 196, 39, 25, 199, + 209, 10, 3, 196, 34, 10, 3, 196, 37, 10, 3, 196, 35, 10, 3, 196, 31, 10, + 3, 196, 16, 10, 3, 196, 17, 25, 222, 56, 10, 3, 196, 14, 10, 3, 191, 123, + 10, 3, 191, 124, 199, 84, 10, 3, 191, 124, 112, 25, 220, 199, 10, 3, 191, + 118, 10, 3, 191, 107, 10, 3, 191, 86, 10, 3, 191, 30, 10, 3, 191, 31, + 139, 191, 30, 10, 3, 191, 29, 10, 3, 191, 27, 10, 3, 191, 28, 222, 118, + 199, 84, 10, 3, 191, 22, 10, 3, 191, 13, 10, 3, 190, 251, 10, 3, 190, + 249, 10, 3, 190, 250, 25, 65, 10, 3, 190, 248, 10, 3, 190, 247, 10, 3, + 222, 81, 234, 139, 10, 3, 252, 158, 25, 212, 132, 10, 3, 252, 75, 25, 65, + 10, 3, 251, 148, 25, 220, 215, 10, 3, 238, 25, 221, 127, 25, 196, 170, + 108, 217, 41, 10, 3, 238, 23, 10, 3, 236, 225, 108, 203, 6, 10, 3, 235, + 90, 25, 203, 114, 10, 3, 233, 183, 25, 230, 170, 10, 3, 233, 183, 25, + 203, 114, 10, 3, 231, 241, 25, 251, 135, 108, 222, 99, 108, 65, 10, 3, + 231, 241, 25, 250, 209, 10, 3, 231, 166, 10, 3, 231, 44, 10, 3, 228, 133, + 10, 3, 222, 144, 25, 251, 93, 10, 3, 222, 144, 25, 250, 208, 10, 3, 222, + 144, 25, 231, 25, 10, 3, 222, 144, 25, 230, 170, 10, 3, 222, 144, 25, + 229, 161, 25, 250, 209, 10, 3, 222, 144, 25, 218, 210, 10, 3, 222, 144, + 25, 168, 10, 3, 222, 144, 25, 202, 254, 10, 3, 222, 144, 25, 197, 94, 10, + 3, 222, 144, 25, 196, 60, 10, 3, 220, 107, 25, 231, 55, 10, 3, 218, 226, + 203, 96, 25, 249, 137, 10, 3, 218, 226, 25, 234, 12, 108, 220, 39, 10, 3, + 218, 226, 25, 203, 6, 10, 3, 216, 174, 10, 3, 215, 102, 25, 191, 123, 10, + 3, 214, 254, 10, 3, 213, 181, 10, 3, 213, 180, 10, 3, 213, 179, 25, 249, + 117, 10, 3, 213, 179, 25, 231, 55, 10, 3, 212, 150, 206, 123, 213, 172, + 237, 126, 10, 3, 209, 246, 250, 195, 10, 3, 209, 127, 10, 3, 205, 187, + 25, 223, 204, 230, 157, 10, 3, 198, 185, 10, 3, 196, 121, 25, 216, 234, + 10, 3, 126, 66, 10, 167, 3, 105, 250, 211, 10, 167, 3, 115, 250, 211, 10, + 167, 3, 232, 130, 250, 211, 10, 167, 3, 232, 228, 250, 211, 10, 167, 3, + 202, 137, 250, 211, 10, 167, 3, 203, 248, 250, 211, 10, 167, 3, 234, 166, + 250, 211, 10, 167, 3, 213, 177, 250, 211, 10, 167, 3, 115, 236, 224, 10, + 167, 3, 232, 130, 236, 224, 10, 167, 3, 232, 228, 236, 224, 10, 167, 3, + 202, 137, 236, 224, 10, 167, 3, 203, 248, 236, 224, 10, 167, 3, 234, 166, + 236, 224, 10, 167, 3, 213, 177, 236, 224, 10, 167, 3, 232, 130, 66, 10, + 167, 3, 232, 228, 66, 10, 167, 3, 202, 137, 66, 10, 167, 3, 203, 248, 66, + 10, 167, 3, 234, 166, 66, 10, 167, 3, 213, 177, 66, 10, 167, 3, 91, 231, + 138, 10, 167, 3, 105, 231, 138, 10, 167, 3, 115, 231, 138, 10, 167, 3, + 232, 130, 231, 138, 10, 167, 3, 232, 228, 231, 138, 10, 167, 3, 202, 137, + 231, 138, 10, 167, 3, 203, 248, 231, 138, 10, 167, 3, 234, 166, 231, 138, + 10, 167, 3, 213, 177, 231, 138, 10, 167, 3, 91, 231, 135, 10, 167, 3, + 105, 231, 135, 10, 167, 3, 115, 231, 135, 10, 167, 3, 232, 130, 231, 135, + 10, 167, 3, 232, 228, 231, 135, 10, 167, 3, 105, 203, 132, 10, 167, 3, + 115, 203, 132, 10, 167, 3, 115, 203, 133, 195, 168, 20, 10, 167, 3, 232, + 130, 203, 132, 10, 167, 3, 232, 228, 203, 132, 10, 167, 3, 202, 137, 203, + 132, 10, 167, 3, 203, 248, 203, 132, 10, 167, 3, 234, 166, 203, 132, 10, + 167, 3, 213, 177, 203, 132, 10, 167, 3, 91, 203, 125, 10, 167, 3, 105, + 203, 125, 10, 167, 3, 115, 203, 125, 10, 167, 3, 115, 203, 126, 195, 168, + 20, 10, 167, 3, 232, 130, 203, 125, 10, 167, 3, 232, 228, 203, 125, 10, + 167, 3, 203, 133, 25, 231, 225, 108, 236, 224, 10, 167, 3, 203, 133, 25, + 231, 225, 108, 216, 46, 10, 167, 3, 91, 247, 228, 10, 167, 3, 105, 247, + 228, 10, 167, 3, 115, 247, 228, 10, 167, 3, 115, 247, 229, 195, 168, 20, + 10, 167, 3, 232, 130, 247, 228, 10, 167, 3, 232, 228, 247, 228, 10, 167, + 3, 115, 195, 168, 232, 148, 234, 13, 10, 167, 3, 115, 195, 168, 232, 148, + 234, 10, 10, 167, 3, 232, 130, 195, 168, 232, 148, 219, 118, 10, 167, 3, + 232, 130, 195, 168, 232, 148, 219, 116, 10, 167, 3, 232, 130, 195, 168, + 232, 148, 219, 119, 65, 10, 167, 3, 232, 130, 195, 168, 232, 148, 219, + 119, 250, 122, 10, 167, 3, 202, 137, 195, 168, 232, 148, 250, 207, 10, + 167, 3, 203, 248, 195, 168, 232, 148, 223, 173, 10, 167, 3, 203, 248, + 195, 168, 232, 148, 223, 175, 65, 10, 167, 3, 203, 248, 195, 168, 232, + 148, 223, 175, 250, 122, 10, 167, 3, 234, 166, 195, 168, 232, 148, 196, + 33, 10, 167, 3, 234, 166, 195, 168, 232, 148, 196, 32, 10, 167, 3, 213, + 177, 195, 168, 232, 148, 223, 190, 10, 167, 3, 213, 177, 195, 168, 232, + 148, 223, 189, 10, 167, 3, 213, 177, 195, 168, 232, 148, 223, 188, 10, + 167, 3, 213, 177, 195, 168, 232, 148, 223, 191, 65, 10, 167, 3, 105, 250, + 212, 199, 84, 10, 167, 3, 115, 250, 212, 199, 84, 10, 167, 3, 232, 130, + 250, 212, 199, 84, 10, 167, 3, 232, 228, 250, 212, 199, 84, 10, 167, 3, + 202, 137, 250, 212, 199, 84, 10, 167, 3, 91, 249, 101, 10, 167, 3, 105, + 249, 101, 10, 167, 3, 115, 249, 101, 10, 167, 3, 232, 130, 249, 101, 10, + 167, 3, 232, 130, 249, 102, 195, 168, 20, 10, 167, 3, 232, 228, 249, 101, + 10, 167, 3, 232, 228, 249, 102, 195, 168, 20, 10, 167, 3, 213, 190, 10, + 167, 3, 213, 191, 10, 167, 3, 91, 234, 9, 10, 167, 3, 105, 234, 9, 10, + 167, 3, 91, 199, 1, 236, 224, 10, 167, 3, 105, 198, 254, 236, 224, 10, + 167, 3, 232, 228, 202, 124, 236, 224, 10, 167, 3, 91, 199, 1, 195, 168, + 232, 148, 65, 10, 167, 3, 105, 198, 254, 195, 168, 232, 148, 65, 10, 167, + 3, 91, 234, 162, 250, 211, 10, 167, 3, 91, 208, 25, 250, 211, 10, 167, 3, + 39, 250, 198, 91, 202, 125, 10, 167, 3, 39, 250, 198, 91, 208, 24, 10, + 167, 3, 91, 208, 25, 230, 151, 10, 167, 3, 91, 132, 230, 151, 10, 167, 3, + 234, 140, 91, 199, 0, 10, 167, 3, 234, 140, 105, 198, 253, 10, 167, 3, + 234, 140, 232, 137, 10, 167, 3, 234, 140, 233, 17, 10, 167, 3, 232, 130, + 126, 195, 168, 20, 10, 167, 3, 232, 228, 126, 195, 168, 20, 10, 167, 3, + 202, 137, 126, 195, 168, 20, 10, 167, 3, 203, 248, 126, 195, 168, 20, 10, + 167, 3, 234, 166, 126, 195, 168, 20, 10, 167, 3, 213, 177, 126, 195, 168, + 20, 10, 208, 154, 3, 39, 250, 198, 193, 23, 236, 207, 10, 208, 154, 3, + 81, 242, 85, 10, 208, 154, 3, 237, 41, 242, 85, 10, 208, 154, 3, 237, 41, + 197, 237, 10, 208, 154, 3, 237, 41, 208, 31, 10, 3, 252, 158, 25, 212, + 133, 199, 84, 10, 3, 252, 158, 25, 203, 4, 10, 3, 252, 45, 25, 234, 11, + 10, 3, 249, 138, 25, 236, 225, 199, 84, 10, 3, 249, 124, 25, 252, 74, 10, + 3, 249, 124, 25, 213, 221, 10, 3, 249, 124, 25, 191, 123, 10, 3, 248, 13, + 139, 248, 13, 25, 214, 255, 10, 3, 238, 35, 25, 199, 209, 10, 3, 238, 25, + 25, 220, 199, 10, 3, 237, 2, 25, 223, 203, 10, 3, 237, 2, 25, 126, 126, + 66, 10, 3, 237, 0, 25, 196, 158, 10, 3, 235, 85, 25, 251, 93, 10, 3, 235, + 85, 25, 250, 211, 10, 3, 235, 85, 25, 250, 212, 250, 185, 219, 226, 10, + 3, 235, 85, 25, 236, 245, 10, 3, 235, 85, 25, 235, 77, 10, 3, 235, 85, + 25, 234, 30, 10, 3, 235, 85, 25, 231, 242, 10, 3, 235, 85, 25, 231, 55, + 10, 3, 235, 85, 25, 231, 35, 230, 157, 10, 3, 235, 85, 25, 231, 25, 10, + 3, 235, 85, 25, 140, 10, 3, 235, 85, 25, 229, 160, 10, 3, 235, 85, 25, + 223, 204, 230, 157, 10, 3, 235, 85, 25, 222, 56, 10, 3, 235, 85, 25, 220, + 199, 10, 3, 235, 85, 25, 220, 192, 10, 3, 235, 85, 25, 220, 193, 108, + 222, 56, 10, 3, 235, 85, 25, 220, 94, 10, 3, 235, 85, 25, 220, 37, 10, 3, + 235, 85, 25, 220, 38, 25, 220, 199, 10, 3, 235, 85, 25, 218, 216, 108, + 231, 25, 10, 3, 235, 85, 25, 217, 41, 10, 3, 235, 85, 25, 216, 175, 10, + 3, 235, 85, 25, 216, 102, 10, 3, 235, 85, 25, 213, 221, 10, 3, 235, 85, + 25, 209, 187, 10, 3, 235, 85, 25, 203, 114, 10, 3, 235, 85, 25, 202, 224, + 230, 157, 10, 3, 234, 221, 25, 220, 199, 10, 3, 234, 221, 25, 210, 139, + 10, 3, 234, 31, 192, 235, 10, 3, 234, 12, 238, 212, 234, 11, 10, 3, 233, + 183, 203, 96, 25, 250, 211, 10, 3, 233, 183, 203, 96, 25, 229, 160, 10, + 3, 233, 183, 203, 96, 25, 223, 204, 230, 157, 10, 3, 233, 183, 203, 96, + 25, 173, 10, 3, 233, 183, 203, 96, 25, 220, 39, 10, 3, 233, 183, 203, 96, + 25, 216, 234, 10, 3, 233, 183, 203, 96, 25, 216, 175, 10, 3, 233, 183, + 203, 96, 25, 201, 5, 10, 3, 233, 183, 25, 201, 5, 10, 3, 231, 241, 25, + 249, 123, 10, 3, 231, 241, 25, 237, 2, 230, 157, 10, 3, 231, 241, 25, + 235, 85, 25, 223, 204, 230, 157, 10, 3, 231, 241, 25, 235, 85, 25, 222, + 56, 10, 3, 231, 241, 25, 234, 33, 10, 3, 231, 241, 25, 231, 242, 10, 3, + 231, 241, 25, 231, 203, 108, 237, 46, 10, 3, 231, 241, 25, 231, 203, 108, + 214, 123, 10, 3, 231, 241, 25, 230, 107, 108, 65, 10, 3, 231, 241, 25, + 220, 193, 108, 222, 56, 10, 3, 231, 241, 25, 220, 37, 10, 3, 231, 241, + 25, 220, 38, 25, 220, 199, 10, 3, 231, 241, 25, 218, 215, 10, 3, 231, + 241, 25, 215, 103, 10, 3, 231, 241, 25, 214, 123, 10, 3, 231, 241, 25, + 214, 124, 108, 234, 220, 10, 3, 231, 241, 25, 214, 124, 108, 231, 55, 10, + 3, 231, 241, 25, 203, 74, 10, 3, 231, 241, 25, 191, 13, 10, 3, 231, 236, + 206, 123, 213, 172, 237, 126, 10, 3, 231, 137, 25, 66, 10, 3, 231, 26, + 25, 231, 26, 238, 212, 231, 25, 10, 3, 230, 180, 25, 223, 204, 230, 157, + 10, 3, 230, 171, 108, 231, 26, 25, 199, 209, 10, 3, 230, 107, 199, 85, + 230, 157, 10, 3, 229, 161, 25, 250, 212, 139, 229, 161, 25, 250, 211, 10, + 3, 222, 144, 25, 248, 12, 10, 3, 222, 144, 25, 155, 10, 3, 222, 144, 25, + 126, 126, 66, 10, 3, 222, 144, 25, 196, 62, 10, 3, 220, 107, 25, 190, + 252, 139, 190, 251, 10, 3, 220, 95, 10, 3, 220, 93, 10, 3, 220, 92, 10, + 3, 220, 91, 10, 3, 220, 90, 10, 3, 220, 89, 10, 3, 220, 88, 10, 3, 220, + 87, 139, 220, 87, 230, 157, 10, 3, 220, 86, 10, 3, 220, 85, 139, 220, 84, + 10, 3, 220, 83, 10, 3, 220, 82, 10, 3, 220, 81, 10, 3, 220, 80, 10, 3, + 220, 79, 10, 3, 220, 78, 10, 3, 220, 77, 10, 3, 220, 76, 10, 3, 220, 75, + 10, 3, 220, 74, 10, 3, 220, 73, 10, 3, 220, 72, 10, 3, 220, 71, 10, 3, + 220, 70, 10, 3, 220, 69, 10, 3, 220, 68, 10, 3, 220, 67, 10, 3, 220, 66, + 10, 3, 220, 64, 10, 3, 220, 65, 25, 230, 181, 10, 3, 220, 65, 25, 223, + 203, 10, 3, 220, 65, 25, 210, 140, 108, 218, 224, 10, 3, 220, 65, 25, + 210, 140, 108, 210, 140, 108, 218, 224, 10, 3, 220, 65, 25, 196, 170, + 108, 249, 155, 10, 3, 220, 63, 10, 3, 220, 62, 10, 3, 220, 61, 10, 3, + 220, 60, 10, 3, 220, 59, 10, 3, 220, 58, 10, 3, 220, 57, 10, 3, 220, 56, + 10, 3, 220, 55, 10, 3, 220, 54, 10, 3, 220, 52, 10, 3, 220, 53, 25, 250, + 211, 10, 3, 220, 53, 25, 249, 137, 10, 3, 220, 53, 25, 235, 76, 230, 158, + 230, 157, 10, 3, 220, 53, 25, 220, 225, 10, 3, 220, 53, 25, 173, 10, 3, + 220, 53, 25, 199, 179, 10, 3, 220, 53, 25, 199, 145, 10, 3, 220, 53, 25, + 196, 169, 10, 3, 220, 53, 25, 196, 158, 10, 3, 220, 53, 25, 196, 49, 10, + 3, 220, 51, 10, 3, 220, 49, 10, 3, 220, 50, 25, 235, 89, 10, 3, 220, 50, + 25, 231, 242, 10, 3, 220, 50, 25, 223, 203, 10, 3, 220, 50, 25, 223, 204, + 230, 157, 10, 3, 220, 50, 25, 213, 221, 10, 3, 220, 50, 25, 210, 140, + 108, 210, 140, 108, 218, 224, 10, 3, 220, 50, 25, 203, 99, 108, 221, 168, + 10, 3, 220, 50, 25, 196, 158, 10, 3, 220, 50, 25, 196, 49, 10, 3, 220, + 47, 10, 3, 220, 46, 10, 3, 218, 226, 230, 158, 25, 250, 211, 10, 3, 218, + 226, 25, 236, 224, 10, 3, 218, 226, 25, 230, 75, 10, 3, 218, 226, 25, + 210, 139, 10, 3, 218, 226, 25, 210, 140, 108, 210, 140, 108, 218, 224, + 10, 3, 218, 226, 25, 199, 209, 10, 3, 216, 103, 108, 191, 122, 10, 3, + 215, 104, 139, 215, 104, 25, 231, 242, 10, 3, 215, 104, 139, 215, 104, + 25, 222, 98, 10, 3, 213, 179, 25, 237, 2, 230, 157, 10, 3, 213, 179, 25, + 231, 25, 10, 3, 213, 179, 25, 230, 162, 10, 3, 213, 179, 25, 229, 160, + 10, 3, 213, 179, 25, 221, 244, 10, 3, 213, 179, 25, 220, 90, 10, 3, 213, + 179, 25, 217, 41, 10, 3, 213, 179, 25, 210, 140, 108, 210, 139, 10, 3, + 213, 179, 25, 66, 10, 3, 213, 179, 25, 126, 108, 66, 10, 3, 213, 179, 25, + 196, 49, 10, 3, 205, 187, 230, 158, 25, 140, 10, 3, 205, 187, 25, 234, + 105, 10, 3, 205, 187, 25, 203, 115, 250, 185, 219, 226, 10, 3, 205, 187, + 25, 199, 209, 10, 3, 203, 163, 199, 84, 10, 3, 203, 115, 139, 203, 114, + 10, 3, 203, 115, 108, 228, 153, 10, 3, 203, 115, 108, 214, 231, 10, 3, + 203, 115, 108, 205, 128, 10, 3, 203, 5, 108, 235, 85, 25, 213, 221, 10, + 3, 203, 5, 108, 234, 221, 25, 251, 134, 10, 3, 202, 224, 25, 199, 209, + 10, 3, 199, 210, 108, 205, 186, 10, 3, 197, 77, 25, 231, 211, 199, 84, + 10, 3, 197, 77, 25, 115, 236, 224, 10, 3, 196, 61, 223, 94, 10, 3, 196, + 61, 25, 196, 158, 10, 3, 196, 52, 25, 237, 226, 10, 3, 196, 52, 25, 220, + 48, 10, 3, 196, 52, 25, 218, 224, 10, 3, 191, 122, 10, 3, 190, 252, 139, + 190, 252, 108, 205, 128, 10, 3, 190, 250, 25, 115, 236, 225, 199, 84, + 238, 136, 3, 242, 200, 238, 136, 3, 242, 199, 238, 136, 3, 242, 198, 238, + 136, 3, 242, 197, 238, 136, 3, 242, 196, 238, 136, 3, 242, 195, 238, 136, + 3, 242, 194, 238, 136, 3, 242, 193, 238, 136, 3, 242, 192, 238, 136, 3, + 242, 191, 238, 136, 3, 242, 190, 238, 136, 3, 242, 189, 238, 136, 3, 242, + 188, 238, 136, 3, 242, 187, 238, 136, 3, 242, 186, 238, 136, 3, 242, 185, + 238, 136, 3, 242, 184, 238, 136, 3, 242, 183, 238, 136, 3, 242, 182, 238, + 136, 3, 242, 181, 238, 136, 3, 242, 180, 238, 136, 3, 242, 179, 238, 136, + 3, 242, 178, 238, 136, 3, 242, 177, 238, 136, 3, 242, 176, 238, 136, 3, + 242, 175, 238, 136, 3, 242, 174, 238, 136, 3, 242, 173, 238, 136, 3, 242, + 172, 238, 136, 3, 242, 171, 238, 136, 3, 242, 170, 238, 136, 3, 242, 169, + 238, 136, 3, 242, 168, 238, 136, 3, 242, 167, 238, 136, 3, 242, 166, 238, + 136, 3, 242, 165, 238, 136, 3, 242, 164, 238, 136, 3, 242, 163, 238, 136, + 3, 242, 162, 238, 136, 3, 242, 161, 238, 136, 3, 242, 160, 238, 136, 3, + 242, 159, 238, 136, 3, 242, 158, 238, 136, 3, 242, 157, 238, 136, 3, 242, + 156, 238, 136, 3, 242, 155, 238, 136, 3, 242, 154, 238, 136, 3, 242, 153, + 238, 136, 3, 242, 152, 238, 136, 3, 242, 151, 238, 136, 3, 242, 150, 238, + 136, 3, 242, 149, 238, 136, 3, 242, 148, 238, 136, 3, 242, 147, 238, 136, + 3, 242, 146, 238, 136, 3, 242, 145, 238, 136, 3, 242, 144, 238, 136, 3, + 242, 143, 238, 136, 3, 242, 142, 238, 136, 3, 242, 141, 238, 136, 3, 242, + 140, 238, 136, 3, 242, 139, 238, 136, 3, 242, 138, 238, 136, 3, 242, 137, + 238, 136, 3, 242, 136, 238, 136, 3, 242, 135, 238, 136, 3, 242, 134, 238, + 136, 3, 242, 133, 238, 136, 3, 242, 132, 238, 136, 3, 242, 131, 238, 136, + 3, 242, 130, 238, 136, 3, 242, 129, 238, 136, 3, 242, 128, 238, 136, 3, + 242, 127, 238, 136, 3, 242, 126, 238, 136, 3, 242, 125, 238, 136, 3, 242, + 124, 238, 136, 3, 242, 123, 238, 136, 3, 242, 122, 238, 136, 3, 242, 121, + 238, 136, 3, 242, 120, 238, 136, 3, 242, 119, 238, 136, 3, 242, 118, 238, + 136, 3, 242, 117, 238, 136, 3, 242, 116, 238, 136, 3, 242, 115, 238, 136, + 3, 242, 114, 238, 136, 3, 242, 113, 238, 136, 3, 242, 112, 238, 136, 3, + 242, 111, 238, 136, 3, 242, 110, 238, 136, 3, 242, 109, 238, 136, 3, 242, + 108, 238, 136, 3, 242, 107, 238, 136, 3, 242, 106, 238, 136, 3, 242, 105, + 238, 136, 3, 242, 104, 238, 136, 3, 242, 103, 238, 136, 3, 242, 102, 14, + 7, 255, 201, 14, 7, 255, 200, 14, 7, 255, 199, 14, 7, 255, 198, 14, 7, + 255, 197, 14, 7, 255, 196, 14, 7, 255, 195, 14, 7, 255, 194, 14, 7, 255, + 193, 14, 7, 255, 192, 14, 7, 255, 191, 14, 7, 255, 190, 14, 7, 255, 189, + 14, 7, 255, 187, 14, 7, 255, 186, 14, 7, 255, 185, 14, 7, 255, 184, 14, + 7, 255, 183, 14, 7, 255, 182, 14, 7, 255, 181, 14, 7, 255, 180, 14, 7, + 255, 179, 14, 7, 255, 178, 14, 7, 255, 177, 14, 7, 255, 176, 14, 7, 255, + 175, 14, 7, 255, 174, 14, 7, 255, 173, 14, 7, 255, 172, 14, 7, 255, 171, + 14, 7, 255, 170, 14, 7, 255, 168, 14, 7, 255, 167, 14, 7, 255, 165, 14, + 7, 255, 164, 14, 7, 255, 163, 14, 7, 255, 162, 14, 7, 255, 161, 14, 7, + 255, 160, 14, 7, 255, 159, 14, 7, 255, 158, 14, 7, 255, 157, 14, 7, 255, + 156, 14, 7, 255, 155, 14, 7, 255, 154, 14, 7, 255, 152, 14, 7, 255, 151, + 14, 7, 255, 150, 14, 7, 255, 148, 14, 7, 255, 147, 14, 7, 255, 146, 14, + 7, 255, 145, 14, 7, 255, 144, 14, 7, 255, 143, 14, 7, 255, 142, 14, 7, + 255, 141, 14, 7, 255, 138, 14, 7, 255, 137, 14, 7, 255, 136, 14, 7, 255, + 135, 14, 7, 255, 134, 14, 7, 255, 133, 14, 7, 255, 132, 14, 7, 255, 131, + 14, 7, 255, 130, 14, 7, 255, 129, 14, 7, 255, 128, 14, 7, 255, 127, 14, + 7, 255, 126, 14, 7, 255, 125, 14, 7, 255, 124, 14, 7, 255, 123, 14, 7, + 255, 122, 14, 7, 255, 121, 14, 7, 255, 120, 14, 7, 255, 119, 14, 7, 255, + 115, 14, 7, 255, 114, 14, 7, 255, 113, 14, 7, 255, 112, 14, 7, 250, 120, + 14, 7, 250, 118, 14, 7, 250, 116, 14, 7, 250, 114, 14, 7, 250, 112, 14, + 7, 250, 111, 14, 7, 250, 109, 14, 7, 250, 107, 14, 7, 250, 105, 14, 7, + 250, 103, 14, 7, 247, 191, 14, 7, 247, 190, 14, 7, 247, 189, 14, 7, 247, + 188, 14, 7, 247, 187, 14, 7, 247, 186, 14, 7, 247, 185, 14, 7, 247, 184, + 14, 7, 247, 183, 14, 7, 247, 182, 14, 7, 247, 181, 14, 7, 247, 180, 14, + 7, 247, 179, 14, 7, 247, 178, 14, 7, 247, 177, 14, 7, 247, 176, 14, 7, + 247, 175, 14, 7, 247, 174, 14, 7, 247, 173, 14, 7, 247, 172, 14, 7, 247, + 171, 14, 7, 247, 170, 14, 7, 247, 169, 14, 7, 247, 168, 14, 7, 247, 167, + 14, 7, 247, 166, 14, 7, 247, 165, 14, 7, 247, 164, 14, 7, 238, 128, 14, + 7, 238, 127, 14, 7, 238, 126, 14, 7, 238, 125, 14, 7, 238, 124, 14, 7, + 238, 123, 14, 7, 238, 122, 14, 7, 238, 121, 14, 7, 238, 120, 14, 7, 238, + 119, 14, 7, 238, 118, 14, 7, 238, 117, 14, 7, 238, 116, 14, 7, 238, 115, + 14, 7, 238, 114, 14, 7, 238, 113, 14, 7, 238, 112, 14, 7, 238, 111, 14, + 7, 238, 110, 14, 7, 238, 109, 14, 7, 238, 108, 14, 7, 238, 107, 14, 7, + 238, 106, 14, 7, 238, 105, 14, 7, 238, 104, 14, 7, 238, 103, 14, 7, 238, + 102, 14, 7, 238, 101, 14, 7, 238, 100, 14, 7, 238, 99, 14, 7, 238, 98, + 14, 7, 238, 97, 14, 7, 238, 96, 14, 7, 238, 95, 14, 7, 238, 94, 14, 7, + 238, 93, 14, 7, 238, 92, 14, 7, 238, 91, 14, 7, 238, 90, 14, 7, 238, 89, + 14, 7, 238, 88, 14, 7, 238, 87, 14, 7, 238, 86, 14, 7, 238, 85, 14, 7, + 238, 84, 14, 7, 238, 83, 14, 7, 238, 82, 14, 7, 238, 81, 14, 7, 238, 80, + 14, 7, 238, 79, 14, 7, 238, 78, 14, 7, 238, 77, 14, 7, 238, 76, 14, 7, + 238, 75, 14, 7, 238, 74, 14, 7, 238, 73, 14, 7, 238, 72, 14, 7, 238, 71, + 14, 7, 238, 70, 14, 7, 238, 69, 14, 7, 238, 68, 14, 7, 238, 67, 14, 7, + 238, 66, 14, 7, 238, 65, 14, 7, 238, 64, 14, 7, 238, 63, 14, 7, 238, 62, + 14, 7, 238, 61, 14, 7, 238, 60, 14, 7, 238, 59, 14, 7, 238, 58, 14, 7, + 238, 57, 14, 7, 238, 56, 14, 7, 238, 55, 14, 7, 238, 54, 14, 7, 238, 53, + 14, 7, 238, 52, 14, 7, 238, 51, 14, 7, 238, 50, 14, 7, 238, 49, 14, 7, + 238, 48, 14, 7, 238, 47, 14, 7, 238, 46, 14, 7, 238, 45, 14, 7, 238, 44, + 14, 7, 238, 43, 14, 7, 238, 42, 14, 7, 238, 41, 14, 7, 238, 40, 14, 7, + 238, 39, 14, 7, 238, 38, 14, 7, 238, 37, 14, 7, 235, 9, 14, 7, 235, 8, + 14, 7, 235, 7, 14, 7, 235, 6, 14, 7, 235, 5, 14, 7, 235, 4, 14, 7, 235, + 3, 14, 7, 235, 2, 14, 7, 235, 1, 14, 7, 235, 0, 14, 7, 234, 255, 14, 7, + 234, 254, 14, 7, 234, 253, 14, 7, 234, 252, 14, 7, 234, 251, 14, 7, 234, + 250, 14, 7, 234, 249, 14, 7, 234, 248, 14, 7, 234, 247, 14, 7, 234, 246, + 14, 7, 234, 245, 14, 7, 234, 244, 14, 7, 234, 243, 14, 7, 234, 242, 14, + 7, 234, 241, 14, 7, 234, 240, 14, 7, 234, 239, 14, 7, 234, 238, 14, 7, + 234, 237, 14, 7, 234, 236, 14, 7, 234, 235, 14, 7, 234, 234, 14, 7, 234, + 233, 14, 7, 234, 232, 14, 7, 234, 231, 14, 7, 234, 230, 14, 7, 234, 229, + 14, 7, 234, 228, 14, 7, 234, 227, 14, 7, 234, 226, 14, 7, 234, 225, 14, + 7, 234, 224, 14, 7, 234, 223, 14, 7, 234, 222, 14, 7, 233, 176, 14, 7, + 233, 175, 14, 7, 233, 174, 14, 7, 233, 173, 14, 7, 233, 172, 14, 7, 233, + 171, 14, 7, 233, 170, 14, 7, 233, 169, 14, 7, 233, 168, 14, 7, 233, 167, + 14, 7, 233, 166, 14, 7, 233, 165, 14, 7, 233, 164, 14, 7, 233, 163, 14, + 7, 233, 162, 14, 7, 233, 161, 14, 7, 233, 160, 14, 7, 233, 159, 14, 7, + 233, 158, 14, 7, 233, 157, 14, 7, 233, 156, 14, 7, 233, 155, 14, 7, 233, + 154, 14, 7, 233, 153, 14, 7, 233, 152, 14, 7, 233, 151, 14, 7, 233, 150, + 14, 7, 233, 149, 14, 7, 233, 148, 14, 7, 233, 147, 14, 7, 233, 146, 14, + 7, 233, 145, 14, 7, 233, 144, 14, 7, 233, 143, 14, 7, 233, 142, 14, 7, + 233, 141, 14, 7, 233, 140, 14, 7, 233, 139, 14, 7, 233, 138, 14, 7, 233, + 137, 14, 7, 233, 136, 14, 7, 233, 135, 14, 7, 233, 134, 14, 7, 233, 133, + 14, 7, 233, 132, 14, 7, 233, 131, 14, 7, 233, 130, 14, 7, 233, 129, 14, + 7, 233, 128, 14, 7, 233, 127, 14, 7, 233, 126, 14, 7, 233, 125, 14, 7, + 233, 124, 14, 7, 233, 123, 14, 7, 233, 122, 14, 7, 233, 121, 14, 7, 233, + 120, 14, 7, 233, 119, 14, 7, 233, 118, 14, 7, 233, 117, 14, 7, 233, 116, + 14, 7, 233, 115, 14, 7, 233, 114, 14, 7, 233, 113, 14, 7, 233, 112, 14, + 7, 232, 52, 14, 7, 232, 51, 14, 7, 232, 50, 14, 7, 232, 49, 14, 7, 232, + 48, 14, 7, 232, 47, 14, 7, 232, 46, 14, 7, 232, 45, 14, 7, 232, 44, 14, + 7, 232, 43, 14, 7, 232, 42, 14, 7, 232, 41, 14, 7, 232, 40, 14, 7, 232, + 39, 14, 7, 232, 38, 14, 7, 232, 37, 14, 7, 232, 36, 14, 7, 232, 35, 14, + 7, 232, 34, 14, 7, 232, 33, 14, 7, 232, 32, 14, 7, 232, 31, 14, 7, 232, + 30, 14, 7, 232, 29, 14, 7, 232, 28, 14, 7, 232, 27, 14, 7, 232, 26, 14, + 7, 232, 25, 14, 7, 232, 24, 14, 7, 232, 23, 14, 7, 232, 22, 14, 7, 232, + 21, 14, 7, 232, 20, 14, 7, 232, 19, 14, 7, 232, 18, 14, 7, 232, 17, 14, + 7, 232, 16, 14, 7, 232, 15, 14, 7, 232, 14, 14, 7, 232, 13, 14, 7, 232, + 12, 14, 7, 232, 11, 14, 7, 232, 10, 14, 7, 232, 9, 14, 7, 232, 8, 14, 7, + 232, 7, 14, 7, 232, 6, 14, 7, 232, 5, 14, 7, 232, 4, 14, 7, 232, 3, 14, + 7, 232, 2, 14, 7, 232, 1, 14, 7, 232, 0, 14, 7, 231, 255, 14, 7, 231, + 254, 14, 7, 231, 253, 14, 7, 231, 252, 14, 7, 231, 251, 14, 7, 231, 250, + 14, 7, 231, 249, 14, 7, 231, 248, 14, 7, 231, 247, 14, 7, 231, 246, 14, + 7, 231, 245, 14, 7, 230, 116, 14, 7, 230, 115, 14, 7, 230, 114, 14, 7, + 230, 113, 14, 7, 230, 112, 14, 7, 230, 111, 14, 7, 230, 110, 14, 7, 230, + 109, 14, 7, 230, 108, 14, 7, 228, 56, 14, 7, 228, 55, 14, 7, 228, 54, 14, + 7, 228, 53, 14, 7, 228, 52, 14, 7, 228, 51, 14, 7, 228, 50, 14, 7, 228, + 49, 14, 7, 228, 48, 14, 7, 228, 47, 14, 7, 228, 46, 14, 7, 228, 45, 14, + 7, 228, 44, 14, 7, 228, 43, 14, 7, 228, 42, 14, 7, 228, 41, 14, 7, 228, + 40, 14, 7, 228, 39, 14, 7, 228, 38, 14, 7, 222, 153, 14, 7, 222, 152, 14, + 7, 222, 151, 14, 7, 222, 150, 14, 7, 222, 149, 14, 7, 222, 148, 14, 7, + 222, 147, 14, 7, 222, 146, 14, 7, 220, 142, 14, 7, 220, 141, 14, 7, 220, + 140, 14, 7, 220, 139, 14, 7, 220, 138, 14, 7, 220, 137, 14, 7, 220, 136, + 14, 7, 220, 135, 14, 7, 220, 134, 14, 7, 220, 133, 14, 7, 218, 168, 14, + 7, 218, 167, 14, 7, 218, 166, 14, 7, 218, 164, 14, 7, 218, 162, 14, 7, + 218, 161, 14, 7, 218, 159, 14, 7, 218, 157, 14, 7, 218, 155, 14, 7, 218, + 153, 14, 7, 218, 151, 14, 7, 218, 149, 14, 7, 218, 147, 14, 7, 218, 146, + 14, 7, 218, 144, 14, 7, 218, 142, 14, 7, 218, 141, 14, 7, 218, 140, 14, + 7, 218, 139, 14, 7, 218, 138, 14, 7, 218, 137, 14, 7, 218, 136, 14, 7, + 218, 135, 14, 7, 218, 134, 14, 7, 218, 132, 14, 7, 218, 130, 14, 7, 218, + 128, 14, 7, 218, 127, 14, 7, 218, 125, 14, 7, 218, 124, 14, 7, 218, 122, + 14, 7, 218, 121, 14, 7, 218, 119, 14, 7, 218, 117, 14, 7, 218, 115, 14, + 7, 218, 113, 14, 7, 218, 111, 14, 7, 218, 110, 14, 7, 218, 108, 14, 7, + 218, 106, 14, 7, 218, 105, 14, 7, 218, 103, 14, 7, 218, 101, 14, 7, 218, + 99, 14, 7, 218, 97, 14, 7, 218, 96, 14, 7, 218, 94, 14, 7, 218, 92, 14, + 7, 218, 90, 14, 7, 218, 89, 14, 7, 218, 87, 14, 7, 218, 85, 14, 7, 218, + 84, 14, 7, 218, 83, 14, 7, 218, 81, 14, 7, 218, 79, 14, 7, 218, 77, 14, + 7, 218, 75, 14, 7, 218, 73, 14, 7, 218, 71, 14, 7, 218, 69, 14, 7, 218, + 68, 14, 7, 218, 66, 14, 7, 218, 64, 14, 7, 218, 62, 14, 7, 218, 60, 14, + 7, 215, 58, 14, 7, 215, 57, 14, 7, 215, 56, 14, 7, 215, 55, 14, 7, 215, + 54, 14, 7, 215, 53, 14, 7, 215, 52, 14, 7, 215, 51, 14, 7, 215, 50, 14, + 7, 215, 49, 14, 7, 215, 48, 14, 7, 215, 47, 14, 7, 215, 46, 14, 7, 215, + 45, 14, 7, 215, 44, 14, 7, 215, 43, 14, 7, 215, 42, 14, 7, 215, 41, 14, + 7, 215, 40, 14, 7, 215, 39, 14, 7, 215, 38, 14, 7, 215, 37, 14, 7, 215, + 36, 14, 7, 215, 35, 14, 7, 215, 34, 14, 7, 215, 33, 14, 7, 215, 32, 14, + 7, 215, 31, 14, 7, 215, 30, 14, 7, 215, 29, 14, 7, 215, 28, 14, 7, 215, + 27, 14, 7, 215, 26, 14, 7, 215, 25, 14, 7, 215, 24, 14, 7, 215, 23, 14, + 7, 215, 22, 14, 7, 215, 21, 14, 7, 215, 20, 14, 7, 215, 19, 14, 7, 215, + 18, 14, 7, 215, 17, 14, 7, 215, 16, 14, 7, 215, 15, 14, 7, 215, 14, 14, + 7, 215, 13, 14, 7, 215, 12, 14, 7, 215, 11, 14, 7, 215, 10, 14, 7, 213, + 106, 14, 7, 213, 105, 14, 7, 213, 104, 14, 7, 213, 103, 14, 7, 213, 102, + 14, 7, 213, 101, 14, 7, 213, 100, 14, 7, 213, 99, 14, 7, 213, 98, 14, 7, + 213, 97, 14, 7, 213, 96, 14, 7, 213, 95, 14, 7, 213, 94, 14, 7, 213, 93, + 14, 7, 213, 92, 14, 7, 213, 91, 14, 7, 213, 90, 14, 7, 213, 89, 14, 7, + 213, 88, 14, 7, 213, 87, 14, 7, 213, 86, 14, 7, 213, 85, 14, 7, 212, 176, + 14, 7, 212, 175, 14, 7, 212, 174, 14, 7, 212, 173, 14, 7, 212, 172, 14, + 7, 212, 171, 14, 7, 212, 170, 14, 7, 212, 169, 14, 7, 212, 168, 14, 7, + 212, 167, 14, 7, 212, 166, 14, 7, 212, 165, 14, 7, 212, 164, 14, 7, 212, + 163, 14, 7, 212, 162, 14, 7, 212, 161, 14, 7, 212, 160, 14, 7, 212, 159, + 14, 7, 212, 158, 14, 7, 212, 157, 14, 7, 212, 156, 14, 7, 212, 155, 14, + 7, 212, 154, 14, 7, 212, 153, 14, 7, 212, 152, 14, 7, 212, 151, 14, 7, + 212, 4, 14, 7, 212, 3, 14, 7, 212, 2, 14, 7, 212, 1, 14, 7, 212, 0, 14, + 7, 211, 255, 14, 7, 211, 254, 14, 7, 211, 253, 14, 7, 211, 252, 14, 7, + 211, 251, 14, 7, 211, 250, 14, 7, 211, 249, 14, 7, 211, 248, 14, 7, 211, + 247, 14, 7, 211, 246, 14, 7, 211, 245, 14, 7, 211, 244, 14, 7, 211, 243, + 14, 7, 211, 242, 14, 7, 211, 241, 14, 7, 211, 240, 14, 7, 211, 239, 14, + 7, 211, 238, 14, 7, 211, 237, 14, 7, 211, 236, 14, 7, 211, 235, 14, 7, + 211, 234, 14, 7, 211, 233, 14, 7, 211, 232, 14, 7, 211, 231, 14, 7, 211, + 230, 14, 7, 211, 229, 14, 7, 211, 228, 14, 7, 211, 227, 14, 7, 211, 226, + 14, 7, 211, 225, 14, 7, 211, 224, 14, 7, 211, 223, 14, 7, 211, 222, 14, + 7, 211, 221, 14, 7, 211, 220, 14, 7, 211, 219, 14, 7, 211, 218, 14, 7, + 211, 217, 14, 7, 211, 216, 14, 7, 211, 215, 14, 7, 211, 214, 14, 7, 211, + 213, 14, 7, 211, 212, 14, 7, 211, 211, 14, 7, 211, 210, 14, 7, 211, 209, + 14, 7, 211, 208, 14, 7, 211, 207, 14, 7, 211, 206, 14, 7, 211, 205, 14, + 7, 211, 204, 14, 7, 211, 203, 14, 7, 211, 202, 14, 7, 211, 201, 14, 7, + 211, 200, 14, 7, 211, 199, 14, 7, 211, 198, 14, 7, 211, 197, 14, 7, 211, + 196, 14, 7, 211, 195, 14, 7, 211, 194, 14, 7, 211, 193, 14, 7, 211, 192, + 14, 7, 211, 191, 14, 7, 211, 190, 14, 7, 211, 189, 14, 7, 211, 188, 14, + 7, 211, 187, 14, 7, 211, 186, 14, 7, 210, 237, 14, 7, 210, 236, 14, 7, + 210, 235, 14, 7, 210, 234, 14, 7, 210, 233, 14, 7, 210, 232, 14, 7, 210, + 231, 14, 7, 210, 230, 14, 7, 210, 229, 14, 7, 210, 228, 14, 7, 210, 227, + 14, 7, 210, 226, 14, 7, 210, 225, 14, 7, 208, 105, 14, 7, 208, 104, 14, + 7, 208, 103, 14, 7, 208, 102, 14, 7, 208, 101, 14, 7, 208, 100, 14, 7, + 208, 99, 14, 7, 207, 222, 14, 7, 207, 221, 14, 7, 207, 220, 14, 7, 207, + 219, 14, 7, 207, 218, 14, 7, 207, 217, 14, 7, 207, 216, 14, 7, 207, 215, + 14, 7, 207, 214, 14, 7, 207, 213, 14, 7, 207, 212, 14, 7, 207, 211, 14, + 7, 207, 210, 14, 7, 207, 209, 14, 7, 207, 208, 14, 7, 207, 207, 14, 7, + 207, 206, 14, 7, 207, 205, 14, 7, 207, 204, 14, 7, 207, 203, 14, 7, 207, + 202, 14, 7, 207, 201, 14, 7, 207, 200, 14, 7, 207, 199, 14, 7, 207, 198, + 14, 7, 207, 197, 14, 7, 207, 196, 14, 7, 207, 195, 14, 7, 207, 194, 14, + 7, 207, 193, 14, 7, 207, 192, 14, 7, 207, 191, 14, 7, 207, 190, 14, 7, + 207, 189, 14, 7, 206, 6, 14, 7, 206, 5, 14, 7, 206, 4, 14, 7, 206, 3, 14, + 7, 206, 2, 14, 7, 206, 1, 14, 7, 206, 0, 14, 7, 205, 255, 14, 7, 205, + 254, 14, 7, 205, 253, 14, 7, 205, 252, 14, 7, 205, 251, 14, 7, 205, 250, + 14, 7, 205, 249, 14, 7, 205, 248, 14, 7, 205, 247, 14, 7, 205, 246, 14, + 7, 205, 245, 14, 7, 205, 244, 14, 7, 205, 243, 14, 7, 205, 242, 14, 7, + 205, 241, 14, 7, 205, 240, 14, 7, 205, 239, 14, 7, 205, 238, 14, 7, 205, + 237, 14, 7, 205, 236, 14, 7, 205, 235, 14, 7, 205, 234, 14, 7, 205, 233, + 14, 7, 205, 232, 14, 7, 205, 231, 14, 7, 205, 230, 14, 7, 205, 229, 14, + 7, 205, 228, 14, 7, 205, 227, 14, 7, 205, 226, 14, 7, 205, 225, 14, 7, + 205, 224, 14, 7, 205, 223, 14, 7, 205, 222, 14, 7, 205, 221, 14, 7, 205, + 220, 14, 7, 205, 219, 14, 7, 205, 218, 14, 7, 205, 217, 14, 7, 205, 216, + 14, 7, 205, 215, 14, 7, 205, 214, 14, 7, 205, 213, 14, 7, 205, 212, 14, + 7, 205, 211, 14, 7, 205, 210, 14, 7, 205, 209, 14, 7, 200, 40, 14, 7, 200, 39, 14, 7, 200, 38, 14, 7, 200, 37, 14, 7, 200, 36, 14, 7, 200, 35, 14, 7, 200, 34, 14, 7, 200, 33, 14, 7, 200, 32, 14, 7, 200, 31, 14, 7, 200, 30, 14, 7, 200, 29, 14, 7, 200, 28, 14, 7, 200, 27, 14, 7, 200, 26, @@ -16914,698 +16919,698 @@ static const unsigned char phrasebook[] = { 139, 14, 7, 191, 138, 14, 7, 191, 137, 14, 7, 191, 136, 14, 7, 191, 135, 14, 7, 191, 134, 14, 7, 191, 133, 14, 7, 191, 132, 14, 7, 191, 131, 14, 7, 191, 130, 14, 7, 191, 129, 14, 7, 191, 128, 14, 7, 191, 127, 14, 7, - 191, 126, 14, 7, 191, 125, 14, 7, 252, 205, 14, 7, 252, 204, 14, 7, 252, - 203, 14, 7, 252, 202, 14, 7, 252, 201, 14, 7, 252, 200, 14, 7, 252, 199, - 14, 7, 252, 198, 14, 7, 252, 197, 14, 7, 252, 196, 14, 7, 252, 195, 14, - 7, 252, 194, 14, 7, 252, 193, 14, 7, 252, 192, 14, 7, 252, 191, 14, 7, - 252, 190, 14, 7, 252, 189, 14, 7, 252, 188, 14, 7, 252, 187, 14, 7, 252, - 186, 14, 7, 252, 185, 14, 7, 252, 184, 14, 7, 252, 183, 14, 7, 252, 182, - 14, 7, 252, 181, 14, 7, 252, 180, 14, 7, 252, 179, 14, 7, 252, 178, 14, - 7, 252, 177, 14, 7, 252, 176, 14, 7, 252, 175, 14, 7, 252, 174, 14, 7, - 252, 173, 14, 7, 252, 172, 14, 7, 195, 241, 14, 7, 81, 222, 196, 14, 7, - 228, 241, 222, 196, 14, 7, 223, 120, 250, 183, 198, 54, 201, 97, 14, 7, - 223, 120, 250, 183, 248, 77, 201, 97, 14, 7, 223, 120, 250, 183, 198, 54, - 234, 94, 14, 7, 223, 120, 250, 183, 248, 77, 234, 94, 14, 7, 211, 0, 216, - 84, 14, 7, 248, 249, 205, 43, 14, 7, 234, 95, 205, 43, 14, 7, 223, 120, - 250, 183, 216, 84, 14, 7, 223, 120, 250, 183, 198, 53, 14, 7, 223, 120, - 250, 183, 248, 76, 14, 7, 248, 249, 234, 98, 14, 7, 234, 95, 234, 98, 14, - 7, 248, 249, 193, 166, 234, 98, 14, 7, 234, 95, 193, 166, 234, 98, 14, 7, - 216, 27, 228, 189, 14, 7, 232, 80, 248, 132, 14, 7, 132, 248, 132, 14, 7, - 218, 251, 56, 14, 7, 132, 218, 251, 56, 14, 7, 199, 200, 218, 251, 56, - 14, 7, 193, 78, 218, 251, 56, 14, 7, 52, 237, 249, 250, 183, 198, 54, - 201, 97, 14, 7, 52, 237, 249, 250, 183, 248, 77, 201, 97, 14, 7, 52, 237, - 249, 250, 183, 201, 97, 14, 7, 52, 237, 249, 250, 183, 198, 54, 234, 94, - 14, 7, 52, 237, 249, 250, 183, 198, 53, 14, 7, 52, 237, 249, 250, 183, - 248, 77, 201, 98, 23, 198, 54, 234, 94, 14, 7, 52, 237, 249, 250, 183, - 201, 98, 23, 198, 53, 14, 7, 52, 237, 249, 250, 183, 248, 77, 234, 94, - 14, 7, 52, 237, 249, 250, 183, 198, 54, 201, 98, 23, 248, 77, 234, 94, - 14, 7, 52, 237, 249, 250, 183, 248, 76, 14, 7, 52, 237, 249, 250, 183, - 201, 98, 23, 248, 76, 14, 7, 52, 237, 249, 250, 183, 234, 94, 14, 7, 52, - 237, 249, 250, 183, 198, 54, 23, 234, 94, 14, 7, 52, 237, 249, 250, 183, - 248, 77, 23, 234, 94, 14, 7, 52, 237, 248, 29, 7, 255, 199, 29, 7, 255, - 198, 29, 7, 255, 197, 29, 7, 255, 196, 29, 7, 255, 195, 29, 7, 255, 193, - 29, 7, 255, 190, 29, 7, 255, 189, 29, 7, 255, 188, 29, 7, 255, 187, 29, - 7, 255, 186, 29, 7, 255, 185, 29, 7, 255, 184, 29, 7, 255, 183, 29, 7, - 255, 182, 29, 7, 255, 180, 29, 7, 255, 179, 29, 7, 255, 178, 29, 7, 255, - 176, 29, 7, 255, 175, 29, 7, 255, 174, 29, 7, 255, 173, 29, 7, 255, 172, - 29, 7, 255, 171, 29, 7, 255, 170, 29, 7, 255, 169, 29, 7, 255, 168, 29, - 7, 255, 167, 29, 7, 255, 166, 29, 7, 255, 165, 29, 7, 255, 163, 29, 7, - 255, 162, 29, 7, 255, 161, 29, 7, 255, 160, 29, 7, 255, 158, 29, 7, 255, - 157, 29, 7, 255, 156, 29, 7, 255, 155, 29, 7, 255, 154, 29, 7, 255, 153, - 29, 7, 255, 152, 29, 7, 255, 151, 29, 7, 255, 150, 29, 7, 255, 148, 29, - 7, 255, 147, 29, 7, 255, 146, 29, 7, 255, 144, 29, 7, 255, 142, 29, 7, - 255, 141, 29, 7, 255, 140, 29, 7, 255, 139, 29, 7, 255, 138, 29, 7, 255, - 137, 29, 7, 255, 136, 29, 7, 255, 135, 29, 7, 255, 134, 29, 7, 255, 133, - 29, 7, 255, 132, 29, 7, 255, 131, 29, 7, 255, 130, 29, 7, 255, 129, 29, - 7, 255, 128, 29, 7, 255, 127, 29, 7, 255, 126, 29, 7, 255, 125, 29, 7, - 255, 124, 29, 7, 255, 123, 29, 7, 255, 122, 29, 7, 255, 121, 29, 7, 255, - 120, 29, 7, 255, 119, 29, 7, 255, 118, 29, 7, 255, 117, 29, 7, 255, 116, - 29, 7, 255, 115, 29, 7, 255, 114, 29, 7, 255, 113, 29, 7, 255, 112, 29, - 7, 255, 111, 29, 7, 255, 110, 29, 7, 255, 109, 29, 7, 255, 108, 29, 7, - 255, 107, 29, 7, 255, 106, 29, 7, 255, 105, 29, 7, 255, 104, 29, 7, 255, - 103, 29, 7, 255, 102, 29, 7, 255, 101, 29, 7, 255, 100, 29, 7, 255, 99, - 29, 7, 255, 98, 29, 7, 255, 97, 29, 7, 255, 96, 29, 7, 255, 95, 29, 7, - 255, 94, 29, 7, 255, 93, 29, 7, 255, 92, 29, 7, 255, 91, 29, 7, 255, 90, - 29, 7, 255, 89, 29, 7, 255, 88, 29, 7, 255, 87, 29, 7, 255, 86, 29, 7, - 255, 85, 29, 7, 255, 84, 29, 7, 255, 83, 29, 7, 255, 82, 29, 7, 255, 81, - 29, 7, 255, 80, 29, 7, 255, 79, 29, 7, 255, 78, 29, 7, 255, 76, 29, 7, - 255, 75, 29, 7, 255, 74, 29, 7, 255, 73, 29, 7, 255, 72, 29, 7, 255, 71, - 29, 7, 255, 70, 29, 7, 255, 69, 29, 7, 255, 68, 29, 7, 255, 67, 29, 7, - 255, 66, 29, 7, 255, 65, 29, 7, 255, 64, 29, 7, 255, 63, 29, 7, 255, 62, - 29, 7, 255, 61, 29, 7, 255, 60, 29, 7, 255, 59, 29, 7, 255, 58, 29, 7, - 255, 57, 29, 7, 255, 56, 29, 7, 255, 55, 29, 7, 255, 54, 29, 7, 255, 53, - 29, 7, 255, 52, 29, 7, 255, 51, 29, 7, 255, 50, 29, 7, 255, 49, 29, 7, - 255, 48, 29, 7, 255, 47, 29, 7, 255, 46, 29, 7, 255, 45, 29, 7, 255, 44, - 29, 7, 255, 43, 29, 7, 255, 41, 29, 7, 255, 40, 29, 7, 255, 39, 29, 7, - 255, 38, 29, 7, 255, 37, 29, 7, 255, 36, 29, 7, 255, 35, 29, 7, 255, 34, - 29, 7, 255, 33, 29, 7, 255, 32, 29, 7, 255, 31, 29, 7, 255, 30, 29, 7, - 255, 28, 29, 7, 255, 27, 29, 7, 255, 26, 29, 7, 255, 25, 29, 7, 255, 24, - 29, 7, 255, 23, 29, 7, 255, 22, 29, 7, 255, 21, 29, 7, 255, 20, 29, 7, - 255, 19, 29, 7, 255, 18, 29, 7, 255, 17, 29, 7, 255, 16, 29, 7, 255, 15, - 29, 7, 255, 14, 29, 7, 255, 13, 29, 7, 255, 12, 29, 7, 255, 11, 29, 7, - 255, 10, 29, 7, 255, 9, 29, 7, 255, 8, 29, 7, 255, 7, 29, 7, 255, 6, 29, - 7, 255, 5, 29, 7, 255, 4, 29, 7, 255, 3, 29, 7, 255, 2, 29, 7, 255, 1, - 29, 7, 255, 0, 29, 7, 254, 255, 29, 7, 254, 254, 29, 7, 254, 253, 29, 7, - 254, 252, 29, 7, 254, 251, 29, 7, 254, 250, 29, 7, 254, 249, 29, 7, 254, - 248, 29, 7, 254, 247, 29, 7, 254, 246, 29, 7, 254, 245, 29, 7, 254, 244, - 29, 7, 254, 243, 29, 7, 254, 242, 29, 7, 254, 241, 29, 7, 254, 240, 29, - 7, 254, 239, 29, 7, 254, 238, 29, 7, 254, 237, 29, 7, 254, 236, 29, 7, - 254, 235, 29, 7, 254, 234, 29, 7, 254, 233, 29, 7, 254, 232, 29, 7, 254, - 231, 29, 7, 254, 230, 29, 7, 254, 229, 29, 7, 254, 228, 29, 7, 254, 227, - 29, 7, 254, 226, 29, 7, 254, 225, 29, 7, 254, 224, 29, 7, 254, 223, 29, - 7, 254, 222, 29, 7, 254, 221, 29, 7, 254, 220, 29, 7, 254, 219, 29, 7, - 254, 218, 29, 7, 254, 217, 29, 7, 254, 216, 29, 7, 254, 214, 29, 7, 254, - 213, 29, 7, 254, 212, 29, 7, 254, 211, 29, 7, 254, 210, 29, 7, 254, 209, - 29, 7, 254, 208, 29, 7, 254, 207, 29, 7, 254, 206, 29, 7, 254, 205, 29, - 7, 254, 204, 29, 7, 254, 203, 29, 7, 254, 202, 29, 7, 254, 201, 29, 7, - 254, 200, 29, 7, 254, 199, 29, 7, 254, 198, 29, 7, 254, 197, 29, 7, 254, - 196, 29, 7, 254, 195, 29, 7, 254, 194, 29, 7, 254, 193, 29, 7, 254, 192, - 29, 7, 254, 191, 29, 7, 254, 190, 29, 7, 254, 189, 29, 7, 254, 188, 29, - 7, 254, 187, 29, 7, 254, 186, 29, 7, 254, 185, 29, 7, 254, 184, 29, 7, - 254, 183, 29, 7, 254, 182, 29, 7, 254, 181, 29, 7, 254, 180, 29, 7, 254, - 179, 29, 7, 254, 178, 29, 7, 254, 177, 29, 7, 254, 176, 29, 7, 254, 175, - 29, 7, 254, 174, 29, 7, 254, 173, 29, 7, 254, 172, 29, 7, 254, 171, 29, - 7, 254, 170, 29, 7, 254, 169, 29, 7, 254, 168, 29, 7, 254, 167, 29, 7, - 254, 166, 29, 7, 254, 165, 29, 7, 254, 164, 29, 7, 254, 163, 29, 7, 254, - 162, 29, 7, 254, 161, 29, 7, 254, 160, 29, 7, 254, 159, 29, 7, 254, 158, - 29, 7, 254, 157, 29, 7, 254, 156, 29, 7, 254, 155, 29, 7, 254, 154, 29, - 7, 254, 153, 29, 7, 254, 152, 29, 7, 254, 151, 29, 7, 254, 150, 29, 7, - 254, 149, 29, 7, 254, 148, 29, 7, 254, 147, 29, 7, 254, 146, 29, 7, 254, - 145, 29, 7, 254, 144, 29, 7, 254, 143, 29, 7, 254, 142, 29, 7, 254, 141, - 29, 7, 254, 140, 29, 7, 254, 139, 29, 7, 254, 138, 29, 7, 254, 137, 29, - 7, 254, 136, 29, 7, 254, 135, 29, 7, 254, 134, 29, 7, 254, 133, 29, 7, - 254, 132, 29, 7, 254, 131, 29, 7, 254, 130, 29, 7, 254, 129, 29, 7, 254, - 128, 29, 7, 254, 127, 29, 7, 254, 126, 29, 7, 254, 125, 29, 7, 254, 124, - 29, 7, 254, 123, 29, 7, 254, 122, 29, 7, 254, 121, 29, 7, 254, 120, 29, - 7, 254, 119, 29, 7, 254, 118, 29, 7, 254, 117, 29, 7, 254, 116, 29, 7, - 254, 115, 29, 7, 254, 114, 29, 7, 254, 113, 29, 7, 254, 112, 29, 7, 254, - 111, 29, 7, 254, 110, 29, 7, 254, 109, 29, 7, 254, 108, 29, 7, 254, 107, - 29, 7, 254, 106, 29, 7, 254, 105, 29, 7, 254, 104, 29, 7, 254, 102, 29, - 7, 254, 101, 29, 7, 254, 100, 29, 7, 254, 99, 29, 7, 254, 98, 29, 7, 254, - 97, 29, 7, 254, 96, 29, 7, 254, 95, 29, 7, 254, 94, 29, 7, 254, 93, 29, - 7, 254, 92, 29, 7, 254, 89, 29, 7, 254, 88, 29, 7, 254, 87, 29, 7, 254, - 86, 29, 7, 254, 82, 29, 7, 254, 81, 29, 7, 254, 80, 29, 7, 254, 79, 29, - 7, 254, 78, 29, 7, 254, 77, 29, 7, 254, 76, 29, 7, 254, 75, 29, 7, 254, - 74, 29, 7, 254, 73, 29, 7, 254, 72, 29, 7, 254, 71, 29, 7, 254, 70, 29, - 7, 254, 69, 29, 7, 254, 68, 29, 7, 254, 67, 29, 7, 254, 66, 29, 7, 254, - 65, 29, 7, 254, 64, 29, 7, 254, 62, 29, 7, 254, 61, 29, 7, 254, 60, 29, - 7, 254, 59, 29, 7, 254, 58, 29, 7, 254, 57, 29, 7, 254, 56, 29, 7, 254, - 55, 29, 7, 254, 54, 29, 7, 254, 53, 29, 7, 254, 52, 29, 7, 254, 51, 29, - 7, 254, 50, 29, 7, 254, 49, 29, 7, 254, 48, 29, 7, 254, 47, 29, 7, 254, - 46, 29, 7, 254, 45, 29, 7, 254, 44, 29, 7, 254, 43, 29, 7, 254, 42, 29, - 7, 254, 41, 29, 7, 254, 40, 29, 7, 254, 39, 29, 7, 254, 38, 29, 7, 254, - 37, 29, 7, 254, 36, 29, 7, 254, 35, 29, 7, 254, 34, 29, 7, 254, 33, 29, - 7, 254, 32, 29, 7, 254, 31, 29, 7, 254, 30, 29, 7, 254, 29, 29, 7, 254, - 28, 29, 7, 254, 27, 29, 7, 254, 26, 29, 7, 254, 25, 29, 7, 254, 24, 29, - 7, 254, 23, 29, 7, 254, 22, 29, 7, 254, 21, 29, 7, 254, 20, 29, 7, 254, - 19, 29, 7, 254, 18, 29, 7, 254, 17, 29, 7, 254, 16, 29, 7, 254, 15, 29, - 7, 254, 14, 29, 7, 254, 13, 29, 7, 254, 12, 29, 7, 254, 11, 29, 7, 254, - 10, 29, 7, 254, 9, 29, 7, 254, 8, 29, 7, 254, 7, 29, 7, 254, 6, 29, 7, - 254, 5, 29, 7, 254, 4, 29, 7, 254, 3, 29, 7, 254, 2, 29, 7, 254, 1, 207, - 186, 211, 57, 207, 1, 29, 7, 254, 0, 29, 7, 253, 255, 29, 7, 253, 254, - 29, 7, 253, 253, 29, 7, 253, 252, 29, 7, 253, 251, 29, 7, 253, 250, 29, - 7, 253, 249, 29, 7, 253, 248, 29, 7, 253, 247, 29, 7, 253, 246, 29, 7, - 253, 245, 171, 29, 7, 253, 244, 29, 7, 253, 243, 29, 7, 253, 242, 29, 7, - 253, 241, 29, 7, 253, 240, 29, 7, 253, 239, 29, 7, 253, 238, 29, 7, 253, - 236, 29, 7, 253, 234, 29, 7, 253, 232, 29, 7, 253, 230, 29, 7, 253, 228, - 29, 7, 253, 226, 29, 7, 253, 224, 29, 7, 253, 222, 29, 7, 253, 220, 29, - 7, 253, 218, 248, 249, 219, 28, 77, 29, 7, 253, 216, 234, 95, 219, 28, - 77, 29, 7, 253, 215, 29, 7, 253, 213, 29, 7, 253, 211, 29, 7, 253, 209, - 29, 7, 253, 207, 29, 7, 253, 205, 29, 7, 253, 203, 29, 7, 253, 201, 29, - 7, 253, 199, 29, 7, 253, 198, 29, 7, 253, 197, 29, 7, 253, 196, 29, 7, - 253, 195, 29, 7, 253, 194, 29, 7, 253, 193, 29, 7, 253, 192, 29, 7, 253, - 191, 29, 7, 253, 190, 29, 7, 253, 189, 29, 7, 253, 188, 29, 7, 253, 187, - 29, 7, 253, 186, 29, 7, 253, 185, 29, 7, 253, 184, 29, 7, 253, 183, 29, - 7, 253, 182, 29, 7, 253, 181, 29, 7, 253, 180, 29, 7, 253, 179, 29, 7, - 253, 178, 29, 7, 253, 177, 29, 7, 253, 176, 29, 7, 253, 175, 29, 7, 253, - 174, 29, 7, 253, 173, 29, 7, 253, 172, 29, 7, 253, 171, 29, 7, 253, 170, - 29, 7, 253, 169, 29, 7, 253, 168, 29, 7, 253, 167, 29, 7, 253, 166, 29, - 7, 253, 165, 29, 7, 253, 164, 29, 7, 253, 163, 29, 7, 253, 162, 29, 7, - 253, 161, 29, 7, 253, 160, 29, 7, 253, 159, 29, 7, 253, 158, 29, 7, 253, - 157, 29, 7, 253, 156, 29, 7, 253, 155, 29, 7, 253, 154, 29, 7, 253, 153, - 29, 7, 253, 152, 29, 7, 253, 151, 29, 7, 253, 150, 29, 7, 253, 149, 29, - 7, 253, 148, 29, 7, 253, 147, 29, 7, 253, 146, 29, 7, 253, 145, 29, 7, - 253, 144, 29, 7, 253, 143, 29, 7, 253, 142, 29, 7, 253, 141, 29, 7, 253, - 140, 29, 7, 253, 139, 29, 7, 253, 138, 29, 7, 253, 137, 29, 7, 253, 136, - 29, 7, 253, 135, 29, 7, 253, 134, 29, 7, 253, 133, 29, 7, 253, 132, 29, - 7, 253, 131, 29, 7, 253, 130, 29, 7, 253, 129, 29, 7, 253, 128, 29, 7, - 253, 127, 29, 7, 253, 126, 29, 7, 253, 125, 29, 7, 253, 124, 29, 7, 253, - 123, 29, 7, 253, 122, 29, 7, 253, 121, 29, 7, 253, 120, 29, 7, 253, 119, - 29, 7, 253, 118, 29, 7, 253, 117, 29, 7, 253, 116, 29, 7, 253, 115, 29, - 7, 253, 114, 29, 7, 253, 113, 29, 7, 253, 112, 29, 7, 253, 111, 29, 7, - 253, 110, 29, 7, 253, 109, 29, 7, 253, 108, 29, 7, 253, 107, 29, 7, 253, - 106, 29, 7, 253, 105, 29, 7, 253, 104, 29, 7, 253, 103, 29, 7, 253, 102, - 29, 7, 253, 101, 29, 7, 253, 100, 29, 7, 253, 99, 29, 7, 253, 98, 29, 7, - 253, 97, 29, 7, 253, 96, 29, 7, 253, 95, 29, 7, 253, 94, 29, 7, 253, 93, - 29, 7, 253, 92, 29, 7, 253, 91, 29, 7, 253, 90, 29, 7, 253, 89, 26, 1, - 209, 218, 214, 1, 216, 142, 26, 1, 209, 218, 231, 173, 232, 166, 26, 1, - 209, 218, 209, 40, 216, 143, 209, 127, 26, 1, 209, 218, 209, 40, 216, - 143, 209, 128, 26, 1, 209, 218, 214, 251, 216, 142, 26, 1, 209, 218, 203, - 0, 26, 1, 209, 218, 198, 124, 216, 142, 26, 1, 209, 218, 212, 47, 216, - 142, 26, 1, 209, 218, 203, 68, 210, 221, 213, 141, 26, 1, 209, 218, 209, - 40, 210, 221, 213, 142, 209, 127, 26, 1, 209, 218, 209, 40, 210, 221, - 213, 142, 209, 128, 26, 1, 209, 218, 217, 131, 26, 1, 209, 218, 197, 95, - 217, 132, 26, 1, 209, 218, 214, 62, 26, 1, 209, 218, 217, 128, 26, 1, - 209, 218, 217, 77, 26, 1, 209, 218, 215, 86, 26, 1, 209, 218, 203, 249, - 26, 1, 209, 218, 212, 187, 26, 1, 209, 218, 221, 234, 26, 1, 209, 218, - 213, 108, 26, 1, 209, 218, 200, 160, 26, 1, 209, 218, 214, 0, 26, 1, 209, - 218, 220, 15, 26, 1, 209, 218, 219, 177, 220, 188, 26, 1, 209, 218, 212, - 197, 216, 150, 26, 1, 209, 218, 217, 135, 26, 1, 209, 218, 210, 98, 26, - 1, 209, 218, 231, 72, 26, 1, 209, 218, 210, 170, 26, 1, 209, 218, 215, - 232, 214, 35, 26, 1, 209, 218, 212, 28, 216, 153, 26, 1, 209, 218, 126, - 191, 195, 214, 244, 26, 1, 209, 218, 231, 73, 26, 1, 209, 218, 212, 197, - 212, 198, 26, 1, 209, 218, 202, 139, 26, 1, 209, 218, 216, 135, 26, 1, - 209, 218, 216, 156, 26, 1, 209, 218, 215, 207, 26, 1, 209, 218, 222, 105, - 26, 1, 209, 218, 210, 221, 219, 225, 26, 1, 209, 218, 214, 163, 219, 225, - 26, 1, 209, 218, 209, 240, 26, 1, 209, 218, 217, 129, 26, 1, 209, 218, - 213, 185, 26, 1, 209, 218, 208, 144, 26, 1, 209, 218, 197, 87, 26, 1, - 209, 218, 218, 221, 26, 1, 209, 218, 202, 17, 26, 1, 209, 218, 199, 58, - 26, 1, 209, 218, 217, 126, 26, 1, 209, 218, 221, 241, 26, 1, 209, 218, - 214, 159, 26, 1, 209, 218, 220, 203, 26, 1, 209, 218, 215, 208, 26, 1, - 209, 218, 202, 252, 26, 1, 209, 218, 219, 20, 26, 1, 209, 218, 232, 239, - 26, 1, 209, 218, 206, 137, 26, 1, 209, 218, 221, 10, 26, 1, 209, 218, - 202, 13, 26, 1, 209, 218, 217, 72, 209, 173, 26, 1, 209, 218, 203, 61, - 26, 1, 209, 218, 212, 196, 26, 1, 209, 218, 203, 42, 212, 208, 191, 203, - 26, 1, 209, 218, 212, 69, 215, 228, 26, 1, 209, 218, 210, 216, 26, 1, - 209, 218, 213, 110, 26, 1, 209, 218, 196, 85, 26, 1, 209, 218, 214, 38, - 26, 1, 209, 218, 217, 125, 26, 1, 209, 218, 213, 153, 26, 1, 209, 218, - 217, 6, 26, 1, 209, 218, 212, 84, 26, 1, 209, 218, 199, 62, 26, 1, 209, - 218, 202, 8, 26, 1, 209, 218, 210, 217, 26, 1, 209, 218, 212, 212, 26, 1, - 209, 218, 217, 133, 26, 1, 209, 218, 212, 81, 26, 1, 209, 218, 222, 66, - 26, 1, 209, 218, 212, 215, 26, 1, 209, 218, 195, 148, 26, 1, 209, 218, - 218, 225, 26, 1, 209, 218, 214, 102, 26, 1, 209, 218, 214, 217, 26, 1, - 209, 218, 217, 5, 26, 1, 209, 217, 212, 210, 26, 1, 209, 217, 197, 95, - 217, 130, 26, 1, 209, 217, 202, 204, 26, 1, 209, 217, 203, 253, 197, 94, - 26, 1, 209, 217, 219, 23, 212, 193, 26, 1, 209, 217, 217, 12, 217, 134, - 26, 1, 209, 217, 221, 150, 26, 1, 209, 217, 192, 43, 26, 1, 209, 217, - 217, 7, 26, 1, 209, 217, 222, 90, 26, 1, 209, 217, 210, 44, 26, 1, 209, - 217, 192, 126, 219, 225, 26, 1, 209, 217, 220, 36, 212, 208, 212, 95, 26, - 1, 209, 217, 212, 190, 203, 87, 26, 1, 209, 217, 214, 130, 213, 156, 26, - 1, 209, 217, 231, 70, 26, 1, 209, 217, 209, 117, 26, 1, 209, 217, 197, - 95, 212, 206, 26, 1, 209, 217, 203, 92, 213, 151, 26, 1, 209, 217, 203, - 88, 26, 1, 209, 217, 216, 143, 199, 61, 26, 1, 209, 217, 216, 250, 217, - 8, 26, 1, 209, 217, 212, 82, 212, 193, 26, 1, 209, 217, 221, 230, 26, 1, - 209, 217, 231, 71, 26, 1, 209, 217, 221, 226, 26, 1, 209, 217, 220, 120, - 26, 1, 209, 217, 210, 101, 26, 1, 209, 217, 195, 77, 26, 1, 209, 217, - 214, 2, 215, 84, 26, 1, 209, 217, 214, 37, 216, 246, 26, 1, 209, 217, - 192, 254, 26, 1, 209, 217, 205, 175, 26, 1, 209, 217, 199, 240, 26, 1, - 209, 217, 216, 155, 26, 1, 209, 217, 214, 21, 26, 1, 209, 217, 214, 22, - 220, 12, 26, 1, 209, 217, 216, 145, 26, 1, 209, 217, 200, 214, 26, 1, - 209, 217, 216, 254, 26, 1, 209, 217, 215, 212, 26, 1, 209, 217, 212, 99, - 26, 1, 209, 217, 208, 148, 26, 1, 209, 217, 216, 154, 214, 39, 26, 1, - 209, 217, 233, 28, 26, 1, 209, 217, 216, 241, 26, 1, 209, 217, 233, 52, - 26, 1, 209, 217, 221, 238, 26, 1, 209, 217, 217, 160, 213, 145, 26, 1, - 209, 217, 217, 160, 213, 121, 26, 1, 209, 217, 219, 176, 26, 1, 209, 217, - 214, 45, 26, 1, 209, 217, 212, 217, 26, 1, 209, 217, 174, 26, 1, 209, - 217, 221, 133, 26, 1, 209, 217, 213, 246, 26, 1, 209, 216, 214, 1, 217, - 132, 26, 1, 209, 216, 212, 46, 26, 1, 209, 216, 191, 203, 26, 1, 209, - 216, 193, 160, 26, 1, 209, 216, 214, 38, 26, 1, 209, 216, 214, 151, 26, - 1, 209, 216, 214, 8, 26, 1, 209, 216, 231, 80, 26, 1, 209, 216, 217, 2, - 26, 1, 209, 216, 231, 180, 26, 1, 209, 216, 212, 71, 216, 21, 216, 157, - 26, 1, 209, 216, 212, 184, 216, 249, 26, 1, 209, 216, 216, 255, 26, 1, - 209, 216, 209, 123, 26, 1, 209, 216, 214, 136, 26, 1, 209, 216, 217, 10, - 247, 156, 26, 1, 209, 216, 221, 228, 26, 1, 209, 216, 231, 81, 26, 1, - 209, 216, 221, 235, 26, 1, 209, 216, 191, 226, 215, 117, 26, 1, 209, 216, - 212, 40, 26, 1, 209, 216, 216, 243, 26, 1, 209, 216, 212, 216, 26, 1, - 209, 216, 216, 249, 26, 1, 209, 216, 192, 44, 26, 1, 209, 216, 221, 18, - 26, 1, 209, 216, 222, 127, 26, 1, 209, 216, 203, 248, 26, 1, 209, 216, - 214, 145, 26, 1, 209, 216, 199, 238, 26, 1, 209, 216, 213, 125, 26, 1, - 209, 216, 198, 124, 191, 207, 26, 1, 209, 216, 200, 247, 26, 1, 209, 216, - 214, 28, 212, 95, 26, 1, 209, 216, 195, 76, 26, 1, 209, 216, 214, 220, - 26, 1, 209, 216, 217, 160, 221, 237, 26, 1, 209, 216, 212, 198, 26, 1, - 209, 216, 214, 23, 26, 1, 209, 216, 220, 16, 26, 1, 209, 216, 216, 251, - 26, 1, 209, 216, 216, 134, 26, 1, 209, 216, 212, 192, 26, 1, 209, 216, - 199, 57, 26, 1, 209, 216, 214, 25, 26, 1, 209, 216, 232, 84, 26, 1, 209, - 216, 214, 150, 26, 1, 209, 216, 212, 218, 26, 1, 209, 216, 212, 214, 26, - 1, 209, 216, 247, 240, 26, 1, 209, 216, 195, 78, 26, 1, 209, 216, 217, 0, - 26, 1, 209, 216, 206, 68, 26, 1, 209, 216, 213, 155, 26, 1, 209, 216, - 220, 35, 26, 1, 209, 216, 198, 121, 26, 1, 209, 216, 212, 200, 213, 246, - 26, 1, 209, 216, 213, 147, 26, 1, 209, 216, 221, 241, 26, 1, 209, 216, - 214, 30, 26, 1, 209, 216, 217, 125, 26, 1, 209, 216, 216, 244, 26, 1, - 209, 216, 218, 225, 26, 1, 209, 216, 220, 188, 26, 1, 209, 216, 213, 153, - 26, 1, 209, 216, 213, 246, 26, 1, 209, 216, 192, 244, 26, 1, 209, 216, - 214, 26, 26, 1, 209, 216, 212, 203, 26, 1, 209, 216, 212, 194, 26, 1, - 209, 216, 220, 205, 213, 110, 26, 1, 209, 216, 212, 201, 26, 1, 209, 216, - 214, 158, 26, 1, 209, 216, 217, 160, 212, 206, 26, 1, 209, 216, 192, 140, - 26, 1, 209, 216, 214, 157, 26, 1, 209, 216, 202, 255, 26, 1, 209, 216, - 203, 251, 26, 1, 209, 216, 216, 252, 26, 1, 209, 216, 217, 132, 26, 1, - 209, 216, 217, 6, 26, 1, 209, 216, 221, 229, 26, 1, 209, 216, 216, 253, - 26, 1, 209, 216, 221, 233, 26, 1, 209, 216, 217, 10, 209, 179, 26, 1, - 209, 216, 191, 186, 26, 1, 209, 216, 213, 143, 26, 1, 209, 216, 216, 80, - 26, 1, 209, 216, 215, 149, 26, 1, 209, 216, 203, 64, 26, 1, 209, 216, - 221, 252, 219, 250, 26, 1, 209, 216, 221, 252, 233, 65, 26, 1, 209, 216, - 214, 60, 26, 1, 209, 216, 214, 217, 26, 1, 209, 216, 219, 94, 26, 1, 209, - 216, 209, 139, 26, 1, 209, 216, 210, 34, 26, 1, 209, 216, 199, 73, 26, 1, - 158, 216, 242, 26, 1, 158, 193, 158, 26, 1, 158, 213, 141, 26, 1, 158, - 216, 142, 26, 1, 158, 213, 139, 26, 1, 158, 219, 139, 26, 1, 158, 213, - 144, 26, 1, 158, 212, 213, 26, 1, 158, 214, 44, 26, 1, 158, 212, 95, 26, - 1, 158, 192, 255, 26, 1, 158, 213, 254, 26, 1, 158, 203, 111, 26, 1, 158, - 214, 9, 26, 1, 158, 221, 236, 26, 1, 158, 199, 59, 26, 1, 158, 203, 90, - 26, 1, 158, 213, 152, 26, 1, 158, 200, 214, 26, 1, 158, 221, 241, 26, 1, - 158, 192, 128, 26, 1, 158, 220, 206, 26, 1, 158, 205, 130, 26, 1, 158, - 216, 147, 26, 1, 158, 214, 149, 26, 1, 158, 217, 95, 26, 1, 158, 216, - 153, 26, 1, 158, 203, 250, 26, 1, 158, 192, 70, 26, 1, 158, 213, 146, 26, - 1, 158, 221, 232, 216, 245, 26, 1, 158, 214, 5, 26, 1, 158, 197, 94, 26, - 1, 158, 231, 90, 26, 1, 158, 213, 251, 26, 1, 158, 233, 29, 26, 1, 158, - 214, 153, 26, 1, 158, 216, 126, 26, 1, 158, 219, 170, 26, 1, 158, 214, - 135, 26, 1, 158, 215, 227, 26, 1, 158, 216, 130, 26, 1, 158, 208, 127, - 26, 1, 158, 216, 128, 26, 1, 158, 216, 144, 26, 1, 158, 218, 208, 26, 1, - 158, 212, 205, 26, 1, 158, 217, 9, 26, 1, 158, 220, 177, 26, 1, 158, 212, - 84, 26, 1, 158, 199, 62, 26, 1, 158, 202, 8, 26, 1, 158, 191, 186, 26, 1, - 158, 221, 233, 26, 1, 158, 207, 162, 26, 1, 158, 199, 120, 26, 1, 158, - 214, 6, 26, 1, 158, 216, 149, 26, 1, 158, 212, 204, 26, 1, 158, 221, 231, - 26, 1, 158, 209, 129, 26, 1, 158, 209, 233, 26, 1, 158, 212, 57, 26, 1, - 158, 219, 176, 26, 1, 158, 214, 45, 26, 1, 158, 216, 146, 26, 1, 158, - 214, 18, 26, 1, 158, 191, 200, 26, 1, 158, 210, 137, 26, 1, 158, 191, - 199, 26, 1, 158, 214, 158, 26, 1, 158, 212, 193, 26, 1, 158, 200, 249, - 26, 1, 158, 220, 210, 26, 1, 158, 214, 34, 26, 1, 158, 214, 3, 26, 1, - 158, 197, 69, 26, 1, 158, 216, 157, 26, 1, 158, 220, 199, 26, 1, 158, - 212, 202, 26, 1, 158, 199, 60, 26, 1, 158, 217, 127, 26, 1, 158, 214, 43, - 26, 1, 158, 219, 169, 26, 1, 158, 214, 24, 26, 1, 158, 212, 207, 26, 1, - 158, 213, 125, 26, 1, 158, 231, 74, 26, 1, 158, 220, 232, 26, 1, 158, - 207, 56, 211, 119, 26, 1, 158, 199, 226, 26, 1, 158, 198, 50, 26, 1, 158, - 212, 81, 26, 1, 158, 206, 195, 26, 1, 158, 219, 227, 26, 1, 158, 216, - 210, 26, 1, 158, 218, 168, 26, 1, 158, 200, 160, 26, 1, 158, 215, 155, - 26, 1, 158, 203, 76, 26, 1, 158, 203, 86, 26, 1, 158, 220, 149, 26, 1, - 158, 212, 178, 26, 1, 158, 203, 5, 26, 1, 158, 212, 195, 26, 1, 158, 210, - 49, 26, 1, 158, 213, 219, 26, 1, 158, 203, 41, 26, 1, 158, 208, 143, 26, - 1, 158, 215, 84, 26, 1, 158, 219, 0, 26, 1, 158, 207, 56, 215, 144, 26, - 1, 158, 198, 193, 26, 1, 158, 212, 181, 26, 1, 158, 217, 10, 175, 26, 1, - 158, 205, 128, 26, 1, 158, 233, 108, 26, 1, 114, 214, 157, 26, 1, 114, - 198, 57, 26, 1, 114, 216, 255, 26, 1, 114, 220, 16, 26, 1, 114, 195, 10, - 26, 1, 114, 219, 6, 26, 1, 114, 210, 220, 26, 1, 114, 202, 21, 26, 1, - 114, 207, 134, 26, 1, 114, 212, 209, 26, 1, 114, 214, 128, 26, 1, 114, - 208, 161, 26, 1, 114, 199, 197, 26, 1, 114, 214, 11, 26, 1, 114, 221, 14, - 26, 1, 114, 192, 247, 26, 1, 114, 205, 50, 26, 1, 114, 214, 35, 26, 1, - 114, 210, 217, 26, 1, 114, 198, 59, 26, 1, 114, 220, 204, 26, 1, 114, - 219, 22, 26, 1, 114, 212, 212, 26, 1, 114, 213, 243, 26, 1, 114, 217, - 133, 26, 1, 114, 214, 4, 26, 1, 114, 213, 242, 26, 1, 114, 212, 211, 26, - 1, 114, 206, 192, 26, 1, 114, 213, 143, 26, 1, 114, 210, 46, 26, 1, 114, - 205, 197, 26, 1, 114, 214, 19, 26, 1, 114, 216, 136, 26, 1, 114, 231, 68, - 26, 1, 114, 214, 7, 26, 1, 114, 213, 154, 26, 1, 114, 217, 71, 26, 1, - 114, 219, 2, 26, 1, 114, 214, 40, 26, 1, 114, 214, 141, 26, 1, 114, 199, - 225, 212, 193, 26, 1, 114, 203, 252, 26, 1, 114, 208, 154, 26, 1, 114, - 214, 161, 202, 30, 26, 1, 114, 214, 27, 212, 95, 26, 1, 114, 192, 29, 26, - 1, 114, 231, 69, 26, 1, 114, 197, 88, 26, 1, 114, 192, 47, 26, 1, 114, - 209, 73, 26, 1, 114, 197, 75, 26, 1, 114, 221, 239, 26, 1, 114, 200, 248, - 26, 1, 114, 199, 61, 26, 1, 114, 195, 79, 26, 1, 114, 193, 100, 26, 1, - 114, 220, 123, 26, 1, 114, 208, 165, 26, 1, 114, 199, 239, 26, 1, 114, - 231, 89, 26, 1, 114, 214, 50, 26, 1, 114, 203, 89, 26, 1, 114, 216, 131, - 26, 1, 114, 217, 3, 26, 1, 114, 212, 44, 26, 1, 114, 213, 106, 26, 1, - 114, 231, 176, 26, 1, 114, 197, 76, 26, 1, 114, 220, 215, 26, 1, 114, - 192, 104, 26, 1, 114, 212, 82, 242, 237, 26, 1, 114, 192, 18, 26, 1, 114, - 216, 148, 26, 1, 114, 214, 146, 26, 1, 114, 209, 174, 26, 1, 114, 191, - 206, 26, 1, 114, 219, 171, 26, 1, 114, 232, 84, 26, 1, 114, 231, 175, 26, - 1, 114, 213, 253, 26, 1, 114, 221, 241, 26, 1, 114, 217, 136, 26, 1, 114, - 214, 10, 26, 1, 114, 231, 75, 26, 1, 114, 233, 109, 26, 1, 114, 212, 182, - 26, 1, 114, 209, 234, 26, 1, 114, 192, 45, 26, 1, 114, 214, 36, 26, 1, - 114, 212, 82, 248, 209, 26, 1, 114, 212, 24, 26, 1, 114, 209, 35, 26, 1, - 114, 216, 80, 26, 1, 114, 232, 82, 26, 1, 114, 214, 244, 26, 1, 114, 215, - 149, 26, 1, 114, 231, 74, 26, 1, 114, 232, 87, 68, 26, 1, 114, 215, 85, - 26, 1, 114, 208, 160, 26, 1, 114, 213, 255, 26, 1, 114, 220, 188, 26, 1, - 114, 209, 171, 26, 1, 114, 212, 196, 26, 1, 114, 192, 46, 26, 1, 114, - 214, 20, 26, 1, 114, 210, 221, 210, 19, 26, 1, 114, 232, 87, 247, 138, - 26, 1, 114, 232, 167, 26, 1, 114, 213, 148, 26, 1, 114, 65, 26, 1, 114, - 198, 50, 26, 1, 114, 74, 26, 1, 114, 68, 26, 1, 114, 220, 14, 26, 1, 114, - 210, 221, 209, 82, 26, 1, 114, 199, 245, 26, 1, 114, 199, 180, 26, 1, - 114, 214, 161, 215, 71, 228, 172, 26, 1, 114, 203, 64, 26, 1, 114, 192, - 42, 26, 1, 114, 213, 236, 26, 1, 114, 191, 211, 26, 1, 114, 191, 244, - 200, 136, 26, 1, 114, 191, 244, 238, 242, 26, 1, 114, 191, 194, 26, 1, - 114, 191, 202, 26, 1, 114, 221, 227, 26, 1, 114, 209, 232, 26, 1, 114, - 213, 149, 234, 49, 26, 1, 114, 208, 156, 26, 1, 114, 192, 253, 26, 1, - 114, 233, 52, 26, 1, 114, 195, 148, 26, 1, 114, 218, 225, 26, 1, 114, - 216, 100, 26, 1, 114, 207, 20, 26, 1, 114, 207, 163, 26, 1, 114, 213, - 235, 26, 1, 114, 214, 68, 26, 1, 114, 203, 56, 26, 1, 114, 203, 41, 26, - 1, 114, 232, 87, 207, 59, 26, 1, 114, 180, 26, 1, 114, 209, 185, 26, 1, - 114, 219, 0, 26, 1, 114, 221, 67, 26, 1, 114, 216, 186, 26, 1, 114, 174, - 26, 1, 114, 217, 68, 26, 1, 114, 199, 63, 26, 1, 114, 221, 166, 26, 1, - 114, 215, 231, 26, 1, 114, 199, 95, 26, 1, 114, 233, 76, 26, 1, 114, 231, - 62, 26, 1, 209, 215, 155, 26, 1, 209, 215, 66, 26, 1, 209, 215, 220, 232, - 26, 1, 209, 215, 234, 188, 26, 1, 209, 215, 207, 84, 26, 1, 209, 215, - 199, 226, 26, 1, 209, 215, 212, 81, 26, 1, 209, 215, 173, 26, 1, 209, - 215, 206, 195, 26, 1, 209, 215, 206, 242, 26, 1, 209, 215, 216, 210, 26, - 1, 209, 215, 199, 245, 26, 1, 209, 215, 214, 160, 26, 1, 209, 215, 213, - 155, 26, 1, 209, 215, 218, 168, 26, 1, 209, 215, 200, 160, 26, 1, 209, - 215, 203, 76, 26, 1, 209, 215, 202, 222, 26, 1, 209, 215, 203, 248, 26, - 1, 209, 215, 220, 149, 26, 1, 209, 215, 221, 241, 26, 1, 209, 215, 212, - 146, 26, 1, 209, 215, 212, 178, 26, 1, 209, 215, 213, 126, 26, 1, 209, - 215, 191, 243, 26, 1, 209, 215, 203, 5, 26, 1, 209, 215, 170, 26, 1, 209, - 215, 212, 215, 26, 1, 209, 215, 209, 232, 26, 1, 209, 215, 212, 195, 26, - 1, 209, 215, 192, 253, 26, 1, 209, 215, 210, 49, 26, 1, 209, 215, 206, - 68, 26, 1, 209, 215, 213, 219, 26, 1, 209, 215, 207, 20, 26, 1, 209, 215, - 221, 251, 26, 1, 209, 215, 213, 252, 26, 1, 209, 215, 214, 47, 26, 1, - 209, 215, 203, 56, 26, 1, 209, 215, 208, 161, 26, 1, 209, 215, 232, 167, - 26, 1, 209, 215, 193, 190, 26, 1, 209, 215, 219, 146, 26, 1, 209, 215, - 219, 0, 26, 1, 209, 215, 221, 67, 26, 1, 209, 215, 217, 1, 26, 1, 209, - 215, 207, 55, 26, 1, 209, 215, 174, 26, 1, 209, 215, 216, 12, 26, 1, 209, - 215, 217, 9, 26, 1, 209, 215, 199, 73, 26, 1, 209, 215, 221, 21, 26, 1, - 209, 215, 205, 150, 26, 1, 209, 215, 193, 248, 215, 159, 1, 190, 190, - 215, 159, 1, 214, 16, 215, 159, 1, 192, 12, 215, 159, 1, 216, 46, 215, - 159, 1, 249, 153, 215, 159, 1, 238, 32, 215, 159, 1, 65, 215, 159, 1, - 209, 211, 215, 159, 1, 221, 209, 215, 159, 1, 230, 22, 215, 159, 1, 238, - 7, 215, 159, 1, 243, 48, 215, 159, 1, 222, 15, 215, 159, 1, 211, 120, - 215, 159, 1, 217, 133, 215, 159, 1, 213, 179, 215, 159, 1, 168, 215, 159, - 1, 211, 87, 215, 159, 1, 74, 215, 159, 1, 206, 162, 215, 159, 1, 203, 81, - 215, 159, 1, 199, 32, 215, 159, 1, 234, 217, 215, 159, 1, 193, 190, 215, - 159, 1, 71, 215, 159, 1, 221, 67, 215, 159, 1, 220, 24, 215, 159, 1, 173, - 215, 159, 1, 230, 80, 215, 159, 1, 207, 1, 215, 159, 1, 199, 110, 215, - 159, 17, 191, 77, 215, 159, 17, 107, 215, 159, 17, 109, 215, 159, 17, - 138, 215, 159, 17, 134, 215, 159, 17, 149, 215, 159, 17, 169, 215, 159, - 17, 175, 215, 159, 17, 171, 215, 159, 17, 178, 215, 159, 237, 238, 215, - 159, 55, 237, 238, 199, 186, 1, 210, 238, 199, 186, 1, 211, 166, 199, - 186, 1, 211, 58, 199, 186, 1, 210, 247, 199, 186, 1, 250, 123, 199, 186, - 1, 252, 63, 199, 186, 1, 251, 37, 199, 186, 1, 250, 133, 199, 186, 1, - 193, 227, 199, 186, 1, 195, 155, 199, 186, 1, 194, 255, 199, 186, 1, 193, - 236, 199, 186, 1, 233, 182, 199, 186, 1, 234, 197, 199, 186, 1, 234, 46, - 199, 186, 1, 233, 221, 199, 186, 1, 223, 41, 199, 186, 1, 228, 28, 199, - 186, 1, 223, 79, 199, 186, 1, 223, 45, 199, 186, 1, 196, 18, 199, 186, 1, - 196, 160, 199, 186, 1, 196, 64, 199, 186, 1, 196, 22, 199, 186, 1, 250, - 134, 199, 186, 1, 250, 138, 199, 186, 1, 250, 136, 199, 186, 1, 250, 135, - 199, 186, 1, 196, 129, 199, 186, 1, 196, 138, 199, 186, 1, 196, 135, 199, - 186, 1, 196, 130, 199, 186, 1, 53, 214, 70, 199, 186, 1, 179, 196, 145, - 199, 186, 1, 203, 40, 196, 143, 199, 186, 1, 203, 40, 250, 135, 199, 186, - 1, 196, 150, 199, 186, 1, 196, 143, 199, 186, 1, 196, 146, 199, 186, 1, - 196, 145, 199, 186, 1, 196, 131, 199, 186, 1, 196, 134, 199, 186, 1, 196, - 133, 199, 186, 1, 196, 132, 199, 186, 1, 215, 63, 199, 186, 1, 216, 238, - 199, 186, 1, 215, 165, 199, 186, 1, 215, 72, 199, 186, 1, 155, 199, 186, - 1, 221, 215, 199, 186, 1, 231, 240, 199, 186, 1, 214, 68, 199, 186, 1, - 188, 199, 186, 1, 170, 199, 186, 1, 193, 190, 199, 186, 1, 168, 199, 186, - 1, 212, 101, 199, 186, 1, 209, 228, 199, 186, 1, 249, 153, 199, 186, 1, - 174, 199, 186, 1, 180, 199, 186, 1, 140, 199, 186, 1, 173, 199, 186, 1, - 228, 164, 199, 186, 1, 190, 190, 199, 186, 1, 238, 32, 199, 186, 1, 165, - 199, 186, 1, 213, 224, 199, 186, 1, 203, 165, 199, 186, 1, 247, 160, 199, - 186, 1, 197, 168, 199, 186, 1, 231, 91, 199, 186, 1, 228, 161, 199, 186, - 1, 199, 49, 199, 186, 1, 192, 220, 199, 186, 1, 233, 109, 199, 186, 1, - 237, 68, 199, 186, 1, 247, 1, 199, 186, 1, 191, 123, 199, 186, 17, 191, - 77, 199, 186, 17, 107, 199, 186, 17, 109, 199, 186, 17, 138, 199, 186, - 17, 134, 199, 186, 17, 149, 199, 186, 17, 169, 199, 186, 17, 175, 199, - 186, 17, 171, 199, 186, 17, 178, 249, 67, 195, 185, 1, 234, 84, 249, 67, - 195, 185, 1, 155, 249, 67, 195, 185, 1, 205, 68, 249, 67, 195, 185, 1, - 233, 109, 249, 67, 195, 185, 1, 217, 4, 249, 67, 195, 185, 1, 192, 30, - 249, 67, 195, 185, 1, 231, 225, 249, 67, 195, 185, 1, 237, 49, 249, 67, - 195, 185, 1, 221, 20, 249, 67, 195, 185, 1, 222, 201, 249, 67, 195, 185, - 1, 228, 124, 249, 67, 195, 185, 1, 193, 190, 249, 67, 195, 185, 1, 191, - 7, 249, 67, 195, 185, 1, 231, 169, 249, 67, 195, 185, 1, 236, 174, 249, - 67, 195, 185, 1, 247, 42, 249, 67, 195, 185, 1, 196, 23, 249, 67, 195, - 185, 1, 159, 249, 67, 195, 185, 1, 249, 153, 249, 67, 195, 185, 1, 193, - 249, 249, 67, 195, 185, 1, 192, 74, 249, 67, 195, 185, 1, 168, 249, 67, - 195, 185, 1, 193, 177, 249, 67, 195, 185, 1, 65, 249, 67, 195, 185, 1, - 74, 249, 67, 195, 185, 1, 211, 87, 249, 67, 195, 185, 1, 66, 249, 67, - 195, 185, 1, 234, 188, 249, 67, 195, 185, 1, 71, 249, 67, 195, 185, 1, - 68, 249, 67, 195, 185, 33, 137, 198, 79, 249, 67, 195, 185, 33, 130, 198, - 79, 249, 67, 195, 185, 33, 216, 87, 198, 79, 249, 67, 195, 185, 33, 218, - 238, 198, 79, 249, 67, 195, 185, 33, 229, 133, 198, 79, 249, 67, 195, - 185, 232, 80, 201, 63, 145, 90, 18, 222, 12, 145, 90, 18, 222, 8, 145, - 90, 18, 221, 155, 145, 90, 18, 221, 118, 145, 90, 18, 222, 41, 145, 90, - 18, 222, 38, 145, 90, 18, 220, 216, 145, 90, 18, 220, 185, 145, 90, 18, - 222, 14, 145, 90, 18, 221, 225, 145, 90, 18, 222, 101, 145, 90, 18, 222, - 98, 145, 90, 18, 221, 40, 145, 90, 18, 221, 37, 145, 90, 18, 222, 34, - 145, 90, 18, 222, 31, 145, 90, 18, 220, 218, 145, 90, 18, 220, 217, 145, - 90, 18, 221, 60, 145, 90, 18, 221, 25, 145, 90, 18, 221, 157, 145, 90, - 18, 221, 156, 145, 90, 18, 222, 117, 145, 90, 18, 222, 37, 145, 90, 18, - 220, 175, 145, 90, 18, 220, 166, 145, 90, 18, 222, 126, 145, 90, 18, 222, - 118, 145, 90, 120, 195, 160, 145, 90, 120, 212, 185, 145, 90, 120, 220, - 0, 145, 90, 120, 230, 2, 145, 90, 120, 213, 82, 145, 90, 120, 207, 125, - 145, 90, 120, 213, 109, 145, 90, 120, 208, 69, 145, 90, 120, 192, 91, - 145, 90, 120, 229, 108, 145, 90, 120, 217, 25, 145, 90, 120, 243, 131, - 145, 90, 120, 214, 165, 145, 90, 120, 229, 44, 145, 90, 120, 209, 91, - 145, 90, 120, 212, 191, 145, 90, 120, 214, 205, 145, 90, 120, 250, 163, - 145, 90, 120, 192, 216, 145, 90, 120, 247, 76, 145, 90, 87, 243, 17, 197, - 85, 145, 90, 87, 243, 17, 202, 46, 145, 90, 87, 243, 17, 221, 243, 145, - 90, 87, 243, 17, 221, 198, 145, 90, 87, 243, 17, 200, 246, 145, 90, 87, - 243, 17, 229, 2, 145, 90, 87, 243, 17, 199, 165, 145, 90, 3, 195, 5, 198, - 238, 145, 90, 3, 195, 5, 197, 156, 247, 33, 145, 90, 3, 243, 17, 243, - 120, 145, 90, 3, 195, 5, 199, 10, 145, 90, 3, 195, 5, 233, 49, 145, 90, - 3, 192, 171, 212, 179, 145, 90, 3, 192, 171, 207, 3, 145, 90, 3, 192, - 171, 198, 32, 145, 90, 3, 192, 171, 233, 90, 145, 90, 3, 195, 5, 205, 44, - 145, 90, 3, 216, 209, 200, 250, 145, 90, 3, 195, 5, 212, 231, 145, 90, 3, - 228, 31, 192, 111, 145, 90, 3, 192, 215, 145, 90, 3, 243, 17, 197, 143, - 206, 144, 145, 90, 17, 191, 77, 145, 90, 17, 107, 145, 90, 17, 109, 145, - 90, 17, 138, 145, 90, 17, 134, 145, 90, 17, 149, 145, 90, 17, 169, 145, - 90, 17, 175, 145, 90, 17, 171, 145, 90, 17, 178, 145, 90, 31, 199, 90, - 145, 90, 31, 228, 138, 145, 90, 31, 199, 96, 198, 228, 145, 90, 31, 216, - 47, 145, 90, 31, 228, 141, 216, 47, 145, 90, 31, 199, 96, 248, 169, 145, - 90, 31, 197, 227, 145, 90, 3, 195, 5, 218, 220, 145, 90, 3, 192, 168, - 145, 90, 3, 229, 103, 145, 90, 3, 198, 255, 229, 103, 145, 90, 3, 190, - 236, 199, 43, 145, 90, 3, 229, 28, 145, 90, 3, 212, 245, 145, 90, 3, 192, - 206, 145, 90, 3, 212, 183, 145, 90, 3, 250, 146, 145, 90, 3, 197, 7, 247, - 32, 145, 90, 3, 216, 209, 197, 159, 145, 90, 3, 199, 166, 145, 90, 3, - 218, 253, 145, 90, 3, 215, 103, 145, 90, 3, 243, 17, 230, 76, 218, 196, - 212, 189, 212, 188, 145, 90, 3, 243, 17, 238, 194, 197, 150, 145, 90, 3, - 243, 17, 197, 5, 145, 90, 3, 243, 17, 197, 6, 243, 36, 145, 90, 3, 243, - 17, 208, 159, 237, 206, 145, 90, 3, 243, 17, 212, 238, 198, 41, 145, 90, - 242, 244, 3, 197, 154, 145, 90, 242, 244, 3, 192, 76, 145, 90, 242, 244, - 3, 219, 90, 145, 90, 242, 244, 3, 219, 254, 145, 90, 242, 244, 3, 192, - 167, 145, 90, 242, 244, 3, 221, 41, 145, 90, 242, 244, 3, 229, 254, 145, - 90, 242, 244, 3, 215, 147, 145, 90, 242, 244, 3, 198, 239, 145, 90, 242, - 244, 3, 197, 165, 145, 90, 242, 244, 3, 209, 225, 145, 90, 242, 244, 3, - 221, 213, 145, 90, 242, 244, 3, 230, 64, 145, 90, 242, 244, 3, 195, 182, - 145, 90, 242, 244, 3, 233, 86, 145, 90, 242, 244, 3, 192, 118, 145, 90, - 242, 244, 3, 197, 137, 145, 90, 242, 244, 3, 220, 170, 145, 90, 242, 244, - 3, 193, 237, 216, 218, 6, 1, 218, 168, 216, 218, 6, 1, 206, 8, 216, 218, - 6, 1, 196, 12, 216, 218, 6, 1, 193, 224, 216, 218, 6, 1, 250, 176, 216, - 218, 6, 1, 191, 166, 216, 218, 6, 1, 221, 22, 216, 218, 6, 1, 210, 236, - 216, 218, 6, 1, 200, 43, 216, 218, 6, 1, 232, 51, 216, 218, 6, 1, 233, - 175, 216, 218, 6, 1, 68, 216, 218, 6, 1, 222, 152, 216, 218, 6, 1, 65, - 216, 218, 6, 1, 223, 35, 216, 218, 6, 1, 71, 216, 218, 6, 1, 250, 120, - 216, 218, 6, 1, 247, 193, 216, 218, 6, 1, 66, 216, 218, 6, 1, 191, 225, - 216, 218, 6, 1, 172, 216, 218, 6, 1, 208, 104, 216, 218, 6, 1, 228, 169, - 216, 218, 6, 1, 212, 103, 216, 218, 6, 1, 192, 235, 216, 218, 6, 1, 238, - 127, 216, 218, 6, 1, 211, 151, 216, 218, 6, 1, 215, 61, 216, 218, 6, 1, - 146, 216, 218, 6, 1, 74, 216, 218, 6, 1, 251, 236, 216, 218, 6, 1, 192, - 159, 216, 218, 2, 1, 218, 168, 216, 218, 2, 1, 206, 8, 216, 218, 2, 1, - 196, 12, 216, 218, 2, 1, 193, 224, 216, 218, 2, 1, 250, 176, 216, 218, 2, - 1, 191, 166, 216, 218, 2, 1, 221, 22, 216, 218, 2, 1, 210, 236, 216, 218, - 2, 1, 200, 43, 216, 218, 2, 1, 232, 51, 216, 218, 2, 1, 233, 175, 216, - 218, 2, 1, 68, 216, 218, 2, 1, 222, 152, 216, 218, 2, 1, 65, 216, 218, 2, - 1, 223, 35, 216, 218, 2, 1, 71, 216, 218, 2, 1, 250, 120, 216, 218, 2, 1, - 247, 193, 216, 218, 2, 1, 66, 216, 218, 2, 1, 191, 225, 216, 218, 2, 1, - 172, 216, 218, 2, 1, 208, 104, 216, 218, 2, 1, 228, 169, 216, 218, 2, 1, - 212, 103, 216, 218, 2, 1, 192, 235, 216, 218, 2, 1, 238, 127, 216, 218, - 2, 1, 211, 151, 216, 218, 2, 1, 215, 61, 216, 218, 2, 1, 146, 216, 218, - 2, 1, 74, 216, 218, 2, 1, 251, 236, 216, 218, 2, 1, 192, 159, 216, 218, - 17, 191, 77, 216, 218, 17, 107, 216, 218, 17, 109, 216, 218, 17, 138, - 216, 218, 17, 134, 216, 218, 17, 149, 216, 218, 17, 169, 216, 218, 17, - 175, 216, 218, 17, 171, 216, 218, 17, 178, 216, 218, 31, 199, 95, 216, - 218, 31, 234, 127, 216, 218, 31, 197, 37, 216, 218, 31, 198, 251, 216, - 218, 31, 232, 122, 216, 218, 31, 233, 19, 216, 218, 31, 202, 130, 216, - 218, 31, 203, 244, 216, 218, 31, 234, 161, 216, 218, 31, 213, 171, 216, - 218, 17, 91, 251, 157, 20, 216, 218, 17, 105, 251, 157, 20, 216, 218, 17, - 115, 251, 157, 20, 216, 218, 242, 74, 216, 218, 232, 80, 201, 63, 216, - 218, 16, 251, 221, 216, 218, 233, 216, 211, 136, 121, 1, 168, 121, 1, - 249, 153, 121, 1, 11, 168, 121, 1, 209, 110, 121, 1, 174, 121, 1, 216, - 103, 121, 1, 251, 14, 174, 121, 1, 233, 109, 121, 1, 195, 188, 121, 1, - 195, 71, 121, 1, 190, 190, 121, 1, 238, 32, 121, 1, 11, 197, 132, 121, 1, - 11, 190, 190, 121, 1, 197, 132, 121, 1, 237, 191, 121, 1, 180, 121, 1, - 213, 224, 121, 1, 11, 213, 79, 121, 1, 251, 14, 180, 121, 1, 213, 79, - 121, 1, 213, 65, 121, 1, 173, 121, 1, 218, 182, 121, 1, 219, 159, 121, 1, - 219, 148, 121, 1, 198, 112, 121, 1, 236, 183, 121, 1, 198, 104, 121, 1, - 236, 182, 121, 1, 155, 121, 1, 231, 240, 121, 1, 11, 155, 121, 1, 208, - 96, 121, 1, 208, 72, 121, 1, 214, 68, 121, 1, 214, 17, 121, 1, 251, 14, - 214, 68, 121, 1, 140, 121, 1, 192, 220, 121, 1, 231, 91, 121, 1, 231, 66, - 121, 1, 197, 142, 121, 1, 235, 18, 121, 1, 212, 101, 121, 1, 212, 83, - 121, 1, 197, 157, 121, 1, 235, 29, 121, 1, 11, 197, 157, 121, 1, 11, 235, - 29, 121, 1, 207, 82, 197, 157, 121, 1, 203, 165, 121, 1, 201, 175, 121, - 1, 191, 71, 121, 1, 190, 253, 121, 1, 197, 168, 121, 1, 235, 35, 121, 1, - 11, 197, 168, 121, 1, 188, 121, 1, 191, 123, 121, 1, 190, 254, 121, 1, - 190, 224, 121, 1, 190, 204, 121, 1, 251, 14, 190, 224, 121, 1, 190, 196, - 121, 1, 190, 203, 121, 1, 193, 190, 121, 1, 251, 245, 121, 1, 229, 177, - 121, 1, 248, 32, 121, 1, 200, 125, 121, 1, 235, 19, 121, 1, 199, 145, - 121, 1, 197, 161, 121, 1, 206, 71, 121, 3, 120, 52, 164, 121, 1, 214, - 212, 121, 3, 250, 199, 121, 3, 207, 82, 195, 18, 121, 3, 207, 82, 250, - 199, 121, 18, 3, 65, 121, 18, 3, 252, 206, 121, 18, 3, 251, 241, 121, 18, - 3, 251, 132, 121, 18, 3, 251, 122, 121, 18, 3, 74, 121, 18, 3, 211, 87, - 121, 18, 3, 193, 48, 121, 18, 3, 193, 224, 121, 18, 3, 71, 121, 18, 3, - 234, 103, 121, 18, 3, 234, 88, 121, 18, 3, 211, 147, 121, 18, 3, 68, 121, - 18, 3, 228, 35, 121, 18, 3, 228, 34, 121, 18, 3, 228, 33, 121, 18, 3, - 223, 88, 121, 18, 3, 223, 226, 121, 18, 3, 223, 199, 121, 18, 3, 223, 49, - 121, 18, 3, 223, 136, 121, 18, 3, 66, 121, 18, 3, 196, 168, 121, 18, 3, - 196, 167, 121, 18, 3, 196, 166, 121, 18, 3, 196, 30, 121, 18, 3, 196, - 148, 121, 18, 3, 196, 97, 121, 18, 3, 192, 159, 121, 18, 3, 192, 33, 121, - 18, 3, 252, 25, 121, 18, 3, 252, 21, 121, 18, 3, 234, 26, 121, 18, 3, - 206, 113, 234, 26, 121, 18, 3, 234, 34, 121, 18, 3, 206, 113, 234, 34, - 121, 18, 3, 251, 236, 121, 18, 3, 234, 166, 121, 18, 3, 250, 163, 121, - 18, 3, 211, 19, 121, 18, 3, 215, 61, 121, 18, 3, 214, 70, 121, 18, 3, - 196, 81, 121, 18, 3, 191, 205, 121, 18, 3, 211, 141, 121, 18, 3, 211, - 148, 121, 18, 3, 193, 239, 121, 18, 3, 223, 204, 121, 18, 3, 234, 217, - 121, 18, 3, 223, 86, 121, 18, 3, 196, 139, 121, 163, 183, 121, 163, 198, - 54, 183, 121, 163, 58, 121, 163, 60, 121, 1, 198, 77, 121, 1, 198, 76, - 121, 1, 198, 75, 121, 1, 198, 74, 121, 1, 198, 73, 121, 1, 198, 72, 121, - 1, 198, 71, 121, 1, 207, 82, 198, 78, 121, 1, 207, 82, 198, 77, 121, 1, - 207, 82, 198, 75, 121, 1, 207, 82, 198, 74, 121, 1, 207, 82, 198, 73, - 121, 1, 207, 82, 198, 71, 19, 223, 51, 77, 46, 223, 51, 77, 39, 243, 80, - 228, 251, 77, 39, 243, 80, 223, 51, 77, 41, 2, 27, 233, 3, 195, 57, 251, - 157, 207, 107, 87, 247, 160, 195, 57, 251, 157, 207, 107, 87, 213, 223, - 19, 242, 63, 19, 242, 62, 19, 242, 61, 19, 242, 60, 19, 242, 59, 19, 242, - 58, 19, 242, 57, 19, 242, 56, 19, 242, 55, 19, 242, 54, 19, 242, 53, 19, - 242, 52, 19, 242, 51, 19, 242, 50, 19, 242, 49, 19, 242, 48, 19, 242, 47, - 19, 242, 46, 19, 242, 45, 19, 242, 44, 19, 242, 43, 19, 242, 42, 19, 242, - 41, 19, 242, 40, 19, 242, 39, 19, 242, 38, 19, 242, 37, 19, 242, 36, 19, - 242, 35, 19, 242, 34, 19, 242, 33, 19, 242, 32, 19, 242, 31, 19, 242, 30, - 19, 242, 29, 19, 242, 28, 19, 242, 27, 19, 242, 26, 19, 242, 25, 19, 242, - 24, 19, 242, 23, 19, 242, 22, 19, 242, 21, 19, 242, 20, 19, 242, 19, 19, - 242, 18, 19, 242, 17, 19, 242, 16, 19, 242, 15, 19, 242, 14, 19, 242, 13, - 19, 242, 12, 19, 242, 11, 19, 242, 10, 19, 242, 9, 19, 242, 8, 19, 242, - 7, 19, 242, 6, 19, 242, 5, 19, 242, 4, 19, 242, 3, 19, 242, 2, 19, 242, - 1, 19, 242, 0, 19, 241, 255, 19, 241, 254, 19, 241, 253, 19, 241, 252, - 19, 241, 251, 19, 241, 250, 19, 241, 249, 19, 241, 248, 19, 241, 247, 19, - 241, 246, 19, 241, 245, 19, 241, 244, 19, 241, 243, 19, 241, 242, 19, - 241, 241, 19, 241, 240, 19, 241, 239, 19, 241, 238, 19, 241, 237, 19, - 241, 236, 19, 241, 235, 19, 241, 234, 19, 241, 233, 19, 241, 232, 19, - 241, 231, 19, 241, 230, 19, 241, 229, 19, 241, 228, 19, 241, 227, 19, - 241, 226, 19, 241, 225, 19, 241, 224, 19, 241, 223, 19, 241, 222, 19, - 241, 221, 19, 241, 220, 19, 241, 219, 19, 241, 218, 19, 241, 217, 19, - 241, 216, 19, 241, 215, 19, 241, 214, 19, 241, 213, 19, 241, 212, 19, - 241, 211, 19, 241, 210, 19, 241, 209, 19, 241, 208, 19, 241, 207, 19, - 241, 206, 19, 241, 205, 19, 241, 204, 19, 241, 203, 19, 241, 202, 19, - 241, 201, 19, 241, 200, 19, 241, 199, 19, 241, 198, 19, 241, 197, 19, - 241, 196, 19, 241, 195, 19, 241, 194, 19, 241, 193, 19, 241, 192, 19, - 241, 191, 19, 241, 190, 19, 241, 189, 19, 241, 188, 19, 241, 187, 19, - 241, 186, 19, 241, 185, 19, 241, 184, 19, 241, 183, 19, 241, 182, 19, - 241, 181, 19, 241, 180, 19, 241, 179, 19, 241, 178, 19, 241, 177, 19, - 241, 176, 19, 241, 175, 19, 241, 174, 19, 241, 173, 19, 241, 172, 19, - 241, 171, 19, 241, 170, 19, 241, 169, 19, 241, 168, 19, 241, 167, 19, - 241, 166, 19, 241, 165, 19, 241, 164, 19, 241, 163, 19, 241, 162, 19, - 241, 161, 19, 241, 160, 19, 241, 159, 19, 241, 158, 19, 241, 157, 19, - 241, 156, 19, 241, 155, 19, 241, 154, 19, 241, 153, 19, 241, 152, 19, - 241, 151, 19, 241, 150, 19, 241, 149, 19, 241, 148, 19, 241, 147, 19, - 241, 146, 19, 241, 145, 19, 241, 144, 19, 241, 143, 19, 241, 142, 19, - 241, 141, 19, 241, 140, 19, 241, 139, 19, 241, 138, 19, 241, 137, 19, - 241, 136, 19, 241, 135, 19, 241, 134, 19, 241, 133, 19, 241, 132, 19, - 241, 131, 19, 241, 130, 19, 241, 129, 19, 241, 128, 19, 241, 127, 19, - 241, 126, 19, 241, 125, 19, 241, 124, 19, 241, 123, 19, 241, 122, 19, - 241, 121, 19, 241, 120, 19, 241, 119, 19, 241, 118, 19, 241, 117, 19, - 241, 116, 19, 241, 115, 19, 241, 114, 19, 241, 113, 19, 241, 112, 19, - 241, 111, 19, 241, 110, 19, 241, 109, 19, 241, 108, 19, 241, 107, 19, - 241, 106, 19, 241, 105, 19, 241, 104, 19, 241, 103, 19, 241, 102, 19, - 241, 101, 19, 241, 100, 19, 241, 99, 19, 241, 98, 19, 241, 97, 19, 241, - 96, 19, 241, 95, 19, 241, 94, 19, 241, 93, 19, 241, 92, 19, 241, 91, 19, - 241, 90, 19, 241, 89, 19, 241, 88, 19, 241, 87, 19, 241, 86, 19, 241, 85, - 19, 241, 84, 19, 241, 83, 19, 241, 82, 19, 241, 81, 19, 241, 80, 19, 241, - 79, 19, 241, 78, 19, 241, 77, 19, 241, 76, 19, 241, 75, 19, 241, 74, 19, - 241, 73, 19, 241, 72, 19, 241, 71, 19, 241, 70, 19, 241, 69, 19, 241, 68, - 19, 241, 67, 19, 241, 66, 19, 241, 65, 19, 241, 64, 19, 241, 63, 19, 241, - 62, 19, 241, 61, 19, 241, 60, 19, 241, 59, 19, 241, 58, 19, 241, 57, 19, - 241, 56, 19, 241, 55, 19, 241, 54, 19, 241, 53, 19, 241, 52, 19, 241, 51, - 19, 241, 50, 19, 241, 49, 19, 241, 48, 19, 241, 47, 19, 241, 46, 19, 241, - 45, 19, 241, 44, 19, 241, 43, 19, 241, 42, 19, 241, 41, 19, 241, 40, 19, - 241, 39, 19, 241, 38, 19, 241, 37, 19, 241, 36, 19, 241, 35, 19, 241, 34, - 19, 241, 33, 19, 241, 32, 19, 241, 31, 19, 241, 30, 19, 241, 29, 19, 241, - 28, 19, 241, 27, 19, 241, 26, 19, 241, 25, 19, 241, 24, 19, 241, 23, 19, - 241, 22, 19, 241, 21, 19, 241, 20, 19, 241, 19, 19, 241, 18, 19, 241, 17, - 19, 241, 16, 19, 241, 15, 19, 241, 14, 19, 241, 13, 19, 241, 12, 19, 241, - 11, 19, 241, 10, 19, 241, 9, 19, 241, 8, 19, 241, 7, 19, 241, 6, 19, 241, - 5, 19, 241, 4, 19, 241, 3, 19, 241, 2, 19, 241, 1, 19, 241, 0, 19, 240, - 255, 19, 240, 254, 19, 240, 253, 19, 240, 252, 19, 240, 251, 19, 240, - 250, 19, 240, 249, 19, 240, 248, 19, 240, 247, 19, 240, 246, 19, 240, - 245, 19, 240, 244, 19, 240, 243, 19, 240, 242, 19, 240, 241, 19, 240, - 240, 19, 240, 239, 19, 240, 238, 19, 240, 237, 19, 240, 236, 19, 240, - 235, 19, 240, 234, 19, 240, 233, 19, 240, 232, 19, 240, 231, 19, 240, - 230, 19, 240, 229, 19, 240, 228, 19, 240, 227, 19, 240, 226, 19, 240, - 225, 19, 240, 224, 19, 240, 223, 19, 240, 222, 19, 240, 221, 19, 240, - 220, 19, 240, 219, 19, 240, 218, 19, 240, 217, 19, 240, 216, 19, 240, - 215, 19, 240, 214, 19, 240, 213, 19, 240, 212, 19, 240, 211, 19, 240, - 210, 19, 240, 209, 19, 240, 208, 19, 240, 207, 19, 240, 206, 19, 240, - 205, 19, 240, 204, 19, 240, 203, 19, 240, 202, 19, 240, 201, 19, 240, - 200, 19, 240, 199, 19, 240, 198, 19, 240, 197, 19, 240, 196, 19, 240, - 195, 19, 240, 194, 19, 240, 193, 19, 240, 192, 19, 240, 191, 19, 240, - 190, 19, 240, 189, 19, 240, 188, 19, 240, 187, 19, 240, 186, 19, 240, - 185, 19, 240, 184, 19, 240, 183, 19, 240, 182, 19, 240, 181, 19, 240, - 180, 19, 240, 179, 19, 240, 178, 19, 240, 177, 19, 240, 176, 19, 240, - 175, 19, 240, 174, 19, 240, 173, 19, 240, 172, 19, 240, 171, 19, 240, - 170, 19, 240, 169, 19, 240, 168, 19, 240, 167, 19, 240, 166, 19, 240, - 165, 19, 240, 164, 19, 240, 163, 19, 240, 162, 19, 240, 161, 19, 240, - 160, 19, 240, 159, 19, 240, 158, 19, 240, 157, 19, 240, 156, 19, 240, - 155, 19, 240, 154, 19, 240, 153, 19, 240, 152, 19, 240, 151, 19, 240, - 150, 19, 240, 149, 19, 240, 148, 19, 240, 147, 19, 240, 146, 19, 240, - 145, 19, 240, 144, 19, 240, 143, 19, 240, 142, 19, 240, 141, 19, 240, - 140, 19, 240, 139, 19, 240, 138, 19, 240, 137, 19, 240, 136, 19, 240, - 135, 19, 240, 134, 19, 240, 133, 19, 240, 132, 19, 240, 131, 19, 240, - 130, 19, 240, 129, 19, 240, 128, 19, 240, 127, 19, 240, 126, 19, 240, - 125, 19, 240, 124, 19, 240, 123, 19, 240, 122, 19, 240, 121, 19, 240, - 120, 19, 240, 119, 19, 240, 118, 19, 240, 117, 19, 240, 116, 19, 240, - 115, 19, 240, 114, 19, 240, 113, 19, 240, 112, 19, 240, 111, 19, 240, - 110, 19, 240, 109, 19, 240, 108, 19, 240, 107, 19, 240, 106, 19, 240, - 105, 19, 240, 104, 19, 240, 103, 19, 240, 102, 19, 240, 101, 19, 240, - 100, 19, 240, 99, 19, 240, 98, 19, 240, 97, 19, 240, 96, 19, 240, 95, 19, - 240, 94, 19, 240, 93, 19, 240, 92, 19, 240, 91, 19, 240, 90, 19, 240, 89, - 19, 240, 88, 19, 240, 87, 19, 240, 86, 19, 240, 85, 19, 240, 84, 19, 240, - 83, 19, 240, 82, 19, 240, 81, 19, 240, 80, 19, 240, 79, 19, 240, 78, 19, - 240, 77, 19, 240, 76, 19, 240, 75, 19, 240, 74, 19, 240, 73, 19, 240, 72, - 19, 240, 71, 19, 240, 70, 19, 240, 69, 19, 240, 68, 19, 240, 67, 19, 240, - 66, 19, 240, 65, 19, 240, 64, 19, 240, 63, 19, 240, 62, 19, 240, 61, 19, - 240, 60, 19, 240, 59, 19, 240, 58, 19, 240, 57, 19, 240, 56, 19, 240, 55, - 19, 240, 54, 19, 240, 53, 19, 240, 52, 19, 240, 51, 19, 240, 50, 19, 240, - 49, 19, 240, 48, 19, 240, 47, 19, 240, 46, 19, 240, 45, 19, 240, 44, 19, - 240, 43, 19, 240, 42, 19, 240, 41, 19, 240, 40, 19, 240, 39, 19, 240, 38, - 19, 240, 37, 19, 240, 36, 19, 240, 35, 19, 240, 34, 19, 240, 33, 19, 240, - 32, 19, 240, 31, 19, 240, 30, 19, 240, 29, 19, 240, 28, 19, 240, 27, 19, - 240, 26, 19, 240, 25, 19, 240, 24, 19, 240, 23, 19, 240, 22, 19, 240, 21, - 19, 240, 20, 19, 240, 19, 19, 240, 18, 19, 240, 17, 19, 240, 16, 19, 240, - 15, 19, 240, 14, 19, 240, 13, 19, 240, 12, 19, 240, 11, 19, 240, 10, 19, - 240, 9, 19, 240, 8, 19, 240, 7, 19, 240, 6, 19, 240, 5, 19, 240, 4, 19, - 240, 3, 19, 240, 2, 19, 240, 1, 19, 240, 0, 19, 239, 255, 19, 239, 254, - 19, 239, 253, 19, 239, 252, 19, 239, 251, 19, 239, 250, 19, 239, 249, 19, - 239, 248, 19, 239, 247, 19, 239, 246, 19, 239, 245, 19, 239, 244, 19, - 239, 243, 19, 239, 242, 19, 239, 241, 19, 239, 240, 19, 239, 239, 19, - 239, 238, 19, 239, 237, 19, 239, 236, 19, 239, 235, 19, 239, 234, 19, - 239, 233, 19, 239, 232, 19, 239, 231, 19, 239, 230, 19, 239, 229, 19, - 239, 228, 19, 239, 227, 19, 239, 226, 19, 239, 225, 19, 239, 224, 19, - 239, 223, 19, 239, 222, 19, 239, 221, 19, 239, 220, 19, 239, 219, 19, - 239, 218, 19, 239, 217, 19, 239, 216, 19, 239, 215, 19, 239, 214, 19, - 239, 213, 19, 239, 212, 19, 239, 211, 19, 239, 210, 19, 239, 209, 19, - 239, 208, 19, 239, 207, 19, 239, 206, 19, 239, 205, 19, 239, 204, 19, - 239, 203, 19, 239, 202, 19, 239, 201, 19, 239, 200, 19, 239, 199, 19, - 239, 198, 19, 239, 197, 19, 239, 196, 19, 239, 195, 19, 239, 194, 19, - 239, 193, 19, 239, 192, 19, 239, 191, 19, 239, 190, 19, 239, 189, 19, - 239, 188, 19, 239, 187, 19, 239, 186, 19, 239, 185, 19, 239, 184, 19, - 239, 183, 19, 239, 182, 19, 239, 181, 19, 239, 180, 19, 239, 179, 19, - 239, 178, 19, 239, 177, 19, 239, 176, 19, 239, 175, 19, 239, 174, 19, - 239, 173, 19, 239, 172, 19, 239, 171, 19, 239, 170, 19, 239, 169, 19, - 239, 168, 19, 239, 167, 19, 239, 166, 19, 239, 165, 19, 239, 164, 19, - 239, 163, 19, 239, 162, 19, 239, 161, 19, 239, 160, 19, 239, 159, 19, - 239, 158, 19, 239, 157, 19, 239, 156, 19, 239, 155, 19, 239, 154, 19, - 239, 153, 19, 239, 152, 19, 239, 151, 19, 239, 150, 19, 239, 149, 19, - 239, 148, 19, 239, 147, 19, 239, 146, 19, 239, 145, 19, 239, 144, 19, - 239, 143, 19, 239, 142, 19, 239, 141, 19, 239, 140, 19, 239, 139, 19, - 239, 138, 19, 239, 137, 19, 239, 136, 19, 239, 135, 19, 239, 134, 19, - 239, 133, 19, 239, 132, 19, 239, 131, 19, 239, 130, 19, 239, 129, 19, - 239, 128, 19, 239, 127, 19, 239, 126, 19, 239, 125, 19, 239, 124, 19, - 239, 123, 19, 239, 122, 19, 239, 121, 19, 239, 120, 19, 239, 119, 19, - 239, 118, 19, 239, 117, 19, 239, 116, 19, 239, 115, 19, 239, 114, 19, - 239, 113, 19, 239, 112, 19, 239, 111, 19, 239, 110, 19, 239, 109, 19, - 239, 108, 19, 239, 107, 19, 239, 106, 19, 239, 105, 19, 239, 104, 19, - 239, 103, 19, 239, 102, 19, 239, 101, 19, 239, 100, 19, 239, 99, 19, 239, - 98, 19, 239, 97, 19, 239, 96, 19, 239, 95, 19, 239, 94, 19, 239, 93, 19, - 239, 92, 19, 239, 91, 19, 239, 90, 19, 239, 89, 19, 239, 88, 19, 239, 87, - 19, 239, 86, 19, 239, 85, 19, 239, 84, 19, 239, 83, 19, 239, 82, 19, 239, - 81, 19, 239, 80, 19, 239, 79, 19, 239, 78, 19, 239, 77, 19, 239, 76, 19, - 239, 75, 19, 239, 74, 19, 239, 73, 19, 239, 72, 19, 239, 71, 19, 239, 70, - 19, 239, 69, 19, 239, 68, 19, 239, 67, 19, 239, 66, 19, 239, 65, 19, 239, - 64, 41, 2, 27, 246, 238, 41, 2, 27, 246, 237, 41, 2, 27, 246, 236, 41, 2, - 27, 246, 235, 41, 2, 27, 246, 234, 41, 2, 27, 246, 233, 41, 2, 27, 246, - 232, 41, 2, 27, 246, 231, 41, 2, 27, 246, 230, 41, 2, 27, 246, 229, 41, - 2, 27, 246, 228, 41, 2, 27, 246, 227, 41, 2, 27, 246, 226, 41, 2, 27, + 191, 126, 14, 7, 191, 125, 14, 7, 252, 207, 14, 7, 252, 206, 14, 7, 252, + 205, 14, 7, 252, 204, 14, 7, 252, 203, 14, 7, 252, 202, 14, 7, 252, 201, + 14, 7, 252, 200, 14, 7, 252, 199, 14, 7, 252, 198, 14, 7, 252, 197, 14, + 7, 252, 196, 14, 7, 252, 195, 14, 7, 252, 194, 14, 7, 252, 193, 14, 7, + 252, 192, 14, 7, 252, 191, 14, 7, 252, 190, 14, 7, 252, 189, 14, 7, 252, + 188, 14, 7, 252, 187, 14, 7, 252, 186, 14, 7, 252, 185, 14, 7, 252, 184, + 14, 7, 252, 183, 14, 7, 252, 182, 14, 7, 252, 181, 14, 7, 252, 180, 14, + 7, 252, 179, 14, 7, 252, 178, 14, 7, 252, 177, 14, 7, 252, 176, 14, 7, + 252, 175, 14, 7, 252, 174, 14, 7, 195, 241, 14, 7, 81, 222, 198, 14, 7, + 228, 243, 222, 198, 14, 7, 223, 122, 250, 185, 198, 54, 201, 98, 14, 7, + 223, 122, 250, 185, 248, 79, 201, 98, 14, 7, 223, 122, 250, 185, 198, 54, + 234, 96, 14, 7, 223, 122, 250, 185, 248, 79, 234, 96, 14, 7, 211, 2, 216, + 86, 14, 7, 248, 251, 205, 44, 14, 7, 234, 97, 205, 44, 14, 7, 223, 122, + 250, 185, 216, 86, 14, 7, 223, 122, 250, 185, 198, 53, 14, 7, 223, 122, + 250, 185, 248, 78, 14, 7, 248, 251, 234, 100, 14, 7, 234, 97, 234, 100, + 14, 7, 248, 251, 193, 166, 234, 100, 14, 7, 234, 97, 193, 166, 234, 100, + 14, 7, 216, 29, 228, 191, 14, 7, 232, 82, 248, 134, 14, 7, 132, 248, 134, + 14, 7, 218, 253, 56, 14, 7, 132, 218, 253, 56, 14, 7, 199, 200, 218, 253, + 56, 14, 7, 193, 78, 218, 253, 56, 14, 7, 52, 237, 251, 250, 185, 198, 54, + 201, 98, 14, 7, 52, 237, 251, 250, 185, 248, 79, 201, 98, 14, 7, 52, 237, + 251, 250, 185, 201, 98, 14, 7, 52, 237, 251, 250, 185, 198, 54, 234, 96, + 14, 7, 52, 237, 251, 250, 185, 198, 53, 14, 7, 52, 237, 251, 250, 185, + 248, 79, 201, 99, 23, 198, 54, 234, 96, 14, 7, 52, 237, 251, 250, 185, + 201, 99, 23, 198, 53, 14, 7, 52, 237, 251, 250, 185, 248, 79, 234, 96, + 14, 7, 52, 237, 251, 250, 185, 198, 54, 201, 99, 23, 248, 79, 234, 96, + 14, 7, 52, 237, 251, 250, 185, 248, 78, 14, 7, 52, 237, 251, 250, 185, + 201, 99, 23, 248, 78, 14, 7, 52, 237, 251, 250, 185, 234, 96, 14, 7, 52, + 237, 251, 250, 185, 198, 54, 23, 234, 96, 14, 7, 52, 237, 251, 250, 185, + 248, 79, 23, 234, 96, 14, 7, 52, 237, 250, 29, 7, 255, 201, 29, 7, 255, + 200, 29, 7, 255, 199, 29, 7, 255, 198, 29, 7, 255, 197, 29, 7, 255, 195, + 29, 7, 255, 192, 29, 7, 255, 191, 29, 7, 255, 190, 29, 7, 255, 189, 29, + 7, 255, 188, 29, 7, 255, 187, 29, 7, 255, 186, 29, 7, 255, 185, 29, 7, + 255, 184, 29, 7, 255, 182, 29, 7, 255, 181, 29, 7, 255, 180, 29, 7, 255, + 178, 29, 7, 255, 177, 29, 7, 255, 176, 29, 7, 255, 175, 29, 7, 255, 174, + 29, 7, 255, 173, 29, 7, 255, 172, 29, 7, 255, 171, 29, 7, 255, 170, 29, + 7, 255, 169, 29, 7, 255, 168, 29, 7, 255, 167, 29, 7, 255, 165, 29, 7, + 255, 164, 29, 7, 255, 163, 29, 7, 255, 162, 29, 7, 255, 160, 29, 7, 255, + 159, 29, 7, 255, 158, 29, 7, 255, 157, 29, 7, 255, 156, 29, 7, 255, 155, + 29, 7, 255, 154, 29, 7, 255, 153, 29, 7, 255, 152, 29, 7, 255, 150, 29, + 7, 255, 149, 29, 7, 255, 148, 29, 7, 255, 146, 29, 7, 255, 144, 29, 7, + 255, 143, 29, 7, 255, 142, 29, 7, 255, 141, 29, 7, 255, 140, 29, 7, 255, + 139, 29, 7, 255, 138, 29, 7, 255, 137, 29, 7, 255, 136, 29, 7, 255, 135, + 29, 7, 255, 134, 29, 7, 255, 133, 29, 7, 255, 132, 29, 7, 255, 131, 29, + 7, 255, 130, 29, 7, 255, 129, 29, 7, 255, 128, 29, 7, 255, 127, 29, 7, + 255, 126, 29, 7, 255, 125, 29, 7, 255, 124, 29, 7, 255, 123, 29, 7, 255, + 122, 29, 7, 255, 121, 29, 7, 255, 120, 29, 7, 255, 119, 29, 7, 255, 118, + 29, 7, 255, 117, 29, 7, 255, 116, 29, 7, 255, 115, 29, 7, 255, 114, 29, + 7, 255, 113, 29, 7, 255, 112, 29, 7, 255, 111, 29, 7, 255, 110, 29, 7, + 255, 109, 29, 7, 255, 108, 29, 7, 255, 107, 29, 7, 255, 106, 29, 7, 255, + 105, 29, 7, 255, 104, 29, 7, 255, 103, 29, 7, 255, 102, 29, 7, 255, 101, + 29, 7, 255, 100, 29, 7, 255, 99, 29, 7, 255, 98, 29, 7, 255, 97, 29, 7, + 255, 96, 29, 7, 255, 95, 29, 7, 255, 94, 29, 7, 255, 93, 29, 7, 255, 92, + 29, 7, 255, 91, 29, 7, 255, 90, 29, 7, 255, 89, 29, 7, 255, 88, 29, 7, + 255, 87, 29, 7, 255, 86, 29, 7, 255, 85, 29, 7, 255, 84, 29, 7, 255, 83, + 29, 7, 255, 82, 29, 7, 255, 81, 29, 7, 255, 80, 29, 7, 255, 78, 29, 7, + 255, 77, 29, 7, 255, 76, 29, 7, 255, 75, 29, 7, 255, 74, 29, 7, 255, 73, + 29, 7, 255, 72, 29, 7, 255, 71, 29, 7, 255, 70, 29, 7, 255, 69, 29, 7, + 255, 68, 29, 7, 255, 67, 29, 7, 255, 66, 29, 7, 255, 65, 29, 7, 255, 64, + 29, 7, 255, 63, 29, 7, 255, 62, 29, 7, 255, 61, 29, 7, 255, 60, 29, 7, + 255, 59, 29, 7, 255, 58, 29, 7, 255, 57, 29, 7, 255, 56, 29, 7, 255, 55, + 29, 7, 255, 54, 29, 7, 255, 53, 29, 7, 255, 52, 29, 7, 255, 51, 29, 7, + 255, 50, 29, 7, 255, 49, 29, 7, 255, 48, 29, 7, 255, 47, 29, 7, 255, 46, + 29, 7, 255, 45, 29, 7, 255, 43, 29, 7, 255, 42, 29, 7, 255, 41, 29, 7, + 255, 40, 29, 7, 255, 39, 29, 7, 255, 38, 29, 7, 255, 37, 29, 7, 255, 36, + 29, 7, 255, 35, 29, 7, 255, 34, 29, 7, 255, 33, 29, 7, 255, 32, 29, 7, + 255, 30, 29, 7, 255, 29, 29, 7, 255, 28, 29, 7, 255, 27, 29, 7, 255, 26, + 29, 7, 255, 25, 29, 7, 255, 24, 29, 7, 255, 23, 29, 7, 255, 22, 29, 7, + 255, 21, 29, 7, 255, 20, 29, 7, 255, 19, 29, 7, 255, 18, 29, 7, 255, 17, + 29, 7, 255, 16, 29, 7, 255, 15, 29, 7, 255, 14, 29, 7, 255, 13, 29, 7, + 255, 12, 29, 7, 255, 11, 29, 7, 255, 10, 29, 7, 255, 9, 29, 7, 255, 8, + 29, 7, 255, 7, 29, 7, 255, 6, 29, 7, 255, 5, 29, 7, 255, 4, 29, 7, 255, + 3, 29, 7, 255, 2, 29, 7, 255, 1, 29, 7, 255, 0, 29, 7, 254, 255, 29, 7, + 254, 254, 29, 7, 254, 253, 29, 7, 254, 252, 29, 7, 254, 251, 29, 7, 254, + 250, 29, 7, 254, 249, 29, 7, 254, 248, 29, 7, 254, 247, 29, 7, 254, 246, + 29, 7, 254, 245, 29, 7, 254, 244, 29, 7, 254, 243, 29, 7, 254, 242, 29, + 7, 254, 241, 29, 7, 254, 240, 29, 7, 254, 239, 29, 7, 254, 238, 29, 7, + 254, 237, 29, 7, 254, 236, 29, 7, 254, 235, 29, 7, 254, 234, 29, 7, 254, + 233, 29, 7, 254, 232, 29, 7, 254, 231, 29, 7, 254, 230, 29, 7, 254, 229, + 29, 7, 254, 228, 29, 7, 254, 227, 29, 7, 254, 226, 29, 7, 254, 225, 29, + 7, 254, 224, 29, 7, 254, 223, 29, 7, 254, 222, 29, 7, 254, 221, 29, 7, + 254, 220, 29, 7, 254, 219, 29, 7, 254, 218, 29, 7, 254, 216, 29, 7, 254, + 215, 29, 7, 254, 214, 29, 7, 254, 213, 29, 7, 254, 212, 29, 7, 254, 211, + 29, 7, 254, 210, 29, 7, 254, 209, 29, 7, 254, 208, 29, 7, 254, 207, 29, + 7, 254, 206, 29, 7, 254, 205, 29, 7, 254, 204, 29, 7, 254, 203, 29, 7, + 254, 202, 29, 7, 254, 201, 29, 7, 254, 200, 29, 7, 254, 199, 29, 7, 254, + 198, 29, 7, 254, 197, 29, 7, 254, 196, 29, 7, 254, 195, 29, 7, 254, 194, + 29, 7, 254, 193, 29, 7, 254, 192, 29, 7, 254, 191, 29, 7, 254, 190, 29, + 7, 254, 189, 29, 7, 254, 188, 29, 7, 254, 187, 29, 7, 254, 186, 29, 7, + 254, 185, 29, 7, 254, 184, 29, 7, 254, 183, 29, 7, 254, 182, 29, 7, 254, + 181, 29, 7, 254, 180, 29, 7, 254, 179, 29, 7, 254, 178, 29, 7, 254, 177, + 29, 7, 254, 176, 29, 7, 254, 175, 29, 7, 254, 174, 29, 7, 254, 173, 29, + 7, 254, 172, 29, 7, 254, 171, 29, 7, 254, 170, 29, 7, 254, 169, 29, 7, + 254, 168, 29, 7, 254, 167, 29, 7, 254, 166, 29, 7, 254, 165, 29, 7, 254, + 164, 29, 7, 254, 163, 29, 7, 254, 162, 29, 7, 254, 161, 29, 7, 254, 160, + 29, 7, 254, 159, 29, 7, 254, 158, 29, 7, 254, 157, 29, 7, 254, 156, 29, + 7, 254, 155, 29, 7, 254, 154, 29, 7, 254, 153, 29, 7, 254, 152, 29, 7, + 254, 151, 29, 7, 254, 150, 29, 7, 254, 149, 29, 7, 254, 148, 29, 7, 254, + 147, 29, 7, 254, 146, 29, 7, 254, 145, 29, 7, 254, 144, 29, 7, 254, 143, + 29, 7, 254, 142, 29, 7, 254, 141, 29, 7, 254, 140, 29, 7, 254, 139, 29, + 7, 254, 138, 29, 7, 254, 137, 29, 7, 254, 136, 29, 7, 254, 135, 29, 7, + 254, 134, 29, 7, 254, 133, 29, 7, 254, 132, 29, 7, 254, 131, 29, 7, 254, + 130, 29, 7, 254, 129, 29, 7, 254, 128, 29, 7, 254, 127, 29, 7, 254, 126, + 29, 7, 254, 125, 29, 7, 254, 124, 29, 7, 254, 123, 29, 7, 254, 122, 29, + 7, 254, 121, 29, 7, 254, 120, 29, 7, 254, 119, 29, 7, 254, 118, 29, 7, + 254, 117, 29, 7, 254, 116, 29, 7, 254, 115, 29, 7, 254, 114, 29, 7, 254, + 113, 29, 7, 254, 112, 29, 7, 254, 111, 29, 7, 254, 110, 29, 7, 254, 109, + 29, 7, 254, 108, 29, 7, 254, 107, 29, 7, 254, 106, 29, 7, 254, 104, 29, + 7, 254, 103, 29, 7, 254, 102, 29, 7, 254, 101, 29, 7, 254, 100, 29, 7, + 254, 99, 29, 7, 254, 98, 29, 7, 254, 97, 29, 7, 254, 96, 29, 7, 254, 95, + 29, 7, 254, 94, 29, 7, 254, 91, 29, 7, 254, 90, 29, 7, 254, 89, 29, 7, + 254, 88, 29, 7, 254, 84, 29, 7, 254, 83, 29, 7, 254, 82, 29, 7, 254, 81, + 29, 7, 254, 80, 29, 7, 254, 79, 29, 7, 254, 78, 29, 7, 254, 77, 29, 7, + 254, 76, 29, 7, 254, 75, 29, 7, 254, 74, 29, 7, 254, 73, 29, 7, 254, 72, + 29, 7, 254, 71, 29, 7, 254, 70, 29, 7, 254, 69, 29, 7, 254, 68, 29, 7, + 254, 67, 29, 7, 254, 66, 29, 7, 254, 64, 29, 7, 254, 63, 29, 7, 254, 62, + 29, 7, 254, 61, 29, 7, 254, 60, 29, 7, 254, 59, 29, 7, 254, 58, 29, 7, + 254, 57, 29, 7, 254, 56, 29, 7, 254, 55, 29, 7, 254, 54, 29, 7, 254, 53, + 29, 7, 254, 52, 29, 7, 254, 51, 29, 7, 254, 50, 29, 7, 254, 49, 29, 7, + 254, 48, 29, 7, 254, 47, 29, 7, 254, 46, 29, 7, 254, 45, 29, 7, 254, 44, + 29, 7, 254, 43, 29, 7, 254, 42, 29, 7, 254, 41, 29, 7, 254, 40, 29, 7, + 254, 39, 29, 7, 254, 38, 29, 7, 254, 37, 29, 7, 254, 36, 29, 7, 254, 35, + 29, 7, 254, 34, 29, 7, 254, 33, 29, 7, 254, 32, 29, 7, 254, 31, 29, 7, + 254, 30, 29, 7, 254, 29, 29, 7, 254, 28, 29, 7, 254, 27, 29, 7, 254, 26, + 29, 7, 254, 25, 29, 7, 254, 24, 29, 7, 254, 23, 29, 7, 254, 22, 29, 7, + 254, 21, 29, 7, 254, 20, 29, 7, 254, 19, 29, 7, 254, 18, 29, 7, 254, 17, + 29, 7, 254, 16, 29, 7, 254, 15, 29, 7, 254, 14, 29, 7, 254, 13, 29, 7, + 254, 12, 29, 7, 254, 11, 29, 7, 254, 10, 29, 7, 254, 9, 29, 7, 254, 8, + 29, 7, 254, 7, 29, 7, 254, 6, 29, 7, 254, 5, 29, 7, 254, 4, 29, 7, 254, + 3, 207, 188, 211, 59, 207, 2, 29, 7, 254, 2, 29, 7, 254, 1, 29, 7, 254, + 0, 29, 7, 253, 255, 29, 7, 253, 254, 29, 7, 253, 253, 29, 7, 253, 252, + 29, 7, 253, 251, 29, 7, 253, 250, 29, 7, 253, 249, 29, 7, 253, 248, 29, + 7, 253, 247, 171, 29, 7, 253, 246, 29, 7, 253, 245, 29, 7, 253, 244, 29, + 7, 253, 243, 29, 7, 253, 242, 29, 7, 253, 241, 29, 7, 253, 240, 29, 7, + 253, 238, 29, 7, 253, 236, 29, 7, 253, 234, 29, 7, 253, 232, 29, 7, 253, + 230, 29, 7, 253, 228, 29, 7, 253, 226, 29, 7, 253, 224, 29, 7, 253, 222, + 29, 7, 253, 220, 248, 251, 219, 30, 77, 29, 7, 253, 218, 234, 97, 219, + 30, 77, 29, 7, 253, 217, 29, 7, 253, 215, 29, 7, 253, 213, 29, 7, 253, + 211, 29, 7, 253, 209, 29, 7, 253, 207, 29, 7, 253, 205, 29, 7, 253, 203, + 29, 7, 253, 201, 29, 7, 253, 200, 29, 7, 253, 199, 29, 7, 253, 198, 29, + 7, 253, 197, 29, 7, 253, 196, 29, 7, 253, 195, 29, 7, 253, 194, 29, 7, + 253, 193, 29, 7, 253, 192, 29, 7, 253, 191, 29, 7, 253, 190, 29, 7, 253, + 189, 29, 7, 253, 188, 29, 7, 253, 187, 29, 7, 253, 186, 29, 7, 253, 185, + 29, 7, 253, 184, 29, 7, 253, 183, 29, 7, 253, 182, 29, 7, 253, 181, 29, + 7, 253, 180, 29, 7, 253, 179, 29, 7, 253, 178, 29, 7, 253, 177, 29, 7, + 253, 176, 29, 7, 253, 175, 29, 7, 253, 174, 29, 7, 253, 173, 29, 7, 253, + 172, 29, 7, 253, 171, 29, 7, 253, 170, 29, 7, 253, 169, 29, 7, 253, 168, + 29, 7, 253, 167, 29, 7, 253, 166, 29, 7, 253, 165, 29, 7, 253, 164, 29, + 7, 253, 163, 29, 7, 253, 162, 29, 7, 253, 161, 29, 7, 253, 160, 29, 7, + 253, 159, 29, 7, 253, 158, 29, 7, 253, 157, 29, 7, 253, 156, 29, 7, 253, + 155, 29, 7, 253, 154, 29, 7, 253, 153, 29, 7, 253, 152, 29, 7, 253, 151, + 29, 7, 253, 150, 29, 7, 253, 149, 29, 7, 253, 148, 29, 7, 253, 147, 29, + 7, 253, 146, 29, 7, 253, 145, 29, 7, 253, 144, 29, 7, 253, 143, 29, 7, + 253, 142, 29, 7, 253, 141, 29, 7, 253, 140, 29, 7, 253, 139, 29, 7, 253, + 138, 29, 7, 253, 137, 29, 7, 253, 136, 29, 7, 253, 135, 29, 7, 253, 134, + 29, 7, 253, 133, 29, 7, 253, 132, 29, 7, 253, 131, 29, 7, 253, 130, 29, + 7, 253, 129, 29, 7, 253, 128, 29, 7, 253, 127, 29, 7, 253, 126, 29, 7, + 253, 125, 29, 7, 253, 124, 29, 7, 253, 123, 29, 7, 253, 122, 29, 7, 253, + 121, 29, 7, 253, 120, 29, 7, 253, 119, 29, 7, 253, 118, 29, 7, 253, 117, + 29, 7, 253, 116, 29, 7, 253, 115, 29, 7, 253, 114, 29, 7, 253, 113, 29, + 7, 253, 112, 29, 7, 253, 111, 29, 7, 253, 110, 29, 7, 253, 109, 29, 7, + 253, 108, 29, 7, 253, 107, 29, 7, 253, 106, 29, 7, 253, 105, 29, 7, 253, + 104, 29, 7, 253, 103, 29, 7, 253, 102, 29, 7, 253, 101, 29, 7, 253, 100, + 29, 7, 253, 99, 29, 7, 253, 98, 29, 7, 253, 97, 29, 7, 253, 96, 29, 7, + 253, 95, 29, 7, 253, 94, 29, 7, 253, 93, 29, 7, 253, 92, 29, 7, 253, 91, + 26, 1, 209, 220, 214, 3, 216, 144, 26, 1, 209, 220, 231, 175, 232, 168, + 26, 1, 209, 220, 209, 42, 216, 145, 209, 129, 26, 1, 209, 220, 209, 42, + 216, 145, 209, 130, 26, 1, 209, 220, 214, 253, 216, 144, 26, 1, 209, 220, + 203, 1, 26, 1, 209, 220, 198, 124, 216, 144, 26, 1, 209, 220, 212, 49, + 216, 144, 26, 1, 209, 220, 203, 69, 210, 223, 213, 143, 26, 1, 209, 220, + 209, 42, 210, 223, 213, 144, 209, 129, 26, 1, 209, 220, 209, 42, 210, + 223, 213, 144, 209, 130, 26, 1, 209, 220, 217, 133, 26, 1, 209, 220, 197, + 95, 217, 134, 26, 1, 209, 220, 214, 64, 26, 1, 209, 220, 217, 130, 26, 1, + 209, 220, 217, 79, 26, 1, 209, 220, 215, 88, 26, 1, 209, 220, 203, 250, + 26, 1, 209, 220, 212, 189, 26, 1, 209, 220, 221, 236, 26, 1, 209, 220, + 213, 110, 26, 1, 209, 220, 200, 160, 26, 1, 209, 220, 214, 2, 26, 1, 209, + 220, 220, 17, 26, 1, 209, 220, 219, 179, 220, 190, 26, 1, 209, 220, 212, + 199, 216, 152, 26, 1, 209, 220, 217, 137, 26, 1, 209, 220, 210, 100, 26, + 1, 209, 220, 231, 74, 26, 1, 209, 220, 210, 172, 26, 1, 209, 220, 215, + 234, 214, 37, 26, 1, 209, 220, 212, 30, 216, 155, 26, 1, 209, 220, 126, + 191, 195, 214, 246, 26, 1, 209, 220, 231, 75, 26, 1, 209, 220, 212, 199, + 212, 200, 26, 1, 209, 220, 202, 140, 26, 1, 209, 220, 216, 137, 26, 1, + 209, 220, 216, 158, 26, 1, 209, 220, 215, 209, 26, 1, 209, 220, 222, 107, + 26, 1, 209, 220, 210, 223, 219, 227, 26, 1, 209, 220, 214, 165, 219, 227, + 26, 1, 209, 220, 209, 242, 26, 1, 209, 220, 217, 131, 26, 1, 209, 220, + 213, 187, 26, 1, 209, 220, 208, 146, 26, 1, 209, 220, 197, 87, 26, 1, + 209, 220, 218, 223, 26, 1, 209, 220, 202, 18, 26, 1, 209, 220, 199, 58, + 26, 1, 209, 220, 217, 128, 26, 1, 209, 220, 221, 243, 26, 1, 209, 220, + 214, 161, 26, 1, 209, 220, 220, 205, 26, 1, 209, 220, 215, 210, 26, 1, + 209, 220, 202, 253, 26, 1, 209, 220, 219, 22, 26, 1, 209, 220, 232, 241, + 26, 1, 209, 220, 206, 138, 26, 1, 209, 220, 221, 12, 26, 1, 209, 220, + 202, 14, 26, 1, 209, 220, 217, 74, 209, 175, 26, 1, 209, 220, 203, 62, + 26, 1, 209, 220, 212, 198, 26, 1, 209, 220, 203, 43, 212, 210, 191, 203, + 26, 1, 209, 220, 212, 71, 215, 230, 26, 1, 209, 220, 210, 218, 26, 1, + 209, 220, 213, 112, 26, 1, 209, 220, 196, 85, 26, 1, 209, 220, 214, 40, + 26, 1, 209, 220, 217, 127, 26, 1, 209, 220, 213, 155, 26, 1, 209, 220, + 217, 8, 26, 1, 209, 220, 212, 86, 26, 1, 209, 220, 199, 62, 26, 1, 209, + 220, 202, 9, 26, 1, 209, 220, 210, 219, 26, 1, 209, 220, 212, 214, 26, 1, + 209, 220, 217, 135, 26, 1, 209, 220, 212, 83, 26, 1, 209, 220, 222, 68, + 26, 1, 209, 220, 212, 217, 26, 1, 209, 220, 195, 148, 26, 1, 209, 220, + 218, 227, 26, 1, 209, 220, 214, 104, 26, 1, 209, 220, 214, 219, 26, 1, + 209, 220, 217, 7, 26, 1, 209, 219, 212, 212, 26, 1, 209, 219, 197, 95, + 217, 132, 26, 1, 209, 219, 202, 205, 26, 1, 209, 219, 203, 254, 197, 94, + 26, 1, 209, 219, 219, 25, 212, 195, 26, 1, 209, 219, 217, 14, 217, 136, + 26, 1, 209, 219, 221, 152, 26, 1, 209, 219, 192, 43, 26, 1, 209, 219, + 217, 9, 26, 1, 209, 219, 222, 92, 26, 1, 209, 219, 210, 46, 26, 1, 209, + 219, 192, 126, 219, 227, 26, 1, 209, 219, 220, 38, 212, 210, 212, 97, 26, + 1, 209, 219, 212, 192, 203, 88, 26, 1, 209, 219, 214, 132, 213, 158, 26, + 1, 209, 219, 231, 72, 26, 1, 209, 219, 209, 119, 26, 1, 209, 219, 197, + 95, 212, 208, 26, 1, 209, 219, 203, 93, 213, 153, 26, 1, 209, 219, 203, + 89, 26, 1, 209, 219, 216, 145, 199, 61, 26, 1, 209, 219, 216, 252, 217, + 10, 26, 1, 209, 219, 212, 84, 212, 195, 26, 1, 209, 219, 221, 232, 26, 1, + 209, 219, 231, 73, 26, 1, 209, 219, 221, 228, 26, 1, 209, 219, 220, 122, + 26, 1, 209, 219, 210, 103, 26, 1, 209, 219, 195, 77, 26, 1, 209, 219, + 214, 4, 215, 86, 26, 1, 209, 219, 214, 39, 216, 248, 26, 1, 209, 219, + 192, 254, 26, 1, 209, 219, 205, 176, 26, 1, 209, 219, 199, 240, 26, 1, + 209, 219, 216, 157, 26, 1, 209, 219, 214, 23, 26, 1, 209, 219, 214, 24, + 220, 14, 26, 1, 209, 219, 216, 147, 26, 1, 209, 219, 200, 214, 26, 1, + 209, 219, 217, 0, 26, 1, 209, 219, 215, 214, 26, 1, 209, 219, 212, 101, + 26, 1, 209, 219, 208, 150, 26, 1, 209, 219, 216, 156, 214, 41, 26, 1, + 209, 219, 233, 30, 26, 1, 209, 219, 216, 243, 26, 1, 209, 219, 233, 54, + 26, 1, 209, 219, 221, 240, 26, 1, 209, 219, 217, 162, 213, 147, 26, 1, + 209, 219, 217, 162, 213, 123, 26, 1, 209, 219, 219, 178, 26, 1, 209, 219, + 214, 47, 26, 1, 209, 219, 212, 219, 26, 1, 209, 219, 174, 26, 1, 209, + 219, 221, 135, 26, 1, 209, 219, 213, 248, 26, 1, 209, 218, 214, 3, 217, + 134, 26, 1, 209, 218, 212, 48, 26, 1, 209, 218, 191, 203, 26, 1, 209, + 218, 193, 160, 26, 1, 209, 218, 214, 40, 26, 1, 209, 218, 214, 153, 26, + 1, 209, 218, 214, 10, 26, 1, 209, 218, 231, 82, 26, 1, 209, 218, 217, 4, + 26, 1, 209, 218, 231, 182, 26, 1, 209, 218, 212, 73, 216, 23, 216, 159, + 26, 1, 209, 218, 212, 186, 216, 251, 26, 1, 209, 218, 217, 1, 26, 1, 209, + 218, 209, 125, 26, 1, 209, 218, 214, 138, 26, 1, 209, 218, 217, 12, 247, + 158, 26, 1, 209, 218, 221, 230, 26, 1, 209, 218, 231, 83, 26, 1, 209, + 218, 221, 237, 26, 1, 209, 218, 191, 226, 215, 119, 26, 1, 209, 218, 212, + 42, 26, 1, 209, 218, 216, 245, 26, 1, 209, 218, 212, 218, 26, 1, 209, + 218, 216, 251, 26, 1, 209, 218, 192, 44, 26, 1, 209, 218, 221, 20, 26, 1, + 209, 218, 222, 129, 26, 1, 209, 218, 203, 249, 26, 1, 209, 218, 214, 147, + 26, 1, 209, 218, 199, 238, 26, 1, 209, 218, 213, 127, 26, 1, 209, 218, + 198, 124, 191, 207, 26, 1, 209, 218, 200, 248, 26, 1, 209, 218, 214, 30, + 212, 97, 26, 1, 209, 218, 195, 76, 26, 1, 209, 218, 214, 222, 26, 1, 209, + 218, 217, 162, 221, 239, 26, 1, 209, 218, 212, 200, 26, 1, 209, 218, 214, + 25, 26, 1, 209, 218, 220, 18, 26, 1, 209, 218, 216, 253, 26, 1, 209, 218, + 216, 136, 26, 1, 209, 218, 212, 194, 26, 1, 209, 218, 199, 57, 26, 1, + 209, 218, 214, 27, 26, 1, 209, 218, 232, 86, 26, 1, 209, 218, 214, 152, + 26, 1, 209, 218, 212, 220, 26, 1, 209, 218, 212, 216, 26, 1, 209, 218, + 247, 242, 26, 1, 209, 218, 195, 78, 26, 1, 209, 218, 217, 2, 26, 1, 209, + 218, 206, 69, 26, 1, 209, 218, 213, 157, 26, 1, 209, 218, 220, 37, 26, 1, + 209, 218, 198, 121, 26, 1, 209, 218, 212, 202, 213, 248, 26, 1, 209, 218, + 213, 149, 26, 1, 209, 218, 221, 243, 26, 1, 209, 218, 214, 32, 26, 1, + 209, 218, 217, 127, 26, 1, 209, 218, 216, 246, 26, 1, 209, 218, 218, 227, + 26, 1, 209, 218, 220, 190, 26, 1, 209, 218, 213, 155, 26, 1, 209, 218, + 213, 248, 26, 1, 209, 218, 192, 244, 26, 1, 209, 218, 214, 28, 26, 1, + 209, 218, 212, 205, 26, 1, 209, 218, 212, 196, 26, 1, 209, 218, 220, 207, + 213, 112, 26, 1, 209, 218, 212, 203, 26, 1, 209, 218, 214, 160, 26, 1, + 209, 218, 217, 162, 212, 208, 26, 1, 209, 218, 192, 140, 26, 1, 209, 218, + 214, 159, 26, 1, 209, 218, 203, 0, 26, 1, 209, 218, 203, 252, 26, 1, 209, + 218, 216, 254, 26, 1, 209, 218, 217, 134, 26, 1, 209, 218, 217, 8, 26, 1, + 209, 218, 221, 231, 26, 1, 209, 218, 216, 255, 26, 1, 209, 218, 221, 235, + 26, 1, 209, 218, 217, 12, 209, 181, 26, 1, 209, 218, 191, 186, 26, 1, + 209, 218, 213, 145, 26, 1, 209, 218, 216, 82, 26, 1, 209, 218, 215, 151, + 26, 1, 209, 218, 203, 65, 26, 1, 209, 218, 221, 254, 219, 252, 26, 1, + 209, 218, 221, 254, 233, 67, 26, 1, 209, 218, 214, 62, 26, 1, 209, 218, + 214, 219, 26, 1, 209, 218, 219, 96, 26, 1, 209, 218, 209, 141, 26, 1, + 209, 218, 210, 36, 26, 1, 209, 218, 199, 73, 26, 1, 158, 216, 244, 26, 1, + 158, 193, 158, 26, 1, 158, 213, 143, 26, 1, 158, 216, 144, 26, 1, 158, + 213, 141, 26, 1, 158, 219, 141, 26, 1, 158, 213, 146, 26, 1, 158, 212, + 215, 26, 1, 158, 214, 46, 26, 1, 158, 212, 97, 26, 1, 158, 192, 255, 26, + 1, 158, 214, 0, 26, 1, 158, 203, 112, 26, 1, 158, 214, 11, 26, 1, 158, + 221, 238, 26, 1, 158, 199, 59, 26, 1, 158, 203, 91, 26, 1, 158, 213, 154, + 26, 1, 158, 200, 214, 26, 1, 158, 221, 243, 26, 1, 158, 192, 128, 26, 1, + 158, 220, 208, 26, 1, 158, 205, 131, 26, 1, 158, 216, 149, 26, 1, 158, + 214, 151, 26, 1, 158, 217, 97, 26, 1, 158, 216, 155, 26, 1, 158, 203, + 251, 26, 1, 158, 192, 70, 26, 1, 158, 213, 148, 26, 1, 158, 221, 234, + 216, 247, 26, 1, 158, 214, 7, 26, 1, 158, 197, 94, 26, 1, 158, 231, 92, + 26, 1, 158, 213, 253, 26, 1, 158, 233, 31, 26, 1, 158, 214, 155, 26, 1, + 158, 216, 128, 26, 1, 158, 219, 172, 26, 1, 158, 214, 137, 26, 1, 158, + 215, 229, 26, 1, 158, 216, 132, 26, 1, 158, 208, 129, 26, 1, 158, 216, + 130, 26, 1, 158, 216, 146, 26, 1, 158, 218, 210, 26, 1, 158, 212, 207, + 26, 1, 158, 217, 11, 26, 1, 158, 220, 179, 26, 1, 158, 212, 86, 26, 1, + 158, 199, 62, 26, 1, 158, 202, 9, 26, 1, 158, 191, 186, 26, 1, 158, 221, + 235, 26, 1, 158, 207, 164, 26, 1, 158, 199, 120, 26, 1, 158, 214, 8, 26, + 1, 158, 216, 151, 26, 1, 158, 212, 206, 26, 1, 158, 221, 233, 26, 1, 158, + 209, 131, 26, 1, 158, 209, 235, 26, 1, 158, 212, 59, 26, 1, 158, 219, + 178, 26, 1, 158, 214, 47, 26, 1, 158, 216, 148, 26, 1, 158, 214, 20, 26, + 1, 158, 191, 200, 26, 1, 158, 210, 139, 26, 1, 158, 191, 199, 26, 1, 158, + 214, 160, 26, 1, 158, 212, 195, 26, 1, 158, 200, 250, 26, 1, 158, 220, + 212, 26, 1, 158, 214, 36, 26, 1, 158, 214, 5, 26, 1, 158, 197, 69, 26, 1, + 158, 216, 159, 26, 1, 158, 220, 201, 26, 1, 158, 212, 204, 26, 1, 158, + 199, 60, 26, 1, 158, 217, 129, 26, 1, 158, 214, 45, 26, 1, 158, 219, 171, + 26, 1, 158, 214, 26, 26, 1, 158, 212, 209, 26, 1, 158, 213, 127, 26, 1, + 158, 231, 76, 26, 1, 158, 220, 234, 26, 1, 158, 207, 57, 211, 121, 26, 1, + 158, 199, 226, 26, 1, 158, 198, 50, 26, 1, 158, 212, 83, 26, 1, 158, 206, + 196, 26, 1, 158, 219, 229, 26, 1, 158, 216, 212, 26, 1, 158, 218, 170, + 26, 1, 158, 200, 160, 26, 1, 158, 215, 157, 26, 1, 158, 203, 77, 26, 1, + 158, 203, 87, 26, 1, 158, 220, 151, 26, 1, 158, 212, 180, 26, 1, 158, + 203, 6, 26, 1, 158, 212, 197, 26, 1, 158, 210, 51, 26, 1, 158, 213, 221, + 26, 1, 158, 203, 42, 26, 1, 158, 208, 145, 26, 1, 158, 215, 86, 26, 1, + 158, 219, 2, 26, 1, 158, 207, 57, 215, 146, 26, 1, 158, 198, 193, 26, 1, + 158, 212, 183, 26, 1, 158, 217, 12, 175, 26, 1, 158, 205, 129, 26, 1, + 158, 233, 110, 26, 1, 114, 214, 159, 26, 1, 114, 198, 57, 26, 1, 114, + 217, 1, 26, 1, 114, 220, 18, 26, 1, 114, 195, 10, 26, 1, 114, 219, 8, 26, + 1, 114, 210, 222, 26, 1, 114, 202, 22, 26, 1, 114, 207, 136, 26, 1, 114, + 212, 211, 26, 1, 114, 214, 130, 26, 1, 114, 208, 163, 26, 1, 114, 199, + 197, 26, 1, 114, 214, 13, 26, 1, 114, 221, 16, 26, 1, 114, 192, 247, 26, + 1, 114, 205, 51, 26, 1, 114, 214, 37, 26, 1, 114, 210, 219, 26, 1, 114, + 198, 59, 26, 1, 114, 220, 206, 26, 1, 114, 219, 24, 26, 1, 114, 212, 214, + 26, 1, 114, 213, 245, 26, 1, 114, 217, 135, 26, 1, 114, 214, 6, 26, 1, + 114, 213, 244, 26, 1, 114, 212, 213, 26, 1, 114, 206, 193, 26, 1, 114, + 213, 145, 26, 1, 114, 210, 48, 26, 1, 114, 205, 198, 26, 1, 114, 214, 21, + 26, 1, 114, 216, 138, 26, 1, 114, 231, 70, 26, 1, 114, 214, 9, 26, 1, + 114, 213, 156, 26, 1, 114, 217, 73, 26, 1, 114, 219, 4, 26, 1, 114, 214, + 42, 26, 1, 114, 214, 143, 26, 1, 114, 199, 225, 212, 195, 26, 1, 114, + 203, 253, 26, 1, 114, 208, 156, 26, 1, 114, 214, 163, 202, 31, 26, 1, + 114, 214, 29, 212, 97, 26, 1, 114, 192, 29, 26, 1, 114, 231, 71, 26, 1, + 114, 197, 88, 26, 1, 114, 192, 47, 26, 1, 114, 209, 75, 26, 1, 114, 197, + 75, 26, 1, 114, 221, 241, 26, 1, 114, 200, 249, 26, 1, 114, 199, 61, 26, + 1, 114, 195, 79, 26, 1, 114, 193, 100, 26, 1, 114, 220, 125, 26, 1, 114, + 208, 167, 26, 1, 114, 199, 239, 26, 1, 114, 231, 91, 26, 1, 114, 214, 52, + 26, 1, 114, 203, 90, 26, 1, 114, 216, 133, 26, 1, 114, 217, 5, 26, 1, + 114, 212, 46, 26, 1, 114, 213, 108, 26, 1, 114, 231, 178, 26, 1, 114, + 197, 76, 26, 1, 114, 220, 217, 26, 1, 114, 192, 104, 26, 1, 114, 212, 84, + 242, 239, 26, 1, 114, 192, 18, 26, 1, 114, 216, 150, 26, 1, 114, 214, + 148, 26, 1, 114, 209, 176, 26, 1, 114, 191, 206, 26, 1, 114, 219, 173, + 26, 1, 114, 232, 86, 26, 1, 114, 231, 177, 26, 1, 114, 213, 255, 26, 1, + 114, 221, 243, 26, 1, 114, 217, 138, 26, 1, 114, 214, 12, 26, 1, 114, + 231, 77, 26, 1, 114, 233, 111, 26, 1, 114, 212, 184, 26, 1, 114, 209, + 236, 26, 1, 114, 192, 45, 26, 1, 114, 214, 38, 26, 1, 114, 212, 84, 248, + 211, 26, 1, 114, 212, 26, 26, 1, 114, 209, 37, 26, 1, 114, 216, 82, 26, + 1, 114, 232, 84, 26, 1, 114, 214, 246, 26, 1, 114, 215, 151, 26, 1, 114, + 231, 76, 26, 1, 114, 232, 89, 68, 26, 1, 114, 215, 87, 26, 1, 114, 208, + 162, 26, 1, 114, 214, 1, 26, 1, 114, 220, 190, 26, 1, 114, 209, 173, 26, + 1, 114, 212, 198, 26, 1, 114, 192, 46, 26, 1, 114, 214, 22, 26, 1, 114, + 210, 223, 210, 21, 26, 1, 114, 232, 89, 247, 140, 26, 1, 114, 232, 169, + 26, 1, 114, 213, 150, 26, 1, 114, 65, 26, 1, 114, 198, 50, 26, 1, 114, + 74, 26, 1, 114, 68, 26, 1, 114, 220, 16, 26, 1, 114, 210, 223, 209, 84, + 26, 1, 114, 199, 245, 26, 1, 114, 199, 180, 26, 1, 114, 214, 163, 215, + 73, 228, 174, 26, 1, 114, 203, 65, 26, 1, 114, 192, 42, 26, 1, 114, 213, + 238, 26, 1, 114, 191, 211, 26, 1, 114, 191, 244, 200, 136, 26, 1, 114, + 191, 244, 238, 244, 26, 1, 114, 191, 194, 26, 1, 114, 191, 202, 26, 1, + 114, 221, 229, 26, 1, 114, 209, 234, 26, 1, 114, 213, 151, 234, 51, 26, + 1, 114, 208, 158, 26, 1, 114, 192, 253, 26, 1, 114, 233, 54, 26, 1, 114, + 195, 148, 26, 1, 114, 218, 227, 26, 1, 114, 216, 102, 26, 1, 114, 207, + 21, 26, 1, 114, 207, 165, 26, 1, 114, 213, 237, 26, 1, 114, 214, 70, 26, + 1, 114, 203, 57, 26, 1, 114, 203, 42, 26, 1, 114, 232, 89, 207, 60, 26, + 1, 114, 181, 26, 1, 114, 209, 187, 26, 1, 114, 219, 2, 26, 1, 114, 221, + 69, 26, 1, 114, 216, 188, 26, 1, 114, 174, 26, 1, 114, 217, 70, 26, 1, + 114, 199, 63, 26, 1, 114, 221, 168, 26, 1, 114, 215, 233, 26, 1, 114, + 199, 95, 26, 1, 114, 233, 78, 26, 1, 114, 231, 64, 26, 1, 209, 217, 155, + 26, 1, 209, 217, 66, 26, 1, 209, 217, 220, 234, 26, 1, 209, 217, 234, + 190, 26, 1, 209, 217, 207, 86, 26, 1, 209, 217, 199, 226, 26, 1, 209, + 217, 212, 83, 26, 1, 209, 217, 173, 26, 1, 209, 217, 206, 196, 26, 1, + 209, 217, 206, 243, 26, 1, 209, 217, 216, 212, 26, 1, 209, 217, 199, 245, + 26, 1, 209, 217, 214, 162, 26, 1, 209, 217, 213, 157, 26, 1, 209, 217, + 218, 170, 26, 1, 209, 217, 200, 160, 26, 1, 209, 217, 203, 77, 26, 1, + 209, 217, 202, 223, 26, 1, 209, 217, 203, 249, 26, 1, 209, 217, 220, 151, + 26, 1, 209, 217, 221, 243, 26, 1, 209, 217, 212, 148, 26, 1, 209, 217, + 212, 180, 26, 1, 209, 217, 213, 128, 26, 1, 209, 217, 191, 243, 26, 1, + 209, 217, 203, 6, 26, 1, 209, 217, 170, 26, 1, 209, 217, 212, 217, 26, 1, + 209, 217, 209, 234, 26, 1, 209, 217, 212, 197, 26, 1, 209, 217, 192, 253, + 26, 1, 209, 217, 210, 51, 26, 1, 209, 217, 206, 69, 26, 1, 209, 217, 213, + 221, 26, 1, 209, 217, 207, 21, 26, 1, 209, 217, 221, 253, 26, 1, 209, + 217, 213, 254, 26, 1, 209, 217, 214, 49, 26, 1, 209, 217, 203, 57, 26, 1, + 209, 217, 208, 163, 26, 1, 209, 217, 232, 169, 26, 1, 209, 217, 193, 190, + 26, 1, 209, 217, 219, 148, 26, 1, 209, 217, 219, 2, 26, 1, 209, 217, 221, + 69, 26, 1, 209, 217, 217, 3, 26, 1, 209, 217, 207, 56, 26, 1, 209, 217, + 174, 26, 1, 209, 217, 216, 14, 26, 1, 209, 217, 217, 11, 26, 1, 209, 217, + 199, 73, 26, 1, 209, 217, 221, 23, 26, 1, 209, 217, 205, 151, 26, 1, 209, + 217, 193, 248, 215, 161, 1, 190, 190, 215, 161, 1, 214, 18, 215, 161, 1, + 192, 12, 215, 161, 1, 216, 48, 215, 161, 1, 249, 155, 215, 161, 1, 238, + 34, 215, 161, 1, 65, 215, 161, 1, 209, 213, 215, 161, 1, 221, 211, 215, + 161, 1, 230, 24, 215, 161, 1, 238, 9, 215, 161, 1, 243, 50, 215, 161, 1, + 222, 17, 215, 161, 1, 211, 122, 215, 161, 1, 217, 135, 215, 161, 1, 213, + 181, 215, 161, 1, 168, 215, 161, 1, 211, 89, 215, 161, 1, 74, 215, 161, + 1, 206, 163, 215, 161, 1, 203, 82, 215, 161, 1, 199, 32, 215, 161, 1, + 234, 219, 215, 161, 1, 193, 190, 215, 161, 1, 71, 215, 161, 1, 221, 69, + 215, 161, 1, 220, 26, 215, 161, 1, 173, 215, 161, 1, 230, 82, 215, 161, + 1, 207, 2, 215, 161, 1, 199, 110, 215, 161, 17, 191, 77, 215, 161, 17, + 107, 215, 161, 17, 109, 215, 161, 17, 138, 215, 161, 17, 134, 215, 161, + 17, 150, 215, 161, 17, 169, 215, 161, 17, 175, 215, 161, 17, 171, 215, + 161, 17, 178, 215, 161, 237, 240, 215, 161, 55, 237, 240, 199, 186, 1, + 210, 240, 199, 186, 1, 211, 168, 199, 186, 1, 211, 60, 199, 186, 1, 210, + 249, 199, 186, 1, 250, 125, 199, 186, 1, 252, 65, 199, 186, 1, 251, 39, + 199, 186, 1, 250, 135, 199, 186, 1, 193, 227, 199, 186, 1, 195, 155, 199, + 186, 1, 194, 255, 199, 186, 1, 193, 236, 199, 186, 1, 233, 184, 199, 186, + 1, 234, 199, 199, 186, 1, 234, 48, 199, 186, 1, 233, 223, 199, 186, 1, + 223, 43, 199, 186, 1, 228, 30, 199, 186, 1, 223, 81, 199, 186, 1, 223, + 47, 199, 186, 1, 196, 18, 199, 186, 1, 196, 160, 199, 186, 1, 196, 64, + 199, 186, 1, 196, 22, 199, 186, 1, 250, 136, 199, 186, 1, 250, 140, 199, + 186, 1, 250, 138, 199, 186, 1, 250, 137, 199, 186, 1, 196, 129, 199, 186, + 1, 196, 138, 199, 186, 1, 196, 135, 199, 186, 1, 196, 130, 199, 186, 1, + 53, 214, 72, 199, 186, 1, 180, 196, 145, 199, 186, 1, 203, 41, 196, 143, + 199, 186, 1, 203, 41, 250, 137, 199, 186, 1, 196, 150, 199, 186, 1, 196, + 143, 199, 186, 1, 196, 146, 199, 186, 1, 196, 145, 199, 186, 1, 196, 131, + 199, 186, 1, 196, 134, 199, 186, 1, 196, 133, 199, 186, 1, 196, 132, 199, + 186, 1, 215, 65, 199, 186, 1, 216, 240, 199, 186, 1, 215, 167, 199, 186, + 1, 215, 74, 199, 186, 1, 155, 199, 186, 1, 221, 217, 199, 186, 1, 231, + 242, 199, 186, 1, 214, 70, 199, 186, 1, 188, 199, 186, 1, 170, 199, 186, + 1, 193, 190, 199, 186, 1, 168, 199, 186, 1, 212, 103, 199, 186, 1, 209, + 230, 199, 186, 1, 249, 155, 199, 186, 1, 174, 199, 186, 1, 181, 199, 186, + 1, 140, 199, 186, 1, 173, 199, 186, 1, 228, 166, 199, 186, 1, 190, 190, + 199, 186, 1, 238, 34, 199, 186, 1, 165, 199, 186, 1, 213, 226, 199, 186, + 1, 203, 166, 199, 186, 1, 247, 162, 199, 186, 1, 197, 168, 199, 186, 1, + 231, 93, 199, 186, 1, 228, 163, 199, 186, 1, 199, 49, 199, 186, 1, 192, + 220, 199, 186, 1, 233, 111, 199, 186, 1, 237, 70, 199, 186, 1, 247, 3, + 199, 186, 1, 191, 123, 199, 186, 17, 191, 77, 199, 186, 17, 107, 199, + 186, 17, 109, 199, 186, 17, 138, 199, 186, 17, 134, 199, 186, 17, 150, + 199, 186, 17, 169, 199, 186, 17, 175, 199, 186, 17, 171, 199, 186, 17, + 178, 249, 69, 195, 185, 1, 234, 86, 249, 69, 195, 185, 1, 155, 249, 69, + 195, 185, 1, 205, 69, 249, 69, 195, 185, 1, 233, 111, 249, 69, 195, 185, + 1, 217, 6, 249, 69, 195, 185, 1, 192, 30, 249, 69, 195, 185, 1, 231, 227, + 249, 69, 195, 185, 1, 237, 51, 249, 69, 195, 185, 1, 221, 22, 249, 69, + 195, 185, 1, 222, 203, 249, 69, 195, 185, 1, 228, 126, 249, 69, 195, 185, + 1, 193, 190, 249, 69, 195, 185, 1, 191, 7, 249, 69, 195, 185, 1, 231, + 171, 249, 69, 195, 185, 1, 236, 176, 249, 69, 195, 185, 1, 247, 44, 249, + 69, 195, 185, 1, 196, 23, 249, 69, 195, 185, 1, 159, 249, 69, 195, 185, + 1, 249, 155, 249, 69, 195, 185, 1, 193, 249, 249, 69, 195, 185, 1, 192, + 74, 249, 69, 195, 185, 1, 168, 249, 69, 195, 185, 1, 193, 177, 249, 69, + 195, 185, 1, 65, 249, 69, 195, 185, 1, 74, 249, 69, 195, 185, 1, 211, 89, + 249, 69, 195, 185, 1, 66, 249, 69, 195, 185, 1, 234, 190, 249, 69, 195, + 185, 1, 71, 249, 69, 195, 185, 1, 68, 249, 69, 195, 185, 33, 137, 198, + 79, 249, 69, 195, 185, 33, 130, 198, 79, 249, 69, 195, 185, 33, 216, 89, + 198, 79, 249, 69, 195, 185, 33, 218, 240, 198, 79, 249, 69, 195, 185, 33, + 229, 135, 198, 79, 249, 69, 195, 185, 232, 82, 201, 64, 145, 90, 18, 222, + 14, 145, 90, 18, 222, 10, 145, 90, 18, 221, 157, 145, 90, 18, 221, 120, + 145, 90, 18, 222, 43, 145, 90, 18, 222, 40, 145, 90, 18, 220, 218, 145, + 90, 18, 220, 187, 145, 90, 18, 222, 16, 145, 90, 18, 221, 227, 145, 90, + 18, 222, 103, 145, 90, 18, 222, 100, 145, 90, 18, 221, 42, 145, 90, 18, + 221, 39, 145, 90, 18, 222, 36, 145, 90, 18, 222, 33, 145, 90, 18, 220, + 220, 145, 90, 18, 220, 219, 145, 90, 18, 221, 62, 145, 90, 18, 221, 27, + 145, 90, 18, 221, 159, 145, 90, 18, 221, 158, 145, 90, 18, 222, 119, 145, + 90, 18, 222, 39, 145, 90, 18, 220, 177, 145, 90, 18, 220, 168, 145, 90, + 18, 222, 128, 145, 90, 18, 222, 120, 145, 90, 120, 195, 160, 145, 90, + 120, 212, 187, 145, 90, 120, 220, 2, 145, 90, 120, 230, 4, 145, 90, 120, + 213, 84, 145, 90, 120, 207, 127, 145, 90, 120, 213, 111, 145, 90, 120, + 208, 71, 145, 90, 120, 192, 91, 145, 90, 120, 229, 110, 145, 90, 120, + 217, 27, 145, 90, 120, 243, 133, 145, 90, 120, 214, 167, 145, 90, 120, + 229, 46, 145, 90, 120, 209, 93, 145, 90, 120, 212, 193, 145, 90, 120, + 214, 207, 145, 90, 120, 250, 165, 145, 90, 120, 192, 216, 145, 90, 120, + 247, 78, 145, 90, 87, 243, 19, 197, 85, 145, 90, 87, 243, 19, 202, 47, + 145, 90, 87, 243, 19, 221, 245, 145, 90, 87, 243, 19, 221, 200, 145, 90, + 87, 243, 19, 200, 247, 145, 90, 87, 243, 19, 229, 4, 145, 90, 87, 243, + 19, 199, 165, 145, 90, 3, 195, 5, 198, 238, 145, 90, 3, 195, 5, 197, 156, + 247, 35, 145, 90, 3, 243, 19, 243, 122, 145, 90, 3, 195, 5, 199, 10, 145, + 90, 3, 195, 5, 233, 51, 145, 90, 3, 192, 171, 212, 181, 145, 90, 3, 192, + 171, 207, 4, 145, 90, 3, 192, 171, 198, 32, 145, 90, 3, 192, 171, 233, + 92, 145, 90, 3, 195, 5, 205, 45, 145, 90, 3, 216, 211, 200, 251, 145, 90, + 3, 195, 5, 212, 233, 145, 90, 3, 228, 33, 192, 111, 145, 90, 3, 192, 215, + 145, 90, 3, 243, 19, 197, 143, 206, 145, 145, 90, 17, 191, 77, 145, 90, + 17, 107, 145, 90, 17, 109, 145, 90, 17, 138, 145, 90, 17, 134, 145, 90, + 17, 150, 145, 90, 17, 169, 145, 90, 17, 175, 145, 90, 17, 171, 145, 90, + 17, 178, 145, 90, 31, 199, 90, 145, 90, 31, 228, 140, 145, 90, 31, 199, + 96, 198, 228, 145, 90, 31, 216, 49, 145, 90, 31, 228, 143, 216, 49, 145, + 90, 31, 199, 96, 248, 171, 145, 90, 31, 197, 227, 145, 90, 3, 195, 5, + 218, 222, 145, 90, 3, 192, 168, 145, 90, 3, 229, 105, 145, 90, 3, 198, + 255, 229, 105, 145, 90, 3, 190, 236, 199, 43, 145, 90, 3, 229, 30, 145, + 90, 3, 212, 247, 145, 90, 3, 192, 206, 145, 90, 3, 212, 185, 145, 90, 3, + 250, 148, 145, 90, 3, 197, 7, 247, 34, 145, 90, 3, 216, 211, 197, 159, + 145, 90, 3, 199, 166, 145, 90, 3, 218, 255, 145, 90, 3, 215, 105, 145, + 90, 3, 243, 19, 230, 78, 218, 198, 212, 191, 212, 190, 145, 90, 3, 243, + 19, 238, 196, 197, 150, 145, 90, 3, 243, 19, 197, 5, 145, 90, 3, 243, 19, + 197, 6, 243, 38, 145, 90, 3, 243, 19, 208, 161, 237, 208, 145, 90, 3, + 243, 19, 212, 240, 198, 41, 145, 90, 242, 246, 3, 197, 154, 145, 90, 242, + 246, 3, 192, 76, 145, 90, 242, 246, 3, 219, 92, 145, 90, 242, 246, 3, + 220, 0, 145, 90, 242, 246, 3, 192, 167, 145, 90, 242, 246, 3, 221, 43, + 145, 90, 242, 246, 3, 230, 0, 145, 90, 242, 246, 3, 215, 149, 145, 90, + 242, 246, 3, 198, 239, 145, 90, 242, 246, 3, 197, 165, 145, 90, 242, 246, + 3, 209, 227, 145, 90, 242, 246, 3, 221, 215, 145, 90, 242, 246, 3, 230, + 66, 145, 90, 242, 246, 3, 195, 182, 145, 90, 242, 246, 3, 233, 88, 145, + 90, 242, 246, 3, 192, 118, 145, 90, 242, 246, 3, 197, 137, 145, 90, 242, + 246, 3, 220, 172, 145, 90, 242, 246, 3, 193, 237, 216, 220, 6, 1, 218, + 170, 216, 220, 6, 1, 206, 9, 216, 220, 6, 1, 196, 12, 216, 220, 6, 1, + 193, 224, 216, 220, 6, 1, 250, 178, 216, 220, 6, 1, 191, 166, 216, 220, + 6, 1, 221, 24, 216, 220, 6, 1, 210, 238, 216, 220, 6, 1, 200, 43, 216, + 220, 6, 1, 232, 53, 216, 220, 6, 1, 233, 177, 216, 220, 6, 1, 68, 216, + 220, 6, 1, 222, 154, 216, 220, 6, 1, 65, 216, 220, 6, 1, 223, 37, 216, + 220, 6, 1, 71, 216, 220, 6, 1, 250, 122, 216, 220, 6, 1, 247, 195, 216, + 220, 6, 1, 66, 216, 220, 6, 1, 191, 225, 216, 220, 6, 1, 172, 216, 220, + 6, 1, 208, 106, 216, 220, 6, 1, 228, 171, 216, 220, 6, 1, 212, 105, 216, + 220, 6, 1, 192, 235, 216, 220, 6, 1, 238, 129, 216, 220, 6, 1, 211, 153, + 216, 220, 6, 1, 215, 63, 216, 220, 6, 1, 146, 216, 220, 6, 1, 74, 216, + 220, 6, 1, 251, 238, 216, 220, 6, 1, 192, 159, 216, 220, 2, 1, 218, 170, + 216, 220, 2, 1, 206, 9, 216, 220, 2, 1, 196, 12, 216, 220, 2, 1, 193, + 224, 216, 220, 2, 1, 250, 178, 216, 220, 2, 1, 191, 166, 216, 220, 2, 1, + 221, 24, 216, 220, 2, 1, 210, 238, 216, 220, 2, 1, 200, 43, 216, 220, 2, + 1, 232, 53, 216, 220, 2, 1, 233, 177, 216, 220, 2, 1, 68, 216, 220, 2, 1, + 222, 154, 216, 220, 2, 1, 65, 216, 220, 2, 1, 223, 37, 216, 220, 2, 1, + 71, 216, 220, 2, 1, 250, 122, 216, 220, 2, 1, 247, 195, 216, 220, 2, 1, + 66, 216, 220, 2, 1, 191, 225, 216, 220, 2, 1, 172, 216, 220, 2, 1, 208, + 106, 216, 220, 2, 1, 228, 171, 216, 220, 2, 1, 212, 105, 216, 220, 2, 1, + 192, 235, 216, 220, 2, 1, 238, 129, 216, 220, 2, 1, 211, 153, 216, 220, + 2, 1, 215, 63, 216, 220, 2, 1, 146, 216, 220, 2, 1, 74, 216, 220, 2, 1, + 251, 238, 216, 220, 2, 1, 192, 159, 216, 220, 17, 191, 77, 216, 220, 17, + 107, 216, 220, 17, 109, 216, 220, 17, 138, 216, 220, 17, 134, 216, 220, + 17, 150, 216, 220, 17, 169, 216, 220, 17, 175, 216, 220, 17, 171, 216, + 220, 17, 178, 216, 220, 31, 199, 95, 216, 220, 31, 234, 129, 216, 220, + 31, 197, 37, 216, 220, 31, 198, 251, 216, 220, 31, 232, 124, 216, 220, + 31, 233, 21, 216, 220, 31, 202, 131, 216, 220, 31, 203, 245, 216, 220, + 31, 234, 163, 216, 220, 31, 213, 173, 216, 220, 17, 91, 251, 159, 20, + 216, 220, 17, 105, 251, 159, 20, 216, 220, 17, 115, 251, 159, 20, 216, + 220, 242, 76, 216, 220, 232, 82, 201, 64, 216, 220, 16, 251, 223, 216, + 220, 233, 218, 211, 138, 121, 1, 168, 121, 1, 249, 155, 121, 1, 11, 168, + 121, 1, 209, 112, 121, 1, 174, 121, 1, 216, 105, 121, 1, 251, 16, 174, + 121, 1, 233, 111, 121, 1, 195, 188, 121, 1, 195, 71, 121, 1, 190, 190, + 121, 1, 238, 34, 121, 1, 11, 197, 132, 121, 1, 11, 190, 190, 121, 1, 197, + 132, 121, 1, 237, 193, 121, 1, 181, 121, 1, 213, 226, 121, 1, 11, 213, + 81, 121, 1, 251, 16, 181, 121, 1, 213, 81, 121, 1, 213, 67, 121, 1, 173, + 121, 1, 218, 184, 121, 1, 219, 161, 121, 1, 219, 150, 121, 1, 198, 112, + 121, 1, 236, 185, 121, 1, 198, 104, 121, 1, 236, 184, 121, 1, 155, 121, + 1, 231, 242, 121, 1, 11, 155, 121, 1, 208, 98, 121, 1, 208, 74, 121, 1, + 214, 70, 121, 1, 214, 19, 121, 1, 251, 16, 214, 70, 121, 1, 140, 121, 1, + 192, 220, 121, 1, 231, 93, 121, 1, 231, 68, 121, 1, 197, 142, 121, 1, + 235, 20, 121, 1, 212, 103, 121, 1, 212, 85, 121, 1, 197, 157, 121, 1, + 235, 31, 121, 1, 11, 197, 157, 121, 1, 11, 235, 31, 121, 1, 207, 83, 197, + 157, 121, 1, 203, 166, 121, 1, 201, 176, 121, 1, 191, 71, 121, 1, 190, + 253, 121, 1, 197, 168, 121, 1, 235, 37, 121, 1, 11, 197, 168, 121, 1, + 188, 121, 1, 191, 123, 121, 1, 190, 254, 121, 1, 190, 224, 121, 1, 190, + 204, 121, 1, 251, 16, 190, 224, 121, 1, 190, 196, 121, 1, 190, 203, 121, + 1, 193, 190, 121, 1, 251, 247, 121, 1, 229, 179, 121, 1, 248, 34, 121, 1, + 200, 125, 121, 1, 235, 21, 121, 1, 199, 145, 121, 1, 197, 161, 121, 1, + 206, 72, 121, 3, 120, 52, 164, 121, 1, 214, 214, 121, 3, 250, 201, 121, + 3, 207, 83, 195, 18, 121, 3, 207, 83, 250, 201, 121, 18, 3, 65, 121, 18, + 3, 252, 208, 121, 18, 3, 251, 243, 121, 18, 3, 251, 134, 121, 18, 3, 251, + 124, 121, 18, 3, 74, 121, 18, 3, 211, 89, 121, 18, 3, 193, 48, 121, 18, + 3, 193, 224, 121, 18, 3, 71, 121, 18, 3, 234, 105, 121, 18, 3, 234, 90, + 121, 18, 3, 211, 149, 121, 18, 3, 68, 121, 18, 3, 228, 37, 121, 18, 3, + 228, 36, 121, 18, 3, 228, 35, 121, 18, 3, 223, 90, 121, 18, 3, 223, 228, + 121, 18, 3, 223, 201, 121, 18, 3, 223, 51, 121, 18, 3, 223, 138, 121, 18, + 3, 66, 121, 18, 3, 196, 168, 121, 18, 3, 196, 167, 121, 18, 3, 196, 166, + 121, 18, 3, 196, 30, 121, 18, 3, 196, 148, 121, 18, 3, 196, 97, 121, 18, + 3, 192, 159, 121, 18, 3, 192, 33, 121, 18, 3, 252, 27, 121, 18, 3, 252, + 23, 121, 18, 3, 234, 28, 121, 18, 3, 206, 114, 234, 28, 121, 18, 3, 234, + 36, 121, 18, 3, 206, 114, 234, 36, 121, 18, 3, 251, 238, 121, 18, 3, 234, + 168, 121, 18, 3, 250, 165, 121, 18, 3, 211, 21, 121, 18, 3, 215, 63, 121, + 18, 3, 214, 72, 121, 18, 3, 196, 81, 121, 18, 3, 191, 205, 121, 18, 3, + 211, 143, 121, 18, 3, 211, 150, 121, 18, 3, 193, 239, 121, 18, 3, 223, + 206, 121, 18, 3, 234, 219, 121, 18, 3, 223, 88, 121, 18, 3, 196, 139, + 121, 163, 179, 121, 163, 198, 54, 179, 121, 163, 58, 121, 163, 60, 121, + 1, 198, 77, 121, 1, 198, 76, 121, 1, 198, 75, 121, 1, 198, 74, 121, 1, + 198, 73, 121, 1, 198, 72, 121, 1, 198, 71, 121, 1, 207, 83, 198, 78, 121, + 1, 207, 83, 198, 77, 121, 1, 207, 83, 198, 75, 121, 1, 207, 83, 198, 74, + 121, 1, 207, 83, 198, 73, 121, 1, 207, 83, 198, 71, 19, 223, 53, 77, 46, + 223, 53, 77, 39, 243, 82, 228, 253, 77, 39, 243, 82, 223, 53, 77, 41, 2, + 27, 233, 5, 195, 57, 251, 159, 207, 109, 87, 247, 162, 195, 57, 251, 159, + 207, 109, 87, 213, 225, 19, 242, 65, 19, 242, 64, 19, 242, 63, 19, 242, + 62, 19, 242, 61, 19, 242, 60, 19, 242, 59, 19, 242, 58, 19, 242, 57, 19, + 242, 56, 19, 242, 55, 19, 242, 54, 19, 242, 53, 19, 242, 52, 19, 242, 51, + 19, 242, 50, 19, 242, 49, 19, 242, 48, 19, 242, 47, 19, 242, 46, 19, 242, + 45, 19, 242, 44, 19, 242, 43, 19, 242, 42, 19, 242, 41, 19, 242, 40, 19, + 242, 39, 19, 242, 38, 19, 242, 37, 19, 242, 36, 19, 242, 35, 19, 242, 34, + 19, 242, 33, 19, 242, 32, 19, 242, 31, 19, 242, 30, 19, 242, 29, 19, 242, + 28, 19, 242, 27, 19, 242, 26, 19, 242, 25, 19, 242, 24, 19, 242, 23, 19, + 242, 22, 19, 242, 21, 19, 242, 20, 19, 242, 19, 19, 242, 18, 19, 242, 17, + 19, 242, 16, 19, 242, 15, 19, 242, 14, 19, 242, 13, 19, 242, 12, 19, 242, + 11, 19, 242, 10, 19, 242, 9, 19, 242, 8, 19, 242, 7, 19, 242, 6, 19, 242, + 5, 19, 242, 4, 19, 242, 3, 19, 242, 2, 19, 242, 1, 19, 242, 0, 19, 241, + 255, 19, 241, 254, 19, 241, 253, 19, 241, 252, 19, 241, 251, 19, 241, + 250, 19, 241, 249, 19, 241, 248, 19, 241, 247, 19, 241, 246, 19, 241, + 245, 19, 241, 244, 19, 241, 243, 19, 241, 242, 19, 241, 241, 19, 241, + 240, 19, 241, 239, 19, 241, 238, 19, 241, 237, 19, 241, 236, 19, 241, + 235, 19, 241, 234, 19, 241, 233, 19, 241, 232, 19, 241, 231, 19, 241, + 230, 19, 241, 229, 19, 241, 228, 19, 241, 227, 19, 241, 226, 19, 241, + 225, 19, 241, 224, 19, 241, 223, 19, 241, 222, 19, 241, 221, 19, 241, + 220, 19, 241, 219, 19, 241, 218, 19, 241, 217, 19, 241, 216, 19, 241, + 215, 19, 241, 214, 19, 241, 213, 19, 241, 212, 19, 241, 211, 19, 241, + 210, 19, 241, 209, 19, 241, 208, 19, 241, 207, 19, 241, 206, 19, 241, + 205, 19, 241, 204, 19, 241, 203, 19, 241, 202, 19, 241, 201, 19, 241, + 200, 19, 241, 199, 19, 241, 198, 19, 241, 197, 19, 241, 196, 19, 241, + 195, 19, 241, 194, 19, 241, 193, 19, 241, 192, 19, 241, 191, 19, 241, + 190, 19, 241, 189, 19, 241, 188, 19, 241, 187, 19, 241, 186, 19, 241, + 185, 19, 241, 184, 19, 241, 183, 19, 241, 182, 19, 241, 181, 19, 241, + 180, 19, 241, 179, 19, 241, 178, 19, 241, 177, 19, 241, 176, 19, 241, + 175, 19, 241, 174, 19, 241, 173, 19, 241, 172, 19, 241, 171, 19, 241, + 170, 19, 241, 169, 19, 241, 168, 19, 241, 167, 19, 241, 166, 19, 241, + 165, 19, 241, 164, 19, 241, 163, 19, 241, 162, 19, 241, 161, 19, 241, + 160, 19, 241, 159, 19, 241, 158, 19, 241, 157, 19, 241, 156, 19, 241, + 155, 19, 241, 154, 19, 241, 153, 19, 241, 152, 19, 241, 151, 19, 241, + 150, 19, 241, 149, 19, 241, 148, 19, 241, 147, 19, 241, 146, 19, 241, + 145, 19, 241, 144, 19, 241, 143, 19, 241, 142, 19, 241, 141, 19, 241, + 140, 19, 241, 139, 19, 241, 138, 19, 241, 137, 19, 241, 136, 19, 241, + 135, 19, 241, 134, 19, 241, 133, 19, 241, 132, 19, 241, 131, 19, 241, + 130, 19, 241, 129, 19, 241, 128, 19, 241, 127, 19, 241, 126, 19, 241, + 125, 19, 241, 124, 19, 241, 123, 19, 241, 122, 19, 241, 121, 19, 241, + 120, 19, 241, 119, 19, 241, 118, 19, 241, 117, 19, 241, 116, 19, 241, + 115, 19, 241, 114, 19, 241, 113, 19, 241, 112, 19, 241, 111, 19, 241, + 110, 19, 241, 109, 19, 241, 108, 19, 241, 107, 19, 241, 106, 19, 241, + 105, 19, 241, 104, 19, 241, 103, 19, 241, 102, 19, 241, 101, 19, 241, + 100, 19, 241, 99, 19, 241, 98, 19, 241, 97, 19, 241, 96, 19, 241, 95, 19, + 241, 94, 19, 241, 93, 19, 241, 92, 19, 241, 91, 19, 241, 90, 19, 241, 89, + 19, 241, 88, 19, 241, 87, 19, 241, 86, 19, 241, 85, 19, 241, 84, 19, 241, + 83, 19, 241, 82, 19, 241, 81, 19, 241, 80, 19, 241, 79, 19, 241, 78, 19, + 241, 77, 19, 241, 76, 19, 241, 75, 19, 241, 74, 19, 241, 73, 19, 241, 72, + 19, 241, 71, 19, 241, 70, 19, 241, 69, 19, 241, 68, 19, 241, 67, 19, 241, + 66, 19, 241, 65, 19, 241, 64, 19, 241, 63, 19, 241, 62, 19, 241, 61, 19, + 241, 60, 19, 241, 59, 19, 241, 58, 19, 241, 57, 19, 241, 56, 19, 241, 55, + 19, 241, 54, 19, 241, 53, 19, 241, 52, 19, 241, 51, 19, 241, 50, 19, 241, + 49, 19, 241, 48, 19, 241, 47, 19, 241, 46, 19, 241, 45, 19, 241, 44, 19, + 241, 43, 19, 241, 42, 19, 241, 41, 19, 241, 40, 19, 241, 39, 19, 241, 38, + 19, 241, 37, 19, 241, 36, 19, 241, 35, 19, 241, 34, 19, 241, 33, 19, 241, + 32, 19, 241, 31, 19, 241, 30, 19, 241, 29, 19, 241, 28, 19, 241, 27, 19, + 241, 26, 19, 241, 25, 19, 241, 24, 19, 241, 23, 19, 241, 22, 19, 241, 21, + 19, 241, 20, 19, 241, 19, 19, 241, 18, 19, 241, 17, 19, 241, 16, 19, 241, + 15, 19, 241, 14, 19, 241, 13, 19, 241, 12, 19, 241, 11, 19, 241, 10, 19, + 241, 9, 19, 241, 8, 19, 241, 7, 19, 241, 6, 19, 241, 5, 19, 241, 4, 19, + 241, 3, 19, 241, 2, 19, 241, 1, 19, 241, 0, 19, 240, 255, 19, 240, 254, + 19, 240, 253, 19, 240, 252, 19, 240, 251, 19, 240, 250, 19, 240, 249, 19, + 240, 248, 19, 240, 247, 19, 240, 246, 19, 240, 245, 19, 240, 244, 19, + 240, 243, 19, 240, 242, 19, 240, 241, 19, 240, 240, 19, 240, 239, 19, + 240, 238, 19, 240, 237, 19, 240, 236, 19, 240, 235, 19, 240, 234, 19, + 240, 233, 19, 240, 232, 19, 240, 231, 19, 240, 230, 19, 240, 229, 19, + 240, 228, 19, 240, 227, 19, 240, 226, 19, 240, 225, 19, 240, 224, 19, + 240, 223, 19, 240, 222, 19, 240, 221, 19, 240, 220, 19, 240, 219, 19, + 240, 218, 19, 240, 217, 19, 240, 216, 19, 240, 215, 19, 240, 214, 19, + 240, 213, 19, 240, 212, 19, 240, 211, 19, 240, 210, 19, 240, 209, 19, + 240, 208, 19, 240, 207, 19, 240, 206, 19, 240, 205, 19, 240, 204, 19, + 240, 203, 19, 240, 202, 19, 240, 201, 19, 240, 200, 19, 240, 199, 19, + 240, 198, 19, 240, 197, 19, 240, 196, 19, 240, 195, 19, 240, 194, 19, + 240, 193, 19, 240, 192, 19, 240, 191, 19, 240, 190, 19, 240, 189, 19, + 240, 188, 19, 240, 187, 19, 240, 186, 19, 240, 185, 19, 240, 184, 19, + 240, 183, 19, 240, 182, 19, 240, 181, 19, 240, 180, 19, 240, 179, 19, + 240, 178, 19, 240, 177, 19, 240, 176, 19, 240, 175, 19, 240, 174, 19, + 240, 173, 19, 240, 172, 19, 240, 171, 19, 240, 170, 19, 240, 169, 19, + 240, 168, 19, 240, 167, 19, 240, 166, 19, 240, 165, 19, 240, 164, 19, + 240, 163, 19, 240, 162, 19, 240, 161, 19, 240, 160, 19, 240, 159, 19, + 240, 158, 19, 240, 157, 19, 240, 156, 19, 240, 155, 19, 240, 154, 19, + 240, 153, 19, 240, 152, 19, 240, 151, 19, 240, 150, 19, 240, 149, 19, + 240, 148, 19, 240, 147, 19, 240, 146, 19, 240, 145, 19, 240, 144, 19, + 240, 143, 19, 240, 142, 19, 240, 141, 19, 240, 140, 19, 240, 139, 19, + 240, 138, 19, 240, 137, 19, 240, 136, 19, 240, 135, 19, 240, 134, 19, + 240, 133, 19, 240, 132, 19, 240, 131, 19, 240, 130, 19, 240, 129, 19, + 240, 128, 19, 240, 127, 19, 240, 126, 19, 240, 125, 19, 240, 124, 19, + 240, 123, 19, 240, 122, 19, 240, 121, 19, 240, 120, 19, 240, 119, 19, + 240, 118, 19, 240, 117, 19, 240, 116, 19, 240, 115, 19, 240, 114, 19, + 240, 113, 19, 240, 112, 19, 240, 111, 19, 240, 110, 19, 240, 109, 19, + 240, 108, 19, 240, 107, 19, 240, 106, 19, 240, 105, 19, 240, 104, 19, + 240, 103, 19, 240, 102, 19, 240, 101, 19, 240, 100, 19, 240, 99, 19, 240, + 98, 19, 240, 97, 19, 240, 96, 19, 240, 95, 19, 240, 94, 19, 240, 93, 19, + 240, 92, 19, 240, 91, 19, 240, 90, 19, 240, 89, 19, 240, 88, 19, 240, 87, + 19, 240, 86, 19, 240, 85, 19, 240, 84, 19, 240, 83, 19, 240, 82, 19, 240, + 81, 19, 240, 80, 19, 240, 79, 19, 240, 78, 19, 240, 77, 19, 240, 76, 19, + 240, 75, 19, 240, 74, 19, 240, 73, 19, 240, 72, 19, 240, 71, 19, 240, 70, + 19, 240, 69, 19, 240, 68, 19, 240, 67, 19, 240, 66, 19, 240, 65, 19, 240, + 64, 19, 240, 63, 19, 240, 62, 19, 240, 61, 19, 240, 60, 19, 240, 59, 19, + 240, 58, 19, 240, 57, 19, 240, 56, 19, 240, 55, 19, 240, 54, 19, 240, 53, + 19, 240, 52, 19, 240, 51, 19, 240, 50, 19, 240, 49, 19, 240, 48, 19, 240, + 47, 19, 240, 46, 19, 240, 45, 19, 240, 44, 19, 240, 43, 19, 240, 42, 19, + 240, 41, 19, 240, 40, 19, 240, 39, 19, 240, 38, 19, 240, 37, 19, 240, 36, + 19, 240, 35, 19, 240, 34, 19, 240, 33, 19, 240, 32, 19, 240, 31, 19, 240, + 30, 19, 240, 29, 19, 240, 28, 19, 240, 27, 19, 240, 26, 19, 240, 25, 19, + 240, 24, 19, 240, 23, 19, 240, 22, 19, 240, 21, 19, 240, 20, 19, 240, 19, + 19, 240, 18, 19, 240, 17, 19, 240, 16, 19, 240, 15, 19, 240, 14, 19, 240, + 13, 19, 240, 12, 19, 240, 11, 19, 240, 10, 19, 240, 9, 19, 240, 8, 19, + 240, 7, 19, 240, 6, 19, 240, 5, 19, 240, 4, 19, 240, 3, 19, 240, 2, 19, + 240, 1, 19, 240, 0, 19, 239, 255, 19, 239, 254, 19, 239, 253, 19, 239, + 252, 19, 239, 251, 19, 239, 250, 19, 239, 249, 19, 239, 248, 19, 239, + 247, 19, 239, 246, 19, 239, 245, 19, 239, 244, 19, 239, 243, 19, 239, + 242, 19, 239, 241, 19, 239, 240, 19, 239, 239, 19, 239, 238, 19, 239, + 237, 19, 239, 236, 19, 239, 235, 19, 239, 234, 19, 239, 233, 19, 239, + 232, 19, 239, 231, 19, 239, 230, 19, 239, 229, 19, 239, 228, 19, 239, + 227, 19, 239, 226, 19, 239, 225, 19, 239, 224, 19, 239, 223, 19, 239, + 222, 19, 239, 221, 19, 239, 220, 19, 239, 219, 19, 239, 218, 19, 239, + 217, 19, 239, 216, 19, 239, 215, 19, 239, 214, 19, 239, 213, 19, 239, + 212, 19, 239, 211, 19, 239, 210, 19, 239, 209, 19, 239, 208, 19, 239, + 207, 19, 239, 206, 19, 239, 205, 19, 239, 204, 19, 239, 203, 19, 239, + 202, 19, 239, 201, 19, 239, 200, 19, 239, 199, 19, 239, 198, 19, 239, + 197, 19, 239, 196, 19, 239, 195, 19, 239, 194, 19, 239, 193, 19, 239, + 192, 19, 239, 191, 19, 239, 190, 19, 239, 189, 19, 239, 188, 19, 239, + 187, 19, 239, 186, 19, 239, 185, 19, 239, 184, 19, 239, 183, 19, 239, + 182, 19, 239, 181, 19, 239, 180, 19, 239, 179, 19, 239, 178, 19, 239, + 177, 19, 239, 176, 19, 239, 175, 19, 239, 174, 19, 239, 173, 19, 239, + 172, 19, 239, 171, 19, 239, 170, 19, 239, 169, 19, 239, 168, 19, 239, + 167, 19, 239, 166, 19, 239, 165, 19, 239, 164, 19, 239, 163, 19, 239, + 162, 19, 239, 161, 19, 239, 160, 19, 239, 159, 19, 239, 158, 19, 239, + 157, 19, 239, 156, 19, 239, 155, 19, 239, 154, 19, 239, 153, 19, 239, + 152, 19, 239, 151, 19, 239, 150, 19, 239, 149, 19, 239, 148, 19, 239, + 147, 19, 239, 146, 19, 239, 145, 19, 239, 144, 19, 239, 143, 19, 239, + 142, 19, 239, 141, 19, 239, 140, 19, 239, 139, 19, 239, 138, 19, 239, + 137, 19, 239, 136, 19, 239, 135, 19, 239, 134, 19, 239, 133, 19, 239, + 132, 19, 239, 131, 19, 239, 130, 19, 239, 129, 19, 239, 128, 19, 239, + 127, 19, 239, 126, 19, 239, 125, 19, 239, 124, 19, 239, 123, 19, 239, + 122, 19, 239, 121, 19, 239, 120, 19, 239, 119, 19, 239, 118, 19, 239, + 117, 19, 239, 116, 19, 239, 115, 19, 239, 114, 19, 239, 113, 19, 239, + 112, 19, 239, 111, 19, 239, 110, 19, 239, 109, 19, 239, 108, 19, 239, + 107, 19, 239, 106, 19, 239, 105, 19, 239, 104, 19, 239, 103, 19, 239, + 102, 19, 239, 101, 19, 239, 100, 19, 239, 99, 19, 239, 98, 19, 239, 97, + 19, 239, 96, 19, 239, 95, 19, 239, 94, 19, 239, 93, 19, 239, 92, 19, 239, + 91, 19, 239, 90, 19, 239, 89, 19, 239, 88, 19, 239, 87, 19, 239, 86, 19, + 239, 85, 19, 239, 84, 19, 239, 83, 19, 239, 82, 19, 239, 81, 19, 239, 80, + 19, 239, 79, 19, 239, 78, 19, 239, 77, 19, 239, 76, 19, 239, 75, 19, 239, + 74, 19, 239, 73, 19, 239, 72, 19, 239, 71, 19, 239, 70, 19, 239, 69, 19, + 239, 68, 19, 239, 67, 19, 239, 66, 41, 2, 27, 246, 240, 41, 2, 27, 246, + 239, 41, 2, 27, 246, 238, 41, 2, 27, 246, 237, 41, 2, 27, 246, 236, 41, + 2, 27, 246, 235, 41, 2, 27, 246, 234, 41, 2, 27, 246, 233, 41, 2, 27, + 246, 232, 41, 2, 27, 246, 231, 41, 2, 27, 246, 230, 41, 2, 27, 246, 229, + 41, 2, 27, 246, 228, 41, 2, 27, 246, 227, 41, 2, 27, 246, 226, 41, 2, 27, 246, 225, 41, 2, 27, 246, 224, 41, 2, 27, 246, 223, 41, 2, 27, 246, 222, 41, 2, 27, 246, 221, 41, 2, 27, 246, 220, 41, 2, 27, 246, 219, 41, 2, 27, 246, 218, 41, 2, 27, 246, 217, 41, 2, 27, 246, 216, 41, 2, 27, 246, 215, @@ -17734,2952 +17739,2953 @@ static const unsigned char phrasebook[] = { 39, 41, 2, 27, 245, 38, 41, 2, 27, 245, 37, 41, 2, 27, 245, 36, 41, 2, 27, 245, 35, 41, 2, 27, 245, 34, 41, 2, 27, 245, 33, 41, 2, 27, 245, 32, 41, 2, 27, 245, 31, 41, 2, 27, 245, 30, 41, 2, 27, 245, 29, 41, 2, 27, - 245, 28, 41, 2, 27, 245, 27, 41, 2, 27, 245, 26, 41, 2, 27, 245, 25, 72, - 1, 216, 36, 198, 77, 72, 1, 216, 36, 198, 76, 72, 1, 216, 36, 198, 75, - 72, 1, 216, 36, 198, 74, 72, 1, 216, 36, 198, 72, 72, 1, 216, 36, 198, - 71, 72, 1, 216, 36, 214, 211, 198, 78, 72, 1, 216, 36, 214, 211, 198, 77, - 72, 1, 216, 36, 214, 211, 198, 76, 72, 1, 216, 36, 214, 211, 198, 75, 72, - 1, 216, 36, 214, 211, 198, 74, 72, 1, 216, 36, 214, 211, 198, 72, 72, 1, - 216, 36, 214, 211, 198, 71, 72, 1, 251, 14, 71, 229, 120, 1, 251, 14, - 192, 80, 61, 1, 255, 206, 61, 1, 255, 205, 61, 1, 255, 204, 61, 1, 255, - 200, 61, 1, 228, 73, 61, 1, 228, 72, 61, 1, 228, 71, 61, 1, 228, 70, 61, - 1, 196, 231, 61, 1, 196, 230, 61, 1, 196, 229, 61, 1, 196, 228, 61, 1, - 196, 227, 61, 1, 235, 13, 61, 1, 235, 12, 61, 1, 235, 11, 61, 1, 235, 10, - 61, 1, 235, 9, 61, 1, 212, 14, 61, 1, 212, 13, 61, 1, 212, 12, 61, 1, - 222, 141, 61, 1, 222, 138, 61, 1, 222, 137, 61, 1, 222, 136, 61, 1, 222, - 135, 61, 1, 222, 134, 61, 1, 222, 133, 61, 1, 222, 132, 61, 1, 222, 131, - 61, 1, 222, 140, 61, 1, 222, 139, 61, 1, 222, 130, 61, 1, 221, 165, 61, - 1, 221, 164, 61, 1, 221, 163, 61, 1, 221, 162, 61, 1, 221, 161, 61, 1, - 221, 160, 61, 1, 221, 159, 61, 1, 221, 158, 61, 1, 220, 231, 61, 1, 220, - 230, 61, 1, 220, 229, 61, 1, 220, 228, 61, 1, 220, 227, 61, 1, 220, 226, - 61, 1, 220, 225, 61, 1, 222, 21, 61, 1, 222, 20, 61, 1, 222, 19, 61, 1, - 222, 18, 61, 1, 222, 17, 61, 1, 222, 16, 61, 1, 221, 66, 61, 1, 221, 65, - 61, 1, 221, 64, 61, 1, 221, 63, 61, 1, 205, 206, 61, 1, 205, 205, 61, 1, - 205, 204, 61, 1, 205, 203, 61, 1, 205, 202, 61, 1, 205, 201, 61, 1, 205, - 200, 61, 1, 205, 199, 61, 1, 202, 221, 61, 1, 202, 220, 61, 1, 202, 219, - 61, 1, 202, 218, 61, 1, 202, 217, 61, 1, 202, 216, 61, 1, 201, 3, 61, 1, - 201, 2, 61, 1, 201, 1, 61, 1, 201, 0, 61, 1, 200, 255, 61, 1, 200, 254, - 61, 1, 200, 253, 61, 1, 200, 252, 61, 1, 205, 67, 61, 1, 205, 66, 61, 1, - 205, 65, 61, 1, 205, 64, 61, 1, 205, 63, 61, 1, 202, 45, 61, 1, 202, 44, - 61, 1, 202, 43, 61, 1, 202, 42, 61, 1, 202, 41, 61, 1, 202, 40, 61, 1, - 202, 39, 61, 1, 199, 251, 61, 1, 199, 250, 61, 1, 199, 249, 61, 1, 199, - 248, 61, 1, 198, 192, 61, 1, 198, 191, 61, 1, 198, 190, 61, 1, 198, 189, - 61, 1, 198, 188, 61, 1, 198, 187, 61, 1, 198, 186, 61, 1, 197, 93, 61, 1, - 197, 92, 61, 1, 197, 91, 61, 1, 197, 90, 61, 1, 197, 89, 61, 1, 199, 144, - 61, 1, 199, 143, 61, 1, 199, 142, 61, 1, 199, 141, 61, 1, 199, 140, 61, - 1, 199, 139, 61, 1, 199, 138, 61, 1, 199, 137, 61, 1, 199, 136, 61, 1, - 198, 98, 61, 1, 198, 97, 61, 1, 198, 96, 61, 1, 198, 95, 61, 1, 198, 94, - 61, 1, 198, 93, 61, 1, 198, 92, 61, 1, 215, 6, 61, 1, 215, 5, 61, 1, 215, - 4, 61, 1, 215, 3, 61, 1, 215, 2, 61, 1, 215, 1, 61, 1, 215, 0, 61, 1, - 214, 255, 61, 1, 214, 254, 61, 1, 213, 218, 61, 1, 213, 217, 61, 1, 213, - 216, 61, 1, 213, 215, 61, 1, 213, 214, 61, 1, 213, 213, 61, 1, 213, 212, - 61, 1, 213, 211, 61, 1, 212, 177, 61, 1, 212, 176, 61, 1, 212, 175, 61, - 1, 214, 120, 61, 1, 214, 119, 61, 1, 214, 118, 61, 1, 214, 117, 61, 1, - 214, 116, 61, 1, 214, 115, 61, 1, 214, 114, 61, 1, 213, 42, 61, 1, 213, - 41, 61, 1, 213, 40, 61, 1, 213, 39, 61, 1, 213, 38, 61, 1, 230, 104, 61, - 1, 230, 101, 61, 1, 230, 100, 61, 1, 230, 99, 61, 1, 230, 98, 61, 1, 230, - 97, 61, 1, 230, 96, 61, 1, 230, 95, 61, 1, 230, 94, 61, 1, 230, 103, 61, - 1, 230, 102, 61, 1, 229, 157, 61, 1, 229, 156, 61, 1, 229, 155, 61, 1, - 229, 154, 61, 1, 229, 153, 61, 1, 229, 152, 61, 1, 229, 151, 61, 1, 228, - 158, 61, 1, 228, 157, 61, 1, 228, 156, 61, 1, 229, 244, 61, 1, 229, 243, - 61, 1, 229, 242, 61, 1, 229, 241, 61, 1, 229, 240, 61, 1, 229, 239, 61, - 1, 229, 238, 61, 1, 229, 22, 61, 1, 229, 21, 61, 1, 229, 20, 61, 1, 229, - 19, 61, 1, 229, 18, 61, 1, 229, 17, 61, 1, 229, 16, 61, 1, 229, 15, 61, - 1, 217, 159, 61, 1, 217, 158, 61, 1, 217, 157, 61, 1, 217, 156, 61, 1, - 217, 155, 61, 1, 217, 154, 61, 1, 217, 153, 61, 1, 216, 99, 61, 1, 216, - 98, 61, 1, 216, 97, 61, 1, 216, 96, 61, 1, 216, 95, 61, 1, 216, 94, 61, - 1, 216, 93, 61, 1, 215, 154, 61, 1, 215, 153, 61, 1, 215, 152, 61, 1, - 215, 151, 61, 1, 216, 231, 61, 1, 216, 230, 61, 1, 216, 229, 61, 1, 216, - 11, 61, 1, 216, 10, 61, 1, 216, 9, 61, 1, 216, 8, 61, 1, 216, 7, 61, 1, - 216, 6, 61, 1, 192, 148, 61, 1, 192, 147, 61, 1, 192, 146, 61, 1, 192, - 145, 61, 1, 192, 144, 61, 1, 192, 141, 61, 1, 191, 224, 61, 1, 191, 223, - 61, 1, 191, 222, 61, 1, 191, 221, 61, 1, 192, 11, 61, 1, 192, 10, 61, 1, - 192, 9, 61, 1, 192, 8, 61, 1, 192, 7, 61, 1, 192, 6, 61, 1, 207, 185, 61, - 1, 207, 184, 61, 1, 207, 183, 61, 1, 207, 182, 61, 1, 207, 0, 61, 1, 206, - 255, 61, 1, 206, 254, 61, 1, 206, 253, 61, 1, 206, 252, 61, 1, 206, 251, - 61, 1, 206, 250, 61, 1, 206, 67, 61, 1, 206, 66, 61, 1, 206, 65, 61, 1, - 206, 64, 61, 1, 206, 63, 61, 1, 206, 62, 61, 1, 207, 112, 61, 1, 207, - 111, 61, 1, 207, 110, 61, 1, 207, 109, 61, 1, 206, 161, 61, 1, 206, 160, - 61, 1, 206, 159, 61, 1, 206, 158, 61, 1, 206, 157, 61, 1, 206, 156, 61, - 1, 193, 189, 61, 1, 193, 188, 61, 1, 193, 187, 61, 1, 193, 186, 61, 1, - 193, 185, 61, 1, 193, 85, 61, 1, 193, 84, 61, 1, 193, 83, 61, 1, 193, 82, - 61, 1, 193, 81, 61, 1, 193, 124, 61, 1, 193, 123, 61, 1, 193, 122, 61, 1, - 193, 121, 61, 1, 193, 47, 61, 1, 193, 46, 61, 1, 193, 45, 61, 1, 193, 44, - 61, 1, 193, 43, 61, 1, 193, 42, 61, 1, 193, 41, 61, 1, 215, 58, 61, 1, - 215, 57, 229, 120, 1, 251, 14, 193, 0, 72, 1, 251, 14, 192, 33, 72, 1, - 251, 14, 192, 80, 72, 1, 251, 14, 193, 0, 229, 120, 1, 2, 221, 67, 229, - 120, 1, 2, 193, 86, 229, 120, 1, 2, 193, 125, 229, 120, 1, 2, 193, 48, - 72, 1, 2, 221, 67, 72, 1, 2, 193, 86, 72, 1, 2, 193, 125, 72, 1, 2, 193, - 48, 72, 1, 2, 215, 61, 46, 245, 24, 46, 245, 23, 46, 245, 22, 46, 245, - 21, 46, 245, 20, 46, 245, 19, 46, 245, 18, 46, 245, 17, 46, 245, 16, 46, - 245, 15, 46, 245, 14, 46, 245, 13, 46, 245, 12, 46, 245, 11, 46, 245, 10, - 46, 245, 9, 46, 245, 8, 46, 245, 7, 46, 245, 6, 46, 245, 5, 46, 245, 4, - 46, 245, 3, 46, 245, 2, 46, 245, 1, 46, 245, 0, 46, 244, 255, 46, 244, - 254, 46, 244, 253, 46, 244, 252, 46, 244, 251, 46, 244, 250, 46, 244, - 249, 46, 244, 248, 46, 244, 247, 46, 244, 246, 46, 244, 245, 46, 244, - 244, 46, 244, 243, 46, 244, 242, 46, 244, 241, 46, 244, 240, 46, 244, - 239, 46, 244, 238, 46, 244, 237, 46, 244, 236, 46, 244, 235, 46, 244, - 234, 46, 244, 233, 46, 244, 232, 46, 244, 231, 46, 244, 230, 46, 244, - 229, 46, 244, 228, 46, 244, 227, 46, 244, 226, 46, 244, 225, 46, 244, - 224, 46, 244, 223, 46, 244, 222, 46, 244, 221, 46, 244, 220, 46, 244, - 219, 46, 244, 218, 46, 244, 217, 46, 244, 216, 46, 244, 215, 46, 244, - 214, 46, 244, 213, 46, 244, 212, 46, 244, 211, 46, 244, 210, 46, 244, - 209, 46, 244, 208, 46, 244, 207, 46, 244, 206, 46, 244, 205, 46, 244, - 204, 46, 244, 203, 46, 244, 202, 46, 244, 201, 46, 244, 200, 46, 244, - 199, 46, 244, 198, 46, 244, 197, 46, 244, 196, 46, 244, 195, 46, 244, - 194, 46, 244, 193, 46, 244, 192, 46, 244, 191, 46, 244, 190, 46, 244, - 189, 46, 244, 188, 46, 244, 187, 46, 244, 186, 46, 244, 185, 46, 244, - 184, 46, 244, 183, 46, 244, 182, 46, 244, 181, 46, 244, 180, 46, 244, - 179, 46, 244, 178, 46, 244, 177, 46, 244, 176, 46, 244, 175, 46, 244, - 174, 46, 244, 173, 46, 244, 172, 46, 244, 171, 46, 244, 170, 46, 244, - 169, 46, 244, 168, 46, 244, 167, 46, 244, 166, 46, 244, 165, 46, 244, - 164, 46, 244, 163, 46, 244, 162, 46, 244, 161, 46, 244, 160, 46, 244, - 159, 46, 244, 158, 46, 244, 157, 46, 244, 156, 46, 244, 155, 46, 244, - 154, 46, 244, 153, 46, 244, 152, 46, 244, 151, 46, 244, 150, 46, 244, - 149, 46, 244, 148, 46, 244, 147, 46, 244, 146, 46, 244, 145, 46, 244, - 144, 46, 244, 143, 46, 244, 142, 46, 244, 141, 46, 244, 140, 46, 244, - 139, 46, 244, 138, 46, 244, 137, 46, 244, 136, 46, 244, 135, 46, 244, - 134, 46, 244, 133, 46, 244, 132, 46, 244, 131, 46, 244, 130, 46, 244, - 129, 46, 244, 128, 46, 244, 127, 46, 244, 126, 46, 244, 125, 46, 244, - 124, 46, 244, 123, 46, 244, 122, 46, 244, 121, 46, 244, 120, 46, 244, - 119, 46, 244, 118, 46, 244, 117, 46, 244, 116, 46, 244, 115, 46, 244, - 114, 46, 244, 113, 46, 244, 112, 46, 244, 111, 46, 244, 110, 46, 244, - 109, 46, 244, 108, 46, 244, 107, 46, 244, 106, 46, 244, 105, 46, 244, - 104, 46, 244, 103, 46, 244, 102, 46, 244, 101, 46, 244, 100, 46, 244, 99, - 46, 244, 98, 46, 244, 97, 46, 244, 96, 46, 244, 95, 46, 244, 94, 46, 244, - 93, 46, 244, 92, 46, 244, 91, 46, 244, 90, 46, 244, 89, 46, 244, 88, 46, - 244, 87, 46, 244, 86, 46, 244, 85, 46, 244, 84, 46, 244, 83, 46, 244, 82, - 46, 244, 81, 46, 244, 80, 46, 244, 79, 46, 244, 78, 46, 244, 77, 46, 244, - 76, 46, 244, 75, 46, 244, 74, 46, 244, 73, 46, 244, 72, 46, 244, 71, 46, - 244, 70, 46, 244, 69, 46, 244, 68, 46, 244, 67, 46, 244, 66, 46, 244, 65, - 46, 244, 64, 46, 244, 63, 46, 244, 62, 46, 244, 61, 46, 244, 60, 46, 244, - 59, 46, 244, 58, 46, 244, 57, 46, 244, 56, 46, 244, 55, 46, 244, 54, 46, - 244, 53, 46, 244, 52, 46, 244, 51, 46, 244, 50, 46, 244, 49, 46, 244, 48, - 46, 244, 47, 46, 244, 46, 46, 244, 45, 46, 244, 44, 46, 244, 43, 46, 244, - 42, 46, 244, 41, 46, 244, 40, 46, 244, 39, 46, 244, 38, 46, 244, 37, 46, - 244, 36, 46, 244, 35, 46, 244, 34, 46, 244, 33, 46, 244, 32, 46, 244, 31, - 46, 244, 30, 46, 244, 29, 46, 244, 28, 46, 244, 27, 46, 244, 26, 46, 244, - 25, 46, 244, 24, 46, 244, 23, 46, 244, 22, 46, 244, 21, 46, 244, 20, 46, - 244, 19, 46, 244, 18, 46, 244, 17, 46, 244, 16, 46, 244, 15, 46, 244, 14, - 46, 244, 13, 46, 244, 12, 46, 244, 11, 46, 244, 10, 46, 244, 9, 46, 244, - 8, 46, 244, 7, 46, 244, 6, 46, 244, 5, 46, 244, 4, 46, 244, 3, 46, 244, - 2, 46, 244, 1, 46, 244, 0, 46, 243, 255, 46, 243, 254, 46, 243, 253, 46, - 243, 252, 46, 243, 251, 46, 243, 250, 46, 243, 249, 46, 243, 248, 46, - 243, 247, 46, 243, 246, 46, 243, 245, 46, 243, 244, 46, 243, 243, 46, - 243, 242, 46, 243, 241, 46, 243, 240, 46, 243, 239, 46, 243, 238, 46, - 243, 237, 46, 243, 236, 46, 243, 235, 46, 243, 234, 46, 243, 233, 46, - 243, 232, 46, 243, 231, 46, 243, 230, 46, 243, 229, 46, 243, 228, 46, - 243, 227, 46, 243, 226, 46, 243, 225, 46, 243, 224, 46, 243, 223, 46, - 243, 222, 46, 243, 221, 46, 243, 220, 46, 243, 219, 46, 243, 218, 46, - 243, 217, 46, 243, 216, 46, 243, 215, 46, 243, 214, 46, 243, 213, 46, - 243, 212, 46, 243, 211, 46, 243, 210, 46, 243, 209, 46, 243, 208, 46, - 243, 207, 46, 243, 206, 46, 243, 205, 46, 243, 204, 46, 243, 203, 46, - 243, 202, 46, 243, 201, 46, 243, 200, 46, 243, 199, 46, 243, 198, 46, - 243, 197, 46, 243, 196, 46, 243, 195, 46, 243, 194, 46, 243, 193, 46, - 243, 192, 46, 243, 191, 46, 243, 190, 46, 243, 189, 46, 243, 188, 46, - 243, 187, 46, 243, 186, 46, 243, 185, 46, 243, 184, 46, 243, 183, 46, - 243, 182, 46, 243, 181, 46, 243, 180, 46, 243, 179, 46, 243, 178, 46, - 243, 177, 46, 243, 176, 46, 243, 175, 46, 243, 174, 46, 243, 173, 46, - 243, 172, 46, 243, 171, 46, 243, 170, 46, 243, 169, 46, 243, 168, 46, - 243, 167, 46, 243, 166, 46, 243, 165, 46, 243, 164, 46, 243, 163, 46, - 243, 162, 46, 243, 161, 46, 243, 160, 46, 243, 159, 46, 243, 158, 46, - 243, 157, 46, 243, 156, 46, 243, 155, 46, 243, 154, 46, 243, 153, 46, - 243, 152, 46, 243, 151, 46, 243, 150, 46, 243, 149, 46, 243, 148, 46, - 243, 147, 46, 243, 146, 46, 243, 145, 46, 243, 144, 46, 243, 143, 46, - 243, 142, 46, 243, 141, 124, 1, 230, 116, 124, 1, 192, 235, 124, 1, 210, - 236, 124, 1, 200, 43, 124, 1, 233, 175, 124, 1, 222, 152, 124, 1, 172, - 124, 1, 250, 120, 124, 1, 238, 127, 124, 1, 196, 12, 124, 1, 232, 51, - 124, 1, 146, 124, 1, 210, 237, 215, 61, 124, 1, 238, 128, 206, 8, 124, 1, - 233, 176, 215, 61, 124, 1, 222, 153, 218, 168, 124, 1, 207, 222, 206, 8, - 124, 1, 199, 51, 124, 1, 202, 82, 237, 69, 124, 1, 237, 69, 124, 1, 221, - 102, 124, 1, 202, 82, 223, 35, 124, 1, 229, 112, 124, 1, 219, 160, 124, - 1, 207, 7, 124, 1, 218, 168, 124, 1, 215, 61, 124, 1, 223, 35, 124, 1, - 206, 8, 124, 1, 218, 169, 215, 61, 124, 1, 215, 62, 218, 168, 124, 1, - 223, 36, 218, 168, 124, 1, 206, 9, 223, 35, 124, 1, 218, 169, 4, 236, - 140, 124, 1, 215, 62, 4, 236, 140, 124, 1, 223, 36, 4, 236, 140, 124, 1, - 223, 36, 4, 185, 223, 118, 23, 58, 124, 1, 206, 9, 4, 236, 140, 124, 1, - 206, 9, 4, 75, 60, 124, 1, 218, 169, 206, 8, 124, 1, 215, 62, 206, 8, - 124, 1, 223, 36, 206, 8, 124, 1, 206, 9, 206, 8, 124, 1, 218, 169, 215, - 62, 206, 8, 124, 1, 215, 62, 218, 169, 206, 8, 124, 1, 223, 36, 218, 169, - 206, 8, 124, 1, 206, 9, 223, 36, 206, 8, 124, 1, 223, 36, 206, 9, 4, 236, - 140, 124, 1, 223, 36, 215, 61, 124, 1, 223, 36, 215, 62, 206, 8, 124, 1, - 206, 9, 200, 43, 124, 1, 206, 9, 200, 44, 146, 124, 1, 206, 9, 210, 236, - 124, 1, 206, 9, 210, 237, 146, 124, 1, 200, 44, 206, 8, 124, 1, 200, 44, - 207, 222, 206, 8, 124, 1, 193, 224, 124, 1, 193, 97, 124, 1, 193, 225, - 146, 124, 1, 206, 9, 215, 61, 124, 1, 206, 9, 218, 168, 124, 1, 222, 153, - 207, 222, 206, 8, 124, 1, 232, 52, 207, 222, 206, 8, 124, 1, 206, 9, 222, - 152, 124, 1, 206, 9, 222, 153, 146, 124, 1, 65, 124, 1, 202, 82, 210, - 250, 124, 1, 211, 182, 124, 1, 74, 124, 1, 251, 66, 124, 1, 68, 124, 1, - 71, 124, 1, 223, 226, 124, 1, 203, 40, 68, 124, 1, 196, 139, 124, 1, 234, - 188, 124, 1, 202, 82, 234, 173, 124, 1, 206, 135, 68, 124, 1, 202, 82, - 234, 188, 124, 1, 179, 68, 124, 1, 192, 80, 124, 1, 66, 124, 1, 233, 242, - 124, 1, 192, 182, 124, 1, 126, 215, 61, 124, 1, 179, 66, 124, 1, 206, - 135, 66, 124, 1, 196, 141, 124, 1, 202, 82, 66, 124, 1, 211, 84, 124, 1, - 210, 250, 124, 1, 211, 19, 124, 1, 193, 190, 124, 1, 193, 48, 124, 1, - 193, 86, 124, 1, 193, 112, 124, 1, 193, 14, 124, 1, 214, 214, 66, 124, 1, - 214, 214, 74, 124, 1, 214, 214, 68, 124, 1, 214, 214, 65, 124, 1, 210, 0, - 251, 132, 124, 1, 210, 0, 251, 149, 124, 1, 202, 82, 234, 103, 124, 1, - 202, 82, 251, 132, 124, 1, 202, 82, 211, 104, 124, 1, 117, 218, 168, 124, - 252, 4, 45, 228, 241, 205, 58, 124, 252, 4, 216, 87, 228, 241, 205, 58, - 124, 252, 4, 50, 228, 241, 205, 58, 124, 252, 4, 130, 81, 205, 58, 124, - 252, 4, 216, 87, 81, 205, 58, 124, 252, 4, 137, 81, 205, 58, 124, 252, 4, - 250, 170, 205, 58, 124, 252, 4, 250, 170, 219, 215, 205, 58, 124, 252, 4, - 250, 170, 199, 188, 124, 252, 4, 250, 170, 199, 215, 124, 252, 4, 250, - 170, 235, 15, 102, 124, 252, 4, 250, 170, 228, 74, 102, 124, 252, 4, 250, - 170, 199, 189, 102, 124, 252, 4, 137, 252, 46, 124, 252, 4, 137, 198, - 172, 252, 46, 124, 252, 4, 137, 230, 210, 124, 252, 4, 137, 179, 230, - 210, 124, 252, 4, 137, 236, 140, 124, 252, 4, 137, 243, 10, 124, 252, 4, - 137, 219, 112, 124, 252, 4, 137, 193, 138, 124, 252, 4, 137, 195, 135, - 124, 252, 4, 130, 252, 46, 124, 252, 4, 130, 198, 172, 252, 46, 124, 252, - 4, 130, 230, 210, 124, 252, 4, 130, 179, 230, 210, 124, 252, 4, 130, 236, - 140, 124, 252, 4, 130, 243, 10, 124, 252, 4, 130, 219, 112, 124, 252, 4, - 130, 193, 138, 124, 252, 4, 130, 195, 135, 124, 252, 4, 130, 57, 124, 3, - 187, 4, 238, 217, 124, 199, 9, 1, 205, 34, 124, 55, 77, 124, 208, 152, - 243, 78, 232, 80, 201, 63, 203, 27, 232, 145, 1, 211, 2, 203, 27, 232, - 145, 239, 28, 211, 2, 203, 27, 232, 145, 144, 201, 78, 203, 27, 232, 145, - 133, 201, 78, 97, 33, 87, 230, 240, 213, 159, 206, 9, 220, 251, 211, 105, - 219, 224, 97, 33, 87, 213, 159, 206, 9, 220, 251, 211, 105, 219, 224, 97, - 33, 87, 197, 162, 211, 105, 219, 224, 97, 33, 87, 230, 240, 213, 159, - 211, 105, 219, 224, 97, 33, 87, 213, 159, 211, 105, 219, 224, 97, 33, 87, - 201, 179, 211, 105, 219, 224, 97, 33, 87, 217, 94, 209, 3, 211, 105, 219, - 224, 97, 33, 87, 209, 3, 211, 105, 219, 224, 97, 33, 87, 193, 231, 211, - 105, 219, 224, 97, 33, 87, 217, 94, 209, 3, 206, 9, 221, 181, 211, 105, - 219, 224, 97, 33, 87, 209, 3, 206, 9, 221, 181, 211, 105, 219, 224, 97, - 33, 87, 193, 231, 206, 9, 221, 181, 211, 105, 219, 224, 97, 33, 87, 230, - 240, 213, 159, 206, 9, 220, 251, 211, 105, 183, 97, 33, 87, 213, 159, - 206, 9, 220, 251, 211, 105, 183, 97, 33, 87, 197, 162, 211, 105, 183, 97, - 33, 87, 230, 240, 213, 159, 211, 105, 183, 97, 33, 87, 213, 159, 211, - 105, 183, 97, 33, 87, 201, 179, 211, 105, 183, 97, 33, 87, 217, 94, 209, - 3, 211, 105, 183, 97, 33, 87, 209, 3, 211, 105, 183, 97, 33, 87, 193, - 231, 211, 105, 183, 97, 33, 87, 217, 94, 209, 3, 206, 9, 221, 181, 211, - 105, 183, 97, 33, 87, 209, 3, 206, 9, 221, 181, 211, 105, 183, 97, 33, - 87, 193, 231, 206, 9, 221, 181, 211, 105, 183, 97, 33, 87, 197, 162, 206, - 9, 220, 250, 97, 33, 87, 217, 94, 209, 3, 206, 9, 220, 250, 97, 33, 87, - 201, 49, 217, 94, 209, 2, 97, 33, 87, 209, 3, 206, 9, 220, 250, 97, 33, - 87, 209, 3, 201, 48, 97, 33, 87, 193, 231, 206, 9, 220, 250, 97, 33, 87, - 217, 94, 209, 3, 201, 48, 97, 33, 87, 230, 240, 193, 230, 97, 33, 87, - 191, 83, 97, 33, 87, 211, 104, 97, 33, 87, 207, 124, 97, 33, 87, 198, - 157, 97, 33, 87, 248, 83, 97, 33, 87, 196, 156, 97, 33, 87, 209, 65, 97, - 33, 87, 219, 21, 97, 33, 87, 220, 200, 97, 33, 87, 222, 115, 97, 33, 87, - 191, 74, 97, 33, 87, 202, 105, 97, 33, 87, 207, 117, 97, 33, 87, 220, - 253, 211, 105, 219, 224, 97, 33, 198, 80, 207, 137, 87, 215, 162, 97, 33, - 198, 80, 207, 137, 87, 200, 153, 97, 33, 198, 80, 207, 137, 87, 197, 246, - 97, 33, 87, 191, 120, 97, 33, 87, 237, 105, 191, 120, 97, 33, 87, 211, - 25, 97, 33, 87, 209, 67, 97, 33, 87, 209, 68, 4, 81, 106, 97, 33, 87, - 243, 134, 97, 33, 87, 243, 135, 209, 45, 97, 33, 87, 211, 174, 97, 33, - 87, 202, 10, 212, 249, 97, 33, 87, 198, 89, 97, 33, 87, 235, 48, 97, 33, - 250, 169, 81, 211, 109, 97, 33, 87, 238, 163, 211, 109, 97, 33, 87, 220, - 252, 97, 33, 110, 198, 80, 207, 137, 223, 144, 97, 208, 203, 52, 219, - 167, 97, 208, 203, 52, 219, 166, 97, 208, 203, 52, 236, 233, 232, 195, - 97, 208, 203, 52, 220, 252, 97, 208, 203, 52, 206, 144, 97, 161, 221, 0, - 97, 161, 221, 1, 198, 156, 97, 161, 210, 122, 97, 161, 235, 56, 196, 13, - 243, 113, 97, 161, 221, 90, 97, 161, 191, 105, 97, 161, 201, 61, 97, 161, - 201, 62, 206, 9, 211, 163, 97, 161, 210, 10, 97, 161, 210, 11, 214, 96, - 97, 161, 201, 62, 4, 202, 10, 212, 249, 97, 161, 243, 112, 97, 161, 210, - 186, 97, 161, 191, 103, 97, 161, 230, 248, 248, 82, 97, 161, 230, 248, - 198, 156, 97, 161, 230, 248, 215, 160, 97, 161, 230, 248, 200, 152, 97, - 161, 230, 248, 197, 245, 97, 161, 194, 253, 208, 183, 97, 161, 194, 253, - 215, 163, 97, 161, 194, 253, 200, 154, 97, 161, 194, 253, 197, 247, 97, - 161, 194, 253, 221, 85, 208, 183, 97, 161, 194, 253, 221, 85, 215, 163, - 97, 161, 194, 253, 221, 85, 200, 154, 97, 161, 194, 253, 221, 85, 197, - 247, 97, 161, 55, 191, 103, 97, 161, 207, 18, 243, 112, 97, 161, 237, 91, - 97, 161, 221, 207, 97, 161, 243, 134, 97, 161, 209, 67, 97, 161, 202, - 113, 215, 163, 97, 161, 202, 113, 200, 154, 97, 161, 202, 113, 197, 247, - 97, 161, 202, 113, 198, 157, 97, 161, 237, 105, 221, 90, 97, 161, 202, - 113, 221, 85, 200, 154, 97, 161, 202, 113, 221, 89, 97, 161, 202, 113, - 221, 85, 198, 157, 97, 161, 202, 113, 235, 53, 208, 183, 97, 161, 202, - 113, 235, 53, 200, 154, 97, 161, 202, 113, 235, 53, 214, 96, 97, 161, - 202, 113, 235, 53, 221, 84, 97, 161, 202, 72, 97, 161, 202, 73, 206, 9, - 191, 101, 97, 161, 202, 73, 191, 110, 97, 161, 202, 73, 206, 9, 220, 250, - 97, 161, 220, 252, 97, 161, 206, 144, 97, 161, 232, 228, 97, 161, 221, - 59, 97, 161, 191, 8, 97, 161, 201, 90, 97, 161, 201, 91, 206, 9, 191, - 101, 97, 161, 201, 91, 206, 9, 220, 250, 97, 161, 201, 91, 206, 9, 191, - 102, 228, 74, 220, 250, 97, 161, 201, 91, 206, 9, 220, 251, 228, 74, 191, - 101, 97, 161, 201, 91, 191, 111, 97, 161, 201, 91, 191, 112, 206, 9, 191, - 101, 97, 161, 201, 91, 206, 9, 206, 143, 97, 161, 201, 91, 206, 9, 235, - 47, 191, 100, 97, 161, 201, 91, 206, 9, 191, 102, 228, 74, 209, 66, 97, - 161, 209, 47, 97, 161, 201, 91, 214, 96, 97, 161, 201, 40, 208, 183, 97, - 161, 201, 40, 215, 161, 97, 161, 201, 40, 220, 249, 97, 161, 201, 40, - 209, 43, 97, 161, 201, 40, 209, 5, 97, 161, 201, 40, 214, 96, 97, 161, - 201, 40, 221, 87, 97, 161, 201, 40, 221, 89, 97, 161, 201, 40, 198, 158, - 208, 130, 97, 161, 201, 40, 235, 52, 97, 161, 201, 40, 235, 51, 97, 161, - 201, 40, 235, 49, 97, 161, 201, 40, 235, 53, 221, 84, 97, 161, 201, 40, - 235, 50, 221, 84, 97, 161, 201, 40, 230, 195, 4, 202, 170, 191, 103, 97, - 161, 201, 40, 230, 191, 4, 202, 170, 191, 103, 97, 161, 201, 40, 230, - 194, 97, 161, 201, 40, 230, 190, 97, 161, 201, 40, 230, 191, 4, 55, 191, - 103, 97, 161, 201, 40, 230, 192, 97, 161, 201, 40, 230, 193, 209, 5, 97, - 161, 216, 221, 97, 161, 216, 222, 209, 4, 97, 161, 216, 222, 221, 83, 97, - 161, 216, 222, 221, 86, 97, 161, 216, 222, 221, 88, 97, 161, 201, 40, - 197, 174, 97, 161, 201, 40, 197, 173, 97, 161, 201, 40, 197, 172, 97, - 161, 211, 31, 97, 161, 211, 32, 200, 154, 97, 161, 211, 32, 197, 247, 97, - 161, 211, 32, 220, 255, 200, 154, 97, 161, 211, 32, 221, 85, 200, 154, - 97, 161, 211, 32, 221, 85, 214, 96, 97, 161, 201, 40, 220, 254, 97, 161, - 201, 40, 220, 255, 209, 5, 97, 161, 201, 40, 220, 255, 230, 195, 4, 202, - 170, 191, 103, 97, 161, 201, 40, 220, 255, 230, 191, 4, 202, 170, 191, - 103, 97, 161, 201, 40, 220, 255, 230, 194, 97, 161, 201, 40, 220, 255, - 230, 190, 97, 161, 201, 40, 220, 255, 230, 191, 4, 55, 191, 103, 97, 161, - 201, 40, 220, 255, 230, 192, 97, 161, 201, 40, 220, 255, 230, 193, 209, - 5, 97, 161, 201, 40, 220, 255, 197, 175, 97, 161, 220, 214, 97, 161, 211, - 173, 97, 161, 235, 84, 97, 161, 214, 103, 97, 161, 210, 79, 73, 37, 16, - 208, 169, 73, 37, 16, 237, 217, 73, 37, 16, 210, 4, 73, 37, 16, 210, 246, - 234, 144, 73, 37, 16, 210, 246, 236, 238, 73, 37, 16, 195, 172, 234, 144, - 73, 37, 16, 195, 172, 236, 238, 73, 37, 16, 222, 44, 73, 37, 16, 200, 60, - 73, 37, 16, 210, 120, 73, 37, 16, 191, 231, 73, 37, 16, 191, 232, 236, - 238, 73, 37, 16, 221, 3, 73, 37, 16, 251, 61, 234, 144, 73, 37, 16, 233, - 210, 234, 144, 73, 37, 16, 199, 108, 73, 37, 16, 221, 247, 73, 37, 16, - 251, 50, 73, 37, 16, 251, 51, 236, 238, 73, 37, 16, 200, 67, 73, 37, 16, - 198, 244, 73, 37, 16, 211, 116, 251, 12, 73, 37, 16, 230, 238, 251, 12, - 73, 37, 16, 208, 168, 73, 37, 16, 246, 248, 73, 37, 16, 195, 161, 73, 37, - 16, 223, 58, 251, 12, 73, 37, 16, 221, 249, 251, 12, 73, 37, 16, 221, - 248, 251, 12, 73, 37, 16, 205, 105, 73, 37, 16, 210, 110, 73, 37, 16, - 201, 88, 251, 54, 73, 37, 16, 210, 245, 251, 12, 73, 37, 16, 195, 171, - 251, 12, 73, 37, 16, 251, 55, 251, 12, 73, 37, 16, 251, 48, 73, 37, 16, - 221, 92, 73, 37, 16, 207, 14, 73, 37, 16, 209, 183, 251, 12, 73, 37, 16, - 198, 142, 73, 37, 16, 251, 128, 73, 37, 16, 205, 37, 73, 37, 16, 200, 71, - 251, 12, 73, 37, 16, 200, 71, 216, 166, 201, 86, 73, 37, 16, 210, 240, - 251, 12, 73, 37, 16, 199, 27, 73, 37, 16, 219, 202, 73, 37, 16, 235, 38, - 73, 37, 16, 197, 243, 73, 37, 16, 199, 76, 73, 37, 16, 221, 6, 73, 37, - 16, 251, 61, 233, 210, 214, 98, 73, 37, 16, 232, 88, 251, 12, 73, 37, 16, - 223, 175, 73, 37, 16, 197, 210, 251, 12, 73, 37, 16, 222, 47, 197, 209, - 73, 37, 16, 210, 36, 73, 37, 16, 208, 173, 73, 37, 16, 221, 42, 73, 37, - 16, 243, 60, 251, 12, 73, 37, 16, 207, 135, 73, 37, 16, 210, 124, 251, - 12, 73, 37, 16, 210, 121, 251, 12, 73, 37, 16, 228, 24, 73, 37, 16, 214, - 225, 73, 37, 16, 209, 238, 73, 37, 16, 221, 43, 251, 167, 73, 37, 16, - 197, 210, 251, 167, 73, 37, 16, 201, 55, 73, 37, 16, 230, 189, 73, 37, - 16, 223, 58, 214, 98, 73, 37, 16, 211, 116, 214, 98, 73, 37, 16, 210, - 246, 214, 98, 73, 37, 16, 209, 237, 73, 37, 16, 221, 26, 73, 37, 16, 209, - 236, 73, 37, 16, 221, 5, 73, 37, 16, 210, 37, 214, 98, 73, 37, 16, 221, - 248, 214, 99, 251, 93, 73, 37, 16, 221, 249, 214, 99, 251, 93, 73, 37, - 16, 191, 229, 73, 37, 16, 251, 51, 214, 98, 73, 37, 16, 251, 52, 200, 68, - 214, 98, 73, 37, 16, 191, 230, 73, 37, 16, 221, 4, 73, 37, 16, 234, 139, - 73, 37, 16, 246, 249, 73, 37, 16, 216, 57, 223, 57, 73, 37, 16, 195, 172, - 214, 98, 73, 37, 16, 209, 183, 214, 98, 73, 37, 16, 208, 174, 214, 98, - 73, 37, 16, 211, 112, 73, 37, 16, 251, 80, 73, 37, 16, 218, 179, 73, 37, - 16, 210, 121, 214, 98, 73, 37, 16, 210, 124, 214, 98, 73, 37, 16, 233, - 249, 210, 123, 73, 37, 16, 220, 147, 73, 37, 16, 251, 81, 73, 37, 16, - 197, 210, 214, 98, 73, 37, 16, 234, 142, 73, 37, 16, 200, 71, 214, 98, - 73, 37, 16, 200, 61, 73, 37, 16, 243, 60, 214, 98, 73, 37, 16, 234, 53, - 73, 37, 16, 205, 38, 214, 98, 73, 37, 16, 192, 199, 221, 92, 73, 37, 16, - 197, 207, 73, 37, 16, 208, 175, 73, 37, 16, 197, 211, 73, 37, 16, 197, - 208, 73, 37, 16, 208, 172, 73, 37, 16, 197, 206, 73, 37, 16, 208, 171, - 73, 37, 16, 230, 237, 73, 37, 16, 251, 4, 73, 37, 16, 233, 249, 251, 4, - 73, 37, 16, 210, 240, 214, 98, 73, 37, 16, 199, 26, 234, 6, 73, 37, 16, - 199, 26, 233, 209, 73, 37, 16, 199, 28, 251, 56, 73, 37, 16, 199, 20, - 222, 103, 251, 47, 73, 37, 16, 222, 46, 73, 37, 16, 234, 90, 73, 37, 16, - 192, 38, 222, 43, 73, 37, 16, 192, 38, 251, 93, 73, 37, 16, 201, 87, 73, - 37, 16, 221, 93, 251, 93, 73, 37, 16, 236, 239, 251, 12, 73, 37, 16, 221, - 7, 251, 12, 73, 37, 16, 221, 7, 251, 167, 73, 37, 16, 221, 7, 214, 98, - 73, 37, 16, 251, 55, 214, 98, 73, 37, 16, 251, 57, 73, 37, 16, 236, 238, - 73, 37, 16, 197, 223, 73, 37, 16, 199, 66, 73, 37, 16, 221, 30, 73, 37, - 16, 219, 207, 234, 83, 243, 50, 73, 37, 16, 219, 207, 235, 39, 243, 51, - 73, 37, 16, 219, 207, 197, 226, 243, 51, 73, 37, 16, 219, 207, 199, 78, - 243, 51, 73, 37, 16, 219, 207, 223, 170, 243, 50, 73, 37, 16, 230, 238, - 214, 99, 251, 93, 73, 37, 16, 230, 238, 210, 111, 251, 0, 73, 37, 16, - 230, 238, 210, 111, 237, 73, 73, 37, 16, 237, 7, 73, 37, 16, 237, 8, 210, - 111, 251, 1, 222, 43, 73, 37, 16, 237, 8, 210, 111, 251, 1, 251, 93, 73, - 37, 16, 237, 8, 210, 111, 237, 73, 73, 37, 16, 197, 232, 73, 37, 16, 251, - 5, 73, 37, 16, 223, 177, 73, 37, 16, 237, 30, 73, 37, 16, 251, 247, 209, - 51, 251, 6, 73, 37, 16, 251, 247, 251, 3, 73, 37, 16, 251, 247, 251, 6, - 73, 37, 16, 251, 247, 216, 160, 73, 37, 16, 251, 247, 216, 171, 73, 37, - 16, 251, 247, 230, 239, 73, 37, 16, 251, 247, 230, 236, 73, 37, 16, 251, - 247, 209, 51, 230, 239, 73, 37, 16, 217, 45, 208, 181, 228, 22, 73, 37, - 16, 217, 45, 251, 169, 208, 181, 228, 22, 73, 37, 16, 217, 45, 237, 72, - 228, 22, 73, 37, 16, 217, 45, 251, 169, 237, 72, 228, 22, 73, 37, 16, - 217, 45, 197, 218, 228, 22, 73, 37, 16, 217, 45, 197, 233, 73, 37, 16, - 217, 45, 199, 71, 228, 22, 73, 37, 16, 217, 45, 199, 71, 219, 211, 228, - 22, 73, 37, 16, 217, 45, 219, 211, 228, 22, 73, 37, 16, 217, 45, 209, - 105, 228, 22, 73, 37, 16, 223, 66, 199, 101, 228, 23, 73, 37, 16, 251, - 52, 199, 101, 228, 23, 73, 37, 16, 233, 79, 199, 68, 73, 37, 16, 233, 79, - 215, 222, 73, 37, 16, 233, 79, 237, 13, 73, 37, 16, 217, 45, 195, 165, - 228, 22, 73, 37, 16, 217, 45, 208, 180, 228, 22, 73, 37, 16, 217, 45, - 209, 105, 199, 71, 228, 22, 73, 37, 16, 230, 233, 215, 62, 251, 56, 73, - 37, 16, 230, 233, 215, 62, 236, 237, 73, 37, 16, 234, 101, 222, 103, 232, - 88, 195, 3, 73, 37, 16, 223, 176, 73, 37, 16, 223, 174, 73, 37, 16, 232, - 88, 251, 13, 237, 71, 228, 21, 73, 37, 16, 232, 88, 237, 28, 168, 73, 37, - 16, 232, 88, 237, 28, 214, 225, 73, 37, 16, 232, 88, 214, 219, 228, 22, - 73, 37, 16, 232, 88, 237, 28, 237, 44, 73, 37, 16, 232, 88, 202, 106, - 237, 27, 237, 44, 73, 37, 16, 232, 88, 237, 28, 222, 22, 73, 37, 16, 232, - 88, 237, 28, 191, 7, 73, 37, 16, 232, 88, 237, 28, 213, 220, 222, 43, 73, - 37, 16, 232, 88, 237, 28, 213, 220, 251, 93, 73, 37, 16, 232, 88, 217, - 98, 243, 52, 237, 13, 73, 37, 16, 232, 88, 217, 98, 243, 52, 215, 222, - 73, 37, 16, 233, 24, 202, 106, 243, 52, 195, 164, 73, 37, 16, 232, 88, - 202, 106, 243, 52, 200, 72, 73, 37, 16, 232, 88, 214, 101, 73, 37, 16, - 243, 53, 190, 230, 73, 37, 16, 243, 53, 221, 91, 73, 37, 16, 243, 53, - 201, 238, 73, 37, 16, 232, 88, 228, 74, 192, 37, 199, 72, 73, 37, 16, - 232, 88, 234, 102, 251, 82, 73, 37, 16, 192, 37, 197, 219, 73, 37, 16, - 237, 21, 197, 219, 73, 37, 16, 237, 21, 199, 72, 73, 37, 16, 237, 21, - 251, 58, 235, 39, 236, 166, 73, 37, 16, 237, 21, 215, 220, 199, 77, 236, - 166, 73, 37, 16, 237, 21, 237, 4, 233, 222, 236, 166, 73, 37, 16, 237, - 21, 197, 230, 211, 122, 236, 166, 73, 37, 16, 192, 37, 251, 58, 235, 39, - 236, 166, 73, 37, 16, 192, 37, 215, 220, 199, 77, 236, 166, 73, 37, 16, - 192, 37, 237, 4, 233, 222, 236, 166, 73, 37, 16, 192, 37, 197, 230, 211, - 122, 236, 166, 73, 37, 16, 231, 147, 237, 20, 73, 37, 16, 231, 147, 192, - 36, 73, 37, 16, 237, 29, 251, 58, 216, 58, 73, 37, 16, 237, 29, 251, 58, - 216, 202, 73, 37, 16, 237, 29, 236, 238, 73, 37, 16, 237, 29, 199, 18, - 73, 37, 16, 202, 181, 199, 18, 73, 37, 16, 202, 181, 199, 19, 236, 221, - 73, 37, 16, 202, 181, 199, 19, 197, 220, 73, 37, 16, 202, 181, 199, 19, - 199, 64, 73, 37, 16, 202, 181, 250, 228, 73, 37, 16, 202, 181, 250, 229, - 236, 221, 73, 37, 16, 202, 181, 250, 229, 197, 220, 73, 37, 16, 202, 181, - 250, 229, 199, 64, 73, 37, 16, 237, 5, 231, 128, 73, 37, 16, 237, 12, - 211, 19, 73, 37, 16, 201, 73, 73, 37, 16, 250, 253, 168, 73, 37, 16, 250, - 253, 195, 3, 73, 37, 16, 250, 253, 231, 240, 73, 37, 16, 250, 253, 237, - 44, 73, 37, 16, 250, 253, 222, 22, 73, 37, 16, 250, 253, 191, 7, 73, 37, - 16, 250, 253, 213, 219, 73, 37, 16, 221, 248, 214, 99, 216, 170, 73, 37, - 16, 221, 249, 214, 99, 216, 170, 73, 37, 16, 221, 248, 214, 99, 222, 43, - 73, 37, 16, 221, 249, 214, 99, 222, 43, 73, 37, 16, 221, 93, 222, 43, 73, - 37, 16, 230, 238, 214, 99, 222, 43, 37, 16, 202, 170, 249, 83, 37, 16, - 55, 249, 83, 37, 16, 53, 249, 83, 37, 16, 207, 19, 53, 249, 83, 37, 16, - 237, 214, 249, 83, 37, 16, 203, 40, 249, 83, 37, 16, 45, 207, 49, 56, 37, - 16, 50, 207, 49, 56, 37, 16, 207, 49, 236, 138, 37, 16, 238, 4, 205, 41, - 37, 16, 238, 33, 247, 108, 37, 16, 205, 41, 37, 16, 242, 92, 37, 16, 207, - 47, 233, 11, 37, 16, 207, 47, 233, 10, 37, 16, 207, 47, 233, 9, 37, 16, - 233, 34, 37, 16, 233, 35, 60, 37, 16, 248, 39, 77, 37, 16, 247, 150, 37, - 16, 248, 55, 37, 16, 248, 53, 37, 16, 211, 99, 201, 111, 37, 16, 197, 12, - 201, 111, 37, 16, 198, 220, 201, 111, 37, 16, 232, 127, 201, 111, 37, 16, - 232, 224, 201, 111, 37, 16, 202, 135, 201, 111, 37, 16, 202, 133, 232, - 105, 37, 16, 232, 125, 232, 105, 37, 16, 232, 52, 242, 235, 37, 16, 232, - 52, 242, 236, 211, 23, 251, 158, 37, 16, 232, 52, 242, 236, 211, 23, 249, - 66, 37, 16, 247, 194, 242, 235, 37, 16, 233, 176, 242, 235, 37, 16, 233, - 176, 242, 236, 211, 23, 251, 158, 37, 16, 233, 176, 242, 236, 211, 23, - 249, 66, 37, 16, 235, 95, 242, 234, 37, 16, 235, 95, 242, 233, 37, 16, - 215, 129, 216, 228, 207, 30, 37, 16, 55, 203, 126, 37, 16, 55, 232, 206, - 37, 16, 232, 207, 196, 77, 37, 16, 232, 207, 235, 123, 37, 16, 214, 206, - 196, 77, 37, 16, 214, 206, 235, 123, 37, 16, 203, 127, 196, 77, 37, 16, - 203, 127, 235, 123, 37, 16, 208, 23, 163, 203, 126, 37, 16, 208, 23, 163, - 232, 206, 37, 16, 242, 71, 198, 146, 37, 16, 238, 155, 198, 146, 37, 16, - 211, 23, 251, 158, 37, 16, 211, 23, 249, 66, 37, 16, 208, 3, 251, 158, - 37, 16, 208, 3, 249, 66, 37, 16, 215, 132, 207, 30, 37, 16, 193, 87, 207, - 30, 37, 16, 132, 207, 30, 37, 16, 208, 23, 207, 30, 37, 16, 234, 160, - 207, 30, 37, 16, 202, 129, 207, 30, 37, 16, 198, 246, 207, 30, 37, 16, - 202, 119, 207, 30, 37, 16, 91, 228, 141, 197, 30, 207, 30, 37, 16, 192, - 236, 213, 2, 37, 16, 108, 213, 2, 37, 16, 243, 11, 192, 236, 213, 2, 37, - 16, 51, 213, 3, 193, 89, 37, 16, 51, 213, 3, 248, 139, 37, 16, 197, 242, - 213, 3, 133, 193, 89, 37, 16, 197, 242, 213, 3, 133, 248, 139, 37, 16, - 197, 242, 213, 3, 45, 193, 89, 37, 16, 197, 242, 213, 3, 45, 248, 139, - 37, 16, 197, 242, 213, 3, 50, 193, 89, 37, 16, 197, 242, 213, 3, 50, 248, - 139, 37, 16, 197, 242, 213, 3, 144, 193, 89, 37, 16, 197, 242, 213, 3, - 144, 248, 139, 37, 16, 197, 242, 213, 3, 133, 50, 193, 89, 37, 16, 197, - 242, 213, 3, 133, 50, 248, 139, 37, 16, 215, 206, 213, 3, 193, 89, 37, - 16, 215, 206, 213, 3, 248, 139, 37, 16, 197, 239, 213, 3, 144, 193, 89, - 37, 16, 197, 239, 213, 3, 144, 248, 139, 37, 16, 210, 114, 213, 2, 37, - 16, 195, 17, 213, 2, 37, 16, 213, 3, 248, 139, 37, 16, 212, 139, 213, 2, - 37, 16, 242, 203, 213, 3, 193, 89, 37, 16, 242, 203, 213, 3, 248, 139, - 37, 16, 248, 36, 37, 16, 193, 87, 213, 6, 37, 16, 132, 213, 6, 37, 16, - 208, 23, 213, 6, 37, 16, 234, 160, 213, 6, 37, 16, 202, 129, 213, 6, 37, - 16, 198, 246, 213, 6, 37, 16, 202, 119, 213, 6, 37, 16, 91, 228, 141, - 197, 30, 213, 6, 37, 16, 33, 201, 80, 37, 16, 33, 201, 197, 201, 80, 37, + 245, 28, 41, 2, 27, 245, 27, 72, 1, 216, 38, 198, 77, 72, 1, 216, 38, + 198, 76, 72, 1, 216, 38, 198, 75, 72, 1, 216, 38, 198, 74, 72, 1, 216, + 38, 198, 72, 72, 1, 216, 38, 198, 71, 72, 1, 216, 38, 214, 213, 198, 78, + 72, 1, 216, 38, 214, 213, 198, 77, 72, 1, 216, 38, 214, 213, 198, 76, 72, + 1, 216, 38, 214, 213, 198, 75, 72, 1, 216, 38, 214, 213, 198, 74, 72, 1, + 216, 38, 214, 213, 198, 72, 72, 1, 216, 38, 214, 213, 198, 71, 72, 1, + 251, 16, 71, 229, 122, 1, 251, 16, 192, 80, 61, 1, 255, 208, 61, 1, 255, + 207, 61, 1, 255, 206, 61, 1, 255, 202, 61, 1, 228, 75, 61, 1, 228, 74, + 61, 1, 228, 73, 61, 1, 228, 72, 61, 1, 196, 231, 61, 1, 196, 230, 61, 1, + 196, 229, 61, 1, 196, 228, 61, 1, 196, 227, 61, 1, 235, 15, 61, 1, 235, + 14, 61, 1, 235, 13, 61, 1, 235, 12, 61, 1, 235, 11, 61, 1, 212, 16, 61, + 1, 212, 15, 61, 1, 212, 14, 61, 1, 222, 143, 61, 1, 222, 140, 61, 1, 222, + 139, 61, 1, 222, 138, 61, 1, 222, 137, 61, 1, 222, 136, 61, 1, 222, 135, + 61, 1, 222, 134, 61, 1, 222, 133, 61, 1, 222, 142, 61, 1, 222, 141, 61, + 1, 222, 132, 61, 1, 221, 167, 61, 1, 221, 166, 61, 1, 221, 165, 61, 1, + 221, 164, 61, 1, 221, 163, 61, 1, 221, 162, 61, 1, 221, 161, 61, 1, 221, + 160, 61, 1, 220, 233, 61, 1, 220, 232, 61, 1, 220, 231, 61, 1, 220, 230, + 61, 1, 220, 229, 61, 1, 220, 228, 61, 1, 220, 227, 61, 1, 222, 23, 61, 1, + 222, 22, 61, 1, 222, 21, 61, 1, 222, 20, 61, 1, 222, 19, 61, 1, 222, 18, + 61, 1, 221, 68, 61, 1, 221, 67, 61, 1, 221, 66, 61, 1, 221, 65, 61, 1, + 205, 207, 61, 1, 205, 206, 61, 1, 205, 205, 61, 1, 205, 204, 61, 1, 205, + 203, 61, 1, 205, 202, 61, 1, 205, 201, 61, 1, 205, 200, 61, 1, 202, 222, + 61, 1, 202, 221, 61, 1, 202, 220, 61, 1, 202, 219, 61, 1, 202, 218, 61, + 1, 202, 217, 61, 1, 201, 4, 61, 1, 201, 3, 61, 1, 201, 2, 61, 1, 201, 1, + 61, 1, 201, 0, 61, 1, 200, 255, 61, 1, 200, 254, 61, 1, 200, 253, 61, 1, + 205, 68, 61, 1, 205, 67, 61, 1, 205, 66, 61, 1, 205, 65, 61, 1, 205, 64, + 61, 1, 202, 46, 61, 1, 202, 45, 61, 1, 202, 44, 61, 1, 202, 43, 61, 1, + 202, 42, 61, 1, 202, 41, 61, 1, 202, 40, 61, 1, 199, 251, 61, 1, 199, + 250, 61, 1, 199, 249, 61, 1, 199, 248, 61, 1, 198, 192, 61, 1, 198, 191, + 61, 1, 198, 190, 61, 1, 198, 189, 61, 1, 198, 188, 61, 1, 198, 187, 61, + 1, 198, 186, 61, 1, 197, 93, 61, 1, 197, 92, 61, 1, 197, 91, 61, 1, 197, + 90, 61, 1, 197, 89, 61, 1, 199, 144, 61, 1, 199, 143, 61, 1, 199, 142, + 61, 1, 199, 141, 61, 1, 199, 140, 61, 1, 199, 139, 61, 1, 199, 138, 61, + 1, 199, 137, 61, 1, 199, 136, 61, 1, 198, 98, 61, 1, 198, 97, 61, 1, 198, + 96, 61, 1, 198, 95, 61, 1, 198, 94, 61, 1, 198, 93, 61, 1, 198, 92, 61, + 1, 215, 8, 61, 1, 215, 7, 61, 1, 215, 6, 61, 1, 215, 5, 61, 1, 215, 4, + 61, 1, 215, 3, 61, 1, 215, 2, 61, 1, 215, 1, 61, 1, 215, 0, 61, 1, 213, + 220, 61, 1, 213, 219, 61, 1, 213, 218, 61, 1, 213, 217, 61, 1, 213, 216, + 61, 1, 213, 215, 61, 1, 213, 214, 61, 1, 213, 213, 61, 1, 212, 179, 61, + 1, 212, 178, 61, 1, 212, 177, 61, 1, 214, 122, 61, 1, 214, 121, 61, 1, + 214, 120, 61, 1, 214, 119, 61, 1, 214, 118, 61, 1, 214, 117, 61, 1, 214, + 116, 61, 1, 213, 44, 61, 1, 213, 43, 61, 1, 213, 42, 61, 1, 213, 41, 61, + 1, 213, 40, 61, 1, 230, 106, 61, 1, 230, 103, 61, 1, 230, 102, 61, 1, + 230, 101, 61, 1, 230, 100, 61, 1, 230, 99, 61, 1, 230, 98, 61, 1, 230, + 97, 61, 1, 230, 96, 61, 1, 230, 105, 61, 1, 230, 104, 61, 1, 229, 159, + 61, 1, 229, 158, 61, 1, 229, 157, 61, 1, 229, 156, 61, 1, 229, 155, 61, + 1, 229, 154, 61, 1, 229, 153, 61, 1, 228, 160, 61, 1, 228, 159, 61, 1, + 228, 158, 61, 1, 229, 246, 61, 1, 229, 245, 61, 1, 229, 244, 61, 1, 229, + 243, 61, 1, 229, 242, 61, 1, 229, 241, 61, 1, 229, 240, 61, 1, 229, 24, + 61, 1, 229, 23, 61, 1, 229, 22, 61, 1, 229, 21, 61, 1, 229, 20, 61, 1, + 229, 19, 61, 1, 229, 18, 61, 1, 229, 17, 61, 1, 217, 161, 61, 1, 217, + 160, 61, 1, 217, 159, 61, 1, 217, 158, 61, 1, 217, 157, 61, 1, 217, 156, + 61, 1, 217, 155, 61, 1, 216, 101, 61, 1, 216, 100, 61, 1, 216, 99, 61, 1, + 216, 98, 61, 1, 216, 97, 61, 1, 216, 96, 61, 1, 216, 95, 61, 1, 215, 156, + 61, 1, 215, 155, 61, 1, 215, 154, 61, 1, 215, 153, 61, 1, 216, 233, 61, + 1, 216, 232, 61, 1, 216, 231, 61, 1, 216, 13, 61, 1, 216, 12, 61, 1, 216, + 11, 61, 1, 216, 10, 61, 1, 216, 9, 61, 1, 216, 8, 61, 1, 192, 148, 61, 1, + 192, 147, 61, 1, 192, 146, 61, 1, 192, 145, 61, 1, 192, 144, 61, 1, 192, + 141, 61, 1, 191, 224, 61, 1, 191, 223, 61, 1, 191, 222, 61, 1, 191, 221, + 61, 1, 192, 11, 61, 1, 192, 10, 61, 1, 192, 9, 61, 1, 192, 8, 61, 1, 192, + 7, 61, 1, 192, 6, 61, 1, 207, 187, 61, 1, 207, 186, 61, 1, 207, 185, 61, + 1, 207, 184, 61, 1, 207, 1, 61, 1, 207, 0, 61, 1, 206, 255, 61, 1, 206, + 254, 61, 1, 206, 253, 61, 1, 206, 252, 61, 1, 206, 251, 61, 1, 206, 68, + 61, 1, 206, 67, 61, 1, 206, 66, 61, 1, 206, 65, 61, 1, 206, 64, 61, 1, + 206, 63, 61, 1, 207, 114, 61, 1, 207, 113, 61, 1, 207, 112, 61, 1, 207, + 111, 61, 1, 206, 162, 61, 1, 206, 161, 61, 1, 206, 160, 61, 1, 206, 159, + 61, 1, 206, 158, 61, 1, 206, 157, 61, 1, 193, 189, 61, 1, 193, 188, 61, + 1, 193, 187, 61, 1, 193, 186, 61, 1, 193, 185, 61, 1, 193, 85, 61, 1, + 193, 84, 61, 1, 193, 83, 61, 1, 193, 82, 61, 1, 193, 81, 61, 1, 193, 124, + 61, 1, 193, 123, 61, 1, 193, 122, 61, 1, 193, 121, 61, 1, 193, 47, 61, 1, + 193, 46, 61, 1, 193, 45, 61, 1, 193, 44, 61, 1, 193, 43, 61, 1, 193, 42, + 61, 1, 193, 41, 61, 1, 215, 60, 61, 1, 215, 59, 229, 122, 1, 251, 16, + 193, 0, 72, 1, 251, 16, 192, 33, 72, 1, 251, 16, 192, 80, 72, 1, 251, 16, + 193, 0, 229, 122, 1, 2, 221, 69, 229, 122, 1, 2, 193, 86, 229, 122, 1, 2, + 193, 125, 229, 122, 1, 2, 193, 48, 72, 1, 2, 221, 69, 72, 1, 2, 193, 86, + 72, 1, 2, 193, 125, 72, 1, 2, 193, 48, 72, 1, 2, 215, 63, 46, 245, 26, + 46, 245, 25, 46, 245, 24, 46, 245, 23, 46, 245, 22, 46, 245, 21, 46, 245, + 20, 46, 245, 19, 46, 245, 18, 46, 245, 17, 46, 245, 16, 46, 245, 15, 46, + 245, 14, 46, 245, 13, 46, 245, 12, 46, 245, 11, 46, 245, 10, 46, 245, 9, + 46, 245, 8, 46, 245, 7, 46, 245, 6, 46, 245, 5, 46, 245, 4, 46, 245, 3, + 46, 245, 2, 46, 245, 1, 46, 245, 0, 46, 244, 255, 46, 244, 254, 46, 244, + 253, 46, 244, 252, 46, 244, 251, 46, 244, 250, 46, 244, 249, 46, 244, + 248, 46, 244, 247, 46, 244, 246, 46, 244, 245, 46, 244, 244, 46, 244, + 243, 46, 244, 242, 46, 244, 241, 46, 244, 240, 46, 244, 239, 46, 244, + 238, 46, 244, 237, 46, 244, 236, 46, 244, 235, 46, 244, 234, 46, 244, + 233, 46, 244, 232, 46, 244, 231, 46, 244, 230, 46, 244, 229, 46, 244, + 228, 46, 244, 227, 46, 244, 226, 46, 244, 225, 46, 244, 224, 46, 244, + 223, 46, 244, 222, 46, 244, 221, 46, 244, 220, 46, 244, 219, 46, 244, + 218, 46, 244, 217, 46, 244, 216, 46, 244, 215, 46, 244, 214, 46, 244, + 213, 46, 244, 212, 46, 244, 211, 46, 244, 210, 46, 244, 209, 46, 244, + 208, 46, 244, 207, 46, 244, 206, 46, 244, 205, 46, 244, 204, 46, 244, + 203, 46, 244, 202, 46, 244, 201, 46, 244, 200, 46, 244, 199, 46, 244, + 198, 46, 244, 197, 46, 244, 196, 46, 244, 195, 46, 244, 194, 46, 244, + 193, 46, 244, 192, 46, 244, 191, 46, 244, 190, 46, 244, 189, 46, 244, + 188, 46, 244, 187, 46, 244, 186, 46, 244, 185, 46, 244, 184, 46, 244, + 183, 46, 244, 182, 46, 244, 181, 46, 244, 180, 46, 244, 179, 46, 244, + 178, 46, 244, 177, 46, 244, 176, 46, 244, 175, 46, 244, 174, 46, 244, + 173, 46, 244, 172, 46, 244, 171, 46, 244, 170, 46, 244, 169, 46, 244, + 168, 46, 244, 167, 46, 244, 166, 46, 244, 165, 46, 244, 164, 46, 244, + 163, 46, 244, 162, 46, 244, 161, 46, 244, 160, 46, 244, 159, 46, 244, + 158, 46, 244, 157, 46, 244, 156, 46, 244, 155, 46, 244, 154, 46, 244, + 153, 46, 244, 152, 46, 244, 151, 46, 244, 150, 46, 244, 149, 46, 244, + 148, 46, 244, 147, 46, 244, 146, 46, 244, 145, 46, 244, 144, 46, 244, + 143, 46, 244, 142, 46, 244, 141, 46, 244, 140, 46, 244, 139, 46, 244, + 138, 46, 244, 137, 46, 244, 136, 46, 244, 135, 46, 244, 134, 46, 244, + 133, 46, 244, 132, 46, 244, 131, 46, 244, 130, 46, 244, 129, 46, 244, + 128, 46, 244, 127, 46, 244, 126, 46, 244, 125, 46, 244, 124, 46, 244, + 123, 46, 244, 122, 46, 244, 121, 46, 244, 120, 46, 244, 119, 46, 244, + 118, 46, 244, 117, 46, 244, 116, 46, 244, 115, 46, 244, 114, 46, 244, + 113, 46, 244, 112, 46, 244, 111, 46, 244, 110, 46, 244, 109, 46, 244, + 108, 46, 244, 107, 46, 244, 106, 46, 244, 105, 46, 244, 104, 46, 244, + 103, 46, 244, 102, 46, 244, 101, 46, 244, 100, 46, 244, 99, 46, 244, 98, + 46, 244, 97, 46, 244, 96, 46, 244, 95, 46, 244, 94, 46, 244, 93, 46, 244, + 92, 46, 244, 91, 46, 244, 90, 46, 244, 89, 46, 244, 88, 46, 244, 87, 46, + 244, 86, 46, 244, 85, 46, 244, 84, 46, 244, 83, 46, 244, 82, 46, 244, 81, + 46, 244, 80, 46, 244, 79, 46, 244, 78, 46, 244, 77, 46, 244, 76, 46, 244, + 75, 46, 244, 74, 46, 244, 73, 46, 244, 72, 46, 244, 71, 46, 244, 70, 46, + 244, 69, 46, 244, 68, 46, 244, 67, 46, 244, 66, 46, 244, 65, 46, 244, 64, + 46, 244, 63, 46, 244, 62, 46, 244, 61, 46, 244, 60, 46, 244, 59, 46, 244, + 58, 46, 244, 57, 46, 244, 56, 46, 244, 55, 46, 244, 54, 46, 244, 53, 46, + 244, 52, 46, 244, 51, 46, 244, 50, 46, 244, 49, 46, 244, 48, 46, 244, 47, + 46, 244, 46, 46, 244, 45, 46, 244, 44, 46, 244, 43, 46, 244, 42, 46, 244, + 41, 46, 244, 40, 46, 244, 39, 46, 244, 38, 46, 244, 37, 46, 244, 36, 46, + 244, 35, 46, 244, 34, 46, 244, 33, 46, 244, 32, 46, 244, 31, 46, 244, 30, + 46, 244, 29, 46, 244, 28, 46, 244, 27, 46, 244, 26, 46, 244, 25, 46, 244, + 24, 46, 244, 23, 46, 244, 22, 46, 244, 21, 46, 244, 20, 46, 244, 19, 46, + 244, 18, 46, 244, 17, 46, 244, 16, 46, 244, 15, 46, 244, 14, 46, 244, 13, + 46, 244, 12, 46, 244, 11, 46, 244, 10, 46, 244, 9, 46, 244, 8, 46, 244, + 7, 46, 244, 6, 46, 244, 5, 46, 244, 4, 46, 244, 3, 46, 244, 2, 46, 244, + 1, 46, 244, 0, 46, 243, 255, 46, 243, 254, 46, 243, 253, 46, 243, 252, + 46, 243, 251, 46, 243, 250, 46, 243, 249, 46, 243, 248, 46, 243, 247, 46, + 243, 246, 46, 243, 245, 46, 243, 244, 46, 243, 243, 46, 243, 242, 46, + 243, 241, 46, 243, 240, 46, 243, 239, 46, 243, 238, 46, 243, 237, 46, + 243, 236, 46, 243, 235, 46, 243, 234, 46, 243, 233, 46, 243, 232, 46, + 243, 231, 46, 243, 230, 46, 243, 229, 46, 243, 228, 46, 243, 227, 46, + 243, 226, 46, 243, 225, 46, 243, 224, 46, 243, 223, 46, 243, 222, 46, + 243, 221, 46, 243, 220, 46, 243, 219, 46, 243, 218, 46, 243, 217, 46, + 243, 216, 46, 243, 215, 46, 243, 214, 46, 243, 213, 46, 243, 212, 46, + 243, 211, 46, 243, 210, 46, 243, 209, 46, 243, 208, 46, 243, 207, 46, + 243, 206, 46, 243, 205, 46, 243, 204, 46, 243, 203, 46, 243, 202, 46, + 243, 201, 46, 243, 200, 46, 243, 199, 46, 243, 198, 46, 243, 197, 46, + 243, 196, 46, 243, 195, 46, 243, 194, 46, 243, 193, 46, 243, 192, 46, + 243, 191, 46, 243, 190, 46, 243, 189, 46, 243, 188, 46, 243, 187, 46, + 243, 186, 46, 243, 185, 46, 243, 184, 46, 243, 183, 46, 243, 182, 46, + 243, 181, 46, 243, 180, 46, 243, 179, 46, 243, 178, 46, 243, 177, 46, + 243, 176, 46, 243, 175, 46, 243, 174, 46, 243, 173, 46, 243, 172, 46, + 243, 171, 46, 243, 170, 46, 243, 169, 46, 243, 168, 46, 243, 167, 46, + 243, 166, 46, 243, 165, 46, 243, 164, 46, 243, 163, 46, 243, 162, 46, + 243, 161, 46, 243, 160, 46, 243, 159, 46, 243, 158, 46, 243, 157, 46, + 243, 156, 46, 243, 155, 46, 243, 154, 46, 243, 153, 46, 243, 152, 46, + 243, 151, 46, 243, 150, 46, 243, 149, 46, 243, 148, 46, 243, 147, 46, + 243, 146, 46, 243, 145, 46, 243, 144, 46, 243, 143, 124, 1, 230, 118, + 124, 1, 192, 235, 124, 1, 210, 238, 124, 1, 200, 43, 124, 1, 233, 177, + 124, 1, 222, 154, 124, 1, 172, 124, 1, 250, 122, 124, 1, 238, 129, 124, + 1, 196, 12, 124, 1, 232, 53, 124, 1, 146, 124, 1, 210, 239, 215, 63, 124, + 1, 238, 130, 206, 9, 124, 1, 233, 178, 215, 63, 124, 1, 222, 155, 218, + 170, 124, 1, 207, 224, 206, 9, 124, 1, 199, 51, 124, 1, 202, 83, 237, 71, + 124, 1, 237, 71, 124, 1, 221, 104, 124, 1, 202, 83, 223, 37, 124, 1, 229, + 114, 124, 1, 219, 162, 124, 1, 207, 8, 124, 1, 218, 170, 124, 1, 215, 63, + 124, 1, 223, 37, 124, 1, 206, 9, 124, 1, 218, 171, 215, 63, 124, 1, 215, + 64, 218, 170, 124, 1, 223, 38, 218, 170, 124, 1, 206, 10, 223, 37, 124, + 1, 218, 171, 4, 236, 142, 124, 1, 215, 64, 4, 236, 142, 124, 1, 223, 38, + 4, 236, 142, 124, 1, 223, 38, 4, 185, 223, 120, 23, 58, 124, 1, 206, 10, + 4, 236, 142, 124, 1, 206, 10, 4, 75, 60, 124, 1, 218, 171, 206, 9, 124, + 1, 215, 64, 206, 9, 124, 1, 223, 38, 206, 9, 124, 1, 206, 10, 206, 9, + 124, 1, 218, 171, 215, 64, 206, 9, 124, 1, 215, 64, 218, 171, 206, 9, + 124, 1, 223, 38, 218, 171, 206, 9, 124, 1, 206, 10, 223, 38, 206, 9, 124, + 1, 223, 38, 206, 10, 4, 236, 142, 124, 1, 223, 38, 215, 63, 124, 1, 223, + 38, 215, 64, 206, 9, 124, 1, 206, 10, 200, 43, 124, 1, 206, 10, 200, 44, + 146, 124, 1, 206, 10, 210, 238, 124, 1, 206, 10, 210, 239, 146, 124, 1, + 200, 44, 206, 9, 124, 1, 200, 44, 207, 224, 206, 9, 124, 1, 193, 224, + 124, 1, 193, 97, 124, 1, 193, 225, 146, 124, 1, 206, 10, 215, 63, 124, 1, + 206, 10, 218, 170, 124, 1, 222, 155, 207, 224, 206, 9, 124, 1, 232, 54, + 207, 224, 206, 9, 124, 1, 206, 10, 222, 154, 124, 1, 206, 10, 222, 155, + 146, 124, 1, 65, 124, 1, 202, 83, 210, 252, 124, 1, 211, 184, 124, 1, 74, + 124, 1, 251, 68, 124, 1, 68, 124, 1, 71, 124, 1, 223, 228, 124, 1, 203, + 41, 68, 124, 1, 196, 139, 124, 1, 234, 190, 124, 1, 202, 83, 234, 175, + 124, 1, 206, 136, 68, 124, 1, 202, 83, 234, 190, 124, 1, 180, 68, 124, 1, + 192, 80, 124, 1, 66, 124, 1, 233, 244, 124, 1, 192, 182, 124, 1, 126, + 215, 63, 124, 1, 180, 66, 124, 1, 206, 136, 66, 124, 1, 196, 141, 124, 1, + 202, 83, 66, 124, 1, 211, 86, 124, 1, 210, 252, 124, 1, 211, 21, 124, 1, + 193, 190, 124, 1, 193, 48, 124, 1, 193, 86, 124, 1, 193, 112, 124, 1, + 193, 14, 124, 1, 214, 216, 66, 124, 1, 214, 216, 74, 124, 1, 214, 216, + 68, 124, 1, 214, 216, 65, 124, 1, 210, 2, 251, 134, 124, 1, 210, 2, 251, + 151, 124, 1, 202, 83, 234, 105, 124, 1, 202, 83, 251, 134, 124, 1, 202, + 83, 211, 106, 124, 1, 117, 218, 170, 124, 252, 6, 45, 228, 243, 205, 59, + 124, 252, 6, 216, 89, 228, 243, 205, 59, 124, 252, 6, 50, 228, 243, 205, + 59, 124, 252, 6, 130, 81, 205, 59, 124, 252, 6, 216, 89, 81, 205, 59, + 124, 252, 6, 137, 81, 205, 59, 124, 252, 6, 250, 172, 205, 59, 124, 252, + 6, 250, 172, 219, 217, 205, 59, 124, 252, 6, 250, 172, 199, 188, 124, + 252, 6, 250, 172, 199, 215, 124, 252, 6, 250, 172, 235, 17, 102, 124, + 252, 6, 250, 172, 228, 76, 102, 124, 252, 6, 250, 172, 199, 189, 102, + 124, 252, 6, 137, 252, 48, 124, 252, 6, 137, 198, 172, 252, 48, 124, 252, + 6, 137, 230, 212, 124, 252, 6, 137, 180, 230, 212, 124, 252, 6, 137, 236, + 142, 124, 252, 6, 137, 243, 12, 124, 252, 6, 137, 219, 114, 124, 252, 6, + 137, 193, 138, 124, 252, 6, 137, 195, 135, 124, 252, 6, 130, 252, 48, + 124, 252, 6, 130, 198, 172, 252, 48, 124, 252, 6, 130, 230, 212, 124, + 252, 6, 130, 180, 230, 212, 124, 252, 6, 130, 236, 142, 124, 252, 6, 130, + 243, 12, 124, 252, 6, 130, 219, 114, 124, 252, 6, 130, 193, 138, 124, + 252, 6, 130, 195, 135, 124, 252, 6, 130, 57, 124, 3, 187, 4, 238, 219, + 124, 199, 9, 1, 205, 35, 124, 55, 77, 124, 208, 154, 243, 80, 232, 82, + 201, 64, 203, 28, 232, 147, 1, 211, 4, 203, 28, 232, 147, 239, 30, 211, + 4, 203, 28, 232, 147, 144, 201, 79, 203, 28, 232, 147, 133, 201, 79, 97, + 33, 87, 230, 242, 213, 161, 206, 10, 220, 253, 211, 107, 219, 226, 97, + 33, 87, 213, 161, 206, 10, 220, 253, 211, 107, 219, 226, 97, 33, 87, 197, + 162, 211, 107, 219, 226, 97, 33, 87, 230, 242, 213, 161, 211, 107, 219, + 226, 97, 33, 87, 213, 161, 211, 107, 219, 226, 97, 33, 87, 201, 180, 211, + 107, 219, 226, 97, 33, 87, 217, 96, 209, 5, 211, 107, 219, 226, 97, 33, + 87, 209, 5, 211, 107, 219, 226, 97, 33, 87, 193, 231, 211, 107, 219, 226, + 97, 33, 87, 217, 96, 209, 5, 206, 10, 221, 183, 211, 107, 219, 226, 97, + 33, 87, 209, 5, 206, 10, 221, 183, 211, 107, 219, 226, 97, 33, 87, 193, + 231, 206, 10, 221, 183, 211, 107, 219, 226, 97, 33, 87, 230, 242, 213, + 161, 206, 10, 220, 253, 211, 107, 179, 97, 33, 87, 213, 161, 206, 10, + 220, 253, 211, 107, 179, 97, 33, 87, 197, 162, 211, 107, 179, 97, 33, 87, + 230, 242, 213, 161, 211, 107, 179, 97, 33, 87, 213, 161, 211, 107, 179, + 97, 33, 87, 201, 180, 211, 107, 179, 97, 33, 87, 217, 96, 209, 5, 211, + 107, 179, 97, 33, 87, 209, 5, 211, 107, 179, 97, 33, 87, 193, 231, 211, + 107, 179, 97, 33, 87, 217, 96, 209, 5, 206, 10, 221, 183, 211, 107, 179, + 97, 33, 87, 209, 5, 206, 10, 221, 183, 211, 107, 179, 97, 33, 87, 193, + 231, 206, 10, 221, 183, 211, 107, 179, 97, 33, 87, 197, 162, 206, 10, + 220, 252, 97, 33, 87, 217, 96, 209, 5, 206, 10, 220, 252, 97, 33, 87, + 201, 50, 217, 96, 209, 4, 97, 33, 87, 209, 5, 206, 10, 220, 252, 97, 33, + 87, 209, 5, 201, 49, 97, 33, 87, 193, 231, 206, 10, 220, 252, 97, 33, 87, + 217, 96, 209, 5, 201, 49, 97, 33, 87, 230, 242, 193, 230, 97, 33, 87, + 191, 83, 97, 33, 87, 211, 106, 97, 33, 87, 207, 126, 97, 33, 87, 198, + 157, 97, 33, 87, 248, 85, 97, 33, 87, 196, 156, 97, 33, 87, 209, 67, 97, + 33, 87, 219, 23, 97, 33, 87, 220, 202, 97, 33, 87, 222, 117, 97, 33, 87, + 191, 74, 97, 33, 87, 202, 106, 97, 33, 87, 207, 119, 97, 33, 87, 220, + 255, 211, 107, 219, 226, 97, 33, 198, 80, 207, 139, 87, 215, 164, 97, 33, + 198, 80, 207, 139, 87, 200, 153, 97, 33, 198, 80, 207, 139, 87, 197, 246, + 97, 33, 87, 191, 120, 97, 33, 87, 237, 107, 191, 120, 97, 33, 87, 211, + 27, 97, 33, 87, 209, 69, 97, 33, 87, 209, 70, 4, 81, 106, 97, 33, 87, + 243, 136, 97, 33, 87, 243, 137, 209, 47, 97, 33, 87, 211, 176, 97, 33, + 87, 202, 11, 212, 251, 97, 33, 87, 198, 89, 97, 33, 87, 235, 50, 97, 33, + 250, 171, 81, 211, 111, 97, 33, 87, 238, 165, 211, 111, 97, 33, 87, 220, + 254, 97, 33, 110, 198, 80, 207, 139, 223, 146, 97, 208, 205, 52, 219, + 169, 97, 208, 205, 52, 219, 168, 97, 208, 205, 52, 236, 235, 232, 197, + 97, 208, 205, 52, 220, 254, 97, 208, 205, 52, 206, 145, 97, 161, 221, 2, + 97, 161, 221, 3, 198, 156, 97, 161, 210, 124, 97, 161, 235, 58, 196, 13, + 243, 115, 97, 161, 221, 92, 97, 161, 191, 105, 97, 161, 201, 62, 97, 161, + 201, 63, 206, 10, 211, 165, 97, 161, 210, 12, 97, 161, 210, 13, 214, 98, + 97, 161, 201, 63, 4, 202, 11, 212, 251, 97, 161, 243, 114, 97, 161, 210, + 188, 97, 161, 191, 103, 97, 161, 230, 250, 248, 84, 97, 161, 230, 250, + 198, 156, 97, 161, 230, 250, 215, 162, 97, 161, 230, 250, 200, 152, 97, + 161, 230, 250, 197, 245, 97, 161, 194, 253, 208, 185, 97, 161, 194, 253, + 215, 165, 97, 161, 194, 253, 200, 154, 97, 161, 194, 253, 197, 247, 97, + 161, 194, 253, 221, 87, 208, 185, 97, 161, 194, 253, 221, 87, 215, 165, + 97, 161, 194, 253, 221, 87, 200, 154, 97, 161, 194, 253, 221, 87, 197, + 247, 97, 161, 55, 191, 103, 97, 161, 207, 19, 243, 114, 97, 161, 237, 93, + 97, 161, 221, 209, 97, 161, 243, 136, 97, 161, 209, 69, 97, 161, 202, + 114, 215, 165, 97, 161, 202, 114, 200, 154, 97, 161, 202, 114, 197, 247, + 97, 161, 202, 114, 198, 157, 97, 161, 237, 107, 221, 92, 97, 161, 202, + 114, 221, 87, 200, 154, 97, 161, 202, 114, 221, 91, 97, 161, 202, 114, + 221, 87, 198, 157, 97, 161, 202, 114, 235, 55, 208, 185, 97, 161, 202, + 114, 235, 55, 200, 154, 97, 161, 202, 114, 235, 55, 214, 98, 97, 161, + 202, 114, 235, 55, 221, 86, 97, 161, 202, 73, 97, 161, 202, 74, 206, 10, + 191, 101, 97, 161, 202, 74, 191, 110, 97, 161, 202, 74, 206, 10, 220, + 252, 97, 161, 220, 254, 97, 161, 206, 145, 97, 161, 232, 230, 97, 161, + 221, 61, 97, 161, 191, 8, 97, 161, 201, 91, 97, 161, 201, 92, 206, 10, + 191, 101, 97, 161, 201, 92, 206, 10, 220, 252, 97, 161, 201, 92, 206, 10, + 191, 102, 228, 76, 220, 252, 97, 161, 201, 92, 206, 10, 220, 253, 228, + 76, 191, 101, 97, 161, 201, 92, 191, 111, 97, 161, 201, 92, 191, 112, + 206, 10, 191, 101, 97, 161, 201, 92, 206, 10, 206, 144, 97, 161, 201, 92, + 206, 10, 235, 49, 191, 100, 97, 161, 201, 92, 206, 10, 191, 102, 228, 76, + 209, 68, 97, 161, 209, 49, 97, 161, 201, 92, 214, 98, 97, 161, 201, 41, + 208, 185, 97, 161, 201, 41, 215, 163, 97, 161, 201, 41, 220, 251, 97, + 161, 201, 41, 209, 45, 97, 161, 201, 41, 209, 7, 97, 161, 201, 41, 214, + 98, 97, 161, 201, 41, 221, 89, 97, 161, 201, 41, 221, 91, 97, 161, 201, + 41, 198, 158, 208, 132, 97, 161, 201, 41, 235, 54, 97, 161, 201, 41, 235, + 53, 97, 161, 201, 41, 235, 51, 97, 161, 201, 41, 235, 55, 221, 86, 97, + 161, 201, 41, 235, 52, 221, 86, 97, 161, 201, 41, 230, 197, 4, 202, 171, + 191, 103, 97, 161, 201, 41, 230, 193, 4, 202, 171, 191, 103, 97, 161, + 201, 41, 230, 196, 97, 161, 201, 41, 230, 192, 97, 161, 201, 41, 230, + 193, 4, 55, 191, 103, 97, 161, 201, 41, 230, 194, 97, 161, 201, 41, 230, + 195, 209, 7, 97, 161, 216, 223, 97, 161, 216, 224, 209, 6, 97, 161, 216, + 224, 221, 85, 97, 161, 216, 224, 221, 88, 97, 161, 216, 224, 221, 90, 97, + 161, 201, 41, 197, 174, 97, 161, 201, 41, 197, 173, 97, 161, 201, 41, + 197, 172, 97, 161, 211, 33, 97, 161, 211, 34, 200, 154, 97, 161, 211, 34, + 197, 247, 97, 161, 211, 34, 221, 1, 200, 154, 97, 161, 211, 34, 221, 87, + 200, 154, 97, 161, 211, 34, 221, 87, 214, 98, 97, 161, 201, 41, 221, 0, + 97, 161, 201, 41, 221, 1, 209, 7, 97, 161, 201, 41, 221, 1, 230, 197, 4, + 202, 171, 191, 103, 97, 161, 201, 41, 221, 1, 230, 193, 4, 202, 171, 191, + 103, 97, 161, 201, 41, 221, 1, 230, 196, 97, 161, 201, 41, 221, 1, 230, + 192, 97, 161, 201, 41, 221, 1, 230, 193, 4, 55, 191, 103, 97, 161, 201, + 41, 221, 1, 230, 194, 97, 161, 201, 41, 221, 1, 230, 195, 209, 7, 97, + 161, 201, 41, 221, 1, 197, 175, 97, 161, 220, 216, 97, 161, 211, 175, 97, + 161, 235, 86, 97, 161, 214, 105, 97, 161, 210, 81, 73, 37, 16, 208, 171, + 73, 37, 16, 237, 219, 73, 37, 16, 210, 6, 73, 37, 16, 210, 248, 234, 146, + 73, 37, 16, 210, 248, 236, 240, 73, 37, 16, 195, 172, 234, 146, 73, 37, + 16, 195, 172, 236, 240, 73, 37, 16, 222, 46, 73, 37, 16, 200, 60, 73, 37, + 16, 210, 122, 73, 37, 16, 191, 231, 73, 37, 16, 191, 232, 236, 240, 73, + 37, 16, 221, 5, 73, 37, 16, 251, 63, 234, 146, 73, 37, 16, 233, 212, 234, + 146, 73, 37, 16, 199, 108, 73, 37, 16, 221, 249, 73, 37, 16, 251, 52, 73, + 37, 16, 251, 53, 236, 240, 73, 37, 16, 200, 67, 73, 37, 16, 198, 244, 73, + 37, 16, 211, 118, 251, 14, 73, 37, 16, 230, 240, 251, 14, 73, 37, 16, + 208, 170, 73, 37, 16, 246, 250, 73, 37, 16, 195, 161, 73, 37, 16, 223, + 60, 251, 14, 73, 37, 16, 221, 251, 251, 14, 73, 37, 16, 221, 250, 251, + 14, 73, 37, 16, 205, 106, 73, 37, 16, 210, 112, 73, 37, 16, 201, 89, 251, + 56, 73, 37, 16, 210, 247, 251, 14, 73, 37, 16, 195, 171, 251, 14, 73, 37, + 16, 251, 57, 251, 14, 73, 37, 16, 251, 50, 73, 37, 16, 221, 94, 73, 37, + 16, 207, 15, 73, 37, 16, 209, 185, 251, 14, 73, 37, 16, 198, 142, 73, 37, + 16, 251, 130, 73, 37, 16, 205, 38, 73, 37, 16, 200, 71, 251, 14, 73, 37, + 16, 200, 71, 216, 168, 201, 87, 73, 37, 16, 210, 242, 251, 14, 73, 37, + 16, 199, 27, 73, 37, 16, 219, 204, 73, 37, 16, 235, 40, 73, 37, 16, 197, + 243, 73, 37, 16, 199, 76, 73, 37, 16, 221, 8, 73, 37, 16, 251, 63, 233, + 212, 214, 100, 73, 37, 16, 232, 90, 251, 14, 73, 37, 16, 223, 177, 73, + 37, 16, 197, 210, 251, 14, 73, 37, 16, 222, 49, 197, 209, 73, 37, 16, + 210, 38, 73, 37, 16, 208, 175, 73, 37, 16, 221, 44, 73, 37, 16, 243, 62, + 251, 14, 73, 37, 16, 207, 137, 73, 37, 16, 210, 126, 251, 14, 73, 37, 16, + 210, 123, 251, 14, 73, 37, 16, 228, 26, 73, 37, 16, 214, 227, 73, 37, 16, + 209, 240, 73, 37, 16, 221, 45, 251, 169, 73, 37, 16, 197, 210, 251, 169, + 73, 37, 16, 201, 56, 73, 37, 16, 230, 191, 73, 37, 16, 223, 60, 214, 100, + 73, 37, 16, 211, 118, 214, 100, 73, 37, 16, 210, 248, 214, 100, 73, 37, + 16, 209, 239, 73, 37, 16, 221, 28, 73, 37, 16, 209, 238, 73, 37, 16, 221, + 7, 73, 37, 16, 210, 39, 214, 100, 73, 37, 16, 221, 250, 214, 101, 251, + 95, 73, 37, 16, 221, 251, 214, 101, 251, 95, 73, 37, 16, 191, 229, 73, + 37, 16, 251, 53, 214, 100, 73, 37, 16, 251, 54, 200, 68, 214, 100, 73, + 37, 16, 191, 230, 73, 37, 16, 221, 6, 73, 37, 16, 234, 141, 73, 37, 16, + 246, 251, 73, 37, 16, 216, 59, 223, 59, 73, 37, 16, 195, 172, 214, 100, + 73, 37, 16, 209, 185, 214, 100, 73, 37, 16, 208, 176, 214, 100, 73, 37, + 16, 211, 114, 73, 37, 16, 251, 82, 73, 37, 16, 218, 181, 73, 37, 16, 210, + 123, 214, 100, 73, 37, 16, 210, 126, 214, 100, 73, 37, 16, 233, 251, 210, + 125, 73, 37, 16, 220, 149, 73, 37, 16, 251, 83, 73, 37, 16, 197, 210, + 214, 100, 73, 37, 16, 234, 144, 73, 37, 16, 200, 71, 214, 100, 73, 37, + 16, 200, 61, 73, 37, 16, 243, 62, 214, 100, 73, 37, 16, 234, 55, 73, 37, + 16, 205, 39, 214, 100, 73, 37, 16, 192, 199, 221, 94, 73, 37, 16, 197, + 207, 73, 37, 16, 208, 177, 73, 37, 16, 197, 211, 73, 37, 16, 197, 208, + 73, 37, 16, 208, 174, 73, 37, 16, 197, 206, 73, 37, 16, 208, 173, 73, 37, + 16, 230, 239, 73, 37, 16, 251, 6, 73, 37, 16, 233, 251, 251, 6, 73, 37, + 16, 210, 242, 214, 100, 73, 37, 16, 199, 26, 234, 8, 73, 37, 16, 199, 26, + 233, 211, 73, 37, 16, 199, 28, 251, 58, 73, 37, 16, 199, 20, 222, 105, + 251, 49, 73, 37, 16, 222, 48, 73, 37, 16, 234, 92, 73, 37, 16, 192, 38, + 222, 45, 73, 37, 16, 192, 38, 251, 95, 73, 37, 16, 201, 88, 73, 37, 16, + 221, 95, 251, 95, 73, 37, 16, 236, 241, 251, 14, 73, 37, 16, 221, 9, 251, + 14, 73, 37, 16, 221, 9, 251, 169, 73, 37, 16, 221, 9, 214, 100, 73, 37, + 16, 251, 57, 214, 100, 73, 37, 16, 251, 59, 73, 37, 16, 236, 240, 73, 37, + 16, 197, 223, 73, 37, 16, 199, 66, 73, 37, 16, 221, 32, 73, 37, 16, 219, + 209, 234, 85, 243, 52, 73, 37, 16, 219, 209, 235, 41, 243, 53, 73, 37, + 16, 219, 209, 197, 226, 243, 53, 73, 37, 16, 219, 209, 199, 78, 243, 53, + 73, 37, 16, 219, 209, 223, 172, 243, 52, 73, 37, 16, 230, 240, 214, 101, + 251, 95, 73, 37, 16, 230, 240, 210, 113, 251, 2, 73, 37, 16, 230, 240, + 210, 113, 237, 75, 73, 37, 16, 237, 9, 73, 37, 16, 237, 10, 210, 113, + 251, 3, 222, 45, 73, 37, 16, 237, 10, 210, 113, 251, 3, 251, 95, 73, 37, + 16, 237, 10, 210, 113, 237, 75, 73, 37, 16, 197, 232, 73, 37, 16, 251, 7, + 73, 37, 16, 223, 179, 73, 37, 16, 237, 32, 73, 37, 16, 251, 249, 209, 53, + 251, 8, 73, 37, 16, 251, 249, 251, 5, 73, 37, 16, 251, 249, 251, 8, 73, + 37, 16, 251, 249, 216, 162, 73, 37, 16, 251, 249, 216, 173, 73, 37, 16, + 251, 249, 230, 241, 73, 37, 16, 251, 249, 230, 238, 73, 37, 16, 251, 249, + 209, 53, 230, 241, 73, 37, 16, 217, 47, 208, 183, 228, 24, 73, 37, 16, + 217, 47, 251, 171, 208, 183, 228, 24, 73, 37, 16, 217, 47, 237, 74, 228, + 24, 73, 37, 16, 217, 47, 251, 171, 237, 74, 228, 24, 73, 37, 16, 217, 47, + 197, 218, 228, 24, 73, 37, 16, 217, 47, 197, 233, 73, 37, 16, 217, 47, + 199, 71, 228, 24, 73, 37, 16, 217, 47, 199, 71, 219, 213, 228, 24, 73, + 37, 16, 217, 47, 219, 213, 228, 24, 73, 37, 16, 217, 47, 209, 107, 228, + 24, 73, 37, 16, 223, 68, 199, 101, 228, 25, 73, 37, 16, 251, 54, 199, + 101, 228, 25, 73, 37, 16, 233, 81, 199, 68, 73, 37, 16, 233, 81, 215, + 224, 73, 37, 16, 233, 81, 237, 15, 73, 37, 16, 217, 47, 195, 165, 228, + 24, 73, 37, 16, 217, 47, 208, 182, 228, 24, 73, 37, 16, 217, 47, 209, + 107, 199, 71, 228, 24, 73, 37, 16, 230, 235, 215, 64, 251, 58, 73, 37, + 16, 230, 235, 215, 64, 236, 239, 73, 37, 16, 234, 103, 222, 105, 232, 90, + 195, 3, 73, 37, 16, 223, 178, 73, 37, 16, 223, 176, 73, 37, 16, 232, 90, + 251, 15, 237, 73, 228, 23, 73, 37, 16, 232, 90, 237, 30, 168, 73, 37, 16, + 232, 90, 237, 30, 214, 227, 73, 37, 16, 232, 90, 214, 221, 228, 24, 73, + 37, 16, 232, 90, 237, 30, 237, 46, 73, 37, 16, 232, 90, 202, 107, 237, + 29, 237, 46, 73, 37, 16, 232, 90, 237, 30, 222, 24, 73, 37, 16, 232, 90, + 237, 30, 191, 7, 73, 37, 16, 232, 90, 237, 30, 213, 222, 222, 45, 73, 37, + 16, 232, 90, 237, 30, 213, 222, 251, 95, 73, 37, 16, 232, 90, 217, 100, + 243, 54, 237, 15, 73, 37, 16, 232, 90, 217, 100, 243, 54, 215, 224, 73, + 37, 16, 233, 26, 202, 107, 243, 54, 195, 164, 73, 37, 16, 232, 90, 202, + 107, 243, 54, 200, 72, 73, 37, 16, 232, 90, 214, 103, 73, 37, 16, 243, + 55, 190, 230, 73, 37, 16, 243, 55, 221, 93, 73, 37, 16, 243, 55, 201, + 239, 73, 37, 16, 232, 90, 228, 76, 192, 37, 199, 72, 73, 37, 16, 232, 90, + 234, 104, 251, 84, 73, 37, 16, 192, 37, 197, 219, 73, 37, 16, 237, 23, + 197, 219, 73, 37, 16, 237, 23, 199, 72, 73, 37, 16, 237, 23, 251, 60, + 235, 41, 236, 168, 73, 37, 16, 237, 23, 215, 222, 199, 77, 236, 168, 73, + 37, 16, 237, 23, 237, 6, 233, 224, 236, 168, 73, 37, 16, 237, 23, 197, + 230, 211, 124, 236, 168, 73, 37, 16, 192, 37, 251, 60, 235, 41, 236, 168, + 73, 37, 16, 192, 37, 215, 222, 199, 77, 236, 168, 73, 37, 16, 192, 37, + 237, 6, 233, 224, 236, 168, 73, 37, 16, 192, 37, 197, 230, 211, 124, 236, + 168, 73, 37, 16, 231, 149, 237, 22, 73, 37, 16, 231, 149, 192, 36, 73, + 37, 16, 237, 31, 251, 60, 216, 60, 73, 37, 16, 237, 31, 251, 60, 216, + 204, 73, 37, 16, 237, 31, 236, 240, 73, 37, 16, 237, 31, 199, 18, 73, 37, + 16, 202, 182, 199, 18, 73, 37, 16, 202, 182, 199, 19, 236, 223, 73, 37, + 16, 202, 182, 199, 19, 197, 220, 73, 37, 16, 202, 182, 199, 19, 199, 64, + 73, 37, 16, 202, 182, 250, 230, 73, 37, 16, 202, 182, 250, 231, 236, 223, + 73, 37, 16, 202, 182, 250, 231, 197, 220, 73, 37, 16, 202, 182, 250, 231, + 199, 64, 73, 37, 16, 237, 7, 231, 130, 73, 37, 16, 237, 14, 211, 21, 73, + 37, 16, 201, 74, 73, 37, 16, 250, 255, 168, 73, 37, 16, 250, 255, 195, 3, + 73, 37, 16, 250, 255, 231, 242, 73, 37, 16, 250, 255, 237, 46, 73, 37, + 16, 250, 255, 222, 24, 73, 37, 16, 250, 255, 191, 7, 73, 37, 16, 250, + 255, 213, 221, 73, 37, 16, 221, 250, 214, 101, 216, 172, 73, 37, 16, 221, + 251, 214, 101, 216, 172, 73, 37, 16, 221, 250, 214, 101, 222, 45, 73, 37, + 16, 221, 251, 214, 101, 222, 45, 73, 37, 16, 221, 95, 222, 45, 73, 37, + 16, 230, 240, 214, 101, 222, 45, 37, 16, 202, 171, 249, 85, 37, 16, 55, + 249, 85, 37, 16, 53, 249, 85, 37, 16, 207, 20, 53, 249, 85, 37, 16, 237, + 216, 249, 85, 37, 16, 203, 41, 249, 85, 37, 16, 45, 207, 50, 56, 37, 16, + 50, 207, 50, 56, 37, 16, 207, 50, 236, 140, 37, 16, 238, 6, 205, 42, 37, + 16, 238, 35, 247, 110, 37, 16, 205, 42, 37, 16, 242, 94, 37, 16, 207, 48, + 233, 13, 37, 16, 207, 48, 233, 12, 37, 16, 207, 48, 233, 11, 37, 16, 233, + 36, 37, 16, 233, 37, 60, 37, 16, 248, 41, 77, 37, 16, 247, 152, 37, 16, + 248, 57, 37, 16, 248, 55, 37, 16, 211, 101, 201, 112, 37, 16, 197, 12, + 201, 112, 37, 16, 198, 220, 201, 112, 37, 16, 232, 129, 201, 112, 37, 16, + 232, 226, 201, 112, 37, 16, 202, 136, 201, 112, 37, 16, 202, 134, 232, + 107, 37, 16, 232, 127, 232, 107, 37, 16, 232, 54, 242, 237, 37, 16, 232, + 54, 242, 238, 211, 25, 251, 160, 37, 16, 232, 54, 242, 238, 211, 25, 249, + 68, 37, 16, 247, 196, 242, 237, 37, 16, 233, 178, 242, 237, 37, 16, 233, + 178, 242, 238, 211, 25, 251, 160, 37, 16, 233, 178, 242, 238, 211, 25, + 249, 68, 37, 16, 235, 97, 242, 236, 37, 16, 235, 97, 242, 235, 37, 16, + 215, 131, 216, 230, 207, 31, 37, 16, 55, 203, 127, 37, 16, 55, 232, 208, + 37, 16, 232, 209, 196, 77, 37, 16, 232, 209, 235, 125, 37, 16, 214, 208, + 196, 77, 37, 16, 214, 208, 235, 125, 37, 16, 203, 128, 196, 77, 37, 16, + 203, 128, 235, 125, 37, 16, 208, 25, 163, 203, 127, 37, 16, 208, 25, 163, + 232, 208, 37, 16, 242, 73, 198, 146, 37, 16, 238, 157, 198, 146, 37, 16, + 211, 25, 251, 160, 37, 16, 211, 25, 249, 68, 37, 16, 208, 5, 251, 160, + 37, 16, 208, 5, 249, 68, 37, 16, 215, 134, 207, 31, 37, 16, 193, 87, 207, + 31, 37, 16, 132, 207, 31, 37, 16, 208, 25, 207, 31, 37, 16, 234, 162, + 207, 31, 37, 16, 202, 130, 207, 31, 37, 16, 198, 246, 207, 31, 37, 16, + 202, 120, 207, 31, 37, 16, 91, 228, 143, 197, 30, 207, 31, 37, 16, 192, + 236, 213, 4, 37, 16, 108, 213, 4, 37, 16, 243, 13, 192, 236, 213, 4, 37, + 16, 51, 213, 5, 193, 89, 37, 16, 51, 213, 5, 248, 141, 37, 16, 197, 242, + 213, 5, 133, 193, 89, 37, 16, 197, 242, 213, 5, 133, 248, 141, 37, 16, + 197, 242, 213, 5, 45, 193, 89, 37, 16, 197, 242, 213, 5, 45, 248, 141, + 37, 16, 197, 242, 213, 5, 50, 193, 89, 37, 16, 197, 242, 213, 5, 50, 248, + 141, 37, 16, 197, 242, 213, 5, 144, 193, 89, 37, 16, 197, 242, 213, 5, + 144, 248, 141, 37, 16, 197, 242, 213, 5, 133, 50, 193, 89, 37, 16, 197, + 242, 213, 5, 133, 50, 248, 141, 37, 16, 215, 208, 213, 5, 193, 89, 37, + 16, 215, 208, 213, 5, 248, 141, 37, 16, 197, 239, 213, 5, 144, 193, 89, + 37, 16, 197, 239, 213, 5, 144, 248, 141, 37, 16, 210, 116, 213, 4, 37, + 16, 195, 17, 213, 4, 37, 16, 213, 5, 248, 141, 37, 16, 212, 141, 213, 4, + 37, 16, 242, 205, 213, 5, 193, 89, 37, 16, 242, 205, 213, 5, 248, 141, + 37, 16, 248, 38, 37, 16, 193, 87, 213, 8, 37, 16, 132, 213, 8, 37, 16, + 208, 25, 213, 8, 37, 16, 234, 162, 213, 8, 37, 16, 202, 130, 213, 8, 37, + 16, 198, 246, 213, 8, 37, 16, 202, 120, 213, 8, 37, 16, 91, 228, 143, + 197, 30, 213, 8, 37, 16, 33, 201, 81, 37, 16, 33, 201, 198, 201, 81, 37, 16, 33, 197, 253, 37, 16, 33, 197, 252, 37, 16, 33, 197, 251, 37, 16, - 232, 250, 197, 253, 37, 16, 232, 250, 197, 252, 37, 16, 232, 250, 197, - 251, 37, 16, 33, 250, 160, 236, 140, 37, 16, 33, 232, 216, 37, 16, 33, - 232, 215, 37, 16, 33, 232, 214, 37, 16, 33, 232, 213, 37, 16, 33, 232, - 212, 37, 16, 248, 249, 249, 14, 37, 16, 234, 95, 249, 14, 37, 16, 248, - 249, 198, 178, 37, 16, 234, 95, 198, 178, 37, 16, 248, 249, 202, 71, 37, - 16, 234, 95, 202, 71, 37, 16, 248, 249, 209, 192, 37, 16, 234, 95, 209, - 192, 37, 16, 33, 252, 60, 37, 16, 33, 201, 115, 37, 16, 33, 199, 83, 37, - 16, 33, 201, 116, 37, 16, 33, 217, 60, 37, 16, 33, 217, 59, 37, 16, 33, - 252, 59, 37, 16, 33, 218, 243, 37, 16, 250, 241, 196, 77, 37, 16, 250, - 241, 235, 123, 37, 16, 33, 236, 158, 37, 16, 33, 206, 184, 37, 16, 33, - 232, 195, 37, 16, 33, 202, 67, 37, 16, 33, 248, 227, 37, 16, 33, 55, 198, - 61, 37, 16, 33, 197, 225, 198, 61, 37, 16, 206, 190, 37, 16, 200, 241, - 37, 16, 191, 166, 37, 16, 209, 184, 37, 16, 216, 151, 37, 16, 232, 140, - 37, 16, 238, 229, 37, 16, 237, 132, 37, 16, 230, 228, 213, 7, 202, 97, - 37, 16, 230, 228, 213, 7, 213, 44, 202, 97, 37, 16, 198, 27, 37, 16, 197, - 58, 37, 16, 223, 93, 197, 58, 37, 16, 197, 59, 202, 97, 37, 16, 197, 59, - 196, 77, 37, 16, 211, 43, 201, 27, 37, 16, 211, 43, 201, 24, 37, 16, 211, - 43, 201, 23, 37, 16, 211, 43, 201, 22, 37, 16, 211, 43, 201, 21, 37, 16, - 211, 43, 201, 20, 37, 16, 211, 43, 201, 19, 37, 16, 211, 43, 201, 18, 37, - 16, 211, 43, 201, 17, 37, 16, 211, 43, 201, 26, 37, 16, 211, 43, 201, 25, - 37, 16, 230, 0, 37, 16, 214, 113, 37, 16, 234, 95, 79, 201, 69, 37, 16, - 237, 125, 202, 97, 37, 16, 33, 144, 248, 69, 37, 16, 33, 133, 248, 69, - 37, 16, 33, 230, 14, 37, 16, 33, 202, 57, 209, 111, 37, 16, 210, 54, 77, - 37, 16, 210, 54, 133, 77, 37, 16, 132, 210, 54, 77, 37, 16, 231, 13, 196, - 77, 37, 16, 231, 13, 235, 123, 37, 16, 4, 232, 249, 37, 16, 237, 241, 37, - 16, 237, 242, 251, 174, 37, 16, 217, 23, 37, 16, 219, 10, 37, 16, 248, - 33, 37, 16, 204, 29, 193, 89, 37, 16, 204, 29, 248, 139, 37, 16, 216, 39, - 37, 16, 216, 40, 248, 139, 37, 16, 204, 23, 193, 89, 37, 16, 204, 23, - 248, 139, 37, 16, 232, 70, 193, 89, 37, 16, 232, 70, 248, 139, 37, 16, - 219, 11, 210, 9, 207, 30, 37, 16, 219, 11, 223, 167, 207, 30, 37, 16, - 248, 34, 207, 30, 37, 16, 204, 29, 207, 30, 37, 16, 216, 40, 207, 30, 37, - 16, 204, 23, 207, 30, 37, 16, 199, 97, 210, 7, 238, 186, 208, 192, 210, - 8, 37, 16, 199, 97, 210, 7, 238, 186, 208, 192, 223, 166, 37, 16, 199, - 97, 210, 7, 238, 186, 208, 192, 210, 9, 236, 248, 37, 16, 199, 97, 223, - 165, 238, 186, 208, 192, 210, 8, 37, 16, 199, 97, 223, 165, 238, 186, - 208, 192, 223, 166, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, - 167, 236, 248, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, 167, - 236, 247, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, 167, 236, - 246, 37, 16, 238, 220, 37, 16, 230, 199, 247, 194, 242, 235, 37, 16, 230, - 199, 233, 176, 242, 235, 37, 16, 51, 250, 120, 37, 16, 195, 39, 37, 16, - 209, 69, 37, 16, 242, 224, 37, 16, 205, 95, 37, 16, 242, 229, 37, 16, - 198, 47, 37, 16, 209, 28, 37, 16, 209, 29, 232, 198, 37, 16, 205, 96, - 232, 198, 37, 16, 198, 48, 207, 27, 37, 16, 209, 246, 200, 231, 37, 16, - 221, 148, 247, 194, 242, 235, 37, 16, 221, 148, 234, 95, 79, 209, 175, - 37, 16, 221, 148, 53, 213, 6, 37, 16, 221, 148, 207, 99, 77, 37, 16, 221, - 148, 193, 87, 213, 6, 37, 16, 221, 148, 132, 213, 6, 37, 16, 221, 148, - 208, 23, 213, 7, 201, 81, 235, 123, 37, 16, 221, 148, 208, 23, 213, 7, - 201, 81, 196, 77, 37, 16, 221, 148, 234, 160, 213, 7, 201, 81, 235, 123, - 37, 16, 221, 148, 234, 160, 213, 7, 201, 81, 196, 77, 37, 16, 221, 148, - 232, 207, 56, 37, 16, 202, 11, 37, 16, 221, 31, 35, 195, 23, 213, 10, - 200, 123, 35, 195, 23, 213, 10, 200, 112, 35, 195, 23, 213, 10, 200, 102, - 35, 195, 23, 213, 10, 200, 95, 35, 195, 23, 213, 10, 200, 87, 35, 195, - 23, 213, 10, 200, 81, 35, 195, 23, 213, 10, 200, 80, 35, 195, 23, 213, - 10, 200, 79, 35, 195, 23, 213, 10, 200, 78, 35, 195, 23, 213, 10, 200, - 122, 35, 195, 23, 213, 10, 200, 121, 35, 195, 23, 213, 10, 200, 120, 35, - 195, 23, 213, 10, 200, 119, 35, 195, 23, 213, 10, 200, 118, 35, 195, 23, - 213, 10, 200, 117, 35, 195, 23, 213, 10, 200, 116, 35, 195, 23, 213, 10, - 200, 115, 35, 195, 23, 213, 10, 200, 114, 35, 195, 23, 213, 10, 200, 113, - 35, 195, 23, 213, 10, 200, 111, 35, 195, 23, 213, 10, 200, 110, 35, 195, - 23, 213, 10, 200, 109, 35, 195, 23, 213, 10, 200, 108, 35, 195, 23, 213, - 10, 200, 107, 35, 195, 23, 213, 10, 200, 86, 35, 195, 23, 213, 10, 200, - 85, 35, 195, 23, 213, 10, 200, 84, 35, 195, 23, 213, 10, 200, 83, 35, - 195, 23, 213, 10, 200, 82, 35, 223, 116, 213, 10, 200, 123, 35, 223, 116, - 213, 10, 200, 112, 35, 223, 116, 213, 10, 200, 95, 35, 223, 116, 213, 10, - 200, 87, 35, 223, 116, 213, 10, 200, 80, 35, 223, 116, 213, 10, 200, 79, - 35, 223, 116, 213, 10, 200, 121, 35, 223, 116, 213, 10, 200, 120, 35, - 223, 116, 213, 10, 200, 119, 35, 223, 116, 213, 10, 200, 118, 35, 223, - 116, 213, 10, 200, 115, 35, 223, 116, 213, 10, 200, 114, 35, 223, 116, - 213, 10, 200, 113, 35, 223, 116, 213, 10, 200, 108, 35, 223, 116, 213, - 10, 200, 107, 35, 223, 116, 213, 10, 200, 106, 35, 223, 116, 213, 10, - 200, 105, 35, 223, 116, 213, 10, 200, 104, 35, 223, 116, 213, 10, 200, - 103, 35, 223, 116, 213, 10, 200, 101, 35, 223, 116, 213, 10, 200, 100, - 35, 223, 116, 213, 10, 200, 99, 35, 223, 116, 213, 10, 200, 98, 35, 223, - 116, 213, 10, 200, 97, 35, 223, 116, 213, 10, 200, 96, 35, 223, 116, 213, - 10, 200, 94, 35, 223, 116, 213, 10, 200, 93, 35, 223, 116, 213, 10, 200, - 92, 35, 223, 116, 213, 10, 200, 91, 35, 223, 116, 213, 10, 200, 90, 35, - 223, 116, 213, 10, 200, 89, 35, 223, 116, 213, 10, 200, 88, 35, 223, 116, - 213, 10, 200, 86, 35, 223, 116, 213, 10, 200, 85, 35, 223, 116, 213, 10, - 200, 84, 35, 223, 116, 213, 10, 200, 83, 35, 223, 116, 213, 10, 200, 82, - 33, 35, 37, 197, 221, 33, 35, 37, 199, 65, 33, 35, 37, 210, 22, 35, 37, - 219, 206, 222, 93, 212, 134, 191, 77, 222, 93, 212, 134, 107, 222, 93, - 212, 134, 109, 222, 93, 212, 134, 138, 222, 93, 212, 134, 134, 222, 93, - 212, 134, 149, 222, 93, 212, 134, 169, 222, 93, 212, 134, 175, 222, 93, - 212, 134, 171, 222, 93, 212, 134, 178, 222, 93, 212, 134, 199, 95, 222, - 93, 212, 134, 234, 127, 222, 93, 212, 134, 197, 37, 222, 93, 212, 134, - 198, 251, 222, 93, 212, 134, 232, 122, 222, 93, 212, 134, 233, 19, 222, - 93, 212, 134, 202, 130, 222, 93, 212, 134, 203, 244, 222, 93, 212, 134, - 234, 161, 222, 93, 212, 134, 213, 171, 217, 20, 212, 134, 191, 77, 217, - 20, 212, 134, 107, 217, 20, 212, 134, 109, 217, 20, 212, 134, 138, 217, - 20, 212, 134, 134, 217, 20, 212, 134, 149, 217, 20, 212, 134, 169, 217, - 20, 212, 134, 175, 217, 20, 212, 134, 171, 217, 20, 212, 134, 178, 217, - 20, 212, 134, 199, 95, 217, 20, 212, 134, 234, 127, 217, 20, 212, 134, - 197, 37, 217, 20, 212, 134, 198, 251, 217, 20, 212, 134, 232, 122, 217, - 20, 212, 134, 233, 19, 217, 20, 212, 134, 202, 130, 217, 20, 212, 134, - 203, 244, 217, 20, 212, 134, 234, 161, 217, 20, 212, 134, 213, 171, 215, - 221, 40, 234, 207, 237, 6, 40, 229, 218, 234, 207, 237, 6, 40, 228, 145, - 234, 207, 237, 6, 40, 234, 206, 229, 219, 237, 6, 40, 234, 206, 228, 144, - 237, 6, 40, 234, 207, 199, 67, 40, 247, 21, 199, 67, 40, 232, 80, 243, - 10, 199, 67, 40, 216, 30, 199, 67, 40, 249, 78, 199, 67, 40, 222, 10, - 202, 70, 199, 67, 40, 239, 23, 199, 67, 40, 250, 212, 199, 67, 40, 211, - 62, 199, 67, 40, 248, 45, 211, 14, 199, 67, 40, 237, 127, 211, 57, 236, - 213, 199, 67, 40, 236, 210, 199, 67, 40, 191, 237, 199, 67, 40, 223, 153, - 199, 67, 40, 210, 32, 199, 67, 40, 207, 108, 199, 67, 40, 239, 35, 199, - 67, 40, 229, 6, 249, 146, 199, 67, 40, 193, 171, 199, 67, 40, 232, 169, - 199, 67, 40, 252, 28, 199, 67, 40, 207, 62, 199, 67, 40, 207, 34, 199, - 67, 40, 234, 205, 199, 67, 40, 222, 185, 199, 67, 40, 239, 30, 199, 67, - 40, 234, 93, 199, 67, 40, 235, 59, 199, 67, 40, 246, 244, 199, 67, 40, - 237, 137, 199, 67, 40, 28, 207, 33, 199, 67, 40, 210, 211, 199, 67, 40, - 219, 210, 199, 67, 40, 242, 217, 199, 67, 40, 221, 136, 199, 67, 40, 231, - 189, 199, 67, 40, 201, 39, 199, 67, 40, 208, 140, 199, 67, 40, 232, 79, - 199, 67, 40, 207, 35, 199, 67, 40, 219, 251, 211, 57, 216, 2, 199, 67, - 40, 207, 31, 199, 67, 40, 230, 252, 119, 216, 206, 199, 67, 40, 234, 96, - 199, 67, 40, 201, 56, 199, 67, 40, 230, 202, 199, 67, 40, 234, 86, 199, - 67, 40, 210, 83, 199, 67, 40, 206, 177, 199, 67, 40, 232, 196, 199, 67, - 40, 195, 163, 211, 57, 193, 147, 199, 67, 40, 239, 40, 199, 67, 40, 216, - 227, 199, 67, 40, 233, 250, 199, 67, 40, 196, 88, 199, 67, 40, 236, 249, - 199, 67, 40, 242, 219, 215, 179, 199, 67, 40, 230, 171, 199, 67, 40, 231, - 190, 223, 162, 199, 67, 40, 217, 32, 199, 67, 40, 252, 54, 199, 67, 40, - 234, 112, 199, 67, 40, 235, 127, 199, 67, 40, 193, 145, 199, 67, 40, 202, - 165, 199, 67, 40, 223, 126, 199, 67, 40, 237, 93, 199, 67, 40, 237, 219, - 199, 67, 40, 236, 245, 199, 67, 40, 233, 213, 199, 67, 40, 203, 240, 199, - 67, 40, 201, 60, 199, 67, 40, 230, 16, 199, 67, 40, 242, 66, 199, 67, 40, - 242, 214, 199, 67, 40, 233, 88, 199, 67, 40, 251, 248, 199, 67, 40, 242, - 65, 199, 67, 40, 211, 105, 199, 34, 195, 138, 199, 67, 40, 237, 15, 199, - 67, 40, 220, 113, 199, 67, 40, 232, 131, 238, 244, 206, 145, 196, 91, 17, - 107, 238, 244, 206, 145, 196, 91, 17, 109, 238, 244, 206, 145, 196, 91, - 17, 138, 238, 244, 206, 145, 196, 91, 17, 134, 238, 244, 206, 145, 196, - 91, 17, 149, 238, 244, 206, 145, 196, 91, 17, 169, 238, 244, 206, 145, - 196, 91, 17, 175, 238, 244, 206, 145, 196, 91, 17, 171, 238, 244, 206, - 145, 196, 91, 17, 178, 238, 244, 206, 145, 199, 91, 17, 107, 238, 244, - 206, 145, 199, 91, 17, 109, 238, 244, 206, 145, 199, 91, 17, 138, 238, - 244, 206, 145, 199, 91, 17, 134, 238, 244, 206, 145, 199, 91, 17, 149, - 238, 244, 206, 145, 199, 91, 17, 169, 238, 244, 206, 145, 199, 91, 17, - 175, 238, 244, 206, 145, 199, 91, 17, 171, 238, 244, 206, 145, 199, 91, - 17, 178, 154, 199, 198, 87, 107, 154, 199, 198, 87, 109, 154, 199, 198, - 87, 138, 154, 199, 198, 87, 134, 154, 199, 198, 87, 149, 199, 198, 87, - 107, 199, 198, 87, 149, 13, 28, 6, 65, 13, 28, 6, 250, 120, 13, 28, 6, - 247, 193, 13, 28, 6, 238, 127, 13, 28, 6, 71, 13, 28, 6, 233, 175, 13, - 28, 6, 232, 51, 13, 28, 6, 230, 116, 13, 28, 6, 68, 13, 28, 6, 223, 35, - 13, 28, 6, 222, 152, 13, 28, 6, 172, 13, 28, 6, 218, 168, 13, 28, 6, 215, - 61, 13, 28, 6, 74, 13, 28, 6, 210, 236, 13, 28, 6, 208, 104, 13, 28, 6, - 146, 13, 28, 6, 206, 8, 13, 28, 6, 200, 43, 13, 28, 6, 66, 13, 28, 6, - 196, 12, 13, 28, 6, 193, 224, 13, 28, 6, 192, 235, 13, 28, 6, 192, 159, - 13, 28, 6, 191, 166, 13, 28, 2, 65, 13, 28, 2, 250, 120, 13, 28, 2, 247, - 193, 13, 28, 2, 238, 127, 13, 28, 2, 71, 13, 28, 2, 233, 175, 13, 28, 2, - 232, 51, 13, 28, 2, 230, 116, 13, 28, 2, 68, 13, 28, 2, 223, 35, 13, 28, - 2, 222, 152, 13, 28, 2, 172, 13, 28, 2, 218, 168, 13, 28, 2, 215, 61, 13, - 28, 2, 74, 13, 28, 2, 210, 236, 13, 28, 2, 208, 104, 13, 28, 2, 146, 13, - 28, 2, 206, 8, 13, 28, 2, 200, 43, 13, 28, 2, 66, 13, 28, 2, 196, 12, 13, - 28, 2, 193, 224, 13, 28, 2, 192, 235, 13, 28, 2, 192, 159, 13, 28, 2, - 191, 166, 13, 43, 6, 65, 13, 43, 6, 250, 120, 13, 43, 6, 247, 193, 13, - 43, 6, 238, 127, 13, 43, 6, 71, 13, 43, 6, 233, 175, 13, 43, 6, 232, 51, - 13, 43, 6, 230, 116, 13, 43, 6, 68, 13, 43, 6, 223, 35, 13, 43, 6, 222, - 152, 13, 43, 6, 172, 13, 43, 6, 218, 168, 13, 43, 6, 215, 61, 13, 43, 6, - 74, 13, 43, 6, 210, 236, 13, 43, 6, 208, 104, 13, 43, 6, 146, 13, 43, 6, - 206, 8, 13, 43, 6, 200, 43, 13, 43, 6, 66, 13, 43, 6, 196, 12, 13, 43, 6, - 193, 224, 13, 43, 6, 192, 235, 13, 43, 6, 192, 159, 13, 43, 6, 191, 166, - 13, 43, 2, 65, 13, 43, 2, 250, 120, 13, 43, 2, 247, 193, 13, 43, 2, 238, - 127, 13, 43, 2, 71, 13, 43, 2, 233, 175, 13, 43, 2, 232, 51, 13, 43, 2, - 68, 13, 43, 2, 223, 35, 13, 43, 2, 222, 152, 13, 43, 2, 172, 13, 43, 2, - 218, 168, 13, 43, 2, 215, 61, 13, 43, 2, 74, 13, 43, 2, 210, 236, 13, 43, - 2, 208, 104, 13, 43, 2, 146, 13, 43, 2, 206, 8, 13, 43, 2, 200, 43, 13, - 43, 2, 66, 13, 43, 2, 196, 12, 13, 43, 2, 193, 224, 13, 43, 2, 192, 235, - 13, 43, 2, 192, 159, 13, 43, 2, 191, 166, 13, 28, 43, 6, 65, 13, 28, 43, - 6, 250, 120, 13, 28, 43, 6, 247, 193, 13, 28, 43, 6, 238, 127, 13, 28, - 43, 6, 71, 13, 28, 43, 6, 233, 175, 13, 28, 43, 6, 232, 51, 13, 28, 43, - 6, 230, 116, 13, 28, 43, 6, 68, 13, 28, 43, 6, 223, 35, 13, 28, 43, 6, - 222, 152, 13, 28, 43, 6, 172, 13, 28, 43, 6, 218, 168, 13, 28, 43, 6, - 215, 61, 13, 28, 43, 6, 74, 13, 28, 43, 6, 210, 236, 13, 28, 43, 6, 208, - 104, 13, 28, 43, 6, 146, 13, 28, 43, 6, 206, 8, 13, 28, 43, 6, 200, 43, - 13, 28, 43, 6, 66, 13, 28, 43, 6, 196, 12, 13, 28, 43, 6, 193, 224, 13, - 28, 43, 6, 192, 235, 13, 28, 43, 6, 192, 159, 13, 28, 43, 6, 191, 166, - 13, 28, 43, 2, 65, 13, 28, 43, 2, 250, 120, 13, 28, 43, 2, 247, 193, 13, - 28, 43, 2, 238, 127, 13, 28, 43, 2, 71, 13, 28, 43, 2, 233, 175, 13, 28, - 43, 2, 232, 51, 13, 28, 43, 2, 230, 116, 13, 28, 43, 2, 68, 13, 28, 43, - 2, 223, 35, 13, 28, 43, 2, 222, 152, 13, 28, 43, 2, 172, 13, 28, 43, 2, - 218, 168, 13, 28, 43, 2, 215, 61, 13, 28, 43, 2, 74, 13, 28, 43, 2, 210, - 236, 13, 28, 43, 2, 208, 104, 13, 28, 43, 2, 146, 13, 28, 43, 2, 206, 8, - 13, 28, 43, 2, 200, 43, 13, 28, 43, 2, 66, 13, 28, 43, 2, 196, 12, 13, - 28, 43, 2, 193, 224, 13, 28, 43, 2, 192, 235, 13, 28, 43, 2, 192, 159, - 13, 28, 43, 2, 191, 166, 13, 27, 6, 65, 13, 27, 6, 247, 193, 13, 27, 6, - 238, 127, 13, 27, 6, 232, 51, 13, 27, 6, 223, 35, 13, 27, 6, 222, 152, - 13, 27, 6, 215, 61, 13, 27, 6, 74, 13, 27, 6, 210, 236, 13, 27, 6, 208, - 104, 13, 27, 6, 206, 8, 13, 27, 6, 200, 43, 13, 27, 6, 66, 13, 27, 6, + 232, 252, 197, 253, 37, 16, 232, 252, 197, 252, 37, 16, 232, 252, 197, + 251, 37, 16, 33, 250, 162, 236, 142, 37, 16, 33, 232, 218, 37, 16, 33, + 232, 217, 37, 16, 33, 232, 216, 37, 16, 33, 232, 215, 37, 16, 33, 232, + 214, 37, 16, 248, 251, 249, 16, 37, 16, 234, 97, 249, 16, 37, 16, 248, + 251, 198, 178, 37, 16, 234, 97, 198, 178, 37, 16, 248, 251, 202, 72, 37, + 16, 234, 97, 202, 72, 37, 16, 248, 251, 209, 194, 37, 16, 234, 97, 209, + 194, 37, 16, 33, 252, 62, 37, 16, 33, 201, 116, 37, 16, 33, 199, 83, 37, + 16, 33, 201, 117, 37, 16, 33, 217, 62, 37, 16, 33, 217, 61, 37, 16, 33, + 252, 61, 37, 16, 33, 218, 245, 37, 16, 250, 243, 196, 77, 37, 16, 250, + 243, 235, 125, 37, 16, 33, 236, 160, 37, 16, 33, 206, 185, 37, 16, 33, + 232, 197, 37, 16, 33, 202, 68, 37, 16, 33, 248, 229, 37, 16, 33, 55, 198, + 61, 37, 16, 33, 197, 225, 198, 61, 37, 16, 206, 191, 37, 16, 200, 242, + 37, 16, 191, 166, 37, 16, 209, 186, 37, 16, 216, 153, 37, 16, 232, 142, + 37, 16, 238, 231, 37, 16, 237, 134, 37, 16, 230, 230, 213, 9, 202, 98, + 37, 16, 230, 230, 213, 9, 213, 46, 202, 98, 37, 16, 198, 27, 37, 16, 197, + 58, 37, 16, 223, 95, 197, 58, 37, 16, 197, 59, 202, 98, 37, 16, 197, 59, + 196, 77, 37, 16, 211, 45, 201, 28, 37, 16, 211, 45, 201, 25, 37, 16, 211, + 45, 201, 24, 37, 16, 211, 45, 201, 23, 37, 16, 211, 45, 201, 22, 37, 16, + 211, 45, 201, 21, 37, 16, 211, 45, 201, 20, 37, 16, 211, 45, 201, 19, 37, + 16, 211, 45, 201, 18, 37, 16, 211, 45, 201, 27, 37, 16, 211, 45, 201, 26, + 37, 16, 230, 2, 37, 16, 214, 115, 37, 16, 234, 97, 79, 201, 70, 37, 16, + 237, 127, 202, 98, 37, 16, 33, 144, 248, 71, 37, 16, 33, 133, 248, 71, + 37, 16, 33, 230, 16, 37, 16, 33, 202, 58, 209, 113, 37, 16, 210, 56, 77, + 37, 16, 210, 56, 133, 77, 37, 16, 132, 210, 56, 77, 37, 16, 231, 15, 196, + 77, 37, 16, 231, 15, 235, 125, 37, 16, 4, 232, 251, 37, 16, 237, 243, 37, + 16, 237, 244, 251, 176, 37, 16, 217, 25, 37, 16, 219, 12, 37, 16, 248, + 35, 37, 16, 204, 30, 193, 89, 37, 16, 204, 30, 248, 141, 37, 16, 216, 41, + 37, 16, 216, 42, 248, 141, 37, 16, 204, 24, 193, 89, 37, 16, 204, 24, + 248, 141, 37, 16, 232, 72, 193, 89, 37, 16, 232, 72, 248, 141, 37, 16, + 219, 13, 210, 11, 207, 31, 37, 16, 219, 13, 223, 169, 207, 31, 37, 16, + 248, 36, 207, 31, 37, 16, 204, 30, 207, 31, 37, 16, 216, 42, 207, 31, 37, + 16, 204, 24, 207, 31, 37, 16, 199, 97, 210, 9, 238, 188, 208, 194, 210, + 10, 37, 16, 199, 97, 210, 9, 238, 188, 208, 194, 223, 168, 37, 16, 199, + 97, 210, 9, 238, 188, 208, 194, 210, 11, 236, 250, 37, 16, 199, 97, 223, + 167, 238, 188, 208, 194, 210, 10, 37, 16, 199, 97, 223, 167, 238, 188, + 208, 194, 223, 168, 37, 16, 199, 97, 223, 167, 238, 188, 208, 194, 223, + 169, 236, 250, 37, 16, 199, 97, 223, 167, 238, 188, 208, 194, 223, 169, + 236, 249, 37, 16, 199, 97, 223, 167, 238, 188, 208, 194, 223, 169, 236, + 248, 37, 16, 238, 222, 37, 16, 230, 201, 247, 196, 242, 237, 37, 16, 230, + 201, 233, 178, 242, 237, 37, 16, 51, 250, 122, 37, 16, 195, 39, 37, 16, + 209, 71, 37, 16, 242, 226, 37, 16, 205, 96, 37, 16, 242, 231, 37, 16, + 198, 47, 37, 16, 209, 30, 37, 16, 209, 31, 232, 200, 37, 16, 205, 97, + 232, 200, 37, 16, 198, 48, 207, 28, 37, 16, 209, 248, 200, 232, 37, 16, + 221, 150, 247, 196, 242, 237, 37, 16, 221, 150, 234, 97, 79, 209, 177, + 37, 16, 221, 150, 53, 213, 8, 37, 16, 221, 150, 207, 101, 77, 37, 16, + 221, 150, 193, 87, 213, 8, 37, 16, 221, 150, 132, 213, 8, 37, 16, 221, + 150, 208, 25, 213, 9, 201, 82, 235, 125, 37, 16, 221, 150, 208, 25, 213, + 9, 201, 82, 196, 77, 37, 16, 221, 150, 234, 162, 213, 9, 201, 82, 235, + 125, 37, 16, 221, 150, 234, 162, 213, 9, 201, 82, 196, 77, 37, 16, 221, + 150, 232, 209, 56, 37, 16, 202, 12, 37, 16, 221, 33, 35, 195, 23, 213, + 12, 200, 123, 35, 195, 23, 213, 12, 200, 112, 35, 195, 23, 213, 12, 200, + 102, 35, 195, 23, 213, 12, 200, 95, 35, 195, 23, 213, 12, 200, 87, 35, + 195, 23, 213, 12, 200, 81, 35, 195, 23, 213, 12, 200, 80, 35, 195, 23, + 213, 12, 200, 79, 35, 195, 23, 213, 12, 200, 78, 35, 195, 23, 213, 12, + 200, 122, 35, 195, 23, 213, 12, 200, 121, 35, 195, 23, 213, 12, 200, 120, + 35, 195, 23, 213, 12, 200, 119, 35, 195, 23, 213, 12, 200, 118, 35, 195, + 23, 213, 12, 200, 117, 35, 195, 23, 213, 12, 200, 116, 35, 195, 23, 213, + 12, 200, 115, 35, 195, 23, 213, 12, 200, 114, 35, 195, 23, 213, 12, 200, + 113, 35, 195, 23, 213, 12, 200, 111, 35, 195, 23, 213, 12, 200, 110, 35, + 195, 23, 213, 12, 200, 109, 35, 195, 23, 213, 12, 200, 108, 35, 195, 23, + 213, 12, 200, 107, 35, 195, 23, 213, 12, 200, 86, 35, 195, 23, 213, 12, + 200, 85, 35, 195, 23, 213, 12, 200, 84, 35, 195, 23, 213, 12, 200, 83, + 35, 195, 23, 213, 12, 200, 82, 35, 223, 118, 213, 12, 200, 123, 35, 223, + 118, 213, 12, 200, 112, 35, 223, 118, 213, 12, 200, 95, 35, 223, 118, + 213, 12, 200, 87, 35, 223, 118, 213, 12, 200, 80, 35, 223, 118, 213, 12, + 200, 79, 35, 223, 118, 213, 12, 200, 121, 35, 223, 118, 213, 12, 200, + 120, 35, 223, 118, 213, 12, 200, 119, 35, 223, 118, 213, 12, 200, 118, + 35, 223, 118, 213, 12, 200, 115, 35, 223, 118, 213, 12, 200, 114, 35, + 223, 118, 213, 12, 200, 113, 35, 223, 118, 213, 12, 200, 108, 35, 223, + 118, 213, 12, 200, 107, 35, 223, 118, 213, 12, 200, 106, 35, 223, 118, + 213, 12, 200, 105, 35, 223, 118, 213, 12, 200, 104, 35, 223, 118, 213, + 12, 200, 103, 35, 223, 118, 213, 12, 200, 101, 35, 223, 118, 213, 12, + 200, 100, 35, 223, 118, 213, 12, 200, 99, 35, 223, 118, 213, 12, 200, 98, + 35, 223, 118, 213, 12, 200, 97, 35, 223, 118, 213, 12, 200, 96, 35, 223, + 118, 213, 12, 200, 94, 35, 223, 118, 213, 12, 200, 93, 35, 223, 118, 213, + 12, 200, 92, 35, 223, 118, 213, 12, 200, 91, 35, 223, 118, 213, 12, 200, + 90, 35, 223, 118, 213, 12, 200, 89, 35, 223, 118, 213, 12, 200, 88, 35, + 223, 118, 213, 12, 200, 86, 35, 223, 118, 213, 12, 200, 85, 35, 223, 118, + 213, 12, 200, 84, 35, 223, 118, 213, 12, 200, 83, 35, 223, 118, 213, 12, + 200, 82, 33, 35, 37, 197, 221, 33, 35, 37, 199, 65, 33, 35, 37, 210, 24, + 35, 37, 219, 208, 222, 95, 212, 136, 191, 77, 222, 95, 212, 136, 107, + 222, 95, 212, 136, 109, 222, 95, 212, 136, 138, 222, 95, 212, 136, 134, + 222, 95, 212, 136, 150, 222, 95, 212, 136, 169, 222, 95, 212, 136, 175, + 222, 95, 212, 136, 171, 222, 95, 212, 136, 178, 222, 95, 212, 136, 199, + 95, 222, 95, 212, 136, 234, 129, 222, 95, 212, 136, 197, 37, 222, 95, + 212, 136, 198, 251, 222, 95, 212, 136, 232, 124, 222, 95, 212, 136, 233, + 21, 222, 95, 212, 136, 202, 131, 222, 95, 212, 136, 203, 245, 222, 95, + 212, 136, 234, 163, 222, 95, 212, 136, 213, 173, 217, 22, 212, 136, 191, + 77, 217, 22, 212, 136, 107, 217, 22, 212, 136, 109, 217, 22, 212, 136, + 138, 217, 22, 212, 136, 134, 217, 22, 212, 136, 150, 217, 22, 212, 136, + 169, 217, 22, 212, 136, 175, 217, 22, 212, 136, 171, 217, 22, 212, 136, + 178, 217, 22, 212, 136, 199, 95, 217, 22, 212, 136, 234, 129, 217, 22, + 212, 136, 197, 37, 217, 22, 212, 136, 198, 251, 217, 22, 212, 136, 232, + 124, 217, 22, 212, 136, 233, 21, 217, 22, 212, 136, 202, 131, 217, 22, + 212, 136, 203, 245, 217, 22, 212, 136, 234, 163, 217, 22, 212, 136, 213, + 173, 215, 223, 40, 234, 209, 237, 8, 40, 229, 220, 234, 209, 237, 8, 40, + 228, 147, 234, 209, 237, 8, 40, 234, 208, 229, 221, 237, 8, 40, 234, 208, + 228, 146, 237, 8, 40, 234, 209, 199, 67, 40, 247, 23, 199, 67, 40, 232, + 82, 243, 12, 199, 67, 40, 216, 32, 199, 67, 40, 249, 80, 199, 67, 40, + 222, 12, 202, 71, 199, 67, 40, 239, 25, 199, 67, 40, 250, 214, 199, 67, + 40, 211, 64, 199, 67, 40, 248, 47, 211, 16, 199, 67, 40, 237, 129, 211, + 59, 236, 215, 199, 67, 40, 236, 212, 199, 67, 40, 191, 237, 199, 67, 40, + 223, 155, 199, 67, 40, 210, 34, 199, 67, 40, 207, 110, 199, 67, 40, 239, + 37, 199, 67, 40, 229, 8, 249, 148, 199, 67, 40, 193, 171, 199, 67, 40, + 232, 171, 199, 67, 40, 252, 30, 199, 67, 40, 207, 63, 199, 67, 40, 207, + 35, 199, 67, 40, 234, 207, 199, 67, 40, 222, 187, 199, 67, 40, 239, 32, + 199, 67, 40, 234, 95, 199, 67, 40, 235, 61, 199, 67, 40, 246, 246, 199, + 67, 40, 237, 139, 199, 67, 40, 28, 207, 34, 199, 67, 40, 210, 213, 199, + 67, 40, 219, 212, 199, 67, 40, 242, 219, 199, 67, 40, 221, 138, 199, 67, + 40, 231, 191, 199, 67, 40, 201, 40, 199, 67, 40, 208, 142, 199, 67, 40, + 232, 81, 199, 67, 40, 207, 36, 199, 67, 40, 219, 253, 211, 59, 216, 4, + 199, 67, 40, 207, 32, 199, 67, 40, 230, 254, 119, 216, 208, 199, 67, 40, + 234, 98, 199, 67, 40, 201, 57, 199, 67, 40, 230, 204, 199, 67, 40, 234, + 88, 199, 67, 40, 210, 85, 199, 67, 40, 206, 178, 199, 67, 40, 232, 198, + 199, 67, 40, 195, 163, 211, 59, 193, 147, 199, 67, 40, 239, 42, 199, 67, + 40, 216, 229, 199, 67, 40, 233, 252, 199, 67, 40, 196, 88, 199, 67, 40, + 236, 251, 199, 67, 40, 242, 221, 215, 181, 199, 67, 40, 230, 173, 199, + 67, 40, 231, 192, 223, 164, 199, 67, 40, 217, 34, 199, 67, 40, 252, 56, + 199, 67, 40, 234, 114, 199, 67, 40, 235, 129, 199, 67, 40, 193, 145, 199, + 67, 40, 202, 166, 199, 67, 40, 223, 128, 199, 67, 40, 237, 95, 199, 67, + 40, 237, 221, 199, 67, 40, 236, 247, 199, 67, 40, 233, 215, 199, 67, 40, + 203, 241, 199, 67, 40, 201, 61, 199, 67, 40, 230, 18, 199, 67, 40, 242, + 68, 199, 67, 40, 242, 216, 199, 67, 40, 233, 90, 199, 67, 40, 251, 250, + 199, 67, 40, 242, 67, 199, 67, 40, 211, 107, 199, 34, 195, 138, 199, 67, + 40, 237, 17, 199, 67, 40, 220, 115, 199, 67, 40, 232, 133, 238, 246, 206, + 146, 196, 91, 17, 107, 238, 246, 206, 146, 196, 91, 17, 109, 238, 246, + 206, 146, 196, 91, 17, 138, 238, 246, 206, 146, 196, 91, 17, 134, 238, + 246, 206, 146, 196, 91, 17, 150, 238, 246, 206, 146, 196, 91, 17, 169, + 238, 246, 206, 146, 196, 91, 17, 175, 238, 246, 206, 146, 196, 91, 17, + 171, 238, 246, 206, 146, 196, 91, 17, 178, 238, 246, 206, 146, 199, 91, + 17, 107, 238, 246, 206, 146, 199, 91, 17, 109, 238, 246, 206, 146, 199, + 91, 17, 138, 238, 246, 206, 146, 199, 91, 17, 134, 238, 246, 206, 146, + 199, 91, 17, 150, 238, 246, 206, 146, 199, 91, 17, 169, 238, 246, 206, + 146, 199, 91, 17, 175, 238, 246, 206, 146, 199, 91, 17, 171, 238, 246, + 206, 146, 199, 91, 17, 178, 148, 199, 198, 87, 107, 148, 199, 198, 87, + 109, 148, 199, 198, 87, 138, 148, 199, 198, 87, 134, 148, 199, 198, 87, + 150, 199, 198, 87, 107, 199, 198, 87, 150, 13, 28, 6, 65, 13, 28, 6, 250, + 122, 13, 28, 6, 247, 195, 13, 28, 6, 238, 129, 13, 28, 6, 71, 13, 28, 6, + 233, 177, 13, 28, 6, 232, 53, 13, 28, 6, 230, 118, 13, 28, 6, 68, 13, 28, + 6, 223, 37, 13, 28, 6, 222, 154, 13, 28, 6, 172, 13, 28, 6, 218, 170, 13, + 28, 6, 215, 63, 13, 28, 6, 74, 13, 28, 6, 210, 238, 13, 28, 6, 208, 106, + 13, 28, 6, 146, 13, 28, 6, 206, 9, 13, 28, 6, 200, 43, 13, 28, 6, 66, 13, + 28, 6, 196, 12, 13, 28, 6, 193, 224, 13, 28, 6, 192, 235, 13, 28, 6, 192, + 159, 13, 28, 6, 191, 166, 13, 28, 2, 65, 13, 28, 2, 250, 122, 13, 28, 2, + 247, 195, 13, 28, 2, 238, 129, 13, 28, 2, 71, 13, 28, 2, 233, 177, 13, + 28, 2, 232, 53, 13, 28, 2, 230, 118, 13, 28, 2, 68, 13, 28, 2, 223, 37, + 13, 28, 2, 222, 154, 13, 28, 2, 172, 13, 28, 2, 218, 170, 13, 28, 2, 215, + 63, 13, 28, 2, 74, 13, 28, 2, 210, 238, 13, 28, 2, 208, 106, 13, 28, 2, + 146, 13, 28, 2, 206, 9, 13, 28, 2, 200, 43, 13, 28, 2, 66, 13, 28, 2, + 196, 12, 13, 28, 2, 193, 224, 13, 28, 2, 192, 235, 13, 28, 2, 192, 159, + 13, 28, 2, 191, 166, 13, 43, 6, 65, 13, 43, 6, 250, 122, 13, 43, 6, 247, + 195, 13, 43, 6, 238, 129, 13, 43, 6, 71, 13, 43, 6, 233, 177, 13, 43, 6, + 232, 53, 13, 43, 6, 230, 118, 13, 43, 6, 68, 13, 43, 6, 223, 37, 13, 43, + 6, 222, 154, 13, 43, 6, 172, 13, 43, 6, 218, 170, 13, 43, 6, 215, 63, 13, + 43, 6, 74, 13, 43, 6, 210, 238, 13, 43, 6, 208, 106, 13, 43, 6, 146, 13, + 43, 6, 206, 9, 13, 43, 6, 200, 43, 13, 43, 6, 66, 13, 43, 6, 196, 12, 13, + 43, 6, 193, 224, 13, 43, 6, 192, 235, 13, 43, 6, 192, 159, 13, 43, 6, + 191, 166, 13, 43, 2, 65, 13, 43, 2, 250, 122, 13, 43, 2, 247, 195, 13, + 43, 2, 238, 129, 13, 43, 2, 71, 13, 43, 2, 233, 177, 13, 43, 2, 232, 53, + 13, 43, 2, 68, 13, 43, 2, 223, 37, 13, 43, 2, 222, 154, 13, 43, 2, 172, + 13, 43, 2, 218, 170, 13, 43, 2, 215, 63, 13, 43, 2, 74, 13, 43, 2, 210, + 238, 13, 43, 2, 208, 106, 13, 43, 2, 146, 13, 43, 2, 206, 9, 13, 43, 2, + 200, 43, 13, 43, 2, 66, 13, 43, 2, 196, 12, 13, 43, 2, 193, 224, 13, 43, + 2, 192, 235, 13, 43, 2, 192, 159, 13, 43, 2, 191, 166, 13, 28, 43, 6, 65, + 13, 28, 43, 6, 250, 122, 13, 28, 43, 6, 247, 195, 13, 28, 43, 6, 238, + 129, 13, 28, 43, 6, 71, 13, 28, 43, 6, 233, 177, 13, 28, 43, 6, 232, 53, + 13, 28, 43, 6, 230, 118, 13, 28, 43, 6, 68, 13, 28, 43, 6, 223, 37, 13, + 28, 43, 6, 222, 154, 13, 28, 43, 6, 172, 13, 28, 43, 6, 218, 170, 13, 28, + 43, 6, 215, 63, 13, 28, 43, 6, 74, 13, 28, 43, 6, 210, 238, 13, 28, 43, + 6, 208, 106, 13, 28, 43, 6, 146, 13, 28, 43, 6, 206, 9, 13, 28, 43, 6, + 200, 43, 13, 28, 43, 6, 66, 13, 28, 43, 6, 196, 12, 13, 28, 43, 6, 193, + 224, 13, 28, 43, 6, 192, 235, 13, 28, 43, 6, 192, 159, 13, 28, 43, 6, + 191, 166, 13, 28, 43, 2, 65, 13, 28, 43, 2, 250, 122, 13, 28, 43, 2, 247, + 195, 13, 28, 43, 2, 238, 129, 13, 28, 43, 2, 71, 13, 28, 43, 2, 233, 177, + 13, 28, 43, 2, 232, 53, 13, 28, 43, 2, 230, 118, 13, 28, 43, 2, 68, 13, + 28, 43, 2, 223, 37, 13, 28, 43, 2, 222, 154, 13, 28, 43, 2, 172, 13, 28, + 43, 2, 218, 170, 13, 28, 43, 2, 215, 63, 13, 28, 43, 2, 74, 13, 28, 43, + 2, 210, 238, 13, 28, 43, 2, 208, 106, 13, 28, 43, 2, 146, 13, 28, 43, 2, + 206, 9, 13, 28, 43, 2, 200, 43, 13, 28, 43, 2, 66, 13, 28, 43, 2, 196, + 12, 13, 28, 43, 2, 193, 224, 13, 28, 43, 2, 192, 235, 13, 28, 43, 2, 192, + 159, 13, 28, 43, 2, 191, 166, 13, 27, 6, 65, 13, 27, 6, 247, 195, 13, 27, + 6, 238, 129, 13, 27, 6, 232, 53, 13, 27, 6, 223, 37, 13, 27, 6, 222, 154, + 13, 27, 6, 215, 63, 13, 27, 6, 74, 13, 27, 6, 210, 238, 13, 27, 6, 208, + 106, 13, 27, 6, 206, 9, 13, 27, 6, 200, 43, 13, 27, 6, 66, 13, 27, 6, 196, 12, 13, 27, 6, 193, 224, 13, 27, 6, 192, 235, 13, 27, 6, 192, 159, - 13, 27, 6, 191, 166, 13, 27, 2, 65, 13, 27, 2, 250, 120, 13, 27, 2, 247, - 193, 13, 27, 2, 238, 127, 13, 27, 2, 233, 175, 13, 27, 2, 230, 116, 13, - 27, 2, 68, 13, 27, 2, 223, 35, 13, 27, 2, 222, 152, 13, 27, 2, 172, 13, - 27, 2, 218, 168, 13, 27, 2, 215, 61, 13, 27, 2, 210, 236, 13, 27, 2, 208, - 104, 13, 27, 2, 146, 13, 27, 2, 206, 8, 13, 27, 2, 200, 43, 13, 27, 2, + 13, 27, 6, 191, 166, 13, 27, 2, 65, 13, 27, 2, 250, 122, 13, 27, 2, 247, + 195, 13, 27, 2, 238, 129, 13, 27, 2, 233, 177, 13, 27, 2, 230, 118, 13, + 27, 2, 68, 13, 27, 2, 223, 37, 13, 27, 2, 222, 154, 13, 27, 2, 172, 13, + 27, 2, 218, 170, 13, 27, 2, 215, 63, 13, 27, 2, 210, 238, 13, 27, 2, 208, + 106, 13, 27, 2, 146, 13, 27, 2, 206, 9, 13, 27, 2, 200, 43, 13, 27, 2, 66, 13, 27, 2, 196, 12, 13, 27, 2, 193, 224, 13, 27, 2, 192, 235, 13, 27, 2, 192, 159, 13, 27, 2, 191, 166, 13, 28, 27, 6, 65, 13, 28, 27, 6, 250, - 120, 13, 28, 27, 6, 247, 193, 13, 28, 27, 6, 238, 127, 13, 28, 27, 6, 71, - 13, 28, 27, 6, 233, 175, 13, 28, 27, 6, 232, 51, 13, 28, 27, 6, 230, 116, - 13, 28, 27, 6, 68, 13, 28, 27, 6, 223, 35, 13, 28, 27, 6, 222, 152, 13, - 28, 27, 6, 172, 13, 28, 27, 6, 218, 168, 13, 28, 27, 6, 215, 61, 13, 28, - 27, 6, 74, 13, 28, 27, 6, 210, 236, 13, 28, 27, 6, 208, 104, 13, 28, 27, - 6, 146, 13, 28, 27, 6, 206, 8, 13, 28, 27, 6, 200, 43, 13, 28, 27, 6, 66, + 122, 13, 28, 27, 6, 247, 195, 13, 28, 27, 6, 238, 129, 13, 28, 27, 6, 71, + 13, 28, 27, 6, 233, 177, 13, 28, 27, 6, 232, 53, 13, 28, 27, 6, 230, 118, + 13, 28, 27, 6, 68, 13, 28, 27, 6, 223, 37, 13, 28, 27, 6, 222, 154, 13, + 28, 27, 6, 172, 13, 28, 27, 6, 218, 170, 13, 28, 27, 6, 215, 63, 13, 28, + 27, 6, 74, 13, 28, 27, 6, 210, 238, 13, 28, 27, 6, 208, 106, 13, 28, 27, + 6, 146, 13, 28, 27, 6, 206, 9, 13, 28, 27, 6, 200, 43, 13, 28, 27, 6, 66, 13, 28, 27, 6, 196, 12, 13, 28, 27, 6, 193, 224, 13, 28, 27, 6, 192, 235, 13, 28, 27, 6, 192, 159, 13, 28, 27, 6, 191, 166, 13, 28, 27, 2, 65, 13, - 28, 27, 2, 250, 120, 13, 28, 27, 2, 247, 193, 13, 28, 27, 2, 238, 127, - 13, 28, 27, 2, 71, 13, 28, 27, 2, 233, 175, 13, 28, 27, 2, 232, 51, 13, - 28, 27, 2, 230, 116, 13, 28, 27, 2, 68, 13, 28, 27, 2, 223, 35, 13, 28, - 27, 2, 222, 152, 13, 28, 27, 2, 172, 13, 28, 27, 2, 218, 168, 13, 28, 27, - 2, 215, 61, 13, 28, 27, 2, 74, 13, 28, 27, 2, 210, 236, 13, 28, 27, 2, - 208, 104, 13, 28, 27, 2, 146, 13, 28, 27, 2, 206, 8, 13, 28, 27, 2, 200, + 28, 27, 2, 250, 122, 13, 28, 27, 2, 247, 195, 13, 28, 27, 2, 238, 129, + 13, 28, 27, 2, 71, 13, 28, 27, 2, 233, 177, 13, 28, 27, 2, 232, 53, 13, + 28, 27, 2, 230, 118, 13, 28, 27, 2, 68, 13, 28, 27, 2, 223, 37, 13, 28, + 27, 2, 222, 154, 13, 28, 27, 2, 172, 13, 28, 27, 2, 218, 170, 13, 28, 27, + 2, 215, 63, 13, 28, 27, 2, 74, 13, 28, 27, 2, 210, 238, 13, 28, 27, 2, + 208, 106, 13, 28, 27, 2, 146, 13, 28, 27, 2, 206, 9, 13, 28, 27, 2, 200, 43, 13, 28, 27, 2, 66, 13, 28, 27, 2, 196, 12, 13, 28, 27, 2, 193, 224, 13, 28, 27, 2, 192, 235, 13, 28, 27, 2, 192, 159, 13, 28, 27, 2, 191, - 166, 13, 232, 115, 6, 65, 13, 232, 115, 6, 250, 120, 13, 232, 115, 6, - 238, 127, 13, 232, 115, 6, 71, 13, 232, 115, 6, 233, 175, 13, 232, 115, - 6, 232, 51, 13, 232, 115, 6, 223, 35, 13, 232, 115, 6, 222, 152, 13, 232, - 115, 6, 172, 13, 232, 115, 6, 218, 168, 13, 232, 115, 6, 215, 61, 13, - 232, 115, 6, 74, 13, 232, 115, 6, 210, 236, 13, 232, 115, 6, 208, 104, - 13, 232, 115, 6, 206, 8, 13, 232, 115, 6, 200, 43, 13, 232, 115, 6, 66, - 13, 232, 115, 6, 196, 12, 13, 232, 115, 6, 193, 224, 13, 232, 115, 6, - 192, 235, 13, 232, 115, 6, 192, 159, 13, 232, 115, 2, 65, 13, 232, 115, - 2, 250, 120, 13, 232, 115, 2, 247, 193, 13, 232, 115, 2, 238, 127, 13, - 232, 115, 2, 71, 13, 232, 115, 2, 233, 175, 13, 232, 115, 2, 232, 51, 13, - 232, 115, 2, 230, 116, 13, 232, 115, 2, 68, 13, 232, 115, 2, 223, 35, 13, - 232, 115, 2, 222, 152, 13, 232, 115, 2, 172, 13, 232, 115, 2, 218, 168, - 13, 232, 115, 2, 215, 61, 13, 232, 115, 2, 74, 13, 232, 115, 2, 210, 236, - 13, 232, 115, 2, 208, 104, 13, 232, 115, 2, 146, 13, 232, 115, 2, 206, 8, - 13, 232, 115, 2, 200, 43, 13, 232, 115, 2, 66, 13, 232, 115, 2, 196, 12, - 13, 232, 115, 2, 193, 224, 13, 232, 115, 2, 192, 235, 13, 232, 115, 2, - 192, 159, 13, 232, 115, 2, 191, 166, 13, 235, 129, 6, 65, 13, 235, 129, - 6, 250, 120, 13, 235, 129, 6, 238, 127, 13, 235, 129, 6, 71, 13, 235, - 129, 6, 233, 175, 13, 235, 129, 6, 232, 51, 13, 235, 129, 6, 68, 13, 235, - 129, 6, 223, 35, 13, 235, 129, 6, 222, 152, 13, 235, 129, 6, 172, 13, - 235, 129, 6, 218, 168, 13, 235, 129, 6, 74, 13, 235, 129, 6, 206, 8, 13, - 235, 129, 6, 200, 43, 13, 235, 129, 6, 66, 13, 235, 129, 6, 196, 12, 13, - 235, 129, 6, 193, 224, 13, 235, 129, 6, 192, 235, 13, 235, 129, 6, 192, - 159, 13, 235, 129, 2, 65, 13, 235, 129, 2, 250, 120, 13, 235, 129, 2, - 247, 193, 13, 235, 129, 2, 238, 127, 13, 235, 129, 2, 71, 13, 235, 129, - 2, 233, 175, 13, 235, 129, 2, 232, 51, 13, 235, 129, 2, 230, 116, 13, - 235, 129, 2, 68, 13, 235, 129, 2, 223, 35, 13, 235, 129, 2, 222, 152, 13, - 235, 129, 2, 172, 13, 235, 129, 2, 218, 168, 13, 235, 129, 2, 215, 61, - 13, 235, 129, 2, 74, 13, 235, 129, 2, 210, 236, 13, 235, 129, 2, 208, - 104, 13, 235, 129, 2, 146, 13, 235, 129, 2, 206, 8, 13, 235, 129, 2, 200, - 43, 13, 235, 129, 2, 66, 13, 235, 129, 2, 196, 12, 13, 235, 129, 2, 193, - 224, 13, 235, 129, 2, 192, 235, 13, 235, 129, 2, 192, 159, 13, 235, 129, - 2, 191, 166, 13, 28, 232, 115, 6, 65, 13, 28, 232, 115, 6, 250, 120, 13, - 28, 232, 115, 6, 247, 193, 13, 28, 232, 115, 6, 238, 127, 13, 28, 232, - 115, 6, 71, 13, 28, 232, 115, 6, 233, 175, 13, 28, 232, 115, 6, 232, 51, - 13, 28, 232, 115, 6, 230, 116, 13, 28, 232, 115, 6, 68, 13, 28, 232, 115, - 6, 223, 35, 13, 28, 232, 115, 6, 222, 152, 13, 28, 232, 115, 6, 172, 13, - 28, 232, 115, 6, 218, 168, 13, 28, 232, 115, 6, 215, 61, 13, 28, 232, - 115, 6, 74, 13, 28, 232, 115, 6, 210, 236, 13, 28, 232, 115, 6, 208, 104, - 13, 28, 232, 115, 6, 146, 13, 28, 232, 115, 6, 206, 8, 13, 28, 232, 115, - 6, 200, 43, 13, 28, 232, 115, 6, 66, 13, 28, 232, 115, 6, 196, 12, 13, - 28, 232, 115, 6, 193, 224, 13, 28, 232, 115, 6, 192, 235, 13, 28, 232, - 115, 6, 192, 159, 13, 28, 232, 115, 6, 191, 166, 13, 28, 232, 115, 2, 65, - 13, 28, 232, 115, 2, 250, 120, 13, 28, 232, 115, 2, 247, 193, 13, 28, - 232, 115, 2, 238, 127, 13, 28, 232, 115, 2, 71, 13, 28, 232, 115, 2, 233, - 175, 13, 28, 232, 115, 2, 232, 51, 13, 28, 232, 115, 2, 230, 116, 13, 28, - 232, 115, 2, 68, 13, 28, 232, 115, 2, 223, 35, 13, 28, 232, 115, 2, 222, - 152, 13, 28, 232, 115, 2, 172, 13, 28, 232, 115, 2, 218, 168, 13, 28, - 232, 115, 2, 215, 61, 13, 28, 232, 115, 2, 74, 13, 28, 232, 115, 2, 210, - 236, 13, 28, 232, 115, 2, 208, 104, 13, 28, 232, 115, 2, 146, 13, 28, - 232, 115, 2, 206, 8, 13, 28, 232, 115, 2, 200, 43, 13, 28, 232, 115, 2, - 66, 13, 28, 232, 115, 2, 196, 12, 13, 28, 232, 115, 2, 193, 224, 13, 28, - 232, 115, 2, 192, 235, 13, 28, 232, 115, 2, 192, 159, 13, 28, 232, 115, - 2, 191, 166, 13, 49, 6, 65, 13, 49, 6, 250, 120, 13, 49, 6, 247, 193, 13, - 49, 6, 238, 127, 13, 49, 6, 71, 13, 49, 6, 233, 175, 13, 49, 6, 232, 51, - 13, 49, 6, 230, 116, 13, 49, 6, 68, 13, 49, 6, 223, 35, 13, 49, 6, 222, - 152, 13, 49, 6, 172, 13, 49, 6, 218, 168, 13, 49, 6, 215, 61, 13, 49, 6, - 74, 13, 49, 6, 210, 236, 13, 49, 6, 208, 104, 13, 49, 6, 146, 13, 49, 6, - 206, 8, 13, 49, 6, 200, 43, 13, 49, 6, 66, 13, 49, 6, 196, 12, 13, 49, 6, + 166, 13, 232, 117, 6, 65, 13, 232, 117, 6, 250, 122, 13, 232, 117, 6, + 238, 129, 13, 232, 117, 6, 71, 13, 232, 117, 6, 233, 177, 13, 232, 117, + 6, 232, 53, 13, 232, 117, 6, 223, 37, 13, 232, 117, 6, 222, 154, 13, 232, + 117, 6, 172, 13, 232, 117, 6, 218, 170, 13, 232, 117, 6, 215, 63, 13, + 232, 117, 6, 74, 13, 232, 117, 6, 210, 238, 13, 232, 117, 6, 208, 106, + 13, 232, 117, 6, 206, 9, 13, 232, 117, 6, 200, 43, 13, 232, 117, 6, 66, + 13, 232, 117, 6, 196, 12, 13, 232, 117, 6, 193, 224, 13, 232, 117, 6, + 192, 235, 13, 232, 117, 6, 192, 159, 13, 232, 117, 2, 65, 13, 232, 117, + 2, 250, 122, 13, 232, 117, 2, 247, 195, 13, 232, 117, 2, 238, 129, 13, + 232, 117, 2, 71, 13, 232, 117, 2, 233, 177, 13, 232, 117, 2, 232, 53, 13, + 232, 117, 2, 230, 118, 13, 232, 117, 2, 68, 13, 232, 117, 2, 223, 37, 13, + 232, 117, 2, 222, 154, 13, 232, 117, 2, 172, 13, 232, 117, 2, 218, 170, + 13, 232, 117, 2, 215, 63, 13, 232, 117, 2, 74, 13, 232, 117, 2, 210, 238, + 13, 232, 117, 2, 208, 106, 13, 232, 117, 2, 146, 13, 232, 117, 2, 206, 9, + 13, 232, 117, 2, 200, 43, 13, 232, 117, 2, 66, 13, 232, 117, 2, 196, 12, + 13, 232, 117, 2, 193, 224, 13, 232, 117, 2, 192, 235, 13, 232, 117, 2, + 192, 159, 13, 232, 117, 2, 191, 166, 13, 235, 131, 6, 65, 13, 235, 131, + 6, 250, 122, 13, 235, 131, 6, 238, 129, 13, 235, 131, 6, 71, 13, 235, + 131, 6, 233, 177, 13, 235, 131, 6, 232, 53, 13, 235, 131, 6, 68, 13, 235, + 131, 6, 223, 37, 13, 235, 131, 6, 222, 154, 13, 235, 131, 6, 172, 13, + 235, 131, 6, 218, 170, 13, 235, 131, 6, 74, 13, 235, 131, 6, 206, 9, 13, + 235, 131, 6, 200, 43, 13, 235, 131, 6, 66, 13, 235, 131, 6, 196, 12, 13, + 235, 131, 6, 193, 224, 13, 235, 131, 6, 192, 235, 13, 235, 131, 6, 192, + 159, 13, 235, 131, 2, 65, 13, 235, 131, 2, 250, 122, 13, 235, 131, 2, + 247, 195, 13, 235, 131, 2, 238, 129, 13, 235, 131, 2, 71, 13, 235, 131, + 2, 233, 177, 13, 235, 131, 2, 232, 53, 13, 235, 131, 2, 230, 118, 13, + 235, 131, 2, 68, 13, 235, 131, 2, 223, 37, 13, 235, 131, 2, 222, 154, 13, + 235, 131, 2, 172, 13, 235, 131, 2, 218, 170, 13, 235, 131, 2, 215, 63, + 13, 235, 131, 2, 74, 13, 235, 131, 2, 210, 238, 13, 235, 131, 2, 208, + 106, 13, 235, 131, 2, 146, 13, 235, 131, 2, 206, 9, 13, 235, 131, 2, 200, + 43, 13, 235, 131, 2, 66, 13, 235, 131, 2, 196, 12, 13, 235, 131, 2, 193, + 224, 13, 235, 131, 2, 192, 235, 13, 235, 131, 2, 192, 159, 13, 235, 131, + 2, 191, 166, 13, 28, 232, 117, 6, 65, 13, 28, 232, 117, 6, 250, 122, 13, + 28, 232, 117, 6, 247, 195, 13, 28, 232, 117, 6, 238, 129, 13, 28, 232, + 117, 6, 71, 13, 28, 232, 117, 6, 233, 177, 13, 28, 232, 117, 6, 232, 53, + 13, 28, 232, 117, 6, 230, 118, 13, 28, 232, 117, 6, 68, 13, 28, 232, 117, + 6, 223, 37, 13, 28, 232, 117, 6, 222, 154, 13, 28, 232, 117, 6, 172, 13, + 28, 232, 117, 6, 218, 170, 13, 28, 232, 117, 6, 215, 63, 13, 28, 232, + 117, 6, 74, 13, 28, 232, 117, 6, 210, 238, 13, 28, 232, 117, 6, 208, 106, + 13, 28, 232, 117, 6, 146, 13, 28, 232, 117, 6, 206, 9, 13, 28, 232, 117, + 6, 200, 43, 13, 28, 232, 117, 6, 66, 13, 28, 232, 117, 6, 196, 12, 13, + 28, 232, 117, 6, 193, 224, 13, 28, 232, 117, 6, 192, 235, 13, 28, 232, + 117, 6, 192, 159, 13, 28, 232, 117, 6, 191, 166, 13, 28, 232, 117, 2, 65, + 13, 28, 232, 117, 2, 250, 122, 13, 28, 232, 117, 2, 247, 195, 13, 28, + 232, 117, 2, 238, 129, 13, 28, 232, 117, 2, 71, 13, 28, 232, 117, 2, 233, + 177, 13, 28, 232, 117, 2, 232, 53, 13, 28, 232, 117, 2, 230, 118, 13, 28, + 232, 117, 2, 68, 13, 28, 232, 117, 2, 223, 37, 13, 28, 232, 117, 2, 222, + 154, 13, 28, 232, 117, 2, 172, 13, 28, 232, 117, 2, 218, 170, 13, 28, + 232, 117, 2, 215, 63, 13, 28, 232, 117, 2, 74, 13, 28, 232, 117, 2, 210, + 238, 13, 28, 232, 117, 2, 208, 106, 13, 28, 232, 117, 2, 146, 13, 28, + 232, 117, 2, 206, 9, 13, 28, 232, 117, 2, 200, 43, 13, 28, 232, 117, 2, + 66, 13, 28, 232, 117, 2, 196, 12, 13, 28, 232, 117, 2, 193, 224, 13, 28, + 232, 117, 2, 192, 235, 13, 28, 232, 117, 2, 192, 159, 13, 28, 232, 117, + 2, 191, 166, 13, 49, 6, 65, 13, 49, 6, 250, 122, 13, 49, 6, 247, 195, 13, + 49, 6, 238, 129, 13, 49, 6, 71, 13, 49, 6, 233, 177, 13, 49, 6, 232, 53, + 13, 49, 6, 230, 118, 13, 49, 6, 68, 13, 49, 6, 223, 37, 13, 49, 6, 222, + 154, 13, 49, 6, 172, 13, 49, 6, 218, 170, 13, 49, 6, 215, 63, 13, 49, 6, + 74, 13, 49, 6, 210, 238, 13, 49, 6, 208, 106, 13, 49, 6, 146, 13, 49, 6, + 206, 9, 13, 49, 6, 200, 43, 13, 49, 6, 66, 13, 49, 6, 196, 12, 13, 49, 6, 193, 224, 13, 49, 6, 192, 235, 13, 49, 6, 192, 159, 13, 49, 6, 191, 166, - 13, 49, 2, 65, 13, 49, 2, 250, 120, 13, 49, 2, 247, 193, 13, 49, 2, 238, - 127, 13, 49, 2, 71, 13, 49, 2, 233, 175, 13, 49, 2, 232, 51, 13, 49, 2, - 230, 116, 13, 49, 2, 68, 13, 49, 2, 223, 35, 13, 49, 2, 222, 152, 13, 49, - 2, 172, 13, 49, 2, 218, 168, 13, 49, 2, 215, 61, 13, 49, 2, 74, 13, 49, - 2, 210, 236, 13, 49, 2, 208, 104, 13, 49, 2, 146, 13, 49, 2, 206, 8, 13, + 13, 49, 2, 65, 13, 49, 2, 250, 122, 13, 49, 2, 247, 195, 13, 49, 2, 238, + 129, 13, 49, 2, 71, 13, 49, 2, 233, 177, 13, 49, 2, 232, 53, 13, 49, 2, + 230, 118, 13, 49, 2, 68, 13, 49, 2, 223, 37, 13, 49, 2, 222, 154, 13, 49, + 2, 172, 13, 49, 2, 218, 170, 13, 49, 2, 215, 63, 13, 49, 2, 74, 13, 49, + 2, 210, 238, 13, 49, 2, 208, 106, 13, 49, 2, 146, 13, 49, 2, 206, 9, 13, 49, 2, 200, 43, 13, 49, 2, 66, 13, 49, 2, 196, 12, 13, 49, 2, 193, 224, 13, 49, 2, 192, 235, 13, 49, 2, 192, 159, 13, 49, 2, 191, 166, 13, 49, - 28, 6, 65, 13, 49, 28, 6, 250, 120, 13, 49, 28, 6, 247, 193, 13, 49, 28, - 6, 238, 127, 13, 49, 28, 6, 71, 13, 49, 28, 6, 233, 175, 13, 49, 28, 6, - 232, 51, 13, 49, 28, 6, 230, 116, 13, 49, 28, 6, 68, 13, 49, 28, 6, 223, - 35, 13, 49, 28, 6, 222, 152, 13, 49, 28, 6, 172, 13, 49, 28, 6, 218, 168, - 13, 49, 28, 6, 215, 61, 13, 49, 28, 6, 74, 13, 49, 28, 6, 210, 236, 13, - 49, 28, 6, 208, 104, 13, 49, 28, 6, 146, 13, 49, 28, 6, 206, 8, 13, 49, + 28, 6, 65, 13, 49, 28, 6, 250, 122, 13, 49, 28, 6, 247, 195, 13, 49, 28, + 6, 238, 129, 13, 49, 28, 6, 71, 13, 49, 28, 6, 233, 177, 13, 49, 28, 6, + 232, 53, 13, 49, 28, 6, 230, 118, 13, 49, 28, 6, 68, 13, 49, 28, 6, 223, + 37, 13, 49, 28, 6, 222, 154, 13, 49, 28, 6, 172, 13, 49, 28, 6, 218, 170, + 13, 49, 28, 6, 215, 63, 13, 49, 28, 6, 74, 13, 49, 28, 6, 210, 238, 13, + 49, 28, 6, 208, 106, 13, 49, 28, 6, 146, 13, 49, 28, 6, 206, 9, 13, 49, 28, 6, 200, 43, 13, 49, 28, 6, 66, 13, 49, 28, 6, 196, 12, 13, 49, 28, 6, 193, 224, 13, 49, 28, 6, 192, 235, 13, 49, 28, 6, 192, 159, 13, 49, 28, - 6, 191, 166, 13, 49, 28, 2, 65, 13, 49, 28, 2, 250, 120, 13, 49, 28, 2, - 247, 193, 13, 49, 28, 2, 238, 127, 13, 49, 28, 2, 71, 13, 49, 28, 2, 233, - 175, 13, 49, 28, 2, 232, 51, 13, 49, 28, 2, 230, 116, 13, 49, 28, 2, 68, - 13, 49, 28, 2, 223, 35, 13, 49, 28, 2, 222, 152, 13, 49, 28, 2, 172, 13, - 49, 28, 2, 218, 168, 13, 49, 28, 2, 215, 61, 13, 49, 28, 2, 74, 13, 49, - 28, 2, 210, 236, 13, 49, 28, 2, 208, 104, 13, 49, 28, 2, 146, 13, 49, 28, - 2, 206, 8, 13, 49, 28, 2, 200, 43, 13, 49, 28, 2, 66, 13, 49, 28, 2, 196, + 6, 191, 166, 13, 49, 28, 2, 65, 13, 49, 28, 2, 250, 122, 13, 49, 28, 2, + 247, 195, 13, 49, 28, 2, 238, 129, 13, 49, 28, 2, 71, 13, 49, 28, 2, 233, + 177, 13, 49, 28, 2, 232, 53, 13, 49, 28, 2, 230, 118, 13, 49, 28, 2, 68, + 13, 49, 28, 2, 223, 37, 13, 49, 28, 2, 222, 154, 13, 49, 28, 2, 172, 13, + 49, 28, 2, 218, 170, 13, 49, 28, 2, 215, 63, 13, 49, 28, 2, 74, 13, 49, + 28, 2, 210, 238, 13, 49, 28, 2, 208, 106, 13, 49, 28, 2, 146, 13, 49, 28, + 2, 206, 9, 13, 49, 28, 2, 200, 43, 13, 49, 28, 2, 66, 13, 49, 28, 2, 196, 12, 13, 49, 28, 2, 193, 224, 13, 49, 28, 2, 192, 235, 13, 49, 28, 2, 192, - 159, 13, 49, 28, 2, 191, 166, 13, 49, 43, 6, 65, 13, 49, 43, 6, 250, 120, - 13, 49, 43, 6, 247, 193, 13, 49, 43, 6, 238, 127, 13, 49, 43, 6, 71, 13, - 49, 43, 6, 233, 175, 13, 49, 43, 6, 232, 51, 13, 49, 43, 6, 230, 116, 13, - 49, 43, 6, 68, 13, 49, 43, 6, 223, 35, 13, 49, 43, 6, 222, 152, 13, 49, - 43, 6, 172, 13, 49, 43, 6, 218, 168, 13, 49, 43, 6, 215, 61, 13, 49, 43, - 6, 74, 13, 49, 43, 6, 210, 236, 13, 49, 43, 6, 208, 104, 13, 49, 43, 6, - 146, 13, 49, 43, 6, 206, 8, 13, 49, 43, 6, 200, 43, 13, 49, 43, 6, 66, + 159, 13, 49, 28, 2, 191, 166, 13, 49, 43, 6, 65, 13, 49, 43, 6, 250, 122, + 13, 49, 43, 6, 247, 195, 13, 49, 43, 6, 238, 129, 13, 49, 43, 6, 71, 13, + 49, 43, 6, 233, 177, 13, 49, 43, 6, 232, 53, 13, 49, 43, 6, 230, 118, 13, + 49, 43, 6, 68, 13, 49, 43, 6, 223, 37, 13, 49, 43, 6, 222, 154, 13, 49, + 43, 6, 172, 13, 49, 43, 6, 218, 170, 13, 49, 43, 6, 215, 63, 13, 49, 43, + 6, 74, 13, 49, 43, 6, 210, 238, 13, 49, 43, 6, 208, 106, 13, 49, 43, 6, + 146, 13, 49, 43, 6, 206, 9, 13, 49, 43, 6, 200, 43, 13, 49, 43, 6, 66, 13, 49, 43, 6, 196, 12, 13, 49, 43, 6, 193, 224, 13, 49, 43, 6, 192, 235, 13, 49, 43, 6, 192, 159, 13, 49, 43, 6, 191, 166, 13, 49, 43, 2, 65, 13, - 49, 43, 2, 250, 120, 13, 49, 43, 2, 247, 193, 13, 49, 43, 2, 238, 127, - 13, 49, 43, 2, 71, 13, 49, 43, 2, 233, 175, 13, 49, 43, 2, 232, 51, 13, - 49, 43, 2, 230, 116, 13, 49, 43, 2, 68, 13, 49, 43, 2, 223, 35, 13, 49, - 43, 2, 222, 152, 13, 49, 43, 2, 172, 13, 49, 43, 2, 218, 168, 13, 49, 43, - 2, 215, 61, 13, 49, 43, 2, 74, 13, 49, 43, 2, 210, 236, 13, 49, 43, 2, - 208, 104, 13, 49, 43, 2, 146, 13, 49, 43, 2, 206, 8, 13, 49, 43, 2, 200, + 49, 43, 2, 250, 122, 13, 49, 43, 2, 247, 195, 13, 49, 43, 2, 238, 129, + 13, 49, 43, 2, 71, 13, 49, 43, 2, 233, 177, 13, 49, 43, 2, 232, 53, 13, + 49, 43, 2, 230, 118, 13, 49, 43, 2, 68, 13, 49, 43, 2, 223, 37, 13, 49, + 43, 2, 222, 154, 13, 49, 43, 2, 172, 13, 49, 43, 2, 218, 170, 13, 49, 43, + 2, 215, 63, 13, 49, 43, 2, 74, 13, 49, 43, 2, 210, 238, 13, 49, 43, 2, + 208, 106, 13, 49, 43, 2, 146, 13, 49, 43, 2, 206, 9, 13, 49, 43, 2, 200, 43, 13, 49, 43, 2, 66, 13, 49, 43, 2, 196, 12, 13, 49, 43, 2, 193, 224, 13, 49, 43, 2, 192, 235, 13, 49, 43, 2, 192, 159, 13, 49, 43, 2, 191, - 166, 13, 49, 28, 43, 6, 65, 13, 49, 28, 43, 6, 250, 120, 13, 49, 28, 43, - 6, 247, 193, 13, 49, 28, 43, 6, 238, 127, 13, 49, 28, 43, 6, 71, 13, 49, - 28, 43, 6, 233, 175, 13, 49, 28, 43, 6, 232, 51, 13, 49, 28, 43, 6, 230, - 116, 13, 49, 28, 43, 6, 68, 13, 49, 28, 43, 6, 223, 35, 13, 49, 28, 43, - 6, 222, 152, 13, 49, 28, 43, 6, 172, 13, 49, 28, 43, 6, 218, 168, 13, 49, - 28, 43, 6, 215, 61, 13, 49, 28, 43, 6, 74, 13, 49, 28, 43, 6, 210, 236, - 13, 49, 28, 43, 6, 208, 104, 13, 49, 28, 43, 6, 146, 13, 49, 28, 43, 6, - 206, 8, 13, 49, 28, 43, 6, 200, 43, 13, 49, 28, 43, 6, 66, 13, 49, 28, + 166, 13, 49, 28, 43, 6, 65, 13, 49, 28, 43, 6, 250, 122, 13, 49, 28, 43, + 6, 247, 195, 13, 49, 28, 43, 6, 238, 129, 13, 49, 28, 43, 6, 71, 13, 49, + 28, 43, 6, 233, 177, 13, 49, 28, 43, 6, 232, 53, 13, 49, 28, 43, 6, 230, + 118, 13, 49, 28, 43, 6, 68, 13, 49, 28, 43, 6, 223, 37, 13, 49, 28, 43, + 6, 222, 154, 13, 49, 28, 43, 6, 172, 13, 49, 28, 43, 6, 218, 170, 13, 49, + 28, 43, 6, 215, 63, 13, 49, 28, 43, 6, 74, 13, 49, 28, 43, 6, 210, 238, + 13, 49, 28, 43, 6, 208, 106, 13, 49, 28, 43, 6, 146, 13, 49, 28, 43, 6, + 206, 9, 13, 49, 28, 43, 6, 200, 43, 13, 49, 28, 43, 6, 66, 13, 49, 28, 43, 6, 196, 12, 13, 49, 28, 43, 6, 193, 224, 13, 49, 28, 43, 6, 192, 235, 13, 49, 28, 43, 6, 192, 159, 13, 49, 28, 43, 6, 191, 166, 13, 49, 28, 43, - 2, 65, 13, 49, 28, 43, 2, 250, 120, 13, 49, 28, 43, 2, 247, 193, 13, 49, - 28, 43, 2, 238, 127, 13, 49, 28, 43, 2, 71, 13, 49, 28, 43, 2, 233, 175, - 13, 49, 28, 43, 2, 232, 51, 13, 49, 28, 43, 2, 230, 116, 13, 49, 28, 43, - 2, 68, 13, 49, 28, 43, 2, 223, 35, 13, 49, 28, 43, 2, 222, 152, 13, 49, - 28, 43, 2, 172, 13, 49, 28, 43, 2, 218, 168, 13, 49, 28, 43, 2, 215, 61, - 13, 49, 28, 43, 2, 74, 13, 49, 28, 43, 2, 210, 236, 13, 49, 28, 43, 2, - 208, 104, 13, 49, 28, 43, 2, 146, 13, 49, 28, 43, 2, 206, 8, 13, 49, 28, + 2, 65, 13, 49, 28, 43, 2, 250, 122, 13, 49, 28, 43, 2, 247, 195, 13, 49, + 28, 43, 2, 238, 129, 13, 49, 28, 43, 2, 71, 13, 49, 28, 43, 2, 233, 177, + 13, 49, 28, 43, 2, 232, 53, 13, 49, 28, 43, 2, 230, 118, 13, 49, 28, 43, + 2, 68, 13, 49, 28, 43, 2, 223, 37, 13, 49, 28, 43, 2, 222, 154, 13, 49, + 28, 43, 2, 172, 13, 49, 28, 43, 2, 218, 170, 13, 49, 28, 43, 2, 215, 63, + 13, 49, 28, 43, 2, 74, 13, 49, 28, 43, 2, 210, 238, 13, 49, 28, 43, 2, + 208, 106, 13, 49, 28, 43, 2, 146, 13, 49, 28, 43, 2, 206, 9, 13, 49, 28, 43, 2, 200, 43, 13, 49, 28, 43, 2, 66, 13, 49, 28, 43, 2, 196, 12, 13, 49, 28, 43, 2, 193, 224, 13, 49, 28, 43, 2, 192, 235, 13, 49, 28, 43, 2, - 192, 159, 13, 49, 28, 43, 2, 191, 166, 13, 215, 217, 6, 65, 13, 215, 217, - 6, 250, 120, 13, 215, 217, 6, 247, 193, 13, 215, 217, 6, 238, 127, 13, - 215, 217, 6, 71, 13, 215, 217, 6, 233, 175, 13, 215, 217, 6, 232, 51, 13, - 215, 217, 6, 230, 116, 13, 215, 217, 6, 68, 13, 215, 217, 6, 223, 35, 13, - 215, 217, 6, 222, 152, 13, 215, 217, 6, 172, 13, 215, 217, 6, 218, 168, - 13, 215, 217, 6, 215, 61, 13, 215, 217, 6, 74, 13, 215, 217, 6, 210, 236, - 13, 215, 217, 6, 208, 104, 13, 215, 217, 6, 146, 13, 215, 217, 6, 206, 8, - 13, 215, 217, 6, 200, 43, 13, 215, 217, 6, 66, 13, 215, 217, 6, 196, 12, - 13, 215, 217, 6, 193, 224, 13, 215, 217, 6, 192, 235, 13, 215, 217, 6, - 192, 159, 13, 215, 217, 6, 191, 166, 13, 215, 217, 2, 65, 13, 215, 217, - 2, 250, 120, 13, 215, 217, 2, 247, 193, 13, 215, 217, 2, 238, 127, 13, - 215, 217, 2, 71, 13, 215, 217, 2, 233, 175, 13, 215, 217, 2, 232, 51, 13, - 215, 217, 2, 230, 116, 13, 215, 217, 2, 68, 13, 215, 217, 2, 223, 35, 13, - 215, 217, 2, 222, 152, 13, 215, 217, 2, 172, 13, 215, 217, 2, 218, 168, - 13, 215, 217, 2, 215, 61, 13, 215, 217, 2, 74, 13, 215, 217, 2, 210, 236, - 13, 215, 217, 2, 208, 104, 13, 215, 217, 2, 146, 13, 215, 217, 2, 206, 8, - 13, 215, 217, 2, 200, 43, 13, 215, 217, 2, 66, 13, 215, 217, 2, 196, 12, - 13, 215, 217, 2, 193, 224, 13, 215, 217, 2, 192, 235, 13, 215, 217, 2, - 192, 159, 13, 215, 217, 2, 191, 166, 13, 43, 2, 236, 139, 68, 13, 43, 2, - 236, 139, 223, 35, 13, 28, 6, 251, 160, 13, 28, 6, 248, 212, 13, 28, 6, - 231, 211, 13, 28, 6, 237, 106, 13, 28, 6, 234, 47, 13, 28, 6, 191, 76, - 13, 28, 6, 233, 253, 13, 28, 6, 199, 15, 13, 28, 6, 223, 83, 13, 28, 6, - 222, 72, 13, 28, 6, 220, 31, 13, 28, 6, 215, 155, 13, 28, 6, 212, 178, - 13, 28, 6, 192, 207, 13, 28, 6, 211, 107, 13, 28, 6, 209, 185, 13, 28, 6, - 207, 3, 13, 28, 6, 199, 16, 113, 13, 28, 6, 202, 196, 13, 28, 6, 199, - 166, 13, 28, 6, 196, 70, 13, 28, 6, 209, 211, 13, 28, 6, 243, 95, 13, 28, - 6, 208, 176, 13, 28, 6, 211, 110, 13, 28, 214, 245, 13, 28, 2, 251, 160, - 13, 28, 2, 248, 212, 13, 28, 2, 231, 211, 13, 28, 2, 237, 106, 13, 28, 2, - 234, 47, 13, 28, 2, 191, 76, 13, 28, 2, 233, 253, 13, 28, 2, 199, 15, 13, - 28, 2, 223, 83, 13, 28, 2, 222, 72, 13, 28, 2, 220, 31, 13, 28, 2, 215, - 155, 13, 28, 2, 212, 178, 13, 28, 2, 192, 207, 13, 28, 2, 211, 107, 13, - 28, 2, 209, 185, 13, 28, 2, 207, 3, 13, 28, 2, 53, 202, 196, 13, 28, 2, - 202, 196, 13, 28, 2, 199, 166, 13, 28, 2, 196, 70, 13, 28, 2, 209, 211, - 13, 28, 2, 243, 95, 13, 28, 2, 208, 176, 13, 28, 2, 211, 110, 13, 28, - 210, 105, 237, 16, 13, 28, 234, 48, 113, 13, 28, 199, 16, 113, 13, 28, - 222, 73, 113, 13, 28, 209, 212, 113, 13, 28, 207, 4, 113, 13, 28, 209, - 186, 113, 13, 43, 6, 251, 160, 13, 43, 6, 248, 212, 13, 43, 6, 231, 211, - 13, 43, 6, 237, 106, 13, 43, 6, 234, 47, 13, 43, 6, 191, 76, 13, 43, 6, - 233, 253, 13, 43, 6, 199, 15, 13, 43, 6, 223, 83, 13, 43, 6, 222, 72, 13, - 43, 6, 220, 31, 13, 43, 6, 215, 155, 13, 43, 6, 212, 178, 13, 43, 6, 192, - 207, 13, 43, 6, 211, 107, 13, 43, 6, 209, 185, 13, 43, 6, 207, 3, 13, 43, - 6, 199, 16, 113, 13, 43, 6, 202, 196, 13, 43, 6, 199, 166, 13, 43, 6, - 196, 70, 13, 43, 6, 209, 211, 13, 43, 6, 243, 95, 13, 43, 6, 208, 176, - 13, 43, 6, 211, 110, 13, 43, 214, 245, 13, 43, 2, 251, 160, 13, 43, 2, - 248, 212, 13, 43, 2, 231, 211, 13, 43, 2, 237, 106, 13, 43, 2, 234, 47, - 13, 43, 2, 191, 76, 13, 43, 2, 233, 253, 13, 43, 2, 199, 15, 13, 43, 2, - 223, 83, 13, 43, 2, 222, 72, 13, 43, 2, 220, 31, 13, 43, 2, 215, 155, 13, - 43, 2, 212, 178, 13, 43, 2, 192, 207, 13, 43, 2, 211, 107, 13, 43, 2, - 209, 185, 13, 43, 2, 207, 3, 13, 43, 2, 53, 202, 196, 13, 43, 2, 202, - 196, 13, 43, 2, 199, 166, 13, 43, 2, 196, 70, 13, 43, 2, 209, 211, 13, - 43, 2, 243, 95, 13, 43, 2, 208, 176, 13, 43, 2, 211, 110, 13, 43, 210, - 105, 237, 16, 13, 43, 234, 48, 113, 13, 43, 199, 16, 113, 13, 43, 222, - 73, 113, 13, 43, 209, 212, 113, 13, 43, 207, 4, 113, 13, 43, 209, 186, - 113, 13, 28, 43, 6, 251, 160, 13, 28, 43, 6, 248, 212, 13, 28, 43, 6, - 231, 211, 13, 28, 43, 6, 237, 106, 13, 28, 43, 6, 234, 47, 13, 28, 43, 6, - 191, 76, 13, 28, 43, 6, 233, 253, 13, 28, 43, 6, 199, 15, 13, 28, 43, 6, - 223, 83, 13, 28, 43, 6, 222, 72, 13, 28, 43, 6, 220, 31, 13, 28, 43, 6, - 215, 155, 13, 28, 43, 6, 212, 178, 13, 28, 43, 6, 192, 207, 13, 28, 43, - 6, 211, 107, 13, 28, 43, 6, 209, 185, 13, 28, 43, 6, 207, 3, 13, 28, 43, - 6, 199, 16, 113, 13, 28, 43, 6, 202, 196, 13, 28, 43, 6, 199, 166, 13, - 28, 43, 6, 196, 70, 13, 28, 43, 6, 209, 211, 13, 28, 43, 6, 243, 95, 13, - 28, 43, 6, 208, 176, 13, 28, 43, 6, 211, 110, 13, 28, 43, 214, 245, 13, - 28, 43, 2, 251, 160, 13, 28, 43, 2, 248, 212, 13, 28, 43, 2, 231, 211, - 13, 28, 43, 2, 237, 106, 13, 28, 43, 2, 234, 47, 13, 28, 43, 2, 191, 76, - 13, 28, 43, 2, 233, 253, 13, 28, 43, 2, 199, 15, 13, 28, 43, 2, 223, 83, - 13, 28, 43, 2, 222, 72, 13, 28, 43, 2, 220, 31, 13, 28, 43, 2, 215, 155, - 13, 28, 43, 2, 212, 178, 13, 28, 43, 2, 192, 207, 13, 28, 43, 2, 211, - 107, 13, 28, 43, 2, 209, 185, 13, 28, 43, 2, 207, 3, 13, 28, 43, 2, 53, - 202, 196, 13, 28, 43, 2, 202, 196, 13, 28, 43, 2, 199, 166, 13, 28, 43, - 2, 196, 70, 13, 28, 43, 2, 209, 211, 13, 28, 43, 2, 243, 95, 13, 28, 43, - 2, 208, 176, 13, 28, 43, 2, 211, 110, 13, 28, 43, 210, 105, 237, 16, 13, - 28, 43, 234, 48, 113, 13, 28, 43, 199, 16, 113, 13, 28, 43, 222, 73, 113, - 13, 28, 43, 209, 212, 113, 13, 28, 43, 207, 4, 113, 13, 28, 43, 209, 186, - 113, 13, 49, 28, 6, 251, 160, 13, 49, 28, 6, 248, 212, 13, 49, 28, 6, - 231, 211, 13, 49, 28, 6, 237, 106, 13, 49, 28, 6, 234, 47, 13, 49, 28, 6, - 191, 76, 13, 49, 28, 6, 233, 253, 13, 49, 28, 6, 199, 15, 13, 49, 28, 6, - 223, 83, 13, 49, 28, 6, 222, 72, 13, 49, 28, 6, 220, 31, 13, 49, 28, 6, - 215, 155, 13, 49, 28, 6, 212, 178, 13, 49, 28, 6, 192, 207, 13, 49, 28, - 6, 211, 107, 13, 49, 28, 6, 209, 185, 13, 49, 28, 6, 207, 3, 13, 49, 28, - 6, 199, 16, 113, 13, 49, 28, 6, 202, 196, 13, 49, 28, 6, 199, 166, 13, - 49, 28, 6, 196, 70, 13, 49, 28, 6, 209, 211, 13, 49, 28, 6, 243, 95, 13, - 49, 28, 6, 208, 176, 13, 49, 28, 6, 211, 110, 13, 49, 28, 214, 245, 13, - 49, 28, 2, 251, 160, 13, 49, 28, 2, 248, 212, 13, 49, 28, 2, 231, 211, - 13, 49, 28, 2, 237, 106, 13, 49, 28, 2, 234, 47, 13, 49, 28, 2, 191, 76, - 13, 49, 28, 2, 233, 253, 13, 49, 28, 2, 199, 15, 13, 49, 28, 2, 223, 83, - 13, 49, 28, 2, 222, 72, 13, 49, 28, 2, 220, 31, 13, 49, 28, 2, 215, 155, - 13, 49, 28, 2, 212, 178, 13, 49, 28, 2, 192, 207, 13, 49, 28, 2, 211, - 107, 13, 49, 28, 2, 209, 185, 13, 49, 28, 2, 207, 3, 13, 49, 28, 2, 53, - 202, 196, 13, 49, 28, 2, 202, 196, 13, 49, 28, 2, 199, 166, 13, 49, 28, - 2, 196, 70, 13, 49, 28, 2, 209, 211, 13, 49, 28, 2, 243, 95, 13, 49, 28, - 2, 208, 176, 13, 49, 28, 2, 211, 110, 13, 49, 28, 210, 105, 237, 16, 13, - 49, 28, 234, 48, 113, 13, 49, 28, 199, 16, 113, 13, 49, 28, 222, 73, 113, - 13, 49, 28, 209, 212, 113, 13, 49, 28, 207, 4, 113, 13, 49, 28, 209, 186, - 113, 13, 49, 28, 43, 6, 251, 160, 13, 49, 28, 43, 6, 248, 212, 13, 49, - 28, 43, 6, 231, 211, 13, 49, 28, 43, 6, 237, 106, 13, 49, 28, 43, 6, 234, - 47, 13, 49, 28, 43, 6, 191, 76, 13, 49, 28, 43, 6, 233, 253, 13, 49, 28, - 43, 6, 199, 15, 13, 49, 28, 43, 6, 223, 83, 13, 49, 28, 43, 6, 222, 72, - 13, 49, 28, 43, 6, 220, 31, 13, 49, 28, 43, 6, 215, 155, 13, 49, 28, 43, - 6, 212, 178, 13, 49, 28, 43, 6, 192, 207, 13, 49, 28, 43, 6, 211, 107, - 13, 49, 28, 43, 6, 209, 185, 13, 49, 28, 43, 6, 207, 3, 13, 49, 28, 43, - 6, 199, 16, 113, 13, 49, 28, 43, 6, 202, 196, 13, 49, 28, 43, 6, 199, - 166, 13, 49, 28, 43, 6, 196, 70, 13, 49, 28, 43, 6, 209, 211, 13, 49, 28, - 43, 6, 243, 95, 13, 49, 28, 43, 6, 208, 176, 13, 49, 28, 43, 6, 211, 110, - 13, 49, 28, 43, 214, 245, 13, 49, 28, 43, 2, 251, 160, 13, 49, 28, 43, 2, - 248, 212, 13, 49, 28, 43, 2, 231, 211, 13, 49, 28, 43, 2, 237, 106, 13, - 49, 28, 43, 2, 234, 47, 13, 49, 28, 43, 2, 191, 76, 13, 49, 28, 43, 2, - 233, 253, 13, 49, 28, 43, 2, 199, 15, 13, 49, 28, 43, 2, 223, 83, 13, 49, - 28, 43, 2, 222, 72, 13, 49, 28, 43, 2, 220, 31, 13, 49, 28, 43, 2, 215, - 155, 13, 49, 28, 43, 2, 212, 178, 13, 49, 28, 43, 2, 192, 207, 13, 49, - 28, 43, 2, 211, 107, 13, 49, 28, 43, 2, 209, 185, 13, 49, 28, 43, 2, 207, - 3, 13, 49, 28, 43, 2, 53, 202, 196, 13, 49, 28, 43, 2, 202, 196, 13, 49, + 192, 159, 13, 49, 28, 43, 2, 191, 166, 13, 215, 219, 6, 65, 13, 215, 219, + 6, 250, 122, 13, 215, 219, 6, 247, 195, 13, 215, 219, 6, 238, 129, 13, + 215, 219, 6, 71, 13, 215, 219, 6, 233, 177, 13, 215, 219, 6, 232, 53, 13, + 215, 219, 6, 230, 118, 13, 215, 219, 6, 68, 13, 215, 219, 6, 223, 37, 13, + 215, 219, 6, 222, 154, 13, 215, 219, 6, 172, 13, 215, 219, 6, 218, 170, + 13, 215, 219, 6, 215, 63, 13, 215, 219, 6, 74, 13, 215, 219, 6, 210, 238, + 13, 215, 219, 6, 208, 106, 13, 215, 219, 6, 146, 13, 215, 219, 6, 206, 9, + 13, 215, 219, 6, 200, 43, 13, 215, 219, 6, 66, 13, 215, 219, 6, 196, 12, + 13, 215, 219, 6, 193, 224, 13, 215, 219, 6, 192, 235, 13, 215, 219, 6, + 192, 159, 13, 215, 219, 6, 191, 166, 13, 215, 219, 2, 65, 13, 215, 219, + 2, 250, 122, 13, 215, 219, 2, 247, 195, 13, 215, 219, 2, 238, 129, 13, + 215, 219, 2, 71, 13, 215, 219, 2, 233, 177, 13, 215, 219, 2, 232, 53, 13, + 215, 219, 2, 230, 118, 13, 215, 219, 2, 68, 13, 215, 219, 2, 223, 37, 13, + 215, 219, 2, 222, 154, 13, 215, 219, 2, 172, 13, 215, 219, 2, 218, 170, + 13, 215, 219, 2, 215, 63, 13, 215, 219, 2, 74, 13, 215, 219, 2, 210, 238, + 13, 215, 219, 2, 208, 106, 13, 215, 219, 2, 146, 13, 215, 219, 2, 206, 9, + 13, 215, 219, 2, 200, 43, 13, 215, 219, 2, 66, 13, 215, 219, 2, 196, 12, + 13, 215, 219, 2, 193, 224, 13, 215, 219, 2, 192, 235, 13, 215, 219, 2, + 192, 159, 13, 215, 219, 2, 191, 166, 13, 43, 2, 236, 141, 68, 13, 43, 2, + 236, 141, 223, 37, 13, 28, 6, 251, 162, 13, 28, 6, 248, 214, 13, 28, 6, + 231, 213, 13, 28, 6, 237, 108, 13, 28, 6, 234, 49, 13, 28, 6, 191, 76, + 13, 28, 6, 233, 255, 13, 28, 6, 199, 15, 13, 28, 6, 223, 85, 13, 28, 6, + 222, 74, 13, 28, 6, 220, 33, 13, 28, 6, 215, 157, 13, 28, 6, 212, 180, + 13, 28, 6, 192, 207, 13, 28, 6, 211, 109, 13, 28, 6, 209, 187, 13, 28, 6, + 207, 4, 13, 28, 6, 199, 16, 113, 13, 28, 6, 202, 197, 13, 28, 6, 199, + 166, 13, 28, 6, 196, 70, 13, 28, 6, 209, 213, 13, 28, 6, 243, 97, 13, 28, + 6, 208, 178, 13, 28, 6, 211, 112, 13, 28, 214, 247, 13, 28, 2, 251, 162, + 13, 28, 2, 248, 214, 13, 28, 2, 231, 213, 13, 28, 2, 237, 108, 13, 28, 2, + 234, 49, 13, 28, 2, 191, 76, 13, 28, 2, 233, 255, 13, 28, 2, 199, 15, 13, + 28, 2, 223, 85, 13, 28, 2, 222, 74, 13, 28, 2, 220, 33, 13, 28, 2, 215, + 157, 13, 28, 2, 212, 180, 13, 28, 2, 192, 207, 13, 28, 2, 211, 109, 13, + 28, 2, 209, 187, 13, 28, 2, 207, 4, 13, 28, 2, 53, 202, 197, 13, 28, 2, + 202, 197, 13, 28, 2, 199, 166, 13, 28, 2, 196, 70, 13, 28, 2, 209, 213, + 13, 28, 2, 243, 97, 13, 28, 2, 208, 178, 13, 28, 2, 211, 112, 13, 28, + 210, 107, 237, 18, 13, 28, 234, 50, 113, 13, 28, 199, 16, 113, 13, 28, + 222, 75, 113, 13, 28, 209, 214, 113, 13, 28, 207, 5, 113, 13, 28, 209, + 188, 113, 13, 43, 6, 251, 162, 13, 43, 6, 248, 214, 13, 43, 6, 231, 213, + 13, 43, 6, 237, 108, 13, 43, 6, 234, 49, 13, 43, 6, 191, 76, 13, 43, 6, + 233, 255, 13, 43, 6, 199, 15, 13, 43, 6, 223, 85, 13, 43, 6, 222, 74, 13, + 43, 6, 220, 33, 13, 43, 6, 215, 157, 13, 43, 6, 212, 180, 13, 43, 6, 192, + 207, 13, 43, 6, 211, 109, 13, 43, 6, 209, 187, 13, 43, 6, 207, 4, 13, 43, + 6, 199, 16, 113, 13, 43, 6, 202, 197, 13, 43, 6, 199, 166, 13, 43, 6, + 196, 70, 13, 43, 6, 209, 213, 13, 43, 6, 243, 97, 13, 43, 6, 208, 178, + 13, 43, 6, 211, 112, 13, 43, 214, 247, 13, 43, 2, 251, 162, 13, 43, 2, + 248, 214, 13, 43, 2, 231, 213, 13, 43, 2, 237, 108, 13, 43, 2, 234, 49, + 13, 43, 2, 191, 76, 13, 43, 2, 233, 255, 13, 43, 2, 199, 15, 13, 43, 2, + 223, 85, 13, 43, 2, 222, 74, 13, 43, 2, 220, 33, 13, 43, 2, 215, 157, 13, + 43, 2, 212, 180, 13, 43, 2, 192, 207, 13, 43, 2, 211, 109, 13, 43, 2, + 209, 187, 13, 43, 2, 207, 4, 13, 43, 2, 53, 202, 197, 13, 43, 2, 202, + 197, 13, 43, 2, 199, 166, 13, 43, 2, 196, 70, 13, 43, 2, 209, 213, 13, + 43, 2, 243, 97, 13, 43, 2, 208, 178, 13, 43, 2, 211, 112, 13, 43, 210, + 107, 237, 18, 13, 43, 234, 50, 113, 13, 43, 199, 16, 113, 13, 43, 222, + 75, 113, 13, 43, 209, 214, 113, 13, 43, 207, 5, 113, 13, 43, 209, 188, + 113, 13, 28, 43, 6, 251, 162, 13, 28, 43, 6, 248, 214, 13, 28, 43, 6, + 231, 213, 13, 28, 43, 6, 237, 108, 13, 28, 43, 6, 234, 49, 13, 28, 43, 6, + 191, 76, 13, 28, 43, 6, 233, 255, 13, 28, 43, 6, 199, 15, 13, 28, 43, 6, + 223, 85, 13, 28, 43, 6, 222, 74, 13, 28, 43, 6, 220, 33, 13, 28, 43, 6, + 215, 157, 13, 28, 43, 6, 212, 180, 13, 28, 43, 6, 192, 207, 13, 28, 43, + 6, 211, 109, 13, 28, 43, 6, 209, 187, 13, 28, 43, 6, 207, 4, 13, 28, 43, + 6, 199, 16, 113, 13, 28, 43, 6, 202, 197, 13, 28, 43, 6, 199, 166, 13, + 28, 43, 6, 196, 70, 13, 28, 43, 6, 209, 213, 13, 28, 43, 6, 243, 97, 13, + 28, 43, 6, 208, 178, 13, 28, 43, 6, 211, 112, 13, 28, 43, 214, 247, 13, + 28, 43, 2, 251, 162, 13, 28, 43, 2, 248, 214, 13, 28, 43, 2, 231, 213, + 13, 28, 43, 2, 237, 108, 13, 28, 43, 2, 234, 49, 13, 28, 43, 2, 191, 76, + 13, 28, 43, 2, 233, 255, 13, 28, 43, 2, 199, 15, 13, 28, 43, 2, 223, 85, + 13, 28, 43, 2, 222, 74, 13, 28, 43, 2, 220, 33, 13, 28, 43, 2, 215, 157, + 13, 28, 43, 2, 212, 180, 13, 28, 43, 2, 192, 207, 13, 28, 43, 2, 211, + 109, 13, 28, 43, 2, 209, 187, 13, 28, 43, 2, 207, 4, 13, 28, 43, 2, 53, + 202, 197, 13, 28, 43, 2, 202, 197, 13, 28, 43, 2, 199, 166, 13, 28, 43, + 2, 196, 70, 13, 28, 43, 2, 209, 213, 13, 28, 43, 2, 243, 97, 13, 28, 43, + 2, 208, 178, 13, 28, 43, 2, 211, 112, 13, 28, 43, 210, 107, 237, 18, 13, + 28, 43, 234, 50, 113, 13, 28, 43, 199, 16, 113, 13, 28, 43, 222, 75, 113, + 13, 28, 43, 209, 214, 113, 13, 28, 43, 207, 5, 113, 13, 28, 43, 209, 188, + 113, 13, 49, 28, 6, 251, 162, 13, 49, 28, 6, 248, 214, 13, 49, 28, 6, + 231, 213, 13, 49, 28, 6, 237, 108, 13, 49, 28, 6, 234, 49, 13, 49, 28, 6, + 191, 76, 13, 49, 28, 6, 233, 255, 13, 49, 28, 6, 199, 15, 13, 49, 28, 6, + 223, 85, 13, 49, 28, 6, 222, 74, 13, 49, 28, 6, 220, 33, 13, 49, 28, 6, + 215, 157, 13, 49, 28, 6, 212, 180, 13, 49, 28, 6, 192, 207, 13, 49, 28, + 6, 211, 109, 13, 49, 28, 6, 209, 187, 13, 49, 28, 6, 207, 4, 13, 49, 28, + 6, 199, 16, 113, 13, 49, 28, 6, 202, 197, 13, 49, 28, 6, 199, 166, 13, + 49, 28, 6, 196, 70, 13, 49, 28, 6, 209, 213, 13, 49, 28, 6, 243, 97, 13, + 49, 28, 6, 208, 178, 13, 49, 28, 6, 211, 112, 13, 49, 28, 214, 247, 13, + 49, 28, 2, 251, 162, 13, 49, 28, 2, 248, 214, 13, 49, 28, 2, 231, 213, + 13, 49, 28, 2, 237, 108, 13, 49, 28, 2, 234, 49, 13, 49, 28, 2, 191, 76, + 13, 49, 28, 2, 233, 255, 13, 49, 28, 2, 199, 15, 13, 49, 28, 2, 223, 85, + 13, 49, 28, 2, 222, 74, 13, 49, 28, 2, 220, 33, 13, 49, 28, 2, 215, 157, + 13, 49, 28, 2, 212, 180, 13, 49, 28, 2, 192, 207, 13, 49, 28, 2, 211, + 109, 13, 49, 28, 2, 209, 187, 13, 49, 28, 2, 207, 4, 13, 49, 28, 2, 53, + 202, 197, 13, 49, 28, 2, 202, 197, 13, 49, 28, 2, 199, 166, 13, 49, 28, + 2, 196, 70, 13, 49, 28, 2, 209, 213, 13, 49, 28, 2, 243, 97, 13, 49, 28, + 2, 208, 178, 13, 49, 28, 2, 211, 112, 13, 49, 28, 210, 107, 237, 18, 13, + 49, 28, 234, 50, 113, 13, 49, 28, 199, 16, 113, 13, 49, 28, 222, 75, 113, + 13, 49, 28, 209, 214, 113, 13, 49, 28, 207, 5, 113, 13, 49, 28, 209, 188, + 113, 13, 49, 28, 43, 6, 251, 162, 13, 49, 28, 43, 6, 248, 214, 13, 49, + 28, 43, 6, 231, 213, 13, 49, 28, 43, 6, 237, 108, 13, 49, 28, 43, 6, 234, + 49, 13, 49, 28, 43, 6, 191, 76, 13, 49, 28, 43, 6, 233, 255, 13, 49, 28, + 43, 6, 199, 15, 13, 49, 28, 43, 6, 223, 85, 13, 49, 28, 43, 6, 222, 74, + 13, 49, 28, 43, 6, 220, 33, 13, 49, 28, 43, 6, 215, 157, 13, 49, 28, 43, + 6, 212, 180, 13, 49, 28, 43, 6, 192, 207, 13, 49, 28, 43, 6, 211, 109, + 13, 49, 28, 43, 6, 209, 187, 13, 49, 28, 43, 6, 207, 4, 13, 49, 28, 43, + 6, 199, 16, 113, 13, 49, 28, 43, 6, 202, 197, 13, 49, 28, 43, 6, 199, + 166, 13, 49, 28, 43, 6, 196, 70, 13, 49, 28, 43, 6, 209, 213, 13, 49, 28, + 43, 6, 243, 97, 13, 49, 28, 43, 6, 208, 178, 13, 49, 28, 43, 6, 211, 112, + 13, 49, 28, 43, 214, 247, 13, 49, 28, 43, 2, 251, 162, 13, 49, 28, 43, 2, + 248, 214, 13, 49, 28, 43, 2, 231, 213, 13, 49, 28, 43, 2, 237, 108, 13, + 49, 28, 43, 2, 234, 49, 13, 49, 28, 43, 2, 191, 76, 13, 49, 28, 43, 2, + 233, 255, 13, 49, 28, 43, 2, 199, 15, 13, 49, 28, 43, 2, 223, 85, 13, 49, + 28, 43, 2, 222, 74, 13, 49, 28, 43, 2, 220, 33, 13, 49, 28, 43, 2, 215, + 157, 13, 49, 28, 43, 2, 212, 180, 13, 49, 28, 43, 2, 192, 207, 13, 49, + 28, 43, 2, 211, 109, 13, 49, 28, 43, 2, 209, 187, 13, 49, 28, 43, 2, 207, + 4, 13, 49, 28, 43, 2, 53, 202, 197, 13, 49, 28, 43, 2, 202, 197, 13, 49, 28, 43, 2, 199, 166, 13, 49, 28, 43, 2, 196, 70, 13, 49, 28, 43, 2, 209, - 211, 13, 49, 28, 43, 2, 243, 95, 13, 49, 28, 43, 2, 208, 176, 13, 49, 28, - 43, 2, 211, 110, 13, 49, 28, 43, 210, 105, 237, 16, 13, 49, 28, 43, 234, - 48, 113, 13, 49, 28, 43, 199, 16, 113, 13, 49, 28, 43, 222, 73, 113, 13, - 49, 28, 43, 209, 212, 113, 13, 49, 28, 43, 207, 4, 113, 13, 49, 28, 43, - 209, 186, 113, 13, 28, 6, 237, 10, 13, 28, 2, 237, 10, 13, 28, 17, 191, + 213, 13, 49, 28, 43, 2, 243, 97, 13, 49, 28, 43, 2, 208, 178, 13, 49, 28, + 43, 2, 211, 112, 13, 49, 28, 43, 210, 107, 237, 18, 13, 49, 28, 43, 234, + 50, 113, 13, 49, 28, 43, 199, 16, 113, 13, 49, 28, 43, 222, 75, 113, 13, + 49, 28, 43, 209, 214, 113, 13, 49, 28, 43, 207, 5, 113, 13, 49, 28, 43, + 209, 188, 113, 13, 28, 6, 237, 12, 13, 28, 2, 237, 12, 13, 28, 17, 191, 77, 13, 28, 17, 107, 13, 28, 17, 109, 13, 28, 17, 138, 13, 28, 17, 134, - 13, 28, 17, 149, 13, 28, 17, 169, 13, 28, 17, 175, 13, 28, 17, 171, 13, - 28, 17, 178, 13, 235, 129, 17, 191, 77, 13, 235, 129, 17, 107, 13, 235, - 129, 17, 109, 13, 235, 129, 17, 138, 13, 235, 129, 17, 134, 13, 235, 129, - 17, 149, 13, 235, 129, 17, 169, 13, 235, 129, 17, 175, 13, 235, 129, 17, - 171, 13, 235, 129, 17, 178, 13, 49, 17, 191, 77, 13, 49, 17, 107, 13, 49, - 17, 109, 13, 49, 17, 138, 13, 49, 17, 134, 13, 49, 17, 149, 13, 49, 17, + 13, 28, 17, 150, 13, 28, 17, 169, 13, 28, 17, 175, 13, 28, 17, 171, 13, + 28, 17, 178, 13, 235, 131, 17, 191, 77, 13, 235, 131, 17, 107, 13, 235, + 131, 17, 109, 13, 235, 131, 17, 138, 13, 235, 131, 17, 134, 13, 235, 131, + 17, 150, 13, 235, 131, 17, 169, 13, 235, 131, 17, 175, 13, 235, 131, 17, + 171, 13, 235, 131, 17, 178, 13, 49, 17, 191, 77, 13, 49, 17, 107, 13, 49, + 17, 109, 13, 49, 17, 138, 13, 49, 17, 134, 13, 49, 17, 150, 13, 49, 17, 169, 13, 49, 17, 175, 13, 49, 17, 171, 13, 49, 17, 178, 13, 49, 28, 17, 191, 77, 13, 49, 28, 17, 107, 13, 49, 28, 17, 109, 13, 49, 28, 17, 138, - 13, 49, 28, 17, 134, 13, 49, 28, 17, 149, 13, 49, 28, 17, 169, 13, 49, - 28, 17, 175, 13, 49, 28, 17, 171, 13, 49, 28, 17, 178, 13, 215, 217, 17, - 191, 77, 13, 215, 217, 17, 107, 13, 215, 217, 17, 109, 13, 215, 217, 17, - 138, 13, 215, 217, 17, 134, 13, 215, 217, 17, 149, 13, 215, 217, 17, 169, - 13, 215, 217, 17, 175, 13, 215, 217, 17, 171, 13, 215, 217, 17, 178, 24, - 151, 223, 148, 24, 230, 50, 223, 148, 24, 230, 46, 223, 148, 24, 230, 35, - 223, 148, 24, 230, 39, 223, 148, 24, 230, 52, 223, 148, 24, 151, 141, - 248, 223, 24, 230, 50, 141, 248, 223, 24, 151, 176, 196, 105, 141, 248, - 223, 24, 151, 141, 207, 147, 221, 70, 24, 151, 141, 238, 177, 24, 151, - 141, 229, 124, 24, 151, 141, 229, 125, 218, 241, 24, 230, 50, 141, 229, - 126, 24, 151, 141, 216, 84, 24, 230, 50, 141, 216, 84, 24, 151, 141, 82, - 248, 223, 24, 151, 141, 82, 207, 147, 221, 69, 24, 151, 141, 82, 229, - 124, 24, 151, 141, 133, 82, 229, 124, 24, 151, 141, 229, 125, 82, 196, - 77, 24, 151, 141, 82, 239, 46, 24, 151, 141, 82, 239, 47, 141, 248, 223, - 24, 151, 141, 82, 239, 47, 82, 248, 223, 24, 151, 141, 82, 239, 47, 238, - 177, 24, 151, 141, 82, 239, 47, 229, 124, 24, 151, 141, 82, 238, 213, 24, - 230, 50, 141, 82, 238, 213, 24, 151, 82, 248, 224, 139, 223, 148, 24, - 151, 141, 248, 224, 139, 216, 84, 24, 151, 141, 82, 198, 212, 24, 230, - 50, 141, 82, 198, 212, 24, 151, 141, 82, 201, 53, 176, 248, 223, 24, 151, - 141, 82, 248, 224, 176, 201, 52, 24, 151, 141, 82, 176, 248, 223, 24, - 151, 141, 82, 229, 125, 201, 199, 176, 202, 207, 24, 151, 141, 133, 82, - 229, 125, 176, 202, 207, 24, 151, 141, 133, 82, 229, 125, 176, 239, 46, - 24, 151, 141, 229, 125, 82, 133, 176, 202, 207, 24, 151, 141, 82, 133, - 201, 199, 176, 232, 132, 24, 151, 141, 82, 176, 238, 177, 24, 151, 141, - 82, 176, 243, 9, 24, 151, 141, 82, 176, 228, 249, 24, 151, 141, 82, 176, - 229, 124, 24, 151, 176, 248, 210, 141, 82, 201, 52, 24, 151, 141, 82, - 239, 47, 176, 202, 207, 24, 151, 141, 82, 239, 47, 176, 202, 208, 239, - 46, 24, 151, 141, 82, 239, 47, 176, 202, 208, 248, 223, 24, 151, 82, 176, - 228, 250, 141, 196, 77, 24, 151, 141, 176, 228, 250, 82, 196, 77, 24, - 151, 141, 82, 239, 47, 229, 125, 176, 202, 207, 24, 151, 141, 82, 238, - 214, 176, 202, 207, 24, 151, 141, 82, 239, 47, 176, 232, 132, 24, 151, - 141, 82, 239, 47, 238, 178, 176, 232, 132, 24, 151, 82, 176, 238, 178, - 141, 196, 77, 24, 151, 141, 176, 238, 178, 82, 196, 77, 24, 151, 82, 176, - 47, 141, 196, 77, 24, 151, 82, 176, 47, 141, 229, 124, 24, 151, 141, 176, - 251, 114, 211, 15, 82, 196, 77, 24, 151, 141, 176, 251, 114, 223, 163, - 82, 196, 77, 24, 151, 141, 176, 47, 82, 196, 77, 24, 151, 141, 82, 176, - 239, 47, 229, 124, 24, 151, 141, 82, 176, 251, 114, 211, 14, 24, 151, - 141, 82, 176, 251, 113, 24, 151, 82, 176, 251, 114, 211, 15, 141, 196, - 77, 24, 151, 82, 176, 251, 114, 211, 15, 141, 238, 213, 24, 151, 82, 176, - 251, 114, 141, 196, 77, 24, 151, 141, 176, 228, 250, 82, 229, 124, 24, - 230, 41, 232, 128, 232, 247, 24, 230, 41, 232, 128, 232, 248, 248, 223, - 24, 230, 41, 232, 128, 232, 248, 229, 124, 24, 230, 41, 232, 128, 232, - 248, 239, 46, 24, 230, 41, 232, 128, 232, 248, 239, 47, 201, 209, 24, - 230, 48, 232, 128, 232, 248, 239, 46, 24, 151, 232, 128, 232, 248, 239, - 47, 248, 223, 24, 230, 39, 232, 128, 232, 248, 239, 46, 24, 230, 41, 232, - 226, 232, 248, 201, 198, 24, 230, 41, 229, 213, 232, 226, 232, 248, 201, - 198, 24, 230, 41, 232, 226, 232, 248, 201, 199, 232, 128, 248, 223, 24, - 230, 41, 229, 213, 232, 226, 232, 248, 201, 199, 232, 128, 248, 223, 24, - 230, 41, 232, 226, 232, 248, 201, 199, 248, 223, 24, 230, 41, 229, 213, - 232, 226, 232, 248, 201, 199, 248, 223, 24, 230, 41, 232, 226, 232, 248, - 201, 199, 176, 232, 132, 24, 230, 46, 232, 226, 232, 248, 201, 198, 24, - 230, 46, 232, 226, 232, 248, 201, 199, 211, 76, 24, 230, 39, 232, 226, - 232, 248, 201, 199, 211, 76, 24, 230, 35, 232, 226, 232, 248, 201, 198, - 24, 230, 41, 232, 226, 232, 248, 201, 199, 229, 124, 24, 230, 41, 232, - 226, 232, 248, 201, 199, 229, 125, 176, 202, 207, 24, 230, 41, 232, 226, - 232, 248, 201, 199, 229, 125, 213, 44, 198, 212, 24, 230, 40, 24, 230, - 41, 248, 210, 210, 183, 233, 95, 24, 230, 41, 229, 212, 24, 230, 41, 176, - 202, 207, 24, 230, 41, 229, 213, 176, 202, 207, 24, 230, 41, 176, 248, - 223, 24, 230, 41, 176, 232, 132, 24, 230, 41, 201, 210, 141, 176, 202, - 207, 24, 230, 41, 201, 210, 247, 21, 24, 230, 41, 201, 210, 247, 22, 176, - 202, 207, 24, 230, 41, 201, 210, 247, 22, 176, 202, 208, 248, 223, 24, - 230, 41, 201, 210, 219, 82, 24, 230, 47, 24, 230, 48, 176, 202, 207, 24, - 230, 48, 213, 44, 198, 212, 24, 230, 48, 176, 232, 132, 24, 230, 37, 238, - 173, 24, 230, 36, 24, 230, 46, 211, 76, 24, 230, 45, 24, 230, 46, 211, - 77, 176, 202, 207, 24, 230, 46, 176, 202, 207, 24, 230, 46, 211, 77, 213, - 44, 198, 212, 24, 230, 46, 213, 44, 198, 212, 24, 230, 46, 211, 77, 176, - 232, 132, 24, 230, 46, 176, 232, 132, 24, 230, 44, 211, 76, 24, 230, 43, - 24, 230, 49, 24, 230, 34, 24, 230, 35, 176, 202, 207, 24, 230, 35, 213, - 44, 198, 212, 24, 230, 35, 176, 232, 132, 24, 230, 39, 211, 76, 24, 230, - 39, 211, 77, 176, 232, 132, 24, 230, 38, 24, 230, 39, 202, 70, 24, 230, - 39, 211, 77, 176, 202, 207, 24, 230, 39, 176, 202, 207, 24, 230, 39, 211, - 77, 213, 44, 198, 212, 24, 230, 39, 213, 44, 198, 212, 24, 230, 39, 176, - 202, 208, 198, 35, 223, 148, 24, 230, 39, 176, 248, 210, 82, 206, 188, - 24, 230, 51, 24, 151, 141, 82, 206, 188, 24, 230, 50, 141, 82, 206, 188, - 24, 230, 39, 141, 82, 206, 188, 24, 230, 52, 141, 82, 206, 188, 24, 230, - 39, 219, 82, 24, 151, 141, 82, 206, 189, 248, 223, 24, 151, 141, 82, 206, - 189, 239, 46, 24, 230, 39, 141, 82, 206, 189, 239, 46, 24, 151, 219, 83, - 235, 123, 24, 151, 219, 83, 144, 206, 183, 201, 52, 24, 151, 219, 83, - 144, 206, 183, 238, 162, 24, 151, 219, 83, 144, 211, 26, 243, 9, 24, 151, - 219, 83, 196, 77, 24, 151, 176, 196, 105, 219, 83, 196, 77, 24, 230, 50, - 219, 83, 196, 77, 24, 230, 35, 219, 83, 196, 77, 24, 230, 52, 219, 83, - 196, 77, 24, 151, 219, 83, 207, 147, 221, 70, 24, 151, 219, 83, 248, 223, - 24, 151, 219, 83, 198, 36, 198, 212, 24, 151, 219, 83, 198, 212, 24, 230, - 39, 219, 83, 198, 212, 24, 151, 219, 83, 141, 198, 212, 24, 230, 39, 219, - 83, 141, 198, 212, 24, 230, 52, 219, 83, 141, 176, 141, 176, 211, 14, 24, - 230, 52, 219, 83, 141, 176, 141, 198, 212, 24, 151, 219, 83, 223, 148, - 24, 230, 50, 219, 83, 223, 148, 24, 230, 39, 219, 83, 223, 148, 24, 230, - 52, 219, 83, 223, 148, 24, 151, 141, 82, 219, 82, 24, 230, 50, 141, 82, - 219, 82, 24, 230, 39, 141, 82, 219, 82, 24, 230, 39, 206, 188, 24, 230, - 52, 141, 82, 219, 82, 24, 151, 141, 82, 238, 218, 219, 82, 24, 230, 50, - 141, 82, 238, 218, 219, 82, 24, 151, 206, 189, 235, 123, 24, 230, 39, - 206, 189, 144, 141, 176, 228, 251, 216, 84, 24, 230, 52, 206, 189, 144, - 82, 176, 141, 238, 217, 24, 151, 206, 189, 196, 77, 24, 151, 206, 189, - 207, 147, 221, 70, 24, 151, 206, 189, 219, 82, 24, 230, 50, 206, 189, - 219, 82, 24, 230, 35, 206, 189, 219, 82, 24, 230, 52, 206, 189, 219, 82, - 24, 151, 206, 189, 216, 84, 24, 151, 206, 189, 82, 239, 46, 24, 151, 206, - 189, 82, 207, 147, 221, 69, 24, 151, 206, 189, 223, 148, 24, 151, 206, - 189, 198, 212, 24, 230, 37, 206, 189, 198, 212, 24, 151, 141, 206, 189, - 219, 82, 24, 230, 50, 141, 206, 189, 219, 82, 24, 230, 44, 141, 206, 189, - 219, 83, 211, 104, 24, 230, 37, 141, 206, 189, 219, 83, 211, 14, 24, 230, - 37, 141, 206, 189, 219, 83, 223, 162, 24, 230, 37, 141, 206, 189, 219, - 83, 196, 104, 24, 230, 46, 141, 206, 189, 219, 82, 24, 230, 39, 141, 206, - 189, 219, 82, 24, 230, 52, 141, 206, 189, 219, 83, 211, 14, 24, 230, 52, - 141, 206, 189, 219, 82, 24, 151, 82, 235, 123, 24, 230, 39, 216, 84, 24, - 151, 82, 196, 77, 24, 230, 50, 82, 196, 77, 24, 151, 82, 207, 147, 221, - 70, 24, 151, 82, 133, 176, 202, 207, 24, 230, 37, 82, 198, 212, 24, 151, - 82, 176, 219, 82, 24, 151, 82, 219, 82, 24, 151, 82, 206, 189, 219, 82, - 24, 230, 50, 82, 206, 189, 219, 82, 24, 230, 44, 82, 206, 189, 219, 83, - 211, 104, 24, 230, 46, 82, 206, 189, 219, 82, 24, 230, 39, 82, 206, 189, - 219, 82, 24, 230, 52, 82, 206, 189, 219, 83, 211, 14, 24, 230, 52, 82, - 206, 189, 219, 83, 223, 162, 24, 230, 52, 82, 206, 189, 219, 82, 24, 230, - 50, 82, 206, 189, 219, 83, 248, 223, 24, 230, 48, 82, 206, 189, 219, 83, - 239, 46, 24, 230, 48, 82, 206, 189, 219, 83, 239, 47, 202, 207, 24, 230, - 37, 82, 206, 189, 219, 83, 239, 47, 211, 14, 24, 230, 37, 82, 206, 189, - 219, 83, 239, 47, 223, 162, 24, 230, 37, 82, 206, 189, 219, 83, 239, 46, - 24, 230, 39, 141, 229, 124, 24, 151, 141, 176, 202, 207, 24, 230, 39, - 141, 176, 202, 207, 24, 151, 141, 176, 202, 208, 176, 237, 38, 24, 151, - 141, 176, 202, 208, 176, 239, 46, 24, 151, 141, 176, 202, 208, 176, 248, - 223, 24, 151, 141, 176, 202, 208, 141, 248, 223, 24, 151, 141, 176, 202, - 208, 248, 80, 248, 223, 24, 151, 141, 176, 202, 208, 141, 229, 126, 24, - 151, 141, 176, 232, 133, 141, 201, 52, 24, 151, 141, 176, 232, 133, 141, - 248, 223, 24, 151, 141, 176, 102, 24, 151, 141, 176, 238, 173, 24, 151, - 141, 176, 238, 165, 176, 223, 117, 24, 230, 48, 141, 176, 238, 165, 176, - 223, 117, 24, 151, 141, 176, 238, 165, 176, 196, 104, 24, 151, 141, 176, - 243, 10, 24, 230, 46, 141, 198, 212, 24, 230, 46, 141, 176, 211, 76, 24, - 230, 39, 141, 176, 211, 76, 24, 230, 39, 141, 176, 220, 12, 24, 230, 39, - 141, 198, 212, 24, 230, 39, 141, 176, 202, 70, 24, 230, 52, 141, 176, - 211, 14, 24, 230, 52, 141, 176, 223, 162, 24, 230, 52, 141, 198, 212, 24, - 151, 198, 212, 24, 151, 176, 229, 212, 24, 151, 176, 202, 208, 237, 38, - 24, 151, 176, 202, 208, 239, 46, 24, 151, 176, 202, 208, 248, 223, 24, - 151, 176, 232, 132, 24, 151, 176, 248, 210, 141, 216, 84, 24, 151, 176, - 248, 210, 82, 206, 188, 24, 151, 176, 248, 210, 206, 189, 219, 82, 24, - 151, 176, 196, 105, 105, 232, 247, 24, 151, 176, 139, 105, 232, 247, 24, - 151, 176, 196, 105, 115, 232, 247, 24, 151, 176, 196, 105, 232, 128, 232, - 247, 24, 151, 176, 139, 232, 128, 207, 147, 221, 69, 24, 230, 42, 24, - 151, 229, 212, 24, 198, 37, 202, 169, 24, 198, 37, 215, 128, 24, 198, 37, - 248, 209, 24, 230, 215, 202, 169, 24, 230, 215, 215, 128, 24, 230, 215, - 248, 209, 24, 201, 33, 202, 169, 24, 201, 33, 215, 128, 24, 201, 33, 248, - 209, 24, 248, 18, 202, 169, 24, 248, 18, 215, 128, 24, 248, 18, 248, 209, - 24, 206, 60, 202, 169, 24, 206, 60, 215, 128, 24, 206, 60, 248, 209, 24, - 200, 171, 200, 76, 24, 200, 171, 248, 209, 24, 201, 186, 220, 13, 202, - 169, 24, 201, 186, 2, 202, 169, 24, 201, 186, 220, 13, 215, 128, 24, 201, - 186, 2, 215, 128, 24, 201, 186, 204, 6, 24, 232, 197, 220, 13, 202, 169, - 24, 232, 197, 2, 202, 169, 24, 232, 197, 220, 13, 215, 128, 24, 232, 197, - 2, 215, 128, 24, 232, 197, 204, 6, 24, 201, 186, 232, 197, 251, 154, 24, - 215, 172, 133, 144, 220, 12, 24, 215, 172, 133, 144, 202, 70, 24, 215, - 172, 133, 204, 6, 24, 215, 172, 144, 204, 6, 24, 215, 172, 133, 144, 251, - 155, 220, 12, 24, 215, 172, 133, 144, 251, 155, 202, 70, 24, 215, 172, - 202, 208, 119, 202, 208, 205, 84, 24, 215, 171, 232, 253, 239, 35, 24, - 215, 173, 232, 253, 239, 35, 24, 215, 171, 202, 170, 201, 53, 202, 70, - 24, 215, 171, 202, 170, 201, 53, 216, 212, 24, 215, 171, 202, 170, 201, - 53, 220, 12, 24, 215, 171, 202, 170, 201, 53, 220, 10, 24, 215, 171, 202, - 170, 193, 4, 232, 200, 24, 215, 171, 55, 201, 52, 24, 215, 171, 55, 193, - 4, 232, 200, 24, 215, 171, 55, 251, 154, 24, 215, 171, 55, 251, 155, 193, - 4, 232, 200, 24, 215, 171, 238, 217, 24, 215, 171, 197, 225, 201, 53, - 215, 175, 24, 215, 171, 197, 225, 193, 4, 232, 200, 24, 215, 171, 197, - 225, 251, 154, 24, 215, 171, 197, 225, 251, 155, 193, 4, 232, 200, 24, - 215, 171, 248, 228, 202, 70, 24, 215, 171, 248, 228, 216, 212, 24, 215, - 171, 248, 228, 220, 12, 24, 215, 171, 239, 2, 202, 70, 24, 215, 171, 239, - 2, 216, 212, 24, 215, 171, 239, 2, 220, 12, 24, 215, 171, 239, 2, 206, - 120, 24, 215, 171, 243, 126, 202, 70, 24, 215, 171, 243, 126, 216, 212, - 24, 215, 171, 243, 126, 220, 12, 24, 215, 171, 111, 202, 70, 24, 215, - 171, 111, 216, 212, 24, 215, 171, 111, 220, 12, 24, 215, 171, 191, 21, - 202, 70, 24, 215, 171, 191, 21, 216, 212, 24, 215, 171, 191, 21, 220, 12, - 24, 215, 171, 210, 57, 202, 70, 24, 215, 171, 210, 57, 216, 212, 24, 215, - 171, 210, 57, 220, 12, 24, 198, 3, 206, 118, 202, 169, 24, 198, 3, 206, - 118, 235, 133, 24, 198, 3, 206, 118, 251, 154, 24, 198, 3, 206, 119, 202, - 169, 24, 198, 3, 206, 119, 235, 133, 24, 198, 3, 206, 119, 251, 154, 24, - 198, 3, 203, 144, 24, 198, 3, 250, 251, 201, 218, 202, 169, 24, 198, 3, - 250, 251, 201, 218, 235, 133, 24, 198, 3, 250, 251, 201, 218, 197, 224, - 24, 215, 174, 250, 139, 202, 70, 24, 215, 174, 250, 139, 216, 212, 24, - 215, 174, 250, 139, 220, 12, 24, 215, 174, 250, 139, 220, 10, 24, 215, - 174, 198, 31, 202, 70, 24, 215, 174, 198, 31, 216, 212, 24, 215, 174, - 198, 31, 220, 12, 24, 215, 174, 198, 31, 220, 10, 24, 215, 174, 248, 210, - 250, 139, 202, 70, 24, 215, 174, 248, 210, 250, 139, 216, 212, 24, 215, - 174, 248, 210, 250, 139, 220, 12, 24, 215, 174, 248, 210, 250, 139, 220, - 10, 24, 215, 174, 248, 210, 198, 31, 202, 70, 24, 215, 174, 248, 210, - 198, 31, 216, 212, 24, 215, 174, 248, 210, 198, 31, 220, 12, 24, 215, - 174, 248, 210, 198, 31, 220, 10, 24, 215, 173, 202, 170, 201, 53, 202, - 70, 24, 215, 173, 202, 170, 201, 53, 216, 212, 24, 215, 173, 202, 170, - 201, 53, 220, 12, 24, 215, 173, 202, 170, 201, 53, 220, 10, 24, 215, 173, - 202, 170, 193, 4, 232, 200, 24, 215, 173, 55, 201, 52, 24, 215, 173, 55, - 193, 4, 232, 200, 24, 215, 173, 55, 251, 154, 24, 215, 173, 55, 251, 155, - 193, 4, 232, 200, 24, 215, 173, 238, 217, 24, 215, 173, 197, 225, 201, - 53, 215, 175, 24, 215, 173, 197, 225, 193, 4, 232, 200, 24, 215, 173, - 197, 225, 251, 155, 215, 175, 24, 215, 173, 197, 225, 251, 155, 193, 4, - 232, 200, 24, 215, 173, 248, 227, 24, 215, 173, 239, 2, 202, 70, 24, 215, - 173, 239, 2, 216, 212, 24, 215, 173, 239, 2, 220, 12, 24, 215, 173, 243, - 125, 24, 215, 173, 111, 202, 70, 24, 215, 173, 111, 216, 212, 24, 215, - 173, 111, 220, 12, 24, 215, 173, 191, 21, 202, 70, 24, 215, 173, 191, 21, - 216, 212, 24, 215, 173, 191, 21, 220, 12, 24, 215, 173, 210, 57, 202, 70, - 24, 215, 173, 210, 57, 216, 212, 24, 215, 173, 210, 57, 220, 12, 24, 198, - 4, 206, 119, 202, 169, 24, 198, 4, 206, 119, 235, 133, 24, 198, 4, 206, - 119, 251, 154, 24, 198, 4, 206, 118, 202, 169, 24, 198, 4, 206, 118, 235, - 133, 24, 198, 4, 206, 118, 251, 154, 24, 198, 4, 203, 144, 24, 215, 171, - 238, 165, 208, 23, 202, 70, 24, 215, 171, 238, 165, 208, 23, 216, 212, - 24, 215, 171, 238, 165, 208, 23, 220, 12, 24, 215, 171, 238, 165, 208, - 23, 220, 10, 24, 215, 171, 238, 165, 230, 67, 202, 70, 24, 215, 171, 238, - 165, 230, 67, 216, 212, 24, 215, 171, 238, 165, 230, 67, 220, 12, 24, - 215, 171, 238, 165, 230, 67, 220, 10, 24, 215, 171, 238, 165, 198, 218, - 243, 11, 202, 70, 24, 215, 171, 238, 165, 198, 218, 243, 11, 216, 212, - 24, 215, 171, 228, 143, 202, 70, 24, 215, 171, 228, 143, 216, 212, 24, - 215, 171, 228, 143, 220, 12, 24, 215, 171, 219, 5, 202, 70, 24, 215, 171, - 219, 5, 216, 212, 24, 215, 171, 219, 5, 220, 12, 24, 215, 171, 219, 5, 2, - 235, 133, 24, 215, 171, 193, 139, 238, 165, 55, 202, 70, 24, 215, 171, - 193, 139, 238, 165, 55, 216, 212, 24, 215, 171, 193, 139, 238, 165, 55, - 220, 12, 24, 215, 171, 193, 139, 238, 165, 197, 225, 202, 70, 24, 215, - 171, 193, 139, 238, 165, 197, 225, 216, 212, 24, 215, 171, 193, 139, 238, - 165, 197, 225, 220, 12, 24, 215, 171, 238, 165, 199, 25, 201, 52, 24, - 215, 171, 238, 163, 238, 218, 202, 70, 24, 215, 171, 238, 163, 238, 218, - 216, 212, 24, 206, 118, 202, 169, 24, 206, 118, 235, 133, 24, 206, 118, - 251, 156, 24, 215, 171, 203, 144, 24, 215, 171, 238, 165, 229, 116, 232, - 97, 193, 167, 24, 215, 171, 228, 143, 229, 116, 232, 97, 193, 167, 24, - 215, 171, 219, 5, 229, 116, 232, 97, 193, 167, 24, 215, 171, 193, 139, - 229, 116, 232, 97, 193, 167, 24, 206, 118, 202, 170, 229, 116, 232, 97, - 193, 167, 24, 206, 118, 55, 229, 116, 232, 97, 193, 167, 24, 206, 118, - 251, 155, 229, 116, 232, 97, 193, 167, 24, 215, 171, 238, 165, 229, 116, - 243, 104, 24, 215, 171, 228, 143, 229, 116, 243, 104, 24, 215, 171, 219, - 5, 229, 116, 243, 104, 24, 215, 171, 193, 139, 229, 116, 243, 104, 24, - 206, 118, 202, 170, 229, 116, 243, 104, 24, 206, 118, 55, 229, 116, 243, - 104, 24, 206, 118, 251, 155, 229, 116, 243, 104, 24, 215, 171, 193, 139, - 237, 39, 210, 86, 202, 70, 24, 215, 171, 193, 139, 237, 39, 210, 86, 216, - 212, 24, 215, 171, 193, 139, 237, 39, 210, 86, 220, 12, 24, 215, 173, - 238, 165, 229, 116, 247, 31, 202, 70, 24, 215, 173, 238, 165, 229, 116, - 247, 31, 220, 12, 24, 215, 173, 228, 143, 229, 116, 247, 31, 2, 235, 133, - 24, 215, 173, 228, 143, 229, 116, 247, 31, 220, 13, 235, 133, 24, 215, - 173, 228, 143, 229, 116, 247, 31, 2, 197, 224, 24, 215, 173, 228, 143, - 229, 116, 247, 31, 220, 13, 197, 224, 24, 215, 173, 219, 5, 229, 116, - 247, 31, 2, 202, 169, 24, 215, 173, 219, 5, 229, 116, 247, 31, 220, 13, - 202, 169, 24, 215, 173, 219, 5, 229, 116, 247, 31, 2, 235, 133, 24, 215, - 173, 219, 5, 229, 116, 247, 31, 220, 13, 235, 133, 24, 215, 173, 193, - 139, 229, 116, 247, 31, 202, 70, 24, 215, 173, 193, 139, 229, 116, 247, - 31, 220, 12, 24, 206, 119, 202, 170, 229, 116, 247, 30, 24, 206, 119, 55, - 229, 116, 247, 30, 24, 206, 119, 251, 155, 229, 116, 247, 30, 24, 215, - 173, 238, 165, 229, 116, 232, 194, 202, 70, 24, 215, 173, 238, 165, 229, - 116, 232, 194, 220, 12, 24, 215, 173, 228, 143, 229, 116, 232, 194, 2, - 235, 133, 24, 215, 173, 228, 143, 229, 116, 232, 194, 220, 13, 235, 133, - 24, 215, 173, 228, 143, 229, 116, 232, 194, 197, 225, 2, 197, 224, 24, - 215, 173, 228, 143, 229, 116, 232, 194, 197, 225, 220, 13, 197, 224, 24, - 215, 173, 219, 5, 229, 116, 232, 194, 2, 202, 169, 24, 215, 173, 219, 5, - 229, 116, 232, 194, 220, 13, 202, 169, 24, 215, 173, 219, 5, 229, 116, - 232, 194, 2, 235, 133, 24, 215, 173, 219, 5, 229, 116, 232, 194, 220, 13, - 235, 133, 24, 215, 173, 193, 139, 229, 116, 232, 194, 202, 70, 24, 215, - 173, 193, 139, 229, 116, 232, 194, 220, 12, 24, 206, 119, 202, 170, 229, - 116, 232, 193, 24, 206, 119, 55, 229, 116, 232, 193, 24, 206, 119, 251, - 155, 229, 116, 232, 193, 24, 215, 173, 238, 165, 202, 70, 24, 215, 173, - 238, 165, 216, 212, 24, 215, 173, 238, 165, 220, 12, 24, 215, 173, 238, - 165, 220, 10, 24, 215, 173, 238, 165, 242, 78, 24, 215, 173, 228, 143, - 202, 70, 24, 215, 173, 219, 5, 202, 70, 24, 215, 173, 193, 139, 202, 58, - 24, 215, 173, 193, 139, 202, 70, 24, 215, 173, 193, 139, 220, 12, 24, - 206, 119, 202, 169, 24, 206, 119, 235, 133, 24, 206, 119, 251, 154, 24, - 215, 173, 203, 145, 210, 118, 24, 215, 171, 250, 251, 243, 11, 2, 202, - 169, 24, 215, 171, 250, 251, 243, 11, 216, 213, 202, 169, 24, 215, 171, - 250, 251, 243, 11, 2, 235, 133, 24, 215, 171, 250, 251, 243, 11, 216, - 213, 235, 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 2, - 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 216, 213, - 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 220, 13, - 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 2, 235, - 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 216, 213, 235, - 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 220, 13, 235, - 133, 24, 215, 171, 193, 4, 243, 11, 232, 97, 202, 169, 24, 215, 171, 193, - 4, 243, 11, 232, 97, 235, 133, 24, 215, 173, 193, 4, 243, 11, 229, 116, - 193, 168, 202, 169, 24, 215, 173, 193, 4, 243, 11, 229, 116, 193, 168, - 235, 133, 24, 215, 171, 232, 253, 243, 8, 202, 169, 24, 215, 171, 232, - 253, 243, 8, 235, 133, 24, 215, 173, 232, 253, 243, 8, 229, 116, 193, - 168, 202, 169, 24, 215, 173, 232, 253, 243, 8, 229, 116, 193, 168, 235, - 133, 24, 235, 40, 250, 236, 202, 70, 24, 235, 40, 250, 236, 220, 12, 24, - 235, 40, 233, 73, 24, 235, 40, 202, 75, 24, 235, 40, 199, 88, 24, 235, - 40, 207, 63, 24, 235, 40, 202, 176, 24, 235, 40, 202, 177, 251, 154, 24, - 235, 40, 233, 225, 211, 27, 198, 146, 24, 235, 40, 230, 226, 24, 229, - 235, 24, 229, 236, 206, 193, 24, 229, 236, 215, 171, 201, 52, 24, 229, - 236, 215, 171, 198, 149, 24, 229, 236, 215, 173, 201, 52, 24, 229, 236, - 215, 171, 238, 164, 24, 229, 236, 215, 173, 238, 164, 24, 229, 236, 215, - 176, 243, 10, 24, 233, 104, 236, 233, 209, 25, 213, 14, 232, 133, 198, - 147, 24, 233, 104, 236, 233, 209, 25, 213, 14, 133, 211, 57, 235, 123, - 24, 233, 104, 236, 233, 209, 25, 213, 14, 133, 211, 57, 144, 198, 147, - 24, 233, 191, 201, 53, 196, 77, 24, 233, 191, 201, 53, 214, 81, 24, 233, - 191, 201, 53, 235, 123, 24, 235, 107, 233, 191, 214, 82, 235, 123, 24, - 235, 107, 233, 191, 144, 214, 81, 24, 235, 107, 233, 191, 133, 214, 81, - 24, 235, 107, 233, 191, 214, 82, 196, 77, 24, 232, 151, 214, 81, 24, 232, - 151, 239, 35, 24, 232, 151, 193, 7, 24, 233, 186, 211, 76, 24, 233, 186, - 201, 185, 24, 233, 186, 242, 218, 24, 233, 194, 248, 130, 202, 169, 24, - 233, 194, 248, 130, 215, 128, 24, 233, 186, 132, 211, 76, 24, 233, 186, - 193, 78, 211, 76, 24, 233, 186, 132, 242, 218, 24, 233, 186, 193, 76, - 215, 175, 24, 233, 194, 193, 58, 24, 233, 187, 196, 77, 24, 233, 187, - 235, 123, 24, 233, 187, 232, 180, 24, 233, 189, 201, 52, 24, 233, 189, - 201, 53, 235, 133, 24, 233, 189, 201, 53, 251, 154, 24, 233, 190, 201, - 52, 24, 233, 190, 201, 53, 235, 133, 24, 233, 190, 201, 53, 251, 154, 24, - 233, 189, 238, 162, 24, 233, 190, 238, 162, 24, 233, 189, 243, 5, 24, - 243, 121, 208, 155, 24, 243, 121, 214, 81, 24, 243, 121, 200, 218, 24, - 199, 89, 243, 121, 229, 135, 24, 199, 89, 243, 121, 216, 84, 24, 199, 89, - 243, 121, 218, 241, 24, 234, 209, 24, 213, 14, 214, 81, 24, 213, 14, 239, - 35, 24, 213, 14, 193, 5, 24, 213, 14, 193, 73, 24, 251, 226, 248, 116, - 211, 14, 24, 251, 226, 200, 217, 223, 162, 24, 251, 226, 248, 118, 2, - 206, 117, 24, 251, 226, 200, 219, 2, 206, 117, 24, 248, 39, 223, 134, 24, - 248, 39, 233, 214, 24, 215, 180, 242, 219, 214, 81, 24, 215, 180, 242, - 219, 232, 132, 24, 215, 180, 242, 219, 239, 35, 24, 215, 180, 202, 65, - 24, 215, 180, 202, 66, 193, 7, 24, 215, 180, 202, 66, 211, 76, 24, 215, - 180, 232, 93, 24, 215, 180, 232, 94, 193, 7, 24, 215, 180, 232, 94, 211, - 76, 24, 215, 180, 211, 77, 243, 10, 24, 215, 180, 211, 77, 232, 132, 24, - 215, 180, 211, 77, 193, 7, 24, 215, 180, 211, 77, 211, 7, 24, 215, 180, - 211, 77, 211, 8, 193, 7, 24, 215, 180, 211, 77, 211, 8, 192, 88, 24, 215, - 180, 211, 77, 207, 92, 24, 215, 180, 211, 77, 207, 93, 193, 7, 24, 215, - 180, 211, 77, 207, 93, 192, 88, 24, 215, 180, 221, 122, 24, 215, 180, - 221, 123, 232, 132, 24, 215, 180, 221, 123, 193, 7, 24, 215, 180, 199, - 88, 24, 215, 180, 199, 89, 232, 132, 24, 215, 180, 199, 89, 200, 218, 24, - 219, 97, 208, 219, 198, 87, 24, 219, 99, 110, 139, 196, 74, 24, 219, 99, - 116, 139, 218, 236, 24, 215, 180, 239, 0, 24, 215, 180, 193, 6, 202, 169, - 24, 215, 180, 193, 6, 235, 133, 24, 198, 62, 201, 74, 211, 15, 233, 75, - 24, 198, 62, 219, 142, 219, 96, 24, 198, 62, 198, 136, 248, 210, 219, 96, - 24, 198, 62, 198, 136, 198, 35, 223, 118, 215, 179, 24, 198, 62, 223, - 118, 215, 180, 207, 63, 24, 198, 62, 215, 170, 251, 251, 243, 122, 24, - 198, 62, 247, 22, 201, 74, 211, 14, 24, 198, 62, 247, 22, 223, 118, 215, - 179, 24, 199, 117, 24, 199, 118, 215, 175, 24, 199, 118, 211, 105, 198, - 61, 24, 199, 118, 211, 105, 198, 62, 215, 175, 24, 199, 118, 211, 105, - 219, 96, 24, 199, 118, 211, 105, 219, 97, 215, 175, 24, 199, 118, 248, - 146, 219, 96, 24, 215, 171, 223, 14, 24, 215, 173, 223, 14, 24, 214, 112, - 24, 230, 78, 24, 233, 217, 24, 203, 22, 229, 123, 201, 219, 24, 203, 22, - 229, 123, 209, 23, 24, 193, 165, 203, 22, 229, 123, 215, 178, 24, 232, - 192, 203, 22, 229, 123, 215, 178, 24, 203, 22, 198, 148, 232, 98, 193, - 172, 24, 198, 43, 201, 53, 201, 37, 24, 198, 43, 238, 163, 248, 227, 24, - 198, 44, 197, 16, 24, 116, 248, 105, 198, 148, 232, 98, 229, 123, 222, - 195, 24, 219, 124, 242, 79, 24, 219, 124, 219, 197, 24, 219, 124, 219, - 196, 24, 219, 124, 219, 195, 24, 219, 124, 219, 194, 24, 219, 124, 219, - 193, 24, 219, 124, 219, 192, 24, 219, 124, 219, 191, 24, 232, 252, 24, - 219, 37, 201, 247, 24, 219, 38, 201, 247, 24, 219, 40, 229, 208, 24, 219, - 40, 193, 74, 24, 219, 40, 237, 92, 24, 219, 40, 229, 236, 214, 112, 24, - 219, 40, 198, 45, 24, 219, 40, 219, 123, 237, 9, 24, 242, 74, 24, 232, - 80, 201, 63, 24, 204, 25, 24, 242, 83, 24, 210, 113, 24, 233, 6, 215, - 244, 24, 233, 6, 215, 243, 24, 233, 6, 215, 242, 24, 233, 6, 215, 241, - 24, 233, 6, 215, 240, 24, 206, 121, 215, 244, 24, 206, 121, 215, 243, 24, - 206, 121, 215, 242, 24, 206, 121, 215, 241, 24, 206, 121, 215, 240, 24, - 206, 121, 215, 239, 24, 206, 121, 215, 238, 24, 206, 121, 215, 237, 24, - 206, 121, 215, 251, 24, 206, 121, 215, 250, 24, 206, 121, 215, 249, 24, - 206, 121, 215, 248, 24, 206, 121, 215, 247, 24, 206, 121, 215, 246, 24, - 206, 121, 215, 245, 8, 2, 1, 233, 37, 237, 3, 4, 197, 228, 8, 2, 1, 207, - 18, 27, 232, 51, 8, 1, 2, 6, 153, 232, 51, 8, 2, 1, 207, 18, 222, 152, 8, - 1, 2, 6, 220, 143, 4, 248, 231, 8, 2, 1, 219, 163, 4, 207, 24, 102, 8, 2, - 1, 153, 192, 160, 4, 248, 231, 8, 2, 1, 207, 18, 234, 88, 8, 2, 1, 153, - 207, 222, 4, 179, 219, 213, 23, 207, 24, 102, 8, 2, 1, 200, 44, 4, 228, - 251, 23, 207, 24, 102, 8, 1, 207, 24, 242, 232, 4, 207, 24, 102, 8, 2, 1, - 234, 13, 4, 55, 164, 8, 2, 1, 234, 13, 4, 55, 249, 88, 23, 238, 175, 8, - 2, 1, 153, 200, 44, 4, 238, 175, 8, 1, 223, 93, 231, 11, 201, 64, 4, 238, - 175, 8, 1, 201, 36, 247, 194, 4, 238, 175, 8, 1, 2, 6, 153, 222, 152, 8, - 2, 1, 220, 143, 4, 232, 233, 8, 2, 1, 237, 70, 237, 3, 4, 210, 192, 102, - 8, 2, 1, 220, 143, 4, 248, 232, 23, 210, 192, 102, 8, 2, 1, 234, 89, 4, - 210, 192, 102, 8, 2, 1, 153, 207, 222, 4, 210, 192, 102, 8, 2, 1, 207, - 222, 4, 232, 234, 23, 210, 192, 102, 8, 2, 1, 199, 79, 237, 3, 4, 210, - 192, 102, 8, 2, 1, 233, 179, 4, 210, 192, 102, 8, 2, 1, 237, 70, 237, 3, - 4, 207, 24, 102, 8, 2, 1, 228, 74, 4, 201, 28, 23, 207, 24, 102, 8, 2, 1, - 187, 4, 207, 24, 102, 8, 2, 1, 199, 79, 237, 3, 4, 207, 24, 102, 8, 2, 1, - 247, 194, 4, 207, 24, 102, 8, 2, 1, 206, 9, 4, 238, 175, 8, 2, 1, 238, - 128, 4, 216, 86, 45, 102, 8, 2, 1, 220, 143, 4, 216, 86, 45, 102, 8, 2, - 1, 215, 62, 4, 216, 86, 45, 102, 8, 2, 1, 207, 222, 4, 216, 86, 45, 102, - 8, 2, 1, 206, 9, 4, 216, 86, 45, 102, 8, 2, 1, 200, 44, 4, 216, 86, 45, - 102, 33, 135, 1, 250, 122, 33, 135, 1, 247, 252, 33, 135, 1, 195, 151, - 33, 135, 1, 231, 18, 33, 135, 1, 236, 169, 33, 135, 1, 192, 49, 33, 135, - 1, 191, 55, 33, 135, 1, 191, 82, 33, 135, 1, 223, 39, 33, 135, 1, 89, - 223, 39, 33, 135, 1, 68, 33, 135, 1, 236, 190, 33, 135, 1, 222, 94, 33, - 135, 1, 219, 75, 33, 135, 1, 215, 66, 33, 135, 1, 214, 210, 33, 135, 1, - 211, 89, 33, 135, 1, 209, 55, 33, 135, 1, 206, 179, 33, 135, 1, 202, 77, - 33, 135, 1, 197, 44, 33, 135, 1, 196, 124, 33, 135, 1, 232, 101, 33, 135, - 1, 229, 188, 33, 135, 1, 203, 8, 33, 135, 1, 197, 146, 33, 135, 1, 243, - 54, 33, 135, 1, 203, 165, 33, 135, 1, 192, 58, 33, 135, 1, 192, 60, 33, - 135, 1, 192, 93, 33, 135, 1, 191, 225, 33, 135, 1, 2, 191, 190, 33, 135, - 1, 192, 12, 33, 135, 1, 223, 82, 2, 191, 190, 33, 135, 1, 248, 175, 191, - 190, 33, 135, 1, 223, 82, 248, 175, 191, 190, 33, 135, 1, 232, 228, 52, - 1, 38, 2, 65, 52, 1, 38, 2, 249, 17, 52, 1, 38, 2, 195, 153, 52, 1, 38, - 2, 231, 77, 52, 1, 38, 2, 237, 146, 52, 1, 38, 2, 223, 226, 52, 1, 38, 2, - 191, 62, 52, 1, 38, 2, 191, 87, 52, 1, 38, 2, 68, 52, 1, 38, 2, 155, 52, - 1, 38, 2, 234, 140, 52, 1, 38, 2, 234, 114, 52, 1, 38, 2, 74, 52, 1, 38, - 2, 210, 63, 52, 1, 38, 2, 234, 34, 52, 1, 38, 2, 234, 22, 52, 1, 38, 2, - 199, 145, 52, 1, 38, 2, 66, 52, 1, 38, 2, 234, 181, 52, 1, 38, 2, 140, - 52, 1, 38, 2, 197, 161, 52, 1, 38, 2, 243, 127, 52, 1, 38, 2, 203, 165, - 52, 1, 38, 2, 192, 58, 52, 1, 38, 2, 71, 52, 1, 38, 2, 191, 225, 52, 1, - 38, 2, 235, 17, 52, 1, 38, 2, 205, 86, 52, 1, 38, 2, 247, 203, 68, 52, 1, - 38, 2, 223, 10, 52, 1, 38, 2, 249, 82, 74, 52, 1, 38, 2, 201, 53, 66, 52, - 1, 38, 2, 210, 179, 38, 200, 230, 2, 1, 65, 38, 200, 230, 2, 1, 249, 17, - 38, 200, 230, 2, 1, 195, 153, 38, 200, 230, 2, 1, 231, 77, 38, 200, 230, - 2, 1, 237, 146, 38, 200, 230, 2, 1, 223, 226, 38, 200, 230, 2, 1, 191, - 62, 38, 200, 230, 2, 1, 191, 87, 38, 200, 230, 2, 1, 68, 38, 200, 230, 2, - 1, 155, 38, 200, 230, 2, 1, 234, 140, 38, 200, 230, 2, 1, 74, 38, 200, - 230, 2, 1, 210, 63, 38, 200, 230, 2, 1, 234, 22, 38, 200, 230, 2, 1, 66, - 38, 200, 230, 2, 1, 234, 181, 38, 200, 230, 2, 1, 140, 38, 200, 230, 2, - 1, 197, 161, 38, 200, 230, 2, 1, 243, 127, 38, 200, 230, 2, 1, 203, 165, - 38, 200, 230, 2, 1, 230, 17, 56, 38, 200, 230, 2, 1, 192, 58, 38, 200, - 230, 2, 1, 231, 78, 4, 196, 69, 38, 200, 230, 2, 1, 247, 203, 68, 38, - 200, 230, 2, 1, 235, 32, 38, 200, 230, 2, 1, 235, 28, 52, 1, 38, 2, 234, - 23, 4, 237, 87, 52, 1, 38, 2, 192, 59, 4, 249, 147, 192, 62, 52, 1, 38, - 2, 201, 53, 126, 4, 106, 33, 38, 2, 1, 247, 203, 68, 212, 80, 208, 162, - 90, 1, 174, 212, 80, 208, 162, 90, 1, 197, 168, 212, 80, 208, 162, 90, 1, - 212, 199, 212, 80, 208, 162, 90, 1, 190, 190, 212, 80, 208, 162, 90, 1, - 140, 212, 80, 208, 162, 90, 1, 180, 212, 80, 208, 162, 90, 1, 192, 220, - 212, 80, 208, 162, 90, 1, 213, 111, 212, 80, 208, 162, 90, 1, 247, 160, - 212, 80, 208, 162, 90, 1, 173, 212, 80, 208, 162, 90, 1, 188, 212, 80, - 208, 162, 90, 1, 191, 123, 212, 80, 208, 162, 90, 1, 214, 166, 212, 80, - 208, 162, 90, 1, 212, 186, 212, 80, 208, 162, 90, 1, 155, 212, 80, 208, - 162, 90, 1, 238, 32, 212, 80, 208, 162, 90, 1, 212, 101, 212, 80, 208, - 162, 90, 1, 212, 244, 212, 80, 208, 162, 90, 1, 195, 188, 212, 80, 208, - 162, 90, 1, 212, 180, 212, 80, 208, 162, 90, 1, 197, 8, 212, 80, 208, - 162, 90, 1, 233, 109, 212, 80, 208, 162, 90, 1, 165, 212, 80, 208, 162, - 90, 1, 208, 96, 212, 80, 208, 162, 90, 1, 170, 212, 80, 208, 162, 90, 1, - 212, 246, 212, 80, 208, 162, 90, 1, 168, 212, 80, 208, 162, 90, 1, 192, - 175, 212, 80, 208, 162, 90, 1, 212, 248, 212, 80, 208, 162, 90, 1, 236, - 186, 212, 80, 208, 162, 90, 1, 212, 247, 212, 80, 208, 162, 90, 1, 230, - 81, 212, 80, 208, 162, 90, 1, 216, 19, 212, 80, 208, 162, 90, 1, 209, - 110, 212, 80, 208, 162, 90, 1, 231, 240, 212, 80, 208, 162, 90, 1, 206, - 109, 212, 80, 208, 162, 90, 1, 65, 212, 80, 208, 162, 90, 1, 252, 206, - 212, 80, 208, 162, 90, 1, 68, 212, 80, 208, 162, 90, 1, 66, 212, 80, 208, - 162, 90, 1, 74, 212, 80, 208, 162, 90, 1, 211, 87, 212, 80, 208, 162, 90, - 1, 71, 212, 80, 208, 162, 90, 1, 234, 188, 212, 80, 208, 162, 90, 1, 193, - 224, 212, 80, 208, 162, 90, 198, 70, 212, 80, 208, 162, 90, 198, 66, 212, - 80, 208, 162, 90, 198, 67, 212, 80, 208, 162, 90, 198, 64, 212, 80, 208, - 162, 90, 198, 65, 212, 80, 208, 162, 90, 198, 68, 212, 80, 208, 162, 90, - 198, 69, 212, 80, 208, 162, 90, 3, 40, 209, 250, 212, 80, 208, 162, 90, - 3, 40, 199, 3, 212, 80, 208, 162, 90, 3, 40, 219, 39, 212, 80, 208, 162, - 90, 3, 40, 251, 101, 212, 80, 208, 162, 90, 3, 40, 223, 94, 212, 80, 208, - 162, 90, 3, 192, 183, 192, 182, 212, 80, 208, 162, 90, 5, 219, 190, 212, - 80, 208, 162, 90, 17, 191, 77, 212, 80, 208, 162, 90, 17, 107, 212, 80, - 208, 162, 90, 17, 109, 212, 80, 208, 162, 90, 17, 138, 212, 80, 208, 162, - 90, 17, 134, 212, 80, 208, 162, 90, 17, 149, 212, 80, 208, 162, 90, 17, - 169, 212, 80, 208, 162, 90, 17, 175, 212, 80, 208, 162, 90, 17, 171, 212, - 80, 208, 162, 90, 17, 178, 212, 80, 208, 162, 90, 219, 28, 212, 96, 212, - 80, 208, 162, 90, 47, 247, 160, 198, 38, 1, 168, 198, 38, 1, 249, 153, - 198, 38, 1, 190, 190, 198, 38, 1, 238, 32, 198, 38, 1, 155, 198, 38, 1, - 231, 240, 198, 38, 1, 174, 198, 38, 1, 180, 198, 38, 1, 214, 68, 198, 38, - 1, 188, 198, 38, 1, 247, 1, 198, 38, 1, 170, 198, 38, 1, 193, 190, 198, - 38, 1, 223, 32, 198, 38, 1, 140, 198, 38, 1, 165, 198, 38, 1, 173, 198, - 38, 1, 68, 198, 38, 1, 248, 38, 68, 198, 38, 1, 223, 49, 198, 38, 1, 248, - 38, 223, 49, 198, 38, 1, 66, 198, 38, 1, 71, 198, 38, 1, 248, 38, 71, - 198, 38, 1, 234, 65, 198, 38, 1, 248, 38, 234, 65, 198, 38, 1, 74, 198, - 38, 1, 252, 25, 198, 38, 1, 248, 38, 252, 25, 198, 38, 1, 65, 198, 38, 3, - 206, 180, 198, 79, 193, 163, 1, 252, 206, 193, 163, 1, 65, 193, 163, 1, - 249, 153, 193, 163, 1, 247, 160, 193, 163, 1, 238, 32, 193, 163, 1, 231, - 240, 193, 163, 1, 170, 193, 163, 1, 209, 228, 193, 163, 1, 173, 193, 163, - 1, 180, 193, 163, 1, 168, 193, 163, 1, 190, 190, 193, 163, 1, 199, 49, - 193, 163, 1, 233, 109, 193, 163, 1, 188, 193, 163, 1, 203, 165, 193, 163, - 1, 223, 32, 193, 163, 1, 191, 123, 193, 163, 1, 193, 190, 193, 163, 1, - 195, 188, 193, 163, 1, 155, 193, 163, 1, 74, 193, 163, 1, 250, 163, 193, - 163, 1, 165, 193, 163, 1, 174, 193, 163, 1, 221, 215, 193, 163, 1, 140, - 193, 163, 1, 71, 193, 163, 1, 68, 193, 163, 1, 214, 68, 193, 163, 1, 66, - 193, 163, 1, 219, 66, 193, 163, 1, 197, 168, 193, 163, 1, 198, 26, 193, - 163, 1, 211, 94, 193, 163, 1, 252, 165, 193, 163, 1, 251, 122, 193, 163, - 1, 223, 136, 193, 163, 1, 211, 104, 193, 163, 1, 234, 103, 193, 163, 1, - 252, 166, 193, 163, 1, 212, 101, 193, 163, 1, 196, 147, 193, 163, 1, 192, - 24, 193, 163, 163, 197, 67, 193, 163, 163, 197, 66, 193, 163, 163, 221, - 54, 193, 163, 163, 221, 53, 193, 163, 17, 191, 77, 193, 163, 17, 107, - 193, 163, 17, 109, 193, 163, 17, 138, 193, 163, 17, 134, 193, 163, 17, - 149, 193, 163, 17, 169, 193, 163, 17, 175, 193, 163, 17, 171, 193, 163, - 17, 178, 193, 163, 213, 232, 56, 214, 243, 215, 120, 1, 74, 214, 243, - 215, 120, 1, 211, 78, 214, 243, 215, 120, 1, 211, 120, 214, 243, 215, - 120, 1, 210, 242, 214, 243, 215, 120, 1, 211, 94, 214, 243, 215, 120, 1, - 65, 214, 243, 215, 120, 1, 251, 218, 214, 243, 215, 120, 1, 252, 155, - 214, 243, 215, 120, 1, 251, 69, 214, 243, 215, 120, 1, 251, 245, 214, - 243, 215, 120, 1, 68, 214, 243, 215, 120, 1, 223, 68, 214, 243, 215, 120, - 1, 228, 18, 214, 243, 215, 120, 1, 223, 53, 214, 243, 215, 120, 1, 223, - 200, 214, 243, 215, 120, 1, 66, 214, 243, 215, 120, 1, 196, 160, 214, - 243, 215, 120, 1, 196, 158, 214, 243, 215, 120, 1, 196, 128, 214, 243, - 215, 120, 1, 196, 62, 214, 243, 215, 120, 1, 71, 214, 243, 215, 120, 1, - 234, 85, 214, 243, 215, 120, 1, 234, 180, 214, 243, 215, 120, 1, 234, - 114, 214, 243, 215, 120, 1, 234, 103, 214, 243, 215, 120, 1, 233, 245, - 214, 243, 215, 120, 1, 234, 122, 214, 243, 215, 120, 3, 211, 127, 214, - 243, 215, 120, 3, 215, 138, 214, 243, 215, 120, 3, 198, 28, 214, 243, - 215, 120, 3, 223, 193, 214, 243, 215, 120, 3, 200, 161, 214, 243, 215, - 120, 17, 191, 77, 214, 243, 215, 120, 17, 107, 214, 243, 215, 120, 17, - 109, 214, 243, 215, 120, 17, 138, 214, 243, 215, 120, 17, 134, 214, 243, - 215, 120, 17, 149, 214, 243, 215, 120, 17, 169, 214, 243, 215, 120, 17, - 175, 214, 243, 215, 120, 17, 171, 214, 243, 215, 120, 17, 178, 36, 5, - 229, 166, 36, 5, 229, 160, 36, 5, 229, 162, 36, 5, 229, 165, 36, 5, 229, - 163, 36, 5, 229, 164, 36, 5, 229, 161, 36, 5, 230, 147, 229, 170, 36, 5, - 229, 167, 36, 5, 229, 168, 36, 5, 229, 169, 36, 5, 230, 147, 215, 76, 36, - 5, 230, 147, 215, 77, 36, 5, 230, 147, 207, 236, 36, 5, 230, 147, 207, - 237, 36, 5, 230, 147, 207, 238, 36, 5, 230, 147, 247, 207, 36, 5, 230, - 147, 247, 208, 36, 5, 230, 147, 220, 172, 36, 5, 230, 147, 220, 173, 36, - 5, 230, 147, 220, 174, 36, 5, 230, 147, 230, 131, 36, 5, 230, 147, 230, - 132, 36, 5, 230, 147, 230, 133, 36, 5, 230, 147, 232, 58, 36, 5, 230, - 147, 232, 59, 36, 5, 230, 147, 208, 118, 36, 5, 230, 147, 208, 119, 85, - 84, 5, 218, 167, 221, 166, 85, 84, 5, 218, 163, 155, 85, 84, 5, 218, 161, - 220, 232, 85, 84, 5, 218, 37, 222, 13, 85, 84, 5, 218, 7, 222, 22, 85, - 84, 5, 218, 26, 221, 41, 85, 84, 5, 218, 54, 221, 67, 85, 84, 5, 217, - 179, 220, 219, 85, 84, 5, 218, 158, 193, 86, 85, 84, 5, 218, 156, 193, - 190, 85, 84, 5, 218, 154, 193, 0, 85, 84, 5, 217, 232, 193, 114, 85, 84, - 5, 217, 240, 193, 125, 85, 84, 5, 217, 244, 193, 29, 85, 84, 5, 218, 57, - 193, 48, 85, 84, 5, 217, 164, 192, 252, 85, 84, 5, 217, 215, 193, 112, - 85, 84, 5, 218, 41, 192, 240, 85, 84, 5, 218, 53, 192, 242, 85, 84, 5, - 217, 219, 192, 241, 85, 84, 5, 218, 152, 216, 44, 85, 84, 5, 218, 150, - 217, 90, 85, 84, 5, 218, 148, 215, 122, 85, 84, 5, 218, 43, 216, 186, 85, - 84, 5, 218, 8, 215, 231, 85, 84, 5, 217, 204, 215, 148, 85, 84, 5, 217, - 169, 215, 142, 85, 84, 5, 218, 146, 248, 188, 85, 84, 5, 218, 143, 249, - 153, 85, 84, 5, 218, 141, 248, 10, 85, 84, 5, 217, 208, 249, 1, 85, 84, - 5, 218, 5, 249, 17, 85, 84, 5, 217, 255, 248, 97, 85, 84, 5, 217, 220, - 248, 111, 85, 84, 5, 218, 131, 68, 85, 84, 5, 218, 129, 65, 85, 84, 5, - 218, 127, 66, 85, 84, 5, 217, 195, 234, 188, 85, 84, 5, 218, 2, 71, 85, - 84, 5, 217, 193, 211, 87, 85, 84, 5, 217, 211, 74, 85, 84, 5, 217, 221, - 234, 166, 85, 84, 5, 217, 227, 223, 162, 85, 84, 5, 217, 223, 223, 162, - 85, 84, 5, 217, 163, 251, 132, 85, 84, 5, 217, 180, 234, 103, 85, 84, 5, - 218, 116, 202, 222, 85, 84, 5, 218, 114, 188, 85, 84, 5, 218, 112, 201, - 4, 85, 84, 5, 217, 196, 205, 50, 85, 84, 5, 217, 242, 205, 68, 85, 84, 5, - 217, 222, 202, 16, 85, 84, 5, 218, 23, 202, 46, 85, 84, 5, 217, 162, 202, - 215, 85, 84, 5, 218, 102, 219, 146, 85, 84, 5, 218, 100, 173, 85, 84, 5, - 218, 98, 218, 225, 85, 84, 5, 218, 18, 219, 228, 85, 84, 5, 218, 29, 219, - 238, 85, 84, 5, 218, 48, 219, 8, 85, 84, 5, 217, 205, 219, 43, 85, 84, 5, - 217, 248, 179, 219, 238, 85, 84, 5, 218, 124, 237, 44, 85, 84, 5, 218, - 121, 238, 32, 85, 84, 5, 218, 118, 235, 89, 85, 84, 5, 218, 13, 237, 131, - 85, 84, 5, 217, 178, 236, 146, 85, 84, 5, 217, 177, 236, 174, 85, 84, 5, - 218, 110, 198, 193, 85, 84, 5, 218, 107, 190, 190, 85, 84, 5, 218, 105, - 197, 94, 85, 84, 5, 218, 11, 199, 121, 85, 84, 5, 218, 47, 199, 145, 85, - 84, 5, 217, 254, 198, 59, 85, 84, 5, 218, 33, 159, 85, 84, 5, 218, 96, - 222, 244, 85, 84, 5, 218, 93, 223, 32, 85, 84, 5, 218, 91, 222, 182, 85, - 84, 5, 217, 201, 223, 8, 85, 84, 5, 217, 245, 223, 10, 85, 84, 5, 217, - 198, 222, 191, 85, 84, 5, 218, 39, 222, 201, 85, 84, 5, 217, 183, 179, - 222, 201, 85, 84, 5, 218, 89, 192, 33, 85, 84, 5, 218, 86, 170, 85, 84, - 5, 218, 84, 191, 225, 85, 84, 5, 217, 249, 192, 77, 85, 84, 5, 218, 22, - 192, 80, 85, 84, 5, 217, 217, 191, 246, 85, 84, 5, 217, 237, 192, 12, 85, - 84, 5, 218, 80, 233, 23, 85, 84, 5, 218, 78, 233, 109, 85, 84, 5, 218, - 76, 232, 86, 85, 84, 5, 218, 24, 233, 52, 85, 84, 5, 218, 27, 233, 59, - 85, 84, 5, 217, 225, 232, 162, 85, 84, 5, 218, 14, 232, 175, 85, 84, 5, - 217, 161, 232, 85, 85, 84, 5, 218, 1, 233, 80, 85, 84, 5, 218, 74, 213, - 179, 85, 84, 5, 218, 72, 214, 226, 85, 84, 5, 218, 70, 212, 130, 85, 84, - 5, 217, 241, 214, 102, 85, 84, 5, 217, 189, 213, 31, 85, 84, 5, 217, 182, - 229, 158, 85, 84, 5, 218, 65, 140, 85, 84, 5, 217, 172, 228, 159, 85, 84, - 5, 218, 68, 229, 215, 85, 84, 5, 218, 6, 229, 245, 85, 84, 5, 218, 63, - 228, 252, 85, 84, 5, 217, 218, 229, 23, 85, 84, 5, 218, 19, 229, 214, 85, - 84, 5, 217, 230, 228, 245, 85, 84, 5, 218, 49, 229, 128, 85, 84, 5, 217, - 228, 230, 56, 85, 84, 5, 218, 15, 228, 142, 85, 84, 5, 218, 50, 229, 198, - 85, 84, 5, 217, 165, 228, 255, 85, 84, 5, 218, 56, 228, 155, 85, 84, 5, - 218, 12, 214, 33, 85, 84, 5, 218, 61, 214, 47, 85, 84, 5, 218, 20, 214, - 30, 85, 84, 5, 217, 243, 214, 41, 85, 84, 5, 217, 212, 214, 42, 85, 84, - 5, 217, 202, 214, 31, 85, 84, 5, 217, 238, 214, 32, 85, 84, 5, 217, 199, - 214, 46, 85, 84, 5, 217, 231, 214, 29, 85, 84, 5, 218, 16, 179, 214, 42, - 85, 84, 5, 217, 252, 179, 214, 31, 85, 84, 5, 217, 175, 179, 214, 32, 85, - 84, 5, 217, 203, 231, 53, 85, 84, 5, 217, 247, 231, 240, 85, 84, 5, 217, - 190, 230, 179, 85, 84, 5, 217, 168, 231, 157, 85, 84, 5, 217, 192, 230, - 165, 85, 84, 5, 217, 191, 230, 175, 85, 84, 5, 217, 174, 214, 52, 85, 84, - 5, 218, 45, 213, 245, 85, 84, 5, 217, 181, 213, 234, 85, 84, 5, 218, 34, - 209, 185, 85, 84, 5, 218, 3, 168, 85, 84, 5, 218, 52, 208, 165, 85, 84, - 5, 218, 21, 210, 49, 85, 84, 5, 218, 51, 210, 63, 85, 84, 5, 218, 0, 209, - 37, 85, 84, 5, 218, 36, 209, 73, 85, 84, 5, 217, 213, 216, 252, 85, 84, - 5, 218, 40, 217, 11, 85, 84, 5, 217, 236, 216, 246, 85, 84, 5, 218, 55, - 217, 3, 85, 84, 5, 217, 170, 217, 3, 85, 84, 5, 218, 30, 217, 4, 85, 84, - 5, 217, 186, 216, 247, 85, 84, 5, 217, 184, 216, 248, 85, 84, 5, 217, - 171, 216, 240, 85, 84, 5, 217, 197, 179, 217, 4, 85, 84, 5, 217, 253, - 179, 216, 247, 85, 84, 5, 217, 216, 179, 216, 248, 85, 84, 5, 217, 226, - 221, 13, 85, 84, 5, 218, 10, 221, 21, 85, 84, 5, 218, 28, 221, 9, 85, 84, - 5, 218, 59, 221, 16, 85, 84, 5, 217, 250, 221, 17, 85, 84, 5, 217, 246, - 221, 11, 85, 84, 5, 217, 200, 221, 12, 85, 84, 5, 217, 234, 231, 174, 85, - 84, 5, 218, 46, 231, 182, 85, 84, 5, 217, 210, 231, 169, 85, 84, 5, 218, - 9, 231, 178, 85, 84, 5, 217, 251, 231, 179, 85, 84, 5, 218, 31, 231, 170, - 85, 84, 5, 218, 32, 231, 172, 85, 84, 5, 217, 187, 165, 85, 84, 5, 217, - 235, 214, 147, 85, 84, 5, 217, 229, 214, 162, 85, 84, 5, 217, 233, 214, - 129, 85, 84, 5, 217, 167, 214, 153, 85, 84, 5, 217, 239, 214, 154, 85, - 84, 5, 218, 35, 214, 134, 85, 84, 5, 218, 38, 214, 138, 85, 84, 5, 217, - 206, 213, 157, 85, 84, 5, 217, 166, 213, 127, 85, 84, 5, 217, 209, 213, - 148, 85, 84, 5, 217, 224, 213, 131, 85, 84, 5, 217, 176, 195, 69, 85, 84, - 5, 217, 173, 195, 188, 85, 84, 5, 217, 207, 193, 249, 85, 84, 5, 217, - 185, 195, 148, 85, 84, 5, 218, 17, 195, 153, 85, 84, 5, 217, 214, 195, 8, - 85, 84, 5, 218, 25, 195, 24, 85, 84, 5, 217, 194, 212, 74, 85, 84, 5, - 218, 44, 212, 94, 85, 84, 5, 217, 188, 212, 56, 85, 84, 5, 218, 4, 212, - 86, 85, 84, 5, 218, 42, 212, 63, 85, 84, 17, 107, 85, 84, 17, 109, 85, - 84, 17, 138, 85, 84, 17, 134, 85, 84, 17, 149, 85, 84, 17, 169, 85, 84, - 17, 175, 85, 84, 17, 171, 85, 84, 17, 178, 85, 84, 33, 31, 199, 119, 85, - 84, 33, 31, 199, 90, 85, 84, 33, 31, 228, 138, 85, 84, 33, 31, 198, 228, - 85, 84, 33, 31, 199, 96, 198, 228, 85, 84, 33, 31, 228, 141, 198, 228, - 85, 84, 33, 31, 216, 47, 252, 33, 6, 1, 251, 180, 252, 33, 6, 1, 238, 29, - 252, 33, 6, 1, 220, 123, 252, 33, 6, 1, 216, 60, 252, 33, 6, 1, 249, 153, - 252, 33, 6, 1, 202, 164, 252, 33, 6, 1, 210, 63, 252, 33, 6, 1, 248, 196, - 252, 33, 6, 1, 165, 252, 33, 6, 1, 71, 252, 33, 6, 1, 233, 109, 252, 33, - 6, 1, 68, 252, 33, 6, 1, 74, 252, 33, 6, 1, 237, 68, 252, 33, 6, 1, 192, - 34, 252, 33, 6, 1, 193, 133, 252, 33, 6, 1, 212, 130, 252, 33, 6, 1, 222, - 106, 252, 33, 6, 1, 170, 252, 33, 6, 1, 66, 252, 33, 6, 1, 222, 235, 252, - 33, 6, 1, 243, 95, 252, 33, 6, 1, 140, 252, 33, 6, 1, 208, 94, 252, 33, - 6, 1, 231, 240, 252, 33, 6, 1, 212, 101, 252, 33, 6, 1, 197, 94, 252, 33, - 6, 1, 213, 224, 252, 33, 6, 1, 195, 188, 252, 33, 6, 1, 221, 215, 252, - 33, 6, 1, 231, 179, 252, 33, 6, 1, 191, 108, 252, 33, 6, 1, 221, 12, 252, - 33, 6, 1, 203, 165, 252, 33, 2, 1, 251, 180, 252, 33, 2, 1, 238, 29, 252, - 33, 2, 1, 220, 123, 252, 33, 2, 1, 216, 60, 252, 33, 2, 1, 249, 153, 252, - 33, 2, 1, 202, 164, 252, 33, 2, 1, 210, 63, 252, 33, 2, 1, 248, 196, 252, - 33, 2, 1, 165, 252, 33, 2, 1, 71, 252, 33, 2, 1, 233, 109, 252, 33, 2, 1, - 68, 252, 33, 2, 1, 74, 252, 33, 2, 1, 237, 68, 252, 33, 2, 1, 192, 34, - 252, 33, 2, 1, 193, 133, 252, 33, 2, 1, 212, 130, 252, 33, 2, 1, 222, - 106, 252, 33, 2, 1, 170, 252, 33, 2, 1, 66, 252, 33, 2, 1, 222, 235, 252, - 33, 2, 1, 243, 95, 252, 33, 2, 1, 140, 252, 33, 2, 1, 208, 94, 252, 33, - 2, 1, 231, 240, 252, 33, 2, 1, 212, 101, 252, 33, 2, 1, 197, 94, 252, 33, - 2, 1, 213, 224, 252, 33, 2, 1, 195, 188, 252, 33, 2, 1, 221, 215, 252, - 33, 2, 1, 231, 179, 252, 33, 2, 1, 191, 108, 252, 33, 2, 1, 221, 12, 252, - 33, 2, 1, 203, 165, 252, 33, 251, 181, 219, 190, 252, 33, 18, 219, 190, - 252, 33, 231, 153, 77, 252, 33, 230, 57, 252, 33, 120, 215, 252, 252, 33, - 231, 154, 120, 215, 252, 252, 33, 212, 141, 252, 33, 214, 213, 77, 252, - 33, 17, 191, 77, 252, 33, 17, 107, 252, 33, 17, 109, 252, 33, 17, 138, - 252, 33, 17, 134, 252, 33, 17, 149, 252, 33, 17, 169, 252, 33, 17, 175, - 252, 33, 17, 171, 252, 33, 17, 178, 252, 33, 89, 233, 216, 77, 252, 33, - 89, 208, 13, 77, 223, 146, 143, 31, 107, 223, 146, 143, 31, 109, 223, - 146, 143, 31, 138, 223, 146, 143, 31, 134, 223, 146, 143, 31, 149, 223, - 146, 143, 31, 169, 223, 146, 143, 31, 175, 223, 146, 143, 31, 171, 223, - 146, 143, 31, 178, 223, 146, 143, 31, 199, 95, 223, 146, 143, 31, 197, - 32, 223, 146, 143, 31, 198, 249, 223, 146, 143, 31, 232, 135, 223, 146, - 143, 31, 233, 15, 223, 146, 143, 31, 202, 120, 223, 146, 143, 31, 203, - 241, 223, 146, 143, 31, 234, 153, 223, 146, 143, 31, 213, 169, 223, 146, - 143, 31, 91, 228, 140, 223, 146, 143, 31, 105, 228, 140, 223, 146, 143, - 31, 115, 228, 140, 223, 146, 143, 31, 232, 128, 228, 140, 223, 146, 143, - 31, 232, 226, 228, 140, 223, 146, 143, 31, 202, 136, 228, 140, 223, 146, - 143, 31, 203, 247, 228, 140, 223, 146, 143, 31, 234, 164, 228, 140, 223, - 146, 143, 31, 213, 175, 228, 140, 223, 146, 143, 31, 91, 189, 223, 146, - 143, 31, 105, 189, 223, 146, 143, 31, 115, 189, 223, 146, 143, 31, 232, - 128, 189, 223, 146, 143, 31, 232, 226, 189, 223, 146, 143, 31, 202, 136, - 189, 223, 146, 143, 31, 203, 247, 189, 223, 146, 143, 31, 234, 164, 189, - 223, 146, 143, 31, 213, 175, 189, 223, 146, 143, 31, 199, 96, 189, 223, - 146, 143, 31, 197, 33, 189, 223, 146, 143, 31, 198, 250, 189, 223, 146, - 143, 31, 232, 136, 189, 223, 146, 143, 31, 233, 16, 189, 223, 146, 143, - 31, 202, 121, 189, 223, 146, 143, 31, 203, 242, 189, 223, 146, 143, 31, - 234, 154, 189, 223, 146, 143, 31, 213, 170, 189, 223, 146, 143, 31, 220, - 41, 223, 146, 143, 31, 220, 40, 223, 146, 143, 220, 42, 77, 223, 146, - 143, 31, 222, 60, 223, 146, 143, 31, 222, 59, 223, 146, 143, 31, 208, - 227, 107, 223, 146, 143, 31, 208, 227, 109, 223, 146, 143, 31, 208, 227, - 138, 223, 146, 143, 31, 208, 227, 134, 223, 146, 143, 31, 208, 227, 149, - 223, 146, 143, 31, 208, 227, 169, 223, 146, 143, 31, 208, 227, 175, 223, - 146, 143, 31, 208, 227, 171, 223, 146, 143, 31, 208, 227, 178, 223, 146, - 143, 209, 106, 223, 146, 143, 232, 118, 91, 208, 22, 223, 146, 143, 232, - 118, 91, 230, 70, 223, 146, 143, 232, 118, 115, 208, 20, 223, 146, 143, - 206, 36, 77, 223, 146, 143, 31, 251, 157, 107, 223, 146, 143, 31, 251, - 157, 109, 223, 146, 143, 31, 251, 157, 199, 96, 189, 223, 146, 143, 251, - 157, 220, 42, 77, 211, 21, 143, 31, 107, 211, 21, 143, 31, 109, 211, 21, - 143, 31, 138, 211, 21, 143, 31, 134, 211, 21, 143, 31, 149, 211, 21, 143, - 31, 169, 211, 21, 143, 31, 175, 211, 21, 143, 31, 171, 211, 21, 143, 31, - 178, 211, 21, 143, 31, 199, 95, 211, 21, 143, 31, 197, 32, 211, 21, 143, - 31, 198, 249, 211, 21, 143, 31, 232, 135, 211, 21, 143, 31, 233, 15, 211, - 21, 143, 31, 202, 120, 211, 21, 143, 31, 203, 241, 211, 21, 143, 31, 234, - 153, 211, 21, 143, 31, 213, 169, 211, 21, 143, 31, 91, 228, 140, 211, 21, - 143, 31, 105, 228, 140, 211, 21, 143, 31, 115, 228, 140, 211, 21, 143, - 31, 232, 128, 228, 140, 211, 21, 143, 31, 232, 226, 228, 140, 211, 21, - 143, 31, 202, 136, 228, 140, 211, 21, 143, 31, 203, 247, 228, 140, 211, - 21, 143, 31, 234, 164, 228, 140, 211, 21, 143, 31, 213, 175, 228, 140, - 211, 21, 143, 31, 91, 189, 211, 21, 143, 31, 105, 189, 211, 21, 143, 31, - 115, 189, 211, 21, 143, 31, 232, 128, 189, 211, 21, 143, 31, 232, 226, - 189, 211, 21, 143, 31, 202, 136, 189, 211, 21, 143, 31, 203, 247, 189, - 211, 21, 143, 31, 234, 164, 189, 211, 21, 143, 31, 213, 175, 189, 211, - 21, 143, 31, 199, 96, 189, 211, 21, 143, 31, 197, 33, 189, 211, 21, 143, - 31, 198, 250, 189, 211, 21, 143, 31, 232, 136, 189, 211, 21, 143, 31, - 233, 16, 189, 211, 21, 143, 31, 202, 121, 189, 211, 21, 143, 31, 203, - 242, 189, 211, 21, 143, 31, 234, 154, 189, 211, 21, 143, 31, 213, 170, - 189, 211, 21, 143, 217, 49, 211, 21, 143, 251, 157, 31, 109, 211, 21, - 143, 251, 157, 31, 138, 211, 21, 143, 251, 157, 31, 134, 211, 21, 143, - 251, 157, 31, 149, 211, 21, 143, 251, 157, 31, 169, 211, 21, 143, 251, - 157, 31, 175, 211, 21, 143, 251, 157, 31, 171, 211, 21, 143, 251, 157, - 31, 178, 211, 21, 143, 251, 157, 31, 199, 95, 211, 21, 143, 251, 157, 31, - 232, 128, 228, 140, 211, 21, 143, 251, 157, 31, 202, 136, 228, 140, 211, - 21, 143, 251, 157, 31, 105, 189, 211, 21, 143, 251, 157, 31, 199, 96, - 189, 211, 21, 143, 232, 118, 91, 230, 70, 211, 21, 143, 232, 118, 91, - 202, 124, 9, 13, 251, 192, 9, 13, 248, 245, 9, 13, 223, 6, 9, 13, 238, 3, - 9, 13, 193, 133, 9, 13, 191, 113, 9, 13, 230, 81, 9, 13, 199, 219, 9, 13, - 192, 75, 9, 13, 222, 106, 9, 13, 220, 35, 9, 13, 216, 208, 9, 13, 213, - 24, 9, 13, 205, 46, 9, 13, 251, 230, 9, 13, 233, 46, 9, 13, 205, 192, 9, - 13, 208, 89, 9, 13, 207, 71, 9, 13, 203, 109, 9, 13, 199, 114, 9, 13, - 199, 29, 9, 13, 221, 210, 9, 13, 199, 41, 9, 13, 238, 26, 9, 13, 191, - 116, 9, 13, 231, 86, 9, 13, 236, 139, 248, 245, 9, 13, 236, 139, 213, 24, - 9, 13, 236, 139, 233, 46, 9, 13, 236, 139, 208, 89, 9, 13, 89, 248, 245, - 9, 13, 89, 223, 6, 9, 13, 89, 229, 210, 9, 13, 89, 230, 81, 9, 13, 89, - 192, 75, 9, 13, 89, 222, 106, 9, 13, 89, 220, 35, 9, 13, 89, 216, 208, 9, - 13, 89, 213, 24, 9, 13, 89, 205, 46, 9, 13, 89, 251, 230, 9, 13, 89, 233, - 46, 9, 13, 89, 205, 192, 9, 13, 89, 208, 89, 9, 13, 89, 203, 109, 9, 13, - 89, 199, 114, 9, 13, 89, 199, 29, 9, 13, 89, 221, 210, 9, 13, 89, 238, - 26, 9, 13, 89, 231, 86, 9, 13, 199, 214, 223, 6, 9, 13, 199, 214, 230, - 81, 9, 13, 199, 214, 192, 75, 9, 13, 199, 214, 220, 35, 9, 13, 199, 214, - 213, 24, 9, 13, 199, 214, 205, 46, 9, 13, 199, 214, 251, 230, 9, 13, 199, - 214, 205, 192, 9, 13, 199, 214, 208, 89, 9, 13, 199, 214, 203, 109, 9, - 13, 199, 214, 221, 210, 9, 13, 199, 214, 238, 26, 9, 13, 199, 214, 231, - 86, 9, 13, 199, 214, 236, 139, 213, 24, 9, 13, 199, 214, 236, 139, 208, - 89, 9, 13, 201, 36, 248, 245, 9, 13, 201, 36, 223, 6, 9, 13, 201, 36, - 229, 210, 9, 13, 201, 36, 230, 81, 9, 13, 201, 36, 199, 219, 9, 13, 201, - 36, 192, 75, 9, 13, 201, 36, 222, 106, 9, 13, 201, 36, 216, 208, 9, 13, - 201, 36, 213, 24, 9, 13, 201, 36, 205, 46, 9, 13, 201, 36, 251, 230, 9, - 13, 201, 36, 233, 46, 9, 13, 201, 36, 205, 192, 9, 13, 201, 36, 208, 89, - 9, 13, 201, 36, 203, 109, 9, 13, 201, 36, 199, 114, 9, 13, 201, 36, 199, - 29, 9, 13, 201, 36, 221, 210, 9, 13, 201, 36, 238, 26, 9, 13, 201, 36, - 191, 116, 9, 13, 201, 36, 231, 86, 9, 13, 201, 36, 236, 139, 248, 245, 9, - 13, 201, 36, 236, 139, 233, 46, 9, 13, 219, 3, 251, 192, 9, 13, 219, 3, - 248, 245, 9, 13, 219, 3, 223, 6, 9, 13, 219, 3, 238, 3, 9, 13, 219, 3, - 229, 210, 9, 13, 219, 3, 193, 133, 9, 13, 219, 3, 191, 113, 9, 13, 219, - 3, 230, 81, 9, 13, 219, 3, 199, 219, 9, 13, 219, 3, 192, 75, 9, 13, 219, - 3, 220, 35, 9, 13, 219, 3, 216, 208, 9, 13, 219, 3, 213, 24, 9, 13, 219, - 3, 205, 46, 9, 13, 219, 3, 251, 230, 9, 13, 219, 3, 233, 46, 9, 13, 219, - 3, 205, 192, 9, 13, 219, 3, 208, 89, 9, 13, 219, 3, 207, 71, 9, 13, 219, - 3, 203, 109, 9, 13, 219, 3, 199, 114, 9, 13, 219, 3, 199, 29, 9, 13, 219, - 3, 221, 210, 9, 13, 219, 3, 199, 41, 9, 13, 219, 3, 238, 26, 9, 13, 219, - 3, 191, 116, 9, 13, 219, 3, 231, 86, 9, 13, 235, 129, 248, 245, 9, 13, - 235, 129, 223, 6, 9, 13, 235, 129, 238, 3, 9, 13, 235, 129, 193, 133, 9, - 13, 235, 129, 191, 113, 9, 13, 235, 129, 230, 81, 9, 13, 235, 129, 199, - 219, 9, 13, 235, 129, 192, 75, 9, 13, 235, 129, 220, 35, 9, 13, 235, 129, - 216, 208, 9, 13, 235, 129, 213, 24, 9, 13, 235, 129, 205, 46, 9, 13, 235, - 129, 251, 230, 9, 13, 235, 129, 233, 46, 9, 13, 235, 129, 205, 192, 9, - 13, 235, 129, 208, 89, 9, 13, 235, 129, 207, 71, 9, 13, 235, 129, 203, - 109, 9, 13, 235, 129, 199, 114, 9, 13, 235, 129, 199, 29, 9, 13, 235, - 129, 221, 210, 9, 13, 235, 129, 199, 41, 9, 13, 235, 129, 238, 26, 9, 13, - 235, 129, 191, 116, 9, 13, 235, 129, 231, 86, 9, 13, 211, 67, 92, 4, 182, - 4, 199, 168, 9, 13, 211, 67, 182, 4, 238, 3, 217, 114, 123, 234, 204, - 193, 66, 217, 114, 123, 202, 2, 193, 66, 217, 114, 123, 193, 105, 193, - 66, 217, 114, 123, 186, 193, 66, 217, 114, 123, 207, 87, 235, 111, 217, - 114, 123, 230, 201, 235, 111, 217, 114, 123, 63, 235, 111, 217, 114, 123, - 91, 79, 243, 140, 217, 114, 123, 105, 79, 243, 140, 217, 114, 123, 115, - 79, 243, 140, 217, 114, 123, 232, 128, 79, 243, 140, 217, 114, 123, 232, - 226, 79, 243, 140, 217, 114, 123, 202, 136, 79, 243, 140, 217, 114, 123, - 203, 247, 79, 243, 140, 217, 114, 123, 234, 164, 79, 243, 140, 217, 114, - 123, 213, 175, 79, 243, 140, 217, 114, 123, 91, 79, 249, 102, 217, 114, - 123, 105, 79, 249, 102, 217, 114, 123, 115, 79, 249, 102, 217, 114, 123, - 232, 128, 79, 249, 102, 217, 114, 123, 232, 226, 79, 249, 102, 217, 114, - 123, 202, 136, 79, 249, 102, 217, 114, 123, 203, 247, 79, 249, 102, 217, - 114, 123, 234, 164, 79, 249, 102, 217, 114, 123, 213, 175, 79, 249, 102, - 217, 114, 123, 91, 79, 243, 7, 217, 114, 123, 105, 79, 243, 7, 217, 114, - 123, 115, 79, 243, 7, 217, 114, 123, 232, 128, 79, 243, 7, 217, 114, 123, - 232, 226, 79, 243, 7, 217, 114, 123, 202, 136, 79, 243, 7, 217, 114, 123, - 203, 247, 79, 243, 7, 217, 114, 123, 234, 164, 79, 243, 7, 217, 114, 123, - 213, 175, 79, 243, 7, 217, 114, 123, 209, 85, 217, 114, 123, 211, 53, - 217, 114, 123, 249, 103, 217, 114, 123, 243, 49, 217, 114, 123, 201, 196, - 217, 114, 123, 200, 200, 217, 114, 123, 250, 149, 217, 114, 123, 193, 56, - 217, 114, 123, 222, 194, 217, 114, 123, 249, 146, 236, 151, 123, 228, - 241, 249, 146, 236, 151, 123, 228, 239, 236, 151, 123, 228, 238, 236, - 151, 123, 228, 237, 236, 151, 123, 228, 236, 236, 151, 123, 228, 235, - 236, 151, 123, 228, 234, 236, 151, 123, 228, 233, 236, 151, 123, 228, - 232, 236, 151, 123, 228, 231, 236, 151, 123, 228, 230, 236, 151, 123, - 228, 229, 236, 151, 123, 228, 228, 236, 151, 123, 228, 227, 236, 151, - 123, 228, 226, 236, 151, 123, 228, 225, 236, 151, 123, 228, 224, 236, - 151, 123, 228, 223, 236, 151, 123, 228, 222, 236, 151, 123, 228, 221, - 236, 151, 123, 228, 220, 236, 151, 123, 228, 219, 236, 151, 123, 228, - 218, 236, 151, 123, 228, 217, 236, 151, 123, 228, 216, 236, 151, 123, - 228, 215, 236, 151, 123, 228, 214, 236, 151, 123, 228, 213, 236, 151, - 123, 228, 212, 236, 151, 123, 228, 211, 236, 151, 123, 228, 210, 236, - 151, 123, 228, 209, 236, 151, 123, 228, 208, 236, 151, 123, 228, 207, - 236, 151, 123, 228, 206, 236, 151, 123, 228, 205, 236, 151, 123, 228, - 204, 236, 151, 123, 228, 203, 236, 151, 123, 228, 202, 236, 151, 123, - 228, 201, 236, 151, 123, 228, 200, 236, 151, 123, 228, 199, 236, 151, - 123, 228, 198, 236, 151, 123, 228, 197, 236, 151, 123, 228, 196, 236, - 151, 123, 228, 195, 236, 151, 123, 228, 194, 236, 151, 123, 228, 193, - 236, 151, 123, 228, 192, 236, 151, 123, 228, 191, 236, 151, 123, 81, 249, - 146, 236, 151, 123, 195, 134, 236, 151, 123, 195, 133, 236, 151, 123, - 195, 132, 236, 151, 123, 195, 131, 236, 151, 123, 195, 130, 236, 151, - 123, 195, 129, 236, 151, 123, 195, 128, 236, 151, 123, 195, 127, 236, - 151, 123, 195, 126, 236, 151, 123, 195, 125, 236, 151, 123, 195, 124, - 236, 151, 123, 195, 123, 236, 151, 123, 195, 122, 236, 151, 123, 195, - 121, 236, 151, 123, 195, 120, 236, 151, 123, 195, 119, 236, 151, 123, - 195, 118, 236, 151, 123, 195, 117, 236, 151, 123, 195, 116, 236, 151, - 123, 195, 115, 236, 151, 123, 195, 114, 236, 151, 123, 195, 113, 236, - 151, 123, 195, 112, 236, 151, 123, 195, 111, 236, 151, 123, 195, 110, - 236, 151, 123, 195, 109, 236, 151, 123, 195, 108, 236, 151, 123, 195, - 107, 236, 151, 123, 195, 106, 236, 151, 123, 195, 105, 236, 151, 123, - 195, 104, 236, 151, 123, 195, 103, 236, 151, 123, 195, 102, 236, 151, - 123, 195, 101, 236, 151, 123, 195, 100, 236, 151, 123, 195, 99, 236, 151, - 123, 195, 98, 236, 151, 123, 195, 97, 236, 151, 123, 195, 96, 236, 151, - 123, 195, 95, 236, 151, 123, 195, 94, 236, 151, 123, 195, 93, 236, 151, - 123, 195, 92, 236, 151, 123, 195, 91, 236, 151, 123, 195, 90, 236, 151, - 123, 195, 89, 236, 151, 123, 195, 88, 236, 151, 123, 195, 87, 236, 151, - 123, 195, 86, 209, 95, 247, 101, 249, 146, 209, 95, 247, 101, 252, 53, - 79, 201, 244, 209, 95, 247, 101, 105, 79, 201, 244, 209, 95, 247, 101, - 115, 79, 201, 244, 209, 95, 247, 101, 232, 128, 79, 201, 244, 209, 95, - 247, 101, 232, 226, 79, 201, 244, 209, 95, 247, 101, 202, 136, 79, 201, - 244, 209, 95, 247, 101, 203, 247, 79, 201, 244, 209, 95, 247, 101, 234, - 164, 79, 201, 244, 209, 95, 247, 101, 213, 175, 79, 201, 244, 209, 95, - 247, 101, 199, 96, 79, 201, 244, 209, 95, 247, 101, 223, 30, 79, 201, - 244, 209, 95, 247, 101, 221, 77, 79, 201, 244, 209, 95, 247, 101, 208, - 15, 79, 201, 244, 209, 95, 247, 101, 221, 139, 79, 201, 244, 209, 95, - 247, 101, 252, 53, 79, 229, 221, 209, 95, 247, 101, 105, 79, 229, 221, - 209, 95, 247, 101, 115, 79, 229, 221, 209, 95, 247, 101, 232, 128, 79, - 229, 221, 209, 95, 247, 101, 232, 226, 79, 229, 221, 209, 95, 247, 101, - 202, 136, 79, 229, 221, 209, 95, 247, 101, 203, 247, 79, 229, 221, 209, - 95, 247, 101, 234, 164, 79, 229, 221, 209, 95, 247, 101, 213, 175, 79, - 229, 221, 209, 95, 247, 101, 199, 96, 79, 229, 221, 209, 95, 247, 101, - 223, 30, 79, 229, 221, 209, 95, 247, 101, 221, 77, 79, 229, 221, 209, 95, - 247, 101, 208, 15, 79, 229, 221, 209, 95, 247, 101, 221, 139, 79, 229, - 221, 209, 95, 247, 101, 207, 87, 222, 194, 209, 95, 247, 101, 252, 53, - 79, 237, 31, 209, 95, 247, 101, 105, 79, 237, 31, 209, 95, 247, 101, 115, - 79, 237, 31, 209, 95, 247, 101, 232, 128, 79, 237, 31, 209, 95, 247, 101, - 232, 226, 79, 237, 31, 209, 95, 247, 101, 202, 136, 79, 237, 31, 209, 95, - 247, 101, 203, 247, 79, 237, 31, 209, 95, 247, 101, 234, 164, 79, 237, - 31, 209, 95, 247, 101, 213, 175, 79, 237, 31, 209, 95, 247, 101, 199, 96, - 79, 237, 31, 209, 95, 247, 101, 223, 30, 79, 237, 31, 209, 95, 247, 101, - 221, 77, 79, 237, 31, 209, 95, 247, 101, 208, 15, 79, 237, 31, 209, 95, - 247, 101, 221, 139, 79, 237, 31, 209, 95, 247, 101, 62, 222, 194, 209, - 95, 247, 101, 252, 53, 79, 242, 204, 209, 95, 247, 101, 105, 79, 242, - 204, 209, 95, 247, 101, 115, 79, 242, 204, 209, 95, 247, 101, 232, 128, - 79, 242, 204, 209, 95, 247, 101, 232, 226, 79, 242, 204, 209, 95, 247, - 101, 202, 136, 79, 242, 204, 209, 95, 247, 101, 203, 247, 79, 242, 204, - 209, 95, 247, 101, 234, 164, 79, 242, 204, 209, 95, 247, 101, 213, 175, - 79, 242, 204, 209, 95, 247, 101, 199, 96, 79, 242, 204, 209, 95, 247, - 101, 223, 30, 79, 242, 204, 209, 95, 247, 101, 221, 77, 79, 242, 204, - 209, 95, 247, 101, 208, 15, 79, 242, 204, 209, 95, 247, 101, 221, 139, - 79, 242, 204, 209, 95, 247, 101, 63, 222, 194, 209, 95, 247, 101, 232, - 160, 209, 95, 247, 101, 197, 200, 209, 95, 247, 101, 197, 189, 209, 95, - 247, 101, 197, 186, 209, 95, 247, 101, 197, 185, 209, 95, 247, 101, 197, - 184, 209, 95, 247, 101, 197, 183, 209, 95, 247, 101, 197, 182, 209, 95, - 247, 101, 197, 181, 209, 95, 247, 101, 197, 180, 209, 95, 247, 101, 197, - 199, 209, 95, 247, 101, 197, 198, 209, 95, 247, 101, 197, 197, 209, 95, - 247, 101, 197, 196, 209, 95, 247, 101, 197, 195, 209, 95, 247, 101, 197, - 194, 209, 95, 247, 101, 197, 193, 209, 95, 247, 101, 197, 192, 209, 95, - 247, 101, 197, 191, 209, 95, 247, 101, 197, 190, 209, 95, 247, 101, 197, - 188, 209, 95, 247, 101, 197, 187, 17, 191, 78, 232, 80, 201, 63, 17, 191, - 78, 242, 74, 17, 91, 242, 74, 17, 105, 242, 74, 17, 115, 242, 74, 17, - 232, 128, 242, 74, 17, 232, 226, 242, 74, 17, 202, 136, 242, 74, 17, 203, - 247, 242, 74, 17, 234, 164, 242, 74, 17, 213, 175, 242, 74, 236, 241, 47, - 49, 17, 191, 77, 236, 241, 214, 106, 47, 49, 17, 191, 77, 47, 191, 78, 4, - 202, 97, 47, 251, 85, 57, 47, 236, 155, 3, 4, 211, 4, 249, 141, 127, 8, - 6, 1, 65, 127, 8, 6, 1, 250, 120, 127, 8, 6, 1, 247, 193, 127, 8, 6, 1, - 238, 127, 127, 8, 6, 1, 71, 127, 8, 6, 1, 233, 175, 127, 8, 6, 1, 232, - 51, 127, 8, 6, 1, 230, 116, 127, 8, 6, 1, 68, 127, 8, 6, 1, 223, 35, 127, - 8, 6, 1, 222, 152, 127, 8, 6, 1, 172, 127, 8, 6, 1, 218, 168, 127, 8, 6, - 1, 215, 61, 127, 8, 6, 1, 74, 127, 8, 6, 1, 210, 236, 127, 8, 6, 1, 208, - 104, 127, 8, 6, 1, 146, 127, 8, 6, 1, 206, 8, 127, 8, 6, 1, 200, 43, 127, + 13, 49, 28, 17, 134, 13, 49, 28, 17, 150, 13, 49, 28, 17, 169, 13, 49, + 28, 17, 175, 13, 49, 28, 17, 171, 13, 49, 28, 17, 178, 13, 215, 219, 17, + 191, 77, 13, 215, 219, 17, 107, 13, 215, 219, 17, 109, 13, 215, 219, 17, + 138, 13, 215, 219, 17, 134, 13, 215, 219, 17, 150, 13, 215, 219, 17, 169, + 13, 215, 219, 17, 175, 13, 215, 219, 17, 171, 13, 215, 219, 17, 178, 24, + 152, 223, 150, 24, 230, 52, 223, 150, 24, 230, 48, 223, 150, 24, 230, 37, + 223, 150, 24, 230, 41, 223, 150, 24, 230, 54, 223, 150, 24, 152, 141, + 248, 225, 24, 230, 52, 141, 248, 225, 24, 152, 176, 196, 105, 141, 248, + 225, 24, 152, 141, 207, 149, 221, 72, 24, 152, 141, 238, 179, 24, 152, + 141, 229, 126, 24, 152, 141, 229, 127, 218, 243, 24, 230, 52, 141, 229, + 128, 24, 152, 141, 216, 86, 24, 230, 52, 141, 216, 86, 24, 152, 141, 82, + 248, 225, 24, 152, 141, 82, 207, 149, 221, 71, 24, 152, 141, 82, 229, + 126, 24, 152, 141, 133, 82, 229, 126, 24, 152, 141, 229, 127, 82, 196, + 77, 24, 152, 141, 82, 239, 48, 24, 152, 141, 82, 239, 49, 141, 248, 225, + 24, 152, 141, 82, 239, 49, 82, 248, 225, 24, 152, 141, 82, 239, 49, 238, + 179, 24, 152, 141, 82, 239, 49, 229, 126, 24, 152, 141, 82, 238, 215, 24, + 230, 52, 141, 82, 238, 215, 24, 152, 82, 248, 226, 139, 223, 150, 24, + 152, 141, 248, 226, 139, 216, 86, 24, 152, 141, 82, 198, 212, 24, 230, + 52, 141, 82, 198, 212, 24, 152, 141, 82, 201, 54, 176, 248, 225, 24, 152, + 141, 82, 248, 226, 176, 201, 53, 24, 152, 141, 82, 176, 248, 225, 24, + 152, 141, 82, 229, 127, 201, 200, 176, 202, 208, 24, 152, 141, 133, 82, + 229, 127, 176, 202, 208, 24, 152, 141, 133, 82, 229, 127, 176, 239, 48, + 24, 152, 141, 229, 127, 82, 133, 176, 202, 208, 24, 152, 141, 82, 133, + 201, 200, 176, 232, 134, 24, 152, 141, 82, 176, 238, 179, 24, 152, 141, + 82, 176, 243, 11, 24, 152, 141, 82, 176, 228, 251, 24, 152, 141, 82, 176, + 229, 126, 24, 152, 176, 248, 212, 141, 82, 201, 53, 24, 152, 141, 82, + 239, 49, 176, 202, 208, 24, 152, 141, 82, 239, 49, 176, 202, 209, 239, + 48, 24, 152, 141, 82, 239, 49, 176, 202, 209, 248, 225, 24, 152, 82, 176, + 228, 252, 141, 196, 77, 24, 152, 141, 176, 228, 252, 82, 196, 77, 24, + 152, 141, 82, 239, 49, 229, 127, 176, 202, 208, 24, 152, 141, 82, 238, + 216, 176, 202, 208, 24, 152, 141, 82, 239, 49, 176, 232, 134, 24, 152, + 141, 82, 239, 49, 238, 180, 176, 232, 134, 24, 152, 82, 176, 238, 180, + 141, 196, 77, 24, 152, 141, 176, 238, 180, 82, 196, 77, 24, 152, 82, 176, + 47, 141, 196, 77, 24, 152, 82, 176, 47, 141, 229, 126, 24, 152, 141, 176, + 251, 116, 211, 17, 82, 196, 77, 24, 152, 141, 176, 251, 116, 223, 165, + 82, 196, 77, 24, 152, 141, 176, 47, 82, 196, 77, 24, 152, 141, 82, 176, + 239, 49, 229, 126, 24, 152, 141, 82, 176, 251, 116, 211, 16, 24, 152, + 141, 82, 176, 251, 115, 24, 152, 82, 176, 251, 116, 211, 17, 141, 196, + 77, 24, 152, 82, 176, 251, 116, 211, 17, 141, 238, 215, 24, 152, 82, 176, + 251, 116, 141, 196, 77, 24, 152, 141, 176, 228, 252, 82, 229, 126, 24, + 230, 43, 232, 130, 232, 249, 24, 230, 43, 232, 130, 232, 250, 248, 225, + 24, 230, 43, 232, 130, 232, 250, 229, 126, 24, 230, 43, 232, 130, 232, + 250, 239, 48, 24, 230, 43, 232, 130, 232, 250, 239, 49, 201, 210, 24, + 230, 50, 232, 130, 232, 250, 239, 48, 24, 152, 232, 130, 232, 250, 239, + 49, 248, 225, 24, 230, 41, 232, 130, 232, 250, 239, 48, 24, 230, 43, 232, + 228, 232, 250, 201, 199, 24, 230, 43, 229, 215, 232, 228, 232, 250, 201, + 199, 24, 230, 43, 232, 228, 232, 250, 201, 200, 232, 130, 248, 225, 24, + 230, 43, 229, 215, 232, 228, 232, 250, 201, 200, 232, 130, 248, 225, 24, + 230, 43, 232, 228, 232, 250, 201, 200, 248, 225, 24, 230, 43, 229, 215, + 232, 228, 232, 250, 201, 200, 248, 225, 24, 230, 43, 232, 228, 232, 250, + 201, 200, 176, 232, 134, 24, 230, 48, 232, 228, 232, 250, 201, 199, 24, + 230, 48, 232, 228, 232, 250, 201, 200, 211, 78, 24, 230, 41, 232, 228, + 232, 250, 201, 200, 211, 78, 24, 230, 37, 232, 228, 232, 250, 201, 199, + 24, 230, 43, 232, 228, 232, 250, 201, 200, 229, 126, 24, 230, 43, 232, + 228, 232, 250, 201, 200, 229, 127, 176, 202, 208, 24, 230, 43, 232, 228, + 232, 250, 201, 200, 229, 127, 213, 46, 198, 212, 24, 230, 42, 24, 230, + 43, 248, 212, 210, 185, 233, 97, 24, 230, 43, 229, 214, 24, 230, 43, 176, + 202, 208, 24, 230, 43, 229, 215, 176, 202, 208, 24, 230, 43, 176, 248, + 225, 24, 230, 43, 176, 232, 134, 24, 230, 43, 201, 211, 141, 176, 202, + 208, 24, 230, 43, 201, 211, 247, 23, 24, 230, 43, 201, 211, 247, 24, 176, + 202, 208, 24, 230, 43, 201, 211, 247, 24, 176, 202, 209, 248, 225, 24, + 230, 43, 201, 211, 219, 84, 24, 230, 49, 24, 230, 50, 176, 202, 208, 24, + 230, 50, 213, 46, 198, 212, 24, 230, 50, 176, 232, 134, 24, 230, 39, 238, + 175, 24, 230, 38, 24, 230, 48, 211, 78, 24, 230, 47, 24, 230, 48, 211, + 79, 176, 202, 208, 24, 230, 48, 176, 202, 208, 24, 230, 48, 211, 79, 213, + 46, 198, 212, 24, 230, 48, 213, 46, 198, 212, 24, 230, 48, 211, 79, 176, + 232, 134, 24, 230, 48, 176, 232, 134, 24, 230, 46, 211, 78, 24, 230, 45, + 24, 230, 51, 24, 230, 36, 24, 230, 37, 176, 202, 208, 24, 230, 37, 213, + 46, 198, 212, 24, 230, 37, 176, 232, 134, 24, 230, 41, 211, 78, 24, 230, + 41, 211, 79, 176, 232, 134, 24, 230, 40, 24, 230, 41, 202, 71, 24, 230, + 41, 211, 79, 176, 202, 208, 24, 230, 41, 176, 202, 208, 24, 230, 41, 211, + 79, 213, 46, 198, 212, 24, 230, 41, 213, 46, 198, 212, 24, 230, 41, 176, + 202, 209, 198, 35, 223, 150, 24, 230, 41, 176, 248, 212, 82, 206, 189, + 24, 230, 53, 24, 152, 141, 82, 206, 189, 24, 230, 52, 141, 82, 206, 189, + 24, 230, 41, 141, 82, 206, 189, 24, 230, 54, 141, 82, 206, 189, 24, 230, + 41, 219, 84, 24, 152, 141, 82, 206, 190, 248, 225, 24, 152, 141, 82, 206, + 190, 239, 48, 24, 230, 41, 141, 82, 206, 190, 239, 48, 24, 152, 219, 85, + 235, 125, 24, 152, 219, 85, 144, 206, 184, 201, 53, 24, 152, 219, 85, + 144, 206, 184, 238, 164, 24, 152, 219, 85, 144, 211, 28, 243, 11, 24, + 152, 219, 85, 196, 77, 24, 152, 176, 196, 105, 219, 85, 196, 77, 24, 230, + 52, 219, 85, 196, 77, 24, 230, 37, 219, 85, 196, 77, 24, 230, 54, 219, + 85, 196, 77, 24, 152, 219, 85, 207, 149, 221, 72, 24, 152, 219, 85, 248, + 225, 24, 152, 219, 85, 198, 36, 198, 212, 24, 152, 219, 85, 198, 212, 24, + 230, 41, 219, 85, 198, 212, 24, 152, 219, 85, 141, 198, 212, 24, 230, 41, + 219, 85, 141, 198, 212, 24, 230, 54, 219, 85, 141, 176, 141, 176, 211, + 16, 24, 230, 54, 219, 85, 141, 176, 141, 198, 212, 24, 152, 219, 85, 223, + 150, 24, 230, 52, 219, 85, 223, 150, 24, 230, 41, 219, 85, 223, 150, 24, + 230, 54, 219, 85, 223, 150, 24, 152, 141, 82, 219, 84, 24, 230, 52, 141, + 82, 219, 84, 24, 230, 41, 141, 82, 219, 84, 24, 230, 41, 206, 189, 24, + 230, 54, 141, 82, 219, 84, 24, 152, 141, 82, 238, 220, 219, 84, 24, 230, + 52, 141, 82, 238, 220, 219, 84, 24, 152, 206, 190, 235, 125, 24, 230, 41, + 206, 190, 144, 141, 176, 228, 253, 216, 86, 24, 230, 54, 206, 190, 144, + 82, 176, 141, 238, 219, 24, 152, 206, 190, 196, 77, 24, 152, 206, 190, + 207, 149, 221, 72, 24, 152, 206, 190, 219, 84, 24, 230, 52, 206, 190, + 219, 84, 24, 230, 37, 206, 190, 219, 84, 24, 230, 54, 206, 190, 219, 84, + 24, 152, 206, 190, 216, 86, 24, 152, 206, 190, 82, 239, 48, 24, 152, 206, + 190, 82, 207, 149, 221, 71, 24, 152, 206, 190, 223, 150, 24, 152, 206, + 190, 198, 212, 24, 230, 39, 206, 190, 198, 212, 24, 152, 141, 206, 190, + 219, 84, 24, 230, 52, 141, 206, 190, 219, 84, 24, 230, 46, 141, 206, 190, + 219, 85, 211, 106, 24, 230, 39, 141, 206, 190, 219, 85, 211, 16, 24, 230, + 39, 141, 206, 190, 219, 85, 223, 164, 24, 230, 39, 141, 206, 190, 219, + 85, 196, 104, 24, 230, 48, 141, 206, 190, 219, 84, 24, 230, 41, 141, 206, + 190, 219, 84, 24, 230, 54, 141, 206, 190, 219, 85, 211, 16, 24, 230, 54, + 141, 206, 190, 219, 84, 24, 152, 82, 235, 125, 24, 230, 41, 216, 86, 24, + 152, 82, 196, 77, 24, 230, 52, 82, 196, 77, 24, 152, 82, 207, 149, 221, + 72, 24, 152, 82, 133, 176, 202, 208, 24, 230, 39, 82, 198, 212, 24, 152, + 82, 176, 219, 84, 24, 152, 82, 219, 84, 24, 152, 82, 206, 190, 219, 84, + 24, 230, 52, 82, 206, 190, 219, 84, 24, 230, 46, 82, 206, 190, 219, 85, + 211, 106, 24, 230, 48, 82, 206, 190, 219, 84, 24, 230, 41, 82, 206, 190, + 219, 84, 24, 230, 54, 82, 206, 190, 219, 85, 211, 16, 24, 230, 54, 82, + 206, 190, 219, 85, 223, 164, 24, 230, 54, 82, 206, 190, 219, 84, 24, 230, + 52, 82, 206, 190, 219, 85, 248, 225, 24, 230, 50, 82, 206, 190, 219, 85, + 239, 48, 24, 230, 50, 82, 206, 190, 219, 85, 239, 49, 202, 208, 24, 230, + 39, 82, 206, 190, 219, 85, 239, 49, 211, 16, 24, 230, 39, 82, 206, 190, + 219, 85, 239, 49, 223, 164, 24, 230, 39, 82, 206, 190, 219, 85, 239, 48, + 24, 230, 41, 141, 229, 126, 24, 152, 141, 176, 202, 208, 24, 230, 41, + 141, 176, 202, 208, 24, 152, 141, 176, 202, 209, 176, 237, 40, 24, 152, + 141, 176, 202, 209, 176, 239, 48, 24, 152, 141, 176, 202, 209, 176, 248, + 225, 24, 152, 141, 176, 202, 209, 141, 248, 225, 24, 152, 141, 176, 202, + 209, 248, 82, 248, 225, 24, 152, 141, 176, 202, 209, 141, 229, 128, 24, + 152, 141, 176, 232, 135, 141, 201, 53, 24, 152, 141, 176, 232, 135, 141, + 248, 225, 24, 152, 141, 176, 102, 24, 152, 141, 176, 238, 175, 24, 152, + 141, 176, 238, 167, 176, 223, 119, 24, 230, 50, 141, 176, 238, 167, 176, + 223, 119, 24, 152, 141, 176, 238, 167, 176, 196, 104, 24, 152, 141, 176, + 243, 12, 24, 230, 48, 141, 198, 212, 24, 230, 48, 141, 176, 211, 78, 24, + 230, 41, 141, 176, 211, 78, 24, 230, 41, 141, 176, 220, 14, 24, 230, 41, + 141, 198, 212, 24, 230, 41, 141, 176, 202, 71, 24, 230, 54, 141, 176, + 211, 16, 24, 230, 54, 141, 176, 223, 164, 24, 230, 54, 141, 198, 212, 24, + 152, 198, 212, 24, 152, 176, 229, 214, 24, 152, 176, 202, 209, 237, 40, + 24, 152, 176, 202, 209, 239, 48, 24, 152, 176, 202, 209, 248, 225, 24, + 152, 176, 232, 134, 24, 152, 176, 248, 212, 141, 216, 86, 24, 152, 176, + 248, 212, 82, 206, 189, 24, 152, 176, 248, 212, 206, 190, 219, 84, 24, + 152, 176, 196, 105, 105, 232, 249, 24, 152, 176, 139, 105, 232, 249, 24, + 152, 176, 196, 105, 115, 232, 249, 24, 152, 176, 196, 105, 232, 130, 232, + 249, 24, 152, 176, 139, 232, 130, 207, 149, 221, 71, 24, 230, 44, 24, + 152, 229, 214, 24, 198, 37, 202, 170, 24, 198, 37, 215, 130, 24, 198, 37, + 248, 211, 24, 230, 217, 202, 170, 24, 230, 217, 215, 130, 24, 230, 217, + 248, 211, 24, 201, 34, 202, 170, 24, 201, 34, 215, 130, 24, 201, 34, 248, + 211, 24, 248, 20, 202, 170, 24, 248, 20, 215, 130, 24, 248, 20, 248, 211, + 24, 206, 61, 202, 170, 24, 206, 61, 215, 130, 24, 206, 61, 248, 211, 24, + 200, 171, 200, 76, 24, 200, 171, 248, 211, 24, 201, 187, 220, 15, 202, + 170, 24, 201, 187, 2, 202, 170, 24, 201, 187, 220, 15, 215, 130, 24, 201, + 187, 2, 215, 130, 24, 201, 187, 204, 7, 24, 232, 199, 220, 15, 202, 170, + 24, 232, 199, 2, 202, 170, 24, 232, 199, 220, 15, 215, 130, 24, 232, 199, + 2, 215, 130, 24, 232, 199, 204, 7, 24, 201, 187, 232, 199, 251, 156, 24, + 215, 174, 133, 144, 220, 14, 24, 215, 174, 133, 144, 202, 71, 24, 215, + 174, 133, 204, 7, 24, 215, 174, 144, 204, 7, 24, 215, 174, 133, 144, 251, + 157, 220, 14, 24, 215, 174, 133, 144, 251, 157, 202, 71, 24, 215, 174, + 202, 209, 119, 202, 209, 205, 85, 24, 215, 173, 232, 255, 239, 37, 24, + 215, 175, 232, 255, 239, 37, 24, 215, 173, 202, 171, 201, 54, 202, 71, + 24, 215, 173, 202, 171, 201, 54, 216, 214, 24, 215, 173, 202, 171, 201, + 54, 220, 14, 24, 215, 173, 202, 171, 201, 54, 220, 12, 24, 215, 173, 202, + 171, 193, 4, 232, 202, 24, 215, 173, 55, 201, 53, 24, 215, 173, 55, 193, + 4, 232, 202, 24, 215, 173, 55, 251, 156, 24, 215, 173, 55, 251, 157, 193, + 4, 232, 202, 24, 215, 173, 238, 219, 24, 215, 173, 197, 225, 201, 54, + 215, 177, 24, 215, 173, 197, 225, 193, 4, 232, 202, 24, 215, 173, 197, + 225, 251, 156, 24, 215, 173, 197, 225, 251, 157, 193, 4, 232, 202, 24, + 215, 173, 248, 230, 202, 71, 24, 215, 173, 248, 230, 216, 214, 24, 215, + 173, 248, 230, 220, 14, 24, 215, 173, 239, 4, 202, 71, 24, 215, 173, 239, + 4, 216, 214, 24, 215, 173, 239, 4, 220, 14, 24, 215, 173, 239, 4, 206, + 121, 24, 215, 173, 243, 128, 202, 71, 24, 215, 173, 243, 128, 216, 214, + 24, 215, 173, 243, 128, 220, 14, 24, 215, 173, 111, 202, 71, 24, 215, + 173, 111, 216, 214, 24, 215, 173, 111, 220, 14, 24, 215, 173, 191, 21, + 202, 71, 24, 215, 173, 191, 21, 216, 214, 24, 215, 173, 191, 21, 220, 14, + 24, 215, 173, 210, 59, 202, 71, 24, 215, 173, 210, 59, 216, 214, 24, 215, + 173, 210, 59, 220, 14, 24, 198, 3, 206, 119, 202, 170, 24, 198, 3, 206, + 119, 235, 135, 24, 198, 3, 206, 119, 251, 156, 24, 198, 3, 206, 120, 202, + 170, 24, 198, 3, 206, 120, 235, 135, 24, 198, 3, 206, 120, 251, 156, 24, + 198, 3, 203, 145, 24, 198, 3, 250, 253, 201, 219, 202, 170, 24, 198, 3, + 250, 253, 201, 219, 235, 135, 24, 198, 3, 250, 253, 201, 219, 197, 224, + 24, 215, 176, 250, 141, 202, 71, 24, 215, 176, 250, 141, 216, 214, 24, + 215, 176, 250, 141, 220, 14, 24, 215, 176, 250, 141, 220, 12, 24, 215, + 176, 198, 31, 202, 71, 24, 215, 176, 198, 31, 216, 214, 24, 215, 176, + 198, 31, 220, 14, 24, 215, 176, 198, 31, 220, 12, 24, 215, 176, 248, 212, + 250, 141, 202, 71, 24, 215, 176, 248, 212, 250, 141, 216, 214, 24, 215, + 176, 248, 212, 250, 141, 220, 14, 24, 215, 176, 248, 212, 250, 141, 220, + 12, 24, 215, 176, 248, 212, 198, 31, 202, 71, 24, 215, 176, 248, 212, + 198, 31, 216, 214, 24, 215, 176, 248, 212, 198, 31, 220, 14, 24, 215, + 176, 248, 212, 198, 31, 220, 12, 24, 215, 175, 202, 171, 201, 54, 202, + 71, 24, 215, 175, 202, 171, 201, 54, 216, 214, 24, 215, 175, 202, 171, + 201, 54, 220, 14, 24, 215, 175, 202, 171, 201, 54, 220, 12, 24, 215, 175, + 202, 171, 193, 4, 232, 202, 24, 215, 175, 55, 201, 53, 24, 215, 175, 55, + 193, 4, 232, 202, 24, 215, 175, 55, 251, 156, 24, 215, 175, 55, 251, 157, + 193, 4, 232, 202, 24, 215, 175, 238, 219, 24, 215, 175, 197, 225, 201, + 54, 215, 177, 24, 215, 175, 197, 225, 193, 4, 232, 202, 24, 215, 175, + 197, 225, 251, 157, 215, 177, 24, 215, 175, 197, 225, 251, 157, 193, 4, + 232, 202, 24, 215, 175, 248, 229, 24, 215, 175, 239, 4, 202, 71, 24, 215, + 175, 239, 4, 216, 214, 24, 215, 175, 239, 4, 220, 14, 24, 215, 175, 243, + 127, 24, 215, 175, 111, 202, 71, 24, 215, 175, 111, 216, 214, 24, 215, + 175, 111, 220, 14, 24, 215, 175, 191, 21, 202, 71, 24, 215, 175, 191, 21, + 216, 214, 24, 215, 175, 191, 21, 220, 14, 24, 215, 175, 210, 59, 202, 71, + 24, 215, 175, 210, 59, 216, 214, 24, 215, 175, 210, 59, 220, 14, 24, 198, + 4, 206, 120, 202, 170, 24, 198, 4, 206, 120, 235, 135, 24, 198, 4, 206, + 120, 251, 156, 24, 198, 4, 206, 119, 202, 170, 24, 198, 4, 206, 119, 235, + 135, 24, 198, 4, 206, 119, 251, 156, 24, 198, 4, 203, 145, 24, 215, 173, + 238, 167, 208, 25, 202, 71, 24, 215, 173, 238, 167, 208, 25, 216, 214, + 24, 215, 173, 238, 167, 208, 25, 220, 14, 24, 215, 173, 238, 167, 208, + 25, 220, 12, 24, 215, 173, 238, 167, 230, 69, 202, 71, 24, 215, 173, 238, + 167, 230, 69, 216, 214, 24, 215, 173, 238, 167, 230, 69, 220, 14, 24, + 215, 173, 238, 167, 230, 69, 220, 12, 24, 215, 173, 238, 167, 198, 218, + 243, 13, 202, 71, 24, 215, 173, 238, 167, 198, 218, 243, 13, 216, 214, + 24, 215, 173, 228, 145, 202, 71, 24, 215, 173, 228, 145, 216, 214, 24, + 215, 173, 228, 145, 220, 14, 24, 215, 173, 219, 7, 202, 71, 24, 215, 173, + 219, 7, 216, 214, 24, 215, 173, 219, 7, 220, 14, 24, 215, 173, 219, 7, 2, + 235, 135, 24, 215, 173, 193, 139, 238, 167, 55, 202, 71, 24, 215, 173, + 193, 139, 238, 167, 55, 216, 214, 24, 215, 173, 193, 139, 238, 167, 55, + 220, 14, 24, 215, 173, 193, 139, 238, 167, 197, 225, 202, 71, 24, 215, + 173, 193, 139, 238, 167, 197, 225, 216, 214, 24, 215, 173, 193, 139, 238, + 167, 197, 225, 220, 14, 24, 215, 173, 238, 167, 199, 25, 201, 53, 24, + 215, 173, 238, 165, 238, 220, 202, 71, 24, 215, 173, 238, 165, 238, 220, + 216, 214, 24, 206, 119, 202, 170, 24, 206, 119, 235, 135, 24, 206, 119, + 251, 158, 24, 215, 173, 203, 145, 24, 215, 173, 238, 167, 229, 118, 232, + 99, 193, 167, 24, 215, 173, 228, 145, 229, 118, 232, 99, 193, 167, 24, + 215, 173, 219, 7, 229, 118, 232, 99, 193, 167, 24, 215, 173, 193, 139, + 229, 118, 232, 99, 193, 167, 24, 206, 119, 202, 171, 229, 118, 232, 99, + 193, 167, 24, 206, 119, 55, 229, 118, 232, 99, 193, 167, 24, 206, 119, + 251, 157, 229, 118, 232, 99, 193, 167, 24, 215, 173, 238, 167, 229, 118, + 243, 106, 24, 215, 173, 228, 145, 229, 118, 243, 106, 24, 215, 173, 219, + 7, 229, 118, 243, 106, 24, 215, 173, 193, 139, 229, 118, 243, 106, 24, + 206, 119, 202, 171, 229, 118, 243, 106, 24, 206, 119, 55, 229, 118, 243, + 106, 24, 206, 119, 251, 157, 229, 118, 243, 106, 24, 215, 173, 193, 139, + 237, 41, 210, 88, 202, 71, 24, 215, 173, 193, 139, 237, 41, 210, 88, 216, + 214, 24, 215, 173, 193, 139, 237, 41, 210, 88, 220, 14, 24, 215, 175, + 238, 167, 229, 118, 247, 33, 202, 71, 24, 215, 175, 238, 167, 229, 118, + 247, 33, 220, 14, 24, 215, 175, 228, 145, 229, 118, 247, 33, 2, 235, 135, + 24, 215, 175, 228, 145, 229, 118, 247, 33, 220, 15, 235, 135, 24, 215, + 175, 228, 145, 229, 118, 247, 33, 2, 197, 224, 24, 215, 175, 228, 145, + 229, 118, 247, 33, 220, 15, 197, 224, 24, 215, 175, 219, 7, 229, 118, + 247, 33, 2, 202, 170, 24, 215, 175, 219, 7, 229, 118, 247, 33, 220, 15, + 202, 170, 24, 215, 175, 219, 7, 229, 118, 247, 33, 2, 235, 135, 24, 215, + 175, 219, 7, 229, 118, 247, 33, 220, 15, 235, 135, 24, 215, 175, 193, + 139, 229, 118, 247, 33, 202, 71, 24, 215, 175, 193, 139, 229, 118, 247, + 33, 220, 14, 24, 206, 120, 202, 171, 229, 118, 247, 32, 24, 206, 120, 55, + 229, 118, 247, 32, 24, 206, 120, 251, 157, 229, 118, 247, 32, 24, 215, + 175, 238, 167, 229, 118, 232, 196, 202, 71, 24, 215, 175, 238, 167, 229, + 118, 232, 196, 220, 14, 24, 215, 175, 228, 145, 229, 118, 232, 196, 2, + 235, 135, 24, 215, 175, 228, 145, 229, 118, 232, 196, 220, 15, 235, 135, + 24, 215, 175, 228, 145, 229, 118, 232, 196, 197, 225, 2, 197, 224, 24, + 215, 175, 228, 145, 229, 118, 232, 196, 197, 225, 220, 15, 197, 224, 24, + 215, 175, 219, 7, 229, 118, 232, 196, 2, 202, 170, 24, 215, 175, 219, 7, + 229, 118, 232, 196, 220, 15, 202, 170, 24, 215, 175, 219, 7, 229, 118, + 232, 196, 2, 235, 135, 24, 215, 175, 219, 7, 229, 118, 232, 196, 220, 15, + 235, 135, 24, 215, 175, 193, 139, 229, 118, 232, 196, 202, 71, 24, 215, + 175, 193, 139, 229, 118, 232, 196, 220, 14, 24, 206, 120, 202, 171, 229, + 118, 232, 195, 24, 206, 120, 55, 229, 118, 232, 195, 24, 206, 120, 251, + 157, 229, 118, 232, 195, 24, 215, 175, 238, 167, 202, 71, 24, 215, 175, + 238, 167, 216, 214, 24, 215, 175, 238, 167, 220, 14, 24, 215, 175, 238, + 167, 220, 12, 24, 215, 175, 238, 167, 242, 80, 24, 215, 175, 228, 145, + 202, 71, 24, 215, 175, 219, 7, 202, 71, 24, 215, 175, 193, 139, 202, 59, + 24, 215, 175, 193, 139, 202, 71, 24, 215, 175, 193, 139, 220, 14, 24, + 206, 120, 202, 170, 24, 206, 120, 235, 135, 24, 206, 120, 251, 156, 24, + 215, 175, 203, 146, 210, 120, 24, 215, 173, 250, 253, 243, 13, 2, 202, + 170, 24, 215, 173, 250, 253, 243, 13, 216, 215, 202, 170, 24, 215, 173, + 250, 253, 243, 13, 2, 235, 135, 24, 215, 173, 250, 253, 243, 13, 216, + 215, 235, 135, 24, 215, 175, 250, 253, 243, 13, 229, 118, 193, 168, 2, + 202, 170, 24, 215, 175, 250, 253, 243, 13, 229, 118, 193, 168, 216, 215, + 202, 170, 24, 215, 175, 250, 253, 243, 13, 229, 118, 193, 168, 220, 15, + 202, 170, 24, 215, 175, 250, 253, 243, 13, 229, 118, 193, 168, 2, 235, + 135, 24, 215, 175, 250, 253, 243, 13, 229, 118, 193, 168, 216, 215, 235, + 135, 24, 215, 175, 250, 253, 243, 13, 229, 118, 193, 168, 220, 15, 235, + 135, 24, 215, 173, 193, 4, 243, 13, 232, 99, 202, 170, 24, 215, 173, 193, + 4, 243, 13, 232, 99, 235, 135, 24, 215, 175, 193, 4, 243, 13, 229, 118, + 193, 168, 202, 170, 24, 215, 175, 193, 4, 243, 13, 229, 118, 193, 168, + 235, 135, 24, 215, 173, 232, 255, 243, 10, 202, 170, 24, 215, 173, 232, + 255, 243, 10, 235, 135, 24, 215, 175, 232, 255, 243, 10, 229, 118, 193, + 168, 202, 170, 24, 215, 175, 232, 255, 243, 10, 229, 118, 193, 168, 235, + 135, 24, 235, 42, 250, 238, 202, 71, 24, 235, 42, 250, 238, 220, 14, 24, + 235, 42, 233, 75, 24, 235, 42, 202, 76, 24, 235, 42, 199, 88, 24, 235, + 42, 207, 64, 24, 235, 42, 202, 177, 24, 235, 42, 202, 178, 251, 156, 24, + 235, 42, 233, 227, 211, 29, 198, 146, 24, 235, 42, 230, 228, 24, 229, + 237, 24, 229, 238, 206, 194, 24, 229, 238, 215, 173, 201, 53, 24, 229, + 238, 215, 173, 198, 149, 24, 229, 238, 215, 175, 201, 53, 24, 229, 238, + 215, 173, 238, 166, 24, 229, 238, 215, 175, 238, 166, 24, 229, 238, 215, + 178, 243, 12, 24, 233, 106, 236, 235, 209, 27, 213, 16, 232, 135, 198, + 147, 24, 233, 106, 236, 235, 209, 27, 213, 16, 133, 211, 59, 235, 125, + 24, 233, 106, 236, 235, 209, 27, 213, 16, 133, 211, 59, 144, 198, 147, + 24, 233, 193, 201, 54, 196, 77, 24, 233, 193, 201, 54, 214, 83, 24, 233, + 193, 201, 54, 235, 125, 24, 235, 109, 233, 193, 214, 84, 235, 125, 24, + 235, 109, 233, 193, 144, 214, 83, 24, 235, 109, 233, 193, 133, 214, 83, + 24, 235, 109, 233, 193, 214, 84, 196, 77, 24, 232, 153, 214, 83, 24, 232, + 153, 239, 37, 24, 232, 153, 193, 7, 24, 233, 188, 211, 78, 24, 233, 188, + 201, 186, 24, 233, 188, 242, 220, 24, 233, 196, 248, 132, 202, 170, 24, + 233, 196, 248, 132, 215, 130, 24, 233, 188, 132, 211, 78, 24, 233, 188, + 193, 78, 211, 78, 24, 233, 188, 132, 242, 220, 24, 233, 188, 193, 76, + 215, 177, 24, 233, 196, 193, 58, 24, 233, 189, 196, 77, 24, 233, 189, + 235, 125, 24, 233, 189, 232, 182, 24, 233, 191, 201, 53, 24, 233, 191, + 201, 54, 235, 135, 24, 233, 191, 201, 54, 251, 156, 24, 233, 192, 201, + 53, 24, 233, 192, 201, 54, 235, 135, 24, 233, 192, 201, 54, 251, 156, 24, + 233, 191, 238, 164, 24, 233, 192, 238, 164, 24, 233, 191, 243, 7, 24, + 243, 123, 208, 157, 24, 243, 123, 214, 83, 24, 243, 123, 200, 218, 24, + 199, 89, 243, 123, 229, 137, 24, 199, 89, 243, 123, 216, 86, 24, 199, 89, + 243, 123, 218, 243, 24, 234, 211, 24, 213, 16, 214, 83, 24, 213, 16, 239, + 37, 24, 213, 16, 193, 5, 24, 213, 16, 193, 73, 24, 251, 228, 248, 118, + 211, 16, 24, 251, 228, 200, 217, 223, 164, 24, 251, 228, 248, 120, 2, + 206, 118, 24, 251, 228, 200, 219, 2, 206, 118, 24, 248, 41, 223, 136, 24, + 248, 41, 233, 216, 24, 215, 182, 242, 221, 214, 83, 24, 215, 182, 242, + 221, 232, 134, 24, 215, 182, 242, 221, 239, 37, 24, 215, 182, 202, 66, + 24, 215, 182, 202, 67, 193, 7, 24, 215, 182, 202, 67, 211, 78, 24, 215, + 182, 232, 95, 24, 215, 182, 232, 96, 193, 7, 24, 215, 182, 232, 96, 211, + 78, 24, 215, 182, 211, 79, 243, 12, 24, 215, 182, 211, 79, 232, 134, 24, + 215, 182, 211, 79, 193, 7, 24, 215, 182, 211, 79, 211, 9, 24, 215, 182, + 211, 79, 211, 10, 193, 7, 24, 215, 182, 211, 79, 211, 10, 192, 88, 24, + 215, 182, 211, 79, 207, 94, 24, 215, 182, 211, 79, 207, 95, 193, 7, 24, + 215, 182, 211, 79, 207, 95, 192, 88, 24, 215, 182, 221, 124, 24, 215, + 182, 221, 125, 232, 134, 24, 215, 182, 221, 125, 193, 7, 24, 215, 182, + 199, 88, 24, 215, 182, 199, 89, 232, 134, 24, 215, 182, 199, 89, 200, + 218, 24, 219, 99, 208, 221, 198, 87, 24, 219, 101, 110, 139, 196, 74, 24, + 219, 101, 116, 139, 218, 238, 24, 215, 182, 239, 2, 24, 215, 182, 193, 6, + 202, 170, 24, 215, 182, 193, 6, 235, 135, 24, 198, 62, 201, 75, 211, 17, + 233, 77, 24, 198, 62, 219, 144, 219, 98, 24, 198, 62, 198, 136, 248, 212, + 219, 98, 24, 198, 62, 198, 136, 198, 35, 223, 120, 215, 181, 24, 198, 62, + 223, 120, 215, 182, 207, 64, 24, 198, 62, 215, 172, 251, 253, 243, 124, + 24, 198, 62, 247, 24, 201, 75, 211, 16, 24, 198, 62, 247, 24, 223, 120, + 215, 181, 24, 199, 117, 24, 199, 118, 215, 177, 24, 199, 118, 211, 107, + 198, 61, 24, 199, 118, 211, 107, 198, 62, 215, 177, 24, 199, 118, 211, + 107, 219, 98, 24, 199, 118, 211, 107, 219, 99, 215, 177, 24, 199, 118, + 248, 148, 219, 98, 24, 215, 173, 223, 16, 24, 215, 175, 223, 16, 24, 214, + 114, 24, 230, 80, 24, 233, 219, 24, 203, 23, 229, 125, 201, 220, 24, 203, + 23, 229, 125, 209, 25, 24, 193, 165, 203, 23, 229, 125, 215, 180, 24, + 232, 194, 203, 23, 229, 125, 215, 180, 24, 203, 23, 198, 148, 232, 100, + 193, 172, 24, 198, 43, 201, 54, 201, 38, 24, 198, 43, 238, 165, 248, 229, + 24, 198, 44, 197, 16, 24, 116, 248, 107, 198, 148, 232, 100, 229, 125, + 222, 197, 24, 219, 126, 242, 81, 24, 219, 126, 219, 199, 24, 219, 126, + 219, 198, 24, 219, 126, 219, 197, 24, 219, 126, 219, 196, 24, 219, 126, + 219, 195, 24, 219, 126, 219, 194, 24, 219, 126, 219, 193, 24, 232, 254, + 24, 219, 39, 201, 248, 24, 219, 40, 201, 248, 24, 219, 42, 229, 210, 24, + 219, 42, 193, 74, 24, 219, 42, 237, 94, 24, 219, 42, 229, 238, 214, 114, + 24, 219, 42, 198, 45, 24, 219, 42, 219, 125, 237, 11, 24, 242, 76, 24, + 232, 82, 201, 64, 24, 204, 26, 24, 242, 85, 24, 210, 115, 24, 233, 8, + 215, 246, 24, 233, 8, 215, 245, 24, 233, 8, 215, 244, 24, 233, 8, 215, + 243, 24, 233, 8, 215, 242, 24, 206, 122, 215, 246, 24, 206, 122, 215, + 245, 24, 206, 122, 215, 244, 24, 206, 122, 215, 243, 24, 206, 122, 215, + 242, 24, 206, 122, 215, 241, 24, 206, 122, 215, 240, 24, 206, 122, 215, + 239, 24, 206, 122, 215, 253, 24, 206, 122, 215, 252, 24, 206, 122, 215, + 251, 24, 206, 122, 215, 250, 24, 206, 122, 215, 249, 24, 206, 122, 215, + 248, 24, 206, 122, 215, 247, 8, 2, 1, 233, 39, 237, 5, 4, 197, 228, 8, 2, + 1, 207, 19, 27, 232, 53, 8, 1, 2, 6, 154, 232, 53, 8, 2, 1, 207, 19, 222, + 154, 8, 1, 2, 6, 220, 145, 4, 248, 233, 8, 2, 1, 219, 165, 4, 207, 25, + 102, 8, 2, 1, 154, 192, 160, 4, 248, 233, 8, 2, 1, 207, 19, 234, 90, 8, + 2, 1, 154, 207, 224, 4, 180, 219, 215, 23, 207, 25, 102, 8, 2, 1, 200, + 44, 4, 228, 253, 23, 207, 25, 102, 8, 1, 207, 25, 242, 234, 4, 207, 25, + 102, 8, 2, 1, 234, 15, 4, 55, 164, 8, 2, 1, 234, 15, 4, 55, 249, 90, 23, + 238, 177, 8, 2, 1, 154, 200, 44, 4, 238, 177, 8, 1, 223, 95, 231, 13, + 201, 65, 4, 238, 177, 8, 1, 201, 37, 247, 196, 4, 238, 177, 8, 1, 2, 6, + 154, 222, 154, 8, 2, 1, 220, 145, 4, 232, 235, 8, 2, 1, 237, 72, 237, 5, + 4, 210, 194, 102, 8, 2, 1, 220, 145, 4, 248, 234, 23, 210, 194, 102, 8, + 2, 1, 234, 91, 4, 210, 194, 102, 8, 2, 1, 154, 207, 224, 4, 210, 194, + 102, 8, 2, 1, 207, 224, 4, 232, 236, 23, 210, 194, 102, 8, 2, 1, 199, 79, + 237, 5, 4, 210, 194, 102, 8, 2, 1, 233, 181, 4, 210, 194, 102, 8, 2, 1, + 237, 72, 237, 5, 4, 207, 25, 102, 8, 2, 1, 228, 76, 4, 201, 29, 23, 207, + 25, 102, 8, 2, 1, 187, 4, 207, 25, 102, 8, 2, 1, 199, 79, 237, 5, 4, 207, + 25, 102, 8, 2, 1, 247, 196, 4, 207, 25, 102, 8, 2, 1, 206, 10, 4, 238, + 177, 8, 2, 1, 238, 130, 4, 216, 88, 45, 102, 8, 2, 1, 220, 145, 4, 216, + 88, 45, 102, 8, 2, 1, 215, 64, 4, 216, 88, 45, 102, 8, 2, 1, 207, 224, 4, + 216, 88, 45, 102, 8, 2, 1, 206, 10, 4, 216, 88, 45, 102, 8, 2, 1, 200, + 44, 4, 216, 88, 45, 102, 33, 135, 1, 250, 124, 33, 135, 1, 247, 254, 33, + 135, 1, 195, 151, 33, 135, 1, 231, 20, 33, 135, 1, 236, 171, 33, 135, 1, + 192, 49, 33, 135, 1, 191, 55, 33, 135, 1, 191, 82, 33, 135, 1, 223, 41, + 33, 135, 1, 89, 223, 41, 33, 135, 1, 68, 33, 135, 1, 236, 192, 33, 135, + 1, 222, 96, 33, 135, 1, 219, 77, 33, 135, 1, 215, 68, 33, 135, 1, 214, + 212, 33, 135, 1, 211, 91, 33, 135, 1, 209, 57, 33, 135, 1, 206, 180, 33, + 135, 1, 202, 78, 33, 135, 1, 197, 44, 33, 135, 1, 196, 124, 33, 135, 1, + 232, 103, 33, 135, 1, 229, 190, 33, 135, 1, 203, 9, 33, 135, 1, 197, 146, + 33, 135, 1, 243, 56, 33, 135, 1, 203, 166, 33, 135, 1, 192, 58, 33, 135, + 1, 192, 60, 33, 135, 1, 192, 93, 33, 135, 1, 191, 225, 33, 135, 1, 2, + 191, 190, 33, 135, 1, 192, 12, 33, 135, 1, 223, 84, 2, 191, 190, 33, 135, + 1, 248, 177, 191, 190, 33, 135, 1, 223, 84, 248, 177, 191, 190, 33, 135, + 1, 232, 230, 52, 1, 38, 2, 65, 52, 1, 38, 2, 249, 19, 52, 1, 38, 2, 195, + 153, 52, 1, 38, 2, 231, 79, 52, 1, 38, 2, 237, 148, 52, 1, 38, 2, 223, + 228, 52, 1, 38, 2, 191, 62, 52, 1, 38, 2, 191, 87, 52, 1, 38, 2, 68, 52, + 1, 38, 2, 155, 52, 1, 38, 2, 234, 142, 52, 1, 38, 2, 234, 116, 52, 1, 38, + 2, 74, 52, 1, 38, 2, 210, 65, 52, 1, 38, 2, 234, 36, 52, 1, 38, 2, 234, + 24, 52, 1, 38, 2, 199, 145, 52, 1, 38, 2, 66, 52, 1, 38, 2, 234, 183, 52, + 1, 38, 2, 140, 52, 1, 38, 2, 197, 161, 52, 1, 38, 2, 243, 129, 52, 1, 38, + 2, 203, 166, 52, 1, 38, 2, 192, 58, 52, 1, 38, 2, 71, 52, 1, 38, 2, 191, + 225, 52, 1, 38, 2, 235, 19, 52, 1, 38, 2, 205, 87, 52, 1, 38, 2, 247, + 205, 68, 52, 1, 38, 2, 223, 12, 52, 1, 38, 2, 249, 84, 74, 52, 1, 38, 2, + 201, 54, 66, 52, 1, 38, 2, 210, 181, 38, 200, 231, 2, 1, 65, 38, 200, + 231, 2, 1, 249, 19, 38, 200, 231, 2, 1, 195, 153, 38, 200, 231, 2, 1, + 231, 79, 38, 200, 231, 2, 1, 237, 148, 38, 200, 231, 2, 1, 223, 228, 38, + 200, 231, 2, 1, 191, 62, 38, 200, 231, 2, 1, 191, 87, 38, 200, 231, 2, 1, + 68, 38, 200, 231, 2, 1, 155, 38, 200, 231, 2, 1, 234, 142, 38, 200, 231, + 2, 1, 74, 38, 200, 231, 2, 1, 210, 65, 38, 200, 231, 2, 1, 234, 24, 38, + 200, 231, 2, 1, 66, 38, 200, 231, 2, 1, 234, 183, 38, 200, 231, 2, 1, + 140, 38, 200, 231, 2, 1, 197, 161, 38, 200, 231, 2, 1, 243, 129, 38, 200, + 231, 2, 1, 203, 166, 38, 200, 231, 2, 1, 230, 19, 56, 38, 200, 231, 2, 1, + 192, 58, 38, 200, 231, 2, 1, 231, 80, 4, 196, 69, 38, 200, 231, 2, 1, + 247, 205, 68, 38, 200, 231, 2, 1, 235, 34, 38, 200, 231, 2, 1, 235, 30, + 52, 1, 38, 2, 234, 25, 4, 237, 89, 52, 1, 38, 2, 192, 59, 4, 249, 149, + 192, 62, 52, 1, 38, 2, 201, 54, 126, 4, 106, 33, 38, 2, 1, 247, 205, 68, + 212, 82, 208, 164, 90, 1, 174, 212, 82, 208, 164, 90, 1, 197, 168, 212, + 82, 208, 164, 90, 1, 212, 201, 212, 82, 208, 164, 90, 1, 190, 190, 212, + 82, 208, 164, 90, 1, 140, 212, 82, 208, 164, 90, 1, 181, 212, 82, 208, + 164, 90, 1, 192, 220, 212, 82, 208, 164, 90, 1, 213, 113, 212, 82, 208, + 164, 90, 1, 247, 162, 212, 82, 208, 164, 90, 1, 173, 212, 82, 208, 164, + 90, 1, 188, 212, 82, 208, 164, 90, 1, 191, 123, 212, 82, 208, 164, 90, 1, + 214, 168, 212, 82, 208, 164, 90, 1, 212, 188, 212, 82, 208, 164, 90, 1, + 155, 212, 82, 208, 164, 90, 1, 238, 34, 212, 82, 208, 164, 90, 1, 212, + 103, 212, 82, 208, 164, 90, 1, 212, 246, 212, 82, 208, 164, 90, 1, 195, + 188, 212, 82, 208, 164, 90, 1, 212, 182, 212, 82, 208, 164, 90, 1, 197, + 8, 212, 82, 208, 164, 90, 1, 233, 111, 212, 82, 208, 164, 90, 1, 165, + 212, 82, 208, 164, 90, 1, 208, 98, 212, 82, 208, 164, 90, 1, 170, 212, + 82, 208, 164, 90, 1, 212, 248, 212, 82, 208, 164, 90, 1, 168, 212, 82, + 208, 164, 90, 1, 192, 175, 212, 82, 208, 164, 90, 1, 212, 250, 212, 82, + 208, 164, 90, 1, 236, 188, 212, 82, 208, 164, 90, 1, 212, 249, 212, 82, + 208, 164, 90, 1, 230, 83, 212, 82, 208, 164, 90, 1, 216, 21, 212, 82, + 208, 164, 90, 1, 209, 112, 212, 82, 208, 164, 90, 1, 231, 242, 212, 82, + 208, 164, 90, 1, 206, 110, 212, 82, 208, 164, 90, 1, 65, 212, 82, 208, + 164, 90, 1, 252, 208, 212, 82, 208, 164, 90, 1, 68, 212, 82, 208, 164, + 90, 1, 66, 212, 82, 208, 164, 90, 1, 74, 212, 82, 208, 164, 90, 1, 211, + 89, 212, 82, 208, 164, 90, 1, 71, 212, 82, 208, 164, 90, 1, 234, 190, + 212, 82, 208, 164, 90, 1, 193, 224, 212, 82, 208, 164, 90, 198, 70, 212, + 82, 208, 164, 90, 198, 66, 212, 82, 208, 164, 90, 198, 67, 212, 82, 208, + 164, 90, 198, 64, 212, 82, 208, 164, 90, 198, 65, 212, 82, 208, 164, 90, + 198, 68, 212, 82, 208, 164, 90, 198, 69, 212, 82, 208, 164, 90, 3, 40, + 209, 252, 212, 82, 208, 164, 90, 3, 40, 199, 3, 212, 82, 208, 164, 90, 3, + 40, 219, 41, 212, 82, 208, 164, 90, 3, 40, 251, 103, 212, 82, 208, 164, + 90, 3, 40, 223, 96, 212, 82, 208, 164, 90, 3, 192, 183, 192, 182, 212, + 82, 208, 164, 90, 5, 219, 192, 212, 82, 208, 164, 90, 17, 191, 77, 212, + 82, 208, 164, 90, 17, 107, 212, 82, 208, 164, 90, 17, 109, 212, 82, 208, + 164, 90, 17, 138, 212, 82, 208, 164, 90, 17, 134, 212, 82, 208, 164, 90, + 17, 150, 212, 82, 208, 164, 90, 17, 169, 212, 82, 208, 164, 90, 17, 175, + 212, 82, 208, 164, 90, 17, 171, 212, 82, 208, 164, 90, 17, 178, 212, 82, + 208, 164, 90, 219, 30, 212, 98, 212, 82, 208, 164, 90, 47, 247, 162, 198, + 38, 1, 168, 198, 38, 1, 249, 155, 198, 38, 1, 190, 190, 198, 38, 1, 238, + 34, 198, 38, 1, 155, 198, 38, 1, 231, 242, 198, 38, 1, 174, 198, 38, 1, + 181, 198, 38, 1, 214, 70, 198, 38, 1, 188, 198, 38, 1, 247, 3, 198, 38, + 1, 170, 198, 38, 1, 193, 190, 198, 38, 1, 223, 34, 198, 38, 1, 140, 198, + 38, 1, 165, 198, 38, 1, 173, 198, 38, 1, 68, 198, 38, 1, 248, 40, 68, + 198, 38, 1, 223, 51, 198, 38, 1, 248, 40, 223, 51, 198, 38, 1, 66, 198, + 38, 1, 71, 198, 38, 1, 248, 40, 71, 198, 38, 1, 234, 67, 198, 38, 1, 248, + 40, 234, 67, 198, 38, 1, 74, 198, 38, 1, 252, 27, 198, 38, 1, 248, 40, + 252, 27, 198, 38, 1, 65, 198, 38, 3, 206, 181, 198, 79, 193, 163, 1, 252, + 208, 193, 163, 1, 65, 193, 163, 1, 249, 155, 193, 163, 1, 247, 162, 193, + 163, 1, 238, 34, 193, 163, 1, 231, 242, 193, 163, 1, 170, 193, 163, 1, + 209, 230, 193, 163, 1, 173, 193, 163, 1, 181, 193, 163, 1, 168, 193, 163, + 1, 190, 190, 193, 163, 1, 199, 49, 193, 163, 1, 233, 111, 193, 163, 1, + 188, 193, 163, 1, 203, 166, 193, 163, 1, 223, 34, 193, 163, 1, 191, 123, + 193, 163, 1, 193, 190, 193, 163, 1, 195, 188, 193, 163, 1, 155, 193, 163, + 1, 74, 193, 163, 1, 250, 165, 193, 163, 1, 165, 193, 163, 1, 174, 193, + 163, 1, 221, 217, 193, 163, 1, 140, 193, 163, 1, 71, 193, 163, 1, 68, + 193, 163, 1, 214, 70, 193, 163, 1, 66, 193, 163, 1, 219, 68, 193, 163, 1, + 197, 168, 193, 163, 1, 198, 26, 193, 163, 1, 211, 96, 193, 163, 1, 252, + 167, 193, 163, 1, 251, 124, 193, 163, 1, 223, 138, 193, 163, 1, 211, 106, + 193, 163, 1, 234, 105, 193, 163, 1, 252, 168, 193, 163, 1, 212, 103, 193, + 163, 1, 196, 147, 193, 163, 1, 192, 24, 193, 163, 163, 197, 67, 193, 163, + 163, 197, 66, 193, 163, 163, 221, 56, 193, 163, 163, 221, 55, 193, 163, + 17, 191, 77, 193, 163, 17, 107, 193, 163, 17, 109, 193, 163, 17, 138, + 193, 163, 17, 134, 193, 163, 17, 150, 193, 163, 17, 169, 193, 163, 17, + 175, 193, 163, 17, 171, 193, 163, 17, 178, 193, 163, 213, 234, 56, 214, + 245, 215, 122, 1, 74, 214, 245, 215, 122, 1, 211, 80, 214, 245, 215, 122, + 1, 211, 122, 214, 245, 215, 122, 1, 210, 244, 214, 245, 215, 122, 1, 211, + 96, 214, 245, 215, 122, 1, 65, 214, 245, 215, 122, 1, 251, 220, 214, 245, + 215, 122, 1, 252, 157, 214, 245, 215, 122, 1, 251, 71, 214, 245, 215, + 122, 1, 251, 247, 214, 245, 215, 122, 1, 68, 214, 245, 215, 122, 1, 223, + 70, 214, 245, 215, 122, 1, 228, 20, 214, 245, 215, 122, 1, 223, 55, 214, + 245, 215, 122, 1, 223, 202, 214, 245, 215, 122, 1, 66, 214, 245, 215, + 122, 1, 196, 160, 214, 245, 215, 122, 1, 196, 158, 214, 245, 215, 122, 1, + 196, 128, 214, 245, 215, 122, 1, 196, 62, 214, 245, 215, 122, 1, 71, 214, + 245, 215, 122, 1, 234, 87, 214, 245, 215, 122, 1, 234, 182, 214, 245, + 215, 122, 1, 234, 116, 214, 245, 215, 122, 1, 234, 105, 214, 245, 215, + 122, 1, 233, 247, 214, 245, 215, 122, 1, 234, 124, 214, 245, 215, 122, 3, + 211, 129, 214, 245, 215, 122, 3, 215, 140, 214, 245, 215, 122, 3, 198, + 28, 214, 245, 215, 122, 3, 223, 195, 214, 245, 215, 122, 3, 200, 161, + 214, 245, 215, 122, 17, 191, 77, 214, 245, 215, 122, 17, 107, 214, 245, + 215, 122, 17, 109, 214, 245, 215, 122, 17, 138, 214, 245, 215, 122, 17, + 134, 214, 245, 215, 122, 17, 150, 214, 245, 215, 122, 17, 169, 214, 245, + 215, 122, 17, 175, 214, 245, 215, 122, 17, 171, 214, 245, 215, 122, 17, + 178, 36, 5, 229, 168, 36, 5, 229, 162, 36, 5, 229, 164, 36, 5, 229, 167, + 36, 5, 229, 165, 36, 5, 229, 166, 36, 5, 229, 163, 36, 5, 230, 149, 229, + 172, 36, 5, 229, 169, 36, 5, 229, 170, 36, 5, 229, 171, 36, 5, 230, 149, + 215, 78, 36, 5, 230, 149, 215, 79, 36, 5, 230, 149, 207, 238, 36, 5, 230, + 149, 207, 239, 36, 5, 230, 149, 207, 240, 36, 5, 230, 149, 247, 209, 36, + 5, 230, 149, 247, 210, 36, 5, 230, 149, 220, 174, 36, 5, 230, 149, 220, + 175, 36, 5, 230, 149, 220, 176, 36, 5, 230, 149, 230, 133, 36, 5, 230, + 149, 230, 134, 36, 5, 230, 149, 230, 135, 36, 5, 230, 149, 232, 60, 36, + 5, 230, 149, 232, 61, 36, 5, 230, 149, 208, 120, 36, 5, 230, 149, 208, + 121, 85, 84, 5, 218, 169, 221, 168, 85, 84, 5, 218, 165, 155, 85, 84, 5, + 218, 163, 220, 234, 85, 84, 5, 218, 39, 222, 15, 85, 84, 5, 218, 9, 222, + 24, 85, 84, 5, 218, 28, 221, 43, 85, 84, 5, 218, 56, 221, 69, 85, 84, 5, + 217, 181, 220, 221, 85, 84, 5, 218, 160, 193, 86, 85, 84, 5, 218, 158, + 193, 190, 85, 84, 5, 218, 156, 193, 0, 85, 84, 5, 217, 234, 193, 114, 85, + 84, 5, 217, 242, 193, 125, 85, 84, 5, 217, 246, 193, 29, 85, 84, 5, 218, + 59, 193, 48, 85, 84, 5, 217, 166, 192, 252, 85, 84, 5, 217, 217, 193, + 112, 85, 84, 5, 218, 43, 192, 240, 85, 84, 5, 218, 55, 192, 242, 85, 84, + 5, 217, 221, 192, 241, 85, 84, 5, 218, 154, 216, 46, 85, 84, 5, 218, 152, + 217, 92, 85, 84, 5, 218, 150, 215, 124, 85, 84, 5, 218, 45, 216, 188, 85, + 84, 5, 218, 10, 215, 233, 85, 84, 5, 217, 206, 215, 150, 85, 84, 5, 217, + 171, 215, 144, 85, 84, 5, 218, 148, 248, 190, 85, 84, 5, 218, 145, 249, + 155, 85, 84, 5, 218, 143, 248, 12, 85, 84, 5, 217, 210, 249, 3, 85, 84, + 5, 218, 7, 249, 19, 85, 84, 5, 218, 1, 248, 99, 85, 84, 5, 217, 222, 248, + 113, 85, 84, 5, 218, 133, 68, 85, 84, 5, 218, 131, 65, 85, 84, 5, 218, + 129, 66, 85, 84, 5, 217, 197, 234, 190, 85, 84, 5, 218, 4, 71, 85, 84, 5, + 217, 195, 211, 89, 85, 84, 5, 217, 213, 74, 85, 84, 5, 217, 223, 234, + 168, 85, 84, 5, 217, 229, 223, 164, 85, 84, 5, 217, 225, 223, 164, 85, + 84, 5, 217, 165, 251, 134, 85, 84, 5, 217, 182, 234, 105, 85, 84, 5, 218, + 118, 202, 223, 85, 84, 5, 218, 116, 188, 85, 84, 5, 218, 114, 201, 5, 85, + 84, 5, 217, 198, 205, 51, 85, 84, 5, 217, 244, 205, 69, 85, 84, 5, 217, + 224, 202, 17, 85, 84, 5, 218, 25, 202, 47, 85, 84, 5, 217, 164, 202, 216, + 85, 84, 5, 218, 104, 219, 148, 85, 84, 5, 218, 102, 173, 85, 84, 5, 218, + 100, 218, 227, 85, 84, 5, 218, 20, 219, 230, 85, 84, 5, 218, 31, 219, + 240, 85, 84, 5, 218, 50, 219, 10, 85, 84, 5, 217, 207, 219, 45, 85, 84, + 5, 217, 250, 180, 219, 240, 85, 84, 5, 218, 126, 237, 46, 85, 84, 5, 218, + 123, 238, 34, 85, 84, 5, 218, 120, 235, 91, 85, 84, 5, 218, 15, 237, 133, + 85, 84, 5, 217, 180, 236, 148, 85, 84, 5, 217, 179, 236, 176, 85, 84, 5, + 218, 112, 198, 193, 85, 84, 5, 218, 109, 190, 190, 85, 84, 5, 218, 107, + 197, 94, 85, 84, 5, 218, 13, 199, 121, 85, 84, 5, 218, 49, 199, 145, 85, + 84, 5, 218, 0, 198, 59, 85, 84, 5, 218, 35, 159, 85, 84, 5, 218, 98, 222, + 246, 85, 84, 5, 218, 95, 223, 34, 85, 84, 5, 218, 93, 222, 184, 85, 84, + 5, 217, 203, 223, 10, 85, 84, 5, 217, 247, 223, 12, 85, 84, 5, 217, 200, + 222, 193, 85, 84, 5, 218, 41, 222, 203, 85, 84, 5, 217, 185, 180, 222, + 203, 85, 84, 5, 218, 91, 192, 33, 85, 84, 5, 218, 88, 170, 85, 84, 5, + 218, 86, 191, 225, 85, 84, 5, 217, 251, 192, 77, 85, 84, 5, 218, 24, 192, + 80, 85, 84, 5, 217, 219, 191, 246, 85, 84, 5, 217, 239, 192, 12, 85, 84, + 5, 218, 82, 233, 25, 85, 84, 5, 218, 80, 233, 111, 85, 84, 5, 218, 78, + 232, 88, 85, 84, 5, 218, 26, 233, 54, 85, 84, 5, 218, 29, 233, 61, 85, + 84, 5, 217, 227, 232, 164, 85, 84, 5, 218, 16, 232, 177, 85, 84, 5, 217, + 163, 232, 87, 85, 84, 5, 218, 3, 233, 82, 85, 84, 5, 218, 76, 213, 181, + 85, 84, 5, 218, 74, 214, 228, 85, 84, 5, 218, 72, 212, 132, 85, 84, 5, + 217, 243, 214, 104, 85, 84, 5, 217, 191, 213, 33, 85, 84, 5, 217, 184, + 229, 160, 85, 84, 5, 218, 67, 140, 85, 84, 5, 217, 174, 228, 161, 85, 84, + 5, 218, 70, 229, 217, 85, 84, 5, 218, 8, 229, 247, 85, 84, 5, 218, 65, + 228, 254, 85, 84, 5, 217, 220, 229, 25, 85, 84, 5, 218, 21, 229, 216, 85, + 84, 5, 217, 232, 228, 247, 85, 84, 5, 218, 51, 229, 130, 85, 84, 5, 217, + 230, 230, 58, 85, 84, 5, 218, 17, 228, 144, 85, 84, 5, 218, 52, 229, 200, + 85, 84, 5, 217, 167, 229, 1, 85, 84, 5, 218, 58, 228, 157, 85, 84, 5, + 218, 14, 214, 35, 85, 84, 5, 218, 63, 214, 49, 85, 84, 5, 218, 22, 214, + 32, 85, 84, 5, 217, 245, 214, 43, 85, 84, 5, 217, 214, 214, 44, 85, 84, + 5, 217, 204, 214, 33, 85, 84, 5, 217, 240, 214, 34, 85, 84, 5, 217, 201, + 214, 48, 85, 84, 5, 217, 233, 214, 31, 85, 84, 5, 218, 18, 180, 214, 44, + 85, 84, 5, 217, 254, 180, 214, 33, 85, 84, 5, 217, 177, 180, 214, 34, 85, + 84, 5, 217, 205, 231, 55, 85, 84, 5, 217, 249, 231, 242, 85, 84, 5, 217, + 192, 230, 181, 85, 84, 5, 217, 170, 231, 159, 85, 84, 5, 217, 194, 230, + 167, 85, 84, 5, 217, 193, 230, 177, 85, 84, 5, 217, 176, 214, 54, 85, 84, + 5, 218, 47, 213, 247, 85, 84, 5, 217, 183, 213, 236, 85, 84, 5, 218, 36, + 209, 187, 85, 84, 5, 218, 5, 168, 85, 84, 5, 218, 54, 208, 167, 85, 84, + 5, 218, 23, 210, 51, 85, 84, 5, 218, 53, 210, 65, 85, 84, 5, 218, 2, 209, + 39, 85, 84, 5, 218, 38, 209, 75, 85, 84, 5, 217, 215, 216, 254, 85, 84, + 5, 218, 42, 217, 13, 85, 84, 5, 217, 238, 216, 248, 85, 84, 5, 218, 57, + 217, 5, 85, 84, 5, 217, 172, 217, 5, 85, 84, 5, 218, 32, 217, 6, 85, 84, + 5, 217, 188, 216, 249, 85, 84, 5, 217, 186, 216, 250, 85, 84, 5, 217, + 173, 216, 242, 85, 84, 5, 217, 199, 180, 217, 6, 85, 84, 5, 217, 255, + 180, 216, 249, 85, 84, 5, 217, 218, 180, 216, 250, 85, 84, 5, 217, 228, + 221, 15, 85, 84, 5, 218, 12, 221, 23, 85, 84, 5, 218, 30, 221, 11, 85, + 84, 5, 218, 61, 221, 18, 85, 84, 5, 217, 252, 221, 19, 85, 84, 5, 217, + 248, 221, 13, 85, 84, 5, 217, 202, 221, 14, 85, 84, 5, 217, 236, 231, + 176, 85, 84, 5, 218, 48, 231, 184, 85, 84, 5, 217, 212, 231, 171, 85, 84, + 5, 218, 11, 231, 180, 85, 84, 5, 217, 253, 231, 181, 85, 84, 5, 218, 33, + 231, 172, 85, 84, 5, 218, 34, 231, 174, 85, 84, 5, 217, 189, 165, 85, 84, + 5, 217, 237, 214, 149, 85, 84, 5, 217, 231, 214, 164, 85, 84, 5, 217, + 235, 214, 131, 85, 84, 5, 217, 169, 214, 155, 85, 84, 5, 217, 241, 214, + 156, 85, 84, 5, 218, 37, 214, 136, 85, 84, 5, 218, 40, 214, 140, 85, 84, + 5, 217, 208, 213, 159, 85, 84, 5, 217, 168, 213, 129, 85, 84, 5, 217, + 211, 213, 150, 85, 84, 5, 217, 226, 213, 133, 85, 84, 5, 217, 178, 195, + 69, 85, 84, 5, 217, 175, 195, 188, 85, 84, 5, 217, 209, 193, 249, 85, 84, + 5, 217, 187, 195, 148, 85, 84, 5, 218, 19, 195, 153, 85, 84, 5, 217, 216, + 195, 8, 85, 84, 5, 218, 27, 195, 24, 85, 84, 5, 217, 196, 212, 76, 85, + 84, 5, 218, 46, 212, 96, 85, 84, 5, 217, 190, 212, 58, 85, 84, 5, 218, 6, + 212, 88, 85, 84, 5, 218, 44, 212, 65, 85, 84, 17, 107, 85, 84, 17, 109, + 85, 84, 17, 138, 85, 84, 17, 134, 85, 84, 17, 150, 85, 84, 17, 169, 85, + 84, 17, 175, 85, 84, 17, 171, 85, 84, 17, 178, 85, 84, 33, 31, 199, 119, + 85, 84, 33, 31, 199, 90, 85, 84, 33, 31, 228, 140, 85, 84, 33, 31, 198, + 228, 85, 84, 33, 31, 199, 96, 198, 228, 85, 84, 33, 31, 228, 143, 198, + 228, 85, 84, 33, 31, 216, 49, 252, 35, 6, 1, 251, 182, 252, 35, 6, 1, + 238, 31, 252, 35, 6, 1, 220, 125, 252, 35, 6, 1, 216, 62, 252, 35, 6, 1, + 249, 155, 252, 35, 6, 1, 202, 165, 252, 35, 6, 1, 210, 65, 252, 35, 6, 1, + 248, 198, 252, 35, 6, 1, 165, 252, 35, 6, 1, 71, 252, 35, 6, 1, 233, 111, + 252, 35, 6, 1, 68, 252, 35, 6, 1, 74, 252, 35, 6, 1, 237, 70, 252, 35, 6, + 1, 192, 34, 252, 35, 6, 1, 193, 133, 252, 35, 6, 1, 212, 132, 252, 35, 6, + 1, 222, 108, 252, 35, 6, 1, 170, 252, 35, 6, 1, 66, 252, 35, 6, 1, 222, + 237, 252, 35, 6, 1, 243, 97, 252, 35, 6, 1, 140, 252, 35, 6, 1, 208, 96, + 252, 35, 6, 1, 231, 242, 252, 35, 6, 1, 212, 103, 252, 35, 6, 1, 197, 94, + 252, 35, 6, 1, 213, 226, 252, 35, 6, 1, 195, 188, 252, 35, 6, 1, 221, + 217, 252, 35, 6, 1, 231, 181, 252, 35, 6, 1, 191, 108, 252, 35, 6, 1, + 221, 14, 252, 35, 6, 1, 203, 166, 252, 35, 2, 1, 251, 182, 252, 35, 2, 1, + 238, 31, 252, 35, 2, 1, 220, 125, 252, 35, 2, 1, 216, 62, 252, 35, 2, 1, + 249, 155, 252, 35, 2, 1, 202, 165, 252, 35, 2, 1, 210, 65, 252, 35, 2, 1, + 248, 198, 252, 35, 2, 1, 165, 252, 35, 2, 1, 71, 252, 35, 2, 1, 233, 111, + 252, 35, 2, 1, 68, 252, 35, 2, 1, 74, 252, 35, 2, 1, 237, 70, 252, 35, 2, + 1, 192, 34, 252, 35, 2, 1, 193, 133, 252, 35, 2, 1, 212, 132, 252, 35, 2, + 1, 222, 108, 252, 35, 2, 1, 170, 252, 35, 2, 1, 66, 252, 35, 2, 1, 222, + 237, 252, 35, 2, 1, 243, 97, 252, 35, 2, 1, 140, 252, 35, 2, 1, 208, 96, + 252, 35, 2, 1, 231, 242, 252, 35, 2, 1, 212, 103, 252, 35, 2, 1, 197, 94, + 252, 35, 2, 1, 213, 226, 252, 35, 2, 1, 195, 188, 252, 35, 2, 1, 221, + 217, 252, 35, 2, 1, 231, 181, 252, 35, 2, 1, 191, 108, 252, 35, 2, 1, + 221, 14, 252, 35, 2, 1, 203, 166, 252, 35, 251, 183, 219, 192, 252, 35, + 18, 219, 192, 252, 35, 231, 155, 77, 252, 35, 230, 59, 252, 35, 120, 215, + 254, 252, 35, 231, 156, 120, 215, 254, 252, 35, 212, 143, 252, 35, 214, + 215, 77, 252, 35, 17, 191, 77, 252, 35, 17, 107, 252, 35, 17, 109, 252, + 35, 17, 138, 252, 35, 17, 134, 252, 35, 17, 150, 252, 35, 17, 169, 252, + 35, 17, 175, 252, 35, 17, 171, 252, 35, 17, 178, 252, 35, 89, 233, 218, + 77, 252, 35, 89, 208, 15, 77, 223, 148, 143, 31, 107, 223, 148, 143, 31, + 109, 223, 148, 143, 31, 138, 223, 148, 143, 31, 134, 223, 148, 143, 31, + 150, 223, 148, 143, 31, 169, 223, 148, 143, 31, 175, 223, 148, 143, 31, + 171, 223, 148, 143, 31, 178, 223, 148, 143, 31, 199, 95, 223, 148, 143, + 31, 197, 32, 223, 148, 143, 31, 198, 249, 223, 148, 143, 31, 232, 137, + 223, 148, 143, 31, 233, 17, 223, 148, 143, 31, 202, 121, 223, 148, 143, + 31, 203, 242, 223, 148, 143, 31, 234, 155, 223, 148, 143, 31, 213, 171, + 223, 148, 143, 31, 91, 228, 142, 223, 148, 143, 31, 105, 228, 142, 223, + 148, 143, 31, 115, 228, 142, 223, 148, 143, 31, 232, 130, 228, 142, 223, + 148, 143, 31, 232, 228, 228, 142, 223, 148, 143, 31, 202, 137, 228, 142, + 223, 148, 143, 31, 203, 248, 228, 142, 223, 148, 143, 31, 234, 166, 228, + 142, 223, 148, 143, 31, 213, 177, 228, 142, 223, 148, 143, 31, 91, 189, + 223, 148, 143, 31, 105, 189, 223, 148, 143, 31, 115, 189, 223, 148, 143, + 31, 232, 130, 189, 223, 148, 143, 31, 232, 228, 189, 223, 148, 143, 31, + 202, 137, 189, 223, 148, 143, 31, 203, 248, 189, 223, 148, 143, 31, 234, + 166, 189, 223, 148, 143, 31, 213, 177, 189, 223, 148, 143, 31, 199, 96, + 189, 223, 148, 143, 31, 197, 33, 189, 223, 148, 143, 31, 198, 250, 189, + 223, 148, 143, 31, 232, 138, 189, 223, 148, 143, 31, 233, 18, 189, 223, + 148, 143, 31, 202, 122, 189, 223, 148, 143, 31, 203, 243, 189, 223, 148, + 143, 31, 234, 156, 189, 223, 148, 143, 31, 213, 172, 189, 223, 148, 143, + 31, 220, 43, 223, 148, 143, 31, 220, 42, 223, 148, 143, 220, 44, 77, 223, + 148, 143, 31, 222, 62, 223, 148, 143, 31, 222, 61, 223, 148, 143, 31, + 208, 229, 107, 223, 148, 143, 31, 208, 229, 109, 223, 148, 143, 31, 208, + 229, 138, 223, 148, 143, 31, 208, 229, 134, 223, 148, 143, 31, 208, 229, + 150, 223, 148, 143, 31, 208, 229, 169, 223, 148, 143, 31, 208, 229, 175, + 223, 148, 143, 31, 208, 229, 171, 223, 148, 143, 31, 208, 229, 178, 223, + 148, 143, 209, 108, 223, 148, 143, 232, 120, 91, 208, 24, 223, 148, 143, + 232, 120, 91, 230, 72, 223, 148, 143, 232, 120, 115, 208, 22, 223, 148, + 143, 206, 37, 77, 223, 148, 143, 31, 251, 159, 107, 223, 148, 143, 31, + 251, 159, 109, 223, 148, 143, 31, 251, 159, 199, 96, 189, 223, 148, 143, + 251, 159, 220, 44, 77, 211, 23, 143, 31, 107, 211, 23, 143, 31, 109, 211, + 23, 143, 31, 138, 211, 23, 143, 31, 134, 211, 23, 143, 31, 150, 211, 23, + 143, 31, 169, 211, 23, 143, 31, 175, 211, 23, 143, 31, 171, 211, 23, 143, + 31, 178, 211, 23, 143, 31, 199, 95, 211, 23, 143, 31, 197, 32, 211, 23, + 143, 31, 198, 249, 211, 23, 143, 31, 232, 137, 211, 23, 143, 31, 233, 17, + 211, 23, 143, 31, 202, 121, 211, 23, 143, 31, 203, 242, 211, 23, 143, 31, + 234, 155, 211, 23, 143, 31, 213, 171, 211, 23, 143, 31, 91, 228, 142, + 211, 23, 143, 31, 105, 228, 142, 211, 23, 143, 31, 115, 228, 142, 211, + 23, 143, 31, 232, 130, 228, 142, 211, 23, 143, 31, 232, 228, 228, 142, + 211, 23, 143, 31, 202, 137, 228, 142, 211, 23, 143, 31, 203, 248, 228, + 142, 211, 23, 143, 31, 234, 166, 228, 142, 211, 23, 143, 31, 213, 177, + 228, 142, 211, 23, 143, 31, 91, 189, 211, 23, 143, 31, 105, 189, 211, 23, + 143, 31, 115, 189, 211, 23, 143, 31, 232, 130, 189, 211, 23, 143, 31, + 232, 228, 189, 211, 23, 143, 31, 202, 137, 189, 211, 23, 143, 31, 203, + 248, 189, 211, 23, 143, 31, 234, 166, 189, 211, 23, 143, 31, 213, 177, + 189, 211, 23, 143, 31, 199, 96, 189, 211, 23, 143, 31, 197, 33, 189, 211, + 23, 143, 31, 198, 250, 189, 211, 23, 143, 31, 232, 138, 189, 211, 23, + 143, 31, 233, 18, 189, 211, 23, 143, 31, 202, 122, 189, 211, 23, 143, 31, + 203, 243, 189, 211, 23, 143, 31, 234, 156, 189, 211, 23, 143, 31, 213, + 172, 189, 211, 23, 143, 217, 51, 211, 23, 143, 251, 159, 31, 109, 211, + 23, 143, 251, 159, 31, 138, 211, 23, 143, 251, 159, 31, 134, 211, 23, + 143, 251, 159, 31, 150, 211, 23, 143, 251, 159, 31, 169, 211, 23, 143, + 251, 159, 31, 175, 211, 23, 143, 251, 159, 31, 171, 211, 23, 143, 251, + 159, 31, 178, 211, 23, 143, 251, 159, 31, 199, 95, 211, 23, 143, 251, + 159, 31, 232, 130, 228, 142, 211, 23, 143, 251, 159, 31, 202, 137, 228, + 142, 211, 23, 143, 251, 159, 31, 105, 189, 211, 23, 143, 251, 159, 31, + 199, 96, 189, 211, 23, 143, 232, 120, 91, 230, 72, 211, 23, 143, 232, + 120, 91, 202, 125, 9, 13, 251, 194, 9, 13, 248, 247, 9, 13, 223, 8, 9, + 13, 238, 5, 9, 13, 193, 133, 9, 13, 191, 113, 9, 13, 230, 83, 9, 13, 199, + 219, 9, 13, 192, 75, 9, 13, 222, 108, 9, 13, 220, 37, 9, 13, 216, 210, 9, + 13, 213, 26, 9, 13, 205, 47, 9, 13, 251, 232, 9, 13, 233, 48, 9, 13, 205, + 193, 9, 13, 208, 91, 9, 13, 207, 72, 9, 13, 203, 110, 9, 13, 199, 114, 9, + 13, 199, 29, 9, 13, 221, 212, 9, 13, 199, 41, 9, 13, 238, 28, 9, 13, 191, + 116, 9, 13, 231, 88, 9, 13, 236, 141, 248, 247, 9, 13, 236, 141, 213, 26, + 9, 13, 236, 141, 233, 48, 9, 13, 236, 141, 208, 91, 9, 13, 89, 248, 247, + 9, 13, 89, 223, 8, 9, 13, 89, 229, 212, 9, 13, 89, 230, 83, 9, 13, 89, + 192, 75, 9, 13, 89, 222, 108, 9, 13, 89, 220, 37, 9, 13, 89, 216, 210, 9, + 13, 89, 213, 26, 9, 13, 89, 205, 47, 9, 13, 89, 251, 232, 9, 13, 89, 233, + 48, 9, 13, 89, 205, 193, 9, 13, 89, 208, 91, 9, 13, 89, 203, 110, 9, 13, + 89, 199, 114, 9, 13, 89, 199, 29, 9, 13, 89, 221, 212, 9, 13, 89, 238, + 28, 9, 13, 89, 231, 88, 9, 13, 199, 214, 223, 8, 9, 13, 199, 214, 230, + 83, 9, 13, 199, 214, 192, 75, 9, 13, 199, 214, 220, 37, 9, 13, 199, 214, + 213, 26, 9, 13, 199, 214, 205, 47, 9, 13, 199, 214, 251, 232, 9, 13, 199, + 214, 205, 193, 9, 13, 199, 214, 208, 91, 9, 13, 199, 214, 203, 110, 9, + 13, 199, 214, 221, 212, 9, 13, 199, 214, 238, 28, 9, 13, 199, 214, 231, + 88, 9, 13, 199, 214, 236, 141, 213, 26, 9, 13, 199, 214, 236, 141, 208, + 91, 9, 13, 201, 37, 248, 247, 9, 13, 201, 37, 223, 8, 9, 13, 201, 37, + 229, 212, 9, 13, 201, 37, 230, 83, 9, 13, 201, 37, 199, 219, 9, 13, 201, + 37, 192, 75, 9, 13, 201, 37, 222, 108, 9, 13, 201, 37, 216, 210, 9, 13, + 201, 37, 213, 26, 9, 13, 201, 37, 205, 47, 9, 13, 201, 37, 251, 232, 9, + 13, 201, 37, 233, 48, 9, 13, 201, 37, 205, 193, 9, 13, 201, 37, 208, 91, + 9, 13, 201, 37, 203, 110, 9, 13, 201, 37, 199, 114, 9, 13, 201, 37, 199, + 29, 9, 13, 201, 37, 221, 212, 9, 13, 201, 37, 238, 28, 9, 13, 201, 37, + 191, 116, 9, 13, 201, 37, 231, 88, 9, 13, 201, 37, 236, 141, 248, 247, 9, + 13, 201, 37, 236, 141, 233, 48, 9, 13, 219, 5, 251, 194, 9, 13, 219, 5, + 248, 247, 9, 13, 219, 5, 223, 8, 9, 13, 219, 5, 238, 5, 9, 13, 219, 5, + 229, 212, 9, 13, 219, 5, 193, 133, 9, 13, 219, 5, 191, 113, 9, 13, 219, + 5, 230, 83, 9, 13, 219, 5, 199, 219, 9, 13, 219, 5, 192, 75, 9, 13, 219, + 5, 220, 37, 9, 13, 219, 5, 216, 210, 9, 13, 219, 5, 213, 26, 9, 13, 219, + 5, 205, 47, 9, 13, 219, 5, 251, 232, 9, 13, 219, 5, 233, 48, 9, 13, 219, + 5, 205, 193, 9, 13, 219, 5, 208, 91, 9, 13, 219, 5, 207, 72, 9, 13, 219, + 5, 203, 110, 9, 13, 219, 5, 199, 114, 9, 13, 219, 5, 199, 29, 9, 13, 219, + 5, 221, 212, 9, 13, 219, 5, 199, 41, 9, 13, 219, 5, 238, 28, 9, 13, 219, + 5, 191, 116, 9, 13, 219, 5, 231, 88, 9, 13, 235, 131, 248, 247, 9, 13, + 235, 131, 223, 8, 9, 13, 235, 131, 238, 5, 9, 13, 235, 131, 193, 133, 9, + 13, 235, 131, 191, 113, 9, 13, 235, 131, 230, 83, 9, 13, 235, 131, 199, + 219, 9, 13, 235, 131, 192, 75, 9, 13, 235, 131, 220, 37, 9, 13, 235, 131, + 216, 210, 9, 13, 235, 131, 213, 26, 9, 13, 235, 131, 205, 47, 9, 13, 235, + 131, 251, 232, 9, 13, 235, 131, 233, 48, 9, 13, 235, 131, 205, 193, 9, + 13, 235, 131, 208, 91, 9, 13, 235, 131, 207, 72, 9, 13, 235, 131, 203, + 110, 9, 13, 235, 131, 199, 114, 9, 13, 235, 131, 199, 29, 9, 13, 235, + 131, 221, 212, 9, 13, 235, 131, 199, 41, 9, 13, 235, 131, 238, 28, 9, 13, + 235, 131, 191, 116, 9, 13, 235, 131, 231, 88, 9, 13, 211, 69, 92, 4, 183, + 4, 199, 168, 9, 13, 211, 69, 183, 4, 238, 5, 217, 116, 123, 234, 206, + 193, 66, 217, 116, 123, 202, 3, 193, 66, 217, 116, 123, 193, 105, 193, + 66, 217, 116, 123, 186, 193, 66, 217, 116, 123, 207, 89, 235, 113, 217, + 116, 123, 230, 203, 235, 113, 217, 116, 123, 63, 235, 113, 217, 116, 123, + 91, 79, 243, 142, 217, 116, 123, 105, 79, 243, 142, 217, 116, 123, 115, + 79, 243, 142, 217, 116, 123, 232, 130, 79, 243, 142, 217, 116, 123, 232, + 228, 79, 243, 142, 217, 116, 123, 202, 137, 79, 243, 142, 217, 116, 123, + 203, 248, 79, 243, 142, 217, 116, 123, 234, 166, 79, 243, 142, 217, 116, + 123, 213, 177, 79, 243, 142, 217, 116, 123, 91, 79, 249, 104, 217, 116, + 123, 105, 79, 249, 104, 217, 116, 123, 115, 79, 249, 104, 217, 116, 123, + 232, 130, 79, 249, 104, 217, 116, 123, 232, 228, 79, 249, 104, 217, 116, + 123, 202, 137, 79, 249, 104, 217, 116, 123, 203, 248, 79, 249, 104, 217, + 116, 123, 234, 166, 79, 249, 104, 217, 116, 123, 213, 177, 79, 249, 104, + 217, 116, 123, 91, 79, 243, 9, 217, 116, 123, 105, 79, 243, 9, 217, 116, + 123, 115, 79, 243, 9, 217, 116, 123, 232, 130, 79, 243, 9, 217, 116, 123, + 232, 228, 79, 243, 9, 217, 116, 123, 202, 137, 79, 243, 9, 217, 116, 123, + 203, 248, 79, 243, 9, 217, 116, 123, 234, 166, 79, 243, 9, 217, 116, 123, + 213, 177, 79, 243, 9, 217, 116, 123, 209, 87, 217, 116, 123, 211, 55, + 217, 116, 123, 249, 105, 217, 116, 123, 243, 51, 217, 116, 123, 201, 197, + 217, 116, 123, 200, 200, 217, 116, 123, 250, 151, 217, 116, 123, 193, 56, + 217, 116, 123, 222, 196, 217, 116, 123, 249, 148, 236, 153, 123, 228, + 243, 249, 148, 236, 153, 123, 228, 241, 236, 153, 123, 228, 240, 236, + 153, 123, 228, 239, 236, 153, 123, 228, 238, 236, 153, 123, 228, 237, + 236, 153, 123, 228, 236, 236, 153, 123, 228, 235, 236, 153, 123, 228, + 234, 236, 153, 123, 228, 233, 236, 153, 123, 228, 232, 236, 153, 123, + 228, 231, 236, 153, 123, 228, 230, 236, 153, 123, 228, 229, 236, 153, + 123, 228, 228, 236, 153, 123, 228, 227, 236, 153, 123, 228, 226, 236, + 153, 123, 228, 225, 236, 153, 123, 228, 224, 236, 153, 123, 228, 223, + 236, 153, 123, 228, 222, 236, 153, 123, 228, 221, 236, 153, 123, 228, + 220, 236, 153, 123, 228, 219, 236, 153, 123, 228, 218, 236, 153, 123, + 228, 217, 236, 153, 123, 228, 216, 236, 153, 123, 228, 215, 236, 153, + 123, 228, 214, 236, 153, 123, 228, 213, 236, 153, 123, 228, 212, 236, + 153, 123, 228, 211, 236, 153, 123, 228, 210, 236, 153, 123, 228, 209, + 236, 153, 123, 228, 208, 236, 153, 123, 228, 207, 236, 153, 123, 228, + 206, 236, 153, 123, 228, 205, 236, 153, 123, 228, 204, 236, 153, 123, + 228, 203, 236, 153, 123, 228, 202, 236, 153, 123, 228, 201, 236, 153, + 123, 228, 200, 236, 153, 123, 228, 199, 236, 153, 123, 228, 198, 236, + 153, 123, 228, 197, 236, 153, 123, 228, 196, 236, 153, 123, 228, 195, + 236, 153, 123, 228, 194, 236, 153, 123, 228, 193, 236, 153, 123, 81, 249, + 148, 236, 153, 123, 195, 134, 236, 153, 123, 195, 133, 236, 153, 123, + 195, 132, 236, 153, 123, 195, 131, 236, 153, 123, 195, 130, 236, 153, + 123, 195, 129, 236, 153, 123, 195, 128, 236, 153, 123, 195, 127, 236, + 153, 123, 195, 126, 236, 153, 123, 195, 125, 236, 153, 123, 195, 124, + 236, 153, 123, 195, 123, 236, 153, 123, 195, 122, 236, 153, 123, 195, + 121, 236, 153, 123, 195, 120, 236, 153, 123, 195, 119, 236, 153, 123, + 195, 118, 236, 153, 123, 195, 117, 236, 153, 123, 195, 116, 236, 153, + 123, 195, 115, 236, 153, 123, 195, 114, 236, 153, 123, 195, 113, 236, + 153, 123, 195, 112, 236, 153, 123, 195, 111, 236, 153, 123, 195, 110, + 236, 153, 123, 195, 109, 236, 153, 123, 195, 108, 236, 153, 123, 195, + 107, 236, 153, 123, 195, 106, 236, 153, 123, 195, 105, 236, 153, 123, + 195, 104, 236, 153, 123, 195, 103, 236, 153, 123, 195, 102, 236, 153, + 123, 195, 101, 236, 153, 123, 195, 100, 236, 153, 123, 195, 99, 236, 153, + 123, 195, 98, 236, 153, 123, 195, 97, 236, 153, 123, 195, 96, 236, 153, + 123, 195, 95, 236, 153, 123, 195, 94, 236, 153, 123, 195, 93, 236, 153, + 123, 195, 92, 236, 153, 123, 195, 91, 236, 153, 123, 195, 90, 236, 153, + 123, 195, 89, 236, 153, 123, 195, 88, 236, 153, 123, 195, 87, 236, 153, + 123, 195, 86, 209, 97, 247, 103, 249, 148, 209, 97, 247, 103, 252, 55, + 79, 201, 245, 209, 97, 247, 103, 105, 79, 201, 245, 209, 97, 247, 103, + 115, 79, 201, 245, 209, 97, 247, 103, 232, 130, 79, 201, 245, 209, 97, + 247, 103, 232, 228, 79, 201, 245, 209, 97, 247, 103, 202, 137, 79, 201, + 245, 209, 97, 247, 103, 203, 248, 79, 201, 245, 209, 97, 247, 103, 234, + 166, 79, 201, 245, 209, 97, 247, 103, 213, 177, 79, 201, 245, 209, 97, + 247, 103, 199, 96, 79, 201, 245, 209, 97, 247, 103, 223, 32, 79, 201, + 245, 209, 97, 247, 103, 221, 79, 79, 201, 245, 209, 97, 247, 103, 208, + 17, 79, 201, 245, 209, 97, 247, 103, 221, 141, 79, 201, 245, 209, 97, + 247, 103, 252, 55, 79, 229, 223, 209, 97, 247, 103, 105, 79, 229, 223, + 209, 97, 247, 103, 115, 79, 229, 223, 209, 97, 247, 103, 232, 130, 79, + 229, 223, 209, 97, 247, 103, 232, 228, 79, 229, 223, 209, 97, 247, 103, + 202, 137, 79, 229, 223, 209, 97, 247, 103, 203, 248, 79, 229, 223, 209, + 97, 247, 103, 234, 166, 79, 229, 223, 209, 97, 247, 103, 213, 177, 79, + 229, 223, 209, 97, 247, 103, 199, 96, 79, 229, 223, 209, 97, 247, 103, + 223, 32, 79, 229, 223, 209, 97, 247, 103, 221, 79, 79, 229, 223, 209, 97, + 247, 103, 208, 17, 79, 229, 223, 209, 97, 247, 103, 221, 141, 79, 229, + 223, 209, 97, 247, 103, 207, 89, 222, 196, 209, 97, 247, 103, 252, 55, + 79, 237, 33, 209, 97, 247, 103, 105, 79, 237, 33, 209, 97, 247, 103, 115, + 79, 237, 33, 209, 97, 247, 103, 232, 130, 79, 237, 33, 209, 97, 247, 103, + 232, 228, 79, 237, 33, 209, 97, 247, 103, 202, 137, 79, 237, 33, 209, 97, + 247, 103, 203, 248, 79, 237, 33, 209, 97, 247, 103, 234, 166, 79, 237, + 33, 209, 97, 247, 103, 213, 177, 79, 237, 33, 209, 97, 247, 103, 199, 96, + 79, 237, 33, 209, 97, 247, 103, 223, 32, 79, 237, 33, 209, 97, 247, 103, + 221, 79, 79, 237, 33, 209, 97, 247, 103, 208, 17, 79, 237, 33, 209, 97, + 247, 103, 221, 141, 79, 237, 33, 209, 97, 247, 103, 62, 222, 196, 209, + 97, 247, 103, 252, 55, 79, 242, 206, 209, 97, 247, 103, 105, 79, 242, + 206, 209, 97, 247, 103, 115, 79, 242, 206, 209, 97, 247, 103, 232, 130, + 79, 242, 206, 209, 97, 247, 103, 232, 228, 79, 242, 206, 209, 97, 247, + 103, 202, 137, 79, 242, 206, 209, 97, 247, 103, 203, 248, 79, 242, 206, + 209, 97, 247, 103, 234, 166, 79, 242, 206, 209, 97, 247, 103, 213, 177, + 79, 242, 206, 209, 97, 247, 103, 199, 96, 79, 242, 206, 209, 97, 247, + 103, 223, 32, 79, 242, 206, 209, 97, 247, 103, 221, 79, 79, 242, 206, + 209, 97, 247, 103, 208, 17, 79, 242, 206, 209, 97, 247, 103, 221, 141, + 79, 242, 206, 209, 97, 247, 103, 63, 222, 196, 209, 97, 247, 103, 232, + 162, 209, 97, 247, 103, 197, 200, 209, 97, 247, 103, 197, 189, 209, 97, + 247, 103, 197, 186, 209, 97, 247, 103, 197, 185, 209, 97, 247, 103, 197, + 184, 209, 97, 247, 103, 197, 183, 209, 97, 247, 103, 197, 182, 209, 97, + 247, 103, 197, 181, 209, 97, 247, 103, 197, 180, 209, 97, 247, 103, 197, + 199, 209, 97, 247, 103, 197, 198, 209, 97, 247, 103, 197, 197, 209, 97, + 247, 103, 197, 196, 209, 97, 247, 103, 197, 195, 209, 97, 247, 103, 197, + 194, 209, 97, 247, 103, 197, 193, 209, 97, 247, 103, 197, 192, 209, 97, + 247, 103, 197, 191, 209, 97, 247, 103, 197, 190, 209, 97, 247, 103, 197, + 188, 209, 97, 247, 103, 197, 187, 17, 191, 78, 232, 82, 201, 64, 17, 191, + 78, 242, 76, 17, 91, 242, 76, 17, 105, 242, 76, 17, 115, 242, 76, 17, + 232, 130, 242, 76, 17, 232, 228, 242, 76, 17, 202, 137, 242, 76, 17, 203, + 248, 242, 76, 17, 234, 166, 242, 76, 17, 213, 177, 242, 76, 236, 243, 47, + 49, 17, 191, 77, 236, 243, 214, 108, 47, 49, 17, 191, 77, 47, 191, 78, 4, + 202, 98, 47, 251, 87, 57, 47, 236, 157, 3, 4, 211, 6, 249, 143, 127, 8, + 6, 1, 65, 127, 8, 6, 1, 250, 122, 127, 8, 6, 1, 247, 195, 127, 8, 6, 1, + 238, 129, 127, 8, 6, 1, 71, 127, 8, 6, 1, 233, 177, 127, 8, 6, 1, 232, + 53, 127, 8, 6, 1, 230, 118, 127, 8, 6, 1, 68, 127, 8, 6, 1, 223, 37, 127, + 8, 6, 1, 222, 154, 127, 8, 6, 1, 172, 127, 8, 6, 1, 218, 170, 127, 8, 6, + 1, 215, 63, 127, 8, 6, 1, 74, 127, 8, 6, 1, 210, 238, 127, 8, 6, 1, 208, + 106, 127, 8, 6, 1, 146, 127, 8, 6, 1, 206, 9, 127, 8, 6, 1, 200, 43, 127, 8, 6, 1, 66, 127, 8, 6, 1, 196, 12, 127, 8, 6, 1, 193, 224, 127, 8, 6, 1, 192, 235, 127, 8, 6, 1, 192, 159, 127, 8, 6, 1, 191, 166, 198, 42, 203, - 103, 248, 52, 8, 6, 1, 206, 8, 47, 43, 8, 6, 1, 247, 193, 47, 43, 8, 6, - 1, 146, 47, 247, 43, 47, 192, 237, 239, 7, 113, 112, 8, 6, 1, 65, 112, 8, - 6, 1, 250, 120, 112, 8, 6, 1, 247, 193, 112, 8, 6, 1, 238, 127, 112, 8, - 6, 1, 71, 112, 8, 6, 1, 233, 175, 112, 8, 6, 1, 232, 51, 112, 8, 6, 1, - 230, 116, 112, 8, 6, 1, 68, 112, 8, 6, 1, 223, 35, 112, 8, 6, 1, 222, - 152, 112, 8, 6, 1, 172, 112, 8, 6, 1, 218, 168, 112, 8, 6, 1, 215, 61, - 112, 8, 6, 1, 74, 112, 8, 6, 1, 210, 236, 112, 8, 6, 1, 208, 104, 112, 8, - 6, 1, 146, 112, 8, 6, 1, 206, 8, 112, 8, 6, 1, 200, 43, 112, 8, 6, 1, 66, + 104, 248, 54, 8, 6, 1, 206, 9, 47, 43, 8, 6, 1, 247, 195, 47, 43, 8, 6, + 1, 146, 47, 247, 45, 47, 192, 237, 239, 9, 113, 112, 8, 6, 1, 65, 112, 8, + 6, 1, 250, 122, 112, 8, 6, 1, 247, 195, 112, 8, 6, 1, 238, 129, 112, 8, + 6, 1, 71, 112, 8, 6, 1, 233, 177, 112, 8, 6, 1, 232, 53, 112, 8, 6, 1, + 230, 118, 112, 8, 6, 1, 68, 112, 8, 6, 1, 223, 37, 112, 8, 6, 1, 222, + 154, 112, 8, 6, 1, 172, 112, 8, 6, 1, 218, 170, 112, 8, 6, 1, 215, 63, + 112, 8, 6, 1, 74, 112, 8, 6, 1, 210, 238, 112, 8, 6, 1, 208, 106, 112, 8, + 6, 1, 146, 112, 8, 6, 1, 206, 9, 112, 8, 6, 1, 200, 43, 112, 8, 6, 1, 66, 112, 8, 6, 1, 196, 12, 112, 8, 6, 1, 193, 224, 112, 8, 6, 1, 192, 235, - 112, 8, 6, 1, 192, 159, 112, 8, 6, 1, 191, 166, 112, 228, 126, 112, 215, - 87, 112, 205, 70, 112, 201, 178, 112, 208, 248, 112, 193, 126, 214, 106, - 47, 8, 6, 1, 65, 214, 106, 47, 8, 6, 1, 250, 120, 214, 106, 47, 8, 6, 1, - 247, 193, 214, 106, 47, 8, 6, 1, 238, 127, 214, 106, 47, 8, 6, 1, 71, - 214, 106, 47, 8, 6, 1, 233, 175, 214, 106, 47, 8, 6, 1, 232, 51, 214, - 106, 47, 8, 6, 1, 230, 116, 214, 106, 47, 8, 6, 1, 68, 214, 106, 47, 8, - 6, 1, 223, 35, 214, 106, 47, 8, 6, 1, 222, 152, 214, 106, 47, 8, 6, 1, - 172, 214, 106, 47, 8, 6, 1, 218, 168, 214, 106, 47, 8, 6, 1, 215, 61, - 214, 106, 47, 8, 6, 1, 74, 214, 106, 47, 8, 6, 1, 210, 236, 214, 106, 47, - 8, 6, 1, 208, 104, 214, 106, 47, 8, 6, 1, 146, 214, 106, 47, 8, 6, 1, - 206, 8, 214, 106, 47, 8, 6, 1, 200, 43, 214, 106, 47, 8, 6, 1, 66, 214, - 106, 47, 8, 6, 1, 196, 12, 214, 106, 47, 8, 6, 1, 193, 224, 214, 106, 47, - 8, 6, 1, 192, 235, 214, 106, 47, 8, 6, 1, 192, 159, 214, 106, 47, 8, 6, - 1, 191, 166, 207, 147, 216, 239, 56, 207, 147, 216, 235, 56, 207, 147, - 215, 164, 56, 47, 247, 66, 47, 247, 194, 4, 211, 4, 249, 141, 47, 228, - 145, 233, 12, 214, 106, 112, 8, 6, 1, 65, 214, 106, 112, 8, 6, 1, 250, - 120, 214, 106, 112, 8, 6, 1, 247, 193, 214, 106, 112, 8, 6, 1, 238, 127, - 214, 106, 112, 8, 6, 1, 71, 214, 106, 112, 8, 6, 1, 233, 175, 214, 106, - 112, 8, 6, 1, 232, 51, 214, 106, 112, 8, 6, 1, 230, 116, 214, 106, 112, - 8, 6, 1, 68, 214, 106, 112, 8, 6, 1, 223, 35, 214, 106, 112, 8, 6, 1, - 222, 152, 214, 106, 112, 8, 6, 1, 172, 214, 106, 112, 8, 6, 1, 218, 168, - 214, 106, 112, 8, 6, 1, 215, 61, 214, 106, 112, 8, 6, 1, 74, 214, 106, - 112, 8, 6, 1, 210, 236, 214, 106, 112, 8, 6, 1, 208, 104, 214, 106, 112, - 8, 6, 1, 146, 214, 106, 112, 8, 6, 1, 206, 8, 214, 106, 112, 8, 6, 1, - 200, 43, 214, 106, 112, 8, 6, 1, 66, 214, 106, 112, 8, 6, 1, 196, 12, - 214, 106, 112, 8, 6, 1, 193, 224, 214, 106, 112, 8, 6, 1, 192, 235, 214, - 106, 112, 8, 6, 1, 192, 159, 214, 106, 112, 8, 6, 1, 191, 166, 238, 214, - 214, 106, 112, 8, 6, 1, 210, 236, 214, 106, 112, 228, 28, 214, 106, 112, - 168, 214, 106, 112, 188, 214, 106, 112, 252, 155, 214, 106, 112, 193, - 126, 51, 236, 194, 112, 242, 247, 112, 239, 14, 112, 232, 108, 112, 228, - 19, 112, 214, 79, 112, 214, 70, 112, 211, 125, 112, 202, 9, 112, 133, 4, - 233, 216, 77, 112, 194, 252, 112, 115, 238, 127, 112, 205, 57, 205, 76, - 112, 105, 222, 152, 112, 232, 128, 222, 152, 112, 234, 164, 222, 152, - 112, 232, 226, 209, 62, 107, 112, 203, 247, 209, 62, 107, 112, 197, 21, - 209, 62, 109, 112, 202, 121, 210, 236, 112, 91, 228, 141, 197, 33, 210, - 236, 112, 8, 2, 1, 238, 127, 112, 229, 248, 112, 229, 247, 112, 229, 150, - 112, 218, 252, 112, 202, 241, 112, 196, 140, 112, 195, 21, 217, 36, 193, - 21, 113, 207, 79, 223, 145, 16, 1, 65, 207, 79, 223, 145, 16, 1, 250, - 120, 207, 79, 223, 145, 16, 1, 247, 193, 207, 79, 223, 145, 16, 1, 238, - 127, 207, 79, 223, 145, 16, 1, 71, 207, 79, 223, 145, 16, 1, 233, 175, - 207, 79, 223, 145, 16, 1, 232, 51, 207, 79, 223, 145, 16, 1, 230, 116, - 207, 79, 223, 145, 16, 1, 68, 207, 79, 223, 145, 16, 1, 223, 35, 207, 79, - 223, 145, 16, 1, 222, 152, 207, 79, 223, 145, 16, 1, 172, 207, 79, 223, - 145, 16, 1, 218, 168, 207, 79, 223, 145, 16, 1, 215, 61, 207, 79, 223, - 145, 16, 1, 74, 207, 79, 223, 145, 16, 1, 210, 236, 207, 79, 223, 145, - 16, 1, 208, 104, 207, 79, 223, 145, 16, 1, 146, 207, 79, 223, 145, 16, 1, - 206, 8, 207, 79, 223, 145, 16, 1, 200, 43, 207, 79, 223, 145, 16, 1, 66, - 207, 79, 223, 145, 16, 1, 196, 12, 207, 79, 223, 145, 16, 1, 193, 224, - 207, 79, 223, 145, 16, 1, 192, 235, 207, 79, 223, 145, 16, 1, 192, 159, - 207, 79, 223, 145, 16, 1, 191, 166, 51, 229, 120, 229, 9, 112, 72, 221, - 49, 112, 72, 188, 112, 12, 196, 95, 225, 217, 112, 12, 196, 95, 225, 221, - 112, 12, 196, 95, 225, 229, 112, 72, 237, 146, 112, 12, 196, 95, 225, - 236, 112, 12, 196, 95, 225, 223, 112, 12, 196, 95, 225, 195, 112, 12, - 196, 95, 225, 222, 112, 12, 196, 95, 225, 235, 112, 12, 196, 95, 225, - 209, 112, 12, 196, 95, 225, 202, 112, 12, 196, 95, 225, 211, 112, 12, - 196, 95, 225, 232, 112, 12, 196, 95, 225, 218, 112, 12, 196, 95, 225, - 234, 112, 12, 196, 95, 225, 210, 112, 12, 196, 95, 225, 233, 112, 12, - 196, 95, 225, 196, 112, 12, 196, 95, 225, 201, 112, 12, 196, 95, 225, - 194, 112, 12, 196, 95, 225, 224, 112, 12, 196, 95, 225, 226, 112, 12, - 196, 95, 225, 204, 112, 12, 196, 95, 225, 215, 112, 12, 196, 95, 225, - 213, 112, 12, 196, 95, 225, 239, 112, 12, 196, 95, 225, 238, 112, 12, - 196, 95, 225, 192, 112, 12, 196, 95, 225, 219, 112, 12, 196, 95, 225, - 237, 112, 12, 196, 95, 225, 228, 112, 12, 196, 95, 225, 214, 112, 12, - 196, 95, 225, 193, 112, 12, 196, 95, 225, 216, 112, 12, 196, 95, 225, - 198, 112, 12, 196, 95, 225, 197, 112, 12, 196, 95, 225, 227, 112, 12, - 196, 95, 225, 205, 112, 12, 196, 95, 225, 207, 112, 12, 196, 95, 225, - 208, 112, 12, 196, 95, 225, 200, 112, 12, 196, 95, 225, 231, 112, 12, - 196, 95, 225, 225, 112, 12, 196, 95, 225, 191, 198, 42, 203, 103, 248, - 52, 12, 196, 95, 225, 206, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, - 238, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 236, 198, 42, 203, - 103, 248, 52, 12, 196, 95, 225, 220, 198, 42, 203, 103, 248, 52, 12, 196, - 95, 225, 203, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 216, 198, 42, - 203, 103, 248, 52, 12, 196, 95, 225, 199, 198, 42, 203, 103, 248, 52, 12, - 196, 95, 225, 230, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 212, 47, - 228, 14, 252, 27, 47, 228, 14, 252, 58, 206, 113, 16, 40, 232, 86, 206, - 113, 16, 40, 218, 225, 206, 113, 16, 40, 203, 23, 206, 113, 16, 40, 192, - 207, 206, 113, 16, 40, 203, 2, 206, 113, 16, 40, 247, 148, 238, 139, 232, - 173, 242, 219, 196, 117, 213, 191, 4, 201, 99, 200, 193, 139, 215, 183, - 200, 192, 242, 251, 250, 183, 235, 61, 200, 191, 139, 247, 253, 207, 148, - 248, 29, 250, 183, 213, 190, 193, 144, 193, 138, 195, 14, 216, 52, 193, - 128, 234, 208, 231, 12, 233, 232, 234, 208, 231, 12, 251, 140, 234, 208, - 231, 12, 250, 202, 231, 12, 4, 216, 177, 214, 80, 215, 206, 113, 193, - 130, 238, 228, 215, 206, 113, 232, 238, 208, 23, 215, 206, 113, 193, 130, - 231, 49, 215, 206, 113, 232, 80, 215, 206, 113, 193, 159, 231, 49, 215, - 206, 113, 220, 6, 208, 23, 215, 206, 113, 193, 159, 238, 228, 215, 206, - 113, 238, 228, 215, 205, 214, 80, 215, 206, 4, 233, 103, 232, 238, 208, - 23, 215, 206, 4, 233, 103, 220, 6, 208, 23, 215, 206, 4, 233, 103, 232, - 80, 215, 206, 4, 233, 103, 200, 199, 4, 233, 103, 231, 8, 201, 102, 203, - 45, 201, 102, 199, 21, 62, 235, 97, 63, 200, 198, 63, 200, 199, 4, 2, - 242, 210, 63, 200, 199, 248, 242, 242, 210, 63, 200, 199, 248, 242, 242, - 211, 4, 207, 149, 242, 211, 4, 207, 149, 242, 211, 4, 202, 52, 242, 211, - 4, 219, 129, 242, 211, 4, 198, 46, 232, 174, 193, 67, 248, 116, 233, 103, - 228, 181, 236, 162, 199, 227, 247, 228, 243, 103, 205, 48, 233, 226, 197, - 254, 237, 139, 197, 254, 210, 183, 197, 254, 247, 153, 228, 181, 210, 15, - 197, 78, 243, 107, 248, 119, 206, 126, 229, 149, 200, 196, 248, 119, 234, - 212, 79, 217, 103, 234, 212, 79, 206, 245, 229, 193, 232, 128, 219, 234, - 242, 209, 217, 69, 219, 233, 233, 84, 219, 233, 219, 234, 232, 181, 223, - 163, 193, 66, 215, 98, 198, 83, 250, 162, 230, 218, 216, 196, 193, 142, - 199, 187, 219, 201, 249, 98, 209, 133, 207, 87, 251, 46, 230, 201, 251, - 46, 210, 55, 210, 59, 243, 108, 201, 42, 230, 63, 202, 89, 79, 209, 112, - 216, 225, 211, 105, 248, 98, 209, 9, 219, 212, 206, 246, 238, 234, 206, - 246, 249, 111, 239, 17, 206, 245, 238, 167, 23, 206, 245, 201, 83, 248, - 66, 201, 243, 248, 43, 232, 106, 232, 102, 206, 152, 200, 142, 209, 12, - 237, 235, 211, 153, 200, 165, 232, 103, 203, 13, 232, 237, 247, 147, 4, - 200, 134, 237, 80, 202, 32, 228, 27, 238, 232, 203, 121, 228, 26, 228, - 27, 238, 232, 235, 126, 239, 16, 243, 66, 164, 247, 118, 219, 24, 238, - 158, 228, 254, 209, 14, 203, 29, 248, 222, 248, 62, 209, 15, 79, 232, - 161, 239, 15, 232, 150, 23, 221, 78, 199, 133, 193, 51, 230, 31, 205, - 176, 248, 79, 23, 238, 181, 193, 63, 231, 16, 242, 94, 231, 16, 197, 204, - 235, 104, 248, 253, 215, 140, 242, 226, 248, 253, 215, 139, 249, 149, - 248, 78, 232, 150, 23, 221, 79, 4, 209, 97, 248, 79, 4, 209, 30, 239, 3, - 209, 32, 206, 247, 193, 11, 208, 222, 248, 157, 247, 146, 223, 29, 243, - 56, 197, 254, 233, 67, 243, 55, 232, 240, 232, 241, 201, 241, 249, 109, - 210, 102, 209, 31, 239, 54, 249, 111, 199, 191, 197, 254, 238, 214, 232, - 211, 209, 134, 237, 136, 223, 19, 236, 154, 247, 90, 201, 41, 193, 67, - 243, 82, 215, 206, 195, 54, 247, 8, 205, 90, 205, 120, 230, 225, 247, - 111, 229, 224, 4, 198, 136, 211, 105, 199, 34, 219, 224, 248, 72, 79, - 232, 185, 216, 54, 216, 219, 207, 58, 206, 247, 37, 221, 221, 4, 223, 28, - 201, 11, 216, 89, 219, 168, 202, 86, 239, 22, 221, 72, 249, 13, 250, 213, - 37, 213, 1, 249, 13, 237, 86, 37, 213, 1, 233, 0, 232, 112, 252, 31, 198, - 180, 247, 91, 228, 183, 233, 33, 193, 93, 206, 139, 242, 97, 232, 232, - 209, 53, 23, 232, 236, 216, 89, 215, 169, 247, 132, 243, 14, 229, 231, - 250, 224, 210, 188, 198, 54, 230, 9, 243, 0, 199, 87, 198, 181, 242, 242, - 248, 107, 210, 6, 250, 222, 195, 65, 231, 214, 236, 234, 229, 117, 202, - 79, 217, 148, 248, 170, 231, 215, 237, 24, 248, 65, 232, 187, 209, 95, - 247, 99, 37, 213, 6, 215, 129, 37, 213, 1, 205, 104, 230, 162, 37, 221, - 220, 197, 179, 195, 42, 37, 205, 82, 206, 42, 203, 60, 4, 205, 123, 199, - 92, 207, 170, 23, 249, 111, 202, 109, 23, 202, 109, 248, 91, 249, 68, 23, - 228, 247, 243, 109, 232, 217, 202, 51, 206, 43, 200, 170, 201, 202, 216, - 219, 197, 205, 228, 184, 207, 171, 251, 141, 232, 158, 206, 56, 232, 158, - 200, 137, 193, 110, 219, 134, 230, 249, 207, 172, 215, 191, 207, 172, - 247, 102, 238, 225, 249, 65, 23, 249, 111, 195, 13, 233, 22, 229, 12, - 201, 75, 23, 249, 111, 228, 27, 229, 12, 201, 75, 23, 208, 157, 199, 234, - 199, 92, 210, 207, 23, 249, 111, 202, 53, 247, 107, 215, 184, 247, 130, - 249, 16, 4, 196, 117, 247, 255, 239, 36, 228, 173, 247, 253, 242, 250, - 237, 90, 228, 173, 247, 254, 242, 240, 247, 254, 237, 82, 237, 83, 223, - 60, 214, 208, 210, 109, 201, 113, 228, 173, 247, 254, 228, 173, 4, 231, - 198, 211, 144, 247, 254, 223, 19, 209, 20, 211, 143, 233, 231, 209, 20, - 211, 143, 228, 182, 249, 92, 250, 151, 199, 102, 217, 148, 228, 178, 218, - 242, 228, 178, 239, 20, 201, 57, 205, 89, 237, 94, 201, 57, 233, 92, 223, - 40, 220, 18, 223, 19, 247, 80, 233, 231, 247, 80, 63, 210, 28, 62, 210, - 28, 193, 136, 63, 232, 217, 193, 136, 62, 232, 217, 206, 125, 62, 206, - 125, 220, 117, 249, 132, 207, 170, 23, 202, 244, 248, 70, 23, 57, 251, - 136, 234, 109, 52, 232, 227, 196, 253, 234, 109, 52, 232, 227, 196, 250, - 234, 109, 52, 232, 227, 196, 248, 234, 109, 52, 232, 227, 196, 246, 234, - 109, 52, 232, 227, 196, 244, 207, 130, 215, 181, 210, 247, 193, 144, 248, - 3, 238, 239, 198, 173, 219, 185, 207, 174, 247, 78, 235, 111, 238, 223, - 193, 96, 202, 60, 202, 58, 228, 183, 207, 142, 230, 255, 203, 107, 215, - 225, 206, 129, 243, 93, 236, 162, 209, 147, 248, 109, 234, 131, 211, 156, - 201, 218, 203, 102, 248, 2, 251, 89, 228, 253, 220, 108, 248, 251, 232, - 236, 197, 204, 232, 236, 248, 117, 197, 55, 230, 7, 243, 94, 249, 149, - 243, 94, 232, 96, 249, 149, 243, 94, 248, 160, 210, 30, 221, 61, 209, 36, - 235, 101, 247, 134, 249, 137, 247, 134, 236, 153, 215, 182, 233, 103, - 238, 240, 233, 103, 198, 174, 233, 103, 207, 175, 233, 103, 247, 79, 233, - 103, 235, 112, 233, 103, 201, 200, 193, 96, 228, 184, 233, 103, 215, 226, - 233, 103, 236, 163, 233, 103, 209, 148, 233, 103, 232, 100, 233, 103, - 230, 59, 233, 103, 193, 38, 233, 103, 249, 10, 233, 103, 210, 162, 233, - 103, 209, 148, 213, 13, 210, 76, 208, 208, 243, 77, 233, 185, 233, 193, - 234, 211, 213, 13, 215, 179, 198, 61, 63, 133, 209, 58, 249, 144, 223, - 148, 63, 144, 209, 58, 249, 144, 223, 148, 63, 45, 209, 58, 249, 144, - 223, 148, 63, 50, 209, 58, 249, 144, 223, 148, 232, 230, 230, 54, 56, - 193, 136, 230, 54, 56, 211, 126, 230, 54, 56, 198, 211, 133, 56, 198, - 211, 144, 56, 242, 241, 230, 29, 56, 211, 77, 230, 29, 56, 238, 208, 193, - 34, 230, 9, 233, 188, 214, 111, 200, 41, 223, 9, 235, 106, 221, 142, 248, - 173, 193, 34, 242, 212, 208, 137, 230, 33, 209, 10, 217, 78, 203, 52, - 250, 178, 203, 52, 229, 134, 203, 52, 193, 34, 205, 139, 193, 34, 248, - 90, 232, 156, 247, 220, 223, 163, 202, 187, 247, 219, 223, 163, 202, 187, - 248, 60, 231, 28, 217, 90, 193, 35, 233, 81, 217, 91, 23, 193, 36, 229, - 6, 230, 28, 105, 216, 187, 229, 6, 230, 28, 105, 193, 33, 229, 6, 230, - 28, 209, 50, 211, 142, 193, 36, 4, 247, 239, 234, 209, 248, 30, 4, 195, - 144, 209, 251, 4, 248, 121, 230, 78, 217, 91, 4, 230, 176, 209, 186, 217, - 73, 217, 91, 4, 197, 63, 211, 118, 217, 90, 211, 118, 193, 35, 249, 148, - 239, 37, 193, 19, 208, 213, 223, 19, 211, 137, 223, 19, 230, 254, 231, - 61, 249, 149, 251, 120, 233, 198, 251, 182, 251, 183, 215, 215, 223, 168, - 202, 103, 223, 137, 237, 79, 209, 250, 230, 170, 237, 240, 219, 95, 214, - 235, 209, 48, 233, 104, 217, 33, 230, 77, 249, 86, 209, 52, 200, 62, 209, - 140, 221, 123, 77, 218, 242, 219, 175, 206, 188, 231, 155, 201, 65, 221, - 122, 248, 71, 238, 243, 4, 229, 223, 193, 117, 249, 6, 229, 223, 248, 22, - 229, 223, 105, 229, 221, 201, 239, 229, 223, 230, 186, 229, 223, 229, - 224, 4, 57, 248, 115, 229, 223, 230, 201, 229, 223, 192, 73, 229, 223, - 208, 138, 229, 223, 229, 224, 4, 206, 247, 207, 12, 229, 221, 229, 224, - 237, 136, 237, 33, 203, 135, 4, 42, 75, 223, 117, 234, 135, 156, 247, - 251, 251, 119, 113, 248, 99, 202, 92, 113, 242, 85, 113, 201, 212, 200, - 144, 113, 235, 97, 237, 216, 113, 209, 141, 79, 209, 37, 232, 199, 248, - 185, 236, 195, 113, 201, 230, 249, 109, 198, 231, 249, 109, 63, 232, 186, - 228, 141, 209, 56, 113, 215, 230, 249, 130, 238, 170, 233, 218, 88, 236, - 155, 56, 238, 230, 247, 100, 249, 91, 4, 192, 71, 56, 249, 91, 4, 236, - 155, 56, 249, 91, 4, 233, 234, 56, 249, 91, 4, 209, 8, 56, 215, 230, 4, - 193, 60, 243, 137, 4, 196, 66, 197, 250, 23, 192, 71, 56, 205, 60, 209, - 249, 239, 59, 248, 28, 216, 41, 232, 191, 236, 220, 211, 60, 236, 226, - 235, 55, 233, 7, 232, 171, 211, 77, 233, 7, 232, 171, 210, 205, 4, 238, - 175, 210, 205, 233, 96, 196, 77, 247, 140, 199, 130, 247, 140, 247, 101, - 223, 148, 243, 137, 4, 196, 66, 197, 249, 243, 137, 4, 235, 119, 197, - 249, 249, 88, 243, 136, 242, 225, 208, 133, 206, 115, 208, 133, 210, 134, - 201, 53, 206, 50, 197, 238, 206, 50, 248, 95, 199, 232, 219, 229, 213, 4, - 213, 5, 4, 237, 135, 238, 242, 242, 219, 248, 96, 211, 77, 248, 96, 230, - 201, 248, 96, 248, 115, 248, 96, 211, 55, 248, 96, 248, 93, 214, 228, - 249, 134, 205, 73, 216, 188, 199, 107, 207, 101, 210, 203, 233, 64, 217, - 148, 205, 119, 251, 86, 208, 158, 252, 39, 218, 244, 243, 119, 216, 201, - 211, 13, 198, 2, 223, 159, 198, 2, 210, 212, 235, 8, 113, 223, 156, 234, - 67, 234, 68, 4, 235, 119, 64, 58, 242, 219, 217, 109, 4, 218, 235, 232, - 217, 242, 219, 217, 109, 4, 207, 147, 232, 217, 211, 77, 217, 109, 4, - 207, 147, 232, 217, 211, 77, 217, 109, 4, 218, 235, 232, 217, 209, 17, - 209, 18, 228, 187, 214, 75, 216, 4, 209, 194, 216, 4, 209, 195, 4, 96, - 64, 250, 183, 219, 224, 195, 68, 216, 3, 216, 4, 209, 195, 211, 145, 213, - 44, 216, 4, 209, 193, 251, 87, 4, 249, 76, 247, 132, 247, 133, 4, 232, - 208, 195, 65, 247, 132, 199, 104, 207, 165, 195, 64, 233, 0, 208, 193, - 209, 27, 201, 77, 208, 236, 249, 15, 197, 17, 96, 250, 231, 242, 221, 96, - 23, 118, 211, 77, 243, 11, 250, 231, 242, 221, 96, 23, 118, 211, 77, 243, - 11, 250, 232, 4, 47, 91, 210, 255, 242, 221, 235, 119, 23, 196, 66, 211, - 77, 243, 11, 250, 231, 251, 85, 235, 119, 23, 196, 66, 211, 77, 243, 11, - 250, 231, 130, 248, 26, 113, 137, 248, 26, 113, 201, 235, 4, 247, 125, - 106, 201, 234, 201, 235, 4, 91, 202, 5, 193, 138, 201, 235, 4, 115, 202, - 5, 193, 137, 249, 58, 234, 135, 209, 87, 219, 219, 217, 121, 231, 16, - 206, 203, 217, 121, 231, 16, 219, 35, 4, 223, 129, 210, 34, 242, 219, - 219, 35, 4, 221, 222, 221, 222, 219, 34, 211, 77, 219, 34, 248, 235, 248, - 236, 4, 247, 125, 106, 248, 94, 219, 103, 113, 207, 166, 247, 213, 249, - 147, 4, 118, 64, 58, 234, 95, 4, 118, 64, 58, 211, 105, 4, 233, 216, 87, - 4, 45, 50, 64, 58, 202, 15, 4, 96, 64, 58, 198, 54, 4, 196, 66, 64, 58, - 213, 44, 91, 196, 105, 234, 162, 113, 221, 219, 199, 95, 223, 123, 16, - 40, 8, 6, 219, 174, 223, 123, 16, 40, 8, 2, 219, 174, 223, 123, 16, 40, - 212, 135, 223, 123, 16, 40, 200, 76, 223, 123, 16, 40, 8, 219, 174, 232, - 243, 234, 135, 198, 49, 193, 9, 230, 61, 212, 118, 23, 248, 101, 229, 13, - 209, 118, 216, 88, 199, 105, 238, 197, 249, 111, 202, 136, 209, 60, 201, - 103, 4, 82, 236, 140, 223, 19, 16, 40, 248, 248, 197, 236, 234, 111, 62, - 51, 247, 213, 63, 51, 247, 213, 220, 13, 207, 87, 243, 10, 220, 13, 248, - 115, 243, 10, 220, 13, 211, 55, 237, 32, 220, 13, 248, 115, 237, 32, 2, - 211, 55, 237, 32, 2, 248, 115, 237, 32, 196, 76, 207, 87, 197, 241, 235, - 122, 207, 87, 197, 241, 196, 76, 2, 207, 87, 197, 241, 235, 122, 2, 207, - 87, 197, 241, 110, 50, 203, 151, 63, 243, 10, 116, 50, 203, 151, 63, 243, - 10, 47, 238, 218, 209, 41, 238, 218, 209, 42, 4, 230, 67, 60, 238, 218, - 209, 41, 213, 8, 45, 204, 28, 4, 115, 236, 138, 213, 8, 50, 204, 28, 4, - 115, 236, 138, 16, 40, 217, 50, 246, 242, 63, 8, 238, 217, 88, 8, 238, - 217, 247, 26, 238, 217, 211, 114, 113, 235, 125, 79, 210, 60, 222, 125, - 215, 197, 200, 70, 216, 183, 4, 213, 175, 248, 46, 248, 67, 79, 228, 90, - 242, 223, 233, 104, 91, 211, 162, 242, 223, 233, 104, 105, 211, 162, 242, - 223, 233, 104, 115, 211, 162, 242, 223, 233, 104, 232, 128, 211, 162, - 242, 223, 233, 104, 232, 226, 211, 162, 242, 223, 233, 104, 202, 136, - 211, 162, 242, 223, 233, 104, 203, 247, 211, 162, 242, 223, 233, 104, - 234, 164, 211, 162, 242, 223, 233, 104, 213, 175, 211, 162, 242, 223, - 233, 104, 199, 96, 211, 162, 242, 223, 233, 104, 234, 128, 211, 162, 242, - 223, 233, 104, 197, 38, 211, 162, 242, 223, 233, 104, 211, 97, 242, 223, - 233, 104, 197, 11, 242, 223, 233, 104, 198, 217, 242, 223, 233, 104, 232, - 124, 242, 223, 233, 104, 232, 223, 242, 223, 233, 104, 202, 132, 242, - 223, 233, 104, 203, 246, 242, 223, 233, 104, 234, 163, 242, 223, 233, - 104, 213, 173, 242, 223, 233, 104, 199, 94, 242, 223, 233, 104, 234, 126, - 242, 223, 233, 104, 197, 36, 50, 201, 234, 50, 201, 235, 4, 91, 202, 5, - 193, 138, 50, 201, 235, 4, 115, 202, 5, 193, 137, 247, 246, 247, 247, 4, - 202, 5, 193, 137, 206, 186, 248, 235, 248, 96, 247, 123, 217, 75, 242, - 222, 62, 202, 104, 23, 238, 215, 213, 44, 209, 124, 229, 5, 217, 91, 223, - 163, 247, 222, 200, 212, 219, 165, 202, 90, 211, 57, 201, 191, 237, 221, - 200, 194, 201, 221, 201, 222, 193, 118, 222, 183, 217, 91, 237, 239, 45, - 230, 54, 199, 107, 207, 101, 199, 107, 207, 102, 4, 210, 204, 50, 230, - 54, 199, 107, 207, 101, 63, 198, 34, 199, 106, 62, 198, 34, 199, 106, - 199, 107, 211, 105, 198, 54, 79, 216, 0, 242, 245, 216, 4, 209, 194, 249, - 147, 79, 234, 67, 201, 109, 234, 67, 234, 68, 4, 219, 129, 232, 178, 234, - 67, 210, 35, 139, 201, 109, 234, 67, 219, 102, 210, 133, 62, 208, 133, - 110, 45, 210, 33, 110, 45, 249, 105, 210, 34, 110, 45, 232, 130, 210, 34, - 110, 45, 210, 197, 110, 45, 238, 233, 45, 193, 3, 230, 53, 153, 211, 126, - 230, 54, 56, 207, 147, 230, 54, 4, 232, 248, 201, 211, 207, 18, 207, 147, - 230, 54, 4, 232, 248, 201, 211, 207, 18, 198, 211, 133, 56, 207, 18, 198, - 211, 144, 56, 207, 18, 195, 67, 230, 53, 207, 18, 230, 54, 4, 82, 232, - 253, 233, 204, 207, 147, 230, 54, 4, 210, 107, 248, 210, 82, 23, 206, - 189, 232, 247, 63, 144, 209, 58, 45, 230, 54, 223, 148, 202, 206, 63, 45, - 209, 58, 223, 148, 202, 206, 63, 50, 209, 58, 223, 148, 202, 206, 62, 45, - 209, 58, 223, 148, 202, 206, 62, 50, 209, 58, 223, 148, 62, 45, 209, 58, - 249, 144, 223, 148, 62, 50, 209, 58, 249, 144, 223, 148, 202, 206, 63, - 133, 209, 58, 223, 148, 202, 206, 63, 144, 209, 58, 223, 148, 202, 206, - 62, 133, 209, 58, 223, 148, 202, 206, 62, 144, 209, 58, 223, 148, 62, - 133, 209, 58, 249, 144, 223, 148, 62, 144, 209, 58, 249, 144, 223, 148, - 62, 229, 223, 237, 78, 239, 59, 221, 221, 23, 215, 181, 115, 214, 84, - 239, 58, 208, 209, 209, 71, 247, 142, 62, 230, 17, 203, 103, 232, 191, - 236, 220, 63, 230, 17, 203, 103, 232, 191, 236, 220, 202, 32, 203, 103, - 232, 191, 236, 220, 199, 182, 247, 84, 193, 55, 221, 220, 91, 247, 214, - 215, 181, 105, 247, 214, 215, 181, 115, 247, 214, 215, 181, 198, 24, 39, - 209, 249, 239, 59, 230, 17, 236, 220, 205, 76, 208, 210, 228, 20, 233, - 64, 228, 20, 211, 60, 236, 227, 228, 20, 236, 168, 4, 199, 53, 236, 168, - 4, 199, 54, 23, 209, 177, 236, 168, 4, 209, 177, 232, 114, 4, 209, 177, - 232, 114, 4, 198, 150, 232, 114, 4, 251, 133, 192, 235, 62, 232, 171, - 232, 171, 211, 77, 232, 171, 247, 101, 141, 236, 204, 247, 101, 233, 7, - 248, 62, 233, 7, 247, 155, 234, 105, 213, 6, 234, 105, 213, 7, 210, 204, - 234, 105, 213, 7, 210, 210, 213, 6, 213, 7, 210, 204, 213, 7, 210, 210, - 234, 105, 236, 167, 234, 105, 210, 204, 234, 105, 210, 202, 236, 167, - 210, 204, 210, 202, 193, 148, 201, 218, 213, 7, 210, 210, 201, 218, 247, - 141, 210, 210, 237, 78, 193, 65, 216, 38, 217, 22, 211, 2, 242, 221, 50, - 23, 45, 204, 28, 250, 231, 247, 125, 192, 235, 223, 154, 232, 163, 202, - 116, 113, 237, 134, 232, 163, 202, 116, 113, 239, 60, 39, 221, 222, 206, - 140, 214, 75, 210, 205, 4, 47, 199, 53, 201, 67, 243, 136, 238, 15, 221, - 78, 219, 96, 201, 233, 229, 236, 223, 163, 202, 187, 115, 207, 120, 58, - 115, 207, 120, 60, 115, 207, 120, 219, 224, 115, 207, 120, 183, 45, 201, - 230, 248, 8, 50, 201, 230, 248, 8, 105, 201, 230, 248, 7, 115, 201, 230, - 248, 7, 45, 198, 231, 248, 8, 50, 198, 231, 248, 8, 45, 251, 119, 248, 8, - 50, 251, 119, 248, 8, 215, 210, 248, 8, 219, 130, 215, 210, 248, 8, 219, - 130, 215, 209, 249, 107, 111, 4, 249, 106, 249, 107, 27, 192, 235, 249, - 107, 111, 4, 27, 192, 235, 249, 107, 28, 27, 192, 235, 249, 107, 111, 4, - 28, 27, 192, 235, 156, 243, 126, 77, 249, 107, 111, 4, 28, 243, 125, 193, - 18, 217, 71, 215, 186, 232, 81, 198, 85, 198, 30, 201, 92, 79, 219, 144, - 202, 188, 79, 223, 20, 215, 167, 230, 196, 233, 103, 230, 196, 233, 104, - 4, 202, 64, 233, 185, 233, 104, 4, 199, 126, 79, 222, 185, 202, 64, 233, - 104, 4, 211, 77, 215, 179, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, - 202, 64, 233, 185, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, 242, 87, - 200, 143, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, 198, 171, 233, - 185, 202, 64, 233, 104, 4, 230, 66, 202, 64, 233, 104, 4, 228, 186, 193, - 57, 233, 103, 202, 64, 233, 104, 4, 202, 64, 233, 185, 233, 104, 205, - 109, 237, 114, 232, 161, 207, 61, 233, 103, 202, 64, 233, 104, 4, 229, - 222, 233, 185, 202, 64, 233, 104, 4, 200, 194, 202, 63, 233, 103, 214, - 82, 233, 103, 233, 206, 233, 103, 196, 111, 233, 103, 233, 104, 4, 242, - 87, 200, 143, 210, 26, 233, 103, 239, 51, 233, 103, 239, 52, 233, 103, - 221, 121, 233, 103, 233, 104, 198, 214, 42, 221, 122, 221, 121, 233, 104, - 4, 202, 64, 233, 185, 221, 121, 233, 104, 4, 242, 219, 233, 185, 233, - 104, 4, 201, 12, 198, 61, 233, 104, 4, 201, 12, 198, 62, 23, 193, 57, - 233, 193, 233, 104, 4, 201, 12, 198, 62, 23, 198, 171, 233, 185, 236, - 228, 233, 103, 193, 16, 233, 103, 251, 111, 233, 103, 209, 6, 233, 103, - 238, 199, 233, 103, 209, 253, 233, 103, 233, 104, 4, 219, 7, 79, 197, - 217, 236, 228, 247, 218, 207, 61, 233, 103, 232, 92, 233, 104, 4, 211, - 77, 215, 179, 251, 109, 233, 103, 233, 57, 233, 103, 193, 119, 233, 103, - 202, 91, 233, 103, 198, 130, 233, 103, 230, 197, 233, 103, 218, 245, 238, - 199, 233, 103, 233, 104, 4, 211, 77, 215, 179, 228, 130, 233, 103, 233, - 104, 4, 211, 77, 215, 180, 23, 242, 87, 200, 143, 233, 104, 205, 78, 223, - 163, 233, 58, 250, 190, 233, 103, 232, 183, 233, 103, 202, 92, 233, 103, - 236, 195, 233, 103, 233, 104, 193, 51, 215, 179, 233, 104, 4, 216, 216, - 217, 35, 230, 196, 247, 79, 233, 104, 4, 202, 64, 233, 185, 247, 79, 233, - 104, 4, 199, 126, 79, 222, 185, 202, 64, 247, 79, 233, 104, 4, 211, 77, - 215, 179, 202, 64, 247, 79, 233, 104, 4, 229, 222, 233, 185, 247, 79, - 233, 104, 4, 193, 1, 202, 65, 221, 121, 247, 79, 233, 104, 4, 242, 219, - 233, 185, 209, 6, 247, 79, 233, 103, 238, 199, 247, 79, 233, 103, 193, - 119, 247, 79, 233, 103, 202, 84, 232, 92, 233, 103, 202, 84, 202, 64, - 233, 103, 196, 72, 233, 103, 233, 104, 4, 206, 138, 233, 185, 233, 104, - 4, 213, 44, 230, 244, 231, 132, 233, 104, 4, 211, 126, 231, 132, 209, - 251, 248, 68, 237, 129, 205, 49, 215, 225, 229, 226, 215, 225, 201, 236, - 215, 225, 230, 20, 209, 251, 207, 145, 91, 230, 53, 209, 251, 207, 145, - 248, 80, 230, 29, 223, 163, 247, 28, 209, 251, 232, 91, 209, 251, 4, 209, - 6, 233, 103, 209, 251, 4, 232, 172, 230, 28, 186, 193, 105, 209, 58, 219, - 233, 202, 2, 193, 105, 209, 58, 219, 233, 186, 234, 204, 209, 58, 219, - 233, 202, 2, 234, 204, 209, 58, 219, 233, 153, 186, 193, 105, 209, 58, - 219, 233, 153, 202, 2, 193, 105, 209, 58, 219, 233, 153, 186, 234, 204, - 209, 58, 219, 233, 153, 202, 2, 234, 204, 209, 58, 219, 233, 186, 193, - 105, 209, 58, 195, 48, 219, 233, 202, 2, 193, 105, 209, 58, 195, 48, 219, - 233, 186, 234, 204, 209, 58, 195, 48, 219, 233, 202, 2, 234, 204, 209, - 58, 195, 48, 219, 233, 88, 186, 193, 105, 209, 58, 195, 48, 219, 233, 88, - 202, 2, 193, 105, 209, 58, 195, 48, 219, 233, 88, 186, 234, 204, 209, 58, - 195, 48, 219, 233, 88, 202, 2, 234, 204, 209, 58, 195, 48, 219, 233, 186, - 193, 105, 209, 58, 248, 4, 202, 2, 193, 105, 209, 58, 248, 4, 186, 234, - 204, 209, 58, 248, 4, 202, 2, 234, 204, 209, 58, 248, 4, 88, 186, 193, - 105, 209, 58, 248, 4, 88, 202, 2, 193, 105, 209, 58, 248, 4, 88, 186, - 234, 204, 209, 58, 248, 4, 88, 202, 2, 234, 204, 209, 58, 248, 4, 229, 4, - 208, 6, 51, 211, 42, 229, 4, 208, 6, 51, 211, 43, 223, 163, 62, 201, 190, - 202, 25, 208, 6, 51, 211, 42, 202, 25, 208, 6, 51, 211, 43, 223, 163, 62, - 201, 190, 118, 206, 146, 196, 66, 206, 146, 96, 206, 146, 235, 119, 206, - 146, 27, 34, 234, 0, 211, 42, 88, 27, 34, 234, 0, 211, 42, 34, 211, 77, - 234, 0, 211, 42, 88, 34, 211, 77, 234, 0, 211, 42, 88, 251, 138, 211, 42, - 200, 146, 251, 138, 211, 42, 49, 88, 55, 153, 242, 75, 207, 252, 87, 211, - 42, 49, 88, 55, 242, 75, 207, 252, 87, 211, 42, 49, 88, 130, 55, 242, 75, - 207, 252, 87, 211, 42, 88, 223, 103, 211, 42, 49, 223, 103, 211, 42, 88, - 49, 223, 103, 211, 42, 195, 83, 88, 202, 23, 195, 83, 88, 207, 19, 202, - 23, 243, 124, 248, 107, 207, 19, 243, 124, 248, 107, 206, 146, 229, 205, - 201, 85, 219, 32, 207, 152, 247, 102, 229, 131, 198, 16, 229, 131, 198, - 17, 4, 247, 249, 213, 13, 198, 16, 216, 158, 156, 207, 153, 201, 93, 198, - 14, 198, 15, 247, 102, 247, 223, 211, 101, 247, 223, 197, 212, 247, 224, - 201, 63, 216, 42, 251, 142, 232, 244, 234, 87, 209, 50, 247, 102, 211, - 101, 209, 50, 247, 102, 199, 155, 211, 101, 199, 155, 250, 150, 211, 101, - 250, 150, 207, 94, 195, 145, 237, 110, 197, 203, 250, 225, 218, 254, 198, - 23, 215, 218, 215, 185, 207, 151, 200, 164, 207, 151, 215, 185, 247, 154, - 252, 11, 198, 13, 203, 65, 206, 112, 201, 228, 228, 241, 198, 20, 219, - 132, 81, 198, 20, 219, 132, 239, 37, 56, 209, 50, 247, 86, 207, 12, 219, - 132, 197, 238, 232, 218, 211, 105, 209, 19, 236, 144, 213, 44, 234, 73, - 56, 202, 62, 113, 213, 44, 202, 62, 113, 208, 132, 219, 84, 223, 163, - 223, 50, 209, 108, 113, 236, 175, 213, 12, 219, 84, 113, 209, 13, 193, - 144, 113, 213, 28, 193, 144, 113, 248, 184, 213, 44, 248, 183, 248, 182, - 215, 185, 248, 182, 210, 51, 213, 44, 210, 50, 243, 85, 238, 209, 216, - 182, 113, 193, 32, 113, 207, 28, 249, 149, 113, 198, 86, 193, 144, 242, - 216, 203, 20, 249, 61, 249, 59, 210, 91, 239, 21, 238, 156, 249, 126, - 242, 246, 45, 218, 215, 197, 242, 4, 206, 113, 239, 0, 208, 196, 56, 47, - 223, 137, 202, 3, 248, 59, 113, 231, 27, 113, 238, 248, 23, 220, 25, 202, - 92, 252, 57, 203, 43, 249, 125, 248, 234, 248, 235, 249, 2, 209, 108, 79, - 193, 15, 211, 159, 56, 203, 43, 197, 213, 201, 8, 210, 201, 229, 127, - 199, 98, 228, 129, 234, 130, 193, 54, 209, 96, 202, 87, 193, 93, 206, - 189, 247, 233, 230, 62, 23, 193, 9, 203, 78, 211, 132, 235, 94, 215, 189, - 207, 152, 198, 25, 215, 192, 248, 106, 196, 76, 216, 54, 251, 223, 196, - 76, 251, 223, 196, 76, 2, 251, 223, 2, 251, 223, 213, 17, 251, 223, 251, - 224, 237, 93, 251, 224, 250, 238, 205, 118, 211, 101, 232, 244, 234, 87, - 237, 22, 219, 32, 210, 95, 203, 65, 205, 83, 215, 192, 205, 83, 247, 113, - 202, 94, 232, 178, 205, 113, 202, 111, 250, 152, 206, 243, 209, 178, 197, - 203, 206, 139, 202, 112, 160, 16, 40, 208, 2, 160, 16, 40, 251, 225, 160, - 16, 40, 232, 243, 160, 16, 40, 234, 207, 160, 16, 40, 193, 143, 160, 16, - 40, 251, 35, 160, 16, 40, 251, 36, 207, 81, 160, 16, 40, 251, 36, 207, - 80, 160, 16, 40, 251, 36, 195, 31, 160, 16, 40, 251, 36, 195, 30, 160, + 112, 8, 6, 1, 192, 159, 112, 8, 6, 1, 191, 166, 112, 228, 128, 112, 215, + 89, 112, 205, 71, 112, 201, 179, 112, 208, 250, 112, 193, 126, 214, 108, + 47, 8, 6, 1, 65, 214, 108, 47, 8, 6, 1, 250, 122, 214, 108, 47, 8, 6, 1, + 247, 195, 214, 108, 47, 8, 6, 1, 238, 129, 214, 108, 47, 8, 6, 1, 71, + 214, 108, 47, 8, 6, 1, 233, 177, 214, 108, 47, 8, 6, 1, 232, 53, 214, + 108, 47, 8, 6, 1, 230, 118, 214, 108, 47, 8, 6, 1, 68, 214, 108, 47, 8, + 6, 1, 223, 37, 214, 108, 47, 8, 6, 1, 222, 154, 214, 108, 47, 8, 6, 1, + 172, 214, 108, 47, 8, 6, 1, 218, 170, 214, 108, 47, 8, 6, 1, 215, 63, + 214, 108, 47, 8, 6, 1, 74, 214, 108, 47, 8, 6, 1, 210, 238, 214, 108, 47, + 8, 6, 1, 208, 106, 214, 108, 47, 8, 6, 1, 146, 214, 108, 47, 8, 6, 1, + 206, 9, 214, 108, 47, 8, 6, 1, 200, 43, 214, 108, 47, 8, 6, 1, 66, 214, + 108, 47, 8, 6, 1, 196, 12, 214, 108, 47, 8, 6, 1, 193, 224, 214, 108, 47, + 8, 6, 1, 192, 235, 214, 108, 47, 8, 6, 1, 192, 159, 214, 108, 47, 8, 6, + 1, 191, 166, 207, 149, 216, 241, 56, 207, 149, 216, 237, 56, 207, 149, + 215, 166, 56, 47, 247, 68, 47, 247, 196, 4, 211, 6, 249, 143, 47, 228, + 147, 233, 14, 214, 108, 112, 8, 6, 1, 65, 214, 108, 112, 8, 6, 1, 250, + 122, 214, 108, 112, 8, 6, 1, 247, 195, 214, 108, 112, 8, 6, 1, 238, 129, + 214, 108, 112, 8, 6, 1, 71, 214, 108, 112, 8, 6, 1, 233, 177, 214, 108, + 112, 8, 6, 1, 232, 53, 214, 108, 112, 8, 6, 1, 230, 118, 214, 108, 112, + 8, 6, 1, 68, 214, 108, 112, 8, 6, 1, 223, 37, 214, 108, 112, 8, 6, 1, + 222, 154, 214, 108, 112, 8, 6, 1, 172, 214, 108, 112, 8, 6, 1, 218, 170, + 214, 108, 112, 8, 6, 1, 215, 63, 214, 108, 112, 8, 6, 1, 74, 214, 108, + 112, 8, 6, 1, 210, 238, 214, 108, 112, 8, 6, 1, 208, 106, 214, 108, 112, + 8, 6, 1, 146, 214, 108, 112, 8, 6, 1, 206, 9, 214, 108, 112, 8, 6, 1, + 200, 43, 214, 108, 112, 8, 6, 1, 66, 214, 108, 112, 8, 6, 1, 196, 12, + 214, 108, 112, 8, 6, 1, 193, 224, 214, 108, 112, 8, 6, 1, 192, 235, 214, + 108, 112, 8, 6, 1, 192, 159, 214, 108, 112, 8, 6, 1, 191, 166, 238, 216, + 214, 108, 112, 8, 6, 1, 210, 238, 214, 108, 112, 228, 30, 214, 108, 112, + 168, 214, 108, 112, 188, 214, 108, 112, 252, 157, 214, 108, 112, 193, + 126, 51, 236, 196, 112, 242, 249, 112, 239, 16, 112, 232, 110, 112, 228, + 21, 112, 214, 81, 112, 214, 72, 112, 211, 127, 112, 202, 10, 112, 133, 4, + 233, 218, 77, 112, 194, 252, 112, 115, 238, 129, 112, 205, 58, 205, 77, + 112, 105, 222, 154, 112, 232, 130, 222, 154, 112, 234, 166, 222, 154, + 112, 232, 228, 209, 64, 107, 112, 203, 248, 209, 64, 107, 112, 197, 21, + 209, 64, 109, 112, 202, 122, 210, 238, 112, 91, 228, 143, 197, 33, 210, + 238, 112, 8, 2, 1, 238, 129, 112, 229, 250, 112, 229, 249, 112, 229, 152, + 112, 218, 254, 112, 202, 242, 112, 196, 140, 112, 195, 21, 217, 38, 193, + 21, 113, 207, 80, 223, 147, 16, 1, 65, 207, 80, 223, 147, 16, 1, 250, + 122, 207, 80, 223, 147, 16, 1, 247, 195, 207, 80, 223, 147, 16, 1, 238, + 129, 207, 80, 223, 147, 16, 1, 71, 207, 80, 223, 147, 16, 1, 233, 177, + 207, 80, 223, 147, 16, 1, 232, 53, 207, 80, 223, 147, 16, 1, 230, 118, + 207, 80, 223, 147, 16, 1, 68, 207, 80, 223, 147, 16, 1, 223, 37, 207, 80, + 223, 147, 16, 1, 222, 154, 207, 80, 223, 147, 16, 1, 172, 207, 80, 223, + 147, 16, 1, 218, 170, 207, 80, 223, 147, 16, 1, 215, 63, 207, 80, 223, + 147, 16, 1, 74, 207, 80, 223, 147, 16, 1, 210, 238, 207, 80, 223, 147, + 16, 1, 208, 106, 207, 80, 223, 147, 16, 1, 146, 207, 80, 223, 147, 16, 1, + 206, 9, 207, 80, 223, 147, 16, 1, 200, 43, 207, 80, 223, 147, 16, 1, 66, + 207, 80, 223, 147, 16, 1, 196, 12, 207, 80, 223, 147, 16, 1, 193, 224, + 207, 80, 223, 147, 16, 1, 192, 235, 207, 80, 223, 147, 16, 1, 192, 159, + 207, 80, 223, 147, 16, 1, 191, 166, 51, 229, 122, 229, 11, 112, 72, 221, + 51, 112, 72, 188, 112, 12, 196, 95, 225, 219, 112, 12, 196, 95, 225, 223, + 112, 12, 196, 95, 225, 231, 112, 72, 237, 148, 112, 12, 196, 95, 225, + 238, 112, 12, 196, 95, 225, 225, 112, 12, 196, 95, 225, 197, 112, 12, + 196, 95, 225, 224, 112, 12, 196, 95, 225, 237, 112, 12, 196, 95, 225, + 211, 112, 12, 196, 95, 225, 204, 112, 12, 196, 95, 225, 213, 112, 12, + 196, 95, 225, 234, 112, 12, 196, 95, 225, 220, 112, 12, 196, 95, 225, + 236, 112, 12, 196, 95, 225, 212, 112, 12, 196, 95, 225, 235, 112, 12, + 196, 95, 225, 198, 112, 12, 196, 95, 225, 203, 112, 12, 196, 95, 225, + 196, 112, 12, 196, 95, 225, 226, 112, 12, 196, 95, 225, 228, 112, 12, + 196, 95, 225, 206, 112, 12, 196, 95, 225, 217, 112, 12, 196, 95, 225, + 215, 112, 12, 196, 95, 225, 241, 112, 12, 196, 95, 225, 240, 112, 12, + 196, 95, 225, 194, 112, 12, 196, 95, 225, 221, 112, 12, 196, 95, 225, + 239, 112, 12, 196, 95, 225, 230, 112, 12, 196, 95, 225, 216, 112, 12, + 196, 95, 225, 195, 112, 12, 196, 95, 225, 218, 112, 12, 196, 95, 225, + 200, 112, 12, 196, 95, 225, 199, 112, 12, 196, 95, 225, 229, 112, 12, + 196, 95, 225, 207, 112, 12, 196, 95, 225, 209, 112, 12, 196, 95, 225, + 210, 112, 12, 196, 95, 225, 202, 112, 12, 196, 95, 225, 233, 112, 12, + 196, 95, 225, 227, 112, 12, 196, 95, 225, 193, 198, 42, 203, 104, 248, + 54, 12, 196, 95, 225, 208, 198, 42, 203, 104, 248, 54, 12, 196, 95, 225, + 240, 198, 42, 203, 104, 248, 54, 12, 196, 95, 225, 238, 198, 42, 203, + 104, 248, 54, 12, 196, 95, 225, 222, 198, 42, 203, 104, 248, 54, 12, 196, + 95, 225, 205, 198, 42, 203, 104, 248, 54, 12, 196, 95, 225, 218, 198, 42, + 203, 104, 248, 54, 12, 196, 95, 225, 201, 198, 42, 203, 104, 248, 54, 12, + 196, 95, 225, 232, 198, 42, 203, 104, 248, 54, 12, 196, 95, 225, 214, 47, + 228, 16, 252, 29, 47, 228, 16, 252, 60, 206, 114, 16, 40, 232, 88, 206, + 114, 16, 40, 218, 227, 206, 114, 16, 40, 203, 24, 206, 114, 16, 40, 192, + 207, 206, 114, 16, 40, 203, 3, 206, 114, 16, 40, 247, 150, 238, 141, 232, + 175, 242, 221, 196, 117, 213, 193, 4, 201, 100, 200, 193, 139, 215, 185, + 200, 192, 242, 253, 250, 185, 235, 63, 200, 191, 139, 247, 255, 207, 150, + 248, 31, 250, 185, 213, 192, 193, 144, 193, 138, 195, 14, 216, 54, 193, + 128, 234, 210, 231, 14, 233, 234, 234, 210, 231, 14, 251, 142, 234, 210, + 231, 14, 250, 204, 231, 14, 4, 216, 179, 214, 82, 215, 208, 113, 193, + 130, 238, 230, 215, 208, 113, 232, 240, 208, 25, 215, 208, 113, 193, 130, + 231, 51, 215, 208, 113, 232, 82, 215, 208, 113, 193, 159, 231, 51, 215, + 208, 113, 220, 8, 208, 25, 215, 208, 113, 193, 159, 238, 230, 215, 208, + 113, 238, 230, 215, 207, 214, 82, 215, 208, 4, 233, 105, 232, 240, 208, + 25, 215, 208, 4, 233, 105, 220, 8, 208, 25, 215, 208, 4, 233, 105, 232, + 82, 215, 208, 4, 233, 105, 200, 199, 4, 233, 105, 231, 10, 201, 103, 203, + 46, 201, 103, 199, 21, 62, 235, 99, 63, 200, 198, 63, 200, 199, 4, 2, + 242, 212, 63, 200, 199, 248, 244, 242, 212, 63, 200, 199, 248, 244, 242, + 213, 4, 207, 151, 242, 213, 4, 207, 151, 242, 213, 4, 202, 53, 242, 213, + 4, 219, 131, 242, 213, 4, 198, 46, 232, 176, 193, 67, 248, 118, 233, 105, + 228, 183, 236, 164, 199, 227, 247, 230, 243, 105, 205, 49, 233, 228, 197, + 254, 237, 141, 197, 254, 210, 185, 197, 254, 247, 155, 228, 183, 210, 17, + 197, 78, 243, 109, 248, 121, 206, 127, 229, 151, 200, 196, 248, 121, 234, + 214, 79, 217, 105, 234, 214, 79, 206, 246, 229, 195, 232, 130, 219, 236, + 242, 211, 217, 71, 219, 235, 233, 86, 219, 235, 219, 236, 232, 183, 223, + 165, 193, 66, 215, 100, 198, 83, 250, 164, 230, 220, 216, 198, 193, 142, + 199, 187, 219, 203, 249, 100, 209, 135, 207, 89, 251, 48, 230, 203, 251, + 48, 210, 57, 210, 61, 243, 110, 201, 43, 230, 65, 202, 90, 79, 209, 114, + 216, 227, 211, 107, 248, 100, 209, 11, 219, 214, 206, 247, 238, 236, 206, + 247, 249, 113, 239, 19, 206, 246, 238, 169, 23, 206, 246, 201, 84, 248, + 68, 201, 244, 248, 45, 232, 108, 232, 104, 206, 153, 200, 142, 209, 14, + 237, 237, 211, 155, 200, 165, 232, 105, 203, 14, 232, 239, 247, 149, 4, + 200, 134, 237, 82, 202, 33, 228, 29, 238, 234, 203, 122, 228, 28, 228, + 29, 238, 234, 235, 128, 239, 18, 243, 68, 164, 247, 120, 219, 26, 238, + 160, 229, 0, 209, 16, 203, 30, 248, 224, 248, 64, 209, 17, 79, 232, 163, + 239, 17, 232, 152, 23, 221, 80, 199, 133, 193, 51, 230, 33, 205, 177, + 248, 81, 23, 238, 183, 193, 63, 231, 18, 242, 96, 231, 18, 197, 204, 235, + 106, 248, 255, 215, 142, 242, 228, 248, 255, 215, 141, 249, 151, 248, 80, + 232, 152, 23, 221, 81, 4, 209, 99, 248, 81, 4, 209, 32, 239, 5, 209, 34, + 206, 248, 193, 11, 208, 224, 248, 159, 247, 148, 223, 31, 243, 58, 197, + 254, 233, 69, 243, 57, 232, 242, 232, 243, 201, 242, 249, 111, 210, 104, + 209, 33, 239, 56, 249, 113, 199, 191, 197, 254, 238, 216, 232, 213, 209, + 136, 237, 138, 223, 21, 236, 156, 247, 92, 201, 42, 193, 67, 243, 84, + 215, 208, 195, 54, 247, 10, 205, 91, 205, 121, 230, 227, 247, 113, 229, + 226, 4, 198, 136, 211, 107, 199, 34, 219, 226, 248, 74, 79, 232, 187, + 216, 56, 216, 221, 207, 59, 206, 248, 37, 221, 223, 4, 223, 30, 201, 12, + 216, 91, 219, 170, 202, 87, 239, 24, 221, 74, 249, 15, 250, 215, 37, 213, + 3, 249, 15, 237, 88, 37, 213, 3, 233, 2, 232, 114, 252, 33, 198, 180, + 247, 93, 228, 185, 233, 35, 193, 93, 206, 140, 242, 99, 232, 234, 209, + 55, 23, 232, 238, 216, 91, 215, 171, 247, 134, 243, 16, 229, 233, 250, + 226, 210, 190, 198, 54, 230, 11, 243, 2, 199, 87, 198, 181, 242, 244, + 248, 109, 210, 8, 250, 224, 195, 65, 231, 216, 236, 236, 229, 119, 202, + 80, 217, 150, 248, 172, 231, 217, 237, 26, 248, 67, 232, 189, 209, 97, + 247, 101, 37, 213, 8, 215, 131, 37, 213, 3, 205, 105, 230, 164, 37, 221, + 222, 197, 179, 195, 42, 37, 205, 83, 206, 43, 203, 61, 4, 205, 124, 199, + 92, 207, 172, 23, 249, 113, 202, 110, 23, 202, 110, 248, 93, 249, 70, 23, + 228, 249, 243, 111, 232, 219, 202, 52, 206, 44, 200, 170, 201, 203, 216, + 221, 197, 205, 228, 186, 207, 173, 251, 143, 232, 160, 206, 57, 232, 160, + 200, 137, 193, 110, 219, 136, 230, 251, 207, 174, 215, 193, 207, 174, + 247, 104, 238, 227, 249, 67, 23, 249, 113, 195, 13, 233, 24, 229, 14, + 201, 76, 23, 249, 113, 228, 29, 229, 14, 201, 76, 23, 208, 159, 199, 234, + 199, 92, 210, 209, 23, 249, 113, 202, 54, 247, 109, 215, 186, 247, 132, + 249, 18, 4, 196, 117, 248, 1, 239, 38, 228, 175, 247, 255, 242, 252, 237, + 92, 228, 175, 248, 0, 242, 242, 248, 0, 237, 84, 237, 85, 223, 62, 214, + 210, 210, 111, 201, 114, 228, 175, 248, 0, 228, 175, 4, 231, 200, 211, + 146, 248, 0, 223, 21, 209, 22, 211, 145, 233, 233, 209, 22, 211, 145, + 228, 184, 249, 94, 250, 153, 199, 102, 217, 150, 228, 180, 218, 244, 228, + 180, 239, 22, 201, 58, 205, 90, 237, 96, 201, 58, 233, 94, 223, 42, 220, + 20, 223, 21, 247, 82, 233, 233, 247, 82, 63, 210, 30, 62, 210, 30, 193, + 136, 63, 232, 219, 193, 136, 62, 232, 219, 206, 126, 62, 206, 126, 220, + 119, 249, 134, 207, 172, 23, 202, 245, 248, 72, 23, 57, 251, 138, 234, + 111, 52, 232, 229, 196, 253, 234, 111, 52, 232, 229, 196, 250, 234, 111, + 52, 232, 229, 196, 248, 234, 111, 52, 232, 229, 196, 246, 234, 111, 52, + 232, 229, 196, 244, 207, 132, 215, 183, 210, 249, 193, 144, 248, 5, 238, + 241, 198, 173, 219, 187, 207, 176, 247, 80, 235, 113, 238, 225, 193, 96, + 202, 61, 202, 59, 228, 185, 207, 144, 231, 1, 203, 108, 215, 227, 206, + 130, 243, 95, 236, 164, 209, 149, 248, 111, 234, 133, 211, 158, 201, 219, + 203, 103, 248, 4, 251, 91, 228, 255, 220, 110, 248, 253, 232, 238, 197, + 204, 232, 238, 248, 119, 197, 55, 230, 9, 243, 96, 249, 151, 243, 96, + 232, 98, 249, 151, 243, 96, 248, 162, 210, 32, 221, 63, 209, 38, 235, + 103, 247, 136, 249, 139, 247, 136, 236, 155, 215, 184, 233, 105, 238, + 242, 233, 105, 198, 174, 233, 105, 207, 177, 233, 105, 247, 81, 233, 105, + 235, 114, 233, 105, 201, 201, 193, 96, 228, 186, 233, 105, 215, 228, 233, + 105, 236, 165, 233, 105, 209, 150, 233, 105, 232, 102, 233, 105, 230, 61, + 233, 105, 193, 38, 233, 105, 249, 12, 233, 105, 210, 164, 233, 105, 209, + 150, 213, 15, 210, 78, 208, 210, 243, 79, 233, 187, 233, 195, 234, 213, + 213, 15, 215, 181, 198, 61, 63, 133, 209, 60, 249, 146, 223, 150, 63, + 144, 209, 60, 249, 146, 223, 150, 63, 45, 209, 60, 249, 146, 223, 150, + 63, 50, 209, 60, 249, 146, 223, 150, 232, 232, 230, 56, 56, 193, 136, + 230, 56, 56, 211, 128, 230, 56, 56, 198, 211, 133, 56, 198, 211, 144, 56, + 242, 243, 230, 31, 56, 211, 79, 230, 31, 56, 238, 210, 193, 34, 230, 11, + 233, 190, 214, 113, 200, 41, 223, 11, 235, 108, 221, 144, 248, 175, 193, + 34, 242, 214, 208, 139, 230, 35, 209, 12, 217, 80, 203, 53, 250, 180, + 203, 53, 229, 136, 203, 53, 193, 34, 205, 140, 193, 34, 248, 92, 232, + 158, 247, 222, 223, 165, 202, 188, 247, 221, 223, 165, 202, 188, 248, 62, + 231, 30, 217, 92, 193, 35, 233, 83, 217, 93, 23, 193, 36, 229, 8, 230, + 30, 105, 216, 189, 229, 8, 230, 30, 105, 193, 33, 229, 8, 230, 30, 209, + 52, 211, 144, 193, 36, 4, 247, 241, 234, 211, 248, 32, 4, 195, 144, 209, + 253, 4, 248, 123, 230, 80, 217, 93, 4, 230, 178, 209, 188, 217, 75, 217, + 93, 4, 197, 63, 211, 120, 217, 92, 211, 120, 193, 35, 249, 150, 239, 39, + 193, 19, 208, 215, 223, 21, 211, 139, 223, 21, 231, 0, 231, 63, 249, 151, + 251, 122, 233, 200, 251, 184, 251, 185, 215, 217, 223, 170, 202, 104, + 223, 139, 237, 81, 209, 252, 230, 172, 237, 242, 219, 97, 214, 237, 209, + 50, 233, 106, 217, 35, 230, 79, 249, 88, 209, 54, 200, 62, 209, 142, 221, + 125, 77, 218, 244, 219, 177, 206, 189, 231, 157, 201, 66, 221, 124, 248, + 73, 238, 245, 4, 229, 225, 193, 117, 249, 8, 229, 225, 248, 24, 229, 225, + 105, 229, 223, 201, 240, 229, 225, 230, 188, 229, 225, 229, 226, 4, 57, + 248, 117, 229, 225, 230, 203, 229, 225, 192, 73, 229, 225, 208, 140, 229, + 225, 229, 226, 4, 206, 248, 207, 13, 229, 223, 229, 226, 237, 138, 237, + 35, 203, 136, 4, 42, 75, 223, 119, 234, 137, 156, 247, 253, 251, 121, + 113, 248, 101, 202, 93, 113, 242, 87, 113, 201, 213, 200, 144, 113, 235, + 99, 237, 218, 113, 209, 143, 79, 209, 39, 232, 201, 248, 187, 236, 197, + 113, 201, 231, 249, 111, 198, 231, 249, 111, 63, 232, 188, 228, 143, 209, + 58, 113, 215, 232, 249, 132, 238, 172, 233, 220, 88, 236, 157, 56, 238, + 232, 247, 102, 249, 93, 4, 192, 71, 56, 249, 93, 4, 236, 157, 56, 249, + 93, 4, 233, 236, 56, 249, 93, 4, 209, 10, 56, 215, 232, 4, 193, 60, 243, + 139, 4, 196, 66, 197, 250, 23, 192, 71, 56, 205, 61, 209, 251, 239, 61, + 248, 30, 216, 43, 232, 193, 236, 222, 211, 62, 236, 228, 235, 57, 233, 9, + 232, 173, 211, 79, 233, 9, 232, 173, 210, 207, 4, 238, 177, 210, 207, + 233, 98, 196, 77, 247, 142, 199, 130, 247, 142, 247, 103, 223, 150, 243, + 139, 4, 196, 66, 197, 249, 243, 139, 4, 235, 121, 197, 249, 249, 90, 243, + 138, 242, 227, 208, 135, 206, 116, 208, 135, 210, 136, 201, 54, 206, 51, + 197, 238, 206, 51, 248, 97, 199, 232, 219, 231, 213, 6, 213, 7, 4, 237, + 137, 238, 244, 242, 221, 248, 98, 211, 79, 248, 98, 230, 203, 248, 98, + 248, 117, 248, 98, 211, 57, 248, 98, 248, 95, 214, 230, 249, 136, 205, + 74, 216, 190, 199, 107, 207, 103, 210, 205, 233, 66, 217, 150, 205, 120, + 251, 88, 208, 160, 252, 41, 218, 246, 243, 121, 216, 203, 211, 15, 198, + 2, 223, 161, 198, 2, 210, 214, 235, 10, 113, 223, 158, 234, 69, 234, 70, + 4, 235, 121, 64, 58, 242, 221, 217, 111, 4, 218, 237, 232, 219, 242, 221, + 217, 111, 4, 207, 149, 232, 219, 211, 79, 217, 111, 4, 207, 149, 232, + 219, 211, 79, 217, 111, 4, 218, 237, 232, 219, 209, 19, 209, 20, 228, + 189, 214, 77, 216, 6, 209, 196, 216, 6, 209, 197, 4, 96, 64, 250, 185, + 219, 226, 195, 68, 216, 5, 216, 6, 209, 197, 211, 147, 213, 46, 216, 6, + 209, 195, 251, 89, 4, 249, 78, 247, 134, 247, 135, 4, 232, 210, 195, 65, + 247, 134, 199, 104, 207, 167, 195, 64, 233, 2, 208, 195, 209, 29, 201, + 78, 208, 238, 249, 17, 197, 17, 96, 250, 233, 242, 223, 96, 23, 118, 211, + 79, 243, 13, 250, 233, 242, 223, 96, 23, 118, 211, 79, 243, 13, 250, 234, + 4, 47, 91, 211, 1, 242, 223, 235, 121, 23, 196, 66, 211, 79, 243, 13, + 250, 233, 251, 87, 235, 121, 23, 196, 66, 211, 79, 243, 13, 250, 233, + 130, 248, 28, 113, 137, 248, 28, 113, 201, 236, 4, 247, 127, 106, 201, + 235, 201, 236, 4, 91, 202, 6, 193, 138, 201, 236, 4, 115, 202, 6, 193, + 137, 249, 60, 234, 137, 209, 89, 219, 221, 217, 123, 231, 18, 206, 204, + 217, 123, 231, 18, 219, 37, 4, 223, 131, 210, 36, 242, 221, 219, 37, 4, + 221, 224, 221, 224, 219, 36, 211, 79, 219, 36, 248, 237, 248, 238, 4, + 247, 127, 106, 248, 96, 219, 105, 113, 207, 168, 247, 215, 249, 149, 4, + 118, 64, 58, 234, 97, 4, 118, 64, 58, 211, 107, 4, 233, 218, 87, 4, 45, + 50, 64, 58, 202, 16, 4, 96, 64, 58, 198, 54, 4, 196, 66, 64, 58, 213, 46, + 91, 196, 105, 234, 164, 113, 221, 221, 199, 95, 223, 125, 16, 40, 8, 6, + 219, 176, 223, 125, 16, 40, 8, 2, 219, 176, 223, 125, 16, 40, 212, 137, + 223, 125, 16, 40, 200, 76, 223, 125, 16, 40, 8, 219, 176, 232, 245, 234, + 137, 198, 49, 193, 9, 230, 63, 212, 120, 23, 248, 103, 229, 15, 209, 120, + 216, 90, 199, 105, 238, 199, 249, 113, 202, 137, 209, 62, 201, 104, 4, + 82, 236, 142, 223, 21, 16, 40, 248, 250, 197, 236, 234, 113, 62, 51, 247, + 215, 63, 51, 247, 215, 220, 15, 207, 89, 243, 12, 220, 15, 248, 117, 243, + 12, 220, 15, 211, 57, 237, 34, 220, 15, 248, 117, 237, 34, 2, 211, 57, + 237, 34, 2, 248, 117, 237, 34, 196, 76, 207, 89, 197, 241, 235, 124, 207, + 89, 197, 241, 196, 76, 2, 207, 89, 197, 241, 235, 124, 2, 207, 89, 197, + 241, 110, 50, 203, 152, 63, 243, 12, 116, 50, 203, 152, 63, 243, 12, 47, + 238, 220, 209, 43, 238, 220, 209, 44, 4, 230, 69, 60, 238, 220, 209, 43, + 213, 10, 45, 204, 29, 4, 115, 236, 140, 213, 10, 50, 204, 29, 4, 115, + 236, 140, 16, 40, 217, 52, 246, 244, 63, 8, 238, 219, 88, 8, 238, 219, + 247, 28, 238, 219, 211, 116, 113, 235, 127, 79, 210, 62, 222, 127, 215, + 199, 200, 70, 216, 185, 4, 213, 177, 248, 48, 248, 69, 79, 228, 92, 242, + 225, 233, 106, 91, 211, 164, 242, 225, 233, 106, 105, 211, 164, 242, 225, + 233, 106, 115, 211, 164, 242, 225, 233, 106, 232, 130, 211, 164, 242, + 225, 233, 106, 232, 228, 211, 164, 242, 225, 233, 106, 202, 137, 211, + 164, 242, 225, 233, 106, 203, 248, 211, 164, 242, 225, 233, 106, 234, + 166, 211, 164, 242, 225, 233, 106, 213, 177, 211, 164, 242, 225, 233, + 106, 199, 96, 211, 164, 242, 225, 233, 106, 234, 130, 211, 164, 242, 225, + 233, 106, 197, 38, 211, 164, 242, 225, 233, 106, 211, 99, 242, 225, 233, + 106, 197, 11, 242, 225, 233, 106, 198, 217, 242, 225, 233, 106, 232, 126, + 242, 225, 233, 106, 232, 225, 242, 225, 233, 106, 202, 133, 242, 225, + 233, 106, 203, 247, 242, 225, 233, 106, 234, 165, 242, 225, 233, 106, + 213, 175, 242, 225, 233, 106, 199, 94, 242, 225, 233, 106, 234, 128, 242, + 225, 233, 106, 197, 36, 50, 201, 235, 50, 201, 236, 4, 91, 202, 6, 193, + 138, 50, 201, 236, 4, 115, 202, 6, 193, 137, 247, 248, 247, 249, 4, 202, + 6, 193, 137, 206, 187, 248, 237, 248, 98, 247, 125, 217, 77, 242, 224, + 62, 202, 105, 23, 238, 217, 213, 46, 209, 126, 229, 7, 217, 93, 223, 165, + 247, 224, 200, 212, 219, 167, 202, 91, 211, 59, 201, 192, 237, 223, 200, + 194, 201, 222, 201, 223, 193, 118, 222, 185, 217, 93, 237, 241, 45, 230, + 56, 199, 107, 207, 103, 199, 107, 207, 104, 4, 210, 206, 50, 230, 56, + 199, 107, 207, 103, 63, 198, 34, 199, 106, 62, 198, 34, 199, 106, 199, + 107, 211, 107, 198, 54, 79, 216, 2, 242, 247, 216, 6, 209, 196, 249, 149, + 79, 234, 69, 201, 110, 234, 69, 234, 70, 4, 219, 131, 232, 180, 234, 69, + 210, 37, 139, 201, 110, 234, 69, 219, 104, 210, 135, 62, 208, 135, 110, + 45, 210, 35, 110, 45, 249, 107, 210, 36, 110, 45, 232, 132, 210, 36, 110, + 45, 210, 199, 110, 45, 238, 235, 45, 193, 3, 230, 55, 154, 211, 128, 230, + 56, 56, 207, 149, 230, 56, 4, 232, 250, 201, 212, 207, 19, 207, 149, 230, + 56, 4, 232, 250, 201, 212, 207, 19, 198, 211, 133, 56, 207, 19, 198, 211, + 144, 56, 207, 19, 195, 67, 230, 55, 207, 19, 230, 56, 4, 82, 232, 255, + 233, 206, 207, 149, 230, 56, 4, 210, 109, 248, 212, 82, 23, 206, 190, + 232, 249, 63, 144, 209, 60, 45, 230, 56, 223, 150, 202, 207, 63, 45, 209, + 60, 223, 150, 202, 207, 63, 50, 209, 60, 223, 150, 202, 207, 62, 45, 209, + 60, 223, 150, 202, 207, 62, 50, 209, 60, 223, 150, 62, 45, 209, 60, 249, + 146, 223, 150, 62, 50, 209, 60, 249, 146, 223, 150, 202, 207, 63, 133, + 209, 60, 223, 150, 202, 207, 63, 144, 209, 60, 223, 150, 202, 207, 62, + 133, 209, 60, 223, 150, 202, 207, 62, 144, 209, 60, 223, 150, 62, 133, + 209, 60, 249, 146, 223, 150, 62, 144, 209, 60, 249, 146, 223, 150, 62, + 229, 225, 237, 80, 239, 61, 221, 223, 23, 215, 183, 115, 214, 86, 239, + 60, 208, 211, 209, 73, 247, 144, 62, 230, 19, 203, 104, 232, 193, 236, + 222, 63, 230, 19, 203, 104, 232, 193, 236, 222, 202, 33, 203, 104, 232, + 193, 236, 222, 199, 182, 247, 86, 193, 55, 221, 222, 91, 247, 216, 215, + 183, 105, 247, 216, 215, 183, 115, 247, 216, 215, 183, 198, 24, 39, 209, + 251, 239, 61, 230, 19, 236, 222, 205, 77, 208, 212, 228, 22, 233, 66, + 228, 22, 211, 62, 236, 229, 228, 22, 236, 170, 4, 199, 53, 236, 170, 4, + 199, 54, 23, 209, 179, 236, 170, 4, 209, 179, 232, 116, 4, 209, 179, 232, + 116, 4, 198, 150, 232, 116, 4, 251, 135, 192, 235, 62, 232, 173, 232, + 173, 211, 79, 232, 173, 247, 103, 141, 236, 206, 247, 103, 233, 9, 248, + 64, 233, 9, 247, 157, 234, 107, 213, 8, 234, 107, 213, 9, 210, 206, 234, + 107, 213, 9, 210, 212, 213, 8, 213, 9, 210, 206, 213, 9, 210, 212, 234, + 107, 236, 169, 234, 107, 210, 206, 234, 107, 210, 204, 236, 169, 210, + 206, 210, 204, 193, 148, 201, 219, 213, 9, 210, 212, 201, 219, 247, 143, + 210, 212, 237, 80, 193, 65, 216, 40, 217, 24, 211, 4, 242, 223, 50, 23, + 45, 204, 29, 250, 233, 247, 127, 192, 235, 223, 156, 232, 165, 202, 117, + 113, 237, 136, 232, 165, 202, 117, 113, 239, 62, 39, 221, 224, 206, 141, + 214, 77, 210, 207, 4, 47, 199, 53, 201, 68, 243, 138, 238, 17, 221, 80, + 219, 98, 201, 234, 229, 238, 223, 165, 202, 188, 115, 207, 122, 58, 115, + 207, 122, 60, 115, 207, 122, 219, 226, 115, 207, 122, 179, 45, 201, 231, + 248, 10, 50, 201, 231, 248, 10, 105, 201, 231, 248, 9, 115, 201, 231, + 248, 9, 45, 198, 231, 248, 10, 50, 198, 231, 248, 10, 45, 251, 121, 248, + 10, 50, 251, 121, 248, 10, 215, 212, 248, 10, 219, 132, 215, 212, 248, + 10, 219, 132, 215, 211, 249, 109, 111, 4, 249, 108, 249, 109, 27, 192, + 235, 249, 109, 111, 4, 27, 192, 235, 249, 109, 28, 27, 192, 235, 249, + 109, 111, 4, 28, 27, 192, 235, 156, 243, 128, 77, 249, 109, 111, 4, 28, + 243, 127, 193, 18, 217, 73, 215, 188, 232, 83, 198, 85, 198, 30, 201, 93, + 79, 219, 146, 202, 189, 79, 223, 22, 215, 169, 230, 198, 233, 105, 230, + 198, 233, 106, 4, 202, 65, 233, 187, 233, 106, 4, 199, 126, 79, 222, 187, + 202, 65, 233, 106, 4, 211, 79, 215, 181, 202, 65, 233, 106, 4, 211, 79, + 215, 182, 23, 202, 65, 233, 187, 202, 65, 233, 106, 4, 211, 79, 215, 182, + 23, 242, 89, 200, 143, 202, 65, 233, 106, 4, 211, 79, 215, 182, 23, 198, + 171, 233, 187, 202, 65, 233, 106, 4, 230, 68, 202, 65, 233, 106, 4, 228, + 188, 193, 57, 233, 105, 202, 65, 233, 106, 4, 202, 65, 233, 187, 233, + 106, 205, 110, 237, 116, 232, 163, 207, 62, 233, 105, 202, 65, 233, 106, + 4, 229, 224, 233, 187, 202, 65, 233, 106, 4, 200, 194, 202, 64, 233, 105, + 214, 84, 233, 105, 233, 208, 233, 105, 196, 111, 233, 105, 233, 106, 4, + 242, 89, 200, 143, 210, 28, 233, 105, 239, 53, 233, 105, 239, 54, 233, + 105, 221, 123, 233, 105, 233, 106, 198, 214, 42, 221, 124, 221, 123, 233, + 106, 4, 202, 65, 233, 187, 221, 123, 233, 106, 4, 242, 221, 233, 187, + 233, 106, 4, 201, 13, 198, 61, 233, 106, 4, 201, 13, 198, 62, 23, 193, + 57, 233, 195, 233, 106, 4, 201, 13, 198, 62, 23, 198, 171, 233, 187, 236, + 230, 233, 105, 193, 16, 233, 105, 251, 113, 233, 105, 209, 8, 233, 105, + 238, 201, 233, 105, 209, 255, 233, 105, 233, 106, 4, 219, 9, 79, 197, + 217, 236, 230, 247, 220, 207, 62, 233, 105, 232, 94, 233, 106, 4, 211, + 79, 215, 181, 251, 111, 233, 105, 233, 59, 233, 105, 193, 119, 233, 105, + 202, 92, 233, 105, 198, 130, 233, 105, 230, 199, 233, 105, 218, 247, 238, + 201, 233, 105, 233, 106, 4, 211, 79, 215, 181, 228, 132, 233, 105, 233, + 106, 4, 211, 79, 215, 182, 23, 242, 89, 200, 143, 233, 106, 205, 79, 223, + 165, 233, 60, 250, 192, 233, 105, 232, 185, 233, 105, 202, 93, 233, 105, + 236, 197, 233, 105, 233, 106, 193, 51, 215, 181, 233, 106, 4, 216, 218, + 217, 37, 230, 198, 247, 81, 233, 106, 4, 202, 65, 233, 187, 247, 81, 233, + 106, 4, 199, 126, 79, 222, 187, 202, 65, 247, 81, 233, 106, 4, 211, 79, + 215, 181, 202, 65, 247, 81, 233, 106, 4, 229, 224, 233, 187, 247, 81, + 233, 106, 4, 193, 1, 202, 66, 221, 123, 247, 81, 233, 106, 4, 242, 221, + 233, 187, 209, 8, 247, 81, 233, 105, 238, 201, 247, 81, 233, 105, 193, + 119, 247, 81, 233, 105, 202, 85, 232, 94, 233, 105, 202, 85, 202, 65, + 233, 105, 196, 72, 233, 105, 233, 106, 4, 206, 139, 233, 187, 233, 106, + 4, 213, 46, 230, 246, 231, 134, 233, 106, 4, 211, 128, 231, 134, 209, + 253, 248, 70, 237, 131, 205, 50, 215, 227, 229, 228, 215, 227, 201, 237, + 215, 227, 230, 22, 209, 253, 207, 147, 91, 230, 55, 209, 253, 207, 147, + 248, 82, 230, 31, 223, 165, 247, 30, 209, 253, 232, 93, 209, 253, 4, 209, + 8, 233, 105, 209, 253, 4, 232, 174, 230, 30, 186, 193, 105, 209, 60, 219, + 235, 202, 3, 193, 105, 209, 60, 219, 235, 186, 234, 206, 209, 60, 219, + 235, 202, 3, 234, 206, 209, 60, 219, 235, 154, 186, 193, 105, 209, 60, + 219, 235, 154, 202, 3, 193, 105, 209, 60, 219, 235, 154, 186, 234, 206, + 209, 60, 219, 235, 154, 202, 3, 234, 206, 209, 60, 219, 235, 186, 193, + 105, 209, 60, 195, 48, 219, 235, 202, 3, 193, 105, 209, 60, 195, 48, 219, + 235, 186, 234, 206, 209, 60, 195, 48, 219, 235, 202, 3, 234, 206, 209, + 60, 195, 48, 219, 235, 88, 186, 193, 105, 209, 60, 195, 48, 219, 235, 88, + 202, 3, 193, 105, 209, 60, 195, 48, 219, 235, 88, 186, 234, 206, 209, 60, + 195, 48, 219, 235, 88, 202, 3, 234, 206, 209, 60, 195, 48, 219, 235, 186, + 193, 105, 209, 60, 248, 6, 202, 3, 193, 105, 209, 60, 248, 6, 186, 234, + 206, 209, 60, 248, 6, 202, 3, 234, 206, 209, 60, 248, 6, 88, 186, 193, + 105, 209, 60, 248, 6, 88, 202, 3, 193, 105, 209, 60, 248, 6, 88, 186, + 234, 206, 209, 60, 248, 6, 88, 202, 3, 234, 206, 209, 60, 248, 6, 229, 6, + 208, 8, 51, 211, 44, 229, 6, 208, 8, 51, 211, 45, 223, 165, 62, 201, 191, + 202, 26, 208, 8, 51, 211, 44, 202, 26, 208, 8, 51, 211, 45, 223, 165, 62, + 201, 191, 118, 206, 147, 196, 66, 206, 147, 96, 206, 147, 235, 121, 206, + 147, 27, 34, 234, 2, 211, 44, 88, 27, 34, 234, 2, 211, 44, 34, 211, 79, + 234, 2, 211, 44, 88, 34, 211, 79, 234, 2, 211, 44, 88, 251, 140, 211, 44, + 200, 146, 251, 140, 211, 44, 49, 88, 55, 154, 242, 77, 207, 254, 87, 211, + 44, 49, 88, 55, 242, 77, 207, 254, 87, 211, 44, 49, 88, 130, 55, 242, 77, + 207, 254, 87, 211, 44, 88, 223, 105, 211, 44, 49, 223, 105, 211, 44, 88, + 49, 223, 105, 211, 44, 195, 83, 88, 202, 24, 195, 83, 88, 207, 20, 202, + 24, 243, 126, 248, 109, 207, 20, 243, 126, 248, 109, 206, 147, 229, 207, + 201, 86, 219, 34, 207, 154, 247, 104, 229, 133, 198, 16, 229, 133, 198, + 17, 4, 247, 251, 213, 15, 198, 16, 216, 160, 156, 207, 155, 201, 94, 198, + 14, 198, 15, 247, 104, 247, 225, 211, 103, 247, 225, 197, 212, 247, 226, + 201, 64, 216, 44, 251, 144, 232, 246, 234, 89, 209, 52, 247, 104, 211, + 103, 209, 52, 247, 104, 199, 155, 211, 103, 199, 155, 250, 152, 211, 103, + 250, 152, 207, 96, 195, 145, 237, 112, 197, 203, 250, 227, 219, 0, 198, + 23, 215, 220, 215, 187, 207, 153, 200, 164, 207, 153, 215, 187, 247, 156, + 252, 13, 198, 13, 203, 66, 206, 113, 201, 229, 228, 243, 198, 20, 219, + 134, 81, 198, 20, 219, 134, 239, 39, 56, 209, 52, 247, 88, 207, 13, 219, + 134, 197, 238, 232, 220, 211, 107, 209, 21, 236, 146, 213, 46, 234, 75, + 56, 202, 63, 113, 213, 46, 202, 63, 113, 208, 134, 219, 86, 223, 165, + 223, 52, 209, 110, 113, 236, 177, 213, 14, 219, 86, 113, 209, 15, 193, + 144, 113, 213, 30, 193, 144, 113, 248, 186, 213, 46, 248, 185, 248, 184, + 215, 187, 248, 184, 210, 53, 213, 46, 210, 52, 243, 87, 238, 211, 216, + 184, 113, 193, 32, 113, 207, 29, 249, 151, 113, 198, 86, 193, 144, 242, + 218, 203, 21, 249, 63, 249, 61, 210, 93, 239, 23, 238, 158, 249, 128, + 242, 248, 45, 218, 217, 197, 242, 4, 206, 114, 239, 2, 208, 198, 56, 47, + 223, 139, 202, 4, 248, 61, 113, 231, 29, 113, 238, 250, 23, 220, 27, 202, + 93, 252, 59, 203, 44, 249, 127, 248, 236, 248, 237, 249, 4, 209, 110, 79, + 193, 15, 211, 161, 56, 203, 44, 197, 213, 201, 9, 210, 203, 229, 129, + 199, 98, 228, 131, 234, 132, 193, 54, 209, 98, 202, 88, 193, 93, 206, + 190, 247, 235, 230, 64, 23, 193, 9, 203, 79, 211, 134, 235, 96, 215, 191, + 207, 154, 198, 25, 215, 194, 248, 108, 196, 76, 216, 56, 251, 225, 196, + 76, 251, 225, 196, 76, 2, 251, 225, 2, 251, 225, 213, 19, 251, 225, 251, + 226, 237, 95, 251, 226, 250, 240, 205, 119, 211, 103, 232, 246, 234, 89, + 237, 24, 219, 34, 210, 97, 203, 66, 205, 84, 215, 194, 205, 84, 247, 115, + 202, 95, 232, 180, 205, 114, 202, 112, 250, 154, 206, 244, 209, 180, 197, + 203, 206, 140, 202, 113, 160, 16, 40, 208, 4, 160, 16, 40, 251, 227, 160, + 16, 40, 232, 245, 160, 16, 40, 234, 209, 160, 16, 40, 193, 143, 160, 16, + 40, 251, 37, 160, 16, 40, 251, 38, 207, 82, 160, 16, 40, 251, 38, 207, + 81, 160, 16, 40, 251, 38, 195, 31, 160, 16, 40, 251, 38, 195, 30, 160, 16, 40, 195, 45, 160, 16, 40, 195, 44, 160, 16, 40, 195, 43, 160, 16, 40, - 200, 205, 160, 16, 40, 209, 203, 200, 205, 160, 16, 40, 62, 200, 205, - 160, 16, 40, 216, 181, 200, 236, 160, 16, 40, 216, 181, 200, 235, 160, - 16, 40, 216, 181, 200, 234, 160, 16, 40, 243, 13, 160, 16, 40, 205, 158, - 160, 16, 40, 213, 161, 160, 16, 40, 195, 28, 160, 16, 40, 195, 27, 160, - 16, 40, 206, 148, 205, 158, 160, 16, 40, 206, 148, 205, 157, 160, 16, 40, - 230, 250, 160, 16, 40, 202, 184, 160, 16, 40, 223, 74, 211, 49, 160, 16, - 40, 223, 74, 211, 48, 160, 16, 40, 238, 222, 79, 223, 73, 160, 16, 40, - 207, 77, 79, 223, 73, 160, 16, 40, 239, 12, 211, 49, 160, 16, 40, 223, - 72, 211, 49, 160, 16, 40, 200, 237, 79, 239, 11, 160, 16, 40, 238, 222, - 79, 239, 11, 160, 16, 40, 238, 222, 79, 239, 10, 160, 16, 40, 239, 12, - 251, 79, 160, 16, 40, 205, 159, 79, 239, 12, 251, 79, 160, 16, 40, 200, - 237, 79, 205, 159, 79, 239, 11, 160, 16, 40, 195, 139, 160, 16, 40, 198, - 143, 211, 49, 160, 16, 40, 219, 237, 211, 49, 160, 16, 40, 251, 78, 211, - 49, 160, 16, 40, 200, 237, 79, 251, 77, 160, 16, 40, 205, 159, 79, 251, - 77, 160, 16, 40, 200, 237, 79, 205, 159, 79, 251, 77, 160, 16, 40, 195, - 46, 79, 251, 77, 160, 16, 40, 207, 77, 79, 251, 77, 160, 16, 40, 207, 77, - 79, 251, 76, 160, 16, 40, 207, 76, 160, 16, 40, 207, 75, 160, 16, 40, - 207, 74, 160, 16, 40, 207, 73, 160, 16, 40, 251, 177, 160, 16, 40, 251, - 176, 160, 16, 40, 217, 61, 160, 16, 40, 205, 168, 160, 16, 40, 250, 230, - 160, 16, 40, 207, 105, 160, 16, 40, 207, 104, 160, 16, 40, 250, 154, 160, - 16, 40, 248, 150, 211, 49, 160, 16, 40, 199, 177, 160, 16, 40, 199, 176, - 160, 16, 40, 208, 8, 219, 121, 160, 16, 40, 248, 87, 160, 16, 40, 248, - 86, 160, 16, 40, 248, 85, 160, 16, 40, 251, 151, 160, 16, 40, 211, 131, - 160, 16, 40, 201, 214, 160, 16, 40, 198, 141, 160, 16, 40, 230, 158, 160, - 16, 40, 193, 131, 160, 16, 40, 209, 1, 160, 16, 40, 247, 137, 160, 16, - 40, 197, 50, 160, 16, 40, 247, 104, 215, 198, 160, 16, 40, 205, 93, 79, - 222, 187, 160, 16, 40, 247, 151, 160, 16, 40, 197, 235, 160, 16, 40, 201, - 100, 197, 235, 160, 16, 40, 219, 31, 160, 16, 40, 202, 37, 160, 16, 40, - 196, 54, 160, 16, 40, 228, 184, 235, 71, 160, 16, 40, 250, 204, 160, 16, - 40, 209, 15, 250, 204, 160, 16, 40, 248, 31, 160, 16, 40, 209, 0, 248, - 31, 160, 16, 40, 251, 148, 160, 16, 40, 201, 46, 200, 186, 201, 45, 160, - 16, 40, 201, 46, 200, 186, 201, 44, 160, 16, 40, 200, 233, 160, 16, 40, - 208, 229, 160, 16, 40, 236, 215, 160, 16, 40, 236, 217, 160, 16, 40, 236, - 216, 160, 16, 40, 208, 141, 160, 16, 40, 208, 129, 160, 16, 40, 238, 207, - 160, 16, 40, 238, 206, 160, 16, 40, 238, 205, 160, 16, 40, 238, 204, 160, - 16, 40, 238, 203, 160, 16, 40, 251, 191, 160, 16, 40, 249, 62, 79, 217, - 42, 160, 16, 40, 249, 62, 79, 195, 174, 160, 16, 40, 207, 26, 160, 16, - 40, 228, 176, 160, 16, 40, 213, 190, 160, 16, 40, 237, 203, 160, 16, 40, - 215, 213, 160, 16, 40, 132, 235, 109, 160, 16, 40, 132, 211, 17, 218, - 250, 79, 232, 137, 211, 164, 218, 207, 234, 194, 230, 1, 217, 101, 230, - 246, 208, 24, 211, 52, 62, 219, 219, 223, 56, 50, 197, 241, 62, 196, 76, - 223, 56, 50, 197, 241, 62, 206, 203, 223, 56, 50, 197, 241, 62, 235, 122, - 223, 56, 50, 197, 241, 62, 202, 84, 2, 243, 10, 216, 213, 28, 63, 243, - 10, 28, 63, 243, 10, 88, 63, 243, 10, 195, 83, 88, 63, 243, 10, 233, 197, - 88, 63, 243, 10, 63, 243, 11, 239, 33, 62, 2, 243, 10, 206, 115, 199, - 178, 62, 198, 138, 201, 190, 62, 202, 84, 2, 201, 190, 156, 63, 201, 190, - 216, 213, 63, 201, 190, 28, 63, 201, 190, 88, 63, 201, 190, 195, 83, 88, - 63, 201, 190, 233, 197, 88, 63, 201, 190, 63, 51, 239, 33, 62, 195, 83, - 2, 201, 190, 63, 51, 239, 33, 62, 216, 213, 201, 190, 51, 199, 178, 62, - 198, 138, 237, 32, 62, 195, 83, 2, 237, 32, 62, 216, 213, 2, 237, 32, 63, - 237, 33, 239, 33, 62, 195, 83, 2, 237, 32, 63, 237, 33, 239, 33, 62, 216, - 213, 237, 32, 237, 33, 199, 178, 62, 198, 138, 218, 232, 62, 195, 83, 2, - 218, 232, 62, 216, 213, 2, 218, 232, 63, 218, 233, 239, 33, 62, 2, 218, - 232, 199, 4, 35, 238, 217, 156, 35, 238, 217, 216, 213, 35, 238, 217, 28, - 35, 238, 217, 195, 83, 28, 35, 238, 217, 195, 83, 88, 35, 238, 217, 233, - 197, 88, 35, 238, 217, 199, 4, 205, 154, 156, 205, 154, 216, 213, 205, - 154, 28, 205, 154, 88, 205, 154, 195, 83, 88, 205, 154, 233, 197, 88, - 205, 154, 156, 232, 226, 201, 206, 250, 193, 216, 213, 232, 226, 201, - 206, 250, 193, 28, 232, 226, 201, 206, 250, 193, 88, 232, 226, 201, 206, - 250, 193, 195, 83, 88, 232, 226, 201, 206, 250, 193, 233, 197, 88, 232, - 226, 201, 206, 250, 193, 156, 202, 136, 201, 206, 250, 193, 216, 213, - 202, 136, 201, 206, 250, 193, 28, 202, 136, 201, 206, 250, 193, 88, 202, - 136, 201, 206, 250, 193, 195, 83, 88, 202, 136, 201, 206, 250, 193, 233, - 197, 88, 202, 136, 201, 206, 250, 193, 156, 234, 164, 201, 206, 250, 193, - 216, 213, 234, 164, 201, 206, 250, 193, 28, 234, 164, 201, 206, 250, 193, - 88, 234, 164, 201, 206, 250, 193, 195, 83, 88, 234, 164, 201, 206, 250, - 193, 156, 115, 209, 60, 62, 201, 102, 216, 213, 115, 209, 60, 62, 201, - 102, 115, 209, 60, 62, 201, 102, 216, 213, 115, 209, 60, 209, 130, 201, - 102, 156, 232, 128, 209, 60, 62, 201, 102, 216, 213, 232, 128, 209, 60, - 62, 201, 102, 232, 128, 209, 60, 62, 201, 102, 216, 213, 232, 128, 209, - 60, 209, 130, 201, 102, 207, 19, 156, 232, 128, 209, 60, 209, 130, 201, - 102, 156, 232, 226, 209, 60, 62, 201, 102, 88, 232, 226, 209, 60, 62, - 201, 102, 216, 213, 202, 136, 209, 60, 62, 201, 102, 88, 202, 136, 209, - 60, 62, 201, 102, 202, 136, 209, 60, 209, 130, 201, 102, 216, 213, 234, - 164, 209, 60, 62, 201, 102, 88, 234, 164, 209, 60, 62, 201, 102, 195, 83, - 88, 234, 164, 209, 60, 62, 201, 102, 88, 234, 164, 209, 60, 209, 130, - 201, 102, 156, 197, 38, 209, 60, 62, 201, 102, 88, 197, 38, 209, 60, 62, - 201, 102, 88, 197, 38, 209, 60, 209, 130, 201, 102, 47, 197, 241, 214, - 106, 47, 197, 241, 47, 201, 190, 214, 106, 47, 201, 190, 213, 175, 209, - 60, 63, 201, 102, 220, 13, 211, 55, 243, 10, 220, 13, 192, 73, 243, 10, - 220, 13, 230, 201, 243, 10, 220, 13, 208, 138, 243, 10, 220, 13, 248, 19, - 243, 10, 220, 13, 207, 87, 201, 190, 220, 13, 248, 115, 201, 190, 220, - 13, 211, 55, 201, 190, 220, 13, 192, 73, 201, 190, 220, 13, 230, 201, - 201, 190, 220, 13, 208, 138, 201, 190, 220, 13, 248, 19, 201, 190, 88, - 234, 43, 56, 118, 64, 4, 2, 197, 242, 250, 235, 196, 66, 64, 4, 2, 197, - 242, 250, 235, 96, 64, 4, 2, 197, 242, 250, 235, 235, 119, 64, 4, 2, 197, - 242, 250, 235, 118, 64, 4, 216, 213, 197, 242, 250, 235, 196, 66, 64, 4, - 216, 213, 197, 242, 250, 235, 96, 64, 4, 216, 213, 197, 242, 250, 235, - 235, 119, 64, 4, 216, 213, 197, 242, 250, 235, 118, 64, 4, 220, 13, 197, - 242, 250, 235, 196, 66, 64, 4, 220, 13, 197, 242, 250, 235, 96, 64, 4, - 220, 13, 197, 242, 250, 235, 235, 119, 64, 4, 220, 13, 197, 242, 250, - 235, 118, 64, 4, 2, 234, 37, 250, 235, 196, 66, 64, 4, 2, 234, 37, 250, - 235, 96, 64, 4, 2, 234, 37, 250, 235, 235, 119, 64, 4, 2, 234, 37, 250, - 235, 118, 64, 4, 234, 37, 250, 235, 196, 66, 64, 4, 234, 37, 250, 235, - 96, 64, 4, 234, 37, 250, 235, 235, 119, 64, 4, 234, 37, 250, 235, 88, - 118, 64, 4, 234, 37, 250, 235, 88, 196, 66, 64, 4, 234, 37, 250, 235, 88, - 96, 64, 4, 234, 37, 250, 235, 88, 235, 119, 64, 4, 234, 37, 250, 235, 88, - 118, 64, 4, 220, 13, 234, 37, 250, 235, 88, 196, 66, 64, 4, 220, 13, 234, - 37, 250, 235, 88, 96, 64, 4, 220, 13, 234, 37, 250, 235, 88, 235, 119, - 64, 4, 220, 13, 234, 37, 250, 235, 118, 197, 240, 64, 4, 214, 215, 203, - 149, 196, 66, 197, 240, 64, 4, 214, 215, 203, 149, 96, 197, 240, 64, 4, - 214, 215, 203, 149, 235, 119, 197, 240, 64, 4, 214, 215, 203, 149, 118, - 197, 240, 64, 4, 216, 213, 203, 149, 196, 66, 197, 240, 64, 4, 216, 213, - 203, 149, 96, 197, 240, 64, 4, 216, 213, 203, 149, 235, 119, 197, 240, - 64, 4, 216, 213, 203, 149, 118, 197, 240, 64, 4, 28, 203, 149, 196, 66, - 197, 240, 64, 4, 28, 203, 149, 96, 197, 240, 64, 4, 28, 203, 149, 235, - 119, 197, 240, 64, 4, 28, 203, 149, 118, 197, 240, 64, 4, 88, 203, 149, - 196, 66, 197, 240, 64, 4, 88, 203, 149, 96, 197, 240, 64, 4, 88, 203, - 149, 235, 119, 197, 240, 64, 4, 88, 203, 149, 118, 197, 240, 64, 4, 195, - 83, 88, 203, 149, 196, 66, 197, 240, 64, 4, 195, 83, 88, 203, 149, 96, - 197, 240, 64, 4, 195, 83, 88, 203, 149, 235, 119, 197, 240, 64, 4, 195, - 83, 88, 203, 149, 118, 232, 251, 57, 196, 66, 232, 251, 57, 96, 232, 251, - 57, 235, 119, 232, 251, 57, 118, 112, 57, 196, 66, 112, 57, 96, 112, 57, - 235, 119, 112, 57, 118, 239, 61, 57, 196, 66, 239, 61, 57, 96, 239, 61, - 57, 235, 119, 239, 61, 57, 118, 88, 239, 61, 57, 196, 66, 88, 239, 61, - 57, 96, 88, 239, 61, 57, 235, 119, 88, 239, 61, 57, 118, 88, 57, 196, 66, - 88, 57, 96, 88, 57, 235, 119, 88, 57, 118, 49, 57, 196, 66, 49, 57, 96, - 49, 57, 235, 119, 49, 57, 186, 193, 105, 49, 57, 186, 234, 204, 49, 57, - 202, 2, 234, 204, 49, 57, 202, 2, 193, 105, 49, 57, 45, 50, 49, 57, 133, - 144, 49, 57, 193, 77, 118, 156, 181, 57, 193, 77, 196, 66, 156, 181, 57, - 193, 77, 96, 156, 181, 57, 193, 77, 235, 119, 156, 181, 57, 193, 77, 186, - 193, 105, 156, 181, 57, 193, 77, 186, 234, 204, 156, 181, 57, 193, 77, - 202, 2, 234, 204, 156, 181, 57, 193, 77, 202, 2, 193, 105, 156, 181, 57, - 193, 77, 118, 181, 57, 193, 77, 196, 66, 181, 57, 193, 77, 96, 181, 57, - 193, 77, 235, 119, 181, 57, 193, 77, 186, 193, 105, 181, 57, 193, 77, - 186, 234, 204, 181, 57, 193, 77, 202, 2, 234, 204, 181, 57, 193, 77, 202, - 2, 193, 105, 181, 57, 193, 77, 118, 216, 213, 181, 57, 193, 77, 196, 66, - 216, 213, 181, 57, 193, 77, 96, 216, 213, 181, 57, 193, 77, 235, 119, - 216, 213, 181, 57, 193, 77, 186, 193, 105, 216, 213, 181, 57, 193, 77, - 186, 234, 204, 216, 213, 181, 57, 193, 77, 202, 2, 234, 204, 216, 213, - 181, 57, 193, 77, 202, 2, 193, 105, 216, 213, 181, 57, 193, 77, 118, 88, - 181, 57, 193, 77, 196, 66, 88, 181, 57, 193, 77, 96, 88, 181, 57, 193, - 77, 235, 119, 88, 181, 57, 193, 77, 186, 193, 105, 88, 181, 57, 193, 77, - 186, 234, 204, 88, 181, 57, 193, 77, 202, 2, 234, 204, 88, 181, 57, 193, - 77, 202, 2, 193, 105, 88, 181, 57, 193, 77, 118, 195, 83, 88, 181, 57, - 193, 77, 196, 66, 195, 83, 88, 181, 57, 193, 77, 96, 195, 83, 88, 181, - 57, 193, 77, 235, 119, 195, 83, 88, 181, 57, 193, 77, 186, 193, 105, 195, - 83, 88, 181, 57, 193, 77, 186, 234, 204, 195, 83, 88, 181, 57, 193, 77, - 202, 2, 234, 204, 195, 83, 88, 181, 57, 193, 77, 202, 2, 193, 105, 195, - 83, 88, 181, 57, 118, 197, 242, 250, 235, 196, 66, 197, 242, 250, 235, - 96, 197, 242, 250, 235, 235, 119, 197, 242, 250, 235, 118, 63, 64, 193, - 53, 197, 242, 250, 235, 196, 66, 63, 64, 193, 53, 197, 242, 250, 235, 96, - 63, 64, 193, 53, 197, 242, 250, 235, 235, 119, 63, 64, 193, 53, 197, 242, - 250, 235, 118, 64, 4, 213, 8, 199, 215, 196, 66, 64, 4, 213, 8, 199, 215, - 96, 64, 4, 213, 8, 199, 215, 235, 119, 64, 4, 213, 8, 199, 215, 88, 64, - 203, 150, 193, 75, 107, 88, 64, 203, 150, 193, 75, 105, 198, 253, 88, 64, - 203, 150, 193, 75, 91, 230, 70, 88, 64, 203, 150, 193, 75, 91, 199, 0, - 118, 248, 74, 63, 57, 96, 248, 77, 203, 152, 63, 57, 118, 198, 54, 203, - 152, 63, 57, 96, 198, 54, 203, 152, 63, 57, 118, 219, 218, 63, 57, 96, - 206, 202, 63, 57, 118, 206, 202, 63, 57, 96, 219, 218, 63, 57, 118, 249, - 145, 203, 151, 63, 57, 96, 249, 145, 203, 151, 63, 57, 118, 232, 95, 203, - 151, 63, 57, 96, 232, 95, 203, 151, 63, 57, 63, 64, 203, 150, 193, 75, - 107, 63, 64, 203, 150, 193, 75, 105, 198, 253, 64, 209, 58, 196, 66, 199, - 25, 186, 193, 104, 64, 209, 58, 96, 199, 25, 238, 161, 202, 2, 193, 104, - 47, 238, 218, 232, 143, 4, 232, 128, 236, 138, 47, 238, 218, 232, 143, 4, - 105, 236, 138, 47, 238, 218, 232, 142, 45, 132, 243, 11, 4, 232, 128, - 236, 138, 45, 132, 243, 11, 4, 115, 236, 138, 45, 132, 243, 11, 4, 105, - 236, 138, 45, 132, 243, 11, 4, 236, 140, 45, 132, 243, 10, 235, 120, 233, - 96, 102, 235, 120, 233, 96, 213, 8, 102, 235, 120, 233, 96, 228, 251, 4, - 236, 140, 235, 120, 233, 96, 213, 8, 228, 251, 4, 236, 140, 209, 136, - 232, 247, 63, 229, 223, 248, 19, 229, 223, 209, 135, 230, 53, 191, 17, - 233, 103, 215, 229, 233, 103, 233, 104, 4, 199, 21, 214, 92, 233, 103, - 199, 2, 233, 103, 233, 104, 4, 229, 234, 206, 150, 233, 103, 228, 150, - 233, 103, 3, 79, 199, 34, 228, 186, 247, 139, 216, 233, 230, 53, 207, - 147, 249, 147, 79, 230, 53, 219, 223, 232, 231, 206, 207, 232, 231, 230, - 27, 230, 54, 4, 141, 23, 82, 232, 248, 238, 213, 228, 74, 218, 242, 191, - 239, 230, 54, 56, 233, 104, 4, 238, 238, 230, 9, 242, 208, 233, 103, 214, - 202, 233, 103, 206, 138, 211, 105, 199, 34, 232, 194, 219, 255, 235, 100, - 233, 103, 218, 178, 233, 103, 233, 104, 210, 182, 202, 56, 233, 103, 233, - 104, 4, 91, 233, 192, 207, 146, 230, 196, 233, 104, 4, 201, 103, 233, - 185, 230, 196, 233, 104, 4, 91, 220, 13, 23, 91, 2, 233, 193, 233, 104, - 4, 232, 253, 238, 241, 242, 219, 219, 96, 204, 2, 233, 104, 4, 200, 77, - 238, 241, 215, 179, 202, 64, 233, 104, 4, 202, 64, 233, 186, 23, 230, 54, - 238, 241, 215, 179, 233, 104, 4, 211, 77, 215, 180, 195, 9, 203, 54, 233, - 104, 4, 233, 208, 229, 235, 208, 226, 193, 35, 248, 40, 210, 181, 133, - 198, 87, 204, 31, 208, 214, 217, 91, 223, 163, 197, 46, 215, 194, 243, - 55, 203, 9, 209, 251, 236, 159, 247, 83, 222, 177, 233, 38, 215, 255, - 210, 21, 193, 8, 193, 144, 209, 44, 230, 32, 236, 201, 217, 35, 193, 69, - 232, 186, 235, 95, 4, 235, 93, 242, 226, 231, 15, 197, 74, 231, 16, 201, - 203, 231, 1, 214, 85, 206, 208, 232, 238, 209, 108, 216, 219, 205, 57, - 209, 108, 216, 219, 199, 1, 209, 108, 216, 219, 248, 61, 231, 10, 217, - 46, 250, 223, 196, 94, 238, 172, 201, 65, 220, 110, 201, 75, 23, 249, - 111, 202, 31, 232, 178, 236, 226, 238, 221, 250, 141, 238, 188, 249, 138, - 209, 12, 247, 87, 249, 124, 248, 43, 230, 201, 205, 165, 203, 142, 210, - 167, 79, 232, 161, 201, 9, 232, 205, 234, 179, 231, 17, 79, 216, 53, 210, - 56, 221, 116, 210, 163, 235, 76, 232, 138, 239, 16, 199, 207, 248, 62, - 243, 62, 248, 67, 4, 201, 203, 238, 182, 4, 201, 43, 242, 93, 248, 23, - 209, 176, 208, 218, 238, 155, 79, 216, 224, 205, 137, 247, 115, 232, 161, - 219, 232, 230, 200, 217, 82, 215, 206, 247, 146, 249, 127, 202, 64, 233, - 104, 4, 202, 64, 233, 186, 23, 115, 229, 221, 192, 87, 233, 103, 202, 64, - 233, 104, 4, 199, 131, 233, 104, 4, 210, 102, 228, 188, 23, 210, 102, - 230, 9, 233, 104, 4, 196, 98, 233, 186, 23, 193, 135, 215, 179, 211, 5, - 233, 103, 232, 107, 233, 103, 213, 168, 236, 224, 233, 103, 233, 104, - 229, 6, 249, 147, 199, 125, 233, 104, 4, 209, 93, 233, 185, 205, 125, - 220, 119, 242, 96, 230, 253, 229, 129, 248, 91, 232, 207, 203, 52, 238, - 235, 219, 100, 233, 103, 205, 81, 197, 62, 196, 96, 233, 103, 234, 214, - 235, 85, 249, 64, 203, 128, 210, 249, 232, 120, 233, 103, 247, 215, 237, - 128, 230, 235, 219, 78, 207, 5, 203, 13, 201, 184, 231, 29, 233, 103, - 191, 85, 233, 103, 229, 216, 205, 110, 200, 42, 238, 224, 222, 82, 219, - 70, 210, 58, 229, 121, 210, 108, 207, 173, 219, 41, 215, 196, 216, 90, - 249, 133, 200, 148, 217, 92, 236, 165, 202, 78, 211, 22, 211, 54, 202, - 102, 232, 209, 210, 239, 249, 4, 248, 149, 205, 61, 230, 163, 236, 162, - 208, 202, 247, 117, 234, 109, 242, 64, 207, 87, 230, 78, 234, 109, 242, - 64, 238, 171, 230, 78, 234, 109, 242, 64, 249, 113, 234, 109, 242, 64, - 63, 230, 78, 248, 98, 219, 212, 232, 159, 198, 56, 200, 184, 200, 179, - 205, 188, 195, 81, 234, 212, 4, 229, 225, 251, 235, 215, 190, 193, 91, - 217, 74, 193, 91, 216, 223, 250, 250, 216, 223, 219, 212, 243, 118, 193, - 116, 238, 180, 205, 159, 203, 146, 248, 208, 248, 62, 231, 197, 211, 93, - 233, 85, 193, 174, 247, 216, 217, 29, 235, 104, 228, 27, 238, 190, 248, - 9, 199, 134, 197, 214, 201, 105, 209, 250, 221, 80, 209, 250, 237, 144, - 209, 250, 233, 104, 4, 215, 224, 252, 29, 243, 86, 211, 118, 252, 29, - 249, 8, 209, 250, 209, 251, 4, 229, 230, 209, 251, 223, 163, 201, 82, - 206, 130, 209, 251, 242, 228, 209, 251, 223, 163, 218, 247, 209, 24, 217, - 124, 233, 87, 195, 177, 216, 174, 234, 125, 231, 148, 191, 5, 248, 50, - 211, 55, 229, 223, 248, 171, 247, 111, 205, 94, 231, 9, 242, 96, 202, 34, - 207, 87, 231, 43, 234, 67, 232, 242, 222, 238, 208, 125, 209, 175, 199, - 75, 197, 84, 209, 235, 236, 222, 236, 176, 55, 229, 204, 242, 69, 252, - 71, 232, 244, 233, 202, 198, 58, 248, 31, 217, 122, 218, 215, 218, 248, - 248, 78, 201, 204, 79, 198, 227, 249, 112, 79, 192, 100, 205, 188, 209, - 139, 199, 124, 249, 9, 248, 20, 249, 69, 206, 141, 79, 210, 135, 249, 88, - 79, 202, 37, 201, 205, 207, 103, 214, 196, 251, 134, 214, 82, 243, 105, - 221, 138, 214, 82, 243, 105, 208, 14, 214, 82, 243, 105, 206, 131, 214, - 82, 243, 105, 248, 152, 214, 82, 243, 105, 221, 76, 214, 82, 243, 105, - 210, 74, 63, 243, 105, 221, 77, 206, 122, 232, 134, 237, 124, 62, 243, - 105, 221, 77, 206, 122, 232, 134, 237, 124, 214, 82, 243, 105, 221, 77, - 206, 122, 232, 134, 237, 124, 63, 243, 105, 221, 139, 206, 122, 213, 170, - 237, 124, 63, 243, 105, 208, 15, 206, 122, 213, 170, 237, 124, 63, 243, - 105, 206, 132, 206, 122, 213, 170, 237, 124, 63, 243, 105, 248, 153, 206, - 122, 213, 170, 237, 124, 63, 243, 105, 221, 77, 206, 122, 213, 170, 237, - 124, 63, 243, 105, 210, 75, 206, 122, 213, 170, 237, 124, 62, 243, 105, - 221, 139, 206, 122, 213, 170, 237, 124, 62, 243, 105, 208, 15, 206, 122, - 213, 170, 237, 124, 62, 243, 105, 206, 132, 206, 122, 213, 170, 237, 124, - 62, 243, 105, 248, 153, 206, 122, 213, 170, 237, 124, 62, 243, 105, 221, - 77, 206, 122, 213, 170, 237, 124, 62, 243, 105, 210, 75, 206, 122, 213, - 170, 237, 124, 214, 82, 243, 105, 221, 139, 206, 122, 213, 170, 237, 124, - 214, 82, 243, 105, 208, 15, 206, 122, 213, 170, 237, 124, 214, 82, 243, - 105, 206, 132, 206, 122, 213, 170, 237, 124, 214, 82, 243, 105, 248, 153, - 206, 122, 213, 170, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 213, - 170, 237, 124, 214, 82, 243, 105, 210, 75, 206, 122, 213, 170, 237, 124, - 63, 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 62, - 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 214, 82, - 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 63, 243, - 105, 153, 221, 138, 63, 243, 105, 153, 208, 14, 63, 243, 105, 153, 206, - 131, 63, 243, 105, 153, 248, 152, 63, 243, 105, 153, 221, 76, 63, 243, - 105, 153, 210, 74, 62, 243, 105, 153, 221, 138, 62, 243, 105, 153, 208, - 14, 62, 243, 105, 153, 206, 131, 62, 243, 105, 153, 248, 152, 62, 243, - 105, 153, 221, 76, 62, 243, 105, 153, 210, 74, 214, 82, 243, 105, 153, - 221, 138, 214, 82, 243, 105, 153, 208, 14, 214, 82, 243, 105, 153, 206, - 131, 214, 82, 243, 105, 153, 248, 152, 214, 82, 243, 105, 153, 221, 76, - 214, 82, 243, 105, 153, 210, 74, 63, 243, 105, 221, 77, 206, 122, 105, - 228, 141, 197, 29, 237, 124, 62, 243, 105, 221, 77, 206, 122, 105, 228, - 141, 197, 29, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 105, 228, - 141, 197, 29, 237, 124, 63, 243, 105, 221, 139, 206, 122, 105, 228, 141, - 203, 242, 237, 124, 63, 243, 105, 208, 15, 206, 122, 105, 228, 141, 203, - 242, 237, 124, 63, 243, 105, 206, 132, 206, 122, 105, 228, 141, 203, 242, - 237, 124, 63, 243, 105, 248, 153, 206, 122, 105, 228, 141, 203, 242, 237, - 124, 63, 243, 105, 221, 77, 206, 122, 105, 228, 141, 203, 242, 237, 124, - 63, 243, 105, 210, 75, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, - 243, 105, 221, 139, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, - 105, 208, 15, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, - 206, 132, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 248, - 153, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 221, 77, - 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 210, 75, 206, - 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 221, 139, 206, - 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 208, 15, 206, - 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 206, 132, 206, - 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 248, 153, 206, - 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 221, 77, 206, - 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 210, 75, 206, - 122, 105, 228, 141, 203, 242, 237, 124, 63, 243, 105, 221, 77, 206, 122, - 115, 228, 141, 233, 20, 237, 124, 62, 243, 105, 221, 77, 206, 122, 115, - 228, 141, 233, 20, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 115, - 228, 141, 233, 20, 237, 124, 63, 243, 105, 234, 38, 62, 243, 105, 234, - 38, 214, 82, 243, 105, 234, 38, 63, 243, 105, 234, 39, 206, 122, 213, - 170, 237, 124, 62, 243, 105, 234, 39, 206, 122, 213, 170, 237, 124, 214, - 82, 243, 105, 234, 39, 206, 122, 213, 170, 237, 124, 63, 243, 105, 221, - 74, 63, 243, 105, 221, 73, 63, 243, 105, 221, 75, 62, 243, 105, 221, 74, - 62, 243, 105, 221, 73, 62, 243, 105, 221, 75, 192, 205, 207, 87, 231, - 150, 192, 205, 207, 87, 217, 84, 192, 205, 207, 87, 234, 131, 192, 205, - 207, 87, 228, 183, 192, 205, 207, 87, 243, 138, 192, 205, 207, 87, 247, - 114, 192, 205, 207, 87, 202, 26, 192, 205, 62, 231, 150, 192, 205, 62, - 217, 84, 192, 205, 62, 234, 131, 192, 205, 62, 228, 183, 192, 205, 62, - 243, 138, 192, 205, 62, 247, 114, 192, 205, 62, 202, 26, 249, 110, 203, - 51, 211, 98, 200, 135, 248, 27, 203, 25, 198, 237, 205, 139, 156, 248, - 115, 229, 223, 230, 198, 229, 223, 209, 131, 229, 223, 235, 99, 79, 248, - 120, 252, 35, 249, 96, 201, 76, 192, 234, 238, 201, 191, 253, 221, 119, - 210, 129, 248, 92, 217, 123, 193, 162, 209, 137, 214, 87, 236, 154, 217, - 64, 232, 182, 206, 187, 209, 100, 246, 252, 207, 118, 250, 132, 236, 196, - 220, 25, 249, 94, 216, 54, 229, 200, 252, 56, 179, 235, 94, 242, 88, 247, - 89, 205, 108, 205, 75, 220, 109, 102, 216, 26, 193, 65, 209, 83, 203, - 239, 214, 109, 221, 71, 248, 6, 215, 182, 198, 6, 198, 55, 229, 228, 209, - 109, 206, 147, 216, 27, 249, 111, 228, 16, 247, 100, 130, 249, 58, 230, - 60, 232, 170, 230, 54, 233, 80, 230, 79, 209, 180, 221, 203, 232, 179, - 193, 17, 248, 251, 242, 95, 209, 11, 209, 99, 193, 28, 233, 54, 218, 246, - 239, 4, 234, 105, 214, 89, 214, 90, 4, 234, 178, 228, 92, 223, 2, 193, - 61, 230, 243, 251, 129, 229, 223, 218, 205, 210, 20, 228, 149, 208, 226, - 217, 90, 208, 226, 209, 250, 209, 251, 4, 238, 208, 215, 204, 236, 147, - 248, 113, 248, 236, 210, 15, 211, 115, 232, 205, 199, 196, 232, 165, 199, - 132, 209, 7, 219, 92, 249, 11, 223, 18, 231, 36, 206, 128, 210, 62, 209, - 70, 216, 195, 233, 103, 205, 153, 233, 103, 233, 104, 4, 211, 77, 233, - 186, 23, 230, 54, 139, 215, 179, 233, 104, 4, 210, 47, 233, 193, 233, - 104, 4, 237, 39, 215, 179, 235, 138, 219, 113, 233, 103, 248, 145, 219, - 98, 248, 7, 203, 145, 233, 103, 230, 54, 4, 141, 232, 253, 23, 176, 238, - 213, 96, 230, 53, 118, 230, 53, 210, 183, 144, 230, 53, 210, 183, 133, - 230, 53, 141, 209, 58, 250, 183, 199, 34, 195, 55, 229, 224, 230, 28, - 118, 208, 135, 230, 53, 96, 208, 135, 230, 53, 184, 203, 236, 184, 203, - 206, 184, 203, 235, 184, 203, 191, 184, 203, 220, 184, 203, 205, 184, - 203, 234, 184, 203, 183, 184, 203, 213, 184, 203, 197, 184, 203, 227, - 184, 203, 190, 184, 203, 219, 184, 203, 204, 184, 203, 233, 184, 203, - 179, 184, 203, 209, 184, 203, 194, 184, 203, 223, 184, 203, 186, 184, + 200, 205, 160, 16, 40, 209, 205, 200, 205, 160, 16, 40, 62, 200, 205, + 160, 16, 40, 216, 183, 200, 237, 160, 16, 40, 216, 183, 200, 236, 160, + 16, 40, 216, 183, 200, 235, 160, 16, 40, 243, 15, 160, 16, 40, 205, 159, + 160, 16, 40, 213, 163, 160, 16, 40, 195, 28, 160, 16, 40, 195, 27, 160, + 16, 40, 206, 149, 205, 159, 160, 16, 40, 206, 149, 205, 158, 160, 16, 40, + 230, 252, 160, 16, 40, 202, 185, 160, 16, 40, 223, 76, 211, 51, 160, 16, + 40, 223, 76, 211, 50, 160, 16, 40, 238, 224, 79, 223, 75, 160, 16, 40, + 207, 78, 79, 223, 75, 160, 16, 40, 239, 14, 211, 51, 160, 16, 40, 223, + 74, 211, 51, 160, 16, 40, 200, 238, 79, 239, 13, 160, 16, 40, 238, 224, + 79, 239, 13, 160, 16, 40, 238, 224, 79, 239, 12, 160, 16, 40, 239, 14, + 251, 81, 160, 16, 40, 205, 160, 79, 239, 14, 251, 81, 160, 16, 40, 200, + 238, 79, 205, 160, 79, 239, 13, 160, 16, 40, 195, 139, 160, 16, 40, 198, + 143, 211, 51, 160, 16, 40, 219, 239, 211, 51, 160, 16, 40, 251, 80, 211, + 51, 160, 16, 40, 200, 238, 79, 251, 79, 160, 16, 40, 205, 160, 79, 251, + 79, 160, 16, 40, 200, 238, 79, 205, 160, 79, 251, 79, 160, 16, 40, 195, + 46, 79, 251, 79, 160, 16, 40, 207, 78, 79, 251, 79, 160, 16, 40, 207, 78, + 79, 251, 78, 160, 16, 40, 207, 77, 160, 16, 40, 207, 76, 160, 16, 40, + 207, 75, 160, 16, 40, 207, 74, 160, 16, 40, 251, 179, 160, 16, 40, 251, + 178, 160, 16, 40, 217, 63, 160, 16, 40, 205, 169, 160, 16, 40, 250, 232, + 160, 16, 40, 207, 107, 160, 16, 40, 207, 106, 160, 16, 40, 250, 156, 160, + 16, 40, 248, 152, 211, 51, 160, 16, 40, 199, 177, 160, 16, 40, 199, 176, + 160, 16, 40, 208, 10, 219, 123, 160, 16, 40, 248, 89, 160, 16, 40, 248, + 88, 160, 16, 40, 248, 87, 160, 16, 40, 251, 153, 160, 16, 40, 211, 133, + 160, 16, 40, 201, 215, 160, 16, 40, 198, 141, 160, 16, 40, 230, 160, 160, + 16, 40, 193, 131, 160, 16, 40, 209, 3, 160, 16, 40, 247, 139, 160, 16, + 40, 197, 50, 160, 16, 40, 247, 106, 215, 200, 160, 16, 40, 205, 94, 79, + 222, 189, 160, 16, 40, 247, 153, 160, 16, 40, 197, 235, 160, 16, 40, 201, + 101, 197, 235, 160, 16, 40, 219, 33, 160, 16, 40, 202, 38, 160, 16, 40, + 196, 54, 160, 16, 40, 228, 186, 235, 73, 160, 16, 40, 250, 206, 160, 16, + 40, 209, 17, 250, 206, 160, 16, 40, 248, 33, 160, 16, 40, 209, 2, 248, + 33, 160, 16, 40, 251, 150, 160, 16, 40, 201, 47, 200, 186, 201, 46, 160, + 16, 40, 201, 47, 200, 186, 201, 45, 160, 16, 40, 200, 234, 160, 16, 40, + 208, 231, 160, 16, 40, 236, 217, 160, 16, 40, 236, 219, 160, 16, 40, 236, + 218, 160, 16, 40, 208, 143, 160, 16, 40, 208, 131, 160, 16, 40, 238, 209, + 160, 16, 40, 238, 208, 160, 16, 40, 238, 207, 160, 16, 40, 238, 206, 160, + 16, 40, 238, 205, 160, 16, 40, 251, 193, 160, 16, 40, 249, 64, 79, 217, + 44, 160, 16, 40, 249, 64, 79, 195, 174, 160, 16, 40, 207, 27, 160, 16, + 40, 228, 178, 160, 16, 40, 213, 192, 160, 16, 40, 237, 205, 160, 16, 40, + 215, 215, 160, 16, 40, 132, 235, 111, 160, 16, 40, 132, 211, 19, 218, + 252, 79, 232, 139, 211, 166, 218, 209, 234, 196, 230, 3, 217, 103, 230, + 248, 208, 26, 211, 54, 62, 219, 221, 223, 58, 50, 197, 241, 62, 196, 76, + 223, 58, 50, 197, 241, 62, 206, 204, 223, 58, 50, 197, 241, 62, 235, 124, + 223, 58, 50, 197, 241, 62, 202, 85, 2, 243, 12, 216, 215, 28, 63, 243, + 12, 28, 63, 243, 12, 88, 63, 243, 12, 195, 83, 88, 63, 243, 12, 233, 199, + 88, 63, 243, 12, 63, 243, 13, 239, 35, 62, 2, 243, 12, 206, 116, 199, + 178, 62, 198, 138, 201, 191, 62, 202, 85, 2, 201, 191, 156, 63, 201, 191, + 216, 215, 63, 201, 191, 28, 63, 201, 191, 88, 63, 201, 191, 195, 83, 88, + 63, 201, 191, 233, 199, 88, 63, 201, 191, 63, 51, 239, 35, 62, 195, 83, + 2, 201, 191, 63, 51, 239, 35, 62, 216, 215, 201, 191, 51, 199, 178, 62, + 198, 138, 237, 34, 62, 195, 83, 2, 237, 34, 62, 216, 215, 2, 237, 34, 63, + 237, 35, 239, 35, 62, 195, 83, 2, 237, 34, 63, 237, 35, 239, 35, 62, 216, + 215, 237, 34, 237, 35, 199, 178, 62, 198, 138, 218, 234, 62, 195, 83, 2, + 218, 234, 62, 216, 215, 2, 218, 234, 63, 218, 235, 239, 35, 62, 2, 218, + 234, 199, 4, 35, 238, 219, 156, 35, 238, 219, 216, 215, 35, 238, 219, 28, + 35, 238, 219, 195, 83, 28, 35, 238, 219, 195, 83, 88, 35, 238, 219, 233, + 199, 88, 35, 238, 219, 199, 4, 205, 155, 156, 205, 155, 216, 215, 205, + 155, 28, 205, 155, 88, 205, 155, 195, 83, 88, 205, 155, 233, 199, 88, + 205, 155, 156, 232, 228, 201, 207, 250, 195, 216, 215, 232, 228, 201, + 207, 250, 195, 28, 232, 228, 201, 207, 250, 195, 88, 232, 228, 201, 207, + 250, 195, 195, 83, 88, 232, 228, 201, 207, 250, 195, 233, 199, 88, 232, + 228, 201, 207, 250, 195, 156, 202, 137, 201, 207, 250, 195, 216, 215, + 202, 137, 201, 207, 250, 195, 28, 202, 137, 201, 207, 250, 195, 88, 202, + 137, 201, 207, 250, 195, 195, 83, 88, 202, 137, 201, 207, 250, 195, 233, + 199, 88, 202, 137, 201, 207, 250, 195, 156, 234, 166, 201, 207, 250, 195, + 216, 215, 234, 166, 201, 207, 250, 195, 28, 234, 166, 201, 207, 250, 195, + 88, 234, 166, 201, 207, 250, 195, 195, 83, 88, 234, 166, 201, 207, 250, + 195, 156, 115, 209, 62, 62, 201, 103, 216, 215, 115, 209, 62, 62, 201, + 103, 115, 209, 62, 62, 201, 103, 216, 215, 115, 209, 62, 209, 132, 201, + 103, 156, 232, 130, 209, 62, 62, 201, 103, 216, 215, 232, 130, 209, 62, + 62, 201, 103, 232, 130, 209, 62, 62, 201, 103, 216, 215, 232, 130, 209, + 62, 209, 132, 201, 103, 207, 20, 156, 232, 130, 209, 62, 209, 132, 201, + 103, 156, 232, 228, 209, 62, 62, 201, 103, 88, 232, 228, 209, 62, 62, + 201, 103, 216, 215, 202, 137, 209, 62, 62, 201, 103, 88, 202, 137, 209, + 62, 62, 201, 103, 202, 137, 209, 62, 209, 132, 201, 103, 216, 215, 234, + 166, 209, 62, 62, 201, 103, 88, 234, 166, 209, 62, 62, 201, 103, 195, 83, + 88, 234, 166, 209, 62, 62, 201, 103, 88, 234, 166, 209, 62, 209, 132, + 201, 103, 156, 197, 38, 209, 62, 62, 201, 103, 88, 197, 38, 209, 62, 62, + 201, 103, 88, 197, 38, 209, 62, 209, 132, 201, 103, 47, 197, 241, 214, + 108, 47, 197, 241, 47, 201, 191, 214, 108, 47, 201, 191, 213, 177, 209, + 62, 63, 201, 103, 220, 15, 211, 57, 243, 12, 220, 15, 192, 73, 243, 12, + 220, 15, 230, 203, 243, 12, 220, 15, 208, 140, 243, 12, 220, 15, 248, 21, + 243, 12, 220, 15, 207, 89, 201, 191, 220, 15, 248, 117, 201, 191, 220, + 15, 211, 57, 201, 191, 220, 15, 192, 73, 201, 191, 220, 15, 230, 203, + 201, 191, 220, 15, 208, 140, 201, 191, 220, 15, 248, 21, 201, 191, 88, + 234, 45, 56, 118, 64, 4, 2, 197, 242, 250, 237, 196, 66, 64, 4, 2, 197, + 242, 250, 237, 96, 64, 4, 2, 197, 242, 250, 237, 235, 121, 64, 4, 2, 197, + 242, 250, 237, 118, 64, 4, 216, 215, 197, 242, 250, 237, 196, 66, 64, 4, + 216, 215, 197, 242, 250, 237, 96, 64, 4, 216, 215, 197, 242, 250, 237, + 235, 121, 64, 4, 216, 215, 197, 242, 250, 237, 118, 64, 4, 220, 15, 197, + 242, 250, 237, 196, 66, 64, 4, 220, 15, 197, 242, 250, 237, 96, 64, 4, + 220, 15, 197, 242, 250, 237, 235, 121, 64, 4, 220, 15, 197, 242, 250, + 237, 118, 64, 4, 2, 234, 39, 250, 237, 196, 66, 64, 4, 2, 234, 39, 250, + 237, 96, 64, 4, 2, 234, 39, 250, 237, 235, 121, 64, 4, 2, 234, 39, 250, + 237, 118, 64, 4, 234, 39, 250, 237, 196, 66, 64, 4, 234, 39, 250, 237, + 96, 64, 4, 234, 39, 250, 237, 235, 121, 64, 4, 234, 39, 250, 237, 88, + 118, 64, 4, 234, 39, 250, 237, 88, 196, 66, 64, 4, 234, 39, 250, 237, 88, + 96, 64, 4, 234, 39, 250, 237, 88, 235, 121, 64, 4, 234, 39, 250, 237, 88, + 118, 64, 4, 220, 15, 234, 39, 250, 237, 88, 196, 66, 64, 4, 220, 15, 234, + 39, 250, 237, 88, 96, 64, 4, 220, 15, 234, 39, 250, 237, 88, 235, 121, + 64, 4, 220, 15, 234, 39, 250, 237, 118, 197, 240, 64, 4, 214, 217, 203, + 150, 196, 66, 197, 240, 64, 4, 214, 217, 203, 150, 96, 197, 240, 64, 4, + 214, 217, 203, 150, 235, 121, 197, 240, 64, 4, 214, 217, 203, 150, 118, + 197, 240, 64, 4, 216, 215, 203, 150, 196, 66, 197, 240, 64, 4, 216, 215, + 203, 150, 96, 197, 240, 64, 4, 216, 215, 203, 150, 235, 121, 197, 240, + 64, 4, 216, 215, 203, 150, 118, 197, 240, 64, 4, 28, 203, 150, 196, 66, + 197, 240, 64, 4, 28, 203, 150, 96, 197, 240, 64, 4, 28, 203, 150, 235, + 121, 197, 240, 64, 4, 28, 203, 150, 118, 197, 240, 64, 4, 88, 203, 150, + 196, 66, 197, 240, 64, 4, 88, 203, 150, 96, 197, 240, 64, 4, 88, 203, + 150, 235, 121, 197, 240, 64, 4, 88, 203, 150, 118, 197, 240, 64, 4, 195, + 83, 88, 203, 150, 196, 66, 197, 240, 64, 4, 195, 83, 88, 203, 150, 96, + 197, 240, 64, 4, 195, 83, 88, 203, 150, 235, 121, 197, 240, 64, 4, 195, + 83, 88, 203, 150, 118, 232, 253, 57, 196, 66, 232, 253, 57, 96, 232, 253, + 57, 235, 121, 232, 253, 57, 118, 112, 57, 196, 66, 112, 57, 96, 112, 57, + 235, 121, 112, 57, 118, 239, 63, 57, 196, 66, 239, 63, 57, 96, 239, 63, + 57, 235, 121, 239, 63, 57, 118, 88, 239, 63, 57, 196, 66, 88, 239, 63, + 57, 96, 88, 239, 63, 57, 235, 121, 88, 239, 63, 57, 118, 88, 57, 196, 66, + 88, 57, 96, 88, 57, 235, 121, 88, 57, 118, 49, 57, 196, 66, 49, 57, 96, + 49, 57, 235, 121, 49, 57, 186, 193, 105, 49, 57, 186, 234, 206, 49, 57, + 202, 3, 234, 206, 49, 57, 202, 3, 193, 105, 49, 57, 45, 50, 49, 57, 133, + 144, 49, 57, 193, 77, 118, 156, 182, 57, 193, 77, 196, 66, 156, 182, 57, + 193, 77, 96, 156, 182, 57, 193, 77, 235, 121, 156, 182, 57, 193, 77, 186, + 193, 105, 156, 182, 57, 193, 77, 186, 234, 206, 156, 182, 57, 193, 77, + 202, 3, 234, 206, 156, 182, 57, 193, 77, 202, 3, 193, 105, 156, 182, 57, + 193, 77, 118, 182, 57, 193, 77, 196, 66, 182, 57, 193, 77, 96, 182, 57, + 193, 77, 235, 121, 182, 57, 193, 77, 186, 193, 105, 182, 57, 193, 77, + 186, 234, 206, 182, 57, 193, 77, 202, 3, 234, 206, 182, 57, 193, 77, 202, + 3, 193, 105, 182, 57, 193, 77, 118, 216, 215, 182, 57, 193, 77, 196, 66, + 216, 215, 182, 57, 193, 77, 96, 216, 215, 182, 57, 193, 77, 235, 121, + 216, 215, 182, 57, 193, 77, 186, 193, 105, 216, 215, 182, 57, 193, 77, + 186, 234, 206, 216, 215, 182, 57, 193, 77, 202, 3, 234, 206, 216, 215, + 182, 57, 193, 77, 202, 3, 193, 105, 216, 215, 182, 57, 193, 77, 118, 88, + 182, 57, 193, 77, 196, 66, 88, 182, 57, 193, 77, 96, 88, 182, 57, 193, + 77, 235, 121, 88, 182, 57, 193, 77, 186, 193, 105, 88, 182, 57, 193, 77, + 186, 234, 206, 88, 182, 57, 193, 77, 202, 3, 234, 206, 88, 182, 57, 193, + 77, 202, 3, 193, 105, 88, 182, 57, 193, 77, 118, 195, 83, 88, 182, 57, + 193, 77, 196, 66, 195, 83, 88, 182, 57, 193, 77, 96, 195, 83, 88, 182, + 57, 193, 77, 235, 121, 195, 83, 88, 182, 57, 193, 77, 186, 193, 105, 195, + 83, 88, 182, 57, 193, 77, 186, 234, 206, 195, 83, 88, 182, 57, 193, 77, + 202, 3, 234, 206, 195, 83, 88, 182, 57, 193, 77, 202, 3, 193, 105, 195, + 83, 88, 182, 57, 118, 197, 242, 250, 237, 196, 66, 197, 242, 250, 237, + 96, 197, 242, 250, 237, 235, 121, 197, 242, 250, 237, 118, 63, 64, 193, + 53, 197, 242, 250, 237, 196, 66, 63, 64, 193, 53, 197, 242, 250, 237, 96, + 63, 64, 193, 53, 197, 242, 250, 237, 235, 121, 63, 64, 193, 53, 197, 242, + 250, 237, 118, 64, 4, 213, 10, 199, 215, 196, 66, 64, 4, 213, 10, 199, + 215, 96, 64, 4, 213, 10, 199, 215, 235, 121, 64, 4, 213, 10, 199, 215, + 88, 64, 203, 151, 193, 75, 107, 88, 64, 203, 151, 193, 75, 105, 198, 253, + 88, 64, 203, 151, 193, 75, 91, 230, 72, 88, 64, 203, 151, 193, 75, 91, + 199, 0, 118, 248, 76, 63, 57, 96, 248, 79, 203, 153, 63, 57, 118, 198, + 54, 203, 153, 63, 57, 96, 198, 54, 203, 153, 63, 57, 118, 219, 220, 63, + 57, 96, 206, 203, 63, 57, 118, 206, 203, 63, 57, 96, 219, 220, 63, 57, + 118, 249, 147, 203, 152, 63, 57, 96, 249, 147, 203, 152, 63, 57, 118, + 232, 97, 203, 152, 63, 57, 96, 232, 97, 203, 152, 63, 57, 63, 64, 203, + 151, 193, 75, 107, 63, 64, 203, 151, 193, 75, 105, 198, 253, 64, 209, 60, + 196, 66, 199, 25, 186, 193, 104, 64, 209, 60, 96, 199, 25, 238, 163, 202, + 3, 193, 104, 47, 238, 220, 232, 145, 4, 232, 130, 236, 140, 47, 238, 220, + 232, 145, 4, 105, 236, 140, 47, 238, 220, 232, 144, 45, 132, 243, 13, 4, + 232, 130, 236, 140, 45, 132, 243, 13, 4, 115, 236, 140, 45, 132, 243, 13, + 4, 105, 236, 140, 45, 132, 243, 13, 4, 236, 142, 45, 132, 243, 12, 235, + 122, 233, 98, 102, 235, 122, 233, 98, 213, 10, 102, 235, 122, 233, 98, + 228, 253, 4, 236, 142, 235, 122, 233, 98, 213, 10, 228, 253, 4, 236, 142, + 209, 138, 232, 249, 63, 229, 225, 248, 21, 229, 225, 209, 137, 230, 55, + 191, 17, 233, 105, 215, 231, 233, 105, 233, 106, 4, 199, 21, 214, 94, + 233, 105, 199, 2, 233, 105, 233, 106, 4, 229, 236, 206, 151, 233, 105, + 228, 152, 233, 105, 3, 79, 199, 34, 228, 188, 247, 141, 216, 235, 230, + 55, 207, 149, 249, 149, 79, 230, 55, 219, 225, 232, 233, 206, 208, 232, + 233, 230, 29, 230, 56, 4, 141, 23, 82, 232, 250, 238, 215, 228, 76, 218, + 244, 191, 239, 230, 56, 56, 233, 106, 4, 238, 240, 230, 11, 242, 210, + 233, 105, 214, 204, 233, 105, 206, 139, 211, 107, 199, 34, 232, 196, 220, + 1, 235, 102, 233, 105, 218, 180, 233, 105, 233, 106, 210, 184, 202, 57, + 233, 105, 233, 106, 4, 91, 233, 194, 207, 148, 230, 198, 233, 106, 4, + 201, 104, 233, 187, 230, 198, 233, 106, 4, 91, 220, 15, 23, 91, 2, 233, + 195, 233, 106, 4, 232, 255, 238, 243, 242, 221, 219, 98, 204, 3, 233, + 106, 4, 200, 77, 238, 243, 215, 181, 202, 65, 233, 106, 4, 202, 65, 233, + 188, 23, 230, 56, 238, 243, 215, 181, 233, 106, 4, 211, 79, 215, 182, + 195, 9, 203, 55, 233, 106, 4, 233, 210, 229, 237, 208, 228, 193, 35, 248, + 42, 210, 183, 133, 198, 87, 204, 32, 208, 216, 217, 93, 223, 165, 197, + 46, 215, 196, 243, 57, 203, 10, 209, 253, 236, 161, 247, 85, 222, 179, + 233, 40, 216, 1, 210, 23, 193, 8, 193, 144, 209, 46, 230, 34, 236, 203, + 217, 37, 193, 69, 232, 188, 235, 97, 4, 235, 95, 242, 228, 231, 17, 197, + 74, 231, 18, 201, 204, 231, 3, 214, 87, 206, 209, 232, 240, 209, 110, + 216, 221, 205, 58, 209, 110, 216, 221, 199, 1, 209, 110, 216, 221, 248, + 63, 231, 12, 217, 48, 250, 225, 196, 94, 238, 174, 201, 66, 220, 112, + 201, 76, 23, 249, 113, 202, 32, 232, 180, 236, 228, 238, 223, 250, 143, + 238, 190, 249, 140, 209, 14, 247, 89, 249, 126, 248, 45, 230, 203, 205, + 166, 203, 143, 210, 169, 79, 232, 163, 201, 10, 232, 207, 234, 181, 231, + 19, 79, 216, 55, 210, 58, 221, 118, 210, 165, 235, 78, 232, 140, 239, 18, + 199, 207, 248, 64, 243, 64, 248, 69, 4, 201, 204, 238, 184, 4, 201, 44, + 242, 95, 248, 25, 209, 178, 208, 220, 238, 157, 79, 216, 226, 205, 138, + 247, 117, 232, 163, 219, 234, 230, 202, 217, 84, 215, 208, 247, 148, 249, + 129, 202, 65, 233, 106, 4, 202, 65, 233, 188, 23, 115, 229, 223, 192, 87, + 233, 105, 202, 65, 233, 106, 4, 199, 131, 233, 106, 4, 210, 104, 228, + 190, 23, 210, 104, 230, 11, 233, 106, 4, 196, 98, 233, 188, 23, 193, 135, + 215, 181, 211, 7, 233, 105, 232, 109, 233, 105, 213, 170, 236, 226, 233, + 105, 233, 106, 229, 8, 249, 149, 199, 125, 233, 106, 4, 209, 95, 233, + 187, 205, 126, 220, 121, 242, 98, 230, 255, 229, 131, 248, 93, 232, 209, + 203, 53, 238, 237, 219, 102, 233, 105, 205, 82, 197, 62, 196, 96, 233, + 105, 234, 216, 235, 87, 249, 66, 203, 129, 210, 251, 232, 122, 233, 105, + 247, 217, 237, 130, 230, 237, 219, 80, 207, 6, 203, 14, 201, 185, 231, + 31, 233, 105, 191, 85, 233, 105, 229, 218, 205, 111, 200, 42, 238, 226, + 222, 84, 219, 72, 210, 60, 229, 123, 210, 110, 207, 175, 219, 43, 215, + 198, 216, 92, 249, 135, 200, 148, 217, 94, 236, 167, 202, 79, 211, 24, + 211, 56, 202, 103, 232, 211, 210, 241, 249, 6, 248, 151, 205, 62, 230, + 165, 236, 164, 208, 204, 247, 119, 234, 111, 242, 66, 207, 89, 230, 80, + 234, 111, 242, 66, 238, 173, 230, 80, 234, 111, 242, 66, 249, 115, 234, + 111, 242, 66, 63, 230, 80, 248, 100, 219, 214, 232, 161, 198, 56, 200, + 184, 200, 179, 205, 189, 195, 81, 234, 214, 4, 229, 227, 251, 237, 215, + 192, 193, 91, 217, 76, 193, 91, 216, 225, 250, 252, 216, 225, 219, 214, + 243, 120, 193, 116, 238, 182, 205, 160, 203, 147, 248, 210, 248, 64, 231, + 199, 211, 95, 233, 87, 193, 174, 247, 218, 217, 31, 235, 106, 228, 29, + 238, 192, 248, 11, 199, 134, 197, 214, 201, 106, 209, 252, 221, 82, 209, + 252, 237, 146, 209, 252, 233, 106, 4, 215, 226, 252, 31, 243, 88, 211, + 120, 252, 31, 249, 10, 209, 252, 209, 253, 4, 229, 232, 209, 253, 223, + 165, 201, 83, 206, 131, 209, 253, 242, 230, 209, 253, 223, 165, 218, 249, + 209, 26, 217, 126, 233, 89, 195, 177, 216, 176, 234, 127, 231, 150, 191, + 5, 248, 52, 211, 57, 229, 225, 248, 173, 247, 113, 205, 95, 231, 11, 242, + 98, 202, 35, 207, 89, 231, 45, 234, 69, 232, 244, 222, 240, 208, 127, + 209, 177, 199, 75, 197, 84, 209, 237, 236, 224, 236, 178, 55, 229, 206, + 242, 71, 252, 73, 232, 246, 233, 204, 198, 58, 248, 33, 217, 124, 218, + 217, 218, 250, 248, 80, 201, 205, 79, 198, 227, 249, 114, 79, 192, 100, + 205, 189, 209, 141, 199, 124, 249, 11, 248, 22, 249, 71, 206, 142, 79, + 210, 137, 249, 90, 79, 202, 38, 201, 206, 207, 105, 214, 198, 251, 136, + 214, 84, 243, 107, 221, 140, 214, 84, 243, 107, 208, 16, 214, 84, 243, + 107, 206, 132, 214, 84, 243, 107, 248, 154, 214, 84, 243, 107, 221, 78, + 214, 84, 243, 107, 210, 76, 63, 243, 107, 221, 79, 206, 123, 232, 136, + 237, 126, 62, 243, 107, 221, 79, 206, 123, 232, 136, 237, 126, 214, 84, + 243, 107, 221, 79, 206, 123, 232, 136, 237, 126, 63, 243, 107, 221, 141, + 206, 123, 213, 172, 237, 126, 63, 243, 107, 208, 17, 206, 123, 213, 172, + 237, 126, 63, 243, 107, 206, 133, 206, 123, 213, 172, 237, 126, 63, 243, + 107, 248, 155, 206, 123, 213, 172, 237, 126, 63, 243, 107, 221, 79, 206, + 123, 213, 172, 237, 126, 63, 243, 107, 210, 77, 206, 123, 213, 172, 237, + 126, 62, 243, 107, 221, 141, 206, 123, 213, 172, 237, 126, 62, 243, 107, + 208, 17, 206, 123, 213, 172, 237, 126, 62, 243, 107, 206, 133, 206, 123, + 213, 172, 237, 126, 62, 243, 107, 248, 155, 206, 123, 213, 172, 237, 126, + 62, 243, 107, 221, 79, 206, 123, 213, 172, 237, 126, 62, 243, 107, 210, + 77, 206, 123, 213, 172, 237, 126, 214, 84, 243, 107, 221, 141, 206, 123, + 213, 172, 237, 126, 214, 84, 243, 107, 208, 17, 206, 123, 213, 172, 237, + 126, 214, 84, 243, 107, 206, 133, 206, 123, 213, 172, 237, 126, 214, 84, + 243, 107, 248, 155, 206, 123, 213, 172, 237, 126, 214, 84, 243, 107, 221, + 79, 206, 123, 213, 172, 237, 126, 214, 84, 243, 107, 210, 77, 206, 123, + 213, 172, 237, 126, 63, 243, 107, 221, 79, 206, 123, 91, 228, 143, 198, + 248, 237, 126, 62, 243, 107, 221, 79, 206, 123, 91, 228, 143, 198, 248, + 237, 126, 214, 84, 243, 107, 221, 79, 206, 123, 91, 228, 143, 198, 248, + 237, 126, 63, 243, 107, 154, 221, 140, 63, 243, 107, 154, 208, 16, 63, + 243, 107, 154, 206, 132, 63, 243, 107, 154, 248, 154, 63, 243, 107, 154, + 221, 78, 63, 243, 107, 154, 210, 76, 62, 243, 107, 154, 221, 140, 62, + 243, 107, 154, 208, 16, 62, 243, 107, 154, 206, 132, 62, 243, 107, 154, + 248, 154, 62, 243, 107, 154, 221, 78, 62, 243, 107, 154, 210, 76, 214, + 84, 243, 107, 154, 221, 140, 214, 84, 243, 107, 154, 208, 16, 214, 84, + 243, 107, 154, 206, 132, 214, 84, 243, 107, 154, 248, 154, 214, 84, 243, + 107, 154, 221, 78, 214, 84, 243, 107, 154, 210, 76, 63, 243, 107, 221, + 79, 206, 123, 105, 228, 143, 197, 29, 237, 126, 62, 243, 107, 221, 79, + 206, 123, 105, 228, 143, 197, 29, 237, 126, 214, 84, 243, 107, 221, 79, + 206, 123, 105, 228, 143, 197, 29, 237, 126, 63, 243, 107, 221, 141, 206, + 123, 105, 228, 143, 203, 243, 237, 126, 63, 243, 107, 208, 17, 206, 123, + 105, 228, 143, 203, 243, 237, 126, 63, 243, 107, 206, 133, 206, 123, 105, + 228, 143, 203, 243, 237, 126, 63, 243, 107, 248, 155, 206, 123, 105, 228, + 143, 203, 243, 237, 126, 63, 243, 107, 221, 79, 206, 123, 105, 228, 143, + 203, 243, 237, 126, 63, 243, 107, 210, 77, 206, 123, 105, 228, 143, 203, + 243, 237, 126, 62, 243, 107, 221, 141, 206, 123, 105, 228, 143, 203, 243, + 237, 126, 62, 243, 107, 208, 17, 206, 123, 105, 228, 143, 203, 243, 237, + 126, 62, 243, 107, 206, 133, 206, 123, 105, 228, 143, 203, 243, 237, 126, + 62, 243, 107, 248, 155, 206, 123, 105, 228, 143, 203, 243, 237, 126, 62, + 243, 107, 221, 79, 206, 123, 105, 228, 143, 203, 243, 237, 126, 62, 243, + 107, 210, 77, 206, 123, 105, 228, 143, 203, 243, 237, 126, 214, 84, 243, + 107, 221, 141, 206, 123, 105, 228, 143, 203, 243, 237, 126, 214, 84, 243, + 107, 208, 17, 206, 123, 105, 228, 143, 203, 243, 237, 126, 214, 84, 243, + 107, 206, 133, 206, 123, 105, 228, 143, 203, 243, 237, 126, 214, 84, 243, + 107, 248, 155, 206, 123, 105, 228, 143, 203, 243, 237, 126, 214, 84, 243, + 107, 221, 79, 206, 123, 105, 228, 143, 203, 243, 237, 126, 214, 84, 243, + 107, 210, 77, 206, 123, 105, 228, 143, 203, 243, 237, 126, 63, 243, 107, + 221, 79, 206, 123, 115, 228, 143, 233, 22, 237, 126, 62, 243, 107, 221, + 79, 206, 123, 115, 228, 143, 233, 22, 237, 126, 214, 84, 243, 107, 221, + 79, 206, 123, 115, 228, 143, 233, 22, 237, 126, 63, 243, 107, 234, 40, + 62, 243, 107, 234, 40, 214, 84, 243, 107, 234, 40, 63, 243, 107, 234, 41, + 206, 123, 213, 172, 237, 126, 62, 243, 107, 234, 41, 206, 123, 213, 172, + 237, 126, 214, 84, 243, 107, 234, 41, 206, 123, 213, 172, 237, 126, 63, + 243, 107, 221, 76, 63, 243, 107, 221, 75, 63, 243, 107, 221, 77, 62, 243, + 107, 221, 76, 62, 243, 107, 221, 75, 62, 243, 107, 221, 77, 192, 205, + 207, 89, 231, 152, 192, 205, 207, 89, 217, 86, 192, 205, 207, 89, 234, + 133, 192, 205, 207, 89, 228, 185, 192, 205, 207, 89, 243, 140, 192, 205, + 207, 89, 247, 116, 192, 205, 207, 89, 202, 27, 192, 205, 62, 231, 152, + 192, 205, 62, 217, 86, 192, 205, 62, 234, 133, 192, 205, 62, 228, 185, + 192, 205, 62, 243, 140, 192, 205, 62, 247, 116, 192, 205, 62, 202, 27, + 249, 112, 203, 52, 211, 100, 200, 135, 248, 29, 203, 26, 198, 237, 205, + 140, 156, 248, 117, 229, 225, 230, 200, 229, 225, 209, 133, 229, 225, + 235, 101, 79, 248, 122, 252, 37, 249, 98, 201, 77, 192, 234, 238, 203, + 191, 253, 221, 121, 210, 131, 248, 94, 217, 125, 193, 162, 209, 139, 214, + 89, 236, 156, 217, 66, 232, 184, 206, 188, 209, 102, 246, 254, 207, 120, + 250, 134, 236, 198, 220, 27, 249, 96, 216, 56, 229, 202, 252, 58, 180, + 235, 96, 242, 90, 247, 91, 205, 109, 205, 76, 220, 111, 102, 216, 28, + 193, 65, 209, 85, 203, 240, 214, 111, 221, 73, 248, 8, 215, 184, 198, 6, + 198, 55, 229, 230, 209, 111, 206, 148, 216, 29, 249, 113, 228, 18, 247, + 102, 130, 249, 60, 230, 62, 232, 172, 230, 56, 233, 82, 230, 81, 209, + 182, 221, 205, 232, 181, 193, 17, 248, 253, 242, 97, 209, 13, 209, 101, + 193, 28, 233, 56, 218, 248, 239, 6, 234, 107, 214, 91, 214, 92, 4, 234, + 180, 228, 94, 223, 4, 193, 61, 230, 245, 251, 131, 229, 225, 218, 207, + 210, 22, 228, 151, 208, 228, 217, 92, 208, 228, 209, 252, 209, 253, 4, + 238, 210, 215, 206, 236, 149, 248, 115, 248, 238, 210, 17, 211, 117, 232, + 207, 199, 196, 232, 167, 199, 132, 209, 9, 219, 94, 249, 13, 223, 20, + 231, 38, 206, 129, 210, 64, 209, 72, 216, 197, 233, 105, 205, 154, 233, + 105, 233, 106, 4, 211, 79, 233, 188, 23, 230, 56, 139, 215, 181, 233, + 106, 4, 210, 49, 233, 195, 233, 106, 4, 237, 41, 215, 181, 235, 140, 219, + 115, 233, 105, 248, 147, 219, 100, 248, 9, 203, 146, 233, 105, 230, 56, + 4, 141, 232, 255, 23, 176, 238, 215, 96, 230, 55, 118, 230, 55, 210, 185, + 144, 230, 55, 210, 185, 133, 230, 55, 141, 209, 60, 250, 185, 199, 34, + 195, 55, 229, 226, 230, 30, 118, 208, 137, 230, 55, 96, 208, 137, 230, + 55, 184, 203, 237, 184, 203, 207, 184, 203, 236, 184, 203, 192, 184, 203, + 221, 184, 203, 206, 184, 203, 235, 184, 203, 184, 184, 203, 214, 184, + 203, 198, 184, 203, 228, 184, 203, 191, 184, 203, 220, 184, 203, 205, + 184, 203, 234, 184, 203, 180, 184, 203, 210, 184, 203, 195, 184, 203, + 224, 184, 203, 187, 184, 203, 201, 184, 203, 231, 184, 203, 183, 184, + 203, 213, 184, 203, 197, 184, 203, 227, 184, 203, 190, 184, 203, 219, + 184, 203, 204, 184, 203, 233, 184, 203, 178, 184, 203, 208, 184, 203, + 193, 184, 203, 222, 184, 203, 185, 184, 203, 215, 184, 203, 199, 184, + 203, 229, 184, 203, 181, 184, 203, 211, 184, 203, 225, 184, 203, 188, + 184, 203, 217, 184, 203, 202, 184, 203, 232, 184, 203, 179, 184, 203, + 209, 184, 203, 194, 184, 203, 223, 184, 203, 186, 184, 203, 216, 184, 203, 200, 184, 203, 230, 184, 203, 182, 184, 203, 212, 184, 203, 196, - 184, 203, 226, 184, 203, 189, 184, 203, 218, 184, 203, 203, 184, 203, - 232, 184, 203, 177, 184, 203, 207, 184, 203, 192, 184, 203, 221, 184, - 203, 184, 184, 203, 214, 184, 203, 198, 184, 203, 228, 184, 203, 180, - 184, 203, 210, 184, 203, 224, 184, 203, 187, 184, 203, 216, 184, 203, - 201, 184, 203, 231, 184, 203, 178, 184, 203, 208, 184, 203, 193, 184, - 203, 222, 184, 203, 185, 184, 203, 215, 184, 203, 199, 184, 203, 229, - 184, 203, 181, 184, 203, 211, 184, 203, 195, 184, 203, 225, 184, 203, - 188, 184, 203, 217, 184, 203, 202, 110, 45, 184, 237, 39, 110, 82, 45, - 119, 110, 247, 21, 110, 45, 184, 237, 39, 110, 82, 45, 119, 110, 183, - 110, 45, 184, 237, 39, 116, 82, 45, 119, 110, 247, 21, 110, 45, 184, 237, - 39, 116, 82, 45, 119, 110, 183, 110, 45, 184, 237, 39, 116, 45, 119, 110, - 247, 21, 110, 50, 184, 237, 39, 116, 82, 45, 119, 116, 247, 21, 110, 50, - 184, 237, 39, 116, 82, 45, 119, 116, 183, 110, 50, 184, 237, 39, 110, 82, - 45, 119, 116, 247, 21, 110, 50, 184, 237, 39, 110, 82, 45, 119, 116, 183, - 110, 50, 184, 237, 39, 110, 45, 119, 116, 247, 21, 110, 50, 184, 237, 39, - 110, 82, 45, 119, 116, 82, 183, 110, 50, 184, 237, 39, 110, 247, 22, 119, - 110, 82, 183, 110, 50, 184, 237, 39, 110, 45, 119, 110, 82, 183, 110, 50, - 184, 237, 39, 110, 247, 22, 119, 116, 82, 183, 110, 50, 184, 237, 39, - 110, 45, 119, 116, 82, 183, 110, 50, 184, 237, 39, 110, 247, 22, 119, - 116, 183, 110, 45, 184, 237, 39, 116, 247, 22, 119, 116, 82, 183, 110, - 45, 184, 237, 39, 116, 45, 119, 116, 82, 183, 110, 45, 184, 237, 39, 116, - 247, 22, 119, 110, 82, 183, 110, 45, 184, 237, 39, 116, 45, 119, 110, 82, - 183, 110, 45, 184, 237, 39, 116, 247, 22, 119, 110, 183, 110, 45, 184, - 237, 39, 116, 82, 45, 119, 110, 82, 183, 116, 50, 184, 237, 39, 110, 82, - 45, 119, 110, 247, 21, 116, 50, 184, 237, 39, 110, 82, 45, 119, 110, 183, - 116, 50, 184, 237, 39, 116, 82, 45, 119, 110, 247, 21, 116, 50, 184, 237, - 39, 116, 82, 45, 119, 110, 183, 116, 50, 184, 237, 39, 116, 45, 119, 110, - 247, 21, 116, 45, 184, 237, 39, 116, 82, 45, 119, 116, 247, 21, 116, 45, - 184, 237, 39, 116, 82, 45, 119, 116, 183, 116, 45, 184, 237, 39, 110, 82, - 45, 119, 116, 247, 21, 116, 45, 184, 237, 39, 110, 82, 45, 119, 116, 183, - 116, 45, 184, 237, 39, 110, 45, 119, 116, 247, 21, 116, 45, 184, 237, 39, - 110, 82, 45, 119, 116, 82, 183, 116, 45, 184, 237, 39, 110, 247, 22, 119, - 110, 82, 183, 116, 45, 184, 237, 39, 110, 45, 119, 110, 82, 183, 116, 45, - 184, 237, 39, 110, 247, 22, 119, 116, 82, 183, 116, 45, 184, 237, 39, - 110, 45, 119, 116, 82, 183, 116, 45, 184, 237, 39, 110, 247, 22, 119, - 116, 183, 116, 50, 184, 237, 39, 116, 247, 22, 119, 116, 82, 183, 116, - 50, 184, 237, 39, 116, 45, 119, 116, 82, 183, 116, 50, 184, 237, 39, 116, - 247, 22, 119, 110, 82, 183, 116, 50, 184, 237, 39, 116, 45, 119, 110, 82, - 183, 116, 50, 184, 237, 39, 116, 247, 22, 119, 110, 183, 116, 50, 184, - 237, 39, 116, 82, 45, 119, 110, 82, 183, 116, 23, 50, 23, 110, 197, 238, - 115, 208, 21, 248, 129, 45, 23, 110, 23, 50, 197, 238, 115, 208, 21, 248, - 129, 116, 23, 45, 23, 110, 197, 238, 115, 208, 21, 248, 129, 45, 23, 116, - 23, 50, 197, 238, 115, 208, 21, 248, 129, 45, 197, 238, 91, 208, 23, 248, - 129, 116, 197, 238, 91, 208, 23, 248, 129, 50, 197, 238, 91, 208, 23, - 248, 129, 110, 197, 238, 91, 208, 23, 248, 129, 81, 91, 234, 160, 248, - 127, 81, 91, 234, 160, 248, 126, 81, 91, 234, 160, 248, 125, 81, 91, 234, - 160, 248, 124, 81, 91, 234, 160, 248, 123, 81, 91, 234, 160, 248, 122, - 228, 241, 91, 234, 160, 248, 127, 228, 241, 91, 234, 160, 248, 126, 228, - 241, 91, 234, 160, 248, 125, 228, 241, 91, 234, 160, 248, 124, 228, 241, - 91, 234, 160, 248, 123, 228, 241, 91, 234, 160, 248, 122, 45, 23, 110, - 91, 234, 160, 248, 129, 45, 23, 116, 91, 234, 160, 248, 129, 50, 23, 116, - 91, 234, 160, 248, 129, 50, 23, 110, 91, 234, 160, 248, 129, 116, 23, - 110, 91, 234, 160, 248, 129, 228, 241, 91, 234, 160, 248, 128, 116, 91, - 208, 23, 248, 129, 116, 115, 234, 158, 248, 129, 116, 232, 226, 234, 158, - 248, 129, 116, 115, 208, 21, 248, 129, 116, 203, 247, 234, 158, 248, 129, - 50, 91, 208, 23, 248, 129, 50, 115, 234, 158, 248, 129, 50, 232, 226, - 234, 158, 248, 129, 50, 115, 208, 21, 248, 129, 50, 203, 247, 234, 158, - 248, 129, 45, 132, 216, 213, 203, 153, 50, 132, 216, 213, 203, 153, 116, - 132, 216, 213, 203, 153, 110, 132, 216, 213, 203, 153, 223, 95, 216, 213, - 203, 153, 116, 132, 184, 23, 110, 132, 223, 95, 216, 213, 203, 153, 116, - 132, 223, 95, 216, 213, 203, 154, 23, 110, 132, 248, 129, 45, 132, 223, - 95, 216, 213, 203, 154, 23, 50, 132, 248, 129, 243, 124, 248, 108, 233, - 5, 223, 95, 243, 124, 248, 108, 233, 5, 88, 228, 241, 233, 5, 116, 45, - 119, 110, 50, 233, 5, 116, 50, 119, 110, 45, 233, 5, 116, 23, 110, 197, - 238, 132, 248, 129, 45, 23, 50, 197, 238, 132, 248, 129, 116, 45, 197, - 238, 216, 213, 203, 153, 116, 50, 197, 238, 216, 213, 203, 153, 110, 50, - 197, 238, 216, 213, 203, 153, 110, 45, 197, 238, 216, 213, 203, 153, 111, - 122, 156, 237, 39, 116, 247, 22, 119, 82, 219, 224, 111, 122, 156, 237, - 39, 116, 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, 82, 45, 119, 110, - 247, 21, 111, 122, 156, 237, 39, 82, 50, 119, 110, 247, 21, 111, 122, - 156, 237, 39, 116, 247, 22, 119, 82, 45, 119, 110, 247, 21, 111, 122, - 156, 237, 39, 116, 247, 22, 119, 82, 50, 119, 110, 247, 21, 111, 122, - 156, 237, 39, 82, 45, 119, 110, 247, 22, 119, 82, 183, 111, 122, 156, - 237, 39, 82, 45, 119, 116, 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, - 116, 247, 22, 119, 82, 45, 23, 82, 50, 119, 110, 247, 21, 111, 122, 156, - 237, 39, 116, 247, 22, 119, 82, 50, 23, 82, 45, 119, 110, 247, 21, 111, - 122, 156, 237, 39, 116, 247, 22, 119, 82, 50, 119, 110, 247, 22, 119, 82, - 219, 224, 111, 122, 156, 237, 39, 116, 247, 22, 119, 82, 45, 119, 110, - 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, 82, 45, 119, 116, 247, 22, - 119, 82, 50, 119, 110, 247, 21, 111, 122, 156, 237, 39, 82, 50, 119, 116, - 247, 22, 119, 82, 45, 119, 110, 247, 21, 111, 122, 156, 237, 39, 237, 32, - 111, 122, 156, 228, 241, 4, 81, 106, 250, 234, 209, 59, 223, 95, 243, - 126, 77, 45, 132, 206, 42, 217, 90, 50, 132, 206, 42, 217, 90, 223, 95, - 235, 119, 64, 4, 198, 136, 219, 214, 118, 64, 23, 116, 23, 110, 91, 234, - 160, 248, 129, 96, 64, 23, 116, 23, 110, 91, 234, 160, 248, 129, 235, - 119, 64, 23, 50, 91, 234, 160, 248, 129, 196, 66, 64, 23, 50, 91, 234, - 160, 248, 129, 45, 132, 232, 171, 50, 132, 232, 171, 195, 16, 35, 238, - 217, 50, 211, 77, 112, 236, 140, 214, 106, 237, 39, 238, 217, 214, 106, - 237, 39, 82, 50, 119, 110, 247, 21, 214, 106, 237, 39, 237, 32, 63, 88, - 205, 155, 4, 206, 113, 239, 0, 45, 199, 1, 63, 50, 209, 58, 223, 148, 82, - 199, 1, 63, 50, 209, 58, 223, 148, 50, 199, 1, 63, 50, 209, 58, 223, 148, - 214, 106, 112, 208, 13, 77, 201, 75, 233, 12, 201, 75, 233, 13, 4, 250, - 247, 207, 146, 201, 75, 233, 13, 219, 231, 219, 224, 201, 75, 233, 13, - 219, 231, 183, 201, 75, 233, 13, 4, 235, 106, 63, 196, 76, 243, 100, 205, - 42, 17, 191, 77, 205, 42, 17, 107, 205, 42, 17, 109, 205, 42, 17, 138, - 205, 42, 17, 134, 205, 42, 17, 149, 205, 42, 17, 169, 205, 42, 17, 175, - 205, 42, 17, 171, 205, 42, 17, 178, 12, 15, 228, 13, 12, 15, 228, 12, 12, - 15, 228, 11, 12, 15, 228, 10, 12, 15, 228, 9, 12, 15, 228, 8, 12, 15, - 228, 7, 12, 15, 228, 6, 12, 15, 228, 5, 12, 15, 228, 4, 12, 15, 228, 3, - 12, 15, 228, 2, 12, 15, 228, 1, 12, 15, 228, 0, 12, 15, 227, 255, 12, 15, - 227, 254, 12, 15, 227, 253, 12, 15, 227, 252, 12, 15, 227, 251, 12, 15, - 227, 250, 12, 15, 227, 249, 12, 15, 227, 248, 12, 15, 227, 247, 12, 15, - 227, 246, 12, 15, 227, 245, 12, 15, 227, 244, 12, 15, 227, 243, 12, 15, - 227, 242, 12, 15, 227, 241, 12, 15, 227, 240, 12, 15, 227, 239, 12, 15, - 227, 238, 12, 15, 227, 237, 12, 15, 227, 236, 12, 15, 227, 235, 12, 15, - 227, 234, 12, 15, 227, 233, 12, 15, 227, 232, 12, 15, 227, 231, 12, 15, - 227, 230, 12, 15, 227, 229, 12, 15, 227, 228, 12, 15, 227, 227, 12, 15, - 227, 226, 12, 15, 227, 225, 12, 15, 227, 224, 12, 15, 227, 223, 12, 15, - 227, 222, 12, 15, 227, 221, 12, 15, 227, 220, 12, 15, 227, 219, 12, 15, - 227, 218, 12, 15, 227, 217, 12, 15, 227, 216, 12, 15, 227, 215, 12, 15, - 227, 214, 12, 15, 227, 213, 12, 15, 227, 212, 12, 15, 227, 211, 12, 15, - 227, 210, 12, 15, 227, 209, 12, 15, 227, 208, 12, 15, 227, 207, 12, 15, - 227, 206, 12, 15, 227, 205, 12, 15, 227, 204, 12, 15, 227, 203, 12, 15, - 227, 202, 12, 15, 227, 201, 12, 15, 227, 200, 12, 15, 227, 199, 12, 15, - 227, 198, 12, 15, 227, 197, 12, 15, 227, 196, 12, 15, 227, 195, 12, 15, - 227, 194, 12, 15, 227, 193, 12, 15, 227, 192, 12, 15, 227, 191, 12, 15, - 227, 190, 12, 15, 227, 189, 12, 15, 227, 188, 12, 15, 227, 187, 12, 15, - 227, 186, 12, 15, 227, 185, 12, 15, 227, 184, 12, 15, 227, 183, 12, 15, - 227, 182, 12, 15, 227, 181, 12, 15, 227, 180, 12, 15, 227, 179, 12, 15, - 227, 178, 12, 15, 227, 177, 12, 15, 227, 176, 12, 15, 227, 175, 12, 15, - 227, 174, 12, 15, 227, 173, 12, 15, 227, 172, 12, 15, 227, 171, 12, 15, - 227, 170, 12, 15, 227, 169, 12, 15, 227, 168, 12, 15, 227, 167, 12, 15, - 227, 166, 12, 15, 227, 165, 12, 15, 227, 164, 12, 15, 227, 163, 12, 15, - 227, 162, 12, 15, 227, 161, 12, 15, 227, 160, 12, 15, 227, 159, 12, 15, - 227, 158, 12, 15, 227, 157, 12, 15, 227, 156, 12, 15, 227, 155, 12, 15, - 227, 154, 12, 15, 227, 153, 12, 15, 227, 152, 12, 15, 227, 151, 12, 15, - 227, 150, 12, 15, 227, 149, 12, 15, 227, 148, 12, 15, 227, 147, 12, 15, - 227, 146, 12, 15, 227, 145, 12, 15, 227, 144, 12, 15, 227, 143, 12, 15, - 227, 142, 12, 15, 227, 141, 12, 15, 227, 140, 12, 15, 227, 139, 12, 15, - 227, 138, 12, 15, 227, 137, 12, 15, 227, 136, 12, 15, 227, 135, 12, 15, - 227, 134, 12, 15, 227, 133, 12, 15, 227, 132, 12, 15, 227, 131, 12, 15, - 227, 130, 12, 15, 227, 129, 12, 15, 227, 128, 12, 15, 227, 127, 12, 15, - 227, 126, 12, 15, 227, 125, 12, 15, 227, 124, 12, 15, 227, 123, 12, 15, - 227, 122, 12, 15, 227, 121, 12, 15, 227, 120, 12, 15, 227, 119, 12, 15, - 227, 118, 12, 15, 227, 117, 12, 15, 227, 116, 12, 15, 227, 115, 12, 15, - 227, 114, 12, 15, 227, 113, 12, 15, 227, 112, 12, 15, 227, 111, 12, 15, - 227, 110, 12, 15, 227, 109, 12, 15, 227, 108, 12, 15, 227, 107, 12, 15, - 227, 106, 12, 15, 227, 105, 12, 15, 227, 104, 12, 15, 227, 103, 12, 15, - 227, 102, 12, 15, 227, 101, 12, 15, 227, 100, 12, 15, 227, 99, 12, 15, - 227, 98, 12, 15, 227, 97, 12, 15, 227, 96, 12, 15, 227, 95, 12, 15, 227, - 94, 12, 15, 227, 93, 12, 15, 227, 92, 12, 15, 227, 91, 12, 15, 227, 90, - 12, 15, 227, 89, 12, 15, 227, 88, 12, 15, 227, 87, 12, 15, 227, 86, 12, - 15, 227, 85, 12, 15, 227, 84, 12, 15, 227, 83, 12, 15, 227, 82, 12, 15, - 227, 81, 12, 15, 227, 80, 12, 15, 227, 79, 12, 15, 227, 78, 12, 15, 227, - 77, 12, 15, 227, 76, 12, 15, 227, 75, 12, 15, 227, 74, 12, 15, 227, 73, - 12, 15, 227, 72, 12, 15, 227, 71, 12, 15, 227, 70, 12, 15, 227, 69, 12, - 15, 227, 68, 12, 15, 227, 67, 12, 15, 227, 66, 12, 15, 227, 65, 12, 15, - 227, 64, 12, 15, 227, 63, 12, 15, 227, 62, 12, 15, 227, 61, 12, 15, 227, - 60, 12, 15, 227, 59, 12, 15, 227, 58, 12, 15, 227, 57, 12, 15, 227, 56, - 12, 15, 227, 55, 12, 15, 227, 54, 12, 15, 227, 53, 12, 15, 227, 52, 12, - 15, 227, 51, 12, 15, 227, 50, 12, 15, 227, 49, 12, 15, 227, 48, 12, 15, - 227, 47, 12, 15, 227, 46, 12, 15, 227, 45, 12, 15, 227, 44, 12, 15, 227, - 43, 12, 15, 227, 42, 12, 15, 227, 41, 12, 15, 227, 40, 12, 15, 227, 39, - 12, 15, 227, 38, 12, 15, 227, 37, 12, 15, 227, 36, 12, 15, 227, 35, 12, - 15, 227, 34, 12, 15, 227, 33, 12, 15, 227, 32, 12, 15, 227, 31, 12, 15, - 227, 30, 12, 15, 227, 29, 12, 15, 227, 28, 12, 15, 227, 27, 12, 15, 227, - 26, 12, 15, 227, 25, 12, 15, 227, 24, 12, 15, 227, 23, 12, 15, 227, 22, - 12, 15, 227, 21, 12, 15, 227, 20, 12, 15, 227, 19, 12, 15, 227, 18, 12, - 15, 227, 17, 12, 15, 227, 16, 12, 15, 227, 15, 12, 15, 227, 14, 12, 15, - 227, 13, 12, 15, 227, 12, 12, 15, 227, 11, 12, 15, 227, 10, 12, 15, 227, - 9, 12, 15, 227, 8, 12, 15, 227, 7, 12, 15, 227, 6, 12, 15, 227, 5, 12, - 15, 227, 4, 12, 15, 227, 3, 12, 15, 227, 2, 12, 15, 227, 1, 12, 15, 227, - 0, 12, 15, 226, 255, 12, 15, 226, 254, 12, 15, 226, 253, 12, 15, 226, - 252, 12, 15, 226, 251, 12, 15, 226, 250, 12, 15, 226, 249, 12, 15, 226, - 248, 12, 15, 226, 247, 12, 15, 226, 246, 12, 15, 226, 245, 12, 15, 226, - 244, 12, 15, 226, 243, 12, 15, 226, 242, 12, 15, 226, 241, 12, 15, 226, - 240, 12, 15, 226, 239, 12, 15, 226, 238, 12, 15, 226, 237, 12, 15, 226, - 236, 12, 15, 226, 235, 12, 15, 226, 234, 12, 15, 226, 233, 12, 15, 226, - 232, 12, 15, 226, 231, 12, 15, 226, 230, 12, 15, 226, 229, 12, 15, 226, - 228, 12, 15, 226, 227, 12, 15, 226, 226, 12, 15, 226, 225, 12, 15, 226, - 224, 12, 15, 226, 223, 12, 15, 226, 222, 12, 15, 226, 221, 12, 15, 226, - 220, 12, 15, 226, 219, 12, 15, 226, 218, 12, 15, 226, 217, 12, 15, 226, - 216, 12, 15, 226, 215, 12, 15, 226, 214, 12, 15, 226, 213, 12, 15, 226, - 212, 12, 15, 226, 211, 12, 15, 226, 210, 12, 15, 226, 209, 12, 15, 226, - 208, 12, 15, 226, 207, 12, 15, 226, 206, 12, 15, 226, 205, 12, 15, 226, - 204, 12, 15, 226, 203, 12, 15, 226, 202, 12, 15, 226, 201, 12, 15, 226, - 200, 12, 15, 226, 199, 12, 15, 226, 198, 12, 15, 226, 197, 12, 15, 226, - 196, 12, 15, 226, 195, 12, 15, 226, 194, 12, 15, 226, 193, 12, 15, 226, - 192, 12, 15, 226, 191, 12, 15, 226, 190, 12, 15, 226, 189, 12, 15, 226, - 188, 12, 15, 226, 187, 12, 15, 226, 186, 12, 15, 226, 185, 12, 15, 226, - 184, 12, 15, 226, 183, 12, 15, 226, 182, 12, 15, 226, 181, 12, 15, 226, - 180, 12, 15, 226, 179, 12, 15, 226, 178, 12, 15, 226, 177, 12, 15, 226, - 176, 12, 15, 226, 175, 12, 15, 226, 174, 12, 15, 226, 173, 12, 15, 226, - 172, 12, 15, 226, 171, 12, 15, 226, 170, 12, 15, 226, 169, 12, 15, 226, - 168, 12, 15, 226, 167, 12, 15, 226, 166, 12, 15, 226, 165, 12, 15, 226, - 164, 12, 15, 226, 163, 12, 15, 226, 162, 12, 15, 226, 161, 12, 15, 226, - 160, 12, 15, 226, 159, 12, 15, 226, 158, 12, 15, 226, 157, 12, 15, 226, - 156, 12, 15, 226, 155, 12, 15, 226, 154, 12, 15, 226, 153, 12, 15, 226, - 152, 12, 15, 226, 151, 12, 15, 226, 150, 12, 15, 226, 149, 12, 15, 226, - 148, 12, 15, 226, 147, 12, 15, 226, 146, 12, 15, 226, 145, 12, 15, 226, - 144, 12, 15, 226, 143, 12, 15, 226, 142, 12, 15, 226, 141, 12, 15, 226, - 140, 12, 15, 226, 139, 12, 15, 226, 138, 12, 15, 226, 137, 12, 15, 226, - 136, 12, 15, 226, 135, 12, 15, 226, 134, 12, 15, 226, 133, 12, 15, 226, - 132, 12, 15, 226, 131, 12, 15, 226, 130, 12, 15, 226, 129, 12, 15, 226, - 128, 12, 15, 226, 127, 12, 15, 226, 126, 12, 15, 226, 125, 12, 15, 226, - 124, 12, 15, 226, 123, 12, 15, 226, 122, 12, 15, 226, 121, 12, 15, 226, - 120, 12, 15, 226, 119, 12, 15, 226, 118, 12, 15, 226, 117, 12, 15, 226, - 116, 12, 15, 226, 115, 12, 15, 226, 114, 12, 15, 226, 113, 12, 15, 226, - 112, 12, 15, 226, 111, 12, 15, 226, 110, 12, 15, 226, 109, 12, 15, 226, - 108, 12, 15, 226, 107, 12, 15, 226, 106, 12, 15, 226, 105, 12, 15, 226, - 104, 12, 15, 226, 103, 12, 15, 226, 102, 12, 15, 226, 101, 12, 15, 226, - 100, 12, 15, 226, 99, 12, 15, 226, 98, 12, 15, 226, 97, 12, 15, 226, 96, - 12, 15, 226, 95, 12, 15, 226, 94, 12, 15, 226, 93, 12, 15, 226, 92, 12, - 15, 226, 91, 12, 15, 226, 90, 12, 15, 226, 89, 12, 15, 226, 88, 12, 15, - 226, 87, 12, 15, 226, 86, 12, 15, 226, 85, 12, 15, 226, 84, 12, 15, 226, - 83, 12, 15, 226, 82, 12, 15, 226, 81, 12, 15, 226, 80, 12, 15, 226, 79, - 12, 15, 226, 78, 12, 15, 226, 77, 12, 15, 226, 76, 12, 15, 226, 75, 12, - 15, 226, 74, 12, 15, 226, 73, 12, 15, 226, 72, 12, 15, 226, 71, 12, 15, - 226, 70, 12, 15, 226, 69, 12, 15, 226, 68, 12, 15, 226, 67, 12, 15, 226, - 66, 12, 15, 226, 65, 12, 15, 226, 64, 12, 15, 226, 63, 12, 15, 226, 62, - 12, 15, 226, 61, 12, 15, 226, 60, 12, 15, 226, 59, 12, 15, 226, 58, 12, - 15, 226, 57, 12, 15, 226, 56, 12, 15, 226, 55, 12, 15, 226, 54, 12, 15, - 226, 53, 12, 15, 226, 52, 12, 15, 226, 51, 12, 15, 226, 50, 12, 15, 226, - 49, 12, 15, 226, 48, 12, 15, 226, 47, 12, 15, 226, 46, 12, 15, 226, 45, - 12, 15, 226, 44, 12, 15, 226, 43, 12, 15, 226, 42, 12, 15, 226, 41, 12, - 15, 226, 40, 12, 15, 226, 39, 12, 15, 226, 38, 12, 15, 226, 37, 12, 15, - 226, 36, 12, 15, 226, 35, 12, 15, 226, 34, 12, 15, 226, 33, 12, 15, 226, - 32, 12, 15, 226, 31, 12, 15, 226, 30, 12, 15, 226, 29, 12, 15, 226, 28, - 12, 15, 226, 27, 12, 15, 226, 26, 12, 15, 226, 25, 12, 15, 226, 24, 12, - 15, 226, 23, 12, 15, 226, 22, 12, 15, 226, 21, 12, 15, 226, 20, 12, 15, - 226, 19, 12, 15, 226, 18, 12, 15, 226, 17, 12, 15, 226, 16, 12, 15, 226, - 15, 12, 15, 226, 14, 12, 15, 226, 13, 12, 15, 226, 12, 12, 15, 226, 11, - 12, 15, 226, 10, 12, 15, 226, 9, 12, 15, 226, 8, 12, 15, 226, 7, 12, 15, - 226, 6, 12, 15, 226, 5, 12, 15, 226, 4, 12, 15, 226, 3, 12, 15, 226, 2, - 12, 15, 226, 1, 12, 15, 226, 0, 12, 15, 225, 255, 12, 15, 225, 254, 12, - 15, 225, 253, 12, 15, 225, 252, 12, 15, 225, 251, 12, 15, 225, 250, 12, - 15, 225, 249, 12, 15, 225, 248, 12, 15, 225, 247, 12, 15, 225, 246, 12, - 15, 225, 245, 12, 15, 225, 244, 12, 15, 225, 243, 12, 15, 225, 242, 12, - 15, 225, 241, 12, 15, 225, 240, 220, 20, 199, 223, 199, 224, 201, 247, - 199, 224, 233, 216, 77, 199, 224, 207, 252, 77, 199, 224, 31, 56, 199, - 224, 236, 155, 56, 199, 224, 210, 13, 56, 199, 224, 251, 137, 199, 224, - 251, 49, 199, 224, 45, 210, 113, 199, 224, 50, 210, 113, 199, 224, 250, - 193, 199, 224, 108, 56, 199, 224, 242, 74, 199, 224, 228, 87, 199, 224, - 232, 80, 201, 63, 199, 224, 202, 23, 199, 224, 17, 191, 77, 199, 224, 17, - 107, 199, 224, 17, 109, 199, 224, 17, 138, 199, 224, 17, 134, 199, 224, - 17, 149, 199, 224, 17, 169, 199, 224, 17, 175, 199, 224, 17, 171, 199, - 224, 17, 178, 199, 224, 242, 83, 199, 224, 204, 25, 199, 224, 219, 180, - 56, 199, 224, 234, 43, 56, 199, 224, 230, 204, 56, 199, 224, 208, 13, 77, - 199, 224, 242, 72, 250, 182, 199, 224, 8, 6, 1, 65, 199, 224, 8, 6, 1, - 250, 120, 199, 224, 8, 6, 1, 247, 193, 199, 224, 8, 6, 1, 238, 127, 199, - 224, 8, 6, 1, 71, 199, 224, 8, 6, 1, 233, 175, 199, 224, 8, 6, 1, 232, - 51, 199, 224, 8, 6, 1, 230, 116, 199, 224, 8, 6, 1, 68, 199, 224, 8, 6, - 1, 223, 35, 199, 224, 8, 6, 1, 222, 152, 199, 224, 8, 6, 1, 172, 199, - 224, 8, 6, 1, 218, 168, 199, 224, 8, 6, 1, 215, 61, 199, 224, 8, 6, 1, - 74, 199, 224, 8, 6, 1, 210, 236, 199, 224, 8, 6, 1, 208, 104, 199, 224, - 8, 6, 1, 146, 199, 224, 8, 6, 1, 206, 8, 199, 224, 8, 6, 1, 200, 43, 199, - 224, 8, 6, 1, 66, 199, 224, 8, 6, 1, 196, 12, 199, 224, 8, 6, 1, 193, - 224, 199, 224, 8, 6, 1, 192, 235, 199, 224, 8, 6, 1, 192, 159, 199, 224, - 8, 6, 1, 191, 166, 199, 224, 45, 51, 248, 53, 199, 224, 207, 19, 202, 23, - 199, 224, 50, 51, 248, 53, 199, 224, 243, 2, 252, 60, 199, 224, 130, 219, - 112, 199, 224, 230, 211, 252, 60, 199, 224, 8, 2, 1, 65, 199, 224, 8, 2, - 1, 250, 120, 199, 224, 8, 2, 1, 247, 193, 199, 224, 8, 2, 1, 238, 127, - 199, 224, 8, 2, 1, 71, 199, 224, 8, 2, 1, 233, 175, 199, 224, 8, 2, 1, - 232, 51, 199, 224, 8, 2, 1, 230, 116, 199, 224, 8, 2, 1, 68, 199, 224, 8, - 2, 1, 223, 35, 199, 224, 8, 2, 1, 222, 152, 199, 224, 8, 2, 1, 172, 199, - 224, 8, 2, 1, 218, 168, 199, 224, 8, 2, 1, 215, 61, 199, 224, 8, 2, 1, - 74, 199, 224, 8, 2, 1, 210, 236, 199, 224, 8, 2, 1, 208, 104, 199, 224, - 8, 2, 1, 146, 199, 224, 8, 2, 1, 206, 8, 199, 224, 8, 2, 1, 200, 43, 199, - 224, 8, 2, 1, 66, 199, 224, 8, 2, 1, 196, 12, 199, 224, 8, 2, 1, 193, - 224, 199, 224, 8, 2, 1, 192, 235, 199, 224, 8, 2, 1, 192, 159, 199, 224, - 8, 2, 1, 191, 166, 199, 224, 45, 238, 171, 248, 53, 199, 224, 81, 219, - 112, 199, 224, 50, 238, 171, 248, 53, 199, 224, 198, 152, 247, 127, 199, - 223, 67, 204, 211, 67, 204, 200, 67, 204, 189, 67, 204, 177, 67, 204, - 166, 67, 204, 155, 67, 204, 144, 67, 204, 133, 67, 204, 122, 67, 204, - 114, 67, 204, 113, 67, 204, 112, 67, 204, 111, 67, 204, 109, 67, 204, - 108, 67, 204, 107, 67, 204, 106, 67, 204, 105, 67, 204, 104, 67, 204, - 103, 67, 204, 102, 67, 204, 101, 67, 204, 100, 67, 204, 98, 67, 204, 97, - 67, 204, 96, 67, 204, 95, 67, 204, 94, 67, 204, 93, 67, 204, 92, 67, 204, - 91, 67, 204, 90, 67, 204, 89, 67, 204, 87, 67, 204, 86, 67, 204, 85, 67, - 204, 84, 67, 204, 83, 67, 204, 82, 67, 204, 81, 67, 204, 80, 67, 204, 79, - 67, 204, 78, 67, 204, 76, 67, 204, 75, 67, 204, 74, 67, 204, 73, 67, 204, - 72, 67, 204, 71, 67, 204, 70, 67, 204, 69, 67, 204, 68, 67, 204, 67, 67, - 204, 65, 67, 204, 64, 67, 204, 63, 67, 204, 62, 67, 204, 61, 67, 204, 60, - 67, 204, 59, 67, 204, 58, 67, 204, 57, 67, 204, 56, 67, 204, 54, 67, 204, - 53, 67, 204, 52, 67, 204, 51, 67, 204, 50, 67, 204, 49, 67, 204, 48, 67, - 204, 47, 67, 204, 46, 67, 204, 45, 67, 204, 43, 67, 204, 42, 67, 204, 41, - 67, 204, 40, 67, 204, 39, 67, 204, 38, 67, 204, 37, 67, 204, 36, 67, 204, - 35, 67, 204, 34, 67, 205, 31, 67, 205, 30, 67, 205, 29, 67, 205, 28, 67, - 205, 27, 67, 205, 26, 67, 205, 25, 67, 205, 24, 67, 205, 23, 67, 205, 22, - 67, 205, 20, 67, 205, 19, 67, 205, 18, 67, 205, 17, 67, 205, 16, 67, 205, - 15, 67, 205, 14, 67, 205, 13, 67, 205, 12, 67, 205, 11, 67, 205, 9, 67, - 205, 8, 67, 205, 7, 67, 205, 6, 67, 205, 5, 67, 205, 4, 67, 205, 3, 67, - 205, 2, 67, 205, 1, 67, 205, 0, 67, 204, 254, 67, 204, 253, 67, 204, 252, - 67, 204, 251, 67, 204, 250, 67, 204, 249, 67, 204, 248, 67, 204, 247, 67, - 204, 246, 67, 204, 245, 67, 204, 243, 67, 204, 242, 67, 204, 241, 67, - 204, 240, 67, 204, 239, 67, 204, 238, 67, 204, 237, 67, 204, 236, 67, - 204, 235, 67, 204, 234, 67, 204, 232, 67, 204, 231, 67, 204, 230, 67, - 204, 229, 67, 204, 228, 67, 204, 227, 67, 204, 226, 67, 204, 225, 67, - 204, 224, 67, 204, 223, 67, 204, 221, 67, 204, 220, 67, 204, 219, 67, - 204, 218, 67, 204, 217, 67, 204, 216, 67, 204, 215, 67, 204, 214, 67, - 204, 213, 67, 204, 212, 67, 204, 210, 67, 204, 209, 67, 204, 208, 67, - 204, 207, 67, 204, 206, 67, 204, 205, 67, 204, 204, 67, 204, 203, 67, - 204, 202, 67, 204, 201, 67, 204, 199, 67, 204, 198, 67, 204, 197, 67, - 204, 196, 67, 204, 195, 67, 204, 194, 67, 204, 193, 67, 204, 192, 67, - 204, 191, 67, 204, 190, 67, 204, 188, 67, 204, 187, 67, 204, 186, 67, - 204, 185, 67, 204, 184, 67, 204, 183, 67, 204, 182, 67, 204, 181, 67, - 204, 180, 67, 204, 179, 67, 204, 176, 67, 204, 175, 67, 204, 174, 67, - 204, 173, 67, 204, 172, 67, 204, 171, 67, 204, 170, 67, 204, 169, 67, - 204, 168, 67, 204, 167, 67, 204, 165, 67, 204, 164, 67, 204, 163, 67, - 204, 162, 67, 204, 161, 67, 204, 160, 67, 204, 159, 67, 204, 158, 67, - 204, 157, 67, 204, 156, 67, 204, 154, 67, 204, 153, 67, 204, 152, 67, - 204, 151, 67, 204, 150, 67, 204, 149, 67, 204, 148, 67, 204, 147, 67, - 204, 146, 67, 204, 145, 67, 204, 143, 67, 204, 142, 67, 204, 141, 67, - 204, 140, 67, 204, 139, 67, 204, 138, 67, 204, 137, 67, 204, 136, 67, - 204, 135, 67, 204, 134, 67, 204, 132, 67, 204, 131, 67, 204, 130, 67, - 204, 129, 67, 204, 128, 67, 204, 127, 67, 204, 126, 67, 204, 125, 67, - 204, 124, 67, 204, 123, 67, 204, 121, 67, 204, 120, 67, 204, 119, 67, - 204, 118, 67, 204, 117, 67, 204, 116, 67, 204, 115, 212, 138, 212, 140, - 201, 98, 79, 229, 232, 202, 27, 201, 98, 79, 199, 53, 201, 6, 234, 95, - 79, 199, 53, 233, 244, 234, 95, 79, 198, 11, 234, 57, 234, 81, 234, 82, - 252, 51, 252, 52, 251, 189, 248, 238, 249, 140, 248, 16, 246, 240, 199, - 230, 228, 241, 199, 230, 228, 165, 199, 236, 219, 113, 233, 50, 214, 80, - 219, 112, 234, 95, 79, 219, 112, 219, 161, 213, 105, 234, 60, 219, 113, - 199, 230, 81, 199, 230, 193, 251, 232, 146, 233, 50, 233, 27, 247, 88, - 207, 22, 238, 236, 203, 77, 211, 14, 219, 33, 107, 202, 46, 203, 77, 223, - 162, 219, 33, 191, 77, 202, 222, 237, 210, 219, 103, 234, 14, 236, 185, - 237, 75, 239, 22, 107, 237, 199, 237, 75, 239, 22, 109, 237, 198, 237, - 75, 239, 22, 138, 237, 197, 237, 75, 239, 22, 134, 237, 196, 214, 106, - 252, 51, 214, 233, 200, 69, 223, 228, 200, 73, 234, 95, 79, 198, 12, 248, - 129, 233, 252, 247, 126, 247, 128, 234, 95, 79, 216, 212, 234, 58, 234, - 114, 200, 226, 200, 245, 234, 14, 234, 15, 223, 137, 204, 11, 134, 233, - 7, 204, 10, 232, 90, 223, 137, 204, 11, 138, 230, 187, 204, 10, 230, 184, - 223, 137, 204, 11, 109, 207, 98, 204, 10, 206, 74, 223, 137, 204, 11, - 107, 196, 91, 204, 10, 196, 45, 201, 250, 237, 116, 237, 118, 210, 208, - 246, 239, 210, 210, 137, 211, 158, 208, 220, 228, 244, 248, 42, 210, 1, - 229, 192, 248, 58, 213, 44, 248, 42, 229, 192, 214, 191, 223, 148, 223, - 150, 214, 73, 219, 112, 214, 104, 201, 98, 79, 205, 36, 251, 8, 201, 175, - 234, 95, 79, 205, 36, 251, 8, 234, 17, 246, 240, 199, 231, 203, 252, 228, - 241, 199, 231, 203, 252, 228, 162, 246, 240, 199, 231, 4, 222, 164, 228, - 241, 199, 231, 4, 222, 164, 228, 163, 219, 113, 199, 231, 203, 252, 81, - 199, 231, 203, 252, 193, 250, 210, 105, 219, 113, 232, 132, 210, 105, - 219, 113, 235, 123, 209, 94, 210, 105, 219, 113, 249, 139, 210, 105, 219, - 113, 196, 77, 209, 88, 207, 19, 219, 113, 233, 50, 207, 19, 223, 148, - 207, 1, 202, 170, 203, 77, 109, 202, 167, 201, 177, 202, 170, 203, 77, - 138, 202, 166, 201, 176, 237, 75, 239, 22, 201, 30, 237, 194, 208, 205, - 196, 44, 107, 208, 205, 196, 42, 208, 164, 208, 205, 196, 44, 109, 208, - 205, 196, 41, 208, 163, 203, 253, 198, 10, 201, 95, 201, 13, 247, 127, - 246, 239, 247, 61, 216, 169, 193, 171, 215, 81, 201, 98, 79, 230, 172, - 251, 8, 201, 98, 79, 208, 182, 251, 8, 201, 249, 234, 95, 79, 230, 172, - 251, 8, 234, 95, 79, 208, 182, 251, 8, 234, 55, 201, 98, 79, 201, 30, - 202, 9, 202, 170, 230, 216, 246, 240, 223, 96, 203, 170, 202, 170, 246, - 240, 223, 96, 205, 85, 239, 22, 204, 7, 223, 96, 238, 196, 201, 31, 199, - 80, 201, 118, 211, 68, 200, 58, 242, 73, 211, 34, 208, 206, 216, 168, - 209, 76, 251, 45, 208, 198, 242, 73, 251, 62, 214, 179, 202, 231, 8, 6, - 1, 231, 91, 8, 2, 1, 231, 91, 247, 4, 9, 2, 137, 34, 131, 4, 99, 249, 80, - 251, 166, 200, 63, 200, 232, 242, 84, 202, 110, 219, 224, 222, 81, 1, - 219, 62, 220, 17, 1, 232, 176, 232, 166, 220, 17, 1, 232, 176, 233, 62, - 220, 17, 1, 206, 162, 220, 17, 1, 219, 43, 86, 87, 248, 141, 203, 50, - 231, 54, 216, 118, 207, 9, 30, 125, 192, 54, 30, 125, 192, 50, 30, 125, - 201, 153, 30, 125, 192, 55, 232, 66, 232, 65, 232, 64, 215, 83, 232, 63, - 200, 197, 1, 251, 14, 68, 190, 232, 190, 233, 190, 235, 218, 229, 206, - 170, 218, 231, 206, 172, 210, 66, 218, 228, 206, 169, 213, 75, 216, 16, - 193, 50, 218, 230, 206, 171, 232, 89, 210, 65, 193, 111, 234, 119, 232, - 76, 216, 92, 211, 105, 196, 46, 113, 216, 92, 237, 216, 113, 118, 197, - 240, 64, 4, 55, 81, 106, 96, 197, 240, 64, 4, 55, 81, 106, 11, 5, 223, - 51, 77, 80, 1, 221, 206, 219, 73, 194, 251, 194, 140, 194, 72, 194, 61, - 194, 50, 194, 39, 194, 28, 194, 17, 194, 6, 194, 250, 194, 239, 194, 228, - 194, 217, 194, 206, 194, 195, 194, 184, 208, 221, 232, 146, 40, 81, 50, - 63, 219, 187, 248, 53, 247, 198, 211, 51, 77, 248, 100, 190, 234, 10, 3, - 212, 148, 199, 84, 10, 3, 212, 148, 139, 212, 148, 247, 231, 139, 247, - 230, 216, 218, 6, 1, 230, 116, 216, 218, 6, 1, 214, 70, 216, 218, 2, 1, - 230, 116, 216, 218, 2, 1, 214, 70, 61, 1, 235, 14, 73, 37, 16, 232, 88, - 202, 106, 243, 52, 195, 164, 194, 173, 194, 162, 194, 151, 194, 139, 194, - 128, 194, 117, 194, 106, 194, 95, 194, 84, 194, 76, 194, 75, 194, 74, - 194, 73, 194, 71, 194, 70, 194, 69, 194, 68, 194, 67, 194, 66, 194, 65, - 194, 64, 194, 63, 194, 62, 194, 60, 194, 59, 194, 58, 194, 57, 194, 56, - 194, 55, 194, 54, 194, 53, 194, 52, 194, 51, 194, 49, 194, 48, 194, 47, - 194, 46, 194, 45, 194, 44, 194, 43, 194, 42, 194, 41, 194, 40, 194, 38, - 194, 37, 194, 36, 194, 35, 194, 34, 194, 33, 194, 32, 194, 31, 194, 30, - 194, 29, 194, 27, 194, 26, 194, 25, 194, 24, 194, 23, 194, 22, 194, 21, - 194, 20, 194, 19, 194, 18, 194, 16, 194, 15, 194, 14, 194, 13, 194, 12, - 194, 11, 194, 10, 194, 9, 194, 8, 194, 7, 194, 5, 194, 4, 194, 3, 194, 2, - 194, 1, 194, 0, 193, 255, 193, 254, 193, 253, 193, 252, 194, 249, 194, - 248, 194, 247, 194, 246, 194, 245, 194, 244, 194, 243, 194, 242, 194, - 241, 194, 240, 194, 238, 194, 237, 194, 236, 194, 235, 194, 234, 194, - 233, 194, 232, 194, 231, 194, 230, 194, 229, 194, 227, 194, 226, 194, - 225, 194, 224, 194, 223, 194, 222, 194, 221, 194, 220, 194, 219, 194, - 218, 194, 216, 194, 215, 194, 214, 194, 213, 194, 212, 194, 211, 194, - 210, 194, 209, 194, 208, 194, 207, 194, 205, 194, 204, 194, 203, 194, - 202, 194, 201, 194, 200, 194, 199, 194, 198, 194, 197, 194, 196, 194, - 194, 194, 193, 194, 192, 194, 191, 194, 190, 194, 189, 194, 188, 194, - 187, 194, 186, 194, 185, 194, 183, 194, 182, 194, 181, 194, 180, 194, - 179, 194, 178, 194, 177, 194, 176, 194, 175, 194, 174, 194, 172, 194, - 171, 194, 170, 194, 169, 194, 168, 194, 167, 194, 166, 194, 165, 194, - 164, 194, 163, 194, 161, 194, 160, 194, 159, 194, 158, 194, 157, 194, - 156, 194, 155, 194, 154, 194, 153, 194, 152, 194, 150, 194, 149, 194, - 148, 194, 147, 194, 146, 194, 145, 194, 144, 194, 143, 194, 142, 194, - 141, 194, 138, 194, 137, 194, 136, 194, 135, 194, 134, 194, 133, 194, - 132, 194, 131, 194, 130, 194, 129, 194, 127, 194, 126, 194, 125, 194, - 124, 194, 123, 194, 122, 194, 121, 194, 120, 194, 119, 194, 118, 194, - 116, 194, 115, 194, 114, 194, 113, 194, 112, 194, 111, 194, 110, 194, - 109, 194, 108, 194, 107, 194, 105, 194, 104, 194, 103, 194, 102, 194, - 101, 194, 100, 194, 99, 194, 98, 194, 97, 194, 96, 194, 94, 194, 93, 194, - 92, 194, 91, 194, 90, 194, 89, 194, 88, 194, 87, 194, 86, 194, 85, 194, - 83, 194, 82, 194, 81, 194, 80, 194, 79, 194, 78, 194, 77, 221, 219, 31, - 56, 221, 219, 250, 193, 221, 219, 17, 191, 77, 221, 219, 17, 107, 221, - 219, 17, 109, 221, 219, 17, 138, 221, 219, 17, 134, 221, 219, 17, 149, - 221, 219, 17, 169, 221, 219, 17, 175, 221, 219, 17, 171, 221, 219, 17, - 178, 8, 6, 1, 42, 4, 217, 147, 23, 230, 210, 8, 2, 1, 42, 4, 217, 147, - 23, 230, 210, 8, 6, 1, 228, 74, 4, 217, 147, 23, 230, 210, 8, 2, 1, 228, - 74, 4, 217, 147, 23, 230, 210, 8, 6, 1, 126, 4, 217, 147, 23, 230, 210, - 8, 2, 1, 126, 4, 217, 147, 23, 230, 210, 8, 6, 1, 235, 15, 4, 81, 219, - 113, 60, 8, 2, 1, 235, 15, 4, 81, 219, 113, 60, 8, 6, 1, 235, 15, 4, 81, - 219, 113, 248, 233, 23, 230, 210, 8, 2, 1, 235, 15, 4, 81, 219, 113, 248, - 233, 23, 230, 210, 8, 6, 1, 235, 15, 4, 81, 219, 113, 248, 233, 23, 252, - 46, 8, 2, 1, 235, 15, 4, 81, 219, 113, 248, 233, 23, 252, 46, 8, 6, 1, - 187, 4, 81, 219, 113, 60, 8, 2, 1, 187, 4, 81, 219, 113, 60, 8, 6, 1, - 187, 4, 81, 219, 113, 248, 233, 23, 230, 210, 8, 2, 1, 187, 4, 81, 219, - 113, 248, 233, 23, 230, 210, 8, 6, 1, 187, 4, 81, 219, 113, 248, 233, 23, - 252, 46, 8, 2, 1, 187, 4, 81, 219, 113, 248, 233, 23, 252, 46, 8, 6, 1, - 206, 9, 4, 81, 219, 113, 60, 8, 2, 1, 206, 9, 4, 81, 219, 113, 60, 8, 6, - 1, 235, 15, 4, 243, 2, 23, 217, 146, 8, 2, 1, 235, 15, 4, 243, 2, 23, - 217, 146, 8, 6, 1, 235, 15, 4, 243, 2, 23, 247, 92, 8, 2, 1, 235, 15, 4, - 243, 2, 23, 247, 92, 8, 2, 1, 228, 74, 4, 75, 93, 23, 252, 46, 8, 2, 1, - 214, 71, 4, 198, 153, 58, 8, 6, 1, 42, 4, 211, 139, 23, 252, 46, 8, 2, 1, - 42, 4, 211, 139, 23, 252, 46, 8, 6, 1, 42, 4, 211, 139, 23, 198, 152, 8, - 2, 1, 42, 4, 211, 139, 23, 198, 152, 8, 6, 1, 235, 15, 4, 211, 139, 23, - 252, 46, 8, 2, 1, 235, 15, 4, 211, 139, 23, 252, 46, 8, 6, 1, 235, 15, 4, - 211, 139, 23, 198, 152, 8, 2, 1, 235, 15, 4, 211, 139, 23, 198, 152, 8, - 6, 1, 235, 15, 4, 75, 93, 23, 252, 46, 8, 2, 1, 235, 15, 4, 75, 93, 23, - 252, 46, 8, 6, 1, 235, 15, 4, 75, 93, 23, 198, 152, 8, 2, 1, 235, 15, 4, - 75, 93, 23, 198, 152, 8, 2, 1, 228, 74, 4, 75, 93, 23, 230, 210, 8, 2, 1, - 228, 74, 4, 75, 93, 23, 198, 152, 8, 6, 1, 228, 74, 4, 211, 139, 23, 252, - 46, 8, 2, 1, 228, 74, 4, 211, 139, 23, 75, 93, 23, 252, 46, 8, 6, 1, 228, - 74, 4, 211, 139, 23, 198, 152, 8, 2, 1, 228, 74, 4, 211, 139, 23, 75, 93, - 23, 198, 152, 8, 6, 1, 223, 36, 4, 198, 152, 8, 2, 1, 223, 36, 4, 75, 93, - 23, 198, 152, 8, 6, 1, 220, 143, 4, 198, 152, 8, 2, 1, 220, 143, 4, 198, - 152, 8, 6, 1, 218, 169, 4, 198, 152, 8, 2, 1, 218, 169, 4, 198, 152, 8, - 6, 1, 207, 222, 4, 198, 152, 8, 2, 1, 207, 222, 4, 198, 152, 8, 6, 1, - 126, 4, 211, 139, 23, 252, 46, 8, 2, 1, 126, 4, 211, 139, 23, 252, 46, 8, - 6, 1, 126, 4, 211, 139, 23, 198, 152, 8, 2, 1, 126, 4, 211, 139, 23, 198, - 152, 8, 6, 1, 126, 4, 217, 147, 23, 252, 46, 8, 2, 1, 126, 4, 217, 147, - 23, 252, 46, 8, 6, 1, 126, 4, 217, 147, 23, 198, 152, 8, 2, 1, 126, 4, - 217, 147, 23, 198, 152, 8, 2, 1, 252, 26, 4, 230, 210, 8, 2, 1, 211, 77, - 187, 4, 230, 210, 8, 2, 1, 211, 77, 187, 4, 252, 46, 8, 2, 1, 153, 196, - 13, 4, 230, 210, 8, 2, 1, 153, 196, 13, 4, 252, 46, 8, 2, 1, 205, 87, 4, - 230, 210, 8, 2, 1, 205, 87, 4, 252, 46, 8, 2, 1, 228, 250, 205, 87, 4, - 230, 210, 8, 2, 1, 228, 250, 205, 87, 4, 252, 46, 9, 204, 7, 99, 4, 230, - 58, 93, 4, 251, 192, 9, 204, 7, 99, 4, 230, 58, 93, 4, 193, 133, 9, 204, - 7, 99, 4, 230, 58, 93, 4, 131, 217, 99, 9, 204, 7, 99, 4, 230, 58, 93, 4, - 211, 151, 9, 204, 7, 99, 4, 230, 58, 93, 4, 66, 9, 204, 7, 99, 4, 230, - 58, 93, 4, 191, 225, 9, 204, 7, 99, 4, 230, 58, 93, 4, 71, 9, 204, 7, 99, - 4, 230, 58, 93, 4, 252, 25, 9, 204, 7, 213, 25, 4, 222, 4, 100, 204, 7, - 40, 1, 208, 96, 100, 204, 7, 40, 1, 221, 193, 100, 204, 7, 40, 1, 231, - 66, 100, 204, 7, 40, 1, 191, 123, 100, 204, 7, 40, 1, 237, 180, 100, 204, - 7, 40, 1, 207, 6, 100, 204, 7, 40, 1, 233, 109, 100, 204, 7, 40, 1, 191, - 175, 248, 225, 204, 7, 40, 1, 206, 109, 248, 225, 204, 7, 40, 1, 207, 6, - 248, 225, 204, 7, 40, 1, 191, 175, 230, 144, 204, 7, 40, 1, 219, 73, 230, - 144, 204, 7, 40, 1, 203, 165, 230, 144, 204, 7, 40, 1, 221, 193, 230, - 144, 204, 7, 40, 1, 231, 66, 230, 144, 204, 7, 40, 1, 191, 123, 230, 144, - 204, 7, 40, 1, 233, 109, 211, 45, 204, 7, 40, 1, 206, 109, 211, 45, 204, - 7, 40, 1, 207, 6, 248, 225, 1, 221, 187, 44, 120, 222, 152, 44, 120, 214, - 70, 44, 120, 247, 193, 44, 120, 212, 103, 44, 120, 197, 135, 44, 120, - 213, 80, 44, 120, 200, 43, 44, 120, 215, 61, 44, 120, 210, 236, 44, 120, - 218, 168, 44, 120, 192, 159, 44, 120, 146, 44, 120, 172, 44, 120, 196, - 12, 44, 120, 219, 63, 44, 120, 219, 74, 44, 120, 206, 110, 44, 120, 213, - 62, 44, 120, 223, 35, 44, 120, 203, 167, 44, 120, 201, 178, 44, 120, 206, - 8, 44, 120, 230, 116, 44, 120, 220, 247, 44, 5, 222, 127, 44, 5, 221, - 166, 44, 5, 221, 145, 44, 5, 220, 232, 44, 5, 220, 187, 44, 5, 222, 22, - 44, 5, 222, 13, 44, 5, 222, 102, 44, 5, 221, 67, 44, 5, 221, 41, 44, 5, - 222, 42, 44, 5, 214, 67, 44, 5, 214, 16, 44, 5, 214, 12, 44, 5, 213, 237, - 44, 5, 213, 228, 44, 5, 214, 55, 44, 5, 214, 53, 44, 5, 214, 64, 44, 5, - 213, 249, 44, 5, 213, 244, 44, 5, 214, 57, 44, 5, 247, 159, 44, 5, 243, - 29, 44, 5, 243, 19, 44, 5, 238, 195, 44, 5, 238, 153, 44, 5, 247, 42, 44, - 5, 247, 34, 44, 5, 247, 148, 44, 5, 242, 99, 44, 5, 239, 18, 44, 5, 247, - 76, 44, 5, 212, 100, 44, 5, 212, 81, 44, 5, 212, 75, 44, 5, 212, 58, 44, - 5, 212, 50, 44, 5, 212, 90, 44, 5, 212, 89, 44, 5, 212, 97, 44, 5, 212, - 65, 44, 5, 212, 62, 44, 5, 212, 93, 44, 5, 197, 131, 44, 5, 197, 111, 44, - 5, 197, 110, 44, 5, 197, 99, 44, 5, 197, 96, 44, 5, 197, 127, 44, 5, 197, - 126, 44, 5, 197, 130, 44, 5, 197, 109, 44, 5, 197, 108, 44, 5, 197, 129, - 44, 5, 213, 78, 44, 5, 213, 64, 44, 5, 213, 63, 44, 5, 213, 47, 44, 5, - 213, 46, 44, 5, 213, 74, 44, 5, 213, 73, 44, 5, 213, 77, 44, 5, 213, 49, - 44, 5, 213, 48, 44, 5, 213, 76, 44, 5, 199, 245, 44, 5, 198, 193, 44, 5, - 198, 170, 44, 5, 197, 94, 44, 5, 197, 49, 44, 5, 199, 145, 44, 5, 199, - 121, 44, 5, 199, 217, 44, 5, 159, 44, 5, 198, 59, 44, 5, 199, 166, 44, 5, - 214, 250, 44, 5, 213, 219, 44, 5, 213, 186, 44, 5, 212, 178, 44, 5, 212, - 115, 44, 5, 214, 121, 44, 5, 214, 110, 44, 5, 214, 236, 44, 5, 213, 43, - 44, 5, 213, 26, 44, 5, 214, 205, 44, 5, 210, 220, 44, 5, 209, 185, 44, 5, - 209, 145, 44, 5, 208, 165, 44, 5, 208, 128, 44, 5, 210, 63, 44, 5, 210, - 49, 44, 5, 210, 198, 44, 5, 209, 73, 44, 5, 209, 37, 44, 5, 210, 80, 44, - 5, 217, 151, 44, 5, 216, 100, 44, 5, 216, 61, 44, 5, 215, 155, 44, 5, - 215, 93, 44, 5, 216, 232, 44, 5, 216, 211, 44, 5, 217, 112, 44, 5, 216, - 12, 44, 5, 215, 211, 44, 5, 217, 25, 44, 5, 192, 140, 44, 5, 192, 33, 44, - 5, 192, 23, 44, 5, 191, 225, 44, 5, 191, 188, 44, 5, 192, 80, 44, 5, 192, - 77, 44, 5, 192, 119, 44, 5, 192, 12, 44, 5, 191, 246, 44, 5, 192, 91, 44, - 5, 207, 178, 44, 5, 207, 1, 44, 5, 206, 195, 44, 5, 206, 68, 44, 5, 206, - 29, 44, 5, 207, 113, 44, 5, 207, 84, 44, 5, 207, 156, 44, 5, 206, 162, - 44, 5, 206, 134, 44, 5, 207, 125, 44, 5, 220, 125, 44, 5, 219, 146, 44, - 5, 219, 128, 44, 5, 218, 225, 44, 5, 218, 194, 44, 5, 219, 238, 44, 5, - 219, 228, 44, 5, 220, 96, 44, 5, 219, 43, 44, 5, 219, 8, 44, 5, 220, 0, - 44, 5, 195, 187, 44, 5, 195, 69, 44, 5, 195, 51, 44, 5, 193, 249, 44, 5, - 193, 241, 44, 5, 195, 153, 44, 5, 195, 148, 44, 5, 195, 183, 44, 5, 195, - 24, 44, 5, 195, 8, 44, 5, 195, 160, 44, 5, 219, 61, 44, 5, 219, 56, 44, - 5, 219, 55, 44, 5, 219, 52, 44, 5, 219, 51, 44, 5, 219, 58, 44, 5, 219, - 57, 44, 5, 219, 60, 44, 5, 219, 54, 44, 5, 219, 53, 44, 5, 219, 59, 44, - 5, 219, 72, 44, 5, 219, 65, 44, 5, 219, 64, 44, 5, 219, 48, 44, 5, 219, - 47, 44, 5, 219, 68, 44, 5, 219, 67, 44, 5, 219, 71, 44, 5, 219, 50, 44, - 5, 219, 49, 44, 5, 219, 69, 44, 5, 206, 108, 44, 5, 206, 97, 44, 5, 206, - 96, 44, 5, 206, 89, 44, 5, 206, 82, 44, 5, 206, 104, 44, 5, 206, 103, 44, - 5, 206, 107, 44, 5, 206, 95, 44, 5, 206, 94, 44, 5, 206, 106, 44, 5, 213, - 60, 44, 5, 213, 55, 44, 5, 213, 54, 44, 5, 213, 51, 44, 5, 213, 50, 44, - 5, 213, 57, 44, 5, 213, 56, 44, 5, 213, 59, 44, 5, 213, 53, 44, 5, 213, - 52, 44, 5, 213, 58, 44, 5, 223, 31, 44, 5, 222, 244, 44, 5, 222, 236, 44, - 5, 222, 182, 44, 5, 222, 162, 44, 5, 223, 10, 44, 5, 223, 8, 44, 5, 223, - 25, 44, 5, 222, 201, 44, 5, 222, 191, 44, 5, 223, 17, 44, 5, 203, 160, - 44, 5, 203, 81, 44, 5, 203, 76, 44, 5, 203, 5, 44, 5, 202, 243, 44, 5, - 203, 113, 44, 5, 203, 111, 44, 5, 203, 148, 44, 5, 203, 56, 44, 5, 203, - 48, 44, 5, 203, 122, 44, 5, 201, 174, 44, 5, 201, 142, 44, 5, 201, 138, - 44, 5, 201, 129, 44, 5, 201, 126, 44, 5, 201, 148, 44, 5, 201, 147, 44, - 5, 201, 173, 44, 5, 201, 134, 44, 5, 201, 133, 44, 5, 201, 150, 44, 5, - 205, 197, 44, 5, 202, 222, 44, 5, 202, 193, 44, 5, 201, 4, 44, 5, 200, - 160, 44, 5, 205, 68, 44, 5, 205, 50, 44, 5, 205, 181, 44, 5, 202, 46, 44, - 5, 202, 16, 44, 5, 205, 114, 44, 5, 230, 91, 44, 5, 229, 158, 44, 5, 229, - 130, 44, 5, 228, 159, 44, 5, 228, 128, 44, 5, 229, 245, 44, 5, 229, 215, - 44, 5, 230, 80, 44, 5, 229, 23, 44, 5, 228, 252, 44, 5, 230, 2, 44, 5, - 220, 246, 44, 5, 220, 245, 44, 5, 220, 240, 44, 5, 220, 239, 44, 5, 220, - 236, 44, 5, 220, 235, 44, 5, 220, 242, 44, 5, 220, 241, 44, 5, 220, 244, - 44, 5, 220, 238, 44, 5, 220, 237, 44, 5, 220, 243, 44, 5, 203, 14, 166, - 120, 3, 192, 105, 166, 120, 3, 207, 144, 166, 120, 3, 207, 50, 101, 1, - 196, 224, 95, 120, 3, 242, 91, 155, 95, 120, 3, 242, 91, 221, 215, 95, - 120, 3, 242, 91, 221, 67, 95, 120, 3, 242, 91, 221, 183, 95, 120, 3, 242, - 91, 213, 249, 95, 120, 3, 242, 91, 247, 160, 95, 120, 3, 242, 91, 247, 1, - 95, 120, 3, 242, 91, 242, 99, 95, 120, 3, 242, 91, 243, 68, 95, 120, 3, - 242, 91, 212, 65, 95, 120, 3, 242, 91, 238, 32, 95, 120, 3, 242, 91, 197, - 120, 95, 120, 3, 242, 91, 236, 174, 95, 120, 3, 242, 91, 197, 115, 95, - 120, 3, 242, 91, 180, 95, 120, 3, 242, 91, 190, 190, 95, 120, 3, 242, 91, - 199, 49, 95, 120, 3, 242, 91, 159, 95, 120, 3, 242, 91, 198, 241, 95, - 120, 3, 242, 91, 213, 43, 95, 120, 3, 242, 91, 249, 153, 95, 120, 3, 242, - 91, 209, 228, 95, 120, 3, 242, 91, 209, 73, 95, 120, 3, 242, 91, 209, - 199, 95, 120, 3, 242, 91, 216, 12, 95, 120, 3, 242, 91, 192, 12, 95, 120, - 3, 242, 91, 206, 162, 95, 120, 3, 242, 91, 219, 43, 95, 120, 3, 242, 91, - 195, 24, 95, 120, 3, 242, 91, 203, 165, 95, 120, 3, 242, 91, 201, 175, - 95, 120, 3, 242, 91, 188, 95, 120, 3, 242, 91, 140, 95, 120, 3, 242, 91, - 173, 95, 18, 3, 242, 91, 208, 96, 95, 223, 149, 18, 3, 242, 91, 208, 33, - 95, 223, 149, 18, 3, 242, 91, 206, 17, 95, 223, 149, 18, 3, 242, 91, 206, - 10, 95, 223, 149, 18, 3, 242, 91, 208, 75, 95, 18, 3, 211, 113, 95, 18, - 3, 252, 167, 229, 120, 1, 248, 181, 214, 68, 229, 120, 1, 248, 181, 214, - 16, 229, 120, 1, 248, 181, 213, 237, 229, 120, 1, 248, 181, 214, 55, 229, - 120, 1, 248, 181, 213, 249, 72, 1, 248, 181, 214, 68, 72, 1, 248, 181, - 214, 16, 72, 1, 248, 181, 213, 237, 72, 1, 248, 181, 214, 55, 72, 1, 248, - 181, 213, 249, 72, 1, 251, 228, 247, 42, 72, 1, 251, 228, 197, 94, 72, 1, - 251, 228, 159, 72, 1, 251, 228, 210, 236, 52, 1, 233, 200, 233, 199, 239, - 26, 163, 164, 52, 1, 233, 199, 233, 200, 239, 26, 163, 164, + 184, 203, 226, 184, 203, 189, 184, 203, 218, 184, 203, 203, 110, 45, 184, + 237, 41, 110, 82, 45, 119, 110, 247, 23, 110, 45, 184, 237, 41, 110, 82, + 45, 119, 110, 179, 110, 45, 184, 237, 41, 116, 82, 45, 119, 110, 247, 23, + 110, 45, 184, 237, 41, 116, 82, 45, 119, 110, 179, 110, 45, 184, 237, 41, + 116, 45, 119, 110, 247, 23, 110, 50, 184, 237, 41, 116, 82, 45, 119, 116, + 247, 23, 110, 50, 184, 237, 41, 116, 82, 45, 119, 116, 179, 110, 50, 184, + 237, 41, 110, 82, 45, 119, 116, 247, 23, 110, 50, 184, 237, 41, 110, 82, + 45, 119, 116, 179, 110, 50, 184, 237, 41, 110, 45, 119, 116, 247, 23, + 110, 50, 184, 237, 41, 110, 82, 45, 119, 116, 82, 179, 110, 50, 184, 237, + 41, 110, 247, 24, 119, 110, 82, 179, 110, 50, 184, 237, 41, 110, 45, 119, + 110, 82, 179, 110, 50, 184, 237, 41, 110, 247, 24, 119, 116, 82, 179, + 110, 50, 184, 237, 41, 110, 45, 119, 116, 82, 179, 110, 50, 184, 237, 41, + 110, 247, 24, 119, 116, 179, 110, 45, 184, 237, 41, 116, 247, 24, 119, + 116, 82, 179, 110, 45, 184, 237, 41, 116, 45, 119, 116, 82, 179, 110, 45, + 184, 237, 41, 116, 247, 24, 119, 110, 82, 179, 110, 45, 184, 237, 41, + 116, 45, 119, 110, 82, 179, 110, 45, 184, 237, 41, 116, 247, 24, 119, + 110, 179, 110, 45, 184, 237, 41, 116, 82, 45, 119, 110, 82, 179, 116, 50, + 184, 237, 41, 110, 82, 45, 119, 110, 247, 23, 116, 50, 184, 237, 41, 110, + 82, 45, 119, 110, 179, 116, 50, 184, 237, 41, 116, 82, 45, 119, 110, 247, + 23, 116, 50, 184, 237, 41, 116, 82, 45, 119, 110, 179, 116, 50, 184, 237, + 41, 116, 45, 119, 110, 247, 23, 116, 45, 184, 237, 41, 116, 82, 45, 119, + 116, 247, 23, 116, 45, 184, 237, 41, 116, 82, 45, 119, 116, 179, 116, 45, + 184, 237, 41, 110, 82, 45, 119, 116, 247, 23, 116, 45, 184, 237, 41, 110, + 82, 45, 119, 116, 179, 116, 45, 184, 237, 41, 110, 45, 119, 116, 247, 23, + 116, 45, 184, 237, 41, 110, 82, 45, 119, 116, 82, 179, 116, 45, 184, 237, + 41, 110, 247, 24, 119, 110, 82, 179, 116, 45, 184, 237, 41, 110, 45, 119, + 110, 82, 179, 116, 45, 184, 237, 41, 110, 247, 24, 119, 116, 82, 179, + 116, 45, 184, 237, 41, 110, 45, 119, 116, 82, 179, 116, 45, 184, 237, 41, + 110, 247, 24, 119, 116, 179, 116, 50, 184, 237, 41, 116, 247, 24, 119, + 116, 82, 179, 116, 50, 184, 237, 41, 116, 45, 119, 116, 82, 179, 116, 50, + 184, 237, 41, 116, 247, 24, 119, 110, 82, 179, 116, 50, 184, 237, 41, + 116, 45, 119, 110, 82, 179, 116, 50, 184, 237, 41, 116, 247, 24, 119, + 110, 179, 116, 50, 184, 237, 41, 116, 82, 45, 119, 110, 82, 179, 116, 23, + 50, 23, 110, 197, 238, 115, 208, 23, 248, 131, 45, 23, 110, 23, 50, 197, + 238, 115, 208, 23, 248, 131, 116, 23, 45, 23, 110, 197, 238, 115, 208, + 23, 248, 131, 45, 23, 116, 23, 50, 197, 238, 115, 208, 23, 248, 131, 45, + 197, 238, 91, 208, 25, 248, 131, 116, 197, 238, 91, 208, 25, 248, 131, + 50, 197, 238, 91, 208, 25, 248, 131, 110, 197, 238, 91, 208, 25, 248, + 131, 81, 91, 234, 162, 248, 129, 81, 91, 234, 162, 248, 128, 81, 91, 234, + 162, 248, 127, 81, 91, 234, 162, 248, 126, 81, 91, 234, 162, 248, 125, + 81, 91, 234, 162, 248, 124, 228, 243, 91, 234, 162, 248, 129, 228, 243, + 91, 234, 162, 248, 128, 228, 243, 91, 234, 162, 248, 127, 228, 243, 91, + 234, 162, 248, 126, 228, 243, 91, 234, 162, 248, 125, 228, 243, 91, 234, + 162, 248, 124, 45, 23, 110, 91, 234, 162, 248, 131, 45, 23, 116, 91, 234, + 162, 248, 131, 50, 23, 116, 91, 234, 162, 248, 131, 50, 23, 110, 91, 234, + 162, 248, 131, 116, 23, 110, 91, 234, 162, 248, 131, 228, 243, 91, 234, + 162, 248, 130, 116, 91, 208, 25, 248, 131, 116, 115, 234, 160, 248, 131, + 116, 232, 228, 234, 160, 248, 131, 116, 115, 208, 23, 248, 131, 116, 203, + 248, 234, 160, 248, 131, 50, 91, 208, 25, 248, 131, 50, 115, 234, 160, + 248, 131, 50, 232, 228, 234, 160, 248, 131, 50, 115, 208, 23, 248, 131, + 50, 203, 248, 234, 160, 248, 131, 45, 132, 216, 215, 203, 154, 50, 132, + 216, 215, 203, 154, 116, 132, 216, 215, 203, 154, 110, 132, 216, 215, + 203, 154, 223, 97, 216, 215, 203, 154, 116, 132, 184, 23, 110, 132, 223, + 97, 216, 215, 203, 154, 116, 132, 223, 97, 216, 215, 203, 155, 23, 110, + 132, 248, 131, 45, 132, 223, 97, 216, 215, 203, 155, 23, 50, 132, 248, + 131, 243, 126, 248, 110, 233, 7, 223, 97, 243, 126, 248, 110, 233, 7, 88, + 228, 243, 233, 7, 116, 45, 119, 110, 50, 233, 7, 116, 50, 119, 110, 45, + 233, 7, 116, 23, 110, 197, 238, 132, 248, 131, 45, 23, 50, 197, 238, 132, + 248, 131, 116, 45, 197, 238, 216, 215, 203, 154, 116, 50, 197, 238, 216, + 215, 203, 154, 110, 50, 197, 238, 216, 215, 203, 154, 110, 45, 197, 238, + 216, 215, 203, 154, 111, 122, 156, 237, 41, 116, 247, 24, 119, 82, 219, + 226, 111, 122, 156, 237, 41, 116, 247, 24, 119, 82, 179, 111, 122, 156, + 237, 41, 82, 45, 119, 110, 247, 23, 111, 122, 156, 237, 41, 82, 50, 119, + 110, 247, 23, 111, 122, 156, 237, 41, 116, 247, 24, 119, 82, 45, 119, + 110, 247, 23, 111, 122, 156, 237, 41, 116, 247, 24, 119, 82, 50, 119, + 110, 247, 23, 111, 122, 156, 237, 41, 82, 45, 119, 110, 247, 24, 119, 82, + 179, 111, 122, 156, 237, 41, 82, 45, 119, 116, 247, 24, 119, 82, 179, + 111, 122, 156, 237, 41, 116, 247, 24, 119, 82, 45, 23, 82, 50, 119, 110, + 247, 23, 111, 122, 156, 237, 41, 116, 247, 24, 119, 82, 50, 23, 82, 45, + 119, 110, 247, 23, 111, 122, 156, 237, 41, 116, 247, 24, 119, 82, 50, + 119, 110, 247, 24, 119, 82, 219, 226, 111, 122, 156, 237, 41, 116, 247, + 24, 119, 82, 45, 119, 110, 247, 24, 119, 82, 179, 111, 122, 156, 237, 41, + 82, 45, 119, 116, 247, 24, 119, 82, 50, 119, 110, 247, 23, 111, 122, 156, + 237, 41, 82, 50, 119, 116, 247, 24, 119, 82, 45, 119, 110, 247, 23, 111, + 122, 156, 237, 41, 237, 34, 111, 122, 156, 228, 243, 4, 81, 106, 250, + 236, 209, 61, 223, 97, 243, 128, 77, 45, 132, 206, 43, 217, 92, 50, 132, + 206, 43, 217, 92, 223, 97, 235, 121, 64, 4, 198, 136, 219, 216, 118, 64, + 23, 116, 23, 110, 91, 234, 162, 248, 131, 96, 64, 23, 116, 23, 110, 91, + 234, 162, 248, 131, 235, 121, 64, 23, 50, 91, 234, 162, 248, 131, 196, + 66, 64, 23, 50, 91, 234, 162, 248, 131, 45, 132, 232, 173, 50, 132, 232, + 173, 195, 16, 35, 238, 219, 50, 211, 79, 112, 236, 142, 214, 108, 237, + 41, 238, 219, 214, 108, 237, 41, 82, 50, 119, 110, 247, 23, 214, 108, + 237, 41, 237, 34, 63, 88, 205, 156, 4, 206, 114, 239, 2, 45, 199, 1, 63, + 50, 209, 60, 223, 150, 82, 199, 1, 63, 50, 209, 60, 223, 150, 50, 199, 1, + 63, 50, 209, 60, 223, 150, 214, 108, 112, 208, 15, 77, 201, 76, 233, 14, + 201, 76, 233, 15, 4, 250, 249, 207, 148, 201, 76, 233, 15, 219, 233, 219, + 226, 201, 76, 233, 15, 219, 233, 179, 201, 76, 233, 15, 4, 235, 108, 63, + 196, 76, 243, 102, 205, 43, 17, 191, 77, 205, 43, 17, 107, 205, 43, 17, + 109, 205, 43, 17, 138, 205, 43, 17, 134, 205, 43, 17, 150, 205, 43, 17, + 169, 205, 43, 17, 175, 205, 43, 17, 171, 205, 43, 17, 178, 12, 15, 228, + 15, 12, 15, 228, 14, 12, 15, 228, 13, 12, 15, 228, 12, 12, 15, 228, 11, + 12, 15, 228, 10, 12, 15, 228, 9, 12, 15, 228, 8, 12, 15, 228, 7, 12, 15, + 228, 6, 12, 15, 228, 5, 12, 15, 228, 4, 12, 15, 228, 3, 12, 15, 228, 2, + 12, 15, 228, 1, 12, 15, 228, 0, 12, 15, 227, 255, 12, 15, 227, 254, 12, + 15, 227, 253, 12, 15, 227, 252, 12, 15, 227, 251, 12, 15, 227, 250, 12, + 15, 227, 249, 12, 15, 227, 248, 12, 15, 227, 247, 12, 15, 227, 246, 12, + 15, 227, 245, 12, 15, 227, 244, 12, 15, 227, 243, 12, 15, 227, 242, 12, + 15, 227, 241, 12, 15, 227, 240, 12, 15, 227, 239, 12, 15, 227, 238, 12, + 15, 227, 237, 12, 15, 227, 236, 12, 15, 227, 235, 12, 15, 227, 234, 12, + 15, 227, 233, 12, 15, 227, 232, 12, 15, 227, 231, 12, 15, 227, 230, 12, + 15, 227, 229, 12, 15, 227, 228, 12, 15, 227, 227, 12, 15, 227, 226, 12, + 15, 227, 225, 12, 15, 227, 224, 12, 15, 227, 223, 12, 15, 227, 222, 12, + 15, 227, 221, 12, 15, 227, 220, 12, 15, 227, 219, 12, 15, 227, 218, 12, + 15, 227, 217, 12, 15, 227, 216, 12, 15, 227, 215, 12, 15, 227, 214, 12, + 15, 227, 213, 12, 15, 227, 212, 12, 15, 227, 211, 12, 15, 227, 210, 12, + 15, 227, 209, 12, 15, 227, 208, 12, 15, 227, 207, 12, 15, 227, 206, 12, + 15, 227, 205, 12, 15, 227, 204, 12, 15, 227, 203, 12, 15, 227, 202, 12, + 15, 227, 201, 12, 15, 227, 200, 12, 15, 227, 199, 12, 15, 227, 198, 12, + 15, 227, 197, 12, 15, 227, 196, 12, 15, 227, 195, 12, 15, 227, 194, 12, + 15, 227, 193, 12, 15, 227, 192, 12, 15, 227, 191, 12, 15, 227, 190, 12, + 15, 227, 189, 12, 15, 227, 188, 12, 15, 227, 187, 12, 15, 227, 186, 12, + 15, 227, 185, 12, 15, 227, 184, 12, 15, 227, 183, 12, 15, 227, 182, 12, + 15, 227, 181, 12, 15, 227, 180, 12, 15, 227, 179, 12, 15, 227, 178, 12, + 15, 227, 177, 12, 15, 227, 176, 12, 15, 227, 175, 12, 15, 227, 174, 12, + 15, 227, 173, 12, 15, 227, 172, 12, 15, 227, 171, 12, 15, 227, 170, 12, + 15, 227, 169, 12, 15, 227, 168, 12, 15, 227, 167, 12, 15, 227, 166, 12, + 15, 227, 165, 12, 15, 227, 164, 12, 15, 227, 163, 12, 15, 227, 162, 12, + 15, 227, 161, 12, 15, 227, 160, 12, 15, 227, 159, 12, 15, 227, 158, 12, + 15, 227, 157, 12, 15, 227, 156, 12, 15, 227, 155, 12, 15, 227, 154, 12, + 15, 227, 153, 12, 15, 227, 152, 12, 15, 227, 151, 12, 15, 227, 150, 12, + 15, 227, 149, 12, 15, 227, 148, 12, 15, 227, 147, 12, 15, 227, 146, 12, + 15, 227, 145, 12, 15, 227, 144, 12, 15, 227, 143, 12, 15, 227, 142, 12, + 15, 227, 141, 12, 15, 227, 140, 12, 15, 227, 139, 12, 15, 227, 138, 12, + 15, 227, 137, 12, 15, 227, 136, 12, 15, 227, 135, 12, 15, 227, 134, 12, + 15, 227, 133, 12, 15, 227, 132, 12, 15, 227, 131, 12, 15, 227, 130, 12, + 15, 227, 129, 12, 15, 227, 128, 12, 15, 227, 127, 12, 15, 227, 126, 12, + 15, 227, 125, 12, 15, 227, 124, 12, 15, 227, 123, 12, 15, 227, 122, 12, + 15, 227, 121, 12, 15, 227, 120, 12, 15, 227, 119, 12, 15, 227, 118, 12, + 15, 227, 117, 12, 15, 227, 116, 12, 15, 227, 115, 12, 15, 227, 114, 12, + 15, 227, 113, 12, 15, 227, 112, 12, 15, 227, 111, 12, 15, 227, 110, 12, + 15, 227, 109, 12, 15, 227, 108, 12, 15, 227, 107, 12, 15, 227, 106, 12, + 15, 227, 105, 12, 15, 227, 104, 12, 15, 227, 103, 12, 15, 227, 102, 12, + 15, 227, 101, 12, 15, 227, 100, 12, 15, 227, 99, 12, 15, 227, 98, 12, 15, + 227, 97, 12, 15, 227, 96, 12, 15, 227, 95, 12, 15, 227, 94, 12, 15, 227, + 93, 12, 15, 227, 92, 12, 15, 227, 91, 12, 15, 227, 90, 12, 15, 227, 89, + 12, 15, 227, 88, 12, 15, 227, 87, 12, 15, 227, 86, 12, 15, 227, 85, 12, + 15, 227, 84, 12, 15, 227, 83, 12, 15, 227, 82, 12, 15, 227, 81, 12, 15, + 227, 80, 12, 15, 227, 79, 12, 15, 227, 78, 12, 15, 227, 77, 12, 15, 227, + 76, 12, 15, 227, 75, 12, 15, 227, 74, 12, 15, 227, 73, 12, 15, 227, 72, + 12, 15, 227, 71, 12, 15, 227, 70, 12, 15, 227, 69, 12, 15, 227, 68, 12, + 15, 227, 67, 12, 15, 227, 66, 12, 15, 227, 65, 12, 15, 227, 64, 12, 15, + 227, 63, 12, 15, 227, 62, 12, 15, 227, 61, 12, 15, 227, 60, 12, 15, 227, + 59, 12, 15, 227, 58, 12, 15, 227, 57, 12, 15, 227, 56, 12, 15, 227, 55, + 12, 15, 227, 54, 12, 15, 227, 53, 12, 15, 227, 52, 12, 15, 227, 51, 12, + 15, 227, 50, 12, 15, 227, 49, 12, 15, 227, 48, 12, 15, 227, 47, 12, 15, + 227, 46, 12, 15, 227, 45, 12, 15, 227, 44, 12, 15, 227, 43, 12, 15, 227, + 42, 12, 15, 227, 41, 12, 15, 227, 40, 12, 15, 227, 39, 12, 15, 227, 38, + 12, 15, 227, 37, 12, 15, 227, 36, 12, 15, 227, 35, 12, 15, 227, 34, 12, + 15, 227, 33, 12, 15, 227, 32, 12, 15, 227, 31, 12, 15, 227, 30, 12, 15, + 227, 29, 12, 15, 227, 28, 12, 15, 227, 27, 12, 15, 227, 26, 12, 15, 227, + 25, 12, 15, 227, 24, 12, 15, 227, 23, 12, 15, 227, 22, 12, 15, 227, 21, + 12, 15, 227, 20, 12, 15, 227, 19, 12, 15, 227, 18, 12, 15, 227, 17, 12, + 15, 227, 16, 12, 15, 227, 15, 12, 15, 227, 14, 12, 15, 227, 13, 12, 15, + 227, 12, 12, 15, 227, 11, 12, 15, 227, 10, 12, 15, 227, 9, 12, 15, 227, + 8, 12, 15, 227, 7, 12, 15, 227, 6, 12, 15, 227, 5, 12, 15, 227, 4, 12, + 15, 227, 3, 12, 15, 227, 2, 12, 15, 227, 1, 12, 15, 227, 0, 12, 15, 226, + 255, 12, 15, 226, 254, 12, 15, 226, 253, 12, 15, 226, 252, 12, 15, 226, + 251, 12, 15, 226, 250, 12, 15, 226, 249, 12, 15, 226, 248, 12, 15, 226, + 247, 12, 15, 226, 246, 12, 15, 226, 245, 12, 15, 226, 244, 12, 15, 226, + 243, 12, 15, 226, 242, 12, 15, 226, 241, 12, 15, 226, 240, 12, 15, 226, + 239, 12, 15, 226, 238, 12, 15, 226, 237, 12, 15, 226, 236, 12, 15, 226, + 235, 12, 15, 226, 234, 12, 15, 226, 233, 12, 15, 226, 232, 12, 15, 226, + 231, 12, 15, 226, 230, 12, 15, 226, 229, 12, 15, 226, 228, 12, 15, 226, + 227, 12, 15, 226, 226, 12, 15, 226, 225, 12, 15, 226, 224, 12, 15, 226, + 223, 12, 15, 226, 222, 12, 15, 226, 221, 12, 15, 226, 220, 12, 15, 226, + 219, 12, 15, 226, 218, 12, 15, 226, 217, 12, 15, 226, 216, 12, 15, 226, + 215, 12, 15, 226, 214, 12, 15, 226, 213, 12, 15, 226, 212, 12, 15, 226, + 211, 12, 15, 226, 210, 12, 15, 226, 209, 12, 15, 226, 208, 12, 15, 226, + 207, 12, 15, 226, 206, 12, 15, 226, 205, 12, 15, 226, 204, 12, 15, 226, + 203, 12, 15, 226, 202, 12, 15, 226, 201, 12, 15, 226, 200, 12, 15, 226, + 199, 12, 15, 226, 198, 12, 15, 226, 197, 12, 15, 226, 196, 12, 15, 226, + 195, 12, 15, 226, 194, 12, 15, 226, 193, 12, 15, 226, 192, 12, 15, 226, + 191, 12, 15, 226, 190, 12, 15, 226, 189, 12, 15, 226, 188, 12, 15, 226, + 187, 12, 15, 226, 186, 12, 15, 226, 185, 12, 15, 226, 184, 12, 15, 226, + 183, 12, 15, 226, 182, 12, 15, 226, 181, 12, 15, 226, 180, 12, 15, 226, + 179, 12, 15, 226, 178, 12, 15, 226, 177, 12, 15, 226, 176, 12, 15, 226, + 175, 12, 15, 226, 174, 12, 15, 226, 173, 12, 15, 226, 172, 12, 15, 226, + 171, 12, 15, 226, 170, 12, 15, 226, 169, 12, 15, 226, 168, 12, 15, 226, + 167, 12, 15, 226, 166, 12, 15, 226, 165, 12, 15, 226, 164, 12, 15, 226, + 163, 12, 15, 226, 162, 12, 15, 226, 161, 12, 15, 226, 160, 12, 15, 226, + 159, 12, 15, 226, 158, 12, 15, 226, 157, 12, 15, 226, 156, 12, 15, 226, + 155, 12, 15, 226, 154, 12, 15, 226, 153, 12, 15, 226, 152, 12, 15, 226, + 151, 12, 15, 226, 150, 12, 15, 226, 149, 12, 15, 226, 148, 12, 15, 226, + 147, 12, 15, 226, 146, 12, 15, 226, 145, 12, 15, 226, 144, 12, 15, 226, + 143, 12, 15, 226, 142, 12, 15, 226, 141, 12, 15, 226, 140, 12, 15, 226, + 139, 12, 15, 226, 138, 12, 15, 226, 137, 12, 15, 226, 136, 12, 15, 226, + 135, 12, 15, 226, 134, 12, 15, 226, 133, 12, 15, 226, 132, 12, 15, 226, + 131, 12, 15, 226, 130, 12, 15, 226, 129, 12, 15, 226, 128, 12, 15, 226, + 127, 12, 15, 226, 126, 12, 15, 226, 125, 12, 15, 226, 124, 12, 15, 226, + 123, 12, 15, 226, 122, 12, 15, 226, 121, 12, 15, 226, 120, 12, 15, 226, + 119, 12, 15, 226, 118, 12, 15, 226, 117, 12, 15, 226, 116, 12, 15, 226, + 115, 12, 15, 226, 114, 12, 15, 226, 113, 12, 15, 226, 112, 12, 15, 226, + 111, 12, 15, 226, 110, 12, 15, 226, 109, 12, 15, 226, 108, 12, 15, 226, + 107, 12, 15, 226, 106, 12, 15, 226, 105, 12, 15, 226, 104, 12, 15, 226, + 103, 12, 15, 226, 102, 12, 15, 226, 101, 12, 15, 226, 100, 12, 15, 226, + 99, 12, 15, 226, 98, 12, 15, 226, 97, 12, 15, 226, 96, 12, 15, 226, 95, + 12, 15, 226, 94, 12, 15, 226, 93, 12, 15, 226, 92, 12, 15, 226, 91, 12, + 15, 226, 90, 12, 15, 226, 89, 12, 15, 226, 88, 12, 15, 226, 87, 12, 15, + 226, 86, 12, 15, 226, 85, 12, 15, 226, 84, 12, 15, 226, 83, 12, 15, 226, + 82, 12, 15, 226, 81, 12, 15, 226, 80, 12, 15, 226, 79, 12, 15, 226, 78, + 12, 15, 226, 77, 12, 15, 226, 76, 12, 15, 226, 75, 12, 15, 226, 74, 12, + 15, 226, 73, 12, 15, 226, 72, 12, 15, 226, 71, 12, 15, 226, 70, 12, 15, + 226, 69, 12, 15, 226, 68, 12, 15, 226, 67, 12, 15, 226, 66, 12, 15, 226, + 65, 12, 15, 226, 64, 12, 15, 226, 63, 12, 15, 226, 62, 12, 15, 226, 61, + 12, 15, 226, 60, 12, 15, 226, 59, 12, 15, 226, 58, 12, 15, 226, 57, 12, + 15, 226, 56, 12, 15, 226, 55, 12, 15, 226, 54, 12, 15, 226, 53, 12, 15, + 226, 52, 12, 15, 226, 51, 12, 15, 226, 50, 12, 15, 226, 49, 12, 15, 226, + 48, 12, 15, 226, 47, 12, 15, 226, 46, 12, 15, 226, 45, 12, 15, 226, 44, + 12, 15, 226, 43, 12, 15, 226, 42, 12, 15, 226, 41, 12, 15, 226, 40, 12, + 15, 226, 39, 12, 15, 226, 38, 12, 15, 226, 37, 12, 15, 226, 36, 12, 15, + 226, 35, 12, 15, 226, 34, 12, 15, 226, 33, 12, 15, 226, 32, 12, 15, 226, + 31, 12, 15, 226, 30, 12, 15, 226, 29, 12, 15, 226, 28, 12, 15, 226, 27, + 12, 15, 226, 26, 12, 15, 226, 25, 12, 15, 226, 24, 12, 15, 226, 23, 12, + 15, 226, 22, 12, 15, 226, 21, 12, 15, 226, 20, 12, 15, 226, 19, 12, 15, + 226, 18, 12, 15, 226, 17, 12, 15, 226, 16, 12, 15, 226, 15, 12, 15, 226, + 14, 12, 15, 226, 13, 12, 15, 226, 12, 12, 15, 226, 11, 12, 15, 226, 10, + 12, 15, 226, 9, 12, 15, 226, 8, 12, 15, 226, 7, 12, 15, 226, 6, 12, 15, + 226, 5, 12, 15, 226, 4, 12, 15, 226, 3, 12, 15, 226, 2, 12, 15, 226, 1, + 12, 15, 226, 0, 12, 15, 225, 255, 12, 15, 225, 254, 12, 15, 225, 253, 12, + 15, 225, 252, 12, 15, 225, 251, 12, 15, 225, 250, 12, 15, 225, 249, 12, + 15, 225, 248, 12, 15, 225, 247, 12, 15, 225, 246, 12, 15, 225, 245, 12, + 15, 225, 244, 12, 15, 225, 243, 12, 15, 225, 242, 220, 22, 199, 223, 199, + 224, 201, 248, 199, 224, 233, 218, 77, 199, 224, 207, 254, 77, 199, 224, + 31, 56, 199, 224, 236, 157, 56, 199, 224, 210, 15, 56, 199, 224, 251, + 139, 199, 224, 251, 51, 199, 224, 45, 210, 115, 199, 224, 50, 210, 115, + 199, 224, 250, 195, 199, 224, 108, 56, 199, 224, 242, 76, 199, 224, 228, + 89, 199, 224, 232, 82, 201, 64, 199, 224, 202, 24, 199, 224, 17, 191, 77, + 199, 224, 17, 107, 199, 224, 17, 109, 199, 224, 17, 138, 199, 224, 17, + 134, 199, 224, 17, 150, 199, 224, 17, 169, 199, 224, 17, 175, 199, 224, + 17, 171, 199, 224, 17, 178, 199, 224, 242, 85, 199, 224, 204, 26, 199, + 224, 219, 182, 56, 199, 224, 234, 45, 56, 199, 224, 230, 206, 56, 199, + 224, 208, 15, 77, 199, 224, 242, 74, 250, 184, 199, 224, 8, 6, 1, 65, + 199, 224, 8, 6, 1, 250, 122, 199, 224, 8, 6, 1, 247, 195, 199, 224, 8, 6, + 1, 238, 129, 199, 224, 8, 6, 1, 71, 199, 224, 8, 6, 1, 233, 177, 199, + 224, 8, 6, 1, 232, 53, 199, 224, 8, 6, 1, 230, 118, 199, 224, 8, 6, 1, + 68, 199, 224, 8, 6, 1, 223, 37, 199, 224, 8, 6, 1, 222, 154, 199, 224, 8, + 6, 1, 172, 199, 224, 8, 6, 1, 218, 170, 199, 224, 8, 6, 1, 215, 63, 199, + 224, 8, 6, 1, 74, 199, 224, 8, 6, 1, 210, 238, 199, 224, 8, 6, 1, 208, + 106, 199, 224, 8, 6, 1, 146, 199, 224, 8, 6, 1, 206, 9, 199, 224, 8, 6, + 1, 200, 43, 199, 224, 8, 6, 1, 66, 199, 224, 8, 6, 1, 196, 12, 199, 224, + 8, 6, 1, 193, 224, 199, 224, 8, 6, 1, 192, 235, 199, 224, 8, 6, 1, 192, + 159, 199, 224, 8, 6, 1, 191, 166, 199, 224, 45, 51, 248, 55, 199, 224, + 207, 20, 202, 24, 199, 224, 50, 51, 248, 55, 199, 224, 243, 4, 252, 62, + 199, 224, 130, 219, 114, 199, 224, 230, 213, 252, 62, 199, 224, 8, 2, 1, + 65, 199, 224, 8, 2, 1, 250, 122, 199, 224, 8, 2, 1, 247, 195, 199, 224, + 8, 2, 1, 238, 129, 199, 224, 8, 2, 1, 71, 199, 224, 8, 2, 1, 233, 177, + 199, 224, 8, 2, 1, 232, 53, 199, 224, 8, 2, 1, 230, 118, 199, 224, 8, 2, + 1, 68, 199, 224, 8, 2, 1, 223, 37, 199, 224, 8, 2, 1, 222, 154, 199, 224, + 8, 2, 1, 172, 199, 224, 8, 2, 1, 218, 170, 199, 224, 8, 2, 1, 215, 63, + 199, 224, 8, 2, 1, 74, 199, 224, 8, 2, 1, 210, 238, 199, 224, 8, 2, 1, + 208, 106, 199, 224, 8, 2, 1, 146, 199, 224, 8, 2, 1, 206, 9, 199, 224, 8, + 2, 1, 200, 43, 199, 224, 8, 2, 1, 66, 199, 224, 8, 2, 1, 196, 12, 199, + 224, 8, 2, 1, 193, 224, 199, 224, 8, 2, 1, 192, 235, 199, 224, 8, 2, 1, + 192, 159, 199, 224, 8, 2, 1, 191, 166, 199, 224, 45, 238, 173, 248, 55, + 199, 224, 81, 219, 114, 199, 224, 50, 238, 173, 248, 55, 199, 224, 198, + 152, 247, 129, 199, 223, 67, 204, 212, 67, 204, 201, 67, 204, 190, 67, + 204, 178, 67, 204, 167, 67, 204, 156, 67, 204, 145, 67, 204, 134, 67, + 204, 123, 67, 204, 115, 67, 204, 114, 67, 204, 113, 67, 204, 112, 67, + 204, 110, 67, 204, 109, 67, 204, 108, 67, 204, 107, 67, 204, 106, 67, + 204, 105, 67, 204, 104, 67, 204, 103, 67, 204, 102, 67, 204, 101, 67, + 204, 99, 67, 204, 98, 67, 204, 97, 67, 204, 96, 67, 204, 95, 67, 204, 94, + 67, 204, 93, 67, 204, 92, 67, 204, 91, 67, 204, 90, 67, 204, 88, 67, 204, + 87, 67, 204, 86, 67, 204, 85, 67, 204, 84, 67, 204, 83, 67, 204, 82, 67, + 204, 81, 67, 204, 80, 67, 204, 79, 67, 204, 77, 67, 204, 76, 67, 204, 75, + 67, 204, 74, 67, 204, 73, 67, 204, 72, 67, 204, 71, 67, 204, 70, 67, 204, + 69, 67, 204, 68, 67, 204, 66, 67, 204, 65, 67, 204, 64, 67, 204, 63, 67, + 204, 62, 67, 204, 61, 67, 204, 60, 67, 204, 59, 67, 204, 58, 67, 204, 57, + 67, 204, 55, 67, 204, 54, 67, 204, 53, 67, 204, 52, 67, 204, 51, 67, 204, + 50, 67, 204, 49, 67, 204, 48, 67, 204, 47, 67, 204, 46, 67, 204, 44, 67, + 204, 43, 67, 204, 42, 67, 204, 41, 67, 204, 40, 67, 204, 39, 67, 204, 38, + 67, 204, 37, 67, 204, 36, 67, 204, 35, 67, 205, 32, 67, 205, 31, 67, 205, + 30, 67, 205, 29, 67, 205, 28, 67, 205, 27, 67, 205, 26, 67, 205, 25, 67, + 205, 24, 67, 205, 23, 67, 205, 21, 67, 205, 20, 67, 205, 19, 67, 205, 18, + 67, 205, 17, 67, 205, 16, 67, 205, 15, 67, 205, 14, 67, 205, 13, 67, 205, + 12, 67, 205, 10, 67, 205, 9, 67, 205, 8, 67, 205, 7, 67, 205, 6, 67, 205, + 5, 67, 205, 4, 67, 205, 3, 67, 205, 2, 67, 205, 1, 67, 204, 255, 67, 204, + 254, 67, 204, 253, 67, 204, 252, 67, 204, 251, 67, 204, 250, 67, 204, + 249, 67, 204, 248, 67, 204, 247, 67, 204, 246, 67, 204, 244, 67, 204, + 243, 67, 204, 242, 67, 204, 241, 67, 204, 240, 67, 204, 239, 67, 204, + 238, 67, 204, 237, 67, 204, 236, 67, 204, 235, 67, 204, 233, 67, 204, + 232, 67, 204, 231, 67, 204, 230, 67, 204, 229, 67, 204, 228, 67, 204, + 227, 67, 204, 226, 67, 204, 225, 67, 204, 224, 67, 204, 222, 67, 204, + 221, 67, 204, 220, 67, 204, 219, 67, 204, 218, 67, 204, 217, 67, 204, + 216, 67, 204, 215, 67, 204, 214, 67, 204, 213, 67, 204, 211, 67, 204, + 210, 67, 204, 209, 67, 204, 208, 67, 204, 207, 67, 204, 206, 67, 204, + 205, 67, 204, 204, 67, 204, 203, 67, 204, 202, 67, 204, 200, 67, 204, + 199, 67, 204, 198, 67, 204, 197, 67, 204, 196, 67, 204, 195, 67, 204, + 194, 67, 204, 193, 67, 204, 192, 67, 204, 191, 67, 204, 189, 67, 204, + 188, 67, 204, 187, 67, 204, 186, 67, 204, 185, 67, 204, 184, 67, 204, + 183, 67, 204, 182, 67, 204, 181, 67, 204, 180, 67, 204, 177, 67, 204, + 176, 67, 204, 175, 67, 204, 174, 67, 204, 173, 67, 204, 172, 67, 204, + 171, 67, 204, 170, 67, 204, 169, 67, 204, 168, 67, 204, 166, 67, 204, + 165, 67, 204, 164, 67, 204, 163, 67, 204, 162, 67, 204, 161, 67, 204, + 160, 67, 204, 159, 67, 204, 158, 67, 204, 157, 67, 204, 155, 67, 204, + 154, 67, 204, 153, 67, 204, 152, 67, 204, 151, 67, 204, 150, 67, 204, + 149, 67, 204, 148, 67, 204, 147, 67, 204, 146, 67, 204, 144, 67, 204, + 143, 67, 204, 142, 67, 204, 141, 67, 204, 140, 67, 204, 139, 67, 204, + 138, 67, 204, 137, 67, 204, 136, 67, 204, 135, 67, 204, 133, 67, 204, + 132, 67, 204, 131, 67, 204, 130, 67, 204, 129, 67, 204, 128, 67, 204, + 127, 67, 204, 126, 67, 204, 125, 67, 204, 124, 67, 204, 122, 67, 204, + 121, 67, 204, 120, 67, 204, 119, 67, 204, 118, 67, 204, 117, 67, 204, + 116, 212, 140, 212, 142, 201, 99, 79, 229, 234, 202, 28, 201, 99, 79, + 199, 53, 201, 7, 234, 97, 79, 199, 53, 233, 246, 234, 97, 79, 198, 11, + 234, 59, 234, 83, 234, 84, 252, 53, 252, 54, 251, 191, 248, 240, 249, + 142, 248, 18, 246, 242, 199, 230, 228, 243, 199, 230, 228, 167, 199, 236, + 219, 115, 233, 52, 214, 82, 219, 114, 234, 97, 79, 219, 114, 219, 163, + 213, 107, 234, 62, 219, 115, 199, 230, 81, 199, 230, 193, 251, 232, 148, + 233, 52, 233, 29, 247, 90, 207, 23, 238, 238, 203, 78, 211, 16, 219, 35, + 107, 202, 47, 203, 78, 223, 164, 219, 35, 191, 77, 202, 223, 237, 212, + 219, 105, 234, 16, 236, 187, 237, 77, 239, 24, 107, 237, 201, 237, 77, + 239, 24, 109, 237, 200, 237, 77, 239, 24, 138, 237, 199, 237, 77, 239, + 24, 134, 237, 198, 214, 108, 252, 53, 214, 235, 200, 69, 223, 230, 200, + 73, 234, 97, 79, 198, 12, 248, 131, 233, 254, 247, 128, 247, 130, 234, + 97, 79, 216, 214, 234, 60, 234, 116, 200, 227, 200, 246, 234, 16, 234, + 17, 223, 139, 204, 12, 134, 233, 9, 204, 11, 232, 92, 223, 139, 204, 12, + 138, 230, 189, 204, 11, 230, 186, 223, 139, 204, 12, 109, 207, 100, 204, + 11, 206, 75, 223, 139, 204, 12, 107, 196, 91, 204, 11, 196, 45, 201, 251, + 237, 118, 237, 120, 210, 210, 246, 241, 210, 212, 137, 211, 160, 208, + 222, 228, 246, 248, 44, 210, 3, 229, 194, 248, 60, 213, 46, 248, 44, 229, + 194, 214, 193, 223, 150, 223, 152, 214, 75, 219, 114, 214, 106, 201, 99, + 79, 205, 37, 251, 10, 201, 176, 234, 97, 79, 205, 37, 251, 10, 234, 19, + 246, 242, 199, 231, 203, 253, 228, 243, 199, 231, 203, 253, 228, 164, + 246, 242, 199, 231, 4, 222, 166, 228, 243, 199, 231, 4, 222, 166, 228, + 165, 219, 115, 199, 231, 203, 253, 81, 199, 231, 203, 253, 193, 250, 210, + 107, 219, 115, 232, 134, 210, 107, 219, 115, 235, 125, 209, 96, 210, 107, + 219, 115, 249, 141, 210, 107, 219, 115, 196, 77, 209, 90, 207, 20, 219, + 115, 233, 52, 207, 20, 223, 150, 207, 2, 202, 171, 203, 78, 109, 202, + 168, 201, 178, 202, 171, 203, 78, 138, 202, 167, 201, 177, 237, 77, 239, + 24, 201, 31, 237, 196, 208, 207, 196, 44, 107, 208, 207, 196, 42, 208, + 166, 208, 207, 196, 44, 109, 208, 207, 196, 41, 208, 165, 203, 254, 198, + 10, 201, 96, 201, 14, 247, 129, 246, 241, 247, 63, 216, 171, 193, 171, + 215, 83, 201, 99, 79, 230, 174, 251, 10, 201, 99, 79, 208, 184, 251, 10, + 201, 250, 234, 97, 79, 230, 174, 251, 10, 234, 97, 79, 208, 184, 251, 10, + 234, 57, 201, 99, 79, 201, 31, 202, 10, 202, 171, 230, 218, 246, 242, + 223, 98, 203, 171, 202, 171, 246, 242, 223, 98, 205, 86, 239, 24, 204, 8, + 223, 98, 238, 198, 201, 32, 199, 80, 201, 119, 211, 70, 200, 58, 242, 75, + 211, 36, 208, 208, 216, 170, 209, 78, 251, 47, 208, 200, 242, 75, 251, + 64, 214, 181, 202, 232, 8, 6, 1, 231, 93, 8, 2, 1, 231, 93, 247, 6, 9, 2, + 137, 34, 131, 4, 99, 249, 82, 251, 168, 200, 63, 200, 233, 242, 86, 202, + 111, 219, 226, 222, 83, 1, 219, 64, 220, 19, 1, 232, 178, 232, 168, 220, + 19, 1, 232, 178, 233, 64, 220, 19, 1, 206, 163, 220, 19, 1, 219, 45, 86, + 87, 248, 143, 203, 51, 231, 56, 216, 120, 207, 10, 30, 125, 192, 54, 30, + 125, 192, 50, 30, 125, 201, 154, 30, 125, 192, 55, 232, 68, 232, 67, 232, + 66, 215, 85, 232, 65, 200, 197, 1, 251, 16, 68, 190, 232, 190, 233, 190, + 235, 218, 231, 206, 171, 218, 233, 206, 173, 210, 68, 218, 230, 206, 170, + 213, 77, 216, 18, 193, 50, 218, 232, 206, 172, 232, 91, 210, 67, 193, + 111, 234, 121, 232, 78, 216, 94, 211, 107, 196, 46, 113, 216, 94, 237, + 218, 113, 118, 197, 240, 64, 4, 55, 81, 106, 96, 197, 240, 64, 4, 55, 81, + 106, 11, 5, 223, 53, 77, 80, 1, 221, 208, 219, 75, 194, 251, 194, 140, + 194, 72, 194, 61, 194, 50, 194, 39, 194, 28, 194, 17, 194, 6, 194, 250, + 194, 239, 194, 228, 194, 217, 194, 206, 194, 195, 194, 184, 208, 223, + 232, 148, 40, 81, 50, 63, 219, 189, 248, 55, 247, 200, 211, 53, 77, 248, + 102, 190, 234, 10, 3, 212, 150, 199, 84, 10, 3, 212, 150, 139, 212, 150, + 247, 233, 139, 247, 232, 216, 220, 6, 1, 230, 118, 216, 220, 6, 1, 214, + 72, 216, 220, 2, 1, 230, 118, 216, 220, 2, 1, 214, 72, 61, 1, 235, 16, + 73, 37, 16, 232, 90, 202, 107, 243, 54, 195, 164, 194, 173, 194, 162, + 194, 151, 194, 139, 194, 128, 194, 117, 194, 106, 194, 95, 194, 84, 194, + 76, 194, 75, 194, 74, 194, 73, 194, 71, 194, 70, 194, 69, 194, 68, 194, + 67, 194, 66, 194, 65, 194, 64, 194, 63, 194, 62, 194, 60, 194, 59, 194, + 58, 194, 57, 194, 56, 194, 55, 194, 54, 194, 53, 194, 52, 194, 51, 194, + 49, 194, 48, 194, 47, 194, 46, 194, 45, 194, 44, 194, 43, 194, 42, 194, + 41, 194, 40, 194, 38, 194, 37, 194, 36, 194, 35, 194, 34, 194, 33, 194, + 32, 194, 31, 194, 30, 194, 29, 194, 27, 194, 26, 194, 25, 194, 24, 194, + 23, 194, 22, 194, 21, 194, 20, 194, 19, 194, 18, 194, 16, 194, 15, 194, + 14, 194, 13, 194, 12, 194, 11, 194, 10, 194, 9, 194, 8, 194, 7, 194, 5, + 194, 4, 194, 3, 194, 2, 194, 1, 194, 0, 193, 255, 193, 254, 193, 253, + 193, 252, 194, 249, 194, 248, 194, 247, 194, 246, 194, 245, 194, 244, + 194, 243, 194, 242, 194, 241, 194, 240, 194, 238, 194, 237, 194, 236, + 194, 235, 194, 234, 194, 233, 194, 232, 194, 231, 194, 230, 194, 229, + 194, 227, 194, 226, 194, 225, 194, 224, 194, 223, 194, 222, 194, 221, + 194, 220, 194, 219, 194, 218, 194, 216, 194, 215, 194, 214, 194, 213, + 194, 212, 194, 211, 194, 210, 194, 209, 194, 208, 194, 207, 194, 205, + 194, 204, 194, 203, 194, 202, 194, 201, 194, 200, 194, 199, 194, 198, + 194, 197, 194, 196, 194, 194, 194, 193, 194, 192, 194, 191, 194, 190, + 194, 189, 194, 188, 194, 187, 194, 186, 194, 185, 194, 183, 194, 182, + 194, 181, 194, 180, 194, 179, 194, 178, 194, 177, 194, 176, 194, 175, + 194, 174, 194, 172, 194, 171, 194, 170, 194, 169, 194, 168, 194, 167, + 194, 166, 194, 165, 194, 164, 194, 163, 194, 161, 194, 160, 194, 159, + 194, 158, 194, 157, 194, 156, 194, 155, 194, 154, 194, 153, 194, 152, + 194, 150, 194, 149, 194, 148, 194, 147, 194, 146, 194, 145, 194, 144, + 194, 143, 194, 142, 194, 141, 194, 138, 194, 137, 194, 136, 194, 135, + 194, 134, 194, 133, 194, 132, 194, 131, 194, 130, 194, 129, 194, 127, + 194, 126, 194, 125, 194, 124, 194, 123, 194, 122, 194, 121, 194, 120, + 194, 119, 194, 118, 194, 116, 194, 115, 194, 114, 194, 113, 194, 112, + 194, 111, 194, 110, 194, 109, 194, 108, 194, 107, 194, 105, 194, 104, + 194, 103, 194, 102, 194, 101, 194, 100, 194, 99, 194, 98, 194, 97, 194, + 96, 194, 94, 194, 93, 194, 92, 194, 91, 194, 90, 194, 89, 194, 88, 194, + 87, 194, 86, 194, 85, 194, 83, 194, 82, 194, 81, 194, 80, 194, 79, 194, + 78, 194, 77, 221, 221, 31, 56, 221, 221, 250, 195, 221, 221, 17, 191, 77, + 221, 221, 17, 107, 221, 221, 17, 109, 221, 221, 17, 138, 221, 221, 17, + 134, 221, 221, 17, 150, 221, 221, 17, 169, 221, 221, 17, 175, 221, 221, + 17, 171, 221, 221, 17, 178, 8, 6, 1, 42, 4, 217, 149, 23, 230, 212, 8, 2, + 1, 42, 4, 217, 149, 23, 230, 212, 8, 6, 1, 228, 76, 4, 217, 149, 23, 230, + 212, 8, 2, 1, 228, 76, 4, 217, 149, 23, 230, 212, 8, 6, 1, 126, 4, 217, + 149, 23, 230, 212, 8, 2, 1, 126, 4, 217, 149, 23, 230, 212, 8, 6, 1, 235, + 17, 4, 81, 219, 115, 60, 8, 2, 1, 235, 17, 4, 81, 219, 115, 60, 8, 6, 1, + 235, 17, 4, 81, 219, 115, 248, 235, 23, 230, 212, 8, 2, 1, 235, 17, 4, + 81, 219, 115, 248, 235, 23, 230, 212, 8, 6, 1, 235, 17, 4, 81, 219, 115, + 248, 235, 23, 252, 48, 8, 2, 1, 235, 17, 4, 81, 219, 115, 248, 235, 23, + 252, 48, 8, 6, 1, 187, 4, 81, 219, 115, 60, 8, 2, 1, 187, 4, 81, 219, + 115, 60, 8, 6, 1, 187, 4, 81, 219, 115, 248, 235, 23, 230, 212, 8, 2, 1, + 187, 4, 81, 219, 115, 248, 235, 23, 230, 212, 8, 6, 1, 187, 4, 81, 219, + 115, 248, 235, 23, 252, 48, 8, 2, 1, 187, 4, 81, 219, 115, 248, 235, 23, + 252, 48, 8, 6, 1, 206, 10, 4, 81, 219, 115, 60, 8, 2, 1, 206, 10, 4, 81, + 219, 115, 60, 8, 6, 1, 235, 17, 4, 243, 4, 23, 217, 148, 8, 2, 1, 235, + 17, 4, 243, 4, 23, 217, 148, 8, 6, 1, 235, 17, 4, 243, 4, 23, 247, 94, 8, + 2, 1, 235, 17, 4, 243, 4, 23, 247, 94, 8, 2, 1, 228, 76, 4, 75, 93, 23, + 252, 48, 8, 2, 1, 214, 73, 4, 198, 153, 58, 8, 6, 1, 42, 4, 211, 141, 23, + 252, 48, 8, 2, 1, 42, 4, 211, 141, 23, 252, 48, 8, 6, 1, 42, 4, 211, 141, + 23, 198, 152, 8, 2, 1, 42, 4, 211, 141, 23, 198, 152, 8, 6, 1, 235, 17, + 4, 211, 141, 23, 252, 48, 8, 2, 1, 235, 17, 4, 211, 141, 23, 252, 48, 8, + 6, 1, 235, 17, 4, 211, 141, 23, 198, 152, 8, 2, 1, 235, 17, 4, 211, 141, + 23, 198, 152, 8, 6, 1, 235, 17, 4, 75, 93, 23, 252, 48, 8, 2, 1, 235, 17, + 4, 75, 93, 23, 252, 48, 8, 6, 1, 235, 17, 4, 75, 93, 23, 198, 152, 8, 2, + 1, 235, 17, 4, 75, 93, 23, 198, 152, 8, 2, 1, 228, 76, 4, 75, 93, 23, + 230, 212, 8, 2, 1, 228, 76, 4, 75, 93, 23, 198, 152, 8, 6, 1, 228, 76, 4, + 211, 141, 23, 252, 48, 8, 2, 1, 228, 76, 4, 211, 141, 23, 75, 93, 23, + 252, 48, 8, 6, 1, 228, 76, 4, 211, 141, 23, 198, 152, 8, 2, 1, 228, 76, + 4, 211, 141, 23, 75, 93, 23, 198, 152, 8, 6, 1, 223, 38, 4, 198, 152, 8, + 2, 1, 223, 38, 4, 75, 93, 23, 198, 152, 8, 6, 1, 220, 145, 4, 198, 152, + 8, 2, 1, 220, 145, 4, 198, 152, 8, 6, 1, 218, 171, 4, 198, 152, 8, 2, 1, + 218, 171, 4, 198, 152, 8, 6, 1, 207, 224, 4, 198, 152, 8, 2, 1, 207, 224, + 4, 198, 152, 8, 6, 1, 126, 4, 211, 141, 23, 252, 48, 8, 2, 1, 126, 4, + 211, 141, 23, 252, 48, 8, 6, 1, 126, 4, 211, 141, 23, 198, 152, 8, 2, 1, + 126, 4, 211, 141, 23, 198, 152, 8, 6, 1, 126, 4, 217, 149, 23, 252, 48, + 8, 2, 1, 126, 4, 217, 149, 23, 252, 48, 8, 6, 1, 126, 4, 217, 149, 23, + 198, 152, 8, 2, 1, 126, 4, 217, 149, 23, 198, 152, 8, 2, 1, 252, 28, 4, + 230, 212, 8, 2, 1, 211, 79, 187, 4, 230, 212, 8, 2, 1, 211, 79, 187, 4, + 252, 48, 8, 2, 1, 154, 196, 13, 4, 230, 212, 8, 2, 1, 154, 196, 13, 4, + 252, 48, 8, 2, 1, 205, 88, 4, 230, 212, 8, 2, 1, 205, 88, 4, 252, 48, 8, + 2, 1, 228, 252, 205, 88, 4, 230, 212, 8, 2, 1, 228, 252, 205, 88, 4, 252, + 48, 9, 204, 8, 99, 4, 230, 60, 93, 4, 251, 194, 9, 204, 8, 99, 4, 230, + 60, 93, 4, 193, 133, 9, 204, 8, 99, 4, 230, 60, 93, 4, 131, 217, 101, 9, + 204, 8, 99, 4, 230, 60, 93, 4, 211, 153, 9, 204, 8, 99, 4, 230, 60, 93, + 4, 66, 9, 204, 8, 99, 4, 230, 60, 93, 4, 191, 225, 9, 204, 8, 99, 4, 230, + 60, 93, 4, 71, 9, 204, 8, 99, 4, 230, 60, 93, 4, 252, 27, 9, 204, 8, 213, + 27, 4, 222, 6, 100, 204, 8, 40, 1, 208, 98, 100, 204, 8, 40, 1, 221, 195, + 100, 204, 8, 40, 1, 231, 68, 100, 204, 8, 40, 1, 191, 123, 100, 204, 8, + 40, 1, 237, 182, 100, 204, 8, 40, 1, 207, 7, 100, 204, 8, 40, 1, 233, + 111, 100, 204, 8, 40, 1, 191, 175, 248, 227, 204, 8, 40, 1, 206, 110, + 248, 227, 204, 8, 40, 1, 207, 7, 248, 227, 204, 8, 40, 1, 191, 175, 230, + 146, 204, 8, 40, 1, 219, 75, 230, 146, 204, 8, 40, 1, 203, 166, 230, 146, + 204, 8, 40, 1, 221, 195, 230, 146, 204, 8, 40, 1, 231, 68, 230, 146, 204, + 8, 40, 1, 191, 123, 230, 146, 204, 8, 40, 1, 233, 111, 211, 47, 204, 8, + 40, 1, 206, 110, 211, 47, 204, 8, 40, 1, 207, 7, 248, 227, 1, 221, 189, + 44, 120, 222, 154, 44, 120, 214, 72, 44, 120, 247, 195, 44, 120, 212, + 105, 44, 120, 197, 135, 44, 120, 213, 82, 44, 120, 200, 43, 44, 120, 215, + 63, 44, 120, 210, 238, 44, 120, 218, 170, 44, 120, 192, 159, 44, 120, + 146, 44, 120, 172, 44, 120, 196, 12, 44, 120, 219, 65, 44, 120, 219, 76, + 44, 120, 206, 111, 44, 120, 213, 64, 44, 120, 223, 37, 44, 120, 203, 168, + 44, 120, 201, 179, 44, 120, 206, 9, 44, 120, 230, 118, 44, 120, 220, 249, + 44, 5, 222, 129, 44, 5, 221, 168, 44, 5, 221, 147, 44, 5, 220, 234, 44, + 5, 220, 189, 44, 5, 222, 24, 44, 5, 222, 15, 44, 5, 222, 104, 44, 5, 221, + 69, 44, 5, 221, 43, 44, 5, 222, 44, 44, 5, 214, 69, 44, 5, 214, 18, 44, + 5, 214, 14, 44, 5, 213, 239, 44, 5, 213, 230, 44, 5, 214, 57, 44, 5, 214, + 55, 44, 5, 214, 66, 44, 5, 213, 251, 44, 5, 213, 246, 44, 5, 214, 59, 44, + 5, 247, 161, 44, 5, 243, 31, 44, 5, 243, 21, 44, 5, 238, 197, 44, 5, 238, + 155, 44, 5, 247, 44, 44, 5, 247, 36, 44, 5, 247, 150, 44, 5, 242, 101, + 44, 5, 239, 20, 44, 5, 247, 78, 44, 5, 212, 102, 44, 5, 212, 83, 44, 5, + 212, 77, 44, 5, 212, 60, 44, 5, 212, 52, 44, 5, 212, 92, 44, 5, 212, 91, + 44, 5, 212, 99, 44, 5, 212, 67, 44, 5, 212, 64, 44, 5, 212, 95, 44, 5, + 197, 131, 44, 5, 197, 111, 44, 5, 197, 110, 44, 5, 197, 99, 44, 5, 197, + 96, 44, 5, 197, 127, 44, 5, 197, 126, 44, 5, 197, 130, 44, 5, 197, 109, + 44, 5, 197, 108, 44, 5, 197, 129, 44, 5, 213, 80, 44, 5, 213, 66, 44, 5, + 213, 65, 44, 5, 213, 49, 44, 5, 213, 48, 44, 5, 213, 76, 44, 5, 213, 75, + 44, 5, 213, 79, 44, 5, 213, 51, 44, 5, 213, 50, 44, 5, 213, 78, 44, 5, + 199, 245, 44, 5, 198, 193, 44, 5, 198, 170, 44, 5, 197, 94, 44, 5, 197, + 49, 44, 5, 199, 145, 44, 5, 199, 121, 44, 5, 199, 217, 44, 5, 159, 44, 5, + 198, 59, 44, 5, 199, 166, 44, 5, 214, 252, 44, 5, 213, 221, 44, 5, 213, + 188, 44, 5, 212, 180, 44, 5, 212, 117, 44, 5, 214, 123, 44, 5, 214, 112, + 44, 5, 214, 238, 44, 5, 213, 45, 44, 5, 213, 28, 44, 5, 214, 207, 44, 5, + 210, 222, 44, 5, 209, 187, 44, 5, 209, 147, 44, 5, 208, 167, 44, 5, 208, + 130, 44, 5, 210, 65, 44, 5, 210, 51, 44, 5, 210, 200, 44, 5, 209, 75, 44, + 5, 209, 39, 44, 5, 210, 82, 44, 5, 217, 153, 44, 5, 216, 102, 44, 5, 216, + 63, 44, 5, 215, 157, 44, 5, 215, 95, 44, 5, 216, 234, 44, 5, 216, 213, + 44, 5, 217, 114, 44, 5, 216, 14, 44, 5, 215, 213, 44, 5, 217, 27, 44, 5, + 192, 140, 44, 5, 192, 33, 44, 5, 192, 23, 44, 5, 191, 225, 44, 5, 191, + 188, 44, 5, 192, 80, 44, 5, 192, 77, 44, 5, 192, 119, 44, 5, 192, 12, 44, + 5, 191, 246, 44, 5, 192, 91, 44, 5, 207, 180, 44, 5, 207, 2, 44, 5, 206, + 196, 44, 5, 206, 69, 44, 5, 206, 30, 44, 5, 207, 115, 44, 5, 207, 86, 44, + 5, 207, 158, 44, 5, 206, 163, 44, 5, 206, 135, 44, 5, 207, 127, 44, 5, + 220, 127, 44, 5, 219, 148, 44, 5, 219, 130, 44, 5, 218, 227, 44, 5, 218, + 196, 44, 5, 219, 240, 44, 5, 219, 230, 44, 5, 220, 98, 44, 5, 219, 45, + 44, 5, 219, 10, 44, 5, 220, 2, 44, 5, 195, 187, 44, 5, 195, 69, 44, 5, + 195, 51, 44, 5, 193, 249, 44, 5, 193, 241, 44, 5, 195, 153, 44, 5, 195, + 148, 44, 5, 195, 183, 44, 5, 195, 24, 44, 5, 195, 8, 44, 5, 195, 160, 44, + 5, 219, 63, 44, 5, 219, 58, 44, 5, 219, 57, 44, 5, 219, 54, 44, 5, 219, + 53, 44, 5, 219, 60, 44, 5, 219, 59, 44, 5, 219, 62, 44, 5, 219, 56, 44, + 5, 219, 55, 44, 5, 219, 61, 44, 5, 219, 74, 44, 5, 219, 67, 44, 5, 219, + 66, 44, 5, 219, 50, 44, 5, 219, 49, 44, 5, 219, 70, 44, 5, 219, 69, 44, + 5, 219, 73, 44, 5, 219, 52, 44, 5, 219, 51, 44, 5, 219, 71, 44, 5, 206, + 109, 44, 5, 206, 98, 44, 5, 206, 97, 44, 5, 206, 90, 44, 5, 206, 83, 44, + 5, 206, 105, 44, 5, 206, 104, 44, 5, 206, 108, 44, 5, 206, 96, 44, 5, + 206, 95, 44, 5, 206, 107, 44, 5, 213, 62, 44, 5, 213, 57, 44, 5, 213, 56, + 44, 5, 213, 53, 44, 5, 213, 52, 44, 5, 213, 59, 44, 5, 213, 58, 44, 5, + 213, 61, 44, 5, 213, 55, 44, 5, 213, 54, 44, 5, 213, 60, 44, 5, 223, 33, + 44, 5, 222, 246, 44, 5, 222, 238, 44, 5, 222, 184, 44, 5, 222, 164, 44, + 5, 223, 12, 44, 5, 223, 10, 44, 5, 223, 27, 44, 5, 222, 203, 44, 5, 222, + 193, 44, 5, 223, 19, 44, 5, 203, 161, 44, 5, 203, 82, 44, 5, 203, 77, 44, + 5, 203, 6, 44, 5, 202, 244, 44, 5, 203, 114, 44, 5, 203, 112, 44, 5, 203, + 149, 44, 5, 203, 57, 44, 5, 203, 49, 44, 5, 203, 123, 44, 5, 201, 175, + 44, 5, 201, 143, 44, 5, 201, 139, 44, 5, 201, 130, 44, 5, 201, 127, 44, + 5, 201, 149, 44, 5, 201, 148, 44, 5, 201, 174, 44, 5, 201, 135, 44, 5, + 201, 134, 44, 5, 201, 151, 44, 5, 205, 198, 44, 5, 202, 223, 44, 5, 202, + 194, 44, 5, 201, 5, 44, 5, 200, 160, 44, 5, 205, 69, 44, 5, 205, 51, 44, + 5, 205, 182, 44, 5, 202, 47, 44, 5, 202, 17, 44, 5, 205, 115, 44, 5, 230, + 93, 44, 5, 229, 160, 44, 5, 229, 132, 44, 5, 228, 161, 44, 5, 228, 130, + 44, 5, 229, 247, 44, 5, 229, 217, 44, 5, 230, 82, 44, 5, 229, 25, 44, 5, + 228, 254, 44, 5, 230, 4, 44, 5, 220, 248, 44, 5, 220, 247, 44, 5, 220, + 242, 44, 5, 220, 241, 44, 5, 220, 238, 44, 5, 220, 237, 44, 5, 220, 244, + 44, 5, 220, 243, 44, 5, 220, 246, 44, 5, 220, 240, 44, 5, 220, 239, 44, + 5, 220, 245, 44, 5, 203, 15, 166, 120, 3, 192, 105, 166, 120, 3, 207, + 146, 166, 120, 3, 207, 51, 101, 1, 196, 224, 95, 120, 3, 242, 93, 155, + 95, 120, 3, 242, 93, 221, 217, 95, 120, 3, 242, 93, 221, 69, 95, 120, 3, + 242, 93, 221, 185, 95, 120, 3, 242, 93, 213, 251, 95, 120, 3, 242, 93, + 247, 162, 95, 120, 3, 242, 93, 247, 3, 95, 120, 3, 242, 93, 242, 101, 95, + 120, 3, 242, 93, 243, 70, 95, 120, 3, 242, 93, 212, 67, 95, 120, 3, 242, + 93, 238, 34, 95, 120, 3, 242, 93, 197, 120, 95, 120, 3, 242, 93, 236, + 176, 95, 120, 3, 242, 93, 197, 115, 95, 120, 3, 242, 93, 181, 95, 120, 3, + 242, 93, 190, 190, 95, 120, 3, 242, 93, 199, 49, 95, 120, 3, 242, 93, + 159, 95, 120, 3, 242, 93, 198, 241, 95, 120, 3, 242, 93, 213, 45, 95, + 120, 3, 242, 93, 249, 155, 95, 120, 3, 242, 93, 209, 230, 95, 120, 3, + 242, 93, 209, 75, 95, 120, 3, 242, 93, 209, 201, 95, 120, 3, 242, 93, + 216, 14, 95, 120, 3, 242, 93, 192, 12, 95, 120, 3, 242, 93, 206, 163, 95, + 120, 3, 242, 93, 219, 45, 95, 120, 3, 242, 93, 195, 24, 95, 120, 3, 242, + 93, 203, 166, 95, 120, 3, 242, 93, 201, 176, 95, 120, 3, 242, 93, 188, + 95, 120, 3, 242, 93, 140, 95, 120, 3, 242, 93, 173, 95, 18, 3, 242, 93, + 208, 98, 95, 223, 151, 18, 3, 242, 93, 208, 35, 95, 223, 151, 18, 3, 242, + 93, 206, 18, 95, 223, 151, 18, 3, 242, 93, 206, 11, 95, 223, 151, 18, 3, + 242, 93, 208, 77, 95, 18, 3, 211, 115, 95, 18, 3, 252, 169, 229, 122, 1, + 248, 183, 214, 70, 229, 122, 1, 248, 183, 214, 18, 229, 122, 1, 248, 183, + 213, 239, 229, 122, 1, 248, 183, 214, 57, 229, 122, 1, 248, 183, 213, + 251, 72, 1, 248, 183, 214, 70, 72, 1, 248, 183, 214, 18, 72, 1, 248, 183, + 213, 239, 72, 1, 248, 183, 214, 57, 72, 1, 248, 183, 213, 251, 72, 1, + 251, 230, 247, 44, 72, 1, 251, 230, 197, 94, 72, 1, 251, 230, 159, 72, 1, + 251, 230, 210, 238, 52, 1, 233, 202, 233, 201, 239, 28, 163, 164, 52, 1, + 233, 201, 233, 202, 239, 28, 163, 164, }; static const unsigned short phrasebook_offset1[] = { @@ -22436,108 +22442,108 @@ static const unsigned int phrasebook_offset2[] = { 64361, 64365, 64369, 64373, 64377, 64381, 64385, 64389, 64393, 64397, 64401, 64405, 64409, 64413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64417, 64425, 64433, 64443, 64453, - 64462, 64472, 64482, 64493, 64505, 64516, 64528, 0, 0, 0, 0, 64535, - 64538, 64541, 64546, 64549, 64556, 64560, 64564, 64568, 64573, 64578, - 64584, 64590, 64595, 64600, 64606, 64612, 64618, 64624, 64627, 64630, - 64637, 64644, 64650, 64656, 64664, 64672, 64677, 64682, 64686, 64694, - 64700, 64707, 64712, 64717, 64722, 64727, 64732, 64737, 64742, 64747, - 64752, 64757, 64762, 64767, 64772, 64777, 64783, 64788, 64792, 64798, - 64809, 64818, 64832, 64841, 64845, 64855, 64861, 64867, 64873, 64878, - 64881, 64886, 64890, 0, 64896, 64901, 64905, 64910, 64914, 64919, 64923, - 64928, 64932, 64937, 64941, 64945, 64950, 64955, 64960, 64965, 64970, - 64975, 64980, 64985, 64990, 64994, 64999, 65004, 65009, 65014, 65019, - 65024, 65029, 65034, 65039, 65044, 65049, 65054, 65059, 65065, 65070, - 65075, 65080, 65085, 65089, 65094, 65098, 65103, 65108, 65113, 65118, - 65122, 65127, 65131, 65136, 65141, 65146, 65151, 65156, 65161, 65166, - 65171, 65176, 65181, 65186, 65191, 65195, 65200, 65205, 65210, 65215, - 65220, 65224, 65230, 65235, 65241, 65246, 65250, 65255, 65260, 65265, - 65270, 65276, 65281, 65286, 65291, 65296, 65301, 65306, 65311, 0, 0, - 65317, 65325, 65333, 65340, 65347, 65352, 65359, 65365, 65370, 65374, - 65377, 65381, 65384, 65388, 65391, 65395, 65398, 65402, 65405, 65408, - 65412, 65416, 65420, 65424, 65428, 65432, 65436, 65440, 65444, 65447, - 65451, 65455, 65459, 65463, 65467, 65471, 65475, 65479, 65483, 65487, - 65491, 65495, 65499, 65504, 65508, 65512, 65516, 65520, 65523, 65527, - 65530, 65534, 65538, 65542, 65546, 65549, 65553, 65556, 65560, 65564, - 65568, 65572, 65576, 65580, 65584, 65588, 65592, 65596, 65600, 65604, - 65607, 65611, 65615, 65619, 65623, 65627, 65630, 65635, 65639, 65644, - 65648, 65651, 65655, 65659, 65663, 65667, 65672, 65676, 65680, 65684, - 65688, 65692, 65696, 65700, 65705, 65709, 65713, 65717, 65721, 65725, - 65732, 65736, 65742, 0, 0, 0, 0, 0, 65747, 65752, 65757, 65762, 65767, - 65772, 65777, 65782, 65786, 65791, 65796, 65801, 65806, 65811, 65816, - 65821, 65826, 65831, 65835, 65840, 65845, 65850, 65854, 65858, 65862, - 65867, 65872, 65877, 65882, 65887, 65892, 65897, 65902, 65907, 65912, - 65916, 65920, 65925, 65930, 65935, 65940, 65945, 65952, 0, 65957, 65961, - 65965, 65969, 65973, 65977, 65981, 65985, 65989, 65993, 65997, 66001, - 66005, 66009, 66013, 66017, 66021, 66025, 66029, 66033, 66037, 66041, - 66045, 66049, 66053, 66057, 66061, 66065, 66069, 66073, 66077, 66080, - 66084, 66087, 66091, 66095, 66098, 66102, 66106, 66109, 66113, 66117, - 66121, 66125, 66128, 66132, 66136, 66140, 66144, 66148, 66152, 66155, - 66158, 66162, 66166, 66170, 66174, 66178, 66182, 66186, 66190, 66194, - 66198, 66202, 66206, 66210, 66214, 66218, 66222, 66226, 66230, 66234, - 66238, 66242, 66246, 66250, 66254, 66258, 66262, 66266, 66270, 66274, - 66278, 66282, 66286, 66290, 66294, 66298, 66302, 66306, 66310, 66314, - 66318, 66322, 0, 66326, 66332, 66338, 66343, 66348, 66353, 66359, 66365, - 66370, 66376, 66382, 66388, 66394, 66400, 66406, 66412, 66418, 66423, - 66428, 66433, 66438, 66443, 66448, 66453, 66458, 66463, 66468, 66473, - 66478, 66483, 66488, 66493, 66498, 66503, 66508, 66513, 66518, 66524, - 66530, 66536, 66542, 66547, 66552, 66557, 66563, 66568, 66573, 66578, - 66583, 66588, 66593, 66598, 66603, 66608, 66613, 66618, 66623, 66628, - 66633, 66638, 66643, 66648, 66653, 66658, 66663, 66668, 66673, 66678, - 66683, 66688, 66693, 66698, 66703, 66708, 66713, 66718, 66723, 66728, - 66733, 66738, 66743, 66748, 66753, 66758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 66763, 66768, 66773, 66778, 66782, 66787, 66791, 66796, 66801, - 66806, 66811, 66816, 66820, 66825, 66830, 66835, 66840, 66844, 66848, - 66852, 66856, 66860, 66864, 66868, 66872, 66876, 66880, 66884, 66888, - 66892, 66896, 66901, 66906, 66911, 66916, 66921, 66926, 66931, 66936, - 66941, 66946, 66951, 66956, 66961, 66966, 66971, 66978, 0, 66986, 66990, - 66994, 66998, 67002, 67006, 67010, 67014, 67018, 67022, 67027, 67032, - 67037, 67042, 67047, 67052, 67057, 67062, 67067, 67072, 67077, 67082, - 67087, 67092, 67097, 67102, 67107, 67112, 67117, 67122, 67127, 67132, - 67137, 67142, 67147, 67152, 67157, 67162, 67167, 67172, 67177, 67186, - 67195, 67204, 67213, 67222, 67231, 67240, 67249, 67252, 67257, 67262, - 67267, 67272, 67277, 67282, 67287, 67292, 67297, 67301, 67306, 67311, - 67316, 67321, 67326, 67330, 67334, 67338, 67342, 67346, 67350, 67354, - 67358, 67362, 67366, 67370, 67374, 67378, 67382, 67387, 67392, 67397, - 67402, 67407, 67412, 67417, 67422, 67427, 67432, 67437, 67442, 67447, - 67452, 67459, 67466, 67471, 67476, 67480, 67484, 67488, 67492, 67496, - 67500, 67504, 67508, 67512, 67517, 67522, 67527, 67532, 67537, 67542, - 67547, 67552, 67557, 67562, 67567, 67572, 67577, 67582, 67587, 67592, - 67597, 67602, 67607, 67612, 67617, 67622, 67627, 67632, 67637, 67642, - 67647, 67652, 67657, 67662, 67667, 67671, 67676, 67681, 67686, 67691, - 67696, 67701, 67706, 67711, 67716, 67721, 67726, 67731, 67735, 67740, - 67745, 67750, 67755, 67760, 67765, 67770, 67775, 67780, 67784, 67791, - 67798, 67805, 67812, 67819, 67826, 67833, 67840, 67847, 67854, 67861, - 67868, 67871, 67874, 67877, 67882, 67885, 67888, 67891, 67894, 67897, - 67900, 67904, 67908, 67912, 67916, 67919, 67923, 67927, 67931, 67935, - 67939, 67943, 67947, 67951, 67954, 67957, 67961, 67965, 67969, 67973, - 67976, 67980, 67984, 67988, 67992, 67995, 67999, 68003, 68007, 68011, - 68014, 68018, 68022, 68025, 68029, 68033, 68037, 68041, 68045, 68049, - 68053, 68057, 68064, 68067, 68070, 68073, 68076, 68079, 68082, 68085, - 68088, 68091, 68094, 68097, 68100, 68103, 68106, 68109, 68112, 68115, - 68118, 68121, 68124, 68127, 68130, 68133, 68136, 68139, 68142, 68145, - 68148, 68151, 68154, 68157, 68160, 68163, 68166, 68169, 68172, 68175, - 68178, 68181, 68184, 68187, 68190, 68193, 68196, 68199, 68202, 68205, - 68208, 68211, 68214, 68217, 68220, 68223, 68226, 68229, 68232, 68235, - 68238, 68241, 68244, 68247, 68250, 68253, 68256, 68259, 68262, 68265, - 68268, 68271, 68274, 68277, 68280, 68283, 68286, 68289, 68292, 68295, - 68298, 68301, 68304, 68307, 68310, 68313, 68316, 68319, 68322, 68325, - 68328, 68337, 68345, 68353, 68361, 68369, 68377, 68385, 68393, 68401, - 68409, 68418, 68427, 68436, 68445, 68454, 68463, 68472, 68481, 68490, - 68499, 68508, 68517, 68526, 68535, 68544, 68547, 68550, 68553, 68555, - 68558, 68561, 68564, 68569, 68574, 68577, 68584, 68591, 68598, 68605, - 68608, 68613, 68615, 68619, 68621, 68623, 68626, 68629, 68632, 68635, - 68638, 68641, 68644, 68649, 68654, 68657, 68660, 68663, 68666, 68669, - 68672, 68675, 68679, 68682, 68685, 68688, 68691, 68694, 68699, 68702, - 68705, 68708, 68713, 68718, 68723, 68728, 68733, 68738, 68743, 68748, - 68754, 68762, 68764, 68767, 68770, 68773, 68776, 68782, 68790, 68793, - 68796, 68801, 68804, 68807, 68810, 68815, 68818, 68821, 68826, 68829, - 68832, 68837, 68840, 68843, 68848, 68853, 68858, 68861, 68864, 68867, - 68870, 68876, 68879, 68882, 68885, 68887, 68890, 68893, 68896, 68901, - 68904, 68907, 68910, 68913, 68916, 68921, 68924, 68927, 68930, 68933, - 68936, 68939, 68942, 68945, 68948, 68954, 68959, 68967, 68975, 68983, - 68991, 68999, 69007, 69015, 69023, 69031, 69040, 69049, 69058, 69067, - 69076, 69085, 69094, 69103, 69112, 69121, 69130, 69139, 69148, 69157, - 69166, 69175, 69184, 69193, 69202, 69211, 69220, 69229, 0, 0, 0, 0, 0, 0, + 64462, 64472, 64482, 64493, 64505, 64516, 64528, 64535, 64545, 64556, + 64565, 64572, 64575, 64578, 64583, 64586, 64593, 64597, 64601, 64605, + 64610, 64615, 64621, 64627, 64632, 64637, 64643, 64649, 64655, 64661, + 64664, 64667, 64674, 64681, 64687, 64693, 64701, 64709, 64714, 64719, + 64723, 64731, 64737, 64744, 64749, 64754, 64759, 64764, 64769, 64774, + 64779, 64784, 64789, 64794, 64799, 64804, 64809, 64814, 64820, 64825, + 64829, 64835, 64846, 64855, 64869, 64878, 64882, 64892, 64898, 64904, + 64910, 64915, 64918, 64923, 64927, 0, 64933, 64938, 64942, 64947, 64951, + 64956, 64960, 64965, 64969, 64974, 64978, 64982, 64987, 64992, 64997, + 65002, 65007, 65012, 65017, 65022, 65027, 65031, 65036, 65041, 65046, + 65051, 65056, 65061, 65066, 65071, 65076, 65081, 65086, 65091, 65096, + 65102, 65107, 65112, 65117, 65122, 65126, 65131, 65135, 65140, 65145, + 65150, 65155, 65159, 65164, 65168, 65173, 65178, 65183, 65188, 65193, + 65198, 65203, 65208, 65213, 65218, 65223, 65228, 65232, 65237, 65242, + 65247, 65252, 65257, 65261, 65267, 65272, 65278, 65283, 65287, 65292, + 65297, 65302, 65307, 65313, 65318, 65323, 65328, 65333, 65338, 65343, + 65348, 0, 0, 65354, 65362, 65370, 65377, 65384, 65389, 65396, 65402, + 65407, 65411, 65414, 65418, 65421, 65425, 65428, 65432, 65435, 65439, + 65442, 65445, 65449, 65453, 65457, 65461, 65465, 65469, 65473, 65477, + 65481, 65484, 65488, 65492, 65496, 65500, 65504, 65508, 65512, 65516, + 65520, 65524, 65528, 65532, 65536, 65541, 65545, 65549, 65553, 65557, + 65560, 65564, 65567, 65571, 65575, 65579, 65583, 65586, 65590, 65593, + 65597, 65601, 65605, 65609, 65613, 65617, 65621, 65625, 65629, 65633, + 65637, 65641, 65644, 65648, 65652, 65656, 65660, 65664, 65667, 65672, + 65676, 65681, 65685, 65688, 65692, 65696, 65700, 65704, 65709, 65713, + 65717, 65721, 65725, 65729, 65733, 65737, 65742, 65746, 65750, 65754, + 65758, 65762, 65769, 65773, 65779, 0, 0, 0, 0, 0, 65784, 65789, 65794, + 65799, 65804, 65809, 65814, 65819, 65823, 65828, 65833, 65838, 65843, + 65848, 65853, 65858, 65863, 65868, 65872, 65877, 65882, 65887, 65891, + 65895, 65899, 65904, 65909, 65914, 65919, 65924, 65929, 65934, 65939, + 65944, 65949, 65953, 65957, 65962, 65967, 65972, 65977, 65982, 65989, 0, + 65994, 65998, 66002, 66006, 66010, 66014, 66018, 66022, 66026, 66030, + 66034, 66038, 66042, 66046, 66050, 66054, 66058, 66062, 66066, 66070, + 66074, 66078, 66082, 66086, 66090, 66094, 66098, 66102, 66106, 66110, + 66114, 66117, 66121, 66124, 66128, 66132, 66135, 66139, 66143, 66146, + 66150, 66154, 66158, 66162, 66165, 66169, 66173, 66177, 66181, 66185, + 66189, 66192, 66195, 66199, 66203, 66207, 66211, 66215, 66219, 66223, + 66227, 66231, 66235, 66239, 66243, 66247, 66251, 66255, 66259, 66263, + 66267, 66271, 66275, 66279, 66283, 66287, 66291, 66295, 66299, 66303, + 66307, 66311, 66315, 66319, 66323, 66327, 66331, 66335, 66339, 66343, + 66347, 66351, 66355, 66359, 0, 66363, 66369, 66375, 66380, 66385, 66390, + 66396, 66402, 66407, 66413, 66419, 66425, 66431, 66437, 66443, 66449, + 66455, 66460, 66465, 66470, 66475, 66480, 66485, 66490, 66495, 66500, + 66505, 66510, 66515, 66520, 66525, 66530, 66535, 66540, 66545, 66550, + 66555, 66561, 66567, 66573, 66579, 66584, 66589, 66594, 66600, 66605, + 66610, 66615, 66620, 66625, 66630, 66635, 66640, 66645, 66650, 66655, + 66660, 66665, 66670, 66675, 66680, 66685, 66690, 66695, 66700, 66705, + 66710, 66715, 66720, 66725, 66730, 66735, 66740, 66745, 66750, 66755, + 66760, 66765, 66770, 66775, 66780, 66785, 66790, 66795, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 66800, 66807, 66812, 66817, 66822, 66826, 66831, 66835, + 66840, 66845, 66850, 66855, 66860, 66864, 66869, 66874, 66879, 66884, + 66888, 66892, 66896, 66900, 66904, 66908, 66912, 66916, 66920, 66924, + 66928, 66932, 66936, 66940, 66945, 66950, 66955, 66960, 66965, 66970, + 66975, 66980, 66985, 66990, 66995, 67000, 67005, 67010, 67015, 67022, 0, + 67030, 67034, 67038, 67042, 67046, 67050, 67054, 67058, 67062, 67066, + 67071, 67076, 67081, 67086, 67091, 67096, 67101, 67106, 67111, 67116, + 67121, 67126, 67131, 67136, 67141, 67146, 67151, 67156, 67161, 67166, + 67171, 67176, 67181, 67186, 67191, 67196, 67201, 67206, 67211, 67216, + 67221, 67230, 67239, 67248, 67257, 67266, 67275, 67284, 67293, 67296, + 67301, 67306, 67311, 67316, 67321, 67326, 67331, 67336, 67341, 67345, + 67350, 67355, 67360, 67365, 67370, 67374, 67378, 67382, 67386, 67390, + 67394, 67398, 67402, 67406, 67410, 67414, 67418, 67422, 67426, 67431, + 67436, 67441, 67446, 67451, 67456, 67461, 67466, 67471, 67476, 67481, + 67486, 67491, 67496, 67503, 67510, 67515, 67520, 67524, 67528, 67532, + 67536, 67540, 67544, 67548, 67552, 67556, 67561, 67566, 67571, 67576, + 67581, 67586, 67591, 67596, 67601, 67606, 67611, 67616, 67621, 67626, + 67631, 67636, 67641, 67646, 67651, 67656, 67661, 67666, 67671, 67676, + 67681, 67686, 67691, 67696, 67701, 67706, 67711, 67715, 67720, 67725, + 67730, 67735, 67740, 67745, 67750, 67755, 67760, 67765, 67770, 67775, + 67779, 67784, 67789, 67794, 67799, 67804, 67809, 67814, 67819, 67824, + 67828, 67835, 67842, 67849, 67856, 67863, 67870, 67877, 67884, 67891, + 67898, 67905, 67912, 67915, 67918, 67921, 67926, 67929, 67932, 67935, + 67938, 67941, 67944, 67948, 67952, 67956, 67960, 67963, 67967, 67971, + 67975, 67979, 67983, 67987, 67991, 67995, 67998, 68001, 68005, 68009, + 68013, 68017, 68020, 68024, 68028, 68032, 68036, 68039, 68043, 68047, + 68051, 68055, 68058, 68062, 68066, 68069, 68073, 68077, 68081, 68085, + 68089, 68093, 68097, 68101, 68108, 68111, 68114, 68117, 68120, 68123, + 68126, 68129, 68132, 68135, 68138, 68141, 68144, 68147, 68150, 68153, + 68156, 68159, 68162, 68165, 68168, 68171, 68174, 68177, 68180, 68183, + 68186, 68189, 68192, 68195, 68198, 68201, 68204, 68207, 68210, 68213, + 68216, 68219, 68222, 68225, 68228, 68231, 68234, 68237, 68240, 68243, + 68246, 68249, 68252, 68255, 68258, 68261, 68264, 68267, 68270, 68273, + 68276, 68279, 68282, 68285, 68288, 68291, 68294, 68297, 68300, 68303, + 68306, 68309, 68312, 68315, 68318, 68321, 68324, 68327, 68330, 68333, + 68336, 68339, 68342, 68345, 68348, 68351, 68354, 68357, 68360, 68363, + 68366, 68369, 68372, 68381, 68389, 68397, 68405, 68413, 68421, 68429, + 68437, 68445, 68453, 68462, 68471, 68480, 68489, 68498, 68507, 68516, + 68525, 68534, 68543, 68552, 68561, 68570, 68579, 68588, 68591, 68594, + 68597, 68599, 68602, 68605, 68608, 68613, 68618, 68621, 68628, 68635, + 68642, 68649, 68652, 68657, 68659, 68663, 68665, 68667, 68670, 68673, + 68676, 68679, 68682, 68685, 68688, 68693, 68698, 68701, 68704, 68707, + 68710, 68713, 68716, 68719, 68723, 68726, 68729, 68732, 68735, 68738, + 68743, 68746, 68749, 68752, 68757, 68762, 68767, 68772, 68777, 68782, + 68787, 68792, 68798, 68806, 68808, 68811, 68814, 68817, 68820, 68826, + 68834, 68837, 68840, 68845, 68848, 68851, 68854, 68859, 68862, 68865, + 68870, 68873, 68876, 68881, 68884, 68887, 68892, 68897, 68902, 68905, + 68908, 68911, 68914, 68920, 68923, 68926, 68929, 68931, 68934, 68937, + 68940, 68945, 68948, 68951, 68954, 68957, 68960, 68965, 68968, 68971, + 68974, 68977, 68980, 68983, 68986, 68989, 68992, 68998, 69003, 69011, + 69019, 69027, 69035, 69043, 69051, 69059, 69067, 69075, 69084, 69093, + 69102, 69111, 69120, 69129, 69138, 69147, 69156, 69165, 69174, 69183, + 69192, 69201, 69210, 69219, 69228, 69237, 69246, 69255, 69264, 69273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -22545,320 +22551,319 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69232, 69241, - 69250, 69261, 69268, 69273, 69278, 69285, 69292, 69298, 69303, 69308, - 69313, 69318, 69325, 69330, 69335, 69340, 69351, 69356, 69361, 69368, - 69373, 69380, 69385, 69390, 69397, 69404, 69411, 69420, 69429, 69434, - 69439, 69444, 69451, 69456, 69466, 69473, 69478, 69483, 69488, 69493, - 69498, 69503, 69511, 69518, 69525, 69530, 69537, 69542, 69549, 69558, - 69569, 69574, 69583, 69588, 69595, 69604, 69613, 69618, 69623, 69630, - 69636, 69643, 69650, 69654, 69658, 69661, 69665, 69669, 69673, 69677, - 69681, 69685, 69689, 69692, 69696, 69700, 69704, 69708, 69712, 69716, - 69719, 69723, 69727, 69730, 69734, 69738, 69742, 69746, 69750, 69754, - 69758, 69762, 69766, 69770, 69774, 69778, 69782, 69786, 69790, 69794, - 69798, 69802, 69806, 69810, 69814, 69818, 69822, 69826, 69830, 69834, - 69838, 69842, 69846, 69850, 69854, 69858, 69862, 69866, 69870, 69874, - 69878, 69882, 69886, 69890, 69894, 69898, 69902, 69906, 69909, 69913, - 69917, 69921, 69925, 69929, 69933, 69937, 69941, 69945, 69949, 69953, - 69957, 69961, 69965, 69969, 69973, 69977, 69981, 69985, 69989, 69993, - 69997, 70001, 70005, 70009, 70013, 70017, 70021, 70025, 70029, 70033, - 70037, 70041, 70045, 70049, 70053, 70057, 70061, 70065, 70069, 70073, - 70077, 70081, 70085, 70089, 70093, 70097, 70101, 70105, 70109, 70113, - 70117, 70121, 70125, 70129, 70133, 70137, 70141, 70145, 70149, 70153, - 70157, 70161, 70165, 70169, 70173, 70177, 70181, 70185, 70189, 70193, - 70197, 70201, 70205, 70209, 70213, 70217, 70221, 70225, 70229, 70233, - 70237, 70241, 70245, 70249, 70253, 70257, 70261, 70265, 70269, 70273, - 70277, 70281, 70285, 70289, 70293, 70297, 70301, 70305, 70309, 70313, - 70317, 70321, 70325, 70329, 70333, 70337, 70341, 70345, 70349, 70353, - 70357, 70361, 70365, 70369, 70373, 70377, 70380, 70384, 70388, 70392, - 70396, 70400, 70404, 70408, 70412, 70416, 70420, 70424, 70428, 70432, - 70436, 70440, 70444, 70448, 70452, 70456, 70460, 70464, 70468, 70472, - 70476, 70480, 70484, 70488, 70492, 70496, 70500, 70504, 70508, 70512, - 70516, 70520, 70524, 70528, 70532, 70536, 70540, 70544, 70548, 70552, - 70556, 70560, 70564, 70568, 70572, 70576, 70580, 70584, 70588, 70592, - 70596, 70600, 70604, 70608, 70612, 70616, 70620, 70624, 70628, 70632, - 70636, 70640, 70644, 70648, 70652, 70656, 70660, 70664, 70668, 70672, - 70676, 70680, 70684, 70688, 70692, 70696, 70700, 70704, 70708, 70712, - 70716, 70720, 70724, 70728, 70732, 70736, 70740, 70744, 70748, 70752, - 70756, 70760, 70764, 70768, 70772, 70776, 70780, 70784, 70788, 70792, - 70796, 70800, 70804, 70808, 70812, 70816, 70820, 70824, 70828, 70832, - 70836, 70840, 70843, 70847, 70851, 70855, 70859, 70863, 70867, 70871, - 70875, 70879, 70883, 70887, 70891, 70895, 70899, 70903, 70907, 70911, - 70915, 70919, 70923, 70927, 70931, 70935, 70939, 70943, 70947, 70951, - 70955, 70959, 70963, 70967, 70971, 70975, 70979, 70983, 70987, 70991, - 70995, 70999, 71003, 71007, 71011, 71015, 71019, 71023, 71027, 71031, - 71035, 71039, 71043, 71047, 71051, 71055, 71059, 71063, 71067, 71071, - 71075, 71079, 71083, 71087, 71091, 71095, 71099, 71103, 71107, 71111, - 71115, 71119, 71123, 71127, 71131, 71135, 71139, 71143, 71147, 71151, - 71155, 71159, 71163, 71167, 71171, 71175, 71179, 71183, 71187, 71191, - 71195, 71199, 71202, 71206, 71210, 71214, 71218, 71222, 71226, 71230, - 71234, 71238, 71242, 71246, 71250, 71254, 71258, 71262, 71266, 71270, - 71274, 71278, 71282, 71286, 71290, 71294, 71298, 71302, 71306, 71310, - 71314, 71318, 71322, 71326, 71330, 71334, 71338, 71342, 71346, 71350, - 71354, 71358, 71362, 71366, 71370, 71374, 71378, 71382, 71386, 71390, - 71394, 71398, 71402, 71406, 71410, 71414, 71418, 71422, 71426, 71430, - 71434, 71438, 71441, 71445, 71449, 71453, 71457, 71461, 71465, 71469, - 71473, 71477, 71481, 71485, 71489, 71493, 71497, 71501, 71505, 71509, - 71513, 71517, 71521, 71525, 71529, 71533, 71537, 71541, 71545, 71549, - 71553, 71557, 71561, 71565, 71569, 71573, 71577, 71581, 71585, 71589, - 71593, 71597, 71601, 71605, 71609, 71613, 71617, 71621, 71625, 71629, - 71633, 71637, 71641, 71645, 71649, 71653, 71657, 71661, 71665, 71669, - 71673, 71677, 71681, 71685, 71689, 71693, 71696, 71700, 71704, 71708, - 71712, 71716, 71720, 71724, 71728, 71732, 71736, 71740, 71744, 71748, - 71752, 71756, 71760, 71764, 71768, 71772, 71776, 71780, 71784, 71788, - 71792, 71796, 71800, 71804, 71808, 71812, 71816, 71820, 71824, 71828, - 71832, 71836, 71840, 71844, 71848, 71852, 71856, 71860, 71864, 71868, - 71872, 71876, 71880, 71884, 71888, 71892, 71896, 71900, 71904, 71908, - 71912, 71916, 71920, 71924, 71928, 71932, 71936, 71940, 71944, 71948, - 71952, 71956, 71960, 71964, 71968, 71972, 71976, 71980, 71984, 71988, - 71992, 71996, 72000, 72004, 72008, 72012, 72016, 72020, 72024, 72028, - 72032, 72036, 72040, 72044, 72048, 72052, 72056, 72060, 72064, 72068, - 72072, 72076, 72080, 72084, 72088, 72092, 72096, 72100, 72104, 72108, - 72112, 72116, 72120, 72124, 72128, 72132, 72136, 72140, 72144, 72148, - 72151, 72155, 72159, 72163, 72167, 72171, 72175, 72179, 72183, 72187, - 72191, 72195, 72199, 72203, 72207, 72211, 72215, 72219, 72223, 72227, - 72231, 72235, 72239, 72243, 72247, 72251, 72255, 72259, 72263, 72267, - 72271, 72275, 72279, 72283, 72287, 72291, 72295, 72299, 72303, 72307, - 72311, 72315, 72319, 72323, 72327, 72331, 72335, 72339, 72343, 72347, - 72351, 72355, 72359, 72363, 72367, 72371, 72375, 72379, 72383, 72387, - 72391, 72395, 72399, 72403, 72407, 72411, 72415, 72419, 72423, 72427, - 72431, 72435, 72439, 72443, 72447, 72451, 72455, 72459, 72463, 72467, - 72471, 72475, 72479, 72483, 72487, 72491, 72495, 72499, 72503, 72507, - 72511, 72515, 72519, 72523, 72527, 72531, 72535, 72539, 72543, 72547, - 72551, 72555, 72559, 72563, 72567, 72571, 72575, 72579, 72583, 72587, - 72591, 72595, 72599, 72603, 72607, 72611, 72615, 72619, 72623, 72627, - 72631, 72635, 72639, 72643, 72647, 72651, 72655, 72659, 72663, 72667, - 72671, 72675, 72679, 72683, 72687, 72691, 72695, 72699, 72703, 72707, - 72711, 72715, 72719, 72723, 72727, 72731, 72735, 72739, 72743, 72747, - 72751, 72754, 72758, 72762, 72766, 72770, 72774, 72778, 72782, 72785, - 72789, 72793, 72797, 72801, 72805, 72809, 72813, 72817, 72821, 72825, - 72829, 72833, 72837, 72841, 72845, 72849, 72853, 72857, 72861, 72865, - 72869, 72873, 72877, 72881, 72885, 72889, 72893, 72897, 72901, 72905, - 72909, 72913, 72917, 72921, 72925, 72929, 72933, 72937, 72941, 72945, - 72949, 72953, 72957, 72961, 72965, 72969, 72973, 72977, 72981, 72985, - 72989, 72993, 72997, 73001, 73005, 73009, 73013, 73017, 73021, 73025, - 73029, 73033, 73037, 73041, 73045, 73049, 73053, 73057, 73061, 73065, - 73069, 73073, 73077, 73081, 73085, 73089, 73093, 73097, 73101, 73105, - 73109, 73113, 73117, 73121, 73125, 73129, 73133, 73137, 73141, 73145, - 73149, 73153, 73157, 73161, 73165, 73169, 73173, 73177, 73181, 73185, - 73189, 73193, 73197, 73201, 73205, 73209, 73213, 73217, 73221, 73225, - 73229, 73233, 73237, 73241, 73245, 73249, 73253, 73257, 73261, 73265, - 73269, 73273, 73277, 73281, 73285, 73289, 73293, 73297, 73301, 73305, - 73309, 73313, 73317, 73321, 73325, 73329, 73333, 73337, 73341, 73345, - 73349, 73353, 73357, 73361, 73365, 73369, 73373, 73377, 73381, 73385, - 73389, 73393, 73397, 73401, 73405, 73409, 73413, 73417, 73421, 73425, - 73429, 73433, 73437, 73441, 73445, 73449, 73453, 73457, 73461, 73465, - 73469, 73473, 73477, 73481, 73485, 73489, 73493, 73497, 73501, 73505, - 73509, 73512, 73516, 73520, 73524, 73528, 73532, 73536, 73540, 73544, - 73548, 73552, 73556, 73560, 73564, 73568, 73572, 73576, 73580, 73584, - 73588, 73592, 73596, 73600, 73604, 73608, 73612, 73616, 73620, 73624, - 73628, 73632, 73636, 73640, 73644, 73648, 73652, 73656, 73660, 73664, - 73668, 73672, 73676, 73680, 73684, 73688, 73692, 73696, 73700, 73704, - 73708, 73712, 73716, 73720, 73724, 73728, 73732, 73736, 73740, 73744, - 73748, 73752, 73756, 73760, 73764, 73768, 73772, 73776, 73780, 73784, - 73788, 73792, 73796, 73800, 73804, 73808, 73812, 73816, 73820, 73824, - 73828, 73832, 73836, 73840, 73844, 73848, 73852, 73856, 73860, 73864, - 73868, 73872, 73876, 73880, 73884, 73888, 73892, 73896, 73900, 73904, - 73908, 73912, 73916, 73920, 73924, 73928, 73932, 73936, 73940, 73944, - 73948, 73952, 73956, 73960, 73964, 73968, 73972, 73976, 73980, 73984, - 73988, 73992, 73996, 74000, 74004, 74008, 74012, 74016, 74020, 74024, - 74028, 74032, 74036, 74040, 74044, 74048, 74052, 74056, 74060, 74064, - 74068, 74072, 74076, 74080, 74084, 74088, 74092, 74096, 74100, 74104, - 74108, 74112, 74116, 74120, 74124, 74128, 74132, 74136, 74140, 74144, - 74148, 74152, 74156, 74160, 74164, 74168, 74172, 74176, 74180, 74184, - 74188, 74192, 74196, 74200, 74204, 74208, 74212, 74216, 74220, 74224, - 74228, 74232, 74236, 74240, 74244, 74248, 74252, 74256, 74260, 74264, - 74268, 74272, 74276, 74280, 74284, 74288, 74292, 0, 0, 0, 74296, 74300, - 74304, 74308, 74312, 74316, 74320, 74324, 74328, 74332, 74336, 74340, - 74344, 74348, 74352, 74356, 74360, 74364, 74368, 74372, 74376, 74380, - 74384, 74388, 74392, 74396, 74400, 74404, 74408, 74412, 74416, 74420, - 74424, 74428, 74432, 74436, 74440, 74444, 74448, 74452, 74456, 74460, - 74464, 74468, 74472, 74476, 74480, 74484, 74488, 74492, 74496, 74500, - 74504, 74508, 74512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74516, 74521, 74525, - 74530, 74535, 74540, 74545, 74550, 74554, 74559, 74564, 74569, 74574, - 74579, 74584, 74589, 74593, 74597, 74601, 74605, 74610, 74615, 74620, - 74624, 74629, 74634, 74639, 74644, 74649, 74653, 74658, 74662, 74667, - 74671, 74676, 74680, 74684, 74688, 74693, 74698, 74703, 74711, 74719, - 74727, 74735, 74742, 74750, 74756, 74764, 74768, 74772, 74776, 74780, - 74784, 74788, 74792, 74796, 74800, 74804, 74808, 74812, 74816, 74820, - 74824, 74828, 74832, 74836, 74840, 74844, 74848, 74852, 74856, 74860, - 74864, 74868, 74872, 74876, 74880, 74884, 74888, 74892, 74896, 74900, - 74904, 74908, 74911, 74915, 74919, 74923, 74927, 74931, 74935, 74939, - 74943, 74947, 74951, 74955, 74959, 74963, 74967, 74971, 74975, 74979, - 74983, 74987, 74991, 74995, 74999, 75003, 75007, 75011, 75015, 75019, - 75023, 75027, 75031, 75035, 75039, 75043, 75047, 75051, 75055, 75058, - 75062, 75066, 75069, 75073, 75077, 75081, 75084, 75088, 75092, 75096, - 75100, 75104, 75108, 75112, 75116, 75120, 75124, 75128, 75132, 75136, - 75139, 75142, 75146, 75150, 75153, 75157, 75161, 75165, 75169, 75173, - 75177, 75180, 75183, 75187, 75191, 75195, 75198, 75201, 75205, 75209, - 75213, 75217, 75221, 75225, 75229, 75233, 75237, 75241, 75245, 75249, - 75253, 75257, 75261, 75265, 75269, 75273, 75277, 75281, 75285, 75289, - 75293, 75297, 75301, 75305, 75309, 75313, 75317, 75321, 75325, 75329, - 75333, 75337, 75341, 75345, 75349, 75352, 75356, 75360, 75364, 75368, - 75372, 75376, 75380, 75384, 75388, 75392, 75396, 75400, 75404, 75408, - 75412, 75416, 75420, 75424, 75428, 75432, 75436, 75440, 75444, 75448, - 75452, 75456, 75460, 75464, 75468, 75472, 75476, 75480, 75484, 75488, - 75492, 75496, 75499, 75503, 75507, 75511, 75515, 75519, 75523, 75527, - 75531, 75535, 75539, 75543, 75547, 75551, 75555, 75559, 75563, 75566, - 75570, 75574, 75578, 75582, 75586, 75590, 75594, 75598, 75602, 75606, - 75610, 75614, 75618, 75622, 75626, 75630, 75634, 75638, 75642, 75646, - 75650, 75653, 75657, 75661, 75665, 75669, 75673, 75677, 75681, 75685, - 75689, 75693, 75697, 75701, 75705, 75709, 75713, 75717, 75721, 75725, - 75729, 75733, 75737, 75741, 75745, 75749, 75753, 75757, 75761, 75765, - 75769, 75773, 75777, 75781, 75785, 75789, 75793, 75797, 75801, 75805, - 75809, 75813, 75817, 75821, 75825, 75828, 75833, 75837, 75843, 75848, - 75854, 75858, 75862, 75866, 75870, 75874, 75878, 75882, 75886, 75890, - 75894, 75898, 75902, 75906, 75910, 75913, 75916, 75919, 75922, 75925, - 75928, 75931, 75934, 75937, 75942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 75948, 75953, 75958, 75963, 75968, 75975, 75982, - 75987, 75992, 75997, 76002, 76009, 76016, 76023, 76030, 76037, 76044, - 76054, 76064, 76071, 76078, 76085, 76092, 76098, 76104, 76113, 76122, - 76129, 76136, 76147, 76158, 76163, 76168, 76175, 76182, 76189, 76196, - 76203, 76210, 76217, 76224, 76230, 76236, 76242, 76248, 76255, 76262, - 76267, 76271, 76278, 76285, 76292, 76296, 76303, 76307, 76312, 76316, - 76322, 76327, 76333, 76338, 76342, 76346, 76349, 76352, 76357, 76362, - 76367, 76372, 76377, 76382, 76387, 76392, 76397, 76402, 76410, 76418, - 76423, 76428, 76433, 76438, 76443, 76448, 76453, 76458, 76463, 76468, - 76473, 76478, 76483, 76488, 76494, 76500, 76506, 76512, 76517, 76523, - 76526, 76529, 76532, 76536, 76540, 76544, 76548, 76551, 76555, 76558, - 76561, 76564, 76568, 76572, 76576, 76580, 76584, 76588, 76592, 76596, - 76600, 76604, 76608, 76612, 76616, 76620, 76624, 76628, 76632, 76636, - 76640, 76644, 76648, 76652, 76655, 76659, 76663, 76667, 76671, 76675, - 76679, 76683, 76687, 76691, 76695, 76699, 76703, 76707, 76711, 76715, - 76719, 76723, 76727, 76731, 76735, 76739, 76743, 76747, 76751, 76754, - 76758, 76762, 76766, 76770, 76774, 76778, 76782, 76785, 76789, 76793, - 76797, 76801, 76805, 76809, 76813, 76817, 76821, 76825, 76829, 76833, - 76838, 76843, 76846, 76851, 76854, 76857, 76860, 0, 0, 0, 0, 0, 0, 0, 0, - 76864, 76873, 76882, 76891, 76900, 76909, 76918, 76927, 76936, 76944, - 76951, 76959, 76966, 76974, 76984, 76993, 77003, 77012, 77022, 77030, - 77037, 77045, 77052, 77060, 77065, 77070, 77076, 77084, 77090, 77096, - 77103, 77112, 77120, 77128, 77136, 77143, 77150, 77157, 77164, 77169, - 77174, 77179, 77184, 77189, 77194, 77199, 77204, 77212, 77220, 77226, - 77232, 77237, 77242, 77247, 77252, 77257, 77262, 77267, 77272, 77281, - 77290, 77295, 77300, 77310, 77320, 77327, 77334, 77343, 77352, 77364, - 77376, 77382, 77388, 77396, 77404, 77414, 77424, 77431, 77438, 77443, - 77448, 77460, 77472, 77480, 77488, 77498, 77508, 77520, 77532, 77541, - 77550, 77557, 77564, 77571, 77578, 77587, 77596, 77601, 77606, 77613, - 77620, 77627, 77634, 77646, 77658, 77663, 77668, 77673, 77678, 77683, - 77688, 77693, 77698, 77702, 77707, 77712, 77717, 77722, 77727, 77733, - 77738, 77743, 77750, 77757, 77764, 77771, 77778, 77786, 77794, 77799, - 77804, 77810, 77816, 77823, 77830, 77837, 77844, 77851, 77855, 77862, - 77867, 77872, 77878, 77891, 77897, 77905, 77913, 77920, 77927, 77936, - 77945, 77952, 77959, 77966, 77973, 77980, 77987, 77994, 78001, 78008, - 78015, 78024, 78033, 78042, 78051, 78060, 78069, 78078, 78087, 78096, - 78105, 78112, 78120, 78126, 78134, 78140, 78146, 78152, 78158, 78166, - 78171, 78176, 78181, 78186, 78191, 78197, 78203, 78209, 78215, 78221, - 78227, 78233, 78239, 78246, 78253, 78260, 78267, 78276, 78283, 78292, - 78304, 78316, 78328, 0, 0, 0, 0, 0, 78340, 78349, 0, 78358, 0, 78364, - 78370, 78378, 78386, 78393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 78400, 78405, 78410, 78415, 78423, 78431, - 78438, 78445, 78451, 78458, 78466, 78474, 78482, 78490, 78498, 78504, - 78510, 78517, 78523, 78529, 78535, 78542, 78549, 78556, 78563, 78570, - 78577, 78584, 78591, 78598, 78605, 78612, 78619, 78626, 78633, 78639, - 78646, 78653, 78660, 78667, 78674, 78681, 78688, 78695, 78702, 78709, - 78716, 78723, 78730, 78737, 78744, 78751, 78758, 78765, 78773, 78781, - 78789, 78797, 78805, 0, 0, 0, 78814, 78822, 78830, 78838, 78846, 78854, - 78862, 78868, 78874, 78880, 0, 0, 0, 0, 0, 0, 78886, 78890, 78895, 78900, - 78905, 78910, 78915, 78920, 78925, 78930, 78935, 78940, 78944, 78948, - 78953, 78958, 78962, 78967, 78972, 78977, 78982, 78987, 78992, 78997, - 79001, 79005, 79009, 79014, 79018, 79022, 79026, 79030, 79034, 79038, - 79042, 79047, 79052, 79057, 79062, 79067, 79074, 79080, 79085, 79090, - 79095, 79100, 79106, 79113, 79119, 79126, 79132, 79138, 79143, 79150, - 79156, 79161, 0, 0, 0, 0, 0, 0, 0, 0, 79167, 79172, 79177, 79181, 79186, - 79190, 79195, 79199, 79204, 79209, 79215, 79220, 79226, 79230, 79235, - 79240, 79244, 79249, 79254, 79258, 79263, 79268, 79273, 79278, 79283, - 79288, 79293, 79298, 79303, 79308, 79313, 79318, 79323, 79328, 79333, - 79338, 79343, 79348, 79352, 79356, 79361, 79366, 79371, 79375, 79379, - 79383, 79387, 79392, 79397, 79402, 79406, 79410, 79415, 79421, 79427, - 79432, 79438, 79443, 79449, 79455, 79462, 79468, 79475, 79480, 79486, - 79492, 79497, 79503, 79509, 79514, 0, 0, 0, 0, 0, 0, 0, 0, 79519, 79523, - 79528, 79533, 79537, 79541, 79545, 79549, 79553, 79557, 79561, 79565, 0, - 0, 0, 0, 0, 0, 79569, 79574, 79578, 79582, 79586, 79590, 79594, 79598, - 79602, 79606, 79610, 79614, 79618, 79622, 79626, 79630, 79634, 79639, - 79644, 79650, 79656, 79663, 79668, 79673, 79679, 79683, 79688, 79691, - 79694, 79698, 79703, 79707, 79712, 79719, 79725, 79731, 79737, 79743, - 79749, 79755, 79761, 79767, 79773, 79779, 79786, 79793, 79800, 79806, - 79813, 79820, 79827, 79834, 79841, 79847, 79853, 79860, 79866, 79873, - 79880, 79886, 79892, 79898, 79905, 79912, 79918, 79925, 79932, 79938, - 79945, 79951, 79958, 79965, 79971, 79977, 79984, 79990, 79997, 80004, - 80013, 80020, 80027, 80031, 80036, 80041, 80046, 80051, 80055, 80059, - 80064, 80068, 80073, 80078, 80083, 80087, 80091, 80095, 80099, 80104, - 80108, 80113, 80118, 80123, 80128, 80132, 80137, 80142, 80147, 80153, - 80158, 80164, 80170, 80176, 80182, 80188, 80193, 80199, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80203, 80208, 80212, 80216, 80220, 80224, 80228, 80232, - 80236, 80240, 80244, 80248, 80252, 80256, 80260, 80264, 80268, 80272, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 69276, 69285, 69294, 69305, 69312, 69317, 69322, 69329, 69336, 69342, + 69347, 69352, 69357, 69362, 69369, 69374, 69379, 69384, 69395, 69400, + 69405, 69412, 69417, 69424, 69429, 69434, 69441, 69448, 69455, 69464, + 69473, 69478, 69483, 69488, 69495, 69500, 69510, 69517, 69522, 69527, + 69532, 69537, 69542, 69547, 69555, 69562, 69569, 69574, 69581, 69586, + 69593, 69602, 69613, 69618, 69627, 69632, 69639, 69648, 69657, 69662, + 69667, 69674, 69680, 69687, 69694, 69698, 69702, 69705, 69709, 69713, + 69717, 69721, 69725, 69729, 69733, 69736, 69740, 69744, 69748, 69752, + 69756, 69760, 69763, 69767, 69771, 69774, 69778, 69782, 69786, 69790, + 69794, 69798, 69802, 69806, 69810, 69814, 69818, 69822, 69826, 69830, + 69834, 69838, 69842, 69846, 69850, 69854, 69858, 69862, 69866, 69870, + 69874, 69878, 69882, 69886, 69890, 69894, 69898, 69902, 69906, 69910, + 69914, 69918, 69922, 69926, 69930, 69934, 69938, 69942, 69946, 69950, + 69953, 69957, 69961, 69965, 69969, 69973, 69977, 69981, 69985, 69989, + 69993, 69997, 70001, 70005, 70009, 70013, 70017, 70021, 70025, 70029, + 70033, 70037, 70041, 70045, 70049, 70053, 70057, 70061, 70065, 70069, + 70073, 70077, 70081, 70085, 70089, 70093, 70097, 70101, 70105, 70109, + 70113, 70117, 70121, 70125, 70129, 70133, 70137, 70141, 70145, 70149, + 70153, 70157, 70161, 70165, 70169, 70173, 70177, 70181, 70185, 70189, + 70193, 70197, 70201, 70205, 70209, 70213, 70217, 70221, 70225, 70229, + 70233, 70237, 70241, 70245, 70249, 70253, 70257, 70261, 70265, 70269, + 70273, 70277, 70281, 70285, 70289, 70293, 70297, 70301, 70305, 70309, + 70313, 70317, 70321, 70325, 70329, 70333, 70337, 70341, 70345, 70349, + 70353, 70357, 70361, 70365, 70369, 70373, 70377, 70381, 70385, 70389, + 70393, 70397, 70401, 70405, 70409, 70413, 70417, 70421, 70424, 70428, + 70432, 70436, 70440, 70444, 70448, 70452, 70456, 70460, 70464, 70468, + 70472, 70476, 70480, 70484, 70488, 70492, 70496, 70500, 70504, 70508, + 70512, 70516, 70520, 70524, 70528, 70532, 70536, 70540, 70544, 70548, + 70552, 70556, 70560, 70564, 70568, 70572, 70576, 70580, 70584, 70588, + 70592, 70596, 70600, 70604, 70608, 70612, 70616, 70620, 70624, 70628, + 70632, 70636, 70640, 70644, 70648, 70652, 70656, 70660, 70664, 70668, + 70672, 70676, 70680, 70684, 70688, 70692, 70696, 70700, 70704, 70708, + 70712, 70716, 70720, 70724, 70728, 70732, 70736, 70740, 70744, 70748, + 70752, 70756, 70760, 70764, 70768, 70772, 70776, 70780, 70784, 70788, + 70792, 70796, 70800, 70804, 70808, 70812, 70816, 70820, 70824, 70828, + 70832, 70836, 70840, 70844, 70848, 70852, 70856, 70860, 70864, 70868, + 70872, 70876, 70880, 70884, 70887, 70891, 70895, 70899, 70903, 70907, + 70911, 70915, 70919, 70923, 70927, 70931, 70935, 70939, 70943, 70947, + 70951, 70955, 70959, 70963, 70967, 70971, 70975, 70979, 70983, 70987, + 70991, 70995, 70999, 71003, 71007, 71011, 71015, 71019, 71023, 71027, + 71031, 71035, 71039, 71043, 71047, 71051, 71055, 71059, 71063, 71067, + 71071, 71075, 71079, 71083, 71087, 71091, 71095, 71099, 71103, 71107, + 71111, 71115, 71119, 71123, 71127, 71131, 71135, 71139, 71143, 71147, + 71151, 71155, 71159, 71163, 71167, 71171, 71175, 71179, 71183, 71187, + 71191, 71195, 71199, 71203, 71207, 71211, 71215, 71219, 71223, 71227, + 71231, 71235, 71239, 71243, 71246, 71250, 71254, 71258, 71262, 71266, + 71270, 71274, 71278, 71282, 71286, 71290, 71294, 71298, 71302, 71306, + 71310, 71314, 71318, 71322, 71326, 71330, 71334, 71338, 71342, 71346, + 71350, 71354, 71358, 71362, 71366, 71370, 71374, 71378, 71382, 71386, + 71390, 71394, 71398, 71402, 71406, 71410, 71414, 71418, 71422, 71426, + 71430, 71434, 71438, 71442, 71446, 71450, 71454, 71458, 71462, 71466, + 71470, 71474, 71478, 71482, 71485, 71489, 71493, 71497, 71501, 71505, + 71509, 71513, 71517, 71521, 71525, 71529, 71533, 71537, 71541, 71545, + 71549, 71553, 71557, 71561, 71565, 71569, 71573, 71577, 71581, 71585, + 71589, 71593, 71597, 71601, 71605, 71609, 71613, 71617, 71621, 71625, + 71629, 71633, 71637, 71641, 71645, 71649, 71653, 71657, 71661, 71665, + 71669, 71673, 71677, 71681, 71685, 71689, 71693, 71697, 71701, 71705, + 71709, 71713, 71717, 71721, 71725, 71729, 71733, 71737, 71740, 71744, + 71748, 71752, 71756, 71760, 71764, 71768, 71772, 71776, 71780, 71784, + 71788, 71792, 71796, 71800, 71804, 71808, 71812, 71816, 71820, 71824, + 71828, 71832, 71836, 71840, 71844, 71848, 71852, 71856, 71860, 71864, + 71868, 71872, 71876, 71880, 71884, 71888, 71892, 71896, 71900, 71904, + 71908, 71912, 71916, 71920, 71924, 71928, 71932, 71936, 71940, 71944, + 71948, 71952, 71956, 71960, 71964, 71968, 71972, 71976, 71980, 71984, + 71988, 71992, 71996, 72000, 72004, 72008, 72012, 72016, 72020, 72024, + 72028, 72032, 72036, 72040, 72044, 72048, 72052, 72056, 72060, 72064, + 72068, 72072, 72076, 72080, 72084, 72088, 72092, 72096, 72100, 72104, + 72108, 72112, 72116, 72120, 72124, 72128, 72132, 72136, 72140, 72144, + 72148, 72152, 72156, 72160, 72164, 72168, 72172, 72176, 72180, 72184, + 72188, 72192, 72195, 72199, 72203, 72207, 72211, 72215, 72219, 72223, + 72227, 72231, 72235, 72239, 72243, 72247, 72251, 72255, 72259, 72263, + 72267, 72271, 72275, 72279, 72283, 72287, 72291, 72295, 72299, 72303, + 72307, 72311, 72315, 72319, 72323, 72327, 72331, 72335, 72339, 72343, + 72347, 72351, 72355, 72359, 72363, 72367, 72371, 72375, 72379, 72383, + 72387, 72391, 72395, 72399, 72403, 72407, 72411, 72415, 72419, 72423, + 72427, 72431, 72435, 72439, 72443, 72447, 72451, 72455, 72459, 72463, + 72467, 72471, 72475, 72479, 72483, 72487, 72491, 72495, 72499, 72503, + 72507, 72511, 72515, 72519, 72523, 72527, 72531, 72535, 72539, 72543, + 72547, 72551, 72555, 72559, 72563, 72567, 72571, 72575, 72579, 72583, + 72587, 72591, 72595, 72599, 72603, 72607, 72611, 72615, 72619, 72623, + 72627, 72631, 72635, 72639, 72643, 72647, 72651, 72655, 72659, 72663, + 72667, 72671, 72675, 72679, 72683, 72687, 72691, 72695, 72699, 72703, + 72707, 72711, 72715, 72719, 72723, 72727, 72731, 72735, 72739, 72743, + 72747, 72751, 72755, 72759, 72763, 72767, 72771, 72775, 72779, 72783, + 72787, 72791, 72795, 72798, 72802, 72806, 72810, 72814, 72818, 72822, + 72826, 72829, 72833, 72837, 72841, 72845, 72849, 72853, 72857, 72861, + 72865, 72869, 72873, 72877, 72881, 72885, 72889, 72893, 72897, 72901, + 72905, 72909, 72913, 72917, 72921, 72925, 72929, 72933, 72937, 72941, + 72945, 72949, 72953, 72957, 72961, 72965, 72969, 72973, 72977, 72981, + 72985, 72989, 72993, 72997, 73001, 73005, 73009, 73013, 73017, 73021, + 73025, 73029, 73033, 73037, 73041, 73045, 73049, 73053, 73057, 73061, + 73065, 73069, 73073, 73077, 73081, 73085, 73089, 73093, 73097, 73101, + 73105, 73109, 73113, 73117, 73121, 73125, 73129, 73133, 73137, 73141, + 73145, 73149, 73153, 73157, 73161, 73165, 73169, 73173, 73177, 73181, + 73185, 73189, 73193, 73197, 73201, 73205, 73209, 73213, 73217, 73221, + 73225, 73229, 73233, 73237, 73241, 73245, 73249, 73253, 73257, 73261, + 73265, 73269, 73273, 73277, 73281, 73285, 73289, 73293, 73297, 73301, + 73305, 73309, 73313, 73317, 73321, 73325, 73329, 73333, 73337, 73341, + 73345, 73349, 73353, 73357, 73361, 73365, 73369, 73373, 73377, 73381, + 73385, 73389, 73393, 73397, 73401, 73405, 73409, 73413, 73417, 73421, + 73425, 73429, 73433, 73437, 73441, 73445, 73449, 73453, 73457, 73461, + 73465, 73469, 73473, 73477, 73481, 73485, 73489, 73493, 73497, 73501, + 73505, 73509, 73513, 73517, 73521, 73525, 73529, 73533, 73537, 73541, + 73545, 73549, 73553, 73556, 73560, 73564, 73568, 73572, 73576, 73580, + 73584, 73588, 73592, 73596, 73600, 73604, 73608, 73612, 73616, 73620, + 73624, 73628, 73632, 73636, 73640, 73644, 73648, 73652, 73656, 73660, + 73664, 73668, 73672, 73676, 73680, 73684, 73688, 73692, 73696, 73700, + 73704, 73708, 73712, 73716, 73720, 73724, 73728, 73732, 73736, 73740, + 73744, 73748, 73752, 73756, 73760, 73764, 73768, 73772, 73776, 73780, + 73784, 73788, 73792, 73796, 73800, 73804, 73808, 73812, 73816, 73820, + 73824, 73828, 73832, 73836, 73840, 73844, 73848, 73852, 73856, 73860, + 73864, 73868, 73872, 73876, 73880, 73884, 73888, 73892, 73896, 73900, + 73904, 73908, 73912, 73916, 73920, 73924, 73928, 73932, 73936, 73940, + 73944, 73948, 73952, 73956, 73960, 73964, 73968, 73972, 73976, 73980, + 73984, 73988, 73992, 73996, 74000, 74004, 74008, 74012, 74016, 74020, + 74024, 74028, 74032, 74036, 74040, 74044, 74048, 74052, 74056, 74060, + 74064, 74068, 74072, 74076, 74080, 74084, 74088, 74092, 74096, 74100, + 74104, 74108, 74112, 74116, 74120, 74124, 74128, 74132, 74136, 74140, + 74144, 74148, 74152, 74156, 74160, 74164, 74168, 74172, 74176, 74180, + 74184, 74188, 74192, 74196, 74200, 74204, 74208, 74212, 74216, 74220, + 74224, 74228, 74232, 74236, 74240, 74244, 74248, 74252, 74256, 74260, + 74264, 74268, 74272, 74276, 74280, 74284, 74288, 74292, 74296, 74300, + 74304, 74308, 74312, 74316, 74320, 74324, 74328, 74332, 74336, 0, 0, 0, + 74340, 74344, 74348, 74352, 74356, 74360, 74364, 74368, 74372, 74376, + 74380, 74384, 74388, 74392, 74396, 74400, 74404, 74408, 74412, 74416, + 74420, 74424, 74428, 74432, 74436, 74440, 74444, 74448, 74452, 74456, + 74460, 74464, 74468, 74472, 74476, 74480, 74484, 74488, 74492, 74496, + 74500, 74504, 74508, 74512, 74516, 74520, 74524, 74528, 74532, 74536, + 74540, 74544, 74548, 74552, 74556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74560, + 74565, 74569, 74574, 74579, 74584, 74589, 74594, 74598, 74603, 74608, + 74613, 74618, 74623, 74628, 74633, 74637, 74641, 74645, 74649, 74654, + 74659, 74664, 74668, 74673, 74678, 74683, 74688, 74693, 74697, 74702, + 74706, 74711, 74715, 74720, 74724, 74728, 74732, 74737, 74742, 74747, + 74755, 74763, 74771, 74779, 74786, 74794, 74800, 74808, 74812, 74816, + 74820, 74824, 74828, 74832, 74836, 74840, 74844, 74848, 74852, 74856, + 74860, 74864, 74868, 74872, 74876, 74880, 74884, 74888, 74892, 74896, + 74900, 74904, 74908, 74912, 74916, 74920, 74924, 74928, 74932, 74936, + 74940, 74944, 74948, 74952, 74955, 74959, 74963, 74967, 74971, 74975, + 74979, 74983, 74987, 74991, 74995, 74999, 75003, 75007, 75011, 75015, + 75019, 75023, 75027, 75031, 75035, 75039, 75043, 75047, 75051, 75055, + 75059, 75063, 75067, 75071, 75075, 75079, 75083, 75087, 75091, 75095, + 75099, 75102, 75106, 75110, 75113, 75117, 75121, 75125, 75128, 75132, + 75136, 75140, 75144, 75148, 75152, 75156, 75160, 75164, 75168, 75172, + 75176, 75180, 75183, 75186, 75190, 75194, 75197, 75201, 75205, 75209, + 75213, 75217, 75221, 75224, 75227, 75231, 75235, 75239, 75242, 75245, + 75249, 75253, 75257, 75261, 75265, 75269, 75273, 75277, 75281, 75285, + 75289, 75293, 75297, 75301, 75305, 75309, 75313, 75317, 75321, 75325, + 75329, 75333, 75337, 75341, 75345, 75349, 75353, 75357, 75361, 75365, + 75369, 75373, 75377, 75381, 75385, 75389, 75393, 75396, 75400, 75404, + 75408, 75412, 75416, 75420, 75424, 75428, 75432, 75436, 75440, 75444, + 75448, 75452, 75456, 75460, 75464, 75468, 75472, 75476, 75480, 75484, + 75488, 75492, 75496, 75500, 75504, 75508, 75512, 75516, 75520, 75524, + 75528, 75532, 75536, 75540, 75543, 75547, 75551, 75555, 75559, 75563, + 75567, 75571, 75575, 75579, 75583, 75587, 75591, 75595, 75599, 75603, + 75607, 75610, 75614, 75618, 75622, 75626, 75630, 75634, 75638, 75642, + 75646, 75650, 75654, 75658, 75662, 75666, 75670, 75674, 75678, 75682, + 75686, 75690, 75694, 75697, 75701, 75705, 75709, 75713, 75717, 75721, + 75725, 75729, 75733, 75737, 75741, 75745, 75749, 75753, 75757, 75761, + 75765, 75769, 75773, 75777, 75781, 75785, 75789, 75793, 75797, 75801, + 75805, 75809, 75813, 75817, 75821, 75825, 75829, 75833, 75837, 75841, + 75845, 75849, 75853, 75857, 75861, 75865, 75869, 75872, 75877, 75881, + 75887, 75892, 75898, 75902, 75906, 75910, 75914, 75918, 75922, 75926, + 75930, 75934, 75938, 75942, 75946, 75950, 75954, 75957, 75960, 75963, + 75966, 75969, 75972, 75975, 75978, 75981, 75986, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75992, 75997, 76002, 76007, 76012, + 76019, 76026, 76031, 76036, 76041, 76046, 76053, 76060, 76067, 76074, + 76081, 76088, 76098, 76108, 76115, 76122, 76129, 76136, 76142, 76148, + 76157, 76166, 76173, 76180, 76191, 76202, 76207, 76212, 76219, 76226, + 76233, 76240, 76247, 76254, 76261, 76268, 76274, 76280, 76286, 76292, + 76299, 76306, 76311, 76315, 76322, 76329, 76336, 76340, 76347, 76351, + 76356, 76360, 76366, 76371, 76377, 76382, 76386, 76390, 76393, 76396, + 76401, 76406, 76411, 76416, 76421, 76426, 76431, 76436, 76441, 76446, + 76454, 76462, 76467, 76472, 76477, 76482, 76487, 76492, 76497, 76502, + 76507, 76512, 76517, 76522, 76527, 76532, 76538, 76544, 76550, 76556, + 76561, 76567, 76570, 76573, 76576, 76580, 76584, 76588, 76592, 76595, + 76599, 76602, 76605, 76608, 76612, 76616, 76620, 76624, 76628, 76632, + 76636, 76640, 76644, 76648, 76652, 76656, 76660, 76664, 76668, 76672, + 76676, 76680, 76684, 76688, 76692, 76696, 76699, 76703, 76707, 76711, + 76715, 76719, 76723, 76727, 76731, 76735, 76739, 76743, 76747, 76751, + 76755, 76759, 76763, 76767, 76771, 76775, 76779, 76783, 76787, 76791, + 76795, 76798, 76802, 76806, 76810, 76814, 76818, 76822, 76826, 76829, + 76833, 76837, 76841, 76845, 76849, 76853, 76857, 76861, 76865, 76869, + 76873, 76877, 76882, 76887, 76890, 76895, 76898, 76901, 76904, 0, 0, 0, + 0, 0, 0, 0, 0, 76908, 76917, 76926, 76935, 76944, 76953, 76962, 76971, + 76980, 76988, 76995, 77003, 77010, 77018, 77028, 77037, 77047, 77056, + 77066, 77074, 77081, 77089, 77096, 77104, 77109, 77114, 77120, 77128, + 77134, 77140, 77147, 77156, 77164, 77172, 77180, 77187, 77194, 77201, + 77208, 77213, 77218, 77223, 77228, 77233, 77238, 77243, 77248, 77256, + 77264, 77270, 77276, 77281, 77286, 77291, 77296, 77301, 77306, 77311, + 77316, 77325, 77334, 77339, 77344, 77354, 77364, 77371, 77378, 77387, + 77396, 77408, 77420, 77426, 77432, 77440, 77448, 77458, 77468, 77475, + 77482, 77487, 77492, 77504, 77516, 77524, 77532, 77542, 77552, 77564, + 77576, 77585, 77594, 77601, 77608, 77615, 77622, 77631, 77640, 77645, + 77650, 77657, 77664, 77671, 77678, 77690, 77702, 77707, 77712, 77717, + 77722, 77727, 77732, 77737, 77742, 77746, 77751, 77756, 77761, 77766, + 77771, 77777, 77782, 77787, 77794, 77801, 77808, 77815, 77822, 77830, + 77838, 77843, 77848, 77854, 77860, 77867, 77874, 77881, 77888, 77895, + 77899, 77906, 77911, 77916, 77922, 77935, 77941, 77949, 77957, 77964, + 77971, 77980, 77989, 77996, 78003, 78010, 78017, 78024, 78031, 78038, + 78045, 78052, 78059, 78068, 78077, 78086, 78095, 78104, 78113, 78122, + 78131, 78140, 78149, 78156, 78164, 78170, 78178, 78184, 78190, 78196, + 78202, 78210, 78215, 78220, 78225, 78230, 78235, 78241, 78247, 78253, + 78259, 78265, 78271, 78277, 78283, 78290, 78297, 78304, 78311, 78320, + 78327, 78336, 78348, 78360, 78372, 0, 0, 0, 0, 0, 78384, 78393, 0, 78402, + 0, 78408, 78414, 78422, 78430, 78437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78444, 78449, 78454, 78459, 78467, + 78475, 78482, 78489, 78495, 78502, 78510, 78518, 78526, 78534, 78542, + 78548, 78554, 78561, 78567, 78573, 78579, 78586, 78593, 78600, 78607, + 78614, 78621, 78628, 78635, 78642, 78649, 78656, 78663, 78670, 78677, + 78683, 78690, 78697, 78704, 78711, 78718, 78725, 78732, 78739, 78746, + 78753, 78760, 78767, 78774, 78781, 78788, 78795, 78802, 78809, 78817, + 78825, 78833, 78841, 78849, 0, 0, 0, 78858, 78866, 78874, 78882, 78890, + 78898, 78906, 78912, 78918, 78924, 0, 0, 0, 0, 0, 0, 78930, 78934, 78939, + 78944, 78949, 78954, 78959, 78964, 78969, 78974, 78979, 78984, 78988, + 78992, 78997, 79002, 79006, 79011, 79016, 79021, 79026, 79031, 79036, + 79041, 79045, 79049, 79053, 79058, 79062, 79066, 79070, 79074, 79078, + 79082, 79086, 79091, 79096, 79101, 79106, 79111, 79118, 79124, 79129, + 79134, 79139, 79144, 79150, 79157, 79163, 79170, 79176, 79182, 79187, + 79194, 79200, 79205, 0, 0, 0, 0, 0, 0, 0, 0, 79211, 79216, 79221, 79225, + 79230, 79234, 79239, 79243, 79248, 79253, 79259, 79264, 79270, 79274, + 79279, 79284, 79288, 79293, 79298, 79302, 79307, 79312, 79317, 79322, + 79327, 79332, 79337, 79342, 79347, 79352, 79357, 79362, 79367, 79372, + 79377, 79382, 79387, 79392, 79396, 79400, 79405, 79410, 79415, 79419, + 79423, 79427, 79431, 79436, 79441, 79446, 79450, 79454, 79459, 79465, + 79471, 79476, 79482, 79487, 79493, 79499, 79506, 79512, 79519, 79524, + 79530, 79536, 79541, 79547, 79553, 79558, 0, 0, 0, 0, 0, 0, 0, 0, 79563, + 79567, 79572, 79577, 79581, 79585, 79589, 79593, 79597, 79601, 79605, + 79609, 0, 0, 0, 0, 0, 0, 79613, 79618, 79622, 79626, 79630, 79634, 79638, + 79642, 79646, 79650, 79654, 79658, 79662, 79666, 79670, 79674, 79678, + 79683, 79688, 79694, 79700, 79707, 79712, 79717, 79723, 79727, 79732, + 79735, 79738, 79742, 79747, 79751, 79756, 79763, 79769, 79775, 79781, + 79787, 79793, 79799, 79805, 79811, 79817, 79823, 79830, 79837, 79844, + 79850, 79857, 79864, 79871, 79878, 79885, 79891, 79897, 79904, 79910, + 79917, 79924, 79930, 79936, 79942, 79949, 79956, 79962, 79969, 79976, + 79982, 79989, 79995, 80002, 80009, 80015, 80021, 80028, 80034, 80041, + 80048, 80057, 80064, 80071, 80075, 80080, 80085, 80090, 80095, 80099, + 80103, 80108, 80112, 80117, 80122, 80127, 80131, 80135, 80139, 80143, + 80148, 80152, 80157, 80162, 80167, 80172, 80176, 80181, 80186, 80191, + 80197, 80202, 80208, 80214, 80220, 80226, 80232, 80237, 80243, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80247, 80252, 80256, 80260, 80264, 80268, 80272, 80276, 80280, 80284, 80288, 80292, 80296, 80300, 80304, 80308, 80312, - 80316, 80320, 0, 0, 0, 80324, 80329, 80334, 80339, 80344, 80348, 80355, - 80359, 80364, 80368, 80375, 80382, 80391, 80395, 80400, 80404, 80408, - 80415, 80422, 80427, 80434, 80439, 80444, 80451, 80456, 80463, 80470, - 80475, 80480, 80487, 80492, 80499, 80506, 80511, 80518, 80523, 80530, - 80534, 80538, 80545, 80550, 80557, 80561, 80565, 80569, 80576, 80580, - 80585, 80592, 80599, 80603, 80607, 80614, 80620, 80626, 80632, 80640, - 80646, 80654, 80660, 80668, 80674, 80680, 80686, 80692, 80696, 80701, - 80706, 80712, 80718, 80724, 80730, 80736, 80742, 80748, 80754, 80762, - 80768, 0, 80775, 80779, 80784, 80788, 80792, 80796, 80800, 80804, 80808, - 80812, 80816, 0, 0, 0, 0, 80820, 80828, 80834, 80840, 80846, 80852, - 80858, 80864, 80870, 80877, 80884, 80891, 80898, 80905, 80912, 80919, - 80926, 80933, 80940, 80947, 80953, 80959, 80965, 80971, 80977, 80983, - 80989, 80995, 81001, 81008, 81015, 81022, 81029, 0, 81036, 81040, 81044, - 81048, 81052, 81057, 81061, 81065, 81070, 81075, 81080, 81085, 81090, - 81095, 81100, 81105, 81110, 81115, 81120, 81125, 81130, 81135, 81140, - 81145, 81150, 81154, 81159, 81163, 81168, 81173, 81178, 81183, 81188, - 81192, 81197, 81201, 81205, 81209, 81214, 81219, 81223, 81227, 81233, - 81238, 81244, 81250, 81255, 81261, 81266, 81272, 81278, 81284, 81289, - 81294, 81299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81305, 81311, 81317, 81323, - 81330, 81336, 81342, 81348, 81354, 81360, 81365, 81370, 81376, 81383, 0, - 0, 81390, 81395, 81399, 81403, 81407, 81411, 81415, 81419, 81423, 81427, - 0, 0, 81431, 81437, 81443, 81450, 81458, 81464, 81470, 81476, 81482, - 81488, 81494, 81500, 81506, 81512, 81518, 81524, 81529, 81534, 81539, - 81545, 81551, 81558, 81564, 81570, 81575, 81582, 81589, 81596, 81602, - 81607, 81612, 81617, 81625, 81632, 81639, 81647, 81655, 81662, 81669, - 81676, 81683, 81690, 81697, 81704, 81711, 81718, 81725, 81732, 81739, - 81746, 81753, 81760, 81767, 81774, 81781, 81788, 81795, 81801, 81807, - 81814, 81821, 81828, 81835, 81842, 81849, 81856, 81863, 81870, 81877, - 81884, 81891, 81898, 81905, 81912, 81919, 81926, 81933, 81940, 81947, - 81954, 81961, 81968, 81975, 81981, 81987, 81994, 82000, 82005, 82011, - 82016, 82021, 82026, 82033, 82039, 82045, 82051, 82057, 82063, 82069, - 82075, 82083, 82091, 82099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 82107, 82113, 82119, 82125, 82133, 82141, - 82147, 82153, 82160, 82167, 82174, 82181, 82188, 82195, 82202, 82209, - 82216, 82224, 82232, 82240, 82248, 82256, 82262, 82270, 82276, 82284, - 82293, 82301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82307, 82311, 82315, 82319, - 82323, 82327, 0, 0, 82331, 82335, 82339, 82343, 82347, 82351, 0, 0, - 82355, 82359, 82363, 82367, 82371, 82375, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82379, 82383, 82387, 82391, 82395, 82399, 82403, 0, 82407, 82411, 82415, - 82419, 82423, 82427, 82431, 0, 82435, 82442, 82448, 82454, 82460, 82468, - 82475, 82484, 82496, 82506, 82515, 82523, 82531, 82539, 82545, 82553, - 82561, 82568, 82576, 82586, 82593, 82602, 82608, 82618, 82627, 82632, - 82640, 82649, 82654, 82663, 82670, 82680, 82692, 82697, 82703, 82710, - 82715, 82725, 82735, 82745, 82755, 82770, 82783, 82794, 82802, 82807, - 82819, 82828, 82835, 82842, 82848, 82855, 82860, 82867, 82873, 82884, - 82895, 82905, 82911, 82916, 0, 0, 0, 0, 82921, 82925, 82929, 82933, - 82937, 82941, 82946, 82951, 82955, 82960, 82965, 82970, 82975, 82980, - 82984, 82989, 82994, 82999, 83004, 83009, 83013, 83018, 83023, 83028, - 83033, 83038, 83042, 83047, 83052, 83057, 83062, 83066, 83071, 83076, - 83081, 83086, 83091, 83096, 83101, 83106, 83111, 83116, 83121, 83126, - 83131, 83135, 83140, 83145, 83150, 83155, 83160, 83165, 83170, 83175, - 83180, 83185, 83190, 83195, 83200, 83205, 83210, 83215, 83220, 83225, - 83230, 83235, 83240, 83245, 83250, 83255, 83260, 83265, 83270, 83275, - 83280, 83285, 83290, 83295, 83300, 83305, 83309, 83316, 83323, 83330, - 83337, 83343, 83349, 83356, 83363, 83370, 83377, 83384, 83391, 83398, - 83405, 83412, 83418, 83425, 83432, 83439, 83446, 83453, 83460, 83467, - 83474, 83481, 83488, 83495, 83504, 83513, 83522, 83531, 83540, 83549, - 83558, 83567, 83575, 83583, 83591, 83599, 83607, 83615, 83623, 83631, - 83637, 83645, 0, 0, 83653, 83660, 83666, 83672, 83678, 83684, 83690, - 83696, 83702, 83708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80316, 80320, 80324, 80328, 80332, 80336, 80340, 80344, 80348, 80352, + 80356, 80360, 80364, 0, 0, 0, 80368, 80373, 80378, 80383, 80388, 80392, + 80399, 80403, 80408, 80412, 80419, 80426, 80435, 80439, 80444, 80448, + 80452, 80459, 80466, 80471, 80478, 80483, 80488, 80495, 80500, 80507, + 80514, 80519, 80524, 80531, 80536, 80543, 80550, 80555, 80562, 80567, + 80574, 80578, 80582, 80589, 80594, 80601, 80605, 80609, 80613, 80620, + 80624, 80629, 80636, 80643, 80647, 80651, 80658, 80664, 80670, 80676, + 80684, 80690, 80698, 80704, 80712, 80718, 80724, 80730, 80736, 80740, + 80745, 80750, 80756, 80762, 80768, 80774, 80780, 80786, 80792, 80798, + 80806, 80812, 0, 80819, 80823, 80828, 80832, 80836, 80840, 80844, 80848, + 80852, 80856, 80860, 0, 0, 0, 0, 80864, 80872, 80878, 80884, 80890, + 80896, 80902, 80908, 80914, 80921, 80928, 80935, 80942, 80949, 80956, + 80963, 80970, 80977, 80984, 80991, 80997, 81003, 81009, 81015, 81021, + 81027, 81033, 81039, 81045, 81052, 81059, 81066, 81073, 0, 81080, 81084, + 81088, 81092, 81096, 81101, 81105, 81109, 81114, 81119, 81124, 81129, + 81134, 81139, 81144, 81149, 81154, 81159, 81164, 81169, 81174, 81179, + 81184, 81189, 81194, 81198, 81203, 81207, 81212, 81217, 81222, 81227, + 81232, 81236, 81241, 81245, 81249, 81253, 81258, 81263, 81267, 81271, + 81277, 81282, 81288, 81294, 81299, 81305, 81310, 81316, 81322, 81328, + 81333, 81338, 81343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81349, 81355, 81361, + 81367, 81374, 81380, 81386, 81392, 81398, 81404, 81409, 81414, 81420, + 81427, 0, 0, 81434, 81439, 81443, 81447, 81451, 81455, 81459, 81463, + 81467, 81471, 0, 0, 81475, 81481, 81487, 81494, 81502, 81508, 81514, + 81520, 81526, 81532, 81538, 81544, 81550, 81556, 81562, 81568, 81573, + 81578, 81583, 81589, 81595, 81602, 81608, 81614, 81619, 81626, 81633, + 81640, 81646, 81651, 81656, 81661, 81669, 81676, 81683, 81691, 81699, + 81706, 81713, 81720, 81727, 81734, 81741, 81748, 81755, 81762, 81769, + 81776, 81783, 81790, 81797, 81804, 81811, 81818, 81825, 81832, 81839, + 81845, 81851, 81858, 81865, 81872, 81879, 81886, 81893, 81900, 81907, + 81914, 81921, 81928, 81935, 81942, 81949, 81956, 81963, 81970, 81977, + 81984, 81991, 81998, 82005, 82012, 82019, 82025, 82031, 82038, 82044, + 82049, 82055, 82060, 82065, 82070, 82077, 82083, 82089, 82095, 82101, + 82107, 82113, 82119, 82127, 82135, 82143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82151, 82157, 82163, 82169, + 82177, 82185, 82191, 82197, 82204, 82211, 82218, 82225, 82232, 82239, + 82246, 82253, 82260, 82268, 82276, 82284, 82292, 82300, 82306, 82314, + 82320, 82328, 82337, 82345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82351, 82355, + 82359, 82363, 82367, 82371, 0, 0, 82375, 82379, 82383, 82387, 82391, + 82395, 0, 0, 82399, 82403, 82407, 82411, 82415, 82419, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82423, 82427, 82431, 82435, 82439, 82443, 82447, 0, 82451, + 82455, 82459, 82463, 82467, 82471, 82475, 0, 82479, 82486, 82492, 82498, + 82504, 82512, 82519, 82528, 82540, 82550, 82559, 82567, 82575, 82583, + 82589, 82597, 82605, 82612, 82620, 82630, 82637, 82646, 82652, 82662, + 82671, 82676, 82684, 82693, 82698, 82707, 82714, 82724, 82736, 82741, + 82747, 82754, 82759, 82769, 82779, 82789, 82799, 82814, 82827, 82838, + 82846, 82851, 82863, 82872, 82879, 82886, 82892, 82899, 82904, 82911, + 82917, 82928, 82939, 82949, 82955, 82960, 0, 0, 0, 0, 82965, 82969, + 82973, 82977, 82981, 82985, 82990, 82995, 82999, 83004, 83009, 83014, + 83019, 83024, 83028, 83033, 83038, 83043, 83048, 83053, 83057, 83062, + 83067, 83072, 83077, 83082, 83086, 83091, 83096, 83101, 83106, 83110, + 83115, 83120, 83125, 83130, 83135, 83140, 83145, 83150, 83155, 83160, + 83165, 83170, 83175, 83179, 83184, 83189, 83194, 83199, 83204, 83209, + 83214, 83219, 83224, 83229, 83234, 83239, 83244, 83249, 83254, 83259, + 83264, 83269, 83274, 83279, 83284, 83289, 83294, 83299, 83304, 83309, + 83314, 83319, 83324, 83329, 83334, 83339, 83344, 83349, 83353, 83360, + 83367, 83374, 83381, 83387, 83393, 83400, 83407, 83414, 83421, 83428, + 83435, 83442, 83449, 83456, 83462, 83469, 83476, 83483, 83490, 83497, + 83504, 83511, 83518, 83525, 83532, 83539, 83548, 83557, 83566, 83575, + 83584, 83593, 83602, 83611, 83619, 83627, 83635, 83643, 83651, 83659, + 83667, 83675, 83681, 83689, 0, 0, 83697, 83704, 83710, 83716, 83722, + 83728, 83734, 83740, 83746, 83752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83714, 83719, 83724, 83729, 83734, - 83739, 83744, 83749, 83754, 83759, 83764, 83769, 83774, 83779, 83784, - 83789, 83794, 83799, 83804, 83809, 83814, 83819, 83824, 0, 0, 0, 0, - 83829, 83833, 83837, 83841, 83845, 83849, 83853, 83857, 83861, 83865, - 83869, 83873, 83877, 83881, 83885, 83889, 83893, 83897, 83901, 83905, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83758, 83763, 83768, + 83773, 83778, 83783, 83788, 83793, 83798, 83803, 83808, 83813, 83818, + 83823, 83828, 83833, 83838, 83843, 83848, 83853, 83858, 83863, 83868, 0, + 0, 0, 0, 83873, 83877, 83881, 83885, 83889, 83893, 83897, 83901, 83905, 83909, 83913, 83917, 83921, 83925, 83929, 83933, 83937, 83941, 83945, 83949, 83953, 83957, 83961, 83965, 83969, 83973, 83977, 83981, 83985, - 83989, 83993, 83997, 84001, 84005, 84009, 84013, 84017, 84021, 0, 0, 0, - 0, 84025, 84029, 84033, 84037, 84041, 84045, 84049, 84053, 84057, 84061, - 84065, 84069, 84073, 84077, 84081, 84085, 84089, 84093, 84097, 84101, + 83989, 83993, 83997, 84001, 84005, 84009, 84013, 84017, 84021, 84025, + 84029, 84033, 84037, 84041, 84045, 84049, 84053, 84057, 84061, 84065, 0, + 0, 0, 0, 84069, 84073, 84077, 84081, 84085, 84089, 84093, 84097, 84101, 84105, 84109, 84113, 84117, 84121, 84125, 84129, 84133, 84137, 84141, 84145, 84149, 84153, 84157, 84161, 84165, 84169, 84173, 84177, 84181, 84185, 84189, 84193, 84197, 84201, 84205, 84209, 84213, 84217, 84221, @@ -22893,8 +22898,8 @@ static const unsigned int phrasebook_offset2[] = { 85345, 85349, 85353, 85357, 85361, 85365, 85369, 85373, 85377, 85381, 85385, 85389, 85393, 85397, 85401, 85405, 85409, 85413, 85417, 85421, 85425, 85429, 85433, 85437, 85441, 85445, 85449, 85453, 85457, 85461, - 85465, 85469, 85473, 85477, 85481, 85485, 0, 0, 85489, 85493, 85497, - 85501, 85505, 85509, 85513, 85517, 85521, 85525, 85529, 85533, 85537, + 85465, 85469, 85473, 85477, 85481, 85485, 85489, 85493, 85497, 85501, + 85505, 85509, 85513, 85517, 85521, 85525, 85529, 0, 0, 85533, 85537, 85541, 85545, 85549, 85553, 85557, 85561, 85565, 85569, 85573, 85577, 85581, 85585, 85589, 85593, 85597, 85601, 85605, 85609, 85613, 85617, 85621, 85625, 85629, 85633, 85637, 85641, 85645, 85649, 85653, 85657, @@ -22904,731 +22909,732 @@ static const unsigned int phrasebook_offset2[] = { 85781, 85785, 85789, 85793, 85797, 85801, 85805, 85809, 85813, 85817, 85821, 85825, 85829, 85833, 85837, 85841, 85845, 85849, 85853, 85857, 85861, 85865, 85869, 85873, 85877, 85881, 85885, 85889, 85893, 85897, - 85901, 85905, 85909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85913, - 85918, 85923, 85928, 85933, 85938, 85946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 85951, 85959, 85967, 85975, 85983, 0, 0, 0, 0, 0, 85991, 85998, - 86005, 86015, 86021, 86027, 86033, 86039, 86045, 86051, 86058, 86064, - 86070, 86076, 86085, 86094, 86106, 86118, 86124, 86130, 86136, 86143, - 86150, 86157, 86164, 86171, 0, 86178, 86185, 86192, 86200, 86207, 0, - 86214, 0, 86221, 86228, 0, 86235, 86243, 0, 86250, 86257, 86264, 86271, - 86278, 86285, 86292, 86299, 86306, 86313, 86318, 86325, 86332, 86338, - 86344, 86350, 86357, 86363, 86369, 86375, 86382, 86388, 86394, 86400, - 86407, 86413, 86419, 86425, 86432, 86438, 86444, 86450, 86457, 86463, - 86469, 86475, 86482, 86488, 86494, 86500, 86507, 86513, 86519, 86525, - 86532, 86538, 86544, 86550, 86557, 86563, 86569, 86575, 86582, 86588, - 86594, 86600, 86607, 86613, 86619, 86625, 86632, 86638, 86644, 86650, - 86656, 86662, 86668, 86674, 86680, 86686, 86692, 86698, 86704, 86710, - 86716, 86722, 86729, 86735, 86741, 86747, 86754, 86760, 86766, 86772, - 86779, 86785, 86791, 86797, 86804, 86812, 86820, 86826, 86832, 86838, - 86845, 86854, 86863, 86871, 86879, 86887, 86896, 86904, 86912, 86920, - 86929, 86936, 86943, 86954, 86965, 86969, 86973, 86978, 86983, 86988, - 86993, 87002, 87011, 87017, 87023, 87030, 87037, 87044, 87048, 87054, - 87060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87065, 87071, - 87077, 87083, 87090, 87095, 87100, 87106, 87112, 87118, 87124, 87133, - 87139, 87145, 87153, 87161, 87169, 87177, 87183, 87189, 87195, 87202, - 87215, 87229, 87240, 87251, 87263, 87275, 87287, 87299, 87310, 87321, - 87333, 87345, 87357, 87369, 87381, 87393, 87405, 87422, 87439, 87456, - 87463, 87470, 87477, 87485, 87497, 87508, 87519, 87532, 87543, 87552, - 87560, 87569, 87577, 87587, 87595, 87604, 87612, 87621, 87629, 87639, - 87647, 87656, 87664, 87674, 87682, 87690, 87698, 87706, 87713, 87722, - 87730, 87738, 87747, 87755, 87764, 87772, 87780, 87788, 87797, 87805, - 87814, 87822, 87830, 87838, 87846, 87855, 87863, 87872, 87880, 87889, - 87897, 87906, 87914, 87924, 87932, 87940, 87948, 87958, 87966, 87974, - 87983, 87991, 88000, 88009, 88017, 88027, 88035, 88044, 88052, 88061, - 88069, 88079, 88087, 88095, 88102, 88110, 88117, 88126, 88133, 88142, - 88150, 88159, 88167, 88177, 88185, 88194, 88202, 88212, 88220, 88228, - 88235, 88243, 88250, 88259, 88266, 88276, 88286, 88297, 88306, 88315, - 88324, 88333, 88342, 88352, 88364, 88376, 88387, 88399, 88412, 88423, - 88432, 88441, 88449, 88458, 88468, 88476, 88485, 88494, 88502, 88511, - 88521, 88529, 88538, 88547, 88555, 88564, 88574, 88582, 88592, 88600, - 88610, 88618, 88626, 88635, 88643, 88653, 88661, 88669, 88679, 88687, - 88694, 88701, 88710, 88719, 88727, 88736, 88746, 88754, 88765, 88773, - 88781, 88788, 88796, 88805, 88812, 88824, 88835, 88847, 88858, 88870, - 88879, 88887, 88896, 88904, 88913, 88922, 88930, 88939, 88947, 88956, - 88964, 88972, 88980, 88988, 88995, 89004, 89012, 89021, 89029, 89038, - 89046, 89054, 89063, 89071, 89080, 89088, 89097, 89105, 89113, 89121, - 89130, 89138, 89147, 89155, 89164, 89172, 89181, 89189, 89197, 89205, - 89214, 89222, 89231, 89240, 89248, 89257, 89265, 89274, 89282, 89291, - 89299, 89306, 89314, 89321, 89330, 89338, 89347, 89355, 89364, 89373, - 89381, 89391, 89399, 89406, 89414, 89421, 89429, 89441, 89454, 89463, - 89473, 89482, 89492, 89501, 89511, 89520, 89530, 89539, 89549, 89559, - 89568, 89577, 89586, 89596, 89604, 89613, 89623, 89633, 89643, 89653, - 89661, 89671, 89679, 89689, 89697, 89707, 89715, 89725, 89733, 89742, - 89749, 89759, 89767, 89777, 89785, 89795, 89803, 89813, 89821, 89830, - 89838, 89847, 89855, 89864, 89873, 89882, 89891, 89901, 89909, 89919, - 89927, 89937, 89945, 89955, 89963, 89973, 89981, 89990, 89997, 90007, - 90015, 90025, 90033, 90043, 90051, 90061, 90069, 90078, 90086, 90095, - 90103, 90112, 90121, 90130, 90139, 90148, 90156, 90165, 90173, 90182, - 90191, 90199, 90209, 90218, 90228, 90238, 90247, 90257, 90266, 90275, - 90283, 90291, 90296, 90301, 90307, 90315, 90323, 90331, 90339, 90347, - 90355, 90361, 90367, 90373, 90381, 90387, 90397, 90403, 90409, 90415, - 90426, 90437, 90448, 90458, 90469, 90480, 90490, 90501, 90511, 90521, - 90530, 90541, 90552, 90563, 90576, 90586, 90596, 90607, 90617, 90627, - 90637, 90647, 90657, 90667, 90677, 90688, 90699, 90710, 90720, 90730, - 90742, 90753, 90764, 90774, 90784, 90794, 90804, 90815, 90825, 90835, - 90847, 90857, 90867, 90879, 90890, 90901, 90911, 90921, 90931, 90941, - 90953, 90965, 90977, 90988, 90999, 91009, 91019, 91029, 91038, 91047, - 91057, 91067, 91078, 0, 0, 91088, 91099, 91110, 91120, 91130, 91142, - 91153, 91164, 91177, 91187, 91199, 91208, 91217, 91228, 91239, 91252, - 91263, 91276, 91286, 91298, 91308, 91320, 91332, 91345, 91355, 91365, - 91375, 91386, 91396, 91405, 91415, 91424, 91433, 91443, 91453, 91463, - 91473, 91483, 91493, 91504, 91514, 91525, 91535, 91546, 91557, 91567, - 91577, 91587, 91597, 91607, 91617, 91628, 91638, 91649, 0, 0, 0, 0, 0, 0, - 0, 91660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91666, 91681, 91696, 91702, 91708, - 91714, 91720, 91726, 91732, 91738, 91744, 91752, 91756, 91759, 91767, - 91775, 91783, 91786, 91789, 91792, 91795, 91798, 91801, 91804, 91807, - 91810, 91813, 91816, 91819, 91822, 91825, 91828, 91831, 91839, 91848, - 91859, 91867, 91875, 91884, 91893, 91905, 91917, 0, 0, 0, 0, 0, 0, 91927, - 91932, 91937, 91944, 91951, 91957, 91963, 91968, 91973, 91978, 91984, - 91990, 91996, 92002, 92008, 92015, 92022, 92032, 92042, 92052, 92061, - 92072, 92081, 92090, 92101, 92112, 92125, 92138, 92150, 92162, 92174, - 92186, 92197, 92208, 92219, 92230, 92242, 92254, 92258, 92263, 92273, - 92283, 92287, 92291, 92295, 92300, 92305, 92310, 92315, 92318, 92322, 0, - 92327, 92330, 92333, 92337, 92341, 92346, 92350, 92354, 92360, 92366, - 92374, 92382, 92385, 92388, 92391, 92394, 92397, 92401, 92405, 0, 92409, - 92414, 92418, 92422, 0, 0, 0, 0, 92427, 92432, 92439, 92444, 92449, 0, - 92454, 92459, 92465, 92470, 92476, 92481, 92487, 92492, 92498, 92503, - 92509, 92515, 92524, 92533, 92542, 92551, 92561, 92571, 92581, 92591, - 92600, 92609, 92618, 92628, 92633, 92638, 92644, 92650, 92656, 92663, - 92671, 92679, 92685, 92691, 92697, 92704, 92710, 92716, 92722, 92729, - 92735, 92741, 92747, 92754, 92759, 92764, 92769, 92775, 92781, 92787, - 92793, 92800, 92806, 92812, 92818, 92824, 92830, 92836, 92842, 92848, - 92854, 92860, 92866, 92873, 92879, 92885, 92891, 92898, 92904, 92910, - 92916, 92923, 92929, 92935, 92941, 92948, 92954, 92960, 92966, 92973, - 92979, 92985, 92991, 92998, 93004, 93010, 93016, 93023, 93029, 93035, - 93041, 93048, 93054, 93060, 93066, 93073, 93079, 93085, 93091, 93098, - 93104, 93110, 93116, 93123, 93129, 93135, 93141, 93148, 93153, 93158, - 93163, 93169, 93175, 93181, 93187, 93194, 93200, 93206, 93212, 93219, - 93225, 93231, 93238, 93245, 93250, 93255, 93260, 93266, 93278, 93290, - 93302, 93314, 93327, 93340, 93348, 0, 0, 93356, 0, 93364, 93369, 93374, - 93378, 93383, 93388, 93392, 93396, 93401, 93406, 93410, 93414, 93418, - 93422, 93428, 93432, 93437, 93441, 93445, 93449, 93453, 93457, 93461, - 93465, 93469, 93473, 93477, 93481, 93486, 93491, 93496, 93501, 93507, - 93513, 93520, 93527, 93534, 93540, 93547, 93554, 93561, 93567, 93574, - 93581, 93587, 93594, 93601, 93607, 93614, 93621, 93627, 93634, 93641, - 93647, 93654, 93661, 93668, 93675, 93682, 93688, 93694, 93700, 93706, - 93711, 93717, 93723, 93730, 93737, 93744, 93750, 93757, 93764, 93771, - 93777, 93784, 93791, 93797, 93804, 93811, 93817, 93824, 93831, 93837, - 93844, 93851, 93857, 93864, 93871, 93878, 93885, 93892, 93899, 93904, - 93911, 93915, 93921, 93927, 93933, 93939, 93945, 93949, 93954, 93959, - 93964, 93969, 93974, 93979, 93984, 93989, 93995, 94001, 94007, 94015, - 94019, 94023, 94027, 94031, 94035, 94039, 94044, 94049, 94054, 94059, - 94063, 94068, 94073, 94078, 94083, 94088, 94093, 94098, 94103, 94107, - 94111, 94116, 94121, 94126, 94131, 94135, 94140, 94145, 94150, 94155, - 94159, 94164, 94169, 94174, 94179, 94183, 94188, 94193, 94197, 94202, - 94207, 94212, 94217, 94222, 94227, 94234, 94241, 94245, 94250, 94255, - 94260, 94265, 94270, 94275, 94280, 94285, 94290, 94295, 94300, 94305, - 94310, 94315, 94320, 94325, 94330, 94335, 94340, 94345, 94350, 94355, - 94360, 94365, 94370, 94375, 94380, 94385, 94390, 0, 0, 0, 94395, 94399, - 94404, 94408, 94413, 94418, 0, 0, 94422, 94427, 94432, 94436, 94441, - 94446, 0, 0, 94451, 94456, 94460, 94465, 94470, 94475, 0, 0, 94480, - 94485, 94490, 0, 0, 0, 94494, 94499, 94504, 94509, 94513, 94518, 94523, - 0, 94528, 94534, 94537, 94541, 94544, 94548, 94552, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 94556, 94562, 94568, 94574, 94580, 0, 0, 94584, 94590, 94596, - 94602, 94608, 94614, 94621, 94628, 94635, 94642, 94649, 94656, 0, 94663, - 94670, 94677, 94683, 94690, 94697, 94704, 94711, 94717, 94724, 94731, - 94738, 94745, 94751, 94758, 94765, 94772, 94779, 94785, 94792, 94799, - 94806, 94813, 94820, 94827, 94834, 0, 94841, 94847, 94854, 94861, 94868, - 94875, 94881, 94888, 94895, 94902, 94909, 94916, 94923, 94930, 94936, - 94943, 94950, 94957, 94964, 0, 94971, 94978, 0, 94985, 94992, 94999, - 95006, 95013, 95020, 95027, 95034, 95041, 95048, 95055, 95062, 95069, - 95076, 95083, 0, 0, 95089, 95094, 95099, 95104, 95109, 95114, 95119, - 95124, 95129, 95134, 95139, 95144, 95149, 95154, 0, 0, 0, 0, 0, 0, 0, 0, + 85901, 85905, 85909, 85913, 85917, 85921, 85925, 85929, 85933, 85937, + 85941, 85945, 85949, 85953, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85957, 85962, 85967, 85972, 85977, 85982, 85990, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85995, 86003, 86011, 86019, 86027, 0, 0, 0, 0, 0, 86035, + 86042, 86049, 86059, 86065, 86071, 86077, 86083, 86089, 86095, 86102, + 86108, 86114, 86120, 86129, 86138, 86150, 86162, 86168, 86174, 86180, + 86187, 86194, 86201, 86208, 86215, 0, 86222, 86229, 86236, 86244, 86251, + 0, 86258, 0, 86265, 86272, 0, 86279, 86287, 0, 86294, 86301, 86308, + 86315, 86322, 86329, 86336, 86343, 86350, 86357, 86362, 86369, 86376, + 86382, 86388, 86394, 86401, 86407, 86413, 86419, 86426, 86432, 86438, + 86444, 86451, 86457, 86463, 86469, 86476, 86482, 86488, 86494, 86501, + 86507, 86513, 86519, 86526, 86532, 86538, 86544, 86551, 86557, 86563, + 86569, 86576, 86582, 86588, 86594, 86601, 86607, 86613, 86619, 86626, + 86632, 86638, 86644, 86651, 86657, 86663, 86669, 86676, 86682, 86688, + 86694, 86700, 86706, 86712, 86718, 86724, 86730, 86736, 86742, 86748, + 86754, 86760, 86766, 86773, 86779, 86785, 86791, 86798, 86804, 86810, + 86816, 86823, 86829, 86835, 86841, 86848, 86856, 86864, 86870, 86876, + 86882, 86889, 86898, 86907, 86915, 86923, 86931, 86940, 86948, 86956, + 86964, 86973, 86980, 86987, 86998, 87009, 87013, 87017, 87022, 87027, + 87032, 87037, 87046, 87055, 87061, 87067, 87074, 87081, 87088, 87092, + 87098, 87104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87109, + 87115, 87121, 87127, 87134, 87139, 87144, 87150, 87156, 87162, 87168, + 87177, 87183, 87189, 87197, 87205, 87213, 87221, 87227, 87233, 87239, + 87246, 87259, 87273, 87284, 87295, 87307, 87319, 87331, 87343, 87354, + 87365, 87377, 87389, 87401, 87413, 87425, 87437, 87449, 87466, 87483, + 87500, 87507, 87514, 87521, 87529, 87541, 87552, 87563, 87576, 87587, + 87596, 87604, 87613, 87621, 87631, 87639, 87648, 87656, 87665, 87673, + 87683, 87691, 87700, 87708, 87718, 87726, 87734, 87742, 87750, 87757, + 87766, 87774, 87782, 87791, 87799, 87808, 87816, 87824, 87832, 87841, + 87849, 87858, 87866, 87874, 87882, 87890, 87899, 87907, 87916, 87924, + 87933, 87941, 87950, 87958, 87968, 87976, 87984, 87992, 88002, 88010, + 88018, 88027, 88035, 88044, 88053, 88061, 88071, 88079, 88088, 88096, + 88105, 88113, 88123, 88131, 88139, 88146, 88154, 88161, 88170, 88177, + 88186, 88194, 88203, 88211, 88221, 88229, 88238, 88246, 88256, 88264, + 88272, 88279, 88287, 88294, 88303, 88310, 88320, 88330, 88341, 88350, + 88359, 88368, 88377, 88386, 88396, 88408, 88420, 88431, 88443, 88456, + 88467, 88476, 88485, 88493, 88502, 88512, 88520, 88529, 88538, 88546, + 88555, 88565, 88573, 88582, 88591, 88599, 88608, 88618, 88626, 88636, + 88644, 88654, 88662, 88670, 88679, 88687, 88697, 88705, 88713, 88723, + 88731, 88738, 88745, 88754, 88763, 88771, 88780, 88790, 88798, 88809, + 88817, 88825, 88832, 88840, 88849, 88856, 88868, 88879, 88891, 88902, + 88914, 88923, 88931, 88940, 88948, 88957, 88966, 88974, 88983, 88991, + 89000, 89008, 89016, 89024, 89032, 89039, 89048, 89056, 89065, 89073, + 89082, 89090, 89098, 89107, 89115, 89124, 89132, 89141, 89149, 89157, + 89165, 89174, 89182, 89191, 89199, 89208, 89216, 89225, 89233, 89241, + 89249, 89258, 89266, 89275, 89284, 89292, 89301, 89309, 89318, 89326, + 89335, 89343, 89350, 89358, 89365, 89374, 89382, 89391, 89399, 89408, + 89417, 89425, 89435, 89443, 89450, 89458, 89465, 89473, 89485, 89498, + 89507, 89517, 89526, 89536, 89545, 89555, 89564, 89574, 89583, 89593, + 89603, 89612, 89621, 89630, 89640, 89648, 89657, 89667, 89677, 89687, + 89697, 89705, 89715, 89723, 89733, 89741, 89751, 89759, 89769, 89777, + 89786, 89793, 89803, 89811, 89821, 89829, 89839, 89847, 89857, 89865, + 89874, 89882, 89891, 89899, 89908, 89917, 89926, 89935, 89945, 89953, + 89963, 89971, 89981, 89989, 89999, 90007, 90017, 90025, 90034, 90041, + 90051, 90059, 90069, 90077, 90087, 90095, 90105, 90113, 90122, 90130, + 90139, 90147, 90156, 90165, 90174, 90183, 90192, 90200, 90209, 90217, + 90226, 90235, 90243, 90253, 90262, 90272, 90282, 90291, 90301, 90310, + 90319, 90327, 90335, 90340, 90345, 90351, 90359, 90367, 90375, 90383, + 90391, 90399, 90405, 90411, 90417, 90425, 90431, 90441, 90447, 90453, + 90459, 90470, 90481, 90492, 90502, 90513, 90524, 90534, 90545, 90555, + 90565, 90574, 90585, 90596, 90607, 90620, 90630, 90640, 90651, 90661, + 90671, 90681, 90691, 90701, 90711, 90721, 90732, 90743, 90754, 90764, + 90774, 90786, 90797, 90808, 90818, 90828, 90838, 90848, 90859, 90869, + 90879, 90891, 90901, 90911, 90923, 90934, 90945, 90955, 90965, 90975, + 90985, 90997, 91009, 91021, 91032, 91043, 91053, 91063, 91073, 91082, + 91091, 91101, 91111, 91122, 0, 0, 91132, 91143, 91154, 91164, 91174, + 91186, 91197, 91208, 91221, 91231, 91243, 91252, 91261, 91272, 91283, + 91296, 91307, 91320, 91330, 91342, 91352, 91364, 91376, 91389, 91399, + 91409, 91419, 91430, 91440, 91449, 91459, 91468, 91477, 91487, 91497, + 91507, 91517, 91527, 91537, 91548, 91558, 91569, 91579, 91590, 91601, + 91611, 91621, 91631, 91641, 91651, 91661, 91672, 91682, 91693, 0, 0, 0, + 0, 0, 0, 0, 91704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91710, 91725, 91740, 91746, + 91752, 91758, 91764, 91770, 91776, 91782, 91788, 91796, 91800, 91803, + 91811, 91819, 91827, 91830, 91833, 91836, 91839, 91842, 91845, 91848, + 91851, 91854, 91857, 91860, 91863, 91866, 91869, 91872, 91875, 91883, + 91892, 91903, 91911, 91919, 91928, 91937, 91949, 91961, 0, 0, 0, 0, 0, 0, + 91971, 91976, 91981, 91988, 91995, 92001, 92007, 92012, 92017, 92022, + 92028, 92034, 92040, 92046, 92052, 92059, 92066, 92076, 92086, 92096, + 92105, 92116, 92125, 92134, 92145, 92156, 92169, 92182, 92194, 92206, + 92218, 92230, 92241, 92252, 92263, 92274, 92286, 92298, 92302, 92307, + 92317, 92327, 92331, 92335, 92339, 92344, 92349, 92354, 92359, 92362, + 92366, 0, 92371, 92374, 92377, 92381, 92385, 92390, 92394, 92398, 92404, + 92410, 92418, 92426, 92429, 92432, 92435, 92438, 92441, 92445, 92449, 0, + 92453, 92458, 92462, 92466, 0, 0, 0, 0, 92471, 92476, 92483, 92488, + 92493, 0, 92498, 92503, 92509, 92514, 92520, 92525, 92531, 92536, 92542, + 92547, 92553, 92559, 92568, 92577, 92586, 92595, 92605, 92615, 92625, + 92635, 92644, 92653, 92662, 92672, 92677, 92682, 92688, 92694, 92700, + 92707, 92715, 92723, 92729, 92735, 92741, 92748, 92754, 92760, 92766, + 92773, 92779, 92785, 92791, 92798, 92803, 92808, 92813, 92819, 92825, + 92831, 92837, 92844, 92850, 92856, 92862, 92868, 92874, 92880, 92886, + 92892, 92898, 92904, 92910, 92917, 92923, 92929, 92935, 92942, 92948, + 92954, 92960, 92967, 92973, 92979, 92985, 92992, 92998, 93004, 93010, + 93017, 93023, 93029, 93035, 93042, 93048, 93054, 93060, 93067, 93073, + 93079, 93085, 93092, 93098, 93104, 93110, 93117, 93123, 93129, 93135, + 93142, 93148, 93154, 93160, 93167, 93173, 93179, 93185, 93192, 93197, + 93202, 93207, 93213, 93219, 93225, 93231, 93238, 93244, 93250, 93256, + 93263, 93269, 93275, 93282, 93289, 93294, 93299, 93304, 93310, 93322, + 93334, 93346, 93358, 93371, 93384, 93392, 0, 0, 93400, 0, 93408, 93413, + 93418, 93422, 93427, 93432, 93436, 93440, 93445, 93450, 93454, 93458, + 93462, 93466, 93472, 93476, 93481, 93485, 93489, 93493, 93497, 93501, + 93505, 93509, 93513, 93517, 93521, 93525, 93530, 93535, 93540, 93545, + 93551, 93557, 93564, 93571, 93578, 93584, 93591, 93598, 93605, 93611, + 93618, 93625, 93631, 93638, 93645, 93651, 93658, 93665, 93671, 93678, + 93685, 93691, 93698, 93705, 93712, 93719, 93726, 93732, 93738, 93744, + 93750, 93755, 93761, 93767, 93774, 93781, 93788, 93794, 93801, 93808, + 93815, 93821, 93828, 93835, 93841, 93848, 93855, 93861, 93868, 93875, + 93881, 93888, 93895, 93901, 93908, 93915, 93922, 93929, 93936, 93943, + 93948, 93955, 93959, 93965, 93971, 93977, 93983, 93989, 93993, 93998, + 94003, 94008, 94013, 94018, 94023, 94028, 94033, 94039, 94045, 94051, + 94059, 94063, 94067, 94071, 94075, 94079, 94083, 94088, 94093, 94098, + 94103, 94107, 94112, 94117, 94122, 94127, 94132, 94137, 94142, 94147, + 94151, 94155, 94160, 94165, 94170, 94175, 94179, 94184, 94189, 94194, + 94199, 94203, 94208, 94213, 94218, 94223, 94227, 94232, 94237, 94241, + 94246, 94251, 94256, 94261, 94266, 94271, 94278, 94285, 94289, 94294, + 94299, 94304, 94309, 94314, 94319, 94324, 94329, 94334, 94339, 94344, + 94349, 94354, 94359, 94364, 94369, 94374, 94379, 94384, 94389, 94394, + 94399, 94404, 94409, 94414, 94419, 94424, 94429, 94434, 0, 0, 0, 94439, + 94443, 94448, 94452, 94457, 94462, 0, 0, 94466, 94471, 94476, 94480, + 94485, 94490, 0, 0, 94495, 94500, 94504, 94509, 94514, 94519, 0, 0, + 94524, 94529, 94534, 0, 0, 0, 94538, 94543, 94548, 94553, 94557, 94562, + 94567, 0, 94572, 94578, 94581, 94585, 94588, 94592, 94596, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 94600, 94606, 94612, 94618, 94624, 0, 0, 94628, 94634, + 94640, 94646, 94652, 94658, 94665, 94672, 94679, 94686, 94693, 94700, 0, + 94707, 94714, 94721, 94727, 94734, 94741, 94748, 94755, 94761, 94768, + 94775, 94782, 94789, 94795, 94802, 94809, 94816, 94823, 94829, 94836, + 94843, 94850, 94857, 94864, 94871, 94878, 0, 94885, 94891, 94898, 94905, + 94912, 94919, 94925, 94932, 94939, 94946, 94953, 94960, 94967, 94974, + 94980, 94987, 94994, 95001, 95008, 0, 95015, 95022, 0, 95029, 95036, + 95043, 95050, 95057, 95064, 95071, 95078, 95085, 95092, 95099, 95106, + 95113, 95120, 95127, 0, 0, 95133, 95138, 95143, 95148, 95153, 95158, + 95163, 95168, 95173, 95178, 95183, 95188, 95193, 95198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 95159, 95166, 95173, 95180, 95187, 95194, 95201, 95208, 95215, - 95222, 95229, 95236, 95243, 95250, 95257, 95264, 95271, 95278, 95285, - 95292, 95300, 95308, 95315, 95322, 95327, 95335, 95343, 95350, 95357, - 95362, 95369, 95374, 95379, 95386, 95391, 95396, 95401, 95409, 95414, - 95419, 95426, 95431, 95436, 95443, 95450, 95455, 95460, 95465, 95470, - 95475, 95480, 95485, 95490, 95495, 95502, 95507, 95514, 95519, 95524, - 95529, 95534, 95539, 95544, 95549, 95554, 95559, 95564, 95569, 95576, - 95583, 95590, 95597, 95603, 95608, 95615, 95620, 95625, 95634, 95641, - 95650, 95657, 95662, 95667, 95675, 95680, 95685, 95690, 95695, 95700, - 95707, 95712, 95717, 95722, 95727, 95732, 95739, 95746, 95753, 95760, - 95767, 95774, 95781, 95788, 95795, 95802, 95809, 95816, 95823, 95830, - 95837, 95844, 95851, 95858, 95865, 95872, 95879, 95886, 95893, 95900, - 95907, 95914, 95921, 95928, 0, 0, 0, 0, 0, 95935, 95943, 95951, 0, 0, 0, - 0, 95956, 95960, 95964, 95968, 95972, 95976, 95980, 95984, 95988, 95992, - 95997, 96002, 96007, 96012, 96017, 96022, 96027, 96032, 96037, 96043, - 96049, 96055, 96062, 96069, 96076, 96083, 96090, 96097, 96102, 96107, - 96112, 96118, 96124, 96130, 96136, 96142, 96148, 96154, 96160, 96166, - 96172, 96178, 96184, 96190, 96196, 0, 0, 0, 96202, 96210, 96218, 96226, - 96234, 96242, 96252, 96262, 96270, 96278, 96286, 96294, 96302, 96308, - 96315, 96324, 96332, 96340, 96349, 96358, 96367, 96377, 96388, 96398, - 96409, 96418, 96427, 96436, 96446, 96457, 96467, 96478, 96489, 96498, - 96506, 96512, 96518, 96524, 96530, 96538, 96546, 96552, 96559, 96569, - 96576, 96583, 96590, 96597, 96604, 96614, 96621, 96628, 96636, 96644, - 96653, 96662, 96671, 96680, 96689, 96696, 96704, 96713, 96722, 96726, - 96733, 96738, 96743, 96747, 96751, 96755, 96759, 96764, 96769, 96775, - 96781, 96785, 96791, 96795, 96799, 96803, 96807, 96811, 96815, 96821, - 96825, 96830, 96834, 96838, 0, 96841, 96846, 96851, 96856, 96861, 96868, - 96873, 96878, 96883, 96888, 96893, 96898, 96903, 0, 0, 0, 96906, 0, 0, 0, + 0, 0, 0, 0, 95203, 95210, 95217, 95224, 95231, 95238, 95245, 95252, + 95259, 95266, 95273, 95280, 95287, 95294, 95301, 95308, 95315, 95322, + 95329, 95336, 95344, 95352, 95359, 95366, 95371, 95379, 95387, 95394, + 95401, 95406, 95413, 95418, 95423, 95430, 95435, 95440, 95445, 95453, + 95458, 95463, 95470, 95475, 95480, 95487, 95494, 95499, 95504, 95509, + 95514, 95519, 95524, 95529, 95534, 95539, 95546, 95551, 95558, 95563, + 95568, 95573, 95578, 95583, 95588, 95593, 95598, 95603, 95608, 95613, + 95620, 95627, 95634, 95641, 95647, 95652, 95659, 95664, 95669, 95678, + 95685, 95694, 95701, 95706, 95711, 95719, 95724, 95729, 95734, 95739, + 95744, 95751, 95756, 95761, 95766, 95771, 95776, 95783, 95790, 95797, + 95804, 95811, 95818, 95825, 95832, 95839, 95846, 95853, 95860, 95867, + 95874, 95881, 95888, 95895, 95902, 95909, 95916, 95923, 95930, 95937, + 95944, 95951, 95958, 95965, 95972, 0, 0, 0, 0, 0, 95979, 95987, 95995, 0, + 0, 0, 0, 96000, 96004, 96008, 96012, 96016, 96020, 96024, 96028, 96032, + 96036, 96041, 96046, 96051, 96056, 96061, 96066, 96071, 96076, 96081, + 96087, 96093, 96099, 96106, 96113, 96120, 96127, 96134, 96141, 96146, + 96151, 96156, 96162, 96168, 96174, 96180, 96186, 96192, 96198, 96204, + 96210, 96216, 96222, 96228, 96234, 96240, 0, 0, 0, 96246, 96254, 96262, + 96270, 96278, 96286, 96296, 96306, 96314, 96322, 96330, 96338, 96346, + 96352, 96359, 96368, 96376, 96384, 96393, 96402, 96411, 96421, 96432, + 96442, 96453, 96462, 96471, 96480, 96490, 96501, 96511, 96522, 96533, + 96542, 96550, 96556, 96562, 96568, 96574, 96582, 96590, 96596, 96603, + 96613, 96620, 96627, 96634, 96641, 96648, 96658, 96665, 96672, 96680, + 96688, 96697, 96706, 96715, 96724, 96733, 96740, 96748, 96757, 96766, + 96770, 96777, 96782, 96787, 96791, 96795, 96799, 96803, 96808, 96813, + 96819, 96825, 96829, 96835, 96839, 96843, 96847, 96851, 96855, 96859, + 96865, 96869, 96874, 96878, 96882, 0, 96885, 96890, 96895, 96900, 96905, + 96912, 96917, 96922, 96927, 96932, 96937, 96942, 96947, 0, 0, 0, 96950, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96912, 96919, - 96928, 96937, 96944, 96951, 96958, 96965, 96972, 96979, 96985, 96992, - 96999, 97006, 97013, 97020, 97027, 97034, 97041, 97050, 97057, 97064, - 97071, 97078, 97085, 97092, 97099, 97106, 97115, 97122, 97129, 97136, - 97143, 97150, 97157, 97166, 97173, 97180, 97187, 97194, 97203, 97210, - 97217, 97224, 97232, 97241, 0, 0, 97250, 97254, 97258, 97263, 97268, - 97273, 97278, 97282, 97287, 97292, 97297, 97302, 97307, 97312, 97316, - 97321, 97326, 97331, 97336, 97340, 97345, 97350, 97354, 97359, 97364, - 97369, 97374, 97379, 97384, 0, 0, 0, 97389, 97393, 97398, 97403, 97407, - 97412, 97416, 97421, 97426, 97431, 97436, 97441, 97445, 97450, 97455, - 97460, 97465, 97470, 97475, 97479, 97484, 97489, 97494, 97499, 97504, - 97509, 97513, 97517, 97522, 97527, 97532, 97537, 97542, 97547, 97552, - 97557, 97562, 97567, 97572, 97577, 97582, 97587, 97592, 97597, 97602, - 97607, 97612, 97617, 97622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 97627, 97633, 97638, 97643, 97648, 97653, 97658, 97663, 97668, 97673, - 97678, 97684, 97690, 97696, 97702, 97708, 97714, 97720, 97726, 97732, - 97739, 97746, 97753, 97761, 97769, 97777, 97785, 97793, 0, 0, 0, 0, - 97801, 97805, 97810, 97815, 97820, 97824, 97829, 97834, 97839, 97844, - 97848, 97852, 97857, 97862, 97867, 97872, 97876, 97881, 97886, 97891, - 97896, 97901, 97906, 97910, 97915, 97920, 97925, 97930, 97935, 97940, - 97945, 97950, 97955, 97960, 97965, 97971, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 97977, 97982, 97989, 97996, 98001, 98006, 98011, 98016, 98021, 98026, - 98031, 98036, 98041, 98046, 98051, 98056, 98061, 98066, 98071, 98076, - 98081, 98086, 98091, 98096, 98101, 98106, 98111, 98116, 98121, 98126, 0, - 0, 0, 0, 0, 98133, 98139, 98145, 98151, 98157, 98162, 98168, 98174, - 98180, 98186, 98191, 98197, 98203, 98209, 98215, 98221, 98227, 98233, - 98239, 98245, 98250, 98256, 98262, 98268, 98274, 98280, 98285, 98291, - 98297, 98302, 98308, 98314, 98320, 98326, 98332, 98338, 98344, 98349, - 98355, 98362, 98369, 98376, 98383, 0, 0, 0, 0, 0, 98390, 98395, 98400, - 98405, 98410, 98415, 98420, 98425, 98430, 98435, 98440, 98445, 98450, - 98455, 98460, 98465, 98470, 98475, 98480, 98485, 98490, 98495, 98500, - 98505, 98510, 98515, 98520, 98524, 98528, 98532, 0, 98537, 98543, 98548, - 98553, 98558, 98563, 98569, 98575, 98581, 98587, 98593, 98599, 98605, - 98611, 98617, 98623, 98629, 98635, 98641, 98646, 98652, 98658, 98663, - 98669, 98674, 98680, 98686, 98691, 98697, 98703, 98708, 98714, 98719, - 98724, 98730, 98736, 98742, 0, 0, 0, 0, 98747, 98753, 98759, 98765, - 98771, 98777, 98783, 98789, 98795, 98802, 98807, 98812, 98818, 98824, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 96956, 96963, 96972, 96981, 96988, 96995, 97002, 97009, 97016, 97023, + 97029, 97036, 97043, 97050, 97057, 97064, 97071, 97078, 97085, 97094, + 97101, 97108, 97115, 97122, 97129, 97136, 97143, 97150, 97159, 97166, + 97173, 97180, 97187, 97194, 97201, 97210, 97217, 97224, 97231, 97238, + 97247, 97254, 97261, 97268, 97276, 97285, 0, 0, 97294, 97298, 97302, + 97307, 97312, 97317, 97322, 97326, 97331, 97336, 97341, 97346, 97351, + 97356, 97360, 97365, 97370, 97375, 97380, 97384, 97389, 97394, 97398, + 97403, 97408, 97413, 97418, 97423, 97428, 0, 0, 0, 97433, 97437, 97442, + 97447, 97451, 97456, 97460, 97465, 97470, 97475, 97480, 97485, 97489, + 97494, 97499, 97504, 97509, 97514, 97519, 97523, 97528, 97533, 97538, + 97543, 97548, 97553, 97557, 97561, 97566, 97571, 97576, 97581, 97586, + 97591, 97596, 97601, 97606, 97611, 97616, 97621, 97626, 97631, 97636, + 97641, 97646, 97651, 97656, 97661, 97666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 97671, 97677, 97682, 97687, 97692, 97697, 97702, 97707, + 97712, 97717, 97722, 97728, 97734, 97740, 97746, 97752, 97758, 97764, + 97770, 97776, 97783, 97790, 97797, 97805, 97813, 97821, 97829, 97837, 0, + 0, 0, 0, 97845, 97849, 97854, 97859, 97864, 97868, 97873, 97878, 97883, + 97888, 97892, 97896, 97901, 97906, 97911, 97916, 97920, 97925, 97930, + 97935, 97940, 97945, 97950, 97954, 97959, 97964, 97969, 97974, 97979, + 97984, 97989, 97994, 97999, 98004, 98009, 98015, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 98021, 98026, 98033, 98040, 98045, 98050, 98055, 98060, 98065, 98070, + 98075, 98080, 98085, 98090, 98095, 98100, 98105, 98110, 98115, 98120, + 98125, 98130, 98135, 98140, 98145, 98150, 98155, 98160, 98165, 98170, 0, + 0, 0, 0, 0, 98177, 98183, 98189, 98195, 98201, 98206, 98212, 98218, + 98224, 98230, 98235, 98241, 98247, 98253, 98259, 98265, 98271, 98277, + 98283, 98289, 98294, 98300, 98306, 98312, 98318, 98324, 98329, 98335, + 98341, 98346, 98352, 98358, 98364, 98370, 98376, 98382, 98388, 98393, + 98399, 98406, 98413, 98420, 98427, 0, 0, 0, 0, 0, 98434, 98439, 98444, + 98449, 98454, 98459, 98464, 98469, 98474, 98479, 98484, 98489, 98494, + 98499, 98504, 98509, 98514, 98519, 98524, 98529, 98534, 98539, 98544, + 98549, 98554, 98559, 98564, 98568, 98572, 98576, 0, 98581, 98587, 98592, + 98597, 98602, 98607, 98613, 98619, 98625, 98631, 98637, 98643, 98649, + 98655, 98661, 98667, 98673, 98679, 98685, 98690, 98696, 98702, 98707, + 98713, 98718, 98724, 98730, 98735, 98741, 98747, 98752, 98758, 98763, + 98768, 98774, 98780, 98786, 0, 0, 0, 0, 98791, 98797, 98803, 98809, + 98815, 98821, 98827, 98833, 98839, 98846, 98851, 98856, 98862, 98868, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98830, 98836, 98842, - 98848, 98855, 98861, 98868, 98875, 98882, 98889, 98897, 98904, 98912, - 98918, 98924, 98930, 98936, 98942, 98948, 98954, 98960, 98966, 98972, - 98978, 98984, 98990, 98996, 99002, 99008, 99014, 99020, 99026, 99032, - 99038, 99044, 99050, 99056, 99062, 99068, 99074, 99080, 99086, 99092, - 99098, 99105, 99111, 99118, 99125, 99132, 99139, 99147, 99154, 99162, - 99168, 99174, 99180, 99186, 99192, 99198, 99204, 99210, 99216, 99222, - 99228, 99234, 99240, 99246, 99252, 99258, 99264, 99270, 99276, 99282, - 99288, 99294, 99300, 99306, 99312, 99318, 99324, 99330, 99335, 99340, - 99345, 99350, 99355, 99360, 99365, 99370, 99375, 99380, 99385, 99390, - 99395, 99400, 99405, 99410, 99415, 99420, 99425, 99430, 99435, 99440, - 99445, 99450, 99455, 99460, 99465, 99470, 99475, 99480, 99485, 99490, - 99495, 99500, 99505, 99510, 99515, 99520, 99525, 99530, 99535, 99540, - 99545, 99550, 99555, 99560, 99565, 99570, 99575, 99580, 99585, 99590, - 99595, 99600, 99605, 99609, 99613, 99618, 99623, 99628, 99633, 99638, - 99643, 99648, 99653, 99658, 99663, 99668, 99672, 99676, 99680, 99684, - 99688, 99692, 99696, 99701, 99706, 0, 0, 99711, 99716, 99720, 99724, - 99728, 99732, 99736, 99740, 99744, 99748, 0, 0, 0, 0, 0, 0, 99752, 99757, - 99763, 99769, 99775, 99781, 99787, 99793, 99798, 99804, 99809, 99815, - 99820, 99825, 99831, 99837, 99842, 99847, 99852, 99857, 99863, 99868, - 99874, 99879, 99885, 99891, 99897, 99903, 99909, 99915, 99921, 99926, - 99932, 99938, 99944, 99950, 0, 0, 0, 0, 99956, 99961, 99967, 99973, - 99979, 99985, 99991, 99997, 100002, 100008, 100013, 100019, 100024, - 100029, 100035, 100041, 100046, 100051, 100056, 100061, 100067, 100072, - 100078, 100083, 100089, 100095, 100101, 100107, 100113, 100119, 100125, - 100130, 100136, 100142, 100148, 100154, 0, 0, 0, 0, 100160, 100164, - 100169, 100174, 100179, 100184, 100189, 100194, 100199, 100203, 100208, - 100213, 100218, 100223, 100227, 100232, 100237, 100242, 100247, 100252, - 100257, 100261, 100266, 100270, 100275, 100280, 100285, 100290, 100295, - 100300, 100305, 100310, 100314, 100319, 100324, 100329, 100334, 100339, - 100344, 100349, 0, 0, 0, 0, 0, 0, 0, 0, 100354, 100361, 100368, 100375, - 100382, 100389, 100396, 100403, 100410, 100417, 100424, 100431, 100438, - 100445, 100452, 100459, 100466, 100473, 100480, 100487, 100494, 100501, - 100508, 100515, 100522, 100529, 100536, 100543, 100550, 100557, 100564, - 100571, 100578, 100585, 100592, 100599, 100606, 100613, 100620, 100627, - 100634, 100641, 100648, 100655, 100662, 100669, 100676, 100683, 100690, - 100697, 100704, 100711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100718, 100725, - 100730, 100736, 100742, 100748, 100754, 100760, 100766, 100772, 100777, - 100783, 0, 100789, 100794, 100800, 100805, 100811, 100817, 100822, - 100827, 100833, 100839, 100845, 100851, 100856, 100862, 100868, 0, - 100874, 100880, 100886, 100892, 100898, 100903, 100909, 0, 100915, - 100921, 0, 100927, 100932, 100938, 100944, 100950, 100956, 100962, - 100968, 100974, 100979, 100985, 0, 100991, 100996, 101002, 101007, - 101013, 101019, 101024, 101029, 101035, 101041, 101047, 101053, 101058, - 101064, 101070, 0, 101076, 101082, 101088, 101094, 101100, 101105, - 101111, 0, 101117, 101123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98874, 98880, 98886, + 98892, 98899, 98905, 98912, 98919, 98926, 98933, 98941, 98948, 98956, + 98962, 98968, 98974, 98980, 98986, 98992, 98998, 99004, 99010, 99016, + 99022, 99028, 99034, 99040, 99046, 99052, 99058, 99064, 99070, 99076, + 99082, 99088, 99094, 99100, 99106, 99112, 99118, 99124, 99130, 99136, + 99142, 99149, 99155, 99162, 99169, 99176, 99183, 99191, 99198, 99206, + 99212, 99218, 99224, 99230, 99236, 99242, 99248, 99254, 99260, 99266, + 99272, 99278, 99284, 99290, 99296, 99302, 99308, 99314, 99320, 99326, + 99332, 99338, 99344, 99350, 99356, 99362, 99368, 99374, 99379, 99384, + 99389, 99394, 99399, 99404, 99409, 99414, 99419, 99424, 99429, 99434, + 99439, 99444, 99449, 99454, 99459, 99464, 99469, 99474, 99479, 99484, + 99489, 99494, 99499, 99504, 99509, 99514, 99519, 99524, 99529, 99534, + 99539, 99544, 99549, 99554, 99559, 99564, 99569, 99574, 99579, 99584, + 99589, 99594, 99599, 99604, 99609, 99614, 99619, 99624, 99629, 99634, + 99639, 99644, 99649, 99653, 99657, 99662, 99667, 99672, 99677, 99682, + 99687, 99692, 99697, 99702, 99707, 99712, 99716, 99720, 99724, 99728, + 99732, 99736, 99740, 99745, 99750, 0, 0, 99755, 99760, 99764, 99768, + 99772, 99776, 99780, 99784, 99788, 99792, 0, 0, 0, 0, 0, 0, 99796, 99801, + 99807, 99813, 99819, 99825, 99831, 99837, 99842, 99848, 99853, 99859, + 99864, 99869, 99875, 99881, 99886, 99891, 99896, 99901, 99907, 99912, + 99918, 99923, 99929, 99935, 99941, 99947, 99953, 99959, 99965, 99970, + 99976, 99982, 99988, 99994, 0, 0, 0, 0, 100000, 100005, 100011, 100017, + 100023, 100029, 100035, 100041, 100046, 100052, 100057, 100063, 100068, + 100073, 100079, 100085, 100090, 100095, 100100, 100105, 100111, 100116, + 100122, 100127, 100133, 100139, 100145, 100151, 100157, 100163, 100169, + 100174, 100180, 100186, 100192, 100198, 0, 0, 0, 0, 100204, 100208, + 100213, 100218, 100223, 100228, 100233, 100238, 100243, 100247, 100252, + 100257, 100262, 100267, 100271, 100276, 100281, 100286, 100291, 100296, + 100301, 100305, 100310, 100314, 100319, 100324, 100329, 100334, 100339, + 100344, 100349, 100354, 100358, 100363, 100368, 100373, 100378, 100383, + 100388, 100393, 0, 0, 0, 0, 0, 0, 0, 0, 100398, 100405, 100412, 100419, + 100426, 100433, 100440, 100447, 100454, 100461, 100468, 100475, 100482, + 100489, 100496, 100503, 100510, 100517, 100524, 100531, 100538, 100545, + 100552, 100559, 100566, 100573, 100580, 100587, 100594, 100601, 100608, + 100615, 100622, 100629, 100636, 100643, 100650, 100657, 100664, 100671, + 100678, 100685, 100692, 100699, 100706, 100713, 100720, 100727, 100734, + 100741, 100748, 100755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100762, 100769, + 100774, 100780, 100786, 100792, 100798, 100804, 100810, 100816, 100821, + 100827, 0, 100833, 100838, 100844, 100849, 100855, 100861, 100866, + 100871, 100877, 100883, 100889, 100895, 100900, 100906, 100912, 0, + 100918, 100924, 100930, 100936, 100942, 100947, 100953, 0, 100959, + 100965, 0, 100971, 100976, 100982, 100988, 100994, 101000, 101006, + 101012, 101018, 101023, 101029, 0, 101035, 101040, 101046, 101051, + 101057, 101063, 101068, 101073, 101079, 101085, 101091, 101097, 101102, + 101108, 101114, 0, 101120, 101126, 101132, 101138, 101144, 101149, + 101155, 0, 101161, 101167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 101129, 101134, 101139, 101144, 101149, 101154, 101159, - 101164, 101169, 101174, 101179, 101184, 101189, 101194, 101199, 101204, - 101209, 101214, 101219, 101224, 101229, 101234, 101239, 101244, 101249, - 101254, 101259, 101264, 101269, 101274, 101279, 101284, 101289, 101294, - 101299, 101304, 101309, 101314, 101319, 101324, 101329, 101334, 101339, - 101344, 101349, 101354, 101359, 101364, 101369, 101374, 101379, 101384, - 101389, 101394, 101399, 101404, 101409, 101414, 101419, 101424, 101429, - 101434, 101439, 101444, 101449, 101454, 101459, 101464, 101469, 101474, - 101479, 101484, 101489, 101494, 101499, 101504, 101509, 101514, 101519, - 101524, 101529, 101534, 101539, 101544, 101549, 101554, 101559, 101564, - 101569, 101574, 101579, 101584, 101589, 101594, 101599, 101604, 101609, - 101614, 101619, 101624, 101629, 101634, 101639, 101644, 101649, 101654, - 101659, 101664, 101669, 101674, 101679, 101684, 101689, 101694, 101699, - 101704, 101709, 101714, 101719, 101724, 101729, 101734, 101739, 101744, - 101749, 101754, 101759, 101764, 101769, 101774, 101779, 101784, 101789, - 101794, 101799, 101804, 101809, 101814, 101819, 101824, 101829, 101834, - 101839, 101844, 101849, 101854, 101859, 101864, 101869, 101874, 101879, - 101884, 101889, 101894, 101899, 101904, 101909, 101914, 101919, 101924, - 101929, 101934, 101939, 101944, 101949, 101954, 101959, 101964, 101969, - 101974, 101979, 101984, 101989, 101994, 101999, 102004, 102009, 102014, - 102019, 102024, 102029, 102034, 102039, 102044, 102049, 102054, 102059, - 102064, 102069, 102074, 102079, 102084, 102089, 102094, 102099, 102104, - 102109, 102114, 102119, 102124, 102129, 102134, 102139, 102144, 102149, - 102154, 102159, 102164, 102169, 102174, 102179, 102184, 102189, 102194, - 102199, 102204, 102209, 102214, 102219, 102224, 102229, 102234, 102239, - 102244, 102249, 102254, 102259, 102264, 102269, 102274, 102279, 102284, - 102289, 102294, 102299, 102304, 102309, 102314, 102319, 102324, 102329, - 102334, 102339, 102344, 102349, 102354, 102359, 102364, 102369, 102374, - 102379, 102384, 102389, 102394, 102399, 102404, 102409, 102414, 102419, - 102424, 102429, 102434, 102439, 102444, 102449, 102454, 102459, 102464, - 102469, 102474, 102479, 102484, 102489, 102494, 102499, 102504, 102509, - 102514, 102519, 102524, 102529, 102534, 102539, 102544, 102549, 102554, - 102559, 102564, 102569, 102574, 102579, 102584, 102589, 102594, 102599, - 102604, 102609, 102614, 102619, 102624, 102629, 102634, 102639, 102644, - 102649, 102654, 102659, 102664, 102669, 102674, 102679, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 102684, 102690, 102697, 102704, 102710, 102717, 102724, 102731, - 102738, 102744, 102751, 102758, 102765, 102772, 102779, 102786, 102793, - 102800, 102807, 102814, 102821, 102828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 102835, 102840, 102845, 102850, 102855, 102860, 102865, 102870, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102875, - 102881, 102889, 102898, 102903, 102909, 0, 102915, 102922, 102933, - 102943, 102950, 102958, 102965, 102976, 102982, 102992, 102999, 103006, - 103012, 103019, 103027, 103034, 103040, 103047, 103059, 103066, 103073, - 103081, 103090, 103103, 103108, 103117, 103123, 103132, 103138, 103144, - 103151, 103156, 103166, 103180, 103188, 103196, 103201, 103211, 103218, - 103229, 103236, 103245, 0, 103253, 103259, 103267, 103277, 103283, - 103289, 103295, 103301, 103311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 101173, 101178, 101183, 101188, 101193, 101198, 101203, + 101208, 101213, 101218, 101223, 101228, 101233, 101238, 101243, 101248, + 101253, 101258, 101263, 101268, 101273, 101278, 101283, 101288, 101293, + 101298, 101303, 101308, 101313, 101318, 101323, 101328, 101333, 101338, + 101343, 101348, 101353, 101358, 101363, 101368, 101373, 101378, 101383, + 101388, 101393, 101398, 101403, 101408, 101413, 101418, 101423, 101428, + 101433, 101438, 101443, 101448, 101453, 101458, 101463, 101468, 101473, + 101478, 101483, 101488, 101493, 101498, 101503, 101508, 101513, 101518, + 101523, 101528, 101533, 101538, 101543, 101548, 101553, 101558, 101563, + 101568, 101573, 101578, 101583, 101588, 101593, 101598, 101603, 101608, + 101613, 101618, 101623, 101628, 101633, 101638, 101643, 101648, 101653, + 101658, 101663, 101668, 101673, 101678, 101683, 101688, 101693, 101698, + 101703, 101708, 101713, 101718, 101723, 101728, 101733, 101738, 101743, + 101748, 101753, 101758, 101763, 101768, 101773, 101778, 101783, 101788, + 101793, 101798, 101803, 101808, 101813, 101818, 101823, 101828, 101833, + 101838, 101843, 101848, 101853, 101858, 101863, 101868, 101873, 101878, + 101883, 101888, 101893, 101898, 101903, 101908, 101913, 101918, 101923, + 101928, 101933, 101938, 101943, 101948, 101953, 101958, 101963, 101968, + 101973, 101978, 101983, 101988, 101993, 101998, 102003, 102008, 102013, + 102018, 102023, 102028, 102033, 102038, 102043, 102048, 102053, 102058, + 102063, 102068, 102073, 102078, 102083, 102088, 102093, 102098, 102103, + 102108, 102113, 102118, 102123, 102128, 102133, 102138, 102143, 102148, + 102153, 102158, 102163, 102168, 102173, 102178, 102183, 102188, 102193, + 102198, 102203, 102208, 102213, 102218, 102223, 102228, 102233, 102238, + 102243, 102248, 102253, 102258, 102263, 102268, 102273, 102278, 102283, + 102288, 102293, 102298, 102303, 102308, 102313, 102318, 102323, 102328, + 102333, 102338, 102343, 102348, 102353, 102358, 102363, 102368, 102373, + 102378, 102383, 102388, 102393, 102398, 102403, 102408, 102413, 102418, + 102423, 102428, 102433, 102438, 102443, 102448, 102453, 102458, 102463, + 102468, 102473, 102478, 102483, 102488, 102493, 102498, 102503, 102508, + 102513, 102518, 102523, 102528, 102533, 102538, 102543, 102548, 102553, + 102558, 102563, 102568, 102573, 102578, 102583, 102588, 102593, 102598, + 102603, 102608, 102613, 102618, 102623, 102628, 102633, 102638, 102643, + 102648, 102653, 102658, 102663, 102668, 102673, 102678, 102683, 102688, + 102693, 102698, 102703, 102708, 102713, 102718, 102723, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 102728, 102734, 102741, 102748, 102754, 102761, 102768, 102775, + 102782, 102788, 102795, 102802, 102809, 102816, 102823, 102830, 102837, + 102844, 102851, 102858, 102865, 102872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 102879, 102884, 102889, 102894, 102899, 102904, 102909, 102914, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102919, + 102925, 102933, 102942, 102947, 102953, 0, 102959, 102966, 102977, + 102987, 102994, 103002, 103009, 103020, 103026, 103036, 103043, 103050, + 103056, 103063, 103071, 103078, 103084, 103091, 103103, 103110, 103117, + 103125, 103134, 103147, 103152, 103161, 103167, 103176, 103182, 103188, + 103195, 103200, 103210, 103224, 103232, 103240, 103245, 103255, 103262, + 103273, 103280, 103289, 0, 103297, 103303, 103311, 103321, 103327, + 103333, 103339, 103345, 103355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 103319, 103323, 103327, 103331, 103335, 103339, 0, - 0, 103344, 0, 103349, 103353, 103358, 103363, 103368, 103373, 103377, - 103382, 103387, 103392, 103397, 103401, 103406, 103411, 103416, 103421, - 103425, 103430, 103435, 103440, 103445, 103449, 103454, 103459, 103464, - 103469, 103473, 103478, 103483, 103488, 103493, 103497, 103502, 103507, - 103512, 103517, 103522, 103527, 103532, 103536, 103541, 103546, 103551, - 103556, 0, 103561, 103566, 0, 0, 0, 103571, 0, 0, 103576, 103581, 103588, - 103595, 103602, 103609, 103616, 103623, 103630, 103637, 103644, 103651, - 103658, 103665, 103672, 103679, 103686, 103693, 103700, 103707, 103714, - 103721, 103728, 0, 103735, 103742, 103748, 103754, 103760, 103767, - 103774, 103782, 103789, 103797, 103802, 103807, 103812, 103817, 103822, - 103827, 103832, 103837, 103842, 103847, 103852, 103857, 103862, 103868, - 103873, 103878, 103883, 103888, 103893, 103898, 103903, 103908, 103913, - 103919, 103925, 103929, 103933, 103937, 103941, 103945, 103950, 103955, - 103961, 103966, 103972, 103977, 103982, 103987, 103993, 103998, 104003, - 104008, 104013, 104018, 104024, 104029, 104035, 104040, 104046, 104051, - 104057, 104062, 104068, 104073, 104078, 104083, 104088, 104093, 104098, - 104103, 104109, 104114, 0, 0, 0, 0, 0, 0, 0, 0, 104119, 104123, 104127, - 104131, 104135, 104141, 104145, 104150, 104155, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 103363, 103367, 103371, 103375, 103379, 103383, 0, + 0, 103388, 0, 103393, 103397, 103402, 103407, 103412, 103417, 103421, + 103426, 103431, 103436, 103441, 103445, 103450, 103455, 103460, 103465, + 103469, 103474, 103479, 103484, 103489, 103493, 103498, 103503, 103508, + 103513, 103517, 103522, 103527, 103532, 103537, 103541, 103546, 103551, + 103556, 103561, 103566, 103571, 103576, 103580, 103585, 103590, 103595, + 103600, 0, 103605, 103610, 0, 0, 0, 103615, 0, 0, 103620, 103625, 103632, + 103639, 103646, 103653, 103660, 103667, 103674, 103681, 103688, 103695, + 103702, 103709, 103716, 103723, 103730, 103737, 103744, 103751, 103758, + 103765, 103772, 0, 103779, 103786, 103792, 103798, 103804, 103811, + 103818, 103826, 103833, 103841, 103846, 103851, 103856, 103861, 103866, + 103871, 103876, 103881, 103886, 103891, 103896, 103901, 103906, 103912, + 103917, 103922, 103927, 103932, 103937, 103942, 103947, 103952, 103957, + 103963, 103969, 103973, 103977, 103981, 103985, 103989, 103994, 103999, + 104005, 104010, 104016, 104021, 104026, 104031, 104037, 104042, 104047, + 104052, 104057, 104062, 104068, 104073, 104079, 104084, 104090, 104095, + 104101, 104106, 104112, 104117, 104122, 104127, 104132, 104137, 104142, + 104147, 104153, 104158, 0, 0, 0, 0, 0, 0, 0, 0, 104163, 104167, 104171, + 104175, 104179, 104185, 104189, 104194, 104199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104161, 104166, 104171, - 104176, 104181, 104186, 104191, 104196, 104201, 104206, 104211, 104216, - 104221, 104226, 104231, 104236, 104241, 104246, 104251, 0, 104256, - 104261, 0, 0, 0, 0, 0, 104266, 104270, 104274, 104279, 104284, 104290, - 104295, 104300, 104305, 104310, 104315, 104320, 104325, 104330, 104335, - 104340, 104345, 104350, 104355, 104360, 104365, 104370, 104375, 104380, - 104385, 104390, 104395, 104400, 104404, 104409, 104414, 104420, 104424, - 0, 0, 0, 104428, 104434, 104438, 104443, 104448, 104453, 104457, 104462, - 104466, 104471, 104476, 104480, 104485, 104490, 104494, 104498, 104503, - 104508, 104512, 104517, 104522, 104527, 104532, 104537, 104542, 104547, - 104552, 0, 0, 0, 0, 0, 104557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104205, 104210, 104215, + 104220, 104225, 104230, 104235, 104240, 104245, 104250, 104255, 104260, + 104265, 104270, 104275, 104280, 104285, 104290, 104295, 0, 104300, + 104305, 0, 0, 0, 0, 0, 104310, 104314, 104318, 104323, 104328, 104334, + 104339, 104344, 104349, 104354, 104359, 104364, 104369, 104374, 104379, + 104384, 104389, 104394, 104399, 104404, 104409, 104414, 104419, 104424, + 104429, 104434, 104439, 104444, 104448, 104453, 104458, 104464, 104468, + 0, 0, 0, 104472, 104478, 104482, 104487, 104492, 104497, 104501, 104506, + 104510, 104515, 104520, 104524, 104529, 104534, 104538, 104542, 104547, + 104552, 104556, 104561, 104566, 104571, 104576, 104581, 104586, 104591, + 104596, 0, 0, 0, 0, 0, 104601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 104562, 104567, 104572, 104577, 104582, 104587, 104593, 104599, - 104605, 104610, 104615, 104620, 104626, 104632, 104638, 104643, 104649, - 104654, 104660, 104666, 104671, 104677, 104683, 104688, 104694, 104700, - 104706, 104712, 104718, 104723, 104729, 104735, 104741, 104746, 104751, - 104756, 104761, 104766, 104772, 104778, 104783, 104788, 104793, 104799, - 104804, 104809, 104815, 104821, 104826, 104833, 104839, 104844, 104850, - 104856, 104862, 104867, 0, 0, 0, 0, 104873, 104882, 104890, 104897, - 104904, 104909, 104914, 104919, 104924, 104929, 104934, 104939, 104944, - 104949, 104955, 104961, 104967, 104973, 104979, 104985, 0, 0, 104991, - 104998, 105005, 105012, 105020, 105028, 105036, 105044, 105052, 105060, - 105066, 105072, 105078, 105085, 105092, 105099, 105106, 105113, 105120, - 105127, 105134, 105141, 105148, 105155, 105162, 105169, 105176, 105183, - 105191, 105199, 105207, 105216, 105225, 105234, 105243, 105252, 105261, - 105269, 105277, 105285, 105294, 105303, 105312, 105321, 105330, 105339, - 105348, 105352, 105357, 105362, 0, 105368, 105373, 0, 0, 0, 0, 0, 105378, - 105384, 105391, 105396, 105401, 105405, 105410, 105415, 0, 105420, - 105425, 105430, 0, 105435, 105440, 105445, 105450, 105455, 105460, - 105465, 105470, 105475, 105480, 105485, 105489, 105493, 105498, 105503, - 105508, 105512, 105516, 105520, 105524, 105529, 105534, 105539, 105543, - 105548, 105552, 105557, 105562, 105567, 0, 0, 105572, 105578, 105583, 0, - 0, 0, 0, 105588, 105592, 105596, 105600, 105604, 105608, 105613, 105618, - 105624, 105629, 0, 0, 0, 0, 0, 0, 0, 105636, 105642, 105649, 105655, - 105662, 105668, 105674, 105680, 105687, 0, 0, 0, 0, 0, 0, 0, 105693, - 105701, 105709, 105717, 105725, 105733, 105741, 105749, 105757, 105765, - 105773, 105781, 105789, 105797, 105805, 105813, 105821, 105829, 105837, - 105845, 105853, 105861, 105869, 105877, 105885, 105893, 105901, 105909, - 105917, 105925, 105932, 105940, 105948, 105955, 105962, 105969, 105976, - 105983, 105990, 105997, 106004, 106011, 106018, 106025, 106032, 106039, - 106046, 106053, 106060, 106067, 106074, 106081, 106088, 106095, 106102, - 106109, 106116, 106123, 106130, 106137, 106144, 106151, 106157, 106164, + 0, 0, 104606, 104611, 104616, 104621, 104626, 104631, 104637, 104643, + 104649, 104654, 104659, 104664, 104670, 104676, 104682, 104687, 104693, + 104698, 104704, 104710, 104715, 104721, 104727, 104732, 104738, 104744, + 104750, 104756, 104762, 104767, 104773, 104779, 104785, 104790, 104795, + 104800, 104805, 104810, 104816, 104822, 104827, 104832, 104837, 104843, + 104848, 104853, 104859, 104865, 104870, 104877, 104883, 104888, 104894, + 104900, 104906, 104911, 0, 0, 0, 0, 104917, 104926, 104934, 104941, + 104948, 104953, 104958, 104963, 104968, 104973, 104978, 104983, 104988, + 104993, 104999, 105005, 105011, 105017, 105023, 105029, 0, 0, 105035, + 105042, 105049, 105056, 105064, 105072, 105080, 105088, 105096, 105104, + 105110, 105116, 105122, 105129, 105136, 105143, 105150, 105157, 105164, + 105171, 105178, 105185, 105192, 105199, 105206, 105213, 105220, 105227, + 105235, 105243, 105251, 105260, 105269, 105278, 105287, 105296, 105305, + 105313, 105321, 105329, 105338, 105347, 105356, 105365, 105374, 105383, + 105392, 105396, 105401, 105406, 0, 105412, 105417, 0, 0, 0, 0, 0, 105422, + 105428, 105435, 105440, 105445, 105449, 105454, 105459, 0, 105464, + 105469, 105474, 0, 105479, 105484, 105489, 105494, 105499, 105504, + 105509, 105514, 105519, 105524, 105529, 105533, 105537, 105542, 105547, + 105552, 105556, 105560, 105564, 105568, 105573, 105578, 105583, 105587, + 105592, 105596, 105601, 105606, 105611, 0, 0, 105616, 105622, 105627, 0, + 0, 0, 0, 105632, 105636, 105640, 105644, 105648, 105652, 105657, 105662, + 105668, 105673, 0, 0, 0, 0, 0, 0, 0, 105680, 105686, 105693, 105699, + 105706, 105712, 105718, 105724, 105731, 0, 0, 0, 0, 0, 0, 0, 105737, + 105745, 105753, 105761, 105769, 105777, 105785, 105793, 105801, 105809, + 105817, 105825, 105833, 105841, 105849, 105857, 105865, 105873, 105881, + 105889, 105897, 105905, 105913, 105921, 105929, 105937, 105945, 105953, + 105961, 105969, 105976, 105984, 105992, 105999, 106006, 106013, 106020, + 106027, 106034, 106041, 106048, 106055, 106062, 106069, 106076, 106083, + 106090, 106097, 106104, 106111, 106118, 106125, 106132, 106139, 106146, + 106153, 106160, 106167, 106174, 106181, 106188, 106195, 106201, 106208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 106171, 106176, 106181, 106186, 106191, 106196, - 106201, 106206, 106211, 106216, 106221, 106226, 106231, 106236, 106241, - 106246, 106251, 106256, 106261, 106266, 106271, 106276, 106281, 106286, - 106291, 106296, 106301, 106306, 106311, 106316, 106321, 106326, 106331, - 106336, 106341, 106346, 106351, 106356, 106362, 0, 0, 0, 0, 106368, - 106372, 106376, 106381, 106386, 106392, 106398, 106404, 106414, 106423, - 106429, 106436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106444, 106448, 106453, - 106458, 106463, 106468, 106473, 106478, 106483, 106487, 106492, 106496, - 106501, 106505, 106510, 106514, 106519, 106524, 106529, 106534, 106539, - 106544, 106549, 106554, 106559, 106564, 106569, 106574, 106579, 106584, - 106589, 106594, 106599, 106604, 106609, 106614, 106619, 106624, 106629, - 106634, 106639, 106644, 106649, 106654, 106659, 106664, 106669, 106674, - 106679, 106684, 106689, 106694, 106699, 106704, 0, 0, 0, 106709, 106714, - 106723, 106731, 106740, 106749, 106760, 106771, 106778, 106785, 106792, - 106799, 106806, 106813, 106820, 106827, 106834, 106841, 106848, 106855, - 106862, 106869, 106876, 106883, 106890, 106897, 106904, 106911, 106918, - 0, 0, 106925, 106931, 106937, 106943, 106949, 106956, 106963, 106971, - 106978, 106985, 106992, 106999, 107006, 107013, 107020, 107027, 107034, - 107041, 107048, 107055, 107062, 107069, 107076, 107083, 107090, 107097, - 107104, 0, 0, 0, 0, 0, 107111, 107117, 107123, 107129, 107135, 107142, - 107149, 107157, 107164, 107171, 107178, 107185, 107192, 107199, 107206, - 107213, 107220, 107227, 107234, 107241, 107248, 107255, 107262, 107269, - 107276, 107283, 0, 0, 0, 0, 0, 0, 0, 107290, 107297, 107305, 107315, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107325, 107331, 107337, 107343, 107349, - 107356, 107363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 106215, 106220, 106225, 106230, 106235, 106240, + 106245, 106250, 106255, 106260, 106265, 106270, 106275, 106280, 106285, + 106290, 106295, 106300, 106305, 106310, 106315, 106320, 106325, 106330, + 106335, 106340, 106345, 106350, 106355, 106360, 106365, 106370, 106375, + 106380, 106385, 106390, 106395, 106400, 106406, 0, 0, 0, 0, 106412, + 106416, 106420, 106425, 106430, 106436, 106442, 106448, 106458, 106467, + 106473, 106480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106488, 106492, 106497, + 106502, 106507, 106512, 106517, 106522, 106527, 106531, 106536, 106540, + 106545, 106549, 106554, 106558, 106563, 106568, 106573, 106578, 106583, + 106588, 106593, 106598, 106603, 106608, 106613, 106618, 106623, 106628, + 106633, 106638, 106643, 106648, 106653, 106658, 106663, 106668, 106673, + 106678, 106683, 106688, 106693, 106698, 106703, 106708, 106713, 106718, + 106723, 106728, 106733, 106738, 106743, 106748, 0, 0, 0, 106753, 106758, + 106767, 106775, 106784, 106793, 106804, 106815, 106822, 106829, 106836, + 106843, 106850, 106857, 106864, 106871, 106878, 106885, 106892, 106899, + 106906, 106913, 106920, 106927, 106934, 106941, 106948, 106955, 106962, + 0, 0, 106969, 106975, 106981, 106987, 106993, 107000, 107007, 107015, + 107022, 107029, 107036, 107043, 107050, 107057, 107064, 107071, 107078, + 107085, 107092, 107099, 107106, 107113, 107120, 107127, 107134, 107141, + 107148, 0, 0, 0, 0, 0, 107155, 107161, 107167, 107173, 107179, 107186, + 107193, 107201, 107208, 107215, 107222, 107229, 107236, 107243, 107250, + 107257, 107264, 107271, 107278, 107285, 107292, 107299, 107306, 107313, + 107320, 107327, 0, 0, 0, 0, 0, 0, 0, 107334, 107341, 107349, 107359, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107369, 107375, 107381, 107387, 107393, + 107400, 107407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107371, 107378, 107385, 107393, - 107400, 107407, 107414, 107421, 107429, 107437, 107445, 107453, 107461, - 107469, 107477, 107485, 107493, 107501, 107509, 107517, 107525, 107533, - 107541, 107549, 107557, 107565, 107573, 107581, 107589, 107597, 107605, - 107613, 107621, 107629, 107637, 107645, 107653, 107661, 107669, 107677, - 107685, 107693, 107701, 107709, 107717, 107725, 107733, 107741, 107749, - 107757, 107765, 107773, 107781, 107789, 107797, 107805, 107813, 107821, - 107829, 107837, 107845, 107853, 107861, 107869, 107877, 107885, 107893, - 107901, 107909, 107917, 107925, 107933, 107941, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107415, 107422, 107429, 107437, + 107444, 107451, 107458, 107465, 107473, 107481, 107489, 107497, 107505, + 107513, 107521, 107529, 107537, 107545, 107553, 107561, 107569, 107577, + 107585, 107593, 107601, 107609, 107617, 107625, 107633, 107641, 107649, + 107657, 107665, 107673, 107681, 107689, 107697, 107705, 107713, 107721, + 107729, 107737, 107745, 107753, 107761, 107769, 107777, 107785, 107793, + 107801, 107809, 107817, 107825, 107833, 107841, 107849, 107857, 107865, + 107873, 107881, 107889, 107897, 107905, 107913, 107921, 107929, 107937, + 107945, 107953, 107961, 107969, 107977, 107985, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 107949, 107954, 107960, 107966, 107972, 107978, 107984, 107990, 107996, - 108002, 108007, 108014, 108020, 108026, 108032, 108038, 108044, 108049, - 108055, 108061, 108067, 108073, 108079, 108085, 108091, 108097, 108103, - 108109, 108114, 108120, 108128, 108136, 108142, 108148, 108154, 108160, - 108168, 108174, 108180, 108186, 108192, 108198, 108204, 108209, 108215, - 108223, 108231, 108237, 108243, 108249, 108256, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 108262, 108267, 108273, 108279, 108285, 108291, 108297, - 108303, 108309, 108315, 108320, 108327, 108333, 108339, 108345, 108351, - 108357, 108362, 108368, 108374, 108380, 108386, 108392, 108398, 108404, - 108410, 108416, 108422, 108427, 108433, 108441, 108449, 108455, 108461, - 108467, 108473, 108481, 108487, 108493, 108499, 108505, 108511, 108517, - 108522, 108528, 108536, 108544, 108550, 108556, 108562, 108569, 0, 0, 0, - 0, 0, 0, 0, 108575, 108579, 108583, 108588, 108593, 108599, 108604, - 108610, 108617, 108623, 108630, 108637, 108644, 108651, 108657, 108664, - 108671, 108678, 108685, 108691, 108698, 108705, 108711, 108718, 108724, - 108731, 108737, 108743, 108749, 108756, 108765, 108771, 108779, 108786, - 108793, 108800, 108806, 108812, 108818, 108824, 108830, 108837, 108846, - 108853, 108860, 108867, 0, 0, 0, 0, 0, 0, 0, 0, 108874, 108881, 108887, - 108893, 108899, 108905, 108911, 108917, 108923, 108929, 0, 0, 0, 0, 0, 0, + 107993, 107998, 108004, 108010, 108016, 108022, 108028, 108034, 108040, + 108046, 108051, 108058, 108064, 108070, 108076, 108082, 108088, 108093, + 108099, 108105, 108111, 108117, 108123, 108129, 108135, 108141, 108147, + 108153, 108158, 108164, 108172, 108180, 108186, 108192, 108198, 108204, + 108212, 108218, 108224, 108230, 108236, 108242, 108248, 108253, 108259, + 108267, 108275, 108281, 108287, 108293, 108300, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108306, 108311, 108317, 108323, 108329, 108335, 108341, + 108347, 108353, 108359, 108364, 108371, 108377, 108383, 108389, 108395, + 108401, 108406, 108412, 108418, 108424, 108430, 108436, 108442, 108448, + 108454, 108460, 108466, 108471, 108477, 108485, 108493, 108499, 108505, + 108511, 108517, 108525, 108531, 108537, 108543, 108549, 108555, 108561, + 108566, 108572, 108580, 108588, 108594, 108600, 108606, 108613, 0, 0, 0, + 0, 0, 0, 0, 108619, 108623, 108627, 108632, 108637, 108643, 108648, + 108654, 108661, 108667, 108674, 108681, 108688, 108695, 108701, 108708, + 108715, 108722, 108729, 108735, 108742, 108749, 108755, 108762, 108768, + 108775, 108781, 108787, 108793, 108800, 108809, 108815, 108823, 108830, + 108837, 108844, 108850, 108856, 108862, 108868, 108874, 108881, 108890, + 108897, 108904, 108911, 0, 0, 0, 0, 0, 0, 0, 0, 108918, 108925, 108931, + 108937, 108943, 108949, 108955, 108961, 108967, 108973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108935, 108939, 108943, - 108947, 108951, 108955, 108959, 108963, 108967, 108971, 108976, 108981, - 108986, 108991, 108996, 109001, 109006, 109011, 109016, 109022, 109028, - 109034, 109041, 109048, 109055, 109062, 109069, 109076, 109083, 109090, - 109097, 0, 109104, 109109, 109114, 109119, 109124, 109129, 109134, - 109139, 109144, 109149, 109154, 109159, 109164, 109169, 109173, 109178, - 109183, 109188, 109193, 109198, 109203, 109208, 109213, 109218, 109223, - 109228, 109233, 109238, 109246, 109251, 109256, 109261, 109266, 109271, - 109276, 109281, 109286, 109291, 109296, 109301, 109306, 109311, 0, - 109316, 109322, 109328, 0, 0, 109333, 109341, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108979, 108983, 108987, + 108991, 108995, 108999, 109003, 109007, 109011, 109015, 109020, 109025, + 109030, 109035, 109040, 109045, 109050, 109055, 109060, 109066, 109072, + 109078, 109085, 109092, 109099, 109106, 109113, 109120, 109127, 109134, + 109141, 0, 109148, 109153, 109158, 109163, 109168, 109173, 109178, + 109183, 109188, 109193, 109198, 109203, 109208, 109213, 109217, 109222, + 109227, 109232, 109237, 109242, 109247, 109252, 109257, 109262, 109267, + 109272, 109277, 109282, 109290, 109295, 109300, 109305, 109310, 109315, + 109320, 109325, 109330, 109335, 109340, 109345, 109350, 109355, 0, + 109360, 109366, 109372, 0, 0, 109377, 109385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109350, 109357, - 109364, 109371, 109377, 109384, 109390, 109397, 109403, 109409, 109416, - 109422, 109428, 109434, 109440, 109446, 109452, 109458, 109464, 109471, - 109482, 109488, 109494, 109502, 109508, 109514, 109521, 109532, 109538, - 109544, 109550, 109557, 109568, 109573, 109578, 109583, 109588, 109593, - 109599, 109605, 109611, 109618, 109626, 0, 0, 0, 0, 0, 0, 0, 0, 109632, - 109637, 109642, 109647, 109652, 109657, 109662, 109667, 109672, 109677, - 109682, 109687, 109692, 109697, 109702, 109707, 109712, 109717, 109722, - 109727, 109732, 109737, 109743, 109748, 109754, 109759, 109765, 109771, - 109777, 109783, 109789, 109796, 109802, 109808, 109812, 109817, 109822, - 109828, 109836, 109847, 109856, 109866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109876, 109882, 109888, 109894, 109900, - 109906, 109913, 109919, 109925, 109931, 109937, 109943, 109949, 109955, - 109961, 109967, 109973, 109979, 109985, 109991, 109997, 110004, 110011, - 110017, 110025, 110033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110042, - 110047, 110053, 110058, 110063, 110068, 110073, 110078, 110085, 110090, - 110095, 110100, 110105, 110110, 110115, 110120, 110125, 110130, 110135, - 110140, 110145, 110150, 110154, 110158, 110162, 110166, 110171, 110176, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110182, - 110187, 110192, 110197, 110202, 110207, 110212, 110217, 110222, 110227, - 110232, 110237, 110242, 110247, 110252, 110257, 110262, 110267, 110272, - 110277, 110282, 110287, 110292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110297, - 110301, 110305, 110309, 110313, 110317, 110320, 110324, 110327, 110331, - 110334, 110338, 110342, 110347, 110351, 110356, 110359, 110363, 110366, - 110370, 110373, 110377, 110381, 110385, 110389, 110393, 110397, 110401, - 110405, 110409, 110413, 110417, 110421, 110425, 110429, 110433, 110437, - 110441, 110445, 110448, 110451, 110455, 110459, 110463, 110466, 110469, - 110472, 110475, 110479, 110483, 110487, 110490, 110493, 110497, 110503, - 110509, 110515, 110520, 110527, 110531, 110536, 110540, 110545, 110550, - 110556, 110561, 110567, 110571, 110576, 110580, 110585, 110588, 110591, - 110595, 110600, 110606, 110611, 110617, 0, 0, 0, 0, 110622, 110625, - 110628, 110631, 110634, 110637, 110640, 110643, 110646, 110649, 110653, - 110657, 110661, 110665, 110669, 110673, 110677, 110681, 110685, 110690, - 110694, 110698, 110701, 110704, 110707, 110710, 110713, 110716, 110719, - 110722, 110725, 110731, 110738, 110745, 110753, 110761, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 110767, 110771, 110776, 110781, 110786, 110790, 110795, 110799, - 110804, 110808, 110813, 110817, 110822, 110826, 110831, 110835, 110840, - 110845, 110850, 110855, 110860, 110865, 110870, 110875, 110880, 110885, - 110890, 110895, 110900, 110905, 110910, 110915, 110920, 110925, 110930, - 110935, 110939, 110943, 110948, 110953, 110958, 110962, 110966, 110970, - 110974, 110979, 110984, 110989, 110993, 110997, 111003, 111008, 111014, - 111019, 111025, 111030, 111036, 111041, 111047, 111052, 111057, 111062, - 111067, 111071, 111076, 111082, 111086, 111091, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 111097, 0, 0, 111102, 111109, 111116, 111123, 111130, 111137, - 111144, 111151, 111158, 111165, 111172, 111179, 111186, 111193, 111200, - 111207, 111214, 111221, 111228, 111235, 111242, 111249, 111256, 111263, - 111270, 0, 0, 0, 0, 0, 0, 0, 111277, 111284, 111290, 111296, 111302, - 111308, 111314, 111320, 111326, 111332, 0, 0, 0, 0, 0, 0, 111338, 111343, - 111348, 111353, 111358, 111362, 111366, 111370, 111375, 111380, 111385, - 111390, 111395, 111400, 111405, 111410, 111415, 111420, 111425, 111430, - 111435, 111440, 111445, 111450, 111455, 111460, 111465, 111470, 111475, - 111480, 111485, 111490, 111495, 111500, 111505, 111510, 111515, 111520, - 111525, 111530, 111535, 111540, 111546, 111551, 111557, 111562, 111568, - 111573, 111579, 111585, 111589, 111594, 111598, 0, 111602, 111607, - 111611, 111615, 111619, 111623, 111627, 111631, 111635, 111639, 111643, - 111648, 111652, 111657, 111662, 111667, 111673, 111679, 0, 0, 0, 0, 0, 0, - 0, 0, 111684, 111688, 111692, 111696, 111700, 111704, 111708, 111713, - 111718, 111723, 111728, 111733, 111738, 111743, 111748, 111753, 111758, - 111763, 111768, 111773, 111778, 111783, 111788, 111793, 111797, 111801, - 111806, 111811, 111816, 111820, 111824, 111828, 111833, 111837, 111841, - 111846, 111851, 111856, 111861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111866, - 111871, 111876, 111881, 111885, 111890, 111894, 111899, 111903, 111908, - 111913, 111919, 111924, 111930, 111934, 111939, 111943, 111948, 111952, - 111957, 111962, 111967, 111972, 111977, 111982, 111987, 111992, 111997, - 112002, 112007, 112012, 112017, 112022, 112027, 112032, 112037, 112042, - 112046, 112050, 112055, 112060, 112065, 112069, 112073, 112077, 112081, - 112086, 112091, 112096, 112101, 112105, 112109, 112115, 112120, 112126, - 112131, 112137, 112143, 112150, 112156, 112163, 112168, 112174, 112179, - 112185, 112190, 112195, 112200, 112205, 112209, 112213, 112218, 112223, - 112227, 112232, 112237, 112242, 112250, 112255, 112262, 112269, 112274, - 112278, 112282, 112286, 112290, 112294, 112298, 112302, 112306, 112310, - 112314, 112319, 112323, 112328, 112334, 0, 112340, 112345, 112350, - 112355, 112360, 112365, 112370, 112375, 112380, 112385, 112391, 112397, - 112403, 112409, 112415, 112421, 112427, 112433, 112439, 112446, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 112452, 112456, 112461, 112465, 112469, 112473, - 112478, 112482, 112487, 112491, 112496, 112501, 112506, 112511, 112516, - 112521, 112526, 112531, 0, 112536, 112541, 112546, 112551, 112556, - 112561, 112566, 112571, 112576, 112581, 112586, 112591, 112595, 112599, - 112604, 112609, 112614, 112619, 112623, 112627, 112631, 112635, 112640, - 112644, 112648, 112653, 112659, 112664, 112670, 112675, 112680, 112686, - 112691, 112697, 112702, 112707, 112712, 112717, 112721, 112726, 112732, - 112737, 112743, 112748, 112753, 112758, 112764, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109394, 109401, + 109408, 109415, 109421, 109428, 109434, 109441, 109447, 109453, 109460, + 109466, 109472, 109478, 109484, 109490, 109496, 109502, 109508, 109515, + 109526, 109532, 109538, 109546, 109552, 109558, 109565, 109576, 109582, + 109588, 109594, 109601, 109612, 109617, 109622, 109627, 109632, 109637, + 109643, 109649, 109655, 109662, 109670, 0, 0, 0, 0, 0, 0, 0, 0, 109676, + 109681, 109686, 109691, 109696, 109701, 109706, 109711, 109716, 109721, + 109726, 109731, 109736, 109741, 109746, 109751, 109756, 109761, 109766, + 109771, 109776, 109781, 109787, 109792, 109798, 109803, 109809, 109815, + 109821, 109827, 109833, 109840, 109846, 109852, 109856, 109861, 109866, + 109872, 109880, 109891, 109900, 109910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109920, 109926, 109932, 109938, 109944, + 109950, 109957, 109963, 109969, 109975, 109981, 109987, 109993, 109999, + 110005, 110011, 110017, 110023, 110029, 110035, 110041, 110048, 110055, + 110061, 110069, 110077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110086, + 110091, 110097, 110102, 110107, 110112, 110117, 110122, 110129, 110134, + 110139, 110144, 110149, 110154, 110159, 110164, 110169, 110174, 110179, + 110184, 110189, 110194, 110198, 110202, 110206, 110210, 110215, 110220, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110226, + 110231, 110236, 110241, 110246, 110251, 110256, 110261, 110266, 110271, + 110276, 110281, 110286, 110291, 110296, 110301, 110306, 110311, 110316, + 110321, 110326, 110331, 110336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110341, + 110345, 110349, 110353, 110357, 110361, 110364, 110368, 110371, 110375, + 110378, 110382, 110386, 110391, 110395, 110400, 110403, 110407, 110410, + 110414, 110417, 110421, 110425, 110429, 110433, 110437, 110441, 110445, + 110449, 110453, 110457, 110461, 110465, 110469, 110473, 110477, 110481, + 110485, 110489, 110492, 110495, 110499, 110503, 110507, 110510, 110513, + 110516, 110519, 110523, 110527, 110531, 110534, 110537, 110541, 110547, + 110553, 110559, 110564, 110571, 110575, 110580, 110584, 110589, 110594, + 110600, 110605, 110611, 110615, 110620, 110624, 110629, 110632, 110635, + 110639, 110644, 110650, 110655, 110661, 0, 0, 0, 0, 110666, 110669, + 110672, 110675, 110678, 110681, 110684, 110687, 110690, 110693, 110697, + 110701, 110705, 110709, 110713, 110717, 110721, 110725, 110729, 110734, + 110738, 110742, 110745, 110748, 110751, 110754, 110757, 110760, 110763, + 110766, 110769, 110775, 110782, 110789, 110797, 110805, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 110811, 110815, 110820, 110825, 110830, 110834, 110839, 110843, + 110848, 110852, 110857, 110861, 110866, 110870, 110875, 110879, 110884, + 110889, 110894, 110899, 110904, 110909, 110914, 110919, 110924, 110929, + 110934, 110939, 110944, 110949, 110954, 110959, 110964, 110969, 110974, + 110979, 110983, 110987, 110992, 110997, 111002, 111006, 111010, 111014, + 111018, 111023, 111028, 111033, 111037, 111041, 111047, 111052, 111058, + 111063, 111069, 111074, 111080, 111085, 111091, 111096, 111101, 111106, + 111111, 111115, 111120, 111126, 111130, 111135, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 111141, 0, 0, 111146, 111153, 111160, 111167, 111174, 111181, + 111188, 111195, 111202, 111209, 111216, 111223, 111230, 111237, 111244, + 111251, 111258, 111265, 111272, 111279, 111286, 111293, 111300, 111307, + 111314, 0, 0, 0, 0, 0, 0, 0, 111321, 111328, 111334, 111340, 111346, + 111352, 111358, 111364, 111370, 111376, 0, 0, 0, 0, 0, 0, 111382, 111387, + 111392, 111397, 111402, 111406, 111410, 111414, 111419, 111424, 111429, + 111434, 111439, 111444, 111449, 111454, 111459, 111464, 111469, 111474, + 111479, 111484, 111489, 111494, 111499, 111504, 111509, 111514, 111519, + 111524, 111529, 111534, 111539, 111544, 111549, 111554, 111559, 111564, + 111569, 111574, 111579, 111584, 111590, 111595, 111601, 111606, 111612, + 111617, 111623, 111629, 111633, 111638, 111642, 0, 111646, 111651, + 111655, 111659, 111663, 111667, 111671, 111675, 111679, 111683, 111687, + 111692, 111696, 111701, 111706, 111711, 111717, 111723, 0, 0, 0, 0, 0, 0, + 0, 0, 111728, 111732, 111736, 111740, 111744, 111748, 111752, 111757, + 111762, 111767, 111772, 111777, 111782, 111787, 111792, 111797, 111802, + 111807, 111812, 111817, 111822, 111827, 111832, 111837, 111841, 111845, + 111850, 111855, 111860, 111864, 111868, 111872, 111877, 111881, 111885, + 111890, 111895, 111900, 111905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111910, + 111915, 111920, 111925, 111929, 111934, 111938, 111943, 111947, 111952, + 111957, 111963, 111968, 111974, 111978, 111983, 111987, 111992, 111996, + 112001, 112006, 112011, 112016, 112021, 112026, 112031, 112036, 112041, + 112046, 112051, 112056, 112061, 112066, 112071, 112076, 112081, 112086, + 112090, 112094, 112099, 112104, 112109, 112113, 112117, 112121, 112125, + 112130, 112135, 112140, 112145, 112149, 112153, 112159, 112164, 112170, + 112175, 112181, 112187, 112194, 112200, 112207, 112212, 112218, 112223, + 112229, 112234, 112239, 112244, 112249, 112253, 112257, 112262, 112267, + 112271, 112276, 112281, 112286, 112294, 112299, 112306, 112313, 112318, + 112322, 112326, 112330, 112334, 112338, 112342, 112346, 112350, 112354, + 112358, 112363, 112367, 112372, 112378, 0, 112384, 112389, 112394, + 112399, 112404, 112409, 112414, 112419, 112424, 112429, 112435, 112441, + 112447, 112453, 112459, 112465, 112471, 112477, 112483, 112490, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 112496, 112500, 112505, 112509, 112513, 112517, + 112522, 112526, 112531, 112535, 112540, 112545, 112550, 112555, 112560, + 112565, 112570, 112575, 0, 112580, 112585, 112590, 112595, 112600, + 112605, 112610, 112615, 112620, 112625, 112630, 112635, 112639, 112643, + 112648, 112653, 112658, 112663, 112667, 112671, 112675, 112679, 112684, + 112688, 112692, 112697, 112703, 112708, 112714, 112719, 112724, 112730, + 112735, 112741, 112746, 112751, 112756, 112761, 112765, 112770, 112776, + 112781, 112787, 112792, 112797, 112802, 112808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 112770, 112774, 112778, 112782, 112786, 112790, 112795, - 0, 112800, 0, 112805, 112810, 112815, 112820, 0, 112825, 112830, 112835, - 112840, 112845, 112850, 112855, 112860, 112865, 112870, 112875, 112880, - 112884, 112888, 112893, 0, 112898, 112903, 112907, 112911, 112915, - 112919, 112924, 112928, 112932, 112937, 112942, 0, 0, 0, 0, 0, 0, 112947, - 112951, 112956, 112960, 112965, 112969, 112974, 112978, 112983, 112987, - 112992, 112996, 113001, 113006, 113011, 113016, 113021, 113026, 113031, - 113036, 113041, 113046, 113051, 113056, 113061, 113066, 113071, 113076, - 113081, 113086, 113091, 113096, 113101, 113106, 113110, 113114, 113119, - 113124, 113129, 113134, 113138, 113142, 113146, 113150, 113155, 113160, - 113164, 113168, 113173, 113179, 113184, 113190, 113195, 113201, 113206, - 113212, 113217, 113223, 113228, 0, 0, 0, 0, 0, 113233, 113238, 113242, - 113246, 113250, 113254, 113258, 113262, 113266, 113270, 0, 0, 0, 0, 0, 0, - 113274, 113281, 113286, 113291, 0, 113296, 113300, 113305, 113309, - 113314, 113318, 113323, 113328, 0, 0, 113333, 113338, 0, 0, 113343, - 113348, 113353, 113357, 113362, 113367, 113372, 113377, 113382, 113387, - 113392, 113397, 113402, 113407, 113412, 113417, 113422, 113427, 113432, - 113437, 113442, 113447, 0, 113451, 113455, 113460, 113465, 113470, - 113474, 113478, 0, 113482, 113486, 0, 113491, 113496, 113501, 113506, - 113510, 0, 113514, 113518, 113523, 113528, 113534, 113539, 113545, - 113550, 113556, 113562, 0, 0, 113569, 113575, 0, 0, 113581, 113587, - 113593, 0, 0, 113598, 0, 0, 0, 0, 0, 0, 113602, 0, 0, 0, 0, 0, 113609, - 113614, 113621, 113629, 113635, 113641, 113647, 0, 0, 113654, 113660, - 113665, 113670, 113675, 113680, 113685, 0, 0, 0, 113690, 113695, 113700, - 113705, 113711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113716, 113720, 113725, - 113729, 113734, 113738, 113743, 113748, 113754, 113759, 113765, 113769, - 113774, 113778, 113783, 113787, 113792, 113797, 113802, 113807, 113812, - 113817, 113822, 113827, 113832, 113837, 113842, 113847, 113852, 113857, - 113862, 113867, 113872, 113877, 113882, 113887, 113891, 113896, 113900, - 113905, 113910, 113915, 113919, 113924, 113928, 113932, 113937, 113941, - 113946, 113951, 113956, 113961, 113965, 113969, 113975, 113980, 113986, - 113991, 113997, 114003, 114010, 114016, 114023, 114028, 114034, 114039, - 114045, 114050, 114055, 114060, 114065, 114070, 114075, 114081, 114085, - 114089, 114093, 114098, 114102, 114108, 114113, 114118, 114122, 114126, - 114130, 114134, 114138, 114142, 114146, 114150, 114154, 114159, 0, - 114164, 114169, 114174, 114181, 114186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114191, 114195, - 114199, 114204, 114208, 114213, 114217, 114222, 114227, 114233, 114238, - 114244, 114248, 114253, 114257, 114262, 114266, 114271, 114276, 114281, - 114286, 114291, 114296, 114301, 114306, 114311, 114316, 114321, 114326, - 114331, 114336, 114341, 114346, 114351, 114356, 114360, 114364, 114369, - 114374, 114379, 114383, 114387, 114391, 114395, 114400, 114405, 114410, - 114414, 114418, 114424, 114429, 114435, 114440, 114446, 114452, 114459, - 114465, 114472, 114477, 114484, 114490, 114495, 114502, 114508, 114513, - 114518, 114523, 114528, 114533, 114538, 114542, 114547, 0, 0, 0, 0, 0, 0, - 0, 0, 114551, 114556, 114560, 114564, 114568, 114572, 114576, 114580, - 114584, 114588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114592, 114596, - 114601, 114605, 114610, 114614, 114619, 114624, 114630, 114635, 114641, - 114645, 114650, 114654, 114659, 114663, 114668, 114673, 114678, 114683, - 114688, 114693, 114698, 114703, 114708, 114713, 114718, 114723, 114728, - 114733, 114738, 114743, 114748, 114753, 114757, 114761, 114766, 114771, - 114776, 114780, 114784, 114788, 114792, 114797, 114802, 114807, 114811, - 114815, 114821, 114826, 114832, 114837, 114843, 114849, 0, 0, 114856, - 114861, 114867, 114872, 114878, 114883, 114888, 114893, 114898, 114903, - 114908, 114912, 114917, 114923, 114928, 114934, 114940, 114946, 114954, - 114967, 114980, 114993, 115007, 115022, 115030, 115041, 115050, 115060, - 115070, 115080, 115091, 115103, 115116, 115124, 115132, 115141, 115147, - 115154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115162, 115166, 115171, 115175, - 115180, 115184, 115189, 115194, 115200, 115205, 115211, 115215, 115220, - 115224, 115229, 115233, 115238, 115243, 115248, 115253, 115258, 115263, - 115268, 115273, 115278, 115283, 115288, 115293, 115298, 115303, 115308, - 115313, 115318, 115323, 115327, 115331, 115336, 115341, 115346, 115350, - 115354, 115358, 115362, 115367, 115372, 115377, 115381, 115385, 115390, - 115396, 115401, 115407, 115412, 115418, 115424, 115431, 115437, 115444, - 115449, 115455, 115460, 115466, 115471, 115476, 115481, 115486, 115490, - 115495, 115500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115505, 115510, 115514, - 115518, 115522, 115526, 115530, 115534, 115538, 115542, 0, 0, 0, 0, 0, 0, - 115546, 115552, 115557, 115564, 115572, 115579, 115587, 115596, 115601, - 115610, 115615, 115623, 115632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 115642, 115646, 115651, 115655, 115660, 115664, 115669, - 115673, 115678, 115682, 115687, 115691, 115696, 115701, 115706, 115711, - 115716, 115721, 115726, 115731, 115736, 115741, 115746, 115751, 115756, - 115761, 115766, 115771, 115776, 115781, 115785, 115789, 115794, 115799, - 115804, 115808, 115812, 115816, 115820, 115825, 115830, 115834, 115838, - 115843, 115848, 115853, 115859, 115864, 115870, 115875, 115881, 115886, - 115892, 115897, 115903, 115908, 115913, 115920, 0, 0, 0, 0, 0, 0, 115925, - 115930, 115934, 115938, 115942, 115946, 115950, 115954, 115958, 115962, + 0, 0, 0, 0, 0, 0, 112814, 112818, 112822, 112826, 112830, 112834, 112839, + 0, 112844, 0, 112849, 112854, 112859, 112864, 0, 112869, 112874, 112879, + 112884, 112889, 112894, 112899, 112904, 112909, 112914, 112919, 112924, + 112928, 112932, 112937, 0, 112942, 112947, 112951, 112955, 112959, + 112963, 112968, 112972, 112976, 112981, 112986, 0, 0, 0, 0, 0, 0, 112991, + 112995, 113000, 113004, 113009, 113013, 113018, 113022, 113027, 113031, + 113036, 113040, 113045, 113050, 113055, 113060, 113065, 113070, 113075, + 113080, 113085, 113090, 113095, 113100, 113105, 113110, 113115, 113120, + 113125, 113130, 113135, 113140, 113145, 113150, 113154, 113158, 113163, + 113168, 113173, 113178, 113182, 113186, 113190, 113194, 113199, 113204, + 113208, 113212, 113217, 113223, 113228, 113234, 113239, 113245, 113250, + 113256, 113261, 113267, 113272, 0, 0, 0, 0, 0, 113277, 113282, 113286, + 113290, 113294, 113298, 113302, 113306, 113310, 113314, 0, 0, 0, 0, 0, 0, + 113318, 113325, 113330, 113335, 0, 113340, 113344, 113349, 113353, + 113358, 113362, 113367, 113372, 0, 0, 113377, 113382, 0, 0, 113387, + 113392, 113397, 113401, 113406, 113411, 113416, 113421, 113426, 113431, + 113436, 113441, 113446, 113451, 113456, 113461, 113466, 113471, 113476, + 113481, 113486, 113491, 0, 113495, 113499, 113504, 113509, 113514, + 113518, 113522, 0, 113526, 113530, 0, 113535, 113540, 113545, 113550, + 113554, 0, 113558, 113562, 113567, 113572, 113578, 113583, 113589, + 113594, 113600, 113606, 0, 0, 113613, 113619, 0, 0, 113625, 113631, + 113637, 0, 0, 113642, 0, 0, 0, 0, 0, 0, 113646, 0, 0, 0, 0, 0, 113653, + 113658, 113665, 113673, 113679, 113685, 113691, 0, 0, 113698, 113704, + 113709, 113714, 113719, 113724, 113729, 0, 0, 0, 113734, 113739, 113744, + 113749, 113755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113760, 113764, 113769, + 113773, 113778, 113782, 113787, 113792, 113798, 113803, 113809, 113813, + 113818, 113822, 113827, 113831, 113836, 113841, 113846, 113851, 113856, + 113861, 113866, 113871, 113876, 113881, 113886, 113891, 113896, 113901, + 113906, 113911, 113916, 113921, 113926, 113931, 113935, 113940, 113944, + 113949, 113954, 113959, 113963, 113968, 113972, 113976, 113981, 113985, + 113990, 113995, 114000, 114005, 114009, 114013, 114019, 114024, 114030, + 114035, 114041, 114047, 114054, 114060, 114067, 114072, 114078, 114083, + 114089, 114094, 114099, 114104, 114109, 114114, 114119, 114125, 114129, + 114133, 114137, 114142, 114146, 114152, 114157, 114162, 114166, 114170, + 114174, 114178, 114182, 114186, 114190, 114194, 114198, 114203, 0, + 114208, 114213, 114218, 114225, 114230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114235, 114239, + 114243, 114248, 114252, 114257, 114261, 114266, 114271, 114277, 114282, + 114288, 114292, 114297, 114301, 114306, 114310, 114315, 114320, 114325, + 114330, 114335, 114340, 114345, 114350, 114355, 114360, 114365, 114370, + 114375, 114380, 114385, 114390, 114395, 114400, 114404, 114408, 114413, + 114418, 114423, 114427, 114431, 114435, 114439, 114444, 114449, 114454, + 114458, 114462, 114468, 114473, 114479, 114484, 114490, 114496, 114503, + 114509, 114516, 114521, 114528, 114534, 114539, 114546, 114552, 114557, + 114562, 114567, 114572, 114577, 114582, 114586, 114591, 0, 0, 0, 0, 0, 0, + 0, 0, 114595, 114600, 114604, 114608, 114612, 114616, 114620, 114624, + 114628, 114632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114636, 114640, + 114645, 114649, 114654, 114658, 114663, 114668, 114674, 114679, 114685, + 114689, 114694, 114698, 114703, 114707, 114712, 114717, 114722, 114727, + 114732, 114737, 114742, 114747, 114752, 114757, 114762, 114767, 114772, + 114777, 114782, 114787, 114792, 114797, 114801, 114805, 114810, 114815, + 114820, 114824, 114828, 114832, 114836, 114841, 114846, 114851, 114855, + 114859, 114865, 114870, 114876, 114881, 114887, 114893, 0, 0, 114900, + 114905, 114911, 114916, 114922, 114927, 114932, 114937, 114942, 114947, + 114952, 114956, 114961, 114967, 114972, 114978, 114984, 114990, 114998, + 115011, 115024, 115037, 115051, 115066, 115074, 115085, 115094, 115104, + 115114, 115124, 115135, 115147, 115160, 115168, 115176, 115185, 115191, + 115198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115206, 115210, 115215, 115219, + 115224, 115228, 115233, 115238, 115244, 115249, 115255, 115259, 115264, + 115268, 115273, 115277, 115282, 115287, 115292, 115297, 115302, 115307, + 115312, 115317, 115322, 115327, 115332, 115337, 115342, 115347, 115352, + 115357, 115362, 115367, 115371, 115375, 115380, 115385, 115390, 115394, + 115398, 115402, 115406, 115411, 115416, 115421, 115425, 115429, 115434, + 115440, 115445, 115451, 115456, 115462, 115468, 115475, 115481, 115488, + 115493, 115499, 115504, 115510, 115515, 115520, 115525, 115530, 115534, + 115539, 115544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115549, 115554, 115558, + 115562, 115566, 115570, 115574, 115578, 115582, 115586, 0, 0, 0, 0, 0, 0, + 115590, 115596, 115601, 115608, 115616, 115623, 115631, 115640, 115645, + 115654, 115659, 115667, 115676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 115686, 115690, 115695, 115699, 115704, 115708, 115713, + 115717, 115722, 115726, 115731, 115735, 115740, 115745, 115750, 115755, + 115760, 115765, 115770, 115775, 115780, 115785, 115790, 115795, 115800, + 115805, 115810, 115815, 115820, 115825, 115829, 115833, 115838, 115843, + 115848, 115852, 115856, 115860, 115864, 115869, 115874, 115878, 115882, + 115887, 115892, 115897, 115903, 115908, 115914, 115919, 115925, 115930, + 115936, 115941, 115947, 115952, 115957, 115964, 0, 0, 0, 0, 0, 0, 115969, + 115974, 115978, 115982, 115986, 115990, 115994, 115998, 116002, 116006, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 115966, 115970, 115975, 115980, 115984, 115989, 115996, - 116000, 116005, 116010, 116014, 116019, 116024, 116029, 116033, 116037, - 116041, 116046, 116050, 116054, 116059, 116064, 116069, 116076, 116081, - 116086, 116091, 0, 0, 116098, 116105, 116112, 116121, 116126, 116132, - 116137, 116143, 116148, 116154, 116159, 116165, 116170, 116176, 116182, - 0, 0, 0, 0, 116187, 116192, 116196, 116200, 116204, 116208, 116212, - 116216, 116220, 116224, 116228, 116233, 116238, 116244, 116249, 116254, - 116259, 116264, 116269, 116274, 116279, 116284, 116289, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 116010, 116014, 116019, 116024, 116028, 116033, 116040, + 116044, 116049, 116054, 116058, 116063, 116068, 116073, 116077, 116081, + 116085, 116090, 116094, 116098, 116103, 116108, 116113, 116120, 116125, + 116130, 116135, 0, 0, 116142, 116149, 116156, 116165, 116170, 116176, + 116181, 116187, 116192, 116198, 116203, 116209, 116214, 116220, 116226, + 0, 0, 0, 0, 116231, 116236, 116240, 116244, 116248, 116252, 116256, + 116260, 116264, 116268, 116272, 116277, 116282, 116288, 116293, 116298, + 116303, 116308, 116313, 116318, 116323, 116328, 116333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 116294, 116298, 116303, 116307, 116312, 116316, 116321, 116325, - 116330, 116334, 116339, 116343, 116348, 116353, 116358, 116363, 116368, - 116373, 116378, 116383, 116388, 116393, 116398, 116403, 116408, 116413, - 116418, 116423, 116428, 116433, 116437, 116441, 116446, 116451, 116456, - 116460, 116464, 116468, 116472, 116477, 116482, 116487, 116491, 116495, - 116500, 116506, 116511, 116517, 116522, 116528, 116534, 116541, 116546, - 116552, 116557, 116563, 116568, 116573, 116578, 116583, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 116338, 116342, 116347, 116351, 116356, 116360, 116365, 116369, + 116374, 116378, 116383, 116387, 116392, 116397, 116402, 116407, 116412, + 116417, 116422, 116427, 116432, 116437, 116442, 116447, 116452, 116457, + 116462, 116467, 116472, 116477, 116481, 116485, 116490, 116495, 116500, + 116504, 116508, 116512, 116516, 116521, 116526, 116531, 116535, 116539, + 116544, 116550, 116555, 116561, 116566, 116572, 116578, 116585, 116590, + 116596, 116601, 116607, 116612, 116617, 116622, 116627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116588, - 116596, 116603, 116611, 116619, 116626, 116634, 116642, 116650, 116657, - 116664, 116672, 116680, 116688, 116696, 116704, 116712, 116720, 116728, - 116736, 116744, 116752, 116760, 116768, 116776, 116784, 116792, 116800, - 116808, 116816, 116824, 116832, 116840, 116848, 116855, 116863, 116871, - 116878, 116886, 116894, 116902, 116909, 116916, 116924, 116932, 116940, - 116948, 116956, 116964, 116972, 116980, 116988, 116996, 117004, 117012, - 117020, 117028, 117036, 117044, 117052, 117060, 117068, 117076, 117084, - 117092, 117099, 117105, 117111, 117117, 117123, 117129, 117135, 117141, - 117147, 117153, 117160, 117167, 117174, 117181, 117188, 117195, 117202, - 117209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117216, 117222, 117228, - 117235, 117241, 117248, 117254, 117261, 0, 0, 117267, 0, 0, 117273, - 117279, 117286, 117293, 117300, 117307, 117314, 117321, 0, 117328, - 117335, 0, 117342, 117349, 117356, 117363, 117370, 117377, 117384, - 117391, 117397, 117403, 117410, 117417, 117424, 117430, 117436, 117443, - 117449, 117455, 117462, 117469, 117476, 117482, 117488, 117495, 117502, - 117510, 117517, 117525, 117532, 117540, 0, 117547, 117555, 0, 0, 117562, - 117569, 117576, 117583, 117589, 117598, 117605, 117611, 117618, 117625, - 117632, 117640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117650, 117657, 117663, - 117669, 117675, 117681, 117687, 117693, 117699, 117705, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116632, + 116640, 116647, 116655, 116663, 116670, 116678, 116686, 116694, 116701, + 116708, 116716, 116724, 116732, 116740, 116748, 116756, 116764, 116772, + 116780, 116788, 116796, 116804, 116812, 116820, 116828, 116836, 116844, + 116852, 116860, 116868, 116876, 116884, 116892, 116899, 116907, 116915, + 116922, 116930, 116938, 116946, 116953, 116960, 116968, 116976, 116984, + 116992, 117000, 117008, 117016, 117024, 117032, 117040, 117048, 117056, + 117064, 117072, 117080, 117088, 117096, 117104, 117112, 117120, 117128, + 117136, 117143, 117149, 117155, 117161, 117167, 117173, 117179, 117185, + 117191, 117197, 117204, 117211, 117218, 117225, 117232, 117239, 117246, + 117253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117260, 117266, 117272, + 117279, 117285, 117292, 117298, 117305, 0, 0, 117311, 0, 0, 117317, + 117323, 117330, 117337, 117344, 117351, 117358, 117365, 0, 117372, + 117379, 0, 117386, 117393, 117400, 117407, 117414, 117421, 117428, + 117435, 117441, 117447, 117454, 117461, 117468, 117474, 117480, 117487, + 117493, 117499, 117506, 117513, 117520, 117526, 117532, 117539, 117546, + 117554, 117561, 117569, 117576, 117584, 0, 117591, 117599, 0, 0, 117606, + 117613, 117620, 117627, 117633, 117642, 117649, 117655, 117662, 117669, + 117676, 117684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117694, 117701, 117707, + 117713, 117719, 117725, 117731, 117737, 117743, 117749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117711, 117715, 117720, - 117724, 117729, 117733, 117738, 117743, 0, 0, 117749, 117753, 117758, - 117762, 117767, 117771, 117776, 117781, 117786, 117791, 117796, 117801, - 117806, 117811, 117816, 117821, 117826, 117831, 117836, 117841, 117846, - 117851, 117856, 117861, 117865, 117869, 117874, 117879, 117884, 117888, - 117892, 117896, 117900, 117905, 117910, 117915, 117919, 117923, 117928, - 117933, 117939, 117944, 117950, 117955, 117961, 117967, 0, 0, 117974, - 117979, 117985, 117990, 117996, 118001, 118006, 118011, 118016, 118021, - 118025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 118032, 118037, 118043, 118050, 118056, 118062, 118069, - 118075, 118082, 118089, 118097, 118104, 118109, 118115, 118121, 118127, - 118133, 118139, 118145, 118151, 118157, 118163, 118169, 118175, 118181, - 118187, 118193, 118199, 118205, 118211, 118216, 118221, 118227, 118233, - 118239, 118244, 118250, 118256, 118262, 118268, 118274, 118280, 118286, - 118291, 118296, 118301, 118307, 118313, 118319, 118324, 118329, 118335, - 118341, 118347, 118353, 118362, 118371, 118377, 118383, 118390, 118397, - 118404, 118411, 118419, 118426, 118434, 118440, 118446, 118453, 118460, - 118469, 118479, 0, 0, 0, 0, 0, 0, 0, 0, 118484, 118488, 118493, 118499, - 118504, 118509, 118514, 118520, 118526, 118532, 118538, 118544, 118550, - 118554, 118559, 118564, 118569, 118574, 118579, 118584, 118589, 118594, - 118599, 118604, 118609, 118614, 118619, 118624, 118629, 118634, 118639, - 118644, 118648, 118652, 118657, 118662, 118667, 118671, 118676, 118681, - 118686, 118691, 118696, 118701, 118705, 118709, 118713, 118718, 118723, - 118728, 118732, 118736, 118741, 118746, 118751, 118757, 118763, 118770, - 118776, 118783, 118790, 118797, 118804, 118811, 118818, 118825, 118831, - 118837, 118844, 118851, 118858, 118863, 118868, 118873, 118877, 118882, - 118887, 118893, 118898, 118914, 118928, 118939, 118945, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 118951, 118957, 118963, 118969, 118975, 118980, - 118986, 118992, 118998, 119004, 119010, 119016, 119022, 119026, 119030, - 119034, 119038, 119046, 119054, 119062, 119070, 119079, 119088, 119097, - 119106, 119114, 119123, 119132, 119140, 119149, 119158, 119167, 119176, - 119184, 119193, 119201, 119210, 119219, 119227, 119235, 119243, 119251, - 119259, 119268, 119277, 119287, 119297, 119307, 119317, 119327, 119336, - 119346, 119356, 119366, 119377, 119387, 119399, 119411, 119422, 119436, - 119447, 119457, 119469, 119480, 119490, 119502, 119514, 119525, 119536, - 119546, 119556, 119568, 119579, 0, 0, 0, 0, 0, 0, 0, 119591, 119595, - 119602, 119606, 119612, 119618, 119626, 119634, 119642, 119650, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117755, 117759, 117764, + 117768, 117773, 117777, 117782, 117787, 0, 0, 117793, 117797, 117802, + 117806, 117811, 117815, 117820, 117825, 117830, 117835, 117840, 117845, + 117850, 117855, 117860, 117865, 117870, 117875, 117880, 117885, 117890, + 117895, 117900, 117905, 117909, 117913, 117918, 117923, 117928, 117932, + 117936, 117940, 117944, 117949, 117954, 117959, 117963, 117967, 117972, + 117977, 117983, 117988, 117994, 117999, 118005, 118011, 0, 0, 118018, + 118023, 118029, 118034, 118040, 118045, 118050, 118055, 118060, 118065, + 118069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 118076, 118081, 118087, 118094, 118100, 118106, 118113, + 118119, 118126, 118133, 118141, 118148, 118153, 118159, 118165, 118171, + 118177, 118183, 118189, 118195, 118201, 118207, 118213, 118219, 118225, + 118231, 118237, 118243, 118249, 118255, 118260, 118265, 118271, 118277, + 118283, 118288, 118294, 118300, 118306, 118312, 118318, 118324, 118330, + 118335, 118340, 118345, 118351, 118357, 118363, 118368, 118373, 118379, + 118385, 118391, 118397, 118406, 118415, 118421, 118427, 118434, 118441, + 118448, 118455, 118463, 118470, 118478, 118484, 118490, 118497, 118504, + 118513, 118523, 0, 0, 0, 0, 0, 0, 0, 0, 118528, 118532, 118537, 118543, + 118548, 118553, 118558, 118564, 118570, 118576, 118582, 118588, 118594, + 118598, 118603, 118608, 118613, 118618, 118623, 118628, 118633, 118638, + 118643, 118648, 118653, 118658, 118663, 118668, 118673, 118678, 118683, + 118688, 118692, 118696, 118701, 118706, 118711, 118715, 118720, 118725, + 118730, 118735, 118740, 118745, 118749, 118753, 118757, 118762, 118767, + 118772, 118776, 118780, 118785, 118790, 118795, 118801, 118807, 118814, + 118820, 118827, 118834, 118841, 118848, 118855, 118862, 118869, 118875, + 118881, 118888, 118895, 118902, 118907, 118912, 118917, 118921, 118926, + 118931, 118937, 118942, 118958, 118972, 118983, 118989, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 118995, 119001, 119007, 119013, 119019, 119024, + 119030, 119036, 119042, 119048, 119054, 119060, 119066, 119070, 119074, + 119078, 119082, 119090, 119098, 119106, 119114, 119123, 119132, 119141, + 119150, 119158, 119167, 119176, 119184, 119193, 119202, 119211, 119220, + 119228, 119237, 119245, 119254, 119263, 119271, 119279, 119287, 119295, + 119303, 119312, 119321, 119331, 119341, 119351, 119361, 119371, 119380, + 119390, 119400, 119410, 119421, 119431, 119443, 119455, 119466, 119480, + 119491, 119501, 119513, 119524, 119534, 119546, 119558, 119569, 119580, + 119590, 119600, 119612, 119623, 0, 0, 0, 0, 0, 0, 0, 119635, 119639, + 119646, 119650, 119656, 119662, 119670, 119678, 119686, 119694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119654, 119658, - 119663, 119667, 119672, 119676, 119681, 119686, 119692, 0, 119697, - 119701, 119706, 119710, 119715, 119719, 119724, 119729, 119734, 119739, - 119744, 119749, 119754, 119759, 119764, 119769, 119774, 119779, 119784, - 119789, 119794, 119799, 119804, 119809, 119813, 119817, 119822, 119827, - 119832, 119836, 119840, 119844, 119848, 119853, 119858, 119863, 119867, - 119871, 119877, 119882, 119888, 119893, 119899, 119905, 119912, 0, - 119918, 119923, 119929, 119934, 119940, 119945, 119950, 119955, 119960, - 119965, 119969, 119974, 119980, 119986, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 119992, 119997, 120001, 120005, 120009, 120013, 120017, 120021, 120025, - 120029, 120033, 120037, 120041, 120045, 120049, 120053, 120057, 120061, - 120065, 120069, 120074, 120079, 120084, 120089, 120094, 120099, 120104, - 120109, 120114, 0, 0, 0, 120121, 120126, 120131, 120135, 120140, 120145, - 120150, 120155, 120160, 120165, 120170, 120175, 120180, 120185, 120189, - 120193, 120198, 120203, 120207, 120212, 120217, 120222, 120227, 120232, - 120237, 120242, 120246, 120250, 120254, 120259, 120263, 120267, 0, 0, - 120271, 120277, 120284, 120291, 120298, 120305, 120312, 120319, 120326, - 120333, 120340, 120347, 120353, 120359, 120366, 120373, 120379, 120386, - 120393, 120400, 120407, 120414, 0, 120421, 120427, 120433, 120439, - 120446, 120452, 120458, 120464, 120470, 120475, 120480, 120485, 120490, - 120495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119698, 119702, + 119707, 119711, 119716, 119720, 119725, 119730, 119736, 0, 119741, + 119745, 119750, 119754, 119759, 119763, 119768, 119773, 119778, 119783, + 119788, 119793, 119798, 119803, 119808, 119813, 119818, 119823, 119828, + 119833, 119838, 119843, 119848, 119853, 119857, 119861, 119866, 119871, + 119876, 119880, 119884, 119888, 119892, 119897, 119902, 119907, 119911, + 119915, 119921, 119926, 119932, 119937, 119943, 119949, 119956, 0, + 119962, 119967, 119973, 119978, 119984, 119989, 119994, 119999, 120004, + 120009, 120013, 120018, 120024, 120030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 120036, 120041, 120045, 120049, 120053, 120057, 120061, 120065, 120069, + 120073, 120077, 120081, 120085, 120089, 120093, 120097, 120101, 120105, + 120109, 120113, 120118, 120123, 120128, 120133, 120138, 120143, 120148, + 120153, 120158, 0, 0, 0, 120165, 120170, 120175, 120179, 120184, 120189, + 120194, 120199, 120204, 120209, 120214, 120219, 120224, 120229, 120233, + 120237, 120242, 120247, 120251, 120256, 120261, 120266, 120271, 120276, + 120281, 120286, 120290, 120294, 120298, 120303, 120307, 120311, 0, 0, + 120315, 120321, 120328, 120335, 120342, 120349, 120356, 120363, 120370, + 120377, 120384, 120391, 120397, 120403, 120410, 120417, 120423, 120430, + 120437, 120444, 120451, 120458, 0, 120465, 120471, 120477, 120483, + 120490, 120496, 120502, 120508, 120514, 120519, 120524, 120529, 120534, + 120539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 120500, 120505, 120511, 120516, 120522, 120527, 120533, 0, - 120538, 120544, 0, 120549, 120555, 120560, 120566, 120572, 120578, - 120584, 120590, 120596, 120602, 120608, 120614, 120620, 120626, 120632, - 120638, 120644, 120650, 120656, 120662, 120668, 120673, 120678, 120684, - 120690, 120696, 120701, 120706, 120711, 120716, 120722, 120728, 120734, - 120739, 120744, 120750, 120756, 120762, 120768, 120775, 120781, 120788, - 120794, 120801, 0, 0, 0, 120808, 0, 120814, 120821, 0, 120827, 120834, - 120840, 120846, 120852, 120858, 120864, 120869, 120874, 0, 0, 0, 0, 0, 0, - 0, 0, 120879, 120885, 120890, 120895, 120900, 120905, 120910, 120915, - 120920, 120925, 0, 0, 0, 0, 0, 0, 120930, 120935, 120941, 120946, 120952, - 120957, 0, 120963, 120969, 0, 120975, 120981, 120987, 120992, 120998, - 121004, 121010, 121015, 121020, 121026, 121032, 121038, 121043, 121049, - 121055, 121061, 121067, 121072, 121078, 121084, 121090, 121096, 121102, - 121108, 121114, 121120, 121126, 121132, 121137, 121143, 121148, 121153, - 121158, 121165, 121171, 121178, 121184, 0, 121191, 121198, 0, 121205, - 121212, 121219, 121225, 121231, 121236, 0, 0, 0, 0, 0, 0, 0, 121241, - 121247, 121252, 121257, 121262, 121267, 121272, 121277, 121282, 121287, + 0, 0, 0, 120544, 120549, 120555, 120560, 120566, 120571, 120577, 0, + 120582, 120588, 0, 120593, 120599, 120604, 120610, 120616, 120622, + 120628, 120634, 120640, 120646, 120652, 120658, 120664, 120670, 120676, + 120682, 120688, 120694, 120700, 120706, 120712, 120717, 120722, 120728, + 120734, 120740, 120745, 120750, 120755, 120760, 120766, 120772, 120778, + 120783, 120788, 120794, 120800, 120806, 120812, 120819, 120825, 120832, + 120838, 120845, 0, 0, 0, 120852, 0, 120858, 120865, 0, 120871, 120878, + 120884, 120890, 120896, 120902, 120908, 120913, 120918, 0, 0, 0, 0, 0, 0, + 0, 0, 120923, 120929, 120934, 120939, 120944, 120949, 120954, 120959, + 120964, 120969, 0, 0, 0, 0, 0, 0, 120974, 120979, 120985, 120990, 120996, + 121001, 0, 121007, 121013, 0, 121019, 121025, 121031, 121036, 121042, + 121048, 121054, 121059, 121064, 121070, 121076, 121082, 121087, 121093, + 121099, 121105, 121111, 121116, 121122, 121128, 121134, 121140, 121146, + 121152, 121158, 121164, 121170, 121176, 121181, 121187, 121192, 121197, + 121202, 121209, 121215, 121222, 121228, 0, 121235, 121242, 0, 121249, + 121256, 121263, 121269, 121275, 121280, 0, 0, 0, 0, 0, 0, 0, 121285, + 121291, 121296, 121301, 121306, 121311, 121316, 121321, 121326, 121331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -23636,1725 +23642,1725 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121292, 121296, 121301, 121306, - 121310, 121315, 121319, 121324, 121329, 121333, 121338, 121343, 121348, - 121352, 121356, 121360, 121365, 121369, 121373, 121377, 121382, 121387, - 121392, 121397, 121401, 0, 0, 0, 0, 0, 0, 0, 121408, 121413, 121418, - 121423, 121428, 121432, 121437, 121441, 121446, 121450, 121455, 121460, - 121466, 121471, 121477, 121481, 121486, 0, 121490, 121494, 121499, - 121504, 121509, 121514, 121519, 121524, 121529, 121534, 121539, 121544, - 121549, 121554, 121559, 121564, 121569, 121574, 121579, 121584, 121588, - 121592, 121597, 121602, 121607, 121611, 121615, 121619, 121623, 121628, - 121633, 121638, 121642, 121646, 121651, 121657, 121665, 121670, 121676, - 121681, 121687, 0, 0, 0, 121693, 121698, 121704, 121710, 121715, 121719, - 121723, 121728, 121736, 121746, 121752, 121760, 121766, 121773, 121781, - 121787, 121795, 121801, 121809, 121814, 121818, 121822, 121826, 121830, - 121834, 121838, 121842, 121846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121336, 121340, 121345, 121350, + 121354, 121359, 121363, 121368, 121373, 121377, 121382, 121387, 121392, + 121396, 121400, 121404, 121409, 121413, 121417, 121421, 121426, 121431, + 121436, 121441, 121445, 0, 0, 0, 0, 0, 0, 0, 121452, 121457, 121462, + 121467, 121472, 121476, 121481, 121485, 121490, 121494, 121499, 121504, + 121510, 121515, 121521, 121525, 121530, 0, 121534, 121538, 121543, + 121548, 121553, 121558, 121563, 121568, 121573, 121578, 121583, 121588, + 121593, 121598, 121603, 121608, 121613, 121618, 121623, 121628, 121632, + 121636, 121641, 121646, 121651, 121655, 121659, 121663, 121667, 121672, + 121677, 121682, 121686, 121690, 121695, 121701, 121709, 121714, 121720, + 121725, 121731, 0, 0, 0, 121737, 121742, 121748, 121754, 121759, 121763, + 121767, 121772, 121780, 121790, 121796, 121804, 121810, 121817, 121825, + 121831, 121839, 121845, 121853, 121858, 121862, 121866, 121870, 121874, + 121878, 121882, 121886, 121890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 121850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121855, 121861, - 121867, 121873, 121879, 121885, 121891, 121897, 121903, 121909, 121915, - 121921, 121927, 121933, 121939, 121945, 121951, 121957, 121963, 121969, - 121975, 121984, 121988, 121992, 121996, 122000, 122004, 122008, 122012, - 122016, 122020, 122024, 122028, 122032, 122036, 122040, 122044, 122050, - 122056, 122060, 122066, 122072, 122077, 122081, 122086, 122090, 122094, - 122100, 122106, 122110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122114, - 122122, 122125, 122130, 122136, 122144, 122149, 122155, 122163, 122169, - 122175, 122179, 122183, 122190, 122199, 122206, 122215, 122221, 122230, - 122237, 122244, 122251, 122261, 122267, 122271, 122278, 122287, 122297, - 122304, 122311, 122315, 122319, 122326, 122336, 122340, 122347, 122354, - 122361, 122367, 122374, 122381, 122388, 122395, 122399, 122403, 122407, - 122414, 122418, 122425, 122432, 122446, 122455, 122459, 122463, 122467, - 122474, 122478, 122482, 122486, 122494, 122502, 122521, 122531, 122551, - 122555, 122559, 122563, 122567, 122571, 122575, 122579, 122586, 122590, - 122593, 122597, 122601, 122607, 122614, 122623, 122627, 122636, 122645, - 122653, 122657, 122664, 122668, 122672, 122676, 122680, 122691, 122700, - 122709, 122718, 122727, 122739, 122748, 122757, 122766, 122774, 122783, - 122795, 122804, 122812, 122821, 122833, 122842, 122851, 122863, 122872, - 122881, 122893, 122902, 122906, 122910, 122914, 122918, 122922, 122926, - 122930, 122937, 122941, 122945, 122956, 122960, 122964, 122971, 122977, - 122983, 122987, 122994, 122998, 123002, 123006, 123010, 123014, 123018, - 123024, 123032, 123036, 123040, 123043, 123050, 123062, 123066, 123078, - 123085, 123092, 123099, 123106, 123112, 123116, 123120, 123124, 123128, - 123135, 123144, 123151, 123159, 123167, 123173, 123177, 123181, 123185, - 123189, 123195, 123204, 123216, 123223, 123230, 123239, 123250, 123256, - 123265, 123274, 123281, 123290, 123297, 123303, 123313, 123320, 123327, - 123334, 123341, 123345, 123351, 123355, 123366, 123374, 123383, 123395, - 123402, 123409, 123419, 123426, 123435, 123442, 123451, 123458, 123465, - 123475, 123482, 123489, 123498, 123505, 123517, 123526, 123533, 123540, - 123547, 123556, 123566, 123579, 123586, 123595, 123605, 123612, 123621, - 123634, 123641, 123648, 123655, 123665, 123675, 123681, 123691, 123698, - 123705, 123715, 123721, 123728, 123735, 123742, 123752, 123759, 123766, - 123773, 123779, 123786, 123796, 123803, 123807, 123815, 123819, 123831, - 123835, 123849, 123853, 123857, 123861, 123865, 123871, 123878, 123886, - 123890, 123894, 123898, 123902, 123909, 123913, 123919, 123925, 123933, - 123937, 123944, 123952, 123956, 123960, 123966, 123970, 123979, 123988, - 123995, 124005, 124011, 124015, 124019, 124027, 124034, 124041, 124047, - 124051, 124059, 124063, 124070, 124082, 124089, 124099, 124105, 124109, - 124118, 124125, 124134, 124138, 124142, 124149, 124153, 124157, 124161, - 124165, 124168, 124174, 124180, 124184, 124188, 124195, 124202, 124209, - 124216, 124223, 124230, 124237, 124244, 124250, 124254, 124258, 124265, - 124272, 124279, 124286, 124293, 124297, 124300, 124305, 124309, 124313, - 124322, 124331, 124335, 124339, 124345, 124351, 124368, 124374, 124378, - 124387, 124391, 124395, 124402, 124410, 124418, 124424, 124428, 124432, - 124436, 124440, 124443, 124449, 124456, 124466, 124473, 124480, 124487, - 124493, 124500, 124507, 124514, 124521, 124528, 124537, 124544, 124556, - 124563, 124570, 124580, 124591, 124598, 124605, 124612, 124619, 124626, - 124633, 124640, 124647, 124654, 124661, 124671, 124681, 124691, 124698, - 124708, 124715, 124722, 124729, 124736, 124742, 124749, 124756, 124763, - 124770, 124777, 124784, 124791, 124798, 124804, 124811, 124818, 124827, - 124834, 124841, 124845, 124853, 124857, 124861, 124865, 124869, 124873, - 124880, 124884, 124893, 124897, 124904, 124912, 124916, 124920, 124924, - 124937, 124953, 124957, 124961, 124968, 124974, 124981, 124985, 124989, - 124993, 124997, 125001, 125008, 125012, 125030, 125034, 125038, 125045, - 125049, 125053, 125059, 125063, 125067, 125075, 125079, 125083, 125086, - 125090, 125096, 125107, 125116, 125125, 125132, 125139, 125150, 125157, - 125164, 125171, 125178, 125185, 125192, 125199, 125209, 125215, 125222, - 125232, 125241, 125248, 125257, 125267, 125274, 125281, 125288, 125295, - 125307, 125314, 125321, 125328, 125335, 125342, 125352, 125359, 125366, - 125376, 125389, 125401, 125408, 125418, 125425, 125432, 125439, 125453, - 125459, 125467, 125477, 125487, 125494, 125501, 125507, 125511, 125518, - 125528, 125534, 125547, 125551, 125555, 125562, 125566, 125573, 125583, - 125587, 125591, 125595, 125599, 125603, 125610, 125614, 125621, 125628, - 125635, 125644, 125653, 125663, 125670, 125677, 125684, 125694, 125701, - 125711, 125718, 125728, 125735, 125742, 125752, 125762, 125769, 125775, - 125783, 125791, 125797, 125803, 125807, 125811, 125818, 125826, 125832, - 125836, 125840, 125844, 125851, 125863, 125866, 125873, 125879, 125883, - 125887, 125891, 125895, 125899, 125903, 125907, 125911, 125915, 125919, - 125926, 125930, 125936, 125940, 125944, 125948, 125954, 125961, 125968, - 125975, 125986, 125994, 125998, 126004, 126013, 126020, 126026, 126029, - 126033, 126037, 126043, 126052, 126060, 126064, 126070, 126074, 126078, - 126082, 126088, 126095, 126101, 126105, 126111, 126115, 126119, 126128, - 126140, 126144, 126151, 126158, 126168, 126175, 126187, 126194, 126201, - 126208, 126219, 126229, 126242, 126252, 126259, 126263, 126267, 126271, - 126275, 126284, 126293, 126302, 126319, 126328, 126334, 126341, 126349, - 126362, 126366, 126375, 126384, 126393, 126402, 126413, 126422, 126430, - 126439, 126448, 126457, 126466, 126476, 126479, 126483, 126487, 126491, - 126495, 126499, 126505, 126512, 126519, 126526, 126532, 126538, 126545, - 126551, 126558, 126566, 126570, 126577, 126584, 126591, 126599, 126602, - 126606, 126610, 126614, 126617, 126623, 126627, 126633, 126640, 126647, - 126653, 126660, 126667, 126674, 126681, 126688, 126695, 126702, 126709, - 126716, 126723, 126730, 126737, 126744, 126751, 126757, 126761, 126770, - 126774, 126778, 126782, 126786, 126792, 126799, 126806, 126813, 126820, - 126827, 126833, 126841, 126845, 126849, 126853, 126857, 126863, 126880, - 126897, 126901, 126905, 126909, 126913, 126917, 126921, 126927, 126934, - 126938, 126944, 126951, 126958, 126965, 126972, 126979, 126988, 126995, - 127002, 127009, 127016, 127020, 127024, 127030, 127042, 127046, 127050, - 127059, 127063, 127067, 127071, 127077, 127081, 127085, 127094, 127098, - 127102, 127106, 127113, 127117, 127121, 127125, 127129, 127133, 127137, - 127141, 127145, 127151, 127158, 127165, 127171, 127175, 127192, 127198, - 127202, 127209, 127216, 127223, 127230, 127237, 127244, 127248, 127252, - 127256, 127262, 127266, 127272, 127276, 127280, 127287, 127294, 127311, - 127315, 127319, 127323, 127327, 127331, 127343, 127346, 127351, 127356, - 127371, 127381, 127393, 127397, 127401, 127405, 127411, 127418, 127425, - 127435, 127447, 127453, 127459, 127468, 127472, 127476, 127483, 127493, - 127500, 127506, 127510, 127514, 127521, 127527, 127531, 127537, 127541, - 127549, 127555, 127559, 127567, 127575, 127582, 127588, 127595, 127602, - 127612, 127622, 127626, 127630, 127634, 127638, 127644, 127651, 127657, - 127664, 127671, 127678, 127687, 127694, 127701, 127707, 127714, 127721, - 127728, 127735, 127742, 127749, 127755, 127762, 127769, 127776, 127785, - 127792, 127799, 127803, 127809, 127813, 127819, 127826, 127833, 127840, - 127844, 127848, 127852, 127856, 127860, 127867, 127871, 127875, 127881, - 127889, 127893, 127897, 127901, 127905, 127912, 127916, 127920, 127928, - 127932, 127936, 127940, 127944, 127950, 127954, 127958, 127964, 127971, - 127977, 127984, 127996, 128000, 128007, 128014, 128021, 128028, 128040, - 128047, 128051, 128055, 128059, 128066, 128073, 128080, 128087, 128097, - 128104, 128110, 128117, 128124, 128131, 128138, 128147, 128157, 128164, - 128168, 128175, 128179, 128183, 128187, 128194, 128201, 128211, 128217, - 128221, 128230, 128234, 128241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121899, 121905, + 121911, 121917, 121923, 121929, 121935, 121941, 121947, 121953, 121959, + 121965, 121971, 121977, 121983, 121989, 121995, 122001, 122007, 122013, + 122019, 122028, 122032, 122036, 122040, 122044, 122048, 122052, 122056, + 122060, 122064, 122068, 122072, 122076, 122080, 122084, 122088, 122094, + 122100, 122104, 122110, 122116, 122121, 122125, 122130, 122134, 122138, + 122144, 122150, 122154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122158, + 122166, 122169, 122174, 122180, 122188, 122193, 122199, 122207, 122213, + 122219, 122223, 122227, 122234, 122243, 122250, 122259, 122265, 122274, + 122281, 122288, 122295, 122305, 122311, 122315, 122322, 122331, 122341, + 122348, 122355, 122359, 122363, 122370, 122380, 122384, 122391, 122398, + 122405, 122411, 122418, 122425, 122432, 122439, 122443, 122447, 122451, + 122458, 122462, 122469, 122476, 122490, 122499, 122503, 122507, 122511, + 122518, 122522, 122526, 122530, 122538, 122546, 122565, 122575, 122595, + 122599, 122603, 122607, 122611, 122615, 122619, 122623, 122630, 122634, + 122637, 122641, 122645, 122651, 122658, 122667, 122671, 122680, 122689, + 122697, 122701, 122708, 122712, 122716, 122720, 122724, 122735, 122744, + 122753, 122762, 122771, 122783, 122792, 122801, 122810, 122818, 122827, + 122839, 122848, 122856, 122865, 122877, 122886, 122895, 122907, 122916, + 122925, 122937, 122946, 122950, 122954, 122958, 122962, 122966, 122970, + 122974, 122981, 122985, 122989, 123000, 123004, 123008, 123015, 123021, + 123027, 123031, 123038, 123042, 123046, 123050, 123054, 123058, 123062, + 123068, 123076, 123080, 123084, 123087, 123094, 123106, 123110, 123122, + 123129, 123136, 123143, 123150, 123156, 123160, 123164, 123168, 123172, + 123179, 123188, 123195, 123203, 123211, 123217, 123221, 123225, 123229, + 123233, 123239, 123248, 123260, 123267, 123274, 123283, 123294, 123300, + 123309, 123318, 123325, 123334, 123341, 123347, 123357, 123364, 123371, + 123378, 123385, 123389, 123395, 123399, 123410, 123418, 123427, 123439, + 123446, 123453, 123463, 123470, 123479, 123486, 123495, 123502, 123509, + 123519, 123526, 123533, 123542, 123549, 123561, 123570, 123577, 123584, + 123591, 123600, 123610, 123623, 123630, 123639, 123649, 123656, 123665, + 123678, 123685, 123692, 123699, 123709, 123719, 123725, 123735, 123742, + 123749, 123759, 123765, 123772, 123779, 123786, 123796, 123803, 123810, + 123817, 123823, 123830, 123840, 123847, 123851, 123859, 123863, 123875, + 123879, 123893, 123897, 123901, 123905, 123909, 123915, 123922, 123930, + 123934, 123938, 123942, 123946, 123953, 123957, 123963, 123969, 123977, + 123981, 123988, 123996, 124000, 124004, 124010, 124014, 124023, 124032, + 124039, 124049, 124055, 124059, 124063, 124071, 124078, 124085, 124091, + 124095, 124103, 124107, 124114, 124126, 124133, 124143, 124149, 124153, + 124162, 124169, 124178, 124182, 124186, 124193, 124197, 124201, 124205, + 124209, 124212, 124218, 124224, 124228, 124232, 124239, 124246, 124253, + 124260, 124267, 124274, 124281, 124288, 124294, 124298, 124302, 124309, + 124316, 124323, 124330, 124337, 124341, 124344, 124349, 124353, 124357, + 124366, 124375, 124379, 124383, 124389, 124395, 124412, 124418, 124422, + 124431, 124435, 124439, 124446, 124454, 124462, 124468, 124472, 124476, + 124480, 124484, 124487, 124493, 124500, 124510, 124517, 124524, 124531, + 124537, 124544, 124551, 124558, 124565, 124572, 124581, 124588, 124600, + 124607, 124614, 124624, 124635, 124642, 124649, 124656, 124663, 124670, + 124677, 124684, 124691, 124698, 124705, 124715, 124725, 124735, 124742, + 124752, 124759, 124766, 124773, 124780, 124786, 124793, 124800, 124807, + 124814, 124821, 124828, 124835, 124842, 124848, 124855, 124862, 124871, + 124878, 124885, 124889, 124897, 124901, 124905, 124909, 124913, 124917, + 124924, 124928, 124937, 124941, 124948, 124956, 124960, 124964, 124968, + 124981, 124997, 125001, 125005, 125012, 125018, 125025, 125029, 125033, + 125037, 125041, 125045, 125052, 125056, 125074, 125078, 125082, 125089, + 125093, 125097, 125103, 125107, 125111, 125119, 125123, 125127, 125130, + 125134, 125140, 125151, 125160, 125169, 125176, 125183, 125194, 125201, + 125208, 125215, 125222, 125229, 125236, 125243, 125253, 125259, 125266, + 125276, 125285, 125292, 125301, 125311, 125318, 125325, 125332, 125339, + 125351, 125358, 125365, 125372, 125379, 125386, 125396, 125403, 125410, + 125420, 125433, 125445, 125452, 125462, 125469, 125476, 125483, 125497, + 125503, 125511, 125521, 125531, 125538, 125545, 125551, 125555, 125562, + 125572, 125578, 125591, 125595, 125599, 125606, 125610, 125617, 125627, + 125631, 125635, 125639, 125643, 125647, 125654, 125658, 125665, 125672, + 125679, 125688, 125697, 125707, 125714, 125721, 125728, 125738, 125745, + 125755, 125762, 125772, 125779, 125786, 125796, 125806, 125813, 125819, + 125827, 125835, 125841, 125847, 125851, 125855, 125862, 125870, 125876, + 125880, 125884, 125888, 125895, 125907, 125910, 125917, 125923, 125927, + 125931, 125935, 125939, 125943, 125947, 125951, 125955, 125959, 125963, + 125970, 125974, 125980, 125984, 125988, 125992, 125998, 126005, 126012, + 126019, 126030, 126038, 126042, 126048, 126057, 126064, 126070, 126073, + 126077, 126081, 126087, 126096, 126104, 126108, 126114, 126118, 126122, + 126126, 126132, 126139, 126145, 126149, 126155, 126159, 126163, 126172, + 126184, 126188, 126195, 126202, 126212, 126219, 126231, 126238, 126245, + 126252, 126263, 126273, 126286, 126296, 126303, 126307, 126311, 126315, + 126319, 126328, 126337, 126346, 126363, 126372, 126378, 126385, 126393, + 126406, 126410, 126419, 126428, 126437, 126446, 126457, 126466, 126474, + 126483, 126492, 126501, 126510, 126520, 126523, 126527, 126531, 126535, + 126539, 126543, 126549, 126556, 126563, 126570, 126576, 126582, 126589, + 126595, 126602, 126610, 126614, 126621, 126628, 126635, 126643, 126646, + 126650, 126654, 126658, 126661, 126667, 126671, 126677, 126684, 126691, + 126697, 126704, 126711, 126718, 126725, 126732, 126739, 126746, 126753, + 126760, 126767, 126774, 126781, 126788, 126795, 126801, 126805, 126814, + 126818, 126822, 126826, 126830, 126836, 126843, 126850, 126857, 126864, + 126871, 126877, 126885, 126889, 126893, 126897, 126901, 126907, 126924, + 126941, 126945, 126949, 126953, 126957, 126961, 126965, 126971, 126978, + 126982, 126988, 126995, 127002, 127009, 127016, 127023, 127032, 127039, + 127046, 127053, 127060, 127064, 127068, 127074, 127086, 127090, 127094, + 127103, 127107, 127111, 127115, 127121, 127125, 127129, 127138, 127142, + 127146, 127150, 127157, 127161, 127165, 127169, 127173, 127177, 127181, + 127185, 127189, 127195, 127202, 127209, 127215, 127219, 127236, 127242, + 127246, 127253, 127260, 127267, 127274, 127281, 127288, 127292, 127296, + 127300, 127306, 127310, 127316, 127320, 127324, 127331, 127338, 127355, + 127359, 127363, 127367, 127371, 127375, 127387, 127390, 127395, 127400, + 127415, 127425, 127437, 127441, 127445, 127449, 127455, 127462, 127469, + 127479, 127491, 127497, 127503, 127512, 127516, 127520, 127527, 127537, + 127544, 127550, 127554, 127558, 127565, 127571, 127575, 127581, 127585, + 127593, 127599, 127603, 127611, 127619, 127626, 127632, 127639, 127646, + 127656, 127666, 127670, 127674, 127678, 127682, 127688, 127695, 127701, + 127708, 127715, 127722, 127731, 127738, 127745, 127751, 127758, 127765, + 127772, 127779, 127786, 127793, 127799, 127806, 127813, 127820, 127829, + 127836, 127843, 127847, 127853, 127857, 127863, 127870, 127877, 127884, + 127888, 127892, 127896, 127900, 127904, 127911, 127915, 127919, 127925, + 127933, 127937, 127941, 127945, 127949, 127956, 127960, 127964, 127972, + 127976, 127980, 127984, 127988, 127994, 127998, 128002, 128008, 128015, + 128021, 128028, 128040, 128044, 128051, 128058, 128065, 128072, 128084, + 128091, 128095, 128099, 128103, 128110, 128117, 128124, 128131, 128141, + 128148, 128154, 128161, 128168, 128175, 128182, 128191, 128201, 128208, + 128212, 128219, 128223, 128227, 128231, 128238, 128245, 128255, 128261, + 128265, 128274, 128278, 128285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128245, 128251, 128257, - 128264, 128271, 128278, 128285, 128292, 128299, 128305, 128312, 128319, - 128326, 128333, 128340, 128347, 128353, 128359, 128365, 128371, 128377, - 128383, 128389, 128395, 128401, 128408, 128415, 128422, 128429, 128436, - 128443, 128449, 128455, 128461, 128468, 128475, 128481, 128487, 128496, - 128503, 128510, 128517, 128524, 128531, 128538, 128544, 128550, 128556, - 128565, 128572, 128579, 128590, 128601, 128607, 128613, 128619, 128628, - 128635, 128642, 128652, 128662, 128673, 128684, 128696, 128709, 128720, - 128731, 128743, 128756, 128767, 128778, 128789, 128800, 128811, 128823, - 128831, 128839, 128848, 128857, 128866, 128872, 128878, 128884, 128891, - 128901, 128908, 128918, 128923, 128928, 128934, 128940, 128948, 128956, - 128965, 128976, 128987, 128995, 129003, 129012, 129021, 129029, 129036, - 129044, 129052, 129059, 129066, 129075, 129084, 129093, 129102, 129111, - 0, 129120, 129131, 129138, 129146, 129154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 129162, 129171, 129178, 129185, 129194, 129201, 129208, 129215, - 129225, 129232, 129239, 129246, 129254, 129261, 129268, 129275, 129286, - 129293, 129300, 129307, 129314, 129321, 129330, 129337, 129343, 129350, - 129359, 129366, 129373, 129380, 129390, 129397, 129404, 129414, 129424, - 129431, 129438, 129445, 129452, 129459, 129466, 129475, 129482, 129489, - 129495, 129503, 129512, 129521, 129532, 129540, 129549, 129558, 129567, - 129576, 129583, 129590, 129599, 129611, 129621, 129628, 129635, 129645, - 129655, 129664, 129674, 129681, 129691, 129698, 129705, 129712, 129722, - 129732, 129739, 129746, 129756, 129762, 129773, 129782, 129792, 129800, - 129813, 129820, 129826, 129834, 129841, 129851, 129855, 129859, 129863, - 129867, 129871, 129875, 129879, 129888, 129892, 129899, 129903, 129907, - 129911, 129915, 129919, 129923, 129927, 129931, 129935, 129939, 129943, - 129947, 129951, 129955, 129959, 129963, 129967, 129971, 129975, 129982, - 129989, 129999, 130012, 130022, 130026, 130030, 130034, 130038, 130042, - 130046, 130050, 130054, 130058, 130062, 130066, 130073, 130080, 130091, - 130098, 130104, 130111, 130118, 130125, 130132, 130139, 130143, 130147, - 130154, 130161, 130168, 130177, 130184, 130197, 130207, 130214, 130221, - 130225, 130229, 130238, 130245, 130252, 130259, 130272, 130279, 130286, - 130296, 130306, 130315, 130322, 130329, 130336, 130343, 130350, 130357, - 130367, 130373, 130381, 130388, 130396, 130403, 130414, 130421, 130427, - 130434, 130441, 130448, 130455, 130465, 130475, 130482, 130489, 130498, - 130506, 130512, 130519, 130526, 130533, 130540, 130544, 130554, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128289, 128295, 128301, + 128308, 128315, 128322, 128329, 128336, 128343, 128349, 128356, 128363, + 128370, 128377, 128384, 128391, 128397, 128403, 128409, 128415, 128421, + 128427, 128433, 128439, 128445, 128452, 128459, 128466, 128473, 128480, + 128487, 128493, 128499, 128505, 128512, 128519, 128525, 128531, 128540, + 128547, 128554, 128561, 128568, 128575, 128582, 128588, 128594, 128600, + 128609, 128616, 128623, 128634, 128645, 128651, 128657, 128663, 128672, + 128679, 128686, 128696, 128706, 128717, 128728, 128740, 128753, 128764, + 128775, 128787, 128800, 128811, 128822, 128833, 128844, 128855, 128867, + 128875, 128883, 128892, 128901, 128910, 128916, 128922, 128928, 128935, + 128945, 128952, 128962, 128967, 128972, 128978, 128984, 128992, 129000, + 129009, 129020, 129031, 129039, 129047, 129056, 129065, 129073, 129080, + 129088, 129096, 129103, 129110, 129119, 129128, 129137, 129146, 129155, + 0, 129164, 129175, 129182, 129190, 129198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 129206, 129215, 129222, 129229, 129238, 129245, 129252, 129259, + 129269, 129276, 129283, 129290, 129298, 129305, 129312, 129319, 129330, + 129337, 129344, 129351, 129358, 129365, 129374, 129381, 129387, 129394, + 129403, 129410, 129417, 129424, 129434, 129441, 129448, 129458, 129468, + 129475, 129482, 129489, 129496, 129503, 129510, 129519, 129526, 129533, + 129539, 129547, 129556, 129565, 129576, 129584, 129593, 129602, 129611, + 129620, 129627, 129634, 129643, 129655, 129665, 129672, 129679, 129689, + 129699, 129708, 129718, 129725, 129735, 129742, 129749, 129756, 129766, + 129776, 129783, 129790, 129800, 129806, 129817, 129826, 129836, 129844, + 129857, 129864, 129870, 129878, 129885, 129895, 129899, 129903, 129907, + 129911, 129915, 129919, 129923, 129932, 129936, 129943, 129947, 129951, + 129955, 129959, 129963, 129967, 129971, 129975, 129979, 129983, 129987, + 129991, 129995, 129999, 130003, 130007, 130011, 130015, 130019, 130026, + 130033, 130043, 130056, 130066, 130070, 130074, 130078, 130082, 130086, + 130090, 130094, 130098, 130102, 130106, 130110, 130117, 130124, 130135, + 130142, 130148, 130155, 130162, 130169, 130176, 130183, 130187, 130191, + 130198, 130205, 130212, 130221, 130228, 130241, 130251, 130258, 130265, + 130269, 130273, 130282, 130289, 130296, 130303, 130316, 130323, 130330, + 130340, 130350, 130359, 130366, 130373, 130380, 130387, 130394, 130401, + 130411, 130417, 130425, 130432, 130440, 130447, 130458, 130465, 130471, + 130478, 130485, 130492, 130499, 130509, 130519, 130526, 130533, 130542, + 130550, 130556, 130563, 130570, 130577, 130584, 130588, 130598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 130564, 130569, 130574, 130579, 130584, 130589, 130594, 130599, - 130604, 130609, 130614, 130619, 130624, 130629, 130634, 130639, 130644, - 130649, 130654, 130659, 130664, 130669, 130674, 130679, 130684, 130689, - 130694, 130699, 130704, 130709, 130714, 130719, 130724, 130729, 130734, - 130739, 130744, 130749, 130754, 130759, 130764, 130769, 130774, 130779, - 130784, 130789, 130794, 130799, 130804, 130809, 130814, 130819, 130824, - 130829, 130834, 130839, 130844, 130849, 130854, 130859, 130864, 130869, - 130874, 130879, 130884, 130889, 130894, 130899, 130904, 130909, 130914, - 130919, 130924, 130929, 130934, 130939, 130944, 130949, 130954, 130959, - 130964, 130969, 130974, 130979, 130984, 130989, 130994, 130999, 131004, - 131009, 131014, 131019, 131024, 131029, 131034, 131039, 131044, 131049, - 131054, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131059, 131063, 131067, - 131071, 131075, 131079, 131083, 131087, 131091, 131095, 131099, 131103, - 131107, 131111, 131115, 131119, 131123, 131127, 131131, 131135, 131139, - 131143, 131147, 131151, 131155, 131159, 131163, 131167, 131171, 131175, - 131179, 131183, 131187, 131191, 131195, 131199, 131203, 131207, 131211, - 131215, 131219, 131223, 131227, 131231, 131235, 131239, 131243, 131247, - 131251, 131255, 131259, 131263, 131267, 131271, 131275, 131279, 131283, - 131287, 131291, 131295, 131299, 131303, 131307, 131311, 131315, 131319, - 131323, 131327, 131331, 131335, 131339, 131343, 131347, 131351, 131355, - 131359, 131363, 131367, 131371, 131375, 131379, 131383, 131387, 131391, - 131395, 131399, 131403, 131407, 131411, 131415, 131419, 131423, 131427, - 131431, 131435, 131439, 131443, 131447, 131451, 131455, 131459, 131463, - 131467, 131471, 131475, 131479, 131483, 131487, 131491, 131495, 131499, - 131503, 131507, 131511, 131515, 131519, 131523, 131527, 131531, 131535, - 131539, 131543, 131547, 131551, 131555, 131559, 131563, 131567, 131571, - 131575, 131579, 131583, 131587, 131591, 131595, 131599, 131603, 131607, - 131611, 131615, 131619, 131623, 131627, 131631, 131635, 131639, 131643, - 131647, 131651, 131655, 131659, 131663, 131667, 131671, 131675, 131679, - 131683, 131687, 131691, 131695, 131699, 131703, 131707, 131711, 131715, - 131719, 131723, 131727, 131731, 131735, 131739, 131743, 131747, 131751, - 131755, 131759, 131763, 131767, 131771, 131775, 131779, 131783, 131787, - 131791, 131795, 131799, 131803, 131807, 131811, 131815, 131819, 131823, - 131827, 131831, 131835, 131839, 131843, 131847, 131851, 131855, 131859, - 131863, 131867, 131871, 131875, 131879, 131883, 131887, 131891, 131895, - 131899, 131903, 131907, 131911, 131915, 131919, 131923, 131927, 131931, - 131935, 131939, 131943, 131947, 131951, 131955, 131959, 131963, 131967, - 131971, 131975, 131979, 131983, 131987, 131991, 131995, 131999, 132003, - 132007, 132011, 132015, 132019, 132023, 132027, 132031, 132035, 132039, - 132043, 132047, 132051, 132055, 132059, 132063, 132067, 132071, 132075, - 132079, 132083, 132087, 132091, 132095, 132099, 132103, 132107, 132111, - 132115, 132119, 132123, 132127, 132131, 132135, 132139, 132143, 132147, - 132151, 132155, 132159, 132163, 132167, 132171, 132175, 132179, 132183, - 132187, 132191, 132195, 132199, 132203, 132207, 132211, 132215, 132219, - 132223, 132227, 132231, 132235, 132239, 132243, 132247, 132251, 132255, - 132259, 132263, 132267, 132271, 132275, 132279, 132283, 132287, 132291, - 132295, 132299, 132303, 132307, 132311, 132315, 132319, 132323, 132327, - 132331, 132335, 132339, 132343, 132347, 132351, 132355, 132359, 132363, - 132367, 132371, 132375, 132379, 132383, 132387, 132391, 132395, 132399, - 132403, 132407, 132411, 132415, 132419, 132423, 132427, 132431, 132435, - 132439, 132443, 132447, 132451, 132455, 132459, 132463, 132467, 132471, - 132475, 132479, 132483, 132487, 132491, 132495, 132499, 132503, 132507, - 132511, 132515, 132519, 132523, 132527, 132531, 132535, 132539, 132543, - 132547, 132551, 132555, 132559, 132563, 132567, 132571, 132575, 132579, - 132583, 132587, 132591, 132595, 132599, 132603, 132607, 132611, 132615, - 132619, 132623, 132627, 132631, 132635, 132639, 132643, 132647, 132651, - 132655, 132659, 132663, 132667, 132671, 132675, 132679, 132683, 132687, - 132691, 132695, 132699, 132703, 132707, 132711, 132715, 132719, 132723, - 132727, 132731, 132735, 132739, 132743, 132747, 132751, 132755, 132759, - 132763, 132767, 132771, 132775, 132779, 132783, 132787, 132791, 132795, - 132799, 132803, 132807, 132811, 132815, 132819, 132823, 132827, 132831, - 132835, 132839, 132843, 132847, 132851, 132855, 132859, 132863, 132867, - 132871, 132875, 132879, 132883, 132887, 132891, 132895, 132899, 132903, - 132907, 132911, 132915, 132919, 132923, 132927, 132931, 132935, 132939, - 132943, 132947, 132951, 132955, 132959, 132963, 132967, 132971, 132975, - 132979, 132983, 132987, 132991, 132995, 132999, 133003, 133007, 133011, - 133015, 133019, 133023, 133027, 133031, 133035, 133039, 133043, 133047, - 133051, 133055, 133059, 133063, 133067, 133071, 133075, 133079, 133083, - 133087, 133091, 133095, 133099, 133103, 133107, 133111, 133115, 133119, - 133123, 133127, 133131, 133135, 133139, 133143, 133147, 133151, 133155, - 133159, 133163, 133167, 133171, 133175, 133179, 133183, 133187, 133191, - 133195, 133199, 133203, 133207, 133211, 133215, 133219, 133223, 133227, - 133231, 133235, 133239, 133243, 133247, 133251, 133255, 133259, 133263, - 133267, 133271, 133275, 133279, 133283, 133287, 133291, 133295, 133299, - 133303, 133307, 133311, 133315, 133319, 133323, 133327, 133331, 133335, - 133339, 133343, 133347, 133351, 133355, 133359, 133363, 133367, 133371, - 133375, 133379, 133383, 133387, 133391, 133395, 133399, 133403, 133407, - 133411, 133415, 133419, 133423, 133427, 133431, 133435, 133439, 133443, - 133447, 133451, 133455, 133459, 133463, 133467, 133471, 133475, 133479, - 133483, 133487, 133491, 133495, 133499, 133503, 133507, 133511, 133515, - 133519, 133523, 133527, 133531, 133535, 133539, 133543, 133547, 133551, - 133555, 133559, 133563, 133567, 133571, 133575, 133579, 133583, 133587, - 133591, 133595, 133599, 133603, 133607, 133611, 133615, 133619, 133623, - 133627, 133631, 133635, 133639, 133643, 133647, 133651, 133655, 133659, - 133663, 133667, 133671, 133675, 133679, 133683, 133687, 133691, 133695, - 133699, 133703, 133707, 133711, 133715, 133719, 133723, 133727, 133731, - 133735, 133739, 133743, 133747, 133751, 133755, 133759, 133763, 133767, - 133771, 133775, 133779, 133783, 133787, 133791, 133795, 133799, 133803, - 133807, 133811, 133815, 133819, 133823, 133827, 133831, 133835, 133839, - 133843, 133847, 133851, 133855, 133859, 133863, 133867, 133871, 133875, - 133879, 133883, 133887, 133891, 133895, 133899, 133903, 133907, 133911, - 133915, 133919, 133923, 133927, 133931, 133935, 133939, 133943, 133947, - 133951, 133955, 133959, 133963, 133967, 133971, 133975, 133979, 133983, - 133987, 133991, 133995, 133999, 134003, 134007, 134011, 134015, 134019, - 134023, 134027, 134031, 134035, 134039, 134043, 134047, 134051, 134055, - 134059, 134063, 134067, 134071, 134075, 134079, 134083, 134087, 134091, - 134095, 134099, 134103, 134107, 134111, 134115, 134119, 134123, 134127, - 134131, 134135, 134139, 134143, 134147, 134151, 134155, 134159, 134163, - 134167, 134171, 134175, 134179, 134183, 134187, 134191, 134195, 134199, - 134203, 134207, 134211, 134215, 134219, 134223, 134227, 134231, 134235, - 134239, 134243, 134247, 134251, 134255, 134259, 134263, 134267, 134271, - 134275, 134279, 134283, 134287, 134291, 134295, 134299, 134303, 134307, - 134311, 134315, 134319, 134323, 134327, 134331, 134335, 134339, 134343, - 134347, 134351, 134355, 134359, 134363, 134367, 134371, 134375, 134379, - 134383, 134387, 134391, 134395, 134399, 134403, 134407, 134411, 134415, - 134419, 134423, 134427, 134431, 134435, 134439, 134443, 134447, 134451, - 134455, 134459, 134463, 134467, 134471, 134475, 134479, 134483, 134487, - 134491, 134495, 134499, 134503, 134507, 134511, 134515, 134519, 134523, - 134527, 134531, 134535, 134539, 134543, 134547, 134551, 134555, 134559, - 134563, 134567, 134571, 134575, 134579, 134583, 134587, 134591, 134595, - 134599, 134603, 134607, 134611, 134615, 134619, 134623, 134627, 134631, - 134635, 134639, 134643, 134647, 134651, 134655, 134659, 134663, 134667, - 134671, 134675, 134679, 134683, 134687, 134691, 134695, 134699, 134703, - 134707, 134711, 134715, 134719, 134723, 134727, 134731, 134735, 134739, - 134743, 134747, 134751, 134755, 134759, 134763, 134767, 134771, 134775, - 134779, 134783, 134787, 134791, 134795, 134799, 134803, 134807, 134811, - 134815, 134819, 134823, 134827, 134831, 134835, 134839, 134843, 134847, - 134851, 134855, 134859, 134863, 134867, 134871, 134875, 134879, 134883, - 134887, 134891, 134895, 134899, 134903, 134907, 134911, 134915, 134919, - 134923, 134927, 134931, 134935, 134939, 134943, 134947, 134951, 134955, - 134959, 134963, 134967, 134971, 134975, 134979, 134983, 134987, 134991, - 134995, 134999, 135003, 135007, 135011, 135015, 135019, 135023, 135027, - 135031, 135035, 135039, 135043, 135047, 135051, 135055, 135059, 135063, - 135067, 135071, 135075, 135079, 135083, 135087, 135091, 135095, 135099, - 135103, 135107, 135111, 135115, 135119, 135123, 135127, 135131, 135135, - 135139, 135143, 135147, 135151, 135155, 135159, 135163, 135167, 135171, - 135175, 135179, 135183, 135187, 135191, 135195, 135199, 135203, 135207, - 135211, 135215, 135219, 135223, 135227, 135231, 135235, 135239, 135243, - 135247, 135251, 135255, 135259, 135263, 135267, 135271, 135275, 135279, - 135283, 135287, 135291, 135295, 135299, 135303, 135307, 135311, 135315, - 135319, 135323, 135327, 135331, 135335, 135339, 135343, 135347, 135352, - 135358, 135368, 135378, 135388, 135398, 135404, 135410, 135416, 135424, - 135432, 135440, 135446, 135452, 135460, 135468, 135474, 135480, 135485, - 135490, 135496, 135503, 135510, 135521, 135532, 135541, 135552, 135561, - 135577, 135589, 135600, 135616, 135625, 135637, 135646, 135658, 135670, + 0, 130608, 130613, 130618, 130623, 130628, 130633, 130638, 130643, + 130648, 130653, 130658, 130663, 130668, 130673, 130678, 130683, 130688, + 130693, 130698, 130703, 130708, 130713, 130718, 130723, 130728, 130733, + 130738, 130743, 130748, 130753, 130758, 130763, 130768, 130773, 130778, + 130783, 130788, 130793, 130798, 130803, 130808, 130813, 130818, 130823, + 130828, 130833, 130838, 130843, 130848, 130853, 130858, 130863, 130868, + 130873, 130878, 130883, 130888, 130893, 130898, 130903, 130908, 130913, + 130918, 130923, 130928, 130933, 130938, 130943, 130948, 130953, 130958, + 130963, 130968, 130973, 130978, 130983, 130988, 130993, 130998, 131003, + 131008, 131013, 131018, 131023, 131028, 131033, 131038, 131043, 131048, + 131053, 131058, 131063, 131068, 131073, 131078, 131083, 131088, 131093, + 131098, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131103, 131107, 131111, + 131115, 131119, 131123, 131127, 131131, 131135, 131139, 131143, 131147, + 131151, 131155, 131159, 131163, 131167, 131171, 131175, 131179, 131183, + 131187, 131191, 131195, 131199, 131203, 131207, 131211, 131215, 131219, + 131223, 131227, 131231, 131235, 131239, 131243, 131247, 131251, 131255, + 131259, 131263, 131267, 131271, 131275, 131279, 131283, 131287, 131291, + 131295, 131299, 131303, 131307, 131311, 131315, 131319, 131323, 131327, + 131331, 131335, 131339, 131343, 131347, 131351, 131355, 131359, 131363, + 131367, 131371, 131375, 131379, 131383, 131387, 131391, 131395, 131399, + 131403, 131407, 131411, 131415, 131419, 131423, 131427, 131431, 131435, + 131439, 131443, 131447, 131451, 131455, 131459, 131463, 131467, 131471, + 131475, 131479, 131483, 131487, 131491, 131495, 131499, 131503, 131507, + 131511, 131515, 131519, 131523, 131527, 131531, 131535, 131539, 131543, + 131547, 131551, 131555, 131559, 131563, 131567, 131571, 131575, 131579, + 131583, 131587, 131591, 131595, 131599, 131603, 131607, 131611, 131615, + 131619, 131623, 131627, 131631, 131635, 131639, 131643, 131647, 131651, + 131655, 131659, 131663, 131667, 131671, 131675, 131679, 131683, 131687, + 131691, 131695, 131699, 131703, 131707, 131711, 131715, 131719, 131723, + 131727, 131731, 131735, 131739, 131743, 131747, 131751, 131755, 131759, + 131763, 131767, 131771, 131775, 131779, 131783, 131787, 131791, 131795, + 131799, 131803, 131807, 131811, 131815, 131819, 131823, 131827, 131831, + 131835, 131839, 131843, 131847, 131851, 131855, 131859, 131863, 131867, + 131871, 131875, 131879, 131883, 131887, 131891, 131895, 131899, 131903, + 131907, 131911, 131915, 131919, 131923, 131927, 131931, 131935, 131939, + 131943, 131947, 131951, 131955, 131959, 131963, 131967, 131971, 131975, + 131979, 131983, 131987, 131991, 131995, 131999, 132003, 132007, 132011, + 132015, 132019, 132023, 132027, 132031, 132035, 132039, 132043, 132047, + 132051, 132055, 132059, 132063, 132067, 132071, 132075, 132079, 132083, + 132087, 132091, 132095, 132099, 132103, 132107, 132111, 132115, 132119, + 132123, 132127, 132131, 132135, 132139, 132143, 132147, 132151, 132155, + 132159, 132163, 132167, 132171, 132175, 132179, 132183, 132187, 132191, + 132195, 132199, 132203, 132207, 132211, 132215, 132219, 132223, 132227, + 132231, 132235, 132239, 132243, 132247, 132251, 132255, 132259, 132263, + 132267, 132271, 132275, 132279, 132283, 132287, 132291, 132295, 132299, + 132303, 132307, 132311, 132315, 132319, 132323, 132327, 132331, 132335, + 132339, 132343, 132347, 132351, 132355, 132359, 132363, 132367, 132371, + 132375, 132379, 132383, 132387, 132391, 132395, 132399, 132403, 132407, + 132411, 132415, 132419, 132423, 132427, 132431, 132435, 132439, 132443, + 132447, 132451, 132455, 132459, 132463, 132467, 132471, 132475, 132479, + 132483, 132487, 132491, 132495, 132499, 132503, 132507, 132511, 132515, + 132519, 132523, 132527, 132531, 132535, 132539, 132543, 132547, 132551, + 132555, 132559, 132563, 132567, 132571, 132575, 132579, 132583, 132587, + 132591, 132595, 132599, 132603, 132607, 132611, 132615, 132619, 132623, + 132627, 132631, 132635, 132639, 132643, 132647, 132651, 132655, 132659, + 132663, 132667, 132671, 132675, 132679, 132683, 132687, 132691, 132695, + 132699, 132703, 132707, 132711, 132715, 132719, 132723, 132727, 132731, + 132735, 132739, 132743, 132747, 132751, 132755, 132759, 132763, 132767, + 132771, 132775, 132779, 132783, 132787, 132791, 132795, 132799, 132803, + 132807, 132811, 132815, 132819, 132823, 132827, 132831, 132835, 132839, + 132843, 132847, 132851, 132855, 132859, 132863, 132867, 132871, 132875, + 132879, 132883, 132887, 132891, 132895, 132899, 132903, 132907, 132911, + 132915, 132919, 132923, 132927, 132931, 132935, 132939, 132943, 132947, + 132951, 132955, 132959, 132963, 132967, 132971, 132975, 132979, 132983, + 132987, 132991, 132995, 132999, 133003, 133007, 133011, 133015, 133019, + 133023, 133027, 133031, 133035, 133039, 133043, 133047, 133051, 133055, + 133059, 133063, 133067, 133071, 133075, 133079, 133083, 133087, 133091, + 133095, 133099, 133103, 133107, 133111, 133115, 133119, 133123, 133127, + 133131, 133135, 133139, 133143, 133147, 133151, 133155, 133159, 133163, + 133167, 133171, 133175, 133179, 133183, 133187, 133191, 133195, 133199, + 133203, 133207, 133211, 133215, 133219, 133223, 133227, 133231, 133235, + 133239, 133243, 133247, 133251, 133255, 133259, 133263, 133267, 133271, + 133275, 133279, 133283, 133287, 133291, 133295, 133299, 133303, 133307, + 133311, 133315, 133319, 133323, 133327, 133331, 133335, 133339, 133343, + 133347, 133351, 133355, 133359, 133363, 133367, 133371, 133375, 133379, + 133383, 133387, 133391, 133395, 133399, 133403, 133407, 133411, 133415, + 133419, 133423, 133427, 133431, 133435, 133439, 133443, 133447, 133451, + 133455, 133459, 133463, 133467, 133471, 133475, 133479, 133483, 133487, + 133491, 133495, 133499, 133503, 133507, 133511, 133515, 133519, 133523, + 133527, 133531, 133535, 133539, 133543, 133547, 133551, 133555, 133559, + 133563, 133567, 133571, 133575, 133579, 133583, 133587, 133591, 133595, + 133599, 133603, 133607, 133611, 133615, 133619, 133623, 133627, 133631, + 133635, 133639, 133643, 133647, 133651, 133655, 133659, 133663, 133667, + 133671, 133675, 133679, 133683, 133687, 133691, 133695, 133699, 133703, + 133707, 133711, 133715, 133719, 133723, 133727, 133731, 133735, 133739, + 133743, 133747, 133751, 133755, 133759, 133763, 133767, 133771, 133775, + 133779, 133783, 133787, 133791, 133795, 133799, 133803, 133807, 133811, + 133815, 133819, 133823, 133827, 133831, 133835, 133839, 133843, 133847, + 133851, 133855, 133859, 133863, 133867, 133871, 133875, 133879, 133883, + 133887, 133891, 133895, 133899, 133903, 133907, 133911, 133915, 133919, + 133923, 133927, 133931, 133935, 133939, 133943, 133947, 133951, 133955, + 133959, 133963, 133967, 133971, 133975, 133979, 133983, 133987, 133991, + 133995, 133999, 134003, 134007, 134011, 134015, 134019, 134023, 134027, + 134031, 134035, 134039, 134043, 134047, 134051, 134055, 134059, 134063, + 134067, 134071, 134075, 134079, 134083, 134087, 134091, 134095, 134099, + 134103, 134107, 134111, 134115, 134119, 134123, 134127, 134131, 134135, + 134139, 134143, 134147, 134151, 134155, 134159, 134163, 134167, 134171, + 134175, 134179, 134183, 134187, 134191, 134195, 134199, 134203, 134207, + 134211, 134215, 134219, 134223, 134227, 134231, 134235, 134239, 134243, + 134247, 134251, 134255, 134259, 134263, 134267, 134271, 134275, 134279, + 134283, 134287, 134291, 134295, 134299, 134303, 134307, 134311, 134315, + 134319, 134323, 134327, 134331, 134335, 134339, 134343, 134347, 134351, + 134355, 134359, 134363, 134367, 134371, 134375, 134379, 134383, 134387, + 134391, 134395, 134399, 134403, 134407, 134411, 134415, 134419, 134423, + 134427, 134431, 134435, 134439, 134443, 134447, 134451, 134455, 134459, + 134463, 134467, 134471, 134475, 134479, 134483, 134487, 134491, 134495, + 134499, 134503, 134507, 134511, 134515, 134519, 134523, 134527, 134531, + 134535, 134539, 134543, 134547, 134551, 134555, 134559, 134563, 134567, + 134571, 134575, 134579, 134583, 134587, 134591, 134595, 134599, 134603, + 134607, 134611, 134615, 134619, 134623, 134627, 134631, 134635, 134639, + 134643, 134647, 134651, 134655, 134659, 134663, 134667, 134671, 134675, + 134679, 134683, 134687, 134691, 134695, 134699, 134703, 134707, 134711, + 134715, 134719, 134723, 134727, 134731, 134735, 134739, 134743, 134747, + 134751, 134755, 134759, 134763, 134767, 134771, 134775, 134779, 134783, + 134787, 134791, 134795, 134799, 134803, 134807, 134811, 134815, 134819, + 134823, 134827, 134831, 134835, 134839, 134843, 134847, 134851, 134855, + 134859, 134863, 134867, 134871, 134875, 134879, 134883, 134887, 134891, + 134895, 134899, 134903, 134907, 134911, 134915, 134919, 134923, 134927, + 134931, 134935, 134939, 134943, 134947, 134951, 134955, 134959, 134963, + 134967, 134971, 134975, 134979, 134983, 134987, 134991, 134995, 134999, + 135003, 135007, 135011, 135015, 135019, 135023, 135027, 135031, 135035, + 135039, 135043, 135047, 135051, 135055, 135059, 135063, 135067, 135071, + 135075, 135079, 135083, 135087, 135091, 135095, 135099, 135103, 135107, + 135111, 135115, 135119, 135123, 135127, 135131, 135135, 135139, 135143, + 135147, 135151, 135155, 135159, 135163, 135167, 135171, 135175, 135179, + 135183, 135187, 135191, 135195, 135199, 135203, 135207, 135211, 135215, + 135219, 135223, 135227, 135231, 135235, 135239, 135243, 135247, 135251, + 135255, 135259, 135263, 135267, 135271, 135275, 135279, 135283, 135287, + 135291, 135295, 135299, 135303, 135307, 135311, 135315, 135319, 135323, + 135327, 135331, 135335, 135339, 135343, 135347, 135351, 135355, 135359, + 135363, 135367, 135371, 135375, 135379, 135383, 135387, 135391, 135396, + 135402, 135412, 135422, 135432, 135442, 135448, 135454, 135460, 135468, + 135476, 135484, 135490, 135496, 135504, 135512, 135518, 135524, 135529, + 135534, 135540, 135547, 135554, 135565, 135576, 135585, 135596, 135605, + 135621, 135633, 135644, 135660, 135669, 135681, 135690, 135702, 135714, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135675, 135679, - 135683, 135687, 135691, 135695, 135699, 135703, 135707, 135711, 135715, - 135719, 135723, 135727, 135731, 135735, 135739, 135743, 135747, 135751, - 135755, 135759, 135763, 135767, 135771, 135775, 135779, 135783, 135787, - 135791, 135795, 135799, 135803, 135807, 135811, 135815, 135819, 135823, - 135827, 135831, 135835, 135839, 135843, 135847, 135851, 135855, 135859, - 135863, 135867, 135871, 135875, 135879, 135883, 135887, 135891, 135895, - 135899, 135903, 135907, 135911, 135915, 135919, 135923, 135927, 135931, - 135935, 135939, 135943, 135947, 135951, 135955, 135959, 135963, 135967, - 135971, 135975, 135979, 135983, 135987, 135991, 135995, 135999, 136003, - 136007, 136011, 136015, 136019, 136023, 136027, 136031, 136035, 136039, - 136043, 136047, 136051, 136055, 136059, 136063, 136067, 136071, 136075, - 136079, 136083, 136087, 136091, 136095, 136099, 136103, 136107, 136111, - 136115, 136119, 136123, 136127, 136131, 136135, 136139, 136143, 136147, - 136151, 136155, 136159, 136163, 136167, 136171, 136175, 136179, 136183, - 136187, 136191, 136195, 136199, 136203, 136207, 136211, 136215, 136219, - 136223, 136227, 136231, 136235, 136239, 136243, 136247, 136251, 136255, - 136259, 136263, 136267, 136271, 136275, 136279, 136283, 136287, 136291, - 136295, 136299, 136303, 136307, 136311, 136315, 136319, 136323, 136327, - 136331, 136335, 136339, 136343, 136347, 136351, 136355, 136359, 136363, - 136367, 136371, 136375, 136379, 136383, 136387, 136391, 136395, 136399, - 136403, 136407, 136411, 136415, 136419, 136423, 136427, 136431, 136435, - 136439, 136443, 136447, 136451, 136455, 136459, 136463, 136467, 136471, - 136475, 136479, 136483, 136487, 136491, 136495, 136499, 136503, 136507, - 136511, 136515, 136519, 136523, 136527, 136531, 136535, 136539, 136543, - 136547, 136551, 136555, 136559, 136563, 136567, 136571, 136575, 136579, - 136583, 136587, 136591, 136595, 136599, 136603, 136607, 136611, 136615, - 136619, 136623, 136627, 136631, 136635, 136639, 136643, 136647, 136651, - 136655, 136659, 136663, 136667, 136671, 136675, 136679, 136683, 136687, - 136691, 136695, 136699, 136703, 136707, 136711, 136715, 136719, 136723, - 136727, 136731, 136735, 136739, 136743, 136747, 136751, 136755, 136759, - 136763, 136767, 136771, 136775, 136779, 136783, 136787, 136791, 136795, - 136799, 136803, 136807, 136811, 136815, 136819, 136823, 136827, 136831, - 136835, 136839, 136843, 136847, 136851, 136855, 136859, 136863, 136867, - 136871, 136875, 136879, 136883, 136887, 136891, 136895, 136899, 136903, - 136907, 136911, 136915, 136919, 136923, 136927, 136931, 136935, 136939, - 136943, 136947, 136951, 136955, 136959, 136963, 136967, 136971, 136975, - 136979, 136983, 136987, 136991, 136995, 136999, 137003, 137007, 137011, - 137015, 137019, 137023, 137027, 137031, 137035, 137039, 137043, 137047, - 137051, 137055, 137059, 137063, 137067, 137071, 137075, 137079, 137083, - 137087, 137091, 137095, 137099, 137103, 137107, 137111, 137115, 137119, - 137123, 137127, 137131, 137135, 137139, 137143, 137147, 137151, 137155, - 137159, 137163, 137167, 137171, 137175, 137179, 137183, 137187, 137191, - 137195, 137199, 137203, 137207, 137211, 137215, 137219, 137223, 137227, - 137231, 137235, 137239, 137243, 137247, 137251, 137255, 137259, 137263, - 137267, 137271, 137275, 137279, 137283, 137287, 137291, 137295, 137299, - 137303, 137307, 137311, 137315, 137319, 137323, 137327, 137331, 137335, - 137339, 137343, 137347, 137351, 137355, 137359, 137363, 137367, 137371, - 137375, 137379, 137383, 137387, 137391, 137395, 137399, 137403, 137407, - 137417, 137421, 137425, 137429, 137433, 137437, 137441, 137445, 137449, - 137453, 137457, 137461, 137466, 137470, 137474, 137478, 137482, 137486, - 137490, 137494, 137498, 137502, 137506, 137510, 137514, 137518, 137522, - 137526, 137530, 137539, 137548, 137552, 137556, 137560, 137564, 137568, - 137572, 137576, 137580, 137584, 137588, 137592, 137596, 137600, 137604, - 137608, 137612, 137616, 137620, 137624, 137628, 137632, 137636, 137640, - 137644, 137648, 137652, 137656, 137660, 137664, 137668, 137672, 137676, - 137680, 137684, 137688, 137692, 137696, 137700, 137704, 137708, 137712, - 137716, 137720, 137724, 137728, 137732, 137736, 137740, 137744, 137748, - 137752, 137756, 137760, 137764, 137768, 137772, 137776, 137780, 137784, - 137788, 137792, 137796, 137800, 137804, 137808, 137812, 137816, 137820, - 137824, 137828, 137832, 137836, 137840, 137844, 137848, 137852, 137856, - 137860, 137864, 137868, 137872, 137876, 137880, 137884, 137888, 137892, - 137896, 137900, 137904, 137908, 137912, 137916, 137920, 137924, 137928, - 137932, 137936, 137940, 137944, 137948, 137952, 137956, 137960, 137964, - 137968, 137972, 137976, 137980, 137984, 137988, 137992, 137996, 138000, - 138004, 138008, 138012, 138016, 138020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135719, 135723, + 135727, 135731, 135735, 135739, 135743, 135747, 135751, 135755, 135759, + 135763, 135767, 135771, 135775, 135779, 135783, 135787, 135791, 135795, + 135799, 135803, 135807, 135811, 135815, 135819, 135823, 135827, 135831, + 135835, 135839, 135843, 135847, 135851, 135855, 135859, 135863, 135867, + 135871, 135875, 135879, 135883, 135887, 135891, 135895, 135899, 135903, + 135907, 135911, 135915, 135919, 135923, 135927, 135931, 135935, 135939, + 135943, 135947, 135951, 135955, 135959, 135963, 135967, 135971, 135975, + 135979, 135983, 135987, 135991, 135995, 135999, 136003, 136007, 136011, + 136015, 136019, 136023, 136027, 136031, 136035, 136039, 136043, 136047, + 136051, 136055, 136059, 136063, 136067, 136071, 136075, 136079, 136083, + 136087, 136091, 136095, 136099, 136103, 136107, 136111, 136115, 136119, + 136123, 136127, 136131, 136135, 136139, 136143, 136147, 136151, 136155, + 136159, 136163, 136167, 136171, 136175, 136179, 136183, 136187, 136191, + 136195, 136199, 136203, 136207, 136211, 136215, 136219, 136223, 136227, + 136231, 136235, 136239, 136243, 136247, 136251, 136255, 136259, 136263, + 136267, 136271, 136275, 136279, 136283, 136287, 136291, 136295, 136299, + 136303, 136307, 136311, 136315, 136319, 136323, 136327, 136331, 136335, + 136339, 136343, 136347, 136351, 136355, 136359, 136363, 136367, 136371, + 136375, 136379, 136383, 136387, 136391, 136395, 136399, 136403, 136407, + 136411, 136415, 136419, 136423, 136427, 136431, 136435, 136439, 136443, + 136447, 136451, 136455, 136459, 136463, 136467, 136471, 136475, 136479, + 136483, 136487, 136491, 136495, 136499, 136503, 136507, 136511, 136515, + 136519, 136523, 136527, 136531, 136535, 136539, 136543, 136547, 136551, + 136555, 136559, 136563, 136567, 136571, 136575, 136579, 136583, 136587, + 136591, 136595, 136599, 136603, 136607, 136611, 136615, 136619, 136623, + 136627, 136631, 136635, 136639, 136643, 136647, 136651, 136655, 136659, + 136663, 136667, 136671, 136675, 136679, 136683, 136687, 136691, 136695, + 136699, 136703, 136707, 136711, 136715, 136719, 136723, 136727, 136731, + 136735, 136739, 136743, 136747, 136751, 136755, 136759, 136763, 136767, + 136771, 136775, 136779, 136783, 136787, 136791, 136795, 136799, 136803, + 136807, 136811, 136815, 136819, 136823, 136827, 136831, 136835, 136839, + 136843, 136847, 136851, 136855, 136859, 136863, 136867, 136871, 136875, + 136879, 136883, 136887, 136891, 136895, 136899, 136903, 136907, 136911, + 136915, 136919, 136923, 136927, 136931, 136935, 136939, 136943, 136947, + 136951, 136955, 136959, 136963, 136967, 136971, 136975, 136979, 136983, + 136987, 136991, 136995, 136999, 137003, 137007, 137011, 137015, 137019, + 137023, 137027, 137031, 137035, 137039, 137043, 137047, 137051, 137055, + 137059, 137063, 137067, 137071, 137075, 137079, 137083, 137087, 137091, + 137095, 137099, 137103, 137107, 137111, 137115, 137119, 137123, 137127, + 137131, 137135, 137139, 137143, 137147, 137151, 137155, 137159, 137163, + 137167, 137171, 137175, 137179, 137183, 137187, 137191, 137195, 137199, + 137203, 137207, 137211, 137215, 137219, 137223, 137227, 137231, 137235, + 137239, 137243, 137247, 137251, 137255, 137259, 137263, 137267, 137271, + 137275, 137279, 137283, 137287, 137291, 137295, 137299, 137303, 137307, + 137311, 137315, 137319, 137323, 137327, 137331, 137335, 137339, 137343, + 137347, 137351, 137355, 137359, 137363, 137367, 137371, 137375, 137379, + 137383, 137387, 137391, 137395, 137399, 137403, 137407, 137411, 137415, + 137419, 137423, 137427, 137431, 137435, 137439, 137443, 137447, 137451, + 137461, 137465, 137469, 137473, 137477, 137481, 137485, 137489, 137493, + 137497, 137501, 137505, 137510, 137514, 137518, 137522, 137526, 137530, + 137534, 137538, 137542, 137546, 137550, 137554, 137558, 137562, 137566, + 137570, 137574, 137583, 137592, 137596, 137600, 137604, 137608, 137612, + 137616, 137620, 137624, 137628, 137632, 137636, 137640, 137644, 137648, + 137652, 137656, 137660, 137664, 137668, 137672, 137676, 137680, 137684, + 137688, 137692, 137696, 137700, 137704, 137708, 137712, 137716, 137720, + 137724, 137728, 137732, 137736, 137740, 137744, 137748, 137752, 137756, + 137760, 137764, 137768, 137772, 137776, 137780, 137784, 137788, 137792, + 137796, 137800, 137804, 137808, 137812, 137816, 137820, 137824, 137828, + 137832, 137836, 137840, 137844, 137848, 137852, 137856, 137860, 137864, + 137868, 137872, 137876, 137880, 137884, 137888, 137892, 137896, 137900, + 137904, 137908, 137912, 137916, 137920, 137924, 137928, 137932, 137936, + 137940, 137944, 137948, 137952, 137956, 137960, 137964, 137968, 137972, + 137976, 137980, 137984, 137988, 137992, 137996, 138000, 138004, 138008, + 138012, 138016, 138020, 138024, 138028, 138032, 138036, 138040, 138044, + 138048, 138052, 138056, 138060, 138064, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138024, - 138032, 138040, 138050, 138060, 138068, 138074, 138082, 138090, 138100, - 138112, 138124, 138130, 138138, 138144, 138150, 138156, 138162, 138168, - 138174, 138180, 138186, 138192, 138198, 138204, 138212, 138220, 138226, - 138232, 138238, 138244, 138252, 138260, 138269, 138275, 138283, 138289, - 138295, 138301, 138307, 138313, 138321, 138329, 138335, 138341, 138347, - 138353, 138359, 138365, 138371, 138377, 138383, 138389, 138395, 138401, - 138407, 138413, 138419, 138425, 138431, 138437, 138443, 138451, 138457, - 138463, 138473, 138481, 138487, 138493, 138499, 138505, 138511, 138517, - 138523, 138529, 138535, 138541, 138547, 138553, 138559, 138565, 138571, - 138577, 138583, 138589, 138595, 138601, 138607, 138613, 138621, 138627, - 138635, 138643, 138651, 138657, 138663, 138669, 138675, 138681, 138689, - 138699, 138707, 138715, 138721, 138727, 138735, 138743, 138749, 138757, - 138765, 138773, 138779, 138785, 138791, 138797, 138803, 138809, 138817, - 138825, 138831, 138837, 138843, 138849, 138855, 138863, 138869, 138875, - 138881, 138887, 138893, 138899, 138907, 138913, 138919, 138925, 138931, - 138939, 138947, 138953, 138959, 138965, 138970, 138976, 138982, 138990, - 138996, 139002, 139008, 139014, 139020, 139026, 139032, 139038, 139044, - 139054, 139062, 139068, 139074, 139080, 139088, 139094, 139100, 139106, - 139114, 139120, 139126, 139132, 139138, 139144, 139150, 139156, 139162, - 139168, 139174, 139180, 139188, 139194, 139202, 139208, 139214, 139222, - 139228, 139234, 139240, 139246, 139252, 139258, 139264, 139270, 139276, - 139282, 139288, 139294, 139300, 139306, 139312, 139318, 139324, 139330, - 139336, 139344, 139350, 139356, 139362, 139368, 139374, 139380, 139386, - 139392, 139398, 139404, 139410, 139416, 139422, 139430, 139436, 139442, - 139450, 139456, 139462, 139468, 139474, 139480, 139486, 139492, 139498, - 139504, 139510, 139518, 139524, 139530, 139536, 139542, 139548, 139556, - 139564, 139570, 139576, 139582, 139588, 139594, 139600, 139605, 139610, - 139615, 139620, 139625, 139630, 139635, 139640, 139645, 139650, 139655, - 139660, 139665, 139670, 139675, 139680, 139685, 139690, 139695, 139700, - 139705, 139710, 139715, 139720, 139725, 139730, 139735, 139740, 139745, - 139750, 139757, 139762, 139767, 139772, 139777, 139782, 139787, 139792, - 139797, 139802, 139807, 139812, 139817, 139822, 139827, 139832, 139837, - 139842, 139847, 139852, 139857, 139862, 139867, 139872, 139877, 139882, - 139887, 139892, 139897, 139902, 139907, 139912, 139917, 139922, 139927, - 139932, 139937, 139942, 139947, 139952, 139957, 139962, 139967, 139972, - 139977, 139982, 139987, 139992, 139997, 140002, 140007, 140012, 140017, - 140022, 140027, 140032, 140037, 140042, 140047, 140054, 140059, 140064, - 140069, 140074, 140079, 140084, 140089, 140094, 140099, 140104, 140109, - 140114, 140119, 140124, 140129, 140134, 140139, 140144, 140149, 140154, - 140159, 140166, 140171, 140176, 140182, 140187, 140192, 140197, 140202, - 140207, 140212, 140217, 140222, 140227, 140232, 140237, 140242, 140247, - 140252, 140257, 140262, 140267, 140272, 140277, 140282, 140287, 140292, - 140297, 140302, 140307, 140312, 140317, 140322, 140327, 140332, 140337, - 140342, 140347, 140352, 140357, 140362, 140367, 140372, 140377, 140382, - 140387, 140392, 140397, 140404, 140409, 140414, 140421, 140428, 140433, - 140438, 140443, 140448, 140453, 140458, 140463, 140468, 140473, 140478, - 140483, 140488, 140493, 140498, 140503, 140508, 140513, 140518, 140523, - 140528, 140533, 140538, 140543, 140548, 140553, 140560, 140565, 140570, - 140575, 140580, 140585, 140590, 140595, 140600, 140605, 140610, 140615, - 140620, 140625, 140630, 140635, 140640, 140645, 140650, 140657, 140662, - 140667, 140672, 140677, 140682, 140687, 140692, 140698, 140703, 140708, - 140713, 140718, 140723, 140728, 140733, 140738, 140745, 140752, 140757, - 140762, 140766, 140771, 140775, 140779, 140784, 140791, 140796, 140801, - 140810, 140815, 140820, 140825, 140830, 140837, 140844, 140849, 140854, - 140859, 140864, 140871, 140876, 140881, 140886, 140891, 140896, 140901, - 140906, 140911, 140916, 140921, 140926, 140931, 140938, 140942, 140947, - 140952, 140957, 140962, 140966, 140971, 140976, 140981, 140986, 140991, - 140996, 141001, 141006, 141011, 141017, 141023, 141029, 141035, 141041, - 141046, 141052, 141058, 141064, 141070, 141076, 141082, 141088, 141094, - 141100, 141106, 141112, 141118, 141124, 141130, 141136, 141142, 141148, - 141154, 141159, 141165, 141171, 141177, 141183, 141189, 141195, 141201, - 141207, 141213, 141219, 141225, 141231, 141237, 141243, 141249, 141255, - 141261, 141267, 141273, 141279, 141284, 141290, 141296, 141302, 141308, - 141314, 0, 0, 0, 0, 0, 0, 0, 141320, 141325, 141330, 141335, 141340, - 141345, 141350, 141354, 141359, 141364, 141369, 141374, 141379, 141384, - 141389, 141394, 141399, 141403, 141408, 141412, 141417, 141422, 141427, - 141432, 141437, 141441, 141446, 141451, 141455, 141460, 141465, 0, - 141470, 141475, 141479, 141483, 141487, 141491, 141495, 141499, 141503, - 141507, 0, 0, 0, 0, 141511, 141515, 141520, 141525, 141530, 141535, - 141540, 141545, 141550, 141555, 141560, 141565, 141570, 141575, 141580, - 141585, 141590, 141595, 141600, 141605, 141610, 141615, 141620, 141625, - 141630, 141635, 141640, 141645, 141650, 141655, 141660, 141665, 141670, - 141675, 141680, 141686, 141692, 141699, 141706, 141711, 141716, 141721, - 141726, 141731, 141736, 141741, 141746, 141751, 141756, 141761, 141766, - 141770, 141775, 141780, 141785, 141789, 141793, 141798, 141802, 141807, - 141812, 141817, 141821, 141825, 141829, 141833, 141838, 141843, 141848, - 141852, 141857, 141862, 141867, 141872, 141877, 141882, 141887, 141892, - 141897, 141902, 141907, 0, 141912, 141917, 141921, 141925, 141929, - 141933, 141937, 141941, 141945, 141949, 0, 0, 0, 0, 0, 0, 141953, 141960, - 141966, 141973, 141980, 141987, 141994, 142001, 142008, 142015, 142022, - 142029, 142036, 142043, 142050, 142057, 142064, 142071, 142077, 142084, - 142091, 142098, 142104, 142111, 142117, 142123, 142130, 142136, 142143, - 142149, 0, 0, 142155, 142163, 142171, 142180, 142189, 142198, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 142206, 142211, 142216, 142221, 142226, 142231, 142236, - 142241, 142246, 142251, 142256, 142261, 142266, 142271, 142276, 142281, - 142286, 142291, 142296, 142301, 142306, 142311, 142316, 142321, 142326, - 142331, 142336, 142341, 142346, 142351, 142356, 142361, 142366, 142371, - 142376, 142381, 142386, 142391, 142396, 142401, 142406, 142411, 142416, - 142421, 142426, 142431, 142436, 142441, 142446, 142453, 142460, 142467, - 142474, 142481, 142488, 142495, 142502, 142511, 142518, 142525, 142532, - 142539, 142546, 142553, 142560, 142567, 142574, 142581, 142588, 142593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142602, 142607, 142611, 142615, 142619, - 142623, 142627, 142631, 142635, 142639, 0, 142643, 142648, 142653, - 142660, 142665, 142672, 142679, 0, 142684, 142691, 142696, 142701, - 142708, 142715, 142720, 142725, 142730, 142735, 142740, 142747, 142754, - 142759, 142764, 142769, 142782, 142791, 142798, 142807, 142816, 0, 0, 0, - 0, 0, 142825, 142832, 142839, 142846, 142853, 142860, 142867, 142874, - 142881, 142888, 142895, 142902, 142909, 142916, 142923, 142930, 142937, - 142944, 142951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138068, + 138076, 138084, 138094, 138104, 138112, 138118, 138126, 138134, 138144, + 138156, 138168, 138174, 138182, 138188, 138194, 138200, 138206, 138212, + 138218, 138224, 138230, 138236, 138242, 138248, 138256, 138264, 138270, + 138276, 138282, 138288, 138296, 138304, 138313, 138319, 138327, 138333, + 138339, 138345, 138351, 138357, 138365, 138373, 138379, 138385, 138391, + 138397, 138403, 138409, 138415, 138421, 138427, 138433, 138439, 138445, + 138451, 138457, 138463, 138469, 138475, 138481, 138487, 138495, 138501, + 138507, 138517, 138525, 138531, 138537, 138543, 138549, 138555, 138561, + 138567, 138573, 138579, 138585, 138591, 138597, 138603, 138609, 138615, + 138621, 138627, 138633, 138639, 138645, 138651, 138657, 138665, 138671, + 138679, 138687, 138695, 138701, 138707, 138713, 138719, 138725, 138733, + 138743, 138751, 138759, 138765, 138771, 138779, 138787, 138793, 138801, + 138809, 138817, 138823, 138829, 138835, 138841, 138847, 138853, 138861, + 138869, 138875, 138881, 138887, 138893, 138899, 138907, 138913, 138919, + 138925, 138931, 138937, 138943, 138951, 138957, 138963, 138969, 138975, + 138983, 138991, 138997, 139003, 139009, 139014, 139020, 139026, 139034, + 139040, 139046, 139052, 139058, 139064, 139070, 139076, 139082, 139088, + 139098, 139106, 139112, 139118, 139124, 139132, 139138, 139144, 139150, + 139158, 139164, 139170, 139176, 139182, 139188, 139194, 139200, 139206, + 139212, 139218, 139224, 139232, 139238, 139246, 139252, 139258, 139266, + 139272, 139278, 139284, 139290, 139296, 139302, 139308, 139314, 139320, + 139326, 139332, 139338, 139344, 139350, 139356, 139362, 139368, 139374, + 139380, 139388, 139394, 139400, 139406, 139412, 139418, 139424, 139430, + 139436, 139442, 139448, 139454, 139460, 139466, 139474, 139480, 139486, + 139494, 139500, 139506, 139512, 139518, 139524, 139530, 139536, 139542, + 139548, 139554, 139562, 139568, 139574, 139580, 139586, 139592, 139600, + 139608, 139614, 139620, 139626, 139632, 139638, 139644, 139649, 139654, + 139659, 139664, 139669, 139674, 139679, 139684, 139689, 139694, 139699, + 139704, 139709, 139714, 139719, 139724, 139729, 139734, 139739, 139744, + 139749, 139754, 139759, 139764, 139769, 139774, 139779, 139784, 139789, + 139794, 139801, 139806, 139811, 139816, 139821, 139826, 139831, 139836, + 139841, 139846, 139851, 139856, 139861, 139866, 139871, 139876, 139881, + 139886, 139891, 139896, 139901, 139906, 139911, 139916, 139921, 139926, + 139931, 139936, 139941, 139946, 139951, 139956, 139961, 139966, 139971, + 139976, 139981, 139986, 139991, 139996, 140001, 140006, 140011, 140016, + 140021, 140026, 140031, 140036, 140041, 140046, 140051, 140056, 140061, + 140066, 140071, 140076, 140081, 140086, 140091, 140098, 140103, 140108, + 140113, 140118, 140123, 140128, 140133, 140138, 140143, 140148, 140153, + 140158, 140163, 140168, 140173, 140178, 140183, 140188, 140193, 140198, + 140203, 140210, 140215, 140220, 140226, 140231, 140236, 140241, 140246, + 140251, 140256, 140261, 140266, 140271, 140276, 140281, 140286, 140291, + 140296, 140301, 140306, 140311, 140316, 140321, 140326, 140331, 140336, + 140341, 140346, 140351, 140356, 140361, 140366, 140371, 140376, 140381, + 140386, 140391, 140396, 140401, 140406, 140411, 140416, 140421, 140426, + 140431, 140436, 140441, 140448, 140453, 140458, 140465, 140472, 140477, + 140482, 140487, 140492, 140497, 140502, 140507, 140512, 140517, 140522, + 140527, 140532, 140537, 140542, 140547, 140552, 140557, 140562, 140567, + 140572, 140577, 140582, 140587, 140592, 140597, 140604, 140609, 140614, + 140619, 140624, 140629, 140634, 140639, 140644, 140649, 140654, 140659, + 140664, 140669, 140674, 140679, 140684, 140689, 140694, 140701, 140706, + 140711, 140716, 140721, 140726, 140731, 140736, 140742, 140747, 140752, + 140757, 140762, 140767, 140772, 140777, 140782, 140789, 140796, 140801, + 140806, 140810, 140815, 140819, 140823, 140828, 140835, 140840, 140845, + 140854, 140859, 140864, 140869, 140874, 140881, 140888, 140893, 140898, + 140903, 140908, 140915, 140920, 140925, 140930, 140935, 140940, 140945, + 140950, 140955, 140960, 140965, 140970, 140975, 140982, 140986, 140991, + 140996, 141001, 141006, 141010, 141015, 141020, 141025, 141030, 141035, + 141040, 141045, 141050, 141055, 141061, 141067, 141073, 141079, 141085, + 141090, 141096, 141102, 141108, 141114, 141120, 141126, 141132, 141138, + 141144, 141150, 141156, 141162, 141168, 141174, 141180, 141186, 141192, + 141198, 141203, 141209, 141215, 141221, 141227, 141233, 141239, 141245, + 141251, 141257, 141263, 141269, 141275, 141281, 141287, 141293, 141299, + 141305, 141311, 141317, 141323, 141328, 141334, 141340, 141346, 141352, + 141358, 0, 0, 0, 0, 0, 0, 0, 141364, 141369, 141374, 141379, 141384, + 141389, 141394, 141398, 141403, 141408, 141413, 141418, 141423, 141428, + 141433, 141438, 141443, 141447, 141452, 141456, 141461, 141466, 141471, + 141476, 141481, 141485, 141490, 141495, 141499, 141504, 141509, 0, + 141514, 141519, 141523, 141527, 141531, 141535, 141539, 141543, 141547, + 141551, 0, 0, 0, 0, 141555, 141559, 141564, 141569, 141574, 141579, + 141584, 141589, 141594, 141599, 141604, 141609, 141614, 141619, 141624, + 141629, 141634, 141639, 141644, 141649, 141654, 141659, 141664, 141669, + 141674, 141679, 141684, 141689, 141694, 141699, 141704, 141709, 141714, + 141719, 141724, 141730, 141736, 141743, 141750, 141755, 141760, 141765, + 141770, 141775, 141780, 141785, 141790, 141795, 141800, 141805, 141810, + 141814, 141819, 141824, 141829, 141833, 141837, 141842, 141846, 141851, + 141856, 141861, 141865, 141869, 141873, 141877, 141882, 141887, 141892, + 141896, 141901, 141906, 141911, 141916, 141921, 141926, 141931, 141936, + 141941, 141946, 141951, 0, 141956, 141961, 141965, 141969, 141973, + 141977, 141981, 141985, 141989, 141993, 0, 0, 0, 0, 0, 0, 141997, 142004, + 142010, 142017, 142024, 142031, 142038, 142045, 142052, 142059, 142066, + 142073, 142080, 142087, 142094, 142101, 142108, 142115, 142121, 142128, + 142135, 142142, 142148, 142155, 142161, 142167, 142174, 142180, 142187, + 142193, 0, 0, 142199, 142207, 142215, 142224, 142233, 142242, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 142250, 142255, 142260, 142265, 142270, 142275, 142280, + 142285, 142290, 142295, 142300, 142305, 142310, 142315, 142320, 142325, + 142330, 142335, 142340, 142345, 142350, 142355, 142360, 142365, 142370, + 142375, 142380, 142385, 142390, 142395, 142400, 142405, 142410, 142415, + 142420, 142425, 142430, 142435, 142440, 142445, 142450, 142455, 142460, + 142465, 142470, 142475, 142480, 142485, 142490, 142497, 142504, 142511, + 142518, 142525, 142532, 142539, 142546, 142555, 142562, 142569, 142576, + 142583, 142590, 142597, 142604, 142611, 142618, 142625, 142632, 142637, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142646, 142651, 142655, 142659, 142663, + 142667, 142671, 142675, 142679, 142683, 0, 142687, 142692, 142697, + 142704, 142709, 142716, 142723, 0, 142728, 142735, 142740, 142745, + 142752, 142759, 142764, 142769, 142774, 142779, 142784, 142791, 142798, + 142803, 142808, 142813, 142826, 142835, 142842, 142851, 142860, 0, 0, 0, + 0, 0, 142869, 142876, 142883, 142890, 142897, 142904, 142911, 142918, + 142925, 142932, 142939, 142946, 142953, 142960, 142967, 142974, 142981, + 142988, 142995, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142958, 142964, 142970, 142976, - 142982, 142988, 142994, 143000, 143006, 143012, 143018, 143024, 143029, - 143035, 143040, 143046, 143051, 143057, 143063, 143068, 143074, 143079, - 143085, 143091, 143097, 143103, 143109, 143115, 143121, 143126, 143131, - 143137, 143143, 143149, 143155, 143161, 143167, 143173, 143179, 143185, - 143191, 143197, 143203, 143209, 143214, 143220, 143225, 143231, 143236, - 143242, 143248, 143253, 143259, 143264, 143270, 143276, 143282, 143288, - 143294, 143300, 143306, 143311, 143316, 143322, 143328, 143333, 143337, - 143341, 143345, 143349, 143353, 143357, 143361, 143365, 143369, 143374, - 143379, 143384, 143389, 143394, 143399, 143404, 143409, 143414, 143419, - 143426, 143433, 143440, 143444, 143450, 143455, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143002, 143008, 143014, 143020, + 143026, 143032, 143038, 143044, 143050, 143056, 143062, 143068, 143073, + 143079, 143084, 143090, 143095, 143101, 143107, 143112, 143118, 143123, + 143129, 143135, 143141, 143147, 143153, 143159, 143165, 143170, 143175, + 143181, 143187, 143193, 143199, 143205, 143211, 143217, 143223, 143229, + 143235, 143241, 143247, 143253, 143258, 143264, 143269, 143275, 143280, + 143286, 143292, 143297, 143303, 143308, 143314, 143320, 143326, 143332, + 143338, 143344, 143350, 143355, 143360, 143366, 143372, 143377, 143381, + 143385, 143389, 143393, 143397, 143401, 143405, 143409, 143413, 143418, + 143423, 143428, 143433, 143438, 143443, 143448, 143453, 143458, 143463, + 143470, 143477, 143484, 143488, 143494, 143499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143461, - 143464, 143468, 143472, 143476, 143479, 143483, 143488, 143492, 143496, - 143500, 143504, 143508, 143513, 143518, 143522, 143526, 143529, 143533, - 143538, 143543, 143547, 143551, 143554, 143558, 143562, 143566, 143570, - 143574, 143578, 143582, 143585, 143589, 143593, 143597, 143601, 143605, - 143609, 143615, 143618, 143622, 143626, 143630, 143634, 143638, 143642, - 143646, 143650, 143654, 143659, 143664, 143670, 143674, 143678, 143682, - 143686, 143690, 143694, 143699, 143702, 143706, 143710, 143714, 143718, - 143724, 143728, 143732, 143736, 143740, 143744, 143748, 143752, 143756, - 143760, 143764, 0, 0, 0, 0, 143768, 143773, 143777, 143781, 143787, - 143793, 143797, 143802, 143807, 143812, 143817, 143821, 143826, 143831, - 143836, 143840, 143845, 143850, 143855, 143859, 143864, 143869, 143874, - 143879, 143884, 143889, 143894, 143899, 143903, 143908, 143913, 143918, - 143923, 143928, 143933, 143938, 143943, 143948, 143953, 143958, 143965, - 143970, 143977, 143982, 143987, 143992, 143997, 144002, 144007, 144012, - 144017, 144022, 144027, 144032, 144037, 144042, 144047, 0, 0, 0, 0, 0, 0, - 0, 144052, 144055, 144060, 144063, 144066, 144070, 144074, 144078, - 144082, 144086, 144090, 144094, 144100, 144106, 144112, 144118, 144124, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143505, + 143508, 143512, 143516, 143520, 143523, 143527, 143532, 143536, 143540, + 143544, 143548, 143552, 143557, 143562, 143566, 143570, 143573, 143577, + 143582, 143587, 143591, 143595, 143598, 143602, 143606, 143610, 143614, + 143618, 143622, 143626, 143629, 143633, 143637, 143641, 143645, 143649, + 143653, 143659, 143662, 143666, 143670, 143674, 143678, 143682, 143686, + 143690, 143694, 143698, 143703, 143708, 143714, 143718, 143722, 143726, + 143730, 143734, 143738, 143743, 143746, 143750, 143754, 143758, 143762, + 143768, 143772, 143776, 143780, 143784, 143788, 143792, 143796, 143800, + 143804, 143808, 0, 0, 0, 0, 143812, 143817, 143821, 143825, 143831, + 143837, 143841, 143846, 143851, 143856, 143861, 143865, 143870, 143875, + 143880, 143884, 143889, 143894, 143899, 143903, 143908, 143913, 143918, + 143923, 143928, 143933, 143938, 143943, 143947, 143952, 143957, 143962, + 143967, 143972, 143977, 143982, 143987, 143992, 143997, 144002, 144009, + 144014, 144021, 144026, 144031, 144036, 144041, 144046, 144051, 144056, + 144061, 144066, 144071, 144076, 144081, 144086, 144091, 0, 0, 0, 0, 0, 0, + 0, 144096, 144099, 144104, 144107, 144110, 144114, 144118, 144122, + 144126, 144130, 144134, 144138, 144144, 144150, 144156, 144162, 144168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144130, 144134, 144138, - 144144, 144150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144155, 144164, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144173, 144176, 144179, 144182, 144185, - 144188, 144191, 144194, 144197, 144200, 144203, 144206, 144209, 144212, - 144215, 144218, 144221, 144224, 144227, 144230, 144233, 144236, 144239, - 144242, 144245, 144248, 144251, 144254, 144257, 144260, 144263, 144266, - 144269, 144272, 144275, 144278, 144281, 144284, 144287, 144290, 144293, - 144296, 144299, 144302, 144305, 144308, 144311, 144314, 144317, 144320, - 144323, 144326, 144329, 144332, 144335, 144338, 144341, 144344, 144347, - 144350, 144353, 144356, 144359, 144362, 144365, 144368, 144371, 144374, - 144377, 144380, 144383, 144386, 144389, 144392, 144395, 144398, 144401, - 144404, 144407, 144410, 144413, 144416, 144419, 144422, 144425, 144428, - 144431, 144434, 144437, 144440, 144443, 144446, 144449, 144452, 144455, - 144458, 144461, 144464, 144467, 144470, 144473, 144476, 144479, 144482, - 144485, 144488, 144491, 144494, 144497, 144500, 144503, 144506, 144509, - 144512, 144515, 144518, 144521, 144524, 144527, 144530, 144533, 144536, - 144539, 144542, 144545, 144548, 144551, 144554, 144557, 144560, 144563, - 144566, 144569, 144572, 144575, 144578, 144581, 144584, 144587, 144590, - 144593, 144596, 144599, 144602, 144605, 144608, 144611, 144614, 144617, - 144620, 144623, 144626, 144629, 144632, 144635, 144638, 144641, 144644, - 144647, 144650, 144653, 144656, 144659, 144662, 144665, 144668, 144671, - 144674, 144677, 144680, 144683, 144686, 144689, 144692, 144695, 144698, - 144701, 144704, 144707, 144710, 144713, 144716, 144719, 144722, 144725, - 144728, 144731, 144734, 144737, 144740, 144743, 144746, 144749, 144752, - 144755, 144758, 144761, 144764, 144767, 144770, 144773, 144776, 144779, - 144782, 144785, 144788, 144791, 144794, 144797, 144800, 144803, 144806, - 144809, 144812, 144815, 144818, 144821, 144824, 144827, 144830, 144833, - 144836, 144839, 144842, 144845, 144848, 144851, 144854, 144857, 144860, - 144863, 144866, 144869, 144872, 144875, 144878, 144881, 144884, 144887, - 144890, 144893, 144896, 144899, 144902, 144905, 144908, 144911, 144914, - 144917, 144920, 144923, 144926, 144929, 144932, 144935, 144938, 144941, - 144944, 144947, 144950, 144953, 144956, 144959, 144962, 144965, 144968, - 144971, 144974, 144977, 144980, 144983, 144986, 144989, 144992, 144995, - 144998, 145001, 145004, 145007, 145010, 145013, 145016, 145019, 145022, - 145025, 145028, 145031, 145034, 145037, 145040, 145043, 145046, 145049, - 145052, 145055, 145058, 145061, 145064, 145067, 145070, 145073, 145076, - 145079, 145082, 145085, 145088, 145091, 145094, 145097, 145100, 145103, - 145106, 145109, 145112, 145115, 145118, 145121, 145124, 145127, 145130, - 145133, 145136, 145139, 145142, 145145, 145148, 145151, 145154, 145157, - 145160, 145163, 145166, 145169, 145172, 145175, 145178, 145181, 145184, - 145187, 145190, 145193, 145196, 145199, 145202, 145205, 145208, 145211, - 145214, 145217, 145220, 145223, 145226, 145229, 145232, 145235, 145238, - 145241, 145244, 145247, 145250, 145253, 145256, 145259, 145262, 145265, - 145268, 145271, 145274, 145277, 145280, 145283, 145286, 145289, 145292, - 145295, 145298, 145301, 145304, 145307, 145310, 145313, 145316, 145319, - 145322, 145325, 145328, 145331, 145334, 145337, 145340, 145343, 145346, - 145349, 145352, 145355, 145358, 145361, 145364, 145367, 145370, 145373, - 145376, 145379, 145382, 145385, 145388, 145391, 145394, 145397, 145400, - 145403, 145406, 145409, 145412, 145415, 145418, 145421, 145424, 145427, - 145430, 145433, 145436, 145439, 145442, 145445, 145448, 145451, 145454, - 145457, 145460, 145463, 145466, 145469, 145472, 145475, 145478, 145481, - 145484, 145487, 145490, 145493, 145496, 145499, 145502, 145505, 145508, - 145511, 145514, 145517, 145520, 145523, 145526, 145529, 145532, 145535, - 145538, 145541, 145544, 145547, 145550, 145553, 145556, 145559, 145562, - 145565, 145568, 145571, 145574, 145577, 145580, 145583, 145586, 145589, - 145592, 145595, 145598, 145601, 145604, 145607, 145610, 145613, 145616, - 145619, 145622, 145625, 145628, 145631, 145634, 145637, 145640, 145643, - 145646, 145649, 145652, 145655, 145658, 145661, 145664, 145667, 145670, - 145673, 145676, 145679, 145682, 145685, 145688, 145691, 145694, 145697, - 145700, 145703, 145706, 145709, 145712, 145715, 145718, 145721, 145724, - 145727, 145730, 145733, 145736, 145739, 145742, 145745, 145748, 145751, - 145754, 145757, 145760, 145763, 145766, 145769, 145772, 145775, 145778, - 145781, 145784, 145787, 145790, 145793, 145796, 145799, 145802, 145805, - 145808, 145811, 145814, 145817, 145820, 145823, 145826, 145829, 145832, - 145835, 145838, 145841, 145844, 145847, 145850, 145853, 145856, 145859, - 145862, 145865, 145868, 145871, 145874, 145877, 145880, 145883, 145886, - 145889, 145892, 145895, 145898, 145901, 145904, 145907, 145910, 145913, - 145916, 145919, 145922, 145925, 145928, 145931, 145934, 145937, 145940, - 145943, 145946, 145949, 145952, 145955, 145958, 145961, 145964, 145967, - 145970, 145973, 145976, 145979, 145982, 145985, 145988, 145991, 145994, - 145997, 146000, 146003, 146006, 146009, 146012, 146015, 146018, 146021, - 146024, 146027, 146030, 146033, 146036, 146039, 146042, 146045, 146048, - 146051, 146054, 146057, 146060, 146063, 146066, 146069, 146072, 146075, - 146078, 146081, 146084, 146087, 146090, 146093, 146096, 146099, 146102, - 146105, 146108, 146111, 146114, 146117, 146120, 146123, 146126, 146129, - 146132, 146135, 146138, 146141, 146144, 146147, 146150, 146153, 146156, - 146159, 146162, 146165, 146168, 146171, 146174, 146177, 146180, 146183, - 146186, 146189, 146192, 146195, 146198, 146201, 146204, 146207, 146210, - 146213, 146216, 146219, 146222, 146225, 146228, 146231, 146234, 146237, - 146240, 146243, 146246, 146249, 146252, 146255, 146258, 146261, 146264, - 146267, 146270, 146273, 146276, 146279, 146282, 146285, 146288, 146291, - 146294, 146297, 146300, 146303, 146306, 146309, 146312, 146315, 146318, - 146321, 146324, 146327, 146330, 146333, 146336, 146339, 146342, 146345, - 146348, 146351, 146354, 146357, 146360, 146363, 146366, 146369, 146372, - 146375, 146378, 146381, 146384, 146387, 146390, 146393, 146396, 146399, - 146402, 146405, 146408, 146411, 146414, 146417, 146420, 146423, 146426, - 146429, 146432, 146435, 146438, 146441, 146444, 146447, 146450, 146453, - 146456, 146459, 146462, 146465, 146468, 146471, 146474, 146477, 146482, - 146487, 146492, 146497, 146502, 146507, 146512, 146517, 146522, 146527, - 146532, 146537, 146542, 146547, 146552, 146557, 146562, 146567, 146572, - 146577, 146582, 146587, 146592, 146597, 146602, 146607, 146612, 146617, - 146622, 146627, 146632, 146637, 146642, 146647, 146652, 146657, 146662, - 146667, 146672, 146677, 146682, 146687, 146692, 146697, 146702, 146707, - 146712, 146717, 146722, 146727, 146732, 146737, 146742, 146747, 146752, - 146757, 146762, 146767, 146772, 146777, 146782, 146787, 146792, 146797, - 146802, 146807, 146812, 146817, 146822, 146827, 146832, 146837, 146842, - 146847, 146852, 146857, 146862, 146867, 146872, 146877, 146882, 146887, - 146892, 146897, 146902, 146907, 146912, 146917, 146922, 146927, 146932, - 146937, 146942, 146947, 146952, 146957, 146962, 146967, 146972, 146977, - 146982, 146987, 146992, 146997, 147002, 147007, 147012, 147017, 147022, - 147027, 147032, 147037, 147042, 147047, 147052, 147057, 147062, 147067, - 147072, 147077, 147082, 147087, 147092, 147097, 147102, 147107, 147112, - 147117, 147122, 147127, 147132, 147137, 147142, 147147, 147152, 147157, - 147162, 147167, 147172, 147177, 147182, 147187, 147192, 147197, 147202, - 147207, 147212, 147217, 147222, 147227, 147232, 147237, 147242, 147247, - 147252, 147257, 147262, 147267, 147272, 147277, 147282, 147287, 147292, - 147297, 147302, 147307, 147312, 147317, 147322, 147327, 147332, 147337, - 147342, 147347, 147352, 147357, 147362, 147367, 147372, 147377, 147382, - 147387, 147392, 147397, 147402, 147407, 147412, 147417, 147422, 147427, - 147432, 147437, 147442, 147447, 147452, 147457, 147462, 147467, 147472, - 147477, 147482, 147487, 147492, 147497, 147502, 147507, 147512, 147517, - 147522, 147527, 147532, 147537, 147542, 147547, 147552, 147557, 147562, - 147567, 147572, 147577, 147582, 147587, 147592, 147597, 147602, 147607, - 147612, 147617, 147622, 147627, 147632, 147637, 147642, 147647, 147652, - 147657, 147662, 147667, 147672, 147677, 147682, 147687, 147692, 147697, - 147702, 147707, 147712, 147717, 147722, 147727, 147732, 147737, 147742, - 147747, 147752, 147757, 147762, 147767, 147772, 147777, 147782, 147787, - 147792, 147797, 147802, 147807, 147812, 147817, 147822, 147827, 147832, - 147837, 147842, 147847, 147852, 147857, 147862, 147867, 147872, 147877, - 147882, 147887, 147892, 147897, 147902, 147907, 147912, 147917, 147922, - 147927, 147932, 147937, 147942, 147947, 147952, 147957, 147962, 147967, - 147972, 147977, 147982, 147987, 147992, 147997, 148002, 148007, 148012, - 148017, 148022, 148027, 148032, 148037, 148042, 148047, 148052, 148057, - 148062, 148067, 148072, 148077, 148082, 148087, 148092, 148097, 148102, - 148107, 148112, 148117, 148122, 148127, 148132, 148137, 148142, 148147, - 148152, 148157, 148162, 148167, 148172, 148177, 148182, 148187, 148192, - 148197, 148202, 148207, 148212, 148217, 148222, 148227, 148232, 148237, - 148242, 148247, 148252, 148257, 148262, 148267, 148272, 148277, 148282, - 148287, 148292, 148297, 148302, 148307, 148312, 148317, 148322, 148327, - 148332, 148337, 148342, 148347, 148352, 148357, 148362, 148367, 148372, - 148377, 148382, 148387, 148392, 148397, 148402, 148407, 148412, 148417, - 148422, 148427, 148432, 148437, 148442, 148447, 148452, 148457, 148462, - 148467, 148472, 148477, 148482, 148487, 148492, 148497, 148502, 148507, - 148512, 148517, 148522, 148527, 148532, 148537, 148542, 148547, 148552, - 148557, 148562, 148567, 148572, 148577, 148582, 148587, 148592, 148597, - 148602, 148607, 148612, 148617, 148622, 148627, 148632, 148637, 148642, - 148647, 148652, 148657, 148662, 148667, 148672, 148677, 148682, 148687, - 148692, 148697, 148702, 148707, 148712, 148717, 148722, 148727, 148732, - 148737, 148742, 148747, 148752, 148757, 148762, 148767, 148772, 148777, - 148782, 148787, 148792, 148797, 148802, 148807, 148812, 148817, 148822, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144174, 144178, 144182, + 144188, 144194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144199, 144208, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144217, 144220, 144223, 144226, 144229, + 144232, 144235, 144238, 144241, 144244, 144247, 144250, 144253, 144256, + 144259, 144262, 144265, 144268, 144271, 144274, 144277, 144280, 144283, + 144286, 144289, 144292, 144295, 144298, 144301, 144304, 144307, 144310, + 144313, 144316, 144319, 144322, 144325, 144328, 144331, 144334, 144337, + 144340, 144343, 144346, 144349, 144352, 144355, 144358, 144361, 144364, + 144367, 144370, 144373, 144376, 144379, 144382, 144385, 144388, 144391, + 144394, 144397, 144400, 144403, 144406, 144409, 144412, 144415, 144418, + 144421, 144424, 144427, 144430, 144433, 144436, 144439, 144442, 144445, + 144448, 144451, 144454, 144457, 144460, 144463, 144466, 144469, 144472, + 144475, 144478, 144481, 144484, 144487, 144490, 144493, 144496, 144499, + 144502, 144505, 144508, 144511, 144514, 144517, 144520, 144523, 144526, + 144529, 144532, 144535, 144538, 144541, 144544, 144547, 144550, 144553, + 144556, 144559, 144562, 144565, 144568, 144571, 144574, 144577, 144580, + 144583, 144586, 144589, 144592, 144595, 144598, 144601, 144604, 144607, + 144610, 144613, 144616, 144619, 144622, 144625, 144628, 144631, 144634, + 144637, 144640, 144643, 144646, 144649, 144652, 144655, 144658, 144661, + 144664, 144667, 144670, 144673, 144676, 144679, 144682, 144685, 144688, + 144691, 144694, 144697, 144700, 144703, 144706, 144709, 144712, 144715, + 144718, 144721, 144724, 144727, 144730, 144733, 144736, 144739, 144742, + 144745, 144748, 144751, 144754, 144757, 144760, 144763, 144766, 144769, + 144772, 144775, 144778, 144781, 144784, 144787, 144790, 144793, 144796, + 144799, 144802, 144805, 144808, 144811, 144814, 144817, 144820, 144823, + 144826, 144829, 144832, 144835, 144838, 144841, 144844, 144847, 144850, + 144853, 144856, 144859, 144862, 144865, 144868, 144871, 144874, 144877, + 144880, 144883, 144886, 144889, 144892, 144895, 144898, 144901, 144904, + 144907, 144910, 144913, 144916, 144919, 144922, 144925, 144928, 144931, + 144934, 144937, 144940, 144943, 144946, 144949, 144952, 144955, 144958, + 144961, 144964, 144967, 144970, 144973, 144976, 144979, 144982, 144985, + 144988, 144991, 144994, 144997, 145000, 145003, 145006, 145009, 145012, + 145015, 145018, 145021, 145024, 145027, 145030, 145033, 145036, 145039, + 145042, 145045, 145048, 145051, 145054, 145057, 145060, 145063, 145066, + 145069, 145072, 145075, 145078, 145081, 145084, 145087, 145090, 145093, + 145096, 145099, 145102, 145105, 145108, 145111, 145114, 145117, 145120, + 145123, 145126, 145129, 145132, 145135, 145138, 145141, 145144, 145147, + 145150, 145153, 145156, 145159, 145162, 145165, 145168, 145171, 145174, + 145177, 145180, 145183, 145186, 145189, 145192, 145195, 145198, 145201, + 145204, 145207, 145210, 145213, 145216, 145219, 145222, 145225, 145228, + 145231, 145234, 145237, 145240, 145243, 145246, 145249, 145252, 145255, + 145258, 145261, 145264, 145267, 145270, 145273, 145276, 145279, 145282, + 145285, 145288, 145291, 145294, 145297, 145300, 145303, 145306, 145309, + 145312, 145315, 145318, 145321, 145324, 145327, 145330, 145333, 145336, + 145339, 145342, 145345, 145348, 145351, 145354, 145357, 145360, 145363, + 145366, 145369, 145372, 145375, 145378, 145381, 145384, 145387, 145390, + 145393, 145396, 145399, 145402, 145405, 145408, 145411, 145414, 145417, + 145420, 145423, 145426, 145429, 145432, 145435, 145438, 145441, 145444, + 145447, 145450, 145453, 145456, 145459, 145462, 145465, 145468, 145471, + 145474, 145477, 145480, 145483, 145486, 145489, 145492, 145495, 145498, + 145501, 145504, 145507, 145510, 145513, 145516, 145519, 145522, 145525, + 145528, 145531, 145534, 145537, 145540, 145543, 145546, 145549, 145552, + 145555, 145558, 145561, 145564, 145567, 145570, 145573, 145576, 145579, + 145582, 145585, 145588, 145591, 145594, 145597, 145600, 145603, 145606, + 145609, 145612, 145615, 145618, 145621, 145624, 145627, 145630, 145633, + 145636, 145639, 145642, 145645, 145648, 145651, 145654, 145657, 145660, + 145663, 145666, 145669, 145672, 145675, 145678, 145681, 145684, 145687, + 145690, 145693, 145696, 145699, 145702, 145705, 145708, 145711, 145714, + 145717, 145720, 145723, 145726, 145729, 145732, 145735, 145738, 145741, + 145744, 145747, 145750, 145753, 145756, 145759, 145762, 145765, 145768, + 145771, 145774, 145777, 145780, 145783, 145786, 145789, 145792, 145795, + 145798, 145801, 145804, 145807, 145810, 145813, 145816, 145819, 145822, + 145825, 145828, 145831, 145834, 145837, 145840, 145843, 145846, 145849, + 145852, 145855, 145858, 145861, 145864, 145867, 145870, 145873, 145876, + 145879, 145882, 145885, 145888, 145891, 145894, 145897, 145900, 145903, + 145906, 145909, 145912, 145915, 145918, 145921, 145924, 145927, 145930, + 145933, 145936, 145939, 145942, 145945, 145948, 145951, 145954, 145957, + 145960, 145963, 145966, 145969, 145972, 145975, 145978, 145981, 145984, + 145987, 145990, 145993, 145996, 145999, 146002, 146005, 146008, 146011, + 146014, 146017, 146020, 146023, 146026, 146029, 146032, 146035, 146038, + 146041, 146044, 146047, 146050, 146053, 146056, 146059, 146062, 146065, + 146068, 146071, 146074, 146077, 146080, 146083, 146086, 146089, 146092, + 146095, 146098, 146101, 146104, 146107, 146110, 146113, 146116, 146119, + 146122, 146125, 146128, 146131, 146134, 146137, 146140, 146143, 146146, + 146149, 146152, 146155, 146158, 146161, 146164, 146167, 146170, 146173, + 146176, 146179, 146182, 146185, 146188, 146191, 146194, 146197, 146200, + 146203, 146206, 146209, 146212, 146215, 146218, 146221, 146224, 146227, + 146230, 146233, 146236, 146239, 146242, 146245, 146248, 146251, 146254, + 146257, 146260, 146263, 146266, 146269, 146272, 146275, 146278, 146281, + 146284, 146287, 146290, 146293, 146296, 146299, 146302, 146305, 146308, + 146311, 146314, 146317, 146320, 146323, 146326, 146329, 146332, 146335, + 146338, 146341, 146344, 146347, 146350, 146353, 146356, 146359, 146362, + 146365, 146368, 146371, 146374, 146377, 146380, 146383, 146386, 146389, + 146392, 146395, 146398, 146401, 146404, 146407, 146410, 146413, 146416, + 146419, 146422, 146425, 146428, 146431, 146434, 146437, 146440, 146443, + 146446, 146449, 146452, 146455, 146458, 146461, 146464, 146467, 146470, + 146473, 146476, 146479, 146482, 146485, 146488, 146491, 146494, 146497, + 146500, 146503, 146506, 146509, 146512, 146515, 146518, 146521, 146526, + 146531, 146536, 146541, 146546, 146551, 146556, 146561, 146566, 146571, + 146576, 146581, 146586, 146591, 146596, 146601, 146606, 146611, 146616, + 146621, 146626, 146631, 146636, 146641, 146646, 146651, 146656, 146661, + 146666, 146671, 146676, 146681, 146686, 146691, 146696, 146701, 146706, + 146711, 146716, 146721, 146726, 146731, 146736, 146741, 146746, 146751, + 146756, 146761, 146766, 146771, 146776, 146781, 146786, 146791, 146796, + 146801, 146806, 146811, 146816, 146821, 146826, 146831, 146836, 146841, + 146846, 146851, 146856, 146861, 146866, 146871, 146876, 146881, 146886, + 146891, 146896, 146901, 146906, 146911, 146916, 146921, 146926, 146931, + 146936, 146941, 146946, 146951, 146956, 146961, 146966, 146971, 146976, + 146981, 146986, 146991, 146996, 147001, 147006, 147011, 147016, 147021, + 147026, 147031, 147036, 147041, 147046, 147051, 147056, 147061, 147066, + 147071, 147076, 147081, 147086, 147091, 147096, 147101, 147106, 147111, + 147116, 147121, 147126, 147131, 147136, 147141, 147146, 147151, 147156, + 147161, 147166, 147171, 147176, 147181, 147186, 147191, 147196, 147201, + 147206, 147211, 147216, 147221, 147226, 147231, 147236, 147241, 147246, + 147251, 147256, 147261, 147266, 147271, 147276, 147281, 147286, 147291, + 147296, 147301, 147306, 147311, 147316, 147321, 147326, 147331, 147336, + 147341, 147346, 147351, 147356, 147361, 147366, 147371, 147376, 147381, + 147386, 147391, 147396, 147401, 147406, 147411, 147416, 147421, 147426, + 147431, 147436, 147441, 147446, 147451, 147456, 147461, 147466, 147471, + 147476, 147481, 147486, 147491, 147496, 147501, 147506, 147511, 147516, + 147521, 147526, 147531, 147536, 147541, 147546, 147551, 147556, 147561, + 147566, 147571, 147576, 147581, 147586, 147591, 147596, 147601, 147606, + 147611, 147616, 147621, 147626, 147631, 147636, 147641, 147646, 147651, + 147656, 147661, 147666, 147671, 147676, 147681, 147686, 147691, 147696, + 147701, 147706, 147711, 147716, 147721, 147726, 147731, 147736, 147741, + 147746, 147751, 147756, 147761, 147766, 147771, 147776, 147781, 147786, + 147791, 147796, 147801, 147806, 147811, 147816, 147821, 147826, 147831, + 147836, 147841, 147846, 147851, 147856, 147861, 147866, 147871, 147876, + 147881, 147886, 147891, 147896, 147901, 147906, 147911, 147916, 147921, + 147926, 147931, 147936, 147941, 147946, 147951, 147956, 147961, 147966, + 147971, 147976, 147981, 147986, 147991, 147996, 148001, 148006, 148011, + 148016, 148021, 148026, 148031, 148036, 148041, 148046, 148051, 148056, + 148061, 148066, 148071, 148076, 148081, 148086, 148091, 148096, 148101, + 148106, 148111, 148116, 148121, 148126, 148131, 148136, 148141, 148146, + 148151, 148156, 148161, 148166, 148171, 148176, 148181, 148186, 148191, + 148196, 148201, 148206, 148211, 148216, 148221, 148226, 148231, 148236, + 148241, 148246, 148251, 148256, 148261, 148266, 148271, 148276, 148281, + 148286, 148291, 148296, 148301, 148306, 148311, 148316, 148321, 148326, + 148331, 148336, 148341, 148346, 148351, 148356, 148361, 148366, 148371, + 148376, 148381, 148386, 148391, 148396, 148401, 148406, 148411, 148416, + 148421, 148426, 148431, 148436, 148441, 148446, 148451, 148456, 148461, + 148466, 148471, 148476, 148481, 148486, 148491, 148496, 148501, 148506, + 148511, 148516, 148521, 148526, 148531, 148536, 148541, 148546, 148551, + 148556, 148561, 148566, 148571, 148576, 148581, 148586, 148591, 148596, + 148601, 148606, 148611, 148616, 148621, 148626, 148631, 148636, 148641, + 148646, 148651, 148656, 148661, 148666, 148671, 148676, 148681, 148686, + 148691, 148696, 148701, 148706, 148711, 148716, 148721, 148726, 148731, + 148736, 148741, 148746, 148751, 148756, 148761, 148766, 148771, 148776, + 148781, 148786, 148791, 148796, 148801, 148806, 148811, 148816, 148821, + 148826, 148831, 148836, 148841, 148846, 148851, 148856, 148861, 148866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148827, 148833, 148839, 148845, 0, 148851, - 148857, 148863, 148871, 148879, 148887, 148895, 0, 148903, 148911, 0, - 148919, 148924, 148931, 148935, 148939, 148943, 148947, 148951, 148955, - 148959, 148963, 148967, 148971, 148975, 148979, 148983, 148987, 148991, - 148995, 148999, 149003, 149007, 149011, 149015, 149019, 149023, 149027, - 149031, 149035, 149039, 149043, 149047, 149051, 149055, 149059, 149063, - 149067, 149071, 149075, 149079, 149083, 149087, 149091, 149095, 149099, - 149103, 149107, 149111, 149115, 149119, 149123, 149127, 149131, 149135, - 149139, 149143, 149147, 149151, 149155, 149159, 149163, 149167, 149171, - 149175, 149179, 149183, 149187, 149191, 149195, 149199, 149203, 149207, - 149211, 149215, 149219, 149223, 149227, 149231, 149235, 149239, 149243, - 149247, 149251, 149255, 149259, 149263, 149267, 149271, 149275, 149279, - 149283, 149287, 149291, 149295, 149299, 149303, 149307, 149311, 149315, - 149319, 149323, 149327, 149331, 149335, 149339, 149343, 149347, 149351, - 149355, 149359, 149363, 149367, 149371, 149375, 149379, 149383, 149387, - 149391, 149395, 149399, 149403, 149407, 149411, 149415, 149419, 149423, - 149427, 149431, 149435, 149439, 149443, 149447, 149451, 149455, 149459, - 149463, 149467, 149471, 149475, 149479, 149483, 149487, 149491, 149495, - 149499, 149503, 149507, 149511, 149515, 149519, 149523, 149527, 149531, - 149535, 149539, 149543, 149547, 149551, 149555, 149559, 149563, 149567, - 149571, 149575, 149579, 149583, 149587, 149591, 149595, 149599, 149603, - 149607, 149611, 149615, 149619, 149623, 149627, 149631, 149635, 149639, - 149643, 149647, 149651, 149655, 149659, 149663, 149667, 149671, 149675, - 149679, 149683, 149687, 149691, 149695, 149699, 149703, 149707, 149711, - 149715, 149719, 149723, 149727, 149731, 149735, 149739, 149743, 149747, - 149751, 149755, 149759, 149763, 149767, 149771, 149775, 149779, 149783, - 149787, 149791, 149795, 149799, 149803, 149807, 149811, 149815, 149819, - 149823, 149827, 149831, 149835, 149839, 149843, 149847, 149851, 149855, - 149859, 149863, 149867, 149871, 149875, 149879, 149883, 149887, 149891, - 149895, 149899, 149903, 149907, 149911, 149915, 149919, 149923, 149927, - 149931, 149935, 149939, 149943, 149947, 149951, 149955, 149959, 149963, - 149967, 149971, 149975, 149979, 149983, 149987, 149991, 149995, 149999, - 150003, 150007, 150011, 150015, 150019, 150023, 150027, 150031, 150035, - 150039, 150043, 150047, 150051, 150055, 150059, 150063, 150067, 150071, - 150078, 150084, 150090, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 150096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 150102, 150108, 150114, 0, 0, 150120, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 150125, 150130, 150135, 150140, 0, 0, 0, 0, 0, - 0, 0, 0, 150145, 150148, 150151, 150154, 150157, 150160, 150163, 150166, - 150169, 150172, 150175, 150178, 150181, 150184, 150187, 150190, 150193, - 150196, 150199, 150202, 150205, 150208, 150211, 150214, 150217, 150220, - 150223, 150226, 150229, 150232, 150235, 150238, 150241, 150244, 150247, - 150250, 150253, 150256, 150259, 150262, 150265, 150268, 150271, 150274, - 150277, 150280, 150283, 150286, 150289, 150292, 150295, 150298, 150301, - 150304, 150307, 150310, 150313, 150316, 150319, 150322, 150325, 150328, - 150331, 150334, 150337, 150340, 150343, 150346, 150349, 150352, 150355, - 150358, 150361, 150364, 150367, 150370, 150373, 150376, 150379, 150382, - 150385, 150388, 150391, 150394, 150397, 150400, 150403, 150406, 150409, - 150412, 150415, 150418, 150421, 150424, 150427, 150430, 150433, 150436, - 150439, 150442, 150445, 150448, 150451, 150454, 150457, 150460, 150463, - 150466, 150469, 150472, 150475, 150478, 150481, 150484, 150487, 150490, - 150493, 150496, 150499, 150502, 150505, 150508, 150511, 150514, 150517, - 150520, 150523, 150526, 150529, 150532, 150535, 150538, 150541, 150544, - 150547, 150550, 150553, 150556, 150559, 150562, 150565, 150568, 150571, - 150574, 150577, 150580, 150583, 150586, 150589, 150592, 150595, 150598, - 150601, 150604, 150607, 150610, 150613, 150616, 150619, 150622, 150625, - 150628, 150631, 150634, 150637, 150640, 150643, 150646, 150649, 150652, - 150655, 150658, 150661, 150664, 150667, 150670, 150673, 150676, 150679, - 150682, 150685, 150688, 150691, 150694, 150697, 150700, 150703, 150706, - 150709, 150712, 150715, 150718, 150721, 150724, 150727, 150730, 150733, - 150736, 150739, 150742, 150745, 150748, 150751, 150754, 150757, 150760, - 150763, 150766, 150769, 150772, 150775, 150778, 150781, 150784, 150787, - 150790, 150793, 150796, 150799, 150802, 150805, 150808, 150811, 150814, - 150817, 150820, 150823, 150826, 150829, 150832, 150835, 150838, 150841, - 150844, 150847, 150850, 150853, 150856, 150859, 150862, 150865, 150868, - 150871, 150874, 150877, 150880, 150883, 150886, 150889, 150892, 150895, - 150898, 150901, 150904, 150907, 150910, 150913, 150916, 150919, 150922, - 150925, 150928, 150931, 150934, 150937, 150940, 150943, 150946, 150949, - 150952, 150955, 150958, 150961, 150964, 150967, 150970, 150973, 150976, - 150979, 150982, 150985, 150988, 150991, 150994, 150997, 151000, 151003, - 151006, 151009, 151012, 151015, 151018, 151021, 151024, 151027, 151030, - 151033, 151036, 151039, 151042, 151045, 151048, 151051, 151054, 151057, - 151060, 151063, 151066, 151069, 151072, 151075, 151078, 151081, 151084, - 151087, 151090, 151093, 151096, 151099, 151102, 151105, 151108, 151111, - 151114, 151117, 151120, 151123, 151126, 151129, 151132, 151135, 151138, - 151141, 151144, 151147, 151150, 151153, 151156, 151159, 151162, 151165, - 151168, 151171, 151174, 151177, 151180, 151183, 151186, 151189, 151192, - 151195, 151198, 151201, 151204, 151207, 151210, 151213, 151216, 151219, - 151222, 151225, 151228, 151231, 151234, 151237, 151240, 151243, 151246, - 151249, 151252, 151255, 151258, 151261, 151264, 151267, 151270, 151273, - 151276, 151279, 151282, 151285, 151288, 151291, 151294, 151297, 151300, - 151303, 151306, 151309, 151312, 151315, 151318, 151321, 151324, 151327, - 151330, 0, 0, 0, 0, 151333, 151337, 151341, 151345, 151349, 151353, - 151357, 151360, 151364, 151368, 151372, 151376, 151379, 151385, 151391, - 151397, 151403, 151409, 151413, 151419, 151423, 151427, 151433, 151437, - 151441, 151445, 151449, 151453, 151457, 151461, 151467, 151473, 151479, - 151485, 151492, 151499, 151506, 151516, 151523, 151530, 151536, 151542, - 151548, 151554, 151562, 151570, 151578, 151586, 151595, 151601, 151609, - 151615, 151622, 151628, 151635, 151641, 151649, 151653, 151657, 151662, - 151668, 151674, 151682, 151690, 151696, 151703, 151706, 151712, 151716, - 151719, 151723, 151726, 151729, 151733, 151738, 151742, 151746, 151752, - 151757, 151763, 151767, 151771, 151774, 151778, 151782, 151787, 151791, - 151796, 151800, 151805, 151809, 151813, 151817, 151821, 151825, 151829, - 151833, 151837, 151842, 151847, 151852, 151857, 151863, 151869, 151875, - 151881, 151887, 0, 0, 0, 0, 0, 151892, 151900, 151909, 151917, 151924, - 151932, 151939, 151946, 151955, 151962, 151969, 151977, 151985, 0, 0, 0, - 151993, 151999, 152007, 152013, 152020, 152026, 152032, 152038, 152044, - 0, 0, 0, 0, 0, 0, 0, 152050, 152056, 152064, 152070, 152077, 152083, - 152089, 152095, 152101, 152107, 0, 0, 152112, 152118, 152124, 152127, - 152136, 152143, 152151, 152158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148871, 148877, 148883, 148889, 0, 148895, + 148901, 148907, 148915, 148923, 148931, 148939, 0, 148947, 148955, 0, + 148963, 148968, 148975, 148979, 148983, 148987, 148991, 148995, 148999, + 149003, 149007, 149011, 149015, 149019, 149023, 149027, 149031, 149035, + 149039, 149043, 149047, 149051, 149055, 149059, 149063, 149067, 149071, + 149075, 149079, 149083, 149087, 149091, 149095, 149099, 149103, 149107, + 149111, 149115, 149119, 149123, 149127, 149131, 149135, 149139, 149143, + 149147, 149151, 149155, 149159, 149163, 149167, 149171, 149175, 149179, + 149183, 149187, 149191, 149195, 149199, 149203, 149207, 149211, 149215, + 149219, 149223, 149227, 149231, 149235, 149239, 149243, 149247, 149251, + 149255, 149259, 149263, 149267, 149271, 149275, 149279, 149283, 149287, + 149291, 149295, 149299, 149303, 149307, 149311, 149315, 149319, 149323, + 149327, 149331, 149335, 149339, 149343, 149347, 149351, 149355, 149359, + 149363, 149367, 149371, 149375, 149379, 149383, 149387, 149391, 149395, + 149399, 149403, 149407, 149411, 149415, 149419, 149423, 149427, 149431, + 149435, 149439, 149443, 149447, 149451, 149455, 149459, 149463, 149467, + 149471, 149475, 149479, 149483, 149487, 149491, 149495, 149499, 149503, + 149507, 149511, 149515, 149519, 149523, 149527, 149531, 149535, 149539, + 149543, 149547, 149551, 149555, 149559, 149563, 149567, 149571, 149575, + 149579, 149583, 149587, 149591, 149595, 149599, 149603, 149607, 149611, + 149615, 149619, 149623, 149627, 149631, 149635, 149639, 149643, 149647, + 149651, 149655, 149659, 149663, 149667, 149671, 149675, 149679, 149683, + 149687, 149691, 149695, 149699, 149703, 149707, 149711, 149715, 149719, + 149723, 149727, 149731, 149735, 149739, 149743, 149747, 149751, 149755, + 149759, 149763, 149767, 149771, 149775, 149779, 149783, 149787, 149791, + 149795, 149799, 149803, 149807, 149811, 149815, 149819, 149823, 149827, + 149831, 149835, 149839, 149843, 149847, 149851, 149855, 149859, 149863, + 149867, 149871, 149875, 149879, 149883, 149887, 149891, 149895, 149899, + 149903, 149907, 149911, 149915, 149919, 149923, 149927, 149931, 149935, + 149939, 149943, 149947, 149951, 149955, 149959, 149963, 149967, 149971, + 149975, 149979, 149983, 149987, 149991, 149995, 149999, 150003, 150007, + 150011, 150015, 150019, 150023, 150027, 150031, 150035, 150039, 150043, + 150047, 150051, 150055, 150059, 150063, 150067, 150071, 150075, 150079, + 150083, 150087, 150091, 150095, 150099, 150103, 150107, 150111, 150115, + 150122, 150128, 150134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 150146, 150152, 150158, 0, 0, 150164, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 150169, 150174, 150179, 150184, 0, 0, 0, 0, 0, + 0, 0, 0, 150189, 150192, 150195, 150198, 150201, 150204, 150207, 150210, + 150213, 150216, 150219, 150222, 150225, 150228, 150231, 150234, 150237, + 150240, 150243, 150246, 150249, 150252, 150255, 150258, 150261, 150264, + 150267, 150270, 150273, 150276, 150279, 150282, 150285, 150288, 150291, + 150294, 150297, 150300, 150303, 150306, 150309, 150312, 150315, 150318, + 150321, 150324, 150327, 150330, 150333, 150336, 150339, 150342, 150345, + 150348, 150351, 150354, 150357, 150360, 150363, 150366, 150369, 150372, + 150375, 150378, 150381, 150384, 150387, 150390, 150393, 150396, 150399, + 150402, 150405, 150408, 150411, 150414, 150417, 150420, 150423, 150426, + 150429, 150432, 150435, 150438, 150441, 150444, 150447, 150450, 150453, + 150456, 150459, 150462, 150465, 150468, 150471, 150474, 150477, 150480, + 150483, 150486, 150489, 150492, 150495, 150498, 150501, 150504, 150507, + 150510, 150513, 150516, 150519, 150522, 150525, 150528, 150531, 150534, + 150537, 150540, 150543, 150546, 150549, 150552, 150555, 150558, 150561, + 150564, 150567, 150570, 150573, 150576, 150579, 150582, 150585, 150588, + 150591, 150594, 150597, 150600, 150603, 150606, 150609, 150612, 150615, + 150618, 150621, 150624, 150627, 150630, 150633, 150636, 150639, 150642, + 150645, 150648, 150651, 150654, 150657, 150660, 150663, 150666, 150669, + 150672, 150675, 150678, 150681, 150684, 150687, 150690, 150693, 150696, + 150699, 150702, 150705, 150708, 150711, 150714, 150717, 150720, 150723, + 150726, 150729, 150732, 150735, 150738, 150741, 150744, 150747, 150750, + 150753, 150756, 150759, 150762, 150765, 150768, 150771, 150774, 150777, + 150780, 150783, 150786, 150789, 150792, 150795, 150798, 150801, 150804, + 150807, 150810, 150813, 150816, 150819, 150822, 150825, 150828, 150831, + 150834, 150837, 150840, 150843, 150846, 150849, 150852, 150855, 150858, + 150861, 150864, 150867, 150870, 150873, 150876, 150879, 150882, 150885, + 150888, 150891, 150894, 150897, 150900, 150903, 150906, 150909, 150912, + 150915, 150918, 150921, 150924, 150927, 150930, 150933, 150936, 150939, + 150942, 150945, 150948, 150951, 150954, 150957, 150960, 150963, 150966, + 150969, 150972, 150975, 150978, 150981, 150984, 150987, 150990, 150993, + 150996, 150999, 151002, 151005, 151008, 151011, 151014, 151017, 151020, + 151023, 151026, 151029, 151032, 151035, 151038, 151041, 151044, 151047, + 151050, 151053, 151056, 151059, 151062, 151065, 151068, 151071, 151074, + 151077, 151080, 151083, 151086, 151089, 151092, 151095, 151098, 151101, + 151104, 151107, 151110, 151113, 151116, 151119, 151122, 151125, 151128, + 151131, 151134, 151137, 151140, 151143, 151146, 151149, 151152, 151155, + 151158, 151161, 151164, 151167, 151170, 151173, 151176, 151179, 151182, + 151185, 151188, 151191, 151194, 151197, 151200, 151203, 151206, 151209, + 151212, 151215, 151218, 151221, 151224, 151227, 151230, 151233, 151236, + 151239, 151242, 151245, 151248, 151251, 151254, 151257, 151260, 151263, + 151266, 151269, 151272, 151275, 151278, 151281, 151284, 151287, 151290, + 151293, 151296, 151299, 151302, 151305, 151308, 151311, 151314, 151317, + 151320, 151323, 151326, 151329, 151332, 151335, 151338, 151341, 151344, + 151347, 151350, 151353, 151356, 151359, 151362, 151365, 151368, 151371, + 151374, 0, 0, 0, 0, 151377, 151381, 151385, 151389, 151393, 151397, + 151401, 151404, 151408, 151412, 151416, 151420, 151423, 151429, 151435, + 151441, 151447, 151453, 151457, 151463, 151467, 151471, 151477, 151481, + 151485, 151489, 151493, 151497, 151501, 151505, 151511, 151517, 151523, + 151529, 151536, 151543, 151550, 151560, 151567, 151574, 151580, 151586, + 151592, 151598, 151606, 151614, 151622, 151630, 151639, 151645, 151653, + 151659, 151666, 151672, 151679, 151685, 151693, 151697, 151701, 151706, + 151712, 151718, 151726, 151734, 151740, 151747, 151750, 151756, 151760, + 151763, 151767, 151770, 151773, 151777, 151782, 151786, 151790, 151796, + 151801, 151807, 151811, 151815, 151818, 151822, 151826, 151831, 151835, + 151840, 151844, 151849, 151853, 151857, 151861, 151865, 151869, 151873, + 151877, 151881, 151886, 151891, 151896, 151901, 151907, 151913, 151919, + 151925, 151931, 0, 0, 0, 0, 0, 151936, 151944, 151953, 151961, 151968, + 151976, 151983, 151990, 151999, 152006, 152013, 152021, 152029, 0, 0, 0, + 152037, 152043, 152051, 152057, 152064, 152070, 152076, 152082, 152088, + 0, 0, 0, 0, 0, 0, 0, 152094, 152100, 152108, 152114, 152121, 152127, + 152133, 152139, 152145, 152151, 0, 0, 152156, 152162, 152168, 152171, + 152180, 152187, 152195, 152202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 152165, 152180, 152193, 152202, 152213, 152222, 152231, - 152242, 152251, 152260, 152275, 152288, 152301, 152315, 152327, 152335, - 152345, 152353, 152361, 152371, 152379, 152387, 152401, 152413, 152425, - 152434, 152445, 152454, 152463, 152470, 152479, 152488, 152495, 152500, - 152505, 152510, 152515, 152520, 152525, 152530, 152535, 152540, 152545, - 152550, 152555, 152560, 0, 0, 152569, 152578, 152587, 152596, 152601, - 152608, 152613, 152618, 152626, 152631, 152638, 152643, 152650, 152655, - 152660, 152667, 152674, 152679, 152688, 152694, 152700, 152708, 152714, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 152720, 152724, 152730, 152734, 152742, - 152746, 152750, 152754, 152762, 152766, 152772, 152781, 152785, 152789, - 152793, 152799, 152805, 152811, 152817, 152823, 152829, 152835, 152841, - 152847, 152855, 152863, 152871, 152879, 152884, 152890, 152894, 152898, - 152902, 152906, 152912, 152918, 152924, 152930, 152936, 152944, 152950, - 152958, 152966, 152974, 152982, 152990, 152994, 153002, 153008, 153016, - 153020, 153024, 153028, 153032, 153036, 153040, 153048, 153056, 153068, - 153080, 153086, 153096, 153104, 153114, 153126, 153130, 153136, 153142, - 153148, 153154, 153160, 153166, 153172, 153178, 153184, 153192, 153198, - 153204, 153210, 153218, 153226, 153237, 153248, 153254, 153260, 153270, - 153276, 153284, 153288, 153294, 153300, 153306, 153312, 153318, 153324, - 153330, 153334, 153340, 153346, 153354, 153362, 153370, 153376, 153384, - 153397, 153410, 153418, 153426, 153438, 153446, 153456, 153464, 153468, - 153472, 153476, 153480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 152209, 152224, 152237, 152246, 152257, 152266, 152275, + 152286, 152295, 152304, 152319, 152332, 152345, 152359, 152371, 152379, + 152389, 152397, 152405, 152415, 152423, 152431, 152445, 152457, 152469, + 152478, 152489, 152498, 152507, 152514, 152523, 152532, 152539, 152544, + 152549, 152554, 152559, 152564, 152569, 152574, 152579, 152584, 152589, + 152594, 152599, 152604, 0, 0, 152613, 152622, 152631, 152640, 152645, + 152652, 152657, 152662, 152670, 152675, 152682, 152687, 152694, 152699, + 152704, 152711, 152718, 152723, 152732, 152738, 152744, 152752, 152758, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 152764, 152768, 152774, 152778, 152786, + 152790, 152794, 152798, 152806, 152810, 152816, 152825, 152829, 152833, + 152837, 152843, 152849, 152855, 152861, 152867, 152873, 152879, 152885, + 152891, 152899, 152907, 152915, 152923, 152928, 152934, 152938, 152942, + 152946, 152950, 152956, 152962, 152968, 152974, 152980, 152988, 152994, + 153002, 153010, 153018, 153026, 153034, 153038, 153046, 153052, 153060, + 153064, 153068, 153072, 153076, 153080, 153084, 153092, 153100, 153112, + 153124, 153130, 153140, 153148, 153158, 153170, 153174, 153180, 153186, + 153192, 153198, 153204, 153210, 153216, 153222, 153228, 153236, 153242, + 153248, 153254, 153262, 153270, 153281, 153292, 153298, 153304, 153314, + 153320, 153328, 153332, 153338, 153344, 153350, 153356, 153362, 153368, + 153374, 153378, 153384, 153390, 153398, 153406, 153414, 153420, 153428, + 153441, 153454, 153462, 153470, 153482, 153490, 153500, 153508, 153512, + 153516, 153520, 153524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153484, - 153489, 153494, 153499, 153506, 153513, 153520, 153527, 153532, 153537, - 153542, 153547, 153554, 153559, 153566, 153573, 153578, 153583, 153588, - 153595, 153600, 153605, 153612, 153619, 153624, 153629, 153634, 153641, - 153648, 153655, 153660, 153665, 153672, 153679, 153686, 153693, 153698, - 153703, 153708, 153715, 153720, 153725, 153730, 153737, 153746, 153753, - 153758, 153763, 153768, 153773, 153778, 153783, 153792, 153799, 153804, - 153811, 153818, 153823, 153828, 153833, 153840, 153845, 153852, 153859, - 153864, 153869, 153874, 153881, 153888, 153893, 153898, 153905, 153912, - 153919, 153924, 153929, 153934, 153939, 153946, 153955, 153964, 153969, - 153976, 153985, 153990, 153995, 154000, 154005, 154012, 154019, 154026, - 154033, 154038, 154043, 154048, 154055, 154062, 154069, 154074, 154079, - 154086, 154091, 154098, 154103, 154110, 154115, 154122, 154129, 154134, - 154139, 154144, 154149, 154154, 154159, 154164, 154169, 154174, 154181, - 154188, 154195, 154202, 154209, 154218, 154223, 154228, 154235, 154242, - 154247, 154254, 154261, 154268, 154275, 154282, 154289, 154294, 154299, - 154304, 154309, 154314, 154323, 154332, 154341, 154350, 154359, 154368, - 154377, 154386, 154391, 154402, 154413, 154422, 154427, 154432, 154437, - 154442, 154451, 154458, 154465, 154472, 154479, 154486, 154493, 154502, - 154511, 154522, 154531, 154542, 154551, 154558, 154567, 154578, 154587, - 154596, 154605, 154614, 154621, 154628, 154635, 154644, 154653, 154664, - 154673, 154682, 154693, 154698, 154703, 154714, 154722, 154731, 154740, - 154749, 154760, 154769, 154778, 154789, 154800, 154811, 154822, 154833, - 154844, 154851, 154858, 154865, 154872, 154883, 154892, 154899, 154906, - 154913, 154924, 154935, 154946, 154957, 154968, 154979, 154990, 155001, - 155008, 155015, 155024, 155033, 155040, 155047, 155054, 155063, 155072, - 155081, 155088, 155097, 155106, 155115, 155122, 155129, 155134, 155140, - 155147, 155154, 155161, 155168, 155175, 155182, 155191, 155200, 155209, - 155218, 155225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155234, 155240, 155245, - 155250, 155257, 155263, 155269, 155275, 155281, 155287, 155293, 155299, - 155303, 155307, 155313, 155319, 155325, 155329, 155334, 155339, 155343, - 155347, 155351, 155357, 155363, 155369, 155375, 155381, 155387, 155393, - 155399, 155405, 155415, 155425, 155431, 155437, 155447, 155457, 155463, - 0, 0, 155469, 155477, 155482, 155487, 155493, 155499, 155505, 155511, - 155517, 155523, 155530, 155537, 155543, 155549, 155555, 155561, 155567, - 155573, 155579, 155585, 155590, 155596, 155602, 155608, 155614, 155620, - 155629, 155635, 155640, 155648, 155655, 155662, 155671, 155680, 155689, - 155698, 155707, 155716, 155725, 155734, 155744, 155754, 155762, 155770, - 155779, 155788, 155794, 155800, 155806, 155812, 155820, 155828, 155832, - 155838, 155843, 155849, 155855, 155861, 155867, 155873, 155882, 155887, - 155894, 155899, 155904, 155909, 155915, 155921, 155927, 155934, 155939, - 155944, 155949, 155954, 155959, 155965, 155971, 155977, 155983, 155989, - 155995, 156001, 156007, 156012, 156017, 156022, 156027, 156032, 156037, - 156042, 156047, 156053, 156059, 156064, 156069, 156074, 156079, 156084, - 156090, 156097, 156101, 156105, 156109, 156113, 156117, 156121, 156125, - 156129, 156137, 156147, 156151, 156155, 156161, 156167, 156173, 156179, - 156185, 156191, 156197, 156203, 156209, 156215, 156221, 156227, 156233, - 156239, 156243, 156247, 156254, 156260, 156266, 156272, 156277, 156284, - 156289, 156295, 156301, 156307, 156313, 156318, 156322, 156328, 156332, - 156336, 156340, 156346, 156352, 156356, 156362, 156368, 156374, 156380, - 156386, 156394, 156402, 156408, 156414, 156420, 156426, 156438, 156450, - 156464, 156476, 156488, 156502, 156516, 156530, 156534, 156542, 156550, - 156555, 156559, 156563, 156567, 156571, 156575, 156579, 156583, 156589, - 156595, 156601, 156607, 156615, 156624, 156631, 156638, 156646, 156653, - 156665, 156677, 156689, 156701, 156708, 156712, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156716, 156723, 156730, 156737, - 156744, 156751, 156758, 156765, 156772, 156779, 156786, 156793, 156800, - 156807, 156814, 156821, 156828, 156835, 156842, 156849, 156856, 156863, - 156870, 156877, 156884, 156891, 156898, 156905, 156912, 156919, 156926, - 156933, 156940, 156947, 156954, 156961, 156968, 156975, 156982, 156989, - 156996, 157003, 157010, 157017, 157024, 157031, 157038, 157045, 157052, - 157059, 157066, 157073, 157080, 157087, 157094, 157101, 157108, 157115, - 157122, 157129, 157136, 157143, 157150, 157157, 157164, 157171, 157178, - 157183, 157188, 157193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153528, + 153533, 153538, 153543, 153550, 153557, 153564, 153571, 153576, 153581, + 153586, 153591, 153598, 153603, 153610, 153617, 153622, 153627, 153632, + 153639, 153644, 153649, 153656, 153663, 153668, 153673, 153678, 153685, + 153692, 153699, 153704, 153709, 153716, 153723, 153730, 153737, 153742, + 153747, 153752, 153759, 153764, 153769, 153774, 153781, 153790, 153797, + 153802, 153807, 153812, 153817, 153822, 153827, 153836, 153843, 153848, + 153855, 153862, 153867, 153872, 153877, 153884, 153889, 153896, 153903, + 153908, 153913, 153918, 153925, 153932, 153937, 153942, 153949, 153956, + 153963, 153968, 153973, 153978, 153983, 153990, 153999, 154008, 154013, + 154020, 154029, 154034, 154039, 154044, 154049, 154056, 154063, 154070, + 154077, 154082, 154087, 154092, 154099, 154106, 154113, 154118, 154123, + 154130, 154135, 154142, 154147, 154154, 154159, 154166, 154173, 154178, + 154183, 154188, 154193, 154198, 154203, 154208, 154213, 154218, 154225, + 154232, 154239, 154246, 154253, 154262, 154267, 154272, 154279, 154286, + 154291, 154298, 154305, 154312, 154319, 154326, 154333, 154338, 154343, + 154348, 154353, 154358, 154367, 154376, 154385, 154394, 154403, 154412, + 154421, 154430, 154435, 154446, 154457, 154466, 154471, 154476, 154481, + 154486, 154495, 154502, 154509, 154516, 154523, 154530, 154537, 154546, + 154555, 154566, 154575, 154586, 154595, 154602, 154611, 154622, 154631, + 154640, 154649, 154658, 154665, 154672, 154679, 154688, 154697, 154708, + 154717, 154726, 154737, 154742, 154747, 154758, 154766, 154775, 154784, + 154793, 154804, 154813, 154822, 154833, 154844, 154855, 154866, 154877, + 154888, 154895, 154902, 154909, 154916, 154927, 154936, 154943, 154950, + 154957, 154968, 154979, 154990, 155001, 155012, 155023, 155034, 155045, + 155052, 155059, 155068, 155077, 155084, 155091, 155098, 155107, 155116, + 155125, 155132, 155141, 155150, 155159, 155166, 155173, 155178, 155184, + 155191, 155198, 155205, 155212, 155219, 155226, 155235, 155244, 155253, + 155262, 155269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155278, 155284, 155289, + 155294, 155301, 155307, 155313, 155319, 155325, 155331, 155337, 155343, + 155347, 155351, 155357, 155363, 155369, 155373, 155378, 155383, 155387, + 155391, 155395, 155401, 155407, 155413, 155419, 155425, 155431, 155437, + 155443, 155449, 155459, 155469, 155475, 155481, 155491, 155501, 155507, + 0, 0, 155513, 155521, 155526, 155531, 155537, 155543, 155549, 155555, + 155561, 155567, 155574, 155581, 155587, 155593, 155599, 155605, 155611, + 155617, 155623, 155629, 155634, 155640, 155646, 155652, 155658, 155664, + 155673, 155679, 155684, 155692, 155699, 155706, 155715, 155724, 155733, + 155742, 155751, 155760, 155769, 155778, 155788, 155798, 155806, 155814, + 155823, 155832, 155838, 155844, 155850, 155856, 155864, 155872, 155876, + 155882, 155887, 155893, 155899, 155905, 155911, 155917, 155926, 155931, + 155938, 155943, 155948, 155953, 155959, 155965, 155971, 155978, 155983, + 155988, 155993, 155998, 156003, 156009, 156015, 156021, 156027, 156033, + 156039, 156045, 156051, 156056, 156061, 156066, 156071, 156076, 156081, + 156086, 156091, 156097, 156103, 156108, 156113, 156118, 156123, 156128, + 156134, 156141, 156145, 156149, 156153, 156157, 156161, 156165, 156169, + 156173, 156181, 156191, 156195, 156199, 156205, 156211, 156217, 156223, + 156229, 156235, 156241, 156247, 156253, 156259, 156265, 156271, 156277, + 156283, 156287, 156291, 156298, 156304, 156310, 156316, 156321, 156328, + 156333, 156339, 156345, 156351, 156357, 156362, 156366, 156372, 156376, + 156380, 156384, 156390, 156396, 156400, 156406, 156412, 156418, 156424, + 156430, 156438, 156446, 156452, 156458, 156464, 156470, 156482, 156494, + 156508, 156520, 156532, 156546, 156560, 156574, 156578, 156586, 156594, + 156599, 156603, 156607, 156611, 156615, 156619, 156623, 156627, 156633, + 156639, 156645, 156651, 156659, 156668, 156675, 156682, 156690, 156697, + 156709, 156721, 156733, 156745, 156752, 156756, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156760, 156767, 156774, 156781, + 156788, 156795, 156802, 156809, 156816, 156823, 156830, 156837, 156844, + 156851, 156858, 156865, 156872, 156879, 156886, 156893, 156900, 156907, + 156914, 156921, 156928, 156935, 156942, 156949, 156956, 156963, 156970, + 156977, 156984, 156991, 156998, 157005, 157012, 157019, 157026, 157033, + 157040, 157047, 157054, 157061, 157068, 157075, 157082, 157089, 157096, + 157103, 157110, 157117, 157124, 157131, 157138, 157145, 157152, 157159, + 157166, 157173, 157180, 157187, 157194, 157201, 157208, 157215, 157222, + 157227, 157232, 157237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157197, 157203, 157208, 157213, 157218, - 157223, 157228, 157233, 157238, 157243, 157248, 157254, 157260, 157266, - 157272, 157278, 157284, 157290, 157296, 157302, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 157308, 157314, 157319, 157324, 157329, 157334, 157339, - 157344, 157349, 157354, 157359, 157365, 157371, 157377, 157383, 157389, - 157395, 157401, 157407, 157413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 157419, 157424, 157431, 157438, 157445, 157452, 157457, 157462, 157469, - 157474, 157479, 157486, 157491, 157496, 157501, 157508, 157517, 157522, - 157527, 157532, 157537, 157542, 157547, 157554, 157559, 157564, 157569, - 157574, 157579, 157584, 157589, 157594, 157599, 157604, 157609, 157614, - 157620, 157625, 157630, 157635, 157640, 157645, 157650, 157655, 157660, - 157665, 157674, 157679, 157687, 157692, 157697, 157702, 157707, 157712, - 157717, 157722, 157731, 157736, 157741, 157746, 157751, 157756, 157763, - 157768, 157775, 157780, 157785, 157790, 157795, 157800, 157805, 157810, - 157815, 157820, 157825, 157830, 157835, 157840, 157845, 157850, 157855, - 157860, 157865, 157870, 157879, 157884, 157889, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 157894, 157902, 157910, 157918, 157926, 157934, 157942, 157950, - 157958, 157966, 157974, 157982, 157990, 157998, 158006, 158014, 158022, - 158030, 158038, 158043, 158048, 158053, 158058, 158063, 158067, 0, 0, 0, - 0, 0, 0, 0, 158071, 158075, 158080, 158085, 158090, 158094, 158099, - 158104, 158109, 158113, 158118, 158123, 158127, 158132, 158137, 158141, - 158146, 158151, 158155, 158160, 158165, 158169, 158174, 158179, 158184, - 158189, 158194, 158198, 158203, 158208, 158213, 158217, 158222, 158227, - 158232, 158236, 158241, 158246, 158250, 158255, 158260, 158264, 158269, - 158274, 158278, 158283, 158288, 158292, 158297, 158302, 158307, 158312, - 158317, 158321, 158326, 158331, 158336, 158340, 158345, 158350, 158355, - 158359, 158364, 158369, 158373, 158378, 158383, 158387, 158392, 158397, - 158401, 158406, 158411, 158415, 158420, 158425, 158430, 158435, 158440, - 158444, 158449, 158454, 158459, 158463, 158468, 0, 158473, 158477, - 158482, 158487, 158491, 158496, 158501, 158505, 158510, 158515, 158519, - 158524, 158529, 158533, 158538, 158543, 158548, 158553, 158558, 158563, - 158569, 158575, 158581, 158586, 158592, 158598, 158604, 158609, 158615, - 158621, 158626, 158632, 158638, 158643, 158649, 158655, 158660, 158666, - 158672, 158677, 158683, 158689, 158695, 158701, 158707, 158712, 158718, - 158724, 158730, 158735, 158741, 158747, 158753, 158758, 158764, 158770, - 158775, 158781, 158787, 158792, 158798, 158804, 158809, 158815, 158821, - 158826, 158832, 158838, 158844, 158850, 158856, 0, 158860, 158865, 0, 0, - 158870, 0, 0, 158875, 158880, 0, 0, 158885, 158890, 158894, 158899, 0, - 158904, 158909, 158914, 158918, 158923, 158928, 158933, 158938, 158943, - 158947, 158952, 158957, 0, 158962, 0, 158967, 158972, 158976, 158981, - 158986, 158990, 158995, 0, 159000, 159005, 159010, 159014, 159019, - 159024, 159028, 159033, 159038, 159043, 159048, 159053, 159058, 159064, - 159070, 159076, 159081, 159087, 159093, 159099, 159104, 159110, 159116, - 159121, 159127, 159133, 159138, 159144, 159150, 159155, 159161, 159167, - 159172, 159178, 159184, 159190, 159196, 159202, 159207, 159213, 159219, - 159225, 159230, 159236, 159242, 159248, 159253, 159259, 159265, 159270, - 159276, 159282, 159287, 159293, 159299, 159304, 159310, 159316, 159321, - 159327, 159333, 159339, 159345, 159351, 159356, 0, 159362, 159368, - 159373, 159379, 0, 0, 159385, 159391, 159397, 159402, 159408, 159414, - 159419, 159425, 0, 159431, 159437, 159443, 159448, 159454, 159460, - 159466, 0, 159472, 159477, 159483, 159489, 159495, 159500, 159506, - 159512, 159518, 159523, 159529, 159535, 159540, 159546, 159552, 159557, - 159563, 159569, 159574, 159580, 159586, 159591, 159597, 159603, 159609, - 159615, 159621, 159626, 0, 159632, 159638, 159643, 159649, 0, 159655, - 159660, 159666, 159672, 159677, 0, 159683, 0, 0, 0, 159688, 159694, - 159700, 159705, 159711, 159717, 159723, 0, 159729, 159734, 159740, - 159746, 159752, 159757, 159763, 159769, 159775, 159780, 159786, 159792, - 159797, 159803, 159809, 159814, 159820, 159826, 159831, 159837, 159843, - 159848, 159854, 159860, 159866, 159872, 159878, 159884, 159891, 159898, - 159905, 159911, 159918, 159925, 159932, 159938, 159945, 159952, 159958, - 159965, 159972, 159978, 159985, 159992, 159998, 160005, 160012, 160018, - 160025, 160032, 160039, 160046, 160053, 160059, 160066, 160073, 160080, - 160086, 160093, 160100, 160107, 160113, 160120, 160127, 160133, 160140, - 160147, 160153, 160160, 160167, 160173, 160180, 160187, 160193, 160200, - 160207, 160214, 160221, 160228, 160232, 160237, 160242, 160247, 160251, - 160256, 160261, 160266, 160270, 160275, 160280, 160284, 160289, 160294, - 160298, 160303, 160308, 160312, 160317, 160322, 160326, 160331, 160336, - 160341, 160346, 160351, 160355, 160360, 160365, 160370, 160374, 160379, - 160384, 160389, 160393, 160398, 160403, 160407, 160412, 160417, 160421, - 160426, 160431, 160435, 160440, 160445, 160449, 160454, 160459, 160464, - 160469, 160474, 160479, 160485, 160491, 160497, 160502, 160508, 160514, - 160520, 160525, 160531, 160537, 160542, 160548, 160554, 160559, 160565, - 160571, 160576, 160582, 160588, 160593, 160599, 160605, 160611, 160617, - 160623, 160628, 160634, 160640, 160646, 160651, 160657, 160663, 160669, - 160674, 160680, 160686, 160691, 160697, 160703, 160708, 160714, 160720, - 160725, 160731, 160737, 160742, 160748, 160754, 160760, 160766, 160772, - 160777, 160783, 160789, 160795, 160800, 160806, 160812, 160818, 160823, - 160829, 160835, 160840, 160846, 160852, 160857, 160863, 160869, 160874, - 160880, 160886, 160891, 160897, 160903, 160909, 160915, 160921, 160926, - 160932, 160938, 160944, 160949, 160955, 160961, 160967, 160972, 160978, - 160984, 160989, 160995, 161001, 161006, 161012, 161018, 161023, 161029, - 161035, 161040, 161046, 161052, 161058, 161064, 161070, 161076, 161083, - 161090, 161097, 161103, 161110, 161117, 161124, 161130, 161137, 161144, - 161150, 161157, 161164, 161170, 161177, 161184, 161190, 161197, 161204, - 161210, 161217, 161224, 161231, 161238, 161245, 161251, 161258, 161265, - 161272, 161278, 161285, 161292, 161299, 161305, 161312, 161319, 161325, - 161332, 161339, 161345, 161352, 161359, 161365, 161372, 161379, 161385, - 161392, 161399, 161406, 161413, 161420, 161425, 161431, 161437, 161443, - 161448, 161454, 161460, 161466, 161471, 161477, 161483, 161488, 161494, - 161500, 161505, 161511, 161517, 161522, 161528, 161534, 161539, 161545, - 161551, 161557, 161563, 161569, 161574, 161580, 161586, 161592, 161597, - 161603, 161609, 161615, 161620, 161626, 161632, 161637, 161643, 161649, - 161654, 161660, 161666, 161671, 161677, 161683, 161688, 161694, 161700, - 161706, 161712, 161718, 161724, 0, 0, 161731, 161736, 161741, 161746, - 161751, 161756, 161761, 161766, 161771, 161776, 161781, 161786, 161791, - 161796, 161801, 161806, 161811, 161816, 161822, 161827, 161832, 161837, - 161842, 161847, 161852, 161857, 161861, 161866, 161871, 161876, 161881, - 161886, 161891, 161896, 161901, 161906, 161911, 161916, 161921, 161926, - 161931, 161936, 161941, 161946, 161952, 161957, 161962, 161967, 161972, - 161977, 161982, 161987, 161993, 161998, 162003, 162008, 162013, 162018, - 162023, 162028, 162033, 162038, 162043, 162048, 162053, 162058, 162063, - 162068, 162073, 162078, 162083, 162088, 162093, 162098, 162103, 162108, - 162114, 162119, 162124, 162129, 162134, 162139, 162144, 162149, 162153, - 162158, 162163, 162168, 162173, 162178, 162183, 162188, 162193, 162198, - 162203, 162208, 162213, 162218, 162223, 162228, 162233, 162238, 162244, - 162249, 162254, 162259, 162264, 162269, 162274, 162279, 162285, 162290, - 162295, 162300, 162305, 162310, 162315, 162321, 162327, 162333, 162339, - 162345, 162351, 162357, 162363, 162369, 162375, 162381, 162387, 162393, - 162399, 162405, 162411, 162417, 162424, 162430, 162436, 162442, 162448, - 162454, 162460, 162466, 162471, 162477, 162483, 162489, 162495, 162501, - 162507, 162513, 162519, 162525, 162531, 162537, 162543, 162549, 162555, - 162561, 162567, 162573, 162580, 162586, 162592, 162598, 162604, 162610, - 162616, 162622, 162629, 162635, 162641, 162647, 162653, 162659, 162665, - 162671, 162677, 162683, 162689, 162695, 162701, 162707, 162713, 162719, - 162725, 162731, 162737, 162743, 162749, 162755, 162761, 162767, 162774, - 162780, 162786, 162792, 162798, 162804, 162810, 162816, 162821, 162827, - 162833, 162839, 162845, 162851, 162857, 162863, 162869, 162875, 162881, - 162887, 162893, 162899, 162905, 162911, 162917, 162923, 162930, 162936, - 162942, 162948, 162954, 162960, 162966, 162972, 162979, 162985, 162991, - 162997, 163003, 163009, 163015, 163022, 163029, 163036, 163043, 163050, - 163057, 163064, 163071, 163078, 163085, 163092, 163099, 163106, 163113, - 163120, 163127, 163134, 163142, 163149, 163156, 163163, 163170, 163177, - 163184, 163191, 163197, 163204, 163211, 163218, 163225, 163232, 163239, - 163246, 163253, 163260, 163267, 163274, 163281, 163288, 163295, 163302, - 163309, 163316, 163324, 163331, 163338, 163345, 163352, 163359, 163366, - 163373, 163381, 163388, 163395, 163402, 163409, 163416, 163423, 163428, - 0, 0, 163433, 163438, 163442, 163446, 163450, 163454, 163458, 163462, - 163466, 163470, 163474, 163480, 163485, 163490, 163495, 163500, 163505, - 163510, 163515, 163520, 163525, 163530, 163534, 163538, 163542, 163546, - 163550, 163554, 163558, 163562, 163566, 163572, 163577, 163582, 163587, - 163592, 163597, 163602, 163607, 163612, 163617, 163623, 163628, 163633, - 163638, 163643, 163648, 163653, 163658, 163663, 163668, 163672, 163677, - 163682, 163687, 163692, 163697, 163702, 163708, 163716, 163723, 163728, - 163733, 163740, 163746, 163751, 163757, 163763, 163771, 163777, 163784, - 163792, 163798, 163807, 163816, 163824, 163832, 163838, 163845, 163853, - 163861, 163867, 163874, 163883, 163892, 163899, 163910, 163920, 163930, - 163940, 163950, 163957, 163964, 163971, 163978, 163987, 163996, 164007, - 164018, 164027, 164036, 164047, 164056, 164065, 164076, 164085, 164094, - 164102, 164110, 164121, 164132, 164140, 164149, 164158, 164165, 164176, - 164187, 164196, 164205, 164212, 164221, 164230, 164239, 164250, 164259, - 164269, 164278, 164287, 164298, 164311, 164326, 164337, 164350, 164362, - 164371, 164382, 164393, 164402, 164413, 164427, 164442, 164445, 164454, - 164459, 164465, 164473, 164479, 164485, 164494, 164501, 164511, 164523, - 164530, 164533, 164539, 164546, 164552, 164557, 164560, 164565, 164568, - 164576, 164582, 164591, 164598, 164606, 164612, 164617, 164620, 164623, - 164626, 164632, 164639, 164645, 164650, 164658, 164661, 164666, 164674, - 164680, 164689, 164696, 164706, 164715, 164718, 164724, 164731, 164738, - 164745, 164750, 164758, 164766, 164775, 164781, 164790, 164799, 164808, - 164814, 164823, 164830, 164837, 164844, 164852, 164858, 164866, 164872, - 164879, 164886, 164894, 164905, 164915, 164921, 164928, 164935, 164942, - 164948, 164955, 164962, 164967, 164974, 164982, 164991, 164997, 165009, - 165020, 165026, 165034, 165040, 165047, 165054, 165061, 165067, 165074, - 165083, 165089, 165095, 165102, 165109, 165117, 165127, 165137, 165147, - 165157, 165165, 165173, 165183, 165191, 165196, 165201, 165206, 165212, - 165219, 165226, 165232, 165238, 165243, 165250, 165258, 165268, 165276, - 165284, 165294, 165304, 165312, 165322, 165332, 165344, 165356, 165368, - 165378, 165384, 165390, 165397, 165406, 165415, 165424, 165433, 165443, - 165452, 165461, 165470, 165475, 165481, 165490, 165500, 165509, 165515, - 165521, 165528, 165535, 165542, 165548, 165555, 165562, 165569, 165575, - 165579, 165584, 165591, 165598, 165605, 165610, 165618, 165626, 165635, - 165643, 165650, 165658, 165667, 165677, 165680, 165684, 165689, 165694, - 165699, 165704, 165709, 165714, 165719, 165724, 165729, 165734, 165739, - 165744, 165749, 165754, 165759, 165764, 165769, 165776, 165782, 165789, - 165795, 165800, 165807, 165813, 165820, 165826, 165831, 165838, 165845, - 165852, 165858, 165864, 165873, 165882, 165892, 165899, 165906, 165915, - 165924, 165933, 165942, 165951, 165957, 165965, 165971, 165981, 165986, - 165995, 166004, 166011, 166022, 166029, 166036, 166043, 166050, 166057, - 166064, 166071, 166078, 166085, 166092, 166098, 166104, 166110, 166117, - 166124, 166131, 166138, 166145, 166152, 166159, 166166, 166173, 166180, - 166187, 166194, 166199, 166208, 166217, 166226, 166233, 166240, 166247, - 166254, 166261, 166268, 166275, 166282, 166291, 166300, 166309, 166318, - 166327, 166336, 166345, 166354, 166363, 166372, 166381, 166390, 166399, - 166405, 166413, 166419, 166429, 166434, 166443, 166452, 166461, 166472, - 166477, 166484, 166491, 166498, 166503, 166509, 166515, 166521, 166528, - 166535, 166542, 166549, 166556, 166563, 166570, 166577, 166584, 166591, - 166598, 166605, 166610, 166619, 166628, 166637, 166646, 166655, 166664, - 166673, 166682, 166693, 166704, 166711, 166718, 166725, 166732, 166739, - 166746, 166754, 166764, 166774, 166784, 166795, 166806, 166817, 166826, - 166835, 166844, 166849, 166854, 166859, 166864, 166875, 166886, 166897, - 166908, 166919, 166929, 166940, 166949, 166958, 166967, 166976, 166985, - 166993, 167002, 167013, 167024, 167035, 167046, 167057, 167069, 167082, - 167094, 167107, 167119, 167132, 167144, 167157, 167168, 167179, 167188, - 167196, 167205, 167216, 167227, 167239, 167252, 167266, 167281, 167293, - 167306, 167318, 167331, 167342, 167353, 167362, 167370, 167379, 167386, - 167393, 167400, 167407, 167414, 167421, 167428, 167435, 167442, 167449, - 167454, 167459, 167464, 167471, 167481, 167492, 167502, 167513, 167527, - 167542, 167557, 167571, 167586, 167601, 167612, 167623, 167636, 167649, - 167658, 167667, 167680, 167693, 167700, 167707, 167712, 167717, 167722, - 167727, 167732, 167739, 167748, 167753, 167756, 167761, 167768, 167775, - 167782, 167789, 167796, 167803, 167816, 167830, 167845, 167852, 167859, - 167866, 167875, 167883, 167891, 167900, 167905, 167910, 167915, 167920, - 167925, 167930, 167937, 167944, 167950, 167957, 167963, 167970, 167975, - 167980, 167985, 167990, 167995, 168002, 168009, 168014, 168021, 168028, - 168033, 168038, 168043, 168048, 168053, 168058, 168065, 168072, 168079, - 168082, 168087, 168092, 168097, 168102, 168109, 168116, 168124, 168132, - 168137, 168142, 168149, 168156, 168163, 168168, 168175, 168182, 168187, - 168194, 168201, 168208, 168215, 168222, 168229, 168238, 168247, 168254, - 168263, 168272, 168277, 168284, 168291, 168296, 168303, 168310, 168317, - 168324, 168331, 168336, 168343, 168350, 168359, 168366, 168375, 168386, - 168395, 168404, 168413, 168422, 168425, 168430, 168437, 168446, 168453, - 168462, 168469, 168474, 168479, 168482, 168485, 168488, 168495, 168502, - 168511, 168520, 168529, 168536, 168543, 168548, 168560, 168565, 168570, - 168575, 168580, 168585, 168590, 168595, 168600, 168603, 168608, 168613, - 168618, 168623, 168628, 168635, 168640, 168647, 168650, 168655, 168658, - 168661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168664, 168669, - 168674, 168679, 168684, 0, 168689, 168694, 168699, 168704, 168709, - 168714, 168719, 168724, 168729, 168734, 168739, 168744, 168749, 168754, - 168759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157241, 157247, 157252, 157257, 157262, + 157267, 157272, 157277, 157282, 157287, 157292, 157298, 157304, 157310, + 157316, 157322, 157328, 157334, 157340, 157346, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 157352, 157358, 157363, 157368, 157373, 157378, 157383, + 157388, 157393, 157398, 157403, 157409, 157415, 157421, 157427, 157433, + 157439, 157445, 157451, 157457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 157463, 157468, 157475, 157482, 157489, 157496, 157501, 157506, 157513, + 157518, 157523, 157530, 157535, 157540, 157545, 157552, 157561, 157566, + 157571, 157576, 157581, 157586, 157591, 157598, 157603, 157608, 157613, + 157618, 157623, 157628, 157633, 157638, 157643, 157648, 157653, 157658, + 157664, 157669, 157674, 157679, 157684, 157689, 157694, 157699, 157704, + 157709, 157718, 157723, 157731, 157736, 157741, 157746, 157751, 157756, + 157761, 157766, 157775, 157780, 157785, 157790, 157795, 157800, 157807, + 157812, 157819, 157824, 157829, 157834, 157839, 157844, 157849, 157854, + 157859, 157864, 157869, 157874, 157879, 157884, 157889, 157894, 157899, + 157904, 157909, 157914, 157923, 157928, 157933, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 157938, 157946, 157954, 157962, 157970, 157978, 157986, 157994, + 158002, 158010, 158018, 158026, 158034, 158042, 158050, 158058, 158066, + 158074, 158082, 158087, 158092, 158097, 158102, 158107, 158111, 0, 0, 0, + 0, 0, 0, 0, 158115, 158119, 158124, 158129, 158134, 158138, 158143, + 158148, 158153, 158157, 158162, 158167, 158171, 158176, 158181, 158185, + 158190, 158195, 158199, 158204, 158209, 158213, 158218, 158223, 158228, + 158233, 158238, 158242, 158247, 158252, 158257, 158261, 158266, 158271, + 158276, 158280, 158285, 158290, 158294, 158299, 158304, 158308, 158313, + 158318, 158322, 158327, 158332, 158336, 158341, 158346, 158351, 158356, + 158361, 158365, 158370, 158375, 158380, 158384, 158389, 158394, 158399, + 158403, 158408, 158413, 158417, 158422, 158427, 158431, 158436, 158441, + 158445, 158450, 158455, 158459, 158464, 158469, 158474, 158479, 158484, + 158488, 158493, 158498, 158503, 158507, 158512, 0, 158517, 158521, + 158526, 158531, 158535, 158540, 158545, 158549, 158554, 158559, 158563, + 158568, 158573, 158577, 158582, 158587, 158592, 158597, 158602, 158607, + 158613, 158619, 158625, 158630, 158636, 158642, 158648, 158653, 158659, + 158665, 158670, 158676, 158682, 158687, 158693, 158699, 158704, 158710, + 158716, 158721, 158727, 158733, 158739, 158745, 158751, 158756, 158762, + 158768, 158774, 158779, 158785, 158791, 158797, 158802, 158808, 158814, + 158819, 158825, 158831, 158836, 158842, 158848, 158853, 158859, 158865, + 158870, 158876, 158882, 158888, 158894, 158900, 0, 158904, 158909, 0, 0, + 158914, 0, 0, 158919, 158924, 0, 0, 158929, 158934, 158938, 158943, 0, + 158948, 158953, 158958, 158962, 158967, 158972, 158977, 158982, 158987, + 158991, 158996, 159001, 0, 159006, 0, 159011, 159016, 159020, 159025, + 159030, 159034, 159039, 0, 159044, 159049, 159054, 159058, 159063, + 159068, 159072, 159077, 159082, 159087, 159092, 159097, 159102, 159108, + 159114, 159120, 159125, 159131, 159137, 159143, 159148, 159154, 159160, + 159165, 159171, 159177, 159182, 159188, 159194, 159199, 159205, 159211, + 159216, 159222, 159228, 159234, 159240, 159246, 159251, 159257, 159263, + 159269, 159274, 159280, 159286, 159292, 159297, 159303, 159309, 159314, + 159320, 159326, 159331, 159337, 159343, 159348, 159354, 159360, 159365, + 159371, 159377, 159383, 159389, 159395, 159400, 0, 159406, 159412, + 159417, 159423, 0, 0, 159429, 159435, 159441, 159446, 159452, 159458, + 159463, 159469, 0, 159475, 159481, 159487, 159492, 159498, 159504, + 159510, 0, 159516, 159521, 159527, 159533, 159539, 159544, 159550, + 159556, 159562, 159567, 159573, 159579, 159584, 159590, 159596, 159601, + 159607, 159613, 159618, 159624, 159630, 159635, 159641, 159647, 159653, + 159659, 159665, 159670, 0, 159676, 159682, 159687, 159693, 0, 159699, + 159704, 159710, 159716, 159721, 0, 159727, 0, 0, 0, 159732, 159738, + 159744, 159749, 159755, 159761, 159767, 0, 159773, 159778, 159784, + 159790, 159796, 159801, 159807, 159813, 159819, 159824, 159830, 159836, + 159841, 159847, 159853, 159858, 159864, 159870, 159875, 159881, 159887, + 159892, 159898, 159904, 159910, 159916, 159922, 159928, 159935, 159942, + 159949, 159955, 159962, 159969, 159976, 159982, 159989, 159996, 160002, + 160009, 160016, 160022, 160029, 160036, 160042, 160049, 160056, 160062, + 160069, 160076, 160083, 160090, 160097, 160103, 160110, 160117, 160124, + 160130, 160137, 160144, 160151, 160157, 160164, 160171, 160177, 160184, + 160191, 160197, 160204, 160211, 160217, 160224, 160231, 160237, 160244, + 160251, 160258, 160265, 160272, 160276, 160281, 160286, 160291, 160295, + 160300, 160305, 160310, 160314, 160319, 160324, 160328, 160333, 160338, + 160342, 160347, 160352, 160356, 160361, 160366, 160370, 160375, 160380, + 160385, 160390, 160395, 160399, 160404, 160409, 160414, 160418, 160423, + 160428, 160433, 160437, 160442, 160447, 160451, 160456, 160461, 160465, + 160470, 160475, 160479, 160484, 160489, 160493, 160498, 160503, 160508, + 160513, 160518, 160523, 160529, 160535, 160541, 160546, 160552, 160558, + 160564, 160569, 160575, 160581, 160586, 160592, 160598, 160603, 160609, + 160615, 160620, 160626, 160632, 160637, 160643, 160649, 160655, 160661, + 160667, 160672, 160678, 160684, 160690, 160695, 160701, 160707, 160713, + 160718, 160724, 160730, 160735, 160741, 160747, 160752, 160758, 160764, + 160769, 160775, 160781, 160786, 160792, 160798, 160804, 160810, 160816, + 160821, 160827, 160833, 160839, 160844, 160850, 160856, 160862, 160867, + 160873, 160879, 160884, 160890, 160896, 160901, 160907, 160913, 160918, + 160924, 160930, 160935, 160941, 160947, 160953, 160959, 160965, 160970, + 160976, 160982, 160988, 160993, 160999, 161005, 161011, 161016, 161022, + 161028, 161033, 161039, 161045, 161050, 161056, 161062, 161067, 161073, + 161079, 161084, 161090, 161096, 161102, 161108, 161114, 161120, 161127, + 161134, 161141, 161147, 161154, 161161, 161168, 161174, 161181, 161188, + 161194, 161201, 161208, 161214, 161221, 161228, 161234, 161241, 161248, + 161254, 161261, 161268, 161275, 161282, 161289, 161295, 161302, 161309, + 161316, 161322, 161329, 161336, 161343, 161349, 161356, 161363, 161369, + 161376, 161383, 161389, 161396, 161403, 161409, 161416, 161423, 161429, + 161436, 161443, 161450, 161457, 161464, 161469, 161475, 161481, 161487, + 161492, 161498, 161504, 161510, 161515, 161521, 161527, 161532, 161538, + 161544, 161549, 161555, 161561, 161566, 161572, 161578, 161583, 161589, + 161595, 161601, 161607, 161613, 161618, 161624, 161630, 161636, 161641, + 161647, 161653, 161659, 161664, 161670, 161676, 161681, 161687, 161693, + 161698, 161704, 161710, 161715, 161721, 161727, 161732, 161738, 161744, + 161750, 161756, 161762, 161768, 0, 0, 161775, 161780, 161785, 161790, + 161795, 161800, 161805, 161810, 161815, 161820, 161825, 161830, 161835, + 161840, 161845, 161850, 161855, 161860, 161866, 161871, 161876, 161881, + 161886, 161891, 161896, 161901, 161905, 161910, 161915, 161920, 161925, + 161930, 161935, 161940, 161945, 161950, 161955, 161960, 161965, 161970, + 161975, 161980, 161985, 161990, 161996, 162001, 162006, 162011, 162016, + 162021, 162026, 162031, 162037, 162042, 162047, 162052, 162057, 162062, + 162067, 162072, 162077, 162082, 162087, 162092, 162097, 162102, 162107, + 162112, 162117, 162122, 162127, 162132, 162137, 162142, 162147, 162152, + 162158, 162163, 162168, 162173, 162178, 162183, 162188, 162193, 162197, + 162202, 162207, 162212, 162217, 162222, 162227, 162232, 162237, 162242, + 162247, 162252, 162257, 162262, 162267, 162272, 162277, 162282, 162288, + 162293, 162298, 162303, 162308, 162313, 162318, 162323, 162329, 162334, + 162339, 162344, 162349, 162354, 162359, 162365, 162371, 162377, 162383, + 162389, 162395, 162401, 162407, 162413, 162419, 162425, 162431, 162437, + 162443, 162449, 162455, 162461, 162468, 162474, 162480, 162486, 162492, + 162498, 162504, 162510, 162515, 162521, 162527, 162533, 162539, 162545, + 162551, 162557, 162563, 162569, 162575, 162581, 162587, 162593, 162599, + 162605, 162611, 162617, 162624, 162630, 162636, 162642, 162648, 162654, + 162660, 162666, 162673, 162679, 162685, 162691, 162697, 162703, 162709, + 162715, 162721, 162727, 162733, 162739, 162745, 162751, 162757, 162763, + 162769, 162775, 162781, 162787, 162793, 162799, 162805, 162811, 162818, + 162824, 162830, 162836, 162842, 162848, 162854, 162860, 162865, 162871, + 162877, 162883, 162889, 162895, 162901, 162907, 162913, 162919, 162925, + 162931, 162937, 162943, 162949, 162955, 162961, 162967, 162974, 162980, + 162986, 162992, 162998, 163004, 163010, 163016, 163023, 163029, 163035, + 163041, 163047, 163053, 163059, 163066, 163073, 163080, 163087, 163094, + 163101, 163108, 163115, 163122, 163129, 163136, 163143, 163150, 163157, + 163164, 163171, 163178, 163186, 163193, 163200, 163207, 163214, 163221, + 163228, 163235, 163241, 163248, 163255, 163262, 163269, 163276, 163283, + 163290, 163297, 163304, 163311, 163318, 163325, 163332, 163339, 163346, + 163353, 163360, 163368, 163375, 163382, 163389, 163396, 163403, 163410, + 163417, 163425, 163432, 163439, 163446, 163453, 163460, 163467, 163472, + 0, 0, 163477, 163482, 163486, 163490, 163494, 163498, 163502, 163506, + 163510, 163514, 163518, 163524, 163529, 163534, 163539, 163544, 163549, + 163554, 163559, 163564, 163569, 163574, 163578, 163582, 163586, 163590, + 163594, 163598, 163602, 163606, 163610, 163616, 163621, 163626, 163631, + 163636, 163641, 163646, 163651, 163656, 163661, 163667, 163672, 163677, + 163682, 163687, 163692, 163697, 163702, 163707, 163712, 163716, 163721, + 163726, 163731, 163736, 163741, 163746, 163752, 163760, 163767, 163772, + 163777, 163784, 163790, 163795, 163801, 163807, 163815, 163821, 163828, + 163836, 163842, 163851, 163860, 163868, 163876, 163882, 163889, 163897, + 163905, 163911, 163918, 163927, 163936, 163943, 163954, 163964, 163974, + 163984, 163994, 164001, 164008, 164015, 164022, 164031, 164040, 164051, + 164062, 164071, 164080, 164091, 164100, 164109, 164120, 164129, 164138, + 164146, 164154, 164165, 164176, 164184, 164193, 164202, 164209, 164220, + 164231, 164240, 164249, 164256, 164265, 164274, 164283, 164294, 164303, + 164313, 164322, 164331, 164342, 164355, 164370, 164381, 164394, 164406, + 164415, 164426, 164437, 164446, 164457, 164471, 164486, 164489, 164498, + 164503, 164509, 164517, 164523, 164529, 164538, 164545, 164555, 164567, + 164574, 164577, 164583, 164590, 164596, 164601, 164604, 164609, 164612, + 164620, 164626, 164635, 164642, 164650, 164656, 164661, 164664, 164667, + 164670, 164676, 164683, 164689, 164694, 164702, 164705, 164710, 164718, + 164724, 164733, 164740, 164750, 164759, 164762, 164768, 164775, 164782, + 164789, 164794, 164802, 164810, 164819, 164825, 164834, 164843, 164852, + 164858, 164867, 164874, 164881, 164888, 164896, 164902, 164910, 164916, + 164923, 164930, 164938, 164949, 164959, 164965, 164972, 164979, 164986, + 164992, 164999, 165006, 165011, 165018, 165026, 165035, 165041, 165053, + 165064, 165070, 165078, 165084, 165091, 165098, 165105, 165111, 165118, + 165127, 165133, 165139, 165146, 165153, 165161, 165171, 165181, 165191, + 165201, 165209, 165217, 165227, 165235, 165240, 165245, 165250, 165256, + 165263, 165270, 165276, 165282, 165287, 165294, 165302, 165312, 165320, + 165328, 165338, 165348, 165356, 165366, 165376, 165388, 165400, 165412, + 165422, 165428, 165434, 165441, 165450, 165459, 165468, 165477, 165487, + 165496, 165505, 165514, 165519, 165525, 165534, 165544, 165553, 165559, + 165565, 165572, 165579, 165586, 165592, 165599, 165606, 165613, 165619, + 165623, 165628, 165635, 165642, 165649, 165654, 165662, 165670, 165679, + 165687, 165694, 165702, 165711, 165721, 165724, 165728, 165733, 165738, + 165743, 165748, 165753, 165758, 165763, 165768, 165773, 165778, 165783, + 165788, 165793, 165798, 165803, 165808, 165813, 165820, 165826, 165833, + 165839, 165844, 165851, 165857, 165864, 165870, 165875, 165882, 165889, + 165896, 165902, 165908, 165917, 165926, 165936, 165943, 165950, 165959, + 165968, 165977, 165986, 165995, 166001, 166009, 166015, 166025, 166030, + 166039, 166048, 166055, 166066, 166073, 166080, 166087, 166094, 166101, + 166108, 166115, 166122, 166129, 166136, 166142, 166148, 166154, 166161, + 166168, 166175, 166182, 166189, 166196, 166203, 166210, 166217, 166224, + 166231, 166238, 166243, 166252, 166261, 166270, 166277, 166284, 166291, + 166298, 166305, 166312, 166319, 166326, 166335, 166344, 166353, 166362, + 166371, 166380, 166389, 166398, 166407, 166416, 166425, 166434, 166443, + 166449, 166457, 166463, 166473, 166478, 166487, 166496, 166505, 166516, + 166521, 166528, 166535, 166542, 166547, 166553, 166559, 166565, 166572, + 166579, 166586, 166593, 166600, 166607, 166614, 166621, 166628, 166635, + 166642, 166649, 166654, 166663, 166672, 166681, 166690, 166699, 166708, + 166717, 166726, 166737, 166748, 166755, 166762, 166769, 166776, 166783, + 166790, 166798, 166808, 166818, 166828, 166839, 166850, 166861, 166870, + 166879, 166888, 166893, 166898, 166903, 166908, 166919, 166930, 166941, + 166952, 166963, 166973, 166984, 166993, 167002, 167011, 167020, 167029, + 167037, 167046, 167057, 167068, 167079, 167090, 167101, 167113, 167126, + 167138, 167151, 167163, 167176, 167188, 167201, 167212, 167223, 167232, + 167240, 167249, 167260, 167271, 167283, 167296, 167310, 167325, 167337, + 167350, 167362, 167375, 167386, 167397, 167406, 167414, 167423, 167430, + 167437, 167444, 167451, 167458, 167465, 167472, 167479, 167486, 167493, + 167498, 167503, 167508, 167515, 167525, 167536, 167546, 167557, 167571, + 167586, 167601, 167615, 167630, 167645, 167656, 167667, 167680, 167693, + 167702, 167711, 167724, 167737, 167744, 167751, 167756, 167761, 167766, + 167771, 167776, 167783, 167792, 167797, 167800, 167805, 167812, 167819, + 167826, 167833, 167840, 167847, 167860, 167874, 167889, 167896, 167903, + 167910, 167919, 167927, 167935, 167944, 167949, 167954, 167959, 167964, + 167969, 167974, 167981, 167988, 167994, 168001, 168007, 168014, 168019, + 168024, 168029, 168034, 168039, 168046, 168053, 168058, 168065, 168072, + 168077, 168082, 168087, 168092, 168097, 168102, 168109, 168116, 168123, + 168126, 168131, 168136, 168141, 168146, 168153, 168160, 168168, 168176, + 168181, 168186, 168193, 168200, 168207, 168212, 168219, 168226, 168231, + 168238, 168245, 168252, 168259, 168266, 168273, 168282, 168291, 168298, + 168307, 168316, 168321, 168328, 168335, 168340, 168347, 168354, 168361, + 168368, 168375, 168380, 168387, 168394, 168403, 168410, 168419, 168430, + 168439, 168448, 168457, 168466, 168469, 168474, 168481, 168490, 168497, + 168506, 168513, 168518, 168523, 168526, 168529, 168532, 168539, 168546, + 168555, 168564, 168573, 168580, 168587, 168592, 168604, 168609, 168614, + 168619, 168624, 168629, 168634, 168639, 168644, 168647, 168652, 168657, + 168662, 168667, 168672, 168679, 168684, 168691, 168694, 168699, 168702, + 168705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168708, 168713, + 168718, 168723, 168728, 0, 168733, 168738, 168743, 168748, 168753, + 168758, 168763, 168768, 168773, 168778, 168783, 168788, 168793, 168798, + 168803, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168764, 168774, 168782, 168789, 168796, - 168805, 168814, 168823, 168830, 168844, 168856, 168866, 168874, 168886, - 168895, 168906, 168915, 168922, 168930, 168941, 168953, 168962, 168972, - 168984, 168995, 169004, 169015, 169027, 169035, 169046, 169055, 0, 0, 0, - 0, 0, 0, 169063, 169073, 169083, 169093, 169103, 169113, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168808, 168818, 168826, 168833, 168840, + 168849, 168858, 168867, 168874, 168888, 168900, 168910, 168918, 168930, + 168939, 168950, 168959, 168966, 168974, 168985, 168997, 169006, 169016, + 169028, 169039, 169048, 169059, 169071, 169079, 169090, 169099, 0, 0, 0, + 0, 0, 0, 169107, 169117, 169127, 169137, 169147, 169157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 169123, 169128, 169133, 169138, 169143, 169148, - 169153, 0, 169158, 169163, 169168, 169174, 169178, 169183, 169188, - 169193, 169198, 169203, 169208, 169213, 169218, 169223, 169228, 169233, - 169238, 0, 0, 169243, 169248, 169253, 169258, 169263, 169268, 169273, 0, - 169278, 169283, 0, 169289, 169294, 169302, 169309, 169318, 0, 0, 0, 0, 0, - 169323, 169328, 169334, 169340, 169346, 169352, 169358, 169364, 169370, - 169375, 169380, 169386, 169392, 169397, 169403, 169409, 169415, 169421, - 169426, 169432, 169437, 169443, 169449, 169455, 169461, 169466, 169472, - 169478, 169484, 169491, 169497, 169504, 169511, 169517, 169523, 169530, - 169537, 169544, 169551, 169558, 169565, 169572, 169578, 169584, 169591, - 169597, 169604, 169611, 169617, 169624, 169630, 169637, 169644, 169651, - 169659, 169666, 169676, 169684, 169691, 169698, 169707, 169718, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 169167, 169172, 169177, 169182, 169187, 169192, + 169197, 0, 169202, 169207, 169212, 169218, 169222, 169227, 169232, + 169237, 169242, 169247, 169252, 169257, 169262, 169267, 169272, 169277, + 169282, 0, 0, 169287, 169292, 169297, 169302, 169307, 169312, 169317, 0, + 169322, 169327, 0, 169333, 169338, 169346, 169353, 169362, 0, 0, 0, 0, 0, + 169367, 169372, 169378, 169384, 169390, 169396, 169402, 169408, 169414, + 169419, 169424, 169430, 169436, 169441, 169447, 169453, 169459, 169465, + 169470, 169476, 169481, 169487, 169493, 169499, 169505, 169510, 169516, + 169522, 169528, 169535, 169541, 169548, 169555, 169561, 169567, 169574, + 169581, 169588, 169595, 169602, 169609, 169616, 169622, 169628, 169635, + 169641, 169648, 169655, 169661, 169668, 169674, 169681, 169688, 169695, + 169703, 169710, 169720, 169728, 169735, 169742, 169751, 169762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 169727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 169771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 169734, 169741, 169749, 169757, 169765, 169772, 169779, 169787, 169795, - 169803, 169810, 169817, 169825, 169833, 169841, 169848, 169856, 169864, - 169872, 169880, 169888, 169896, 169904, 169911, 169919, 169926, 169934, - 169941, 169949, 169957, 169965, 169973, 169981, 169989, 169997, 170005, - 170013, 170020, 170028, 170035, 170042, 170049, 170057, 170064, 170072, - 0, 0, 0, 170080, 170087, 170094, 170101, 170108, 170115, 170122, 170129, - 170138, 170147, 170156, 170165, 170174, 170184, 0, 0, 170192, 170200, - 170207, 170214, 170221, 170228, 170235, 170242, 170249, 170256, 0, 0, 0, - 0, 170263, 170272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 169778, 169785, 169793, 169801, 169809, 169816, 169823, 169831, 169839, + 169847, 169854, 169861, 169869, 169877, 169885, 169892, 169900, 169908, + 169916, 169924, 169932, 169940, 169948, 169955, 169963, 169970, 169978, + 169985, 169993, 170001, 170009, 170017, 170025, 170033, 170041, 170049, + 170057, 170064, 170072, 170079, 170086, 170093, 170101, 170108, 170116, + 0, 0, 0, 170124, 170131, 170138, 170145, 170152, 170159, 170166, 170173, + 170182, 170191, 170200, 170209, 170218, 170228, 0, 0, 170236, 170244, + 170251, 170258, 170265, 170272, 170279, 170286, 170293, 170300, 0, 0, 0, + 0, 170307, 170316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170280, - 170284, 170289, 170294, 170299, 170303, 170308, 170312, 170316, 170321, - 170325, 170330, 170334, 170339, 170344, 170348, 170352, 170356, 170360, - 170366, 170371, 170378, 170382, 170386, 170392, 170397, 170404, 170408, - 170413, 170420, 170424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 170431, 170436, 170440, 170445, 170450, 170455, 170460, 170464, - 170469, 170473, 170477, 170481, 170486, 170491, 170496, 170500, 170505, - 170510, 170515, 170520, 170525, 170529, 170533, 170538, 170542, 170546, - 170551, 170555, 170559, 170563, 170568, 170572, 170577, 170582, 170587, - 170592, 170597, 170602, 170607, 170612, 170617, 170622, 170627, 170632, - 170637, 170642, 170647, 170652, 170657, 170662, 170666, 170670, 170674, - 170678, 170682, 170686, 170690, 170694, 0, 0, 0, 0, 0, 170698, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170324, + 170328, 170333, 170338, 170343, 170347, 170352, 170356, 170360, 170365, + 170369, 170374, 170378, 170383, 170388, 170392, 170396, 170400, 170404, + 170410, 170415, 170422, 170426, 170430, 170436, 170441, 170448, 170452, + 170457, 170464, 170468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 170475, 170480, 170484, 170489, 170494, 170499, 170504, 170508, + 170513, 170517, 170521, 170525, 170530, 170535, 170540, 170544, 170549, + 170554, 170559, 170564, 170569, 170573, 170577, 170582, 170586, 170590, + 170595, 170599, 170603, 170607, 170612, 170616, 170621, 170626, 170631, + 170636, 170641, 170646, 170651, 170656, 170661, 170666, 170671, 170676, + 170681, 170686, 170691, 170696, 170701, 170706, 170710, 170714, 170718, + 170722, 170726, 170730, 170734, 170738, 0, 0, 0, 0, 0, 170742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 170703, 170709, 170716, 170723, 170730, 170737, 170743, - 170750, 170757, 170764, 170771, 170777, 170784, 170791, 170798, 170805, - 170811, 170818, 170825, 170832, 170839, 170845, 170852, 170859, 170866, - 170873, 170880, 170887, 170894, 170901, 170908, 170915, 170922, 170929, - 170935, 170941, 170947, 170953, 170959, 170965, 170971, 170977, 0, 0, 0, + 0, 0, 0, 0, 0, 170747, 170753, 170760, 170767, 170774, 170781, 170787, + 170794, 170801, 170808, 170815, 170821, 170828, 170835, 170842, 170849, + 170855, 170862, 170869, 170876, 170883, 170889, 170896, 170903, 170910, + 170917, 170924, 170931, 170938, 170945, 170952, 170959, 170966, 170973, + 170979, 170985, 170991, 170997, 171003, 171009, 171015, 171021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 170983, 170987, 170991, 170995, 170999, 171003, 171007, 0, - 171011, 171017, 171021, 171025, 0, 171029, 171035, 0, 171041, 171047, - 171053, 171059, 171065, 171071, 171077, 171083, 171089, 171095, 171101, - 171107, 171113, 171119, 171125, 0, 171131, 171138, 171144, 171151, - 171158, 171165, 171172, 171179, 171186, 171193, 171200, 171207, 171214, - 171221, 171228, 171235, 171242, 171249, 171256, 171263, 171270, 171277, - 171284, 171291, 171298, 171305, 171312, 171319, 171326, 171333, 171340, - 171347, 171354, 171361, 171368, 171374, 171380, 171386, 171393, 171399, - 171406, 171412, 171419, 171426, 171433, 171440, 171447, 171454, 171460, - 171467, 171474, 171481, 171488, 171495, 171502, 171509, 171515, 171522, - 171529, 171536, 171543, 171550, 171558, 171565, 171572, 171579, 171586, - 171593, 171600, 171607, 171614, 171621, 171628, 171635, 171642, 171648, - 171655, 171662, 171669, 171676, 171683, 171690, 171697, 171705, 171712, - 171718, 171725, 171732, 171739, 171746, 171753, 171760, 171767, 171774, - 171781, 171788, 171795, 171802, 171809, 171816, 171823, 171830, 171837, - 171844, 171851, 171858, 171864, 171871, 171878, 171885, 171892, 171899, - 171906, 171913, 171920, 171927, 171934, 171941, 171948, 171955, 171962, - 171969, 171976, 171983, 171990, 171997, 172004, 172011, 172018, 172026, - 172034, 172042, 172049, 172056, 172063, 172070, 172077, 172084, 172091, - 172098, 172105, 172112, 172118, 172125, 172132, 172139, 172146, 172153, - 172160, 172167, 172174, 172181, 172188, 172195, 172202, 172209, 172216, - 172224, 172232, 172240, 172247, 172254, 172261, 172268, 172275, 172282, - 172289, 172296, 172303, 172310, 172317, 172324, 172331, 172338, 172344, - 172351, 172358, 172365, 172372, 172379, 172386, 172393, 172400, 172407, - 172414, 172421, 172428, 172435, 172442, 172449, 172456, 172463, 172470, - 172477, 172484, 172491, 172498, 0, 0, 172505, 172509, 172513, 172517, - 172521, 172525, 172529, 172533, 172537, 172541, 172547, 172553, 172559, - 172565, 172573, 172581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 171027, 171031, 171035, 171039, 171043, 171047, 171051, 0, + 171055, 171061, 171065, 171069, 0, 171073, 171079, 0, 171085, 171091, + 171097, 171103, 171109, 171115, 171121, 171127, 171133, 171139, 171145, + 171151, 171157, 171163, 171169, 0, 171175, 171182, 171188, 171195, + 171202, 171209, 171216, 171223, 171230, 171237, 171244, 171251, 171258, + 171265, 171272, 171279, 171286, 171293, 171300, 171307, 171314, 171321, + 171328, 171335, 171342, 171349, 171356, 171363, 171370, 171377, 171384, + 171391, 171398, 171405, 171412, 171418, 171424, 171430, 171437, 171443, + 171450, 171456, 171463, 171470, 171477, 171484, 171491, 171498, 171504, + 171511, 171518, 171525, 171532, 171539, 171546, 171553, 171559, 171566, + 171573, 171580, 171587, 171594, 171602, 171609, 171616, 171623, 171630, + 171637, 171644, 171651, 171658, 171665, 171672, 171679, 171686, 171692, + 171699, 171706, 171713, 171720, 171727, 171734, 171741, 171749, 171756, + 171762, 171769, 171776, 171783, 171790, 171797, 171804, 171811, 171818, + 171825, 171832, 171839, 171846, 171853, 171860, 171867, 171874, 171881, + 171888, 171895, 171902, 171908, 171915, 171922, 171929, 171936, 171943, + 171950, 171957, 171964, 171971, 171978, 171985, 171992, 171999, 172006, + 172013, 172020, 172027, 172034, 172041, 172048, 172055, 172062, 172070, + 172078, 172086, 172093, 172100, 172107, 172114, 172121, 172128, 172135, + 172142, 172149, 172156, 172162, 172169, 172176, 172183, 172190, 172197, + 172204, 172211, 172218, 172225, 172232, 172239, 172246, 172253, 172260, + 172268, 172276, 172284, 172291, 172298, 172305, 172312, 172319, 172326, + 172333, 172340, 172347, 172354, 172361, 172368, 172375, 172382, 172388, + 172395, 172402, 172409, 172416, 172423, 172430, 172437, 172444, 172451, + 172458, 172465, 172472, 172479, 172486, 172493, 172500, 172507, 172514, + 172521, 172528, 172535, 172542, 0, 0, 172549, 172553, 172557, 172561, + 172565, 172569, 172573, 172577, 172581, 172585, 172591, 172597, 172603, + 172609, 172617, 172625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 172587, 172593, 172599, 172605, 172611, 172617, 172623, 172629, - 172635, 172640, 172645, 172651, 172656, 172661, 172667, 172673, 172679, - 172685, 172691, 172696, 172701, 172707, 172713, 172718, 172724, 172730, - 172736, 172742, 172748, 172754, 172760, 172766, 172772, 172778, 172784, - 172790, 172796, 172802, 172808, 172814, 172820, 172826, 172832, 172837, - 172842, 172848, 172853, 172858, 172864, 172870, 172876, 172882, 172888, - 172893, 172898, 172904, 172910, 172915, 172921, 172927, 172933, 172939, - 172945, 172951, 172957, 172963, 172969, 172975, 172981, 172987, 172992, - 172997, 173001, 173006, 173013, 173017, 0, 0, 0, 0, 173022, 173027, - 173031, 173035, 173039, 173043, 173047, 173051, 173055, 173059, 0, 0, 0, - 0, 173063, 173069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 172631, 172637, 172643, 172649, 172655, 172661, 172667, 172673, + 172679, 172684, 172689, 172695, 172700, 172705, 172711, 172717, 172723, + 172729, 172735, 172740, 172745, 172751, 172757, 172762, 172768, 172774, + 172780, 172786, 172792, 172798, 172804, 172810, 172816, 172822, 172828, + 172834, 172840, 172846, 172852, 172858, 172864, 172870, 172876, 172881, + 172886, 172892, 172897, 172902, 172908, 172914, 172920, 172926, 172932, + 172937, 172942, 172948, 172954, 172959, 172965, 172971, 172977, 172983, + 172989, 172995, 173001, 173007, 173013, 173019, 173025, 173031, 173036, + 173041, 173045, 173050, 173057, 173061, 0, 0, 0, 0, 173066, 173071, + 173075, 173079, 173083, 173087, 173091, 173095, 173099, 173103, 0, 0, 0, + 0, 173107, 173113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 173075, 173080, 173085, 173090, 173095, 173100, - 173105, 173110, 173115, 173120, 173126, 173132, 173138, 173144, 173150, - 173156, 173162, 173168, 173174, 173181, 173188, 173195, 173203, 173211, - 173219, 173227, 173235, 173243, 173249, 173255, 173261, 173268, 173275, - 173282, 173289, 173296, 173303, 173310, 173317, 173324, 173331, 173338, - 173345, 173352, 173359, 173366, 173372, 173378, 173384, 173390, 173396, - 173403, 173410, 173417, 173424, 173431, 173438, 173445, 173452, 173459, - 173464, 173472, 173480, 173488, 173494, 173501, 173508, 173517, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 173119, 173124, 173129, 173134, 173139, 173144, + 173149, 173154, 173159, 173164, 173170, 173176, 173182, 173188, 173194, + 173200, 173206, 173212, 173218, 173225, 173232, 173239, 173247, 173255, + 173263, 173271, 173279, 173287, 173293, 173299, 173305, 173312, 173319, + 173326, 173333, 173340, 173347, 173354, 173361, 173368, 173375, 173382, + 173389, 173396, 173403, 173410, 173416, 173422, 173428, 173434, 173440, + 173447, 173454, 173461, 173468, 173475, 173482, 173489, 173496, 173503, + 173508, 173516, 173524, 173532, 173538, 173545, 173552, 173561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 173525, 173530, 173535, 173540, 173545, 173550, 173555, 173560, - 173565, 173570, 173576, 173582, 173588, 173594, 173600, 173606, 173612, - 173618, 173624, 173631, 173638, 173645, 173653, 173661, 173669, 173677, - 173685, 173693, 173699, 173705, 173711, 173718, 173725, 173732, 173739, - 173746, 173753, 173760, 173767, 173774, 173781, 173788, 173795, 173802, - 173809, 173816, 173821, 173828, 173835, 173842, 173849, 173856, 173863, - 173870, 173877, 173885, 173895, 173905, 173913, 173922, 173930, 0, 0, 0, + 0, 173569, 173574, 173579, 173584, 173589, 173594, 173599, 173604, + 173609, 173614, 173620, 173626, 173632, 173638, 173644, 173650, 173656, + 173662, 173668, 173675, 173682, 173689, 173697, 173705, 173713, 173721, + 173729, 173737, 173743, 173749, 173755, 173762, 173769, 173776, 173783, + 173790, 173797, 173804, 173811, 173818, 173825, 173832, 173839, 173846, + 173853, 173860, 173865, 173872, 173879, 173886, 173893, 173900, 173907, + 173914, 173921, 173929, 173939, 173949, 173957, 173966, 173974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173938, 173942, 173946, - 173950, 0, 173954, 173958, 173962, 173966, 173970, 173974, 173978, - 173982, 173986, 173990, 173994, 173998, 174002, 174006, 174010, 174014, - 174018, 174022, 174026, 174030, 174034, 174038, 174042, 174046, 174052, - 174058, 174064, 0, 174070, 174075, 0, 174080, 0, 0, 174085, 0, 174090, - 174095, 174100, 174105, 174110, 174115, 174120, 174125, 174130, 174135, - 0, 174140, 174145, 174150, 174155, 0, 174160, 0, 174165, 0, 0, 0, 0, 0, - 0, 174170, 0, 0, 0, 0, 174176, 0, 174182, 0, 174188, 0, 174194, 174200, - 174206, 0, 174212, 174218, 0, 174224, 0, 0, 174230, 0, 174236, 0, 174242, - 0, 174248, 0, 174256, 0, 174264, 174270, 0, 174276, 0, 0, 174282, 174288, - 174294, 174300, 0, 174306, 174312, 174318, 174324, 174330, 174336, - 174342, 0, 174348, 174354, 174360, 174366, 0, 174372, 174378, 174384, - 174390, 0, 174398, 0, 174406, 174412, 174418, 174424, 174430, 174436, - 174442, 174448, 174454, 174460, 0, 174466, 174472, 174478, 174484, - 174490, 174496, 174502, 174508, 174514, 174520, 174526, 174532, 174538, - 174544, 174550, 174556, 174562, 0, 0, 0, 0, 0, 174568, 174574, 174580, 0, - 174586, 174592, 174598, 174604, 174610, 0, 174616, 174622, 174628, - 174634, 174640, 174646, 174652, 174658, 174664, 174670, 174676, 174682, - 174688, 174694, 174700, 174706, 174712, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173982, 173986, 173990, + 173994, 0, 173998, 174002, 174006, 174010, 174014, 174018, 174022, + 174026, 174030, 174034, 174038, 174042, 174046, 174050, 174054, 174058, + 174062, 174066, 174070, 174074, 174078, 174082, 174086, 174090, 174096, + 174102, 174108, 0, 174114, 174119, 0, 174124, 0, 0, 174129, 0, 174134, + 174139, 174144, 174149, 174154, 174159, 174164, 174169, 174174, 174179, + 0, 174184, 174189, 174194, 174199, 0, 174204, 0, 174209, 0, 0, 0, 0, 0, + 0, 174214, 0, 0, 0, 0, 174220, 0, 174226, 0, 174232, 0, 174238, 174244, + 174250, 0, 174256, 174262, 0, 174268, 0, 0, 174274, 0, 174280, 0, 174286, + 0, 174292, 0, 174300, 0, 174308, 174314, 0, 174320, 0, 0, 174326, 174332, + 174338, 174344, 0, 174350, 174356, 174362, 174368, 174374, 174380, + 174386, 0, 174392, 174398, 174404, 174410, 0, 174416, 174422, 174428, + 174434, 0, 174442, 0, 174450, 174456, 174462, 174468, 174474, 174480, + 174486, 174492, 174498, 174504, 0, 174510, 174516, 174522, 174528, + 174534, 174540, 174546, 174552, 174558, 174564, 174570, 174576, 174582, + 174588, 174594, 174600, 174606, 0, 0, 0, 0, 0, 174612, 174618, 174624, 0, + 174630, 174636, 174642, 174648, 174654, 0, 174660, 174666, 174672, + 174678, 174684, 174690, 174696, 174702, 174708, 174714, 174720, 174726, + 174732, 174738, 174744, 174750, 174756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174718, 174728, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174736, 174743, 174750, 174757, - 174763, 174770, 174777, 174783, 174790, 174797, 174804, 174812, 174820, - 174828, 174836, 174844, 174852, 174859, 174866, 174873, 174881, 174889, - 174897, 174905, 174913, 174921, 174928, 174935, 174942, 174950, 174958, - 174966, 174974, 174982, 174990, 174995, 175000, 175005, 175010, 175015, - 175020, 175025, 175030, 175035, 0, 0, 0, 0, 175040, 175047, 175052, - 175057, 175062, 175067, 175072, 175077, 175082, 175087, 175092, 175097, - 175102, 175107, 175112, 175117, 175122, 175127, 175132, 175137, 175142, - 175147, 175152, 175157, 175162, 175167, 175172, 175177, 175182, 175187, - 175192, 175197, 175202, 175207, 175212, 175217, 175222, 175227, 175232, - 175237, 175242, 175247, 175252, 175257, 175262, 175267, 175272, 175277, - 175282, 175287, 175292, 175298, 175303, 175308, 175313, 175318, 175323, - 175328, 175333, 175338, 175343, 175348, 175353, 175358, 175363, 175368, - 175373, 175378, 175383, 175388, 175393, 175398, 175403, 175408, 175413, - 175418, 175423, 175428, 175433, 175438, 175443, 175448, 175453, 175458, - 175463, 175468, 175473, 175478, 175483, 175488, 175493, 175498, 175503, - 175508, 175513, 175518, 175523, 175528, 175533, 175538, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 175543, 175549, 175558, 175566, 175574, 175583, 175592, - 175601, 175610, 175619, 175628, 175637, 175646, 175655, 175664, 0, 0, - 175673, 175682, 175690, 175698, 175707, 175716, 175725, 175734, 175743, - 175752, 175761, 175770, 175779, 175788, 175797, 0, 175805, 175814, - 175822, 175830, 175839, 175848, 175857, 175866, 175875, 175884, 175893, - 175902, 175911, 175920, 175929, 0, 175936, 175945, 175953, 175961, - 175970, 175979, 175988, 175997, 176006, 176015, 176024, 176033, 176042, - 176051, 176060, 176067, 176073, 176079, 176085, 176091, 176097, 176103, - 176109, 176115, 176121, 176127, 176133, 176139, 176145, 176151, 176157, - 176163, 176169, 176175, 176181, 176187, 176193, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 176199, 176206, 176211, 176215, 176219, 176223, 176228, 176233, - 176238, 176243, 176248, 176253, 176260, 176269, 176275, 176279, 176288, - 176293, 176299, 176305, 176311, 176316, 176322, 176328, 176334, 176339, - 176345, 176351, 176356, 176362, 176368, 176373, 176379, 176385, 176390, - 176396, 176402, 176407, 176413, 176419, 176425, 176431, 176437, 176448, - 176455, 176461, 176464, 176467, 176470, 176475, 176481, 176487, 176493, - 176498, 176504, 176510, 176516, 176521, 176527, 176533, 176538, 176544, - 176550, 176555, 176561, 176567, 176572, 176578, 176584, 176589, 176595, - 176601, 176607, 176613, 176619, 176622, 176625, 176628, 176631, 176634, - 176637, 176644, 176652, 176660, 176668, 176675, 176683, 176691, 176699, - 176706, 176714, 176722, 176729, 176737, 176745, 176752, 176760, 176768, - 176775, 176783, 176791, 176798, 176806, 176814, 176822, 176830, 176838, - 176843, 176848, 176853, 176856, 176864, 176869, 176876, 176884, 176892, - 176900, 176907, 176915, 176923, 176931, 176938, 176946, 176954, 176961, - 176969, 176977, 176984, 176992, 177000, 177007, 177015, 177023, 177030, - 177038, 177046, 177054, 177062, 177070, 177080, 177085, 177089, 177093, - 177098, 177103, 177106, 177109, 177112, 177115, 177118, 177121, 177124, - 177127, 177130, 177136, 177139, 177143, 177148, 177152, 177157, 177162, - 177168, 177174, 177180, 177185, 177193, 177199, 177202, 177205, 177208, - 177211, 177214, 177217, 177220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174762, 174772, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174780, 174787, 174794, 174801, + 174807, 174814, 174821, 174827, 174834, 174841, 174848, 174856, 174864, + 174872, 174880, 174888, 174896, 174903, 174910, 174917, 174925, 174933, + 174941, 174949, 174957, 174965, 174972, 174979, 174986, 174994, 175002, + 175010, 175018, 175026, 175034, 175039, 175044, 175049, 175054, 175059, + 175064, 175069, 175074, 175079, 0, 0, 0, 0, 175084, 175091, 175096, + 175101, 175106, 175111, 175116, 175121, 175126, 175131, 175136, 175141, + 175146, 175151, 175156, 175161, 175166, 175171, 175176, 175181, 175186, + 175191, 175196, 175201, 175206, 175211, 175216, 175221, 175226, 175231, + 175236, 175241, 175246, 175251, 175256, 175261, 175266, 175271, 175276, + 175281, 175286, 175291, 175296, 175301, 175306, 175311, 175316, 175321, + 175326, 175331, 175336, 175342, 175347, 175352, 175357, 175362, 175367, + 175372, 175377, 175382, 175387, 175392, 175397, 175402, 175407, 175412, + 175417, 175422, 175427, 175432, 175437, 175442, 175447, 175452, 175457, + 175462, 175467, 175472, 175477, 175482, 175487, 175492, 175497, 175502, + 175507, 175512, 175517, 175522, 175527, 175532, 175537, 175542, 175547, + 175552, 175557, 175562, 175567, 175572, 175577, 175582, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 175587, 175593, 175602, 175610, 175618, 175627, 175636, + 175645, 175654, 175663, 175672, 175681, 175690, 175699, 175708, 0, 0, + 175717, 175726, 175734, 175742, 175751, 175760, 175769, 175778, 175787, + 175796, 175805, 175814, 175823, 175832, 175841, 0, 175849, 175858, + 175866, 175874, 175883, 175892, 175901, 175910, 175919, 175928, 175937, + 175946, 175955, 175964, 175973, 0, 175980, 175989, 175997, 176005, + 176014, 176023, 176032, 176041, 176050, 176059, 176068, 176077, 176086, + 176095, 176104, 176111, 176117, 176123, 176129, 176135, 176141, 176147, + 176153, 176159, 176165, 176171, 176177, 176183, 176189, 176195, 176201, + 176207, 176213, 176219, 176225, 176231, 176237, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 176243, 176250, 176255, 176259, 176263, 176267, 176272, 176277, + 176282, 176287, 176292, 176297, 176304, 176313, 176319, 176323, 176332, + 176337, 176343, 176349, 176355, 176360, 176366, 176372, 176378, 176383, + 176389, 176395, 176400, 176406, 176412, 176417, 176423, 176429, 176434, + 176440, 176446, 176451, 176457, 176463, 176469, 176475, 176481, 176492, + 176499, 176505, 176508, 176511, 176514, 176519, 176525, 176531, 176537, + 176542, 176548, 176554, 176560, 176565, 176571, 176577, 176582, 176588, + 176594, 176599, 176605, 176611, 176616, 176622, 176628, 176633, 176639, + 176645, 176651, 176657, 176663, 176666, 176669, 176672, 176675, 176678, + 176681, 176688, 176696, 176704, 176712, 176719, 176727, 176735, 176743, + 176750, 176758, 176766, 176773, 176781, 176789, 176796, 176804, 176812, + 176819, 176827, 176835, 176842, 176850, 176858, 176866, 176874, 176882, + 176887, 176892, 176897, 176900, 176908, 176913, 176920, 176928, 176936, + 176944, 176951, 176959, 176967, 176975, 176982, 176990, 176998, 177005, + 177013, 177021, 177028, 177036, 177044, 177051, 177059, 177067, 177074, + 177082, 177090, 177098, 177106, 177114, 177124, 177129, 177133, 177137, + 177142, 177147, 177150, 177153, 177156, 177159, 177162, 177165, 177168, + 177171, 177174, 177180, 177183, 177187, 177192, 177196, 177201, 177206, + 177212, 177218, 177224, 177229, 177237, 177243, 177246, 177249, 177252, + 177255, 177258, 177261, 177264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177225, 177232, - 177240, 177248, 177256, 177263, 177271, 177279, 177287, 177294, 177302, - 177310, 177317, 177325, 177333, 177340, 177348, 177356, 177363, 177371, - 177379, 177386, 177394, 177402, 177410, 177418, 177426, 177431, 177435, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177438, 177444, 177450, 177456, - 177460, 177466, 177472, 177478, 177484, 177490, 177496, 177502, 177508, - 177514, 177520, 177526, 177532, 177538, 177544, 177550, 177556, 177562, - 177568, 177574, 177580, 177586, 177592, 177598, 177604, 177610, 177616, - 177622, 177628, 177634, 177640, 177646, 177652, 177658, 177664, 177670, - 177676, 177682, 177688, 177694, 0, 0, 0, 0, 177700, 177711, 177722, - 177733, 177744, 177755, 177766, 177777, 177788, 0, 0, 0, 0, 0, 0, 0, - 177799, 177804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177809, 177815, - 177821, 177827, 177833, 177839, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177845, 177847, 177849, 177853, - 177858, 177863, 177865, 177871, 177876, 177878, 177884, 177888, 177890, - 177894, 177900, 177906, 177912, 177917, 177922, 177929, 177936, 177943, - 177948, 177955, 177962, 177969, 177973, 177980, 177989, 177998, 178005, - 178010, 178014, 178018, 178020, 178023, 178026, 178033, 178040, 178050, - 178055, 178060, 178065, 178070, 178072, 178078, 178082, 178084, 178086, - 178088, 178090, 178094, 178098, 178102, 178104, 178108, 178110, 178114, - 178116, 178118, 178120, 178122, 178127, 178132, 178134, 178140, 178144, - 178148, 178156, 178158, 178160, 178162, 178164, 178166, 178168, 178170, - 178172, 178174, 178176, 178180, 178184, 178186, 178188, 178190, 178192, - 178194, 178199, 178205, 178209, 178213, 178217, 178221, 178226, 178230, - 178232, 178234, 178238, 178244, 178246, 178248, 178250, 178254, 178263, - 178269, 178273, 178277, 178279, 178281, 178284, 178286, 178288, 178290, - 178294, 178296, 178300, 178305, 178307, 178312, 178318, 178325, 178329, - 178333, 178337, 178341, 178347, 178351, 178359, 178366, 178368, 178370, - 178374, 178378, 178380, 178384, 178388, 178390, 178394, 178396, 178400, - 178404, 178408, 178412, 178416, 178420, 178424, 178428, 178434, 178438, - 178442, 178453, 178458, 178462, 178466, 178472, 178476, 178480, 178484, - 178491, 178498, 178502, 178506, 178510, 178514, 178518, 178525, 178527, - 178531, 178533, 178535, 178539, 178543, 178547, 178549, 178553, 178557, - 178561, 178565, 178569, 178571, 178575, 178577, 178583, 178586, 178591, - 178593, 178595, 178598, 178600, 178602, 178605, 178612, 178619, 178626, - 178631, 178635, 178637, 178639, 178641, 178645, 178647, 178651, 178655, - 178659, 178661, 178665, 178667, 178671, 178675, 178682, 178684, 178693, - 178702, 178711, 178717, 178719, 178724, 178728, 178732, 178734, 178740, - 178744, 178746, 178750, 178754, 178756, 178760, 178765, 178769, 178775, - 178781, 178783, 178785, 178791, 178793, 178797, 178801, 178803, 178807, - 178809, 178813, 178817, 178821, 178824, 178827, 178832, 178837, 178839, - 178842, 178844, 178851, 178855, 178857, 178864, 178871, 178878, 178885, - 178892, 178894, 178896, 178898, 178902, 178904, 178906, 178908, 178910, - 178912, 178914, 178916, 178918, 178920, 178922, 178924, 178926, 178928, - 178930, 178932, 178934, 178936, 178938, 178940, 178942, 178944, 178946, - 178950, 178952, 178954, 178956, 178960, 178962, 178966, 178968, 178970, - 178974, 178978, 178984, 178986, 178988, 178990, 178992, 178996, 179000, - 179002, 179006, 179010, 179014, 179018, 179022, 179026, 179030, 179034, - 179038, 179042, 179046, 179050, 179054, 179058, 179062, 179066, 179070, - 179074, 179076, 179078, 179080, 179082, 179084, 179086, 179088, 179096, - 179104, 179112, 179120, 179125, 179130, 179135, 179139, 179143, 179148, - 179153, 179155, 179159, 179161, 179163, 179165, 179167, 179169, 179171, - 179173, 179177, 179179, 179181, 179183, 179187, 179191, 179195, 179199, - 179203, 179205, 179211, 179217, 179219, 179221, 179223, 179225, 179227, - 179236, 179243, 179250, 179254, 179261, 179266, 179273, 179282, 179287, - 179291, 179295, 179297, 179301, 179303, 179307, 179311, 179313, 179317, - 179321, 179325, 179327, 179329, 179335, 179337, 179339, 179341, 179345, - 179349, 179351, 179355, 179357, 179359, 179362, 179366, 179368, 179372, - 179374, 179376, 179381, 179383, 179387, 179391, 179394, 179398, 179402, - 179406, 179410, 179414, 179418, 179422, 179427, 179431, 179435, 179444, - 179449, 179452, 179454, 179457, 179460, 179465, 179467, 179470, 179475, - 179479, 179482, 179486, 179490, 179493, 179498, 179502, 179506, 179510, - 179514, 179520, 179526, 179532, 179538, 179543, 179554, 179556, 179560, - 179562, 179564, 179568, 179572, 179574, 179578, 179584, 179589, 179595, - 179597, 179601, 179605, 179612, 179619, 179623, 179625, 179627, 179631, - 179633, 179637, 179641, 179645, 179647, 179649, 179656, 179660, 179664, - 179668, 179672, 179676, 179678, 179682, 179684, 179686, 179690, 179692, - 179696, 179700, 179706, 179710, 179714, 179718, 179720, 179723, 179727, - 179734, 179743, 179752, 179761, 179770, 179772, 179776, 179778, 179782, - 179793, 179797, 179803, 179809, 179814, 179816, 179821, 179825, 179827, - 179829, 179831, 179835, 179839, 179843, 179848, 179859, 179875, 179888, - 179901, 179905, 179909, 179915, 179917, 179925, 179933, 179935, 179939, - 179945, 179951, 179958, 179965, 179967, 179969, 179973, 179975, 179981, - 179983, 179986, 179990, 179996, 180002, 180013, 180019, 180026, 180034, - 180038, 180046, 180054, 180060, 180066, 180073, 180075, 180079, 180081, - 180083, 180088, 180090, 180092, 180094, 180096, 180100, 180110, 180116, - 180120, 180124, 180128, 180134, 180140, 180146, 180152, 180157, 180162, - 180168, 180174, 180181, 180188, 180195, 180202, 180207, 180215, 180219, - 180228, 180237, 180243, 180247, 180251, 180255, 180258, 180263, 180265, - 180267, 180269, 180276, 180281, 180288, 180295, 180302, 180310, 180318, - 180326, 180334, 180342, 180350, 180358, 180366, 180374, 180380, 180386, - 180392, 180398, 180404, 180410, 180416, 180422, 180428, 180434, 180440, - 180446, 180449, 180458, 180467, 180469, 180476, 180480, 180482, 180484, - 180488, 180494, 180498, 180500, 180510, 180516, 180520, 180522, 180526, - 180528, 180532, 180539, 180546, 180553, 180558, 180563, 180572, 180578, - 180583, 180587, 180592, 180596, 180603, 180607, 180610, 180614, 180620, - 180626, 180630, 180634, 180639, 180645, 180654, 180665, 180671, 180677, - 180683, 180693, 180708, 180717, 180725, 180733, 180741, 180749, 180757, - 180765, 180773, 180781, 180789, 180797, 180805, 180813, 180816, 180820, - 180825, 180830, 180832, 180836, 180845, 180854, 180862, 180866, 180870, - 180875, 180880, 180885, 180887, 180892, 180896, 180898, 180902, 180906, - 180912, 180917, 180925, 180930, 180935, 180940, 180947, 180950, 180952, - 180956, 180961, 180967, 180971, 180975, 180981, 180987, 180989, 180993, - 180997, 181001, 181005, 181009, 181011, 181013, 181015, 181017, 181023, - 181029, 181033, 181035, 181037, 181039, 181048, 181052, 181059, 181066, - 181068, 181071, 181075, 181081, 181085, 181089, 181091, 181099, 181103, - 181107, 181112, 181116, 181121, 181126, 181131, 181136, 181141, 181146, - 181151, 181156, 181160, 181166, 181170, 181176, 181181, 181188, 181194, - 181202, 181206, 181213, 181217, 181221, 181225, 181230, 181235, 181237, - 181241, 181250, 181258, 181267, 181281, 181295, 181309, 181316, 181323, - 181327, 181336, 181344, 181348, 181357, 181364, 181368, 181372, 181376, - 181380, 181387, 181391, 181395, 181399, 181403, 181410, 181419, 181428, - 181435, 181447, 181459, 181463, 181467, 181471, 181475, 181479, 181483, - 181491, 181499, 181508, 181512, 181516, 181520, 181524, 181528, 181532, - 181538, 181545, 181549, 181561, 181569, 181573, 181577, 181581, 181585, - 181591, 181598, 181609, 181619, 181630, 181641, 181650, 181661, 181667, - 181673, 181679, 181685, 181691, 181695, 181702, 181711, 181718, 181724, - 181728, 181732, 181736, 181745, 181757, 181761, 181768, 181775, 181782, - 181790, 181797, 181805, 181813, 181822, 181830, 181839, 181848, 181858, - 181867, 181877, 181887, 181898, 181908, 181919, 181926, 181934, 181941, - 181949, 181957, 181966, 181974, 181983, 181990, 182002, 182009, 182021, - 182024, 182028, 182031, 182035, 182041, 182048, 182055, 182063, 182068, - 182074, 182085, 182095, 182106, 182111, 182116, 182122, 182127, 182134, - 182138, 182144, 182146, 182148, 182152, 182156, 182160, 182169, 182171, - 182173, 182176, 182178, 182180, 182184, 182186, 182190, 182192, 182196, - 182198, 182200, 182204, 182208, 182214, 182216, 182220, 182222, 182226, - 182230, 182234, 182238, 182240, 182242, 182246, 182250, 182254, 182258, - 182260, 182262, 182264, 182270, 182275, 182278, 182286, 182294, 182296, - 182301, 182304, 182309, 182320, 182327, 182332, 182337, 182339, 182343, - 182345, 182349, 182351, 182355, 182359, 182362, 182365, 182367, 182370, - 182372, 182376, 182378, 182380, 182382, 182386, 182388, 182392, 182395, - 182402, 182405, 182410, 182413, 182416, 182421, 182425, 182429, 182433, - 182435, 182440, 182443, 182447, 182449, 182451, 182455, 182457, 0, 0, 0, - 0, 182459, 182461, 182465, 182467, 182471, 182476, 182478, 182482, - 182484, 182488, 182492, 182498, 182502, 182507, 182510, 182514, 182518, - 0, 0, 0, 182522, 182524, 182530, 182534, 182538, 182540, 182544, 182546, - 182548, 182552, 182554, 182558, 182562, 0, 0, 0, 182566, 182571, 182576, - 182581, 182586, 182591, 182596, 182603, 182610, 182617, 182624, 182629, - 182634, 182639, 182644, 182651, 182657, 182664, 182671, 182678, 182683, - 182688, 182693, 182698, 182703, 182710, 182717, 182722, 182727, 182734, - 182741, 182749, 182757, 182764, 182771, 182779, 182787, 182795, 182802, - 182812, 182823, 182828, 182835, 182842, 182849, 182857, 182865, 182876, - 182884, 182892, 182900, 182905, 182910, 182915, 182920, 182925, 182930, - 182935, 182940, 182945, 182950, 182955, 182960, 182967, 182972, 182977, - 182984, 182989, 182994, 182999, 183004, 183009, 183014, 183019, 183024, - 183029, 183034, 183039, 183044, 183051, 183059, 183064, 183069, 183076, - 183081, 183086, 183091, 183098, 183103, 183110, 183115, 183122, 183127, - 183136, 183145, 183150, 183155, 183160, 183165, 183170, 183175, 183180, - 183185, 183190, 183195, 183200, 183205, 183210, 183218, 183226, 183231, - 183236, 183241, 183246, 183251, 183257, 183263, 183268, 183270, 0, 0, 0, - 0, 183274, 183276, 183278, 183280, 183282, 183284, 183292, 183300, - 183308, 183316, 183322, 183328, 183332, 183336, 183342, 183348, 183357, - 183361, 183366, 183372, 183376, 183381, 183385, 183389, 183395, 183401, - 183411, 183420, 183423, 183428, 183434, 183440, 183451, 183461, 183465, - 183470, 183476, 183482, 183491, 183496, 183500, 183505, 183509, 183515, - 183521, 183527, 183531, 183534, 183538, 183541, 183544, 183549, 183554, - 183561, 183569, 183576, 183583, 183592, 183601, 183608, 183616, 183623, - 183630, 183639, 183648, 183655, 183663, 183670, 183677, 183686, 183693, - 183701, 183707, 183716, 183724, 183733, 183740, 183750, 183761, 183769, - 183777, 183786, 183794, 183802, 183811, 183819, 183829, 183838, 183846, - 183854, 183863, 183866, 183871, 183874, 183879, 0, 0, 0, 0, 0, 0, 183886, - 183892, 183898, 183904, 183910, 183916, 183922, 183928, 183934, 183940, - 183946, 183952, 0, 0, 0, 0, 183958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 183962, 183970, 183979, 183987, 183996, 184005, 184015, 184024, - 184034, 184043, 184053, 184062, 0, 0, 0, 0, 184072, 184080, 184089, - 184097, 184106, 184113, 184121, 184128, 184136, 184144, 184153, 184161, - 184170, 184180, 184191, 184201, 184212, 184221, 184231, 184240, 184250, - 184259, 184269, 184278, 184288, 184296, 184305, 184313, 184322, 184330, - 184339, 184347, 184356, 184366, 184377, 184387, 184398, 184402, 184407, - 184411, 184416, 184419, 184423, 184426, 184430, 184434, 184439, 184443, - 184448, 184453, 184459, 184464, 184470, 184473, 184477, 184480, 0, 0, 0, - 0, 0, 0, 0, 0, 184484, 184487, 184491, 184494, 184498, 184503, 184508, - 184514, 184520, 184524, 0, 0, 0, 0, 0, 0, 184528, 184534, 184541, 184547, - 184554, 184562, 184570, 184579, 184588, 184593, 184599, 184604, 184610, - 184617, 184624, 184632, 184640, 184647, 184655, 184662, 184670, 184679, - 184688, 184698, 184708, 184714, 184721, 184727, 184734, 184742, 184750, - 184759, 184768, 184776, 184785, 184793, 184802, 184812, 184822, 184833, - 0, 0, 0, 0, 0, 0, 0, 0, 184844, 184849, 184855, 184860, 184866, 184875, - 184885, 184894, 184904, 184911, 184919, 184926, 184934, 184941, 184950, - 184959, 184968, 184973, 184980, 184987, 184994, 184999, 185004, 185009, - 185014, 185021, 185028, 185035, 185042, 185049, 0, 0, 185058, 185068, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177269, 177276, + 177284, 177292, 177300, 177307, 177315, 177323, 177331, 177338, 177346, + 177354, 177361, 177369, 177377, 177384, 177392, 177400, 177407, 177415, + 177423, 177430, 177438, 177446, 177454, 177462, 177470, 177475, 177479, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177482, 177488, 177494, 177500, + 177504, 177510, 177516, 177522, 177528, 177534, 177540, 177546, 177552, + 177558, 177564, 177570, 177576, 177582, 177588, 177594, 177600, 177606, + 177612, 177618, 177624, 177630, 177636, 177642, 177648, 177654, 177660, + 177666, 177672, 177678, 177684, 177690, 177696, 177702, 177708, 177714, + 177720, 177726, 177732, 177738, 0, 0, 0, 0, 177744, 177755, 177766, + 177777, 177788, 177799, 177810, 177821, 177832, 0, 0, 0, 0, 0, 0, 0, + 177843, 177848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177853, 177859, + 177865, 177871, 177877, 177883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177889, 177891, 177893, 177897, + 177902, 177907, 177909, 177915, 177920, 177922, 177928, 177932, 177934, + 177938, 177944, 177950, 177956, 177961, 177966, 177973, 177980, 177987, + 177992, 177999, 178006, 178013, 178017, 178024, 178033, 178042, 178049, + 178054, 178058, 178062, 178064, 178067, 178070, 178077, 178084, 178094, + 178099, 178104, 178109, 178114, 178116, 178122, 178126, 178128, 178130, + 178132, 178134, 178138, 178142, 178146, 178148, 178152, 178154, 178158, + 178160, 178162, 178164, 178166, 178171, 178176, 178178, 178184, 178188, + 178192, 178200, 178202, 178204, 178206, 178208, 178210, 178212, 178214, + 178216, 178218, 178220, 178224, 178228, 178230, 178232, 178234, 178236, + 178238, 178243, 178249, 178253, 178257, 178261, 178265, 178270, 178274, + 178276, 178278, 178282, 178288, 178290, 178292, 178294, 178298, 178307, + 178313, 178317, 178321, 178323, 178325, 178328, 178330, 178332, 178334, + 178338, 178340, 178344, 178349, 178351, 178356, 178362, 178369, 178373, + 178377, 178381, 178385, 178391, 178395, 178403, 178410, 178412, 178414, + 178418, 178422, 178424, 178428, 178432, 178434, 178438, 178440, 178444, + 178448, 178452, 178456, 178460, 178464, 178468, 178472, 178478, 178482, + 178486, 178497, 178502, 178506, 178510, 178516, 178520, 178524, 178528, + 178535, 178542, 178546, 178550, 178554, 178558, 178562, 178569, 178571, + 178575, 178577, 178579, 178583, 178587, 178591, 178593, 178597, 178601, + 178605, 178609, 178613, 178615, 178619, 178621, 178627, 178630, 178635, + 178637, 178639, 178642, 178644, 178646, 178649, 178656, 178663, 178670, + 178675, 178679, 178681, 178683, 178685, 178689, 178691, 178695, 178699, + 178703, 178705, 178709, 178711, 178715, 178719, 178726, 178728, 178737, + 178746, 178755, 178761, 178763, 178768, 178772, 178776, 178778, 178784, + 178788, 178790, 178794, 178798, 178800, 178804, 178809, 178813, 178819, + 178825, 178827, 178829, 178835, 178837, 178841, 178845, 178847, 178851, + 178853, 178857, 178861, 178865, 178868, 178871, 178876, 178881, 178883, + 178886, 178888, 178895, 178899, 178901, 178908, 178915, 178922, 178929, + 178936, 178938, 178940, 178942, 178946, 178948, 178950, 178952, 178954, + 178956, 178958, 178960, 178962, 178964, 178966, 178968, 178970, 178972, + 178974, 178976, 178978, 178980, 178982, 178984, 178986, 178988, 178990, + 178994, 178996, 178998, 179000, 179004, 179006, 179010, 179012, 179014, + 179018, 179022, 179028, 179030, 179032, 179034, 179036, 179040, 179044, + 179046, 179050, 179054, 179058, 179062, 179066, 179070, 179074, 179078, + 179082, 179086, 179090, 179094, 179098, 179102, 179106, 179110, 179114, + 179118, 179120, 179122, 179124, 179126, 179128, 179130, 179132, 179140, + 179148, 179156, 179164, 179169, 179174, 179179, 179183, 179187, 179192, + 179197, 179199, 179203, 179205, 179207, 179209, 179211, 179213, 179215, + 179217, 179221, 179223, 179225, 179227, 179231, 179235, 179239, 179243, + 179247, 179249, 179255, 179261, 179263, 179265, 179267, 179269, 179271, + 179280, 179287, 179294, 179298, 179305, 179310, 179317, 179326, 179331, + 179335, 179339, 179341, 179345, 179347, 179351, 179355, 179357, 179361, + 179365, 179369, 179371, 179373, 179379, 179381, 179383, 179385, 179389, + 179393, 179395, 179399, 179401, 179403, 179406, 179410, 179412, 179416, + 179418, 179420, 179425, 179427, 179431, 179435, 179438, 179442, 179446, + 179450, 179454, 179458, 179462, 179466, 179471, 179475, 179479, 179488, + 179493, 179496, 179498, 179501, 179504, 179509, 179511, 179514, 179519, + 179523, 179526, 179530, 179534, 179537, 179542, 179546, 179550, 179554, + 179558, 179564, 179570, 179576, 179582, 179587, 179598, 179600, 179604, + 179606, 179608, 179612, 179616, 179618, 179622, 179628, 179633, 179639, + 179641, 179645, 179649, 179656, 179663, 179667, 179669, 179671, 179675, + 179677, 179681, 179685, 179689, 179691, 179693, 179700, 179704, 179708, + 179712, 179716, 179720, 179722, 179726, 179728, 179730, 179734, 179736, + 179740, 179744, 179750, 179754, 179758, 179762, 179764, 179767, 179771, + 179778, 179787, 179796, 179805, 179814, 179816, 179820, 179822, 179826, + 179837, 179841, 179847, 179853, 179858, 179860, 179865, 179869, 179871, + 179873, 179875, 179879, 179883, 179887, 179892, 179903, 179919, 179932, + 179945, 179949, 179953, 179959, 179961, 179969, 179977, 179979, 179983, + 179989, 179995, 180002, 180009, 180011, 180013, 180017, 180019, 180025, + 180027, 180030, 180034, 180040, 180046, 180057, 180063, 180070, 180078, + 180082, 180090, 180098, 180104, 180110, 180117, 180119, 180123, 180125, + 180127, 180132, 180134, 180136, 180138, 180140, 180144, 180154, 180160, + 180164, 180168, 180172, 180178, 180184, 180190, 180196, 180201, 180206, + 180212, 180218, 180225, 180232, 180239, 180246, 180251, 180259, 180263, + 180272, 180281, 180287, 180291, 180295, 180299, 180302, 180307, 180309, + 180311, 180313, 180320, 180325, 180332, 180339, 180346, 180354, 180362, + 180370, 180378, 180386, 180394, 180402, 180410, 180418, 180424, 180430, + 180436, 180442, 180448, 180454, 180460, 180466, 180472, 180478, 180484, + 180490, 180493, 180502, 180511, 180513, 180520, 180524, 180526, 180528, + 180532, 180538, 180542, 180544, 180554, 180560, 180564, 180566, 180570, + 180572, 180576, 180583, 180590, 180597, 180602, 180607, 180616, 180622, + 180627, 180631, 180636, 180640, 180647, 180651, 180654, 180658, 180664, + 180670, 180674, 180678, 180683, 180689, 180698, 180709, 180715, 180721, + 180727, 180737, 180752, 180761, 180769, 180777, 180785, 180793, 180801, + 180809, 180817, 180825, 180833, 180841, 180849, 180857, 180860, 180864, + 180869, 180874, 180876, 180880, 180889, 180898, 180906, 180910, 180914, + 180919, 180924, 180929, 180931, 180936, 180940, 180942, 180946, 180950, + 180956, 180961, 180969, 180974, 180979, 180984, 180991, 180994, 180996, + 181000, 181005, 181011, 181015, 181019, 181025, 181031, 181033, 181037, + 181041, 181045, 181049, 181053, 181055, 181057, 181059, 181061, 181067, + 181073, 181077, 181079, 181081, 181083, 181092, 181096, 181103, 181110, + 181112, 181115, 181119, 181125, 181129, 181133, 181135, 181143, 181147, + 181151, 181156, 181160, 181165, 181170, 181175, 181180, 181185, 181190, + 181195, 181200, 181204, 181210, 181214, 181220, 181225, 181232, 181238, + 181246, 181250, 181257, 181261, 181265, 181269, 181274, 181279, 181281, + 181285, 181294, 181302, 181311, 181325, 181339, 181353, 181360, 181367, + 181371, 181380, 181388, 181392, 181401, 181408, 181412, 181416, 181420, + 181424, 181431, 181435, 181439, 181443, 181447, 181454, 181463, 181472, + 181479, 181491, 181503, 181507, 181511, 181515, 181519, 181523, 181527, + 181535, 181543, 181552, 181556, 181560, 181564, 181568, 181572, 181576, + 181582, 181589, 181593, 181605, 181613, 181617, 181621, 181625, 181629, + 181635, 181642, 181653, 181663, 181674, 181685, 181694, 181705, 181711, + 181717, 181723, 181729, 181735, 181739, 181746, 181755, 181762, 181768, + 181772, 181776, 181780, 181789, 181801, 181805, 181812, 181819, 181826, + 181834, 181841, 181849, 181857, 181866, 181874, 181883, 181892, 181902, + 181911, 181921, 181931, 181942, 181952, 181963, 181970, 181978, 181985, + 181993, 182001, 182010, 182018, 182027, 182034, 182046, 182053, 182065, + 182068, 182072, 182075, 182079, 182085, 182092, 182099, 182107, 182112, + 182118, 182129, 182139, 182150, 182155, 182160, 182166, 182171, 182178, + 182182, 182188, 182190, 182192, 182196, 182200, 182204, 182213, 182215, + 182217, 182220, 182222, 182224, 182228, 182230, 182234, 182236, 182240, + 182242, 182244, 182248, 182252, 182258, 182260, 182264, 182266, 182270, + 182274, 182278, 182282, 182284, 182286, 182290, 182294, 182298, 182302, + 182304, 182306, 182308, 182314, 182319, 182322, 182330, 182338, 182340, + 182345, 182348, 182353, 182364, 182371, 182376, 182381, 182383, 182387, + 182389, 182393, 182395, 182399, 182403, 182406, 182409, 182411, 182414, + 182416, 182420, 182422, 182424, 182426, 182430, 182432, 182436, 182439, + 182446, 182449, 182454, 182457, 182460, 182465, 182469, 182473, 182477, + 182479, 182484, 182487, 182491, 182493, 182495, 182499, 182501, 0, 0, 0, + 0, 182503, 182505, 182509, 182511, 182515, 182520, 182522, 182526, + 182528, 182532, 182536, 182542, 182546, 182551, 182554, 182558, 182562, + 0, 0, 0, 182566, 182568, 182574, 182578, 182582, 182584, 182588, 182590, + 182592, 182596, 182598, 182602, 182606, 0, 0, 0, 182610, 182615, 182620, + 182625, 182630, 182635, 182640, 182647, 182654, 182661, 182668, 182673, + 182678, 182683, 182688, 182695, 182701, 182708, 182715, 182722, 182727, + 182732, 182737, 182742, 182747, 182754, 182761, 182766, 182771, 182778, + 182785, 182793, 182801, 182808, 182815, 182823, 182831, 182839, 182846, + 182856, 182867, 182872, 182879, 182886, 182893, 182901, 182909, 182920, + 182928, 182936, 182944, 182949, 182954, 182959, 182964, 182969, 182974, + 182979, 182984, 182989, 182994, 182999, 183004, 183011, 183016, 183021, + 183028, 183033, 183038, 183043, 183048, 183053, 183058, 183063, 183068, + 183073, 183078, 183083, 183088, 183095, 183103, 183108, 183113, 183120, + 183125, 183130, 183135, 183142, 183147, 183154, 183159, 183166, 183171, + 183180, 183189, 183194, 183199, 183204, 183209, 183214, 183219, 183224, + 183229, 183234, 183239, 183244, 183249, 183254, 183262, 183270, 183275, + 183280, 183285, 183290, 183295, 183301, 183307, 183312, 183314, 0, 0, 0, + 0, 183318, 183320, 183322, 183324, 183326, 183328, 183336, 183344, + 183352, 183360, 183366, 183372, 183376, 183380, 183386, 183392, 183401, + 183405, 183410, 183416, 183420, 183425, 183429, 183433, 183439, 183445, + 183455, 183464, 183467, 183472, 183478, 183484, 183495, 183505, 183509, + 183514, 183520, 183526, 183535, 183540, 183544, 183549, 183553, 183559, + 183565, 183571, 183575, 183578, 183582, 183585, 183588, 183593, 183598, + 183605, 183613, 183620, 183627, 183636, 183645, 183652, 183660, 183667, + 183674, 183683, 183692, 183699, 183707, 183714, 183721, 183730, 183737, + 183745, 183751, 183760, 183768, 183777, 183784, 183794, 183805, 183813, + 183821, 183830, 183838, 183846, 183855, 183863, 183873, 183882, 183890, + 183898, 183907, 183910, 183915, 183918, 183923, 0, 0, 0, 0, 0, 0, 183930, + 183936, 183942, 183948, 183954, 183960, 183966, 183972, 183978, 183984, + 183990, 183996, 0, 0, 0, 0, 184002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 184006, 184014, 184023, 184031, 184040, 184049, 184059, 184068, + 184078, 184087, 184097, 184106, 0, 0, 0, 0, 184116, 184124, 184133, + 184141, 184150, 184157, 184165, 184172, 184180, 184188, 184197, 184205, + 184214, 184224, 184235, 184245, 184256, 184265, 184275, 184284, 184294, + 184303, 184313, 184322, 184332, 184340, 184349, 184357, 184366, 184374, + 184383, 184391, 184400, 184410, 184421, 184431, 184442, 184446, 184451, + 184455, 184460, 184463, 184467, 184470, 184474, 184478, 184483, 184487, + 184492, 184497, 184503, 184508, 184514, 184517, 184521, 184524, 0, 0, 0, + 0, 0, 0, 0, 0, 184528, 184531, 184535, 184538, 184542, 184547, 184552, + 184558, 184564, 184568, 0, 0, 0, 0, 0, 0, 184572, 184578, 184585, 184591, + 184598, 184606, 184614, 184623, 184632, 184637, 184643, 184648, 184654, + 184661, 184668, 184676, 184684, 184691, 184699, 184706, 184714, 184723, + 184732, 184742, 184752, 184758, 184765, 184771, 184778, 184786, 184794, + 184803, 184812, 184820, 184829, 184837, 184846, 184856, 184866, 184877, + 0, 0, 0, 0, 0, 0, 0, 0, 184888, 184893, 184899, 184904, 184910, 184919, + 184929, 184938, 184948, 184955, 184963, 184970, 184978, 184985, 184994, + 185003, 185012, 185017, 185024, 185031, 185038, 185043, 185048, 185053, + 185058, 185065, 185072, 185079, 185086, 185093, 0, 0, 185102, 185112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 185080, 185090, 185099, 185104, 185113, 185121, 185129, - 185136, 185140, 185145, 185152, 185161, 185172, 185176, 185179, 185183, - 185187, 185191, 185195, 185200, 185204, 185208, 185213, 185217, 185221, - 185227, 185233, 185240, 185244, 185248, 185250, 185260, 185269, 185276, - 185280, 185284, 185294, 185298, 185302, 185306, 185310, 185318, 185327, - 185340, 185351, 185362, 185378, 185387, 185396, 185400, 185402, 185407, - 185409, 185411, 185417, 185421, 185423, 185429, 185431, 185433, 185437, - 185439, 185443, 185445, 185449, 185453, 185458, 185462, 185466, 185468, - 185472, 185474, 185480, 185486, 185492, 185496, 185502, 185506, 185513, - 185515, 185519, 185521, 185523, 185525, 185527, 185529, 185531, 185535, - 185539, 185546, 185550, 185552, 185557, 185559, 185561, 185563, 185565, - 185569, 185573, 185575, 185580, 185585, 185587, 185589, 185591, 185593, - 185598, 185600, 185604, 185608, 185610, 185614, 185616, 185629, 185633, - 185640, 185652, 185664, 185668, 185672, 185674, 185678, 185686, 185693, - 185695, 185699, 185701, 185705, 185709, 185711, 185715, 185717, 185719, - 185723, 185725, 185727, 185729, 185731, 185733, 185737, 185739, 185741, - 185743, 185745, 185747, 185749, 185751, 185755, 185759, 185761, 185763, - 185765, 185767, 185769, 185771, 185773, 185775, 185777, 185779, 185781, - 185783, 185785, 185787, 185789, 185791, 185793, 185795, 185797, 185799, - 185801, 185803, 185805, 185807, 185809, 185811, 185815, 185819, 185827, - 185835, 185841, 185848, 185850, 185852, 185854, 185856, 185858, 185860, - 185864, 185871, 185875, 185879, 185883, 185887, 185891, 185893, 185897, - 185901, 185903, 185905, 185907, 185909, 185911, 185915, 185919, 185923, - 185925, 185929, 185933, 185937, 185942, 185944, 185946, 185950, 185954, - 185959, 185967, 185971, 185979, 185981, 185983, 185985, 185987, 185989, - 185991, 185993, 185995, 185999, 186003, 186005, 186007, 186009, 186011, - 186017, 186019, 186025, 186029, 186033, 186038, 186040, 186042, 186046, - 186048, 186050, 186052, 186054, 186058, 186063, 186068, 186072, 186076, - 186078, 186080, 186085, 186090, 186092, 186094, 186098, 186104, 186110, - 186116, 186122, 186128, 186134, 186145, 186156, 186168, 186179, 186190, - 186201, 186212, 186223, 186234, 186245, 186256, 186267, 186278, 186289, - 186300, 186312, 186324, 186336, 186348, 186360, 186372, 186386, 186400, - 186415, 186421, 186427, 186433, 186439, 186445, 186451, 186457, 186463, - 186469, 186475, 186481, 186487, 186494, 186501, 186508, 186515, 186522, - 186529, 186543, 186557, 186572, 186586, 186600, 186614, 186628, 186642, - 186656, 186670, 186684, 186698, 186712, 186726, 186740, 186755, 186770, - 186785, 186800, 186815, 186830, 186844, 186858, 186873, 186878, 186883, - 186889, 186900, 186911, 186923, 186928, 186933, 186938, 186943, 186948, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186953, 186959, 186965, 186971, - 186977, 186983, 186989, 186995, 187000, 187005, 187010, 187015, 187020, - 187025, 0, 0, 187030, 187034, 187038, 187040, 187042, 187046, 187051, - 187055, 187059, 187064, 187068, 187070, 187072, 0, 0, 0, 187074, 187076, - 187078, 187080, 187082, 187086, 187088, 187092, 187094, 0, 0, 0, 0, 0, 0, - 0, 187096, 187100, 187102, 187104, 187106, 187110, 187112, 187116, - 187118, 187121, 187123, 187127, 187129, 187131, 187132, 187134, 187136, - 187138, 187142, 187144, 187146, 187150, 187152, 187154, 187156, 187158, - 187162, 187166, 187169, 187171, 187177, 187181, 187183, 187185, 187187, - 187189, 187191, 187195, 187197, 187199, 187201, 187203, 187207, 187212, - 187214, 187216, 0, 187218, 187220, 187224, 187226, 187230, 187234, - 187238, 0, 0, 0, 0, 0, 0, 0, 0, 187243, 187245, 187247, 187249, 187253, - 187255, 187257, 187259, 187261, 187263, 187267, 187269, 187271, 187275, - 0, 0, 0, 0, 187279, 187283, 187287, 187300, 187307, 187314, 187320, - 187324, 187326, 0, 0, 0, 0, 0, 0, 0, 187330, 187340, 187343, 187346, - 187351, 187356, 187365, 187369, 187374, 0, 0, 0, 0, 0, 0, 0, 187379, - 187382, 187385, 187388, 187391, 187394, 187397, 187400, 187403, 187406, - 187409, 187412, 187415, 187418, 187421, 187424, 187427, 187430, 187433, - 187436, 187439, 187442, 187445, 187448, 187451, 187454, 187457, 187460, - 187463, 187466, 187469, 187472, 187475, 187478, 187481, 187484, 187487, - 187490, 187493, 187496, 187499, 187502, 187505, 187508, 187511, 187514, - 187517, 187520, 187523, 187526, 187529, 187532, 187535, 187538, 187541, - 187544, 187547, 187550, 187553, 187556, 187559, 187571, 187582, 187594, - 187605, 187616, 187628, 187639, 187651, 187662, 187673, 187685, 187697, - 187708, 187720, 187731, 187742, 187754, 187765, 187777, 187788, 187799, - 187811, 187823, 187834, 187846, 187857, 187868, 187880, 187891, 187903, - 187914, 187925, 187937, 187949, 187960, 187972, 187983, 187994, 188006, - 188017, 188029, 188040, 188051, 188063, 188075, 188087, 188099, 188111, - 188119, 188127, 188135, 188143, 188149, 188155, 188161, 188167, 188173, - 188179, 188186, 188193, 188200, 188207, 188214, 188221, 188229, 188237, - 188245, 188253, 188261, 188268, 188274, 188280, 188287, 188293, 188300, - 188306, 188312, 188319, 188325, 188332, 188338, 188344, 188350, 188356, - 188362, 188374, 0, 188387, 188400, 188406, 188414, 188419, 188426, - 188433, 188441, 188449, 188457, 188465, 188473, 188481, 188493, 188504, - 188515, 188526, 188541, 188556, 188570, 188584, 188602, 188620, 188639, - 188657, 188675, 188693, 188700, 188708, 188712, 188717, 188723, 188729, - 188739, 188750, 188761, 188771, 188781, 188785, 188789, 188794, 188800, - 188806, 188816, 188822, 188831, 188840, 188849, 188858, 188864, 188868, - 188877, 188885, 188892, 188899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 185124, 185134, 185143, 185148, 185157, 185165, 185173, + 185180, 185184, 185189, 185196, 185205, 185216, 185220, 185223, 185227, + 185231, 185235, 185239, 185244, 185248, 185252, 185257, 185261, 185265, + 185271, 185277, 185284, 185288, 185292, 185294, 185304, 185313, 185320, + 185324, 185328, 185338, 185342, 185346, 185350, 185354, 185362, 185371, + 185384, 185395, 185406, 185422, 185431, 185440, 185444, 185446, 185451, + 185453, 185455, 185461, 185465, 185467, 185473, 185475, 185477, 185481, + 185483, 185487, 185489, 185493, 185497, 185502, 185506, 185510, 185512, + 185516, 185518, 185524, 185530, 185536, 185540, 185546, 185550, 185557, + 185559, 185563, 185565, 185567, 185569, 185571, 185573, 185575, 185579, + 185583, 185590, 185594, 185596, 185601, 185603, 185605, 185607, 185609, + 185613, 185617, 185619, 185624, 185629, 185631, 185633, 185635, 185637, + 185642, 185644, 185648, 185652, 185654, 185658, 185660, 185673, 185677, + 185684, 185696, 185708, 185712, 185716, 185718, 185722, 185730, 185737, + 185739, 185743, 185745, 185749, 185753, 185755, 185759, 185761, 185763, + 185767, 185769, 185771, 185773, 185775, 185777, 185781, 185783, 185785, + 185787, 185789, 185791, 185793, 185795, 185799, 185803, 185805, 185807, + 185809, 185811, 185813, 185815, 185817, 185819, 185821, 185823, 185825, + 185827, 185829, 185831, 185833, 185835, 185837, 185839, 185841, 185843, + 185845, 185847, 185849, 185851, 185853, 185855, 185859, 185863, 185871, + 185879, 185885, 185892, 185894, 185896, 185898, 185900, 185902, 185904, + 185908, 185915, 185919, 185923, 185927, 185931, 185935, 185937, 185941, + 185945, 185947, 185949, 185951, 185953, 185955, 185959, 185963, 185967, + 185969, 185973, 185977, 185981, 185986, 185988, 185990, 185994, 185998, + 186003, 186011, 186015, 186023, 186025, 186027, 186029, 186031, 186033, + 186035, 186037, 186039, 186043, 186047, 186049, 186051, 186053, 186055, + 186061, 186063, 186069, 186073, 186077, 186082, 186084, 186086, 186090, + 186092, 186094, 186096, 186098, 186102, 186107, 186112, 186116, 186120, + 186122, 186124, 186129, 186134, 186136, 186138, 186142, 186148, 186154, + 186160, 186166, 186172, 186178, 186189, 186200, 186212, 186223, 186234, + 186245, 186256, 186267, 186278, 186289, 186300, 186311, 186322, 186333, + 186344, 186356, 186368, 186380, 186392, 186404, 186416, 186430, 186444, + 186459, 186465, 186471, 186477, 186483, 186489, 186495, 186501, 186507, + 186513, 186519, 186525, 186531, 186538, 186545, 186552, 186559, 186566, + 186573, 186587, 186601, 186616, 186630, 186644, 186658, 186672, 186686, + 186700, 186714, 186728, 186742, 186756, 186770, 186784, 186799, 186814, + 186829, 186844, 186859, 186874, 186888, 186902, 186917, 186922, 186927, + 186933, 186944, 186955, 186967, 186972, 186977, 186982, 186987, 186992, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186997, 187003, 187009, 187015, + 187021, 187027, 187033, 187039, 187044, 187049, 187054, 187059, 187064, + 187069, 0, 0, 187074, 187078, 187082, 187084, 187086, 187090, 187095, + 187099, 187103, 187108, 187112, 187114, 187116, 0, 0, 0, 187118, 187120, + 187122, 187124, 187126, 187130, 187132, 187136, 187138, 0, 0, 0, 0, 0, 0, + 0, 187140, 187144, 187146, 187148, 187150, 187154, 187156, 187160, + 187162, 187165, 187167, 187171, 187173, 187175, 187176, 187178, 187180, + 187182, 187186, 187188, 187190, 187194, 187196, 187198, 187200, 187202, + 187206, 187210, 187213, 187215, 187221, 187225, 187227, 187229, 187231, + 187233, 187235, 187239, 187241, 187243, 187245, 187247, 187251, 187256, + 187258, 187260, 0, 187262, 187264, 187268, 187270, 187274, 187278, + 187282, 0, 0, 0, 0, 0, 0, 0, 0, 187287, 187289, 187291, 187293, 187297, + 187299, 187301, 187303, 187305, 187307, 187311, 187313, 187315, 187319, + 0, 0, 0, 0, 187323, 187327, 187331, 187344, 187351, 187358, 187364, + 187368, 187370, 0, 0, 0, 0, 0, 0, 0, 187374, 187384, 187387, 187390, + 187395, 187400, 187409, 187413, 187418, 0, 0, 0, 0, 0, 0, 0, 187423, + 187426, 187429, 187432, 187435, 187438, 187441, 187444, 187447, 187450, + 187453, 187456, 187459, 187462, 187465, 187468, 187471, 187474, 187477, + 187480, 187483, 187486, 187489, 187492, 187495, 187498, 187501, 187504, + 187507, 187510, 187513, 187516, 187519, 187522, 187525, 187528, 187531, + 187534, 187537, 187540, 187543, 187546, 187549, 187552, 187555, 187558, + 187561, 187564, 187567, 187570, 187573, 187576, 187579, 187582, 187585, + 187588, 187591, 187594, 187597, 187600, 187603, 187615, 187626, 187638, + 187649, 187660, 187672, 187683, 187695, 187706, 187717, 187729, 187741, + 187752, 187764, 187775, 187786, 187798, 187809, 187821, 187832, 187843, + 187855, 187867, 187878, 187890, 187901, 187912, 187924, 187935, 187947, + 187958, 187969, 187981, 187993, 188004, 188016, 188027, 188038, 188050, + 188061, 188073, 188084, 188095, 188107, 188119, 188131, 188143, 188155, + 188163, 188171, 188179, 188187, 188193, 188199, 188205, 188211, 188217, + 188223, 188230, 188237, 188244, 188251, 188258, 188265, 188273, 188281, + 188289, 188297, 188305, 188312, 188318, 188324, 188331, 188337, 188344, + 188350, 188356, 188363, 188369, 188376, 188382, 188388, 188394, 188400, + 188406, 188418, 0, 188431, 188444, 188450, 188458, 188463, 188470, + 188477, 188485, 188493, 188501, 188509, 188517, 188525, 188537, 188548, + 188559, 188570, 188585, 188600, 188614, 188628, 188646, 188664, 188683, + 188701, 188719, 188737, 188744, 188752, 188756, 188761, 188767, 188773, + 188783, 188794, 188805, 188815, 188825, 188829, 188833, 188838, 188844, + 188850, 188860, 188866, 188875, 188884, 188893, 188902, 188908, 188912, + 188921, 188929, 188936, 188943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 188904, 188909, 188913, 188917, 188921, 188925, 188929, 188933, 188937, - 188941, 0, 0, 0, 0, 0, 0, 188945, 188949, 188953, 188957, 188961, 188965, - 188969, 188973, 188977, 188981, 188985, 188989, 188993, 188997, 189001, - 189005, 189009, 189013, 189017, 189021, 189025, 189029, 189033, 189037, - 189041, 189045, 189049, 189053, 189057, 189061, 189065, 189069, 189073, - 189077, 189081, 189085, 189089, 189093, 189097, 189101, 189105, 189109, - 189113, 189117, 189121, 189125, 189129, 189133, 189137, 189141, 189145, - 189149, 189153, 189157, 189161, 189165, 189169, 189173, 189177, 189181, - 189185, 189189, 189193, 189197, 189201, 189205, 189209, 189213, 189217, - 189221, 189225, 189229, 189233, 189237, 189241, 189245, 189249, 189253, - 189257, 189261, 189265, 189269, 189273, 189277, 189281, 189285, 189289, - 189293, 189297, 189301, 189305, 189309, 189313, 189317, 189321, 189325, - 189329, 189333, 189337, 189341, 189345, 189349, 189353, 189357, 189361, - 189365, 189369, 189373, 189377, 189381, 189385, 189389, 189393, 189397, - 189401, 189405, 189409, 189413, 189417, 189421, 189425, 189429, 189433, - 189437, 189441, 189445, 189449, 189453, 189457, 189461, 189465, 189469, - 189473, 189477, 189481, 189485, 189489, 189493, 189497, 189501, 189505, - 189509, 189513, 189517, 189521, 189525, 189529, 189533, 189537, 189541, - 189545, 189549, 189553, 189557, 189561, 189565, 189569, 189573, 189577, - 189581, 189585, 189589, 189593, 189597, 189601, 189605, 189609, 189613, - 189617, 189621, 189625, 189629, 189633, 189637, 189641, 189645, 189649, - 189653, 189657, 189661, 189665, 189669, 189673, 189677, 189681, 189685, - 189689, 189693, 189697, 189701, 189705, 189709, 189713, 189717, 189721, - 189725, 189729, 189733, 189737, 189741, 189745, 189749, 189753, 189757, - 189761, 189765, 189769, 189773, 189777, 189781, 189785, 189789, 189793, - 189797, 189801, 189805, 189809, 189813, 189817, 189821, 189825, 189829, - 189833, 189837, 189841, 189845, 189849, 189853, 189857, 189861, 189865, - 189869, 189873, 189877, 189881, 189885, 189889, 189893, 189897, 189901, - 189905, 189909, 189913, 189917, 189921, 189925, 189929, 189933, 189937, - 189941, 189945, 189949, 189953, 189957, 189961, 189965, 189969, 189973, - 189977, 189981, 189985, 189989, 189993, 189997, 190001, 190005, 190009, - 190013, 190017, 190021, 190025, 190029, 190033, 190037, 190041, 190045, - 190049, 190053, 190057, 190061, 190065, 190069, 190073, 190077, 190081, - 190085, 190089, 190093, 190097, 190101, 190105, 190109, 190113, 190117, - 190121, 190125, 190129, 190133, 190137, 190141, 190145, 190149, 190153, - 190157, 190161, 190165, 190169, 190173, 190177, 190181, 190185, 190189, - 190193, 190197, 190201, 190205, 190209, 190213, 190217, 190221, 190225, - 190229, 190233, 190237, 190241, 190245, 190249, 190253, 190257, 190261, - 190265, 190269, 190273, 190277, 190281, 190285, 190289, 190293, 190297, - 190301, 190305, 190309, 190313, 190317, 190321, 190325, 190329, 190333, - 190337, 190341, 190345, 190349, 190353, 190357, 190361, 190365, 190369, - 190373, 190377, 190381, 190385, 190389, 190393, 190397, 190401, 190405, - 190409, 190413, 190417, 190421, 190425, 190429, 190433, 190437, 190441, - 190445, 190449, 190453, 190457, 190461, 190465, 190469, 190473, 190477, - 190481, 190485, 190489, 190493, 190497, 190501, 190505, 190509, 190513, - 190517, 190521, 190525, 190529, 190533, 190537, 190541, 190545, 190549, - 190553, 190557, 190561, 190565, 190569, 190573, 190577, 190581, 190585, - 190589, 190593, 190597, 190601, 190605, 190609, 190613, 190617, 190621, - 190625, 190629, 190633, 190637, 190641, 190645, 190649, 190653, 190657, - 190661, 190665, 190669, 190673, 190677, 190681, 190685, 190689, 190693, - 190697, 190701, 190705, 190709, 190713, 190717, 190721, 190725, 190729, - 190733, 190737, 190741, 190745, 190749, 190753, 190757, 190761, 190765, - 190769, 190773, 190777, 190781, 190785, 190789, 190793, 190797, 190801, - 190805, 190809, 190813, 190817, 190821, 190825, 190829, 190833, 190837, - 190841, 190845, 190849, 190853, 190857, 190861, 190865, 190869, 190873, - 190877, 190881, 190885, 190889, 190893, 190897, 190901, 190905, 190909, - 190913, 190917, 190921, 190925, 190929, 190933, 190937, 190941, 190945, - 190949, 190953, 190957, 190961, 190965, 190969, 190973, 190977, 190981, - 190985, 190989, 190993, 190997, 191001, 191005, 191009, 191013, 191017, - 191021, 191025, 191029, 191033, 191037, 191041, 191045, 191049, 191053, - 191057, 191061, 191065, 191069, 191073, 191077, 191081, 191085, 191089, - 191093, 191097, 191101, 191105, 191109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 188948, 188953, 188957, 188961, 188965, 188969, 188973, 188977, 188981, + 188985, 0, 0, 0, 0, 0, 0, 188989, 188993, 188997, 189001, 189005, 189009, + 189013, 189017, 189021, 189025, 189029, 189033, 189037, 189041, 189045, + 189049, 189053, 189057, 189061, 189065, 189069, 189073, 189077, 189081, + 189085, 189089, 189093, 189097, 189101, 189105, 189109, 189113, 189117, + 189121, 189125, 189129, 189133, 189137, 189141, 189145, 189149, 189153, + 189157, 189161, 189165, 189169, 189173, 189177, 189181, 189185, 189189, + 189193, 189197, 189201, 189205, 189209, 189213, 189217, 189221, 189225, + 189229, 189233, 189237, 189241, 189245, 189249, 189253, 189257, 189261, + 189265, 189269, 189273, 189277, 189281, 189285, 189289, 189293, 189297, + 189301, 189305, 189309, 189313, 189317, 189321, 189325, 189329, 189333, + 189337, 189341, 189345, 189349, 189353, 189357, 189361, 189365, 189369, + 189373, 189377, 189381, 189385, 189389, 189393, 189397, 189401, 189405, + 189409, 189413, 189417, 189421, 189425, 189429, 189433, 189437, 189441, + 189445, 189449, 189453, 189457, 189461, 189465, 189469, 189473, 189477, + 189481, 189485, 189489, 189493, 189497, 189501, 189505, 189509, 189513, + 189517, 189521, 189525, 189529, 189533, 189537, 189541, 189545, 189549, + 189553, 189557, 189561, 189565, 189569, 189573, 189577, 189581, 189585, + 189589, 189593, 189597, 189601, 189605, 189609, 189613, 189617, 189621, + 189625, 189629, 189633, 189637, 189641, 189645, 189649, 189653, 189657, + 189661, 189665, 189669, 189673, 189677, 189681, 189685, 189689, 189693, + 189697, 189701, 189705, 189709, 189713, 189717, 189721, 189725, 189729, + 189733, 189737, 189741, 189745, 189749, 189753, 189757, 189761, 189765, + 189769, 189773, 189777, 189781, 189785, 189789, 189793, 189797, 189801, + 189805, 189809, 189813, 189817, 189821, 189825, 189829, 189833, 189837, + 189841, 189845, 189849, 189853, 189857, 189861, 189865, 189869, 189873, + 189877, 189881, 189885, 189889, 189893, 189897, 189901, 189905, 189909, + 189913, 189917, 189921, 189925, 189929, 189933, 189937, 189941, 189945, + 189949, 189953, 189957, 189961, 189965, 189969, 189973, 189977, 189981, + 189985, 189989, 189993, 189997, 190001, 190005, 190009, 190013, 190017, + 190021, 190025, 190029, 190033, 190037, 190041, 190045, 190049, 190053, + 190057, 190061, 190065, 190069, 190073, 190077, 190081, 190085, 190089, + 190093, 190097, 190101, 190105, 190109, 190113, 190117, 190121, 190125, + 190129, 190133, 190137, 190141, 190145, 190149, 190153, 190157, 190161, + 190165, 190169, 190173, 190177, 190181, 190185, 190189, 190193, 190197, + 190201, 190205, 190209, 190213, 190217, 190221, 190225, 190229, 190233, + 190237, 190241, 190245, 190249, 190253, 190257, 190261, 190265, 190269, + 190273, 190277, 190281, 190285, 190289, 190293, 190297, 190301, 190305, + 190309, 190313, 190317, 190321, 190325, 190329, 190333, 190337, 190341, + 190345, 190349, 190353, 190357, 190361, 190365, 190369, 190373, 190377, + 190381, 190385, 190389, 190393, 190397, 190401, 190405, 190409, 190413, + 190417, 190421, 190425, 190429, 190433, 190437, 190441, 190445, 190449, + 190453, 190457, 190461, 190465, 190469, 190473, 190477, 190481, 190485, + 190489, 190493, 190497, 190501, 190505, 190509, 190513, 190517, 190521, + 190525, 190529, 190533, 190537, 190541, 190545, 190549, 190553, 190557, + 190561, 190565, 190569, 190573, 190577, 190581, 190585, 190589, 190593, + 190597, 190601, 190605, 190609, 190613, 190617, 190621, 190625, 190629, + 190633, 190637, 190641, 190645, 190649, 190653, 190657, 190661, 190665, + 190669, 190673, 190677, 190681, 190685, 190689, 190693, 190697, 190701, + 190705, 190709, 190713, 190717, 190721, 190725, 190729, 190733, 190737, + 190741, 190745, 190749, 190753, 190757, 190761, 190765, 190769, 190773, + 190777, 190781, 190785, 190789, 190793, 190797, 190801, 190805, 190809, + 190813, 190817, 190821, 190825, 190829, 190833, 190837, 190841, 190845, + 190849, 190853, 190857, 190861, 190865, 190869, 190873, 190877, 190881, + 190885, 190889, 190893, 190897, 190901, 190905, 190909, 190913, 190917, + 190921, 190925, 190929, 190933, 190937, 190941, 190945, 190949, 190953, + 190957, 190961, 190965, 190969, 190973, 190977, 190981, 190985, 190989, + 190993, 190997, 191001, 191005, 191009, 191013, 191017, 191021, 191025, + 191029, 191033, 191037, 191041, 191045, 191049, 191053, 191057, 191061, + 191065, 191069, 191073, 191077, 191081, 191085, 191089, 191093, 191097, + 191101, 191105, 191109, 191113, 191117, 191121, 191125, 191129, 191133, + 191137, 191141, 191145, 191149, 191153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191113, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 191117, 191121, 191126, 191131, 191135, 191140, 191145, 191149, 191153, - 191158, 191163, 191167, 191171, 191175, 191179, 191185, 191189, 191194, - 191198, 191202, 191206, 191210, 191214, 191218, 191222, 191226, 191230, - 191234, 191238, 191243, 191248, 191253, 191258, 191264, 191270, 191277, - 191284, 191291, 191297, 191304, 191311, 191318, 191324, 191331, 191338, - 191344, 191351, 191358, 191364, 191371, 191378, 191384, 191391, 191398, - 191404, 191411, 191418, 191425, 191432, 191439, 191445, 191451, 191457, - 191463, 191468, 191474, 191480, 191487, 191494, 191501, 191507, 191514, - 191521, 191528, 191534, 191541, 191548, 191554, 191561, 191568, 191574, - 191581, 191588, 191594, 191601, 191608, 191614, 191621, 191628, 191635, - 191642, 191649, 191656, 191661, 191668, 191672, 191676, 191679, 191682, - 191685, 191688, 191691, 191694, 191697, 191700, 191703, 191706, 191709, - 191712, 191715, 191718, 191721, 191724, 191727, 191730, 191733, 191736, - 191739, 191742, 191745, 191748, 191751, 191754, 191757, 191760, 191763, - 191766, 191769, 191772, 191775, 191778, 191781, 191784, 191787, 191790, - 191793, 191796, 191799, 191802, 191805, 191808, 191811, 191814, 191817, - 191820, 191823, 191826, 191829, 191832, 191835, 191838, 191841, 191844, - 191847, 191850, 191853, 191856, 191859, 191862, 191865, 191868, 191871, - 191874, 191877, 191880, 191883, 191886, 191889, 191892, 191895, 191898, - 191901, 191904, 191907, 191910, 191913, 191916, 191919, 191922, 191925, - 191928, 191931, 191934, 191937, 191940, 191943, 191946, 191949, 191952, - 191955, 191958, 191961, 191964, 191967, 191970, 191973, 191976, 191979, - 191982, 191985, 191988, 191991, 191994, 191997, 192000, 192003, 192006, - 192009, 192012, 192015, 192018, 192021, 192024, 192027, 192030, 192033, - 192036, 192039, 192042, 192045, 192048, 192051, 192054, 192057, 192060, - 192063, 192066, 192069, 192072, 192075, 192078, 192081, 192084, 192087, - 192090, 192093, 192096, 192099, 192102, 192105, 192108, 192111, 192114, - 192117, 192120, 192123, 192126, 192129, 192132, 192135, 192138, 192141, - 192144, 192147, 192150, 192153, 192156, 192159, 192162, 192165, 192168, - 192171, 192174, 192177, 192180, 192183, 192186, 192189, 192192, 192195, - 192198, 192201, 192204, 192207, 192210, 192213, 192216, 192219, 192222, - 192225, 192228, 192231, 192234, 192237, 192240, 192243, 192246, 192249, - 192252, 192255, 192258, 192261, 192264, 192267, 192270, 192273, 192276, - 192279, 192282, 192285, 192288, 192291, 192294, 192297, 192300, 192303, - 192306, 192309, 192312, 192315, 192318, 192321, 192324, 192327, 192330, - 192333, 192336, 192339, 192342, 192345, 192348, 192351, 192354, 192357, - 192360, 192363, 192366, 192369, 192372, 192375, 192378, 192381, 192384, - 192387, 192390, 192393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 192396, 192398, 192400, 192405, 192407, 192412, 192414, 192419, 192421, - 192426, 192428, 192430, 192432, 192434, 192436, 192438, 192440, 192442, - 192444, 192448, 192452, 192454, 192456, 192460, 192464, 192469, 192471, - 192473, 192475, 192479, 192482, 192484, 192488, 192490, 192494, 192496, - 192500, 192503, 192505, 192509, 192513, 192515, 192521, 192523, 192528, - 192530, 192535, 192537, 192542, 192544, 192549, 192551, 192555, 192557, - 192561, 192563, 192570, 192572, 192574, 192576, 192581, 192583, 192585, - 192587, 192589, 192591, 192593, 192598, 192602, 192604, 192609, 192613, - 192615, 192620, 192624, 192626, 192631, 192635, 192637, 192639, 192641, - 192643, 192647, 192649, 192654, 192656, 192662, 192664, 192670, 192672, - 192674, 192676, 192680, 192682, 192689, 192691, 192698, 192700, 192706, - 192712, 192714, 192721, 192728, 192730, 192736, 192741, 192743, 192749, - 192755, 192757, 192763, 192769, 192771, 192777, 192781, 192783, 192788, - 192790, 192792, 192797, 192799, 192801, 192807, 192809, 192814, 192818, - 192820, 192825, 192829, 192831, 192837, 192839, 192843, 192845, 192849, - 192851, 192858, 192865, 192867, 192874, 192881, 192883, 192888, 192890, - 192898, 192900, 192906, 192908, 192914, 192916, 192920, 192922, 192928, - 192930, 192934, 192936, 192942, 192944, 192946, 192948, 192953, 192958, - 192960, 192969, 192971, 192981, 192986, 192993, 193000, 193005, 193010, - 193022, 193026, 193030, 193034, 193038, 193040, 193042, 193044, 193046, - 193048, 193054, 193056, 193058, 193060, 193062, 193064, 193066, 193068, - 193070, 193072, 193074, 193076, 193078, 193080, 193082, 193084, 193086, - 193088, 193094, 193101, 193106, 193114, 193122, 193127, 193133, 193135, - 193137, 193139, 193141, 193143, 193145, 193147, 193149, 193151, 193153, - 193155, 193157, 193159, 193161, 193163, 193165, 193177, 193182, 193184, - 193186, 193192, 193204, 193210, 193216, 193222, 193228, 193232, 193243, - 193245, 193247, 193249, 193251, 193253, 193255, 193257, 193259, 193261, - 193263, 193265, 193267, 193269, 193271, 193273, 193275, 193277, 193279, - 193281, 193283, 193285, 193287, 193289, 193291, 193293, 193295, 193297, - 193299, 193301, 193303, 193305, 193307, 193309, 193311, 193313, 193315, - 193317, 193319, 193321, 193323, 193325, 193327, 193329, 193331, 193333, - 193335, 193337, 193339, 193341, 193343, 193345, 193347, 193349, 193351, - 193353, 193355, 193357, 193359, 193361, 193363, 193365, 193367, 193369, - 193371, 193373, 193375, 193377, 193379, 193381, 193383, 193385, 193387, - 193389, 193391, 193393, 193395, 193397, 193399, 193401, 193403, 193405, - 193407, 193409, 193411, 193413, 193415, 193417, 193419, 193421, 193423, - 193425, 193427, 193429, 193431, 193433, 193435, 193437, 193439, 193441, - 193443, 193445, 193447, 193449, 193451, 193453, 193455, 193457, 193459, - 193461, 193463, 193465, 193467, 193469, 193471, 193473, 193475, 193477, - 193479, 193481, 193483, 193485, 193487, 193489, 193491, 193493, 193495, - 193497, 193499, 193501, 193503, 193505, 193507, 193509, 193511, 193513, - 193515, 193517, 193519, 193521, 193523, 193525, 193527, 193529, 193531, - 193533, 193535, 193537, 193539, 193541, 193543, 193545, 193547, 193549, - 193551, 193553, 193555, 193557, 193559, 193561, 193563, 193565, 193567, - 193569, 193571, 193573, 193575, 193577, 193579, 193581, 193583, 193585, - 193587, 193589, 193591, 193593, 193595, 193597, 193599, 193601, 193603, - 193605, 193607, 193609, 193611, 193613, 193615, 193617, 193619, 193621, - 193623, 193625, 193627, 193629, 193631, 193633, 193635, 193637, 193639, - 193641, 193643, 193645, 193647, 193649, 193651, 193653, 193655, 193657, - 193659, 193661, 193663, 193665, 193667, 193669, 193671, 193673, 193675, - 193677, 193679, 193681, 193683, 193685, 193687, 193689, 193691, 193693, - 193695, 193697, 193699, 193701, 193703, 193705, 193707, 193709, 193711, - 193713, 193715, 193717, 193719, 193721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 191161, 191165, 191170, 191175, 191179, 191184, 191189, 191193, 191197, + 191202, 191207, 191211, 191215, 191219, 191223, 191229, 191233, 191238, + 191242, 191246, 191250, 191254, 191258, 191262, 191266, 191270, 191274, + 191278, 191282, 191287, 191292, 191297, 191302, 191308, 191314, 191321, + 191328, 191335, 191341, 191348, 191355, 191362, 191368, 191375, 191382, + 191388, 191395, 191402, 191408, 191415, 191422, 191428, 191435, 191442, + 191448, 191455, 191462, 191469, 191476, 191483, 191489, 191495, 191501, + 191507, 191512, 191518, 191524, 191531, 191538, 191545, 191551, 191558, + 191565, 191572, 191578, 191585, 191592, 191598, 191605, 191612, 191618, + 191625, 191632, 191638, 191645, 191652, 191658, 191665, 191672, 191679, + 191686, 191693, 191700, 191705, 191712, 191716, 191720, 191723, 191726, + 191729, 191732, 191735, 191738, 191741, 191744, 191747, 191750, 191753, + 191756, 191759, 191762, 191765, 191768, 191771, 191774, 191777, 191780, + 191783, 191786, 191789, 191792, 191795, 191798, 191801, 191804, 191807, + 191810, 191813, 191816, 191819, 191822, 191825, 191828, 191831, 191834, + 191837, 191840, 191843, 191846, 191849, 191852, 191855, 191858, 191861, + 191864, 191867, 191870, 191873, 191876, 191879, 191882, 191885, 191888, + 191891, 191894, 191897, 191900, 191903, 191906, 191909, 191912, 191915, + 191918, 191921, 191924, 191927, 191930, 191933, 191936, 191939, 191942, + 191945, 191948, 191951, 191954, 191957, 191960, 191963, 191966, 191969, + 191972, 191975, 191978, 191981, 191984, 191987, 191990, 191993, 191996, + 191999, 192002, 192005, 192008, 192011, 192014, 192017, 192020, 192023, + 192026, 192029, 192032, 192035, 192038, 192041, 192044, 192047, 192050, + 192053, 192056, 192059, 192062, 192065, 192068, 192071, 192074, 192077, + 192080, 192083, 192086, 192089, 192092, 192095, 192098, 192101, 192104, + 192107, 192110, 192113, 192116, 192119, 192122, 192125, 192128, 192131, + 192134, 192137, 192140, 192143, 192146, 192149, 192152, 192155, 192158, + 192161, 192164, 192167, 192170, 192173, 192176, 192179, 192182, 192185, + 192188, 192191, 192194, 192197, 192200, 192203, 192206, 192209, 192212, + 192215, 192218, 192221, 192224, 192227, 192230, 192233, 192236, 192239, + 192242, 192245, 192248, 192251, 192254, 192257, 192260, 192263, 192266, + 192269, 192272, 192275, 192278, 192281, 192284, 192287, 192290, 192293, + 192296, 192299, 192302, 192305, 192308, 192311, 192314, 192317, 192320, + 192323, 192326, 192329, 192332, 192335, 192338, 192341, 192344, 192347, + 192350, 192353, 192356, 192359, 192362, 192365, 192368, 192371, 192374, + 192377, 192380, 192383, 192386, 192389, 192392, 192395, 192398, 192401, + 192404, 192407, 192410, 192413, 192416, 192419, 192422, 192425, 192428, + 192431, 192434, 192437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192440, 192442, 192444, 192449, 192451, 192456, 192458, 192463, 192465, + 192470, 192472, 192474, 192476, 192478, 192480, 192482, 192484, 192486, + 192488, 192492, 192496, 192498, 192500, 192504, 192508, 192513, 192515, + 192517, 192519, 192523, 192526, 192528, 192532, 192534, 192538, 192540, + 192544, 192547, 192549, 192553, 192557, 192559, 192565, 192567, 192572, + 192574, 192579, 192581, 192586, 192588, 192593, 192595, 192599, 192601, + 192605, 192607, 192614, 192616, 192618, 192620, 192625, 192627, 192629, + 192631, 192633, 192635, 192637, 192642, 192646, 192648, 192653, 192657, + 192659, 192664, 192668, 192670, 192675, 192679, 192681, 192683, 192685, + 192687, 192691, 192693, 192698, 192700, 192706, 192708, 192714, 192716, + 192718, 192720, 192724, 192726, 192733, 192735, 192742, 192744, 192750, + 192756, 192758, 192765, 192772, 192774, 192780, 192785, 192787, 192793, + 192799, 192801, 192807, 192813, 192815, 192821, 192825, 192827, 192832, + 192834, 192836, 192841, 192843, 192845, 192851, 192853, 192858, 192862, + 192864, 192869, 192873, 192875, 192881, 192883, 192887, 192889, 192893, + 192895, 192902, 192909, 192911, 192918, 192925, 192927, 192932, 192934, + 192942, 192944, 192950, 192952, 192958, 192960, 192964, 192966, 192972, + 192974, 192978, 192980, 192986, 192988, 192990, 192992, 192997, 193002, + 193004, 193013, 193015, 193025, 193030, 193037, 193044, 193049, 193054, + 193066, 193070, 193074, 193078, 193082, 193084, 193086, 193088, 193090, + 193092, 193098, 193100, 193102, 193104, 193106, 193108, 193110, 193112, + 193114, 193116, 193118, 193120, 193122, 193124, 193126, 193128, 193130, + 193132, 193138, 193145, 193150, 193158, 193166, 193171, 193177, 193179, + 193181, 193183, 193185, 193187, 193189, 193191, 193193, 193195, 193197, + 193199, 193201, 193203, 193205, 193207, 193209, 193221, 193226, 193228, + 193230, 193236, 193248, 193254, 193260, 193266, 193272, 193276, 193287, + 193289, 193291, 193293, 193295, 193297, 193299, 193301, 193303, 193305, + 193307, 193309, 193311, 193313, 193315, 193317, 193319, 193321, 193323, + 193325, 193327, 193329, 193331, 193333, 193335, 193337, 193339, 193341, + 193343, 193345, 193347, 193349, 193351, 193353, 193355, 193357, 193359, + 193361, 193363, 193365, 193367, 193369, 193371, 193373, 193375, 193377, + 193379, 193381, 193383, 193385, 193387, 193389, 193391, 193393, 193395, + 193397, 193399, 193401, 193403, 193405, 193407, 193409, 193411, 193413, + 193415, 193417, 193419, 193421, 193423, 193425, 193427, 193429, 193431, + 193433, 193435, 193437, 193439, 193441, 193443, 193445, 193447, 193449, + 193451, 193453, 193455, 193457, 193459, 193461, 193463, 193465, 193467, + 193469, 193471, 193473, 193475, 193477, 193479, 193481, 193483, 193485, + 193487, 193489, 193491, 193493, 193495, 193497, 193499, 193501, 193503, + 193505, 193507, 193509, 193511, 193513, 193515, 193517, 193519, 193521, + 193523, 193525, 193527, 193529, 193531, 193533, 193535, 193537, 193539, + 193541, 193543, 193545, 193547, 193549, 193551, 193553, 193555, 193557, + 193559, 193561, 193563, 193565, 193567, 193569, 193571, 193573, 193575, + 193577, 193579, 193581, 193583, 193585, 193587, 193589, 193591, 193593, + 193595, 193597, 193599, 193601, 193603, 193605, 193607, 193609, 193611, + 193613, 193615, 193617, 193619, 193621, 193623, 193625, 193627, 193629, + 193631, 193633, 193635, 193637, 193639, 193641, 193643, 193645, 193647, + 193649, 193651, 193653, 193655, 193657, 193659, 193661, 193663, 193665, + 193667, 193669, 193671, 193673, 193675, 193677, 193679, 193681, 193683, + 193685, 193687, 193689, 193691, 193693, 193695, 193697, 193699, 193701, + 193703, 193705, 193707, 193709, 193711, 193713, 193715, 193717, 193719, + 193721, 193723, 193725, 193727, 193729, 193731, 193733, 193735, 193737, + 193739, 193741, 193743, 193745, 193747, 193749, 193751, 193753, 193755, + 193757, 193759, 193761, 193763, 193765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 193723, 193727, 193731, 193736, 193740, 193744, 193748, - 193752, 193756, 193760, 193764, 193768, 193772, 193782, 193792, 193803, - 193814, 193824, 193834, 193844, 193854, 193868, 193882, 193896, 193910, - 193919, 193928, 193941, 193954, 193967, 193980, 193990, 194000, 194011, - 194022, 194033, 194044, 194055, 194064, 194074, 194084, 194094, 194104, - 194115, 194126, 194137, 194148, 194159, 194170, 194181, 194192, 194203, - 194214, 194225, 194239, 194250, 194264, 194272, 194283, 194291, 194299, - 194307, 194315, 194323, 194331, 194341, 194351, 194361, 194371, 194381, - 194391, 194401, 194411, 194419, 194428, 194437, 194446, 194455, 194463, - 194471, 194481, 194491, 194502, 194513, 194525, 194536, 194546, 194557, - 194567, 194578, 194586, 194593, 194600, 194607, 194614, 194621, 194628, - 194635, 194642, 194650, 194658, 194666, 194674, 194682, 194690, 194698, - 194706, 194714, 194722, 194730, 194735, 194739, 194743, 194747, 194751, - 194755, 194759, 194763, 194767, 194771, 194775, 194779, 194782, 194785, - 194789, 194793, 194797, 194801, 194805, 194809, 194813, 194817, 194821, - 194825, 194829, 194833, 194837, 194841, 194845, 194849, 194853, 194857, - 194861, 194865, 194869, 194873, 194877, 194881, 194885, 194889, 194893, - 194897, 194901, 194905, 194909, 194913, 194917, 194921, 194925, 194929, - 194933, 194937, 194941, 194945, 194949, 194953, 194957, 194961, 194965, - 194969, 194973, 194977, 194981, 194985, 194989, 194993, 194997, 195001, - 195005, 195009, 195013, 195017, 195021, 195025, 195029, 195033, 195037, - 195041, 195045, 195049, 195053, 195057, 195061, 195065, 195069, 195073, - 195077, 195081, 195085, 195089, 195093, 195097, 195101, 195105, 195109, - 195113, 195117, 195121, 195125, 195128, 195132, 195136, 195140, 195144, - 195148, 195152, 195156, 195160, 195164, 195168, 195172, 195176, 195180, - 195184, 195188, 195192, 195196, 195200, 195204, 195208, 195212, 195216, - 195220, 195224, 195228, 195232, 195236, 195240, 195244, 195248, 195252, - 195256, 195260, 195264, 195268, 195272, 195276, 195280, 195284, 195288, - 195292, 195296, 195300, 195304, 195308, 195312, 195316, 195320, 195324, - 195328, 195332, 195336, 195340, 195344, 195348, 195352, 195356, 195360, - 195364, 195368, 195372, 195376, 195380, 195384, 195388, 195392, 195396, - 195400, 195404, 195408, 195412, 195416, 195420, 195424, 195428, 195432, - 195436, 195440, 195444, 195448, 195452, 195456, 195460, 195464, 195468, - 195472, 195476, 195480, 195484, 195488, 195492, 195496, 195500, 195504, - 195508, 195512, 195516, 195520, 195524, 195528, 195532, 195536, 195540, - 195544, 195548, 195552, 195556, 195560, 195564, 195568, 195572, 195576, - 195580, 195584, 195588, 195592, 195596, 195600, 195604, 195608, 195612, - 195616, 195620, 195624, 195628, 195632, 195636, 195640, 195644, 195648, - 195652, 195656, 195660, 195664, 195668, 195672, 195676, 195680, 195684, - 195688, 195692, 195696, 195700, 195704, 195708, 195712, 195716, 195720, - 195724, 195728, 195732, 195736, 195740, 195744, 195748, 195752, 195756, - 195760, 195764, 195768, 195772, 195776, 195780, 195784, 195788, 195792, - 195796, 195800, 195804, 195808, 195812, 195816, 195820, 195824, 195828, - 195832, 195836, 195840, 195844, 195848, 195852, 195856, 195860, 195864, - 195868, 195872, 195876, 195880, 195884, 195888, 195892, 195897, 195902, - 195907, 195911, 195917, 195924, 195931, 195938, 195945, 195952, 195959, - 195966, 195973, 195980, 195987, 195994, 196001, 196008, 196014, 196021, - 196028, 196034, 196041, 196048, 196055, 196062, 196069, 196076, 196083, - 196090, 196097, 196104, 196111, 196118, 196125, 196131, 196137, 196143, - 196150, 196159, 196168, 196177, 196186, 196191, 196196, 196203, 196210, - 196217, 196224, 196231, 196237, 196243, 196249, 196255, 196261, 196267, - 196273, 196278, 196284, 196294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 193767, 193771, 193775, 193780, 193784, 193788, 193792, + 193796, 193800, 193804, 193808, 193812, 193816, 193826, 193836, 193847, + 193858, 193868, 193878, 193888, 193898, 193912, 193926, 193940, 193954, + 193963, 193972, 193985, 193998, 194011, 194024, 194034, 194044, 194055, + 194066, 194077, 194088, 194099, 194108, 194118, 194128, 194138, 194148, + 194159, 194170, 194181, 194192, 194203, 194214, 194225, 194236, 194247, + 194258, 194269, 194283, 194294, 194308, 194316, 194327, 194335, 194343, + 194351, 194359, 194367, 194375, 194385, 194395, 194405, 194415, 194425, + 194435, 194445, 194455, 194463, 194472, 194481, 194490, 194499, 194507, + 194515, 194525, 194535, 194546, 194557, 194569, 194580, 194590, 194601, + 194611, 194622, 194630, 194637, 194644, 194651, 194658, 194665, 194672, + 194679, 194686, 194694, 194702, 194710, 194718, 194726, 194734, 194742, + 194750, 194758, 194766, 194774, 194779, 194783, 194787, 194791, 194795, + 194799, 194803, 194807, 194811, 194815, 194819, 194823, 194826, 194829, + 194833, 194837, 194841, 194845, 194849, 194853, 194857, 194861, 194865, + 194869, 194873, 194877, 194881, 194885, 194889, 194893, 194897, 194901, + 194905, 194909, 194913, 194917, 194921, 194925, 194929, 194933, 194937, + 194941, 194945, 194949, 194953, 194957, 194961, 194965, 194969, 194973, + 194977, 194981, 194985, 194989, 194993, 194997, 195001, 195005, 195009, + 195013, 195017, 195021, 195025, 195029, 195033, 195037, 195041, 195045, + 195049, 195053, 195057, 195061, 195065, 195069, 195073, 195077, 195081, + 195085, 195089, 195093, 195097, 195101, 195105, 195109, 195113, 195117, + 195121, 195125, 195129, 195133, 195137, 195141, 195145, 195149, 195153, + 195157, 195161, 195165, 195169, 195172, 195176, 195180, 195184, 195188, + 195192, 195196, 195200, 195204, 195208, 195212, 195216, 195220, 195224, + 195228, 195232, 195236, 195240, 195244, 195248, 195252, 195256, 195260, + 195264, 195268, 195272, 195276, 195280, 195284, 195288, 195292, 195296, + 195300, 195304, 195308, 195312, 195316, 195320, 195324, 195328, 195332, + 195336, 195340, 195344, 195348, 195352, 195356, 195360, 195364, 195368, + 195372, 195376, 195380, 195384, 195388, 195392, 195396, 195400, 195404, + 195408, 195412, 195416, 195420, 195424, 195428, 195432, 195436, 195440, + 195444, 195448, 195452, 195456, 195460, 195464, 195468, 195472, 195476, + 195480, 195484, 195488, 195492, 195496, 195500, 195504, 195508, 195512, + 195516, 195520, 195524, 195528, 195532, 195536, 195540, 195544, 195548, + 195552, 195556, 195560, 195564, 195568, 195572, 195576, 195580, 195584, + 195588, 195592, 195596, 195600, 195604, 195608, 195612, 195616, 195620, + 195624, 195628, 195632, 195636, 195640, 195644, 195648, 195652, 195656, + 195660, 195664, 195668, 195672, 195676, 195680, 195684, 195688, 195692, + 195696, 195700, 195704, 195708, 195712, 195716, 195720, 195724, 195728, + 195732, 195736, 195740, 195744, 195748, 195752, 195756, 195760, 195764, + 195768, 195772, 195776, 195780, 195784, 195788, 195792, 195796, 195800, + 195804, 195808, 195812, 195816, 195820, 195824, 195828, 195832, 195836, + 195840, 195844, 195848, 195852, 195856, 195860, 195864, 195868, 195872, + 195876, 195880, 195884, 195888, 195892, 195896, 195900, 195904, 195908, + 195912, 195916, 195920, 195924, 195928, 195932, 195936, 195941, 195946, + 195951, 195955, 195961, 195968, 195975, 195982, 195989, 195996, 196003, + 196010, 196017, 196024, 196031, 196038, 196045, 196052, 196058, 196065, + 196072, 196078, 196085, 196092, 196099, 196106, 196113, 196120, 196127, + 196134, 196141, 196148, 196155, 196162, 196169, 196175, 196181, 196187, + 196194, 196203, 196212, 196221, 196230, 196235, 196240, 196247, 196254, + 196261, 196268, 196275, 196281, 196287, 196293, 196299, 196305, 196311, + 196317, 196322, 196328, 196338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; @@ -25771,7 +25777,7 @@ static const unsigned int code_hash[] = { 64721, 0, 0, 0, 0, 0, 983789, 0, 0, 5311, 0, 965, 0, 11993, 78055, 11278, 128787, 0, 0, 0, 121076, 120705, 0, 6294, 3144, 0, 0, 65019, 0, 0, 0, 0, 118721, 63966, 2330, 535, 3148, 12375, 110774, 0, 10556, 2475, 12388, - 4889, 0, 67863, 120404, 0, 72750, 2342, 0, 0, 0, 4894, 0, 4890, 0, 0, 0, + 4889, 0, 67863, 120404, 0, 12287, 2342, 0, 0, 0, 4894, 0, 4890, 0, 0, 0, 4893, 128426, 6571, 118581, 4888, 4157, 78048, 78049, 78046, 11263, 0, 78045, 64895, 121437, 0, 0, 0, 0, 0, 119041, 2332, 78063, 78060, 78061, 64932, 78059, 65125, 121098, 0, 0, 129991, 73941, 78066, 12203, 78064, @@ -26147,7 +26153,7 @@ static const unsigned int code_hash[] = { 72720, 72020, 11386, 1009, 70405, 66871, 2333, 0, 0, 0, 0, 0, 70407, 128121, 0, 0, 0, 0, 983657, 66949, 0, 74968, 0, 0, 110601, 0, 0, 41261, 0, 0, 0, 0, 118989, 6736, 917883, 124132, 43010, 66952, 0, 69635, 73011, - 983716, 0, 0, 7293, 0, 0, 0, 0, 111332, 0, 128245, 69928, 127071, 0, + 983716, 72750, 0, 7293, 0, 0, 0, 0, 111332, 0, 128245, 69928, 127071, 0, 127072, 64445, 111336, 6635, 0, 0, 72707, 74936, 0, 0, 917876, 0, 93025, 66948, 0, 111329, 0, 129887, 128045, 65219, 11925, 0, 92434, 0, 0, 9845, 101317, 7546, 0, 0, 11230, 4985, 13288, 672, 8098, 0, 0, 0, 128126, @@ -27037,7 +27043,7 @@ static const unsigned int code_hash[] = { 0, 64260, 0, 12606, 0, 0, 0, 0, 562, 983614, 0, 129648, 66455, 127533, 3219, 0, 0, 0, 1037, 0, 64491, 0, 78579, 78572, 78580, 4568, 549, 0, 0, 0, 0, 0, 128095, 70851, 2205, 0, 0, 0, 0, 129716, 0, 10825, 8079, 118962, - 0, 0, 0, 128855, 0, 13071, 0, 0, 41049, 42840, 43614, 129341, 74881, + 12285, 0, 0, 128855, 0, 13071, 0, 0, 41049, 42840, 43614, 129341, 74881, 74596, 127191, 5212, 0, 66402, 119191, 0, 9747, 0, 0, 129778, 984008, 41047, 1668, 0, 0, 0, 1187, 0, 74416, 0, 0, 0, 0, 3240, 128518, 9213, 0, 0, 0, 127174, 69822, 0, 0, 0, 0, 1623, 0, 0, 0, 0, 0, 0, 11272, 0, 73914, @@ -28020,7 +28026,7 @@ static const unsigned int code_hash[] = { 0, 0, 0, 4843, 0, 74772, 4098, 0, 0, 0, 3436, 0, 127279, 12817, 0, 126607, 118678, 0, 0, 0, 74433, 0, 0, 71962, 0, 121296, 65916, 0, 0, 121458, 0, 129107, 93815, 0, 73743, 0, 0, 983133, 67676, 0, 0, 74627, - 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, 0, 128500, 0, 0, + 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, 12284, 128500, 0, 0, 9613, 43425, 4526, 121415, 0, 64520, 71336, 0, 0, 55278, 10228, 64957, 0, 0, 3807, 2081, 66640, 0, 0, 0, 0, 119269, 0, 128688, 0, 128142, 1451, 0, 0, 4134, 0, 74847, 0, 74793, 0, 78913, 74295, 9960, 1201, 0, 12846, @@ -28492,12 +28498,12 @@ static const unsigned int code_hash[] = { 78726, 0, 724, 0, 113675, 78749, 9975, 78746, 78747, 78744, 4175, 78741, 78743, 78751, 939, 0, 128799, 983120, 0, 0, 0, 78763, 78764, 78760, 78761, 78758, 78759, 78755, 8425, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 6370, 0, - 7827, 68441, 75008, 0, 917943, 0, 118863, 0, 0, 0, 0, 121243, 73988, 0, - 113668, 0, 11012, 0, 43764, 178, 12972, 74620, 113671, 0, 113735, 0, - 66764, 0, 0, 65690, 72339, 0, 0, 917950, 9252, 0, 4652, 74259, 0, 917947, - 0, 0, 0, 10806, 0, 0, 70016, 0, 6723, 0, 0, 6993, 0, 0, 12855, 0, 0, - 11390, 0, 0, 0, 92503, 0, 0, 983162, 125270, 92627, 8278, 0, 4034, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 12750, 9350, 66037, 0, 0, 73700, 12747, 0, 0, + 7827, 68441, 75008, 0, 917943, 0, 118863, 0, 0, 0, 0, 121243, 73988, + 12286, 113668, 0, 11012, 0, 43764, 178, 12972, 74620, 113671, 0, 113735, + 0, 66764, 0, 0, 65690, 72339, 0, 0, 917950, 9252, 0, 4652, 74259, 0, + 917947, 0, 0, 0, 10806, 0, 0, 70016, 0, 6723, 0, 0, 6993, 0, 0, 12855, 0, + 0, 11390, 0, 0, 0, 92503, 0, 0, 983162, 125270, 92627, 8278, 0, 4034, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 12750, 9350, 66037, 0, 0, 73700, 12747, 0, 0, 128064, 8922, 74640, 0, 0, 43150, 0, 983090, 983088, 66779, 66777, 10813, 2592, 43139, 0, 0, 118612, 0, 0, 71891, 0, 0, 0, 0, 0, 0, 71697, 0, 128825, 1596, 0, 0, 0, 0, 6838, 66572, 0, 126574, 120627, 8092, 12805, @@ -29642,7 +29648,7 @@ static const unsigned int code_hash[] = { 100884, 0, 0, 0, 123564, 0, 5134, 69980, 322, 4643, 5132, 0, 194942, 0, 5143, 0, 72309, 119628, 0, 0, 72112, 0, 129964, 0, 0, 0, 0, 0, 0, 73097, 0, 0, 0, 127923, 0, 0, 0, 0, 0, 3234, 0, 100886, 0, 100889, 118924, 0, 0, - 100875, 68231, 74489, 100872, 120746, 0, 100876, 0, 12714, 0, 64585, + 100875, 68231, 74489, 100872, 120746, 12783, 100876, 0, 12714, 0, 64585, 93775, 0, 0, 0, 129428, 0, 11027, 0, 10059, 0, 64524, 9767, 789, 1749, 0, 66766, 984010, 320, 0, 0, 0, 3049, 0, 6471, 0, 74479, 9925, 127356, 127355, 127358, 4960, 5549, 127359, 127346, 127345, 127348, 5418, 127350, diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c index 9e4a3d66ef41bd..560f43e5b3a643 100644 --- a/Modules/xxsubtype.c +++ b/Modules/xxsubtype.c @@ -1,5 +1,8 @@ #include "Python.h" -#include "structmember.h" // PyMemberDef + +#include // offsetof() +#include // clock() + PyDoc_STRVAR(xxsubtype__doc__, "xxsubtype is an example module showing how to subtype builtin types from C.\n" @@ -181,7 +184,7 @@ spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds) } static PyMemberDef spamdict_members[] = { - {"state", T_INT, offsetof(spamdictobject, state), READONLY, + {"state", Py_T_INT, offsetof(spamdictobject, state), Py_READONLY, PyDoc_STR("an int variable for demonstration purposes")}, {0} }; diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index c0f6b96f51baba..9b76afa0e56f76 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -3,10 +3,15 @@ /* Windows users: read Python's PCbuild\readme.txt */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" -#include "structmember.h" // PyMemberDef + #include "zlib.h" #include "stdbool.h" +#include // offsetof() #if defined(ZLIB_VERNUM) && ZLIB_VERNUM < 0x1221 #error "At least zlib version 1.2.2.1 is required" @@ -1344,7 +1349,7 @@ typedef struct { decompress_buf() */ Py_ssize_t avail_in_real; bool is_initialised; - char eof; /* T_BOOL expects a char */ + char eof; /* Py_T_BOOL expects a char */ char needs_input; } ZlibDecompressor; @@ -1801,9 +1806,9 @@ static PyMethodDef ZlibDecompressor_methods[] = { #define COMP_OFF(x) offsetof(compobject, x) static PyMemberDef Decomp_members[] = { - {"unused_data", T_OBJECT, COMP_OFF(unused_data), READONLY}, - {"unconsumed_tail", T_OBJECT, COMP_OFF(unconsumed_tail), READONLY}, - {"eof", T_BOOL, COMP_OFF(eof), READONLY}, + {"unused_data", _Py_T_OBJECT, COMP_OFF(unused_data), Py_READONLY}, + {"unconsumed_tail", _Py_T_OBJECT, COMP_OFF(unconsumed_tail), Py_READONLY}, + {"eof", Py_T_BOOL, COMP_OFF(eof), Py_READONLY}, {NULL}, }; @@ -1817,11 +1822,11 @@ PyDoc_STRVAR(ZlibDecompressor_needs_input_doc, "True if more input is needed before more decompressed data can be produced."); static PyMemberDef ZlibDecompressor_members[] = { - {"eof", T_BOOL, offsetof(ZlibDecompressor, eof), - READONLY, ZlibDecompressor_eof__doc__}, - {"unused_data", T_OBJECT_EX, offsetof(ZlibDecompressor, unused_data), - READONLY, ZlibDecompressor_unused_data__doc__}, - {"needs_input", T_BOOL, offsetof(ZlibDecompressor, needs_input), READONLY, + {"eof", Py_T_BOOL, offsetof(ZlibDecompressor, eof), + Py_READONLY, ZlibDecompressor_eof__doc__}, + {"unused_data", Py_T_OBJECT_EX, offsetof(ZlibDecompressor, unused_data), + Py_READONLY, ZlibDecompressor_unused_data__doc__}, + {"needs_input", Py_T_BOOL, offsetof(ZlibDecompressor, needs_input), Py_READONLY, ZlibDecompressor_needs_input_doc}, {NULL}, }; @@ -2030,17 +2035,11 @@ zlib_exec(PyObject *mod) } state->ZlibError = PyErr_NewException("zlib.error", NULL, NULL); - if (state->ZlibError == NULL) { + if (PyModule_AddObjectRef(mod, "error", state->ZlibError) < 0) { return -1; } - - if (PyModule_AddObject(mod, "error", Py_NewRef(state->ZlibError)) < 0) { - Py_DECREF(state->ZlibError); - return -1; - } - if (PyModule_AddObject(mod, "_ZlibDecompressor", - Py_NewRef(state->ZlibDecompressorType)) < 0) { - Py_DECREF(state->ZlibDecompressorType); + if (PyModule_AddObjectRef(mod, "_ZlibDecompressor", + (PyObject *)state->ZlibDecompressorType) < 0) { return -1; } @@ -2082,26 +2081,14 @@ zlib_exec(PyObject *mod) #ifdef Z_TREES // 1.2.3.4, only for inflate ZLIB_ADD_INT_MACRO(Z_TREES); #endif - PyObject *ver = PyUnicode_FromString(ZLIB_VERSION); - if (ver == NULL) { - return -1; - } - - if (PyModule_AddObject(mod, "ZLIB_VERSION", ver) < 0) { - Py_DECREF(ver); + if (PyModule_Add(mod, "ZLIB_VERSION", + PyUnicode_FromString(ZLIB_VERSION)) < 0) { return -1; } - - ver = PyUnicode_FromString(zlibVersion()); - if (ver == NULL) { + if (PyModule_Add(mod, "ZLIB_RUNTIME_VERSION", + PyUnicode_FromString(zlibVersion())) < 0) { return -1; } - - if (PyModule_AddObject(mod, "ZLIB_RUNTIME_VERSION", ver) < 0) { - Py_DECREF(ver); - return -1; - } - if (PyModule_AddStringConstant(mod, "__version__", "1.0") < 0) { return -1; } diff --git a/Objects/abstract.c b/Objects/abstract.c index b4edcec6007710..806ca6584bda95 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_pybuffer.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_object.h" // _Py_CheckSlotResult() @@ -9,9 +10,8 @@ #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_unionobject.h" // _PyUnion_Check() -#include -#include // offsetof() +#include // offsetof() /* Shorthands to return certain errors */ @@ -807,6 +807,27 @@ PyBuffer_Release(Py_buffer *view) Py_DECREF(obj); } +static int +_buffer_release_call(void *arg) +{ + PyBuffer_Release((Py_buffer *)arg); + return 0; +} + +int +_PyBuffer_ReleaseInInterpreter(PyInterpreterState *interp, + Py_buffer *view) +{ + return _Py_CallInInterpreter(interp, _buffer_release_call, view); +} + +int +_PyBuffer_ReleaseInInterpreterAndRawFree(PyInterpreterState *interp, + Py_buffer *view) +{ + return _Py_CallInInterpreterAndRawFree(interp, _buffer_release_call, view); +} + PyObject * PyObject_Format(PyObject *obj, PyObject *format_spec) { @@ -2394,11 +2415,13 @@ int PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject **result) { if (key == NULL) { + *result = NULL; null_error(); return -1; } PyObject *okey = PyUnicode_FromString(key); if (okey == NULL) { + *result = NULL; return -1; } int rc = PyMapping_GetOptionalItem(obj, okey, result); @@ -2425,6 +2448,24 @@ PyMapping_SetItemString(PyObject *o, const char *key, PyObject *value) return r; } +int +PyMapping_HasKeyStringWithError(PyObject *obj, const char *key) +{ + PyObject *res; + int rc = PyMapping_GetOptionalItemString(obj, key, &res); + Py_XDECREF(res); + return rc; +} + +int +PyMapping_HasKeyWithError(PyObject *obj, PyObject *key) +{ + PyObject *res; + int rc = PyMapping_GetOptionalItem(obj, key, &res); + Py_XDECREF(res); + return rc; +} + int PyMapping_HasKeyString(PyObject *o, const char *key) { @@ -2812,7 +2853,7 @@ object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls) return -1; } - /* Probably never reached anymore. */ + /* Can be reached when infinite recursion happens. */ return recursive_issubclass(derived, cls); } diff --git a/Objects/boolobject.c b/Objects/boolobject.c index bbb187cb7121e7..e2e359437f0edf 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -13,8 +13,7 @@ static PyObject * bool_repr(PyObject *self) { - PyObject *res = self == Py_True ? &_Py_ID(True) : &_Py_ID(False); - return Py_NewRef(res); + return self == Py_True ? &_Py_ID(True) : &_Py_ID(False); } /* Function to return a bool from a C long */ diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 18a24a369a64c1..67073190cc889d 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -4,6 +4,7 @@ #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_bytes_methods.h" #include "pycore_bytesobject.h" +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_strhex.h" // _Py_strhex_with_sep() #include "pycore_long.h" // _PyLong_FromUnsignedChar() diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 6b9231a9fa7693..26227dd251122d 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2,11 +2,12 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat() #include "pycore_bytes_methods.h" // _Py_bytes_startswith() +#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat() #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_format.h" // F_LJUST -#include "pycore_global_objects.h" // _Py_GET_GLOBAL_OBJECT() +#include "pycore_global_objects.h"// _Py_GET_GLOBAL_OBJECT() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _PyLong_DigitValue #include "pycore_object.h" // _PyObject_GC_TRACK @@ -41,17 +42,12 @@ Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer, #define EMPTY (&_Py_SINGLETON(bytes_empty)) -// Return a borrowed reference to the empty bytes string singleton. +// Return a reference to the immortal empty bytes string singleton. static inline PyObject* bytes_get_empty(void) { - return &EMPTY->ob_base.ob_base; -} - - -// Return a strong reference to the empty bytes string singleton. -static inline PyObject* bytes_new_empty(void) -{ - return Py_NewRef(EMPTY); + PyObject *empty = &EMPTY->ob_base.ob_base; + assert(_Py_IsImmortal(empty)); + return empty; } @@ -84,7 +80,7 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) assert(size >= 0); if (size == 0) { - return bytes_new_empty(); + return bytes_get_empty(); } if ((size_t)size > (size_t)PY_SSIZE_T_MAX - PyBytesObject_SIZE) { @@ -123,10 +119,11 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) } if (size == 1 && str != NULL) { op = CHARACTER(*str & 255); - return Py_NewRef(op); + assert(_Py_IsImmortal(op)); + return (PyObject *)op; } if (size == 0) { - return bytes_new_empty(); + return bytes_get_empty(); } op = (PyBytesObject *)_PyBytes_FromSize(size, 0); @@ -154,11 +151,12 @@ PyBytes_FromString(const char *str) } if (size == 0) { - return bytes_new_empty(); + return bytes_get_empty(); } else if (size == 1) { op = CHARACTER(*str & 255); - return Py_NewRef(op); + assert(_Py_IsImmortal(op)); + return (PyObject *)op; } /* Inline PyObject_NewVar */ @@ -724,11 +722,11 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, if (--fmtcnt >= 0) c = *fmt++; } - else if (c >= 0 && isdigit(c)) { + else if (c >= 0 && Py_ISDIGIT(c)) { width = c - '0'; while (--fmtcnt >= 0) { c = Py_CHARMASK(*fmt++); - if (!isdigit(c)) + if (!Py_ISDIGIT(c)) break; if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) { PyErr_SetString( @@ -755,7 +753,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, "* wants int"); goto error; } - prec = _PyLong_AsInt(v); + prec = PyLong_AsInt(v); if (prec == -1 && PyErr_Occurred()) goto error; if (prec < 0) @@ -763,11 +761,11 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, if (--fmtcnt >= 0) c = *fmt++; } - else if (c >= 0 && isdigit(c)) { + else if (c >= 0 && Py_ISDIGIT(c)) { prec = c - '0'; while (--fmtcnt >= 0) { c = Py_CHARMASK(*fmt++); - if (!isdigit(c)) + if (!Py_ISDIGIT(c)) break; if (prec > (INT_MAX - ((int)c - '0')) / 10) { PyErr_SetString( @@ -3065,7 +3063,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) goto error; } if (newsize == 0) { - *pv = bytes_new_empty(); + *pv = bytes_get_empty(); Py_DECREF(v); return 0; } diff --git a/Objects/call.c b/Objects/call.c index 396552d85cfca0..b1610dababd466 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -2,6 +2,7 @@ #include "pycore_call.h" // _PyObject_CallNoArgsTstate() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_dict.h" // _PyDict_FromItems() +#include "pycore_function.h" // _PyFunction_Vectorcall() definition #include "pycore_modsupport.h" // _Py_VaBuildStack() #include "pycore_object.h" // _PyCFunctionWithKeywords_TrampolineCall() #include "pycore_pyerrors.h" // _PyErr_Occurred() diff --git a/Objects/capsule.c b/Objects/capsule.c index baaddb3f1f0849..555979dab2b789 100644 --- a/Objects/capsule.c +++ b/Objects/capsule.c @@ -1,6 +1,10 @@ /* Wrap void * pointers to be passed between C modules */ #include "Python.h" +#include "pycore_capsule.h" // export _PyCapsule_SetTraverse() +#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() +#include "pycore_object.h" // _PyObject_GC_TRACK() + /* Internal structure of PyCapsule */ typedef struct { @@ -9,18 +13,28 @@ typedef struct { const char *name; void *context; PyCapsule_Destructor destructor; + traverseproc traverse_func; + inquiry clear_func; } PyCapsule; static int -_is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule) +_is_legal_capsule(PyObject *op, const char *invalid_capsule) { - if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) { - PyErr_SetString(PyExc_ValueError, invalid_capsule); - return 0; + if (!op || !PyCapsule_CheckExact(op)) { + goto error; + } + PyCapsule *capsule = (PyCapsule *)op; + + if (capsule->pointer == NULL) { + goto error; } return 1; + +error: + PyErr_SetString(PyExc_ValueError, invalid_capsule); + return 0; } #define is_legal_capsule(capsule, name) \ @@ -50,7 +64,7 @@ PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor) return NULL; } - capsule = PyObject_New(PyCapsule, &PyCapsule_Type); + capsule = PyObject_GC_New(PyCapsule, &PyCapsule_Type); if (capsule == NULL) { return NULL; } @@ -59,15 +73,18 @@ PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor) capsule->name = name; capsule->context = NULL; capsule->destructor = destructor; + capsule->traverse_func = NULL; + capsule->clear_func = NULL; + // Only track the object by the GC when _PyCapsule_SetTraverse() is called return (PyObject *)capsule; } int -PyCapsule_IsValid(PyObject *o, const char *name) +PyCapsule_IsValid(PyObject *op, const char *name) { - PyCapsule *capsule = (PyCapsule *)o; + PyCapsule *capsule = (PyCapsule *)op; return (capsule != NULL && PyCapsule_CheckExact(capsule) && @@ -77,13 +94,12 @@ PyCapsule_IsValid(PyObject *o, const char *name) void * -PyCapsule_GetPointer(PyObject *o, const char *name) +PyCapsule_GetPointer(PyObject *op, const char *name) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) { + if (!is_legal_capsule(op, "PyCapsule_GetPointer")) { return NULL; } + PyCapsule *capsule = (PyCapsule *)op; if (!name_matches(name, capsule->name)) { PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name"); @@ -95,52 +111,48 @@ PyCapsule_GetPointer(PyObject *o, const char *name) const char * -PyCapsule_GetName(PyObject *o) +PyCapsule_GetName(PyObject *op) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!is_legal_capsule(capsule, "PyCapsule_GetName")) { + if (!is_legal_capsule(op, "PyCapsule_GetName")) { return NULL; } + PyCapsule *capsule = (PyCapsule *)op; return capsule->name; } PyCapsule_Destructor -PyCapsule_GetDestructor(PyObject *o) +PyCapsule_GetDestructor(PyObject *op) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) { + if (!is_legal_capsule(op, "PyCapsule_GetDestructor")) { return NULL; } + PyCapsule *capsule = (PyCapsule *)op; return capsule->destructor; } void * -PyCapsule_GetContext(PyObject *o) +PyCapsule_GetContext(PyObject *op) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) { + if (!is_legal_capsule(op, "PyCapsule_GetContext")) { return NULL; } + PyCapsule *capsule = (PyCapsule *)op; return capsule->context; } int -PyCapsule_SetPointer(PyObject *o, void *pointer) +PyCapsule_SetPointer(PyObject *op, void *pointer) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!pointer) { - PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer"); + if (!is_legal_capsule(op, "PyCapsule_SetPointer")) { return -1; } + PyCapsule *capsule = (PyCapsule *)op; - if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) { + if (!pointer) { + PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer"); return -1; } @@ -150,13 +162,12 @@ PyCapsule_SetPointer(PyObject *o, void *pointer) int -PyCapsule_SetName(PyObject *o, const char *name) +PyCapsule_SetName(PyObject *op, const char *name) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!is_legal_capsule(capsule, "PyCapsule_SetName")) { + if (!is_legal_capsule(op, "PyCapsule_SetName")) { return -1; } + PyCapsule *capsule = (PyCapsule *)op; capsule->name = name; return 0; @@ -164,13 +175,12 @@ PyCapsule_SetName(PyObject *o, const char *name) int -PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor) +PyCapsule_SetDestructor(PyObject *op, PyCapsule_Destructor destructor) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) { + if (!is_legal_capsule(op, "PyCapsule_SetDestructor")) { return -1; } + PyCapsule *capsule = (PyCapsule *)op; capsule->destructor = destructor; return 0; @@ -178,19 +188,42 @@ PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor) int -PyCapsule_SetContext(PyObject *o, void *context) +PyCapsule_SetContext(PyObject *op, void *context) { - PyCapsule *capsule = (PyCapsule *)o; - - if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) { + if (!is_legal_capsule(op, "PyCapsule_SetContext")) { return -1; } + PyCapsule *capsule = (PyCapsule *)op; capsule->context = context; return 0; } +int +_PyCapsule_SetTraverse(PyObject *op, traverseproc traverse_func, inquiry clear_func) +{ + if (!is_legal_capsule(op, "_PyCapsule_SetTraverse")) { + return -1; + } + PyCapsule *capsule = (PyCapsule *)op; + + if (traverse_func == NULL || clear_func == NULL) { + PyErr_SetString(PyExc_ValueError, + "_PyCapsule_SetTraverse() called with NULL callback"); + return -1; + } + + if (!_PyObject_GC_IS_TRACKED(op)) { + _PyObject_GC_TRACK(op); + } + + capsule->traverse_func = traverse_func; + capsule->clear_func = clear_func; + return 0; +} + + void * PyCapsule_Import(const char *name, int no_block) { @@ -249,13 +282,14 @@ PyCapsule_Import(const char *name, int no_block) static void -capsule_dealloc(PyObject *o) +capsule_dealloc(PyObject *op) { - PyCapsule *capsule = (PyCapsule *)o; + PyCapsule *capsule = (PyCapsule *)op; + PyObject_GC_UnTrack(op); if (capsule->destructor) { - capsule->destructor(o); + capsule->destructor(op); } - PyObject_Free(o); + PyObject_GC_Del(op); } @@ -279,6 +313,27 @@ capsule_repr(PyObject *o) } +static int +capsule_traverse(PyCapsule *capsule, visitproc visit, void *arg) +{ + // Capsule object is only tracked by the GC + // if _PyCapsule_SetTraverse() is called + assert(capsule->traverse_func != NULL); + + return capsule->traverse_func((PyObject*)capsule, visit, arg); +} + + +static int +capsule_clear(PyCapsule *capsule) +{ + // Capsule object is only tracked by the GC + // if _PyCapsule_SetTraverse() is called + assert(capsule->clear_func != NULL); + + return capsule->clear_func((PyObject*)capsule); +} + PyDoc_STRVAR(PyCapsule_Type__doc__, "Capsule objects let you wrap a C \"void *\" pointer in a Python\n\ @@ -293,27 +348,14 @@ Python import mechanism to link to one another.\n\ PyTypeObject PyCapsule_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "PyCapsule", /*tp_name*/ - sizeof(PyCapsule), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - capsule_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - capsule_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - 0, /*tp_flags*/ - PyCapsule_Type__doc__ /*tp_doc*/ + .tp_name = "PyCapsule", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_basicsize = sizeof(PyCapsule), + .tp_dealloc = capsule_dealloc, + .tp_repr = capsule_repr, + .tp_doc = PyCapsule_Type__doc__, + .tp_traverse = (traverseproc)capsule_traverse, + .tp_clear = (inquiry)capsule_clear, }; diff --git a/Objects/classobject.c b/Objects/classobject.c index 548b8672f86321..618d88894debbe 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -2,10 +2,11 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_VectorcallTstate() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() -#include "structmember.h" // PyMemberDef + #include "clinic/classobject.c.h" @@ -48,6 +49,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, PyObject *self = PyMethod_GET_SELF(method); PyObject *func = PyMethod_GET_FUNCTION(method); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + assert(nargs == 0 || args[nargs-1]); PyObject *result; if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { @@ -56,6 +58,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, nargs += 1; PyObject *tmp = newargs[0]; newargs[0] = self; + assert(newargs[nargs-1]); result = _PyObject_VectorcallTstate(tstate, func, newargs, nargs, kwnames); newargs[0] = tmp; @@ -150,9 +153,9 @@ static PyMethodDef method_methods[] = { #define MO_OFF(x) offsetof(PyMethodObject, x) static PyMemberDef method_memberlist[] = { - {"__func__", T_OBJECT, MO_OFF(im_func), READONLY, + {"__func__", _Py_T_OBJECT, MO_OFF(im_func), Py_READONLY, "the function (or other callable) implementing a method"}, - {"__self__", T_OBJECT, MO_OFF(im_self), READONLY, + {"__self__", _Py_T_OBJECT, MO_OFF(im_self), Py_READONLY, "the instance to which a method is bound"}, {NULL} /* Sentinel */ }; @@ -372,7 +375,7 @@ PyInstanceMethod_Function(PyObject *im) #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x) static PyMemberDef instancemethod_memberlist[] = { - {"__func__", T_OBJECT, IMO_OFF(func), READONLY, + {"__func__", _Py_T_OBJECT, IMO_OFF(func), Py_READONLY, "the function (or other callable) implementing a method"}, {NULL} /* Sentinel */ }; diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index 33caca28224565..7039db09721998 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() static int bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, @@ -1203,7 +1203,7 @@ bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, goto skip_optional_pos; } } - bytes_per_sep = _PyLong_AsInt(args[1]); + bytes_per_sep = PyLong_AsInt(args[1]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; } @@ -1256,7 +1256,7 @@ bytearray_reduce_ex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t n if (nargs < 1) { goto skip_optional; } - proto = _PyLong_AsInt(args[0]); + proto = PyLong_AsInt(args[0]); if (proto == -1 && PyErr_Occurred()) { goto exit; } @@ -1284,4 +1284,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=0817195f176cd8e3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=94b9b5f492b5fed6 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index 1ec0c95485a209..e2f9ba6c1e55bd 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(bytes___bytes____doc__, "__bytes__($self, /)\n" @@ -958,7 +958,7 @@ bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_pos; } } - bytes_per_sep = _PyLong_AsInt(args[1]); + bytes_per_sep = PyLong_AsInt(args[1]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; } @@ -1060,4 +1060,4 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=bc4801bf1fa628f4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8a9f5c28cbfe7592 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/classobject.c.h b/Objects/clinic/classobject.c.h index a7bac63052bc40..48cfd6c7b78ca3 100644 --- a/Objects/clinic/classobject.c.h +++ b/Objects/clinic/classobject.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(method___reduce____doc__, "__reduce__($self, /)\n" "--\n" @@ -86,4 +80,4 @@ instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=2a5e7fa5947a86cb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a0d17bad3b0734d9 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index 1f2ab56775a1ee..b20b066f494901 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(code_new__doc__, "code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" " flags, codestring, constants, names, varnames, filename, name,\n" @@ -57,27 +56,27 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!_PyArg_CheckPositional("code", PyTuple_GET_SIZE(args), 16, 18)) { goto exit; } - argcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + argcount = PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); if (argcount == -1 && PyErr_Occurred()) { goto exit; } - posonlyargcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 1)); + posonlyargcount = PyLong_AsInt(PyTuple_GET_ITEM(args, 1)); if (posonlyargcount == -1 && PyErr_Occurred()) { goto exit; } - kwonlyargcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 2)); + kwonlyargcount = PyLong_AsInt(PyTuple_GET_ITEM(args, 2)); if (kwonlyargcount == -1 && PyErr_Occurred()) { goto exit; } - nlocals = _PyLong_AsInt(PyTuple_GET_ITEM(args, 3)); + nlocals = PyLong_AsInt(PyTuple_GET_ITEM(args, 3)); if (nlocals == -1 && PyErr_Occurred()) { goto exit; } - stacksize = _PyLong_AsInt(PyTuple_GET_ITEM(args, 4)); + stacksize = PyLong_AsInt(PyTuple_GET_ITEM(args, 4)); if (stacksize == -1 && PyErr_Occurred()) { goto exit; } - flags = _PyLong_AsInt(PyTuple_GET_ITEM(args, 5)); + flags = PyLong_AsInt(PyTuple_GET_ITEM(args, 5)); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -116,7 +115,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } qualname = PyTuple_GET_ITEM(args, 12); - firstlineno = _PyLong_AsInt(PyTuple_GET_ITEM(args, 13)); + firstlineno = PyLong_AsInt(PyTuple_GET_ITEM(args, 13)); if (firstlineno == -1 && PyErr_Occurred()) { goto exit; } @@ -154,12 +153,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } PyDoc_STRVAR(code_replace__doc__, -"replace($self, /, *, co_argcount=-1, co_posonlyargcount=-1,\n" -" co_kwonlyargcount=-1, co_nlocals=-1, co_stacksize=-1,\n" -" co_flags=-1, co_firstlineno=-1, co_code=None, co_consts=None,\n" -" co_names=None, co_varnames=None, co_freevars=None,\n" -" co_cellvars=None, co_filename=None, co_name=None,\n" -" co_qualname=None, co_linetable=None, co_exceptiontable=None)\n" +"replace($self, /, **changes)\n" "--\n" "\n" "Return a copy of the code object with new values for the specified fields."); @@ -171,13 +165,12 @@ static PyObject * code_replace_impl(PyCodeObject *self, int co_argcount, int co_posonlyargcount, int co_kwonlyargcount, int co_nlocals, int co_stacksize, int co_flags, - int co_firstlineno, PyBytesObject *co_code, - PyObject *co_consts, PyObject *co_names, - PyObject *co_varnames, PyObject *co_freevars, - PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyObject *co_qualname, - PyBytesObject *co_linetable, - PyBytesObject *co_exceptiontable); + int co_firstlineno, PyObject *co_code, PyObject *co_consts, + PyObject *co_names, PyObject *co_varnames, + PyObject *co_freevars, PyObject *co_cellvars, + PyObject *co_filename, PyObject *co_name, + PyObject *co_qualname, PyObject *co_linetable, + PyObject *co_exceptiontable); static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -217,7 +210,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje int co_stacksize = self->co_stacksize; int co_flags = self->co_flags; int co_firstlineno = self->co_firstlineno; - PyBytesObject *co_code = NULL; + PyObject *co_code = NULL; PyObject *co_consts = self->co_consts; PyObject *co_names = self->co_names; PyObject *co_varnames = NULL; @@ -226,8 +219,8 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *co_filename = self->co_filename; PyObject *co_name = self->co_name; PyObject *co_qualname = self->co_qualname; - PyBytesObject *co_linetable = (PyBytesObject *)self->co_linetable; - PyBytesObject *co_exceptiontable = (PyBytesObject *)self->co_exceptiontable; + PyObject *co_linetable = self->co_linetable; + PyObject *co_exceptiontable = self->co_exceptiontable; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); if (!args) { @@ -237,7 +230,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje goto skip_optional_kwonly; } if (args[0]) { - co_argcount = _PyLong_AsInt(args[0]); + co_argcount = PyLong_AsInt(args[0]); if (co_argcount == -1 && PyErr_Occurred()) { goto exit; } @@ -246,7 +239,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[1]) { - co_posonlyargcount = _PyLong_AsInt(args[1]); + co_posonlyargcount = PyLong_AsInt(args[1]); if (co_posonlyargcount == -1 && PyErr_Occurred()) { goto exit; } @@ -255,7 +248,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[2]) { - co_kwonlyargcount = _PyLong_AsInt(args[2]); + co_kwonlyargcount = PyLong_AsInt(args[2]); if (co_kwonlyargcount == -1 && PyErr_Occurred()) { goto exit; } @@ -264,7 +257,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[3]) { - co_nlocals = _PyLong_AsInt(args[3]); + co_nlocals = PyLong_AsInt(args[3]); if (co_nlocals == -1 && PyErr_Occurred()) { goto exit; } @@ -273,7 +266,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[4]) { - co_stacksize = _PyLong_AsInt(args[4]); + co_stacksize = PyLong_AsInt(args[4]); if (co_stacksize == -1 && PyErr_Occurred()) { goto exit; } @@ -282,7 +275,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[5]) { - co_flags = _PyLong_AsInt(args[5]); + co_flags = PyLong_AsInt(args[5]); if (co_flags == -1 && PyErr_Occurred()) { goto exit; } @@ -291,7 +284,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[6]) { - co_firstlineno = _PyLong_AsInt(args[6]); + co_firstlineno = PyLong_AsInt(args[6]); if (co_firstlineno == -1 && PyErr_Occurred()) { goto exit; } @@ -304,7 +297,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje _PyArg_BadArgument("replace", "argument 'co_code'", "bytes", args[7]); goto exit; } - co_code = (PyBytesObject *)args[7]; + co_code = args[7]; if (!--noptargs) { goto skip_optional_kwonly; } @@ -394,7 +387,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje _PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[16]); goto exit; } - co_linetable = (PyBytesObject *)args[16]; + co_linetable = args[16]; if (!--noptargs) { goto skip_optional_kwonly; } @@ -403,7 +396,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje _PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[17]); goto exit; } - co_exceptiontable = (PyBytesObject *)args[17]; + co_exceptiontable = args[17]; skip_optional_kwonly: return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_linetable, co_exceptiontable); @@ -461,7 +454,7 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n if (!args) { goto exit; } - oparg = _PyLong_AsInt(args[0]); + oparg = PyLong_AsInt(args[0]); if (oparg == -1 && PyErr_Occurred()) { goto exit; } @@ -470,4 +463,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=4ca4c0c403dbfa71 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b9ccfbfabe1a5f46 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/complexobject.c.h b/Objects/clinic/complexobject.c.h index bb2b3815415f85..788f30d54450f5 100644 --- a/Objects/clinic/complexobject.c.h +++ b/Objects/clinic/complexobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(complex_conjugate__doc__, "conjugate($self, /)\n" "--\n" @@ -157,4 +156,4 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=d438b7ed87f8459e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=002c74f8a33b6697 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/descrobject.c.h b/Objects/clinic/descrobject.c.h index 75706437df83f9..4f18fd77a2c7a0 100644 --- a/Objects/clinic/descrobject.c.h +++ b/Objects/clinic/descrobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - static PyObject * mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping); @@ -167,4 +166,4 @@ property_init(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=8dc1ddfcf764ac8e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a97dc44d12f9f9b6 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index bc2452330e4e2f..eda86c31fcc578 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(dict_fromkeys__doc__, "fromkeys($type, iterable, value=None, /)\n" "--\n" @@ -197,4 +191,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=c0064abbea6091c5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=582766ac0154c8bf input=a9049054013a1b77]*/ diff --git a/Objects/clinic/enumobject.c.h b/Objects/clinic/enumobject.c.h index adf78efd0d66f4..97f20c63cd4adf 100644 --- a/Objects/clinic/enumobject.c.h +++ b/Objects/clinic/enumobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(enum_new__doc__, "enumerate(iterable, start=0)\n" "--\n" @@ -107,4 +106,4 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=aba0ddbeab1601e3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=661b29708f501d19 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h index 3d9cd3a683ff5f..c40eff85cf3552 100644 --- a/Objects/clinic/floatobject.c.h +++ b/Objects/clinic/floatobject.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(float_is_integer__doc__, "is_integer($self, /)\n" "--\n" @@ -322,4 +316,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=355c3f5102034a41 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eb093cc601cc5426 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index c3a3a8edc39278..1be45674286905 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(func_new__doc__, "function(code, globals, name=None, argdefs=None, closure=None)\n" "--\n" @@ -104,4 +103,4 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=777cead7b1f6fad3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b2d676ff51c992d0 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index e3d6ffa9f76fdb..b6f0c5c0c42dd4 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(list_insert__doc__, "insert($self, index, object, /)\n" @@ -383,4 +383,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=2ca109d8acc775bc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e2d9f4092498a5ca input=a9049054013a1b77]*/ diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index d37e44f2f330bd..9288648fe3b7c2 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() static PyObject * long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); @@ -475,4 +475,4 @@ int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) { return int_is_integer_impl(self); } -/*[clinic end generated code: output=75ed306fff493ba1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=009a537ab558763c input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h index 0e6d9a4cad9e8f..74c749e0b6ccc8 100644 --- a/Objects/clinic/memoryobject.c.h +++ b/Objects/clinic/memoryobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(memoryview__doc__, "memoryview(object)\n" "--\n" @@ -112,7 +111,7 @@ memoryview__from_flags(PyTypeObject *type, PyObject *const *args, Py_ssize_t nar goto exit; } object = args[0]; - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -403,7 +402,7 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs goto skip_optional_pos; } } - bytes_per_sep = _PyLong_AsInt(args[1]); + bytes_per_sep = PyLong_AsInt(args[1]); if (bytes_per_sep == -1 && PyErr_Occurred()) { goto exit; } @@ -413,4 +412,4 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=a4f6992947bcaf25 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7ebdadda3b0fcd35 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/moduleobject.c.h b/Objects/clinic/moduleobject.c.h index 29df3888531933..ce21e4728dcb9e 100644 --- a/Objects/clinic/moduleobject.c.h +++ b/Objects/clinic/moduleobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(module___init____doc__, "module(name, doc=None)\n" "--\n" @@ -74,4 +73,4 @@ module___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a5a750cc8190576e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9d3d7854d17a033c input=a9049054013a1b77]*/ diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h index 115a134e3f7f54..643f504535d257 100644 --- a/Objects/clinic/odictobject.c.h +++ b/Objects/clinic/odictobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(OrderedDict_fromkeys__doc__, "fromkeys($type, /, iterable, value=None)\n" "--\n" @@ -332,4 +331,4 @@ OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=76d85a9162d62ca8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6d7ae9fb552c6108 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/structseq.c.h b/Objects/clinic/structseq.c.h index 40ba18a544f4b3..2571888454cb79 100644 --- a/Objects/clinic/structseq.c.h +++ b/Objects/clinic/structseq.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict); @@ -62,4 +61,4 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=802d5663c7d01024 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f88fe2a6f5c13a8 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/tupleobject.c.h b/Objects/clinic/tupleobject.c.h index 3de95759a13f21..f21712746a5ad1 100644 --- a/Objects/clinic/tupleobject.c.h +++ b/Objects/clinic/tupleobject.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(tuple_index__doc__, "index($self, value, start=0, stop=sys.maxsize, /)\n" "--\n" @@ -118,4 +112,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored)) { return tuple___getnewargs___impl(self); } -/*[clinic end generated code: output=48a9e0834b300ac3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7c5d9d12e0cf6a83 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typeobject.c.h b/Objects/clinic/typeobject.c.h index 6feb5b1920fe20..eb0b22a943ae8f 100644 --- a/Objects/clinic/typeobject.c.h +++ b/Objects/clinic/typeobject.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(type___instancecheck____doc__, "__instancecheck__($self, instance, /)\n" "--\n" @@ -190,7 +184,7 @@ object___reduce_ex__(PyObject *self, PyObject *arg) PyObject *return_value = NULL; int protocol; - protocol = _PyLong_AsInt(arg); + protocol = PyLong_AsInt(arg); if (protocol == -1 && PyErr_Occurred()) { goto exit; } @@ -266,4 +260,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=43533e6981550e9e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=943f639f264362d9 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typevarobject.c.h b/Objects/clinic/typevarobject.c.h index 54189b98446814..4762cd63545b60 100644 --- a/Objects/clinic/typevarobject.c.h +++ b/Objects/clinic/typevarobject.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(typevar_new__doc__, "typevar(name, *constraints, *, bound=None, covariant=False,\n" " contravariant=False, infer_variance=False)\n" @@ -110,58 +109,12 @@ typevar_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } PyDoc_STRVAR(typevar_typing_subst__doc__, -"__typing_subst__($self, /, arg)\n" +"__typing_subst__($self, arg, /)\n" "--\n" "\n"); #define TYPEVAR_TYPING_SUBST_METHODDEF \ - {"__typing_subst__", _PyCFunction_CAST(typevar_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevar_typing_subst__doc__}, - -static PyObject * -typevar_typing_subst_impl(typevarobject *self, PyObject *arg); - -static PyObject * -typevar_typing_subst(typevarobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 1 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(arg), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"arg", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "__typing_subst__", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *arg; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - arg = args[0]; - return_value = typevar_typing_subst_impl(self, arg); - -exit: - return return_value; -} + {"__typing_subst__", (PyCFunction)typevar_typing_subst, METH_O, typevar_typing_subst__doc__}, PyDoc_STRVAR(typevar_reduce__doc__, "__reduce__($self, /)\n" @@ -386,106 +339,33 @@ paramspec_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } PyDoc_STRVAR(paramspec_typing_subst__doc__, -"__typing_subst__($self, /, arg)\n" +"__typing_subst__($self, arg, /)\n" "--\n" "\n"); #define PARAMSPEC_TYPING_SUBST_METHODDEF \ - {"__typing_subst__", _PyCFunction_CAST(paramspec_typing_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_subst__doc__}, - -static PyObject * -paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg); - -static PyObject * -paramspec_typing_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 1 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(arg), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"arg", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "__typing_subst__", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *arg; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - arg = args[0]; - return_value = paramspec_typing_subst_impl(self, arg); - -exit: - return return_value; -} + {"__typing_subst__", (PyCFunction)paramspec_typing_subst, METH_O, paramspec_typing_subst__doc__}, PyDoc_STRVAR(paramspec_typing_prepare_subst__doc__, -"__typing_prepare_subst__($self, /, alias, args)\n" +"__typing_prepare_subst__($self, alias, args, /)\n" "--\n" "\n"); #define PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF \ - {"__typing_prepare_subst__", _PyCFunction_CAST(paramspec_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_prepare_subst__doc__}, + {"__typing_prepare_subst__", _PyCFunction_CAST(paramspec_typing_prepare_subst), METH_FASTCALL, paramspec_typing_prepare_subst__doc__}, static PyObject * paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias, PyObject *args); static PyObject * -paramspec_typing_prepare_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +paramspec_typing_prepare_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 2 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(alias), &_Py_ID(args), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"alias", "args", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "__typing_prepare_subst__", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; PyObject *alias; PyObject *__clinic_args; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { + if (!_PyArg_CheckPositional("__typing_prepare_subst__", nargs, 2, 2)) { goto exit; } alias = args[0]; @@ -572,106 +452,33 @@ typevartuple(PyTypeObject *type, PyObject *args, PyObject *kwargs) } PyDoc_STRVAR(typevartuple_typing_subst__doc__, -"__typing_subst__($self, /, arg)\n" +"__typing_subst__($self, arg, /)\n" "--\n" "\n"); #define TYPEVARTUPLE_TYPING_SUBST_METHODDEF \ - {"__typing_subst__", _PyCFunction_CAST(typevartuple_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_subst__doc__}, - -static PyObject * -typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg); - -static PyObject * -typevartuple_typing_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 1 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(arg), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"arg", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "__typing_subst__", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *arg; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - arg = args[0]; - return_value = typevartuple_typing_subst_impl(self, arg); - -exit: - return return_value; -} + {"__typing_subst__", (PyCFunction)typevartuple_typing_subst, METH_O, typevartuple_typing_subst__doc__}, PyDoc_STRVAR(typevartuple_typing_prepare_subst__doc__, -"__typing_prepare_subst__($self, /, alias, args)\n" +"__typing_prepare_subst__($self, alias, args, /)\n" "--\n" "\n"); #define TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF \ - {"__typing_prepare_subst__", _PyCFunction_CAST(typevartuple_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_prepare_subst__doc__}, + {"__typing_prepare_subst__", _PyCFunction_CAST(typevartuple_typing_prepare_subst), METH_FASTCALL, typevartuple_typing_prepare_subst__doc__}, static PyObject * typevartuple_typing_prepare_subst_impl(typevartupleobject *self, PyObject *alias, PyObject *args); static PyObject * -typevartuple_typing_prepare_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +typevartuple_typing_prepare_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 2 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(alias), &_Py_ID(args), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"alias", "args", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "__typing_prepare_subst__", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; PyObject *alias; PyObject *__clinic_args; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { + if (!_PyArg_CheckPositional("__typing_prepare_subst__", nargs, 2, 2)) { goto exit; } alias = args[0]; @@ -783,4 +590,4 @@ typealias_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=807bcd30ebd10ac3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=db0b327ebbb1488f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index b9127e428f4c99..42b8a3c69cad8a 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(EncodingMap_size__doc__, "size($self, /)\n" @@ -289,7 +289,7 @@ unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb if (!noptargs) { goto skip_optional_pos; } - tabsize = _PyLong_AsInt(args[0]); + tabsize = PyLong_AsInt(args[0]); if (tabsize == -1 && PyErr_Occurred()) { goto exit; } @@ -950,7 +950,7 @@ PyDoc_STRVAR(unicode_split__doc__, " The separator used to split the string.\n" "\n" " When set to None (the default value), will split on any whitespace\n" -" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" character (including \\n \\r \\t \\f and spaces) and will discard\n" " empty strings from the result.\n" " maxsplit\n" " Maximum number of splits (starting from the left).\n" @@ -1074,7 +1074,7 @@ PyDoc_STRVAR(unicode_rsplit__doc__, " The separator used to split the string.\n" "\n" " When set to None (the default value), will split on any whitespace\n" -" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" character (including \\n \\r \\t \\f and spaces) and will discard\n" " empty strings from the result.\n" " maxsplit\n" " Maximum number of splits (starting from the left).\n" @@ -1504,4 +1504,4 @@ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=ee76a1b49cd4cbb3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4acdcfdc93f2a0f6 input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index d2670c71caa44a..f662b8e354bb1e 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -2,12 +2,13 @@ #include "Python.h" #include "opcode.h" -#include "structmember.h" // PyMemberDef + #include "pycore_code.h" // _PyCodeConstructor #include "pycore_frame.h" // FRAME_SPECIALS_SIZE #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs -#include "pycore_opcode.h" // _PyOpcode_Deopt +#include "pycore_opcode_metadata.h" // _PyOpcode_Deopt, _PyOpcode_Caches #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "clinic/codeobject.c.h" @@ -394,6 +395,9 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) int nlocals, ncellvars, nfreevars; get_localsplus_counts(con->localsplusnames, con->localspluskinds, &nlocals, &ncellvars, &nfreevars); + if (con->stacksize == 0) { + con->stacksize = 1; + } co->co_filename = Py_NewRef(con->filename); co->co_name = Py_NewRef(con->name); @@ -423,9 +427,10 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE; co->co_ncellvars = ncellvars; co->co_nfreevars = nfreevars; - co->co_version = _Py_next_func_version; - if (_Py_next_func_version != 0) { - _Py_next_func_version++; + PyInterpreterState *interp = _PyInterpreterState_GET(); + co->co_version = interp->next_func_version; + if (interp->next_func_version != 0) { + interp->next_func_version++; } co->_co_monitoring = NULL; co->_co_instrumentation_version = 0; @@ -1475,6 +1480,23 @@ clear_executors(PyCodeObject *co) co->co_executors = NULL; } +void +_PyCode_Clear_Executors(PyCodeObject *code) { + int code_len = (int)Py_SIZE(code); + for (int i = 0; i < code_len; i += _PyInstruction_GetLength(code, i)) { + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + uint8_t opcode = instr->op.code; + uint8_t oparg = instr->op.arg; + if (opcode == ENTER_EXECUTOR) { + _PyExecutorObject *exec = code->co_executors->executors[oparg]; + assert(exec->vm_data.opcode != ENTER_EXECUTOR); + instr->op.code = exec->vm_data.opcode; + instr->op.arg = exec->vm_data.oparg; + } + } + clear_executors(code); +} + static void deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions) { @@ -1483,7 +1505,7 @@ deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions) int opcode = _Py_GetBaseOpcode(code, i); if (opcode == ENTER_EXECUTOR) { _PyExecutorObject *exec = code->co_executors->executors[instructions[i].op.arg]; - opcode = exec->vm_data.opcode; + opcode = _PyOpcode_Deopt[exec->vm_data.opcode]; instructions[i].op.arg = exec->vm_data.oparg; } assert(opcode != ENTER_EXECUTOR); @@ -1776,13 +1798,31 @@ code_richcompare(PyObject *self, PyObject *other, int op) for (int i = 0; i < Py_SIZE(co); i++) { _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i]; - co_instr.op.code = _PyOpcode_Deopt[co_instr.op.code]; - cp_instr.op.code = _PyOpcode_Deopt[cp_instr.op.code]; - eq = co_instr.cache == cp_instr.cache; - if (!eq) { + uint8_t co_code = _Py_GetBaseOpcode(co, i); + uint8_t co_arg = co_instr.op.arg; + uint8_t cp_code = _Py_GetBaseOpcode(cp, i); + uint8_t cp_arg = cp_instr.op.arg; + + if (co_code == ENTER_EXECUTOR) { + const int exec_index = co_arg; + _PyExecutorObject *exec = co->co_executors->executors[exec_index]; + co_code = _PyOpcode_Deopt[exec->vm_data.opcode]; + co_arg = exec->vm_data.oparg; + } + assert(co_code != ENTER_EXECUTOR); + + if (cp_code == ENTER_EXECUTOR) { + const int exec_index = cp_arg; + _PyExecutorObject *exec = cp->co_executors->executors[exec_index]; + cp_code = _PyOpcode_Deopt[exec->vm_data.opcode]; + cp_arg = exec->vm_data.oparg; + } + assert(cp_code != ENTER_EXECUTOR); + + if (co_code != cp_code || co_arg != cp_arg) { goto unequal; } - i += _PyOpcode_Caches[co_instr.op.code]; + i += _PyOpcode_Caches[co_code]; } /* compare constants */ @@ -1861,10 +1901,22 @@ code_hash(PyCodeObject *co) SCRAMBLE_IN(co->co_firstlineno); SCRAMBLE_IN(Py_SIZE(co)); for (int i = 0; i < Py_SIZE(co); i++) { - int deop = _Py_GetBaseOpcode(co, i); - SCRAMBLE_IN(deop); - SCRAMBLE_IN(_PyCode_CODE(co)[i].op.arg); - i += _PyOpcode_Caches[deop]; + _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; + uint8_t co_code = co_instr.op.code; + uint8_t co_arg = co_instr.op.arg; + if (co_code == ENTER_EXECUTOR) { + _PyExecutorObject *exec = co->co_executors->executors[co_arg]; + assert(exec != NULL); + assert(exec->vm_data.opcode != ENTER_EXECUTOR); + co_code = _PyOpcode_Deopt[exec->vm_data.opcode]; + co_arg = exec->vm_data.oparg; + } + else { + co_code = _Py_GetBaseOpcode(co, i); + } + SCRAMBLE_IN(co_code); + SCRAMBLE_IN(co_arg); + i += _PyOpcode_Caches[co_code]; } if ((Py_hash_t)uhash == -1) { return -2; @@ -1876,20 +1928,20 @@ code_hash(PyCodeObject *co) #define OFF(x) offsetof(PyCodeObject, x) static PyMemberDef code_memberlist[] = { - {"co_argcount", T_INT, OFF(co_argcount), READONLY}, - {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, - {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, - {"co_stacksize", T_INT, OFF(co_stacksize), READONLY}, - {"co_flags", T_INT, OFF(co_flags), READONLY}, - {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, - {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, - {"co_names", T_OBJECT, OFF(co_names), READONLY}, - {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, - {"co_name", T_OBJECT, OFF(co_name), READONLY}, - {"co_qualname", T_OBJECT, OFF(co_qualname), READONLY}, - {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, - {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY}, - {"co_exceptiontable", T_OBJECT, OFF(co_exceptiontable), READONLY}, + {"co_argcount", Py_T_INT, OFF(co_argcount), Py_READONLY}, + {"co_posonlyargcount", Py_T_INT, OFF(co_posonlyargcount), Py_READONLY}, + {"co_kwonlyargcount", Py_T_INT, OFF(co_kwonlyargcount), Py_READONLY}, + {"co_stacksize", Py_T_INT, OFF(co_stacksize), Py_READONLY}, + {"co_flags", Py_T_INT, OFF(co_flags), Py_READONLY}, + {"co_nlocals", Py_T_INT, OFF(co_nlocals), Py_READONLY}, + {"co_consts", _Py_T_OBJECT, OFF(co_consts), Py_READONLY}, + {"co_names", _Py_T_OBJECT, OFF(co_names), Py_READONLY}, + {"co_filename", _Py_T_OBJECT, OFF(co_filename), Py_READONLY}, + {"co_name", _Py_T_OBJECT, OFF(co_name), Py_READONLY}, + {"co_qualname", _Py_T_OBJECT, OFF(co_qualname), Py_READONLY}, + {"co_firstlineno", Py_T_INT, OFF(co_firstlineno), Py_READONLY}, + {"co_linetable", _Py_T_OBJECT, OFF(co_linetable), Py_READONLY}, + {"co_exceptiontable", _Py_T_OBJECT, OFF(co_exceptiontable), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -1967,27 +2019,28 @@ code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args)) } /*[clinic input] +@text_signature "($self, /, **changes)" code.replace * - co_argcount: int(c_default="self->co_argcount") = -1 - co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1 - co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1 - co_nlocals: int(c_default="self->co_nlocals") = -1 - co_stacksize: int(c_default="self->co_stacksize") = -1 - co_flags: int(c_default="self->co_flags") = -1 - co_firstlineno: int(c_default="self->co_firstlineno") = -1 - co_code: PyBytesObject(c_default="NULL") = None - co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None - co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None - co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None - co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None - co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None - co_filename: unicode(c_default="self->co_filename") = None - co_name: unicode(c_default="self->co_name") = None - co_qualname: unicode(c_default="self->co_qualname") = None - co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None - co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None + co_argcount: int(c_default="self->co_argcount") = unchanged + co_posonlyargcount: int(c_default="self->co_posonlyargcount") = unchanged + co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = unchanged + co_nlocals: int(c_default="self->co_nlocals") = unchanged + co_stacksize: int(c_default="self->co_stacksize") = unchanged + co_flags: int(c_default="self->co_flags") = unchanged + co_firstlineno: int(c_default="self->co_firstlineno") = unchanged + co_code: object(subclass_of="&PyBytes_Type", c_default="NULL") = unchanged + co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = unchanged + co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = unchanged + co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged + co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged + co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged + co_filename: unicode(c_default="self->co_filename") = unchanged + co_name: unicode(c_default="self->co_name") = unchanged + co_qualname: unicode(c_default="self->co_qualname") = unchanged + co_linetable: object(subclass_of="&PyBytes_Type", c_default="self->co_linetable") = unchanged + co_exceptiontable: object(subclass_of="&PyBytes_Type", c_default="self->co_exceptiontable") = unchanged Return a copy of the code object with new values for the specified fields. [clinic start generated code]*/ @@ -1996,14 +2049,13 @@ static PyObject * code_replace_impl(PyCodeObject *self, int co_argcount, int co_posonlyargcount, int co_kwonlyargcount, int co_nlocals, int co_stacksize, int co_flags, - int co_firstlineno, PyBytesObject *co_code, - PyObject *co_consts, PyObject *co_names, - PyObject *co_varnames, PyObject *co_freevars, - PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyObject *co_qualname, - PyBytesObject *co_linetable, - PyBytesObject *co_exceptiontable) -/*[clinic end generated code: output=b6cd9988391d5711 input=f6f68e03571f8d7c]*/ + int co_firstlineno, PyObject *co_code, PyObject *co_consts, + PyObject *co_names, PyObject *co_varnames, + PyObject *co_freevars, PyObject *co_cellvars, + PyObject *co_filename, PyObject *co_name, + PyObject *co_qualname, PyObject *co_linetable, + PyObject *co_exceptiontable) +/*[clinic end generated code: output=e75c48a15def18b9 input=18e280e07846c122]*/ { #define CHECK_INT_ARG(ARG) \ if (ARG < 0) { \ @@ -2028,7 +2080,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount, if (code == NULL) { return NULL; } - co_code = (PyBytesObject *)code; + co_code = code; } if (PySys_Audit("code.__new__", "OOOiiiiii", @@ -2067,10 +2119,10 @@ code_replace_impl(PyCodeObject *self, int co_argcount, co = PyCode_NewWithPosOnlyArgs( co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, - co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, + co_stacksize, co_flags, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_firstlineno, - (PyObject*)co_linetable, (PyObject*)co_exceptiontable); + co_linetable, co_exceptiontable); error: Py_XDECREF(code); @@ -2109,6 +2161,7 @@ static struct PyMethodDef code_methods[] = { {"co_positions", (PyCFunction)code_positionsiterator, METH_NOARGS}, CODE_REPLACE_METHODDEF CODE__VARNAME_FROM_OPARG_METHODDEF + {"__replace__", _PyCFunction_CAST(code_replace), METH_FASTCALL|METH_KEYWORDS}, {NULL, NULL} /* sentinel */ }; diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 12968a63cd6fdd..0e96f54584677c 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -11,7 +11,7 @@ #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_object.h" // _PyObject_Init() #include "pycore_pymath.h" // _Py_ADJUST_ERANGE2() -#include "structmember.h" // PyMemberDef + /*[clinic input] @@ -720,9 +720,9 @@ static PyMethodDef complex_methods[] = { }; static PyMemberDef complex_members[] = { - {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY, + {"real", Py_T_DOUBLE, offsetof(PyComplexObject, cval.real), Py_READONLY, "the real part of a complex number"}, - {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY, + {"imag", Py_T_DOUBLE, offsetof(PyComplexObject, cval.imag), Py_READONLY, "the imaginary part of a complex number"}, {0}, }; diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 810bd196e8f7e7..56ce34f80ca8e9 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -4,11 +4,12 @@ #include "pycore_abstract.h" // _PyObject_RealIsSubclass() #include "pycore_call.h" // _PyStack_AsDict() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() +#include "pycore_emscripten_trampoline.h" // descr_set_trampoline_call(), descr_get_trampoline_call() +#include "pycore_descrobject.h" // _PyMethodWrapper_Type #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "structmember.h" // PyMemberDef -#include "pycore_descrobject.h" + /*[clinic input] class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type" @@ -16,25 +17,6 @@ class property "propertyobject *" "&PyProperty_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/ -// see pycore_object.h -#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) -#include -EM_JS(int, descr_set_trampoline_call, (setter set, PyObject *obj, PyObject *value, void *closure), { - return wasmTable.get(set)(obj, value, closure); -}); - -EM_JS(PyObject*, descr_get_trampoline_call, (getter get, PyObject *obj, void *closure), { - return wasmTable.get(get)(obj, closure); -}); -#else -#define descr_set_trampoline_call(set, obj, value, closure) \ - (set)((obj), (value), (closure)) - -#define descr_get_trampoline_call(get, obj, closure) \ - (get)((obj), (closure)) - -#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE - static void descr_dealloc(PyDescrObject *descr) { @@ -182,7 +164,7 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) return NULL; } - if (descr->d_member->flags & PY_AUDIT_READ) { + if (descr->d_member->flags & Py_AUDIT_READ) { if (PySys_Audit("object.__getattr__", "Os", obj ? obj : Py_None, descr->d_member->name) < 0) { return NULL; @@ -588,7 +570,9 @@ method_get_doc(PyMethodDescrObject *descr, void *closure) static PyObject * method_get_text_signature(PyMethodDescrObject *descr, void *closure) { - return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc); + return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, + descr->d_method->ml_doc, + descr->d_method->ml_flags); } static PyObject * @@ -640,8 +624,8 @@ static PyMethodDef descr_methods[] = { }; static PyMemberDef descr_members[] = { - {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, - {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, + {"__objclass__", _Py_T_OBJECT, offsetof(PyDescrObject, d_type), Py_READONLY}, + {"__name__", _Py_T_OBJECT, offsetof(PyDescrObject, d_name), Py_READONLY}, {0} }; @@ -691,7 +675,8 @@ wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) static PyObject * wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure) { - return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc); + return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, + descr->d_base->doc, 0); } static PyGetSetDef wrapperdescr_getset[] = { @@ -1355,7 +1340,7 @@ static PyMethodDef wrapper_methods[] = { }; static PyMemberDef wrapper_members[] = { - {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY}, + {"__self__", _Py_T_OBJECT, offsetof(wrapperobject, self), Py_READONLY}, {0} }; @@ -1384,7 +1369,8 @@ wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored)) static PyObject * wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored)) { - return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); + return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, + wp->descr->d_base->doc, 0); } static PyObject * @@ -1515,10 +1501,10 @@ static PyObject * property_copy(PyObject *, PyObject *, PyObject *, PyObject *); static PyMemberDef property_members[] = { - {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, - {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, - {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, - {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0}, + {"fget", _Py_T_OBJECT, offsetof(propertyobject, prop_get), Py_READONLY}, + {"fset", _Py_T_OBJECT, offsetof(propertyobject, prop_set), Py_READONLY}, + {"fdel", _Py_T_OBJECT, offsetof(propertyobject, prop_del), Py_READONLY}, + {"__doc__", _Py_T_OBJECT, offsetof(propertyobject, prop_doc), 0}, {0} }; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 013c21884032aa..361f8e93064b25 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -115,12 +115,14 @@ As a consequence of this, split keys have a maximum size of 16. #include "Python.h" #include "pycore_bitutils.h" // _Py_bit_length #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_code.h" // stats #include "pycore_dict.h" // PyDictKeysObject #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() -#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_setobject.h" // _PySet_NextEntry() #include "stringlib/eq.h" // unicode_eq() #include @@ -1696,9 +1698,8 @@ PyDict_GetItem(PyObject *op, PyObject *key) /* Ignore any exception raised by the lookup */ _PyErr_SetRaisedException(tstate, exc); - assert(ix >= 0 || value == NULL); - return value; + return value; // borrowed reference } Py_ssize_t @@ -1737,9 +1738,46 @@ _PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) ix = _Py_dict_lookup(mp, key, hash, &value); assert(ix >= 0 || value == NULL); - return value; + return value; // borrowed reference } + +int +PyDict_GetItemRef(PyObject *op, PyObject *key, PyObject **result) +{ + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + *result = NULL; + return -1; + } + PyDictObject*mp = (PyDictObject *)op; + + Py_hash_t hash; + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) { + *result = NULL; + return -1; + } + } + + PyObject *value; + Py_ssize_t ix = _Py_dict_lookup(mp, key, hash, &value); + assert(ix >= 0 || value == NULL); + if (ix == DKIX_ERROR) { + *result = NULL; + return -1; + } + if (value == NULL) { + *result = NULL; + return 0; // missing key + } + *result = Py_NewRef(value); + return 1; // key is present +} + + /* Variant of PyDict_GetItem() that doesn't suppress exceptions. This returns NULL *with* an exception set if an exception occurred. It returns NULL *without* an exception set if the key wasn't present. @@ -1766,7 +1804,7 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) ix = _Py_dict_lookup(mp, key, hash, &value); assert(ix >= 0 || value == NULL); - return value; + return value; // borrowed reference } PyObject * @@ -1777,7 +1815,7 @@ _PyDict_GetItemWithError(PyObject *dp, PyObject *kv) if (hash == -1) { return NULL; } - return _PyDict_GetItem_KnownHash(dp, kv, hash); + return _PyDict_GetItem_KnownHash(dp, kv, hash); // borrowed reference } PyObject * @@ -1789,20 +1827,7 @@ _PyDict_GetItemIdWithError(PyObject *dp, _Py_Identifier *key) return NULL; Py_hash_t hash = unicode_get_hash(kv); assert (hash != -1); /* interned strings have their hash value initialised */ - return _PyDict_GetItem_KnownHash(dp, kv, hash); -} - -PyObject * -_PyDict_GetItemStringWithError(PyObject *v, const char *key) -{ - PyObject *kv, *rv; - kv = PyUnicode_FromString(key); - if (kv == NULL) { - return NULL; - } - rv = PyDict_GetItemWithError(v, kv); - Py_DECREF(kv); - return rv; + return _PyDict_GetItem_KnownHash(dp, kv, hash); // borrowed reference } /* Fast version of global value lookup (LOAD_GLOBAL). @@ -2663,12 +2688,11 @@ dict_update_arg(PyObject *self, PyObject *arg) if (PyDict_CheckExact(arg)) { return PyDict_Merge(self, arg, 1); } - PyObject *func; - if (PyObject_GetOptionalAttr(arg, &_Py_ID(keys), &func) < 0) { + int has_keys = PyObject_HasAttrWithError(arg, &_Py_ID(keys)); + if (has_keys < 0) { return -1; } - if (func != NULL) { - Py_DECREF(func); + if (has_keys) { return PyDict_Merge(self, arg, 1); } return PyDict_MergeFromSeq2(self, arg, 1); @@ -3704,6 +3728,18 @@ PyDict_Contains(PyObject *op, PyObject *key) return (ix != DKIX_EMPTY && value != NULL); } +int +PyDict_ContainsString(PyObject *op, const char *key) +{ + PyObject *key_obj = PyUnicode_FromString(key); + if (key_obj == NULL) { + return -1; + } + int res = PyDict_Contains(op, key_obj); + Py_DECREF(key_obj); + return res; +} + /* Internal version of PyDict_Contains used when the hash value is already known */ int _PyDict_Contains_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) @@ -3894,7 +3930,20 @@ PyDict_GetItemString(PyObject *v, const char *key) } rv = PyDict_GetItem(v, kv); Py_DECREF(kv); - return rv; + return rv; // borrowed reference +} + +int +PyDict_GetItemStringRef(PyObject *v, const char *key, PyObject **result) +{ + PyObject *key_obj = PyUnicode_FromString(key); + if (key_obj == NULL) { + *result = NULL; + return -1; + } + int res = PyDict_GetItemRef(v, key_obj, result); + Py_DECREF(key_obj); + return res; } int @@ -4593,7 +4642,7 @@ dictview_mapping(PyObject *view, void *Py_UNUSED(ignored)) { static PyGetSetDef dictview_getset[] = { {"mapping", dictview_mapping, (setter)NULL, - "dictionary that this view refers to", NULL}, + PyDoc_STR("dictionary that this view refers to"), NULL}, {0} }; @@ -5146,15 +5195,11 @@ dictitems_contains(_PyDictViewObject *dv, PyObject *obj) return 0; key = PyTuple_GET_ITEM(obj, 0); value = PyTuple_GET_ITEM(obj, 1); - found = PyDict_GetItemWithError((PyObject *)dv->dv_dict, key); - if (found == NULL) { - if (PyErr_Occurred()) - return -1; - return 0; + result = PyDict_GetItemRef((PyObject *)dv->dv_dict, key, &found); + if (result == 1) { + result = PyObject_RichCompareBool(found, value, Py_EQ); + Py_DECREF(found); } - Py_INCREF(found); - result = PyObject_RichCompareBool(found, value, Py_EQ); - Py_DECREF(found); return result; } @@ -5418,6 +5463,37 @@ _PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values) return make_dict_from_instance_attributes(interp, keys, values); } +// Return true if the dict was dematerialized, false otherwise. +bool +_PyObject_MakeInstanceAttributesFromDict(PyObject *obj, PyDictOrValues *dorv) +{ + assert(_PyObject_DictOrValuesPointer(obj) == dorv); + assert(!_PyDictOrValues_IsValues(*dorv)); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(*dorv); + if (dict == NULL) { + return false; + } + // It's likely that this dict still shares its keys (if it was materialized + // on request and not heavily modified): + if (!PyDict_CheckExact(dict)) { + return false; + } + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_HEAPTYPE)); + if (dict->ma_keys != CACHED_KEYS(Py_TYPE(obj)) || Py_REFCNT(dict) != 1) { + return false; + } + assert(dict->ma_values); + // We have an opportunity to do something *really* cool: dematerialize it! + _PyDictKeys_DecRef(dict->ma_keys); + _PyDictOrValues_SetValues(dorv, dict->ma_values); + OBJECT_STAT_INC(dict_dematerialized); + // Don't try this at home, kids: + dict->ma_keys = NULL; + dict->ma_values = NULL; + Py_DECREF(dict); + return true; +} + int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value) @@ -5573,7 +5649,7 @@ _PyObject_FreeInstanceAttributes(PyObject *self) } int -_PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) +PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) { PyTypeObject *tp = Py_TYPE(obj); if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { @@ -5596,7 +5672,7 @@ _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) } void -_PyObject_ClearManagedDict(PyObject *obj) +PyObject_ClearManagedDict(PyObject *obj) { PyTypeObject *tp = Py_TYPE(obj); if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { @@ -5642,6 +5718,7 @@ PyObject_GenericGetDict(PyObject *obj, void *context) dict = _PyDictOrValues_GetDict(*dorv_ptr); if (dict == NULL) { dictkeys_incref(CACHED_KEYS(tp)); + OBJECT_STAT_INC(dict_materialized_on_request); dict = new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); dorv_ptr->dict = dict; } @@ -5684,6 +5761,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, assert(dictptr != NULL); dict = *dictptr; if (dict == NULL) { + assert(!_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)); dictkeys_incref(cached); dict = new_dict_with_shared_keys(interp, cached); if (dict == NULL) diff --git a/Objects/exception_handling_notes.txt b/Objects/exception_handling_notes.txt index 7de01fdbf5ff48..387ef935ce739e 100644 --- a/Objects/exception_handling_notes.txt +++ b/Objects/exception_handling_notes.txt @@ -47,7 +47,7 @@ a table to determine where to jump to when an exception is raised. 2 2 NOP - 3 4 LOAD_GLOBAL 1 (NULL + g) + 3 4 LOAD_GLOBAL 1 (g + NULL) 16 LOAD_CONST 1 (0) 18 PRECALL 1 22 CALL 1 diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 42c5317d83d0c9..62a44234b34047 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -12,7 +12,7 @@ #include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_initconfig.h" #include "pycore_object.h" -#include "structmember.h" // PyMemberDef + #include "osdefs.h" // SEP @@ -439,7 +439,7 @@ PyExceptionClass_Name(PyObject *ob) } static struct PyMemberDef BaseException_members[] = { - {"__suppress_context__", T_BOOL, + {"__suppress_context__", Py_T_BOOL, offsetof(PyBaseExceptionObject, suppress_context)}, {NULL} }; @@ -569,7 +569,7 @@ SimpleExtendsException(PyExc_Exception, StopAsyncIteration, */ static PyMemberDef StopIteration_members[] = { - {"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0, + {"value", _Py_T_OBJECT, offsetof(PyStopIterationObject, value), 0, PyDoc_STR("generator return value")}, {NULL} /* Sentinel */ }; @@ -671,7 +671,7 @@ SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg) } static PyMemberDef SystemExit_members[] = { - {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0, + {"code", _Py_T_OBJECT, offsetof(PySystemExitObject, code), 0, PyDoc_STR("exception code")}, {NULL} /* Sentinel */ }; @@ -1477,9 +1477,9 @@ PyUnstable_Exc_PrepReraiseStar(PyObject *orig, PyObject *excs) } static PyMemberDef BaseExceptionGroup_members[] = { - {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY, + {"message", _Py_T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), Py_READONLY, PyDoc_STR("exception message")}, - {"exceptions", T_OBJECT, offsetof(PyBaseExceptionGroupObject, excs), READONLY, + {"exceptions", _Py_T_OBJECT, offsetof(PyBaseExceptionGroupObject, excs), Py_READONLY, PyDoc_STR("nested exceptions")}, {NULL} /* Sentinel */ }; @@ -1654,13 +1654,13 @@ ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored)) } static PyMemberDef ImportError_members[] = { - {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0, + {"msg", _Py_T_OBJECT, offsetof(PyImportErrorObject, msg), 0, PyDoc_STR("exception message")}, - {"name", T_OBJECT, offsetof(PyImportErrorObject, name), 0, + {"name", _Py_T_OBJECT, offsetof(PyImportErrorObject, name), 0, PyDoc_STR("module name")}, - {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0, + {"path", _Py_T_OBJECT, offsetof(PyImportErrorObject, path), 0, PyDoc_STR("module path")}, - {"name_from", T_OBJECT, offsetof(PyImportErrorObject, name_from), 0, + {"name_from", _Py_T_OBJECT, offsetof(PyImportErrorObject, name_from), 0, PyDoc_STR("name imported from module")}, {NULL} /* Sentinel */ }; @@ -2103,16 +2103,16 @@ OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context) } static PyMemberDef OSError_members[] = { - {"errno", T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0, + {"errno", _Py_T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0, PyDoc_STR("POSIX exception code")}, - {"strerror", T_OBJECT, offsetof(PyOSErrorObject, strerror), 0, + {"strerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, strerror), 0, PyDoc_STR("exception strerror")}, - {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0, + {"filename", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename), 0, PyDoc_STR("exception filename")}, - {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0, + {"filename2", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename2), 0, PyDoc_STR("second exception filename")}, #ifdef MS_WINDOWS - {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0, + {"winerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, winerror), 0, PyDoc_STR("Win32 exception code")}, #endif {NULL} /* Sentinel */ @@ -2249,7 +2249,7 @@ NameError_traverse(PyNameErrorObject *self, visitproc visit, void *arg) } static PyMemberDef NameError_members[] = { - {"name", T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")}, + {"name", _Py_T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")}, {NULL} /* Sentinel */ }; @@ -2368,8 +2368,8 @@ AttributeError_reduce(PyAttributeErrorObject *self, PyObject *Py_UNUSED(ignored) } static PyMemberDef AttributeError_members[] = { - {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")}, - {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")}, + {"name", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")}, + {"obj", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")}, {NULL} /* Sentinel */ }; @@ -2541,21 +2541,21 @@ SyntaxError_str(PySyntaxErrorObject *self) } static PyMemberDef SyntaxError_members[] = { - {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0, + {"msg", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0, PyDoc_STR("exception msg")}, - {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0, + {"filename", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0, PyDoc_STR("exception filename")}, - {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0, + {"lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0, PyDoc_STR("exception lineno")}, - {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0, + {"offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0, PyDoc_STR("exception offset")}, - {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0, + {"text", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, text), 0, PyDoc_STR("exception text")}, - {"end_lineno", T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0, + {"end_lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0, PyDoc_STR("exception end lineno")}, - {"end_offset", T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0, + {"end_offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0, PyDoc_STR("exception end offset")}, - {"print_file_and_line", T_OBJECT, + {"print_file_and_line", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, print_file_and_line), 0, PyDoc_STR("exception print_file_and_line")}, {NULL} /* Sentinel */ @@ -2910,15 +2910,15 @@ UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg) } static PyMemberDef UnicodeError_members[] = { - {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0, + {"encoding", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0, PyDoc_STR("exception encoding")}, - {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0, + {"object", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0, PyDoc_STR("exception object")}, - {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0, + {"start", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0, PyDoc_STR("exception start")}, - {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0, + {"end", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0, PyDoc_STR("exception end")}, - {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0, + {"reason", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0, PyDoc_STR("exception reason")}, {NULL} /* Sentinel */ }; diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 751fb69d0891cf..5522eba34eace9 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -4,15 +4,19 @@ #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_runtime.h" // _PyRuntime +#ifdef HAVE_UNISTD_H +# include // isatty() +#endif + #if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER) -/* clang MemorySanitizer doesn't yet understand getc_unlocked. */ -#define GETC(f) getc_unlocked(f) -#define FLOCKFILE(f) flockfile(f) -#define FUNLOCKFILE(f) funlockfile(f) + /* clang MemorySanitizer doesn't yet understand getc_unlocked. */ +# define GETC(f) getc_unlocked(f) +# define FLOCKFILE(f) flockfile(f) +# define FUNLOCKFILE(f) funlockfile(f) #else -#define GETC(f) getc(f) -#define FLOCKFILE(f) -#define FUNLOCKFILE(f) +# define GETC(f) getc(f) +# define FLOCKFILE(f) +# define FUNLOCKFILE(f) #endif /* Newline flags */ @@ -21,10 +25,6 @@ #define NEWLINE_LF 2 /* \n newline seen */ #define NEWLINE_CRLF 4 /* \r\n newline seen */ -#ifdef __cplusplus -extern "C" { -#endif - /* External C interface */ PyObject * @@ -174,7 +174,7 @@ PyObject_AsFileDescriptor(PyObject *o) PyObject *meth; if (PyLong_Check(o)) { - fd = _PyLong_AsInt(o); + fd = PyLong_AsInt(o); } else if (PyObject_GetOptionalAttr(o, &_Py_ID(fileno), &meth) < 0) { return -1; @@ -186,7 +186,7 @@ PyObject_AsFileDescriptor(PyObject *o) return -1; if (PyLong_Check(fno)) { - fd = _PyLong_AsInt(fno); + fd = PyLong_AsInt(fno); Py_DECREF(fno); } else { @@ -529,6 +529,13 @@ PyFile_OpenCode(const char *utf8path) } -#ifdef __cplusplus +int +_PyFile_Flush(PyObject *file) +{ + PyObject *tmp = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); + if (tmp == NULL) { + return -1; + } + Py_DECREF(tmp); + return 0; } -#endif diff --git a/Objects/floatobject.c b/Objects/floatobject.c index fa55481f09dec0..776c7092edd057 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -4,19 +4,19 @@ for any kind of float exception without losing portability. */ #include "Python.h" +#include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_dtoa.h" // _Py_dg_dtoa() #include "pycore_floatobject.h" // _PyFloat_FormatAdvancedWriter() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // _PyInterpreterState.float_state #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_modsupport.h" // _PyArg_NoKwnames() -#include "pycore_object.h" // _PyObject_Init() +#include "pycore_object.h" // _PyObject_Init(), _PyDebugAllocatorStats() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() -#include -#include +#include // DBL_MAX #include // strtol() /*[clinic input] diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 18820551a0547e..d75444393f3697 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -6,17 +6,18 @@ #include "pycore_function.h" // _PyFunction_FromConstructor() #include "pycore_moduleobject.h" // _PyModule_GetDict() #include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "pycore_opcode.h" // _PyOpcode_Caches +#include "pycore_opcode_metadata.h" // _PyOpcode_Deopt, _PyOpcode_Caches + #include "frameobject.h" // PyFrameObject #include "pycore_frame.h" #include "opcode.h" // EXTENDED_ARG -#include "structmember.h" // PyMemberDef + #define OFF(x) offsetof(PyFrameObject, x) static PyMemberDef frame_memberlist[] = { - {"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0}, + {"f_trace_lines", Py_T_BOOL, OFF(f_trace_lines), 0}, {NULL} /* Sentinel */ }; @@ -24,10 +25,16 @@ static PyMemberDef frame_memberlist[] = { static PyObject * frame_getlocals(PyFrameObject *f, void *closure) { - if (PyFrame_FastToLocalsWithError(f) < 0) + if (f == NULL) { + PyErr_BadInternalCall(); return NULL; - PyObject *locals = f->f_frame->f_locals; - return Py_NewRef(locals); + } + assert(!_PyFrame_IsIncomplete(f->f_frame)); + PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1); + if (locals) { + f->f_fast_as_locals = 1; + } + return locals; } int @@ -404,10 +411,10 @@ mark_stacks(PyCodeObject *code_obj, int len) case LOAD_GLOBAL: { int j = oparg; + next_stack = push_value(next_stack, Object); if (j & 1) { next_stack = push_value(next_stack, Null); } - next_stack = push_value(next_stack, Object); stacks[next_i] = next_stack; break; } @@ -417,22 +424,12 @@ mark_stacks(PyCodeObject *code_obj, int len) int j = oparg; if (j & 1) { next_stack = pop_value(next_stack); - next_stack = push_value(next_stack, Null); next_stack = push_value(next_stack, Object); + next_stack = push_value(next_stack, Null); } stacks[next_i] = next_stack; break; } - case CALL: - { - int args = oparg; - for (int j = 0; j < args+2; j++) { - next_stack = pop_value(next_stack); - } - next_stack = push_value(next_stack, Object); - stacks[next_i] = next_stack; - break; - } case SWAP: { int n = oparg; @@ -590,39 +587,28 @@ first_line_not_before(int *lines, int len, int line) return result; } -static PyFrameState -_PyFrame_GetState(PyFrameObject *frame) +static bool +frame_is_cleared(PyFrameObject *frame) { assert(!_PyFrame_IsIncomplete(frame->f_frame)); if (frame->f_frame->stacktop == 0) { - return FRAME_CLEARED; + return true; } - switch(frame->f_frame->owner) { - case FRAME_OWNED_BY_GENERATOR: - { - PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame); - return gen->gi_frame_state; - } - case FRAME_OWNED_BY_THREAD: - { - if (_PyInterpreterFrame_LASTI(frame->f_frame) < 0) { - return FRAME_CREATED; - } - switch (frame->f_frame->prev_instr->op.code) - { - case COPY_FREE_VARS: - case MAKE_CELL: - case RETURN_GENERATOR: - /* Frame not fully initialized */ - return FRAME_CREATED; - default: - return FRAME_EXECUTING; - } - } - case FRAME_OWNED_BY_FRAME_OBJECT: - return FRAME_COMPLETED; + if (frame->f_frame->owner == FRAME_OWNED_BY_GENERATOR) { + PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame); + return gen->gi_frame_state == FRAME_CLEARED; } - Py_UNREACHABLE(); + return false; +} + +static bool frame_is_suspended(PyFrameObject *frame) +{ + assert(!_PyFrame_IsIncomplete(frame->f_frame)); + if (frame->f_frame->owner == FRAME_OWNED_BY_GENERATOR) { + PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame); + return gen->gi_frame_state == FRAME_SUSPENDED; + } + return false; } /* Setter for f_lineno - you can set f_lineno from within a trace function in @@ -654,7 +640,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore return -1; } - PyFrameState state = _PyFrame_GetState(f); + bool is_suspended = frame_is_suspended(f); /* * This code preserves the historical restrictions on * setting the line number of a frame. @@ -810,7 +796,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore } assert(unbound == 0); } - if (state == FRAME_SUSPENDED) { + if (is_suspended) { /* Account for value popped by yield */ start_stack = pop_value(start_stack); } @@ -879,9 +865,6 @@ frame_dealloc(PyFrameObject *f) /* It is the responsibility of the owning generator/coroutine * to have cleared the generator pointer */ - assert(f->f_frame->owner != FRAME_OWNED_BY_GENERATOR || - _PyFrame_GetGenerator(f->f_frame)->gi_frame_state == FRAME_CLEARED); - if (_PyObject_GC_IS_TRACKED(f)) { _PyObject_GC_UNTRACK(f); } @@ -889,10 +872,14 @@ frame_dealloc(PyFrameObject *f) Py_TRASHCAN_BEGIN(f, frame_dealloc); PyObject *co = NULL; + /* GH-106092: If f->f_frame was on the stack and we reached the maximum + * nesting depth for deallocations, the trashcan may have delayed this + * deallocation until after f->f_frame is freed. Avoid dereferencing + * f->f_frame unless we know it still points to valid memory. */ + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data; + /* Kill all local variables including specials, if we own them */ - if (f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { - assert(f->f_frame == (_PyInterpreterFrame *)f->_f_frame_data); - _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data; + if (f->f_frame == frame && frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { /* Don't clear code object until the end */ co = frame->f_executable; frame->f_executable = NULL; @@ -1351,11 +1338,11 @@ PyFrame_GetVarString(PyFrameObject *frame, const char *name) int PyFrame_FastToLocalsWithError(PyFrameObject *f) { - assert(!_PyFrame_IsIncomplete(f->f_frame)); if (f == NULL) { PyErr_BadInternalCall(); return -1; } + assert(!_PyFrame_IsIncomplete(f->f_frame)); int err = _PyFrame_FastToLocalsWithError(f->f_frame); if (err == 0) { f->f_fast_as_locals = 1; @@ -1453,7 +1440,7 @@ void PyFrame_LocalsToFast(PyFrameObject *f, int clear) { assert(!_PyFrame_IsIncomplete(f->f_frame)); - if (f && f->f_fast_as_locals && _PyFrame_GetState(f) != FRAME_CLEARED) { + if (f && f->f_fast_as_locals && !frame_is_cleared(f)) { _PyFrame_LocalsToFast(f->f_frame, clear); f->f_fast_as_locals = 0; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 0c69bf4ebcfed5..e8ad486150da47 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -3,10 +3,9 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() -#include "pycore_code.h" // _Py_next_func_version #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_Occurred() -#include "structmember.h" // PyMemberDef + static PyObject* func_repr(PyFunctionObject *op); @@ -223,7 +222,79 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname return NULL; } -uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func) +/* +Function versions +----------------- + +Function versions are used to detect when a function object has been +updated, invalidating inline cache data used by the `CALL` bytecode +(notably `CALL_PY_EXACT_ARGS` and a few other `CALL` specializations). + +They are also used by the Tier 2 superblock creation code to find +the function being called (and from there the code object). + +How does a function's `func_version` field get initialized? + +- `PyFunction_New` and friends initialize it to 0. +- The `MAKE_FUNCTION` instruction sets it from the code's `co_version`. +- It is reset to 0 when various attributes like `__code__` are set. +- A new version is allocated by `_PyFunction_GetVersionForCurrentState` + when the specializer needs a version and the version is 0. + +The latter allocates versions using a counter in the interpreter state; +when the counter wraps around to 0, no more versions are allocated. +There is one other special case: functions with a non-standard +`vectorcall` field are not given a version. + +When the function version is 0, the `CALL` bytecode is not specialized. + +Code object versions +-------------------- + +So where to code objects get their `co_version`? +There is a per-interpreter counter, `next_func_version`. +This is initialized to 1 when the interpreter is created. + +Code objects get a new `co_version` allocated from this counter upon +creation. Since code objects are nominally immutable, `co_version` can +not be invalidated. The only way it can be 0 is when 2**32 or more +code objects have been created during the process's lifetime. +(The counter isn't reset by `fork()`, extending the lifetime.) +*/ + +void +_PyFunction_SetVersion(PyFunctionObject *func, uint32_t version) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (func->func_version != 0) { + PyFunctionObject **slot = + interp->func_state.func_version_cache + + (func->func_version % FUNC_VERSION_CACHE_SIZE); + if (*slot == func) { + *slot = NULL; + } + } + func->func_version = version; + if (version != 0) { + interp->func_state.func_version_cache[ + version % FUNC_VERSION_CACHE_SIZE] = func; + } +} + +PyFunctionObject * +_PyFunction_LookupByVersion(uint32_t version) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyFunctionObject *func = interp->func_state.func_version_cache[ + version % FUNC_VERSION_CACHE_SIZE]; + if (func != NULL && func->func_version == version) { + return func; + } + return NULL; +} + +uint32_t +_PyFunction_GetVersionForCurrentState(PyFunctionObject *func) { if (func->func_version != 0) { return func->func_version; @@ -236,7 +307,7 @@ uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func) return 0; } uint32_t v = interp->func_state.next_version++; - func->func_version = v; + _PyFunction_SetVersion(func, v); return v; } @@ -304,7 +375,7 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults) } handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, (PyFunctionObject *) op, defaults); - ((PyFunctionObject *)op)->func_version = 0; + _PyFunction_SetVersion((PyFunctionObject *)op, 0); Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults); return 0; } @@ -313,7 +384,7 @@ void PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall) { assert(func != NULL); - func->func_version = 0; + _PyFunction_SetVersion(func, 0); func->vectorcall = vectorcall; } @@ -346,7 +417,7 @@ PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults) } handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, (PyFunctionObject *) op, defaults); - ((PyFunctionObject *)op)->func_version = 0; + _PyFunction_SetVersion((PyFunctionObject *)op, 0); Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults); return 0; } @@ -379,7 +450,7 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure) Py_TYPE(closure)->tp_name); return -1; } - ((PyFunctionObject *)op)->func_version = 0; + _PyFunction_SetVersion((PyFunctionObject *)op, 0); Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure); return 0; } @@ -441,7 +512,7 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) "non-dict annotations"); return -1; } - ((PyFunctionObject *)op)->func_version = 0; + _PyFunction_SetVersion((PyFunctionObject *)op, 0); Py_XSETREF(((PyFunctionObject *)op)->func_annotations, annotations); return 0; } @@ -451,11 +522,11 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) #define OFF(x) offsetof(PyFunctionObject, x) static PyMemberDef func_memberlist[] = { - {"__closure__", T_OBJECT, OFF(func_closure), READONLY}, - {"__doc__", T_OBJECT, OFF(func_doc), 0}, - {"__globals__", T_OBJECT, OFF(func_globals), READONLY}, - {"__module__", T_OBJECT, OFF(func_module), 0}, - {"__builtins__", T_OBJECT, OFF(func_builtins), READONLY}, + {"__closure__", _Py_T_OBJECT, OFF(func_closure), Py_READONLY}, + {"__doc__", _Py_T_OBJECT, OFF(func_doc), 0}, + {"__globals__", _Py_T_OBJECT, OFF(func_globals), Py_READONLY}, + {"__module__", _Py_T_OBJECT, OFF(func_module), 0}, + {"__builtins__", _Py_T_OBJECT, OFF(func_builtins), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -500,7 +571,7 @@ func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) return -1; } handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value); - op->func_version = 0; + _PyFunction_SetVersion(op, 0); Py_XSETREF(op->func_code, Py_NewRef(value)); return 0; } @@ -580,7 +651,7 @@ func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored } handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, op, value); - op->func_version = 0; + _PyFunction_SetVersion(op, 0); Py_XSETREF(op->func_defaults, Py_XNewRef(value)); return 0; } @@ -621,7 +692,7 @@ func_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignor } handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, op, value); - op->func_version = 0; + _PyFunction_SetVersion(op, 0); Py_XSETREF(op->func_kwdefaults, Py_XNewRef(value)); return 0; } @@ -651,7 +722,7 @@ func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(igno "__annotations__ must be set to a dict object"); return -1; } - op->func_version = 0; + _PyFunction_SetVersion(op, 0); Py_XSETREF(op->func_annotations, Py_XNewRef(value)); return 0; } @@ -815,7 +886,7 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, static int func_clear(PyFunctionObject *op) { - op->func_version = 0; + _PyFunction_SetVersion(op, 0); Py_CLEAR(op->func_globals); Py_CLEAR(op->func_builtins); Py_CLEAR(op->func_module); @@ -831,8 +902,8 @@ func_clear(PyFunctionObject *op) // However, name and qualname could be str subclasses, so they // could have reference cycles. The solution is to replace them // with a genuinely immutable string. - Py_SETREF(op->func_name, Py_NewRef(&_Py_STR(empty))); - Py_SETREF(op->func_qualname, Py_NewRef(&_Py_STR(empty))); + Py_SETREF(op->func_name, &_Py_STR(empty)); + Py_SETREF(op->func_qualname, &_Py_STR(empty)); return 0; } @@ -851,6 +922,7 @@ func_dealloc(PyFunctionObject *op) if (op->func_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) op); } + _PyFunction_SetVersion(op, 0); (void)func_clear(op); // These aren't cleared by func_clear(). Py_DECREF(op->func_code); @@ -1063,8 +1135,8 @@ cm_init(PyObject *self, PyObject *args, PyObject *kwds) } static PyMemberDef cm_memberlist[] = { - {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY}, - {"__wrapped__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY}, + {"__func__", _Py_T_OBJECT, offsetof(classmethod, cm_callable), Py_READONLY}, + {"__wrapped__", _Py_T_OBJECT, offsetof(classmethod, cm_callable), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -1258,8 +1330,8 @@ sm_call(PyObject *callable, PyObject *args, PyObject *kwargs) } static PyMemberDef sm_memberlist[] = { - {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY}, - {"__wrapped__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY}, + {"__func__", _Py_T_OBJECT, offsetof(staticmethod, sm_callable), Py_READONLY}, + {"__wrapped__", _Py_T_OBJECT, offsetof(staticmethod, sm_callable), Py_READONLY}, {NULL} /* Sentinel */ }; diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 0c478f3717e036..bf13ed3650bac5 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -1,9 +1,10 @@ // types.GenericAlias -- used to represent e.g. list[int]. #include "Python.h" +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_object.h" #include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check -#include "structmember.h" // PyMemberDef + #include @@ -54,8 +55,7 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) PyObject *qualname = NULL; PyObject *module = NULL; PyObject *r = NULL; - PyObject *tmp; - int err; + int rc; if (p == Py_Ellipsis) { // The Ellipsis object @@ -63,19 +63,14 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) goto done; } - if (PyObject_GetOptionalAttr(p, &_Py_ID(__origin__), &tmp) < 0) { - goto done; + if ((rc = PyObject_HasAttrWithError(p, &_Py_ID(__origin__))) > 0 && + (rc = PyObject_HasAttrWithError(p, &_Py_ID(__args__))) > 0) + { + // It looks like a GenericAlias + goto use_repr; } - if (tmp != NULL) { - Py_DECREF(tmp); - if (PyObject_GetOptionalAttr(p, &_Py_ID(__args__), &tmp) < 0) { - goto done; - } - if (tmp != NULL) { - Py_DECREF(tmp); - // It looks like a GenericAlias - goto use_repr; - } + if (rc < 0) { + goto done; } if (PyObject_GetOptionalAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { @@ -112,13 +107,13 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) Py_XDECREF(module); if (r == NULL) { // error if any of the above PyObject_Repr/PyUnicode_From* fail - err = -1; + rc = -1; } else { - err = _PyUnicodeWriter_WriteStr(writer, r); + rc = _PyUnicodeWriter_WriteStr(writer, r); Py_DECREF(r); } - return err; + return rc; } static int @@ -252,18 +247,17 @@ _Py_make_parameters(PyObject *args) Py_ssize_t iparam = 0; for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { PyObject *t = PyTuple_GET_ITEM(args, iarg); - PyObject *subst; // We don't want __parameters__ descriptor of a bare Python class. if (PyType_Check(t)) { continue; } - if (PyObject_GetOptionalAttr(t, &_Py_ID(__typing_subst__), &subst) < 0) { + int rc = PyObject_HasAttrWithError(t, &_Py_ID(__typing_subst__)); + if (rc < 0) { Py_DECREF(parameters); return NULL; } - if (subst) { + if (rc) { iparam += tuple_add(parameters, iparam, t); - Py_DECREF(subst); } else { PyObject *subparams; @@ -626,6 +620,7 @@ ga_vectorcall(PyObject *self, PyObject *const *args, static const char* const attr_exceptions[] = { "__class__", + "__bases__", "__origin__", "__args__", "__unpacked__", @@ -782,9 +777,9 @@ static PyMethodDef ga_methods[] = { }; static PyMemberDef ga_members[] = { - {"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY}, - {"__args__", T_OBJECT, offsetof(gaobject, args), READONLY}, - {"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY}, + {"__origin__", _Py_T_OBJECT, offsetof(gaobject, origin), Py_READONLY}, + {"__args__", _Py_T_OBJECT, offsetof(gaobject, args), Py_READONLY}, + {"__unpacked__", Py_T_BOOL, offsetof(gaobject, starred), Py_READONLY}, {0} }; @@ -812,7 +807,7 @@ ga_unpacked_tuple_args(PyObject *self, void *unused) } static PyGetSetDef ga_properties[] = { - {"__parameters__", ga_parameters, (setter)NULL, "Type variables in the GenericAlias.", NULL}, + {"__parameters__", ga_parameters, (setter)NULL, PyDoc_STR("Type variables in the GenericAlias."), NULL}, {"__typing_unpacked_tuple_args__", ga_unpacked_tuple_args, (setter)NULL, NULL}, {0} }; diff --git a/Objects/genobject.c b/Objects/genobject.c index 103e8b8bb882f6..40033d10bea9ee 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -10,7 +10,7 @@ #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "structmember.h" // PyMemberDef + #include "opcode.h" // SEND #include "frameobject.h" // _PyInterpreterFrame_GetLine #include "pystats.h" @@ -149,14 +149,16 @@ gen_dealloc(PyGenObject *gen) gen->gi_frame_state = FRAME_CLEARED; frame->previous = NULL; _PyFrame_ClearExceptCode(frame); + _PyErr_ClearExcState(&gen->gi_exc_state); } + assert(gen->gi_exc_state.exc_value == NULL); if (_PyGen_GetCode(gen)->co_flags & CO_COROUTINE) { Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer); } Py_DECREF(_PyGen_GetCode(gen)); Py_CLEAR(gen->gi_name); Py_CLEAR(gen->gi_qualname); - _PyErr_ClearExcState(&gen->gi_exc_state); + PyObject_GC_Del(gen); } @@ -252,10 +254,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, !PyErr_ExceptionMatches(PyExc_StopAsyncIteration)); } - /* generator can't be rerun, so release the frame */ - /* first clean reference cycle through stored exception traceback */ - _PyErr_ClearExcState(&gen->gi_exc_state); - + assert(gen->gi_exc_state.exc_value == NULL); assert(gen->gi_frame_state == FRAME_CLEARED); *presult = result; return result ? PYGEN_RETURN : PYGEN_ERROR; @@ -334,7 +333,11 @@ gen_close_iter(PyObject *yf) static inline bool is_resume(_Py_CODEUNIT *instr) { - return instr->op.code == RESUME || instr->op.code == INSTRUMENTED_RESUME; + return ( + instr->op.code == RESUME || + instr->op.code == RESUME_CHECK || + instr->op.code == INSTRUMENTED_RESUME + ); } static inline bool @@ -477,9 +480,9 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, will be reported correctly to the user. */ /* XXX We should probably be updating the current frame somewhere in ceval.c. */ - _PyInterpreterFrame *prev = tstate->cframe->current_frame; + _PyInterpreterFrame *prev = tstate->current_frame; frame->previous = prev; - tstate->cframe->current_frame = frame; + tstate->current_frame = frame; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ PyFrameState state = gen->gi_frame_state; @@ -487,7 +490,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); gen->gi_frame_state = state; - tstate->cframe->current_frame = prev; + tstate->current_frame = prev; frame->previous = NULL; } else { /* `yf` is an iterator or a coroutine-like object. */ @@ -939,7 +942,7 @@ _Py_MakeCoro(PyFunctionObject *func) if (origin_depth == 0) { ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL; } else { - _PyInterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = tstate->current_frame; assert(frame); assert(_PyFrame_IsIncomplete(frame)); frame = _PyFrame_GetFirstComplete(frame->previous); @@ -1144,7 +1147,7 @@ static PyGetSetDef coro_getsetlist[] = { }; static PyMemberDef coro_memberlist[] = { - {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin_or_finalizer), READONLY}, + {"cr_origin", _Py_T_OBJECT, offsetof(PyCoroObject, cr_origin_or_finalizer), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -1558,8 +1561,8 @@ static PyGetSetDef async_gen_getsetlist[] = { }; static PyMemberDef async_gen_memberlist[] = { - {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), - READONLY}, + {"ag_running", Py_T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), + Py_READONLY}, {NULL} /* Sentinel */ }; diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 46239100dcb7b7..16e27b64c0c9c2 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -46,7 +46,7 @@ static int interp_id_converter(PyObject *arg, void *ptr) { int64_t id; - if (PyObject_TypeCheck(arg, &_PyInterpreterID_Type)) { + if (PyObject_TypeCheck(arg, &PyInterpreterID_Type)) { id = ((interpid *)arg)->id; } else if (_PyIndex_Check(arg)) { @@ -183,13 +183,13 @@ interpid_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_NOTIMPLEMENTED; } - if (!PyObject_TypeCheck(self, &_PyInterpreterID_Type)) { + if (!PyObject_TypeCheck(self, &PyInterpreterID_Type)) { Py_RETURN_NOTIMPLEMENTED; } interpid *id = (interpid *)self; int equal; - if (PyObject_TypeCheck(other, &_PyInterpreterID_Type)) { + if (PyObject_TypeCheck(other, &PyInterpreterID_Type)) { interpid *otherid = (interpid *)other; equal = (id->id == otherid->id); } @@ -224,7 +224,7 @@ interpid_richcompare(PyObject *self, PyObject *other, int op) PyDoc_STRVAR(interpid_doc, "A interpreter ID identifies a interpreter and may be used as an int."); -PyTypeObject _PyInterpreterID_Type = { +PyTypeObject PyInterpreterID_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "InterpreterID", /* tp_name */ sizeof(interpid), /* tp_basicsize */ @@ -265,13 +265,13 @@ PyTypeObject _PyInterpreterID_Type = { interpid_new, /* tp_new */ }; -PyObject *_PyInterpreterID_New(int64_t id) +PyObject *PyInterpreterID_New(int64_t id) { - return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0); + return (PyObject *)newinterpid(&PyInterpreterID_Type, id, 0); } PyObject * -_PyInterpreterState_GetIDObject(PyInterpreterState *interp) +PyInterpreterState_GetIDObject(PyInterpreterState *interp) { if (_PyInterpreterState_IDInitref(interp) != 0) { return NULL; @@ -280,11 +280,11 @@ _PyInterpreterState_GetIDObject(PyInterpreterState *interp) if (id < 0) { return NULL; } - return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0); + return (PyObject *)newinterpid(&PyInterpreterID_Type, id, 0); } PyInterpreterState * -_PyInterpreterID_LookUp(PyObject *requested_id) +PyInterpreterID_LookUp(PyObject *requested_id) { int64_t id; if (!interp_id_converter(requested_id, &id)) { diff --git a/Objects/iterobject.c b/Objects/iterobject.c index cf7cb8af52a274..135ced9ea1f268 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyObject_HasLen() #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_object.h" // _PyObject_GC_TRACK() typedef struct { diff --git a/Objects/listobject.c b/Objects/listobject.c index 144ede6351e03c..ad1840b01226ec 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2,11 +2,12 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_interp.h" // PyInterpreterState.list #include "pycore_list.h" // struct _Py_list_state, _PyListIterObject #include "pycore_long.h" // _PyLong_DigitCount #include "pycore_modsupport.h" // _PyArg_NoKwnames() -#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats() #include "pycore_tuple.h" // _PyTuple_FromArray() #include diff --git a/Objects/lnotab_notes.txt b/Objects/lnotab_notes.txt index 362b87a86a481f..d45d09d4ab9a50 100644 --- a/Objects/lnotab_notes.txt +++ b/Objects/lnotab_notes.txt @@ -1,4 +1,7 @@ -Description of the internal format of the line number table +Description of the internal format of the line number table in Python 3.10 +and earlier. + +(For 3.11 onwards, see Objects/locations.md) Conceptually, the line number table consists of a sequence of triples: start-offset (inclusive), end-offset (exclusive), line-number. diff --git a/Objects/longobject.c b/Objects/longobject.c index 5fca55e5c3a2be..e73de742229005 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -10,10 +10,8 @@ #include "pycore_runtime.h" // _PY_NSMALLPOSINTS #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() -#include -#include -#include -#include // abs() +#include // DBL_MANT_DIG +#include // offsetof #include "clinic/longobject.c.h" /*[clinic input] @@ -163,6 +161,9 @@ _PyLong_New(Py_ssize_t size) } _PyLong_SetSignAndDigitCount(result, size != 0, size); _PyObject_Init((PyObject*)result, &PyLong_Type); + /* The digit has to be initialized explicitly to avoid + * use-of-uninitialized-value. */ + result->long_value.ob_digit[0] = 0; return result; } @@ -171,7 +172,7 @@ _PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits) { assert(digit_count >= 0); if (digit_count == 0) { - return (PyLongObject *)Py_NewRef(_PyLong_GetZero()); + return (PyLongObject *)_PyLong_GetZero(); } PyLongObject *result = _PyLong_New(digit_count); if (result == NULL) { @@ -546,7 +547,7 @@ PyLong_AsLong(PyObject *obj) method. Return -1 and set an error if overflow occurs. */ int -_PyLong_AsInt(PyObject *obj) +PyLong_AsInt(PyObject *obj) { int overflow; long result = PyLong_AsLongAndOverflow(obj, &overflow); @@ -2854,8 +2855,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, if (*prem == NULL) { return -1; } - PyObject *zero = _PyLong_GetZero(); - *pdiv = (PyLongObject*)Py_NewRef(zero); + *pdiv = (PyLongObject*)_PyLong_GetZero(); return 0; } if (size_b == 1) { diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index b0168044d9f85a..bcdd2ff0ceafe6 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -12,6 +12,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_memoryobject.h" // _PyManagedBuffer_Type #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_strhex.h" // _Py_strhex_with_sep() #include // offsetof() diff --git a/Objects/methodobject.c b/Objects/methodobject.c index fe081992d51fda..b40b2821c3880d 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -7,7 +7,7 @@ #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() -#include "structmember.h" // PyMemberDef + /* undefine macro trampoline to PyCFunction_NewEx */ #undef PyCFunction_New @@ -192,7 +192,9 @@ static PyMethodDef meth_methods[] = { static PyObject * meth_get__text_signature__(PyCFunctionObject *m, void *closure) { - return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); + return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, + m->m_ml->ml_doc, + m->m_ml->ml_flags); } static PyObject * @@ -273,7 +275,7 @@ static PyGetSetDef meth_getsets [] = { #define OFF(x) offsetof(PyCFunctionObject, x) static PyMemberDef meth_members[] = { - {"__module__", T_OBJECT, OFF(m_module), 0}, + {"__module__", _Py_T_OBJECT, OFF(m_module), 0}, {NULL} }; @@ -551,10 +553,3 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) return _Py_CheckFunctionResult(tstate, func, result, NULL); } -#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) -#include - -EM_JS(PyObject*, _PyCFunctionWithKeywords_TrampolineCall, (PyCFunctionWithKeywords func, PyObject *self, PyObject *args, PyObject *kw), { - return wasmTable.get(func)(self, args, kw); -}); -#endif diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index ba20534c3bdd8d..5b9f74dbddf031 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -9,11 +9,11 @@ #include "pycore_object.h" // _PyType_AllocNoTrack #include "pycore_pyerrors.h" // _PyErr_FormatFromCause() #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "structmember.h" // PyMemberDef + static PyMemberDef module_members[] = { - {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, + {"__dict__", _Py_T_OBJECT, offsetof(PyModuleObject, md_dict), Py_READONLY}, {0} }; @@ -510,25 +510,31 @@ PyModule_GetDict(PyObject *m) } PyObject* -PyModule_GetNameObject(PyObject *m) +PyModule_GetNameObject(PyObject *mod) { - PyObject *d; - PyObject *name; - if (!PyModule_Check(m)) { + if (!PyModule_Check(mod)) { PyErr_BadArgument(); return NULL; } - d = ((PyModuleObject *)m)->md_dict; - if (d == NULL || !PyDict_Check(d) || - (name = PyDict_GetItemWithError(d, &_Py_ID(__name__))) == NULL || - !PyUnicode_Check(name)) - { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_SystemError, "nameless module"); - } - return NULL; + PyObject *dict = ((PyModuleObject *)mod)->md_dict; // borrowed reference + if (dict == NULL || !PyDict_Check(dict)) { + goto error; + } + PyObject *name; + if (PyDict_GetItemRef(dict, &_Py_ID(__name__), &name) <= 0) { + goto error; + } + if (!PyUnicode_Check(name)) { + Py_DECREF(name); + goto error; } - return Py_NewRef(name); + return name; + +error: + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_SystemError, "nameless module"); + } + return NULL; } const char * @@ -544,25 +550,31 @@ PyModule_GetName(PyObject *m) } PyObject* -PyModule_GetFilenameObject(PyObject *m) +PyModule_GetFilenameObject(PyObject *mod) { - PyObject *d; - PyObject *fileobj; - if (!PyModule_Check(m)) { + if (!PyModule_Check(mod)) { PyErr_BadArgument(); return NULL; } - d = ((PyModuleObject *)m)->md_dict; - if (d == NULL || - (fileobj = PyDict_GetItemWithError(d, &_Py_ID(__file__))) == NULL || - !PyUnicode_Check(fileobj)) - { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_SystemError, "module filename missing"); - } - return NULL; + PyObject *dict = ((PyModuleObject *)mod)->md_dict; // borrowed reference + if (dict == NULL) { + goto error; + } + PyObject *fileobj; + if (PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj) <= 0) { + goto error; + } + if (!PyUnicode_Check(fileobj)) { + Py_DECREF(fileobj); + goto error; } - return Py_NewRef(fileobj); + return fileobj; + +error: + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_SystemError, "module filename missing"); + } + return NULL; } const char * diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index 2cc4ddd3c91daa..204c114fd9de2d 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -2,7 +2,9 @@ #include "Python.h" #include "pycore_namespace.h" // _PyNamespace_Type -#include "structmember.h" // PyMemberDef + +#include // offsetof() + typedef struct { @@ -12,7 +14,7 @@ typedef struct { static PyMemberDef namespace_members[] = { - {"__dict__", T_OBJECT, offsetof(_PyNamespaceObject, ns_dict), READONLY}, + {"__dict__", _Py_T_OBJECT, offsetof(_PyNamespaceObject, ns_dict), Py_READONLY}, {NULL} }; @@ -187,9 +189,37 @@ namespace_reduce(_PyNamespaceObject *ns, PyObject *Py_UNUSED(ignored)) } +static PyObject * +namespace_replace(PyObject *self, PyObject *args, PyObject *kwargs) +{ + if (!_PyArg_NoPositional("__replace__", args)) { + return NULL; + } + + PyObject *result = PyObject_CallNoArgs((PyObject *)Py_TYPE(self)); + if (!result) { + return NULL; + } + if (PyDict_Update(((_PyNamespaceObject*)result)->ns_dict, + ((_PyNamespaceObject*)self)->ns_dict) < 0) + { + Py_DECREF(result); + return NULL; + } + if (kwargs) { + if (PyDict_Update(((_PyNamespaceObject*)result)->ns_dict, kwargs) < 0) { + Py_DECREF(result); + return NULL; + } + } + return result; +} + + static PyMethodDef namespace_methods[] = { {"__reduce__", (PyCFunction)namespace_reduce, METH_NOARGS, namespace_reduce__doc__}, + {"__replace__", _PyCFunction_CAST(namespace_replace), METH_VARARGS|METH_KEYWORDS, NULL}, {NULL, NULL} // sentinel }; diff --git a/Objects/object.c b/Objects/object.c index d30e048335ab63..3ed272afdced7c 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -5,18 +5,22 @@ #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_context.h" // _PyContextTokenMissing_Type +#include "pycore_descrobject.h" // _PyMethodWrapper_Type #include "pycore_dict.h" // _PyObject_MakeDictFromInstanceAttributes() #include "pycore_floatobject.h" // _PyFloat_DebugMallocStats() #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() +#include "pycore_hashtable.h" // _Py_hashtable_new() +#include "pycore_memoryobject.h" // _PyManagedBuffer_Type #include "pycore_namespace.h" // _PyNamespace_Type -#include "pycore_object.h" // _PyType_CheckConsistency(), _Py_FatalRefcountError() +#include "pycore_object.h" // PyAPI_DATA() _Py_SwappedOp definition #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntry_Type -#include "pycore_typevarobject.h" // _PyTypeAlias_Type, _Py_initialize_generic #include "pycore_typeobject.h" // _PyBufferWrapper_Type +#include "pycore_typevarobject.h" // _PyTypeAlias_Type, _Py_initialize_generic #include "pycore_unionobject.h" // _PyUnion_Type + #include "interpreteridobject.h" // _PyInterpreterID_Type #ifdef Py_LIMITED_API @@ -24,10 +28,6 @@ # error "Py_LIMITED_API macro must not be defined" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Defined in tracemalloc.c */ extern void _PyMem_DumpTraceback(int fd, const void *ptr); @@ -158,39 +158,52 @@ _PyDebug_PrintTotalRefs(void) { Do not call them otherwise, they do not initialize the object! */ #ifdef Py_TRACE_REFS -/* Head of circular doubly-linked list of all objects. These are linked - * together via the _ob_prev and _ob_next members of a PyObject, which - * exist only in a Py_TRACE_REFS build. - */ -static PyObject refchain = {&refchain, &refchain}; - -/* Insert op at the front of the list of all objects. If force is true, - * op is added even if _ob_prev and _ob_next are non-NULL already. If - * force is false amd _ob_prev or _ob_next are non-NULL, do nothing. - * force should be true if and only if op points to freshly allocated, - * uninitialized memory, or you've unlinked op from the list and are - * relinking it into the front. - * Note that objects are normally added to the list via _Py_NewReference, - * which is called by PyObject_Init. Not all objects are initialized that - * way, though; exceptions include statically allocated type objects, and - * statically allocated singletons (like Py_True and Py_None). - */ -void -_Py_AddToAllObjects(PyObject *op, int force) + +#define REFCHAIN(interp) interp->object_state.refchain +#define REFCHAIN_VALUE ((void*)(uintptr_t)1) + +bool +_PyRefchain_IsTraced(PyInterpreterState *interp, PyObject *obj) { -#ifdef Py_DEBUG - if (!force) { - /* If it's initialized memory, op must be in or out of - * the list unambiguously. - */ - _PyObject_ASSERT(op, (op->_ob_prev == NULL) == (op->_ob_next == NULL)); + return (_Py_hashtable_get(REFCHAIN(interp), obj) == REFCHAIN_VALUE); +} + + +static void +_PyRefchain_Trace(PyInterpreterState *interp, PyObject *obj) +{ + if (_Py_hashtable_set(REFCHAIN(interp), obj, REFCHAIN_VALUE) < 0) { + // Use a fatal error because _Py_NewReference() cannot report + // the error to the caller. + Py_FatalError("_Py_hashtable_set() memory allocation failed"); } +} + + +static void +_PyRefchain_Remove(PyInterpreterState *interp, PyObject *obj) +{ + void *value = _Py_hashtable_steal(REFCHAIN(interp), obj); +#ifndef NDEBUG + assert(value == REFCHAIN_VALUE); +#else + (void)value; #endif - if (force || op->_ob_prev == NULL) { - op->_ob_next = refchain._ob_next; - op->_ob_prev = &refchain; - refchain._ob_next->_ob_prev = op; - refchain._ob_next = op; +} + + +/* Add an object to the refchain hash table. + * + * Note that objects are normally added to the list by PyObject_Init() + * indirectly. Not all objects are initialized that way, though; exceptions + * include statically allocated type objects, and statically allocated + * singletons (like Py_True and Py_None). */ +void +_Py_AddToAllObjects(PyObject *op) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!_PyRefchain_IsTraced(interp, op)) { + _PyRefchain_Trace(interp, op); } } #endif /* Py_TRACE_REFS */ @@ -206,14 +219,14 @@ _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op) /* This is used strictly by Py_INCREF(). */ void -_Py_IncRefTotal_DO_NOT_USE_THIS(void) +_Py_INCREF_IncRefTotal(void) { reftotal_increment(_PyInterpreterState_GET()); } /* This is used strictly by Py_DECREF(). */ void -_Py_DecRefTotal_DO_NOT_USE_THIS(void) +_Py_DECREF_DecRefTotal(void) { reftotal_decrement(_PyInterpreterState_GET()); } @@ -462,16 +475,6 @@ _PyObject_IsFreed(PyObject *op) if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(Py_TYPE(op))) { return 1; } - /* ignore op->ob_ref: its value can have be modified - by Py_INCREF() and Py_DECREF(). */ -#ifdef Py_TRACE_REFS - if (op->_ob_next != NULL && _PyMem_IsPtrFreed(op->_ob_next)) { - return 1; - } - if (op->_ob_prev != NULL && _PyMem_IsPtrFreed(op->_ob_prev)) { - return 1; - } -#endif return 0; } @@ -904,26 +907,24 @@ PyObject_GetAttrString(PyObject *v, const char *name) } int -PyObject_HasAttrString(PyObject *v, const char *name) +PyObject_HasAttrStringWithError(PyObject *obj, const char *name) { - if (Py_TYPE(v)->tp_getattr != NULL) { - PyObject *res = (*Py_TYPE(v)->tp_getattr)(v, (char*)name); - if (res != NULL) { - Py_DECREF(res); - return 1; - } - PyErr_Clear(); - return 0; - } + PyObject *res; + int rc = PyObject_GetOptionalAttrString(obj, name, &res); + Py_XDECREF(res); + return rc; +} + - PyObject *attr_name = PyUnicode_FromString(name); - if (attr_name == NULL) { +int +PyObject_HasAttrString(PyObject *obj, const char *name) +{ + int rc = PyObject_HasAttrStringWithError(obj, name); + if (rc < 0) { PyErr_Clear(); return 0; } - int ok = PyObject_HasAttr(v, attr_name); - Py_DECREF(attr_name); - return ok; + return rc; } int @@ -1142,18 +1143,23 @@ PyObject_GetOptionalAttrString(PyObject *obj, const char *name, PyObject **resul } int -PyObject_HasAttr(PyObject *v, PyObject *name) +PyObject_HasAttrWithError(PyObject *obj, PyObject *name) { PyObject *res; - if (PyObject_GetOptionalAttr(v, name, &res) < 0) { + int rc = PyObject_GetOptionalAttr(obj, name, &res); + Py_XDECREF(res); + return rc; +} + +int +PyObject_HasAttr(PyObject *obj, PyObject *name) +{ + int rc = PyObject_HasAttrWithError(obj, name); + if (rc < 0) { PyErr_Clear(); return 0; } - if (res == NULL) { - return 0; - } - Py_DECREF(res); - return 1; + return rc; } int @@ -1570,15 +1576,32 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, goto error_check; } dictptr = &dorv_ptr->dict; + if (*dictptr == NULL) { + if (_PyObject_InitInlineValues(obj, tp) < 0) { + goto done; + } + res = _PyObject_StoreInstanceAttribute( + obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value); + goto error_check; + } } else { dictptr = _PyObject_ComputedDictPointer(obj); } if (dictptr == NULL) { if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute '%U'", - tp->tp_name, name); + if (tp->tp_setattro == PyObject_GenericSetAttr) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U' and no " + "__dict__ for setting new attributes", + tp->tp_name, name); + } + else { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); + } + set_attribute_error_context(obj, name); } else { PyErr_Format(PyExc_AttributeError, @@ -1611,6 +1634,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, "'%.100s' object has no attribute '%U'", tp->tp_name, name); } + set_attribute_error_context(obj, name); } done: Py_XDECREF(descr); @@ -1902,7 +1926,6 @@ PyTypeObject _PyNone_Type = { }; PyObject _Py_NoneStruct = { - _PyObject_EXTRA_INIT { _Py_IMMORTAL_REFCNT }, &_PyNone_Type }; @@ -2005,16 +2028,47 @@ PyTypeObject _PyNotImplemented_Type = { }; PyObject _Py_NotImplementedStruct = { - _PyObject_EXTRA_INIT { _Py_IMMORTAL_REFCNT }, &_PyNotImplemented_Type }; -extern PyTypeObject _Py_GenericAliasIterType; -extern PyTypeObject _PyMemoryIter_Type; + +PyStatus +_PyObject_InitState(PyInterpreterState *interp) +{ +#ifdef Py_TRACE_REFS + _Py_hashtable_allocator_t alloc = { + // Don't use default PyMem_Malloc() and PyMem_Free() which + // require the caller to hold the GIL. + .malloc = PyMem_RawMalloc, + .free = PyMem_RawFree, + }; + REFCHAIN(interp) = _Py_hashtable_new_full( + _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct, + NULL, NULL, &alloc); + if (REFCHAIN(interp) == NULL) { + return _PyStatus_NO_MEMORY(); + } +#endif + return _PyStatus_OK(); +} + +void +_PyObject_FiniState(PyInterpreterState *interp) +{ +#ifdef Py_TRACE_REFS + _Py_hashtable_destroy(REFCHAIN(interp)); + REFCHAIN(interp) = NULL; +#endif +} + + +extern PyTypeObject _PyAnextAwaitable_Type; +extern PyTypeObject _PyLegacyEventHandler_Type; extern PyTypeObject _PyLineIterator; +extern PyTypeObject _PyMemoryIter_Type; extern PyTypeObject _PyPositionsIterator; -extern PyTypeObject _PyLegacyEventHandler_Type; +extern PyTypeObject _Py_GenericAliasIterType; static PyTypeObject* static_types[] = { // The two most important base types: must be initialized first and @@ -2061,6 +2115,7 @@ static PyTypeObject* static_types[] = { &PyGen_Type, &PyGetSetDescr_Type, &PyInstanceMethod_Type, + &PyInterpreterID_Type, &PyListIter_Type, &PyListRevIter_Type, &PyList_Type, @@ -2111,7 +2166,6 @@ static PyTypeObject* static_types[] = { &_PyHamt_CollisionNode_Type, &_PyHamt_Type, &_PyLegacyEventHandler_Type, - &_PyInterpreterID_Type, &_PyLineIterator, &_PyManagedBuffer_Type, &_PyMemoryIter_Type, @@ -2190,7 +2244,7 @@ new_reference(PyObject *op) // Skip the immortal object check in Py_SET_REFCNT; always set refcnt to 1 op->ob_refcnt = 1; #ifdef Py_TRACE_REFS - _Py_AddToAllObjects(op, 1); + _Py_AddToAllObjects(op); #endif } @@ -2218,91 +2272,164 @@ _Py_ForgetReference(PyObject *op) _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt"); } - if (op == &refchain || - op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) - { - _PyObject_ASSERT_FAILED_MSG(op, "invalid object chain"); - } + PyInterpreterState *interp = _PyInterpreterState_GET(); #ifdef SLOW_UNREF_CHECK - PyObject *p; - for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) { - if (p == op) { - break; - } - } - if (p == &refchain) { + if (!_PyRefchain_Get(interp, op)) { /* Not found */ _PyObject_ASSERT_FAILED_MSG(op, "object not found in the objects list"); } #endif - op->_ob_next->_ob_prev = op->_ob_prev; - op->_ob_prev->_ob_next = op->_ob_next; - op->_ob_next = op->_ob_prev = NULL; + _PyRefchain_Remove(interp, op); } +static int +_Py_PrintReference(_Py_hashtable_t *ht, + const void *key, const void *value, + void *user_data) +{ + PyObject *op = (PyObject*)key; + FILE *fp = (FILE *)user_data; + fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op)); + if (PyObject_Print(op, fp, 0) != 0) { + PyErr_Clear(); + } + putc('\n', fp); + return 0; +} + + /* Print all live objects. Because PyObject_Print is called, the * interpreter must be in a healthy state. */ void -_Py_PrintReferences(FILE *fp) +_Py_PrintReferences(PyInterpreterState *interp, FILE *fp) { - PyObject *op; - fprintf(fp, "Remaining objects:\n"); - for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { - fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op)); - if (PyObject_Print(op, fp, 0) != 0) { - PyErr_Clear(); - } - putc('\n', fp); + if (interp == NULL) { + interp = _PyInterpreterState_Main(); } + fprintf(fp, "Remaining objects:\n"); + _Py_hashtable_foreach(REFCHAIN(interp), _Py_PrintReference, fp); } + +static int +_Py_PrintReferenceAddress(_Py_hashtable_t *ht, + const void *key, const void *value, + void *user_data) +{ + PyObject *op = (PyObject*)key; + FILE *fp = (FILE *)user_data; + fprintf(fp, "%p [%zd] %s\n", + (void *)op, Py_REFCNT(op), Py_TYPE(op)->tp_name); + return 0; +} + + /* Print the addresses of all live objects. Unlike _Py_PrintReferences, this * doesn't make any calls to the Python C API, so is always safe to call. */ +// XXX This function is not safe to use if the interpreter has been +// freed or is in an unhealthy state (e.g. late in finalization). +// The call in Py_FinalizeEx() is okay since the main interpreter +// is statically allocated. void -_Py_PrintReferenceAddresses(FILE *fp) +_Py_PrintReferenceAddresses(PyInterpreterState *interp, FILE *fp) { - PyObject *op; fprintf(fp, "Remaining object addresses:\n"); - for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) - fprintf(fp, "%p [%zd] %s\n", (void *)op, - Py_REFCNT(op), Py_TYPE(op)->tp_name); + _Py_hashtable_foreach(REFCHAIN(interp), _Py_PrintReferenceAddress, fp); +} + + +typedef struct { + PyObject *self; + PyObject *args; + PyObject *list; + PyObject *type; + Py_ssize_t limit; +} _Py_GetObjectsData; + +enum { + _PY_GETOBJECTS_IGNORE = 0, + _PY_GETOBJECTS_ERROR = 1, + _PY_GETOBJECTS_STOP = 2, +}; + +static int +_Py_GetObject(_Py_hashtable_t *ht, + const void *key, const void *value, + void *user_data) +{ + PyObject *op = (PyObject *)key; + _Py_GetObjectsData *data = user_data; + if (data->limit > 0) { + if (PyList_GET_SIZE(data->list) >= data->limit) { + return _PY_GETOBJECTS_STOP; + } + } + + if (op == data->self) { + return _PY_GETOBJECTS_IGNORE; + } + if (op == data->args) { + return _PY_GETOBJECTS_IGNORE; + } + if (op == data->list) { + return _PY_GETOBJECTS_IGNORE; + } + if (data->type != NULL) { + if (op == data->type) { + return _PY_GETOBJECTS_IGNORE; + } + if (!Py_IS_TYPE(op, (PyTypeObject *)data->type)) { + return _PY_GETOBJECTS_IGNORE; + } + } + + if (PyList_Append(data->list, op) < 0) { + return _PY_GETOBJECTS_ERROR; + } + return 0; } + +/* The implementation of sys.getobjects(). */ PyObject * _Py_GetObjects(PyObject *self, PyObject *args) { - int i, n; - PyObject *t = NULL; - PyObject *res, *op; + Py_ssize_t limit; + PyObject *type = NULL; + if (!PyArg_ParseTuple(args, "n|O", &limit, &type)) { + return NULL; + } - if (!PyArg_ParseTuple(args, "i|O", &n, &t)) + PyObject *list = PyList_New(0); + if (list == NULL) { return NULL; - op = refchain._ob_next; - res = PyList_New(0); - if (res == NULL) + } + + _Py_GetObjectsData data = { + .self = self, + .args = args, + .list = list, + .type = type, + .limit = limit, + }; + PyInterpreterState *interp = _PyInterpreterState_GET(); + int res = _Py_hashtable_foreach(REFCHAIN(interp), _Py_GetObject, &data); + if (res == _PY_GETOBJECTS_ERROR) { + Py_DECREF(list); return NULL; - for (i = 0; (n == 0 || i < n) && op != &refchain; i++) { - while (op == self || op == args || op == res || op == t || - (t != NULL && !Py_IS_TYPE(op, (PyTypeObject *) t))) { - op = op->_ob_next; - if (op == &refchain) - return res; - } - if (PyList_Append(res, op) < 0) { - Py_DECREF(res); - return NULL; - } - op = op->_ob_next; } - return res; + return list; } -#endif +#undef REFCHAIN +#undef REFCHAIN_VALUE + +#endif /* Py_TRACE_REFS */ /* Hack to force loading of abstract.o */ @@ -2677,7 +2804,3 @@ int Py_IsFalse(PyObject *x) { return Py_Is(x, Py_False); } - -#ifdef __cplusplus -} -#endif diff --git a/Objects/object_layout.md b/Objects/object_layout.md index 4430790f4f0f36..3f7d72eb22f224 100644 --- a/Objects/object_layout.md +++ b/Objects/object_layout.md @@ -36,7 +36,7 @@ and the ``dict`` field points to the dictionary. ## 3.12 pre-header -In 3.12 the the pointer to the list of weak references is added to the +In 3.12 the pointer to the list of weak references is added to the pre-header. In order to make space for it, the ``dict`` and ``values`` pointers are combined into a single tagged pointer: diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index eb68d7c030d293..7d552ff57c8f1e 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_code.h" // stats +#include "pycore_object.h" // _PyDebugAllocatorStats() definition #include "pycore_obmalloc.h" #include "pycore_pyerrors.h" // _Py_FatalErrorFormat() #include "pycore_pymem.h" diff --git a/Objects/odictobject.c b/Objects/odictobject.c index e76d2ded61cf74..b99896319e0136 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -466,8 +466,10 @@ Potential Optimizations #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_dict.h" // _Py_dict_lookup() +#include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include // offsetof() #include "clinic/odictobject.c.h" diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 6dc41d71287cab..ce9eef69ad75a8 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -2,11 +2,12 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_range.h" #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "structmember.h" // PyMemberDef + /* Support objects whose length is > PY_SSIZE_T_MAX. @@ -106,8 +107,8 @@ range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args) if (!stop) { return NULL; } - start = Py_NewRef(_PyLong_GetZero()); - step = Py_NewRef(_PyLong_GetOne()); + start = _PyLong_GetZero(); + step = _PyLong_GetOne(); break; case 0: PyErr_SetString(PyExc_TypeError, @@ -757,9 +758,9 @@ static PyMethodDef range_methods[] = { }; static PyMemberDef range_members[] = { - {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY}, - {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY}, - {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY}, + {"start", Py_T_OBJECT_EX, offsetof(rangeobject, start), Py_READONLY}, + {"stop", Py_T_OBJECT_EX, offsetof(rangeobject, stop), Py_READONLY}, + {"step", Py_T_OBJECT_EX, offsetof(rangeobject, step), Py_READONLY}, {0} }; diff --git a/Objects/setobject.c b/Objects/setobject.c index 4ac541b9509752..2a3514f2028c3d 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -32,8 +32,12 @@ */ #include "Python.h" +#include "pycore_ceval.h" // _PyEval_GetBuiltin() +#include "pycore_dict.h" // _PyDict_Contains_KnownHash() #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pyerrors.h" // _PyErr_SetKeyError() +#include "pycore_setobject.h" // _PySet_NextEntry() definition #include // offsetof() /* Object used as dummy key to fill deleted entries */ @@ -2018,13 +2022,6 @@ static PySequenceMethods set_as_sequence = { /* set object ********************************************************/ -#ifdef Py_DEBUG -static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored)); - -PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\ -All is well if assertions don't fail."); -#endif - static PyMethodDef set_methods[] = { {"add", (PyCFunction)set_add, METH_O, add_doc}, @@ -2062,10 +2059,6 @@ static PyMethodDef set_methods[] = { symmetric_difference_doc}, {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O, symmetric_difference_update_doc}, -#ifdef Py_DEBUG - {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS, - test_c_api_doc}, -#endif {"union", (PyCFunction)set_union, METH_VARARGS, union_doc}, {"update", (PyCFunction)set_update, METH_VARARGS, @@ -2364,148 +2357,6 @@ _PySet_Update(PyObject *set, PyObject *iterable) /* Exported for the gdb plugin's benefit. */ PyObject *_PySet_Dummy = dummy; -#ifdef Py_DEBUG - -/* Test code to be called with any three element set. - Returns True and original set is restored. */ - -#define assertRaises(call_return_value, exception) \ - do { \ - assert(call_return_value); \ - assert(PyErr_ExceptionMatches(exception)); \ - PyErr_Clear(); \ - } while(0) - -static PyObject * -test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored)) -{ - Py_ssize_t count; - const char *s; - Py_ssize_t i; - PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL; - PyObject *ob = (PyObject *)so; - Py_hash_t hash; - PyObject *str; - - /* Verify preconditions */ - assert(PyAnySet_Check(ob)); - assert(PyAnySet_CheckExact(ob)); - assert(!PyFrozenSet_CheckExact(ob)); - - /* so.clear(); so |= set("abc"); */ - str = PyUnicode_FromString("abc"); - if (str == NULL) - return NULL; - set_clear_internal(so); - if (set_update_internal(so, str)) { - Py_DECREF(str); - return NULL; - } - Py_DECREF(str); - - /* Exercise type/size checks */ - assert(PySet_Size(ob) == 3); - assert(PySet_GET_SIZE(ob) == 3); - - /* Raise TypeError for non-iterable constructor arguments */ - assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError); - assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError); - - /* Raise TypeError for unhashable key */ - dup = PySet_New(ob); - assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError); - assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError); - assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError); - - /* Exercise successful pop, contains, add, and discard */ - elem = PySet_Pop(ob); - assert(PySet_Contains(ob, elem) == 0); - assert(PySet_GET_SIZE(ob) == 2); - assert(PySet_Add(ob, elem) == 0); - assert(PySet_Contains(ob, elem) == 1); - assert(PySet_GET_SIZE(ob) == 3); - assert(PySet_Discard(ob, elem) == 1); - assert(PySet_GET_SIZE(ob) == 2); - assert(PySet_Discard(ob, elem) == 0); - assert(PySet_GET_SIZE(ob) == 2); - - /* Exercise clear */ - dup2 = PySet_New(dup); - assert(PySet_Clear(dup2) == 0); - assert(PySet_Size(dup2) == 0); - Py_DECREF(dup2); - - /* Raise SystemError on clear or update of frozen set */ - f = PyFrozenSet_New(dup); - assertRaises(PySet_Clear(f) == -1, PyExc_SystemError); - assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError); - assert(PySet_Add(f, elem) == 0); - Py_INCREF(f); - assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError); - Py_DECREF(f); - Py_DECREF(f); - - /* Exercise direct iteration */ - i = 0, count = 0; - while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) { - s = PyUnicode_AsUTF8(x); - assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c')); - count++; - } - assert(count == 3); - - /* Exercise updates */ - dup2 = PySet_New(NULL); - assert(_PySet_Update(dup2, dup) == 0); - assert(PySet_Size(dup2) == 3); - assert(_PySet_Update(dup2, dup) == 0); - assert(PySet_Size(dup2) == 3); - Py_DECREF(dup2); - - /* Raise SystemError when self argument is not a set or frozenset. */ - t = PyTuple_New(0); - assertRaises(PySet_Size(t) == -1, PyExc_SystemError); - assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError); - Py_DECREF(t); - - /* Raise SystemError when self argument is not a set. */ - f = PyFrozenSet_New(dup); - assert(PySet_Size(f) == 3); - assert(PyFrozenSet_CheckExact(f)); - assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError); - assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError); - Py_DECREF(f); - - /* Raise KeyError when popping from an empty set */ - assert(PyNumber_InPlaceSubtract(ob, ob) == ob); - Py_DECREF(ob); - assert(PySet_GET_SIZE(ob) == 0); - assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError); - - /* Restore the set from the copy using the PyNumber API */ - assert(PyNumber_InPlaceOr(ob, dup) == ob); - Py_DECREF(ob); - - /* Verify constructors accept NULL arguments */ - f = PySet_New(NULL); - assert(f != NULL); - assert(PySet_GET_SIZE(f) == 0); - Py_DECREF(f); - f = PyFrozenSet_New(NULL); - assert(f != NULL); - assert(PyFrozenSet_CheckExact(f)); - assert(PySet_GET_SIZE(f) == 0); - Py_DECREF(f); - - Py_DECREF(elem); - Py_DECREF(dup); - Py_RETURN_TRUE; -} - -#undef assertRaises - -#endif - /***** Dummy Struct *************************************************/ static PyObject * @@ -2544,7 +2395,6 @@ static PyTypeObject _PySetDummy_Type = { }; static PyObject _dummy_struct = { - _PyObject_EXTRA_INIT { _Py_IMMORTAL_REFCNT }, &_PySetDummy_Type }; diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 5a33977f064421..5ffc52ae674c82 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -17,7 +17,7 @@ this type and there is exactly one in existence. #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_object.h" // _PyObject_GC_TRACK() -#include "structmember.h" // PyMemberDef + static PyObject * ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) @@ -98,7 +98,6 @@ PyTypeObject PyEllipsis_Type = { }; PyObject _Py_EllipsisObject = { - _PyObject_EXTRA_INIT { _Py_IMMORTAL_REFCNT }, &PyEllipsis_Type }; @@ -377,9 +376,9 @@ slice_repr(PySliceObject *r) } static PyMemberDef slice_members[] = { - {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, - {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, - {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY}, + {"start", _Py_T_OBJECT, offsetof(PySliceObject, start), Py_READONLY}, + {"stop", _Py_T_OBJECT, offsetof(PySliceObject, stop), Py_READONLY}, + {"step", _Py_T_OBJECT, offsetof(PySliceObject, step), Py_READONLY}, {0} }; @@ -415,7 +414,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, /* Convert step to an integer; raise for zero step. */ if (self->step == Py_None) { - step = Py_NewRef(_PyLong_GetOne()); + step = _PyLong_GetOne(); step_is_negative = 0; } else { @@ -443,7 +442,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, goto error; } else { - lower = Py_NewRef(_PyLong_GetZero()); + lower = _PyLong_GetZero(); upper = Py_NewRef(length); } diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h index 49388cf043ced2..e81c5916e6f196 100644 --- a/Objects/stringlib/clinic/transmogrify.h.h +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(stringlib_expandtabs__doc__, "expandtabs($self, /, tabsize=8)\n" @@ -62,7 +62,7 @@ stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py if (!noptargs) { goto skip_optional_pos; } - tabsize = _PyLong_AsInt(args[0]); + tabsize = PyLong_AsInt(args[0]); if (tabsize == -1 && PyErr_Occurred()) { goto exit; } @@ -278,4 +278,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=d44a269805f6739e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39cd1ee983137188 input=a9049054013a1b77]*/ diff --git a/Objects/structseq.c b/Objects/structseq.c index 49011139b66534..e4a4b45a8db626 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -8,9 +8,10 @@ */ #include "Python.h" +#include "pycore_dict.h" // _PyDict_Pop() #include "pycore_tuple.h" // _PyTuple_FromArray() #include "pycore_object.h" // _PyObject_GC_TRACK() -#include "structmember.h" // PyMemberDef + #include "pycore_structseq.h" // PyStructSequence_InitType() #include "pycore_initconfig.h" // _PyStatus_OK() @@ -148,7 +149,6 @@ static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) /*[clinic end generated code: output=baa082e788b171da input=90532511101aa3fb]*/ { - PyObject *ob; PyStructSequence *res = NULL; Py_ssize_t len, min_len, max_len, i, n_unnamed_fields; @@ -217,22 +217,34 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) res->ob_item[i] = Py_NewRef(v); } Py_DECREF(arg); - for (; i < max_len; ++i) { - if (dict == NULL) { - ob = Py_None; - } - else { - ob = _PyDict_GetItemStringWithError(dict, - type->tp_members[i-n_unnamed_fields].name); + if (dict != NULL && PyDict_GET_SIZE(dict) > 0) { + Py_ssize_t n_found_keys = 0; + for (i = len; i < max_len; ++i) { + PyObject *ob = NULL; + const char *name = type->tp_members[i - n_unnamed_fields].name; + if (PyDict_GetItemStringRef(dict, name, &ob) < 0) { + Py_DECREF(res); + return NULL; + } if (ob == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(res); - return NULL; - } - ob = Py_None; + ob = Py_NewRef(Py_None); } + else { + ++n_found_keys; + } + res->ob_item[i] = ob; + } + if (PyDict_GET_SIZE(dict) > n_found_keys) { + PyErr_Format(PyExc_TypeError, + "%.500s() got duplicate or unexpected field name(s)", + type->tp_name); + Py_DECREF(res); + return NULL; + } + } else { + for (i = len; i < max_len; ++i) { + res->ob_item[i] = Py_NewRef(Py_None); } - res->ob_item[i] = Py_NewRef(ob); } _PyObject_GC_TRACK(res); @@ -369,9 +381,82 @@ structseq_reduce(PyStructSequence* self, PyObject *Py_UNUSED(ignored)) return NULL; } + +static PyObject * +structseq_replace(PyStructSequence *self, PyObject *args, PyObject *kwargs) +{ + PyStructSequence *result = NULL; + Py_ssize_t n_fields, n_unnamed_fields, i; + + if (!_PyArg_NoPositional("__replace__", args)) { + return NULL; + } + + n_fields = REAL_SIZE(self); + if (n_fields < 0) { + return NULL; + } + n_unnamed_fields = UNNAMED_FIELDS(self); + if (n_unnamed_fields < 0) { + return NULL; + } + if (n_unnamed_fields > 0) { + PyErr_Format(PyExc_TypeError, + "__replace__() is not supported for %.500s " + "because it has unnamed field(s)", + Py_TYPE(self)->tp_name); + return NULL; + } + + result = (PyStructSequence *) PyStructSequence_New(Py_TYPE(self)); + if (!result) { + return NULL; + } + + if (kwargs != NULL) { + // We do not support types with unnamed fields, so we can iterate over + // i >= n_visible_fields case without slicing with (i - n_unnamed_fields). + for (i = 0; i < n_fields; ++i) { + PyObject *key = PyUnicode_FromString(Py_TYPE(self)->tp_members[i].name); + if (!key) { + goto error; + } + PyObject *ob = _PyDict_Pop(kwargs, key, self->ob_item[i]); + Py_DECREF(key); + if (!ob) { + goto error; + } + result->ob_item[i] = ob; + } + // Check if there are any unexpected fields. + if (PyDict_GET_SIZE(kwargs) > 0) { + PyObject *names = PyDict_Keys(kwargs); + if (names) { + PyErr_Format(PyExc_TypeError, "Got unexpected field name(s): %R", names); + Py_DECREF(names); + } + goto error; + } + } + else + { + // Just create a copy of the original. + for (i = 0; i < n_fields; ++i) { + result->ob_item[i] = Py_NewRef(self->ob_item[i]); + } + } + + return (PyObject *)result; + +error: + Py_DECREF(result); + return NULL; +} + static PyMethodDef structseq_methods[] = { {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL}, - {NULL, NULL} + {"__replace__", _PyCFunction_CAST(structseq_replace), METH_VARARGS | METH_KEYWORDS, NULL}, + {NULL, NULL} // sentinel }; static Py_ssize_t @@ -465,10 +550,10 @@ initialize_members(PyStructSequence_Desc *desc, /* The names and docstrings in these MemberDefs are statically */ /* allocated so it is expected that they'll outlive the MemberDef */ members[k].name = desc->fields[i].name; - members[k].type = T_OBJECT; + members[k].type = _Py_T_OBJECT; members[k].offset = offsetof(PyStructSequence, ob_item) + i * sizeof(PyObject*); - members[k].flags = READONLY; + members[k].flags = Py_READONLY; members[k].doc = desc->fields[i].doc; k++; } @@ -577,9 +662,10 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) Py_ssize_t n_members, n_unnamed_members; #ifdef Py_TRACE_REFS - /* if the type object was chained, unchain it first + /* if the type object was traced, remove it first before overwriting its storage */ - if (type->ob_base.ob_base._ob_next) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_PyRefchain_IsTraced(interp, (PyObject *)type)) { _Py_ForgetReference((PyObject *)type); } #endif diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index e85af2b75e4738..d567839c5e3a0b 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -3,10 +3,11 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_modsupport.h" // _PyArg_NoKwnames() -#include "pycore_object.h" // _PyObject_GC_TRACK(), _Py_FatalRefcountError() +#include "pycore_object.h" // _PyObject_GC_TRACK(), _Py_FatalRefcountError(), _PyDebugAllocatorStats() /*[clinic input] class tuple "PyTupleObject *" "&PyTuple_Type" @@ -62,7 +63,7 @@ tuple_alloc(Py_ssize_t size) static inline PyObject * tuple_get_empty(void) { - return Py_NewRef(&_Py_SINGLETON(tuple_empty)); + return (PyObject *)&_Py_SINGLETON(tuple_empty); } PyObject * diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7e5282cabd1bfb..3261a14a053dc8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -18,9 +18,7 @@ #include "pycore_unionobject.h" // _Py_union_type_or #include "pycore_weakref.h" // _PyWeakref_GET_REF() #include "opcode.h" // MAKE_CELL -#include "structmember.h" // PyMemberDef -#include #include // ptrdiff_t /*[clinic input] @@ -586,8 +584,29 @@ _PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc) return PyUnicode_FromString(doc); } +static const char * +signature_from_flags(int flags) +{ + switch (flags & ~METH_COEXIST) { + case METH_NOARGS: + return "($self, /)"; + case METH_NOARGS|METH_CLASS: + return "($type, /)"; + case METH_NOARGS|METH_STATIC: + return "()"; + case METH_O: + return "($self, object, /)"; + case METH_O|METH_CLASS: + return "($type, object, /)"; + case METH_O|METH_STATIC: + return "(object, /)"; + default: + return NULL; + } +} + PyObject * -_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc) +_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc, int flags) { const char *start = find_signature(name, internal_doc); const char *end; @@ -597,6 +616,10 @@ _PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_d else end = NULL; if (!end) { + start = signature_from_flags(flags); + if (start) { + return PyUnicode_FromString(start); + } Py_RETURN_NONE; } @@ -935,16 +958,16 @@ int PyUnstable_Type_AssignVersionTag(PyTypeObject *type) static PyMemberDef type_members[] = { - {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, - {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY}, - {"__flags__", T_ULONG, offsetof(PyTypeObject, tp_flags), READONLY}, + {"__basicsize__", Py_T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),Py_READONLY}, + {"__itemsize__", Py_T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), Py_READONLY}, + {"__flags__", Py_T_ULONG, offsetof(PyTypeObject, tp_flags), Py_READONLY}, /* Note that this value is misleading for static builtin types, since the memory at this offset will always be NULL. */ - {"__weakrefoffset__", T_PYSSIZET, - offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, - {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY}, - {"__dictoffset__", T_PYSSIZET, - offsetof(PyTypeObject, tp_dictoffset), READONLY}, + {"__weakrefoffset__", Py_T_PYSSIZET, + offsetof(PyTypeObject, tp_weaklistoffset), Py_READONLY}, + {"__base__", _Py_T_OBJECT, offsetof(PyTypeObject, tp_base), Py_READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, + offsetof(PyTypeObject, tp_dictoffset), Py_READONLY}, {0} }; @@ -1085,7 +1108,7 @@ type_module(PyTypeObject *type, void *context) PyUnicode_InternInPlace(&mod); } else { - mod = Py_NewRef(&_Py_ID(builtins)); + mod = &_Py_ID(builtins); } } return mod; @@ -1429,7 +1452,7 @@ type_get_doc(PyTypeObject *type, void *context) static PyObject * type_get_text_signature(PyTypeObject *type, void *context) { - return _PyType_GetTextSignatureFromInternalDoc(type->tp_name, type->tp_doc); + return _PyType_GetTextSignatureFromInternalDoc(type->tp_name, type->tp_doc, 0); } static int @@ -1775,7 +1798,7 @@ traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg) n = Py_SIZE(type); mp = _PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { - if (mp->type == T_OBJECT_EX) { + if (mp->type == Py_T_OBJECT_EX) { char *addr = (char *)self + mp->offset; PyObject *obj = *(PyObject **)addr; if (obj != NULL) { @@ -1812,7 +1835,7 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) assert(base->tp_dictoffset == 0); if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { assert(type->tp_dictoffset == -1); - int err = _PyObject_VisitManagedDict(self, visit, arg); + int err = PyObject_VisitManagedDict(self, visit, arg); if (err) { return err; } @@ -1850,7 +1873,7 @@ clear_slots(PyTypeObject *type, PyObject *self) n = Py_SIZE(type); mp = _PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { - if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { + if (mp->type == Py_T_OBJECT_EX && !(mp->flags & Py_READONLY)) { char *addr = (char *)self + mp->offset; PyObject *obj = *(PyObject **)addr; if (obj != NULL) { @@ -1882,7 +1905,7 @@ subtype_clear(PyObject *self) __dict__ slots (as in the case 'self.__dict__ is self'). */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { if ((base->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - _PyObject_ClearManagedDict(self); + PyObject_ClearManagedDict(self); } } else if (type->tp_dictoffset != base->tp_dictoffset) { @@ -2419,7 +2442,7 @@ set_mro_error(PyObject **to_merge, Py_ssize_t to_merge_size, int *remain) n = PyDict_GET_SIZE(set); off = PyOS_snprintf(buf, sizeof(buf), "Cannot create a \ -consistent method resolution\norder (MRO) for bases"); +consistent method resolution order (MRO) for bases"); i = 0; while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) { PyObject *name = class_name(k); @@ -3567,7 +3590,7 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) if (mp->name == NULL) { return -1; } - mp->type = T_OBJECT_EX; + mp->type = Py_T_OBJECT_EX; mp->offset = slotoffset; /* __dict__ and __weakref__ are already filtered out */ @@ -3856,16 +3879,14 @@ type_new_get_bases(type_new_ctx *ctx, PyObject **type) if (PyType_Check(base)) { continue; } - PyObject *mro_entries; - if (PyObject_GetOptionalAttr(base, &_Py_ID(__mro_entries__), - &mro_entries) < 0) { + int rc = PyObject_HasAttrWithError(base, &_Py_ID(__mro_entries__)); + if (rc < 0) { return -1; } - if (mro_entries != NULL) { + if (rc) { PyErr_SetString(PyExc_TypeError, "type() doesn't support MRO entry resolution; " "use types.new_class()"); - Py_DECREF(mro_entries); return -1; } } @@ -4116,20 +4137,20 @@ _PyType_FromMetaclass_impl( nmembers++; if (strcmp(memb->name, "__weaklistoffset__") == 0) { // The PyMemberDef must be a Py_ssize_t and readonly - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); + assert(memb->type == Py_T_PYSSIZET); + assert(memb->flags == Py_READONLY); weaklistoffset = memb->offset; } if (strcmp(memb->name, "__dictoffset__") == 0) { // The PyMemberDef must be a Py_ssize_t and readonly - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); + assert(memb->type == Py_T_PYSSIZET); + assert(memb->flags == Py_READONLY); dictoffset = memb->offset; } if (strcmp(memb->name, "__vectorcalloffset__") == 0) { // The PyMemberDef must be a Py_ssize_t and readonly - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); + assert(memb->type == Py_T_PYSSIZET); + assert(memb->flags == Py_READONLY); vectorcalloffset = memb->offset; } if (memb->flags & Py_RELATIVE_OFFSET) { @@ -4264,9 +4285,9 @@ _PyType_FromMetaclass_impl( if (_allow_tp_new) { if (PyErr_WarnFormat( PyExc_DeprecationWarning, 1, - "Using PyType_Spec with metaclasses that have custom " - "tp_new is deprecated and will no longer be allowed in " - "Python 3.14.") < 0) { + "Type %s uses PyType_Spec with a metaclass that has custom " + "tp_new. This is deprecated and will no longer be allowed in " + "Python 3.14.", spec->name) < 0) { goto finally; } } @@ -4965,9 +4986,6 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) return res; } -extern void -_PyDictKeys_DecRef(PyDictKeysObject *keys); - static void type_dealloc_common(PyTypeObject *type) @@ -7486,7 +7504,7 @@ type_ready(PyTypeObject *type, int rerunbuiltin) * to get type objects into the doubly-linked list of all objects. * Still, not all type objects go through PyType_Ready. */ - _Py_AddToAllObjects((PyObject *)type, 0); + _Py_AddToAllObjects((PyObject *)type); #endif /* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */ @@ -10178,11 +10196,11 @@ typedef struct { } superobject; static PyMemberDef super_members[] = { - {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY, + {"__thisclass__", _Py_T_OBJECT, offsetof(superobject, type), Py_READONLY, "the class invoking super()"}, - {"__self__", T_OBJECT, offsetof(superobject, obj), READONLY, + {"__self__", _Py_T_OBJECT, offsetof(superobject, obj), Py_READONLY, "the instance invoking super(); may be None"}, - {"__self_class__", T_OBJECT, offsetof(superobject, obj_type), READONLY, + {"__self_class__", _Py_T_OBJECT, offsetof(superobject, obj_type), Py_READONLY, "the type of the instance invoking super(); may be None"}, {0} }; diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 5605662f0e6d5e..8a20b23c6866d7 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -3,7 +3,7 @@ #include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK #include "pycore_typevarobject.h" #include "pycore_unionobject.h" // _Py_union_type_or -#include "structmember.h" + /*[clinic input] class typevar "typevarobject *" "&_PyTypeVar_Type" @@ -107,7 +107,7 @@ make_union(PyObject *self, PyObject *other) static PyObject * caller(void) { - _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame; + _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame; if (f == NULL) { Py_RETURN_NONE; } @@ -200,7 +200,8 @@ typevar_dealloc(PyObject *self) Py_XDECREF(tv->evaluate_bound); Py_XDECREF(tv->constraints); Py_XDECREF(tv->evaluate_constraints); - _PyObject_ClearManagedDict(self); + PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); Py_TYPE(self)->tp_free(self); Py_DECREF(tp); @@ -215,7 +216,7 @@ typevar_traverse(PyObject *self, visitproc visit, void *arg) Py_VISIT(tv->evaluate_bound); Py_VISIT(tv->constraints); Py_VISIT(tv->evaluate_constraints); - _PyObject_VisitManagedDict(self, visit, arg); + PyObject_VisitManagedDict(self, visit, arg); return 0; } @@ -226,7 +227,7 @@ typevar_clear(typevarobject *self) Py_CLEAR(self->evaluate_bound); Py_CLEAR(self->constraints); Py_CLEAR(self->evaluate_constraints); - _PyObject_ClearManagedDict((PyObject *)self); + PyObject_ClearManagedDict((PyObject *)self); return 0; } @@ -244,10 +245,10 @@ typevar_repr(PyObject *self) } static PyMemberDef typevar_members[] = { - {"__name__", T_OBJECT, offsetof(typevarobject, name), READONLY}, - {"__covariant__", T_BOOL, offsetof(typevarobject, covariant), READONLY}, - {"__contravariant__", T_BOOL, offsetof(typevarobject, contravariant), READONLY}, - {"__infer_variance__", T_BOOL, offsetof(typevarobject, infer_variance), READONLY}, + {"__name__", _Py_T_OBJECT, offsetof(typevarobject, name), Py_READONLY}, + {"__covariant__", Py_T_BOOL, offsetof(typevarobject, covariant), Py_READONLY}, + {"__contravariant__", Py_T_BOOL, offsetof(typevarobject, contravariant), Py_READONLY}, + {"__infer_variance__", Py_T_BOOL, offsetof(typevarobject, infer_variance), Py_READONLY}, {0} }; @@ -363,24 +364,26 @@ typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, } } - if (!PyTuple_CheckExact(constraints)) { - PyErr_SetString(PyExc_TypeError, - "constraints must be a tuple"); - return NULL; - } - Py_ssize_t n_constraints = PyTuple_GET_SIZE(constraints); - if (n_constraints == 1) { - PyErr_SetString(PyExc_TypeError, - "A single constraint is not allowed"); - Py_XDECREF(bound); - return NULL; - } else if (n_constraints == 0) { - constraints = NULL; - } else if (bound != NULL) { - PyErr_SetString(PyExc_TypeError, - "Constraints cannot be combined with bound=..."); - Py_XDECREF(bound); - return NULL; + if (constraints != NULL) { + if (!PyTuple_CheckExact(constraints)) { + PyErr_SetString(PyExc_TypeError, + "constraints must be a tuple"); + return NULL; + } + Py_ssize_t n_constraints = PyTuple_GET_SIZE(constraints); + if (n_constraints == 1) { + PyErr_SetString(PyExc_TypeError, + "A single constraint is not allowed"); + Py_XDECREF(bound); + return NULL; + } else if (n_constraints == 0) { + constraints = NULL; + } else if (bound != NULL) { + PyErr_SetString(PyExc_TypeError, + "Constraints cannot be combined with bound=..."); + Py_XDECREF(bound); + return NULL; + } } PyObject *module = caller(); if (module == NULL) { @@ -401,12 +404,13 @@ typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, typevar.__typing_subst__ as typevar_typing_subst arg: object + / [clinic start generated code]*/ static PyObject * -typevar_typing_subst_impl(typevarobject *self, PyObject *arg) -/*[clinic end generated code: output=c76ced134ed8f4e1 input=6b70a4bb2da838de]*/ +typevar_typing_subst(typevarobject *self, PyObject *arg) +/*[clinic end generated code: output=0773735e8ce18968 input=9e87b57f0fc59b92]*/ { PyObject *args[2] = {(PyObject *)self, arg}; PyObject *result = call_typing_func_object("_typevar_subst", args, 2); @@ -555,7 +559,7 @@ paramspecattr_richcompare(PyObject *a, PyObject *b, int op) } static PyMemberDef paramspecattr_members[] = { - {"__origin__", T_OBJECT, offsetof(paramspecattrobject, __origin__), READONLY}, + {"__origin__", _Py_T_OBJECT, offsetof(paramspecattrobject, __origin__), Py_READONLY}, {0} }; @@ -742,7 +746,8 @@ paramspec_dealloc(PyObject *self) Py_DECREF(ps->name); Py_XDECREF(ps->bound); - _PyObject_ClearManagedDict(self); + PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); Py_TYPE(self)->tp_free(self); Py_DECREF(tp); @@ -754,7 +759,7 @@ paramspec_traverse(PyObject *self, visitproc visit, void *arg) Py_VISIT(Py_TYPE(self)); paramspecobject *ps = (paramspecobject *)self; Py_VISIT(ps->bound); - _PyObject_VisitManagedDict(self, visit, arg); + PyObject_VisitManagedDict(self, visit, arg); return 0; } @@ -762,7 +767,7 @@ static int paramspec_clear(paramspecobject *self) { Py_CLEAR(self->bound); - _PyObject_ClearManagedDict((PyObject *)self); + PyObject_ClearManagedDict((PyObject *)self); return 0; } @@ -780,11 +785,11 @@ paramspec_repr(PyObject *self) } static PyMemberDef paramspec_members[] = { - {"__name__", T_OBJECT, offsetof(paramspecobject, name), READONLY}, - {"__bound__", T_OBJECT, offsetof(paramspecobject, bound), READONLY}, - {"__covariant__", T_BOOL, offsetof(paramspecobject, covariant), READONLY}, - {"__contravariant__", T_BOOL, offsetof(paramspecobject, contravariant), READONLY}, - {"__infer_variance__", T_BOOL, offsetof(paramspecobject, infer_variance), READONLY}, + {"__name__", _Py_T_OBJECT, offsetof(paramspecobject, name), Py_READONLY}, + {"__bound__", _Py_T_OBJECT, offsetof(paramspecobject, bound), Py_READONLY}, + {"__covariant__", Py_T_BOOL, offsetof(paramspecobject, covariant), Py_READONLY}, + {"__contravariant__", Py_T_BOOL, offsetof(paramspecobject, contravariant), Py_READONLY}, + {"__infer_variance__", Py_T_BOOL, offsetof(paramspecobject, infer_variance), Py_READONLY}, {0} }; @@ -803,8 +808,8 @@ paramspec_kwargs(PyObject *self, void *unused) } static PyGetSetDef paramspec_getset[] = { - {"args", (getter)paramspec_args, NULL, "Represents positional arguments.", NULL}, - {"kwargs", (getter)paramspec_kwargs, NULL, "Represents keyword arguments.", NULL}, + {"args", (getter)paramspec_args, NULL, PyDoc_STR("Represents positional arguments."), NULL}, + {"kwargs", (getter)paramspec_kwargs, NULL, PyDoc_STR("Represents keyword arguments."), NULL}, {0}, }; @@ -882,12 +887,13 @@ paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound, paramspec.__typing_subst__ as paramspec_typing_subst arg: object + / [clinic start generated code]*/ static PyObject * -paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg) -/*[clinic end generated code: output=803e1ade3f13b57d input=4e0005d24023e896]*/ +paramspec_typing_subst(paramspecobject *self, PyObject *arg) +/*[clinic end generated code: output=4c5b4aaada1c5814 input=2d5b5e3d4a717189]*/ { PyObject *args[2] = {(PyObject *)self, arg}; PyObject *result = call_typing_func_object("_paramspec_subst", args, 2); @@ -899,13 +905,14 @@ paramspec.__typing_prepare_subst__ as paramspec_typing_prepare_subst alias: object args: object + / [clinic start generated code]*/ static PyObject * paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias, PyObject *args) -/*[clinic end generated code: output=95449d630a2adb9a input=4375e2ffcb2ad635]*/ +/*[clinic end generated code: output=95449d630a2adb9a input=6df6f9fef3e150da]*/ { PyObject *args_array[3] = {(PyObject *)self, alias, args}; PyObject *result = call_typing_func_object( @@ -1021,7 +1028,8 @@ typevartuple_dealloc(PyObject *self) typevartupleobject *tvt = (typevartupleobject *)self; Py_DECREF(tvt->name); - _PyObject_ClearManagedDict(self); + PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); Py_TYPE(self)->tp_free(self); Py_DECREF(tp); @@ -1054,7 +1062,7 @@ typevartuple_repr(PyObject *self) } static PyMemberDef typevartuple_members[] = { - {"__name__", T_OBJECT, offsetof(typevartupleobject, name), READONLY}, + {"__name__", _Py_T_OBJECT, offsetof(typevartupleobject, name), Py_READONLY}, {0} }; @@ -1103,12 +1111,13 @@ typevartuple_impl(PyTypeObject *type, PyObject *name) typevartuple.__typing_subst__ as typevartuple_typing_subst arg: object + / [clinic start generated code]*/ static PyObject * -typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg) -/*[clinic end generated code: output=814316519441cd76 input=670c4e0a36e5d8c0]*/ +typevartuple_typing_subst(typevartupleobject *self, PyObject *arg) +/*[clinic end generated code: output=237054c6d7484eea input=3fcf2dfd9eee7945]*/ { PyErr_SetString(PyExc_TypeError, "Substitution of bare TypeVarTuple is not supported"); return NULL; @@ -1119,13 +1128,14 @@ typevartuple.__typing_prepare_subst__ as typevartuple_typing_prepare_subst alias: object args: object + / [clinic start generated code]*/ static PyObject * typevartuple_typing_prepare_subst_impl(typevartupleobject *self, PyObject *alias, PyObject *args) -/*[clinic end generated code: output=ff999bc5b02036c1 input=a211b05f2eeb4306]*/ +/*[clinic end generated code: output=ff999bc5b02036c1 input=685b149b0fc47556]*/ { PyObject *args_array[3] = {(PyObject *)self, alias, args}; PyObject *result = call_typing_func_object( @@ -1157,14 +1167,14 @@ static int typevartuple_traverse(PyObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); - _PyObject_VisitManagedDict(self, visit, arg); + PyObject_VisitManagedDict(self, visit, arg); return 0; } static int typevartuple_clear(PyObject *self) { - _PyObject_ClearManagedDict(self); + PyObject_ClearManagedDict(self); return 0; } @@ -1292,7 +1302,7 @@ typealias_repr(PyObject *self) } static PyMemberDef typealias_members[] = { - {"__name__", T_OBJECT, offsetof(typealiasobject, name), READONLY}, + {"__name__", _Py_T_OBJECT, offsetof(typealiasobject, name), Py_READONLY}, {0} }; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f543c0a65b49f6..33cbc987d43282 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -40,9 +40,9 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_atomic_funcs.h" // _Py_atomic_size_get() #include "pycore_bytes_methods.h" // _Py_bytes_lower() #include "pycore_bytesobject.h" // _PyBytes_Repeat() +#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_codecs.h" // _PyCodec_Lookup() #include "pycore_format.h" // F_LJUST #include "pycore_initconfig.h" // _PyStatus_OK() @@ -56,6 +56,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include "pycore_unicodeobject.h" // struct _Py_unicode_state #include "pycore_unicodeobject_generated.h" // _PyUnicode_InitStaticStrings() + #include "stringlib/eq.h" // unicode_eq() #include // ptrdiff_t @@ -99,11 +100,6 @@ NOTE: In the interpreter's initialization phase, some globals are currently */ - -#ifdef __cplusplus -extern "C" { -#endif - // Maximum code point of Unicode 6.0: 0x10ffff (1,114,111). // The value must be the same in fileutils.c. #define MAX_UNICODE 0x10ffff @@ -211,21 +207,13 @@ static int unicode_is_singleton(PyObject *unicode); #endif -// Return a borrowed reference to the empty string singleton. +// Return a reference to the immortal empty string singleton. static inline PyObject* unicode_get_empty(void) { _Py_DECLARE_STR(empty, ""); return &_Py_STR(empty); } - -// Return a strong reference to the empty string singleton. -static inline PyObject* unicode_new_empty(void) -{ - PyObject *empty = unicode_get_empty(); - return Py_NewRef(empty); -} - /* This dictionary holds all interned unicode strings. Note that references to strings in this dictionary are *not* counted in the string's ob_refcnt. When the interned string reaches a refcnt of 0 the string deallocation @@ -236,15 +224,54 @@ static inline PyObject *get_interned_dict(PyInterpreterState *interp) return _Py_INTERP_CACHED_OBJECT(interp, interned_strings); } +#define INTERNED_STRINGS _PyRuntime.cached_objects.interned_strings + Py_ssize_t _PyUnicode_InternedSize(void) { - return PyObject_Length(get_interned_dict(_PyInterpreterState_GET())); + PyObject *dict = get_interned_dict(_PyInterpreterState_GET()); + return _Py_hashtable_len(INTERNED_STRINGS) + PyDict_GET_SIZE(dict); +} + +static Py_hash_t unicode_hash(PyObject *); +static int unicode_compare_eq(PyObject *, PyObject *); + +static Py_uhash_t +hashtable_unicode_hash(const void *key) +{ + return unicode_hash((PyObject *)key); +} + +static int +hashtable_unicode_compare(const void *key1, const void *key2) +{ + PyObject *obj1 = (PyObject *)key1; + PyObject *obj2 = (PyObject *)key2; + if (obj1 != NULL && obj2 != NULL) { + return unicode_compare_eq(obj1, obj2); + } + else { + return obj1 == obj2; + } } static int init_interned_dict(PyInterpreterState *interp) { + if (_Py_IsMainInterpreter(interp)) { + assert(INTERNED_STRINGS == NULL); + _Py_hashtable_allocator_t hashtable_alloc = {PyMem_RawMalloc, PyMem_RawFree}; + INTERNED_STRINGS = _Py_hashtable_new_full( + hashtable_unicode_hash, + hashtable_unicode_compare, + NULL, + NULL, + &hashtable_alloc + ); + if (INTERNED_STRINGS == NULL) { + return -1; + } + } assert(get_interned_dict(interp) == NULL); PyObject *interned = interned = PyDict_New(); if (interned == NULL) { @@ -263,11 +290,15 @@ clear_interned_dict(PyInterpreterState *interp) Py_DECREF(interned); _Py_INTERP_CACHED_OBJECT(interp, interned_strings) = NULL; } + if (_Py_IsMainInterpreter(interp) && INTERNED_STRINGS != NULL) { + _Py_hashtable_destroy(INTERNED_STRINGS); + INTERNED_STRINGS = NULL; + } } #define _Py_RETURN_UNICODE_EMPTY() \ do { \ - return unicode_new_empty(); \ + return unicode_get_empty(); \ } while (0) static inline void @@ -607,7 +638,6 @@ unicode_result(PyObject *unicode) PyObject *empty = unicode_get_empty(); if (unicode != empty) { Py_DECREF(unicode); - Py_INCREF(empty); } return empty; } @@ -619,7 +649,6 @@ unicode_result(PyObject *unicode) Py_UCS1 ch = data[0]; PyObject *latin1_char = LATIN1(ch); if (unicode != latin1_char) { - Py_INCREF(latin1_char); Py_DECREF(unicode); } return latin1_char; @@ -1156,7 +1185,7 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) { /* Optimization for empty strings */ if (size == 0) { - return unicode_new_empty(); + return unicode_get_empty(); } PyObject *obj; @@ -1223,6 +1252,7 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) _PyUnicode_STATE(unicode).kind = kind; _PyUnicode_STATE(unicode).compact = 1; _PyUnicode_STATE(unicode).ascii = is_ascii; + _PyUnicode_STATE(unicode).statically_allocated = 0; if (is_ascii) { ((char*)data)[size] = 0; } @@ -1553,7 +1583,9 @@ unicode_dealloc(PyObject *unicode) * we accidentally decref an immortal string out of existence. Since * the string is an immortal object, just re-set the reference count. */ - if (PyUnicode_CHECK_INTERNED(unicode)) { + if (PyUnicode_CHECK_INTERNED(unicode) + || _PyUnicode_STATE(unicode).statically_allocated) + { _Py_SetImmortal(unicode); return; } @@ -1623,7 +1655,7 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length) return 0; if (length == 0) { - PyObject *empty = unicode_new_empty(); + PyObject *empty = unicode_get_empty(); Py_SETREF(*p_unicode, empty); return 0; } @@ -1718,7 +1750,9 @@ unicode_write_cstr(PyObject *unicode, Py_ssize_t index, static PyObject* get_latin1_char(Py_UCS1 ch) { - return Py_NewRef(LATIN1(ch)); + PyObject *o = LATIN1(ch); + assert(_Py_IsImmortal(o)); + return o; } static PyObject* @@ -1845,7 +1879,7 @@ PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) "NULL string with positive size with NULL passed to PyUnicode_FromStringAndSize"); return NULL; } - return unicode_new_empty(); + return unicode_get_empty(); } PyObject * @@ -1866,19 +1900,19 @@ _PyUnicode_FromId(_Py_Identifier *id) PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_unicode_ids *ids = &interp->unicode.ids; - Py_ssize_t index = _Py_atomic_size_get(&id->index); + Py_ssize_t index = _Py_atomic_load_ssize(&id->index); if (index < 0) { struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids; PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); // Check again to detect concurrent access. Another thread can have // initialized the index while this thread waited for the lock. - index = _Py_atomic_size_get(&id->index); + index = _Py_atomic_load_ssize(&id->index); if (index < 0) { assert(rt_ids->next_index < PY_SSIZE_T_MAX); index = rt_ids->next_index; rt_ids->next_index++; - _Py_atomic_size_set(&id->index, index); + _Py_atomic_store_ssize(&id->index, index); } PyThread_release_lock(rt_ids->lock); } @@ -7061,7 +7095,7 @@ decode_code_page_errors(UINT code_page, if (err != ERROR_NO_UNICODE_TRANSLATION && err != ERROR_INSUFFICIENT_BUFFER) { - PyErr_SetFromWindowsErr(0); + PyErr_SetFromWindowsErr(err); goto error; } insize++; @@ -10215,7 +10249,7 @@ replace(PyObject *self, PyObject *str1, } new_size = slen + n * (len2 - len1); if (new_size == 0) { - u = unicode_new_empty(); + u = unicode_get_empty(); goto done; } if (new_size > (PY_SSIZE_T_MAX / rkind)) { @@ -10639,6 +10673,82 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) } } +int +PyUnicode_EqualToUTF8(PyObject *unicode, const char *str) +{ + return PyUnicode_EqualToUTF8AndSize(unicode, str, strlen(str)); +} + +int +PyUnicode_EqualToUTF8AndSize(PyObject *unicode, const char *str, Py_ssize_t size) +{ + assert(_PyUnicode_CHECK(unicode)); + assert(str); + + if (PyUnicode_IS_ASCII(unicode)) { + Py_ssize_t len = PyUnicode_GET_LENGTH(unicode); + return size == len && + memcmp(PyUnicode_1BYTE_DATA(unicode), str, len) == 0; + } + if (PyUnicode_UTF8(unicode) != NULL) { + Py_ssize_t len = PyUnicode_UTF8_LENGTH(unicode); + return size == len && + memcmp(PyUnicode_UTF8(unicode), str, len) == 0; + } + + Py_ssize_t len = PyUnicode_GET_LENGTH(unicode); + if ((size_t)len >= (size_t)size || (size_t)len < (size_t)size / 4) { + return 0; + } + const unsigned char *s = (const unsigned char *)str; + const unsigned char *ends = s + (size_t)size; + int kind = PyUnicode_KIND(unicode); + const void *data = PyUnicode_DATA(unicode); + /* Compare Unicode string and UTF-8 string */ + for (Py_ssize_t i = 0; i < len; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (ch < 0x80) { + if (ends == s || s[0] != ch) { + return 0; + } + s += 1; + } + else if (ch < 0x800) { + if ((ends - s) < 2 || + s[0] != (0xc0 | (ch >> 6)) || + s[1] != (0x80 | (ch & 0x3f))) + { + return 0; + } + s += 2; + } + else if (ch < 0x10000) { + if (Py_UNICODE_IS_SURROGATE(ch) || + (ends - s) < 3 || + s[0] != (0xe0 | (ch >> 12)) || + s[1] != (0x80 | ((ch >> 6) & 0x3f)) || + s[2] != (0x80 | (ch & 0x3f))) + { + return 0; + } + s += 3; + } + else { + assert(ch <= MAX_UNICODE); + if ((ends - s) < 4 || + s[0] != (0xf0 | (ch >> 18)) || + s[1] != (0x80 | ((ch >> 12) & 0x3f)) || + s[2] != (0x80 | ((ch >> 6) & 0x3f)) || + s[3] != (0x80 | (ch & 0x3f))) + { + return 0; + } + s += 4; + } + } + return s == ends; +} + int _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) { @@ -12362,7 +12472,7 @@ str.split as unicode_split The separator used to split the string. When set to None (the default value), will split on any whitespace - character (including \\n \\r \\t \\f and spaces) and will discard + character (including \n \r \t \f and spaces) and will discard empty strings from the result. maxsplit: Py_ssize_t = -1 Maximum number of splits (starting from the left). @@ -12378,7 +12488,7 @@ the regular expression module. static PyObject * unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) -/*[clinic end generated code: output=3a65b1db356948dc input=906d953b44efc43b]*/ +/*[clinic end generated code: output=3a65b1db356948dc input=07b9040d98c5fe8d]*/ { if (sep == Py_None) return split(self, NULL, maxsplit); @@ -13994,7 +14104,7 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx, "* wants int"); return -1; } - arg->prec = _PyLong_AsInt(v); + arg->prec = PyLong_AsInt(v); if (arg->prec == -1 && PyErr_Occurred()) return -1; if (arg->prec < 0) @@ -14459,7 +14569,7 @@ unicode_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, { PyObject *unicode; if (x == NULL) { - unicode = unicode_new_empty(); + unicode = unicode_get_empty(); } else if (encoding == NULL && errors == NULL) { unicode = PyObject_Str(x); @@ -14503,6 +14613,7 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) _PyUnicode_STATE(self).kind = kind; _PyUnicode_STATE(self).compact = 0; _PyUnicode_STATE(self).ascii = _PyUnicode_STATE(unicode).ascii; + _PyUnicode_STATE(self).statically_allocated = 0; _PyUnicode_UTF8_LENGTH(self) = 0; _PyUnicode_UTF8(self) = NULL; _PyUnicode_DATA_ANY(self) = NULL; @@ -14726,6 +14837,23 @@ _PyUnicode_InternInPlace(PyInterpreterState *interp, PyObject **p) return; } + /* Look in the global cache first. */ + PyObject *r = (PyObject *)_Py_hashtable_get(INTERNED_STRINGS, s); + if (r != NULL && r != s) { + Py_SETREF(*p, Py_NewRef(r)); + return; + } + + /* Handle statically allocated strings. */ + if (_PyUnicode_STATE(s).statically_allocated) { + assert(_Py_IsImmortal(s)); + if (_Py_hashtable_set(INTERNED_STRINGS, s, s) == 0) { + _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL_STATIC; + } + return; + } + + /* Look in the per-interpreter cache. */ PyObject *interned = get_interned_dict(interp); assert(interned != NULL); @@ -14741,9 +14869,11 @@ _PyUnicode_InternInPlace(PyInterpreterState *interp, PyObject **p) } if (_Py_IsImmortal(s)) { + // XXX Restrict this to the main interpreter? _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL_STATIC; - return; + return; } + #ifdef Py_REF_DEBUG /* The reference count value excluding the 2 references from the interned dictionary should be excluded from the RefTotal. The @@ -14818,6 +14948,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) PyObject *s, *ignored_value; while (PyDict_Next(interned, &pos, &s, &ignored_value)) { assert(PyUnicode_IS_READY(s)); + int shared = 0; switch (PyUnicode_CHECK_INTERNED(s)) { case SSTATE_INTERNED_IMMORTAL: // Skip the Immortal Instance check and restore @@ -14829,6 +14960,14 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) #endif break; case SSTATE_INTERNED_IMMORTAL_STATIC: + /* It is shared between interpreters, so we should unmark it + only when this is the last interpreter in which it's + interned. We immortalize all the statically initialized + strings during startup, so we can rely on the + main interpreter to be the last one. */ + if (!_Py_IsMainInterpreter(interp)) { + shared = 1; + } break; case SSTATE_INTERNED_MORTAL: /* fall through */ @@ -14837,7 +14976,9 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) default: Py_UNREACHABLE(); } - _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + if (!shared) { + _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + } } #ifdef INTERNED_STATS fprintf(stderr, @@ -14917,8 +15058,7 @@ unicode_ascii_iter_next(unicodeiterobject *it) Py_UCS1 chr = (Py_UCS1)PyUnicode_READ(PyUnicode_1BYTE_KIND, data, it->it_index); it->it_index++; - PyObject *item = (PyObject*)&_Py_SINGLETON(strings).ascii[chr]; - return Py_NewRef(item); + return (PyObject*)&_Py_SINGLETON(strings).ascii[chr]; } it->it_seq = NULL; Py_DECREF(seq); @@ -14948,7 +15088,7 @@ unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) if (it->it_seq != NULL) { return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); } else { - PyObject *u = unicode_new_empty(); + PyObject *u = unicode_get_empty(); if (u == NULL) { Py_XDECREF(iter); return NULL; @@ -15178,10 +15318,13 @@ init_fs_codec(PyInterpreterState *interp) /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors global configuration variables. */ - if (_Py_SetFileSystemEncoding(fs_codec->encoding, - fs_codec->errors) < 0) { - PyErr_NoMemory(); - return -1; + if (_Py_IsMainInterpreter(interp)) { + + if (_Py_SetFileSystemEncoding(fs_codec->encoding, + fs_codec->errors) < 0) { + PyErr_NoMemory(); + return -1; + } } return 0; } @@ -15325,8 +15468,3 @@ PyInit__string(void) { return PyModuleDef_Init(&_string_module); } - - -#ifdef __cplusplus -} -#endif diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 22f8243eaec1b7..39a567dc46e89a 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -360,6 +360,7 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, -128, 0, 0, 0, 10113}, {0, -126, 0, 0, 0, 10113}, {33555335, 18875268, 16778121, 0, 0, 26433}, + {0, 0, 0, 0, 0, 4608}, {0, 0, 0, 0, 0, 3076}, {0, 0, 0, 0, 4, 3076}, {0, 0, 0, 0, 5, 3076}, @@ -1760,603 +1761,603 @@ static const unsigned short index1[] = { 76, 64, 77, 78, 79, 80, 81, 82, 83, 64, 64, 84, 85, 34, 34, 34, 34, 34, 34, 86, 34, 34, 34, 34, 34, 87, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 88, 89, 90, 91, 34, 34, 34, 92, 34, 34, - 34, 93, 94, 34, 34, 34, 34, 34, 95, 34, 34, 34, 96, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 97, 98, 99, 34, 34, 34, 34, 34, 34, 100, 101, 34, 34, - 34, 34, 34, 34, 34, 34, 102, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 34, 34, 104, 34, 34, 34, 34, - 100, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 105, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 106, 107, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 108, 109, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 110, 34, 34, 34, 34, 34, - 34, 34, 34, 111, 34, 34, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 88, 89, 90, 91, 92, 93, 34, 94, 34, 34, + 34, 95, 96, 34, 34, 34, 34, 34, 97, 34, 34, 34, 98, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 99, 100, 101, 34, 34, 34, 34, 34, 34, 102, 103, 34, + 34, 34, 34, 34, 34, 34, 34, 104, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 105, 34, 34, 34, 93, 34, 34, 34, 34, 34, 34, 34, 34, 106, 34, 34, 34, 34, + 107, 108, 34, 34, 34, 34, 34, 109, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 93, 34, 34, 34, 34, 34, 34, 110, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 111, 112, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 113, 34, 34, 34, 34, 114, 34, 34, 115, 116, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 117, 34, 34, 34, + 34, 34, 34, 34, 34, 118, 34, 34, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, - 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 125, 143, 144, 145, 146, 147, 148, 149, 34, 34, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 125, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 125, 174, 175, 125, 176, 177, 178, 179, - 125, 180, 181, 182, 183, 184, 185, 186, 125, 187, 188, 189, 190, 125, - 191, 192, 193, 34, 34, 34, 34, 34, 34, 34, 194, 195, 34, 196, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 197, 34, 34, 34, 34, 34, 34, 34, 34, 198, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 34, 34, 34, 34, 199, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 34, 34, 34, 34, 200, 201, 202, 203, 125, 125, 125, 125, 204, - 205, 206, 207, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 131, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 133, 134, + 135, 136, 137, 138, 139, 34, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 132, 150, 151, 152, 153, 154, 155, 156, 34, 34, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 132, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 132, 181, 182, 132, 183, 184, 185, + 186, 132, 187, 188, 189, 190, 191, 192, 193, 132, 194, 195, 196, 197, + 132, 198, 199, 200, 34, 34, 34, 34, 34, 34, 34, 201, 202, 34, 203, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 204, 34, 34, 34, 34, 34, 34, 34, 34, 205, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 34, 34, 34, 34, 206, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 34, 34, 34, 34, 207, 208, 209, 210, 132, 132, 132, 132, + 211, 212, 213, 214, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 208, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 209, 210, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 211, 34, 34, 212, 34, 34, 213, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 214, 215, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 216, 217, 64, 218, - 219, 220, 221, 222, 223, 125, 224, 225, 226, 227, 228, 229, 230, 231, 64, - 64, 64, 64, 232, 233, 125, 125, 125, 125, 125, 125, 125, 125, 234, 125, - 235, 236, 237, 125, 125, 238, 125, 125, 125, 239, 125, 125, 125, 125, - 125, 240, 34, 241, 242, 125, 125, 125, 125, 125, 243, 244, 245, 125, 246, - 247, 125, 125, 248, 249, 250, 251, 252, 125, 64, 253, 64, 64, 64, 64, 64, - 254, 255, 256, 257, 258, 64, 64, 259, 260, 64, 261, 125, 125, 125, 125, - 125, 125, 125, 125, 262, 263, 264, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 86, 265, 34, 266, 267, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 215, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 216, 217, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 218, 34, 34, 219, 34, 34, 220, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 221, 222, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 223, 224, 64, + 225, 226, 227, 228, 229, 230, 132, 231, 232, 233, 234, 235, 236, 237, + 238, 64, 64, 64, 64, 239, 240, 132, 132, 132, 132, 132, 132, 132, 132, + 241, 132, 242, 243, 244, 132, 132, 245, 132, 132, 132, 246, 132, 132, + 132, 132, 132, 247, 34, 248, 249, 132, 132, 132, 132, 132, 250, 251, 252, + 132, 253, 254, 132, 132, 255, 256, 257, 258, 259, 132, 64, 260, 64, 64, + 64, 64, 64, 261, 262, 263, 264, 265, 64, 64, 266, 267, 64, 268, 132, 132, + 132, 132, 132, 132, 132, 132, 269, 270, 271, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 86, 272, 34, 273, 274, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 268, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 269, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 270, + 34, 34, 34, 34, 34, 34, 34, 34, 275, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 276, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 277, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 271, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 109, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 272, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 273, 34, 274, 34, 34, + 278, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 279, 34, 280, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 275, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 281, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 276, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 34, 268, 34, 34, 277, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 282, 34, 34, 34, 34, 283, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 34, 275, 34, 34, 284, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 278, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 285, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 279, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 280, 125, 281, 282, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, + 34, 34, 34, 34, 34, 34, 286, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 287, 132, 288, 289, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, }; static const unsigned short index2[] = { @@ -2777,27 +2778,27 @@ static const unsigned short index2[] = { 342, 265, 265, 343, 343, 0, 5, 5, 5, 264, 264, 344, 345, 346, 126, 347, 348, 265, 265, 349, 349, 130, 5, 5, 5, 0, 0, 350, 351, 352, 0, 353, 354, 355, 355, 356, 356, 357, 5, 5, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, - 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 5, 4, 4, 5, 2, 2, 20, 20, 20, 20, 20, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 20, 20, 20, 20, 20, 0, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 358, 101, 0, 0, 359, 360, 361, 362, 363, - 364, 4, 4, 4, 4, 4, 101, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, - 4, 4, 4, 4, 4, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, - 5, 5, 5, 24, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 120, 4, 4, 4, 4, 120, 4, - 4, 19, 120, 120, 120, 19, 19, 120, 120, 120, 19, 4, 120, 4, 4, 365, 120, - 120, 120, 120, 120, 4, 4, 4, 4, 4, 4, 120, 4, 366, 4, 120, 4, 367, 368, - 120, 120, 365, 19, 120, 120, 369, 120, 19, 54, 54, 54, 54, 19, 4, 4, 19, - 19, 120, 120, 4, 4, 4, 4, 4, 120, 19, 19, 19, 19, 4, 4, 4, 4, 370, 4, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 371, 371, - 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 358, 358, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 5, 4, 4, 5, 2, 2, 20, 20, 20, 20, 20, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 20, 20, 20, 20, 20, 0, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 359, 101, 0, 0, 360, 361, 362, 363, + 364, 365, 4, 4, 4, 4, 4, 101, 359, 25, 21, 22, 360, 361, 362, 363, 364, + 365, 4, 4, 4, 4, 4, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 5, 5, 5, 5, 24, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 120, 4, 4, 4, 4, + 120, 4, 4, 19, 120, 120, 120, 19, 19, 120, 120, 120, 19, 4, 120, 4, 4, + 366, 120, 120, 120, 120, 120, 4, 4, 4, 4, 4, 4, 120, 4, 367, 4, 120, 4, + 368, 369, 120, 120, 366, 19, 120, 120, 370, 120, 19, 54, 54, 54, 54, 19, + 4, 4, 19, 19, 120, 120, 4, 4, 4, 4, 4, 120, 19, 19, 19, 19, 4, 4, 4, 4, + 371, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 242, 242, 242, 29, 30, 242, 242, 242, 242, 26, 4, 4, 0, 0, 0, - 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 242, 242, 242, 29, 30, 242, 242, 242, 242, 26, 4, 4, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, @@ -2808,26 +2809,26 @@ static const unsigned short index2[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 373, 373, 373, 373, 373, - 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, - 373, 373, 373, 373, 373, 373, 373, 374, 374, 374, 374, 374, 374, 374, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 21, 22, 360, 361, 362, 363, 364, 365, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 25, 21, 22, 360, 361, 362, 363, 364, 365, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 21, 22, 360, 361, 362, 363, 364, + 365, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 358, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, - 21, 22, 359, 360, 361, 362, 363, 364, 26, 358, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 374, 374, 374, 374, 374, 374, 374, 374, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 359, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 25, 21, 22, 360, 361, 362, 363, 364, 365, 26, 359, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 25, 21, 22, 359, 360, 361, 362, - 363, 364, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 25, 21, 22, - 359, 360, 361, 362, 363, 364, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 25, 21, 22, 360, 361, + 362, 363, 364, 365, 26, 25, 21, 22, 360, 361, 362, 363, 364, 365, 26, 25, + 21, 22, 360, 361, 362, 363, 364, 365, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, @@ -2836,85 +2837,85 @@ static const unsigned short index2[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 135, 135, 135, 135, 135, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 135, 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 29, 30, 375, 376, 377, 378, 379, 29, - 30, 29, 30, 29, 30, 380, 381, 382, 383, 19, 29, 30, 19, 29, 30, 19, 19, - 19, 19, 19, 101, 101, 384, 384, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 19, 4, 4, 4, 4, 4, 4, 29, 30, 29, 30, 24, 24, 24, 29, 30, 0, 0, 0, 0, 0, - 4, 4, 4, 4, 26, 4, 4, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 0, - 385, 0, 0, 0, 0, 0, 385, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 102, 4, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, - 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, - 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, - 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 24, 24, 24, 24, + 136, 136, 136, 136, 136, 136, 136, 136, 29, 30, 376, 377, 378, 379, 380, + 29, 30, 29, 30, 29, 30, 381, 382, 383, 384, 19, 29, 30, 19, 29, 30, 19, + 19, 19, 19, 19, 101, 101, 385, 385, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 19, 4, 4, 4, 4, 4, 4, 29, 30, 29, 30, 24, 24, 24, 29, 30, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 26, 4, 4, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 0, 386, 0, 0, 0, 0, 0, 386, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 102, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, + 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 386, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 387, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 0, 0, 0, 0, 1, 4, 4, 4, 4, 102, 54, 242, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 24, 24, 24, 24, 17, 17, 4, 102, 102, 102, - 102, 102, 4, 4, 242, 242, 242, 102, 54, 4, 4, 4, 0, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 4, 4, 102, 54, 242, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 24, 24, 24, 24, 17, 17, 4, 102, 102, + 102, 102, 102, 4, 4, 242, 242, 242, 102, 54, 4, 4, 4, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 5, 5, 102, 102, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 5, 5, 102, 102, 54, + 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 4, 102, 102, 102, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 102, 102, 102, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 0, 4, 4, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, + 54, 54, 54, 54, 0, 4, 4, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, @@ -2927,14 +2928,14 @@ static const unsigned short index2[] = { 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, - 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -2943,7 +2944,7 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -2952,7 +2953,7 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -2961,501 +2962,551 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 387, 54, 54, 387, 54, 54, 54, 387, - 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 388, 54, 54, 388, 54, 54, 54, 388, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 388, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 388, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 388, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 54, - 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 387, 387, - 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, - 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 388, 54, 388, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, + 54, 388, 388, 388, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 388, 388, 388, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, - 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 387, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 388, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 388, 388, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, - 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, - 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, - 102, 102, 102, 102, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 102, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, - 29, 30, 54, 24, 5, 5, 5, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, - 102, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, - 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 101, 101, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 24, 24, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 29, 30, 29, 30, 29, - 30, 29, 30, 29, 30, 29, 30, 29, 30, 19, 19, 29, 30, 29, 30, 29, 30, 29, - 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, - 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, + 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 388, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 102, 102, + 102, 102, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, - 30, 101, 19, 19, 19, 19, 19, 19, 19, 19, 29, 30, 29, 30, 388, 29, 30, 29, - 30, 29, 30, 29, 30, 29, 30, 102, 5, 5, 29, 30, 389, 19, 54, 29, 30, 29, - 30, 390, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, - 30, 29, 30, 29, 30, 391, 392, 393, 394, 391, 19, 395, 396, 397, 398, 29, - 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 399, 400, - 401, 29, 30, 29, 30, 0, 0, 0, 0, 0, 29, 30, 0, 19, 0, 19, 29, 30, 29, 30, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 101, 101, 101, 29, 30, 54, 101, 101, 19, 54, 54, 54, 54, 54, 54, 54, 24, - 54, 54, 54, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 24, - 17, 4, 4, 4, 4, 24, 0, 0, 0, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, - 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 54, + 24, 5, 5, 5, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 102, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 101, 101, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 24, 24, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 19, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 101, + 19, 19, 19, 19, 19, 19, 19, 19, 29, 30, 29, 30, 389, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 102, 5, 5, 29, 30, 390, 19, 54, 29, 30, 29, 30, 391, + 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 392, 393, 394, 395, 392, 19, 396, 397, 398, 399, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 400, 401, 402, 29, + 30, 29, 30, 0, 0, 0, 0, 0, 29, 30, 0, 19, 0, 19, 29, 30, 29, 30, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 101, + 101, 29, 30, 54, 101, 101, 19, 54, 54, 54, 54, 54, 54, 54, 24, 54, 54, + 54, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 24, 17, 4, 4, + 4, 4, 24, 0, 0, 0, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 4, 4, 4, 54, - 4, 54, 54, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, - 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, - 24, 24, 24, 17, 17, 24, 24, 17, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 0, 102, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 54, - 54, 54, 54, 54, 24, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 4, 4, 4, 54, 4, 54, + 54, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, - 24, 24, 24, 24, 24, 17, 17, 24, 24, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 0, 0, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 4, - 4, 4, 54, 17, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 24, 54, 24, 24, 24, 54, 54, 24, 24, 54, 54, 54, 54, 54, 24, 24, 54, - 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 54, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, - 24, 24, 17, 17, 4, 4, 54, 102, 102, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, - 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, - 54, 54, 54, 54, 54, 54, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 402, 19, 19, 19, 19, 19, 19, 19, 5, 101, 101, - 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 5, 5, 0, 0, 0, 0, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, - 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, 24, + 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 17, 17, 24, 17, 17, - 4, 17, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, 24, + 24, 24, 17, 17, 24, 24, 17, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 102, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 54, 54, + 54, 54, 54, 24, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, + 24, 24, 24, 24, 17, 17, 24, 24, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 54, 17, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 54, 24, 24, 24, 54, 54, 24, 24, 54, 54, 54, 54, 54, 24, 24, 54, 24, + 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 54, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 24, + 24, 17, 17, 4, 4, 54, 102, 102, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, + 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, + 54, 54, 54, 54, 54, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 403, 19, 19, 19, 19, 19, 19, 19, 5, 101, 101, 101, + 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 5, 5, 0, 0, 0, 0, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 17, 17, 24, 17, 17, 4, + 17, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, + 388, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 483, 484, 485, 486, 487, 488, 489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 490, 491, 492, 493, 494, 0, 0, 0, 0, 0, 54, 24, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 0, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 484, + 485, 486, 487, 488, 489, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, + 492, 493, 494, 495, 0, 0, 0, 0, 0, 54, 24, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 0, 54, 0, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, - 495, 495, 495, 495, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 496, 496, 496, + 496, 496, 496, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 4, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, 495, - 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 17, 17, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 17, - 4, 4, 5, 0, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, - 4, 4, 4, 4, 0, 0, 0, 0, 495, 54, 495, 54, 495, 0, 495, 54, 495, 54, 495, - 54, 495, 54, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 496, 496, 4, 4, 4, + 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, + 4, 5, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 17, 4, 4, 5, 0, + 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, + 0, 0, 0, 0, 496, 54, 496, 54, 496, 0, 496, 54, 496, 54, 496, 54, 496, 54, + 496, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 0, 0, 20, 0, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, + 54, 0, 0, 20, 0, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 496, 496, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 497, 497, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, - 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 0, 0, 0, - 4, 4, 4, 5, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 20, 20, 20, 4, 4, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, + 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 0, 0, 0, 4, 4, 4, 5, + 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, + 20, 4, 4, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 4, - 4, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 4, 4, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 26, - 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 4, - 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0, 0, 0, 0, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 26, 26, 26, 26, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 4, 4, 4, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 54, 54, 54, 54, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 26, 26, + 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 26, 26, 26, 26, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 242, 54, + 54, 54, 54, 54, 54, 54, 54, 242, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 242, 54, 54, 54, 54, 54, 54, 54, 54, 242, 0, 0, 0, 0, 0, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, - 24, 24, 24, 24, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, + 24, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 242, 242, 242, - 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 498, 498, 498, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 242, 242, 242, 242, 242, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 498, 54, 54, 54, 54, 54, 54, 54, 54, + 498, 498, 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 0, - 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 0, 0, 0, 0, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, - 499, 499, 499, 499, 499, 499, 0, 499, 499, 0, 500, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, - 0, 500, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, + 500, 500, 500, 0, 500, 500, 0, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 0, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 501, 0, 501, 501, 501, 501, 501, 501, 501, 0, 501, 501, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 102, 102, 101, 101, 101, 0, 101, 101, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 101, 102, 102, 101, 101, 101, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 54, 54, 54, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, 0, 54, 0, 0, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 4, - 26, 26, 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 26, 26, 26, 26, - 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, - 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 54, 54, 0, 0, 0, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 4, 26, 26, 26, 26, + 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 26, 26, 26, 26, 26, 26, 26, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, - 0, 0, 0, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 26, 26, 0, 0, - 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, 0, 0, 0, 26, 26, + 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 26, 26, 0, 0, 0, 4, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 26, 26, 54, 54, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 26, 26, 54, 54, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 54, 24, 24, 24, 0, 24, 24, 0, 0, 0, 0, 0, 24, - 24, 24, 24, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 26, 26, 26, 26, 54, 24, 24, 24, 0, 24, 24, 0, 0, 0, 0, 0, 24, 24, 24, 24, + 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 0, 0, 24, 24, 24, 0, 0, 0, 0, 24, 25, 21, 22, 359, 26, - 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, - 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 4, 54, + 54, 0, 0, 24, 24, 24, 0, 0, 0, 0, 24, 25, 21, 22, 360, 26, 26, 26, 26, + 26, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 24, 24, 0, 0, 0, 0, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 0, 0, 0, 0, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 26, 26, - 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, - 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3473,7 +3524,7 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 25, 21, 22, 360, 361, 362, 363, 364, 365, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -3498,7 +3549,7 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, - 4, 4, 4, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 4, 4, 4, 0, 0, 0, 0, 25, 21, 22, 360, 361, 362, 363, 364, 365, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 54, 54, 24, 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -3974,12 +4025,12 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 501, 501, 501, - 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 502, 24, 24, 24, 24, 24, 24, 24, 102, + 502, 502, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 24, 24, 24, 24, 24, 24, 24, 102, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4023,15 +4074,15 @@ static const unsigned short index2[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 358, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 4, 4, + 0, 0, 359, 359, 25, 21, 22, 360, 361, 362, 363, 364, 365, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 4, 4, 4, 4, 4, 4, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 4, 4, 4, 4, 4, 4, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4089,30 +4140,30 @@ static const unsigned short index2[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 387, 54, 54, 54, 54, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -4124,23 +4175,23 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, + 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -4148,7 +4199,7 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 388, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, @@ -4159,68 +4210,68 @@ static const unsigned short index2[] = { 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, - 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, @@ -4233,8 +4284,8 @@ static const unsigned short index2[] = { 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, }; /* Returns the numeric value as double for Unicode characters @@ -4282,6 +4333,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x24EA: case 0x24FF: case 0x3007: + case 0x6D1E: case 0x96F6: case 0xA620: case 0xA6EF: @@ -4713,6 +4765,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1ECA0: case 0x1ECB4: return (double) 100000.0; + case 0x5146: case 0x16B5E: return (double) 1000000.0; case 0x1ECA1: @@ -4721,11 +4774,14 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x5104: case 0x16B5F: return (double) 100000000.0; + case 0x79ED: + return (double) 1000000000.0; case 0x16B60: return (double) 10000000000.0; - case 0x5146: case 0x16B61: return (double) 1000000000000.0; + case 0x4EAC: + return (double) 1e+16; case 0x216A: case 0x217A: case 0x246A: @@ -4865,7 +4921,10 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x3221: case 0x3281: case 0x3483: + case 0x4E24: case 0x4E8C: + case 0x4FE9: + case 0x5006: case 0x5169: case 0x5F0D: case 0x5F10: @@ -5008,6 +5067,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1EC7B: case 0x1ED0B: return (double) 20.0; + case 0x7695: case 0x1011A: case 0x102F4: case 0x109D3: @@ -5894,6 +5954,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x3286: case 0x3B4D: case 0x4E03: + case 0x62D0: case 0x67D2: case 0x6F06: case 0xA627: @@ -6198,6 +6259,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x4E5D: case 0x5EFE: case 0x7396: + case 0x920E: + case 0x94A9: case 0xA629: case 0xA6EE: case 0xA8D9: diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 269f46914f263d..bf5605686f8df7 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -3,7 +3,7 @@ #include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK #include "pycore_typevarobject.h" // _PyTypeAlias_Type #include "pycore_unionobject.h" -#include "structmember.h" + static PyObject *make_union(PyObject *); @@ -186,28 +186,21 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) { PyObject *qualname = NULL; PyObject *module = NULL; - PyObject *tmp; PyObject *r = NULL; - int err; + int rc; if (p == (PyObject *)&_PyNone_Type) { return _PyUnicodeWriter_WriteASCIIString(writer, "None", 4); } - if (PyObject_GetOptionalAttr(p, &_Py_ID(__origin__), &tmp) < 0) { - goto exit; + if ((rc = PyObject_HasAttrWithError(p, &_Py_ID(__origin__))) > 0 && + (rc = PyObject_HasAttrWithError(p, &_Py_ID(__args__))) > 0) + { + // It looks like a GenericAlias + goto use_repr; } - - if (tmp) { - Py_DECREF(tmp); - if (PyObject_GetOptionalAttr(p, &_Py_ID(__args__), &tmp) < 0) { - goto exit; - } - if (tmp) { - // It looks like a GenericAlias - Py_DECREF(tmp); - goto use_repr; - } + if (rc < 0) { + goto exit; } if (PyObject_GetOptionalAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { @@ -244,9 +237,9 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) if (r == NULL) { return -1; } - err = _PyUnicodeWriter_WriteStr(writer, r); + rc = _PyUnicodeWriter_WriteStr(writer, r); Py_DECREF(r); - return err; + return rc; } static PyObject * @@ -273,7 +266,7 @@ union_repr(PyObject *self) } static PyMemberDef union_members[] = { - {"__args__", T_OBJECT, offsetof(unionobject, args), READONLY}, + {"__args__", _Py_T_OBJECT, offsetof(unionobject, args), Py_READONLY}, {0} }; @@ -331,7 +324,8 @@ union_parameters(PyObject *self, void *Py_UNUSED(unused)) } static PyGetSetDef union_properties[] = { - {"__parameters__", union_parameters, (setter)NULL, "Type variables in the types.UnionType.", NULL}, + {"__parameters__", union_parameters, (setter)NULL, + PyDoc_STR("Type variables in the types.UnionType."), NULL}, {0} }; diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index e9563729bf82ba..df74be6aba7244 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -1,8 +1,9 @@ #include "Python.h" #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_weakref.h" // _PyWeakref_GET_REF() -#include "structmember.h" // PyMemberDef + #define GET_WEAKREFS_LISTPTR(o) \ @@ -351,7 +352,7 @@ weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs) static PyMemberDef weakref_members[] = { - {"__callback__", T_OBJECT, offsetof(PyWeakReference, wr_callback), READONLY}, + {"__callback__", _Py_T_OBJECT, offsetof(PyWeakReference, wr_callback), Py_READONLY}, {NULL} /* Sentinel */ }; diff --git a/PC/_testconsole.c b/PC/_testconsole.c index 3221b985d01ba0..1dc0d230c4d7c3 100644 --- a/PC/_testconsole.c +++ b/PC/_testconsole.c @@ -35,6 +35,23 @@ PyModuleDef_Slot testconsole_slots[] = { {0, NULL}, }; +/*[python input] +class HANDLE_converter(CConverter): + type = 'void *' + format_unit = '"_Py_PARSE_UINTPTR"' + + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=380aa5c91076742b]*/ +/*[python end generated code:]*/ + /*[clinic input] module _testconsole @@ -116,6 +133,7 @@ _testconsole_read_output_impl(PyObject *module, PyObject *file) Py_RETURN_NONE; } + #include "clinic\_testconsole.c.h" PyMethodDef testconsole_methods[] = { diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h index b2f3b4ce8b08a2..99cd302ff34698 100644 --- a/PC/clinic/_testconsole.c.h +++ b/PC/clinic/_testconsole.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - #if defined(MS_WINDOWS) PyDoc_STRVAR(_testconsole_write_input__doc__, @@ -140,4 +139,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=208c72e2c873555b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f59fe72cd4e73704 input=a9049054013a1b77]*/ diff --git a/PC/clinic/_wmimodule.cpp.h b/PC/clinic/_wmimodule.cpp.h index bfcad41750b319..3ece5e6823b462 100644 --- a/PC/clinic/_wmimodule.cpp.h +++ b/PC/clinic/_wmimodule.cpp.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_wmi_exec_query__doc__, "exec_query($module, /, query)\n" "--\n" @@ -69,4 +68,4 @@ _wmi_exec_query(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj exit: return return_value; } -/*[clinic end generated code: output=923d09bee1d15c5f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=53821e597fc2aca4 input=a9049054013a1b77]*/ diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h index 94e17306f2258e..54ae61bd4f10a9 100644 --- a/PC/clinic/msvcrtmodule.c.h +++ b/PC/clinic/msvcrtmodule.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(msvcrt_heapmin__doc__, "heapmin($module, /)\n" "--\n" @@ -59,11 +53,11 @@ msvcrt_locking(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("locking", nargs, 3, 3)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -105,11 +99,11 @@ msvcrt_setmode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("setmode", nargs, 2, 2)) { goto exit; } - fd = _PyLong_AsInt(args[0]); + fd = PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -154,7 +148,7 @@ msvcrt_open_osfhandle(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!handle && PyErr_Occurred()) { goto exit; } - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -189,7 +183,7 @@ msvcrt_get_osfhandle(PyObject *module, PyObject *arg) int fd; void *_return_value; - fd = _PyLong_AsInt(arg); + fd = PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } @@ -207,7 +201,7 @@ PyDoc_STRVAR(msvcrt_kbhit__doc__, "kbhit($module, /)\n" "--\n" "\n" -"Return true if a keypress is waiting to be read."); +"Returns a nonzero value if a keypress is waiting to be read. Otherwise, return 0."); #define MSVCRT_KBHIT_METHODDEF \ {"kbhit", (PyCFunction)msvcrt_kbhit, METH_NOARGS, msvcrt_kbhit__doc__}, @@ -514,7 +508,7 @@ msvcrt_CrtSetReportFile(PyObject *module, PyObject *const *args, Py_ssize_t narg if (!_PyArg_CheckPositional("CrtSetReportFile", nargs, 2, 2)) { goto exit; } - type = _PyLong_AsInt(args[0]); + type = PyLong_AsInt(args[0]); if (type == -1 && PyErr_Occurred()) { goto exit; } @@ -561,11 +555,11 @@ msvcrt_CrtSetReportMode(PyObject *module, PyObject *const *args, Py_ssize_t narg if (!_PyArg_CheckPositional("CrtSetReportMode", nargs, 2, 2)) { goto exit; } - type = _PyLong_AsInt(args[0]); + type = PyLong_AsInt(args[0]); if (type == -1 && PyErr_Occurred()) { goto exit; } - mode = _PyLong_AsInt(args[1]); + mode = PyLong_AsInt(args[1]); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -604,7 +598,7 @@ msvcrt_set_error_mode(PyObject *module, PyObject *arg) int mode; long _return_value; - mode = _PyLong_AsInt(arg); + mode = PyLong_AsInt(arg); if (mode == -1 && PyErr_Occurred()) { goto exit; } @@ -701,4 +695,4 @@ msvcrt_SetErrorMode(PyObject *module, PyObject *arg) #ifndef MSVCRT_GETERRORMODE_METHODDEF #define MSVCRT_GETERRORMODE_METHODDEF #endif /* !defined(MSVCRT_GETERRORMODE_METHODDEF) */ -/*[clinic end generated code: output=9dd12bf210e362a4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=525ec6ac4e3cb4f2 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 2aa0698185960b..7507c1151a9840 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_long.h" // _PyLong_UnsignedLong_Converter() #if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) @@ -92,53 +92,26 @@ winreg_HKEYType___enter__(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) #if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) PyDoc_STRVAR(winreg_HKEYType___exit____doc__, -"__exit__($self, /, exc_type, exc_value, traceback)\n" +"__exit__($self, exc_type, exc_value, traceback, /)\n" "--\n" "\n"); #define WINREG_HKEYTYPE___EXIT___METHODDEF \ - {"__exit__", _PyCFunction_CAST(winreg_HKEYType___exit__), METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, + {"__exit__", _PyCFunction_CAST(winreg_HKEYType___exit__), METH_FASTCALL, winreg_HKEYType___exit____doc__}, static PyObject * winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, PyObject *exc_value, PyObject *traceback); static PyObject * -winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 3 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(exc_type), &_Py_ID(exc_value), &_Py_ID(traceback), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"exc_type", "exc_value", "traceback", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "__exit__", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[3]; PyObject *exc_type; PyObject *exc_value; PyObject *traceback; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_CheckPositional("__exit__", nargs, 3, 3)) { goto exit; } exc_type = args[0]; @@ -401,7 +374,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto skip_optional_pos; } if (args[2]) { - reserved = _PyLong_AsInt(args[2]); + reserved = PyLong_AsInt(args[2]); if (reserved == -1 && PyErr_Occurred()) { goto exit; } @@ -409,7 +382,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto skip_optional_pos; } } - access = _PyLong_AsInt(args[3]); + access = PyLong_AsInt(args[3]); if (access == -1 && PyErr_Occurred()) { goto exit; } @@ -579,7 +552,7 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto skip_optional_pos; } if (args[2]) { - access = _PyLong_AsInt(args[2]); + access = PyLong_AsInt(args[2]); if (access == -1 && PyErr_Occurred()) { goto exit; } @@ -587,7 +560,7 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto skip_optional_pos; } } - reserved = _PyLong_AsInt(args[3]); + reserved = PyLong_AsInt(args[3]); if (reserved == -1 && PyErr_Occurred()) { goto exit; } @@ -695,7 +668,7 @@ winreg_EnumKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } - index = _PyLong_AsInt(args[1]); + index = PyLong_AsInt(args[1]); if (index == -1 && PyErr_Occurred()) { goto exit; } @@ -752,7 +725,7 @@ winreg_EnumValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } - index = _PyLong_AsInt(args[1]); + index = PyLong_AsInt(args[1]); if (index == -1 && PyErr_Occurred()) { goto exit; } @@ -1016,7 +989,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje goto skip_optional_pos; } if (args[2]) { - reserved = _PyLong_AsInt(args[2]); + reserved = PyLong_AsInt(args[2]); if (reserved == -1 && PyErr_Occurred()) { goto exit; } @@ -1024,7 +997,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje goto skip_optional_pos; } } - access = _PyLong_AsInt(args[3]); + access = PyLong_AsInt(args[3]); if (access == -1 && PyErr_Occurred()) { goto exit; } @@ -1133,7 +1106,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } if (args[2]) { - reserved = _PyLong_AsInt(args[2]); + reserved = PyLong_AsInt(args[2]); if (reserved == -1 && PyErr_Occurred()) { goto exit; } @@ -1141,7 +1114,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto skip_optional_pos; } } - access = _PyLong_AsInt(args[3]); + access = PyLong_AsInt(args[3]); if (access == -1 && PyErr_Occurred()) { goto exit; } @@ -1788,4 +1761,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) #ifndef WINREG_QUERYREFLECTIONKEY_METHODDEF #define WINREG_QUERYREFLECTIONKEY_METHODDEF #endif /* !defined(WINREG_QUERYREFLECTIONKEY_METHODDEF) */ -/*[clinic end generated code: output=d2bf1f58ad07e5f8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d7ae41899af53d7c input=a9049054013a1b77]*/ diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h index 241d547c267a4c..b8c8e7d04a699f 100644 --- a/PC/clinic/winsound.c.h +++ b/PC/clinic/winsound.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(winsound_PlaySound__doc__, "PlaySound($module, /, sound, flags)\n" "--\n" @@ -63,7 +62,7 @@ winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto exit; } sound = args[0]; - flags = _PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -128,11 +127,11 @@ winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec if (!args) { goto exit; } - frequency = _PyLong_AsInt(args[0]); + frequency = PyLong_AsInt(args[0]); if (frequency == -1 && PyErr_Occurred()) { goto exit; } - duration = _PyLong_AsInt(args[1]); + duration = PyLong_AsInt(args[1]); if (duration == -1 && PyErr_Occurred()) { goto exit; } @@ -196,7 +195,7 @@ winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, if (!noptargs) { goto skip_optional_pos; } - type = _PyLong_AsInt(args[0]); + type = PyLong_AsInt(args[0]); if (type == -1 && PyErr_Occurred()) { goto exit; } @@ -206,4 +205,4 @@ winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=f70b7730127208d8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=21584101f656198f input=a9049054013a1b77]*/ diff --git a/PC/config.c b/PC/config.c index 88f69758aac764..da2bde640961e0 100644 --- a/PC/config.c +++ b/PC/config.c @@ -22,6 +22,7 @@ extern PyObject* PyInit__sha1(void); extern PyObject* PyInit__sha2(void); extern PyObject* PyInit__sha3(void); extern PyObject* PyInit__statistics(void); +extern PyObject* PyInit__sysconfig(void); extern PyObject* PyInit__typing(void); extern PyObject* PyInit__blake2(void); extern PyObject* PyInit_time(void); @@ -102,6 +103,7 @@ struct _inittab _PyImport_Inittab[] = { {"_sha2", PyInit__sha2}, {"_sha3", PyInit__sha3}, {"_blake2", PyInit__blake2}, + {"_sysconfig", PyInit__sysconfig}, {"time", PyInit_time}, {"_thread", PyInit__thread}, {"_tokenize", PyInit__tokenize}, diff --git a/PC/launcher2.c b/PC/launcher2.c index bb500d4b6bfb07..116091f01227b8 100644 --- a/PC/launcher2.c +++ b/PC/launcher2.c @@ -195,6 +195,13 @@ join(wchar_t *buffer, size_t bufferLength, const wchar_t *fragment) } +bool +split_parent(wchar_t *buffer, size_t bufferLength) +{ + return SUCCEEDED(PathCchRemoveFileSpec(buffer, bufferLength)); +} + + int _compare(const wchar_t *x, int xLen, const wchar_t *y, int yLen) { @@ -414,8 +421,8 @@ typedef struct { // if true, treats 'tag' as a non-PEP 514 filter bool oldStyleTag; // if true, ignores 'tag' when a high priority environment is found - // gh-92817: This is currently set when a tag is read from configuration or - // the environment, rather than the command line or a shebang line, and the + // gh-92817: This is currently set when a tag is read from configuration, + // the environment, or a shebang, rather than the command line, and the // only currently possible high priority environment is an active virtual // environment bool lowPriorityTag; @@ -794,6 +801,8 @@ searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength) } } + debug(L"# Search PATH for %s\n", filename); + wchar_t pathVariable[MAXLEN]; int n = GetEnvironmentVariableW(L"PATH", pathVariable, MAXLEN); if (!n) { @@ -1031,8 +1040,11 @@ checkShebang(SearchInfo *search) debug(L"Shebang: %s\n", shebang); // Handle shebangs that we should search PATH for + int executablePathWasSetByUsrBinEnv = 0; exitCode = searchPath(search, shebang, shebangLength); - if (exitCode != RC_NO_SHEBANG) { + if (exitCode == 0) { + executablePathWasSetByUsrBinEnv = 1; + } else if (exitCode != RC_NO_SHEBANG) { return exitCode; } @@ -1067,7 +1079,7 @@ checkShebang(SearchInfo *search) search->tagLength = commandLength; // If we had 'python3.12.exe' then we want to strip the suffix // off of the tag - if (search->tagLength > 4) { + if (search->tagLength >= 4) { const wchar_t *suffix = &search->tag[search->tagLength - 4]; if (0 == _comparePath(suffix, 4, L".exe", -1)) { search->tagLength -= 4; @@ -1075,13 +1087,14 @@ checkShebang(SearchInfo *search) } // If we had 'python3_d' then we want to strip the '_d' (any // '.exe' is already gone) - if (search->tagLength > 2) { + if (search->tagLength >= 2) { const wchar_t *suffix = &search->tag[search->tagLength - 2]; if (0 == _comparePath(suffix, 2, L"_d", -1)) { search->tagLength -= 2; } } search->oldStyleTag = true; + search->lowPriorityTag = true; search->executableArgs = &command[commandLength]; search->executableArgsLength = shebangLength - commandLength; if (search->tag && search->tagLength) { @@ -1095,6 +1108,11 @@ checkShebang(SearchInfo *search) } } + // Didn't match a template, but we found it on PATH + if (executablePathWasSetByUsrBinEnv) { + return 0; + } + // Unrecognised executables are first tried as command aliases commandLength = 0; while (commandLength < shebangLength && !isspace(shebang[commandLength])) { @@ -1765,7 +1783,15 @@ virtualenvSearch(const SearchInfo *search, EnvironmentInfo **result) return 0; } - if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(buffer)) { + DWORD attr = GetFileAttributesW(buffer); + if (INVALID_FILE_ATTRIBUTES == attr && search->lowPriorityTag) { + if (!split_parent(buffer, MAXLEN) || !join(buffer, MAXLEN, L"python.exe")) { + return 0; + } + attr = GetFileAttributesW(buffer); + } + + if (INVALID_FILE_ATTRIBUTES == attr) { debug(L"Python executable %s missing from virtual env\n", buffer); return 0; } diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index afc810adcf7499..5ff703217b421f 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -38,13 +38,14 @@ class HANDLE_converter(CConverter): type = 'void *' format_unit = '"_Py_PARSE_UINTPTR"' - def parse_arg(self, argname, displayname): - return """ + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" {paramname} = PyLong_AsVoidPtr({argname}); if (!{paramname} && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) class HANDLE_return_converter(CReturnConverter): type = 'void *' @@ -74,7 +75,7 @@ class wchar_t_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = PyUnicode_FromOrdinal(_return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=1e8e9fa3538ec08f]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=ff031be44ab3250d]*/ /*[clinic input] module msvcrt @@ -219,12 +220,12 @@ msvcrt_get_osfhandle_impl(PyObject *module, int fd) /*[clinic input] msvcrt.kbhit -> long -Return true if a keypress is waiting to be read. +Returns a nonzero value if a keypress is waiting to be read. Otherwise, return 0. [clinic start generated code]*/ static long msvcrt_kbhit_impl(PyObject *module) -/*[clinic end generated code: output=940dfce6587c1890 input=e70d678a5c2f6acc]*/ +/*[clinic end generated code: output=940dfce6587c1890 input=d0f4cb3289ff51e2]*/ { return _kbhit(); } @@ -614,6 +615,10 @@ exec_module(PyObject* m) INSERTPTR(m, "CRTDBG_FILE_STDERR", _CRTDBG_FILE_STDERR); INSERTPTR(m, "CRTDBG_FILE_STDOUT", _CRTDBG_FILE_STDOUT); INSERTPTR(m, "CRTDBG_REPORT_FILE", _CRTDBG_REPORT_FILE); + INSERTINT(m, "OUT_TO_DEFAULT", _OUT_TO_DEFAULT); + INSERTINT(m, "OUT_TO_STDERR", _OUT_TO_STDERR); + INSERTINT(m, "OUT_TO_MSGBOX", _OUT_TO_MSGBOX); + INSERTINT(m, "REPORT_ERRMODE", _REPORT_ERRMODE); #endif #undef INSERTINT diff --git a/PC/python3dll.c b/PC/python3dll.c index 0b54c5a707231c..7ee11746770442 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -69,6 +69,7 @@ EXPORT_FUNC(Py_Initialize) EXPORT_FUNC(Py_InitializeEx) EXPORT_FUNC(Py_Is) EXPORT_FUNC(Py_IsFalse) +EXPORT_FUNC(Py_IsFinalizing) EXPORT_FUNC(Py_IsInitialized) EXPORT_FUNC(Py_IsNone) EXPORT_FUNC(Py_IsTrue) @@ -172,7 +173,9 @@ EXPORT_FUNC(PyDict_Copy) EXPORT_FUNC(PyDict_DelItem) EXPORT_FUNC(PyDict_DelItemString) EXPORT_FUNC(PyDict_GetItem) +EXPORT_FUNC(PyDict_GetItemRef) EXPORT_FUNC(PyDict_GetItemString) +EXPORT_FUNC(PyDict_GetItemStringRef) EXPORT_FUNC(PyDict_GetItemWithError) EXPORT_FUNC(PyDict_Items) EXPORT_FUNC(PyDict_Keys) @@ -329,6 +332,7 @@ EXPORT_FUNC(PyList_SetSlice) EXPORT_FUNC(PyList_Size) EXPORT_FUNC(PyList_Sort) EXPORT_FUNC(PyLong_AsDouble) +EXPORT_FUNC(PyLong_AsInt) EXPORT_FUNC(PyLong_AsLong) EXPORT_FUNC(PyLong_AsLongAndOverflow) EXPORT_FUNC(PyLong_AsLongLong) @@ -356,6 +360,8 @@ EXPORT_FUNC(PyMapping_GetOptionalItem) EXPORT_FUNC(PyMapping_GetOptionalItemString) EXPORT_FUNC(PyMapping_HasKey) EXPORT_FUNC(PyMapping_HasKeyString) +EXPORT_FUNC(PyMapping_HasKeyStringWithError) +EXPORT_FUNC(PyMapping_HasKeyWithError) EXPORT_FUNC(PyMapping_Items) EXPORT_FUNC(PyMapping_Keys) EXPORT_FUNC(PyMapping_Length) @@ -477,6 +483,8 @@ EXPORT_FUNC(PyObject_GetOptionalAttrString) EXPORT_FUNC(PyObject_GetTypeData) EXPORT_FUNC(PyObject_HasAttr) EXPORT_FUNC(PyObject_HasAttrString) +EXPORT_FUNC(PyObject_HasAttrStringWithError) +EXPORT_FUNC(PyObject_HasAttrWithError) EXPORT_FUNC(PyObject_Hash) EXPORT_FUNC(PyObject_HashNotImplemented) EXPORT_FUNC(PyObject_Init) @@ -681,6 +689,8 @@ EXPORT_FUNC(PyUnicode_DecodeUTF8Stateful) EXPORT_FUNC(PyUnicode_EncodeCodePage) EXPORT_FUNC(PyUnicode_EncodeFSDefault) EXPORT_FUNC(PyUnicode_EncodeLocale) +EXPORT_FUNC(PyUnicode_EqualToUTF8) +EXPORT_FUNC(PyUnicode_EqualToUTF8AndSize) EXPORT_FUNC(PyUnicode_Find) EXPORT_FUNC(PyUnicode_FindChar) EXPORT_FUNC(PyUnicode_Format) diff --git a/PC/winreg.c b/PC/winreg.c index 5252f78a9bdf72..77b80217ac0ab1 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -15,7 +15,7 @@ #include "Python.h" #include "pycore_object.h" // _PyObject_Init() #include "pycore_moduleobject.h" -#include "structmember.h" // PyMemberDef + #include #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) @@ -220,14 +220,17 @@ class DWORD_converter(unsigned_long_converter): class HKEY_converter(CConverter): type = 'HKEY' converter = 'clinic_HKEY_converter' - - def parse_arg(self, argname, displayname): - return """ - if (!{converter}(_PyModule_GetState(module), {argname}, &{paramname})) {{{{ - goto exit; - }}}} - """.format(argname=argname, paramname=self.parser_name, - converter=self.converter) + broken_limited_capi = True + + def parse_arg(self, argname, displayname, *, limited_capi): + assert not limited_capi + return self.format_code(""" + if (!{converter}(_PyModule_GetState(module), {argname}, &{paramname})) {{{{ + goto exit; + }}}} + """, + argname=argname, + converter=self.converter) class HKEY_return_converter(CReturnConverter): type = 'HKEY' @@ -249,7 +252,7 @@ class self_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = (PyObject *)_return_value;\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=17e645060c7b8ae1]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=4979f33998ffb6f8]*/ #include "clinic/winreg.c.h" @@ -323,12 +326,14 @@ winreg.HKEYType.__exit__ exc_type: object exc_value: object traceback: object + / + [clinic start generated code]*/ static PyObject * winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, PyObject *exc_value, PyObject *traceback) -/*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/ +/*[clinic end generated code: output=923ebe7389e6a263 input=1eac83cd06962689]*/ { winreg_state *st = _PyType_GetModuleState(Py_TYPE(self)); assert(st != NULL); @@ -352,7 +357,7 @@ static struct PyMethodDef PyHKEY_methods[] = { #define OFF(e) offsetof(PyHKEYObject, e) static PyMemberDef PyHKEY_memberlist[] = { - {"handle", T_INT, OFF(hkey), READONLY}, + {"handle", Py_T_INT, OFF(hkey), Py_READONLY}, {NULL} /* Sentinel */ }; diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 87f08e857d0e29..aaa63fe9456fb7 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -172,7 +172,14 @@ - + + + + + + + + @@ -192,6 +199,7 @@ + @@ -217,6 +225,7 @@ + diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index 3dae8cca7a2d56..279736b0fbbb13 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -124,6 +124,9 @@ Source Files + + Source Files + Source Files @@ -280,6 +283,9 @@ Source Files + + Source Files + Source Files @@ -391,7 +397,28 @@ Source Files - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index de17d74c52e56f..0f33c5a76ade9d 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -99,7 +99,10 @@ + + + @@ -110,6 +113,7 @@ + diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index 637f7178d39d0e..4ba6011d8af5b9 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -27,9 +27,15 @@ Source Files + + Source Files + Source Files + + Source Files + Source Files @@ -60,6 +66,9 @@ Source Files + + Source Files + Source Files diff --git a/PCbuild/_testclinic.vcxproj b/PCbuild/_testclinic.vcxproj new file mode 100644 index 00000000000000..e319b3c0f42e0f --- /dev/null +++ b/PCbuild/_testclinic.vcxproj @@ -0,0 +1,110 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + ARM + + + PGInstrument + ARM64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + ARM + + + PGUpdate + ARM64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {A840DDFB-ED50-484B-B527-B32E7CF90FD5} + _testclinic + Win32Proj + false + + + + + DynamicLibrary + NotSet + + + + .pyd + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + \ No newline at end of file diff --git a/PCbuild/_testclinic.vcxproj.filters b/PCbuild/_testclinic.vcxproj.filters new file mode 100644 index 00000000000000..4a2987eb27b223 --- /dev/null +++ b/PCbuild/_testclinic.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {5b0a9282-a01c-4b83-9fd4-6deb6c558f9c} + + + {6a89c8a9-5b51-4525-ac5c-7d0a22f9657e} + + + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/PCbuild/_testclinic_limited.vcxproj b/PCbuild/_testclinic_limited.vcxproj new file mode 100644 index 00000000000000..b00b2be491b423 --- /dev/null +++ b/PCbuild/_testclinic_limited.vcxproj @@ -0,0 +1,109 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + ARM + + + PGInstrument + ARM64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + ARM + + + PGUpdate + ARM64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410} + _testclinic_limited + Win32Proj + + + + + DynamicLibrary + NotSet + + + + .pyd + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + \ No newline at end of file diff --git a/PCbuild/_testclinic_limited.vcxproj.filters b/PCbuild/_testclinic_limited.vcxproj.filters new file mode 100644 index 00000000000000..8ecdd99a4ac220 --- /dev/null +++ b/PCbuild/_testclinic_limited.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {2422278e-eeeb-4241-8182-433e2bc5a7fc} + + + {41f1cd52-b682-46aa-a7fd-7bdf81a18010} + + + + + Source Files + + + + + Resource Files + + + diff --git a/PCbuild/_testinternalcapi.vcxproj b/PCbuild/_testinternalcapi.vcxproj index 6c5b12cd40e983..a729ab3877d91f 100644 --- a/PCbuild/_testinternalcapi.vcxproj +++ b/PCbuild/_testinternalcapi.vcxproj @@ -94,6 +94,9 @@ + + + diff --git a/PCbuild/_testinternalcapi.vcxproj.filters b/PCbuild/_testinternalcapi.vcxproj.filters index 7734da0b7b426b..9c8a5d793ee0f4 100644 --- a/PCbuild/_testinternalcapi.vcxproj.filters +++ b/PCbuild/_testinternalcapi.vcxproj.filters @@ -12,6 +12,12 @@ Source Files + + Source Files + + + Source Files + diff --git a/PCbuild/build.bat b/PCbuild/build.bat index d333ceabd2e53a..e61267b5852a8f 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -33,6 +33,7 @@ echo. -k Attempt to kill any running Pythons before building (usually done echo. automatically by the pythoncore project) echo. --pgo Build with Profile-Guided Optimization. This flag echo. overrides -c and -d +echo. --disable-gil Enable experimental support for running without the GIL. echo. --test-marker Enable the test marker within the build. echo. --regen Regenerate all opcodes, grammar and tokens. echo. @@ -80,6 +81,7 @@ if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts 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"=="--disable-gil" (set UseDisableGil=true) & shift & goto CheckOpts if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts if "%~1"=="-V" shift & goto Version if "%~1"=="--regen" (set Regen=true) & shift & goto CheckOpts @@ -172,6 +174,7 @@ echo on /p:IncludeExternals=%IncludeExternals%^ /p:IncludeCTypes=%IncludeCTypes%^ /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ + /p:DisableGil=%UseDisableGil%^ /p:UseTestMarker=%UseTestMarker% %GITProperty%^ %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index 7af5503d80a0fc..d3f62c93869003 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -52,7 +52,7 @@ @if "%_Py_NUGET%"=="" (set _Py_NUGET=%_Py_EXTERNALS_DIR%\nuget.exe) @if "%_Py_NUGET_URL%"=="" (set _Py_NUGET_URL=https://aka.ms/nugetclidl) @if NOT exist "%_Py_NUGET%" ( - @echo Downloading nuget... + @if not "%_Py_Quiet%"=="1" @echo Downloading nuget... @rem NB: Must use single quotes around NUGET here, NOT double! @rem Otherwise, a space in the path would break things @rem If it fails, retry with any available copy of Python @@ -63,7 +63,11 @@ ) @if not "%_Py_Quiet%"=="1" @echo Installing Python via nuget... -@"%_Py_NUGET%" install pythonx86 -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%" +@if not "%_Py_Quiet%"=="1" ( + @"%_Py_NUGET%" install pythonx86 -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%" +) else ( + @"%_Py_NUGET%" install pythonx86 -Verbosity quiet -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%" +) @rem Quote it here; it's not quoted later because "py -x.y" wouldn't work @if not errorlevel 1 (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") & (set _Py_Python_Source=found on nuget.org) & goto :found diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 257b360ba3506f..94437f054d788c 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.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.4 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.9 -set libraries=%libraries% sqlite-3.42.0.0 +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.11 +set libraries=%libraries% sqlite-3.43.1.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.0 set libraries=%libraries% xz-5.2.5 @@ -76,7 +76,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.4 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.9 +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.11 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.13.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index 46d6961eea0ac5..b7b78be768d7ec 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -77,7 +77,7 @@ - + diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index f8f1b83db97e8e..a0b5fbd1304b41 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -10,42 +10,43 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" ProjectSection(ProjectDependencies) = postProject - {9E48B300-37D1-11DD-8C41-005056C00008} = {9E48B300-37D1-11DD-8C41-005056C00008} - {9EC7190A-249F-4180-A900-548FDCF3055F} = {9EC7190A-249F-4180-A900-548FDCF3055F} - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} = {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} = {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} - {54B1431F-B86B-4ACB-B28C-88BCF93191D8} = {54B1431F-B86B-4ACB-B28C-88BCF93191D8} - {F749B822-B489-4CA5-A3AD-CE078F5F338A} = {F749B822-B489-4CA5-A3AD-CE078F5F338A} - {D06B6426-4762-44CC-8BAD-D79052507F2F} = {D06B6426-4762-44CC-8BAD-D79052507F2F} - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} = {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} - {CB435430-EBB1-478B-8F4E-C256F6838F55} = {CB435430-EBB1-478B-8F4E-C256F6838F55} - {17E1E049-C309-4D79-843F-AE483C264AEA} = {17E1E049-C309-4D79-843F-AE483C264AEA} - {384C224A-7474-476E-A01B-750EA7DE918C} = {384C224A-7474-476E-A01B-750EA7DE918C} + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410} = {01FDF29A-40A1-46DF-84F5-85EBBD2A2410} + {0E9791DB-593A-465F-98BC-681011311617} = {0E9791DB-593A-465F-98BC-681011311617} + {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} {12728250-16EC-4DC6-94D7-E21DD88947F8} = {12728250-16EC-4DC6-94D7-E21DD88947F8} - {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} - {28B5D777-DDF2-4B6B-B34F-31D938813856} = {28B5D777-DDF2-4B6B-B34F-31D938813856} - {31FFC478-7B4A-43E8-9954-8D03E2187E9C} = {31FFC478-7B4A-43E8-9954-8D03E2187E9C} - {F9D71780-F393-11E0-BE50-0800200C9A66} = {F9D71780-F393-11E0-BE50-0800200C9A66} - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} = {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} - {C6E20F84-3247-4AD6-B051-B073268F73BA} = {C6E20F84-3247-4AD6-B051-B073268F73BA} - {B244E787-C445-441C-BDF4-5A4F1A3A1E51} = {B244E787-C445-441C-BDF4-5A4F1A3A1E51} - {18CAE28C-B454-46C1-87A0-493D91D97F03} = {18CAE28C-B454-46C1-87A0-493D91D97F03} {13CECB97-4119-4316-9D42-8534019A5A44} = {13CECB97-4119-4316-9D42-8534019A5A44} - {885D4898-D08D-4091-9C40-C700CFE3FC5A} = {885D4898-D08D-4091-9C40-C700CFE3FC5A} + {16BFE6F0-22EF-40B5-B831-7E937119EF10} = {16BFE6F0-22EF-40B5-B831-7E937119EF10} + {17E1E049-C309-4D79-843F-AE483C264AEA} = {17E1E049-C309-4D79-843F-AE483C264AEA} + {18CAE28C-B454-46C1-87A0-493D91D97F03} = {18CAE28C-B454-46C1-87A0-493D91D97F03} + {2097F1C1-597C-4167-93E3-656A7D6339B2} = {2097F1C1-597C-4167-93E3-656A7D6339B2} + {28B5D777-DDF2-4B6B-B34F-31D938813856} = {28B5D777-DDF2-4B6B-B34F-31D938813856} + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} = {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} + {384C224A-7474-476E-A01B-750EA7DE918C} = {384C224A-7474-476E-A01B-750EA7DE918C} {447F05A8-F581-4CAC-A466-5AC7936E207E} = {447F05A8-F581-4CAC-A466-5AC7936E207E} - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} = {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} = {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} = {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} = {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} + {54B1431F-B86B-4ACB-B28C-88BCF93191D8} = {54B1431F-B86B-4ACB-B28C-88BCF93191D8} + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} = {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} + {6DAC66D9-E703-4624-BE03-49112AB5AA62} = {6DAC66D9-E703-4624-BE03-49112AB5AA62} {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} = {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} - {2097F1C1-597C-4167-93E3-656A7D6339B2} = {2097F1C1-597C-4167-93E3-656A7D6339B2} - {A2697BD3-28C1-4AEC-9106-8B748639FD16} = {A2697BD3-28C1-4AEC-9106-8B748639FD16} + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} = {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} + {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} + {885D4898-D08D-4091-9C40-C700CFE3FC5A} = {885D4898-D08D-4091-9C40-C700CFE3FC5A} {900342D7-516A-4469-B1AD-59A66E49A25F} = {900342D7-516A-4469-B1AD-59A66E49A25F} - {6DAC66D9-E703-4624-BE03-49112AB5AA62} = {6DAC66D9-E703-4624-BE03-49112AB5AA62} - {0E9791DB-593A-465F-98BC-681011311617} = {0E9791DB-593A-465F-98BC-681011311617} - {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} + {9E48B300-37D1-11DD-8C41-005056C00008} = {9E48B300-37D1-11DD-8C41-005056C00008} + {9EC7190A-249F-4180-A900-548FDCF3055F} = {9EC7190A-249F-4180-A900-548FDCF3055F} + {A2697BD3-28C1-4AEC-9106-8B748639FD16} = {A2697BD3-28C1-4AEC-9106-8B748639FD16} + {A840DDFB-ED50-484B-B527-B32E7CF90FD5} = {A840DDFB-ED50-484B-B527-B32E7CF90FD5} + {B244E787-C445-441C-BDF4-5A4F1A3A1E51} = {B244E787-C445-441C-BDF4-5A4F1A3A1E51} + {C6E20F84-3247-4AD6-B051-B073268F73BA} = {C6E20F84-3247-4AD6-B051-B073268F73BA} + {CB435430-EBB1-478B-8F4E-C256F6838F55} = {CB435430-EBB1-478B-8F4E-C256F6838F55} + {D06B6426-4762-44CC-8BAD-D79052507F2F} = {D06B6426-4762-44CC-8BAD-D79052507F2F} {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} = {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} - {16BFE6F0-22EF-40B5-B831-7E937119EF10} = {16BFE6F0-22EF-40B5-B831-7E937119EF10} + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} = {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} + {F749B822-B489-4CA5-A3AD-CE078F5F338A} = {F749B822-B489-4CA5-A3AD-CE078F5F338A} + {F9D71780-F393-11E0-BE50-0800200C9A66} = {F9D71780-F393-11E0-BE50-0800200C9A66} {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} = {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} = {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" @@ -76,6 +77,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testclinic", "_testclinic.vcxproj", "{A840DDFB-ED50-484B-B527-B32E7CF90FD5}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testinternalcapi", "_testinternalcapi.vcxproj", "{900342D7-516A-4469-B1AD-59A66E49A25F}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" @@ -154,6 +157,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_uuid", "_uuid.vcxproj", "{ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_wmi", "_wmi.vcxproj", "{54B1431F-B86B-4ACB-B28C-88BCF93191D8}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testclinic_limited", "_testclinic_limited.vcxproj", "{01FDF29A-40A1-46DF-84F5-85EBBD2A2410}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -430,38 +435,6 @@ Global {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32 {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64 {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM.ActiveCfg = Debug|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM.Build.0 = Debug|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM64.Build.0 = Debug|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM.ActiveCfg = Release|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM.Build.0 = Release|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM64.ActiveCfg = Release|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM64.Build.0 = Release|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64 {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM.ActiveCfg = Debug|ARM {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM.Build.0 = Debug|ARM {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -590,6 +563,38 @@ Global {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM.ActiveCfg = Debug|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM.Build.0 = Debug|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM64.Build.0 = Debug|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|Win32.ActiveCfg = Debug|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|Win32.Build.0 = Debug|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|x64.ActiveCfg = Debug|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|x64.Build.0 = Debug|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM.ActiveCfg = Release|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM.Build.0 = Release|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM64.ActiveCfg = Release|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM64.Build.0 = Release|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|Win32.ActiveCfg = Release|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|Win32.Build.0 = Release|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|x64.ActiveCfg = Release|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|x64.Build.0 = Release|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.ActiveCfg = Debug|ARM {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.Build.0 = Debug|ARM {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -1611,6 +1616,38 @@ Global {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|Win32.Build.0 = Release|Win32 {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|x64.ActiveCfg = Release|x64 {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|x64.Build.0 = Release|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|ARM.ActiveCfg = Debug|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|ARM.Build.0 = Debug|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|ARM64.Build.0 = Debug|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|Win32.ActiveCfg = Debug|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|Win32.Build.0 = Debug|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|x64.ActiveCfg = Debug|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Debug|x64.Build.0 = Debug|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|ARM.ActiveCfg = Release|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|ARM.Build.0 = Release|ARM + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|ARM64.ActiveCfg = Release|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|ARM64.Build.0 = Release|ARM64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|Win32.ActiveCfg = Release|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|Win32.Build.0 = Release|Win32 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|x64.ActiveCfg = Release|x64 + {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index fd928cafd77aaa..b8d2d3d265543f 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -40,6 +40,7 @@ $(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories) WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions) + Py_NOGIL=1;%(PreprocessorDefinitions) MaxSpeed true @@ -232,7 +233,10 @@ public override bool Execute() { - + + + + diff --git a/PCbuild/python.props b/PCbuild/python.props index d3586235c82652..496bc3dd4cf794 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -68,14 +68,14 @@ - $(ExternalsDir)sqlite-3.42.0.0\ + $(ExternalsDir)sqlite-3.43.1.0\ $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.5\ $(ExternalsDir)libffi-3.4.4\ $(libffiDir)$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-3.0.9\ - $(ExternalsDir)openssl-bin-3.0.9\$(ArchName)\ + $(ExternalsDir)openssl-3.0.11\ + $(ExternalsDir)openssl-bin-3.0.11\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.13\ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 760962e4c4b6a9..f240779d2a5d4e 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -166,6 +166,8 @@ + + @@ -174,6 +176,7 @@ + @@ -201,11 +204,11 @@ - + @@ -235,11 +238,15 @@ + + + + @@ -248,6 +255,8 @@ + + @@ -256,11 +265,15 @@ + + + + @@ -278,6 +291,7 @@ + @@ -297,6 +311,7 @@ + @@ -347,13 +362,16 @@ - + + + + + - @@ -424,6 +442,7 @@ + @@ -492,7 +511,14 @@ - + + + + + + + + @@ -520,6 +546,7 @@ + @@ -541,11 +568,14 @@ + + + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index aaebe1908e30da..6e13eb81018f9b 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -144,6 +144,9 @@ Include + + Include + Include @@ -288,7 +291,19 @@ Objects - + + Parser + + + Parser + + + Parser + + + Parser + + Parser @@ -297,9 +312,6 @@ PC - - Python - Python @@ -423,6 +435,18 @@ Include + + Include + + + Include + + + Include + + + Include + Include @@ -480,6 +504,9 @@ Include\cpython + + Include\cpython + Include\cpython @@ -513,9 +540,6 @@ Include\internal - - Include - Include\internal @@ -528,6 +552,9 @@ Include\internal + + Include\internal + Include\internal @@ -609,9 +636,15 @@ Include\internal + + Include\internal + Include\internal + + Include\internal + Include\internal @@ -624,6 +657,12 @@ Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -648,6 +687,12 @@ Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -672,6 +717,12 @@ Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -687,6 +738,12 @@ Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -729,6 +786,9 @@ Include\internal + + Include\internal + Modules\zlib @@ -911,6 +971,9 @@ Modules + + Modules + Modules @@ -1088,7 +1151,28 @@ Parser - + + Parser + + + Parser + + + Parser + + + Parser + + + Parser + + + Parser + + + Parser + + Parser @@ -1145,6 +1229,9 @@ Python + + Python + Python @@ -1202,6 +1289,9 @@ Source Files + + Source Files + Python @@ -1217,6 +1307,12 @@ Python + + Python + + + Python + Python diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index f0de142f0573b9..175ce918ac20f6 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -143,6 +143,8 @@ _overlapped _socket _testbuffer _testcapi +_testclinic +_testclinic_limited _testconsole _testimportmultiple _testmultiphase @@ -187,7 +189,7 @@ _ssl again when building. _sqlite3 - Wraps SQLite 3.42.0, which is itself built by sqlite3.vcxproj + Wraps SQLite 3.43.1, which is itself built by sqlite3.vcxproj Homepage: https://www.sqlite.org/ _tkinter @@ -250,9 +252,11 @@ against a profiling library and contain extra debug information. The PGUpdate configuration takes the profiling data and generates optimized binaries. -The build_pgo.bat script automates the creation of optimized binaries. -It creates the PGI files, runs the unit test suite or PyBench with the -PGI python, and finally creates the optimized files. +The build.bat script has an argument `--pgo` that automate the creation +of optimized binaries. +It creates the PGI files, runs the unit test suite with the PGI python, +and finally creates the optimized files. +You can customize the job for profiling with `--pgo-job ` option. See https://docs.microsoft.com/en-us/cpp/build/profile-guided-optimizations @@ -289,3 +293,31 @@ project, with some projects overriding certain specific values. The GUI doesn't always reflect the correct settings and may confuse the user with false information, especially for settings that automatically adapt for different configurations. + +Add a new project +----------------- + +For example, add a new _testclinic_limited project to build a new +_testclinic_limited extension, the file Modules/_testclinic_limited.c: + +* In PCbuild/, copy _testclinic.vcxproj to _testclinic_limited.vcxproj, + replace RootNamespace value with `_testclinic_limited`, replace + `_asyncio.c` with `_testclinic_limited.c`. +* Open Visual Studio, open PCbuild\pcbuild.sln solution, add the + PCbuild\_testclinic_limited.vcxproj project to the solution ("add existing + project). +* Add a dependency on the python project to the new _testclinic_limited + project. +* Save and exit Visual Studio. +* Add `;_testclinic_limited` to `` in + PCbuild\pcbuild.proj. +* Update "exts" in Tools\msi\lib\lib_files.wxs file or in + Tools\msi\test\test_files.wxs file (for tests). +* PC\layout\main.py needs updating if you add a test-only extension whose name + doesn't start with "_test". +* Add the extension to PCbuild\readme.txt (this file). +* Build Python from scratch (clean the solution) to check that the new project + is built successfully. +* Ensure the new .vcxproj and .vcxproj.filters files are added to your commit, + as well as the changes to pcbuild.sln, pcbuild.proj and any other modified + files. diff --git a/PCbuild/regen.targets b/PCbuild/regen.targets index 2dd786e5e82e36..cc9469c7ddd726 100644 --- a/PCbuild/regen.targets +++ b/PCbuild/regen.targets @@ -13,8 +13,6 @@ <_ASTOutputs Include="$(PySourcePath)Python\Python-ast.c"> -C - <_OpcodeSources Include="$(PySourcePath)Tools\build\generate_opcode_h.py;$(PySourcePath)Lib\opcode.py" /> - <_OpcodeOutputs Include="$(PySourcePath)Include\opcode.h;$(PySourcePath)Include\internal\pycore_opcode.h;$(PySourcePath)Python\opcode_targets.h" /> <_TokenSources Include="$(PySourcePath)Grammar\Tokens" /> <_TokenOutputs Include="$(PySourcePath)Doc\library\token-list.inc"> rst @@ -34,7 +32,7 @@ - @@ -55,16 +53,6 @@ WorkingDirectory="$(PySourcePath)" /> - - - - - - @@ -91,7 +79,7 @@ + DependsOnTargets="_TouchRegenSources;_RegenPegen;_RegenAST_H;_RegenTokens;_RegenKeywords;_RegenGlobalObjects"> diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index 29813c5a87fca7..332ba5edcf4082 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -32,7 +32,7 @@ set pcbuild=%~dp0 set suffix= set qmode= set dashO= -set regrtestargs= +set regrtestargs=--fast-ci set exe= :CheckOpts @@ -48,7 +48,7 @@ if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts if not defined prefix set prefix=%pcbuild%amd64 set exe=%prefix%\python%suffix%.exe -set cmd="%exe%" %dashO% -u -Wd -E -bb -m test %regrtestargs% +set cmd="%exe%" %dashO% -m test %regrtestargs% if defined qmode goto Qmode echo Deleting .pyc files ... diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index 36e0750220a30d..fb2d56af3fc372 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -1,7 +1,6 @@ #include #include "pegen.h" -#include "tokenizer.h" #include "string_parser.h" #include "pycore_runtime.h" // _PyRuntime @@ -998,18 +997,38 @@ _PyPegen_setup_full_format_spec(Parser *p, Token *colon, asdl_expr_seq *spec, in return NULL; } - // This is needed to keep compatibility with 3.11, where an empty format spec is parsed - // as an *empty* JoinedStr node, instead of having an empty constant in it. - if (asdl_seq_LEN(spec) == 1) { - expr_ty e = asdl_seq_GET(spec, 0); - if (e->kind == Constant_kind - && PyUnicode_Check(e->v.Constant.value) - && PyUnicode_GetLength(e->v.Constant.value) == 0) { - spec = _Py_asdl_expr_seq_new(0, arena); + // This is needed to keep compatibility with 3.11, where an empty format + // spec is parsed as an *empty* JoinedStr node, instead of having an empty + // constant in it. + Py_ssize_t n_items = asdl_seq_LEN(spec); + Py_ssize_t non_empty_count = 0; + for (Py_ssize_t i = 0; i < n_items; i++) { + expr_ty item = asdl_seq_GET(spec, i); + non_empty_count += !(item->kind == Constant_kind && + PyUnicode_CheckExact(item->v.Constant.value) && + PyUnicode_GET_LENGTH(item->v.Constant.value) == 0); + } + if (non_empty_count != n_items) { + asdl_expr_seq *resized_spec = + _Py_asdl_expr_seq_new(non_empty_count, p->arena); + if (resized_spec == NULL) { + return NULL; + } + Py_ssize_t j = 0; + for (Py_ssize_t i = 0; i < n_items; i++) { + expr_ty item = asdl_seq_GET(spec, i); + if (item->kind == Constant_kind && + PyUnicode_CheckExact(item->v.Constant.value) && + PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) { + continue; + } + asdl_seq_SET(resized_spec, j++, item); } + assert(j == non_empty_count); + spec = resized_spec; } - - expr_ty res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno, end_col_offset, p->arena); + expr_ty res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno, + end_col_offset, p->arena); if (!res) { return NULL; } diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index e9665dd808af39..f61099b97055ad 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -897,7 +897,7 @@ def visitModule(self, mod): } static PyMemberDef ast_type_members[] = { - {"__dictoffset__", T_PYSSIZET, offsetof(AST_object, dict), READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(AST_object, dict), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -1074,7 +1074,7 @@ def visitModule(self, mod): return 1; } - i = _PyLong_AsInt(obj); + i = PyLong_AsInt(obj); if (i == -1 && PyErr_Occurred()) return 1; *out = i; @@ -1208,6 +1208,9 @@ def visitModule(self, mod): self.emit('if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) {', 1) self.emit("return -1;", 2) self.emit('}', 1) + self.emit('if (PyModule_AddIntMacro(m, PyCF_OPTIMIZED_AST) < 0) {', 1) + self.emit("return -1;", 2) + self.emit('}', 1) for dfn in mod.dfns: self.visit(dfn) self.emit("return 0;", 1) @@ -1393,13 +1396,13 @@ class PartingShots(StaticVisitor): int starting_recursion_depth; /* Be careful here to prevent overflow. */ - int COMPILER_STACK_FRAME_SCALE = 3; + int COMPILER_STACK_FRAME_SCALE = 2; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { return 0; } - state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; - int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + state->recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state->recursion_depth = starting_recursion_depth; @@ -1542,7 +1545,6 @@ def generate_module_def(mod, metadata, f, internal_h): #include "pycore_ceval.h" // _Py_EnterRecursiveCall #include "pycore_interp.h" // _PyInterpreterState.ast #include "pycore_pystate.h" // _PyInterpreterState_GET() - #include "structmember.h" #include // Forward declaration @@ -1583,7 +1585,7 @@ def write_header(mod, metadata, f): # error "this header requires Py_BUILD_CORE define" #endif - #include "pycore_asdl.h" + #include "pycore_asdl.h" // _ASDL_SEQ_HEAD """).lstrip()) diff --git a/Parser/lexer/buffer.c b/Parser/lexer/buffer.c new file mode 100644 index 00000000000000..f6502bf8f7f2d1 --- /dev/null +++ b/Parser/lexer/buffer.c @@ -0,0 +1,76 @@ +#include "Python.h" +#include "errcode.h" + +#include "state.h" + +/* Traverse and remember all f-string buffers, in order to be able to restore + them after reallocating tok->buf */ +void +_PyLexer_remember_fstring_buffers(struct tok_state *tok) +{ + int index; + tokenizer_mode *mode; + + for (index = tok->tok_mode_stack_index; index >= 0; --index) { + mode = &(tok->tok_mode_stack[index]); + mode->f_string_start_offset = mode->f_string_start - tok->buf; + mode->f_string_multi_line_start_offset = mode->f_string_multi_line_start - tok->buf; + } +} + +/* Traverse and restore all f-string buffers after reallocating tok->buf */ +void +_PyLexer_restore_fstring_buffers(struct tok_state *tok) +{ + int index; + tokenizer_mode *mode; + + for (index = tok->tok_mode_stack_index; index >= 0; --index) { + mode = &(tok->tok_mode_stack[index]); + mode->f_string_start = tok->buf + mode->f_string_start_offset; + mode->f_string_multi_line_start = tok->buf + mode->f_string_multi_line_start_offset; + } +} + +/* Read a line of text from TOK into S, using the stream in TOK. + Return NULL on failure, else S. + + On entry, tok->decoding_buffer will be one of: + 1) NULL: need to call tok->decoding_readline to get a new line + 2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and + stored the result in tok->decoding_buffer + 3) PyByteArrayObject *: previous call to tok_readline_recode did not have enough room + (in the s buffer) to copy entire contents of the line read + by tok->decoding_readline. tok->decoding_buffer has the overflow. + In this case, tok_readline_recode is called in a loop (with an expanded buffer) + until the buffer ends with a '\n' (or until the end of the file is + reached): see tok_nextc and its calls to tok_reserve_buf. +*/ +int +_PyLexer_tok_reserve_buf(struct tok_state *tok, Py_ssize_t size) +{ + Py_ssize_t cur = tok->cur - tok->buf; + Py_ssize_t oldsize = tok->inp - tok->buf; + Py_ssize_t newsize = oldsize + Py_MAX(size, oldsize >> 1); + if (newsize > tok->end - tok->buf) { + char *newbuf = tok->buf; + Py_ssize_t start = tok->start == NULL ? -1 : tok->start - tok->buf; + Py_ssize_t line_start = tok->start == NULL ? -1 : tok->line_start - tok->buf; + Py_ssize_t multi_line_start = tok->multi_line_start - tok->buf; + _PyLexer_remember_fstring_buffers(tok); + newbuf = (char *)PyMem_Realloc(newbuf, newsize); + if (newbuf == NULL) { + tok->done = E_NOMEM; + return 0; + } + tok->buf = newbuf; + tok->cur = tok->buf + cur; + tok->inp = tok->buf + oldsize; + tok->end = tok->buf + newsize; + tok->start = start < 0 ? NULL : tok->buf + start; + tok->line_start = line_start < 0 ? NULL : tok->buf + line_start; + tok->multi_line_start = multi_line_start < 0 ? NULL : tok->buf + multi_line_start; + _PyLexer_restore_fstring_buffers(tok); + } + return 1; +} diff --git a/Parser/lexer/buffer.h b/Parser/lexer/buffer.h new file mode 100644 index 00000000000000..bb218162ff4845 --- /dev/null +++ b/Parser/lexer/buffer.h @@ -0,0 +1,10 @@ +#ifndef _LEXER_BUFFER_H_ +#define _LEXER_BUFFER_H_ + +#include "pyport.h" + +void _PyLexer_remember_fstring_buffers(struct tok_state *tok); +void _PyLexer_restore_fstring_buffers(struct tok_state *tok); +int _PyLexer_tok_reserve_buf(struct tok_state *tok, Py_ssize_t size); + +#endif diff --git a/Parser/lexer/lexer.c b/Parser/lexer/lexer.c new file mode 100644 index 00000000000000..c7134ab868bfbd --- /dev/null +++ b/Parser/lexer/lexer.c @@ -0,0 +1,1419 @@ +#include "Python.h" +#include "pycore_token.h" +#include "pycore_unicodeobject.h" +#include "errcode.h" + +#include "state.h" +#include "../tokenizer/helpers.h" + +/* Alternate tab spacing */ +#define ALTTABSIZE 1 + +#define is_potential_identifier_start(c) (\ + (c >= 'a' && c <= 'z')\ + || (c >= 'A' && c <= 'Z')\ + || c == '_'\ + || (c >= 128)) + +#define is_potential_identifier_char(c) (\ + (c >= 'a' && c <= 'z')\ + || (c >= 'A' && c <= 'Z')\ + || (c >= '0' && c <= '9')\ + || c == '_'\ + || (c >= 128)) + +#ifdef Py_DEBUG +static inline tokenizer_mode* TOK_GET_MODE(struct tok_state* tok) { + assert(tok->tok_mode_stack_index >= 0); + assert(tok->tok_mode_stack_index < MAXFSTRINGLEVEL); + return &(tok->tok_mode_stack[tok->tok_mode_stack_index]); +} +static inline tokenizer_mode* TOK_NEXT_MODE(struct tok_state* tok) { + assert(tok->tok_mode_stack_index >= 0); + assert(tok->tok_mode_stack_index + 1 < MAXFSTRINGLEVEL); + return &(tok->tok_mode_stack[++tok->tok_mode_stack_index]); +} +#else +#define TOK_GET_MODE(tok) (&(tok->tok_mode_stack[tok->tok_mode_stack_index])) +#define TOK_NEXT_MODE(tok) (&(tok->tok_mode_stack[++tok->tok_mode_stack_index])) +#endif + +#define MAKE_TOKEN(token_type) _PyLexer_token_setup(tok, token, token_type, p_start, p_end) +#define MAKE_TYPE_COMMENT_TOKEN(token_type, col_offset, end_col_offset) (\ + _PyLexer_type_comment_token_setup(tok, token, token_type, col_offset, end_col_offset, p_start, p_end)) + +/* Spaces in this constant are treated as "zero or more spaces or tabs" when + tokenizing. */ +static const char* type_comment_prefix = "# type: "; + +static inline int +contains_null_bytes(const char* str, size_t size) +{ + return memchr(str, 0, size) != NULL; +} + +/* Get next char, updating state; error code goes into tok->done */ +static int +tok_nextc(struct tok_state *tok) +{ + int rc; + for (;;) { + if (tok->cur != tok->inp) { + tok->col_offset++; + return Py_CHARMASK(*tok->cur++); /* Fast path */ + } + if (tok->done != E_OK) { + return EOF; + } + rc = tok->underflow(tok); +#if defined(Py_DEBUG) + if (tok->debug) { + fprintf(stderr, "line[%d] = ", tok->lineno); + _PyTokenizer_print_escape(stderr, tok->cur, tok->inp - tok->cur); + fprintf(stderr, " tok->done = %d\n", tok->done); + } +#endif + if (!rc) { + tok->cur = tok->inp; + return EOF; + } + tok->line_start = tok->cur; + + if (contains_null_bytes(tok->line_start, tok->inp - tok->line_start)) { + _PyTokenizer_syntaxerror(tok, "source code cannot contain null bytes"); + tok->cur = tok->inp; + return EOF; + } + } + Py_UNREACHABLE(); +} + +/* Back-up one character */ +static void +tok_backup(struct tok_state *tok, int c) +{ + if (c != EOF) { + if (--tok->cur < tok->buf) { + Py_FatalError("tokenizer beginning of buffer"); + } + if ((int)(unsigned char)*tok->cur != Py_CHARMASK(c)) { + Py_FatalError("tok_backup: wrong character"); + } + tok->col_offset--; + } +} + +static int +set_fstring_expr(struct tok_state* tok, struct token *token, char c) { + assert(token != NULL); + assert(c == '}' || c == ':' || c == '!'); + tokenizer_mode *tok_mode = TOK_GET_MODE(tok); + + if (!tok_mode->f_string_debug || token->metadata) { + return 0; + } + + PyObject *res = PyUnicode_DecodeUTF8( + tok_mode->last_expr_buffer, + tok_mode->last_expr_size - tok_mode->last_expr_end, + NULL + ); + if (!res) { + return -1; + } + token->metadata = res; + return 0; +} + +int +_PyLexer_update_fstring_expr(struct tok_state *tok, char cur) +{ + assert(tok->cur != NULL); + + Py_ssize_t size = strlen(tok->cur); + tokenizer_mode *tok_mode = TOK_GET_MODE(tok); + + switch (cur) { + case 0: + if (!tok_mode->last_expr_buffer || tok_mode->last_expr_end >= 0) { + return 1; + } + char *new_buffer = PyMem_Realloc( + tok_mode->last_expr_buffer, + tok_mode->last_expr_size + size + ); + if (new_buffer == NULL) { + PyMem_Free(tok_mode->last_expr_buffer); + goto error; + } + tok_mode->last_expr_buffer = new_buffer; + strncpy(tok_mode->last_expr_buffer + tok_mode->last_expr_size, tok->cur, size); + tok_mode->last_expr_size += size; + break; + case '{': + if (tok_mode->last_expr_buffer != NULL) { + PyMem_Free(tok_mode->last_expr_buffer); + } + tok_mode->last_expr_buffer = PyMem_Malloc(size); + if (tok_mode->last_expr_buffer == NULL) { + goto error; + } + tok_mode->last_expr_size = size; + tok_mode->last_expr_end = -1; + strncpy(tok_mode->last_expr_buffer, tok->cur, size); + break; + case '}': + case '!': + case ':': + if (tok_mode->last_expr_end == -1) { + tok_mode->last_expr_end = strlen(tok->start); + } + break; + default: + Py_UNREACHABLE(); + } + return 1; +error: + tok->done = E_NOMEM; + return 0; +} + +static int +lookahead(struct tok_state *tok, const char *test) +{ + const char *s = test; + int res = 0; + while (1) { + int c = tok_nextc(tok); + if (*s == 0) { + res = !is_potential_identifier_char(c); + } + else if (c == *s) { + s++; + continue; + } + + tok_backup(tok, c); + while (s != test) { + tok_backup(tok, *--s); + } + return res; + } +} + +static int +verify_end_of_number(struct tok_state *tok, int c, const char *kind) { + if (tok->tok_extra_tokens) { + // When we are parsing extra tokens, we don't want to emit warnings + // about invalid literals, because we want to be a bit more liberal. + return 1; + } + /* Emit a deprecation warning only if the numeric literal is immediately + * followed by one of keywords which can occur after a numeric literal + * in valid code: "and", "else", "for", "if", "in", "is" and "or". + * It allows to gradually deprecate existing valid code without adding + * warning before error in most cases of invalid numeric literal (which + * would be confusing and break existing tests). + * Raise a syntax error with slightly better message than plain + * "invalid syntax" if the numeric literal is immediately followed by + * other keyword or identifier. + */ + int r = 0; + if (c == 'a') { + r = lookahead(tok, "nd"); + } + else if (c == 'e') { + r = lookahead(tok, "lse"); + } + else if (c == 'f') { + r = lookahead(tok, "or"); + } + else if (c == 'i') { + int c2 = tok_nextc(tok); + if (c2 == 'f' || c2 == 'n' || c2 == 's') { + r = 1; + } + tok_backup(tok, c2); + } + else if (c == 'o') { + r = lookahead(tok, "r"); + } + else if (c == 'n') { + r = lookahead(tok, "ot"); + } + if (r) { + tok_backup(tok, c); + if (_PyTokenizer_parser_warn(tok, PyExc_SyntaxWarning, + "invalid %s literal", kind)) + { + return 0; + } + tok_nextc(tok); + } + else /* In future releases, only error will remain. */ + if (c < 128 && is_potential_identifier_char(c)) { + tok_backup(tok, c); + _PyTokenizer_syntaxerror(tok, "invalid %s literal", kind); + return 0; + } + return 1; +} + +/* Verify that the identifier follows PEP 3131. + All identifier strings are guaranteed to be "ready" unicode objects. + */ +static int +verify_identifier(struct tok_state *tok) +{ + if (tok->tok_extra_tokens) { + return 1; + } + PyObject *s; + if (tok->decoding_erred) + return 0; + s = PyUnicode_DecodeUTF8(tok->start, tok->cur - tok->start, NULL); + if (s == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + tok->done = E_DECODE; + } + else { + tok->done = E_ERROR; + } + return 0; + } + Py_ssize_t invalid = _PyUnicode_ScanIdentifier(s); + if (invalid < 0) { + Py_DECREF(s); + tok->done = E_ERROR; + return 0; + } + assert(PyUnicode_GET_LENGTH(s) > 0); + if (invalid < PyUnicode_GET_LENGTH(s)) { + Py_UCS4 ch = PyUnicode_READ_CHAR(s, invalid); + if (invalid + 1 < PyUnicode_GET_LENGTH(s)) { + /* Determine the offset in UTF-8 encoded input */ + Py_SETREF(s, PyUnicode_Substring(s, 0, invalid + 1)); + if (s != NULL) { + Py_SETREF(s, PyUnicode_AsUTF8String(s)); + } + if (s == NULL) { + tok->done = E_ERROR; + return 0; + } + tok->cur = (char *)tok->start + PyBytes_GET_SIZE(s); + } + Py_DECREF(s); + if (Py_UNICODE_ISPRINTABLE(ch)) { + _PyTokenizer_syntaxerror(tok, "invalid character '%c' (U+%04X)", ch, ch); + } + else { + _PyTokenizer_syntaxerror(tok, "invalid non-printable character U+%04X", ch); + } + return 0; + } + Py_DECREF(s); + return 1; +} + +static int +tok_decimal_tail(struct tok_state *tok) +{ + int c; + + while (1) { + do { + c = tok_nextc(tok); + } while (Py_ISDIGIT(c)); + if (c != '_') { + break; + } + c = tok_nextc(tok); + if (!Py_ISDIGIT(c)) { + tok_backup(tok, c); + _PyTokenizer_syntaxerror(tok, "invalid decimal literal"); + return 0; + } + } + return c; +} + +static inline int +tok_continuation_line(struct tok_state *tok) { + int c = tok_nextc(tok); + if (c == '\r') { + c = tok_nextc(tok); + } + if (c != '\n') { + tok->done = E_LINECONT; + return -1; + } + c = tok_nextc(tok); + if (c == EOF) { + tok->done = E_EOF; + tok->cur = tok->inp; + return -1; + } else { + tok_backup(tok, c); + } + return c; +} + +static int +tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct token *token) +{ + int c; + int blankline, nonascii; + + const char *p_start = NULL; + const char *p_end = NULL; + nextline: + tok->start = NULL; + tok->starting_col_offset = -1; + blankline = 0; + + + /* Get indentation level */ + if (tok->atbol) { + int col = 0; + int altcol = 0; + tok->atbol = 0; + int cont_line_col = 0; + for (;;) { + c = tok_nextc(tok); + if (c == ' ') { + col++, altcol++; + } + else if (c == '\t') { + col = (col / tok->tabsize + 1) * tok->tabsize; + altcol = (altcol / ALTTABSIZE + 1) * ALTTABSIZE; + } + else if (c == '\014') {/* Control-L (formfeed) */ + col = altcol = 0; /* For Emacs users */ + } + else if (c == '\\') { + // Indentation cannot be split over multiple physical lines + // using backslashes. This means that if we found a backslash + // preceded by whitespace, **the first one we find** determines + // the level of indentation of whatever comes next. + cont_line_col = cont_line_col ? cont_line_col : col; + if ((c = tok_continuation_line(tok)) == -1) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + else { + break; + } + } + tok_backup(tok, c); + if (c == '#' || c == '\n' || c == '\r') { + /* Lines with only whitespace and/or comments + shouldn't affect the indentation and are + not passed to the parser as NEWLINE tokens, + except *totally* empty lines in interactive + mode, which signal the end of a command group. */ + if (col == 0 && c == '\n' && tok->prompt != NULL) { + blankline = 0; /* Let it through */ + } + else if (tok->prompt != NULL && tok->lineno == 1) { + /* In interactive mode, if the first line contains + only spaces and/or a comment, let it through. */ + blankline = 0; + col = altcol = 0; + } + else { + blankline = 1; /* Ignore completely */ + } + /* We can't jump back right here since we still + may need to skip to the end of a comment */ + } + if (!blankline && tok->level == 0) { + col = cont_line_col ? cont_line_col : col; + altcol = cont_line_col ? cont_line_col : altcol; + if (col == tok->indstack[tok->indent]) { + /* No change */ + if (altcol != tok->altindstack[tok->indent]) { + return MAKE_TOKEN(_PyTokenizer_indenterror(tok)); + } + } + else if (col > tok->indstack[tok->indent]) { + /* Indent -- always one */ + if (tok->indent+1 >= MAXINDENT) { + tok->done = E_TOODEEP; + tok->cur = tok->inp; + return MAKE_TOKEN(ERRORTOKEN); + } + if (altcol <= tok->altindstack[tok->indent]) { + return MAKE_TOKEN(_PyTokenizer_indenterror(tok)); + } + tok->pendin++; + tok->indstack[++tok->indent] = col; + tok->altindstack[tok->indent] = altcol; + } + else /* col < tok->indstack[tok->indent] */ { + /* Dedent -- any number, must be consistent */ + while (tok->indent > 0 && + col < tok->indstack[tok->indent]) { + tok->pendin--; + tok->indent--; + } + if (col != tok->indstack[tok->indent]) { + tok->done = E_DEDENT; + tok->cur = tok->inp; + return MAKE_TOKEN(ERRORTOKEN); + } + if (altcol != tok->altindstack[tok->indent]) { + return MAKE_TOKEN(_PyTokenizer_indenterror(tok)); + } + } + } + } + + tok->start = tok->cur; + tok->starting_col_offset = tok->col_offset; + + /* Return pending indents/dedents */ + if (tok->pendin != 0) { + if (tok->pendin < 0) { + if (tok->tok_extra_tokens) { + p_start = tok->cur; + p_end = tok->cur; + } + tok->pendin++; + return MAKE_TOKEN(DEDENT); + } + else { + if (tok->tok_extra_tokens) { + p_start = tok->buf; + p_end = tok->cur; + } + tok->pendin--; + return MAKE_TOKEN(INDENT); + } + } + + /* Peek ahead at the next character */ + c = tok_nextc(tok); + tok_backup(tok, c); + + again: + tok->start = NULL; + /* Skip spaces */ + do { + c = tok_nextc(tok); + } while (c == ' ' || c == '\t' || c == '\014'); + + /* Set start of current token */ + tok->start = tok->cur == NULL ? NULL : tok->cur - 1; + tok->starting_col_offset = tok->col_offset - 1; + + /* Skip comment, unless it's a type comment */ + if (c == '#') { + + const char* p = NULL; + const char *prefix, *type_start; + int current_starting_col_offset; + + while (c != EOF && c != '\n' && c != '\r') { + c = tok_nextc(tok); + } + + if (tok->tok_extra_tokens) { + p = tok->start; + } + + if (tok->type_comments) { + p = tok->start; + current_starting_col_offset = tok->starting_col_offset; + prefix = type_comment_prefix; + while (*prefix && p < tok->cur) { + if (*prefix == ' ') { + while (*p == ' ' || *p == '\t') { + p++; + current_starting_col_offset++; + } + } else if (*prefix == *p) { + p++; + current_starting_col_offset++; + } else { + break; + } + + prefix++; + } + + /* This is a type comment if we matched all of type_comment_prefix. */ + if (!*prefix) { + int is_type_ignore = 1; + // +6 in order to skip the word 'ignore' + const char *ignore_end = p + 6; + const int ignore_end_col_offset = current_starting_col_offset + 6; + tok_backup(tok, c); /* don't eat the newline or EOF */ + + type_start = p; + + /* A TYPE_IGNORE is "type: ignore" followed by the end of the token + * or anything ASCII and non-alphanumeric. */ + is_type_ignore = ( + tok->cur >= ignore_end && memcmp(p, "ignore", 6) == 0 + && !(tok->cur > ignore_end + && ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0])))); + + if (is_type_ignore) { + p_start = ignore_end; + p_end = tok->cur; + + /* If this type ignore is the only thing on the line, consume the newline also. */ + if (blankline) { + tok_nextc(tok); + tok->atbol = 1; + } + return MAKE_TYPE_COMMENT_TOKEN(TYPE_IGNORE, ignore_end_col_offset, tok->col_offset); + } else { + p_start = type_start; + p_end = tok->cur; + return MAKE_TYPE_COMMENT_TOKEN(TYPE_COMMENT, current_starting_col_offset, tok->col_offset); + } + } + } + if (tok->tok_extra_tokens) { + tok_backup(tok, c); /* don't eat the newline or EOF */ + p_start = p; + p_end = tok->cur; + tok->comment_newline = blankline; + return MAKE_TOKEN(COMMENT); + } + } + + if (tok->done == E_INTERACT_STOP) { + return MAKE_TOKEN(ENDMARKER); + } + + /* Check for EOF and errors now */ + if (c == EOF) { + if (tok->level) { + return MAKE_TOKEN(ERRORTOKEN); + } + return MAKE_TOKEN(tok->done == E_EOF ? ENDMARKER : ERRORTOKEN); + } + + /* Identifier (most frequent token!) */ + nonascii = 0; + if (is_potential_identifier_start(c)) { + /* Process the various legal combinations of b"", r"", u"", and f"". */ + int saw_b = 0, saw_r = 0, saw_u = 0, saw_f = 0; + while (1) { + if (!(saw_b || saw_u || saw_f) && (c == 'b' || c == 'B')) + saw_b = 1; + /* Since this is a backwards compatibility support literal we don't + want to support it in arbitrary order like byte literals. */ + else if (!(saw_b || saw_u || saw_r || saw_f) + && (c == 'u'|| c == 'U')) { + saw_u = 1; + } + /* ur"" and ru"" are not supported */ + else if (!(saw_r || saw_u) && (c == 'r' || c == 'R')) { + saw_r = 1; + } + else if (!(saw_f || saw_b || saw_u) && (c == 'f' || c == 'F')) { + saw_f = 1; + } + else { + break; + } + c = tok_nextc(tok); + if (c == '"' || c == '\'') { + if (saw_f) { + goto f_string_quote; + } + goto letter_quote; + } + } + while (is_potential_identifier_char(c)) { + if (c >= 128) { + nonascii = 1; + } + c = tok_nextc(tok); + } + tok_backup(tok, c); + if (nonascii && !verify_identifier(tok)) { + return MAKE_TOKEN(ERRORTOKEN); + } + + p_start = tok->start; + p_end = tok->cur; + + return MAKE_TOKEN(NAME); + } + + if (c == '\r') { + c = tok_nextc(tok); + } + + /* Newline */ + if (c == '\n') { + tok->atbol = 1; + if (blankline || tok->level > 0) { + if (tok->tok_extra_tokens) { + if (tok->comment_newline) { + tok->comment_newline = 0; + } + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NL); + } + goto nextline; + } + if (tok->comment_newline && tok->tok_extra_tokens) { + tok->comment_newline = 0; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NL); + } + p_start = tok->start; + p_end = tok->cur - 1; /* Leave '\n' out of the string */ + tok->cont_line = 0; + return MAKE_TOKEN(NEWLINE); + } + + /* Period or number starting with period? */ + if (c == '.') { + c = tok_nextc(tok); + if (Py_ISDIGIT(c)) { + goto fraction; + } else if (c == '.') { + c = tok_nextc(tok); + if (c == '.') { + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(ELLIPSIS); + } + else { + tok_backup(tok, c); + } + tok_backup(tok, '.'); + } + else { + tok_backup(tok, c); + } + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(DOT); + } + + /* Number */ + if (Py_ISDIGIT(c)) { + if (c == '0') { + /* Hex, octal or binary -- maybe. */ + c = tok_nextc(tok); + if (c == 'x' || c == 'X') { + /* Hex */ + c = tok_nextc(tok); + do { + if (c == '_') { + c = tok_nextc(tok); + } + if (!Py_ISXDIGIT(c)) { + tok_backup(tok, c); + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid hexadecimal literal")); + } + do { + c = tok_nextc(tok); + } while (Py_ISXDIGIT(c)); + } while (c == '_'); + if (!verify_end_of_number(tok, c, "hexadecimal")) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + else if (c == 'o' || c == 'O') { + /* Octal */ + c = tok_nextc(tok); + do { + if (c == '_') { + c = tok_nextc(tok); + } + if (c < '0' || c >= '8') { + if (Py_ISDIGIT(c)) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, + "invalid digit '%c' in octal literal", c)); + } + else { + tok_backup(tok, c); + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid octal literal")); + } + } + do { + c = tok_nextc(tok); + } while ('0' <= c && c < '8'); + } while (c == '_'); + if (Py_ISDIGIT(c)) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, + "invalid digit '%c' in octal literal", c)); + } + if (!verify_end_of_number(tok, c, "octal")) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + else if (c == 'b' || c == 'B') { + /* Binary */ + c = tok_nextc(tok); + do { + if (c == '_') { + c = tok_nextc(tok); + } + if (c != '0' && c != '1') { + if (Py_ISDIGIT(c)) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid digit '%c' in binary literal", c)); + } + else { + tok_backup(tok, c); + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid binary literal")); + } + } + do { + c = tok_nextc(tok); + } while (c == '0' || c == '1'); + } while (c == '_'); + if (Py_ISDIGIT(c)) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid digit '%c' in binary literal", c)); + } + if (!verify_end_of_number(tok, c, "binary")) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + else { + int nonzero = 0; + /* maybe old-style octal; c is first char of it */ + /* in any case, allow '0' as a literal */ + while (1) { + if (c == '_') { + c = tok_nextc(tok); + if (!Py_ISDIGIT(c)) { + tok_backup(tok, c); + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid decimal literal")); + } + } + if (c != '0') { + break; + } + c = tok_nextc(tok); + } + char* zeros_end = tok->cur; + if (Py_ISDIGIT(c)) { + nonzero = 1; + c = tok_decimal_tail(tok); + if (c == 0) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + if (c == '.') { + c = tok_nextc(tok); + goto fraction; + } + else if (c == 'e' || c == 'E') { + goto exponent; + } + else if (c == 'j' || c == 'J') { + goto imaginary; + } + else if (nonzero && !tok->tok_extra_tokens) { + /* Old-style octal: now disallowed. */ + tok_backup(tok, c); + return MAKE_TOKEN(_PyTokenizer_syntaxerror_known_range( + tok, (int)(tok->start + 1 - tok->line_start), + (int)(zeros_end - tok->line_start), + "leading zeros in decimal integer " + "literals are not permitted; " + "use an 0o prefix for octal integers")); + } + if (!verify_end_of_number(tok, c, "decimal")) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + } + else { + /* Decimal */ + c = tok_decimal_tail(tok); + if (c == 0) { + return MAKE_TOKEN(ERRORTOKEN); + } + { + /* Accept floating point numbers. */ + if (c == '.') { + c = tok_nextc(tok); + fraction: + /* Fraction */ + if (Py_ISDIGIT(c)) { + c = tok_decimal_tail(tok); + if (c == 0) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + } + if (c == 'e' || c == 'E') { + int e; + exponent: + e = c; + /* Exponent part */ + c = tok_nextc(tok); + if (c == '+' || c == '-') { + c = tok_nextc(tok); + if (!Py_ISDIGIT(c)) { + tok_backup(tok, c); + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid decimal literal")); + } + } else if (!Py_ISDIGIT(c)) { + tok_backup(tok, c); + if (!verify_end_of_number(tok, e, "decimal")) { + return MAKE_TOKEN(ERRORTOKEN); + } + tok_backup(tok, e); + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NUMBER); + } + c = tok_decimal_tail(tok); + if (c == 0) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + if (c == 'j' || c == 'J') { + /* Imaginary part */ + imaginary: + c = tok_nextc(tok); + if (!verify_end_of_number(tok, c, "imaginary")) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + else if (!verify_end_of_number(tok, c, "decimal")) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + } + tok_backup(tok, c); + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NUMBER); + } + + f_string_quote: + if (((Py_TOLOWER(*tok->start) == 'f' || Py_TOLOWER(*tok->start) == 'r') && (c == '\'' || c == '"'))) { + int quote = c; + int quote_size = 1; /* 1 or 3 */ + + /* Nodes of type STRING, especially multi line strings + must be handled differently in order to get both + the starting line number and the column offset right. + (cf. issue 16806) */ + tok->first_lineno = tok->lineno; + tok->multi_line_start = tok->line_start; + + /* Find the quote size and start of string */ + int after_quote = tok_nextc(tok); + if (after_quote == quote) { + int after_after_quote = tok_nextc(tok); + if (after_after_quote == quote) { + quote_size = 3; + } + else { + // TODO: Check this + tok_backup(tok, after_after_quote); + tok_backup(tok, after_quote); + } + } + if (after_quote != quote) { + tok_backup(tok, after_quote); + } + + + p_start = tok->start; + p_end = tok->cur; + if (tok->tok_mode_stack_index + 1 >= MAXFSTRINGLEVEL) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "too many nested f-strings")); + } + tokenizer_mode *the_current_tok = TOK_NEXT_MODE(tok); + the_current_tok->kind = TOK_FSTRING_MODE; + the_current_tok->f_string_quote = quote; + the_current_tok->f_string_quote_size = quote_size; + the_current_tok->f_string_start = tok->start; + the_current_tok->f_string_multi_line_start = tok->line_start; + the_current_tok->f_string_line_start = tok->lineno; + the_current_tok->f_string_start_offset = -1; + the_current_tok->f_string_multi_line_start_offset = -1; + the_current_tok->last_expr_buffer = NULL; + the_current_tok->last_expr_size = 0; + the_current_tok->last_expr_end = -1; + the_current_tok->f_string_debug = 0; + + switch (*tok->start) { + case 'F': + case 'f': + the_current_tok->f_string_raw = Py_TOLOWER(*(tok->start + 1)) == 'r'; + break; + case 'R': + case 'r': + the_current_tok->f_string_raw = 1; + break; + default: + Py_UNREACHABLE(); + } + + the_current_tok->curly_bracket_depth = 0; + the_current_tok->curly_bracket_expr_start_depth = -1; + return MAKE_TOKEN(FSTRING_START); + } + + letter_quote: + /* String */ + if (c == '\'' || c == '"') { + int quote = c; + int quote_size = 1; /* 1 or 3 */ + int end_quote_size = 0; + + /* Nodes of type STRING, especially multi line strings + must be handled differently in order to get both + the starting line number and the column offset right. + (cf. issue 16806) */ + tok->first_lineno = tok->lineno; + tok->multi_line_start = tok->line_start; + + /* Find the quote size and start of string */ + c = tok_nextc(tok); + if (c == quote) { + c = tok_nextc(tok); + if (c == quote) { + quote_size = 3; + } + else { + end_quote_size = 1; /* empty string found */ + } + } + if (c != quote) { + tok_backup(tok, c); + } + + /* Get rest of string */ + while (end_quote_size != quote_size) { + c = tok_nextc(tok); + if (tok->done == E_ERROR) { + return MAKE_TOKEN(ERRORTOKEN); + } + if (tok->done == E_DECODE) { + break; + } + if (c == EOF || (quote_size == 1 && c == '\n')) { + assert(tok->multi_line_start != NULL); + // shift the tok_state's location into + // the start of string, and report the error + // from the initial quote character + tok->cur = (char *)tok->start; + tok->cur++; + tok->line_start = tok->multi_line_start; + int start = tok->lineno; + tok->lineno = tok->first_lineno; + + if (INSIDE_FSTRING(tok)) { + /* When we are in an f-string, before raising the + * unterminated string literal error, check whether + * does the initial quote matches with f-strings quotes + * and if it is, then this must be a missing '}' token + * so raise the proper error */ + tokenizer_mode *the_current_tok = TOK_GET_MODE(tok); + if (the_current_tok->f_string_quote == quote && + the_current_tok->f_string_quote_size == quote_size) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "f-string: expecting '}'", start)); + } + } + + if (quote_size == 3) { + _PyTokenizer_syntaxerror(tok, "unterminated triple-quoted string literal" + " (detected at line %d)", start); + if (c != '\n') { + tok->done = E_EOFS; + } + return MAKE_TOKEN(ERRORTOKEN); + } + else { + _PyTokenizer_syntaxerror(tok, "unterminated string literal (detected at" + " line %d)", start); + if (c != '\n') { + tok->done = E_EOLS; + } + return MAKE_TOKEN(ERRORTOKEN); + } + } + if (c == quote) { + end_quote_size += 1; + } + else { + end_quote_size = 0; + if (c == '\\') { + c = tok_nextc(tok); /* skip escaped char */ + if (c == '\r') { + c = tok_nextc(tok); + } + } + } + } + + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(STRING); + } + + /* Line continuation */ + if (c == '\\') { + if ((c = tok_continuation_line(tok)) == -1) { + return MAKE_TOKEN(ERRORTOKEN); + } + tok->cont_line = 1; + goto again; /* Read next line */ + } + + /* Punctuation character */ + int is_punctuation = (c == ':' || c == '}' || c == '!' || c == '{'); + if (is_punctuation && INSIDE_FSTRING(tok) && INSIDE_FSTRING_EXPR(current_tok)) { + /* This code block gets executed before the curly_bracket_depth is incremented + * by the `{` case, so for ensuring that we are on the 0th level, we need + * to adjust it manually */ + int cursor = current_tok->curly_bracket_depth - (c != '{'); + if (cursor == 0 && !_PyLexer_update_fstring_expr(tok, c)) { + return MAKE_TOKEN(ENDMARKER); + } + if (cursor == 0 && c != '{' && set_fstring_expr(tok, token, c)) { + return MAKE_TOKEN(ERRORTOKEN); + } + + if (c == ':' && cursor == current_tok->curly_bracket_expr_start_depth) { + current_tok->kind = TOK_FSTRING_MODE; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(_PyToken_OneChar(c)); + } + } + + /* Check for two-character token */ + { + int c2 = tok_nextc(tok); + int current_token = _PyToken_TwoChars(c, c2); + if (current_token != OP) { + int c3 = tok_nextc(tok); + int current_token3 = _PyToken_ThreeChars(c, c2, c3); + if (current_token3 != OP) { + current_token = current_token3; + } + else { + tok_backup(tok, c3); + } + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(current_token); + } + tok_backup(tok, c2); + } + + /* Keep track of parentheses nesting level */ + switch (c) { + case '(': + case '[': + case '{': + if (tok->level >= MAXLEVEL) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "too many nested parentheses")); + } + tok->parenstack[tok->level] = c; + tok->parenlinenostack[tok->level] = tok->lineno; + tok->parencolstack[tok->level] = (int)(tok->start - tok->line_start); + tok->level++; + if (INSIDE_FSTRING(tok)) { + current_tok->curly_bracket_depth++; + } + break; + case ')': + case ']': + case '}': + if (INSIDE_FSTRING(tok) && !current_tok->curly_bracket_depth && c == '}') { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "f-string: single '}' is not allowed")); + } + if (!tok->tok_extra_tokens && !tok->level) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "unmatched '%c'", c)); + } + if (tok->level > 0) { + tok->level--; + int opening = tok->parenstack[tok->level]; + if (!tok->tok_extra_tokens && !((opening == '(' && c == ')') || + (opening == '[' && c == ']') || + (opening == '{' && c == '}'))) { + /* If the opening bracket belongs to an f-string's expression + part (e.g. f"{)}") and the closing bracket is an arbitrary + nested expression, then instead of matching a different + syntactical construct with it; we'll throw an unmatched + parentheses error. */ + if (INSIDE_FSTRING(tok) && opening == '{') { + assert(current_tok->curly_bracket_depth >= 0); + int previous_bracket = current_tok->curly_bracket_depth - 1; + if (previous_bracket == current_tok->curly_bracket_expr_start_depth) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "f-string: unmatched '%c'", c)); + } + } + if (tok->parenlinenostack[tok->level] != tok->lineno) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, + "closing parenthesis '%c' does not match " + "opening parenthesis '%c' on line %d", + c, opening, tok->parenlinenostack[tok->level])); + } + else { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, + "closing parenthesis '%c' does not match " + "opening parenthesis '%c'", + c, opening)); + } + } + } + + if (INSIDE_FSTRING(tok)) { + current_tok->curly_bracket_depth--; + if (c == '}' && current_tok->curly_bracket_depth == current_tok->curly_bracket_expr_start_depth) { + current_tok->curly_bracket_expr_start_depth--; + current_tok->kind = TOK_FSTRING_MODE; + current_tok->f_string_debug = 0; + } + } + break; + default: + break; + } + + if (!Py_UNICODE_ISPRINTABLE(c)) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid non-printable character U+%04X", c)); + } + + if( c == '=' && INSIDE_FSTRING_EXPR(current_tok)) { + current_tok->f_string_debug = 1; + } + + /* Punctuation character */ + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(_PyToken_OneChar(c)); +} + +static int +tok_get_fstring_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct token *token) +{ + const char *p_start = NULL; + const char *p_end = NULL; + int end_quote_size = 0; + int unicode_escape = 0; + + tok->start = tok->cur; + tok->first_lineno = tok->lineno; + tok->starting_col_offset = tok->col_offset; + + // If we start with a bracket, we defer to the normal mode as there is nothing for us to tokenize + // before it. + int start_char = tok_nextc(tok); + if (start_char == '{') { + int peek1 = tok_nextc(tok); + tok_backup(tok, peek1); + tok_backup(tok, start_char); + if (peek1 != '{') { + current_tok->curly_bracket_expr_start_depth++; + if (current_tok->curly_bracket_expr_start_depth >= MAX_EXPR_NESTING) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "f-string: expressions nested too deeply")); + } + TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; + return tok_get_normal_mode(tok, current_tok, token); + } + } + else { + tok_backup(tok, start_char); + } + + // Check if we are at the end of the string + for (int i = 0; i < current_tok->f_string_quote_size; i++) { + int quote = tok_nextc(tok); + if (quote != current_tok->f_string_quote) { + tok_backup(tok, quote); + goto f_string_middle; + } + } + + if (current_tok->last_expr_buffer != NULL) { + PyMem_Free(current_tok->last_expr_buffer); + current_tok->last_expr_buffer = NULL; + current_tok->last_expr_size = 0; + current_tok->last_expr_end = -1; + } + + p_start = tok->start; + p_end = tok->cur; + tok->tok_mode_stack_index--; + return MAKE_TOKEN(FSTRING_END); + +f_string_middle: + + // TODO: This is a bit of a hack, but it works for now. We need to find a better way to handle + // this. + tok->multi_line_start = tok->line_start; + while (end_quote_size != current_tok->f_string_quote_size) { + int c = tok_nextc(tok); + if (tok->done == E_ERROR) { + return MAKE_TOKEN(ERRORTOKEN); + } + int in_format_spec = ( + current_tok->last_expr_end != -1 + && + INSIDE_FSTRING_EXPR(current_tok) + ); + + if (c == EOF || (current_tok->f_string_quote_size == 1 && c == '\n')) { + if (tok->decoding_erred) { + return MAKE_TOKEN(ERRORTOKEN); + } + + // If we are in a format spec and we found a newline, + // it means that the format spec ends here and we should + // return to the regular mode. + if (in_format_spec && c == '\n') { + tok_backup(tok, c); + TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(FSTRING_MIDDLE); + } + + assert(tok->multi_line_start != NULL); + // shift the tok_state's location into + // the start of string, and report the error + // from the initial quote character + tok->cur = (char *)current_tok->f_string_start; + tok->cur++; + tok->line_start = current_tok->f_string_multi_line_start; + int start = tok->lineno; + + tokenizer_mode *the_current_tok = TOK_GET_MODE(tok); + tok->lineno = the_current_tok->f_string_line_start; + + if (current_tok->f_string_quote_size == 3) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, + "unterminated triple-quoted f-string literal" + " (detected at line %d)", start)); + } + else { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, + "unterminated f-string literal (detected at" + " line %d)", start)); + } + } + + if (c == current_tok->f_string_quote) { + end_quote_size += 1; + continue; + } else { + end_quote_size = 0; + } + + if (c == '{') { + int peek = tok_nextc(tok); + if (peek != '{' || in_format_spec) { + tok_backup(tok, peek); + tok_backup(tok, c); + current_tok->curly_bracket_expr_start_depth++; + if (current_tok->curly_bracket_expr_start_depth >= MAX_EXPR_NESTING) { + return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "f-string: expressions nested too deeply")); + } + TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; + p_start = tok->start; + p_end = tok->cur; + } else { + p_start = tok->start; + p_end = tok->cur - 1; + } + return MAKE_TOKEN(FSTRING_MIDDLE); + } else if (c == '}') { + if (unicode_escape) { + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(FSTRING_MIDDLE); + } + int peek = tok_nextc(tok); + + // The tokenizer can only be in the format spec if we have already completed the expression + // scanning (indicated by the end of the expression being set) and we are not at the top level + // of the bracket stack (-1 is the top level). Since format specifiers can't legally use double + // brackets, we can bypass it here. + if (peek == '}' && !in_format_spec) { + p_start = tok->start; + p_end = tok->cur - 1; + } else { + tok_backup(tok, peek); + tok_backup(tok, c); + TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; + p_start = tok->start; + p_end = tok->cur; + } + return MAKE_TOKEN(FSTRING_MIDDLE); + } else if (c == '\\') { + int peek = tok_nextc(tok); + if (peek == '\r') { + peek = tok_nextc(tok); + } + // Special case when the backslash is right before a curly + // brace. We have to restore and return the control back + // to the loop for the next iteration. + if (peek == '{' || peek == '}') { + if (!current_tok->f_string_raw) { + if (_PyTokenizer_warn_invalid_escape_sequence(tok, peek)) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + tok_backup(tok, peek); + continue; + } + + if (!current_tok->f_string_raw) { + if (peek == 'N') { + /* Handle named unicode escapes (\N{BULLET}) */ + peek = tok_nextc(tok); + if (peek == '{') { + unicode_escape = 1; + } else { + tok_backup(tok, peek); + } + } + } /* else { + skip the escaped character + }*/ + } + } + + // Backup the f-string quotes to emit a final FSTRING_MIDDLE and + // add the quotes to the FSTRING_END in the next tokenizer iteration. + for (int i = 0; i < current_tok->f_string_quote_size; i++) { + tok_backup(tok, current_tok->f_string_quote); + } + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(FSTRING_MIDDLE); +} + +static int +tok_get(struct tok_state *tok, struct token *token) +{ + tokenizer_mode *current_tok = TOK_GET_MODE(tok); + if (current_tok->kind == TOK_REGULAR_MODE) { + return tok_get_normal_mode(tok, current_tok, token); + } else { + return tok_get_fstring_mode(tok, current_tok, token); + } +} + +int +_PyTokenizer_Get(struct tok_state *tok, struct token *token) +{ + int result = tok_get(tok, token); + if (tok->decoding_erred) { + result = ERRORTOKEN; + tok->done = E_DECODE; + } + return result; +} diff --git a/Parser/lexer/lexer.h b/Parser/lexer/lexer.h new file mode 100644 index 00000000000000..7f21bf56bba2d1 --- /dev/null +++ b/Parser/lexer/lexer.h @@ -0,0 +1,10 @@ +#ifndef _PY_LEXER_LEXER_H_ +#define _PY_LEXER_LEXER_H_ + +#include "state.h" + +int _PyLexer_update_fstring_expr(struct tok_state *tok, char cur); + +int _PyTokenizer_Get(struct tok_state *, struct token *); + +#endif diff --git a/Parser/lexer/state.c b/Parser/lexer/state.c new file mode 100644 index 00000000000000..653ddafd411095 --- /dev/null +++ b/Parser/lexer/state.c @@ -0,0 +1,149 @@ +#include "Python.h" +#include "pycore_pystate.h" +#include "pycore_token.h" +#include "errcode.h" + +#include "state.h" + +/* Never change this */ +#define TABSIZE 8 + +/* Create and initialize a new tok_state structure */ +struct tok_state * +_PyTokenizer_tok_new(void) +{ + struct tok_state *tok = (struct tok_state *)PyMem_Malloc( + sizeof(struct tok_state)); + if (tok == NULL) + return NULL; + tok->buf = tok->cur = tok->inp = NULL; + tok->fp_interactive = 0; + tok->interactive_src_start = NULL; + tok->interactive_src_end = NULL; + tok->start = NULL; + tok->end = NULL; + tok->done = E_OK; + tok->fp = NULL; + tok->input = NULL; + tok->tabsize = TABSIZE; + tok->indent = 0; + tok->indstack[0] = 0; + tok->atbol = 1; + tok->pendin = 0; + tok->prompt = tok->nextprompt = NULL; + tok->lineno = 0; + tok->starting_col_offset = -1; + tok->col_offset = -1; + tok->level = 0; + tok->altindstack[0] = 0; + tok->decoding_state = STATE_INIT; + tok->decoding_erred = 0; + tok->enc = NULL; + tok->encoding = NULL; + tok->cont_line = 0; + tok->filename = NULL; + tok->decoding_readline = NULL; + tok->decoding_buffer = NULL; + tok->readline = NULL; + tok->type_comments = 0; + tok->interactive_underflow = IUNDERFLOW_NORMAL; + tok->underflow = NULL; + tok->str = NULL; + tok->report_warnings = 1; + tok->tok_extra_tokens = 0; + tok->comment_newline = 0; + tok->implicit_newline = 0; + tok->tok_mode_stack[0] = (tokenizer_mode){.kind =TOK_REGULAR_MODE, .f_string_quote='\0', .f_string_quote_size = 0, .f_string_debug=0}; + tok->tok_mode_stack_index = 0; +#ifdef Py_DEBUG + tok->debug = _Py_GetConfig()->parser_debug; +#endif + return tok; +} + +static void +free_fstring_expressions(struct tok_state *tok) +{ + int index; + tokenizer_mode *mode; + + for (index = tok->tok_mode_stack_index; index >= 0; --index) { + mode = &(tok->tok_mode_stack[index]); + if (mode->last_expr_buffer != NULL) { + PyMem_Free(mode->last_expr_buffer); + mode->last_expr_buffer = NULL; + mode->last_expr_size = 0; + mode->last_expr_end = -1; + } + } +} + +/* Free a tok_state structure */ +void +_PyTokenizer_Free(struct tok_state *tok) +{ + if (tok->encoding != NULL) { + PyMem_Free(tok->encoding); + } + Py_XDECREF(tok->decoding_readline); + Py_XDECREF(tok->decoding_buffer); + Py_XDECREF(tok->readline); + Py_XDECREF(tok->filename); + if ((tok->readline != NULL || tok->fp != NULL ) && tok->buf != NULL) { + PyMem_Free(tok->buf); + } + if (tok->input) { + PyMem_Free(tok->input); + } + if (tok->interactive_src_start != NULL) { + PyMem_Free(tok->interactive_src_start); + } + free_fstring_expressions(tok); + PyMem_Free(tok); +} + +void +_PyToken_Free(struct token *token) { + Py_XDECREF(token->metadata); +} + +void +_PyToken_Init(struct token *token) { + token->metadata = NULL; +} + +int +_PyLexer_type_comment_token_setup(struct tok_state *tok, struct token *token, int type, int col_offset, + int end_col_offset, const char *start, const char *end) +{ + token->level = tok->level; + token->lineno = token->end_lineno = tok->lineno; + token->col_offset = col_offset; + token->end_col_offset = end_col_offset; + token->start = start; + token->end = end; + return type; +} + +int +_PyLexer_token_setup(struct tok_state *tok, struct token *token, int type, const char *start, const char *end) +{ + assert((start == NULL && end == NULL) || (start != NULL && end != NULL)); + token->level = tok->level; + if (ISSTRINGLIT(type)) { + token->lineno = tok->first_lineno; + } + else { + token->lineno = tok->lineno; + } + token->end_lineno = tok->lineno; + token->col_offset = token->end_col_offset = -1; + token->start = start; + token->end = end; + + if (start != NULL && end != NULL) { + token->col_offset = tok->starting_col_offset; + token->end_col_offset = tok->col_offset; + } + return type; +} diff --git a/Parser/tokenizer.h b/Parser/lexer/state.h similarity index 78% rename from Parser/tokenizer.h rename to Parser/lexer/state.h index cb44845c1d306e..61d090d6d2fe21 100644 --- a/Parser/tokenizer.h +++ b/Parser/lexer/state.h @@ -1,19 +1,15 @@ -#ifndef Py_TOKENIZER_H -#define Py_TOKENIZER_H -#ifdef __cplusplus -extern "C" { -#endif +#ifndef _PY_LEXER_H_ +#define _PY_LEXER_H_ #include "object.h" -/* Tokenizer interface */ - -#include "pycore_token.h" /* For token types */ - #define MAXINDENT 100 /* Max indentation level */ #define MAXLEVEL 200 /* Max parentheses level */ #define MAXFSTRINGLEVEL 150 /* Max f-string nesting level */ +#define INSIDE_FSTRING(tok) (tok->tok_mode_stack_index > 0) +#define INSIDE_FSTRING_EXPR(tok) (tok->curly_bracket_expr_start_depth >= 0) + enum decoding_state { STATE_INIT, STATE_SEEK_CODING, @@ -116,19 +112,14 @@ struct tok_state { int type_comments; /* Whether to look for type comments */ - /* async/await related fields (still needed depending on feature_version) */ - int async_hacks; /* =1 if async/await aren't always keywords */ - int async_def; /* =1 if tokens are inside an 'async def' body. */ - int async_def_indent; /* Indentation level of the outermost 'async def'. */ - int async_def_nl; /* =1 if the outermost 'async def' had at least one - NEWLINE token after it. */ /* How to proceed when asked for a new token in interactive mode */ enum interactive_underflow_t interactive_underflow; + int (*underflow)(struct tok_state *); /* Function to call when buffer is empty and we need to refill it*/ + int report_warnings; // TODO: Factor this into its own thing tokenizer_mode tok_mode_stack[MAXFSTRINGLEVEL]; int tok_mode_stack_index; - int tok_report_warnings; int tok_extra_tokens; int comment_newline; int implicit_newline; @@ -137,19 +128,14 @@ struct tok_state { #endif }; -extern struct tok_state *_PyTokenizer_FromString(const char *, int, int); -extern struct tok_state *_PyTokenizer_FromUTF8(const char *, int, int); -extern struct tok_state *_PyTokenizer_FromReadline(PyObject*, const char*, int, int); -extern struct tok_state *_PyTokenizer_FromFile(FILE *, const char*, - const char *, const char *); -extern void _PyTokenizer_Free(struct tok_state *); -extern void _PyToken_Free(struct token *); -extern void _PyToken_Init(struct token *); -extern int _PyTokenizer_Get(struct tok_state *, struct token *); +int _PyLexer_type_comment_token_setup(struct tok_state *tok, struct token *token, int type, int col_offset, + int end_col_offset, const char *start, const char *end); +int _PyLexer_token_setup(struct tok_state *tok, struct token *token, int type, const char *start, const char *end); + +struct tok_state *_PyTokenizer_tok_new(void); +void _PyTokenizer_Free(struct tok_state *); +void _PyToken_Free(struct token *); +void _PyToken_Init(struct token *); -#define tok_dump _Py_tok_dump -#ifdef __cplusplus -} #endif -#endif /* !Py_TOKENIZER_H */ diff --git a/Parser/myreadline.c b/Parser/myreadline.c index 7074aba74b728c..1825665354844b 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -1,5 +1,5 @@ -/* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c. +/* Readline interface for the tokenizer and [raw_]input() in bltinmodule.c. By default, or when stdin is not a tty device, we have a super simple my_readline function using fgets. Optionally, we can use the GNU readline library. @@ -14,13 +14,19 @@ #include "pycore_pystate.h" // _PyThreadState_GET() #ifdef MS_WINDOWS # ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN # endif # include "windows.h" #endif /* MS_WINDOWS */ +#ifdef HAVE_UNISTD_H +# include // isatty() +#endif + -PyThreadState* _PyOS_ReadlineTState = NULL; +// Export the symbol since it's used by the readline shared extension +PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; +PyThreadState *_PyOS_ReadlineTState = NULL; static PyThread_type_lock _PyOS_ReadlineLock = NULL; @@ -358,7 +364,7 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) = NULL; -/* Interface used by tokenizer.c and bltinmodule.c */ +/* Interface used by file_tokenizer.c and bltinmodule.c */ char * PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) diff --git a/Parser/parser.c b/Parser/parser.c index f2ea8f59b00567..b10bf69e4df2ef 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -17,57 +17,59 @@ static KeywordToken *reserved_keywords[] = { (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) { - {"if", 642}, - {"as", 640}, - {"in", 651}, - {"or", 574}, - {"is", 582}, + {"if", 656}, + {"as", 654}, + {"in", 667}, + {"or", 581}, + {"is", 589}, {NULL, -1}, }, (KeywordToken[]) { - {"del", 604}, - {"def", 652}, - {"for", 650}, - {"try", 624}, - {"and", 575}, - {"not", 581}, + {"del", 613}, + {"def", 669}, + {"for", 666}, + {"try", 638}, + {"and", 582}, + {"not", 588}, {NULL, -1}, }, (KeywordToken[]) { - {"from", 608}, + {"from", 618}, {"pass", 504}, - {"with", 615}, - {"elif", 644}, - {"else", 645}, - {"None", 602}, - {"True", 601}, + {"with", 629}, + {"elif", 658}, + {"else", 659}, + {"None", 611}, + {"True", 610}, {NULL, -1}, }, (KeywordToken[]) { - {"raise", 522}, - {"yield", 573}, + {"raise", 525}, + {"yield", 580}, {"break", 508}, - {"class", 654}, - {"while", 647}, - {"False", 603}, + {"async", 668}, + {"class", 671}, + {"while", 661}, + {"False", 612}, + {"await", 590}, {NULL, -1}, }, (KeywordToken[]) { - {"return", 519}, - {"import", 607}, - {"assert", 526}, - {"global", 523}, - {"except", 637}, - {"lambda", 600}, + {"return", 522}, + {"import", 617}, + {"assert", 529}, + {"global", 526}, + {"except", 651}, + {"lambda", 609}, {NULL, -1}, }, (KeywordToken[]) { - {"finally", 633}, + {"finally", 647}, {NULL, -1}, }, (KeywordToken[]) { {"continue", 509}, - {"nonlocal", 524}, + {"nonlocal", 527}, {NULL, -1}, }, }; @@ -82,159 +84,159 @@ static char *soft_keywords[] = { #define interactive_type 1001 #define eval_type 1002 #define func_type_type 1003 -#define fstring_type 1004 -#define statements_type 1005 -#define statement_type 1006 -#define statement_newline_type 1007 -#define simple_stmts_type 1008 -#define simple_stmt_type 1009 -#define compound_stmt_type 1010 -#define assignment_type 1011 -#define annotated_rhs_type 1012 -#define augassign_type 1013 -#define return_stmt_type 1014 -#define raise_stmt_type 1015 -#define global_stmt_type 1016 -#define nonlocal_stmt_type 1017 -#define del_stmt_type 1018 -#define yield_stmt_type 1019 -#define assert_stmt_type 1020 -#define import_stmt_type 1021 -#define import_name_type 1022 -#define import_from_type 1023 -#define import_from_targets_type 1024 -#define import_from_as_names_type 1025 -#define import_from_as_name_type 1026 -#define dotted_as_names_type 1027 -#define dotted_as_name_type 1028 -#define dotted_name_type 1029 // Left-recursive -#define block_type 1030 -#define decorators_type 1031 -#define class_def_type 1032 -#define class_def_raw_type 1033 -#define function_def_type 1034 -#define function_def_raw_type 1035 -#define params_type 1036 -#define parameters_type 1037 -#define slash_no_default_type 1038 -#define slash_with_default_type 1039 -#define star_etc_type 1040 -#define kwds_type 1041 -#define param_no_default_type 1042 -#define param_no_default_star_annotation_type 1043 -#define param_with_default_type 1044 -#define param_maybe_default_type 1045 -#define param_type 1046 -#define param_star_annotation_type 1047 -#define annotation_type 1048 -#define star_annotation_type 1049 -#define default_type 1050 -#define if_stmt_type 1051 -#define elif_stmt_type 1052 -#define else_block_type 1053 -#define while_stmt_type 1054 -#define for_stmt_type 1055 -#define with_stmt_type 1056 -#define with_item_type 1057 -#define try_stmt_type 1058 -#define except_block_type 1059 -#define except_star_block_type 1060 -#define finally_block_type 1061 -#define match_stmt_type 1062 -#define subject_expr_type 1063 -#define case_block_type 1064 -#define guard_type 1065 -#define patterns_type 1066 -#define pattern_type 1067 -#define as_pattern_type 1068 -#define or_pattern_type 1069 -#define closed_pattern_type 1070 -#define literal_pattern_type 1071 -#define literal_expr_type 1072 -#define complex_number_type 1073 -#define signed_number_type 1074 -#define signed_real_number_type 1075 -#define real_number_type 1076 -#define imaginary_number_type 1077 -#define capture_pattern_type 1078 -#define pattern_capture_target_type 1079 -#define wildcard_pattern_type 1080 -#define value_pattern_type 1081 -#define attr_type 1082 // Left-recursive -#define name_or_attr_type 1083 // Left-recursive -#define group_pattern_type 1084 -#define sequence_pattern_type 1085 -#define open_sequence_pattern_type 1086 -#define maybe_sequence_pattern_type 1087 -#define maybe_star_pattern_type 1088 -#define star_pattern_type 1089 -#define mapping_pattern_type 1090 -#define items_pattern_type 1091 -#define key_value_pattern_type 1092 -#define double_star_pattern_type 1093 -#define class_pattern_type 1094 -#define positional_patterns_type 1095 -#define keyword_patterns_type 1096 -#define keyword_pattern_type 1097 -#define type_alias_type 1098 -#define type_params_type 1099 -#define type_param_seq_type 1100 -#define type_param_type 1101 -#define type_param_bound_type 1102 -#define expressions_type 1103 -#define expression_type 1104 -#define yield_expr_type 1105 -#define star_expressions_type 1106 -#define star_expression_type 1107 -#define star_named_expressions_type 1108 -#define star_named_expression_type 1109 -#define assignment_expression_type 1110 -#define named_expression_type 1111 -#define disjunction_type 1112 -#define conjunction_type 1113 -#define inversion_type 1114 -#define comparison_type 1115 -#define compare_op_bitwise_or_pair_type 1116 -#define eq_bitwise_or_type 1117 -#define noteq_bitwise_or_type 1118 -#define lte_bitwise_or_type 1119 -#define lt_bitwise_or_type 1120 -#define gte_bitwise_or_type 1121 -#define gt_bitwise_or_type 1122 -#define notin_bitwise_or_type 1123 -#define in_bitwise_or_type 1124 -#define isnot_bitwise_or_type 1125 -#define is_bitwise_or_type 1126 -#define bitwise_or_type 1127 // Left-recursive -#define bitwise_xor_type 1128 // Left-recursive -#define bitwise_and_type 1129 // Left-recursive -#define shift_expr_type 1130 // Left-recursive -#define sum_type 1131 // Left-recursive -#define term_type 1132 // Left-recursive -#define factor_type 1133 -#define power_type 1134 -#define await_primary_type 1135 -#define primary_type 1136 // Left-recursive -#define slices_type 1137 -#define slice_type 1138 -#define atom_type 1139 -#define group_type 1140 -#define lambdef_type 1141 -#define lambda_params_type 1142 -#define lambda_parameters_type 1143 -#define lambda_slash_no_default_type 1144 -#define lambda_slash_with_default_type 1145 -#define lambda_star_etc_type 1146 -#define lambda_kwds_type 1147 -#define lambda_param_no_default_type 1148 -#define lambda_param_with_default_type 1149 -#define lambda_param_maybe_default_type 1150 -#define lambda_param_type 1151 -#define fstring_middle_type 1152 -#define fstring_replacement_field_type 1153 -#define fstring_conversion_type 1154 -#define fstring_full_format_spec_type 1155 -#define fstring_format_spec_type 1156 +#define statements_type 1004 +#define statement_type 1005 +#define statement_newline_type 1006 +#define simple_stmts_type 1007 +#define simple_stmt_type 1008 +#define compound_stmt_type 1009 +#define assignment_type 1010 +#define annotated_rhs_type 1011 +#define augassign_type 1012 +#define return_stmt_type 1013 +#define raise_stmt_type 1014 +#define global_stmt_type 1015 +#define nonlocal_stmt_type 1016 +#define del_stmt_type 1017 +#define yield_stmt_type 1018 +#define assert_stmt_type 1019 +#define import_stmt_type 1020 +#define import_name_type 1021 +#define import_from_type 1022 +#define import_from_targets_type 1023 +#define import_from_as_names_type 1024 +#define import_from_as_name_type 1025 +#define dotted_as_names_type 1026 +#define dotted_as_name_type 1027 +#define dotted_name_type 1028 // Left-recursive +#define block_type 1029 +#define decorators_type 1030 +#define class_def_type 1031 +#define class_def_raw_type 1032 +#define function_def_type 1033 +#define function_def_raw_type 1034 +#define params_type 1035 +#define parameters_type 1036 +#define slash_no_default_type 1037 +#define slash_with_default_type 1038 +#define star_etc_type 1039 +#define kwds_type 1040 +#define param_no_default_type 1041 +#define param_no_default_star_annotation_type 1042 +#define param_with_default_type 1043 +#define param_maybe_default_type 1044 +#define param_type 1045 +#define param_star_annotation_type 1046 +#define annotation_type 1047 +#define star_annotation_type 1048 +#define default_type 1049 +#define if_stmt_type 1050 +#define elif_stmt_type 1051 +#define else_block_type 1052 +#define while_stmt_type 1053 +#define for_stmt_type 1054 +#define with_stmt_type 1055 +#define with_item_type 1056 +#define try_stmt_type 1057 +#define except_block_type 1058 +#define except_star_block_type 1059 +#define finally_block_type 1060 +#define match_stmt_type 1061 +#define subject_expr_type 1062 +#define case_block_type 1063 +#define guard_type 1064 +#define patterns_type 1065 +#define pattern_type 1066 +#define as_pattern_type 1067 +#define or_pattern_type 1068 +#define closed_pattern_type 1069 +#define literal_pattern_type 1070 +#define literal_expr_type 1071 +#define complex_number_type 1072 +#define signed_number_type 1073 +#define signed_real_number_type 1074 +#define real_number_type 1075 +#define imaginary_number_type 1076 +#define capture_pattern_type 1077 +#define pattern_capture_target_type 1078 +#define wildcard_pattern_type 1079 +#define value_pattern_type 1080 +#define attr_type 1081 // Left-recursive +#define name_or_attr_type 1082 // Left-recursive +#define group_pattern_type 1083 +#define sequence_pattern_type 1084 +#define open_sequence_pattern_type 1085 +#define maybe_sequence_pattern_type 1086 +#define maybe_star_pattern_type 1087 +#define star_pattern_type 1088 +#define mapping_pattern_type 1089 +#define items_pattern_type 1090 +#define key_value_pattern_type 1091 +#define double_star_pattern_type 1092 +#define class_pattern_type 1093 +#define positional_patterns_type 1094 +#define keyword_patterns_type 1095 +#define keyword_pattern_type 1096 +#define type_alias_type 1097 +#define type_params_type 1098 +#define type_param_seq_type 1099 +#define type_param_type 1100 +#define type_param_bound_type 1101 +#define expressions_type 1102 +#define expression_type 1103 +#define yield_expr_type 1104 +#define star_expressions_type 1105 +#define star_expression_type 1106 +#define star_named_expressions_type 1107 +#define star_named_expression_type 1108 +#define assignment_expression_type 1109 +#define named_expression_type 1110 +#define disjunction_type 1111 +#define conjunction_type 1112 +#define inversion_type 1113 +#define comparison_type 1114 +#define compare_op_bitwise_or_pair_type 1115 +#define eq_bitwise_or_type 1116 +#define noteq_bitwise_or_type 1117 +#define lte_bitwise_or_type 1118 +#define lt_bitwise_or_type 1119 +#define gte_bitwise_or_type 1120 +#define gt_bitwise_or_type 1121 +#define notin_bitwise_or_type 1122 +#define in_bitwise_or_type 1123 +#define isnot_bitwise_or_type 1124 +#define is_bitwise_or_type 1125 +#define bitwise_or_type 1126 // Left-recursive +#define bitwise_xor_type 1127 // Left-recursive +#define bitwise_and_type 1128 // Left-recursive +#define shift_expr_type 1129 // Left-recursive +#define sum_type 1130 // Left-recursive +#define term_type 1131 // Left-recursive +#define factor_type 1132 +#define power_type 1133 +#define await_primary_type 1134 +#define primary_type 1135 // Left-recursive +#define slices_type 1136 +#define slice_type 1137 +#define atom_type 1138 +#define group_type 1139 +#define lambdef_type 1140 +#define lambda_params_type 1141 +#define lambda_parameters_type 1142 +#define lambda_slash_no_default_type 1143 +#define lambda_slash_with_default_type 1144 +#define lambda_star_etc_type 1145 +#define lambda_kwds_type 1146 +#define lambda_param_no_default_type 1147 +#define lambda_param_with_default_type 1148 +#define lambda_param_maybe_default_type 1149 +#define lambda_param_type 1150 +#define fstring_middle_type 1151 +#define fstring_replacement_field_type 1152 +#define fstring_conversion_type 1153 +#define fstring_full_format_spec_type 1154 +#define fstring_format_spec_type 1155 +#define fstring_type 1156 #define string_type 1157 #define strings_type 1158 #define list_type 1159 @@ -324,10 +326,10 @@ static char *soft_keywords[] = { #define invalid_conversion_character_type 1243 #define _loop0_1_type 1244 #define _loop0_2_type 1245 -#define _loop0_3_type 1246 -#define _loop1_4_type 1247 -#define _loop0_6_type 1248 -#define _gather_5_type 1249 +#define _loop1_3_type 1246 +#define _loop0_5_type 1247 +#define _gather_4_type 1248 +#define _tmp_6_type 1249 #define _tmp_7_type 1250 #define _tmp_8_type 1251 #define _tmp_9_type 1252 @@ -335,106 +337,106 @@ static char *soft_keywords[] = { #define _tmp_11_type 1254 #define _tmp_12_type 1255 #define _tmp_13_type 1256 -#define _tmp_14_type 1257 -#define _loop1_15_type 1258 +#define _loop1_14_type 1257 +#define _tmp_15_type 1258 #define _tmp_16_type 1259 #define _tmp_17_type 1260 -#define _tmp_18_type 1261 -#define _loop0_20_type 1262 -#define _gather_19_type 1263 -#define _loop0_22_type 1264 -#define _gather_21_type 1265 +#define _loop0_19_type 1261 +#define _gather_18_type 1262 +#define _loop0_21_type 1263 +#define _gather_20_type 1264 +#define _tmp_22_type 1265 #define _tmp_23_type 1266 -#define _tmp_24_type 1267 -#define _loop0_25_type 1268 -#define _loop1_26_type 1269 -#define _loop0_28_type 1270 -#define _gather_27_type 1271 -#define _tmp_29_type 1272 -#define _loop0_31_type 1273 -#define _gather_30_type 1274 -#define _tmp_32_type 1275 -#define _loop1_33_type 1276 +#define _loop0_24_type 1267 +#define _loop1_25_type 1268 +#define _loop0_27_type 1269 +#define _gather_26_type 1270 +#define _tmp_28_type 1271 +#define _loop0_30_type 1272 +#define _gather_29_type 1273 +#define _tmp_31_type 1274 +#define _loop1_32_type 1275 +#define _tmp_33_type 1276 #define _tmp_34_type 1277 #define _tmp_35_type 1278 -#define _tmp_36_type 1279 +#define _loop0_36_type 1279 #define _loop0_37_type 1280 #define _loop0_38_type 1281 -#define _loop0_39_type 1282 -#define _loop1_40_type 1283 -#define _loop0_41_type 1284 +#define _loop1_39_type 1282 +#define _loop0_40_type 1283 +#define _loop1_41_type 1284 #define _loop1_42_type 1285 #define _loop1_43_type 1286 -#define _loop1_44_type 1287 -#define _loop0_45_type 1288 -#define _loop1_46_type 1289 -#define _loop0_47_type 1290 -#define _loop1_48_type 1291 +#define _loop0_44_type 1287 +#define _loop1_45_type 1288 +#define _loop0_46_type 1289 +#define _loop1_47_type 1290 +#define _loop0_48_type 1291 #define _loop0_49_type 1292 -#define _loop0_50_type 1293 -#define _loop1_51_type 1294 -#define _loop0_53_type 1295 -#define _gather_52_type 1296 -#define _loop0_55_type 1297 -#define _gather_54_type 1298 -#define _loop0_57_type 1299 -#define _gather_56_type 1300 -#define _loop0_59_type 1301 -#define _gather_58_type 1302 -#define _tmp_60_type 1303 +#define _loop1_50_type 1293 +#define _loop0_52_type 1294 +#define _gather_51_type 1295 +#define _loop0_54_type 1296 +#define _gather_53_type 1297 +#define _loop0_56_type 1298 +#define _gather_55_type 1299 +#define _loop0_58_type 1300 +#define _gather_57_type 1301 +#define _tmp_59_type 1302 +#define _loop1_60_type 1303 #define _loop1_61_type 1304 -#define _loop1_62_type 1305 +#define _tmp_62_type 1305 #define _tmp_63_type 1306 -#define _tmp_64_type 1307 -#define _loop1_65_type 1308 -#define _loop0_67_type 1309 -#define _gather_66_type 1310 +#define _loop1_64_type 1307 +#define _loop0_66_type 1308 +#define _gather_65_type 1309 +#define _tmp_67_type 1310 #define _tmp_68_type 1311 #define _tmp_69_type 1312 #define _tmp_70_type 1313 -#define _tmp_71_type 1314 -#define _loop0_73_type 1315 -#define _gather_72_type 1316 -#define _loop0_75_type 1317 -#define _gather_74_type 1318 -#define _tmp_76_type 1319 -#define _loop0_78_type 1320 -#define _gather_77_type 1321 -#define _loop0_80_type 1322 -#define _gather_79_type 1323 -#define _loop0_82_type 1324 -#define _gather_81_type 1325 +#define _loop0_72_type 1314 +#define _gather_71_type 1315 +#define _loop0_74_type 1316 +#define _gather_73_type 1317 +#define _tmp_75_type 1318 +#define _loop0_77_type 1319 +#define _gather_76_type 1320 +#define _loop0_79_type 1321 +#define _gather_78_type 1322 +#define _loop0_81_type 1323 +#define _gather_80_type 1324 +#define _loop1_82_type 1325 #define _loop1_83_type 1326 -#define _loop1_84_type 1327 -#define _loop0_86_type 1328 -#define _gather_85_type 1329 +#define _loop0_85_type 1327 +#define _gather_84_type 1328 +#define _loop1_86_type 1329 #define _loop1_87_type 1330 #define _loop1_88_type 1331 -#define _loop1_89_type 1332 -#define _tmp_90_type 1333 -#define _loop0_92_type 1334 -#define _gather_91_type 1335 +#define _tmp_89_type 1332 +#define _loop0_91_type 1333 +#define _gather_90_type 1334 +#define _tmp_92_type 1335 #define _tmp_93_type 1336 #define _tmp_94_type 1337 #define _tmp_95_type 1338 #define _tmp_96_type 1339 #define _tmp_97_type 1340 -#define _tmp_98_type 1341 +#define _loop0_98_type 1341 #define _loop0_99_type 1342 #define _loop0_100_type 1343 -#define _loop0_101_type 1344 -#define _loop1_102_type 1345 -#define _loop0_103_type 1346 +#define _loop1_101_type 1344 +#define _loop0_102_type 1345 +#define _loop1_103_type 1346 #define _loop1_104_type 1347 #define _loop1_105_type 1348 -#define _loop1_106_type 1349 -#define _loop0_107_type 1350 -#define _loop1_108_type 1351 -#define _loop0_109_type 1352 -#define _loop1_110_type 1353 -#define _loop0_111_type 1354 -#define _loop1_112_type 1355 -#define _tmp_113_type 1356 +#define _loop0_106_type 1349 +#define _loop1_107_type 1350 +#define _loop0_108_type 1351 +#define _loop1_109_type 1352 +#define _loop0_110_type 1353 +#define _loop1_111_type 1354 +#define _tmp_112_type 1355 +#define _loop0_113_type 1356 #define _loop0_114_type 1357 #define _loop1_115_type 1358 #define _tmp_116_type 1359 @@ -595,15 +597,19 @@ static char *soft_keywords[] = { #define _tmp_271_type 1514 #define _tmp_272_type 1515 #define _tmp_273_type 1516 -#define _tmp_274_type 1517 -#define _tmp_275_type 1518 +#define _loop0_275_type 1517 +#define _gather_274_type 1518 #define _tmp_276_type 1519 +#define _tmp_277_type 1520 +#define _tmp_278_type 1521 +#define _tmp_279_type 1522 +#define _tmp_280_type 1523 +#define _tmp_281_type 1524 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); static mod_ty eval_rule(Parser *p); static mod_ty func_type_rule(Parser *p); -static expr_ty fstring_rule(Parser *p); static asdl_stmt_seq* statements_rule(Parser *p); static asdl_stmt_seq* statement_rule(Parser *p); static asdl_stmt_seq* statement_newline_rule(Parser *p); @@ -756,6 +762,7 @@ static expr_ty fstring_replacement_field_rule(Parser *p); static ResultTokenWithMetadata* fstring_conversion_rule(Parser *p); static ResultTokenWithMetadata* fstring_full_format_spec_rule(Parser *p); static expr_ty fstring_format_spec_rule(Parser *p); +static expr_ty fstring_rule(Parser *p); static expr_ty string_rule(Parser *p); static expr_ty strings_rule(Parser *p); static expr_ty list_rule(Parser *p); @@ -845,10 +852,10 @@ static void *invalid_replacement_field_rule(Parser *p); static void *invalid_conversion_character_rule(Parser *p); static asdl_seq *_loop0_1_rule(Parser *p); static asdl_seq *_loop0_2_rule(Parser *p); -static asdl_seq *_loop0_3_rule(Parser *p); -static asdl_seq *_loop1_4_rule(Parser *p); -static asdl_seq *_loop0_6_rule(Parser *p); -static asdl_seq *_gather_5_rule(Parser *p); +static asdl_seq *_loop1_3_rule(Parser *p); +static asdl_seq *_loop0_5_rule(Parser *p); +static asdl_seq *_gather_4_rule(Parser *p); +static void *_tmp_6_rule(Parser *p); static void *_tmp_7_rule(Parser *p); static void *_tmp_8_rule(Parser *p); static void *_tmp_9_rule(Parser *p); @@ -856,106 +863,106 @@ static void *_tmp_10_rule(Parser *p); static void *_tmp_11_rule(Parser *p); static void *_tmp_12_rule(Parser *p); static void *_tmp_13_rule(Parser *p); -static void *_tmp_14_rule(Parser *p); -static asdl_seq *_loop1_15_rule(Parser *p); +static asdl_seq *_loop1_14_rule(Parser *p); +static void *_tmp_15_rule(Parser *p); static void *_tmp_16_rule(Parser *p); static void *_tmp_17_rule(Parser *p); -static void *_tmp_18_rule(Parser *p); -static asdl_seq *_loop0_20_rule(Parser *p); -static asdl_seq *_gather_19_rule(Parser *p); -static asdl_seq *_loop0_22_rule(Parser *p); -static asdl_seq *_gather_21_rule(Parser *p); +static asdl_seq *_loop0_19_rule(Parser *p); +static asdl_seq *_gather_18_rule(Parser *p); +static asdl_seq *_loop0_21_rule(Parser *p); +static asdl_seq *_gather_20_rule(Parser *p); +static void *_tmp_22_rule(Parser *p); static void *_tmp_23_rule(Parser *p); -static void *_tmp_24_rule(Parser *p); -static asdl_seq *_loop0_25_rule(Parser *p); -static asdl_seq *_loop1_26_rule(Parser *p); -static asdl_seq *_loop0_28_rule(Parser *p); -static asdl_seq *_gather_27_rule(Parser *p); -static void *_tmp_29_rule(Parser *p); -static asdl_seq *_loop0_31_rule(Parser *p); -static asdl_seq *_gather_30_rule(Parser *p); -static void *_tmp_32_rule(Parser *p); -static asdl_seq *_loop1_33_rule(Parser *p); +static asdl_seq *_loop0_24_rule(Parser *p); +static asdl_seq *_loop1_25_rule(Parser *p); +static asdl_seq *_loop0_27_rule(Parser *p); +static asdl_seq *_gather_26_rule(Parser *p); +static void *_tmp_28_rule(Parser *p); +static asdl_seq *_loop0_30_rule(Parser *p); +static asdl_seq *_gather_29_rule(Parser *p); +static void *_tmp_31_rule(Parser *p); +static asdl_seq *_loop1_32_rule(Parser *p); +static void *_tmp_33_rule(Parser *p); static void *_tmp_34_rule(Parser *p); static void *_tmp_35_rule(Parser *p); -static void *_tmp_36_rule(Parser *p); +static asdl_seq *_loop0_36_rule(Parser *p); static asdl_seq *_loop0_37_rule(Parser *p); static asdl_seq *_loop0_38_rule(Parser *p); -static asdl_seq *_loop0_39_rule(Parser *p); -static asdl_seq *_loop1_40_rule(Parser *p); -static asdl_seq *_loop0_41_rule(Parser *p); +static asdl_seq *_loop1_39_rule(Parser *p); +static asdl_seq *_loop0_40_rule(Parser *p); +static asdl_seq *_loop1_41_rule(Parser *p); static asdl_seq *_loop1_42_rule(Parser *p); static asdl_seq *_loop1_43_rule(Parser *p); -static asdl_seq *_loop1_44_rule(Parser *p); -static asdl_seq *_loop0_45_rule(Parser *p); -static asdl_seq *_loop1_46_rule(Parser *p); -static asdl_seq *_loop0_47_rule(Parser *p); -static asdl_seq *_loop1_48_rule(Parser *p); +static asdl_seq *_loop0_44_rule(Parser *p); +static asdl_seq *_loop1_45_rule(Parser *p); +static asdl_seq *_loop0_46_rule(Parser *p); +static asdl_seq *_loop1_47_rule(Parser *p); +static asdl_seq *_loop0_48_rule(Parser *p); static asdl_seq *_loop0_49_rule(Parser *p); -static asdl_seq *_loop0_50_rule(Parser *p); -static asdl_seq *_loop1_51_rule(Parser *p); -static asdl_seq *_loop0_53_rule(Parser *p); -static asdl_seq *_gather_52_rule(Parser *p); -static asdl_seq *_loop0_55_rule(Parser *p); -static asdl_seq *_gather_54_rule(Parser *p); -static asdl_seq *_loop0_57_rule(Parser *p); -static asdl_seq *_gather_56_rule(Parser *p); -static asdl_seq *_loop0_59_rule(Parser *p); -static asdl_seq *_gather_58_rule(Parser *p); -static void *_tmp_60_rule(Parser *p); +static asdl_seq *_loop1_50_rule(Parser *p); +static asdl_seq *_loop0_52_rule(Parser *p); +static asdl_seq *_gather_51_rule(Parser *p); +static asdl_seq *_loop0_54_rule(Parser *p); +static asdl_seq *_gather_53_rule(Parser *p); +static asdl_seq *_loop0_56_rule(Parser *p); +static asdl_seq *_gather_55_rule(Parser *p); +static asdl_seq *_loop0_58_rule(Parser *p); +static asdl_seq *_gather_57_rule(Parser *p); +static void *_tmp_59_rule(Parser *p); +static asdl_seq *_loop1_60_rule(Parser *p); static asdl_seq *_loop1_61_rule(Parser *p); -static asdl_seq *_loop1_62_rule(Parser *p); +static void *_tmp_62_rule(Parser *p); static void *_tmp_63_rule(Parser *p); -static void *_tmp_64_rule(Parser *p); -static asdl_seq *_loop1_65_rule(Parser *p); -static asdl_seq *_loop0_67_rule(Parser *p); -static asdl_seq *_gather_66_rule(Parser *p); +static asdl_seq *_loop1_64_rule(Parser *p); +static asdl_seq *_loop0_66_rule(Parser *p); +static asdl_seq *_gather_65_rule(Parser *p); +static void *_tmp_67_rule(Parser *p); static void *_tmp_68_rule(Parser *p); static void *_tmp_69_rule(Parser *p); static void *_tmp_70_rule(Parser *p); -static void *_tmp_71_rule(Parser *p); -static asdl_seq *_loop0_73_rule(Parser *p); -static asdl_seq *_gather_72_rule(Parser *p); -static asdl_seq *_loop0_75_rule(Parser *p); -static asdl_seq *_gather_74_rule(Parser *p); -static void *_tmp_76_rule(Parser *p); -static asdl_seq *_loop0_78_rule(Parser *p); -static asdl_seq *_gather_77_rule(Parser *p); -static asdl_seq *_loop0_80_rule(Parser *p); -static asdl_seq *_gather_79_rule(Parser *p); -static asdl_seq *_loop0_82_rule(Parser *p); -static asdl_seq *_gather_81_rule(Parser *p); +static asdl_seq *_loop0_72_rule(Parser *p); +static asdl_seq *_gather_71_rule(Parser *p); +static asdl_seq *_loop0_74_rule(Parser *p); +static asdl_seq *_gather_73_rule(Parser *p); +static void *_tmp_75_rule(Parser *p); +static asdl_seq *_loop0_77_rule(Parser *p); +static asdl_seq *_gather_76_rule(Parser *p); +static asdl_seq *_loop0_79_rule(Parser *p); +static asdl_seq *_gather_78_rule(Parser *p); +static asdl_seq *_loop0_81_rule(Parser *p); +static asdl_seq *_gather_80_rule(Parser *p); +static asdl_seq *_loop1_82_rule(Parser *p); static asdl_seq *_loop1_83_rule(Parser *p); -static asdl_seq *_loop1_84_rule(Parser *p); -static asdl_seq *_loop0_86_rule(Parser *p); -static asdl_seq *_gather_85_rule(Parser *p); +static asdl_seq *_loop0_85_rule(Parser *p); +static asdl_seq *_gather_84_rule(Parser *p); +static asdl_seq *_loop1_86_rule(Parser *p); static asdl_seq *_loop1_87_rule(Parser *p); static asdl_seq *_loop1_88_rule(Parser *p); -static asdl_seq *_loop1_89_rule(Parser *p); -static void *_tmp_90_rule(Parser *p); -static asdl_seq *_loop0_92_rule(Parser *p); -static asdl_seq *_gather_91_rule(Parser *p); +static void *_tmp_89_rule(Parser *p); +static asdl_seq *_loop0_91_rule(Parser *p); +static asdl_seq *_gather_90_rule(Parser *p); +static void *_tmp_92_rule(Parser *p); static void *_tmp_93_rule(Parser *p); static void *_tmp_94_rule(Parser *p); static void *_tmp_95_rule(Parser *p); static void *_tmp_96_rule(Parser *p); static void *_tmp_97_rule(Parser *p); -static void *_tmp_98_rule(Parser *p); +static asdl_seq *_loop0_98_rule(Parser *p); static asdl_seq *_loop0_99_rule(Parser *p); static asdl_seq *_loop0_100_rule(Parser *p); -static asdl_seq *_loop0_101_rule(Parser *p); -static asdl_seq *_loop1_102_rule(Parser *p); -static asdl_seq *_loop0_103_rule(Parser *p); +static asdl_seq *_loop1_101_rule(Parser *p); +static asdl_seq *_loop0_102_rule(Parser *p); +static asdl_seq *_loop1_103_rule(Parser *p); static asdl_seq *_loop1_104_rule(Parser *p); static asdl_seq *_loop1_105_rule(Parser *p); -static asdl_seq *_loop1_106_rule(Parser *p); -static asdl_seq *_loop0_107_rule(Parser *p); -static asdl_seq *_loop1_108_rule(Parser *p); -static asdl_seq *_loop0_109_rule(Parser *p); -static asdl_seq *_loop1_110_rule(Parser *p); -static asdl_seq *_loop0_111_rule(Parser *p); -static asdl_seq *_loop1_112_rule(Parser *p); -static void *_tmp_113_rule(Parser *p); +static asdl_seq *_loop0_106_rule(Parser *p); +static asdl_seq *_loop1_107_rule(Parser *p); +static asdl_seq *_loop0_108_rule(Parser *p); +static asdl_seq *_loop1_109_rule(Parser *p); +static asdl_seq *_loop0_110_rule(Parser *p); +static asdl_seq *_loop1_111_rule(Parser *p); +static void *_tmp_112_rule(Parser *p); +static asdl_seq *_loop0_113_rule(Parser *p); static asdl_seq *_loop0_114_rule(Parser *p); static asdl_seq *_loop1_115_rule(Parser *p); static void *_tmp_116_rule(Parser *p); @@ -1116,9 +1123,14 @@ static void *_tmp_270_rule(Parser *p); static void *_tmp_271_rule(Parser *p); static void *_tmp_272_rule(Parser *p); static void *_tmp_273_rule(Parser *p); -static void *_tmp_274_rule(Parser *p); -static void *_tmp_275_rule(Parser *p); +static asdl_seq *_loop0_275_rule(Parser *p); +static asdl_seq *_gather_274_rule(Parser *p); static void *_tmp_276_rule(Parser *p); +static void *_tmp_277_rule(Parser *p); +static void *_tmp_278_rule(Parser *p); +static void *_tmp_279_rule(Parser *p); +static void *_tmp_280_rule(Parser *p); +static void *_tmp_281_rule(Parser *p); // file: statements? $ @@ -1126,8 +1138,7 @@ static mod_ty file_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1173,8 +1184,7 @@ static mod_ty interactive_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1217,8 +1227,7 @@ static mod_ty eval_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1267,8 +1276,7 @@ static mod_ty func_type_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1324,63 +1332,12 @@ func_type_rule(Parser *p) return _res; } -// fstring: FSTRING_START fstring_middle* FSTRING_END -static expr_ty -fstring_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - expr_ty _res = NULL; - int _mark = p->mark; - { // FSTRING_START fstring_middle* FSTRING_END - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> fstring[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); - Token * a; - asdl_seq * b; - Token * c; - if ( - (a = _PyPegen_expect_token(p, FSTRING_START)) // token='FSTRING_START' - && - (b = _loop0_3_rule(p)) // fstring_middle* - && - (c = _PyPegen_expect_token(p, FSTRING_END)) // token='FSTRING_END' - ) - { - D(fprintf(stderr, "%*c+ fstring[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); - _res = _PyPegen_joined_str ( p , a , ( asdl_expr_seq* ) b , c ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s fstring[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); - } - _res = NULL; - done: - p->level--; - return _res; -} - // statements: statement+ static asdl_stmt_seq* statements_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1396,7 +1353,7 @@ statements_rule(Parser *p) D(fprintf(stderr, "%*c> statements[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement+")); asdl_seq * a; if ( - (a = _loop1_4_rule(p)) // statement+ + (a = _loop1_3_rule(p)) // statement+ ) { D(fprintf(stderr, "%*c+ statements[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement+")); @@ -1423,8 +1380,7 @@ static asdl_stmt_seq* statement_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1491,8 +1447,7 @@ static asdl_stmt_seq* statement_newline_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1623,8 +1578,7 @@ static asdl_stmt_seq* simple_stmts_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1672,7 +1626,7 @@ simple_stmts_rule(Parser *p) asdl_stmt_seq* a; Token * newline_var; if ( - (a = (asdl_stmt_seq*)_gather_5_rule(p)) // ';'.simple_stmt+ + (a = (asdl_stmt_seq*)_gather_4_rule(p)) // ';'.simple_stmt+ && (_opt_var = _PyPegen_expect_token(p, 13), !p->error_indicator) // ';'? && @@ -1717,8 +1671,7 @@ static stmt_ty simple_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1820,7 +1773,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'return' return_stmt")); stmt_ty return_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 519) // token='return' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 522) // token='return' && (return_stmt_var = return_stmt_rule(p)) // return_stmt ) @@ -1841,7 +1794,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); stmt_ty import_stmt_var; if ( - _PyPegen_lookahead(1, _tmp_7_rule, p) + _PyPegen_lookahead(1, _tmp_6_rule, p) && (import_stmt_var = import_stmt_rule(p)) // import_stmt ) @@ -1862,7 +1815,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'raise' raise_stmt")); stmt_ty raise_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 522) // token='raise' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 525) // token='raise' && (raise_stmt_var = raise_stmt_rule(p)) // raise_stmt ) @@ -1916,7 +1869,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'del' del_stmt")); stmt_ty del_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 604) // token='del' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 613) // token='del' && (del_stmt_var = del_stmt_rule(p)) // del_stmt ) @@ -1937,7 +1890,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'yield' yield_stmt")); stmt_ty yield_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 573) // token='yield' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 580) // token='yield' && (yield_stmt_var = yield_stmt_rule(p)) // yield_stmt ) @@ -1958,7 +1911,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'assert' assert_stmt")); stmt_ty assert_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 526) // token='assert' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 529) // token='assert' && (assert_stmt_var = assert_stmt_rule(p)) // assert_stmt ) @@ -2045,7 +1998,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'global' global_stmt")); stmt_ty global_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 523) // token='global' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 526) // token='global' && (global_stmt_var = global_stmt_rule(p)) // global_stmt ) @@ -2066,7 +2019,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'nonlocal' nonlocal_stmt")); stmt_ty nonlocal_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 524) // token='nonlocal' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 527) // token='nonlocal' && (nonlocal_stmt_var = nonlocal_stmt_rule(p)) // nonlocal_stmt ) @@ -2087,11 +2040,11 @@ simple_stmt_rule(Parser *p) } // compound_stmt: -// | &('def' | '@' | ASYNC) function_def +// | &('def' | '@' | 'async') function_def // | &'if' if_stmt // | &('class' | '@') class_def -// | &('with' | ASYNC) with_stmt -// | &('for' | ASYNC) for_stmt +// | &('with' | 'async') with_stmt +// | &('for' | 'async') for_stmt // | &'try' try_stmt // | &'while' while_stmt // | match_stmt @@ -2099,8 +2052,7 @@ static stmt_ty compound_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2108,26 +2060,26 @@ compound_stmt_rule(Parser *p) } stmt_ty _res = NULL; int _mark = p->mark; - { // &('def' | '@' | ASYNC) function_def + { // &('def' | '@' | 'async') function_def if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); + D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | 'async') function_def")); stmt_ty function_def_var; if ( - _PyPegen_lookahead(1, _tmp_8_rule, p) + _PyPegen_lookahead(1, _tmp_7_rule, p) && (function_def_var = function_def_rule(p)) // function_def ) { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | 'async') function_def")); _res = function_def_var; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('def' | '@' | 'async') function_def")); } { // &'if' if_stmt if (p->error_indicator) { @@ -2137,7 +2089,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt")); stmt_ty if_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 642) // token='if' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 656) // token='if' && (if_stmt_var = if_stmt_rule(p)) // if_stmt ) @@ -2158,7 +2110,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('class' | '@') class_def")); stmt_ty class_def_var; if ( - _PyPegen_lookahead(1, _tmp_9_rule, p) + _PyPegen_lookahead(1, _tmp_8_rule, p) && (class_def_var = class_def_rule(p)) // class_def ) @@ -2171,47 +2123,47 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('class' | '@') class_def")); } - { // &('with' | ASYNC) with_stmt + { // &('with' | 'async') with_stmt if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('with' | ASYNC) with_stmt")); + D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('with' | 'async') with_stmt")); stmt_ty with_stmt_var; if ( - _PyPegen_lookahead(1, _tmp_10_rule, p) + _PyPegen_lookahead(1, _tmp_9_rule, p) && (with_stmt_var = with_stmt_rule(p)) // with_stmt ) { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('with' | ASYNC) with_stmt")); + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('with' | 'async') with_stmt")); _res = with_stmt_var; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('with' | ASYNC) with_stmt")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('with' | 'async') with_stmt")); } - { // &('for' | ASYNC) for_stmt + { // &('for' | 'async') for_stmt if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('for' | ASYNC) for_stmt")); + D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('for' | 'async') for_stmt")); stmt_ty for_stmt_var; if ( - _PyPegen_lookahead(1, _tmp_11_rule, p) + _PyPegen_lookahead(1, _tmp_10_rule, p) && (for_stmt_var = for_stmt_rule(p)) // for_stmt ) { - D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('for' | ASYNC) for_stmt")); + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('for' | 'async') for_stmt")); _res = for_stmt_var; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('for' | ASYNC) for_stmt")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('for' | 'async') for_stmt")); } { // &'try' try_stmt if (p->error_indicator) { @@ -2221,7 +2173,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt")); stmt_ty try_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 624) // token='try' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 638) // token='try' && (try_stmt_var = try_stmt_rule(p)) // try_stmt ) @@ -2242,7 +2194,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt")); stmt_ty while_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 647) // token='while' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 661) // token='while' && (while_stmt_var = while_stmt_rule(p)) // while_stmt ) @@ -2290,8 +2242,7 @@ static stmt_ty assignment_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2325,7 +2276,7 @@ assignment_rule(Parser *p) && (b = expression_rule(p)) // expression && - (c = _tmp_12_rule(p), !p->error_indicator) // ['=' annotated_rhs] + (c = _tmp_11_rule(p), !p->error_indicator) // ['=' annotated_rhs] ) { D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); @@ -2361,13 +2312,13 @@ assignment_rule(Parser *p) expr_ty b; void *c; if ( - (a = _tmp_13_rule(p)) // '(' single_target ')' | single_subscript_attribute_target + (a = _tmp_12_rule(p)) // '(' single_target ')' | single_subscript_attribute_target && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (b = expression_rule(p)) // expression && - (c = _tmp_14_rule(p), !p->error_indicator) // ['=' annotated_rhs] + (c = _tmp_13_rule(p), !p->error_indicator) // ['=' annotated_rhs] ) { D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); @@ -2402,9 +2353,9 @@ assignment_rule(Parser *p) void *b; void *tc; if ( - (a = (asdl_expr_seq*)_loop1_15_rule(p)) // ((star_targets '='))+ + (a = (asdl_expr_seq*)_loop1_14_rule(p)) // ((star_targets '='))+ && - (b = _tmp_16_rule(p)) // yield_expr | star_expressions + (b = _tmp_15_rule(p)) // yield_expr | star_expressions && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' && @@ -2450,7 +2401,7 @@ assignment_rule(Parser *p) && (_cut_var = 1) && - (c = _tmp_17_rule(p)) // yield_expr | star_expressions + (c = _tmp_16_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); @@ -2509,8 +2460,7 @@ static expr_ty annotated_rhs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2580,8 +2530,7 @@ static AugOperator* augassign_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2912,8 +2861,7 @@ static stmt_ty return_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2939,7 +2887,7 @@ return_stmt_rule(Parser *p) Token * _keyword; void *a; if ( - (_keyword = _PyPegen_expect_token(p, 519)) // token='return' + (_keyword = _PyPegen_expect_token(p, 522)) // token='return' && (a = star_expressions_rule(p), !p->error_indicator) // star_expressions? ) @@ -2977,8 +2925,7 @@ static stmt_ty raise_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3005,11 +2952,11 @@ raise_stmt_rule(Parser *p) expr_ty a; void *b; if ( - (_keyword = _PyPegen_expect_token(p, 522)) // token='raise' + (_keyword = _PyPegen_expect_token(p, 525)) // token='raise' && (a = expression_rule(p)) // expression && - (b = _tmp_18_rule(p), !p->error_indicator) // ['from' expression] + (b = _tmp_17_rule(p), !p->error_indicator) // ['from' expression] ) { D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]")); @@ -3042,7 +2989,7 @@ raise_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 522)) // token='raise' + (_keyword = _PyPegen_expect_token(p, 525)) // token='raise' ) { D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise'")); @@ -3078,8 +3025,7 @@ static stmt_ty global_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3105,9 +3051,9 @@ global_stmt_rule(Parser *p) Token * _keyword; asdl_expr_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 523)) // token='global' + (_keyword = _PyPegen_expect_token(p, 526)) // token='global' && - (a = (asdl_expr_seq*)_gather_19_rule(p)) // ','.NAME+ + (a = (asdl_expr_seq*)_gather_18_rule(p)) // ','.NAME+ ) { D(fprintf(stderr, "%*c+ global_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); @@ -3143,8 +3089,7 @@ static stmt_ty nonlocal_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3170,9 +3115,9 @@ nonlocal_stmt_rule(Parser *p) Token * _keyword; asdl_expr_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 524)) // token='nonlocal' + (_keyword = _PyPegen_expect_token(p, 527)) // token='nonlocal' && - (a = (asdl_expr_seq*)_gather_21_rule(p)) // ','.NAME+ + (a = (asdl_expr_seq*)_gather_20_rule(p)) // ','.NAME+ ) { D(fprintf(stderr, "%*c+ nonlocal_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); @@ -3208,8 +3153,7 @@ static stmt_ty del_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3235,11 +3179,11 @@ del_stmt_rule(Parser *p) Token * _keyword; asdl_expr_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 604)) // token='del' + (_keyword = _PyPegen_expect_token(p, 613)) // token='del' && (a = del_targets_rule(p)) // del_targets && - _PyPegen_lookahead(1, _tmp_23_rule, p) + _PyPegen_lookahead(1, _tmp_22_rule, p) ) { D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); @@ -3294,8 +3238,7 @@ static stmt_ty yield_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3356,8 +3299,7 @@ static stmt_ty assert_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3384,11 +3326,11 @@ assert_stmt_rule(Parser *p) expr_ty a; void *b; if ( - (_keyword = _PyPegen_expect_token(p, 526)) // token='assert' + (_keyword = _PyPegen_expect_token(p, 529)) // token='assert' && (a = expression_rule(p)) // expression && - (b = _tmp_24_rule(p), !p->error_indicator) // [',' expression] + (b = _tmp_23_rule(p), !p->error_indicator) // [',' expression] ) { D(fprintf(stderr, "%*c+ assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]")); @@ -3424,8 +3366,7 @@ static stmt_ty import_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3501,8 +3442,7 @@ static stmt_ty import_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3528,7 +3468,7 @@ import_name_rule(Parser *p) Token * _keyword; asdl_alias_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 607)) // token='import' + (_keyword = _PyPegen_expect_token(p, 617)) // token='import' && (a = dotted_as_names_rule(p)) // dotted_as_names ) @@ -3568,8 +3508,7 @@ static stmt_ty import_from_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3598,13 +3537,13 @@ import_from_rule(Parser *p) expr_ty b; asdl_alias_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 608)) // token='from' + (_keyword = _PyPegen_expect_token(p, 618)) // token='from' && - (a = _loop0_25_rule(p)) // (('.' | '...'))* + (a = _loop0_24_rule(p)) // (('.' | '...'))* && (b = dotted_name_rule(p)) // dotted_name && - (_keyword_1 = _PyPegen_expect_token(p, 607)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 617)) // token='import' && (c = import_from_targets_rule(p)) // import_from_targets ) @@ -3642,11 +3581,11 @@ import_from_rule(Parser *p) asdl_seq * a; asdl_alias_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 608)) // token='from' + (_keyword = _PyPegen_expect_token(p, 618)) // token='from' && - (a = _loop1_26_rule(p)) // (('.' | '...'))+ + (a = _loop1_25_rule(p)) // (('.' | '...'))+ && - (_keyword_1 = _PyPegen_expect_token(p, 607)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 617)) // token='import' && (b = import_from_targets_rule(p)) // import_from_targets ) @@ -3688,8 +3627,7 @@ static asdl_alias_seq* import_from_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3824,8 +3762,7 @@ static asdl_alias_seq* import_from_as_names_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3841,7 +3778,7 @@ import_from_as_names_rule(Parser *p) D(fprintf(stderr, "%*c> import_from_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); asdl_alias_seq* a; if ( - (a = (asdl_alias_seq*)_gather_27_rule(p)) // ','.import_from_as_name+ + (a = (asdl_alias_seq*)_gather_26_rule(p)) // ','.import_from_as_name+ ) { D(fprintf(stderr, "%*c+ import_from_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); @@ -3868,8 +3805,7 @@ static alias_ty import_from_as_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3897,7 +3833,7 @@ import_from_as_name_rule(Parser *p) if ( (a = _PyPegen_name_token(p)) // NAME && - (b = _tmp_29_rule(p), !p->error_indicator) // ['as' NAME] + (b = _tmp_28_rule(p), !p->error_indicator) // ['as' NAME] ) { D(fprintf(stderr, "%*c+ import_from_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ['as' NAME]")); @@ -3933,8 +3869,7 @@ static asdl_alias_seq* dotted_as_names_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3950,7 +3885,7 @@ dotted_as_names_rule(Parser *p) D(fprintf(stderr, "%*c> dotted_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); asdl_alias_seq* a; if ( - (a = (asdl_alias_seq*)_gather_30_rule(p)) // ','.dotted_as_name+ + (a = (asdl_alias_seq*)_gather_29_rule(p)) // ','.dotted_as_name+ ) { D(fprintf(stderr, "%*c+ dotted_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); @@ -3977,8 +3912,7 @@ static alias_ty dotted_as_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4006,7 +3940,7 @@ dotted_as_name_rule(Parser *p) if ( (a = dotted_name_rule(p)) // dotted_name && - (b = _tmp_32_rule(p), !p->error_indicator) // ['as' NAME] + (b = _tmp_31_rule(p), !p->error_indicator) // ['as' NAME] ) { D(fprintf(stderr, "%*c+ dotted_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name ['as' NAME]")); @@ -4044,8 +3978,7 @@ static expr_ty dotted_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, dotted_name_type, &_res)) { @@ -4079,8 +4012,7 @@ static expr_ty dotted_name_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4148,8 +4080,7 @@ static asdl_stmt_seq* block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4244,8 +4175,7 @@ static asdl_expr_seq* decorators_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4261,7 +4191,7 @@ decorators_rule(Parser *p) D(fprintf(stderr, "%*c> decorators[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_loop1_33_rule(p)) // (('@' named_expression NEWLINE))+ + (a = (asdl_expr_seq*)_loop1_32_rule(p)) // (('@' named_expression NEWLINE))+ ) { D(fprintf(stderr, "%*c+ decorators[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); @@ -4288,8 +4218,7 @@ static stmt_ty class_def_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4356,8 +4285,7 @@ static stmt_ty class_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4406,13 +4334,13 @@ class_def_raw_rule(Parser *p) asdl_stmt_seq* c; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='class' + (_keyword = _PyPegen_expect_token(p, 671)) // token='class' && (a = _PyPegen_name_token(p)) // NAME && (t = type_params_rule(p), !p->error_indicator) // type_params? && - (b = _tmp_34_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (b = _tmp_33_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -4452,8 +4380,7 @@ static stmt_ty function_def_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4516,13 +4443,12 @@ function_def_rule(Parser *p) // function_def_raw: // | invalid_def_raw // | 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block -// | ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block +// | 'async' 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block static stmt_ty function_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4575,7 +4501,7 @@ function_def_raw_rule(Parser *p) void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 652)) // token='def' + (_keyword = _PyPegen_expect_token(p, 669)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -4587,7 +4513,7 @@ function_def_raw_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (a = _tmp_35_rule(p), !p->error_indicator) // ['->' expression] + (a = _tmp_34_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -4618,27 +4544,27 @@ function_def_raw_rule(Parser *p) D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); } - { // ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block + { // 'async' 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async' 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token * _keyword; + Token * _keyword_1; Token * _literal; Token * _literal_1; Token * _literal_2; void *a; - Token * async_var; asdl_stmt_seq* b; expr_ty n; void *params; void *t; void *tc; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' && - (_keyword = _PyPegen_expect_token(p, 652)) // token='def' + (_keyword_1 = _PyPegen_expect_token(p, 669)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -4650,7 +4576,7 @@ function_def_raw_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (a = _tmp_36_rule(p), !p->error_indicator) // ['->' expression] + (a = _tmp_35_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -4659,7 +4585,7 @@ function_def_raw_rule(Parser *p) (b = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async' 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -4679,7 +4605,7 @@ function_def_raw_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async' 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); } _res = NULL; done: @@ -4692,8 +4618,7 @@ static arguments_ty params_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4755,8 +4680,7 @@ static arguments_ty parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4777,9 +4701,9 @@ parameters_rule(Parser *p) if ( (a = slash_no_default_rule(p)) // slash_no_default && - (b = (asdl_arg_seq*)_loop0_37_rule(p)) // param_no_default* + (b = (asdl_arg_seq*)_loop0_36_rule(p)) // param_no_default* && - (c = _loop0_38_rule(p)) // param_with_default* + (c = _loop0_37_rule(p)) // param_with_default* && (d = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4809,7 +4733,7 @@ parameters_rule(Parser *p) if ( (a = slash_with_default_rule(p)) // slash_with_default && - (b = _loop0_39_rule(p)) // param_with_default* + (b = _loop0_38_rule(p)) // param_with_default* && (c = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4837,9 +4761,9 @@ parameters_rule(Parser *p) asdl_seq * b; void *c; if ( - (a = (asdl_arg_seq*)_loop1_40_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_39_rule(p)) // param_no_default+ && - (b = _loop0_41_rule(p)) // param_with_default* + (b = _loop0_40_rule(p)) // param_with_default* && (c = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4866,7 +4790,7 @@ parameters_rule(Parser *p) asdl_seq * a; void *b; if ( - (a = _loop1_42_rule(p)) // param_with_default+ + (a = _loop1_41_rule(p)) // param_with_default+ && (b = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4919,8 +4843,7 @@ static asdl_arg_seq* slash_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4938,7 +4861,7 @@ slash_no_default_rule(Parser *p) Token * _literal_1; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_43_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_42_rule(p)) // param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -4967,7 +4890,7 @@ slash_no_default_rule(Parser *p) Token * _literal; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_44_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_43_rule(p)) // param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -5000,8 +4923,7 @@ static SlashWithDefault* slash_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5020,9 +4942,9 @@ slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_45_rule(p)) // param_no_default* + (a = _loop0_44_rule(p)) // param_no_default* && - (b = _loop1_46_rule(p)) // param_with_default+ + (b = _loop1_45_rule(p)) // param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -5052,9 +4974,9 @@ slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_47_rule(p)) // param_no_default* + (a = _loop0_46_rule(p)) // param_no_default* && - (b = _loop1_48_rule(p)) // param_with_default+ + (b = _loop1_47_rule(p)) // param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -5090,8 +5012,7 @@ static StarEtc* star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5133,7 +5054,7 @@ star_etc_rule(Parser *p) && (a = param_no_default_rule(p)) // param_no_default && - (b = _loop0_49_rule(p)) // param_maybe_default* + (b = _loop0_48_rule(p)) // param_maybe_default* && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -5166,7 +5087,7 @@ star_etc_rule(Parser *p) && (a = param_no_default_star_annotation_rule(p)) // param_no_default_star_annotation && - (b = _loop0_50_rule(p)) // param_maybe_default* + (b = _loop0_49_rule(p)) // param_maybe_default* && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -5199,7 +5120,7 @@ star_etc_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _loop1_51_rule(p)) // param_maybe_default+ + (b = _loop1_50_rule(p)) // param_maybe_default+ && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -5252,8 +5173,7 @@ static arg_ty kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5318,8 +5238,7 @@ static arg_ty param_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5399,8 +5318,7 @@ static arg_ty param_no_default_star_annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5478,8 +5396,7 @@ static NameDefaultPair* param_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5565,8 +5482,7 @@ static NameDefaultPair* param_maybe_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5650,8 +5566,7 @@ static arg_ty param_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5715,8 +5630,7 @@ static arg_ty param_star_annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5780,8 +5694,7 @@ static expr_ty annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5827,8 +5740,7 @@ static expr_ty star_annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5874,8 +5786,7 @@ static expr_ty default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5943,8 +5854,7 @@ static stmt_ty if_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5992,7 +5902,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -6037,7 +5947,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -6084,8 +5994,7 @@ static stmt_ty elif_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6133,7 +6042,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 644)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 658)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6178,7 +6087,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 644)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 658)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6222,8 +6131,7 @@ static asdl_stmt_seq* else_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6260,7 +6168,7 @@ else_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 645)) // token='else' + (_keyword = _PyPegen_expect_token(p, 659)) // token='else' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6291,8 +6199,7 @@ static stmt_ty while_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6340,7 +6247,7 @@ while_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='while' + (_keyword = _PyPegen_expect_token(p, 661)) // token='while' && (a = named_expression_rule(p)) // named_expression && @@ -6382,14 +6289,13 @@ while_stmt_rule(Parser *p) // for_stmt: // | invalid_for_stmt // | 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? -// | ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? +// | 'async' 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? // | invalid_for_target static stmt_ty for_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6441,11 +6347,11 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + (_keyword = _PyPegen_expect_token(p, 666)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' && (_cut_var = 1) && @@ -6486,30 +6392,30 @@ for_stmt_rule(Parser *p) return NULL; } } - { // ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? + { // 'async' 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); + D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async' 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); int _cut_var = 0; Token * _keyword; Token * _keyword_1; + Token * _keyword_2; Token * _literal; - Token * async_var; asdl_stmt_seq* b; void *el; expr_ty ex; expr_ty t; void *tc; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' && - (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 666)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 667)) // token='in' && (_cut_var = 1) && @@ -6524,7 +6430,7 @@ for_stmt_rule(Parser *p) (el = else_block_rule(p), !p->error_indicator) // else_block? ) { - D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); + D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async' 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -6544,7 +6450,7 @@ for_stmt_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async' 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); if (_cut_var) { p->level--; return NULL; @@ -6579,15 +6485,14 @@ for_stmt_rule(Parser *p) // | invalid_with_stmt_indent // | 'with' '(' ','.with_item+ ','? ')' ':' block // | 'with' ','.with_item+ ':' TYPE_COMMENT? block -// | ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block -// | ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block +// | 'async' 'with' '(' ','.with_item+ ','? ')' ':' block +// | 'async' 'with' ','.with_item+ ':' TYPE_COMMENT? block // | invalid_with_stmt static stmt_ty with_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6638,11 +6543,11 @@ with_stmt_rule(Parser *p) asdl_withitem_seq* a; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + (_keyword = _PyPegen_expect_token(p, 629)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_52_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_51_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -6687,9 +6592,9 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + (_keyword = _PyPegen_expect_token(p, 629)) // token='with' && - (a = (asdl_withitem_seq*)_gather_54_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_53_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6720,29 +6625,29 @@ with_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); } - { // ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block + { // 'async' 'with' '(' ','.with_item+ ','? ')' ':' block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async' 'with' '(' ','.with_item+ ','? ')' ':' block")); Token * _keyword; + Token * _keyword_1; Token * _literal; Token * _literal_1; Token * _literal_2; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings asdl_withitem_seq* a; - Token * async_var; asdl_stmt_seq* b; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' && - (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 629)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_56_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_55_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -6753,7 +6658,7 @@ with_stmt_rule(Parser *p) (b = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async' 'with' '(' ','.with_item+ ','? ')' ':' block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -6773,26 +6678,26 @@ with_stmt_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async' 'with' '(' ','.with_item+ ','? ')' ':' block")); } - { // ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block + { // 'async' 'with' ','.with_item+ ':' TYPE_COMMENT? block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async' 'with' ','.with_item+ ':' TYPE_COMMENT? block")); Token * _keyword; + Token * _keyword_1; Token * _literal; asdl_withitem_seq* a; - Token * async_var; asdl_stmt_seq* b; void *tc; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' && - (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 629)) // token='with' && - (a = (asdl_withitem_seq*)_gather_58_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_57_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6801,7 +6706,7 @@ with_stmt_rule(Parser *p) (b = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async' 'with' ','.with_item+ ':' TYPE_COMMENT? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -6821,7 +6726,7 @@ with_stmt_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async' 'with' ','.with_item+ ':' TYPE_COMMENT? block")); } if (p->call_invalid_rules) { // invalid_with_stmt if (p->error_indicator) { @@ -6856,8 +6761,7 @@ static withitem_ty with_item_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6877,11 +6781,11 @@ with_item_rule(Parser *p) if ( (e = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (t = star_target_rule(p)) // star_target && - _PyPegen_lookahead(1, _tmp_60_rule, p) + _PyPegen_lookahead(1, _tmp_59_rule, p) ) { D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); @@ -6955,8 +6859,7 @@ static stmt_ty try_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7003,7 +6906,7 @@ try_stmt_rule(Parser *p) asdl_stmt_seq* b; asdl_stmt_seq* f; if ( - (_keyword = _PyPegen_expect_token(p, 624)) // token='try' + (_keyword = _PyPegen_expect_token(p, 638)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7047,13 +6950,13 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 624)) // token='try' + (_keyword = _PyPegen_expect_token(p, 638)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && (b = block_rule(p)) // block && - (ex = (asdl_excepthandler_seq*)_loop1_61_rule(p)) // except_block+ + (ex = (asdl_excepthandler_seq*)_loop1_60_rule(p)) // except_block+ && (el = else_block_rule(p), !p->error_indicator) // else_block? && @@ -7095,13 +6998,13 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 624)) // token='try' + (_keyword = _PyPegen_expect_token(p, 638)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && (b = block_rule(p)) // block && - (ex = (asdl_excepthandler_seq*)_loop1_62_rule(p)) // except_star_block+ + (ex = (asdl_excepthandler_seq*)_loop1_61_rule(p)) // except_star_block+ && (el = else_block_rule(p), !p->error_indicator) // else_block? && @@ -7145,8 +7048,7 @@ static excepthandler_ty except_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7194,11 +7096,11 @@ except_block_rule(Parser *p) expr_ty e; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='except' + (_keyword = _PyPegen_expect_token(p, 651)) // token='except' && (e = expression_rule(p)) // expression && - (t = _tmp_63_rule(p), !p->error_indicator) // ['as' NAME] + (t = _tmp_62_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7237,7 +7139,7 @@ except_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='except' + (_keyword = _PyPegen_expect_token(p, 651)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7299,8 +7201,7 @@ static excepthandler_ty except_star_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7349,13 +7250,13 @@ except_star_block_rule(Parser *p) expr_ty e; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='except' + (_keyword = _PyPegen_expect_token(p, 651)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (e = expression_rule(p)) // expression && - (t = _tmp_64_rule(p), !p->error_indicator) // ['as' NAME] + (t = _tmp_63_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7414,8 +7315,7 @@ static asdl_stmt_seq* finally_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7452,7 +7352,7 @@ finally_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 633)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 647)) // token='finally' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7485,8 +7385,7 @@ static stmt_ty match_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7527,7 +7426,7 @@ match_stmt_rule(Parser *p) && (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' && - (cases = (asdl_match_case_seq*)_loop1_65_rule(p)) // case_block+ + (cases = (asdl_match_case_seq*)_loop1_64_rule(p)) // case_block+ && (dedent_var = _PyPegen_expect_token(p, DEDENT)) // token='DEDENT' ) @@ -7584,8 +7483,7 @@ static expr_ty subject_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7671,8 +7569,7 @@ static match_case_ty case_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7746,8 +7643,7 @@ static expr_ty guard_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7764,7 +7660,7 @@ guard_rule(Parser *p) Token * _keyword; expr_ty guard; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (guard = named_expression_rule(p)) // named_expression ) @@ -7793,8 +7689,7 @@ static pattern_ty patterns_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7874,8 +7769,7 @@ static pattern_ty pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7932,8 +7826,7 @@ static pattern_ty as_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7962,7 +7855,7 @@ as_pattern_rule(Parser *p) if ( (pattern = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (target = pattern_capture_target_rule(p)) // pattern_capture_target ) @@ -8019,8 +7912,7 @@ static pattern_ty or_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8045,7 +7937,7 @@ or_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> or_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); asdl_pattern_seq* patterns; if ( - (patterns = (asdl_pattern_seq*)_gather_66_rule(p)) // '|'.closed_pattern+ + (patterns = (asdl_pattern_seq*)_gather_65_rule(p)) // '|'.closed_pattern+ ) { D(fprintf(stderr, "%*c+ or_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); @@ -8089,8 +7981,7 @@ static pattern_ty closed_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8272,8 +8163,7 @@ static pattern_ty literal_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8300,7 +8190,7 @@ literal_pattern_rule(Parser *p) if ( (value = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_68_rule, p) + _PyPegen_lookahead(0, _tmp_67_rule, p) ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -8399,7 +8289,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='None' + (_keyword = _PyPegen_expect_token(p, 611)) // token='None' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); @@ -8432,7 +8322,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='True' + (_keyword = _PyPegen_expect_token(p, 610)) // token='True' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -8465,7 +8355,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 603)) // token='False' + (_keyword = _PyPegen_expect_token(p, 612)) // token='False' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -8507,8 +8397,7 @@ static expr_ty literal_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8535,7 +8424,7 @@ literal_expr_rule(Parser *p) if ( (signed_number_var = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_69_rule, p) + _PyPegen_lookahead(0, _tmp_68_rule, p) ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -8592,7 +8481,7 @@ literal_expr_rule(Parser *p) D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='None' + (_keyword = _PyPegen_expect_token(p, 611)) // token='None' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); @@ -8625,7 +8514,7 @@ literal_expr_rule(Parser *p) D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='True' + (_keyword = _PyPegen_expect_token(p, 610)) // token='True' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -8658,7 +8547,7 @@ literal_expr_rule(Parser *p) D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 603)) // token='False' + (_keyword = _PyPegen_expect_token(p, 612)) // token='False' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -8696,8 +8585,7 @@ static expr_ty complex_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8803,8 +8691,7 @@ static expr_ty signed_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8887,8 +8774,7 @@ static expr_ty signed_real_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8971,8 +8857,7 @@ static expr_ty real_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9015,8 +8900,7 @@ static expr_ty imaginary_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9059,8 +8943,7 @@ static pattern_ty capture_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9121,8 +9004,7 @@ static expr_ty pattern_capture_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9142,7 +9024,7 @@ pattern_capture_target_rule(Parser *p) && (name = _PyPegen_name_token(p)) // NAME && - _PyPegen_lookahead(0, _tmp_70_rule, p) + _PyPegen_lookahead(0, _tmp_69_rule, p) ) { D(fprintf(stderr, "%*c+ pattern_capture_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); @@ -9169,8 +9051,7 @@ static pattern_ty wildcard_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9231,8 +9112,7 @@ static pattern_ty value_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9259,7 +9139,7 @@ value_pattern_rule(Parser *p) if ( (attr = attr_rule(p)) // attr && - _PyPegen_lookahead(0, _tmp_71_rule, p) + _PyPegen_lookahead(0, _tmp_70_rule, p) ) { D(fprintf(stderr, "%*c+ value_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')")); @@ -9297,8 +9177,7 @@ static expr_ty attr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, attr_type, &_res)) { @@ -9332,8 +9211,7 @@ static expr_ty attr_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9401,8 +9279,7 @@ static expr_ty name_or_attr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9459,8 +9336,7 @@ static pattern_ty group_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9509,8 +9385,7 @@ static pattern_ty sequence_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9616,8 +9491,7 @@ static asdl_seq* open_sequence_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9666,8 +9540,7 @@ static asdl_seq* maybe_sequence_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9685,7 +9558,7 @@ maybe_sequence_pattern_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * patterns; if ( - (patterns = _gather_72_rule(p)) // ','.maybe_star_pattern+ + (patterns = _gather_71_rule(p)) // ','.maybe_star_pattern+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -9714,8 +9587,7 @@ static pattern_ty maybe_star_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9772,8 +9644,7 @@ static pattern_ty star_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9882,8 +9753,7 @@ static pattern_ty mapping_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10082,8 +9952,7 @@ static asdl_seq* items_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10097,13 +9966,13 @@ items_pattern_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> items_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - asdl_seq * _gather_74_var; + asdl_seq * _gather_73_var; if ( - (_gather_74_var = _gather_74_rule(p)) // ','.key_value_pattern+ + (_gather_73_var = _gather_73_rule(p)) // ','.key_value_pattern+ ) { D(fprintf(stderr, "%*c+ items_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - _res = _gather_74_var; + _res = _gather_73_var; goto done; } p->mark = _mark; @@ -10121,8 +9990,7 @@ static KeyPatternPair* key_value_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10140,7 +10008,7 @@ key_value_pattern_rule(Parser *p) void *key; pattern_ty pattern; if ( - (key = _tmp_76_rule(p)) // literal_expr | attr + (key = _tmp_75_rule(p)) // literal_expr | attr && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -10171,8 +10039,7 @@ static expr_ty double_star_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10223,8 +10090,7 @@ static pattern_ty class_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10454,8 +10320,7 @@ static asdl_pattern_seq* positional_patterns_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10471,7 +10336,7 @@ positional_patterns_rule(Parser *p) D(fprintf(stderr, "%*c> positional_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.pattern+")); asdl_pattern_seq* args; if ( - (args = (asdl_pattern_seq*)_gather_77_rule(p)) // ','.pattern+ + (args = (asdl_pattern_seq*)_gather_76_rule(p)) // ','.pattern+ ) { D(fprintf(stderr, "%*c+ positional_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.pattern+")); @@ -10498,8 +10363,7 @@ static asdl_seq* keyword_patterns_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10513,13 +10377,13 @@ keyword_patterns_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> keyword_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - asdl_seq * _gather_79_var; + asdl_seq * _gather_78_var; if ( - (_gather_79_var = _gather_79_rule(p)) // ','.keyword_pattern+ + (_gather_78_var = _gather_78_rule(p)) // ','.keyword_pattern+ ) { D(fprintf(stderr, "%*c+ keyword_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - _res = _gather_79_var; + _res = _gather_78_var; goto done; } p->mark = _mark; @@ -10537,8 +10401,7 @@ static KeyPatternPair* keyword_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10587,8 +10450,7 @@ static stmt_ty type_alias_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10661,8 +10523,7 @@ static asdl_type_param_seq* type_params_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10711,8 +10572,7 @@ static asdl_type_param_seq* type_param_seq_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10730,7 +10590,7 @@ type_param_seq_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_type_param_seq* a; if ( - (a = (asdl_type_param_seq*)_gather_81_rule(p)) // ','.type_param+ + (a = (asdl_type_param_seq*)_gather_80_rule(p)) // ','.type_param+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -10756,16 +10616,15 @@ type_param_seq_rule(Parser *p) // type_param: // | NAME type_param_bound? -// | '*' NAME ":" expression +// | '*' NAME ':' expression // | '*' NAME -// | '**' NAME ":" expression +// | '**' NAME ':' expression // | '**' NAME static type_param_ty type_param_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10822,12 +10681,12 @@ type_param_rule(Parser *p) D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME type_param_bound?")); } - { // '*' NAME ":" expression + { // '*' NAME ':' expression if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' NAME \":\" expression")); + D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' NAME ':' expression")); Token * _literal; expr_ty a; Token * colon; @@ -10842,7 +10701,7 @@ type_param_rule(Parser *p) (e = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' NAME \":\" expression")); + D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' NAME ':' expression")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with TypeVarTuple" : "cannot use bound with TypeVarTuple" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -10853,7 +10712,7 @@ type_param_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' NAME \":\" expression")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' NAME ':' expression")); } { // '*' NAME if (p->error_indicator) { @@ -10891,12 +10750,12 @@ type_param_rule(Parser *p) D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' NAME")); } - { // '**' NAME ":" expression + { // '**' NAME ':' expression if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' NAME \":\" expression")); + D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' NAME ':' expression")); Token * _literal; expr_ty a; Token * colon; @@ -10911,7 +10770,7 @@ type_param_rule(Parser *p) (e = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' NAME \":\" expression")); + D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' NAME ':' expression")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with ParamSpec" : "cannot use bound with ParamSpec" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -10922,7 +10781,7 @@ type_param_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' NAME \":\" expression")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' NAME ':' expression")); } { // '**' NAME if (p->error_indicator) { @@ -10967,13 +10826,12 @@ type_param_rule(Parser *p) return _res; } -// type_param_bound: ":" expression +// type_param_bound: ':' expression static expr_ty type_param_bound_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10981,12 +10839,12 @@ type_param_bound_rule(Parser *p) } expr_ty _res = NULL; int _mark = p->mark; - { // ":" expression + { // ':' expression if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> type_param_bound[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\":\" expression")); + D(fprintf(stderr, "%*c> type_param_bound[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression")); Token * _literal; expr_ty e; if ( @@ -10995,7 +10853,7 @@ type_param_bound_rule(Parser *p) (e = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ type_param_bound[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\":\" expression")); + D(fprintf(stderr, "%*c+ type_param_bound[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression")); _res = e; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -11006,7 +10864,7 @@ type_param_bound_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s type_param_bound[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\":\" expression")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression")); } _res = NULL; done: @@ -11019,8 +10877,7 @@ static expr_ty expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11050,7 +10907,7 @@ expressions_rule(Parser *p) if ( (a = expression_rule(p)) // expression && - (b = _loop1_83_rule(p)) // ((',' expression))+ + (b = _loop1_82_rule(p)) // ((',' expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -11148,8 +11005,7 @@ static expr_ty expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11222,11 +11078,11 @@ expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 645)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 659)) // token='else' && (c = expression_rule(p)) // expression ) @@ -11303,8 +11159,7 @@ static expr_ty yield_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11331,9 +11186,9 @@ yield_expr_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 573)) // token='yield' + (_keyword = _PyPegen_expect_token(p, 580)) // token='yield' && - (_keyword_1 = _PyPegen_expect_token(p, 608)) // token='from' + (_keyword_1 = _PyPegen_expect_token(p, 618)) // token='from' && (a = expression_rule(p)) // expression ) @@ -11369,7 +11224,7 @@ yield_expr_rule(Parser *p) Token * _keyword; void *a; if ( - (_keyword = _PyPegen_expect_token(p, 573)) // token='yield' + (_keyword = _PyPegen_expect_token(p, 580)) // token='yield' && (a = star_expressions_rule(p), !p->error_indicator) // star_expressions? ) @@ -11410,8 +11265,7 @@ static expr_ty star_expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11441,7 +11295,7 @@ star_expressions_rule(Parser *p) if ( (a = star_expression_rule(p)) // star_expression && - (b = _loop1_84_rule(p)) // ((',' star_expression))+ + (b = _loop1_83_rule(p)) // ((',' star_expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -11534,8 +11388,7 @@ static expr_ty star_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11623,8 +11476,7 @@ static asdl_expr_seq* star_named_expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11642,7 +11494,7 @@ star_named_expressions_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_85_rule(p)) // ','.star_named_expression+ + (a = (asdl_expr_seq*)_gather_84_rule(p)) // ','.star_named_expression+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -11671,8 +11523,7 @@ static expr_ty star_named_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11755,8 +11606,7 @@ static expr_ty assignment_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11830,8 +11680,7 @@ static expr_ty named_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11909,8 +11758,7 @@ static expr_ty disjunction_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11942,7 +11790,7 @@ disjunction_rule(Parser *p) if ( (a = conjunction_rule(p)) // conjunction && - (b = _loop1_87_rule(p)) // (('or' conjunction))+ + (b = _loop1_86_rule(p)) // (('or' conjunction))+ ) { D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); @@ -11998,8 +11846,7 @@ static expr_ty conjunction_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12031,7 +11878,7 @@ conjunction_rule(Parser *p) if ( (a = inversion_rule(p)) // inversion && - (b = _loop1_88_rule(p)) // (('and' inversion))+ + (b = _loop1_87_rule(p)) // (('and' inversion))+ ) { D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); @@ -12087,8 +11934,7 @@ static expr_ty inversion_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12118,7 +11964,7 @@ inversion_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 581)) // token='not' + (_keyword = _PyPegen_expect_token(p, 588)) // token='not' && (a = inversion_rule(p)) // inversion ) @@ -12176,8 +12022,7 @@ static expr_ty comparison_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12205,7 +12050,7 @@ comparison_rule(Parser *p) if ( (a = bitwise_or_rule(p)) // bitwise_or && - (b = _loop1_89_rule(p)) // compare_op_bitwise_or_pair+ + (b = _loop1_88_rule(p)) // compare_op_bitwise_or_pair+ ) { D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); @@ -12270,8 +12115,7 @@ static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12480,8 +12324,7 @@ static CmpopExprPair* eq_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12527,8 +12370,7 @@ static CmpopExprPair* noteq_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12542,10 +12384,10 @@ noteq_bitwise_or_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); - void *_tmp_90_var; + void *_tmp_89_var; expr_ty a; if ( - (_tmp_90_var = _tmp_90_rule(p)) // '!=' + (_tmp_89_var = _tmp_89_rule(p)) // '!=' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12574,8 +12416,7 @@ static CmpopExprPair* lte_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12621,8 +12462,7 @@ static CmpopExprPair* lt_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12668,8 +12508,7 @@ static CmpopExprPair* gte_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12715,8 +12554,7 @@ static CmpopExprPair* gt_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12762,8 +12600,7 @@ static CmpopExprPair* notin_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12781,9 +12618,9 @@ notin_bitwise_or_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 581)) // token='not' + (_keyword = _PyPegen_expect_token(p, 588)) // token='not' && - (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12812,8 +12649,7 @@ static CmpopExprPair* in_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12830,7 +12666,7 @@ in_bitwise_or_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword = _PyPegen_expect_token(p, 667)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12859,8 +12695,7 @@ static CmpopExprPair* isnot_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12878,9 +12713,9 @@ isnot_bitwise_or_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 582)) // token='is' + (_keyword = _PyPegen_expect_token(p, 589)) // token='is' && - (_keyword_1 = _PyPegen_expect_token(p, 581)) // token='not' + (_keyword_1 = _PyPegen_expect_token(p, 588)) // token='not' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12909,8 +12744,7 @@ static CmpopExprPair* is_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12927,7 +12761,7 @@ is_bitwise_or_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 582)) // token='is' + (_keyword = _PyPegen_expect_token(p, 589)) // token='is' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12958,8 +12792,7 @@ static expr_ty bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_or_type, &_res)) { @@ -12993,8 +12826,7 @@ static expr_ty bitwise_or_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13082,8 +12914,7 @@ static expr_ty bitwise_xor_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_xor_type, &_res)) { @@ -13117,8 +12948,7 @@ static expr_ty bitwise_xor_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13206,8 +13036,7 @@ static expr_ty bitwise_and_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_and_type, &_res)) { @@ -13241,8 +13070,7 @@ static expr_ty bitwise_and_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13330,8 +13158,7 @@ static expr_ty shift_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, shift_expr_type, &_res)) { @@ -13365,8 +13192,7 @@ static expr_ty shift_expr_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13493,8 +13319,7 @@ static expr_ty sum_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, sum_type, &_res)) { @@ -13528,8 +13353,7 @@ static expr_ty sum_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13662,8 +13486,7 @@ static expr_ty term_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, term_type, &_res)) { @@ -13697,8 +13520,7 @@ static expr_ty term_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13940,8 +13762,7 @@ static expr_ty factor_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14101,8 +13922,7 @@ static expr_ty power_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14183,13 +14003,12 @@ power_rule(Parser *p) return _res; } -// await_primary: AWAIT primary | primary +// await_primary: 'await' primary | primary static expr_ty await_primary_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14210,21 +14029,21 @@ await_primary_rule(Parser *p) UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro - { // AWAIT primary + { // 'await' primary if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); + D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'await' primary")); + Token * _keyword; expr_ty a; - Token * await_var; if ( - (await_var = _PyPegen_expect_token(p, AWAIT)) // token='AWAIT' + (_keyword = _PyPegen_expect_token(p, 590)) // token='await' && (a = primary_rule(p)) // primary ) { - D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); + D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'await' primary")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -14244,7 +14063,7 @@ await_primary_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s await_primary[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "AWAIT primary")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'await' primary")); } { // primary if (p->error_indicator) { @@ -14284,8 +14103,7 @@ static expr_ty primary_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, primary_type, &_res)) { @@ -14319,8 +14137,7 @@ static expr_ty primary_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14526,8 +14343,7 @@ static expr_ty slices_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14580,7 +14396,7 @@ slices_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_91_rule(p)) // ','.(slice | starred_expression)+ + (a = (asdl_expr_seq*)_gather_90_rule(p)) // ','.(slice | starred_expression)+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -14618,8 +14434,7 @@ static expr_ty slice_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14653,7 +14468,7 @@ slice_rule(Parser *p) && (b = expression_rule(p), !p->error_indicator) // expression? && - (c = _tmp_93_rule(p), !p->error_indicator) // [':' expression?] + (c = _tmp_92_rule(p), !p->error_indicator) // [':' expression?] ) { D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]")); @@ -14723,8 +14538,7 @@ static expr_ty atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14768,7 +14582,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='True' + (_keyword = _PyPegen_expect_token(p, 610)) // token='True' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -14801,7 +14615,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 603)) // token='False' + (_keyword = _PyPegen_expect_token(p, 612)) // token='False' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -14834,7 +14648,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='None' + (_keyword = _PyPegen_expect_token(p, 611)) // token='None' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); @@ -14867,7 +14681,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&(STRING | FSTRING_START) strings")); expr_ty strings_var; if ( - _PyPegen_lookahead(1, _tmp_94_rule, p) + _PyPegen_lookahead(1, _tmp_93_rule, p) && (strings_var = strings_rule(p)) // strings ) @@ -14905,15 +14719,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - void *_tmp_95_var; + void *_tmp_94_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 7) // token='(' && - (_tmp_95_var = _tmp_95_rule(p)) // tuple | group | genexp + (_tmp_94_var = _tmp_94_rule(p)) // tuple | group | genexp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - _res = _tmp_95_var; + _res = _tmp_94_var; goto done; } p->mark = _mark; @@ -14926,15 +14740,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - void *_tmp_96_var; + void *_tmp_95_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 9) // token='[' && - (_tmp_96_var = _tmp_96_rule(p)) // list | listcomp + (_tmp_95_var = _tmp_95_rule(p)) // list | listcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - _res = _tmp_96_var; + _res = _tmp_95_var; goto done; } p->mark = _mark; @@ -14947,15 +14761,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - void *_tmp_97_var; + void *_tmp_96_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 25) // token='{' && - (_tmp_97_var = _tmp_97_rule(p)) // dict | set | dictcomp | setcomp + (_tmp_96_var = _tmp_96_rule(p)) // dict | set | dictcomp | setcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - _res = _tmp_97_var; + _res = _tmp_96_var; goto done; } p->mark = _mark; @@ -15006,8 +14820,7 @@ static expr_ty group_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15027,7 +14840,7 @@ group_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_98_rule(p)) // yield_expr | named_expression + (a = _tmp_97_rule(p)) // yield_expr | named_expression && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) @@ -15075,8 +14888,7 @@ static expr_ty lambdef_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15104,7 +14916,7 @@ lambdef_rule(Parser *p) void *a; expr_ty b; if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='lambda' + (_keyword = _PyPegen_expect_token(p, 609)) // token='lambda' && (a = lambda_params_rule(p), !p->error_indicator) // lambda_params? && @@ -15146,8 +14958,7 @@ static arguments_ty lambda_params_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15209,8 +15020,7 @@ static arguments_ty lambda_parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15231,9 +15041,9 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_no_default_rule(p)) // lambda_slash_no_default && - (b = (asdl_arg_seq*)_loop0_99_rule(p)) // lambda_param_no_default* + (b = (asdl_arg_seq*)_loop0_98_rule(p)) // lambda_param_no_default* && - (c = _loop0_100_rule(p)) // lambda_param_with_default* + (c = _loop0_99_rule(p)) // lambda_param_with_default* && (d = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -15263,7 +15073,7 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default && - (b = _loop0_101_rule(p)) // lambda_param_with_default* + (b = _loop0_100_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -15291,9 +15101,9 @@ lambda_parameters_rule(Parser *p) asdl_seq * b; void *c; if ( - (a = (asdl_arg_seq*)_loop1_102_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_101_rule(p)) // lambda_param_no_default+ && - (b = _loop0_103_rule(p)) // lambda_param_with_default* + (b = _loop0_102_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -15320,7 +15130,7 @@ lambda_parameters_rule(Parser *p) asdl_seq * a; void *b; if ( - (a = _loop1_104_rule(p)) // lambda_param_with_default+ + (a = _loop1_103_rule(p)) // lambda_param_with_default+ && (b = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -15375,8 +15185,7 @@ static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15394,7 +15203,7 @@ lambda_slash_no_default_rule(Parser *p) Token * _literal_1; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_105_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_104_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -15423,7 +15232,7 @@ lambda_slash_no_default_rule(Parser *p) Token * _literal; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_106_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_105_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -15456,8 +15265,7 @@ static SlashWithDefault* lambda_slash_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15476,9 +15284,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_107_rule(p)) // lambda_param_no_default* + (a = _loop0_106_rule(p)) // lambda_param_no_default* && - (b = _loop1_108_rule(p)) // lambda_param_with_default+ + (b = _loop1_107_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -15508,9 +15316,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_109_rule(p)) // lambda_param_no_default* + (a = _loop0_108_rule(p)) // lambda_param_no_default* && - (b = _loop1_110_rule(p)) // lambda_param_with_default+ + (b = _loop1_109_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -15545,8 +15353,7 @@ static StarEtc* lambda_star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15588,7 +15395,7 @@ lambda_star_etc_rule(Parser *p) && (a = lambda_param_no_default_rule(p)) // lambda_param_no_default && - (b = _loop0_111_rule(p)) // lambda_param_maybe_default* + (b = _loop0_110_rule(p)) // lambda_param_maybe_default* && (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? ) @@ -15621,7 +15428,7 @@ lambda_star_etc_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _loop1_112_rule(p)) // lambda_param_maybe_default+ + (b = _loop1_111_rule(p)) // lambda_param_maybe_default+ && (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? ) @@ -15674,8 +15481,7 @@ static arg_ty lambda_kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15740,8 +15546,7 @@ static arg_ty lambda_param_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15813,8 +15618,7 @@ static NameDefaultPair* lambda_param_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15892,8 +15696,7 @@ static NameDefaultPair* lambda_param_maybe_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15971,8 +15774,7 @@ static arg_ty lambda_param_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16033,8 +15835,7 @@ static expr_ty fstring_middle_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16092,14 +15893,13 @@ fstring_middle_rule(Parser *p) } // fstring_replacement_field: -// | '{' (yield_expr | star_expressions) "="? fstring_conversion? fstring_full_format_spec? '}' +// | '{' (yield_expr | star_expressions) '='? fstring_conversion? fstring_full_format_spec? '}' // | invalid_replacement_field static expr_ty fstring_replacement_field_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16116,12 +15916,12 @@ fstring_replacement_field_rule(Parser *p) UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro - { // '{' (yield_expr | star_expressions) "="? fstring_conversion? fstring_full_format_spec? '}' + { // '{' (yield_expr | star_expressions) '='? fstring_conversion? fstring_full_format_spec? '}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> fstring_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) \"=\"? fstring_conversion? fstring_full_format_spec? '}'")); + D(fprintf(stderr, "%*c> fstring_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? fstring_conversion? fstring_full_format_spec? '}'")); Token * _literal; void *a; void *conversion; @@ -16131,9 +15931,9 @@ fstring_replacement_field_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (a = _tmp_113_rule(p)) // yield_expr | star_expressions + (a = _tmp_112_rule(p)) // yield_expr | star_expressions && - (debug_expr = _PyPegen_expect_token(p, 22), !p->error_indicator) // "="? + (debug_expr = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && (conversion = fstring_conversion_rule(p), !p->error_indicator) // fstring_conversion? && @@ -16142,7 +15942,7 @@ fstring_replacement_field_rule(Parser *p) (rbrace = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) \"=\"? fstring_conversion? fstring_full_format_spec? '}'")); + D(fprintf(stderr, "%*c+ fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? fstring_conversion? fstring_full_format_spec? '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -16162,7 +15962,7 @@ fstring_replacement_field_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s fstring_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) \"=\"? fstring_conversion? fstring_full_format_spec? '}'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) '='? fstring_conversion? fstring_full_format_spec? '}'")); } if (p->call_invalid_rules) { // invalid_replacement_field if (p->error_indicator) { @@ -16194,8 +15994,7 @@ static ResultTokenWithMetadata* fstring_conversion_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16241,8 +16040,7 @@ static ResultTokenWithMetadata* fstring_full_format_spec_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16270,7 +16068,7 @@ fstring_full_format_spec_rule(Parser *p) if ( (colon = _PyPegen_expect_token(p, 11)) // token=':' && - (spec = _loop0_114_rule(p)) // fstring_format_spec* + (spec = _loop0_113_rule(p)) // fstring_format_spec* ) { D(fprintf(stderr, "%*c+ fstring_full_format_spec[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' fstring_format_spec*")); @@ -16306,8 +16104,7 @@ static expr_ty fstring_format_spec_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16364,13 +16161,61 @@ fstring_format_spec_rule(Parser *p) return _res; } +// fstring: FSTRING_START fstring_middle* FSTRING_END +static expr_ty +fstring_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // FSTRING_START fstring_middle* FSTRING_END + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); + Token * a; + asdl_seq * b; + Token * c; + if ( + (a = _PyPegen_expect_token(p, FSTRING_START)) // token='FSTRING_START' + && + (b = _loop0_114_rule(p)) // fstring_middle* + && + (c = _PyPegen_expect_token(p, FSTRING_END)) // token='FSTRING_END' + ) + { + D(fprintf(stderr, "%*c+ fstring[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); + _res = _PyPegen_joined_str ( p , a , ( asdl_expr_seq* ) b , c ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // string: STRING static expr_ty string_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16413,8 +16258,7 @@ static expr_ty strings_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16480,8 +16324,7 @@ static expr_ty list_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16548,8 +16391,7 @@ static expr_ty tuple_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16616,8 +16458,7 @@ static expr_ty set_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16684,8 +16525,7 @@ static expr_ty dict_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16777,8 +16617,7 @@ static asdl_seq* double_starred_kvpairs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16825,8 +16664,7 @@ static KeyValuePair* double_starred_kvpair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16891,8 +16729,7 @@ static KeyValuePair* kvpair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16941,8 +16778,7 @@ static asdl_comprehension_seq* for_if_clauses_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16981,15 +16817,14 @@ for_if_clauses_rule(Parser *p) } // for_if_clause: -// | ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))* +// | 'async' 'for' star_targets 'in' ~ disjunction (('if' disjunction))* // | 'for' star_targets 'in' ~ disjunction (('if' disjunction))* // | invalid_for_target static comprehension_ty for_if_clause_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16997,27 +16832,27 @@ for_if_clause_rule(Parser *p) } comprehension_ty _res = NULL; int _mark = p->mark; - { // ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))* + { // 'async' 'for' star_targets 'in' ~ disjunction (('if' disjunction))* if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async' 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); int _cut_var = 0; Token * _keyword; Token * _keyword_1; + Token * _keyword_2; expr_ty a; - Token * async_var; expr_ty b; asdl_expr_seq* c; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' && - (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 666)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 667)) // token='in' && (_cut_var = 1) && @@ -17026,7 +16861,7 @@ for_if_clause_rule(Parser *p) (c = (asdl_expr_seq*)_loop0_120_rule(p)) // (('if' disjunction))* ) { - D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async' 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); _res = CHECK_VERSION ( comprehension_ty , 6 , "Async comprehensions are" , _PyAST_comprehension ( a , b , c , 1 , p -> arena ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -17037,7 +16872,7 @@ for_if_clause_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async' 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); if (_cut_var) { p->level--; return NULL; @@ -17056,11 +16891,11 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + (_keyword = _PyPegen_expect_token(p, 666)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' && (_cut_var = 1) && @@ -17116,8 +16951,7 @@ static expr_ty listcomp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17206,8 +17040,7 @@ static expr_ty setcomp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17298,8 +17131,7 @@ static expr_ty genexp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17388,8 +17220,7 @@ static expr_ty dictcomp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17478,8 +17309,7 @@ static expr_ty arguments_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17554,8 +17384,7 @@ static expr_ty args_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17655,8 +17484,7 @@ static asdl_seq* kwargs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17743,8 +17571,7 @@ static expr_ty starred_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17827,8 +17654,7 @@ static KeywordOrStarred* kwarg_or_starred_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17938,8 +17764,7 @@ static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18061,8 +17886,7 @@ static expr_ty star_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18156,8 +17980,7 @@ static asdl_expr_seq* star_targets_list_seq_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18204,8 +18027,7 @@ static asdl_expr_seq* star_targets_tuple_seq_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18282,8 +18104,7 @@ static expr_ty star_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18374,8 +18195,7 @@ static expr_ty target_with_star_atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18516,8 +18336,7 @@ static expr_ty star_atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18677,8 +18496,7 @@ static expr_ty single_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18772,8 +18590,7 @@ static expr_ty single_subscript_attribute_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18893,8 +18710,7 @@ static expr_ty t_primary_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, t_primary_type, &_res)) { @@ -18928,8 +18744,7 @@ static expr_ty t_primary_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19150,8 +18965,7 @@ static void * t_lookahead_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19227,8 +19041,7 @@ static asdl_expr_seq* del_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19278,8 +19091,7 @@ static expr_ty del_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19416,8 +19228,7 @@ static expr_ty del_t_atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19584,8 +19395,7 @@ static asdl_expr_seq* type_expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19829,8 +19639,7 @@ static Token* func_type_comment_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19912,7 +19721,7 @@ func_type_comment_rule(Parser *p) } // invalid_arguments: -// | args ',' '*' +// | ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*' // | expression for_if_clauses ',' [args | expression for_if_clauses] // | NAME '=' expression for_if_clauses // | [(args ',')] NAME '=' &(',' | ')') @@ -19923,8 +19732,7 @@ static void * invalid_arguments_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19932,25 +19740,25 @@ invalid_arguments_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // args ',' '*' + { // ((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' '*'")); + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); Token * _literal; - Token * _literal_1; - expr_ty a; + void *_tmp_150_var; + Token * b; if ( - (a = args_rule(p)) // args + (_tmp_150_var = _tmp_150_rule(p)) // (','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_literal_1 = _PyPegen_expect_token(p, 16)) // token='*' + (b = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' '*'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "iterable argument unpacking follows keyword argument unpacking" ); + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( b , "iterable argument unpacking follows keyword argument unpacking" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -19960,7 +19768,7 @@ invalid_arguments_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_arguments[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ',' '*'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' '*'")); } { // expression for_if_clauses ',' [args | expression for_if_clauses] if (p->error_indicator) { @@ -19980,7 +19788,7 @@ invalid_arguments_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_opt_var = _tmp_150_rule(p), !p->error_indicator) // [args | expression for_if_clauses] + (_opt_var = _tmp_151_rule(p), !p->error_indicator) // [args | expression for_if_clauses] ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); @@ -20040,13 +19848,13 @@ invalid_arguments_rule(Parser *p) expr_ty a; Token * b; if ( - (_opt_var = _tmp_151_rule(p), !p->error_indicator) // [(args ',')] + (_opt_var = _tmp_152_rule(p), !p->error_indicator) // [(args ',')] && (a = _PyPegen_name_token(p)) // NAME && (b = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(1, _tmp_152_rule, p) + _PyPegen_lookahead(1, _tmp_153_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); @@ -20167,8 +19975,7 @@ static void * invalid_kwarg_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20185,7 +19992,7 @@ invalid_kwarg_rule(Parser *p) Token* a; Token * b; if ( - (a = (Token*)_tmp_153_rule(p)) // 'True' | 'False' | 'None' + (a = (Token*)_tmp_154_rule(p)) // 'True' | 'False' | 'None' && (b = _PyPegen_expect_token(p, 22)) // token='=' ) @@ -20245,7 +20052,7 @@ invalid_kwarg_rule(Parser *p) expr_ty a; Token * b; if ( - _PyPegen_lookahead(0, _tmp_154_rule, p) + _PyPegen_lookahead(0, _tmp_155_rule, p) && (a = expression_rule(p)) // expression && @@ -20314,8 +20121,7 @@ expression_without_invalid_rule(Parser *p) int _prev_call_invalid = p->call_invalid_rules; p->call_invalid_rules = 0; if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->call_invalid_rules = _prev_call_invalid; @@ -20349,11 +20155,11 @@ expression_without_invalid_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 645)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 659)) // token='else' && (c = expression_rule(p)) // expression ) @@ -20434,8 +20240,7 @@ static void * invalid_legacy_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20481,13 +20286,12 @@ invalid_legacy_expression_rule(Parser *p) // invalid_expression: // | !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid // | disjunction 'if' disjunction !('else' | ':') -// | 'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field) +// | 'lambda' lambda_params? ':' &FSTRING_MIDDLE static void * invalid_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20504,7 +20308,7 @@ invalid_expression_rule(Parser *p) expr_ty a; expr_ty b; if ( - _PyPegen_lookahead(0, _tmp_155_rule, p) + _PyPegen_lookahead(0, _tmp_156_rule, p) && (a = disjunction_rule(p)) // disjunction && @@ -20536,11 +20340,11 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (b = disjunction_rule(p)) // disjunction && - _PyPegen_lookahead(0, _tmp_156_rule, p) + _PyPegen_lookahead(0, _tmp_157_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); @@ -20556,27 +20360,27 @@ invalid_expression_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); } - { // 'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field) + { // 'lambda' lambda_params? ':' &FSTRING_MIDDLE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field)")); + D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (a = _PyPegen_expect_token(p, 600)) // token='lambda' + (a = _PyPegen_expect_token(p, 609)) // token='lambda' && (_opt_var = lambda_params_rule(p), !p->error_indicator) // lambda_params? && (b = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_157_rule, p) + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, FSTRING_MIDDLE) // token=FSTRING_MIDDLE ) { - D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field)")); + D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "f-string: lambda expressions are not allowed without parentheses" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -20587,7 +20391,7 @@ invalid_expression_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field)")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); } _res = NULL; done: @@ -20603,8 +20407,7 @@ static void * invalid_named_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20730,8 +20533,7 @@ static void * invalid_assignment_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20936,8 +20738,7 @@ static expr_ty invalid_ann_assign_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21024,8 +20825,7 @@ static void * invalid_del_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21042,7 +20842,7 @@ invalid_del_stmt_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 604)) // token='del' + (_keyword = _PyPegen_expect_token(p, 613)) // token='del' && (a = star_expressions_rule(p)) // star_expressions ) @@ -21071,8 +20871,7 @@ static void * invalid_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21120,8 +20919,7 @@ static void * invalid_comprehension_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21239,8 +21037,7 @@ static void * invalid_dict_comprehension_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21301,8 +21098,7 @@ static void * invalid_parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21519,8 +21315,7 @@ static void * invalid_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21569,8 +21364,7 @@ static void * invalid_star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21712,8 +21506,7 @@ static void * invalid_kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21828,8 +21621,7 @@ static void * invalid_parameters_helper_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21897,8 +21689,7 @@ static void * invalid_lambda_parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22117,8 +21908,7 @@ static void * invalid_lambda_parameters_helper_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22183,8 +21973,7 @@ static void * invalid_lambda_star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22299,8 +22088,7 @@ static void * invalid_lambda_kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22415,8 +22203,7 @@ static void * invalid_double_type_comments_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22471,8 +22258,7 @@ static void * invalid_with_item_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22492,7 +22278,7 @@ invalid_with_item_rule(Parser *p) if ( (expression_var = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (a = expression_rule(p)) // expression && @@ -22518,13 +22304,12 @@ invalid_with_item_rule(Parser *p) return _res; } -// invalid_for_target: ASYNC? 'for' star_expressions +// invalid_for_target: 'async'? 'for' star_expressions static void * invalid_for_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22532,25 +22317,25 @@ invalid_for_target_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ASYNC? 'for' star_expressions + { // 'async'? 'for' star_expressions if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_for_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions")); + D(fprintf(stderr, "%*c> invalid_for_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_expressions")); Token * _keyword; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty a; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + (_keyword = _PyPegen_expect_token(p, 666)) // token='for' && (a = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ invalid_for_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions")); + D(fprintf(stderr, "%*c+ invalid_for_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_expressions")); _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( FOR_TARGETS , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -22561,7 +22346,7 @@ invalid_for_target_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_for_target[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'for' star_expressions")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'for' star_expressions")); } _res = NULL; done: @@ -22574,8 +22359,7 @@ static void * invalid_group_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22657,8 +22441,7 @@ static void * invalid_import_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22677,11 +22460,11 @@ invalid_import_rule(Parser *p) Token * a; expr_ty dotted_name_var; if ( - (a = _PyPegen_expect_token(p, 607)) // token='import' + (a = _PyPegen_expect_token(p, 617)) // token='import' && (_gather_203_var = _gather_203_rule(p)) // ','.dotted_name+ && - (_keyword = _PyPegen_expect_token(p, 608)) // token='from' + (_keyword = _PyPegen_expect_token(p, 618)) // token='from' && (dotted_name_var = dotted_name_rule(p)) // dotted_name ) @@ -22710,8 +22493,7 @@ static void * invalid_import_from_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22756,14 +22538,13 @@ invalid_import_from_targets_rule(Parser *p) } // invalid_with_stmt: -// | ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE -// | ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE +// | 'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE +// | 'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE static void * invalid_with_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22771,28 +22552,28 @@ invalid_with_stmt_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE + { // 'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE")); asdl_seq * _gather_205_var; Token * _keyword; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + (_keyword = _PyPegen_expect_token(p, 629)) // token='with' && (_gather_205_var = _gather_205_rule(p)) // ','.(expression ['as' star_target])+ && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); + D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -22803,14 +22584,14 @@ invalid_with_stmt_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE")); } - { // ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE + { // 'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); asdl_seq * _gather_207_var; Token * _keyword; Token * _literal; @@ -22821,9 +22602,9 @@ invalid_with_stmt_rule(Parser *p) UNUSED(_opt_var_1); // Silence compiler warnings Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + (_keyword = _PyPegen_expect_token(p, 629)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -22836,7 +22617,7 @@ invalid_with_stmt_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); + D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -22847,7 +22628,7 @@ invalid_with_stmt_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); } _res = NULL; done: @@ -22856,14 +22637,13 @@ invalid_with_stmt_rule(Parser *p) } // invalid_with_stmt_indent: -// | ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT -// | ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT +// | 'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT +// | 'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT static void * invalid_with_stmt_indent_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22871,12 +22651,12 @@ invalid_with_stmt_indent_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT + { // 'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); asdl_seq * _gather_209_var; Token * _literal; void *_opt_var; @@ -22884,9 +22664,9 @@ invalid_with_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 615)) // token='with' + (a = _PyPegen_expect_token(p, 629)) // token='with' && (_gather_209_var = _gather_209_rule(p)) // ','.(expression ['as' star_target])+ && @@ -22897,7 +22677,7 @@ invalid_with_stmt_indent_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT ) { - D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -22908,14 +22688,14 @@ invalid_with_stmt_indent_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_with_stmt_indent[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); } - { // ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT + { // 'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); asdl_seq * _gather_211_var; Token * _literal; Token * _literal_1; @@ -22927,9 +22707,9 @@ invalid_with_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 615)) // token='with' + (a = _PyPegen_expect_token(p, 629)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -22946,7 +22726,7 @@ invalid_with_stmt_indent_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT ) { - D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -22957,7 +22737,7 @@ invalid_with_stmt_indent_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_with_stmt_indent[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); } _res = NULL; done: @@ -22974,8 +22754,7 @@ static void * invalid_try_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22993,7 +22772,7 @@ invalid_try_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 624)) // token='try' + (a = _PyPegen_expect_token(p, 638)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23025,7 +22804,7 @@ invalid_try_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 624)) // token='try' + (_keyword = _PyPegen_expect_token(p, 638)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23064,7 +22843,7 @@ invalid_try_stmt_rule(Parser *p) Token * b; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 624)) // token='try' + (_keyword = _PyPegen_expect_token(p, 638)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23072,7 +22851,7 @@ invalid_try_stmt_rule(Parser *p) && (_loop1_215_var = _loop1_215_rule(p)) // except_block+ && - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (b = _PyPegen_expect_token(p, 16)) // token='*' && @@ -23111,7 +22890,7 @@ invalid_try_stmt_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings Token * a; if ( - (_keyword = _PyPegen_expect_token(p, 624)) // token='try' + (_keyword = _PyPegen_expect_token(p, 638)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23119,7 +22898,7 @@ invalid_try_stmt_rule(Parser *p) && (_loop1_218_var = _loop1_218_rule(p)) // except_star_block+ && - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (_opt_var = _tmp_219_rule(p), !p->error_indicator) // [expression ['as' NAME]] && @@ -23154,8 +22933,7 @@ static void * invalid_except_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23179,7 +22957,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty a; expr_ty expressions_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='except' + (_keyword = _PyPegen_expect_token(p, 651)) // token='except' && (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && @@ -23221,7 +22999,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && @@ -23254,7 +23032,7 @@ invalid_except_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -23282,7 +23060,7 @@ invalid_except_stmt_rule(Parser *p) void *_tmp_222_var; Token * a; if ( - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -23313,8 +23091,7 @@ static void * invalid_finally_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23332,7 +23109,7 @@ invalid_finally_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 633)) // token='finally' + (a = _PyPegen_expect_token(p, 647)) // token='finally' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23367,8 +23144,7 @@ static void * invalid_except_stmt_indent_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23389,7 +23165,7 @@ invalid_except_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (expression_var = expression_rule(p)) // expression && @@ -23425,7 +23201,7 @@ invalid_except_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23459,8 +23235,7 @@ static void * invalid_except_star_stmt_indent_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23482,7 +23257,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 637)) // token='except' + (a = _PyPegen_expect_token(p, 651)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -23523,8 +23298,7 @@ static void * invalid_match_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23610,8 +23384,7 @@ static void * invalid_case_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23703,8 +23476,7 @@ static void * invalid_as_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23724,7 +23496,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (a = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' ) @@ -23754,7 +23526,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p) && @@ -23785,8 +23557,7 @@ static void * invalid_class_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23836,8 +23607,7 @@ static asdl_pattern_seq* invalid_class_argument_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23892,8 +23662,7 @@ static void * invalid_if_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23911,7 +23680,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23942,7 +23711,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty a_1; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 642)) // token='if' + (a = _PyPegen_expect_token(p, 656)) // token='if' && (a_1 = named_expression_rule(p)) // named_expression && @@ -23979,8 +23748,7 @@ static void * invalid_elif_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23998,7 +23766,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 644)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 658)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -24029,7 +23797,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 644)) // token='elif' + (a = _PyPegen_expect_token(p, 658)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -24064,8 +23832,7 @@ static void * invalid_else_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24083,7 +23850,7 @@ invalid_else_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 645)) // token='else' + (a = _PyPegen_expect_token(p, 659)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24118,8 +23885,7 @@ static void * invalid_while_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24137,7 +23903,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='while' + (_keyword = _PyPegen_expect_token(p, 661)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -24168,7 +23934,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 647)) // token='while' + (a = _PyPegen_expect_token(p, 661)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -24199,14 +23965,13 @@ invalid_while_stmt_rule(Parser *p) } // invalid_for_stmt: -// | ASYNC? 'for' star_targets 'in' star_expressions NEWLINE -// | ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT +// | 'async'? 'for' star_targets 'in' star_expressions NEWLINE +// | 'async'? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT static void * invalid_for_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24214,12 +23979,12 @@ invalid_for_stmt_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ASYNC? 'for' star_targets 'in' star_expressions NEWLINE + { // 'async'? 'for' star_targets 'in' star_expressions NEWLINE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions NEWLINE")); + D(fprintf(stderr, "%*c> invalid_for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions NEWLINE")); Token * _keyword; Token * _keyword_1; void *_opt_var; @@ -24228,20 +23993,20 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + (_keyword = _PyPegen_expect_token(p, 666)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions NEWLINE")); + D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24252,14 +24017,14 @@ invalid_for_stmt_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions NEWLINE")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions NEWLINE")); } - { // ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT + { // 'async'? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c> invalid_for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); Token * _keyword; Token * _literal; void *_opt_var; @@ -24269,13 +24034,13 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 650)) // token='for' + (a = _PyPegen_expect_token(p, 666)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword = _PyPegen_expect_token(p, 651)) // token='in' + (_keyword = _PyPegen_expect_token(p, 667)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -24286,7 +24051,7 @@ invalid_for_stmt_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT ) { - D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'for' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24297,7 +24062,7 @@ invalid_for_stmt_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); } _res = NULL; done: @@ -24306,13 +24071,12 @@ invalid_for_stmt_rule(Parser *p) } // invalid_def_raw: -// | ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT +// | 'async'? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT static void * invalid_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24320,12 +24084,12 @@ invalid_def_raw_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT + { // 'async'? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c> invalid_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); Token * _literal; Token * _literal_1; Token * _literal_2; @@ -24339,9 +24103,9 @@ invalid_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 652)) // token='def' + (a = _PyPegen_expect_token(p, 669)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -24360,7 +24124,7 @@ invalid_def_raw_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT ) { - D(fprintf(stderr, "%*c+ invalid_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c+ invalid_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after function definition on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24371,7 +24135,7 @@ invalid_def_raw_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); } _res = NULL; done: @@ -24386,8 +24150,7 @@ static void * invalid_class_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24407,7 +24170,7 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='class' + (_keyword = _PyPegen_expect_token(p, 671)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -24442,7 +24205,7 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 654)) // token='class' + (a = _PyPegen_expect_token(p, 671)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -24482,8 +24245,7 @@ static void * invalid_double_starred_kvpairs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24592,8 +24354,7 @@ static void * invalid_kvpair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24700,8 +24461,7 @@ static void * invalid_starred_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24764,8 +24524,7 @@ static void * invalid_replacement_field_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25125,8 +24884,7 @@ static void * invalid_conversion_character_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25197,8 +24955,7 @@ static asdl_seq * _loop0_1_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25265,8 +25022,7 @@ static asdl_seq * _loop0_2_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25328,81 +25084,12 @@ _loop0_2_rule(Parser *p) return _seq; } -// _loop0_3: fstring_middle +// _loop1_3: statement static asdl_seq * -_loop0_3_rule(Parser *p) +_loop1_3_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // fstring_middle - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_middle")); - expr_ty fstring_middle_var; - while ( - (fstring_middle_var = fstring_middle_rule(p)) // fstring_middle - ) - { - _res = fstring_middle_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_3[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_middle")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - p->level--; - return _seq; -} - -// _loop1_4: statement -static asdl_seq * -_loop1_4_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25424,7 +25111,7 @@ _loop1_4_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); + D(fprintf(stderr, "%*c> _loop1_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); asdl_stmt_seq* statement_var; while ( (statement_var = statement_rule(p)) // statement @@ -25447,7 +25134,7 @@ _loop1_4_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_4[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_3[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statement")); } if (_n == 0 || p->error_indicator) { @@ -25469,13 +25156,12 @@ _loop1_4_rule(Parser *p) return _seq; } -// _loop0_6: ';' simple_stmt +// _loop0_5: ';' simple_stmt static asdl_seq * -_loop0_6_rule(Parser *p) +_loop0_5_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25497,7 +25183,7 @@ _loop0_6_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' simple_stmt")); + D(fprintf(stderr, "%*c> _loop0_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' simple_stmt")); Token * _literal; stmt_ty elem; while ( @@ -25529,7 +25215,7 @@ _loop0_6_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_6[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_5[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';' simple_stmt")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25546,13 +25232,12 @@ _loop0_6_rule(Parser *p) return _seq; } -// _gather_5: simple_stmt _loop0_6 +// _gather_4: simple_stmt _loop0_5 static asdl_seq * -_gather_5_rule(Parser *p) +_gather_4_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25560,27 +25245,27 @@ _gather_5_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // simple_stmt _loop0_6 + { // simple_stmt _loop0_5 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_6")); + D(fprintf(stderr, "%*c> _gather_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_5")); stmt_ty elem; asdl_seq * seq; if ( (elem = simple_stmt_rule(p)) // simple_stmt && - (seq = _loop0_6_rule(p)) // _loop0_6 + (seq = _loop0_5_rule(p)) // _loop0_5 ) { - D(fprintf(stderr, "%*c+ _gather_5[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_6")); + D(fprintf(stderr, "%*c+ _gather_4[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_5")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_5[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt _loop0_6")); + D(fprintf(stderr, "%*c%s _gather_4[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt _loop0_5")); } _res = NULL; done: @@ -25588,13 +25273,12 @@ _gather_5_rule(Parser *p) return _res; } -// _tmp_7: 'import' | 'from' +// _tmp_6: 'import' | 'from' static void * -_tmp_7_rule(Parser *p) +_tmp_6_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25607,18 +25291,18 @@ _tmp_7_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); + D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 607)) // token='import' + (_keyword = _PyPegen_expect_token(p, 617)) // token='import' ) { - D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); + D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_6[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import'")); } { // 'from' @@ -25626,18 +25310,18 @@ _tmp_7_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); + D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 608)) // token='from' + (_keyword = _PyPegen_expect_token(p, 618)) // token='from' ) { - D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); + D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_6[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from'")); } _res = NULL; @@ -25646,13 +25330,12 @@ _tmp_7_rule(Parser *p) return _res; } -// _tmp_8: 'def' | '@' | ASYNC +// _tmp_7: 'def' | '@' | 'async' static void * -_tmp_8_rule(Parser *p) +_tmp_7_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25665,18 +25348,18 @@ _tmp_8_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); + D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 652)) // token='def' + (_keyword = _PyPegen_expect_token(p, 669)) // token='def' ) { - D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); + D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def'")); } { // '@' @@ -25684,38 +25367,38 @@ _tmp_8_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 49)) // token='@' ) { - D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@'")); } - { // ASYNC + { // 'async' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); - Token * async_var; + D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); + Token * _keyword; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' ) { - D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); - _res = async_var; + D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); + _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'")); } _res = NULL; done: @@ -25723,13 +25406,12 @@ _tmp_8_rule(Parser *p) return _res; } -// _tmp_9: 'class' | '@' +// _tmp_8: 'class' | '@' static void * -_tmp_9_rule(Parser *p) +_tmp_8_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25742,18 +25424,18 @@ _tmp_9_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); + D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='class' + (_keyword = _PyPegen_expect_token(p, 671)) // token='class' ) { - D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); + D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class'")); } { // '@' @@ -25761,18 +25443,18 @@ _tmp_9_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 49)) // token='@' ) { - D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@'")); } _res = NULL; @@ -25781,13 +25463,12 @@ _tmp_9_rule(Parser *p) return _res; } -// _tmp_10: 'with' | ASYNC +// _tmp_9: 'with' | 'async' static void * -_tmp_10_rule(Parser *p) +_tmp_9_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25800,38 +25481,38 @@ _tmp_10_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); + D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + (_keyword = _PyPegen_expect_token(p, 629)) // token='with' ) { - D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); + D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with'")); } - { // ASYNC + { // 'async' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); - Token * async_var; + D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); + Token * _keyword; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' ) { - D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); - _res = async_var; + D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); + _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'")); } _res = NULL; done: @@ -25839,13 +25520,12 @@ _tmp_10_rule(Parser *p) return _res; } -// _tmp_11: 'for' | ASYNC +// _tmp_10: 'for' | 'async' static void * -_tmp_11_rule(Parser *p) +_tmp_10_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25858,38 +25538,38 @@ _tmp_11_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); + D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + (_keyword = _PyPegen_expect_token(p, 666)) // token='for' ) { - D(fprintf(stderr, "%*c+ _tmp_11[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); + D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_11[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for'")); } - { // ASYNC + { // 'async' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); - Token * async_var; + D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); + Token * _keyword; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_keyword = _PyPegen_expect_token(p, 668)) // token='async' ) { - D(fprintf(stderr, "%*c+ _tmp_11[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); - _res = async_var; + D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); + _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_11[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'")); } _res = NULL; done: @@ -25897,13 +25577,12 @@ _tmp_11_rule(Parser *p) return _res; } -// _tmp_12: '=' annotated_rhs +// _tmp_11: '=' annotated_rhs static void * -_tmp_12_rule(Parser *p) +_tmp_11_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25916,7 +25595,7 @@ _tmp_12_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + D(fprintf(stderr, "%*c> _tmp_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); Token * _literal; expr_ty d; if ( @@ -25925,7 +25604,7 @@ _tmp_12_rule(Parser *p) (d = annotated_rhs_rule(p)) // annotated_rhs ) { - D(fprintf(stderr, "%*c+ _tmp_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + D(fprintf(stderr, "%*c+ _tmp_11[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -25935,7 +25614,7 @@ _tmp_12_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_12[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_11[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); } _res = NULL; @@ -25944,13 +25623,12 @@ _tmp_12_rule(Parser *p) return _res; } -// _tmp_13: '(' single_target ')' | single_subscript_attribute_target +// _tmp_12: '(' single_target ')' | single_subscript_attribute_target static void * -_tmp_13_rule(Parser *p) +_tmp_12_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25963,7 +25641,7 @@ _tmp_13_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); + D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); Token * _literal; Token * _literal_1; expr_ty b; @@ -25975,7 +25653,7 @@ _tmp_13_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_13[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); + D(fprintf(stderr, "%*c+ _tmp_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); _res = b; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -25985,7 +25663,7 @@ _tmp_13_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_13[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_12[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' single_target ')'")); } { // single_subscript_attribute_target @@ -25993,18 +25671,18 @@ _tmp_13_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); + D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); expr_ty single_subscript_attribute_target_var; if ( (single_subscript_attribute_target_var = single_subscript_attribute_target_rule(p)) // single_subscript_attribute_target ) { - D(fprintf(stderr, "%*c+ _tmp_13[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); + D(fprintf(stderr, "%*c+ _tmp_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); _res = single_subscript_attribute_target_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_13[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_12[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_subscript_attribute_target")); } _res = NULL; @@ -26013,13 +25691,12 @@ _tmp_13_rule(Parser *p) return _res; } -// _tmp_14: '=' annotated_rhs +// _tmp_13: '=' annotated_rhs static void * -_tmp_14_rule(Parser *p) +_tmp_13_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26032,7 +25709,7 @@ _tmp_14_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + D(fprintf(stderr, "%*c> _tmp_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); Token * _literal; expr_ty d; if ( @@ -26041,7 +25718,7 @@ _tmp_14_rule(Parser *p) (d = annotated_rhs_rule(p)) // annotated_rhs ) { - D(fprintf(stderr, "%*c+ _tmp_14[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + D(fprintf(stderr, "%*c+ _tmp_13[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -26051,7 +25728,7 @@ _tmp_14_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_14[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_13[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); } _res = NULL; @@ -26060,13 +25737,12 @@ _tmp_14_rule(Parser *p) return _res; } -// _loop1_15: (star_targets '=') +// _loop1_14: (star_targets '=') static asdl_seq * -_loop1_15_rule(Parser *p) +_loop1_14_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26088,7 +25764,7 @@ _loop1_15_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); void *_tmp_248_var; while ( (_tmp_248_var = _tmp_248_rule(p)) // star_targets '=' @@ -26111,7 +25787,7 @@ _loop1_15_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_15[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_14[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } if (_n == 0 || p->error_indicator) { @@ -26133,13 +25809,12 @@ _loop1_15_rule(Parser *p) return _seq; } -// _tmp_16: yield_expr | star_expressions +// _tmp_15: yield_expr | star_expressions static void * -_tmp_16_rule(Parser *p) +_tmp_15_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26152,18 +25827,18 @@ _tmp_16_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_15[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -26171,18 +25846,18 @@ _tmp_16_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_15[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -26191,13 +25866,12 @@ _tmp_16_rule(Parser *p) return _res; } -// _tmp_17: yield_expr | star_expressions +// _tmp_16: yield_expr | star_expressions static void * -_tmp_17_rule(Parser *p) +_tmp_16_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26210,18 +25884,18 @@ _tmp_17_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_17[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -26229,18 +25903,18 @@ _tmp_17_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_17[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -26249,13 +25923,12 @@ _tmp_17_rule(Parser *p) return _res; } -// _tmp_18: 'from' expression +// _tmp_17: 'from' expression static void * -_tmp_18_rule(Parser *p) +_tmp_17_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26268,16 +25941,16 @@ _tmp_18_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression")); + D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 608)) // token='from' + (_keyword = _PyPegen_expect_token(p, 618)) // token='from' && (z = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_18[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' expression")); + D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' expression")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -26287,7 +25960,7 @@ _tmp_18_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_18[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_17[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' expression")); } _res = NULL; @@ -26296,13 +25969,12 @@ _tmp_18_rule(Parser *p) return _res; } -// _loop0_20: ',' NAME +// _loop0_19: ',' NAME static asdl_seq * -_loop0_20_rule(Parser *p) +_loop0_19_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26324,7 +25996,7 @@ _loop0_20_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_20[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); + D(fprintf(stderr, "%*c> _loop0_19[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); Token * _literal; expr_ty elem; while ( @@ -26356,7 +26028,7 @@ _loop0_20_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_20[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_19[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26373,13 +26045,12 @@ _loop0_20_rule(Parser *p) return _seq; } -// _gather_19: NAME _loop0_20 +// _gather_18: NAME _loop0_19 static asdl_seq * -_gather_19_rule(Parser *p) +_gather_18_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26387,27 +26058,27 @@ _gather_19_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // NAME _loop0_20 + { // NAME _loop0_19 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_19[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_20")); + D(fprintf(stderr, "%*c> _gather_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_19")); expr_ty elem; asdl_seq * seq; if ( (elem = _PyPegen_name_token(p)) // NAME && - (seq = _loop0_20_rule(p)) // _loop0_20 + (seq = _loop0_19_rule(p)) // _loop0_19 ) { - D(fprintf(stderr, "%*c+ _gather_19[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_20")); + D(fprintf(stderr, "%*c+ _gather_18[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_19")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_19[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_20")); + D(fprintf(stderr, "%*c%s _gather_18[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_19")); } _res = NULL; done: @@ -26415,13 +26086,12 @@ _gather_19_rule(Parser *p) return _res; } -// _loop0_22: ',' NAME +// _loop0_21: ',' NAME static asdl_seq * -_loop0_22_rule(Parser *p) +_loop0_21_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26443,7 +26113,7 @@ _loop0_22_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); + D(fprintf(stderr, "%*c> _loop0_21[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); Token * _literal; expr_ty elem; while ( @@ -26475,7 +26145,7 @@ _loop0_22_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_22[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_21[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26492,13 +26162,12 @@ _loop0_22_rule(Parser *p) return _seq; } -// _gather_21: NAME _loop0_22 +// _gather_20: NAME _loop0_21 static asdl_seq * -_gather_21_rule(Parser *p) +_gather_20_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26506,27 +26175,27 @@ _gather_21_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // NAME _loop0_22 + { // NAME _loop0_21 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_21[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_22")); + D(fprintf(stderr, "%*c> _gather_20[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_21")); expr_ty elem; asdl_seq * seq; if ( (elem = _PyPegen_name_token(p)) // NAME && - (seq = _loop0_22_rule(p)) // _loop0_22 + (seq = _loop0_21_rule(p)) // _loop0_21 ) { - D(fprintf(stderr, "%*c+ _gather_21[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_22")); + D(fprintf(stderr, "%*c+ _gather_20[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_21")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_21[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_22")); + D(fprintf(stderr, "%*c%s _gather_20[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_21")); } _res = NULL; done: @@ -26534,13 +26203,12 @@ _gather_21_rule(Parser *p) return _res; } -// _tmp_23: ';' | NEWLINE +// _tmp_22: ';' | NEWLINE static void * -_tmp_23_rule(Parser *p) +_tmp_22_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26553,18 +26221,18 @@ _tmp_23_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'")); + D(fprintf(stderr, "%*c> _tmp_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 13)) // token=';' ) { - D(fprintf(stderr, "%*c+ _tmp_23[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'")); + D(fprintf(stderr, "%*c+ _tmp_22[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_23[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_22[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';'")); } { // NEWLINE @@ -26572,18 +26240,18 @@ _tmp_23_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); Token * newline_var; if ( (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_23[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_22[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); _res = newline_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_23[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_22[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } _res = NULL; @@ -26592,13 +26260,12 @@ _tmp_23_rule(Parser *p) return _res; } -// _tmp_24: ',' expression +// _tmp_23: ',' expression static void * -_tmp_24_rule(Parser *p) +_tmp_23_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26611,7 +26278,7 @@ _tmp_24_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty z; if ( @@ -26620,7 +26287,7 @@ _tmp_24_rule(Parser *p) (z = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_24[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_23[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -26630,7 +26297,7 @@ _tmp_24_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_24[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_23[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -26639,13 +26306,12 @@ _tmp_24_rule(Parser *p) return _res; } -// _loop0_25: ('.' | '...') +// _loop0_24: ('.' | '...') static asdl_seq * -_loop0_25_rule(Parser *p) +_loop0_24_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26667,7 +26333,7 @@ _loop0_25_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); + D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); void *_tmp_249_var; while ( (_tmp_249_var = _tmp_249_rule(p)) // '.' | '...' @@ -26690,7 +26356,7 @@ _loop0_25_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_25[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_24[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26707,13 +26373,12 @@ _loop0_25_rule(Parser *p) return _seq; } -// _loop1_26: ('.' | '...') +// _loop1_25: ('.' | '...') static asdl_seq * -_loop1_26_rule(Parser *p) +_loop1_25_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26735,7 +26400,7 @@ _loop1_26_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); + D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); void *_tmp_250_var; while ( (_tmp_250_var = _tmp_250_rule(p)) // '.' | '...' @@ -26758,7 +26423,7 @@ _loop1_26_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_26[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_25[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); } if (_n == 0 || p->error_indicator) { @@ -26780,13 +26445,12 @@ _loop1_26_rule(Parser *p) return _seq; } -// _loop0_28: ',' import_from_as_name +// _loop0_27: ',' import_from_as_name static asdl_seq * -_loop0_28_rule(Parser *p) +_loop0_27_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26808,7 +26472,7 @@ _loop0_28_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_28[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name")); + D(fprintf(stderr, "%*c> _loop0_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name")); Token * _literal; alias_ty elem; while ( @@ -26840,7 +26504,7 @@ _loop0_28_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_28[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_27[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' import_from_as_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26857,13 +26521,12 @@ _loop0_28_rule(Parser *p) return _seq; } -// _gather_27: import_from_as_name _loop0_28 +// _gather_26: import_from_as_name _loop0_27 static asdl_seq * -_gather_27_rule(Parser *p) +_gather_26_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26871,27 +26534,27 @@ _gather_27_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // import_from_as_name _loop0_28 + { // import_from_as_name _loop0_27 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_28")); + D(fprintf(stderr, "%*c> _gather_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_27")); alias_ty elem; asdl_seq * seq; if ( (elem = import_from_as_name_rule(p)) // import_from_as_name && - (seq = _loop0_28_rule(p)) // _loop0_28 + (seq = _loop0_27_rule(p)) // _loop0_27 ) { - D(fprintf(stderr, "%*c+ _gather_27[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_28")); + D(fprintf(stderr, "%*c+ _gather_26[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_27")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_27[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_name _loop0_28")); + D(fprintf(stderr, "%*c%s _gather_26[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_name _loop0_27")); } _res = NULL; done: @@ -26899,13 +26562,12 @@ _gather_27_rule(Parser *p) return _res; } -// _tmp_29: 'as' NAME +// _tmp_28: 'as' NAME static void * -_tmp_29_rule(Parser *p) +_tmp_28_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26918,16 +26580,16 @@ _tmp_29_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_29[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_28[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_29[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_28[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -26937,7 +26599,7 @@ _tmp_29_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_29[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_28[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -26946,13 +26608,12 @@ _tmp_29_rule(Parser *p) return _res; } -// _loop0_31: ',' dotted_as_name +// _loop0_30: ',' dotted_as_name static asdl_seq * -_loop0_31_rule(Parser *p) +_loop0_30_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26974,7 +26635,7 @@ _loop0_31_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name")); + D(fprintf(stderr, "%*c> _loop0_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name")); Token * _literal; alias_ty elem; while ( @@ -27006,7 +26667,7 @@ _loop0_31_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_31[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_30[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_as_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27023,13 +26684,12 @@ _loop0_31_rule(Parser *p) return _seq; } -// _gather_30: dotted_as_name _loop0_31 +// _gather_29: dotted_as_name _loop0_30 static asdl_seq * -_gather_30_rule(Parser *p) +_gather_29_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27037,27 +26697,27 @@ _gather_30_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // dotted_as_name _loop0_31 + { // dotted_as_name _loop0_30 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_31")); + D(fprintf(stderr, "%*c> _gather_29[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_30")); alias_ty elem; asdl_seq * seq; if ( (elem = dotted_as_name_rule(p)) // dotted_as_name && - (seq = _loop0_31_rule(p)) // _loop0_31 + (seq = _loop0_30_rule(p)) // _loop0_30 ) { - D(fprintf(stderr, "%*c+ _gather_30[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_31")); + D(fprintf(stderr, "%*c+ _gather_29[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_30")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_30[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_as_name _loop0_31")); + D(fprintf(stderr, "%*c%s _gather_29[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_as_name _loop0_30")); } _res = NULL; done: @@ -27065,13 +26725,12 @@ _gather_30_rule(Parser *p) return _res; } -// _tmp_32: 'as' NAME +// _tmp_31: 'as' NAME static void * -_tmp_32_rule(Parser *p) +_tmp_31_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27084,16 +26743,16 @@ _tmp_32_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_32[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_31[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -27103,7 +26762,7 @@ _tmp_32_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_32[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_31[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -27112,13 +26771,12 @@ _tmp_32_rule(Parser *p) return _res; } -// _loop1_33: ('@' named_expression NEWLINE) +// _loop1_32: ('@' named_expression NEWLINE) static asdl_seq * -_loop1_33_rule(Parser *p) +_loop1_32_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27140,7 +26798,7 @@ _loop1_33_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); + D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); void *_tmp_251_var; while ( (_tmp_251_var = _tmp_251_rule(p)) // '@' named_expression NEWLINE @@ -27163,7 +26821,7 @@ _loop1_33_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_33[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_32[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('@' named_expression NEWLINE)")); } if (_n == 0 || p->error_indicator) { @@ -27185,13 +26843,12 @@ _loop1_33_rule(Parser *p) return _seq; } -// _tmp_34: '(' arguments? ')' +// _tmp_33: '(' arguments? ')' static void * -_tmp_34_rule(Parser *p) +_tmp_33_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27204,7 +26861,7 @@ _tmp_34_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *z; @@ -27216,7 +26873,7 @@ _tmp_34_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_34[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_33[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -27226,7 +26883,7 @@ _tmp_34_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_34[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_33[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -27235,13 +26892,12 @@ _tmp_34_rule(Parser *p) return _res; } -// _tmp_35: '->' expression +// _tmp_34: '->' expression static void * -_tmp_35_rule(Parser *p) +_tmp_34_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27254,7 +26910,7 @@ _tmp_35_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty z; if ( @@ -27263,7 +26919,7 @@ _tmp_35_rule(Parser *p) (z = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_35[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_34[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -27273,7 +26929,7 @@ _tmp_35_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_35[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_34[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -27282,13 +26938,12 @@ _tmp_35_rule(Parser *p) return _res; } -// _tmp_36: '->' expression +// _tmp_35: '->' expression static void * -_tmp_36_rule(Parser *p) +_tmp_35_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27301,7 +26956,7 @@ _tmp_36_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty z; if ( @@ -27310,7 +26965,7 @@ _tmp_36_rule(Parser *p) (z = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_36[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_35[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -27320,7 +26975,7 @@ _tmp_36_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_36[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_35[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -27329,13 +26984,12 @@ _tmp_36_rule(Parser *p) return _res; } -// _loop0_37: param_no_default +// _loop0_36: param_no_default static asdl_seq * -_loop0_37_rule(Parser *p) +_loop0_36_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27357,7 +27011,7 @@ _loop0_37_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -27380,7 +27034,7 @@ _loop0_37_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_37[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_36[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27397,13 +27051,12 @@ _loop0_37_rule(Parser *p) return _seq; } -// _loop0_38: param_with_default +// _loop0_37: param_with_default static asdl_seq * -_loop0_38_rule(Parser *p) +_loop0_37_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27425,7 +27078,7 @@ _loop0_38_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -27448,7 +27101,7 @@ _loop0_38_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_38[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_37[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27465,13 +27118,12 @@ _loop0_38_rule(Parser *p) return _seq; } -// _loop0_39: param_with_default +// _loop0_38: param_with_default static asdl_seq * -_loop0_39_rule(Parser *p) +_loop0_38_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27493,7 +27145,7 @@ _loop0_39_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop0_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -27516,7 +27168,7 @@ _loop0_39_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_39[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_38[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27533,13 +27185,12 @@ _loop0_39_rule(Parser *p) return _seq; } -// _loop1_40: param_no_default +// _loop1_39: param_no_default static asdl_seq * -_loop1_40_rule(Parser *p) +_loop1_39_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27561,7 +27212,7 @@ _loop1_40_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop1_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -27584,7 +27235,7 @@ _loop1_40_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_40[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_39[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -27606,13 +27257,12 @@ _loop1_40_rule(Parser *p) return _seq; } -// _loop0_41: param_with_default +// _loop0_40: param_with_default static asdl_seq * -_loop0_41_rule(Parser *p) +_loop0_40_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27634,7 +27284,7 @@ _loop0_41_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop0_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -27657,7 +27307,7 @@ _loop0_41_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_41[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_40[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27674,13 +27324,12 @@ _loop0_41_rule(Parser *p) return _seq; } -// _loop1_42: param_with_default +// _loop1_41: param_with_default static asdl_seq * -_loop1_42_rule(Parser *p) +_loop1_41_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27702,7 +27351,7 @@ _loop1_42_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -27725,7 +27374,7 @@ _loop1_42_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_42[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_41[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -27747,13 +27396,84 @@ _loop1_42_rule(Parser *p) return _seq; } -// _loop1_43: param_no_default +// _loop1_42: param_no_default static asdl_seq * -_loop1_43_rule(Parser *p) +_loop1_42_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + _res = param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_42[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop1_43: param_no_default +static asdl_seq * +_loop1_43_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27820,13 +27540,12 @@ _loop1_43_rule(Parser *p) return _seq; } -// _loop1_44: param_no_default +// _loop0_44: param_no_default static asdl_seq * -_loop1_44_rule(Parser *p) +_loop0_44_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27848,7 +27567,7 @@ _loop1_44_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -27871,9 +27590,76 @@ _loop1_44_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_44[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_44[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop1_45: param_with_default +static asdl_seq * +_loop1_45_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + NameDefaultPair* param_with_default_var; + while ( + (param_with_default_var = param_with_default_rule(p)) // param_with_default + ) + { + _res = param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_45[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); + } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); p->level--; @@ -27893,154 +27679,12 @@ _loop1_44_rule(Parser *p) return _seq; } -// _loop0_45: param_no_default +// _loop0_46: param_no_default static asdl_seq * -_loop0_45_rule(Parser *p) +_loop0_46_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; - while ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default - ) - { - _res = param_no_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_45[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - p->level--; - return _seq; -} - -// _loop1_46: param_with_default -static asdl_seq * -_loop1_46_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // param_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); - NameDefaultPair* param_with_default_var; - while ( - (param_with_default_var = param_with_default_rule(p)) // param_with_default - ) - { - _res = param_with_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_46[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - p->level--; - return _seq; -} - -// _loop0_47: param_no_default -static asdl_seq * -_loop0_47_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28062,7 +27706,7 @@ _loop0_47_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -28085,7 +27729,7 @@ _loop0_47_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_47[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_46[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28102,13 +27746,12 @@ _loop0_47_rule(Parser *p) return _seq; } -// _loop1_48: param_with_default +// _loop1_47: param_with_default static asdl_seq * -_loop1_48_rule(Parser *p) +_loop1_47_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28130,7 +27773,7 @@ _loop1_48_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_48[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -28153,7 +27796,7 @@ _loop1_48_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_48[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_47[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -28175,13 +27818,12 @@ _loop1_48_rule(Parser *p) return _seq; } -// _loop0_49: param_maybe_default +// _loop0_48: param_maybe_default static asdl_seq * -_loop0_49_rule(Parser *p) +_loop0_48_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28203,7 +27845,7 @@ _loop0_49_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_48[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -28226,7 +27868,7 @@ _loop0_49_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_49[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_48[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28243,13 +27885,12 @@ _loop0_49_rule(Parser *p) return _seq; } -// _loop0_50: param_maybe_default +// _loop0_49: param_maybe_default static asdl_seq * -_loop0_50_rule(Parser *p) +_loop0_49_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28271,7 +27912,7 @@ _loop0_50_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -28294,7 +27935,7 @@ _loop0_50_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_50[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_49[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28311,13 +27952,12 @@ _loop0_50_rule(Parser *p) return _seq; } -// _loop1_51: param_maybe_default +// _loop1_50: param_maybe_default static asdl_seq * -_loop1_51_rule(Parser *p) +_loop1_50_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28339,7 +27979,7 @@ _loop1_51_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -28362,7 +28002,7 @@ _loop1_51_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_51[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_50[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -28384,13 +28024,12 @@ _loop1_51_rule(Parser *p) return _seq; } -// _loop0_53: ',' with_item +// _loop0_52: ',' with_item static asdl_seq * -_loop0_53_rule(Parser *p) +_loop0_52_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28412,7 +28051,7 @@ _loop0_53_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -28444,7 +28083,7 @@ _loop0_53_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_53[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_52[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28461,13 +28100,12 @@ _loop0_53_rule(Parser *p) return _seq; } -// _gather_52: with_item _loop0_53 +// _gather_51: with_item _loop0_52 static asdl_seq * -_gather_52_rule(Parser *p) +_gather_51_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28475,27 +28113,27 @@ _gather_52_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_53 + { // with_item _loop0_52 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c> _gather_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_53_rule(p)) // _loop0_53 + (seq = _loop0_52_rule(p)) // _loop0_52 ) { - D(fprintf(stderr, "%*c+ _gather_52[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c+ _gather_51[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_52[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c%s _gather_51[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_52")); } _res = NULL; done: @@ -28503,13 +28141,12 @@ _gather_52_rule(Parser *p) return _res; } -// _loop0_55: ',' with_item +// _loop0_54: ',' with_item static asdl_seq * -_loop0_55_rule(Parser *p) +_loop0_54_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28531,7 +28168,7 @@ _loop0_55_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -28563,7 +28200,7 @@ _loop0_55_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_55[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_54[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28580,13 +28217,12 @@ _loop0_55_rule(Parser *p) return _seq; } -// _gather_54: with_item _loop0_55 +// _gather_53: with_item _loop0_54 static asdl_seq * -_gather_54_rule(Parser *p) +_gather_53_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28594,27 +28230,27 @@ _gather_54_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_55 + { // with_item _loop0_54 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c> _gather_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_55_rule(p)) // _loop0_55 + (seq = _loop0_54_rule(p)) // _loop0_54 ) { - D(fprintf(stderr, "%*c+ _gather_54[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c+ _gather_53[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_54[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c%s _gather_53[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_54")); } _res = NULL; done: @@ -28622,13 +28258,12 @@ _gather_54_rule(Parser *p) return _res; } -// _loop0_57: ',' with_item +// _loop0_56: ',' with_item static asdl_seq * -_loop0_57_rule(Parser *p) +_loop0_56_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28650,7 +28285,7 @@ _loop0_57_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -28682,7 +28317,7 @@ _loop0_57_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_57[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_56[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28699,13 +28334,12 @@ _loop0_57_rule(Parser *p) return _seq; } -// _gather_56: with_item _loop0_57 +// _gather_55: with_item _loop0_56 static asdl_seq * -_gather_56_rule(Parser *p) +_gather_55_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28713,27 +28347,27 @@ _gather_56_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_57 + { // with_item _loop0_56 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c> _gather_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_57_rule(p)) // _loop0_57 + (seq = _loop0_56_rule(p)) // _loop0_56 ) { - D(fprintf(stderr, "%*c+ _gather_56[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c+ _gather_55[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_56[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c%s _gather_55[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_56")); } _res = NULL; done: @@ -28741,13 +28375,12 @@ _gather_56_rule(Parser *p) return _res; } -// _loop0_59: ',' with_item +// _loop0_58: ',' with_item static asdl_seq * -_loop0_59_rule(Parser *p) +_loop0_58_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28769,7 +28402,7 @@ _loop0_59_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -28801,7 +28434,7 @@ _loop0_59_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_59[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_58[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28818,13 +28451,12 @@ _loop0_59_rule(Parser *p) return _seq; } -// _gather_58: with_item _loop0_59 +// _gather_57: with_item _loop0_58 static asdl_seq * -_gather_58_rule(Parser *p) +_gather_57_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28832,27 +28464,27 @@ _gather_58_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_59 + { // with_item _loop0_58 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_59")); + D(fprintf(stderr, "%*c> _gather_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_59_rule(p)) // _loop0_59 + (seq = _loop0_58_rule(p)) // _loop0_58 ) { - D(fprintf(stderr, "%*c+ _gather_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_59")); + D(fprintf(stderr, "%*c+ _gather_57[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_58[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_59")); + D(fprintf(stderr, "%*c%s _gather_57[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_58")); } _res = NULL; done: @@ -28860,13 +28492,12 @@ _gather_58_rule(Parser *p) return _res; } -// _tmp_60: ',' | ')' | ':' +// _tmp_59: ',' | ')' | ':' static void * -_tmp_60_rule(Parser *p) +_tmp_59_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28879,18 +28510,18 @@ _tmp_60_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_60[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_60[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -28898,18 +28529,18 @@ _tmp_60_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_60[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_60[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -28917,18 +28548,18 @@ _tmp_60_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_60[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_60[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -28937,13 +28568,12 @@ _tmp_60_rule(Parser *p) return _res; } -// _loop1_61: except_block +// _loop1_60: except_block static asdl_seq * -_loop1_61_rule(Parser *p) +_loop1_60_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28965,7 +28595,7 @@ _loop1_61_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); excepthandler_ty except_block_var; while ( (except_block_var = except_block_rule(p)) // except_block @@ -28988,7 +28618,7 @@ _loop1_61_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_61[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_60[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -29010,13 +28640,12 @@ _loop1_61_rule(Parser *p) return _seq; } -// _loop1_62: except_star_block +// _loop1_61: except_star_block static asdl_seq * -_loop1_62_rule(Parser *p) +_loop1_61_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29038,7 +28667,7 @@ _loop1_62_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); excepthandler_ty except_star_block_var; while ( (except_star_block_var = except_star_block_rule(p)) // except_star_block @@ -29061,7 +28690,7 @@ _loop1_62_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_62[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_61[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -29083,13 +28712,12 @@ _loop1_62_rule(Parser *p) return _seq; } -// _tmp_63: 'as' NAME +// _tmp_62: 'as' NAME static void * -_tmp_63_rule(Parser *p) +_tmp_62_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29102,16 +28730,16 @@ _tmp_63_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_63[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_62[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -29121,7 +28749,7 @@ _tmp_63_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_63[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_62[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -29130,13 +28758,12 @@ _tmp_63_rule(Parser *p) return _res; } -// _tmp_64: 'as' NAME +// _tmp_63: 'as' NAME static void * -_tmp_64_rule(Parser *p) +_tmp_63_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29149,16 +28776,16 @@ _tmp_64_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_64[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_63[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -29168,7 +28795,7 @@ _tmp_64_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_64[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_63[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -29177,13 +28804,12 @@ _tmp_64_rule(Parser *p) return _res; } -// _loop1_65: case_block +// _loop1_64: case_block static asdl_seq * -_loop1_65_rule(Parser *p) +_loop1_64_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29205,7 +28831,7 @@ _loop1_65_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); + D(fprintf(stderr, "%*c> _loop1_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); match_case_ty case_block_var; while ( (case_block_var = case_block_rule(p)) // case_block @@ -29228,7 +28854,7 @@ _loop1_65_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_65[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_64[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "case_block")); } if (_n == 0 || p->error_indicator) { @@ -29250,13 +28876,12 @@ _loop1_65_rule(Parser *p) return _seq; } -// _loop0_67: '|' closed_pattern +// _loop0_66: '|' closed_pattern static asdl_seq * -_loop0_67_rule(Parser *p) +_loop0_66_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29278,7 +28903,7 @@ _loop0_67_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); + D(fprintf(stderr, "%*c> _loop0_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); Token * _literal; pattern_ty elem; while ( @@ -29310,7 +28935,7 @@ _loop0_67_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_66[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'|' closed_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29327,13 +28952,12 @@ _loop0_67_rule(Parser *p) return _seq; } -// _gather_66: closed_pattern _loop0_67 +// _gather_65: closed_pattern _loop0_66 static asdl_seq * -_gather_66_rule(Parser *p) +_gather_65_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29341,27 +28965,27 @@ _gather_66_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // closed_pattern _loop0_67 + { // closed_pattern _loop0_66 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_67")); + D(fprintf(stderr, "%*c> _gather_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); pattern_ty elem; asdl_seq * seq; if ( (elem = closed_pattern_rule(p)) // closed_pattern && - (seq = _loop0_67_rule(p)) // _loop0_67 + (seq = _loop0_66_rule(p)) // _loop0_66 ) { - D(fprintf(stderr, "%*c+ _gather_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_67")); + D(fprintf(stderr, "%*c+ _gather_65[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_66[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_67")); + D(fprintf(stderr, "%*c%s _gather_65[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_66")); } _res = NULL; done: @@ -29369,13 +28993,12 @@ _gather_66_rule(Parser *p) return _res; } -// _tmp_68: '+' | '-' +// _tmp_67: '+' | '-' static void * -_tmp_68_rule(Parser *p) +_tmp_67_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29388,18 +29011,18 @@ _tmp_68_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -29407,18 +29030,18 @@ _tmp_68_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } _res = NULL; @@ -29427,13 +29050,12 @@ _tmp_68_rule(Parser *p) return _res; } -// _tmp_69: '+' | '-' +// _tmp_68: '+' | '-' static void * -_tmp_69_rule(Parser *p) +_tmp_68_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29446,18 +29068,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -29465,18 +29087,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } _res = NULL; @@ -29485,13 +29107,12 @@ _tmp_69_rule(Parser *p) return _res; } -// _tmp_70: '.' | '(' | '=' +// _tmp_69: '.' | '(' | '=' static void * -_tmp_70_rule(Parser *p) +_tmp_69_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29504,18 +29125,18 @@ _tmp_70_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '(' @@ -29523,18 +29144,18 @@ _tmp_70_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '=' @@ -29542,18 +29163,18 @@ _tmp_70_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } _res = NULL; @@ -29562,13 +29183,12 @@ _tmp_70_rule(Parser *p) return _res; } -// _tmp_71: '.' | '(' | '=' +// _tmp_70: '.' | '(' | '=' static void * -_tmp_71_rule(Parser *p) +_tmp_70_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29581,18 +29201,18 @@ _tmp_71_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_71[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '(' @@ -29600,18 +29220,18 @@ _tmp_71_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_71[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '=' @@ -29619,18 +29239,18 @@ _tmp_71_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_71[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } _res = NULL; @@ -29639,13 +29259,12 @@ _tmp_71_rule(Parser *p) return _res; } -// _loop0_73: ',' maybe_star_pattern +// _loop0_72: ',' maybe_star_pattern static asdl_seq * -_loop0_73_rule(Parser *p) +_loop0_72_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29667,7 +29286,7 @@ _loop0_73_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); + D(fprintf(stderr, "%*c> _loop0_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); Token * _literal; pattern_ty elem; while ( @@ -29699,7 +29318,7 @@ _loop0_73_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_73[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_72[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' maybe_star_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29716,13 +29335,12 @@ _loop0_73_rule(Parser *p) return _seq; } -// _gather_72: maybe_star_pattern _loop0_73 +// _gather_71: maybe_star_pattern _loop0_72 static asdl_seq * -_gather_72_rule(Parser *p) +_gather_71_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29730,27 +29348,27 @@ _gather_72_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // maybe_star_pattern _loop0_73 + { // maybe_star_pattern _loop0_72 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_73")); + D(fprintf(stderr, "%*c> _gather_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); pattern_ty elem; asdl_seq * seq; if ( (elem = maybe_star_pattern_rule(p)) // maybe_star_pattern && - (seq = _loop0_73_rule(p)) // _loop0_73 + (seq = _loop0_72_rule(p)) // _loop0_72 ) { - D(fprintf(stderr, "%*c+ _gather_72[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_73")); + D(fprintf(stderr, "%*c+ _gather_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_72[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_73")); + D(fprintf(stderr, "%*c%s _gather_71[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_72")); } _res = NULL; done: @@ -29758,13 +29376,12 @@ _gather_72_rule(Parser *p) return _res; } -// _loop0_75: ',' key_value_pattern +// _loop0_74: ',' key_value_pattern static asdl_seq * -_loop0_75_rule(Parser *p) +_loop0_74_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29786,7 +29403,7 @@ _loop0_75_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); + D(fprintf(stderr, "%*c> _loop0_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -29818,7 +29435,7 @@ _loop0_75_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_75[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_74[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' key_value_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29835,13 +29452,12 @@ _loop0_75_rule(Parser *p) return _seq; } -// _gather_74: key_value_pattern _loop0_75 +// _gather_73: key_value_pattern _loop0_74 static asdl_seq * -_gather_74_rule(Parser *p) +_gather_73_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29849,27 +29465,27 @@ _gather_74_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // key_value_pattern _loop0_75 + { // key_value_pattern _loop0_74 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_75")); + D(fprintf(stderr, "%*c> _gather_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); KeyPatternPair* elem; asdl_seq * seq; if ( (elem = key_value_pattern_rule(p)) // key_value_pattern && - (seq = _loop0_75_rule(p)) // _loop0_75 + (seq = _loop0_74_rule(p)) // _loop0_74 ) { - D(fprintf(stderr, "%*c+ _gather_74[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_75")); + D(fprintf(stderr, "%*c+ _gather_73[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_74[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_75")); + D(fprintf(stderr, "%*c%s _gather_73[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_74")); } _res = NULL; done: @@ -29877,13 +29493,12 @@ _gather_74_rule(Parser *p) return _res; } -// _tmp_76: literal_expr | attr +// _tmp_75: literal_expr | attr static void * -_tmp_76_rule(Parser *p) +_tmp_75_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29896,18 +29511,18 @@ _tmp_76_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); + D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); expr_ty literal_expr_var; if ( (literal_expr_var = literal_expr_rule(p)) // literal_expr ) { - D(fprintf(stderr, "%*c+ _tmp_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); + D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); _res = literal_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_76[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "literal_expr")); } { // attr @@ -29915,18 +29530,18 @@ _tmp_76_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); + D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); expr_ty attr_var; if ( (attr_var = attr_rule(p)) // attr ) { - D(fprintf(stderr, "%*c+ _tmp_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); + D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); _res = attr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_76[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr")); } _res = NULL; @@ -29935,13 +29550,12 @@ _tmp_76_rule(Parser *p) return _res; } -// _loop0_78: ',' pattern +// _loop0_77: ',' pattern static asdl_seq * -_loop0_78_rule(Parser *p) +_loop0_77_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29963,7 +29577,7 @@ _loop0_78_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); + D(fprintf(stderr, "%*c> _loop0_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); Token * _literal; pattern_ty elem; while ( @@ -29995,7 +29609,7 @@ _loop0_78_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_78[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_77[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30012,13 +29626,12 @@ _loop0_78_rule(Parser *p) return _seq; } -// _gather_77: pattern _loop0_78 +// _gather_76: pattern _loop0_77 static asdl_seq * -_gather_77_rule(Parser *p) +_gather_76_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30026,27 +29639,27 @@ _gather_77_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // pattern _loop0_78 + { // pattern _loop0_77 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78")); + D(fprintf(stderr, "%*c> _gather_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); pattern_ty elem; asdl_seq * seq; if ( (elem = pattern_rule(p)) // pattern && - (seq = _loop0_78_rule(p)) // _loop0_78 + (seq = _loop0_77_rule(p)) // _loop0_77 ) { - D(fprintf(stderr, "%*c+ _gather_77[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78")); + D(fprintf(stderr, "%*c+ _gather_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_77[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_78")); + D(fprintf(stderr, "%*c%s _gather_76[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_77")); } _res = NULL; done: @@ -30054,13 +29667,12 @@ _gather_77_rule(Parser *p) return _res; } -// _loop0_80: ',' keyword_pattern +// _loop0_79: ',' keyword_pattern static asdl_seq * -_loop0_80_rule(Parser *p) +_loop0_79_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30082,7 +29694,7 @@ _loop0_80_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); + D(fprintf(stderr, "%*c> _loop0_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -30114,7 +29726,7 @@ _loop0_80_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_80[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_79[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' keyword_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30131,13 +29743,12 @@ _loop0_80_rule(Parser *p) return _seq; } -// _gather_79: keyword_pattern _loop0_80 +// _gather_78: keyword_pattern _loop0_79 static asdl_seq * -_gather_79_rule(Parser *p) +_gather_78_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30145,27 +29756,27 @@ _gather_79_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // keyword_pattern _loop0_80 + { // keyword_pattern _loop0_79 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80")); + D(fprintf(stderr, "%*c> _gather_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); KeyPatternPair* elem; asdl_seq * seq; if ( (elem = keyword_pattern_rule(p)) // keyword_pattern && - (seq = _loop0_80_rule(p)) // _loop0_80 + (seq = _loop0_79_rule(p)) // _loop0_79 ) { - D(fprintf(stderr, "%*c+ _gather_79[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80")); + D(fprintf(stderr, "%*c+ _gather_78[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_79[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_80")); + D(fprintf(stderr, "%*c%s _gather_78[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_79")); } _res = NULL; done: @@ -30173,13 +29784,12 @@ _gather_79_rule(Parser *p) return _res; } -// _loop0_82: ',' type_param +// _loop0_81: ',' type_param static asdl_seq * -_loop0_82_rule(Parser *p) +_loop0_81_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30201,7 +29811,7 @@ _loop0_82_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' type_param")); + D(fprintf(stderr, "%*c> _loop0_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' type_param")); Token * _literal; type_param_ty elem; while ( @@ -30233,7 +29843,7 @@ _loop0_82_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_82[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_81[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' type_param")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30250,13 +29860,12 @@ _loop0_82_rule(Parser *p) return _seq; } -// _gather_81: type_param _loop0_82 +// _gather_80: type_param _loop0_81 static asdl_seq * -_gather_81_rule(Parser *p) +_gather_80_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30264,27 +29873,27 @@ _gather_81_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // type_param _loop0_82 + { // type_param _loop0_81 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "type_param _loop0_82")); + D(fprintf(stderr, "%*c> _gather_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "type_param _loop0_81")); type_param_ty elem; asdl_seq * seq; if ( (elem = type_param_rule(p)) // type_param && - (seq = _loop0_82_rule(p)) // _loop0_82 + (seq = _loop0_81_rule(p)) // _loop0_81 ) { - D(fprintf(stderr, "%*c+ _gather_81[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "type_param _loop0_82")); + D(fprintf(stderr, "%*c+ _gather_80[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "type_param _loop0_81")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_81[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "type_param _loop0_82")); + D(fprintf(stderr, "%*c%s _gather_80[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "type_param _loop0_81")); } _res = NULL; done: @@ -30292,13 +29901,12 @@ _gather_81_rule(Parser *p) return _res; } -// _loop1_83: (',' expression) +// _loop1_82: (',' expression) static asdl_seq * -_loop1_83_rule(Parser *p) +_loop1_82_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30320,7 +29928,7 @@ _loop1_83_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); + D(fprintf(stderr, "%*c> _loop1_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); void *_tmp_252_var; while ( (_tmp_252_var = _tmp_252_rule(p)) // ',' expression @@ -30343,7 +29951,7 @@ _loop1_83_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_83[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_82[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' expression)")); } if (_n == 0 || p->error_indicator) { @@ -30365,13 +29973,12 @@ _loop1_83_rule(Parser *p) return _seq; } -// _loop1_84: (',' star_expression) +// _loop1_83: (',' star_expression) static asdl_seq * -_loop1_84_rule(Parser *p) +_loop1_83_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30393,7 +30000,7 @@ _loop1_84_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); + D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); void *_tmp_253_var; while ( (_tmp_253_var = _tmp_253_rule(p)) // ',' star_expression @@ -30416,7 +30023,7 @@ _loop1_84_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_84[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_83[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)")); } if (_n == 0 || p->error_indicator) { @@ -30438,13 +30045,12 @@ _loop1_84_rule(Parser *p) return _seq; } -// _loop0_86: ',' star_named_expression +// _loop0_85: ',' star_named_expression static asdl_seq * -_loop0_86_rule(Parser *p) +_loop0_85_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30466,7 +30072,7 @@ _loop0_86_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); + D(fprintf(stderr, "%*c> _loop0_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); Token * _literal; expr_ty elem; while ( @@ -30498,7 +30104,7 @@ _loop0_86_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_86[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_85[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30515,13 +30121,12 @@ _loop0_86_rule(Parser *p) return _seq; } -// _gather_85: star_named_expression _loop0_86 +// _gather_84: star_named_expression _loop0_85 static asdl_seq * -_gather_85_rule(Parser *p) +_gather_84_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30529,27 +30134,27 @@ _gather_85_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // star_named_expression _loop0_86 + { // star_named_expression _loop0_85 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_86")); + D(fprintf(stderr, "%*c> _gather_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_85")); expr_ty elem; asdl_seq * seq; if ( (elem = star_named_expression_rule(p)) // star_named_expression && - (seq = _loop0_86_rule(p)) // _loop0_86 + (seq = _loop0_85_rule(p)) // _loop0_85 ) { - D(fprintf(stderr, "%*c+ _gather_85[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_86")); + D(fprintf(stderr, "%*c+ _gather_84[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_85")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_85[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_86")); + D(fprintf(stderr, "%*c%s _gather_84[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_85")); } _res = NULL; done: @@ -30557,13 +30162,12 @@ _gather_85_rule(Parser *p) return _res; } -// _loop1_87: ('or' conjunction) +// _loop1_86: ('or' conjunction) static asdl_seq * -_loop1_87_rule(Parser *p) +_loop1_86_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30585,7 +30189,7 @@ _loop1_87_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); + D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); void *_tmp_254_var; while ( (_tmp_254_var = _tmp_254_rule(p)) // 'or' conjunction @@ -30608,7 +30212,7 @@ _loop1_87_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_87[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_86[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)")); } if (_n == 0 || p->error_indicator) { @@ -30630,13 +30234,12 @@ _loop1_87_rule(Parser *p) return _seq; } -// _loop1_88: ('and' inversion) +// _loop1_87: ('and' inversion) static asdl_seq * -_loop1_88_rule(Parser *p) +_loop1_87_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30658,7 +30261,7 @@ _loop1_88_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); + D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); void *_tmp_255_var; while ( (_tmp_255_var = _tmp_255_rule(p)) // 'and' inversion @@ -30681,7 +30284,7 @@ _loop1_88_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_88[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_87[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)")); } if (_n == 0 || p->error_indicator) { @@ -30703,13 +30306,12 @@ _loop1_88_rule(Parser *p) return _seq; } -// _loop1_89: compare_op_bitwise_or_pair +// _loop1_88: compare_op_bitwise_or_pair static asdl_seq * -_loop1_89_rule(Parser *p) +_loop1_88_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30731,7 +30333,7 @@ _loop1_89_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); + D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); CmpopExprPair* compare_op_bitwise_or_pair_var; while ( (compare_op_bitwise_or_pair_var = compare_op_bitwise_or_pair_rule(p)) // compare_op_bitwise_or_pair @@ -30754,7 +30356,7 @@ _loop1_89_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_89[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_88[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compare_op_bitwise_or_pair")); } if (_n == 0 || p->error_indicator) { @@ -30776,13 +30378,12 @@ _loop1_89_rule(Parser *p) return _seq; } -// _tmp_90: '!=' +// _tmp_89: '!=' static void * -_tmp_90_rule(Parser *p) +_tmp_89_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30795,13 +30396,13 @@ _tmp_90_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c> _tmp_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); Token * tok; if ( (tok = _PyPegen_expect_token(p, 28)) // token='!=' ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c+ _tmp_89[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); _res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -30811,7 +30412,7 @@ _tmp_90_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_89[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!='")); } _res = NULL; @@ -30820,13 +30421,12 @@ _tmp_90_rule(Parser *p) return _res; } -// _loop0_92: ',' (slice | starred_expression) +// _loop0_91: ',' (slice | starred_expression) static asdl_seq * -_loop0_92_rule(Parser *p) +_loop0_91_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30848,7 +30448,7 @@ _loop0_92_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)")); + D(fprintf(stderr, "%*c> _loop0_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)")); Token * _literal; void *elem; while ( @@ -30880,7 +30480,7 @@ _loop0_92_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_91[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (slice | starred_expression)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30897,13 +30497,12 @@ _loop0_92_rule(Parser *p) return _seq; } -// _gather_91: (slice | starred_expression) _loop0_92 +// _gather_90: (slice | starred_expression) _loop0_91 static asdl_seq * -_gather_91_rule(Parser *p) +_gather_90_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30911,27 +30510,27 @@ _gather_91_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (slice | starred_expression) _loop0_92 + { // (slice | starred_expression) _loop0_91 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_92")); + D(fprintf(stderr, "%*c> _gather_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_91")); void *elem; asdl_seq * seq; if ( (elem = _tmp_256_rule(p)) // slice | starred_expression && - (seq = _loop0_92_rule(p)) // _loop0_92 + (seq = _loop0_91_rule(p)) // _loop0_91 ) { - D(fprintf(stderr, "%*c+ _gather_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_92")); + D(fprintf(stderr, "%*c+ _gather_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_91")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_91[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_92")); + D(fprintf(stderr, "%*c%s _gather_90[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_91")); } _res = NULL; done: @@ -30939,13 +30538,12 @@ _gather_91_rule(Parser *p) return _res; } -// _tmp_93: ':' expression? +// _tmp_92: ':' expression? static void * -_tmp_93_rule(Parser *p) +_tmp_92_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30958,7 +30556,7 @@ _tmp_93_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); Token * _literal; void *d; if ( @@ -30967,7 +30565,7 @@ _tmp_93_rule(Parser *p) (d = expression_rule(p), !p->error_indicator) // expression? ) { - D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -30977,7 +30575,7 @@ _tmp_93_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression?")); } _res = NULL; @@ -30986,13 +30584,12 @@ _tmp_93_rule(Parser *p) return _res; } -// _tmp_94: STRING | FSTRING_START +// _tmp_93: STRING | FSTRING_START static void * -_tmp_94_rule(Parser *p) +_tmp_93_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31005,18 +30602,18 @@ _tmp_94_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); expr_ty string_var; if ( (string_var = _PyPegen_string_token(p)) // STRING ) { - D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING")); _res = string_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); } { // FSTRING_START @@ -31024,18 +30621,18 @@ _tmp_94_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START")); Token * fstring_start_var; if ( (fstring_start_var = _PyPegen_expect_token(p, FSTRING_START)) // token='FSTRING_START' ) { - D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START")); _res = fstring_start_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_START")); } _res = NULL; @@ -31044,13 +30641,12 @@ _tmp_94_rule(Parser *p) return _res; } -// _tmp_95: tuple | group | genexp +// _tmp_94: tuple | group | genexp static void * -_tmp_95_rule(Parser *p) +_tmp_94_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31063,18 +30659,18 @@ _tmp_95_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); expr_ty tuple_var; if ( (tuple_var = tuple_rule(p)) // tuple ) { - D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); _res = tuple_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); } { // group @@ -31082,18 +30678,18 @@ _tmp_95_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); expr_ty group_var; if ( (group_var = group_rule(p)) // group ) { - D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); _res = group_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group")); } { // genexp @@ -31101,18 +30697,18 @@ _tmp_95_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); expr_ty genexp_var; if ( (genexp_var = genexp_rule(p)) // genexp ) { - D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); _res = genexp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); } _res = NULL; @@ -31121,13 +30717,12 @@ _tmp_95_rule(Parser *p) return _res; } -// _tmp_96: list | listcomp +// _tmp_95: list | listcomp static void * -_tmp_96_rule(Parser *p) +_tmp_95_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31140,18 +30735,18 @@ _tmp_96_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); expr_ty list_var; if ( (list_var = list_rule(p)) // list ) { - D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); _res = list_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); } { // listcomp @@ -31159,18 +30754,18 @@ _tmp_96_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); expr_ty listcomp_var; if ( (listcomp_var = listcomp_rule(p)) // listcomp ) { - D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); _res = listcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "listcomp")); } _res = NULL; @@ -31179,13 +30774,12 @@ _tmp_96_rule(Parser *p) return _res; } -// _tmp_97: dict | set | dictcomp | setcomp +// _tmp_96: dict | set | dictcomp | setcomp static void * -_tmp_97_rule(Parser *p) +_tmp_96_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31198,18 +30792,18 @@ _tmp_97_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); expr_ty dict_var; if ( (dict_var = dict_rule(p)) // dict ) { - D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); _res = dict_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dict")); } { // set @@ -31217,18 +30811,18 @@ _tmp_97_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); expr_ty set_var; if ( (set_var = set_rule(p)) // set ) { - D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); _res = set_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "set")); } { // dictcomp @@ -31236,18 +30830,18 @@ _tmp_97_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); expr_ty dictcomp_var; if ( (dictcomp_var = dictcomp_rule(p)) // dictcomp ) { - D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); _res = dictcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dictcomp")); } { // setcomp @@ -31255,18 +30849,18 @@ _tmp_97_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); expr_ty setcomp_var; if ( (setcomp_var = setcomp_rule(p)) // setcomp ) { - D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); _res = setcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "setcomp")); } _res = NULL; @@ -31275,13 +30869,12 @@ _tmp_97_rule(Parser *p) return _res; } -// _tmp_98: yield_expr | named_expression +// _tmp_97: yield_expr | named_expression static void * -_tmp_98_rule(Parser *p) +_tmp_97_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31294,18 +30887,18 @@ _tmp_98_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_98[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_98[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // named_expression @@ -31313,18 +30906,18 @@ _tmp_98_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); expr_ty named_expression_var; if ( (named_expression_var = named_expression_rule(p)) // named_expression ) { - D(fprintf(stderr, "%*c+ _tmp_98[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); _res = named_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_98[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); } _res = NULL; @@ -31333,13 +30926,12 @@ _tmp_98_rule(Parser *p) return _res; } -// _loop0_99: lambda_param_no_default +// _loop0_98: lambda_param_no_default static asdl_seq * -_loop0_99_rule(Parser *p) +_loop0_98_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31361,7 +30953,7 @@ _loop0_99_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -31384,7 +30976,7 @@ _loop0_99_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_98[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31401,13 +30993,12 @@ _loop0_99_rule(Parser *p) return _seq; } -// _loop0_100: lambda_param_with_default +// _loop0_99: lambda_param_with_default static asdl_seq * -_loop0_100_rule(Parser *p) +_loop0_99_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31429,7 +31020,7 @@ _loop0_100_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -31452,7 +31043,7 @@ _loop0_100_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_100[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31469,13 +31060,12 @@ _loop0_100_rule(Parser *p) return _seq; } -// _loop0_101: lambda_param_with_default +// _loop0_100: lambda_param_with_default static asdl_seq * -_loop0_101_rule(Parser *p) +_loop0_100_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31497,7 +31087,7 @@ _loop0_101_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -31520,7 +31110,7 @@ _loop0_101_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_101[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_100[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31537,13 +31127,12 @@ _loop0_101_rule(Parser *p) return _seq; } -// _loop1_102: lambda_param_no_default +// _loop1_101: lambda_param_no_default static asdl_seq * -_loop1_102_rule(Parser *p) +_loop1_101_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31565,7 +31154,7 @@ _loop1_102_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -31588,7 +31177,7 @@ _loop1_102_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_102[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_101[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -31610,13 +31199,12 @@ _loop1_102_rule(Parser *p) return _seq; } -// _loop0_103: lambda_param_with_default +// _loop0_102: lambda_param_with_default static asdl_seq * -_loop0_103_rule(Parser *p) +_loop0_102_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31638,7 +31226,7 @@ _loop0_103_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -31661,7 +31249,7 @@ _loop0_103_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_103[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_102[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31678,13 +31266,12 @@ _loop0_103_rule(Parser *p) return _seq; } -// _loop1_104: lambda_param_with_default +// _loop1_103: lambda_param_with_default static asdl_seq * -_loop1_104_rule(Parser *p) +_loop1_103_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31706,7 +31293,7 @@ _loop1_104_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -31729,7 +31316,7 @@ _loop1_104_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_103[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -31751,13 +31338,12 @@ _loop1_104_rule(Parser *p) return _seq; } -// _loop1_105: lambda_param_no_default +// _loop1_104: lambda_param_no_default static asdl_seq * -_loop1_105_rule(Parser *p) +_loop1_104_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31779,7 +31365,7 @@ _loop1_105_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -31802,7 +31388,7 @@ _loop1_105_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_105[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -31824,13 +31410,12 @@ _loop1_105_rule(Parser *p) return _seq; } -// _loop1_106: lambda_param_no_default +// _loop1_105: lambda_param_no_default static asdl_seq * -_loop1_106_rule(Parser *p) +_loop1_105_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31852,7 +31437,7 @@ _loop1_106_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -31875,7 +31460,7 @@ _loop1_106_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_105[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -31897,13 +31482,12 @@ _loop1_106_rule(Parser *p) return _seq; } -// _loop0_107: lambda_param_no_default +// _loop0_106: lambda_param_no_default static asdl_seq * -_loop0_107_rule(Parser *p) +_loop0_106_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31925,7 +31509,7 @@ _loop0_107_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -31948,7 +31532,7 @@ _loop0_107_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_106[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31965,13 +31549,12 @@ _loop0_107_rule(Parser *p) return _seq; } -// _loop1_108: lambda_param_with_default +// _loop1_107: lambda_param_with_default static asdl_seq * -_loop1_108_rule(Parser *p) +_loop1_107_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31993,7 +31576,7 @@ _loop1_108_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -32016,7 +31599,7 @@ _loop1_108_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_107[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -32038,13 +31621,12 @@ _loop1_108_rule(Parser *p) return _seq; } -// _loop0_109: lambda_param_no_default +// _loop0_108: lambda_param_no_default static asdl_seq * -_loop0_109_rule(Parser *p) +_loop0_108_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32066,7 +31648,7 @@ _loop0_109_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -32089,7 +31671,7 @@ _loop0_109_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_109[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_108[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32106,13 +31688,12 @@ _loop0_109_rule(Parser *p) return _seq; } -// _loop1_110: lambda_param_with_default +// _loop1_109: lambda_param_with_default static asdl_seq * -_loop1_110_rule(Parser *p) +_loop1_109_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32134,7 +31715,7 @@ _loop1_110_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -32157,7 +31738,7 @@ _loop1_110_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_110[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_109[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -32179,13 +31760,12 @@ _loop1_110_rule(Parser *p) return _seq; } -// _loop0_111: lambda_param_maybe_default +// _loop0_110: lambda_param_maybe_default static asdl_seq * -_loop0_111_rule(Parser *p) +_loop0_110_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32207,7 +31787,7 @@ _loop0_111_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -32230,7 +31810,7 @@ _loop0_111_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_111[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_110[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32247,13 +31827,12 @@ _loop0_111_rule(Parser *p) return _seq; } -// _loop1_112: lambda_param_maybe_default +// _loop1_111: lambda_param_maybe_default static asdl_seq * -_loop1_112_rule(Parser *p) +_loop1_111_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32275,7 +31854,7 @@ _loop1_112_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -32298,7 +31877,7 @@ _loop1_112_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_112[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_111[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -32320,13 +31899,12 @@ _loop1_112_rule(Parser *p) return _seq; } -// _tmp_113: yield_expr | star_expressions +// _tmp_112: yield_expr | star_expressions static void * -_tmp_113_rule(Parser *p) +_tmp_112_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32339,18 +31917,18 @@ _tmp_113_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_112[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_112[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -32358,18 +31936,18 @@ _tmp_113_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_112[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_112[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -32378,13 +31956,12 @@ _tmp_113_rule(Parser *p) return _res; } -// _loop0_114: fstring_format_spec +// _loop0_113: fstring_format_spec static asdl_seq * -_loop0_114_rule(Parser *p) +_loop0_113_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32406,7 +31983,7 @@ _loop0_114_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); + D(fprintf(stderr, "%*c> _loop0_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); expr_ty fstring_format_spec_var; while ( (fstring_format_spec_var = fstring_format_spec_rule(p)) // fstring_format_spec @@ -32429,7 +32006,7 @@ _loop0_114_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_113[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_format_spec")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32446,13 +32023,79 @@ _loop0_114_rule(Parser *p) return _seq; } -// _loop1_115: (fstring | string) +// _loop0_114: fstring_middle static asdl_seq * -_loop1_115_rule(Parser *p) +_loop0_114_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // fstring_middle + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_middle")); + expr_ty fstring_middle_var; + while ( + (fstring_middle_var = fstring_middle_rule(p)) // fstring_middle + ) + { + _res = fstring_middle_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_middle")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop1_115: (fstring | string) +static asdl_seq * +_loop1_115_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32524,8 +32167,7 @@ static void * _tmp_116_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32574,8 +32216,7 @@ static asdl_seq * _loop0_118_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32651,8 +32292,7 @@ static asdl_seq * _gather_117_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32693,8 +32333,7 @@ static asdl_seq * _loop1_119_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32766,8 +32405,7 @@ static asdl_seq * _loop0_120_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32834,8 +32472,7 @@ static asdl_seq * _loop0_121_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32902,8 +32539,7 @@ static void * _tmp_122_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32962,8 +32598,7 @@ static asdl_seq * _loop0_124_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33040,8 +32675,7 @@ static asdl_seq * _gather_123_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33082,8 +32716,7 @@ static void * _tmp_125_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33129,8 +32762,7 @@ static asdl_seq * _loop0_127_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33206,8 +32838,7 @@ static asdl_seq * _gather_126_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33248,8 +32879,7 @@ static asdl_seq * _loop0_129_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33325,8 +32955,7 @@ static asdl_seq * _gather_128_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33367,8 +32996,7 @@ static asdl_seq * _loop0_131_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33444,8 +33072,7 @@ static asdl_seq * _gather_130_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33486,8 +33113,7 @@ static asdl_seq * _loop0_133_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33563,8 +33189,7 @@ static asdl_seq * _gather_132_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33605,8 +33230,7 @@ static asdl_seq * _loop0_134_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33673,8 +33297,7 @@ static asdl_seq * _loop0_136_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33750,8 +33373,7 @@ static asdl_seq * _gather_135_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33792,8 +33414,7 @@ static asdl_seq * _loop1_137_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33865,8 +33486,7 @@ static void * _tmp_138_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33906,8 +33526,7 @@ static asdl_seq * _loop0_140_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33983,8 +33602,7 @@ static asdl_seq * _gather_139_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34025,8 +33643,7 @@ static asdl_seq * _loop0_142_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34102,8 +33719,7 @@ static asdl_seq * _gather_141_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34144,8 +33760,7 @@ static asdl_seq * _loop0_144_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34221,8 +33836,7 @@ static asdl_seq * _gather_143_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34263,8 +33877,7 @@ static asdl_seq * _loop0_146_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34340,8 +33953,7 @@ static asdl_seq * _gather_145_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34382,8 +33994,7 @@ static asdl_seq * _loop0_148_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34459,8 +34070,7 @@ static asdl_seq * _gather_147_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34501,8 +34111,7 @@ static void * _tmp_149_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34538,13 +34147,71 @@ _tmp_149_rule(Parser *p) return _res; } -// _tmp_150: args | expression for_if_clauses +// _tmp_150: +// | (','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) +// | kwargs static void * _tmp_150_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // (','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs)")); + void *_tmp_263_var; + if ( + (_tmp_263_var = _tmp_263_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs + ) + { + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs)")); + _res = _tmp_263_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs)")); + } + { // kwargs + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwargs")); + asdl_seq* kwargs_var; + if ( + (kwargs_var = kwargs_rule(p)) // kwargs + ) + { + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwargs")); + _res = kwargs_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwargs")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_151: args | expression for_if_clauses +static void * +_tmp_151_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34557,18 +34224,18 @@ _tmp_150_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); expr_ty args_var; if ( (args_var = args_rule(p)) // args ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); _res = args_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); } { // expression for_if_clauses @@ -34576,7 +34243,7 @@ _tmp_150_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); expr_ty expression_var; asdl_comprehension_seq* for_if_clauses_var; if ( @@ -34585,12 +34252,12 @@ _tmp_150_rule(Parser *p) (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); } _res = NULL; @@ -34599,13 +34266,12 @@ _tmp_150_rule(Parser *p) return _res; } -// _tmp_151: args ',' +// _tmp_152: args ',' static void * -_tmp_151_rule(Parser *p) +_tmp_152_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34618,7 +34284,7 @@ _tmp_151_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','")); + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','")); Token * _literal; expr_ty args_var; if ( @@ -34627,12 +34293,12 @@ _tmp_151_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','")); + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','")); _res = _PyPegen_dummy_name(p, args_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ','")); } _res = NULL; @@ -34641,13 +34307,12 @@ _tmp_151_rule(Parser *p) return _res; } -// _tmp_152: ',' | ')' +// _tmp_153: ',' | ')' static void * -_tmp_152_rule(Parser *p) +_tmp_153_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34660,18 +34325,18 @@ _tmp_152_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -34679,18 +34344,18 @@ _tmp_152_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } _res = NULL; @@ -34699,13 +34364,12 @@ _tmp_152_rule(Parser *p) return _res; } -// _tmp_153: 'True' | 'False' | 'None' +// _tmp_154: 'True' | 'False' | 'None' static void * -_tmp_153_rule(Parser *p) +_tmp_154_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34718,18 +34382,18 @@ _tmp_153_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='True' + (_keyword = _PyPegen_expect_token(p, 610)) // token='True' ) { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } { // 'False' @@ -34737,18 +34401,18 @@ _tmp_153_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 603)) // token='False' + (_keyword = _PyPegen_expect_token(p, 612)) // token='False' ) { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } { // 'None' @@ -34756,18 +34420,18 @@ _tmp_153_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='None' + (_keyword = _PyPegen_expect_token(p, 611)) // token='None' ) { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } _res = NULL; @@ -34776,13 +34440,12 @@ _tmp_153_rule(Parser *p) return _res; } -// _tmp_154: NAME '=' +// _tmp_155: NAME '=' static void * -_tmp_154_rule(Parser *p) +_tmp_155_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34795,7 +34458,7 @@ _tmp_154_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); Token * _literal; expr_ty name_var; if ( @@ -34804,12 +34467,12 @@ _tmp_154_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); _res = _PyPegen_dummy_name(p, name_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); } _res = NULL; @@ -34818,13 +34481,12 @@ _tmp_154_rule(Parser *p) return _res; } -// _tmp_155: NAME STRING | SOFT_KEYWORD +// _tmp_156: NAME STRING | SOFT_KEYWORD static void * -_tmp_155_rule(Parser *p) +_tmp_156_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34837,7 +34499,7 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); expr_ty name_var; expr_ty string_var; if ( @@ -34846,12 +34508,12 @@ _tmp_155_rule(Parser *p) (string_var = _PyPegen_string_token(p)) // STRING ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); _res = _PyPegen_dummy_name(p, name_var, string_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); } { // SOFT_KEYWORD @@ -34859,18 +34521,18 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); expr_ty soft_keyword_var; if ( (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); _res = soft_keyword_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); } _res = NULL; @@ -34879,13 +34541,12 @@ _tmp_155_rule(Parser *p) return _res; } -// _tmp_156: 'else' | ':' +// _tmp_157: 'else' | ':' static void * -_tmp_156_rule(Parser *p) +_tmp_157_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34898,18 +34559,18 @@ _tmp_156_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 645)) // token='else' + (_keyword = _PyPegen_expect_token(p, 659)) // token='else' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); } { // ':' @@ -34917,77 +34578,19 @@ _tmp_156_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_157: FSTRING_MIDDLE | fstring_replacement_field -static void * -_tmp_157_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // FSTRING_MIDDLE - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); - Token * fstring_middle_var; - if ( - (fstring_middle_var = _PyPegen_expect_token(p, FSTRING_MIDDLE)) // token='FSTRING_MIDDLE' - ) - { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); - _res = fstring_middle_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_MIDDLE")); - } - { // fstring_replacement_field - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); - expr_ty fstring_replacement_field_var; - if ( - (fstring_replacement_field_var = fstring_replacement_field_rule(p)) // fstring_replacement_field - ) - { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); - _res = fstring_replacement_field_var; - goto done; - } - p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_replacement_field")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; done: @@ -35000,8 +34603,7 @@ static void * _tmp_158_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35058,8 +34660,7 @@ static void * _tmp_159_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35132,7 +34733,7 @@ _tmp_159_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='True' + (_keyword = _PyPegen_expect_token(p, 610)) // token='True' ) { D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -35151,7 +34752,7 @@ _tmp_159_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='None' + (_keyword = _PyPegen_expect_token(p, 611)) // token='None' ) { D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); @@ -35170,7 +34771,7 @@ _tmp_159_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 603)) // token='False' + (_keyword = _PyPegen_expect_token(p, 612)) // token='False' ) { D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -35192,8 +34793,7 @@ static void * _tmp_160_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35250,8 +34850,7 @@ static asdl_seq * _loop0_161_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35318,8 +34917,7 @@ static asdl_seq * _loop0_162_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35342,12 +34940,12 @@ _loop0_162_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_263_var; + void *_tmp_264_var; while ( - (_tmp_263_var = _tmp_263_rule(p)) // star_targets '=' + (_tmp_264_var = _tmp_264_rule(p)) // star_targets '=' ) { - _res = _tmp_263_var; + _res = _tmp_264_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35386,8 +34984,7 @@ static asdl_seq * _loop0_163_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35410,12 +35007,12 @@ _loop0_163_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_264_var; + void *_tmp_265_var; while ( - (_tmp_264_var = _tmp_264_rule(p)) // star_targets '=' + (_tmp_265_var = _tmp_265_rule(p)) // star_targets '=' ) { - _res = _tmp_264_var; + _res = _tmp_265_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35454,8 +35051,7 @@ static void * _tmp_164_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35512,8 +35108,7 @@ static void * _tmp_165_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35589,8 +35184,7 @@ static void * _tmp_166_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35647,8 +35241,7 @@ static void * _tmp_167_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35705,8 +35298,7 @@ static void * _tmp_168_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35763,8 +35355,7 @@ static asdl_seq * _loop0_169_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35831,8 +35422,7 @@ static asdl_seq * _loop0_170_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35899,8 +35489,7 @@ static asdl_seq * _loop0_171_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35967,8 +35556,7 @@ static asdl_seq * _loop1_172_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36040,8 +35628,7 @@ static void * _tmp_173_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36098,8 +35685,7 @@ static asdl_seq * _loop0_174_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36166,8 +35752,7 @@ static void * _tmp_175_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36224,8 +35809,7 @@ static asdl_seq * _loop0_176_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36292,8 +35876,7 @@ static asdl_seq * _loop1_177_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36365,8 +35948,7 @@ static void * _tmp_178_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36423,8 +36005,7 @@ static void * _tmp_179_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36458,15 +36039,15 @@ _tmp_179_rule(Parser *p) } D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_265_var; + void *_tmp_266_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_265_var = _tmp_265_rule(p)) // ')' | '**' + (_tmp_266_var = _tmp_266_rule(p)) // ')' | '**' ) { D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_265_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_266_var); goto done; } p->mark = _mark; @@ -36484,8 +36065,7 @@ static void * _tmp_180_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36542,8 +36122,7 @@ static asdl_seq * _loop0_181_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36610,8 +36189,7 @@ static void * _tmp_182_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36668,8 +36246,7 @@ static void * _tmp_183_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36745,8 +36322,7 @@ static asdl_seq * _loop1_184_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36818,8 +36394,7 @@ static void * _tmp_185_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36876,8 +36451,7 @@ static asdl_seq * _loop0_186_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36944,8 +36518,7 @@ static asdl_seq * _loop0_187_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37012,8 +36585,7 @@ static asdl_seq * _loop0_188_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37080,8 +36652,7 @@ static asdl_seq * _loop0_190_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37157,8 +36728,7 @@ static asdl_seq * _gather_189_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37199,8 +36769,7 @@ static void * _tmp_191_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37257,8 +36826,7 @@ static asdl_seq * _loop0_192_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37325,8 +36893,7 @@ static void * _tmp_193_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37383,8 +36950,7 @@ static asdl_seq * _loop0_194_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37451,8 +37017,7 @@ static asdl_seq * _loop1_195_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37524,8 +37089,7 @@ static asdl_seq * _loop1_196_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37597,8 +37161,7 @@ static void * _tmp_197_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37632,15 +37195,15 @@ _tmp_197_rule(Parser *p) } D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_266_var; + void *_tmp_267_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_266_var = _tmp_266_rule(p)) // ':' | '**' + (_tmp_267_var = _tmp_267_rule(p)) // ':' | '**' ) { D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_266_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_267_var); goto done; } p->mark = _mark; @@ -37658,8 +37221,7 @@ static void * _tmp_198_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37716,8 +37278,7 @@ static asdl_seq * _loop0_199_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37784,8 +37345,7 @@ static void * _tmp_200_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37842,8 +37402,7 @@ static void * _tmp_201_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37919,8 +37478,7 @@ static void * _tmp_202_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37996,8 +37554,7 @@ static asdl_seq * _loop0_204_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38073,8 +37630,7 @@ static asdl_seq * _gather_203_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38115,8 +37671,7 @@ static asdl_seq * _loop0_206_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38144,7 +37699,7 @@ _loop0_206_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_267_rule(p)) // expression ['as' star_target] + (elem = _tmp_268_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -38192,8 +37747,7 @@ static asdl_seq * _gather_205_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38210,7 +37764,7 @@ _gather_205_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_267_rule(p)) // expression ['as' star_target] + (elem = _tmp_268_rule(p)) // expression ['as' star_target] && (seq = _loop0_206_rule(p)) // _loop0_206 ) @@ -38234,8 +37788,7 @@ static asdl_seq * _loop0_208_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38263,7 +37816,7 @@ _loop0_208_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_268_rule(p)) // expressions ['as' star_target] + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -38311,8 +37864,7 @@ static asdl_seq * _gather_207_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38329,7 +37881,7 @@ _gather_207_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_268_rule(p)) // expressions ['as' star_target] + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] && (seq = _loop0_208_rule(p)) // _loop0_208 ) @@ -38353,8 +37905,7 @@ static asdl_seq * _loop0_210_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38382,7 +37933,7 @@ _loop0_210_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_269_rule(p)) // expression ['as' star_target] + (elem = _tmp_270_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -38430,8 +37981,7 @@ static asdl_seq * _gather_209_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38448,7 +37998,7 @@ _gather_209_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_269_rule(p)) // expression ['as' star_target] + (elem = _tmp_270_rule(p)) // expression ['as' star_target] && (seq = _loop0_210_rule(p)) // _loop0_210 ) @@ -38472,8 +38022,7 @@ static asdl_seq * _loop0_212_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38501,7 +38050,7 @@ _loop0_212_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_270_rule(p)) // expressions ['as' star_target] + (elem = _tmp_271_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -38549,8 +38098,7 @@ static asdl_seq * _gather_211_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38567,7 +38115,7 @@ _gather_211_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_270_rule(p)) // expressions ['as' star_target] + (elem = _tmp_271_rule(p)) // expressions ['as' star_target] && (seq = _loop0_212_rule(p)) // _loop0_212 ) @@ -38591,8 +38139,7 @@ static void * _tmp_213_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38608,7 +38155,7 @@ _tmp_213_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='except' + (_keyword = _PyPegen_expect_token(p, 651)) // token='except' ) { D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); @@ -38627,7 +38174,7 @@ _tmp_213_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 633)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 647)) // token='finally' ) { D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); @@ -38649,8 +38196,7 @@ static asdl_seq * _loop0_214_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38717,8 +38263,7 @@ static asdl_seq * _loop1_215_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38790,8 +38335,7 @@ static void * _tmp_216_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38808,7 +38352,7 @@ _tmp_216_rule(Parser *p) Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) @@ -38832,8 +38376,7 @@ static asdl_seq * _loop0_217_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38900,8 +38443,7 @@ static asdl_seq * _loop1_218_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38973,8 +38515,7 @@ static void * _tmp_219_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38994,7 +38535,7 @@ _tmp_219_rule(Parser *p) if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_271_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_272_rule(p), !p->error_indicator) // ['as' NAME] ) { D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); @@ -39016,8 +38557,7 @@ static void * _tmp_220_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39034,7 +38574,7 @@ _tmp_220_rule(Parser *p) Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) @@ -39058,8 +38598,7 @@ static void * _tmp_221_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39076,7 +38615,7 @@ _tmp_221_rule(Parser *p) Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) @@ -39100,8 +38639,7 @@ static void * _tmp_222_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39158,8 +38696,7 @@ static void * _tmp_223_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39176,7 +38713,7 @@ _tmp_223_rule(Parser *p) Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) @@ -39200,8 +38737,7 @@ static void * _tmp_224_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39218,7 +38754,7 @@ _tmp_224_rule(Parser *p) Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) @@ -39242,8 +38778,7 @@ static void * _tmp_225_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39284,8 +38819,7 @@ static void * _tmp_226_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39326,8 +38860,7 @@ static void * _tmp_227_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39372,8 +38905,7 @@ static void * _tmp_228_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39418,8 +38950,7 @@ static asdl_seq * _loop0_230_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39495,8 +39026,7 @@ static asdl_seq * _gather_229_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39537,8 +39067,7 @@ static void * _tmp_231_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39595,8 +39124,7 @@ static void * _tmp_232_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39653,8 +39181,7 @@ static void * _tmp_233_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39711,8 +39238,7 @@ static void * _tmp_234_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39769,8 +39295,7 @@ static void * _tmp_235_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39865,8 +39390,7 @@ static void * _tmp_236_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -39923,8 +39447,7 @@ static void * _tmp_237_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40000,8 +39523,7 @@ static void * _tmp_238_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40058,8 +39580,7 @@ static void * _tmp_239_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40116,8 +39637,7 @@ static void * _tmp_240_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40158,8 +39678,7 @@ static void * _tmp_241_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40216,8 +39735,7 @@ static void * _tmp_242_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40274,8 +39792,7 @@ static void * _tmp_243_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40316,8 +39833,7 @@ static asdl_seq * _loop0_244_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40384,8 +39900,7 @@ static void * _tmp_245_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40442,8 +39957,7 @@ static void * _tmp_246_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40484,8 +39998,7 @@ static void * _tmp_247_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40542,8 +40055,7 @@ static void * _tmp_248_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40589,8 +40101,7 @@ static void * _tmp_249_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40647,8 +40158,7 @@ static void * _tmp_250_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40705,8 +40215,7 @@ static void * _tmp_251_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40755,8 +40264,7 @@ static void * _tmp_252_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40802,8 +40310,7 @@ static void * _tmp_253_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40849,8 +40356,7 @@ static void * _tmp_254_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40867,7 +40373,7 @@ _tmp_254_rule(Parser *p) Token * _keyword; expr_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 574)) // token='or' + (_keyword = _PyPegen_expect_token(p, 581)) // token='or' && (c = conjunction_rule(p)) // conjunction ) @@ -40896,8 +40402,7 @@ static void * _tmp_255_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -40914,7 +40419,7 @@ _tmp_255_rule(Parser *p) Token * _keyword; expr_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 575)) // token='and' + (_keyword = _PyPegen_expect_token(p, 582)) // token='and' && (c = inversion_rule(p)) // inversion ) @@ -40943,8 +40448,7 @@ static void * _tmp_256_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41001,8 +40505,7 @@ static void * _tmp_257_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41059,8 +40562,7 @@ static void * _tmp_258_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41077,7 +40579,7 @@ _tmp_258_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (z = disjunction_rule(p)) // disjunction ) @@ -41106,8 +40608,7 @@ static void * _tmp_259_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41124,7 +40625,7 @@ _tmp_259_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='if' + (_keyword = _PyPegen_expect_token(p, 656)) // token='if' && (z = disjunction_rule(p)) // disjunction ) @@ -41153,8 +40654,7 @@ static void * _tmp_260_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41187,15 +40687,15 @@ _tmp_260_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_272_var; + void *_tmp_273_var; if ( - (_tmp_272_var = _tmp_272_rule(p)) // assignment_expression | expression !':=' + (_tmp_273_var = _tmp_273_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_272_var; + _res = _tmp_273_var; goto done; } p->mark = _mark; @@ -41213,8 +40713,7 @@ static void * _tmp_261_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41260,8 +40759,7 @@ static void * _tmp_262_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41302,13 +40800,13 @@ _tmp_262_rule(Parser *p) return _res; } -// _tmp_263: star_targets '=' +// _tmp_263: +// | ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs static void * _tmp_263_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41316,27 +40814,30 @@ _tmp_263_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // star_targets '=' + { // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); + asdl_seq * _gather_274_var; Token * _literal; - expr_ty star_targets_var; + asdl_seq* kwargs_var; if ( - (star_targets_var = star_targets_rule(p)) // star_targets + (_gather_274_var = _gather_274_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (kwargs_var = kwargs_rule(p)) // kwargs ) { - D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); - _res = _PyPegen_dummy_name(p, star_targets_var, _literal); + D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); + _res = _PyPegen_dummy_name(p, _gather_274_var, _literal, kwargs_var); goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_263[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); } _res = NULL; done: @@ -41349,8 +40850,7 @@ static void * _tmp_264_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41386,13 +40886,53 @@ _tmp_264_rule(Parser *p) return _res; } -// _tmp_265: ')' | '**' +// _tmp_265: star_targets '=' static void * _tmp_265_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // star_targets '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty star_targets_var; + if ( + (star_targets_var = star_targets_rule(p)) // star_targets + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + _res = _PyPegen_dummy_name(p, star_targets_var, _literal); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_266: ')' | '**' +static void * +_tmp_266_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41405,18 +40945,18 @@ _tmp_265_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -41424,18 +40964,18 @@ _tmp_265_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -41444,13 +40984,12 @@ _tmp_265_rule(Parser *p) return _res; } -// _tmp_266: ':' | '**' +// _tmp_267: ':' | '**' static void * -_tmp_266_rule(Parser *p) +_tmp_267_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41463,18 +41002,18 @@ _tmp_266_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -41482,18 +41021,18 @@ _tmp_266_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -41502,13 +41041,12 @@ _tmp_266_rule(Parser *p) return _res; } -// _tmp_267: expression ['as' star_target] +// _tmp_268: expression ['as' star_target] static void * -_tmp_267_rule(Parser *p) +_tmp_268_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41521,22 +41059,22 @@ _tmp_267_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_273_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_276_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -41545,13 +41083,12 @@ _tmp_267_rule(Parser *p) return _res; } -// _tmp_268: expressions ['as' star_target] +// _tmp_269: expressions ['as' star_target] static void * -_tmp_268_rule(Parser *p) +_tmp_269_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41564,22 +41101,22 @@ _tmp_268_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_274_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_277_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -41588,13 +41125,12 @@ _tmp_268_rule(Parser *p) return _res; } -// _tmp_269: expression ['as' star_target] +// _tmp_270: expression ['as' star_target] static void * -_tmp_269_rule(Parser *p) +_tmp_270_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41607,22 +41143,22 @@ _tmp_269_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_275_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_278_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -41631,13 +41167,12 @@ _tmp_269_rule(Parser *p) return _res; } -// _tmp_270: expressions ['as' star_target] +// _tmp_271: expressions ['as' star_target] static void * -_tmp_270_rule(Parser *p) +_tmp_271_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41650,22 +41185,22 @@ _tmp_270_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_276_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_279_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -41674,13 +41209,12 @@ _tmp_270_rule(Parser *p) return _res; } -// _tmp_271: 'as' NAME +// _tmp_272: 'as' NAME static void * -_tmp_271_rule(Parser *p) +_tmp_272_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41693,21 +41227,21 @@ _tmp_271_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -41716,13 +41250,12 @@ _tmp_271_rule(Parser *p) return _res; } -// _tmp_272: assignment_expression | expression !':=' +// _tmp_273: assignment_expression | expression !':=' static void * -_tmp_272_rule(Parser *p) +_tmp_273_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41735,18 +41268,18 @@ _tmp_272_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -41754,7 +41287,7 @@ _tmp_272_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -41762,12 +41295,12 @@ _tmp_272_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -41776,13 +41309,130 @@ _tmp_272_rule(Parser *p) return _res; } -// _tmp_273: 'as' star_target -static void * -_tmp_273_rule(Parser *p) +// _loop0_275: ',' (starred_expression | (assignment_expression | expression !':=') !'=') +static asdl_seq * +_loop0_275_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' (starred_expression | (assignment_expression | expression !':=') !'=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_275[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + Token * _literal; + void *elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _tmp_280_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + ) + { + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_275[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _gather_274: +// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_275 +static asdl_seq * +_gather_274_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_275 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_275")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_280_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + && + (seq = _loop0_275_rule(p)) // _loop0_275 + ) + { + D(fprintf(stderr, "%*c+ _gather_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_275")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_274[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_275")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_276: 'as' star_target +static void * +_tmp_276_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41795,21 +41445,21 @@ _tmp_273_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_276[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_276[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_276[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -41818,13 +41468,12 @@ _tmp_273_rule(Parser *p) return _res; } -// _tmp_274: 'as' star_target +// _tmp_277: 'as' star_target static void * -_tmp_274_rule(Parser *p) +_tmp_277_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41837,21 +41486,21 @@ _tmp_274_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_277[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_277[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_274[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_277[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -41860,13 +41509,12 @@ _tmp_274_rule(Parser *p) return _res; } -// _tmp_275: 'as' star_target +// _tmp_278: 'as' star_target static void * -_tmp_275_rule(Parser *p) +_tmp_278_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41879,21 +41527,21 @@ _tmp_275_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_275[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_278[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_275[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_278[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_275[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_278[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -41902,13 +41550,12 @@ _tmp_275_rule(Parser *p) return _res; } -// _tmp_276: 'as' star_target +// _tmp_279: 'as' star_target static void * -_tmp_276_rule(Parser *p) +_tmp_279_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -41921,21 +41568,21 @@ _tmp_276_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_276[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_279[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + (_keyword = _PyPegen_expect_token(p, 654)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_276[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_279[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_276[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_279[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -41944,6 +41591,124 @@ _tmp_276_rule(Parser *p) return _res; } +// _tmp_280: starred_expression | (assignment_expression | expression !':=') !'=' +static void * +_tmp_280_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // starred_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_280[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_280[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_280[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + { // (assignment_expression | expression !':=') !'=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_280[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_281_var; + if ( + (_tmp_281_var = _tmp_281_rule(p)) // assignment_expression | expression !':=' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_280[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_281_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_280[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_281: assignment_expression | expression !':=' +static void * +_tmp_281_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // assignment_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_281[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + expr_ty assignment_expression_var; + if ( + (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_281[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + _res = assignment_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_281[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); + } + { // expression !':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_281[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_281[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + _res = expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_281[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + void * _PyPegen_parse(Parser *p) { @@ -41962,8 +41727,6 @@ _PyPegen_parse(Parser *p) result = eval_rule(p); } else if (p->start_rule == Py_func_type_input) { result = func_type_rule(p); - } else if (p->start_rule == Py_fstring_input) { - result = fstring_rule(p); } return result; diff --git a/Parser/peg_api.c b/Parser/peg_api.c index 1487ac4ff856c2..d4acc3e4935d10 100644 --- a/Parser/peg_api.c +++ b/Parser/peg_api.c @@ -1,6 +1,5 @@ #include "Python.h" -#include "tokenizer.h" #include "pegen.h" mod_ty @@ -24,5 +23,18 @@ _PyParser_ASTFromFile(FILE *fp, PyObject *filename_ob, const char *enc, return NULL; } return _PyPegen_run_parser_from_file_pointer(fp, mode, filename_ob, enc, ps1, ps2, - flags, errcode, arena); + flags, errcode, NULL, arena); } + +mod_ty +_PyParser_InteractiveASTFromFile(FILE *fp, PyObject *filename_ob, const char *enc, + int mode, const char *ps1, const char* ps2, + PyCompilerFlags *flags, int *errcode, + PyObject **interactive_src, PyArena *arena) +{ + if (PySys_Audit("compile", "OO", Py_None, filename_ob) < 0) { + return NULL; + } + return _PyPegen_run_parser_from_file_pointer(fp, mode, filename_ob, enc, ps1, ps2, + flags, errcode, interactive_src, arena); +} \ No newline at end of file diff --git a/Parser/pegen.c b/Parser/pegen.c index 885d423fca66a9..0c60394e4f199b 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -3,7 +3,8 @@ #include "pycore_pystate.h" // _PyThreadState_GET() #include -#include "tokenizer.h" +#include "lexer/lexer.h" +#include "tokenizer/tokenizer.h" #include "pegen.h" // Internal parser functions @@ -734,9 +735,6 @@ compute_parser_flags(PyCompilerFlags *flags) if (flags->cf_flags & PyCF_TYPE_COMMENTS) { parser_flags |= PyPARSE_TYPE_COMMENTS; } - if ((flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7) { - parser_flags |= PyPARSE_ASYNC_HACKS; - } if (flags->cf_flags & PyCF_ALLOW_INCOMPLETE_INPUT) { parser_flags |= PyPARSE_ALLOW_INCOMPLETE_INPUT; } @@ -755,7 +753,6 @@ _PyPegen_Parser_New(struct tok_state *tok, int start_rule, int flags, } assert(tok != NULL); tok->type_comments = (flags & PyPARSE_TYPE_COMMENTS) > 0; - tok->async_hacks = (flags & PyPARSE_ASYNC_HACKS) > 0; p->tok = tok; p->keywords = NULL; p->n_keyword_lists = -1; @@ -881,7 +878,8 @@ _PyPegen_run_parser(Parser *p) mod_ty _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filename_ob, const char *enc, const char *ps1, const char *ps2, - PyCompilerFlags *flags, int *errcode, PyArena *arena) + PyCompilerFlags *flags, int *errcode, + PyObject **interactive_src, PyArena *arena) { struct tok_state *tok = _PyTokenizer_FromFile(fp, enc, ps1, ps2); if (tok == NULL) { @@ -911,6 +909,15 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filena result = _PyPegen_run_parser(p); _PyPegen_Parser_Free(p); + if (tok->fp_interactive && tok->interactive_src_start && result && interactive_src != NULL) { + *interactive_src = PyUnicode_FromString(tok->interactive_src_start); + if (!interactive_src || _PyArena_AddPyObject(arena, *interactive_src) < 0) { + Py_XDECREF(interactive_src); + result = NULL; + goto error; + } + } + error: _PyTokenizer_Free(tok); return result; diff --git a/Parser/pegen.h b/Parser/pegen.h index 5f29285951e812..424f80acd7be3b 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -20,7 +20,6 @@ #define PyPARSE_IGNORE_COOKIE 0x0010 #define PyPARSE_BARRY_AS_BDFL 0x0020 #define PyPARSE_TYPE_COMMENTS 0x0040 -#define PyPARSE_ASYNC_HACKS 0x0080 #define PyPARSE_ALLOW_INCOMPLETE_INPUT 0x0100 #define CURRENT_POS (-5) @@ -167,6 +166,8 @@ void *_PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, Py_ssize_t end_lineno, Py_ssize_t end_col_offset, const char *errmsg, va_list va); void _Pypegen_set_syntax_error(Parser* p, Token* last_token); +void _Pypegen_stack_overflow(Parser *p); + Py_LOCAL_INLINE(void *) RAISE_ERROR_KNOWN_LOCATION(Parser *p, PyObject *errtype, Py_ssize_t lineno, Py_ssize_t col_offset, @@ -349,7 +350,8 @@ void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehensi Parser *_PyPegen_Parser_New(struct tok_state *, int, int, int, int *, PyArena *); void _PyPegen_Parser_Free(Parser *); mod_ty _PyPegen_run_parser_from_file_pointer(FILE *, int, PyObject *, const char *, - const char *, const char *, PyCompilerFlags *, int *, PyArena *); + const char *, const char *, PyCompilerFlags *, int *, PyObject **, + PyArena *); void *_PyPegen_run_parser(Parser *); mod_ty _PyPegen_run_parser_from_string(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); asdl_stmt_seq *_PyPegen_interactive_exit(Parser *); diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index e543d40ccd8ab7..15e99e23d8490f 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -2,7 +2,8 @@ #include #include "pycore_pyerrors.h" // _PyErr_ProgramDecodedTextObject() -#include "tokenizer.h" +#include "lexer/state.h" +#include "lexer/lexer.h" #include "pegen.h" // TOKENIZER ERRORS @@ -234,6 +235,12 @@ _PyPegen_raise_error(Parser *p, PyObject *errtype, int use_mark, const char *err col_offset = 0; } else { const char* start = p->tok->buf ? p->tok->line_start : p->tok->buf; + if (p->tok->cur - start > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "Parser column offset overflow - source line is too big"); + p->error_indicator = 1; + return NULL; + } col_offset = Py_SAFE_DOWNCAST(p->tok->cur - start, intptr_t, int); } } else { @@ -310,21 +317,6 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, end_col_offset = p->tok->cur - p->tok->line_start; } - if (p->start_rule == Py_fstring_input) { - const char *fstring_msg = "f-string: "; - Py_ssize_t len = strlen(fstring_msg) + strlen(errmsg); - - char *new_errmsg = PyMem_Malloc(len + 1); // Lengths of both strings plus NULL character - if (!new_errmsg) { - return (void *) PyErr_NoMemory(); - } - - // Copy both strings into new buffer - memcpy(new_errmsg, fstring_msg, strlen(fstring_msg)); - memcpy(new_errmsg + strlen(fstring_msg), errmsg, strlen(errmsg)); - new_errmsg[len] = 0; - errmsg = new_errmsg; - } errstr = PyUnicode_FromFormatV(errmsg, va); if (!errstr) { goto error; @@ -363,11 +355,6 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, } } - if (p->start_rule == Py_fstring_input) { - col_offset -= p->starting_col_offset; - end_col_offset -= p->starting_col_offset; - } - Py_ssize_t col_number = col_offset; Py_ssize_t end_col_number = end_col_offset; @@ -398,17 +385,11 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, Py_DECREF(errstr); Py_DECREF(value); - if (p->start_rule == Py_fstring_input) { - PyMem_Free((void *)errmsg); - } return NULL; error: Py_XDECREF(errstr); Py_XDECREF(error_line); - if (p->start_rule == Py_fstring_input) { - PyMem_Free((void *)errmsg); - } return NULL; } @@ -454,3 +435,11 @@ _Pypegen_set_syntax_error(Parser* p, Token* last_token) { // generic SyntaxError we just raised if errors are found. _PyPegen_tokenize_full_source_to_check_for_errors(p); } + +void +_Pypegen_stack_overflow(Parser *p) +{ + p->error_indicator = 1; + PyErr_SetString(PyExc_MemoryError, + "Parser stack overflowed - Python source too complex to parse"); +} diff --git a/Parser/string_parser.c b/Parser/string_parser.c index bc1f99d607ae4d..f1e027765c86b9 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -1,9 +1,10 @@ #include #include +#include "pycore_bytesobject.h" // _PyBytes_DecodeEscape() #include "pycore_unicodeobject.h" // _PyUnicode_DecodeUnicodeEscapeInternal() -#include "tokenizer.h" +#include "lexer/state.h" #include "pegen.h" #include "string_parser.h" @@ -13,8 +14,9 @@ static int warn_invalid_escape_sequence(Parser *p, const char *first_invalid_escape, Token *t) { unsigned char c = *first_invalid_escape; - if ((t->type == FSTRING_MIDDLE || t->type == FSTRING_END) && (c == '{' || c == '}')) { // in this case the tokenizer has already emitted a warning, - // see tokenizer.c:warn_invalid_escape_sequence + if ((t->type == FSTRING_MIDDLE || t->type == FSTRING_END) && (c == '{' || c == '}')) { + // in this case the tokenizer has already emitted a warning, + // see Parser/tokenizer/helpers.c:warn_invalid_escape_sequence return 0; } diff --git a/Parser/token.c b/Parser/token.c index 2bc963a91c7701..4f163f21609a0a 100644 --- a/Parser/token.c +++ b/Parser/token.c @@ -62,8 +62,6 @@ const char * const _PyParser_TokenNames[] = { "COLONEQUAL", "EXCLAMATION", "OP", - "AWAIT", - "ASYNC", "TYPE_IGNORE", "TYPE_COMMENT", "SOFT_KEYWORD", diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c deleted file mode 100644 index f19198600fa018..00000000000000 --- a/Parser/tokenizer.c +++ /dev/null @@ -1,3018 +0,0 @@ - -/* Tokenizer implementation */ - -#include "Python.h" -#include "pycore_call.h" // _PyObject_CallNoArgs() - -#include -#include - -#include "tokenizer.h" -#include "errcode.h" - -/* Alternate tab spacing */ -#define ALTTABSIZE 1 - -#define is_potential_identifier_start(c) (\ - (c >= 'a' && c <= 'z')\ - || (c >= 'A' && c <= 'Z')\ - || c == '_'\ - || (c >= 128)) - -#define is_potential_identifier_char(c) (\ - (c >= 'a' && c <= 'z')\ - || (c >= 'A' && c <= 'Z')\ - || (c >= '0' && c <= '9')\ - || c == '_'\ - || (c >= 128)) - - -/* Don't ever change this -- it would break the portability of Python code */ -#define TABSIZE 8 - -#define MAKE_TOKEN(token_type) token_setup(tok, token, token_type, p_start, p_end) -#define MAKE_TYPE_COMMENT_TOKEN(token_type, col_offset, end_col_offset) (\ - type_comment_token_setup(tok, token, token_type, col_offset, end_col_offset, p_start, p_end)) -#define ADVANCE_LINENO() \ - tok->lineno++; \ - tok->col_offset = 0; - -#define INSIDE_FSTRING(tok) (tok->tok_mode_stack_index > 0) -#define INSIDE_FSTRING_EXPR(tok) (tok->curly_bracket_expr_start_depth >= 0) -#ifdef Py_DEBUG -static inline tokenizer_mode* TOK_GET_MODE(struct tok_state* tok) { - assert(tok->tok_mode_stack_index >= 0); - assert(tok->tok_mode_stack_index < MAXFSTRINGLEVEL); - return &(tok->tok_mode_stack[tok->tok_mode_stack_index]); -} -static inline tokenizer_mode* TOK_NEXT_MODE(struct tok_state* tok) { - assert(tok->tok_mode_stack_index >= 0); - assert(tok->tok_mode_stack_index + 1 < MAXFSTRINGLEVEL); - return &(tok->tok_mode_stack[++tok->tok_mode_stack_index]); -} -#else -#define TOK_GET_MODE(tok) (&(tok->tok_mode_stack[tok->tok_mode_stack_index])) -#define TOK_NEXT_MODE(tok) (&(tok->tok_mode_stack[++tok->tok_mode_stack_index])) -#endif - -/* Forward */ -static struct tok_state *tok_new(void); -static int tok_nextc(struct tok_state *tok); -static void tok_backup(struct tok_state *tok, int c); -static int syntaxerror(struct tok_state *tok, const char *format, ...); - -/* Spaces in this constant are treated as "zero or more spaces or tabs" when - tokenizing. */ -static const char* type_comment_prefix = "# type: "; - -/* Create and initialize a new tok_state structure */ - -static struct tok_state * -tok_new(void) -{ - struct tok_state *tok = (struct tok_state *)PyMem_Malloc( - sizeof(struct tok_state)); - if (tok == NULL) - return NULL; - tok->buf = tok->cur = tok->inp = NULL; - tok->fp_interactive = 0; - tok->interactive_src_start = NULL; - tok->interactive_src_end = NULL; - tok->start = NULL; - tok->end = NULL; - tok->done = E_OK; - tok->fp = NULL; - tok->input = NULL; - tok->tabsize = TABSIZE; - tok->indent = 0; - tok->indstack[0] = 0; - tok->atbol = 1; - tok->pendin = 0; - tok->prompt = tok->nextprompt = NULL; - tok->lineno = 0; - tok->starting_col_offset = -1; - tok->col_offset = -1; - tok->level = 0; - tok->altindstack[0] = 0; - tok->decoding_state = STATE_INIT; - tok->decoding_erred = 0; - tok->enc = NULL; - tok->encoding = NULL; - tok->cont_line = 0; - tok->filename = NULL; - tok->decoding_readline = NULL; - tok->decoding_buffer = NULL; - tok->readline = NULL; - tok->type_comments = 0; - tok->async_hacks = 0; - tok->async_def = 0; - tok->async_def_indent = 0; - tok->async_def_nl = 0; - tok->interactive_underflow = IUNDERFLOW_NORMAL; - tok->str = NULL; - tok->report_warnings = 1; - tok->tok_extra_tokens = 0; - tok->comment_newline = 0; - tok->implicit_newline = 0; - tok->tok_mode_stack[0] = (tokenizer_mode){.kind =TOK_REGULAR_MODE, .f_string_quote='\0', .f_string_quote_size = 0, .f_string_debug=0}; - tok->tok_mode_stack_index = 0; - tok->tok_report_warnings = 1; -#ifdef Py_DEBUG - tok->debug = _Py_GetConfig()->parser_debug; -#endif - return tok; -} - -static char * -new_string(const char *s, Py_ssize_t len, struct tok_state *tok) -{ - char* result = (char *)PyMem_Malloc(len + 1); - if (!result) { - tok->done = E_NOMEM; - return NULL; - } - memcpy(result, s, len); - result[len] = '\0'; - return result; -} - -static char * -error_ret(struct tok_state *tok) /* XXX */ -{ - tok->decoding_erred = 1; - if ((tok->fp != NULL || tok->readline != NULL) && tok->buf != NULL) {/* see _PyTokenizer_Free */ - PyMem_Free(tok->buf); - } - tok->buf = tok->cur = tok->inp = NULL; - tok->start = NULL; - tok->end = NULL; - tok->done = E_DECODE; - return NULL; /* as if it were EOF */ -} - - -static const char * -get_normal_name(const char *s) /* for utf-8 and latin-1 */ -{ - char buf[13]; - int i; - for (i = 0; i < 12; i++) { - int c = s[i]; - if (c == '\0') - break; - else if (c == '_') - buf[i] = '-'; - else - buf[i] = tolower(c); - } - buf[i] = '\0'; - if (strcmp(buf, "utf-8") == 0 || - strncmp(buf, "utf-8-", 6) == 0) - return "utf-8"; - else if (strcmp(buf, "latin-1") == 0 || - strcmp(buf, "iso-8859-1") == 0 || - strcmp(buf, "iso-latin-1") == 0 || - strncmp(buf, "latin-1-", 8) == 0 || - strncmp(buf, "iso-8859-1-", 11) == 0 || - strncmp(buf, "iso-latin-1-", 12) == 0) - return "iso-8859-1"; - else - return s; -} - -/* Return the coding spec in S, or NULL if none is found. */ - -static int -get_coding_spec(const char *s, char **spec, Py_ssize_t size, struct tok_state *tok) -{ - Py_ssize_t i; - *spec = NULL; - /* Coding spec must be in a comment, and that comment must be - * the only statement on the source code line. */ - for (i = 0; i < size - 6; i++) { - if (s[i] == '#') - break; - if (s[i] != ' ' && s[i] != '\t' && s[i] != '\014') - return 1; - } - for (; i < size - 6; i++) { /* XXX inefficient search */ - const char* t = s + i; - if (memcmp(t, "coding", 6) == 0) { - const char* begin = NULL; - t += 6; - if (t[0] != ':' && t[0] != '=') - continue; - do { - t++; - } while (t[0] == ' ' || t[0] == '\t'); - - begin = t; - while (Py_ISALNUM(t[0]) || - t[0] == '-' || t[0] == '_' || t[0] == '.') - t++; - - if (begin < t) { - char* r = new_string(begin, t - begin, tok); - const char* q; - if (!r) - return 0; - q = get_normal_name(r); - if (r != q) { - PyMem_Free(r); - r = new_string(q, strlen(q), tok); - if (!r) - return 0; - } - *spec = r; - break; - } - } - } - return 1; -} - -/* Check whether the line contains a coding spec. If it does, - invoke the set_readline function for the new encoding. - This function receives the tok_state and the new encoding. - Return 1 on success, 0 on failure. */ - -static int -check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, - int set_readline(struct tok_state *, const char *)) -{ - char *cs; - if (tok->cont_line) { - /* It's a continuation line, so it can't be a coding spec. */ - tok->decoding_state = STATE_NORMAL; - return 1; - } - if (!get_coding_spec(line, &cs, size, tok)) { - return 0; - } - if (!cs) { - Py_ssize_t i; - for (i = 0; i < size; i++) { - if (line[i] == '#' || line[i] == '\n' || line[i] == '\r') - break; - if (line[i] != ' ' && line[i] != '\t' && line[i] != '\014') { - /* Stop checking coding spec after a line containing - * anything except a comment. */ - tok->decoding_state = STATE_NORMAL; - break; - } - } - return 1; - } - tok->decoding_state = STATE_NORMAL; - if (tok->encoding == NULL) { - assert(tok->decoding_readline == NULL); - if (strcmp(cs, "utf-8") != 0 && !set_readline(tok, cs)) { - error_ret(tok); - PyErr_Format(PyExc_SyntaxError, "encoding problem: %s", cs); - PyMem_Free(cs); - return 0; - } - tok->encoding = cs; - } else { /* then, compare cs with BOM */ - if (strcmp(tok->encoding, cs) != 0) { - error_ret(tok); - PyErr_Format(PyExc_SyntaxError, - "encoding problem: %s with BOM", cs); - PyMem_Free(cs); - return 0; - } - PyMem_Free(cs); - } - return 1; -} - -/* See whether the file starts with a BOM. If it does, - invoke the set_readline function with the new encoding. - Return 1 on success, 0 on failure. */ - -static int -check_bom(int get_char(struct tok_state *), - void unget_char(int, struct tok_state *), - int set_readline(struct tok_state *, const char *), - struct tok_state *tok) -{ - int ch1, ch2, ch3; - ch1 = get_char(tok); - tok->decoding_state = STATE_SEEK_CODING; - if (ch1 == EOF) { - return 1; - } else if (ch1 == 0xEF) { - ch2 = get_char(tok); - if (ch2 != 0xBB) { - unget_char(ch2, tok); - unget_char(ch1, tok); - return 1; - } - ch3 = get_char(tok); - if (ch3 != 0xBF) { - unget_char(ch3, tok); - unget_char(ch2, tok); - unget_char(ch1, tok); - return 1; - } - } else { - unget_char(ch1, tok); - return 1; - } - if (tok->encoding != NULL) - PyMem_Free(tok->encoding); - tok->encoding = new_string("utf-8", 5, tok); - if (!tok->encoding) - return 0; - /* No need to set_readline: input is already utf-8 */ - return 1; -} - -static int -tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) { - assert(tok->fp_interactive); - - if (!line) { - return 0; - } - - Py_ssize_t current_size = tok->interactive_src_end - tok->interactive_src_start; - Py_ssize_t line_size = strlen(line); - char last_char = line[line_size > 0 ? line_size - 1 : line_size]; - if (last_char != '\n') { - line_size += 1; - } - char* new_str = tok->interactive_src_start; - - new_str = PyMem_Realloc(new_str, current_size + line_size + 1); - if (!new_str) { - if (tok->interactive_src_start) { - PyMem_Free(tok->interactive_src_start); - } - tok->interactive_src_start = NULL; - tok->interactive_src_end = NULL; - tok->done = E_NOMEM; - return -1; - } - strcpy(new_str + current_size, line); - tok->implicit_newline = 0; - if (last_char != '\n') { - /* Last line does not end in \n, fake one */ - new_str[current_size + line_size - 1] = '\n'; - new_str[current_size + line_size] = '\0'; - tok->implicit_newline = 1; - } - tok->interactive_src_start = new_str; - tok->interactive_src_end = new_str + current_size + line_size; - return 0; -} - -/* Traverse and remember all f-string buffers, in order to be able to restore - them after reallocating tok->buf */ -static void -remember_fstring_buffers(struct tok_state *tok) -{ - int index; - tokenizer_mode *mode; - - for (index = tok->tok_mode_stack_index; index >= 0; --index) { - mode = &(tok->tok_mode_stack[index]); - mode->f_string_start_offset = mode->f_string_start - tok->buf; - mode->f_string_multi_line_start_offset = mode->f_string_multi_line_start - tok->buf; - } -} - -/* Traverse and restore all f-string buffers after reallocating tok->buf */ -static void -restore_fstring_buffers(struct tok_state *tok) -{ - int index; - tokenizer_mode *mode; - - for (index = tok->tok_mode_stack_index; index >= 0; --index) { - mode = &(tok->tok_mode_stack[index]); - mode->f_string_start = tok->buf + mode->f_string_start_offset; - mode->f_string_multi_line_start = tok->buf + mode->f_string_multi_line_start_offset; - } -} - -static int -set_fstring_expr(struct tok_state* tok, struct token *token, char c) { - assert(token != NULL); - assert(c == '}' || c == ':' || c == '!'); - tokenizer_mode *tok_mode = TOK_GET_MODE(tok); - - if (!tok_mode->f_string_debug || token->metadata) { - return 0; - } - - PyObject *res = PyUnicode_DecodeUTF8( - tok_mode->last_expr_buffer, - tok_mode->last_expr_size - tok_mode->last_expr_end, - NULL - ); - if (!res) { - return -1; - } - token->metadata = res; - return 0; -} - -static int -update_fstring_expr(struct tok_state *tok, char cur) -{ - assert(tok->cur != NULL); - - Py_ssize_t size = strlen(tok->cur); - tokenizer_mode *tok_mode = TOK_GET_MODE(tok); - - switch (cur) { - case 0: - if (!tok_mode->last_expr_buffer || tok_mode->last_expr_end >= 0) { - return 1; - } - char *new_buffer = PyMem_Realloc( - tok_mode->last_expr_buffer, - tok_mode->last_expr_size + size - ); - if (new_buffer == NULL) { - PyMem_Free(tok_mode->last_expr_buffer); - goto error; - } - tok_mode->last_expr_buffer = new_buffer; - strncpy(tok_mode->last_expr_buffer + tok_mode->last_expr_size, tok->cur, size); - tok_mode->last_expr_size += size; - break; - case '{': - if (tok_mode->last_expr_buffer != NULL) { - PyMem_Free(tok_mode->last_expr_buffer); - } - tok_mode->last_expr_buffer = PyMem_Malloc(size); - if (tok_mode->last_expr_buffer == NULL) { - goto error; - } - tok_mode->last_expr_size = size; - tok_mode->last_expr_end = -1; - strncpy(tok_mode->last_expr_buffer, tok->cur, size); - break; - case '}': - case '!': - case ':': - if (tok_mode->last_expr_end == -1) { - tok_mode->last_expr_end = strlen(tok->start); - } - break; - default: - Py_UNREACHABLE(); - } - return 1; -error: - tok->done = E_NOMEM; - return 0; -} - -static void -free_fstring_expressions(struct tok_state *tok) -{ - int index; - tokenizer_mode *mode; - - for (index = tok->tok_mode_stack_index; index >= 0; --index) { - mode = &(tok->tok_mode_stack[index]); - if (mode->last_expr_buffer != NULL) { - PyMem_Free(mode->last_expr_buffer); - mode->last_expr_buffer = NULL; - mode->last_expr_size = 0; - mode->last_expr_end = -1; - } - } -} - -/* Read a line of text from TOK into S, using the stream in TOK. - Return NULL on failure, else S. - - On entry, tok->decoding_buffer will be one of: - 1) NULL: need to call tok->decoding_readline to get a new line - 2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and - stored the result in tok->decoding_buffer - 3) PyByteArrayObject *: previous call to tok_readline_recode did not have enough room - (in the s buffer) to copy entire contents of the line read - by tok->decoding_readline. tok->decoding_buffer has the overflow. - In this case, tok_readline_recode is called in a loop (with an expanded buffer) - until the buffer ends with a '\n' (or until the end of the file is - reached): see tok_nextc and its calls to tok_reserve_buf. -*/ - -static int -tok_reserve_buf(struct tok_state *tok, Py_ssize_t size) -{ - Py_ssize_t cur = tok->cur - tok->buf; - Py_ssize_t oldsize = tok->inp - tok->buf; - Py_ssize_t newsize = oldsize + Py_MAX(size, oldsize >> 1); - if (newsize > tok->end - tok->buf) { - char *newbuf = tok->buf; - Py_ssize_t start = tok->start == NULL ? -1 : tok->start - tok->buf; - Py_ssize_t line_start = tok->start == NULL ? -1 : tok->line_start - tok->buf; - Py_ssize_t multi_line_start = tok->multi_line_start - tok->buf; - remember_fstring_buffers(tok); - newbuf = (char *)PyMem_Realloc(newbuf, newsize); - if (newbuf == NULL) { - tok->done = E_NOMEM; - return 0; - } - tok->buf = newbuf; - tok->cur = tok->buf + cur; - tok->inp = tok->buf + oldsize; - tok->end = tok->buf + newsize; - tok->start = start < 0 ? NULL : tok->buf + start; - tok->line_start = line_start < 0 ? NULL : tok->buf + line_start; - tok->multi_line_start = multi_line_start < 0 ? NULL : tok->buf + multi_line_start; - restore_fstring_buffers(tok); - } - return 1; -} - -static inline int -contains_null_bytes(const char* str, size_t size) { - return memchr(str, 0, size) != NULL; -} - -static int -tok_readline_recode(struct tok_state *tok) { - PyObject *line; - const char *buf; - Py_ssize_t buflen; - line = tok->decoding_buffer; - if (line == NULL) { - line = PyObject_CallNoArgs(tok->decoding_readline); - if (line == NULL) { - error_ret(tok); - goto error; - } - } - else { - tok->decoding_buffer = NULL; - } - buf = PyUnicode_AsUTF8AndSize(line, &buflen); - if (buf == NULL) { - error_ret(tok); - goto error; - } - // Make room for the null terminator *and* potentially - // an extra newline character that we may need to artificially - // add. - size_t buffer_size = buflen + 2; - if (!tok_reserve_buf(tok, buffer_size)) { - goto error; - } - memcpy(tok->inp, buf, buflen); - tok->inp += buflen; - *tok->inp = '\0'; - if (tok->fp_interactive && - tok_concatenate_interactive_new_line(tok, buf) == -1) { - goto error; - } - Py_DECREF(line); - return 1; -error: - Py_XDECREF(line); - return 0; -} - -/* Set the readline function for TOK to a StreamReader's - readline function. The StreamReader is named ENC. - - This function is called from check_bom and check_coding_spec. - - ENC is usually identical to the future value of tok->encoding, - except for the (currently unsupported) case of UTF-16. - - Return 1 on success, 0 on failure. */ - -static int -fp_setreadl(struct tok_state *tok, const char* enc) -{ - PyObject *readline, *open, *stream; - int fd; - long pos; - - fd = fileno(tok->fp); - /* Due to buffering the file offset for fd can be different from the file - * position of tok->fp. If tok->fp was opened in text mode on Windows, - * its file position counts CRLF as one char and can't be directly mapped - * to the file offset for fd. Instead we step back one byte and read to - * the end of line.*/ - pos = ftell(tok->fp); - if (pos == -1 || - lseek(fd, (off_t)(pos > 0 ? pos - 1 : pos), SEEK_SET) == (off_t)-1) { - PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL); - return 0; - } - - open = _PyImport_GetModuleAttrString("io", "open"); - if (open == NULL) { - return 0; - } - stream = PyObject_CallFunction(open, "isisOOO", - fd, "r", -1, enc, Py_None, Py_None, Py_False); - Py_DECREF(open); - if (stream == NULL) { - return 0; - } - - readline = PyObject_GetAttr(stream, &_Py_ID(readline)); - Py_DECREF(stream); - if (readline == NULL) { - return 0; - } - Py_XSETREF(tok->decoding_readline, readline); - - if (pos > 0) { - PyObject *bufobj = _PyObject_CallNoArgs(readline); - if (bufobj == NULL) { - return 0; - } - Py_DECREF(bufobj); - } - - return 1; -} - -/* Fetch the next byte from TOK. */ - -static int fp_getc(struct tok_state *tok) { - return getc(tok->fp); -} - -/* Unfetch the last byte back into TOK. */ - -static void fp_ungetc(int c, struct tok_state *tok) { - ungetc(c, tok->fp); -} - -/* Check whether the characters at s start a valid - UTF-8 sequence. Return the number of characters forming - the sequence if yes, 0 if not. The special cases match - those in stringlib/codecs.h:utf8_decode. -*/ -static int -valid_utf8(const unsigned char* s) -{ - int expected = 0; - int length; - if (*s < 0x80) { - /* single-byte code */ - return 1; - } - else if (*s < 0xE0) { - /* \xC2\x80-\xDF\xBF -- 0080-07FF */ - if (*s < 0xC2) { - /* invalid sequence - \x80-\xBF -- continuation byte - \xC0-\xC1 -- fake 0000-007F */ - return 0; - } - expected = 1; - } - else if (*s < 0xF0) { - /* \xE0\xA0\x80-\xEF\xBF\xBF -- 0800-FFFF */ - if (*s == 0xE0 && *(s + 1) < 0xA0) { - /* invalid sequence - \xE0\x80\x80-\xE0\x9F\xBF -- fake 0000-0800 */ - return 0; - } - else if (*s == 0xED && *(s + 1) >= 0xA0) { - /* Decoding UTF-8 sequences in range \xED\xA0\x80-\xED\xBF\xBF - will result in surrogates in range D800-DFFF. Surrogates are - not valid UTF-8 so they are rejected. - See https://www.unicode.org/versions/Unicode5.2.0/ch03.pdf - (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */ - return 0; - } - expected = 2; - } - else if (*s < 0xF5) { - /* \xF0\x90\x80\x80-\xF4\x8F\xBF\xBF -- 10000-10FFFF */ - if (*(s + 1) < 0x90 ? *s == 0xF0 : *s == 0xF4) { - /* invalid sequence -- one of: - \xF0\x80\x80\x80-\xF0\x8F\xBF\xBF -- fake 0000-FFFF - \xF4\x90\x80\x80- -- 110000- overflow */ - return 0; - } - expected = 3; - } - else { - /* invalid start byte */ - return 0; - } - length = expected + 1; - for (; expected; expected--) - if (s[expected] < 0x80 || s[expected] >= 0xC0) - return 0; - return length; -} - -static int -ensure_utf8(char *line, struct tok_state *tok) -{ - int badchar = 0; - unsigned char *c; - int length; - for (c = (unsigned char *)line; *c; c += length) { - if (!(length = valid_utf8(c))) { - badchar = *c; - break; - } - } - if (badchar) { - PyErr_Format(PyExc_SyntaxError, - "Non-UTF-8 code starting with '\\x%.2x' " - "in file %U on line %i, " - "but no encoding declared; " - "see https://peps.python.org/pep-0263/ for details", - badchar, tok->filename, tok->lineno); - return 0; - } - return 1; -} - -/* Fetch a byte from TOK, using the string buffer. */ - -static int -buf_getc(struct tok_state *tok) { - return Py_CHARMASK(*tok->str++); -} - -/* Unfetch a byte from TOK, using the string buffer. */ - -static void -buf_ungetc(int c, struct tok_state *tok) { - tok->str--; - assert(Py_CHARMASK(*tok->str) == c); /* tok->cur may point to read-only segment */ -} - -/* Set the readline function for TOK to ENC. For the string-based - tokenizer, this means to just record the encoding. */ - -static int -buf_setreadl(struct tok_state *tok, const char* enc) { - tok->enc = enc; - return 1; -} - -/* Return a UTF-8 encoding Python string object from the - C byte string STR, which is encoded with ENC. */ - -static PyObject * -translate_into_utf8(const char* str, const char* enc) { - PyObject *utf8; - PyObject* buf = PyUnicode_Decode(str, strlen(str), enc, NULL); - if (buf == NULL) - return NULL; - utf8 = PyUnicode_AsUTF8String(buf); - Py_DECREF(buf); - return utf8; -} - - -static char * -translate_newlines(const char *s, int exec_input, int preserve_crlf, - struct tok_state *tok) { - int skip_next_lf = 0; - size_t needed_length = strlen(s) + 2, final_length; - char *buf, *current; - char c = '\0'; - buf = PyMem_Malloc(needed_length); - if (buf == NULL) { - tok->done = E_NOMEM; - return NULL; - } - for (current = buf; *s; s++, current++) { - c = *s; - if (skip_next_lf) { - skip_next_lf = 0; - if (c == '\n') { - c = *++s; - if (!c) - break; - } - } - if (!preserve_crlf && c == '\r') { - skip_next_lf = 1; - c = '\n'; - } - *current = c; - } - /* If this is exec input, add a newline to the end of the string if - there isn't one already. */ - if (exec_input && c != '\n' && c != '\0') { - *current = '\n'; - current++; - } - *current = '\0'; - final_length = current - buf + 1; - if (final_length < needed_length && final_length) { - /* should never fail */ - char* result = PyMem_Realloc(buf, final_length); - if (result == NULL) { - PyMem_Free(buf); - } - buf = result; - } - return buf; -} - -/* Decode a byte string STR for use as the buffer of TOK. - Look for encoding declarations inside STR, and record them - inside TOK. */ - -static char * -decode_str(const char *input, int single, struct tok_state *tok, int preserve_crlf) -{ - PyObject* utf8 = NULL; - char *str; - const char *s; - const char *newl[2] = {NULL, NULL}; - int lineno = 0; - tok->input = str = translate_newlines(input, single, preserve_crlf, tok); - if (str == NULL) - return NULL; - tok->enc = NULL; - tok->str = str; - if (!check_bom(buf_getc, buf_ungetc, buf_setreadl, tok)) - return error_ret(tok); - str = tok->str; /* string after BOM if any */ - assert(str); - if (tok->enc != NULL) { - utf8 = translate_into_utf8(str, tok->enc); - if (utf8 == NULL) - return error_ret(tok); - str = PyBytes_AsString(utf8); - } - for (s = str;; s++) { - if (*s == '\0') break; - else if (*s == '\n') { - assert(lineno < 2); - newl[lineno] = s; - lineno++; - if (lineno == 2) break; - } - } - tok->enc = NULL; - /* need to check line 1 and 2 separately since check_coding_spec - assumes a single line as input */ - if (newl[0]) { - if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) { - return NULL; - } - if (tok->enc == NULL && tok->decoding_state != STATE_NORMAL && newl[1]) { - if (!check_coding_spec(newl[0]+1, newl[1] - newl[0], - tok, buf_setreadl)) - return NULL; - } - } - if (tok->enc != NULL) { - assert(utf8 == NULL); - utf8 = translate_into_utf8(str, tok->enc); - if (utf8 == NULL) - return error_ret(tok); - str = PyBytes_AS_STRING(utf8); - } - assert(tok->decoding_buffer == NULL); - tok->decoding_buffer = utf8; /* CAUTION */ - return str; -} - -/* Set up tokenizer for string */ - -struct tok_state * -_PyTokenizer_FromString(const char *str, int exec_input, int preserve_crlf) -{ - struct tok_state *tok = tok_new(); - char *decoded; - - if (tok == NULL) - return NULL; - decoded = decode_str(str, exec_input, tok, preserve_crlf); - if (decoded == NULL) { - _PyTokenizer_Free(tok); - return NULL; - } - - tok->buf = tok->cur = tok->inp = decoded; - tok->end = decoded; - return tok; -} - -struct tok_state * -_PyTokenizer_FromReadline(PyObject* readline, const char* enc, - int exec_input, int preserve_crlf) -{ - struct tok_state *tok = tok_new(); - if (tok == NULL) - return NULL; - if ((tok->buf = (char *)PyMem_Malloc(BUFSIZ)) == NULL) { - _PyTokenizer_Free(tok); - return NULL; - } - tok->cur = tok->inp = tok->buf; - tok->end = tok->buf + BUFSIZ; - tok->fp = NULL; - if (enc != NULL) { - tok->encoding = new_string(enc, strlen(enc), tok); - if (!tok->encoding) { - _PyTokenizer_Free(tok); - return NULL; - } - } - tok->decoding_state = STATE_NORMAL; - Py_INCREF(readline); - tok->readline = readline; - return tok; -} - -/* Set up tokenizer for UTF-8 string */ - -struct tok_state * -_PyTokenizer_FromUTF8(const char *str, int exec_input, int preserve_crlf) -{ - struct tok_state *tok = tok_new(); - char *translated; - if (tok == NULL) - return NULL; - tok->input = translated = translate_newlines(str, exec_input, preserve_crlf, tok); - if (translated == NULL) { - _PyTokenizer_Free(tok); - return NULL; - } - tok->decoding_state = STATE_NORMAL; - tok->enc = NULL; - tok->str = translated; - tok->encoding = new_string("utf-8", 5, tok); - if (!tok->encoding) { - _PyTokenizer_Free(tok); - return NULL; - } - - tok->buf = tok->cur = tok->inp = translated; - tok->end = translated; - return tok; -} - -/* Set up tokenizer for file */ - -struct tok_state * -_PyTokenizer_FromFile(FILE *fp, const char* enc, - const char *ps1, const char *ps2) -{ - struct tok_state *tok = tok_new(); - if (tok == NULL) - return NULL; - if ((tok->buf = (char *)PyMem_Malloc(BUFSIZ)) == NULL) { - _PyTokenizer_Free(tok); - return NULL; - } - tok->cur = tok->inp = tok->buf; - tok->end = tok->buf + BUFSIZ; - tok->fp = fp; - tok->prompt = ps1; - tok->nextprompt = ps2; - if (enc != NULL) { - /* Must copy encoding declaration since it - gets copied into the parse tree. */ - tok->encoding = new_string(enc, strlen(enc), tok); - if (!tok->encoding) { - _PyTokenizer_Free(tok); - return NULL; - } - tok->decoding_state = STATE_NORMAL; - } - return tok; -} - -/* Free a tok_state structure */ - -void -_PyTokenizer_Free(struct tok_state *tok) -{ - if (tok->encoding != NULL) { - PyMem_Free(tok->encoding); - } - Py_XDECREF(tok->decoding_readline); - Py_XDECREF(tok->decoding_buffer); - Py_XDECREF(tok->readline); - Py_XDECREF(tok->filename); - if ((tok->readline != NULL || tok->fp != NULL ) && tok->buf != NULL) { - PyMem_Free(tok->buf); - } - if (tok->input) { - PyMem_Free(tok->input); - } - if (tok->interactive_src_start != NULL) { - PyMem_Free(tok->interactive_src_start); - } - free_fstring_expressions(tok); - PyMem_Free(tok); -} - -void -_PyToken_Free(struct token *token) { - Py_XDECREF(token->metadata); -} - -void -_PyToken_Init(struct token *token) { - token->metadata = NULL; -} - -static int -tok_readline_raw(struct tok_state *tok) -{ - do { - if (!tok_reserve_buf(tok, BUFSIZ)) { - return 0; - } - int n_chars = (int)(tok->end - tok->inp); - size_t line_size = 0; - char *line = _Py_UniversalNewlineFgetsWithSize(tok->inp, n_chars, tok->fp, NULL, &line_size); - if (line == NULL) { - return 1; - } - if (tok->fp_interactive && - tok_concatenate_interactive_new_line(tok, line) == -1) { - return 0; - } - tok->inp += line_size; - if (tok->inp == tok->buf) { - return 0; - } - } while (tok->inp[-1] != '\n'); - return 1; -} - -static int -tok_readline_string(struct tok_state* tok) { - PyObject* line = NULL; - PyObject* raw_line = PyObject_CallNoArgs(tok->readline); - if (raw_line == NULL) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) { - PyErr_Clear(); - return 1; - } - error_ret(tok); - goto error; - } - if(tok->encoding != NULL) { - if (!PyBytes_Check(raw_line)) { - PyErr_Format(PyExc_TypeError, "readline() returned a non-bytes object"); - error_ret(tok); - goto error; - } - line = PyUnicode_Decode(PyBytes_AS_STRING(raw_line), PyBytes_GET_SIZE(raw_line), - tok->encoding, "replace"); - Py_CLEAR(raw_line); - if (line == NULL) { - error_ret(tok); - goto error; - } - } else { - if(!PyUnicode_Check(raw_line)) { - PyErr_Format(PyExc_TypeError, "readline() returned a non-string object"); - error_ret(tok); - goto error; - } - line = raw_line; - raw_line = NULL; - } - Py_ssize_t buflen; - const char* buf = PyUnicode_AsUTF8AndSize(line, &buflen); - if (buf == NULL) { - error_ret(tok); - goto error; - } - - // Make room for the null terminator *and* potentially - // an extra newline character that we may need to artificially - // add. - size_t buffer_size = buflen + 2; - if (!tok_reserve_buf(tok, buffer_size)) { - goto error; - } - memcpy(tok->inp, buf, buflen); - tok->inp += buflen; - *tok->inp = '\0'; - - tok->line_start = tok->cur; - Py_DECREF(line); - return 1; -error: - Py_XDECREF(raw_line); - Py_XDECREF(line); - return 0; -} - -static int -tok_underflow_string(struct tok_state *tok) { - char *end = strchr(tok->inp, '\n'); - if (end != NULL) { - end++; - } - else { - end = strchr(tok->inp, '\0'); - if (end == tok->inp) { - tok->done = E_EOF; - return 0; - } - } - if (tok->start == NULL) { - tok->buf = tok->cur; - } - tok->line_start = tok->cur; - ADVANCE_LINENO(); - tok->inp = end; - return 1; -} - -static int -tok_underflow_interactive(struct tok_state *tok) { - if (tok->interactive_underflow == IUNDERFLOW_STOP) { - tok->done = E_INTERACT_STOP; - return 1; - } - char *newtok = PyOS_Readline(tok->fp ? tok->fp : stdin, stdout, tok->prompt); - if (newtok != NULL) { - char *translated = translate_newlines(newtok, 0, 0, tok); - PyMem_Free(newtok); - if (translated == NULL) { - return 0; - } - newtok = translated; - } - if (tok->encoding && newtok && *newtok) { - /* Recode to UTF-8 */ - Py_ssize_t buflen; - const char* buf; - PyObject *u = translate_into_utf8(newtok, tok->encoding); - PyMem_Free(newtok); - if (u == NULL) { - tok->done = E_DECODE; - return 0; - } - buflen = PyBytes_GET_SIZE(u); - buf = PyBytes_AS_STRING(u); - newtok = PyMem_Malloc(buflen+1); - if (newtok == NULL) { - Py_DECREF(u); - tok->done = E_NOMEM; - return 0; - } - strcpy(newtok, buf); - Py_DECREF(u); - } - if (tok->fp_interactive && - tok_concatenate_interactive_new_line(tok, newtok) == -1) { - PyMem_Free(newtok); - return 0; - } - if (tok->nextprompt != NULL) { - tok->prompt = tok->nextprompt; - } - if (newtok == NULL) { - tok->done = E_INTR; - } - else if (*newtok == '\0') { - PyMem_Free(newtok); - tok->done = E_EOF; - } - else if (tok->start != NULL) { - Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; - remember_fstring_buffers(tok); - size_t size = strlen(newtok); - ADVANCE_LINENO(); - if (!tok_reserve_buf(tok, size + 1)) { - PyMem_Free(tok->buf); - tok->buf = NULL; - PyMem_Free(newtok); - return 0; - } - memcpy(tok->cur, newtok, size + 1); - PyMem_Free(newtok); - tok->inp += size; - tok->multi_line_start = tok->buf + cur_multi_line_start; - restore_fstring_buffers(tok); - } - else { - remember_fstring_buffers(tok); - ADVANCE_LINENO(); - PyMem_Free(tok->buf); - tok->buf = newtok; - tok->cur = tok->buf; - tok->line_start = tok->buf; - tok->inp = strchr(tok->buf, '\0'); - tok->end = tok->inp + 1; - restore_fstring_buffers(tok); - } - if (tok->done != E_OK) { - if (tok->prompt != NULL) { - PySys_WriteStderr("\n"); - } - return 0; - } - - if (tok->tok_mode_stack_index && !update_fstring_expr(tok, 0)) { - return 0; - } - return 1; -} - -static int -tok_underflow_file(struct tok_state *tok) { - if (tok->start == NULL && !INSIDE_FSTRING(tok)) { - tok->cur = tok->inp = tok->buf; - } - if (tok->decoding_state == STATE_INIT) { - /* We have not yet determined the encoding. - If an encoding is found, use the file-pointer - reader functions from now on. */ - if (!check_bom(fp_getc, fp_ungetc, fp_setreadl, tok)) { - error_ret(tok); - return 0; - } - assert(tok->decoding_state != STATE_INIT); - } - /* Read until '\n' or EOF */ - if (tok->decoding_readline != NULL) { - /* We already have a codec associated with this input. */ - if (!tok_readline_recode(tok)) { - return 0; - } - } - else { - /* We want a 'raw' read. */ - if (!tok_readline_raw(tok)) { - return 0; - } - } - if (tok->inp == tok->cur) { - tok->done = E_EOF; - return 0; - } - tok->implicit_newline = 0; - if (tok->inp[-1] != '\n') { - assert(tok->inp + 1 < tok->end); - /* Last line does not end in \n, fake one */ - *tok->inp++ = '\n'; - *tok->inp = '\0'; - tok->implicit_newline = 1; - } - - if (tok->tok_mode_stack_index && !update_fstring_expr(tok, 0)) { - return 0; - } - - ADVANCE_LINENO(); - if (tok->decoding_state != STATE_NORMAL) { - if (tok->lineno > 2) { - tok->decoding_state = STATE_NORMAL; - } - else if (!check_coding_spec(tok->cur, strlen(tok->cur), - tok, fp_setreadl)) - { - return 0; - } - } - /* The default encoding is UTF-8, so make sure we don't have any - non-UTF-8 sequences in it. */ - if (!tok->encoding && !ensure_utf8(tok->cur, tok)) { - error_ret(tok); - return 0; - } - assert(tok->done == E_OK); - return tok->done == E_OK; -} - -static int -tok_underflow_readline(struct tok_state* tok) { - assert(tok->decoding_state == STATE_NORMAL); - assert(tok->fp == NULL && tok->input == NULL && tok->decoding_readline == NULL); - if (tok->start == NULL && !INSIDE_FSTRING(tok)) { - tok->cur = tok->inp = tok->buf; - } - if (!tok_readline_string(tok)) { - return 0; - } - if (tok->inp == tok->cur) { - tok->done = E_EOF; - return 0; - } - tok->implicit_newline = 0; - if (tok->inp[-1] != '\n') { - assert(tok->inp + 1 < tok->end); - /* Last line does not end in \n, fake one */ - *tok->inp++ = '\n'; - *tok->inp = '\0'; - tok->implicit_newline = 1; - } - - if (tok->tok_mode_stack_index && !update_fstring_expr(tok, 0)) { - return 0; - } - - ADVANCE_LINENO(); - /* The default encoding is UTF-8, so make sure we don't have any - non-UTF-8 sequences in it. */ - if (!tok->encoding && !ensure_utf8(tok->cur, tok)) { - error_ret(tok); - return 0; - } - assert(tok->done == E_OK); - return tok->done == E_OK; -} - -#if defined(Py_DEBUG) -static void -print_escape(FILE *f, const char *s, Py_ssize_t size) -{ - if (s == NULL) { - fputs("NULL", f); - return; - } - putc('"', f); - while (size-- > 0) { - unsigned char c = *s++; - switch (c) { - case '\n': fputs("\\n", f); break; - case '\r': fputs("\\r", f); break; - case '\t': fputs("\\t", f); break; - case '\f': fputs("\\f", f); break; - case '\'': fputs("\\'", f); break; - case '"': fputs("\\\"", f); break; - default: - if (0x20 <= c && c <= 0x7f) - putc(c, f); - else - fprintf(f, "\\x%02x", c); - } - } - putc('"', f); -} -#endif - -/* Get next char, updating state; error code goes into tok->done */ - -static int -tok_nextc(struct tok_state *tok) -{ - int rc; - for (;;) { - if (tok->cur != tok->inp) { - tok->col_offset++; - return Py_CHARMASK(*tok->cur++); /* Fast path */ - } - if (tok->done != E_OK) { - return EOF; - } - if (tok->readline) { - rc = tok_underflow_readline(tok); - } - else if (tok->fp == NULL) { - rc = tok_underflow_string(tok); - } - else if (tok->prompt != NULL) { - rc = tok_underflow_interactive(tok); - } - else { - rc = tok_underflow_file(tok); - } -#if defined(Py_DEBUG) - if (tok->debug) { - fprintf(stderr, "line[%d] = ", tok->lineno); - print_escape(stderr, tok->cur, tok->inp - tok->cur); - fprintf(stderr, " tok->done = %d\n", tok->done); - } -#endif - if (!rc) { - tok->cur = tok->inp; - return EOF; - } - tok->line_start = tok->cur; - - if (contains_null_bytes(tok->line_start, tok->inp - tok->line_start)) { - syntaxerror(tok, "source code cannot contain null bytes"); - tok->cur = tok->inp; - return EOF; - } - } - Py_UNREACHABLE(); -} - -/* Back-up one character */ - -static void -tok_backup(struct tok_state *tok, int c) -{ - if (c != EOF) { - if (--tok->cur < tok->buf) { - Py_FatalError("tokenizer beginning of buffer"); - } - if ((int)(unsigned char)*tok->cur != Py_CHARMASK(c)) { - Py_FatalError("tok_backup: wrong character"); - } - tok->col_offset--; - } -} - -static int -_syntaxerror_range(struct tok_state *tok, const char *format, - int col_offset, int end_col_offset, - va_list vargs) -{ - // In release builds, we don't want to overwrite a previous error, but in debug builds we - // want to fail if we are not doing it so we can fix it. - assert(tok->done != E_ERROR); - if (tok->done == E_ERROR) { - return ERRORTOKEN; - } - PyObject *errmsg, *errtext, *args; - errmsg = PyUnicode_FromFormatV(format, vargs); - if (!errmsg) { - goto error; - } - - errtext = PyUnicode_DecodeUTF8(tok->line_start, tok->cur - tok->line_start, - "replace"); - if (!errtext) { - goto error; - } - - if (col_offset == -1) { - col_offset = (int)PyUnicode_GET_LENGTH(errtext); - } - if (end_col_offset == -1) { - end_col_offset = col_offset; - } - - Py_ssize_t line_len = strcspn(tok->line_start, "\n"); - if (line_len != tok->cur - tok->line_start) { - Py_DECREF(errtext); - errtext = PyUnicode_DecodeUTF8(tok->line_start, line_len, - "replace"); - } - if (!errtext) { - goto error; - } - - args = Py_BuildValue("(O(OiiNii))", errmsg, tok->filename, tok->lineno, - col_offset, errtext, tok->lineno, end_col_offset); - if (args) { - PyErr_SetObject(PyExc_SyntaxError, args); - Py_DECREF(args); - } - -error: - Py_XDECREF(errmsg); - tok->done = E_ERROR; - return ERRORTOKEN; -} - -static int -syntaxerror(struct tok_state *tok, const char *format, ...) -{ - // This errors are cleaned on startup. Todo: Fix it. - va_list vargs; - va_start(vargs, format); - int ret = _syntaxerror_range(tok, format, -1, -1, vargs); - va_end(vargs); - return ret; -} - -static int -syntaxerror_known_range(struct tok_state *tok, - int col_offset, int end_col_offset, - const char *format, ...) -{ - va_list vargs; - va_start(vargs, format); - int ret = _syntaxerror_range(tok, format, col_offset, end_col_offset, vargs); - va_end(vargs); - return ret; -} - -static int -indenterror(struct tok_state *tok) -{ - tok->done = E_TABSPACE; - tok->cur = tok->inp; - return ERRORTOKEN; -} - -static int -parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...) -{ - if (!tok->report_warnings) { - return 0; - } - - PyObject *errmsg; - va_list vargs; - va_start(vargs, format); - errmsg = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - if (!errmsg) { - goto error; - } - - if (PyErr_WarnExplicitObject(category, errmsg, tok->filename, - tok->lineno, NULL, NULL) < 0) { - if (PyErr_ExceptionMatches(category)) { - /* Replace the DeprecationWarning exception with a SyntaxError - to get a more accurate error report */ - PyErr_Clear(); - syntaxerror(tok, "%U", errmsg); - } - goto error; - } - Py_DECREF(errmsg); - return 0; - -error: - Py_XDECREF(errmsg); - tok->done = E_ERROR; - return -1; -} - -static int -warn_invalid_escape_sequence(struct tok_state *tok, int first_invalid_escape_char) -{ - - if (!tok->tok_report_warnings) { - return 0; - } - - PyObject *msg = PyUnicode_FromFormat( - "invalid escape sequence '\\%c'", - (char) first_invalid_escape_char - ); - - if (msg == NULL) { - return -1; - } - - if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, tok->filename, - tok->lineno, NULL, NULL) < 0) { - Py_DECREF(msg); - - if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { - /* Replace the SyntaxWarning exception with a SyntaxError - to get a more accurate error report */ - PyErr_Clear(); - return syntaxerror(tok, "invalid escape sequence '\\%c'", (char) first_invalid_escape_char); - } - - return -1; - } - - Py_DECREF(msg); - return 0; -} - -static int -lookahead(struct tok_state *tok, const char *test) -{ - const char *s = test; - int res = 0; - while (1) { - int c = tok_nextc(tok); - if (*s == 0) { - res = !is_potential_identifier_char(c); - } - else if (c == *s) { - s++; - continue; - } - - tok_backup(tok, c); - while (s != test) { - tok_backup(tok, *--s); - } - return res; - } -} - -static int -verify_end_of_number(struct tok_state *tok, int c, const char *kind) { - if (tok->tok_extra_tokens) { - // When we are parsing extra tokens, we don't want to emit warnings - // about invalid literals, because we want to be a bit more liberal. - return 1; - } - /* Emit a deprecation warning only if the numeric literal is immediately - * followed by one of keywords which can occur after a numeric literal - * in valid code: "and", "else", "for", "if", "in", "is" and "or". - * It allows to gradually deprecate existing valid code without adding - * warning before error in most cases of invalid numeric literal (which - * would be confusing and break existing tests). - * Raise a syntax error with slightly better message than plain - * "invalid syntax" if the numeric literal is immediately followed by - * other keyword or identifier. - */ - int r = 0; - if (c == 'a') { - r = lookahead(tok, "nd"); - } - else if (c == 'e') { - r = lookahead(tok, "lse"); - } - else if (c == 'f') { - r = lookahead(tok, "or"); - } - else if (c == 'i') { - int c2 = tok_nextc(tok); - if (c2 == 'f' || c2 == 'n' || c2 == 's') { - r = 1; - } - tok_backup(tok, c2); - } - else if (c == 'o') { - r = lookahead(tok, "r"); - } - else if (c == 'n') { - r = lookahead(tok, "ot"); - } - if (r) { - tok_backup(tok, c); - if (parser_warn(tok, PyExc_SyntaxWarning, - "invalid %s literal", kind)) - { - return 0; - } - tok_nextc(tok); - } - else /* In future releases, only error will remain. */ - if (is_potential_identifier_char(c)) { - tok_backup(tok, c); - syntaxerror(tok, "invalid %s literal", kind); - return 0; - } - return 1; -} - -/* Verify that the identifier follows PEP 3131. - All identifier strings are guaranteed to be "ready" unicode objects. - */ -static int -verify_identifier(struct tok_state *tok) -{ - if (tok->tok_extra_tokens) { - return 1; - } - PyObject *s; - if (tok->decoding_erred) - return 0; - s = PyUnicode_DecodeUTF8(tok->start, tok->cur - tok->start, NULL); - if (s == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - tok->done = E_DECODE; - } - else { - tok->done = E_ERROR; - } - return 0; - } - Py_ssize_t invalid = _PyUnicode_ScanIdentifier(s); - if (invalid < 0) { - Py_DECREF(s); - tok->done = E_ERROR; - return 0; - } - assert(PyUnicode_GET_LENGTH(s) > 0); - if (invalid < PyUnicode_GET_LENGTH(s)) { - Py_UCS4 ch = PyUnicode_READ_CHAR(s, invalid); - if (invalid + 1 < PyUnicode_GET_LENGTH(s)) { - /* Determine the offset in UTF-8 encoded input */ - Py_SETREF(s, PyUnicode_Substring(s, 0, invalid + 1)); - if (s != NULL) { - Py_SETREF(s, PyUnicode_AsUTF8String(s)); - } - if (s == NULL) { - tok->done = E_ERROR; - return 0; - } - tok->cur = (char *)tok->start + PyBytes_GET_SIZE(s); - } - Py_DECREF(s); - if (Py_UNICODE_ISPRINTABLE(ch)) { - syntaxerror(tok, "invalid character '%c' (U+%04X)", ch, ch); - } - else { - syntaxerror(tok, "invalid non-printable character U+%04X", ch); - } - return 0; - } - Py_DECREF(s); - return 1; -} - -static int -tok_decimal_tail(struct tok_state *tok) -{ - int c; - - while (1) { - do { - c = tok_nextc(tok); - } while (isdigit(c)); - if (c != '_') { - break; - } - c = tok_nextc(tok); - if (!isdigit(c)) { - tok_backup(tok, c); - syntaxerror(tok, "invalid decimal literal"); - return 0; - } - } - return c; -} - - -static inline int -tok_continuation_line(struct tok_state *tok) { - int c = tok_nextc(tok); - if (c == '\r') { - c = tok_nextc(tok); - } - if (c != '\n') { - tok->done = E_LINECONT; - return -1; - } - c = tok_nextc(tok); - if (c == EOF) { - tok->done = E_EOF; - tok->cur = tok->inp; - return -1; - } else { - tok_backup(tok, c); - } - return c; -} - -static int -type_comment_token_setup(struct tok_state *tok, struct token *token, int type, int col_offset, - int end_col_offset, const char *start, const char *end) -{ - token->level = tok->level; - token->lineno = token->end_lineno = tok->lineno; - token->col_offset = col_offset; - token->end_col_offset = end_col_offset; - token->start = start; - token->end = end; - return type; -} - -static int -token_setup(struct tok_state *tok, struct token *token, int type, const char *start, const char *end) -{ - assert((start == NULL && end == NULL) || (start != NULL && end != NULL)); - token->level = tok->level; - if (ISSTRINGLIT(type)) { - token->lineno = tok->first_lineno; - } - else { - token->lineno = tok->lineno; - } - token->end_lineno = tok->lineno; - token->col_offset = token->end_col_offset = -1; - token->start = start; - token->end = end; - - if (start != NULL && end != NULL) { - token->col_offset = tok->starting_col_offset; - token->end_col_offset = tok->col_offset; - } - return type; -} - - -static int -tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct token *token) -{ - int c; - int blankline, nonascii; - - const char *p_start = NULL; - const char *p_end = NULL; - nextline: - tok->start = NULL; - tok->starting_col_offset = -1; - blankline = 0; - - - /* Get indentation level */ - if (tok->atbol) { - int col = 0; - int altcol = 0; - tok->atbol = 0; - int cont_line_col = 0; - for (;;) { - c = tok_nextc(tok); - if (c == ' ') { - col++, altcol++; - } - else if (c == '\t') { - col = (col / tok->tabsize + 1) * tok->tabsize; - altcol = (altcol / ALTTABSIZE + 1) * ALTTABSIZE; - } - else if (c == '\014') {/* Control-L (formfeed) */ - col = altcol = 0; /* For Emacs users */ - } - else if (c == '\\') { - // Indentation cannot be split over multiple physical lines - // using backslashes. This means that if we found a backslash - // preceded by whitespace, **the first one we find** determines - // the level of indentation of whatever comes next. - cont_line_col = cont_line_col ? cont_line_col : col; - if ((c = tok_continuation_line(tok)) == -1) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - else { - break; - } - } - tok_backup(tok, c); - if (c == '#' || c == '\n' || c == '\r') { - /* Lines with only whitespace and/or comments - shouldn't affect the indentation and are - not passed to the parser as NEWLINE tokens, - except *totally* empty lines in interactive - mode, which signal the end of a command group. */ - if (col == 0 && c == '\n' && tok->prompt != NULL) { - blankline = 0; /* Let it through */ - } - else if (tok->prompt != NULL && tok->lineno == 1) { - /* In interactive mode, if the first line contains - only spaces and/or a comment, let it through. */ - blankline = 0; - col = altcol = 0; - } - else { - blankline = 1; /* Ignore completely */ - } - /* We can't jump back right here since we still - may need to skip to the end of a comment */ - } - if (!blankline && tok->level == 0) { - col = cont_line_col ? cont_line_col : col; - altcol = cont_line_col ? cont_line_col : altcol; - if (col == tok->indstack[tok->indent]) { - /* No change */ - if (altcol != tok->altindstack[tok->indent]) { - return MAKE_TOKEN(indenterror(tok)); - } - } - else if (col > tok->indstack[tok->indent]) { - /* Indent -- always one */ - if (tok->indent+1 >= MAXINDENT) { - tok->done = E_TOODEEP; - tok->cur = tok->inp; - return MAKE_TOKEN(ERRORTOKEN); - } - if (altcol <= tok->altindstack[tok->indent]) { - return MAKE_TOKEN(indenterror(tok)); - } - tok->pendin++; - tok->indstack[++tok->indent] = col; - tok->altindstack[tok->indent] = altcol; - } - else /* col < tok->indstack[tok->indent] */ { - /* Dedent -- any number, must be consistent */ - while (tok->indent > 0 && - col < tok->indstack[tok->indent]) { - tok->pendin--; - tok->indent--; - } - if (col != tok->indstack[tok->indent]) { - tok->done = E_DEDENT; - tok->cur = tok->inp; - return MAKE_TOKEN(ERRORTOKEN); - } - if (altcol != tok->altindstack[tok->indent]) { - return MAKE_TOKEN(indenterror(tok)); - } - } - } - } - - tok->start = tok->cur; - tok->starting_col_offset = tok->col_offset; - - /* Return pending indents/dedents */ - if (tok->pendin != 0) { - if (tok->pendin < 0) { - if (tok->tok_extra_tokens) { - p_start = tok->cur; - p_end = tok->cur; - } - tok->pendin++; - return MAKE_TOKEN(DEDENT); - } - else { - if (tok->tok_extra_tokens) { - p_start = tok->buf; - p_end = tok->cur; - } - tok->pendin--; - return MAKE_TOKEN(INDENT); - } - } - - /* Peek ahead at the next character */ - c = tok_nextc(tok); - tok_backup(tok, c); - /* Check if we are closing an async function */ - if (tok->async_def - && !blankline - /* Due to some implementation artifacts of type comments, - * a TYPE_COMMENT at the start of a function won't set an - * indentation level and it will produce a NEWLINE after it. - * To avoid spuriously ending an async function due to this, - * wait until we have some non-newline char in front of us. */ - && c != '\n' - && tok->level == 0 - /* There was a NEWLINE after ASYNC DEF, - so we're past the signature. */ - && tok->async_def_nl - /* Current indentation level is less than where - the async function was defined */ - && tok->async_def_indent >= tok->indent) - { - tok->async_def = 0; - tok->async_def_indent = 0; - tok->async_def_nl = 0; - } - - again: - tok->start = NULL; - /* Skip spaces */ - do { - c = tok_nextc(tok); - } while (c == ' ' || c == '\t' || c == '\014'); - - /* Set start of current token */ - tok->start = tok->cur == NULL ? NULL : tok->cur - 1; - tok->starting_col_offset = tok->col_offset - 1; - - /* Skip comment, unless it's a type comment */ - if (c == '#') { - - const char* p = NULL; - const char *prefix, *type_start; - int current_starting_col_offset; - - while (c != EOF && c != '\n' && c != '\r') { - c = tok_nextc(tok); - } - - if (tok->tok_extra_tokens) { - p = tok->start; - } - - if (tok->type_comments) { - p = tok->start; - current_starting_col_offset = tok->starting_col_offset; - prefix = type_comment_prefix; - while (*prefix && p < tok->cur) { - if (*prefix == ' ') { - while (*p == ' ' || *p == '\t') { - p++; - current_starting_col_offset++; - } - } else if (*prefix == *p) { - p++; - current_starting_col_offset++; - } else { - break; - } - - prefix++; - } - - /* This is a type comment if we matched all of type_comment_prefix. */ - if (!*prefix) { - int is_type_ignore = 1; - // +6 in order to skip the word 'ignore' - const char *ignore_end = p + 6; - const int ignore_end_col_offset = current_starting_col_offset + 6; - tok_backup(tok, c); /* don't eat the newline or EOF */ - - type_start = p; - - /* A TYPE_IGNORE is "type: ignore" followed by the end of the token - * or anything ASCII and non-alphanumeric. */ - is_type_ignore = ( - tok->cur >= ignore_end && memcmp(p, "ignore", 6) == 0 - && !(tok->cur > ignore_end - && ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0])))); - - if (is_type_ignore) { - p_start = ignore_end; - p_end = tok->cur; - - /* If this type ignore is the only thing on the line, consume the newline also. */ - if (blankline) { - tok_nextc(tok); - tok->atbol = 1; - } - return MAKE_TYPE_COMMENT_TOKEN(TYPE_IGNORE, ignore_end_col_offset, tok->col_offset); - } else { - p_start = type_start; - p_end = tok->cur; - return MAKE_TYPE_COMMENT_TOKEN(TYPE_COMMENT, current_starting_col_offset, tok->col_offset); - } - } - } - if (tok->tok_extra_tokens) { - tok_backup(tok, c); /* don't eat the newline or EOF */ - p_start = p; - p_end = tok->cur; - tok->comment_newline = blankline; - return MAKE_TOKEN(COMMENT); - } - } - - if (tok->done == E_INTERACT_STOP) { - return MAKE_TOKEN(ENDMARKER); - } - - /* Check for EOF and errors now */ - if (c == EOF) { - if (tok->level) { - return MAKE_TOKEN(ERRORTOKEN); - } - return MAKE_TOKEN(tok->done == E_EOF ? ENDMARKER : ERRORTOKEN); - } - - /* Identifier (most frequent token!) */ - nonascii = 0; - if (is_potential_identifier_start(c)) { - /* Process the various legal combinations of b"", r"", u"", and f"". */ - int saw_b = 0, saw_r = 0, saw_u = 0, saw_f = 0; - while (1) { - if (!(saw_b || saw_u || saw_f) && (c == 'b' || c == 'B')) - saw_b = 1; - /* Since this is a backwards compatibility support literal we don't - want to support it in arbitrary order like byte literals. */ - else if (!(saw_b || saw_u || saw_r || saw_f) - && (c == 'u'|| c == 'U')) { - saw_u = 1; - } - /* ur"" and ru"" are not supported */ - else if (!(saw_r || saw_u) && (c == 'r' || c == 'R')) { - saw_r = 1; - } - else if (!(saw_f || saw_b || saw_u) && (c == 'f' || c == 'F')) { - saw_f = 1; - } - else { - break; - } - c = tok_nextc(tok); - if (c == '"' || c == '\'') { - if (saw_f) { - goto f_string_quote; - } - goto letter_quote; - } - } - while (is_potential_identifier_char(c)) { - if (c >= 128) { - nonascii = 1; - } - c = tok_nextc(tok); - } - tok_backup(tok, c); - if (nonascii && !verify_identifier(tok)) { - return MAKE_TOKEN(ERRORTOKEN); - } - - p_start = tok->start; - p_end = tok->cur; - - /* async/await parsing block. */ - if (tok->cur - tok->start == 5 && tok->start[0] == 'a') { - /* May be an 'async' or 'await' token. For Python 3.7 or - later we recognize them unconditionally. For Python - 3.5 or 3.6 we recognize 'async' in front of 'def', and - either one inside of 'async def'. (Technically we - shouldn't recognize these at all for 3.4 or earlier, - but there's no *valid* Python 3.4 code that would be - rejected, and async functions will be rejected in a - later phase.) */ - if (!tok->async_hacks || tok->async_def) { - /* Always recognize the keywords. */ - if (memcmp(tok->start, "async", 5) == 0) { - return MAKE_TOKEN(ASYNC); - } - if (memcmp(tok->start, "await", 5) == 0) { - return MAKE_TOKEN(AWAIT); - } - } - else if (memcmp(tok->start, "async", 5) == 0) { - /* The current token is 'async'. - Look ahead one token to see if that is 'def'. */ - - struct tok_state ahead_tok; - struct token ahead_token; - _PyToken_Init(&ahead_token); - int ahead_tok_kind; - - memcpy(&ahead_tok, tok, sizeof(ahead_tok)); - ahead_tok_kind = tok_get_normal_mode(&ahead_tok, - current_tok, - &ahead_token); - - if (ahead_tok_kind == NAME - && ahead_tok.cur - ahead_tok.start == 3 - && memcmp(ahead_tok.start, "def", 3) == 0) - { - /* The next token is going to be 'def', so instead of - returning a plain NAME token, return ASYNC. */ - tok->async_def_indent = tok->indent; - tok->async_def = 1; - _PyToken_Free(&ahead_token); - return MAKE_TOKEN(ASYNC); - } - _PyToken_Free(&ahead_token); - } - } - - return MAKE_TOKEN(NAME); - } - - if (c == '\r') { - c = tok_nextc(tok); - } - - /* Newline */ - if (c == '\n') { - tok->atbol = 1; - if (blankline || tok->level > 0) { - if (tok->tok_extra_tokens) { - if (tok->comment_newline) { - tok->comment_newline = 0; - } - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(NL); - } - goto nextline; - } - if (tok->comment_newline && tok->tok_extra_tokens) { - tok->comment_newline = 0; - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(NL); - } - p_start = tok->start; - p_end = tok->cur - 1; /* Leave '\n' out of the string */ - tok->cont_line = 0; - if (tok->async_def) { - /* We're somewhere inside an 'async def' function, and - we've encountered a NEWLINE after its signature. */ - tok->async_def_nl = 1; - } - return MAKE_TOKEN(NEWLINE); - } - - /* Period or number starting with period? */ - if (c == '.') { - c = tok_nextc(tok); - if (isdigit(c)) { - goto fraction; - } else if (c == '.') { - c = tok_nextc(tok); - if (c == '.') { - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(ELLIPSIS); - } - else { - tok_backup(tok, c); - } - tok_backup(tok, '.'); - } - else { - tok_backup(tok, c); - } - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(DOT); - } - - /* Number */ - if (isdigit(c)) { - if (c == '0') { - /* Hex, octal or binary -- maybe. */ - c = tok_nextc(tok); - if (c == 'x' || c == 'X') { - /* Hex */ - c = tok_nextc(tok); - do { - if (c == '_') { - c = tok_nextc(tok); - } - if (!isxdigit(c)) { - tok_backup(tok, c); - return MAKE_TOKEN(syntaxerror(tok, "invalid hexadecimal literal")); - } - do { - c = tok_nextc(tok); - } while (isxdigit(c)); - } while (c == '_'); - if (!verify_end_of_number(tok, c, "hexadecimal")) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - else if (c == 'o' || c == 'O') { - /* Octal */ - c = tok_nextc(tok); - do { - if (c == '_') { - c = tok_nextc(tok); - } - if (c < '0' || c >= '8') { - if (isdigit(c)) { - return MAKE_TOKEN(syntaxerror(tok, - "invalid digit '%c' in octal literal", c)); - } - else { - tok_backup(tok, c); - return MAKE_TOKEN(syntaxerror(tok, "invalid octal literal")); - } - } - do { - c = tok_nextc(tok); - } while ('0' <= c && c < '8'); - } while (c == '_'); - if (isdigit(c)) { - return MAKE_TOKEN(syntaxerror(tok, - "invalid digit '%c' in octal literal", c)); - } - if (!verify_end_of_number(tok, c, "octal")) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - else if (c == 'b' || c == 'B') { - /* Binary */ - c = tok_nextc(tok); - do { - if (c == '_') { - c = tok_nextc(tok); - } - if (c != '0' && c != '1') { - if (isdigit(c)) { - return MAKE_TOKEN(syntaxerror(tok, "invalid digit '%c' in binary literal", c)); - } - else { - tok_backup(tok, c); - return MAKE_TOKEN(syntaxerror(tok, "invalid binary literal")); - } - } - do { - c = tok_nextc(tok); - } while (c == '0' || c == '1'); - } while (c == '_'); - if (isdigit(c)) { - return MAKE_TOKEN(syntaxerror(tok, "invalid digit '%c' in binary literal", c)); - } - if (!verify_end_of_number(tok, c, "binary")) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - else { - int nonzero = 0; - /* maybe old-style octal; c is first char of it */ - /* in any case, allow '0' as a literal */ - while (1) { - if (c == '_') { - c = tok_nextc(tok); - if (!isdigit(c)) { - tok_backup(tok, c); - return MAKE_TOKEN(syntaxerror(tok, "invalid decimal literal")); - } - } - if (c != '0') { - break; - } - c = tok_nextc(tok); - } - char* zeros_end = tok->cur; - if (isdigit(c)) { - nonzero = 1; - c = tok_decimal_tail(tok); - if (c == 0) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - if (c == '.') { - c = tok_nextc(tok); - goto fraction; - } - else if (c == 'e' || c == 'E') { - goto exponent; - } - else if (c == 'j' || c == 'J') { - goto imaginary; - } - else if (nonzero && !tok->tok_extra_tokens) { - /* Old-style octal: now disallowed. */ - tok_backup(tok, c); - return MAKE_TOKEN(syntaxerror_known_range( - tok, (int)(tok->start + 1 - tok->line_start), - (int)(zeros_end - tok->line_start), - "leading zeros in decimal integer " - "literals are not permitted; " - "use an 0o prefix for octal integers")); - } - if (!verify_end_of_number(tok, c, "decimal")) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - } - else { - /* Decimal */ - c = tok_decimal_tail(tok); - if (c == 0) { - return MAKE_TOKEN(ERRORTOKEN); - } - { - /* Accept floating point numbers. */ - if (c == '.') { - c = tok_nextc(tok); - fraction: - /* Fraction */ - if (isdigit(c)) { - c = tok_decimal_tail(tok); - if (c == 0) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - } - if (c == 'e' || c == 'E') { - int e; - exponent: - e = c; - /* Exponent part */ - c = tok_nextc(tok); - if (c == '+' || c == '-') { - c = tok_nextc(tok); - if (!isdigit(c)) { - tok_backup(tok, c); - return MAKE_TOKEN(syntaxerror(tok, "invalid decimal literal")); - } - } else if (!isdigit(c)) { - tok_backup(tok, c); - if (!verify_end_of_number(tok, e, "decimal")) { - return MAKE_TOKEN(ERRORTOKEN); - } - tok_backup(tok, e); - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(NUMBER); - } - c = tok_decimal_tail(tok); - if (c == 0) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - if (c == 'j' || c == 'J') { - /* Imaginary part */ - imaginary: - c = tok_nextc(tok); - if (!verify_end_of_number(tok, c, "imaginary")) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - else if (!verify_end_of_number(tok, c, "decimal")) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - } - tok_backup(tok, c); - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(NUMBER); - } - - f_string_quote: - if (((tolower(*tok->start) == 'f' || tolower(*tok->start) == 'r') && (c == '\'' || c == '"'))) { - int quote = c; - int quote_size = 1; /* 1 or 3 */ - - /* Nodes of type STRING, especially multi line strings - must be handled differently in order to get both - the starting line number and the column offset right. - (cf. issue 16806) */ - tok->first_lineno = tok->lineno; - tok->multi_line_start = tok->line_start; - - /* Find the quote size and start of string */ - int after_quote = tok_nextc(tok); - if (after_quote == quote) { - int after_after_quote = tok_nextc(tok); - if (after_after_quote == quote) { - quote_size = 3; - } - else { - // TODO: Check this - tok_backup(tok, after_after_quote); - tok_backup(tok, after_quote); - } - } - if (after_quote != quote) { - tok_backup(tok, after_quote); - } - - - p_start = tok->start; - p_end = tok->cur; - if (tok->tok_mode_stack_index + 1 >= MAXFSTRINGLEVEL) { - return MAKE_TOKEN(syntaxerror(tok, "too many nested f-strings")); - } - tokenizer_mode *the_current_tok = TOK_NEXT_MODE(tok); - the_current_tok->kind = TOK_FSTRING_MODE; - the_current_tok->f_string_quote = quote; - the_current_tok->f_string_quote_size = quote_size; - the_current_tok->f_string_start = tok->start; - the_current_tok->f_string_multi_line_start = tok->line_start; - the_current_tok->f_string_line_start = tok->lineno; - the_current_tok->f_string_start_offset = -1; - the_current_tok->f_string_multi_line_start_offset = -1; - the_current_tok->last_expr_buffer = NULL; - the_current_tok->last_expr_size = 0; - the_current_tok->last_expr_end = -1; - the_current_tok->f_string_debug = 0; - - switch (*tok->start) { - case 'F': - case 'f': - the_current_tok->f_string_raw = tolower(*(tok->start + 1)) == 'r'; - break; - case 'R': - case 'r': - the_current_tok->f_string_raw = 1; - break; - default: - Py_UNREACHABLE(); - } - - the_current_tok->curly_bracket_depth = 0; - the_current_tok->curly_bracket_expr_start_depth = -1; - return MAKE_TOKEN(FSTRING_START); - } - - letter_quote: - /* String */ - if (c == '\'' || c == '"') { - int quote = c; - int quote_size = 1; /* 1 or 3 */ - int end_quote_size = 0; - - /* Nodes of type STRING, especially multi line strings - must be handled differently in order to get both - the starting line number and the column offset right. - (cf. issue 16806) */ - tok->first_lineno = tok->lineno; - tok->multi_line_start = tok->line_start; - - /* Find the quote size and start of string */ - c = tok_nextc(tok); - if (c == quote) { - c = tok_nextc(tok); - if (c == quote) { - quote_size = 3; - } - else { - end_quote_size = 1; /* empty string found */ - } - } - if (c != quote) { - tok_backup(tok, c); - } - - /* Get rest of string */ - while (end_quote_size != quote_size) { - c = tok_nextc(tok); - if (tok->done == E_ERROR) { - return MAKE_TOKEN(ERRORTOKEN); - } - if (tok->done == E_DECODE) { - break; - } - if (c == EOF || (quote_size == 1 && c == '\n')) { - assert(tok->multi_line_start != NULL); - // shift the tok_state's location into - // the start of string, and report the error - // from the initial quote character - tok->cur = (char *)tok->start; - tok->cur++; - tok->line_start = tok->multi_line_start; - int start = tok->lineno; - tok->lineno = tok->first_lineno; - - if (INSIDE_FSTRING(tok)) { - /* When we are in an f-string, before raising the - * unterminated string literal error, check whether - * does the initial quote matches with f-strings quotes - * and if it is, then this must be a missing '}' token - * so raise the proper error */ - tokenizer_mode *the_current_tok = TOK_GET_MODE(tok); - if (the_current_tok->f_string_quote == quote && - the_current_tok->f_string_quote_size == quote_size) { - return MAKE_TOKEN(syntaxerror(tok, "f-string: expecting '}'", start)); - } - } - - if (quote_size == 3) { - syntaxerror(tok, "unterminated triple-quoted string literal" - " (detected at line %d)", start); - if (c != '\n') { - tok->done = E_EOFS; - } - return MAKE_TOKEN(ERRORTOKEN); - } - else { - syntaxerror(tok, "unterminated string literal (detected at" - " line %d)", start); - if (c != '\n') { - tok->done = E_EOLS; - } - return MAKE_TOKEN(ERRORTOKEN); - } - } - if (c == quote) { - end_quote_size += 1; - } - else { - end_quote_size = 0; - if (c == '\\') { - c = tok_nextc(tok); /* skip escaped char */ - if (c == '\r') { - c = tok_nextc(tok); - } - } - } - } - - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(STRING); - } - - /* Line continuation */ - if (c == '\\') { - if ((c = tok_continuation_line(tok)) == -1) { - return MAKE_TOKEN(ERRORTOKEN); - } - tok->cont_line = 1; - goto again; /* Read next line */ - } - - /* Punctuation character */ - int is_punctuation = (c == ':' || c == '}' || c == '!' || c == '{'); - if (is_punctuation && INSIDE_FSTRING(tok) && INSIDE_FSTRING_EXPR(current_tok)) { - /* This code block gets executed before the curly_bracket_depth is incremented - * by the `{` case, so for ensuring that we are on the 0th level, we need - * to adjust it manually */ - int cursor = current_tok->curly_bracket_depth - (c != '{'); - if (cursor == 0 && !update_fstring_expr(tok, c)) { - return MAKE_TOKEN(ENDMARKER); - } - if (cursor == 0 && c != '{' && set_fstring_expr(tok, token, c)) { - return MAKE_TOKEN(ERRORTOKEN); - } - - if (c == ':' && cursor == current_tok->curly_bracket_expr_start_depth) { - current_tok->kind = TOK_FSTRING_MODE; - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(_PyToken_OneChar(c)); - } - } - - /* Check for two-character token */ - { - int c2 = tok_nextc(tok); - int current_token = _PyToken_TwoChars(c, c2); - if (current_token != OP) { - int c3 = tok_nextc(tok); - int current_token3 = _PyToken_ThreeChars(c, c2, c3); - if (current_token3 != OP) { - current_token = current_token3; - } - else { - tok_backup(tok, c3); - } - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(current_token); - } - tok_backup(tok, c2); - } - - /* Keep track of parentheses nesting level */ - switch (c) { - case '(': - case '[': - case '{': - if (tok->level >= MAXLEVEL) { - return MAKE_TOKEN(syntaxerror(tok, "too many nested parentheses")); - } - tok->parenstack[tok->level] = c; - tok->parenlinenostack[tok->level] = tok->lineno; - tok->parencolstack[tok->level] = (int)(tok->start - tok->line_start); - tok->level++; - if (INSIDE_FSTRING(tok)) { - current_tok->curly_bracket_depth++; - } - break; - case ')': - case ']': - case '}': - if (INSIDE_FSTRING(tok) && !current_tok->curly_bracket_depth && c == '}') { - return MAKE_TOKEN(syntaxerror(tok, "f-string: single '}' is not allowed")); - } - if (!tok->tok_extra_tokens && !tok->level) { - return MAKE_TOKEN(syntaxerror(tok, "unmatched '%c'", c)); - } - if (tok->level > 0) { - tok->level--; - int opening = tok->parenstack[tok->level]; - if (!tok->tok_extra_tokens && !((opening == '(' && c == ')') || - (opening == '[' && c == ']') || - (opening == '{' && c == '}'))) { - /* If the opening bracket belongs to an f-string's expression - part (e.g. f"{)}") and the closing bracket is an arbitrary - nested expression, then instead of matching a different - syntactical construct with it; we'll throw an unmatched - parentheses error. */ - if (INSIDE_FSTRING(tok) && opening == '{') { - assert(current_tok->curly_bracket_depth >= 0); - int previous_bracket = current_tok->curly_bracket_depth - 1; - if (previous_bracket == current_tok->curly_bracket_expr_start_depth) { - return MAKE_TOKEN(syntaxerror(tok, "f-string: unmatched '%c'", c)); - } - } - if (tok->parenlinenostack[tok->level] != tok->lineno) { - return MAKE_TOKEN(syntaxerror(tok, - "closing parenthesis '%c' does not match " - "opening parenthesis '%c' on line %d", - c, opening, tok->parenlinenostack[tok->level])); - } - else { - return MAKE_TOKEN(syntaxerror(tok, - "closing parenthesis '%c' does not match " - "opening parenthesis '%c'", - c, opening)); - } - } - } - - if (INSIDE_FSTRING(tok)) { - current_tok->curly_bracket_depth--; - if (c == '}' && current_tok->curly_bracket_depth == current_tok->curly_bracket_expr_start_depth) { - current_tok->curly_bracket_expr_start_depth--; - current_tok->kind = TOK_FSTRING_MODE; - current_tok->f_string_debug = 0; - } - } - break; - default: - break; - } - - if (!Py_UNICODE_ISPRINTABLE(c)) { - return MAKE_TOKEN(syntaxerror(tok, "invalid non-printable character U+%04X", c)); - } - - if( c == '=' && INSIDE_FSTRING_EXPR(current_tok)) { - current_tok->f_string_debug = 1; - } - - /* Punctuation character */ - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(_PyToken_OneChar(c)); -} - -static int -tok_get_fstring_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct token *token) -{ - const char *p_start = NULL; - const char *p_end = NULL; - int end_quote_size = 0; - int unicode_escape = 0; - - tok->start = tok->cur; - tok->first_lineno = tok->lineno; - tok->starting_col_offset = tok->col_offset; - - // If we start with a bracket, we defer to the normal mode as there is nothing for us to tokenize - // before it. - int start_char = tok_nextc(tok); - if (start_char == '{') { - int peek1 = tok_nextc(tok); - tok_backup(tok, peek1); - tok_backup(tok, start_char); - if (peek1 != '{') { - current_tok->curly_bracket_expr_start_depth++; - if (current_tok->curly_bracket_expr_start_depth >= MAX_EXPR_NESTING) { - return MAKE_TOKEN(syntaxerror(tok, "f-string: expressions nested too deeply")); - } - TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; - return tok_get_normal_mode(tok, current_tok, token); - } - } - else { - tok_backup(tok, start_char); - } - - // Check if we are at the end of the string - for (int i = 0; i < current_tok->f_string_quote_size; i++) { - int quote = tok_nextc(tok); - if (quote != current_tok->f_string_quote) { - tok_backup(tok, quote); - goto f_string_middle; - } - } - - if (current_tok->last_expr_buffer != NULL) { - PyMem_Free(current_tok->last_expr_buffer); - current_tok->last_expr_buffer = NULL; - current_tok->last_expr_size = 0; - current_tok->last_expr_end = -1; - } - - p_start = tok->start; - p_end = tok->cur; - tok->tok_mode_stack_index--; - return MAKE_TOKEN(FSTRING_END); - -f_string_middle: - - // TODO: This is a bit of a hack, but it works for now. We need to find a better way to handle - // this. - tok->multi_line_start = tok->line_start; - while (end_quote_size != current_tok->f_string_quote_size) { - int c = tok_nextc(tok); - if (tok->done == E_ERROR) { - return MAKE_TOKEN(ERRORTOKEN); - } - if (c == EOF || (current_tok->f_string_quote_size == 1 && c == '\n')) { - if (tok->decoding_erred) { - return MAKE_TOKEN(ERRORTOKEN); - } - - assert(tok->multi_line_start != NULL); - // shift the tok_state's location into - // the start of string, and report the error - // from the initial quote character - tok->cur = (char *)current_tok->f_string_start; - tok->cur++; - tok->line_start = current_tok->f_string_multi_line_start; - int start = tok->lineno; - - tokenizer_mode *the_current_tok = TOK_GET_MODE(tok); - tok->lineno = the_current_tok->f_string_line_start; - - if (current_tok->f_string_quote_size == 3) { - return MAKE_TOKEN(syntaxerror(tok, - "unterminated triple-quoted f-string literal" - " (detected at line %d)", start)); - } - else { - return MAKE_TOKEN(syntaxerror(tok, - "unterminated f-string literal (detected at" - " line %d)", start)); - } - } - - if (c == current_tok->f_string_quote) { - end_quote_size += 1; - continue; - } else { - end_quote_size = 0; - } - - int in_format_spec = ( - current_tok->last_expr_end != -1 - && - INSIDE_FSTRING_EXPR(current_tok) - ); - if (c == '{') { - int peek = tok_nextc(tok); - if (peek != '{' || in_format_spec) { - tok_backup(tok, peek); - tok_backup(tok, c); - current_tok->curly_bracket_expr_start_depth++; - if (current_tok->curly_bracket_expr_start_depth >= MAX_EXPR_NESTING) { - return MAKE_TOKEN(syntaxerror(tok, "f-string: expressions nested too deeply")); - } - TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; - p_start = tok->start; - p_end = tok->cur; - } else { - p_start = tok->start; - p_end = tok->cur - 1; - } - return MAKE_TOKEN(FSTRING_MIDDLE); - } else if (c == '}') { - if (unicode_escape) { - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(FSTRING_MIDDLE); - } - int peek = tok_nextc(tok); - - // The tokenizer can only be in the format spec if we have already completed the expression - // scanning (indicated by the end of the expression being set) and we are not at the top level - // of the bracket stack (-1 is the top level). Since format specifiers can't legally use double - // brackets, we can bypass it here. - if (peek == '}' && !in_format_spec) { - p_start = tok->start; - p_end = tok->cur - 1; - } else { - tok_backup(tok, peek); - tok_backup(tok, c); - TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; - p_start = tok->start; - p_end = tok->cur; - } - return MAKE_TOKEN(FSTRING_MIDDLE); - } else if (c == '\\') { - int peek = tok_nextc(tok); - if (peek == '\r') { - peek = tok_nextc(tok); - } - // Special case when the backslash is right before a curly - // brace. We have to restore and return the control back - // to the loop for the next iteration. - if (peek == '{' || peek == '}') { - if (!current_tok->f_string_raw) { - if (warn_invalid_escape_sequence(tok, peek)) { - return MAKE_TOKEN(ERRORTOKEN); - } - } - tok_backup(tok, peek); - continue; - } - - if (!current_tok->f_string_raw) { - if (peek == 'N') { - /* Handle named unicode escapes (\N{BULLET}) */ - peek = tok_nextc(tok); - if (peek == '{') { - unicode_escape = 1; - } else { - tok_backup(tok, peek); - } - } - } /* else { - skip the escaped character - }*/ - } - } - - // Backup the f-string quotes to emit a final FSTRING_MIDDLE and - // add the quotes to the FSTRING_END in the next tokenizer iteration. - for (int i = 0; i < current_tok->f_string_quote_size; i++) { - tok_backup(tok, current_tok->f_string_quote); - } - p_start = tok->start; - p_end = tok->cur; - return MAKE_TOKEN(FSTRING_MIDDLE); -} - - -static int -tok_get(struct tok_state *tok, struct token *token) -{ - tokenizer_mode *current_tok = TOK_GET_MODE(tok); - if (current_tok->kind == TOK_REGULAR_MODE) { - return tok_get_normal_mode(tok, current_tok, token); - } else { - return tok_get_fstring_mode(tok, current_tok, token); - } -} - -int -_PyTokenizer_Get(struct tok_state *tok, struct token *token) -{ - int result = tok_get(tok, token); - if (tok->decoding_erred) { - result = ERRORTOKEN; - tok->done = E_DECODE; - } - return result; -} - -#if defined(__wasi__) || (defined(__EMSCRIPTEN__) && (__EMSCRIPTEN_major__ >= 3)) -// fdopen() with borrowed fd. WASI does not provide dup() and Emscripten's -// dup() emulation with open() is slow. -typedef union { - void *cookie; - int fd; -} borrowed; - -static ssize_t -borrow_read(void *cookie, char *buf, size_t size) -{ - borrowed b = {.cookie = cookie}; - return read(b.fd, (void *)buf, size); -} - -static FILE * -fdopen_borrow(int fd) { - // supports only reading. seek fails. close and write are no-ops. - cookie_io_functions_t io_cb = {borrow_read, NULL, NULL, NULL}; - borrowed b = {.fd = fd}; - return fopencookie(b.cookie, "r", io_cb); -} -#else -static FILE * -fdopen_borrow(int fd) { - fd = _Py_dup(fd); - if (fd < 0) { - return NULL; - } - return fdopen(fd, "r"); -} -#endif - -/* Get the encoding of a Python file. Check for the coding cookie and check if - the file starts with a BOM. - - _PyTokenizer_FindEncodingFilename() returns NULL when it can't find the - encoding in the first or second line of the file (in which case the encoding - should be assumed to be UTF-8). - - The char* returned is malloc'ed via PyMem_Malloc() and thus must be freed - by the caller. */ - -char * -_PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) -{ - struct tok_state *tok; - FILE *fp; - char *encoding = NULL; - - fp = fdopen_borrow(fd); - if (fp == NULL) { - return NULL; - } - tok = _PyTokenizer_FromFile(fp, NULL, NULL, NULL); - if (tok == NULL) { - fclose(fp); - return NULL; - } - if (filename != NULL) { - tok->filename = Py_NewRef(filename); - } - else { - tok->filename = PyUnicode_FromString(""); - if (tok->filename == NULL) { - fclose(fp); - _PyTokenizer_Free(tok); - return encoding; - } - } - struct token token; - // We don't want to report warnings here because it could cause infinite recursion - // if fetching the encoding shows a warning. - tok->report_warnings = 0; - while (tok->lineno < 2 && tok->done == E_OK) { - _PyToken_Init(&token); - _PyTokenizer_Get(tok, &token); - _PyToken_Free(&token); - } - fclose(fp); - if (tok->encoding) { - encoding = (char *)PyMem_Malloc(strlen(tok->encoding) + 1); - if (encoding) { - strcpy(encoding, tok->encoding); - } - } - _PyTokenizer_Free(tok); - return encoding; -} - -#ifdef Py_DEBUG -void -tok_dump(int type, char *start, char *end) -{ - fprintf(stderr, "%s", _PyParser_TokenNames[type]); - if (type == NAME || type == NUMBER || type == STRING || type == OP) - fprintf(stderr, "(%.*s)", (int)(end - start), start); -} -#endif // Py_DEBUG diff --git a/Parser/tokenizer/file_tokenizer.c b/Parser/tokenizer/file_tokenizer.c new file mode 100644 index 00000000000000..2750527da484aa --- /dev/null +++ b/Parser/tokenizer/file_tokenizer.c @@ -0,0 +1,470 @@ +#include "Python.h" +#include "pycore_call.h" +#include "pycore_import.h" +#include "pycore_fileutils.h" +#include "errcode.h" + +#ifdef HAVE_UNISTD_H +# include // lseek(), read() +#endif + +#include "helpers.h" +#include "../lexer/state.h" +#include "../lexer/lexer.h" +#include "../lexer/buffer.h" + +static int +tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) { + assert(tok->fp_interactive); + + if (!line) { + return 0; + } + + Py_ssize_t current_size = tok->interactive_src_end - tok->interactive_src_start; + Py_ssize_t line_size = strlen(line); + char last_char = line[line_size > 0 ? line_size - 1 : line_size]; + if (last_char != '\n') { + line_size += 1; + } + char* new_str = tok->interactive_src_start; + + new_str = PyMem_Realloc(new_str, current_size + line_size + 1); + if (!new_str) { + if (tok->interactive_src_start) { + PyMem_Free(tok->interactive_src_start); + } + tok->interactive_src_start = NULL; + tok->interactive_src_end = NULL; + tok->done = E_NOMEM; + return -1; + } + strcpy(new_str + current_size, line); + tok->implicit_newline = 0; + if (last_char != '\n') { + /* Last line does not end in \n, fake one */ + new_str[current_size + line_size - 1] = '\n'; + new_str[current_size + line_size] = '\0'; + tok->implicit_newline = 1; + } + tok->interactive_src_start = new_str; + tok->interactive_src_end = new_str + current_size + line_size; + return 0; +} + +static int +tok_readline_raw(struct tok_state *tok) +{ + do { + if (!_PyLexer_tok_reserve_buf(tok, BUFSIZ)) { + return 0; + } + int n_chars = (int)(tok->end - tok->inp); + size_t line_size = 0; + char *line = _Py_UniversalNewlineFgetsWithSize(tok->inp, n_chars, tok->fp, NULL, &line_size); + if (line == NULL) { + return 1; + } + if (tok->fp_interactive && + tok_concatenate_interactive_new_line(tok, line) == -1) { + return 0; + } + tok->inp += line_size; + if (tok->inp == tok->buf) { + return 0; + } + } while (tok->inp[-1] != '\n'); + return 1; +} + +static int +tok_readline_recode(struct tok_state *tok) { + PyObject *line; + const char *buf; + Py_ssize_t buflen; + line = tok->decoding_buffer; + if (line == NULL) { + line = PyObject_CallNoArgs(tok->decoding_readline); + if (line == NULL) { + _PyTokenizer_error_ret(tok); + goto error; + } + } + else { + tok->decoding_buffer = NULL; + } + buf = PyUnicode_AsUTF8AndSize(line, &buflen); + if (buf == NULL) { + _PyTokenizer_error_ret(tok); + goto error; + } + // Make room for the null terminator *and* potentially + // an extra newline character that we may need to artificially + // add. + size_t buffer_size = buflen + 2; + if (!_PyLexer_tok_reserve_buf(tok, buffer_size)) { + goto error; + } + memcpy(tok->inp, buf, buflen); + tok->inp += buflen; + *tok->inp = '\0'; + if (tok->fp_interactive && + tok_concatenate_interactive_new_line(tok, buf) == -1) { + goto error; + } + Py_DECREF(line); + return 1; +error: + Py_XDECREF(line); + return 0; +} + +/* Fetch the next byte from TOK. */ +static int fp_getc(struct tok_state *tok) { + return getc(tok->fp); +} + +/* Unfetch the last byte back into TOK. */ +static void fp_ungetc(int c, struct tok_state *tok) { + ungetc(c, tok->fp); +} + +/* Set the readline function for TOK to a StreamReader's + readline function. The StreamReader is named ENC. + + This function is called from _PyTokenizer_check_bom and _PyTokenizer_check_coding_spec. + + ENC is usually identical to the future value of tok->encoding, + except for the (currently unsupported) case of UTF-16. + + Return 1 on success, 0 on failure. */ +static int +fp_setreadl(struct tok_state *tok, const char* enc) +{ + PyObject *readline, *open, *stream; + int fd; + long pos; + + fd = fileno(tok->fp); + /* Due to buffering the file offset for fd can be different from the file + * position of tok->fp. If tok->fp was opened in text mode on Windows, + * its file position counts CRLF as one char and can't be directly mapped + * to the file offset for fd. Instead we step back one byte and read to + * the end of line.*/ + pos = ftell(tok->fp); + if (pos == -1 || + lseek(fd, (off_t)(pos > 0 ? pos - 1 : pos), SEEK_SET) == (off_t)-1) { + PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL); + return 0; + } + + open = _PyImport_GetModuleAttrString("io", "open"); + if (open == NULL) { + return 0; + } + stream = PyObject_CallFunction(open, "isisOOO", + fd, "r", -1, enc, Py_None, Py_None, Py_False); + Py_DECREF(open); + if (stream == NULL) { + return 0; + } + + readline = PyObject_GetAttr(stream, &_Py_ID(readline)); + Py_DECREF(stream); + if (readline == NULL) { + return 0; + } + Py_XSETREF(tok->decoding_readline, readline); + + if (pos > 0) { + PyObject *bufobj = _PyObject_CallNoArgs(readline); + if (bufobj == NULL) { + return 0; + } + Py_DECREF(bufobj); + } + + return 1; +} + +static int +tok_underflow_interactive(struct tok_state *tok) { + if (tok->interactive_underflow == IUNDERFLOW_STOP) { + tok->done = E_INTERACT_STOP; + return 1; + } + char *newtok = PyOS_Readline(tok->fp ? tok->fp : stdin, stdout, tok->prompt); + if (newtok != NULL) { + char *translated = _PyTokenizer_translate_newlines(newtok, 0, 0, tok); + PyMem_Free(newtok); + if (translated == NULL) { + return 0; + } + newtok = translated; + } + if (tok->encoding && newtok && *newtok) { + /* Recode to UTF-8 */ + Py_ssize_t buflen; + const char* buf; + PyObject *u = _PyTokenizer_translate_into_utf8(newtok, tok->encoding); + PyMem_Free(newtok); + if (u == NULL) { + tok->done = E_DECODE; + return 0; + } + buflen = PyBytes_GET_SIZE(u); + buf = PyBytes_AS_STRING(u); + newtok = PyMem_Malloc(buflen+1); + if (newtok == NULL) { + Py_DECREF(u); + tok->done = E_NOMEM; + return 0; + } + strcpy(newtok, buf); + Py_DECREF(u); + } + if (tok->fp_interactive && + tok_concatenate_interactive_new_line(tok, newtok) == -1) { + PyMem_Free(newtok); + return 0; + } + if (tok->nextprompt != NULL) { + tok->prompt = tok->nextprompt; + } + if (newtok == NULL) { + tok->done = E_INTR; + } + else if (*newtok == '\0') { + PyMem_Free(newtok); + tok->done = E_EOF; + } + else if (tok->start != NULL) { + Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; + _PyLexer_remember_fstring_buffers(tok); + size_t size = strlen(newtok); + ADVANCE_LINENO(); + if (!_PyLexer_tok_reserve_buf(tok, size + 1)) { + PyMem_Free(tok->buf); + tok->buf = NULL; + PyMem_Free(newtok); + return 0; + } + memcpy(tok->cur, newtok, size + 1); + PyMem_Free(newtok); + tok->inp += size; + tok->multi_line_start = tok->buf + cur_multi_line_start; + _PyLexer_restore_fstring_buffers(tok); + } + else { + _PyLexer_remember_fstring_buffers(tok); + ADVANCE_LINENO(); + PyMem_Free(tok->buf); + tok->buf = newtok; + tok->cur = tok->buf; + tok->line_start = tok->buf; + tok->inp = strchr(tok->buf, '\0'); + tok->end = tok->inp + 1; + _PyLexer_restore_fstring_buffers(tok); + } + if (tok->done != E_OK) { + if (tok->prompt != NULL) { + PySys_WriteStderr("\n"); + } + return 0; + } + + if (tok->tok_mode_stack_index && !_PyLexer_update_fstring_expr(tok, 0)) { + return 0; + } + return 1; +} + +static int +tok_underflow_file(struct tok_state *tok) { + if (tok->start == NULL && !INSIDE_FSTRING(tok)) { + tok->cur = tok->inp = tok->buf; + } + if (tok->decoding_state == STATE_INIT) { + /* We have not yet determined the encoding. + If an encoding is found, use the file-pointer + reader functions from now on. */ + if (!_PyTokenizer_check_bom(fp_getc, fp_ungetc, fp_setreadl, tok)) { + _PyTokenizer_error_ret(tok); + return 0; + } + assert(tok->decoding_state != STATE_INIT); + } + /* Read until '\n' or EOF */ + if (tok->decoding_readline != NULL) { + /* We already have a codec associated with this input. */ + if (!tok_readline_recode(tok)) { + return 0; + } + } + else { + /* We want a 'raw' read. */ + if (!tok_readline_raw(tok)) { + return 0; + } + } + if (tok->inp == tok->cur) { + tok->done = E_EOF; + return 0; + } + tok->implicit_newline = 0; + if (tok->inp[-1] != '\n') { + assert(tok->inp + 1 < tok->end); + /* Last line does not end in \n, fake one */ + *tok->inp++ = '\n'; + *tok->inp = '\0'; + tok->implicit_newline = 1; + } + + if (tok->tok_mode_stack_index && !_PyLexer_update_fstring_expr(tok, 0)) { + return 0; + } + + ADVANCE_LINENO(); + if (tok->decoding_state != STATE_NORMAL) { + if (tok->lineno > 2) { + tok->decoding_state = STATE_NORMAL; + } + else if (!_PyTokenizer_check_coding_spec(tok->cur, strlen(tok->cur), + tok, fp_setreadl)) + { + return 0; + } + } + /* The default encoding is UTF-8, so make sure we don't have any + non-UTF-8 sequences in it. */ + if (!tok->encoding && !_PyTokenizer_ensure_utf8(tok->cur, tok)) { + _PyTokenizer_error_ret(tok); + return 0; + } + assert(tok->done == E_OK); + return tok->done == E_OK; +} + +/* Set up tokenizer for file */ +struct tok_state * +_PyTokenizer_FromFile(FILE *fp, const char* enc, + const char *ps1, const char *ps2) +{ + struct tok_state *tok = _PyTokenizer_tok_new(); + if (tok == NULL) + return NULL; + if ((tok->buf = (char *)PyMem_Malloc(BUFSIZ)) == NULL) { + _PyTokenizer_Free(tok); + return NULL; + } + tok->cur = tok->inp = tok->buf; + tok->end = tok->buf + BUFSIZ; + tok->fp = fp; + tok->prompt = ps1; + tok->nextprompt = ps2; + if (ps1 || ps2) { + tok->underflow = &tok_underflow_interactive; + } else { + tok->underflow = &tok_underflow_file; + } + if (enc != NULL) { + /* Must copy encoding declaration since it + gets copied into the parse tree. */ + tok->encoding = _PyTokenizer_new_string(enc, strlen(enc), tok); + if (!tok->encoding) { + _PyTokenizer_Free(tok); + return NULL; + } + tok->decoding_state = STATE_NORMAL; + } + return tok; +} + +#if defined(__wasi__) || (defined(__EMSCRIPTEN__) && (__EMSCRIPTEN_major__ >= 3)) +// fdopen() with borrowed fd. WASI does not provide dup() and Emscripten's +// dup() emulation with open() is slow. +typedef union { + void *cookie; + int fd; +} borrowed; + +static ssize_t +borrow_read(void *cookie, char *buf, size_t size) +{ + borrowed b = {.cookie = cookie}; + return read(b.fd, (void *)buf, size); +} + +static FILE * +fdopen_borrow(int fd) { + // supports only reading. seek fails. close and write are no-ops. + cookie_io_functions_t io_cb = {borrow_read, NULL, NULL, NULL}; + borrowed b = {.fd = fd}; + return fopencookie(b.cookie, "r", io_cb); +} +#else +static FILE * +fdopen_borrow(int fd) { + fd = _Py_dup(fd); + if (fd < 0) { + return NULL; + } + return fdopen(fd, "r"); +} +#endif + +/* Get the encoding of a Python file. Check for the coding cookie and check if + the file starts with a BOM. + + _PyTokenizer_FindEncodingFilename() returns NULL when it can't find the + encoding in the first or second line of the file (in which case the encoding + should be assumed to be UTF-8). + + The char* returned is malloc'ed via PyMem_Malloc() and thus must be freed + by the caller. */ +char * +_PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) +{ + struct tok_state *tok; + FILE *fp; + char *encoding = NULL; + + fp = fdopen_borrow(fd); + if (fp == NULL) { + return NULL; + } + tok = _PyTokenizer_FromFile(fp, NULL, NULL, NULL); + if (tok == NULL) { + fclose(fp); + return NULL; + } + if (filename != NULL) { + tok->filename = Py_NewRef(filename); + } + else { + tok->filename = PyUnicode_FromString(""); + if (tok->filename == NULL) { + fclose(fp); + _PyTokenizer_Free(tok); + return encoding; + } + } + struct token token; + // We don't want to report warnings here because it could cause infinite recursion + // if fetching the encoding shows a warning. + tok->report_warnings = 0; + while (tok->lineno < 2 && tok->done == E_OK) { + _PyToken_Init(&token); + _PyTokenizer_Get(tok, &token); + _PyToken_Free(&token); + } + fclose(fp); + if (tok->encoding) { + encoding = (char *)PyMem_Malloc(strlen(tok->encoding) + 1); + if (encoding) { + strcpy(encoding, tok->encoding); + } + } + _PyTokenizer_Free(tok); + return encoding; +} diff --git a/Parser/tokenizer/helpers.c b/Parser/tokenizer/helpers.c new file mode 100644 index 00000000000000..9c9d05bbef0f1a --- /dev/null +++ b/Parser/tokenizer/helpers.c @@ -0,0 +1,552 @@ +#include "Python.h" +#include "errcode.h" +#include "pycore_token.h" + +#include "../lexer/state.h" + + +/* ############## ERRORS ############## */ + +static int +_syntaxerror_range(struct tok_state *tok, const char *format, + int col_offset, int end_col_offset, + va_list vargs) +{ + // In release builds, we don't want to overwrite a previous error, but in debug builds we + // want to fail if we are not doing it so we can fix it. + assert(tok->done != E_ERROR); + if (tok->done == E_ERROR) { + return ERRORTOKEN; + } + PyObject *errmsg, *errtext, *args; + errmsg = PyUnicode_FromFormatV(format, vargs); + if (!errmsg) { + goto error; + } + + errtext = PyUnicode_DecodeUTF8(tok->line_start, tok->cur - tok->line_start, + "replace"); + if (!errtext) { + goto error; + } + + if (col_offset == -1) { + col_offset = (int)PyUnicode_GET_LENGTH(errtext); + } + if (end_col_offset == -1) { + end_col_offset = col_offset; + } + + Py_ssize_t line_len = strcspn(tok->line_start, "\n"); + if (line_len != tok->cur - tok->line_start) { + Py_DECREF(errtext); + errtext = PyUnicode_DecodeUTF8(tok->line_start, line_len, + "replace"); + } + if (!errtext) { + goto error; + } + + args = Py_BuildValue("(O(OiiNii))", errmsg, tok->filename, tok->lineno, + col_offset, errtext, tok->lineno, end_col_offset); + if (args) { + PyErr_SetObject(PyExc_SyntaxError, args); + Py_DECREF(args); + } + +error: + Py_XDECREF(errmsg); + tok->done = E_ERROR; + return ERRORTOKEN; +} + +int +_PyTokenizer_syntaxerror(struct tok_state *tok, const char *format, ...) +{ + // This errors are cleaned on startup. Todo: Fix it. + va_list vargs; + va_start(vargs, format); + int ret = _syntaxerror_range(tok, format, -1, -1, vargs); + va_end(vargs); + return ret; +} + +int +_PyTokenizer_syntaxerror_known_range(struct tok_state *tok, + int col_offset, int end_col_offset, + const char *format, ...) +{ + va_list vargs; + va_start(vargs, format); + int ret = _syntaxerror_range(tok, format, col_offset, end_col_offset, vargs); + va_end(vargs); + return ret; +} + +int +_PyTokenizer_indenterror(struct tok_state *tok) +{ + tok->done = E_TABSPACE; + tok->cur = tok->inp; + return ERRORTOKEN; +} + +char * +_PyTokenizer_error_ret(struct tok_state *tok) /* XXX */ +{ + tok->decoding_erred = 1; + if ((tok->fp != NULL || tok->readline != NULL) && tok->buf != NULL) {/* see _PyTokenizer_Free */ + PyMem_Free(tok->buf); + } + tok->buf = tok->cur = tok->inp = NULL; + tok->start = NULL; + tok->end = NULL; + tok->done = E_DECODE; + return NULL; /* as if it were EOF */ +} + +int +_PyTokenizer_warn_invalid_escape_sequence(struct tok_state *tok, int first_invalid_escape_char) +{ + if (!tok->report_warnings) { + return 0; + } + + PyObject *msg = PyUnicode_FromFormat( + "invalid escape sequence '\\%c'", + (char) first_invalid_escape_char + ); + + if (msg == NULL) { + return -1; + } + + if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, tok->filename, + tok->lineno, NULL, NULL) < 0) { + Py_DECREF(msg); + + if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { + /* Replace the SyntaxWarning exception with a SyntaxError + to get a more accurate error report */ + PyErr_Clear(); + return _PyTokenizer_syntaxerror(tok, "invalid escape sequence '\\%c'", (char) first_invalid_escape_char); + } + + return -1; + } + + Py_DECREF(msg); + return 0; +} + +int +_PyTokenizer_parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...) +{ + if (!tok->report_warnings) { + return 0; + } + + PyObject *errmsg; + va_list vargs; + va_start(vargs, format); + errmsg = PyUnicode_FromFormatV(format, vargs); + va_end(vargs); + if (!errmsg) { + goto error; + } + + if (PyErr_WarnExplicitObject(category, errmsg, tok->filename, + tok->lineno, NULL, NULL) < 0) { + if (PyErr_ExceptionMatches(category)) { + /* Replace the DeprecationWarning exception with a SyntaxError + to get a more accurate error report */ + PyErr_Clear(); + _PyTokenizer_syntaxerror(tok, "%U", errmsg); + } + goto error; + } + Py_DECREF(errmsg); + return 0; + +error: + Py_XDECREF(errmsg); + tok->done = E_ERROR; + return -1; +} + + +/* ############## STRING MANIPULATION ############## */ + +char * +_PyTokenizer_new_string(const char *s, Py_ssize_t len, struct tok_state *tok) +{ + char* result = (char *)PyMem_Malloc(len + 1); + if (!result) { + tok->done = E_NOMEM; + return NULL; + } + memcpy(result, s, len); + result[len] = '\0'; + return result; +} + +PyObject * +_PyTokenizer_translate_into_utf8(const char* str, const char* enc) { + PyObject *utf8; + PyObject* buf = PyUnicode_Decode(str, strlen(str), enc, NULL); + if (buf == NULL) + return NULL; + utf8 = PyUnicode_AsUTF8String(buf); + Py_DECREF(buf); + return utf8; +} + +char * +_PyTokenizer_translate_newlines(const char *s, int exec_input, int preserve_crlf, + struct tok_state *tok) { + int skip_next_lf = 0; + size_t needed_length = strlen(s) + 2, final_length; + char *buf, *current; + char c = '\0'; + buf = PyMem_Malloc(needed_length); + if (buf == NULL) { + tok->done = E_NOMEM; + return NULL; + } + for (current = buf; *s; s++, current++) { + c = *s; + if (skip_next_lf) { + skip_next_lf = 0; + if (c == '\n') { + c = *++s; + if (!c) + break; + } + } + if (!preserve_crlf && c == '\r') { + skip_next_lf = 1; + c = '\n'; + } + *current = c; + } + /* If this is exec input, add a newline to the end of the string if + there isn't one already. */ + if (exec_input && c != '\n' && c != '\0') { + *current = '\n'; + current++; + } + *current = '\0'; + final_length = current - buf + 1; + if (final_length < needed_length && final_length) { + /* should never fail */ + char* result = PyMem_Realloc(buf, final_length); + if (result == NULL) { + PyMem_Free(buf); + } + buf = result; + } + return buf; +} + +/* ############## ENCODING STUFF ############## */ + + +/* See whether the file starts with a BOM. If it does, + invoke the set_readline function with the new encoding. + Return 1 on success, 0 on failure. */ +int +_PyTokenizer_check_bom(int get_char(struct tok_state *), + void unget_char(int, struct tok_state *), + int set_readline(struct tok_state *, const char *), + struct tok_state *tok) +{ + int ch1, ch2, ch3; + ch1 = get_char(tok); + tok->decoding_state = STATE_SEEK_CODING; + if (ch1 == EOF) { + return 1; + } else if (ch1 == 0xEF) { + ch2 = get_char(tok); + if (ch2 != 0xBB) { + unget_char(ch2, tok); + unget_char(ch1, tok); + return 1; + } + ch3 = get_char(tok); + if (ch3 != 0xBF) { + unget_char(ch3, tok); + unget_char(ch2, tok); + unget_char(ch1, tok); + return 1; + } + } else { + unget_char(ch1, tok); + return 1; + } + if (tok->encoding != NULL) + PyMem_Free(tok->encoding); + tok->encoding = _PyTokenizer_new_string("utf-8", 5, tok); + if (!tok->encoding) + return 0; + /* No need to set_readline: input is already utf-8 */ + return 1; +} + +static const char * +get_normal_name(const char *s) /* for utf-8 and latin-1 */ +{ + char buf[13]; + int i; + for (i = 0; i < 12; i++) { + int c = s[i]; + if (c == '\0') + break; + else if (c == '_') + buf[i] = '-'; + else + buf[i] = Py_TOLOWER(c); + } + buf[i] = '\0'; + if (strcmp(buf, "utf-8") == 0 || + strncmp(buf, "utf-8-", 6) == 0) + return "utf-8"; + else if (strcmp(buf, "latin-1") == 0 || + strcmp(buf, "iso-8859-1") == 0 || + strcmp(buf, "iso-latin-1") == 0 || + strncmp(buf, "latin-1-", 8) == 0 || + strncmp(buf, "iso-8859-1-", 11) == 0 || + strncmp(buf, "iso-latin-1-", 12) == 0) + return "iso-8859-1"; + else + return s; +} + +/* Return the coding spec in S, or NULL if none is found. */ +static int +get_coding_spec(const char *s, char **spec, Py_ssize_t size, struct tok_state *tok) +{ + Py_ssize_t i; + *spec = NULL; + /* Coding spec must be in a comment, and that comment must be + * the only statement on the source code line. */ + for (i = 0; i < size - 6; i++) { + if (s[i] == '#') + break; + if (s[i] != ' ' && s[i] != '\t' && s[i] != '\014') + return 1; + } + for (; i < size - 6; i++) { /* XXX inefficient search */ + const char* t = s + i; + if (memcmp(t, "coding", 6) == 0) { + const char* begin = NULL; + t += 6; + if (t[0] != ':' && t[0] != '=') + continue; + do { + t++; + } while (t[0] == ' ' || t[0] == '\t'); + + begin = t; + while (Py_ISALNUM(t[0]) || + t[0] == '-' || t[0] == '_' || t[0] == '.') + t++; + + if (begin < t) { + char* r = _PyTokenizer_new_string(begin, t - begin, tok); + const char* q; + if (!r) + return 0; + q = get_normal_name(r); + if (r != q) { + PyMem_Free(r); + r = _PyTokenizer_new_string(q, strlen(q), tok); + if (!r) + return 0; + } + *spec = r; + break; + } + } + } + return 1; +} + +/* Check whether the line contains a coding spec. If it does, + invoke the set_readline function for the new encoding. + This function receives the tok_state and the new encoding. + Return 1 on success, 0 on failure. */ +int +_PyTokenizer_check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, + int set_readline(struct tok_state *, const char *)) +{ + char *cs; + if (tok->cont_line) { + /* It's a continuation line, so it can't be a coding spec. */ + tok->decoding_state = STATE_NORMAL; + return 1; + } + if (!get_coding_spec(line, &cs, size, tok)) { + return 0; + } + if (!cs) { + Py_ssize_t i; + for (i = 0; i < size; i++) { + if (line[i] == '#' || line[i] == '\n' || line[i] == '\r') + break; + if (line[i] != ' ' && line[i] != '\t' && line[i] != '\014') { + /* Stop checking coding spec after a line containing + * anything except a comment. */ + tok->decoding_state = STATE_NORMAL; + break; + } + } + return 1; + } + tok->decoding_state = STATE_NORMAL; + if (tok->encoding == NULL) { + assert(tok->decoding_readline == NULL); + if (strcmp(cs, "utf-8") != 0 && !set_readline(tok, cs)) { + _PyTokenizer_error_ret(tok); + PyErr_Format(PyExc_SyntaxError, "encoding problem: %s", cs); + PyMem_Free(cs); + return 0; + } + tok->encoding = cs; + } else { /* then, compare cs with BOM */ + if (strcmp(tok->encoding, cs) != 0) { + _PyTokenizer_error_ret(tok); + PyErr_Format(PyExc_SyntaxError, + "encoding problem: %s with BOM", cs); + PyMem_Free(cs); + return 0; + } + PyMem_Free(cs); + } + return 1; +} + +/* Check whether the characters at s start a valid + UTF-8 sequence. Return the number of characters forming + the sequence if yes, 0 if not. The special cases match + those in stringlib/codecs.h:utf8_decode. +*/ +static int +valid_utf8(const unsigned char* s) +{ + int expected = 0; + int length; + if (*s < 0x80) { + /* single-byte code */ + return 1; + } + else if (*s < 0xE0) { + /* \xC2\x80-\xDF\xBF -- 0080-07FF */ + if (*s < 0xC2) { + /* invalid sequence + \x80-\xBF -- continuation byte + \xC0-\xC1 -- fake 0000-007F */ + return 0; + } + expected = 1; + } + else if (*s < 0xF0) { + /* \xE0\xA0\x80-\xEF\xBF\xBF -- 0800-FFFF */ + if (*s == 0xE0 && *(s + 1) < 0xA0) { + /* invalid sequence + \xE0\x80\x80-\xE0\x9F\xBF -- fake 0000-0800 */ + return 0; + } + else if (*s == 0xED && *(s + 1) >= 0xA0) { + /* Decoding UTF-8 sequences in range \xED\xA0\x80-\xED\xBF\xBF + will result in surrogates in range D800-DFFF. Surrogates are + not valid UTF-8 so they are rejected. + See https://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */ + return 0; + } + expected = 2; + } + else if (*s < 0xF5) { + /* \xF0\x90\x80\x80-\xF4\x8F\xBF\xBF -- 10000-10FFFF */ + if (*(s + 1) < 0x90 ? *s == 0xF0 : *s == 0xF4) { + /* invalid sequence -- one of: + \xF0\x80\x80\x80-\xF0\x8F\xBF\xBF -- fake 0000-FFFF + \xF4\x90\x80\x80- -- 110000- overflow */ + return 0; + } + expected = 3; + } + else { + /* invalid start byte */ + return 0; + } + length = expected + 1; + for (; expected; expected--) + if (s[expected] < 0x80 || s[expected] >= 0xC0) + return 0; + return length; +} + +int +_PyTokenizer_ensure_utf8(char *line, struct tok_state *tok) +{ + int badchar = 0; + unsigned char *c; + int length; + for (c = (unsigned char *)line; *c; c += length) { + if (!(length = valid_utf8(c))) { + badchar = *c; + break; + } + } + if (badchar) { + PyErr_Format(PyExc_SyntaxError, + "Non-UTF-8 code starting with '\\x%.2x' " + "in file %U on line %i, " + "but no encoding declared; " + "see https://peps.python.org/pep-0263/ for details", + badchar, tok->filename, tok->lineno); + return 0; + } + return 1; +} + + +/* ############## DEBUGGING STUFF ############## */ + +#ifdef Py_DEBUG +void +_PyTokenizer_print_escape(FILE *f, const char *s, Py_ssize_t size) +{ + if (s == NULL) { + fputs("NULL", f); + return; + } + putc('"', f); + while (size-- > 0) { + unsigned char c = *s++; + switch (c) { + case '\n': fputs("\\n", f); break; + case '\r': fputs("\\r", f); break; + case '\t': fputs("\\t", f); break; + case '\f': fputs("\\f", f); break; + case '\'': fputs("\\'", f); break; + case '"': fputs("\\\"", f); break; + default: + if (0x20 <= c && c <= 0x7f) + putc(c, f); + else + fprintf(f, "\\x%02x", c); + } + } + putc('"', f); +} + +void +_PyTokenizer_tok_dump(int type, char *start, char *end) +{ + fprintf(stderr, "%s", _PyParser_TokenNames[type]); + if (type == NAME || type == NUMBER || type == STRING || type == OP) + fprintf(stderr, "(%.*s)", (int)(end - start), start); +} +#endif diff --git a/Parser/tokenizer/helpers.h b/Parser/tokenizer/helpers.h new file mode 100644 index 00000000000000..42ea13cd1f853f --- /dev/null +++ b/Parser/tokenizer/helpers.h @@ -0,0 +1,37 @@ +#ifndef _PY_TOKENIZER_HELPERS_H_ +#define _PY_TOKENIZER_HELPERS_H_ + +#include "Python.h" + +#include "../lexer/state.h" + +#define ADVANCE_LINENO() \ + tok->lineno++; \ + tok->col_offset = 0; + +int _PyTokenizer_syntaxerror(struct tok_state *tok, const char *format, ...); +int _PyTokenizer_syntaxerror_known_range(struct tok_state *tok, int col_offset, int end_col_offset, const char *format, ...); +int _PyTokenizer_indenterror(struct tok_state *tok); +int _PyTokenizer_warn_invalid_escape_sequence(struct tok_state *tok, int first_invalid_escape_char); +int _PyTokenizer_parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...); +char *_PyTokenizer_error_ret(struct tok_state *tok); + +char *_PyTokenizer_new_string(const char *s, Py_ssize_t len, struct tok_state *tok); +char *_PyTokenizer_translate_newlines(const char *s, int exec_input, int preserve_crlf, struct tok_state *tok); +PyObject *_PyTokenizer_translate_into_utf8(const char* str, const char* enc); + +int _PyTokenizer_check_bom(int get_char(struct tok_state *), + void unget_char(int, struct tok_state *), + int set_readline(struct tok_state *, const char *), + struct tok_state *tok); +int _PyTokenizer_check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, + int set_readline(struct tok_state *, const char *)); +int _PyTokenizer_ensure_utf8(char *line, struct tok_state *tok); + +#ifdef Py_DEBUG +void _PyTokenizer_print_escape(FILE *f, const char *s, Py_ssize_t size); +void _PyTokenizer_tok_dump(int type, char *start, char *end); +#endif + + +#endif diff --git a/Parser/tokenizer/readline_tokenizer.c b/Parser/tokenizer/readline_tokenizer.c new file mode 100644 index 00000000000000..a2637af9902dd3 --- /dev/null +++ b/Parser/tokenizer/readline_tokenizer.c @@ -0,0 +1,134 @@ +#include "Python.h" +#include "errcode.h" + +#include "helpers.h" +#include "../lexer/lexer.h" +#include "../lexer/state.h" +#include "../lexer/buffer.h" + +static int +tok_readline_string(struct tok_state* tok) { + PyObject* line = NULL; + PyObject* raw_line = PyObject_CallNoArgs(tok->readline); + if (raw_line == NULL) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) { + PyErr_Clear(); + return 1; + } + _PyTokenizer_error_ret(tok); + goto error; + } + if(tok->encoding != NULL) { + if (!PyBytes_Check(raw_line)) { + PyErr_Format(PyExc_TypeError, "readline() returned a non-bytes object"); + _PyTokenizer_error_ret(tok); + goto error; + } + line = PyUnicode_Decode(PyBytes_AS_STRING(raw_line), PyBytes_GET_SIZE(raw_line), + tok->encoding, "replace"); + Py_CLEAR(raw_line); + if (line == NULL) { + _PyTokenizer_error_ret(tok); + goto error; + } + } else { + if(!PyUnicode_Check(raw_line)) { + PyErr_Format(PyExc_TypeError, "readline() returned a non-string object"); + _PyTokenizer_error_ret(tok); + goto error; + } + line = raw_line; + raw_line = NULL; + } + Py_ssize_t buflen; + const char* buf = PyUnicode_AsUTF8AndSize(line, &buflen); + if (buf == NULL) { + _PyTokenizer_error_ret(tok); + goto error; + } + + // Make room for the null terminator *and* potentially + // an extra newline character that we may need to artificially + // add. + size_t buffer_size = buflen + 2; + if (!_PyLexer_tok_reserve_buf(tok, buffer_size)) { + goto error; + } + memcpy(tok->inp, buf, buflen); + tok->inp += buflen; + *tok->inp = '\0'; + + tok->line_start = tok->cur; + Py_DECREF(line); + return 1; +error: + Py_XDECREF(raw_line); + Py_XDECREF(line); + return 0; +} + +static int +tok_underflow_readline(struct tok_state* tok) { + assert(tok->decoding_state == STATE_NORMAL); + assert(tok->fp == NULL && tok->input == NULL && tok->decoding_readline == NULL); + if (tok->start == NULL && !INSIDE_FSTRING(tok)) { + tok->cur = tok->inp = tok->buf; + } + if (!tok_readline_string(tok)) { + return 0; + } + if (tok->inp == tok->cur) { + tok->done = E_EOF; + return 0; + } + tok->implicit_newline = 0; + if (tok->inp[-1] != '\n') { + assert(tok->inp + 1 < tok->end); + /* Last line does not end in \n, fake one */ + *tok->inp++ = '\n'; + *tok->inp = '\0'; + tok->implicit_newline = 1; + } + + if (tok->tok_mode_stack_index && !_PyLexer_update_fstring_expr(tok, 0)) { + return 0; + } + + ADVANCE_LINENO(); + /* The default encoding is UTF-8, so make sure we don't have any + non-UTF-8 sequences in it. */ + if (!tok->encoding && !_PyTokenizer_ensure_utf8(tok->cur, tok)) { + _PyTokenizer_error_ret(tok); + return 0; + } + assert(tok->done == E_OK); + return tok->done == E_OK; +} + +struct tok_state * +_PyTokenizer_FromReadline(PyObject* readline, const char* enc, + int exec_input, int preserve_crlf) +{ + struct tok_state *tok = _PyTokenizer_tok_new(); + if (tok == NULL) + return NULL; + if ((tok->buf = (char *)PyMem_Malloc(BUFSIZ)) == NULL) { + _PyTokenizer_Free(tok); + return NULL; + } + tok->cur = tok->inp = tok->buf; + tok->end = tok->buf + BUFSIZ; + tok->fp = NULL; + if (enc != NULL) { + tok->encoding = _PyTokenizer_new_string(enc, strlen(enc), tok); + if (!tok->encoding) { + _PyTokenizer_Free(tok); + return NULL; + } + } + tok->decoding_state = STATE_NORMAL; + tok->underflow = &tok_underflow_readline; + Py_INCREF(readline); + tok->readline = readline; + return tok; +} diff --git a/Parser/tokenizer/string_tokenizer.c b/Parser/tokenizer/string_tokenizer.c new file mode 100644 index 00000000000000..0c26d5df8d4a40 --- /dev/null +++ b/Parser/tokenizer/string_tokenizer.c @@ -0,0 +1,129 @@ +#include "Python.h" +#include "errcode.h" + +#include "helpers.h" +#include "../lexer/state.h" + +static int +tok_underflow_string(struct tok_state *tok) { + char *end = strchr(tok->inp, '\n'); + if (end != NULL) { + end++; + } + else { + end = strchr(tok->inp, '\0'); + if (end == tok->inp) { + tok->done = E_EOF; + return 0; + } + } + if (tok->start == NULL) { + tok->buf = tok->cur; + } + tok->line_start = tok->cur; + ADVANCE_LINENO(); + tok->inp = end; + return 1; +} + +/* Fetch a byte from TOK, using the string buffer. */ +static int +buf_getc(struct tok_state *tok) { + return Py_CHARMASK(*tok->str++); +} + +/* Unfetch a byte from TOK, using the string buffer. */ +static void +buf_ungetc(int c, struct tok_state *tok) { + tok->str--; + assert(Py_CHARMASK(*tok->str) == c); /* tok->cur may point to read-only segment */ +} + +/* Set the readline function for TOK to ENC. For the string-based + tokenizer, this means to just record the encoding. */ +static int +buf_setreadl(struct tok_state *tok, const char* enc) { + tok->enc = enc; + return 1; +} + +/* Decode a byte string STR for use as the buffer of TOK. + Look for encoding declarations inside STR, and record them + inside TOK. */ +static char * +decode_str(const char *input, int single, struct tok_state *tok, int preserve_crlf) +{ + PyObject* utf8 = NULL; + char *str; + const char *s; + const char *newl[2] = {NULL, NULL}; + int lineno = 0; + tok->input = str = _PyTokenizer_translate_newlines(input, single, preserve_crlf, tok); + if (str == NULL) + return NULL; + tok->enc = NULL; + tok->str = str; + if (!_PyTokenizer_check_bom(buf_getc, buf_ungetc, buf_setreadl, tok)) + return _PyTokenizer_error_ret(tok); + str = tok->str; /* string after BOM if any */ + assert(str); + if (tok->enc != NULL) { + utf8 = _PyTokenizer_translate_into_utf8(str, tok->enc); + if (utf8 == NULL) + return _PyTokenizer_error_ret(tok); + str = PyBytes_AsString(utf8); + } + for (s = str;; s++) { + if (*s == '\0') break; + else if (*s == '\n') { + assert(lineno < 2); + newl[lineno] = s; + lineno++; + if (lineno == 2) break; + } + } + tok->enc = NULL; + /* need to check line 1 and 2 separately since check_coding_spec + assumes a single line as input */ + if (newl[0]) { + if (!_PyTokenizer_check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) { + return NULL; + } + if (tok->enc == NULL && tok->decoding_state != STATE_NORMAL && newl[1]) { + if (!_PyTokenizer_check_coding_spec(newl[0]+1, newl[1] - newl[0], + tok, buf_setreadl)) + return NULL; + } + } + if (tok->enc != NULL) { + assert(utf8 == NULL); + utf8 = _PyTokenizer_translate_into_utf8(str, tok->enc); + if (utf8 == NULL) + return _PyTokenizer_error_ret(tok); + str = PyBytes_AS_STRING(utf8); + } + assert(tok->decoding_buffer == NULL); + tok->decoding_buffer = utf8; /* CAUTION */ + return str; +} + +/* Set up tokenizer for string */ +struct tok_state * +_PyTokenizer_FromString(const char *str, int exec_input, int preserve_crlf) +{ + struct tok_state *tok = _PyTokenizer_tok_new(); + char *decoded; + + if (tok == NULL) + return NULL; + decoded = decode_str(str, exec_input, tok, preserve_crlf); + if (decoded == NULL) { + _PyTokenizer_Free(tok); + return NULL; + } + + tok->buf = tok->cur = tok->inp = decoded; + tok->end = decoded; + tok->underflow = &tok_underflow_string; + return tok; +} diff --git a/Parser/tokenizer/tokenizer.h b/Parser/tokenizer/tokenizer.h new file mode 100644 index 00000000000000..8fbeb2d6ae6df1 --- /dev/null +++ b/Parser/tokenizer/tokenizer.h @@ -0,0 +1,14 @@ +#ifndef Py_TOKENIZER_H +#define Py_TOKENIZER_H + +#include "Python.h" + +struct tok_state *_PyTokenizer_FromString(const char *, int, int); +struct tok_state *_PyTokenizer_FromUTF8(const char *, int, int); +struct tok_state *_PyTokenizer_FromReadline(PyObject*, const char*, int, int); +struct tok_state *_PyTokenizer_FromFile(FILE *, const char*, + const char *, const char *); + +#define tok_dump _Py_tok_dump + +#endif /* !Py_TOKENIZER_H */ diff --git a/Parser/tokenizer/utf8_tokenizer.c b/Parser/tokenizer/utf8_tokenizer.c new file mode 100644 index 00000000000000..1a925f445400fa --- /dev/null +++ b/Parser/tokenizer/utf8_tokenizer.c @@ -0,0 +1,55 @@ +#include "Python.h" +#include "errcode.h" + +#include "helpers.h" +#include "../lexer/state.h" + +static int +tok_underflow_string(struct tok_state *tok) { + char *end = strchr(tok->inp, '\n'); + if (end != NULL) { + end++; + } + else { + end = strchr(tok->inp, '\0'); + if (end == tok->inp) { + tok->done = E_EOF; + return 0; + } + } + if (tok->start == NULL) { + tok->buf = tok->cur; + } + tok->line_start = tok->cur; + ADVANCE_LINENO(); + tok->inp = end; + return 1; +} + +/* Set up tokenizer for UTF-8 string */ +struct tok_state * +_PyTokenizer_FromUTF8(const char *str, int exec_input, int preserve_crlf) +{ + struct tok_state *tok = _PyTokenizer_tok_new(); + char *translated; + if (tok == NULL) + return NULL; + tok->input = translated = _PyTokenizer_translate_newlines(str, exec_input, preserve_crlf, tok); + if (translated == NULL) { + _PyTokenizer_Free(tok); + return NULL; + } + tok->decoding_state = STATE_NORMAL; + tok->enc = NULL; + tok->str = translated; + tok->encoding = _PyTokenizer_new_string("utf-8", 5, tok); + if (!tok->encoding) { + _PyTokenizer_Free(tok); + return NULL; + } + + tok->buf = tok->cur = tok->inp = translated; + tok->end = translated; + tok->underflow = &tok_underflow_string; + return tok; +} diff --git a/Programs/_bootstrap_python.c b/Programs/_bootstrap_python.c index 6c388fc7033dd0..34f79191b4e8d7 100644 --- a/Programs/_bootstrap_python.c +++ b/Programs/_bootstrap_python.c @@ -15,8 +15,6 @@ #include "Python/frozen_modules/zipimport.h" /* End includes */ -uint32_t _Py_next_func_version = 1; - /* Empty initializer for deepfrozen modules */ int _Py_Deepfreeze_Init(void) { diff --git a/Programs/_freeze_module.c b/Programs/_freeze_module.c index e55f1d56745c4d..3de6c6816c1e61 100644 --- a/Programs/_freeze_module.c +++ b/Programs/_freeze_module.c @@ -19,11 +19,9 @@ #include #include #ifndef MS_WINDOWS -#include +# include #endif -uint32_t _Py_next_func_version = 1; - /* Empty initializer for deepfrozen modules */ int _Py_Deepfreeze_Init(void) { diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 351cdc302e8cb0..1f9aa4b3d449a1 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -237,6 +237,11 @@ static void check_stdio_details(const wchar_t *encoding, const wchar_t *errors) if (errors) { config_set_string(&config, &config.stdio_errors, errors); } +#ifdef MS_WINDOWS + // gh-106659: On Windows, don't use _io._WindowsConsoleIO which always + // announce UTF-8 for sys.stdin.encoding. + config.legacy_windows_stdio = 1; +#endif config_set_program_name(&config); init_from_config_clear(&config); @@ -703,9 +708,14 @@ static int test_init_from_config(void) config.pathconfig_warnings = 0; config.safe_path = 1; +#ifdef Py_STATS + putenv("PYTHONSTATS="); + config._pystats = 1; +#endif putenv("PYTHONINTMAXSTRDIGITS=6666"); config.int_max_str_digits = 31337; + config.cpu_count = 4321; init_from_config_clear(&config); @@ -773,6 +783,9 @@ static void set_most_env_vars(void) putenv("PYTHONPLATLIBDIR=env_platlibdir"); putenv("PYTHONSAFEPATH=1"); putenv("PYTHONINTMAXSTRDIGITS=4567"); +#ifdef Py_STATS + putenv("PYTHONSTATS=1"); +#endif } @@ -1266,11 +1279,16 @@ static int _test_audit(Py_ssize_t setValue) printf("Set event failed"); return 4; } + if (PyErr_Occurred()) { + printf("Exception raised"); + return 5; + } if (sawSet != 42) { printf("Failed to see *userData change\n"); - return 5; + return 6; } + return 0; } @@ -1284,6 +1302,57 @@ static int test_audit(void) return result; } +static int test_audit_tuple(void) +{ +#define ASSERT(TEST, EXITCODE) \ + if (!(TEST)) { \ + printf("ERROR test failed at %s:%i\n", __FILE__, __LINE__); \ + return (EXITCODE); \ + } + + Py_ssize_t sawSet = 0; + + // we need at least one hook, otherwise code checking for + // PySys_AuditTuple() is skipped. + PySys_AddAuditHook(_audit_hook, &sawSet); + _testembed_Py_InitializeFromConfig(); + + ASSERT(!PyErr_Occurred(), 0); + + // pass Python tuple object + PyObject *tuple = Py_BuildValue("(i)", 444); + if (tuple == NULL) { + goto error; + } + ASSERT(PySys_AuditTuple("_testembed.set", tuple) == 0, 10); + ASSERT(!PyErr_Occurred(), 11); + ASSERT(sawSet == 444, 12); + Py_DECREF(tuple); + + // pass Python int object + PyObject *int_arg = PyLong_FromLong(555); + if (int_arg == NULL) { + goto error; + } + ASSERT(PySys_AuditTuple("_testembed.set", int_arg) == -1, 20); + ASSERT(PyErr_ExceptionMatches(PyExc_TypeError), 21); + PyErr_Clear(); + Py_DECREF(int_arg); + + // NULL is accepted and means "no arguments" + ASSERT(PySys_AuditTuple("_testembed.test_audit_tuple", NULL) == 0, 30); + ASSERT(!PyErr_Occurred(), 31); + + Py_Finalize(); + return 0; + +error: + PyErr_Print(); + return 1; + +#undef ASSERT +} + static volatile int _audit_subinterpreter_interpreter_count = 0; static int _audit_subinterpreter_hook(const char *event, PyObject *args, void *userdata) @@ -2128,6 +2197,7 @@ static struct TestCase TestCases[] = { // Audit {"test_open_code_hook", test_open_code_hook}, {"test_audit", test_audit}, + {"test_audit_tuple", test_audit_tuple}, {"test_audit_subinterpreter", test_audit_subinterpreter}, {"test_audit_run_command", test_audit_run_command}, {"test_audit_run_file", test_audit_run_file}, diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 9058327e846dc3..4fb78cf632d70e 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,17 +1,17 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,0,0,0,0,243,164,0,0,0,151,0,100,0,100,1, - 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, - 100,2,171,1,0,0,0,0,0,0,1,0,2,0,101,2, - 100,3,101,0,106,6,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,171,2,0,0,0,0,0,0, - 1,0,2,0,101,1,106,8,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,171,0,0,0,0,0, - 0,0,100,4,25,0,0,0,90,5,100,5,68,0,93,20, - 0,0,90,6,2,0,101,2,100,6,101,6,40,0,100,7, - 101,5,101,6,25,0,0,0,40,0,157,4,171,1,0,0, - 0,0,0,0,1,0,140,22,0,0,4,0,121,1,41,8, + 0,0,0,0,0,243,164,0,0,0,149,0,83,0,83,1, + 75,0,114,0,83,0,83,1,75,1,114,1,92,2,34,0, + 83,2,53,1,0,0,0,0,0,0,32,0,92,2,34,0, + 83,3,92,0,82,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,53,2,0,0,0,0,0,0, + 32,0,92,1,82,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,34,0,53,0,0,0,0,0, + 0,0,83,4,5,0,0,0,114,5,83,5,19,0,72,20, + 0,0,114,6,92,2,34,0,83,6,92,6,14,0,83,7, + 92,5,92,6,5,0,0,0,14,0,51,4,53,1,0,0, + 0,0,0,0,32,0,77,22,0,0,11,0,103,1,41,8, 233,0,0,0,0,78,122,18,70,114,111,122,101,110,32,72, 101,108,108,111,32,87,111,114,108,100,122,8,115,121,115,46, 97,114,103,118,218,6,99,111,110,102,105,103,41,5,218,12, @@ -27,12 +27,12 @@ unsigned char M_test_frozenmain[] = { 0,0,218,3,107,101,121,169,0,243,0,0,0,0,250,18, 116,101,115,116,95,102,114,111,122,101,110,109,97,105,110,46, 112,121,250,8,60,109,111,100,117,108,101,62,114,18,0,0, - 0,1,0,0,0,115,102,0,0,0,240,3,1,1,1,243, + 0,1,0,0,0,115,99,0,0,0,240,3,1,1,1,243, 8,0,1,11,219,0,24,225,0,5,208,6,26,212,0,27, 217,0,5,128,106,144,35,151,40,145,40,212,0,27,216,9, - 38,208,9,26,215,9,38,209,9,38,211,9,40,168,24,209, - 9,50,128,6,240,2,6,12,2,242,0,7,1,42,128,67, - 241,14,0,5,10,136,71,144,67,144,53,152,2,152,54,160, - 35,153,59,152,45,208,10,40,214,4,41,241,15,7,1,42, - 114,16,0,0,0, + 26,215,9,38,210,9,38,211,9,40,168,24,209,9,50,128, + 6,240,2,6,12,2,242,0,7,1,42,128,67,241,14,0, + 5,10,136,71,144,67,144,53,152,2,152,54,160,35,153,59, + 152,45,208,10,40,214,4,41,241,15,7,1,42,114,16,0, + 0,0, }; diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 55a1370fbd038b..a197d44868b5aa 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -6,7 +6,6 @@ #include "pycore_ceval.h" // _Py_EnterRecursiveCall #include "pycore_interp.h" // _PyInterpreterState.ast #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "structmember.h" #include // Forward declaration @@ -923,7 +922,7 @@ ast_type_reduce(PyObject *self, PyObject *unused) } static PyMemberDef ast_type_members[] = { - {"__dictoffset__", T_PYSSIZET, offsetof(AST_object, dict), READONLY}, + {"__dictoffset__", Py_T_PYSSIZET, offsetof(AST_object, dict), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -1100,7 +1099,7 @@ static int obj2ast_int(struct ast_state* Py_UNUSED(state), PyObject* obj, int* o return 1; } - i = _PyLong_AsInt(obj); + i = PyLong_AsInt(obj); if (i == -1 && PyErr_Occurred()) return 1; *out = i; @@ -12660,6 +12659,9 @@ astmodule_exec(PyObject *m) if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) { return -1; } + if (PyModule_AddIntMacro(m, PyCF_OPTIMIZED_AST) < 0) { + return -1; + } if (PyModule_AddObjectRef(m, "mod", state->mod_type) < 0) { return -1; } @@ -13074,13 +13076,13 @@ PyObject* PyAST_mod2obj(mod_ty t) int starting_recursion_depth; /* Be careful here to prevent overflow. */ - int COMPILER_STACK_FRAME_SCALE = 3; + int COMPILER_STACK_FRAME_SCALE = 2; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { return 0; } - state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; - int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + state->recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state->recursion_depth = starting_recursion_depth; diff --git a/Python/Python-tokenize.c b/Python/Python-tokenize.c index 1938562706914c..83b4aa4b1a7e11 100644 --- a/Python/Python-tokenize.c +++ b/Python/Python-tokenize.c @@ -1,6 +1,8 @@ #include "Python.h" #include "errcode.h" -#include "../Parser/tokenizer.h" +#include "../Parser/lexer/state.h" +#include "../Parser/lexer/lexer.h" +#include "../Parser/tokenizer/tokenizer.h" #include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset() #include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset() @@ -237,9 +239,6 @@ tokenizeriter_next(tokenizeriterobject *it) if (type > DEDENT && type < OP) { type = OP; } - else if (type == ASYNC || type == AWAIT) { - type = NAME; - } else if (type == NEWLINE) { Py_DECREF(str); if (!it->tok->implicit_newline) { diff --git a/Python/_warnings.c b/Python/_warnings.c index 82e621243a0c15..4b7fb888247145 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1,11 +1,13 @@ #include "Python.h" -#include "pycore_frame.h" -#include "pycore_initconfig.h" +#include "pycore_dict.h" // _PyDict_GetItemWithError() #include "pycore_interp.h" // PyInterpreterState.warnings #include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_pyerrors.h" +#include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_sysmodule.h" // _PySys_GetAttr() +#include "pycore_traceback.h" // _Py_DisplaySourceLine() + #include "clinic/_warnings.c.h" #define MODULE_NAME "_warnings" diff --git a/Python/abstract_interp_cases.c.h b/Python/abstract_interp_cases.c.h new file mode 100644 index 00000000000000..44115da8629e42 --- /dev/null +++ b/Python/abstract_interp_cases.c.h @@ -0,0 +1,930 @@ +// This file is generated by Tools/cases_generator/generate_cases.py +// from: +// Python/bytecodes.c +// Do not edit! + + case NOP: { + break; + } + + case RESUME_CHECK: { + break; + } + + case POP_TOP: { + STACK_SHRINK(1); + break; + } + + case PUSH_NULL: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case END_SEND: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case UNARY_NEGATIVE: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case UNARY_NOT: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case TO_BOOL: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case TO_BOOL_BOOL: { + break; + } + + case TO_BOOL_INT: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case TO_BOOL_LIST: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case TO_BOOL_NONE: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case TO_BOOL_STR: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case TO_BOOL_ALWAYS_TRUE: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case UNARY_INVERT: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _GUARD_BOTH_INT: { + break; + } + + case _GUARD_BOTH_FLOAT: { + break; + } + + case _BINARY_OP_MULTIPLY_FLOAT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _BINARY_OP_ADD_FLOAT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _BINARY_OP_SUBTRACT_FLOAT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _GUARD_BOTH_UNICODE: { + break; + } + + case _BINARY_OP_ADD_UNICODE: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BINARY_SUBSCR: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BINARY_SLICE: { + STACK_SHRINK(2); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case STORE_SLICE: { + STACK_SHRINK(4); + break; + } + + case BINARY_SUBSCR_LIST_INT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BINARY_SUBSCR_STR_INT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BINARY_SUBSCR_TUPLE_INT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BINARY_SUBSCR_DICT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LIST_APPEND: { + STACK_SHRINK(1); + break; + } + + case SET_ADD: { + STACK_SHRINK(1); + break; + } + + case STORE_SUBSCR: { + STACK_SHRINK(3); + break; + } + + case STORE_SUBSCR_LIST_INT: { + STACK_SHRINK(3); + break; + } + + case STORE_SUBSCR_DICT: { + STACK_SHRINK(3); + break; + } + + case DELETE_SUBSCR: { + STACK_SHRINK(2); + break; + } + + case CALL_INTRINSIC_1: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_INTRINSIC_2: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _POP_FRAME: { + STACK_SHRINK(1); + break; + } + + case GET_AITER: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case GET_ANEXT: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case GET_AWAITABLE: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case POP_EXCEPT: { + STACK_SHRINK(1); + break; + } + + case LOAD_ASSERTION_ERROR: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LOAD_BUILD_CLASS: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case STORE_NAME: { + STACK_SHRINK(1); + break; + } + + case DELETE_NAME: { + break; + } + + case UNPACK_SEQUENCE: { + STACK_SHRINK(1); + STACK_GROW(oparg); + break; + } + + case UNPACK_SEQUENCE_TWO_TUPLE: { + STACK_SHRINK(1); + STACK_GROW(oparg); + break; + } + + case UNPACK_SEQUENCE_TUPLE: { + STACK_SHRINK(1); + STACK_GROW(oparg); + break; + } + + case UNPACK_SEQUENCE_LIST: { + STACK_SHRINK(1); + STACK_GROW(oparg); + break; + } + + case UNPACK_EX: { + STACK_GROW((oparg & 0xFF) + (oparg >> 8)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg >> 8))), true); + break; + } + + case STORE_ATTR: { + STACK_SHRINK(2); + break; + } + + case DELETE_ATTR: { + STACK_SHRINK(1); + break; + } + + case STORE_GLOBAL: { + STACK_SHRINK(1); + break; + } + + case DELETE_GLOBAL: { + break; + } + + case LOAD_LOCALS: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LOAD_FROM_DICT_OR_GLOBALS: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LOAD_NAME: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LOAD_GLOBAL: { + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _GUARD_GLOBALS_VERSION: { + break; + } + + case _GUARD_BUILTINS_VERSION: { + break; + } + + case _LOAD_GLOBAL_MODULE: { + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _LOAD_GLOBAL_BUILTINS: { + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case DELETE_FAST: { + break; + } + + case DELETE_DEREF: { + break; + } + + case LOAD_FROM_DICT_OR_DEREF: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LOAD_DEREF: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case STORE_DEREF: { + STACK_SHRINK(1); + break; + } + + case COPY_FREE_VARS: { + break; + } + + case BUILD_STRING: { + STACK_SHRINK(oparg); + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BUILD_TUPLE: { + STACK_SHRINK(oparg); + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BUILD_LIST: { + STACK_SHRINK(oparg); + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LIST_EXTEND: { + STACK_SHRINK(1); + break; + } + + case SET_UPDATE: { + STACK_SHRINK(1); + break; + } + + case BUILD_SET: { + STACK_SHRINK(oparg); + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BUILD_MAP: { + STACK_SHRINK(oparg*2); + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case SETUP_ANNOTATIONS: { + break; + } + + case BUILD_CONST_KEY_MAP: { + STACK_SHRINK(oparg); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case DICT_UPDATE: { + STACK_SHRINK(1); + break; + } + + case DICT_MERGE: { + STACK_SHRINK(1); + break; + } + + case MAP_ADD: { + STACK_SHRINK(2); + break; + } + + case LOAD_SUPER_ATTR_ATTR: { + STACK_SHRINK(2); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(0)), true); + break; + } + + case LOAD_SUPER_ATTR_METHOD: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case LOAD_ATTR: { + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _GUARD_TYPE_VERSION: { + break; + } + + case _CHECK_MANAGED_OBJECT_HAS_VALUES: { + break; + } + + case _LOAD_ATTR_INSTANCE_VALUE: { + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _CHECK_ATTR_MODULE: { + break; + } + + case _LOAD_ATTR_MODULE: { + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _CHECK_ATTR_WITH_HINT: { + break; + } + + case _LOAD_ATTR_WITH_HINT: { + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _LOAD_ATTR_SLOT: { + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _CHECK_ATTR_CLASS: { + break; + } + + case _LOAD_ATTR_CLASS: { + STACK_GROW(((oparg & 1) ? 1 : 0)); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true); + break; + } + + case _GUARD_DORV_VALUES: { + break; + } + + case _STORE_ATTR_INSTANCE_VALUE: { + STACK_SHRINK(2); + break; + } + + case _STORE_ATTR_SLOT: { + STACK_SHRINK(2); + break; + } + + case COMPARE_OP: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case COMPARE_OP_FLOAT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case COMPARE_OP_INT: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case COMPARE_OP_STR: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case IS_OP: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CONTAINS_OP: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CHECK_EG_MATCH: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CHECK_EXC_MATCH: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _IS_NONE: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case GET_LEN: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case MATCH_CLASS: { + STACK_SHRINK(2); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case MATCH_MAPPING: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case MATCH_SEQUENCE: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case MATCH_KEYS: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case GET_ITER: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case GET_YIELD_FROM_ITER: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _ITER_CHECK_LIST: { + break; + } + + case _IS_ITER_EXHAUSTED_LIST: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _ITER_NEXT_LIST: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _ITER_CHECK_TUPLE: { + break; + } + + case _IS_ITER_EXHAUSTED_TUPLE: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _ITER_NEXT_TUPLE: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _ITER_CHECK_RANGE: { + break; + } + + case _IS_ITER_EXHAUSTED_RANGE: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _ITER_NEXT_RANGE: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case WITH_EXCEPT_START: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case PUSH_EXC_INFO: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT: { + break; + } + + case _GUARD_KEYS_VERSION: { + break; + } + + case _LOAD_ATTR_METHOD_WITH_VALUES: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _LOAD_ATTR_METHOD_NO_DICT: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(0)), true); + break; + } + + case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(0)), true); + break; + } + + case _CHECK_ATTR_METHOD_LAZY_DICT: { + break; + } + + case _LOAD_ATTR_METHOD_LAZY_DICT: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: { + break; + } + + case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2 - oparg)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - oparg)), true); + break; + } + + case _CHECK_PEP_523: { + break; + } + + case _CHECK_FUNCTION_EXACT_ARGS: { + break; + } + + case _CHECK_STACK_SPACE: { + break; + } + + case _INIT_CALL_PY_EXACT_ARGS: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _PUSH_FRAME: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_TYPE_1: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_STR_1: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_TUPLE_1: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case EXIT_INIT_CHECK: { + STACK_SHRINK(1); + break; + } + + case CALL_BUILTIN_CLASS: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_BUILTIN_O: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_BUILTIN_FAST: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_BUILTIN_FAST_WITH_KEYWORDS: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_LEN: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_ISINSTANCE: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_METHOD_DESCRIPTOR_O: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_METHOD_DESCRIPTOR_NOARGS: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CALL_METHOD_DESCRIPTOR_FAST: { + STACK_SHRINK(oparg); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case MAKE_FUNCTION: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case SET_FUNCTION_ATTRIBUTE: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BUILD_SLICE: { + STACK_SHRINK(((oparg == 3) ? 1 : 0)); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case CONVERT_VALUE: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case FORMAT_SIMPLE: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case FORMAT_WITH_SPEC: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case BINARY_OP: { + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case SWAP: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2 - (oparg-2))), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + + case _POP_JUMP_IF_FALSE: { + STACK_SHRINK(1); + break; + } + + case _POP_JUMP_IF_TRUE: { + STACK_SHRINK(1); + break; + } + + case _JUMP_TO_TOP: { + break; + } + + case _SET_IP: { + break; + } + + case _EXIT_TRACE: { + break; + } + + case _INSERT: { + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - oparg)), true); + break; + } diff --git a/Python/assemble.c b/Python/assemble.c index b7012534d6cc4e..b6fb432aed4a3b 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -3,9 +3,8 @@ #include "Python.h" #include "pycore_code.h" // write_location_entry_start() #include "pycore_compile.h" -#include "pycore_opcode.h" // _PyOpcode_Caches[] and opcode category macros #include "pycore_opcode_utils.h" // IS_BACKWARDS_JUMP_OPCODE -#include "pycore_opcode_metadata.h" // IS_PSEUDO_INSTR +#include "pycore_opcode_metadata.h" // IS_PSEUDO_INSTR, _PyOpcode_Caches #define DEFAULT_CODE_SIZE 128 @@ -18,7 +17,7 @@ #define ERROR -1 #define RETURN_IF_ERROR(X) \ - if ((X) == -1) { \ + if ((X) < 0) { \ return ERROR; \ } @@ -448,13 +447,17 @@ static PyObject * dict_keys_inorder(PyObject *dict, Py_ssize_t offset) { PyObject *tuple, *k, *v; - Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); + Py_ssize_t pos = 0, size = PyDict_GET_SIZE(dict); tuple = PyTuple_New(size); if (tuple == NULL) return NULL; while (PyDict_Next(dict, &pos, &k, &v)) { - i = PyLong_AS_LONG(v); + Py_ssize_t i = PyLong_AsSsize_t(v); + if (i == -1 && PyErr_Occurred()) { + Py_DECREF(tuple); + return NULL; + } assert((i - offset) < size); assert((i - offset) >= 0); PyTuple_SET_ITEM(tuple, i - offset, Py_NewRef(k)); @@ -466,24 +469,34 @@ dict_keys_inorder(PyObject *dict, Py_ssize_t offset) extern void _Py_set_localsplus_info(int, PyObject *, unsigned char, PyObject *, PyObject *); -static void +static int compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus, PyObject *names, PyObject *kinds) { PyObject *k, *v; Py_ssize_t pos = 0; while (PyDict_Next(umd->u_varnames, &pos, &k, &v)) { - int offset = (int)PyLong_AS_LONG(v); + int offset = PyLong_AsInt(v); + if (offset == -1 && PyErr_Occurred()) { + return ERROR; + } assert(offset >= 0); assert(offset < nlocalsplus); + // For now we do not distinguish arg kinds. _PyLocals_Kind kind = CO_FAST_LOCAL; - if (PyDict_Contains(umd->u_fasthidden, k)) { + int has_key = PyDict_Contains(umd->u_fasthidden, k); + RETURN_IF_ERROR(has_key); + if (has_key) { kind |= CO_FAST_HIDDEN; } - if (PyDict_GetItem(umd->u_cellvars, k) != NULL) { + + has_key = PyDict_Contains(umd->u_cellvars, k); + RETURN_IF_ERROR(has_key); + if (has_key) { kind |= CO_FAST_CELL; } + _Py_set_localsplus_info(offset, k, kind, names, kinds); } int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); @@ -492,12 +505,18 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus, int numdropped = 0; pos = 0; while (PyDict_Next(umd->u_cellvars, &pos, &k, &v)) { - if (PyDict_GetItem(umd->u_varnames, k) != NULL) { + int has_name = PyDict_Contains(umd->u_varnames, k); + RETURN_IF_ERROR(has_name); + if (has_name) { // Skip cells that are already covered by locals. numdropped += 1; continue; } - int offset = (int)PyLong_AS_LONG(v); + + int offset = PyLong_AsInt(v); + if (offset == -1 && PyErr_Occurred()) { + return ERROR; + } assert(offset >= 0); offset += nlocals - numdropped; assert(offset < nlocalsplus); @@ -506,12 +525,16 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus, pos = 0; while (PyDict_Next(umd->u_freevars, &pos, &k, &v)) { - int offset = (int)PyLong_AS_LONG(v); + int offset = PyLong_AsInt(v); + if (offset == -1 && PyErr_Occurred()) { + return ERROR; + } assert(offset >= 0); offset += nlocals - numdropped; assert(offset < nlocalsplus); _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds); } + return SUCCESS; } static PyCodeObject * @@ -556,7 +579,10 @@ makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_ if (localspluskinds == NULL) { goto error; } - compute_localsplus_info(umd, nlocalsplus, localsplusnames, localspluskinds); + if (compute_localsplus_info(umd, nlocalsplus, + localsplusnames, localspluskinds) == ERROR) { + goto error; + } struct _PyCodeConstructor con = { .filename = filename, diff --git a/Python/ast.c b/Python/ast.c index 68600ce683b974..5f46d4149c2ed0 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -381,6 +381,11 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0); break; case NamedExpr_kind: + if (exp->v.NamedExpr.target->kind != Name_kind) { + PyErr_SetString(PyExc_TypeError, + "NamedExpr target must be a Name"); + return 0; + } ret = validate_expr(state, exp->v.NamedExpr.value, Load); break; /* This last case doesn't have any checking. */ @@ -768,6 +773,11 @@ validate_stmt(struct validator *state, stmt_ty stmt) validate_expr(state, stmt->v.AnnAssign.annotation, Load); break; case TypeAlias_kind: + if (stmt->v.TypeAlias.name->kind != Name_kind) { + PyErr_SetString(PyExc_TypeError, + "TypeAlias with non-Name name"); + return 0; + } ret = validate_expr(state, stmt->v.TypeAlias.name, Store) && validate_type_params(state, stmt->v.TypeAlias.type_params) && validate_expr(state, stmt->v.TypeAlias.value, Load); @@ -1029,7 +1039,7 @@ validate_type_params(struct validator *state, asdl_type_param_seq *tps) /* See comments in symtable.c. */ -#define COMPILER_STACK_FRAME_SCALE 3 +#define COMPILER_STACK_FRAME_SCALE 2 int _PyAST_Validate(mod_ty mod) @@ -1046,10 +1056,10 @@ _PyAST_Validate(mod_ty mod) return 0; } /* Be careful here to prevent overflow. */ - int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state.recursion_depth = starting_recursion_depth; - state.recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + state.recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; switch (mod->kind) { case Module_kind: diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 276e910089a277..41f48eba08afc4 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -1,9 +1,10 @@ /* AST Optimizer */ #include "Python.h" #include "pycore_ast.h" // _PyAST_GetDocString() -#include "pycore_long.h" // _PyLong -#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_format.h" // F_LJUST +#include "pycore_long.h" // _PyLong +#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_setobject.h" // _PySet_NextEntry() typedef struct { @@ -1111,7 +1112,7 @@ astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat #undef CALL_SEQ /* See comments in symtable.c. */ -#define COMPILER_STACK_FRAME_SCALE 3 +#define COMPILER_STACK_FRAME_SCALE 2 int _PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize, int ff_features) @@ -1129,10 +1130,10 @@ _PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize, int ff_features) return 0; } /* Be careful here to prevent overflow. */ - int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state.recursion_depth = starting_recursion_depth; - state.recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + state.recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; int ret = astfold_mod(mod, arena, &state); assert(ret || PyErr_Occurred()); diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 7d77fd5c0c328e..c373585c0986ce 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1,20 +1,27 @@ /* Built-in functions */ #include "Python.h" -#include #include "pycore_ast.h" // _PyAST_Validate() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_Vector() #include "pycore_compile.h" // _PyAST_Compile() +#include "pycore_dict.h" // _PyDict_GetItemWithError() #include "pycore_long.h" // _PyLong_CompactValue #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_object.h" // _Py_AddToAllObjects() #include "pycore_pyerrors.h" // _PyErr_NoMemory() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_pythonrun.h" // _Py_SourceAsString() +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_tuple.h" // _PyTuple_FromArray() #include "clinic/bltinmodule.c.h" +#ifdef HAVE_UNISTD_H +# include // isatty() +#endif + + static PyObject* update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) { @@ -803,23 +810,40 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, if (is_ast == -1) goto error; if (is_ast) { - if (flags & PyCF_ONLY_AST) { + if ((flags & PyCF_OPTIMIZED_AST) == PyCF_ONLY_AST) { + // return an un-optimized AST result = Py_NewRef(source); } else { - PyArena *arena; - mod_ty mod; + // Return an optimized AST or code object - arena = _PyArena_New(); - if (arena == NULL) - goto error; - mod = PyAST_obj2mod(source, arena, compile_mode); - if (mod == NULL || !_PyAST_Validate(mod)) { - _PyArena_Free(arena); + PyArena *arena = _PyArena_New(); + if (arena == NULL) { goto error; } - result = (PyObject*)_PyAST_Compile(mod, filename, - &cf, optimize, arena); + + if (flags & PyCF_ONLY_AST) { + mod_ty mod = PyAST_obj2mod(source, arena, compile_mode); + if (mod == NULL || !_PyAST_Validate(mod)) { + _PyArena_Free(arena); + goto error; + } + if (_PyCompile_AstOptimize(mod, filename, &cf, optimize, + arena) < 0) { + _PyArena_Free(arena); + goto error; + } + result = PyAST_mod2obj(mod); + } + else { + mod_ty mod = PyAST_obj2mod(source, arena, compile_mode); + if (mod == NULL || !_PyAST_Validate(mod)) { + _PyArena_Free(arena); + goto error; + } + result = (PyObject*)_PyAST_Compile(mod, filename, + &cf, optimize, arena); + } _PyArena_Free(arena); } goto finally; @@ -841,33 +865,31 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, return result; } -/*[clinic input] -dir as builtin_dir - - arg: object = NULL - / - -Show attributes of an object. - -If called without an argument, return the names in the current scope. -Else, return an alphabetized list of names comprising (some of) the attributes -of the given object, and of attributes reachable from it. -If the object supplies a method named __dir__, it will be used; otherwise -the default dir() logic is used and returns: - for a module object: the module's attributes. - for a class object: its attributes, and recursively the attributes - of its bases. - for any other object: its attributes, its class's attributes, and - recursively the attributes of its class's base classes. -[clinic start generated code]*/ - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * -builtin_dir_impl(PyObject *module, PyObject *arg) -/*[clinic end generated code: output=24f2c7a52c1e3b08 input=ed6d6ccb13d52251]*/ +builtin_dir(PyObject *self, PyObject *args) { + PyObject *arg = NULL; + + if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg)) + return NULL; return PyObject_Dir(arg); } +PyDoc_STRVAR(dir_doc, +"dir([object]) -> list of strings\n" +"\n" +"If called without an argument, return the names in the current scope.\n" +"Else, return an alphabetized list of names comprising (some of) the attributes\n" +"of the given object, and of attributes reachable from it.\n" +"If the object supplies a method named __dir__, it will be used; otherwise\n" +"the default dir() logic is used and returns:\n" +" for a module object: the module's attributes.\n" +" for a class object: its attributes, and recursively the attributes\n" +" of its bases.\n" +" for any other object: its attributes, its class's attributes, and\n" +" recursively the attributes of its class's base classes."); + /*[clinic input] divmod as builtin_divmod @@ -1137,39 +1159,36 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, } -/*[clinic input] -getattr as builtin_getattr - - object: object - name: object - default: object = NULL - / - -Get a named attribute from an object. - -getattr(x, 'y') is equivalent to x.y -When a default argument is given, it is returned when the attribute doesn't -exist; without it, an exception is raised in that case. -[clinic start generated code]*/ - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * -builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name, - PyObject *default_value) -/*[clinic end generated code: output=74ad0e225e3f701c input=d7562cd4c3556171]*/ +builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { - PyObject *result; + PyObject *v, *name, *result; + + if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) + return NULL; - if (default_value != NULL) { - if (PyObject_GetOptionalAttr(object, name, &result) == 0) { - return Py_NewRef(default_value); + v = args[0]; + name = args[1]; + if (nargs > 2) { + if (PyObject_GetOptionalAttr(v, name, &result) == 0) { + PyObject *dflt = args[2]; + return Py_NewRef(dflt); } } else { - result = PyObject_GetAttr(object, name); + result = PyObject_GetAttr(v, name); } return result; } +PyDoc_STRVAR(getattr_doc, +"getattr(object, name[, default]) -> value\n\ +\n\ +Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\ +When a default argument is given, it is returned when the attribute doesn't\n\ +exist; without it, an exception is raised in that case."); + /*[clinic input] globals as builtin_globals @@ -1481,43 +1500,34 @@ PyTypeObject PyMap_Type = { }; -/*[clinic input] -next as builtin_next - - iterator: object - default: object = NULL - / - -Return the next item from the iterator. - -If default is given and the iterator is exhausted, -it is returned instead of raising StopIteration. -[clinic start generated code]*/ - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * -builtin_next_impl(PyObject *module, PyObject *iterator, - PyObject *default_value) -/*[clinic end generated code: output=a38a94eeb447fef9 input=180f9984f182020f]*/ +builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { - PyObject *res; + PyObject *it, *res; + + if (!_PyArg_CheckPositional("next", nargs, 1, 2)) + return NULL; - if (!PyIter_Check(iterator)) { + it = args[0]; + if (!PyIter_Check(it)) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not an iterator", - Py_TYPE(iterator)->tp_name); + Py_TYPE(it)->tp_name); return NULL; } - res = (*Py_TYPE(iterator)->tp_iternext)(iterator); + res = (*Py_TYPE(it)->tp_iternext)(it); if (res != NULL) { return res; - } else if (default_value != NULL) { + } else if (nargs > 1) { + PyObject *def = args[1]; if (PyErr_Occurred()) { if(!PyErr_ExceptionMatches(PyExc_StopIteration)) return NULL; PyErr_Clear(); } - return Py_NewRef(default_value); + return Py_NewRef(def); } else if (PyErr_Occurred()) { return NULL; } else { @@ -1526,6 +1536,12 @@ builtin_next_impl(PyObject *module, PyObject *iterator, } } +PyDoc_STRVAR(next_doc, +"next(iterator[, default])\n\ +\n\ +Return the next item from the iterator. If default is given and the iterator\n\ +is exhausted, it is returned instead of raising StopIteration."); + /*[clinic input] setattr as builtin_setattr @@ -1619,33 +1635,34 @@ builtin_hex(PyObject *module, PyObject *number) } -/*[clinic input] -iter as builtin_iter - - object: object - sentinel: object = NULL - / - -Get an iterator from an object. - -In the first form, the argument must supply its own iterator, or be a sequence. -In the second form, the callable is called until it returns the sentinel. -[clinic start generated code]*/ - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * -builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel) -/*[clinic end generated code: output=12cf64203c195a94 input=a5d64d9d81880ba6]*/ +builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { - if (sentinel == NULL) - return PyObject_GetIter(object); - if (!PyCallable_Check(object)) { + PyObject *v; + + if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) + return NULL; + v = args[0]; + if (nargs == 1) + return PyObject_GetIter(v); + if (!PyCallable_Check(v)) { PyErr_SetString(PyExc_TypeError, - "iter(object, sentinel): object must be callable"); + "iter(v, w): v must be callable"); return NULL; } - return PyCallIter_New(object, sentinel); + PyObject *sentinel = args[1]; + return PyCallIter_New(v, sentinel); } +PyDoc_STRVAR(iter_doc, +"iter(iterable) -> iterator\n\ +iter(callable, sentinel) -> iterator\n\ +\n\ +Get an iterator from an object. In the first form, the argument must\n\ +supply its own iterator, or be a sequence.\n\ +In the second form, the callable is called until it returns the sentinel."); + /*[clinic input] aiter as builtin_aiter @@ -2071,11 +2088,9 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep, } if (flush) { - PyObject *tmp = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); - if (tmp == NULL) { + if (_PyFile_Flush(file) < 0) { return NULL; } - Py_DECREF(tmp); } Py_RETURN_NONE; @@ -2134,11 +2149,9 @@ builtin_input_impl(PyObject *module, PyObject *prompt) } /* First of all, flush stderr */ - tmp = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); - if (tmp == NULL) + if (_PyFile_Flush(ferr) < 0) { PyErr_Clear(); - else - Py_DECREF(tmp); + } /* We should only use (GNU) readline if Python's sys.stdin and sys.stdout are the same as C's stdin and stdout, because we @@ -2206,11 +2219,9 @@ builtin_input_impl(PyObject *module, PyObject *prompt) if (stdin_errors_str == NULL) { goto _readline_errors; } - tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush)); - if (tmp == NULL) + if (_PyFile_Flush(fout) < 0) { PyErr_Clear(); - else - Py_DECREF(tmp); + } if (prompt != NULL) { /* We have a prompt, encode it as stdout would */ const char *stdout_encoding_str, *stdout_errors_str; @@ -2313,11 +2324,9 @@ builtin_input_impl(PyObject *module, PyObject *prompt) if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) return NULL; } - tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush)); - if (tmp == NULL) + if (_PyFile_Flush(fout) < 0) { PyErr_Clear(); - else - Py_DECREF(tmp); + } return PyFile_GetLine(fin, -1); } @@ -2443,29 +2452,20 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } -/*[clinic input] -vars as builtin_vars - - object: object = NULL - / - -Show vars. - -Without arguments, equivalent to locals(). -With an argument, equivalent to object.__dict__. -[clinic start generated code]*/ - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * -builtin_vars_impl(PyObject *module, PyObject *object) -/*[clinic end generated code: output=840a7f64007a3e0a input=80cbdef9182c4ba3]*/ +builtin_vars(PyObject *self, PyObject *args) { + PyObject *v = NULL; PyObject *d; - if (object == NULL) { + if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) + return NULL; + if (v == NULL) { d = _PyEval_GetFrameLocals(); } else { - if (PyObject_GetOptionalAttr(object, &_Py_ID(__dict__), &d) == 0) { + if (PyObject_GetOptionalAttr(v, &_Py_ID(__dict__), &d) == 0) { PyErr_SetString(PyExc_TypeError, "vars() argument must have __dict__ attribute"); } @@ -2473,6 +2473,12 @@ builtin_vars_impl(PyObject *module, PyObject *object) return d; } +PyDoc_STRVAR(vars_doc, +"vars([object]) -> dictionary\n\ +\n\ +Without arguments, equivalent to locals().\n\ +With an argument, equivalent to object.__dict__."); + /*[clinic input] sum as builtin_sum @@ -3021,12 +3027,12 @@ static PyMethodDef builtin_methods[] = { BUILTIN_CHR_METHODDEF BUILTIN_COMPILE_METHODDEF BUILTIN_DELATTR_METHODDEF - BUILTIN_DIR_METHODDEF + {"dir", builtin_dir, METH_VARARGS, dir_doc}, BUILTIN_DIVMOD_METHODDEF BUILTIN_EVAL_METHODDEF BUILTIN_EXEC_METHODDEF BUILTIN_FORMAT_METHODDEF - BUILTIN_GETATTR_METHODDEF + {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, getattr_doc}, BUILTIN_GLOBALS_METHODDEF BUILTIN_HASATTR_METHODDEF BUILTIN_HASH_METHODDEF @@ -3035,13 +3041,13 @@ static PyMethodDef builtin_methods[] = { BUILTIN_INPUT_METHODDEF BUILTIN_ISINSTANCE_METHODDEF BUILTIN_ISSUBCLASS_METHODDEF - BUILTIN_ITER_METHODDEF + {"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, iter_doc}, BUILTIN_AITER_METHODDEF BUILTIN_LEN_METHODDEF BUILTIN_LOCALS_METHODDEF {"max", _PyCFunction_CAST(builtin_max), METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", _PyCFunction_CAST(builtin_min), METH_VARARGS | METH_KEYWORDS, min_doc}, - BUILTIN_NEXT_METHODDEF + {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc}, BUILTIN_ANEXT_METHODDEF BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF @@ -3052,7 +3058,7 @@ static PyMethodDef builtin_methods[] = { BUILTIN_SETATTR_METHODDEF BUILTIN_SORTED_METHODDEF BUILTIN_SUM_METHODDEF - BUILTIN_VARS_METHODDEF + {"vars", builtin_vars, METH_VARARGS, vars_doc}, {NULL, NULL}, }; @@ -3100,7 +3106,7 @@ _PyBuiltin_Init(PyInterpreterState *interp) * result, programs leaking references to None and False (etc) * couldn't be diagnosed by examining sys.getobjects(0). */ -#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT), 0) +#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT)) #else #define ADD_TO_ALL(OBJECT) (void)0 #endif diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index ef693e5df1fcc4..92f2301a012c0a 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -4,22 +4,25 @@ #include "pycore_pylifecycle.h" // _PyOS_URandomNonblock() #include "pycore_runtime.h" // _PyRuntime +#ifdef HAVE_UNISTD_H +# include // close() +#endif #ifdef MS_WINDOWS # include # include #else -# include +# include // O_RDONLY # ifdef HAVE_SYS_STAT_H # include # endif # ifdef HAVE_LINUX_RANDOM_H -# include +# include // GRND_NONBLOCK # endif # if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY)) -# include +# include // getrandom() # endif # if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL) -# include +# include // SYS_getrandom # endif #endif diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ea136a3fca2e02..d7e2ecdd24dcee 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -10,23 +10,23 @@ #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_ceval.h" // _PyEval_SignalAsyncExc() #include "pycore_code.h" +#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_function.h" +#include "pycore_instruments.h" #include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_instruments.h" -#include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_moduleobject.h" // PyModuleObject -#include "pycore_opcode.h" // EXTRA_CASES +#include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_opcode_metadata.h" // uop names #include "pycore_opcode_utils.h" // MAKE_FUNCTION_* #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_range.h" // _PyRangeIterObject +#include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "pycore_typeobject.h" // _PySuper_Lookup() -#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_dict.h" #include "dictobject.h" @@ -35,14 +35,12 @@ #include "optimizer.h" #include "pydtrace.h" #include "setobject.h" -#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX + #define USE_COMPUTED_GOTOS 0 #include "ceval_macros.h" /* Flow control macros */ -#define DEOPT_IF(cond, instname) ((void)0) -#define ERROR_IF(cond, labelname) ((void)0) #define GO_TO_INSTRUCTION(instname) ((void)0) #define inst(name, ...) case name: @@ -72,12 +70,9 @@ dummy_func( _PyInterpreterFrame *frame, unsigned char opcode, unsigned int oparg, - _PyCFrame cframe, _Py_CODEUNIT *next_instr, PyObject **stack_pointer, - PyObject *kwnames, int throwflag, - binaryfunc binary_ops[], PyObject *args[] ) { @@ -134,26 +129,46 @@ dummy_func( inst(NOP, (--)) { } + family(RESUME, 0) = { + RESUME_CHECK, + }; + inst(RESUME, (--)) { - assert(tstate->cframe == &cframe); - assert(frame == cframe.current_frame); - /* Possibly combine this with eval breaker */ - if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) { + TIER_ONE_ONLY + assert(frame == tstate->current_frame); + uintptr_t global_version = + _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) & + ~_PY_EVAL_EVENTS_MASK; + uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + assert((code_version & 255) == 0); + if (code_version != global_version) { int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); ERROR_IF(err, error); next_instr--; } - else if (oparg < 2) { - CHECK_EVAL_BREAKER(); + else { + if (oparg < 2) { + CHECK_EVAL_BREAKER(); + } + next_instr[-1].op.code = RESUME_CHECK; } } + inst(RESUME_CHECK, (--)) { +#if defined(__EMSCRIPTEN__) + DEOPT_IF(_Py_emscripten_signal_clock == 0); + _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; +#endif + uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker); + uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + assert((version & _PY_EVAL_EVENTS_MASK) == 0); + DEOPT_IF(eval_breaker != version); + } + inst(INSTRUMENTED_RESUME, (--)) { - /* Possible performance enhancement: - * We need to check the eval breaker anyway, can we - * combine the instrument verison check and the eval breaker test? - */ - if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) { + uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) & ~_PY_EVAL_EVENTS_MASK; + uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + if (code_version != global_version) { if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) { goto error; } @@ -311,12 +326,12 @@ dummy_func( } inst(TO_BOOL_BOOL, (unused/1, unused/2, value -- value)) { - DEOPT_IF(!PyBool_Check(value), TO_BOOL); + DEOPT_IF(!PyBool_Check(value)); STAT_INC(TO_BOOL, hit); } inst(TO_BOOL_INT, (unused/1, unused/2, value -- res)) { - DEOPT_IF(!PyLong_CheckExact(value), TO_BOOL); + DEOPT_IF(!PyLong_CheckExact(value)); STAT_INC(TO_BOOL, hit); if (_PyLong_IsZero((PyLongObject *)value)) { assert(_Py_IsImmortal(value)); @@ -329,7 +344,7 @@ dummy_func( } inst(TO_BOOL_LIST, (unused/1, unused/2, value -- res)) { - DEOPT_IF(!PyList_CheckExact(value), TO_BOOL); + DEOPT_IF(!PyList_CheckExact(value)); STAT_INC(TO_BOOL, hit); res = Py_SIZE(value) ? Py_True : Py_False; DECREF_INPUTS(); @@ -337,13 +352,13 @@ dummy_func( inst(TO_BOOL_NONE, (unused/1, unused/2, value -- res)) { // This one is a bit weird, because we expect *some* failures: - DEOPT_IF(!Py_IsNone(value), TO_BOOL); + DEOPT_IF(!Py_IsNone(value)); STAT_INC(TO_BOOL, hit); res = Py_False; } inst(TO_BOOL_STR, (unused/1, unused/2, value -- res)) { - DEOPT_IF(!PyUnicode_CheckExact(value), TO_BOOL); + DEOPT_IF(!PyUnicode_CheckExact(value)); STAT_INC(TO_BOOL, hit); if (value == &_Py_STR(empty)) { assert(_Py_IsImmortal(value)); @@ -359,7 +374,7 @@ dummy_func( inst(TO_BOOL_ALWAYS_TRUE, (unused/1, version/2, value -- res)) { // This one is a bit weird, because we expect *some* failures: assert(version); - DEOPT_IF(Py_TYPE(value)->tp_version_tag != version, TO_BOOL); + DEOPT_IF(Py_TYPE(value)->tp_version_tag != version); STAT_INC(TO_BOOL, hit); DECREF_INPUTS(); res = Py_True; @@ -383,8 +398,8 @@ dummy_func( }; op(_GUARD_BOTH_INT, (left, right -- left, right)) { - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(left)); + DEOPT_IF(!PyLong_CheckExact(right)); } op(_BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- res)) { @@ -419,8 +434,8 @@ dummy_func( _GUARD_BOTH_INT + _BINARY_OP_SUBTRACT_INT; op(_GUARD_BOTH_FLOAT, (left, right -- left, right)) { - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(left)); + DEOPT_IF(!PyFloat_CheckExact(right)); } op(_BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- res)) { @@ -455,8 +470,8 @@ dummy_func( _GUARD_BOTH_FLOAT + _BINARY_OP_SUBTRACT_FLOAT; op(_GUARD_BOTH_UNICODE, (left, right -- left, right)) { - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); + DEOPT_IF(!PyUnicode_CheckExact(left)); + DEOPT_IF(!PyUnicode_CheckExact(right)); } op(_BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) { @@ -480,7 +495,7 @@ dummy_func( _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; assert(true_next.op.code == STORE_FAST); PyObject **target_local = &GETLOCAL(true_next.op.arg); - DEOPT_IF(*target_local != left, BINARY_OP); + DEOPT_IF(*target_local != left); STAT_INC(BINARY_OP, hit); /* Handle `left = left + right` or `left += right` for str. * @@ -509,6 +524,7 @@ dummy_func( BINARY_SUBSCR_DICT, BINARY_SUBSCR_GETITEM, BINARY_SUBSCR_LIST_INT, + BINARY_SUBSCR_STR_INT, BINARY_SUBSCR_TUPLE_INT, }; @@ -559,13 +575,13 @@ dummy_func( } inst(BINARY_SUBSCR_LIST_INT, (unused/1, list, sub -- res)) { - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); + DEOPT_IF(!PyLong_CheckExact(sub)); + DEOPT_IF(!PyList_CheckExact(list)); // Deopt unless 0 <= sub < PyList_Size(list) - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); + DEOPT_IF(index >= PyList_GET_SIZE(list)); STAT_INC(BINARY_SUBSCR, hit); res = PyList_GET_ITEM(list, index); assert(res != NULL); @@ -574,14 +590,29 @@ dummy_func( Py_DECREF(list); } + inst(BINARY_SUBSCR_STR_INT, (unused/1, str, sub -- res)) { + DEOPT_IF(!PyLong_CheckExact(sub)); + DEOPT_IF(!PyUnicode_CheckExact(str)); + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index); + // Specialize for reading an ASCII character from any string: + Py_UCS4 c = PyUnicode_READ_CHAR(str, index); + DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c); + STAT_INC(BINARY_SUBSCR, hit); + res = (PyObject*)&_Py_SINGLETON(strings).ascii[c]; + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(str); + } + inst(BINARY_SUBSCR_TUPLE_INT, (unused/1, tuple, sub -- res)) { - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); + DEOPT_IF(!PyLong_CheckExact(sub)); + DEOPT_IF(!PyTuple_CheckExact(tuple)); // Deopt unless 0 <= sub < PyTuple_Size(list) - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); + DEOPT_IF(index >= PyTuple_GET_SIZE(tuple)); STAT_INC(BINARY_SUBSCR, hit); res = PyTuple_GET_ITEM(tuple, index); assert(res != NULL); @@ -591,7 +622,7 @@ dummy_func( } inst(BINARY_SUBSCR_DICT, (unused/1, dict, sub -- res)) { - DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); + DEOPT_IF(!PyDict_CheckExact(dict)); STAT_INC(BINARY_SUBSCR, hit); res = PyDict_GetItemWithError(dict, sub); if (res == NULL) { @@ -606,19 +637,19 @@ dummy_func( } inst(BINARY_SUBSCR_GETITEM, (unused/1, container, sub -- unused)) { - DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); + DEOPT_IF(tstate->interp->eval_frame); PyTypeObject *tp = Py_TYPE(container); - DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR); + DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; PyObject *cached = ht->_spec_cache.getitem; - DEOPT_IF(cached == NULL, BINARY_SUBSCR); + DEOPT_IF(cached == NULL); assert(PyFunction_Check(cached)); PyFunctionObject *getitem = (PyFunctionObject *)cached; uint32_t cached_version = ht->_spec_cache.getitem_version; - DEOPT_IF(getitem->func_version != cached_version, BINARY_SUBSCR); + DEOPT_IF(getitem->func_version != cached_version); PyCodeObject *code = (PyCodeObject *)getitem->func_code; assert(code->co_argcount == 2); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); STAT_INC(BINARY_SUBSCR, hit); Py_INCREF(getitem); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2); @@ -663,14 +694,14 @@ dummy_func( } inst(STORE_SUBSCR_LIST_INT, (unused/1, value, list, sub -- )) { - DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); - DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); + DEOPT_IF(!PyLong_CheckExact(sub)); + DEOPT_IF(!PyList_CheckExact(list)); // Ensure nonnegative, zero-or-one-digit ints. - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), STORE_SUBSCR); + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; // Ensure index < len(list) - DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); + DEOPT_IF(index >= PyList_GET_SIZE(list)); STAT_INC(STORE_SUBSCR, hit); PyObject *old_value = PyList_GET_ITEM(list, index); @@ -682,7 +713,7 @@ dummy_func( } inst(STORE_SUBSCR_DICT, (unused/1, value, dict, sub -- )) { - DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); + DEOPT_IF(!PyDict_CheckExact(dict)); STAT_INC(STORE_SUBSCR, hit); int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); Py_DECREF(dict); @@ -698,14 +729,14 @@ dummy_func( inst(CALL_INTRINSIC_1, (value -- res)) { assert(oparg <= MAX_INTRINSIC_1); - res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); + res = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, value); DECREF_INPUTS(); ERROR_IF(res == NULL, error); } inst(CALL_INTRINSIC_2, (value2, value1 -- res)) { assert(oparg <= MAX_INTRINSIC_2); - res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1); + res = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1); DECREF_INPUTS(); ERROR_IF(res == NULL, error); } @@ -720,7 +751,11 @@ dummy_func( exc = args[0]; /* fall through */ case 0: - ERROR_IF(do_raise(tstate, exc, cause), exception_unwind); + if (do_raise(tstate, exc, cause)) { + assert(oparg == 0); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } break; default: _PyErr_SetString(tstate, PyExc_SystemError, @@ -733,29 +768,44 @@ dummy_func( inst(INTERPRETER_EXIT, (retval --)) { assert(frame == &entry_frame); assert(_PyFrame_IsIncomplete(frame)); - /* Restore previous cframe and return. */ - tstate->cframe = cframe.previous; - assert(tstate->cframe->current_frame == frame->previous); + /* Restore previous frame and return. */ + tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - _Py_LeaveRecursiveCallTstate(tstate); + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; return retval; } - inst(RETURN_VALUE, (retval --)) { - STACK_SHRINK(1); + // The stack effect here is ambiguous. + // We definitely pop the return value off the stack on entry. + // We also push it onto the stack on exit, but that's a + // different frame, and it's accounted for by _PUSH_FRAME. + op(_POP_FRAME, (retval --)) { assert(EMPTY()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _Py_LeaveRecursiveCallPy(tstate); + #if TIER_ONE assert(frame != &entry_frame); + #endif + STORE_SP(); + _Py_LeaveRecursiveCallPy(tstate); // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); - goto resume_frame; + LOAD_SP(); + LOAD_IP(); +#if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } +#endif } + macro(RETURN_VALUE) = + _SAVE_CURRENT_IP + // Sets frame->prev_instr + _POP_FRAME; + inst(INSTRUMENTED_RETURN_VALUE, (retval --)) { int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_RETURN, @@ -768,28 +818,17 @@ dummy_func( assert(frame != &entry_frame); // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; } - inst(RETURN_CONST, (--)) { - PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg); - Py_INCREF(retval); - assert(EMPTY()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _Py_LeaveRecursiveCallPy(tstate); - assert(frame != &entry_frame); - // GH-99729: We need to unlink the frame *before* clearing it: - _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; - _PyFrame_StackPush(frame, retval); - goto resume_frame; - } + macro(RETURN_CONST) = + LOAD_CONST + + _SAVE_CURRENT_IP + // Sets frame->prev_instr + _POP_FRAME; inst(INSTRUMENTED_RETURN_CONST, (--)) { PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg); @@ -804,8 +843,8 @@ dummy_func( assert(frame != &entry_frame); // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; @@ -893,7 +932,7 @@ dummy_func( iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { - format_awaitable_error(tstate, Py_TYPE(iterable), oparg); + _PyEval_FormatAwaitableError(tstate, Py_TYPE(iterable), oparg); } DECREF_INPUTS(); @@ -937,13 +976,13 @@ dummy_func( { PyGenObject *gen = (PyGenObject *)receiver; _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - frame->return_offset = oparg; STACK_SHRINK(1); _PyFrame_StackPush(gen_frame, v); gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); + frame->return_offset = oparg; DISPATCH_INLINED(gen_frame); } if (Py_IsNone(v) && PyIter_Check(receiver)) { @@ -969,20 +1008,19 @@ dummy_func( } inst(SEND_GEN, (unused/1, receiver, v -- receiver, unused)) { - DEOPT_IF(tstate->interp->eval_frame, SEND); + DEOPT_IF(tstate->interp->eval_frame); PyGenObject *gen = (PyGenObject *)receiver; - DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && - Py_TYPE(gen) != &PyCoro_Type, SEND); - DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); STAT_INC(SEND, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - frame->return_offset = oparg; STACK_SHRINK(1); _PyFrame_StackPush(gen_frame, v); gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); + frame->return_offset = oparg; DISPATCH_INLINED(gen_frame); } @@ -1000,7 +1038,7 @@ dummy_func( gen->gi_exc_state.previous_item = NULL; _Py_LeaveRecursiveCallPy(tstate); _PyInterpreterFrame *gen_frame = frame; - frame = cframe.current_frame = frame->previous; + frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; @@ -1019,7 +1057,7 @@ dummy_func( gen->gi_exc_state.previous_item = NULL; _Py_LeaveRecursiveCallPy(tstate); _PyInterpreterFrame *gen_frame = frame; - frame = cframe.current_frame = frame->previous; + frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; @@ -1047,6 +1085,7 @@ dummy_func( assert(exc && PyExceptionInstance_Check(exc)); Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); goto exception_unwind; } @@ -1058,6 +1097,7 @@ dummy_func( else { Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); goto exception_unwind; } } @@ -1072,6 +1112,7 @@ dummy_func( } else { _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); + monitor_reraise(tstate, frame, next_instr-1); goto exception_unwind; } } @@ -1120,9 +1161,9 @@ dummy_func( err = PyObject_DelItem(ns, name); // Can't use ERROR_IF here. if (err != 0) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); goto error; } } @@ -1145,14 +1186,14 @@ dummy_func( DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; - int res = unpack_iterable(tstate, seq, oparg, -1, top); + int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top); DECREF_INPUTS(); ERROR_IF(res == 0, error); } inst(UNPACK_SEQUENCE_TWO_TUPLE, (unused/1, seq -- values[oparg])) { - DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); + DEOPT_IF(!PyTuple_CheckExact(seq)); + DEOPT_IF(PyTuple_GET_SIZE(seq) != 2); assert(oparg == 2); STAT_INC(UNPACK_SEQUENCE, hit); values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); @@ -1161,8 +1202,8 @@ dummy_func( } inst(UNPACK_SEQUENCE_TUPLE, (unused/1, seq -- values[oparg])) { - DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + DEOPT_IF(!PyTuple_CheckExact(seq)); + DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg); STAT_INC(UNPACK_SEQUENCE, hit); PyObject **items = _PyTuple_ITEMS(seq); for (int i = oparg; --i >= 0; ) { @@ -1172,8 +1213,8 @@ dummy_func( } inst(UNPACK_SEQUENCE_LIST, (unused/1, seq -- values[oparg])) { - DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + DEOPT_IF(!PyList_CheckExact(seq)); + DEOPT_IF(PyList_GET_SIZE(seq) != oparg); STAT_INC(UNPACK_SEQUENCE, hit); PyObject **items = _PyList_ITEMS(seq); for (int i = oparg; --i >= 0; ) { @@ -1185,7 +1226,7 @@ dummy_func( inst(UNPACK_EX, (seq -- unused[oparg & 0xFF], unused, unused[oparg >> 8])) { int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; - int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); + int res = _PyEval_UnpackIterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); DECREF_INPUTS(); ERROR_IF(res == 0, error); } @@ -1235,14 +1276,14 @@ dummy_func( // Can't use ERROR_IF here. if (err != 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } goto error; } } - op(_LOAD_LOCALS, ( -- locals)) { + inst(LOAD_LOCALS, ( -- locals)) { locals = LOCALS(); if (locals == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -1252,15 +1293,11 @@ dummy_func( Py_INCREF(locals); } - macro(LOAD_LOCALS) = _LOAD_LOCALS; - - op(_LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) { + inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { - Py_DECREF(mod_or_class_dict); goto error; } - Py_DECREF(mod_or_class_dict); if (v == NULL) { v = PyDict_GetItemWithError(GLOBALS(), name); if (v != NULL) { @@ -1274,25 +1311,55 @@ dummy_func( goto error; } if (v == NULL) { - format_exc_check_arg( + _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); goto error; } } } + DECREF_INPUTS(); } - macro(LOAD_NAME) = _LOAD_LOCALS + _LOAD_FROM_DICT_OR_GLOBALS; - - macro(LOAD_FROM_DICT_OR_GLOBALS) = _LOAD_FROM_DICT_OR_GLOBALS; + inst(LOAD_NAME, (-- v)) { + PyObject *mod_or_class_dict = LOCALS(); + if (mod_or_class_dict == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + ERROR_IF(true, error); + } + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { + goto error; + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { + goto error; + } + if (v == NULL) { + _PyEval_FormatExcCheckArg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + goto error; + } + } + } + } family(LOAD_GLOBAL, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { LOAD_GLOBAL_MODULE, LOAD_GLOBAL_BUILTIN, }; - inst(LOAD_GLOBAL, (unused/1, unused/1, unused/1, unused/1 -- null if (oparg & 1), v)) { + inst(LOAD_GLOBAL, (unused/1, unused/1, unused/1, unused/1 -- res, null if (oparg & 1))) { #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1308,30 +1375,30 @@ dummy_func( if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) { - v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), - (PyDictObject *)BUILTINS(), - name); - if (v == NULL) { + res = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), + (PyDictObject *)BUILTINS(), + name); + if (res == NULL) { if (!_PyErr_Occurred(tstate)) { /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } ERROR_IF(true, error); } - Py_INCREF(v); + Py_INCREF(res); } else { /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ - ERROR_IF(PyMapping_GetOptionalItem(GLOBALS(), name, &v) < 0, error); - if (v == NULL) { + ERROR_IF(PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0, error); + if (res == NULL) { /* namespace 2: builtins */ - ERROR_IF(PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0, error); - if (v == NULL) { - format_exc_check_arg( + ERROR_IF(PyMapping_GetOptionalItem(BUILTINS(), name, &res) < 0, error); + if (res == NULL) { + _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); ERROR_IF(true, error); @@ -1341,51 +1408,48 @@ dummy_func( null = NULL; } - op(_SKIP_CACHE, (unused/1 -- )) { - } - op(_GUARD_GLOBALS_VERSION, (version/1 --)) { PyDictObject *dict = (PyDictObject *)GLOBALS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(dict)); + DEOPT_IF(dict->ma_keys->dk_version != version); assert(DK_IS_UNICODE(dict->ma_keys)); } op(_GUARD_BUILTINS_VERSION, (version/1 --)) { PyDictObject *dict = (PyDictObject *)BUILTINS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(dict)); + DEOPT_IF(dict->ma_keys->dk_version != version); assert(DK_IS_UNICODE(dict->ma_keys)); } - op(_LOAD_GLOBAL_MODULE, (index/1 -- null if (oparg & 1), res)) { + op(_LOAD_GLOBAL_MODULE, (index/1 -- res, null if (oparg & 1))) { PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); + DEOPT_IF(res == NULL); Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; } - op(_LOAD_GLOBAL_BUILTINS, (index/1 -- null if (oparg & 1), res)) { + op(_LOAD_GLOBAL_BUILTINS, (index/1 -- res, null if (oparg & 1))) { PyDictObject *bdict = (PyDictObject *)BUILTINS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); + DEOPT_IF(res == NULL); Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; } macro(LOAD_GLOBAL_MODULE) = - _SKIP_CACHE + // Skip over the counter + unused/1 + // Skip over the counter _GUARD_GLOBALS_VERSION + - _SKIP_CACHE + // Skip over the builtins version + unused/1 + // Skip over the builtins version _LOAD_GLOBAL_MODULE; macro(LOAD_GLOBAL_BUILTIN) = - _SKIP_CACHE + // Skip over the counter + unused/1 + // Skip over the counter _GUARD_GLOBALS_VERSION + _GUARD_BUILTINS_VERSION + _LOAD_GLOBAL_BUILTINS; @@ -1413,7 +1477,7 @@ dummy_func( // Can't use ERROR_IF here. // Fortunately we don't need its superpower. if (oldobj == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); goto error; } PyCell_SET(cell, NULL); @@ -1434,7 +1498,7 @@ dummy_func( PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); goto error; } Py_INCREF(value); @@ -1445,7 +1509,7 @@ dummy_func( PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); ERROR_IF(true, error); } Py_INCREF(value); @@ -1533,9 +1597,6 @@ dummy_func( values, 2, values+1, 2, oparg); - if (map == NULL) - goto error; - DECREF_INPUTS(); ERROR_IF(map == NULL, error); } @@ -1594,8 +1655,7 @@ dummy_func( ERROR_IF(map == NULL, error); } - inst(DICT_UPDATE, (update --)) { - PyObject *dict = PEEK(oparg + 1); // update is still on the stack + inst(DICT_UPDATE, (dict, unused[oparg - 1], update -- dict, unused[oparg - 1])) { if (PyDict_Update(dict, update) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { _PyErr_Format(tstate, PyExc_TypeError, @@ -1608,26 +1668,23 @@ dummy_func( DECREF_INPUTS(); } - inst(DICT_MERGE, (update --)) { - PyObject *dict = PEEK(oparg + 1); // update is still on the stack - + inst(DICT_MERGE, (callable, unused, unused, dict, unused[oparg - 1], update -- callable, unused, unused, dict, unused[oparg - 1])) { if (_PyDict_MergeEx(dict, update, 2) < 0) { - format_kwargs_error(tstate, PEEK(3 + oparg), update); + _PyEval_FormatKwargsError(tstate, callable, update); DECREF_INPUTS(); ERROR_IF(true, error); } DECREF_INPUTS(); } - inst(MAP_ADD, (key, value --)) { - PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack + inst(MAP_ADD, (dict, unused[oparg - 1], key, value -- dict, unused[oparg - 1])) { assert(PyDict_CheckExact(dict)); /* dict[key] = value */ // Do not DECREF INPUTS because the function steals the references ERROR_IF(_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0, error); } - inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/9, unused, unused, unused -- unused if (oparg & 1), unused)) { + inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/9, unused, unused, unused -- unused, unused if (oparg & 1))) { _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we // don't want to specialize instrumented instructions @@ -1640,7 +1697,7 @@ dummy_func( LOAD_SUPER_ATTR_METHOD, }; - inst(LOAD_SUPER_ATTR, (unused/1, global_super, class, self -- res2 if (oparg & 1), res)) { + inst(LOAD_SUPER_ATTR, (unused/1, global_super, class, self -- attr, null if (oparg & 1))) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); int load_method = oparg & 1; #if ENABLE_SPECIALIZATION @@ -1684,9 +1741,10 @@ dummy_func( } DECREF_INPUTS(); ERROR_IF(super == NULL, error); - res = PyObject_GetAttr(super, name); + attr = PyObject_GetAttr(super, name); Py_DECREF(super); - ERROR_IF(res == NULL, error); + ERROR_IF(attr == NULL, error); + null = NULL; } pseudo(LOAD_SUPER_METHOD) = { @@ -1701,39 +1759,38 @@ dummy_func( LOAD_SUPER_ATTR, }; - inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super, class, self -- res2 if (oparg & 1), res)) { + inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super, class, self -- attr, unused if (0))) { assert(!(oparg & 1)); - DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); - DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); + DEOPT_IF(global_super != (PyObject *)&PySuper_Type); + DEOPT_IF(!PyType_Check(class)); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); - res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); + attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); DECREF_INPUTS(); - ERROR_IF(res == NULL, error); + ERROR_IF(attr == NULL, error); } - inst(LOAD_SUPER_ATTR_METHOD, (unused/1, global_super, class, self -- res2, res)) { + inst(LOAD_SUPER_ATTR_METHOD, (unused/1, global_super, class, self -- attr, self_or_null)) { assert(oparg & 1); - DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); - DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); + DEOPT_IF(global_super != (PyObject *)&PySuper_Type); + DEOPT_IF(!PyType_Check(class)); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); PyTypeObject *cls = (PyTypeObject *)class; int method_found = 0; - res2 = _PySuper_Lookup(cls, self, name, - cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); + attr = _PySuper_Lookup(cls, self, name, + Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); Py_DECREF(global_super); Py_DECREF(class); - if (res2 == NULL) { + if (attr == NULL) { Py_DECREF(self); ERROR_IF(true, error); } if (method_found) { - res = self; // transfer ownership + self_or_null = self; // transfer ownership } else { Py_DECREF(self); - res = res2; - res2 = NULL; + self_or_null = NULL; } } @@ -1752,7 +1809,7 @@ dummy_func( LOAD_ATTR_NONDESCRIPTOR_NO_DICT, }; - inst(LOAD_ATTR, (unused/9, owner -- res2 if (oparg & 1), res)) { + inst(LOAD_ATTR, (unused/9, owner -- attr, self_or_null if (oparg & 1))) { #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1767,16 +1824,15 @@ dummy_func( PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ - PyObject* meth = NULL; - if (_PyObject_GetMethod(owner, name, &meth)) { + attr = NULL; + if (_PyObject_GetMethod(owner, name, &attr)) { /* We can bypass temporary bound method object. meth is unbound method and obj is self. meth | self | arg1 | ... | argN */ - assert(meth != NULL); // No errors on this branch - res2 = meth; - res = owner; // Transfer ownership + assert(attr != NULL); // No errors on this branch + self_or_null = owner; // Transfer ownership } else { /* meth is not an unbound method (but a regular attr, or @@ -1787,16 +1843,15 @@ dummy_func( NULL | meth | arg1 | ... | argN */ DECREF_INPUTS(); - ERROR_IF(meth == NULL, error); - res2 = NULL; - res = meth; + ERROR_IF(attr == NULL, error); + self_or_null = NULL; } } else { /* Classic, pushes one value. */ - res = PyObject_GetAttr(owner, name); + attr = PyObject_GetAttr(owner, name); DECREF_INPUTS(); - ERROR_IF(res == NULL, error); + ERROR_IF(attr == NULL, error); } } @@ -1807,153 +1862,179 @@ dummy_func( op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) { PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + DEOPT_IF(tp->tp_version_tag != type_version); } op(_CHECK_MANAGED_OBJECT_HAS_VALUES, (owner -- owner)) { assert(Py_TYPE(owner)->tp_dictoffset < 0); assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)); } - op(_LOAD_ATTR_INSTANCE_VALUE, (index/1, unused/5, owner -- res2 if (oparg & 1), res)) { + op(_LOAD_ATTR_INSTANCE_VALUE, (index/1, owner -- attr, null if (oparg & 1))) { PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - res = _PyDictOrValues_GetValues(dorv)->values[index]; - DEOPT_IF(res == NULL, LOAD_ATTR); + attr = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; + Py_INCREF(attr); + null = NULL; DECREF_INPUTS(); } macro(LOAD_ATTR_INSTANCE_VALUE) = - _SKIP_CACHE + // Skip over the counter + unused/1 + // Skip over the counter _GUARD_TYPE_VERSION + _CHECK_MANAGED_OBJECT_HAS_VALUES + - _LOAD_ATTR_INSTANCE_VALUE; + _LOAD_ATTR_INSTANCE_VALUE + + unused/5; // Skip over rest of cache - inst(LOAD_ATTR_MODULE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { - DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); + op(_CHECK_ATTR_MODULE, (type_version/2, owner -- owner)) { + DEOPT_IF(!PyModule_CheckExact(owner)); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; assert(dict != NULL); - DEOPT_IF(dict->ma_keys->dk_version != type_version, LOAD_ATTR); + DEOPT_IF(dict->ma_keys->dk_version != type_version); + } + + op(_LOAD_ATTR_MODULE, (index/1, owner -- attr, null if (oparg & 1))) { + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); assert(index < dict->ma_keys->dk_nentries); PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index; - res = ep->me_value; - DEOPT_IF(res == NULL, LOAD_ATTR); + attr = ep->me_value; + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; + Py_INCREF(attr); + null = NULL; DECREF_INPUTS(); } - inst(LOAD_ATTR_WITH_HINT, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + macro(LOAD_ATTR_MODULE) = + unused/1 + + _CHECK_ATTR_MODULE + + _LOAD_ATTR_MODULE + + unused/5; + + op(_CHECK_ATTR_WITH_HINT, (owner -- owner)) { + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + DEOPT_IF(_PyDictOrValues_IsValues(dorv)); PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); - DEOPT_IF(dict == NULL, LOAD_ATTR); + DEOPT_IF(dict == NULL); assert(PyDict_CheckExact((PyObject *)dict)); + } + + op(_LOAD_ATTR_WITH_HINT, (hint/1, owner -- attr, null if (oparg & 1))) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - uint16_t hint = index; - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); if (DK_IS_UNICODE(dict->ma_keys)) { PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; + DEOPT_IF(ep->me_key != name); + attr = ep->me_value; } else { PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; + DEOPT_IF(ep->me_key != name); + attr = ep->me_value; } - DEOPT_IF(res == NULL, LOAD_ATTR); + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; + Py_INCREF(attr); + null = NULL; DECREF_INPUTS(); } - inst(LOAD_ATTR_SLOT, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + macro(LOAD_ATTR_WITH_HINT) = + unused/1 + + _GUARD_TYPE_VERSION + + _CHECK_ATTR_WITH_HINT + + _LOAD_ATTR_WITH_HINT + + unused/5; + + op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) { char *addr = (char *)owner + index; - res = *(PyObject **)addr; - DEOPT_IF(res == NULL, LOAD_ATTR); + attr = *(PyObject **)addr; + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; + Py_INCREF(attr); + null = NULL; DECREF_INPUTS(); } - inst(LOAD_ATTR_CLASS, (unused/1, type_version/2, unused/2, descr/4, cls -- res2 if (oparg & 1), res)) { + macro(LOAD_ATTR_SLOT) = + unused/1 + + _GUARD_TYPE_VERSION + + _LOAD_ATTR_SLOT + // NOTE: This action may also deopt + unused/5; - DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); - DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, - LOAD_ATTR); + op(_CHECK_ATTR_CLASS, (type_version/2, owner -- owner)) { + DEOPT_IF(!PyType_Check(owner)); assert(type_version != 0); + DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version); + + } + op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) { STAT_INC(LOAD_ATTR, hit); - res2 = NULL; - res = descr; - assert(res != NULL); - Py_INCREF(res); + assert(descr != NULL); + attr = Py_NewRef(descr); + null = NULL; DECREF_INPUTS(); } - inst(LOAD_ATTR_PROPERTY, (unused/1, type_version/2, func_version/2, fget/4, owner -- unused if (oparg & 1), unused)) { - DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + macro(LOAD_ATTR_CLASS) = + unused/1 + + _CHECK_ATTR_CLASS + + unused/2 + + _LOAD_ATTR_CLASS; + + inst(LOAD_ATTR_PROPERTY, (unused/1, type_version/2, func_version/2, fget/4, owner -- unused, unused if (0))) { + assert((oparg & 1) == 0); + DEOPT_IF(tstate->interp->eval_frame); PyTypeObject *cls = Py_TYPE(owner); - DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + DEOPT_IF(cls->tp_version_tag != type_version); assert(type_version != 0); assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; assert(func_version != 0); - DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + DEOPT_IF(f->func_version != func_version); PyCodeObject *code = (PyCodeObject *)f->func_code; assert(code->co_argcount == 1); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); STAT_INC(LOAD_ATTR, hit); Py_INCREF(fget); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); // Manipulate stack directly because we exit with DISPATCH_INLINED(). - SET_TOP(NULL); - int shrink_stack = !(oparg & 1); - STACK_SHRINK(shrink_stack); + STACK_SHRINK(1); new_frame->localsplus[0] = owner; SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } - inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused if (oparg & 1), unused)) { - DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused, unused if (0))) { + assert((oparg & 1) == 0); + DEOPT_IF(tstate->interp->eval_frame); PyTypeObject *cls = Py_TYPE(owner); - DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + DEOPT_IF(cls->tp_version_tag != type_version); assert(type_version != 0); assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)getattribute; assert(func_version != 0); - DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + DEOPT_IF(f->func_version != func_version); PyCodeObject *code = (PyCodeObject *)f->func_code; assert(code->co_argcount == 2); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); STAT_INC(LOAD_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); Py_INCREF(f); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2); // Manipulate stack directly because we exit with DISPATCH_INLINED(). - SET_TOP(NULL); - int shrink_stack = !(oparg & 1); - STACK_SHRINK(shrink_stack); + STACK_SHRINK(1); new_frame->localsplus[0] = owner; new_frame->localsplus[1] = Py_NewRef(name); SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); @@ -1961,13 +2042,14 @@ dummy_func( DISPATCH_INLINED(new_frame); } - inst(STORE_ATTR_INSTANCE_VALUE, (unused/1, type_version/2, index/1, value, owner --)) { - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + op(_GUARD_DORV_VALUES, (owner -- owner)) { + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv)); + } + + op(_STORE_ATTR_INSTANCE_VALUE, (index/1, value, owner --)) { PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); STAT_INC(STORE_ATTR, hit); PyDictValues *values = _PyDictOrValues_GetValues(dorv); PyObject *old_value = values->values[index]; @@ -1981,33 +2063,39 @@ dummy_func( Py_DECREF(owner); } + macro(STORE_ATTR_INSTANCE_VALUE) = + unused/1 + + _GUARD_TYPE_VERSION + + _GUARD_DORV_VALUES + + _STORE_ATTR_INSTANCE_VALUE; + inst(STORE_ATTR_WITH_HINT, (unused/1, type_version/2, hint/1, value, owner --)) { PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + DEOPT_IF(tp->tp_version_tag != type_version); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv), STORE_ATTR); + DEOPT_IF(_PyDictOrValues_IsValues(dorv)); PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); - DEOPT_IF(dict == NULL, STORE_ATTR); + DEOPT_IF(dict == NULL); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries); PyObject *old_value; uint64_t new_version; if (DK_IS_UNICODE(dict->ma_keys)) { PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); + DEOPT_IF(ep->me_key != name); old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); + DEOPT_IF(old_value == NULL); new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); ep->me_value = value; } else { PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); + DEOPT_IF(ep->me_key != name); old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); + DEOPT_IF(old_value == NULL); new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); ep->me_value = value; } @@ -2022,10 +2110,7 @@ dummy_func( Py_DECREF(owner); } - inst(STORE_ATTR_SLOT, (unused/1, type_version/2, index/1, value, owner --)) { - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + op(_STORE_ATTR_SLOT, (index/1, value, owner --)) { char *addr = (char *)owner + index; STAT_INC(STORE_ATTR, hit); PyObject *old_value = *(PyObject **)addr; @@ -2034,6 +2119,11 @@ dummy_func( Py_DECREF(owner); } + macro(STORE_ATTR_SLOT) = + unused/1 + + _GUARD_TYPE_VERSION + + _STORE_ATTR_SLOT; + family(COMPARE_OP, INLINE_CACHE_ENTRIES_COMPARE_OP) = { COMPARE_OP_FLOAT, COMPARE_OP_INT, @@ -2064,8 +2154,8 @@ dummy_func( } inst(COMPARE_OP_FLOAT, (unused/1, left, right -- res)) { - DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); + DEOPT_IF(!PyFloat_CheckExact(left)); + DEOPT_IF(!PyFloat_CheckExact(right)); STAT_INC(COMPARE_OP, hit); double dleft = PyFloat_AS_DOUBLE(left); double dright = PyFloat_AS_DOUBLE(right); @@ -2079,10 +2169,10 @@ dummy_func( // Similar to COMPARE_OP_FLOAT inst(COMPARE_OP_INT, (unused/1, left, right -- res)) { - DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); - DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); - DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP); + DEOPT_IF(!PyLong_CheckExact(left)); + DEOPT_IF(!PyLong_CheckExact(right)); + DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left)); + DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right)); STAT_INC(COMPARE_OP, hit); assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 && _PyLong_DigitCount((PyLongObject *)right) <= 1); @@ -2098,8 +2188,8 @@ dummy_func( // Similar to COMPARE_OP_FLOAT, but for ==, != only inst(COMPARE_OP_STR, (unused/1, left, right -- res)) { - DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); + DEOPT_IF(!PyUnicode_CheckExact(left)); + DEOPT_IF(!PyUnicode_CheckExact(right)); STAT_INC(COMPARE_OP, hit); int eq = _PyUnicode_Equal(left, right); assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE); @@ -2126,15 +2216,15 @@ dummy_func( } inst(CHECK_EG_MATCH, (exc_value, match_type -- rest, match)) { - if (check_except_star_type_valid(tstate, match_type) < 0) { + if (_PyEval_CheckExceptStarTypeValid(tstate, match_type) < 0) { DECREF_INPUTS(); ERROR_IF(true, error); } match = NULL; rest = NULL; - int res = exception_group_match(exc_value, match_type, - &match, &rest); + int res = _PyEval_ExceptionGroupMatch(exc_value, match_type, + &match, &rest); DECREF_INPUTS(); ERROR_IF(res < 0, error); @@ -2148,7 +2238,7 @@ dummy_func( inst(CHECK_EXC_MATCH, (left, right -- left, b)) { assert(PyExceptionInstance_Check(left)); - if (check_except_type_valid(tstate, right) < 0) { + if (_PyEval_CheckExceptTypeValid(tstate, right) < 0) { DECREF_INPUTS(); ERROR_IF(true, error); } @@ -2182,16 +2272,19 @@ dummy_func( JUMPBY(1-oparg); #if ENABLE_SPECIALIZATION here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER); - if (here[1].cache > tstate->interp->optimizer_backedge_threshold) { - OBJECT_STAT_INC(optimization_attempts); - frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer); - if (frame == NULL) { - frame = cframe.current_frame; - goto resume_with_error; + if (here[1].cache > tstate->interp->optimizer_backedge_threshold && + // Double-check that the opcode isn't instrumented or something: + here->op.code == JUMP_BACKWARD) + { + OPT_STAT_INC(attempts); + int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer); + ERROR_IF(optimized < 0, error); + if (optimized) { + // Rewind and enter the executor: + assert(here->op.code == ENTER_EXECUTOR); + next_instr = here; } - assert(frame == cframe.current_frame); - here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) -1); - goto resume_frame; + here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); } #endif /* ENABLE_SPECIALIZATION */ } @@ -2217,23 +2310,31 @@ dummy_func( Py_INCREF(executor); frame = executor->execute(executor, frame, stack_pointer); if (frame == NULL) { - frame = cframe.current_frame; + frame = tstate->current_frame; goto resume_with_error; } goto resume_frame; } - inst(POP_JUMP_IF_FALSE, (cond -- )) { + inst(POP_JUMP_IF_FALSE, (unused/1, cond -- )) { assert(PyBool_Check(cond)); - JUMPBY(oparg * Py_IsFalse(cond)); + int flag = Py_IsFalse(cond); + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif + JUMPBY(oparg * flag); } - inst(POP_JUMP_IF_TRUE, (cond -- )) { + inst(POP_JUMP_IF_TRUE, (unused/1, cond -- )) { assert(PyBool_Check(cond)); - JUMPBY(oparg * Py_IsTrue(cond)); + int flag = Py_IsTrue(cond); + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif + JUMPBY(oparg * flag); } - op(IS_NONE, (value -- b)) { + op(_IS_NONE, (value -- b)) { if (Py_IsNone(value)) { b = Py_True; } @@ -2243,9 +2344,9 @@ dummy_func( } } - macro(POP_JUMP_IF_NONE) = IS_NONE + POP_JUMP_IF_TRUE; + macro(POP_JUMP_IF_NONE) = _IS_NONE + POP_JUMP_IF_TRUE; - macro(POP_JUMP_IF_NOT_NONE) = IS_NONE + POP_JUMP_IF_FALSE; + macro(POP_JUMP_IF_NOT_NONE) = _IS_NONE + POP_JUMP_IF_FALSE; inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) { /* This bytecode is used in the `yield from` or `await` loop. @@ -2268,7 +2369,7 @@ dummy_func( // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); - attrs = match_class(tstate, subject, type, oparg, names); + attrs = _PyEval_MatchClass(tstate, subject, type, oparg, names); DECREF_INPUTS(); if (attrs) { assert(PyTuple_CheckExact(attrs)); // Success! @@ -2291,7 +2392,7 @@ dummy_func( inst(MATCH_KEYS, (subject, keys -- subject, keys, values_or_none)) { // On successful match, PUSH(values). Otherwise, PUSH(None). - values_or_none = match_keys(tstate, subject, keys); + values_or_none = _PyEval_MatchKeys(tstate, subject, keys); ERROR_IF(values_or_none == NULL, error); } @@ -2405,7 +2506,7 @@ dummy_func( } op(_ITER_CHECK_LIST, (iter -- iter)) { - DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); + DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type); } op(_ITER_JUMP_LIST, (iter -- iter)) { @@ -2461,7 +2562,7 @@ dummy_func( _ITER_NEXT_LIST; op(_ITER_CHECK_TUPLE, (iter -- iter)) { - DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER); + DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type); } op(_ITER_JUMP_TUPLE, (iter -- iter)) { @@ -2518,7 +2619,7 @@ dummy_func( op(_ITER_CHECK_RANGE, (iter -- iter)) { _PyRangeIterObject *r = (_PyRangeIterObject *)iter; - DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type); } op(_ITER_JUMP_RANGE, (iter -- iter)) { @@ -2560,13 +2661,12 @@ dummy_func( _ITER_NEXT_RANGE; inst(FOR_ITER_GEN, (unused/1, iter -- iter, unused)) { - DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); + DEOPT_IF(tstate->interp->eval_frame); PyGenObject *gen = (PyGenObject *)iter; - DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); - DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); STAT_INC(FOR_ITER, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - frame->return_offset = oparg; _PyFrame_StackPush(gen_frame, Py_None); gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; @@ -2574,6 +2674,7 @@ dummy_func( SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); + frame->return_offset = oparg; DISPATCH_INLINED(gen_frame); } @@ -2658,7 +2759,12 @@ dummy_func( assert(val && PyExceptionInstance_Check(val)); exc = PyExceptionInstance_Class(val); tb = PyException_GetTraceback(val); - Py_XDECREF(tb); + if (tb == NULL) { + tb = Py_None; + } + else { + Py_DECREF(tb); + } assert(PyLong_Check(lasti)); (void)lasti; // Shut up compiler warning if asserts are off PyObject *stack[4] = {NULL, exc, val, tb}; @@ -2695,92 +2801,109 @@ dummy_func( exc_info->exc_value = Py_NewRef(new_exc); } - inst(LOAD_ATTR_METHOD_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (1), res)) { + op(_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, (owner -- owner)) { + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)); + } + + op(_GUARD_KEYS_VERSION, (keys_version/2, owner -- owner)) { + PyTypeObject *owner_cls = Py_TYPE(owner); + PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; + DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version); + } + + op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) { assert(oparg & 1); /* Cached method object */ - PyTypeObject *self_cls = Py_TYPE(self); - assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; - DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != - keys_version, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); - res2 = Py_NewRef(descr); - assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); - res = self; + attr = Py_NewRef(descr); + assert(_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + self = owner; } - inst(LOAD_ATTR_METHOD_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (1), res)) { + macro(LOAD_ATTR_METHOD_WITH_VALUES) = + unused/1 + + _GUARD_TYPE_VERSION + + _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT + + _GUARD_KEYS_VERSION + + _LOAD_ATTR_METHOD_WITH_VALUES; + + op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) { assert(oparg & 1); - PyTypeObject *self_cls = Py_TYPE(self); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_dictoffset == 0); + assert(Py_TYPE(owner)->tp_dictoffset == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); - res2 = Py_NewRef(descr); - res = self; + attr = Py_NewRef(descr); + self = owner; } - inst(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (0), res)) { + macro(LOAD_ATTR_METHOD_NO_DICT) = + unused/1 + + _GUARD_TYPE_VERSION + + unused/2 + + _LOAD_ATTR_METHOD_NO_DICT; + + op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr, unused if (0))) { assert((oparg & 1) == 0); - PyTypeObject *self_cls = Py_TYPE(self); - assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; - DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != - keys_version, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); DECREF_INPUTS(); - res = Py_NewRef(descr); + attr = Py_NewRef(descr); } - inst(LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (0), res)) { + macro(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES) = + unused/1 + + _GUARD_TYPE_VERSION + + _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT + + _GUARD_KEYS_VERSION + + _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES; + + op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr, unused if (0))) { assert((oparg & 1) == 0); - PyTypeObject *self_cls = Py_TYPE(self); - assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_dictoffset == 0); + assert(Py_TYPE(owner)->tp_dictoffset == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); DECREF_INPUTS(); - res = Py_NewRef(descr); + attr = Py_NewRef(descr); } - inst(LOAD_ATTR_METHOD_LAZY_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (1), res)) { - assert(oparg & 1); - PyTypeObject *self_cls = Py_TYPE(self); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - Py_ssize_t dictoffset = self_cls->tp_dictoffset; + macro(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) = + unused/1 + + _GUARD_TYPE_VERSION + + unused/2 + + _LOAD_ATTR_NONDESCRIPTOR_NO_DICT; + + op(_CHECK_ATTR_METHOD_LAZY_DICT, (owner -- owner)) { + Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset; assert(dictoffset > 0); - PyObject *dict = *(PyObject **)((char *)self + dictoffset); + PyObject *dict = *(PyObject **)((char *)owner + dictoffset); /* This object has a __dict__, just not yet created */ - DEOPT_IF(dict != NULL, LOAD_ATTR); + DEOPT_IF(dict != NULL); + } + + op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) { + assert(oparg & 1); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); - res2 = Py_NewRef(descr); - res = self; + attr = Py_NewRef(descr); + self = owner; } - inst(KW_NAMES, (--)) { - ASSERT_KWNAMES_IS_NULL(); - assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS)); - kwnames = GETITEM(FRAME_CO_CONSTS, oparg); - } + macro(LOAD_ATTR_METHOD_LAZY_DICT) = + unused/1 + + _GUARD_TYPE_VERSION + + _CHECK_ATTR_METHOD_LAZY_DICT + + unused/2 + + _LOAD_ATTR_METHOD_LAZY_DICT; inst(INSTRUMENTED_CALL, ( -- )) { - int is_meth = PEEK(oparg+2) != NULL; + int is_meth = PEEK(oparg + 1) != NULL; int total_args = oparg + is_meth; - PyObject *function = PEEK(total_args + 1); + PyObject *function = PEEK(oparg + 2); PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING : PEEK(total_args); int err = _Py_call_instrumentation_2args( @@ -2793,40 +2916,33 @@ dummy_func( } // Cache layout: counter/1, func_version/2 - // Neither CALL_INTRINSIC_1/2 nor CALL_FUNCTION_EX are members! + // CALL_INTRINSIC_1/2, CALL_KW, and CALL_FUNCTION_EX aren't members! family(CALL, INLINE_CACHE_ENTRIES_CALL) = { CALL_BOUND_METHOD_EXACT_ARGS, CALL_PY_EXACT_ARGS, CALL_PY_WITH_DEFAULTS, - CALL_NO_KW_TYPE_1, - CALL_NO_KW_STR_1, - CALL_NO_KW_TUPLE_1, + CALL_TYPE_1, + CALL_STR_1, + CALL_TUPLE_1, CALL_BUILTIN_CLASS, - CALL_NO_KW_BUILTIN_O, - CALL_NO_KW_BUILTIN_FAST, + CALL_BUILTIN_O, + CALL_BUILTIN_FAST, CALL_BUILTIN_FAST_WITH_KEYWORDS, - CALL_NO_KW_LEN, - CALL_NO_KW_ISINSTANCE, - CALL_NO_KW_LIST_APPEND, - CALL_NO_KW_METHOD_DESCRIPTOR_O, + CALL_LEN, + CALL_ISINSTANCE, + CALL_LIST_APPEND, + CALL_METHOD_DESCRIPTOR_O, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, - CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, - CALL_NO_KW_METHOD_DESCRIPTOR_FAST, - CALL_NO_KW_ALLOC_AND_ENTER_INIT, + CALL_METHOD_DESCRIPTOR_NOARGS, + CALL_METHOD_DESCRIPTOR_FAST, + CALL_ALLOC_AND_ENTER_INIT, }; - // On entry, the stack is either - // [NULL, callable, arg1, arg2, ...] - // or - // [method, self, arg1, arg2, ...] - // (Some args may be keywords, see KW_NAMES, which sets 'kwnames'.) - // On exit, the stack is [result]. // When calling Python, inline the call using DISPATCH_INLINED(). - inst(CALL, (unused/1, unused/2, method, callable, args[oparg] -- res)) { - int is_meth = method != NULL; + inst(CALL, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { + // oparg counts all of the args, but *not* self: int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } @@ -2834,24 +2950,22 @@ dummy_func( _PyCallCache *cache = (_PyCallCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { next_instr--; - _Py_Specialize_Call(callable, next_instr, total_args, kwnames); + _Py_Specialize_Call(callable, next_instr, total_args); DISPATCH_SAME_OPARG(); } STAT_INC(CALL, deferred); DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ - if (!is_meth && Py_TYPE(callable) == &PyMethod_Type) { - is_meth = 1; // For consistenct; it's dead, though + if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) { args--; total_args++; PyObject *self = ((PyMethodObject *)callable)->im_self; args[0] = Py_NewRef(self); - method = ((PyMethodObject *)callable)->im_func; + PyObject *method = ((PyMethodObject *)callable)->im_func; args[-1] = Py_NewRef(method); Py_DECREF(callable); callable = method; } - int positional_args = total_args - KWNAMES_LEN(); // Check if the call can be inlined or not if (Py_TYPE(callable) == &PyFunction_Type && tstate->interp->eval_frame == NULL && @@ -2861,9 +2975,8 @@ dummy_func( PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( tstate, (PyFunctionObject *)callable, locals, - args, positional_args, kwnames + args, total_args, NULL ); - kwnames = NULL; // Manipulate stack directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); // The frame has stolen all the arguments from the stack, @@ -2878,11 +2991,11 @@ dummy_func( /* Callable is not a normal Python function */ res = PyObject_Vectorcall( callable, args, - positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, - kwnames); + total_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + NULL); if (opcode == INSTRUMENTED_CALL) { PyObject *arg = total_args == 0 ? - &_PyInstrumentation_MISSING : PEEK(total_args); + &_PyInstrumentation_MISSING : args[0]; if (res == NULL) { _Py_call_instrumentation_exc2( tstate, PY_MONITORING_EVENT_C_RAISE, @@ -2897,7 +3010,6 @@ dummy_func( } } } - kwnames = NULL; assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); Py_DECREF(callable); for (int i = 0; i < total_args; i++) { @@ -2907,71 +3019,115 @@ dummy_func( CHECK_EVAL_BREAKER(); } - // Start out with [NULL, bound_method, arg1, arg2, ...] - // Transform to [callable, self, arg1, arg2, ...] - // Then fall through to CALL_PY_EXACT_ARGS - inst(CALL_BOUND_METHOD_EXACT_ARGS, (unused/1, unused/2, method, callable, unused[oparg] -- unused)) { - DEOPT_IF(method != NULL, CALL); - DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); + op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) { + DEOPT_IF(null != NULL); + DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type); + } + + op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- func, self, unused[oparg])) { STAT_INC(CALL, hit); - PyObject *self = ((PyMethodObject *)callable)->im_self; - PEEK(oparg + 1) = Py_NewRef(self); // callable - PyObject *meth = ((PyMethodObject *)callable)->im_func; - PEEK(oparg + 2) = Py_NewRef(meth); // method + self = Py_NewRef(((PyMethodObject *)callable)->im_self); + stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _INIT_CALL_PY_EXACT_ARGS + func = Py_NewRef(((PyMethodObject *)callable)->im_func); + stack_pointer[-2 - oparg] = func; // This is used by CALL, upon deoptimization Py_DECREF(callable); - GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); } - inst(CALL_PY_EXACT_ARGS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) { - ASSERT_KWNAMES_IS_NULL(); - DEOPT_IF(tstate->interp->eval_frame, CALL); - int is_meth = method != NULL; + op(_CHECK_PEP_523, (--)) { + DEOPT_IF(tstate->interp->eval_frame); + } + + op(_CHECK_FUNCTION_EXACT_ARGS, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { + DEOPT_IF(!PyFunction_Check(callable)); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL)); + } + + op(_CHECK_STACK_SPACE, (callable, unused, unused[oparg] -- callable, unused, unused[oparg])) { + PyFunctionObject *func = (PyFunctionObject *)callable; + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); + DEOPT_IF(tstate->py_recursion_remaining <= 1); + } + + op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) { int argcount = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; argcount++; } - DEOPT_IF(!PyFunction_Check(callable), CALL); - PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != func_version, CALL); - PyCodeObject *code = (PyCodeObject *)func->func_code; - DEOPT_IF(code->co_argcount != argcount, CALL); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); STAT_INC(CALL, hit); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + PyFunctionObject *func = (PyFunctionObject *)callable; + new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); for (int i = 0; i < argcount; i++) { new_frame->localsplus[i] = args[i]; } - // Manipulate stack directly since we leave using DISPATCH_INLINED(). - STACK_SHRINK(oparg + 2); - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); } - inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) { - ASSERT_KWNAMES_IS_NULL(); - DEOPT_IF(tstate->interp->eval_frame, CALL); - int is_meth = method != NULL; + // The 'unused' output effect represents the return value + // (which will be pushed when the frame returns). + // It is needed so CALL_PY_EXACT_ARGS matches its family. + op(_PUSH_FRAME, (new_frame: _PyInterpreterFrame* -- unused)) { + // Write it out explicitly because it's subtly different. + // Eventually this should be the only occurrence of this code. + frame->return_offset = 0; + assert(tstate->interp->eval_frame == NULL); + STORE_SP(); + new_frame->previous = frame; + CALL_STAT_INC(inlined_py_calls); + frame = tstate->current_frame = new_frame; + tstate->py_recursion_remaining--; + LOAD_SP(); + LOAD_IP(); +#if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } +#endif + } + + macro(CALL_BOUND_METHOD_EXACT_ARGS) = + unused/1 + // Skip over the counter + _CHECK_PEP_523 + + _CHECK_CALL_BOUND_METHOD_EXACT_ARGS + + _INIT_CALL_BOUND_METHOD_EXACT_ARGS + + _CHECK_FUNCTION_EXACT_ARGS + + _CHECK_STACK_SPACE + + _INIT_CALL_PY_EXACT_ARGS + + _SAVE_CURRENT_IP + // Sets frame->prev_instr + _PUSH_FRAME; + + macro(CALL_PY_EXACT_ARGS) = + unused/1 + // Skip over the counter + _CHECK_PEP_523 + + _CHECK_FUNCTION_EXACT_ARGS + + _CHECK_STACK_SPACE + + _INIT_CALL_PY_EXACT_ARGS + + _SAVE_CURRENT_IP + // Sets frame->prev_instr + _PUSH_FRAME; + + inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) { + DEOPT_IF(tstate->interp->eval_frame); int argcount = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; argcount++; } - DEOPT_IF(!PyFunction_Check(callable), CALL); + DEOPT_IF(!PyFunction_Check(callable)); PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != func_version, CALL); + DEOPT_IF(func->func_version != func_version); PyCodeObject *code = (PyCodeObject *)func->func_code; assert(func->func_defaults); assert(PyTuple_CheckExact(func->func_defaults)); int defcount = (int)PyTuple_GET_SIZE(func->func_defaults); assert(defcount <= code->co_argcount); int min_args = code->co_argcount - defcount; - DEOPT_IF(argcount > code->co_argcount, CALL); - DEOPT_IF(argcount < min_args, CALL); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + DEOPT_IF(argcount > code->co_argcount); + DEOPT_IF(argcount < min_args); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); STAT_INC(CALL, hit); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount); for (int i = 0; i < argcount; i++) { @@ -2988,23 +3144,21 @@ dummy_func( DISPATCH_INLINED(new_frame); } - inst(CALL_NO_KW_TYPE_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); + inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) { assert(oparg == 1); - DEOPT_IF(null != NULL, CALL); + DEOPT_IF(null != NULL); PyObject *obj = args[0]; - DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); + DEOPT_IF(callable != (PyObject *)&PyType_Type); STAT_INC(CALL, hit); res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable } - inst(CALL_NO_KW_STR_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); + inst(CALL_STR_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) { assert(oparg == 1); - DEOPT_IF(null != NULL, CALL); - DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); + DEOPT_IF(null != NULL); + DEOPT_IF(callable != (PyObject *)&PyUnicode_Type); STAT_INC(CALL, hit); PyObject *arg = args[0]; res = PyObject_Str(arg); @@ -3014,11 +3168,10 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_NO_KW_TUPLE_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); + inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) { assert(oparg == 1); - DEOPT_IF(null != NULL, CALL); - DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); + DEOPT_IF(null != NULL); + DEOPT_IF(callable != (PyObject *)&PyTuple_Type); STAT_INC(CALL, hit); PyObject *arg = args[0]; res = PySequence_Tuple(arg); @@ -3028,23 +3181,22 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_NO_KW_ALLOC_AND_ENTER_INIT, (unused/1, unused/2, null, callable, args[oparg] -- unused)) { + inst(CALL_ALLOC_AND_ENTER_INIT, (unused/1, unused/2, callable, null, args[oparg] -- unused)) { /* This instruction does the following: * 1. Creates the object (by calling ``object.__new__``) * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) * 3. Pushes the frame for ``__init__`` to the frame stack * */ - ASSERT_KWNAMES_IS_NULL(); _PyCallCache *cache = (_PyCallCache *)next_instr; - DEOPT_IF(null != NULL, CALL); - DEOPT_IF(!PyType_Check(callable), CALL); + DEOPT_IF(null != NULL); + DEOPT_IF(!PyType_Check(callable)); PyTypeObject *tp = (PyTypeObject *)callable; - DEOPT_IF(tp->tp_version_tag != read_u32(cache->func_version), CALL); + DEOPT_IF(tp->tp_version_tag != read_u32(cache->func_version)); PyHeapTypeObject *cls = (PyHeapTypeObject *)callable; PyFunctionObject *init = (PyFunctionObject *)cls->_spec_cache.init; PyCodeObject *code = (PyCodeObject *)init->func_code; - DEOPT_IF(code->co_argcount != oparg+1, CALL); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize + _Py_InitCleanup.co_framesize), CALL); + DEOPT_IF(code->co_argcount != oparg+1); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize + _Py_InitCleanup.co_framesize)); STAT_INC(CALL, hit); PyObject *self = _PyType_NewManagedObject(tp); if (self == NULL) { @@ -3052,7 +3204,7 @@ dummy_func( } Py_DECREF(tp); _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( - tstate, (PyCodeObject *)&_Py_InitCleanup, 1, 0); + tstate, (PyCodeObject *)&_Py_InitCleanup, 1); assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK); /* Push self onto stack of shim */ Py_INCREF(self); @@ -3072,7 +3224,7 @@ dummy_func( /* Link frames */ init_frame->previous = shim; shim->previous = frame; - frame = cframe.current_frame = init_frame; + frame = tstate->current_frame = init_frame; CALL_STAT_INC(inlined_py_calls); /* Account for pushing the extra frame. * We don't check recursion depth here, @@ -3091,22 +3243,17 @@ dummy_func( } } - inst(CALL_BUILTIN_CLASS, (unused/1, unused/2, method, callable, args[oparg] -- res)) { - int is_meth = method != NULL; + inst(CALL_BUILTIN_CLASS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } - int kwnames_len = KWNAMES_LEN(); - DEOPT_IF(!PyType_Check(callable), CALL); + DEOPT_IF(!PyType_Check(callable)); PyTypeObject *tp = (PyTypeObject *)callable; - DEOPT_IF(tp->tp_vectorcall == NULL, CALL); + DEOPT_IF(tp->tp_vectorcall == NULL); STAT_INC(CALL, hit); - res = tp->tp_vectorcall((PyObject *)tp, args, - total_args - kwnames_len, kwnames); - kwnames = NULL; + res = tp->tp_vectorcall((PyObject *)tp, args, total_args, NULL); /* Free the arguments. */ for (int i = 0; i < total_args; i++) { Py_DECREF(args[i]); @@ -3116,19 +3263,16 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_NO_KW_BUILTIN_O, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + inst(CALL_BUILTIN_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { /* Builtin METH_O functions */ - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); + DEOPT_IF(total_args != 1); + DEOPT_IF(!PyCFunction_CheckExact(callable)); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O); STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); // This is slower but CPython promises to check all non-vectorcall @@ -3147,18 +3291,15 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_NO_KW_BUILTIN_FAST, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + inst(CALL_BUILTIN_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { /* Builtin METH_FASTCALL functions, without keywords */ - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, CALL); + DEOPT_IF(!PyCFunction_CheckExact(callable)); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL); STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); /* res = func(self, args, nargs) */ @@ -3182,31 +3323,22 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_BUILTIN_FAST_WITH_KEYWORDS, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + inst(CALL_BUILTIN_FAST_WITH_KEYWORDS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != - (METH_FASTCALL | METH_KEYWORDS), CALL); + DEOPT_IF(!PyCFunction_CheckExact(callable)); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS)); STAT_INC(CALL, hit); /* res = func(self, args, nargs, kwnames) */ _PyCFunctionFastWithKeywords cfunc = (_PyCFunctionFastWithKeywords)(void(*)(void)) PyCFunction_GET_FUNCTION(callable); - res = cfunc( - PyCFunction_GET_SELF(callable), - args, - total_args - KWNAMES_LEN(), - kwnames - ); + res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - kwnames = NULL; /* Free the arguments. */ for (int i = 0; i < total_args; i++) { @@ -3217,19 +3349,16 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_NO_KW_LEN, (unused/1, unused/2, method, callable, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); + inst(CALL_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { /* len(o) */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); - PyInterpreterState *interp = _PyInterpreterState_GET(); - DEOPT_IF(callable != interp->callable_cache.len, CALL); + DEOPT_IF(total_args != 1); + PyInterpreterState *interp = tstate->interp; + DEOPT_IF(callable != interp->callable_cache.len); STAT_INC(CALL, hit); PyObject *arg = args[0]; Py_ssize_t len_i = PyObject_Length(arg); @@ -3244,19 +3373,16 @@ dummy_func( ERROR_IF(res == NULL, error); } - inst(CALL_NO_KW_ISINSTANCE, (unused/1, unused/2, method, callable, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); + inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { /* isinstance(o, o2) */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } - DEOPT_IF(total_args != 2, CALL); - PyInterpreterState *interp = _PyInterpreterState_GET(); - DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + DEOPT_IF(total_args != 2); + PyInterpreterState *interp = tstate->interp; + DEOPT_IF(callable != interp->callable_cache.isinstance); STAT_INC(CALL, hit); PyObject *cls = args[1]; PyObject *inst = args[0]; @@ -3274,19 +3400,18 @@ dummy_func( } // This is secretly a super-instruction - inst(CALL_NO_KW_LIST_APPEND, (unused/1, unused/2, method, self, args[oparg] -- unused)) { - ASSERT_KWNAMES_IS_NULL(); + inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) { assert(oparg == 1); - assert(method != NULL); - PyInterpreterState *interp = _PyInterpreterState_GET(); - DEOPT_IF(method != interp->callable_cache.list_append, CALL); - DEOPT_IF(!PyList_Check(self), CALL); + PyInterpreterState *interp = tstate->interp; + DEOPT_IF(callable != interp->callable_cache.list_append); + assert(self != NULL); + DEOPT_IF(!PyList_Check(self)); STAT_INC(CALL, hit); if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) { goto pop_1_error; // Since arg is DECREF'ed already } Py_DECREF(self); - Py_DECREF(method); + Py_DECREF(callable); STACK_SHRINK(3); // CALL + POP_TOP SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); @@ -3294,23 +3419,20 @@ dummy_func( DISPATCH(); } - inst(CALL_NO_KW_METHOD_DESCRIPTOR_O, (unused/1, unused/2, method, unused, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; + inst(CALL_METHOD_DESCRIPTOR_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); - DEOPT_IF(total_args != 2, CALL); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; - DEOPT_IF(meth->ml_flags != METH_O, CALL); + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + DEOPT_IF(total_args != 2); + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); + PyMethodDef *meth = method->d_method; + DEOPT_IF(meth->ml_flags != METH_O); PyObject *arg = args[1]; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall @@ -3328,28 +3450,25 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (unused/1, unused/2, method, unused, args[oparg] -- res)) { - int is_meth = method != NULL; + inst(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; - DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); - PyTypeObject *d_type = callable->d_common.d_type; + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); + PyMethodDef *meth = method->d_method; + DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS)); + PyTypeObject *d_type = method->d_common.d_type; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, d_type)); STAT_INC(CALL, hit); int nargs = total_args - 1; _PyCFunctionFastWithKeywords cfunc = (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; - res = cfunc(self, args + 1, nargs - KWNAMES_LEN(), kwnames); + res = cfunc(self, args + 1, nargs, NULL); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - kwnames = NULL; /* Free the arguments. */ for (int i = 0; i < total_args; i++) { @@ -3360,22 +3479,20 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, method, unused, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); + inst(CALL_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { assert(oparg == 0 || oparg == 1); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); - PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + DEOPT_IF(total_args != 1); + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); + PyMethodDef *meth = method->d_method; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); - DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); + DEOPT_IF(meth->ml_flags != METH_NOARGS); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall @@ -3392,22 +3509,19 @@ dummy_func( CHECK_EVAL_BREAKER(); } - inst(CALL_NO_KW_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, method, unused, args[oparg] -- res)) { - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; + inst(CALL_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; /* Builtin METH_FASTCALL methods, without keywords */ - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; - DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); + PyMethodDef *meth = method->d_method; + DEOPT_IF(meth->ml_flags != METH_FASTCALL); PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); STAT_INC(CALL, hit); _PyCFunctionFast cfunc = (_PyCFunctionFast)(void(*)(void))meth->ml_meth; @@ -3423,11 +3537,96 @@ dummy_func( CHECK_EVAL_BREAKER(); } + inst(INSTRUMENTED_CALL_KW, ( -- )) { + int is_meth = PEEK(oparg + 2) != NULL; + int total_args = oparg + is_meth; + PyObject *function = PEEK(oparg + 3); + PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING + : PEEK(total_args + 1); + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr - 1, function, arg); + ERROR_IF(err, error); + GO_TO_INSTRUCTION(CALL_KW); + } + + inst(CALL_KW, (callable, self_or_null, args[oparg], kwnames -- res)) { + // oparg counts all of the args, but *not* self: + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; + } + if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) { + args--; + total_args++; + PyObject *self = ((PyMethodObject *)callable)->im_self; + args[0] = Py_NewRef(self); + PyObject *method = ((PyMethodObject *)callable)->im_func; + args[-1] = Py_NewRef(method); + Py_DECREF(callable); + callable = method; + } + int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames); + // Check if the call can be inlined or not + if (Py_TYPE(callable) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)callable)->vectorcall == _PyFunction_Vectorcall) + { + int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( + tstate, (PyFunctionObject *)callable, locals, + args, positional_args, kwnames + ); + Py_DECREF(kwnames); + // Manipulate stack directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 3); + // The frame has stolen all the arguments from the stack, + // so there is no need to clean them up. + if (new_frame == NULL) { + goto error; + } + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + /* Callable is not a normal Python function */ + res = PyObject_Vectorcall( + callable, args, + positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames); + if (opcode == INSTRUMENTED_CALL_KW) { + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : args[0]; + if (res == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, callable, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, callable, arg); + if (err < 0) { + Py_CLEAR(res); + } + } + } + Py_DECREF(kwnames); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(callable); + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) { GO_TO_INSTRUCTION(CALL_FUNCTION_EX); } - inst(CALL_FUNCTION_EX, (unused, func, callargs, kwargs if (oparg & 1) -- result)) { + inst(CALL_FUNCTION_EX, (func, unused, callargs, kwargs if (oparg & 1) -- result)) { // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -3490,7 +3689,7 @@ dummy_func( result = PyObject_Call(func, callargs, kwargs); } DECREF_INPUTS(); - assert(PEEK(3 + (oparg & 1)) == NULL); + assert(PEEK(2 + (oparg & 1)) == NULL); ERROR_IF(result == NULL, error); CHECK_EVAL_BREAKER(); } @@ -3505,7 +3704,8 @@ dummy_func( goto error; } - func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; + _PyFunction_SetVersion( + func_obj, ((PyCodeObject *)codeobj)->co_version); func = (PyObject *)func_obj; } @@ -3554,7 +3754,7 @@ dummy_func( assert(frame != &entry_frame); _PyInterpreterFrame *prev = frame->previous; _PyThreadState_PopFrame(tstate, frame); - frame = cframe.current_frame = prev; + frame = tstate->current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; } @@ -3610,10 +3810,10 @@ dummy_func( STAT_INC(BINARY_OP, deferred); DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ - assert(0 <= oparg); - assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); - assert(binary_ops[oparg]); - res = binary_ops[oparg](lhs, rhs); + assert(NB_ADD <= oparg); + assert(oparg <= NB_INPLACE_XOR); + assert(_PyEval_BinaryOps[oparg]); + res = _PyEval_BinaryOps[oparg](lhs, rhs); DECREF_INPUTS(); ERROR_IF(res == NULL, error); } @@ -3646,47 +3846,63 @@ dummy_func( INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); } - inst(INSTRUMENTED_POP_JUMP_IF_TRUE, ( -- )) { + inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) { PyObject *cond = POP(); assert(PyBool_Check(cond)); _Py_CODEUNIT *here = next_instr - 1; - int offset = Py_IsTrue(cond) * oparg; + int flag = Py_IsTrue(cond); + int offset = flag * oparg; + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } - inst(INSTRUMENTED_POP_JUMP_IF_FALSE, ( -- )) { + inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) { PyObject *cond = POP(); assert(PyBool_Check(cond)); _Py_CODEUNIT *here = next_instr - 1; - int offset = Py_IsFalse(cond) * oparg; + int flag = Py_IsFalse(cond); + int offset = flag * oparg; + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } - inst(INSTRUMENTED_POP_JUMP_IF_NONE, ( -- )) { + inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1 -- )) { PyObject *value = POP(); - _Py_CODEUNIT *here = next_instr-1; + _Py_CODEUNIT *here = next_instr - 1; + int flag = Py_IsNone(value); int offset; - if (Py_IsNone(value)) { + if (flag) { offset = oparg; } else { Py_DECREF(value); offset = 0; } + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } - inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, ( -- )) { + inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1 -- )) { PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; - if (Py_IsNone(value)) { + int nflag = Py_IsNone(value); + if (nflag) { offset = 0; } else { Py_DECREF(value); offset = oparg; } + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | !nflag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } @@ -3722,22 +3938,34 @@ dummy_func( } } - op(JUMP_TO_TOP, (--)) { + op(_JUMP_TO_TOP, (--)) { pc = 0; CHECK_EVAL_BREAKER(); } - op(SAVE_IP, (--)) { + op(_SET_IP, (--)) { + TIER_TWO_ONLY frame->prev_instr = ip_offset + oparg; } - op(EXIT_TRACE, (--)) { + op(_SAVE_CURRENT_IP, (--)) { + TIER_ONE_ONLY + frame->prev_instr = next_instr - 1; + } + + op(_EXIT_TRACE, (--)) { frame->prev_instr--; // Back up to just before destination _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(self); + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); return frame; } + op(_INSERT, (unused[oparg], top -- top, unused[oparg])) { + // Inserts TOS at position specified by oparg; + memmove(&stack_pointer[-1 - oparg], &stack_pointer[-oparg], oparg * sizeof(stack_pointer[0])); + } + // END BYTECODES // diff --git a/Python/ceval.c b/Python/ceval.c index b56ddfb4bd286d..ac40425263931f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -7,24 +7,25 @@ #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_SignalAsyncExc() #include "pycore_code.h" +#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_function.h" +#include "pycore_instruments.h" #include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_instruments.h" -#include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_moduleobject.h" // PyModuleObject -#include "pycore_opcode.h" // EXTRA_CASES -#include "pycore_opcode_metadata.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_opcode_metadata.h" // EXTRA_CASES #include "pycore_opcode_utils.h" // MAKE_FUNCTION_* #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_range.h" // _PyRangeIterObject +#include "pycore_setobject.h" // _PySet_Update() #include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "pycore_typeobject.h" // _PySuper_Lookup() #include "pycore_uops.h" // _PyUOpExecutorObject -#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS +#include "pycore_pyerrors.h" #include "pycore_dict.h" #include "dictobject.h" @@ -33,10 +34,8 @@ #include "opcode.h" #include "pydtrace.h" #include "setobject.h" -#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX -#include -#include +#include // bool #ifdef Py_DEBUG /* For debugging the interpreter: */ @@ -96,13 +95,6 @@ } while (0) #endif -// GH-89279: Similar to above, force inlining by using a macro. -#if defined(_MSC_VER) && SIZEOF_INT == 4 -#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value))) -#else -#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) -#endif - #ifdef LLTRACE static void @@ -115,11 +107,24 @@ dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer) if (ptr != stack_base) { printf(", "); } - if (PyObject_Print(*ptr, stdout, 0) != 0) { + if (*ptr == NULL) { + printf(""); + continue; + } + if ( + *ptr == Py_None + || PyBool_Check(*ptr) + || PyLong_CheckExact(*ptr) + || PyFloat_CheckExact(*ptr) + || PyUnicode_CheckExact(*ptr) + ) { + if (PyObject_Print(*ptr, stdout, 0) == 0) { + continue; + } PyErr_Clear(); - printf("<%s object at %p>", - Py_TYPE(*ptr)->tp_name, (void *)(*ptr)); } + // Don't call __repr__(), it might recurse into the interpreter. + printf("<%s at %p>", Py_TYPE(*ptr)->tp_name, (void *)(*ptr)); } printf("]\n"); fflush(stdout); @@ -134,9 +139,6 @@ lltrace_instruction(_PyInterpreterFrame *frame, if (frame->owner == FRAME_OWNED_BY_CSTACK) { return; } - /* This dump_stack() operation is risky, since the repr() of some - objects enters the interpreter recursively. It is also slow. - So you might want to comment it out. */ dump_stack(frame, stack_pointer); int oparg = next_instr->op.arg; int opcode = next_instr->op.code; @@ -185,18 +187,49 @@ lltrace_resume_frame(_PyInterpreterFrame *frame) fflush(stdout); PyErr_SetRaisedException(exc); } + +static int +maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, _PyInterpreterFrame *skip_frame, PyObject *globals) +{ + if (globals == NULL) { + return 0; + } + if (frame == skip_frame) { + return 0; + } + int r = PyDict_Contains(globals, &_Py_ID(__lltrace__)); + if (r < 0) { + return -1; + } + int lltrace = r; + if (!lltrace) { + // When tracing executed uops, also trace bytecode + char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG"); + if (uop_debug != NULL && *uop_debug >= '0') { + lltrace = (*uop_debug - '0') >= 5; // TODO: Parse an int and all that + } + } + if (lltrace) { + lltrace_resume_frame(frame); + } + return lltrace; +} + #endif static void monitor_raise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); +static void monitor_reraise(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr); static int monitor_stop_iteration(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); static void monitor_unwind(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); -static void monitor_handled(PyThreadState *tstate, +static int monitor_handled(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *exc); static void monitor_throw(PyThreadState *tstate, @@ -206,13 +239,7 @@ static void monitor_throw(PyThreadState *tstate, static PyObject * import_name(PyThreadState *, _PyInterpreterFrame *, PyObject *, PyObject *, PyObject *); static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); -static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); -static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); -static int check_except_type_valid(PyThreadState *tstate, PyObject* right); -static int check_except_star_type_valid(PyThreadState *tstate, PyObject* right); -static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); -static void format_awaitable_error(PyThreadState *, PyTypeObject *, int); static int get_exception_handler(PyCodeObject *, int, int*, int*, int*); static _PyInterpreterFrame * _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, @@ -221,14 +248,6 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, static _PyInterpreterFrame * _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs); -static void -_PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame); - -#define UNBOUNDLOCAL_ERROR_MSG \ - "cannot access local variable '%s' where it is not associated with a value" -#define UNBOUNDFREE_ERROR_MSG \ - "cannot access free variable '%s' where it is not associated with a" \ - " value in enclosing scope" #ifdef HAVE_ERRNO_H #include @@ -286,7 +305,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) } -static const binaryfunc binary_ops[] = { +const binaryfunc _PyEval_BinaryOps[] = { [NB_ADD] = PyNumber_Add, [NB_AND] = PyNumber_And, [NB_FLOOR_DIVIDE] = PyNumber_FloorDivide, @@ -321,8 +340,8 @@ static const binaryfunc binary_ops[] = { // Return a tuple of values corresponding to keys, with error checks for // duplicate/missing keys. -static PyObject* -match_keys(PyThreadState *tstate, PyObject *map, PyObject *keys) +PyObject * +_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys) { assert(PyTuple_CheckExact(keys)); Py_ssize_t nkeys = PyTuple_GET_SIZE(keys); @@ -403,7 +422,7 @@ match_keys(PyThreadState *tstate, PyObject *map, PyObject *keys) // Extract a named attribute from the subject, with additional bookkeeping to // raise TypeErrors for repeated lookups. On failure, return NULL (with no // error set). Use _PyErr_Occurred(tstate) to disambiguate. -static PyObject* +static PyObject * match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type, PyObject *name, PyObject *seen) { @@ -425,9 +444,9 @@ match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type, // On success (match), return a tuple of extracted attributes. On failure (no // match), return NULL. Use _PyErr_Occurred(tstate) to disambiguate. -static PyObject* -match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, - Py_ssize_t nargs, PyObject *kwargs) +PyObject* +_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, + Py_ssize_t nargs, PyObject *kwargs) { if (!PyType_Check(type)) { const char *e = "called match pattern must be a class"; @@ -487,7 +506,9 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, } if (match_self) { // Easy. Copy the subject itself, and move on to kwargs. - PyList_Append(attrs, subject); + if (PyList_Append(attrs, subject) < 0) { + goto fail; + } } else { for (Py_ssize_t i = 0; i < nargs; i++) { @@ -503,7 +524,10 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, if (attr == NULL) { goto fail; } - PyList_Append(attrs, attr); + if (PyList_Append(attrs, attr) < 0) { + Py_DECREF(attr); + goto fail; + } Py_DECREF(attr); } } @@ -516,7 +540,10 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, if (attr == NULL) { goto fail; } - PyList_Append(attrs, attr); + if (PyList_Append(attrs, attr) < 0) { + Py_DECREF(attr); + goto fail; + } Py_DECREF(attr); } Py_SETREF(attrs, PyList_AsTuple(attrs)); @@ -533,11 +560,6 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); -static int exception_group_match( - PyObject* exc_value, PyObject *match_type, - PyObject **match, PyObject **rest); - -static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); PyObject * PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) @@ -588,6 +610,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) return _PyEval_EvalFrame(tstate, f->f_frame, throwflag); } +#define TIER_ONE 1 #include "ceval_macros.h" @@ -612,15 +635,6 @@ int _Py_CheckRecursiveCallPy( return 0; } -static inline int _Py_EnterRecursivePy(PyThreadState *tstate) { - return (tstate->py_recursion_remaining-- <= 0) && - _Py_CheckRecursiveCallPy(tstate); -} - - -static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) { - tstate->py_recursion_remaining++; -} static const _Py_CODEUNIT _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = { /* Put a NOP at the start, so that the IP points into @@ -644,6 +658,11 @@ extern const struct _PyCode_DEF(8) _Py_InitCleanup; # pragma warning(disable:4102) #endif + +/* _PyEval_EvalFrameDefault() is a *big* function, + * so consume 3 units of C stack */ +#define PY_EVAL_C_STACK_UNITS 2 + PyObject* _Py_HOT_FUNCTION _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) { @@ -666,17 +685,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int int lltrace = 0; #endif - _PyCFrame cframe; _PyInterpreterFrame entry_frame; - PyObject *kwnames = NULL; // Borrowed reference. Reset by CALL instructions. - /* WARNING: Because the _PyCFrame lives on the C stack, - * but can be accessed from a heap allocated object (tstate) - * strict stack discipline must be maintained. - */ - _PyCFrame *prev_cframe = tstate->cframe; - cframe.previous = prev_cframe; - tstate->cframe = &cframe; + #ifdef Py_DEBUG /* Set these to invalid but identifiable values for debugging. */ @@ -692,10 +703,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int entry_frame.owner = FRAME_OWNED_BY_CSTACK; entry_frame.return_offset = 0; /* Push frame */ - entry_frame.previous = prev_cframe->current_frame; + entry_frame.previous = tstate->current_frame; frame->previous = &entry_frame; - cframe.current_frame = frame; + tstate->current_frame = frame; + tstate->c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1); if (_Py_EnterRecursiveCallTstate(tstate, "")) { tstate->c_recursion_remaining--; tstate->py_recursion_remaining--; @@ -736,17 +748,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_LOCALS_FROM_FRAME(); #ifdef LLTRACE - { - if (frame != &entry_frame && GLOBALS()) { - int r = PyDict_Contains(GLOBALS(), &_Py_ID(__lltrace__)); - if (r < 0) { - goto exit_unwind; - } - lltrace = r; - } - if (lltrace) { - lltrace_resume_frame(frame); - } + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; } #endif @@ -827,7 +831,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int unbound_local_error: { - format_exc_check_arg(tstate, PyExc_UnboundLocalError, + _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) ); @@ -843,7 +847,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int pop_1_error: STACK_SHRINK(1); error: - kwnames = NULL; /* Double-check exception status. */ #ifdef NDEBUG if (!_PyErr_Occurred(tstate)) { @@ -863,7 +866,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } } monitor_raise(tstate, frame, next_instr-1); - exception_unwind: { /* We can't use frame->f_lasti here, as RERAISE may have set it */ @@ -907,8 +909,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *exc = _PyErr_GetRaisedException(tstate); PUSH(exc); JUMPTO(handler); - monitor_handled(tstate, frame, next_instr, exc); + if (monitor_handled(tstate, frame, next_instr, exc) < 0) { + goto exception_unwind; + } /* Resume normal execution */ +#ifdef LLTRACE + if (lltrace) { + lltrace_resume_frame(frame); + } +#endif DISPATCH(); } } @@ -919,14 +928,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(frame != &entry_frame); // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); frame->return_offset = 0; if (frame == &entry_frame) { - /* Restore previous cframe and exit */ - tstate->cframe = cframe.previous; - assert(tstate->cframe->current_frame == frame->previous); - _Py_LeaveRecursiveCallTstate(tstate); + /* Restore previous frame and exit */ + tstate->current_frame = frame->previous; + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; return NULL; } @@ -1278,7 +1286,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, if (co->co_flags & CO_VARARGS) { PyObject *u = NULL; if (argcount == n) { - u = Py_NewRef(&_Py_SINGLETON(tuple_empty)); + u = (PyObject *)&_Py_SINGLETON(tuple_empty); } else { assert(args != NULL); @@ -1346,9 +1354,33 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, goto kw_fail; } - _PyErr_Format(tstate, PyExc_TypeError, - "%U() got an unexpected keyword argument '%S'", - func->func_qualname, keyword); + PyObject* suggestion_keyword = NULL; + if (total_args > co->co_posonlyargcount) { + PyObject* possible_keywords = PyList_New(total_args - co->co_posonlyargcount); + + if (!possible_keywords) { + PyErr_Clear(); + } else { + for (Py_ssize_t k = co->co_posonlyargcount; k < total_args; k++) { + PyList_SET_ITEM(possible_keywords, k - co->co_posonlyargcount, co_varnames[k]); + } + + suggestion_keyword = _Py_CalculateSuggestions(possible_keywords, keyword); + Py_DECREF(possible_keywords); + } + } + + if (suggestion_keyword) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got an unexpected keyword argument '%S'. Did you mean '%S'?", + func->func_qualname, keyword, suggestion_keyword); + Py_DECREF(suggestion_keyword); + } else { + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got an unexpected keyword argument '%S'", + func->func_qualname, keyword); + } + goto kw_fail; } @@ -1485,12 +1517,13 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) tstate->c_recursion_remaining--; assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); + _PyErr_ClearExcState(&gen->gi_exc_state); tstate->c_recursion_remaining++; frame->previous = NULL; } -static void -_PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) +void +_PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) { if (frame->owner == FRAME_OWNED_BY_THREAD) { clear_thread_frame(tstate, frame); @@ -1777,9 +1810,9 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) complicated for inlining). */ -static int -exception_group_match(PyObject* exc_value, PyObject *match_type, - PyObject **match, PyObject **rest) +int +_PyEval_ExceptionGroupMatch(PyObject* exc_value, PyObject *match_type, + PyObject **match, PyObject **rest) { if (Py_IsNone(exc_value)) { *match = Py_NewRef(Py_None); @@ -1840,9 +1873,9 @@ exception_group_match(PyObject* exc_value, PyObject *match_type, with a variable target. */ -static int -unpack_iterable(PyThreadState *tstate, PyObject *v, - int argcnt, int argcntafter, PyObject **sp) +int +_PyEval_UnpackIterable(PyThreadState *tstate, PyObject *v, + int argcnt, int argcntafter, PyObject **sp) { int i = 0, j = 0; Py_ssize_t ll = 0; @@ -1937,7 +1970,7 @@ static int do_monitor_exc(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, int event) { - assert(event < PY_MONITORING_UNGROUPED_EVENTS); + assert(event < _PY_MONITORING_UNGROUPED_EVENTS); PyObject *exc = PyErr_GetRaisedException(); assert(exc != NULL); int err = _Py_call_instrumentation_arg(tstate, event, frame, instr, exc); @@ -1945,43 +1978,56 @@ do_monitor_exc(PyThreadState *tstate, _PyInterpreterFrame *frame, PyErr_SetRaisedException(exc); } else { + assert(PyErr_Occurred()); Py_DECREF(exc); } return err; } -static inline int -no_tools_for_event(PyThreadState *tstate, _PyInterpreterFrame *frame, int event) +static inline bool +no_tools_for_global_event(PyThreadState *tstate, int event) { + return tstate->interp->monitors.tools[event] == 0; +} + +static inline bool +no_tools_for_local_event(PyThreadState *tstate, _PyInterpreterFrame *frame, int event) +{ + assert(event < _PY_MONITORING_LOCAL_EVENTS); _PyCoMonitoringData *data = _PyFrame_GetCode(frame)->_co_monitoring; if (data) { - if (data->active_monitors.tools[event] == 0) { - return 1; - } + return data->active_monitors.tools[event] == 0; } else { - if (tstate->interp->monitors.tools[event] == 0) { - return 1; - } + return no_tools_for_global_event(tstate, event); } - return 0; } static void monitor_raise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr) { - if (no_tools_for_event(tstate, frame, PY_MONITORING_EVENT_RAISE)) { + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_RAISE)) { return; } do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_RAISE); } +static void +monitor_reraise(PyThreadState *tstate, _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr) +{ + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_RERAISE)) { + return; + } + do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_RERAISE); +} + static int monitor_stop_iteration(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr) { - if (no_tools_for_event(tstate, frame, PY_MONITORING_EVENT_STOP_ITERATION)) { + if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_STOP_ITERATION)) { return 0; } return do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_STOP_ITERATION); @@ -1992,22 +2038,22 @@ monitor_unwind(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr) { - if (no_tools_for_event(tstate, frame, PY_MONITORING_EVENT_PY_UNWIND)) { + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_PY_UNWIND)) { return; } - _Py_call_instrumentation_exc0(tstate, PY_MONITORING_EVENT_PY_UNWIND, frame, instr); + do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_UNWIND); } -static void +static int monitor_handled(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *exc) { - if (no_tools_for_event(tstate, frame, PY_MONITORING_EVENT_EXCEPTION_HANDLED)) { - return; + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED)) { + return 0; } - _Py_call_instrumentation_arg(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED, frame, instr, exc); + return _Py_call_instrumentation_arg(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED, frame, instr, exc); } static void @@ -2015,10 +2061,10 @@ monitor_throw(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr) { - if (no_tools_for_event(tstate, frame, PY_MONITORING_EVENT_PY_THROW)) { + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_PY_THROW)) { return; } - _Py_call_instrumentation_exc0(tstate, PY_MONITORING_EVENT_PY_THROW, frame, instr); + do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_THROW); } void @@ -2280,7 +2326,7 @@ int PyEval_MergeCompilerFlags(PyCompilerFlags *cf) { PyThreadState *tstate = _PyThreadState_GET(); - _PyInterpreterFrame *current_frame = tstate->cframe->current_frame; + _PyInterpreterFrame *current_frame = tstate->current_frame; int result = cf->cf_flags != 0; if (current_frame != NULL) { @@ -2389,7 +2435,7 @@ import_name(PyThreadState *tstate, _PyInterpreterFrame *frame, /* Fast path for not overloaded __import__. */ if (_PyImport_IsDefaultImportFunc(tstate->interp, import_func)) { - int ilevel = _PyLong_AsInt(level); + int ilevel = PyLong_AsInt(level); if (ilevel == -1 && _PyErr_Occurred(tstate)) { return NULL; } @@ -2487,8 +2533,8 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) #define CANNOT_EXCEPT_STAR_EG "catching ExceptionGroup with except* "\ "is not allowed. Use except instead." -static int -check_except_type_valid(PyThreadState *tstate, PyObject* right) +int +_PyEval_CheckExceptTypeValid(PyThreadState *tstate, PyObject* right) { if (PyTuple_Check(right)) { Py_ssize_t i, length; @@ -2512,10 +2558,10 @@ check_except_type_valid(PyThreadState *tstate, PyObject* right) return 0; } -static int -check_except_star_type_valid(PyThreadState *tstate, PyObject* right) +int +_PyEval_CheckExceptStarTypeValid(PyThreadState *tstate, PyObject* right) { - if (check_except_type_valid(tstate, right) < 0) { + if (_PyEval_CheckExceptTypeValid(tstate, right) < 0) { return -1; } @@ -2569,8 +2615,8 @@ check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args) return 0; } -static void -format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) +void +_PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs) { /* _PyDict_MergeEx raises attribute * error (percolated from an attempt @@ -2611,9 +2657,9 @@ format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) } } -static void -format_exc_check_arg(PyThreadState *tstate, PyObject *exc, - const char *format_str, PyObject *obj) +void +_PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, + const char *format_str, PyObject *obj) { const char *obj_str; @@ -2640,8 +2686,8 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc, } } -static void -format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) +void +_PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg) { PyObject *name; /* Don't stomp existing exception */ @@ -2649,16 +2695,16 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) return; name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg); if (oparg < PyCode_GetFirstFree(co)) { - format_exc_check_arg(tstate, PyExc_UnboundLocalError, - UNBOUNDLOCAL_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, name); } else { - format_exc_check_arg(tstate, PyExc_NameError, - UNBOUNDFREE_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + UNBOUNDFREE_ERROR_MSG, name); } } -static void -format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int oparg) +void +_PyEval_FormatAwaitableError(PyThreadState *tstate, PyTypeObject *type, int oparg) { if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { if (oparg == 1) { @@ -2703,110 +2749,3 @@ void Py_LeaveRecursiveCall(void) { _Py_LeaveRecursiveCall(); } - -///////////////////// Experimental UOp Interpreter ///////////////////// - -#undef ASSERT_KWNAMES_IS_NULL -#define ASSERT_KWNAMES_IS_NULL() (void)0 - -#undef DEOPT_IF -#define DEOPT_IF(COND, INSTNAME) \ - if ((COND)) { \ - goto deoptimize; \ - } - -_PyInterpreterFrame * -_PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject **stack_pointer) -{ -#ifdef Py_DEBUG - char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG"); - int lltrace = 0; - if (uop_debug != NULL && *uop_debug >= '0') { - lltrace = *uop_debug - '0'; // TODO: Parse an int and all that - } -#define DPRINTF(level, ...) \ - if (lltrace >= (level)) { fprintf(stderr, __VA_ARGS__); } -#else -#define DPRINTF(level, ...) -#endif - - DPRINTF(3, - "Entering _PyUopExecute for %s (%s:%d) at byte offset %ld\n", - PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_qualname), - PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_filename), - _PyFrame_GetCode(frame)->co_firstlineno, - 2 * (long)(frame->prev_instr + 1 - - (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive)); - - PyThreadState *tstate = _PyThreadState_GET(); - _PyUOpExecutorObject *self = (_PyUOpExecutorObject *)executor; - - CHECK_EVAL_BREAKER(); - - OBJECT_STAT_INC(optimization_traces_executed); - _Py_CODEUNIT *ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; - int pc = 0; - int opcode; - int oparg; - uint64_t operand; - - for (;;) { - opcode = self->trace[pc].opcode; - oparg = self->trace[pc].oparg; - operand = self->trace[pc].operand; - DPRINTF(3, - "%4d: uop %s, oparg %d, operand %" PRIu64 ", stack_level %d\n", - pc, - opcode < 256 ? _PyOpcode_OpName[opcode] : _PyOpcode_uop_name[opcode], - oparg, - operand, - (int)(stack_pointer - _PyFrame_Stackbase(frame))); - pc++; - OBJECT_STAT_INC(optimization_uops_executed); - switch (opcode) { - -#undef ENABLE_SPECIALIZATION -#define ENABLE_SPECIALIZATION 0 -#include "executor_cases.c.h" - - default: - { - fprintf(stderr, "Unknown uop %d, operand %" PRIu64 "\n", opcode, operand); - Py_FatalError("Unknown uop"); - } - - } - } - -unbound_local_error: - format_exc_check_arg(tstate, PyExc_UnboundLocalError, - UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) - ); - goto error; - -pop_4_error: - STACK_SHRINK(1); -pop_3_error: - STACK_SHRINK(1); -pop_2_error: - STACK_SHRINK(1); -pop_1_error: - STACK_SHRINK(1); -error: - // On ERROR_IF we return NULL as the frame. - // The caller recovers the frame from cframe.current_frame. - DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand); - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_DECREF(self); - return NULL; - -deoptimize: - // On DEOPT_IF we just repeat the last instruction. - // This presumes nothing was popped from the stack (nor pushed). - DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand); - frame->prev_instr--; // Back up to just before destination - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_DECREF(self); - return frame; -} diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index 7c9ad07cc7207b..bbb1e784dfa04e 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -2,11 +2,12 @@ #include "Python.h" #include "pycore_atomic.h" // _Py_atomic_int #include "pycore_ceval.h" // _PyEval_SignalReceived() -#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() -#include "pycore_pylifecycle.h" // _PyErr_Print() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // _Py_RunGC() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() +#include "pycore_pylifecycle.h" // _PyErr_Print() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() +#include "pycore_pystats.h" // _Py_PrintSpecializationStats() /* Notes about the implementation: @@ -56,123 +57,62 @@ #define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) #endif -/* This can set eval_breaker to 0 even though gil_drop_request became - 1. We believe this is all right because the eval loop will release - the GIL eventually anyway. */ +/* bpo-40010: eval_breaker should be recomputed if there + is a pending signal: signal received by another thread which cannot + handle signals. + Similarly, we set CALLS_TO_DO and ASYNC_EXCEPTION to match the thread. +*/ static inline void -COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, - struct _ceval_runtime_state *ceval, - struct _ceval_state *ceval2) +update_eval_breaker_from_thread(PyInterpreterState *interp, PyThreadState *tstate) { - _Py_atomic_store_relaxed(&ceval2->eval_breaker, - _Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request) - | (_Py_atomic_load_relaxed_int32(&ceval->signals_pending) - && _Py_ThreadCanHandleSignals(interp)) - | (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do)) - | (_Py_IsMainThread() && _Py_IsMainInterpreter(interp) - &&_Py_atomic_load_relaxed_int32(&ceval->pending_mainthread.calls_to_do)) - | ceval2->pending.async_exc - | _Py_atomic_load_relaxed_int32(&ceval2->gc_scheduled)); -} + if (tstate == NULL) { + return; + } + if (_Py_IsMainThread()) { + int32_t calls_to_do = _Py_atomic_load_int32_relaxed( + &_PyRuntime.ceval.pending_mainthread.calls_to_do); + if (calls_to_do) { + _Py_set_eval_breaker_bit(interp, _PY_CALLS_TO_DO_BIT, 1); + } + if (_Py_ThreadCanHandleSignals(interp)) { + if (_Py_atomic_load_int(&_PyRuntime.signals.is_tripped)) { + _Py_set_eval_breaker_bit(interp, _PY_SIGNALS_PENDING_BIT, 1); + } + } + } + if (tstate->async_exc != NULL) { + _Py_set_eval_breaker_bit(interp, _PY_ASYNC_EXCEPTION_BIT, 1); + } +} static inline void SET_GIL_DROP_REQUEST(PyInterpreterState *interp) { - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); + _Py_set_eval_breaker_bit(interp, _PY_GIL_DROP_REQUEST_BIT, 1); } static inline void RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) { - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + _Py_set_eval_breaker_bit(interp, _PY_GIL_DROP_REQUEST_BIT, 0); } static inline void -SIGNAL_PENDING_CALLS(struct _pending_calls *pending, PyInterpreterState *interp) +SIGNAL_PENDING_CALLS(PyInterpreterState *interp) { - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&pending->calls_to_do, 1); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + _Py_set_eval_breaker_bit(interp, _PY_CALLS_TO_DO_BIT, 1); } static inline void UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) { - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) { - _Py_atomic_store_relaxed(&ceval->pending_mainthread.calls_to_do, 0); - } - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + _Py_set_eval_breaker_bit(interp, _PY_CALLS_TO_DO_BIT, 0); } - -static inline void -SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 1); - if (force) { - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); - } - else { - /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } -} - - -static inline void -UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 1; - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 0; - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - -#ifndef NDEBUG -/* Ensure that tstate is valid */ -static int -is_tstate_valid(PyThreadState *tstate) -{ - assert(!_PyMem_IsPtrFreed(tstate)); - assert(!_PyMem_IsPtrFreed(tstate->interp)); - return 1; -} -#endif - /* * Implementation of the Global Interpreter Lock (GIL). */ @@ -249,7 +189,7 @@ static void create_gil(struct _gil_runtime_state *gil) #ifdef FORCE_SWITCHING COND_INIT(gil->switch_cond); #endif - _Py_atomic_store_relaxed(&gil->last_holder, 0); + _Py_atomic_store_ptr_relaxed(&gil->last_holder, 0); _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); } @@ -280,8 +220,9 @@ static void recreate_gil(struct _gil_runtime_state *gil) #endif static void -drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) +drop_gil(PyInterpreterState *interp, PyThreadState *tstate) { + struct _ceval_state *ceval = &interp->ceval; /* If tstate is NULL, the caller is indicating that we're releasing the GIL for the last time in this thread. This is particularly relevant when the current thread state is finalizing or its @@ -292,7 +233,7 @@ drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) // XXX assert(tstate == NULL || !tstate->_status.cleared); struct _gil_runtime_state *gil = ceval->gil; - if (!_Py_atomic_load_relaxed(&gil->locked)) { + if (!_Py_atomic_load_ptr_relaxed(&gil->locked)) { Py_FatalError("drop_gil: GIL is not locked"); } @@ -301,7 +242,7 @@ drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) /* Sub-interpreter support: threads might have been switched under our feet using PyThreadState_Swap(). Fix the GIL last holder variable so that our heuristics work. */ - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + _Py_atomic_store_ptr_relaxed(&gil->last_holder, tstate); } MUTEX_LOCK(gil->mutex); @@ -319,12 +260,12 @@ drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) the GIL, and that's the only time we might delete the interpreter, so checking tstate first prevents the crash. See https://github.com/python/cpython/issues/104341. */ - if (tstate != NULL && _Py_atomic_load_relaxed(&ceval->gil_drop_request)) { + if (tstate != NULL && _Py_eval_breaker_bit_is_set(interp, _PY_GIL_DROP_REQUEST_BIT)) { MUTEX_LOCK(gil->switch_mutex); /* Not switched yet => wait */ - if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) + if (((PyThreadState*)_Py_atomic_load_ptr_relaxed(&gil->last_holder)) == tstate) { - assert(is_tstate_valid(tstate)); + assert(_PyThreadState_CheckConsistency(tstate)); RESET_GIL_DROP_REQUEST(tstate->interp); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take @@ -338,28 +279,6 @@ drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) } -/* Check if a Python thread must exit immediately, rather than taking the GIL - if Py_Finalize() has been called. - - When this function is called by a daemon thread after Py_Finalize() has been - called, the GIL does no longer exist. - - tstate must be non-NULL. */ -static inline int -tstate_must_exit(PyThreadState *tstate) -{ - /* bpo-39877: Access _PyRuntime directly rather than using - tstate->interp->runtime to support calls from Python daemon threads. - After Py_Finalize() has been called, tstate can be a dangling pointer: - point to PyThreadState freed memory. */ - PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); - if (finalizing == NULL) { - finalizing = _PyInterpreterState_GetFinalizing(tstate->interp); - } - return (finalizing != NULL && finalizing != tstate); -} - - /* Take the GIL. The function saves errno at entry and restores its value at exit. @@ -375,7 +294,7 @@ take_gil(PyThreadState *tstate) // XXX It may be more correct to check tstate->_status.finalizing. // XXX assert(!tstate->_status.cleared); - if (tstate_must_exit(tstate)) { + if (_PyThreadState_MustExit(tstate)) { /* bpo-39877: If Py_Finalize() has been called and tstate is not the thread which called Py_Finalize(), exit immediately the thread. @@ -385,10 +304,9 @@ take_gil(PyThreadState *tstate) PyThread_exit_thread(); } - assert(is_tstate_valid(tstate)); + assert(_PyThreadState_CheckConsistency(tstate)); PyInterpreterState *interp = tstate->interp; - struct _ceval_state *ceval = &interp->ceval; - struct _gil_runtime_state *gil = ceval->gil; + struct _gil_runtime_state *gil = interp->ceval.gil; /* Check that _PyEval_InitThreads() was called to create the lock */ assert(gil_created(gil)); @@ -413,7 +331,7 @@ take_gil(PyThreadState *tstate) _Py_atomic_load_relaxed(&gil->locked) && gil->switch_number == saved_switchnum) { - if (tstate_must_exit(tstate)) { + if (_PyThreadState_MustExit(tstate)) { MUTEX_UNLOCK(gil->mutex); // gh-96387: If the loop requested a drop request in a previous // iteration, reset the request. Otherwise, drop_gil() can @@ -426,7 +344,7 @@ take_gil(PyThreadState *tstate) } PyThread_exit_thread(); } - assert(is_tstate_valid(tstate)); + assert(_PyThreadState_CheckConsistency(tstate)); SET_GIL_DROP_REQUEST(interp); drop_requested = 1; @@ -443,8 +361,8 @@ take_gil(PyThreadState *tstate) _Py_atomic_store_relaxed(&gil->locked, 1); _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); - if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + if (tstate != (PyThreadState*)_Py_atomic_load_ptr_relaxed(&gil->last_holder)) { + _Py_atomic_store_ptr_relaxed(&gil->last_holder, tstate); ++gil->switch_number; } @@ -453,7 +371,7 @@ take_gil(PyThreadState *tstate) MUTEX_UNLOCK(gil->switch_mutex); #endif - if (tstate_must_exit(tstate)) { + if (_PyThreadState_MustExit(tstate)) { /* bpo-36475: If Py_Finalize() has been called and tstate is not the thread which called Py_Finalize(), exit immediately the thread. @@ -462,27 +380,13 @@ take_gil(PyThreadState *tstate) in take_gil() while the main thread called wait_for_thread_shutdown() from Py_Finalize(). */ MUTEX_UNLOCK(gil->mutex); - drop_gil(ceval, tstate); + drop_gil(interp, tstate); PyThread_exit_thread(); } - assert(is_tstate_valid(tstate)); - - if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { - RESET_GIL_DROP_REQUEST(interp); - } - else { - /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there - is a pending signal: signal received by another thread which cannot - handle signals. + assert(_PyThreadState_CheckConsistency(tstate)); - Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ - COMPUTE_EVAL_BREAKER(interp, &_PyRuntime.ceval, ceval); - } - - /* Don't access tstate if the thread must exit */ - if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(tstate->interp); - } + RESET_GIL_DROP_REQUEST(interp); + update_eval_breaker_from_thread(interp, tstate); MUTEX_UNLOCK(gil->mutex); @@ -530,7 +434,7 @@ PyEval_ThreadsInitialized(void) static inline int current_thread_holds_gil(struct _gil_runtime_state *gil, PyThreadState *tstate) { - if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) != tstate) { + if (((PyThreadState*)_Py_atomic_load_ptr_relaxed(&gil->last_holder)) != tstate) { return 0; } return _Py_atomic_load_relaxed(&gil->locked); @@ -558,24 +462,22 @@ PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil) { assert(tstate->interp->ceval.gil == NULL); - int locked; if (!own_gil) { /* The interpreter will share the main interpreter's instead. */ PyInterpreterState *main_interp = _PyInterpreterState_Main(); assert(tstate->interp != main_interp); struct _gil_runtime_state *gil = main_interp->ceval.gil; init_shared_gil(tstate->interp, gil); - locked = current_thread_holds_gil(gil, tstate); + assert(!current_thread_holds_gil(gil, tstate)); } else { PyThread_init_thread(); init_own_gil(tstate->interp, &tstate->interp->_gil); - locked = 0; - } - if (!locked) { - take_gil(tstate); } + // Lock the GIL and mark the current thread as attached. + _PyThreadState_Attach(tstate); + return _PyStatus_OK(); } @@ -642,8 +544,7 @@ PyEval_ReleaseLock(void) /* This function must succeed when the current thread state is NULL. We therefore avoid PyThreadState_Get() which dumps a fatal error in debug mode. */ - struct _ceval_state *ceval = &tstate->interp->ceval; - drop_gil(ceval, tstate); + drop_gil(tstate->interp, tstate); } void @@ -659,33 +560,21 @@ _PyEval_ReleaseLock(PyInterpreterState *interp, PyThreadState *tstate) /* If tstate is NULL then we do not expect the current thread to acquire the GIL ever again. */ assert(tstate == NULL || tstate->interp == interp); - struct _ceval_state *ceval = &interp->ceval; - drop_gil(ceval, tstate); + drop_gil(interp, tstate); } void PyEval_AcquireThread(PyThreadState *tstate) { _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - if (_PyThreadState_SwapNoGIL(tstate) != NULL) { - Py_FatalError("non-NULL old thread state"); - } + _PyThreadState_Attach(tstate); } void PyEval_ReleaseThread(PyThreadState *tstate) { - assert(is_tstate_valid(tstate)); - - PyThreadState *new_tstate = _PyThreadState_SwapNoGIL(NULL); - if (new_tstate != tstate) { - Py_FatalError("wrong thread state"); - } - struct _ceval_state *ceval = &tstate->interp->ceval; - drop_gil(ceval, tstate); + assert(_PyThreadState_CheckConsistency(tstate)); + _PyThreadState_Detach(tstate); } #ifdef HAVE_FORK @@ -722,18 +611,14 @@ _PyEval_ReInitThreads(PyThreadState *tstate) void _PyEval_SignalAsyncExc(PyInterpreterState *interp) { - SIGNAL_ASYNC_EXC(interp); + _Py_set_eval_breaker_bit(interp, _PY_ASYNC_EXCEPTION_BIT, 1); } PyThreadState * PyEval_SaveThread(void) { - PyThreadState *tstate = _PyThreadState_SwapNoGIL(NULL); - _Py_EnsureTstateNotNULL(tstate); - - struct _ceval_state *ceval = &tstate->interp->ceval; - assert(gil_created(ceval->gil)); - drop_gil(ceval, tstate); + PyThreadState *tstate = _PyThreadState_GET(); + _PyThreadState_Detach(tstate); return tstate; } @@ -741,10 +626,7 @@ void PyEval_RestoreThread(PyThreadState *tstate) { _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - _PyThreadState_SwapNoGIL(tstate); + _PyThreadState_Attach(tstate); } @@ -773,28 +655,15 @@ PyEval_RestoreThread(PyThreadState *tstate) void _PyEval_SignalReceived(PyInterpreterState *interp) { -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal - // handler which can run in a thread different than the Python thread, in - // which case _Py_ThreadCanHandleSignals() is wrong. Ignore - // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. - // - // The next eval_frame_handle_pending() call will call - // _Py_ThreadCanHandleSignals() to recompute eval_breaker. - int force = 1; -#else - int force = 0; -#endif - /* bpo-30703: Function called when the C signal handler of Python gets a - signal. We cannot queue a callback using _PyEval_AddPendingCall() since - that function is not async-signal-safe. */ - SIGNAL_PENDING_SIGNALS(interp, force); + if (_Py_ThreadCanHandleSignals(interp)) { + _Py_set_eval_breaker_bit(interp, _PY_SIGNALS_PENDING_BIT, 1); + } } /* Push one item onto the queue while holding the lock. */ static int _push_pending_call(struct _pending_calls *pending, - int (*func)(void *), void *arg) + _Py_pending_call_func func, void *arg, int flags) { int i = pending->last; int j = (i + 1) % NPENDINGCALLS; @@ -803,13 +672,16 @@ _push_pending_call(struct _pending_calls *pending, } pending->calls[i].func = func; pending->calls[i].arg = arg; + pending->calls[i].flags = flags; pending->last = j; + assert(pending->calls_to_do < NPENDINGCALLS); + pending->calls_to_do++; return 0; } static int _next_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) + int (**func)(void *), void **arg, int *flags) { int i = pending->first; if (i == pending->last) { @@ -819,18 +691,21 @@ _next_pending_call(struct _pending_calls *pending, } *func = pending->calls[i].func; *arg = pending->calls[i].arg; + *flags = pending->calls[i].flags; return i; } /* Pop one item off the queue while holding the lock. */ static void _pop_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) + int (**func)(void *), void **arg, int *flags) { - int i = _next_pending_call(pending, func, arg); + int i = _next_pending_call(pending, func, arg, flags); if (i >= 0) { pending->calls[i] = (struct _pending_call){0}; pending->first = (i + 1) % NPENDINGCALLS; + assert(pending->calls_to_do > 0); + pending->calls_to_do--; } } @@ -841,12 +716,12 @@ _pop_pending_call(struct _pending_calls *pending, int _PyEval_AddPendingCall(PyInterpreterState *interp, - int (*func)(void *), void *arg, - int mainthreadonly) + _Py_pending_call_func func, void *arg, int flags) { - assert(!mainthreadonly || _Py_IsMainInterpreter(interp)); + assert(!(flags & _Py_PENDING_MAINTHREADONLY) + || _Py_IsMainInterpreter(interp)); struct _pending_calls *pending = &interp->ceval.pending; - if (mainthreadonly) { + if (flags & _Py_PENDING_MAINTHREADONLY) { /* The main thread only exists in the main interpreter. */ assert(_Py_IsMainInterpreter(interp)); pending = &_PyRuntime.ceval.pending_mainthread; @@ -856,72 +731,62 @@ _PyEval_AddPendingCall(PyInterpreterState *interp, assert(pending->lock != NULL); PyThread_acquire_lock(pending->lock, WAIT_LOCK); - int result = _push_pending_call(pending, func, arg); + int result = _push_pending_call(pending, func, arg, flags); PyThread_release_lock(pending->lock); /* signal main loop */ - SIGNAL_PENDING_CALLS(pending, interp); + SIGNAL_PENDING_CALLS(interp); return result; } int -Py_AddPendingCall(int (*func)(void *), void *arg) +Py_AddPendingCall(_Py_pending_call_func func, void *arg) { /* Legacy users of this API will continue to target the main thread (of the main interpreter). */ PyInterpreterState *interp = _PyInterpreterState_Main(); - return _PyEval_AddPendingCall(interp, func, arg, 1); + return _PyEval_AddPendingCall(interp, func, arg, _Py_PENDING_MAINTHREADONLY); } static int handle_signals(PyThreadState *tstate) { - assert(is_tstate_valid(tstate)); + assert(_PyThreadState_CheckConsistency(tstate)); + _Py_set_eval_breaker_bit(tstate->interp, _PY_SIGNALS_PENDING_BIT, 0); if (!_Py_ThreadCanHandleSignals(tstate->interp)) { return 0; } - - UNSIGNAL_PENDING_SIGNALS(tstate->interp); if (_PyErr_CheckSignalsTstate(tstate) < 0) { /* On failure, re-schedule a call to handle_signals(). */ - SIGNAL_PENDING_SIGNALS(tstate->interp, 0); + _Py_set_eval_breaker_bit(tstate->interp, _PY_SIGNALS_PENDING_BIT, 1); return -1; } return 0; } -static inline int -maybe_has_pending_calls(PyInterpreterState *interp) -{ - struct _pending_calls *pending = &interp->ceval.pending; - if (_Py_atomic_load_relaxed_int32(&pending->calls_to_do)) { - return 1; - } - if (!_Py_IsMainThread() || !_Py_IsMainInterpreter(interp)) { - return 0; - } - pending = &_PyRuntime.ceval.pending_mainthread; - return _Py_atomic_load_relaxed_int32(&pending->calls_to_do); -} - static int _make_pending_calls(struct _pending_calls *pending) { /* perform a bounded number of calls, in case of recursion */ for (int i=0; ilock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); + _pop_pending_call(pending, &func, &arg, &flags); PyThread_release_lock(pending->lock); /* having released the lock, perform the callback */ if (func == NULL) { break; } - if (func(arg) != 0) { + int res = func(arg); + if ((flags & _Py_PENDING_RAWFREE) && arg != NULL) { + PyMem_RawFree(arg); + } + if (res != 0) { return -1; } } @@ -961,7 +826,7 @@ make_pending_calls(PyInterpreterState *interp) if (_make_pending_calls(pending) != 0) { pending->busy = 0; /* There might not be more calls to make, but we play it safe. */ - SIGNAL_PENDING_CALLS(pending, interp); + SIGNAL_PENDING_CALLS(interp); return -1; } @@ -969,7 +834,7 @@ make_pending_calls(PyInterpreterState *interp) if (_make_pending_calls(pending_main) != 0) { pending->busy = 0; /* There might not be more calls to make, but we play it safe. */ - SIGNAL_PENDING_CALLS(pending_main, interp); + SIGNAL_PENDING_CALLS(interp); return -1; } } @@ -982,7 +847,7 @@ void _Py_FinishPendingCalls(PyThreadState *tstate) { assert(PyGILState_Check()); - assert(is_tstate_valid(tstate)); + assert(_PyThreadState_CheckConsistency(tstate)); if (make_pending_calls(tstate->interp) < 0) { PyObject *exc = _PyErr_GetRaisedException(tstate); @@ -1023,7 +888,7 @@ Py_MakePendingCalls(void) assert(PyGILState_Check()); PyThreadState *tstate = _PyThreadState_GET(); - assert(is_tstate_valid(tstate)); + assert(_PyThreadState_CheckConsistency(tstate)); /* Only execute pending calls on the main thread. */ if (!_Py_IsMainThread() || !_Py_IsMainInterpreter(tstate->interp)) { @@ -1114,70 +979,49 @@ _PyEval_FiniState(struct _ceval_state *ceval) int _Py_HandlePending(PyThreadState *tstate) { - _PyRuntimeState * const runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *interp_ceval_state = &tstate->interp->ceval; + PyInterpreterState *interp = tstate->interp; /* Pending signals */ - if (_Py_atomic_load_relaxed_int32(&ceval->signals_pending)) { + if (_Py_eval_breaker_bit_is_set(interp, _PY_SIGNALS_PENDING_BIT)) { if (handle_signals(tstate) != 0) { return -1; } } /* Pending calls */ - if (maybe_has_pending_calls(tstate->interp)) { - if (make_pending_calls(tstate->interp) != 0) { + if (_Py_eval_breaker_bit_is_set(interp, _PY_CALLS_TO_DO_BIT)) { + if (make_pending_calls(interp) != 0) { return -1; } } /* GC scheduled to run */ - if (_Py_atomic_load_relaxed_int32(&interp_ceval_state->gc_scheduled)) { - _Py_atomic_store_relaxed(&interp_ceval_state->gc_scheduled, 0); - COMPUTE_EVAL_BREAKER(tstate->interp, ceval, interp_ceval_state); + if (_Py_eval_breaker_bit_is_set(interp, _PY_GC_SCHEDULED_BIT)) { + _Py_set_eval_breaker_bit(interp, _PY_GC_SCHEDULED_BIT, 0); _Py_RunGC(tstate); } /* GIL drop request */ - if (_Py_atomic_load_relaxed_int32(&interp_ceval_state->gil_drop_request)) { + if (_Py_eval_breaker_bit_is_set(interp, _PY_GIL_DROP_REQUEST_BIT)) { /* Give another thread a chance */ - if (_PyThreadState_SwapNoGIL(NULL) != tstate) { - Py_FatalError("tstate mix-up"); - } - drop_gil(interp_ceval_state, tstate); + _PyThreadState_Detach(tstate); /* Other threads may run now */ - take_gil(tstate); - - if (_PyThreadState_SwapNoGIL(tstate) != NULL) { - Py_FatalError("orphan tstate"); - } + _PyThreadState_Attach(tstate); } /* Check for asynchronous exception. */ - if (tstate->async_exc != NULL) { - PyObject *exc = tstate->async_exc; - tstate->async_exc = NULL; - UNSIGNAL_ASYNC_EXC(tstate->interp); - _PyErr_SetNone(tstate, exc); - Py_DECREF(exc); - return -1; + if (_Py_eval_breaker_bit_is_set(interp, _PY_ASYNC_EXCEPTION_BIT)) { + _Py_set_eval_breaker_bit(interp, _PY_ASYNC_EXCEPTION_BIT, 0); + if (tstate->async_exc != NULL) { + PyObject *exc = tstate->async_exc; + tstate->async_exc = NULL; + _PyErr_SetNone(tstate, exc); + Py_DECREF(exc); + return -1; + } } - - - // It is possible that some of the conditions that trigger the eval breaker - // are called in a different thread than the Python thread. An example of - // this is bpo-42296: On Windows, _PyEval_SignalReceived() can be called in - // a different thread than the Python thread, in which case - // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the - // current Python thread with the correct _Py_ThreadCanHandleSignals() - // value. It prevents to interrupt the eval loop at every instruction if - // the current Python thread cannot handle signals (if - // _Py_ThreadCanHandleSignals() is false). - COMPUTE_EVAL_BREAKER(tstate->interp, ceval, interp_ceval_state); - return 0; } diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index c2c323317d10f9..bd28126b0b7dfb 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -1,4 +1,4 @@ -// Macros and other things needed by ceval.c and bytecodes.c +// Macros and other things needed by ceval.c, executor.c, and bytecodes.c /* Computed GOTOs, or the-optimization-commonly-but-improperly-known-as-"threaded code" @@ -64,7 +64,7 @@ do { \ frame->prev_instr = next_instr++; \ OPCODE_EXE_INC(op); \ - if (_py_stats) _py_stats->opcode_stats[lastopcode].pair_count[op]++; \ + if (_Py_stats) _Py_stats->opcode_stats[lastopcode].pair_count[op]++; \ lastopcode = op; \ } while (0) #else @@ -109,14 +109,14 @@ _PyFrame_SetStackPointer(frame, stack_pointer); \ frame->prev_instr = next_instr - 1; \ (NEW_FRAME)->previous = frame; \ - frame = cframe.current_frame = (NEW_FRAME); \ + frame = tstate->current_frame = (NEW_FRAME); \ CALL_STAT_INC(inlined_py_calls); \ goto start_frame; \ } while (0) #define CHECK_EVAL_BREAKER() \ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \ - if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker)) { \ + if (_Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) & _PY_EVAL_EVENTS_MASK) { \ if (_Py_HandlePending(tstate) != 0) { \ goto error; \ } \ @@ -304,11 +304,13 @@ GETITEM(PyObject *v, Py_ssize_t i) { (COUNTER) += (1 << ADAPTIVE_BACKOFF_BITS); \ } while (0); +#define UNBOUNDLOCAL_ERROR_MSG \ + "cannot access local variable '%s' where it is not associated with a value" +#define UNBOUNDFREE_ERROR_MSG \ + "cannot access free variable '%s' where it is not associated with a value" \ + " in enclosing scope" #define NAME_ERROR_MSG "name '%.200s' is not defined" -#define KWNAMES_LEN() \ - (kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(kwnames))) - #define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \ do { \ if (Py_REFCNT(left) == 1) { \ @@ -351,4 +353,59 @@ static const convertion_func_ptr CONVERSION_FUNCTIONS[4] = { [FVC_ASCII] = PyObject_ASCII }; -#define ASSERT_KWNAMES_IS_NULL() assert(kwnames == NULL) +// GH-89279: Force inlining by using a macro. +#if defined(_MSC_VER) && SIZEOF_INT == 4 +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value))) +#else +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) +#endif + +static inline int _Py_EnterRecursivePy(PyThreadState *tstate) { + return (tstate->py_recursion_remaining-- <= 0) && + _Py_CheckRecursiveCallPy(tstate); +} + +static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) { + tstate->py_recursion_remaining++; +} + +/* Marker to specify tier 1 only instructions */ +#define TIER_ONE_ONLY + +/* Marker to specify tier 2 only instructions */ +#define TIER_TWO_ONLY + +/* Implementation of "macros" that modify the instruction pointer, + * stack pointer, or frame pointer. + * These need to treated differently by tier 1 and 2. */ + +#if TIER_ONE + +#define LOAD_IP() \ +do { next_instr = frame->prev_instr+1; } while (0) + +#define STORE_SP() \ +_PyFrame_SetStackPointer(frame, stack_pointer) + +#define LOAD_SP() \ +stack_pointer = _PyFrame_GetStackPointer(frame); + +#endif + + +#if TIER_TWO + +#define LOAD_IP() \ +do { ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; } while (0) + +#define STORE_SP() \ +_PyFrame_SetStackPointer(frame, stack_pointer) + +#define LOAD_SP() \ +stack_pointer = _PyFrame_GetStackPointer(frame); + +#endif + + + + diff --git a/Python/clinic/Python-tokenize.c.h b/Python/clinic/Python-tokenize.c.h index 28f5075826e36f..a8453e25807b0d 100644 --- a/Python/clinic/Python-tokenize.c.h +++ b/Python/clinic/Python-tokenize.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - static PyObject * tokenizeriter_new_impl(PyTypeObject *type, PyObject *readline, int extra_tokens, const char *encoding); @@ -80,4 +79,4 @@ tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=48be65a2808bdfa6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=406b5a433a59069c input=a9049054013a1b77]*/ diff --git a/Python/clinic/_warnings.c.h b/Python/clinic/_warnings.c.h index c71663919852ff..cf3c73b1cf0e6e 100644 --- a/Python/clinic/_warnings.c.h +++ b/Python/clinic/_warnings.c.h @@ -3,10 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - +#include "pycore_abstract.h" // _PyNumber_Index() PyDoc_STRVAR(warnings_warn__doc__, "warn($module, /, message, category=None, stacklevel=1, source=None, *,\n" @@ -194,7 +194,7 @@ warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } filename = args[2]; - lineno = _PyLong_AsInt(args[3]); + lineno = PyLong_AsInt(args[3]); if (lineno == -1 && PyErr_Occurred()) { goto exit; } @@ -243,4 +243,4 @@ warnings_filters_mutated(PyObject *module, PyObject *Py_UNUSED(ignored)) { return warnings_filters_mutated_impl(module); } -/*[clinic end generated code: output=f8d67e0f75771c36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c396a721ef75739 input=a9049054013a1b77]*/ diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index b0d05dde956efd..b4dcc6bf1d2978 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(builtin___import____doc__, "__import__($module, /, name, globals=None, locals=None, fromlist=(),\n" " level=0)\n" @@ -99,7 +98,7 @@ builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py goto skip_optional_pos; } } - level = _PyLong_AsInt(args[4]); + level = PyLong_AsInt(args[4]); if (level == -1 && PyErr_Occurred()) { goto exit; } @@ -242,7 +241,7 @@ builtin_chr(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int i; - i = _PyLong_AsInt(arg); + i = PyLong_AsInt(arg); if (i == -1 && PyErr_Occurred()) { goto exit; } @@ -342,7 +341,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } if (args[3]) { - flags = _PyLong_AsInt(args[3]); + flags = PyLong_AsInt(args[3]); if (flags == -1 && PyErr_Occurred()) { goto exit; } @@ -360,7 +359,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[5]) { - optimize = _PyLong_AsInt(args[5]); + optimize = PyLong_AsInt(args[5]); if (optimize == -1 && PyErr_Occurred()) { goto exit; } @@ -372,7 +371,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_kwonly; } - feature_version = _PyLong_AsInt(args[6]); + feature_version = PyLong_AsInt(args[6]); if (feature_version == -1 && PyErr_Occurred()) { goto exit; } @@ -383,49 +382,6 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -PyDoc_STRVAR(builtin_dir__doc__, -"dir($module, arg=, /)\n" -"--\n" -"\n" -"Show attributes of an object.\n" -"\n" -"If called without an argument, return the names in the current scope.\n" -"Else, return an alphabetized list of names comprising (some of) the attributes\n" -"of the given object, and of attributes reachable from it.\n" -"If the object supplies a method named __dir__, it will be used; otherwise\n" -"the default dir() logic is used and returns:\n" -" for a module object: the module\'s attributes.\n" -" for a class object: its attributes, and recursively the attributes\n" -" of its bases.\n" -" for any other object: its attributes, its class\'s attributes, and\n" -" recursively the attributes of its class\'s base classes."); - -#define BUILTIN_DIR_METHODDEF \ - {"dir", _PyCFunction_CAST(builtin_dir), METH_FASTCALL, builtin_dir__doc__}, - -static PyObject * -builtin_dir_impl(PyObject *module, PyObject *arg); - -static PyObject * -builtin_dir(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *arg = NULL; - - if (!_PyArg_CheckPositional("dir", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - arg = args[0]; -skip_optional: - return_value = builtin_dir_impl(module, arg); - -exit: - return return_value; -} - PyDoc_STRVAR(builtin_divmod__doc__, "divmod($module, x, y, /)\n" "--\n" @@ -586,47 +542,6 @@ builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject return return_value; } -PyDoc_STRVAR(builtin_getattr__doc__, -"getattr($module, object, name, default=, /)\n" -"--\n" -"\n" -"Get a named attribute from an object.\n" -"\n" -"getattr(x, \'y\') is equivalent to x.y\n" -"When a default argument is given, it is returned when the attribute doesn\'t\n" -"exist; without it, an exception is raised in that case."); - -#define BUILTIN_GETATTR_METHODDEF \ - {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, builtin_getattr__doc__}, - -static PyObject * -builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name, - PyObject *default_value); - -static PyObject * -builtin_getattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *object; - PyObject *name; - PyObject *default_value = NULL; - - if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) { - goto exit; - } - object = args[0]; - name = args[1]; - if (nargs < 3) { - goto skip_optional; - } - default_value = args[2]; -skip_optional: - return_value = builtin_getattr_impl(module, object, name, default_value); - -exit: - return return_value; -} - PyDoc_STRVAR(builtin_globals__doc__, "globals($module, /)\n" "--\n" @@ -692,44 +607,6 @@ PyDoc_STRVAR(builtin_id__doc__, #define BUILTIN_ID_METHODDEF \ {"id", (PyCFunction)builtin_id, METH_O, builtin_id__doc__}, -PyDoc_STRVAR(builtin_next__doc__, -"next($module, iterator, default=, /)\n" -"--\n" -"\n" -"Return the next item from the iterator.\n" -"\n" -"If default is given and the iterator is exhausted,\n" -"it is returned instead of raising StopIteration."); - -#define BUILTIN_NEXT_METHODDEF \ - {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, builtin_next__doc__}, - -static PyObject * -builtin_next_impl(PyObject *module, PyObject *iterator, - PyObject *default_value); - -static PyObject * -builtin_next(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *iterator; - PyObject *default_value = NULL; - - if (!_PyArg_CheckPositional("next", nargs, 1, 2)) { - goto exit; - } - iterator = args[0]; - if (nargs < 2) { - goto skip_optional; - } - default_value = args[1]; -skip_optional: - return_value = builtin_next_impl(module, iterator, default_value); - -exit: - return return_value; -} - PyDoc_STRVAR(builtin_setattr__doc__, "setattr($module, obj, name, value, /)\n" "--\n" @@ -821,43 +698,6 @@ PyDoc_STRVAR(builtin_hex__doc__, #define BUILTIN_HEX_METHODDEF \ {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, -PyDoc_STRVAR(builtin_iter__doc__, -"iter($module, object, sentinel=, /)\n" -"--\n" -"\n" -"Get an iterator from an object.\n" -"\n" -"In the first form, the argument must supply its own iterator, or be a sequence.\n" -"In the second form, the callable is called until it returns the sentinel."); - -#define BUILTIN_ITER_METHODDEF \ - {"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, builtin_iter__doc__}, - -static PyObject * -builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel); - -static PyObject * -builtin_iter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *object; - PyObject *sentinel = NULL; - - if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) { - goto exit; - } - object = args[0]; - if (nargs < 2) { - goto skip_optional; - } - sentinel = args[1]; -skip_optional: - return_value = builtin_iter_impl(module, object, sentinel); - -exit: - return return_value; -} - PyDoc_STRVAR(builtin_aiter__doc__, "aiter($module, async_iterable, /)\n" "--\n" @@ -1236,41 +1076,6 @@ builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec return return_value; } -PyDoc_STRVAR(builtin_vars__doc__, -"vars($module, object=, /)\n" -"--\n" -"\n" -"Show vars.\n" -"\n" -"Without arguments, equivalent to locals().\n" -"With an argument, equivalent to object.__dict__."); - -#define BUILTIN_VARS_METHODDEF \ - {"vars", _PyCFunction_CAST(builtin_vars), METH_FASTCALL, builtin_vars__doc__}, - -static PyObject * -builtin_vars_impl(PyObject *module, PyObject *object); - -static PyObject * -builtin_vars(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *object = NULL; - - if (!_PyArg_CheckPositional("vars", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - object = args[0]; -skip_optional: - return_value = builtin_vars_impl(module, object); - -exit: - return return_value; -} - PyDoc_STRVAR(builtin_sum__doc__, "sum($module, iterable, /, start=0)\n" "--\n" @@ -1406,4 +1211,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=ef2f16ece134d62d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=607c62f2341ebfc0 input=a9049054013a1b77]*/ diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h index 27c375717bff96..292d3f7f4ff49c 100644 --- a/Python/clinic/context.c.h +++ b/Python/clinic/context.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(_contextvars_Context_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -183,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=0c94d4b919500438 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2436b16a92452869 input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index dec9ea90b863c7..890c3026fc9996 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(_imp_lock_held__doc__, "lock_held($module, /)\n" "--\n" @@ -411,7 +410,7 @@ _imp__override_frozen_modules_for_tests(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int override; - override = _PyLong_AsInt(arg); + override = PyLong_AsInt(arg); if (override == -1 && PyErr_Occurred()) { goto exit; } @@ -442,7 +441,7 @@ _imp__override_multi_interp_extensions_check(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int override; - override = _PyLong_AsInt(arg); + override = PyLong_AsInt(arg); if (override == -1 && PyErr_Occurred()) { goto exit; } @@ -627,4 +626,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=a95ec234672280a2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=058f6aa1c9f4ebe4 input=a9049054013a1b77]*/ diff --git a/Python/clinic/instrumentation.c.h b/Python/clinic/instrumentation.c.h index cf3984ca24bbfe..1b1b6d048b0dd0 100644 --- a/Python/clinic/instrumentation.c.h +++ b/Python/clinic/instrumentation.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(monitoring_use_tool_id__doc__, "use_tool_id($module, tool_id, name, /)\n" "--\n" @@ -29,7 +23,7 @@ monitoring_use_tool_id(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (!_PyArg_CheckPositional("use_tool_id", nargs, 2, 2)) { goto exit; } - tool_id = _PyLong_AsInt(args[0]); + tool_id = PyLong_AsInt(args[0]); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } @@ -57,7 +51,7 @@ monitoring_free_tool_id(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int tool_id; - tool_id = _PyLong_AsInt(arg); + tool_id = PyLong_AsInt(arg); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } @@ -84,7 +78,7 @@ monitoring_get_tool(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int tool_id; - tool_id = _PyLong_AsInt(arg); + tool_id = PyLong_AsInt(arg); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } @@ -117,11 +111,11 @@ monitoring_register_callback(PyObject *module, PyObject *const *args, Py_ssize_t if (!_PyArg_CheckPositional("register_callback", nargs, 3, 3)) { goto exit; } - tool_id = _PyLong_AsInt(args[0]); + tool_id = PyLong_AsInt(args[0]); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } - event = _PyLong_AsInt(args[1]); + event = PyLong_AsInt(args[1]); if (event == -1 && PyErr_Occurred()) { goto exit; } @@ -150,7 +144,7 @@ monitoring_get_events(PyObject *module, PyObject *arg) int tool_id; int _return_value; - tool_id = _PyLong_AsInt(arg); + tool_id = PyLong_AsInt(arg); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } @@ -185,11 +179,11 @@ monitoring_set_events(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("set_events", nargs, 2, 2)) { goto exit; } - tool_id = _PyLong_AsInt(args[0]); + tool_id = PyLong_AsInt(args[0]); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } - event_set = _PyLong_AsInt(args[1]); + event_set = PyLong_AsInt(args[1]); if (event_set == -1 && PyErr_Occurred()) { goto exit; } @@ -222,7 +216,7 @@ monitoring_get_local_events(PyObject *module, PyObject *const *args, Py_ssize_t if (!_PyArg_CheckPositional("get_local_events", nargs, 2, 2)) { goto exit; } - tool_id = _PyLong_AsInt(args[0]); + tool_id = PyLong_AsInt(args[0]); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } @@ -260,12 +254,12 @@ monitoring_set_local_events(PyObject *module, PyObject *const *args, Py_ssize_t if (!_PyArg_CheckPositional("set_local_events", nargs, 3, 3)) { goto exit; } - tool_id = _PyLong_AsInt(args[0]); + tool_id = PyLong_AsInt(args[0]); if (tool_id == -1 && PyErr_Occurred()) { goto exit; } code = args[1]; - event_set = _PyLong_AsInt(args[2]); + event_set = PyLong_AsInt(args[2]); if (event_set == -1 && PyErr_Occurred()) { goto exit; } @@ -308,4 +302,4 @@ monitoring__all_events(PyObject *module, PyObject *Py_UNUSED(ignored)) { return monitoring__all_events_impl(module); } -/*[clinic end generated code: output=11cc0803875b3ffa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=46f449b18195f976 input=a9049054013a1b77]*/ diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h index a593b980544b72..16e48f77c87fdb 100644 --- a/Python/clinic/marshal.c.h +++ b/Python/clinic/marshal.c.h @@ -2,12 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - PyDoc_STRVAR(marshal_dump__doc__, "dump($module, value, file, version=version, /)\n" "--\n" @@ -48,7 +42,7 @@ marshal_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - version = _PyLong_AsInt(args[2]); + version = PyLong_AsInt(args[2]); if (version == -1 && PyErr_Occurred()) { goto exit; } @@ -112,7 +106,7 @@ marshal_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - version = _PyLong_AsInt(args[1]); + version = PyLong_AsInt(args[1]); if (version == -1 && PyErr_Occurred()) { goto exit; } @@ -161,4 +155,4 @@ marshal_loads(PyObject *module, PyObject *arg) return return_value; } -/*[clinic end generated code: output=12082d61d2942473 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=23091e077319f596 input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index a95a32f65edb89..06105e221c1f89 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(sys_addaudithook__doc__, "addaudithook($module, /, hook)\n" "--\n" @@ -444,7 +443,7 @@ sys_setrecursionlimit(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int new_limit; - new_limit = _PyLong_AsInt(arg); + new_limit = PyLong_AsInt(arg); if (new_limit == -1 && PyErr_Occurred()) { goto exit; } @@ -507,7 +506,7 @@ sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, if (!args) { goto exit; } - depth = _PyLong_AsInt(args[0]); + depth = PyLong_AsInt(args[0]); if (depth == -1 && PyErr_Occurred()) { goto exit; } @@ -675,7 +674,7 @@ sys_setdlopenflags(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int new_val; - new_val = _PyLong_AsInt(arg); + new_val = PyLong_AsInt(arg); if (new_val == -1 && PyErr_Occurred()) { goto exit; } @@ -730,7 +729,7 @@ sys_mdebug(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - flag = _PyLong_AsInt(arg); + flag = PyLong_AsInt(arg); if (flag == -1 && PyErr_Occurred()) { goto exit; } @@ -808,7 +807,7 @@ sys_set_int_max_str_digits(PyObject *module, PyObject *const *args, Py_ssize_t n if (!args) { goto exit; } - maxdigits = _PyLong_AsInt(args[0]); + maxdigits = PyLong_AsInt(args[0]); if (maxdigits == -1 && PyErr_Occurred()) { goto exit; } @@ -969,7 +968,7 @@ sys__getframe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - depth = _PyLong_AsInt(args[0]); + depth = PyLong_AsInt(args[0]); if (depth == -1 && PyErr_Occurred()) { goto exit; } @@ -1121,7 +1120,7 @@ PyDoc_STRVAR(sys__stats_on__doc__, "_stats_on($module, /)\n" "--\n" "\n" -"Turns on stats gathering (stats gathering is on by default)."); +"Turns on stats gathering (stats gathering is off by default)."); #define SYS__STATS_ON_METHODDEF \ {"_stats_on", (PyCFunction)sys__stats_on, METH_NOARGS, sys__stats_on__doc__}, @@ -1143,7 +1142,7 @@ PyDoc_STRVAR(sys__stats_off__doc__, "_stats_off($module, /)\n" "--\n" "\n" -"Turns off stats gathering (stats gathering is on by default)."); +"Turns off stats gathering (stats gathering is off by default)."); #define SYS__STATS_OFF_METHODDEF \ {"_stats_off", (PyCFunction)sys__stats_off, METH_NOARGS, sys__stats_off__doc__}, @@ -1187,18 +1186,30 @@ PyDoc_STRVAR(sys__stats_dump__doc__, "_stats_dump($module, /)\n" "--\n" "\n" -"Dump stats to file, and clears the stats."); +"Dump stats to file, and clears the stats.\n" +"\n" +"Return False if no statistics were not dumped because stats gathering was off."); #define SYS__STATS_DUMP_METHODDEF \ {"_stats_dump", (PyCFunction)sys__stats_dump, METH_NOARGS, sys__stats_dump__doc__}, -static PyObject * +static int sys__stats_dump_impl(PyObject *module); static PyObject * sys__stats_dump(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return sys__stats_dump_impl(module); + PyObject *return_value = NULL; + int _return_value; + + _return_value = sys__stats_dump_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; } #endif /* defined(Py_STATS) */ @@ -1358,7 +1369,7 @@ sys__getframemodulename(PyObject *module, PyObject *const *args, Py_ssize_t narg if (!noptargs) { goto skip_optional_pos; } - depth = _PyLong_AsInt(args[0]); + depth = PyLong_AsInt(args[0]); if (depth == -1 && PyErr_Occurred()) { goto exit; } @@ -1369,6 +1380,34 @@ sys__getframemodulename(PyObject *module, PyObject *const *args, Py_ssize_t narg return return_value; } +PyDoc_STRVAR(sys__get_cpu_count_config__doc__, +"_get_cpu_count_config($module, /)\n" +"--\n" +"\n" +"Private function for getting PyConfig.cpu_count"); + +#define SYS__GET_CPU_COUNT_CONFIG_METHODDEF \ + {"_get_cpu_count_config", (PyCFunction)sys__get_cpu_count_config, METH_NOARGS, sys__get_cpu_count_config__doc__}, + +static int +sys__get_cpu_count_config_impl(PyObject *module); + +static PyObject * +sys__get_cpu_count_config(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = sys__get_cpu_count_config_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + #ifndef SYS_GETWINDOWSVERSION_METHODDEF #define SYS_GETWINDOWSVERSION_METHODDEF #endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ @@ -1412,4 +1451,4 @@ sys__getframemodulename(PyObject *module, PyObject *const *args, Py_ssize_t narg #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=41937e0843c68009 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3a7d3fbbcb281c22 input=a9049054013a1b77]*/ diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index 3c344934971643..c5687e30748782 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -3,11 +3,10 @@ preserve [clinic start generated code]*/ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() #endif - PyDoc_STRVAR(tb_new__doc__, "TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" "--\n" @@ -65,11 +64,11 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } tb_frame = (PyFrameObject *)fastargs[1]; - tb_lasti = _PyLong_AsInt(fastargs[2]); + tb_lasti = PyLong_AsInt(fastargs[2]); if (tb_lasti == -1 && PyErr_Occurred()) { goto exit; } - tb_lineno = _PyLong_AsInt(fastargs[3]); + tb_lineno = PyLong_AsInt(fastargs[3]); if (tb_lineno == -1 && PyErr_Occurred()) { goto exit; } @@ -78,4 +77,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=7bc9927e362fdfb7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=57e27eb68d04d842 input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index 4e47ff93a3691b..b79bf555f2f22a 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -14,7 +14,6 @@ Copyright (c) Corporation for National Research Initiatives. #include "pycore_pyerrors.h" // _PyErr_FormatNote() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI -#include const char *Py_hexdigits = "0123456789abcdef"; @@ -617,20 +616,19 @@ int PyCodec_RegisterError(const char *name, PyObject *error) the error handling callback for strict encoding will be returned. */ PyObject *PyCodec_LookupError(const char *name) { - PyObject *handler = NULL; - PyInterpreterState *interp = _PyInterpreterState_GET(); if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) return NULL; if (name==NULL) name = "strict"; - handler = _PyDict_GetItemStringWithError(interp->codec_error_registry, name); - if (handler) { - Py_INCREF(handler); + PyObject *handler; + if (PyDict_GetItemStringRef(interp->codec_error_registry, name, &handler) < 0) { + return NULL; } - else if (!PyErr_Occurred()) { + if (handler == NULL) { PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); + return NULL; } return handler; } diff --git a/Python/compile.c b/Python/compile.c index d5405b46561820..1d9ae626677310 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -24,16 +24,19 @@ #include #include "Python.h" +#include "opcode.h" #include "pycore_ast.h" // _PyAST_GetDocString() #define NEED_OPCODE_TABLES #include "pycore_opcode_utils.h" #undef NEED_OPCODE_TABLES -#include "pycore_flowgraph.h" #include "pycore_code.h" // _PyCode_New() #include "pycore_compile.h" +#include "pycore_flowgraph.h" #include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() #include "pycore_pystate.h" // _Py_GetConfig() +#include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST() #define NEED_OPCODE_METADATA @@ -69,9 +72,7 @@ && ((C)->u->u_ste->ste_type == ModuleBlock)) typedef _PyCompilerSrcLocation location; -typedef _PyCfgInstruction cfg_instr; -typedef _PyCfgBasicblock basicblock; -typedef _PyCfgBuilder cfg_builder; +typedef struct _PyCfgBuilder cfg_builder; #define LOCATION(LNO, END_LNO, COL, END_COL) \ ((const _PyCompilerSrcLocation){(LNO), (END_LNO), (COL), (END_COL)}) @@ -100,7 +101,7 @@ static jump_target_label NO_LABEL = {-1}; } #define USE_LABEL(C, LBL) \ - RETURN_IF_ERROR(instr_sequence_use_label(INSTR_SEQUENCE(C), (LBL).id)) + RETURN_IF_ERROR(_PyCompile_InstructionSequence_UseLabel(INSTR_SEQUENCE(C), (LBL).id)) /* fblockinfo tracks the current frame block. @@ -217,8 +218,9 @@ instr_sequence_new_label(instr_sequence *seq) return lbl; } -static int -instr_sequence_use_label(instr_sequence *seq, int lbl) { +int +_PyCompile_InstructionSequence_UseLabel(instr_sequence *seq, int lbl) +{ int old_size = seq->s_labelmap_size; RETURN_IF_ERROR( _PyCompile_EnsureArrayLargeEnough(lbl, @@ -237,8 +239,9 @@ instr_sequence_use_label(instr_sequence *seq, int lbl) { #define MAX_OPCODE 511 -static int -instr_sequence_addop(instr_sequence *seq, int opcode, int oparg, location loc) +int +_PyCompile_InstructionSequence_Addop(instr_sequence *seq, int opcode, int oparg, + location loc) { assert(0 <= opcode && opcode <= MAX_OPCODE); assert(IS_WITHIN_OPCODE_RANGE(opcode)); @@ -287,10 +290,12 @@ instr_sequence_fini(instr_sequence *seq) { seq->s_instrs = NULL; } -static int -instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) { - memset(g, 0, sizeof(cfg_builder)); - RETURN_IF_ERROR(_PyCfgBuilder_Init(g)); +static cfg_builder* +instr_sequence_to_cfg(instr_sequence *seq) { + cfg_builder *g = _PyCfgBuilder_New(); + if (g == NULL) { + return NULL; + } /* There can be more than one label for the same offset. The * offset2lbl maping selects one of them which we use consistently. @@ -299,7 +304,7 @@ instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) { int *offset2lbl = PyMem_Malloc(seq->s_used * sizeof(int)); if (offset2lbl == NULL) { PyErr_NoMemory(); - return ERROR; + goto error; } for (int i = 0; i < seq->s_used; i++) { offset2lbl[i] = -1; @@ -335,23 +340,17 @@ instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) { goto error; } } - PyMem_Free(offset2lbl); - - int nblocks = 0; - for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) { - nblocks++; - } - if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { - PyErr_NoMemory(); - return ERROR; + if (_PyCfgBuilder_CheckSize(g) < 0) { + goto error; } - return SUCCESS; + PyMem_Free(offset2lbl); + return g; error: + _PyCfgBuilder_Free(g); PyMem_Free(offset2lbl); - return ERROR; + return NULL; } - /* The following items change on entry and exit of code blocks. They must be saved and restored when returning to a block. */ @@ -560,6 +559,24 @@ _PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags, return co; } +int +_PyCompile_AstOptimize(mod_ty mod, PyObject *filename, PyCompilerFlags *cf, + int optimize, PyArena *arena) +{ + PyFutureFeatures future; + if (!_PyFuture_FromAST(mod, filename, &future)) { + return -1; + } + int flags = future.ff_features | cf->cf_flags; + if (optimize == -1) { + optimize = _Py_GetConfig()->optimization_level; + } + if (!_PyAST_Optimize(mod, arena, optimize, flags)) { + return -1; + } + return 0; +} + static void compiler_free(struct compiler *c) { @@ -919,7 +936,7 @@ codegen_addop_noarg(instr_sequence *seq, int opcode, location loc) { assert(!OPCODE_HAS_ARG(opcode)); assert(!IS_ASSEMBLER_OPCODE(opcode)); - return instr_sequence_addop(seq, opcode, 0, loc); + return _PyCompile_InstructionSequence_Addop(seq, opcode, 0, loc); } static Py_ssize_t @@ -1152,7 +1169,7 @@ codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc) int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); assert(!IS_ASSEMBLER_OPCODE(opcode)); - return instr_sequence_addop(seq, opcode, oparg_, loc); + return _PyCompile_InstructionSequence_Addop(seq, opcode, oparg_, loc); } static int @@ -1162,7 +1179,7 @@ codegen_addop_j(instr_sequence *seq, location loc, assert(IS_LABEL(target)); assert(OPCODE_HAS_JUMP(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); assert(!IS_ASSEMBLER_OPCODE(opcode)); - return instr_sequence_addop(seq, opcode, target.id, loc); + return _PyCompile_InstructionSequence_Addop(seq, opcode, target.id, loc); } #define RETURN_IF_ERROR_IN_SCOPE(C, CALL) { \ @@ -1279,7 +1296,7 @@ compiler_enter_scope(struct compiler *c, identifier name, u->u_metadata.u_argcount = 0; u->u_metadata.u_posonlyargcount = 0; u->u_metadata.u_kwonlyargcount = 0; - u->u_ste = PySymtable_Lookup(c->c_st, key); + u->u_ste = _PySymtable_Lookup(c->c_st, key); if (!u->u_ste) { compiler_unit_free(u); return ERROR; @@ -2360,11 +2377,6 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) int is_generic = asdl_seq_LEN(type_params) > 0; - if (is_generic) { - // Used by the CALL to the type parameters function. - ADDOP(c, loc, PUSH_NULL); - } - funcflags = compiler_default_arguments(c, loc, args); if (funcflags == -1) { return ERROR; @@ -2435,8 +2447,12 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) Py_DECREF(co); if (num_typeparam_args > 0) { ADDOP_I(c, loc, SWAP, num_typeparam_args + 1); + ADDOP_I(c, loc, CALL, num_typeparam_args - 1); + } + else { + ADDOP(c, loc, PUSH_NULL); + ADDOP_I(c, loc, CALL, 0); } - ADDOP_I(c, loc, CALL, num_typeparam_args); } RETURN_IF_ERROR(compiler_apply_decorators(c, decos)); @@ -2564,8 +2580,8 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno) // these instructions should be attributed to the class line, // not a decorator line loc = LOC(s); - ADDOP(c, loc, PUSH_NULL); ADDOP(c, loc, LOAD_BUILD_CLASS); + ADDOP(c, loc, PUSH_NULL); /* 3. load a function (or closure) made from the code object */ if (compiler_make_closure(c, loc, co, 0) < 0) { @@ -2597,7 +2613,6 @@ compiler_class(struct compiler *c, stmt_ty s) int is_generic = asdl_seq_LEN(type_params) > 0; if (is_generic) { Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name)); - ADDOP(c, loc, PUSH_NULL); PyObject *type_params_name = PyUnicode_FromFormat("", s->v.ClassDef.name); if (!type_params_name) { @@ -2665,6 +2680,7 @@ compiler_class(struct compiler *c, stmt_ty s) return ERROR; } Py_DECREF(co); + ADDOP(c, loc, PUSH_NULL); ADDOP_I(c, loc, CALL, 0); } else { RETURN_IF_ERROR(compiler_call_helper(c, loc, 2, @@ -2715,7 +2731,6 @@ compiler_typealias(struct compiler *c, stmt_ty s) int is_generic = asdl_seq_LEN(type_params) > 0; PyObject *name = s->v.TypeAlias.name->v.Name.id; if (is_generic) { - ADDOP(c, loc, PUSH_NULL); PyObject *type_params_name = PyUnicode_FromFormat("", name); if (!type_params_name) { @@ -2755,6 +2770,7 @@ compiler_typealias(struct compiler *c, stmt_ty s) return ERROR; } Py_DECREF(co); + ADDOP(c, loc, PUSH_NULL); ADDOP_I(c, loc, CALL, 0); } RETURN_IF_ERROR(compiler_nameop(c, loc, name, Store)); @@ -3245,18 +3261,6 @@ compiler_continue(struct compiler *c, location loc) } -static location -location_of_last_executing_statement(asdl_stmt_seq *stmts) -{ - for (Py_ssize_t i = asdl_seq_LEN(stmts) - 1; i >= 0; i++) { - location loc = LOC((stmt_ty)asdl_seq_GET(stmts, i)); - if (loc.lineno > 0) { - return loc; - } - } - return NO_LOCATION; -} - /* Code generated for "try: finally: " is as follows: SETUP_FINALLY L @@ -3325,9 +3329,9 @@ compiler_try_finally(struct compiler *c, stmt_ty s) RETURN_IF_ERROR( compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - loc = location_of_last_executing_statement(s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); + loc = NO_LOCATION; ADDOP_I(c, loc, RERAISE, 0); USE_LABEL(c, cleanup); @@ -3376,9 +3380,9 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s) compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); - loc = location_of_last_executing_statement(s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); + loc = NO_LOCATION; ADDOP_I(c, loc, RERAISE, 0); USE_LABEL(c, cleanup); @@ -3956,7 +3960,7 @@ compiler_assert(struct compiler *c, stmt_ty s) VISIT(c, expr, s->v.Assert.msg); ADDOP_I(c, LOC(s), CALL, 0); } - ADDOP_I(c, LOC(s), RAISE_VARARGS, 1); + ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1); USE_LABEL(c, end); return SUCCESS; @@ -4198,9 +4202,20 @@ compiler_nameop(struct compiler *c, location loc, optype = OP_DEREF; break; case LOCAL: - if (_PyST_IsFunctionLike(c->u->u_ste) || - (PyDict_GetItem(c->u->u_metadata.u_fasthidden, mangled) == Py_True)) + if (_PyST_IsFunctionLike(c->u->u_ste)) { optype = OP_FAST; + } + else { + PyObject *item; + if (PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, mangled, + &item) < 0) { + goto error; + } + if (item == Py_True) { + optype = OP_FAST; + } + Py_XDECREF(item); + } break; case GLOBAL_IMPLICIT: if (_PyST_IsFunctionLike(c->u->u_ste)) @@ -4225,7 +4240,7 @@ compiler_nameop(struct compiler *c, location loc, op = LOAD_FROM_DICT_OR_DEREF; // First load the locals if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) { - return ERROR; + goto error; } } else if (c->u->u_ste->ste_can_see_class_scope) { @@ -4233,7 +4248,7 @@ compiler_nameop(struct compiler *c, location loc, // First load the classdict if (compiler_addop_o(c->u, loc, LOAD_DEREF, c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) { - return ERROR; + goto error; } } else { @@ -4260,7 +4275,7 @@ compiler_nameop(struct compiler *c, location loc, // First load the classdict if (compiler_addop_o(c->u, loc, LOAD_DEREF, c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) { - return ERROR; + goto error; } } else { op = LOAD_GLOBAL; @@ -4294,6 +4309,10 @@ compiler_nameop(struct compiler *c, location loc, arg <<= 1; } return codegen_addop_i(INSTR_SEQUENCE(c), op, arg, loc); + +error: + Py_DECREF(mangled); + return ERROR; } static int @@ -4837,7 +4856,7 @@ load_args_for_super(struct compiler *c, expr_ty e) { // load super() global PyObject *super_name = e->v.Call.func->v.Name.id; - RETURN_IF_ERROR(compiler_nameop(c, loc, super_name, Load)); + RETURN_IF_ERROR(compiler_nameop(c, LOC(e->v.Call.func), super_name, Load)); if (asdl_seq_LEN(e->v.Call.args) == 2) { VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0)); @@ -4951,9 +4970,13 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) VISIT_SEQ(c, keyword, kwds); RETURN_IF_ERROR( compiler_call_simple_kw_helper(c, loc, kwds, kwdsl)); + loc = update_start_location_to_match_attr(c, LOC(e), meth); + ADDOP_I(c, loc, CALL_KW, argsl + kwdsl); + } + else { + loc = update_start_location_to_match_attr(c, LOC(e), meth); + ADDOP_I(c, loc, CALL, argsl); } - loc = update_start_location_to_match_attr(c, LOC(e), meth); - ADDOP_I(c, loc, CALL, argsl + kwdsl); return 1; } @@ -4993,9 +5016,9 @@ compiler_call(struct compiler *c, expr_ty e) return SUCCESS; } RETURN_IF_ERROR(check_caller(c, e->v.Call.func)); + VISIT(c, expr, e->v.Call.func); location loc = LOC(e->v.Call.func); ADDOP(c, loc, PUSH_NULL); - VISIT(c, expr, e->v.Call.func); loc = LOC(e); return compiler_call_helper(c, loc, 0, e->v.Call.args, @@ -5119,7 +5142,7 @@ compiler_subkwargs(struct compiler *c, location loc, } /* Used by compiler_call_helper and maybe_optimize_method_call to emit - * KW_NAMES before CALL. + * a tuple of keyword names before CALL. */ static int compiler_call_simple_kw_helper(struct compiler *c, location loc, @@ -5134,12 +5157,7 @@ compiler_call_simple_kw_helper(struct compiler *c, location loc, keyword_ty kw = asdl_seq_GET(keywords, i); PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg)); } - Py_ssize_t arg = compiler_add_const(c->c_const_cache, c->u, names); - if (arg < 0) { - return ERROR; - } - Py_DECREF(names); - ADDOP_I(c, loc, KW_NAMES, arg); + ADDOP_LOAD_CONST_NEW(c, loc, names); return SUCCESS; } @@ -5184,8 +5202,11 @@ compiler_call_helper(struct compiler *c, location loc, VISIT_SEQ(c, keyword, keywords); RETURN_IF_ERROR( compiler_call_simple_kw_helper(c, loc, keywords, nkwelts)); + ADDOP_I(c, loc, CALL_KW, n + nelts + nkwelts); + } + else { + ADDOP_I(c, loc, CALL, n + nelts); } - ADDOP_I(c, loc, CALL, n + nelts + nkwelts); return SUCCESS; ex_call: @@ -5499,6 +5520,8 @@ typedef struct { PyObject *pushed_locals; PyObject *temp_symbols; PyObject *fast_hidden; + jump_target_label cleanup; + jump_target_label end; } inlined_comprehension_state; static int @@ -5522,8 +5545,13 @@ push_inlined_comprehension_state(struct compiler *c, location loc, if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) { if (!_PyST_IsFunctionLike(c->u->u_ste)) { // non-function scope: override this name to use fast locals - PyObject *orig = PyDict_GetItem(c->u->u_metadata.u_fasthidden, k); - if (orig != Py_True) { + PyObject *orig; + if (PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, k, &orig) < 0) { + return ERROR; + } + int orig_is_true = (orig == Py_True); + Py_XDECREF(orig); + if (!orig_is_true) { if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) { return ERROR; } @@ -5604,11 +5632,45 @@ push_inlined_comprehension_state(struct compiler *c, location loc, // `pushed_locals` on the stack, but this will be reversed when we swap // out the comprehension result in pop_inlined_comprehension_state ADDOP_I(c, loc, SWAP, PyList_GET_SIZE(state->pushed_locals) + 1); + + // Add our own cleanup handler to restore comprehension locals in case + // of exception, so they have the correct values inside an exception + // handler or finally block. + NEW_JUMP_TARGET_LABEL(c, cleanup); + state->cleanup = cleanup; + NEW_JUMP_TARGET_LABEL(c, end); + state->end = end; + + // no need to push an fblock for this "virtual" try/finally; there can't + // be return/continue/break inside a comprehension + ADDOP_JUMP(c, loc, SETUP_FINALLY, cleanup); } return SUCCESS; } +static int +restore_inlined_comprehension_locals(struct compiler *c, location loc, + inlined_comprehension_state state) +{ + PyObject *k; + // pop names we pushed to stack earlier + Py_ssize_t npops = PyList_GET_SIZE(state.pushed_locals); + // Preserve the comprehension result (or exception) as TOS. This + // reverses the SWAP we did in push_inlined_comprehension_state to get + // the outermost iterable to TOS, so we can still just iterate + // pushed_locals in simple reverse order + ADDOP_I(c, loc, SWAP, npops + 1); + for (Py_ssize_t i = npops - 1; i >= 0; --i) { + k = PyList_GetItem(state.pushed_locals, i); + if (k == NULL) { + return ERROR; + } + ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames); + } + return SUCCESS; +} + static int pop_inlined_comprehension_state(struct compiler *c, location loc, inlined_comprehension_state state) @@ -5625,19 +5687,22 @@ pop_inlined_comprehension_state(struct compiler *c, location loc, Py_CLEAR(state.temp_symbols); } if (state.pushed_locals) { - // pop names we pushed to stack earlier - Py_ssize_t npops = PyList_GET_SIZE(state.pushed_locals); - // Preserve the list/dict/set result of the comprehension as TOS. This - // reverses the SWAP we did in push_inlined_comprehension_state to get - // the outermost iterable to TOS, so we can still just iterate - // pushed_locals in simple reverse order - ADDOP_I(c, loc, SWAP, npops + 1); - for (Py_ssize_t i = npops - 1; i >= 0; --i) { - k = PyList_GetItem(state.pushed_locals, i); - if (k == NULL) { - return ERROR; - } - ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_JUMP(c, NO_LOCATION, JUMP, state.end); + + // cleanup from an exception inside the comprehension + USE_LABEL(c, state.cleanup); + // discard incomplete comprehension result (beneath exc on stack) + ADDOP_I(c, NO_LOCATION, SWAP, 2); + ADDOP(c, NO_LOCATION, POP_TOP); + if (restore_inlined_comprehension_locals(c, loc, state) < 0) { + return ERROR; + } + ADDOP_I(c, NO_LOCATION, RERAISE, 0); + + USE_LABEL(c, state.end); + if (restore_inlined_comprehension_locals(c, loc, state) < 0) { + return ERROR; } Py_CLEAR(state.pushed_locals); } @@ -5680,11 +5745,11 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, expr_ty val) { PyCodeObject *co = NULL; - inlined_comprehension_state inline_state = {NULL, NULL}; + inlined_comprehension_state inline_state = {NULL, NULL, NULL, NO_LABEL, NO_LABEL}; comprehension_ty outermost; int scope_type = c->u->u_scope_type; int is_top_level_await = IS_TOP_LEVEL_AWAIT(c); - PySTEntryObject *entry = PySymtable_Lookup(c->c_st, (void *)e); + PySTEntryObject *entry = _PySymtable_Lookup(c->c_st, (void *)e); if (entry == NULL) { goto error; } @@ -7492,194 +7557,6 @@ _PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj) return SUCCESS; } - -static int * -build_cellfixedoffsets(_PyCompile_CodeUnitMetadata *umd) -{ - int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); - int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); - int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); - - int noffsets = ncellvars + nfreevars; - int *fixed = PyMem_New(int, noffsets); - if (fixed == NULL) { - PyErr_NoMemory(); - return NULL; - } - for (int i = 0; i < noffsets; i++) { - fixed[i] = nlocals + i; - } - - PyObject *varname, *cellindex; - Py_ssize_t pos = 0; - while (PyDict_Next(umd->u_cellvars, &pos, &varname, &cellindex)) { - PyObject *varindex = PyDict_GetItem(umd->u_varnames, varname); - if (varindex != NULL) { - assert(PyLong_AS_LONG(cellindex) < INT_MAX); - assert(PyLong_AS_LONG(varindex) < INT_MAX); - int oldindex = (int)PyLong_AS_LONG(cellindex); - int argoffset = (int)PyLong_AS_LONG(varindex); - fixed[oldindex] = argoffset; - } - } - - return fixed; -} - -static int -insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, - int *fixed, int nfreevars, int code_flags) -{ - assert(umd->u_firstlineno > 0); - - /* Add the generator prefix instructions. */ - if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - cfg_instr make_gen = { - .i_opcode = RETURN_GENERATOR, - .i_oparg = 0, - .i_loc = LOCATION(umd->u_firstlineno, umd->u_firstlineno, -1, -1), - .i_target = NULL, - }; - RETURN_IF_ERROR(_PyBasicblock_InsertInstruction(entryblock, 0, &make_gen)); - cfg_instr pop_top = { - .i_opcode = POP_TOP, - .i_oparg = 0, - .i_loc = NO_LOCATION, - .i_target = NULL, - }; - RETURN_IF_ERROR(_PyBasicblock_InsertInstruction(entryblock, 1, &pop_top)); - } - - /* Set up cells for any variable that escapes, to be put in a closure. */ - const int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); - if (ncellvars) { - // umd->u_cellvars has the cells out of order so we sort them - // before adding the MAKE_CELL instructions. Note that we - // adjust for arg cells, which come first. - const int nvars = ncellvars + (int)PyDict_GET_SIZE(umd->u_varnames); - int *sorted = PyMem_RawCalloc(nvars, sizeof(int)); - if (sorted == NULL) { - PyErr_NoMemory(); - return ERROR; - } - for (int i = 0; i < ncellvars; i++) { - sorted[fixed[i]] = i + 1; - } - for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) { - int oldindex = sorted[i] - 1; - if (oldindex == -1) { - continue; - } - cfg_instr make_cell = { - .i_opcode = MAKE_CELL, - // This will get fixed in offset_derefs(). - .i_oparg = oldindex, - .i_loc = NO_LOCATION, - .i_target = NULL, - }; - if (_PyBasicblock_InsertInstruction(entryblock, ncellsused, &make_cell) < 0) { - PyMem_RawFree(sorted); - return ERROR; - } - ncellsused += 1; - } - PyMem_RawFree(sorted); - } - - if (nfreevars) { - cfg_instr copy_frees = { - .i_opcode = COPY_FREE_VARS, - .i_oparg = nfreevars, - .i_loc = NO_LOCATION, - .i_target = NULL, - }; - RETURN_IF_ERROR(_PyBasicblock_InsertInstruction(entryblock, 0, ©_frees)); - } - - return SUCCESS; -} - -static int -fix_cell_offsets(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, int *fixedmap) -{ - int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); - int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); - int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); - int noffsets = ncellvars + nfreevars; - - // First deal with duplicates (arg cells). - int numdropped = 0; - for (int i = 0; i < noffsets ; i++) { - if (fixedmap[i] == i + nlocals) { - fixedmap[i] -= numdropped; - } - else { - // It was a duplicate (cell/arg). - numdropped += 1; - } - } - - // Then update offsets, either relative to locals or by cell2arg. - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - for (int i = 0; i < b->b_iused; i++) { - cfg_instr *inst = &b->b_instr[i]; - // This is called before extended args are generated. - assert(inst->i_opcode != EXTENDED_ARG); - int oldoffset = inst->i_oparg; - switch(inst->i_opcode) { - case MAKE_CELL: - case LOAD_CLOSURE: - case LOAD_DEREF: - case STORE_DEREF: - case DELETE_DEREF: - case LOAD_FROM_DICT_OR_DEREF: - assert(oldoffset >= 0); - assert(oldoffset < noffsets); - assert(fixedmap[oldoffset] >= 0); - inst->i_oparg = fixedmap[oldoffset]; - } - } - } - - return numdropped; -} - - -static int -prepare_localsplus(_PyCompile_CodeUnitMetadata *umd, cfg_builder *g, int code_flags) -{ - assert(PyDict_GET_SIZE(umd->u_varnames) < INT_MAX); - assert(PyDict_GET_SIZE(umd->u_cellvars) < INT_MAX); - assert(PyDict_GET_SIZE(umd->u_freevars) < INT_MAX); - int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); - int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); - int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); - assert(INT_MAX - nlocals - ncellvars > 0); - assert(INT_MAX - nlocals - ncellvars - nfreevars > 0); - int nlocalsplus = nlocals + ncellvars + nfreevars; - int* cellfixedoffsets = build_cellfixedoffsets(umd); - if (cellfixedoffsets == NULL) { - return ERROR; - } - - - // This must be called before fix_cell_offsets(). - if (insert_prefix_instructions(umd, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) { - PyMem_Free(cellfixedoffsets); - return ERROR; - } - - int numdropped = fix_cell_offsets(umd, g->g_entryblock, cellfixedoffsets); - PyMem_Free(cellfixedoffsets); // At this point we're done with it. - cellfixedoffsets = NULL; - if (numdropped < 0) { - return ERROR; - } - - nlocalsplus -= numdropped; - return nlocalsplus; -} - static int add_return_at_end(struct compiler *c, int addNone) { @@ -7693,12 +7570,11 @@ add_return_at_end(struct compiler *c, int addNone) return SUCCESS; } -static int cfg_to_instr_sequence(cfg_builder *g, instr_sequence *seq); - static PyCodeObject * optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache, int code_flags, PyObject *filename) { + cfg_builder *g = NULL; instr_sequence optimized_instrs; memset(&optimized_instrs, 0, sizeof(instr_sequence)); @@ -7707,51 +7583,37 @@ optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache, if (consts == NULL) { goto error; } - cfg_builder g; - if (instr_sequence_to_cfg(&u->u_instr_sequence, &g) < 0) { + g = instr_sequence_to_cfg(&u->u_instr_sequence); + if (g == NULL) { goto error; } - int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames); int nlocals = (int)PyDict_GET_SIZE(u->u_metadata.u_varnames); + int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames); assert(u->u_metadata.u_firstlineno); - if (_PyCfg_OptimizeCodeUnit(&g, consts, const_cache, code_flags, nlocals, - nparams, u->u_metadata.u_firstlineno) < 0) { - goto error; - } - /** Assembly **/ - int nlocalsplus = prepare_localsplus(&u->u_metadata, &g, code_flags); - if (nlocalsplus < 0) { - goto error; - } - - int maxdepth = _PyCfg_Stackdepth(g.g_entryblock, code_flags); - if (maxdepth < 0) { + if (_PyCfg_OptimizeCodeUnit(g, consts, const_cache, nlocals, + nparams, u->u_metadata.u_firstlineno) < 0) { goto error; } - _PyCfg_ConvertPseudoOps(g.g_entryblock); - - /* Order of basic blocks must have been determined by now */ - - if (_PyCfg_ResolveJumps(&g) < 0) { + int stackdepth; + int nlocalsplus; + if (_PyCfg_OptimizedCfgToInstructionSequence(g, &u->u_metadata, code_flags, + &stackdepth, &nlocalsplus, + &optimized_instrs) < 0) { goto error; } - /* Can't modify the bytecode after computing jump offsets. */ - - if (cfg_to_instr_sequence(&g, &optimized_instrs) < 0) { - goto error; - } + /** Assembly **/ co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts, - maxdepth, &optimized_instrs, nlocalsplus, + stackdepth, &optimized_instrs, nlocalsplus, code_flags, filename); error: Py_XDECREF(consts); instr_sequence_fini(&optimized_instrs); - _PyCfgBuilder_Fini(&g); + _PyCfgBuilder_Free(g); return co; } @@ -7774,39 +7636,6 @@ optimize_and_assemble(struct compiler *c, int addNone) return optimize_and_assemble_code_unit(u, const_cache, code_flags, filename); } -static int -cfg_to_instr_sequence(cfg_builder *g, instr_sequence *seq) -{ - int lbl = 0; - for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - b->b_label = (jump_target_label){lbl}; - lbl += b->b_iused; - } - for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - RETURN_IF_ERROR(instr_sequence_use_label(seq, b->b_label.id)); - for (int i = 0; i < b->b_iused; i++) { - cfg_instr *instr = &b->b_instr[i]; - if (OPCODE_HAS_JUMP(instr->i_opcode)) { - instr->i_oparg = instr->i_target->b_label.id; - } - RETURN_IF_ERROR( - instr_sequence_addop(seq, instr->i_opcode, instr->i_oparg, instr->i_loc)); - - _PyCompile_ExceptHandlerInfo *hi = &seq->s_instrs[seq->s_used-1].i_except_handler_info; - if (instr->i_except != NULL) { - hi->h_label = instr->i_except->b_label.id; - hi->h_startdepth = instr->i_except->b_startdepth; - hi->h_preserve_lasti = instr->i_except->b_preserve_lasti; - } - else { - hi->h_label = -1; - } - } - } - return SUCCESS; -} - - /* Access to compiler optimizations for unit tests. * * _PyCompile_CodeGen takes and AST, applies code-gen and @@ -7856,7 +7685,7 @@ instructions_to_instr_sequence(PyObject *instructions, instr_sequence *seq) for (int i = 0; i < num_insts; i++) { if (is_target[i]) { - if (instr_sequence_use_label(seq, i) < 0) { + if (_PyCompile_InstructionSequence_UseLabel(seq, i) < 0) { goto error; } } @@ -7896,7 +7725,7 @@ instructions_to_instr_sequence(PyObject *instructions, instr_sequence *seq) if (PyErr_Occurred()) { goto error; } - if (instr_sequence_addop(seq, opcode, oparg, loc) < 0) { + if (_PyCompile_InstructionSequence_Addop(seq, opcode, oparg, loc) < 0) { goto error; } } @@ -7907,23 +7736,26 @@ instructions_to_instr_sequence(PyObject *instructions, instr_sequence *seq) return ERROR; } -static int -instructions_to_cfg(PyObject *instructions, cfg_builder *g) +static cfg_builder* +instructions_to_cfg(PyObject *instructions) { + cfg_builder *g = NULL; instr_sequence seq; memset(&seq, 0, sizeof(instr_sequence)); if (instructions_to_instr_sequence(instructions, &seq) < 0) { goto error; } - if (instr_sequence_to_cfg(&seq, g) < 0) { + g = instr_sequence_to_cfg(&seq); + if (g == NULL) { goto error; } instr_sequence_fini(&seq); - return SUCCESS; + return g; error: + _PyCfgBuilder_Free(g); instr_sequence_fini(&seq); - return ERROR; + return NULL; } static PyObject * @@ -7962,42 +7794,14 @@ instr_sequence_to_instructions(instr_sequence *seq) static PyObject * cfg_to_instructions(cfg_builder *g) { - PyObject *instructions = PyList_New(0); - if (instructions == NULL) { + instr_sequence seq; + memset(&seq, 0, sizeof(seq)); + if (_PyCfg_ToInstructionSequence(g, &seq) < 0) { return NULL; } - int lbl = 0; - for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - b->b_label = (jump_target_label){lbl}; - lbl += b->b_iused; - } - for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - for (int i = 0; i < b->b_iused; i++) { - cfg_instr *instr = &b->b_instr[i]; - location loc = instr->i_loc; - int arg = HAS_TARGET(instr->i_opcode) ? - instr->i_target->b_label.id : instr->i_oparg; - - PyObject *inst_tuple = Py_BuildValue( - "(iiiiii)", instr->i_opcode, arg, - loc.lineno, loc.end_lineno, - loc.col_offset, loc.end_col_offset); - if (inst_tuple == NULL) { - goto error; - } - - if (PyList_Append(instructions, inst_tuple) != 0) { - Py_DECREF(inst_tuple); - goto error; - } - Py_DECREF(inst_tuple); - } - } - - return instructions; -error: - Py_DECREF(instructions); - return NULL; + PyObject *res = instr_sequence_to_instructions(&seq); + instr_sequence_fini(&seq); + return res; } // C implementation of inspect.cleandoc() @@ -8053,6 +7857,12 @@ _PyCompile_CleanDoc(PyObject *doc) } char *buff = PyMem_Malloc(doc_size); + if (buff == NULL){ + Py_DECREF(doc); + PyErr_NoMemory(); + return NULL; + } + char *w = buff; while (p < pend) { @@ -8173,34 +7983,36 @@ _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags, PyObject * _PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts, int nlocals) { + cfg_builder *g = NULL; PyObject *res = NULL; PyObject *const_cache = PyDict_New(); if (const_cache == NULL) { return NULL; } - cfg_builder g; - if (instructions_to_cfg(instructions, &g) < 0) { + g = instructions_to_cfg(instructions); + if (g == NULL) { goto error; } - int code_flags = 0, nparams = 0, firstlineno = 1; - if (_PyCfg_OptimizeCodeUnit(&g, consts, const_cache, code_flags, nlocals, + int nparams = 0, firstlineno = 1; + if (_PyCfg_OptimizeCodeUnit(g, consts, const_cache, nlocals, nparams, firstlineno) < 0) { goto error; } - res = cfg_to_instructions(&g); + res = cfg_to_instructions(g); error: Py_DECREF(const_cache); - _PyCfgBuilder_Fini(&g); + _PyCfgBuilder_Free(g); return res; } -int _PyCfg_JumpLabelsToTargets(basicblock *entryblock); +int _PyCfg_JumpLabelsToTargets(cfg_builder *g); PyCodeObject * _PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename, PyObject *instructions) { + cfg_builder *g = NULL; PyCodeObject *co = NULL; instr_sequence optimized_instrs; memset(&optimized_instrs, 0, sizeof(instr_sequence)); @@ -8210,37 +8022,20 @@ _PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename, return NULL; } - cfg_builder g; - if (instructions_to_cfg(instructions, &g) < 0) { + g = instructions_to_cfg(instructions); + if (g == NULL) { goto error; } - if (_PyCfg_JumpLabelsToTargets(g.g_entryblock) < 0) { + if (_PyCfg_JumpLabelsToTargets(g) < 0) { goto error; } int code_flags = 0; - int nlocalsplus = prepare_localsplus(umd, &g, code_flags); - if (nlocalsplus < 0) { - goto error; - } - - int maxdepth = _PyCfg_Stackdepth(g.g_entryblock, code_flags); - if (maxdepth < 0) { - goto error; - } - - _PyCfg_ConvertPseudoOps(g.g_entryblock); - - /* Order of basic blocks must have been determined by now */ - - if (_PyCfg_ResolveJumps(&g) < 0) { - goto error; - } - - /* Can't modify the bytecode after computing jump offsets. */ - - if (cfg_to_instr_sequence(&g, &optimized_instrs) < 0) { + int stackdepth, nlocalsplus; + if (_PyCfg_OptimizedCfgToInstructionSequence(g, umd, code_flags, + &stackdepth, &nlocalsplus, + &optimized_instrs) < 0) { goto error; } @@ -8249,13 +8044,13 @@ _PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename, goto error; } co = _PyAssemble_MakeCodeObject(umd, const_cache, - consts, maxdepth, &optimized_instrs, + consts, stackdepth, &optimized_instrs, nlocalsplus, code_flags, filename); Py_DECREF(consts); error: Py_DECREF(const_cache); - _PyCfgBuilder_Fini(&g); + _PyCfgBuilder_Free(g); instr_sequence_fini(&optimized_instrs); return co; } diff --git a/Python/condvar.h b/Python/condvar.h index 4ddc5311cf8fad..d54db94f2c871d 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -41,7 +41,8 @@ #define _CONDVAR_IMPL_H_ #include "Python.h" -#include "pycore_condvar.h" +#include "pycore_pythread.h" // _POSIX_THREADS + #ifdef _POSIX_THREADS /* diff --git a/Python/context.c b/Python/context.c index 1ffae9871be7b3..c94c014219d0e4 100644 --- a/Python/context.c +++ b/Python/context.c @@ -7,7 +7,7 @@ #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() -#include "structmember.h" // PyMemberDef + #include "clinic/context.c.h" @@ -1042,7 +1042,7 @@ _contextvars_ContextVar_reset(PyContextVar *self, PyObject *token) static PyMemberDef PyContextVar_members[] = { - {"name", T_OBJECT, offsetof(PyContextVar, var_name), READONLY}, + {"name", _Py_T_OBJECT, offsetof(PyContextVar, var_name), Py_READONLY}, {NULL} }; @@ -1267,7 +1267,7 @@ PyTypeObject _PyContextTokenMissing_Type = { static PyObject * get_token_missing(void) { - return Py_NewRef(&_Py_SINGLETON(context_token_missing)); + return (PyObject *)&_Py_SINGLETON(context_token_missing); } diff --git a/Python/dtoa.c b/Python/dtoa.c index c5e343b82f74c5..5dfc0e179cbc34 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -172,10 +172,6 @@ typedef uint64_t ULLong; #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef union { double d; ULong L[2]; } U; #ifdef IEEE_8087 @@ -2813,8 +2809,5 @@ _Py_dg_dtoa(double dd, int mode, int ndigits, _Py_dg_freedtoa(s0); return NULL; } -#ifdef __cplusplus -} -#endif #endif // _PY_SHORT_FLOAT_REPR == 1 diff --git a/Python/dup2.c b/Python/dup2.c index a1df0492099163..936211f27ec737 100644 --- a/Python/dup2.c +++ b/Python/dup2.c @@ -11,9 +11,9 @@ * Return fd2 if all went well; return BADEXIT otherwise. */ -#include -#include -#include +#include // errno +#include // fcntl() +#include // close() #define BADEXIT -1 diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c index a53373038ed859..1c44722ff9a2d0 100644 --- a/Python/dynload_hpux.c +++ b/Python/dynload_hpux.c @@ -5,7 +5,7 @@ #include #include "Python.h" -#include "importdl.h" +#include "pycore_importdl.h" #if defined(__hp9000s300) #define FUNCNAME_PATTERN "_%.20s_%.200s" diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 6761bba457983b..5a37a83805ba78 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -4,7 +4,7 @@ #include "Python.h" #include "pycore_interp.h" // _PyInterpreterState.dlopenflags #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "importdl.h" +#include "pycore_importdl.h" #include #include diff --git a/Python/dynload_stub.c b/Python/dynload_stub.c index 59160483caa448..11f7e5f643f79e 100644 --- a/Python/dynload_stub.c +++ b/Python/dynload_stub.c @@ -3,7 +3,7 @@ not present. */ #include "Python.h" -#include "importdl.h" +#include "pycore_importdl.h" const char *_PyImport_DynLoadFiletab[] = {NULL}; diff --git a/Python/dynload_win.c b/Python/dynload_win.c index acab05e2c6def3..a0ac31c80a5f6e 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -5,29 +5,10 @@ #include "pycore_fileutils.h" // _Py_add_relfile() #include "pycore_pystate.h" // _PyInterpreterState_GET() -#ifdef HAVE_DIRECT_H -#include -#endif -#include - -#include "importdl.h" -#include "patchlevel.h" +#include "pycore_importdl.h" // dl_funcptr +#include "patchlevel.h" // PY_MAJOR_VERSION #include -#ifdef _DEBUG -#define PYD_DEBUG_SUFFIX "_d" -#else -#define PYD_DEBUG_SUFFIX "" -#endif - -#ifdef PYD_PLATFORM_TAG -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" -#else -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) ".pyd" -#endif - -#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" - const char *_PyImport_DynLoadFiletab[] = { PYD_TAGGED_SUFFIX, PYD_UNTAGGED_SUFFIX, diff --git a/Python/emscripten_signal.c b/Python/emscripten_signal.c index d617ddfeb37c5a..561b5b73cd6b70 100644 --- a/Python/emscripten_signal.c +++ b/Python/emscripten_signal.c @@ -38,19 +38,17 @@ _Py_CheckEmscriptenSignals(void) } } - #define PY_EMSCRIPTEN_SIGNAL_INTERVAL 50 -static int emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; +int _Py_emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; void _Py_CheckEmscriptenSignalsPeriodically(void) { - if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) { - return; - } - emscripten_signal_clock--; - if (emscripten_signal_clock == 0) { - emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; + if (_Py_emscripten_signal_clock == 0) { + _Py_emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; _Py_CheckEmscriptenSignals(); } + else if (Py_EMSCRIPTEN_SIGNAL_HANDLING) { + _Py_emscripten_signal_clock--; + } } diff --git a/Python/emscripten_trampoline.c b/Python/emscripten_trampoline.c new file mode 100644 index 00000000000000..2a80ec4f18d757 --- /dev/null +++ b/Python/emscripten_trampoline.c @@ -0,0 +1,82 @@ +#if defined(PY_CALL_TRAMPOLINE) + +#include // EM_JS +#include +#include "pycore_runtime.h" // _PyRuntime + + +/** + * This is the GoogleChromeLabs approved way to feature detect type-reflection: + * https://github.com/GoogleChromeLabs/wasm-feature-detect/blob/main/src/detectors/type-reflection/index.js + */ +EM_JS(int, _PyEM_detect_type_reflection, (), { + return "Function" in WebAssembly; +}); + +void +_Py_EmscriptenTrampoline_Init(_PyRuntimeState *runtime) +{ + runtime->wasm_type_reflection_available = _PyEM_detect_type_reflection(); +} + +/** + * Backwards compatible trampoline works with all JS runtimes + */ +EM_JS(PyObject*, +_PyEM_TrampolineCall_JavaScript, (PyCFunctionWithKeywords func, + PyObject *arg1, + PyObject *arg2, + PyObject *arg3), +{ + return wasmTable.get(func)(arg1, arg2, arg3); +} +); + +/** + * In runtimes with WebAssembly type reflection, count the number of parameters + * and cast to the appropriate signature + */ +EM_JS(int, _PyEM_CountFuncParams, (PyCFunctionWithKeywords func), +{ + let n = _PyEM_CountFuncParams.cache.get(func); + + if (n !== undefined) { + return n; + } + n = WebAssembly.Function.type(wasmTable.get(func)).parameters.length; + _PyEM_CountFuncParams.cache.set(func, n); + return n; +} +_PyEM_CountFuncParams.cache = new Map(); +) + + +typedef PyObject* (*zero_arg)(void); +typedef PyObject* (*one_arg)(PyObject*); +typedef PyObject* (*two_arg)(PyObject*, PyObject*); +typedef PyObject* (*three_arg)(PyObject*, PyObject*, PyObject*); + + +PyObject* +_PyEM_TrampolineCall_Reflection(PyCFunctionWithKeywords func, + PyObject* self, + PyObject* args, + PyObject* kw) +{ + switch (_PyEM_CountFuncParams(func)) { + case 0: + return ((zero_arg)func)(); + case 1: + return ((one_arg)func)(self); + case 2: + return ((two_arg)func)(self, args); + case 3: + return ((three_arg)func)(self, args, kw); + default: + PyErr_SetString(PyExc_SystemError, + "Handler takes too many arguments"); + return NULL; + } +} + +#endif diff --git a/Python/errors.c b/Python/errors.c index 916958c9a0ab00..15af39b10dc07e 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -10,18 +10,12 @@ #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_traceback.h" // _PyTraceBack_FromFrame() -#include #ifdef MS_WINDOWS # include # include # include // _sys_nerr #endif - -#ifdef __cplusplus -extern "C" { -#endif - /* Forward declarations */ static PyObject * _PyErr_FormatV(PyThreadState *tstate, PyObject *exception, @@ -292,8 +286,10 @@ _PyErr_SetString(PyThreadState *tstate, PyObject *exception, const char *string) { PyObject *value = PyUnicode_FromString(string); - _PyErr_SetObject(tstate, exception, value); - Py_XDECREF(value); + if (value != NULL) { + _PyErr_SetObject(tstate, exception, value); + Py_DECREF(value); + } } void @@ -891,7 +887,15 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P PyObject * PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + int i = errno; + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + errno = i; + } PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; @@ -988,7 +992,16 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename( int ierr, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + if ((DWORD)ierr == 0) { + ierr = (int)GetLastError(); + } + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + } PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, name, @@ -1012,7 +1025,16 @@ PyObject *PyErr_SetFromWindowsErrWithFilename( int ierr, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + if ((DWORD)ierr == 0) { + ierr = (int)GetLastError(); + } + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + } PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, ierr, name, NULL); @@ -1137,9 +1159,10 @@ _PyErr_FormatV(PyThreadState *tstate, PyObject *exception, _PyErr_Clear(tstate); string = PyUnicode_FromFormatV(format, vargs); - - _PyErr_SetObject(tstate, exception, string); - Py_XDECREF(string); + if (string != NULL) { + _PyErr_SetObject(tstate, exception, string); + Py_DECREF(string); + } return NULL; } @@ -1485,11 +1508,9 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, } /* Explicitly call file.flush() */ - PyObject *res = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); - if (!res) { + if (_PyFile_Flush(file) < 0) { return -1; } - Py_DECREF(res); return 0; } @@ -1748,13 +1769,11 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, } } if ((PyObject *)Py_TYPE(exc) != PyExc_SyntaxError) { - if (PyObject_GetOptionalAttr(exc, &_Py_ID(msg), &tmp) < 0) { + int rc = PyObject_HasAttrWithError(exc, &_Py_ID(msg)); + if (rc < 0) { _PyErr_Clear(tstate); } - else if (tmp) { - Py_DECREF(tmp); - } - else { + else if (!rc) { tmp = PyObject_Str(exc); if (tmp) { if (PyObject_SetAttr(exc, &_Py_ID(msg), tmp)) { @@ -1767,13 +1786,11 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, } } - if (PyObject_GetOptionalAttr(exc, &_Py_ID(print_file_and_line), &tmp) < 0) { + rc = PyObject_HasAttrWithError(exc, &_Py_ID(print_file_and_line)); + if (rc < 0) { _PyErr_Clear(tstate); } - else if (tmp) { - Py_DECREF(tmp); - } - else { + else if (!rc) { if (PyObject_SetAttr(exc, &_Py_ID(print_file_and_line), Py_None)) { _PyErr_Clear(tstate); } @@ -1896,7 +1913,3 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno) { return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL); } - -#ifdef __cplusplus -} -#endif diff --git a/Python/executor.c b/Python/executor.c new file mode 100644 index 00000000000000..1630f018626449 --- /dev/null +++ b/Python/executor.c @@ -0,0 +1,147 @@ +#include "Python.h" + +#include "opcode.h" + +#include "pycore_bitutils.h" +#include "pycore_call.h" +#include "pycore_ceval.h" +#include "pycore_dict.h" +#include "pycore_emscripten_signal.h" +#include "pycore_intrinsics.h" +#include "pycore_long.h" +#include "pycore_object.h" +#include "pycore_opcode_metadata.h" +#include "pycore_opcode_utils.h" +#include "pycore_pyerrors.h" +#include "pycore_range.h" +#include "pycore_setobject.h" // _PySet_Update() +#include "pycore_sliceobject.h" +#include "pycore_uops.h" + +#define TIER_TWO 2 +#include "ceval_macros.h" + + +#undef DEOPT_IF +#define DEOPT_IF(COND, INSTNAME) \ + if ((COND)) { \ + goto deoptimize; \ + } + +#ifdef Py_STATS +// Disable these macros that apply to Tier 1 stats when we are in Tier 2 +#undef STAT_INC +#define STAT_INC(opname, name) ((void)0) +#undef STAT_DEC +#define STAT_DEC(opname, name) ((void)0) +#undef CALL_STAT_INC +#define CALL_STAT_INC(name) ((void)0) +#endif + +#undef ENABLE_SPECIALIZATION +#define ENABLE_SPECIALIZATION 0 + + +_PyInterpreterFrame * +_PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject **stack_pointer) +{ +#ifdef Py_DEBUG + char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG"); + int lltrace = 0; + if (uop_debug != NULL && *uop_debug >= '0') { + lltrace = *uop_debug - '0'; // TODO: Parse an int and all that + } + #define DPRINTF(level, ...) \ + if (lltrace >= (level)) { printf(__VA_ARGS__); } +#else + #define DPRINTF(level, ...) +#endif + + DPRINTF(3, + "Entering _PyUopExecute for %s (%s:%d) at byte offset %ld\n", + PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_qualname), + PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_filename), + _PyFrame_GetCode(frame)->co_firstlineno, + 2 * (long)(frame->prev_instr + 1 - + (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive)); + + PyThreadState *tstate = _PyThreadState_GET(); + _PyUOpExecutorObject *self = (_PyUOpExecutorObject *)executor; + + CHECK_EVAL_BREAKER(); + + OPT_STAT_INC(traces_executed); + _Py_CODEUNIT *ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; + int pc = 0; + int opcode; + int oparg; + uint64_t operand; +#ifdef Py_STATS + uint64_t trace_uop_execution_counter = 0; +#endif + + for (;;) { + opcode = self->trace[pc].opcode; + oparg = self->trace[pc].oparg; + operand = self->trace[pc].operand; + DPRINTF(3, + "%4d: uop %s, oparg %d, operand %" PRIu64 ", stack_level %d\n", + pc, + opcode < 256 ? _PyOpcode_OpName[opcode] : _PyOpcode_uop_name[opcode], + oparg, + operand, + (int)(stack_pointer - _PyFrame_Stackbase(frame))); + pc++; + OPT_STAT_INC(uops_executed); + UOP_EXE_INC(opcode); +#ifdef Py_STATS + trace_uop_execution_counter++; +#endif + + switch (opcode) { + +#include "executor_cases.c.h" + + default: + { + fprintf(stderr, "Unknown uop %d, operand %" PRIu64 "\n", opcode, operand); + Py_FatalError("Unknown uop"); + } + + } + } + +unbound_local_error: + _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, + PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) + ); + goto error; + +pop_4_error: + STACK_SHRINK(1); +pop_3_error: + STACK_SHRINK(1); +pop_2_error: + STACK_SHRINK(1); +pop_1_error: + STACK_SHRINK(1); +error: + // On ERROR_IF we return NULL as the frame. + // The caller recovers the frame from tstate->current_frame. + DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand); + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(self); + return NULL; + +deoptimize: + // On DEOPT_IF we just repeat the last instruction. + // This presumes nothing was popped from the stack (nor pushed). + DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand); + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); + frame->prev_instr--; // Back up to just before destination + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(self); + return frame; +} diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index e1f8b9f208c76d..119e77b9369b13 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -7,6 +7,18 @@ break; } + case RESUME_CHECK: { +#if defined(__EMSCRIPTEN__) + DEOPT_IF(_Py_emscripten_signal_clock == 0, RESUME); + _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; +#endif + uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker); + uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + assert((version & _PY_EVAL_EVENTS_MASK) == 0); + DEOPT_IF(eval_breaker != version, RESUME); + break; + } + case LOAD_FAST_CHECK: { PyObject *value; value = GETLOCAL(oparg); @@ -47,14 +59,16 @@ } case STORE_FAST: { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; SETLOCAL(oparg, value); STACK_SHRINK(1); break; } case POP_TOP: { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; Py_DECREF(value); STACK_SHRINK(1); break; @@ -69,8 +83,10 @@ } case END_SEND: { - PyObject *value = stack_pointer[-1]; - PyObject *receiver = stack_pointer[-2]; + PyObject *value; + PyObject *receiver; + value = stack_pointer[-1]; + receiver = stack_pointer[-2]; Py_DECREF(receiver); STACK_SHRINK(1); stack_pointer[-1] = value; @@ -78,8 +94,9 @@ } case UNARY_NEGATIVE: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; res = PyNumber_Negative(value); Py_DECREF(value); if (res == NULL) goto pop_1_error; @@ -88,8 +105,9 @@ } case UNARY_NOT: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; assert(PyBool_Check(value)); res = Py_IsFalse(value) ? Py_True : Py_False; stack_pointer[-1] = res; @@ -97,9 +115,9 @@ } case TO_BOOL: { - static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; #if ENABLE_SPECIALIZATION _PyToBoolCache *cache = (_PyToBoolCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -119,15 +137,17 @@ } case TO_BOOL_BOOL: { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; DEOPT_IF(!PyBool_Check(value), TO_BOOL); STAT_INC(TO_BOOL, hit); break; } case TO_BOOL_INT: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; DEOPT_IF(!PyLong_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); if (_PyLong_IsZero((PyLongObject *)value)) { @@ -143,8 +163,9 @@ } case TO_BOOL_LIST: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; DEOPT_IF(!PyList_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); res = Py_SIZE(value) ? Py_True : Py_False; @@ -154,8 +175,9 @@ } case TO_BOOL_NONE: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; // This one is a bit weird, because we expect *some* failures: DEOPT_IF(!Py_IsNone(value), TO_BOOL); STAT_INC(TO_BOOL, hit); @@ -165,8 +187,9 @@ } case TO_BOOL_STR: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; DEOPT_IF(!PyUnicode_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); if (value == &_Py_STR(empty)) { @@ -183,8 +206,9 @@ } case TO_BOOL_ALWAYS_TRUE: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; uint32_t version = (uint32_t)operand; // This one is a bit weird, because we expect *some* failures: assert(version); @@ -197,8 +221,9 @@ } case UNARY_INVERT: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; res = PyNumber_Invert(value); Py_DECREF(value); if (res == NULL) goto pop_1_error; @@ -207,17 +232,21 @@ } case _GUARD_BOTH_INT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + PyObject *right; + PyObject *left; + right = stack_pointer[-1]; + left = stack_pointer[-2]; + DEOPT_IF(!PyLong_CheckExact(left), _GUARD_BOTH_INT); + DEOPT_IF(!PyLong_CheckExact(right), _GUARD_BOTH_INT); break; } case _BINARY_OP_MULTIPLY_INT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); res = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); @@ -229,9 +258,11 @@ } case _BINARY_OP_ADD_INT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); res = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); @@ -243,9 +274,11 @@ } case _BINARY_OP_SUBTRACT_INT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); res = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); @@ -257,17 +290,21 @@ } case _GUARD_BOTH_FLOAT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + PyObject *right; + PyObject *left; + right = stack_pointer[-1]; + left = stack_pointer[-2]; + DEOPT_IF(!PyFloat_CheckExact(left), _GUARD_BOTH_FLOAT); + DEOPT_IF(!PyFloat_CheckExact(right), _GUARD_BOTH_FLOAT); break; } case _BINARY_OP_MULTIPLY_FLOAT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); double dres = ((PyFloatObject *)left)->ob_fval * @@ -279,9 +316,11 @@ } case _BINARY_OP_ADD_FLOAT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); double dres = ((PyFloatObject *)left)->ob_fval + @@ -293,9 +332,11 @@ } case _BINARY_OP_SUBTRACT_FLOAT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); double dres = ((PyFloatObject *)left)->ob_fval - @@ -307,17 +348,21 @@ } case _GUARD_BOTH_UNICODE: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); + PyObject *right; + PyObject *left; + right = stack_pointer[-1]; + left = stack_pointer[-2]; + DEOPT_IF(!PyUnicode_CheckExact(left), _GUARD_BOTH_UNICODE); + DEOPT_IF(!PyUnicode_CheckExact(right), _GUARD_BOTH_UNICODE); break; } case _BINARY_OP_ADD_UNICODE: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); res = PyUnicode_Concat(left, right); _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); @@ -329,10 +374,11 @@ } case BINARY_SUBSCR: { - static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); - PyObject *sub = stack_pointer[-1]; - PyObject *container = stack_pointer[-2]; + PyObject *sub; + PyObject *container; PyObject *res; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -353,10 +399,13 @@ } case BINARY_SLICE: { - PyObject *stop = stack_pointer[-1]; - PyObject *start = stack_pointer[-2]; - PyObject *container = stack_pointer[-3]; + PyObject *stop; + PyObject *start; + PyObject *container; PyObject *res; + stop = stack_pointer[-1]; + start = stack_pointer[-2]; + container = stack_pointer[-3]; PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); // Can't use ERROR_IF() here, because we haven't // DECREF'ed container yet, and we still own slice. @@ -375,10 +424,14 @@ } case STORE_SLICE: { - PyObject *stop = stack_pointer[-1]; - PyObject *start = stack_pointer[-2]; - PyObject *container = stack_pointer[-3]; - PyObject *v = stack_pointer[-4]; + PyObject *stop; + PyObject *start; + PyObject *container; + PyObject *v; + stop = stack_pointer[-1]; + start = stack_pointer[-2]; + container = stack_pointer[-3]; + v = stack_pointer[-4]; PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); int err; if (slice == NULL) { @@ -396,9 +449,11 @@ } case BINARY_SUBSCR_LIST_INT: { - PyObject *sub = stack_pointer[-1]; - PyObject *list = stack_pointer[-2]; + PyObject *sub; + PyObject *list; PyObject *res; + sub = stack_pointer[-1]; + list = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); @@ -417,10 +472,35 @@ break; } + case BINARY_SUBSCR_STR_INT: { + PyObject *sub; + PyObject *str; + PyObject *res; + sub = stack_pointer[-1]; + str = stack_pointer[-2]; + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyUnicode_CheckExact(str), BINARY_SUBSCR); + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index, BINARY_SUBSCR); + // Specialize for reading an ASCII character from any string: + Py_UCS4 c = PyUnicode_READ_CHAR(str, index); + DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c, BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = (PyObject*)&_Py_SINGLETON(strings).ascii[c]; + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(str); + STACK_SHRINK(1); + stack_pointer[-1] = res; + break; + } + case BINARY_SUBSCR_TUPLE_INT: { - PyObject *sub = stack_pointer[-1]; - PyObject *tuple = stack_pointer[-2]; + PyObject *sub; + PyObject *tuple; PyObject *res; + sub = stack_pointer[-1]; + tuple = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); @@ -440,9 +520,11 @@ } case BINARY_SUBSCR_DICT: { - PyObject *sub = stack_pointer[-1]; - PyObject *dict = stack_pointer[-2]; + PyObject *sub; + PyObject *dict; PyObject *res; + sub = stack_pointer[-1]; + dict = stack_pointer[-2]; DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); res = PyDict_GetItemWithError(dict, sub); @@ -463,16 +545,20 @@ } case LIST_APPEND: { - PyObject *v = stack_pointer[-1]; - PyObject *list = stack_pointer[-(2 + (oparg-1))]; + PyObject *v; + PyObject *list; + v = stack_pointer[-1]; + list = stack_pointer[-2 - (oparg-1)]; if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error; STACK_SHRINK(1); break; } case SET_ADD: { - PyObject *v = stack_pointer[-1]; - PyObject *set = stack_pointer[-(2 + (oparg-1))]; + PyObject *v; + PyObject *set; + v = stack_pointer[-1]; + set = stack_pointer[-2 - (oparg-1)]; int err = PySet_Add(set, v); Py_DECREF(v); if (err) goto pop_1_error; @@ -481,10 +567,12 @@ } case STORE_SUBSCR: { - static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size"); - PyObject *sub = stack_pointer[-1]; - PyObject *container = stack_pointer[-2]; - PyObject *v = stack_pointer[-3]; + PyObject *sub; + PyObject *container; + PyObject *v; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; + v = stack_pointer[-3]; #if ENABLE_SPECIALIZATION _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -506,9 +594,12 @@ } case STORE_SUBSCR_LIST_INT: { - PyObject *sub = stack_pointer[-1]; - PyObject *list = stack_pointer[-2]; - PyObject *value = stack_pointer[-3]; + PyObject *sub; + PyObject *list; + PyObject *value; + sub = stack_pointer[-1]; + list = stack_pointer[-2]; + value = stack_pointer[-3]; DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); @@ -530,9 +621,12 @@ } case STORE_SUBSCR_DICT: { - PyObject *sub = stack_pointer[-1]; - PyObject *dict = stack_pointer[-2]; - PyObject *value = stack_pointer[-3]; + PyObject *sub; + PyObject *dict; + PyObject *value; + sub = stack_pointer[-1]; + dict = stack_pointer[-2]; + value = stack_pointer[-3]; DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); STAT_INC(STORE_SUBSCR, hit); int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); @@ -543,8 +637,10 @@ } case DELETE_SUBSCR: { - PyObject *sub = stack_pointer[-1]; - PyObject *container = stack_pointer[-2]; + PyObject *sub; + PyObject *container; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; /* del container[sub] */ int err = PyObject_DelItem(container, sub); Py_DECREF(container); @@ -555,10 +651,11 @@ } case CALL_INTRINSIC_1: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; assert(oparg <= MAX_INTRINSIC_1); - res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); + res = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, value); Py_DECREF(value); if (res == NULL) goto pop_1_error; stack_pointer[-1] = res; @@ -566,11 +663,13 @@ } case CALL_INTRINSIC_2: { - PyObject *value1 = stack_pointer[-1]; - PyObject *value2 = stack_pointer[-2]; + PyObject *value1; + PyObject *value2; PyObject *res; + value1 = stack_pointer[-1]; + value2 = stack_pointer[-2]; assert(oparg <= MAX_INTRINSIC_2); - res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1); + res = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1); Py_DECREF(value2); Py_DECREF(value1); if (res == NULL) goto pop_2_error; @@ -579,9 +678,37 @@ break; } + case _POP_FRAME: { + PyObject *retval; + retval = stack_pointer[-1]; + STACK_SHRINK(1); + assert(EMPTY()); + #if TIER_ONE + assert(frame != &entry_frame); + #endif + STORE_SP(); + _Py_LeaveRecursiveCallPy(tstate); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + LOAD_SP(); + LOAD_IP(); +#if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } +#endif + break; + } + case GET_AITER: { - PyObject *obj = stack_pointer[-1]; + PyObject *obj; PyObject *iter; + obj = stack_pointer[-1]; unaryfunc getter = NULL; PyTypeObject *type = Py_TYPE(obj); @@ -617,8 +744,9 @@ } case GET_ANEXT: { - PyObject *aiter = stack_pointer[-1]; + PyObject *aiter; PyObject *awaitable; + aiter = stack_pointer[-1]; unaryfunc getter = NULL; PyObject *next_iter = NULL; PyTypeObject *type = Py_TYPE(aiter); @@ -667,12 +795,13 @@ } case GET_AWAITABLE: { - PyObject *iterable = stack_pointer[-1]; + PyObject *iterable; PyObject *iter; + iterable = stack_pointer[-1]; iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { - format_awaitable_error(tstate, Py_TYPE(iterable), oparg); + _PyEval_FormatAwaitableError(tstate, Py_TYPE(iterable), oparg); } Py_DECREF(iterable); @@ -697,7 +826,8 @@ } case POP_EXCEPT: { - PyObject *exc_value = stack_pointer[-1]; + PyObject *exc_value; + exc_value = stack_pointer[-1]; _PyErr_StackItem *exc_info = tstate->exc_info; Py_XSETREF(exc_info->exc_value, exc_value); STACK_SHRINK(1); @@ -726,7 +856,8 @@ } case STORE_NAME: { - PyObject *v = stack_pointer[-1]; + PyObject *v; + v = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *ns = LOCALS(); int err; @@ -758,17 +889,17 @@ err = PyObject_DelItem(ns, name); // Can't use ERROR_IF here. if (err != 0) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); goto error; } break; } case UNPACK_SEQUENCE: { - static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); - PyObject *seq = stack_pointer[-1]; + PyObject *seq; + seq = stack_pointer[-1]; #if ENABLE_SPECIALIZATION _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -780,7 +911,7 @@ DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; - int res = unpack_iterable(tstate, seq, oparg, -1, top); + int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top); Py_DECREF(seq); if (res == 0) goto pop_1_error; STACK_SHRINK(1); @@ -789,8 +920,10 @@ } case UNPACK_SEQUENCE_TWO_TUPLE: { - PyObject *seq = stack_pointer[-1]; - PyObject **values = stack_pointer - (1); + PyObject *seq; + PyObject **values; + seq = stack_pointer[-1]; + values = stack_pointer - 1; DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); assert(oparg == 2); @@ -804,8 +937,10 @@ } case UNPACK_SEQUENCE_TUPLE: { - PyObject *seq = stack_pointer[-1]; - PyObject **values = stack_pointer - (1); + PyObject *seq; + PyObject **values; + seq = stack_pointer[-1]; + values = stack_pointer - 1; DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -820,8 +955,10 @@ } case UNPACK_SEQUENCE_LIST: { - PyObject *seq = stack_pointer[-1]; - PyObject **values = stack_pointer - (1); + PyObject *seq; + PyObject **values; + seq = stack_pointer[-1]; + values = stack_pointer - 1; DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -836,10 +973,11 @@ } case UNPACK_EX: { - PyObject *seq = stack_pointer[-1]; + PyObject *seq; + seq = stack_pointer[-1]; int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; - int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); + int res = _PyEval_UnpackIterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); Py_DECREF(seq); if (res == 0) goto pop_1_error; STACK_GROW((oparg & 0xFF) + (oparg >> 8)); @@ -847,9 +985,10 @@ } case STORE_ATTR: { - static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); - PyObject *owner = stack_pointer[-1]; - PyObject *v = stack_pointer[-2]; + PyObject *owner; + PyObject *v; + owner = stack_pointer[-1]; + v = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -871,7 +1010,8 @@ } case DELETE_ATTR: { - PyObject *owner = stack_pointer[-1]; + PyObject *owner; + owner = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyObject_DelAttr(owner, name); Py_DECREF(owner); @@ -881,7 +1021,8 @@ } case STORE_GLOBAL: { - PyObject *v = stack_pointer[-1]; + PyObject *v; + v = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyDict_SetItem(GLOBALS(), name, v); Py_DECREF(v); @@ -897,15 +1038,15 @@ // Can't use ERROR_IF here. if (err != 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } goto error; } break; } - case _LOAD_LOCALS: { + case LOAD_LOCALS: { PyObject *locals; locals = LOCALS(); if (locals == NULL) { @@ -919,15 +1060,51 @@ break; } - case _LOAD_FROM_DICT_OR_GLOBALS: { - PyObject *mod_or_class_dict = stack_pointer[-1]; + case LOAD_FROM_DICT_OR_GLOBALS: { + PyObject *mod_or_class_dict; PyObject *v; + mod_or_class_dict = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { - Py_DECREF(mod_or_class_dict); goto error; } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { + goto error; + } + if (v == NULL) { + _PyEval_FormatExcCheckArg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + goto error; + } + } + } Py_DECREF(mod_or_class_dict); + stack_pointer[-1] = v; + break; + } + + case LOAD_NAME: { + PyObject *v; + PyObject *mod_or_class_dict = LOCALS(); + if (mod_or_class_dict == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; + } + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { + goto error; + } if (v == NULL) { v = PyDict_GetItemWithError(GLOBALS(), name); if (v != NULL) { @@ -941,21 +1118,21 @@ goto error; } if (v == NULL) { - format_exc_check_arg( + _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); goto error; } } } + STACK_GROW(1); stack_pointer[-1] = v; break; } case LOAD_GLOBAL: { - static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); + PyObject *res; PyObject *null = NULL; - PyObject *v; #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -971,30 +1148,30 @@ if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) { - v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), - (PyDictObject *)BUILTINS(), - name); - if (v == NULL) { + res = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), + (PyDictObject *)BUILTINS(), + name); + if (res == NULL) { if (!_PyErr_Occurred(tstate)) { /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } if (true) goto error; } - Py_INCREF(v); + Py_INCREF(res); } else { /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ - if (PyMapping_GetOptionalItem(GLOBALS(), name, &v) < 0) goto error; - if (v == NULL) { + if (PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0) goto error; + if (res == NULL) { /* namespace 2: builtins */ - if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) goto error; - if (v == NULL) { - format_exc_check_arg( + if (PyMapping_GetOptionalItem(BUILTINS(), name, &res) < 0) goto error; + if (res == NULL) { + _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); if (true) goto error; @@ -1004,20 +1181,16 @@ null = NULL; STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = v; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; } - break; - } - - case _SKIP_CACHE: { + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } break; } case _GUARD_GLOBALS_VERSION: { uint16_t version = (uint16_t)operand; PyDictObject *dict = (PyDictObject *)GLOBALS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(dict), _GUARD_GLOBALS_VERSION); + DEOPT_IF(dict->ma_keys->dk_version != version, _GUARD_GLOBALS_VERSION); assert(DK_IS_UNICODE(dict->ma_keys)); break; } @@ -1025,45 +1198,45 @@ case _GUARD_BUILTINS_VERSION: { uint16_t version = (uint16_t)operand; PyDictObject *dict = (PyDictObject *)BUILTINS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(dict), _GUARD_BUILTINS_VERSION); + DEOPT_IF(dict->ma_keys->dk_version != version, _GUARD_BUILTINS_VERSION); assert(DK_IS_UNICODE(dict->ma_keys)); break; } case _LOAD_GLOBAL_MODULE: { - PyObject *null = NULL; PyObject *res; + PyObject *null = NULL; uint16_t index = (uint16_t)operand; PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); + DEOPT_IF(res == NULL, _LOAD_GLOBAL_MODULE); Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } break; } case _LOAD_GLOBAL_BUILTINS: { - PyObject *null = NULL; PyObject *res; + PyObject *null = NULL; uint16_t index = (uint16_t)operand; PyDictObject *bdict = (PyDictObject *)BUILTINS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); + DEOPT_IF(res == NULL, _LOAD_GLOBAL_BUILTINS); Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } break; } @@ -1080,7 +1253,7 @@ // Can't use ERROR_IF here. // Fortunately we don't need its superpower. if (oldobj == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); goto error; } PyCell_SET(cell, NULL); @@ -1089,8 +1262,9 @@ } case LOAD_FROM_DICT_OR_DEREF: { - PyObject *class_dict = stack_pointer[-1]; + PyObject *class_dict; PyObject *value; + class_dict = stack_pointer[-1]; PyObject *name; assert(class_dict); assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); @@ -1104,7 +1278,7 @@ PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); goto error; } Py_INCREF(value); @@ -1118,7 +1292,7 @@ PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); if (true) goto error; } Py_INCREF(value); @@ -1128,7 +1302,8 @@ } case STORE_DEREF: { - PyObject *v = stack_pointer[-1]; + PyObject *v; + v = stack_pointer[-1]; PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); PyCell_SET(cell, v); @@ -1152,8 +1327,9 @@ } case BUILD_STRING: { - PyObject **pieces = (stack_pointer - oparg); + PyObject **pieces; PyObject *str; + pieces = stack_pointer - oparg; str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); for (int _i = oparg; --_i >= 0;) { Py_DECREF(pieces[_i]); @@ -1166,8 +1342,9 @@ } case BUILD_TUPLE: { - PyObject **values = (stack_pointer - oparg); + PyObject **values; PyObject *tup; + values = stack_pointer - oparg; tup = _PyTuple_FromArraySteal(values, oparg); if (tup == NULL) { STACK_SHRINK(oparg); goto error; } STACK_SHRINK(oparg); @@ -1177,8 +1354,9 @@ } case BUILD_LIST: { - PyObject **values = (stack_pointer - oparg); + PyObject **values; PyObject *list; + values = stack_pointer - oparg; list = _PyList_FromArraySteal(values, oparg); if (list == NULL) { STACK_SHRINK(oparg); goto error; } STACK_SHRINK(oparg); @@ -1188,8 +1366,10 @@ } case LIST_EXTEND: { - PyObject *iterable = stack_pointer[-1]; - PyObject *list = stack_pointer[-(2 + (oparg-1))]; + PyObject *iterable; + PyObject *list; + iterable = stack_pointer[-1]; + list = stack_pointer[-2 - (oparg-1)]; PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && @@ -1210,8 +1390,10 @@ } case SET_UPDATE: { - PyObject *iterable = stack_pointer[-1]; - PyObject *set = stack_pointer[-(2 + (oparg-1))]; + PyObject *iterable; + PyObject *set; + iterable = stack_pointer[-1]; + set = stack_pointer[-2 - (oparg-1)]; int err = _PySet_Update(set, iterable); Py_DECREF(iterable); if (err < 0) goto pop_1_error; @@ -1220,8 +1402,9 @@ } case BUILD_SET: { - PyObject **values = (stack_pointer - oparg); + PyObject **values; PyObject *set; + values = stack_pointer - oparg; set = PySet_New(NULL); if (set == NULL) goto error; @@ -1243,15 +1426,13 @@ } case BUILD_MAP: { - PyObject **values = (stack_pointer - oparg*2); + PyObject **values; PyObject *map; + values = stack_pointer - oparg*2; map = _PyDict_FromItems( values, 2, values+1, 2, oparg); - if (map == NULL) - goto error; - for (int _i = oparg*2; --_i >= 0;) { Py_DECREF(values[_i]); } @@ -1304,9 +1485,11 @@ } case BUILD_CONST_KEY_MAP: { - PyObject *keys = stack_pointer[-1]; - PyObject **values = (stack_pointer - (1 + oparg)); + PyObject *keys; + PyObject **values; PyObject *map; + keys = stack_pointer[-1]; + values = stack_pointer - 1 - oparg; if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -1327,8 +1510,10 @@ } case DICT_UPDATE: { - PyObject *update = stack_pointer[-1]; - PyObject *dict = PEEK(oparg + 1); // update is still on the stack + PyObject *update; + PyObject *dict; + update = stack_pointer[-1]; + dict = stack_pointer[-2 - (oparg - 1)]; if (PyDict_Update(dict, update) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { _PyErr_Format(tstate, PyExc_TypeError, @@ -1344,11 +1529,14 @@ } case DICT_MERGE: { - PyObject *update = stack_pointer[-1]; - PyObject *dict = PEEK(oparg + 1); // update is still on the stack - + PyObject *update; + PyObject *dict; + PyObject *callable; + update = stack_pointer[-1]; + dict = stack_pointer[-2 - (oparg - 1)]; + callable = stack_pointer[-5 - (oparg - 1)]; if (_PyDict_MergeEx(dict, update, 2) < 0) { - format_kwargs_error(tstate, PEEK(3 + oparg), update); + _PyEval_FormatKwargsError(tstate, callable, update); Py_DECREF(update); if (true) goto pop_1_error; } @@ -1358,9 +1546,12 @@ } case MAP_ADD: { - PyObject *value = stack_pointer[-1]; - PyObject *key = stack_pointer[-2]; - PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack + PyObject *value; + PyObject *key; + PyObject *dict; + value = stack_pointer[-1]; + key = stack_pointer[-2]; + dict = stack_pointer[-3 - (oparg - 1)]; assert(PyDict_CheckExact(dict)); /* dict[key] = value */ // Do not DECREF INPUTS because the function steals the references @@ -1370,34 +1561,37 @@ } case LOAD_SUPER_ATTR_ATTR: { - PyObject *self = stack_pointer[-1]; - PyObject *class = stack_pointer[-2]; - PyObject *global_super = stack_pointer[-3]; - PyObject *res2 = NULL; - PyObject *res; + PyObject *self; + PyObject *class; + PyObject *global_super; + PyObject *attr; + self = stack_pointer[-1]; + class = stack_pointer[-2]; + global_super = stack_pointer[-3]; assert(!(oparg & 1)); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); - res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); + attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - if (res == NULL) goto pop_3_error; + if (attr == NULL) goto pop_3_error; STACK_SHRINK(2); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1] = attr; break; } case LOAD_SUPER_ATTR_METHOD: { - PyObject *self = stack_pointer[-1]; - PyObject *class = stack_pointer[-2]; - PyObject *global_super = stack_pointer[-3]; - PyObject *res2; - PyObject *res; + PyObject *self; + PyObject *class; + PyObject *global_super; + PyObject *attr; + PyObject *self_or_null; + self = stack_pointer[-1]; + class = stack_pointer[-2]; + global_super = stack_pointer[-3]; assert(oparg & 1); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); @@ -1405,32 +1599,31 @@ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); PyTypeObject *cls = (PyTypeObject *)class; int method_found = 0; - res2 = _PySuper_Lookup(cls, self, name, - cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); + attr = _PySuper_Lookup(cls, self, name, + Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); Py_DECREF(global_super); Py_DECREF(class); - if (res2 == NULL) { + if (attr == NULL) { Py_DECREF(self); if (true) goto pop_3_error; } if (method_found) { - res = self; // transfer ownership + self_or_null = self; // transfer ownership } else { Py_DECREF(self); - res = res2; - res2 = NULL; + self_or_null = NULL; } STACK_SHRINK(1); - stack_pointer[-1] = res; - stack_pointer[-2] = res2; + stack_pointer[-2] = attr; + stack_pointer[-1] = self_or_null; break; } case LOAD_ATTR: { - static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); - PyObject *owner = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; + PyObject *owner; + PyObject *attr; + PyObject *self_or_null = NULL; + owner = stack_pointer[-1]; #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1445,16 +1638,15 @@ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ - PyObject* meth = NULL; - if (_PyObject_GetMethod(owner, name, &meth)) { + attr = NULL; + if (_PyObject_GetMethod(owner, name, &attr)) { /* We can bypass temporary bound method object. meth is unbound method and obj is self. meth | self | arg1 | ... | argN */ - assert(meth != NULL); // No errors on this branch - res2 = meth; - res = owner; // Transfer ownership + assert(attr != NULL); // No errors on this branch + self_or_null = owner; // Transfer ownership } else { /* meth is not an unbound method (but a regular attr, or @@ -1465,64 +1657,236 @@ NULL | meth | arg1 | ... | argN */ Py_DECREF(owner); - if (meth == NULL) goto pop_1_error; - res2 = NULL; - res = meth; + if (attr == NULL) goto pop_1_error; + self_or_null = NULL; } } else { /* Classic, pushes one value. */ - res = PyObject_GetAttr(owner, name); + attr = PyObject_GetAttr(owner, name); Py_DECREF(owner); - if (res == NULL) goto pop_1_error; + if (attr == NULL) goto pop_1_error; } STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = self_or_null; } break; } case _GUARD_TYPE_VERSION: { - PyObject *owner = stack_pointer[-1]; + PyObject *owner; + owner = stack_pointer[-1]; uint32_t type_version = (uint32_t)operand; PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + DEOPT_IF(tp->tp_version_tag != type_version, _GUARD_TYPE_VERSION); break; } case _CHECK_MANAGED_OBJECT_HAS_VALUES: { - PyObject *owner = stack_pointer[-1]; + PyObject *owner; + owner = stack_pointer[-1]; assert(Py_TYPE(owner)->tp_dictoffset < 0); assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), _CHECK_MANAGED_OBJECT_HAS_VALUES); break; } case _LOAD_ATTR_INSTANCE_VALUE: { - PyObject *owner = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + owner = stack_pointer[-1]; uint16_t index = (uint16_t)operand; PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - res = _PyDictOrValues_GetValues(dorv)->values[index]; - DEOPT_IF(res == NULL, LOAD_ATTR); + attr = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(attr == NULL, _LOAD_ATTR_INSTANCE_VALUE); STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; + Py_INCREF(attr); + null = NULL; Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + break; + } + + case _CHECK_ATTR_MODULE: { + PyObject *owner; + owner = stack_pointer[-1]; + uint32_t type_version = (uint32_t)operand; + DEOPT_IF(!PyModule_CheckExact(owner), _CHECK_ATTR_MODULE); + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict != NULL); + DEOPT_IF(dict->ma_keys->dk_version != type_version, _CHECK_ATTR_MODULE); + break; + } + + case _LOAD_ATTR_MODULE: { + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + owner = stack_pointer[-1]; + uint16_t index = (uint16_t)operand; + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + assert(index < dict->ma_keys->dk_nentries); + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index; + attr = ep->me_value; + DEOPT_IF(attr == NULL, _LOAD_ATTR_MODULE); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + break; + } + + case _CHECK_ATTR_WITH_HINT: { + PyObject *owner; + owner = stack_pointer[-1]; + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), _CHECK_ATTR_WITH_HINT); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, _CHECK_ATTR_WITH_HINT); + assert(PyDict_CheckExact((PyObject *)dict)); + break; + } + + case _LOAD_ATTR_WITH_HINT: { + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + owner = stack_pointer[-1]; + uint16_t hint = (uint16_t)operand; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, _LOAD_ATTR_WITH_HINT); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, _LOAD_ATTR_WITH_HINT); + attr = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, _LOAD_ATTR_WITH_HINT); + attr = ep->me_value; + } + DEOPT_IF(attr == NULL, _LOAD_ATTR_WITH_HINT); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + break; + } + + case _LOAD_ATTR_SLOT: { + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + owner = stack_pointer[-1]; + uint16_t index = (uint16_t)operand; + char *addr = (char *)owner + index; + attr = *(PyObject **)addr; + DEOPT_IF(attr == NULL, _LOAD_ATTR_SLOT); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + break; + } + + case _CHECK_ATTR_CLASS: { + PyObject *owner; + owner = stack_pointer[-1]; + uint32_t type_version = (uint32_t)operand; + DEOPT_IF(!PyType_Check(owner), _CHECK_ATTR_CLASS); + assert(type_version != 0); + DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, _CHECK_ATTR_CLASS); + break; + } + + case _LOAD_ATTR_CLASS: { + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)operand; + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + attr = Py_NewRef(descr); + null = NULL; + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + break; + } + + case _GUARD_DORV_VALUES: { + PyObject *owner; + owner = stack_pointer[-1]; + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), _GUARD_DORV_VALUES); + break; + } + + case _STORE_ATTR_INSTANCE_VALUE: { + PyObject *owner; + PyObject *value; + owner = stack_pointer[-1]; + value = stack_pointer[-2]; + uint16_t index = (uint16_t)operand; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + STAT_INC(STORE_ATTR, hit); + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyObject *old_value = values->values[index]; + values->values[index] = value; + if (old_value == NULL) { + _PyDictValues_AddToInsertionOrder(values, index); + } + else { + Py_DECREF(old_value); + } + Py_DECREF(owner); + STACK_SHRINK(2); + break; + } + + case _STORE_ATTR_SLOT: { + PyObject *owner; + PyObject *value; + owner = stack_pointer[-1]; + value = stack_pointer[-2]; + uint16_t index = (uint16_t)operand; + char *addr = (char *)owner + index; + STAT_INC(STORE_ATTR, hit); + PyObject *old_value = *(PyObject **)addr; + *(PyObject **)addr = value; + Py_XDECREF(old_value); + Py_DECREF(owner); + STACK_SHRINK(2); break; } case COMPARE_OP: { - static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1550,9 +1914,11 @@ } case COMPARE_OP_FLOAT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -1570,9 +1936,11 @@ } case COMPARE_OP_INT: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); @@ -1594,9 +1962,11 @@ } case COMPARE_OP_STR: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -1615,9 +1985,11 @@ } case IS_OP: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *b; + right = stack_pointer[-1]; + left = stack_pointer[-2]; int res = Py_Is(left, right) ^ oparg; Py_DECREF(left); Py_DECREF(right); @@ -1628,9 +2000,11 @@ } case CONTAINS_OP: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *b; + right = stack_pointer[-1]; + left = stack_pointer[-2]; int res = PySequence_Contains(right, left); Py_DECREF(left); Py_DECREF(right); @@ -1642,11 +2016,13 @@ } case CHECK_EG_MATCH: { - PyObject *match_type = stack_pointer[-1]; - PyObject *exc_value = stack_pointer[-2]; + PyObject *match_type; + PyObject *exc_value; PyObject *rest; PyObject *match; - if (check_except_star_type_valid(tstate, match_type) < 0) { + match_type = stack_pointer[-1]; + exc_value = stack_pointer[-2]; + if (_PyEval_CheckExceptStarTypeValid(tstate, match_type) < 0) { Py_DECREF(exc_value); Py_DECREF(match_type); if (true) goto pop_2_error; @@ -1654,8 +2030,8 @@ match = NULL; rest = NULL; - int res = exception_group_match(exc_value, match_type, - &match, &rest); + int res = _PyEval_ExceptionGroupMatch(exc_value, match_type, + &match, &rest); Py_DECREF(exc_value); Py_DECREF(match_type); if (res < 0) goto pop_2_error; @@ -1666,17 +2042,19 @@ if (!Py_IsNone(match)) { PyErr_SetHandledException(match); } - stack_pointer[-1] = match; stack_pointer[-2] = rest; + stack_pointer[-1] = match; break; } case CHECK_EXC_MATCH: { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *b; + right = stack_pointer[-1]; + left = stack_pointer[-2]; assert(PyExceptionInstance_Check(left)); - if (check_except_type_valid(tstate, right) < 0) { + if (_PyEval_CheckExceptTypeValid(tstate, right) < 0) { Py_DECREF(right); if (true) goto pop_1_error; } @@ -1688,9 +2066,10 @@ break; } - case IS_NONE: { - PyObject *value = stack_pointer[-1]; + case _IS_NONE: { + PyObject *value; PyObject *b; + value = stack_pointer[-1]; if (Py_IsNone(value)) { b = Py_True; } @@ -1703,8 +2082,9 @@ } case GET_LEN: { - PyObject *obj = stack_pointer[-1]; + PyObject *obj; PyObject *len_o; + obj = stack_pointer[-1]; // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; @@ -1716,14 +2096,17 @@ } case MATCH_CLASS: { - PyObject *names = stack_pointer[-1]; - PyObject *type = stack_pointer[-2]; - PyObject *subject = stack_pointer[-3]; + PyObject *names; + PyObject *type; + PyObject *subject; PyObject *attrs; + names = stack_pointer[-1]; + type = stack_pointer[-2]; + subject = stack_pointer[-3]; // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); - attrs = match_class(tstate, subject, type, oparg, names); + attrs = _PyEval_MatchClass(tstate, subject, type, oparg, names); Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); @@ -1740,8 +2123,9 @@ } case MATCH_MAPPING: { - PyObject *subject = stack_pointer[-1]; + PyObject *subject; PyObject *res; + subject = stack_pointer[-1]; int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = match ? Py_True : Py_False; STACK_GROW(1); @@ -1750,8 +2134,9 @@ } case MATCH_SEQUENCE: { - PyObject *subject = stack_pointer[-1]; + PyObject *subject; PyObject *res; + subject = stack_pointer[-1]; int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = match ? Py_True : Py_False; STACK_GROW(1); @@ -1760,11 +2145,13 @@ } case MATCH_KEYS: { - PyObject *keys = stack_pointer[-1]; - PyObject *subject = stack_pointer[-2]; + PyObject *keys; + PyObject *subject; PyObject *values_or_none; + keys = stack_pointer[-1]; + subject = stack_pointer[-2]; // On successful match, PUSH(values). Otherwise, PUSH(None). - values_or_none = match_keys(tstate, subject, keys); + values_or_none = _PyEval_MatchKeys(tstate, subject, keys); if (values_or_none == NULL) goto error; STACK_GROW(1); stack_pointer[-1] = values_or_none; @@ -1772,8 +2159,9 @@ } case GET_ITER: { - PyObject *iterable = stack_pointer[-1]; + PyObject *iterable; PyObject *iter; + iterable = stack_pointer[-1]; /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); Py_DECREF(iterable); @@ -1783,8 +2171,9 @@ } case GET_YIELD_FROM_ITER: { - PyObject *iterable = stack_pointer[-1]; + PyObject *iterable; PyObject *iter; + iterable = stack_pointer[-1]; /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -1814,14 +2203,16 @@ } case _ITER_CHECK_LIST: { - PyObject *iter = stack_pointer[-1]; - DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); + PyObject *iter; + iter = stack_pointer[-1]; + DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, _ITER_CHECK_LIST); break; } case _IS_ITER_EXHAUSTED_LIST: { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; PyObject *exhausted; + iter = stack_pointer[-1]; _PyListIterObject *it = (_PyListIterObject *)iter; assert(Py_TYPE(iter) == &PyListIter_Type); PyListObject *seq = it->it_seq; @@ -1842,8 +2233,9 @@ } case _ITER_NEXT_LIST: { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; PyObject *next; + iter = stack_pointer[-1]; _PyListIterObject *it = (_PyListIterObject *)iter; assert(Py_TYPE(iter) == &PyListIter_Type); PyListObject *seq = it->it_seq; @@ -1856,14 +2248,16 @@ } case _ITER_CHECK_TUPLE: { - PyObject *iter = stack_pointer[-1]; - DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER); + PyObject *iter; + iter = stack_pointer[-1]; + DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, _ITER_CHECK_TUPLE); break; } case _IS_ITER_EXHAUSTED_TUPLE: { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; PyObject *exhausted; + iter = stack_pointer[-1]; _PyTupleIterObject *it = (_PyTupleIterObject *)iter; assert(Py_TYPE(iter) == &PyTupleIter_Type); PyTupleObject *seq = it->it_seq; @@ -1884,8 +2278,9 @@ } case _ITER_NEXT_TUPLE: { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; PyObject *next; + iter = stack_pointer[-1]; _PyTupleIterObject *it = (_PyTupleIterObject *)iter; assert(Py_TYPE(iter) == &PyTupleIter_Type); PyTupleObject *seq = it->it_seq; @@ -1898,15 +2293,17 @@ } case _ITER_CHECK_RANGE: { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; + iter = stack_pointer[-1]; _PyRangeIterObject *r = (_PyRangeIterObject *)iter; - DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, _ITER_CHECK_RANGE); break; } case _IS_ITER_EXHAUSTED_RANGE: { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; PyObject *exhausted; + iter = stack_pointer[-1]; _PyRangeIterObject *r = (_PyRangeIterObject *)iter; assert(Py_TYPE(r) == &PyRangeIter_Type); exhausted = r->len <= 0 ? Py_True : Py_False; @@ -1916,8 +2313,9 @@ } case _ITER_NEXT_RANGE: { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; PyObject *next; + iter = stack_pointer[-1]; _PyRangeIterObject *r = (_PyRangeIterObject *)iter; assert(Py_TYPE(r) == &PyRangeIter_Type); assert(r->len > 0); @@ -1932,10 +2330,13 @@ } case WITH_EXCEPT_START: { - PyObject *val = stack_pointer[-1]; - PyObject *lasti = stack_pointer[-3]; - PyObject *exit_func = stack_pointer[-4]; + PyObject *val; + PyObject *lasti; + PyObject *exit_func; PyObject *res; + val = stack_pointer[-1]; + lasti = stack_pointer[-3]; + exit_func = stack_pointer[-4]; /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -1949,7 +2350,12 @@ assert(val && PyExceptionInstance_Check(val)); exc = PyExceptionInstance_Class(val); tb = PyException_GetTraceback(val); - Py_XDECREF(tb); + if (tb == NULL) { + tb = Py_None; + } + else { + Py_DECREF(tb); + } assert(PyLong_Check(lasti)); (void)lasti; // Shut up compiler warning if asserts are off PyObject *stack[4] = {NULL, exc, val, tb}; @@ -1962,8 +2368,9 @@ } case PUSH_EXC_INFO: { - PyObject *new_exc = stack_pointer[-1]; + PyObject *new_exc; PyObject *prev_exc; + new_exc = stack_pointer[-1]; _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -1974,17 +2381,238 @@ assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); STACK_GROW(1); - stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; + stack_pointer[-1] = new_exc; + break; + } + + case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT: { + PyObject *owner; + owner = stack_pointer[-1]; + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT); + break; + } + + case _GUARD_KEYS_VERSION: { + PyObject *owner; + owner = stack_pointer[-1]; + uint32_t keys_version = (uint32_t)operand; + PyTypeObject *owner_cls = Py_TYPE(owner); + PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; + DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, _GUARD_KEYS_VERSION); + break; + } + + case _LOAD_ATTR_METHOD_WITH_VALUES: { + PyObject *owner; + PyObject *attr; + PyObject *self; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)operand; + assert(oparg & 1); + /* Cached method object */ + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + attr = Py_NewRef(descr); + assert(_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + self = owner; + STACK_GROW(1); + stack_pointer[-2] = attr; + stack_pointer[-1] = self; + break; + } + + case _LOAD_ATTR_METHOD_NO_DICT: { + PyObject *owner; + PyObject *attr; + PyObject *self; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)operand; + assert(oparg & 1); + assert(Py_TYPE(owner)->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + attr = Py_NewRef(descr); + self = owner; + STACK_GROW(1); + stack_pointer[-2] = attr; + stack_pointer[-1] = self; + break; + } + + case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: { + PyObject *owner; + PyObject *attr; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)operand; + assert((oparg & 1) == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + Py_DECREF(owner); + attr = Py_NewRef(descr); + stack_pointer[-1] = attr; + break; + } + + case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: { + PyObject *owner; + PyObject *attr; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)operand; + assert((oparg & 1) == 0); + assert(Py_TYPE(owner)->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + Py_DECREF(owner); + attr = Py_NewRef(descr); + stack_pointer[-1] = attr; + break; + } + + case _CHECK_ATTR_METHOD_LAZY_DICT: { + PyObject *owner; + owner = stack_pointer[-1]; + Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset; + assert(dictoffset > 0); + PyObject *dict = *(PyObject **)((char *)owner + dictoffset); + /* This object has a __dict__, just not yet created */ + DEOPT_IF(dict != NULL, _CHECK_ATTR_METHOD_LAZY_DICT); + break; + } + + case _LOAD_ATTR_METHOD_LAZY_DICT: { + PyObject *owner; + PyObject *attr; + PyObject *self; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)operand; + assert(oparg & 1); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + attr = Py_NewRef(descr); + self = owner; + STACK_GROW(1); + stack_pointer[-2] = attr; + stack_pointer[-1] = self; + break; + } + + case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: { + PyObject *null; + PyObject *callable; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + DEOPT_IF(null != NULL, _CHECK_CALL_BOUND_METHOD_EXACT_ARGS); + DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, _CHECK_CALL_BOUND_METHOD_EXACT_ARGS); + break; + } + + case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: { + PyObject *callable; + PyObject *func; + PyObject *self; + callable = stack_pointer[-2 - oparg]; + STAT_INC(CALL, hit); + self = Py_NewRef(((PyMethodObject *)callable)->im_self); + stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _INIT_CALL_PY_EXACT_ARGS + func = Py_NewRef(((PyMethodObject *)callable)->im_func); + stack_pointer[-2 - oparg] = func; // This is used by CALL, upon deoptimization + Py_DECREF(callable); + stack_pointer[-2 - oparg] = func; + stack_pointer[-1 - oparg] = self; + break; + } + + case _CHECK_PEP_523: { + DEOPT_IF(tstate->interp->eval_frame, _CHECK_PEP_523); break; } - case CALL_NO_KW_TYPE_1: { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *null = stack_pointer[-(2 + oparg)]; + case _CHECK_FUNCTION_EXACT_ARGS: { + PyObject *self_or_null; + PyObject *callable; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + uint32_t func_version = (uint32_t)operand; + DEOPT_IF(!PyFunction_Check(callable), _CHECK_FUNCTION_EXACT_ARGS); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, _CHECK_FUNCTION_EXACT_ARGS); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), _CHECK_FUNCTION_EXACT_ARGS); + break; + } + + case _CHECK_STACK_SPACE: { + PyObject *callable; + callable = stack_pointer[-2 - oparg]; + PyFunctionObject *func = (PyFunctionObject *)callable; + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), _CHECK_STACK_SPACE); + DEOPT_IF(tstate->py_recursion_remaining <= 1, _CHECK_STACK_SPACE); + break; + } + + case _INIT_CALL_PY_EXACT_ARGS: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; + _PyInterpreterFrame *new_frame; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + int argcount = oparg; + if (self_or_null != NULL) { + args--; + argcount++; + } + STAT_INC(CALL, hit); + PyFunctionObject *func = (PyFunctionObject *)callable; + new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; + } + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = (PyObject *)new_frame; + break; + } + + case _PUSH_FRAME: { + _PyInterpreterFrame *new_frame; + new_frame = (_PyInterpreterFrame *)stack_pointer[-1]; + STACK_SHRINK(1); + // Write it out explicitly because it's subtly different. + // Eventually this should be the only occurrence of this code. + frame->return_offset = 0; + assert(tstate->interp->eval_frame == NULL); + STORE_SP(); + new_frame->previous = frame; + CALL_STAT_INC(inlined_py_calls); + frame = tstate->current_frame = new_frame; + tstate->py_recursion_remaining--; + LOAD_SP(); + LOAD_IP(); +#if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } +#endif + break; + } + + case CALL_TYPE_1: { + PyObject **args; + PyObject *null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 1); DEOPT_IF(null != NULL, CALL); PyObject *obj = args[0]; @@ -1999,12 +2627,14 @@ break; } - case CALL_NO_KW_STR_1: { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *null = stack_pointer[-(2 + oparg)]; + case CALL_STR_1: { + PyObject **args; + PyObject *null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 1); DEOPT_IF(null != NULL, CALL); DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); @@ -2017,15 +2647,18 @@ STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); break; } - case CALL_NO_KW_TUPLE_1: { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *null = stack_pointer[-(2 + oparg)]; + case CALL_TUPLE_1: { + PyObject **args; + PyObject *null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 1); DEOPT_IF(null != NULL, CALL); DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); @@ -2038,11 +2671,13 @@ STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); break; } case EXIT_INIT_CHECK: { - PyObject *should_be_none = stack_pointer[-1]; + PyObject *should_be_none; + should_be_none = stack_pointer[-1]; assert(STACK_LEVEL() == 2); if (should_be_none != Py_None) { PyErr_Format(PyExc_TypeError, @@ -2054,17 +2689,48 @@ break; } - case CALL_NO_KW_BUILTIN_O: { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + case CALL_BUILTIN_CLASS: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; + } + DEOPT_IF(!PyType_Check(callable), CALL); + PyTypeObject *tp = (PyTypeObject *)callable; + DEOPT_IF(tp->tp_vectorcall == NULL, CALL); + STAT_INC(CALL, hit); + res = tp->tp_vectorcall((PyObject *)tp, args, total_args, NULL); + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(tp); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); + break; + } + + case CALL_BUILTIN_O: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; + PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* Builtin METH_O functions */ - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } @@ -2089,20 +2755,21 @@ STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); break; } - case CALL_NO_KW_BUILTIN_FAST: { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + case CALL_BUILTIN_FAST: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* Builtin METH_FASTCALL functions, without keywords */ - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } @@ -2131,25 +2798,63 @@ STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); break; } - case CALL_NO_KW_LEN: { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + case CALL_BUILTIN_FAST_WITH_KEYWORDS: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; + } + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS), CALL); + STAT_INC(CALL, hit); + /* res = func(self, args, nargs, kwnames) */ + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void)) + PyCFunction_GET_FUNCTION(callable); + res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); + break; + } + + case CALL_LEN: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; + PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* len(o) */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } DEOPT_IF(total_args != 1, CALL); - PyInterpreterState *interp = _PyInterpreterState_GET(); + PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable != interp->callable_cache.len, CALL); STAT_INC(CALL, hit); PyObject *arg = args[0]; @@ -2169,22 +2874,22 @@ break; } - case CALL_NO_KW_ISINSTANCE: { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + case CALL_ISINSTANCE: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* isinstance(o, o2) */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } DEOPT_IF(total_args != 2, CALL); - PyInterpreterState *interp = _PyInterpreterState_GET(); + PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); STAT_INC(CALL, hit); PyObject *cls = args[1]; @@ -2206,26 +2911,27 @@ break; } - case CALL_NO_KW_METHOD_DESCRIPTOR_O: { - PyObject **args = (stack_pointer - oparg); - PyObject *method = stack_pointer[-(2 + oparg)]; + case CALL_METHOD_DESCRIPTOR_O: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; DEOPT_IF(total_args != 2, CALL); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; DEOPT_IF(meth->ml_flags != METH_O, CALL); PyObject *arg = args[1]; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall @@ -2243,27 +2949,70 @@ STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); + break; + } + + case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; + PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; + } + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; + DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); + PyTypeObject *d_type = method->d_common.d_type; + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); + STAT_INC(CALL, hit); + int nargs = total_args - 1; + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + res = cfunc(self, args + 1, nargs, NULL); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); break; } - case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: { - PyObject **args = (stack_pointer - oparg); - PyObject *method = stack_pointer[-(2 + oparg)]; + case CALL_METHOD_DESCRIPTOR_NOARGS: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 0 || oparg == 1); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } DEOPT_IF(total_args != 1, CALL); - PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; @@ -2281,28 +3030,30 @@ STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); break; } - case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: { - PyObject **args = (stack_pointer - oparg); - PyObject *method = stack_pointer[-(2 + oparg)]; + case CALL_METHOD_DESCRIPTOR_FAST: { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; /* Builtin METH_FASTCALL methods, without keywords */ - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); STAT_INC(CALL, hit); _PyCFunctionFast cfunc = (_PyCFunctionFast)(void(*)(void))meth->ml_meth; @@ -2318,12 +3069,14 @@ STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); break; } case MAKE_FUNCTION: { - PyObject *codeobj = stack_pointer[-1]; + PyObject *codeobj; PyObject *func; + codeobj = stack_pointer[-1]; PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -2333,15 +3086,18 @@ goto error; } - func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; + _PyFunction_SetVersion( + func_obj, ((PyCodeObject *)codeobj)->co_version); func = (PyObject *)func_obj; stack_pointer[-1] = func; break; } case SET_FUNCTION_ATTRIBUTE: { - PyObject *func = stack_pointer[-1]; - PyObject *attr = stack_pointer[-2]; + PyObject *func; + PyObject *attr; + func = stack_pointer[-1]; + attr = stack_pointer[-2]; assert(PyFunction_Check(func)); PyFunctionObject *func_obj = (PyFunctionObject *)func; switch(oparg) { @@ -2372,10 +3128,13 @@ } case BUILD_SLICE: { - PyObject *step = (oparg == 3) ? stack_pointer[-(((oparg == 3) ? 1 : 0))] : NULL; - PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; - PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; + PyObject *step = NULL; + PyObject *stop; + PyObject *start; PyObject *slice; + if (oparg == 3) { step = stack_pointer[-(oparg == 3 ? 1 : 0)]; } + stop = stack_pointer[-1 - (oparg == 3 ? 1 : 0)]; + start = stack_pointer[-2 - (oparg == 3 ? 1 : 0)]; slice = PySlice_New(start, stop, step); Py_DECREF(start); Py_DECREF(stop); @@ -2388,8 +3147,9 @@ } case CONVERT_VALUE: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *result; + value = stack_pointer[-1]; convertion_func_ptr conv_fn; assert(oparg >= FVC_STR && oparg <= FVC_ASCII); conv_fn = CONVERSION_FUNCTIONS[oparg]; @@ -2401,8 +3161,9 @@ } case FORMAT_SIMPLE: { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; /* If value is a unicode object, then we know the result * of format(value) is value itself. */ if (!PyUnicode_CheckExact(value)) { @@ -2418,9 +3179,11 @@ } case FORMAT_WITH_SPEC: { - PyObject *fmt_spec = stack_pointer[-1]; - PyObject *value = stack_pointer[-2]; + PyObject *fmt_spec; + PyObject *value; PyObject *res; + fmt_spec = stack_pointer[-1]; + value = stack_pointer[-2]; res = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_DECREF(fmt_spec); @@ -2431,8 +3194,9 @@ } case COPY: { - PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; + PyObject *bottom; PyObject *top; + bottom = stack_pointer[-1 - (oparg-1)]; assert(oparg > 0); top = Py_NewRef(bottom); STACK_GROW(1); @@ -2441,10 +3205,11 @@ } case BINARY_OP: { - static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); - PyObject *rhs = stack_pointer[-1]; - PyObject *lhs = stack_pointer[-2]; + PyObject *rhs; + PyObject *lhs; PyObject *res; + rhs = stack_pointer[-1]; + lhs = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2455,10 +3220,10 @@ STAT_INC(BINARY_OP, deferred); DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ - assert(0 <= oparg); - assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); - assert(binary_ops[oparg]); - res = binary_ops[oparg](lhs, rhs); + assert(NB_ADD <= oparg); + assert(oparg <= NB_INPLACE_XOR); + assert(_PyEval_BinaryOps[oparg]); + res = _PyEval_BinaryOps[oparg](lhs, rhs); Py_DECREF(lhs); Py_DECREF(rhs); if (res == NULL) goto pop_2_error; @@ -2468,16 +3233,19 @@ } case SWAP: { - PyObject *top = stack_pointer[-1]; - PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; + PyObject *top; + PyObject *bottom; + top = stack_pointer[-1]; + bottom = stack_pointer[-2 - (oparg-2)]; assert(oparg >= 2); + stack_pointer[-2 - (oparg-2)] = top; stack_pointer[-1] = bottom; - stack_pointer[-(2 + (oparg-2))] = top; break; } case _POP_JUMP_IF_FALSE: { - PyObject *flag = stack_pointer[-1]; + PyObject *flag; + flag = stack_pointer[-1]; if (Py_IsFalse(flag)) { pc = oparg; } @@ -2486,7 +3254,8 @@ } case _POP_JUMP_IF_TRUE: { - PyObject *flag = stack_pointer[-1]; + PyObject *flag; + flag = stack_pointer[-1]; if (Py_IsTrue(flag)) { pc = oparg; } @@ -2494,20 +3263,32 @@ break; } - case JUMP_TO_TOP: { + case _JUMP_TO_TOP: { pc = 0; + CHECK_EVAL_BREAKER(); break; } - case SAVE_IP: { + case _SET_IP: { + TIER_TWO_ONLY frame->prev_instr = ip_offset + oparg; break; } - case EXIT_TRACE: { + case _EXIT_TRACE: { frame->prev_instr--; // Back up to just before destination _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(self); + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); return frame; break; } + + case _INSERT: { + PyObject *top; + top = stack_pointer[-1]; + // Inserts TOS at position specified by oparg; + memmove(&stack_pointer[-1 - oparg], &stack_pointer[-oparg], oparg * sizeof(stack_pointer[0])); + stack_pointer[-1 - oparg] = top; + break; + } diff --git a/Python/fileutils.c b/Python/fileutils.c index f262c3e095c9ba..17a4ae56ef0528 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -2,8 +2,11 @@ #include "pycore_fileutils.h" // fileutils definitions #include "pycore_runtime.h" // _PyRuntime #include "osdefs.h" // SEP -#include + #include // mbstowcs() +#ifdef HAVE_UNISTD_H +# include // getcwd() +#endif #ifdef MS_WINDOWS # include @@ -19,7 +22,7 @@ extern int winerror_to_errno(int); #endif #ifdef HAVE_LANGINFO_H -#include +# include // nl_langinfo(CODESET) #endif #ifdef HAVE_SYS_IOCTL_H @@ -27,12 +30,12 @@ extern int winerror_to_errno(int); #endif #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION -#include +# include // iconv_open() #endif #ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ +# include // fcntl(F_GETFD) +#endif #ifdef O_CLOEXEC /* Does open() support the O_CLOEXEC flag? Possible values: @@ -105,7 +108,7 @@ _Py_device_encoding(int fd) #else if (_PyRuntime.preconfig.utf8_mode) { _Py_DECLARE_STR(utf_8, "utf-8"); - return Py_NewRef(&_Py_STR(utf_8)); + return &_Py_STR(utf_8); } return _Py_GetLocaleEncodingObject(); #endif @@ -1790,6 +1793,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_END_ALLOW_THREADS } while (f == NULL && errno == EINTR && !(async_err = PyErr_CheckSignals())); + int saved_errno = errno; PyMem_Free(wpath); #else PyObject *bytes; @@ -1812,13 +1816,14 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_END_ALLOW_THREADS } while (f == NULL && errno == EINTR && !(async_err = PyErr_CheckSignals())); - + int saved_errno = errno; Py_DECREF(bytes); #endif if (async_err) return NULL; if (f == NULL) { + errno = saved_errno; PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); return NULL; } @@ -2377,12 +2382,14 @@ _Py_find_basename(const wchar_t *filename) path, which will be within the original buffer. Guaranteed to not make the path longer, and will not fail. 'size' is the length of the path, if known. If -1, the first null character will be assumed - to be the end of the path. */ + to be the end of the path. 'normsize' will be set to contain the + length of the resulting normalized path. */ wchar_t * -_Py_normpath(wchar_t *path, Py_ssize_t size) +_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) { assert(path != NULL); - if (!path[0] || size == 0) { + if ((size < 0 && !path[0]) || size == 0) { + *normsize = 0; return path; } wchar_t *pEnd = size >= 0 ? &path[size] : NULL; @@ -2431,11 +2438,7 @@ _Py_normpath(wchar_t *path, Py_ssize_t size) *p2++ = lastC = *p1; } } - if (sepCount) { - minP2 = p2; // Invalid path - } else { - minP2 = p2 - 1; // Absolute path has SEP at minP2 - } + minP2 = p2 - 1; } #else // Skip past two leading SEPs @@ -2495,13 +2498,28 @@ _Py_normpath(wchar_t *path, Py_ssize_t size) while (--p2 != minP2 && *p2 == SEP) { *p2 = L'\0'; } + } else { + --p2; } + *normsize = p2 - path + 1; #undef SEP_OR_END #undef IS_SEP #undef IS_END return path; } +/* In-place path normalisation. Returns the start of the normalized + path, which will be within the original buffer. Guaranteed to not + make the path longer, and will not fail. 'size' is the length of + the path, if known. If -1, the first null character will be assumed + to be the end of the path. */ +wchar_t * +_Py_normpath(wchar_t *path, Py_ssize_t size) +{ + Py_ssize_t norm_length; + return _Py_normpath_and_size(path, size, &norm_length); +} + /* Get the current directory. buflen is the buffer size in wide characters including the null character. Decode the path from the locale encoding. diff --git a/Python/flowgraph.c b/Python/flowgraph.c index e485ed103147a1..e89ad39b35719b 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -24,15 +24,75 @@ typedef _PyCompilerSrcLocation location; typedef _PyCfgJumpTargetLabel jump_target_label; -typedef _PyCfgBasicblock basicblock; -typedef _PyCfgBuilder cfg_builder; -typedef _PyCfgInstruction cfg_instr; + +typedef struct _PyCfgInstruction { + int i_opcode; + int i_oparg; + _PyCompilerSrcLocation i_loc; + struct _PyCfgBasicblock *i_target; /* target block (if jump instruction) */ + struct _PyCfgBasicblock *i_except; /* target block when exception is raised */ +} cfg_instr; + +typedef struct _PyCfgBasicblock { + /* Each basicblock in a compilation unit is linked via b_list in the + reverse order that the block are allocated. b_list points to the next + block in this list, not to be confused with b_next, which is next by + control flow. */ + struct _PyCfgBasicblock *b_list; + /* The label of this block if it is a jump target, -1 otherwise */ + _PyCfgJumpTargetLabel b_label; + /* Exception stack at start of block, used by assembler to create the exception handling table */ + struct _PyCfgExceptStack *b_exceptstack; + /* pointer to an array of instructions, initially NULL */ + cfg_instr *b_instr; + /* If b_next is non-NULL, it is a pointer to the next + block reached by normal control flow. */ + struct _PyCfgBasicblock *b_next; + /* number of instructions used */ + int b_iused; + /* length of instruction array (b_instr) */ + int b_ialloc; + /* Used by add_checks_for_loads_of_unknown_variables */ + uint64_t b_unsafe_locals_mask; + /* Number of predecessors that a block has. */ + int b_predecessors; + /* depth of stack upon entry of block, computed by stackdepth() */ + int b_startdepth; + /* Basic block is an exception handler that preserves lasti */ + unsigned b_preserve_lasti : 1; + /* Used by compiler passes to mark whether they have visited a basic block. */ + unsigned b_visited : 1; + /* b_except_handler is used by the cold-detection algorithm to mark exception targets */ + unsigned b_except_handler : 1; + /* b_cold is true if this block is not perf critical (like an exception handler) */ + unsigned b_cold : 1; + /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */ + unsigned b_warm : 1; +} basicblock; + + +struct _PyCfgBuilder { + /* The entryblock, at which control flow begins. All blocks of the + CFG are reachable through the b_next links */ + struct _PyCfgBasicblock *g_entryblock; + /* Pointer to the most recently allocated block. By following + b_list links, you can reach all allocated blocks. */ + struct _PyCfgBasicblock *g_block_list; + /* pointer to the block currently being constructed */ + struct _PyCfgBasicblock *g_curblock; + /* label for the next instruction to be placed */ + _PyCfgJumpTargetLabel g_current_label; +}; + +typedef struct _PyCfgBuilder cfg_builder; static const jump_target_label NO_LABEL = {-1}; #define SAME_LABEL(L1, L2) ((L1).id == (L2).id) #define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL))) +#define LOCATION(LNO, END_LNO, COL, END_COL) \ + ((const _PyCompilerSrcLocation){(LNO), (END_LNO), (COL), (END_COL)}) static inline int is_block_push(cfg_instr *i) @@ -50,7 +110,7 @@ is_jump(cfg_instr *i) #define INSTR_SET_OP1(I, OP, ARG) \ do { \ assert(OPCODE_HAS_ARG(OP)); \ - _PyCfgInstruction *_instr__ptr_ = (I); \ + cfg_instr *_instr__ptr_ = (I); \ _instr__ptr_->i_opcode = (OP); \ _instr__ptr_->i_oparg = (ARG); \ } while (0); @@ -59,7 +119,7 @@ is_jump(cfg_instr *i) #define INSTR_SET_OP0(I, OP) \ do { \ assert(!OPCODE_HAS_ARG(OP)); \ - _PyCfgInstruction *_instr__ptr_ = (I); \ + cfg_instr *_instr__ptr_ = (I); \ _instr__ptr_->i_opcode = (OP); \ _instr__ptr_->i_oparg = 0; \ } while (0); @@ -137,6 +197,27 @@ basicblock_append_instructions(basicblock *target, basicblock *source) return SUCCESS; } +static cfg_instr * +basicblock_last_instr(const basicblock *b) { + assert(b->b_iused >= 0); + if (b->b_iused > 0) { + assert(b->b_instr != NULL); + return &b->b_instr[b->b_iused - 1]; + } + return NULL; +} + +static inline int +basicblock_nofallthrough(const basicblock *b) { + cfg_instr *last = basicblock_last_instr(b); + return (last && + (IS_SCOPE_EXIT_OPCODE(last->i_opcode) || + IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode))); +} + +#define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B)) +#define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B)) + static basicblock * copy_basicblock(cfg_builder *g, basicblock *block) { @@ -154,8 +235,8 @@ copy_basicblock(cfg_builder *g, basicblock *block) return result; } -int -_PyBasicblock_InsertInstruction(basicblock *block, int pos, cfg_instr *instr) { +static int +basicblock_insert_instruction(basicblock *block, int pos, cfg_instr *instr) { RETURN_IF_ERROR(basicblock_next_instr(block)); for (int i = block->b_iused - 1; i > pos; i--) { block->b_instr[i] = block->b_instr[i-1]; @@ -180,13 +261,13 @@ dump_instr(cfg_instr *i) if (HAS_TARGET(i->i_opcode)) { sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg); } - fprintf(stderr, "line: %d, opcode: %d %s%s\n", - i->i_loc.lineno, i->i_opcode, arg, jump); + fprintf(stderr, "line: %d, %s (%d) %s%s\n", + i->i_loc.lineno, _PyOpcode_OpName[i->i_opcode], i->i_opcode, arg, jump); } static inline int basicblock_returns(const basicblock *b) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST); } @@ -228,26 +309,16 @@ cfg_builder_use_next_block(cfg_builder *g, basicblock *block) return block; } -cfg_instr * -_PyCfg_BasicblockLastInstr(const basicblock *b) { - assert(b->b_iused >= 0); - if (b->b_iused > 0) { - assert(b->b_instr != NULL); - return &b->b_instr[b->b_iused - 1]; - } - return NULL; -} - static inline int basicblock_exits_scope(const basicblock *b) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode); } static bool cfg_builder_current_block_is_terminated(cfg_builder *g) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(g->g_curblock); + cfg_instr *last = basicblock_last_instr(g->g_curblock); if (last && IS_TERMINATOR_OPCODE(last->i_opcode)) { return true; } @@ -300,8 +371,8 @@ cfg_builder_check(cfg_builder *g) } #endif -int -_PyCfgBuilder_Init(cfg_builder *g) +static int +init_cfg_builder(cfg_builder *g) { g->g_block_list = NULL; basicblock *block = cfg_builder_new_block(g); @@ -313,9 +384,28 @@ _PyCfgBuilder_Init(cfg_builder *g) return SUCCESS; } +cfg_builder * +_PyCfgBuilder_New(void) +{ + cfg_builder *g = PyMem_Malloc(sizeof(cfg_builder)); + if (g == NULL) { + PyErr_NoMemory(); + return NULL; + } + memset(g, 0, sizeof(cfg_builder)); + if (init_cfg_builder(g) < 0) { + PyMem_Free(g); + return NULL; + } + return g; +} + void -_PyCfgBuilder_Fini(cfg_builder* g) +_PyCfgBuilder_Free(cfg_builder *g) { + if (g == NULL) { + return; + } assert(cfg_builder_check(g)); basicblock *b = g->g_block_list; while (b != NULL) { @@ -326,6 +416,21 @@ _PyCfgBuilder_Fini(cfg_builder* g) PyObject_Free((void *)b); b = next; } + PyMem_Free(g); +} + +int +_PyCfgBuilder_CheckSize(cfg_builder *g) +{ + int nblocks = 0; + for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) { + nblocks++; + } + if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { + PyErr_NoMemory(); + return ERROR; + } + return SUCCESS; } int @@ -371,7 +476,7 @@ no_empty_basic_blocks(cfg_builder *g) { static bool no_redundant_jumps(cfg_builder *g) { for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); if (last != NULL) { if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { assert(last->i_target != b->b_next); @@ -390,7 +495,7 @@ no_redundant_jumps(cfg_builder *g) { static int normalize_jumps_in_block(cfg_builder *g, basicblock *b) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); if (last == NULL || !is_jump(last) || IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { return SUCCESS; @@ -426,7 +531,7 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) { if (backwards_jump == NULL) { return ERROR; } - basicblock_addop(backwards_jump, JUMP, target->b_label.id, NO_LOCATION); + basicblock_addop(backwards_jump, JUMP, target->b_label.id, last->i_loc); backwards_jump->b_instr[0].i_target = target; last->i_opcode = reversed_opcode; last->i_target = b->b_next; @@ -439,7 +544,7 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) { static int -normalize_jumps(_PyCfgBuilder *g) +normalize_jumps(cfg_builder *g) { basicblock *entryblock = g->g_entryblock; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { @@ -452,14 +557,6 @@ normalize_jumps(_PyCfgBuilder *g) return SUCCESS; } -int -_PyCfg_ResolveJumps(_PyCfgBuilder *g) -{ - RETURN_IF_ERROR(normalize_jumps(g)); - assert(no_redundant_jumps(g)); - return SUCCESS; -} - static int check_cfg(cfg_builder *g) { for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { @@ -478,16 +575,23 @@ check_cfg(cfg_builder *g) { return SUCCESS; } -/* Calculate the actual jump target from the target_label */ static int -translate_jump_labels_to_targets(basicblock *entryblock) +get_max_label(basicblock *entryblock) { - int max_label = -1; + int lbl = -1; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - if (b->b_label.id > max_label) { - max_label = b->b_label.id; + if (b->b_label.id > lbl) { + lbl = b->b_label.id; } } + return lbl; +} + +/* Calculate the actual jump target from the target_label */ +static int +translate_jump_labels_to_targets(basicblock *entryblock) +{ + int max_label = get_max_label(entryblock); size_t mapsize = sizeof(basicblock *) * (max_label + 1); basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize); if (!label2block) { @@ -518,9 +622,9 @@ translate_jump_labels_to_targets(basicblock *entryblock) } int -_PyCfg_JumpLabelsToTargets(basicblock *entryblock) +_PyCfg_JumpLabelsToTargets(cfg_builder *g) { - return translate_jump_labels_to_targets(entryblock); + return translate_jump_labels_to_targets(g->g_entryblock); } static int @@ -542,10 +646,14 @@ mark_except_handlers(basicblock *entryblock) { } -typedef _PyCfgExceptStack ExceptStack; +struct _PyCfgExceptStack { + basicblock *handlers[CO_MAXBLOCKS+1]; + int depth; +}; + static basicblock * -push_except_block(ExceptStack *stack, cfg_instr *setup) { +push_except_block(struct _PyCfgExceptStack *stack, cfg_instr *setup) { assert(is_block_push(setup)); int opcode = setup->i_opcode; basicblock * target = setup->i_target; @@ -557,19 +665,19 @@ push_except_block(ExceptStack *stack, cfg_instr *setup) { } static basicblock * -pop_except_block(ExceptStack *stack) { +pop_except_block(struct _PyCfgExceptStack *stack) { assert(stack->depth > 0); return stack->handlers[--stack->depth]; } static basicblock * -except_stack_top(ExceptStack *stack) { +except_stack_top(struct _PyCfgExceptStack *stack) { return stack->handlers[stack->depth]; } -static ExceptStack * +static struct _PyCfgExceptStack * make_except_stack(void) { - ExceptStack *new = PyMem_Malloc(sizeof(ExceptStack)); + struct _PyCfgExceptStack *new = PyMem_Malloc(sizeof(struct _PyCfgExceptStack)); if (new == NULL) { PyErr_NoMemory(); return NULL; @@ -579,14 +687,14 @@ make_except_stack(void) { return new; } -static ExceptStack * -copy_except_stack(ExceptStack *stack) { - ExceptStack *copy = PyMem_Malloc(sizeof(ExceptStack)); +static struct _PyCfgExceptStack * +copy_except_stack(struct _PyCfgExceptStack *stack) { + struct _PyCfgExceptStack *copy = PyMem_Malloc(sizeof(struct _PyCfgExceptStack)); if (copy == NULL) { PyErr_NoMemory(); return NULL; } - memcpy(copy, stack, sizeof(ExceptStack)); + memcpy(copy, stack, sizeof(struct _PyCfgExceptStack)); return copy; } @@ -604,23 +712,28 @@ make_cfg_traversal_stack(basicblock *entryblock) { return stack; } -Py_LOCAL_INLINE(void) +Py_LOCAL_INLINE(int) stackdepth_push(basicblock ***sp, basicblock *b, int depth) { - assert(b->b_startdepth < 0 || b->b_startdepth == depth); + if (!(b->b_startdepth < 0 || b->b_startdepth == depth)) { + PyErr_Format(PyExc_ValueError, "Invalid CFG, inconsistent stackdepth"); + return ERROR; + } if (b->b_startdepth < depth && b->b_startdepth < 100) { assert(b->b_startdepth < 0); b->b_startdepth = depth; *(*sp)++ = b; } + return SUCCESS; } /* Find the flow path that needs the largest stack. We assume that * cycles in the flow graph have no net effect on the stack depth. */ -int -_PyCfg_Stackdepth(basicblock *entryblock, int code_flags) +static int +calculate_stackdepth(cfg_builder *g) { + basicblock *entryblock = g->g_entryblock; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { b->b_startdepth = INT_MIN; } @@ -629,14 +742,13 @@ _PyCfg_Stackdepth(basicblock *entryblock, int code_flags) return ERROR; } + + int stackdepth = -1; int maxdepth = 0; basicblock **sp = stack; - if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - stackdepth_push(&sp, entryblock, 1); - } else { - stackdepth_push(&sp, entryblock, 0); + if (stackdepth_push(&sp, entryblock, 0) < 0) { + goto error; } - while (sp != stack) { basicblock *b = *--sp; int depth = b->b_startdepth; @@ -644,27 +756,40 @@ _PyCfg_Stackdepth(basicblock *entryblock, int code_flags) basicblock *next = b->b_next; for (int i = 0; i < b->b_iused; i++) { cfg_instr *instr = &b->b_instr[i]; - int effect = PyCompile_OpcodeStackEffectWithJump(instr->i_opcode, instr->i_oparg, 0); + int effect = PyCompile_OpcodeStackEffectWithJump( + instr->i_opcode, instr->i_oparg, 0); if (effect == PY_INVALID_STACK_EFFECT) { PyErr_Format(PyExc_SystemError, - "compiler PyCompile_OpcodeStackEffectWithJump(opcode=%d, arg=%i) failed", + "Invalid stack effect for opcode=%d, arg=%i", instr->i_opcode, instr->i_oparg); - return ERROR; + goto error; } int new_depth = depth + effect; - assert(new_depth >= 0); /* invalid code or bug in stackdepth() */ + if (new_depth < 0) { + PyErr_Format(PyExc_ValueError, + "Invalid CFG, stack underflow"); + goto error; + } if (new_depth > maxdepth) { maxdepth = new_depth; } if (HAS_TARGET(instr->i_opcode)) { - effect = PyCompile_OpcodeStackEffectWithJump(instr->i_opcode, instr->i_oparg, 1); - assert(effect != PY_INVALID_STACK_EFFECT); + effect = PyCompile_OpcodeStackEffectWithJump( + instr->i_opcode, instr->i_oparg, 1); + if (effect == PY_INVALID_STACK_EFFECT) { + PyErr_Format(PyExc_SystemError, + "Invalid stack effect for opcode=%d, arg=%i", + instr->i_opcode, instr->i_oparg); + goto error; + } int target_depth = depth + effect; assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ if (target_depth > maxdepth) { maxdepth = target_depth; } - stackdepth_push(&sp, instr->i_target, target_depth); + if (stackdepth_push(&sp, instr->i_target, target_depth) < 0) { + goto error; + } } depth = new_depth; assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode)); @@ -678,11 +803,15 @@ _PyCfg_Stackdepth(basicblock *entryblock, int code_flags) } if (next != NULL) { assert(BB_HAS_FALLTHROUGH(b)); - stackdepth_push(&sp, next, depth); + if (stackdepth_push(&sp, next, depth) < 0) { + goto error; + } } } + stackdepth = maxdepth; +error: PyMem_Free(stack); - return maxdepth; + return stackdepth; } static int @@ -691,7 +820,7 @@ label_exception_targets(basicblock *entryblock) { if (todo_stack == NULL) { return ERROR; } - ExceptStack *except_stack = make_except_stack(); + struct _PyCfgExceptStack *except_stack = make_except_stack(); if (except_stack == NULL) { PyMem_Free(todo_stack); PyErr_NoMemory(); @@ -715,7 +844,7 @@ label_exception_targets(basicblock *entryblock) { cfg_instr *instr = &b->b_instr[i]; if (is_block_push(instr)) { if (!instr->i_target->b_visited) { - ExceptStack *copy = copy_except_stack(except_stack); + struct _PyCfgExceptStack *copy = copy_except_stack(except_stack); if (copy == NULL) { goto error; } @@ -734,7 +863,7 @@ label_exception_targets(basicblock *entryblock) { assert(i == b->b_iused -1); if (!instr->i_target->b_visited) { if (BB_HAS_FALLTHROUGH(b)) { - ExceptStack *copy = copy_except_stack(except_stack); + struct _PyCfgExceptStack *copy = copy_except_stack(except_stack); if (copy == NULL) { goto error; } @@ -831,6 +960,7 @@ eliminate_empty_basic_blocks(cfg_builder *g) { while(g->g_entryblock && g->g_entryblock->b_iused == 0) { g->g_entryblock = g->g_entryblock->b_next; } + int next_lbl = get_max_label(g->g_entryblock) + 1; for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { assert(b->b_iused > 0); for (int i = 0; i < b->b_iused; i++) { @@ -840,7 +970,13 @@ eliminate_empty_basic_blocks(cfg_builder *g) { while (target->b_iused == 0) { target = target->b_next; } - instr->i_target = target; + if (instr->i_target != target) { + if (!IS_LABEL(target->b_label)) { + target->b_label.id = next_lbl++; + } + instr->i_target = target; + instr->i_oparg = target->b_label.id; + } assert(instr->i_target && instr->i_target->b_iused > 0); } } @@ -881,7 +1017,17 @@ remove_redundant_nops(basicblock *bb) { } /* or if last instruction in BB and next BB has same line number */ if (next) { - if (lineno == next->b_instr[0].i_loc.lineno) { + location next_loc = NO_LOCATION; + for (int next_i=0; next_i < next->b_iused; next_i++) { + cfg_instr *instr = &next->b_instr[next_i]; + if (instr->i_opcode == NOP && instr->i_loc.lineno == NO_LOCATION.lineno) { + /* Skip over NOPs without location, they will be removed */ + continue; + } + next_loc = instr->i_loc; + break; + } + if (lineno == next_loc.lineno) { continue; } } @@ -953,7 +1099,7 @@ remove_redundant_jumps(cfg_builder *g) { */ assert(no_empty_basic_blocks(g)); for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); assert(last != NULL); assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { @@ -979,7 +1125,7 @@ remove_redundant_jumps(cfg_builder *g) { */ static int inline_small_exit_blocks(basicblock *bb) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(bb); + cfg_instr *last = basicblock_last_instr(bb); if (last == NULL) { return 0; } @@ -1502,12 +1648,10 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts) INSTR_SET_OP0(inst, NOP); } break; - case KW_NAMES: - break; - case PUSH_NULL: - if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) { - INSTR_SET_OP0(inst, NOP); - inst[1].i_oparg |= 1; + case LOAD_GLOBAL: + if (nextop == PUSH_NULL && (oparg & 1) == 0) { + INSTR_SET_OP1(inst, LOAD_GLOBAL, oparg | 1); + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); } break; case COMPARE_OP: @@ -1715,7 +1859,7 @@ scan_block_for_locals(basicblock *b, basicblock ***sp) if (b->b_next && BB_HAS_FALLTHROUGH(b)) { maybe_push(b->b_next, unsafe_mask, sp); } - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); if (last && is_jump(last)) { assert(last->i_target != NULL); maybe_push(last->i_target, unsafe_mask, sp); @@ -1998,7 +2142,7 @@ mark_cold(basicblock *entryblock) { static int -push_cold_blocks_to_end(cfg_builder *g, int code_flags) { +push_cold_blocks_to_end(cfg_builder *g) { basicblock *entryblock = g->g_entryblock; if (entryblock->b_next == NULL) { /* single basicblock, no need to reorder */ @@ -2006,6 +2150,8 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) { } RETURN_IF_ERROR(mark_cold(entryblock)); + int next_lbl = get_max_label(g->g_entryblock) + 1; + /* If we have a cold block with fallthrough to a warm block, add */ /* an explicit jump instead of fallthrough */ for (basicblock *b = entryblock; b != NULL; b = b->b_next) { @@ -2014,13 +2160,16 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) { if (explicit_jump == NULL) { return ERROR; } + if (!IS_LABEL(b->b_next->b_label)) { + b->b_next->b_label.id = next_lbl++; + } basicblock_addop(explicit_jump, JUMP, b->b_next->b_label.id, NO_LOCATION); explicit_jump->b_cold = 1; explicit_jump->b_next = b->b_next; b->b_next = explicit_jump; /* set target */ - cfg_instr *last = _PyCfg_BasicblockLastInstr(explicit_jump); + cfg_instr *last = basicblock_last_instr(explicit_jump); last->i_target = explicit_jump->b_next; } } @@ -2071,8 +2220,8 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) { return SUCCESS; } -void -_PyCfg_ConvertPseudoOps(basicblock *entryblock) +static void +convert_pseudo_ops(basicblock *entryblock) { for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { @@ -2109,6 +2258,7 @@ is_exit_without_lineno(basicblock *b) { return true; } + /* PEP 626 mandates that the f_lineno of a frame is correct * after a frame terminates. It would be prohibitively expensive * to continuously update the f_lineno field at runtime, @@ -2122,11 +2272,14 @@ static int duplicate_exits_without_lineno(cfg_builder *g) { assert(no_empty_basic_blocks(g)); + + int next_lbl = get_max_label(g->g_entryblock) + 1; + /* Copy all exit blocks without line number that are targets of a jump. */ basicblock *entryblock = g->g_entryblock; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); assert(last != NULL); if (is_jump(last)) { basicblock *target = last->i_target; @@ -2140,6 +2293,7 @@ duplicate_exits_without_lineno(cfg_builder *g) target->b_predecessors--; new_target->b_predecessors = 1; new_target->b_next = target->b_next; + new_target->b_label.id = next_lbl++; target->b_next = new_target; } } @@ -2150,7 +2304,7 @@ duplicate_exits_without_lineno(cfg_builder *g) for (basicblock *b = entryblock; b != NULL; b = b->b_next) { if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) { if (is_exit_without_lineno(b->b_next)) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); assert(last != NULL); b->b_next->b_instr[0].i_loc = last->i_loc; } @@ -2170,7 +2324,7 @@ duplicate_exits_without_lineno(cfg_builder *g) static void propagate_line_numbers(basicblock *entryblock) { for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); if (last == NULL) { continue; } @@ -2210,7 +2364,7 @@ guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) { int lineno = firstlineno; assert(lineno > 0); for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + cfg_instr *last = basicblock_last_instr(b); if (last == NULL) { continue; } @@ -2240,7 +2394,7 @@ resolve_line_numbers(cfg_builder *g, int firstlineno) int _PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache, - int code_flags, int nlocals, int nparams, int firstlineno) + int nlocals, int nparams, int firstlineno) { assert(cfg_builder_check(g)); /** Preprocessing **/ @@ -2257,7 +2411,289 @@ _PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache, g->g_entryblock, nlocals, nparams)); insert_superinstructions(g); - RETURN_IF_ERROR(push_cold_blocks_to_end(g, code_flags)); + RETURN_IF_ERROR(push_cold_blocks_to_end(g)); RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno)); return SUCCESS; } + +static int * +build_cellfixedoffsets(_PyCompile_CodeUnitMetadata *umd) +{ + int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); + int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); + + int noffsets = ncellvars + nfreevars; + int *fixed = PyMem_New(int, noffsets); + if (fixed == NULL) { + PyErr_NoMemory(); + return NULL; + } + for (int i = 0; i < noffsets; i++) { + fixed[i] = nlocals + i; + } + + PyObject *varname, *cellindex; + Py_ssize_t pos = 0; + while (PyDict_Next(umd->u_cellvars, &pos, &varname, &cellindex)) { + PyObject *varindex; + if (PyDict_GetItemRef(umd->u_varnames, varname, &varindex) < 0) { + goto error; + } + if (varindex == NULL) { + continue; + } + + int argoffset = PyLong_AsInt(varindex); + Py_DECREF(varindex); + if (argoffset == -1 && PyErr_Occurred()) { + goto error; + } + + int oldindex = PyLong_AsInt(cellindex); + if (oldindex == -1 && PyErr_Occurred()) { + goto error; + } + fixed[oldindex] = argoffset; + } + return fixed; + +error: + PyMem_Free(fixed); + return NULL; +} + +#define IS_GENERATOR(CF) \ + ((CF) & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) + +static int +insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, + int *fixed, int nfreevars, int code_flags) +{ + assert(umd->u_firstlineno > 0); + + /* Add the generator prefix instructions. */ + if (IS_GENERATOR(code_flags)) { + /* Note that RETURN_GENERATOR + POP_TOP have a net stack effect + * of 0. This is because RETURN_GENERATOR pushes an element + * with _PyFrame_StackPush before switching stacks. + */ + + location loc = LOCATION(umd->u_firstlineno, umd->u_firstlineno, -1, -1); + cfg_instr make_gen = { + .i_opcode = RETURN_GENERATOR, + .i_oparg = 0, + .i_loc = loc, + .i_target = NULL, + }; + RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, &make_gen)); + cfg_instr pop_top = { + .i_opcode = POP_TOP, + .i_oparg = 0, + .i_loc = loc, + .i_target = NULL, + }; + RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 1, &pop_top)); + } + + /* Set up cells for any variable that escapes, to be put in a closure. */ + const int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + if (ncellvars) { + // umd->u_cellvars has the cells out of order so we sort them + // before adding the MAKE_CELL instructions. Note that we + // adjust for arg cells, which come first. + const int nvars = ncellvars + (int)PyDict_GET_SIZE(umd->u_varnames); + int *sorted = PyMem_RawCalloc(nvars, sizeof(int)); + if (sorted == NULL) { + PyErr_NoMemory(); + return ERROR; + } + for (int i = 0; i < ncellvars; i++) { + sorted[fixed[i]] = i + 1; + } + for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) { + int oldindex = sorted[i] - 1; + if (oldindex == -1) { + continue; + } + cfg_instr make_cell = { + .i_opcode = MAKE_CELL, + // This will get fixed in offset_derefs(). + .i_oparg = oldindex, + .i_loc = NO_LOCATION, + .i_target = NULL, + }; + if (basicblock_insert_instruction(entryblock, ncellsused, &make_cell) < 0) { + PyMem_RawFree(sorted); + return ERROR; + } + ncellsused += 1; + } + PyMem_RawFree(sorted); + } + + if (nfreevars) { + cfg_instr copy_frees = { + .i_opcode = COPY_FREE_VARS, + .i_oparg = nfreevars, + .i_loc = NO_LOCATION, + .i_target = NULL, + }; + RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, ©_frees)); + } + + return SUCCESS; +} + +static int +fix_cell_offsets(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, int *fixedmap) +{ + int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); + int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); + int noffsets = ncellvars + nfreevars; + + // First deal with duplicates (arg cells). + int numdropped = 0; + for (int i = 0; i < noffsets ; i++) { + if (fixedmap[i] == i + nlocals) { + fixedmap[i] -= numdropped; + } + else { + // It was a duplicate (cell/arg). + numdropped += 1; + } + } + + // Then update offsets, either relative to locals or by cell2arg. + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *inst = &b->b_instr[i]; + // This is called before extended args are generated. + assert(inst->i_opcode != EXTENDED_ARG); + int oldoffset = inst->i_oparg; + switch(inst->i_opcode) { + case MAKE_CELL: + case LOAD_CLOSURE: + case LOAD_DEREF: + case STORE_DEREF: + case DELETE_DEREF: + case LOAD_FROM_DICT_OR_DEREF: + assert(oldoffset >= 0); + assert(oldoffset < noffsets); + assert(fixedmap[oldoffset] >= 0); + inst->i_oparg = fixedmap[oldoffset]; + } + } + } + + return numdropped; +} + +static int +prepare_localsplus(_PyCompile_CodeUnitMetadata *umd, cfg_builder *g, int code_flags) +{ + assert(PyDict_GET_SIZE(umd->u_varnames) < INT_MAX); + assert(PyDict_GET_SIZE(umd->u_cellvars) < INT_MAX); + assert(PyDict_GET_SIZE(umd->u_freevars) < INT_MAX); + int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); + int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); + assert(INT_MAX - nlocals - ncellvars > 0); + assert(INT_MAX - nlocals - ncellvars - nfreevars > 0); + int nlocalsplus = nlocals + ncellvars + nfreevars; + int* cellfixedoffsets = build_cellfixedoffsets(umd); + if (cellfixedoffsets == NULL) { + return ERROR; + } + + // This must be called before fix_cell_offsets(). + if (insert_prefix_instructions(umd, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) { + PyMem_Free(cellfixedoffsets); + return ERROR; + } + + int numdropped = fix_cell_offsets(umd, g->g_entryblock, cellfixedoffsets); + PyMem_Free(cellfixedoffsets); // At this point we're done with it. + cellfixedoffsets = NULL; + if (numdropped < 0) { + return ERROR; + } + + nlocalsplus -= numdropped; + return nlocalsplus; +} + +int +_PyCfg_ToInstructionSequence(cfg_builder *g, _PyCompile_InstructionSequence *seq) +{ + int lbl = 0; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + b->b_label = (jump_target_label){lbl}; + lbl += b->b_iused; + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + RETURN_IF_ERROR(_PyCompile_InstructionSequence_UseLabel(seq, b->b_label.id)); + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + if (OPCODE_HAS_JUMP(instr->i_opcode)) { + instr->i_oparg = instr->i_target->b_label.id; + } + RETURN_IF_ERROR( + _PyCompile_InstructionSequence_Addop( + seq, instr->i_opcode, instr->i_oparg, instr->i_loc)); + + _PyCompile_ExceptHandlerInfo *hi = &seq->s_instrs[seq->s_used-1].i_except_handler_info; + if (instr->i_except != NULL) { + hi->h_label = instr->i_except->b_label.id; + hi->h_startdepth = instr->i_except->b_startdepth; + hi->h_preserve_lasti = instr->i_except->b_preserve_lasti; + } + else { + hi->h_label = -1; + } + } + } + return SUCCESS; +} + + +int +_PyCfg_OptimizedCfgToInstructionSequence(cfg_builder *g, + _PyCompile_CodeUnitMetadata *umd, int code_flags, + int *stackdepth, int *nlocalsplus, + _PyCompile_InstructionSequence *seq) +{ + *stackdepth = calculate_stackdepth(g); + if (*stackdepth < 0) { + return ERROR; + } + + /* prepare_localsplus adds instructions for generators that push + * and pop an item on the stack. This assertion makes sure there + * is space on the stack for that. + * It should always be true, because a generator must have at + * least one expression or call to INTRINSIC_STOPITERATION_ERROR, + * which requires stackspace. + */ + assert(!(IS_GENERATOR(code_flags) && *stackdepth == 0)); + + *nlocalsplus = prepare_localsplus(umd, g, code_flags); + if (*nlocalsplus < 0) { + return ERROR; + } + + convert_pseudo_ops(g->g_entryblock); + + /* Order of basic blocks must have been determined by now */ + + RETURN_IF_ERROR(normalize_jumps(g)); + assert(no_redundant_jumps(g)); + + /* Can't modify the bytecode after computing jump offsets. */ + if (_PyCfg_ToInstructionSequence(g, seq) < 0) { + return ERROR; + } + + return SUCCESS; +} diff --git a/Python/frame.c b/Python/frame.c index 581e4f95710fe2..b483903fdf3018 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -124,7 +124,7 @@ _PyFrame_ClearExceptCode(_PyInterpreterFrame *frame) _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED); // GH-99729: Clearing this frame can expose the stack (via finalizers). It's // crucial that this frame has been unlinked, and is no longer visible: - assert(_PyThreadState_GET()->cframe->current_frame != frame); + assert(_PyThreadState_GET()->current_frame != frame); if (frame->frame_obj) { PyFrameObject *f = frame->frame_obj; frame->frame_obj = NULL; @@ -167,10 +167,10 @@ PyUnstable_InterpreterFrame_GetLine(_PyInterpreterFrame *frame) return PyCode_Addr2Line(_PyFrame_GetCode(frame), addr); } -const PyTypeObject *const PyUnstable_ExecutableKinds[PY_EXECUTABLE_KINDS+1] = { - [PY_EXECUTABLE_KIND_SKIP] = &_PyNone_Type, - [PY_EXECUTABLE_KIND_PY_FUNCTION] = &PyCode_Type, - [PY_EXECUTABLE_KIND_BUILTIN_FUNCTION] = &PyMethod_Type, - [PY_EXECUTABLE_KIND_METHOD_DESCRIPTOR] = &PyMethodDescr_Type, - [PY_EXECUTABLE_KINDS] = NULL, +const PyTypeObject *const PyUnstable_ExecutableKinds[PyUnstable_EXECUTABLE_KINDS+1] = { + [PyUnstable_EXECUTABLE_KIND_SKIP] = &_PyNone_Type, + [PyUnstable_EXECUTABLE_KIND_PY_FUNCTION] = &PyCode_Type, + [PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION] = &PyMethod_Type, + [PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR] = &PyMethodDescr_Type, + [PyUnstable_EXECUTABLE_KINDS] = NULL, }; diff --git a/Python/frozen.c b/Python/frozen.c index 6b977710e6e342..0fb38a11902f35 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -101,46 +101,46 @@ extern PyObject *_Py_get_frozen_only_toplevel(void); /* End extern declarations */ static const struct _frozen bootstrap_modules[] = { - {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap), false, GET_CODE(importlib__bootstrap)}, - {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external), false, GET_CODE(importlib__bootstrap_external)}, - {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport), false, GET_CODE(zipimport)}, + {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap), false}, + {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external), false}, + {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport), false}, {0, 0, 0} /* bootstrap sentinel */ }; static const struct _frozen stdlib_modules[] = { /* stdlib - startup, without site (python -S) */ - {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc), false, GET_CODE(abc)}, - {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs), false, GET_CODE(codecs)}, - {"io", _Py_M__io, (int)sizeof(_Py_M__io), false, GET_CODE(io)}, + {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc), false}, + {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs), false}, + {"io", _Py_M__io, (int)sizeof(_Py_M__io), false}, /* stdlib - startup, with site */ - {"_collections_abc", _Py_M___collections_abc, (int)sizeof(_Py_M___collections_abc), false, GET_CODE(_collections_abc)}, - {"_sitebuiltins", _Py_M___sitebuiltins, (int)sizeof(_Py_M___sitebuiltins), false, GET_CODE(_sitebuiltins)}, - {"genericpath", _Py_M__genericpath, (int)sizeof(_Py_M__genericpath), false, GET_CODE(genericpath)}, - {"ntpath", _Py_M__ntpath, (int)sizeof(_Py_M__ntpath), false, GET_CODE(ntpath)}, - {"posixpath", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), false, GET_CODE(posixpath)}, - {"os.path", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), false, GET_CODE(posixpath)}, - {"os", _Py_M__os, (int)sizeof(_Py_M__os), false, GET_CODE(os)}, - {"site", _Py_M__site, (int)sizeof(_Py_M__site), false, GET_CODE(site)}, - {"stat", _Py_M__stat, (int)sizeof(_Py_M__stat), false, GET_CODE(stat)}, + {"_collections_abc", _Py_M___collections_abc, (int)sizeof(_Py_M___collections_abc), false}, + {"_sitebuiltins", _Py_M___sitebuiltins, (int)sizeof(_Py_M___sitebuiltins), false}, + {"genericpath", _Py_M__genericpath, (int)sizeof(_Py_M__genericpath), false}, + {"ntpath", _Py_M__ntpath, (int)sizeof(_Py_M__ntpath), false}, + {"posixpath", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), false}, + {"os.path", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), false}, + {"os", _Py_M__os, (int)sizeof(_Py_M__os), false}, + {"site", _Py_M__site, (int)sizeof(_Py_M__site), false}, + {"stat", _Py_M__stat, (int)sizeof(_Py_M__stat), false}, /* runpy - run module with -m */ - {"importlib.util", _Py_M__importlib_util, (int)sizeof(_Py_M__importlib_util), false, GET_CODE(importlib_util)}, - {"importlib.machinery", _Py_M__importlib_machinery, (int)sizeof(_Py_M__importlib_machinery), false, GET_CODE(importlib_machinery)}, - {"runpy", _Py_M__runpy, (int)sizeof(_Py_M__runpy), false, GET_CODE(runpy)}, + {"importlib.util", _Py_M__importlib_util, (int)sizeof(_Py_M__importlib_util), false}, + {"importlib.machinery", _Py_M__importlib_machinery, (int)sizeof(_Py_M__importlib_machinery), false}, + {"runpy", _Py_M__runpy, (int)sizeof(_Py_M__runpy), false}, {0, 0, 0} /* stdlib sentinel */ }; static const struct _frozen test_modules[] = { - {"__hello__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false, GET_CODE(__hello__)}, - {"__hello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false, GET_CODE(__hello__)}, - {"__phello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), true, GET_CODE(__hello__)}, - {"__phello_alias__.spam", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false, GET_CODE(__hello__)}, - {"__phello__", _Py_M____phello__, (int)sizeof(_Py_M____phello__), true, GET_CODE(__phello__)}, - {"__phello__.__init__", _Py_M____phello__, (int)sizeof(_Py_M____phello__), false, GET_CODE(__phello__)}, - {"__phello__.ham", _Py_M____phello___ham, (int)sizeof(_Py_M____phello___ham), true, GET_CODE(__phello___ham)}, - {"__phello__.ham.__init__", _Py_M____phello___ham, (int)sizeof(_Py_M____phello___ham), false, GET_CODE(__phello___ham)}, - {"__phello__.ham.eggs", _Py_M____phello___ham_eggs, (int)sizeof(_Py_M____phello___ham_eggs), false, GET_CODE(__phello___ham_eggs)}, - {"__phello__.spam", _Py_M____phello___spam, (int)sizeof(_Py_M____phello___spam), false, GET_CODE(__phello___spam)}, - {"__hello_only__", _Py_M__frozen_only, (int)sizeof(_Py_M__frozen_only), false, GET_CODE(frozen_only)}, + {"__hello__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false}, + {"__hello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false}, + {"__phello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), true}, + {"__phello_alias__.spam", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false}, + {"__phello__", _Py_M____phello__, (int)sizeof(_Py_M____phello__), true}, + {"__phello__.__init__", _Py_M____phello__, (int)sizeof(_Py_M____phello__), false}, + {"__phello__.ham", _Py_M____phello___ham, (int)sizeof(_Py_M____phello___ham), true}, + {"__phello__.ham.__init__", _Py_M____phello___ham, (int)sizeof(_Py_M____phello___ham), false}, + {"__phello__.ham.eggs", _Py_M____phello___ham_eggs, (int)sizeof(_Py_M____phello___ham_eggs), false}, + {"__phello__.spam", _Py_M____phello___spam, (int)sizeof(_Py_M____phello___spam), false}, + {"__hello_only__", _Py_M__frozen_only, (int)sizeof(_Py_M__frozen_only), false}, {0, 0, 0} /* test sentinel */ }; const struct _frozen *_PyImport_FrozenBootstrap = bootstrap_modules; diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 767f9804903a9e..3ce9476c9ad46c 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -3,7 +3,11 @@ #include "Python.h" #include "pycore_pystate.h" // _Py_GetConfig() #include "pycore_runtime.h" // _PyRuntime_Initialize() -#include + +#ifdef HAVE_UNISTD_H +# include // isatty() +#endif + #ifdef MS_WINDOWS extern void PyWinFreeze_ExeInit(void); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index b2b0aa6ece4816..6fbe80fe03a128 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -8,26 +8,45 @@ } TARGET(RESUME) { - assert(tstate->cframe == &cframe); - assert(frame == cframe.current_frame); - /* Possibly combine this with eval breaker */ - if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) { + PREDICTED(RESUME); + static_assert(0 == 0, "incorrect cache size"); + TIER_ONE_ONLY + assert(frame == tstate->current_frame); + uintptr_t global_version = + _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) & + ~_PY_EVAL_EVENTS_MASK; + uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + assert((code_version & 255) == 0); + if (code_version != global_version) { int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); if (err) goto error; next_instr--; } - else if (oparg < 2) { - CHECK_EVAL_BREAKER(); + else { + if (oparg < 2) { + CHECK_EVAL_BREAKER(); + } + next_instr[-1].op.code = RESUME_CHECK; } DISPATCH(); } + TARGET(RESUME_CHECK) { +#if defined(__EMSCRIPTEN__) + DEOPT_IF(_Py_emscripten_signal_clock == 0, RESUME); + _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; +#endif + uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker); + uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + assert((version & _PY_EVAL_EVENTS_MASK) == 0); + DEOPT_IF(eval_breaker != version, RESUME); + DISPATCH(); + } + TARGET(INSTRUMENTED_RESUME) { - /* Possible performance enhancement: - * We need to check the eval breaker anyway, can we - * combine the instrument verison check and the eval breaker test? - */ - if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) { + uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) & ~_PY_EVAL_EVENTS_MASK; + uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + if (code_version != global_version) { if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) { goto error; } @@ -91,8 +110,8 @@ Py_INCREF(value1); Py_INCREF(value2); STACK_GROW(2); - stack_pointer[-1] = value2; stack_pointer[-2] = value1; + stack_pointer[-1] = value2; DISPATCH(); } @@ -106,15 +125,17 @@ } TARGET(STORE_FAST) { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; SETLOCAL(oparg, value); STACK_SHRINK(1); DISPATCH(); } TARGET(STORE_FAST_LOAD_FAST) { - PyObject *value1 = stack_pointer[-1]; + PyObject *value1; PyObject *value2; + value1 = stack_pointer[-1]; uint32_t oparg1 = oparg >> 4; uint32_t oparg2 = oparg & 15; SETLOCAL(oparg1, value1); @@ -125,8 +146,10 @@ } TARGET(STORE_FAST_STORE_FAST) { - PyObject *value1 = stack_pointer[-1]; - PyObject *value2 = stack_pointer[-2]; + PyObject *value1; + PyObject *value2; + value1 = stack_pointer[-1]; + value2 = stack_pointer[-2]; uint32_t oparg1 = oparg >> 4; uint32_t oparg2 = oparg & 15; SETLOCAL(oparg1, value1); @@ -136,7 +159,8 @@ } TARGET(POP_TOP) { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; Py_DECREF(value); STACK_SHRINK(1); DISPATCH(); @@ -151,14 +175,15 @@ } TARGET(END_FOR) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *value; + // POP_TOP + value = stack_pointer[-1]; { - PyObject *value = _tmp_1; Py_DECREF(value); } + // POP_TOP + value = stack_pointer[-2]; { - PyObject *value = _tmp_2; Py_DECREF(value); } STACK_SHRINK(2); @@ -166,8 +191,10 @@ } TARGET(INSTRUMENTED_END_FOR) { - PyObject *value = stack_pointer[-1]; - PyObject *receiver = stack_pointer[-2]; + PyObject *value; + PyObject *receiver; + value = stack_pointer[-1]; + receiver = stack_pointer[-2]; /* Need to create a fake StopIteration error here, * to conform to PEP 380 */ if (PyGen_Check(receiver)) { @@ -184,8 +211,10 @@ } TARGET(END_SEND) { - PyObject *value = stack_pointer[-1]; - PyObject *receiver = stack_pointer[-2]; + PyObject *value; + PyObject *receiver; + value = stack_pointer[-1]; + receiver = stack_pointer[-2]; Py_DECREF(receiver); STACK_SHRINK(1); stack_pointer[-1] = value; @@ -193,8 +222,10 @@ } TARGET(INSTRUMENTED_END_SEND) { - PyObject *value = stack_pointer[-1]; - PyObject *receiver = stack_pointer[-2]; + PyObject *value; + PyObject *receiver; + value = stack_pointer[-1]; + receiver = stack_pointer[-2]; if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) { PyErr_SetObject(PyExc_StopIteration, value); if (monitor_stop_iteration(tstate, frame, next_instr-1)) { @@ -209,8 +240,9 @@ } TARGET(UNARY_NEGATIVE) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; res = PyNumber_Negative(value); Py_DECREF(value); if (res == NULL) goto pop_1_error; @@ -219,8 +251,9 @@ } TARGET(UNARY_NOT) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; assert(PyBool_Check(value)); res = Py_IsFalse(value) ? Py_True : Py_False; stack_pointer[-1] = res; @@ -230,8 +263,9 @@ TARGET(TO_BOOL) { PREDICTED(TO_BOOL); static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; #if ENABLE_SPECIALIZATION _PyToBoolCache *cache = (_PyToBoolCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -252,7 +286,8 @@ } TARGET(TO_BOOL_BOOL) { - PyObject *value = stack_pointer[-1]; + PyObject *value; + value = stack_pointer[-1]; DEOPT_IF(!PyBool_Check(value), TO_BOOL); STAT_INC(TO_BOOL, hit); next_instr += 3; @@ -260,8 +295,9 @@ } TARGET(TO_BOOL_INT) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; DEOPT_IF(!PyLong_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); if (_PyLong_IsZero((PyLongObject *)value)) { @@ -278,8 +314,9 @@ } TARGET(TO_BOOL_LIST) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; DEOPT_IF(!PyList_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); res = Py_SIZE(value) ? Py_True : Py_False; @@ -290,8 +327,9 @@ } TARGET(TO_BOOL_NONE) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; // This one is a bit weird, because we expect *some* failures: DEOPT_IF(!Py_IsNone(value), TO_BOOL); STAT_INC(TO_BOOL, hit); @@ -302,8 +340,9 @@ } TARGET(TO_BOOL_STR) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; DEOPT_IF(!PyUnicode_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); if (value == &_Py_STR(empty)) { @@ -321,8 +360,9 @@ } TARGET(TO_BOOL_ALWAYS_TRUE) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; uint32_t version = read_u32(&next_instr[1].cache); // This one is a bit weird, because we expect *some* failures: assert(version); @@ -336,8 +376,9 @@ } TARGET(UNARY_INVERT) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; res = PyNumber_Invert(value); Py_DECREF(value); if (res == NULL) goto pop_1_error; @@ -346,215 +387,192 @@ } TARGET(BINARY_OP_MULTIPLY_INT) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_INT + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_MULTIPLY_INT { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *res; STAT_INC(BINARY_OP, hit); res = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); if (res == NULL) goto pop_2_error; - _tmp_2 = res; } - next_instr += 1; STACK_SHRINK(1); - stack_pointer[-1] = _tmp_2; + stack_pointer[-1] = res; + next_instr += 1; DISPATCH(); } TARGET(BINARY_OP_ADD_INT) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_INT + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_ADD_INT { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *res; STAT_INC(BINARY_OP, hit); res = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); if (res == NULL) goto pop_2_error; - _tmp_2 = res; } - next_instr += 1; STACK_SHRINK(1); - stack_pointer[-1] = _tmp_2; + stack_pointer[-1] = res; + next_instr += 1; DISPATCH(); } TARGET(BINARY_OP_SUBTRACT_INT) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_INT + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_SUBTRACT_INT { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *res; STAT_INC(BINARY_OP, hit); res = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); if (res == NULL) goto pop_2_error; - _tmp_2 = res; } - next_instr += 1; STACK_SHRINK(1); - stack_pointer[-1] = _tmp_2; + stack_pointer[-1] = res; + next_instr += 1; DISPATCH(); } TARGET(BINARY_OP_MULTIPLY_FLOAT) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_FLOAT + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_MULTIPLY_FLOAT { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *res; STAT_INC(BINARY_OP, hit); double dres = ((PyFloatObject *)left)->ob_fval * ((PyFloatObject *)right)->ob_fval; DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - _tmp_2 = res; } - next_instr += 1; STACK_SHRINK(1); - stack_pointer[-1] = _tmp_2; + stack_pointer[-1] = res; + next_instr += 1; DISPATCH(); } TARGET(BINARY_OP_ADD_FLOAT) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_FLOAT + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_ADD_FLOAT { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *res; STAT_INC(BINARY_OP, hit); double dres = ((PyFloatObject *)left)->ob_fval + ((PyFloatObject *)right)->ob_fval; DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - _tmp_2 = res; } - next_instr += 1; STACK_SHRINK(1); - stack_pointer[-1] = _tmp_2; + stack_pointer[-1] = res; + next_instr += 1; DISPATCH(); } TARGET(BINARY_OP_SUBTRACT_FLOAT) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_FLOAT + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_SUBTRACT_FLOAT { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *res; STAT_INC(BINARY_OP, hit); double dres = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - _tmp_2 = res; } - next_instr += 1; STACK_SHRINK(1); - stack_pointer[-1] = _tmp_2; + stack_pointer[-1] = res; + next_instr += 1; DISPATCH(); } TARGET(BINARY_OP_ADD_UNICODE) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_UNICODE + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_ADD_UNICODE { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; - PyObject *res; STAT_INC(BINARY_OP, hit); res = PyUnicode_Concat(left, right); _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); if (res == NULL) goto pop_2_error; - _tmp_2 = res; } - next_instr += 1; STACK_SHRINK(1); - stack_pointer[-1] = _tmp_2; + stack_pointer[-1] = res; + next_instr += 1; DISPATCH(); } TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; + PyObject *right; + PyObject *left; + // _GUARD_BOTH_UNICODE + right = stack_pointer[-1]; + left = stack_pointer[-2]; { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); - _tmp_2 = left; - _tmp_1 = right; } + // _BINARY_OP_INPLACE_ADD_UNICODE { - PyObject *right = _tmp_1; - PyObject *left = _tmp_2; _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; assert(true_next.op.code == STORE_FAST); PyObject **target_local = &GETLOCAL(true_next.op.arg); @@ -586,9 +604,11 @@ TARGET(BINARY_SUBSCR) { PREDICTED(BINARY_SUBSCR); static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); - PyObject *sub = stack_pointer[-1]; - PyObject *container = stack_pointer[-2]; + PyObject *sub; + PyObject *container; PyObject *res; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -610,10 +630,13 @@ } TARGET(BINARY_SLICE) { - PyObject *stop = stack_pointer[-1]; - PyObject *start = stack_pointer[-2]; - PyObject *container = stack_pointer[-3]; + PyObject *stop; + PyObject *start; + PyObject *container; PyObject *res; + stop = stack_pointer[-1]; + start = stack_pointer[-2]; + container = stack_pointer[-3]; PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); // Can't use ERROR_IF() here, because we haven't // DECREF'ed container yet, and we still own slice. @@ -632,10 +655,14 @@ } TARGET(STORE_SLICE) { - PyObject *stop = stack_pointer[-1]; - PyObject *start = stack_pointer[-2]; - PyObject *container = stack_pointer[-3]; - PyObject *v = stack_pointer[-4]; + PyObject *stop; + PyObject *start; + PyObject *container; + PyObject *v; + stop = stack_pointer[-1]; + start = stack_pointer[-2]; + container = stack_pointer[-3]; + v = stack_pointer[-4]; PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); int err; if (slice == NULL) { @@ -653,9 +680,11 @@ } TARGET(BINARY_SUBSCR_LIST_INT) { - PyObject *sub = stack_pointer[-1]; - PyObject *list = stack_pointer[-2]; + PyObject *sub; + PyObject *list; PyObject *res; + sub = stack_pointer[-1]; + list = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); @@ -675,10 +704,36 @@ DISPATCH(); } + TARGET(BINARY_SUBSCR_STR_INT) { + PyObject *sub; + PyObject *str; + PyObject *res; + sub = stack_pointer[-1]; + str = stack_pointer[-2]; + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyUnicode_CheckExact(str), BINARY_SUBSCR); + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index, BINARY_SUBSCR); + // Specialize for reading an ASCII character from any string: + Py_UCS4 c = PyUnicode_READ_CHAR(str, index); + DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c, BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = (PyObject*)&_Py_SINGLETON(strings).ascii[c]; + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(str); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + TARGET(BINARY_SUBSCR_TUPLE_INT) { - PyObject *sub = stack_pointer[-1]; - PyObject *tuple = stack_pointer[-2]; + PyObject *sub; + PyObject *tuple; PyObject *res; + sub = stack_pointer[-1]; + tuple = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); @@ -699,9 +754,11 @@ } TARGET(BINARY_SUBSCR_DICT) { - PyObject *sub = stack_pointer[-1]; - PyObject *dict = stack_pointer[-2]; + PyObject *sub; + PyObject *dict; PyObject *res; + sub = stack_pointer[-1]; + dict = stack_pointer[-2]; DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); res = PyDict_GetItemWithError(dict, sub); @@ -723,8 +780,10 @@ } TARGET(BINARY_SUBSCR_GETITEM) { - PyObject *sub = stack_pointer[-1]; - PyObject *container = stack_pointer[-2]; + PyObject *sub; + PyObject *container; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); PyTypeObject *tp = Py_TYPE(container); DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR); @@ -750,16 +809,20 @@ } TARGET(LIST_APPEND) { - PyObject *v = stack_pointer[-1]; - PyObject *list = stack_pointer[-(2 + (oparg-1))]; + PyObject *v; + PyObject *list; + v = stack_pointer[-1]; + list = stack_pointer[-2 - (oparg-1)]; if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error; STACK_SHRINK(1); DISPATCH(); } TARGET(SET_ADD) { - PyObject *v = stack_pointer[-1]; - PyObject *set = stack_pointer[-(2 + (oparg-1))]; + PyObject *v; + PyObject *set; + v = stack_pointer[-1]; + set = stack_pointer[-2 - (oparg-1)]; int err = PySet_Add(set, v); Py_DECREF(v); if (err) goto pop_1_error; @@ -770,9 +833,12 @@ TARGET(STORE_SUBSCR) { PREDICTED(STORE_SUBSCR); static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size"); - PyObject *sub = stack_pointer[-1]; - PyObject *container = stack_pointer[-2]; - PyObject *v = stack_pointer[-3]; + PyObject *sub; + PyObject *container; + PyObject *v; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; + v = stack_pointer[-3]; #if ENABLE_SPECIALIZATION _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -795,9 +861,12 @@ } TARGET(STORE_SUBSCR_LIST_INT) { - PyObject *sub = stack_pointer[-1]; - PyObject *list = stack_pointer[-2]; - PyObject *value = stack_pointer[-3]; + PyObject *sub; + PyObject *list; + PyObject *value; + sub = stack_pointer[-1]; + list = stack_pointer[-2]; + value = stack_pointer[-3]; DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); @@ -820,9 +889,12 @@ } TARGET(STORE_SUBSCR_DICT) { - PyObject *sub = stack_pointer[-1]; - PyObject *dict = stack_pointer[-2]; - PyObject *value = stack_pointer[-3]; + PyObject *sub; + PyObject *dict; + PyObject *value; + sub = stack_pointer[-1]; + dict = stack_pointer[-2]; + value = stack_pointer[-3]; DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); STAT_INC(STORE_SUBSCR, hit); int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); @@ -834,8 +906,10 @@ } TARGET(DELETE_SUBSCR) { - PyObject *sub = stack_pointer[-1]; - PyObject *container = stack_pointer[-2]; + PyObject *sub; + PyObject *container; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; /* del container[sub] */ int err = PyObject_DelItem(container, sub); Py_DECREF(container); @@ -846,10 +920,11 @@ } TARGET(CALL_INTRINSIC_1) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; assert(oparg <= MAX_INTRINSIC_1); - res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); + res = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, value); Py_DECREF(value); if (res == NULL) goto pop_1_error; stack_pointer[-1] = res; @@ -857,11 +932,13 @@ } TARGET(CALL_INTRINSIC_2) { - PyObject *value1 = stack_pointer[-1]; - PyObject *value2 = stack_pointer[-2]; + PyObject *value1; + PyObject *value2; PyObject *res; + value1 = stack_pointer[-1]; + value2 = stack_pointer[-2]; assert(oparg <= MAX_INTRINSIC_2); - res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1); + res = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1); Py_DECREF(value2); Py_DECREF(value1); if (res == NULL) goto pop_2_error; @@ -871,7 +948,8 @@ } TARGET(RAISE_VARARGS) { - PyObject **args = (stack_pointer - oparg); + PyObject **args; + args = stack_pointer - oparg; PyObject *cause = NULL, *exc = NULL; switch (oparg) { case 2: @@ -881,7 +959,11 @@ exc = args[0]; /* fall through */ case 0: - if (do_raise(tstate, exc, cause)) { STACK_SHRINK(oparg); goto exception_unwind; } + if (do_raise(tstate, exc, cause)) { + assert(oparg == 0); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } break; default: _PyErr_SetString(tstate, PyExc_SystemError, @@ -892,35 +974,55 @@ } TARGET(INTERPRETER_EXIT) { - PyObject *retval = stack_pointer[-1]; + PyObject *retval; + retval = stack_pointer[-1]; assert(frame == &entry_frame); assert(_PyFrame_IsIncomplete(frame)); - /* Restore previous cframe and return. */ - tstate->cframe = cframe.previous; - assert(tstate->cframe->current_frame == frame->previous); + /* Restore previous frame and return. */ + tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - _Py_LeaveRecursiveCallTstate(tstate); + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; return retval; } TARGET(RETURN_VALUE) { - PyObject *retval = stack_pointer[-1]; + PyObject *retval; + // _SAVE_CURRENT_IP + { + TIER_ONE_ONLY + frame->prev_instr = next_instr - 1; + } + // _POP_FRAME + retval = stack_pointer[-1]; STACK_SHRINK(1); - assert(EMPTY()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _Py_LeaveRecursiveCallPy(tstate); - assert(frame != &entry_frame); - // GH-99729: We need to unlink the frame *before* clearing it: - _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; - _PyFrame_StackPush(frame, retval); - goto resume_frame; + { + assert(EMPTY()); + #if TIER_ONE + assert(frame != &entry_frame); + #endif + STORE_SP(); + _Py_LeaveRecursiveCallPy(tstate); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + LOAD_SP(); + LOAD_IP(); + #if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } + #endif + } + DISPATCH(); } TARGET(INSTRUMENTED_RETURN_VALUE) { - PyObject *retval = stack_pointer[-1]; + PyObject *retval; + retval = stack_pointer[-1]; int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_RETURN, frame, next_instr-1, retval); @@ -932,27 +1034,51 @@ assert(frame != &entry_frame); // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; } TARGET(RETURN_CONST) { - PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg); - Py_INCREF(retval); - assert(EMPTY()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _Py_LeaveRecursiveCallPy(tstate); - assert(frame != &entry_frame); - // GH-99729: We need to unlink the frame *before* clearing it: - _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; - _PyFrame_StackPush(frame, retval); - goto resume_frame; + PyObject *value; + PyObject *retval; + // LOAD_CONST + { + value = GETITEM(FRAME_CO_CONSTS, oparg); + Py_INCREF(value); + } + // _SAVE_CURRENT_IP + { + TIER_ONE_ONLY + frame->prev_instr = next_instr - 1; + } + // _POP_FRAME + retval = value; + { + assert(EMPTY()); + #if TIER_ONE + assert(frame != &entry_frame); + #endif + STORE_SP(); + _Py_LeaveRecursiveCallPy(tstate); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + LOAD_SP(); + LOAD_IP(); + #if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } + #endif + } + DISPATCH(); } TARGET(INSTRUMENTED_RETURN_CONST) { @@ -968,16 +1094,17 @@ assert(frame != &entry_frame); // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; } TARGET(GET_AITER) { - PyObject *obj = stack_pointer[-1]; + PyObject *obj; PyObject *iter; + obj = stack_pointer[-1]; unaryfunc getter = NULL; PyTypeObject *type = Py_TYPE(obj); @@ -1013,8 +1140,9 @@ } TARGET(GET_ANEXT) { - PyObject *aiter = stack_pointer[-1]; + PyObject *aiter; PyObject *awaitable; + aiter = stack_pointer[-1]; unaryfunc getter = NULL; PyObject *next_iter = NULL; PyTypeObject *type = Py_TYPE(aiter); @@ -1063,12 +1191,13 @@ } TARGET(GET_AWAITABLE) { - PyObject *iterable = stack_pointer[-1]; + PyObject *iterable; PyObject *iter; + iterable = stack_pointer[-1]; iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { - format_awaitable_error(tstate, Py_TYPE(iterable), oparg); + _PyEval_FormatAwaitableError(tstate, Py_TYPE(iterable), oparg); } Py_DECREF(iterable); @@ -1095,9 +1224,11 @@ TARGET(SEND) { PREDICTED(SEND); static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); - PyObject *v = stack_pointer[-1]; - PyObject *receiver = stack_pointer[-2]; + PyObject *v; + PyObject *receiver; PyObject *retval; + v = stack_pointer[-1]; + receiver = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PySendCache *cache = (_PySendCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1115,13 +1246,13 @@ { PyGenObject *gen = (PyGenObject *)receiver; _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - frame->return_offset = oparg; STACK_SHRINK(1); _PyFrame_StackPush(gen_frame, v); gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); + frame->return_offset = oparg; DISPATCH_INLINED(gen_frame); } if (Py_IsNone(v) && PyIter_Check(receiver)) { @@ -1150,27 +1281,29 @@ } TARGET(SEND_GEN) { - PyObject *v = stack_pointer[-1]; - PyObject *receiver = stack_pointer[-2]; + PyObject *v; + PyObject *receiver; + v = stack_pointer[-1]; + receiver = stack_pointer[-2]; DEOPT_IF(tstate->interp->eval_frame, SEND); PyGenObject *gen = (PyGenObject *)receiver; - DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && - Py_TYPE(gen) != &PyCoro_Type, SEND); + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); STAT_INC(SEND, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - frame->return_offset = oparg; STACK_SHRINK(1); _PyFrame_StackPush(gen_frame, v); gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); + frame->return_offset = oparg; DISPATCH_INLINED(gen_frame); } TARGET(INSTRUMENTED_YIELD_VALUE) { - PyObject *retval = stack_pointer[-1]; + PyObject *retval; + retval = stack_pointer[-1]; assert(frame != &entry_frame); assert(oparg >= 0); /* make the generator identify this as HAS_ARG */ PyGenObject *gen = _PyFrame_GetGenerator(frame); @@ -1184,14 +1317,15 @@ gen->gi_exc_state.previous_item = NULL; _Py_LeaveRecursiveCallPy(tstate); _PyInterpreterFrame *gen_frame = frame; - frame = cframe.current_frame = frame->previous; + frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; } TARGET(YIELD_VALUE) { - PyObject *retval = stack_pointer[-1]; + PyObject *retval; + retval = stack_pointer[-1]; // NOTE: It's important that YIELD_VALUE never raises an exception! // The compiler treats any exception raised here as a failed close() // or throw() call. @@ -1204,14 +1338,15 @@ gen->gi_exc_state.previous_item = NULL; _Py_LeaveRecursiveCallPy(tstate); _PyInterpreterFrame *gen_frame = frame; - frame = cframe.current_frame = frame->previous; + frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; } TARGET(POP_EXCEPT) { - PyObject *exc_value = stack_pointer[-1]; + PyObject *exc_value; + exc_value = stack_pointer[-1]; _PyErr_StackItem *exc_info = tstate->exc_info; Py_XSETREF(exc_info->exc_value, exc_value); STACK_SHRINK(1); @@ -1219,8 +1354,10 @@ } TARGET(RERAISE) { - PyObject *exc = stack_pointer[-1]; - PyObject **values = (stack_pointer - (1 + oparg)); + PyObject *exc; + PyObject **values; + exc = stack_pointer[-1]; + values = stack_pointer - 1 - oparg; assert(oparg >= 0 && oparg <= 2); if (oparg) { PyObject *lasti = values[0]; @@ -1237,12 +1374,15 @@ assert(exc && PyExceptionInstance_Check(exc)); Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); goto exception_unwind; } TARGET(END_ASYNC_FOR) { - PyObject *exc = stack_pointer[-1]; - PyObject *awaitable = stack_pointer[-2]; + PyObject *exc; + PyObject *awaitable; + exc = stack_pointer[-1]; + awaitable = stack_pointer[-2]; assert(exc && PyExceptionInstance_Check(exc)); if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { Py_DECREF(awaitable); @@ -1251,6 +1391,7 @@ else { Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); goto exception_unwind; } STACK_SHRINK(2); @@ -1258,11 +1399,14 @@ } TARGET(CLEANUP_THROW) { - PyObject *exc_value = stack_pointer[-1]; - PyObject *last_sent_val = stack_pointer[-2]; - PyObject *sub_iter = stack_pointer[-3]; + PyObject *exc_value; + PyObject *last_sent_val; + PyObject *sub_iter; PyObject *none; PyObject *value; + exc_value = stack_pointer[-1]; + last_sent_val = stack_pointer[-2]; + sub_iter = stack_pointer[-3]; assert(throwflag); assert(exc_value && PyExceptionInstance_Check(exc_value)); if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { @@ -1274,11 +1418,12 @@ } else { _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); + monitor_reraise(tstate, frame, next_instr-1); goto exception_unwind; } STACK_SHRINK(1); - stack_pointer[-1] = value; stack_pointer[-2] = none; + stack_pointer[-1] = value; DISPATCH(); } @@ -1304,7 +1449,8 @@ } TARGET(STORE_NAME) { - PyObject *v = stack_pointer[-1]; + PyObject *v; + v = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *ns = LOCALS(); int err; @@ -1336,9 +1482,9 @@ err = PyObject_DelItem(ns, name); // Can't use ERROR_IF here. if (err != 0) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); goto error; } DISPATCH(); @@ -1347,7 +1493,8 @@ TARGET(UNPACK_SEQUENCE) { PREDICTED(UNPACK_SEQUENCE); static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); - PyObject *seq = stack_pointer[-1]; + PyObject *seq; + seq = stack_pointer[-1]; #if ENABLE_SPECIALIZATION _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1359,7 +1506,7 @@ DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; - int res = unpack_iterable(tstate, seq, oparg, -1, top); + int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top); Py_DECREF(seq); if (res == 0) goto pop_1_error; STACK_SHRINK(1); @@ -1369,8 +1516,10 @@ } TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { - PyObject *seq = stack_pointer[-1]; - PyObject **values = stack_pointer - (1); + PyObject *seq; + PyObject **values; + seq = stack_pointer[-1]; + values = stack_pointer - 1; DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); assert(oparg == 2); @@ -1385,8 +1534,10 @@ } TARGET(UNPACK_SEQUENCE_TUPLE) { - PyObject *seq = stack_pointer[-1]; - PyObject **values = stack_pointer - (1); + PyObject *seq; + PyObject **values; + seq = stack_pointer[-1]; + values = stack_pointer - 1; DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1402,8 +1553,10 @@ } TARGET(UNPACK_SEQUENCE_LIST) { - PyObject *seq = stack_pointer[-1]; - PyObject **values = stack_pointer - (1); + PyObject *seq; + PyObject **values; + seq = stack_pointer[-1]; + values = stack_pointer - 1; DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1419,10 +1572,11 @@ } TARGET(UNPACK_EX) { - PyObject *seq = stack_pointer[-1]; + PyObject *seq; + seq = stack_pointer[-1]; int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; - int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); + int res = _PyEval_UnpackIterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); Py_DECREF(seq); if (res == 0) goto pop_1_error; STACK_GROW((oparg & 0xFF) + (oparg >> 8)); @@ -1432,8 +1586,10 @@ TARGET(STORE_ATTR) { PREDICTED(STORE_ATTR); static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); - PyObject *owner = stack_pointer[-1]; - PyObject *v = stack_pointer[-2]; + PyObject *owner; + PyObject *v; + owner = stack_pointer[-1]; + v = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1456,7 +1612,8 @@ } TARGET(DELETE_ATTR) { - PyObject *owner = stack_pointer[-1]; + PyObject *owner; + owner = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyObject_DelAttr(owner, name); Py_DECREF(owner); @@ -1466,7 +1623,8 @@ } TARGET(STORE_GLOBAL) { - PyObject *v = stack_pointer[-1]; + PyObject *v; + v = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyDict_SetItem(GLOBALS(), name, v); Py_DECREF(v); @@ -1482,8 +1640,8 @@ // Can't use ERROR_IF here. if (err != 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } goto error; } @@ -1491,114 +1649,94 @@ } TARGET(LOAD_LOCALS) { - PyObject *_tmp_1; - { - PyObject *locals; - locals = LOCALS(); - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found"); - if (true) goto error; - } - Py_INCREF(locals); - _tmp_1 = locals; + PyObject *locals; + locals = LOCALS(); + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; } + Py_INCREF(locals); STACK_GROW(1); - stack_pointer[-1] = _tmp_1; + stack_pointer[-1] = locals; DISPATCH(); } - TARGET(LOAD_NAME) { - PyObject *_tmp_1; - { - PyObject *locals; - locals = LOCALS(); - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found"); - if (true) goto error; - } - Py_INCREF(locals); - _tmp_1 = locals; + TARGET(LOAD_FROM_DICT_OR_GLOBALS) { + PyObject *mod_or_class_dict; + PyObject *v; + mod_or_class_dict = stack_pointer[-1]; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { + goto error; } - { - PyObject *mod_or_class_dict = _tmp_1; - PyObject *v; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { - Py_DECREF(mod_or_class_dict); + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { goto error; } - Py_DECREF(mod_or_class_dict); - if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { + else { + if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { goto error; } - else { - if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { - goto error; - } - if (v == NULL) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; - } + if (v == NULL) { + _PyEval_FormatExcCheckArg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + goto error; } } - _tmp_1 = v; } - STACK_GROW(1); - stack_pointer[-1] = _tmp_1; + Py_DECREF(mod_or_class_dict); + stack_pointer[-1] = v; DISPATCH(); } - TARGET(LOAD_FROM_DICT_OR_GLOBALS) { - PyObject *_tmp_1 = stack_pointer[-1]; - { - PyObject *mod_or_class_dict = _tmp_1; - PyObject *v; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { - Py_DECREF(mod_or_class_dict); + TARGET(LOAD_NAME) { + PyObject *v; + PyObject *mod_or_class_dict = LOCALS(); + if (mod_or_class_dict == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; + } + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { + goto error; + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { goto error; } - Py_DECREF(mod_or_class_dict); - if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { + else { + if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { goto error; } - else { - if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { - goto error; - } - if (v == NULL) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; - } + if (v == NULL) { + _PyEval_FormatExcCheckArg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + goto error; } } - _tmp_1 = v; } - stack_pointer[-1] = _tmp_1; + STACK_GROW(1); + stack_pointer[-1] = v; DISPATCH(); } TARGET(LOAD_GLOBAL) { PREDICTED(LOAD_GLOBAL); static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); + PyObject *res; PyObject *null = NULL; - PyObject *v; #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1614,30 +1752,30 @@ if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) { - v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), - (PyDictObject *)BUILTINS(), - name); - if (v == NULL) { + res = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), + (PyDictObject *)BUILTINS(), + name); + if (res == NULL) { if (!_PyErr_Occurred(tstate)) { /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } if (true) goto error; } - Py_INCREF(v); + Py_INCREF(res); } else { /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ - if (PyMapping_GetOptionalItem(GLOBALS(), name, &v) < 0) goto error; - if (v == NULL) { + if (PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0) goto error; + if (res == NULL) { /* namespace 2: builtins */ - if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) goto error; - if (v == NULL) { - format_exc_check_arg( + if (PyMapping_GetOptionalItem(BUILTINS(), name, &res) < 0) goto error; + if (res == NULL) { + _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); if (true) goto error; @@ -1647,17 +1785,16 @@ null = NULL; STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = v; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } next_instr += 4; DISPATCH(); } TARGET(LOAD_GLOBAL_MODULE) { - PyObject *_tmp_1; - PyObject *_tmp_2; - { - } + PyObject *res; + PyObject *null = NULL; + // _GUARD_GLOBALS_VERSION { uint16_t version = read_u16(&next_instr[1].cache); PyDictObject *dict = (PyDictObject *)GLOBALS(); @@ -1665,11 +1802,8 @@ DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); assert(DK_IS_UNICODE(dict->ma_keys)); } + // _LOAD_GLOBAL_MODULE { - } - { - PyObject *null = NULL; - PyObject *res; uint16_t index = read_u16(&next_instr[3].cache); PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); @@ -1678,22 +1812,19 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - if (oparg & 1) { _tmp_2 = null; } - _tmp_1 = res; } - next_instr += 4; STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = _tmp_1; - if (oparg & 1) { stack_pointer[-2] = _tmp_2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + next_instr += 4; DISPATCH(); } TARGET(LOAD_GLOBAL_BUILTIN) { - PyObject *_tmp_1; - PyObject *_tmp_2; - { - } + PyObject *res; + PyObject *null = NULL; + // _GUARD_GLOBALS_VERSION { uint16_t version = read_u16(&next_instr[1].cache); PyDictObject *dict = (PyDictObject *)GLOBALS(); @@ -1701,6 +1832,7 @@ DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); assert(DK_IS_UNICODE(dict->ma_keys)); } + // _GUARD_BUILTINS_VERSION { uint16_t version = read_u16(&next_instr[2].cache); PyDictObject *dict = (PyDictObject *)BUILTINS(); @@ -1708,9 +1840,8 @@ DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); assert(DK_IS_UNICODE(dict->ma_keys)); } + // _LOAD_GLOBAL_BUILTINS { - PyObject *null = NULL; - PyObject *res; uint16_t index = read_u16(&next_instr[3].cache); PyDictObject *bdict = (PyDictObject *)BUILTINS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); @@ -1719,14 +1850,12 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - if (oparg & 1) { _tmp_2 = null; } - _tmp_1 = res; } - next_instr += 4; STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = _tmp_1; - if (oparg & 1) { stack_pointer[-2] = _tmp_2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + next_instr += 4; DISPATCH(); } @@ -1755,7 +1884,7 @@ // Can't use ERROR_IF here. // Fortunately we don't need its superpower. if (oldobj == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); goto error; } PyCell_SET(cell, NULL); @@ -1764,8 +1893,9 @@ } TARGET(LOAD_FROM_DICT_OR_DEREF) { - PyObject *class_dict = stack_pointer[-1]; + PyObject *class_dict; PyObject *value; + class_dict = stack_pointer[-1]; PyObject *name; assert(class_dict); assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); @@ -1779,7 +1909,7 @@ PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); goto error; } Py_INCREF(value); @@ -1793,7 +1923,7 @@ PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); if (true) goto error; } Py_INCREF(value); @@ -1803,7 +1933,8 @@ } TARGET(STORE_DEREF) { - PyObject *v = stack_pointer[-1]; + PyObject *v; + v = stack_pointer[-1]; PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); PyCell_SET(cell, v); @@ -1827,8 +1958,9 @@ } TARGET(BUILD_STRING) { - PyObject **pieces = (stack_pointer - oparg); + PyObject **pieces; PyObject *str; + pieces = stack_pointer - oparg; str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); for (int _i = oparg; --_i >= 0;) { Py_DECREF(pieces[_i]); @@ -1841,8 +1973,9 @@ } TARGET(BUILD_TUPLE) { - PyObject **values = (stack_pointer - oparg); + PyObject **values; PyObject *tup; + values = stack_pointer - oparg; tup = _PyTuple_FromArraySteal(values, oparg); if (tup == NULL) { STACK_SHRINK(oparg); goto error; } STACK_SHRINK(oparg); @@ -1852,8 +1985,9 @@ } TARGET(BUILD_LIST) { - PyObject **values = (stack_pointer - oparg); + PyObject **values; PyObject *list; + values = stack_pointer - oparg; list = _PyList_FromArraySteal(values, oparg); if (list == NULL) { STACK_SHRINK(oparg); goto error; } STACK_SHRINK(oparg); @@ -1863,8 +1997,10 @@ } TARGET(LIST_EXTEND) { - PyObject *iterable = stack_pointer[-1]; - PyObject *list = stack_pointer[-(2 + (oparg-1))]; + PyObject *iterable; + PyObject *list; + iterable = stack_pointer[-1]; + list = stack_pointer[-2 - (oparg-1)]; PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && @@ -1885,8 +2021,10 @@ } TARGET(SET_UPDATE) { - PyObject *iterable = stack_pointer[-1]; - PyObject *set = stack_pointer[-(2 + (oparg-1))]; + PyObject *iterable; + PyObject *set; + iterable = stack_pointer[-1]; + set = stack_pointer[-2 - (oparg-1)]; int err = _PySet_Update(set, iterable); Py_DECREF(iterable); if (err < 0) goto pop_1_error; @@ -1895,8 +2033,9 @@ } TARGET(BUILD_SET) { - PyObject **values = (stack_pointer - oparg); + PyObject **values; PyObject *set; + values = stack_pointer - oparg; set = PySet_New(NULL); if (set == NULL) goto error; @@ -1918,15 +2057,13 @@ } TARGET(BUILD_MAP) { - PyObject **values = (stack_pointer - oparg*2); + PyObject **values; PyObject *map; + values = stack_pointer - oparg*2; map = _PyDict_FromItems( values, 2, values+1, 2, oparg); - if (map == NULL) - goto error; - for (int _i = oparg*2; --_i >= 0;) { Py_DECREF(values[_i]); } @@ -1979,9 +2116,11 @@ } TARGET(BUILD_CONST_KEY_MAP) { - PyObject *keys = stack_pointer[-1]; - PyObject **values = (stack_pointer - (1 + oparg)); + PyObject *keys; + PyObject **values; PyObject *map; + keys = stack_pointer[-1]; + values = stack_pointer - 1 - oparg; if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -2002,8 +2141,10 @@ } TARGET(DICT_UPDATE) { - PyObject *update = stack_pointer[-1]; - PyObject *dict = PEEK(oparg + 1); // update is still on the stack + PyObject *update; + PyObject *dict; + update = stack_pointer[-1]; + dict = stack_pointer[-2 - (oparg - 1)]; if (PyDict_Update(dict, update) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { _PyErr_Format(tstate, PyExc_TypeError, @@ -2019,11 +2160,14 @@ } TARGET(DICT_MERGE) { - PyObject *update = stack_pointer[-1]; - PyObject *dict = PEEK(oparg + 1); // update is still on the stack - + PyObject *update; + PyObject *dict; + PyObject *callable; + update = stack_pointer[-1]; + dict = stack_pointer[-2 - (oparg - 1)]; + callable = stack_pointer[-5 - (oparg - 1)]; if (_PyDict_MergeEx(dict, update, 2) < 0) { - format_kwargs_error(tstate, PEEK(3 + oparg), update); + _PyEval_FormatKwargsError(tstate, callable, update); Py_DECREF(update); if (true) goto pop_1_error; } @@ -2033,9 +2177,12 @@ } TARGET(MAP_ADD) { - PyObject *value = stack_pointer[-1]; - PyObject *key = stack_pointer[-2]; - PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack + PyObject *value; + PyObject *key; + PyObject *dict; + value = stack_pointer[-1]; + key = stack_pointer[-2]; + dict = stack_pointer[-3 - (oparg - 1)]; assert(PyDict_CheckExact(dict)); /* dict[key] = value */ // Do not DECREF INPUTS because the function steals the references @@ -2055,11 +2202,14 @@ TARGET(LOAD_SUPER_ATTR) { PREDICTED(LOAD_SUPER_ATTR); static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size"); - PyObject *self = stack_pointer[-1]; - PyObject *class = stack_pointer[-2]; - PyObject *global_super = stack_pointer[-3]; - PyObject *res2 = NULL; - PyObject *res; + PyObject *self; + PyObject *class; + PyObject *global_super; + PyObject *attr; + PyObject *null = NULL; + self = stack_pointer[-1]; + class = stack_pointer[-2]; + global_super = stack_pointer[-3]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); int load_method = oparg & 1; #if ENABLE_SPECIALIZATION @@ -2105,47 +2255,51 @@ Py_DECREF(class); Py_DECREF(self); if (super == NULL) goto pop_3_error; - res = PyObject_GetAttr(super, name); + attr = PyObject_GetAttr(super, name); Py_DECREF(super); - if (res == NULL) goto pop_3_error; + if (attr == NULL) goto pop_3_error; + null = NULL; STACK_SHRINK(2); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } next_instr += 1; DISPATCH(); } TARGET(LOAD_SUPER_ATTR_ATTR) { - PyObject *self = stack_pointer[-1]; - PyObject *class = stack_pointer[-2]; - PyObject *global_super = stack_pointer[-3]; - PyObject *res2 = NULL; - PyObject *res; + PyObject *self; + PyObject *class; + PyObject *global_super; + PyObject *attr; + self = stack_pointer[-1]; + class = stack_pointer[-2]; + global_super = stack_pointer[-3]; assert(!(oparg & 1)); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); - res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); + attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - if (res == NULL) goto pop_3_error; + if (attr == NULL) goto pop_3_error; STACK_SHRINK(2); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1] = attr; next_instr += 1; DISPATCH(); } TARGET(LOAD_SUPER_ATTR_METHOD) { - PyObject *self = stack_pointer[-1]; - PyObject *class = stack_pointer[-2]; - PyObject *global_super = stack_pointer[-3]; - PyObject *res2; - PyObject *res; + PyObject *self; + PyObject *class; + PyObject *global_super; + PyObject *attr; + PyObject *self_or_null; + self = stack_pointer[-1]; + class = stack_pointer[-2]; + global_super = stack_pointer[-3]; assert(oparg & 1); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); @@ -2153,24 +2307,23 @@ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); PyTypeObject *cls = (PyTypeObject *)class; int method_found = 0; - res2 = _PySuper_Lookup(cls, self, name, - cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); + attr = _PySuper_Lookup(cls, self, name, + Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); Py_DECREF(global_super); Py_DECREF(class); - if (res2 == NULL) { + if (attr == NULL) { Py_DECREF(self); if (true) goto pop_3_error; } if (method_found) { - res = self; // transfer ownership + self_or_null = self; // transfer ownership } else { Py_DECREF(self); - res = res2; - res2 = NULL; + self_or_null = NULL; } STACK_SHRINK(1); - stack_pointer[-1] = res; - stack_pointer[-2] = res2; + stack_pointer[-2] = attr; + stack_pointer[-1] = self_or_null; next_instr += 1; DISPATCH(); } @@ -2178,9 +2331,10 @@ TARGET(LOAD_ATTR) { PREDICTED(LOAD_ATTR); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); - PyObject *owner = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; + PyObject *owner; + PyObject *attr; + PyObject *self_or_null = NULL; + owner = stack_pointer[-1]; #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2195,16 +2349,15 @@ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ - PyObject* meth = NULL; - if (_PyObject_GetMethod(owner, name, &meth)) { + attr = NULL; + if (_PyObject_GetMethod(owner, name, &attr)) { /* We can bypass temporary bound method object. meth is unbound method and obj is self. meth | self | arg1 | ... | argN */ - assert(meth != NULL); // No errors on this branch - res2 = meth; - res = owner; // Transfer ownership + assert(attr != NULL); // No errors on this branch + self_or_null = owner; // Transfer ownership } else { /* meth is not an unbound method (but a regular attr, or @@ -2215,186 +2368,210 @@ NULL | meth | arg1 | ... | argN */ Py_DECREF(owner); - if (meth == NULL) goto pop_1_error; - res2 = NULL; - res = meth; + if (attr == NULL) goto pop_1_error; + self_or_null = NULL; } } else { /* Classic, pushes one value. */ - res = PyObject_GetAttr(owner, name); + attr = PyObject_GetAttr(owner, name); Py_DECREF(owner); - if (res == NULL) goto pop_1_error; + if (attr == NULL) goto pop_1_error; } STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = self_or_null; } next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_INSTANCE_VALUE) { - PyObject *_tmp_1; - PyObject *_tmp_2 = stack_pointer[-1]; - { - } + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; { - PyObject *owner = _tmp_2; uint32_t type_version = read_u32(&next_instr[1].cache); PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - _tmp_2 = owner; } + // _CHECK_MANAGED_OBJECT_HAS_VALUES { - PyObject *owner = _tmp_2; assert(Py_TYPE(owner)->tp_dictoffset < 0); assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - _tmp_2 = owner; + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); } + // _LOAD_ATTR_INSTANCE_VALUE { - PyObject *owner = _tmp_2; - PyObject *res2 = NULL; - PyObject *res; uint16_t index = read_u16(&next_instr[3].cache); PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - res = _PyDictOrValues_GetValues(dorv)->values[index]; - DEOPT_IF(res == NULL, LOAD_ATTR); + attr = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(attr == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; + Py_INCREF(attr); + null = NULL; Py_DECREF(owner); - if (oparg & 1) { _tmp_2 = res2; } - _tmp_1 = res; } - next_instr += 9; STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = _tmp_1; - if (oparg & 1) { stack_pointer[-2] = _tmp_2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_MODULE) { - PyObject *owner = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint16_t index = read_u16(&next_instr[3].cache); - DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); - PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; - assert(dict != NULL); - DEOPT_IF(dict->ma_keys->dk_version != type_version, LOAD_ATTR); - assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); - assert(index < dict->ma_keys->dk_nentries); - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index; - res = ep->me_value; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; - Py_DECREF(owner); + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + // _CHECK_ATTR_MODULE + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict != NULL); + DEOPT_IF(dict->ma_keys->dk_version != type_version, LOAD_ATTR); + } + // _LOAD_ATTR_MODULE + { + uint16_t index = read_u16(&next_instr[3].cache); + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + assert(index < dict->ma_keys->dk_nentries); + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index; + attr = ep->me_value; + DEOPT_IF(attr == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); + } STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_WITH_HINT) { - PyObject *owner = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint16_t index = read_u16(&next_instr[3].cache); - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); - DEOPT_IF(dict == NULL, LOAD_ATTR); - assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - uint16_t hint = index; - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); - if (DK_IS_UNICODE(dict->ma_keys)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); } - else { - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; + // _CHECK_ATTR_WITH_HINT + { + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, LOAD_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + } + // _LOAD_ATTR_WITH_HINT + { + uint16_t hint = read_u16(&next_instr[3].cache); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + attr = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + attr = ep->me_value; + } + DEOPT_IF(attr == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); } - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; - Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_SLOT) { - PyObject *owner = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint16_t index = read_u16(&next_instr[3].cache); - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - char *addr = (char *)owner + index; - res = *(PyObject **)addr; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; - Py_DECREF(owner); + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + } + // _LOAD_ATTR_SLOT + { + uint16_t index = read_u16(&next_instr[3].cache); + char *addr = (char *)owner + index; + attr = *(PyObject **)addr; + DEOPT_IF(attr == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); + } STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_CLASS) { - PyObject *cls = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - - DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); - DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, - LOAD_ATTR); - assert(type_version != 0); - - STAT_INC(LOAD_ATTR, hit); - res2 = NULL; - res = descr; - assert(res != NULL); - Py_INCREF(res); - Py_DECREF(cls); + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + // _CHECK_ATTR_CLASS + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + DEOPT_IF(!PyType_Check(owner), LOAD_ATTR); + assert(type_version != 0); + DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, LOAD_ATTR); + } + // _LOAD_ATTR_CLASS + { + PyObject *descr = read_obj(&next_instr[5].cache); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + attr = Py_NewRef(descr); + null = NULL; + Py_DECREF(owner); + } STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; + if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_PROPERTY) { - PyObject *owner = stack_pointer[-1]; + PyObject *owner; + owner = stack_pointer[-1]; uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *fget = read_obj(&next_instr[5].cache); + assert((oparg & 1) == 0); DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); @@ -2411,9 +2588,7 @@ Py_INCREF(fget); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); // Manipulate stack directly because we exit with DISPATCH_INLINED(). - SET_TOP(NULL); - int shrink_stack = !(oparg & 1); - STACK_SHRINK(shrink_stack); + STACK_SHRINK(1); new_frame->localsplus[0] = owner; SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; @@ -2421,10 +2596,12 @@ } TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { - PyObject *owner = stack_pointer[-1]; + PyObject *owner; + owner = stack_pointer[-1]; uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *getattribute = read_obj(&next_instr[5].cache); + assert((oparg & 1) == 0); DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); @@ -2442,9 +2619,7 @@ Py_INCREF(f); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2); // Manipulate stack directly because we exit with DISPATCH_INLINED(). - SET_TOP(NULL); - int shrink_stack = !(oparg & 1); - STACK_SHRINK(shrink_stack); + STACK_SHRINK(1); new_frame->localsplus[0] = owner; new_frame->localsplus[1] = Py_NewRef(name); SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); @@ -2453,35 +2628,49 @@ } TARGET(STORE_ATTR_INSTANCE_VALUE) { - PyObject *owner = stack_pointer[-1]; - PyObject *value = stack_pointer[-2]; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint16_t index = read_u16(&next_instr[3].cache); - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); - STAT_INC(STORE_ATTR, hit); - PyDictValues *values = _PyDictOrValues_GetValues(dorv); - PyObject *old_value = values->values[index]; - values->values[index] = value; - if (old_value == NULL) { - _PyDictValues_AddToInsertionOrder(values, index); + PyObject *owner; + PyObject *value; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); } - else { - Py_DECREF(old_value); + // _GUARD_DORV_VALUES + { + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); + } + // _STORE_ATTR_INSTANCE_VALUE + value = stack_pointer[-2]; + { + uint16_t index = read_u16(&next_instr[3].cache); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + STAT_INC(STORE_ATTR, hit); + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyObject *old_value = values->values[index]; + values->values[index] = value; + if (old_value == NULL) { + _PyDictValues_AddToInsertionOrder(values, index); + } + else { + Py_DECREF(old_value); + } + Py_DECREF(owner); } - Py_DECREF(owner); STACK_SHRINK(2); next_instr += 4; DISPATCH(); } TARGET(STORE_ATTR_WITH_HINT) { - PyObject *owner = stack_pointer[-1]; - PyObject *value = stack_pointer[-2]; + PyObject *owner; + PyObject *value; + owner = stack_pointer[-1]; + value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t hint = read_u16(&next_instr[3].cache); PyTypeObject *tp = Py_TYPE(owner); @@ -2528,19 +2717,27 @@ } TARGET(STORE_ATTR_SLOT) { - PyObject *owner = stack_pointer[-1]; - PyObject *value = stack_pointer[-2]; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint16_t index = read_u16(&next_instr[3].cache); - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); - char *addr = (char *)owner + index; - STAT_INC(STORE_ATTR, hit); - PyObject *old_value = *(PyObject **)addr; - *(PyObject **)addr = value; - Py_XDECREF(old_value); - Py_DECREF(owner); + PyObject *owner; + PyObject *value; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + } + // _STORE_ATTR_SLOT + value = stack_pointer[-2]; + { + uint16_t index = read_u16(&next_instr[3].cache); + char *addr = (char *)owner + index; + STAT_INC(STORE_ATTR, hit); + PyObject *old_value = *(PyObject **)addr; + *(PyObject **)addr = value; + Py_XDECREF(old_value); + Py_DECREF(owner); + } STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2549,9 +2746,11 @@ TARGET(COMPARE_OP) { PREDICTED(COMPARE_OP); static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2580,9 +2779,11 @@ } TARGET(COMPARE_OP_FLOAT) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2601,9 +2802,11 @@ } TARGET(COMPARE_OP_INT) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); @@ -2626,9 +2829,11 @@ } TARGET(COMPARE_OP_STR) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *res; + right = stack_pointer[-1]; + left = stack_pointer[-2]; DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2648,9 +2853,11 @@ } TARGET(IS_OP) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *b; + right = stack_pointer[-1]; + left = stack_pointer[-2]; int res = Py_Is(left, right) ^ oparg; Py_DECREF(left); Py_DECREF(right); @@ -2661,9 +2868,11 @@ } TARGET(CONTAINS_OP) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *b; + right = stack_pointer[-1]; + left = stack_pointer[-2]; int res = PySequence_Contains(right, left); Py_DECREF(left); Py_DECREF(right); @@ -2675,11 +2884,13 @@ } TARGET(CHECK_EG_MATCH) { - PyObject *match_type = stack_pointer[-1]; - PyObject *exc_value = stack_pointer[-2]; + PyObject *match_type; + PyObject *exc_value; PyObject *rest; PyObject *match; - if (check_except_star_type_valid(tstate, match_type) < 0) { + match_type = stack_pointer[-1]; + exc_value = stack_pointer[-2]; + if (_PyEval_CheckExceptStarTypeValid(tstate, match_type) < 0) { Py_DECREF(exc_value); Py_DECREF(match_type); if (true) goto pop_2_error; @@ -2687,8 +2898,8 @@ match = NULL; rest = NULL; - int res = exception_group_match(exc_value, match_type, - &match, &rest); + int res = _PyEval_ExceptionGroupMatch(exc_value, match_type, + &match, &rest); Py_DECREF(exc_value); Py_DECREF(match_type); if (res < 0) goto pop_2_error; @@ -2699,17 +2910,19 @@ if (!Py_IsNone(match)) { PyErr_SetHandledException(match); } - stack_pointer[-1] = match; stack_pointer[-2] = rest; + stack_pointer[-1] = match; DISPATCH(); } TARGET(CHECK_EXC_MATCH) { - PyObject *right = stack_pointer[-1]; - PyObject *left = stack_pointer[-2]; + PyObject *right; + PyObject *left; PyObject *b; + right = stack_pointer[-1]; + left = stack_pointer[-2]; assert(PyExceptionInstance_Check(left)); - if (check_except_type_valid(tstate, right) < 0) { + if (_PyEval_CheckExceptTypeValid(tstate, right) < 0) { Py_DECREF(right); if (true) goto pop_1_error; } @@ -2722,9 +2935,11 @@ } TARGET(IMPORT_NAME) { - PyObject *fromlist = stack_pointer[-1]; - PyObject *level = stack_pointer[-2]; + PyObject *fromlist; + PyObject *level; PyObject *res; + fromlist = stack_pointer[-1]; + level = stack_pointer[-2]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); res = import_name(tstate, frame, name, fromlist, level); Py_DECREF(level); @@ -2736,8 +2951,9 @@ } TARGET(IMPORT_FROM) { - PyObject *from = stack_pointer[-1]; + PyObject *from; PyObject *res; + from = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); res = import_from(tstate, from, name); if (res == NULL) goto error; @@ -2758,16 +2974,19 @@ JUMPBY(1-oparg); #if ENABLE_SPECIALIZATION here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER); - if (here[1].cache > tstate->interp->optimizer_backedge_threshold) { - OBJECT_STAT_INC(optimization_attempts); - frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer); - if (frame == NULL) { - frame = cframe.current_frame; - goto resume_with_error; + if (here[1].cache > tstate->interp->optimizer_backedge_threshold && + // Double-check that the opcode isn't instrumented or something: + here->op.code == JUMP_BACKWARD) + { + OPT_STAT_INC(attempts); + int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer); + if (optimized < 0) goto error; + if (optimized) { + // Rewind and enter the executor: + assert(here->op.code == ENTER_EXECUTOR); + next_instr = here; } - assert(frame == cframe.current_frame); - here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) -1); - goto resume_frame; + here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); } #endif /* ENABLE_SPECIALIZATION */ DISPATCH(); @@ -2784,33 +3003,47 @@ Py_INCREF(executor); frame = executor->execute(executor, frame, stack_pointer); if (frame == NULL) { - frame = cframe.current_frame; + frame = tstate->current_frame; goto resume_with_error; } goto resume_frame; } TARGET(POP_JUMP_IF_FALSE) { - PyObject *cond = stack_pointer[-1]; + PyObject *cond; + cond = stack_pointer[-1]; assert(PyBool_Check(cond)); - JUMPBY(oparg * Py_IsFalse(cond)); + int flag = Py_IsFalse(cond); + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif + JUMPBY(oparg * flag); STACK_SHRINK(1); + next_instr += 1; DISPATCH(); } TARGET(POP_JUMP_IF_TRUE) { - PyObject *cond = stack_pointer[-1]; + PyObject *cond; + cond = stack_pointer[-1]; assert(PyBool_Check(cond)); - JUMPBY(oparg * Py_IsTrue(cond)); + int flag = Py_IsTrue(cond); + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif + JUMPBY(oparg * flag); STACK_SHRINK(1); + next_instr += 1; DISPATCH(); } TARGET(POP_JUMP_IF_NONE) { - PyObject *_tmp_1 = stack_pointer[-1]; + PyObject *value; + PyObject *b; + PyObject *cond; + // _IS_NONE + value = stack_pointer[-1]; { - PyObject *value = _tmp_1; - PyObject *b; if (Py_IsNone(value)) { b = Py_True; } @@ -2818,22 +3051,29 @@ b = Py_False; Py_DECREF(value); } - _tmp_1 = b; } + // POP_JUMP_IF_TRUE + cond = b; { - PyObject *cond = _tmp_1; assert(PyBool_Check(cond)); - JUMPBY(oparg * Py_IsTrue(cond)); + int flag = Py_IsTrue(cond); + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif + JUMPBY(oparg * flag); } STACK_SHRINK(1); + next_instr += 1; DISPATCH(); } TARGET(POP_JUMP_IF_NOT_NONE) { - PyObject *_tmp_1 = stack_pointer[-1]; + PyObject *value; + PyObject *b; + PyObject *cond; + // _IS_NONE + value = stack_pointer[-1]; { - PyObject *value = _tmp_1; - PyObject *b; if (Py_IsNone(value)) { b = Py_True; } @@ -2841,14 +3081,19 @@ b = Py_False; Py_DECREF(value); } - _tmp_1 = b; } + // POP_JUMP_IF_FALSE + cond = b; { - PyObject *cond = _tmp_1; assert(PyBool_Check(cond)); - JUMPBY(oparg * Py_IsFalse(cond)); + int flag = Py_IsFalse(cond); + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif + JUMPBY(oparg * flag); } STACK_SHRINK(1); + next_instr += 1; DISPATCH(); } @@ -2863,8 +3108,9 @@ } TARGET(GET_LEN) { - PyObject *obj = stack_pointer[-1]; + PyObject *obj; PyObject *len_o; + obj = stack_pointer[-1]; // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; @@ -2876,14 +3122,17 @@ } TARGET(MATCH_CLASS) { - PyObject *names = stack_pointer[-1]; - PyObject *type = stack_pointer[-2]; - PyObject *subject = stack_pointer[-3]; + PyObject *names; + PyObject *type; + PyObject *subject; PyObject *attrs; + names = stack_pointer[-1]; + type = stack_pointer[-2]; + subject = stack_pointer[-3]; // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); - attrs = match_class(tstate, subject, type, oparg, names); + attrs = _PyEval_MatchClass(tstate, subject, type, oparg, names); Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); @@ -2900,8 +3149,9 @@ } TARGET(MATCH_MAPPING) { - PyObject *subject = stack_pointer[-1]; + PyObject *subject; PyObject *res; + subject = stack_pointer[-1]; int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = match ? Py_True : Py_False; STACK_GROW(1); @@ -2910,8 +3160,9 @@ } TARGET(MATCH_SEQUENCE) { - PyObject *subject = stack_pointer[-1]; + PyObject *subject; PyObject *res; + subject = stack_pointer[-1]; int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = match ? Py_True : Py_False; STACK_GROW(1); @@ -2920,11 +3171,13 @@ } TARGET(MATCH_KEYS) { - PyObject *keys = stack_pointer[-1]; - PyObject *subject = stack_pointer[-2]; + PyObject *keys; + PyObject *subject; PyObject *values_or_none; + keys = stack_pointer[-1]; + subject = stack_pointer[-2]; // On successful match, PUSH(values). Otherwise, PUSH(None). - values_or_none = match_keys(tstate, subject, keys); + values_or_none = _PyEval_MatchKeys(tstate, subject, keys); if (values_or_none == NULL) goto error; STACK_GROW(1); stack_pointer[-1] = values_or_none; @@ -2932,8 +3185,9 @@ } TARGET(GET_ITER) { - PyObject *iterable = stack_pointer[-1]; + PyObject *iterable; PyObject *iter; + iterable = stack_pointer[-1]; /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); Py_DECREF(iterable); @@ -2943,8 +3197,9 @@ } TARGET(GET_YIELD_FROM_ITER) { - PyObject *iterable = stack_pointer[-1]; + PyObject *iterable; PyObject *iter; + iterable = stack_pointer[-1]; /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -2976,8 +3231,9 @@ TARGET(FOR_ITER) { PREDICTED(FOR_ITER); static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); - PyObject *iter = stack_pointer[-1]; + PyObject *iter; PyObject *next; + iter = stack_pointer[-1]; #if ENABLE_SPECIALIZATION _PyForIterCache *cache = (_PyForIterCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -3045,15 +3301,15 @@ } TARGET(FOR_ITER_LIST) { - PyObject *_tmp_1; - PyObject *_tmp_2 = stack_pointer[-1]; + PyObject *iter; + PyObject *next; + // _ITER_CHECK_LIST + iter = stack_pointer[-1]; { - PyObject *iter = _tmp_2; DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); - _tmp_2 = iter; } + // _ITER_JUMP_LIST { - PyObject *iter = _tmp_2; _PyListIterObject *it = (_PyListIterObject *)iter; assert(Py_TYPE(iter) == &PyListIter_Type); STAT_INC(FOR_ITER, hit); @@ -3070,37 +3326,32 @@ JUMPBY(oparg + 1); DISPATCH(); } - _tmp_2 = iter; } + // _ITER_NEXT_LIST { - PyObject *iter = _tmp_2; - PyObject *next; _PyListIterObject *it = (_PyListIterObject *)iter; assert(Py_TYPE(iter) == &PyListIter_Type); PyListObject *seq = it->it_seq; assert(seq); assert(it->it_index < PyList_GET_SIZE(seq)); next = Py_NewRef(PyList_GET_ITEM(seq, it->it_index++)); - _tmp_2 = iter; - _tmp_1 = next; } - next_instr += 1; STACK_GROW(1); - stack_pointer[-1] = _tmp_1; - stack_pointer[-2] = _tmp_2; + stack_pointer[-1] = next; + next_instr += 1; DISPATCH(); } TARGET(FOR_ITER_TUPLE) { - PyObject *_tmp_1; - PyObject *_tmp_2 = stack_pointer[-1]; + PyObject *iter; + PyObject *next; + // _ITER_CHECK_TUPLE + iter = stack_pointer[-1]; { - PyObject *iter = _tmp_2; DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER); - _tmp_2 = iter; } + // _ITER_JUMP_TUPLE { - PyObject *iter = _tmp_2; _PyTupleIterObject *it = (_PyTupleIterObject *)iter; assert(Py_TYPE(iter) == &PyTupleIter_Type); STAT_INC(FOR_ITER, hit); @@ -3117,38 +3368,33 @@ JUMPBY(oparg + 1); DISPATCH(); } - _tmp_2 = iter; } + // _ITER_NEXT_TUPLE { - PyObject *iter = _tmp_2; - PyObject *next; _PyTupleIterObject *it = (_PyTupleIterObject *)iter; assert(Py_TYPE(iter) == &PyTupleIter_Type); PyTupleObject *seq = it->it_seq; assert(seq); assert(it->it_index < PyTuple_GET_SIZE(seq)); next = Py_NewRef(PyTuple_GET_ITEM(seq, it->it_index++)); - _tmp_2 = iter; - _tmp_1 = next; } - next_instr += 1; STACK_GROW(1); - stack_pointer[-1] = _tmp_1; - stack_pointer[-2] = _tmp_2; + stack_pointer[-1] = next; + next_instr += 1; DISPATCH(); } TARGET(FOR_ITER_RANGE) { - PyObject *_tmp_1; - PyObject *_tmp_2 = stack_pointer[-1]; + PyObject *iter; + PyObject *next; + // _ITER_CHECK_RANGE + iter = stack_pointer[-1]; { - PyObject *iter = _tmp_2; _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); - _tmp_2 = iter; } + // _ITER_JUMP_RANGE { - PyObject *iter = _tmp_2; _PyRangeIterObject *r = (_PyRangeIterObject *)iter; assert(Py_TYPE(r) == &PyRangeIter_Type); STAT_INC(FOR_ITER, hit); @@ -3160,11 +3406,9 @@ JUMPBY(oparg + 1); DISPATCH(); } - _tmp_2 = iter; } + // _ITER_NEXT_RANGE { - PyObject *iter = _tmp_2; - PyObject *next; _PyRangeIterObject *r = (_PyRangeIterObject *)iter; assert(Py_TYPE(r) == &PyRangeIter_Type); assert(r->len > 0); @@ -3173,25 +3417,22 @@ r->len--; next = PyLong_FromLong(value); if (next == NULL) goto error; - _tmp_2 = iter; - _tmp_1 = next; } - next_instr += 1; STACK_GROW(1); - stack_pointer[-1] = _tmp_1; - stack_pointer[-2] = _tmp_2; + stack_pointer[-1] = next; + next_instr += 1; DISPATCH(); } TARGET(FOR_ITER_GEN) { - PyObject *iter = stack_pointer[-1]; + PyObject *iter; + iter = stack_pointer[-1]; DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); STAT_INC(FOR_ITER, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - frame->return_offset = oparg; _PyFrame_StackPush(gen_frame, Py_None); gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; @@ -3199,13 +3440,15 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); + frame->return_offset = oparg; DISPATCH_INLINED(gen_frame); } TARGET(BEFORE_ASYNC_WITH) { - PyObject *mgr = stack_pointer[-1]; + PyObject *mgr; PyObject *exit; PyObject *res; + mgr = stack_pointer[-1]; PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3236,15 +3479,16 @@ if (true) goto pop_1_error; } STACK_GROW(1); - stack_pointer[-1] = res; stack_pointer[-2] = exit; + stack_pointer[-1] = res; DISPATCH(); } TARGET(BEFORE_WITH) { - PyObject *mgr = stack_pointer[-1]; + PyObject *mgr; PyObject *exit; PyObject *res; + mgr = stack_pointer[-1]; /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3278,16 +3522,19 @@ if (true) goto pop_1_error; } STACK_GROW(1); - stack_pointer[-1] = res; stack_pointer[-2] = exit; + stack_pointer[-1] = res; DISPATCH(); } TARGET(WITH_EXCEPT_START) { - PyObject *val = stack_pointer[-1]; - PyObject *lasti = stack_pointer[-3]; - PyObject *exit_func = stack_pointer[-4]; + PyObject *val; + PyObject *lasti; + PyObject *exit_func; PyObject *res; + val = stack_pointer[-1]; + lasti = stack_pointer[-3]; + exit_func = stack_pointer[-4]; /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3301,7 +3548,12 @@ assert(val && PyExceptionInstance_Check(val)); exc = PyExceptionInstance_Class(val); tb = PyException_GetTraceback(val); - Py_XDECREF(tb); + if (tb == NULL) { + tb = Py_None; + } + else { + Py_DECREF(tb); + } assert(PyLong_Check(lasti)); (void)lasti; // Shut up compiler warning if asserts are off PyObject *stack[4] = {NULL, exc, val, tb}; @@ -3314,8 +3566,9 @@ } TARGET(PUSH_EXC_INFO) { - PyObject *new_exc = stack_pointer[-1]; + PyObject *new_exc; PyObject *prev_exc; + new_exc = stack_pointer[-1]; _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3326,144 +3579,189 @@ assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); STACK_GROW(1); - stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; + stack_pointer[-1] = new_exc; DISPATCH(); } TARGET(LOAD_ATTR_METHOD_WITH_VALUES) { - PyObject *self = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint32_t keys_version = read_u32(&next_instr[3].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - assert(oparg & 1); - /* Cached method object */ - PyTypeObject *self_cls = Py_TYPE(self); - assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; - DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != - keys_version, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - res2 = Py_NewRef(descr); - assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); - res = self; + PyObject *owner; + PyObject *attr; + PyObject *self; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + } + // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT + { + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); + } + // _GUARD_KEYS_VERSION + { + uint32_t keys_version = read_u32(&next_instr[3].cache); + PyTypeObject *owner_cls = Py_TYPE(owner); + PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; + DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR); + } + // _LOAD_ATTR_METHOD_WITH_VALUES + { + PyObject *descr = read_obj(&next_instr[5].cache); + assert(oparg & 1); + /* Cached method object */ + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + attr = Py_NewRef(descr); + assert(_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + self = owner; + } STACK_GROW(1); - stack_pointer[-1] = res; - stack_pointer[-2] = res2; + stack_pointer[-2] = attr; + stack_pointer[-1] = self; next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_METHOD_NO_DICT) { - PyObject *self = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - assert(oparg & 1); - PyTypeObject *self_cls = Py_TYPE(self); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_dictoffset == 0); - STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); - res2 = Py_NewRef(descr); - res = self; + PyObject *owner; + PyObject *attr; + PyObject *self; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + } + // _LOAD_ATTR_METHOD_NO_DICT + { + PyObject *descr = read_obj(&next_instr[5].cache); + assert(oparg & 1); + assert(Py_TYPE(owner)->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + attr = Py_NewRef(descr); + self = owner; + } STACK_GROW(1); - stack_pointer[-1] = res; - stack_pointer[-2] = res2; + stack_pointer[-2] = attr; + stack_pointer[-1] = self; next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES) { - PyObject *self = stack_pointer[-1]; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint32_t keys_version = read_u32(&next_instr[3].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - assert((oparg & 1) == 0); - PyTypeObject *self_cls = Py_TYPE(self); - assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; - DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != - keys_version, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - Py_DECREF(self); - res = Py_NewRef(descr); - stack_pointer[-1] = res; + PyObject *owner; + PyObject *attr; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + } + // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT + { + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); + } + // _GUARD_KEYS_VERSION + { + uint32_t keys_version = read_u32(&next_instr[3].cache); + PyTypeObject *owner_cls = Py_TYPE(owner); + PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; + DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR); + } + // _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES + { + PyObject *descr = read_obj(&next_instr[5].cache); + assert((oparg & 1) == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + Py_DECREF(owner); + attr = Py_NewRef(descr); + } + stack_pointer[-1] = attr; next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) { - PyObject *self = stack_pointer[-1]; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - assert((oparg & 1) == 0); - PyTypeObject *self_cls = Py_TYPE(self); - assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(self_cls->tp_dictoffset == 0); - STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - Py_DECREF(self); - res = Py_NewRef(descr); - stack_pointer[-1] = res; + PyObject *owner; + PyObject *attr; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + } + // _LOAD_ATTR_NONDESCRIPTOR_NO_DICT + { + PyObject *descr = read_obj(&next_instr[5].cache); + assert((oparg & 1) == 0); + assert(Py_TYPE(owner)->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + Py_DECREF(owner); + attr = Py_NewRef(descr); + } + stack_pointer[-1] = attr; next_instr += 9; DISPATCH(); } TARGET(LOAD_ATTR_METHOD_LAZY_DICT) { - PyObject *self = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - assert(oparg & 1); - PyTypeObject *self_cls = Py_TYPE(self); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); - Py_ssize_t dictoffset = self_cls->tp_dictoffset; - assert(dictoffset > 0); - PyObject *dict = *(PyObject **)((char *)self + dictoffset); - /* This object has a __dict__, just not yet created */ - DEOPT_IF(dict != NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); - res2 = Py_NewRef(descr); - res = self; + PyObject *owner; + PyObject *attr; + PyObject *self; + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + } + // _CHECK_ATTR_METHOD_LAZY_DICT + { + Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset; + assert(dictoffset > 0); + PyObject *dict = *(PyObject **)((char *)owner + dictoffset); + /* This object has a __dict__, just not yet created */ + DEOPT_IF(dict != NULL, LOAD_ATTR); + } + // _LOAD_ATTR_METHOD_LAZY_DICT + { + PyObject *descr = read_obj(&next_instr[5].cache); + assert(oparg & 1); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + attr = Py_NewRef(descr); + self = owner; + } STACK_GROW(1); - stack_pointer[-1] = res; - stack_pointer[-2] = res2; + stack_pointer[-2] = attr; + stack_pointer[-1] = self; next_instr += 9; DISPATCH(); } - TARGET(KW_NAMES) { - ASSERT_KWNAMES_IS_NULL(); - assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS)); - kwnames = GETITEM(FRAME_CO_CONSTS, oparg); - DISPATCH(); - } - TARGET(INSTRUMENTED_CALL) { - int is_meth = PEEK(oparg+2) != NULL; + int is_meth = PEEK(oparg + 1) != NULL; int total_args = oparg + is_meth; - PyObject *function = PEEK(total_args + 1); + PyObject *function = PEEK(oparg + 2); PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING : PEEK(total_args); int err = _Py_call_instrumentation_2args( @@ -3478,14 +3776,16 @@ TARGET(CALL) { PREDICTED(CALL); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - int is_meth = method != NULL; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + // oparg counts all of the args, but *not* self: int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } @@ -3493,24 +3793,22 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { next_instr--; - _Py_Specialize_Call(callable, next_instr, total_args, kwnames); + _Py_Specialize_Call(callable, next_instr, total_args); DISPATCH_SAME_OPARG(); } STAT_INC(CALL, deferred); DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ - if (!is_meth && Py_TYPE(callable) == &PyMethod_Type) { - is_meth = 1; // For consistenct; it's dead, though + if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) { args--; total_args++; PyObject *self = ((PyMethodObject *)callable)->im_self; args[0] = Py_NewRef(self); - method = ((PyMethodObject *)callable)->im_func; + PyObject *method = ((PyMethodObject *)callable)->im_func; args[-1] = Py_NewRef(method); Py_DECREF(callable); callable = method; } - int positional_args = total_args - KWNAMES_LEN(); // Check if the call can be inlined or not if (Py_TYPE(callable) == &PyFunction_Type && tstate->interp->eval_frame == NULL && @@ -3520,9 +3818,8 @@ PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( tstate, (PyFunctionObject *)callable, locals, - args, positional_args, kwnames + args, total_args, NULL ); - kwnames = NULL; // Manipulate stack directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); // The frame has stolen all the arguments from the stack, @@ -3537,11 +3834,11 @@ /* Callable is not a normal Python function */ res = PyObject_Vectorcall( callable, args, - positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, - kwnames); + total_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + NULL); if (opcode == INSTRUMENTED_CALL) { PyObject *arg = total_args == 0 ? - &_PyInstrumentation_MISSING : PEEK(total_args); + &_PyInstrumentation_MISSING : args[0]; if (res == NULL) { _Py_call_instrumentation_exc2( tstate, PY_MONITORING_EVENT_C_RAISE, @@ -3556,7 +3853,6 @@ } } } - kwnames = NULL; assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); Py_DECREF(callable); for (int i = 0; i < total_args; i++) { @@ -3572,63 +3868,181 @@ } TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; - DEOPT_IF(method != NULL, CALL); - DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); - STAT_INC(CALL, hit); - PyObject *self = ((PyMethodObject *)callable)->im_self; - PEEK(oparg + 1) = Py_NewRef(self); // callable - PyObject *meth = ((PyMethodObject *)callable)->im_func; - PEEK(oparg + 2) = Py_NewRef(meth); // method - Py_DECREF(callable); - GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); + PyObject *null; + PyObject *callable; + PyObject *self; + PyObject *self_or_null; + PyObject *func; + PyObject **args; + _PyInterpreterFrame *new_frame; + // _CHECK_PEP_523 + { + DEOPT_IF(tstate->interp->eval_frame, CALL); + } + // _CHECK_CALL_BOUND_METHOD_EXACT_ARGS + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + { + DEOPT_IF(null != NULL, CALL); + DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); + } + // _INIT_CALL_BOUND_METHOD_EXACT_ARGS + { + STAT_INC(CALL, hit); + self = Py_NewRef(((PyMethodObject *)callable)->im_self); + stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _INIT_CALL_PY_EXACT_ARGS + func = Py_NewRef(((PyMethodObject *)callable)->im_func); + stack_pointer[-2 - oparg] = func; // This is used by CALL, upon deoptimization + Py_DECREF(callable); + } + // _CHECK_FUNCTION_EXACT_ARGS + self_or_null = self; + callable = func; + { + uint32_t func_version = read_u32(&next_instr[1].cache); + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL); + } + // _CHECK_STACK_SPACE + { + PyFunctionObject *func = (PyFunctionObject *)callable; + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL); + } + // _INIT_CALL_PY_EXACT_ARGS + args = stack_pointer - oparg; + { + int argcount = oparg; + if (self_or_null != NULL) { + args--; + argcount++; + } + STAT_INC(CALL, hit); + PyFunctionObject *func = (PyFunctionObject *)callable; + new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; + } + } + // _SAVE_CURRENT_IP + next_instr += 3; + { + TIER_ONE_ONLY + frame->prev_instr = next_instr - 1; + } + // _PUSH_FRAME + STACK_SHRINK(oparg); + STACK_SHRINK(2); + { + // Write it out explicitly because it's subtly different. + // Eventually this should be the only occurrence of this code. + frame->return_offset = 0; + assert(tstate->interp->eval_frame == NULL); + STORE_SP(); + new_frame->previous = frame; + CALL_STAT_INC(inlined_py_calls); + frame = tstate->current_frame = new_frame; + tstate->py_recursion_remaining--; + LOAD_SP(); + LOAD_IP(); + #if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } + #endif + } + DISPATCH(); } TARGET(CALL_PY_EXACT_ARGS) { - PREDICTED(CALL_PY_EXACT_ARGS); - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; - uint32_t func_version = read_u32(&next_instr[1].cache); - ASSERT_KWNAMES_IS_NULL(); - DEOPT_IF(tstate->interp->eval_frame, CALL); - int is_meth = method != NULL; - int argcount = oparg; - if (is_meth) { - callable = method; - args--; - argcount++; + PyObject *self_or_null; + PyObject *callable; + PyObject **args; + _PyInterpreterFrame *new_frame; + // _CHECK_PEP_523 + { + DEOPT_IF(tstate->interp->eval_frame, CALL); } - DEOPT_IF(!PyFunction_Check(callable), CALL); - PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != func_version, CALL); - PyCodeObject *code = (PyCodeObject *)func->func_code; - DEOPT_IF(code->co_argcount != argcount, CALL); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); - STAT_INC(CALL, hit); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); - for (int i = 0; i < argcount; i++) { - new_frame->localsplus[i] = args[i]; + // _CHECK_FUNCTION_EXACT_ARGS + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + { + uint32_t func_version = read_u32(&next_instr[1].cache); + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL); + } + // _CHECK_STACK_SPACE + { + PyFunctionObject *func = (PyFunctionObject *)callable; + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL); } - // Manipulate stack directly since we leave using DISPATCH_INLINED(). - STACK_SHRINK(oparg + 2); - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); + // _INIT_CALL_PY_EXACT_ARGS + args = stack_pointer - oparg; + { + int argcount = oparg; + if (self_or_null != NULL) { + args--; + argcount++; + } + STAT_INC(CALL, hit); + PyFunctionObject *func = (PyFunctionObject *)callable; + new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; + } + } + // _SAVE_CURRENT_IP + next_instr += 3; + { + TIER_ONE_ONLY + frame->prev_instr = next_instr - 1; + } + // _PUSH_FRAME + STACK_SHRINK(oparg); + STACK_SHRINK(2); + { + // Write it out explicitly because it's subtly different. + // Eventually this should be the only occurrence of this code. + frame->return_offset = 0; + assert(tstate->interp->eval_frame == NULL); + STORE_SP(); + new_frame->previous = frame; + CALL_STAT_INC(inlined_py_calls); + frame = tstate->current_frame = new_frame; + tstate->py_recursion_remaining--; + LOAD_SP(); + LOAD_IP(); + #if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } + #endif + } + DISPATCH(); } TARGET(CALL_PY_WITH_DEFAULTS) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject **args; + PyObject *self_or_null; + PyObject *callable; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; uint32_t func_version = read_u32(&next_instr[1].cache); - ASSERT_KWNAMES_IS_NULL(); DEOPT_IF(tstate->interp->eval_frame, CALL); - int is_meth = method != NULL; int argcount = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; argcount++; } @@ -3660,12 +4074,14 @@ DISPATCH_INLINED(new_frame); } - TARGET(CALL_NO_KW_TYPE_1) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *null = stack_pointer[-(2 + oparg)]; + TARGET(CALL_TYPE_1) { + PyObject **args; + PyObject *null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 1); DEOPT_IF(null != NULL, CALL); PyObject *obj = args[0]; @@ -3681,12 +4097,14 @@ DISPATCH(); } - TARGET(CALL_NO_KW_STR_1) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *null = stack_pointer[-(2 + oparg)]; + TARGET(CALL_STR_1) { + PyObject **args; + PyObject *null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 1); DEOPT_IF(null != NULL, CALL); DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); @@ -3704,12 +4122,14 @@ DISPATCH(); } - TARGET(CALL_NO_KW_TUPLE_1) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *null = stack_pointer[-(2 + oparg)]; + TARGET(CALL_TUPLE_1) { + PyObject **args; + PyObject *null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 1); DEOPT_IF(null != NULL, CALL); DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); @@ -3727,16 +4147,18 @@ DISPATCH(); } - TARGET(CALL_NO_KW_ALLOC_AND_ENTER_INIT) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *null = stack_pointer[-(2 + oparg)]; + TARGET(CALL_ALLOC_AND_ENTER_INIT) { + PyObject **args; + PyObject *null; + PyObject *callable; + args = stack_pointer - oparg; + null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* This instruction does the following: * 1. Creates the object (by calling ``object.__new__``) * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) * 3. Pushes the frame for ``__init__`` to the frame stack * */ - ASSERT_KWNAMES_IS_NULL(); _PyCallCache *cache = (_PyCallCache *)next_instr; DEOPT_IF(null != NULL, CALL); DEOPT_IF(!PyType_Check(callable), CALL); @@ -3754,7 +4176,7 @@ } Py_DECREF(tp); _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( - tstate, (PyCodeObject *)&_Py_InitCleanup, 1, 0); + tstate, (PyCodeObject *)&_Py_InitCleanup, 1); assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK); /* Push self onto stack of shim */ Py_INCREF(self); @@ -3774,7 +4196,7 @@ /* Link frames */ init_frame->previous = shim; shim->previous = frame; - frame = cframe.current_frame = init_frame; + frame = tstate->current_frame = init_frame; CALL_STAT_INC(inlined_py_calls); /* Account for pushing the extra frame. * We don't check recursion depth here, @@ -3784,7 +4206,8 @@ } TARGET(EXIT_INIT_CHECK) { - PyObject *should_be_none = stack_pointer[-1]; + PyObject *should_be_none; + should_be_none = stack_pointer[-1]; assert(STACK_LEVEL() == 2); if (should_be_none != Py_None) { PyErr_Format(PyExc_TypeError, @@ -3797,25 +4220,23 @@ } TARGET(CALL_BUILTIN_CLASS) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - int is_meth = method != NULL; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } - int kwnames_len = KWNAMES_LEN(); DEOPT_IF(!PyType_Check(callable), CALL); PyTypeObject *tp = (PyTypeObject *)callable; DEOPT_IF(tp->tp_vectorcall == NULL, CALL); STAT_INC(CALL, hit); - res = tp->tp_vectorcall((PyObject *)tp, args, - total_args - kwnames_len, kwnames); - kwnames = NULL; + res = tp->tp_vectorcall((PyObject *)tp, args, total_args, NULL); /* Free the arguments. */ for (int i = 0; i < total_args; i++) { Py_DECREF(args[i]); @@ -3830,17 +4251,17 @@ DISPATCH(); } - TARGET(CALL_NO_KW_BUILTIN_O) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + TARGET(CALL_BUILTIN_O) { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* Builtin METH_O functions */ - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } @@ -3870,17 +4291,17 @@ DISPATCH(); } - TARGET(CALL_NO_KW_BUILTIN_FAST) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + TARGET(CALL_BUILTIN_FAST) { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* Builtin METH_FASTCALL functions, without keywords */ - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } @@ -3915,34 +4336,28 @@ } TARGET(CALL_BUILTIN_FAST_WITH_KEYWORDS) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != - (METH_FASTCALL | METH_KEYWORDS), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS), CALL); STAT_INC(CALL, hit); /* res = func(self, args, nargs, kwnames) */ _PyCFunctionFastWithKeywords cfunc = (_PyCFunctionFastWithKeywords)(void(*)(void)) PyCFunction_GET_FUNCTION(callable); - res = cfunc( - PyCFunction_GET_SELF(callable), - args, - total_args - KWNAMES_LEN(), - kwnames - ); + res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - kwnames = NULL; /* Free the arguments. */ for (int i = 0; i < total_args; i++) { @@ -3958,22 +4373,22 @@ DISPATCH(); } - TARGET(CALL_NO_KW_LEN) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + TARGET(CALL_LEN) { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* len(o) */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } DEOPT_IF(total_args != 1, CALL); - PyInterpreterState *interp = _PyInterpreterState_GET(); + PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable != interp->callable_cache.len, CALL); STAT_INC(CALL, hit); PyObject *arg = args[0]; @@ -3994,22 +4409,22 @@ DISPATCH(); } - TARGET(CALL_NO_KW_ISINSTANCE) { - PyObject **args = (stack_pointer - oparg); - PyObject *callable = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; + TARGET(CALL_ISINSTANCE) { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; /* isinstance(o, o2) */ - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { - callable = method; + if (self_or_null != NULL) { args--; total_args++; } DEOPT_IF(total_args != 2, CALL); - PyInterpreterState *interp = _PyInterpreterState_GET(); + PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); STAT_INC(CALL, hit); PyObject *cls = args[1]; @@ -4032,22 +4447,24 @@ DISPATCH(); } - TARGET(CALL_NO_KW_LIST_APPEND) { - PyObject **args = (stack_pointer - oparg); - PyObject *self = stack_pointer[-(1 + oparg)]; - PyObject *method = stack_pointer[-(2 + oparg)]; - ASSERT_KWNAMES_IS_NULL(); + TARGET(CALL_LIST_APPEND) { + PyObject **args; + PyObject *self; + PyObject *callable; + args = stack_pointer - oparg; + self = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 1); - assert(method != NULL); - PyInterpreterState *interp = _PyInterpreterState_GET(); - DEOPT_IF(method != interp->callable_cache.list_append, CALL); + PyInterpreterState *interp = tstate->interp; + DEOPT_IF(callable != interp->callable_cache.list_append, CALL); + assert(self != NULL); DEOPT_IF(!PyList_Check(self), CALL); STAT_INC(CALL, hit); if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) { goto pop_1_error; // Since arg is DECREF'ed already } Py_DECREF(self); - Py_DECREF(method); + Py_DECREF(callable); STACK_SHRINK(3); // CALL + POP_TOP SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); @@ -4055,26 +4472,27 @@ DISPATCH(); } - TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { - PyObject **args = (stack_pointer - oparg); - PyObject *method = stack_pointer[-(2 + oparg)]; + TARGET(CALL_METHOD_DESCRIPTOR_O) { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; DEOPT_IF(total_args != 2, CALL); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; DEOPT_IF(meth->ml_flags != METH_O, CALL); PyObject *arg = args[1]; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall @@ -4098,30 +4516,31 @@ } TARGET(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { - PyObject **args = (stack_pointer - oparg); - PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - int is_meth = method != NULL; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); - PyTypeObject *d_type = callable->d_common.d_type; + PyTypeObject *d_type = method->d_common.d_type; PyObject *self = args[0]; DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); STAT_INC(CALL, hit); int nargs = total_args - 1; _PyCFunctionFastWithKeywords cfunc = (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; - res = cfunc(self, args + 1, nargs - KWNAMES_LEN(), kwnames); + res = cfunc(self, args + 1, nargs, NULL); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - kwnames = NULL; /* Free the arguments. */ for (int i = 0; i < total_args; i++) { @@ -4137,24 +4556,26 @@ DISPATCH(); } - TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { - PyObject **args = (stack_pointer - oparg); - PyObject *method = stack_pointer[-(2 + oparg)]; + TARGET(CALL_METHOD_DESCRIPTOR_NOARGS) { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; assert(oparg == 0 || oparg == 1); - int is_meth = method != NULL; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } DEOPT_IF(total_args != 1, CALL); - PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; @@ -4177,25 +4598,26 @@ DISPATCH(); } - TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) { - PyObject **args = (stack_pointer - oparg); - PyObject *method = stack_pointer[-(2 + oparg)]; + TARGET(CALL_METHOD_DESCRIPTOR_FAST) { + PyObject **args; + PyObject *self_or_null; + PyObject *callable; PyObject *res; - ASSERT_KWNAMES_IS_NULL(); - int is_meth = method != NULL; + args = stack_pointer - oparg; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; int total_args = oparg; - if (is_meth) { + if (self_or_null != NULL) { args--; total_args++; } - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; /* Builtin METH_FASTCALL methods, without keywords */ - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); - PyMethodDef *meth = callable->d_method; + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = method->d_method; DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); STAT_INC(CALL, hit); _PyCFunctionFast cfunc = (_PyCFunctionFast)(void(*)(void))meth->ml_meth; @@ -4216,16 +4638,118 @@ DISPATCH(); } + TARGET(INSTRUMENTED_CALL_KW) { + int is_meth = PEEK(oparg + 2) != NULL; + int total_args = oparg + is_meth; + PyObject *function = PEEK(oparg + 3); + PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING + : PEEK(total_args + 1); + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr - 1, function, arg); + if (err) goto error; + GO_TO_INSTRUCTION(CALL_KW); + } + + TARGET(CALL_KW) { + PREDICTED(CALL_KW); + PyObject *kwnames; + PyObject **args; + PyObject *self_or_null; + PyObject *callable; + PyObject *res; + kwnames = stack_pointer[-1]; + args = stack_pointer - 1 - oparg; + self_or_null = stack_pointer[-2 - oparg]; + callable = stack_pointer[-3 - oparg]; + // oparg counts all of the args, but *not* self: + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; + } + if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) { + args--; + total_args++; + PyObject *self = ((PyMethodObject *)callable)->im_self; + args[0] = Py_NewRef(self); + PyObject *method = ((PyMethodObject *)callable)->im_func; + args[-1] = Py_NewRef(method); + Py_DECREF(callable); + callable = method; + } + int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames); + // Check if the call can be inlined or not + if (Py_TYPE(callable) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)callable)->vectorcall == _PyFunction_Vectorcall) + { + int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( + tstate, (PyFunctionObject *)callable, locals, + args, positional_args, kwnames + ); + Py_DECREF(kwnames); + // Manipulate stack directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 3); + // The frame has stolen all the arguments from the stack, + // so there is no need to clean them up. + if (new_frame == NULL) { + goto error; + } + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + /* Callable is not a normal Python function */ + res = PyObject_Vectorcall( + callable, args, + positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames); + if (opcode == INSTRUMENTED_CALL_KW) { + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : args[0]; + if (res == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, callable, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, callable, arg); + if (err < 0) { + Py_CLEAR(res); + } + } + } + Py_DECREF(kwnames); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(callable); + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + if (res == NULL) { STACK_SHRINK(oparg); goto pop_3_error; } + STACK_SHRINK(oparg); + STACK_SHRINK(2); + stack_pointer[-1] = res; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { GO_TO_INSTRUCTION(CALL_FUNCTION_EX); } TARGET(CALL_FUNCTION_EX) { PREDICTED(CALL_FUNCTION_EX); - PyObject *kwargs = (oparg & 1) ? stack_pointer[-(((oparg & 1) ? 1 : 0))] : NULL; - PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; - PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; + PyObject *kwargs = NULL; + PyObject *callargs; + PyObject *func; PyObject *result; + if (oparg & 1) { kwargs = stack_pointer[-(oparg & 1 ? 1 : 0)]; } + callargs = stack_pointer[-1 - (oparg & 1 ? 1 : 0)]; + func = stack_pointer[-3 - (oparg & 1 ? 1 : 0)]; // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4290,7 +4814,7 @@ Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - assert(PEEK(3 + (oparg & 1)) == NULL); + assert(PEEK(2 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); @@ -4300,8 +4824,9 @@ } TARGET(MAKE_FUNCTION) { - PyObject *codeobj = stack_pointer[-1]; + PyObject *codeobj; PyObject *func; + codeobj = stack_pointer[-1]; PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4311,15 +4836,18 @@ goto error; } - func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; + _PyFunction_SetVersion( + func_obj, ((PyCodeObject *)codeobj)->co_version); func = (PyObject *)func_obj; stack_pointer[-1] = func; DISPATCH(); } TARGET(SET_FUNCTION_ATTRIBUTE) { - PyObject *func = stack_pointer[-1]; - PyObject *attr = stack_pointer[-2]; + PyObject *func; + PyObject *attr; + func = stack_pointer[-1]; + attr = stack_pointer[-2]; assert(PyFunction_Check(func)); PyFunctionObject *func_obj = (PyFunctionObject *)func; switch(oparg) { @@ -4367,16 +4895,19 @@ assert(frame != &entry_frame); _PyInterpreterFrame *prev = frame->previous; _PyThreadState_PopFrame(tstate, frame); - frame = cframe.current_frame = prev; + frame = tstate->current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; } TARGET(BUILD_SLICE) { - PyObject *step = (oparg == 3) ? stack_pointer[-(((oparg == 3) ? 1 : 0))] : NULL; - PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; - PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; + PyObject *step = NULL; + PyObject *stop; + PyObject *start; PyObject *slice; + if (oparg == 3) { step = stack_pointer[-(oparg == 3 ? 1 : 0)]; } + stop = stack_pointer[-1 - (oparg == 3 ? 1 : 0)]; + start = stack_pointer[-2 - (oparg == 3 ? 1 : 0)]; slice = PySlice_New(start, stop, step); Py_DECREF(start); Py_DECREF(stop); @@ -4389,8 +4920,9 @@ } TARGET(CONVERT_VALUE) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *result; + value = stack_pointer[-1]; convertion_func_ptr conv_fn; assert(oparg >= FVC_STR && oparg <= FVC_ASCII); conv_fn = CONVERSION_FUNCTIONS[oparg]; @@ -4402,8 +4934,9 @@ } TARGET(FORMAT_SIMPLE) { - PyObject *value = stack_pointer[-1]; + PyObject *value; PyObject *res; + value = stack_pointer[-1]; /* If value is a unicode object, then we know the result * of format(value) is value itself. */ if (!PyUnicode_CheckExact(value)) { @@ -4419,9 +4952,11 @@ } TARGET(FORMAT_WITH_SPEC) { - PyObject *fmt_spec = stack_pointer[-1]; - PyObject *value = stack_pointer[-2]; + PyObject *fmt_spec; + PyObject *value; PyObject *res; + fmt_spec = stack_pointer[-1]; + value = stack_pointer[-2]; res = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_DECREF(fmt_spec); @@ -4432,8 +4967,9 @@ } TARGET(COPY) { - PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; + PyObject *bottom; PyObject *top; + bottom = stack_pointer[-1 - (oparg-1)]; assert(oparg > 0); top = Py_NewRef(bottom); STACK_GROW(1); @@ -4444,9 +4980,11 @@ TARGET(BINARY_OP) { PREDICTED(BINARY_OP); static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); - PyObject *rhs = stack_pointer[-1]; - PyObject *lhs = stack_pointer[-2]; + PyObject *rhs; + PyObject *lhs; PyObject *res; + rhs = stack_pointer[-1]; + lhs = stack_pointer[-2]; #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4457,10 +4995,10 @@ STAT_INC(BINARY_OP, deferred); DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ - assert(0 <= oparg); - assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); - assert(binary_ops[oparg]); - res = binary_ops[oparg](lhs, rhs); + assert(NB_ADD <= oparg); + assert(oparg <= NB_INPLACE_XOR); + assert(_PyEval_BinaryOps[oparg]); + res = _PyEval_BinaryOps[oparg](lhs, rhs); Py_DECREF(lhs); Py_DECREF(rhs); if (res == NULL) goto pop_2_error; @@ -4471,11 +5009,13 @@ } TARGET(SWAP) { - PyObject *top = stack_pointer[-1]; - PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; + PyObject *top; + PyObject *bottom; + top = stack_pointer[-1]; + bottom = stack_pointer[-2 - (oparg-2)]; assert(oparg >= 2); + stack_pointer[-2 - (oparg-2)] = top; stack_pointer[-1] = bottom; - stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } @@ -4508,8 +5048,13 @@ PyObject *cond = POP(); assert(PyBool_Check(cond)); _Py_CODEUNIT *here = next_instr - 1; - int offset = Py_IsTrue(cond) * oparg; + int flag = Py_IsTrue(cond); + int offset = flag * oparg; + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + next_instr += 1; DISPATCH(); } @@ -4517,23 +5062,33 @@ PyObject *cond = POP(); assert(PyBool_Check(cond)); _Py_CODEUNIT *here = next_instr - 1; - int offset = Py_IsFalse(cond) * oparg; + int flag = Py_IsFalse(cond); + int offset = flag * oparg; + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + next_instr += 1; DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { PyObject *value = POP(); - _Py_CODEUNIT *here = next_instr-1; + _Py_CODEUNIT *here = next_instr - 1; + int flag = Py_IsNone(value); int offset; - if (Py_IsNone(value)) { + if (flag) { offset = oparg; } else { Py_DECREF(value); offset = 0; } + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | flag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + next_instr += 1; DISPATCH(); } @@ -4541,14 +5096,19 @@ PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; - if (Py_IsNone(value)) { + int nflag = Py_IsNone(value); + if (nflag) { offset = 0; } else { Py_DECREF(value); offset = oparg; } + #if ENABLE_SPECIALIZATION + next_instr->cache = (next_instr->cache << 1) | !nflag; + #endif INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + next_instr += 1; DISPATCH(); } diff --git a/Python/getargs.c b/Python/getargs.c index 45befab4f8bc37..d590e2e153389e 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2,16 +2,10 @@ /* New getargs implementation */ #include "Python.h" -#include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_dict.h" // _PyDict_HasOnlyStringKeys() #include "pycore_pylifecycle.h" // _PyArg_Fini - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif +#include "pycore_tuple.h" // _PyTuple_ITEMS() /* Export Stable ABIs (abi only) */ PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); @@ -1417,20 +1411,6 @@ _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyOb } -PyAPI_FUNC(int) -_PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, - struct _PyArg_Parser *parser, va_list va) -{ - int retval; - va_list lva; - - va_copy(lva, va); - - retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0); - va_end(lva); - return retval; -} - static void error_unexpected_keyword_arg(PyObject *kwargs, PyObject *kwnames, PyObject *kwtuple, const char *fname) { @@ -1504,7 +1484,6 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, int i, pos, len; int skip = 0; Py_ssize_t nargs, nkwargs; - PyObject *current_arg; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; @@ -1634,17 +1613,17 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, return cleanreturn(0, &freelist); } if (!skip) { + PyObject *current_arg; if (i < nargs) { - current_arg = PyTuple_GET_ITEM(args, i); + current_arg = Py_NewRef(PyTuple_GET_ITEM(args, i)); } else if (nkwargs && i >= pos) { - current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); + if (PyDict_GetItemStringRef(kwargs, kwlist[i], ¤t_arg) < 0) { + return cleanreturn(0, &freelist); + } if (current_arg) { --nkwargs; } - else if (PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } } else { current_arg = NULL; @@ -1653,6 +1632,7 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, if (current_arg) { msg = convertitem(current_arg, &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); + Py_DECREF(current_arg); if (msg) { seterror(i+1, msg, levels, fname, custom_msg); return cleanreturn(0, &freelist); @@ -1723,8 +1703,12 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, Py_ssize_t j; /* make sure there are no arguments given by name and position */ for (i = pos; i < nargs; i++) { - current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); + PyObject *current_arg; + if (PyDict_GetItemStringRef(kwargs, kwlist[i], ¤t_arg) < 0) { + return cleanreturn(0, &freelist); + } if (current_arg) { + Py_DECREF(current_arg); /* arg present in tuple and in dict */ PyErr_Format(PyExc_TypeError, "argument for %.200s%s given by name ('%s') " @@ -1734,9 +1718,6 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, kwlist[i], i+1); return cleanreturn(0, &freelist); } - else if (PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } } /* make sure there are no extraneous keyword arguments */ j = 0; @@ -1998,7 +1979,7 @@ find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key) /* kwname == key will normally find a match in since keyword keys should be interned strings; if not retry below in a new loop. */ if (kwname == key) { - return kwstack[i]; + return Py_NewRef(kwstack[i]); } } @@ -2006,7 +1987,7 @@ find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key) PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); assert(PyUnicode_Check(kwname)); if (_PyUnicode_EQ(kwname, key)) { - return kwstack[i]; + return Py_NewRef(kwstack[i]); } } return NULL; @@ -2026,7 +2007,6 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, PyObject *keyword; int i, pos, len; Py_ssize_t nkwargs; - PyObject *current_arg; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; PyObject *const *kwstack = NULL; @@ -2121,14 +2101,14 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, } assert(!IS_END_OF_FORMAT(*format)); + PyObject *current_arg; if (i < nargs) { - current_arg = args[i]; + current_arg = Py_NewRef(args[i]); } else if (nkwargs && i >= pos) { keyword = PyTuple_GET_ITEM(kwtuple, i - pos); if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { + if (PyDict_GetItemRef(kwargs, keyword, ¤t_arg) < 0) { return cleanreturn(0, &freelist); } } @@ -2146,6 +2126,7 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, if (current_arg) { msg = convertitem(current_arg, &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); + Py_DECREF(current_arg); if (msg) { seterror(i+1, msg, levels, parser->fname, parser->custom_msg); return cleanreturn(0, &freelist); @@ -2196,10 +2177,10 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, if (nkwargs > 0) { /* make sure there are no arguments given by name and position */ for (i = pos; i < nargs; i++) { + PyObject *current_arg; keyword = PyTuple_GET_ITEM(kwtuple, i - pos); if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { + if (PyDict_GetItemRef(kwargs, keyword, ¤t_arg) < 0) { return cleanreturn(0, &freelist); } } @@ -2207,6 +2188,7 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, current_arg = find_keyword(kwnames, kwstack, keyword); } if (current_arg) { + Py_DECREF(current_arg); /* arg present in tuple and in dict */ PyErr_Format(PyExc_TypeError, "argument for %.200s%s given by name ('%U') " @@ -2261,7 +2243,6 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, int i, posonly, minposonly, maxargs; int reqlimit = minkw ? maxpos + minkw : minpos; Py_ssize_t nkwargs; - PyObject *current_arg; PyObject * const *kwstack = NULL; assert(kwargs == NULL || PyDict_Check(kwargs)); @@ -2356,11 +2337,11 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, /* copy keyword args using kwtuple to drive process */ for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) { + PyObject *current_arg; if (nkwargs) { keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { + if (PyDict_GetItemRef(kwargs, keyword, ¤t_arg) < 0) { return NULL; } } @@ -2378,6 +2359,7 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, buf[i] = current_arg; if (current_arg) { + Py_DECREF(current_arg); --nkwargs; } else if (i < minpos || (maxpos <= i && i < reqlimit)) { @@ -2395,10 +2377,10 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, if (nkwargs > 0) { /* make sure there are no arguments given by name and position */ for (i = posonly; i < nargs; i++) { + PyObject *current_arg; keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { + if (PyDict_GetItemRef(kwargs, keyword, ¤t_arg) < 0) { return NULL; } } @@ -2406,6 +2388,7 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, current_arg = find_keyword(kwnames, kwstack, keyword); } if (current_arg) { + Py_DECREF(current_arg); /* arg present in tuple and in dict */ PyErr_Format(PyExc_TypeError, "argument for %.200s%s given by name ('%U') " @@ -2437,7 +2420,6 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, int i, posonly, minposonly, maxargs; int reqlimit = minkw ? maxpos + minkw : minpos; Py_ssize_t nkwargs; - PyObject *current_arg; PyObject * const *kwstack = NULL; assert(kwargs == NULL || PyDict_Check(kwargs)); @@ -2510,13 +2492,12 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, } /* copy keyword args using kwtuple to drive process */ - for (i = Py_MAX((int)nargs, posonly) - - Py_SAFE_DOWNCAST(varargssize, Py_ssize_t, int); i < maxargs; i++) { + for (i = Py_MAX((int)nargs, posonly) - Py_SAFE_DOWNCAST(varargssize, Py_ssize_t, int); i < maxargs; i++) { + PyObject *current_arg; if (nkwargs) { keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { + if (PyDict_GetItemRef(kwargs, keyword, ¤t_arg) < 0) { goto exit; } } @@ -2549,6 +2530,7 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, } if (current_arg) { + Py_DECREF(current_arg); --nkwargs; } else if (i < minpos || (maxpos <= i && i < reqlimit)) { @@ -2881,7 +2863,3 @@ _PyArg_Fini(void) } _PyRuntime.getargs.static_parsers = NULL; } - -#ifdef __cplusplus -}; -#endif diff --git a/Python/getopt.c b/Python/getopt.c index 4135bf1446ecfc..f64c89fa22734a 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -29,10 +29,6 @@ #include #include "pycore_getopt.h" -#ifdef __cplusplus -extern "C" { -#endif - int _PyOS_opterr = 1; /* generate error messages */ Py_ssize_t _PyOS_optind = 1; /* index into argv array */ const wchar_t *_PyOS_optarg = NULL; /* optional argument */ @@ -172,8 +168,3 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) return option; } - -#ifdef __cplusplus -} -#endif - diff --git a/Python/hamt.c b/Python/hamt.c index c78b5a7fab94f0..a8fbb00b807934 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -1,9 +1,10 @@ #include "Python.h" - -#include "pycore_bitutils.h" // _Py_popcount32 +#include "pycore_bitutils.h" // _Py_popcount32() #include "pycore_hamt.h" #include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_long.h" // _PyLong_Format() #include "pycore_object.h" // _PyObject_GC_TRACK() + #include // offsetof() /* @@ -514,7 +515,7 @@ hamt_node_bitmap_new(Py_ssize_t size) /* Since bitmap nodes are immutable, we can cache the instance for size=0 and reuse it whenever we need an empty bitmap node. */ - return (PyHamtNode *)Py_NewRef(&_Py_SINGLETON(hamt_bitmap_node_empty)); + return (PyHamtNode *)&_Py_SINGLETON(hamt_bitmap_node_empty); } assert(size >= 0); diff --git a/Python/hashtable.c b/Python/hashtable.c index 09501de199b0e6..8f5e8168ba1339 100644 --- a/Python/hashtable.c +++ b/Python/hashtable.c @@ -46,6 +46,7 @@ #include "Python.h" #include "pycore_hashtable.h" +#include "pycore_pyhash.h" // _Py_HashPointerRaw() #define HASHTABLE_MIN_SIZE 16 #define HASHTABLE_HIGH 0.50 @@ -128,6 +129,13 @@ _Py_hashtable_size(const _Py_hashtable_t *ht) } +size_t +_Py_hashtable_len(const _Py_hashtable_t *ht) +{ + return ht->nentries; +} + + _Py_hashtable_entry_t * _Py_hashtable_get_entry_generic(_Py_hashtable_t *ht, const void *key) { @@ -218,7 +226,6 @@ _Py_hashtable_set(_Py_hashtable_t *ht, const void *key, void *value) assert(entry == NULL); #endif - entry = ht->alloc.malloc(sizeof(_Py_hashtable_entry_t)); if (entry == NULL) { /* memory allocation failed */ diff --git a/Python/import.c b/Python/import.c index cf993cbd62a2ef..cafdd834502224 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1,11 +1,13 @@ /* Module definition and import implementation */ #include "Python.h" - +#include "pycore_dict.h" // _PyDict_Pop() +#include "pycore_hashtable.h" // _Py_hashtable_new_full() #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // struct _import_runtime_state #include "pycore_namespace.h" // _PyNamespace_Type +#include "pycore_object.h" // _Py_SetImmortal() #include "pycore_pyerrors.h" // _PyErr_SetString() #include "pycore_pyhash.h" // _Py_KeyedHash() #include "pycore_pylifecycle.h" @@ -13,17 +15,15 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_weakref.h" // _PyWeakref_GET_REF() + #include "marshal.h" // PyMarshal_ReadObjectFromString() -#include "importdl.h" // _PyImport_DynLoadFiletab +#include "pycore_importdl.h" // _PyImport_DynLoadFiletab #include "pydtrace.h" // PyDTrace_IMPORT_FIND_LOAD_START_ENABLED() #include // bool #ifdef HAVE_FCNTL_H #include #endif -#ifdef __cplusplus -extern "C" { -#endif /*[clinic input] @@ -210,17 +210,6 @@ PyImport_GetModuleDict(void) return MODULES(interp); } -// This is only kept around for extensions that use _Py_IDENTIFIER. -PyObject * -_PyImport_GetModuleId(_Py_Identifier *nameid) -{ - PyObject *name = _PyUnicode_FromId(nameid); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyImport_GetModule(name); -} - int _PyImport_SetModule(PyObject *name, PyObject *m) { @@ -610,7 +599,7 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp) when an extension is loaded. This includes when it is imported for the first time. - Here's a summary, using importlib._boostrap._load() as a starting point. + Here's a summary, using importlib._bootstrap._load() as a starting point. 1. importlib._bootstrap._load() 2. _load(): acquire import lock @@ -916,35 +905,79 @@ extensions_lock_release(void) dictionary, to avoid loading shared libraries twice. */ +static void * +hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep) +{ + Py_ssize_t str1_len, str2_len; + const char *str1_data = PyUnicode_AsUTF8AndSize(str1, &str1_len); + const char *str2_data = PyUnicode_AsUTF8AndSize(str2, &str2_len); + if (str1_data == NULL || str2_data == NULL) { + return NULL; + } + /* Make sure sep and the NULL byte won't cause an overflow. */ + assert(SIZE_MAX - str1_len - str2_len > 2); + size_t size = str1_len + 1 + str2_len + 1; + + char *key = PyMem_RawMalloc(size); + if (key == NULL) { + PyErr_NoMemory(); + return NULL; + } + + strncpy(key, str1_data, str1_len); + key[str1_len] = sep; + strncpy(key + str1_len + 1, str2_data, str2_len + 1); + assert(strlen(key) == size - 1); + return key; +} + +static Py_uhash_t +hashtable_hash_str(const void *key) +{ + return _Py_HashBytes(key, strlen((const char *)key)); +} + +static int +hashtable_compare_str(const void *key1, const void *key2) +{ + return strcmp((const char *)key1, (const char *)key2) == 0; +} + static void -_extensions_cache_init(void) +hashtable_destroy_str(void *ptr) { - /* The runtime (i.e. main interpreter) must be initializing, - so we don't need to worry about the lock. */ - _PyThreadState_InitDetached(&EXTENSIONS.main_tstate, - _PyInterpreterState_Main()); + PyMem_RawFree(ptr); } +#define HTSEP ':' + static PyModuleDef * _extensions_cache_get(PyObject *filename, PyObject *name) { PyModuleDef *def = NULL; + void *key = NULL; extensions_lock_acquire(); - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { + if (EXTENSIONS.hashtable == NULL) { goto finally; } - PyObject *extensions = EXTENSIONS.dict; - if (extensions == NULL) { + key = hashtable_key_from_2_strings(filename, name, HTSEP); + if (key == NULL) { + goto finally; + } + _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry( + EXTENSIONS.hashtable, key); + if (entry == NULL) { goto finally; } - def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); + def = (PyModuleDef *)entry->value; finally: - Py_XDECREF(key); extensions_lock_release(); + if (key != NULL) { + PyMem_RawFree(key); + } return def; } @@ -952,124 +985,100 @@ static int _extensions_cache_set(PyObject *filename, PyObject *name, PyModuleDef *def) { int res = -1; - PyThreadState *oldts = NULL; extensions_lock_acquire(); - /* Swap to the main interpreter, if necessary. This matters if - the dict hasn't been created yet or if the item isn't in the - dict yet. In both cases we must ensure the relevant objects - are created using the main interpreter. */ - PyThreadState *main_tstate = &EXTENSIONS.main_tstate; - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (!_Py_IsMainInterpreter(interp)) { - _PyThreadState_BindDetached(main_tstate); - oldts = _PyThreadState_Swap(interp->runtime, main_tstate); - assert(!_Py_IsMainInterpreter(oldts->interp)); - - /* Make sure the name and filename objects are owned - by the main interpreter. */ - name = PyUnicode_InternFromString(PyUnicode_AsUTF8(name)); - assert(name != NULL); - filename = PyUnicode_InternFromString(PyUnicode_AsUTF8(filename)); - assert(filename != NULL); + if (EXTENSIONS.hashtable == NULL) { + _Py_hashtable_allocator_t alloc = {PyMem_RawMalloc, PyMem_RawFree}; + EXTENSIONS.hashtable = _Py_hashtable_new_full( + hashtable_hash_str, + hashtable_compare_str, + hashtable_destroy_str, // key + /* There's no need to decref the def since it's immortal. */ + NULL, // value + &alloc + ); + if (EXTENSIONS.hashtable == NULL) { + PyErr_NoMemory(); + goto finally; + } } - PyObject *key = PyTuple_Pack(2, filename, name); + void *key = hashtable_key_from_2_strings(filename, name, HTSEP); if (key == NULL) { goto finally; } - PyObject *extensions = EXTENSIONS.dict; - if (extensions == NULL) { - extensions = PyDict_New(); - if (extensions == NULL) { + int already_set = 0; + _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry( + EXTENSIONS.hashtable, key); + if (entry == NULL) { + if (_Py_hashtable_set(EXTENSIONS.hashtable, key, def) < 0) { + PyMem_RawFree(key); + PyErr_NoMemory(); goto finally; } - EXTENSIONS.dict = extensions; - } - - PyModuleDef *actual = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); - if (PyErr_Occurred()) { - goto finally; } - else if (actual != NULL) { - /* We expect it to be static, so it must be the same pointer. */ - assert(def == actual); - res = 0; - goto finally; + else { + if (entry->value == NULL) { + entry->value = def; + } + else { + /* We expect it to be static, so it must be the same pointer. */ + assert((PyModuleDef *)entry->value == def); + already_set = 1; + } + PyMem_RawFree(key); } - - /* This might trigger a resize, which is why we must switch - to the main interpreter. */ - res = PyDict_SetItem(extensions, key, (PyObject *)def); - if (res < 0) { - res = -1; - goto finally; + if (!already_set) { + /* We assume that all module defs are statically allocated + and will never be freed. Otherwise, we would incref here. */ + _Py_SetImmortal(def); } res = 0; finally: - Py_XDECREF(key); - if (oldts != NULL) { - _PyThreadState_Swap(interp->runtime, oldts); - _PyThreadState_UnbindDetached(main_tstate); - Py_DECREF(name); - Py_DECREF(filename); - } extensions_lock_release(); return res; } -static int +static void _extensions_cache_delete(PyObject *filename, PyObject *name) { - int res = -1; - PyThreadState *oldts = NULL; + void *key = NULL; extensions_lock_acquire(); - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { + if (EXTENSIONS.hashtable == NULL) { + /* It was never added. */ goto finally; } - PyObject *extensions = EXTENSIONS.dict; - if (extensions == NULL) { - res = 0; + key = hashtable_key_from_2_strings(filename, name, HTSEP); + if (key == NULL) { goto finally; } - PyModuleDef *actual = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); - if (PyErr_Occurred()) { + _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry( + EXTENSIONS.hashtable, key); + if (entry == NULL) { + /* It was never added. */ goto finally; } - else if (actual == NULL) { - /* It was already removed or never added. */ - res = 0; + if (entry->value == NULL) { + /* It was already removed. */ goto finally; } - - /* Swap to the main interpreter, if necessary. */ - PyThreadState *main_tstate = &EXTENSIONS.main_tstate; - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (!_Py_IsMainInterpreter(interp)) { - _PyThreadState_BindDetached(main_tstate); - oldts = _PyThreadState_Swap(interp->runtime, main_tstate); - assert(!_Py_IsMainInterpreter(oldts->interp)); - } - - if (PyDict_DelItem(extensions, key) < 0) { - goto finally; - } - res = 0; + /* If we hadn't made the stored defs immortal, we would decref here. + However, this decref would be problematic if the module def were + dynamically allocated, it were the last ref, and this function + were called with an interpreter other than the def's owner. */ + assert(_Py_IsImmortal(entry->value)); + entry->value = NULL; finally: - if (oldts != NULL) { - _PyThreadState_Swap(interp->runtime, oldts); - _PyThreadState_UnbindDetached(main_tstate); - } - Py_XDECREF(key); extensions_lock_release(); - return res; + if (key != NULL) { + PyMem_RawFree(key); + } } static void @@ -1077,11 +1086,12 @@ _extensions_cache_clear_all(void) { /* The runtime (i.e. main interpreter) must be finalizing, so we don't need to worry about the lock. */ - // XXX assert(_Py_IsMainInterpreter(_PyInterpreterState_GET())); - Py_CLEAR(EXTENSIONS.dict); - _PyThreadState_ClearDetached(&EXTENSIONS.main_tstate); + _Py_hashtable_destroy(EXTENSIONS.hashtable); + EXTENSIONS.hashtable = NULL; } +#undef HTSEP + static bool check_multi_interp_extensions(PyInterpreterState *interp) @@ -1226,6 +1236,15 @@ import_find_extension(PyThreadState *tstate, PyObject *name, return NULL; } + /* It may have been successfully imported previously + in an interpreter that allows legacy modules + but is not allowed in the current interpreter. */ + const char *name_buf = PyUnicode_AsUTF8(name); + assert(name_buf != NULL); + if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) { + return NULL; + } + PyObject *mod, *mdict; PyObject *modules = MODULES(tstate->interp); @@ -1233,6 +1252,8 @@ import_find_extension(PyThreadState *tstate, PyObject *name, PyObject *m_copy = def->m_base.m_copy; /* Module does not support repeated initialization */ if (m_copy == NULL) { + /* It might be a core module (e.g. sys & builtins), + for which we don't set m_copy. */ m_copy = get_core_module_dict(tstate->interp, name, filename); if (m_copy == NULL) { return NULL; @@ -1302,9 +1323,7 @@ clear_singlephase_extension(PyInterpreterState *interp, } /* Clear the cached module def. */ - if (_extensions_cache_delete(filename, name) < 0) { - return -1; - } + _extensions_cache_delete(filename, name); return 0; } @@ -1984,7 +2003,6 @@ look_up_frozen(const char *name) struct frozen_info { PyObject *nameobj; const char *data; - PyObject *(*get_code)(void); Py_ssize_t size; bool is_package; bool is_alias; @@ -2018,7 +2036,6 @@ find_frozen(PyObject *nameobj, struct frozen_info *info) if (info != NULL) { info->nameobj = nameobj; // borrowed info->data = (const char *)p->code; - info->get_code = p->get_code; info->size = p->size; info->is_package = p->is_package; if (p->size < 0) { @@ -2030,10 +2047,6 @@ find_frozen(PyObject *nameobj, struct frozen_info *info) info->is_alias = resolve_module_alias(name, _PyImport_FrozenAliases, &info->origname); } - if (p->code == NULL && p->size == 0 && p->get_code != NULL) { - /* It is only deepfrozen. */ - return FROZEN_OKAY; - } if (p->code == NULL) { /* It is frozen but marked as un-importable. */ return FROZEN_EXCLUDED; @@ -2048,11 +2061,6 @@ find_frozen(PyObject *nameobj, struct frozen_info *info) static PyObject * unmarshal_frozen_code(PyInterpreterState *interp, struct frozen_info *info) { - if (info->get_code && _Py_IsMainInterpreter(interp)) { - PyObject *code = info->get_code(); - assert(code != NULL); - return code; - } PyObject *co = PyMarshal_ReadObjectFromString(info->data, info->size); if (co == NULL) { /* Does not contain executable code. */ @@ -2352,9 +2360,14 @@ get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, PyObject *importer; Py_ssize_t j, nhooks; - /* These conditions are the caller's responsibility: */ - assert(PyList_Check(path_hooks)); - assert(PyDict_Check(path_importer_cache)); + if (!PyList_Check(path_hooks)) { + PyErr_SetString(PyExc_RuntimeError, "sys.path_hooks is not a list"); + return NULL; + } + if (!PyDict_Check(path_importer_cache)) { + PyErr_SetString(PyExc_RuntimeError, "sys.path_importer_cache is not a dict"); + return NULL; + } nhooks = PyList_Size(path_hooks); if (nhooks < 0) @@ -2397,11 +2410,22 @@ PyImport_GetImporter(PyObject *path) { PyThreadState *tstate = _PyThreadState_GET(); PyObject *path_importer_cache = PySys_GetObject("path_importer_cache"); + if (path_importer_cache == NULL) { + PyErr_SetString(PyExc_RuntimeError, "lost sys.path_importer_cache"); + return NULL; + } + Py_INCREF(path_importer_cache); PyObject *path_hooks = PySys_GetObject("path_hooks"); - if (path_importer_cache == NULL || path_hooks == NULL) { + if (path_hooks == NULL) { + PyErr_SetString(PyExc_RuntimeError, "lost sys.path_hooks"); + Py_DECREF(path_importer_cache); return NULL; } - return get_path_importer(tstate, path_importer_cache, path_hooks, path); + Py_INCREF(path_hooks); + PyObject *importer = get_path_importer(tstate, path_importer_cache, path_hooks, path); + Py_DECREF(path_hooks); + Py_DECREF(path_importer_cache); + return importer; } @@ -2413,12 +2437,11 @@ int _PyImport_InitDefaultImportFunc(PyInterpreterState *interp) { // Get the __import__ function - PyObject *import_func = _PyDict_GetItemStringWithError(interp->builtins, - "__import__"); - if (import_func == NULL) { + PyObject *import_func; + if (PyDict_GetItemStringRef(interp->builtins, "__import__", &import_func) <= 0) { return -1; } - IMPORT_FUNC(interp) = Py_NewRef(import_func); + IMPORT_FUNC(interp) = import_func; return 0; } @@ -2877,12 +2900,11 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, } } else { - PyObject *path; - if (PyObject_GetOptionalAttr(mod, &_Py_ID(__path__), &path) < 0) { + int has_path = PyObject_HasAttrWithError(mod, &_Py_ID(__path__)); + if (has_path < 0) { goto error; } - if (path) { - Py_DECREF(path); + if (has_path) { final_mod = PyObject_CallMethodObjArgs( IMPORTLIB(interp), &_Py_ID(_handle_fromlist), mod, fromlist, IMPORT_FUNC(interp), NULL); @@ -3053,6 +3075,8 @@ void _PyImport_Fini(void) { /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ + // XXX Should we actually leave them (mostly) intact, since we don't + // ever dlclose() the module files? _extensions_cache_clear_all(); /* Use the same memory allocator as _PyImport_Init(). */ @@ -3090,10 +3114,6 @@ _PyImport_Fini2(void) PyStatus _PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib) { - if (_Py_IsMainInterpreter(tstate->interp)) { - _extensions_cache_init(); - } - // XXX Initialize here: interp->modules and interp->import_func. // XXX Initialize here: sys.modules and sys.meta_path. @@ -3548,7 +3568,7 @@ _imp_get_frozen_object_impl(PyObject *module, PyObject *name, if (info.nameobj == NULL) { info.nameobj = name; } - if (info.size == 0 && info.get_code == NULL) { + if (info.size == 0) { /* Does not contain executable code. */ set_frozen_error(FROZEN_INVALID, name); return NULL; @@ -3715,16 +3735,8 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) PyThreadState *tstate = _PyThreadState_GET(); mod = import_find_extension(tstate, name, path); - if (mod != NULL) { - const char *name_buf = PyUnicode_AsUTF8(name); - assert(name_buf != NULL); - if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) { - Py_DECREF(mod); - mod = NULL; - } - goto finally; - } - else if (PyErr_Occurred()) { + if (mod != NULL || _PyErr_Occurred(tstate)) { + assert(mod == NULL || !_PyErr_Occurred(tstate)); goto finally; } @@ -3872,8 +3884,3 @@ PyInit__imp(void) { return PyModuleDef_Init(&imp_module); } - - -#ifdef __cplusplus -} -#endif diff --git a/Python/importdl.c b/Python/importdl.c index 9ab0a5ad33aaac..7dfd301d77efb4 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -15,7 +15,7 @@ */ #ifdef HAVE_DYNAMIC_LOADING -#include "importdl.h" +#include "pycore_importdl.h" #ifdef MS_WINDOWS extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, diff --git a/Python/importdl.h b/Python/importdl.h deleted file mode 100644 index 9171adc2770689..00000000000000 --- a/Python/importdl.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef Py_IMPORTDL_H -#define Py_IMPORTDL_H - -#ifdef __cplusplus -extern "C" { -#endif - - -extern const char *_PyImport_DynLoadFiletab[]; - -extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *); - -typedef PyObject *(*PyModInitFunction)(void); - -/* Max length of module suffix searched for -- accommodates "module.slb" */ -#define MAXSUFFIXSIZE 12 - -#ifdef MS_WINDOWS -#include -typedef FARPROC dl_funcptr; -#else -typedef void (*dl_funcptr)(void); -#endif - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_IMPORTDL_H */ diff --git a/Python/initconfig.c b/Python/initconfig.c index 787e583262406c..f7eb8535e98a6a 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -9,6 +9,7 @@ #include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig() #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_pystats.h" // _Py_StatsOn() #include "osdefs.h" // DELIM @@ -23,6 +24,106 @@ # endif #endif +/* --- PyConfig spec ---------------------------------------------- */ + +typedef enum { + PyConfig_MEMBER_INT = 0, + PyConfig_MEMBER_UINT = 1, + PyConfig_MEMBER_ULONG = 2, + + PyConfig_MEMBER_WSTR = 10, + PyConfig_MEMBER_WSTR_OPT = 11, + PyConfig_MEMBER_WSTR_LIST = 12, +} PyConfigMemberType; + +typedef struct { + const char *name; + size_t offset; + PyConfigMemberType type; +} PyConfigSpec; + +#define SPEC(MEMBER, TYPE) \ + {#MEMBER, offsetof(PyConfig, MEMBER), PyConfig_MEMBER_##TYPE} + +static const PyConfigSpec PYCONFIG_SPEC[] = { + SPEC(_config_init, UINT), + SPEC(isolated, UINT), + SPEC(use_environment, UINT), + SPEC(dev_mode, UINT), + SPEC(install_signal_handlers, UINT), + SPEC(use_hash_seed, UINT), + SPEC(hash_seed, ULONG), + SPEC(faulthandler, UINT), + SPEC(tracemalloc, UINT), + SPEC(perf_profiling, UINT), + SPEC(import_time, UINT), + SPEC(code_debug_ranges, UINT), + SPEC(show_ref_count, UINT), + SPEC(dump_refs, UINT), + SPEC(dump_refs_file, WSTR_OPT), + SPEC(malloc_stats, UINT), + SPEC(filesystem_encoding, WSTR), + SPEC(filesystem_errors, WSTR), + SPEC(pycache_prefix, WSTR_OPT), + SPEC(parse_argv, UINT), + SPEC(orig_argv, WSTR_LIST), + SPEC(argv, WSTR_LIST), + SPEC(xoptions, WSTR_LIST), + SPEC(warnoptions, WSTR_LIST), + SPEC(site_import, UINT), + SPEC(bytes_warning, UINT), + SPEC(warn_default_encoding, UINT), + SPEC(inspect, UINT), + SPEC(interactive, UINT), + SPEC(optimization_level, UINT), + SPEC(parser_debug, UINT), + SPEC(write_bytecode, UINT), + SPEC(verbose, UINT), + SPEC(quiet, UINT), + SPEC(user_site_directory, UINT), + SPEC(configure_c_stdio, UINT), + SPEC(buffered_stdio, UINT), + SPEC(stdio_encoding, WSTR), + SPEC(stdio_errors, WSTR), +#ifdef MS_WINDOWS + SPEC(legacy_windows_stdio, UINT), +#endif + SPEC(check_hash_pycs_mode, WSTR), + SPEC(use_frozen_modules, UINT), + SPEC(safe_path, UINT), + SPEC(int_max_str_digits, INT), + SPEC(cpu_count, INT), + SPEC(pathconfig_warnings, UINT), + SPEC(program_name, WSTR), + SPEC(pythonpath_env, WSTR_OPT), + SPEC(home, WSTR_OPT), + SPEC(platlibdir, WSTR), + SPEC(sys_path_0, WSTR_OPT), + SPEC(module_search_paths_set, UINT), + SPEC(module_search_paths, WSTR_LIST), + SPEC(stdlib_dir, WSTR_OPT), + SPEC(executable, WSTR_OPT), + SPEC(base_executable, WSTR_OPT), + SPEC(prefix, WSTR_OPT), + SPEC(base_prefix, WSTR_OPT), + SPEC(exec_prefix, WSTR_OPT), + SPEC(base_exec_prefix, WSTR_OPT), + SPEC(skip_source_first_line, UINT), + SPEC(run_command, WSTR_OPT), + SPEC(run_module, WSTR_OPT), + SPEC(run_filename, WSTR_OPT), + SPEC(_install_importlib, UINT), + SPEC(_init_main, UINT), + SPEC(_is_python_build, UINT), +#ifdef Py_STATS + SPEC(_pystats, UINT), +#endif + {NULL, 0, 0}, +}; + +#undef SPEC + + /* --- Command line options --------------------------------------- */ /* Short usage message (with %s for argv0) */ @@ -129,7 +230,11 @@ The following implementation-specific options are available:\n\ \n\ -X int_max_str_digits=number: limit the size of int<->str conversions.\n\ This helps avoid denial of service attacks when parsing untrusted data.\n\ - The default is sys.int_info.default_max_str_digits. 0 disables." + The default is sys.int_info.default_max_str_digits. 0 disables.\n\ +\n\ +-X cpu_count=[n|default]: Override the return value of os.cpu_count(),\n\ + os.process_cpu_count(), and multiprocessing.cpu_count(). This can help users who need\n\ + to limit resources in a container." #ifdef Py_STATS "\n\ @@ -167,6 +272,8 @@ static const char usage_envvars[] = " locale coercion and locale compatibility warnings on stderr.\n" "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n" " debugger. It can be set to the callable of your debugger of choice.\n" +"PYTHON_CPU_COUNT: Overrides the return value of os.process_cpu_count(),\n" +" os.cpu_count(), and multiprocessing.cpu_count() if set to a positive integer.\n" "PYTHONDEVMODE: enable the development mode.\n" "PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n" "PYTHONWARNDEFAULTENCODING: enable opt-in EncodingWarning for 'encoding=None'.\n" @@ -186,7 +293,11 @@ static const char usage_envvars[] = "PYTHONSAFEPATH : don't prepend a potentially unsafe path to sys.path (-P)\n" "PYTHONUNBUFFERED : disable stdout/stderr buffering (-u)\n" "PYTHONVERBOSE : trace import statements (-v)\n" -"PYTHONWARNINGS=arg : warning control (-W arg)\n"; +"PYTHONWARNINGS=arg : warning control (-W arg)\n" +#ifdef Py_STATS +"PYTHONSTATS : turns on statistics gathering\n" +#endif +; #if defined(MS_WINDOWS) # define PYTHONHOMEHELP "\\python{major}{minor}" @@ -335,21 +446,34 @@ int PyStatus_IsExit(PyStatus status) int PyStatus_Exception(PyStatus status) { return _PyStatus_EXCEPTION(status); } -PyObject* +void _PyErr_SetFromPyStatus(PyStatus status) { if (!_PyStatus_IS_ERROR(status)) { PyErr_Format(PyExc_SystemError, - "%s() expects an error PyStatus", - _PyStatus_GET_FUNC()); + "_PyErr_SetFromPyStatus() status is not an error"); + return; + } + + const char *err_msg = status.err_msg; + if (err_msg == NULL || strlen(err_msg) == 0) { + PyErr_Format(PyExc_SystemError, + "_PyErr_SetFromPyStatus() status has no error message"); + return; } - else if (status.func) { - PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg); + + if (strcmp(err_msg, _PyStatus_NO_MEMORY_ERRMSG) == 0) { + PyErr_NoMemory(); + return; + } + + const char *func = status.func; + if (func) { + PyErr_Format(PyExc_RuntimeError, "%s: %s", func, err_msg); } else { - PyErr_Format(PyExc_ValueError, "%s", status.err_msg); + PyErr_Format(PyExc_RuntimeError, "%s", err_msg); } - return NULL; } @@ -615,8 +739,13 @@ config_check_consistency(const PyConfig *config) assert(config->_is_python_build >= 0); assert(config->safe_path >= 0); assert(config->int_max_str_digits >= 0); + // cpu_count can be -1 if the user doesn't override it. + assert(config->cpu_count != 0); // config->use_frozen_modules is initialized later // by _PyConfig_InitImportConfig(). +#ifdef Py_STATS + assert(config->_pystats >= 0); +#endif return 1; } #endif @@ -651,6 +780,7 @@ PyConfig_Clear(PyConfig *config) CLEAR(config->exec_prefix); CLEAR(config->base_exec_prefix); CLEAR(config->platlibdir); + CLEAR(config->sys_path_0); CLEAR(config->filesystem_encoding); CLEAR(config->filesystem_errors); @@ -711,6 +841,7 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->int_max_str_digits = -1; config->_is_python_build = 0; config->code_debug_ranges = 1; + config->cpu_count = -1; } @@ -848,100 +979,47 @@ PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str, PyStatus _PyConfig_Copy(PyConfig *config, const PyConfig *config2) { - PyStatus status; - PyConfig_Clear(config); -#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR -#define COPY_WSTR_ATTR(ATTR) \ - do { \ - status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \ - if (_PyStatus_EXCEPTION(status)) { \ - return status; \ - } \ - } while (0) -#define COPY_WSTRLIST(LIST) \ - do { \ - if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \ - return _PyStatus_NO_MEMORY(); \ - } \ - } while (0) - - COPY_ATTR(_config_init); - COPY_ATTR(isolated); - COPY_ATTR(use_environment); - COPY_ATTR(dev_mode); - COPY_ATTR(install_signal_handlers); - COPY_ATTR(use_hash_seed); - COPY_ATTR(hash_seed); - COPY_ATTR(_install_importlib); - COPY_ATTR(faulthandler); - COPY_ATTR(tracemalloc); - COPY_ATTR(perf_profiling); - COPY_ATTR(import_time); - COPY_ATTR(code_debug_ranges); - COPY_ATTR(show_ref_count); - COPY_ATTR(dump_refs); - COPY_ATTR(dump_refs_file); - COPY_ATTR(malloc_stats); - - COPY_WSTR_ATTR(pycache_prefix); - COPY_WSTR_ATTR(pythonpath_env); - COPY_WSTR_ATTR(home); - COPY_WSTR_ATTR(program_name); - - COPY_ATTR(parse_argv); - COPY_WSTRLIST(argv); - COPY_WSTRLIST(warnoptions); - COPY_WSTRLIST(xoptions); - COPY_WSTRLIST(module_search_paths); - COPY_ATTR(module_search_paths_set); - COPY_WSTR_ATTR(stdlib_dir); - - COPY_WSTR_ATTR(executable); - COPY_WSTR_ATTR(base_executable); - COPY_WSTR_ATTR(prefix); - COPY_WSTR_ATTR(base_prefix); - COPY_WSTR_ATTR(exec_prefix); - COPY_WSTR_ATTR(base_exec_prefix); - COPY_WSTR_ATTR(platlibdir); - - COPY_ATTR(site_import); - COPY_ATTR(bytes_warning); - COPY_ATTR(warn_default_encoding); - COPY_ATTR(inspect); - COPY_ATTR(interactive); - COPY_ATTR(optimization_level); - COPY_ATTR(parser_debug); - COPY_ATTR(write_bytecode); - COPY_ATTR(verbose); - COPY_ATTR(quiet); - COPY_ATTR(user_site_directory); - COPY_ATTR(configure_c_stdio); - COPY_ATTR(buffered_stdio); - COPY_WSTR_ATTR(filesystem_encoding); - COPY_WSTR_ATTR(filesystem_errors); - COPY_WSTR_ATTR(stdio_encoding); - COPY_WSTR_ATTR(stdio_errors); -#ifdef MS_WINDOWS - COPY_ATTR(legacy_windows_stdio); -#endif - COPY_ATTR(skip_source_first_line); - COPY_WSTR_ATTR(run_command); - COPY_WSTR_ATTR(run_module); - COPY_WSTR_ATTR(run_filename); - COPY_WSTR_ATTR(check_hash_pycs_mode); - COPY_ATTR(pathconfig_warnings); - COPY_ATTR(_init_main); - COPY_ATTR(use_frozen_modules); - COPY_ATTR(safe_path); - COPY_WSTRLIST(orig_argv); - COPY_ATTR(_is_python_build); - COPY_ATTR(int_max_str_digits); - -#undef COPY_ATTR -#undef COPY_WSTR_ATTR -#undef COPY_WSTRLIST + PyStatus status; + const PyConfigSpec *spec = PYCONFIG_SPEC; + for (; spec->name != NULL; spec++) { + char *member = (char *)config + spec->offset; + char *member2 = (char *)config2 + spec->offset; + switch (spec->type) { + case PyConfig_MEMBER_INT: + case PyConfig_MEMBER_UINT: + { + *(int*)member = *(int*)member2; + break; + } + case PyConfig_MEMBER_ULONG: + { + *(unsigned long*)member = *(unsigned long*)member2; + break; + } + case PyConfig_MEMBER_WSTR: + case PyConfig_MEMBER_WSTR_OPT: + { + const wchar_t *str = *(const wchar_t**)member2; + status = PyConfig_SetString(config, (wchar_t**)member, str); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + break; + } + case PyConfig_MEMBER_WSTR_LIST: + { + if (_PyWideStringList_Copy((PyWideStringList*)member, + (const PyWideStringList*)member2) < 0) { + return _PyStatus_NO_MEMORY(); + } + break; + } + default: + Py_UNREACHABLE(); + } + } return _PyStatus_OK(); } @@ -954,118 +1032,69 @@ _PyConfig_AsDict(const PyConfig *config) return NULL; } -#define SET_ITEM(KEY, EXPR) \ - do { \ - PyObject *obj = (EXPR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define SET_ITEM_INT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) -#define SET_ITEM_UINT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) -#define FROM_WSTRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromWideChar(STR, -1) \ - : Py_NewRef(Py_None)) -#define SET_ITEM_WSTR(ATTR) \ - SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) -#define SET_ITEM_WSTRLIST(LIST) \ - SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST)) - - SET_ITEM_INT(_config_init); - SET_ITEM_INT(isolated); - SET_ITEM_INT(use_environment); - SET_ITEM_INT(dev_mode); - SET_ITEM_INT(install_signal_handlers); - SET_ITEM_INT(use_hash_seed); - SET_ITEM_UINT(hash_seed); - SET_ITEM_INT(faulthandler); - SET_ITEM_INT(tracemalloc); - SET_ITEM_INT(perf_profiling); - SET_ITEM_INT(import_time); - SET_ITEM_INT(code_debug_ranges); - SET_ITEM_INT(show_ref_count); - SET_ITEM_INT(dump_refs); - SET_ITEM_INT(malloc_stats); - SET_ITEM_WSTR(filesystem_encoding); - SET_ITEM_WSTR(filesystem_errors); - SET_ITEM_WSTR(pycache_prefix); - SET_ITEM_WSTR(program_name); - SET_ITEM_INT(parse_argv); - SET_ITEM_WSTRLIST(argv); - SET_ITEM_WSTRLIST(xoptions); - SET_ITEM_WSTRLIST(warnoptions); - SET_ITEM_WSTR(pythonpath_env); - SET_ITEM_WSTR(home); - SET_ITEM_INT(module_search_paths_set); - SET_ITEM_WSTRLIST(module_search_paths); - SET_ITEM_WSTR(stdlib_dir); - SET_ITEM_WSTR(executable); - SET_ITEM_WSTR(base_executable); - SET_ITEM_WSTR(prefix); - SET_ITEM_WSTR(base_prefix); - SET_ITEM_WSTR(exec_prefix); - SET_ITEM_WSTR(base_exec_prefix); - SET_ITEM_WSTR(platlibdir); - SET_ITEM_INT(site_import); - SET_ITEM_INT(bytes_warning); - SET_ITEM_INT(warn_default_encoding); - SET_ITEM_INT(inspect); - SET_ITEM_INT(interactive); - SET_ITEM_INT(optimization_level); - SET_ITEM_INT(parser_debug); - SET_ITEM_INT(write_bytecode); - SET_ITEM_INT(verbose); - SET_ITEM_INT(quiet); - SET_ITEM_INT(user_site_directory); - SET_ITEM_INT(configure_c_stdio); - SET_ITEM_INT(buffered_stdio); - SET_ITEM_WSTR(stdio_encoding); - SET_ITEM_WSTR(stdio_errors); -#ifdef MS_WINDOWS - SET_ITEM_INT(legacy_windows_stdio); -#endif - SET_ITEM_INT(skip_source_first_line); - SET_ITEM_WSTR(run_command); - SET_ITEM_WSTR(run_module); - SET_ITEM_WSTR(run_filename); - SET_ITEM_INT(_install_importlib); - SET_ITEM_WSTR(check_hash_pycs_mode); - SET_ITEM_INT(pathconfig_warnings); - SET_ITEM_INT(_init_main); - SET_ITEM_WSTRLIST(orig_argv); - SET_ITEM_INT(use_frozen_modules); - SET_ITEM_INT(safe_path); - SET_ITEM_INT(_is_python_build); - SET_ITEM_INT(int_max_str_digits); + const PyConfigSpec *spec = PYCONFIG_SPEC; + for (; spec->name != NULL; spec++) { + char *member = (char *)config + spec->offset; + PyObject *obj; + switch (spec->type) { + case PyConfig_MEMBER_INT: + case PyConfig_MEMBER_UINT: + { + int value = *(int*)member; + obj = PyLong_FromLong(value); + break; + } + case PyConfig_MEMBER_ULONG: + { + unsigned long value = *(unsigned long*)member; + obj = PyLong_FromUnsignedLong(value); + break; + } + case PyConfig_MEMBER_WSTR: + case PyConfig_MEMBER_WSTR_OPT: + { + const wchar_t *wstr = *(const wchar_t**)member; + if (wstr != NULL) { + obj = PyUnicode_FromWideChar(wstr, -1); + } + else { + obj = Py_NewRef(Py_None); + } + break; + } + case PyConfig_MEMBER_WSTR_LIST: + { + const PyWideStringList *list = (const PyWideStringList*)member; + obj = _PyWideStringList_AsList(list); + break; + } + default: + Py_UNREACHABLE(); + } + if (obj == NULL) { + Py_DECREF(dict); + return NULL; + } + int res = PyDict_SetItemString(dict, spec->name, obj); + Py_DECREF(obj); + if (res < 0) { + Py_DECREF(dict); + return NULL; + } + } return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef FROM_WSTRING -#undef SET_ITEM -#undef SET_ITEM_INT -#undef SET_ITEM_UINT -#undef SET_ITEM_WSTR -#undef SET_ITEM_WSTRLIST } static PyObject* config_dict_get(PyObject *dict, const char *name) { - PyObject *item = _PyDict_GetItemStringWithError(dict, name); - if (item == NULL && !PyErr_Occurred()) { + PyObject *item; + if (PyDict_GetItemStringRef(dict, name, &item) < 0) { + return NULL; + } + if (item == NULL) { PyErr_Format(PyExc_ValueError, "missing config key: %s", name); return NULL; } @@ -1094,7 +1123,8 @@ config_dict_get_int(PyObject *dict, const char *name, int *result) if (item == NULL) { return -1; } - int value = _PyLong_AsInt(item); + int value = PyLong_AsInt(item); + Py_DECREF(item); if (value == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { config_dict_invalid_type(name); @@ -1117,6 +1147,7 @@ config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result) return -1; } unsigned long value = PyLong_AsUnsignedLong(item); + Py_DECREF(item); if (value == (unsigned long)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { config_dict_invalid_type(name); @@ -1139,27 +1170,33 @@ config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config, if (item == NULL) { return -1; } + PyStatus status; if (item == Py_None) { status = PyConfig_SetString(config, result, NULL); } else if (!PyUnicode_Check(item)) { config_dict_invalid_type(name); - return -1; + goto error; } else { wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL); if (wstr == NULL) { - return -1; + goto error; } status = PyConfig_SetString(config, result, wstr); PyMem_Free(wstr); } if (_PyStatus_EXCEPTION(status)) { PyErr_NoMemory(); - return -1; + goto error; } + Py_DECREF(item); return 0; + +error: + Py_DECREF(item); + return -1; } @@ -1173,6 +1210,7 @@ config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config, } if (!PyList_CheckExact(list)) { + Py_DECREF(list); config_dict_invalid_type(name); return -1; } @@ -1206,10 +1244,12 @@ config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config, goto error; } _PyWideStringList_Clear(&wstrlist); + Py_DECREF(list); return 0; error: _PyWideStringList_Clear(&wstrlist); + Py_DECREF(list); return -1; } @@ -1222,128 +1262,81 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) return -1; } -#define CHECK_VALUE(NAME, TEST) \ - if (!(TEST)) { \ - config_dict_invalid_value(NAME); \ - return -1; \ + const PyConfigSpec *spec = PYCONFIG_SPEC; + for (; spec->name != NULL; spec++) { + char *member = (char *)config + spec->offset; + switch (spec->type) { + case PyConfig_MEMBER_INT: + if (config_dict_get_int(dict, spec->name, (int*)member) < 0) { + return -1; + } + break; + case PyConfig_MEMBER_UINT: + { + int value; + if (config_dict_get_int(dict, spec->name, &value) < 0) { + return -1; + } + if (value < 0) { + config_dict_invalid_value(spec->name); + return -1; + } + *(int*)member = value; + break; + } + case PyConfig_MEMBER_ULONG: + { + if (config_dict_get_ulong(dict, spec->name, + (unsigned long*)member) < 0) { + return -1; + } + break; + } + case PyConfig_MEMBER_WSTR: + { + wchar_t **wstr = (wchar_t**)member; + if (config_dict_get_wstr(dict, spec->name, config, wstr) < 0) { + return -1; + } + if (*wstr == NULL) { + config_dict_invalid_value(spec->name); + return -1; + } + break; + } + case PyConfig_MEMBER_WSTR_OPT: + { + wchar_t **wstr = (wchar_t**)member; + if (config_dict_get_wstr(dict, spec->name, config, wstr) < 0) { + return -1; + } + break; + } + case PyConfig_MEMBER_WSTR_LIST: + { + if (config_dict_get_wstrlist(dict, spec->name, config, + (PyWideStringList*)member) < 0) { + return -1; + } + break; + } + default: + Py_UNREACHABLE(); + } } -#define GET_UINT(KEY) \ - do { \ - if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \ - return -1; \ - } \ - CHECK_VALUE(#KEY, config->KEY >= 0); \ - } while (0) -#define GET_INT(KEY) \ - do { \ - if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \ - return -1; \ - } \ - } while (0) -#define GET_WSTR(KEY) \ - do { \ - if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ - return -1; \ - } \ - CHECK_VALUE(#KEY, config->KEY != NULL); \ - } while (0) -#define GET_WSTR_OPT(KEY) \ - do { \ - if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ - return -1; \ - } \ - } while (0) -#define GET_WSTRLIST(KEY) \ - do { \ - if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \ - return -1; \ - } \ - } while (0) - GET_UINT(_config_init); - CHECK_VALUE("_config_init", - config->_config_init == _PyConfig_INIT_COMPAT - || config->_config_init == _PyConfig_INIT_PYTHON - || config->_config_init == _PyConfig_INIT_ISOLATED); - GET_UINT(isolated); - GET_UINT(use_environment); - GET_UINT(dev_mode); - GET_UINT(install_signal_handlers); - GET_UINT(use_hash_seed); - if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) { + if (!(config->_config_init == _PyConfig_INIT_COMPAT + || config->_config_init == _PyConfig_INIT_PYTHON + || config->_config_init == _PyConfig_INIT_ISOLATED)) + { + config_dict_invalid_value("_config_init"); + return -1; + } + + if (config->hash_seed > MAX_HASH_SEED) { + config_dict_invalid_value("hash_seed"); return -1; } - CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED); - GET_UINT(faulthandler); - GET_UINT(tracemalloc); - GET_UINT(perf_profiling); - GET_UINT(import_time); - GET_UINT(code_debug_ranges); - GET_UINT(show_ref_count); - GET_UINT(dump_refs); - GET_UINT(malloc_stats); - GET_WSTR(filesystem_encoding); - GET_WSTR(filesystem_errors); - GET_WSTR_OPT(pycache_prefix); - GET_UINT(parse_argv); - GET_WSTRLIST(orig_argv); - GET_WSTRLIST(argv); - GET_WSTRLIST(xoptions); - GET_WSTRLIST(warnoptions); - GET_UINT(site_import); - GET_UINT(bytes_warning); - GET_UINT(warn_default_encoding); - GET_UINT(inspect); - GET_UINT(interactive); - GET_UINT(optimization_level); - GET_UINT(parser_debug); - GET_UINT(write_bytecode); - GET_UINT(verbose); - GET_UINT(quiet); - GET_UINT(user_site_directory); - GET_UINT(configure_c_stdio); - GET_UINT(buffered_stdio); - GET_WSTR(stdio_encoding); - GET_WSTR(stdio_errors); -#ifdef MS_WINDOWS - GET_UINT(legacy_windows_stdio); -#endif - GET_WSTR(check_hash_pycs_mode); - - GET_UINT(pathconfig_warnings); - GET_WSTR(program_name); - GET_WSTR_OPT(pythonpath_env); - GET_WSTR_OPT(home); - GET_WSTR(platlibdir); - - // Path configuration output - GET_UINT(module_search_paths_set); - GET_WSTRLIST(module_search_paths); - GET_WSTR_OPT(stdlib_dir); - GET_WSTR_OPT(executable); - GET_WSTR_OPT(base_executable); - GET_WSTR_OPT(prefix); - GET_WSTR_OPT(base_prefix); - GET_WSTR_OPT(exec_prefix); - GET_WSTR_OPT(base_exec_prefix); - - GET_UINT(skip_source_first_line); - GET_WSTR_OPT(run_command); - GET_WSTR_OPT(run_module); - GET_WSTR_OPT(run_filename); - - GET_UINT(_install_importlib); - GET_UINT(_init_main); - GET_UINT(use_frozen_modules); - GET_UINT(safe_path); - GET_UINT(_is_python_build); - GET_INT(int_max_str_digits); - -#undef CHECK_VALUE -#undef GET_UINT -#undef GET_INT -#undef GET_WSTR -#undef GET_WSTR_OPT return 0; } @@ -1634,6 +1627,45 @@ config_read_env_vars(PyConfig *config) return _PyStatus_OK(); } +static PyStatus +config_init_cpu_count(PyConfig *config) +{ + const char *env = config_get_env(config, "PYTHON_CPU_COUNT"); + if (env) { + int cpu_count = -1; + if (strcmp(env, "default") == 0) { + cpu_count = -1; + } + else if (_Py_str_to_int(env, &cpu_count) < 0 || cpu_count < 1) { + goto error; + } + config->cpu_count = cpu_count; + } + + const wchar_t *xoption = config_get_xoption(config, L"cpu_count"); + if (xoption) { + int cpu_count = -1; + const wchar_t *sep = wcschr(xoption, L'='); + if (sep) { + if (wcscmp(sep + 1, L"default") == 0) { + cpu_count = -1; + } + else if (config_wstr_to_int(sep + 1, &cpu_count) < 0 || cpu_count < 1) { + goto error; + } + } + else { + goto error; + } + config->cpu_count = cpu_count; + } + return _PyStatus_OK(); + +error: + return _PyStatus_ERR("-X cpu_count=n option: n is missing or an invalid number, " + "n must be greater than 0"); +} + static PyStatus config_init_perf_profiling(PyConfig *config) { @@ -1816,6 +1848,13 @@ config_read_complex_options(PyConfig *config) } } + if (config->cpu_count < 0) { + status = config_init_cpu_count(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + if (config->pycache_prefix == NULL) { status = config_init_pycache_prefix(config); if (_PyStatus_EXCEPTION(status)) { @@ -2089,7 +2128,13 @@ config_read(PyConfig *config, int compute_path_config) #ifdef Py_STATS if (config_get_xoption(config, L"pystats")) { - _py_stats = &_py_stats_struct; + config->_pystats = 1; + } + else if (config_get_env(config, "PYTHONSTATS")) { + config->_pystats = 1; + } + if (config->_pystats < 0) { + config->_pystats = 0; } #endif @@ -2227,6 +2272,13 @@ _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime) { return _PyStatus_NO_MEMORY(); } + +#ifdef Py_STATS + if (config->_pystats) { + _Py_StatsOn(); + } +#endif + return _PyStatus_OK(); } @@ -3057,6 +3109,7 @@ _Py_DumpPathConfig(PyThreadState *tstate) PySys_WriteStderr(" import site = %i\n", config->site_import); PySys_WriteStderr(" is in build tree = %i\n", config->_is_python_build); DUMP_CONFIG("stdlib dir", stdlib_dir); + DUMP_CONFIG("sys.path[0]", sys_path_0); #undef DUMP_CONFIG #define DUMP_SYS(NAME) \ diff --git a/Python/instrumentation.c b/Python/instrumentation.c index e29748f0ad9872..eee1908e503e43 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1,12 +1,18 @@ #include "Python.h" + +#include "opcode_ids.h" + +#include "pycore_bitutils.h" // _Py_popcount32 #include "pycore_call.h" +#include "pycore_ceval.h" // _PY_EVAL_EVENTS_BITS +#include "pycore_code.h" // _PyCode_Clear_Executors() #include "pycore_frame.h" #include "pycore_interp.h" #include "pycore_long.h" #include "pycore_modsupport.h" // _PyModule_CreateInitialized() #include "pycore_namespace.h" #include "pycore_object.h" -#include "pycore_opcode.h" +#include "pycore_opcode_metadata.h" // IS_VALID_OPCODE, _PyOpcode_Caches #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyInterpreterState_GET() @@ -32,6 +38,8 @@ static const int8_t EVENT_FOR_OPCODE[256] = { [INSTRUMENTED_RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN, [CALL] = PY_MONITORING_EVENT_CALL, [INSTRUMENTED_CALL] = PY_MONITORING_EVENT_CALL, + [CALL_KW] = PY_MONITORING_EVENT_CALL, + [INSTRUMENTED_CALL_KW] = PY_MONITORING_EVENT_CALL, [CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL, [INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL, [LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL, @@ -64,6 +72,7 @@ static const uint8_t DE_INSTRUMENT[256] = { [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE, [INSTRUMENTED_RETURN_CONST] = RETURN_CONST, [INSTRUMENTED_CALL] = CALL, + [INSTRUMENTED_CALL_KW] = CALL_KW, [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX, [INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE, [INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD, @@ -85,6 +94,8 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = { [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, [CALL] = INSTRUMENTED_CALL, [INSTRUMENTED_CALL] = INSTRUMENTED_CALL, + [CALL_KW] = INSTRUMENTED_CALL_KW, + [INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW, [CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, [YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, @@ -120,7 +131,7 @@ static inline bool opcode_has_event(int opcode) { return ( - opcode < INSTRUMENTED_LINE && + opcode != INSTRUMENTED_LINE && INSTRUMENTED_OPCODES[opcode] > 0 ); } @@ -135,9 +146,9 @@ is_instrumented(int opcode) #ifndef NDEBUG static inline bool -monitors_equals(_Py_Monitors a, _Py_Monitors b) +monitors_equals(_Py_LocalMonitors a, _Py_LocalMonitors b) { - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { if (a.tools[i] != b.tools[i]) { return false; } @@ -146,42 +157,47 @@ monitors_equals(_Py_Monitors a, _Py_Monitors b) } #endif -static inline _Py_Monitors -monitors_sub(_Py_Monitors a, _Py_Monitors b) +static inline _Py_LocalMonitors +monitors_sub(_Py_LocalMonitors a, _Py_LocalMonitors b) { - _Py_Monitors res; - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + _Py_LocalMonitors res; + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { res.tools[i] = a.tools[i] & ~b.tools[i]; } return res; } #ifndef NDEBUG -static inline _Py_Monitors -monitors_and(_Py_Monitors a, _Py_Monitors b) +static inline _Py_LocalMonitors +monitors_and(_Py_LocalMonitors a, _Py_LocalMonitors b) { - _Py_Monitors res; - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + _Py_LocalMonitors res; + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { res.tools[i] = a.tools[i] & b.tools[i]; } return res; } #endif -static inline _Py_Monitors -monitors_or(_Py_Monitors a, _Py_Monitors b) +/* The union of the *local* events in a and b. + * Global events like RAISE are ignored. + * Used for instrumentation, as only local + * events get instrumented. + */ +static inline _Py_LocalMonitors +local_union(_Py_GlobalMonitors a, _Py_LocalMonitors b) { - _Py_Monitors res; - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + _Py_LocalMonitors res; + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { res.tools[i] = a.tools[i] | b.tools[i]; } return res; } static inline bool -monitors_are_empty(_Py_Monitors m) +monitors_are_empty(_Py_LocalMonitors m) { - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { if (m.tools[i]) { return false; } @@ -190,9 +206,9 @@ monitors_are_empty(_Py_Monitors m) } static inline bool -multiple_tools(_Py_Monitors *m) +multiple_tools(_Py_LocalMonitors *m) { - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { if (_Py_popcount32(m->tools[i]) > 1) { return true; } @@ -201,10 +217,22 @@ multiple_tools(_Py_Monitors *m) } static inline _PyMonitoringEventSet -get_events(_Py_Monitors *m, int tool_id) +get_local_events(_Py_LocalMonitors *m, int tool_id) +{ + _PyMonitoringEventSet result = 0; + for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) { + if ((m->tools[e] >> tool_id) & 1) { + result |= (1 << e); + } + } + return result; +} + +static inline _PyMonitoringEventSet +get_events(_Py_GlobalMonitors *m, int tool_id) { _PyMonitoringEventSet result = 0; - for (int e = 0; e < PY_MONITORING_UNGROUPED_EVENTS; e++) { + for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) { if ((m->tools[e] >> tool_id) & 1) { result |= (1 << e); } @@ -276,6 +304,13 @@ _PyInstruction_GetLength(PyCodeObject *code, int offset) } assert(opcode != 0); assert(!is_instrumented(opcode)); + if (opcode == ENTER_EXECUTOR) { + int exec_index = _PyCode_CODE(code)[offset].op.arg; + _PyExecutorObject *exec = code->co_executors->executors[exec_index]; + opcode = _PyOpcode_Deopt[exec->vm_data.opcode]; + + } + assert(opcode != ENTER_EXECUTOR); assert(opcode == _PyOpcode_Deopt[opcode]); return 1 + _PyOpcode_Caches[opcode]; } @@ -336,45 +371,21 @@ dump_instrumentation_data_per_instruction(PyCodeObject *code, _PyCoMonitoringDat } static void -dump_monitors(const char *prefix, _Py_Monitors monitors, FILE*out) +dump_global_monitors(const char *prefix, _Py_GlobalMonitors monitors, FILE*out) { fprintf(out, "%s monitors:\n", prefix); - for (int event = 0; event < PY_MONITORING_UNGROUPED_EVENTS; event++) { + for (int event = 0; event < _PY_MONITORING_UNGROUPED_EVENTS; event++) { fprintf(out, " Event %d: Tools %x\n", event, monitors.tools[event]); } } -/* Like _Py_GetBaseOpcode but without asserts. - * Does its best to give the right answer, but won't abort - * if something is wrong */ -static int -get_base_opcode_best_attempt(PyCodeObject *code, int offset) +static void +dump_local_monitors(const char *prefix, _Py_LocalMonitors monitors, FILE*out) { - int opcode = _Py_OPCODE(_PyCode_CODE(code)[offset]); - if (INSTRUMENTED_OPCODES[opcode] != opcode) { - /* Not instrumented */ - return _PyOpcode_Deopt[opcode] == 0 ? opcode : _PyOpcode_Deopt[opcode]; - } - if (opcode == INSTRUMENTED_INSTRUCTION) { - if (code->_co_monitoring->per_instruction_opcodes[offset] == 0) { - return opcode; - } - opcode = code->_co_monitoring->per_instruction_opcodes[offset]; - } - if (opcode == INSTRUMENTED_LINE) { - if (code->_co_monitoring->lines[offset].original_opcode == 0) { - return opcode; - } - opcode = code->_co_monitoring->lines[offset].original_opcode; - } - int deinstrumented = DE_INSTRUMENT[opcode]; - if (deinstrumented) { - return deinstrumented; - } - if (_PyOpcode_Deopt[opcode] == 0) { - return opcode; + fprintf(out, "%s monitors:\n", prefix); + for (int event = 0; event < _PY_MONITORING_LOCAL_EVENTS; event++) { + fprintf(out, " Event %d: Tools %x\n", event, monitors.tools[event]); } - return _PyOpcode_Deopt[opcode]; } /* No error checking -- Don't use this for anything but experimental debugging */ @@ -389,9 +400,9 @@ dump_instrumentation_data(PyCodeObject *code, int star, FILE*out) fprintf(out, "NULL\n"); return; } - dump_monitors("Global", _PyInterpreterState_GET()->monitors, out); - dump_monitors("Code", data->local_monitors, out); - dump_monitors("Active", data->active_monitors, out); + dump_global_monitors("Global", _PyInterpreterState_GET()->monitors, out); + dump_local_monitors("Code", data->local_monitors, out); + dump_local_monitors("Active", data->active_monitors, out); int code_len = (int)Py_SIZE(code); bool starred = false; for (int i = 0; i < code_len; i += _PyInstruction_GetLength(code, i)) { @@ -430,11 +441,13 @@ dump_instrumentation_data(PyCodeObject *code, int star, FILE*out) static bool valid_opcode(int opcode) { - if (opcode > 0 && + if (opcode == INSTRUMENTED_LINE) { + return true; + } + if (IS_VALID_OPCODE(opcode) && + opcode != CACHE && opcode != RESERVED && - opcode < 255 && - _PyOpcode_OpName[opcode] && - _PyOpcode_OpName[opcode][0] != '<') + opcode < 255) { return true; } @@ -448,18 +461,23 @@ sanity_check_instrumentation(PyCodeObject *code) if (data == NULL) { return; } - _Py_Monitors active_monitors = _PyInterpreterState_GET()->monitors; + _Py_GlobalMonitors global_monitors = _PyInterpreterState_GET()->monitors; + _Py_LocalMonitors active_monitors; if (code->_co_monitoring) { - _Py_Monitors local_monitors = code->_co_monitoring->local_monitors; - active_monitors = monitors_or(active_monitors, local_monitors); + _Py_LocalMonitors local_monitors = code->_co_monitoring->local_monitors; + active_monitors = local_union(global_monitors, local_monitors); + } + else { + _Py_LocalMonitors empty = (_Py_LocalMonitors) { 0 }; + active_monitors = local_union(global_monitors, empty); } assert(monitors_equals( code->_co_monitoring->active_monitors, - active_monitors) - ); + active_monitors)); int code_len = (int)Py_SIZE(code); for (int i = 0; i < code_len;) { - int opcode = _PyCode_CODE(code)[i].op.code; + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + int opcode = instr->op.code; int base_opcode = _Py_GetBaseOpcode(code, i); CHECK(valid_opcode(opcode)); CHECK(valid_opcode(base_opcode)); @@ -479,23 +497,30 @@ sanity_check_instrumentation(PyCodeObject *code) opcode = data->lines[i].original_opcode; CHECK(opcode != END_FOR); CHECK(opcode != RESUME); + CHECK(opcode != RESUME_CHECK); CHECK(opcode != INSTRUMENTED_RESUME); if (!is_instrumented(opcode)) { CHECK(_PyOpcode_Deopt[opcode] == opcode); } CHECK(opcode != INSTRUMENTED_LINE); } - else if (data->lines && !is_instrumented(opcode)) { - CHECK(data->lines[i].original_opcode == 0 || - data->lines[i].original_opcode == base_opcode || - DE_INSTRUMENT[data->lines[i].original_opcode] == base_opcode); + else if (data->lines) { + /* If original_opcode is INSTRUMENTED_INSTRUCTION + * *and* we are executing a INSTRUMENTED_LINE instruction + * that has de-instrumented itself, then we will execute + * an invalid INSTRUMENTED_INSTRUCTION */ + CHECK(data->lines[i].original_opcode != INSTRUMENTED_INSTRUCTION); + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + CHECK(data->per_instruction_opcodes[i] != 0); + opcode = data->per_instruction_opcodes[i]; } if (is_instrumented(opcode)) { CHECK(DE_INSTRUMENT[opcode] == base_opcode); int event = EVENT_FOR_OPCODE[DE_INSTRUMENT[opcode]]; if (event < 0) { /* RESUME fixup */ - event = _PyCode_CODE(code)[i].op.arg; + event = instr->op.arg ? 1: 0; } CHECK(active_monitors.tools[event] != 0); } @@ -557,6 +582,7 @@ de_instrument(PyCodeObject *code, int i, int event) _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t *opcode_ptr = &instr->op.code; int opcode = *opcode_ptr; + assert(opcode != ENTER_EXECUTOR); if (opcode == INSTRUMENTED_LINE) { opcode_ptr = &code->_co_monitoring->lines[i].original_opcode; opcode = *opcode_ptr; @@ -580,30 +606,30 @@ static void de_instrument_line(PyCodeObject *code, int i) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; - uint8_t *opcode_ptr = &instr->op.code; - int opcode =*opcode_ptr; + int opcode = instr->op.code; if (opcode != INSTRUMENTED_LINE) { return; } _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; int original_opcode = lines->original_opcode; + if (original_opcode == INSTRUMENTED_INSTRUCTION) { + lines->original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } CHECK(original_opcode != 0); CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); - *opcode_ptr = instr->op.code = original_opcode; + instr->op.code = original_opcode; if (_PyOpcode_Caches[original_opcode]) { instr[1].cache = adaptive_counter_warmup(); } - assert(*opcode_ptr != INSTRUMENTED_LINE); assert(instr->op.code != INSTRUMENTED_LINE); } - static void de_instrument_per_instruction(PyCodeObject *code, int i) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t *opcode_ptr = &instr->op.code; - int opcode =*opcode_ptr; + int opcode = *opcode_ptr; if (opcode == INSTRUMENTED_LINE) { opcode_ptr = &code->_co_monitoring->lines[i].original_opcode; opcode = *opcode_ptr; @@ -614,10 +640,11 @@ de_instrument_per_instruction(PyCodeObject *code, int i) int original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; CHECK(original_opcode != 0); CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); - instr->op.code = original_opcode; + *opcode_ptr = original_opcode; if (_PyOpcode_Caches[original_opcode]) { instr[1].cache = adaptive_counter_warmup(); } + assert(*opcode_ptr != INSTRUMENTED_INSTRUCTION); assert(instr->op.code != INSTRUMENTED_INSTRUCTION); /* Keep things clean for sanity check */ code->_co_monitoring->per_instruction_opcodes[i] = 0; @@ -638,7 +665,7 @@ instrument(PyCodeObject *code, int i) if (opcode == INSTRUMENTED_INSTRUCTION) { opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i]; opcode = *opcode_ptr; - CHECK(!is_instrumented(opcode)); + CHECK(opcode != INSTRUMENTED_INSTRUCTION && opcode != INSTRUMENTED_LINE); CHECK(opcode == _PyOpcode_Deopt[opcode]); } CHECK(opcode != 0); @@ -657,7 +684,7 @@ static void instrument_line(PyCodeObject *code, int i) { uint8_t *opcode_ptr = &_PyCode_CODE(code)[i].op.code; - int opcode =*opcode_ptr; + int opcode = *opcode_ptr; if (opcode == INSTRUMENTED_LINE) { return; } @@ -672,13 +699,14 @@ instrument_per_instruction(PyCodeObject *code, int i) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t *opcode_ptr = &instr->op.code; - int opcode =*opcode_ptr; + int opcode = *opcode_ptr; if (opcode == INSTRUMENTED_LINE) { _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; opcode_ptr = &lines->original_opcode; opcode = *opcode_ptr; } if (opcode == INSTRUMENTED_INSTRUCTION) { + assert(code->_co_monitoring->per_instruction_opcodes[i] > 0); return; } CHECK(opcode != 0); @@ -695,29 +723,13 @@ instrument_per_instruction(PyCodeObject *code, int i) *opcode_ptr = INSTRUMENTED_INSTRUCTION; } -#ifndef NDEBUG -static bool -instruction_has_event(PyCodeObject *code, int offset) -{ - _Py_CODEUNIT instr = _PyCode_CODE(code)[offset]; - int opcode = instr.op.code; - if (opcode == INSTRUMENTED_LINE) { - opcode = code->_co_monitoring->lines[offset].original_opcode; - } - if (opcode == INSTRUMENTED_INSTRUCTION) { - opcode = code->_co_monitoring->per_instruction_opcodes[offset]; - } - return opcode_has_event(opcode); -} -#endif - static void remove_tools(PyCodeObject * code, int offset, int event, int tools) { assert(event != PY_MONITORING_EVENT_LINE); assert(event != PY_MONITORING_EVENT_INSTRUCTION); - assert(event < PY_MONITORING_INSTRUMENTED_EVENTS); - assert(instruction_has_event(code, offset)); + assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event)); + assert(opcode_has_event(_Py_GetBaseOpcode(code, offset))); _PyCoMonitoringData *monitoring = code->_co_monitoring; if (monitoring && monitoring->tools) { monitoring->tools[offset] &= ~tools; @@ -772,7 +784,7 @@ add_tools(PyCodeObject * code, int offset, int event, int tools) { assert(event != PY_MONITORING_EVENT_LINE); assert(event != PY_MONITORING_EVENT_INSTRUCTION); - assert(event < PY_MONITORING_INSTRUMENTED_EVENTS); + assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event)); assert(code->_co_monitoring); if (code->_co_monitoring && code->_co_monitoring->tools @@ -884,17 +896,34 @@ static inline int most_significant_bit(uint8_t bits) { return MOST_SIGNIFICANT_BITS[bits]; } +static uint32_t +global_version(PyInterpreterState *interp) +{ + return interp->ceval.eval_breaker & ~_PY_EVAL_EVENTS_MASK; +} + +static void +set_global_version(PyInterpreterState *interp, uint32_t version) +{ + assert((version & _PY_EVAL_EVENTS_MASK) == 0); + uintptr_t old = _Py_atomic_load_uintptr(&interp->ceval.eval_breaker); + intptr_t new; + do { + new = (old & _PY_EVAL_EVENTS_MASK) | version; + } while (!_Py_atomic_compare_exchange_uintptr(&interp->ceval.eval_breaker, &old, new)); +} + static bool is_version_up_to_date(PyCodeObject *code, PyInterpreterState *interp) { - return interp->monitoring_version == code->_co_instrumentation_version; + return global_version(interp) == code->_co_instrumentation_version; } #ifndef NDEBUG static bool instrumentation_cross_checks(PyInterpreterState *interp, PyCodeObject *code) { - _Py_Monitors expected = monitors_or( + _Py_LocalMonitors expected = local_union( interp->monitors, code->_co_monitoring->local_monitors); return monitors_equals(code->_co_monitoring->active_monitors, expected); @@ -907,12 +936,12 @@ get_tools_for_instruction(PyCodeObject *code, PyInterpreterState *interp, int i, uint8_t tools; assert(event != PY_MONITORING_EVENT_LINE); assert(event != PY_MONITORING_EVENT_INSTRUCTION); - if (event >= PY_MONITORING_UNGROUPED_EVENTS) { + if (event >= _PY_MONITORING_UNGROUPED_EVENTS) { assert(event == PY_MONITORING_EVENT_C_RAISE || event == PY_MONITORING_EVENT_C_RETURN); event = PY_MONITORING_EVENT_CALL; } - if (event < PY_MONITORING_INSTRUMENTED_EVENTS) { + if (PY_MONITORING_IS_INSTRUMENTED_EVENT(event)) { CHECK(is_version_up_to_date(code, interp)); CHECK(instrumentation_cross_checks(interp, code)); if (code->_co_monitoring->tools) { @@ -923,16 +952,31 @@ get_tools_for_instruction(PyCodeObject *code, PyInterpreterState *interp, int i, } } else { - if (code->_co_monitoring) { - tools = code->_co_monitoring->active_monitors.tools[event]; - } - else { - tools = interp->monitors.tools[event]; - } + tools = interp->monitors.tools[event]; } return tools; } +static const char *const event_names [] = { + [PY_MONITORING_EVENT_PY_START] = "PY_START", + [PY_MONITORING_EVENT_PY_RESUME] = "PY_RESUME", + [PY_MONITORING_EVENT_PY_RETURN] = "PY_RETURN", + [PY_MONITORING_EVENT_PY_YIELD] = "PY_YIELD", + [PY_MONITORING_EVENT_CALL] = "CALL", + [PY_MONITORING_EVENT_LINE] = "LINE", + [PY_MONITORING_EVENT_INSTRUCTION] = "INSTRUCTION", + [PY_MONITORING_EVENT_JUMP] = "JUMP", + [PY_MONITORING_EVENT_BRANCH] = "BRANCH", + [PY_MONITORING_EVENT_C_RETURN] = "C_RETURN", + [PY_MONITORING_EVENT_PY_THROW] = "PY_THROW", + [PY_MONITORING_EVENT_RAISE] = "RAISE", + [PY_MONITORING_EVENT_RERAISE] = "RERAISE", + [PY_MONITORING_EVENT_EXCEPTION_HANDLED] = "EXCEPTION_HANDLED", + [PY_MONITORING_EVENT_C_RAISE] = "C_RAISE", + [PY_MONITORING_EVENT_PY_UNWIND] = "PY_UNWIND", + [PY_MONITORING_EVENT_STOP_ITERATION] = "STOP_ITERATION", +}; + static int call_instrumentation_vector( PyThreadState *tstate, int event, @@ -950,7 +994,7 @@ call_instrumentation_vector( /* Offset visible to user should be the offset in bytes, as that is the * convention for APIs involving code offsets. */ int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT); - PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset); + PyObject *offset_obj = PyLong_FromLong(bytes_offset); if (offset_obj == NULL) { return -1; } @@ -977,7 +1021,18 @@ call_instrumentation_vector( } else { /* DISABLE */ - remove_tools(code, offset, event, 1 << tool); + if (!PY_MONITORING_IS_INSTRUMENTED_EVENT(event)) { + PyErr_Format(PyExc_ValueError, + "Cannot disable %s events. Callback removed.", + event_names[event]); + /* Clear tool to prevent infinite loop */ + Py_CLEAR(interp->monitoring_callables[tool][event]); + err = -1; + break; + } + else { + remove_tools(code, offset, event, 1 << tool); + } } } Py_DECREF(offset_obj); @@ -1019,8 +1074,6 @@ _Py_call_instrumentation_jump( assert(event == PY_MONITORING_EVENT_JUMP || event == PY_MONITORING_EVENT_BRANCH); assert(frame->prev_instr == instr); - /* Event should occur after the jump */ - frame->prev_instr = target; PyCodeObject *code = _PyFrame_GetCode(frame); int to = (int)(target - _PyCode_CODE(code)); PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT)); @@ -1033,12 +1086,10 @@ _Py_call_instrumentation_jump( if (err) { return NULL; } - if (frame->prev_instr != target) { + if (frame->prev_instr != instr) { /* The callback has caused a jump (by setting the line number) */ return frame->prev_instr; } - /* Reset prev_instr for INSTRUMENTED_LINE */ - frame->prev_instr = instr; return target; } @@ -1059,16 +1110,6 @@ call_instrumentation_vector_protected( assert(_PyErr_Occurred(tstate)); } -void -_Py_call_instrumentation_exc0( - PyThreadState *tstate, int event, - _PyInterpreterFrame *frame, _Py_CODEUNIT *instr) -{ - assert(_PyErr_Occurred(tstate)); - PyObject *args[3] = { NULL, NULL, NULL }; - call_instrumentation_vector_protected(tstate, event, frame, instr, 2, args); -} - void _Py_call_instrumentation_exc2( PyThreadState *tstate, int event, @@ -1097,7 +1138,7 @@ _Py_Instrumentation_GetLine(PyCodeObject *code, int index) int _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev) { - frame->prev_instr = instr; + assert(frame->prev_instr == instr); PyCodeObject *code = _PyFrame_GetCode(frame); assert(is_version_up_to_date(code, tstate->interp)); assert(instrumentation_cross_checks(tstate->interp, code)); @@ -1105,7 +1146,6 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _PyCoMonitoringData *monitoring = code->_co_monitoring; _PyCoLineInstrumentationData *line_data = &monitoring->lines[i]; - uint8_t original_opcode = line_data->original_opcode; if (tstate->tracing) { goto done; } @@ -1129,14 +1169,46 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, (interp->monitors.tools[PY_MONITORING_EVENT_LINE] | code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_LINE] ); - PyObject *line_obj = PyLong_FromSsize_t(line); + /* Special case sys.settrace to avoid boxing the line number, + * only to immediately unbox it. */ + if (tools & (1 << PY_MONITORING_SYS_TRACE_ID)) { + if (tstate->c_tracefunc != NULL && line >= 0) { + PyFrameObject *frame_obj = _PyFrame_GetFrameObject(frame); + if (frame_obj == NULL) { + return -1; + } + if (frame_obj->f_trace_lines) { + /* Need to set tracing and what_event as if using + * the instrumentation call. */ + int old_what = tstate->what_event; + tstate->what_event = PY_MONITORING_EVENT_LINE; + tstate->tracing++; + /* Call c_tracefunc directly, having set the line number. */ + Py_INCREF(frame_obj); + frame_obj->f_lineno = line; + int err = tstate->c_tracefunc(tstate->c_traceobj, frame_obj, PyTrace_LINE, Py_None); + frame_obj->f_lineno = 0; + tstate->tracing--; + tstate->what_event = old_what; + Py_DECREF(frame_obj); + if (err) { + return -1; + } + } + } + tools &= (255 - (1 << PY_MONITORING_SYS_TRACE_ID)); + } + if (tools == 0) { + goto done; + } + PyObject *line_obj = PyLong_FromLong(line); if (line_obj == NULL) { return -1; } PyObject *args[3] = { NULL, (PyObject *)code, line_obj }; - while (tools) { + do { int tool = most_significant_bit(tools); - assert(tool >= 0 && tool < 8); + assert(tool >= 0 && tool < PY_MONITORING_SYS_PROFILE_ID); assert(tools & (1 << tool)); tools &= ~(1 << tool); int res = call_one_instrument(interp, tstate, &args[1], @@ -1154,11 +1226,13 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, /* DISABLE */ remove_line_tools(code, i, 1 << tool); } - } + } while (tools); Py_DECREF(line_obj); + uint8_t original_opcode; done: + original_opcode = line_data->original_opcode; assert(original_opcode != 0); - assert(original_opcode < INSTRUMENTED_LINE); + assert(original_opcode != INSTRUMENTED_LINE); assert(_PyOpcode_Deopt[original_opcode] == original_opcode); return original_opcode; } @@ -1183,7 +1257,7 @@ _Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame* code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION] ); int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT); - PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset); + PyObject *offset_obj = PyLong_FromLong(bytes_offset); if (offset_obj == NULL) { return -1; } @@ -1220,7 +1294,7 @@ _PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj) { PyInterpreterState *is = _PyInterpreterState_GET(); assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); - assert(0 <= event_id && event_id < PY_MONITORING_EVENTS); + assert(0 <= event_id && event_id < _PY_MONITORING_EVENTS); PyObject *callback = is->monitoring_callables[tool_id][event_id]; is->monitoring_callables[tool_id][event_id] = Py_XNewRef(obj); return callback; @@ -1235,9 +1309,13 @@ initialize_tools(PyCodeObject *code) for (int i = 0; i < code_len; i++) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; int opcode = instr->op.code; + assert(opcode != ENTER_EXECUTOR); if (opcode == INSTRUMENTED_LINE) { opcode = code->_co_monitoring->lines[i].original_opcode; } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } bool instrumented = is_instrumented(opcode); if (instrumented) { opcode = DE_INSTRUMENT[opcode]; @@ -1255,7 +1333,7 @@ initialize_tools(PyCodeObject *code) assert(event > 0); } assert(event >= 0); - assert(event < PY_MONITORING_INSTRUMENTED_EVENTS); + assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event)); tools[i] = code->_co_monitoring->active_monitors.tools[event]; CHECK(tools[i] != 0); } @@ -1396,7 +1474,7 @@ initialize_lines(PyCodeObject *code) } static void -initialize_line_tools(PyCodeObject *code, _Py_Monitors *all_events) +initialize_line_tools(PyCodeObject *code, _Py_LocalMonitors *all_events) { uint8_t *line_tools = code->_co_monitoring->line_tools; assert(line_tools != NULL); @@ -1416,8 +1494,8 @@ allocate_instrumentation_data(PyCodeObject *code) PyErr_NoMemory(); return -1; } - code->_co_monitoring->local_monitors = (_Py_Monitors){ 0 }; - code->_co_monitoring->active_monitors = (_Py_Monitors){ 0 }; + code->_co_monitoring->local_monitors = (_Py_LocalMonitors){ 0 }; + code->_co_monitoring->active_monitors = (_Py_LocalMonitors){ 0 }; code->_co_monitoring->tools = NULL; code->_co_monitoring->lines = NULL; code->_co_monitoring->line_tools = NULL; @@ -1434,7 +1512,7 @@ update_instrumentation_data(PyCodeObject *code, PyInterpreterState *interp) if (allocate_instrumentation_data(code)) { return -1; } - _Py_Monitors all_events = monitors_or( + _Py_LocalMonitors all_events = local_union( interp->monitors, code->_co_monitoring->local_monitors); bool multitools = multiple_tools(&all_events); @@ -1496,20 +1574,32 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) { if (is_version_up_to_date(code, interp)) { assert( - interp->monitoring_version == 0 || + (interp->ceval.eval_breaker & ~_PY_EVAL_EVENTS_MASK) == 0 || instrumentation_cross_checks(interp, code) ); return 0; } + if (code->co_executors != NULL) { + _PyCode_Clear_Executors(code); + } int code_len = (int)Py_SIZE(code); + /* code->_co_firsttraceable >= code_len indicates + * that no instrumentation can be inserted. + * Exit early to avoid creating instrumentation + * data for potential statically allocated code + * objects. + * See https://github.com/python/cpython/issues/108390 */ + if (code->_co_firsttraceable >= code_len) { + return 0; + } if (update_instrumentation_data(code, interp)) { return -1; } - _Py_Monitors active_events = monitors_or( + _Py_LocalMonitors active_events = local_union( interp->monitors, code->_co_monitoring->local_monitors); - _Py_Monitors new_events; - _Py_Monitors removed_events; + _Py_LocalMonitors new_events; + _Py_LocalMonitors removed_events; bool restarted = interp->last_restart_version > code->_co_instrumentation_version; if (restarted) { @@ -1522,7 +1612,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) assert(monitors_are_empty(monitors_and(new_events, removed_events))); } code->_co_monitoring->active_monitors = active_events; - code->_co_instrumentation_version = interp->monitoring_version; + code->_co_instrumentation_version = global_version(interp); if (monitors_are_empty(new_events) && monitors_are_empty(removed_events)) { #ifdef INSTRUMENT_DEBUG sanity_check_instrumentation(code); @@ -1533,7 +1623,9 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) for (int i = code->_co_firsttraceable; i < code_len; i+= _PyInstruction_GetLength(code, i)) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; CHECK(instr->op.code != 0); + assert(instr->op.code != ENTER_EXECUTOR); int base_opcode = _Py_GetBaseOpcode(code, i); + assert(base_opcode != ENTER_EXECUTOR); if (opcode_has_event(base_opcode)) { int8_t event; if (base_opcode == RESUME) { @@ -1584,7 +1676,9 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) i += _PyInstruction_GetLength(code, i); } } - +#ifdef INSTRUMENT_DEBUG + sanity_check_instrumentation(code); +#endif uint8_t new_line_tools = new_events.tools[PY_MONITORING_EVENT_LINE]; uint8_t new_per_instruction_tools = new_events.tools[PY_MONITORING_EVENT_INSTRUCTION]; @@ -1633,7 +1727,7 @@ instrument_all_executing_code_objects(PyInterpreterState *interp) { PyThreadState* ts = PyInterpreterState_ThreadHead(interp); HEAD_UNLOCK(runtime); while (ts) { - _PyInterpreterFrame *frame = ts->cframe->current_frame; + _PyInterpreterFrame *frame = ts->current_frame; while (frame) { if (frame->owner != FRAME_OWNED_BY_CSTACK) { if (_Py_Instrument(_PyFrame_GetCode(frame), interp)) { @@ -1650,10 +1744,22 @@ instrument_all_executing_code_objects(PyInterpreterState *interp) { } static void -set_events(_Py_Monitors *m, int tool_id, _PyMonitoringEventSet events) +set_events(_Py_GlobalMonitors *m, int tool_id, _PyMonitoringEventSet events) { assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); - for (int e = 0; e < PY_MONITORING_UNGROUPED_EVENTS; e++) { + for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) { + uint8_t *tools = &m->tools[e]; + int active = (events >> e) & 1; + *tools &= ~(1 << tool_id); + *tools |= (active << tool_id); + } +} + +static void +set_local_events(_Py_LocalMonitors *m, int tool_id, _PyMonitoringEventSet events) +{ + assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); + for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) { uint8_t *tools = &m->tools[e]; int val = (events >> e) & 1; *tools &= ~(1 << tool_id); @@ -1673,12 +1779,16 @@ check_tool(PyInterpreterState *interp, int tool_id) return 0; } +/* We share the eval-breaker with flags, so the monitoring + * version goes in the top 24 bits */ +#define MONITORING_VERSION_INCREMENT (1 << _PY_EVAL_EVENTS_BITS) + int _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events) { assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); PyInterpreterState *interp = _PyInterpreterState_GET(); - assert(events < (1 << PY_MONITORING_UNGROUPED_EVENTS)); + assert(events < (1 << _PY_MONITORING_UNGROUPED_EVENTS)); if (check_tool(interp, tool_id)) { return -1; } @@ -1687,7 +1797,12 @@ _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events) return 0; } set_events(&interp->monitors, tool_id, events); - interp->monitoring_version++; + uint32_t new_version = global_version(interp) + MONITORING_VERSION_INCREMENT; + if (new_version == 0) { + PyErr_Format(PyExc_OverflowError, "events set too many times"); + return -1; + } + set_global_version(interp, new_version); return instrument_all_executing_code_objects(interp); } @@ -1696,22 +1811,26 @@ _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEvent { assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); PyInterpreterState *interp = _PyInterpreterState_GET(); - assert(events < (1 << PY_MONITORING_UNGROUPED_EVENTS)); + assert(events < (1 << _PY_MONITORING_LOCAL_EVENTS)); + if (code->_co_firsttraceable >= Py_SIZE(code)) { + PyErr_Format(PyExc_SystemError, "cannot instrument shim code object '%U'", code->co_name); + return -1; + } if (check_tool(interp, tool_id)) { return -1; } if (allocate_instrumentation_data(code)) { return -1; } - _Py_Monitors *local = &code->_co_monitoring->local_monitors; - uint32_t existing_events = get_events(local, tool_id); + _Py_LocalMonitors *local = &code->_co_monitoring->local_monitors; + uint32_t existing_events = get_local_events(local, tool_id); if (existing_events == events) { return 0; } - set_events(local, tool_id, events); + set_local_events(local, tool_id, events); if (is_version_up_to_date(code, interp)) { /* Force instrumentation update */ - code->_co_instrumentation_version = UINT64_MAX; + code->_co_instrumentation_version -= MONITORING_VERSION_INCREMENT; } if (_Py_Instrument(code, interp)) { return -1; @@ -1835,10 +1954,13 @@ monitoring_register_callback_impl(PyObject *module, int tool_id, int event, return NULL; } int event_id = _Py_bit_length(event)-1; - if (event_id < 0 || event_id >= PY_MONITORING_EVENTS) { + if (event_id < 0 || event_id >= _PY_MONITORING_EVENTS) { PyErr_Format(PyExc_ValueError, "invalid event %d", event); return NULL; } + if (PySys_Audit("sys.monitoring.register_callback", "O", func) < 0) { + return NULL; + } if (func == Py_None) { func = NULL; } @@ -1864,7 +1986,7 @@ monitoring_get_events_impl(PyObject *module, int tool_id) if (check_valid_tool(tool_id)) { return -1; } - _Py_Monitors *m = &_PyInterpreterState_GET()->monitors; + _Py_GlobalMonitors *m = &_PyInterpreterState_GET()->monitors; _PyMonitoringEventSet event_set = get_events(m, tool_id); return event_set; } @@ -1885,7 +2007,7 @@ monitoring_set_events_impl(PyObject *module, int tool_id, int event_set) if (check_valid_tool(tool_id)) { return NULL; } - if (event_set < 0 || event_set >= (1 << PY_MONITORING_EVENTS)) { + if (event_set < 0 || event_set >= (1 << _PY_MONITORING_EVENTS)) { PyErr_Format(PyExc_ValueError, "invalid event set 0x%x", event_set); return NULL; } @@ -1927,7 +2049,7 @@ monitoring_get_local_events_impl(PyObject *module, int tool_id, _PyMonitoringEventSet event_set = 0; _PyCoMonitoringData *data = ((PyCodeObject *)code)->_co_monitoring; if (data != NULL) { - for (int e = 0; e < PY_MONITORING_UNGROUPED_EVENTS; e++) { + for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) { if ((data->local_monitors.tools[e] >> tool_id) & 1) { event_set |= (1 << e); } @@ -1961,15 +2083,16 @@ monitoring_set_local_events_impl(PyObject *module, int tool_id, if (check_valid_tool(tool_id)) { return NULL; } - if (event_set < 0 || event_set >= (1 << PY_MONITORING_EVENTS)) { - PyErr_Format(PyExc_ValueError, "invalid event set 0x%x", event_set); - return NULL; - } if ((event_set & C_RETURN_EVENTS) && (event_set & C_CALL_EVENTS) != C_CALL_EVENTS) { PyErr_Format(PyExc_ValueError, "cannot set C_RETURN or C_RAISE events independently"); return NULL; } event_set &= ~C_RETURN_EVENTS; + if (event_set < 0 || event_set >= (1 << _PY_MONITORING_LOCAL_EVENTS)) { + PyErr_Format(PyExc_ValueError, "invalid local event set 0x%x", event_set); + return NULL; + } + if (_PyMonitoring_SetLocalEvents((PyCodeObject*)code, tool_id, event_set)) { return NULL; } @@ -1990,8 +2113,14 @@ monitoring_restart_events_impl(PyObject *module) * last restart version < current version */ PyInterpreterState *interp = _PyInterpreterState_GET(); - interp->last_restart_version = interp->monitoring_version + 1; - interp->monitoring_version = interp->last_restart_version + 1; + uint32_t restart_version = global_version(interp) + MONITORING_VERSION_INCREMENT; + uint32_t new_version = restart_version + MONITORING_VERSION_INCREMENT; + if (new_version <= MONITORING_VERSION_INCREMENT) { + PyErr_Format(PyExc_OverflowError, "events set too many times"); + return NULL; + } + interp->last_restart_version = restart_version; + set_global_version(interp, new_version); if (instrument_all_executing_code_objects(interp)) { return NULL; } @@ -2010,25 +2139,6 @@ add_power2_constant(PyObject *obj, const char *name, int i) return err; } -static const char *const event_names [] = { - [PY_MONITORING_EVENT_PY_START] = "PY_START", - [PY_MONITORING_EVENT_PY_RESUME] = "PY_RESUME", - [PY_MONITORING_EVENT_PY_RETURN] = "PY_RETURN", - [PY_MONITORING_EVENT_PY_YIELD] = "PY_YIELD", - [PY_MONITORING_EVENT_CALL] = "CALL", - [PY_MONITORING_EVENT_LINE] = "LINE", - [PY_MONITORING_EVENT_INSTRUCTION] = "INSTRUCTION", - [PY_MONITORING_EVENT_JUMP] = "JUMP", - [PY_MONITORING_EVENT_BRANCH] = "BRANCH", - [PY_MONITORING_EVENT_C_RETURN] = "C_RETURN", - [PY_MONITORING_EVENT_PY_THROW] = "PY_THROW", - [PY_MONITORING_EVENT_RAISE] = "RAISE", - [PY_MONITORING_EVENT_EXCEPTION_HANDLED] = "EXCEPTION_HANDLED", - [PY_MONITORING_EVENT_C_RAISE] = "C_RAISE", - [PY_MONITORING_EVENT_PY_UNWIND] = "PY_UNWIND", - [PY_MONITORING_EVENT_STOP_ITERATION] = "STOP_ITERATION", -}; - /*[clinic input] monitoring._all_events [clinic start generated code]*/ @@ -2042,7 +2152,7 @@ monitoring__all_events_impl(PyObject *module) if (res == NULL) { return NULL; } - for (int e = 0; e < PY_MONITORING_UNGROUPED_EVENTS; e++) { + for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) { uint8_t tools = interp->monitors.tools[e]; if (tools == 0) { continue; @@ -2101,7 +2211,7 @@ PyObject *_Py_CreateMonitoringObject(void) if (err) { goto error; } - for (int i = 0; i < PY_MONITORING_EVENTS; i++) { + for (int i = 0; i < _PY_MONITORING_EVENTS; i++) { if (add_power2_constant(events, event_names[i], i)) { goto error; } diff --git a/Python/intrinsics.c b/Python/intrinsics.c index 037b74ca820fab..bbd79ec473f470 100644 --- a/Python/intrinsics.c +++ b/Python/intrinsics.c @@ -4,17 +4,18 @@ #include "Python.h" #include "pycore_frame.h" #include "pycore_function.h" -#include "pycore_runtime.h" #include "pycore_global_objects.h" -#include "pycore_intrinsics.h" -#include "pycore_pyerrors.h" -#include "pycore_typevarobject.h" +#include "pycore_intrinsics.h" // INTRINSIC_PRINT +#include "pycore_pyerrors.h" // _PyErr_SetString() +#include "pycore_runtime.h" // _Py_ID() +#include "pycore_sysmodule.h" // _PySys_GetAttr() +#include "pycore_typevarobject.h" // _Py_make_typevar() /******** Unary functions ********/ static PyObject * -no_intrinsic(PyThreadState* tstate, PyObject *unused) +no_intrinsic1(PyThreadState* tstate, PyObject *unused) { _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function"); return NULL; @@ -120,7 +121,7 @@ import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) static PyObject * import_star(PyThreadState* tstate, PyObject *from) { - _PyInterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = tstate->current_frame; if (_PyFrame_FastToLocalsWithError(frame) < 0) { return NULL; } @@ -142,7 +143,7 @@ import_star(PyThreadState* tstate, PyObject *from) static PyObject * stopiteration_error(PyThreadState* tstate, PyObject *exc) { - _PyInterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = tstate->current_frame; assert(frame->owner == FRAME_OWNED_BY_GENERATOR); assert(PyExceptionInstance_Check(exc)); const char *msg = NULL; @@ -203,25 +204,35 @@ make_typevar(PyThreadState* Py_UNUSED(ignored), PyObject *v) return _Py_make_typevar(v, NULL, NULL); } -const instrinsic_func1 + +#define INTRINSIC_FUNC_ENTRY(N, F) \ + [N] = {F, #N}, + +const intrinsic_func1_info _PyIntrinsics_UnaryFunctions[] = { - [0] = no_intrinsic, - [INTRINSIC_PRINT] = print_expr, - [INTRINSIC_IMPORT_STAR] = import_star, - [INTRINSIC_STOPITERATION_ERROR] = stopiteration_error, - [INTRINSIC_ASYNC_GEN_WRAP] = _PyAsyncGenValueWrapperNew, - [INTRINSIC_UNARY_POSITIVE] = unary_pos, - [INTRINSIC_LIST_TO_TUPLE] = list_to_tuple, - [INTRINSIC_TYPEVAR] = make_typevar, - [INTRINSIC_PARAMSPEC] = _Py_make_paramspec, - [INTRINSIC_TYPEVARTUPLE] = _Py_make_typevartuple, - [INTRINSIC_SUBSCRIPT_GENERIC] = _Py_subscript_generic, - [INTRINSIC_TYPEALIAS] = _Py_make_typealias, + INTRINSIC_FUNC_ENTRY(INTRINSIC_1_INVALID, no_intrinsic1) + INTRINSIC_FUNC_ENTRY(INTRINSIC_PRINT, print_expr) + INTRINSIC_FUNC_ENTRY(INTRINSIC_IMPORT_STAR, import_star) + INTRINSIC_FUNC_ENTRY(INTRINSIC_STOPITERATION_ERROR, stopiteration_error) + INTRINSIC_FUNC_ENTRY(INTRINSIC_ASYNC_GEN_WRAP, _PyAsyncGenValueWrapperNew) + INTRINSIC_FUNC_ENTRY(INTRINSIC_UNARY_POSITIVE, unary_pos) + INTRINSIC_FUNC_ENTRY(INTRINSIC_LIST_TO_TUPLE, list_to_tuple) + INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR, make_typevar) + INTRINSIC_FUNC_ENTRY(INTRINSIC_PARAMSPEC, _Py_make_paramspec) + INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVARTUPLE, _Py_make_typevartuple) + INTRINSIC_FUNC_ENTRY(INTRINSIC_SUBSCRIPT_GENERIC, _Py_subscript_generic) + INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEALIAS, _Py_make_typealias) }; /******** Binary functions ********/ +static PyObject * +no_intrinsic2(PyThreadState* tstate, PyObject *unused1, PyObject *unused2) +{ + _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function"); + return NULL; +} static PyObject * prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs) @@ -246,10 +257,31 @@ make_typevar_with_constraints(PyThreadState* Py_UNUSED(ignored), PyObject *name, return _Py_make_typevar(name, NULL, evaluate_constraints); } -const instrinsic_func2 +const intrinsic_func2_info _PyIntrinsics_BinaryFunctions[] = { - [INTRINSIC_PREP_RERAISE_STAR] = prep_reraise_star, - [INTRINSIC_TYPEVAR_WITH_BOUND] = make_typevar_with_bound, - [INTRINSIC_TYPEVAR_WITH_CONSTRAINTS] = make_typevar_with_constraints, - [INTRINSIC_SET_FUNCTION_TYPE_PARAMS] = _Py_set_function_type_params, + INTRINSIC_FUNC_ENTRY(INTRINSIC_2_INVALID, no_intrinsic2) + INTRINSIC_FUNC_ENTRY(INTRINSIC_PREP_RERAISE_STAR, prep_reraise_star) + INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_BOUND, make_typevar_with_bound) + INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_CONSTRAINTS, make_typevar_with_constraints) + INTRINSIC_FUNC_ENTRY(INTRINSIC_SET_FUNCTION_TYPE_PARAMS, _Py_set_function_type_params) }; + +#undef INTRINSIC_FUNC_ENTRY + +PyObject* +PyUnstable_GetUnaryIntrinsicName(int index) +{ + if (index < 0 || index > MAX_INTRINSIC_1) { + return NULL; + } + return PyUnicode_FromString(_PyIntrinsics_UnaryFunctions[index].name); +} + +PyObject* +PyUnstable_GetBinaryIntrinsicName(int index) +{ + if (index < 0 || index > MAX_INTRINSIC_2) { + return NULL; + } + return PyUnicode_FromString(_PyIntrinsics_BinaryFunctions[index].name); +} diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index 9cc48fc9493a05..97d39a14ae43d0 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -2,12 +2,13 @@ * Provides callables to forward PEP 669 events to legacy events. */ -#include #include "Python.h" -#include "opcode.h" -#include "pycore_ceval.h" +#include "pycore_ceval.h" // export _PyEval_SetProfile() #include "pycore_object.h" -#include "pycore_sysmodule.h" +#include "pycore_sysmodule.h" // _PySys_Audit() + +#include "opcode.h" +#include typedef struct _PyLegacyEventHandler { PyObject_HEAD @@ -64,6 +65,16 @@ sys_profile_func3( return call_profile_func(self, args[2]); } +static PyObject * +sys_profile_unwind( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + return call_profile_func(self, Py_None); +} + static PyObject * sys_profile_call_or_return( _PyLegacyEventHandler *self, PyObject *const *args, @@ -152,6 +163,16 @@ sys_trace_func2( return call_trace_func(self, Py_None); } +static PyObject * +sys_trace_func3( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + return call_trace_func(self, Py_None); +} + static PyObject * sys_trace_return( _PyLegacyEventHandler *self, PyObject *const *args, @@ -236,7 +257,7 @@ sys_trace_line_func( Py_RETURN_NONE; } assert(PyVectorcall_NARGS(nargsf) == 2); - int line = _PyLong_AsInt(args[1]); + int line = PyLong_AsInt(args[1]); assert(line >= 0); PyFrameObject *frame = PyEval_GetFrame(); if (frame == NULL) { @@ -262,9 +283,9 @@ sys_trace_jump_func( Py_RETURN_NONE; } assert(PyVectorcall_NARGS(nargsf) == 3); - int from = _PyLong_AsInt(args[1])/sizeof(_Py_CODEUNIT); + int from = PyLong_AsInt(args[1])/sizeof(_Py_CODEUNIT); assert(from >= 0); - int to = _PyLong_AsInt(args[2])/sizeof(_Py_CODEUNIT); + int to = PyLong_AsInt(args[2])/sizeof(_Py_CODEUNIT); assert(to >= 0); if (to > from) { /* Forward jump */ @@ -356,13 +377,18 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) PY_MONITORING_EVENT_PY_START, PY_MONITORING_EVENT_PY_RESUME)) { return -1; } + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_func3, PyTrace_CALL, + PY_MONITORING_EVENT_PY_THROW, -1)) { + return -1; + } if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, (vectorcallfunc)sys_profile_func3, PyTrace_RETURN, PY_MONITORING_EVENT_PY_RETURN, PY_MONITORING_EVENT_PY_YIELD)) { return -1; } if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, - (vectorcallfunc)sys_profile_func2, PyTrace_RETURN, + (vectorcallfunc)sys_profile_unwind, PyTrace_RETURN, PY_MONITORING_EVENT_PY_UNWIND, -1)) { return -1; } @@ -396,7 +422,8 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) events = (1 << PY_MONITORING_EVENT_PY_START) | (1 << PY_MONITORING_EVENT_PY_RESUME) | (1 << PY_MONITORING_EVENT_PY_RETURN) | (1 << PY_MONITORING_EVENT_PY_YIELD) | - (1 << PY_MONITORING_EVENT_CALL) | (1 << PY_MONITORING_EVENT_PY_UNWIND); + (1 << PY_MONITORING_EVENT_CALL) | (1 << PY_MONITORING_EVENT_PY_UNWIND) | + (1 << PY_MONITORING_EVENT_PY_THROW); } return _PyMonitoring_SetEvents(PY_MONITORING_SYS_PROFILE_ID, events); } @@ -425,7 +452,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) return -1; } if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, - (vectorcallfunc)sys_trace_func2, PyTrace_CALL, + (vectorcallfunc)sys_trace_func3, PyTrace_CALL, PY_MONITORING_EVENT_PY_THROW, -1)) { return -1; } @@ -450,7 +477,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) return -1; } if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, - (vectorcallfunc)sys_trace_func2, PyTrace_RETURN, + (vectorcallfunc)sys_trace_func3, PyTrace_RETURN, PY_MONITORING_EVENT_PY_UNWIND, -1)) { return -1; } diff --git a/Python/lock.c b/Python/lock.c new file mode 100644 index 00000000000000..3dad2aa93b5cc9 --- /dev/null +++ b/Python/lock.c @@ -0,0 +1,297 @@ +// Lock implementation + +#include "Python.h" + +#include "pycore_lock.h" +#include "pycore_parking_lot.h" +#include "pycore_semaphore.h" + +#ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include // SwitchToThread() +#elif defined(HAVE_SCHED_H) +#include // sched_yield() +#endif + +// If a thread waits on a lock for longer than TIME_TO_BE_FAIR_NS (1 ms), then +// the unlocking thread directly hands off ownership of the lock. This avoids +// starvation. +static const _PyTime_t TIME_TO_BE_FAIR_NS = 1000*1000; + +// Spin for a bit before parking the thread. This is only enabled for +// `--disable-gil` builds because it is unlikely to be helpful if the GIL is +// enabled. +#if Py_NOGIL +static const int MAX_SPIN_COUNT = 40; +#else +static const int MAX_SPIN_COUNT = 0; +#endif + +struct mutex_entry { + // The time after which the unlocking thread should hand off lock ownership + // directly to the waiting thread. Written by the waiting thread. + _PyTime_t time_to_be_fair; + + // Set to 1 if the lock was handed off. Written by the unlocking thread. + int handed_off; +}; + +static void +_Py_yield(void) +{ +#ifdef MS_WINDOWS + SwitchToThread(); +#elif defined(HAVE_SCHED_H) + sched_yield(); +#endif +} + +void +_PyMutex_LockSlow(PyMutex *m) +{ + _PyMutex_LockTimed(m, -1, _PY_LOCK_DETACH); +} + +PyLockStatus +_PyMutex_LockTimed(PyMutex *m, _PyTime_t timeout, _PyLockFlags flags) +{ + uint8_t v = _Py_atomic_load_uint8_relaxed(&m->v); + if ((v & _Py_LOCKED) == 0) { + if (_Py_atomic_compare_exchange_uint8(&m->v, &v, v|_Py_LOCKED)) { + return PY_LOCK_ACQUIRED; + } + } + else if (timeout == 0) { + return PY_LOCK_FAILURE; + } + + _PyTime_t now = _PyTime_GetMonotonicClock(); + _PyTime_t endtime = 0; + if (timeout > 0) { + endtime = _PyTime_Add(now, timeout); + } + + struct mutex_entry entry = { + .time_to_be_fair = now + TIME_TO_BE_FAIR_NS, + .handed_off = 0, + }; + + Py_ssize_t spin_count = 0; + for (;;) { + if ((v & _Py_LOCKED) == 0) { + // The lock is unlocked. Try to grab it. + if (_Py_atomic_compare_exchange_uint8(&m->v, &v, v|_Py_LOCKED)) { + return PY_LOCK_ACQUIRED; + } + continue; + } + + if (!(v & _Py_HAS_PARKED) && spin_count < MAX_SPIN_COUNT) { + // Spin for a bit. + _Py_yield(); + spin_count++; + continue; + } + + if (timeout == 0) { + return PY_LOCK_FAILURE; + } + + uint8_t newv = v; + if (!(v & _Py_HAS_PARKED)) { + // We are the first waiter. Set the _Py_HAS_PARKED flag. + newv = v | _Py_HAS_PARKED; + if (!_Py_atomic_compare_exchange_uint8(&m->v, &v, newv)) { + continue; + } + } + + int ret = _PyParkingLot_Park(&m->v, &newv, sizeof(newv), timeout, + &entry, (flags & _PY_LOCK_DETACH) != 0); + if (ret == Py_PARK_OK) { + if (entry.handed_off) { + // We own the lock now. + assert(_Py_atomic_load_uint8_relaxed(&m->v) & _Py_LOCKED); + return PY_LOCK_ACQUIRED; + } + } + else if (ret == Py_PARK_INTR && (flags & _PY_LOCK_HANDLE_SIGNALS)) { + if (Py_MakePendingCalls() < 0) { + return PY_LOCK_INTR; + } + } + else if (ret == Py_PARK_TIMEOUT) { + assert(timeout >= 0); + return PY_LOCK_FAILURE; + } + + if (timeout > 0) { + timeout = _PyDeadline_Get(endtime); + if (timeout <= 0) { + // Avoid negative values because those mean block forever. + timeout = 0; + } + } + + v = _Py_atomic_load_uint8_relaxed(&m->v); + } +} + +static void +mutex_unpark(PyMutex *m, struct mutex_entry *entry, int has_more_waiters) +{ + uint8_t v = 0; + if (entry) { + _PyTime_t now = _PyTime_GetMonotonicClock(); + int should_be_fair = now > entry->time_to_be_fair; + + entry->handed_off = should_be_fair; + if (should_be_fair) { + v |= _Py_LOCKED; + } + if (has_more_waiters) { + v |= _Py_HAS_PARKED; + } + } + _Py_atomic_store_uint8(&m->v, v); +} + +int +_PyMutex_TryUnlock(PyMutex *m) +{ + uint8_t v = _Py_atomic_load_uint8(&m->v); + for (;;) { + if ((v & _Py_LOCKED) == 0) { + // error: the mutex is not locked + return -1; + } + else if ((v & _Py_HAS_PARKED)) { + // wake up a single thread + _PyParkingLot_Unpark(&m->v, (_Py_unpark_fn_t *)mutex_unpark, m); + return 0; + } + else if (_Py_atomic_compare_exchange_uint8(&m->v, &v, _Py_UNLOCKED)) { + // fast-path: no waiters + return 0; + } + } +} + +void +_PyMutex_UnlockSlow(PyMutex *m) +{ + if (_PyMutex_TryUnlock(m) < 0) { + Py_FatalError("unlocking mutex that is not locked"); + } +} + +// _PyRawMutex stores a linked list of `struct raw_mutex_entry`, one for each +// thread waiting on the mutex, directly in the mutex itself. +struct raw_mutex_entry { + struct raw_mutex_entry *next; + _PySemaphore sema; +}; + +void +_PyRawMutex_LockSlow(_PyRawMutex *m) +{ + struct raw_mutex_entry waiter; + _PySemaphore_Init(&waiter.sema); + + uintptr_t v = _Py_atomic_load_uintptr(&m->v); + for (;;) { + if ((v & _Py_LOCKED) == 0) { + // Unlocked: try to grab it (even if it has a waiter). + if (_Py_atomic_compare_exchange_uintptr(&m->v, &v, v|_Py_LOCKED)) { + break; + } + continue; + } + + // Locked: try to add ourselves as a waiter. + waiter.next = (struct raw_mutex_entry *)(v & ~1); + uintptr_t desired = ((uintptr_t)&waiter)|_Py_LOCKED; + if (!_Py_atomic_compare_exchange_uintptr(&m->v, &v, desired)) { + continue; + } + + // Wait for us to be woken up. Note that we still have to lock the + // mutex ourselves: it is NOT handed off to us. + _PySemaphore_Wait(&waiter.sema, -1, /*detach=*/0); + } + + _PySemaphore_Destroy(&waiter.sema); +} + +void +_PyRawMutex_UnlockSlow(_PyRawMutex *m) +{ + uintptr_t v = _Py_atomic_load_uintptr(&m->v); + for (;;) { + if ((v & _Py_LOCKED) == 0) { + Py_FatalError("unlocking mutex that is not locked"); + } + + struct raw_mutex_entry *waiter = (struct raw_mutex_entry *)(v & ~1); + if (waiter) { + uintptr_t next_waiter = (uintptr_t)waiter->next; + if (_Py_atomic_compare_exchange_uintptr(&m->v, &v, next_waiter)) { + _PySemaphore_Wakeup(&waiter->sema); + return; + } + } + else { + if (_Py_atomic_compare_exchange_uintptr(&m->v, &v, _Py_UNLOCKED)) { + return; + } + } + } +} + +void +_PyEvent_Notify(PyEvent *evt) +{ + uintptr_t v = _Py_atomic_exchange_uint8(&evt->v, _Py_LOCKED); + if (v == _Py_UNLOCKED) { + // no waiters + return; + } + else if (v == _Py_LOCKED) { + // event already set + return; + } + else { + assert(v == _Py_HAS_PARKED); + _PyParkingLot_UnparkAll(&evt->v); + } +} + +void +PyEvent_Wait(PyEvent *evt) +{ + while (!PyEvent_WaitTimed(evt, -1)) + ; +} + +int +PyEvent_WaitTimed(PyEvent *evt, _PyTime_t timeout_ns) +{ + for (;;) { + uint8_t v = _Py_atomic_load_uint8(&evt->v); + if (v == _Py_LOCKED) { + // event already set + return 1; + } + if (v == _Py_UNLOCKED) { + if (!_Py_atomic_compare_exchange_uint8(&evt->v, &v, _Py_HAS_PARKED)) { + continue; + } + } + + uint8_t expected = _Py_HAS_PARKED; + (void) _PyParkingLot_Park(&evt->v, &expected, sizeof(evt->v), + timeout_ns, NULL, 1); + + return _Py_atomic_load_uint8(&evt->v) == _Py_LOCKED; + } +} diff --git a/Python/makeopcodetargets.py b/Python/makeopcodetargets.py deleted file mode 100755 index 5843079b729936..00000000000000 --- a/Python/makeopcodetargets.py +++ /dev/null @@ -1,56 +0,0 @@ -#! /usr/bin/env python -"""Generate C code for the jump table of the threaded code interpreter -(for compilers supporting computed gotos or "labels-as-values", such as gcc). -""" - -import os -import sys - - -# 2023-04-27(warsaw): Pre-Python 3.12, this would catch ImportErrors and try to -# import imp, and then use imp.load_module(). The imp module was removed in -# Python 3.12 (and long deprecated before that), and it's unclear under what -# conditions this import will now fail, so the fallback was simply removed. -from importlib.machinery import SourceFileLoader - -def find_module(modname): - """Finds and returns a module in the local dist/checkout. - """ - modpath = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "Lib", modname + ".py") - return SourceFileLoader(modname, modpath).load_module() - - -def write_contents(f): - """Write C code contents to the target file object. - """ - opcode = find_module('opcode') - _opcode_metadata = find_module('_opcode_metadata') - targets = ['_unknown_opcode'] * 256 - for opname, op in opcode.opmap.items(): - if not opcode.is_pseudo(op): - targets[op] = "TARGET_%s" % opname - next_op = 1 - for opname in _opcode_metadata._specialized_instructions: - while targets[next_op] != '_unknown_opcode': - next_op += 1 - targets[next_op] = "TARGET_%s" % opname - f.write("static void *opcode_targets[256] = {\n") - f.write(",\n".join([" &&%s" % s for s in targets])) - f.write("\n};\n") - - -def main(): - if len(sys.argv) >= 3: - sys.exit("Too many arguments") - if len(sys.argv) == 2: - target = sys.argv[1] - else: - target = "Python/opcode_targets.h" - with open(target, "w") as f: - write_contents(f) - print("Jump table written into %s" % target) - - -if __name__ == "__main__": - main() diff --git a/Python/marshal.c b/Python/marshal.c index 517220a4463cf3..8940582c7f5328 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -9,8 +9,9 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_code.h" // _PyCode_New() -#include "pycore_long.h" // _PyLong_DigitCount #include "pycore_hashtable.h" // _Py_hashtable_t +#include "pycore_long.h" // _PyLong_DigitCount +#include "pycore_setobject.h" // _PySet_NextEntry() #include "marshal.h" // Py_MARSHAL_VERSION /*[clinic input] diff --git a/Python/modsupport.c b/Python/modsupport.c index 18b3322ae81d11..e9abf304e6502c 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -88,6 +88,24 @@ static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t); static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t); static PyObject *do_mkvalue(const char**, va_list *); +static int +check_end(const char **p_format, char endchar) +{ + const char *f = *p_format; + while (*f != endchar) { + if (*f != ' ' && *f != '\t' && *f != ',' && *f != ':') { + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return 0; + } + f++; + } + if (endchar) { + f++; + } + *p_format = f; + return 1; +} static void do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) @@ -108,14 +126,9 @@ do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) } } Py_XDECREF(v); - if (**p_format != endchar) { - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); + if (!check_end(p_format, endchar)) { return; } - if (endchar) { - ++*p_format; - } } static PyObject * @@ -157,14 +170,10 @@ do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) Py_DECREF(k); Py_DECREF(v); } - if (**p_format != endchar) { + if (!check_end(p_format, endchar)) { Py_DECREF(d); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); return NULL; } - if (endchar) - ++*p_format; return d; } @@ -191,14 +200,10 @@ do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) } PyList_SET_ITEM(v, i, w); } - if (**p_format != endchar) { + if (!check_end(p_format, endchar)) { Py_DECREF(v); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); return NULL; } - if (endchar) - ++*p_format; return v; } @@ -221,14 +226,9 @@ do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, } stack[i] = w; } - if (**p_format != endchar) { - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); + if (!check_end(p_format, endchar)) { goto error; } - if (endchar) { - ++*p_format; - } return 0; error: @@ -261,14 +261,10 @@ do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) } PyTuple_SET_ITEM(v, i, w); } - if (**p_format != endchar) { + if (!check_end(p_format, endchar)) { Py_DECREF(v); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); return NULL; } - if (endchar) - ++*p_format; return v; } diff --git a/Python/mystrtoul.c b/Python/mystrtoul.c index e6fe154eed611a..fcd3e27f17f4e9 100644 --- a/Python/mystrtoul.c +++ b/Python/mystrtoul.c @@ -1,16 +1,22 @@ +// strtol() and strtoul(), renamed to avoid conflicts. +// +// API: +// +// - PyOS_strtol(): convert string to C long integer. +// - PyOS_strtoul(): convert string to C unsigned long integer. + #include "Python.h" #include "pycore_long.h" // _PyLong_DigitValue #if defined(__sgi) && !defined(_SGI_MP_SOURCE) -#define _SGI_MP_SOURCE +# define _SGI_MP_SOURCE #endif /* strtol and strtoul, renamed to avoid conflicts */ -#include #ifdef HAVE_ERRNO_H -#include +# include // errno #endif /* Static overflow check values for bases 2 through 36. @@ -75,7 +81,7 @@ static const int digitlimit[] = { 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */ 13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */ #else -#error "Need table for SIZEOF_LONG" +# error "Need table for SIZEOF_LONG" #endif /* diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index d84d253c912a28..bcd6ea7564f9b3 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -1,193 +1,123 @@ static void *opcode_targets[256] = { &&TARGET_CACHE, - &&TARGET_POP_TOP, - &&TARGET_PUSH_NULL, - &&TARGET_INTERPRETER_EXIT, + &&TARGET_BEFORE_ASYNC_WITH, + &&TARGET_BEFORE_WITH, + &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, + &&TARGET_BINARY_SLICE, + &&TARGET_BINARY_SUBSCR, + &&TARGET_CHECK_EG_MATCH, + &&TARGET_CHECK_EXC_MATCH, + &&TARGET_CLEANUP_THROW, + &&TARGET_DELETE_SUBSCR, + &&TARGET_END_ASYNC_FOR, &&TARGET_END_FOR, &&TARGET_END_SEND, - &&TARGET_TO_BOOL, - &&TARGET_TO_BOOL_ALWAYS_TRUE, - &&TARGET_TO_BOOL_BOOL, - &&TARGET_NOP, - &&TARGET_TO_BOOL_INT, - &&TARGET_UNARY_NEGATIVE, - &&TARGET_UNARY_NOT, - &&TARGET_TO_BOOL_LIST, - &&TARGET_TO_BOOL_NONE, - &&TARGET_UNARY_INVERT, &&TARGET_EXIT_INIT_CHECK, - &&TARGET_RESERVED, - &&TARGET_TO_BOOL_STR, - &&TARGET_BINARY_OP_MULTIPLY_INT, - &&TARGET_BINARY_OP_ADD_INT, - &&TARGET_BINARY_OP_SUBTRACT_INT, - &&TARGET_BINARY_OP_MULTIPLY_FLOAT, - &&TARGET_BINARY_OP_ADD_FLOAT, - &&TARGET_MAKE_FUNCTION, - &&TARGET_BINARY_SUBSCR, - &&TARGET_BINARY_SLICE, - &&TARGET_STORE_SLICE, - &&TARGET_BINARY_OP_SUBTRACT_FLOAT, - &&TARGET_BINARY_OP_ADD_UNICODE, - &&TARGET_GET_LEN, - &&TARGET_MATCH_MAPPING, - &&TARGET_MATCH_SEQUENCE, - &&TARGET_MATCH_KEYS, - &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, - &&TARGET_PUSH_EXC_INFO, - &&TARGET_CHECK_EXC_MATCH, - &&TARGET_CHECK_EG_MATCH, - &&TARGET_BINARY_SUBSCR_DICT, - &&TARGET_BINARY_SUBSCR_GETITEM, &&TARGET_FORMAT_SIMPLE, &&TARGET_FORMAT_WITH_SPEC, - &&TARGET_BINARY_SUBSCR_LIST_INT, - &&TARGET_BINARY_SUBSCR_TUPLE_INT, - &&TARGET_STORE_SUBSCR_DICT, - &&TARGET_STORE_SUBSCR_LIST_INT, - &&TARGET_SEND_GEN, - &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, - &&TARGET_UNPACK_SEQUENCE_TUPLE, - &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, + &&TARGET_RESERVED, &&TARGET_GET_ANEXT, - &&TARGET_BEFORE_ASYNC_WITH, - &&TARGET_BEFORE_WITH, - &&TARGET_END_ASYNC_FOR, - &&TARGET_CLEANUP_THROW, - &&TARGET_UNPACK_SEQUENCE_LIST, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, - &&TARGET_STORE_ATTR_SLOT, - &&TARGET_STORE_ATTR_WITH_HINT, - &&TARGET_STORE_SUBSCR, - &&TARGET_DELETE_SUBSCR, - &&TARGET_LOAD_GLOBAL_MODULE, - &&TARGET_LOAD_GLOBAL_BUILTIN, - &&TARGET_LOAD_SUPER_ATTR_ATTR, - &&TARGET_LOAD_SUPER_ATTR_METHOD, - &&TARGET_LOAD_ATTR_INSTANCE_VALUE, - &&TARGET_LOAD_ATTR_MODULE, &&TARGET_GET_ITER, + &&TARGET_GET_LEN, &&TARGET_GET_YIELD_FROM_ITER, - &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_LOAD_ATTR_SLOT, - &&TARGET_LOAD_ATTR_CLASS, + &&TARGET_INTERPRETER_EXIT, &&TARGET_LOAD_ASSERTION_ERROR, + &&TARGET_LOAD_BUILD_CLASS, + &&TARGET_LOAD_LOCALS, + &&TARGET_MAKE_FUNCTION, + &&TARGET_MATCH_KEYS, + &&TARGET_MATCH_MAPPING, + &&TARGET_MATCH_SEQUENCE, + &&TARGET_NOP, + &&TARGET_POP_EXCEPT, + &&TARGET_POP_TOP, + &&TARGET_PUSH_EXC_INFO, + &&TARGET_PUSH_NULL, &&TARGET_RETURN_GENERATOR, - &&TARGET_LOAD_ATTR_PROPERTY, - &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, - &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, - &&TARGET_LOAD_ATTR_METHOD_NO_DICT, - &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, - &&TARGET_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, - &&TARGET_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, &&TARGET_RETURN_VALUE, - &&TARGET_COMPARE_OP_FLOAT, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_COMPARE_OP_INT, - &&TARGET_LOAD_LOCALS, - &&TARGET_COMPARE_OP_STR, - &&TARGET_POP_EXCEPT, - &&TARGET_STORE_NAME, - &&TARGET_DELETE_NAME, - &&TARGET_UNPACK_SEQUENCE, - &&TARGET_FOR_ITER, - &&TARGET_UNPACK_EX, - &&TARGET_STORE_ATTR, - &&TARGET_DELETE_ATTR, - &&TARGET_STORE_GLOBAL, - &&TARGET_DELETE_GLOBAL, - &&TARGET_SWAP, - &&TARGET_LOAD_CONST, - &&TARGET_LOAD_NAME, - &&TARGET_BUILD_TUPLE, + &&TARGET_STORE_SLICE, + &&TARGET_STORE_SUBSCR, + &&TARGET_TO_BOOL, + &&TARGET_UNARY_INVERT, + &&TARGET_UNARY_NEGATIVE, + &&TARGET_UNARY_NOT, + &&TARGET_WITH_EXCEPT_START, + &&TARGET_BINARY_OP, + &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_LIST, - &&TARGET_BUILD_SET, &&TARGET_BUILD_MAP, - &&TARGET_LOAD_ATTR, + &&TARGET_BUILD_SET, + &&TARGET_BUILD_SLICE, + &&TARGET_BUILD_STRING, + &&TARGET_BUILD_TUPLE, + &&TARGET_CALL, + &&TARGET_CALL_FUNCTION_EX, + &&TARGET_CALL_INTRINSIC_1, + &&TARGET_CALL_INTRINSIC_2, + &&TARGET_CALL_KW, &&TARGET_COMPARE_OP, - &&TARGET_IMPORT_NAME, - &&TARGET_IMPORT_FROM, - &&TARGET_JUMP_FORWARD, - &&TARGET_FOR_ITER_LIST, - &&TARGET_FOR_ITER_TUPLE, - &&TARGET_FOR_ITER_RANGE, - &&TARGET_POP_JUMP_IF_FALSE, - &&TARGET_POP_JUMP_IF_TRUE, - &&TARGET_LOAD_GLOBAL, - &&TARGET_IS_OP, &&TARGET_CONTAINS_OP, - &&TARGET_RERAISE, + &&TARGET_CONVERT_VALUE, &&TARGET_COPY, - &&TARGET_RETURN_CONST, - &&TARGET_BINARY_OP, - &&TARGET_SEND, - &&TARGET_LOAD_FAST, - &&TARGET_STORE_FAST, + &&TARGET_COPY_FREE_VARS, + &&TARGET_DELETE_ATTR, + &&TARGET_DELETE_DEREF, &&TARGET_DELETE_FAST, - &&TARGET_LOAD_FAST_CHECK, - &&TARGET_POP_JUMP_IF_NOT_NONE, - &&TARGET_POP_JUMP_IF_NONE, - &&TARGET_RAISE_VARARGS, + &&TARGET_DELETE_GLOBAL, + &&TARGET_DELETE_NAME, + &&TARGET_DICT_MERGE, + &&TARGET_DICT_UPDATE, + &&TARGET_ENTER_EXECUTOR, + &&TARGET_EXTENDED_ARG, + &&TARGET_FOR_ITER, &&TARGET_GET_AWAITABLE, - &&TARGET_FOR_ITER_GEN, - &&TARGET_BUILD_SLICE, + &&TARGET_IMPORT_FROM, + &&TARGET_IMPORT_NAME, + &&TARGET_IS_OP, + &&TARGET_JUMP_BACKWARD, &&TARGET_JUMP_BACKWARD_NO_INTERRUPT, - &&TARGET_MAKE_CELL, - &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS, + &&TARGET_JUMP_FORWARD, + &&TARGET_LIST_APPEND, + &&TARGET_LIST_EXTEND, + &&TARGET_LOAD_ATTR, + &&TARGET_LOAD_CONST, &&TARGET_LOAD_DEREF, - &&TARGET_STORE_DEREF, - &&TARGET_DELETE_DEREF, - &&TARGET_JUMP_BACKWARD, - &&TARGET_LOAD_SUPER_ATTR, - &&TARGET_CALL_FUNCTION_EX, + &&TARGET_LOAD_FAST, &&TARGET_LOAD_FAST_AND_CLEAR, - &&TARGET_EXTENDED_ARG, - &&TARGET_LIST_APPEND, - &&TARGET_SET_ADD, + &&TARGET_LOAD_FAST_CHECK, + &&TARGET_LOAD_FAST_LOAD_FAST, + &&TARGET_LOAD_FROM_DICT_OR_DEREF, + &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, + &&TARGET_LOAD_GLOBAL, + &&TARGET_LOAD_NAME, + &&TARGET_LOAD_SUPER_ATTR, + &&TARGET_MAKE_CELL, &&TARGET_MAP_ADD, - &&TARGET_CALL_PY_EXACT_ARGS, - &&TARGET_COPY_FREE_VARS, - &&TARGET_YIELD_VALUE, - &&TARGET_RESUME, &&TARGET_MATCH_CLASS, - &&TARGET_CALL_PY_WITH_DEFAULTS, - &&TARGET_CALL_NO_KW_TYPE_1, - &&TARGET_CALL_NO_KW_STR_1, - &&TARGET_BUILD_CONST_KEY_MAP, - &&TARGET_BUILD_STRING, - &&TARGET_CONVERT_VALUE, - &&TARGET_CALL_NO_KW_TUPLE_1, - &&TARGET_CALL_BUILTIN_CLASS, - &&TARGET_CALL_NO_KW_BUILTIN_O, - &&TARGET_LIST_EXTEND, + &&TARGET_POP_JUMP_IF_FALSE, + &&TARGET_POP_JUMP_IF_NONE, + &&TARGET_POP_JUMP_IF_NOT_NONE, + &&TARGET_POP_JUMP_IF_TRUE, + &&TARGET_RAISE_VARARGS, + &&TARGET_RERAISE, + &&TARGET_RETURN_CONST, + &&TARGET_SEND, + &&TARGET_SET_ADD, + &&TARGET_SET_FUNCTION_ATTRIBUTE, &&TARGET_SET_UPDATE, - &&TARGET_DICT_MERGE, - &&TARGET_DICT_UPDATE, - &&TARGET_CALL_NO_KW_BUILTIN_FAST, - &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS, - &&TARGET_LOAD_FAST_LOAD_FAST, + &&TARGET_STORE_ATTR, + &&TARGET_STORE_DEREF, + &&TARGET_STORE_FAST, &&TARGET_STORE_FAST_LOAD_FAST, &&TARGET_STORE_FAST_STORE_FAST, - &&TARGET_CALL, - &&TARGET_KW_NAMES, - &&TARGET_CALL_INTRINSIC_1, - &&TARGET_CALL_INTRINSIC_2, - &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, - &&TARGET_LOAD_FROM_DICT_OR_DEREF, - &&TARGET_SET_FUNCTION_ATTRIBUTE, - &&TARGET_CALL_NO_KW_LEN, - &&TARGET_CALL_NO_KW_ISINSTANCE, - &&TARGET_CALL_NO_KW_LIST_APPEND, - &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_O, - &&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, - &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, - &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_FAST, - &&TARGET_CALL_NO_KW_ALLOC_AND_ENTER_INIT, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_STORE_GLOBAL, + &&TARGET_STORE_NAME, + &&TARGET_SWAP, + &&TARGET_UNPACK_EX, + &&TARGET_UNPACK_SEQUENCE, + &&TARGET_YIELD_VALUE, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, @@ -218,6 +148,76 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&TARGET_RESUME, + &&TARGET_BINARY_OP_ADD_FLOAT, + &&TARGET_BINARY_OP_ADD_INT, + &&TARGET_BINARY_OP_ADD_UNICODE, + &&TARGET_BINARY_OP_MULTIPLY_FLOAT, + &&TARGET_BINARY_OP_MULTIPLY_INT, + &&TARGET_BINARY_OP_SUBTRACT_FLOAT, + &&TARGET_BINARY_OP_SUBTRACT_INT, + &&TARGET_BINARY_SUBSCR_DICT, + &&TARGET_BINARY_SUBSCR_GETITEM, + &&TARGET_BINARY_SUBSCR_LIST_INT, + &&TARGET_BINARY_SUBSCR_STR_INT, + &&TARGET_BINARY_SUBSCR_TUPLE_INT, + &&TARGET_CALL_ALLOC_AND_ENTER_INIT, + &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS, + &&TARGET_CALL_BUILTIN_CLASS, + &&TARGET_CALL_BUILTIN_FAST, + &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS, + &&TARGET_CALL_BUILTIN_O, + &&TARGET_CALL_ISINSTANCE, + &&TARGET_CALL_LEN, + &&TARGET_CALL_LIST_APPEND, + &&TARGET_CALL_METHOD_DESCRIPTOR_FAST, + &&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, + &&TARGET_CALL_METHOD_DESCRIPTOR_NOARGS, + &&TARGET_CALL_METHOD_DESCRIPTOR_O, + &&TARGET_CALL_PY_EXACT_ARGS, + &&TARGET_CALL_PY_WITH_DEFAULTS, + &&TARGET_CALL_STR_1, + &&TARGET_CALL_TUPLE_1, + &&TARGET_CALL_TYPE_1, + &&TARGET_COMPARE_OP_FLOAT, + &&TARGET_COMPARE_OP_INT, + &&TARGET_COMPARE_OP_STR, + &&TARGET_FOR_ITER_GEN, + &&TARGET_FOR_ITER_LIST, + &&TARGET_FOR_ITER_RANGE, + &&TARGET_FOR_ITER_TUPLE, + &&TARGET_LOAD_ATTR_CLASS, + &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, + &&TARGET_LOAD_ATTR_INSTANCE_VALUE, + &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, + &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, + &&TARGET_LOAD_ATTR_MODULE, + &&TARGET_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, + &&TARGET_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, + &&TARGET_LOAD_ATTR_PROPERTY, + &&TARGET_LOAD_ATTR_SLOT, + &&TARGET_LOAD_ATTR_WITH_HINT, + &&TARGET_LOAD_GLOBAL_BUILTIN, + &&TARGET_LOAD_GLOBAL_MODULE, + &&TARGET_LOAD_SUPER_ATTR_ATTR, + &&TARGET_LOAD_SUPER_ATTR_METHOD, + &&TARGET_RESUME_CHECK, + &&TARGET_SEND_GEN, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_STORE_ATTR_SLOT, + &&TARGET_STORE_ATTR_WITH_HINT, + &&TARGET_STORE_SUBSCR_DICT, + &&TARGET_STORE_SUBSCR_LIST_INT, + &&TARGET_TO_BOOL_ALWAYS_TRUE, + &&TARGET_TO_BOOL_BOOL, + &&TARGET_TO_BOOL_INT, + &&TARGET_TO_BOOL_LIST, + &&TARGET_TO_BOOL_NONE, + &&TARGET_TO_BOOL_STR, + &&TARGET_UNPACK_SEQUENCE_LIST, + &&TARGET_UNPACK_SEQUENCE_TUPLE, + &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, @@ -229,30 +229,29 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&TARGET_ENTER_EXECUTOR, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR, - &&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE, - &&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE, &&TARGET_INSTRUMENTED_RESUME, - &&TARGET_INSTRUMENTED_CALL, + &&TARGET_INSTRUMENTED_END_FOR, + &&TARGET_INSTRUMENTED_END_SEND, &&TARGET_INSTRUMENTED_RETURN_VALUE, + &&TARGET_INSTRUMENTED_RETURN_CONST, &&TARGET_INSTRUMENTED_YIELD_VALUE, + &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR, + &&TARGET_INSTRUMENTED_FOR_ITER, + &&TARGET_INSTRUMENTED_CALL, + &&TARGET_INSTRUMENTED_CALL_KW, &&TARGET_INSTRUMENTED_CALL_FUNCTION_EX, + &&TARGET_INSTRUMENTED_INSTRUCTION, &&TARGET_INSTRUMENTED_JUMP_FORWARD, &&TARGET_INSTRUMENTED_JUMP_BACKWARD, - &&TARGET_INSTRUMENTED_RETURN_CONST, - &&TARGET_INSTRUMENTED_FOR_ITER, - &&TARGET_INSTRUMENTED_POP_JUMP_IF_FALSE, &&TARGET_INSTRUMENTED_POP_JUMP_IF_TRUE, - &&TARGET_INSTRUMENTED_END_FOR, - &&TARGET_INSTRUMENTED_END_SEND, - &&TARGET_INSTRUMENTED_INSTRUCTION, + &&TARGET_INSTRUMENTED_POP_JUMP_IF_FALSE, + &&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE, + &&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE, &&TARGET_INSTRUMENTED_LINE, - &&_unknown_opcode -}; + &&_unknown_opcode}; diff --git a/Python/optimizer.c b/Python/optimizer.c index 3d385a1506cba3..955ac812177ac4 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1,9 +1,10 @@ #include "Python.h" #include "opcode.h" #include "pycore_interp.h" -#include "pycore_opcode.h" -#include "pycore_opcode_metadata.h" -#include "pycore_opcode_utils.h" +#include "pycore_bitutils.h" // _Py_popcount32() +#include "pycore_opcode_metadata.h" // _PyOpcode_OpName() +#include "pycore_opcode_utils.h" // MAX_REAL_OPCODE +#include "pycore_optimizer.h" // _Py_uop_analyze_and_optimize() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_uops.h" #include "cpython/optimizer.h" @@ -103,7 +104,8 @@ error_optimize( _PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, - _PyExecutorObject **exec) + _PyExecutorObject **exec, + int Py_UNUSED(stack_entries)) { PyErr_Format(PyExc_SystemError, "Should never call error_optimize"); return -1; @@ -152,24 +154,22 @@ PyUnstable_SetOptimizer(_PyOptimizerObject *optimizer) Py_DECREF(old); } -_PyInterpreterFrame * +int _PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest, PyObject **stack_pointer) { + assert(src->op.code == JUMP_BACKWARD); PyCodeObject *code = (PyCodeObject *)frame->f_executable; assert(PyCode_Check(code)); PyInterpreterState *interp = _PyInterpreterState_GET(); if (!has_space_for_executor(code, src)) { - goto jump_to_destination; + return 0; } _PyOptimizerObject *opt = interp->optimizer; _PyExecutorObject *executor = NULL; - int err = opt->optimize(opt, code, dest, &executor); + int err = opt->optimize(opt, code, dest, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame))); if (err <= 0) { assert(executor == NULL); - if (err < 0) { - return NULL; - } - goto jump_to_destination; + return err; } int index = get_index_for_executor(code, src); if (index < 0) { @@ -180,16 +180,11 @@ _PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNI * it might get confused by the executor disappearing, * but there is not much we can do about that here. */ Py_DECREF(executor); - goto jump_to_destination; + return 0; } insert_executor(code, src, index, executor); - assert(frame->prev_instr == src); - frame->prev_instr = dest - 1; - return executor->execute(executor, frame, stack_pointer); -jump_to_destination: - frame->prev_instr = dest - 1; - _PyFrame_SetStackPointer(frame, stack_pointer); - return frame; + Py_DECREF(executor); + return 1; } _PyExecutorObject * @@ -253,7 +248,9 @@ counter_optimize( _PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, - _PyExecutorObject **exec_ptr) + _PyExecutorObject **exec_ptr, + int Py_UNUSED(curr_stackentries) +) { _PyCounterExecutorObject *executor = (_PyCounterExecutorObject *)_PyObject_New(&CounterExecutor_Type); if (executor == NULL) { @@ -285,6 +282,7 @@ static PyTypeObject CounterOptimizer_Type = { .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, .tp_methods = counter_methods, + .tp_dealloc = (destructor)PyObject_Del, }; PyObject * @@ -319,13 +317,7 @@ uop_name(int index) { static Py_ssize_t uop_len(_PyUOpExecutorObject *self) { - int count = 0; - for (; count < _Py_UOP_MAX_TRACE_LENGTH; count++) { - if (self->trace[count].opcode == 0) { - break; - } - } - return count; + return Py_SIZE(self); } static PyObject * @@ -367,13 +359,41 @@ PySequenceMethods uop_as_sequence = { static PyTypeObject UOpExecutor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "uop_executor", - .tp_basicsize = sizeof(_PyUOpExecutorObject), - .tp_itemsize = 0, + .tp_basicsize = sizeof(_PyUOpExecutorObject) - sizeof(_PyUOpInstruction), + .tp_itemsize = sizeof(_PyUOpInstruction), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, .tp_dealloc = (destructor)uop_dealloc, .tp_as_sequence = &uop_as_sequence, }; +static int +move_stubs( + _PyUOpInstruction *trace, + int trace_length, + int stubs_start, + int stubs_end +) +{ + memmove(trace + trace_length, + trace + stubs_start, + (stubs_end - stubs_start) * sizeof(_PyUOpInstruction)); + // Patch up the jump targets + for (int i = 0; i < trace_length; i++) { + if (trace[i].opcode == _POP_JUMP_IF_FALSE || + trace[i].opcode == _POP_JUMP_IF_TRUE) + { + int target = trace[i].oparg; + if (target >= stubs_start) { + target += trace_length - stubs_start; + trace[i].oparg = target; + } + } + } + return trace_length + stubs_end - stubs_start; +} + +#define TRACE_STACK_SIZE 5 + static int translate_bytecode_to_trace( PyCodeObject *code, @@ -381,10 +401,16 @@ translate_bytecode_to_trace( _PyUOpInstruction *trace, int buffer_size) { + PyCodeObject *initial_code = code; _Py_CODEUNIT *initial_instr = instr; int trace_length = 0; int max_length = buffer_size; int reserved = 0; + struct { + PyCodeObject *code; + _Py_CODEUNIT *instr; + } trace_stack[TRACE_STACK_SIZE]; + int trace_stack_depth = 0; #ifdef Py_DEBUG char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG"); @@ -396,7 +422,7 @@ translate_bytecode_to_trace( #ifdef Py_DEBUG #define DPRINTF(level, ...) \ - if (lltrace >= (level)) { fprintf(stderr, __VA_ARGS__); } + if (lltrace >= (level)) { printf(__VA_ARGS__); } #else #define DPRINTF(level, ...) #endif @@ -435,13 +461,33 @@ translate_bytecode_to_trace( if (trace_length + (n) > max_length) { \ DPRINTF(2, "No room for %s (need %d, got %d)\n", \ (opname), (n), max_length - trace_length); \ + OPT_STAT_INC(trace_too_long); \ goto done; \ } \ reserved = (n); // Keep ADD_TO_TRACE / ADD_TO_STUB honest -// Reserve space for main+stub uops, plus 2 for SAVE_IP and EXIT_TRACE +// Reserve space for main+stub uops, plus 2 for _SET_IP and _EXIT_TRACE #define RESERVE(main, stub) RESERVE_RAW((main) + (stub) + 2, uop_name(opcode)) +// Trace stack operations (used by _PUSH_FRAME, _POP_FRAME) +#define TRACE_STACK_PUSH() \ + if (trace_stack_depth >= TRACE_STACK_SIZE) { \ + DPRINTF(2, "Trace stack overflow\n"); \ + OPT_STAT_INC(trace_stack_overflow); \ + ADD_TO_TRACE(_SET_IP, 0, 0); \ + goto done; \ + } \ + trace_stack[trace_stack_depth].code = code; \ + trace_stack[trace_stack_depth].instr = instr; \ + trace_stack_depth++; +#define TRACE_STACK_POP() \ + if (trace_stack_depth <= 0) { \ + Py_FatalError("Trace stack underflow\n"); \ + } \ + trace_stack_depth--; \ + code = trace_stack[trace_stack_depth].code; \ + instr = trace_stack[trace_stack_depth].instr; + DPRINTF(4, "Optimizing %s (%s:%d) at byte offset %d\n", PyUnicode_AsUTF8(code->co_qualname), @@ -449,9 +495,10 @@ translate_bytecode_to_trace( code->co_firstlineno, 2 * INSTR_IP(initial_instr, code)); +top: // Jump here after _PUSH_FRAME or likely branches for (;;) { - RESERVE_RAW(2, "epilogue"); // Always need space for SAVE_IP and EXIT_TRACE - ADD_TO_TRACE(SAVE_IP, INSTR_IP(instr, code), 0); + RESERVE_RAW(2, "epilogue"); // Always need space for _SET_IP and _EXIT_TRACE + ADD_TO_TRACE(_SET_IP, INSTR_IP(instr, code), 0); uint32_t opcode = instr->op.code; uint32_t oparg = instr->op.arg; @@ -477,7 +524,7 @@ translate_bytecode_to_trace( case POP_JUMP_IF_NONE: { RESERVE(2, 2); - ADD_TO_TRACE(IS_NONE, 0, 0); + ADD_TO_TRACE(_IS_NONE, 0, 0); opcode = POP_JUMP_IF_TRUE; goto pop_jump_if_bool; } @@ -485,7 +532,7 @@ translate_bytecode_to_trace( case POP_JUMP_IF_NOT_NONE: { RESERVE(2, 2); - ADD_TO_TRACE(IS_NONE, 0, 0); + ADD_TO_TRACE(_IS_NONE, 0, 0); opcode = POP_JUMP_IF_FALSE; goto pop_jump_if_bool; } @@ -494,26 +541,40 @@ translate_bytecode_to_trace( case POP_JUMP_IF_TRUE: { pop_jump_if_bool: - // Assume jump unlikely (TODO: handle jump likely case) RESERVE(1, 2); - _Py_CODEUNIT *target_instr = - instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + oparg; max_length -= 2; // Really the start of the stubs - uint32_t uopcode = opcode == POP_JUMP_IF_TRUE ? + int counter = instr[1].cache; + int bitcount = _Py_popcount32(counter); + bool jump_likely = bitcount > 8; + bool jump_sense = opcode == POP_JUMP_IF_TRUE; + uint32_t uopcode = jump_sense ^ jump_likely ? _POP_JUMP_IF_TRUE : _POP_JUMP_IF_FALSE; + _Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; + _Py_CODEUNIT *target_instr = next_instr + oparg; + _Py_CODEUNIT *stub_target = jump_likely ? next_instr : target_instr; + DPRINTF(4, "%s(%d): counter=%x, bitcount=%d, likely=%d, sense=%d, uopcode=%s\n", + uop_name(opcode), oparg, + counter, bitcount, jump_likely, jump_sense, uop_name(uopcode)); ADD_TO_TRACE(uopcode, max_length, 0); - ADD_TO_STUB(max_length, SAVE_IP, INSTR_IP(target_instr, code), 0); - ADD_TO_STUB(max_length + 1, EXIT_TRACE, 0, 0); + ADD_TO_STUB(max_length, _SET_IP, INSTR_IP(stub_target, code), 0); + ADD_TO_STUB(max_length + 1, _EXIT_TRACE, 0, 0); + if (jump_likely) { + DPRINTF(2, "Jump likely (%x = %d bits), continue at byte offset %d\n", + instr[1].cache, bitcount, 2 * INSTR_IP(target_instr, code)); + instr = target_instr; + goto top; + } break; } case JUMP_BACKWARD: { - if (instr + 2 - oparg == initial_instr) { + if (instr + 2 - oparg == initial_instr && code == initial_code) { RESERVE(1, 0); - ADD_TO_TRACE(JUMP_TO_TOP, 0, 0); + ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0); } else { + OPT_STAT_INC(inner_loop); DPRINTF(2, "JUMP_BACKWARD not to top ends trace\n"); } goto done; @@ -522,7 +583,7 @@ translate_bytecode_to_trace( case JUMP_FORWARD: { RESERVE(0, 0); - // This will emit two SAVE_IP instructions; leave it to the optimizer + // This will emit two _SET_IP instructions; leave it to the optimizer instr += oparg; break; } @@ -562,8 +623,8 @@ translate_bytecode_to_trace( ADD_TO_TRACE(next_op, 0, 0); ADD_TO_STUB(max_length + 0, POP_TOP, 0, 0); - ADD_TO_STUB(max_length + 1, SAVE_IP, INSTR_IP(target_instr, code), 0); - ADD_TO_STUB(max_length + 2, EXIT_TRACE, 0, 0); + ADD_TO_STUB(max_length + 1, _SET_IP, INSTR_IP(target_instr, code), 0); + ADD_TO_STUB(max_length + 2, _EXIT_TRACE, 0, 0); break; } @@ -571,14 +632,26 @@ translate_bytecode_to_trace( { const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode]; if (expansion->nuops > 0) { - // Reserve space for nuops (+ SAVE_IP + EXIT_TRACE) + // Reserve space for nuops (+ _SET_IP + _EXIT_TRACE) int nuops = expansion->nuops; RESERVE(nuops, 0); + if (expansion->uops[nuops-1].uop == _POP_FRAME) { + // Check for trace stack underflow now: + // We can't bail e.g. in the middle of + // LOAD_CONST + _POP_FRAME. + if (trace_stack_depth == 0) { + DPRINTF(2, "Trace stack underflow\n"); + OPT_STAT_INC(trace_stack_underflow); + goto done; + } + } uint32_t orig_oparg = oparg; // For OPARG_TOP/BOTTOM for (int i = 0; i < nuops; i++) { oparg = orig_oparg; + uint32_t uop = expansion->uops[i].uop; uint64_t operand = 0; - int offset = expansion->uops[i].offset; + // Add one to account for the actual opcode/oparg pair: + int offset = expansion->uops[i].offset + 1; switch (expansion->uops[i].size) { case OPARG_FULL: if (extras && OPCODE_HAS_JUMP(opcode)) { @@ -606,6 +679,11 @@ translate_bytecode_to_trace( case OPARG_BOTTOM: // Second half of super-instr oparg = orig_oparg & 0xF; break; + case OPARG_SET_IP: // op==_SET_IP; oparg=next instr + oparg = INSTR_IP(instr + offset, code); + uop = _SET_IP; + break; + default: fprintf(stderr, "opcode=%d, oparg=%d; nuops=%d, i=%d; size=%d, offset=%d\n", @@ -614,11 +692,67 @@ translate_bytecode_to_trace( expansion->uops[i].offset); Py_FatalError("garbled expansion"); } - ADD_TO_TRACE(expansion->uops[i].uop, oparg, operand); + ADD_TO_TRACE(uop, oparg, operand); + if (uop == _POP_FRAME) { + TRACE_STACK_POP(); + DPRINTF(2, + "Returning to %s (%s:%d) at byte offset %d\n", + PyUnicode_AsUTF8(code->co_qualname), + PyUnicode_AsUTF8(code->co_filename), + code->co_firstlineno, + 2 * INSTR_IP(instr, code)); + goto top; + } + if (uop == _PUSH_FRAME) { + assert(i + 1 == nuops); + int func_version_offset = + offsetof(_PyCallCache, func_version)/sizeof(_Py_CODEUNIT) + // Add one to account for the actual opcode/oparg pair: + + 1; + uint32_t func_version = read_u32(&instr[func_version_offset].cache); + PyFunctionObject *func = _PyFunction_LookupByVersion(func_version); + DPRINTF(3, "Function object: %p\n", func); + if (func != NULL) { + PyCodeObject *new_code = (PyCodeObject *)PyFunction_GET_CODE(func); + if (new_code == code) { + // Recursive call, bail (we could be here forever). + DPRINTF(2, "Bailing on recursive call to %s (%s:%d)\n", + PyUnicode_AsUTF8(new_code->co_qualname), + PyUnicode_AsUTF8(new_code->co_filename), + new_code->co_firstlineno); + OPT_STAT_INC(recursive_call); + ADD_TO_TRACE(_SET_IP, 0, 0); + goto done; + } + if (new_code->co_version != func_version) { + // func.__code__ was updated. + // Perhaps it may happen again, so don't bother tracing. + // TODO: Reason about this -- is it better to bail or not? + DPRINTF(2, "Bailing because co_version != func_version\n"); + ADD_TO_TRACE(_SET_IP, 0, 0); + goto done; + } + // Increment IP to the return address + instr += _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + 1; + TRACE_STACK_PUSH(); + code = new_code; + instr = _PyCode_CODE(code); + DPRINTF(2, + "Continuing in %s (%s:%d) at byte offset %d\n", + PyUnicode_AsUTF8(code->co_qualname), + PyUnicode_AsUTF8(code->co_filename), + code->co_firstlineno, + 2 * INSTR_IP(instr, code)); + goto top; + } + ADD_TO_TRACE(_SET_IP, 0, 0); + goto done; + } } break; } DPRINTF(2, "Unsupported opcode %s\n", uop_name(opcode)); + OPT_UNSUPPORTED_OPCODE(opcode); goto done; // Break out of loop } // End default @@ -630,43 +764,43 @@ translate_bytecode_to_trace( } // End for (;;) done: - // Skip short traces like SAVE_IP, LOAD_FAST, SAVE_IP, EXIT_TRACE + while (trace_stack_depth > 0) { + TRACE_STACK_POP(); + } + assert(code == initial_code); + // Skip short traces like _SET_IP, LOAD_FAST, _SET_IP, _EXIT_TRACE if (trace_length > 3) { - ADD_TO_TRACE(EXIT_TRACE, 0, 0); + ADD_TO_TRACE(_EXIT_TRACE, 0, 0); DPRINTF(1, - "Created a trace for %s (%s:%d) at byte offset %d -- length %d\n", + "Created a trace for %s (%s:%d) at byte offset %d -- length %d+%d\n", PyUnicode_AsUTF8(code->co_qualname), PyUnicode_AsUTF8(code->co_filename), code->co_firstlineno, 2 * INSTR_IP(initial_instr, code), - trace_length); - if (max_length < buffer_size && trace_length < max_length) { - // Move the stubs back to be immediately after the main trace - // (which ends at trace_length) - DPRINTF(2, - "Moving %d stub uops back by %d\n", - buffer_size - max_length, - max_length - trace_length); - memmove(trace + trace_length, - trace + max_length, - (buffer_size - max_length) * sizeof(_PyUOpInstruction)); - // Patch up the jump targets - for (int i = 0; i < trace_length; i++) { - if (trace[i].opcode == _POP_JUMP_IF_FALSE || - trace[i].opcode == _POP_JUMP_IF_TRUE) - { - int target = trace[i].oparg; - if (target >= max_length) { - target += trace_length - max_length; - trace[i].oparg = target; - } - } + trace_length, + buffer_size - max_length); + if (max_length < buffer_size) { + // There are stubs + if (trace_length < max_length) { + // There's a gap before the stubs + // Move the stubs back to be immediately after the main trace + // (which ends at trace_length) + DPRINTF(2, + "Moving %d stub uops back by %d\n", + buffer_size - max_length, + max_length - trace_length); + trace_length = move_stubs(trace, trace_length, max_length, buffer_size); + } + else { + assert(trace_length == max_length); + // There's no gap + trace_length = buffer_size; } } - trace_length += buffer_size - max_length; return trace_length; } else { + OPT_STAT_INC(trace_too_short); DPRINTF(4, "No trace for %s (%s:%d) at byte offset %d\n", PyUnicode_AsUTF8(code->co_qualname), @@ -683,12 +817,83 @@ translate_bytecode_to_trace( #undef DPRINTF } +static int +remove_unneeded_uops(_PyUOpInstruction *trace, int trace_length) +{ + // Stage 1: Replace unneeded _SET_IP uops with NOP. + // Note that we don't enter stubs, those SET_IPs are needed. + int last_set_ip = -1; + int last_instr = 0; + bool need_ip = true; + for (int pc = 0; pc < trace_length; pc++) { + int opcode = trace[pc].opcode; + if (opcode == _SAVE_CURRENT_IP) { + // Special case: never remove preceding _SET_IP + last_set_ip = -1; + } + else if (opcode == _SET_IP) { + if (!need_ip && last_set_ip >= 0) { + trace[last_set_ip].opcode = NOP; + } + need_ip = false; + last_set_ip = pc; + } + else if (opcode == _JUMP_TO_TOP || opcode == _EXIT_TRACE) { + last_instr = pc + 1; + break; + } + else { + // If opcode has ERROR or DEOPT, set need_up to true + if (_PyOpcode_opcode_metadata[opcode].flags & (HAS_ERROR_FLAG | HAS_DEOPT_FLAG)) { + need_ip = true; + } + } + } + // Stage 2: Squash NOP opcodes (pre-existing or set above). + int dest = 0; + for (int pc = 0; pc < last_instr; pc++) { + int opcode = trace[pc].opcode; + if (opcode != NOP) { + if (pc != dest) { + trace[dest] = trace[pc]; + } + dest++; + } + } + // Stage 3: Move the stubs back. + if (dest < last_instr) { + int new_trace_length = move_stubs(trace, dest, last_instr, trace_length); +#ifdef Py_DEBUG + char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG"); + int lltrace = 0; + if (uop_debug != NULL && *uop_debug >= '0') { + lltrace = *uop_debug - '0'; // TODO: Parse an int and all that + } + if (lltrace >= 2) { + printf("Optimized trace (length %d+%d = %d, saved %d):\n", + dest, trace_length - last_instr, new_trace_length, + trace_length - new_trace_length); + for (int pc = 0; pc < new_trace_length; pc++) { + printf("%4d: (%s, %d, %" PRIu64 ")\n", + pc, + uop_name(trace[pc].opcode), + (trace[pc].oparg), + (uint64_t)(trace[pc].operand)); + } + } +#endif + trace_length = new_trace_length; + } + return trace_length; +} + static int uop_optimize( _PyOptimizerObject *self, PyCodeObject *code, _Py_CODEUNIT *instr, - _PyExecutorObject **exec_ptr) + _PyExecutorObject **exec_ptr, + int curr_stackentries) { _PyUOpInstruction trace[_Py_UOP_MAX_TRACE_LENGTH]; int trace_length = translate_bytecode_to_trace(code, instr, trace, _Py_UOP_MAX_TRACE_LENGTH); @@ -696,16 +901,20 @@ uop_optimize( // Error or nothing translated return trace_length; } - OBJECT_STAT_INC(optimization_traces_created); - _PyUOpExecutorObject *executor = PyObject_New(_PyUOpExecutorObject, &UOpExecutor_Type); + OPT_HIST(trace_length, trace_length_hist); + OPT_STAT_INC(traces_created); + char *uop_optimize = Py_GETENV("PYTHONUOPSOPTIMIZE"); + if (uop_optimize != NULL && *uop_optimize > '0') { + trace_length = _Py_uop_analyze_and_optimize(code, trace, trace_length, curr_stackentries); + } + trace_length = remove_unneeded_uops(trace, trace_length); + _PyUOpExecutorObject *executor = PyObject_NewVar(_PyUOpExecutorObject, &UOpExecutor_Type, trace_length); if (executor == NULL) { return -1; } + OPT_HIST(trace_length, optimized_trace_length_hist); executor->base.execute = _PyUopExecute; memcpy(executor->trace, trace, trace_length * sizeof(_PyUOpInstruction)); - if (trace_length < _Py_UOP_MAX_TRACE_LENGTH) { - executor->trace[trace_length].opcode = 0; // Sentinel - } *exec_ptr = (_PyExecutorObject *)executor; return 1; } @@ -735,6 +944,6 @@ PyUnstable_Optimizer_NewUOpOptimizer(void) opt->resume_threshold = UINT16_MAX; // Need at least 3 iterations to settle specializations. // A few lower bits of the counter are reserved for other flags. - opt->backedge_threshold = 3 << OPTIMIZER_BITS_IN_COUNTER; + opt->backedge_threshold = 16 << OPTIMIZER_BITS_IN_COUNTER; return (PyObject *)opt; } diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c new file mode 100644 index 00000000000000..2d177f14ff268b --- /dev/null +++ b/Python/optimizer_analysis.c @@ -0,0 +1,25 @@ +#include "Python.h" +#include "opcode.h" +#include "pycore_interp.h" +#include "pycore_opcode_metadata.h" +#include "pycore_opcode_utils.h" +#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_uops.h" +#include "pycore_long.h" +#include "cpython/optimizer.h" +#include +#include +#include +#include "pycore_optimizer.h" + + +int +_Py_uop_analyze_and_optimize( + PyCodeObject *co, + _PyUOpInstruction *trace, + int trace_len, + int curr_stacklen +) +{ + return trace_len; +} diff --git a/Python/parking_lot.c b/Python/parking_lot.c new file mode 100644 index 00000000000000..664e622cc17474 --- /dev/null +++ b/Python/parking_lot.c @@ -0,0 +1,370 @@ +#include "Python.h" + +#include "pycore_llist.h" +#include "pycore_lock.h" // _PyRawMutex +#include "pycore_parking_lot.h" +#include "pycore_pyerrors.h" // _Py_FatalErrorFormat +#include "pycore_pystate.h" // _PyThreadState_GET +#include "pycore_semaphore.h" // _PySemaphore + +#include + + +typedef struct { + // The mutex protects the waiter queue and the num_waiters counter. + _PyRawMutex mutex; + + // Linked list of `struct wait_entry` waiters in this bucket. + struct llist_node root; + size_t num_waiters; +} Bucket; + +struct wait_entry { + void *park_arg; + uintptr_t addr; + _PySemaphore sema; + struct llist_node node; + bool is_unparking; +}; + +// Prime number to avoid correlations with memory addresses. +// We want this to be roughly proportional to the number of CPU cores +// to minimize contention on the bucket locks, but not too big to avoid +// wasting memory. The exact choice does not matter much. +#define NUM_BUCKETS 257 + +#define BUCKET_INIT(b, i) [i] = { .root = LLIST_INIT(b[i].root) } +#define BUCKET_INIT_2(b, i) BUCKET_INIT(b, i), BUCKET_INIT(b, i+1) +#define BUCKET_INIT_4(b, i) BUCKET_INIT_2(b, i), BUCKET_INIT_2(b, i+2) +#define BUCKET_INIT_8(b, i) BUCKET_INIT_4(b, i), BUCKET_INIT_4(b, i+4) +#define BUCKET_INIT_16(b, i) BUCKET_INIT_8(b, i), BUCKET_INIT_8(b, i+8) +#define BUCKET_INIT_32(b, i) BUCKET_INIT_16(b, i), BUCKET_INIT_16(b, i+16) +#define BUCKET_INIT_64(b, i) BUCKET_INIT_32(b, i), BUCKET_INIT_32(b, i+32) +#define BUCKET_INIT_128(b, i) BUCKET_INIT_64(b, i), BUCKET_INIT_64(b, i+64) +#define BUCKET_INIT_256(b, i) BUCKET_INIT_128(b, i), BUCKET_INIT_128(b, i+128) + +// Table of waiters (hashed by address) +static Bucket buckets[NUM_BUCKETS] = { + BUCKET_INIT_256(buckets, 0), + BUCKET_INIT(buckets, 256), +}; + +void +_PySemaphore_Init(_PySemaphore *sema) +{ +#if defined(MS_WINDOWS) + sema->platform_sem = CreateSemaphore( + NULL, // attributes + 0, // initial count + 10, // maximum count + NULL // unnamed + ); + if (!sema->platform_sem) { + Py_FatalError("parking_lot: CreateSemaphore failed"); + } +#elif defined(_Py_USE_SEMAPHORES) + if (sem_init(&sema->platform_sem, /*pshared=*/0, /*value=*/0) < 0) { + Py_FatalError("parking_lot: sem_init failed"); + } +#else + if (pthread_mutex_init(&sema->mutex, NULL) != 0) { + Py_FatalError("parking_lot: pthread_mutex_init failed"); + } + if (pthread_cond_init(&sema->cond, NULL)) { + Py_FatalError("parking_lot: pthread_cond_init failed"); + } + sema->counter = 0; +#endif +} + +void +_PySemaphore_Destroy(_PySemaphore *sema) +{ +#if defined(MS_WINDOWS) + CloseHandle(sema->platform_sem); +#elif defined(_Py_USE_SEMAPHORES) + sem_destroy(&sema->platform_sem); +#else + pthread_mutex_destroy(&sema->mutex); + pthread_cond_destroy(&sema->cond); +#endif +} + +static int +_PySemaphore_PlatformWait(_PySemaphore *sema, _PyTime_t timeout) +{ + int res; +#if defined(MS_WINDOWS) + DWORD wait; + DWORD millis = 0; + if (timeout < 0) { + millis = INFINITE; + } + else { + millis = (DWORD) (timeout / 1000000); + } + wait = WaitForSingleObjectEx(sema->platform_sem, millis, FALSE); + if (wait == WAIT_OBJECT_0) { + res = Py_PARK_OK; + } + else if (wait == WAIT_TIMEOUT) { + res = Py_PARK_TIMEOUT; + } + else { + res = Py_PARK_INTR; + } +#elif defined(_Py_USE_SEMAPHORES) + int err; + if (timeout >= 0) { + struct timespec ts; + + _PyTime_t deadline = _PyTime_Add(_PyTime_GetSystemClock(), timeout); + _PyTime_AsTimespec(deadline, &ts); + + err = sem_timedwait(&sema->platform_sem, &ts); + } + else { + err = sem_wait(&sema->platform_sem); + } + if (err == -1) { + err = errno; + if (err == EINTR) { + res = Py_PARK_INTR; + } + else if (err == ETIMEDOUT) { + res = Py_PARK_TIMEOUT; + } + else { + _Py_FatalErrorFormat(__func__, + "unexpected error from semaphore: %d", + err); + } + } + else { + res = Py_PARK_OK; + } +#else + pthread_mutex_lock(&sema->mutex); + int err = 0; + if (sema->counter == 0) { + if (timeout >= 0) { + struct timespec ts; + + _PyTime_t deadline = _PyTime_Add(_PyTime_GetSystemClock(), timeout); + _PyTime_AsTimespec(deadline, &ts); + + err = pthread_cond_timedwait(&sema->cond, &sema->mutex, &ts); + } + else { + err = pthread_cond_wait(&sema->cond, &sema->mutex); + } + } + if (sema->counter > 0) { + sema->counter--; + res = Py_PARK_OK; + } + else if (err) { + res = Py_PARK_TIMEOUT; + } + else { + res = Py_PARK_INTR; + } + pthread_mutex_unlock(&sema->mutex); +#endif + return res; +} + +int +_PySemaphore_Wait(_PySemaphore *sema, _PyTime_t timeout, int detach) +{ + PyThreadState *tstate = NULL; + if (detach) { + tstate = _PyThreadState_GET(); + if (tstate) { + PyEval_ReleaseThread(tstate); + } + } + + int res = _PySemaphore_PlatformWait(sema, timeout); + + if (detach && tstate) { + PyEval_AcquireThread(tstate); + } + return res; +} + +void +_PySemaphore_Wakeup(_PySemaphore *sema) +{ +#if defined(MS_WINDOWS) + if (!ReleaseSemaphore(sema->platform_sem, 1, NULL)) { + Py_FatalError("parking_lot: ReleaseSemaphore failed"); + } +#elif defined(_Py_USE_SEMAPHORES) + int err = sem_post(&sema->platform_sem); + if (err != 0) { + Py_FatalError("parking_lot: sem_post failed"); + } +#else + pthread_mutex_lock(&sema->mutex); + sema->counter++; + pthread_cond_signal(&sema->cond); + pthread_mutex_unlock(&sema->mutex); +#endif +} + +static void +enqueue(Bucket *bucket, const void *address, struct wait_entry *wait) +{ + llist_insert_tail(&bucket->root, &wait->node); + ++bucket->num_waiters; +} + +static struct wait_entry * +dequeue(Bucket *bucket, const void *address) +{ + // find the first waiter that is waiting on `address` + struct llist_node *root = &bucket->root; + struct llist_node *node; + llist_for_each(node, root) { + struct wait_entry *wait = llist_data(node, struct wait_entry, node); + if (wait->addr == (uintptr_t)address) { + llist_remove(node); + --bucket->num_waiters; + return wait; + } + } + return NULL; +} + +static void +dequeue_all(Bucket *bucket, const void *address, struct llist_node *dst) +{ + // remove and append all matching waiters to dst + struct llist_node *root = &bucket->root; + struct llist_node *node; + llist_for_each_safe(node, root) { + struct wait_entry *wait = llist_data(node, struct wait_entry, node); + if (wait->addr == (uintptr_t)address) { + llist_remove(node); + llist_insert_tail(dst, node); + --bucket->num_waiters; + } + } +} + +// Checks that `*addr == *expected` (only works for 1, 2, 4, or 8 bytes) +static int +atomic_memcmp(const void *addr, const void *expected, size_t addr_size) +{ + switch (addr_size) { + case 1: return _Py_atomic_load_uint8(addr) == *(const uint8_t *)expected; + case 2: return _Py_atomic_load_uint16(addr) == *(const uint16_t *)expected; + case 4: return _Py_atomic_load_uint32(addr) == *(const uint32_t *)expected; + case 8: return _Py_atomic_load_uint64(addr) == *(const uint64_t *)expected; + default: Py_UNREACHABLE(); + } +} + +int +_PyParkingLot_Park(const void *addr, const void *expected, size_t size, + _PyTime_t timeout_ns, void *park_arg, int detach) +{ + struct wait_entry wait = { + .park_arg = park_arg, + .addr = (uintptr_t)addr, + .is_unparking = false, + }; + + Bucket *bucket = &buckets[((uintptr_t)addr) % NUM_BUCKETS]; + + _PyRawMutex_Lock(&bucket->mutex); + if (!atomic_memcmp(addr, expected, size)) { + _PyRawMutex_Unlock(&bucket->mutex); + return Py_PARK_AGAIN; + } + _PySemaphore_Init(&wait.sema); + enqueue(bucket, addr, &wait); + _PyRawMutex_Unlock(&bucket->mutex); + + int res = _PySemaphore_Wait(&wait.sema, timeout_ns, detach); + if (res == Py_PARK_OK) { + goto done; + } + + // timeout or interrupt + _PyRawMutex_Lock(&bucket->mutex); + if (wait.is_unparking) { + _PyRawMutex_Unlock(&bucket->mutex); + // Another thread has started to unpark us. Wait until we process the + // wakeup signal. + do { + res = _PySemaphore_Wait(&wait.sema, -1, detach); + } while (res != Py_PARK_OK); + goto done; + } + else { + llist_remove(&wait.node); + --bucket->num_waiters; + } + _PyRawMutex_Unlock(&bucket->mutex); + +done: + _PySemaphore_Destroy(&wait.sema); + return res; + +} + +void +_PyParkingLot_Unpark(const void *addr, _Py_unpark_fn_t *fn, void *arg) +{ + Bucket *bucket = &buckets[((uintptr_t)addr) % NUM_BUCKETS]; + + // Find the first waiter that is waiting on `addr` + _PyRawMutex_Lock(&bucket->mutex); + struct wait_entry *waiter = dequeue(bucket, addr); + if (waiter) { + waiter->is_unparking = true; + + int has_more_waiters = (bucket->num_waiters > 0); + fn(arg, waiter->park_arg, has_more_waiters); + } + else { + fn(arg, NULL, 0); + } + _PyRawMutex_Unlock(&bucket->mutex); + + if (waiter) { + // Wakeup the waiter outside of the bucket lock + _PySemaphore_Wakeup(&waiter->sema); + } +} + +void +_PyParkingLot_UnparkAll(const void *addr) +{ + struct llist_node head = LLIST_INIT(head); + Bucket *bucket = &buckets[((uintptr_t)addr) % NUM_BUCKETS]; + + _PyRawMutex_Lock(&bucket->mutex); + dequeue_all(bucket, addr, &head); + _PyRawMutex_Unlock(&bucket->mutex); + + struct llist_node *node; + llist_for_each_safe(node, &head) { + struct wait_entry *waiter = llist_data(node, struct wait_entry, node); + llist_remove(node); + _PySemaphore_Wakeup(&waiter->sema); + } +} + +void +_PyParkingLot_AfterFork(void) +{ + // After a fork only one thread remains. That thread cannot be blocked + // so all entries in the parking lot are for dead threads. + memset(buckets, 0, sizeof(buckets)); + for (Py_ssize_t i = 0; i < NUM_BUCKETS; i++) { + llist_init(&buckets[i].root); + } +} diff --git a/Python/pathconfig.c b/Python/pathconfig.c index afffa134e893ba..50c60093cd4e32 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -1,23 +1,21 @@ /* Path configuration like module_search_path (sys.path) */ #include "Python.h" -#include "marshal.h" // PyMarshal_ReadObjectFromString -#include "osdefs.h" // DELIM -#include "pycore_initconfig.h" -#include "pycore_fileutils.h" +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_fileutils.h" // _Py_wgetcwd() #include "pycore_pathconfig.h" #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include + +#include "marshal.h" // PyMarshal_ReadObjectFromString +#include "osdefs.h" // DELIM + #ifdef MS_WINDOWS # include // GetFullPathNameW(), MAX_PATH # include # include #endif -#ifdef __cplusplus -extern "C" { -#endif - /* External interface */ @@ -498,8 +496,3 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) *path0_p = path0_obj; return 1; } - - -#ifdef __cplusplus -} -#endif diff --git a/Python/perf_trampoline.c b/Python/perf_trampoline.c index b8885a303977d0..209a23b6c1cbc7 100644 --- a/Python/perf_trampoline.c +++ b/Python/perf_trampoline.c @@ -130,9 +130,10 @@ any DWARF information available for them). */ #include "Python.h" -#include "pycore_ceval.h" +#include "pycore_ceval.h" // _PyPerf_Callbacks #include "pycore_frame.h" #include "pycore_interp.h" +#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() #ifdef PY_HAVE_PERF_TRAMPOLINE @@ -140,9 +141,9 @@ any DWARF information available for them). #include #include #include -#include +#include // mmap() #include -#include +#include // sysconf() #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) #define PY_HAVE_INVALIDATE_ICACHE diff --git a/Python/pyhash.c b/Python/pyhash.c index d5ac9f83be61cc..f9060b8003a0a7 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -4,6 +4,7 @@ All the utility functions (_Py_Hash*()) return "-1" to signify an error. */ #include "Python.h" +#include "pycore_pyhash.h" // _Py_HashSecret_t #ifdef __APPLE__ # include @@ -13,10 +14,6 @@ # include #endif -#ifdef __cplusplus -extern "C" { -#endif - _Py_HashSecret_t _Py_HashSecret = {{0}}; #if Py_HASH_ALGORITHM == Py_HASH_EXTERNAL @@ -502,7 +499,3 @@ pysiphash(const void *src, Py_ssize_t src_sz) { static PyHash_FuncDef PyHash_Func = {pysiphash, "siphash24", 64, 128}; #endif - -#ifdef __cplusplus -} -#endif diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index cf8b4379c1467f..14033162377489 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -17,13 +17,14 @@ #include "pycore_list.h" // _PyList_Fini() #include "pycore_long.h" // _PyLong_InitTypes() #include "pycore_object.h" // _PyDebug_PrintTotalRefs() -#include "pycore_pathconfig.h" // _PyConfig_WritePathConfig() +#include "pycore_pathconfig.h" // _PyPathConfig_UpdateGlobal() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pylifecycle.h" // _PyErr_Print() #include "pycore_pymem.h" // _PyObject_DebugMallocStats() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_runtime.h" // _Py_ID() #include "pycore_runtime_init.h" // _PyRuntimeState_INIT +#include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_sliceobject.h" // _PySlice_Fini() #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() @@ -31,13 +32,17 @@ #include "pycore_typevarobject.h" // _Py_clear_generic_types() #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() #include "pycore_weakref.h" // _PyWeakref_GET_REF() + #include "opcode.h" #include // setlocale() #include // getenv() +#ifdef HAVE_UNISTD_H +# include // isatty() +#endif #if defined(__APPLE__) -#include +# include #endif #ifdef HAVE_SIGNAL_H @@ -56,12 +61,7 @@ # undef BYTE #endif -#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) - - -#ifdef __cplusplus -extern "C" { -#endif +#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, (int)strlen(str)) /* Forward declarations */ @@ -128,7 +128,7 @@ _PyRuntime_Finalize(void) } int -_Py_IsFinalizing(void) +Py_IsFinalizing(void) { return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL; } @@ -628,10 +628,12 @@ pycore_create_interpreter(_PyRuntimeState *runtime, PyThreadState **tstate_p) { PyStatus status; - PyInterpreterState *interp = PyInterpreterState_New(); - if (interp == NULL) { - return _PyStatus_ERR("can't make main interpreter"); + PyInterpreterState *interp; + status = _PyInterpreterState_New(NULL, &interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } + assert(interp != NULL); assert(_Py_IsMainInterpreter(interp)); status = _PyConfig_Copy(&interp->config, src_config); @@ -653,13 +655,12 @@ pycore_create_interpreter(_PyRuntimeState *runtime, return status; } - PyThreadState *tstate = _PyThreadState_New(interp); + PyThreadState *tstate = _PyThreadState_New(interp, + _PyThreadState_WHENCE_INTERP); if (tstate == NULL) { return _PyStatus_ERR("can't make first thread"); } _PyThreadState_Bind(tstate); - // XXX For now we do this before the GIL is created. - (void) _PyThreadState_SwapNoGIL(tstate); status = init_interp_create_gil(tstate, config.gil); if (_PyStatus_EXCEPTION(status)) { @@ -761,18 +762,30 @@ pycore_init_builtins(PyThreadState *tstate) } interp->builtins = Py_NewRef(builtins_dict); - PyObject *isinstance = PyDict_GetItem(builtins_dict, &_Py_ID(isinstance)); - assert(isinstance); + PyObject *isinstance = PyDict_GetItemWithError(builtins_dict, &_Py_ID(isinstance)); + if (!isinstance) { + goto error; + } interp->callable_cache.isinstance = isinstance; - PyObject *len = PyDict_GetItem(builtins_dict, &_Py_ID(len)); - assert(len); + + PyObject *len = PyDict_GetItemWithError(builtins_dict, &_Py_ID(len)); + if (!len) { + goto error; + } interp->callable_cache.len = len; + PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append)); - assert(list_append); + if (list_append == NULL) { + goto error; + } interp->callable_cache.list_append = list_append; + PyObject *object__getattribute__ = _PyType_Lookup(&PyBaseObject_Type, &_Py_ID(__getattribute__)); - assert(object__getattribute__); + if (object__getattribute__ == NULL) { + goto error; + } interp->callable_cache.object__getattribute__ = object__getattribute__; + if (_PyBuiltins_AddExceptions(bimod) < 0) { return _PyStatus_ERR("failed to add exceptions to builtins"); } @@ -816,11 +829,6 @@ pycore_interp_init(PyThreadState *tstate) if (_PyStatus_EXCEPTION(status)) { return status; } - // Intern strings in deep-frozen modules first so that others - // can use it instead of creating a heap allocated string. - if (_Py_Deepfreeze_Init() < 0) { - return _PyStatus_ERR("failed to initialize deep-frozen modules"); - } status = pycore_init_types(interp); if (_PyStatus_EXCEPTION(status)) { @@ -1192,7 +1200,36 @@ init_interp_main(PyThreadState *tstate) } if (enabled) { PyObject *opt = PyUnstable_Optimizer_NewUOpOptimizer(); + if (opt == NULL) { + return _PyStatus_ERR("can't initialize optimizer"); + } PyUnstable_SetOptimizer((_PyOptimizerObject *)opt); + Py_DECREF(opt); + } + } + + if (!is_main_interp) { + // The main interpreter is handled in Py_Main(), for now. + if (config->sys_path_0 != NULL) { + PyObject *path0 = PyUnicode_FromWideChar(config->sys_path_0, -1); + if (path0 == NULL) { + return _PyStatus_ERR("can't initialize sys.path[0]"); + } + PyObject *sysdict = interp->sysdict; + if (sysdict == NULL) { + Py_DECREF(path0); + return _PyStatus_ERR("can't initialize sys.path[0]"); + } + PyObject *sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path)); + if (sys_path == NULL) { + Py_DECREF(path0); + return _PyStatus_ERR("can't initialize sys.path[0]"); + } + int res = PyList_Insert(sys_path, 0, path0); + Py_DECREF(path0); + if (res) { + return _PyStatus_ERR("can't initialize sys.path[0]"); + } } } @@ -1355,17 +1392,17 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose) if (verbose) { PySys_WriteStderr("# restore sys.%s\n", name); } - PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict, - orig_name); + PyObject *value; + if (PyDict_GetItemStringRef(interp->sysdict, orig_name, &value) < 0) { + PyErr_WriteUnraisable(NULL); + } if (value == NULL) { - if (_PyErr_Occurred(tstate)) { - PyErr_WriteUnraisable(NULL); - } - value = Py_None; + value = Py_NewRef(Py_None); } if (PyDict_SetItemString(interp->sysdict, name, value) < 0) { PyErr_WriteUnraisable(NULL); } + Py_DECREF(value); } } @@ -1624,27 +1661,20 @@ flush_std_files(void) PyThreadState *tstate = _PyThreadState_GET(); PyObject *fout = _PySys_GetAttr(tstate, &_Py_ID(stdout)); PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); - PyObject *tmp; int status = 0; if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { - tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush)); - if (tmp == NULL) { + if (_PyFile_Flush(fout) < 0) { PyErr_WriteUnraisable(fout); status = -1; } - else - Py_DECREF(tmp); } if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { - tmp = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); - if (tmp == NULL) { + if (_PyFile_Flush(ferr) < 0) { PyErr_Clear(); status = -1; } - else - Py_DECREF(tmp); } return status; @@ -1723,7 +1753,6 @@ finalize_interp_clear(PyThreadState *tstate) _Py_HashRandomization_Fini(); _PyArg_Fini(); _Py_ClearFileSystemEncoding(); - _Py_Deepfreeze_Fini(); _PyPerfTrampoline_Fini(); } @@ -1916,11 +1945,11 @@ Py_FinalizeEx(void) } if (dump_refs) { - _Py_PrintReferences(stderr); + _Py_PrintReferences(tstate->interp, stderr); } if (dump_refs_fp != NULL) { - _Py_PrintReferences(dump_refs_fp); + _Py_PrintReferences(tstate->interp, dump_refs_fp); } #endif /* Py_TRACE_REFS */ @@ -1939,31 +1968,30 @@ Py_FinalizeEx(void) // XXX Ensure finalizer errors are handled properly. finalize_interp_clear(tstate); - finalize_interp_delete(tstate->interp); - -#ifdef Py_REF_DEBUG - if (show_ref_count) { - _PyDebug_PrintTotalRefs(); - } - _Py_FinalizeRefTotal(runtime); -#endif - _Py_FinalizeAllocatedBlocks(runtime); #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. * An address can be used to find the repr of the object, printed - * above by _Py_PrintReferences. - */ - + * above by _Py_PrintReferences. */ if (dump_refs) { - _Py_PrintReferenceAddresses(stderr); + _Py_PrintReferenceAddresses(tstate->interp, stderr); } - if (dump_refs_fp != NULL) { - _Py_PrintReferenceAddresses(dump_refs_fp); + _Py_PrintReferenceAddresses(tstate->interp, dump_refs_fp); fclose(dump_refs_fp); } #endif /* Py_TRACE_REFS */ + + finalize_interp_delete(tstate->interp); + +#ifdef Py_REF_DEBUG + if (show_ref_count) { + _PyDebug_PrintTotalRefs(); + } + _Py_FinalizeRefTotal(runtime); +#endif + _Py_FinalizeAllocatedBlocks(runtime); + #ifdef WITH_PYMALLOC if (malloc_stats) { _PyObject_DebugMallocStats(stderr); @@ -2021,7 +2049,8 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) return _PyStatus_OK(); } - PyThreadState *tstate = _PyThreadState_New(interp); + PyThreadState *tstate = _PyThreadState_New(interp, + _PyThreadState_WHENCE_INTERP); if (tstate == NULL) { PyInterpreterState_Delete(interp); *tstate_p = NULL; @@ -2029,8 +2058,7 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) } _PyThreadState_Bind(tstate); - // XXX For now we do this before the GIL is created. - PyThreadState *save_tstate = _PyThreadState_SwapNoGIL(tstate); + PyThreadState *save_tstate = _PyThreadState_GET(); int has_gil = 0; /* From this point until the init_interp_create_gil() call, @@ -2042,7 +2070,7 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) const PyConfig *src_config; if (save_tstate != NULL) { // XXX Might new_interpreter() have been called without the GIL held? - _PyEval_ReleaseLock(save_tstate->interp, save_tstate); + _PyThreadState_Detach(save_tstate); src_config = _PyInterpreterState_GetConfig(save_tstate->interp); } else @@ -2070,6 +2098,8 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) } has_gil = 1; + /* No objects have been created yet. */ + status = pycore_interp_init(tstate); if (_PyStatus_EXCEPTION(status)) { goto error; @@ -2087,12 +2117,11 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) *tstate_p = NULL; /* Oops, it didn't work. Undo it all. */ - PyErr_PrintEx(0); if (has_gil) { - PyThreadState_Swap(save_tstate); + _PyThreadState_Detach(tstate); } - else { - _PyThreadState_SwapNoGIL(save_tstate); + if (save_tstate != NULL) { + _PyThreadState_Attach(save_tstate); } PyThreadState_Clear(tstate); PyThreadState_Delete(tstate); @@ -2140,7 +2169,7 @@ Py_EndInterpreter(PyThreadState *tstate) if (tstate != _PyThreadState_GET()) { Py_FatalError("thread is not current"); } - if (tstate->cframe->current_frame != NULL) { + if (tstate->current_frame != NULL) { Py_FatalError("thread still has a frame"); } interp->finalizing = 1; @@ -2188,7 +2217,7 @@ _Py_IsInterpreterFinalizing(PyInterpreterState *interp) static PyStatus add_main_module(PyInterpreterState *interp) { - PyObject *m, *d, *loader, *ann_dict; + PyObject *m, *d, *ann_dict; m = PyImport_AddModule("__main__"); if (m == NULL) return _PyStatus_ERR("can't create __main__ module"); @@ -2201,10 +2230,11 @@ add_main_module(PyInterpreterState *interp) } Py_DECREF(ann_dict); - if (_PyDict_GetItemStringWithError(d, "__builtins__") == NULL) { - if (PyErr_Occurred()) { - return _PyStatus_ERR("Failed to test __main__.__builtins__"); - } + int has_builtins = PyDict_ContainsString(d, "__builtins__"); + if (has_builtins < 0) { + return _PyStatus_ERR("Failed to test __main__.__builtins__"); + } + if (!has_builtins) { PyObject *bimod = PyImport_ImportModule("builtins"); if (bimod == NULL) { return _PyStatus_ERR("Failed to retrieve builtins module"); @@ -2220,11 +2250,13 @@ add_main_module(PyInterpreterState *interp) * will be set if __main__ gets further initialized later in the startup * process. */ - loader = _PyDict_GetItemStringWithError(d, "__loader__"); - if (loader == NULL || loader == Py_None) { - if (PyErr_Occurred()) { - return _PyStatus_ERR("Failed to test __main__.__loader__"); - } + PyObject *loader; + if (PyDict_GetItemStringRef(d, "__loader__", &loader) < 0) { + return _PyStatus_ERR("Failed to test __main__.__loader__"); + } + int has_loader = !(loader == NULL || loader == Py_None); + Py_XDECREF(loader); + if (!has_loader) { PyObject *loader = _PyImport_GetImportlibLoader(interp, "BuiltinImporter"); if (loader == NULL) { @@ -2614,13 +2646,9 @@ _Py_FatalError_PrintExc(PyThreadState *tstate) Py_DECREF(exc); /* sys.stderr may be buffered: call sys.stderr.flush() */ - PyObject *res = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); - if (res == NULL) { + if (_PyFile_Flush(ferr) < 0) { _PyErr_Clear(tstate); } - else { - Py_DECREF(res); - } return has_tb; } @@ -3132,7 +3160,3 @@ PyOS_setsig(int sig, PyOS_sighandler_t handler) return oldhandler; #endif } - -#ifdef __cplusplus -} -#endif diff --git a/Python/pystate.c b/Python/pystate.c index a9b404bd5c93e3..92cf741f4ca4ed 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -5,11 +5,13 @@ #include "pycore_ceval.h" #include "pycore_code.h" // stats #include "pycore_dtoa.h" // _dtoa_state_INIT() +#include "pycore_emscripten_trampoline.h" // _Py_EmscriptenTrampoline_Init() #include "pycore_frame.h" -#include "pycore_initconfig.h" +#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_object.h" // _PyType_InitCache() -#include "pycore_pyerrors.h" -#include "pycore_pylifecycle.h" +#include "pycore_parking_lot.h" // _PyParkingLot_AfterFork() +#include "pycore_pyerrors.h" // _PyErr_Clear() +#include "pycore_pylifecycle.h" // _PyAST_Fini() #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" #include "pycore_runtime_init.h" // _PyRuntimeState_INIT @@ -27,16 +29,12 @@ to avoid the expense of doing their own locking). -------------------------------------------------------------------------- */ #ifdef HAVE_DLOPEN -#ifdef HAVE_DLFCN_H -#include -#endif -#if !HAVE_DECL_RTLD_LAZY -#define RTLD_LAZY 1 -#endif -#endif - -#ifdef __cplusplus -extern "C" { +# ifdef HAVE_DLFCN_H +# include +# endif +# if !HAVE_DECL_RTLD_LAZY +# define RTLD_LAZY 1 +# endif #endif @@ -265,10 +263,10 @@ static void unbind_tstate(PyThreadState *tstate) { assert(tstate != NULL); - // XXX assert(tstate_is_alive(tstate)); assert(tstate_is_bound(tstate)); - // XXX assert(!tstate->_status.active); +#ifndef HAVE_PTHREAD_STUBS assert(tstate->thread_id > 0); +#endif #ifdef PY_HAVE_THREAD_NATIVE_ID assert(tstate->native_thread_id > 0); #endif @@ -426,13 +424,11 @@ init_runtime(_PyRuntimeState *runtime, Py_ssize_t unicode_next_index, PyThread_type_lock locks[NUMLOCKS]) { - if (runtime->_initialized) { - Py_FatalError("runtime already initialized"); - } - assert(!runtime->preinitializing && - !runtime->preinitialized && - !runtime->core_initialized && - !runtime->initialized); + assert(!runtime->preinitializing); + assert(!runtime->preinitialized); + assert(!runtime->core_initialized); + assert(!runtime->initialized); + assert(!runtime->_initialized); runtime->open_code_hook = open_code_hook; runtime->open_code_userdata = open_code_userdata; @@ -451,6 +447,10 @@ init_runtime(_PyRuntimeState *runtime, runtime->unicode_state.ids.next_index = unicode_next_index; +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) + _Py_EmscriptenTrampoline_Init(runtime); +#endif + runtime->_initialized = 1; } @@ -476,6 +476,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) // Py_Initialize() must be running again. // Reset to _PyRuntimeState_INIT. memcpy(runtime, &initial, sizeof(*runtime)); + assert(!runtime->_initialized); } if (gilstate_tss_init(runtime) != 0) { @@ -494,6 +495,8 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) return _PyStatus_OK(); } +static void _xidregistry_clear(struct _xidregistry *); + void _PyRuntimeState_Fini(_PyRuntimeState *runtime) { @@ -502,6 +505,8 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) assert(runtime->object_state.interpreter_leaks == 0); #endif + _xidregistry_clear(&runtime->xidregistry); + if (gilstate_tss_initialized(runtime)) { gilstate_tss_fini(runtime); } @@ -547,9 +552,18 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) for (int i = 0; i < NUMLOCKS; i++) { reinit_err += _PyThread_at_fork_reinit(lockptrs[i]); } + /* PyOS_AfterFork_Child(), which calls this function, later calls + _PyInterpreterState_DeleteExceptMain(), so we only need to update + the main interpreter here. */ + assert(runtime->interpreters.main != NULL); + runtime->interpreters.main->xidregistry.mutex = runtime->xidregistry.mutex; PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + // Clears the parking lot. Any waiting threads are dead. This must be + // called before releasing any locks that use the parking lot. + _PyParkingLot_AfterFork(); + /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does * not force the default allocator. */ reinit_err += _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); @@ -647,14 +661,14 @@ free_interpreter(PyInterpreterState *interp) main interpreter. We fix those fields here, in addition to the other dynamically initialized fields. */ -static void +static PyStatus init_interpreter(PyInterpreterState *interp, _PyRuntimeState *runtime, int64_t id, PyInterpreterState *next, PyThread_type_lock pending_lock) { if (interp->_initialized) { - Py_FatalError("interpreter already initialized"); + return _PyStatus_ERR("interpreter already initialized"); } assert(runtime != NULL); @@ -675,15 +689,20 @@ init_interpreter(PyInterpreterState *interp, memcpy(&interp->obmalloc.pools.used, temp, sizeof(temp)); } + PyStatus status = _PyObject_InitState(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + _PyEval_InitState(interp, pending_lock); _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); _PyType_InitCache(interp); - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) { interp->monitors.tools[i] = 0; } for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { - for (int e = 0; e < PY_MONITORING_EVENTS; e++) { + for (int e = 0; e < _PY_MONITORING_EVENTS; e++) { interp->monitoring_callables[t][e] = NULL; } @@ -693,48 +712,55 @@ init_interpreter(PyInterpreterState *interp, interp->optimizer = &_PyOptimizer_Default; interp->optimizer_backedge_threshold = _PyOptimizer_Default.backedge_threshold; interp->optimizer_resume_threshold = _PyOptimizer_Default.backedge_threshold; + interp->next_func_version = 1; if (interp != &runtime->_main_interpreter) { /* Fix the self-referential, statically initialized fields. */ interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp); } interp->f_opcode_trace_set = false; + + assert(runtime->xidregistry.mutex != NULL); + interp->xidregistry.mutex = runtime->xidregistry.mutex; + interp->_initialized = 1; + return _PyStatus_OK(); } -PyInterpreterState * -PyInterpreterState_New(void) + +PyStatus +_PyInterpreterState_New(PyThreadState *tstate, PyInterpreterState **pinterp) { - PyInterpreterState *interp; + *pinterp = NULL; + + // Don't get runtime from tstate since tstate can be NULL _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = current_fast_get(runtime); - /* tstate is NULL when Py_InitializeFromConfig() calls - PyInterpreterState_New() to create the main interpreter. */ - if (_PySys_Audit(tstate, "cpython.PyInterpreterState_New", NULL) < 0) { - return NULL; + // tstate is NULL when pycore_create_interpreter() calls + // _PyInterpreterState_New() to create the main interpreter. + if (tstate != NULL) { + if (_PySys_Audit(tstate, "cpython.PyInterpreterState_New", NULL) < 0) { + return _PyStatus_ERR("sys.audit failed"); + } } PyThread_type_lock pending_lock = PyThread_allocate_lock(); if (pending_lock == NULL) { - if (tstate != NULL) { - _PyErr_NoMemory(tstate); - } - return NULL; + return _PyStatus_NO_MEMORY(); } - /* Don't get runtime from tstate since tstate can be NULL. */ - struct pyinterpreters *interpreters = &runtime->interpreters; - /* We completely serialize creation of multiple interpreters, since it simplifies things here and blocking concurrent calls isn't a problem. Regardless, we must fully block subinterpreter creation until after the main interpreter is created. */ HEAD_LOCK(runtime); + struct pyinterpreters *interpreters = &runtime->interpreters; int64_t id = interpreters->next_id; interpreters->next_id += 1; // Allocate the interpreter and add it to the runtime state. + PyInterpreterState *interp; + PyStatus status; PyInterpreterState *old_head = interpreters->head; if (old_head == NULL) { // We are creating the main interpreter. @@ -753,36 +779,59 @@ PyInterpreterState_New(void) interp = alloc_interpreter(); if (interp == NULL) { + status = _PyStatus_NO_MEMORY(); goto error; } // Set to _PyInterpreterState_INIT. - memcpy(interp, &initial._main_interpreter, - sizeof(*interp)); + memcpy(interp, &initial._main_interpreter, sizeof(*interp)); if (id < 0) { /* overflow or Py_Initialize() not called yet! */ - if (tstate != NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "failed to get an interpreter ID"); - } + status = _PyStatus_ERR("failed to get an interpreter ID"); goto error; } } interpreters->head = interp; - init_interpreter(interp, runtime, id, old_head, pending_lock); + status = init_interpreter(interp, runtime, + id, old_head, pending_lock); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + pending_lock = NULL; HEAD_UNLOCK(runtime); - return interp; + + assert(interp != NULL); + *pinterp = interp; + return _PyStatus_OK(); error: HEAD_UNLOCK(runtime); - PyThread_free_lock(pending_lock); + if (pending_lock != NULL) { + PyThread_free_lock(pending_lock); + } if (interp != NULL) { free_interpreter(interp); } - return NULL; + return status; +} + + +PyInterpreterState * +PyInterpreterState_New(void) +{ + // tstate can be NULL + PyThreadState *tstate = current_fast_get(&_PyRuntime); + + PyInterpreterState *interp; + PyStatus status = _PyInterpreterState_New(tstate, &interp); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); + } + assert(interp != NULL); + return interp; } @@ -841,11 +890,15 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) Py_CLEAR(interp->audit_hooks); - for (int i = 0; i < PY_MONITORING_UNGROUPED_EVENTS; i++) { + // At this time, all the threads should be cleared so we don't need + // atomic operations for eval_breaker + interp->ceval.eval_breaker = 0; + + for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) { interp->monitors.tools[i] = 0; } for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { - for (int e = 0; e < PY_MONITORING_EVENTS; e++) { + for (int e = 0; e < _PY_MONITORING_EVENTS; e++) { Py_CLEAR(interp->monitoring_callables[t][e]); } } @@ -894,6 +947,10 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); + _xidregistry_clear(&interp->xidregistry); + /* The lock is owned by the runtime, so we don't free it here. */ + interp->xidregistry.mutex = NULL; + if (tstate->interp == interp) { /* We are now safe to fix tstate->_status.cleared. */ // XXX Do this (much) earlier? @@ -945,6 +1002,7 @@ _PyInterpreterState_Clear(PyThreadState *tstate) static inline void tstate_deactivate(PyThreadState *tstate); +static void tstate_set_detached(PyThreadState *tstate); static void zapthreads(PyInterpreterState *interp); void @@ -958,9 +1016,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp) PyThreadState *tcur = current_fast_get(runtime); if (tcur != NULL && interp == tcur->interp) { /* Unset current thread. After this, many C API calls become crashy. */ - current_fast_clear(runtime); - tstate_deactivate(tcur); - _PyEval_ReleaseLock(interp, NULL); + _PyThreadState_Detach(tcur); } zapthreads(interp); @@ -1000,6 +1056,9 @@ PyInterpreterState_Delete(PyInterpreterState *interp) if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } + + _PyObject_FiniState(interp); + free_interpreter(interp); } @@ -1052,6 +1111,61 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) #endif +int +_PyInterpreterState_SetRunningMain(PyInterpreterState *interp) +{ + if (_PyInterpreterState_FailIfRunningMain(interp) < 0) { + return -1; + } + PyThreadState *tstate = current_fast_get(&_PyRuntime); + _Py_EnsureTstateNotNULL(tstate); + if (tstate->interp != interp) { + PyErr_SetString(PyExc_RuntimeError, + "current tstate has wrong interpreter"); + return -1; + } + interp->threads.main = tstate; + return 0; +} + +void +_PyInterpreterState_SetNotRunningMain(PyInterpreterState *interp) +{ + PyThreadState *tstate = interp->threads.main; + assert(tstate == current_fast_get(&_PyRuntime)); + + if (tstate->on_delete != NULL) { + // The threading module was imported for the first time in this + // thread, so it was set as threading._main_thread. (See gh-75698.) + // The thread has finished running the Python program so we mark + // the thread object as finished. + assert(tstate->_whence != _PyThreadState_WHENCE_THREADING); + tstate->on_delete(tstate->on_delete_data); + tstate->on_delete = NULL; + tstate->on_delete_data = NULL; + } + + interp->threads.main = NULL; +} + +int +_PyInterpreterState_IsRunningMain(PyInterpreterState *interp) +{ + return (interp->threads.main != NULL); +} + +int +_PyInterpreterState_FailIfRunningMain(PyInterpreterState *interp) +{ + if (interp->threads.main != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "interpreter already running"); + return -1; + } + return 0; +} + + //---------- // accessors //---------- @@ -1111,8 +1225,10 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) PyThread_release_lock(interp->id_mutex); if (refcount == 0 && interp->requires_idref) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + PyThreadState *tstate = _PyThreadState_New(interp, + _PyThreadState_WHENCE_INTERP); + _PyThreadState_Bind(tstate); + // XXX Possible GILState issues? PyThreadState *save_tstate = _PyThreadState_Swap(runtime, tstate); Py_EndInterpreter(tstate); @@ -1133,7 +1249,7 @@ _PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required) } PyObject * -_PyInterpreterState_GetMainModule(PyInterpreterState *interp) +PyUnstable_InterpreterState_GetMainModule(PyInterpreterState *interp) { PyObject *modules = _PyImport_GetModules(interp); if (modules == NULL) { @@ -1266,7 +1382,14 @@ free_threadstate(PyThreadState *tstate) { // The initial thread state of the interpreter is allocated // as part of the interpreter state so should not be freed. - if (tstate != &tstate->interp->_initial_thread) { + if (tstate == &tstate->interp->_initial_thread) { + // Restore to _PyThreadState_INIT. + tstate = &tstate->interp->_initial_thread; + memcpy(tstate, + &initial._main_interpreter._initial_thread, + sizeof(*tstate)); + } + else { PyMem_RawFree(tstate); } } @@ -1281,7 +1404,7 @@ free_threadstate(PyThreadState *tstate) static void init_threadstate(PyThreadState *tstate, - PyInterpreterState *interp, uint64_t id) + PyInterpreterState *interp, uint64_t id, int whence) { if (tstate->_status.initialized) { Py_FatalError("thread state already initialized"); @@ -1294,6 +1417,10 @@ init_threadstate(PyThreadState *tstate, assert(tstate->next == NULL); assert(tstate->prev == NULL); + assert(tstate->_whence == _PyThreadState_WHENCE_NOTSET); + assert(whence >= 0 && whence <= _PyThreadState_WHENCE_EXEC); + tstate->_whence = whence; + assert(id > 0); tstate->id = id; @@ -1301,7 +1428,7 @@ init_threadstate(PyThreadState *tstate, tstate->py_recursion_limit = interp->ceval.recursion_limit, tstate->py_recursion_remaining = interp->ceval.recursion_limit, - tstate->c_recursion_remaining = C_RECURSION_LIMIT; + tstate->c_recursion_remaining = Py_C_RECURSION_LIMIT; tstate->exc_info = &tstate->exc_state; @@ -1309,7 +1436,7 @@ init_threadstate(PyThreadState *tstate, // This is cleared when PyGILState_Ensure() creates the thread state. tstate->gilstate_counter = 1; - tstate->cframe = &tstate->root_cframe; + tstate->current_frame = NULL; tstate->datastack_chunk = NULL; tstate->datastack_top = NULL; tstate->datastack_limit = NULL; @@ -1323,8 +1450,6 @@ add_threadstate(PyInterpreterState *interp, PyThreadState *tstate, PyThreadState *next) { assert(interp->threads.head != tstate); - assert((next != NULL && tstate->id != 1) || - (next == NULL && tstate->id == 1)); if (next != NULL) { assert(next->prev == NULL || next->prev == tstate); next->prev = tstate; @@ -1335,7 +1460,7 @@ add_threadstate(PyInterpreterState *interp, PyThreadState *tstate, } static PyThreadState * -new_threadstate(PyInterpreterState *interp) +new_threadstate(PyInterpreterState *interp, int whence) { PyThreadState *tstate; _PyRuntimeState *runtime = interp->runtime; @@ -1358,10 +1483,10 @@ new_threadstate(PyInterpreterState *interp) PyThreadState *old_head = interp->threads.head; if (old_head == NULL) { // It's the interpreter's initial thread state. - assert(id == 1); used_newtstate = 0; tstate = &interp->_initial_thread; } + // XXX Re-use interp->_initial_thread if not in use? else { // Every valid interpreter must have at least one thread. assert(id > 1); @@ -1374,7 +1499,7 @@ new_threadstate(PyInterpreterState *interp) sizeof(*tstate)); } - init_threadstate(tstate, interp, id); + init_threadstate(tstate, interp, id, whence); add_threadstate(interp, tstate, old_head); HEAD_UNLOCK(runtime); @@ -1388,7 +1513,8 @@ new_threadstate(PyInterpreterState *interp) PyThreadState * PyThreadState_New(PyInterpreterState *interp) { - PyThreadState *tstate = new_threadstate(interp); + PyThreadState *tstate = new_threadstate(interp, + _PyThreadState_WHENCE_UNKNOWN); if (tstate) { bind_tstate(tstate); // This makes sure there's a gilstate tstate bound @@ -1402,16 +1528,16 @@ PyThreadState_New(PyInterpreterState *interp) // This must be followed by a call to _PyThreadState_Bind(); PyThreadState * -_PyThreadState_New(PyInterpreterState *interp) +_PyThreadState_New(PyInterpreterState *interp, int whence) { - return new_threadstate(interp); + return new_threadstate(interp, whence); } // We keep this for stable ABI compabibility. PyAPI_FUNC(PyThreadState*) _PyThreadState_Prealloc(PyInterpreterState *interp) { - return _PyThreadState_New(interp); + return _PyThreadState_New(interp, _PyThreadState_WHENCE_UNKNOWN); } // We keep this around for (accidental) stable ABI compatibility. @@ -1451,7 +1577,7 @@ PyThreadState_Clear(PyThreadState *tstate) int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; - if (verbose && tstate->cframe->current_frame != NULL) { + if (verbose && tstate->current_frame != NULL) { /* bpo-20526: After the main thread calls _PyInterpreterState_SetFinalizing() in Py_FinalizeEx() (or in Py_EndInterpreter() for subinterpreters), @@ -1508,6 +1634,12 @@ PyThreadState_Clear(PyThreadState *tstate) Py_CLEAR(tstate->context); if (tstate->on_delete != NULL) { + // For the "main" thread of each interpreter, this is meant + // to be done in _PyInterpreterState_SetNotRunningMain(). + // That leaves threads created by the threading module, + // and any threads killed by forking. + // However, we also accommodate "main" threads that still + // don't call _PyInterpreterState_SetNotRunningMain() yet. tstate->on_delete(tstate->on_delete_data); } @@ -1522,6 +1654,7 @@ static void tstate_delete_common(PyThreadState *tstate) { assert(tstate->_status.cleared && !tstate->_status.finalized); + assert(tstate->state != _Py_THREAD_ATTACHED); PyInterpreterState *interp = tstate->interp; if (interp == NULL) { @@ -1582,6 +1715,7 @@ void _PyThreadState_DeleteCurrent(PyThreadState *tstate) { _Py_EnsureTstateNotNULL(tstate); + tstate_set_detached(tstate); tstate_delete_common(tstate); current_fast_clear(tstate->interp->runtime); _PyEval_ReleaseLock(tstate->interp, NULL); @@ -1640,75 +1774,6 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate) } -//------------------------- -// "detached" thread states -//------------------------- - -void -_PyThreadState_InitDetached(PyThreadState *tstate, PyInterpreterState *interp) -{ - _PyRuntimeState *runtime = interp->runtime; - - HEAD_LOCK(runtime); - interp->threads.next_unique_id += 1; - uint64_t id = interp->threads.next_unique_id; - HEAD_UNLOCK(runtime); - - init_threadstate(tstate, interp, id); - // We do not call add_threadstate(). -} - -void -_PyThreadState_ClearDetached(PyThreadState *tstate) -{ - assert(!tstate->_status.bound); - assert(!tstate->_status.bound_gilstate); - assert(tstate->datastack_chunk == NULL); - assert(tstate->thread_id == 0); - assert(tstate->native_thread_id == 0); - assert(tstate->next == NULL); - assert(tstate->prev == NULL); - - PyThreadState_Clear(tstate); - clear_datastack(tstate); -} - -void -_PyThreadState_BindDetached(PyThreadState *tstate) -{ - assert(!_Py_IsMainInterpreter( - current_fast_get(tstate->interp->runtime)->interp)); - assert(_Py_IsMainInterpreter(tstate->interp)); - bind_tstate(tstate); - /* Unlike _PyThreadState_Bind(), we do not modify gilstate TSS. */ -} - -void -_PyThreadState_UnbindDetached(PyThreadState *tstate) -{ - assert(!_Py_IsMainInterpreter( - current_fast_get(tstate->interp->runtime)->interp)); - assert(_Py_IsMainInterpreter(tstate->interp)); - assert(tstate_is_alive(tstate)); - assert(!tstate->_status.active); - assert(gilstate_tss_get(tstate->interp->runtime) != tstate); - - unbind_tstate(tstate); - - /* This thread state may be bound/unbound repeatedly, - so we must erase evidence that it was ever bound (or unbound). */ - tstate->_status.bound = 0; - tstate->_status.unbound = 0; - - /* We must fully unlink the thread state from any OS thread, - to allow it to be bound more than once. */ - tstate->thread_id = 0; -#ifdef PY_HAVE_THREAD_NATIVE_ID - tstate->native_thread_id = 0; -#endif -} - - //---------- // accessors //---------- @@ -1807,6 +1872,79 @@ tstate_deactivate(PyThreadState *tstate) // It will still be used in PyGILState_Ensure(). } +static int +tstate_try_attach(PyThreadState *tstate) +{ +#ifdef Py_NOGIL + int expected = _Py_THREAD_DETACHED; + if (_Py_atomic_compare_exchange_int( + &tstate->state, + &expected, + _Py_THREAD_ATTACHED)) { + return 1; + } + return 0; +#else + assert(tstate->state == _Py_THREAD_DETACHED); + tstate->state = _Py_THREAD_ATTACHED; + return 1; +#endif +} + +static void +tstate_set_detached(PyThreadState *tstate) +{ + assert(tstate->state == _Py_THREAD_ATTACHED); +#ifdef Py_NOGIL + _Py_atomic_store_int(&tstate->state, _Py_THREAD_DETACHED); +#else + tstate->state = _Py_THREAD_DETACHED; +#endif +} + +void +_PyThreadState_Attach(PyThreadState *tstate) +{ +#if defined(Py_DEBUG) + // This is called from PyEval_RestoreThread(). Similar + // to it, we need to ensure errno doesn't change. + int err = errno; +#endif + + _Py_EnsureTstateNotNULL(tstate); + if (current_fast_get(&_PyRuntime) != NULL) { + Py_FatalError("non-NULL old thread state"); + } + + _PyEval_AcquireLock(tstate); + + // XXX assert(tstate_is_alive(tstate)); + current_fast_set(&_PyRuntime, tstate); + tstate_activate(tstate); + + if (!tstate_try_attach(tstate)) { + // TODO: Once stop-the-world GC is implemented for --disable-gil builds + // this will need to wait until the GC completes. For now, this case + // should never happen. + Py_FatalError("thread attach failed"); + } + +#if defined(Py_DEBUG) + errno = err; +#endif +} + +void +_PyThreadState_Detach(PyThreadState *tstate) +{ + // XXX assert(tstate_is_alive(tstate) && tstate_is_bound(tstate)); + assert(tstate->state == _Py_THREAD_ATTACHED); + assert(tstate == current_fast_get(&_PyRuntime)); + tstate_set_detached(tstate); + tstate_deactivate(tstate); + current_fast_clear(&_PyRuntime); + _PyEval_ReleaseLock(tstate->interp, tstate); +} //---------- // other API @@ -1865,7 +2003,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) //--------------------------------- PyThreadState * -_PyThreadState_UncheckedGet(void) +PyThreadState_GetUnchecked(void) { return current_fast_get(&_PyRuntime); } @@ -1879,56 +2017,15 @@ PyThreadState_Get(void) return tstate; } - -static void -_swap_thread_states(_PyRuntimeState *runtime, - PyThreadState *oldts, PyThreadState *newts) -{ - // XXX Do this only if oldts != NULL? - current_fast_clear(runtime); - - if (oldts != NULL) { - // XXX assert(tstate_is_alive(oldts) && tstate_is_bound(oldts)); - tstate_deactivate(oldts); - } - - if (newts != NULL) { - // XXX assert(tstate_is_alive(newts)); - assert(tstate_is_bound(newts)); - current_fast_set(runtime, newts); - tstate_activate(newts); - } -} - -PyThreadState * -_PyThreadState_SwapNoGIL(PyThreadState *newts) -{ -#if defined(Py_DEBUG) - /* This can be called from PyEval_RestoreThread(). Similar - to it, we need to ensure errno doesn't change. - */ - int err = errno; -#endif - - PyThreadState *oldts = current_fast_get(&_PyRuntime); - _swap_thread_states(&_PyRuntime, oldts, newts); - -#if defined(Py_DEBUG) - errno = err; -#endif - return oldts; -} - PyThreadState * _PyThreadState_Swap(_PyRuntimeState *runtime, PyThreadState *newts) { PyThreadState *oldts = current_fast_get(runtime); if (oldts != NULL) { - _PyEval_ReleaseLock(oldts->interp, oldts); + _PyThreadState_Detach(oldts); } - _swap_thread_states(runtime, oldts, newts); if (newts != NULL) { - _PyEval_AcquireLock(newts); + _PyThreadState_Attach(newts); } return oldts; } @@ -1943,6 +2040,10 @@ PyThreadState_Swap(PyThreadState *newts) void _PyThreadState_Bind(PyThreadState *tstate) { + // gh-104690: If Python is being finalized and PyInterpreterState_Delete() + // was called, tstate becomes a dangling pointer. + assert(_PyThreadState_CheckConsistency(tstate)); + bind_tstate(tstate); // This makes sure there's a gilstate tstate bound // as soon as possible. @@ -2021,7 +2122,7 @@ _PyThread_CurrentFrames(void) for (i = runtime->interpreters.head; i != NULL; i = i->next) { PyThreadState *t; for (t = i->threads.head; t != NULL; t = t->next) { - _PyInterpreterFrame *frame = t->cframe->current_frame; + _PyInterpreterFrame *frame = t->current_frame; frame = _PyFrame_GetFirstComplete(frame); if (frame == NULL) { continue; @@ -2233,7 +2334,9 @@ PyGILState_Ensure(void) int has_gil; if (tcur == NULL) { /* Create a new Python thread state for this thread */ - tcur = new_threadstate(runtime->gilstate.autoInterpreterState); + // XXX Use PyInterpreterState_EnsureThreadState()? + tcur = new_threadstate(runtime->gilstate.autoInterpreterState, + _PyThreadState_WHENCE_GILSTATE); if (tcur == NULL) { Py_FatalError("Couldn't create thread-state for new thread"); } @@ -2331,10 +2434,16 @@ _xidata_init(_PyCrossInterpreterData *data) static inline void _xidata_clear(_PyCrossInterpreterData *data) { - if (data->free != NULL) { - data->free(data->data); + // _PyCrossInterpreterData only has two members that need to be + // cleaned up, if set: "data" must be freed and "obj" must be decref'ed. + // In both cases the original (owning) interpreter must be used, + // which is the caller's responsibility to ensure. + if (data->data != NULL) { + if (data->free != NULL) { + data->free(data->data); + } + data->data = NULL; } - data->data = NULL; Py_CLEAR(data->obj); } @@ -2479,40 +2588,50 @@ _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) return data->new_object(data); } -typedef void (*releasefunc)(PyInterpreterState *, void *); - -static void -_call_in_interpreter(PyInterpreterState *interp, releasefunc func, void *arg) +int +_Py_CallInInterpreter(PyInterpreterState *interp, + _Py_simple_func func, void *arg) { - /* We would use Py_AddPendingCall() if it weren't specific to the - * main interpreter (see bpo-33608). In the meantime we take a - * naive approach. - */ - _PyRuntimeState *runtime = interp->runtime; - PyThreadState *save_tstate = NULL; - if (interp != current_fast_get(runtime)->interp) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - // XXX Possible GILState issues? - save_tstate = _PyThreadState_Swap(runtime, tstate); + if (interp == current_fast_get(interp->runtime)->interp) { + return func(arg); } + // XXX Emit a warning if this fails? + _PyEval_AddPendingCall(interp, (_Py_pending_call_func)func, arg, 0); + return 0; +} - // XXX Once the GIL is per-interpreter, this should be called with the - // calling interpreter's GIL released and the target interpreter's held. - func(interp, arg); - - // Switch back. - if (save_tstate != NULL) { - _PyThreadState_Swap(runtime, save_tstate); +int +_Py_CallInInterpreterAndRawFree(PyInterpreterState *interp, + _Py_simple_func func, void *arg) +{ + if (interp == current_fast_get(interp->runtime)->interp) { + int res = func(arg); + PyMem_RawFree(arg); + return res; } + // XXX Emit a warning if this fails? + _PyEval_AddPendingCall(interp, func, arg, _Py_PENDING_RAWFREE); + return 0; } -int -_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) +static int +_call_clear_xidata(void *data) +{ + _xidata_clear((_PyCrossInterpreterData *)data); + return 0; +} + +static int +_xidata_release(_PyCrossInterpreterData *data, int rawfree) { - if (data->free == NULL && data->obj == NULL) { + if ((data->data == NULL || data->free == NULL) && data->obj == NULL) { // Nothing to release! - data->data = NULL; + if (rawfree) { + PyMem_RawFree(data); + } + else { + data->data = NULL; + } return 0; } @@ -2523,13 +2642,31 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) // This function shouldn't have been called. // XXX Someone leaked some memory... assert(PyErr_Occurred()); + if (rawfree) { + PyMem_RawFree(data); + } return -1; } // "Release" the data and/or the object. - _call_in_interpreter(interp, - (releasefunc)_PyCrossInterpreterData_Clear, data); - return 0; + if (rawfree) { + return _Py_CallInInterpreterAndRawFree(interp, _call_clear_xidata, data); + } + else { + return _Py_CallInInterpreter(interp, _call_clear_xidata, data); + } +} + +int +_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) +{ + return _xidata_release(data, 0); +} + +int +_PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *data) +{ + return _xidata_release(data, 1); } /* registry of {type -> crossinterpdatafunc} */ @@ -2539,23 +2676,27 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) crossinterpdatafunc. It would be simpler and more efficient. */ static int -_xidregistry_add_type(struct _xidregistry *xidregistry, PyTypeObject *cls, - crossinterpdatafunc getdata) +_xidregistry_add_type(struct _xidregistry *xidregistry, + PyTypeObject *cls, crossinterpdatafunc getdata) { - // Note that we effectively replace already registered classes - // rather than failing. struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); if (newhead == NULL) { return -1; } - // XXX Assign a callback to clear the entry from the registry? - newhead->cls = PyWeakref_NewRef((PyObject *)cls, NULL); - if (newhead->cls == NULL) { - PyMem_RawFree(newhead); - return -1; + *newhead = (struct _xidregitem){ + // We do not keep a reference, to avoid keeping the class alive. + .cls = cls, + .refcount = 1, + .getdata = getdata, + }; + if (cls->tp_flags & Py_TPFLAGS_HEAPTYPE) { + // XXX Assign a callback to clear the entry from the registry? + newhead->weakref = PyWeakref_NewRef((PyObject *)cls, NULL); + if (newhead->weakref == NULL) { + PyMem_RawFree(newhead); + return -1; + } } - newhead->getdata = getdata; - newhead->prev = NULL; newhead->next = xidregistry->head; if (newhead->next != NULL) { newhead->next->prev = newhead; @@ -2580,39 +2721,77 @@ _xidregistry_remove_entry(struct _xidregistry *xidregistry, if (next != NULL) { next->prev = entry->prev; } - Py_DECREF(entry->cls); + Py_XDECREF(entry->weakref); PyMem_RawFree(entry); return next; } +static void +_xidregistry_clear(struct _xidregistry *xidregistry) +{ + struct _xidregitem *cur = xidregistry->head; + xidregistry->head = NULL; + while (cur != NULL) { + struct _xidregitem *next = cur->next; + Py_XDECREF(cur->weakref); + PyMem_RawFree(cur); + cur = next; + } +} + static struct _xidregitem * _xidregistry_find_type(struct _xidregistry *xidregistry, PyTypeObject *cls) { struct _xidregitem *cur = xidregistry->head; while (cur != NULL) { - PyObject *registered = _PyWeakref_GET_REF(cur->cls); - if (registered == NULL) { - // The weakly ref'ed object was freed. - cur = _xidregistry_remove_entry(xidregistry, cur); - } - else { - assert(PyType_Check(registered)); - if (registered == (PyObject *)cls) { - Py_DECREF(registered); - return cur; + if (cur->weakref != NULL) { + // cur is/was a heap type. + PyObject *registered = _PyWeakref_GET_REF(cur->weakref); + if (registered == NULL) { + // The weakly ref'ed object was freed. + cur = _xidregistry_remove_entry(xidregistry, cur); + continue; } + assert(PyType_Check(registered)); + assert(cur->cls == (PyTypeObject *)registered); + assert(cur->cls->tp_flags & Py_TPFLAGS_HEAPTYPE); Py_DECREF(registered); - cur = cur->next; } + if (cur->cls == cls) { + return cur; + } + cur = cur->next; } return NULL; } +static inline struct _xidregistry * +_get_xidregistry(PyInterpreterState *interp, PyTypeObject *cls) +{ + struct _xidregistry *xidregistry = &interp->runtime->xidregistry; + if (cls->tp_flags & Py_TPFLAGS_HEAPTYPE) { + assert(interp->xidregistry.mutex == xidregistry->mutex); + xidregistry = &interp->xidregistry; + } + return xidregistry; +} + static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry); +static inline void +_ensure_builtins_xid(PyInterpreterState *interp, struct _xidregistry *xidregistry) +{ + if (xidregistry != &interp->xidregistry) { + assert(xidregistry == &interp->runtime->xidregistry); + if (xidregistry->head == NULL) { + _register_builtins_for_crossinterpreter_data(xidregistry); + } + } +} + int _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, - crossinterpdatafunc getdata) + crossinterpdatafunc getdata) { if (!PyType_Check(cls)) { PyErr_Format(PyExc_ValueError, "only classes may be registered"); @@ -2623,12 +2802,23 @@ _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, return -1; } - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; + int res = 0; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _xidregistry *xidregistry = _get_xidregistry(interp, cls); PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - if (xidregistry->head == NULL) { - _register_builtins_for_crossinterpreter_data(xidregistry); + + _ensure_builtins_xid(interp, xidregistry); + + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); + if (matched != NULL) { + assert(matched->getdata == getdata); + matched->refcount += 1; + goto finally; } - int res = _xidregistry_add_type(xidregistry, cls, getdata); + + res = _xidregistry_add_type(xidregistry, cls, getdata); + +finally: PyThread_release_lock(xidregistry->mutex); return res; } @@ -2637,13 +2827,20 @@ int _PyCrossInterpreterData_UnregisterClass(PyTypeObject *cls) { int res = 0; - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _xidregistry *xidregistry = _get_xidregistry(interp, cls); PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); if (matched != NULL) { - (void)_xidregistry_remove_entry(xidregistry, matched); + assert(matched->refcount > 0); + matched->refcount -= 1; + if (matched->refcount == 0) { + (void)_xidregistry_remove_entry(xidregistry, matched); + } res = 1; } + PyThread_release_lock(xidregistry->mutex); return res; } @@ -2656,17 +2853,19 @@ _PyCrossInterpreterData_UnregisterClass(PyTypeObject *cls) crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *obj) { - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyObject *cls = PyObject_Type(obj); + PyTypeObject *cls = Py_TYPE(obj); + + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _xidregistry *xidregistry = _get_xidregistry(interp, cls); PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - if (xidregistry->head == NULL) { - _register_builtins_for_crossinterpreter_data(xidregistry); - } - struct _xidregitem *matched = _xidregistry_find_type(xidregistry, - (PyTypeObject *)cls); - Py_DECREF(cls); + + _ensure_builtins_xid(interp, xidregistry); + + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); + crossinterpdatafunc func = matched != NULL ? matched->getdata : NULL; + PyThread_release_lock(xidregistry->mutex); - return matched != NULL ? matched->getdata : NULL; + return func; } /* cross-interpreter data for builtin types */ @@ -2802,6 +3001,10 @@ _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) } +/*************/ +/* Other API */ +/*************/ + _PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp) { @@ -2926,6 +3129,59 @@ _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) } -#ifdef __cplusplus +#ifndef NDEBUG +// Check that a Python thread state valid. In practice, this function is used +// on a Python debug build to check if 'tstate' is a dangling pointer, if the +// PyThreadState memory has been freed. +// +// Usage: +// +// assert(_PyThreadState_CheckConsistency(tstate)); +int +_PyThreadState_CheckConsistency(PyThreadState *tstate) +{ + assert(!_PyMem_IsPtrFreed(tstate)); + assert(!_PyMem_IsPtrFreed(tstate->interp)); + return 1; } #endif + + +// Check if a Python thread must exit immediately, rather than taking the GIL +// if Py_Finalize() has been called. +// +// When this function is called by a daemon thread after Py_Finalize() has been +// called, the GIL does no longer exist. +// +// tstate can be a dangling pointer (point to freed memory): only tstate value +// is used, the pointer is not deferenced. +// +// tstate must be non-NULL. +int +_PyThreadState_MustExit(PyThreadState *tstate) +{ + /* bpo-39877: Access _PyRuntime directly rather than using + tstate->interp->runtime to support calls from Python daemon threads. + After Py_Finalize() has been called, tstate can be a dangling pointer: + point to PyThreadState freed memory. */ + unsigned long finalizing_id = _PyRuntimeState_GetFinalizingID(&_PyRuntime); + PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); + if (finalizing == NULL) { + // XXX This isn't completely safe from daemon thraeds, + // since tstate might be a dangling pointer. + finalizing = _PyInterpreterState_GetFinalizing(tstate->interp); + finalizing_id = _PyInterpreterState_GetFinalizingID(tstate->interp); + } + // XXX else check &_PyRuntime._main_interpreter._initial_thread + if (finalizing == NULL) { + return 0; + } + else if (finalizing == tstate) { + return 0; + } + else if (finalizing_id == PyThread_get_thread_ident()) { + /* gh-109793: we must have switched interpreters. */ + return 0; + } + return 1; +} diff --git a/Python/pystrcmp.c b/Python/pystrcmp.c index 9224ce4c706055..9796cb013ad450 100644 --- a/Python/pystrcmp.c +++ b/Python/pystrcmp.c @@ -11,11 +11,11 @@ PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size) return 0; p1 = (const unsigned char *)s1; p2 = (const unsigned char *)s2; - for (; (--size > 0) && *p1 && *p2 && (tolower(*p1) == tolower(*p2)); + for (; (--size > 0) && *p1 && *p2 && (Py_TOLOWER(*p1) == Py_TOLOWER(*p2)); p1++, p2++) { ; } - return tolower(*p1) - tolower(*p2); + return Py_TOLOWER(*p1) - Py_TOLOWER(*p2); } int @@ -23,8 +23,8 @@ PyOS_mystricmp(const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; - for (; *p1 && *p2 && (tolower(*p1) == tolower(*p2)); p1++, p2++) { + for (; *p1 && *p2 && (Py_TOLOWER(*p1) == Py_TOLOWER(*p2)); p1++, p2++) { ; } - return (tolower(*p1) - tolower(*p2)); + return (Py_TOLOWER(*p1) - Py_TOLOWER(*p2)); } diff --git a/Python/pystrhex.c b/Python/pystrhex.c index ce456b79f1655f..38484f5a7d4227 100644 --- a/Python/pystrhex.c +++ b/Python/pystrhex.c @@ -3,7 +3,6 @@ #include "Python.h" #include "pycore_strhex.h" // _Py_strhex_with_sep() #include "pycore_unicodeobject.h" // _PyUnicode_CheckConsistency() -#include // abs() static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, PyObject* sep, int bytes_per_sep_group, @@ -44,7 +43,7 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, bytes_per_sep_group = 0; } - unsigned int abs_bytes_per_sep = abs(bytes_per_sep_group); + unsigned int abs_bytes_per_sep = Py_ABS(bytes_per_sep_group); Py_ssize_t resultlen = 0; if (bytes_per_sep_group && arglen > 0) { /* How many sep characters we'll be inserting. */ diff --git a/Python/pystrtod.c b/Python/pystrtod.c index 9bb060e3d11979..16bf06f0e6cca2 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -3,7 +3,8 @@ #include #include "pycore_dtoa.h" // _Py_dg_strtod() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR -#include + +#include // localeconv() /* Case-insensitive string match used for nan and inf detection; t should be lower-case. Returns 1 for a successful match, 0 otherwise. */ diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 721c527745c44a..74994295a9b23a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -12,17 +12,18 @@ #include "Python.h" -#include "pycore_ast.h" // PyAST_mod2obj -#include "pycore_ceval.h" // _Py_EnterRecursiveCall +#include "pycore_ast.h" // PyAST_mod2obj() +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "pycore_compile.h" // _PyAST_Compile() #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_object.h" // _PyDebug_PrintTotalRefs() #include "pycore_parser.h" // _PyParser_ASTFromString() -#include "pycore_pyerrors.h" // _PyErr_GetRaisedException, _Py_Offer_Suggestions -#include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() +#include "pycore_pylifecycle.h" // _Py_FdIsInteractive() #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_pythonrun.h" // export _PyRun_InteractiveLoopObject() #include "pycore_sysmodule.h" // _PySys_Audit() -#include "pycore_traceback.h" // _PyTraceBack_Print_Indented() +#include "pycore_traceback.h" // _PyTraceBack_Print() #include "errcode.h" // E_EOF #include "marshal.h" // PyMarshal_ReadLongFromFile() @@ -36,15 +37,10 @@ # include "windows.h" #endif - -#ifdef __cplusplus -extern "C" { -#endif - /* Forward */ static void flush_io(void); static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, - PyCompilerFlags *, PyArena *); + PyCompilerFlags *, PyArena *, PyObject*); static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *, PyCompilerFlags *); static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *); @@ -182,7 +178,8 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag // Call _PyParser_ASTFromFile() with sys.stdin.encoding, sys.ps1 and sys.ps2 static int pyrun_one_parse_ast(FILE *fp, PyObject *filename, - PyCompilerFlags *flags, PyArena *arena, mod_ty *pmod) + PyCompilerFlags *flags, PyArena *arena, + mod_ty *pmod, PyObject** interactive_src) { PyThreadState *tstate = _PyThreadState_GET(); @@ -240,9 +237,9 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename, } int errcode = 0; - *pmod = _PyParser_ASTFromFile(fp, filename, encoding, - Py_single_input, ps1, ps2, - flags, &errcode, arena); + *pmod = _PyParser_InteractiveASTFromFile(fp, filename, encoding, + Py_single_input, ps1, ps2, + flags, &errcode, interactive_src, arena); Py_XDECREF(ps1_obj); Py_XDECREF(ps2_obj); Py_XDECREF(encoding_obj); @@ -270,7 +267,8 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } mod_ty mod; - int parse_res = pyrun_one_parse_ast(fp, filename, flags, arena, &mod); + PyObject *interactive_src; + int parse_res = pyrun_one_parse_ast(fp, filename, flags, arena, &mod, &interactive_src); if (parse_res != 0) { _PyArena_Free(arena); return parse_res; @@ -283,7 +281,7 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } PyObject *main_dict = PyModule_GetDict(main_module); // borrowed ref - PyObject *res = run_mod(mod, filename, main_dict, main_dict, flags, arena); + PyObject *res = run_mod(mod, filename, main_dict, main_dict, flags, arena, interactive_src); _PyArena_Free(arena); Py_DECREF(main_module); if (res == NULL) { @@ -412,10 +410,11 @@ _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, PyObject *dict = PyModule_GetDict(main_module); // borrowed ref int set_file_name = 0; - if (_PyDict_GetItemStringWithError(dict, "__file__") == NULL) { - if (PyErr_Occurred()) { - goto done; - } + int has_file = PyDict_ContainsString(dict, "__file__"); + if (has_file < 0) { + goto done; + } + if (!has_file) { if (PyDict_SetItemString(dict, "__file__", filename) < 0) { goto done; } @@ -520,204 +519,6 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) return 0; } -static int -parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, - Py_ssize_t *lineno, Py_ssize_t *offset, - Py_ssize_t* end_lineno, Py_ssize_t* end_offset, - PyObject **text) -{ - Py_ssize_t hold; - PyObject *v; - - *message = NULL; - *filename = NULL; - - /* new style errors. `err' is an instance */ - *message = PyObject_GetAttr(err, &_Py_ID(msg)); - if (!*message) - goto finally; - - v = PyObject_GetAttr(err, &_Py_ID(filename)); - if (!v) - goto finally; - if (v == Py_None) { - Py_DECREF(v); - _Py_DECLARE_STR(anon_string, ""); - *filename = Py_NewRef(&_Py_STR(anon_string)); - } - else { - *filename = v; - } - - v = PyObject_GetAttr(err, &_Py_ID(lineno)); - if (!v) - goto finally; - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *lineno = hold; - - v = PyObject_GetAttr(err, &_Py_ID(offset)); - if (!v) - goto finally; - if (v == Py_None) { - *offset = -1; - Py_DECREF(v); - } else { - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *offset = hold; - } - - if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) { - v = PyObject_GetAttr(err, &_Py_ID(end_lineno)); - if (!v) { - PyErr_Clear(); - *end_lineno = *lineno; - } - else if (v == Py_None) { - *end_lineno = *lineno; - Py_DECREF(v); - } else { - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *end_lineno = hold; - } - - v = PyObject_GetAttr(err, &_Py_ID(end_offset)); - if (!v) { - PyErr_Clear(); - *end_offset = -1; - } - else if (v == Py_None) { - *end_offset = -1; - Py_DECREF(v); - } else { - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *end_offset = hold; - } - } else { - // SyntaxError subclasses - *end_lineno = *lineno; - *end_offset = -1; - } - - v = PyObject_GetAttr(err, &_Py_ID(text)); - if (!v) - goto finally; - if (v == Py_None) { - Py_DECREF(v); - *text = NULL; - } - else { - *text = v; - } - return 1; - -finally: - Py_XDECREF(*message); - Py_XDECREF(*filename); - return 0; -} - -static int -print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, - PyObject *text_obj) -{ - size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ? - end_offset - offset : 1; - - /* Convert text to a char pointer; return if error */ - const char *text = PyUnicode_AsUTF8(text_obj); - if (text == NULL) { - return -1; - } - - /* Convert offset from 1-based to 0-based */ - offset--; - - /* Strip leading whitespace from text, adjusting offset as we go */ - while (*text == ' ' || *text == '\t' || *text == '\f') { - text++; - offset--; - } - - /* Calculate text length excluding trailing newline */ - Py_ssize_t len = strlen(text); - if (len > 0 && text[len-1] == '\n') { - len--; - } - - /* Clip offset to at most len */ - if (offset > len) { - offset = len; - } - - /* Skip past newlines embedded in text */ - for (;;) { - const char *nl = strchr(text, '\n'); - if (nl == NULL) { - break; - } - Py_ssize_t inl = nl - text; - if (inl >= offset) { - break; - } - inl += 1; - text += inl; - len -= inl; - offset -= (int)inl; - } - - /* Print text */ - if (PyFile_WriteString(" ", f) < 0) { - return -1; - } - if (PyFile_WriteString(text, f) < 0) { - return -1; - } - - /* Make sure there's a newline at the end */ - if (text[len] != '\n') { - if (PyFile_WriteString("\n", f) < 0) { - return -1; - } - } - - /* Don't print caret if it points to the left of the text */ - if (offset < 0) { - return 0; - } - - /* Write caret line */ - if (PyFile_WriteString(" ", f) < 0) { - return -1; - } - while (--offset >= 0) { - if (PyFile_WriteString(" ", f) < 0) { - return -1; - } - } - for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) { - if (PyFile_WriteString("^", f) < 0) { - return -1; - } - } - if (PyFile_WriteString("\n", f) < 0) { - return -1; - } - return 0; -} - - int _Py_HandleSystemExit(int *exitcode_p) { @@ -886,29 +687,13 @@ struct exception_print_context { PyObject *file; PyObject *seen; // Prevent cycles in recursion - int exception_group_depth; // nesting level of current exception group - bool need_close; // Need a closing bottom frame - int max_group_width; // Maximum number of children of each EG - int max_group_depth; // Maximum nesting level of EGs }; -#define EXC_MARGIN(ctx) ((ctx)->exception_group_depth ? "| " : "") -#define EXC_INDENT(ctx) (2 * (ctx)->exception_group_depth) - -static int -write_indented_margin(struct exception_print_context *ctx, PyObject *f) -{ - return _Py_WriteIndentedMargin(EXC_INDENT(ctx), EXC_MARGIN(ctx), f); -} - static int print_exception_invalid_type(struct exception_print_context *ctx, PyObject *value) { PyObject *f = ctx->file; - if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) { - return -1; - } const char *const msg = "TypeError: print_exception(): Exception expected " "for value, "; if (PyFile_WriteString(msg, f) < 0) { @@ -932,15 +717,7 @@ print_exception_traceback(struct exception_print_context *ctx, PyObject *value) PyObject *tb = PyException_GetTraceback(value); if (tb && tb != Py_None) { const char *header = EXCEPTION_TB_HEADER; - const char *header_margin = EXC_MARGIN(ctx); - if (_PyBaseExceptionGroup_Check(value)) { - header = EXCEPTION_GROUP_TB_HEADER; - if (ctx->exception_group_depth == 1) { - header_margin = "+ "; - } - } - err = _PyTraceBack_Print_Indented( - tb, EXC_INDENT(ctx), EXC_MARGIN(ctx), header_margin, header, f); + err = _PyTraceBack_Print(tb, header, f); } Py_XDECREF(tb); return err; @@ -962,16 +739,20 @@ print_exception_file_and_line(struct exception_print_context *ctx, } Py_DECREF(tmp); - PyObject *message, *filename, *text; - Py_ssize_t lineno, offset, end_lineno, end_offset; - if (!parse_syntax_error(*value_p, &message, &filename, - &lineno, &offset, - &end_lineno, &end_offset, &text)) { - PyErr_Clear(); - return 0; + PyObject *filename = NULL; + Py_ssize_t lineno = 0; + PyObject* v = PyObject_GetAttr(*value_p, &_Py_ID(filename)); + if (!v) { + return -1; + } + if (v == Py_None) { + Py_DECREF(v); + _Py_DECLARE_STR(anon_string, ""); + filename = Py_NewRef(&_Py_STR(anon_string)); + } + else { + filename = v; } - - Py_SETREF(*value_p, message); PyObject *line = PyUnicode_FromFormat(" File \"%S\", line %zd\n", filename, lineno); @@ -979,40 +760,16 @@ print_exception_file_and_line(struct exception_print_context *ctx, if (line == NULL) { goto error; } - if (write_indented_margin(ctx, f) < 0) { - goto error; - } if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) { goto error; } Py_CLEAR(line); - if (text != NULL) { - Py_ssize_t line_size; - const char *error_line = PyUnicode_AsUTF8AndSize(text, &line_size); - // If the location of the error spawn multiple lines, we want - // to just print the first one and highlight everything until - // the end of that one since we don't support multi-line error - // messages. - if (end_lineno > lineno) { - end_offset = (error_line != NULL) ? line_size : -1; - } - // Limit the amount of '^' that we can display to - // the size of the text in the source line. - if (error_line != NULL && end_offset > line_size + 1) { - end_offset = line_size + 1; - } - if (print_error_text(f, offset, end_offset, text) < 0) { - goto error; - } - Py_DECREF(text); - } assert(!PyErr_Occurred()); return 0; error: Py_XDECREF(line); - Py_XDECREF(text); return -1; } @@ -1023,11 +780,14 @@ print_exception_message(struct exception_print_context *ctx, PyObject *type, { PyObject *f = ctx->file; - assert(PyExceptionClass_Check(type)); - - if (write_indented_margin(ctx, f) < 0) { + if (PyErr_GivenExceptionMatches(value, PyExc_MemoryError)) { + // The Python APIs in this function require allocating memory + // for various objects. If we're out of memory, we can't do that, return -1; } + + assert(PyExceptionClass_Check(type)); + PyObject *modulename = PyObject_GetAttr(type, &_Py_ID(__module__)); if (modulename == NULL || !PyUnicode_Check(modulename)) { Py_XDECREF(modulename); @@ -1101,108 +861,6 @@ print_exception_message(struct exception_print_context *ctx, PyObject *type, return 0; } -static int -print_exception_suggestions(struct exception_print_context *ctx, - PyObject *value) -{ - PyObject *f = ctx->file; - PyObject *suggestions = _Py_Offer_Suggestions(value); - if (suggestions) { - if (PyFile_WriteObject(suggestions, f, Py_PRINT_RAW) < 0) { - goto error; - } - Py_DECREF(suggestions); - } - else if (PyErr_Occurred()) { - PyErr_Clear(); - } - return 0; -error: - Py_XDECREF(suggestions); - return -1; -} - -static int -print_exception_notes(struct exception_print_context *ctx, PyObject *value) -{ - PyObject *f = ctx->file; - - if (!PyExceptionInstance_Check(value)) { - return 0; - } - - PyObject *notes; - int res = PyObject_GetOptionalAttr(value, &_Py_ID(__notes__), ¬es); - if (res <= 0) { - return res; - } - if (!PySequence_Check(notes) || PyUnicode_Check(notes) || PyBytes_Check(notes)) { - res = 0; - if (write_indented_margin(ctx, f) < 0) { - res = -1; - } - PyObject *s = PyObject_Repr(notes); - if (s == NULL) { - PyErr_Clear(); - res = PyFile_WriteString("<__notes__ repr() failed>", f); - } - else { - res = PyFile_WriteObject(s, f, Py_PRINT_RAW); - Py_DECREF(s); - } - Py_DECREF(notes); - if (PyFile_WriteString("\n", f) < 0) { - res = -1; - } - return res; - } - Py_ssize_t num_notes = PySequence_Length(notes); - PyObject *lines = NULL; - for (Py_ssize_t ni = 0; ni < num_notes; ni++) { - PyObject *note = PySequence_GetItem(notes, ni); - PyObject *note_str = PyObject_Str(note); - Py_DECREF(note); - - if (note_str == NULL) { - PyErr_Clear(); - if (PyFile_WriteString("", f) < 0) { - goto error; - } - } - else { - lines = PyUnicode_Splitlines(note_str, 1); - Py_DECREF(note_str); - - if (lines == NULL) { - goto error; - } - - Py_ssize_t n = PyList_GET_SIZE(lines); - for (Py_ssize_t i = 0; i < n; i++) { - PyObject *line = PyList_GET_ITEM(lines, i); - assert(PyUnicode_Check(line)); - if (write_indented_margin(ctx, f) < 0) { - goto error; - } - if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) { - goto error; - } - } - Py_CLEAR(lines); - } - if (PyFile_WriteString("\n", f) < 0) { - goto error; - } - } - - Py_DECREF(notes); - return 0; -error: - Py_XDECREF(lines); - Py_DECREF(notes); - return -1; -} - static int print_exception(struct exception_print_context *ctx, PyObject *value) { @@ -1219,7 +877,7 @@ print_exception(struct exception_print_context *ctx, PyObject *value) goto error; } - /* grab the type now because value can change below */ + /* grab the type and notes now because value can change below */ PyObject *type = (PyObject *) Py_TYPE(value); if (print_exception_file_and_line(ctx, &value) < 0) { @@ -1228,16 +886,9 @@ print_exception(struct exception_print_context *ctx, PyObject *value) if (print_exception_message(ctx, type, value) < 0) { goto error; } - if (print_exception_suggestions(ctx, value) < 0) { - goto error; - } if (PyFile_WriteString("\n", f) < 0) { goto error; } - if (print_exception_notes(ctx, value) < 0) { - goto error; - } - Py_DECREF(value); assert(!PyErr_Occurred()); return 0; @@ -1265,29 +916,18 @@ print_chained(struct exception_print_context* ctx, PyObject *value, if (_Py_EnterRecursiveCall(" in print_chained")) { return -1; } - bool need_close = ctx->need_close; int res = print_exception_recursive(ctx, value); - ctx->need_close = need_close; _Py_LeaveRecursiveCall(); if (res < 0) { return -1; } - if (write_indented_margin(ctx, f) < 0) { - return -1; - } if (PyFile_WriteString("\n", f) < 0) { return -1; } - if (write_indented_margin(ctx, f) < 0) { - return -1; - } if (PyFile_WriteString(message, f) < 0) { return -1; } - if (write_indented_margin(ctx, f) < 0) { - return -1; - } if (PyFile_WriteString("\n", f) < 0) { return -1; } @@ -1364,133 +1004,6 @@ print_exception_cause_and_context(struct exception_print_context *ctx, return 0; } -static int -print_exception_group(struct exception_print_context *ctx, PyObject *value) -{ - PyObject *f = ctx->file; - - if (ctx->exception_group_depth > ctx->max_group_depth) { - /* depth exceeds limit */ - - if (write_indented_margin(ctx, f) < 0) { - return -1; - } - - PyObject *line = PyUnicode_FromFormat("... (max_group_depth is %d)\n", - ctx->max_group_depth); - if (line == NULL) { - return -1; - } - int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - Py_DECREF(line); - return err; - } - - if (ctx->exception_group_depth == 0) { - ctx->exception_group_depth += 1; - } - if (print_exception(ctx, value) < 0) { - return -1; - } - - PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs; - assert(excs && PyTuple_Check(excs)); - Py_ssize_t num_excs = PyTuple_GET_SIZE(excs); - assert(num_excs > 0); - Py_ssize_t n; - if (num_excs <= ctx->max_group_width) { - n = num_excs; - } - else { - n = ctx->max_group_width + 1; - } - - ctx->need_close = false; - for (Py_ssize_t i = 0; i < n; i++) { - bool last_exc = (i == n - 1); - if (last_exc) { - // The closing frame may be added in a recursive call - ctx->need_close = true; - } - - if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) { - return -1; - } - bool truncated = (i >= ctx->max_group_width); - PyObject *line; - if (!truncated) { - line = PyUnicode_FromFormat( - "%s+---------------- %zd ----------------\n", - (i == 0) ? "+-" : " ", i + 1); - } - else { - line = PyUnicode_FromFormat( - "%s+---------------- ... ----------------\n", - (i == 0) ? "+-" : " "); - } - if (line == NULL) { - return -1; - } - int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - Py_DECREF(line); - if (err < 0) { - return -1; - } - - ctx->exception_group_depth += 1; - PyObject *exc = PyTuple_GET_ITEM(excs, i); - - if (!truncated) { - if (_Py_EnterRecursiveCall(" in print_exception_group")) { - return -1; - } - int res = print_exception_recursive(ctx, exc); - _Py_LeaveRecursiveCall(); - if (res < 0) { - return -1; - } - } - else { - Py_ssize_t excs_remaining = num_excs - ctx->max_group_width; - - if (write_indented_margin(ctx, f) < 0) { - return -1; - } - - PyObject *line = PyUnicode_FromFormat( - "and %zd more exception%s\n", - excs_remaining, excs_remaining > 1 ? "s" : ""); - - if (line == NULL) { - return -1; - } - - int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - Py_DECREF(line); - if (err < 0) { - return -1; - } - } - - if (last_exc && ctx->need_close) { - if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) { - return -1; - } - if (PyFile_WriteString( - "+------------------------------------\n", f) < 0) { - return -1; - } - ctx->need_close = false; - } - ctx->exception_group_depth -= 1; - } - - if (ctx->exception_group_depth == 1) { - ctx->exception_group_depth -= 1; - } - return 0; -} - static int print_exception_recursive(struct exception_print_context *ctx, PyObject *value) { @@ -1503,12 +1016,7 @@ print_exception_recursive(struct exception_print_context *ctx, PyObject *value) goto error; } } - if (!_PyBaseExceptionGroup_Check(value)) { - if (print_exception(ctx, value) < 0) { - goto error; - } - } - else if (print_exception_group(ctx, value) < 0) { + if (print_exception(ctx, value) < 0) { goto error; } assert(!PyErr_Occurred()); @@ -1520,9 +1028,6 @@ print_exception_recursive(struct exception_print_context *ctx, PyObject *value) return -1; } -#define PyErr_MAX_GROUP_WIDTH 15 -#define PyErr_MAX_GROUP_DEPTH 10 - void _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb) { @@ -1540,12 +1045,45 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb) } } + int unhandled_keyboard_interrupt = _PyRuntime.signals.unhandled_keyboard_interrupt; + + if (!value || PyErr_GivenExceptionMatches(value, PyExc_MemoryError)) { + goto fallback; + } + + // Try first with the stdlib traceback module + PyObject *traceback_module = PyImport_ImportModule("traceback"); + + if (traceback_module == NULL) { + goto fallback; + } + + PyObject *print_exception_fn = PyObject_GetAttrString(traceback_module, "_print_exception_bltin"); + + if (print_exception_fn == NULL || !PyCallable_Check(print_exception_fn)) { + Py_DECREF(traceback_module); + goto fallback; + } + + PyObject* result = PyObject_CallOneArg(print_exception_fn, value); + + Py_DECREF(traceback_module); + Py_XDECREF(print_exception_fn); + if (result) { + Py_DECREF(result); + _PyRuntime.signals.unhandled_keyboard_interrupt = unhandled_keyboard_interrupt; + return; + } +fallback: + _PyRuntime.signals.unhandled_keyboard_interrupt = unhandled_keyboard_interrupt; +#ifdef Py_DEBUG + if (PyErr_Occurred()) { + _PyErr_WriteUnraisableMsg("in the internal traceback machinery", NULL); + } +#endif + PyErr_Clear(); struct exception_print_context ctx; ctx.file = file; - ctx.exception_group_depth = 0; - ctx.need_close = false; - ctx.max_group_width = PyErr_MAX_GROUP_WIDTH; - ctx.max_group_depth = PyErr_MAX_GROUP_DEPTH; /* We choose to ignore seen being possibly NULL, and report at least the main exception (it could be a MemoryError). @@ -1562,14 +1100,10 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb) Py_XDECREF(ctx.seen); /* Call file.flush() */ - PyObject *res = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); - if (!res) { + if (_PyFile_Flush(file) < 0) { /* Silently ignore file.flush() error */ PyErr_Clear(); } - else { - Py_DECREF(res); - } } void @@ -1617,7 +1151,7 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, str, &_Py_STR(anon_string), start, flags, arena); if (mod != NULL) - ret = run_mod(mod, &_Py_STR(anon_string), globals, locals, flags, arena); + ret = run_mod(mod, &_Py_STR(anon_string), globals, locals, flags, arena, NULL); _PyArena_Free(arena); return ret; } @@ -1642,7 +1176,7 @@ pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, PyObject *ret; if (mod != NULL) { - ret = run_mod(mod, filename, globals, locals, flags, arena); + ret = run_mod(mod, filename, globals, locals, flags, arena, NULL); } else { ret = NULL; @@ -1674,11 +1208,7 @@ flush_io_stream(PyThreadState *tstate, PyObject *name) { PyObject *f = _PySys_GetAttr(tstate, name); if (f != NULL) { - PyObject *r = PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); - if (r) { - Py_DECREF(r); - } - else { + if (_PyFile_Flush(f) < 0) { PyErr_Clear(); } } @@ -1712,13 +1242,17 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py _PyRuntime.signals.unhandled_keyboard_interrupt = 0; /* Set globals['__builtins__'] if it doesn't exist */ - if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) { - if (PyErr_Occurred() || - PyDict_SetItemString(globals, "__builtins__", - tstate->interp->builtins) < 0) - { + if (globals != NULL) { + int has_builtins = PyDict_ContainsString(globals, "__builtins__"); + if (has_builtins < 0) { return NULL; } + if (!has_builtins) { + if (PyDict_SetItemString(globals, "__builtins__", + tstate->interp->builtins) < 0) { + return NULL; + } + } } v = PyEval_EvalCode((PyObject*)co, globals, locals); @@ -1730,12 +1264,70 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py static PyObject * run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, - PyCompilerFlags *flags, PyArena *arena) + PyCompilerFlags *flags, PyArena *arena, PyObject* interactive_src) { PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena); - if (co == NULL) + PyObject* interactive_filename = filename; + if (interactive_src) { + PyInterpreterState *interp = tstate->interp; + interactive_filename = PyUnicode_FromFormat( + "", interp->_interactive_src_count++ + ); + if (interactive_filename == NULL) { + return NULL; + } + } + + PyCodeObject *co = _PyAST_Compile(mod, interactive_filename, flags, -1, arena); + if (co == NULL) { + Py_DECREF(interactive_filename); return NULL; + } + + if (interactive_src) { + PyObject *linecache_module = PyImport_ImportModule("linecache"); + + if (linecache_module == NULL) { + Py_DECREF(co); + Py_DECREF(interactive_filename); + return NULL; + } + + PyObject *print_tb_func = PyObject_GetAttrString(linecache_module, "_register_code"); + + if (print_tb_func == NULL) { + Py_DECREF(co); + Py_DECREF(interactive_filename); + Py_DECREF(linecache_module); + return NULL; + } + + if (!PyCallable_Check(print_tb_func)) { + Py_DECREF(co); + Py_DECREF(interactive_filename); + Py_DECREF(linecache_module); + Py_DECREF(print_tb_func); + PyErr_SetString(PyExc_ValueError, "linecache._register_code is not callable"); + return NULL; + } + + PyObject* result = PyObject_CallFunction( + print_tb_func, "OOO", + interactive_filename, + interactive_src, + filename + ); + + Py_DECREF(interactive_filename); + + Py_DECREF(linecache_module); + Py_XDECREF(print_tb_func); + Py_XDECREF(result); + if (!result) { + Py_DECREF(co); + return NULL; + } + } if (_PySys_Audit(tstate, "exec", "O", co) < 0) { Py_DECREF(co); @@ -1806,6 +1398,11 @@ Py_CompileStringObject(const char *str, PyObject *filename, int start, return NULL; } if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { + if ((flags->cf_flags & PyCF_OPTIMIZED_AST) == PyCF_OPTIMIZED_AST) { + if (_PyCompile_AstOptimize(mod, filename, flags, optimize, arena) < 0) { + return NULL; + } + } PyObject *result = PyAST_mod2obj(mod); _PyArena_Free(arena); return result; @@ -2016,7 +1613,3 @@ PyRun_InteractiveLoop(FILE *f, const char *p) { return PyRun_InteractiveLoopFlags(f, p, NULL); } - -#ifdef __cplusplus -} -#endif diff --git a/Python/pytime.c b/Python/pytime.c index 49cd5f4e8ea617..e4813d4a9c2a2a 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -1,5 +1,10 @@ #include "Python.h" #include "pycore_time.h" // _PyTime_t + +#include // gmtime_r() +#ifdef HAVE_SYS_TIME_H +# include // gettimeofday() +#endif #ifdef MS_WINDOWS # include // struct timeval #endif @@ -465,7 +470,7 @@ _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) #ifdef HAVE_CLOCK_GETTIME static int -pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise_exc) +pytime_fromtimespec(_PyTime_t *tp, const struct timespec *ts, int raise_exc) { _PyTime_t t, tv_nsec; @@ -488,7 +493,7 @@ pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise_exc) } int -_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts) +_PyTime_FromTimespec(_PyTime_t *tp, const struct timespec *ts) { return pytime_fromtimespec(tp, ts, 1); } @@ -630,6 +635,16 @@ _PyTime_AsNanosecondsObject(_PyTime_t t) return PyLong_FromLongLong((long long)ns); } +_PyTime_t +_PyTime_FromSecondsDouble(double seconds, _PyTime_round_t round) +{ + _PyTime_t tp; + if(pytime_from_double(&tp, seconds, round, SEC_TO_NS) < 0) { + return -1; + } + return tp; +} + static _PyTime_t pytime_divide_round_up(const _PyTime_t t, const _PyTime_t k) diff --git a/Python/specialize.c b/Python/specialize.c index dcf4be712db20d..49633b103b3815 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1,25 +1,29 @@ #include "Python.h" + +#include "opcode.h" + #include "pycore_code.h" -#include "pycore_dict.h" +#include "pycore_descrobject.h" // _PyMethodWrapper_Type +#include "pycore_dict.h" // DICT_KEYS_UNICODE #include "pycore_function.h" // _PyFunction_GetVersionForCurrentState() -#include "pycore_global_strings.h" // _Py_ID() -#include "pycore_long.h" +#include "pycore_long.h" // _PyLong_IsNonNegativeCompact() #include "pycore_moduleobject.h" #include "pycore_object.h" -#include "pycore_opcode.h" // _PyOpcode_Caches -#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX -#include "pycore_descrobject.h" +#include "pycore_opcode_metadata.h" // _PyOpcode_Caches #include "pycore_pylifecycle.h" // _PyOS_URandomNonblock() +#include "pycore_runtime.h" // _Py_ID() #include // rand() + /* For guidance on adding or extending families of instructions see * ./adaptive.md */ #ifdef Py_STATS -PyStats _py_stats_struct = { 0 }; -PyStats *_py_stats = NULL; +GCStats _py_gc_stats[NUM_GENERATIONS] = { 0 }; +static PyStats _Py_stats_struct = { .gc_stats = _py_gc_stats }; +PyStats *_Py_stats = NULL; #define ADD_STAT_TO_DICT(res, field) \ do { \ @@ -79,7 +83,7 @@ add_stat_dict( int opcode, const char *name) { - SpecializationStats *stats = &_py_stats_struct.opcode_stats[opcode].specialization; + SpecializationStats *stats = &_Py_stats_struct.opcode_stats[opcode].specialization; PyObject *d = stats_to_dict(stats); if (d == NULL) { return -1; @@ -89,7 +93,6 @@ add_stat_dict( return err; } -#ifdef Py_STATS PyObject* _Py_GetSpecializationStats(void) { PyObject *stats = PyDict_New(); @@ -116,12 +119,11 @@ _Py_GetSpecializationStats(void) { } return stats; } -#endif #define PRINT_STAT(i, field) \ if (stats[i].field) { \ - fprintf(out, " opcode[%d]." #field " : %" PRIu64 "\n", i, stats[i].field); \ + fprintf(out, " opcode[%s]." #field " : %" PRIu64 "\n", _PyOpcode_OpName[i], stats[i].field); \ } static void @@ -129,11 +131,11 @@ print_spec_stats(FILE *out, OpcodeStats *stats) { /* Mark some opcodes as specializable for stats, * even though we don't specialize them yet. */ - fprintf(out, "opcode[%d].specializable : 1\n", BINARY_SLICE); - fprintf(out, "opcode[%d].specializable : 1\n", STORE_SLICE); + fprintf(out, "opcode[BINARY_SLICE].specializable : 1\n"); + fprintf(out, "opcode[STORE_SLICE].specializable : 1\n"); for (int i = 0; i < 256; i++) { if (_PyOpcode_Caches[i]) { - fprintf(out, "opcode[%d].specializable : 1\n", i); + fprintf(out, "opcode[%s].specializable : 1\n", _PyOpcode_OpName[i]); } PRINT_STAT(i, specialization.success); PRINT_STAT(i, specialization.failure); @@ -145,14 +147,14 @@ print_spec_stats(FILE *out, OpcodeStats *stats) for (int j = 0; j < SPECIALIZATION_FAILURE_KINDS; j++) { uint64_t val = stats[i].specialization.failure_kinds[j]; if (val) { - fprintf(out, " opcode[%d].specialization.failure_kinds[%d] : %" - PRIu64 "\n", i, j, val); + fprintf(out, " opcode[%s].specialization.failure_kinds[%d] : %" + PRIu64 "\n", _PyOpcode_OpName[i], j, val); } } for (int j = 0; j < 256; j++) { if (stats[i].pair_count[j]) { - fprintf(out, "opcode[%d].pair_count[%d] : %" PRIu64 "\n", - i, j, stats[i].pair_count[j]); + fprintf(out, "opcode[%s].pair_count[%s] : %" PRIu64 "\n", + _PyOpcode_OpName[i], _PyOpcode_OpName[j], stats[i].pair_count[j]); } } } @@ -191,33 +193,135 @@ print_object_stats(FILE *out, ObjectStats *stats) fprintf(out, "Object materialize dict (new key): %" PRIu64 "\n", stats->dict_materialized_new_key); fprintf(out, "Object materialize dict (too big): %" PRIu64 "\n", stats->dict_materialized_too_big); fprintf(out, "Object materialize dict (str subclass): %" PRIu64 "\n", stats->dict_materialized_str_subclass); + fprintf(out, "Object dematerialize dict: %" PRIu64 "\n", stats->dict_dematerialized); fprintf(out, "Object method cache hits: %" PRIu64 "\n", stats->type_cache_hits); fprintf(out, "Object method cache misses: %" PRIu64 "\n", stats->type_cache_misses); fprintf(out, "Object method cache collisions: %" PRIu64 "\n", stats->type_cache_collisions); fprintf(out, "Object method cache dunder hits: %" PRIu64 "\n", stats->type_cache_dunder_hits); fprintf(out, "Object method cache dunder misses: %" PRIu64 "\n", stats->type_cache_dunder_misses); - fprintf(out, "Optimization attempts: %" PRIu64 "\n", stats->optimization_attempts); - fprintf(out, "Optimization traces created: %" PRIu64 "\n", stats->optimization_traces_created); - fprintf(out, "Optimization traces executed: %" PRIu64 "\n", stats->optimization_traces_executed); - fprintf(out, "Optimization uops executed: %" PRIu64 "\n", stats->optimization_uops_executed); } static void -print_stats(FILE *out, PyStats *stats) { +print_gc_stats(FILE *out, GCStats *stats) +{ + for (int i = 0; i < NUM_GENERATIONS; i++) { + fprintf(out, "GC[%d] collections: %" PRIu64 "\n", i, stats[i].collections); + fprintf(out, "GC[%d] object visits: %" PRIu64 "\n", i, stats[i].object_visits); + fprintf(out, "GC[%d] objects collected: %" PRIu64 "\n", i, stats[i].objects_collected); + } +} + +static void +print_histogram(FILE *out, const char *name, uint64_t hist[_Py_UOP_HIST_SIZE]) +{ + for (int i = 0; i < _Py_UOP_HIST_SIZE; i++) { + fprintf(out, "%s[%" PRIu64"]: %" PRIu64 "\n", name, (uint64_t)1 << i, hist[i]); + } +} + +static void +print_optimization_stats(FILE *out, OptimizationStats *stats) +{ + fprintf(out, "Optimization attempts: %" PRIu64 "\n", stats->attempts); + fprintf(out, "Optimization traces created: %" PRIu64 "\n", stats->traces_created); + fprintf(out, "Optimization traces executed: %" PRIu64 "\n", stats->traces_executed); + fprintf(out, "Optimization uops executed: %" PRIu64 "\n", stats->uops_executed); + fprintf(out, "Optimization trace stack overflow: %" PRIu64 "\n", stats->trace_stack_overflow); + fprintf(out, "Optimization trace stack underflow: %" PRIu64 "\n", stats->trace_stack_underflow); + fprintf(out, "Optimization trace too long: %" PRIu64 "\n", stats->trace_too_long); + fprintf(out, "Optimization trace too short: %" PRIu64 "\n", stats->trace_too_short); + fprintf(out, "Optimization inner loop: %" PRIu64 "\n", stats->inner_loop); + fprintf(out, "Optimization recursive call: %" PRIu64 "\n", stats->recursive_call); + + print_histogram(out, "Trace length", stats->trace_length_hist); + print_histogram(out, "Trace run length", stats->trace_run_length_hist); + print_histogram(out, "Optimized trace length", stats->optimized_trace_length_hist); + + const char* const* names; + for (int i = 0; i < 512; i++) { + if (i < 256) { + names = _PyOpcode_OpName; + } else { + names = _PyOpcode_uop_name; + } + if (stats->opcode[i].execution_count) { + fprintf(out, "uops[%s].execution_count : %" PRIu64 "\n", names[i], stats->opcode[i].execution_count); + } + } + + for (int i = 0; i < 256; i++) { + if (stats->unsupported_opcode[i]) { + fprintf( + out, + "unsupported_opcode[%s].count : %" PRIu64 "\n", + _PyOpcode_OpName[i], + stats->unsupported_opcode[i] + ); + } + } +} + +static void +print_stats(FILE *out, PyStats *stats) +{ print_spec_stats(out, stats->opcode_stats); print_call_stats(out, &stats->call_stats); print_object_stats(out, &stats->object_stats); + print_gc_stats(out, stats->gc_stats); + print_optimization_stats(out, &stats->optimization_stats); } void -_Py_StatsClear(void) +_Py_StatsOn(void) { - _py_stats_struct = (PyStats) { 0 }; + _Py_stats = &_Py_stats_struct; } void +_Py_StatsOff(void) +{ + _Py_stats = NULL; +} + +void +_Py_StatsClear(void) +{ + memset(&_py_gc_stats, 0, sizeof(_py_gc_stats)); + memset(&_Py_stats_struct, 0, sizeof(_Py_stats_struct)); + _Py_stats_struct.gc_stats = _py_gc_stats; +} + +static int +mem_is_zero(unsigned char *ptr, size_t size) +{ + for (size_t i=0; i < size; i++) { + if (*ptr != 0) { + return 0; + } + ptr++; + } + return 1; +} + +int _Py_PrintSpecializationStats(int to_file) { + PyStats *stats = &_Py_stats_struct; +#define MEM_IS_ZERO(DATA) mem_is_zero((unsigned char*)DATA, sizeof(*(DATA))) + int is_zero = ( + MEM_IS_ZERO(stats->gc_stats) // is a pointer + && MEM_IS_ZERO(&stats->opcode_stats) + && MEM_IS_ZERO(&stats->call_stats) + && MEM_IS_ZERO(&stats->object_stats) + ); +#undef MEM_IS_ZERO + if (is_zero) { + // gh-108753: -X pystats command line was used, but then _stats_off() + // and _stats_clear() have been called: in this case, avoid printing + // useless "all zeros" statistics. + return 0; + } + FILE *out = stderr; if (to_file) { /* Write to a file instead of stderr. */ @@ -233,8 +337,8 @@ _Py_PrintSpecializationStats(int to_file) char hex_name[41]; _PyOS_URandomNonblock(rand, 20); for (int i = 0; i < 20; i++) { - hex_name[2*i] = "0123456789abcdef"[rand[i]&15]; - hex_name[2*i+1] = "0123456789abcdef"[(rand[i]>>4)&15]; + hex_name[2*i] = Py_hexdigits[rand[i]&15]; + hex_name[2*i+1] = Py_hexdigits[(rand[i]>>4)&15]; } hex_name[40] = '\0'; char buf[64]; @@ -248,26 +352,25 @@ _Py_PrintSpecializationStats(int to_file) else { fprintf(out, "Specialization stats:\n"); } - print_stats(out, &_py_stats_struct); + print_stats(out, stats); if (out != stderr) { fclose(out); } + return 1; } -#ifdef Py_STATS - #define SPECIALIZATION_FAIL(opcode, kind) \ do { \ - if (_py_stats) { \ - _py_stats->opcode_stats[opcode].specialization.failure_kinds[kind]++; \ + if (_Py_stats) { \ + _Py_stats->opcode_stats[opcode].specialization.failure_kinds[kind]++; \ } \ } while (0) -#endif -#endif +#endif // Py_STATS + #ifndef SPECIALIZATION_FAIL -#define SPECIALIZATION_FAIL(opcode, kind) ((void)0) +# define SPECIALIZATION_FAIL(opcode, kind) ((void)0) #endif // Initialize warmup counters and insert superinstructions. This cannot fail. @@ -282,7 +385,23 @@ _PyCode_Quicken(PyCodeObject *code) assert(opcode < MIN_INSTRUMENTED_OPCODE); int caches = _PyOpcode_Caches[opcode]; if (caches) { - instructions[i + 1].cache = adaptive_counter_warmup(); + // The initial value depends on the opcode + int initial_value; + switch (opcode) { + case JUMP_BACKWARD: + initial_value = 0; + break; + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + case POP_JUMP_IF_NONE: + case POP_JUMP_IF_NOT_NONE: + initial_value = 0x5555; // Alternating 0, 1 bits + break; + default: + initial_value = adaptive_counter_warmup(); + break; + } + instructions[i + 1].cache = initial_value; i += caches; } } @@ -347,7 +466,6 @@ _PyCode_Quicken(PyCodeObject *code) #define SPEC_FAIL_SUBSCR_ARRAY_SLICE 10 #define SPEC_FAIL_SUBSCR_LIST_SLICE 11 #define SPEC_FAIL_SUBSCR_TUPLE_SLICE 12 -#define SPEC_FAIL_SUBSCR_STRING_INT 13 #define SPEC_FAIL_SUBSCR_STRING_SLICE 14 #define SPEC_FAIL_SUBSCR_BUFFER_INT 15 #define SPEC_FAIL_SUBSCR_BUFFER_SLICE 16 @@ -402,7 +520,6 @@ _PyCode_Quicken(PyCodeObject *code) #define SPEC_FAIL_CALL_STR 24 #define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 25 #define SPEC_FAIL_CALL_CLASS_MUTABLE 26 -#define SPEC_FAIL_CALL_KWNAMES 27 #define SPEC_FAIL_CALL_METHOD_WRAPPER 28 #define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29 #define SPEC_FAIL_CALL_INIT_NOT_SIMPLE 30 @@ -621,7 +738,7 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto if (desc_cls == &PyMemberDescr_Type) { PyMemberDescrObject *member = (PyMemberDescrObject *)descriptor; struct PyMemberDef *dmem = member->d_member; - if (dmem->type == T_OBJECT_EX) { + if (dmem->type == Py_T_OBJECT_EX) { return OBJECT_SLOT; } return OTHER_SLOT; @@ -670,8 +787,10 @@ specialize_dict_access( return 0; } _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - if (_PyDictOrValues_IsValues(dorv)) { + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); + if (_PyDictOrValues_IsValues(*dorv) || + _PyObject_MakeInstanceAttributesFromDict(owner, dorv)) + { // Virtual dictionary PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; assert(PyUnicode_CheckExact(name)); @@ -689,12 +808,16 @@ specialize_dict_access( instr->op.code = values_op; } else { - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(*dorv); if (dict == NULL || !PyDict_CheckExact(dict)) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT); return 0; } // We found an instance with a __dict__. + if (dict->ma_values) { + SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT); + return 0; + } Py_ssize_t index = _PyDict_LookupIndex(dict, name); if (index != (uint16_t)index) { @@ -778,6 +901,10 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) if (!function_check_args(fget, 1, LOAD_ATTR)) { goto fail; } + if (instr->op.arg & 1) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); + goto fail; + } uint32_t version = function_get_version(fget, LOAD_ATTR); if (version == 0) { goto fail; @@ -803,7 +930,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); goto fail; } - if (dmem->flags & PY_AUDIT_READ) { + if (dmem->flags & Py_AUDIT_READ) { SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_AUDITED_SLOT); goto fail; } @@ -811,7 +938,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE); goto fail; } - assert(dmem->type == T_OBJECT_EX); + assert(dmem->type == Py_T_OBJECT_EX); assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); @@ -844,6 +971,10 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) if (!function_check_args(descr, 2, LOAD_ATTR)) { goto fail; } + if (instr->op.arg & 1) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); + goto fail; + } uint32_t version = function_get_version(descr, LOAD_ATTR); if (version == 0) { goto fail; @@ -939,7 +1070,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_EXPECTED_ERROR); goto fail; } - if (dmem->flags & READONLY) { + if (dmem->flags & Py_READONLY) { SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_READ_ONLY); goto fail; } @@ -947,7 +1078,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OUT_OF_RANGE); goto fail; } - assert(dmem->type == T_OBJECT_EX); + assert(dmem->type == Py_T_OBJECT_EX); assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); @@ -1032,7 +1163,7 @@ load_attr_fail_kind(DescriptorClassification kind) } Py_UNREACHABLE(); } -#endif +#endif // Py_STATS static int specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr, @@ -1077,9 +1208,11 @@ PyObject *descr, DescriptorClassification kind, bool is_method) assert(descr != NULL); assert((is_method && kind == METHOD) || (!is_method && kind == NON_DESCRIPTOR)); if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); PyDictKeysObject *keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys; - if (!_PyDictOrValues_IsValues(dorv)) { + if (!_PyDictOrValues_IsValues(*dorv) && + !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)) + { SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT); return 0; } @@ -1244,16 +1377,7 @@ _Py_Specialize_LoadGlobal( static int binary_subscr_fail_kind(PyTypeObject *container_type, PyObject *sub) { - if (container_type == &PyUnicode_Type) { - if (PyLong_CheckExact(sub)) { - return SPEC_FAIL_SUBSCR_STRING_INT; - } - if (PySlice_Check(sub)) { - return SPEC_FAIL_SUBSCR_STRING_SLICE; - } - return SPEC_FAIL_OTHER; - } - else if (strcmp(container_type->tp_name, "array.array") == 0) { + if (strcmp(container_type->tp_name, "array.array") == 0) { if (PyLong_CheckExact(sub)) { return SPEC_FAIL_SUBSCR_ARRAY_INT; } @@ -1278,7 +1402,7 @@ binary_subscr_fail_kind(PyTypeObject *container_type, PyObject *sub) } return SPEC_FAIL_OTHER; } -#endif +#endif // Py_STATS static int function_kind(PyCodeObject *code) { @@ -1360,6 +1484,19 @@ _Py_Specialize_BinarySubscr( PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_TUPLE_SLICE : SPEC_FAIL_OTHER); goto fail; } + if (container_type == &PyUnicode_Type) { + if (PyLong_CheckExact(sub)) { + if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { + instr->op.code = BINARY_SUBSCR_STR_INT; + goto success; + } + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); + goto fail; + } + SPECIALIZATION_FAIL(BINARY_SUBSCR, + PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_STRING_SLICE : SPEC_FAIL_OTHER); + goto fail; + } if (container_type == &PyDict_Type) { instr->op.code = BINARY_SUBSCR_DICT; goto success; @@ -1504,7 +1641,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } goto fail; } -#endif +#endif // Py_STATS SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OTHER); fail: STAT_INC(STORE_SUBSCR, failure); @@ -1553,24 +1690,23 @@ get_init_for_simple_managed_python_class(PyTypeObject *tp) } static int -specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames) +specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs) { assert(PyType_Check(callable)); PyTypeObject *tp = _PyType_CAST(callable); if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { int oparg = instr->op.arg; - if (nargs == 1 && kwnames == NULL && oparg == 1) { + if (nargs == 1 && oparg == 1) { if (tp == &PyUnicode_Type) { - instr->op.code = CALL_NO_KW_STR_1; + instr->op.code = CALL_STR_1; return 0; } else if (tp == &PyType_Type) { - instr->op.code = CALL_NO_KW_TYPE_1; + instr->op.code = CALL_TYPE_1; return 0; } else if (tp == &PyTuple_Type) { - instr->op.code = CALL_NO_KW_TUPLE_1; + instr->op.code = CALL_TUPLE_1; return 0; } } @@ -1589,13 +1725,9 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } - if (kwnames) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); - return -1; - } _PyCallCache *cache = (_PyCallCache *)(instr + 1); write_u32(cache->func_version, tp->tp_version_tag); - _Py_SET_OPCODE(*instr, CALL_NO_KW_ALLOC_AND_ENTER_INIT); + _Py_SET_OPCODE(*instr, CALL_ALLOC_AND_ENTER_INIT); return 0; } return -1; @@ -1649,17 +1781,12 @@ meth_descr_call_fail_kind(int ml_flags) return SPEC_FAIL_CALL_BAD_CALL_FLAGS; } } -#endif +#endif // Py_STATS static int specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames) + int nargs) { - if (kwnames) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); - return -1; - } - switch (descr->d_method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { @@ -1668,7 +1795,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } - instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS; + instr->op.code = CALL_METHOD_DESCRIPTOR_NOARGS; return 0; } case METH_O: { @@ -1682,14 +1809,14 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, bool pop = (next.op.code == POP_TOP); int oparg = instr->op.arg; if ((PyObject *)descr == list_append && oparg == 1 && pop) { - instr->op.code = CALL_NO_KW_LIST_APPEND; + instr->op.code = CALL_LIST_APPEND; return 0; } - instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_O; + instr->op.code = CALL_METHOD_DESCRIPTOR_O; return 0; } case METH_FASTCALL: { - instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_FAST; + instr->op.code = CALL_METHOD_DESCRIPTOR_FAST; return 0; } case METH_FASTCALL | METH_KEYWORDS: { @@ -1703,7 +1830,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, static int specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames, bool bound_method) + bool bound_method) { _PyCallCache *cache = (_PyCallCache *)(instr + 1); PyCodeObject *code = (PyCodeObject *)func->func_code; @@ -1713,10 +1840,6 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523); return -1; } - if (kwnames) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); - return -1; - } if (kind != SIMPLE_FUNCTION) { SPECIALIZATION_FAIL(CALL, kind); return -1; @@ -1752,8 +1875,7 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, } static int -specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames) +specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs) { if (PyCFunction_GET_FUNCTION(callable) == NULL) { return 1; @@ -1762,10 +1884,6 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { case METH_O: { - if (kwnames) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); - return -1; - } if (nargs != 1) { SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return 1; @@ -1773,26 +1891,22 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, /* len(o) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.len) { - instr->op.code = CALL_NO_KW_LEN; + instr->op.code = CALL_LEN; return 0; } - instr->op.code = CALL_NO_KW_BUILTIN_O; + instr->op.code = CALL_BUILTIN_O; return 0; } case METH_FASTCALL: { - if (kwnames) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); - return -1; - } if (nargs == 2) { /* isinstance(o1, o2) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.isinstance) { - instr->op.code = CALL_NO_KW_ISINSTANCE; + instr->op.code = CALL_ISINSTANCE; return 0; } } - instr->op.code = CALL_NO_KW_BUILTIN_FAST; + instr->op.code = CALL_BUILTIN_FAST; return 0; } case METH_FASTCALL | METH_KEYWORDS: { @@ -1830,15 +1944,11 @@ call_fail_kind(PyObject *callable) } return SPEC_FAIL_OTHER; } -#endif +#endif // Py_STATS -/* TODO: - - Specialize calling classes. -*/ void -_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames) +_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs) { assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL); @@ -1846,25 +1956,23 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, _PyCallCache *cache = (_PyCallCache *)(instr + 1); int fail; if (PyCFunction_CheckExact(callable)) { - fail = specialize_c_call(callable, instr, nargs, kwnames); + fail = specialize_c_call(callable, instr, nargs); } else if (PyFunction_Check(callable)) { - fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, - kwnames, false); + fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, false); } else if (PyType_Check(callable)) { - fail = specialize_class_call(callable, instr, nargs, kwnames); + fail = specialize_class_call(callable, instr, nargs); } else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { - fail = specialize_method_descriptor((PyMethodDescrObject *)callable, - instr, nargs, kwnames); + fail = specialize_method_descriptor((PyMethodDescrObject *)callable, instr, nargs); } else if (PyMethod_Check(callable)) { PyObject *func = ((PyMethodObject *)callable)->im_func; if (PyFunction_Check(func)) { - fail = specialize_py_call((PyFunctionObject *)func, - instr, nargs+1, kwnames, true); - } else { + fail = specialize_py_call((PyFunctionObject *)func, instr, nargs+1, true); + } + else { SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD); fail = -1; } @@ -1954,7 +2062,7 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs) } Py_UNREACHABLE(); } -#endif +#endif // Py_STATS void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, @@ -2061,7 +2169,7 @@ compare_op_fail_kind(PyObject *lhs, PyObject *rhs) } return SPEC_FAIL_OTHER; } -#endif +#endif // Py_STATS void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, @@ -2124,7 +2232,7 @@ unpack_sequence_fail_kind(PyObject *seq) } return SPEC_FAIL_OTHER; } -#endif +#endif // Py_STATS void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) @@ -2165,7 +2273,6 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) } #ifdef Py_STATS - int _PySpecialization_ClassifyIterator(PyObject *iter) { @@ -2236,8 +2343,7 @@ int } return SPEC_FAIL_OTHER; } - -#endif +#endif // Py_STATS void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg) @@ -2390,7 +2496,7 @@ _Py_Specialize_ToBool(PyObject *value, _Py_CODEUNIT *instr) goto failure; } SPECIALIZATION_FAIL(TO_BOOL, SPEC_FAIL_OTHER); -#endif +#endif // Py_STATS failure: STAT_INC(TO_BOOL, failure); instr->op.code = TO_BOOL; @@ -2402,7 +2508,7 @@ _Py_Specialize_ToBool(PyObject *value, _Py_CODEUNIT *instr) } /* Code init cleanup. - * CALL_NO_KW_ALLOC_AND_ENTER_INIT will set up + * CALL_ALLOC_AND_ENTER_INIT will set up * the frame to execute the EXIT_INIT_CHECK * instruction. * Ends with a RESUME so that it is not traced. diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index 13b1764f0886d1..701bfc35cc8182 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -77,6 +77,7 @@ static const char* _Py_stdlib_module_names[] = { "_strptime", "_struct", "_symtable", +"_sysconfig", "_thread", "_threading_local", "_tkinter", diff --git a/Python/structmember.c b/Python/structmember.c index 19a75224a0f32e..7a5a6a49d23116 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -2,7 +2,7 @@ /* Map C struct members to Python object attributes */ #include "Python.h" -#include "structmember.h" // PyMemberDef + PyObject * PyMember_GetOne(const char *obj_addr, PyMemberDef *l) @@ -17,62 +17,62 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) const char* addr = obj_addr + l->offset; switch (l->type) { - case T_BOOL: + case Py_T_BOOL: v = PyBool_FromLong(*(char*)addr); break; - case T_BYTE: + case Py_T_BYTE: v = PyLong_FromLong(*(char*)addr); break; - case T_UBYTE: + case Py_T_UBYTE: v = PyLong_FromUnsignedLong(*(unsigned char*)addr); break; - case T_SHORT: + case Py_T_SHORT: v = PyLong_FromLong(*(short*)addr); break; - case T_USHORT: + case Py_T_USHORT: v = PyLong_FromUnsignedLong(*(unsigned short*)addr); break; - case T_INT: + case Py_T_INT: v = PyLong_FromLong(*(int*)addr); break; - case T_UINT: + case Py_T_UINT: v = PyLong_FromUnsignedLong(*(unsigned int*)addr); break; - case T_LONG: + case Py_T_LONG: v = PyLong_FromLong(*(long*)addr); break; - case T_ULONG: + case Py_T_ULONG: v = PyLong_FromUnsignedLong(*(unsigned long*)addr); break; - case T_PYSSIZET: + case Py_T_PYSSIZET: v = PyLong_FromSsize_t(*(Py_ssize_t*)addr); break; - case T_FLOAT: + case Py_T_FLOAT: v = PyFloat_FromDouble((double)*(float*)addr); break; - case T_DOUBLE: + case Py_T_DOUBLE: v = PyFloat_FromDouble(*(double*)addr); break; - case T_STRING: + case Py_T_STRING: if (*(char**)addr == NULL) { v = Py_NewRef(Py_None); } else v = PyUnicode_FromString(*(char**)addr); break; - case T_STRING_INPLACE: + case Py_T_STRING_INPLACE: v = PyUnicode_FromString((char*)addr); break; - case T_CHAR: + case Py_T_CHAR: v = PyUnicode_FromStringAndSize((char*)addr, 1); break; - case T_OBJECT: + case _Py_T_OBJECT: v = *(PyObject **)addr; if (v == NULL) v = Py_None; Py_INCREF(v); break; - case T_OBJECT_EX: + case Py_T_OBJECT_EX: v = *(PyObject **)addr; if (v == NULL) { PyObject *obj = (PyObject *)obj_addr; @@ -83,13 +83,13 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) } Py_XINCREF(v); break; - case T_LONGLONG: + case Py_T_LONGLONG: v = PyLong_FromLongLong(*(long long *)addr); break; - case T_ULONGLONG: + case Py_T_ULONGLONG: v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr); break; - case T_NONE: + case _Py_T_NONE: v = Py_NewRef(Py_None); break; default: @@ -118,27 +118,27 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) addr += l->offset; - if ((l->flags & READONLY)) + if ((l->flags & Py_READONLY)) { PyErr_SetString(PyExc_AttributeError, "readonly attribute"); return -1; } if (v == NULL) { - if (l->type == T_OBJECT_EX) { + if (l->type == Py_T_OBJECT_EX) { /* Check if the attribute is set. */ if (*(PyObject **)addr == NULL) { PyErr_SetString(PyExc_AttributeError, l->name); return -1; } } - else if (l->type != T_OBJECT) { + else if (l->type != _Py_T_OBJECT) { PyErr_SetString(PyExc_TypeError, "can't delete numeric/char attribute"); return -1; } } switch (l->type) { - case T_BOOL:{ + case Py_T_BOOL:{ if (!PyBool_Check(v)) { PyErr_SetString(PyExc_TypeError, "attribute value type must be bool"); @@ -150,7 +150,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) *(char*)addr = (char) 0; break; } - case T_BYTE:{ + case Py_T_BYTE:{ long long_val = PyLong_AsLong(v); if ((long_val == -1) && PyErr_Occurred()) return -1; @@ -161,7 +161,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) WARN("Truncation of value to char"); break; } - case T_UBYTE:{ + case Py_T_UBYTE:{ long long_val = PyLong_AsLong(v); if ((long_val == -1) && PyErr_Occurred()) return -1; @@ -170,7 +170,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) WARN("Truncation of value to unsigned char"); break; } - case T_SHORT:{ + case Py_T_SHORT:{ long long_val = PyLong_AsLong(v); if ((long_val == -1) && PyErr_Occurred()) return -1; @@ -179,7 +179,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) WARN("Truncation of value to short"); break; } - case T_USHORT:{ + case Py_T_USHORT:{ long long_val = PyLong_AsLong(v); if ((long_val == -1) && PyErr_Occurred()) return -1; @@ -188,7 +188,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) WARN("Truncation of value to unsigned short"); break; } - case T_INT:{ + case Py_T_INT:{ long long_val = PyLong_AsLong(v); if ((long_val == -1) && PyErr_Occurred()) return -1; @@ -197,7 +197,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) WARN("Truncation of value to int"); break; } - case T_UINT:{ + case Py_T_UINT:{ unsigned long ulong_val = PyLong_AsUnsignedLong(v); if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) { /* XXX: For compatibility, accept negative int values @@ -215,13 +215,13 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) WARN("Truncation of value to unsigned int"); break; } - case T_LONG:{ + case Py_T_LONG:{ *(long*)addr = PyLong_AsLong(v); if ((*(long*)addr == -1) && PyErr_Occurred()) return -1; break; } - case T_ULONG:{ + case Py_T_ULONG:{ *(unsigned long*)addr = PyLong_AsUnsignedLong(v); if ((*(unsigned long*)addr == (unsigned long)-1) && PyErr_Occurred()) { @@ -236,32 +236,32 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) } break; } - case T_PYSSIZET:{ + case Py_T_PYSSIZET:{ *(Py_ssize_t*)addr = PyLong_AsSsize_t(v); if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) && PyErr_Occurred()) return -1; break; } - case T_FLOAT:{ + case Py_T_FLOAT:{ double double_val = PyFloat_AsDouble(v); if ((double_val == -1) && PyErr_Occurred()) return -1; *(float*)addr = (float)double_val; break; } - case T_DOUBLE: + case Py_T_DOUBLE: *(double*)addr = PyFloat_AsDouble(v); if ((*(double*)addr == -1) && PyErr_Occurred()) return -1; break; - case T_OBJECT: - case T_OBJECT_EX: + case _Py_T_OBJECT: + case Py_T_OBJECT_EX: oldv = *(PyObject **)addr; *(PyObject **)addr = Py_XNewRef(v); Py_XDECREF(oldv); break; - case T_CHAR: { + case Py_T_CHAR: { const char *string; Py_ssize_t len; @@ -273,18 +273,18 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) *(char*)addr = string[0]; break; } - case T_STRING: - case T_STRING_INPLACE: + case Py_T_STRING: + case Py_T_STRING_INPLACE: PyErr_SetString(PyExc_TypeError, "readonly attribute"); return -1; - case T_LONGLONG:{ + case Py_T_LONGLONG:{ long long value; *(long long*)addr = value = PyLong_AsLongLong(v); if ((value == -1) && PyErr_Occurred()) return -1; break; } - case T_ULONGLONG:{ + case Py_T_ULONGLONG:{ unsigned long long value; /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong doesn't ??? */ diff --git a/Python/suggestions.c b/Python/suggestions.c index 47aeb08180f6b1..1ad359b18923f3 100644 --- a/Python/suggestions.c +++ b/Python/suggestions.c @@ -1,10 +1,9 @@ #include "Python.h" +#include "pycore_code.h" // _PyCode_GetVarnames() #include "pycore_frame.h" -#include "pycore_runtime.h" // _PyRuntime -#include "pycore_global_objects.h" // _Py_ID() +#include "pycore_pyerrors.h" // export _Py_UTF8_Edit_Cost() +#include "pycore_runtime.h" // _Py_ID() -#include "pycore_pyerrors.h" -#include "pycore_code.h" // _PyCode_GetVarnames() #include "stdlib_module_names.h" // _Py_stdlib_module_names #define MAX_CANDIDATE_ITEMS 750 @@ -126,8 +125,8 @@ levenshtein_distance(const char *a, size_t a_size, return result; } -static inline PyObject * -calculate_suggestions(PyObject *dir, +PyObject * +_Py_CalculateSuggestions(PyObject *dir, PyObject *name) { assert(!PyErr_Occurred()); @@ -195,7 +194,7 @@ get_suggestions_for_attribute_error(PyAttributeErrorObject *exc) return NULL; } - PyObject *suggestions = calculate_suggestions(dir, name); + PyObject *suggestions = _Py_CalculateSuggestions(dir, name); Py_DECREF(dir); return suggestions; } @@ -246,20 +245,18 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame) goto error; } - PyObject *value; - res = PyObject_GetOptionalAttr(self, name, &value); + res = PyObject_HasAttrWithError(self, name); Py_DECREF(locals); if (res < 0) { goto error; } - if (value) { - Py_DECREF(value); + if (res) { Py_DECREF(dir); return PyUnicode_FromFormat("self.%U", name); } } - PyObject *suggestions = calculate_suggestions(dir, name); + PyObject *suggestions = _Py_CalculateSuggestions(dir, name); Py_DECREF(dir); if (suggestions != NULL || PyErr_Occurred()) { return suggestions; @@ -269,7 +266,7 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame) if (dir == NULL) { return NULL; } - suggestions = calculate_suggestions(dir, name); + suggestions = _Py_CalculateSuggestions(dir, name); Py_DECREF(dir); if (suggestions != NULL || PyErr_Occurred()) { return suggestions; @@ -279,7 +276,7 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame) if (dir == NULL) { return NULL; } - suggestions = calculate_suggestions(dir, name); + suggestions = _Py_CalculateSuggestions(dir, name); Py_DECREF(dir); return suggestions; @@ -371,7 +368,7 @@ offer_suggestions_for_import_error(PyImportErrorObject *exc) return NULL; } - PyObject *suggestion = calculate_suggestions(dir, name); + PyObject *suggestion = _Py_CalculateSuggestions(dir, name); Py_DECREF(dir); if (!suggestion) { return NULL; diff --git a/Python/symtable.c b/Python/symtable.c index e2c00d17480dd1..75ea9e902f4381 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1,9 +1,11 @@ #include "Python.h" -#include "pycore_ast.h" // identifier, stmt_ty +#include "pycore_ast.h" // stmt_ty #include "pycore_parser.h" // _PyParser_ASTFromString() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntryObject -#include "structmember.h" // PyMemberDef + +// Set this to 1 to dump all symtables to stdout for debugging +#define _PY_DUMP_SYMTABLE 0 /* error strings used for warnings */ #define GLOBAL_PARAM \ @@ -150,9 +152,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, static PyObject * ste_repr(PySTEntryObject *ste) { - return PyUnicode_FromFormat("", - ste->ste_name, - PyLong_AS_LONG(ste->ste_id), ste->ste_lineno); + return PyUnicode_FromFormat("", + ste->ste_name, ste->ste_id, ste->ste_lineno); } static void @@ -171,14 +172,14 @@ ste_dealloc(PySTEntryObject *ste) #define OFF(x) offsetof(PySTEntryObject, x) static PyMemberDef ste_memberlist[] = { - {"id", T_OBJECT, OFF(ste_id), READONLY}, - {"name", T_OBJECT, OFF(ste_name), READONLY}, - {"symbols", T_OBJECT, OFF(ste_symbols), READONLY}, - {"varnames", T_OBJECT, OFF(ste_varnames), READONLY}, - {"children", T_OBJECT, OFF(ste_children), READONLY}, - {"nested", T_INT, OFF(ste_nested), READONLY}, - {"type", T_INT, OFF(ste_type), READONLY}, - {"lineno", T_INT, OFF(ste_lineno), READONLY}, + {"id", _Py_T_OBJECT, OFF(ste_id), Py_READONLY}, + {"name", _Py_T_OBJECT, OFF(ste_name), Py_READONLY}, + {"symbols", _Py_T_OBJECT, OFF(ste_symbols), Py_READONLY}, + {"varnames", _Py_T_OBJECT, OFF(ste_varnames), Py_READONLY}, + {"children", _Py_T_OBJECT, OFF(ste_children), Py_READONLY}, + {"nested", Py_T_INT, OFF(ste_nested), Py_READONLY}, + {"type", Py_T_INT, OFF(ste_type), Py_READONLY}, + {"lineno", Py_T_INT, OFF(ste_lineno), Py_READONLY}, {NULL} }; @@ -252,6 +253,109 @@ static int symtable_visit_pattern(struct symtable *st, pattern_ty s); static int symtable_raise_if_annotation_block(struct symtable *st, const char *, expr_ty); static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty); +/* For debugging purposes only */ +#if _PY_DUMP_SYMTABLE +static void _dump_symtable(PySTEntryObject* ste, PyObject* prefix) +{ + const char *blocktype = ""; + switch (ste->ste_type) { + case FunctionBlock: blocktype = "FunctionBlock"; break; + case ClassBlock: blocktype = "ClassBlock"; break; + case ModuleBlock: blocktype = "ModuleBlock"; break; + case AnnotationBlock: blocktype = "AnnotationBlock"; break; + case TypeVarBoundBlock: blocktype = "TypeVarBoundBlock"; break; + case TypeAliasBlock: blocktype = "TypeAliasBlock"; break; + case TypeParamBlock: blocktype = "TypeParamBlock"; break; + } + const char *comptype = ""; + switch (ste->ste_comprehension) { + case ListComprehension: comptype = " ListComprehension"; break; + case DictComprehension: comptype = " DictComprehension"; break; + case SetComprehension: comptype = " SetComprehension"; break; + case GeneratorExpression: comptype = " GeneratorExpression"; break; + case NoComprehension: break; + } + PyObject* msg = PyUnicode_FromFormat( + ( + "%U=== Symtable for %U ===\n" + "%U%s%s\n" + "%U%s%s%s%s%s%s%s%s%s%s%s%s%s\n" + "%Ulineno: %d col_offset: %d\n" + "%U--- Symbols ---\n" + ), + prefix, + ste->ste_name, + prefix, + blocktype, + comptype, + prefix, + ste->ste_nested ? " nested" : "", + ste->ste_free ? " free" : "", + ste->ste_child_free ? " child_free" : "", + ste->ste_generator ? " generator" : "", + ste->ste_coroutine ? " coroutine" : "", + ste->ste_varargs ? " varargs" : "", + ste->ste_varkeywords ? " varkeywords" : "", + ste->ste_returns_value ? " returns_value" : "", + ste->ste_needs_class_closure ? " needs_class_closure" : "", + ste->ste_needs_classdict ? " needs_classdict" : "", + ste->ste_comp_inlined ? " comp_inlined" : "", + ste->ste_comp_iter_target ? " comp_iter_target" : "", + ste->ste_can_see_class_scope ? " can_see_class_scope" : "", + prefix, + ste->ste_lineno, + ste->ste_col_offset, + prefix + ); + assert(msg != NULL); + printf("%s", PyUnicode_AsUTF8(msg)); + Py_DECREF(msg); + PyObject *name, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(ste->ste_symbols, &pos, &name, &value)) { + int scope = _PyST_GetScope(ste, name); + long flags = _PyST_GetSymbol(ste, name); + printf("%s %s: ", PyUnicode_AsUTF8(prefix), PyUnicode_AsUTF8(name)); + if (flags & DEF_GLOBAL) printf(" DEF_GLOBAL"); + if (flags & DEF_LOCAL) printf(" DEF_LOCAL"); + if (flags & DEF_PARAM) printf(" DEF_PARAM"); + if (flags & DEF_NONLOCAL) printf(" DEF_NONLOCAL"); + if (flags & USE) printf(" USE"); + if (flags & DEF_FREE) printf(" DEF_FREE"); + if (flags & DEF_FREE_CLASS) printf(" DEF_FREE_CLASS"); + if (flags & DEF_IMPORT) printf(" DEF_IMPORT"); + if (flags & DEF_ANNOT) printf(" DEF_ANNOT"); + if (flags & DEF_COMP_ITER) printf(" DEF_COMP_ITER"); + if (flags & DEF_TYPE_PARAM) printf(" DEF_TYPE_PARAM"); + if (flags & DEF_COMP_CELL) printf(" DEF_COMP_CELL"); + switch (scope) { + case LOCAL: printf(" LOCAL"); break; + case GLOBAL_EXPLICIT: printf(" GLOBAL_EXPLICIT"); break; + case GLOBAL_IMPLICIT: printf(" GLOBAL_IMPLICIT"); break; + case FREE: printf(" FREE"); break; + case CELL: printf(" CELL"); break; + } + printf("\n"); + } + printf("%s--- Children ---\n", PyUnicode_AsUTF8(prefix)); + PyObject *new_prefix = PyUnicode_FromFormat(" %U", prefix); + assert(new_prefix != NULL); + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(ste->ste_children); i++) { + PyObject *child = PyList_GetItem(ste->ste_children, i); + assert(child != NULL && PySTEntry_Check(child)); + _dump_symtable((PySTEntryObject *)child, new_prefix); + } + Py_DECREF(new_prefix); +} + +static void dump_symtable(PySTEntryObject* ste) +{ + PyObject *empty = PyUnicode_FromString(""); + assert(empty != NULL); + _dump_symtable(ste, empty); + Py_DECREF(empty); +} +#endif #define DUPLICATE_ARGUMENT \ "duplicate argument '%U' in function definition" @@ -282,17 +386,10 @@ symtable_new(void) return NULL; } -/* When compiling the use of C stack is probably going to be a lot - lighter than when executing Python code but still can overflow - and causing a Python crash if not checked (e.g. eval("()"*300000)). - Using the current recursion limit for the compiler seems too - restrictive (it caused at least one test to fail) so a factor is - used to allow deeper recursion when compiling an expression. - - Using a scaling factor means this should automatically adjust when +/* Using a scaling factor means this should automatically adjust when the recursion limit is adjusted for small or large C stack allocations. */ -#define COMPILER_STACK_FRAME_SCALE 3 +#define COMPILER_STACK_FRAME_SCALE 2 struct symtable * _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) @@ -319,10 +416,10 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) return NULL; } /* Be careful here to prevent overflow. */ - int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; st->recursion_depth = starting_recursion_depth; - st->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + st->recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; /* Make the initial symbol information gathering pass */ if (!symtable_enter_block(st, &_Py_ID(top), ModuleBlock, (void *)mod, 0, 0, 0, 0)) { @@ -368,8 +465,12 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) return NULL; } /* Make the second symbol analysis pass */ - if (symtable_analyze(st)) + if (symtable_analyze(st)) { +#if _PY_DUMP_SYMTABLE + dump_symtable(st->st_top); +#endif return st; + } _PySymtable_Free(st); return NULL; error: @@ -389,7 +490,7 @@ _PySymtable_Free(struct symtable *st) } PySTEntryObject * -PySymtable_Lookup(struct symtable *st, void *key) +_PySymtable_Lookup(struct symtable *st, void *key) { PyObject *k, *v; @@ -530,6 +631,7 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, PyObject *bound, PyObject *local, PyObject *free, PyObject *global, PyObject *type_params, PySTEntryObject *class_entry) { + int contains; if (flags & DEF_GLOBAL) { if (flags & DEF_NONLOCAL) { PyErr_Format(PyExc_SyntaxError, @@ -550,14 +652,22 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, "nonlocal declaration not allowed at module level"); return error_at_directive(ste, name); } - if (!PySet_Contains(bound, name)) { + contains = PySet_Contains(bound, name); + if (contains < 0) { + return 0; + } + if (!contains) { PyErr_Format(PyExc_SyntaxError, "no binding for nonlocal '%U' found", name); return error_at_directive(ste, name); } - if (PySet_Contains(type_params, name)) { + contains = PySet_Contains(type_params, name); + if (contains < 0) { + return 0; + } + if (contains) { PyErr_Format(PyExc_SyntaxError, "nonlocal binding not allowed for type parameter '%U'", name); @@ -606,17 +716,29 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, Note that having a non-NULL bound implies that the block is nested. */ - if (bound && PySet_Contains(bound, name)) { - SET_SCOPE(scopes, name, FREE); - ste->ste_free = 1; - return PySet_Add(free, name) >= 0; + if (bound) { + contains = PySet_Contains(bound, name); + if (contains < 0) { + return 0; + } + if (contains) { + SET_SCOPE(scopes, name, FREE); + ste->ste_free = 1; + return PySet_Add(free, name) >= 0; + } } /* If a parent has a global statement, then call it global explicit? It could also be global implicit. */ - if (global && PySet_Contains(global, name)) { - SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); - return 1; + if (global) { + contains = PySet_Contains(global, name); + if (contains < 0) { + return 0; + } + if (contains) { + SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); + return 1; + } } if (ste->ste_nested) ste->ste_free = 1; @@ -719,8 +841,19 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells) scope = PyLong_AS_LONG(v); if (scope != LOCAL) continue; - if (!PySet_Contains(free, name) && !PySet_Contains(inlined_cells, name)) - continue; + int contains = PySet_Contains(free, name); + if (contains < 0) { + goto error; + } + if (!contains) { + contains = PySet_Contains(inlined_cells, name); + if (contains < 0) { + goto error; + } + if (!contains) { + continue; + } + } /* Replace LOCAL with CELL for this name, and remove from free. It is safe to replace the value of name in the dict, because it will not cause a resize. @@ -771,7 +904,11 @@ update_symbols(PyObject *symbols, PyObject *scopes, long scope, flags; assert(PyLong_Check(v)); flags = PyLong_AS_LONG(v); - if (PySet_Contains(inlined_cells, name)) { + int contains = PySet_Contains(inlined_cells, name); + if (contains < 0) { + return 0; + } + if (contains) { flags |= DEF_COMP_CELL; } v_scope = PyDict_GetItemWithError(scopes, name); @@ -808,8 +945,7 @@ update_symbols(PyObject *symbols, PyObject *scopes, the class that has the same name as a local or global in the class scope. */ - if (classflag && - PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) { + if (classflag) { long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS; v_new = PyLong_FromLong(flags); if (!v_new) { @@ -829,9 +965,15 @@ update_symbols(PyObject *symbols, PyObject *scopes, goto error; } /* Handle global symbol */ - if (bound && !PySet_Contains(bound, name)) { - Py_DECREF(name); - continue; /* it's a global */ + if (bound) { + int contains = PySet_Contains(bound, name); + if (contains < 0) { + goto error; + } + if (!contains) { + Py_DECREF(name); + continue; /* it's a global */ + } } /* Propagate new free symbol up the lexical stack */ if (PyDict_SetItem(symbols, name, v_free) < 0) { @@ -1044,7 +1186,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, goto error; /* Records the results of the analysis in the symbol table entry */ if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, inlined_cells, - ste->ste_type == ClassBlock)) + (ste->ste_type == ClassBlock) || ste->ste_can_see_class_scope)) goto error; temp = PyNumber_InPlaceOr(free, newfree); @@ -1976,6 +2118,17 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT(st, expr, e->v.UnaryOp.operand); break; case Lambda_kind: { + if (st->st_cur->ste_can_see_class_scope) { + // gh-109118 + PyErr_Format(PyExc_SyntaxError, + "Cannot use lambda in annotation scope within class scope"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); + VISIT_QUIT(st, 0); + } if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); if (e->v.Lambda.args->kw_defaults) @@ -2425,6 +2578,18 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, identifier scope_name, asdl_comprehension_seq *generators, expr_ty elt, expr_ty value) { + if (st->st_cur->ste_can_see_class_scope) { + // gh-109118 + PyErr_Format(PyExc_SyntaxError, + "Cannot use comprehension in annotation scope within class scope"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); + VISIT_QUIT(st, 0); + } + int is_generator = (e->kind == GeneratorExp_kind); comprehension_ty outermost = ((comprehension_ty) asdl_seq_GET(generators, 0)); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index fea3f61ee01762..3debe7f7c139c6 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -17,30 +17,36 @@ Data members: #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer() +#include "pycore_dict.h" // _PyDict_GetItemWithError() #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() #include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD #include "pycore_modsupport.h" // _PyModule_CreateInitialized() #include "pycore_namespace.h" // _PyNamespace_New() -#include "pycore_object.h" // _PyObject_IS_GC() +#include "pycore_object.h" // _PyObject_DebugTypeStats() #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_pystats.h" // _Py_PrintSpecializationStats() #include "pycore_structseq.h" // _PyStructSequence_InitBuiltinWithFlags() +#include "pycore_sysmodule.h" // export _PySys_GetSizeOf() #include "pycore_tuple.h" // _PyTuple_FromArray() #include "frameobject.h" // PyFrame_FastToLocalsWithError() -#include "pydtrace.h" +#include "pydtrace.h" // PyDTrace_AUDIT() #include "osdefs.h" // DELIM #include "stdlib_module_names.h" // _Py_stdlib_module_names -#include + +#ifdef HAVE_UNISTD_H +# include // getpid() +#endif #ifdef MS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include +# define WIN32_LEAN_AND_MEAN +# include #endif /* MS_WINDOWS */ #ifdef MS_COREDLL @@ -50,11 +56,11 @@ extern const char *PyWin_DLLVersionString; #endif #ifdef __EMSCRIPTEN__ -#include +# include #endif #ifdef HAVE_FCNTL_H -#include +# include #endif /*[clinic input] @@ -64,6 +70,7 @@ module sys #include "clinic/sysmodule.c.h" + PyObject * _PySys_GetAttr(PyThreadState *tstate, PyObject *name) { @@ -86,7 +93,12 @@ _PySys_GetObject(PyInterpreterState *interp, const char *name) if (sysdict == NULL) { return NULL; } - return _PyDict_GetItemStringWithError(sysdict, name); + PyObject *value; + if (PyDict_GetItemStringRef(sysdict, name, &value) != 1) { + return NULL; + } + Py_DECREF(value); // return a borrowed reference + return value; } PyObject * @@ -179,9 +191,7 @@ static int sys_audit_tstate(PyThreadState *ts, const char *event, const char *argFormat, va_list vargs) { - /* N format is inappropriate, because you do not know - whether the reference is consumed by the call. - Assert rather than exception for perf reasons */ + assert(event != NULL); assert(!argFormat || !strchr(argFormat, 'N')); if (!ts) { @@ -326,6 +336,21 @@ PySys_Audit(const char *event, const char *argFormat, ...) return res; } +int +PySys_AuditTuple(const char *event, PyObject *args) +{ + if (args == NULL) { + return PySys_Audit(event, NULL); + } + + if (!PyTuple_Check(args)) { + PyErr_Format(PyExc_TypeError, "args must be tuple, got %s", + Py_TYPE(args)->tp_name); + return -1; + } + return PySys_Audit(event, "O", args); +} + /* We expose this function primarily for our own cleanup during * finalization. In general, it should not need to be called, * and as such the function is not exported. @@ -497,6 +522,9 @@ sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc) return NULL; } + assert(args[0] != NULL); + assert(PyUnicode_Check(args[0])); + if (!should_audit(tstate->interp)) { Py_RETURN_NONE; } @@ -1953,7 +1981,7 @@ sys__getframe_impl(PyObject *module, int depth) /*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/ { PyThreadState *tstate = _PyThreadState_GET(); - _PyInterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = tstate->current_frame; if (frame != NULL) { while (depth > 0) { @@ -2029,11 +2057,6 @@ sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs) return _PyEval_CallTracing(func, funcargs); } - -#ifdef __cplusplus -extern "C" { -#endif - /*[clinic input] sys._debugmallocstats @@ -2062,10 +2085,6 @@ sys__debugmallocstats_impl(PyObject *module) extern PyObject *_Py_GetObjects(PyObject *, PyObject *); #endif -#ifdef __cplusplus -} -#endif - /*[clinic input] sys._clear_type_cache @@ -2094,35 +2113,36 @@ static PyObject * sys_is_finalizing_impl(PyObject *module) /*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/ { - return PyBool_FromLong(_Py_IsFinalizing()); + return PyBool_FromLong(Py_IsFinalizing()); } + #ifdef Py_STATS /*[clinic input] sys._stats_on -Turns on stats gathering (stats gathering is on by default). +Turns on stats gathering (stats gathering is off by default). [clinic start generated code]*/ static PyObject * sys__stats_on_impl(PyObject *module) -/*[clinic end generated code: output=aca53eafcbb4d9fe input=8ddc6df94e484f3a]*/ +/*[clinic end generated code: output=aca53eafcbb4d9fe input=43b5bfe145299e55]*/ { - _py_stats = &_py_stats_struct; + _Py_StatsOn(); Py_RETURN_NONE; } /*[clinic input] sys._stats_off -Turns off stats gathering (stats gathering is on by default). +Turns off stats gathering (stats gathering is off by default). [clinic start generated code]*/ static PyObject * sys__stats_off_impl(PyObject *module) -/*[clinic end generated code: output=1534c1ee63812214 input=b3e50e71ecf29f66]*/ +/*[clinic end generated code: output=1534c1ee63812214 input=d1a84c60c56cbce2]*/ { - _py_stats = NULL; + _Py_StatsOff(); Py_RETURN_NONE; } @@ -2141,21 +2161,23 @@ sys__stats_clear_impl(PyObject *module) } /*[clinic input] -sys._stats_dump +sys._stats_dump -> bool Dump stats to file, and clears the stats. + +Return False if no statistics were not dumped because stats gathering was off. [clinic start generated code]*/ -static PyObject * +static int sys__stats_dump_impl(PyObject *module) -/*[clinic end generated code: output=79f796fb2b4ddf05 input=92346f16d64f6f95]*/ +/*[clinic end generated code: output=6e346b4ba0de4489 input=31a489e39418b2a5]*/ { - _Py_PrintSpecializationStats(1); + int res = _Py_PrintSpecializationStats(1); _Py_StatsClear(); - Py_RETURN_NONE; + return res; } +#endif // Py_STATS -#endif #ifdef ANDROID_API_LEVEL /*[clinic input] @@ -2269,7 +2291,7 @@ sys__getframemodulename_impl(PyObject *module, int depth) if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) { return NULL; } - _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame; + _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame; while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) { f = f->previous; } @@ -2284,10 +2306,19 @@ sys__getframemodulename_impl(PyObject *module, int depth) return Py_NewRef(r); } +/*[clinic input] +sys._get_cpu_count_config -> int -#ifdef __cplusplus -extern "C" { -#endif +Private function for getting PyConfig.cpu_count +[clinic start generated code]*/ + +static int +sys__get_cpu_count_config_impl(PyObject *module) +/*[clinic end generated code: output=36611bb5efad16dc input=523e1ade2204084e]*/ +{ + const PyConfig *config = _Py_GetConfig(); + return config->cpu_count; +} static PerfMapState perf_map_state; @@ -2357,10 +2388,6 @@ PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) { #endif } -#ifdef __cplusplus -} -#endif - static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ @@ -2427,6 +2454,7 @@ static PyMethodDef sys_methods[] = { SYS__STATS_CLEAR_METHODDEF SYS__STATS_DUMP_METHODDEF #endif + SYS__GET_CPU_COUNT_CONFIG_METHODDEF {NULL, NULL} // sentinel }; @@ -3489,7 +3517,9 @@ _PySys_UpdateConfig(PyThreadState *tstate) if (config->pycache_prefix != NULL) { SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); } else { - PyDict_SetItemString(sysdict, "pycache_prefix", Py_None); + if (PyDict_SetItemString(sysdict, "pycache_prefix", Py_None) < 0) { + return -1; + } } COPY_LIST("argv", config->argv); @@ -3503,7 +3533,9 @@ _PySys_UpdateConfig(PyThreadState *tstate) SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir); } else { - PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None); + if (PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None) < 0) { + return -1; + } } #undef SET_SYS_FROM_WSTR @@ -3513,6 +3545,9 @@ _PySys_UpdateConfig(PyThreadState *tstate) // sys.flags PyObject *flags = _PySys_GetObject(interp, "flags"); // borrowed ref if (flags == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.flags"); + } return -1; } if (set_flags_from_config(interp, flags) < 0) { diff --git a/Python/thread.c b/Python/thread.c index 7fc53f9b61360b..bf207cecb90505 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -8,15 +8,35 @@ #include "Python.h" #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() -#include "pycore_pythread.h" +#include "pycore_pythread.h" // _POSIX_THREADS #ifndef DONT_HAVE_STDIO_H -#include +# include #endif #include +// Define PY_TIMEOUT_MAX constant. +#ifdef _POSIX_THREADS + // PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000), + // convert microseconds to nanoseconds. +# define PY_TIMEOUT_MAX_VALUE (LLONG_MAX / 1000) +#elif defined (NT_THREADS) + // WaitForSingleObject() accepts timeout in milliseconds in the range + // [0; 0xFFFFFFFE] (DWORD type). INFINITE value (0xFFFFFFFF) means no + // timeout. 0xFFFFFFFE milliseconds is around 49.7 days. +# if 0xFFFFFFFELL < LLONG_MAX / 1000 +# define PY_TIMEOUT_MAX_VALUE (0xFFFFFFFELL * 1000) +# else +# define PY_TIMEOUT_MAX_VALUE LLONG_MAX +# endif +#else +# define PY_TIMEOUT_MAX_VALUE LLONG_MAX +#endif +const long long PY_TIMEOUT_MAX = PY_TIMEOUT_MAX_VALUE; + + static void PyThread__init_thread(void); /* Forward */ #define initialized _PyRuntime.threads.initialized diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index f96c57da64636d..76a1f7763f23b9 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -1,4 +1,5 @@ -#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize +#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize +#include "pycore_pythread.h" // _POSIX_SEMAPHORES /* Posix threads interface */ @@ -84,10 +85,10 @@ /* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so we need to add 0 to make it work there as well. */ #if (_POSIX_SEMAPHORES+0) == -1 -#define HAVE_BROKEN_POSIX_SEMAPHORES +# define HAVE_BROKEN_POSIX_SEMAPHORES #else -#include -#include +# include +# include #endif #endif diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h index 56e5b6141924b4..48bad36ec449ab 100644 --- a/Python/thread_pthread_stubs.h +++ b/Python/thread_pthread_stubs.h @@ -40,7 +40,7 @@ pthread_cond_init(pthread_cond_t *restrict cond, return 0; } -PyAPI_FUNC(int)pthread_cond_destroy(pthread_cond_t *cond) +PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond) { return 0; } diff --git a/Python/traceback.c b/Python/traceback.c index c5787b5ea4678c..05d841e56ad7bd 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -3,9 +3,9 @@ #include "Python.h" -#include "pycore_ast.h" // asdl_seq_* +#include "pycore_ast.h" // asdl_seq_GET() #include "pycore_call.h" // _PyObject_CallMethodFormat() -#include "pycore_compile.h" // _PyAST_Optimize +#include "pycore_compile.h" // _PyAST_Optimize() #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH #include "pycore_frame.h" // _PyFrame_GetCode() #include "pycore_interp.h" // PyInterpreterState.gc @@ -13,24 +13,26 @@ #include "pycore_pyarena.h" // _PyArena_Free() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_traceback.h" // EXCEPTION_TB_HEADER #include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset() #include "frameobject.h" // PyFrame_New() -#include "structmember.h" // PyMemberDef + #include "osdefs.h" // SEP -#ifdef HAVE_FCNTL_H -# include +#ifdef HAVE_UNISTD_H +# include // lseek() #endif + #define OFF(x) offsetof(PyTracebackObject, x) +#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, (int)strlen(str)) -#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) #define MAX_STRING_LENGTH 500 #define MAX_FRAME_DEPTH 100 #define MAX_NTHREADS 100 -/* Function from Parser/tokenizer.c */ +/* Function from Parser/tokenizer/file_tokenizer.c */ extern char* _PyTokenizer_FindEncodingFilename(int, PyObject *); /*[clinic input] @@ -148,9 +150,9 @@ static PyMethodDef tb_methods[] = { }; static PyMemberDef tb_memberlist[] = { - {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ}, - {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, - {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, + {"tb_frame", _Py_T_OBJECT, OFF(tb_frame), Py_READONLY|Py_AUDIT_READ}, + {"tb_lasti", Py_T_INT, OFF(tb_lasti), Py_READONLY}, + {"tb_lineno", Py_T_INT, OFF(tb_lineno), Py_READONLY}, {NULL} /* Sentinel */ }; @@ -395,27 +397,9 @@ _Py_WriteIndent(int indent, PyObject *f) return 0; } -/* Writes indent spaces, followed by the margin if it is not `\0`. - Returns 0 on success and non-zero on failure. - */ -int -_Py_WriteIndentedMargin(int indent, const char *margin, PyObject *f) -{ - if (_Py_WriteIndent(indent, f) < 0) { - return -1; - } - if (margin) { - if (PyFile_WriteString(margin, f) < 0) { - return -1; - } - } - return 0; -} - static int -display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int indent, - int margin_indent, const char *margin, - int *truncation, PyObject **line) +display_source_line(PyObject *f, PyObject *filename, int lineno, int indent, + int *truncation, PyObject **line) { int fd; int i; @@ -543,10 +527,6 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int *truncation = i - indent; } - if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { - goto error; - } - /* Write some spaces before the line */ if (_Py_WriteIndent(indent, f) < 0) { goto error; @@ -572,144 +552,11 @@ int _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent, int *truncation, PyObject **line) { - return display_source_line_with_margin(f, filename, lineno, indent, 0, - NULL, truncation, line); + return display_source_line(f, filename, lineno, indent, truncation, line); } -/* AST based Traceback Specialization - * - * When displaying a new traceback line, for certain syntactical constructs - * (e.g a subscript, an arithmetic operation) we try to create a representation - * that separates the primary source of error from the rest. - * - * Example specialization of BinOp nodes: - * Traceback (most recent call last): - * File "/home/isidentical/cpython/cpython/t.py", line 10, in - * add_values(1, 2, 'x', 3, 4) - * File "/home/isidentical/cpython/cpython/t.py", line 2, in add_values - * return a + b + c + d + e - * ~~~~~~^~~ - * TypeError: 'NoneType' object is not subscriptable - */ #define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\f')) - -static int -extract_anchors_from_expr(const char *segment_str, expr_ty expr, Py_ssize_t *left_anchor, Py_ssize_t *right_anchor, - char** primary_error_char, char** secondary_error_char) -{ - switch (expr->kind) { - case BinOp_kind: { - expr_ty left = expr->v.BinOp.left; - expr_ty right = expr->v.BinOp.right; - for (int i = left->end_col_offset; i < right->col_offset; i++) { - if (IS_WHITESPACE(segment_str[i])) { - continue; - } - - *left_anchor = i; - *right_anchor = i + 1; - - // Check whether if this a two-character operator (e.g //) - if (i + 1 < right->col_offset && !IS_WHITESPACE(segment_str[i + 1])) { - ++*right_anchor; - } - - // Set the error characters - *primary_error_char = "~"; - *secondary_error_char = "^"; - break; - } - return 1; - } - case Subscript_kind: { - *left_anchor = expr->v.Subscript.value->end_col_offset; - *right_anchor = expr->v.Subscript.slice->end_col_offset + 1; - - // Set the error characters - *primary_error_char = "~"; - *secondary_error_char = "^"; - return 1; - } - default: - return 0; - } -} - -static int -extract_anchors_from_stmt(const char *segment_str, stmt_ty statement, Py_ssize_t *left_anchor, Py_ssize_t *right_anchor, - char** primary_error_char, char** secondary_error_char) -{ - switch (statement->kind) { - case Expr_kind: { - return extract_anchors_from_expr(segment_str, statement->v.Expr.value, left_anchor, right_anchor, - primary_error_char, secondary_error_char); - } - default: - return 0; - } -} - -static int -extract_anchors_from_line(PyObject *filename, PyObject *line, - Py_ssize_t start_offset, Py_ssize_t end_offset, - Py_ssize_t *left_anchor, Py_ssize_t *right_anchor, - char** primary_error_char, char** secondary_error_char) -{ - int res = -1; - PyArena *arena = NULL; - PyObject *segment = PyUnicode_Substring(line, start_offset, end_offset); - if (!segment) { - goto done; - } - - const char *segment_str = PyUnicode_AsUTF8(segment); - if (!segment_str) { - goto done; - } - - arena = _PyArena_New(); - if (!arena) { - goto done; - } - - PyCompilerFlags flags = _PyCompilerFlags_INIT; - - mod_ty module = _PyParser_ASTFromString(segment_str, filename, Py_file_input, - &flags, arena); - if (!module) { - goto done; - } - if (!_PyAST_Optimize(module, arena, _Py_GetConfig()->optimization_level, 0)) { - goto done; - } - - assert(module->kind == Module_kind); - if (asdl_seq_LEN(module->v.Module.body) == 1) { - stmt_ty statement = asdl_seq_GET(module->v.Module.body, 0); - res = extract_anchors_from_stmt(segment_str, statement, left_anchor, right_anchor, - primary_error_char, secondary_error_char); - } else { - res = 0; - } - -done: - if (res > 0) { - // Normalize the AST offsets to byte offsets and adjust them with the - // start of the actual line (instead of the source code segment). - assert(segment != NULL); - assert(*left_anchor >= 0); - assert(*right_anchor >= 0); - *left_anchor = _PyPegen_byte_offset_to_character_offset(segment, *left_anchor) + start_offset; - *right_anchor = _PyPegen_byte_offset_to_character_offset(segment, *right_anchor) + start_offset; - } - Py_XDECREF(segment); - if (arena) { - _PyArena_Free(arena); - } - return res; -} - #define _TRACEBACK_SOURCE_LINE_INDENT 4 static inline int @@ -723,42 +570,14 @@ ignore_source_errors(void) { return 0; } -static inline int -print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py_ssize_t end_offset, - Py_ssize_t right_start_offset, Py_ssize_t left_end_offset, - const char *primary, const char *secondary) { - int special_chars = (left_end_offset != -1 || right_start_offset != -1); - const char *str; - while (++offset <= end_offset) { - if (offset <= start_offset) { - str = " "; - } else if (special_chars && left_end_offset < offset && offset <= right_start_offset) { - str = secondary; - } else { - str = primary; - } - if (PyFile_WriteString(str, f) < 0) { - return -1; - } - } - if (PyFile_WriteString("\n", f) < 0) { - return -1; - } - return 0; -} - static int tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int lineno, - PyFrameObject *frame, PyObject *name, int margin_indent, const char *margin) + PyFrameObject *frame, PyObject *name) { if (filename == NULL || name == NULL) { return -1; } - if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { - return -1; - } - PyObject *line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", filename, lineno, name); if (line == NULL) { @@ -775,9 +594,9 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen int truncation = _TRACEBACK_SOURCE_LINE_INDENT; PyObject* source_line = NULL; - int rc = display_source_line_with_margin( + int rc = display_source_line( f, filename, lineno, _TRACEBACK_SOURCE_LINE_INDENT, - margin_indent, margin, &truncation, &source_line); + &truncation, &source_line); if (rc != 0 || !source_line) { /* ignore errors since we can't report them, can we? */ err = ignore_source_errors(); @@ -804,86 +623,18 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen goto done; } - // When displaying errors, we will use the following generic structure: - // - // ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE - // ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~~~~~~~~~ - // | |-> left_end_offset | |-> end_offset - // |-> start_offset |-> right_start_offset - // - // In general we will only have (start_offset, end_offset) but we can gather more information - // by analyzing the AST of the text between *start_offset* and *end_offset*. If this succeeds - // we could get *left_end_offset* and *right_start_offset* and some selection of characters for - // the different ranges (primary_error_char and secondary_error_char). If we cannot obtain the - // AST information or we cannot identify special ranges within it, then left_end_offset and - // right_end_offset will be set to -1. - // - // To keep the column indicators pertinent, they are not shown when the primary character - // spans the whole line. - - // Convert the utf-8 byte offset to the actual character offset so we print the right number of carets. - assert(source_line); - Py_ssize_t start_offset = _PyPegen_byte_offset_to_character_offset(source_line, start_col_byte_offset); - if (start_offset < 0) { - err = ignore_source_errors() < 0; - goto done; - } - - Py_ssize_t end_offset = _PyPegen_byte_offset_to_character_offset(source_line, end_col_byte_offset); - if (end_offset < 0) { - err = ignore_source_errors() < 0; + // If this is a multi-line expression, then we will highlight until + // the last non-whitespace character. + const char *source_line_str = PyUnicode_AsUTF8(source_line); + if (!source_line_str) { goto done; } - Py_ssize_t left_end_offset = -1; - Py_ssize_t right_start_offset = -1; - - char *primary_error_char = "^"; - char *secondary_error_char = primary_error_char; - - if (start_line == end_line) { - int res = extract_anchors_from_line(filename, source_line, start_offset, end_offset, - &left_end_offset, &right_start_offset, - &primary_error_char, &secondary_error_char); - if (res < 0 && ignore_source_errors() < 0) { - goto done; - } - } - else { - // If this is a multi-line expression, then we will highlight until - // the last non-whitespace character. - const char *source_line_str = PyUnicode_AsUTF8(source_line); - if (!source_line_str) { - goto done; - } - - Py_ssize_t i = source_line_len; - while (--i >= 0) { - if (!IS_WHITESPACE(source_line_str[i])) { - break; - } + Py_ssize_t i = source_line_len; + while (--i >= 0) { + if (!IS_WHITESPACE(source_line_str[i])) { + break; } - - end_offset = i + 1; - } - - // Elide indicators if primary char spans the frame line - Py_ssize_t stripped_line_len = source_line_len - truncation - _TRACEBACK_SOURCE_LINE_INDENT; - bool has_secondary_ranges = (left_end_offset != -1 || right_start_offset != -1); - if (end_offset - start_offset == stripped_line_len && !has_secondary_ranges) { - goto done; - } - - if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { - err = -1; - goto done; - } - - if (print_error_location_carets(f, truncation, start_offset, end_offset, - right_start_offset, left_end_offset, - primary_error_char, secondary_error_char) < 0) { - err = -1; - goto done; } done: @@ -911,8 +662,7 @@ tb_print_line_repeated(PyObject *f, long cnt) } static int -tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, - int indent, const char *margin) +tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit) { PyCodeObject *code = NULL; Py_ssize_t depth = 0; @@ -948,7 +698,7 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, cnt++; if (cnt <= TB_RECURSIVE_CUTOFF) { if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno, - tb->tb_frame, code->co_name, indent, margin) < 0) { + tb->tb_frame, code->co_name) < 0) { goto error; } @@ -973,8 +723,7 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, #define PyTraceBack_LIMIT 1000 int -_PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin, - const char *header_margin, const char *header, PyObject *f) +_PyTraceBack_Print(PyObject *v, const char *header, PyObject *f) { PyObject *limitv; long limit = PyTraceBack_LIMIT; @@ -997,15 +746,12 @@ _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin, return 0; } } - if (_Py_WriteIndentedMargin(indent, header_margin, f) < 0) { - return -1; - } if (PyFile_WriteString(header, f) < 0) { return -1; } - if (tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin) < 0) { + if (tb_printinternal((PyTracebackObject *)v, f, limit) < 0) { return -1; } @@ -1015,12 +761,8 @@ _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin, int PyTraceBack_Print(PyObject *v, PyObject *f) { - int indent = 0; - const char *margin = NULL; - const char *header_margin = NULL; const char *header = EXCEPTION_TB_HEADER; - - return _PyTraceBack_Print_Indented(v, indent, margin, header_margin, header, f); + return _PyTraceBack_Print(v, header, f); } /* Format an integer in range [0; 0xffffffff] to decimal and write it @@ -1047,7 +789,7 @@ _Py_DumpDecimal(int fd, size_t value) value /= 10; } while (value); - _Py_write_noraise(fd, ptr, end - ptr); + (void)_Py_write_noraise(fd, ptr, end - ptr); } /* Format an integer as hexadecimal with width digits into fd file descriptor. @@ -1072,7 +814,7 @@ _Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width) value >>= 4; } while ((end - ptr) < width || value); - _Py_write_noraise(fd, ptr, end - ptr); + (void)_Py_write_noraise(fd, ptr, end - ptr); } void @@ -1125,7 +867,7 @@ _Py_DumpASCII(int fd, PyObject *text) } if (!need_escape) { // The string can be written with a single write() syscall - _Py_write_noraise(fd, str, size); + (void)_Py_write_noraise(fd, str, size); goto done; } } @@ -1135,7 +877,7 @@ _Py_DumpASCII(int fd, PyObject *text) if (' ' <= ch && ch <= 126) { /* printable ASCII character */ char c = (char)ch; - _Py_write_noraise(fd, &c, 1); + (void)_Py_write_noraise(fd, &c, 1); } else if (ch <= 0xff) { PUTS(fd, "\\x"); @@ -1197,23 +939,45 @@ dump_frame(int fd, _PyInterpreterFrame *frame) PUTS(fd, "\n"); } +static int +tstate_is_freed(PyThreadState *tstate) +{ + if (_PyMem_IsPtrFreed(tstate)) { + return 1; + } + if (_PyMem_IsPtrFreed(tstate->interp)) { + return 1; + } + return 0; +} + + +static int +interp_is_freed(PyInterpreterState *interp) +{ + return _PyMem_IsPtrFreed(interp); +} + + static void dump_traceback(int fd, PyThreadState *tstate, int write_header) { - _PyInterpreterFrame *frame; - unsigned int depth; - if (write_header) { PUTS(fd, "Stack (most recent call first):\n"); } - frame = tstate->cframe->current_frame; + if (tstate_is_freed(tstate)) { + PUTS(fd, " \n"); + return; + } + + _PyInterpreterFrame *frame = tstate->current_frame; if (frame == NULL) { PUTS(fd, " \n"); return; } - depth = 0; + unsigned int depth = 0; while (1) { if (MAX_FRAME_DEPTH <= depth) { PUTS(fd, " ...\n"); @@ -1277,9 +1041,6 @@ const char* _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, PyThreadState *current_tstate) { - PyThreadState *tstate; - unsigned int nthreads; - if (current_tstate == NULL) { /* _Py_DumpTracebackThreads() is called from signal handlers by faulthandler. @@ -1295,6 +1056,10 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, current_tstate = PyGILState_GetThisThreadState(); } + if (current_tstate != NULL && tstate_is_freed(current_tstate)) { + return "tstate is freed"; + } + if (interp == NULL) { if (current_tstate == NULL) { interp = _PyGILState_GetInterpreterStateUnsafe(); @@ -1309,14 +1074,18 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, } assert(interp != NULL); + if (interp_is_freed(interp)) { + return "interp is freed"; + } + /* Get the current interpreter from the current thread */ - tstate = PyInterpreterState_ThreadHead(interp); + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); if (tstate == NULL) return "unable to get the thread head state"; /* Dump the traceback of each thread */ tstate = PyInterpreterState_ThreadHead(interp); - nthreads = 0; + unsigned int nthreads = 0; _Py_BEGIN_SUPPRESS_IPH do { diff --git a/Python/tracemalloc.c b/Python/tracemalloc.c index f8ad939dccaccd..19b64c619feb6a 100644 --- a/Python/tracemalloc.c +++ b/Python/tracemalloc.c @@ -2,11 +2,12 @@ #include "pycore_fileutils.h" // _Py_write_noraise() #include "pycore_gc.h" // PyGC_Head #include "pycore_hashtable.h" // _Py_hashtable_t -#include "pycore_object.h" // _PyType_PreHeaderSize +#include "pycore_object.h" // _PyType_PreHeaderSize() #include "pycore_pymem.h" // _Py_tracemalloc_config #include "pycore_runtime.h" // _Py_ID() -#include "pycore_traceback.h" +#include "pycore_traceback.h" // _Py_DumpASCII() #include + #include "frameobject.h" // _PyInterpreterFrame_GetLine #include // malloc() @@ -1247,7 +1248,7 @@ tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr) } -#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) +#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, (int)strlen(str)) static void _PyMem_DumpFrame(int fd, frame_t * frame) diff --git a/README.rst b/README.rst index 4ab26565a13e03..9ba06f76ba5da8 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.13.0 alpha 0 +This is Python version 3.13.0 alpha 1 ===================================== .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg @@ -76,6 +76,9 @@ to macOS framework and universal builds. Refer to `Mac/README.rst On Windows, see `PCbuild/readme.txt `_. +To build Windows installer, see `Tools/msi/README.txt +`_. + If you wish, you can create a subdirectory and invoke configure from there. For example:: @@ -177,7 +180,7 @@ is printed about a failed test or a traceback or core dump is produced, something is wrong. By default, tests are prevented from overusing resources like disk space and -memory. To enable these tests, run ``make testall``. +memory. To enable these tests, run ``make buildbottest``. If any tests fail, you can re-run the failing test(s) in verbose mode. For example, if ``test_os`` and ``test_gdb`` failed, you can run:: @@ -211,30 +214,6 @@ primary version, you would execute ``make install`` in your 3.13 build directory and ``make altinstall`` in the others. -Issue Tracker and Mailing List ------------------------------- - -Bug reports are welcome! You can use Github to `report bugs -`_, and/or `submit pull requests -`_. - -You can also follow development discussion on the `python-dev mailing list -`_. - - -Proposals for enhancement -------------------------- - -If you have a proposal to change Python, you may want to send an email to the -`comp.lang.python`_ or `python-ideas`_ mailing lists for initial feedback. A -Python Enhancement Proposal (PEP) may be submitted if your idea gains ground. -All current PEPs, as well as guidelines for submitting a new PEP, are listed at -`peps.python.org `_. - -.. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas/ -.. _comp.lang.python: https://mail.python.org/mailman/listinfo/python-list - - Release Schedule ---------------- diff --git a/Tools/build/deepfreeze.py b/Tools/build/deepfreeze.py index b084d3e457f782..c3231a5a40c326 100644 --- a/Tools/build/deepfreeze.py +++ b/Tools/build/deepfreeze.py @@ -6,7 +6,6 @@ by Python 3.10, and 3.11 features are not available. """ import argparse -import ast import builtins import collections import contextlib @@ -17,13 +16,13 @@ from typing import Dict, FrozenSet, TextIO, Tuple import umarshal -from generate_global_objects import get_identifiers_and_strings + +ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) verbose = False -identifiers, strings = get_identifiers_and_strings() -# This must be kept in sync with opcode.py -RESUME = 151 +# This must be kept in sync with Tools/cases_generator/generate_cases.py +RESUME = 149 def isprintable(b: bytes) -> bool: return all(0x20 <= c < 0x7f for c in b) @@ -114,6 +113,7 @@ def __init__(self, file: TextIO) -> None: self.hits, self.misses = 0, 0 self.finis: list[str] = [] self.inits: list[str] = [] + self.identifiers, self.strings = self.get_identifiers_and_strings() self.write('#include "Python.h"') self.write('#include "internal/pycore_gc.h"') self.write('#include "internal/pycore_code.h"') @@ -121,6 +121,19 @@ def __init__(self, file: TextIO) -> None: self.write('#include "internal/pycore_long.h"') self.write("") + def get_identifiers_and_strings(self) -> tuple[set[str], dict[str, str]]: + filename = os.path.join(ROOT, "Include", "internal", "pycore_global_strings.h") + with open(filename) as fp: + lines = fp.readlines() + identifiers: set[str] = set() + strings: dict[str, str] = {} + for line in lines: + if m := re.search(r"STRUCT_FOR_ID\((\w+)\)", line): + identifiers.add(m.group(1)) + if m := re.search(r'STRUCT_FOR_STR\((\w+), "(.*?)"\)', line): + strings[m.group(2)] = m.group(1) + return identifiers, strings + @contextlib.contextmanager def indent(self) -> None: save_level = self.level @@ -171,9 +184,9 @@ def generate_bytes(self, name: str, b: bytes) -> str: return f"& {name}.ob_base.ob_base" def generate_unicode(self, name: str, s: str) -> str: - if s in strings: - return f"&_Py_STR({strings[s]})" - if s in identifiers: + if s in self.strings: + return f"&_Py_STR({self.strings[s]})" + if s in self.identifiers: return f"&_Py_ID({s})" if len(s) == 1: c = ord(s) @@ -208,6 +221,7 @@ def generate_unicode(self, name: str, s: str) -> str: self.write(".kind = 1,") self.write(".compact = 1,") self.write(".ascii = 1,") + self.write(".statically_allocated = 1,") self.write(f"._data = {make_string_literal(s.encode('ascii'))},") return f"& {name}._ascii.ob_base" else: @@ -220,6 +234,7 @@ def generate_unicode(self, name: str, s: str) -> str: self.write(f".kind = {kind},") self.write(".compact = 1,") self.write(".ascii = 0,") + self.write(".statically_allocated = 1,") utf8 = s.encode('utf-8') self.write(f'.utf8 = {make_string_literal(utf8)},') self.write(f'.utf8_length = {len(utf8)},') @@ -282,10 +297,12 @@ def generate_code(self, name: str, code: types.CodeType) -> str: self.write(f".co_linetable = {co_linetable},") self.write(f"._co_cached = NULL,") self.write(f".co_code_adaptive = {co_code_adaptive},") - for i, op in enumerate(code.co_code[::2]): + first_traceable = 0 + for op in code.co_code[::2]: if op == RESUME: - self.write(f"._co_firsttraceable = {i},") break + first_traceable += 1 + self.write(f"._co_firsttraceable = {first_traceable},") name_as_code = f"(PyCodeObject *)&{name}" self.finis.append(f"_PyStaticCode_Fini({name_as_code});") self.inits.append(f"_PyStaticCode_Init({name_as_code})") @@ -439,12 +456,10 @@ def is_frozen_header(source: str) -> bool: def decode_frozen_data(source: str) -> types.CodeType: - lines = source.splitlines() - while lines and re.match(FROZEN_DATA_LINE, lines[0]) is None: - del lines[0] - while lines and re.match(FROZEN_DATA_LINE, lines[-1]) is None: - del lines[-1] - values: Tuple[int, ...] = ast.literal_eval("".join(lines).strip()) + values: list[int] = [] + for line in source.splitlines(): + if re.match(FROZEN_DATA_LINE, line): + values.extend([int(x) for x in line.split(",") if x.strip()]) data = bytes(values) return umarshal.loads(data) diff --git a/Tools/build/freeze_modules.py b/Tools/build/freeze_modules.py index ee4dd2f8682ba4..a07f4d9786ea65 100644 --- a/Tools/build/freeze_modules.py +++ b/Tools/build/freeze_modules.py @@ -467,15 +467,14 @@ def replace_block(lines, start_marker, end_marker, replacements, file): return lines[:start_pos + 1] + replacements + lines[end_pos:] -def regen_frozen(modules, frozen_modules: bool): +def regen_frozen(modules): headerlines = [] parentdir = os.path.dirname(FROZEN_FILE) - if frozen_modules: - for src in _iter_sources(modules): - # Adding a comment to separate sections here doesn't add much, - # so we don't. - header = relpath_for_posix_display(src.frozenfile, parentdir) - headerlines.append(f'#include "{header}"') + for src in _iter_sources(modules): + # Adding a comment to separate sections here doesn't add much, + # so we don't. + header = relpath_for_posix_display(src.frozenfile, parentdir) + headerlines.append(f'#include "{header}"') externlines = [] bootstraplines = [] @@ -504,14 +503,9 @@ def regen_frozen(modules, frozen_modules: bool): get_code_name = "_Py_get_%s_toplevel" % code_name externlines.append("extern PyObject *%s(void);" % get_code_name) - symbol = mod.symbol pkg = 'true' if mod.ispkg else 'false' - if not frozen_modules: - line = ('{"%s", NULL, 0, %s, GET_CODE(%s)},' - ) % (mod.name, pkg, code_name) - else: - line = ('{"%s", %s, (int)sizeof(%s), %s, GET_CODE(%s)},' - ) % (mod.name, symbol, symbol, pkg, code_name) + size = f"(int)sizeof({mod.symbol})" + line = f'{{"{mod.name}", {mod.symbol}, {size}, {pkg}}},' lines.append(line) if mod.isalias: @@ -585,7 +579,7 @@ def regen_makefile(modules): pyfiles = [] frozenfiles = [] rules = [''] - deepfreezerules = ["Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS)", + deepfreezerules = ["$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS)", "\t$(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \\"] for src in _iter_sources(modules): frozen_header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) @@ -718,20 +712,14 @@ def regen_pcbuild(modules): ####################################### # the script -parser = argparse.ArgumentParser() -parser.add_argument("--frozen-modules", action="store_true", - help="Use both frozen and deepfrozen modules. (default: uses only deepfrozen modules)") - def main(): - args = parser.parse_args() - frozen_modules: bool = args.frozen_modules # Expand the raw specs, preserving order. modules = list(parse_frozen_specs()) # Regen build-related files. regen_makefile(modules) regen_pcbuild(modules) - regen_frozen(modules, frozen_modules) + regen_frozen(modules) if __name__ == '__main__': diff --git a/Tools/build/generate_opcode_h.py b/Tools/build/generate_opcode_h.py deleted file mode 100644 index 5b0560e6b21a99..00000000000000 --- a/Tools/build/generate_opcode_h.py +++ /dev/null @@ -1,206 +0,0 @@ -# This script generates the opcode.h header file. - -import sys -import tokenize - -SCRIPT_NAME = "Tools/build/generate_opcode_h.py" -PYTHON_OPCODE = "Lib/opcode.py" - -header = f""" -// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} - -#ifndef Py_OPCODE_H -#define Py_OPCODE_H -#ifdef __cplusplus -extern "C" {{ -#endif - - -/* Instruction opcodes for compiled code */ -""".lstrip() - -footer = """ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OPCODE_H */ -""" - -internal_header = f""" -// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} - -#ifndef Py_INTERNAL_OPCODE_H -#define Py_INTERNAL_OPCODE_H -#ifdef __cplusplus -extern "C" {{ -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "opcode.h" -""".lstrip() - -internal_footer = """ -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_OPCODE_H -""" - -intrinsic_header = f""" -// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} - -""".lstrip() - -intrinsic_footer = """ -typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value); -typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2); -extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[]; -extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[]; -""" - -DEFINE = "#define {:<38} {:>3}\n" - -UINT32_MASK = (1<<32)-1 - -def get_python_module_dict(filename): - mod = {} - with tokenize.open(filename) as fp: - code = fp.read() - exec(code, mod) - return mod - -def main(opcode_py, - _opcode_metadata_py='Lib/_opcode_metadata.py', - outfile='Include/opcode.h', - internaloutfile='Include/internal/pycore_opcode.h', - intrinsicoutfile='Include/internal/pycore_intrinsics.h'): - - _opcode_metadata = get_python_module_dict(_opcode_metadata_py) - - opcode = get_python_module_dict(opcode_py) - opmap = opcode['opmap'] - opname = opcode['opname'] - is_pseudo = opcode['is_pseudo'] - - ENABLE_SPECIALIZATION = opcode["ENABLE_SPECIALIZATION"] - MIN_PSEUDO_OPCODE = opcode["MIN_PSEUDO_OPCODE"] - MAX_PSEUDO_OPCODE = opcode["MAX_PSEUDO_OPCODE"] - MIN_INSTRUMENTED_OPCODE = opcode["MIN_INSTRUMENTED_OPCODE"] - - NUM_OPCODES = len(opname) - used = [ False ] * len(opname) - next_op = 1 - - for name, op in opmap.items(): - used[op] = True - - specialized_opmap = {} - opname_including_specialized = opname.copy() - for name in _opcode_metadata['_specialized_instructions']: - while used[next_op]: - next_op += 1 - specialized_opmap[name] = next_op - opname_including_specialized[next_op] = name - used[next_op] = True - - with open(outfile, 'w') as fobj, open(internaloutfile, 'w') as iobj, open( - intrinsicoutfile, "w") as nobj: - fobj.write(header) - iobj.write(internal_header) - nobj.write(intrinsic_header) - - for name in opname: - if name in opmap: - op = opmap[name] - if op == MIN_PSEUDO_OPCODE: - fobj.write(DEFINE.format("MIN_PSEUDO_OPCODE", MIN_PSEUDO_OPCODE)) - if op == MIN_INSTRUMENTED_OPCODE: - fobj.write(DEFINE.format("MIN_INSTRUMENTED_OPCODE", MIN_INSTRUMENTED_OPCODE)) - - fobj.write(DEFINE.format(name, op)) - - if op == MAX_PSEUDO_OPCODE: - fobj.write(DEFINE.format("MAX_PSEUDO_OPCODE", MAX_PSEUDO_OPCODE)) - - - for name, op in specialized_opmap.items(): - fobj.write(DEFINE.format(name, op)) - - iobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n") - iobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n") - iobj.write("\n#ifdef NEED_OPCODE_TABLES\n") - - iobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n") - for i, entries in enumerate(opcode["_inline_cache_entries"]): - if entries: - iobj.write(f" [{opname[i]}] = {entries},\n") - iobj.write("};\n") - - deoptcodes = {} - for basic, op in opmap.items(): - if not is_pseudo(op): - deoptcodes[basic] = basic - for basic, family in _opcode_metadata["_specializations"].items(): - for specialized in family: - deoptcodes[specialized] = basic - iobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n") - for opt, deopt in sorted(deoptcodes.items()): - iobj.write(f" [{opt}] = {deopt},\n") - iobj.write("};\n") - iobj.write("#endif // NEED_OPCODE_TABLES\n") - - fobj.write("\n") - for i, (op, _) in enumerate(opcode["_nb_ops"]): - fobj.write(DEFINE.format(op, i)) - - nobj.write("/* Unary Functions: */") - nobj.write("\n") - for i, op in enumerate(opcode["_intrinsic_1_descs"]): - nobj.write(DEFINE.format(op, i)) - nobj.write("\n") - nobj.write(DEFINE.format("MAX_INTRINSIC_1", i)) - - nobj.write("\n\n") - nobj.write("/* Binary Functions: */\n") - for i, op in enumerate(opcode["_intrinsic_2_descs"]): - nobj.write(DEFINE.format(op, i)) - nobj.write("\n") - nobj.write(DEFINE.format("MAX_INTRINSIC_2", i)) - - nobj.write(intrinsic_footer) - - fobj.write("\n") - fobj.write("/* Defined in Lib/opcode.py */\n") - fobj.write(f"#define ENABLE_SPECIALIZATION {int(ENABLE_SPECIALIZATION)}") - - iobj.write("\n") - iobj.write(f"\nextern const char *const _PyOpcode_OpName[{NUM_OPCODES}];\n") - iobj.write("\n#ifdef NEED_OPCODE_TABLES\n") - iobj.write(f"const char *const _PyOpcode_OpName[{NUM_OPCODES}] = {{\n") - for op, name in enumerate(opname_including_specialized): - if name[0] != "<": - op = name - iobj.write(f''' [{op}] = "{name}",\n''') - iobj.write("};\n") - iobj.write("#endif // NEED_OPCODE_TABLES\n") - - iobj.write("\n") - iobj.write("#define EXTRA_CASES \\\n") - for i, flag in enumerate(used): - if not flag: - iobj.write(f" case {i}: \\\n") - iobj.write(" ;\n") - - fobj.write(footer) - iobj.write(internal_footer) - - - print(f"{outfile} regenerated from {opcode_py}") - - -if __name__ == '__main__': - main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]) diff --git a/Tools/build/generate_stdlib_module_names.py b/Tools/build/generate_stdlib_module_names.py index 72f6923c7c316a..766a85d3d6f39e 100644 --- a/Tools/build/generate_stdlib_module_names.py +++ b/Tools/build/generate_stdlib_module_names.py @@ -28,6 +28,7 @@ '_testbuffer', '_testcapi', '_testclinic', + '_testclinic_limited', '_testconsole', '_testimportmultiple', '_testinternalcapi', diff --git a/Tools/build/generate_token.py b/Tools/build/generate_token.py index 3bd307c1733867..16c38841e44a4d 100755 --- a/Tools/build/generate_token.py +++ b/Tools/build/generate_token.py @@ -50,7 +50,7 @@ def update_file(file, content): token_h_template = f"""\ -/* {AUTO_GENERATED_BY_SCRIPT} */ +// {AUTO_GENERATED_BY_SCRIPT} """ token_h_template += """\ @@ -84,7 +84,7 @@ def update_file(file, content): (x) == FSTRING_MIDDLE) -// Symbols exported for test_peg_generator +// Export these 4 symbols for 'test_peg_generator' PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ PyAPI_FUNC(int) _PyToken_OneChar(int); PyAPI_FUNC(int) _PyToken_TwoChars(int, int); diff --git a/Tools/build/smelly.py b/Tools/build/smelly.py index 276a5ab2cc84c6..ab345307ff9b64 100755 --- a/Tools/build/smelly.py +++ b/Tools/build/smelly.py @@ -11,6 +11,11 @@ if sys.platform == 'darwin': ALLOWED_PREFIXES += ('__Py',) +# "Legacy": some old symbols are prefixed by "PY_". +EXCEPTIONS = frozenset({ + 'PY_TIMEOUT_MAX', +}) + IGNORED_EXTENSION = "_ctypes_test" # Ignore constructor and destructor functions IGNORED_SYMBOLS = {'_init', '_fini'} @@ -72,7 +77,7 @@ def get_smelly_symbols(stdout): symbol = parts[-1] result = '%s (type: %s)' % (symbol, symtype) - if symbol.startswith(ALLOWED_PREFIXES): + if symbol.startswith(ALLOWED_PREFIXES) or symbol in EXCEPTIONS: python_symbols.append(result) continue diff --git a/Tools/build/umarshal.py b/Tools/build/umarshal.py index f61570cbaff751..8198a1780b8dad 100644 --- a/Tools/build/umarshal.py +++ b/Tools/build/umarshal.py @@ -1,4 +1,4 @@ -# Implementat marshal.loads() in pure Python +# Implementation of marshal.loads() in pure Python import ast @@ -125,10 +125,10 @@ def r_long64(self) -> int: x |= buf[1] << 8 x |= buf[2] << 16 x |= buf[3] << 24 - x |= buf[1] << 32 - x |= buf[1] << 40 - x |= buf[1] << 48 - x |= buf[1] << 56 + x |= buf[4] << 32 + x |= buf[5] << 40 + x |= buf[6] << 48 + x |= buf[7] << 56 x |= -(x & (1<<63)) # Sign-extend return x diff --git a/Tools/build/verify_ensurepip_wheels.py b/Tools/build/verify_ensurepip_wheels.py index 09fd5d9e3103ac..29897425da6c03 100755 --- a/Tools/build/verify_ensurepip_wheels.py +++ b/Tools/build/verify_ensurepip_wheels.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 """ Compare checksums for wheels in :mod:`ensurepip` against the Cheeseshop. @@ -35,11 +35,17 @@ def print_error(file_path: str, message: str) -> None: def verify_wheel(package_name: str) -> bool: # Find the package on disk - package_path = next(WHEEL_DIR.glob(f"{package_name}*.whl"), None) - if not package_path: - print_error("", f"Could not find a {package_name} wheel on disk.") + package_paths = list(WHEEL_DIR.glob(f"{package_name}*.whl")) + if len(package_paths) != 1: + if package_paths: + for p in package_paths: + print_error(p, f"Found more than one wheel for package {package_name}.") + else: + print_error("", f"Could not find a {package_name} wheel on disk.") return False + package_path = package_paths[0] + print(f"Verifying checksum for {package_path}.") # Find the version of the package used by ensurepip diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index 25c796a60e173d..781f9a4c8206c8 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -5,7 +5,7 @@ setlocal set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH set here=%~dp0 set rt_opts=-q -d -set regrtest_args=-j1 +set regrtest_args= set arm32_ssh= :CheckOpts @@ -23,7 +23,7 @@ if "%PROCESSOR_ARCHITECTURE%"=="ARM" if "%arm32_ssh%"=="true" goto NativeExecuti if "%arm32_ssh%"=="true" goto :Arm32Ssh :NativeExecution -call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% +call "%here%..\..\PCbuild\rt.bat" %rt_opts% --slow-ci %regrtest_args% exit /b %ERRORLEVEL% :Arm32Ssh @@ -35,7 +35,7 @@ if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DI set TEMP_ARGS=--temp %REMOTE_PYTHON_DIR%temp -set rt_args=%rt_opts% %dashU% -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% %TEMP_ARGS% +set rt_args=%rt_opts% --slow-ci %dashU% %regrtest_args% %TEMP_ARGS% ssh %SSH_SERVER% "set TEMP=%REMOTE_PYTHON_DIR%temp& cd %REMOTE_PYTHON_DIR% & %REMOTE_PYTHON_DIR%PCbuild\rt.bat" %rt_args% set ERR=%ERRORLEVEL% scp %SSH_SERVER%:"%REMOTE_PYTHON_DIR%test-results.xml" "%PYTHON_SOURCE%\test-results.xml" diff --git a/Tools/c-analyzer/TODO b/Tools/c-analyzer/TODO index 27a535814ea52b..3d599538510bd9 100644 --- a/Tools/c-analyzer/TODO +++ b/Tools/c-analyzer/TODO @@ -428,8 +428,8 @@ Objects/typeobject.c:type_new():PyId___slots__ _Py_IDENTIFIER( Objects/unicodeobject.c:unicodeiter_reduce():PyId_iter _Py_IDENTIFIER(iter) Objects/weakrefobject.c:proxy_bytes():PyId___bytes__ _Py_IDENTIFIER(__bytes__) Objects/weakrefobject.c:weakref_repr():PyId___name__ _Py_IDENTIFIER(__name__) -Parser/tokenizer.c:fp_setreadl():PyId_open _Py_IDENTIFIER(open) -Parser/tokenizer.c:fp_setreadl():PyId_readline _Py_IDENTIFIER(readline) +Parser/tokenizer/file_tokenizer.c:fp_setreadl():PyId_open _Py_IDENTIFIER(open) +Parser/tokenizer/file_tokenizer.c:fp_setreadl():PyId_readline _Py_IDENTIFIER(readline) Python/Python-ast.c:ast_type_reduce():PyId___dict__ _Py_IDENTIFIER(__dict__) Python/Python-ast.c:make_type():PyId___module__ _Py_IDENTIFIER(__module__) Python/_warnings.c:PyId_stderr _Py_IDENTIFIER(stderr) diff --git a/Tools/c-analyzer/c_parser/info.py b/Tools/c-analyzer/c_parser/info.py index 799f9237877447..f96172e8ca8dfb 100644 --- a/Tools/c-analyzer/c_parser/info.py +++ b/Tools/c-analyzer/c_parser/info.py @@ -206,7 +206,7 @@ def from_row(cls, row, **markers): row = _tables.fix_row(row, **markers) return cls(*row) - # We have to provde _make() becaose we implemented __new__(). + # We have to provide _make() because we implemented __new__(). @classmethod def _make(cls, iterable): diff --git a/Tools/c-analyzer/c_parser/preprocessor/__init__.py b/Tools/c-analyzer/c_parser/preprocessor/__init__.py index cdc1a4e1269059..30a86cbd7dc494 100644 --- a/Tools/c-analyzer/c_parser/preprocessor/__init__.py +++ b/Tools/c-analyzer/c_parser/preprocessor/__init__.py @@ -2,6 +2,7 @@ import logging import os import os.path +import platform import re import sys @@ -242,6 +243,8 @@ def _get_default_compiler(): return 'unix' if os.name == 'nt': return 'msvc' + if sys.platform == 'darwin' and 'clang' in platform.python_compiler(): + return 'clang' return 'unix' diff --git a/Tools/c-analyzer/c_parser/preprocessor/gcc.py b/Tools/c-analyzer/c_parser/preprocessor/gcc.py index 415a2ba63dfe68..6ece70c77fd55c 100644 --- a/Tools/c-analyzer/c_parser/preprocessor/gcc.py +++ b/Tools/c-analyzer/c_parser/preprocessor/gcc.py @@ -3,14 +3,21 @@ from . import common as _common -# Modules/socketmodule.h uses pycore_time.h which needs the Py_BUILD_CORE -# macro. Usually it's defined by the C file which includes it. -# Other header files have a similar issue. -NEED_BUILD_CORE = { - 'cjkcodecs.h', - 'multibytecodec.h', - 'socketmodule.h', -} +# The following C files must not built with Py_BUILD_CORE. +FILES_WITHOUT_INTERNAL_CAPI = frozenset(( + # Modules/ + '_testcapimodule.c', + '_testclinic_limited.c', + 'xxlimited.c', + 'xxlimited_35.c', +)) + +# C files in the fhe following directories must not be built with +# Py_BUILD_CORE. +DIRS_WITHOUT_INTERNAL_CAPI = frozenset(( + # Modules/_testcapi/ + '_testcapi', +)) TOOL = 'gcc' @@ -70,7 +77,10 @@ def preprocess(filename, filename = _normpath(filename, cwd) postargs = POST_ARGS - if os.path.basename(filename) in NEED_BUILD_CORE: + basename = os.path.basename(filename) + dirname = os.path.basename(os.path.dirname(filename)) + if (basename not in FILES_WITHOUT_INTERNAL_CAPI + and dirname not in DIRS_WITHOUT_INTERNAL_CAPI): postargs += ('-DPy_BUILD_CORE=1',) text = _common.preprocess( diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index 9bc7285e18b2fb..4523b2ed5b9fdf 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -84,6 +84,7 @@ def clean_lines(text): Python/frozen_modules/*.h Python/generated_cases.c.h Python/executor_cases.c.h +Python/abstract_interp_cases.c.h # not actually source Python/bytecodes.c @@ -313,6 +314,7 @@ def clean_lines(text): _abs('Objects/stringlib/unicode_format.h'): (10_000, 400), _abs('Objects/typeobject.c'): (35_000, 200), _abs('Python/compile.c'): (20_000, 500), + _abs('Python/parking_lot.c'): (40_000, 1000), _abs('Python/pylifecycle.c'): (500_000, 5000), _abs('Python/pystate.c'): (500_000, 5000), diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 90bbc8928b428a..aa8ce49ae86376 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -54,9 +54,10 @@ Objects/genobject.c - _PyAsyncGenASend_Type - Objects/genobject.c - _PyAsyncGenAThrow_Type - Objects/genobject.c - _PyAsyncGenWrappedValue_Type - Objects/genobject.c - _PyCoroWrapper_Type - -Objects/interpreteridobject.c - _PyInterpreterID_Type - +Objects/interpreteridobject.c - PyInterpreterID_Type - Objects/iterobject.c - PyCallIter_Type - Objects/iterobject.c - PySeqIter_Type - +Objects/iterobject.c - _PyAnextAwaitable_Type - Objects/listobject.c - PyListIter_Type - Objects/listobject.c - PyListRevIter_Type - Objects/listobject.c - PyList_Type - @@ -70,6 +71,7 @@ Objects/moduleobject.c - PyModule_Type - Objects/namespaceobject.c - _PyNamespace_Type - Objects/object.c - _PyNone_Type - Objects/object.c - _PyNotImplemented_Type - +Objects/object.c - _PyAnextAwaitable_Type - Objects/odictobject.c - PyODictItems_Type - Objects/odictobject.c - PyODictIter_Type - Objects/odictobject.c - PyODictKeys_Type - @@ -113,8 +115,6 @@ Objects/codeobject.c - _PyLineIterator - Objects/codeobject.c - _PyPositionsIterator - Objects/genericaliasobject.c - _Py_GenericAliasIterType - # Not in a .h file: -Objects/iterobject.c - _PyAnextAwaitable_Type - -# Not in a .h file: Objects/memoryobject.c - _PyMemoryIter_Type - Objects/unicodeobject.c - _PyUnicodeASCIIIter_Type - Objects/unionobject.c - _PyUnion_Type - @@ -322,6 +322,12 @@ Modules/_testcapi/vectorcall.c - MethodDescriptorBase_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorNopGet_Type - Modules/_testcapi/vectorcall.c - MethodDescriptor2_Type - +Modules/_testclinic.c - DeprStarInit - +Modules/_testclinic.c - DeprStarInitNoInline - +Modules/_testclinic.c - DeprStarNew - +Modules/_testclinic.c - DeprKwdInit - +Modules/_testclinic.c - DeprKwdInitNoInline - +Modules/_testclinic.c - DeprKwdNew - ################################## @@ -412,23 +418,12 @@ Modules/_ctypes/_ctypes.c - _unpickle - Modules/_ctypes/_ctypes.c PyCArrayType_from_ctype cache - Modules/_cursesmodule.c - ModDict - Modules/_datetimemodule.c datetime_strptime module - -Modules/_datetimemodule.c - PyDateTime_TimeZone_UTC - -Modules/_datetimemodule.c - PyDateTime_Epoch - -Modules/_datetimemodule.c - us_per_ms - -Modules/_datetimemodule.c - us_per_second - -Modules/_datetimemodule.c - us_per_minute - -Modules/_datetimemodule.c - us_per_hour - -Modules/_datetimemodule.c - us_per_day - -Modules/_datetimemodule.c - us_per_week - -Modules/_datetimemodule.c - seconds_per_day - -Modules/_decimal/_decimal.c - global_state - ## state -Modules/_asynciomodule.c - fi_freelist - -Modules/_asynciomodule.c - fi_freelist_len - Modules/_ctypes/_ctypes.c - _ctypes_ptrtype_cache - Modules/_ctypes/_ctypes.c - global_state - Modules/_ctypes/ctypes.h - global_state - +Modules/_datetimemodule.c - _datetime_global_state - Modules/_tkinter.c - tcl_lock - Modules/_tkinter.c - excInCmd - Modules/_tkinter.c - valInCmd - diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 73eec6631d9512..0ba7ab15ce89b8 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -50,6 +50,9 @@ Python/getversion.c - version - Python/bootstrap_hash.c - _Py_HashSecret_Initialized - Python/pyhash.c - _Py_HashSecret - +## thread-safe hashtable (internal locks) +Python/parking_lot.c - buckets - + ################################## ## state tied to Py_Main() @@ -85,6 +88,10 @@ Parser/myreadline.c - PyOS_ReadlineFunctionPointer - Python/initconfig.c - _Py_StandardStreamEncoding - Python/initconfig.c - _Py_StandardStreamErrors - +# Internal constant list +Python/initconfig.c - PYCONFIG_SPEC - + + ##----------------------- ## public C-API @@ -159,6 +166,9 @@ Python/pylifecycle.c fatal_error reentrant - # explicitly protected, internal-only Modules/_xxinterpchannelsmodule.c - _globals - +# set once during module init +Modules/_decimal/_decimal.c - minalloc_is_set - + ################################## ## not significant @@ -205,14 +215,15 @@ Modules/_datetimemodule.c - max_fold_seconds - Modules/_datetimemodule.c datetime_isoformat specs - Modules/_datetimemodule.c parse_hh_mm_ss_ff correction - Modules/_datetimemodule.c time_isoformat specs - -Modules/_decimal/_decimal.c - cond_map - +Modules/_decimal/_decimal.c - cond_map_template - Modules/_decimal/_decimal.c - dec_signal_string - Modules/_decimal/_decimal.c - dflt_ctx - Modules/_decimal/_decimal.c - int_constants - Modules/_decimal/_decimal.c - invalid_rounding_err - Modules/_decimal/_decimal.c - invalid_signals_err - -Modules/_decimal/_decimal.c - signal_map - +Modules/_decimal/_decimal.c - signal_map_template - Modules/_decimal/_decimal.c - ssize_constants - +Modules/_decimal/_decimal.c - INVALID_SIGNALDICT_ERROR_MSG - Modules/_elementtree.c - ExpatMemoryHandler - Modules/_hashopenssl.c - py_hashes - Modules/_hacl/Hacl_Hash_SHA1.c - _h0 - @@ -324,9 +335,9 @@ Objects/unicodeobject.c unicode_encode_call_errorhandler argparse - Objects/unicodeobject.c unicode_translate_call_errorhandler argparse - Parser/parser.c - reserved_keywords - Parser/parser.c - soft_keywords - -Parser/tokenizer.c - type_comment_prefix - +Parser/lexer/lexer.c - type_comment_prefix - Python/ast_opt.c fold_unaryop ops - -Python/ceval.c - binary_ops - +Python/ceval.c - _PyEval_BinaryOps - Python/ceval.c - _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS - Python/codecs.c - Py_hexdigits - Python/codecs.c - ucnhash_capi - @@ -418,6 +429,8 @@ Modules/_testbuffer.c staticarray_init kwlist - Modules/_testcapi/buffer.c - testBufType - Modules/_testcapi/code.c get_code_extra_index key - Modules/_testcapi/datetime.c - test_run_counter - +Modules/_testcapi/docstring.c - DocStringNoSignatureTest - +Modules/_testcapi/docstring.c - DocStringUnrepresentableSignatureTest - Modules/_testcapi/exceptions.c - PyRecursingInfinitelyError_Type - Modules/_testcapi/heaptype.c - _testcapimodule - Modules/_testcapi/mem.c - FmData - @@ -428,6 +441,7 @@ Modules/_testcapi/watchers.c - g_dict_watch_events - Modules/_testcapi/watchers.c - g_dict_watchers_installed - Modules/_testcapi/watchers.c - g_type_modified_events - Modules/_testcapi/watchers.c - g_type_watchers_installed - +Modules/_testcapi/watchers.c - code_watcher_ids - Modules/_testcapi/watchers.c - num_code_object_created_events - Modules/_testcapi/watchers.c - num_code_object_destroyed_events - Modules/_testcapi/watchers.c - pyfunc_watchers - @@ -573,15 +587,15 @@ Modules/_testmultiphase.c - uninitialized_def - Modules/_testsinglephase.c - global_state - Modules/_xxtestfuzz/_xxtestfuzz.c - _fuzzmodule - Modules/_xxtestfuzz/_xxtestfuzz.c - module_methods - -Modules/_xxtestfuzz/fuzzer.c - SRE_FLAG_DEBUG - +Modules/_xxtestfuzz/fuzzer.c - RE_FLAG_DEBUG - Modules/_xxtestfuzz/fuzzer.c - ast_literal_eval_method - Modules/_xxtestfuzz/fuzzer.c - compiled_patterns - Modules/_xxtestfuzz/fuzzer.c - csv_error - Modules/_xxtestfuzz/fuzzer.c - csv_module - Modules/_xxtestfuzz/fuzzer.c - json_loads_method - Modules/_xxtestfuzz/fuzzer.c - regex_patterns - -Modules/_xxtestfuzz/fuzzer.c - sre_compile_method - -Modules/_xxtestfuzz/fuzzer.c - sre_error_exception - +Modules/_xxtestfuzz/fuzzer.c - re_compile_method - +Modules/_xxtestfuzz/fuzzer.c - re_error_exception - Modules/_xxtestfuzz/fuzzer.c - struct_error - Modules/_xxtestfuzz/fuzzer.c - struct_unpack_method - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput CSV_READER_INITIALIZED - @@ -596,6 +610,7 @@ Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput AST_LITERAL_EVAL_INITIALIZED # XXX Fix the analyzer. ## forward/extern references +Include/internal/pycore_importdl.h - _PyImport_DynLoadFiletab - Include/py_curses.h - PyCurses_API - Include/pydecimal.h - _decimal_api - Modules/_blake2/blake2module.c - blake2b_type_spec - @@ -657,7 +672,6 @@ Objects/object.c - _PyLineIterator - Objects/object.c - _PyPositionsIterator - Python/perf_trampoline.c - _Py_trampoline_func_start - Python/perf_trampoline.c - _Py_trampoline_func_end - -Python/importdl.h - _PyImport_DynLoadFiletab - Modules/expat/xmlrole.c - prolog0 - Modules/expat/xmlrole.c - prolog1 - Modules/expat/xmlrole.c - prolog2 - @@ -713,3 +727,5 @@ Modules/expat/xmlrole.c - error - ## other Modules/_io/_iomodule.c - _PyIO_Module - Modules/_sqlite/module.c - _sqlite3module - +Python/optimizer_analysis.c - _Py_PartitionRootNode_Type - +Python/optimizer_analysis.c - _Py_UOpsAbstractInterpContext_Type - diff --git a/Tools/cases_generator/README.md b/Tools/cases_generator/README.md index fc9331656fe787..ed802e44f31ad5 100644 --- a/Tools/cases_generator/README.md +++ b/Tools/cases_generator/README.md @@ -7,10 +7,14 @@ What's currently here: - `lexer.py`: lexer for C, originally written by Mark Shannon - `plexer.py`: OO interface on top of lexer.py; main class: `PLexer` -- `parser.py`: Parser for instruction definition DSL; main class `Parser` +- `parsing.py`: Parser for instruction definition DSL; main class `Parser` - `generate_cases.py`: driver script to read `Python/bytecodes.c` and write `Python/generated_cases.c.h` (and several other files) -- `test_generator.py`: tests, require manual running using `pytest` +- `analysis.py`: `Analyzer` class used to read the input files +- `flags.py`: abstractions related to metadata flags for instructions +- `formatting.py`: `Formatter` class used to write the output files +- `instructions.py`: classes to analyze and write instructions +- `stacking.py`: code to handle generalized stack effects Note that there is some dummy C code at the top and bottom of `Python/bytecodes.c` diff --git a/Tools/cases_generator/_typing_backports.py b/Tools/cases_generator/_typing_backports.py new file mode 100644 index 00000000000000..c2aa50804cefe2 --- /dev/null +++ b/Tools/cases_generator/_typing_backports.py @@ -0,0 +1,15 @@ +"""Backports from newer versions of the typing module. + +We backport these features here so that Python can still build +while using an older Python version for PYTHON_FOR_REGEN. +""" + +from typing import NoReturn + + +def assert_never(obj: NoReturn) -> NoReturn: + """Statically assert that a line of code is unreachable. + + Backport of typing.assert_never (introduced in Python 3.11). + """ + raise AssertionError(f"Expected code to be unreachable, but got: {obj}") diff --git a/Tools/cases_generator/analysis.py b/Tools/cases_generator/analysis.py new file mode 100644 index 00000000000000..b2fa0205bea342 --- /dev/null +++ b/Tools/cases_generator/analysis.py @@ -0,0 +1,481 @@ +import re +import sys +import typing + +from _typing_backports import assert_never +from flags import InstructionFlags, variable_used +from formatting import prettify_filename, UNUSED +from instructions import ( + ActiveCacheEffect, + Component, + Instruction, + InstructionOrCacheEffect, + MacroInstruction, + MacroParts, + PseudoInstruction, +) +import parsing +from parsing import StackEffect + +BEGIN_MARKER = "// BEGIN BYTECODES //" +END_MARKER = "// END BYTECODES //" + +RESERVED_WORDS = { + "co_consts": "Use FRAME_CO_CONSTS.", + "co_names": "Use FRAME_CO_NAMES.", +} + +RE_GO_TO_INSTR = r"^\s*GO_TO_INSTRUCTION\((\w+)\);\s*(?://.*)?$" + + +class Analyzer: + """Parse input, analyze it, and write to output.""" + + input_filenames: list[str] + errors: int = 0 + warnings: int = 0 + + def __init__(self, input_filenames: list[str]): + self.input_filenames = input_filenames + + def message(self, msg: str, node: parsing.Node) -> None: + lineno = 0 + filename = "" + if context := node.context: + filename = context.owner.filename + # Use line number of first non-comment in the node + for token in context.owner.tokens[context.begin : context.end]: + lineno = token.line + if token.kind != "COMMENT": + break + print(f"{filename}:{lineno}: {msg}", file=sys.stderr) + + def error(self, msg: str, node: parsing.Node) -> None: + self.message("error: " + msg, node) + self.errors += 1 + + def warning(self, msg: str, node: parsing.Node) -> None: + self.message("warning: " + msg, node) + self.warnings += 1 + + def note(self, msg: str, node: parsing.Node) -> None: + self.message("note: " + msg, node) + + everything: list[ + parsing.InstDef + | parsing.Macro + | parsing.Pseudo + ] + instrs: dict[str, Instruction] # Includes ops + macros: dict[str, parsing.Macro] + macro_instrs: dict[str, MacroInstruction] + families: dict[str, parsing.Family] + pseudos: dict[str, parsing.Pseudo] + pseudo_instrs: dict[str, PseudoInstruction] + + def parse(self) -> None: + """Parse the source text. + + We only want the parser to see the stuff between the + begin and end markers. + """ + + self.everything = [] + self.instrs = {} + self.macros = {} + self.families = {} + self.pseudos = {} + + instrs_idx: dict[str, int] = dict() + + for filename in self.input_filenames: + self.parse_file(filename, instrs_idx) + + files = " + ".join(self.input_filenames) + n_instrs = len(set(self.instrs) & set(self.macros)) + n_ops = len(self.instrs) - n_instrs + print( + f"Read {n_instrs} instructions, {n_ops} ops, " + f"{len(self.macros)} macros, {len(self.pseudos)} pseudos, " + f"and {len(self.families)} families from {files}", + file=sys.stderr, + ) + + def parse_file(self, filename: str, instrs_idx: dict[str, int]) -> None: + with open(filename) as file: + src = file.read() + + psr = parsing.Parser(src, filename=prettify_filename(filename)) + + # Skip until begin marker + while tkn := psr.next(raw=True): + if tkn.text == BEGIN_MARKER: + break + else: + raise psr.make_syntax_error( + f"Couldn't find {BEGIN_MARKER!r} in {psr.filename}" + ) + start = psr.getpos() + + # Find end marker, then delete everything after it + while tkn := psr.next(raw=True): + if tkn.text == END_MARKER: + break + del psr.tokens[psr.getpos() - 1 :] + + # Parse from start + psr.setpos(start) + thing: parsing.Node | None + thing_first_token = psr.peek() + while thing := psr.definition(): + thing = typing.cast( + parsing.InstDef | parsing.Macro | parsing.Pseudo | parsing.Family, thing + ) + if ws := [w for w in RESERVED_WORDS if variable_used(thing, w)]: + self.error( + f"'{ws[0]}' is a reserved word. {RESERVED_WORDS[ws[0]]}", thing + ) + + match thing: + case parsing.InstDef(name=name): + macro: parsing.Macro | None = None + if thing.kind == "inst" and not thing.override: + macro = parsing.Macro(name, [parsing.OpName(name)]) + if name in self.instrs: + if not thing.override: + raise psr.make_syntax_error( + f"Duplicate definition of '{name}' @ {thing.context} " + f"previous definition @ {self.instrs[name].inst.context}", + thing_first_token, + ) + self.everything[instrs_idx[name]] = thing + if name not in self.instrs and thing.override: + raise psr.make_syntax_error( + f"Definition of '{name}' @ {thing.context} is supposed to be " + "an override but no previous definition exists.", + thing_first_token, + ) + self.instrs[name] = Instruction(thing) + instrs_idx[name] = len(self.everything) + self.everything.append(thing) + if macro is not None: + self.macros[macro.name] = macro + self.everything.append(macro) + case parsing.Macro(name): + self.macros[name] = thing + self.everything.append(thing) + case parsing.Family(name): + self.families[name] = thing + case parsing.Pseudo(name): + self.pseudos[name] = thing + self.everything.append(thing) + case _: + assert_never(thing) + if not psr.eof(): + raise psr.make_syntax_error(f"Extra stuff at the end of {filename}") + + def analyze(self) -> None: + """Analyze the inputs. + + Raises SystemExit if there is an error. + """ + self.analyze_macros_and_pseudos() + self.map_families() + self.mark_predictions() + self.check_families() + + def mark_predictions(self) -> None: + """Mark the instructions that need PREDICTED() labels.""" + # Start with family heads + for family in self.families.values(): + if family.name in self.instrs: + self.instrs[family.name].predicted = True + if family.name in self.macro_instrs: + self.macro_instrs[family.name].predicted = True + # Also look for GO_TO_INSTRUCTION() calls + for instr in self.instrs.values(): + targets: set[str] = set() + for line in instr.block_text: + if m := re.match(RE_GO_TO_INSTR, line): + targets.add(m.group(1)) + for target in targets: + if target_instr := self.instrs.get(target): + target_instr.predicted = True + if target_macro := self.macro_instrs.get(target): + target_macro.predicted = True + if not target_instr and not target_macro: + self.error( + f"Unknown instruction {target!r} predicted in {instr.name!r}", + instr.inst, # TODO: Use better location + ) + + def map_families(self) -> None: + """Link instruction names back to their family, if they have one.""" + for family in self.families.values(): + for member in [family.name] + family.members: + if member_instr := self.instrs.get(member): + if ( + member_instr.family is not family + and member_instr.family is not None + ): + self.error( + f"Instruction {member} is a member of multiple families " + f"({member_instr.family.name}, {family.name}).", + family, + ) + else: + member_instr.family = family + if member_mac := self.macro_instrs.get(member): + assert member_mac.family is None, (member, member_mac.family.name) + member_mac.family = family + if not member_instr and not member_mac: + self.error( + f"Unknown instruction {member!r} referenced in family {family.name!r}", + family, + ) + # A sanctioned exception: + # This opcode is a member of the family but it doesn't pass the checks. + if mac := self.macro_instrs.get("BINARY_OP_INPLACE_ADD_UNICODE"): + mac.family = self.families.get("BINARY_OP") + + def check_families(self) -> None: + """Check each family: + + - Must have at least 2 members (including head) + - Head and all members must be known instructions + - Head and all members must have the same cache, input and output effects + """ + for family in self.families.values(): + if family.name not in self.macro_instrs and family.name not in self.instrs: + self.error( + f"Family {family.name!r} has unknown instruction {family.name!r}", + family, + ) + members = [ + member + for member in family.members + if member in self.instrs or member in self.macro_instrs + ] + if members != family.members: + unknown = set(family.members) - set(members) + self.error( + f"Family {family.name!r} has unknown members: {unknown}", family + ) + expected_effects = self.effect_counts(family.name) + for member in members: + member_effects = self.effect_counts(member) + if member_effects != expected_effects: + self.error( + f"Family {family.name!r} has inconsistent " + f"(cache, input, output) effects:\n" + f" {family.name} = {expected_effects}; " + f"{member} = {member_effects}", + family, + ) + + def effect_counts(self, name: str) -> tuple[int, int, int]: + if mac := self.macro_instrs.get(name): + cache = mac.cache_offset + input, output = 0, 0 + for part in mac.parts: + if isinstance(part, Component): + # A component may pop what the previous component pushed, + # so we offset the input/output counts by that. + delta_i = len(part.instr.input_effects) + delta_o = len(part.instr.output_effects) + offset = min(delta_i, output) + input += delta_i - offset + output += delta_o - offset + else: + assert False, f"Unknown instruction {name!r}" + return cache, input, output + + def analyze_macros_and_pseudos(self) -> None: + """Analyze each macro and pseudo instruction.""" + self.macro_instrs = {} + self.pseudo_instrs = {} + for name, macro in self.macros.items(): + self.macro_instrs[name] = mac = self.analyze_macro(macro) + self.check_macro_consistency(mac) + for name, pseudo in self.pseudos.items(): + self.pseudo_instrs[name] = self.analyze_pseudo(pseudo) + + # TODO: Merge with similar code in stacking.py, write_components() + def check_macro_consistency(self, mac: MacroInstruction) -> None: + def get_var_names(instr: Instruction) -> dict[str, StackEffect]: + vars: dict[str, StackEffect] = {} + for eff in instr.input_effects + instr.output_effects: + if eff.name == UNUSED: + continue + if eff.name in vars: + if vars[eff.name] != eff: + self.error( + f"Instruction {instr.name!r} has " + f"inconsistent type/cond/size for variable " + f"{eff.name!r}: {vars[eff.name]} vs {eff}", + instr.inst, + ) + else: + vars[eff.name] = eff + return vars + + all_vars: dict[str, StackEffect] = {} + # print("Checking", mac.name) + prevop: Instruction | None = None + for part in mac.parts: + if not isinstance(part, Component): + continue + vars = get_var_names(part.instr) + # print(" //", part.instr.name, "//", vars) + for name, eff in vars.items(): + if name in all_vars: + if all_vars[name] != eff: + self.error( + f"Macro {mac.name!r} has " + f"inconsistent type/cond/size for variable " + f"{name!r}: " + f"{all_vars[name]} vs {eff} in {part.instr.name!r}", + mac.macro, + ) + else: + all_vars[name] = eff + if prevop is not None: + pushes = list(prevop.output_effects) + pops = list(reversed(part.instr.input_effects)) + copies: list[tuple[StackEffect, StackEffect]] = [] + while pushes and pops and pushes[-1] == pops[0]: + src, dst = pushes.pop(), pops.pop(0) + if src.name == dst.name or dst.name == UNUSED: + continue + copies.append((src, dst)) + reads = set(copy[0].name for copy in copies) + writes = set(copy[1].name for copy in copies) + if reads & writes: + self.error( + f"Macro {mac.name!r} has conflicting copies " + f"(source of one copy is destination of another): " + f"{reads & writes}", + mac.macro, + ) + prevop = part.instr + + def analyze_macro(self, macro: parsing.Macro) -> MacroInstruction: + components = self.check_macro_components(macro) + parts: MacroParts = [] + flags = InstructionFlags.newEmpty() + offset = 0 + for component in components: + match component: + case parsing.CacheEffect() as ceffect: + parts.append(ceffect) + offset += ceffect.size + case Instruction() as instr: + part, offset = self.analyze_instruction(instr, offset) + parts.append(part) + if instr.name != "_SET_IP": + # _SET_IP in a macro is a no-op in Tier 1 + flags.add(instr.instr_flags) + case _: + assert_never(component) + format = "IB" if flags.HAS_ARG_FLAG else "IX" + if offset: + format += "C" + "0" * (offset - 1) + return MacroInstruction(macro.name, format, flags, macro, parts, offset) + + def analyze_pseudo(self, pseudo: parsing.Pseudo) -> PseudoInstruction: + targets = [self.instrs[target] for target in pseudo.targets] + assert targets + # Make sure the targets have the same fmt + fmts = list(set([t.instr_fmt for t in targets])) + assert len(fmts) == 1 + ignored_flags = {"HAS_EVAL_BREAK_FLAG", "HAS_DEOPT_FLAG", "HAS_ERROR_FLAG"} + assert len({t.instr_flags.bitmap(ignore=ignored_flags) for t in targets}) == 1 + return PseudoInstruction(pseudo.name, targets, fmts[0], targets[0].instr_flags) + + def analyze_instruction( + self, instr: Instruction, offset: int + ) -> tuple[Component, int]: + active_effects: list[ActiveCacheEffect] = [] + for ceffect in instr.cache_effects: + if ceffect.name != UNUSED: + active_effects.append(ActiveCacheEffect(ceffect, offset)) + offset += ceffect.size + return ( + Component(instr, active_effects), + offset, + ) + + def check_macro_components( + self, macro: parsing.Macro + ) -> list[InstructionOrCacheEffect]: + components: list[InstructionOrCacheEffect] = [] + for uop in macro.uops: + match uop: + case parsing.OpName(name): + if name not in self.instrs: + self.error(f"Unknown instruction {name!r}", macro) + else: + components.append(self.instrs[name]) + case parsing.CacheEffect(): + components.append(uop) + case _: + assert_never(uop) + return components + + def report_non_viable_uops(self, jsonfile: str) -> None: + print("The following ops are not viable uops:") + skips = { + "CACHE", + "RESERVED", + "INTERPRETER_EXIT", + "JUMP_BACKWARD", + "LOAD_FAST_LOAD_FAST", + "LOAD_CONST_LOAD_FAST", + "STORE_FAST_STORE_FAST", + "_BINARY_OP_INPLACE_ADD_UNICODE", + "POP_JUMP_IF_TRUE", + "POP_JUMP_IF_FALSE", + "_ITER_JUMP_LIST", + "_ITER_JUMP_TUPLE", + "_ITER_JUMP_RANGE", + } + try: + # Secret feature: if bmraw.json exists, print and sort by execution count + counts = load_execution_counts(jsonfile) + except FileNotFoundError as err: + counts = {} + non_viable = [ + instr + for instr in self.instrs.values() + if instr.name not in skips + and not instr.name.startswith("INSTRUMENTED_") + and not instr.is_viable_uop() + ] + non_viable.sort(key=lambda instr: (-counts.get(instr.name, 0), instr.name)) + for instr in non_viable: + if instr.name in counts: + scount = f"{counts[instr.name]:,}" + else: + scount = "" + print(f" {scount:>15} {instr.name:<35}", end="") + if instr.name in self.families: + print(" (unspecialized)", end="") + elif instr.family is not None: + print(f" (specialization of {instr.family.name})", end="") + print() + + +def load_execution_counts(jsonfile: str) -> dict[str, int]: + import json + + with open(jsonfile) as f: + jsondata = json.load(f) + + # Look for keys like "opcode[LOAD_FAST].execution_count" + prefix = "opcode[" + suffix = "].execution_count" + res: dict[str, int] = {} + for key, value in jsondata.items(): + if key.startswith(prefix) and key.endswith(suffix): + res[key[len(prefix) : -len(suffix)]] = value + return res diff --git a/Tools/cases_generator/flags.py b/Tools/cases_generator/flags.py new file mode 100644 index 00000000000000..5241331bb97cdb --- /dev/null +++ b/Tools/cases_generator/flags.py @@ -0,0 +1,115 @@ +import dataclasses + +from formatting import Formatter +import lexer as lx +import parsing +from typing import AbstractSet + + +@dataclasses.dataclass +class InstructionFlags: + """Construct and manipulate instruction flags""" + + HAS_ARG_FLAG: bool = False + HAS_CONST_FLAG: bool = False + HAS_NAME_FLAG: bool = False + HAS_JUMP_FLAG: bool = False + HAS_FREE_FLAG: bool = False + HAS_LOCAL_FLAG: bool = False + HAS_EVAL_BREAK_FLAG: bool = False + HAS_DEOPT_FLAG: bool = False + HAS_ERROR_FLAG: bool = False + + def __post_init__(self) -> None: + self.bitmask = {name: (1 << i) for i, name in enumerate(self.names())} + + @staticmethod + def fromInstruction(instr: parsing.Node) -> "InstructionFlags": + has_free = ( + variable_used(instr, "PyCell_New") + or variable_used(instr, "PyCell_GET") + or variable_used(instr, "PyCell_SET") + ) + + return InstructionFlags( + HAS_ARG_FLAG=variable_used(instr, "oparg"), + HAS_CONST_FLAG=variable_used(instr, "FRAME_CO_CONSTS"), + HAS_NAME_FLAG=variable_used(instr, "FRAME_CO_NAMES"), + HAS_JUMP_FLAG=variable_used(instr, "JUMPBY"), + HAS_FREE_FLAG=has_free, + HAS_LOCAL_FLAG=( + variable_used(instr, "GETLOCAL") or variable_used(instr, "SETLOCAL") + ) + and not has_free, + HAS_EVAL_BREAK_FLAG=variable_used(instr, "CHECK_EVAL_BREAKER"), + HAS_DEOPT_FLAG=variable_used(instr, "DEOPT_IF"), + HAS_ERROR_FLAG=( + variable_used(instr, "ERROR_IF") + or variable_used(instr, "error") + or variable_used(instr, "pop_1_error") + or variable_used(instr, "exception_unwind") + or variable_used(instr, "resume_with_error") + ), + ) + + @staticmethod + def newEmpty() -> "InstructionFlags": + return InstructionFlags() + + def add(self, other: "InstructionFlags") -> None: + for name, value in dataclasses.asdict(other).items(): + if value: + setattr(self, name, value) + + def names(self, value: bool | None = None) -> list[str]: + if value is None: + return list(dataclasses.asdict(self).keys()) + return [n for n, v in dataclasses.asdict(self).items() if v == value] + + def bitmap(self, ignore: AbstractSet[str] = frozenset()) -> int: + flags = 0 + assert all(hasattr(self, name) for name in ignore) + for name in self.names(): + if getattr(self, name) and name not in ignore: + flags |= self.bitmask[name] + return flags + + @classmethod + def emit_macros(cls, out: Formatter) -> None: + flags = cls.newEmpty() + for name, value in flags.bitmask.items(): + out.emit(f"#define {name} ({value})") + + for name, value in flags.bitmask.items(): + out.emit( + f"#define OPCODE_{name[:-len('_FLAG')]}(OP) " + f"(_PyOpcode_opcode_metadata[OP].flags & ({name}))" + ) + + +def variable_used(node: parsing.Node, name: str) -> bool: + """Determine whether a variable with a given name is used in a node.""" + return any( + token.kind == "IDENTIFIER" and token.text == name for token in node.tokens + ) + + +def variable_used_unspecialized(node: parsing.Node, name: str) -> bool: + """Like variable_used(), but skips #if ENABLE_SPECIALIZATION blocks.""" + tokens: list[lx.Token] = [] + skipping = False + for i, token in enumerate(node.tokens): + if token.kind == "MACRO": + text = "".join(token.text.split()) + # TODO: Handle nested #if + if text == "#if": + if i + 1 < len(node.tokens) and node.tokens[i + 1].text in ( + "ENABLE_SPECIALIZATION", + "TIER_ONE", + ): + skipping = True + elif text in ("#else", "#endif"): + skipping = False + if not skipping: + tokens.append(token) + return any(token.kind == "IDENTIFIER" and token.text == name for token in tokens) diff --git a/Tools/cases_generator/formatting.py b/Tools/cases_generator/formatting.py new file mode 100644 index 00000000000000..4fd9172d20c274 --- /dev/null +++ b/Tools/cases_generator/formatting.py @@ -0,0 +1,206 @@ +import contextlib +import re +import typing +from collections.abc import Iterator + +from parsing import StackEffect, Family + +UNUSED = "unused" + + +class Formatter: + """Wraps an output stream with the ability to indent etc.""" + + stream: typing.TextIO + prefix: str + emit_line_directives: bool = False + lineno: int # Next line number, 1-based + filename: str # Slightly improved stream.filename + nominal_lineno: int + nominal_filename: str + + def __init__( + self, + stream: typing.TextIO, + indent: int, + emit_line_directives: bool = False, + comment: str = "//", + ) -> None: + self.stream = stream + self.prefix = " " * indent + self.emit_line_directives = emit_line_directives + self.comment = comment + self.lineno = 1 + self.filename = prettify_filename(self.stream.name) + self.nominal_lineno = 1 + self.nominal_filename = self.filename + + def write_raw(self, s: str) -> None: + self.stream.write(s) + newlines = s.count("\n") + self.lineno += newlines + self.nominal_lineno += newlines + + def emit(self, arg: str) -> None: + if arg: + self.write_raw(f"{self.prefix}{arg}\n") + else: + self.write_raw("\n") + + def set_lineno(self, lineno: int, filename: str) -> None: + if self.emit_line_directives: + if lineno != self.nominal_lineno or filename != self.nominal_filename: + self.emit(f'#line {lineno} "{filename}"') + self.nominal_lineno = lineno + self.nominal_filename = filename + + def reset_lineno(self) -> None: + if self.lineno != self.nominal_lineno or self.filename != self.nominal_filename: + self.set_lineno(self.lineno + 1, self.filename) + + @contextlib.contextmanager + def indent(self) -> Iterator[None]: + self.prefix += " " + yield + self.prefix = self.prefix[:-4] + + @contextlib.contextmanager + def block(self, head: str, tail: str = "") -> Iterator[None]: + if head: + self.emit(head + " {") + else: + self.emit("{") + with self.indent(): + yield + self.emit("}" + tail) + + def stack_adjust( + self, + input_effects: list[StackEffect], + output_effects: list[StackEffect], + ) -> None: + shrink, isym = list_effect_size(input_effects) + grow, osym = list_effect_size(output_effects) + diff = grow - shrink + if isym and isym != osym: + self.emit(f"STACK_SHRINK({isym});") + if diff < 0: + self.emit(f"STACK_SHRINK({-diff});") + if diff > 0: + self.emit(f"STACK_GROW({diff});") + if osym and osym != isym: + self.emit(f"STACK_GROW({osym});") + + def declare(self, dst: StackEffect, src: StackEffect | None) -> None: + if dst.name == UNUSED or dst.cond == "0": + return + typ = f"{dst.type}" if dst.type else "PyObject *" + if src: + cast = self.cast(dst, src) + initexpr = f"{cast}{src.name}" + if src.cond and src.cond != "1": + initexpr = f"{parenthesize_cond(src.cond)} ? {initexpr} : NULL" + init = f" = {initexpr}" + elif dst.cond and dst.cond != "1": + init = " = NULL" + else: + init = "" + sepa = "" if typ.endswith("*") else " " + self.emit(f"{typ}{sepa}{dst.name}{init};") + + def assign(self, dst: StackEffect, src: StackEffect) -> None: + if src.name == UNUSED or dst.name == UNUSED: + return + cast = self.cast(dst, src) + if re.match(r"^REG\(oparg(\d+)\)$", dst.name): + self.emit(f"Py_XSETREF({dst.name}, {cast}{src.name});") + else: + stmt = f"{dst.name} = {cast}{src.name};" + if src.cond and src.cond != "1": + if src.cond == "0": + # It will not be executed + return + stmt = f"if ({src.cond}) {{ {stmt} }}" + self.emit(stmt) + + def cast(self, dst: StackEffect, src: StackEffect) -> str: + return f"({dst.type or 'PyObject *'})" if src.type != dst.type else "" + + def static_assert_family_size( + self, name: str, family: Family | None, cache_offset: int + ) -> None: + """Emit a static_assert for the size of a family, if known. + + This will fail at compile time if the cache size computed from + the instruction definition does not match the size of the struct + used by specialize.c. + """ + if family and name == family.name: + cache_size = family.size + if cache_size: + self.emit( + f"static_assert({cache_size} == {cache_offset}, " + f'"incorrect cache size");' + ) + + +def prettify_filename(filename: str) -> str: + # Make filename more user-friendly and less platform-specific, + # it is only used for error reporting at this point. + filename = filename.replace("\\", "/") + if filename.startswith("./"): + filename = filename[2:] + if filename.endswith(".new"): + filename = filename[:-4] + return filename + + +def list_effect_size(effects: list[StackEffect]) -> tuple[int, str]: + numeric = 0 + symbolic: list[str] = [] + for effect in effects: + diff, sym = effect_size(effect) + numeric += diff + if sym: + symbolic.append(maybe_parenthesize(sym)) + return numeric, " + ".join(symbolic) + + +def effect_size(effect: StackEffect) -> tuple[int, str]: + """Return the 'size' impact of a stack effect. + + Returns a tuple (numeric, symbolic) where: + + - numeric is an int giving the statically analyzable size of the effect + - symbolic is a string representing a variable effect (e.g. 'oparg*2') + + At most one of these will be non-zero / non-empty. + """ + if effect.size: + assert not effect.cond, "Array effects cannot have a condition" + return 0, effect.size + elif effect.cond: + if effect.cond in ("0", "1"): + return int(effect.cond), "" + return 0, f"{maybe_parenthesize(effect.cond)} ? 1 : 0" + else: + return 1, "" + + +def maybe_parenthesize(sym: str) -> str: + """Add parentheses around a string if it contains an operator. + + An exception is made for '*' which is common and harmless + in the context where the symbolic size is used. + """ + if re.match(r"^[\s\w*]+$", sym): + return sym + else: + return f"({sym})" + + +def parenthesize_cond(cond: str) -> str: + """Parenthesize a condition, but only if it contains ?: itself.""" + if "?" in cond: + cond = f"({cond})" + return cond diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py index 33eff548a18809..04d617ba9f5173 100644 --- a/Tools/cases_generator/generate_cases.py +++ b/Tools/cases_generator/generate_cases.py @@ -1,21 +1,37 @@ """Generate the main interpreter switch. - Reads the instruction definitions from bytecodes.c. Writes the cases to generated_cases.c.h, which is #included in ceval.c. """ import argparse import contextlib -import dataclasses +import itertools import os import posixpath -import re import sys +import textwrap import typing +from collections.abc import Iterator + +import stacking # Early import to avoid circular import +from _typing_backports import assert_never +from analysis import Analyzer +from formatting import Formatter, list_effect_size +from flags import InstructionFlags, variable_used +from instructions import ( + AnyInstruction, + AbstractInstruction, + Component, + Instruction, + MacroInstruction, + MacroParts, + PseudoInstruction, + TIER_ONE, + TIER_TWO, +) +import parsing +from parsing import StackEffect -import lexer as lx -import parser -from parser import StackEffect HERE = os.path.dirname(__file__) ROOT = os.path.join(HERE, "../..") @@ -23,6 +39,12 @@ DEFAULT_INPUT = os.path.relpath(os.path.join(ROOT, "Python/bytecodes.c")) DEFAULT_OUTPUT = os.path.relpath(os.path.join(ROOT, "Python/generated_cases.c.h")) +DEFAULT_OPCODE_IDS_H_OUTPUT = os.path.relpath( + os.path.join(ROOT, "Include/opcode_ids.h") +) +DEFAULT_OPCODE_TARGETS_H_OUTPUT = os.path.relpath( + os.path.join(ROOT, "Python/opcode_targets.h") +) DEFAULT_METADATA_OUTPUT = os.path.relpath( os.path.join(ROOT, "Include/internal/pycore_opcode_metadata.h") ) @@ -32,13 +54,9 @@ DEFAULT_EXECUTOR_OUTPUT = os.path.relpath( os.path.join(ROOT, "Python/executor_cases.c.h") ) -BEGIN_MARKER = "// BEGIN BYTECODES //" -END_MARKER = "// END BYTECODES //" -RE_PREDICTED = ( - r"^\s*(?:GO_TO_INSTRUCTION\(|DEOPT_IF\(.*?,\s*)(\w+)\);\s*(?://.*)?$" +DEFAULT_ABSTRACT_INTERPRETER_OUTPUT = os.path.relpath( + os.path.join(ROOT, "Python/abstract_interp_cases.c.h") ) -UNUSED = "unused" -BITS_PER_CODE_UNIT = 16 # Constants used instead of size for macro expansions. # Note: 1, 2, 4 must match actual cache entry sizes. @@ -49,25 +67,67 @@ "OPARG_CACHE_4": 4, "OPARG_TOP": 5, "OPARG_BOTTOM": 6, + "OPARG_SET_IP": 7, } -RESERVED_WORDS = { - "co_consts" : "Use FRAME_CO_CONSTS.", - "co_names": "Use FRAME_CO_NAMES.", +INSTR_FMT_PREFIX = "INSTR_FMT_" + +# TODO: generate all these after updating the DSL +SPECIALLY_HANDLED_ABSTRACT_INSTR = { + "LOAD_FAST", + "LOAD_FAST_CHECK", + "LOAD_FAST_AND_CLEAR", + "LOAD_CONST", + "STORE_FAST", + "STORE_FAST_MAYBE_NULL", + "COPY", + # Arithmetic + "_BINARY_OP_MULTIPLY_INT", + "_BINARY_OP_ADD_INT", + "_BINARY_OP_SUBTRACT_INT", } arg_parser = argparse.ArgumentParser( description="Generate the code for the interpreter switch.", formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) + +arg_parser.add_argument( + "-v", + "--verbose", + help="Print list of non-viable uops and exit", + action="store_true", +) arg_parser.add_argument( "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT ) arg_parser.add_argument( - "-m", "--metadata", type=str, help="Generated C metadata", default=DEFAULT_METADATA_OUTPUT + "-n", + "--opcode_ids_h", + type=str, + help="Header file with opcode number definitions", + default=DEFAULT_OPCODE_IDS_H_OUTPUT, ) arg_parser.add_argument( - "-p", "--pymetadata", type=str, help="Generated Python metadata", default=DEFAULT_PYMETADATA_OUTPUT + "-t", + "--opcode_targets_h", + type=str, + help="File with opcode targets for computed gotos", + default=DEFAULT_OPCODE_TARGETS_H_OUTPUT, +) +arg_parser.add_argument( + "-m", + "--metadata", + type=str, + help="Generated C metadata", + default=DEFAULT_METADATA_OUTPUT, +) +arg_parser.add_argument( + "-p", + "--pymetadata", + type=str, + help="Generated Python metadata", + default=DEFAULT_PYMETADATA_OUTPUT, ) arg_parser.add_argument( "-l", "--emit-line-directives", help="Emit #line directives", action="store_true" @@ -82,969 +142,19 @@ help="Write executor cases to this file", default=DEFAULT_EXECUTOR_OUTPUT, ) - - -def effect_size(effect: StackEffect) -> tuple[int, str]: - """Return the 'size' impact of a stack effect. - - Returns a tuple (numeric, symbolic) where: - - - numeric is an int giving the statically analyzable size of the effect - - symbolic is a string representing a variable effect (e.g. 'oparg*2') - - At most one of these will be non-zero / non-empty. - """ - if effect.size: - assert not effect.cond, "Array effects cannot have a condition" - return 0, effect.size - elif effect.cond: - if effect.cond in ("0", "1"): - return int(effect.cond), "" - return 0, f"{maybe_parenthesize(effect.cond)} ? 1 : 0" - else: - return 1, "" - - -def maybe_parenthesize(sym: str) -> str: - """Add parentheses around a string if it contains an operator. - - An exception is made for '*' which is common and harmless - in the context where the symbolic size is used. - """ - if re.match(r"^[\s\w*]+$", sym): - return sym - else: - return f"({sym})" - - -def list_effect_size(effects: list[StackEffect]) -> tuple[int, str]: - numeric = 0 - symbolic: list[str] = [] - for effect in effects: - diff, sym = effect_size(effect) - numeric += diff - if sym: - symbolic.append(maybe_parenthesize(sym)) - return numeric, " + ".join(symbolic) - - -def string_effect_size(arg: tuple[int, str]) -> str: - numeric, symbolic = arg - if numeric and symbolic: - return f"{numeric} + {symbolic}" - elif symbolic: - return symbolic - else: - return str(numeric) - - -class Formatter: - """Wraps an output stream with the ability to indent etc.""" - - stream: typing.TextIO - prefix: str - emit_line_directives: bool = False - lineno: int # Next line number, 1-based - filename: str # Slightly improved stream.filename - nominal_lineno: int - nominal_filename: str - - def __init__( - self, stream: typing.TextIO, indent: int, - emit_line_directives: bool = False, comment: str = "//", - ) -> None: - self.stream = stream - self.prefix = " " * indent - self.emit_line_directives = emit_line_directives - self.comment = comment - self.lineno = 1 - self.filename = prettify_filename(self.stream.name) - self.nominal_lineno = 1 - self.nominal_filename = self.filename - - def write_raw(self, s: str) -> None: - self.stream.write(s) - newlines = s.count("\n") - self.lineno += newlines - self.nominal_lineno += newlines - - def emit(self, arg: str) -> None: - if arg: - self.write_raw(f"{self.prefix}{arg}\n") - else: - self.write_raw("\n") - - def set_lineno(self, lineno: int, filename: str) -> None: - if self.emit_line_directives: - if lineno != self.nominal_lineno or filename != self.nominal_filename: - self.emit(f'#line {lineno} "{filename}"') - self.nominal_lineno = lineno - self.nominal_filename = filename - - def reset_lineno(self) -> None: - if self.lineno != self.nominal_lineno or self.filename != self.nominal_filename: - self.set_lineno(self.lineno + 1, self.filename) - - @contextlib.contextmanager - def indent(self): - self.prefix += " " - yield - self.prefix = self.prefix[:-4] - - @contextlib.contextmanager - def block(self, head: str, tail: str = ""): - if head: - self.emit(head + " {") - else: - self.emit("{") - with self.indent(): - yield - self.emit("}" + tail) - - def stack_adjust( - self, - input_effects: list[StackEffect], - output_effects: list[StackEffect], - ): - shrink, isym = list_effect_size(input_effects) - grow, osym = list_effect_size(output_effects) - diff = grow - shrink - if isym and isym != osym: - self.emit(f"STACK_SHRINK({isym});") - if diff < 0: - self.emit(f"STACK_SHRINK({-diff});") - if diff > 0: - self.emit(f"STACK_GROW({diff});") - if osym and osym != isym: - self.emit(f"STACK_GROW({osym});") - - def declare(self, dst: StackEffect, src: StackEffect | None): - if dst.name == UNUSED or dst.cond == "0": - return - typ = f"{dst.type}" if dst.type else "PyObject *" - if src: - cast = self.cast(dst, src) - init = f" = {cast}{src.name}" - elif dst.cond: - init = " = NULL" - else: - init = "" - sepa = "" if typ.endswith("*") else " " - self.emit(f"{typ}{sepa}{dst.name}{init};") - - def assign(self, dst: StackEffect, src: StackEffect): - if src.name == UNUSED: - return - if src.size: - # Don't write sized arrays -- it's up to the user code. - return - cast = self.cast(dst, src) - if re.match(r"^REG\(oparg(\d+)\)$", dst.name): - self.emit(f"Py_XSETREF({dst.name}, {cast}{src.name});") - else: - stmt = f"{dst.name} = {cast}{src.name};" - if src.cond and src.cond != "1": - if src.cond == "0": - # It will not be executed - return - stmt = f"if ({src.cond}) {{ {stmt} }}" - self.emit(stmt) - - def cast(self, dst: StackEffect, src: StackEffect) -> str: - return f"({dst.type or 'PyObject *'})" if src.type != dst.type else "" - -@dataclasses.dataclass -class InstructionFlags: - """Construct and manipulate instruction flags""" - - HAS_ARG_FLAG: bool - HAS_CONST_FLAG: bool - HAS_NAME_FLAG: bool - HAS_JUMP_FLAG: bool - HAS_FREE_FLAG: bool - HAS_LOCAL_FLAG: bool - - def __post_init__(self): - self.bitmask = { - name : (1 << i) for i, name in enumerate(self.names()) - } - - @staticmethod - def fromInstruction(instr: "AnyInstruction"): - - has_free = (variable_used(instr, "PyCell_New") or - variable_used(instr, "PyCell_GET") or - variable_used(instr, "PyCell_SET")) - - return InstructionFlags( - HAS_ARG_FLAG=variable_used(instr, "oparg"), - HAS_CONST_FLAG=variable_used(instr, "FRAME_CO_CONSTS"), - HAS_NAME_FLAG=variable_used(instr, "FRAME_CO_NAMES"), - HAS_JUMP_FLAG=variable_used(instr, "JUMPBY"), - HAS_FREE_FLAG=has_free, - HAS_LOCAL_FLAG=(variable_used(instr, "GETLOCAL") or - variable_used(instr, "SETLOCAL")) and - not has_free, - ) - - @staticmethod - def newEmpty(): - return InstructionFlags(False, False, False, False, False, False) - - def add(self, other: "InstructionFlags") -> None: - for name, value in dataclasses.asdict(other).items(): - if value: - setattr(self, name, value) - - def names(self, value=None): - if value is None: - return dataclasses.asdict(self).keys() - return [n for n, v in dataclasses.asdict(self).items() if v == value] - - def bitmap(self) -> int: - flags = 0 - for name in self.names(): - if getattr(self, name): - flags |= self.bitmask[name] - return flags - - @classmethod - def emit_macros(cls, out: Formatter): - flags = cls.newEmpty() - for name, value in flags.bitmask.items(): - out.emit(f"#define {name} ({value})"); - - for name, value in flags.bitmask.items(): - out.emit( - f"#define OPCODE_{name[:-len('_FLAG')]}(OP) " - f"(_PyOpcode_opcode_metadata[OP].flags & ({name}))") - - -@dataclasses.dataclass -class ActiveCacheEffect: - """Wraps a CacheEffect that is actually used, in context.""" - effect: parser.CacheEffect - offset: int - - -FORBIDDEN_NAMES_IN_UOPS = ( - "resume_with_error", - "kwnames", - "next_instr", - "oparg1", # Proxy for super-instructions like LOAD_FAST_LOAD_FAST - "JUMPBY", - "DISPATCH", - "INSTRUMENTED_JUMP", - "throwflag", - "exception_unwind", - "import_from", - "import_name", - "_PyObject_CallNoArgs", # Proxy for BEFORE_WITH +arg_parser.add_argument( + "-a", + "--abstract-interpreter-cases", + type=str, + help="Write abstract interpreter cases to this file", + default=DEFAULT_ABSTRACT_INTERPRETER_OUTPUT, ) -# Interpreter tiers -TIER_ONE = 1 # Specializing adaptive interpreter (PEP 659) -TIER_TWO = 2 # Experimental tracing interpreter -Tiers: typing.TypeAlias = typing.Literal[1, 2] - - -@dataclasses.dataclass -class Instruction: - """An instruction with additional data and code.""" - - # Parts of the underlying instruction definition - inst: parser.InstDef - kind: typing.Literal["inst", "op"] - name: str - block: parser.Block - block_text: list[str] # Block.text, less curlies, less PREDICT() calls - block_line: int # First line of block in original code - - # Computed by constructor - always_exits: bool - cache_offset: int - cache_effects: list[parser.CacheEffect] - input_effects: list[StackEffect] - output_effects: list[StackEffect] - unmoved_names: frozenset[str] - instr_fmt: str - instr_flags: InstructionFlags - active_caches: list[ActiveCacheEffect] - - # Set later - family: parser.Family | None = None - predicted: bool = False - - def __init__(self, inst: parser.InstDef): - self.inst = inst - self.kind = inst.kind - self.name = inst.name - self.block = inst.block - self.block_text, self.check_eval_breaker, self.block_line = \ - extract_block_text(self.block) - self.always_exits = always_exits(self.block_text) - self.cache_effects = [ - effect for effect in inst.inputs if isinstance(effect, parser.CacheEffect) - ] - self.cache_offset = sum(c.size for c in self.cache_effects) - self.input_effects = [ - effect for effect in inst.inputs if isinstance(effect, StackEffect) - ] - self.output_effects = inst.outputs # For consistency/completeness - unmoved_names: set[str] = set() - for ieffect, oeffect in zip(self.input_effects, self.output_effects): - if ieffect.name == oeffect.name: - unmoved_names.add(ieffect.name) - else: - break - self.unmoved_names = frozenset(unmoved_names) - - self.instr_flags = InstructionFlags.fromInstruction(inst) - - self.active_caches = [] - offset = 0 - for effect in self.cache_effects: - if effect.name != UNUSED: - self.active_caches.append(ActiveCacheEffect(effect, offset)) - offset += effect.size - - if self.instr_flags.HAS_ARG_FLAG: - fmt = "IB" - else: - fmt = "IX" - if offset: - fmt += "C" + "0"*(offset-1) - self.instr_fmt = fmt - - def is_viable_uop(self) -> bool: - """Whether this instruction is viable as a uop.""" - dprint: typing.Callable[..., None] = lambda *args, **kwargs: None - # if self.name.startswith("CALL"): - # dprint = print - - if self.name == "EXIT_TRACE": - return True # This has 'return frame' but it's okay - if self.always_exits: - dprint(f"Skipping {self.name} because it always exits") - return False - if len(self.active_caches) > 1: - # print(f"Skipping {self.name} because it has >1 cache entries") - return False - res = True - for forbidden in FORBIDDEN_NAMES_IN_UOPS: - # NOTE: To disallow unspecialized uops, use - # if variable_used(self.inst, forbidden): - if variable_used_unspecialized(self.inst, forbidden): - dprint(f"Skipping {self.name} because it uses {forbidden}") - res = False - return res - - def write(self, out: Formatter, tier: Tiers = TIER_ONE) -> None: - """Write one instruction, sans prologue and epilogue.""" - # Write a static assertion that a family's cache size is correct - if family := self.family: - if self.name == family.name: - if cache_size := family.size: - out.emit( - f"static_assert({cache_size} == " - f'{self.cache_offset}, "incorrect cache size");' - ) - - # Write input stack effect variable declarations and initializations - ieffects = list(reversed(self.input_effects)) - for i, ieffect in enumerate(ieffects): - isize = string_effect_size( - list_effect_size([ieff for ieff in ieffects[: i + 1]]) - ) - if ieffect.size: - src = StackEffect(f"(stack_pointer - {maybe_parenthesize(isize)})", "PyObject **") - elif ieffect.cond: - src = StackEffect(f"({ieffect.cond}) ? stack_pointer[-{maybe_parenthesize(isize)}] : NULL", "") - else: - src = StackEffect(f"stack_pointer[-{maybe_parenthesize(isize)}]", "") - out.declare(ieffect, src) - - # Write output stack effect variable declarations - isize = string_effect_size(list_effect_size(self.input_effects)) - input_names = {ieffect.name for ieffect in self.input_effects} - for i, oeffect in enumerate(self.output_effects): - if oeffect.name not in input_names: - if oeffect.size: - osize = string_effect_size( - list_effect_size([oeff for oeff in self.output_effects[:i]]) - ) - offset = "stack_pointer" - if isize != osize: - if isize != "0": - offset += f" - ({isize})" - if osize != "0": - offset += f" + {osize}" - src = StackEffect(offset, "PyObject **") - out.declare(oeffect, src) - else: - out.declare(oeffect, None) - - # out.emit(f"next_instr += OPSIZE({self.inst.name}) - 1;") - - self.write_body(out, 0, self.active_caches, tier=tier) - - # Skip the rest if the block always exits - if self.always_exits: - return - - # Write net stack growth/shrinkage - out.stack_adjust( - [ieff for ieff in self.input_effects], - [oeff for oeff in self.output_effects], - ) - - # Write output stack effect assignments - oeffects = list(reversed(self.output_effects)) - for i, oeffect in enumerate(oeffects): - if oeffect.name in self.unmoved_names: - continue - osize = string_effect_size( - list_effect_size([oeff for oeff in oeffects[: i + 1]]) - ) - if oeffect.size: - dst = StackEffect(f"stack_pointer - {maybe_parenthesize(osize)}", "PyObject **") - else: - dst = StackEffect(f"stack_pointer[-{maybe_parenthesize(osize)}]", "") - out.assign(dst, oeffect) - - # Write cache effect - if tier == TIER_ONE and self.cache_offset: - out.emit(f"next_instr += {self.cache_offset};") - - def write_body( - self, - out: Formatter, - dedent: int, - active_caches: list[ActiveCacheEffect], - tier: Tiers = TIER_ONE, - ) -> None: - """Write the instruction body.""" - # Write cache effect variable declarations and initializations - for active in active_caches: - ceffect = active.effect - bits = ceffect.size * BITS_PER_CODE_UNIT - if bits == 64: - # NOTE: We assume that 64-bit data in the cache - # is always an object pointer. - # If this becomes false, we need a way to specify - # syntactically what type the cache data is. - typ = "PyObject *" - func = "read_obj" - else: - typ = f"uint{bits}_t " - func = f"read_u{bits}" - if tier == TIER_ONE: - out.emit( - f"{typ}{ceffect.name} = {func}(&next_instr[{active.offset}].cache);" - ) - else: - out.emit(f"{typ}{ceffect.name} = ({typ.strip()})operand;") - - # Write the body, substituting a goto for ERROR_IF() and other stuff - assert dedent <= 0 - extra = " " * -dedent - names_to_skip = self.unmoved_names | frozenset({UNUSED, "null"}) - offset = 0 - context = self.block.context - assert context is not None and context.owner is not None - filename = context.owner.filename - for line in self.block_text: - out.set_lineno(self.block_line + offset, filename) - offset += 1 - if m := re.match(r"(\s*)ERROR_IF\((.+), (\w+)\);\s*(?://.*)?$", line): - space, cond, label = m.groups() - space = extra + space - # ERROR_IF() must pop the inputs from the stack. - # The code block is responsible for DECREF()ing them. - # NOTE: If the label doesn't exist, just add it to ceval.c. - - # Don't pop common input/output effects at the bottom! - # These aren't DECREF'ed so they can stay. - ieffs = list(self.input_effects) - oeffs = list(self.output_effects) - while ieffs and oeffs and ieffs[0] == oeffs[0]: - ieffs.pop(0) - oeffs.pop(0) - ninputs, symbolic = list_effect_size(ieffs) - if ninputs: - label = f"pop_{ninputs}_{label}" - if symbolic: - out.write_raw( - f"{space}if ({cond}) {{ STACK_SHRINK({symbolic}); goto {label}; }}\n" - ) - else: - out.write_raw(f"{space}if ({cond}) goto {label};\n") - elif m := re.match(r"(\s*)DECREF_INPUTS\(\);\s*(?://.*)?$", line): - out.reset_lineno() - space = extra + m.group(1) - for ieff in self.input_effects: - if ieff.name in names_to_skip: - continue - if ieff.size: - out.write_raw( - f"{space}for (int _i = {ieff.size}; --_i >= 0;) {{\n" - ) - out.write_raw(f"{space} Py_DECREF({ieff.name}[_i]);\n") - out.write_raw(f"{space}}}\n") - else: - decref = "XDECREF" if ieff.cond else "DECREF" - out.write_raw(f"{space}Py_{decref}({ieff.name});\n") - else: - out.write_raw(extra + line) - out.reset_lineno() - - -InstructionOrCacheEffect = Instruction | parser.CacheEffect -StackEffectMapping = list[tuple[StackEffect, StackEffect]] - - -@dataclasses.dataclass -class Component: - instr: Instruction - input_mapping: StackEffectMapping - output_mapping: StackEffectMapping - active_caches: list[ActiveCacheEffect] - - def write_body(self, out: Formatter) -> None: - with out.block(""): - input_names = {ieffect.name for _, ieffect in self.input_mapping} - for var, ieffect in self.input_mapping: - out.declare(ieffect, var) - for _, oeffect in self.output_mapping: - if oeffect.name not in input_names: - out.declare(oeffect, None) - - self.instr.write_body(out, -4, self.active_caches) - - for var, oeffect in self.output_mapping: - out.assign(var, oeffect) - - -MacroParts = list[Component | parser.CacheEffect] - - -@dataclasses.dataclass -class MacroInstruction: - """A macro instruction.""" - - name: str - stack: list[StackEffect] - initial_sp: int - final_sp: int - instr_fmt: str - instr_flags: InstructionFlags - macro: parser.Macro - parts: MacroParts - cache_offset: int - predicted: bool = False - - -@dataclasses.dataclass -class PseudoInstruction: - """A pseudo instruction.""" - - name: str - targets: list[Instruction] - instr_fmt: str - instr_flags: InstructionFlags - - -@dataclasses.dataclass -class OverriddenInstructionPlaceHolder: - name: str - - -AnyInstruction = Instruction | MacroInstruction | PseudoInstruction -INSTR_FMT_PREFIX = "INSTR_FMT_" - - -class Analyzer: - """Parse input, analyze it, and write to output.""" - - input_filenames: list[str] - output_filename: str - metadata_filename: str - pymetadata_filename: str - executor_filename: str - errors: int = 0 - emit_line_directives: bool = False - - def __init__( - self, - input_filenames: list[str], - output_filename: str, - metadata_filename: str, - pymetadata_filename: str, - executor_filename: str, - ): - """Read the input file.""" - self.input_filenames = input_filenames - self.output_filename = output_filename - self.metadata_filename = metadata_filename - self.pymetadata_filename = pymetadata_filename - self.executor_filename = executor_filename - - def error(self, msg: str, node: parser.Node) -> None: - lineno = 0 - filename = "" - if context := node.context: - filename = context.owner.filename - # Use line number of first non-comment in the node - for token in context.owner.tokens[context.begin : context.end]: - lineno = token.line - if token.kind != "COMMENT": - break - print(f"{filename}:{lineno}: {msg}", file=sys.stderr) - self.errors += 1 - - everything: list[ - parser.InstDef | parser.Macro | parser.Pseudo | OverriddenInstructionPlaceHolder - ] - instrs: dict[str, Instruction] # Includes ops - macros: dict[str, parser.Macro] - macro_instrs: dict[str, MacroInstruction] - families: dict[str, parser.Family] - pseudos: dict[str, parser.Pseudo] - pseudo_instrs: dict[str, PseudoInstruction] - - def parse(self) -> None: - """Parse the source text. - - We only want the parser to see the stuff between the - begin and end markers. - """ - - self.everything = [] - self.instrs = {} - self.macros = {} - self.families = {} - self.pseudos = {} - - instrs_idx: dict[str, int] = dict() - - for filename in self.input_filenames: - self.parse_file(filename, instrs_idx) - - files = " + ".join(self.input_filenames) - print( - f"Read {len(self.instrs)} instructions/ops, " - f"{len(self.macros)} macros, {len(self.pseudos)} pseudos, " - f"and {len(self.families)} families from {files}", - file=sys.stderr, - ) - - def parse_file(self, filename: str, instrs_idx: dict[str, int]) -> None: - with open(filename) as file: - src = file.read() - - - psr = parser.Parser(src, filename=prettify_filename(filename)) - - # Skip until begin marker - while tkn := psr.next(raw=True): - if tkn.text == BEGIN_MARKER: - break - else: - raise psr.make_syntax_error( - f"Couldn't find {BEGIN_MARKER!r} in {psr.filename}" - ) - start = psr.getpos() - - # Find end marker, then delete everything after it - while tkn := psr.next(raw=True): - if tkn.text == END_MARKER: - break - del psr.tokens[psr.getpos() - 1 :] - - # Parse from start - psr.setpos(start) - thing: parser.InstDef | parser.Macro | parser.Pseudo | parser.Family | None - thing_first_token = psr.peek() - while thing := psr.definition(): - if ws := [w for w in RESERVED_WORDS if variable_used(thing, w)]: - self.error(f"'{ws[0]}' is a reserved word. {RESERVED_WORDS[ws[0]]}", thing) - - match thing: - case parser.InstDef(name=name): - if name in self.instrs: - if not thing.override: - raise psr.make_syntax_error( - f"Duplicate definition of '{name}' @ {thing.context} " - f"previous definition @ {self.instrs[name].inst.context}", - thing_first_token, - ) - self.everything[instrs_idx[name]] = OverriddenInstructionPlaceHolder(name=name) - if name not in self.instrs and thing.override: - raise psr.make_syntax_error( - f"Definition of '{name}' @ {thing.context} is supposed to be " - "an override but no previous definition exists.", - thing_first_token, - ) - self.instrs[name] = Instruction(thing) - instrs_idx[name] = len(self.everything) - self.everything.append(thing) - case parser.Macro(name): - self.macros[name] = thing - self.everything.append(thing) - case parser.Family(name): - self.families[name] = thing - case parser.Pseudo(name): - self.pseudos[name] = thing - self.everything.append(thing) - case _: - typing.assert_never(thing) - if not psr.eof(): - raise psr.make_syntax_error(f"Extra stuff at the end of {filename}") - - def analyze(self) -> None: - """Analyze the inputs. - - Raises SystemExit if there is an error. - """ - self.analyze_macros_and_pseudos() - self.find_predictions() - self.map_families() - self.check_families() - - def find_predictions(self) -> None: - """Find the instructions that need PREDICTED() labels.""" - for instr in self.instrs.values(): - targets: set[str] = set() - for line in instr.block_text: - if m := re.match(RE_PREDICTED, line): - targets.add(m.group(1)) - for target in targets: - if target_instr := self.instrs.get(target): - target_instr.predicted = True - elif target_macro := self.macro_instrs.get(target): - target_macro.predicted = True - else: - self.error( - f"Unknown instruction {target!r} predicted in {instr.name!r}", - instr.inst, # TODO: Use better location - ) - - def map_families(self) -> None: - """Link instruction names back to their family, if they have one.""" - for family in self.families.values(): - for member in [family.name] + family.members: - if member_instr := self.instrs.get(member): - if member_instr.family not in (family, None): - self.error( - f"Instruction {member} is a member of multiple families " - f"({member_instr.family.name}, {family.name}).", - family, - ) - else: - member_instr.family = family - elif not self.macro_instrs.get(member): - self.error( - f"Unknown instruction {member!r} referenced in family {family.name!r}", - family, - ) - - def check_families(self) -> None: - """Check each family: - - - Must have at least 2 members (including head) - - Head and all members must be known instructions - - Head and all members must have the same cache, input and output effects - """ - for family in self.families.values(): - if family.name not in self.macro_instrs and family.name not in self.instrs: - self.error( - f"Family {family.name!r} has unknown instruction {family.name!r}", - family, - ) - members = [ - member - for member in family.members - if member in self.instrs or member in self.macro_instrs - ] - if members != family.members: - unknown = set(family.members) - set(members) - self.error( - f"Family {family.name!r} has unknown members: {unknown}", family - ) - expected_effects = self.effect_counts(family.name) - for member in members: - member_effects = self.effect_counts(member) - if member_effects != expected_effects: - self.error( - f"Family {family.name!r} has inconsistent " - f"(cache, input, output) effects:\n" - f" {family.name} = {expected_effects}; " - f"{member} = {member_effects}", - family, - ) - - def effect_counts(self, name: str) -> tuple[int, int, int]: - if instr := self.instrs.get(name): - cache = instr.cache_offset - input = len(instr.input_effects) - output = len(instr.output_effects) - elif mac := self.macro_instrs.get(name): - cache = mac.cache_offset - input, output = 0, 0 - for part in mac.parts: - if isinstance(part, Component): - # A component may pop what the previous component pushed, - # so we offset the input/output counts by that. - delta_i = len(part.instr.input_effects) - delta_o = len(part.instr.output_effects) - offset = min(delta_i, output) - input += delta_i - offset - output += delta_o - offset - else: - assert False, f"Unknown instruction {name!r}" - return cache, input, output - - def analyze_macros_and_pseudos(self) -> None: - """Analyze each macro and pseudo instruction.""" - self.macro_instrs = {} - self.pseudo_instrs = {} - for name, macro in self.macros.items(): - self.macro_instrs[name] = self.analyze_macro(macro) - for name, pseudo in self.pseudos.items(): - self.pseudo_instrs[name] = self.analyze_pseudo(pseudo) - - def analyze_macro(self, macro: parser.Macro) -> MacroInstruction: - components = self.check_macro_components(macro) - stack, initial_sp = self.stack_analysis(components) - sp = initial_sp - parts: MacroParts = [] - flags = InstructionFlags.newEmpty() - offset = 0 - for component in components: - match component: - case parser.CacheEffect() as ceffect: - parts.append(ceffect) - offset += ceffect.size - case Instruction() as instr: - part, sp, offset = self.analyze_instruction(instr, stack, sp, offset) - parts.append(part) - flags.add(instr.instr_flags) - case _: - typing.assert_never(component) - final_sp = sp - format = "IB" - if offset: - format += "C" + "0"*(offset-1) - return MacroInstruction( - macro.name, stack, initial_sp, final_sp, format, flags, macro, parts, offset - ) - - def analyze_pseudo(self, pseudo: parser.Pseudo) -> PseudoInstruction: - targets = [self.instrs[target] for target in pseudo.targets] - assert targets - # Make sure the targets have the same fmt - fmts = list(set([t.instr_fmt for t in targets])) - assert(len(fmts) == 1) - assert(len(list(set([t.instr_flags.bitmap() for t in targets]))) == 1) - return PseudoInstruction(pseudo.name, targets, fmts[0], targets[0].instr_flags) - - def analyze_instruction( - self, instr: Instruction, stack: list[StackEffect], sp: int, offset: int - ) -> tuple[Component, int, int]: - input_mapping: StackEffectMapping = [] - for ieffect in reversed(instr.input_effects): - sp -= 1 - input_mapping.append((stack[sp], ieffect)) - output_mapping: StackEffectMapping = [] - for oeffect in instr.output_effects: - output_mapping.append((stack[sp], oeffect)) - sp += 1 - active_effects: list[ActiveCacheEffect] = [] - for ceffect in instr.cache_effects: - if ceffect.name != UNUSED: - active_effects.append(ActiveCacheEffect(ceffect, offset)) - offset += ceffect.size - return Component(instr, input_mapping, output_mapping, active_effects), sp, offset - - def check_macro_components( - self, macro: parser.Macro - ) -> list[InstructionOrCacheEffect]: - components: list[InstructionOrCacheEffect] = [] - for uop in macro.uops: - match uop: - case parser.OpName(name): - if name not in self.instrs: - self.error(f"Unknown instruction {name!r}", macro) - components.append(self.instrs[name]) - case parser.CacheEffect(): - components.append(uop) - case _: - typing.assert_never(uop) - return components - - def stack_analysis( - self, components: typing.Iterable[InstructionOrCacheEffect] - ) -> tuple[list[StackEffect], int]: - """Analyze a macro. - - Ignore cache effects. - - Return the list of variables (as StackEffects) and the initial stack pointer. - """ - lowest = current = highest = 0 - conditions: dict[int, str] = {} # Indexed by 'current'. - last_instr: Instruction | None = None - for thing in components: - if isinstance(thing, Instruction): - last_instr = thing - for thing in components: - match thing: - case Instruction() as instr: - if any( - eff.size for eff in instr.input_effects + instr.output_effects - ): - # TODO: Eventually this will be needed, at least for macros. - self.error( - f"Instruction {instr.name!r} has variable-sized stack effect, " - "which are not supported in macro instructions", - instr.inst, # TODO: Pass name+location of macro - ) - if any(eff.cond for eff in instr.input_effects): - self.error( - f"Instruction {instr.name!r} has conditional input stack effect, " - "which are not supported in macro instructions", - instr.inst, # TODO: Pass name+location of macro - ) - if any(eff.cond for eff in instr.output_effects) and instr is not last_instr: - self.error( - f"Instruction {instr.name!r} has conditional output stack effect, " - "but is not the last instruction in a macro", - instr.inst, # TODO: Pass name+location of macro - ) - current -= len(instr.input_effects) - lowest = min(lowest, current) - for eff in instr.output_effects: - if eff.cond: - conditions[current] = eff.cond - current += 1 - highest = max(highest, current) - case parser.CacheEffect(): - pass - case _: - typing.assert_never(thing) - # At this point, 'current' is the net stack effect, - # and 'lowest' and 'highest' are the extremes. - # Note that 'lowest' may be negative. - stack = [ - StackEffect(f"_tmp_{i}", "", conditions.get(highest - i, "")) - for i in reversed(range(1, highest - lowest + 1)) - ] - return stack, -lowest - +class Generator(Analyzer): def get_stack_effect_info( - self, thing: parser.InstDef | parser.Macro | parser.Pseudo - ) -> tuple[AnyInstruction | None, str | None, str | None]: + self, thing: parsing.InstDef | parsing.Macro | parsing.Pseudo + ) -> tuple[AnyInstruction | None, str, str]: def effect_str(effects: list[StackEffect]) -> str: n_effect, sym_effect = list_effect_size(effects) if sym_effect: @@ -1052,53 +162,19 @@ def effect_str(effects: list[StackEffect]) -> str: return str(n_effect) instr: AnyInstruction | None + popped: str | None = None + pushed: str | None = None match thing: - case parser.InstDef(): - if thing.kind != "op": - instr = self.instrs[thing.name] - popped = effect_str(instr.input_effects) - pushed = effect_str(instr.output_effects) - else: - instr = None - popped = "" - pushed = "" - case parser.Macro(): + case parsing.InstDef(): + instr = self.instrs[thing.name] + popped = effect_str(instr.input_effects) + pushed = effect_str(instr.output_effects) + case parsing.Macro(): instr = self.macro_instrs[thing.name] - parts = [comp for comp in instr.parts if isinstance(comp, Component)] - # Note: stack_analysis() already verifies that macro components - # have no variable-sized stack effects. - low = 0 - sp = 0 - high = 0 - pushed_symbolic: list[str] = [] - for comp in parts: - for effect in comp.instr.input_effects: - assert not effect.cond, effect - assert not effect.size, effect - sp -= 1 - low = min(low, sp) - for effect in comp.instr.output_effects: - assert not effect.size, effect - if effect.cond: - if effect.cond in ("0", "1"): - pushed_symbolic.append(effect.cond) - else: - pushed_symbolic.append(maybe_parenthesize(f"{maybe_parenthesize(effect.cond)} ? 1 : 0")) - sp += 1 - high = max(sp, high) - if high != max(0, sp): - # If you get this, intermediate stack growth occurs, - # and stack size calculations may go awry. - # E.g. [push, pop]. The fix would be for stack size - # calculations to use the micro ops. - self.error("Macro has virtual stack growth", thing) - popped = str(-low) - pushed_symbolic.append(str(sp - low - len(pushed_symbolic))) - pushed = " + ".join(pushed_symbolic) - case parser.Pseudo(): + popped, pushed = stacking.get_stack_effect_info_for_macro(instr) + case parsing.Pseudo(): instr = self.pseudo_instrs[thing.name] - popped = pushed = None - # Calculate stack effect, and check that it's the the same + # Calculate stack effect, and check that it's the same # for all targets. for target in self.pseudos[thing.name].targets: target_instr = self.instrs.get(target) @@ -1108,77 +184,217 @@ def effect_str(effects: list[StackEffect]) -> str: assert target_instr target_popped = effect_str(target_instr.input_effects) target_pushed = effect_str(target_instr.output_effects) - if popped is None and pushed is None: + if popped is None: popped, pushed = target_popped, target_pushed else: assert popped == target_popped assert pushed == target_pushed case _: - typing.assert_never(thing) + assert_never(thing) + assert popped is not None and pushed is not None return instr, popped, pushed + @contextlib.contextmanager + def metadata_item(self, signature: str, open: str, close: str) -> Iterator[None]: + self.out.emit("") + self.out.emit(f"extern {signature};") + self.out.emit("#ifdef NEED_OPCODE_METADATA") + with self.out.block(f"{signature} {open}", close): + yield + self.out.emit("#endif // NEED_OPCODE_METADATA") + def write_stack_effect_functions(self) -> None: popped_data: list[tuple[AnyInstruction, str]] = [] pushed_data: list[tuple[AnyInstruction, str]] = [] for thing in self.everything: - if isinstance(thing, OverriddenInstructionPlaceHolder): + if isinstance(thing, parsing.Macro) and thing.name in self.instrs: continue instr, popped, pushed = self.get_stack_effect_info(thing) if instr is not None: - assert popped is not None and pushed is not None popped_data.append((instr, popped)) pushed_data.append((instr, pushed)) def write_function( direction: str, data: list[tuple[AnyInstruction, str]] ) -> None: - self.out.emit("") - self.out.emit("#ifndef NEED_OPCODE_METADATA") - self.out.emit(f"extern int _PyOpcode_num_{direction}(int opcode, int oparg, bool jump);") - self.out.emit("#else") - self.out.emit("int") - self.out.emit(f"_PyOpcode_num_{direction}(int opcode, int oparg, bool jump) {{") - self.out.emit(" switch(opcode) {") - for instr, effect in data: - self.out.emit(f" case {instr.name}:") - self.out.emit(f" return {effect};") - self.out.emit(" default:") - self.out.emit(" return -1;") - self.out.emit(" }") - self.out.emit("}") - self.out.emit("#endif") + with self.metadata_item( + f"int _PyOpcode_num_{direction}(int opcode, int oparg, bool jump)", + "", + "", + ): + with self.out.block("switch(opcode)"): + for instr, effect in data: + self.out.emit(f"case {instr.name}:") + self.out.emit(f" return {effect};") + self.out.emit("default:") + self.out.emit(" return -1;") write_function("popped", popped_data) write_function("pushed", pushed_data) self.out.emit("") def from_source_files(self) -> str: - paths = f"\n{self.out.comment} ".join( - prettify_filename(filename) - for filename in self.input_filenames - ) + filenames = [] + for filename in self.input_filenames: + try: + filename = os.path.relpath(filename, ROOT) + except ValueError: + # May happen on Windows if root and temp on different volumes + pass + filenames.append(filename.replace(os.path.sep, posixpath.sep)) + paths = f"\n{self.out.comment} ".join(filenames) return f"{self.out.comment} from:\n{self.out.comment} {paths}\n" - def write_provenance_header(self): + def write_provenance_header(self) -> None: self.out.write_raw(f"{self.out.comment} This file is generated by {THIS}\n") self.out.write_raw(self.from_source_files()) self.out.write_raw(f"{self.out.comment} Do not edit!\n") - def write_metadata(self) -> None: + def assign_opcode_ids(self) -> None: + """Assign IDs to opcodes""" + + ops: list[tuple[bool, str]] = [] # (has_arg, name) for each opcode + instrumented_ops: list[str] = [] + + specialized_ops: set[str] = set() + for name, family in self.families.items(): + specialized_ops.update(family.members) + + for instr in self.macro_instrs.values(): + name = instr.name + if name in specialized_ops: + continue + if name.startswith("INSTRUMENTED_"): + instrumented_ops.append(name) + else: + ops.append((instr.instr_flags.HAS_ARG_FLAG, name)) + + # Special case: this instruction is implemented in ceval.c + # rather than bytecodes.c, so we need to add it explicitly + # here (at least until we add something to bytecodes.c to + # declare external instructions). + instrumented_ops.append("INSTRUMENTED_LINE") + + # assert lists are unique + assert len(set(ops)) == len(ops) + assert len(set(instrumented_ops)) == len(instrumented_ops) + + opname: list[str | None] = [None] * 512 + opmap: dict[str, int] = {} + markers: dict[str, int] = {} + + def map_op(op: int, name: str) -> None: + assert op < len(opname) + assert opname[op] is None, (op, name) + assert name not in opmap + opname[op] = name + opmap[name] = op + + # 0 is reserved for cache entries. This helps debugging. + map_op(0, "CACHE") + + # 17 is reserved as it is the initial value for the specializing counter. + # This helps catch cases where we attempt to execute a cache. + map_op(17, "RESERVED") + + # 149 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py + map_op(149, "RESUME") + + # Specialized ops appear in their own section + # Instrumented opcodes are at the end of the valid range + min_internal = 150 + min_instrumented = 254 - (len(instrumented_ops) - 1) + assert min_internal + len(specialized_ops) < min_instrumented + + next_opcode = 1 + for has_arg, name in sorted(ops): + if name in opmap: + continue # an anchored name, like CACHE + map_op(next_opcode, name) + if has_arg and "HAVE_ARGUMENT" not in markers: + markers["HAVE_ARGUMENT"] = next_opcode + + while opname[next_opcode] is not None: + next_opcode += 1 + + assert next_opcode < min_internal, next_opcode + + for i, op in enumerate(sorted(specialized_ops)): + map_op(min_internal + i, op) + + markers["MIN_INSTRUMENTED_OPCODE"] = min_instrumented + for i, op in enumerate(instrumented_ops): + map_op(min_instrumented + i, op) + + # Pseudo opcodes are after the valid range + for i, op in enumerate(sorted(self.pseudos)): + map_op(256 + i, op) + + assert 255 not in opmap.values() # 255 is reserved + self.opmap = opmap + self.markers = markers + + def write_opcode_ids( + self, opcode_ids_h_filename: str, opcode_targets_filename: str + ) -> None: + """Write header file that defined the opcode IDs""" + + with open(opcode_ids_h_filename, "w") as f: + # Create formatter + self.out = Formatter(f, 0) + + self.write_provenance_header() + + self.out.emit("") + self.out.emit("#ifndef Py_OPCODE_IDS_H") + self.out.emit("#define Py_OPCODE_IDS_H") + self.out.emit("#ifdef __cplusplus") + self.out.emit('extern "C" {') + self.out.emit("#endif") + self.out.emit("") + self.out.emit("/* Instruction opcodes for compiled code */") + + def define(name: str, opcode: int) -> None: + self.out.emit(f"#define {name:<38} {opcode:>3}") + + all_pairs: list[tuple[int, int, str]] = [] + # the second item in the tuple sorts the markers before the ops + all_pairs.extend((i, 1, name) for (name, i) in self.markers.items()) + all_pairs.extend((i, 2, name) for (name, i) in self.opmap.items()) + for i, _, name in sorted(all_pairs): + assert name is not None + define(name, i) + + self.out.emit("") + self.out.emit("#ifdef __cplusplus") + self.out.emit("}") + self.out.emit("#endif") + self.out.emit("#endif /* !Py_OPCODE_IDS_H */") + + with open(opcode_targets_filename, "w") as f: + # Create formatter + self.out = Formatter(f, 0) + + with self.out.block("static void *opcode_targets[256] =", ";"): + targets = ["_unknown_opcode"] * 256 + for name, op in self.opmap.items(): + if op < 256: + targets[op] = f"TARGET_{name}" + f.write(",\n".join([f" &&{s}" for s in targets])) + + def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> None: """Write instruction metadata to output file.""" # Compute the set of all instruction formats. all_formats: set[str] = set() for thing in self.everything: + format: str | None = None match thing: - case OverriddenInstructionPlaceHolder(): - continue - case parser.InstDef(): + case parsing.InstDef(): format = self.instrs[thing.name].instr_fmt - case parser.Macro(): + case parsing.Macro(): format = self.macro_instrs[thing.name].instr_fmt - case parser.Pseudo(): - format = None + case parsing.Pseudo(): for target in self.pseudos[thing.name].targets: target_instr = self.instrs.get(target) assert target_instr @@ -1187,18 +403,25 @@ def write_metadata(self) -> None: else: assert format == target_instr.instr_fmt case _: - typing.assert_never(thing) + assert_never(thing) + assert format is not None all_formats.add(format) - # Turn it into a list of enum definitions. + + # Turn it into a sorted list of enum values. format_enums = [INSTR_FMT_PREFIX + format for format in sorted(all_formats)] - with open(self.metadata_filename, "w") as f: + with open(metadata_filename, "w") as f: # Create formatter self.out = Formatter(f, 0) self.write_provenance_header() - self.out.emit("\n#include ") + self.out.emit("") + self.out.emit("#ifndef Py_BUILD_CORE") + self.out.emit('# error "this header requires Py_BUILD_CORE define"') + self.out.emit("#endif") + self.out.emit("") + self.out.emit("#include // bool") self.write_pseudo_instrs() @@ -1207,14 +430,17 @@ def write_metadata(self) -> None: self.write_stack_effect_functions() - # Write type definitions - self.out.emit(f"enum InstructionFormat {{ {', '.join(format_enums)} }};") + # Write the enum definition for instruction formats. + with self.out.block("enum InstructionFormat", ";"): + for enum in format_enums: + self.out.emit(enum + ",") self.out.emit("") self.out.emit( "#define IS_VALID_OPCODE(OP) \\\n" " (((OP) >= 0) && ((OP) < OPCODE_METADATA_SIZE) && \\\n" - " (_PyOpcode_opcode_metadata[(OP)].valid_entry))") + " (_PyOpcode_opcode_metadata[(OP)].valid_entry))" + ) self.out.emit("") InstructionFlags.emit_macros(self.out) @@ -1228,100 +454,141 @@ def write_metadata(self) -> None: with self.out.block("struct opcode_macro_expansion", ";"): self.out.emit("int nuops;") - self.out.emit("struct { int16_t uop; int8_t size; int8_t offset; } uops[8];") + self.out.emit( + "struct { int16_t uop; int8_t size; int8_t offset; } uops[12];" + ) self.out.emit("") for key, value in OPARG_SIZES.items(): self.out.emit(f"#define {key} {value}") self.out.emit("") - self.out.emit("#define OPCODE_METADATA_FMT(OP) " - "(_PyOpcode_opcode_metadata[(OP)].instr_format)") + self.out.emit( + "#define OPCODE_METADATA_FMT(OP) " + "(_PyOpcode_opcode_metadata[(OP)].instr_format)" + ) self.out.emit("#define SAME_OPCODE_METADATA(OP1, OP2) \\") - self.out.emit(" (OPCODE_METADATA_FMT(OP1) == OPCODE_METADATA_FMT(OP2))") + self.out.emit( + " (OPCODE_METADATA_FMT(OP1) == OPCODE_METADATA_FMT(OP2))" + ) self.out.emit("") # Write metadata array declaration self.out.emit("#define OPCODE_METADATA_SIZE 512") self.out.emit("#define OPCODE_UOP_NAME_SIZE 512") self.out.emit("#define OPCODE_MACRO_EXPANSION_SIZE 256") - self.out.emit("") - self.out.emit("#ifndef NEED_OPCODE_METADATA") - self.out.emit("extern const struct opcode_metadata " - "_PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE];") - self.out.emit("extern const struct opcode_macro_expansion " - "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE];") - self.out.emit("extern const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE];") - self.out.emit("#else // if NEED_OPCODE_METADATA") - - self.out.emit("const struct opcode_metadata " - "_PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {") - - # Write metadata for each instruction - for thing in self.everything: - match thing: - case OverriddenInstructionPlaceHolder(): - continue - case parser.InstDef(): - if thing.kind != "op": - self.write_metadata_for_inst(self.instrs[thing.name]) - case parser.Macro(): - self.write_metadata_for_macro(self.macro_instrs[thing.name]) - case parser.Pseudo(): - self.write_metadata_for_pseudo(self.pseudo_instrs[thing.name]) - case _: - typing.assert_never(thing) - - # Write end of array - self.out.emit("};") - with self.out.block( - "const struct opcode_macro_expansion " - "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE] =", + with self.metadata_item( + "const struct opcode_metadata " + "_PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE]", + "=", ";", ): - # Write macro expansion for each non-pseudo instruction + # Write metadata for each instruction for thing in self.everything: match thing: - case OverriddenInstructionPlaceHolder(): - pass - case parser.InstDef(name=name): - instr = self.instrs[name] - # Since an 'op' is not a bytecode, it has no expansion; but 'inst' is - if instr.kind == "inst" and instr.is_viable_uop(): - # Construct a dummy Component -- input/output mappings are not used - part = Component(instr, [], [], instr.active_caches) - self.write_macro_expansions(instr.name, [part]) - elif instr.kind == "inst" and variable_used(instr.inst, "oparg1"): - assert variable_used(instr.inst, "oparg2"), "Half super-instr?" - self.write_super_expansions(instr.name) - case parser.Macro(): - mac = self.macro_instrs[thing.name] - self.write_macro_expansions(mac.name, mac.parts) - case parser.Pseudo(): - pass + case parsing.InstDef(): + self.write_metadata_for_inst(self.instrs[thing.name]) + case parsing.Macro(): + if thing.name not in self.instrs: + self.write_metadata_for_macro( + self.macro_instrs[thing.name] + ) + case parsing.Pseudo(): + self.write_metadata_for_pseudo( + self.pseudo_instrs[thing.name] + ) case _: - typing.assert_never(thing) + assert_never(thing) - with self.out.block("const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] =", ";"): - self.write_uop_items(lambda name, counter: f"[{name}] = \"{name}\",") + with self.metadata_item( + "const struct opcode_macro_expansion " + "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE]", + "=", + ";", + ): + # Write macro expansion for each non-pseudo instruction + for mac in self.macro_instrs.values(): + if is_super_instruction(mac): + # Special-case the heck out of super-instructions + self.write_super_expansions(mac.name) + else: + self.write_macro_expansions( + mac.name, mac.parts, mac.cache_offset + ) + + with self.metadata_item( + "const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE]", "=", ";" + ): + self.write_uop_items(lambda name, counter: f'[{name}] = "{name}",') + + with self.metadata_item( + f"const char *const _PyOpcode_OpName[{1 + max(self.opmap.values())}]", + "=", + ";", + ): + for name in self.opmap: + self.out.emit(f'[{name}] = "{name}",') + + with self.metadata_item( + f"const uint8_t _PyOpcode_Caches[256]", + "=", + ";", + ): + family_member_names: set[str] = set() + for family in self.families.values(): + family_member_names.update(family.members) + for mac in self.macro_instrs.values(): + if ( + mac.cache_offset > 0 + and mac.name not in family_member_names + and not mac.name.startswith("INSTRUMENTED_") + ): + self.out.emit(f"[{mac.name}] = {mac.cache_offset},") + # Irregular case: + self.out.emit("[JUMP_BACKWARD] = 1,") + + deoptcodes = {} + for name, op in self.opmap.items(): + if op < 256: + deoptcodes[name] = name + for name, family in self.families.items(): + for m in family.members: + deoptcodes[m] = name + # special case: + deoptcodes["BINARY_OP_INPLACE_ADD_UNICODE"] = "BINARY_OP" - self.out.emit("#endif // NEED_OPCODE_METADATA") + with self.metadata_item(f"const uint8_t _PyOpcode_Deopt[256]", "=", ";"): + for opt, deopt in sorted(deoptcodes.items()): + self.out.emit(f"[{opt}] = {deopt},") - with open(self.pymetadata_filename, "w") as f: + self.out.emit("") + self.out.emit("#define EXTRA_CASES \\") + valid_opcodes = set(self.opmap.values()) + with self.out.indent(): + for op in range(256): + if op not in valid_opcodes: + self.out.emit(f"case {op}: \\") + self.out.emit(" ;\n") + + with open(pymetadata_filename, "w") as f: # Create formatter - self.out = Formatter(f, 0, comment = "#") + self.out = Formatter(f, 0, comment="#") self.write_provenance_header() + # emit specializations + specialized_ops = set() + self.out.emit("") self.out.emit("_specializations = {") for name, family in self.families.items(): with self.out.indent(): - self.out.emit(f"\"{family.name}\": [") + self.out.emit(f'"{family.name}": [') with self.out.indent(): for m in family.members: - self.out.emit(f"\"{m}\",") + self.out.emit(f'"{m}",') + specialized_ops.update(family.members) self.out.emit(f"],") self.out.emit("}") @@ -1329,15 +596,28 @@ def write_metadata(self) -> None: self.out.emit("") self.out.emit("# An irregular case:") self.out.emit( - "_specializations[\"BINARY_OP\"].append(" - "\"BINARY_OP_INPLACE_ADD_UNICODE\")") + '_specializations["BINARY_OP"].append(' + '"BINARY_OP_INPLACE_ADD_UNICODE")' + ) + specialized_ops.add("BINARY_OP_INPLACE_ADD_UNICODE") - # Make list of specialized instructions + ops = sorted((id, name) for (name, id) in self.opmap.items()) + # emit specialized opmap self.out.emit("") - self.out.emit( - "_specialized_instructions = [" - "opcode for family in _specializations.values() for opcode in family" - "]") + with self.out.block("_specialized_opmap ="): + for op, name in ops: + if name in specialized_ops: + self.out.emit(f"'{name}': {op},") + + # emit opmap + self.out.emit("") + with self.out.block("opmap ="): + for op, name in ops: + if name not in specialized_ops: + self.out.emit(f"'{name}': {op},") + + for name in ["MIN_INSTRUMENTED_OPCODE", "HAVE_ARGUMENT"]: + self.out.emit(f"{name} = {self.markers[name]}") def write_pseudo_instrs(self) -> None: """Write the IS_PSEUDO_INSTR macro""" @@ -1360,14 +640,17 @@ def add(name: str) -> None: seen.add(name) # These two are first by convention - add("EXIT_TRACE") - add("SAVE_IP") + add("_EXIT_TRACE") + add("_SET_IP") for instr in self.instrs.values(): - if instr.kind == "op" and instr.is_viable_uop(): + # Skip ops that are also macros -- those are desugared inst()s + if instr.name not in self.macros: add(instr.name) - def write_macro_expansions(self, name: str, parts: MacroParts) -> None: + def write_macro_expansions( + self, name: str, parts: MacroParts, cache_offset: int + ) -> None: """Write the macro expansions for a macro-instruction.""" # TODO: Refactor to share code with write_cody(), is_viaible_uop(), etc. offset = 0 # Cache effect offset @@ -1375,11 +658,23 @@ def write_macro_expansions(self, name: str, parts: MacroParts) -> None: for part in parts: if isinstance(part, Component): # All component instructions must be viable uops - if not part.instr.is_viable_uop(): - print(f"NOTE: Part {part.instr.name} of {name} is not a viable uop") + if not part.instr.is_viable_uop() and part.instr.name != "_SAVE_CURRENT_IP": + # This note just reminds us about macros that cannot + # be expanded to Tier 2 uops. It is not an error. + # It is sometimes emitted for macros that have a + # manual translation in translate_bytecode_to_trace() + # in Python/optimizer.c. + if len(parts) > 1 or part.instr.name != name: + self.note( + f"Part {part.instr.name} of {name} is not a viable uop", + part.instr.inst, + ) return if not part.active_caches: - size, offset = OPARG_SIZES["OPARG_FULL"], 0 + if part.instr.name == "_SAVE_CURRENT_IP": + size, offset = OPARG_SIZES["OPARG_SET_IP"], cache_offset - 1 + else: + size, offset = OPARG_SIZES["OPARG_FULL"], 0 else: # If this assert triggers, is_viable_uops() lied assert len(part.active_caches) == 1, (name, part.instr.name) @@ -1420,27 +715,29 @@ def write_super_expansions(self, name: str) -> None: instr2 = self.instrs[name2] assert not instr1.active_caches, f"{name1} has active caches" assert not instr2.active_caches, f"{name2} has active caches" - expansions = [ + expansions: list[tuple[str, int, int]] = [ (name1, OPARG_SIZES["OPARG_TOP"], 0), (name2, OPARG_SIZES["OPARG_BOTTOM"], 0), ] self.write_expansions(name, expansions) - def write_expansions(self, name: str, expansions: list[tuple[str, int, int]]) -> None: - pieces = [f"{{ {name}, {size}, {offset} }}" for name, size, offset in expansions] + def write_expansions( + self, name: str, expansions: list[tuple[str, int, int]] + ) -> None: + pieces = [ + f"{{ {name}, {size}, {offset} }}" for name, size, offset in expansions + ] self.out.emit( f"[{name}] = " f"{{ .nuops = {len(pieces)}, .uops = {{ {', '.join(pieces)} }} }}," ) - def emit_metadata_entry( - self, name: str, fmt: str, flags: InstructionFlags - ) -> None: + def emit_metadata_entry(self, name: str, fmt: str, flags: InstructionFlags) -> None: flag_names = flags.names(value=True) if not flag_names: flag_names.append("0") self.out.emit( - f" [{name}] = {{ true, {INSTR_FMT_PREFIX}{fmt}," + f"[{name}] = {{ true, {INSTR_FMT_PREFIX}{fmt}," f" {' | '.join(flag_names)} }}," ) @@ -1456,265 +753,121 @@ def write_metadata_for_pseudo(self, ps: PseudoInstruction) -> None: """Write metadata for a macro-instruction.""" self.emit_metadata_entry(ps.name, ps.instr_fmt, ps.instr_flags) - def write_instructions(self) -> None: + def write_instructions( + self, output_filename: str, emit_line_directives: bool + ) -> None: """Write instructions to output file.""" - with open(self.output_filename, "w") as f: + with open(output_filename, "w") as f: # Create formatter - self.out = Formatter(f, 8, self.emit_line_directives) + self.out = Formatter(f, 8, emit_line_directives) self.write_provenance_header() # Write and count instructions of all kinds - n_instrs = 0 n_macros = 0 - n_pseudos = 0 for thing in self.everything: match thing: - case OverriddenInstructionPlaceHolder(): - self.write_overridden_instr_place_holder(thing) - case parser.InstDef(): - if thing.kind != "op": - n_instrs += 1 - self.write_instr(self.instrs[thing.name]) - case parser.Macro(): + case parsing.InstDef(): + pass + case parsing.Macro(): n_macros += 1 - self.write_macro(self.macro_instrs[thing.name]) - case parser.Pseudo(): - n_pseudos += 1 + mac = self.macro_instrs[thing.name] + stacking.write_macro_instr(mac, self.out) + case parsing.Pseudo(): + pass case _: - typing.assert_never(thing) + assert_never(thing) print( - f"Wrote {n_instrs} instructions, {n_macros} macros, " - f"and {n_pseudos} pseudos to {self.output_filename}", + f"Wrote {n_macros} cases to {output_filename}", file=sys.stderr, ) - def write_executor_instructions(self) -> None: + def write_executor_instructions( + self, executor_filename: str, emit_line_directives: bool + ) -> None: """Generate cases for the Tier 2 interpreter.""" - with open(self.executor_filename, "w") as f: - self.out = Formatter(f, 8, self.emit_line_directives) + n_uops = 0 + with open(executor_filename, "w") as f: + self.out = Formatter(f, 8, emit_line_directives) self.write_provenance_header() - for thing in self.everything: - match thing: - case OverriddenInstructionPlaceHolder(): - # TODO: Is this helpful? - self.write_overridden_instr_place_holder(thing) - case parser.InstDef(): - instr = self.instrs[thing.name] - if instr.is_viable_uop(): - self.out.emit("") - with self.out.block(f"case {thing.name}:"): - instr.write(self.out, tier=TIER_TWO) - self.out.emit("break;") - # elif instr.kind != "op": - # print(f"NOTE: {thing.name} is not a viable uop") - case parser.Macro(): - pass - case parser.Pseudo(): - pass - case _: - typing.assert_never(thing) + for instr in self.instrs.values(): + if instr.is_viable_uop(): + n_uops += 1 + self.out.emit("") + with self.out.block(f"case {instr.name}:"): + stacking.write_single_instr(instr, self.out, tier=TIER_TWO) + if instr.check_eval_breaker: + self.out.emit("CHECK_EVAL_BREAKER();") + self.out.emit("break;") print( - f"Wrote some stuff to {self.executor_filename}", + f"Wrote {n_uops} cases to {executor_filename}", file=sys.stderr, ) - def write_overridden_instr_place_holder(self, - place_holder: OverriddenInstructionPlaceHolder) -> None: - self.out.emit("") - self.out.emit( - f"{self.out.comment} TARGET({place_holder.name}) overridden by later definition") - - def write_instr(self, instr: Instruction) -> None: - name = instr.name - self.out.emit("") - if instr.inst.override: - self.out.emit("{self.out.comment} Override") - with self.out.block(f"TARGET({name})"): - if instr.predicted: - self.out.emit(f"PREDICTED({name});") - instr.write(self.out) - if not instr.always_exits: - if instr.check_eval_breaker: - self.out.emit("CHECK_EVAL_BREAKER();") - self.out.emit(f"DISPATCH();") - - def write_macro(self, mac: MacroInstruction) -> None: - """Write code for a macro instruction.""" - last_instr: Instruction | None = None - with self.wrap_macro(mac): - cache_adjust = 0 - for part in mac.parts: - match part: - case parser.CacheEffect(size=size): - cache_adjust += size - case Component() as comp: - last_instr = comp.instr - comp.write_body(self.out) - cache_adjust += comp.instr.cache_offset - - if cache_adjust: - self.out.emit(f"next_instr += {cache_adjust};") - - if ( - (family := self.families.get(mac.name)) - and mac.name == family.name - and (cache_size := family.size) - ): - self.out.emit( - f"static_assert({cache_size} == " - f'{cache_adjust}, "incorrect cache size");' - ) - - @contextlib.contextmanager - def wrap_macro(self, mac: MacroInstruction): - """Boilerplate for macro instructions.""" - # TODO: Somewhere (where?) make it so that if one instruction - # has an output that is input to another, and the variable names - # and types match and don't conflict with other instructions, - # that variable is declared with the right name and type in the - # outer block, rather than trusting the compiler to optimize it. - self.out.emit("") - with self.out.block(f"TARGET({mac.name})"): - if mac.predicted: - self.out.emit(f"PREDICTED({mac.name});") - - # The input effects should have no conditionals. - # Only the output effects do (for now). - ieffects = [ - StackEffect(eff.name, eff.type) if eff.cond else eff - for eff in mac.stack - ] - - for i, var in reversed(list(enumerate(ieffects))): - src = None - if i < mac.initial_sp: - src = StackEffect(f"stack_pointer[-{mac.initial_sp - i}]", "") - self.out.declare(var, src) - - yield - - self.out.stack_adjust(ieffects[:mac.initial_sp], mac.stack[:mac.final_sp]) - - for i, var in enumerate(reversed(mac.stack[: mac.final_sp]), 1): - dst = StackEffect(f"stack_pointer[-{i}]", "") - self.out.assign(dst, var) - - self.out.emit(f"DISPATCH();") - - -def prettify_filename(filename: str) -> str: - # Make filename more user-friendly and less platform-specific, - # it is only used for error reporting at this point. - filename = filename.replace("\\", "/") - if filename.startswith("./"): - filename = filename[2:] - if filename.endswith(".new"): - filename = filename[:-4] - return filename - - -def extract_block_text(block: parser.Block) -> tuple[list[str], bool, int]: - # Get lines of text with proper dedent - blocklines = block.text.splitlines(True) - first_token: lx.Token = block.tokens[0] # IndexError means the context is broken - block_line = first_token.begin[0] - - # Remove blank lines from both ends - while blocklines and not blocklines[0].strip(): - blocklines.pop(0) - block_line += 1 - while blocklines and not blocklines[-1].strip(): - blocklines.pop() - - # Remove leading and trailing braces - assert blocklines and blocklines[0].strip() == "{" - assert blocklines and blocklines[-1].strip() == "}" - blocklines.pop() - blocklines.pop(0) - block_line += 1 - - # Remove trailing blank lines - while blocklines and not blocklines[-1].strip(): - blocklines.pop() - - # Separate CHECK_EVAL_BREAKER() macro from end - check_eval_breaker = \ - blocklines != [] and blocklines[-1].strip() == "CHECK_EVAL_BREAKER();" - if check_eval_breaker: - del blocklines[-1] - - return blocklines, check_eval_breaker, block_line - - -def always_exits(lines: list[str]) -> bool: - """Determine whether a block always ends in a return/goto/etc.""" - if not lines: - return False - line = lines[-1].rstrip() - # Indent must match exactly (TODO: Do something better) - if line[:12] != " " * 12: - return False - line = line[12:] - return line.startswith( - ( - "goto ", - "return ", - "DISPATCH", - "GO_TO_", - "Py_UNREACHABLE()", - "ERROR_IF(true, ", + def write_abstract_interpreter_instructions( + self, abstract_interpreter_filename: str, emit_line_directives: bool + ) -> None: + """Generate cases for the Tier 2 abstract interpreter/analzyer.""" + with open(abstract_interpreter_filename, "w") as f: + self.out = Formatter(f, 8, emit_line_directives) + self.write_provenance_header() + for instr in self.instrs.values(): + instr = AbstractInstruction(instr.inst) + if ( + instr.is_viable_uop() + and instr.name not in SPECIALLY_HANDLED_ABSTRACT_INSTR + ): + self.out.emit("") + with self.out.block(f"case {instr.name}:"): + instr.write(self.out, tier=TIER_TWO) + self.out.emit("break;") + print( + f"Wrote some stuff to {abstract_interpreter_filename}", + file=sys.stderr, ) - ) -def variable_used(node: parser.Node, name: str) -> bool: - """Determine whether a variable with a given name is used in a node.""" - return any( - token.kind == "IDENTIFIER" and token.text == name for token in node.tokens - ) - - -def variable_used_unspecialized(node: parser.Node, name: str) -> bool: - """Like variable_used(), but skips #if ENABLE_SPECIALIZATION blocks.""" - tokens: list[lx.Token] = [] - skipping = False - for i, token in enumerate(node.tokens): - if token.kind == "MACRO": - text = "".join(token.text.split()) - # TODO: Handle nested #if - if text == "#if": - if ( - i + 1 < len(node.tokens) - and node.tokens[i + 1].text == "ENABLE_SPECIALIZATION" - ): - skipping = True - elif text in ("#else", "#endif"): - skipping = False - if not skipping: - tokens.append(token) - return any(token.kind == "IDENTIFIER" and token.text == name for token in tokens) +def is_super_instruction(mac: MacroInstruction) -> bool: + if ( + len(mac.parts) == 1 + and isinstance(mac.parts[0], Component) + and variable_used(mac.parts[0].instr.inst, "oparg1") + ): + assert variable_used(mac.parts[0].instr.inst, "oparg2") + return True + else: + return False -def main(): +def main() -> None: """Parse command line, parse input, analyze, write output.""" args = arg_parser.parse_args() # Prints message and sys.exit(2) on error if len(args.input) == 0: args.input.append(DEFAULT_INPUT) # Raises OSError if input unreadable - a = Analyzer(args.input, args.output, args.metadata, args.pymetadata, args.executor_cases) + a = Generator(args.input) - if args.emit_line_directives: - a.emit_line_directives = True a.parse() # Raises SyntaxError on failure a.analyze() # Prints messages and sets a.errors on failure if a.errors: sys.exit(f"Found {a.errors} errors") - a.write_instructions() # Raises OSError if output can't be written - a.write_metadata() - a.write_executor_instructions() + if args.verbose: + # Load execution counts from bmraw.json, if it exists + a.report_non_viable_uops("bmraw.json") + return + + # These raise OSError if output can't be written + a.write_instructions(args.output, args.emit_line_directives) + + a.assign_opcode_ids() + a.write_opcode_ids(args.opcode_ids_h, args.opcode_targets_h) + a.write_metadata(args.metadata, args.pymetadata) + a.write_executor_instructions(args.executor_cases, args.emit_line_directives) + a.write_abstract_interpreter_instructions( + args.abstract_interpreter_cases, args.emit_line_directives + ) if __name__ == "__main__": diff --git a/Tools/cases_generator/instructions.py b/Tools/cases_generator/instructions.py new file mode 100644 index 00000000000000..c6b551675e3e7e --- /dev/null +++ b/Tools/cases_generator/instructions.py @@ -0,0 +1,355 @@ +import dataclasses +import re +import typing + +from flags import InstructionFlags, variable_used, variable_used_unspecialized +from formatting import ( + Formatter, + UNUSED, + list_effect_size, +) +import lexer as lx +import parsing +from parsing import StackEffect +import stacking + +BITS_PER_CODE_UNIT = 16 + + +@dataclasses.dataclass +class ActiveCacheEffect: + """Wraps a CacheEffect that is actually used, in context.""" + + effect: parsing.CacheEffect + offset: int + + +FORBIDDEN_NAMES_IN_UOPS = ( + "resume_with_error", + "kwnames", + "next_instr", + "oparg1", # Proxy for super-instructions like LOAD_FAST_LOAD_FAST + "JUMPBY", + "DISPATCH", + "INSTRUMENTED_JUMP", + "throwflag", + "exception_unwind", + "import_from", + "import_name", + "_PyObject_CallNoArgs", # Proxy for BEFORE_WITH + "TIER_ONE_ONLY", +) + + +# Interpreter tiers +TIER_ONE: typing.Final = 1 # Specializing adaptive interpreter (PEP 659) +TIER_TWO: typing.Final = 2 # Experimental tracing interpreter +Tiers: typing.TypeAlias = typing.Literal[1, 2] + + +@dataclasses.dataclass +class Instruction: + """An instruction with additional data and code.""" + + # Parts of the underlying instruction definition + inst: parsing.InstDef + name: str + block: parsing.Block + block_text: list[str] # Block.text, less curlies, less PREDICT() calls + block_line: int # First line of block in original code + + # Computed by constructor + always_exits: str # If the block always exits, its last line; else "" + has_deopt: bool + cache_offset: int + cache_effects: list[parsing.CacheEffect] + input_effects: list[StackEffect] + output_effects: list[StackEffect] + unmoved_names: frozenset[str] + instr_fmt: str + instr_flags: InstructionFlags + active_caches: list[ActiveCacheEffect] + + # Set later + family: parsing.Family | None = None + predicted: bool = False + + def __init__(self, inst: parsing.InstDef): + self.inst = inst + self.name = inst.name + self.block = inst.block + self.block_text, self.check_eval_breaker, self.block_line = extract_block_text( + self.block + ) + self.always_exits = always_exits(self.block_text) + self.has_deopt = variable_used(self.inst, "DEOPT_IF") + self.cache_effects = [ + effect for effect in inst.inputs if isinstance(effect, parsing.CacheEffect) + ] + self.cache_offset = sum(c.size for c in self.cache_effects) + self.input_effects = [ + effect for effect in inst.inputs if isinstance(effect, StackEffect) + ] + self.output_effects = inst.outputs # For consistency/completeness + unmoved_names: set[str] = set() + for ieffect, oeffect in zip(self.input_effects, self.output_effects): + if ieffect == oeffect and ieffect.name == oeffect.name: + unmoved_names.add(ieffect.name) + else: + break + self.unmoved_names = frozenset(unmoved_names) + + self.instr_flags = InstructionFlags.fromInstruction(inst) + + self.active_caches = [] + offset = 0 + for effect in self.cache_effects: + if effect.name != UNUSED: + self.active_caches.append(ActiveCacheEffect(effect, offset)) + offset += effect.size + + if self.instr_flags.HAS_ARG_FLAG: + fmt = "IB" + else: + fmt = "IX" + if offset: + fmt += "C" + "0" * (offset - 1) + self.instr_fmt = fmt + + def is_viable_uop(self) -> bool: + """Whether this instruction is viable as a uop.""" + dprint: typing.Callable[..., None] = lambda *args, **kwargs: None + if "FRAME" in self.name: + dprint = print + + if self.name == "_EXIT_TRACE": + return True # This has 'return frame' but it's okay + if self.always_exits: + dprint(f"Skipping {self.name} because it always exits: {self.always_exits}") + return False + if len(self.active_caches) > 1: + # print(f"Skipping {self.name} because it has >1 cache entries") + return False + res = True + for forbidden in FORBIDDEN_NAMES_IN_UOPS: + # NOTE: To disallow unspecialized uops, use + # if variable_used(self.inst, forbidden): + if variable_used_unspecialized(self.inst, forbidden): + dprint(f"Skipping {self.name} because it uses {forbidden}") + res = False + return res + + def write_body( + self, + out: Formatter, + dedent: int, + active_caches: list[ActiveCacheEffect], + tier: Tiers, + family: parsing.Family | None, + ) -> None: + """Write the instruction body.""" + # Write cache effect variable declarations and initializations + for active in active_caches: + ceffect = active.effect + bits = ceffect.size * BITS_PER_CODE_UNIT + if bits == 64: + # NOTE: We assume that 64-bit data in the cache + # is always an object pointer. + # If this becomes false, we need a way to specify + # syntactically what type the cache data is. + typ = "PyObject *" + func = "read_obj" + else: + typ = f"uint{bits}_t " + func = f"read_u{bits}" + if tier == TIER_ONE: + out.emit( + f"{typ}{ceffect.name} = {func}(&next_instr[{active.offset}].cache);" + ) + else: + out.emit(f"{typ}{ceffect.name} = ({typ.strip()})operand;") + + # Write the body, substituting a goto for ERROR_IF() and other stuff + assert dedent <= 0 + extra = " " * -dedent + names_to_skip = self.unmoved_names | frozenset({UNUSED, "null"}) + offset = 0 + context = self.block.context + assert context is not None and context.owner is not None + filename = context.owner.filename + for line in self.block_text: + out.set_lineno(self.block_line + offset, filename) + offset += 1 + if m := re.match(r"(\s*)ERROR_IF\((.+), (\w+)\);\s*(?://.*)?$", line): + space, cond, label = m.groups() + space = extra + space + # ERROR_IF() must pop the inputs from the stack. + # The code block is responsible for DECREF()ing them. + # NOTE: If the label doesn't exist, just add it to ceval.c. + + # Don't pop common input/output effects at the bottom! + # These aren't DECREF'ed so they can stay. + ieffs = list(self.input_effects) + oeffs = list(self.output_effects) + while ( + ieffs + and oeffs + and ieffs[0] == oeffs[0] + and ieffs[0].name == oeffs[0].name + ): + ieffs.pop(0) + oeffs.pop(0) + ninputs, symbolic = list_effect_size(ieffs) + if ninputs: + label = f"pop_{ninputs}_{label}" + if symbolic: + out.write_raw( + f"{space}if ({cond}) {{ STACK_SHRINK({symbolic}); goto {label}; }}\n" + ) + else: + out.write_raw(f"{space}if ({cond}) goto {label};\n") + elif m := re.match(r"(\s*)DEOPT_IF\((.+)\);\s*(?://.*)?$", line): + space, cond = m.groups() + space = extra + space + target = family.name if family else self.name + out.write_raw(f"{space}DEOPT_IF({cond}, {target});\n") + elif "DEOPT" in line: + filename = context.owner.filename + lineno = context.owner.tokens[context.begin].line + print(f"{filename}:{lineno}: ERROR: DEOPT_IF() must be all on one line") + out.write_raw(extra + line) + elif m := re.match(r"(\s*)DECREF_INPUTS\(\);\s*(?://.*)?$", line): + out.reset_lineno() + space = extra + m.group(1) + for ieff in self.input_effects: + if ieff.name in names_to_skip: + continue + if ieff.size: + out.write_raw( + f"{space}for (int _i = {ieff.size}; --_i >= 0;) {{\n" + ) + out.write_raw(f"{space} Py_DECREF({ieff.name}[_i]);\n") + out.write_raw(f"{space}}}\n") + else: + decref = "XDECREF" if ieff.cond else "DECREF" + out.write_raw(f"{space}Py_{decref}({ieff.name});\n") + else: + out.write_raw(extra + line) + out.reset_lineno() + + +InstructionOrCacheEffect = Instruction | parsing.CacheEffect + + +# Instruction used for abstract interpretation. +class AbstractInstruction(Instruction): + def __init__(self, inst: parsing.InstDef): + super().__init__(inst) + + def write(self, out: Formatter, tier: Tiers = TIER_ONE) -> None: + """Write one abstract instruction, sans prologue and epilogue.""" + stacking.write_single_instr_for_abstract_interp(self, out) + + def write_body( + self, + out: Formatter, + dedent: int, + active_caches: list[ActiveCacheEffect], + tier: Tiers, + family: parsing.Family | None, + ) -> None: + pass + + +@dataclasses.dataclass +class Component: + instr: Instruction + active_caches: list[ActiveCacheEffect] + + +MacroParts = list[Component | parsing.CacheEffect] + + +@dataclasses.dataclass +class MacroInstruction: + """A macro instruction.""" + + name: str + instr_fmt: str + instr_flags: InstructionFlags + macro: parsing.Macro + parts: MacroParts + cache_offset: int + # Set later + predicted: bool = False + family: parsing.Family | None = None + + +@dataclasses.dataclass +class PseudoInstruction: + """A pseudo instruction.""" + + name: str + targets: list[Instruction] + instr_fmt: str + instr_flags: InstructionFlags + + +AnyInstruction = Instruction | MacroInstruction | PseudoInstruction + + +def extract_block_text(block: parsing.Block) -> tuple[list[str], bool, int]: + # Get lines of text with proper dedent + blocklines = block.text.splitlines(True) + first_token: lx.Token = block.tokens[0] # IndexError means the context is broken + block_line = first_token.begin[0] + + # Remove blank lines from both ends + while blocklines and not blocklines[0].strip(): + blocklines.pop(0) + block_line += 1 + while blocklines and not blocklines[-1].strip(): + blocklines.pop() + + # Remove leading and trailing braces + assert blocklines and blocklines[0].strip() == "{" + assert blocklines and blocklines[-1].strip() == "}" + blocklines.pop() + blocklines.pop(0) + block_line += 1 + + # Remove trailing blank lines + while blocklines and not blocklines[-1].strip(): + blocklines.pop() + + # Separate CHECK_EVAL_BREAKER() macro from end + check_eval_breaker = ( + blocklines != [] and blocklines[-1].strip() == "CHECK_EVAL_BREAKER();" + ) + if check_eval_breaker: + del blocklines[-1] + + return blocklines, check_eval_breaker, block_line + + +def always_exits(lines: list[str]) -> str: + """Determine whether a block always ends in a return/goto/etc.""" + if not lines: + return "" + line = lines[-1].rstrip() + # Indent must match exactly (TODO: Do something better) + if line[:12] != " " * 12: + return "" + line = line[12:] + if line.startswith( + ( + "goto ", + "return ", + "DISPATCH", + "GO_TO_", + "Py_UNREACHABLE()", + "ERROR_IF(true, ", + ) + ): + return line + return "" diff --git a/Tools/cases_generator/interpreter_definition.md b/Tools/cases_generator/interpreter_definition.md index f141848631d04a..5c4238756748a7 100644 --- a/Tools/cases_generator/interpreter_definition.md +++ b/Tools/cases_generator/interpreter_definition.md @@ -108,7 +108,7 @@ and a piece of C code describing its semantics:: NAME [":" type] [ "if" "(" C-expression ")" ] type: - NAME + NAME ["*"] stream: NAME "/" size diff --git a/Tools/cases_generator/lexer.py b/Tools/cases_generator/lexer.py index fe9c05ede5aa47..a60f6c11a4c460 100644 --- a/Tools/cases_generator/lexer.py +++ b/Tools/cases_generator/lexer.py @@ -4,132 +4,221 @@ import re from dataclasses import dataclass +from collections.abc import Iterator -def choice(*opts): + +def choice(*opts: str) -> str: return "|".join("(%s)" % opt for opt in opts) + # Regexes # Longer operators must go before shorter ones. -PLUSPLUS = r'\+\+' -MINUSMINUS = r'--' +PLUSPLUS = r"\+\+" +MINUSMINUS = r"--" # -> -ARROW = r'->' -ELLIPSIS = r'\.\.\.' +ARROW = r"->" +ELLIPSIS = r"\.\.\." # Assignment operators -TIMESEQUAL = r'\*=' -DIVEQUAL = r'/=' -MODEQUAL = r'%=' -PLUSEQUAL = r'\+=' -MINUSEQUAL = r'-=' -LSHIFTEQUAL = r'<<=' -RSHIFTEQUAL = r'>>=' -ANDEQUAL = r'&=' -OREQUAL = r'\|=' -XOREQUAL = r'\^=' +TIMESEQUAL = r"\*=" +DIVEQUAL = r"/=" +MODEQUAL = r"%=" +PLUSEQUAL = r"\+=" +MINUSEQUAL = r"-=" +LSHIFTEQUAL = r"<<=" +RSHIFTEQUAL = r">>=" +ANDEQUAL = r"&=" +OREQUAL = r"\|=" +XOREQUAL = r"\^=" # Operators -PLUS = r'\+' -MINUS = r'-' -TIMES = r'\*' -DIVIDE = r'/' -MOD = r'%' -NOT = r'~' -XOR = r'\^' -LOR = r'\|\|' -LAND = r'&&' -LSHIFT = r'<<' -RSHIFT = r'>>' -LE = r'<=' -GE = r'>=' -EQ = r'==' -NE = r'!=' -LT = r'<' -GT = r'>' -LNOT = r'!' -OR = r'\|' -AND = r'&' -EQUALS = r'=' +PLUS = r"\+" +MINUS = r"-" +TIMES = r"\*" +DIVIDE = r"/" +MOD = r"%" +NOT = r"~" +XOR = r"\^" +LOR = r"\|\|" +LAND = r"&&" +LSHIFT = r"<<" +RSHIFT = r">>" +LE = r"<=" +GE = r">=" +EQ = r"==" +NE = r"!=" +LT = r"<" +GT = r">" +LNOT = r"!" +OR = r"\|" +AND = r"&" +EQUALS = r"=" # ? -CONDOP = r'\?' +CONDOP = r"\?" # Delimiters -LPAREN = r'\(' -RPAREN = r'\)' -LBRACKET = r'\[' -RBRACKET = r'\]' -LBRACE = r'\{' -RBRACE = r'\}' -COMMA = r',' -PERIOD = r'\.' -SEMI = r';' -COLON = r':' -BACKSLASH = r'\\' - -operators = { op: pattern for op, pattern in globals().items() if op == op.upper() } +LPAREN = r"\(" +RPAREN = r"\)" +LBRACKET = r"\[" +RBRACKET = r"\]" +LBRACE = r"\{" +RBRACE = r"\}" +COMMA = r"," +PERIOD = r"\." +SEMI = r";" +COLON = r":" +BACKSLASH = r"\\" + +operators = {op: pattern for op, pattern in globals().items() if op == op.upper()} for op in operators: globals()[op] = op -opmap = { pattern.replace("\\", "") or '\\' : op for op, pattern in operators.items() } +opmap = {pattern.replace("\\", "") or "\\": op for op, pattern in operators.items()} # Macros -macro = r'# *(ifdef|ifndef|undef|define|error|endif|if|else|include|#)' -MACRO = 'MACRO' +macro = r"# *(ifdef|ifndef|undef|define|error|endif|if|else|include|#)" +MACRO = "MACRO" -id_re = r'[a-zA-Z_][0-9a-zA-Z_]*' -IDENTIFIER = 'IDENTIFIER' +id_re = r"[a-zA-Z_][0-9a-zA-Z_]*" +IDENTIFIER = "IDENTIFIER" -suffix = r'([uU]?[lL]?[lL]?)' -octal = r'0[0-7]+' + suffix -hex = r'0[xX][0-9a-fA-F]+' -decimal_digits = r'(0|[1-9][0-9]*)' +suffix = r"([uU]?[lL]?[lL]?)" +octal = r"0[0-7]+" + suffix +hex = r"0[xX][0-9a-fA-F]+" +decimal_digits = r"(0|[1-9][0-9]*)" decimal = decimal_digits + suffix exponent = r"""([eE][-+]?[0-9]+)""" fraction = r"""([0-9]*\.[0-9]+)|([0-9]+\.)""" -float = '(((('+fraction+')'+exponent+'?)|([0-9]+'+exponent+'))[FfLl]?)' +float = "((((" + fraction + ")" + exponent + "?)|([0-9]+" + exponent + "))[FfLl]?)" number_re = choice(octal, hex, float, decimal) -NUMBER = 'NUMBER' +NUMBER = "NUMBER" simple_escape = r"""([a-zA-Z._~!=&\^\-\\?'"])""" decimal_escape = r"""(\d+)""" hex_escape = r"""(x[0-9a-fA-F]+)""" -escape_sequence = r"""(\\("""+simple_escape+'|'+decimal_escape+'|'+hex_escape+'))' -string_char = r"""([^"\\\n]|"""+escape_sequence+')' -str_re = '"'+string_char+'*"' -STRING = 'STRING' -char = r'\'.\'' # TODO: escape sequence -CHARACTER = 'CHARACTER' +escape_sequence = ( + r"""(\\(""" + simple_escape + "|" + decimal_escape + "|" + hex_escape + "))" +) +string_char = r"""([^"\\\n]|""" + escape_sequence + ")" +str_re = '"' + string_char + '*"' +STRING = "STRING" +char = r"\'.\'" # TODO: escape sequence +CHARACTER = "CHARACTER" -comment_re = r'//.*|/\*([^*]|\*[^/])*\*/' -COMMENT = 'COMMENT' +comment_re = r"//.*|/\*([^*]|\*[^/])*\*/" +COMMENT = "COMMENT" newline = r"\n" -invalid = r"\S" # A single non-space character that's not caught by any of the other patterns -matcher = re.compile(choice(id_re, number_re, str_re, char, newline, macro, comment_re, *operators.values(), invalid)) -letter = re.compile(r'[a-zA-Z_]') - -kwds = ( - 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', - 'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN', - 'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG', 'OVERRIDE', - 'REGISTER', 'OFFSETOF', - 'RESTRICT', 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', - 'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID', - 'VOLATILE', 'WHILE' +invalid = ( + r"\S" # A single non-space character that's not caught by any of the other patterns ) -for name in kwds: - globals()[name] = name -keywords = { name.lower() : name for name in kwds } +matcher = re.compile( + choice( + id_re, + number_re, + str_re, + char, + newline, + macro, + comment_re, + *operators.values(), + invalid, + ) +) +letter = re.compile(r"[a-zA-Z_]") + + +kwds = [] +AUTO = "AUTO" +kwds.append(AUTO) +BREAK = "BREAK" +kwds.append(BREAK) +CASE = "CASE" +kwds.append(CASE) +CHAR = "CHAR" +kwds.append(CHAR) +CONST = "CONST" +kwds.append(CONST) +CONTINUE = "CONTINUE" +kwds.append(CONTINUE) +DEFAULT = "DEFAULT" +kwds.append(DEFAULT) +DO = "DO" +kwds.append(DO) +DOUBLE = "DOUBLE" +kwds.append(DOUBLE) +ELSE = "ELSE" +kwds.append(ELSE) +ENUM = "ENUM" +kwds.append(ENUM) +EXTERN = "EXTERN" +kwds.append(EXTERN) +FLOAT = "FLOAT" +kwds.append(FLOAT) +FOR = "FOR" +kwds.append(FOR) +GOTO = "GOTO" +kwds.append(GOTO) +IF = "IF" +kwds.append(IF) +INLINE = "INLINE" +kwds.append(INLINE) +INT = "INT" +kwds.append(INT) +LONG = "LONG" +kwds.append(LONG) +OVERRIDE = "OVERRIDE" +kwds.append(OVERRIDE) +REGISTER = "REGISTER" +kwds.append(REGISTER) +OFFSETOF = "OFFSETOF" +kwds.append(OFFSETOF) +RESTRICT = "RESTRICT" +kwds.append(RESTRICT) +RETURN = "RETURN" +kwds.append(RETURN) +SHORT = "SHORT" +kwds.append(SHORT) +SIGNED = "SIGNED" +kwds.append(SIGNED) +SIZEOF = "SIZEOF" +kwds.append(SIZEOF) +STATIC = "STATIC" +kwds.append(STATIC) +STRUCT = "STRUCT" +kwds.append(STRUCT) +SWITCH = "SWITCH" +kwds.append(SWITCH) +TYPEDEF = "TYPEDEF" +kwds.append(TYPEDEF) +UNION = "UNION" +kwds.append(UNION) +UNSIGNED = "UNSIGNED" +kwds.append(UNSIGNED) +VOID = "VOID" +kwds.append(VOID) +VOLATILE = "VOLATILE" +kwds.append(VOLATILE) +WHILE = "WHILE" +kwds.append(WHILE) +keywords = {name.lower(): name for name in kwds} + +__all__ = [] +__all__.extend(kwds) def make_syntax_error( - message: str, filename: str, line: int, column: int, line_text: str, + message: str, + filename: str | None, + line: int, + column: int, + line_text: str, ) -> SyntaxError: return SyntaxError(message, (filename, line, column, line_text)) @@ -142,30 +231,30 @@ class Token: end: tuple[int, int] @property - def line(self): + def line(self) -> int: return self.begin[0] @property - def column(self): + def column(self) -> int: return self.begin[1] @property - def end_line(self): + def end_line(self) -> int: return self.end[0] @property - def end_column(self): + def end_column(self) -> int: return self.end[1] @property - def width(self): + def width(self) -> int: return self.end[1] - self.begin[1] - def replaceText(self, txt): + def replaceText(self, txt: str) -> "Token": assert isinstance(txt, str) return Token(self.kind, txt, self.begin, self.end) - def __repr__(self): + def __repr__(self) -> str: b0, b1 = self.begin e0, e1 = self.end if b0 == e0: @@ -174,7 +263,7 @@ def __repr__(self): return f"{self.kind}({self.text!r}, {b0}:{b1}, {e0}:{e1})" -def tokenize(src, line=1, filename=None): +def tokenize(src: str, line: int = 1, filename: str | None = None) -> Iterator[Token]: linestart = -1 for m in matcher.finditer(src): start, end = m.span() @@ -183,73 +272,75 @@ def tokenize(src, line=1, filename=None): kind = keywords[text] elif letter.match(text): kind = IDENTIFIER - elif text == '...': + elif text == "...": kind = ELLIPSIS - elif text == '.': + elif text == ".": kind = PERIOD - elif text[0] in '0123456789.': + elif text[0] in "0123456789.": kind = NUMBER elif text[0] == '"': kind = STRING elif text in opmap: kind = opmap[text] - elif text == '\n': + elif text == "\n": linestart = start line += 1 - kind = '\n' + kind = "\n" elif text[0] == "'": kind = CHARACTER - elif text[0] == '#': + elif text[0] == "#": kind = MACRO - elif text[0] == '/' and text[1] in '/*': + elif text[0] == "/" and text[1] in "/*": kind = COMMENT else: lineend = src.find("\n", start) if lineend == -1: lineend = len(src) - raise make_syntax_error(f"Bad token: {text}", - filename, line, start-linestart+1, src[linestart:lineend]) + raise make_syntax_error( + f"Bad token: {text}", + filename, + line, + start - linestart + 1, + src[linestart:lineend], + ) if kind == COMMENT: - begin = line, start-linestart - newlines = text.count('\n') + begin = line, start - linestart + newlines = text.count("\n") if newlines: - linestart = start + text.rfind('\n') + linestart = start + text.rfind("\n") line += newlines else: - begin = line, start-linestart + begin = line, start - linestart if kind != "\n": - yield Token(kind, text, begin, (line, start-linestart+len(text))) - - -__all__ = [] -__all__.extend([kind for kind in globals() if kind.upper() == kind]) + yield Token(kind, text, begin, (line, start - linestart + len(text))) def to_text(tkns: list[Token], dedent: int = 0) -> str: res: list[str] = [] - line, col = -1, 1+dedent + line, col = -1, 1 + dedent for tkn in tkns: if line == -1: line, _ = tkn.begin l, c = tkn.begin - #assert(l >= line), (line, txt, start, end) + # assert(l >= line), (line, txt, start, end) while l > line: line += 1 - res.append('\n') - col = 1+dedent - res.append(' '*(c-col)) + res.append("\n") + col = 1 + dedent + res.append(" " * (c - col)) text = tkn.text - if dedent != 0 and tkn.kind == 'COMMENT' and '\n' in text: + if dedent != 0 and tkn.kind == "COMMENT" and "\n" in text: if dedent < 0: - text = text.replace('\n', '\n' + ' '*-dedent) + text = text.replace("\n", "\n" + " " * -dedent) # TODO: dedent > 0 res.append(text) line, col = tkn.end - return ''.join(res) + return "".join(res) if __name__ == "__main__": import sys + filename = sys.argv[1] if filename == "-c": src = sys.argv[2] diff --git a/Tools/cases_generator/mypy.ini b/Tools/cases_generator/mypy.ini new file mode 100644 index 00000000000000..e7175e263350b2 --- /dev/null +++ b/Tools/cases_generator/mypy.ini @@ -0,0 +1,13 @@ +[mypy] +files = Tools/cases_generator/ +pretty = True + +# Make sure Python can still be built +# using Python 3.10 for `PYTHON_FOR_REGEN`... +python_version = 3.10 + +# ...And be strict: +strict = True +strict_concatenate = True +enable_error_code = ignore-without-code,redundant-expr,truthy-bool,possibly-undefined +warn_unreachable = True diff --git a/Tools/cases_generator/parser.py b/Tools/cases_generator/parsing.py similarity index 89% rename from Tools/cases_generator/parser.py rename to Tools/cases_generator/parsing.py index ac77e7eae81ad3..25be5ca3e0da5d 100644 --- a/Tools/cases_generator/parser.py +++ b/Tools/cases_generator/parsing.py @@ -1,7 +1,7 @@ """Parser for bytecodes.inst.""" from dataclasses import dataclass, field -from typing import NamedTuple, Callable, TypeVar, Literal +from typing import NamedTuple, Callable, TypeVar, Literal, cast import lexer as lx from plexer import PLexer @@ -19,7 +19,7 @@ def contextual_wrapper(self: P) -> N | None: res = func(self) if res is None: self.setpos(begin) - return + return None end = self.getpos() res.context = Context(begin, end, self) return res @@ -32,7 +32,7 @@ class Context(NamedTuple): end: int owner: PLexer - def __repr__(self): + def __repr__(self) -> str: return f"<{self.owner.filename}: {self.begin}-{self.end}>" @@ -69,12 +69,18 @@ class Block(Node): @dataclass class StackEffect(Node): - name: str + name: str = field(compare=False) # __eq__ only uses type, cond, size type: str = "" # Optional `:type` cond: str = "" # Optional `if (cond)` size: str = "" # Optional `[size]` # Note: size cannot be combined with type or cond + def __repr__(self) -> str: + items = [self.name, self.type, self.cond, self.size] + while items and items[-1] == "": + del items[-1] + return f"StackEffect({', '.join(repr(item) for item in items)})" + @dataclass class Expression(Node): @@ -130,6 +136,7 @@ class Family(Node): size: str # Variable giving the cache size in code units members: list[str] + @dataclass class Pseudo(Node): name: str @@ -147,13 +154,20 @@ def definition(self) -> InstDef | Macro | Pseudo | Family | None: return family if pseudo := self.pseudo_def(): return pseudo + return None @contextual def inst_def(self) -> InstDef | None: if hdr := self.inst_header(): if block := self.block(): return InstDef( - hdr.override, hdr.register, hdr.kind, hdr.name, hdr.inputs, hdr.outputs, block + hdr.override, + hdr.register, + hdr.kind, + hdr.name, + hdr.inputs, + hdr.outputs, + block, ) raise self.make_syntax_error("Expected block") return None @@ -166,7 +180,8 @@ def inst_header(self) -> InstHeader | None: # TODO: Make INST a keyword in the lexer. override = bool(self.expect(lx.OVERRIDE)) register = bool(self.expect(lx.REGISTER)) - if (tkn := self.expect(lx.IDENTIFIER)) and (kind := tkn.text) in ("inst", "op"): + if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text in ("inst", "op"): + kind = cast(Literal["inst", "op"], tkn.text) if self.expect(lx.LPAREN) and (tkn := self.expect(lx.IDENTIFIER)): name = tkn.text if self.expect(lx.COMMA): @@ -190,6 +205,7 @@ def inputs(self) -> list[InputEffect] | None: # input (',' input)* here = self.getpos() if inp := self.input(): + inp = cast(InputEffect, inp) near = self.getpos() if self.expect(lx.COMMA): if rest := self.inputs(): @@ -232,15 +248,18 @@ def cache_effect(self) -> CacheEffect | None: raise self.make_syntax_error(f"Expected integer, got {num!r}") else: return CacheEffect(tkn.text, size) + return None @contextual def stack_effect(self) -> StackEffect | None: - # IDENTIFIER [':' IDENTIFIER] ['if' '(' expression ')'] + # IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')'] # | IDENTIFIER '[' expression ']' if tkn := self.expect(lx.IDENTIFIER): type_text = "" if self.expect(lx.COLON): type_text = self.require(lx.IDENTIFIER).text.strip() + if self.expect(lx.TIMES): + type_text += " *" cond_text = "" if self.expect(lx.IF): self.require(lx.LPAREN) @@ -258,6 +277,7 @@ def stack_effect(self) -> StackEffect | None: type_text = "PyObject **" size_text = size.text.strip() return StackEffect(tkn.text, type_text, cond_text, size_text) + return None @contextual def expression(self) -> Expression | None: @@ -288,6 +308,7 @@ def expression(self) -> Expression | None: def op(self) -> OpName | None: if tkn := self.expect(lx.IDENTIFIER): return OpName(tkn.text) + return None @contextual def macro_def(self) -> Macro | None: @@ -300,16 +321,20 @@ def macro_def(self) -> Macro | None: self.require(lx.SEMI) res = Macro(tkn.text, uops) return res + return None def uops(self) -> list[UOp] | None: if uop := self.uop(): + uop = cast(UOp, uop) uops = [uop] while self.expect(lx.PLUS): if uop := self.uop(): + uop = cast(UOp, uop) uops.append(uop) else: raise self.make_syntax_error("Expected op name or cache effect") return uops + return None @contextual def uop(self) -> UOp | None: @@ -327,6 +352,7 @@ def uop(self) -> UOp | None: raise self.make_syntax_error("Expected integer") else: return OpName(tkn.text) + return None @contextual def family_def(self) -> Family | None: @@ -336,7 +362,8 @@ def family_def(self) -> Family | None: if tkn := self.expect(lx.IDENTIFIER): if self.expect(lx.COMMA): if not (size := self.expect(lx.IDENTIFIER)): - raise self.make_syntax_error("Expected identifier") + if not (size := self.expect(lx.NUMBER)): + raise self.make_syntax_error("Expected identifier or number") if self.expect(lx.RPAREN): if self.expect(lx.EQUALS): if not self.expect(lx.LBRACE): @@ -360,9 +387,7 @@ def pseudo_def(self) -> Pseudo | None: raise self.make_syntax_error("Expected {") if members := self.members(): if self.expect(lx.RBRACE) and self.expect(lx.SEMI): - return Pseudo( - tkn.text, members - ) + return Pseudo(tkn.text, members) return None def members(self) -> list[str] | None: @@ -385,6 +410,7 @@ def members(self) -> list[str] | None: def block(self) -> Block | None: if self.c_blob(): return Block() + return None def c_blob(self) -> list[lx.Token]: tokens: list[lx.Token] = [] diff --git a/Tools/cases_generator/plexer.py b/Tools/cases_generator/plexer.py index a73254ed5b1daa..cb6c5375866490 100644 --- a/Tools/cases_generator/plexer.py +++ b/Tools/cases_generator/plexer.py @@ -1,4 +1,5 @@ import lexer as lx + Token = lx.Token @@ -64,7 +65,9 @@ def require(self, kind: str) -> Token: tkn = self.next() if tkn is not None and tkn.kind == kind: return tkn - raise self.make_syntax_error(f"Expected {kind!r} but got {tkn and tkn.text!r}", tkn) + raise self.make_syntax_error( + f"Expected {kind!r} but got {tkn and tkn.text!r}", tkn + ) def extract_line(self, lineno: int) -> str: # Return source line `lineno` (1-based) @@ -73,18 +76,20 @@ def extract_line(self, lineno: int) -> str: return "" return lines[lineno - 1] - def make_syntax_error(self, message: str, tkn: Token|None = None) -> SyntaxError: + def make_syntax_error(self, message: str, tkn: Token | None = None) -> SyntaxError: # Construct a SyntaxError instance from message and token if tkn is None: tkn = self.peek() if tkn is None: tkn = self.tokens[-1] - return lx.make_syntax_error(message, - self.filename, tkn.line, tkn.column, self.extract_line(tkn.line)) + return lx.make_syntax_error( + message, self.filename, tkn.line, tkn.column, self.extract_line(tkn.line) + ) if __name__ == "__main__": import sys + if sys.argv[1:]: filename = sys.argv[1] if filename == "-c" and sys.argv[2:]: diff --git a/Tools/cases_generator/stacking.py b/Tools/cases_generator/stacking.py new file mode 100644 index 00000000000000..bba2db8b059da8 --- /dev/null +++ b/Tools/cases_generator/stacking.py @@ -0,0 +1,529 @@ +import dataclasses +import typing + +from flags import variable_used_unspecialized +from formatting import ( + Formatter, + UNUSED, + maybe_parenthesize, + parenthesize_cond, +) +from instructions import ( + ActiveCacheEffect, + Instruction, + MacroInstruction, + Component, + Tiers, + TIER_ONE, +) +from parsing import StackEffect, CacheEffect, Family + + +@dataclasses.dataclass +class StackOffset: + """Represent the stack offset for a PEEK or POKE. + + - At stack_pointer[0], deep and high are both empty. + (Note that that is an invalid stack reference.) + - Below stack top, only deep is non-empty. + - Above stack top, only high is non-empty. + - In complex cases, both deep and high may be non-empty. + + All this would be much simpler if all stack entries were the same + size, but with conditional and array effects, they aren't. + The offsets are each represented by a list of StackEffect objects. + The name in the StackEffects is unused. + """ + + deep: list[StackEffect] = dataclasses.field(default_factory=list) + high: list[StackEffect] = dataclasses.field(default_factory=list) + + def clone(self) -> "StackOffset": + return StackOffset(list(self.deep), list(self.high)) + + def negate(self) -> "StackOffset": + return StackOffset(list(self.high), list(self.deep)) + + def deeper(self, eff: StackEffect) -> None: + if eff in self.high: + self.high.remove(eff) + else: + self.deep.append(eff) + + def higher(self, eff: StackEffect) -> None: + if eff in self.deep: + self.deep.remove(eff) + else: + self.high.append(eff) + + def as_terms(self) -> list[tuple[str, str]]: + num = 0 + terms: list[tuple[str, str]] = [] + for eff in self.deep: + if eff.size: + terms.append(("-", maybe_parenthesize(eff.size))) + elif eff.cond and eff.cond not in ("0", "1"): + terms.append(("-", f"({parenthesize_cond(eff.cond)} ? 1 : 0)")) + elif eff.cond != "0": + num -= 1 + for eff in self.high: + if eff.size: + terms.append(("+", maybe_parenthesize(eff.size))) + elif eff.cond and eff.cond not in ("0", "1"): + terms.append(("+", f"({parenthesize_cond(eff.cond)} ? 1 : 0)")) + elif eff.cond != "0": + num += 1 + if num < 0: + terms.insert(0, ("-", str(-num))) + elif num > 0: + terms.append(("+", str(num))) + return terms + + def as_index(self) -> str: + terms = self.as_terms() + return make_index(terms) + + def equivalent_to(self, other: "StackOffset") -> bool: + if self.deep == other.deep and self.high == other.high: + return True + deep = list(self.deep) + for x in other.deep: + try: + deep.remove(x) + except ValueError: + return False + if deep: + return False + high = list(self.high) + for x in other.high: + try: + high.remove(x) + except ValueError: + return False + if high: + return False + return True + + +def make_index(terms: list[tuple[str, str]]) -> str: + # Produce an index expression from the terms honoring PEP 8, + # surrounding binary ops with spaces but not unary minus + index = "" + for sign, term in terms: + if index: + index += f" {sign} {term}" + elif sign == "+": + index = term + else: + index = sign + term + return index or "0" + + +@dataclasses.dataclass +class StackItem: + offset: StackOffset + effect: StackEffect + + def as_variable(self, lax: bool = False) -> str: + """Return e.g. stack_pointer[-1].""" + terms = self.offset.as_terms() + if self.effect.size: + terms.insert(0, ("+", "stack_pointer")) + index = make_index(terms) + if self.effect.size: + res = index + else: + res = f"stack_pointer[{index}]" + if not lax: + # Check that we're not reading or writing above stack top. + # Skip this for output variable initialization (lax=True). + assert ( + self.effect in self.offset.deep and not self.offset.high + ), f"Push or pop above current stack level: {res}" + return res + + def as_stack_effect(self, lax: bool = False) -> StackEffect: + return StackEffect( + self.as_variable(lax=lax), + self.effect.type if self.effect.size else "", + self.effect.cond, + self.effect.size, + ) + + +@dataclasses.dataclass +class CopyItem: + src: StackItem + dst: StackItem + + +class EffectManager: + """Manage stack effects and offsets for an instruction.""" + + instr: Instruction + active_caches: list[ActiveCacheEffect] + peeks: list[StackItem] + pokes: list[StackItem] + copies: list[CopyItem] # See merge() + # Track offsets from stack pointer + min_offset: StackOffset + final_offset: StackOffset + # Link to previous manager + pred: "EffectManager | None" = None + + def __init__( + self, + instr: Instruction, + active_caches: list[ActiveCacheEffect], + pred: "EffectManager | None" = None, + ): + self.instr = instr + self.active_caches = active_caches + self.peeks = [] + self.pokes = [] + self.copies = [] + self.final_offset = pred.final_offset.clone() if pred else StackOffset() + for eff in reversed(instr.input_effects): + self.final_offset.deeper(eff) + self.peeks.append(StackItem(offset=self.final_offset.clone(), effect=eff)) + self.min_offset = self.final_offset.clone() + for eff in instr.output_effects: + self.pokes.append(StackItem(offset=self.final_offset.clone(), effect=eff)) + self.final_offset.higher(eff) + + self.pred = pred + while pred: + # Replace push(x) + pop(y) with copy(x, y). + # Check that the sources and destinations are disjoint. + sources: set[str] = set() + destinations: set[str] = set() + while ( + pred.pokes + and self.peeks + and pred.pokes[-1].effect == self.peeks[0].effect + ): + src = pred.pokes.pop(-1) + dst = self.peeks.pop(0) + assert src.offset.equivalent_to(dst.offset), (src, dst) + pred.final_offset.deeper(src.effect) + if dst.effect.name != src.effect.name: + if dst.effect.name != UNUSED: + destinations.add(dst.effect.name) + if src.effect.name != UNUSED: + sources.add(src.effect.name) + self.copies.append(CopyItem(src, dst)) + # TODO: Turn this into an error (pass an Analyzer instance?) + assert sources & destinations == set(), ( + pred.instr.name, + self.instr.name, + sources, + destinations, + ) + # See if we can get more copies of a earlier predecessor. + if self.peeks and not pred.pokes and not pred.peeks: + pred = pred.pred + else: + pred = None # Break + + # Fix up patterns of copies through UNUSED, + # e.g. cp(a, UNUSED) + cp(UNUSED, b) -> cp(a, b). + if any(copy.src.effect.name == UNUSED for copy in self.copies): + pred = self.pred + while pred is not None: + for copy in self.copies: + if copy.src.effect.name == UNUSED: + for pred_copy in pred.copies: + if pred_copy.dst == copy.src: + copy.src = pred_copy.src + break + pred = pred.pred + + def adjust_deeper(self, eff: StackEffect) -> None: + for peek in self.peeks: + peek.offset.deeper(eff) + for poke in self.pokes: + poke.offset.deeper(eff) + for copy in self.copies: + copy.src.offset.deeper(eff) + copy.dst.offset.deeper(eff) + self.min_offset.deeper(eff) + self.final_offset.deeper(eff) + + def adjust_higher(self, eff: StackEffect) -> None: + for peek in self.peeks: + peek.offset.higher(eff) + for poke in self.pokes: + poke.offset.higher(eff) + for copy in self.copies: + copy.src.offset.higher(eff) + copy.dst.offset.higher(eff) + self.min_offset.higher(eff) + self.final_offset.higher(eff) + + def adjust(self, offset: StackOffset) -> None: + deep = list(offset.deep) + high = list(offset.high) + for down in deep: + self.adjust_deeper(down) + for up in high: + self.adjust_higher(up) + + def adjust_inverse(self, offset: StackOffset) -> None: + deep = list(offset.deep) + high = list(offset.high) + for down in deep: + self.adjust_higher(down) + for up in high: + self.adjust_deeper(up) + + def collect_vars(self) -> dict[str, StackEffect]: + """Collect all variables, skipping unused ones.""" + vars: dict[str, StackEffect] = {} + + def add(eff: StackEffect) -> None: + if eff.name != UNUSED: + if eff.name in vars: + # TODO: Make this an error + assert vars[eff.name] == eff, ( + self.instr.name, + eff.name, + vars[eff.name], + eff, + ) + else: + vars[eff.name] = eff + + for copy in self.copies: + add(copy.src.effect) + add(copy.dst.effect) + for peek in self.peeks: + add(peek.effect) + for poke in self.pokes: + add(poke.effect) + + return vars + + +def less_than(a: StackOffset, b: StackOffset) -> bool: + # TODO: Handle more cases + if a.high != b.high: + return False + return a.deep[: len(b.deep)] == b.deep + + +def get_managers(parts: list[Component]) -> list[EffectManager]: + managers: list[EffectManager] = [] + pred: EffectManager | None = None + for part in parts: + mgr = EffectManager(part.instr, part.active_caches, pred) + managers.append(mgr) + pred = mgr + return managers + + +def get_stack_effect_info_for_macro(mac: MacroInstruction) -> tuple[str, str]: + """Get the stack effect info for a macro instruction. + + Returns a tuple (popped, pushed) where each is a string giving a + symbolic expression for the number of values popped/pushed. + """ + parts = [part for part in mac.parts if isinstance(part, Component)] + managers = get_managers(parts) + popped = StackOffset() + for mgr in managers: + if less_than(mgr.min_offset, popped): + popped = mgr.min_offset.clone() + # Compute pushed = final - popped + pushed = managers[-1].final_offset.clone() + for effect in popped.deep: + pushed.higher(effect) + for effect in popped.high: + pushed.deeper(effect) + return popped.negate().as_index(), pushed.as_index() + + +def write_single_instr( + instr: Instruction, out: Formatter, tier: Tiers = TIER_ONE +) -> None: + try: + write_components( + [Component(instr, instr.active_caches)], + out, + tier, + 0, + instr.family, + ) + except AssertionError as err: + raise AssertionError(f"Error writing instruction {instr.name}") from err + + +def write_macro_instr(mac: MacroInstruction, out: Formatter) -> None: + parts = [ + part + for part in mac.parts + if isinstance(part, Component) and part.instr.name != "_SET_IP" + ] + out.emit("") + with out.block(f"TARGET({mac.name})"): + if mac.predicted: + out.emit(f"PREDICTED({mac.name});") + out.static_assert_family_size(mac.name, mac.family, mac.cache_offset) + try: + next_instr_is_set = write_components( + parts, out, TIER_ONE, mac.cache_offset, mac.family + ) + except AssertionError as err: + raise AssertionError(f"Error writing macro {mac.name}") from err + if not parts[-1].instr.always_exits: + if not next_instr_is_set and mac.cache_offset: + out.emit(f"next_instr += {mac.cache_offset};") + if parts[-1].instr.check_eval_breaker: + out.emit("CHECK_EVAL_BREAKER();") + out.emit("DISPATCH();") + + +def write_components( + parts: list[Component], + out: Formatter, + tier: Tiers, + cache_offset: int, + family: Family | None, +) -> bool: + managers = get_managers(parts) + + all_vars: dict[str, StackEffect] = {} + for mgr in managers: + for name, eff in mgr.collect_vars().items(): + if name in all_vars: + # TODO: Turn this into an error -- variable conflict + assert all_vars[name] == eff, ( + name, + mgr.instr.name, + all_vars[name], + eff, + ) + else: + all_vars[name] = eff + + # Declare all variables + for name, eff in all_vars.items(): + out.declare(eff, None) + + next_instr_is_set = False + for mgr in managers: + if len(parts) > 1: + out.emit(f"// {mgr.instr.name}") + + for copy in mgr.copies: + copy_src_effect = copy.src.effect + if copy_src_effect.name != copy.dst.effect.name: + if copy_src_effect.name == UNUSED: + copy_src_effect = copy.src.as_stack_effect() + out.assign(copy.dst.effect, copy_src_effect) + for peek in mgr.peeks: + out.assign( + peek.effect, + peek.as_stack_effect(), + ) + # Initialize array outputs + for poke in mgr.pokes: + if poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names: + out.assign( + poke.effect, + poke.as_stack_effect(lax=True), + ) + + if mgr.instr.name in ("_PUSH_FRAME", "_POP_FRAME"): + # Adjust stack to min_offset. + # This means that all input effects of this instruction + # are materialized, but not its output effects. + # That's as intended, since these two are so special. + out.stack_adjust(mgr.min_offset.deep, mgr.min_offset.high) + # However, for tier 2, pretend the stack is at final offset. + mgr.adjust_inverse(mgr.final_offset) + if tier == TIER_ONE: + # TODO: Check in analyzer that _{PUSH,POP}_FRAME is last. + assert ( + mgr is managers[-1] + ), f"Expected {mgr.instr.name!r} to be the last uop" + assert_no_pokes(managers) + + if mgr.instr.name == "_SAVE_CURRENT_IP": + next_instr_is_set = True + if cache_offset: + out.emit(f"next_instr += {cache_offset};") + if tier == TIER_ONE: + assert_no_pokes(managers) + + if len(parts) == 1: + mgr.instr.write_body(out, 0, mgr.active_caches, tier, family) + else: + with out.block(""): + mgr.instr.write_body(out, -4, mgr.active_caches, tier, family) + + if mgr is managers[-1] and not next_instr_is_set and not mgr.instr.always_exits: + # Adjust the stack to its final depth, *then* write the + # pokes for all preceding uops. + # Note that for array output effects we may still write + # past the stack top. + out.stack_adjust(mgr.final_offset.deep, mgr.final_offset.high) + write_all_pokes(mgr.final_offset, managers, out) + + return next_instr_is_set + + +def assert_no_pokes(managers: list[EffectManager]) -> None: + for mgr in managers: + for poke in mgr.pokes: + if not poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names: + assert ( + poke.effect.name == UNUSED + ), f"Unexpected poke of {poke.effect.name} in {mgr.instr.name!r}" + + +def write_all_pokes( + offset: StackOffset, managers: list[EffectManager], out: Formatter +) -> None: + # Emit all remaining pushes (pokes) + for m in managers: + m.adjust_inverse(offset) + write_pokes(m, out) + + +def write_pokes(mgr: EffectManager, out: Formatter) -> None: + for poke in mgr.pokes: + if not poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names: + out.assign( + poke.as_stack_effect(), + poke.effect, + ) + + +def write_single_instr_for_abstract_interp(instr: Instruction, out: Formatter) -> None: + try: + _write_components_for_abstract_interp( + [Component(instr, instr.active_caches)], + out, + ) + except AssertionError as err: + raise AssertionError( + f"Error writing abstract instruction {instr.name}" + ) from err + + +def _write_components_for_abstract_interp( + parts: list[Component], + out: Formatter, +) -> None: + managers = get_managers(parts) + for mgr in managers: + if mgr is managers[-1]: + out.stack_adjust(mgr.final_offset.deep, mgr.final_offset.high) + mgr.adjust_inverse(mgr.final_offset) + # NULL out the output stack effects + for poke in mgr.pokes: + if not poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names: + out.emit( + f"PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)" + f"PARTITIONNODE_NULLROOT, PEEK(-({poke.offset.as_index()})), true);" + ) diff --git a/Tools/clinic/.ruff.toml b/Tools/clinic/.ruff.toml new file mode 100644 index 00000000000000..cbb3a9a8f3a8c2 --- /dev/null +++ b/Tools/clinic/.ruff.toml @@ -0,0 +1,29 @@ +target-version = "py310" +fix = true +select = [ + "F", # Enable all pyflakes rules + "UP", # Enable all pyupgrade rules by default + "RUF100", # Ban unused `# noqa` comments + "PGH004", # Ban blanket `# noqa` comments (only ignore specific error codes) +] +ignore = [ + # Unnecessary parentheses to functools.lru_cache: just leads to unnecessary churn. + # https://github.com/python/cpython/pull/104684#discussion_r1199653347. + "UP011", + # Use format specifiers instead of %-style formatting. + # Doesn't always make code more readable. + "UP031", + # Use f-strings instead of format specifiers. + # Doesn't always make code more readable. + "UP032", + # Use PEP-604 unions rather than tuples for isinstance() checks. + # Makes code slower and more verbose. https://github.com/astral-sh/ruff/issues/7871. + "UP038", +] +unfixable = [ + # The autofixes sometimes do the wrong things for these; + # it's better to have to manually look at the code and see how it needs fixing + "F841", # Detects unused variables + "F601", # Detects dictionaries that have duplicate keys + "F602", # Also detects dictionaries that have duplicate keys +] diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index bff8935df13bc6..1bcc85537bf2da 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -7,6 +7,7 @@ from __future__ import annotations import abc +import argparse import ast import builtins as bltns import collections @@ -27,7 +28,6 @@ import string import sys import textwrap -import traceback from collections.abc import ( Callable, @@ -35,15 +35,18 @@ Iterator, Sequence, ) +from operator import attrgetter from types import FunctionType, NoneType from typing import ( + TYPE_CHECKING, Any, Final, Literal, NamedTuple, NoReturn, Protocol, - TypeGuard, + TypeVar, + cast, overload, ) @@ -75,6 +78,12 @@ "return_value", } +# '#include "header.h" // reason': column of '//' comment +INCLUDE_COMMENT_COLUMN = 35 + +# match '#define Py_LIMITED_API' +LIMITED_CAPI_REGEX = re.compile(r'#define +Py_LIMITED_API') + class Sentinels(enum.Enum): unspecified = "unspecified" @@ -134,6 +143,28 @@ def text_accumulator() -> TextAccumulator: text, append, output = _text_accumulator() return TextAccumulator(append, output) + +@dc.dataclass +class ClinicError(Exception): + message: str + _: dc.KW_ONLY + lineno: int | None = None + filename: str | None = None + + def __post_init__(self) -> None: + super().__init__(self.message) + + def report(self, *, warn_only: bool = False) -> str: + msg = "Warning" if warn_only else "Error" + if self.filename is not None: + msg += f" in file {self.filename!r}" + if self.lineno is not None: + msg += f" on line {self.lineno}" + msg += ":\n" + msg += f"{self.message}\n" + return msg + + @overload def warn_or_fail( *args: object, @@ -157,25 +188,16 @@ def warn_or_fail( line_number: int | None = None, ) -> None: joined = " ".join([str(a) for a in args]) - add, output = text_accumulator() - if fail: - add("Error") - else: - add("Warning") if clinic: if filename is None: filename = clinic.filename if getattr(clinic, 'block_parser', None) and (line_number is None): line_number = clinic.block_parser.line_number - if filename is not None: - add(' in file "' + filename + '"') - if line_number is not None: - add(" on line " + str(line_number)) - add(':\n') - add(joined) - print(output()) + error = ClinicError(joined, filename=filename, lineno=line_number) if fail: - sys.exit(-1) + raise error + else: + print(error.report(warn_only=True)) def warn( @@ -206,6 +228,20 @@ def c_repr(s: str) -> str: return '"' + s + '"' +def wrapped_c_string_literal( + text: str, + *, + width: int = 72, + suffix: str = '', + initial_indent: int = 0, + subsequent_indent: int = 4 +) -> str: + wrapped = textwrap.wrap(text, width=width, replace_whitespace=False, + drop_whitespace=False, break_on_hyphens=False) + separator = '"' + suffix + '\n' + subsequent_indent * ' ' + '"' + return initial_indent * ' ' + '"' + separator.join(wrapped) + '"' + + is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match def is_legal_py_identifier(s: str) -> bool: @@ -275,9 +311,11 @@ def linear_format(s: str, **kwargs: str) -> str: continue if trailing: - fail("Text found after {" + name + "} block marker! It must be on a line by itself.") + fail(f"Text found after {{{name}}} block marker! " + "It must be on a line by itself.") if indent.strip(): - fail("Non-whitespace characters found before {" + name + "} block marker! It must be on a line by itself.") + fail(f"Non-whitespace characters found before {{{name}}} block marker! " + "It must be on a line by itself.") value = kwargs[name] if not value: @@ -330,6 +368,13 @@ def suffix_all_lines(s: str, suffix: str) -> str: return ''.join(final) +def pprint_words(items: list[str]) -> str: + if len(items) <= 2: + return " and ".join(items) + else: + return ", ".join(items[:-1]) + " and " + items[-1] + + def version_splitter(s: str) -> tuple[int, ...]: """Splits a version string into a tuple of integers. @@ -344,7 +389,7 @@ def version_splitter(s: str) -> tuple[int, ...]: accumulator: list[str] = [] def flush() -> None: if not accumulator: - raise ValueError('Unsupported version string: ' + repr(s)) + fail(f'Unsupported version string: {s!r}') version.append(int(''.join(accumulator))) accumulator.clear() @@ -357,13 +402,15 @@ def flush() -> None: flush() version.append('abc'.index(c) - 3) else: - raise ValueError('Illegal character ' + repr(c) + ' in version string ' + repr(s)) + fail(f'Illegal character {c!r} in version string {s!r}') flush() return tuple(version) def version_comparitor(version1: str, version2: str) -> Literal[-1, 0, 1]: - iterator = itertools.zip_longest(version_splitter(version1), version_splitter(version2), fillvalue=0) - for i, (a, b) in enumerate(iterator): + iterator = itertools.zip_longest( + version_splitter(version1), version_splitter(version2), fillvalue=0 + ) + for a, b in iterator: if a < b: return -1 if a > b: @@ -372,36 +419,36 @@ def version_comparitor(version1: str, version2: str) -> Literal[-1, 0, 1]: class CRenderData: - def __init__(self): + def __init__(self) -> None: # The C statements to declare variables. # Should be full lines with \n eol characters. - self.declarations = [] + self.declarations: list[str] = [] # The C statements required to initialize the variables before the parse call. # Should be full lines with \n eol characters. - self.initializers = [] + self.initializers: list[str] = [] # The C statements needed to dynamically modify the values # parsed by the parse call, before calling the impl. - self.modifications = [] + self.modifications: list[str] = [] # The entries for the "keywords" array for PyArg_ParseTuple. # Should be individual strings representing the names. - self.keywords = [] + self.keywords: list[str] = [] # The "format units" for PyArg_ParseTuple. # Should be individual strings that will get - self.format_units = [] + self.format_units: list[str] = [] # The varargs arguments for PyArg_ParseTuple. - self.parse_arguments = [] + self.parse_arguments: list[str] = [] # The parameter declarations for the impl function. - self.impl_parameters = [] + self.impl_parameters: list[str] = [] # The arguments to the impl function at the time it's called. - self.impl_arguments = [] + self.impl_arguments: list[str] = [] # For return converters: the name of the variable that # should receive the value returned by the impl. @@ -411,17 +458,17 @@ def __init__(self): # value from the parse function. This is also where # you should check the _return_value for errors, and # "goto exit" if there are any. - self.return_conversion = [] + self.return_conversion: list[str] = [] self.converter_retval = "_return_value" # The C statements required to do some operations # after the end of parsing but before cleaning up. # These operations may be, for example, memory deallocations which # can only be done without any error happening during argument parsing. - self.post_parsing = [] + self.post_parsing: list[str] = [] # The C statements required to clean up after the impl call. - self.cleanup = [] + self.cleanup: list[str] = [] class FormatCounterFormatter(string.Formatter): @@ -436,7 +483,9 @@ class FormatCounterFormatter(string.Formatter): def __init__(self) -> None: self.counts = collections.Counter[str]() - def get_value(self, key: str, args, kwargs) -> str: # type: ignore[override] + def get_value( + self, key: str, args: object, kwargs: object # type: ignore[override] + ) -> Literal['']: self.counts[key] += 1 return '' @@ -448,7 +497,7 @@ class Language(metaclass=abc.ABCMeta): checksum_line = "" def __init__(self, filename: str) -> None: - pass + ... @abc.abstractmethod def render( @@ -456,10 +505,10 @@ def render( clinic: Clinic | None, signatures: Iterable[Module | Class | Function] ) -> str: - pass + ... def parse_line(self, line: str) -> None: - pass + ... def validate(self) -> None: def assert_only_one( @@ -530,12 +579,11 @@ class PythonLanguage(Language): checksum_line = "#/*[{dsl_name} end generated code: {arguments}]*/" -ParamGroup = Iterable["Parameter"] ParamTuple = tuple["Parameter", ...] def permute_left_option_groups( - l: Sequence[ParamGroup] + l: Sequence[Iterable[Parameter]] ) -> Iterator[ParamTuple]: """ Given [(1,), (2,), (3,)], should yield: @@ -552,7 +600,7 @@ def permute_left_option_groups( def permute_right_option_groups( - l: Sequence[ParamGroup] + l: Sequence[Iterable[Parameter]] ) -> Iterator[ParamTuple]: """ Given [(1,), (2,), (3,)], should yield: @@ -569,9 +617,9 @@ def permute_right_option_groups( def permute_optional_groups( - left: Sequence[ParamGroup], - required: ParamGroup, - right: Sequence[ParamGroup] + left: Sequence[Iterable[Parameter]], + required: Iterable[Parameter], + right: Sequence[Iterable[Parameter]] ) -> tuple[ParamTuple, ...]: """ Generator function that computes the set of acceptable @@ -632,7 +680,9 @@ def normalize_snippet( def declare_parser( f: Function, *, - hasformat: bool = False + hasformat: bool = False, + clinic: Clinic, + limited_capi: bool, ) -> str: """ Generates the code template for a static local PyArg_Parser variable, @@ -651,7 +701,11 @@ def declare_parser( p for p in f.parameters.values() if not p.is_positional_only() and not p.is_vararg() ]) - if num_keywords == 0: + if limited_capi: + declarations = """ + #define KWTUPLE NULL + """ + elif num_keywords == 0: declarations = """ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) @@ -680,6 +734,10 @@ def declare_parser( #endif // !Py_BUILD_CORE """ % num_keywords + condition = '#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)' + clinic.add_include('pycore_gc.h', 'PyGC_Head', condition=condition) + clinic.add_include('pycore_runtime.h', '_Py_ID()', condition=condition) + declarations += """ static const char * const _keywords[] = {{{keywords_c} NULL}}; static _PyArg_Parser _parser = {{ @@ -756,6 +814,80 @@ class CLanguage(Language): stop_line = "[{dsl_name} start generated code]*/" checksum_line = "/*[{dsl_name} end generated code: {arguments}]*/" + PARSER_PROTOTYPE_KEYWORD: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) + """) + PARSER_PROTOTYPE_KEYWORD___INIT__: Final[str] = normalize_snippet(""" + static int + {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) + """) + PARSER_PROTOTYPE_VARARGS: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *args) + """) + PARSER_PROTOTYPE_FASTCALL: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs) + """) + PARSER_PROTOTYPE_FASTCALL_KEYWORDS: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) + """) + PARSER_PROTOTYPE_DEF_CLASS: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyTypeObject *{defining_class_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) + """) + PARSER_PROTOTYPE_NOARGS: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) + """) + METH_O_PROTOTYPE: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({impl_parameters}) + """) + DOCSTRING_PROTOTYPE_VAR: Final[str] = normalize_snippet(""" + PyDoc_VAR({c_basename}__doc__); + """) + DOCSTRING_PROTOTYPE_STRVAR: Final[str] = normalize_snippet(""" + PyDoc_STRVAR({c_basename}__doc__, + {docstring}); + """) + IMPL_DEFINITION_PROTOTYPE: Final[str] = normalize_snippet(""" + static {impl_return_type} + {c_basename}_impl({impl_parameters}) + """) + METHODDEF_PROTOTYPE_DEFINE: Final[str] = normalize_snippet(r""" + #define {methoddef_name} \ + {{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}}, + """) + METHODDEF_PROTOTYPE_IFNDEF: Final[str] = normalize_snippet(""" + #ifndef {methoddef_name} + #define {methoddef_name} + #endif /* !defined({methoddef_name}) */ + """) + COMPILER_DEPRECATION_WARNING_PROTOTYPE: Final[str] = r""" + // Emit compiler warnings when we get to Python {major}.{minor}. + #if PY_VERSION_HEX >= 0x{major:02x}{minor:02x}00C0 + # error {message} + #elif PY_VERSION_HEX >= 0x{major:02x}{minor:02x}00A0 + # ifdef _MSC_VER + # pragma message ({message}) + # else + # warning {message} + # endif + #endif + """ + DEPRECATION_WARNING_PROTOTYPE: Final[str] = r""" + if ({condition}) {{{{{errcheck} + if (PyErr_WarnEx(PyExc_DeprecationWarning, + {message}, 1)) + {{{{ + goto exit; + }}}} + }}}} + """ + def __init__(self, filename: str) -> None: super().__init__(filename) self.cpp = cpp.Monitor(filename) @@ -777,13 +909,167 @@ def render( function = o return self.render_function(clinic, function) + def compiler_deprecated_warning( + self, + func: Function, + parameters: list[Parameter], + ) -> str | None: + minversion: VersionTuple | None = None + for p in parameters: + for version in p.deprecated_positional, p.deprecated_keyword: + if version and (not minversion or minversion > version): + minversion = version + if not minversion: + return None + + # Format the preprocessor warning and error messages. + assert isinstance(self.cpp.filename, str) + message = f"Update the clinic input of {func.full_name!r}." + code = self.COMPILER_DEPRECATION_WARNING_PROTOTYPE.format( + major=minversion[0], + minor=minversion[1], + message=c_repr(message), + ) + return normalize_snippet(code) + + def deprecate_positional_use( + self, + func: Function, + params: dict[int, Parameter], + ) -> str: + assert len(params) > 0 + first_pos = next(iter(params)) + last_pos = next(reversed(params)) + + # Format the deprecation message. + if len(params) == 1: + condition = f"nargs == {first_pos+1}" + amount = f"{first_pos+1} " if first_pos else "" + pl = "s" + else: + condition = f"nargs > {first_pos} && nargs <= {last_pos+1}" + amount = f"more than {first_pos} " if first_pos else "" + pl = "s" if first_pos != 1 else "" + message = ( + f"Passing {amount}positional argument{pl} to " + f"{func.fulldisplayname}() is deprecated." + ) + + for (major, minor), group in itertools.groupby( + params.values(), key=attrgetter("deprecated_positional") + ): + names = [repr(p.name) for p in group] + pstr = pprint_words(names) + if len(names) == 1: + message += ( + f" Parameter {pstr} will become a keyword-only parameter " + f"in Python {major}.{minor}." + ) + else: + message += ( + f" Parameters {pstr} will become keyword-only parameters " + f"in Python {major}.{minor}." + ) + + # Append deprecation warning to docstring. + docstring = textwrap.fill(f"Note: {message}") + func.docstring += f"\n\n{docstring}\n" + # Format and return the code block. + code = self.DEPRECATION_WARNING_PROTOTYPE.format( + condition=condition, + errcheck="", + message=wrapped_c_string_literal(message, width=64, + subsequent_indent=20), + ) + return normalize_snippet(code, indent=4) + + def deprecate_keyword_use( + self, + func: Function, + params: dict[int, Parameter], + argname_fmt: str | None, + *, + fastcall: bool, + limited_capi: bool, + clinic: Clinic, + ) -> str: + assert len(params) > 0 + last_param = next(reversed(params.values())) + + # Format the deprecation message. + containscheck = "" + conditions = [] + for i, p in params.items(): + if p.is_optional(): + if argname_fmt: + conditions.append(f"nargs < {i+1} && {argname_fmt % i}") + elif fastcall: + conditions.append(f"nargs < {i+1} && PySequence_Contains(kwnames, &_Py_ID({p.name}))") + containscheck = "PySequence_Contains" + clinic.add_include('pycore_runtime.h', '_Py_ID()') + else: + conditions.append(f"nargs < {i+1} && PyDict_Contains(kwargs, &_Py_ID({p.name}))") + containscheck = "PyDict_Contains" + clinic.add_include('pycore_runtime.h', '_Py_ID()') + else: + conditions = [f"nargs < {i+1}"] + condition = ") || (".join(conditions) + if len(conditions) > 1: + condition = f"(({condition}))" + if last_param.is_optional(): + if fastcall: + if limited_capi: + condition = f"kwnames && PyTuple_Size(kwnames) && {condition}" + else: + condition = f"kwnames && PyTuple_GET_SIZE(kwnames) && {condition}" + else: + if limited_capi: + condition = f"kwargs && PyDict_Size(kwargs) && {condition}" + else: + condition = f"kwargs && PyDict_GET_SIZE(kwargs) && {condition}" + names = [repr(p.name) for p in params.values()] + pstr = pprint_words(names) + pl = 's' if len(params) != 1 else '' + message = ( + f"Passing keyword argument{pl} {pstr} to " + f"{func.fulldisplayname}() is deprecated." + ) + + for (major, minor), group in itertools.groupby( + params.values(), key=attrgetter("deprecated_keyword") + ): + names = [repr(p.name) for p in group] + pstr = pprint_words(names) + pl = 's' if len(names) != 1 else '' + message += ( + f" Parameter{pl} {pstr} will become positional-only " + f"in Python {major}.{minor}." + ) + + if containscheck: + errcheck = f""" + if (PyErr_Occurred()) {{{{ // {containscheck}() above can fail + goto exit; + }}}}""" + else: + errcheck = "" + if argname_fmt: + # Append deprecation warning to docstring. + docstring = textwrap.fill(f"Note: {message}") + func.docstring += f"\n\n{docstring}\n" + # Format and return the code block. + code = self.DEPRECATION_WARNING_PROTOTYPE.format( + condition=condition, + errcheck=errcheck, + message=wrapped_c_string_literal(message, width=64, + subsequent_indent=20), + ) + return normalize_snippet(code, indent=4) + def docstring_for_c_string( self, f: Function ) -> str: - if re.search(r'[^\x00-\x7F]', f.docstring): - warn("Non-ascii character appear in docstring.") - text, add, output = _text_accumulator() # turn docstring into a properly quoted C string for line in f.docstring.split('\n'): @@ -802,7 +1088,8 @@ def docstring_for_c_string( def output_templates( self, - f: Function + f: Function, + clinic: Clinic ) -> dict[str, str]: parameters = list(f.parameters.values()) assert parameters @@ -814,10 +1101,15 @@ def output_templates( del parameters[0] converters = [p.converter for p in parameters] - has_option_groups = parameters and (parameters[0].group or parameters[-1].group) - default_return_converter = (not f.return_converter or - f.return_converter.type == 'PyObject *') + # Copy includes from parameters to Clinic + for converter in converters: + include = converter.include + if include: + clinic.add_include(include.filename, include.reason, + condition=include.condition) + has_option_groups = parameters and (parameters[0].group or parameters[-1].group) + default_return_converter = f.return_converter.type == 'PyObject *' new_or_init = f.kind.new_or_init vararg: int | str = NO_VARARG @@ -860,52 +1152,15 @@ def output_templates( # methoddef_ifndef return_value_declaration = "PyObject *return_value = NULL;" - - methoddef_define = normalize_snippet(""" - #define {methoddef_name} \\ - {{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}}, - """) + methoddef_define = self.METHODDEF_PROTOTYPE_DEFINE if new_or_init and not f.docstring: docstring_prototype = docstring_definition = '' else: - docstring_prototype = normalize_snippet(""" - PyDoc_VAR({c_basename}__doc__); - """) - docstring_definition = normalize_snippet(""" - PyDoc_STRVAR({c_basename}__doc__, - {docstring}); - """) - impl_definition = normalize_snippet(""" - static {impl_return_type} - {c_basename}_impl({impl_parameters}) - """) + docstring_prototype = self.DOCSTRING_PROTOTYPE_VAR + docstring_definition = self.DOCSTRING_PROTOTYPE_STRVAR + impl_definition = self.IMPL_DEFINITION_PROTOTYPE impl_prototype = parser_prototype = parser_definition = None - parser_prototype_keyword = normalize_snippet(""" - static PyObject * - {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) - """) - - parser_prototype_varargs = normalize_snippet(""" - static PyObject * - {c_basename}({self_type}{self_name}, PyObject *args) - """) - - parser_prototype_fastcall = normalize_snippet(""" - static PyObject * - {c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs) - """) - - parser_prototype_fastcall_keywords = normalize_snippet(""" - static PyObject * - {c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) - """) - - parser_prototype_def_class = normalize_snippet(""" - static PyObject * - {c_basename}({self_type}{self_name}, PyTypeObject *{defining_class_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) - """) - # parser_body_fields remembers the fields passed in to the # previous call to parser_body. this is used for an awful hack. parser_body_fields: tuple[str, ...] = () @@ -942,25 +1197,28 @@ def parser_body( add(field) return linear_format(output(), parser_declarations=declarations) + fastcall = not new_or_init + limited_capi = clinic.limited_capi + if limited_capi and (requires_defining_class or pseudo_args or + (any(p.is_optional() for p in parameters) and + any(p.is_keyword_only() and not p.is_optional() for p in parameters)) or + any(c.broken_limited_capi for c in converters)): + warn(f"Function {f.full_name} cannot use limited C API") + limited_capi = False + parsearg: str | None if not parameters: parser_code: list[str] | None if not requires_defining_class: # no parameters, METH_NOARGS flags = "METH_NOARGS" - - parser_prototype = normalize_snippet(""" - static PyObject * - {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) - """) + parser_prototype = self.PARSER_PROTOTYPE_NOARGS parser_code = [] - else: - assert not new_or_init + assert fastcall flags = "METH_METHOD|METH_FASTCALL|METH_KEYWORDS" - - parser_prototype = parser_prototype_def_class + parser_prototype = self.PARSER_PROTOTYPE_DEF_CLASS return_error = ('return NULL;' if default_return_converter else 'goto exit;') parser_code = [normalize_snippet(""" @@ -985,10 +1243,7 @@ def parser_body( if (isinstance(converters[0], object_converter) and converters[0].format_unit == 'O'): - meth_o_prototype = normalize_snippet(""" - static PyObject * - {c_basename}({impl_parameters}) - """) + meth_o_prototype = self.METH_O_PROTOTYPE if default_return_converter: # maps perfectly to METH_O, doesn't need a return converter. @@ -1012,7 +1267,7 @@ def parser_body( """ % argname) displayname = parameters[0].get_displayname(0) - parsearg = converters[0].parse_arg(argname, displayname) + parsearg = converters[0].parse_arg(argname, displayname, limited_capi=limited_capi) if parsearg is None: parsearg = """ if (!PyArg_Parse(%s, "{format_units}:{name}", {parse_arguments})) {{ @@ -1028,17 +1283,16 @@ def parser_body( # in a big switch statement) flags = "METH_VARARGS" - parser_prototype = parser_prototype_varargs - + parser_prototype = self.PARSER_PROTOTYPE_VARARGS parser_definition = parser_body(parser_prototype, ' {option_group_parsing}') elif not requires_defining_class and pos_only == len(parameters) - pseudo_args: - if not new_or_init: + if fastcall: # positional-only, but no option groups # we only need one call to _PyArg_ParseStack flags = "METH_FASTCALL" - parser_prototype = parser_prototype_fastcall + parser_prototype = self.PARSER_PROTOTYPE_FASTCALL nargs = 'nargs' argname_fmt = 'args[%d]' else: @@ -1046,26 +1300,60 @@ def parser_body( # we only need one call to PyArg_ParseTuple flags = "METH_VARARGS" - parser_prototype = parser_prototype_varargs - nargs = 'PyTuple_GET_SIZE(args)' - argname_fmt = 'PyTuple_GET_ITEM(args, %d)' - + parser_prototype = self.PARSER_PROTOTYPE_VARARGS + if limited_capi: + nargs = 'PyTuple_Size(args)' + argname_fmt = 'PyTuple_GetItem(args, %d)' + else: + nargs = 'PyTuple_GET_SIZE(args)' + argname_fmt = 'PyTuple_GET_ITEM(args, %d)' left_args = f"{nargs} - {max_pos}" max_args = NO_VARARG if (vararg != NO_VARARG) else max_pos - parser_code = [normalize_snippet(""" - if (!_PyArg_CheckPositional("{name}", %s, %d, %s)) {{ - goto exit; - }} - """ % (nargs, min_pos, max_args), indent=4)] + if limited_capi: + parser_code = [] + if nargs != 'nargs': + parser_code.append(normalize_snippet(f'Py_ssize_t nargs = {nargs};', indent=4)) + nargs = 'nargs' + if min_pos == max_args: + pl = '' if min_pos == 1 else 's' + parser_code.append(normalize_snippet(f""" + if ({nargs} != {min_pos}) {{{{ + PyErr_Format(PyExc_TypeError, "{{name}} expected {min_pos} argument{pl}, got %zd", {nargs}); + goto exit; + }}}} + """, + indent=4)) + else: + if min_pos: + pl = '' if min_pos == 1 else 's' + parser_code.append(normalize_snippet(f""" + if ({nargs} < {min_pos}) {{{{ + PyErr_Format(PyExc_TypeError, "{{name}} expected at least {min_pos} argument{pl}, got %zd", {nargs}); + goto exit; + }}}} + """, + indent=4)) + if max_args != NO_VARARG: + pl = '' if max_args == 1 else 's' + parser_code.append(normalize_snippet(f""" + if ({nargs} > {max_args}) {{{{ + PyErr_Format(PyExc_TypeError, "{{name}} expected at most {max_args} argument{pl}, got %zd", {nargs}); + goto exit; + }}}} + """, + indent=4)) + else: + parser_code = [normalize_snippet(f""" + if (!_PyArg_CheckPositional("{{name}}", {nargs}, {min_pos}, {max_args})) {{{{ + goto exit; + }}}} + """, indent=4)] has_optional = False for i, p in enumerate(parameters): - displayname = p.get_displayname(i+1) - argname = argname_fmt % i - if p.is_vararg(): - if not new_or_init: + if fastcall: parser_code.append(normalize_snippet(""" %s = PyTuple_New(%s); if (!%s) {{ @@ -1091,9 +1379,10 @@ def parser_body( ), indent=4)) continue - parsearg = p.converter.parse_arg(argname, displayname) + displayname = p.get_displayname(i+1) + argname = argname_fmt % i + parsearg = p.converter.parse_arg(argname, displayname, limited_capi=limited_capi) 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 break if has_optional or p.is_optional(): @@ -1109,7 +1398,9 @@ def parser_body( if has_optional: parser_code.append("skip_optional:") else: - if not new_or_init: + if limited_capi: + fastcall = False + if fastcall: parser_code = [normalize_snippet(""" if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}", {parse_arguments})) {{ @@ -1117,6 +1408,8 @@ def parser_body( }} """, indent=4)] else: + flags = "METH_VARARGS" + parser_prototype = self.PARSER_PROTOTYPE_VARARGS parser_code = [normalize_snippet(""" if (!PyArg_ParseTuple(args, "{format_units}:{name}", {parse_arguments})) {{ @@ -1126,6 +1419,14 @@ def parser_body( parser_definition = parser_body(parser_prototype, *parser_code) else: + deprecated_positionals: dict[int, Parameter] = {} + deprecated_keywords: dict[int, Parameter] = {} + for i, p in enumerate(parameters): + if p.deprecated_positional: + deprecated_positionals[i] = p + if p.deprecated_keyword: + deprecated_keywords[i] = p + has_optional_kw = (max(pos_only, min_pos) + min_kw_only < len(converters) - int(vararg != NO_VARARG)) if vararg == NO_VARARG: args_declaration = "_PyArg_UnpackKeywords", "%s, %s, %s" % ( @@ -1142,11 +1443,17 @@ def parser_body( vararg ) nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0" - if not new_or_init: + + if limited_capi: + parser_code = None + fastcall = False + + elif fastcall: flags = "METH_FASTCALL|METH_KEYWORDS" - parser_prototype = parser_prototype_fastcall_keywords + parser_prototype = self.PARSER_PROTOTYPE_FASTCALL_KEYWORDS argname_fmt = 'args[%d]' - declarations = declare_parser(f) + declarations = declare_parser(f, clinic=clinic, + limited_capi=clinic.limited_capi) declarations += "\nPyObject *argsbuf[%s];" % len(converters) if has_optional_kw: declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (nargs, min_pos + min_kw_only) @@ -1159,9 +1466,10 @@ def parser_body( else: # positional-or-keyword arguments flags = "METH_VARARGS|METH_KEYWORDS" - parser_prototype = parser_prototype_keyword + parser_prototype = self.PARSER_PROTOTYPE_KEYWORD argname_fmt = 'fastargs[%d]' - declarations = declare_parser(f) + declarations = declare_parser(f, clinic=clinic, + limited_capi=clinic.limited_capi) declarations += "\nPyObject *argsbuf[%s];" % len(converters) declarations += "\nPyObject * const *fastargs;" declarations += "\nPy_ssize_t nargs = PyTuple_GET_SIZE(args);" @@ -1176,73 +1484,96 @@ def parser_body( if requires_defining_class: flags = 'METH_METHOD|' + flags - parser_prototype = parser_prototype_def_class + parser_prototype = self.PARSER_PROTOTYPE_DEF_CLASS - add_label: str | None = None - for i, p in enumerate(parameters): - if isinstance(p.converter, defining_class_converter): - raise ValueError("defining_class should be the first " - "parameter (after self)") - 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 - break - if add_label and (i == pos_only or i == max_pos): - parser_code.append("%s:" % add_label) - add_label = None - if not p.is_optional(): - parser_code.append(normalize_snippet(parsearg, indent=4)) - elif i < pos_only: - add_label = 'skip_optional_posonly' - parser_code.append(normalize_snippet(""" - if (nargs < %d) {{ - goto %s; - }} - """ % (i + 1, add_label), indent=4)) - if has_optional_kw: - parser_code.append(normalize_snippet(""" - noptargs--; - """, indent=4)) - parser_code.append(normalize_snippet(parsearg, indent=4)) - else: - if i < max_pos: - label = 'skip_optional_pos' - first_opt = max(min_pos, pos_only) - else: - label = 'skip_optional_kwonly' - first_opt = max_pos + min_kw_only - if vararg != NO_VARARG: - first_opt += 1 - if i == first_opt: - add_label = label + if parser_code is not None: + if deprecated_keywords: + code = self.deprecate_keyword_use(f, deprecated_keywords, argname_fmt, + clinic=clinic, + fastcall=fastcall, + limited_capi=limited_capi) + parser_code.append(code) + + add_label: str | None = None + for i, p in enumerate(parameters): + if isinstance(p.converter, defining_class_converter): + raise ValueError("defining_class should be the first " + "parameter (after self)") + displayname = p.get_displayname(i+1) + parsearg = p.converter.parse_arg(argname_fmt % i, displayname, limited_capi=limited_capi) + if parsearg is None: + parser_code = None + break + if add_label and (i == pos_only or i == max_pos): + parser_code.append("%s:" % add_label) + add_label = None + if not p.is_optional(): + parser_code.append(normalize_snippet(parsearg, indent=4)) + elif i < pos_only: + add_label = 'skip_optional_posonly' parser_code.append(normalize_snippet(""" - if (!noptargs) {{ + if (nargs < %d) {{ goto %s; }} - """ % add_label, indent=4)) - if i + 1 == len(parameters): + """ % (i + 1, add_label), indent=4)) + if has_optional_kw: + parser_code.append(normalize_snippet(""" + noptargs--; + """, indent=4)) parser_code.append(normalize_snippet(parsearg, indent=4)) else: - add_label = label - parser_code.append(normalize_snippet(""" - if (%s) {{ - """ % (argname_fmt % i), indent=4)) - parser_code.append(normalize_snippet(parsearg, indent=8)) - parser_code.append(normalize_snippet(""" - if (!--noptargs) {{ + if i < max_pos: + label = 'skip_optional_pos' + first_opt = max(min_pos, pos_only) + else: + label = 'skip_optional_kwonly' + first_opt = max_pos + min_kw_only + if vararg != NO_VARARG: + first_opt += 1 + if i == first_opt: + add_label = label + parser_code.append(normalize_snippet(""" + if (!noptargs) {{ goto %s; }} - }} - """ % add_label, indent=4)) + """ % add_label, indent=4)) + if i + 1 == len(parameters): + parser_code.append(normalize_snippet(parsearg, indent=4)) + else: + add_label = label + parser_code.append(normalize_snippet(""" + if (%s) {{ + """ % (argname_fmt % i), indent=4)) + parser_code.append(normalize_snippet(parsearg, indent=8)) + parser_code.append(normalize_snippet(""" + if (!--noptargs) {{ + goto %s; + }} + }} + """ % add_label, indent=4)) if parser_code is not None: if add_label: parser_code.append("%s:" % add_label) else: - declarations = declare_parser(f, hasformat=True) - if not new_or_init: + declarations = declare_parser(f, clinic=clinic, + hasformat=True, + limited_capi=limited_capi) + if limited_capi: + # positional-or-keyword arguments + assert not fastcall + flags = "METH_VARARGS|METH_KEYWORDS" + parser_prototype = self.PARSER_PROTOTYPE_KEYWORD + parser_code = [normalize_snippet(""" + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "{format_units}:{name}", _keywords, + {parse_arguments})) + goto exit; + """, indent=4)] + declarations = "static char *_keywords[] = {{{keywords_c} NULL}};" + if deprecated_positionals or deprecated_keywords: + declarations += "\nPy_ssize_t nargs = PyTuple_Size(args);" + + elif fastcall: parser_code = [normalize_snippet(""" if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser{parse_arguments_comma} {parse_arguments})) {{ @@ -1256,6 +1587,21 @@ def parser_body( goto exit; }} """, indent=4)] + if deprecated_positionals or deprecated_keywords: + declarations += "\nPy_ssize_t nargs = PyTuple_GET_SIZE(args);" + if deprecated_keywords: + code = self.deprecate_keyword_use(f, deprecated_keywords, None, + clinic=clinic, + fastcall=fastcall, + limited_capi=limited_capi) + parser_code.append(code) + + if deprecated_positionals: + code = self.deprecate_positional_use(f, deprecated_positionals) + # Insert the deprecation code before parameter parsing. + parser_code.insert(0, code) + + assert parser_prototype is not None parser_definition = parser_body(parser_prototype, *parser_code, declarations=declarations) @@ -1264,13 +1610,10 @@ def parser_body( methoddef_define = '' if f.kind is METHOD_NEW: - parser_prototype = parser_prototype_keyword + parser_prototype = self.PARSER_PROTOTYPE_KEYWORD else: return_value_declaration = "int return_value = -1;" - parser_prototype = normalize_snippet(""" - static int - {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) - """) + parser_prototype = self.PARSER_PROTOTYPE_KEYWORD___INIT__ fields = list(parser_body_fields) parses_positional = 'METH_NOARGS' not in flags @@ -1302,6 +1645,9 @@ def parser_body( if flags in ('METH_NOARGS', 'METH_O', 'METH_VARARGS'): methoddef_cast = "(PyCFunction)" methoddef_cast_end = "" + elif limited_capi: + methoddef_cast = "(PyCFunction)(void(*)(void))" + methoddef_cast_end = "" else: methoddef_cast = "_PyCFunction_CAST(" methoddef_cast_end = ")" @@ -1321,16 +1667,9 @@ def parser_body( cpp_if = "#if " + conditional cpp_endif = "#endif /* " + conditional + " */" - assert clinic is not None - assert f.full_name is not None if methoddef_define and f.full_name not in clinic.ifndef_symbols: clinic.ifndef_symbols.add(f.full_name) - methoddef_ifndef = normalize_snippet(""" - #ifndef {methoddef_name} - #define {methoddef_name} - #endif /* !defined({methoddef_name}) */ - """) - + methoddef_ifndef = self.METHODDEF_PROTOTYPE_IFNDEF # add ';' to the end of parser_prototype and impl_prototype # (they mustn't be None, but they could be an empty string.) @@ -1346,6 +1685,10 @@ def parser_body( parser_definition = parser_definition.replace("{return_value_declaration}", return_value_declaration) + compiler_warning = self.compiler_deprecated_warning(f, parameters) + if compiler_warning: + parser_definition = compiler_warning + "\n\n" + parser_definition + d = { "docstring_prototype" : docstring_prototype, "docstring_definition" : docstring_definition, @@ -1374,7 +1717,12 @@ def group_to_variable_name(group: int) -> str: adjective = "left_" if group < 0 else "right_" return "group_" + adjective + str(abs(group)) - def render_option_group_parsing(self, f, template_dict): + def render_option_group_parsing( + self, + f: Function, + template_dict: TemplateDict, + limited_capi: bool, + ) -> None: # positional only, grouped, optional arguments! # can be optional on the left or right. # here's an example: @@ -1398,11 +1746,11 @@ def render_option_group_parsing(self, f, template_dict): if isinstance(parameters[0].converter, self_converter): del parameters[0] - group = None + group: list[Parameter] | None = None left = [] right = [] - required = [] - last = unspecified + required: list[Parameter] = [] + last: int | Literal[Sentinels.unspecified] = unspecified for p in parameters: group_id = p.group @@ -1415,12 +1763,17 @@ def render_option_group_parsing(self, f, template_dict): group = required else: right.append(group) + assert group is not None group.append(p) count_min = sys.maxsize count_max = -1 - add("switch (PyTuple_GET_SIZE(args)) {\n") + if limited_capi: + nargs = 'PyTuple_Size(args)' + else: + nargs = 'PyTuple_GET_SIZE(args)' + add(f"switch ({nargs}) {{\n") for subset in permute_optional_groups(left, required, right): count = len(subset) count_min = min(count_min, count) @@ -1433,19 +1786,21 @@ def render_option_group_parsing(self, f, template_dict): continue group_ids = {p.group for p in subset} # eliminate duplicates - d = {} + d: dict[str, str | int] = {} d['count'] = count d['name'] = f.name d['format_units'] = "".join(p.converter.format_unit for p in subset) - parse_arguments = [] + parse_arguments: list[str] = [] for p in subset: p.converter.parse_argument(parse_arguments) d['parse_arguments'] = ", ".join(parse_arguments) group_ids.discard(0) - lines = [self.group_to_variable_name(g) + " = 1;" for g in group_ids] - lines = "\n".join(lines) + lines = "\n".join([ + self.group_to_variable_name(g) + " = 1;" + for g in group_ids + ]) s = """\ case {count}: @@ -1481,7 +1836,7 @@ def render_function( parameters = f.render_parameters converters = [p.converter for p in parameters] - templates = self.output_templates(f) + templates = self.output_templates(f, clinic) f_self = parameters[0] selfless = parameters[1:] @@ -1490,7 +1845,6 @@ def render_function( last_group = 0 first_optional = len(selfless) positional = selfless and selfless[-1].is_positional_only() - new_or_init = f.kind.new_or_init has_option_groups = False # offset i by -1 because first_optional needs to ignore self @@ -1517,7 +1871,8 @@ def render_function( c.render(p, data) if has_option_groups and (not positional): - fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').") + fail("You cannot use optional groups ('[' and ']') " + "unless all parameters are positional-only ('/').") # HACK # when we're METH_O, but have a custom return converter, @@ -1531,31 +1886,11 @@ def render_function( '{impl_parameters}' in templates['parser_prototype']): data.declarations.pop(0) - template_dict = {} - - assert isinstance(f.full_name, str) full_name = f.full_name - template_dict['full_name'] = full_name - - if new_or_init: - assert isinstance(f.cls, Class) - name = f.cls.name - else: - name = f.name - - template_dict['name'] = name - - if f.c_basename: - c_basename = f.c_basename - else: - fields = full_name.split(".") - if fields[-1] == '__new__': - fields.pop() - c_basename = "_".join(fields) - - template_dict['c_basename'] = c_basename - - template_dict['methoddef_name'] = c_basename.upper() + "_METHODDEF" + template_dict = {'full_name': full_name} + template_dict['name'] = f.displayname + template_dict['c_basename'] = f.c_basename + template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF" template_dict['docstring'] = self.docstring_for_c_string(f) @@ -1594,7 +1929,8 @@ def render_function( template_dict['unpack_max'] = str(unpack_max) if has_option_groups: - self.render_option_group_parsing(f, template_dict) + self.render_option_group_parsing(f, template_dict, + limited_capi=clinic.limited_capi) # buffers, not destination for name, destination in clinic.destination_buffers.items(): @@ -1669,27 +2005,30 @@ class Block: found on the start line of the block between the square brackets. - signatures is either list or None. If it's a list, - it may only contain clinic.Module, clinic.Class, and + signatures is a list. + It may only contain clinic.Module, clinic.Class, and clinic.Function objects. At the moment it should contain at most one of each. output is either str or None. If str, it's the output from this block, with embedded '\n' characters. - indent is either str or None. It's the leading whitespace + indent is a str. It's the leading whitespace that was found on every line of input. (If body_prefix is not empty, this is the indent *after* removing the body_prefix.) - preindent is either str or None. It's the whitespace that + "indent" is different from the concept of "preindent" + (which is not stored as state on Block objects). + "preindent" is the whitespace that was found in front of every line of input *before* the "body_prefix" (see the Language object). If body_prefix is empty, preindent must always be empty too. - To illustrate indent and preindent: Assume that '_' - represents whitespace. If the block processed was in a - Python file, and looked like this: + To illustrate the difference between "indent" and "preindent": + + Assume that '_' represents whitespace. + If the block processed was in a Python file, and looked like this: ____#/*[python] ____#__for a in range(20): ____#____print(a) @@ -1702,7 +2041,6 @@ class Block: signatures: list[Module | Class | Function] = dc.field(default_factory=list) output: Any = None # TODO: Very dynamic; probably untypeable in its current form? indent: str = '' - preindent: str = '' def __repr__(self) -> str: dsl_name = self.dsl_name or "text" @@ -1711,8 +2049,12 @@ def summarize(s: object) -> str: if len(s) > 30: return s[:26] + "..." + s[0] return s - return "".join(( - "")) + parts = ( + repr(dsl_name), + f"input={summarize(self.input)}", + f"output={summarize(self.output)}" + ) + return f"" class BlockParser: @@ -1857,7 +2199,7 @@ def is_stop_line(line: str) -> bool: for field in shlex.split(arguments): name, equals, value = field.partition('=') if not equals: - fail("Mangled Argument Clinic marker line:", repr(line)) + fail(f"Mangled Argument Clinic marker line: {line!r}") d[name.strip()] = value.strip() if self.verify: @@ -1868,11 +2210,10 @@ def is_stop_line(line: str) -> bool: computed = compute_checksum(output, len(checksum)) if checksum != computed: - fail("Checksum mismatch!\nExpected: {}\nComputed: {}\n" + fail("Checksum mismatch! " + f"Expected {checksum!r}, computed {computed!r}. " "Suggested fix: remove all generated code including " - "the end marker,\n" - "or use the '-f' option." - .format(checksum, computed)) + "the end marker, or use the '-f' option.") else: # put back output output_lines = output.splitlines(keepends=True) @@ -1883,6 +2224,26 @@ def is_stop_line(line: str) -> bool: return Block(input_output(), dsl_name, output=output) +@dc.dataclass(slots=True, frozen=True) +class Include: + """ + An include like: #include "pycore_long.h" // _Py_ID() + """ + # Example: "pycore_long.h". + filename: str + + # Example: "_Py_ID()". + reason: str + + # None means unconditional include. + # Example: "#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)". + condition: str | None + + def sort_key(self) -> tuple[str, str]: + # order: '#if' comes before 'NO_CONDITION' + return (self.condition or 'NO_CONDITION', self.filename) + + @dc.dataclass(slots=True) class BlockPrinter: language: Language @@ -1892,7 +2253,9 @@ def print_block( self, block: Block, *, - core_includes: bool = False + core_includes: bool = False, + limited_capi: bool, + header_includes: dict[str, Include], ) -> None: input = block.input output = block.output @@ -1921,14 +2284,31 @@ def print_block( write("\n") output = '' - if core_includes: - output += textwrap.dedent(""" - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # include "pycore_gc.h" // PyGC_Head - # include "pycore_runtime.h" // _Py_ID() - #endif + if core_includes and header_includes: + # Emit optional "#include" directives for C headers + output += '\n' + + current_condition: str | None = None + includes = sorted(header_includes.values(), key=Include.sort_key) + for include in includes: + if include.condition != current_condition: + if current_condition: + output += '#endif\n' + current_condition = include.condition + if include.condition: + output += f'{include.condition}\n' + + if current_condition: + line = f'# include "{include.filename}"' + else: + line = f'#include "{include.filename}"' + if include.reason: + comment = f'// {include.reason}\n' + line = line.ljust(INCLUDE_COMMENT_COLUMN - 1) + comment + output += line - """) + if current_condition: + output += '#endif\n' input = ''.join(block.input) output += ''.join(block.output) @@ -1959,12 +2339,12 @@ class BufferSeries: e.g. o[-1] is an element immediately preceding o[0]. """ - def __init__(self): + def __init__(self) -> None: self._start = 0 - self._array = [] + self._array: list[_TextAccumulator] = [] self._constructor = _text_accumulator - def __getitem__(self, i): + def __getitem__(self, i: int) -> _TextAccumulator: i -= self._start if i < 0: self._start += i @@ -1975,11 +2355,11 @@ def __getitem__(self, i): self._array.append(self._constructor()) return self._array[i] - def clear(self): + def clear(self) -> None: for ta in self._array: - ta._text.clear() + ta.text.clear() - def dump(self): + def dump(self) -> str: texts = [ta.output() for ta in self._array] return "".join(texts) @@ -2003,13 +2383,13 @@ def __post_init__(self, args: tuple[str, ...]) -> None: ) extra_arguments = 1 if self.type == "file" else 0 if len(args) < extra_arguments: - fail(f"Not enough arguments for destination {self.name} new {self.type}") + fail(f"Not enough arguments for destination " + f"{self.name!r} new {self.type!r}") if len(args) > extra_arguments: - fail(f"Too many arguments for destination {self.name} new {self.type}") + fail(f"Too many arguments for destination {self.name!r} new {self.type!r}") if self.type =='file': d = {} filename = self.clinic.filename - assert filename is not None d['path'] = filename dirname, basename = os.path.split(filename) if not dirname: @@ -2021,33 +2401,29 @@ def __post_init__(self, args: tuple[str, ...]) -> None: def __repr__(self) -> str: if self.type == 'file': - file_repr = " " + repr(self.filename) + type_repr = f"type='file' file={self.filename!r}" else: - file_repr = '' - return "".join(("")) + type_repr = f"type={self.type!r}" + return f"" def clear(self) -> None: if self.type != 'buffer': - fail("Can't clear destination" + self.name + " , it's not of type buffer") + fail(f"Can't clear destination {self.name!r}: it's not of type 'buffer'") self.buffers.clear() def dump(self) -> str: return self.buffers.dump() -# maps strings to Language objects. -# "languages" maps the name of the language ("C", "Python"). -# "extensions" maps the file extension ("c", "py"). +# "extensions" maps the file extension ("c", "py") to Language classes. LangDict = dict[str, Callable[[str], Language]] - -languages = { 'C': CLanguage, 'Python': PythonLanguage } extensions: LangDict = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() } extensions['py'] = PythonLanguage def write_file(filename: str, new_contents: str) -> None: try: - with open(filename, 'r', encoding="utf-8") as fp: + with open(filename, encoding="utf-8") as fp: old_contents = fp.read() if old_contents == new_contents: @@ -2076,7 +2452,7 @@ def __init__(self, clinic: Clinic) -> None: ... def parse(self, block: Block) -> None: ... -clinic = None +clinic: Clinic | None = None class Clinic: presets_text = """ @@ -2127,8 +2503,9 @@ def __init__( language: CLanguage, printer: BlockPrinter | None = None, *, + filename: str, + limited_capi: bool, verify: bool = True, - filename: str | None = None ) -> None: # maps strings to Parser objects. # (instantiated from the "parsers" global.) @@ -2138,10 +2515,13 @@ def __init__( fail("Custom printers are broken right now") self.printer = printer or BlockPrinter(language) self.verify = verify + self.limited_capi = limited_capi self.filename = filename self.modules: ModuleDict = {} self.classes: ClassDict = {} self.functions: list[Function] = [] + # dict: include name => Include instance + self.includes: dict[str, Include] = {} self.line_prefix = self.line_suffix = '' @@ -2166,7 +2546,7 @@ def __init__( 'impl_definition': d('block'), } - DestBufferType = dict[str, Callable[..., Any]] + DestBufferType = dict[str, _TextAccumulator] DestBufferList = list[DestBufferType] self.destination_buffers_stack: DestBufferList = [] @@ -2200,6 +2580,24 @@ def __init__( global clinic clinic = self + def add_include(self, name: str, reason: str, + *, condition: str | None = None) -> None: + try: + existing = self.includes[name] + except KeyError: + pass + else: + if existing.condition and not condition: + # If the previous include has a condition and the new one is + # unconditional, override the include. + pass + else: + # Already included, do nothing. Only mention a single reason, + # no need to list all of them. + return + + self.includes[name] = Include(name, reason, condition) + def add_destination( self, name: str, @@ -2207,20 +2605,20 @@ def add_destination( *args: str ) -> None: if name in self.destinations: - fail("Destination already exists: " + repr(name)) + fail(f"Destination already exists: {name!r}") self.destinations[name] = Destination(name, type, self, args) def get_destination(self, name: str) -> Destination: d = self.destinations.get(name) if not d: - fail("Destination does not exist: " + repr(name)) + fail(f"Destination does not exist: {name!r}") return d def get_destination_buffer( self, name: str, item: int = 0 - ): + ) -> _TextAccumulator: d = self.get_destination(name) return d.buffers[item] @@ -2234,12 +2632,10 @@ def parse(self, input: str) -> str: assert dsl_name in parsers, f"No parser to handle {dsl_name!r} block." self.parsers[dsl_name] = parsers[dsl_name](self) parser = self.parsers[dsl_name] - try: - parser.parse(block) - except Exception: - fail('Exception raised during parsing:\n' + - traceback.format_exc().rstrip()) - printer.print_block(block) + parser.parse(block) + printer.print_block(block, + limited_capi=self.limited_capi, + header_includes=self.includes) # these are destinations not buffers for name, destination in self.destinations.items(): @@ -2254,7 +2650,9 @@ def parse(self, input: str) -> str: block.input = "dump " + name + "\n" warn("Destination buffer " + repr(name) + " not empty at end of file, emptying.") printer.write("\n") - printer.print_block(block) + printer.print_block(block, + limited_capi=self.limited_capi, + header_includes=self.includes) continue if destination.type == 'file': @@ -2264,28 +2662,33 @@ def parse(self, input: str) -> str: os.makedirs(dirname) except FileExistsError: if not os.path.isdir(dirname): - fail("Can't write to destination {}, " - "can't make directory {}!".format( - destination.filename, dirname)) + fail(f"Can't write to destination " + f"{destination.filename!r}; " + f"can't make directory {dirname!r}!") if self.verify: with open(destination.filename) as f: parser_2 = BlockParser(f.read(), language=self.language) blocks = list(parser_2) if (len(blocks) != 1) or (blocks[0].input != 'preserve\n'): - fail("Modified destination file " + repr(destination.filename) + ", not overwriting!") + fail(f"Modified destination file " + f"{destination.filename!r}; not overwriting!") except FileNotFoundError: pass block.input = 'preserve\n' printer_2 = BlockPrinter(self.language) - printer_2.print_block(block, core_includes=True) + printer_2.print_block(block, + core_includes=True, + limited_capi=self.limited_capi, + header_includes=self.includes) write_file(destination.filename, printer_2.f.getvalue()) continue return printer.f.getvalue() - - def _module_and_class(self, fields): + def _module_and_class( + self, fields: Sequence[str] + ) -> tuple[Module | Clinic, Class | None]: """ fields should be an iterable of field names. returns a tuple of (module, class). @@ -2293,46 +2696,45 @@ def _module_and_class(self, fields): this function is only ever used to find the parent of where a new class/module should go. """ - in_classes = False - parent = module = self - cls = None - so_far = [] - - for field in fields: - so_far.append(field) - if not in_classes: - child = parent.modules.get(field) - if child: - parent = module = child + parent: Clinic | Module | Class = self + module: Clinic | Module = self + cls: Class | None = None + + for idx, field in enumerate(fields): + if not isinstance(parent, Class): + if field in parent.modules: + parent = module = parent.modules[field] continue - in_classes = True - if not hasattr(parent, 'classes'): - return module, cls - child = parent.classes.get(field) - if not child: - fail('Parent class or module ' + '.'.join(so_far) + " does not exist.") - cls = parent = child + if field in parent.classes: + parent = cls = parent.classes[field] + else: + fullname = ".".join(fields[idx:]) + fail(f"Parent class or module {fullname!r} does not exist.") return module, cls + def __repr__(self) -> str: + return "" + def parse_file( filename: str, *, + limited_capi: bool, + output: str | None = None, verify: bool = True, - output: str | None = None ) -> None: if not output: output = filename extension = os.path.splitext(filename)[1][1:] if not extension: - fail("Can't extract file type for file " + repr(filename)) + fail(f"Can't extract file type for file {filename!r}") try: language = extensions[extension](filename) except KeyError: - fail("Can't identify file type for file " + repr(filename)) + fail(f"Can't identify file type for file {filename!r}") with open(filename, encoding="utf-8") as f: raw = f.read() @@ -2342,8 +2744,14 @@ def parse_file( if not find_start_re.search(raw): return + if LIMITED_CAPI_REGEX.search(raw): + limited_capi = True + assert isinstance(language, CLanguage) - clinic = Clinic(language, verify=verify, filename=filename) + clinic = Clinic(language, + verify=verify, + filename=filename, + limited_capi=limited_capi) cooked = clinic.parse(raw) write_file(output, cooked) @@ -2373,7 +2781,7 @@ def parse(self, block: Block) -> None: @dc.dataclass(repr=False) class Module: name: str - module: Module | None = None + module: Module | Clinic def __post_init__(self) -> None: self.parent = self.module @@ -2388,10 +2796,10 @@ def __repr__(self) -> str: @dc.dataclass(repr=False) class Class: name: str - module: Module | None = None - cls: Class | None = None - typedef: str | None = None - type_object: str | None = None + module: Module | Clinic + cls: Class | None + typedef: str + type_object: str def __post_init__(self) -> None: self.parent = self.cls or self.module @@ -2487,7 +2895,7 @@ def new_or_init(self) -> bool: return self in {FunctionKind.METHOD_INIT, FunctionKind.METHOD_NEW} def __repr__(self) -> str: - return f"" + return f"" INVALID: Final = FunctionKind.INVALID @@ -2516,15 +2924,15 @@ class Function: parameters: ParamDict = dc.field(default_factory=dict) _: dc.KW_ONLY name: str - module: Module - cls: Class | None = None - c_basename: str | None = None - full_name: str | None = None + module: Module | Clinic + cls: Class | None + c_basename: str + full_name: str return_converter: CReturnConverter + kind: FunctionKind + coexist: bool return_annotation: object = inspect.Signature.empty docstring: str = '' - kind: FunctionKind = CALLABLE - coexist: bool = False # docstring_only means "don't generate a machine-readable # signature, just a normal docstring". it's True for # functions with optional groups because we can't represent @@ -2532,10 +2940,32 @@ class Function: docstring_only: bool = False def __post_init__(self) -> None: - self.parent: Class | Module = self.cls or self.module + self.parent = self.cls or self.module self.self_converter: self_converter | None = None self.__render_parameters__: list[Parameter] | None = None + @functools.cached_property + def displayname(self) -> str: + """Pretty-printable name.""" + if self.kind.new_or_init: + assert isinstance(self.cls, Class) + return self.cls.name + else: + return self.name + + @functools.cached_property + def fulldisplayname(self) -> str: + parent: Class | Module | Clinic | None + if self.kind.new_or_init: + parent = getattr(self.cls, "parent", None) + else: + parent = self.parent + name = self.displayname + while isinstance(parent, (Module, Class)): + name = f"{parent.name}.{name}" + parent = parent.parent + return name + @property def render_parameters(self) -> list[Parameter]: if not self.__render_parameters__: @@ -2564,7 +2994,7 @@ def methoddef_flags(self) -> str | None: return '|'.join(flags) def __repr__(self) -> str: - return '' + return f'' def copy(self, **overrides: Any) -> Function: f = dc.replace(self, **overrides) @@ -2575,6 +3005,9 @@ def copy(self, **overrides: Any) -> Function: return f +VersionTuple = tuple[int, int] + + @dc.dataclass(repr=False, slots=True) class Parameter: """ @@ -2589,10 +3022,13 @@ class Parameter: annotation: object = inspect.Parameter.empty docstring: str = '' group: int = 0 + # (`None` signifies that there is no deprecation) + deprecated_positional: VersionTuple | None = None + deprecated_keyword: VersionTuple | None = None right_bracket_count: int = dc.field(init=False, default=0) def __repr__(self) -> str: - return '' + return f'' def is_keyword_only(self) -> bool: return self.kind == inspect.Parameter.KEYWORD_ONLY @@ -2622,29 +3058,26 @@ def copy( def get_displayname(self, i: int) -> str: if i == 0: - return '"argument"' + return 'argument' if not self.is_positional_only(): - return f'"argument {self.name!r}"' + return f'argument {self.name!r}' else: - return f'"argument {i}"' + return f'argument {i}' + def render_docstring(self) -> str: + add, out = text_accumulator() + add(f" {self.name}\n") + for line in self.docstring.split("\n"): + add(f" {line}\n") + return out().rstrip() -@dc.dataclass -class LandMine: - # try to access any - __message__: str - - def __getattribute__(self, name: str): - if name in ('__repr__', '__message__'): - return super().__getattribute__(name) - # raise RuntimeError(repr(name)) - fail("Stepped on a land mine, trying to access attribute " + repr(name) + ":\n" + self.__message__) +CConverterClassT = TypeVar("CConverterClassT", bound=type["CConverter"]) def add_c_converter( - f: type[CConverter], + f: CConverterClassT, name: str | None = None -) -> type[CConverter]: +) -> CConverterClassT: if not name: name = f.__name__ if not name.endswith('_converter'): @@ -2653,7 +3086,7 @@ def add_c_converter( converters[name] = f return f -def add_default_legacy_c_converter(cls): +def add_default_legacy_c_converter(cls: CConverterClassT) -> CConverterClassT: # automatically add converter for default format unit # (but without stomping on the existing one if it's already # set, in case you subclass) @@ -2664,25 +3097,31 @@ def add_default_legacy_c_converter(cls): def add_legacy_c_converter( format_unit: str, - **kwargs -) -> Callable[[ConverterType], ConverterType]: + **kwargs: Any +) -> Callable[[CConverterClassT], CConverterClassT]: """ Adds a legacy converter. """ - def closure(f): + def closure(f: CConverterClassT) -> CConverterClassT: + added_f: Callable[..., CConverter] if not kwargs: added_f = f else: - added_f = functools.partial(f, **kwargs) + # mypy's special-casing for functools.partial + # can't quite grapple with this code here + added_f = functools.partial(f, **kwargs) # type: ignore[arg-type] if format_unit: legacy_converters[format_unit] = added_f return f return closure class CConverterAutoRegister(type): - def __init__(cls, name, bases, classdict): - add_c_converter(cls) - add_default_legacy_c_converter(cls) + def __init__( + cls, name: str, bases: tuple[type, ...], classdict: dict[str, Any] + ) -> None: + converter_cls = cast(type["CConverter"], cls) + add_c_converter(converter_cls) + add_default_legacy_c_converter(converter_cls) class CConverter(metaclass=CConverterAutoRegister): """ @@ -2692,10 +3131,10 @@ class CConverter(metaclass=CConverterAutoRegister): """ # The C name to use for this variable. - name: str | None = None + name: str # The Python name to use for this variable. - py_name: str | None = None + py_name: str # The C type to use for this variable. # 'type' should be a Python string specifying the type, e.g. "int". @@ -2770,7 +3209,7 @@ class CConverter(metaclass=CConverterAutoRegister): # Only used by the 'O!' format unit (and the "object" converter). subclass_of: str | None = None - # Do we want an adjacent '_length' variable for this variable? + # See also the 'length_name' property. # Only used by format units ending with '#'. length = False @@ -2785,7 +3224,10 @@ class CConverter(metaclass=CConverterAutoRegister): # This lets the self_converter overrule the user-settable # name, *just* for the text signature. # Only set by self_converter. - signature_name = None + signature_name: str | None = None + + include: Include | None = None + broken_limited_capi: bool = False # keep in sync with self_converter.__init__! def __init__(self, @@ -2799,8 +3241,8 @@ def __init__(self, py_default: str | None = None, annotation: str | Literal[Sentinels.unspecified] = unspecified, unused: bool = False, - **kwargs - ): + **kwargs: Any + ) -> None: self.name = ensure_legal_c_identifier(name) self.py_name = py_name self.unused = unused @@ -2815,8 +3257,9 @@ def __init__(self, else: names = [cls.__name__ for cls in self.default_type] types_str = ', '.join(names) - fail("{}: default value {!r} for field {} is not of type {}".format( - self.__class__.__name__, default, name, types_str)) + cls_name = self.__class__.__name__ + fail(f"{cls_name}: default value {default!r} for field " + f"{name!r} is not of type {types_str!r}") self.default = default if c_default: @@ -2827,17 +3270,32 @@ def __init__(self, if annotation is not unspecified: fail("The 'annotation' parameter is not currently permitted.") - # this is deliberate, to prevent you from caching information - # about the function in the init. - # (that breaks if we get cloned.) - # so after this change we will noisily fail. - self.function: Function | LandMine = LandMine( - "Don't access members of self.function inside converter_init!" - ) + # Make sure not to set self.function until after converter_init() has been called. + # This prevents you from caching information + # about the function in converter_init(). + # (That breaks if we get cloned.) self.converter_init(**kwargs) self.function = function - def converter_init(self): + # Add a custom __getattr__ method to improve the error message + # if somebody tries to access self.function in converter_init(). + # + # mypy will assume arbitrary access is okay for a class with a __getattr__ method, + # and that's not what we want, + # so put it inside an `if not TYPE_CHECKING` block + if not TYPE_CHECKING: + def __getattr__(self, attr): + if attr == "function": + fail( + f"{self.__class__.__name__!r} object has no attribute 'function'.\n" + f"Note: accessing self.function inside converter_init is disallowed!" + ) + return super().__getattr__(attr) + # this branch is just here for coverage reporting + else: # pragma: no cover + pass + + def converter_init(self) -> None: pass def is_optional(self) -> bool: @@ -2851,14 +3309,18 @@ def _render_self(self, parameter: Parameter, data: CRenderData) -> None: s = ("&" if self.impl_by_reference else "") + name data.impl_arguments.append(s) if self.length: - data.impl_arguments.append(self.length_name()) + data.impl_arguments.append(self.length_name) # impl_parameters data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference)) if self.length: - data.impl_parameters.append("Py_ssize_t " + self.length_name()) + data.impl_parameters.append(f"Py_ssize_t {self.length_name}") - def _render_non_self(self, parameter, data): + def _render_non_self( + self, + parameter: Parameter, + data: CRenderData + ) -> None: self.parameter = parameter name = self.name @@ -2911,42 +3373,48 @@ def render(self, parameter: Parameter, data: CRenderData) -> None: self._render_self(parameter, data) self._render_non_self(parameter, data) - def length_name(self): + @functools.cached_property + def length_name(self) -> str: """Computes the name of the associated "length" variable.""" - if not self.length: - return None + assert self.length is not None return self.parser_name + "_length" # Why is this one broken out separately? # For "positional-only" function parsing, # which generates a bunch of PyArg_ParseTuple calls. - def parse_argument(self, list): + def parse_argument(self, args: list[str]) -> None: assert not (self.converter and self.encoding) if self.format_unit == 'O&': assert self.converter - list.append(self.converter) + args.append(self.converter) if self.encoding: - list.append(c_repr(self.encoding)) + args.append(c_repr(self.encoding)) elif self.subclass_of: - list.append(self.subclass_of) + args.append(self.subclass_of) - s = ("&" if self.parse_by_reference else "") + self.name - list.append(s) + s = ("&" if self.parse_by_reference else "") + self.parser_name + args.append(s) if self.length: - list.append("&" + self.length_name()) + args.append(f"&{self.length_name}") # # All the functions after here are intended as extension points. # - def simple_declaration(self, by_reference=False, *, in_parser=False): + def simple_declaration( + self, + by_reference: bool = False, + *, + in_parser: bool = False + ) -> str: """ Computes the basic declaration of the variable. Used in computing the prototype declaration and the variable declaration. """ + assert isinstance(self.type, str) prototype = [self.type] if by_reference or not self.type.endswith('*'): prototype.append(" ") @@ -2961,7 +3429,7 @@ def simple_declaration(self, by_reference=False, *, in_parser=False): prototype.append(name) return "".join(prototype) - def declaration(self, *, in_parser=False) -> str: + def declaration(self, *, in_parser: bool = False) -> str: """ The C statement to declare this variable. """ @@ -2974,9 +3442,8 @@ def declaration(self, *, in_parser=False) -> str: declaration.append(default) declaration.append(";") if self.length: - declaration.append('\nPy_ssize_t ') - declaration.append(self.length_name()) - declaration.append(';') + declaration.append('\n') + declaration.append(f"Py_ssize_t {self.length_name};") return "".join(declaration) def initialize(self) -> str: @@ -3011,7 +3478,7 @@ def cleanup(self) -> str: """ return "" - def pre_render(self): + def pre_render(self) -> None: """ A second initialization function, like converter_init, called just before rendering. @@ -3019,53 +3486,96 @@ def pre_render(self): """ pass - def parse_arg(self, argname: str, displayname: str): + def bad_argument(self, displayname: str, expected: str, *, limited_capi: bool, expected_literal: bool = True) -> str: + assert '"' not in expected + if limited_capi: + if expected_literal: + return (f'PyErr_Format(PyExc_TypeError, ' + f'"{{{{name}}}}() {displayname} must be {expected}, not %.50s", ' + f'{{argname}} == Py_None ? "None" : Py_TYPE({{argname}})->tp_name);') + else: + return (f'PyErr_Format(PyExc_TypeError, ' + f'"{{{{name}}}}() {displayname} must be %.50s, not %.50s", ' + f'"{expected}", ' + f'{{argname}} == Py_None ? "None" : Py_TYPE({{argname}})->tp_name);') + else: + if expected_literal: + expected = f'"{expected}"' + return f'_PyArg_BadArgument("{{{{name}}}}", "{displayname}", {expected}, {{argname}});' + + def format_code(self, fmt: str, *, + argname: str, + bad_argument: str | None = None, + bad_argument2: str | None = None, + **kwargs: Any) -> str: + if '{bad_argument}' in fmt: + if not bad_argument: + raise TypeError("required 'bad_argument' argument") + fmt = fmt.replace('{bad_argument}', bad_argument) + if '{bad_argument2}' in fmt: + if not bad_argument2: + raise TypeError("required 'bad_argument2' argument") + fmt = fmt.replace('{bad_argument2}', bad_argument2) + return fmt.format(argname=argname, paramname=self.parser_name, **kwargs) + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'O&': - return """ + return self.format_code(""" if (!{converter}({argname}, &{paramname})) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name, - converter=self.converter) + """, + argname=argname, + converter=self.converter) if self.format_unit == 'O!': cast = '(%s)' % self.type if self.type != 'PyObject *' else '' if self.subclass_of in type_checks: typecheck, typename = type_checks[self.subclass_of] - return """ + return self.format_code(""" if (!{typecheck}({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "{typename}", {argname}); + {bad_argument} goto exit; }}}} {paramname} = {cast}{argname}; - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname, typecheck=typecheck, - typename=typename, cast=cast) - return """ + """, + argname=argname, + bad_argument=self.bad_argument(displayname, typename, limited_capi=limited_capi), + typecheck=typecheck, typename=typename, cast=cast) + return self.format_code(""" if (!PyObject_TypeCheck({argname}, {subclass_of})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, ({subclass_of})->tp_name, {argname}); + {bad_argument} goto exit; }}}} {paramname} = {cast}{argname}; - """.format(argname=argname, paramname=self.parser_name, - subclass_of=self.subclass_of, cast=cast, - displayname=displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, '({subclass_of})->tp_name', + expected_literal=False, limited_capi=limited_capi), + subclass_of=self.subclass_of, cast=cast) if self.format_unit == 'O': cast = '(%s)' % self.type if self.type != 'PyObject *' else '' - return """ + return self.format_code(""" {paramname} = {cast}{argname}; - """.format(argname=argname, paramname=self.parser_name, cast=cast) + """, + argname=argname, cast=cast) return None def set_template_dict(self, template_dict: TemplateDict) -> None: pass @property - def parser_name(self): + def parser_name(self) -> str: if self.name in CLINIC_PREFIXED_ARGS: # bpo-39741 return CLINIC_PREFIX + self.name else: return self.name + def add_include(self, name: str, reason: str, + *, condition: str | None = None) -> None: + if self.include is not None: + raise ValueError("a converter only supports a single include") + self.include = Include(name, reason, condition) + type_checks = { '&PyLong_Type': ('PyLong_Check', 'int'), '&PyTuple_Type': ('PyTuple_Check', 'tuple'), @@ -3117,27 +3627,29 @@ def converter_init(self, *, accept: TypeSet = {object}) -> None: if accept == {int}: self.format_unit = 'i' elif accept != {object}: - fail("bool_converter: illegal 'accept' argument " + repr(accept)) + fail(f"bool_converter: illegal 'accept' argument {accept!r}") if self.default is not unspecified: self.default = bool(self.default) self.c_default = str(int(self.default)) - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'i': - return """ - {paramname} = _PyLong_AsInt({argname}); + return self.format_code(""" + {paramname} = PyLong_AsInt({argname}); if ({paramname} == -1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) elif self.format_unit == 'p': - return """ + return self.format_code(""" {paramname} = PyObject_IsTrue({argname}); if ({paramname} < 0) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class defining_class_converter(CConverter): """ @@ -3148,13 +3660,13 @@ class defining_class_converter(CConverter): format_unit = '' show_in_signature = False - def converter_init(self, *, type=None) -> None: + def converter_init(self, *, type: str | None = None) -> None: self.specified_type = type - def render(self, parameter, data) -> None: + def render(self, parameter: Parameter, data: CRenderData) -> None: self._render_self(parameter, data) - def set_template_dict(self, template_dict): + def set_template_dict(self, template_dict: TemplateDict) -> None: template_dict['defining_class_name'] = self.name @@ -3167,15 +3679,15 @@ class char_converter(CConverter): def converter_init(self) -> None: if isinstance(self.default, self.default_type): if len(self.default) != 1: - fail("char_converter: illegal default value " + repr(self.default)) + fail(f"char_converter: illegal default value {self.default!r}") self.c_default = repr(bytes(self.default))[1:] if self.c_default == '"\'"': self.c_default = r"'\''" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'c': - return """ + return self.format_code(""" if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{ {paramname} = PyBytes_AS_STRING({argname})[0]; }}}} @@ -3183,12 +3695,14 @@ def parse_arg(self, argname: str, displayname: str) -> str: {paramname} = PyByteArray_AS_STRING({argname})[0]; }}}} else {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "a byte string of length 1", {argname}); + {bad_argument} goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'a byte string of length 1', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) @add_legacy_c_converter('B', bitwise=True) @@ -3202,9 +3716,9 @@ def converter_init(self, *, bitwise: bool = False) -> None: if bitwise: self.format_unit = 'B' - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'b': - return """ + return self.format_code(""" {{{{ long ival = PyLong_AsLong({argname}); if (ival == -1 && PyErr_Occurred()) {{{{ @@ -3224,9 +3738,10 @@ def parse_arg(self, argname: str, displayname: str) -> str: {paramname} = (unsigned char) ival; }}}} }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) elif self.format_unit == 'B': - return """ + return self.format_code(""" {{{{ unsigned long ival = PyLong_AsUnsignedLongMask({argname}); if (ival == (unsigned long)-1 && PyErr_Occurred()) {{{{ @@ -3236,8 +3751,9 @@ def parse_arg(self, argname: str, displayname: str) -> str: {paramname} = (unsigned char) ival; }}}} }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class byte_converter(unsigned_char_converter): pass @@ -3247,9 +3763,9 @@ class short_converter(CConverter): format_unit = 'h' c_ignored_default = "0" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'h': - return """ + return self.format_code(""" {{{{ long ival = PyLong_AsLong({argname}); if (ival == -1 && PyErr_Occurred()) {{{{ @@ -3269,8 +3785,9 @@ def parse_arg(self, argname: str, displayname: str) -> str: {paramname} = (short) ival; }}}} }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class unsigned_short_converter(CConverter): type = 'unsigned short' @@ -3282,16 +3799,36 @@ def converter_init(self, *, bitwise: bool = False) -> None: self.format_unit = 'H' else: self.converter = '_PyLong_UnsignedShort_Converter' + self.add_include('pycore_long.h', + '_PyLong_UnsignedShort_Converter()') - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'H': - return """ + return self.format_code(""" {paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname}); if ({paramname} == (unsigned short)-1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {{{{ + unsigned long uval = PyLong_AsUnsignedLong({argname}); + if (uval == (unsigned long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + if (uval > USHRT_MAX) {{{{ + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned short"); + goto exit; + }}}} + {paramname} = (unsigned short) uval; + }}}} + """, + argname=argname) @add_legacy_c_converter('C', accept={str}) class int_converter(CConverter): @@ -3300,36 +3837,41 @@ class int_converter(CConverter): format_unit = 'i' c_ignored_default = "0" - def converter_init(self, *, accept: TypeSet = {int}, type=None) -> None: + def converter_init( + self, *, accept: TypeSet = {int}, type: str | None = None + ) -> None: if accept == {str}: self.format_unit = 'C' elif accept != {int}: - fail("int_converter: illegal 'accept' argument " + repr(accept)) + fail(f"int_converter: illegal 'accept' argument {accept!r}") if type is not None: self.type = type - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'i': - return """ - {paramname} = _PyLong_AsInt({argname}); + return self.format_code(""" + {paramname} = PyLong_AsInt({argname}); if ({paramname} == -1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) + """, + argname=argname) elif self.format_unit == 'C': - return """ + return self.format_code(""" if (!PyUnicode_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname}); + {bad_argument} goto exit; }}}} if (PyUnicode_GET_LENGTH({argname}) != 1) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname}); + {bad_argument} goto exit; }}}} {paramname} = PyUnicode_READ_CHAR({argname}, 0); - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'a unicode character', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class unsigned_int_converter(CConverter): type = 'unsigned int' @@ -3341,16 +3883,36 @@ def converter_init(self, *, bitwise: bool = False) -> None: self.format_unit = 'I' else: self.converter = '_PyLong_UnsignedInt_Converter' + self.add_include('pycore_long.h', + '_PyLong_UnsignedInt_Converter()') - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'I': - return """ + return self.format_code(""" {paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname}); if ({paramname} == (unsigned int)-1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {{{{ + unsigned long uval = PyLong_AsUnsignedLong({argname}); + if (uval == (unsigned long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + if (uval > UINT_MAX) {{{{ + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned int"); + goto exit; + }}}} + {paramname} = (unsigned int) uval; + }}}} + """, + argname=argname) class long_converter(CConverter): type = 'long' @@ -3358,15 +3920,16 @@ class long_converter(CConverter): format_unit = 'l' c_ignored_default = "0" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'l': - return """ + return self.format_code(""" {paramname} = PyLong_AsLong({argname}); if ({paramname} == -1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class unsigned_long_converter(CConverter): type = 'unsigned long' @@ -3378,18 +3941,31 @@ def converter_init(self, *, bitwise: bool = False) -> None: self.format_unit = 'k' else: self.converter = '_PyLong_UnsignedLong_Converter' + self.add_include('pycore_long.h', + '_PyLong_UnsignedLong_Converter()') - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'k': - return """ + return self.format_code(""" if (!PyLong_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname}); + {bad_argument} goto exit; }}}} {paramname} = PyLong_AsUnsignedLongMask({argname}); - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi), + ) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {paramname} = PyLong_AsUnsignedLong({argname}); + if ({paramname} == (unsigned long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) class long_long_converter(CConverter): type = 'long long' @@ -3397,15 +3973,16 @@ class long_long_converter(CConverter): format_unit = 'L' c_ignored_default = "0" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'L': - return """ + return self.format_code(""" {paramname} = PyLong_AsLongLong({argname}); if ({paramname} == -1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class unsigned_long_long_converter(CConverter): type = 'unsigned long long' @@ -3417,18 +3994,31 @@ def converter_init(self, *, bitwise: bool = False) -> None: self.format_unit = 'K' else: self.converter = '_PyLong_UnsignedLongLong_Converter' + self.add_include('pycore_long.h', + '_PyLong_UnsignedLongLong_Converter()') - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'K': - return """ + return self.format_code(""" if (!PyLong_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname}); + {bad_argument} goto exit; }}}} {paramname} = PyLong_AsUnsignedLongLongMask({argname}); - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi), + ) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {paramname} = PyLong_AsUnsignedLongLong({argname}); + if ({paramname} == (unsigned long long)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) class Py_ssize_t_converter(CConverter): type = 'Py_ssize_t' @@ -3438,17 +4028,24 @@ def converter_init(self, *, accept: TypeSet = {int}) -> None: if accept == {int}: self.format_unit = 'n' self.default_type = int + self.add_include('pycore_abstract.h', '_PyNumber_Index()') elif accept == {int, NoneType}: self.converter = '_Py_convert_optional_to_ssize_t' + self.add_include('pycore_abstract.h', + '_Py_convert_optional_to_ssize_t()') else: - fail("Py_ssize_t_converter: illegal 'accept' argument " + repr(accept)) + fail(f"Py_ssize_t_converter: illegal 'accept' argument {accept!r}") - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'n': - return """ + if limited_capi: + PyNumber_Index = 'PyNumber_Index' + else: + PyNumber_Index = '_PyNumber_Index' + return self.format_code(""" {{{{ Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index({argname}); + PyObject *iobj = {PyNumber_Index}({argname}); if (iobj != NULL) {{{{ ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); @@ -3458,8 +4055,28 @@ def parse_arg(self, argname: str, displayname: str) -> str: }}}} {paramname} = ival; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname, + PyNumber_Index=PyNumber_Index) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + return self.format_code(""" + if ({argname} != Py_None) {{{{ + if (PyIndex_Check({argname})) {{{{ + {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + }}}} + else {{{{ + {bad_argument} + goto exit; + }}}} + }}}} + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'integer or None', limited_capi=limited_capi), + ) class slice_index_converter(CConverter): @@ -3468,38 +4085,97 @@ class slice_index_converter(CConverter): def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None: if accept == {int}: self.converter = '_PyEval_SliceIndexNotNone' + self.nullable = False elif accept == {int, NoneType}: self.converter = '_PyEval_SliceIndex' + self.nullable = True else: - fail("slice_index_converter: illegal 'accept' argument " + repr(accept)) + fail(f"slice_index_converter: illegal 'accept' argument {accept!r}") + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + if self.nullable: + return self.format_code(""" + if (!Py_IsNone({argname})) {{{{ + if (PyIndex_Check({argname})) {{{{ + {paramname} = PyNumber_AsSsize_t({argname}, NULL); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + return 0; + }}}} + }}}} + else {{{{ + PyErr_SetString(PyExc_TypeError, + "slice indices must be integers or " + "None or have an __index__ method"); + goto exit; + }}}} + }}}} + """, + argname=argname) + else: + return self.format_code(""" + if (PyIndex_Check({argname})) {{{{ + {paramname} = PyNumber_AsSsize_t({argname}, NULL); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + }}}} + else {{{{ + PyErr_SetString(PyExc_TypeError, + "slice indices must be integers or " + "have an __index__ method"); + goto exit; + }}}} + """, + argname=argname) class size_t_converter(CConverter): type = 'size_t' converter = '_PyLong_Size_t_Converter' c_ignored_default = "0" - def parse_arg(self, argname: str, displayname: str) -> str: + def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None: + self.add_include('pycore_long.h', + '_PyLong_Size_t_Converter()') + + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'n': - return """ + return self.format_code(""" {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); if ({paramname} == -1 && PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + if not limited_capi: + return super().parse_arg(argname, displayname, limited_capi=limited_capi) + # NOTE: Raises OverflowError for negative integer. + return self.format_code(""" + {paramname} = PyLong_AsSize_t({argname}); + if ({paramname} == (size_t)-1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, + argname=argname) class fildes_converter(CConverter): type = 'int' converter = '_PyLong_FileDescriptor_Converter' - def _parse_arg(self, argname: str, displayname: str) -> str: - return """ + def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None: + self.add_include('pycore_fileutils.h', + '_PyLong_FileDescriptor_Converter()') + + def _parse_arg(self, argname: str, displayname: str) -> str | None: + return self.format_code(""" {paramname} = PyObject_AsFileDescriptor({argname}); if ({paramname} == -1) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.name) + """, + argname=argname) class float_converter(CConverter): @@ -3508,9 +4184,9 @@ class float_converter(CConverter): format_unit = 'f' c_ignored_default = "0.0" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'f': - return """ + return self.format_code(""" if (PyFloat_CheckExact({argname})) {{{{ {paramname} = (float) (PyFloat_AS_DOUBLE({argname})); }}}} @@ -3521,8 +4197,9 @@ def parse_arg(self, argname: str, displayname: str) -> str: goto exit; }}}} }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class double_converter(CConverter): type = 'double' @@ -3530,9 +4207,9 @@ class double_converter(CConverter): format_unit = 'd' c_ignored_default = "0.0" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'd': - return """ + return self.format_code(""" if (PyFloat_CheckExact({argname})) {{{{ {paramname} = PyFloat_AS_DOUBLE({argname}); }}}} @@ -3543,8 +4220,9 @@ def parse_arg(self, argname: str, displayname: str) -> str: goto exit; }}}} }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class Py_complex_converter(CConverter): @@ -3553,15 +4231,16 @@ class Py_complex_converter(CConverter): format_unit = 'D' c_ignored_default = "{0.0, 0.0}" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'D': - return """ + return self.format_code(""" {paramname} = PyComplex_AsCComplex({argname}); if (PyErr_Occurred()) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name) - return super().parse_arg(argname, displayname) + """, + argname=argname) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class object_converter(CConverter): @@ -3570,9 +4249,9 @@ class object_converter(CConverter): def converter_init( self, *, - converter=None, - type=None, - subclass_of=None + converter: str | None = None, + type: str | None = None, + subclass_of: str | None = None ) -> None: if converter: if subclass_of: @@ -3599,10 +4278,14 @@ class buffer: pass class rwbuffer: pass class robuffer: pass -def str_converter_key(types, encoding, zeroes): +StrConverterKeyType = tuple[frozenset[type], bool, bool] + +def str_converter_key( + types: TypeSet, encoding: bool | str | None, zeroes: bool +) -> StrConverterKeyType: return (frozenset(types), bool(encoding), bool(zeroes)) -str_converter_argument_map: dict[str, str] = {} +str_converter_argument_map: dict[StrConverterKeyType, str] = {} class str_converter(CConverter): type = 'const char *' @@ -3635,52 +4318,58 @@ def converter_init( if NoneType in accept and self.c_default == "Py_None": self.c_default = "NULL" - def post_parsing(self): + def post_parsing(self) -> str: if self.encoding: name = self.name return f"PyMem_FREE({name});\n" + else: + return "" - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 's': - return """ + return self.format_code(""" if (!PyUnicode_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname}); + {bad_argument} goto exit; }}}} - Py_ssize_t {paramname}_length; - {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{paramname}_length); + Py_ssize_t {length_name}; + {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{length_name}); if ({paramname} == NULL) {{{{ goto exit; }}}} - if (strlen({paramname}) != (size_t){paramname}_length) {{{{ + if (strlen({paramname}) != (size_t){length_name}) {{{{ PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), + length_name=self.length_name) if self.format_unit == 'z': - return """ + return self.format_code(""" if ({argname} == Py_None) {{{{ {paramname} = NULL; }}}} else if (PyUnicode_Check({argname})) {{{{ - Py_ssize_t {paramname}_length; - {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{paramname}_length); + Py_ssize_t {length_name}; + {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{length_name}); if ({paramname} == NULL) {{{{ goto exit; }}}} - if (strlen({paramname}) != (size_t){paramname}_length) {{{{ + if (strlen({paramname}) != (size_t){length_name}) {{{{ PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; }}}} }}}} else {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "str or None", {argname}); + {bad_argument} goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str or None', limited_capi=limited_capi), + length_name=self.length_name) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) # # This is the fourth or fifth rewrite of registering all the @@ -3742,51 +4431,57 @@ class PyBytesObject_converter(CConverter): format_unit = 'S' # accept = {bytes} - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'S': - return """ + return self.format_code(""" if (!PyBytes_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "bytes", {argname}); + {bad_argument} goto exit; }}}} {paramname} = ({type}){argname}; - """.format(argname=argname, paramname=self.parser_name, - type=self.type, displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'bytes', limited_capi=limited_capi), + type=self.type) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class PyByteArrayObject_converter(CConverter): type = 'PyByteArrayObject *' format_unit = 'Y' # accept = {bytearray} - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'Y': - return """ + return self.format_code(""" if (!PyByteArray_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "bytearray", {argname}); + {bad_argument} goto exit; }}}} {paramname} = ({type}){argname}; - """.format(argname=argname, paramname=self.parser_name, - type=self.type, displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'bytearray', limited_capi=limited_capi), + type=self.type) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) class unicode_converter(CConverter): type = 'PyObject *' default_type = (str, Null, NoneType) format_unit = 'U' - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'U': - return """ + return self.format_code(""" if (!PyUnicode_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname}); + {bad_argument} goto exit; }}}} {paramname} = {argname}; - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) @add_legacy_c_converter('u') @add_legacy_c_converter('u#', zeroes=True) @@ -3813,30 +4508,33 @@ def converter_init( elif accept == {str, NoneType}: self.converter = '_PyUnicode_WideCharString_Opt_Converter' else: - fail("Py_UNICODE_converter: illegal 'accept' argument " + repr(accept)) + fail(f"Py_UNICODE_converter: illegal 'accept' argument {accept!r}") self.c_default = "NULL" - def cleanup(self): - if not self.length: - return """\ -PyMem_Free((void *){name}); -""".format(name=self.name) + def cleanup(self) -> str: + if self.length: + return "" + else: + return f"""PyMem_Free((void *){self.parser_name});\n""" - def parse_arg(self, argname: str, argnum: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if not self.length: if self.accept == {str}: - return """ + return self.format_code(""" if (!PyUnicode_Check({argname})) {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "str", {argname}); + {bad_argument} goto exit; }}}} {paramname} = PyUnicode_AsWideCharString({argname}, NULL); if ({paramname} == NULL) {{{{ goto exit; }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str', limited_capi=limited_capi), + ) elif self.accept == {str, NoneType}: - return """ + return self.format_code(""" if ({argname} == Py_None) {{{{ {paramname} = NULL; }}}} @@ -3847,11 +4545,14 @@ def parse_arg(self, argname: str, argnum: str) -> str: }}}} }}}} else {{{{ - _PyArg_BadArgument("{{name}}", {argnum}, "str or None", {argname}); + {bad_argument} goto exit; }}}} - """.format(argname=argname, paramname=self.name, argnum=argnum) - return super().parse_arg(argname, argnum) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'str or None', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) @add_legacy_c_converter('s*', accept={str, buffer}) @add_legacy_c_converter('z*', accept={str, buffer, NoneType}) @@ -3881,24 +4582,26 @@ def converter_init(self, *, accept: TypeSet = {buffer}) -> None: self.format_unit = format_unit - def cleanup(self): + def cleanup(self) -> str: name = self.name return "".join(["if (", name, ".obj) {\n PyBuffer_Release(&", name, ");\n}\n"]) - def parse_arg(self, argname: str, displayname: str) -> str: + def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: if self.format_unit == 'y*': - return """ + return self.format_code(""" if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ goto exit; }}}} if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname}); + {bad_argument} goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), + ) elif self.format_unit == 's*': - return """ + return self.format_code(""" if (PyUnicode_Check({argname})) {{{{ Py_ssize_t len; const char *ptr = PyUnicode_AsUTF8AndSize({argname}, &len); @@ -3912,26 +4615,30 @@ def parse_arg(self, argname: str, displayname: str) -> str: goto exit; }}}} if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname}); + {bad_argument} goto exit; }}}} }}}} - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), + ) elif self.format_unit == 'w*': - return """ + return self.format_code(""" if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_WRITABLE) < 0) {{{{ - PyErr_Clear(); - _PyArg_BadArgument("{{name}}", {displayname}, "read-write bytes-like object", {argname}); + {bad_argument} goto exit; }}}} if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname}); + {bad_argument2} goto exit; }}}} - """.format(argname=argname, paramname=self.parser_name, - displayname=displayname) - return super().parse_arg(argname, displayname) + """, + argname=argname, + bad_argument=self.bad_argument(displayname, 'read-write bytes-like object', limited_capi=limited_capi), + bad_argument2=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), + ) + return super().parse_arg(argname, displayname, limited_capi=limited_capi) def correct_name_for_self( @@ -3945,7 +4652,7 @@ def correct_name_for_self( return "void *", "null" if f.kind in (CLASS_METHOD, METHOD_NEW): return "PyTypeObject *", "type" - raise RuntimeError("Unhandled type of function f: " + repr(f.kind)) + raise AssertionError(f"Unhandled type of function f: {f.kind!r}") def required_type_for_self_for_parser( f: Function @@ -3961,13 +4668,13 @@ class self_converter(CConverter): A special-case converter: this is the default converter used for "self". """ - type = None + type: str | None = None format_unit = '' - def converter_init(self, *, type=None) -> None: + def converter_init(self, *, type: str | None = None) -> None: self.specified_type = type - def pre_render(self): + def pre_render(self) -> None: f = self.function default_type, default_name = correct_name_for_self(f) self.signature_name = default_name @@ -4017,10 +4724,11 @@ def pre_render(self): # in the impl call. @property - def parser_type(self): + def parser_type(self) -> str: + assert self.type is not None return required_type_for_self_for_parser(self.function) or self.type - def render(self, parameter, data): + def render(self, parameter: Parameter, data: CRenderData) -> None: """ parameter is a clinic.Parameter instance. data is a CRenderData instance. @@ -4036,9 +4744,10 @@ def render(self, parameter, data): # because we render parameters in order, and self is always first. assert len(data.impl_arguments) == 1 assert data.impl_arguments[0] == self.name + assert self.type is not None data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0] - def set_template_dict(self, template_dict): + def set_template_dict(self, template_dict: TemplateDict) -> None: template_dict['self_name'] = self.name template_dict['self_type'] = self.parser_type kind = self.function.kind @@ -4057,7 +4766,7 @@ def set_template_dict(self, template_dict): line = f'{type_check} &&\n ' template_dict['self_type_check'] = line - type_object = self.function.cls.type_object + type_object = cls.type_object type_ptr = f'PyTypeObject *base_tp = {type_object};' template_dict['base_type_ptr'] = type_ptr @@ -4100,7 +4809,7 @@ def __init__( self, *, py_default: str | None = None, - **kwargs + **kwargs: Any ) -> None: self.py_default = py_default try: @@ -4248,10 +4957,11 @@ def eval_ast_expr( globals: dict[str, Any], *, filename: str = '-' -) -> FunctionType: +) -> Any: """ - Takes an ast.Expr node. Compiles and evaluates it. - Returns the result of the expression. + Takes an ast.Expr node. Compiles it into a function object, + then calls the function object with 0 arguments. + Returns the result of that function call. globals represents the globals dict the expression should see. (There's no equivalent for "locals" here.) @@ -4267,15 +4977,15 @@ def eval_ast_expr( class IndentStack: - def __init__(self): - self.indents = [] - self.margin = None + def __init__(self) -> None: + self.indents: list[int] = [] + self.margin: str | None = None - def _ensure(self): + def _ensure(self) -> None: if not self.indents: fail('IndentStack expected indents, but none are defined.') - def measure(self, line): + def measure(self, line: str) -> int: """ Returns the length of the line's margin. """ @@ -4289,7 +4999,7 @@ def measure(self, line): return self.indents[-1] return len(line) - len(stripped) - def infer(self, line): + def infer(self, line: str) -> int: """ Infer what is now the current margin based on this line. Returns: @@ -4322,31 +5032,25 @@ def infer(self, line): return outdent_count @property - def depth(self): + def depth(self) -> int: """ Returns how many margins are currently defined. """ return len(self.indents) - def indent(self, line): - """ - Indents a line by the currently defined margin. - """ - return self.margin + line - - def dedent(self, line): + def dedent(self, line: str) -> str: """ Dedents a line by the currently defined margin. - (The inverse of 'indent'.) """ + assert self.margin is not None, "Cannot call .dedent() before calling .infer()" margin = self.margin indent = self.indents[-1] if not line.startswith(margin): - fail('Cannot dedent, line does not start with the previous margin:') + fail('Cannot dedent; line does not start with the previous margin.') return line[indent:] -StateKeeper = Callable[[str | None], None] +StateKeeper = Callable[[str], None] ConverterArgs = dict[str, Any] class ParamState(enum.IntEnum): @@ -4380,19 +5084,26 @@ class ParamState(enum.IntEnum): RIGHT_SQUARE_AFTER = 6 +class FunctionNames(NamedTuple): + full_name: str + c_basename: str + + class DSLParser: function: Function | None state: StateKeeper keyword_only: bool positional_only: bool + deprecated_positional: VersionTuple | None + deprecated_keyword: VersionTuple | None group: int - parameter_state: int - seen_positional_with_default: bool + parameter_state: ParamState indent: IndentStack kind: FunctionKind coexist: bool parameter_continuation: str preserve_output: bool + from_version_re = re.compile(r'([*/]) +\[from +(.+)\]') def __init__(self, clinic: Clinic) -> None: self.clinic = clinic @@ -4416,19 +5127,23 @@ def reset(self) -> None: self.state = self.state_dsl_start self.keyword_only = False self.positional_only = False + self.deprecated_positional = None + self.deprecated_keyword = None self.group = 0 self.parameter_state: ParamState = ParamState.START - self.seen_positional_with_default = False self.indent = IndentStack() self.kind = CALLABLE self.coexist = False + self.forced_text_signature: str | None = None self.parameter_continuation = '' self.preserve_output = False def directive_version(self, required: str) -> None: global version if version_comparitor(version, required) < 0: - fail("Insufficient Clinic version!\n Version: " + version + "\n Required: " + required) + fail("Insufficient Clinic version!\n" + f" Version: {version}\n" + f" Required: {required}") def directive_module(self, name: str) -> None: fields = name.split('.')[:-1] @@ -4436,8 +5151,8 @@ def directive_module(self, name: str) -> None: if cls: fail("Can't nest a module inside a class!") - if name in module.classes: - fail("Already defined module " + repr(name) + "!") + if name in module.modules: + fail(f"Already defined module {name!r}!") m = Module(name, module) module.modules[name] = m @@ -4455,7 +5170,7 @@ def directive_class( parent = cls or module if name in parent.classes: - fail("Already defined class " + repr(name) + "!") + fail(f"Already defined class {name!r}!") c = Class(name, module, cls, typedef, type_object) parent.classes[name] = c @@ -4463,7 +5178,7 @@ def directive_class( def directive_set(self, name: str, value: str) -> None: if name not in ("line_prefix", "line_suffix"): - fail("unknown variable", repr(name)) + fail(f"unknown variable {name!r}") value = value.format_map({ 'block comment start': '/*', @@ -4476,15 +5191,15 @@ def directive_destination( self, name: str, command: str, - *args + *args: str ) -> None: - if command == 'new': - self.clinic.add_destination(name, *args) - return - - if command == 'clear': - self.clinic.get_destination(name).clear() - fail("unknown destination command", repr(command)) + match command: + case "new": + self.clinic.add_destination(name, *args) + case "clear": + self.clinic.get_destination(name).clear() + case _: + fail(f"unknown destination command {command!r}") def directive_output( @@ -4497,7 +5212,7 @@ def directive_output( if command_or_name == "preset": preset = self.clinic.presets.get(destination) if not preset: - fail("Unknown preset " + repr(destination) + "!") + fail(f"Unknown preset {destination!r}!") fd.update(preset) return @@ -4526,7 +5241,11 @@ def directive_output( return if command_or_name not in fd: - fail("Invalid command / destination name " + repr(command_or_name) + ", must be one of:\n preset push pop print everything " + " ".join(fd)) + allowed = ["preset", "push", "pop", "print", "everything"] + allowed.extend(fd) + fail(f"Invalid command or destination name {command_or_name!r}. " + "Must be one of:\n -", + "\n - ".join([repr(word) for word in allowed])) fd[command_or_name] = d def directive_dump(self, name: str) -> None: @@ -4538,7 +5257,7 @@ def directive_printout(self, *args: str) -> None: def directive_preserve(self) -> None: if self.preserve_output: - fail("Can't have preserve twice in one block!") + fail("Can't have 'preserve' twice in one block!") self.preserve_output = True def at_classmethod(self) -> None: @@ -4556,6 +5275,11 @@ def at_coexist(self) -> None: fail("Called @coexist twice!") self.coexist = True + def at_text_signature(self, text_signature: str) -> None: + if self.forced_text_signature: + fail("Called @text_signature twice!") + self.forced_text_signature = text_signature + def parse(self, block: Block) -> None: self.reset() self.block = block @@ -4565,51 +5289,51 @@ def parse(self, block: Block) -> None: lines = block.input.split('\n') for line_number, line in enumerate(lines, self.clinic.block_parser.block_start_line_number): if '\t' in line: - fail('Tab characters are illegal in the Clinic DSL.\n\t' + repr(line), line_number=block_start) - self.state(line) - - self.next(self.state_terminal) - self.state(None) + fail(f'Tab characters are illegal in the Clinic DSL: {line!r}', + line_number=block_start) + try: + self.state(line) + except ClinicError as exc: + exc.lineno = line_number + raise - block.output.extend(self.clinic.language.render(clinic, block.signatures)) + self.do_post_block_processing_cleanup(line_number) + block.output.extend(self.clinic.language.render(self.clinic, block.signatures)) if self.preserve_output: if block.output: fail("'preserve' only works for blocks that don't produce any output!") block.output = self.saved_output - @staticmethod - def valid_line(line: str | None) -> TypeGuard[str]: - if line is None: - return False + def in_docstring(self) -> bool: + """Return true if we are processing a docstring.""" + return self.state in { + self.state_parameter_docstring, + self.state_function_docstring, + } + def valid_line(self, line: str) -> bool: # ignore comment-only lines if line.lstrip().startswith('#'): return False # Ignore empty lines too # (but not in docstring sections!) - if not line.strip(): + if not self.in_docstring() and not line.strip(): return False return True - @staticmethod - def calculate_indent(line: str) -> int: - return len(line) - len(line.strip()) - def next( self, state: StateKeeper, line: str | None = None ) -> None: - # real_print(self.state.__name__, "->", state.__name__, ", line=", line) self.state = state if line is not None: self.state(line) - def state_dsl_start(self, line: str | None) -> None: - # self.block = self.ClinicOutputBlock(self) + def state_dsl_start(self, line: str) -> None: if not self.valid_line(line): return @@ -4626,7 +5350,40 @@ def state_dsl_start(self, line: str | None) -> None: self.next(self.state_modulename_name, line) - def state_modulename_name(self, line: str | None) -> None: + @staticmethod + def parse_function_names(line: str) -> FunctionNames: + left, as_, right = line.partition(' as ') + full_name = left.strip() + c_basename = right.strip() + if as_ and not c_basename: + fail("No C basename provided after 'as' keyword") + if not c_basename: + fields = full_name.split(".") + if fields[-1] == '__new__': + fields.pop() + c_basename = "_".join(fields) + if not is_legal_py_identifier(full_name): + fail(f"Illegal function name: {full_name!r}") + if not is_legal_c_identifier(c_basename): + fail(f"Illegal C basename: {c_basename!r}") + return FunctionNames(full_name=full_name, c_basename=c_basename) + + def update_function_kind(self, fullname: str) -> None: + fields = fullname.split('.') + name = fields.pop() + _, cls = self.clinic._module_and_class(fields) + if name in unsupported_special_methods: + fail(f"{name!r} is a special method and cannot be converted to Argument Clinic!") + if name == '__new__': + if (self.kind is not CLASS_METHOD) or (not cls): + fail("'__new__' must be a class method!") + self.kind = METHOD_NEW + elif name == '__init__': + if (self.kind is not CALLABLE) or (not cls): + fail("'__init__' must be a normal method, not a class or static method!") + self.kind = METHOD_INIT + + def state_modulename_name(self, line: str) -> None: # looking for declaration, which establishes the leftmost column # line should be # modulename.fnname [as c_basename] [-> return annotation] @@ -4643,22 +5400,15 @@ def state_modulename_name(self, line: str | None) -> None: # this line is permitted to start with whitespace. # we'll call this number of spaces F (for "function"). - if not self.valid_line(line): - return - + assert self.valid_line(line) self.indent.infer(line) # are we cloning? before, equals, existing = line.rpartition('=') - c_basename: str | None if equals: - full_name, _, c_basename = before.partition(' as ') - full_name = full_name.strip() - c_basename = c_basename.strip() + full_name, c_basename = self.parse_function_names(before) existing = existing.strip() - if (is_legal_py_identifier(full_name) and - (not c_basename or is_legal_c_identifier(c_basename)) and - is_legal_py_identifier(existing)): + if is_legal_py_identifier(existing): # we're cloning! fields = [x.strip() for x in existing.split('.')] function_name = fields.pop() @@ -4668,22 +5418,34 @@ def state_modulename_name(self, line: str | None) -> None: if existing_function.name == function_name: break else: - existing_function = None - if not existing_function: - print("class", cls, "module", module, "existing", existing) - print("cls. functions", cls.functions) - fail("Couldn't find existing function " + repr(existing) + "!") + print(f"{cls=}, {module=}, {existing=}", file=sys.stderr) + print(f"{(cls or module).functions=}", file=sys.stderr) + fail(f"Couldn't find existing function {existing!r}!") fields = [x.strip() for x in full_name.split('.')] function_name = fields.pop() module, cls = self.clinic._module_and_class(fields) - if not (existing_function.kind is self.kind and existing_function.coexist == self.coexist): - fail("'kind' of function and cloned function don't match! (@classmethod/@staticmethod/@coexist)") - function = existing_function.copy( - name=function_name, full_name=full_name, module=module, - cls=cls, c_basename=c_basename, docstring='' - ) + self.update_function_kind(full_name) + overrides: dict[str, Any] = { + "name": function_name, + "full_name": full_name, + "module": module, + "cls": cls, + "c_basename": c_basename, + "docstring": "", + } + if not (existing_function.kind is self.kind and + existing_function.coexist == self.coexist): + # Allow __new__ or __init__ methods. + if existing_function.kind.new_or_init: + overrides["kind"] = self.kind + # Future enhancement: allow custom return converters + overrides["return_converter"] = CReturnConverter() + else: + fail("'kind' of function and cloned function don't match! " + "(@classmethod/@staticmethod/@coexist)") + function = existing_function.copy(**overrides) self.function = function self.block.signatures.append(function) (cls or module).functions.append(function) @@ -4691,61 +5453,39 @@ def state_modulename_name(self, line: str | None) -> None: return line, _, returns = line.partition('->') - - full_name, _, c_basename = line.partition(' as ') - full_name = full_name.strip() - c_basename = c_basename.strip() or None - - if not is_legal_py_identifier(full_name): - fail("Illegal function name:", full_name) - if c_basename and not is_legal_c_identifier(c_basename): - fail("Illegal C basename:", c_basename) + returns = returns.strip() + full_name, c_basename = self.parse_function_names(line) return_converter = None if returns: ast_input = f"def x() -> {returns}: pass" - module = None try: - module = ast.parse(ast_input) + module_node = ast.parse(ast_input) except SyntaxError: - pass - if not module: - fail("Badly-formed annotation for " + full_name + ": " + returns) + fail(f"Badly formed annotation for {full_name!r}: {returns!r}") + function_node = module_node.body[0] + assert isinstance(function_node, ast.FunctionDef) try: - name, legacy, kwargs = self.parse_converter(module.body[0].returns) + name, legacy, kwargs = self.parse_converter(function_node.returns) if legacy: - fail("Legacy converter {!r} not allowed as a return converter" - .format(name)) + fail(f"Legacy converter {name!r} not allowed as a return converter") if name not in return_converters: - fail("No available return converter called " + repr(name)) + fail(f"No available return converter called {name!r}") return_converter = return_converters[name](**kwargs) except ValueError: - fail("Badly-formed annotation for " + full_name + ": " + returns) + fail(f"Badly formed annotation for {full_name!r}: {returns!r}") fields = [x.strip() for x in full_name.split('.')] function_name = fields.pop() module, cls = self.clinic._module_and_class(fields) - fields = full_name.split('.') - if fields[-1] in unsupported_special_methods: - fail(f"{fields[-1]} is a special method and cannot be converted to Argument Clinic! (Yet.)") - - if fields[-1] == '__new__': - if (self.kind is not CLASS_METHOD) or (not cls): - fail("__new__ must be a class method!") - self.kind = METHOD_NEW - elif fields[-1] == '__init__': - if (self.kind is not CALLABLE) or (not cls): - fail("__init__ must be a normal method, not a class or static method!") - self.kind = METHOD_INIT - if not return_converter: - return_converter = init_return_converter() + self.update_function_kind(full_name) + if self.kind is METHOD_INIT and not return_converter: + return_converter = init_return_converter() if not return_converter: return_converter = CReturnConverter() - if not module: - fail("Undefined module used in declaration of " + repr(full_name.strip()) + ".") self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, return_converter=return_converter, kind=self.kind, coexist=self.coexist) self.block.signatures.append(self.function) @@ -4818,7 +5558,7 @@ def state_modulename_name(self, line: str | None) -> None: # separate boolean state variables.) The states are defined in the # ParamState class. - def state_parameters_start(self, line: str | None) -> None: + def state_parameters_start(self, line: str) -> None: if not self.valid_line(line): return @@ -4830,16 +5570,17 @@ def state_parameters_start(self, line: str | None) -> None: return self.next(self.state_parameter, line) - def to_required(self): + def to_required(self) -> None: """ Transition to the "required" parameter state. """ if self.parameter_state is not ParamState.REQUIRED: self.parameter_state = ParamState.REQUIRED + assert self.function is not None for p in self.function.parameters.values(): p.group = -p.group - def state_parameter(self, line: str | None) -> None: + def state_parameter(self, line: str) -> None: assert isinstance(self.function, Function) if not self.valid_line(line): @@ -4864,16 +5605,23 @@ def state_parameter(self, line: str | None) -> None: self.parameter_continuation = line[:-1] return + line = line.lstrip() + version: VersionTuple | None = None + match = self.from_version_re.fullmatch(line) + if match: + line = match[1] + version = self.parse_version(match[2]) + func = self.function - match line.lstrip(): + match line: case '*': - self.parse_star(func) + self.parse_star(func, version) case '[': self.parse_opening_square_bracket(func) case ']': self.parse_closing_square_bracket(func) case '/': - self.parse_slash(func) + self.parse_slash(func, version) case param: self.parse_parameter(param) @@ -4930,18 +5678,22 @@ def parse_parameter(self, line: str) -> None: except SyntaxError: pass if not module: - fail("Function " + self.function.name + " has an invalid parameter declaration:\n\t" + line) + fail(f"Function {self.function.name!r} has an invalid parameter declaration:\n\t", + repr(line)) function = module.body[0] assert isinstance(function, ast.FunctionDef) function_args = function.args if len(function_args.args) > 1: - fail("Function " + self.function.name + " has an invalid parameter declaration (comma?):\n\t" + line) + fail(f"Function {self.function.name!r} has an " + f"invalid parameter declaration (comma?): {line!r}") if function_args.defaults or function_args.kw_defaults: - fail("Function " + self.function.name + " has an invalid parameter declaration (default value?):\n\t" + line) + fail(f"Function {self.function.name!r} has an " + f"invalid parameter declaration (default value?): {line!r}") if function_args.kwarg: - fail("Function " + self.function.name + " has an invalid parameter declaration (**kwargs?):\n\t" + line) + fail(f"Function {self.function.name!r} has an " + f"invalid parameter declaration (**kwargs?): {line!r}") if function_args.vararg: is_vararg = True @@ -4955,7 +5707,7 @@ def parse_parameter(self, line: str) -> None: if not default: if self.parameter_state is ParamState.OPTIONAL: - fail(f"Can't have a parameter without a default ({parameter_name!r})\n" + fail(f"Can't have a parameter without a default ({parameter_name!r}) " "after a parameter with a default!") value: Sentinels | Null if is_vararg: @@ -4983,7 +5735,7 @@ def parse_parameter(self, line: str) -> None: # of disallowed ast nodes. class DetectBadNodes(ast.NodeVisitor): bad = False - def bad_node(self, node): + def bad_node(self, node: ast.AST) -> None: self.bad = True # inline function call @@ -5010,15 +5762,16 @@ def bad_node(self, node): # but at least make an attempt at ensuring it's a valid expression. try: value = eval(default) - if value is unspecified: - fail("'unspecified' is not a legal default value!") except NameError: pass # probably a named constant except Exception as e: - fail("Malformed expression given as default value\n" - "{!r} caused {!r}".format(default, e)) + fail("Malformed expression given as default value " + f"{default!r} caused {e!r}") + else: + if value is unspecified: + fail("'unspecified' is not a legal default value!") if bad: - fail("Unsupported expression as default value: " + repr(default)) + fail(f"Unsupported expression as default value: {default!r}") assignment = module.body[0] assert isinstance(assignment, ast.Assign) @@ -5036,7 +5789,10 @@ def bad_node(self, node): )): c_default = kwargs.get("c_default") if not (isinstance(c_default, str) and c_default): - fail("When you specify an expression (" + repr(default) + ") as your default value,\nyou MUST specify a valid c_default." + ast.dump(expr)) + fail(f"When you specify an expression ({default!r}) " + f"as your default value, " + f"you MUST specify a valid c_default.", + ast.dump(expr)) py_default = default value = unknown elif isinstance(expr, ast.Attribute): @@ -5046,13 +5802,16 @@ def bad_node(self, node): a.append(n.attr) n = n.value if not isinstance(n, ast.Name): - fail("Unsupported default value " + repr(default) + " (looked like a Python constant)") + fail(f"Unsupported default value {default!r} " + "(looked like a Python constant)") a.append(n.id) py_default = ".".join(reversed(a)) c_default = kwargs.get("c_default") if not (isinstance(c_default, str) and c_default): - fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.") + fail(f"When you specify a named constant ({py_default!r}) " + "as your default value, " + "you MUST specify a valid c_default.") try: value = eval(py_default) @@ -5069,13 +5828,15 @@ def bad_node(self, node): c_default = py_default except SyntaxError as e: - fail("Syntax error: " + repr(e.text)) + fail(f"Syntax error: {e.text!r}") except (ValueError, AttributeError): value = unknown c_default = kwargs.get("c_default") py_default = default if not (isinstance(c_default, str) and c_default): - fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.") + fail("When you specify a named constant " + f"({py_default!r}) as your default value, " + "you MUST specify a valid c_default.") kwargs.setdefault('c_default', c_default) kwargs.setdefault('py_default', py_default) @@ -5083,7 +5844,7 @@ def bad_node(self, node): dict = legacy_converters if legacy else converters legacy_str = "legacy " if legacy else "" if name not in dict: - fail(f'{name} is not a valid {legacy_str}converter') + fail(f'{name!r} is not a valid {legacy_str}converter') # if you use a c_name for the parameter, we just give that name to the converter # but the parameter object gets the python name converter = dict[name](c_name or parameter_name, parameter_name, self.function, value, **kwargs) @@ -5108,7 +5869,8 @@ def bad_node(self, node): self.parameter_state = ParamState.START self.function.parameters.clear() else: - fail("A 'self' parameter, if specified, must be the very first thing in the parameter block.") + fail("A 'self' parameter, if specified, must be the " + "very first thing in the parameter block.") if isinstance(converter, defining_class_converter): _lp = len(self.function.parameters) @@ -5120,16 +5882,20 @@ def bad_node(self, node): if self.group: fail("A 'defining_class' parameter cannot be in an optional group.") else: - fail("A 'defining_class' parameter, if specified, must either be the first thing in the parameter block, or come just after 'self'.") + fail("A 'defining_class' parameter, if specified, must either " + "be the first thing in the parameter block, or come just " + "after 'self'.") - p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group) + p = Parameter(parameter_name, kind, function=self.function, + converter=converter, default=value, group=self.group, + deprecated_positional=self.deprecated_positional) names = [k.name for k in self.function.parameters.values()] if parameter_name in names[1:]: - fail("You can't have two parameters named " + repr(parameter_name) + "!") + fail(f"You can't have two parameters named {parameter_name!r}!") elif names and parameter_name == names[0] and c_name is None: - fail(f"Parameter '{parameter_name}' requires a custom C name") + fail(f"Parameter {parameter_name!r} requires a custom C name") key = f"{parameter_name}_as_{c_name}" if c_name else parameter_name self.function.parameters[key] = p @@ -5156,11 +5922,42 @@ def parse_converter( "Annotations must be either a name, a function call, or a string." ) - def parse_star(self, function: Function) -> None: - """Parse keyword-only parameter marker '*'.""" - if self.keyword_only: - fail(f"Function {function.name} uses '*' more than once.") - self.keyword_only = True + def parse_version(self, thenceforth: str) -> VersionTuple: + """Parse Python version in `[from ...]` marker.""" + assert isinstance(self.function, Function) + + try: + major, minor = thenceforth.split(".") + return int(major), int(minor) + except ValueError: + fail( + f"Function {self.function.name!r}: expected format '[from major.minor]' " + f"where 'major' and 'minor' are integers; got {thenceforth!r}" + ) + + def parse_star(self, function: Function, version: VersionTuple | None) -> None: + """Parse keyword-only parameter marker '*'. + + The 'version' parameter signifies the future version from which + the marker will take effect (None means it is already in effect). + """ + if version is None: + if self.keyword_only: + fail(f"Function {function.name!r} uses '*' more than once.") + self.check_remaining_star() + self.keyword_only = True + else: + if self.keyword_only: + fail(f"Function {function.name!r}: '* [from ...]' must precede '*'") + if self.deprecated_positional: + if self.deprecated_positional == version: + fail(f"Function {function.name!r} uses '* [from " + f"{version[0]}.{version[1]}]' more than once.") + if self.deprecated_positional < version: + fail(f"Function {function.name!r}: '* [from " + f"{version[0]}.{version[1]}]' must precede '* [from " + f"{self.deprecated_positional[0]}.{self.deprecated_positional[1]}]'") + self.deprecated_positional = version def parse_opening_square_bracket(self, function: Function) -> None: """Parse opening parameter group symbol '['.""" @@ -5170,7 +5967,8 @@ def parse_opening_square_bracket(self, function: Function) -> None: case ParamState.REQUIRED | ParamState.GROUP_AFTER: self.parameter_state = ParamState.GROUP_AFTER case st: - fail(f"Function {function.name} has an unsupported group configuration. " + fail(f"Function {function.name!r} " + f"has an unsupported group configuration. " f"(Unexpected state {st}.b)") self.group += 1 function.docstring_only = True @@ -5178,9 +5976,9 @@ def parse_opening_square_bracket(self, function: Function) -> None: def parse_closing_square_bracket(self, function: Function) -> None: """Parse closing parameter group symbol ']'.""" if not self.group: - fail(f"Function {function.name} has a ] without a matching [.") + fail(f"Function {function.name!r} has a ']' without a matching '['.") if not any(p.group == self.group for p in function.parameters.values()): - fail(f"Function {function.name} has an empty group.\n" + fail(f"Function {function.name!r} has an empty group. " "All groups must contain at least one parameter.") self.group -= 1 match self.parameter_state: @@ -5189,14 +5987,48 @@ def parse_closing_square_bracket(self, function: Function) -> None: case ParamState.GROUP_AFTER | ParamState.RIGHT_SQUARE_AFTER: self.parameter_state = ParamState.RIGHT_SQUARE_AFTER case st: - fail(f"Function {function.name} has an unsupported group configuration. " + fail(f"Function {function.name!r} " + f"has an unsupported group configuration. " f"(Unexpected state {st}.c)") - def parse_slash(self, function: Function) -> None: - """Parse positional-only parameter marker '/'.""" - if self.positional_only: - fail(f"Function {function.name} uses '/' more than once.") + def parse_slash(self, function: Function, version: VersionTuple | None) -> None: + """Parse positional-only parameter marker '/'. + + The 'version' parameter signifies the future version from which + the marker will take effect (None means it is already in effect). + """ + if version is None: + if self.deprecated_keyword: + fail(f"Function {function.name!r}: '/' must precede '/ [from ...]'") + if self.deprecated_positional: + fail(f"Function {function.name!r}: '/' must precede '* [from ...]'") + if self.keyword_only: + fail(f"Function {function.name!r}: '/' must precede '*'") + if self.positional_only: + fail(f"Function {function.name!r} uses '/' more than once.") + else: + if self.deprecated_keyword: + if self.deprecated_keyword == version: + fail(f"Function {function.name!r} uses '/ [from " + f"{version[0]}.{version[1]}]' more than once.") + if self.deprecated_keyword > version: + fail(f"Function {function.name!r}: '/ [from " + f"{version[0]}.{version[1]}]' must precede '/ [from " + f"{self.deprecated_keyword[0]}.{self.deprecated_keyword[1]}]'") + if self.deprecated_positional: + fail(f"Function {function.name!r}: '/ [from ...]' must precede '* [from ...]'") + if self.keyword_only: + fail(f"Function {function.name!r}: '/ [from ...]' must precede '*'") self.positional_only = True + self.deprecated_keyword = version + if version is not None: + found = False + for p in reversed(function.parameters.values()): + found = p.kind is inspect.Parameter.POSITIONAL_OR_KEYWORD + break + if not found: + fail(f"Function {function.name!r} specifies '/ [from ...]' " + f"without preceding parameters.") # REQUIRED and OPTIONAL are allowed here, that allows positional-only # without option groups to work (and have default values!) allowed = { @@ -5206,33 +6038,46 @@ def parse_slash(self, function: Function) -> None: ParamState.GROUP_BEFORE, } if (self.parameter_state not in allowed) or self.group: - fail(f"Function {function.name} has an unsupported group configuration. " + fail(f"Function {function.name!r} has an unsupported group configuration. " f"(Unexpected state {self.parameter_state}.d)") - if self.keyword_only: - fail(f"Function {function.name} mixes keyword-only and " - "positional-only parameters, which is unsupported.") # fixup preceding parameters for p in function.parameters.values(): - if p.is_vararg(): - continue - if (p.kind is not inspect.Parameter.POSITIONAL_OR_KEYWORD and - not isinstance(p.converter, self_converter) - ): - fail(f"Function {function.name} mixes keyword-only and " - "positional-only parameters, which is unsupported.") - p.kind = inspect.Parameter.POSITIONAL_ONLY - - def state_parameter_docstring_start(self, line: str | None) -> None: + if p.kind is inspect.Parameter.POSITIONAL_OR_KEYWORD: + if version is None: + p.kind = inspect.Parameter.POSITIONAL_ONLY + elif p.deprecated_keyword is None: + p.deprecated_keyword = version + + def state_parameter_docstring_start(self, line: str) -> None: + assert self.indent.margin is not None, "self.margin.infer() has not yet been called to set the margin" self.parameter_docstring_indent = len(self.indent.margin) assert self.indent.depth == 3 return self.next(self.state_parameter_docstring, line) + def docstring_append(self, obj: Function | Parameter, line: str) -> None: + """Add a rstripped line to the current docstring.""" + # gh-80282: We filter out non-ASCII characters from the docstring, + # since historically, some compilers may balk on non-ASCII input. + # If you're using Argument Clinic in an external project, + # you may not need to support the same array of platforms as CPython, + # so you may be able to remove this restriction. + matches = re.finditer(r'[^\x00-\x7F]', line) + if offending := ", ".join([repr(m[0]) for m in matches]): + warn("Non-ascii characters are not allowed in docstrings:", + offending) + + docstring = obj.docstring + if docstring: + docstring += "\n" + if stripped := line.rstrip(): + docstring += self.indent.dedent(stripped) + obj.docstring = docstring + # every line of the docstring must start with at least F spaces, # where F > P. # these F spaces will be stripped. - def state_parameter_docstring(self, line): - stripped = line.strip() - if stripped.startswith('#'): + def state_parameter_docstring(self, line: str) -> None: + if not self.valid_line(line): return indent = self.indent.measure(line) @@ -5245,195 +6090,166 @@ def state_parameter_docstring(self, line): assert self.indent.depth == 1 return self.next(self.state_function_docstring, line) - assert self.function.parameters - last_parameter = next(reversed(list(self.function.parameters.values()))) - - new_docstring = last_parameter.docstring - - if new_docstring: - new_docstring += '\n' - if stripped: - new_docstring += self.indent.dedent(line) - - last_parameter.docstring = new_docstring + assert self.function and self.function.parameters + last_param = next(reversed(self.function.parameters.values())) + self.docstring_append(last_param, line) # the final stanza of the DSL is the docstring. - def state_function_docstring(self, line): + def state_function_docstring(self, line: str) -> None: + assert self.function is not None + if self.group: - fail("Function " + self.function.name + " has a ] without a matching [.") + fail(f"Function {self.function.name!r} has a ']' without a matching '['.") - stripped = line.strip() - if stripped.startswith('#'): + if not self.valid_line(line): return - new_docstring = self.function.docstring - if new_docstring: - new_docstring += "\n" - if stripped: - line = self.indent.dedent(line).rstrip() - else: - line = '' - new_docstring += line - self.function.docstring = new_docstring - - def format_docstring(self): - f = self.function - - new_or_init = f.kind.new_or_init - if new_or_init and not f.docstring: - # don't render a docstring at all, no signature, nothing. - return f.docstring + self.docstring_append(self.function, line) + def format_docstring_signature( + self, f: Function, parameters: list[Parameter] + ) -> str: text, add, output = _text_accumulator() - parameters = f.render_parameters - - ## - ## docstring first line - ## - - if new_or_init: - # classes get *just* the name of the class - # not __new__, not __init__, and not module.classname - assert f.cls - add(f.cls.name) + add(f.displayname) + if self.forced_text_signature: + add(self.forced_text_signature) else: - add(f.name) - add('(') - - # populate "right_bracket_count" field for every parameter - assert parameters, "We should always have a self parameter. " + repr(f) - assert isinstance(parameters[0].converter, self_converter) - # self is always positional-only. - assert parameters[0].is_positional_only() - assert parameters[0].right_bracket_count == 0 - positional_only = True - for p in parameters[1:]: - if not p.is_positional_only(): - positional_only = False - else: - assert positional_only - if positional_only: - p.right_bracket_count = abs(p.group) - else: - # don't put any right brackets around non-positional-only parameters, ever. - p.right_bracket_count = 0 - - right_bracket_count = 0 - - def fix_right_bracket_count(desired): - nonlocal right_bracket_count - s = '' - while right_bracket_count < desired: - s += '[' - right_bracket_count += 1 - while right_bracket_count > desired: - s += ']' - right_bracket_count -= 1 - return s - - need_slash = False - added_slash = False - need_a_trailing_slash = False - - # we only need a trailing slash: - # * if this is not a "docstring_only" signature - # * and if the last *shown* parameter is - # positional only - if not f.docstring_only: - for p in reversed(parameters): - if not p.converter.show_in_signature: - continue - if p.is_positional_only(): - need_a_trailing_slash = True - break + add('(') + + # populate "right_bracket_count" field for every parameter + assert parameters, "We should always have a self parameter. " + repr(f) + assert isinstance(parameters[0].converter, self_converter) + # self is always positional-only. + assert parameters[0].is_positional_only() + assert parameters[0].right_bracket_count == 0 + positional_only = True + for p in parameters[1:]: + if not p.is_positional_only(): + positional_only = False + else: + assert positional_only + if positional_only: + p.right_bracket_count = abs(p.group) + else: + # don't put any right brackets around non-positional-only parameters, ever. + p.right_bracket_count = 0 + + right_bracket_count = 0 + + def fix_right_bracket_count(desired: int) -> str: + nonlocal right_bracket_count + s = '' + while right_bracket_count < desired: + s += '[' + right_bracket_count += 1 + while right_bracket_count > desired: + s += ']' + right_bracket_count -= 1 + return s + + need_slash = False + added_slash = False + need_a_trailing_slash = False + + # we only need a trailing slash: + # * if this is not a "docstring_only" signature + # * and if the last *shown* parameter is + # positional only + if not f.docstring_only: + for p in reversed(parameters): + if not p.converter.show_in_signature: + continue + if p.is_positional_only(): + need_a_trailing_slash = True + break - added_star = False + added_star = False - first_parameter = True - last_p = parameters[-1] - line_length = len(''.join(text)) - indent = " " * line_length - def add_parameter(text): - nonlocal line_length - nonlocal first_parameter - if first_parameter: - s = text - first_parameter = False - else: - s = ' ' + text - if line_length + len(s) >= 72: - add('\n') - add(indent) - line_length = len(indent) + first_parameter = True + last_p = parameters[-1] + line_length = len(''.join(text)) + indent = " " * line_length + def add_parameter(text: str) -> None: + nonlocal line_length + nonlocal first_parameter + if first_parameter: s = text - line_length += len(s) - add(s) - - for p in parameters: - if not p.converter.show_in_signature: - continue - assert p.name + first_parameter = False + else: + s = ' ' + text + if line_length + len(s) >= 72: + add('\n') + add(indent) + line_length = len(indent) + s = text + line_length += len(s) + add(s) + + for p in parameters: + if not p.converter.show_in_signature: + continue + assert p.name - is_self = isinstance(p.converter, self_converter) - if is_self and f.docstring_only: - # this isn't a real machine-parsable signature, - # so let's not print the "self" parameter - continue + is_self = isinstance(p.converter, self_converter) + if is_self and f.docstring_only: + # this isn't a real machine-parsable signature, + # so let's not print the "self" parameter + continue - if p.is_positional_only(): - need_slash = not f.docstring_only - elif need_slash and not (added_slash or p.is_positional_only()): - added_slash = True - add_parameter('/,') - - if p.is_keyword_only() and not added_star: - added_star = True - add_parameter('*,') - - p_add, p_output = text_accumulator() - p_add(fix_right_bracket_count(p.right_bracket_count)) - - if isinstance(p.converter, self_converter): - # annotate first parameter as being a "self". - # - # if inspect.Signature gets this function, - # and it's already bound, the self parameter - # will be stripped off. - # - # if it's not bound, it should be marked - # as positional-only. - # - # note: we don't print "self" for __init__, - # because this isn't actually the signature - # for __init__. (it can't be, __init__ doesn't - # have a docstring.) if this is an __init__ - # (or __new__), then this signature is for - # calling the class to construct a new instance. - p_add('$') + if p.is_positional_only(): + need_slash = not f.docstring_only + elif need_slash and not (added_slash or p.is_positional_only()): + added_slash = True + add_parameter('/,') + + if p.is_keyword_only() and not added_star: + added_star = True + add_parameter('*,') + + p_add, p_output = text_accumulator() + p_add(fix_right_bracket_count(p.right_bracket_count)) + + if isinstance(p.converter, self_converter): + # annotate first parameter as being a "self". + # + # if inspect.Signature gets this function, + # and it's already bound, the self parameter + # will be stripped off. + # + # if it's not bound, it should be marked + # as positional-only. + # + # note: we don't print "self" for __init__, + # because this isn't actually the signature + # for __init__. (it can't be, __init__ doesn't + # have a docstring.) if this is an __init__ + # (or __new__), then this signature is for + # calling the class to construct a new instance. + p_add('$') - if p.is_vararg(): - p_add("*") + if p.is_vararg(): + p_add("*") - name = p.converter.signature_name or p.name - p_add(name) + name = p.converter.signature_name or p.name + p_add(name) - if not p.is_vararg() and p.converter.is_optional(): - p_add('=') - value = p.converter.py_default - if not value: - value = repr(p.converter.default) - p_add(value) + if not p.is_vararg() and p.converter.is_optional(): + p_add('=') + value = p.converter.py_default + if not value: + value = repr(p.converter.default) + p_add(value) - if (p != last_p) or need_a_trailing_slash: - p_add(',') + if (p != last_p) or need_a_trailing_slash: + p_add(',') - add_parameter(p_output()) + add_parameter(p_output()) - add(fix_right_bracket_count(0)) - if need_a_trailing_slash: - add_parameter('/') - add(')') + add(fix_right_bracket_count(0)) + if need_a_trailing_slash: + add_parameter('/') + add(')') # PEP 8 says: # @@ -5451,35 +6267,27 @@ def add_parameter(text): if not f.docstring_only: add("\n" + sig_end_marker + "\n") - docstring_first_line = output() + signature_line = output() # now fix up the places where the brackets look wrong - docstring_first_line = docstring_first_line.replace(', ]', ',] ') + return signature_line.replace(', ]', ',] ') - # okay. now we're officially building the "parameters" section. - # create substitution text for {parameters} - spacer_line = False - for p in parameters: - if not p.docstring.strip(): - continue - if spacer_line: + @staticmethod + def format_docstring_parameters(params: list[Parameter]) -> str: + """Create substitution text for {parameters}""" + add, output = text_accumulator() + for p in params: + if p.docstring: + add(p.render_docstring()) add('\n') - else: - spacer_line = True - add(" ") - add(p.name) - add('\n') - add(textwrap.indent(rstrip_lines(p.docstring.rstrip()), " ")) - parameters = output() - if parameters: - parameters += '\n' - - ## - ## docstring body - ## + return output() - docstring = f.docstring.rstrip() - lines = [line.rstrip() for line in docstring.split('\n')] + def format_docstring(self) -> str: + assert self.function is not None + f = self.function + if f.kind.new_or_init and not f.docstring: + # don't render a docstring at all, no signature, nothing. + return f.docstring # Enforce the summary line! # The first line of a docstring should be a summary of the function. @@ -5493,63 +6301,66 @@ def add_parameter(text): # Guido said Clinic should enforce this: # http://mail.python.org/pipermail/python-dev/2013-June/127110.html + lines = f.docstring.split('\n') if len(lines) >= 2: if lines[1]: - fail("Docstring for " + f.full_name + " does not have a summary line!\n" + - "Every non-blank function docstring must start with\n" + - "a single line summary followed by an empty line.") + fail(f"Docstring for {f.full_name!r} does not have a summary line!\n" + "Every non-blank function docstring must start with " + "a single line summary followed by an empty line.") elif len(lines) == 1: # the docstring is only one line right now--the summary line. # add an empty line after the summary line so we have space # between it and the {parameters} we're about to add. lines.append('') - parameters_marker_count = len(docstring.split('{parameters}')) - 1 + parameters_marker_count = len(f.docstring.split('{parameters}')) - 1 if parameters_marker_count > 1: fail('You may not specify {parameters} more than once in a docstring!') + # insert signature at front and params after the summary line if not parameters_marker_count: - # insert after summary line lines.insert(2, '{parameters}') + lines.insert(0, '{signature}') - # insert at front of docstring - lines.insert(0, docstring_first_line) - + # finalize docstring + params = f.render_parameters + parameters = self.format_docstring_parameters(params) + signature = self.format_docstring_signature(f, params) docstring = "\n".join(lines) + return linear_format(docstring, + signature=signature, + parameters=parameters).rstrip() - add(docstring) - docstring = output() + def check_remaining_star(self, lineno: int | None = None) -> None: + assert isinstance(self.function, Function) - docstring = linear_format(docstring, parameters=parameters) - docstring = docstring.rstrip() + if self.keyword_only: + symbol = '*' + elif self.deprecated_positional: + symbol = '* [from ...]' + else: + return - return docstring + for p in reversed(self.function.parameters.values()): + if self.keyword_only: + if p.kind == inspect.Parameter.KEYWORD_ONLY: + return + elif self.deprecated_positional: + if p.deprecated_positional == self.deprecated_positional: + return + break + + fail(f"Function {self.function.name!r} specifies {symbol!r} " + f"without following parameters.", line_number=lineno) - def state_terminal(self, line): + def do_post_block_processing_cleanup(self, lineno: int) -> None: """ Called when processing the block is done. """ - assert not line - if not self.function: return - if self.keyword_only: - values = self.function.parameters.values() - if not values: - no_parameter_after_star = True - else: - last_parameter = next(reversed(list(values))) - no_parameter_after_star = last_parameter.kind != inspect.Parameter.KEYWORD_ONLY - if no_parameter_after_star: - fail("Function " + self.function.name + " specifies '*' without any parameters afterwards.") - - # remove trailing whitespace from all parameter docstrings - for name, value in self.function.parameters.items(): - if not value: - continue - value.docstring = value.docstring.rstrip() - + self.check_remaining_star(lineno) self.function.docstring = self.format_docstring() @@ -5570,13 +6381,9 @@ def state_terminal(self, line): } -clinic = None - - -def main(argv): - import sys - import argparse +def create_cli() -> argparse.ArgumentParser: cmdline = argparse.ArgumentParser( + prog="clinic.py", description="""Preprocessor for CPython C files. The purpose of the Argument Clinic is automating all the boilerplate involved @@ -5584,25 +6391,37 @@ def main(argv): signatures ("docstrings") for CPython builtins. For more information see https://docs.python.org/3/howto/clinic.html""") - cmdline.add_argument("-f", "--force", action='store_true') - cmdline.add_argument("-o", "--output", type=str) - cmdline.add_argument("-v", "--verbose", action='store_true') - cmdline.add_argument("--converters", action='store_true') + cmdline.add_argument("-f", "--force", action='store_true', + help="force output regeneration") + cmdline.add_argument("-o", "--output", type=str, + help="redirect file output to OUTPUT") + cmdline.add_argument("-v", "--verbose", action='store_true', + help="enable verbose mode") + cmdline.add_argument("--converters", action='store_true', + help=("print a list of all supported converters " + "and return converters")) cmdline.add_argument("--make", action='store_true', - help="Walk --srcdir to run over all relevant files.") + help="walk --srcdir to run over all relevant files") cmdline.add_argument("--srcdir", type=str, default=os.curdir, - help="The directory tree to walk in --make mode.") - cmdline.add_argument("filename", type=str, nargs="*") - ns = cmdline.parse_args(argv) - + help="the directory tree to walk in --make mode") + cmdline.add_argument("--exclude", type=str, action="append", + help=("a file to exclude in --make mode; " + "can be given multiple times")) + cmdline.add_argument("--limited", dest="limited_capi", action='store_true', + help="use the Limited C API") + cmdline.add_argument("filename", metavar="FILE", type=str, nargs="*", + help="the list of files to process") + return cmdline + + +def run_clinic(parser: argparse.ArgumentParser, ns: argparse.Namespace) -> None: if ns.converters: if ns.filename: - print("Usage error: can't specify --converters and a filename at the same time.") - print() - cmdline.print_usage() - sys.exit(-1) - converters = [] - return_converters = [] + parser.error( + "can't specify --converters and a filename at the same time" + ) + converters: list[tuple[str, str]] = [] + return_converters: list[tuple[str, str]] = [] ignored = set(""" add_c_converter add_c_return_converter @@ -5654,19 +6473,18 @@ def main(argv): print() print("All converters also accept (c_default=None, py_default=None, annotation=None).") print("All return converters also accept (py_default=None).") - sys.exit(0) + return if ns.make: if ns.output or ns.filename: - print("Usage error: can't use -o or filenames with --make.") - print() - cmdline.print_usage() - sys.exit(-1) + parser.error("can't use -o or filenames with --make") if not ns.srcdir: - print("Usage error: --srcdir must not be empty with --make.") - print() - cmdline.print_usage() - sys.exit(-1) + parser.error("--srcdir must not be empty with --make") + if ns.exclude: + excludes = [os.path.join(ns.srcdir, f) for f in ns.exclude] + excludes = [os.path.normpath(f) for f in excludes] + else: + excludes = [] for root, dirs, files in os.walk(ns.srcdir): for rcs_dir in ('.svn', '.git', '.hg', 'build', 'externals'): if rcs_dir in dirs: @@ -5676,26 +6494,39 @@ def main(argv): if not filename.endswith(('.c', '.cpp', '.h')): continue path = os.path.join(root, filename) + path = os.path.normpath(path) + if path in excludes: + continue if ns.verbose: print(path) - parse_file(path, verify=not ns.force) + parse_file(path, + verify=not ns.force, limited_capi=ns.limited_capi) return if not ns.filename: - cmdline.print_usage() - sys.exit(-1) + parser.error("no input files") if ns.output and len(ns.filename) > 1: - print("Usage error: can't use -o with multiple filenames.") - print() - cmdline.print_usage() - sys.exit(-1) + parser.error("can't use -o with multiple filenames") for filename in ns.filename: if ns.verbose: print(filename) - parse_file(filename, output=ns.output, verify=not ns.force) + parse_file(filename, output=ns.output, + verify=not ns.force, limited_capi=ns.limited_capi) + + +def main(argv: list[str] | None = None) -> NoReturn: + parser = create_cli() + args = parser.parse_args(argv) + try: + run_clinic(parser, args) + except ClinicError as exc: + sys.stderr.write(exc.report()) + sys.exit(1) + else: + sys.exit(0) if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) + main() diff --git a/Tools/clinic/cpp.py b/Tools/clinic/cpp.py index fbac81336b545e..16eee6fc399491 100644 --- a/Tools/clinic/cpp.py +++ b/Tools/clinic/cpp.py @@ -1,7 +1,6 @@ import dataclasses as dc import re import sys -from collections.abc import Callable from typing import NoReturn @@ -44,9 +43,12 @@ def __post_init__(self) -> None: self.line_number = 0 def __repr__(self) -> str: - return ( - f"" + parts = ( + str(id(self)), + f"line={self.line_number}", + f"condition={self.condition()!r}" ) + return f"" def status(self) -> str: return str(self.line_number).rjust(4) + ": " + self.condition() @@ -66,14 +68,6 @@ def fail(self, *a: object) -> NoReturn: print(" ", ' '.join(str(x) for x in a)) sys.exit(-1) - def close(self) -> None: - if self.stack: - self.fail("Ended file while still in a preprocessor conditional block!") - - def write(self, s: str) -> None: - for line in s.split("\n"): - self.writeline(line) - def writeline(self, line: str) -> None: self.line_number += 1 line = line.strip() @@ -184,11 +178,17 @@ def pop_stack() -> TokenAndCondition: if self.verbose: print(self.status()) -if __name__ == '__main__': - for filename in sys.argv[1:]: + +def _main(filenames: list[str] | None = None) -> None: + filenames = filenames or sys.argv[1:] + for filename in filenames: with open(filename) as f: cpp = Monitor(filename, verbose=True) print() print(filename) - for line_number, line in enumerate(f.read().split('\n'), 1): + for line in f: cpp.writeline(line) + + +if __name__ == '__main__': + _main() diff --git a/Tools/clinic/mypy.ini b/Tools/clinic/mypy.ini index 672911dc19abda..b1fdad673c61a1 100644 --- a/Tools/clinic/mypy.ini +++ b/Tools/clinic/mypy.ini @@ -1,12 +1,12 @@ [mypy] +files = Tools/clinic/ +pretty = True + # make sure clinic can still be run on Python 3.10 python_version = 3.10 -pretty = True -enable_error_code = ignore-without-code -disallow_any_generics = True + +# and be strict! +strict = True strict_concatenate = True -warn_redundant_casts = True -warn_unused_ignores = True -warn_unused_configs = True +enable_error_code = ignore-without-code,redundant-expr,truthy-bool warn_unreachable = True -files = Tools/clinic/ diff --git a/Tools/clinic/requirements-dev.txt b/Tools/clinic/requirements-dev.txt deleted file mode 100644 index e9529f3527e95e..00000000000000 --- a/Tools/clinic/requirements-dev.txt +++ /dev/null @@ -1,2 +0,0 @@ -# Requirements file for external linters and checks we run on Tools/clinic/ in CI -mypy==1.4.1 diff --git a/Tools/freeze/test/freeze.py b/Tools/freeze/test/freeze.py index 92e97cb261719c..1e3687dbb807a6 100644 --- a/Tools/freeze/test/freeze.py +++ b/Tools/freeze/test/freeze.py @@ -1,14 +1,22 @@ import os import os.path -import re import shlex import shutil import subprocess +import sysconfig +from test import support + + +def get_python_source_dir(): + src_dir = sysconfig.get_config_var('abs_srcdir') + if not src_dir: + src_dir = sysconfig.get_config_var('srcdir') + return os.path.abspath(src_dir) TESTS_DIR = os.path.dirname(__file__) TOOL_ROOT = os.path.dirname(TESTS_DIR) -SRCDIR = os.path.dirname(os.path.dirname(TOOL_ROOT)) +SRCDIR = get_python_source_dir() MAKE = shutil.which('make') FREEZE = os.path.join(TOOL_ROOT, 'freeze.py') @@ -19,8 +27,10 @@ class UnsupportedError(Exception): """The operation isn't supported.""" -def _run_quiet(cmd, cwd=None): - #print(f'# {" ".join(shlex.quote(a) for a in cmd)}') +def _run_quiet(cmd, *, cwd=None): + if cwd: + print('+', 'cd', cwd, flush=True) + print('+', shlex.join(cmd), flush=True) try: return subprocess.run( cmd, @@ -40,8 +50,8 @@ def _run_quiet(cmd, cwd=None): raise -def _run_stdout(cmd, cwd=None): - proc = _run_quiet(cmd, cwd) +def _run_stdout(cmd): + proc = _run_quiet(cmd) return proc.stdout.strip() @@ -75,60 +85,26 @@ def ensure_opt(args, name, value): def copy_source_tree(newroot, oldroot): - print(f'copying the source tree into {newroot}...') + print(f'copying the source tree from {oldroot} to {newroot}...') if os.path.exists(newroot): if newroot == SRCDIR: raise Exception('this probably isn\'t what you wanted') shutil.rmtree(newroot) - def ignore_non_src(src, names): - """Turns what could be a 1000M copy into a 100M copy.""" - # Don't copy the ~600M+ of needless git repo metadata. - # source only, ignore cached .pyc files. - subdirs_to_skip = {'.git', '__pycache__'} - if os.path.basename(src) == 'Doc': - # Another potential ~250M+ of non test related data. - subdirs_to_skip.add('build') - subdirs_to_skip.add('venv') - return subdirs_to_skip - - shutil.copytree(oldroot, newroot, ignore=ignore_non_src) + shutil.copytree(oldroot, newroot, ignore=support.copy_python_src_ignore) if os.path.exists(os.path.join(newroot, 'Makefile')): - _run_quiet([MAKE, 'clean'], newroot) - - -def get_makefile_var(builddir, name): - regex = re.compile(rf'^{name} *=\s*(.*?)\s*$') - filename = os.path.join(builddir, 'Makefile') - try: - infile = open(filename, encoding='utf-8') - except FileNotFoundError: - return None - with infile: - for line in infile: - m = regex.match(line) - if m: - value, = m.groups() - return value or '' - return None - - -def get_config_var(builddir, name): - python = os.path.join(builddir, 'python') - if os.path.isfile(python): - cmd = [python, '-c', - f'import sysconfig; print(sysconfig.get_config_var("{name}"))'] - try: - return _run_stdout(cmd) - except subprocess.CalledProcessError: - pass - return get_makefile_var(builddir, name) + # Out-of-tree builds require a clean srcdir. "make clean" keeps + # the "python" program, so use "make distclean" instead. + _run_quiet([MAKE, 'distclean'], cwd=newroot) ################################## # freezing def prepare(script=None, outdir=None): + print() + print("cwd:", os.getcwd()) + if not outdir: outdir = OUTDIR os.makedirs(outdir, exist_ok=True) @@ -151,37 +127,33 @@ def prepare(script=None, outdir=None): # Run configure. print(f'configuring python in {builddir}...') - cmd = [ - os.path.join(srcdir, 'configure'), - *shlex.split(get_config_var(SRCDIR, 'CONFIG_ARGS') or ''), - ] + config_args = shlex.split(sysconfig.get_config_var('CONFIG_ARGS') or '') + cmd = [os.path.join(srcdir, 'configure'), *config_args] ensure_opt(cmd, 'cache-file', os.path.join(outdir, 'python-config.cache')) prefix = os.path.join(outdir, 'python-installation') ensure_opt(cmd, 'prefix', prefix) - _run_quiet(cmd, builddir) + _run_quiet(cmd, cwd=builddir) if not MAKE: raise UnsupportedError('make') - cores = os.cpu_count() + cores = os.process_cpu_count() if cores and cores >= 3: # this test is most often run as part of the whole suite with a lot # of other tests running in parallel, from 1-2 vCPU systems up to # people's NNN core beasts. Don't attempt to use it all. - parallel = f'-j{cores*2//3}' + jobs = cores * 2 // 3 + parallel = f'-j{jobs}' else: parallel = '-j2' # Build python. print(f'building python {parallel=} in {builddir}...') - if os.path.exists(os.path.join(srcdir, 'Makefile')): - # Out-of-tree builds require a clean srcdir. - _run_quiet([MAKE, '-C', srcdir, 'clean']) - _run_quiet([MAKE, '-C', builddir, parallel]) + _run_quiet([MAKE, parallel], cwd=builddir) # Install the build. print(f'installing python into {prefix}...') - _run_quiet([MAKE, '-C', builddir, 'install']) + _run_quiet([MAKE, 'install'], cwd=builddir) python = os.path.join(prefix, 'bin', 'python3') return outdir, scriptfile, python @@ -194,8 +166,8 @@ def freeze(python, scriptfile, outdir): print(f'freezing {scriptfile}...') os.makedirs(outdir, exist_ok=True) # Use -E to ignore PYTHONSAFEPATH - _run_quiet([python, '-E', FREEZE, '-o', outdir, scriptfile], outdir) - _run_quiet([MAKE, '-C', os.path.dirname(scriptfile)]) + _run_quiet([python, '-E', FREEZE, '-o', outdir, scriptfile], cwd=outdir) + _run_quiet([MAKE], cwd=os.path.dirname(scriptfile)) name = os.path.basename(scriptfile).rpartition('.')[0] executable = os.path.join(outdir, name) diff --git a/Tools/lockbench/lockbench.py b/Tools/lockbench/lockbench.py new file mode 100644 index 00000000000000..9833d703e00cbb --- /dev/null +++ b/Tools/lockbench/lockbench.py @@ -0,0 +1,53 @@ +# Measure the performance of PyMutex and PyThread_type_lock locks +# with short critical sections. +# +# Usage: python Tools/lockbench/lockbench.py [CRITICAL_SECTION_LENGTH] +# +# How to interpret the results: +# +# Acquisitions (kHz): Reports the total number of lock acquisitions in +# thousands of acquisitions per second. This is the most important metric, +# particularly for the 1 thread case because even in multithreaded programs, +# most locks acquisitions are not contended. Values for 2+ threads are +# only meaningful for `--disable-gil` builds, because the GIL prevents most +# situations where there is lock contention with short critical sections. +# +# Fairness: A measure of how evenly the lock acquisitions are distributed. +# A fairness of 1.0 means that all threads acquired the lock the same number +# of times. A fairness of 1/N means that only one thread ever acquired the +# lock. +# See https://en.wikipedia.org/wiki/Fairness_measure#Jain's_fairness_index + +from _testinternalcapi import benchmark_locks +import sys + +# Max number of threads to test +MAX_THREADS = 10 + +# How much "work" to do while holding the lock +CRITICAL_SECTION_LENGTH = 1 + + +def jains_fairness(values): + # Jain's fairness index + # See https://en.wikipedia.org/wiki/Fairness_measure + return (sum(values) ** 2) / (len(values) * sum(x ** 2 for x in values)) + +def main(): + print("Lock Type Threads Acquisitions (kHz) Fairness") + for lock_type in ["PyMutex", "PyThread_type_lock"]: + use_pymutex = (lock_type == "PyMutex") + for num_threads in range(1, MAX_THREADS + 1): + acquisitions, thread_iters = benchmark_locks( + num_threads, use_pymutex, CRITICAL_SECTION_LENGTH) + + acquisitions /= 1000 # report in kHz for readability + fairness = jains_fairness(thread_iters) + + print(f"{lock_type: <20}{num_threads: <18}{acquisitions: >5.0f}{fairness: >20.2f}") + + +if __name__ == "__main__": + if len(sys.argv) > 1: + CRITICAL_SECTION_LENGTH = int(sys.argv[1]) + main() diff --git a/Tools/msi/README.txt b/Tools/msi/README.txt index 8c6ec516f18e9d..c25ada8397cd95 100644 --- a/Tools/msi/README.txt +++ b/Tools/msi/README.txt @@ -73,6 +73,13 @@ building on a recent Windows version, use the Control Panel (Programs | Programs and Features | Turn Windows Features on or off) and ensure that the entry ".NET Framework 3.5 (includes .NET 2.0 and 3.0)" is enabled. +For Python 3.11.x and above, enable "Microsoft .NET Framework 4.8 Advanced Services" +instead of "Microsoft .NET Framework Version 3.5" available for Windows 10 and above. +Also make sure "MSVC v143 - VS 2022 C++ ARM64 build tools" are selected under +"Desktop Development with C++" in "Visual Studio installer" even if you are not +building on ARM64 along with other x64 related v143 build tools. This is because for +3.11.x and above we have upgraded to Wix-3.14. + For testing, the installer should be built with the Tools/msi/build.bat script: diff --git a/Tools/msi/test/test_files.wxs b/Tools/msi/test/test_files.wxs index b5f68faef30e02..bb9b258692a62f 100644 --- a/Tools/msi/test/test_files.wxs +++ b/Tools/msi/test/test_files.wxs @@ -1,41 +1,41 @@ - + - + - + - + - + - + - + - + - + diff --git a/Tools/patchcheck/patchcheck.py b/Tools/patchcheck/patchcheck.py index fa3a43af6e6048..af1f0584bb5403 100755 --- a/Tools/patchcheck/patchcheck.py +++ b/Tools/patchcheck/patchcheck.py @@ -11,6 +11,13 @@ import untabify +def get_python_source_dir(): + src_dir = sysconfig.get_config_var('abs_srcdir') + if not src_dir: + src_dir = sysconfig.get_config_var('srcdir') + return os.path.abspath(src_dir) + + # Excluded directories which are copies of external libraries: # don't check their coding style EXCLUDE_DIRS = [ @@ -18,12 +25,13 @@ os.path.join('Modules', 'expat'), os.path.join('Modules', 'zlib'), ] -SRCDIR = sysconfig.get_config_var('srcdir') +SRCDIR = get_python_source_dir() def n_files_str(count): """Return 'N file(s)' with the proper plurality on 'file'.""" - return "{} file{}".format(count, "s" if count != 1 else "") + s = "s" if count != 1 else "" + return f"{count} file{s}" def status(message, modal=False, info=None): @@ -77,7 +85,7 @@ def get_git_remote_default_branch(remote_name): It is typically called 'main', but may differ """ - cmd = "git remote show {}".format(remote_name).split() + cmd = f"git remote show {remote_name}".split() env = os.environ.copy() env['LANG'] = 'C' try: @@ -164,9 +172,9 @@ def report_modified_files(file_paths): if count == 0: return n_files_str(count) else: - lines = ["{}:".format(n_files_str(count))] + lines = [f"{n_files_str(count)}:"] for path in file_paths: - lines.append(" {}".format(path)) + lines.append(f" {path}") return "\n".join(lines) @@ -205,27 +213,6 @@ def normalize_c_whitespace(file_paths): return fixed -ws_re = re.compile(br'\s+(\r?\n)$') - -@status("Fixing docs whitespace", info=report_modified_files) -def normalize_docs_whitespace(file_paths): - fixed = [] - for path in file_paths: - abspath = os.path.join(SRCDIR, path) - try: - with open(abspath, 'rb') as f: - lines = f.readlines() - new_lines = [ws_re.sub(br'\1', line) for line in lines] - if new_lines != lines: - shutil.copyfile(abspath, abspath + '.bak') - with open(abspath, 'wb') as f: - f.writelines(new_lines) - fixed.append(path) - except Exception as err: - print('Cannot fix %s: %s' % (path, err)) - return fixed - - @status("Docs modified", modal=True) def docs_modified(file_paths): """Report if any file in the Doc directory has been changed.""" @@ -244,6 +231,7 @@ def reported_news(file_paths): return any(p.startswith(os.path.join('Misc', 'NEWS.d', 'next')) for p in file_paths) + @status("configure regenerated", modal=True, info=str) def regenerated_configure(file_paths): """Check if configure has been regenerated.""" @@ -252,6 +240,7 @@ def regenerated_configure(file_paths): else: return "not needed" + @status("pyconfig.h.in regenerated", modal=True, info=str) def regenerated_pyconfig_h_in(file_paths): """Check if pyconfig.h.in has been regenerated.""" @@ -260,6 +249,7 @@ def regenerated_pyconfig_h_in(file_paths): else: return "not needed" + def ci(pull_request): if pull_request == 'false': print('Not a pull request; skipping') @@ -268,19 +258,18 @@ def ci(pull_request): file_paths = changed_files(base_branch) python_files = [fn for fn in file_paths if fn.endswith('.py')] c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))] - doc_files = [fn for fn in file_paths if fn.startswith('Doc') and - fn.endswith(('.rst', '.inc'))] fixed = [] fixed.extend(normalize_whitespace(python_files)) fixed.extend(normalize_c_whitespace(c_files)) - fixed.extend(normalize_docs_whitespace(doc_files)) if not fixed: print('No whitespace issues found') else: - print(f'Please fix the {len(fixed)} file(s) with whitespace issues') - print('(on UNIX you can run `make patchcheck` to make the fixes)') + count = len(fixed) + print(f'Please fix the {n_files_str(count)} with whitespace issues') + print('(on Unix you can run `make patchcheck` to make the fixes)') sys.exit(1) + def main(): base_branch = get_base_branch() file_paths = changed_files(base_branch) @@ -293,8 +282,6 @@ def main(): normalize_whitespace(python_files) # C rules enforcement. normalize_c_whitespace(c_files) - # Doc whitespace enforcement. - normalize_docs_whitespace(doc_files) # Docs updated. docs_modified(doc_files) # Misc/ACKS changed. diff --git a/Tools/patchcheck/untabify.py b/Tools/patchcheck/untabify.py index 861c83ced90f24..5c9d1208540830 100755 --- a/Tools/patchcheck/untabify.py +++ b/Tools/patchcheck/untabify.py @@ -21,8 +21,7 @@ def main(): if optname == '-t': tabsize = int(optvalue) - for filename in args: - process(filename, tabsize) + return max(process(filename, tabsize) for filename in args) def process(filename, tabsize, verbose=True): @@ -32,10 +31,10 @@ def process(filename, tabsize, verbose=True): encoding = f.encoding except IOError as msg: print("%r: I/O error: %s" % (filename, msg)) - return + return 2 newtext = text.expandtabs(tabsize) if newtext == text: - return + return 0 backup = filename + "~" try: os.unlink(backup) @@ -49,7 +48,8 @@ def process(filename, tabsize, verbose=True): f.write(newtext) if verbose: print(filename) + return 1 if __name__ == '__main__': - main() + raise SystemExit(main()) diff --git a/Tools/peg_generator/mypy.ini b/Tools/peg_generator/mypy.ini index 17323722c85ad0..f38f21bed004b2 100644 --- a/Tools/peg_generator/mypy.ini +++ b/Tools/peg_generator/mypy.ini @@ -1,26 +1,23 @@ [mypy] -files = pegen - -follow_imports = error -no_implicit_optional = True -strict_optional = True - -#check_untyped_defs = True -disallow_untyped_calls = True -disallow_untyped_defs = True +files = Tools/peg_generator/pegen +pretty = True +show_traceback = True -disallow_any_generics = true -disallow_any_unimported = True -disallow_incomplete_defs = True -disallow_subclassing_any = True +# Make sure the peg_generator can be run using Python 3.10: +python_version = 3.10 -warn_unused_configs = True -warn_unused_ignores = true -warn_redundant_casts = true -warn_no_return = True +# Be strict... +strict = True +warn_unreachable = True +enable_error_code = truthy-bool,ignore-without-code,redundant-expr -show_traceback = True -show_error_codes = True +# This causes *many* false positives on the peg_generator +# due to pegen.grammar.GrammarVisitor returning Any from visit() and generic_visit(). +# It would be possible to workaround the false positives using asserts, +# but it would be pretty tedious, and probably isn't worth it. +warn_return_any = False -[mypy-pegen.grammar_parser] -strict_optional = False +# Not all of the strictest settings can be enabled +# on generated Python code yet: +[mypy-pegen.grammar_parser.*] +disable_error_code = redundant-expr diff --git a/Tools/peg_generator/peg_extension/peg_extension.c b/Tools/peg_generator/peg_extension/peg_extension.c index 7df134b5ade8bb..b081240ffff017 100644 --- a/Tools/peg_generator/peg_extension/peg_extension.c +++ b/Tools/peg_generator/peg_extension/peg_extension.c @@ -52,7 +52,7 @@ parse_file(PyObject *self, PyObject *args, PyObject *kwds) PyCompilerFlags flags = _PyCompilerFlags_INIT; mod_ty res = _PyPegen_run_parser_from_file_pointer( fp, Py_file_input, filename_ob, - NULL, NULL, NULL, &flags, NULL, arena); + NULL, NULL, NULL, &flags, NULL, NULL, arena); fclose(fp); if (res == NULL) { goto error; diff --git a/Tools/peg_generator/pegen/__main__.py b/Tools/peg_generator/pegen/__main__.py index 2910d6ccf1c694..262c8a6db68f6e 100755 --- a/Tools/peg_generator/pegen/__main__.py +++ b/Tools/peg_generator/pegen/__main__.py @@ -12,7 +12,10 @@ import traceback from typing import Tuple -from pegen.build import Grammar, Parser, ParserGenerator, Tokenizer +from pegen.grammar import Grammar +from pegen.parser import Parser +from pegen.parser_generator import ParserGenerator +from pegen.tokenizer import Tokenizer from pegen.validator import validate_grammar diff --git a/Tools/peg_generator/pegen/ast_dump.py b/Tools/peg_generator/pegen/ast_dump.py index 2c57d0932fda37..07f8799c114f5d 100644 --- a/Tools/peg_generator/pegen/ast_dump.py +++ b/Tools/peg_generator/pegen/ast_dump.py @@ -66,6 +66,4 @@ def _format(node: Any, level: int = 0) -> Tuple[str, bool]: if all(cls.__name__ != "AST" for cls in node.__class__.__mro__): raise TypeError("expected AST, got %r" % node.__class__.__name__) - if indent is not None and not isinstance(indent, str): - indent = " " * indent return _format(node)[0] diff --git a/Tools/peg_generator/pegen/build.py b/Tools/peg_generator/pegen/build.py index e41330fade94e3..30bfb31471c7b2 100644 --- a/Tools/peg_generator/pegen/build.py +++ b/Tools/peg_generator/pegen/build.py @@ -1,11 +1,12 @@ import itertools +import logging import os import pathlib import sys import sysconfig import tempfile import tokenize -from typing import IO, Dict, List, Optional, Set, Tuple +from typing import IO, Any, Dict, List, Optional, Set, Tuple from pegen.c_generator import CParserGenerator from pegen.grammar import Grammar @@ -18,6 +19,7 @@ MOD_DIR = pathlib.Path(__file__).resolve().parent TokenDefinitions = Tuple[Dict[int, str], Dict[str, int], Set[str]] +Incomplete = Any # TODO: install `types-setuptools` and remove this alias def get_extra_flags(compiler_flags: str, compiler_py_flags_nodist: str) -> List[str]: @@ -28,7 +30,7 @@ def get_extra_flags(compiler_flags: str, compiler_py_flags_nodist: str) -> List[ return f"{flags} {py_flags_nodist}".split() -def fixup_build_ext(cmd): +def fixup_build_ext(cmd: Incomplete) -> None: """Function needed to make build_ext tests pass. When Python was built with --enable-shared on Unix, -L. is not enough to @@ -74,7 +76,7 @@ def compile_c_extension( keep_asserts: bool = True, disable_optimization: bool = False, library_dir: Optional[str] = None, -) -> str: +) -> pathlib.Path: """Compile the generated source for a parser generator into an extension module. The extension module will be generated in the same directory as the provided path @@ -89,6 +91,7 @@ def compile_c_extension( static library of the common parser sources (this is useful in case you are creating multiple extensions). """ + import setuptools.command.build_ext import setuptools.logging from setuptools import Extension, Distribution @@ -97,7 +100,7 @@ def compile_c_extension( from setuptools._distutils.sysconfig import customize_compiler if verbose: - setuptools.logging.set_threshold(setuptools.logging.logging.DEBUG) + setuptools.logging.set_threshold(logging.DEBUG) source_file_path = pathlib.Path(generated_source_path) extension_name = source_file_path.stem @@ -120,7 +123,14 @@ def compile_c_extension( common_sources = [ str(MOD_DIR.parent.parent.parent / "Python" / "Python-ast.c"), str(MOD_DIR.parent.parent.parent / "Python" / "asdl.c"), - str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "lexer" / "lexer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "lexer" / "state.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "lexer" / "buffer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer" / "string_tokenizer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer" / "file_tokenizer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer" / "utf8_tokenizer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer" / "readline_tokenizer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer" / "helpers.c"), str(MOD_DIR.parent.parent.parent / "Parser" / "pegen.c"), str(MOD_DIR.parent.parent.parent / "Parser" / "pegen_errors.c"), str(MOD_DIR.parent.parent.parent / "Parser" / "action_helpers.c"), @@ -130,6 +140,8 @@ def compile_c_extension( include_dirs = [ str(MOD_DIR.parent.parent.parent / "Include" / "internal"), str(MOD_DIR.parent.parent.parent / "Parser"), + str(MOD_DIR.parent.parent.parent / "Parser" / "lexer"), + str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer"), ] extension = Extension( extension_name, @@ -139,6 +151,7 @@ def compile_c_extension( ) dist = Distribution({"name": extension_name, "ext_modules": [extension]}) cmd = dist.get_command_obj("build_ext") + assert isinstance(cmd, setuptools.command.build_ext.build_ext) fixup_build_ext(cmd) cmd.build_lib = str(source_file_path.parent) cmd.include_dirs = include_dirs @@ -155,6 +168,7 @@ def compile_c_extension( library_filename = compiler.library_filename(extension_name, output_dir=library_dir) if newer_group(common_sources, library_filename, "newer"): if sys.platform == "win32": + assert compiler.static_lib_format pdb = compiler.static_lib_format % (extension_name, ".pdb") compile_opts = [f"/Fd{library_dir}\\{pdb}"] compile_opts.extend(extra_compile_args) @@ -207,7 +221,7 @@ def compile_c_extension( ext_path, libraries=cmd.get_libraries(extension), extra_postargs=extra_link_args, - export_symbols=cmd.get_export_symbols(extension), + export_symbols=cmd.get_export_symbols(extension), # type: ignore[no-untyped-call] debug=cmd.debug, build_temp=cmd.build_temp, ) diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index f57b6275f671d3..301949bdae96fe 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -375,8 +375,7 @@ def __init__( def add_level(self) -> None: self.print("if (p->level++ == MAXSTACK) {") with self.indent(): - self.print("p->error_indicator = 1;") - self.print("PyErr_NoMemory();") + self.print("_Pypegen_stack_overflow(p);") self.print("}") def remove_level(self) -> None: diff --git a/Tools/peg_generator/pegen/grammar.py b/Tools/peg_generator/pegen/grammar.py index 03d60d01026f85..1ee9d100b61f49 100644 --- a/Tools/peg_generator/pegen/grammar.py +++ b/Tools/peg_generator/pegen/grammar.py @@ -35,7 +35,13 @@ def generic_visit(self, node: Iterable[Any], *args: Any, **kwargs: Any) -> Any: class Grammar: def __init__(self, rules: Iterable[Rule], metas: Iterable[Tuple[str, Optional[str]]]): - self.rules = {rule.name: rule for rule in rules} + # Check if there are repeated rules in "rules" + all_rules = {} + for rule in rules: + if rule.name in all_rules: + raise GrammarError(f"Repeated rule {rule.name!r}") + all_rules[rule.name] = rule + self.rules = all_rules self.metas = dict(metas) def __str__(self) -> str: @@ -112,8 +118,7 @@ def __str__(self) -> str: return self.value def __iter__(self) -> Iterable[str]: - if False: - yield + yield from () class NameLeaf(Leaf): @@ -335,8 +340,7 @@ def __str__(self) -> str: return f"~" def __iter__(self) -> Iterator[Tuple[str, str]]: - if False: - yield + yield from () def __eq__(self, other: object) -> bool: if not isinstance(other, Cut): @@ -349,7 +353,7 @@ def initial_names(self) -> AbstractSet[str]: Plain = Union[Leaf, Group] Item = Union[Plain, Opt, Repeat, Forced, Lookahead, Rhs, Cut] -RuleName = Tuple[str, str] +RuleName = Tuple[str, Optional[str]] MetaTuple = Tuple[str, Optional[str]] MetaList = List[MetaTuple] RuleList = List[Rule] diff --git a/Tools/peg_generator/pegen/keywordgen.py b/Tools/peg_generator/pegen/keywordgen.py index 35a5e1a229cdec..82d717b72976e5 100644 --- a/Tools/peg_generator/pegen/keywordgen.py +++ b/Tools/peg_generator/pegen/keywordgen.py @@ -35,8 +35,6 @@ issoftkeyword = frozenset(softkwlist).__contains__ '''.lstrip() -EXTRA_KEYWORDS = ["async", "await"] - def main() -> None: parser = argparse.ArgumentParser( @@ -62,7 +60,7 @@ def main() -> None: gen.collect_rules() with args.keyword_file as thefile: - all_keywords = sorted(list(gen.keywords.keys()) + EXTRA_KEYWORDS) + all_keywords = sorted(list(gen.keywords.keys())) all_soft_keywords = sorted(gen.soft_keywords) keywords = "" if not all_keywords else " " + ",\n ".join(map(repr, all_keywords)) diff --git a/Tools/peg_generator/pegen/parser.py b/Tools/peg_generator/pegen/parser.py index 034e8e6017a22d..ed0aec9db2443f 100644 --- a/Tools/peg_generator/pegen/parser.py +++ b/Tools/peg_generator/pegen/parser.py @@ -10,7 +10,6 @@ from pegen.tokenizer import Mark, Tokenizer, exact_token_types T = TypeVar("T") -P = TypeVar("P", bound="Parser") F = TypeVar("F", bound=Callable[..., Any]) @@ -21,7 +20,7 @@ def logger(method: F) -> F: """ method_name = method.__name__ - def logger_wrapper(self: P, *args: object) -> T: + def logger_wrapper(self: "Parser", *args: object) -> Any: if not self._verbose: return method(self, *args) argsr = ",".join(repr(arg) for arg in args) @@ -33,7 +32,7 @@ def logger_wrapper(self: P, *args: object) -> T: print(f"{fill}... {method_name}({argsr}) --> {tree!s:.200}") return tree - logger_wrapper.__wrapped__ = method # type: ignore + logger_wrapper.__wrapped__ = method # type: ignore[attr-defined] return cast(F, logger_wrapper) @@ -41,7 +40,7 @@ def memoize(method: F) -> F: """Memoize a symbol method.""" method_name = method.__name__ - def memoize_wrapper(self: P, *args: object) -> T: + def memoize_wrapper(self: "Parser", *args: object) -> Any: mark = self._mark() key = mark, method_name, args # Fast path: cache hit, and not verbose. @@ -70,15 +69,17 @@ def memoize_wrapper(self: P, *args: object) -> T: self._reset(endmark) return tree - memoize_wrapper.__wrapped__ = method # type: ignore + memoize_wrapper.__wrapped__ = method # type: ignore[attr-defined] return cast(F, memoize_wrapper) -def memoize_left_rec(method: Callable[[P], Optional[T]]) -> Callable[[P], Optional[T]]: +def memoize_left_rec( + method: Callable[["Parser"], Optional[T]] +) -> Callable[["Parser"], Optional[T]]: """Memoize a left-recursive symbol method.""" method_name = method.__name__ - def memoize_left_rec_wrapper(self: P) -> Optional[T]: + def memoize_left_rec_wrapper(self: "Parser") -> Optional[T]: mark = self._mark() key = mark, method_name, () # Fast path: cache hit, and not verbose. @@ -152,7 +153,7 @@ def memoize_left_rec_wrapper(self: P) -> Optional[T]: self._reset(endmark) return tree - memoize_left_rec_wrapper.__wrapped__ = method # type: ignore + memoize_left_rec_wrapper.__wrapped__ = method # type: ignore[attr-defined] return memoize_left_rec_wrapper diff --git a/Tools/peg_generator/pegen/python_generator.py b/Tools/peg_generator/pegen/python_generator.py index 5329d0ebe5e64c..4a2883eb4ee202 100644 --- a/Tools/peg_generator/pegen/python_generator.py +++ b/Tools/peg_generator/pegen/python_generator.py @@ -102,7 +102,7 @@ def visit_NameLeaf(self, node: NameLeaf) -> Tuple[Optional[str], str]: if name in ("NAME", "NUMBER", "STRING", "OP", "TYPE_COMMENT"): name = name.lower() return name, f"self.{name}()" - if name in ("NEWLINE", "DEDENT", "INDENT", "ENDMARKER", "ASYNC", "AWAIT"): + if name in ("NEWLINE", "DEDENT", "INDENT", "ENDMARKER"): # Avoid using names that can be Python keywords return "_" + name.lower(), f"self.expect({name!r})" return name, f"self.{name}()" diff --git a/Tools/peg_generator/pegen/testutil.py b/Tools/peg_generator/pegen/testutil.py index 9fcca928b08ee5..0e85b844ef152b 100644 --- a/Tools/peg_generator/pegen/testutil.py +++ b/Tools/peg_generator/pegen/testutil.py @@ -37,7 +37,7 @@ def generate_parser(grammar: Grammar) -> Type[Parser]: def run_parser(file: IO[bytes], parser_class: Type[Parser], *, verbose: bool = False) -> Any: # Run a parser on a file (stream). - tokenizer = Tokenizer(tokenize.generate_tokens(file.readline)) # type: ignore # typeshed issue #3515 + tokenizer = Tokenizer(tokenize.generate_tokens(file.readline)) # type: ignore[arg-type] # typeshed issue #3515 parser = parser_class(tokenizer, verbose=verbose) result = parser.start() if result is None: @@ -52,7 +52,7 @@ def parse_string( if dedent: source = textwrap.dedent(source) file = io.StringIO(source) - return run_parser(file, parser_class, verbose=verbose) # type: ignore # typeshed issue #3515 + return run_parser(file, parser_class, verbose=verbose) # type: ignore[arg-type] # typeshed issue #3515 def make_parser(source: str) -> Type[Parser]: @@ -116,7 +116,7 @@ def generate_parser_c_extension( def print_memstats() -> bool: MiB: Final = 2**20 try: - import psutil # type: ignore + import psutil except ImportError: return False print("Memory stats:") diff --git a/Tools/requirements-dev.txt b/Tools/requirements-dev.txt new file mode 100644 index 00000000000000..add28b1bb38183 --- /dev/null +++ b/Tools/requirements-dev.txt @@ -0,0 +1,7 @@ +# Requirements file for external linters and checks we run on +# Tools/clinic, Tools/cases_generator/, and Tools/peg_generator/ in CI +mypy==1.5.1 + +# needed for peg_generator: +types-psutil==5.9.5.16 +types-setuptools==68.2.0.0 diff --git a/Tools/requirements-hypothesis.txt b/Tools/requirements-hypothesis.txt new file mode 100644 index 00000000000000..b95300a07dd2b4 --- /dev/null +++ b/Tools/requirements-hypothesis.txt @@ -0,0 +1,4 @@ +# Requirements file for hypothesis that +# we use to run our property-based tests in CI. + +hypothesis==6.87.1 diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py deleted file mode 100644 index 445a34ae3e8eee..00000000000000 --- a/Tools/scripts/run_tests.py +++ /dev/null @@ -1,92 +0,0 @@ -"""Run Python's test suite in a fast, rigorous way. - -The defaults are meant to be reasonably thorough, while skipping certain -tests that can be time-consuming or resource-intensive (e.g. largefile), -or distracting (e.g. audio and gui). These defaults can be overridden by -simply passing a -u option to this script. - -""" - -import os -import shlex -import sys -import sysconfig -import test.support - - -def is_multiprocess_flag(arg): - return arg.startswith('-j') or arg.startswith('--multiprocess') - - -def is_resource_use_flag(arg): - return arg.startswith('-u') or arg.startswith('--use') - -def is_python_flag(arg): - return arg.startswith('-p') or arg.startswith('--python') - - -def main(regrtest_args): - args = [sys.executable, - '-u', # Unbuffered stdout and stderr - '-W', 'default', # Warnings set to 'default' - '-bb', # Warnings about bytes/bytearray - ] - - cross_compile = '_PYTHON_HOST_PLATFORM' in os.environ - if (hostrunner := os.environ.get("_PYTHON_HOSTRUNNER")) is None: - hostrunner = sysconfig.get_config_var("HOSTRUNNER") - if cross_compile: - # emulate -E, but keep PYTHONPATH + cross compile env vars, so - # test executable can load correct sysconfigdata file. - keep = { - '_PYTHON_PROJECT_BASE', - '_PYTHON_HOST_PLATFORM', - '_PYTHON_SYSCONFIGDATA_NAME', - 'PYTHONPATH' - } - environ = { - name: value for name, value in os.environ.items() - if not name.startswith(('PYTHON', '_PYTHON')) or name in keep - } - else: - environ = os.environ.copy() - args.append("-E") - - # Allow user-specified interpreter options to override our defaults. - args.extend(test.support.args_from_interpreter_flags()) - - args.extend(['-m', 'test', # Run the test suite - '-r', # Randomize test order - '-w', # Re-run failed tests in verbose mode - ]) - if sys.platform == 'win32': - args.append('-n') # Silence alerts under Windows - if not any(is_multiprocess_flag(arg) for arg in regrtest_args): - if cross_compile and hostrunner: - # For now use only two cores for cross-compiled builds; - # hostrunner can be expensive. - args.extend(['-j', '2']) - else: - args.extend(['-j', '0']) # Use all CPU cores - if not any(is_resource_use_flag(arg) for arg in regrtest_args): - args.extend(['-u', 'all,-largefile,-audio,-gui']) - - if cross_compile and hostrunner: - # If HOSTRUNNER is set and -p/--python option is not given, then - # use hostrunner to execute python binary for tests. - if not any(is_python_flag(arg) for arg in regrtest_args): - buildpython = sysconfig.get_config_var("BUILDPYTHON") - args.extend(["--python", f"{hostrunner} {buildpython}"]) - - args.extend(regrtest_args) - - print(shlex.join(args)) - if sys.platform == 'win32': - from subprocess import call - sys.exit(call(args)) - else: - os.execve(sys.executable, args, environ) - - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py index 9c881897c2de1d..bdca51df3dac53 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -2,38 +2,27 @@ default stats folders. """ +# NOTE: Bytecode introspection modules (opcode, dis, etc.) should only +# happen when loading a single dataset. When comparing datasets, it +# could get it wrong, leading to subtle errors. + import argparse import collections import json import os.path -import opcode from datetime import date import itertools import sys +import re if os.name == "nt": DEFAULT_DIR = "c:\\temp\\py_stats\\" else: DEFAULT_DIR = "/tmp/py_stats/" -#Create list of all instruction names -specialized = iter(opcode._specialized_instructions) -opname = ["<0>"] -for name in opcode.opname[1:]: - if name.startswith("<"): - try: - name = next(specialized) - except StopIteration: - pass - opname.append(name) - -# opcode_name --> opcode -# Sort alphabetically. -opmap = {name: i for i, name in enumerate(opname)} -opmap = dict(sorted(opmap.items())) - TOTAL = "specialization.hit", "specialization.miss", "execution_count" + def format_ratio(num, den): """ Format a ratio as a percentage. When the denominator is 0, returns the empty @@ -44,6 +33,18 @@ def format_ratio(num, den): else: return f"{num/den:.01%}" + +def percentage_to_float(s): + """ + Converts a percentage string to a float. The empty string is returned as 0.0 + """ + if s == "": + return 0.0 + else: + assert s[-1] == "%" + return float(s[:-1]) + + def join_rows(a_rows, b_rows): """ Joins two tables together, side-by-side, where the first column in each is a @@ -82,40 +83,53 @@ def join_rows(a_rows, b_rows): keys = list(a_data.keys()) + [k for k in b_data.keys() if k not in a_data] return [(k, *a_data.get(k, default), *b_data.get(k, default)) for k in keys] + def calculate_specialization_stats(family_stats, total): rows = [] for key in sorted(family_stats): if key.startswith("specialization.failure_kinds"): continue if key in ("specialization.hit", "specialization.miss"): - label = key[len("specialization."):] + label = key[len("specialization.") :] elif key == "execution_count": continue - elif key in ("specialization.success", "specialization.failure", "specializable"): + elif key in ( + "specialization.success", + "specialization.failure", + "specializable", + ): continue elif key.startswith("pair"): continue else: label = key - rows.append((f"{label:>12}", f"{family_stats[key]:>12}", format_ratio(family_stats[key], total))) + rows.append( + ( + f"{label:>12}", + f"{family_stats[key]:>12}", + format_ratio(family_stats[key], total), + ) + ) return rows + def calculate_specialization_success_failure(family_stats): total_attempts = 0 - for key in ("specialization.success", "specialization.failure"): + for key in ("specialization.success", "specialization.failure"): total_attempts += family_stats.get(key, 0) rows = [] if total_attempts: - for key in ("specialization.success", "specialization.failure"): - label = key[len("specialization."):] + for key in ("specialization.success", "specialization.failure"): + label = key[len("specialization.") :] label = label[0].upper() + label[1:] val = family_stats.get(key, 0) rows.append((label, val, format_ratio(val, total_attempts))) return rows + def calculate_specialization_failure_kinds(name, family_stats, defines): total_failures = family_stats.get("specialization.failure", 0) - failure_kinds = [ 0 ] * 40 + failure_kinds = [0] * 40 for key in family_stats: if not key.startswith("specialization.failure_kind"): continue @@ -128,9 +142,16 @@ def calculate_specialization_failure_kinds(name, family_stats, defines): for value, index in failures: if not value: continue - rows.append((kind_to_text(index, defines, name), value, format_ratio(value, total_failures))) + rows.append( + ( + kind_to_text(index, defines, name), + value, + format_ratio(value, total_failures), + ) + ) return rows + def print_specialization_stats(name, family_stats, defines): if "specializable" not in family_stats: return @@ -147,7 +168,10 @@ def print_specialization_stats(name, family_stats, defines): rows = calculate_specialization_failure_kinds(name, family_stats, defines) emit_table(("Failure kind", "Count:", "Ratio:"), rows) -def print_comparative_specialization_stats(name, base_family_stats, head_family_stats, defines): + +def print_comparative_specialization_stats( + name, base_family_stats, head_family_stats, defines +): if "specializable" not in base_family_stats: return @@ -160,27 +184,47 @@ def print_comparative_specialization_stats(name, base_family_stats, head_family_ head_rows = calculate_specialization_stats(head_family_stats, head_total) emit_table( ("Kind", "Base Count", "Base Ratio", "Head Count", "Head Ratio"), - join_rows(base_rows, head_rows) + join_rows(base_rows, head_rows), ) base_rows = calculate_specialization_success_failure(base_family_stats) head_rows = calculate_specialization_success_failure(head_family_stats) rows = join_rows(base_rows, head_rows) if rows: print_title("Specialization attempts", 4) - emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows) - base_rows = calculate_specialization_failure_kinds(name, base_family_stats, defines) - head_rows = calculate_specialization_failure_kinds(name, head_family_stats, defines) emit_table( - ("Failure kind", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), - join_rows(base_rows, head_rows) + ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows + ) + base_rows = calculate_specialization_failure_kinds( + name, base_family_stats, defines + ) + head_rows = calculate_specialization_failure_kinds( + name, head_family_stats, defines + ) + emit_table( + ( + "Failure kind", + "Base Count:", + "Base Ratio:", + "Head Count:", + "Head Ratio:", + ), + join_rows(base_rows, head_rows), ) + def gather_stats(input): # Note the output of this function must be JSON-serializable if os.path.isfile(input): with open(input, "r") as fd: - return json.load(fd) + stats = json.load(fd) + + stats["_stats_defines"] = { + int(k): v for k, v in stats["_stats_defines"].items() + } + stats["_defines"] = {int(k): v for k, v in stats["_defines"].items()} + return stats + elif os.path.isdir(input): stats = collections.Counter() for filename in os.listdir(input): @@ -189,25 +233,39 @@ def gather_stats(input): try: key, value = line.split(":") except ValueError: - print(f"Unparsable line: '{line.strip()}' in {filename}", file=sys.stderr) + print( + f"Unparsable line: '{line.strip()}' in {filename}", + file=sys.stderr, + ) continue key = key.strip() value = int(value) stats[key] += value - stats['__nfiles__'] += 1 + stats["__nfiles__"] += 1 + + import opcode + + stats["_specialized_instructions"] = [ + op for op in opcode._specialized_opmap.keys() if "__" not in op + ] + stats["_stats_defines"] = get_stats_defines() + stats["_defines"] = get_defines() + return stats else: raise ValueError(f"{input:r} is not a file or directory path") -def extract_opcode_stats(stats): - opcode_stats = [ {} for _ in range(256) ] + +def extract_opcode_stats(stats, prefix): + opcode_stats = collections.defaultdict(dict) for key, value in stats.items(): - if not key.startswith("opcode"): + if not key.startswith(prefix): continue - n, _, rest = key[7:].partition("]") - opcode_stats[int(n)][rest.strip(".")] = value + name, _, rest = key[len(prefix) + 1 :].partition("]") + opcode_stats[name][rest.strip(".")] = value return opcode_stats + def parse_kinds(spec_src, prefix="SPEC_FAIL"): defines = collections.defaultdict(list) start = "#define " + prefix + "_" @@ -215,14 +273,16 @@ def parse_kinds(spec_src, prefix="SPEC_FAIL"): line = line.strip() if not line.startswith(start): continue - line = line[len(start):] + line = line[len(start) :] name, val = line.split() defines[int(val.strip())].append(name.strip()) return defines + def pretty(defname): return defname.replace("_", " ").lower() + def kind_to_text(kind, defines, opname): if kind <= 8: return pretty(defines[kind][0]) @@ -236,21 +296,18 @@ def kind_to_text(kind, defines, opname): opname = "SUBSCR" for name in defines[kind]: if name.startswith(opname): - return pretty(name[len(opname)+1:]) + return pretty(name[len(opname) + 1 :]) return "kind " + str(kind) -def categorized_counts(opcode_stats): + +def categorized_counts(opcode_stats, specialized_instructions): basic = 0 specialized = 0 not_specialized = 0 - specialized_instructions = { - op for op in opcode._specialized_instructions - if "__" not in op} - for i, opcode_stat in enumerate(opcode_stats): + for name, opcode_stat in opcode_stats.items(): if "execution_count" not in opcode_stat: continue - count = opcode_stat['execution_count'] - name = opname[i] + count = opcode_stat["execution_count"] if "specializable" in opcode_stat: not_specialized += count elif name in specialized_instructions: @@ -261,12 +318,13 @@ def categorized_counts(opcode_stats): basic += count return basic, not_specialized, specialized + def print_title(name, level=2): - print("#"*level, name) + print("#" * level, name) print() -class Section: +class Section: def __init__(self, title, level=2, summary=None): self.title = title self.level = level @@ -287,12 +345,14 @@ def __exit__(*args): print("") print() + def to_str(x): if isinstance(x, int): return format(x, ",d") else: return str(x) + def emit_table(header, rows): width = len(header) header_line = "|" @@ -312,65 +372,90 @@ def emit_table(header, rows): print("|", " | ".join(to_str(i) for i in row), "|") print() + +def emit_histogram(title, stats, key, total): + rows = [] + for k, v in stats.items(): + if k.startswith(key): + entry = int(re.match(r".+\[([0-9]+)\]", k).groups()[0]) + rows.append((f"<= {entry}", int(v), format_ratio(int(v), total))) + # Don't include larger buckets with 0 entries + for j in range(len(rows) - 1, -1, -1): + if rows[j][1] != 0: + break + rows = rows[: j + 1] + + print(f"**{title}**\n") + emit_table(("Range", "Count:", "Ratio:"), rows) + + def calculate_execution_counts(opcode_stats, total): counts = [] - for i, opcode_stat in enumerate(opcode_stats): + for name, opcode_stat in opcode_stats.items(): if "execution_count" in opcode_stat: - count = opcode_stat['execution_count'] + count = opcode_stat["execution_count"] miss = 0 if "specializable" not in opcode_stat: miss = opcode_stat.get("specialization.miss") - counts.append((count, opname[i], miss)) + counts.append((count, name, miss)) counts.sort(reverse=True) cumulative = 0 rows = [] - for (count, name, miss) in counts: + for count, name, miss in counts: cumulative += count if miss: miss = format_ratio(miss, count) else: miss = "" - rows.append((name, count, format_ratio(count, total), - format_ratio(cumulative, total), miss)) + rows.append( + ( + name, + count, + format_ratio(count, total), + format_ratio(cumulative, total), + miss, + ) + ) return rows + def emit_execution_counts(opcode_stats, total): with Section("Execution counts", summary="execution counts for all instructions"): rows = calculate_execution_counts(opcode_stats, total) - emit_table( - ("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), - rows - ) + emit_table(("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), rows) + + +def _emit_comparative_execution_counts(base_rows, head_rows): + base_data = {x[0]: x[1:] for x in base_rows} + head_data = {x[0]: x[1:] for x in head_rows} + opcodes = base_data.keys() | head_data.keys() + + rows = [] + default = [0, "0.0%", "0.0%", 0] + for opcode in opcodes: + base_entry = base_data.get(opcode, default) + head_entry = head_data.get(opcode, default) + if base_entry[0] == 0: + change = 1 + else: + change = (head_entry[0] - base_entry[0]) / base_entry[0] + rows.append((opcode, base_entry[0], head_entry[0], f"{change:0.1%}")) + + rows.sort(key=lambda x: abs(percentage_to_float(x[-1])), reverse=True) + + emit_table(("Name", "Base Count:", "Head Count:", "Change:"), rows) + def emit_comparative_execution_counts( - base_opcode_stats, base_total, head_opcode_stats, head_total + base_opcode_stats, base_total, head_opcode_stats, head_total, level=2 ): - with Section("Execution counts", summary="execution counts for all instructions"): + with Section( + "Execution counts", summary="execution counts for all instructions", level=level + ): base_rows = calculate_execution_counts(base_opcode_stats, base_total) head_rows = calculate_execution_counts(head_opcode_stats, head_total) - base_data = dict((x[0], x[1:]) for x in base_rows) - head_data = dict((x[0], x[1:]) for x in head_rows) - opcodes = set(base_data.keys()) | set(head_data.keys()) + _emit_comparative_execution_counts(base_rows, head_rows) - rows = [] - default = [0, "0.0%", "0.0%", 0] - for opcode in opcodes: - base_entry = base_data.get(opcode, default) - head_entry = head_data.get(opcode, default) - if base_entry[0] == 0: - change = 1 - else: - change = (head_entry[0] - base_entry[0]) / base_entry[0] - rows.append( - (opcode, base_entry[0], head_entry[0], - f"{100*change:0.1f}%")) - - rows.sort(key=lambda x: -abs(float(x[-1][:-1]))) - - emit_table( - ("Name", "Base Count:", "Head Count:", "Change:"), - rows - ) def get_defines(): spec_path = os.path.join(os.path.dirname(__file__), "../../Python/specialize.c") @@ -378,65 +463,102 @@ def get_defines(): defines = parse_kinds(spec_src) return defines -def emit_specialization_stats(opcode_stats): - defines = get_defines() + +def emit_specialization_stats(opcode_stats, defines): with Section("Specialization stats", summary="specialization stats by family"): - for i, opcode_stat in enumerate(opcode_stats): - name = opname[i] + for name, opcode_stat in opcode_stats.items(): print_specialization_stats(name, opcode_stat, defines) -def emit_comparative_specialization_stats(base_opcode_stats, head_opcode_stats): - defines = get_defines() + +def emit_comparative_specialization_stats( + base_opcode_stats, head_opcode_stats, defines +): with Section("Specialization stats", summary="specialization stats by family"): - for i, (base_opcode_stat, head_opcode_stat) in enumerate(zip(base_opcode_stats, head_opcode_stats)): - name = opname[i] - print_comparative_specialization_stats(name, base_opcode_stat, head_opcode_stat, defines) + opcodes = set(base_opcode_stats.keys()) & set(head_opcode_stats.keys()) + for opcode in opcodes: + print_comparative_specialization_stats( + opcode, base_opcode_stats[opcode], head_opcode_stats[opcode], defines + ) -def calculate_specialization_effectiveness(opcode_stats, total): - basic, not_specialized, specialized = categorized_counts(opcode_stats) + +def calculate_specialization_effectiveness( + opcode_stats, total, specialized_instructions +): + basic, not_specialized, specialized = categorized_counts( + opcode_stats, specialized_instructions + ) return [ ("Basic", basic, format_ratio(basic, total)), ("Not specialized", not_specialized, format_ratio(not_specialized, total)), ("Specialized", specialized, format_ratio(specialized, total)), ] -def emit_specialization_overview(opcode_stats, total): + +def emit_specialization_overview(opcode_stats, total, specialized_instructions): with Section("Specialization effectiveness"): - rows = calculate_specialization_effectiveness(opcode_stats, total) + rows = calculate_specialization_effectiveness( + opcode_stats, total, specialized_instructions + ) emit_table(("Instructions", "Count:", "Ratio:"), rows) - for title, field in (("Deferred", "specialization.deferred"), ("Misses", "specialization.miss")): + for title, field in ( + ("Deferred", "specialization.deferred"), + ("Misses", "specialization.miss"), + ): total = 0 counts = [] - for i, opcode_stat in enumerate(opcode_stats): + for name, opcode_stat in opcode_stats.items(): # Avoid double counting misses if title == "Misses" and "specializable" in opcode_stat: continue value = opcode_stat.get(field, 0) - counts.append((value, opname[i])) + counts.append((value, name)) total += value counts.sort(reverse=True) if total: with Section(f"{title} by instruction", 3): - rows = [ (name, count, format_ratio(count, total)) for (count, name) in counts[:10] ] + rows = [ + (name, count, format_ratio(count, total)) + for (count, name) in counts[:10] + ] emit_table(("Name", "Count:", "Ratio:"), rows) -def emit_comparative_specialization_overview(base_opcode_stats, base_total, head_opcode_stats, head_total): + +def emit_comparative_specialization_overview( + base_opcode_stats, + base_total, + head_opcode_stats, + head_total, + specialized_instructions, +): with Section("Specialization effectiveness"): - base_rows = calculate_specialization_effectiveness(base_opcode_stats, base_total) - head_rows = calculate_specialization_effectiveness(head_opcode_stats, head_total) + base_rows = calculate_specialization_effectiveness( + base_opcode_stats, base_total, specialized_instructions + ) + head_rows = calculate_specialization_effectiveness( + head_opcode_stats, head_total, specialized_instructions + ) emit_table( - ("Instructions", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), - join_rows(base_rows, head_rows) + ( + "Instructions", + "Base Count:", + "Base Ratio:", + "Head Count:", + "Head Ratio:", + ), + join_rows(base_rows, head_rows), ) + def get_stats_defines(): - stats_path = os.path.join(os.path.dirname(__file__), "../../Include/pystats.h") + stats_path = os.path.join( + os.path.dirname(__file__), "../../Include/cpython/pystats.h" + ) with open(stats_path) as stats_src: defines = parse_kinds(stats_src, prefix="EVAL_CALL") return defines -def calculate_call_stats(stats): - defines = get_stats_defines() + +def calculate_call_stats(stats, defines): total = 0 for key, value in stats.items(): if "Calls to" in key: @@ -447,7 +569,7 @@ def calculate_call_stats(stats): rows.append((key, value, format_ratio(value, total))) elif key.startswith("Calls "): name, index = key[:-1].split("[") - index = int(index) + index = int(index) label = name + " (" + pretty(defines[index][0]) + ")" rows.append((label, value, format_ratio(value, total))) for key, value in stats.items(): @@ -455,27 +577,35 @@ def calculate_call_stats(stats): rows.append((key, value, format_ratio(value, total))) return rows -def emit_call_stats(stats): + +def emit_call_stats(stats, defines): with Section("Call stats", summary="Inlined calls and frame stats"): - rows = calculate_call_stats(stats) + rows = calculate_call_stats(stats, defines) emit_table(("", "Count:", "Ratio:"), rows) -def emit_comparative_call_stats(base_stats, head_stats): + +def emit_comparative_call_stats(base_stats, head_stats, defines): with Section("Call stats", summary="Inlined calls and frame stats"): - base_rows = calculate_call_stats(base_stats) - head_rows = calculate_call_stats(head_stats) + base_rows = calculate_call_stats(base_stats, defines) + head_rows = calculate_call_stats(head_stats, defines) rows = join_rows(base_rows, head_rows) - rows.sort(key=lambda x: -float(x[-1][:-1])) + rows.sort(key=lambda x: -percentage_to_float(x[-1])) emit_table( - ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), - rows + ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows ) + def calculate_object_stats(stats): total_materializations = stats.get("Object new values") - total_allocations = stats.get("Object allocations") + stats.get("Object allocations from freelist") - total_increfs = stats.get("Object interpreter increfs") + stats.get("Object increfs") - total_decrefs = stats.get("Object interpreter decrefs") + stats.get("Object decrefs") + total_allocations = stats.get("Object allocations") + stats.get( + "Object allocations from freelist" + ) + total_increfs = stats.get("Object interpreter increfs") + stats.get( + "Object increfs" + ) + total_decrefs = stats.get("Object interpreter decrefs") + stats.get( + "Object decrefs" + ) rows = [] for key, value in stats.items(): if key.startswith("Object"): @@ -483,9 +613,9 @@ def calculate_object_stats(stats): ratio = format_ratio(value, total_materializations) elif "allocations" in key: ratio = format_ratio(value, total_allocations) - elif "increfs" in key: + elif "increfs" in key: ratio = format_ratio(value, total_increfs) - elif "decrefs" in key: + elif "decrefs" in key: ratio = format_ratio(value, total_decrefs) else: ratio = "" @@ -494,47 +624,103 @@ def calculate_object_stats(stats): rows.append((label, value, ratio)) return rows + +def calculate_gc_stats(stats): + gc_stats = [] + for key, value in stats.items(): + if not key.startswith("GC"): + continue + n, _, rest = key[3:].partition("]") + name = rest.strip() + gen_n = int(n) + while len(gc_stats) <= gen_n: + gc_stats.append({}) + gc_stats[gen_n][name] = value + return [ + (i, gen["collections"], gen["objects collected"], gen["object visits"]) + for (i, gen) in enumerate(gc_stats) + ] + + def emit_object_stats(stats): with Section("Object stats", summary="allocations, frees and dict materializatons"): rows = calculate_object_stats(stats) - emit_table(("", "Count:", "Ratio:"), rows) + emit_table(("", "Count:", "Ratio:"), rows) + def emit_comparative_object_stats(base_stats, head_stats): with Section("Object stats", summary="allocations, frees and dict materializatons"): base_rows = calculate_object_stats(base_stats) head_rows = calculate_object_stats(head_stats) - emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), join_rows(base_rows, head_rows)) + emit_table( + ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), + join_rows(base_rows, head_rows), + ) + + +def emit_gc_stats(stats): + with Section("GC stats", summary="GC collections and effectiveness"): + rows = calculate_gc_stats(stats) + emit_table( + ("Generation:", "Collections:", "Objects collected:", "Object visits:"), + rows, + ) + + +def emit_comparative_gc_stats(base_stats, head_stats): + with Section("GC stats", summary="GC collections and effectiveness"): + base_rows = calculate_gc_stats(base_stats) + head_rows = calculate_gc_stats(head_stats) + emit_table( + ( + "Generation:", + "Base collections:", + "Head collections:", + "Base objects collected:", + "Head objects collected:", + "Base object visits:", + "Head object visits:", + ), + join_rows(base_rows, head_rows), + ) + def get_total(opcode_stats): total = 0 - for opcode_stat in opcode_stats: + for opcode_stat in opcode_stats.values(): if "execution_count" in opcode_stat: - total += opcode_stat['execution_count'] + total += opcode_stat["execution_count"] return total + def emit_pair_counts(opcode_stats, total): pair_counts = [] - for i, opcode_stat in enumerate(opcode_stats): - if i == 0: - continue + for name_i, opcode_stat in opcode_stats.items(): for key, value in opcode_stat.items(): if key.startswith("pair_count"): - x, _, _ = key[11:].partition("]") + name_j, _, _ = key[11:].partition("]") if value: - pair_counts.append((value, (i, int(x)))) + pair_counts.append((value, (name_i, name_j))) with Section("Pair counts", summary="Pair counts for top 100 pairs"): pair_counts.sort(reverse=True) cumulative = 0 rows = [] - for (count, pair) in itertools.islice(pair_counts, 100): - i, j = pair + for count, pair in itertools.islice(pair_counts, 100): + name_i, name_j = pair cumulative += count - rows.append((opname[i] + " " + opname[j], count, format_ratio(count, total), - format_ratio(cumulative, total))) - emit_table(("Pair", "Count:", "Self:", "Cumulative:"), - rows - ) - with Section("Predecessor/Successor Pairs", summary="Top 5 predecessors and successors of each opcode"): + rows.append( + ( + f"{name_i} {name_j}", + count, + format_ratio(count, total), + format_ratio(cumulative, total), + ) + ) + emit_table(("Pair", "Count:", "Self:", "Cumulative:"), rows) + with Section( + "Predecessor/Successor Pairs", + summary="Top 5 predecessors and successors of each opcode", + ): predecessors = collections.defaultdict(collections.Counter) successors = collections.defaultdict(collections.Counter) total_predecessors = collections.Counter() @@ -545,57 +731,164 @@ def emit_pair_counts(opcode_stats, total): successors[first][second] = count total_predecessors[second] += count total_successors[first] += count - for name, i in opmap.items(): - total1 = total_predecessors[i] - total2 = total_successors[i] + for name in opcode_stats.keys(): + total1 = total_predecessors[name] + total2 = total_successors[name] if total1 == 0 and total2 == 0: continue pred_rows = succ_rows = () if total1: - pred_rows = [(opname[pred], count, f"{count/total1:.1%}") - for (pred, count) in predecessors[i].most_common(5)] + pred_rows = [ + (pred, count, f"{count/total1:.1%}") + for (pred, count) in predecessors[name].most_common(5) + ] if total2: - succ_rows = [(opname[succ], count, f"{count/total2:.1%}") - for (succ, count) in successors[i].most_common(5)] + succ_rows = [ + (succ, count, f"{count/total2:.1%}") + for (succ, count) in successors[name].most_common(5) + ] with Section(name, 3, f"Successors and predecessors for {name}"): - emit_table(("Predecessors", "Count:", "Percentage:"), - pred_rows - ) - emit_table(("Successors", "Count:", "Percentage:"), - succ_rows - ) + emit_table(("Predecessors", "Count:", "Percentage:"), pred_rows) + emit_table(("Successors", "Count:", "Percentage:"), succ_rows) + + +def calculate_optimization_stats(stats): + attempts = stats["Optimization attempts"] + created = stats["Optimization traces created"] + executed = stats["Optimization traces executed"] + uops = stats["Optimization uops executed"] + trace_stack_overflow = stats["Optimization trace stack overflow"] + trace_stack_underflow = stats["Optimization trace stack underflow"] + trace_too_long = stats["Optimization trace too long"] + trace_too_short = stats["Optimiztion trace too short"] + inner_loop = stats["Optimization inner loop"] + recursive_call = stats["Optimization recursive call"] + + return [ + ("Optimization attempts", attempts, ""), + ("Traces created", created, format_ratio(created, attempts)), + ("Traces executed", executed, ""), + ("Uops executed", uops, int(uops / (executed or 1))), + ("Trace stack overflow", trace_stack_overflow, ""), + ("Trace stack underflow", trace_stack_underflow, ""), + ("Trace too long", trace_too_long, ""), + ("Trace too short", trace_too_short, ""), + ("Inner loop found", inner_loop, ""), + ("Recursive call", recursive_call, ""), + ] + + +def calculate_uop_execution_counts(opcode_stats): + total = 0 + counts = [] + for name, opcode_stat in opcode_stats.items(): + if "execution_count" in opcode_stat: + count = opcode_stat["execution_count"] + counts.append((count, name)) + total += count + counts.sort(reverse=True) + cumulative = 0 + rows = [] + for count, name in counts: + cumulative += count + rows.append( + (name, count, format_ratio(count, total), format_ratio(cumulative, total)) + ) + return rows + + +def emit_optimization_stats(stats): + if "Optimization attempts" not in stats: + return + + uop_stats = extract_opcode_stats(stats, "uops") + + with Section( + "Optimization (Tier 2) stats", summary="statistics about the Tier 2 optimizer" + ): + with Section("Overall stats", level=3): + rows = calculate_optimization_stats(stats) + emit_table(("", "Count:", "Ratio:"), rows) + + emit_histogram( + "Trace length histogram", + stats, + "Trace length", + stats["Optimization traces created"], + ) + emit_histogram( + "Optimized trace length histogram", + stats, + "Optimized trace length", + stats["Optimization traces created"], + ) + emit_histogram( + "Trace run length histogram", + stats, + "Trace run length", + stats["Optimization traces executed"], + ) + + with Section("Uop stats", level=3): + rows = calculate_uop_execution_counts(uop_stats) + emit_table(("Uop", "Count:", "Self:", "Cumulative:"), rows) + + with Section("Unsupported opcodes", level=3): + unsupported_opcodes = extract_opcode_stats(stats, "unsupported_opcode") + data = [] + for opcode, entry in unsupported_opcodes.items(): + data.append((entry["count"], opcode)) + data.sort(reverse=True) + rows = [(x[1], x[0]) for x in data] + emit_table(("Opcode", "Count"), rows) + + +def emit_comparative_optimization_stats(base_stats, head_stats): + print("## Comparative optimization stats not implemented\n\n") + def output_single_stats(stats): - opcode_stats = extract_opcode_stats(stats) + opcode_stats = extract_opcode_stats(stats, "opcode") total = get_total(opcode_stats) emit_execution_counts(opcode_stats, total) emit_pair_counts(opcode_stats, total) - emit_specialization_stats(opcode_stats) - emit_specialization_overview(opcode_stats, total) - emit_call_stats(stats) + emit_specialization_stats(opcode_stats, stats["_defines"]) + emit_specialization_overview( + opcode_stats, total, stats["_specialized_instructions"] + ) + emit_call_stats(stats, stats["_stats_defines"]) emit_object_stats(stats) + emit_gc_stats(stats) + emit_optimization_stats(stats) with Section("Meta stats", summary="Meta statistics"): - emit_table(("", "Count:"), [('Number of data files', stats['__nfiles__'])]) + emit_table(("", "Count:"), [("Number of data files", stats["__nfiles__"])]) def output_comparative_stats(base_stats, head_stats): - base_opcode_stats = extract_opcode_stats(base_stats) + base_opcode_stats = extract_opcode_stats(base_stats, "opcode") base_total = get_total(base_opcode_stats) - head_opcode_stats = extract_opcode_stats(head_stats) + head_opcode_stats = extract_opcode_stats(head_stats, "opcode") head_total = get_total(head_opcode_stats) emit_comparative_execution_counts( base_opcode_stats, base_total, head_opcode_stats, head_total ) emit_comparative_specialization_stats( - base_opcode_stats, head_opcode_stats + base_opcode_stats, head_opcode_stats, head_stats["_defines"] ) emit_comparative_specialization_overview( - base_opcode_stats, base_total, head_opcode_stats, head_total + base_opcode_stats, + base_total, + head_opcode_stats, + head_total, + head_stats["_specialized_instructions"], ) - emit_comparative_call_stats(base_stats, head_stats) + emit_comparative_call_stats(base_stats, head_stats, head_stats["_stats_defines"]) emit_comparative_object_stats(base_stats, head_stats) + emit_comparative_gc_stats(base_stats, head_stats) + emit_comparative_optimization_stats(base_stats, head_stats) + def output_stats(inputs, json_output=None): if len(inputs) == 1: @@ -605,9 +898,7 @@ def output_stats(inputs, json_output=None): output_single_stats(stats) elif len(inputs) == 2: if json_output is not None: - raise ValueError( - "Can not output to JSON when there are multiple inputs" - ) + raise ValueError("Can not output to JSON when there are multiple inputs") base_stats = gather_stats(inputs[0]) head_stats = gather_stats(inputs[1]) @@ -616,6 +907,7 @@ def output_stats(inputs, json_output=None): print("---") print("Stats gathered on:", date.today()) + def main(): parser = argparse.ArgumentParser(description="Summarize pystats results") @@ -631,14 +923,14 @@ def main(): If one source is provided, its stats are printed. If two sources are provided, comparative stats are printed. Default is {DEFAULT_DIR}. - """ + """, ) parser.add_argument( "--json-output", nargs="?", type=argparse.FileType("w"), - help="Output complete raw results to the given JSON file." + help="Output complete raw results to the given JSON file.", ) args = parser.parse_args() @@ -648,5 +940,6 @@ def main(): output_stats(args.inputs, json_output=args.json_output) + if __name__ == "__main__": main() diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index f9809c9b54665b..120e3883adc795 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -46,9 +46,9 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1u", - "3.0.9", - "3.1.1", + "1.1.1w", + "3.0.11", + "3.1.3", ] LIBRESSL_OLD_VERSIONS = [ @@ -151,7 +151,10 @@ class AbstractBuilder(object): build_template = None depend_target = None install_target = 'install' - jobs = os.cpu_count() + if hasattr(os, 'process_cpu_count'): + jobs = os.process_cpu_count() + else: + jobs = os.cpu_count() module_files = ( os.path.join(PYTHONROOT, "Modules/_ssl.c"), diff --git a/Tools/unicode/genmap_japanese.py b/Tools/unicode/genmap_japanese.py index 21de37b62bced0..838317fa54175e 100644 --- a/Tools/unicode/genmap_japanese.py +++ b/Tools/unicode/genmap_japanese.py @@ -2,7 +2,7 @@ # genmap_ja_codecs.py: Japanese Codecs Map Generator # # Original Author: Hye-Shik Chang -# Modified Author: Dong-hee Na +# Modified Author: Donghee Na # import os diff --git a/Tools/unicode/genmap_korean.py b/Tools/unicode/genmap_korean.py index 4b94a6c43e5382..4432a3601b7e3b 100644 --- a/Tools/unicode/genmap_korean.py +++ b/Tools/unicode/genmap_korean.py @@ -2,7 +2,7 @@ # genmap_korean.py: Korean Codecs Map Generator # # Original Author: Hye-Shik Chang -# Modified Author: Dong-hee Na +# Modified Author: Donghee Na # import os diff --git a/Tools/unicode/genmap_schinese.py b/Tools/unicode/genmap_schinese.py index 647c0333ed2728..862f1def71d122 100644 --- a/Tools/unicode/genmap_schinese.py +++ b/Tools/unicode/genmap_schinese.py @@ -2,7 +2,7 @@ # genmap_schinese.py: Simplified Chinese Codecs Map Generator # # Original Author: Hye-Shik Chang -# Modified Author: Dong-hee Na +# Modified Author: Donghee Na # import os import re diff --git a/Tools/unicode/genmap_support.py b/Tools/unicode/genmap_support.py index 5e1d9ee77b0002..4649bc3b7125fe 100644 --- a/Tools/unicode/genmap_support.py +++ b/Tools/unicode/genmap_support.py @@ -2,7 +2,7 @@ # genmap_support.py: Multibyte Codec Map Generator # # Original Author: Hye-Shik Chang -# Modified Author: Dong-hee Na +# Modified Author: Donghee Na # diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 034642db06e48b..6bf5274551c00a 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -44,7 +44,7 @@ # * Doc/library/stdtypes.rst, and # * Doc/library/unicodedata.rst # * Doc/reference/lexical_analysis.rst (two occurrences) -UNIDATA_VERSION = "15.0.0" +UNIDATA_VERSION = "15.1.0" UNICODE_DATA = "UnicodeData%s.txt" COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt" EASTASIAN_WIDTH = "EastAsianWidth%s.txt" @@ -101,15 +101,16 @@ # these ranges need to match unicodedata.c:is_unified_ideograph cjk_ranges = [ - ('3400', '4DBF'), - ('4E00', '9FFF'), - ('20000', '2A6DF'), - ('2A700', '2B739'), - ('2B740', '2B81D'), - ('2B820', '2CEA1'), - ('2CEB0', '2EBE0'), - ('30000', '3134A'), - ('31350', '323AF'), + ('3400', '4DBF'), # CJK Ideograph Extension A CJK + ('4E00', '9FFF'), # CJK Ideograph + ('20000', '2A6DF'), # CJK Ideograph Extension B + ('2A700', '2B739'), # CJK Ideograph Extension C + ('2B740', '2B81D'), # CJK Ideograph Extension D + ('2B820', '2CEA1'), # CJK Ideograph Extension E + ('2CEB0', '2EBE0'), # CJK Ideograph Extension F + ('2EBF0', '2EE5D'), # CJK Ideograph Extension I + ('30000', '3134A'), # CJK Ideograph Extension G + ('31350', '323AF'), # CJK Ideograph Extension H ] @@ -1105,11 +1106,15 @@ def __init__(self, version, cjk_check=True): table[i].east_asian_width = widths[i] self.widths = widths - for char, (p,) in UcdFile(DERIVED_CORE_PROPERTIES, version).expanded(): + for char, (propname, *propinfo) in UcdFile(DERIVED_CORE_PROPERTIES, version).expanded(): + if propinfo: + # this is not a binary property, ignore it + continue + if table[char]: # Some properties (e.g. Default_Ignorable_Code_Point) # apply to unassigned code points; ignore them - table[char].binary_properties.add(p) + table[char].binary_properties.add(propname) for char_range, value in UcdFile(LINE_BREAK, version): if value not in MANDATORY_LINE_BREAKS: diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index cd749dee8920c6..8ef63c6dcd9ddc 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -79,7 +79,7 @@ PIC. To populate the build cache, run: ```shell . /opt/emsdk/emsdk_env.sh embuilder build zlib bzip2 MINIMAL_PIC -embuilder build --pic zlib bzip2 MINIMAL_PIC +embuilder --pic build zlib bzip2 MINIMAL_PIC ``` @@ -141,7 +141,7 @@ and header files with debug builds. #### Cross compile to wasm32-emscripten for node ```shell -./Tools/wasm/wasm_build.py emscripten-browser-dl +./Tools/wasm/wasm_build.py emscripten-node-dl ``` The command is roughly equivalent to: diff --git a/Tools/wasm/mypy.ini b/Tools/wasm/mypy.ini new file mode 100644 index 00000000000000..c62598f89eba69 --- /dev/null +++ b/Tools/wasm/mypy.ini @@ -0,0 +1,14 @@ +[mypy] +files = Tools/wasm +pretty = True +show_traceback = True + +# Make sure the wasm can be run using Python 3.8: +python_version = 3.8 + +# Be strict... +strict = True +enable_error_code = truthy-bool,ignore-without-code + +# except for incomplete defs, which are useful for module authors: +disallow_incomplete_defs = False diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py index f1c8e0bf007f4c..ffa5e303412c46 100755 --- a/Tools/wasm/wasm_assets.py +++ b/Tools/wasm/wasm_assets.py @@ -16,6 +16,7 @@ import sys import sysconfig import zipfile +from typing import Dict # source directory SRCDIR = pathlib.Path(__file__).parent.parent.parent.absolute() @@ -110,7 +111,8 @@ def get_builddir(args: argparse.Namespace) -> pathlib.Path: def get_sysconfigdata(args: argparse.Namespace) -> pathlib.Path: """Get path to sysconfigdata relative to build root""" - data_name = sysconfig._get_sysconfigdata_name() + assert isinstance(args.builddir, pathlib.Path) + data_name: str = sysconfig._get_sysconfigdata_name() # type: ignore[attr-defined] if not data_name.startswith(SYSCONFIG_NAMES): raise ValueError( f"Invalid sysconfig data name '{data_name}'.", SYSCONFIG_NAMES @@ -146,7 +148,7 @@ def filterfunc(filename: str) -> bool: pzf.writepy(entry, filterfunc=filterfunc) -def detect_extension_modules(args: argparse.Namespace): +def detect_extension_modules(args: argparse.Namespace) -> Dict[str, bool]: modules = {} # disabled by Modules/Setup.local ? @@ -161,7 +163,7 @@ def detect_extension_modules(args: argparse.Namespace): # disabled by configure? with open(args.sysconfig_data) as f: data = f.read() - loc = {} + loc: Dict[str, Dict[str, str]] = {} exec(data, globals(), loc) for key, value in loc["build_time_vars"].items(): @@ -195,7 +197,7 @@ def path(val: str) -> pathlib.Path: ) -def main(): +def main() -> None: args = parser.parse_args() relative_prefix = args.prefix.relative_to(pathlib.Path("/")) diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py index c9947057a90754..c0b9999a5dad03 100755 --- a/Tools/wasm/wasm_build.py +++ b/Tools/wasm/wasm_build.py @@ -40,7 +40,17 @@ import webbrowser # for Python 3.8 -from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union +from typing import ( + cast, + Any, + Callable, + Dict, + Iterable, + List, + Optional, + Tuple, + Union, +) logger = logging.getLogger("wasm_build") @@ -64,7 +74,7 @@ (3, 1, 16): "https://github.com/emscripten-core/emscripten/issues/17393", (3, 1, 20): "https://github.com/emscripten-core/emscripten/issues/17720", } -_MISSING = pathlib.PurePath("MISSING") +_MISSING = pathlib.Path("MISSING") WASM_WEBSERVER = WASMTOOLS / "wasm_webserver.py" @@ -109,7 +119,7 @@ def parse_emconfig( emconfig: pathlib.Path = EM_CONFIG, -) -> Tuple[pathlib.PurePath, pathlib.PurePath]: +) -> Tuple[pathlib.Path, pathlib.Path]: """Parse EM_CONFIG file and lookup EMSCRIPTEN_ROOT and NODE_JS. The ".emscripten" config file is a Python snippet that uses "EM_CONFIG" @@ -150,11 +160,11 @@ def read_python_version(configure: pathlib.Path = CONFIGURE) -> str: class ConditionError(ValueError): - def __init__(self, info: str, text: str): + def __init__(self, info: str, text: str) -> None: self.info = info self.text = text - def __str__(self): + def __str__(self) -> str: return f"{type(self).__name__}: '{self.info}'\n{self.text}" @@ -180,19 +190,19 @@ class Platform: name: str pythonexe: str config_site: Optional[pathlib.PurePath] - configure_wrapper: Optional[pathlib.PurePath] + configure_wrapper: Optional[pathlib.Path] make_wrapper: Optional[pathlib.PurePath] - environ: dict + environ: Dict[str, Any] check: Callable[[], None] # Used for build_emports(). ports: Optional[pathlib.PurePath] cc: Optional[pathlib.PurePath] - def getenv(self, profile: "BuildProfile") -> dict: + def getenv(self, profile: "BuildProfile") -> Dict[str, Any]: return self.environ.copy() -def _check_clean_src(): +def _check_clean_src() -> None: candidates = [ SRCDIR / "Programs" / "python.o", SRCDIR / "Python" / "frozen_modules" / "importlib._bootstrap.h", @@ -202,7 +212,7 @@ def _check_clean_src(): raise DirtySourceDirectory(os.fspath(candidate), CLEAN_SRCDIR) -def _check_native(): +def _check_native() -> None: if not any(shutil.which(cc) for cc in ["cc", "gcc", "clang"]): raise MissingDependency("cc", INSTALL_NATIVE) if not shutil.which("make"): @@ -234,12 +244,12 @@ def _check_native(): ) -def _check_emscripten(): +def _check_emscripten() -> None: if EMSCRIPTEN_ROOT is _MISSING: raise MissingDependency("Emscripten SDK EM_CONFIG", INSTALL_EMSDK) # sanity check emconfigure = EMSCRIPTEN.configure_wrapper - if not emconfigure.exists(): + if emconfigure is not None and not emconfigure.exists(): raise MissingDependency(os.fspath(emconfigure), INSTALL_EMSDK) # version check version_txt = EMSCRIPTEN_ROOT / "emscripten-version.txt" @@ -250,7 +260,10 @@ def _check_emscripten(): if version.endswith("-git"): # git / upstream / tot-upstream installation version = version[:-4] - version_tuple = tuple(int(v) for v in version.split(".")) + version_tuple = cast( + Tuple[int, int, int], + tuple(int(v) for v in version.split(".")) + ) if version_tuple < EMSDK_MIN_VERSION: raise ConditionError( os.fspath(version_txt), @@ -293,7 +306,7 @@ def _check_emscripten(): ) -def _check_wasi(): +def _check_wasi() -> None: wasm_ld = WASI_SDK_PATH / "bin" / "wasm-ld" if not wasm_ld.exists(): raise MissingDependency(os.fspath(wasm_ld), INSTALL_WASI_SDK) @@ -400,7 +413,7 @@ class EmscriptenTarget(enum.Enum): node_debug = "node-debug" @property - def is_browser(self): + def is_browser(self) -> bool: cls = type(self) return self in {cls.browser, cls.browser_debug} @@ -421,7 +434,7 @@ class SupportLevel(enum.Enum): experimental = "experimental, may be broken" broken = "broken / unavailable" - def __bool__(self): + def __bool__(self) -> bool: cls = type(self) return self in {cls.supported, cls.working} @@ -500,10 +513,14 @@ def make_cmd(self) -> List[str]: cmd.insert(0, os.fspath(platform.make_wrapper)) return cmd - def getenv(self) -> dict: + def getenv(self) -> Dict[str, Any]: """Generate environ dict for platform""" env = os.environ.copy() - env.setdefault("MAKEFLAGS", f"-j{os.cpu_count()}") + if hasattr(os, 'process_cpu_count'): + cpu_count = os.process_cpu_count() + else: + cpu_count = os.cpu_count() + env.setdefault("MAKEFLAGS", f"-j{cpu_count}") platenv = self.host.platform.getenv(self) for key, value in platenv.items(): if value is None: @@ -529,7 +546,7 @@ def _run_cmd( cmd: Iterable[str], args: Iterable[str] = (), cwd: Optional[pathlib.Path] = None, - ): + ) -> int: cmd = list(cmd) cmd.extend(args) if cwd is None: @@ -541,46 +558,46 @@ def _run_cmd( env=self.getenv(), ) - def _check_execute(self): + def _check_execute(self) -> None: if self.is_browser: raise ValueError(f"Cannot execute on {self.target}") - def run_build(self, *args): + def run_build(self, *args: str) -> None: """Run configure (if necessary) and make""" if not self.makefile.exists(): logger.info("Makefile not found, running configure") self.run_configure(*args) self.run_make("all", *args) - def run_configure(self, *args): + def run_configure(self, *args: str) -> int: """Run configure script to generate Makefile""" os.makedirs(self.builddir, exist_ok=True) return self._run_cmd(self.configure_cmd, args) - def run_make(self, *args): + def run_make(self, *args: str) -> int: """Run make (defaults to build all)""" return self._run_cmd(self.make_cmd, args) - def run_pythoninfo(self, *args): + def run_pythoninfo(self, *args: str) -> int: """Run 'make pythoninfo'""" self._check_execute() return self.run_make("pythoninfo", *args) - def run_test(self, target: str, testopts: Optional[str] = None): + def run_test(self, target: str, testopts: Optional[str] = None) -> int: """Run buildbottests""" self._check_execute() if testopts is None: testopts = self.default_testopts return self.run_make(target, f"TESTOPTS={testopts}") - def run_py(self, *args): + def run_py(self, *args: str) -> int: """Run Python with hostrunner""" self._check_execute() - self.run_make( + return self.run_make( "--eval", f"run: all; $(HOSTRUNNER) ./$(PYTHON) {shlex.join(args)}", "run" ) - def run_browser(self, bind="127.0.0.1", port=8000): + def run_browser(self, bind: str = "127.0.0.1", port: int = 8000) -> None: """Run WASM webserver and open build in browser""" relbuilddir = self.builddir.relative_to(SRCDIR) url = f"http://{bind}:{port}/{relbuilddir}/python.html" @@ -611,7 +628,7 @@ def run_browser(self, bind="127.0.0.1", port=8000): except KeyboardInterrupt: pass - def clean(self, all: bool = False): + def clean(self, all: bool = False) -> None: """Clean build directory""" if all: if self.builddir.exists(): @@ -619,7 +636,7 @@ def clean(self, all: bool = False): elif self.makefile.exists(): self.run_make("clean") - def build_emports(self, force: bool = False): + def build_emports(self, force: bool = False) -> None: """Pre-build emscripten ports.""" platform = self.host.platform if platform.ports is None or platform.cc is None: @@ -829,7 +846,7 @@ def build_emports(self, force: bool = False): ) -def main(): +def main() -> None: args = parser.parse_args() logging.basicConfig( level=logging.INFO if args.verbose else logging.ERROR, diff --git a/Tools/wasm/wasm_webserver.py b/Tools/wasm/wasm_webserver.py index 186bd57fc2067d..3d1d5d42a1e8c4 100755 --- a/Tools/wasm/wasm_webserver.py +++ b/Tools/wasm/wasm_webserver.py @@ -21,21 +21,21 @@ class MyHTTPRequestHandler(server.SimpleHTTPRequestHandler): } ) - def end_headers(self): + def end_headers(self) -> None: self.send_my_headers() super().end_headers() - def send_my_headers(self): + def send_my_headers(self) -> None: self.send_header("Cross-Origin-Opener-Policy", "same-origin") self.send_header("Cross-Origin-Embedder-Policy", "require-corp") -def main(): +def main() -> None: args = parser.parse_args() if not args.bind: args.bind = None - server.test( + server.test( # type: ignore[attr-defined] HandlerClass=MyHTTPRequestHandler, protocol="HTTP/1.1", port=args.port, diff --git a/configure b/configure index e6fb5e3c2b0c2f..c87f518382f2ec 100755 --- a/configure +++ b/configure @@ -669,6 +669,8 @@ MODULE__TESTBUFFER_FALSE MODULE__TESTBUFFER_TRUE MODULE__TESTINTERNALCAPI_FALSE MODULE__TESTINTERNALCAPI_TRUE +MODULE__TESTCLINIC_LIMITED_FALSE +MODULE__TESTCLINIC_LIMITED_TRUE MODULE__TESTCLINIC_FALSE MODULE__TESTCLINIC_TRUE MODULE__TESTCAPI_FALSE @@ -1063,6 +1065,7 @@ with_suffix enable_shared with_static_libpython enable_profiling +enable_gil with_pydebug with_trace_refs enable_pystats @@ -1789,6 +1792,8 @@ Optional Features: no) --enable-profiling enable C-level code profiling with gprof (default is no) + --disable-gil enable experimental support for running without the + GIL (default is no) --enable-pystats enable internal statistics gathering (default is no) --enable-optimizations enable expensive, stable optimizations (PGO, etc.) (default is no) @@ -4279,6 +4284,15 @@ then darwin*) MACHDEP="darwin";; '') MACHDEP="unknown";; esac + + if test "$ac_sys_system" = "SunOS"; then + # For Solaris, there isn't an OS version specific macro defined + # in most compilers, so we define one here. + SUNOS_VERSION=`echo $ac_sys_release | sed -e 's!\.\(0-9\)$!.0\1!g' | tr -d '.'` + +printf "%s\n" "#define Py_SUNOS_VERSION $SUNOS_VERSION" >>confdefs.h + + fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$MACHDEP\"" >&5 printf "%s\n" "\"$MACHDEP\"" >&6; } @@ -6716,200 +6730,16 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 printf %s "checking for the platform triplet based on compiler characteristics... " >&6; } -cat > conftest.c <=6) && defined(_MIPSEL) -# if _MIPS_SIM == _ABIO32 - mipsisa32r6el-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mipsisa64r6el-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mipsisa64r6el-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__mips_hard_float) && defined(__mips_isa_rev) && (__mips_isa_rev >=6) -# if _MIPS_SIM == _ABIO32 - mipsisa32r6-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mipsisa64r6-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mipsisa64r6-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__mips_hard_float) && defined(_MIPSEL) -# if _MIPS_SIM == _ABIO32 - mipsel-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mips64el-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mips64el-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__mips_hard_float) -# if _MIPS_SIM == _ABIO32 - mips-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mips64-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mips64-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__or1k__) - or1k-linux-gnu -# elif defined(__powerpc__) && defined(__SPE__) - powerpc-linux-gnuspe -# elif defined(__powerpc64__) -# if defined(__LITTLE_ENDIAN__) - powerpc64le-linux-gnu -# else - powerpc64-linux-gnu -# endif -# elif defined(__powerpc__) - powerpc-linux-gnu -# elif defined(__s390x__) - s390x-linux-gnu -# elif defined(__s390__) - s390-linux-gnu -# elif defined(__sh__) && defined(__LITTLE_ENDIAN__) - sh4-linux-gnu -# elif defined(__sparc__) && defined(__arch64__) - sparc64-linux-gnu -# elif defined(__sparc__) - sparc-linux-gnu -# elif defined(__riscv) -# if __riscv_xlen == 32 - riscv32-linux-gnu -# elif __riscv_xlen == 64 - riscv64-linux-gnu -# else -# error unknown platform triplet -# endif -# else -# error unknown platform triplet -# endif -#elif defined(__FreeBSD_kernel__) -# if defined(__LP64__) - x86_64-kfreebsd-gnu -# elif defined(__i386__) - i386-kfreebsd-gnu -# else -# error unknown platform triplet -# endif -#elif defined(__gnu_hurd__) - i386-gnu -#elif defined(__APPLE__) - darwin -#elif defined(__VXWORKS__) - vxworks -#elif defined(__wasm32__) -# if defined(__EMSCRIPTEN__) - wasm32-emscripten -# elif defined(__wasi__) -# if defined(_REENTRANT) - wasm32-wasi-threads -# else - wasm32-wasi -# endif -# else -# error unknown wasm32 platform -# endif -#elif defined(__wasm64__) -# if defined(__EMSCRIPTEN__) - wasm64-emscripten -# elif defined(__wasi__) - wasm64-wasi -# else -# error unknown wasm64 platform -# endif -#else -# error unknown platform triplet -#endif - -EOF - -if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then - PLATFORM_TRIPLET=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` - case "$build_os" in - linux-musl*) - PLATFORM_TRIPLET=`echo "$PLATFORM_TRIPLET" | sed 's/linux-gnu/linux-musl/'` - ;; - esac +if $CPP $CPPFLAGS $srcdir/Misc/platform_triplet.c >conftest.out 2>/dev/null; then + PLATFORM_TRIPLET=`grep '^PLATFORM_TRIPLET=' conftest.out | tr -d ' '` + PLATFORM_TRIPLET="${PLATFORM_TRIPLET#PLATFORM_TRIPLET=}" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PLATFORM_TRIPLET" >&5 printf "%s\n" "$PLATFORM_TRIPLET" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi -rm -f conftest.c conftest.out +rm -f conftest.out { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for multiarch" >&5 printf %s "checking for multiarch... " >&6; } @@ -8024,6 +7854,36 @@ fi ABIFLAGS="" +# Check for --disable-gil +# --disable-gil +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --disable-gil" >&5 +printf %s "checking for --disable-gil... " >&6; } +# Check whether --enable-gil was given. +if test ${enable_gil+y} +then : + enableval=$enable_gil; if test "x$enable_gil" = xyes +then : + disable_gil=no +else $as_nop + disable_gil=yes +fi +else $as_nop + disable_gil=no + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $disable_gil" >&5 +printf "%s\n" "$disable_gil" >&6; } + +if test "$disable_gil" = "yes" +then + +printf "%s\n" "#define Py_NOGIL 1" >>confdefs.h + + # Add "t" for "threaded" + ABIFLAGS="${ABIFLAGS}t" +fi + # Check for --with-pydebug { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-pydebug" >&5 printf %s "checking for --with-pydebug... " >&6; } @@ -8743,7 +8603,10 @@ printf "%s\n" "$as_me: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&6;} fi fi LLVM_PROF_ERR=no -case $CC in + +# GNU Autoconf recommends the use of expr instead of basename. +CC_BASENAME=$(expr "//$CC" : '.*/\(.*\)') +case "$CC_BASENAME" in *clang*) # Any changes made here should be reflected in the GCC+Darwin case below PGO_PROF_GEN_FLAG="-fprofile-instr-generate" @@ -9572,7 +9435,7 @@ fi # ICC doesn't recognize the option, but only emits a warning ## XXX does it emit an unused result warning and can it be disabled? - case $CC in #( + case "$CC_BASENAME" in #( *icc*) : ac_cv_disable_unused_result_warning=no @@ -10153,7 +10016,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ ;; esac -case "$CC" in +case "$CC_BASENAME" in +*mpicc*) + CFLAGS_NODIST="$CFLAGS_NODIST" + ;; *icc*) # ICC needs -fp-model strict or floats behave badly CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" @@ -10498,12 +10364,6 @@ if test "x$ac_cv_header_grp_h" = xyes then : printf "%s\n" "#define HAVE_GRP_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "ieeefp.h" "ac_cv_header_ieeefp_h" "$ac_includes_default" -if test "x$ac_cv_header_ieeefp_h" = xyes -then : - printf "%s\n" "#define HAVE_IEEEFP_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default" if test "x$ac_cv_header_io_h" = xyes @@ -10546,6 +10406,12 @@ if test "x$ac_cv_header_linux_fs_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_FS_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "linux/limits.h" "ac_cv_header_linux_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_limits_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_LIMITS_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "linux/memfd.h" "ac_cv_header_linux_memfd_h" "$ac_includes_default" if test "x$ac_cv_header_linux_memfd_h" = xyes @@ -10852,6 +10718,12 @@ if test "x$ac_cv_header_sys_times_h" = xyes then : printf "%s\n" "#define HAVE_SYS_TIMES_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "sys/timerfd.h" "ac_cv_header_sys_timerfd_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_timerfd_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TIMERFD_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes @@ -11144,6 +11016,7 @@ fi # On Linux, netlink.h requires asm/types.h +# On FreeBSD, netlink.h is located in netlink/netlink.h ac_fn_c_check_header_compile "$LINENO" "linux/netlink.h" "ac_cv_header_linux_netlink_h" " #ifdef HAVE_ASM_TYPES_H #include @@ -11158,6 +11031,20 @@ then : printf "%s\n" "#define HAVE_LINUX_NETLINK_H 1" >>confdefs.h fi +ac_fn_c_check_header_compile "$LINENO" "netlink/netlink.h" "ac_cv_header_netlink_netlink_h" " +#ifdef HAVE_ASM_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +" +if test "x$ac_cv_header_netlink_netlink_h" = xyes +then : + printf "%s\n" "#define HAVE_NETLINK_NETLINK_H 1" >>confdefs.h + +fi # On Linux, qrtr.h requires asm/types.h @@ -17099,8 +16986,8 @@ PLATFORM_OBJS= case $ac_sys_system in #( Emscripten) : - as_fn_append PLATFORM_OBJS ' Python/emscripten_signal.o' - as_fn_append PLATFORM_HEADERS ' $(srcdir)/Include/internal/pycore_emscripten_signal.h' + as_fn_append PLATFORM_OBJS ' Python/emscripten_signal.o Python/emscripten_trampoline.o' + as_fn_append PLATFORM_HEADERS ' $(srcdir)/Include/internal/pycore_emscripten_signal.h $(srcdir)/Include/internal/pycore_emscripten_trampoline.h' ;; #( *) : ;; @@ -18909,6 +18796,50 @@ fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for timerfd_create" >&5 +printf %s "checking for timerfd_create... " >&6; } +if test ${ac_cv_func_timerfd_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_SYS_TIMERFD_H +#include +#endif + +int +main (void) +{ +void *x=timerfd_create + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_timerfd_create=yes +else $as_nop + ac_cv_func_timerfd_create=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_timerfd_create" >&5 +printf "%s\n" "$ac_cv_func_timerfd_create" >&6; } + if test "x$ac_cv_func_timerfd_create" = xyes +then : + +printf "%s\n" "#define HAVE_TIMERFD_CREATE 1" >>confdefs.h + +fi + + + + # On some systems (eg. FreeBSD 5), we would find a definition of the # functions ctermid_r, setgroups in the library, but no prototype # (e.g. because we use _XOPEN_SOURCE). See whether we can take their @@ -23704,6 +23635,7 @@ printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h # # * The Python implementation (always 'cpython-' for us) # * The major and minor version numbers +# * --disable-gil (adds a 't') # * --with-pydebug (adds a 'd') # # Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, @@ -23723,8 +23655,9 @@ SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5 printf "%s\n" "$SOABI" >&6; } -# Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI -if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then +# Release build, debug build (Py_DEBUG), and trace refs build (Py_TRACE_REFS) +# are ABI compatible +if test "$Py_DEBUG" = 'true'; then # Similar to SOABI but remove "d" flag from ABIFLAGS ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} @@ -23907,6 +23840,7 @@ fi + # Check whether --with-readline was given. if test ${with_readline+y} then : @@ -23929,6 +23863,22 @@ else $as_nop fi +# gh-105323: Need to handle the macOS editline as an alias of readline. +case $ac_sys_system/$ac_sys_release in #( + Darwin/*) : + ac_fn_c_check_type "$LINENO" "Function" "ac_cv_type_Function" "#include +" +if test "x$ac_cv_type_Function" = xyes +then : + printf "%s\n" "#define WITH_APPLE_EDITLINE 1" >>confdefs.h + +fi + ;; #( + *) : + + ;; +esac + if test "x$with_readline" = xreadline then : @@ -24727,6 +24677,25 @@ printf "%s\n" "#define HAVE_RL_APPEND_HISTORY 1" >>confdefs.h fi + # in readline as well as newer editline (April 2023) + ac_fn_c_check_type "$LINENO" "rl_compdisp_func_t" "ac_cv_type_rl_compdisp_func_t" " + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + +" +if test "x$ac_cv_type_rl_compdisp_func_t" = xyes +then : + +printf "%s\n" "#define HAVE_RL_COMPDISP_FUNC_T 1" >>confdefs.h + +fi + + CFLAGS=$save_CFLAGS @@ -26704,11 +26673,14 @@ SRCDIRS="\ Modules/_sqlite \ Modules/_sre \ Modules/_testcapi \ + Modules/_testinternalcapi \ Modules/_xxtestfuzz \ Modules/cjkcodecs \ Modules/expat \ Objects \ Parser \ + Parser/tokenizer \ + Parser/lexer \ Programs \ Python \ Python/frozen_modules \ @@ -27880,6 +27852,85 @@ fi printf "%s\n" "$TEST_MODULES" >&6; } +# gh-109054: Check if -latomic is needed to get atomic functions. +# On Linux aarch64, GCC may require programs and libraries to be linked +# explicitly to libatomic. Call _Py_atomic_or_uint64() which may require +# libatomic __atomic_fetch_or_8(), or not, depending on the C compiler and the +# compiler flags. +# +# Avoid #include or #include . The header +# requires header which is only written below by AC_OUTPUT below. +# If the check is done after AC_OUTPUT, modifying LIBS has no effect +# anymore. cannot be included alone, it's designed to be included +# by : it expects other includes and macros to be defined. +save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether libatomic is needed by " >&5 +printf %s "checking whether libatomic is needed by ... " >&6; } +if test ${ac_cv_libatomic_needed+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ac_cv_libatomic_needed=no +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +// pyatomic.h needs uint64_t and Py_ssize_t types +#include // int64_t, intptr_t +#ifdef HAVE_SYS_TYPES_H +# include // ssize_t +#endif +// Code adapted from Include/pyport.h +#if HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef intptr_t Py_ssize_t; +#else +# error "unable to define Py_ssize_t" +#endif + +#include "pyatomic.h" + +int main() +{ + uint64_t byte; + _Py_atomic_store_uint64(&byte, 2); + if (_Py_atomic_or_uint64(&byte, 8) != 2) { + return 1; // error + } + if (_Py_atomic_load_uint64(&byte) != 10) { + return 1; // error + } + return 0; // all good +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_libatomic_needed=no +else $as_nop + ac_cv_libatomic_needed=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libatomic_needed" >&5 +printf "%s\n" "$ac_cv_libatomic_needed" >&6; } + +if test "x$ac_cv_libatomic_needed" = xyes +then : + LIBS="${LIBS} -latomic" +fi +CPPFLAGS=$save_CPPFLAGS + + +# stdlib # stdlib not available @@ -30081,6 +30132,44 @@ fi printf "%s\n" "$py_cv_module__testclinic" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testclinic_limited" >&5 +printf %s "checking for stdlib extension module _testclinic_limited... " >&6; } + if test "$py_cv_module__testclinic_limited" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__testclinic_limited=yes +else $as_nop + py_cv_module__testclinic_limited=missing +fi +else $as_nop + py_cv_module__testclinic_limited=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTCLINIC_LIMITED_STATE=$py_cv_module__testclinic_limited$as_nl" + if test "x$py_cv_module__testclinic_limited" = xyes +then : + + + + +fi + if test "$py_cv_module__testclinic_limited" = yes; then + MODULE__TESTCLINIC_LIMITED_TRUE= + MODULE__TESTCLINIC_LIMITED_FALSE='#' +else + MODULE__TESTCLINIC_LIMITED_TRUE='#' + MODULE__TESTCLINIC_LIMITED_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testclinic_limited" >&5 +printf "%s\n" "$py_cv_module__testclinic_limited" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testinternalcapi" >&5 printf %s "checking for stdlib extension module _testinternalcapi... " >&6; } if test "$py_cv_module__testinternalcapi" != "n/a" @@ -30353,7 +30442,7 @@ printf %s "checking for stdlib extension module xxlimited... " >&6; } if test "$py_cv_module_xxlimited" != "n/a" then : - if test "$with_trace_refs" = "no" + if true then : if test "$ac_cv_func_dlopen" = yes then : @@ -30391,7 +30480,7 @@ printf %s "checking for stdlib extension module xxlimited_35... " >&6; } if test "$py_cv_module_xxlimited_35" != "n/a" then : - if test "$with_trace_refs" = "no" + if true then : if test "$ac_cv_func_dlopen" = yes then : @@ -30434,6 +30523,7 @@ ac_config_files="$ac_config_files Modules/Setup.bootstrap Modules/Setup.stdlib" ac_config_files="$ac_config_files Modules/ld_so_aix" +# Generate files like pyconfig.h cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -30820,6 +30910,10 @@ if test -z "${MODULE__TESTCLINIC_TRUE}" && test -z "${MODULE__TESTCLINIC_FALSE}" as_fn_error $? "conditional \"MODULE__TESTCLINIC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__TESTCLINIC_LIMITED_TRUE}" && test -z "${MODULE__TESTCLINIC_LIMITED_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTCLINIC_LIMITED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__TESTINTERNALCAPI_TRUE}" && test -z "${MODULE__TESTINTERNALCAPI_FALSE}"; then as_fn_error $? "conditional \"MODULE__TESTINTERNALCAPI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/configure.ac b/configure.ac index a1ee78047692fd..cd69f0ede54496 100644 --- a/configure.ac +++ b/configure.ac @@ -590,6 +590,14 @@ then darwin*) MACHDEP="darwin";; '') MACHDEP="unknown";; esac + + if test "$ac_sys_system" = "SunOS"; then + # For Solaris, there isn't an OS version specific macro defined + # in most compilers, so we define one here. + SUNOS_VERSION=`echo $ac_sys_release | sed -e 's!\.\([0-9]\)$!.0\1!g' | tr -d '.'` + AC_DEFINE_UNQUOTED([Py_SUNOS_VERSION], [$SUNOS_VERSION], + [The version of SunOS/Solaris as reported by `uname -r' without the dot.]) + fi fi AC_MSG_RESULT(["$MACHDEP"]) @@ -921,198 +929,14 @@ fi AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) -cat > conftest.c <=6) && defined(_MIPSEL) -# if _MIPS_SIM == _ABIO32 - mipsisa32r6el-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mipsisa64r6el-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mipsisa64r6el-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__mips_hard_float) && defined(__mips_isa_rev) && (__mips_isa_rev >=6) -# if _MIPS_SIM == _ABIO32 - mipsisa32r6-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mipsisa64r6-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mipsisa64r6-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__mips_hard_float) && defined(_MIPSEL) -# if _MIPS_SIM == _ABIO32 - mipsel-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mips64el-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mips64el-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__mips_hard_float) -# if _MIPS_SIM == _ABIO32 - mips-linux-gnu -# elif _MIPS_SIM == _ABIN32 - mips64-linux-gnuabin32 -# elif _MIPS_SIM == _ABI64 - mips64-linux-gnuabi64 -# else -# error unknown platform triplet -# endif -# elif defined(__or1k__) - or1k-linux-gnu -# elif defined(__powerpc__) && defined(__SPE__) - powerpc-linux-gnuspe -# elif defined(__powerpc64__) -# if defined(__LITTLE_ENDIAN__) - powerpc64le-linux-gnu -# else - powerpc64-linux-gnu -# endif -# elif defined(__powerpc__) - powerpc-linux-gnu -# elif defined(__s390x__) - s390x-linux-gnu -# elif defined(__s390__) - s390-linux-gnu -# elif defined(__sh__) && defined(__LITTLE_ENDIAN__) - sh4-linux-gnu -# elif defined(__sparc__) && defined(__arch64__) - sparc64-linux-gnu -# elif defined(__sparc__) - sparc-linux-gnu -# elif defined(__riscv) -# if __riscv_xlen == 32 - riscv32-linux-gnu -# elif __riscv_xlen == 64 - riscv64-linux-gnu -# else -# error unknown platform triplet -# endif -# else -# error unknown platform triplet -# endif -#elif defined(__FreeBSD_kernel__) -# if defined(__LP64__) - x86_64-kfreebsd-gnu -# elif defined(__i386__) - i386-kfreebsd-gnu -# else -# error unknown platform triplet -# endif -#elif defined(__gnu_hurd__) - i386-gnu -#elif defined(__APPLE__) - darwin -#elif defined(__VXWORKS__) - vxworks -#elif defined(__wasm32__) -# if defined(__EMSCRIPTEN__) - wasm32-emscripten -# elif defined(__wasi__) -# if defined(_REENTRANT) - wasm32-wasi-threads -# else - wasm32-wasi -# endif -# else -# error unknown wasm32 platform -# endif -#elif defined(__wasm64__) -# if defined(__EMSCRIPTEN__) - wasm64-emscripten -# elif defined(__wasi__) - wasm64-wasi -# else -# error unknown wasm64 platform -# endif -#else -# error unknown platform triplet -#endif - -EOF - -if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then - PLATFORM_TRIPLET=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` - case "$build_os" in - linux-musl*) - PLATFORM_TRIPLET=`echo "$PLATFORM_TRIPLET" | sed 's/linux-gnu/linux-musl/'` - ;; - esac +if $CPP $CPPFLAGS $srcdir/Misc/platform_triplet.c >conftest.out 2>/dev/null; then + PLATFORM_TRIPLET=`grep '^PLATFORM_TRIPLET=' conftest.out | tr -d ' '` + PLATFORM_TRIPLET="${PLATFORM_TRIPLET@%:@PLATFORM_TRIPLET=}" AC_MSG_RESULT([$PLATFORM_TRIPLET]) else AC_MSG_RESULT([none]) fi -rm -f conftest.c conftest.out +rm -f conftest.out AC_MSG_CHECKING([for multiarch]) AS_CASE([$ac_sys_system], @@ -1673,6 +1497,23 @@ fi AC_SUBST([ABIFLAGS]) ABIFLAGS="" +# Check for --disable-gil +# --disable-gil +AC_MSG_CHECKING([for --disable-gil]) +AC_ARG_ENABLE([gil], + [AS_HELP_STRING([--disable-gil], [enable experimental support for running without the GIL (default is no)])], + [AS_VAR_IF([enable_gil], [yes], [disable_gil=no], [disable_gil=yes])], [disable_gil=no] +) +AC_MSG_RESULT([$disable_gil]) + +if test "$disable_gil" = "yes" +then + AC_DEFINE([Py_NOGIL], [1], + [Define if you want to disable the GIL]) + # Add "t" for "threaded" + ABIFLAGS="${ABIFLAGS}t" +fi + # Check for --with-pydebug AC_MSG_CHECKING([for --with-pydebug]) AC_ARG_WITH([pydebug], @@ -1978,7 +1819,10 @@ then fi fi LLVM_PROF_ERR=no -case $CC in + +# GNU Autoconf recommends the use of expr instead of basename. +AS_VAR_SET([CC_BASENAME], [$(expr "//$CC" : '.*/\(.*\)')]) +case "$CC_BASENAME" in *clang*) # Any changes made here should be reflected in the GCC+Darwin case below PGO_PROF_GEN_FLAG="-fprofile-instr-generate" @@ -2409,7 +2253,7 @@ yes) # ICC doesn't recognize the option, but only emits a warning ## XXX does it emit an unused result warning and can it be disabled? - AS_CASE([$CC], + AS_CASE(["$CC_BASENAME"], [*icc*], [ac_cv_disable_unused_result_warning=no] [PY_CHECK_CC_WARNING([disable], [unused-result])]) AS_VAR_IF([ac_cv_disable_unused_result_warning], [yes], @@ -2655,7 +2499,10 @@ yes) ;; esac -case "$CC" in +case "$CC_BASENAME" in +*mpicc*) + CFLAGS_NODIST="$CFLAGS_NODIST" + ;; *icc*) # ICC needs -fp-model strict or floats behave badly CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" @@ -2845,14 +2692,14 @@ AC_DEFINE([STDC_HEADERS], [1], # checks for header files AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/memfd.h \ + io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \ linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \ sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ - sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h \ + sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h sys/timerfd.h \ sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \ termios.h util.h utime.h utmp.h \ ]) @@ -2877,7 +2724,8 @@ AC_CHECK_HEADERS([net/if.h], [], [], ]) # On Linux, netlink.h requires asm/types.h -AC_CHECK_HEADERS([linux/netlink.h], [], [], [ +# On FreeBSD, netlink.h is located in netlink/netlink.h +AC_CHECK_HEADERS([linux/netlink.h netlink/netlink.h], [], [], [ #ifdef HAVE_ASM_TYPES_H #include #endif @@ -4770,8 +4618,8 @@ PLATFORM_OBJS= AS_CASE([$ac_sys_system], [Emscripten], [ - AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_signal.o']) - AS_VAR_APPEND([PLATFORM_HEADERS], [' $(srcdir)/Include/internal/pycore_emscripten_signal.h']) + AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_signal.o Python/emscripten_trampoline.o']) + AS_VAR_APPEND([PLATFORM_HEADERS], [' $(srcdir)/Include/internal/pycore_emscripten_signal.h $(srcdir)/Include/internal/pycore_emscripten_trampoline.h']) ], ) AC_SUBST([PLATFORM_HEADERS]) @@ -4904,6 +4752,13 @@ PY_CHECK_FUNC([eventfd], [ #endif ]) +PY_CHECK_FUNC([timerfd_create], [ +#ifdef HAVE_SYS_TIMERFD_H +#include +#endif +], +[HAVE_TIMERFD_CREATE]) + # On some systems (eg. FreeBSD 5), we would find a definition of the # functions ctermid_r, setgroups in the library, but no prototype # (e.g. because we use _XOPEN_SOURCE). See whether we can take their @@ -5846,6 +5701,7 @@ AC_C_BIGENDIAN # # * The Python implementation (always 'cpython-' for us) # * The major and minor version numbers +# * --disable-gil (adds a 't') # * --with-pydebug (adds a 'd') # # Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, @@ -5861,8 +5717,9 @@ AC_MSG_CHECKING([SOABI]) SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} AC_MSG_RESULT([$SOABI]) -# Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI -if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then +# Release build, debug build (Py_DEBUG), and trace refs build (Py_TRACE_REFS) +# are ABI compatible +if test "$Py_DEBUG" = 'true'; then # Similar to SOABI but remove "d" flag from ABIFLAGS AC_SUBST([ALT_SOABI]) ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} @@ -5990,6 +5847,7 @@ dnl library (tinfo ncursesw ncurses termcap). We now assume that libreadline dnl or readline.pc provide correct linker information. AH_TEMPLATE([WITH_EDITLINE], [Define to build the readline module against libedit.]) +AH_TEMPLATE([WITH_APPLE_EDITLINE], [Define to build the readline module against Apple BSD editline.]) AC_ARG_WITH( [readline], @@ -6006,6 +5864,15 @@ AC_ARG_WITH( [with_readline=readline] ) +# gh-105323: Need to handle the macOS editline as an alias of readline. +AS_CASE([$ac_sys_system/$ac_sys_release], + [Darwin/*], [AC_CHECK_TYPE([Function], + [AC_DEFINE([WITH_APPLE_EDITLINE])], + [], + [@%:@include ])], + [] +) + AS_VAR_IF([with_readline], [readline], [ PKG_CHECK_MODULES([LIBREADLINE], [readline], [ LIBREADLINE=readline @@ -6140,6 +6007,13 @@ AS_VAR_IF([with_readline], [no], [ AC_DEFINE([HAVE_RL_APPEND_HISTORY], [1], [Define if readline supports append_history]) ]) + # in readline as well as newer editline (April 2023) + AC_CHECK_TYPE([rl_compdisp_func_t], + [AC_DEFINE([HAVE_RL_COMPDISP_FUNC_T], [1], + [Define if readline supports rl_compdisp_func_t])], + [], + [readline_includes]) + m4_undefine([readline_includes]) ])dnl WITH_SAVE_ENV() ]) @@ -6646,11 +6520,14 @@ SRCDIRS="\ Modules/_sqlite \ Modules/_sre \ Modules/_testcapi \ + Modules/_testinternalcapi \ Modules/_xxtestfuzz \ Modules/cjkcodecs \ Modules/expat \ Objects \ Parser \ + Parser/tokenizer \ + Parser/lexer \ Programs \ Python \ Python/frozen_modules \ @@ -7122,6 +6999,63 @@ AC_ARG_ENABLE([test-modules], AC_MSG_RESULT([$TEST_MODULES]) AC_SUBST([TEST_MODULES]) +# gh-109054: Check if -latomic is needed to get atomic functions. +# On Linux aarch64, GCC may require programs and libraries to be linked +# explicitly to libatomic. Call _Py_atomic_or_uint64() which may require +# libatomic __atomic_fetch_or_8(), or not, depending on the C compiler and the +# compiler flags. +# +# Avoid #include or #include . The header +# requires header which is only written below by AC_OUTPUT below. +# If the check is done after AC_OUTPUT, modifying LIBS has no effect +# anymore. cannot be included alone, it's designed to be included +# by : it expects other includes and macros to be defined. +_SAVE_VAR([CPPFLAGS]) +CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}" + +AC_CACHE_CHECK([whether libatomic is needed by ], + [ac_cv_libatomic_needed], +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +// pyatomic.h needs uint64_t and Py_ssize_t types +#include // int64_t, intptr_t +#ifdef HAVE_SYS_TYPES_H +# include // ssize_t +#endif +// Code adapted from Include/pyport.h +#if HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef intptr_t Py_ssize_t; +#else +# error "unable to define Py_ssize_t" +#endif + +#include "pyatomic.h" + +int main() +{ + uint64_t byte; + _Py_atomic_store_uint64(&byte, 2); + if (_Py_atomic_or_uint64(&byte, 8) != 2) { + return 1; // error + } + if (_Py_atomic_load_uint64(&byte) != 10) { + return 1; // error + } + return 0; // all good +} +]])], + [ac_cv_libatomic_needed=no], dnl build succeeded + [ac_cv_libatomic_needed=yes], dnl build failed + [ac_cv_libatomic_needed=no]) dnl cross compilation +]) + +AS_VAR_IF([ac_cv_libatomic_needed], [yes], + [LIBS="${LIBS} -latomic"]) +_RESTORE_VAR([CPPFLAGS]) + + +# stdlib AC_DEFUN([PY_STDLIB_MOD_SET_NA], [ m4_foreach([mod], [$@], [ AS_VAR_SET([py_cv_module_]mod, [n/a])]) @@ -7391,6 +7325,7 @@ PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], dnl test modules PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testclinic_limited], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testbuffer], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) @@ -7402,10 +7337,9 @@ PY_STDLIB_MOD([_ctypes_test], [], [$LIBM]) dnl Limited API template modules. -dnl The limited C API is not compatible with the Py_TRACE_REFS macro. dnl Emscripten does not support shared libraries yet. -PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) -PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxlimited], [], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxlimited_35], [], [test "$ac_cv_func_dlopen" = yes]) # substitute multiline block, must come after last PY_STDLIB_MOD() AC_SUBST([MODULE_BLOCK]) @@ -7422,6 +7356,7 @@ AC_CONFIG_FILES(m4_normalize([ Modules/Setup.stdlib ])) AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) +# Generate files like pyconfig.h AC_OUTPUT AC_MSG_NOTICE([creating Modules/Setup.local]) diff --git a/pyconfig.h.in b/pyconfig.h.in index 0828dc8d4b58cd..4b8fc4a677c776 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -607,9 +607,6 @@ /* Define this if you have le64toh() */ #undef HAVE_HTOLE64 -/* Define to 1 if you have the header file. */ -#undef HAVE_IEEEFP_H - /* Define to 1 if you have the `if_nameindex' function. */ #undef HAVE_IF_NAMEINDEX @@ -721,6 +718,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_FS_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_LIMITS_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_MEMFD_H @@ -838,6 +838,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NETLINK_NETLINK_H + /* Define to 1 if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H @@ -980,6 +983,9 @@ /* Define if you can turn off readline's signal handling. */ #undef HAVE_RL_CATCH_SIGNAL +/* Define if readline supports rl_compdisp_func_t */ +#undef HAVE_RL_COMPDISP_FUNC_T + /* Define if you have readline 2.2 */ #undef HAVE_RL_COMPLETION_APPEND_CHARACTER @@ -1360,6 +1366,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TERMIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIMERFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIMES_H @@ -1402,6 +1411,9 @@ /* Define to 1 if you have the `timegm' function. */ #undef HAVE_TIMEGM +/* Define if you have the 'timerfd_create' function. */ +#undef HAVE_TIMERFD_CREATE + /* Define to 1 if you have the `times' function. */ #undef HAVE_TIMES @@ -1603,9 +1615,15 @@ SipHash13: 3, externally defined: 0 */ #undef Py_HASH_ALGORITHM +/* Define if you want to disable the GIL */ +#undef Py_NOGIL + /* Define if you want to enable internal statistics gathering. */ #undef Py_STATS +/* The version of SunOS/Solaris as reported by `uname -r' without the dot. */ +#undef Py_SUNOS_VERSION + /* Define if you want to enable tracing references for debugging purpose */ #undef Py_TRACE_REFS @@ -1782,6 +1800,9 @@ /* Define if WINDOW in curses.h offers a field _flags. */ #undef WINDOW_HAS_FLAGS +/* Define to build the readline module against Apple BSD editline. */ +#undef WITH_APPLE_EDITLINE + /* Define if you want build the _decimal module using a coroutine-local rather than a thread-local context */ #undef WITH_DECIMAL_CONTEXTVAR